From 73d1bbe04df495c82e112afa74380a9c9fe30d5f Mon Sep 17 00:00:00 2001 From: thanga Date: Thu, 21 Nov 2019 20:44:24 +0530 Subject: [PATCH 01/51] Delete org.eclipse.jdt.core.prefs --- .settings/org.eclipse.jdt.core.prefs | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 .settings/org.eclipse.jdt.core.prefs diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 3a21537..0000000 --- a/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,11 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.8 From ae0ba282681bca6315d2ead0109c26ef7f6deb7f Mon Sep 17 00:00:00 2001 From: thanga Date: Thu, 21 Nov 2019 20:44:39 +0530 Subject: [PATCH 02/51] Delete AmazonProblems.kotlin_module --- bin/META-INF/AmazonProblems.kotlin_module | Bin 16 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 bin/META-INF/AmazonProblems.kotlin_module diff --git a/bin/META-INF/AmazonProblems.kotlin_module b/bin/META-INF/AmazonProblems.kotlin_module deleted file mode 100644 index 2983af70661ad375cc499ebc4da5a68ca46c532e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16 RcmZQzU|?ooU|@t|egFVe02KfL From 1ff709968b2b84cd56df8901fa2f0853a41cb44d Mon Sep 17 00:00:00 2001 From: Thangaraj A Date: Thu, 21 Nov 2019 20:53:46 +0530 Subject: [PATCH 03/51] Inital commit --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index ab31b20..2a017ab 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ *.class +.DS_Store +.classpath +.project +AmazonProblems.iml From 95a3522cd79a0b0c23f57dea36c6e1829ead856f Mon Sep 17 00:00:00 2001 From: thanga Date: Thu, 21 Nov 2019 20:54:16 +0530 Subject: [PATCH 04/51] Delete .DS_Store --- .DS_Store | Bin 8196 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 5a83bd58e1045099751b7729697efaf0cb0cf234..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMTWl0n82?Z|Yd?#%82 zO_R!lMkU43)lfA};d=f|DG}MjNFw?>| z5P=YZ5P=YZ5P=YZ+W`T(vw2Zwxc7xNtV0As1pb!@@b^QE9xfA7jtUvPI;aX#0Fu?z z9TaNwbb$NBq)bRTDkN#Bpl~HATv4VNDBP((ChZbZjtVK<0cG-mGBU~x1%v1`ek?Et zOb8j)Ap#)+QxV|DMTHjdz@+TGB7bj9<=w#{;Skw9z15)G*_pH59BCE%hXt2w-~6b3 zCQIWVS`H0VMh;GM73BDL1-rje)8|kmsi~aDEAjSc*R)*a^BC9Oj6GF5As)ubjr=?) zKt5OYhUDu0$PL++=f~qWFj7@LYxW#P)oRq5+M1dpsR6f~^0R)?OJ)lhwk%~CW-eRk zu?&A8Z8|$_vt&B^3VX7?SvbUv)2?fifoNxQ2Q0IkVGBE4$In`hSqR1xV;t_W9K$Uq z-J)Z7fxR3&Xm@4(0UAfCPaI3|S%a#m8Kw^px2<2_9BbPUA8C#aZ`>HC_PPxtBdV$_ zY23O0Xz}zj=bwM|wF?)oeH?fJ$~P+1iQnV(C)AQqOoV>N;tGvd>JT7BPEH4szViWX zSFe?Kos@OT%&>VLL9mN{b`{JLExjl2+QmV~%don9*3K7g!l~W1xv|&lnE*Fim;C@)Ad7K(@`*~Hl)K{4Z4>0XiY3D4e!23 z)6&Ojr@mg3c6v+UlwP1ld| z$a}J$zi-HNXjY%g@JX6gAJ?@T2A>nLr%7yhuw0e#dw2<~f;QL!UC;*xl;I4Vg>&#S zT!Q!D1NaQSfG^=I_!@4&_wW<^48Opy@E2C&Y@CA%*5Ptofh(~ISK}ItV=HdP?bwb< z?7%&^AJf>42QY*EXyGGx9DN+YQG5(fJdktY+po4974P&i@O9AO=cu2P62ObLE!4beuGh|ExE8>06r z3X2F`OEj($cUhItt<%;k#8Ng(Xg6t_RpK$L7TT@ac7^E5W(#dn>s0xPVlbI^GqUat zxB^#+ao@ss@FTJ9cVZe4%W6>%Shfo5u>o6%X|1>x+i)vx!vwL7b8Rm^gk9K&2k|f- zA;t|5 zHnzPV+=BAeIq2TJeWq$B+&=Id44*!lm#(S>4m8D7yrt|!N$IRdVZ)M1E ztPp_^f!hoLtnN&8CTUVLy=Zu@9i!)AdU)Y>qe2EQR0Zic$sipkIsS(swPR$;eG*cR V3Q0Xw{`C(5;r$=p|Ka@)e*;gks22bL From 4477cdbb071a20129f3eb599b7f94370cd8e7afb Mon Sep 17 00:00:00 2001 From: thanga Date: Thu, 21 Nov 2019 20:54:34 +0530 Subject: [PATCH 05/51] Delete .classpath --- .classpath | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .classpath diff --git a/.classpath b/.classpath deleted file mode 100644 index 51a8bba..0000000 --- a/.classpath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - From ccafc3e54c5b43f5d804815486c55e0d248983a5 Mon Sep 17 00:00:00 2001 From: thanga Date: Thu, 21 Nov 2019 20:54:42 +0530 Subject: [PATCH 06/51] Delete .project --- .project | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 .project diff --git a/.project b/.project deleted file mode 100644 index cd4a1be..0000000 --- a/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - AmazonProblems - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - From d8036c7c2b19510c9ac06cb9322cdba110e33047 Mon Sep 17 00:00:00 2001 From: thanga Date: Thu, 21 Nov 2019 20:54:50 +0530 Subject: [PATCH 07/51] Delete AmazonProblems.iml --- AmazonProblems.iml | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 AmazonProblems.iml diff --git a/AmazonProblems.iml b/AmazonProblems.iml deleted file mode 100644 index ea1542a..0000000 --- a/AmazonProblems.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file From 8dde0603ba6aa6d3520dbf46c8dc020e0b6cd129 Mon Sep 17 00:00:00 2001 From: thanga Date: Thu, 21 Nov 2019 20:55:09 +0530 Subject: [PATCH 08/51] Delete .DS_Store --- src/.DS_Store | Bin 8196 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/.DS_Store diff --git a/src/.DS_Store b/src/.DS_Store deleted file mode 100644 index 67688a563b97503d236a1f9bd7a425b1560c7f6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHLOKjX!6umc})^=LrgmjXWOgl7*650fkHXqssI!Pu!K1$Tdw+)?o#%^NOV^7DP zNz)Jr6awH{LV}82$_5D*zy=9K5iCGdqJZe83l?lZAS70BpPwhBNt3Dz1XBDY zzx#aeJ+|NRd46*T0I(~gHUm@ufItVcauIbmX)Ml;RV~l+upkm1z=jiGK^mq&Tb1oQ zd7dRn0mv4R z+if(aI>5z*JRA1x0=F)duF0zh^q}aK7|7ui53zKzVb3mb%i(|=4(Qz(y$S{0yAv+t zrUQn#^?RQIpMlj3uw}E=t=Ba;c|-l~p2uhGRNS!Ql=XQ$W$3ok)buUpK>Z*QXUzP9;!Q7Er%eqi8ua`w#J zuF-O9V+pf!@A;DJGX@ zY2Je=N4HFSR7=}rV{)-gTn!{Fb11E`_*lX+GD*{p$t4NJNMsDf(K-zys-My9aYsAt zu+b6QN;}D9 zeyys&4pDwjm{jR*k6J22syx3cuuBk*GJkhkqn^8^+CZHsE5fi%56myITWSzxTO2+~ z@0~;MlbQut6-Nvut{L3bBDD$f!{S($v&NnKrGr8VHi+Z&qLTF7Hg`W52n+IM;TXI3 zBZ}<|rZn@Pr-}%|1dDX4s-_Cn;d=gt-I-R0oA{YX`%op^OS?`#OwzwtDVT+Ga2{TO z*Wqor1nszKU<+TX+#K;XC*~eu$s&N6X6z z`XPRv>+w?>t+R#=JL|3Cykj?$Xt1ZZ??000cUzb)OG@u7+qR>+ZckI|fkR8Lbj4e| zL1@d>APs7y!4zrGMhEBdNqh>Q#05RtWVr5vl3rAMdZ&gRQeNveC3@SmqRE<<=HMY?PMICtAVk z|DLt~|KBKd`1AA`*pLihK_nXKqN%U-5oEP?h>qiQu*UKhxOE}au@vTa%W<+^Iqv#G jUM%d{1#Vp^VO%I#UdjLKe*`T5)$8y7{{Fu~_y4~Eg%Um7 From 0e3bc9efe00b3123cdf0fdc86366fe2be97ad0c7 Mon Sep 17 00:00:00 2001 From: Thangaraj A Date: Mon, 25 Nov 2019 19:26:13 +0530 Subject: [PATCH 09/51] Modified the code --- .DS_Store | Bin 8196 -> 8196 bytes bin/META-INF/AmazonProblems.kotlin_module | Bin 0 -> 16 bytes .../AlternateOddAndEvenNumbers.java | 14 +---- .../FirstNonReapeatingCharacterStream.java | 52 ++++++++++++++++++ src/geeksforgeeks/PrintParenthesis.java | 35 ++++++++++++ 5 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 bin/META-INF/AmazonProblems.kotlin_module create mode 100644 src/geeksforgeeks/FirstNonReapeatingCharacterStream.java create mode 100644 src/geeksforgeeks/PrintParenthesis.java diff --git a/.DS_Store b/.DS_Store index 5a83bd58e1045099751b7729697efaf0cb0cf234..f3a95b2f243fc940a05f1c1446a75595955d1a44 100644 GIT binary patch delta 57 zcmZp1XmOa}&(Fiaz`)4BAi!W4oSdIqu(5C&`@{y}&Fma39E?1h*9b%dxeGS4OMGM5 MJXbV}X=1}%0Je7#QUCw| delta 222 zcmZp1XmOa}FDk&mz`)4B0HjJ7G8yt1(iw_#(l;h9X5Y-t!NO4wlICR4V<=`w1u8&N zVi=s9pIZQw1p+2-Ab~|yZoZ34QcivnP?jU-iSQb}^#>ersZ7DDQVG-Qf(&G<1sFE- Y2t)%NEAfqmiA#O*1;N_QcSJgv0M*Sh{Qv*} diff --git a/bin/META-INF/AmazonProblems.kotlin_module b/bin/META-INF/AmazonProblems.kotlin_module new file mode 100644 index 0000000000000000000000000000000000000000..2983af70661ad375cc499ebc4da5a68ca46c532e GIT binary patch literal 16 RcmZQzU|?ooU|@t|egFVe02KfL literal 0 HcmV?d00001 diff --git a/src/geeksforgeeks/AlternateOddAndEvenNumbers.java b/src/geeksforgeeks/AlternateOddAndEvenNumbers.java index c8e4d68..d96f881 100644 --- a/src/geeksforgeeks/AlternateOddAndEvenNumbers.java +++ b/src/geeksforgeeks/AlternateOddAndEvenNumbers.java @@ -5,13 +5,8 @@ class AlternateOddAndEvenNumbers { - // The main function that rearranges elements of given - // array. It puts positive elements at even indexes (0, - // 2, ..) and negative numbers at odd indexes (1, 3, ..). static void rearrange(int arr[], int n) { - // The following few lines are similar to partition - // process of QuickSort. The idea is to consider 0 - // as pivot and divide the array around it. + //-1, 2, -3, 4, 5, 6, -7, 8, 9 int i = -1, temp = 0; for (int j = 0; j < n; j++) { if (arr[j] < 0) { @@ -22,13 +17,10 @@ static void rearrange(int arr[], int n) { } } - // Now all positive numbers are at end and negative numbers at - // the beginning of array. Initialize indexes for starting point - // of positive and negative numbers to be swapped + int pos = i + 1, neg = 0; - // Increment the negative index by 2 and positive index by 1, i.e., - // swap every alternate negative number with next positive number + while (pos < n && neg < pos && arr[neg] < 0) { temp = arr[neg]; arr[neg] = arr[pos]; diff --git a/src/geeksforgeeks/FirstNonReapeatingCharacterStream.java b/src/geeksforgeeks/FirstNonReapeatingCharacterStream.java new file mode 100644 index 0000000..f00bd9b --- /dev/null +++ b/src/geeksforgeeks/FirstNonReapeatingCharacterStream.java @@ -0,0 +1,52 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.List; + +public class FirstNonReapeatingCharacterStream { + final static int MAX_CHAR = 256; + + static void findFirstNonRepeating() { + // inDLL[x] contains pointer to a DLL node if x is present + // in DLL. If x is not present, then inDLL[x] is NULL + List inDLL = new ArrayList<>(); + + // repeated[x] is true if x is repeated two or more times. + // If x is not seen so far or x is seen only once. then + // repeated[x] is false + boolean[] repeated = new boolean[MAX_CHAR]; + + // Let us consider following stream and see the process + String stream = "geeksforgeeksandgeeksquizfor"; + for (int i = 0; i < stream.length(); i++) { + char x = stream.charAt(i); + System.out.println("Reading " + x + " from stream n"); + + // We process this character only if it has not occurred + // or occurred only once. repeated[x] is true if x is + // repeated twice or more.s + if (!repeated[x]) { + // If the character is not in DLL, then add this at + // the end of DLL. + if (!(inDLL.contains(x))) { + inDLL.add(x); + } else // Otherwise remove this character from DLL + { + inDLL.remove((Character) x); + repeated[x] = true; // Also mark it as repeated + } + } + + // Print the current first non-repeating character from + // stream + if (inDLL.size() != 0) { + System.out.print("First non-repeating character so far is "); + System.out.println(inDLL.get(0)); + } + } + } + + public static void main(String[] args) { + findFirstNonRepeating(); + } +} diff --git a/src/geeksforgeeks/PrintParenthesis.java b/src/geeksforgeeks/PrintParenthesis.java new file mode 100644 index 0000000..064713b --- /dev/null +++ b/src/geeksforgeeks/PrintParenthesis.java @@ -0,0 +1,35 @@ +package geeksforgeeks; + + +class PrintParenthesis { + + static void formParenthesis(char str[], int pos, int n, int open, int close) { + if (close == n) { + for (int i = 0; i < str.length; i++) + System.out.print(str[i]); + System.out.println(); + return; + } else { + if (open > close) { + str[pos] = '}'; + formParenthesis(str, pos + 1, n, open, close + 1); + } + if (open < n) { + str[pos] = '{'; + formParenthesis(str, pos + 1, n, open + 1, close); + } + } + } + + static void printParenthesis(char str[], int n) { + if (n > 0) + formParenthesis(str, 0, n, 0, 0); + return; + } + + public static void main(String[] args) { + int n = 3; + char[] str = new char[2 * n]; + printParenthesis(str, n); + } +} \ No newline at end of file From 49a107ae6ce5c4187f3f2295c68aecac9ff5b91b Mon Sep 17 00:00:00 2001 From: Thangaraj A Date: Sat, 7 Dec 2019 21:30:37 +0530 Subject: [PATCH 10/51] Init project --- bin/META-INF/AmazonProblems.kotlin_module | Bin 16 -> 0 bytes .../FirstNonReapeatingCharacterStream.java | 3 + .../InorderSuccessorPredecessor.java | 76 ++++++++++++++++++ src/geeksforgeeks/MaxHistogram.java | 41 ++++++++++ .../MobileKeyPadCombinations.java | 37 +++++++++ src/geeksforgeeks/NumberOfBallons.java | 20 +++++ src/geeksforgeeks/PrintParenthesis.java | 4 +- 7 files changed, 179 insertions(+), 2 deletions(-) delete mode 100644 bin/META-INF/AmazonProblems.kotlin_module create mode 100644 src/geeksforgeeks/InorderSuccessorPredecessor.java create mode 100644 src/geeksforgeeks/MaxHistogram.java create mode 100644 src/geeksforgeeks/MobileKeyPadCombinations.java create mode 100644 src/geeksforgeeks/NumberOfBallons.java diff --git a/bin/META-INF/AmazonProblems.kotlin_module b/bin/META-INF/AmazonProblems.kotlin_module deleted file mode 100644 index 2983af70661ad375cc499ebc4da5a68ca46c532e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16 RcmZQzU|?ooU|@t|egFVe02KfL diff --git a/src/geeksforgeeks/FirstNonReapeatingCharacterStream.java b/src/geeksforgeeks/FirstNonReapeatingCharacterStream.java index f00bd9b..54b3089 100644 --- a/src/geeksforgeeks/FirstNonReapeatingCharacterStream.java +++ b/src/geeksforgeeks/FirstNonReapeatingCharacterStream.java @@ -3,6 +3,9 @@ import java.util.ArrayList; import java.util.List; +/** + * https://www.geeksforgeeks.org/find-first-non-repeating-character-stream-characters/ + */ public class FirstNonReapeatingCharacterStream { final static int MAX_CHAR = 256; diff --git a/src/geeksforgeeks/InorderSuccessorPredecessor.java b/src/geeksforgeeks/InorderSuccessorPredecessor.java new file mode 100644 index 0000000..76f1bda --- /dev/null +++ b/src/geeksforgeeks/InorderSuccessorPredecessor.java @@ -0,0 +1,76 @@ +package geeksforgeeks; + +/** + * https://algorithms.tutorialhorizon.com/inorder-predecessor-and-successor-in-binary-search-tree/ + */ +public class InorderSuccessorPredecessor { + static int successor, predecessor; + + public void successorPredecessor(TNode root, int val) { + if (root != null) { + if (root.data == val) { + // go to the right most element in the left subtree, it will be the + // predecessor. + if (root.left != null) { + TNode t = root.left; + while (t.right != null) { + t = t.right; + } + predecessor = t.data; + } + if (root.right != null) { + // go to the left most element in the right subtree, it will be + // the successor. + TNode t = root.right; + while (t.left != null) { + t = t.left; + } + successor = t.data; + } + } else if (root.data > val) { + // we make the root as successor because we might have a + // situation when value matches with the root, it wont have + // right subtree to find the successor, in that case we need + // parent to be the successor + successor = root.data; + successorPredecessor(root.left, val); + } else if (root.data < val) { + // we make the root as predecessor because we might have a + // situation when value matches with the root, it wont have + // left subtree to find the predecessor, in that case we need + // parent to be the predecessor. + predecessor = root.data; + successorPredecessor(root.right, val); + } + } + } + + public static void main(String args[]) { + TNode root = new TNode(25); + root.left = new TNode(15); + root.right = new TNode(40); + root.left.left = new TNode(10); + root.left.left.left = new TNode(5); + root.left.right = new TNode(18); + root.right.left = new TNode(35); + root.right.right = new TNode(45); + root.left.right.left = new TNode(19); + root.left.right.right = new TNode(20); + InorderSuccessorPredecessor i = new InorderSuccessorPredecessor(); + i.successorPredecessor(root, 20); + System.out.println("Inorder Successor of 10 is : " + successor + " and predecessor is : " + predecessor); + + } +} + +class TNode { + int data; + TNode left; + TNode right; + + public TNode(int data) { + this.data = data; + left = null; + right = null; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MaxHistogram.java b/src/geeksforgeeks/MaxHistogram.java new file mode 100644 index 0000000..ed23515 --- /dev/null +++ b/src/geeksforgeeks/MaxHistogram.java @@ -0,0 +1,41 @@ +package geeksforgeeks; + +import java.util.Stack; + +/** + * https://leetcode.com/problems/largest-rectangle-in-histogram/ + */ +public class MaxHistogram { + + public static int largestRectangleArea(int[] heights) { + if (heights == null || heights.length == 0) { + return 0; + } + if (heights.length == 1) { + return heights[0]; + } + int result = 0; + Stack stack = new Stack(); + //i<=heights because it needs to cross the ith pos to calculate the right boundary + for (int i = 0; i <= heights.length; ) { + int h = (i == heights.length ? 0 : heights[i]); + if (stack.isEmpty() || h >= heights[stack.peek()]) { + stack.push(i); + i++; + } else { + int height = heights[stack.pop()]; + int rightboundary = i - 1; + int leftboundary = stack.isEmpty() ? 0 : stack.peek() + 1; + int width = rightboundary - leftboundary + 1; + result = Math.max(result, height * width); + } + } + + return result; + } + + public static void main(String[] args) { + int[] arr = new int[] { 2, 1, 5, 6, 2, 3 }; + System.out.println(largestRectangleArea(arr)); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MobileKeyPadCombinations.java b/src/geeksforgeeks/MobileKeyPadCombinations.java new file mode 100644 index 0000000..9ac4a10 --- /dev/null +++ b/src/geeksforgeeks/MobileKeyPadCombinations.java @@ -0,0 +1,37 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.List; + +public class MobileKeyPadCombinations { + + public List letterCombinations(String digits) { + List result = new ArrayList<>(); + if (digits == null || digits.length() == 0) { + return result; + } + + String[] charsCombs = { "--", "00", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; + + generateCombinations(digits, charsCombs, digits.length(), 0, new StringBuilder(), result); + return result; + } + + public void generateCombinations(String digits, String[] charsCombos, int len, int start, StringBuilder sb, + List result) { + if (start == len) { + result.add(sb.toString()); + return; + } + + for (char ch : charsCombos[digits.charAt(start) - '0'].toCharArray()) { + sb.append(ch); + generateCombinations(digits, charsCombos, len, start + 1, sb, result); + sb.deleteCharAt(sb.length() - 1); + } + } + + public static void main(String[] args) { + + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/NumberOfBallons.java b/src/geeksforgeeks/NumberOfBallons.java new file mode 100644 index 0000000..cbb05eb --- /dev/null +++ b/src/geeksforgeeks/NumberOfBallons.java @@ -0,0 +1,20 @@ +package geeksforgeeks; + +/** + * https://leetcode.com/problems/maximum-number-of-balloons/discuss/382401/WithComments-StraightForward-Java-Simple-count-of-chars + */ +public class NumberOfBallons { + + public int maxNumberOfBalloons(String text) { + int[] chars = new int[26]; //count all letters + for (char c : text.toCharArray()) { + chars[c - 'a']++; + } + int min = chars[1];//for b + min = Math.min(min, chars[0]);//for a + min = Math.min(min, chars[11] / 2);// for l /2 + min = Math.min(min, chars[14] / 2);//similarly for o/2 + min = Math.min(min, chars[13]);//for n + return min; + } +} diff --git a/src/geeksforgeeks/PrintParenthesis.java b/src/geeksforgeeks/PrintParenthesis.java index 064713b..869d054 100644 --- a/src/geeksforgeeks/PrintParenthesis.java +++ b/src/geeksforgeeks/PrintParenthesis.java @@ -1,6 +1,5 @@ package geeksforgeeks; - class PrintParenthesis { static void formParenthesis(char str[], int pos, int n, int open, int close) { @@ -22,8 +21,9 @@ static void formParenthesis(char str[], int pos, int n, int open, int close) { } static void printParenthesis(char str[], int n) { - if (n > 0) + if (n > 0) { formParenthesis(str, 0, n, 0, 0); + } return; } From 0748ce795ffa4d7cb5bced6ada9d422d2dc360fa Mon Sep 17 00:00:00 2001 From: vignesh Date: Tue, 24 Dec 2019 22:24:00 +0530 Subject: [PATCH 11/51] new problems --- src/geeksforgeeks/LivecellDeadCellGame.java | 28 +++++++ src/geeksforgeeks/SlidingWindow.java | 45 ++++++----- src/geeksforgeeks/SnakeAndLadder.java | 89 ++++++++++----------- src/geeksforgeeks/TreasureIsland.java | 3 +- 4 files changed, 95 insertions(+), 70 deletions(-) create mode 100644 src/geeksforgeeks/LivecellDeadCellGame.java diff --git a/src/geeksforgeeks/LivecellDeadCellGame.java b/src/geeksforgeeks/LivecellDeadCellGame.java new file mode 100644 index 0000000..fb2c97a --- /dev/null +++ b/src/geeksforgeeks/LivecellDeadCellGame.java @@ -0,0 +1,28 @@ +package geeksforgeeks; +public class LongestSpanWithSameSumArray { + //https://leetcode.com/problems/game-of-life/discuss/73366/Clean-O(1)-space-O(mn)-time-Java-Solution + public void gameOfLife(int[][] board) { + int[][] dir ={{1,-1},{1,0},{1,1},{0,-1},{0,1},{-1,-1},{-1,0},{-1,1}}; + int row=board.length; + int col=board[0].length; + for(int i=0; i=row || j+dir[k][1]>=col || i+dir[k][0]<0 || j+dir[k][1]<0) continue; + if(board[i+dir[k][0]][j+dir[k][1]]==1 || board[i+dir[k][0]][j+dir[k][1]]==2) liveCells++; + } + + if(board[i][j]==0 && liveCells==3) board[i][j]=3; + if(board[i][j]==1 && (liveCells<2 || liveCells>3)) board[i][j]=2; + } + } + + for(int i=0; i deque = new LinkedList<>(); - int i = 0; - for (; i < k; i++) { - while (!deque.isEmpty() && arr[i] >= arr[deque.peekLast()]) - deque.removeLast(); - deque.addLast(i); - } - for (; i < length; i++) { - System.out.println(arr[deque.peekFirst()]); - - while (!deque.isEmpty() && deque.peekFirst() <= i - k) - deque.removeFirst(); - - while (!deque.isEmpty() && arr[i] >= arr[deque.peekLast()]) - deque.removeLast(); - - deque.addLast(i); + public static int[] maxSlidingWindow(int[] nums, int k) { + if(nums.length==0)return new int[0]; + List result= new ArrayList<>(); + + Deque queue= new ArrayDeque<>(); + // queue.offer(nums[0]); + for(int i=0;i=k-1){ + result.add(nums[queue.peekFirst()]); + } } - System.out.println(arr[deque.peekFirst()]); + //int[] res= new int[result.size()]; + return result.stream().mapToInt(Integer::intValue).toArray(); } - } \ No newline at end of file diff --git a/src/geeksforgeeks/SnakeAndLadder.java b/src/geeksforgeeks/SnakeAndLadder.java index cc10da3..599dc0e 100644 --- a/src/geeksforgeeks/SnakeAndLadder.java +++ b/src/geeksforgeeks/SnakeAndLadder.java @@ -13,60 +13,55 @@ static class QEntry { int noOfMoves; } - static int getMinDiceThrows(int board[], int n) { - Queue queue = new LinkedList<>(); - QEntry qEntry = new QEntry(); - qEntry.vertex = 0; - qEntry.noOfMoves = 0; - - board[0] = -21; - queue.add(qEntry); - - while (!queue.isEmpty()) { - qEntry = queue.remove(); - int v = qEntry.vertex; - - System.out.println(v); - - if (v == n - 1) - break; - - for (int j = v + 1; j <= (v + 6) && j < n; j++) { - if (board[j] != -21) { - QEntry entry = new QEntry(); - entry.noOfMoves = (qEntry.noOfMoves + 1); - - if (board[j] != -1) - entry.vertex = board[j]; - else - entry.vertex = j; - queue.add(entry); - board[j] = -21; + int getMinDiceThrows(int[][] board, int n) { + //int n = board.length; + Queue queue = new LinkedList<>(); + queue.offer(1); + boolean[] visited = new boolean[n * n + 1]; + for (int move = 0; !queue.isEmpty(); move++) { + for (int size = queue.size(); size > 0; size--) { + int num = queue.poll(); + if (visited[num]) continue; + visited[num] = true; + if (num == n * n) return move; + for (int i = 1; i <= 6 && num + i <= n * n; i++) { + int next = num + i; + int value = getBoardValue(board, next); + if (value > 0) next = value; + if (!visited[next]) queue.offer(next); } } } - return qEntry.noOfMoves; + return -1; + } + + private int getBoardValue(int[][] board, int num) { + int n = board.length; + int r = (num - 1) / n; + int x = n - 1 - r; + int y = r % 2 == 0 ? num - 1 - r * n : n + r * n - num; + return board[x][y]; } - public static void main(String[] args) { + // public static void main(String[] args) { - int N = 30; - int moves[] = new int[N]; - for (int i = 0; i < N; i++) - moves[i] = -1; + // int N = 30; + // int moves[] = new int[N]; + // for (int i = 0; i < N; i++) + // moves[i] = -1; - // Ladders - moves[2] = 21; - moves[4] = 7; - moves[10] = 25; - moves[19] = 28; + // // Ladders + // moves[2] = 21; + // moves[4] = 7; + // moves[10] = 25; + // moves[19] = 28; - // Snakes - moves[3] = 1; - moves[23] = 8; - moves[16] = 3; - moves[18] = 6; + // // Snakes + // moves[3] = 1; + // moves[23] = 8; + // moves[16] = 3; + // moves[18] = 6; - System.out.println("Min Dice throws required is " + getMinDiceThrows(moves, N)); - } + // System.out.println("Min Dice throws required is " + getMinDiceThrows(moves, N)); + // } } \ No newline at end of file diff --git a/src/geeksforgeeks/TreasureIsland.java b/src/geeksforgeeks/TreasureIsland.java index 1230d8f..4a47009 100644 --- a/src/geeksforgeeks/TreasureIsland.java +++ b/src/geeksforgeeks/TreasureIsland.java @@ -49,7 +49,8 @@ public String toString() { } public static void main(String[] args) { - char[][] grid = {{'O', 'O', 'O', 'O'}, + char[][] grid = + {{'O', 'O', 'O', 'O'}, {'D', 'O', 'D', 'O'}, {'O', 'O', 'O', 'O'}, {'X', 'D', 'D', 'O'}}; From d4ba1be11a5e78d92a08fe3e4baf9a2e149b7de2 Mon Sep 17 00:00:00 2001 From: Vignesh Rajarajan Date: Tue, 24 Dec 2019 22:28:02 +0530 Subject: [PATCH 12/51] Create LivecellDeadCellGame.java --- src/geeksforgeeks/LivecellDeadCellGame.java | 28 +++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/geeksforgeeks/LivecellDeadCellGame.java diff --git a/src/geeksforgeeks/LivecellDeadCellGame.java b/src/geeksforgeeks/LivecellDeadCellGame.java new file mode 100644 index 0000000..6641214 --- /dev/null +++ b/src/geeksforgeeks/LivecellDeadCellGame.java @@ -0,0 +1,28 @@ +package geeksforgeeks; +public class LivecellDeadCellGame { + //https://leetcode.com/problems/game-of-life/discuss/73366/Clean-O(1)-space-O(mn)-time-Java-Solution + public void gameOfLife(int[][] board) { + int[][] dir ={{1,-1},{1,0},{1,1},{0,-1},{0,1},{-1,-1},{-1,0},{-1,1}}; + int row=board.length; + int col=board[0].length; + for(int i=0; i=row || j+dir[k][1]>=col || i+dir[k][0]<0 || j+dir[k][1]<0) continue; + if(board[i+dir[k][0]][j+dir[k][1]]==1 || board[i+dir[k][0]][j+dir[k][1]]==2) liveCells++; + } + + if(board[i][j]==0 && liveCells==3) board[i][j]=3; + if(board[i][j]==1 && (liveCells<2 || liveCells>3)) board[i][j]=2; + } + } + + for(int i=0; i Date: Tue, 24 Dec 2019 22:30:55 +0530 Subject: [PATCH 13/51] renaming file --- src/geeksforgeeks/LivecellDeadCellGame.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geeksforgeeks/LivecellDeadCellGame.java b/src/geeksforgeeks/LivecellDeadCellGame.java index fb2c97a..46bee19 100644 --- a/src/geeksforgeeks/LivecellDeadCellGame.java +++ b/src/geeksforgeeks/LivecellDeadCellGame.java @@ -1,5 +1,5 @@ package geeksforgeeks; -public class LongestSpanWithSameSumArray { +public class LivecellDeadCellGame { //https://leetcode.com/problems/game-of-life/discuss/73366/Clean-O(1)-space-O(mn)-time-Java-Solution public void gameOfLife(int[][] board) { int[][] dir ={{1,-1},{1,0},{1,1},{0,-1},{0,1},{-1,-1},{-1,0},{-1,1}}; From 92650f96b0e3edfb7c554416dedfecffaba3ff10 Mon Sep 17 00:00:00 2001 From: vignesh Date: Mon, 30 Dec 2019 15:34:22 +0530 Subject: [PATCH 14/51] new problems --- src/geeksforgeeks/DutchNationalFlag.java | 28 ++++++++++ src/geeksforgeeks/Flatten2DVector.java | 48 +++++++++++++++++ src/geeksforgeeks/IslandBFS.java | 53 +++++++++++++++++++ src/geeksforgeeks/MeetingRoomsII.java | 22 ++++++++ .../MobileKeyPadCombinations.java | 2 +- src/geeksforgeeks/PalindromePartion.java | 49 +++++++++++++++++ src/geeksforgeeks/PascalsTriangle.java | 17 ++++++ src/geeksforgeeks/PreOrderInOrderTree.java | 31 +++++++++++ 8 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 src/geeksforgeeks/DutchNationalFlag.java create mode 100644 src/geeksforgeeks/Flatten2DVector.java create mode 100644 src/geeksforgeeks/IslandBFS.java create mode 100644 src/geeksforgeeks/MeetingRoomsII.java create mode 100644 src/geeksforgeeks/PalindromePartion.java create mode 100644 src/geeksforgeeks/PascalsTriangle.java create mode 100644 src/geeksforgeeks/PreOrderInOrderTree.java diff --git a/src/geeksforgeeks/DutchNationalFlag.java b/src/geeksforgeeks/DutchNationalFlag.java new file mode 100644 index 0000000..116a4dc --- /dev/null +++ b/src/geeksforgeeks/DutchNationalFlag.java @@ -0,0 +1,28 @@ +package geeksforgeeks; +class DutchNationalFlag { + public void sortColors(int[] arr) { + if(arr.length==0) return; + int pivot=1; + int i=0; + int j= arr.length-1; + int zeroPos=0; + while(i<=j){ + if(arr[i]>pivot){ + swap(arr,i,j); + j--; + }else if(arr[i]==pivot){ + i++; + }else{ + swap(arr,zeroPos,i); + zeroPos++; + i++; + } + } + } + + public void swap(int[] arr, int i, int j){ + int temp=arr[j]; + arr[j]=arr[i]; + arr[i]=temp; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/Flatten2DVector.java b/src/geeksforgeeks/Flatten2DVector.java new file mode 100644 index 0000000..77141f2 --- /dev/null +++ b/src/geeksforgeeks/Flatten2DVector.java @@ -0,0 +1,48 @@ +package geeksforgeeks; +/* +Thoughts: +As hint indicates: use 2 pointers to hold position. +Use hasNext to validate (x,y) and move x. +Use next() to return (x,y) and move it(regardless of correctness, which is determined by hasNext()) +*/ +public class Flatten2DVector { + private int x; + private int y; + private List> list; + public Vector2D(List> vec2d) { + if (vec2d == null) { + return; + } + this.x = 0; + this.y = 0; + this.list = vec2d; + } + + public int next() { + int rst = list.get(x).get(y); + if (y + 1 >= list.get(x).size()) { + y = 0; + x++; + } else { + y++; + } + return rst; + } + + public boolean hasNext() { + if (list == null) { + return false; + } + while (x < list.size() && list.get(x).size() == 0) { + x++; + y = 0; + } + if (x >= list.size()) { + return false; + } + if (y >= list.get(x).size()) { + return false; + } + return true; + } +} diff --git a/src/geeksforgeeks/IslandBFS.java b/src/geeksforgeeks/IslandBFS.java new file mode 100644 index 0000000..de0a2f5 --- /dev/null +++ b/src/geeksforgeeks/IslandBFS.java @@ -0,0 +1,53 @@ +package geeksforgeeks; + +class IslandBFS { + private class Pair{ + int x; + int y; + Pair(int x, int y){ + this.x=x; + this.y=y; + } + } + public int numIslands(char[][] grid) { + int result=0; + //i-1,j i+1,j i,j-1 j,j+1 + int[][] directions= new int[][]{{-1,0},{1,0},{0,-1},{0,1}}; + for(int i=0;i queue= new ArrayDeque<>(); + queue.offer(root); + while(!queue.isEmpty()){ + Pair temp= queue.poll(); + for(int[] dir: directions){ + + int x= temp.x+dir[0]; + int y= temp.y+dir[1]; + if(isvalid(grid,x,y)){ + grid[x][y]='0'; + queue.offer(new Pair(x,y)); + } + } + } + } + + public boolean isvalid(char[][] grid,int x, int y){ + if(x<0 || x>=grid.length || y<0 || y>=grid[0].length || grid[x][y]=='0') return false; + return true; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MeetingRoomsII.java b/src/geeksforgeeks/MeetingRoomsII.java new file mode 100644 index 0000000..7998378 --- /dev/null +++ b/src/geeksforgeeks/MeetingRoomsII.java @@ -0,0 +1,22 @@ +package geeksforgeeks; + +public class MeetingRoomsII { + /** + * @param intervals: an array of meeting time intervals + * @return: the minimum number of conference rooms required + */ + public int minMeetingRooms(List intervals) { + if(intervals==null || intervals.size()==0) return -1; + + Collections.sort(intervals,(a,b)->Integer.compare(a.start,b.start)); + PriorityQueue queue= new PriorityQueue<>(); + //Interval max= intervals.get(0); + queue.offer(intervals.get(0).end); + for(int i=1;i> partition(String s) { + List> result= new ArrayList<>(); + if(s==null || s.length()==0) return result; + + backtrackingUtil(s, result, new ArrayList()); + + return result; + + } + + public void backtrackingUtil(String s, List> result, List tempList){ + if(s==null || s.length()==0){ + result.add(new ArrayList<>(tempList)); + return; + } + + for(int i=1;i<=s.length();i++){ + String temp= s.substring(0,i); + if(isPalin(temp)){ + tempList.add(temp); + backtrackingUtil(s.substring(i,s.length()),result,tempList); + tempList.remove(tempList.size()-1); + } + } + + } + + public boolean isPalin(String s){ + int start=0; + int end= s.length()-1; + while(start<=end){ + if(s.charAt(start)!=s.charAt(end)) return false; + start++; + end--; + } + return true; + } + + public static void main(String[] args) { + new PalindromePartion().partition("aab"); + } + + +} \ No newline at end of file diff --git a/src/geeksforgeeks/PascalsTriangle.java b/src/geeksforgeeks/PascalsTriangle.java new file mode 100644 index 0000000..741b065 --- /dev/null +++ b/src/geeksforgeeks/PascalsTriangle.java @@ -0,0 +1,17 @@ +package geeksforgeeks; + +public class PascalsTriangle { + public List> generate(int numRows) { + + List> allrows = new ArrayList>(); + ArrayList row = new ArrayList(); + for (int i = 0; i < numRows; i++) { + row.add(0, 1); // append 1 at the end of each iteration + for (int j = 1; j < row.size() - 1; j++) + row.set(j, row.get(j) + row.get(j + 1)); // modify after adding 1 + allrows.add(new ArrayList(row));// take a copy of row and save it in result + } + return allrows; + + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/PreOrderInOrderTree.java b/src/geeksforgeeks/PreOrderInOrderTree.java new file mode 100644 index 0000000..4376269 --- /dev/null +++ b/src/geeksforgeeks/PreOrderInOrderTree.java @@ -0,0 +1,31 @@ +package geeksforgeeks; + +class PreOrderInOrderTree { + public TreeNode buildTree(int[] preorder, int[] inorder) { + Map map= new HashMap<>(); + List set= new ArrayList<>(); + + for(int i=0;i map, List set,int start,int end){ + if(start>end) return null; + if(set.isEmpty()) return null; + int rootval= set.get(0); + set.remove(0); + TreeNode root= new TreeNode(rootval); + int inorderIndex= map.get(rootval); + root.left=buildTreeUtil(map,set,start,inorderIndex-1); + root.right=buildTreeUtil(map,set,inorderIndex+1,end); + return root; + } +} \ No newline at end of file From 99b214ff02e24581f9a539e52c26538be0d8cf75 Mon Sep 17 00:00:00 2001 From: Thangaraj A Date: Tue, 31 Dec 2019 18:02:47 +0530 Subject: [PATCH 15/51] Added leetcode problems --- src/geeksforgeeks/BuyAndSellStockAnytime.java | 23 ++++++ .../ConstructTreeFromInorderAndPreorder.java | 35 +++++++++ src/geeksforgeeks/FourSum.java | 41 +++++++++++ src/geeksforgeeks/GameOfLife.java | 66 +++++++++++++++++ src/geeksforgeeks/HappyNumber.java | 28 ++++++++ src/geeksforgeeks/IntersectionOfArrays.java | 44 ++++++++++++ src/geeksforgeeks/MajorityVoting.java | 54 ++++++++------ src/geeksforgeeks/MergeTwoLinkedList.java | 46 ++++++++++++ src/geeksforgeeks/MoveZeroes.java | 30 ++++++++ src/geeksforgeeks/NumberOfBallons.java | 6 +- src/geeksforgeeks/PhoneLetterCombination.java | 33 +++++++++ src/geeksforgeeks/RailwayPlatformProblem.java | 39 +++++++++- src/geeksforgeeks/RotateMatrixInPlace.java | 72 ------------------- .../RotateMatrixInPlaceAntiClockwise.java | 63 ++++++++++++++++ src/geeksforgeeks/SetBitCount.java | 21 ++++++ src/geeksforgeeks/ShuffleArray.java | 47 ++++++++++++ src/geeksforgeeks/SymmetricTree.java | 21 ++++++ src/geeksforgeeks/TopKFrequentElements.java | 38 ++++++++++ src/geeksforgeeks/TreasureIsland.java | 44 ++++++------ src/geeksforgeeks/Twitter.java | 23 +++--- src/geeksforgeeks/UniquePath.java | 5 +- src/geeksforgeeks/UniquePathMaximum.java | 22 ++++-- src/geeksforgeeks/ValidPalindromeII.java | 15 +++- src/geeksforgeeks/ValidSudoku.java | 37 ++++++++++ src/geeksforgeeks/VulgarDecimal.java | 28 ++++---- 25 files changed, 727 insertions(+), 154 deletions(-) create mode 100644 src/geeksforgeeks/BuyAndSellStockAnytime.java create mode 100644 src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java create mode 100644 src/geeksforgeeks/FourSum.java create mode 100644 src/geeksforgeeks/GameOfLife.java create mode 100644 src/geeksforgeeks/HappyNumber.java create mode 100644 src/geeksforgeeks/IntersectionOfArrays.java create mode 100644 src/geeksforgeeks/MergeTwoLinkedList.java create mode 100644 src/geeksforgeeks/MoveZeroes.java create mode 100644 src/geeksforgeeks/PhoneLetterCombination.java delete mode 100644 src/geeksforgeeks/RotateMatrixInPlace.java create mode 100644 src/geeksforgeeks/RotateMatrixInPlaceAntiClockwise.java create mode 100644 src/geeksforgeeks/SetBitCount.java create mode 100644 src/geeksforgeeks/ShuffleArray.java create mode 100644 src/geeksforgeeks/SymmetricTree.java create mode 100644 src/geeksforgeeks/TopKFrequentElements.java create mode 100644 src/geeksforgeeks/ValidSudoku.java diff --git a/src/geeksforgeeks/BuyAndSellStockAnytime.java b/src/geeksforgeeks/BuyAndSellStockAnytime.java new file mode 100644 index 0000000..ffbe021 --- /dev/null +++ b/src/geeksforgeeks/BuyAndSellStockAnytime.java @@ -0,0 +1,23 @@ +package geeksforgeeks; + +/** + * https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ + */ +public class BuyAndSellStockAnytime { + + public int maxProfit(int[] prices) { + int total = 0; + for (int i = 0; i < prices.length - 1; i++) { + if (prices[i + 1] > prices[i]) { + total += prices[i + 1] - prices[i]; + } + } + return total; + } + + public static void main(String[] args) { + BuyAndSellStockAnytime stock = new BuyAndSellStockAnytime(); + int[] arr = { 7, 1, 5, 6, 4 }; + stock.maxProfit(arr); + } +} diff --git a/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java b/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java new file mode 100644 index 0000000..ac4e991 --- /dev/null +++ b/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java @@ -0,0 +1,35 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +class ConstructTreeFromInorderAndPreorder { + public TreeNode buildTree(int[] preorder, int[] inorder) { + Map inMap = new HashMap<>(); + for (int i = 0; i < inorder.length; i++) { + inMap.put(inorder[i], i); + } + ArrayList pre = new ArrayList<>(); + for (int i = 0; i < preorder.length; i++) { + pre.add(preorder[i]); + } + TreeNode root = buildTree(pre, 0, inorder.length - 1, inMap); + return root; + } + + public TreeNode buildTree(ArrayList pre, int inStart, int inEnd, Map inMap) { + if (inStart > inEnd) { + return null; + } + + TreeNode root = new TreeNode(pre.get(0)); + int inRoot = inMap.get(root.val); + pre.remove(0); + + root.left = buildTree(pre, inStart, inRoot - 1, inMap); + root.right = buildTree(pre, inRoot + 1, inEnd, inMap); + + return root; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/FourSum.java b/src/geeksforgeeks/FourSum.java new file mode 100644 index 0000000..96a925c --- /dev/null +++ b/src/geeksforgeeks/FourSum.java @@ -0,0 +1,41 @@ +package geeksforgeeks; + +import java.util.HashMap; +import java.util.Map; + +/** + * https://leetcode.com/problems/4sum-ii/ + */ +public class FourSum { + + public int fourSumCount(int[] A, int[] B, int[] C, int[] D) { + Map sums = new HashMap<>(); + int count = 0; + for (int i = 0; i < A.length; i++) { + for (int j = 0; j < B.length; j++) { + int sum = A[i] + B[j]; + sums.put(sum, sums.getOrDefault(sum, 0) + 1); + + } + } + for (int k = 0; k < A.length; k++) { + for (int z = 0; z < C.length; z++) { + int sum = -(C[k] + D[z]); + if (sums.containsKey(sum)) { + count += sums.get(sum); + } + } + } + return count; + } + + public static void main(String[] args) { + int[] A = { 1, 2 }; + int[] B = { -2, -1 }; + int[] C = { -1, 2 }; + int[] D = { 0, 2 }; + + FourSum fs = new FourSum(); + fs.fourSumCount(A, B, C, D); + } +} diff --git a/src/geeksforgeeks/GameOfLife.java b/src/geeksforgeeks/GameOfLife.java new file mode 100644 index 0000000..cca3480 --- /dev/null +++ b/src/geeksforgeeks/GameOfLife.java @@ -0,0 +1,66 @@ +package geeksforgeeks; + +import java.util.Arrays; + +/** + * https://forum.letstalkalgorithms.com/t/game-of-life/516/2 + */ +public class GameOfLife { + + int[][] c = { { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, -1 }, { 0, 1 }, { 1, -1 }, { 1, 0 }, { 1, 1 } }; + + int die = 2; + int live = 3; + + void gameOfLife(int[][] board) { + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + int neighbors = getLiveNeigborCount(board, i, j); + if (board[i][j] == 0 && neighbors == 3) { + board[i][j] = live; + } else if (board[i][j] == 1) { + if (neighbors == 2 || neighbors == 3) { + continue; + } + if (neighbors < 2 || neighbors > 3) { + board[i][j] = die; + } + } + } + } + + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (board[i][j] == die) { + board[i][j] = 0; + } else if (board[i][j] == live) { + board[i][j] = 1; + } + } + } + } + + int getLiveNeigborCount(int[][] board, int i, int j) { + + int count = 0; + for (int m = 0; m < board.length; m++) { + int mx = c[m][0] + i; + int my = c[m][1] + j; + if (mx >= 0 && my >= 0 && mx < board.length && my < board[0].length) { + if (board[mx][my] == 1 || board[mx][my] == die) { + count++; + } + } + } + return count; + } + + public static void main(String[] args) { + GameOfLife gol = new GameOfLife(); + int[][] arr = { { 0, 1, 0 }, { 0, 0, 1 }, { 1, 1, 1 }, { 0, 0, 0 } }; + System.out.println(Arrays.deepToString(arr)); + gol.gameOfLife(arr); + + System.out.println(Arrays.deepToString(arr)); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/HappyNumber.java b/src/geeksforgeeks/HappyNumber.java new file mode 100644 index 0000000..c8af4a7 --- /dev/null +++ b/src/geeksforgeeks/HappyNumber.java @@ -0,0 +1,28 @@ +package geeksforgeeks; + +import java.util.HashSet; +import java.util.Set; + +class HappyNumber { + public boolean isHappy(int n) { + + Set set = new HashSet<>(); + int sum = String.valueOf(n).chars().map(Character::getNumericValue).map(val -> val * val).sum() == 1 ? 1 : n; + while (true) { + if (sum == 1) { + return true; + } + sum = String.valueOf(sum).chars().map(Character::getNumericValue).map(val -> val * val).sum(); + if (set.contains(sum)) { + return false; + } + + set.add(sum); + } + } + + public static void main(String[] args) { + HappyNumber hn = new HappyNumber(); + System.out.println(hn.isHappy(19)); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/IntersectionOfArrays.java b/src/geeksforgeeks/IntersectionOfArrays.java new file mode 100644 index 0000000..a0dad5c --- /dev/null +++ b/src/geeksforgeeks/IntersectionOfArrays.java @@ -0,0 +1,44 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * https://leetcode.com/problems/intersection-of-two-arrays-ii/discuss/82241/AC-solution-using-Java-HashMap + *

+ * Example 1: + *

+ * Input: nums1 = [1,2,2,1], nums2 = [2,2] + * Output: [2,2] + * Example 2: + *

+ * Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] + * Output: [4,9] + */ +public class IntersectionOfArrays { + public int[] intersect(int[] nums1, int[] nums2) { + HashMap map = new HashMap<>(); + ArrayList result = new ArrayList<>(); + for (int i = 0; i < nums1.length; i++) { + if (map.containsKey(nums1[i])) { + map.put(nums1[i], map.get(nums1[i]) + 1); + } else { + map.put(nums1[i], 1); + } + } + + for (int i = 0; i < nums2.length; i++) { + if (map.containsKey(nums2[i]) && map.get(nums2[i]) > 0) { + result.add(nums2[i]); + map.put(nums2[i], map.get(nums2[i]) - 1); + } + } + + int[] r = new int[result.size()]; + for (int i = 0; i < result.size(); i++) { + r[i] = result.get(i); + } + + return r; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MajorityVoting.java b/src/geeksforgeeks/MajorityVoting.java index d857bdb..d53cfa0 100644 --- a/src/geeksforgeeks/MajorityVoting.java +++ b/src/geeksforgeeks/MajorityVoting.java @@ -7,24 +7,25 @@ public class MajorityVoting { public static List majorityElementII(int[] nums) { - if (nums == null || nums.length == 0) + if (nums == null || nums.length == 0) { return new ArrayList<>(); + } List result = new ArrayList<>(); - int number1 = nums[0]; - int number2 = nums[0]; + int candidate1 = nums[0]; + int candidate2 = nums[0]; int count1 = 0; int count2 = 0; int len = nums.length; for (int i = 0; i < len; i++) { - if (nums[i] == number1) + if (nums[i] == candidate1) { count1++; - else if (nums[i] == number2) + } else if (nums[i] == candidate2) { count2++; - else if (count1 == 0) { - number1 = nums[i]; + } else if (count1 == 0) { + candidate1 = nums[i]; count1 = 1; } else if (count2 == 0) { - number2 = nums[i]; + candidate2 = nums[i]; count2 = 1; } else { count1--; @@ -34,29 +35,38 @@ else if (count1 == 0) { count1 = 0; count2 = 0; for (int i = 0; i < len; i++) { - if (nums[i] == number1) + if (nums[i] == candidate1) { count1++; - else if (nums[i] == number2) + } else if (nums[i] == candidate2) { count2++; + } + } + if (count1 > len / 3) { + result.add(candidate1); + } + if (count2 > len / 3) { + result.add(candidate2); } - if (count1 > len / 3) - result.add(number1); - if (count2 > len / 3) - result.add(number2); return result; } public static int majorityElementI(int[] nums) { - int count = 0; - int candidate = 0; + int count = 1; + int candidate = nums[0]; int majority = nums.length / 2; - for (int num : nums) { + for (int i = 1; i < nums.length; i++) { if (count == 0) { - candidate = num; + count++; + candidate = nums[i]; + } else if (candidate == nums[i]) { + count++; + } else { + count--; } - count += (num == candidate) ? 1 : -1; + } + count = 0; for (int num : nums) { if (num == candidate) { @@ -68,9 +78,13 @@ public static int majorityElementI(int[] nums) { } public static void main(String[] args) { - int[] arr = {1, 1, 1, 1, 1, 2, 2, 4, 4, 4, 4, 4, 2, 2}; + int[] arr = { 1, 1, 1, 1, 1, 2, 2, 4, 4, 4, 4, 4, 2, 2 }; System.out.println(majorityElementI(arr)); System.out.println(majorityElementII(arr)); + + } + + } diff --git a/src/geeksforgeeks/MergeTwoLinkedList.java b/src/geeksforgeeks/MergeTwoLinkedList.java new file mode 100644 index 0000000..3d4912a --- /dev/null +++ b/src/geeksforgeeks/MergeTwoLinkedList.java @@ -0,0 +1,46 @@ +package geeksforgeeks; + +/** + * @author i312458 + */ +public class MergeTwoLinkedList { + + public static ListNode mergeTwoLists(ListNode l1, ListNode l2) { + if (l1 == null) { + return l2; + } else if (l2 == null) { + return l1; + } + ListNode dummy = new ListNode(0); + ListNode curr = dummy; + while (l1 != null && l2 != null) { + if (l1.val <= l2.val) { + curr.next = l1; + l1 = l1.next; + } else { + curr.next = l2; + l2 = l2.next; + } + curr = curr.next; + } + curr.next = l1 == null ? l2 : l1; + return dummy.next; + } + + public static void main(String[] args) { + ListNode l1 = new ListNode(1); + l1.next = new ListNode(2); + l1.next.next = new ListNode(3); + l1.next.next.next = new ListNode(4); + + ListNode l2 = new ListNode(1); +// l2.next = new ListNode(7); + + ListNode head = mergeTwoLists(l1, l2); + + while (head != null) { + System.out.println(head.val); + head = head.next; + } + } +} diff --git a/src/geeksforgeeks/MoveZeroes.java b/src/geeksforgeeks/MoveZeroes.java new file mode 100644 index 0000000..307f5ac --- /dev/null +++ b/src/geeksforgeeks/MoveZeroes.java @@ -0,0 +1,30 @@ +package geeksforgeeks; + +import java.util.Arrays; + +class MoveZeroes { + + public static void main(String[] args) { + MoveZeroes mz = new MoveZeroes(); + int[] arr = { 0, 1, 0, 3, 12 }; + mz.moveZeroes(arr); + System.out.println(Arrays.toString(arr)); + } + + public void moveZeroes(int[] nums) { + if (nums == null || nums.length == 0) { + return; + } + + int insertPos = 0; + for (int num : nums) { + if (num != 0) { + nums[insertPos++] = num; + } + } + + while (insertPos < nums.length) { + nums[insertPos++] = 0; + } + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/NumberOfBallons.java b/src/geeksforgeeks/NumberOfBallons.java index cbb05eb..1923824 100644 --- a/src/geeksforgeeks/NumberOfBallons.java +++ b/src/geeksforgeeks/NumberOfBallons.java @@ -5,7 +5,7 @@ */ public class NumberOfBallons { - public int maxNumberOfBalloons(String text) { + public static int maxNumberOfBalloons(String text) { int[] chars = new int[26]; //count all letters for (char c : text.toCharArray()) { chars[c - 'a']++; @@ -17,4 +17,8 @@ public int maxNumberOfBalloons(String text) { min = Math.min(min, chars[13]);//for n return min; } + + public static void main(String[] args) { + maxNumberOfBalloons("llonbioan"); + } } diff --git a/src/geeksforgeeks/PhoneLetterCombination.java b/src/geeksforgeeks/PhoneLetterCombination.java new file mode 100644 index 0000000..e619898 --- /dev/null +++ b/src/geeksforgeeks/PhoneLetterCombination.java @@ -0,0 +1,33 @@ +package geeksforgeeks; + +import java.util.LinkedList; +import java.util.List; + +/** + * https://leetcode.com/problems/letter-combinations-of-a-phone-number/discuss/8064/My-java-solution-with-FIFO-queue + */ +public class PhoneLetterCombination { + + public List letterCombinations(String digits) { + LinkedList ans = new LinkedList<>(); + if (digits.isEmpty()) { + return ans; + } + String[] mapping = { "0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; + ans.add(""); + for (int i = 0; i < digits.length(); i++) { + int x = Character.getNumericValue(digits.charAt(i)); + while (ans.peek().length() == i) { + String t = ans.remove(); + for (char s : mapping[x].toCharArray()) + ans.add(t + s); + } + } + return ans; + } + + public static void main(String[] args) { + PhoneLetterCombination plc = new PhoneLetterCombination(); + plc.letterCombinations("23"); + } +} diff --git a/src/geeksforgeeks/RailwayPlatformProblem.java b/src/geeksforgeeks/RailwayPlatformProblem.java index 60fadd4..bad5b47 100644 --- a/src/geeksforgeeks/RailwayPlatformProblem.java +++ b/src/geeksforgeeks/RailwayPlatformProblem.java @@ -1,6 +1,9 @@ package geeksforgeeks; import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.PriorityQueue; /** * https://www.geeksforgeeks.org/minimum-number-platforms-required-railwaybus-station/ @@ -21,8 +24,9 @@ static int findPlatform(int[] arrival, int[] departure, int n) { platNeeded++; i++; - if (platNeeded > result) + if (platNeeded > result) { result = platNeeded; + } } else { platNeeded--; j++; @@ -31,13 +35,42 @@ static int findPlatform(int[] arrival, int[] departure, int n) { return result; } + public int minMeetingRooms(List intervals) { + if (intervals == null || intervals.size() == 0) { + return -1; + } + //[(0,12),(5,10),(15,20)] + + Collections.sort(intervals, (a, b) -> Integer.compare(a.start, b.start)); + PriorityQueue queue = new PriorityQueue<>(); + queue.offer(intervals.get(0).end); + for (int i = 1; i < intervals.size(); i++) { + Interval temp = intervals.get(i); + if (queue.peek() <= temp.start) { + queue.poll(); + } + queue.offer(temp.end); + } + return queue.size(); + } + public static void main(String[] args) { - int[] arr = {900, 940, 950, 1100, 1500, 1800}; - int[] dep = {910, 1200, 1120, 1130, 1900, 2000}; + int[] arr = { 900, 940, 950, 1100, 1500, 1800 }; + int[] dep = { 910, 1200, 1120, 1130, 1900, 2000 }; int n = arr.length; System.out.println("Minimum Number of Platforms Required = " + findPlatform(arr, dep, n)); } + class Interval { + int start, end; + + Interval(int start, int end) { + this.start = start; + this.end = end; + } + } + } + diff --git a/src/geeksforgeeks/RotateMatrixInPlace.java b/src/geeksforgeeks/RotateMatrixInPlace.java deleted file mode 100644 index 950813b..0000000 --- a/src/geeksforgeeks/RotateMatrixInPlace.java +++ /dev/null @@ -1,72 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/inplace-rotate-square-matrix-by-90-degrees/ - */ -// looking for easy solution -class RotateMatrixInPlace { - - /** - * N/2 for time complexity o(n) - *

- * get all the corners first and swap ( rotate 90 degree) - * - * @param N - * @param mat - */ - static void rotateMatrix(int N, int mat[][]) { - // Consider all squares one by one - for (int x = 0; x < N / 2; x++) { - // Consider elements in group of 4 in - // current square - for (int y = x; y < N - x - 1; y++) { - // store current cell in temp variable - System.out.println("mat[" + x + "][" + y + "] = " + mat[x][y]); - int temp = mat[x][y]; - - // move values from right to top - System.out.println("mat[" + y + "][" + (N - 1 - x) + "] = " + mat[y][N - 1 - x]); - mat[x][y] = mat[y][N - 1 - x]; - - // move values from bottom to right - System.out.println("mat[" + (N - 1 - x) + "][" + (N - 1 - y) + "] = " + mat[N - 1 - x][N - 1 - y]); - mat[y][N - 1 - x] = mat[N - 1 - x][N - 1 - y]; - - // move values from left to bottom - System.out.println("mat[" + (N - 1 - y) + "][" + (x) + "] = " + mat[N - 1 - y][x]); - mat[N - 1 - x][N - 1 - y] = mat[N - 1 - y][x]; - - // assign temp to left - System.out.println("mat[" + (N - 1 - y) + "][" + (x) + "] = " + temp); - mat[N - 1 - y][x] = temp; - } - } - } - - static void displayMatrix(int N, int mat[][]) { - for (int i = 0; i < N; i++) { - for (int j = 0; j < N; j++) - System.out.print(" " + mat[i][j]); - - System.out.print("\n"); - } - System.out.print("\n"); - } - - public static void main(String[] args) { - int N = 4; - - // Test Case 1 - int mat[][] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}; - - // int mat[][] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; - // int mat[][] = { {1, 2}, {4, 5} }; - - // displayMatrix(mat); - - rotateMatrix(N, mat); - - // Print rotated matrix - displayMatrix(N, mat); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/RotateMatrixInPlaceAntiClockwise.java b/src/geeksforgeeks/RotateMatrixInPlaceAntiClockwise.java new file mode 100644 index 0000000..c74c661 --- /dev/null +++ b/src/geeksforgeeks/RotateMatrixInPlaceAntiClockwise.java @@ -0,0 +1,63 @@ +package geeksforgeeks; + +/** + * https://www.geeksforgeeks.org/inplace-rotate-square-matrix-by-90-degrees/ + *

+ * https://leetcode.com/problems/rotate-image/discuss/298719/A-Java-one-pass-solution-with-detailed-explanation + *

+ * //x,y1=x2,y2 + * // x1=y2 + */ +class RotateMatrixInPlaceAntiClockwise { + + static void rotateMatrix(int N, int mat[][]) { + + for (int x = 0; x < N / 2; x++) { + + for (int y = x; y < N - x; y++) { + + // store current cell in temp variable + int temp = mat[x][y]; + + // move values from right to top + mat[x][y] = mat[y][N - x]; + + // move values from bottom to right + mat[y][N - x] = mat[N - x][N - y]; + + // move values from left to bottom + mat[N - x][N - y] = mat[N - y][x]; + + // assign temp to left + mat[N - y][x] = temp; + } + } + } + + static void displayMatrix(int N, int mat[][]) { + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) + System.out.print(" " + mat[i][j]); + + System.out.print("\n"); + } + System.out.print("\n"); + } + + public static void main(String[] args) { + int N = 4; + + // Test Case 1 + int mat[][] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } }; + + // int mat[][] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; + // int mat[][] = { {1, 2}, {4, 5} }; + + // displayMatrix(mat); + + rotateMatrix(N - 1, mat); + + // Print rotated matrix + displayMatrix(N, mat); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/SetBitCount.java b/src/geeksforgeeks/SetBitCount.java new file mode 100644 index 0000000..2e056d3 --- /dev/null +++ b/src/geeksforgeeks/SetBitCount.java @@ -0,0 +1,21 @@ +package geeksforgeeks; + +/** + * https://leetcode.com/problems/number-of-1-bits/discuss/55099/Simple-Java-Solution-Bit-Shifting + */ +public class SetBitCount { + public int hammingWeight(int n) { + int count = 0; + + while (n != 0) { + n = n & (n - 1); + count++; + } + + return count; + } + + public static void main(String[] args) { + + } +} diff --git a/src/geeksforgeeks/ShuffleArray.java b/src/geeksforgeeks/ShuffleArray.java new file mode 100644 index 0000000..e052c5d --- /dev/null +++ b/src/geeksforgeeks/ShuffleArray.java @@ -0,0 +1,47 @@ +package geeksforgeeks; + +import java.util.Random; + +public class ShuffleArray { + private int[] nums; + private Random random; + + public ShuffleArray(int[] nums) { + this.nums = nums; + random = new Random(); + } + + /** + * Resets the array to its original configuration and return it. + */ + public int[] reset() { + return nums; + } + + /** + * Returns a random shuffling of the array. + */ + public int[] shuffle() { + if (nums == null) { + return null; + } + int[] a = nums.clone(); + for (int j = 1; j < a.length; j++) { + int i = random.nextInt(j + 1); + swap(a, i, j); + } + return a; + } + + private void swap(int[] a, int i, int j) { + int t = a[i]; + a[i] = a[j]; + a[j] = t; + } + + public static void main(String[] args) { + int[] arr = { 1, 2, 3 }; + ShuffleArray sa = new ShuffleArray(arr); + sa.shuffle(); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/SymmetricTree.java b/src/geeksforgeeks/SymmetricTree.java new file mode 100644 index 0000000..8ef690c --- /dev/null +++ b/src/geeksforgeeks/SymmetricTree.java @@ -0,0 +1,21 @@ +package geeksforgeeks; + +class SymmetricTree { + public boolean isSymmetric(TreeNode root) { + if (root == null) { + return true; + } + + return isSymmetricHelp(root.left, root.right); + } + + private boolean isSymmetricHelp(TreeNode left, TreeNode right) { + if (left == null || right == null) { + return left == right; + } + if (left.val != right.val) { + return false; + } + return isSymmetricHelp(left.left, right.right) && isSymmetricHelp(left.right, right.left); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/TopKFrequentElements.java b/src/geeksforgeeks/TopKFrequentElements.java new file mode 100644 index 0000000..9084b2d --- /dev/null +++ b/src/geeksforgeeks/TopKFrequentElements.java @@ -0,0 +1,38 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * https://leetcode.com/problems/top-k-frequent-elements/discuss/445815/Java8-Lambda-solution-3-lines-code + */ +public class TopKFrequentElements { + + public List topKFrequent(int[] nums, int k) { + if (nums.length == 0) { + return Collections.emptyList(); + } + + PriorityQueue> pq = new PriorityQueue<>( + (obj1, obj2) -> obj2.getValue() - obj1.getValue()); + Map map = new HashMap<>(); + + for (int i : nums) { + map.put(i, map.getOrDefault(i, 0) + 1); + } + + for (Map.Entry mapEntry : map.entrySet()) { + pq.add(mapEntry); + } + + List result = new ArrayList<>(); + for (int i = 0; i < k; i++) { + result.add(pq.remove().getKey()); + } + return result; + } +} diff --git a/src/geeksforgeeks/TreasureIsland.java b/src/geeksforgeeks/TreasureIsland.java index 1230d8f..4f87ea9 100644 --- a/src/geeksforgeeks/TreasureIsland.java +++ b/src/geeksforgeeks/TreasureIsland.java @@ -5,26 +5,25 @@ // https://leetcode.com/discuss/interview-question/347457/Amazon-or-OA-2019-or-Treasure-Island public class TreasureIsland { - private static final int[][] DIRS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + private static final int[][] DIRS = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } }; public static int minSteps(char[][] grid) { Queue q = new LinkedList<>(); - q.add(new Point(0, 0)); - grid[0][0] = 'D'; // mark as visited - for (int steps = 1; !q.isEmpty(); steps++) { - for (int sz = q.size(); sz > 0; sz--) { - Point p = q.poll(); - - for (int[] dir : DIRS) { - int r = p.r + dir[0]; - int c = p.c + dir[1]; - - if (isSafe(grid, r, c)) { - if (grid[r][c] == 'X') - return steps; - grid[r][c] = 'D'; - q.add(new Point(r, c)); + q.add(new Point(0, 0, 0)); + grid[0][0] = 'D'; + while (!q.isEmpty()) { + Point p = q.poll(); + + for (int[] dir : DIRS) { + int r = p.r + dir[0]; + int c = p.c + dir[1]; + + if (isSafe(grid, r, c)) { + if (grid[r][c] == 'X') { + return p.steps + 1; } + grid[r][c] = 'D'; + q.add(new Point(r, c, p.steps + 1)); } } } @@ -36,11 +35,14 @@ private static boolean isSafe(char[][] grid, int r, int c) { } private static class Point { - int r, c; + int r; + int c; + int steps; - Point(int r, int c) { + Point(int r, int c, int steps) { this.r = r; this.c = c; + this.steps = steps; } public String toString() { @@ -49,10 +51,8 @@ public String toString() { } public static void main(String[] args) { - char[][] grid = {{'O', 'O', 'O', 'O'}, - {'D', 'O', 'D', 'O'}, - {'O', 'O', 'O', 'O'}, - {'X', 'D', 'D', 'O'}}; + char[][] grid = { { 'O', 'O', 'O', 'O' }, { 'D', 'O', 'D', 'O' }, { 'O', 'O', 'O', 'O' }, + { 'X', 'D', 'D', 'O' } }; System.out.println(minSteps(grid)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/Twitter.java b/src/geeksforgeeks/Twitter.java index 7441e4e..92716f3 100644 --- a/src/geeksforgeeks/Twitter.java +++ b/src/geeksforgeeks/Twitter.java @@ -42,7 +42,6 @@ public void unfollow(int id) { followed.remove(id); } - // everytime user post a new tweet, add it to the head of tweet list. public void post(int id) { Tweet t = new Tweet(id); @@ -51,7 +50,6 @@ public void post(int id) { } } - /** * Initialize your data structure here. */ @@ -71,7 +69,6 @@ public void postTweet(int userId, int tweetId) { } - // Best part of this. // first get all tweets lists from one user including itself and all people it followed. // Second add all heads into a max heap. Every time we poll a tweet with @@ -79,15 +76,17 @@ public void postTweet(int userId, int tweetId) { // So after adding all heads we only need to add 9 tweets at most into this // heap before we get the 10 most recent tweet. public List getNewsFeed(int userId) { - List res = new LinkedList<>(); + List result = new LinkedList<>(); - if (!userMap.containsKey(userId)) return res; + if (!userMap.containsKey(userId)) { + return result; + } Set users = userMap.get(userId).followed; - PriorityQueue q = new PriorityQueue(users.size(), (a, b) -> (b.time - a.time)); + PriorityQueue q = new PriorityQueue<>(users.size(), (a, b) -> (b.time - a.time)); for (int user : users) { Tweet t = userMap.get(user).tweet_head; - // very imporant! If we add null to the head we are screwed. + // very important! If we add null to the head we are screwed. if (t != null) { q.add(t); } @@ -95,13 +94,14 @@ public List getNewsFeed(int userId) { int n = 0; while (!q.isEmpty() && n < 10) { Tweet t = q.poll(); - res.add(t.id); + result.add(t.id); n++; - if (t.next != null) + if (t.next != null) { q.add(t.next); + } } - return res; + return result; } @@ -124,8 +124,9 @@ public void follow(int followerId, int followeeId) { * Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ public void unfollow(int followerId, int followeeId) { - if (!userMap.containsKey(followerId) || followerId == followeeId) + if (!userMap.containsKey(followerId) || followerId == followeeId) { return; + } userMap.get(followerId).unfollow(followeeId); } diff --git a/src/geeksforgeeks/UniquePath.java b/src/geeksforgeeks/UniquePath.java index c022223..687525d 100644 --- a/src/geeksforgeeks/UniquePath.java +++ b/src/geeksforgeeks/UniquePath.java @@ -7,9 +7,7 @@ public class UniquePath { public static void main(String[] args) { System.out.println(uniquePathI(3, 2)); - int[][] matrix = {{0, 0, 0}, - {0, 1, 0}, - {0, 0, 0}}; + int[][] matrix = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } }; System.out.println(uniquePathII(matrix)); @@ -34,7 +32,6 @@ private static int uniquePathI(int row, int col) { return dp[row - 1][col - 1]; } - private static int uniquePathII(int[][] mat) { int[][] dp = new int[mat.length][mat[0].length]; for (int i = 0; i < mat[0].length; i++) { diff --git a/src/geeksforgeeks/UniquePathMaximum.java b/src/geeksforgeeks/UniquePathMaximum.java index ab7b7aa..ceef295 100644 --- a/src/geeksforgeeks/UniquePathMaximum.java +++ b/src/geeksforgeeks/UniquePathMaximum.java @@ -4,10 +4,25 @@ https://leetcode.com/discuss/interview-question/383669/ */ +/** + * find the maximum score of a path starting at [0, 0] and ending at [r-1, c-1]. The score of a path is the minimum value in that path. + *

+ * Input: + * [[1, 2, 3] + * [4, 5, 1]] + *

+ * Output: 4 + * Explanation: + * Possible paths: + * 1-> 2 -> 3 -> 1 + * 1-> 2 -> 5 -> 1 + * 1-> 4 -> 5 -> 1 + * So min of all the paths = [2, 2, 4]. Note that we don't include the first and final entry. + */ public class UniquePathMaximum { public static void main(String[] args) { - int[][] matrix = {{6, 7, 8}, {5, 4, 2}, {8, 7, 6}}; + int[][] matrix = { { 6, 7, 8 }, { 5, 4, 2 }, { 8, 7, 6 } }; System.out.println(findMaximumOfUniquePath(matrix)); } @@ -22,11 +37,10 @@ private static int findMaximumOfUniquePath(int[][] matrix) { for (int i = 1; i < matrix.length; i++) { for (int j = 1; j < matrix[i].length; j++) { - matrix[i][j] = Math.max(Math.min(matrix[i - 1][j], matrix[i][j]), Math.min(matrix[i][j - 1], matrix[i][j])); + matrix[i][j] = Math.max(Math.min(matrix[i - 1][j], matrix[i][j]), + Math.min(matrix[i][j - 1], matrix[i][j])); } } return matrix[matrix.length - 1][matrix[0].length - 1]; } - - } \ No newline at end of file diff --git a/src/geeksforgeeks/ValidPalindromeII.java b/src/geeksforgeeks/ValidPalindromeII.java index 6036c1a..84768c8 100644 --- a/src/geeksforgeeks/ValidPalindromeII.java +++ b/src/geeksforgeeks/ValidPalindromeII.java @@ -1,5 +1,8 @@ package geeksforgeeks; +/** + * https://leetcode.com/problems/valid-palindrome-ii/ + */ class ValidPalindromeII { public static boolean validPalindrome(String s) { @@ -9,9 +12,13 @@ public static boolean validPalindrome(String s) { j--; } - if (i >= j) return true; + if (i >= j) { + return true; + } - if (isPalindrome(s, i + 1, j) || isPalindrome(s, i, j - 1)) return true; + if (isPalindrome(s, i + 1, j) || isPalindrome(s, i, j - 1)) { + return true; + } return false; } @@ -20,7 +27,9 @@ private static boolean isPalindrome(String s, int i, int j) { if (s.charAt(i) == s.charAt(j)) { i++; j--; - } else return false; + } else { + return false; + } } return true; } diff --git a/src/geeksforgeeks/ValidSudoku.java b/src/geeksforgeeks/ValidSudoku.java new file mode 100644 index 0000000..e67d31d --- /dev/null +++ b/src/geeksforgeeks/ValidSudoku.java @@ -0,0 +1,37 @@ +package geeksforgeeks; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author i312458 + */ +public class ValidSudoku { + + public boolean isValidSudoku(char[][] board) { + Set seen = new HashSet(); + for (int i = 0; i < 9; ++i) { + for (int j = 0; j < 9; ++j) { + char number = board[i][j]; + if (number != '.') { + if (!seen.add(number + " in row " + i) || !seen.add(number + " in column " + j) || !seen.add( + number + " in block " + i / 3 + '-' + j / 3)) { + return false; + } + } + } + } + return true; + } + + public static void main(String[] args) { + char[][] board = { { '5', '3', '.', '.', '7', '.', '.', '.', '.' }, + { '6', '.', '.', '1', '9', '5', '.', '.', '.' }, { '.', '9', '8', '.', '.', '.', '.', '6', '.' }, + { '8', '.', '.', '.', '6', '.', '.', '.', '3' }, { '4', '.', '.', '8', '.', '3', '.', '.', '1' }, + { '7', '.', '.', '.', '2', '.', '.', '.', '6' }, { '.', '6', '.', '.', '.', '.', '2', '8', '.' }, + { '.', '.', '.', '4', '1', '9', '.', '.', '5' }, { '.', '.', '.', '.', '8', '.', '.', '7', '9' } }; + + ValidSudoku vs = new ValidSudoku(); + System.out.println(vs.isValidSudoku(board)); + } +} diff --git a/src/geeksforgeeks/VulgarDecimal.java b/src/geeksforgeeks/VulgarDecimal.java index 973665e..2ac9c7e 100644 --- a/src/geeksforgeeks/VulgarDecimal.java +++ b/src/geeksforgeeks/VulgarDecimal.java @@ -6,33 +6,33 @@ public class VulgarDecimal { - public static String fractionToDecimal(long num, long den) { - if (num == 0) { + public static String fractionToDecimal(long numerator, long denominator) { + if (numerator == 0) { return "0"; } StringBuilder result = new StringBuilder(); - result.append(((num > 0) ^ (den > 0)) ? "-" : ""); - result.append(num / den); - num %= den; - if (num == 0) { + result.append(((numerator < 0) || (denominator < 0)) ? "-" : ""); + result.append(numerator / denominator); + numerator %= denominator; + if (numerator == 0) { return result.toString(); } result.append("."); HashMap map = new HashMap<>(); - map.put(num, result.length()); - while (num != 0) { - num *= 10; - result.append(num / den); - num %= den; - if (map.containsKey(num)) { - int index = map.get(num); + map.put(numerator, result.length()); + while (numerator != 0) { + numerator *= 10; + result.append(numerator / denominator); + numerator %= denominator; + if (map.containsKey(numerator)) { + int index = map.get(numerator); result.insert(index, "("); result.append(")"); break; } else { - map.put(num, result.length()); + map.put(numerator, result.length()); } } return result.toString(); From 9ffb03c1e7e84ce18cb3b1f396a7aa63230223b3 Mon Sep 17 00:00:00 2001 From: vignesh Date: Mon, 6 Jan 2020 22:24:35 +0530 Subject: [PATCH 16/51] new problem set --- src/geeksforgeeks/CourseSchedule.java | 35 ++++++++++ src/geeksforgeeks/LIS2DMatrix.java | 54 +++++++++++++++ .../LongestConsequtiveSequence.java | 31 +++++++++ src/geeksforgeeks/MinimumStack.java | 39 +++++++++++ src/geeksforgeeks/Trie.java | 65 +++++++++++++++++++ 5 files changed, 224 insertions(+) create mode 100644 src/geeksforgeeks/CourseSchedule.java create mode 100644 src/geeksforgeeks/LIS2DMatrix.java create mode 100644 src/geeksforgeeks/LongestConsequtiveSequence.java create mode 100644 src/geeksforgeeks/Trie.java diff --git a/src/geeksforgeeks/CourseSchedule.java b/src/geeksforgeeks/CourseSchedule.java new file mode 100644 index 0000000..3bd531b --- /dev/null +++ b/src/geeksforgeeks/CourseSchedule.java @@ -0,0 +1,35 @@ +package geeksforgeeks; + +class CourseSchedule { + public boolean canFinish(int numCourses, int[][] prerequisites) { + + Map> map= new HashMap<>(); // Courses that depend on the key + int[] degrees= new int[numCourses]; // # of prerequisites for course i + Queue queue= new ArrayDeque<>(); // Used to find dependants and decrease their outdegree + + for(int[] pre: prerequisites){ + List tempList= map.getOrDefault(pre[1],new ArrayList<>()); + tempList.add(pre[0]); + degrees[pre[0]]++; + map.put(pre[1],tempList); + } + + for(int i=0;i=matrix.length || j<0 || j>=matrix[0].length|| data>=matrix[i][j]) return 0; + + + + if(cache[i][j]!=null) return cache[i][j]; + + int max=1; + + for(int[] dir: dirs){ + + int x=i+dir[0]; + int y=j+dir[1]; + + int count=1+dfsUtil(matrix,x,y,cache, matrix[i][j]); + max=Math.max(count,max); + } + cache[i][j]=max; + + return cache[i][j]; + + } + + +} \ No newline at end of file diff --git a/src/geeksforgeeks/LongestConsequtiveSequence.java b/src/geeksforgeeks/LongestConsequtiveSequence.java new file mode 100644 index 0000000..09b3a20 --- /dev/null +++ b/src/geeksforgeeks/LongestConsequtiveSequence.java @@ -0,0 +1,31 @@ +package geeksforgeeks; + +class LongestConsequtiveSequence { + public int longestConsecutive(int[] nums) { + if(nums.length==0) return 0; + int max=1; + Set set= new HashSet<>(); + for(int i: nums){ + set.add(i); + } + + for(Integer i: nums){ + int num=i; + int count=1; + // looking left; + while(set.contains(--num)){ + count++; + set.remove(num); + } + num=i; + while(set.contains(++num)){ + count++; + set.remove(num); + } + + max=Math.max(max,count); + } + + return max; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MinimumStack.java b/src/geeksforgeeks/MinimumStack.java index 7510a6d..4b7eaca 100644 --- a/src/geeksforgeeks/MinimumStack.java +++ b/src/geeksforgeeks/MinimumStack.java @@ -84,4 +84,43 @@ public static void main(String[] args) { s.pop(); s.peek(); } +} + +class MinStack { + private Node head; + + public void push(int x) { + if(head == null) + head = new Node(x, x); + else + head = new Node(x, Math.min(x, head.min), head); + } + + public void pop() { + head = head.next; + } + + public int top() { + return head.val; + } + + public int getMin() { + return head.min; + } + + private class Node { + int val; + int min; + Node next; + + private Node(int val, int min) { + this(val, min, null); + } + + private Node(int val, int min, Node next) { + this.val = val; + this.min = min; + this.next = next; + } + } } \ No newline at end of file diff --git a/src/geeksforgeeks/Trie.java b/src/geeksforgeeks/Trie.java new file mode 100644 index 0000000..3483d59 --- /dev/null +++ b/src/geeksforgeeks/Trie.java @@ -0,0 +1,65 @@ +package geeksforgeeks; + +class Trie { + + class TrieNode{ + char data; + TrieNode[] children; + boolean isWord; + TrieNode(char data){ + this.data=data; + this.children= new TrieNode[26]; + } + } + + + TrieNode root; + public Trie() { + this.root=new TrieNode(' '); + } + + + public void insert(String word) { + TrieNode head=root; + + for(int i=0;i Date: Sat, 11 Jan 2020 18:22:28 +0530 Subject: [PATCH 17/51] new and updated problems --- src/geeksforgeeks/CelebrityProblem.java | 24 ++++++ .../CountNumbersLessThanSelf.java | 43 +++++++++++ src/geeksforgeeks/InOrderSuccessor.java | 27 +++++++ .../InorderSuccessorPredecessor.java | 41 +++++----- .../LengthOfLongestSubstringKDistinct.java | 36 +++++++++ src/geeksforgeeks/ProductExceptSelf.java | 14 ++++ src/geeksforgeeks/WordBreak.java | 75 +++++++++++++++++++ 7 files changed, 240 insertions(+), 20 deletions(-) create mode 100644 src/geeksforgeeks/CelebrityProblem.java create mode 100644 src/geeksforgeeks/CountNumbersLessThanSelf.java create mode 100644 src/geeksforgeeks/InOrderSuccessor.java create mode 100644 src/geeksforgeeks/LengthOfLongestSubstringKDistinct.java create mode 100644 src/geeksforgeeks/WordBreak.java diff --git a/src/geeksforgeeks/CelebrityProblem.java b/src/geeksforgeeks/CelebrityProblem.java new file mode 100644 index 0000000..68f1962 --- /dev/null +++ b/src/geeksforgeeks/CelebrityProblem.java @@ -0,0 +1,24 @@ +package geeksforgeeks; + +public class CelebrityProblem { + /** + * @param n a party with n people + * @return the celebrity's label or -1 + */ + public int findCelebrity(int n) { + int candidate=0; + for(int i=1;i countSmaller(int[] nums) { + if(nums.length==0) return new ArrayList<>(); + + Integer[] result= new Integer[nums.length]; + Node root=null; + for(int i=nums.length-1;i>=0;i--){ // build tree from end so that end is root and has sum 0 + root=buildBSTHelper(nums[i],root,result,i,0); + } + return Arrays.asList(result); + } + + public Node buildBSTHelper(int val, Node root, Integer[] result, int index, int sum){ + if(root==null){ + root= new Node(val,0); + result[index]=sum; + } + else if(root.val==val){ + root.dup++; + result[index]=sum+root.sum; + } + else if(root.val>val){ + root.sum++; + root.left=buildBSTHelper(val,root.left,result,index,sum); + }else{ + root.right=buildBSTHelper(val,root.right,result,index,root.sum+root.dup+sum); + } + return root; + } + + private class Node{ + int val; + int sum; + Node right; + Node left; + int dup=1; + public Node(int val, int sum){ + this.val=val; + this.sum=sum; + } + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/InOrderSuccessor.java b/src/geeksforgeeks/InOrderSuccessor.java new file mode 100644 index 0000000..42af496 --- /dev/null +++ b/src/geeksforgeeks/InOrderSuccessor.java @@ -0,0 +1,27 @@ +package geeksforgeeks; +public class InOrderSuccessor { + /* + * @param root: The root of the BST. + * @param p: You need find the successor node of p. + * @return: Successor of p. + */ + TreeNode result=null; + public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { + helperFn(root,p); + return result; + } + + public void helperFn(TreeNode root, TreeNode p){ + if(root==null) return; + + if(root.val>p.val){ + + result=root; + helperFn(root.left,p); + }else{ + + helperFn(root.right,p); + } + + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/InorderSuccessorPredecessor.java b/src/geeksforgeeks/InorderSuccessorPredecessor.java index 76f1bda..f7512e3 100644 --- a/src/geeksforgeeks/InorderSuccessorPredecessor.java +++ b/src/geeksforgeeks/InorderSuccessorPredecessor.java @@ -7,27 +7,28 @@ public class InorderSuccessorPredecessor { static int successor, predecessor; public void successorPredecessor(TNode root, int val) { + // if (root.data == val) { + // // go to the right most element in the left subtree, it will be the + // // predecessor. + // if (root.left != null) { + // TNode t = root.left; + // while (t.right != null) { + // t = t.right; + // } + // predecessor = t.data; + // } + // if (root.right != null) { + // // go to the left most element in the right subtree, it will be + // // the successor. + // TNode t = root.right; + // while (t.left != null) { + // t = t.left; + // } + // successor = t.data; + // } + // } else if (root != null) { - if (root.data == val) { - // go to the right most element in the left subtree, it will be the - // predecessor. - if (root.left != null) { - TNode t = root.left; - while (t.right != null) { - t = t.right; - } - predecessor = t.data; - } - if (root.right != null) { - // go to the left most element in the right subtree, it will be - // the successor. - TNode t = root.right; - while (t.left != null) { - t = t.left; - } - successor = t.data; - } - } else if (root.data > val) { + if (root.data > val) { // we make the root as successor because we might have a // situation when value matches with the root, it wont have // right subtree to find the successor, in that case we need diff --git a/src/geeksforgeeks/LengthOfLongestSubstringKDistinct.java b/src/geeksforgeeks/LengthOfLongestSubstringKDistinct.java new file mode 100644 index 0000000..c83854f --- /dev/null +++ b/src/geeksforgeeks/LengthOfLongestSubstringKDistinct.java @@ -0,0 +1,36 @@ + +package geeksforgeeks; +public class LengthOfLongestSubstringKDistinct { + /** + * @param s: A string + * @param k: An integer + * @return: An integer + */ + public int lengthOfLongestSubstringKDistinct(String s, int k) { + if(s==null || k==0) return 0; + Map map= new HashMap<>(); + + + int result=0; + int left=0; + int right=0; + + while(leftk){ + char chright= s.charAt(right); + map.put(chright, map.get(chright)-1); + if(map.get(chright)<=0){ + map.remove(chright); + } + right++; + } + left++; + result= Math.max(result,left-right); + } + + return result; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/ProductExceptSelf.java b/src/geeksforgeeks/ProductExceptSelf.java index 6a0306e..494e9ba 100644 --- a/src/geeksforgeeks/ProductExceptSelf.java +++ b/src/geeksforgeeks/ProductExceptSelf.java @@ -4,6 +4,20 @@ /** * https://leetcode.com/problems/product-of-array-except-self/ + * + * Given numbers [2, 3, 4, 5], regarding the third number 4, + * the product of array except 4 is 2*3*5 which consists of two parts: left 2*3 and right 5. + * The product is left*right. We can get lefts and rights + * + * Numbers: 2 3 4 5 + Lefts: 2 2*3 2*3*4 + Rights: 3*4*5 4*5 5 + + Let’s fill the empty with 1: + +Numbers: 2 3 4 5 +Lefts: 1 2 2*3 2*3*4 +Rights: 3*4*5 4*5 5 1 */ public class ProductExceptSelf { public static int[] productExceptSelf(int[] nums) { diff --git a/src/geeksforgeeks/WordBreak.java b/src/geeksforgeeks/WordBreak.java new file mode 100644 index 0000000..14d35ef --- /dev/null +++ b/src/geeksforgeeks/WordBreak.java @@ -0,0 +1,75 @@ +package geeksforgeeks; +class WordBreak { + + /* + +|T| | | | | | | | | +0 1 2 3 4 5 6 7 8 + +i = 1 +j = o sub = l + +i = 2 +j = 0 sub = le +j = 1 sub = e + +i = 3 +j = 0 sub = lee +j = 1 sub = ee +j = 2 sub = e + +i = 4 +j = 0 sub = leet && T[0] and then break, no need to check for rest +|T | | | |T| | | | | +0 1 2 3 4 5 6 7 8 + +i = 5 +j = 0 sub = leetc +j = 1 sub = eetc +j = 2 sub = etc +j = 3 sub = tc +j = 4 sub = c + +i = 6 +j = 0 sub = leetco +j = 1 sub = eetco +j = 2 sub = etco +j = 3 sub = tco +j = 4 sub = co +j = 5 sub = o + +i = 7 +j = 0 sub = leetcod +j = 1 sub = eetcod +j = 2 sub = etcod +j = 3 sub = tcod +j = 4 sub = cod +j = 5 sub = od +j = 6 sub = d + +i = 8 +j = 0 sub = leetcode +j = 1 sub = eetcode +j = 2 sub = etcode +j = 3 sub = tcode +j = 4 sub = code && T[4] and then break + +|T| | | |T| | | | T| +0 1 2 3 4 5 6 7 8 +*/ + public boolean wordBreak(String s, List wordDict) { + if(s==null) return false; + boolean[] dp= new boolean[s.length()+1]; + dp[0]=true; + Set set= new HashSet<>(wordDict); + + for(int i=1;i<=s.length();i++){ + for(int j=0;j Date: Wed, 29 Jan 2020 23:07:20 +0530 Subject: [PATCH 18/51] new set of questions --- src/geeksforgeeks/BoatsToSave.java | 25 ++++++++ src/geeksforgeeks/CloneGraph.java | 53 ++++++++++++++++ src/geeksforgeeks/LargestPossibleNumber.java | 13 ++++ src/geeksforgeeks/NextLargestList.java | 49 +++++++++++++++ src/geeksforgeeks/PalindromicSubSequence.java | 42 +++++++++++++ src/geeksforgeeks/RemoveParanthesisValid.java | 58 +++++++++++++++++ src/geeksforgeeks/SurroundedRegions.java | 62 +++++++++++++++++++ 7 files changed, 302 insertions(+) create mode 100644 src/geeksforgeeks/BoatsToSave.java create mode 100644 src/geeksforgeeks/CloneGraph.java create mode 100644 src/geeksforgeeks/NextLargestList.java create mode 100644 src/geeksforgeeks/PalindromicSubSequence.java create mode 100644 src/geeksforgeeks/RemoveParanthesisValid.java create mode 100644 src/geeksforgeeks/SurroundedRegions.java diff --git a/src/geeksforgeeks/BoatsToSave.java b/src/geeksforgeeks/BoatsToSave.java new file mode 100644 index 0000000..1b495a5 --- /dev/null +++ b/src/geeksforgeeks/BoatsToSave.java @@ -0,0 +1,25 @@ +package geeksforgeeks; +class BoatsToSave { + public int numRescueBoats(int[] people, int limit) { + if(people.length==0 || limit==0) return 0; + + Arrays.sort(people); + + int i=0; + int j=people.length-1; + int res=0; + while(i<=j){ + if(people[i]+people[j]<=limit){ + res++; + i++; + j--; + }else{ + res++; + j--;// neglecting people with more weight + } + + } + + return res; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/CloneGraph.java b/src/geeksforgeeks/CloneGraph.java new file mode 100644 index 0000000..4594889 --- /dev/null +++ b/src/geeksforgeeks/CloneGraph.java @@ -0,0 +1,53 @@ +package geeksforgeeks; +/* +// Definition for a Node. +class Node { + public int val; + public List neighbors; + + public Node() { + val = 0; + neighbors = new ArrayList(); + } + + public Node(int _val) { + val = _val; + neighbors = new ArrayList(); + } + + public Node(int _val, ArrayList _neighbors) { + val = _val; + neighbors = _neighbors; + } +} +*/ +class Solution { + public Node cloneGraph(Node node) { + if(node==null) return node; + + Map map= new HashMap<>(); + + Queue queue= new ArrayDeque<>(); + queue.offer(node); + map.put(node,new Node(node.val)); + + while(!queue.isEmpty()){ + Node current= queue.poll(); + + for(Node neighbors: current.neighbors){ + if(!map.containsKey(neighbors)){ + Node neighborClone= new Node(neighbors.val); + map.put(neighbors,neighborClone); + queue.offer(neighbors); + } + + map.get(current).neighbors.add(map.get(neighbors)); + } + } + + return map.get(node); + + } + + +} \ No newline at end of file diff --git a/src/geeksforgeeks/LargestPossibleNumber.java b/src/geeksforgeeks/LargestPossibleNumber.java index 9f349c3..c0c379a 100644 --- a/src/geeksforgeeks/LargestPossibleNumber.java +++ b/src/geeksforgeeks/LargestPossibleNumber.java @@ -36,4 +36,17 @@ public String largestNumber(int[] nums) { return sb.toString(); } + + public String largestNumber1(int[] nums) { + if(nums==null || nums.length==0) return null; + List list= new LinkedList<>(); + for(int i: nums){ + list.add(String.valueOf(i)); + } + + Collections.sort(list, (a,b)->(int)(Long.parseLong(b+a)-Long.parseLong(a+b))); + + return String.join("",list).replaceFirst("^0+(?!$)", ""); + + } } \ No newline at end of file diff --git a/src/geeksforgeeks/NextLargestList.java b/src/geeksforgeeks/NextLargestList.java new file mode 100644 index 0000000..f8cdcf8 --- /dev/null +++ b/src/geeksforgeeks/NextLargestList.java @@ -0,0 +1,49 @@ +package geeksforgeeks; +class NextLargestList { + public int[] nextLargerNodes(ListNode head) { + + if(head==null) return new int[0]; + int size=getSize(head); + int[] result= new int[size]; + head=reverse(head); + Stack stack= new Stack<>(); + stack.push(head.val); + head=head.next; + int i=size-2; + result[size-1]=0; + while(head!=null){ + + while(!stack.isEmpty() && stack.peek()<=head.val){ + stack.pop(); + } + result[i]=stack.isEmpty()?0:stack.peek(); + stack.push(head.val); + head=head.next; + i--; + } + + return result; + } + + public int getSize(ListNode head){ + int size=0; + ListNode root=head; + while(root!=null){ + root=root.next; + size++; + } + return size; + } + + public ListNode reverse(ListNode head){ + ListNode root=head; + ListNode prev=null; + while(root!=null){ + ListNode next=root.next; + root.next=prev; + prev=root; + root=next; + } + return prev; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/PalindromicSubSequence.java b/src/geeksforgeeks/PalindromicSubSequence.java new file mode 100644 index 0000000..3392f11 --- /dev/null +++ b/src/geeksforgeeks/PalindromicSubSequence.java @@ -0,0 +1,42 @@ +package geeksforgeeks; + +class PalindromicSubSequence { + public int longestPalindromeSubseq(String s) { + if(s==null || s.length()==0) return 0; + + int[][] dp= new int[s.length()][s.length()]; + + for(int i=s.length()-1;i>=0;i--){ + for(int j=i;j= 0; i--) { + dp[i] = 1; + int pre = 0; + for (int j = i + 1; j < s.length(); j++) { + int tmp = dp[j]; + if (s.charAt(i) == s.charAt(j)) { + dp[j] = pre + 2; + } + else { + dp[j] = Math.max(dp[j], dp[j - 1]); + } + pre = tmp; + } + } + + return dp[s.length() - 1]; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/RemoveParanthesisValid.java b/src/geeksforgeeks/RemoveParanthesisValid.java new file mode 100644 index 0000000..88982dc --- /dev/null +++ b/src/geeksforgeeks/RemoveParanthesisValid.java @@ -0,0 +1,58 @@ +package geeksforgeeks; +class RemoveParanthesisValid { + + public List removeInvalidParentheses(String s) { + if (isValid(s)) + return Collections.singletonList(s); + List ans = new ArrayList<>(); + //The queue only contains invalid middle steps + Queue queue = new LinkedList<>(); + //The 3-Tuple is (string, startIndex, lastRemovedChar) + queue.add(new Tuple(s, 0, ')')); + while (!queue.isEmpty()) { + Tuple x = queue.poll(); + //Observation 2, start from last removal position + for (int i = x.start; i < x.string.length(); ++i) { + char ch = x.string.charAt(i); + //Not parentheses + if (ch != '(' && ch != ')') continue; + //Observation 1, do not repeatedly remove from consecutive ones + if (i != x.start && x.string.charAt(i - 1) == ch) continue; + //Observation 3, do not remove a pair of valid parentheses + if (x.removed == '(' && ch == ')') continue; + String t = x.string.substring(0, i) + x.string.substring(i + 1); + //Check isValid before add + if (isValid(t)) + ans.add(t); + //Avoid adding leaf level strings + else if (ans.isEmpty()) + queue.add(new Tuple(t, i, ch)); + } + } + return ans; +} + +public static boolean isValid(String s) { + int count = 0; + for (int i = 0; i < s.length(); ++i) { + char c = s.charAt(i); + if (c == '(') ++count; + if (c == ')' && count-- == 0) return false; + } + return count == 0; +} + +} + + class Tuple { + public final String string; + public final int start; + public final char removed; + + public Tuple(String string, int start, char removed) { + this.string = string; + this.start = start; + this.removed = removed; + +} +} \ No newline at end of file diff --git a/src/geeksforgeeks/SurroundedRegions.java b/src/geeksforgeeks/SurroundedRegions.java new file mode 100644 index 0000000..ee37925 --- /dev/null +++ b/src/geeksforgeeks/SurroundedRegions.java @@ -0,0 +1,62 @@ +package geeksforgeeks; +class Solution { + public void solve(char[][] board) { + if(board==null || board.length==0) return; + + Queue queue= new ArrayDeque<>(); + int[][] dirs= { { -1, 0 }, { 1, 0 }, { 0, 1 }, { 0, -1 } }; + for(int i=0;i=board.length || y<0 || y>=board[0].length) return false; + return true; + } +} + +class Pair { + int x; + int y; + int level; + + public Pair(int x, int y, int level){ + this.x=x; + this.y=y; + this.level=level; + } +} \ No newline at end of file From 8fcf554fa18f1cd37cf4b00ee7c46d07d9e0243a Mon Sep 17 00:00:00 2001 From: Thangaraj A Date: Tue, 18 Feb 2020 19:19:06 +0530 Subject: [PATCH 19/51] new problems --- src/geeksforgeeks/CountAndSay.java | 32 +++++ src/geeksforgeeks/CountOfSmallNumbers.java | 53 +++++++++ src/geeksforgeeks/CourseScheduling.java | 109 ++++++++++++++++++ src/geeksforgeeks/HouseRobber.java | 25 ++++ src/geeksforgeeks/LongestIncreasingPath.java | 65 +++++++++++ .../MaximumSubstringWithKDistinctChar.java | 32 ++++- src/geeksforgeeks/MergeIntervals.java | 35 +++--- src/geeksforgeeks/MergeSortLinkedList.java | 20 +--- src/geeksforgeeks/MinimumStack.java | 18 +-- src/geeksforgeeks/PalindromePartitioning.java | 54 +++++++++ src/geeksforgeeks/PeakElement.java | 29 +++++ src/geeksforgeeks/PerfectSquare.java | 44 +++++++ src/geeksforgeeks/PhoneLetterCombination.java | 3 +- src/geeksforgeeks/PlusOne.java | 36 ++++++ src/geeksforgeeks/RemoveDuplicates.java | 24 ++++ 15 files changed, 537 insertions(+), 42 deletions(-) create mode 100644 src/geeksforgeeks/CountAndSay.java create mode 100644 src/geeksforgeeks/CountOfSmallNumbers.java create mode 100644 src/geeksforgeeks/CourseScheduling.java create mode 100644 src/geeksforgeeks/HouseRobber.java create mode 100644 src/geeksforgeeks/LongestIncreasingPath.java create mode 100644 src/geeksforgeeks/PalindromePartitioning.java create mode 100644 src/geeksforgeeks/PeakElement.java create mode 100644 src/geeksforgeeks/PerfectSquare.java create mode 100644 src/geeksforgeeks/PlusOne.java create mode 100644 src/geeksforgeeks/RemoveDuplicates.java diff --git a/src/geeksforgeeks/CountAndSay.java b/src/geeksforgeeks/CountAndSay.java new file mode 100644 index 0000000..423a253 --- /dev/null +++ b/src/geeksforgeeks/CountAndSay.java @@ -0,0 +1,32 @@ +package geeksforgeeks; + +public class CountAndSay { + public String countAndSay(int n) { + if (n <= 0) { + return "-1"; + } + String result = "1"; + + for (int i = 1; i < n; i++) { + result = build(result); + } + return result; + } + + private String build(String result) { + StringBuilder builder = new StringBuilder(); + int p = 0; + while (p < result.length()) { + char val = result.charAt(p); + int count = 0; + + while (p < result.length() && result.charAt(p) == val) { + p++; + count++; + } + builder.append(String.valueOf(count)); + builder.append(val); + } + return builder.toString(); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/CountOfSmallNumbers.java b/src/geeksforgeeks/CountOfSmallNumbers.java new file mode 100644 index 0000000..68c39f5 --- /dev/null +++ b/src/geeksforgeeks/CountOfSmallNumbers.java @@ -0,0 +1,53 @@ +package geeksforgeeks; + +import java.util.Arrays; +import java.util.List; + +class CountOfSmallNumbers { + class Node { + Node left, right; + int val, sum, dup = 1; + + public Node(int v, int s) { + val = v; + sum = s; + } + + @Override + public String toString() { + return "Node{" + "left=" + left + ", right=" + right + ", val=" + val + ", sum=" + sum + ", dup=" + dup + + '}'; + } + } + + public List countSmaller(int[] nums) { + Integer[] ans = new Integer[nums.length]; + Node root = null; + for (int i = nums.length - 1; i >= 0; i--) { + root = insert(nums[i], root, ans, i, 0); + } + return Arrays.asList(ans); + } + + private Node insert(int num, Node node, Integer[] ans, int i, int preSum) { + if (node == null) { + node = new Node(num, 0); + ans[i] = preSum; + } else if (node.val == num) { + node.dup++; + ans[i] = preSum + node.sum; + } else if (node.val > num) { + node.sum++; + node.left = insert(num, node.left, ans, i, preSum); + } else { + node.right = insert(num, node.right, ans, i, preSum + node.dup + node.sum); + } + return node; + } + + public static void main(String[] args) { + CountOfSmallNumbers csn = new CountOfSmallNumbers(); + int[] arr = { 5, 2, 6, 1 }; + System.out.println(csn.countSmaller(arr)); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/CourseScheduling.java b/src/geeksforgeeks/CourseScheduling.java new file mode 100644 index 0000000..5933e31 --- /dev/null +++ b/src/geeksforgeeks/CourseScheduling.java @@ -0,0 +1,109 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.Set; + +/** + * @author i312458 + * + */ +public class CourseScheduling { + + Map> graph = new HashMap<>(); + int[][] p; + int n; + + public boolean canFinishI(int numCourses, int[][] prerequisites) { + p = prerequisites; + for (int i = 0; i < p.length; i++) { + List l = graph.getOrDefault(p[i][1], new ArrayList<>()); + l.add(p[i][0]); + graph.put(p[i][1], l); + } + for (int i = 0; i < numCourses; i++) { + if (!vis.contains(i)) { + if (cycleExist(i)) { + return false; + } + } + } + + return true; + } + + Set vis = new HashSet<>(); + Set recur = new HashSet<>(); + + public boolean cycleExist(int u) { + if (!graph.containsKey(u)) { + return false; + } + if (recur.contains(u)) { + return true; + } + if (vis.contains(u)) { + return false; + } + recur.add(u); + for (int i : graph.get(u)) { + if (!vis.contains(i)) { + if (cycleExist(i)) { + return true; + } + } + } + recur.remove(u); + vis.add(u); + return false; + } + + int n1; + int[] indegree; + Map> adj = new HashMap<>(); + + public boolean canFinish(int numCourses, int[][] prerequisites) { + n1 = numCourses; + indegree = new int[n1]; + for (int[] pr : prerequisites) { + List l = adj.getOrDefault(pr[1], new ArrayList<>()); + l.add(pr[0]); + indegree[pr[0]]++; + adj.put(pr[1], l); + } + Queue q = new LinkedList<>(); + int count = 0; + for (int i = 0; i < indegree.length; i++) { + if (indegree[i] == 0) { + q.add(i); + } + } + while (!q.isEmpty()) { + int cur = q.poll(); + if (indegree[cur] == 0) { + count++; + } + if (!adj.containsKey(cur)) { + continue; + } + for (int nei : adj.get(cur)) { + indegree[nei]--; + if (indegree[nei] == 0) { + q.add(nei); + } + } + + } + + return count == n1; + } + + public static void main(String[] args) { + + } +} diff --git a/src/geeksforgeeks/HouseRobber.java b/src/geeksforgeeks/HouseRobber.java new file mode 100644 index 0000000..6cd604f --- /dev/null +++ b/src/geeksforgeeks/HouseRobber.java @@ -0,0 +1,25 @@ +package geeksforgeeks; + +import java.util.Collections; +import java.util.PriorityQueue; +import java.util.Queue; + +/** + * @author i312458 + */ +public class HouseRobber { + + public int rob(int[] nums) { + if (nums.length == 0) { + return 0; + } + int incl = nums[0]; + int excl = 0; + for (int i = 1; i < nums.length; i++) { + int temp = incl; + incl = Math.max(incl, excl + nums[i]); + excl = temp; + } + return incl; + } +} diff --git a/src/geeksforgeeks/LongestIncreasingPath.java b/src/geeksforgeeks/LongestIncreasingPath.java new file mode 100644 index 0000000..e7bc49d --- /dev/null +++ b/src/geeksforgeeks/LongestIncreasingPath.java @@ -0,0 +1,65 @@ +package geeksforgeeks; + +/** + * https://leetcode.com/problems/longest-increasing-path-in-a-matrix/discuss/78308/15ms-Concise-Java-Solution + */ +public class LongestIncreasingPath { + + /** + * DFS + Memoization + *

+ * Traverse all points in matrix, use every point as starting point to do dfs traversal. DFS function returns max increasing + * path after comparing four max return distance from four directions. + * + * @param cache: cache[i][j] represents longest increasing path starts from point matrix[i][j] + * @param prev: previous value used by DFS traversal, to compare whether current value is greater than previous value + */ + static final int[][] dirs = new int[][] { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }; + + public static int longestIncreasingPath(int[][] matrix) { + if (matrix.length == 0) { + return 0; + } + + int result = 0; + int n = matrix.length; + int m = matrix[0].length; + Integer[][] cache = new Integer[n][m]; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + int curLen = dfsUtil(matrix, i, j, cache, -1); + result = Math.max(result, curLen); + } + } + return result; + } + + public static int dfsUtil(int[][] matrix, int i, int j, Integer[][] cache, int data) { + if (i < 0 || i >= matrix.length || j < 0 || j >= matrix[0].length || data >= matrix[i][j]) { + return 0; + } + + if (cache[i][j] != null) { + return cache[i][j]; + } + + int max = 1; + + for (int[] dir : dirs) { + + int x = i + dir[0]; + int y = j + dir[1]; + + int count = 1 + dfsUtil(matrix, x, y, cache, matrix[i][j]); + max = Math.max(count, max); + } + cache[i][j] = max; + + return cache[i][j]; + } + + public static void main(String[] args) { + int[][] arr = { { 9, 9, 4 }, { 6, 6, 8 }, { 2, 1, 1 } }; + System.out.println(longestIncreasingPath(arr)); + } +} diff --git a/src/geeksforgeeks/MaximumSubstringWithKDistinctChar.java b/src/geeksforgeeks/MaximumSubstringWithKDistinctChar.java index 12f3007..5ef5e8a 100644 --- a/src/geeksforgeeks/MaximumSubstringWithKDistinctChar.java +++ b/src/geeksforgeeks/MaximumSubstringWithKDistinctChar.java @@ -6,7 +6,8 @@ public class MaximumSubstringWithKDistinctChar { public static void main(String[] args) { - System.out.println(lengthOfLongestSubstringTwoDistinct("abaaaaacccddcc", 2)); + // System.out.println(lengthOfLongestSubstringTwoDistinct("abaaaaacccddcc", 2)); + System.out.println(lengthOfLongestSubstringKDistinct("eqgkcwGFvjjmxutystqdfhuMblWbylgjxsxgnoh", 16)); } public static int lengthOfLongestSubstringTwoDistinct(String s, int k) { @@ -18,7 +19,9 @@ public static int lengthOfLongestSubstringTwoDistinct(String s, int k) { while (end < s.length()) { char c = s.charAt(end); map.put(c, map.getOrDefault(c, 0) + 1); - if (map.get(c) == 1) counter++;//new char + if (map.get(c) == 1) { + counter++;//new char + } end++; while (counter > k) { char cTemp = s.charAt(start); @@ -32,4 +35,29 @@ public static int lengthOfLongestSubstringTwoDistinct(String s, int k) { } return length; } + + public static int lengthOfLongestSubstringKDistinct(String s, int k) { + if(s==null || s.isEmpty()) return 0; + if(k==0) return 0; + int start=0; + int maxCount=0; + int[] arr = new int[26]; + s = s.toLowerCase(); + for(int i=0;i result = new ArrayList<>(); - if (intervals.length == 0 || intervals == null) return result.toArray(new int[0][]); - - Arrays.sort(intervals, (a, b) -> a[0] - b[0]); - - int start = intervals[0][0]; - int end = intervals[0][1]; + if (intervals.length <= 1) { + return intervals; + } + Arrays.sort(intervals, (i1, i2) -> Integer.compare(i1[0], i2[0])); - for (int[] arr : intervals) { - System.out.println(arr[0] + "" + arr[1]); - if (arr[0] <= end) { - end = Math.max(end, arr[1]); - } else { - result.add(new int[]{start, end}); - start = arr[0]; - end = arr[1]; + List result = new ArrayList<>(); + int[] prevInterval = intervals[0]; + result.add(prevInterval); + for (int[] currInterval : intervals) { + if (currInterval[0] <= prevInterval[1]) // Overlapping intervals, move the end if needed + { + prevInterval[1] = Math.max(prevInterval[1], currInterval[1]); + } else { // Disjoint intervals, add the new interval to the list + prevInterval = currInterval; + result.add(prevInterval); } } - result.add(new int[]{start, end}); - return result.toArray(new int[0][]); + return result.toArray(new int[result.size()][]); } public static void main(String[] args) { - int[][] arr = {{1, 3}, {2, 4}, {5, 7}, {6, 8}}; + // [[1,3],[2,6],[8,10],[15,18]] + int[][] arr = { { 1, 3 }, { 2, 4 }, { 5, 7 }, { 6, 8 } }; //{{1, 9}, {2, 4}, {4, 7}, {6, 8}}; System.out.println(Arrays.deepToString(merge(arr))); } diff --git a/src/geeksforgeeks/MergeSortLinkedList.java b/src/geeksforgeeks/MergeSortLinkedList.java index 4e8fbb2..ca29b2c 100644 --- a/src/geeksforgeeks/MergeSortLinkedList.java +++ b/src/geeksforgeeks/MergeSortLinkedList.java @@ -3,36 +3,29 @@ public class MergeSortLinkedList { public static ListNode sortList(ListNode head) { - if (head == null || head.next == null) + if (head == null || head.next == null) { return head; - + } // step 1. cut the list to two halves ListNode prev = null; ListNode slow = head; ListNode fast = head; - // find the mid node while (fast != null && fast.next != null) { prev = slow; slow = slow.next; fast = fast.next.next; } - prev.next = null; - // step 2. sort each half ListNode l1 = sortList(head); ListNode l2 = sortList(slow); - // step 3. merge l1 and l2 return merge(l1, l2); } - static ListNode merge(ListNode l1, ListNode l2) { - ListNode node = new ListNode(0); ListNode temp = node; - while (l1 != null && l2 != null) { if (l1.val < l2.val) { temp.next = l1; @@ -43,13 +36,12 @@ static ListNode merge(ListNode l1, ListNode l2) { } temp = temp.next; } - - if (l1 != null) + if (l1 != null) { temp.next = l1; - - if (l2 != null) + } + if (l2 != null) { temp.next = l2; - + } return node.next; } diff --git a/src/geeksforgeeks/MinimumStack.java b/src/geeksforgeeks/MinimumStack.java index 7510a6d..ecc8a20 100644 --- a/src/geeksforgeeks/MinimumStack.java +++ b/src/geeksforgeeks/MinimumStack.java @@ -8,14 +8,15 @@ class MyStack { Integer minEle; MyStack() { - s = new Stack(); + s = new Stack<>(); } void getMin() { - if (s.isEmpty()) + if (s.isEmpty()) { System.out.println("Stack is empty"); - else + } else { System.out.println("Minimum Element in the " + " stack is: " + minEle); + } } void peek() { @@ -27,10 +28,11 @@ void peek() { Integer t = s.peek(); System.out.print("Top Most Element is: "); - if (t < minEle) + if (t < minEle) { System.out.println(minEle); - else + } else { System.out.println(t); + } } void pop() { @@ -45,8 +47,9 @@ void pop() { if (t < minEle) { System.out.println(minEle); minEle = 2 * minEle - t; - } else + } else { System.out.println(t); + } } void push(Integer x) { @@ -63,8 +66,9 @@ void push(Integer x) { // 2x-minEle> partition(String s) { + + if (s == null || s.length() == 0) { + return Collections.emptyList(); + } + + List> result = new ArrayList<>(); + backtrackingUtil(s, result, new ArrayList<>()); + + return result; + } + + public void backtrackingUtil(String s, List> result, List tempList) { + if (s == null || s.length() == 0) { + result.add(new ArrayList<>(tempList)); + return; + } + + for (int i = 1; i <= s.length(); i++) { + String temp = s.substring(0, i); + if (isPalindrome(temp)) { + tempList.add(temp); + backtrackingUtil(s.substring(i, s.length()), result, tempList); + tempList.remove(tempList.size() - 1); + } + } + } + + public boolean isPalindrome(String s) { + int start = 0; + int end = s.length() - 1; + while (start <= end) { + if (s.charAt(start) != s.charAt(end)) { + return false; + } + start++; + end--; + } + return true; + } + + public static void main(String[] args) { + PalindromePartitioning partitioning = new PalindromePartitioning(); + partitioning.partition("aab"); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/PeakElement.java b/src/geeksforgeeks/PeakElement.java new file mode 100644 index 0000000..dfeedb9 --- /dev/null +++ b/src/geeksforgeeks/PeakElement.java @@ -0,0 +1,29 @@ +package geeksforgeeks; + +/** + * @author i312458 + */ +public class PeakElement { + public int findPeakElement(int[] nums) { + + int low = 0; + int high = nums.length - 1; + + while (low < high) { + int mid = (low + high) / 2; + if (nums[mid] < nums[mid + 1]) { + low = mid + 1; + } else { + high = mid; + } + } + return low; + } + + public static void main(String[] args) { + PeakElement pe = new PeakElement(); + int[] arr = { 1, 1, 1, 3, 2, 1, 2 }; + System.out.println(arr[pe.findPeakElement(arr)]); + } + +} diff --git a/src/geeksforgeeks/PerfectSquare.java b/src/geeksforgeeks/PerfectSquare.java new file mode 100644 index 0000000..87e7913 --- /dev/null +++ b/src/geeksforgeeks/PerfectSquare.java @@ -0,0 +1,44 @@ +package geeksforgeeks; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Queue; +import java.util.Set; + +class PerfectSquare { + + public int numSquares(int n) { + Queue q = new LinkedList<>(); + Set visited = new HashSet<>(); + q.offer(0); + visited.add(0); + int depth = 0; + while (!q.isEmpty()) { + int size = q.size(); + depth++; + while (size > 0) { + int removed = q.poll(); + for (int i = 1; i * i <= n; i++) { + int v = removed + i * i; + if (v == n) { + return depth; + } + if (v > n) { + break; + } + if (!visited.contains(v)) { + q.offer(v); + visited.add(v); + } + } + size--; + } + } + return depth; + } + + public static void main(String[] args) { + PerfectSquare ps = new PerfectSquare(); + System.out.println(ps.numSquares(12)); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/PhoneLetterCombination.java b/src/geeksforgeeks/PhoneLetterCombination.java index e619898..942fd06 100644 --- a/src/geeksforgeeks/PhoneLetterCombination.java +++ b/src/geeksforgeeks/PhoneLetterCombination.java @@ -28,6 +28,7 @@ public List letterCombinations(String digits) { public static void main(String[] args) { PhoneLetterCombination plc = new PhoneLetterCombination(); - plc.letterCombinations("23"); + List strings = plc.letterCombinations("2345"); + strings.forEach(System.out::println); } } diff --git a/src/geeksforgeeks/PlusOne.java b/src/geeksforgeeks/PlusOne.java new file mode 100644 index 0000000..3961917 --- /dev/null +++ b/src/geeksforgeeks/PlusOne.java @@ -0,0 +1,36 @@ +package geeksforgeeks; + +import java.util.Arrays; + +class PlusOne { + + public static int[] plusOne(int[] digits) { + + StringBuilder sb = new StringBuilder(); + int remainder = 0; + for (int i = digits.length - 1; i >= 0; i--) { + int num = 0; + if (i == digits.length - 1) { + num = digits[i] + 1; + } else { + num = digits[i] + remainder; + } + int count = String.valueOf(num).length(); + if (count > 1) { + sb.append(num % 10); + remainder = num / 10; + } else { + remainder = 0; + sb.append(num); + } + } + + return sb.reverse().toString().chars().map(i -> i-'0').toArray(); + } + + public static void main(String[] args) { + int[] digits = { 1, 2, 9 }; + int[] endpointUrl = plusOne(digits); + Arrays.stream(endpointUrl).forEach(System.out::println); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/RemoveDuplicates.java b/src/geeksforgeeks/RemoveDuplicates.java new file mode 100644 index 0000000..7f2c5c3 --- /dev/null +++ b/src/geeksforgeeks/RemoveDuplicates.java @@ -0,0 +1,24 @@ +package geeksforgeeks; + +class RemoveDuplicates { + + public int removeDuplicates(int[] nums) { + if (nums == null || nums.length == 0) { + return 0; + } + int i = 0; + nums[i++] = nums[0]; + for (int j = 1; j < nums.length; j++) { + if (nums[j] != nums[j - 1]) { + nums[i++] = nums[j]; + } + } + return i; + } + + public static void main(String[] args) { + RemoveDuplicates removeDuplicates = new RemoveDuplicates(); + int[] nums = { 1 , 1, 2 }; + removeDuplicates.removeDuplicates(nums); + } +} \ No newline at end of file From c825cd4e21addea7805d3f9e10bf70d56bcea765 Mon Sep 17 00:00:00 2001 From: Thangaraj A Date: Wed, 11 Mar 2020 19:21:09 +0530 Subject: [PATCH 20/51] Adding some problems --- src/geeksforgeeks/AircraftOptimization.java | 94 ++++++++-------- .../AlternateOddAndEvenNumbers.java | 7 +- src/geeksforgeeks/BitonicSearch.java | 2 +- src/geeksforgeeks/BuyAndSellStockAnytime.java | 2 +- .../BuyAndSellStockAtMostTwice.java | 16 +++ src/geeksforgeeks/Candy.java | 14 ++- src/geeksforgeeks/ClosestNumbers.java | 33 +++--- src/geeksforgeeks/CompareVersions.java | 39 ++++--- .../ConstructBSTFromPreorder.java | 6 +- .../ConstructTreeFromInorderAndPreorder.java | 1 + src/geeksforgeeks/ConvertXToY.java | 65 +++++++++++ .../CountAllPathsFrom2DMatrix.java | 2 +- src/geeksforgeeks/CountAndSay.java | 8 ++ .../CountDistinctKSubString.java | 16 +-- ...ntMinimumStepsToFormDesiredInputArray.java | 19 ++-- src/geeksforgeeks/CountOfSmallNumbers.java | 3 + src/geeksforgeeks/CountingInversion.java | 101 +++++++++-------- src/geeksforgeeks/CourseScheduling.java | 3 +- src/geeksforgeeks/DivideSubArrayAverage.java | 2 +- .../FindMinimumInRotatedArray.java | 11 +- .../FindNumberOfOccurrences.java | 2 +- src/geeksforgeeks/FindSmallestInteger.java | 12 +- src/geeksforgeeks/GrammarMistake.java | 105 ++++++++++++++++++ src/geeksforgeeks/IntegerToBinary.java | 31 ++++++ src/geeksforgeeks/MaximumDifference.java | 10 +- src/geeksforgeeks/MaximumSubarray.java | 3 +- 26 files changed, 424 insertions(+), 183 deletions(-) create mode 100644 src/geeksforgeeks/ConvertXToY.java create mode 100644 src/geeksforgeeks/GrammarMistake.java create mode 100644 src/geeksforgeeks/IntegerToBinary.java diff --git a/src/geeksforgeeks/AircraftOptimization.java b/src/geeksforgeeks/AircraftOptimization.java index ad49b7f..8f5f2dc 100644 --- a/src/geeksforgeeks/AircraftOptimization.java +++ b/src/geeksforgeeks/AircraftOptimization.java @@ -7,56 +7,54 @@ import java.util.List; /** - * https://leetcode.com/discuss/interview-question/318918/Amazon-or-Online-Assessment-2019-or-Optimal-Aircraft-Utilization - * * https://leetcode.com/discuss/interview-question/373202 */ public class AircraftOptimization { - public List> calculateOptimalRoute(final List> forwardList, - final List> returnList, int capacity) { - - Collections.sort(forwardList, (o1, o2) -> Integer.compare(o1.get(1), o2.get(1))); - Collections.sort(returnList, (o1, o2) -> Integer.compare(o1.get(1), o2.get(1))); - - int max = 0; - int i = 0; - int j = returnList.size() - 1; - - List> result = null; - while (i < forwardList.size() && j >= 0) { - int currentSum = forwardList.get(i).get(1) + returnList.get(j).get(1); - - if (currentSum > max && currentSum <= capacity) { - max = forwardList.get(i).get(1) + returnList.get(j).get(1); - // Initializing new list - result = new LinkedList<>(); - result.add(new ArrayList<>(Arrays.asList(forwardList.get(i).get(0), returnList.get(j).get(0)))); - i++; - } else if (forwardList.get(i).get(1) + returnList.get(j).get(1) == max) { - // no need to reset result list - result.add(new ArrayList<>(Arrays.asList(forwardList.get(i).get(0), returnList.get(j).get(0)))); - i++; - } else { - j--; - } - } - return result; - } - - public static void main(String[] args) { - AircraftOptimization aircraft = new AircraftOptimization(); - List> returnList = new ArrayList<>(); - returnList.add(new ArrayList(Arrays.asList(1, 2000))); - returnList.add(new ArrayList(Arrays.asList(2, 3000))); - returnList.add(new ArrayList(Arrays.asList(3, 4000))); - returnList.add(new ArrayList(Arrays.asList(4, 5000))); - List> forwardList = new ArrayList<>(); - forwardList.add(new ArrayList(Arrays.asList(1, 3000))); - forwardList.add(new ArrayList(Arrays.asList(2, 5000))); - forwardList.add(new ArrayList(Arrays.asList(3, 7000))); - forwardList.add(new ArrayList(Arrays.asList(4, 10000))); - List> calculateOptimalRoute = aircraft.calculateOptimalRoute(forwardList, returnList, 10000); - System.out.println(calculateOptimalRoute); - } + public List> calculateOptimalRoute(final List> forwardList, + final List> returnList, int capacity) { + + Collections.sort(forwardList, (o1, o2) -> Integer.compare(o1.get(1), o2.get(1))); + Collections.sort(returnList, (o1, o2) -> Integer.compare(o1.get(1), o2.get(1))); + + int max = 0; + int i = 0; + int j = returnList.size() - 1; + + List> result = null; + while (i < forwardList.size() && j >= 0) { + int currentSum = forwardList.get(i).get(1) + returnList.get(j).get(1); + + if (currentSum > max && currentSum <= capacity) { + max = forwardList.get(i).get(1) + returnList.get(j).get(1); + // Initializing new list + result = new LinkedList<>(); + result.add(new ArrayList<>(Arrays.asList(forwardList.get(i).get(0), returnList.get(j).get(0)))); + i++; + } else if (forwardList.get(i).get(1) + returnList.get(j).get(1) == max) { + // no need to reset result list + result.add(new ArrayList<>(Arrays.asList(forwardList.get(i).get(0), returnList.get(j).get(0)))); + i++; + } else { + j--; + } + } + return result; + } + + public static void main(String[] args) { + AircraftOptimization aircraft = new AircraftOptimization(); + List> returnList = new ArrayList<>(); + returnList.add(new ArrayList(Arrays.asList(1, 2000))); + returnList.add(new ArrayList(Arrays.asList(2, 3000))); + returnList.add(new ArrayList(Arrays.asList(3, 4000))); + returnList.add(new ArrayList(Arrays.asList(4, 5000))); + List> forwardList = new ArrayList<>(); + forwardList.add(new ArrayList(Arrays.asList(1, 3000))); + forwardList.add(new ArrayList(Arrays.asList(2, 5000))); + forwardList.add(new ArrayList(Arrays.asList(3, 7000))); + forwardList.add(new ArrayList(Arrays.asList(4, 10000))); + List> calculateOptimalRoute = aircraft.calculateOptimalRoute(forwardList, returnList, 10000); + System.out.println(calculateOptimalRoute); + } } diff --git a/src/geeksforgeeks/AlternateOddAndEvenNumbers.java b/src/geeksforgeeks/AlternateOddAndEvenNumbers.java index d96f881..027e347 100644 --- a/src/geeksforgeeks/AlternateOddAndEvenNumbers.java +++ b/src/geeksforgeeks/AlternateOddAndEvenNumbers.java @@ -3,6 +3,9 @@ // (0, 2, 4,..) and negative numbers at odd indexes (1, 3, // 5, ..) +/** + * https://www.geeksforgeeks.org/rearrange-positive-and-negative-numbers-publish/ + */ class AlternateOddAndEvenNumbers { static void rearrange(int arr[], int n) { @@ -17,10 +20,8 @@ static void rearrange(int arr[], int n) { } } - int pos = i + 1, neg = 0; - while (pos < n && neg < pos && arr[neg] < 0) { temp = arr[neg]; arr[neg] = arr[pos]; @@ -36,7 +37,7 @@ static void printArray(int arr[], int n) { } public static void main(String[] args) { - int arr[] = {-1, 2, -3, 4, 5, 6, -7, 8, 9}; + int arr[] = { -1, 2, -3, 4, 5, 6, -7, 8, 9 }; int n = arr.length; rearrange(arr, n); System.out.println("Array after rearranging: "); diff --git a/src/geeksforgeeks/BitonicSearch.java b/src/geeksforgeeks/BitonicSearch.java index 7e22457..df4f259 100644 --- a/src/geeksforgeeks/BitonicSearch.java +++ b/src/geeksforgeeks/BitonicSearch.java @@ -67,7 +67,7 @@ static int searchBitonic(int arr[], int n, int key, int index) { } public static void main(String args[]) { - int arr[] = {-3, 3, 9, 8, 20, 17, 5, 3, 1}; + int arr[] = { -3, 3, 9, 8, 20, 17, 5, 3, 1 }; int key = 3; int n = arr.length; int l = 0; diff --git a/src/geeksforgeeks/BuyAndSellStockAnytime.java b/src/geeksforgeeks/BuyAndSellStockAnytime.java index ffbe021..a3a6e46 100644 --- a/src/geeksforgeeks/BuyAndSellStockAnytime.java +++ b/src/geeksforgeeks/BuyAndSellStockAnytime.java @@ -18,6 +18,6 @@ public int maxProfit(int[] prices) { public static void main(String[] args) { BuyAndSellStockAnytime stock = new BuyAndSellStockAnytime(); int[] arr = { 7, 1, 5, 6, 4 }; - stock.maxProfit(arr); + System.out.println(stock.maxProfit(arr)); } } diff --git a/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java b/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java index 88c31ec..48c1fe1 100644 --- a/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java +++ b/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java @@ -56,4 +56,20 @@ public static void main(String args[]) { System.out.println("Maximum Profit = " + maxProfit(price, n)); } + public int maxProfit(int[] prices) { + int oneBuy = Integer.MIN_VALUE; + int oneBuyOneSell = 0; + int twoBuy = Integer.MIN_VALUE; + int twoBuyTwoSell = 0; + for(int i = 0; i < prices.length; i++){ + oneBuy = Math.min(oneBuy, prices[i]);//we set prices to negative, so the calculation of profit will be + // convenient + oneBuyOneSell = Math.max(oneBuyOneSell, prices[i] + oneBuy); + twoBuy = Math.min(twoBuy, prices[i] - oneBuyOneSell);//we can buy the second only after first is sold + twoBuyTwoSell = Math.max(twoBuyTwoSell, twoBuy + prices[i]); + } + + return Math.max(oneBuyOneSell, twoBuyTwoSell); + } + } diff --git a/src/geeksforgeeks/Candy.java b/src/geeksforgeeks/Candy.java index 2bf6b7d..4a7ff88 100644 --- a/src/geeksforgeeks/Candy.java +++ b/src/geeksforgeeks/Candy.java @@ -12,21 +12,25 @@ class Candy { // 1,2,4,3,2,1 int candy(int[] ratings) { int size = ratings.length; - if (size <= 1) + if (size <= 1) { return size; + } int[] num = new int[size]; Arrays.fill(num, 1); - // left to righ + // left to right for (int i = 1; i < size; i++) { - if (ratings[i] > ratings[i - 1]) + if (ratings[i] > ratings[i - 1]) { num[i] = num[i - 1] + 1; + } } // right to left for (int i = size - 1; i > 0; i--) { - if (ratings[i - 1] > ratings[i]) + if (ratings[i - 1] > ratings[i]) { + // check curr index + 1 or existing value num[i - 1] = Math.max(num[i] + 1, num[i - 1]); + } } int result = 0; for (int i = 0; i < size; i++) { @@ -38,7 +42,7 @@ int candy(int[] ratings) { public static void main(String[] args) { Candy candy = new Candy(); - int[] ratings = {2, 4, 2, 6, 1, 7, 8, 9, 2, 1}; + int[] ratings = { 2, 4, 2, 6, 1, 7, 8, 9, 2, 1 }; System.out.println(candy.candy(ratings)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/ClosestNumbers.java b/src/geeksforgeeks/ClosestNumbers.java index e9f4efc..311364a 100644 --- a/src/geeksforgeeks/ClosestNumbers.java +++ b/src/geeksforgeeks/ClosestNumbers.java @@ -11,23 +11,28 @@ public class ClosestNumbers { public static void main(String[] args) { //10, 50, 12, 100 - int[] arr = new int[]{5, 4, 3, 2}; - Arrays.sort(arr); + int[] arr = new int[] { 10, 50, 12, 100 }; + int n = arr.length; + if (n <= 1) { + return; + } - Map map = new HashMap<>(); + // Sort array elements + Arrays.sort(arr); - for (int i = 0; i < arr.length - 1; i++) { - map.put(arr[i] + "-" + arr[i + 1], arr[i + 1] - arr[i]); - } - int min = arr[1] - arr[0]; - for (Map.Entry m : map.entrySet()) { - if (min > m.getValue()) - min = m.getValue(); - } + // Compare differences of adjacent + // pairs to find the minimum difference. + int minDiff = arr[1] - arr[0]; + for (int i = 2; i < n; i++) + minDiff = Math.min(minDiff, arr[i] - arr[i - 1]); - for (Map.Entry ma : map.entrySet()) { - if (ma.getValue().equals(min)) - System.out.println(ma.getKey()); + // Traverse array again and print all pairs + // with difference as minDiff. + for (int i = 1; i < n; i++) { + if ((arr[i] - arr[i - 1]) == minDiff) { + System.out.print("(" + arr[i - 1] + ", " + arr[i] + "),"); + } } } + } diff --git a/src/geeksforgeeks/CompareVersions.java b/src/geeksforgeeks/CompareVersions.java index 344f946..e52da75 100644 --- a/src/geeksforgeeks/CompareVersions.java +++ b/src/geeksforgeeks/CompareVersions.java @@ -2,31 +2,30 @@ /** * https://leetcode.com/problems/compare-version-numbers/ - * */ public class CompareVersions { - public static void main(String[] args) { - String str1 = "1.3.4"; - String str2 = "1.3.1.7"; - System.out.println(compareVersion(str1, str2)); - } + public static void main(String[] args) { + String str1 = "1.3.4"; + String str2 = "1.3.1.7"; + System.out.println(compareVersion(str1, str2)); + } - public static int compareVersion(String version1, String version2) { - String[] levels1 = version1.split("\\."); - String[] levels2 = version2.split("\\."); + public static int compareVersion(String version1, String version2) { + String[] levels1 = version1.split("\\."); + String[] levels2 = version2.split("\\."); - int length = Math.max(levels1.length, levels2.length); - for (int i = 0; i < length; i++) { - Integer v1 = i < levels1.length ? Integer.parseInt(levels1[i]) : 0; - Integer v2 = i < levels2.length ? Integer.parseInt(levels2[i]) : 0; - int compare = v1.compareTo(v2); - if (compare != 0) { - return compare; - } - } + int length = Math.max(levels1.length, levels2.length); + for (int i = 0; i < length; i++) { + Integer v1 = i < levels1.length ? Integer.parseInt(levels1[i]) : 0; + Integer v2 = i < levels2.length ? Integer.parseInt(levels2[i]) : 0; + int compare = v1.compareTo(v2); + if (compare != 0) { + return compare; + } + } - return 0; - } + return 0; + } } diff --git a/src/geeksforgeeks/ConstructBSTFromPreorder.java b/src/geeksforgeeks/ConstructBSTFromPreorder.java index 951d6aa..6a94d3d 100644 --- a/src/geeksforgeeks/ConstructBSTFromPreorder.java +++ b/src/geeksforgeeks/ConstructBSTFromPreorder.java @@ -2,14 +2,16 @@ import java.util.Stack; +/** + * https://leetcode.com/problems/construct-binary-search-tree-from-preorder-traversal/ + */ class ConstructBSTFromPreorder { public static void main(String[] args) { - int[] arr = {8, 3, 1, 6, 4, 7, 10, 14, 13}; + int[] arr = { 8, 3, 1, 6, 4, 7, 10, 14, 13 }; bstFromPreorder(arr); } - public static TreeNode bstFromPreorder(int[] preorder) { if (preorder == null || preorder.length == 0) { return null; diff --git a/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java b/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java index ac4e991..011c059 100644 --- a/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java +++ b/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java @@ -5,6 +5,7 @@ import java.util.Map; class ConstructTreeFromInorderAndPreorder { + public TreeNode buildTree(int[] preorder, int[] inorder) { Map inMap = new HashMap<>(); for (int i = 0; i < inorder.length; i++) { diff --git a/src/geeksforgeeks/ConvertXToY.java b/src/geeksforgeeks/ConvertXToY.java new file mode 100644 index 0000000..5c5ba14 --- /dev/null +++ b/src/geeksforgeeks/ConvertXToY.java @@ -0,0 +1,65 @@ +package geeksforgeeks; +// Java program to find minimum +// number of steps needed to +// convert a number x into y +// with two operations allowed : +// (1) multiplication with 2 +// (2) subtraction with 1. + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Set; + +class Steps { + int val; + int steps; + + public Steps(int val, int steps) { + this.val = val; + this.steps = steps; + } +} + +public class ConvertXToY { + + private static int minOperations(int src, int target) { + + Set visited = new HashSet<>(); + LinkedList queue = new LinkedList<>(); + + Steps node = new Steps(src, 0); + + queue.offer(node); + visited.add(node); + + while (!queue.isEmpty()) { + Steps temp = queue.poll(); + visited.add(temp); + + if (temp.val == target) { + return temp.steps; + } + + int mul = temp.val * 2; + int sub = temp.val - 1; + + // given constraints + if (mul > 0 && mul < 1000) { + Steps nodeMul = new Steps(mul, temp.steps + 1); + queue.offer(nodeMul); + } + if (sub > 0 && sub < 1000) { + Steps nodeSub = new Steps(sub, temp.steps + 1); + queue.offer(nodeSub); + } + } + return -1; + } + + public static void main(String[] args) { + // int x = 2, y = 5; + int x = 4, y = 7; + Steps src = new Steps(x, y); + System.out.println(minOperations(x, y)); + } +} diff --git a/src/geeksforgeeks/CountAllPathsFrom2DMatrix.java b/src/geeksforgeeks/CountAllPathsFrom2DMatrix.java index dd13894..48ee7da 100644 --- a/src/geeksforgeeks/CountAllPathsFrom2DMatrix.java +++ b/src/geeksforgeeks/CountAllPathsFrom2DMatrix.java @@ -3,7 +3,7 @@ /*https://www.geeksforgeeks.org/count-possible-paths-top-left-bottom-right-nxm-matrix/*/ class CountAllPathsFrom2DMatrix { // A Java program to count all possible paths -// from top left to bottom right + // from top left to bottom right // Returns count of possible paths to reach // cell at row number m and column number n from // the topmost leftmost cell (cell at 1, 1) diff --git a/src/geeksforgeeks/CountAndSay.java b/src/geeksforgeeks/CountAndSay.java index 423a253..df8cce4 100644 --- a/src/geeksforgeeks/CountAndSay.java +++ b/src/geeksforgeeks/CountAndSay.java @@ -1,5 +1,8 @@ package geeksforgeeks; +/** + * https://leetcode.com/problems/count-and-say/ + */ public class CountAndSay { public String countAndSay(int n) { if (n <= 0) { @@ -29,4 +32,9 @@ private String build(String result) { } return builder.toString(); } + + public static void main(String[] args) { + CountAndSay countAndSay = new CountAndSay(); + System.out.println(countAndSay.countAndSay(4)); + } } \ No newline at end of file diff --git a/src/geeksforgeeks/CountDistinctKSubString.java b/src/geeksforgeeks/CountDistinctKSubString.java index 57ab9ab..a302b66 100644 --- a/src/geeksforgeeks/CountDistinctKSubString.java +++ b/src/geeksforgeeks/CountDistinctKSubString.java @@ -6,30 +6,26 @@ import java.util.Arrays; /*https://www.geeksforgeeks.org/count-number-of-substrings-with-exactly-k-distinct-characters/*/ + public class CountDistinctKSubString { private int countKDist(String str, int k) { int result = 0; - int n = str.length(); - int count[] = new int[26]; for (int i = 0; i < n; i++) { int distinctCount = 0; - Arrays.fill(count, 0); - for (int j = i; j < n; j++) { - - if (count[str.charAt(j) - 'a'] == 0) + if (count[str.charAt(j) - 'a'] == 0) { distinctCount++; - + } count[str.charAt(j) - 'a']++; - - if (distinctCount == k) + if (distinctCount == k) { result++; + } } } return result; @@ -37,7 +33,7 @@ private int countKDist(String str, int k) { public static void main(String[] args) { CountDistinctKSubString ob = new CountDistinctKSubString(); - String ch = "pqpqs"; + String ch = "abc"; int k = 2; System.out.println("Total substrings with exactly " + k + " distinct characters : " + ob.countKDist(ch, k)); } diff --git a/src/geeksforgeeks/CountMinimumStepsToFormDesiredInputArray.java b/src/geeksforgeeks/CountMinimumStepsToFormDesiredInputArray.java index b36b8fa..9b0310a 100644 --- a/src/geeksforgeeks/CountMinimumStepsToFormDesiredInputArray.java +++ b/src/geeksforgeeks/CountMinimumStepsToFormDesiredInputArray.java @@ -4,7 +4,7 @@ /*https://www.geeksforgeeks.org/count-minimum-steps-get-given-desired-array/*/ // unsolved class CountMinimumStepsToFormDesiredInputArray { - static int arr[] = new int[]{16, 16, 16}; + static int arr[] = new int[] { 16, 16, 16 }; // Returns count of minimum operations to covert a // zero array to arr array with increment and @@ -25,17 +25,20 @@ static int countMinOperations(int n) { int i; // To find first odd element for (i = 0; i < n; i++) { // If odd number found - if (arr[i] % 2 == 1) + if (arr[i] % 2 == 1) { break; + } - // If 0, then increment zero_count - else if (arr[i] == 0) + // If 0, then increment zero_count + else if (arr[i] == 0) { zero_count++; + } } // All numbers are 0 - if (zero_count == n) + if (zero_count == n) { return result; + } // All numbers are even if (i == n) { @@ -59,9 +62,9 @@ else if (arr[i] == 0) public static void main(String[] args) { - System.out.println("Minimum number of steps required to \n" + - "get the given target array is " + - countMinOperations(arr.length)); + System.out.println( + "Minimum number of steps required to \n" + "get the given target array is " + countMinOperations( + arr.length)); } } diff --git a/src/geeksforgeeks/CountOfSmallNumbers.java b/src/geeksforgeeks/CountOfSmallNumbers.java index 68c39f5..12e1c16 100644 --- a/src/geeksforgeeks/CountOfSmallNumbers.java +++ b/src/geeksforgeeks/CountOfSmallNumbers.java @@ -3,6 +3,9 @@ import java.util.Arrays; import java.util.List; +/** + * https://leetcode.com/problems/count-of-smaller-numbers-after-self/ + */ class CountOfSmallNumbers { class Node { Node left, right; diff --git a/src/geeksforgeeks/CountingInversion.java b/src/geeksforgeeks/CountingInversion.java index b381ec3..e3db597 100644 --- a/src/geeksforgeeks/CountingInversion.java +++ b/src/geeksforgeeks/CountingInversion.java @@ -2,58 +2,57 @@ /** * https://www.geeksforgeeks.org/counting-inversions/ - * */ class CountingInversion { - static int mergeSort(int[] arr, int arrSize) { - int[] temp = new int[arrSize]; - return mergeSort(arr, temp, 0, arrSize - 1); - } - - static int mergeSort(int[] arr, int[] temp, int left, int right) { - int mid; - int invCount = 0; - if (left < right) { - mid = ((right - left) / 2) + left; - - invCount = mergeSort(arr, temp, left, mid); - invCount += mergeSort(arr, temp, mid + 1, right); - - invCount += merge(arr, temp, left, mid + 1, right); - } - return invCount; - } - - static int merge(int[] arr, int[] temp, int left, int mid, int right) { - int invCount = 0; - - int i = left; - int j = mid; - int k = left; - while ((i <= mid - 1) && (j <= right)) { - if (arr[i] <= arr[j]) { - temp[k++] = arr[i++]; - } else { - temp[k++] = arr[j++]; - - invCount = invCount + (mid - i); - } - } - - while (i <= mid - 1) - temp[k++] = arr[i++]; - while (j <= right) - temp[k++] = arr[j++]; - - for (i = left; i <= right; i++) - arr[i] = temp[i]; - - return invCount; - } - - public static void main(String[] args) { - int arr[] = new int[] { 4, 6, 2, 1, 9, 7 }; - System.out.println("Number of inversions are " + mergeSort(arr, arr.length)); - } + static int mergeSort(int[] arr, int arrSize) { + int[] temp = new int[arrSize]; + return mergeSort(arr, temp, 0, arrSize - 1); + } + + static int mergeSort(int[] arr, int[] temp, int left, int right) { + int mid; + int invCount = 0; + if (left < right) { + mid = ((right - left) / 2) + left; + + invCount = mergeSort(arr, temp, left, mid); + invCount += mergeSort(arr, temp, mid + 1, right); + + invCount += merge(arr, temp, left, mid + 1, right); + } + return invCount; + } + + static int merge(int[] arr, int[] temp, int left, int mid, int right) { + int invCount = 0; + + int i = left; + int j = mid; + int k = left; + while ((i <= mid - 1) && (j <= right)) { + if (arr[i] <= arr[j]) { + temp[k++] = arr[i++]; + } else { + temp[k++] = arr[j++]; + + invCount = invCount + (mid - i); + } + } + + while (i <= mid - 1) + temp[k++] = arr[i++]; + while (j <= right) + temp[k++] = arr[j++]; + + for (i = left; i <= right; i++) + arr[i] = temp[i]; + + return invCount; + } + + public static void main(String[] args) { + int arr[] = new int[] { 4, 6, 2, 1, 9, 7 }; + System.out.println("Number of inversions are " + mergeSort(arr, arr.length)); + } } diff --git a/src/geeksforgeeks/CourseScheduling.java b/src/geeksforgeeks/CourseScheduling.java index 5933e31..aa1460d 100644 --- a/src/geeksforgeeks/CourseScheduling.java +++ b/src/geeksforgeeks/CourseScheduling.java @@ -10,8 +10,7 @@ import java.util.Set; /** - * @author i312458 - * + * https://leetcode.com/problems/course-schedule/ */ public class CourseScheduling { diff --git a/src/geeksforgeeks/DivideSubArrayAverage.java b/src/geeksforgeeks/DivideSubArrayAverage.java index 72ee60e..dfdfa0f 100644 --- a/src/geeksforgeeks/DivideSubArrayAverage.java +++ b/src/geeksforgeeks/DivideSubArrayAverage.java @@ -29,7 +29,7 @@ static void findSubarrays(int arr[], int n) { } public static void main(String[] args) { - int[] arr = {1, 5, 7, 2, 0}; + int[] arr = { 1, 5, 7, 2, 0 }; int n = arr.length; findSubarrays(arr, n); } diff --git a/src/geeksforgeeks/FindMinimumInRotatedArray.java b/src/geeksforgeeks/FindMinimumInRotatedArray.java index cafb09c..72ecb2e 100644 --- a/src/geeksforgeeks/FindMinimumInRotatedArray.java +++ b/src/geeksforgeeks/FindMinimumInRotatedArray.java @@ -4,8 +4,12 @@ public class FindMinimumInRotatedArray { public static int findMin(int[] nums) { - if (nums.length == 0) return -1; - if (nums.length == 1) return nums[0]; + if (nums.length == 0) { + return -1; + } + if (nums.length == 1) { + return nums[0]; + } int start = 0; int end = nums.length - 1; while (start <= end) { @@ -24,9 +28,8 @@ public static int findMin(int[] nums) { return -1; } - public static void main(String[] args) { - int[] arr = {7, 1, 2, 3, 4, 5, 6}; + int[] arr = { 7, 1, 2, 3, 4, 5, 6 }; findMin(arr); } } \ No newline at end of file diff --git a/src/geeksforgeeks/FindNumberOfOccurrences.java b/src/geeksforgeeks/FindNumberOfOccurrences.java index e4113b4..3e81c4c 100644 --- a/src/geeksforgeeks/FindNumberOfOccurrences.java +++ b/src/geeksforgeeks/FindNumberOfOccurrences.java @@ -4,7 +4,7 @@ public class FindNumberOfOccurrences { public static void main(String[] args) { - int arr[] = {1, 1, 2, 2, 2, 2, 3, 3}; + int arr[] = { 1, 1, 2, 2, 2, 2, 3, 3 }; System.out.println( findLastOccurrence(arr, 0, arr.length - 1, 2) - findFirstOccurrence(arr, 0, arr.length - 1, 2) + 1); diff --git a/src/geeksforgeeks/FindSmallestInteger.java b/src/geeksforgeeks/FindSmallestInteger.java index b844cc8..8c3d88b 100644 --- a/src/geeksforgeeks/FindSmallestInteger.java +++ b/src/geeksforgeeks/FindSmallestInteger.java @@ -8,27 +8,29 @@ int findSmallest(int arr[], int n) { // Traverse the array and increment 'result' if arr[i] is // smaller than or equal to 'result'. - for (int i = 0; i < n && arr[i] <= result; i++) + for (int i = 0; i < n && arr[i] <= result; i++) { + System.out.println("Result :" + result + ":: arr[" + i + "]" + arr[i]); result = result + arr[i]; + } return result; } public static void main(String[] args) { FindSmallestInteger small = new FindSmallestInteger(); - int arr1[] = {1, 3, 4, 5}; + int arr1[] = { 1, 3, 4, 5 }; int n1 = arr1.length; System.out.println(small.findSmallest(arr1, n1)); - int arr2[] = {1, 2, 6, 10, 11, 15}; + int arr2[] = { 1, 2, 6, 10, 11, 15 }; int n2 = arr2.length; System.out.println(small.findSmallest(arr2, n2)); - int arr3[] = {1, 1, 1, 1}; + int arr3[] = { 1, 1, 1, 1 }; int n3 = arr3.length; System.out.println(small.findSmallest(arr3, n3)); - int arr4[] = {1, 1, 3, 4}; + int arr4[] = { 1, 1, 3, 4 }; int n4 = arr4.length; System.out.println(small.findSmallest(arr4, n4)); diff --git a/src/geeksforgeeks/GrammarMistake.java b/src/geeksforgeeks/GrammarMistake.java new file mode 100644 index 0000000..e5f290c --- /dev/null +++ b/src/geeksforgeeks/GrammarMistake.java @@ -0,0 +1,105 @@ +package geeksforgeeks; + +class GrammarMistake { + + // Method to check a given sentence for given rules + static boolean checkSentence(char[] str) { + + // Calculate the length of the string. + int len = str.length; + + // Check that the first character lies in [A-Z]. + // Otherwise return false. + if (str[0] < 'A' || str[0] > 'Z') { + return false; + } + + // If the last character is not a full stop(.) + // no need to check further. + if (str[len - 1] != '.') { + return false; + } + + // Maintain 2 states. Previous and current state + // based on which vertex state you are. + // Initialise both with 0 = start state. + int prev_state = 0, curr_state = 0; + + // Keep the index to the next character in the string. + int index = 1; + + // Loop to go over the string. + while (index <= str.length) { + + // Set states according to the input characters + // in the string and the rule defined in the description. + // If current character is [A-Z]. Set current state as 0. + if (str[index] >= 'A' && str[index] <= 'Z') { + curr_state = 0; + } + + // If current character is a space. + // Set current state as 1. + else if (str[index] == ' ') { + curr_state = 1; + } + + // If current character is [a-z]. + // Set current state as 2. + else if (str[index] >= 'a' && str[index] <= 'z') { + curr_state = 2; + } + + // If current state is a dot(.). + // Set current state as 3. + else if (str[index] == '.') { + curr_state = 3; + } + + // Validates all current state with previous state + // for the rules in the description of the problem. + if (prev_state == curr_state && curr_state != 2) { + return false; + } + + if (prev_state == 2 && curr_state == 0) { + return false; + } + + // If we have reached last state and previous state + // is not 1, then check next character. If next character + // is '\0', then return true, else false + // "My name is Ram." + if (curr_state == 3 && prev_state != 1) { + return (index + 1 == str.length); + } + + index++; + + // Set previous state as current state + // before going over to the next character. + prev_state = curr_state; + } + return false; + } + + // Driver Code + public static void main(String[] args) { + String[] str = { "I love cinema.", "The vertex is S.", "I am single.", "My name is KG.", "I lovE cinema.", + "GeeksQuiz. is a quiz site.", "I love Geeksquiz and Geeksforgeeks.", " You are my friend.", + "I love cinema" }; + int str_size = str.length; + + int i = 0; + for (i = 0; i < str_size; i++) { + if (checkSentence(str[i].toCharArray())) { + System.out.println("\"" + str[i] + "\"" + " is correct"); + } else { + System.out.println("\"" + str[i] + "\"" + " is incorrect"); + } + } + } +} + +// This code is contributed by +// sanjeev2552 diff --git a/src/geeksforgeeks/IntegerToBinary.java b/src/geeksforgeeks/IntegerToBinary.java new file mode 100644 index 0000000..96135a7 --- /dev/null +++ b/src/geeksforgeeks/IntegerToBinary.java @@ -0,0 +1,31 @@ +package geeksforgeeks;// Java program to convert a decimal +// number to binary number + +class IntegerToBinary { + // function to convert decimal to binary + static void decToBinary(int n) { + // array to store binary number + int[] binaryNum = new int[1000]; + + // counter for binary array + int i = 0; + while (n > 0) { + // storing remainder in binary array + binaryNum[i] = n % 2; + n = n / 2; + i++; + } + + // printing binary array in reverse order + for (int j = i - 1; j >= 0; j--) + System.out.print(binaryNum[j]); + } + + public static void main(String[] args) { + int n = 4; + decToBinary(n); + // System.out.println("Default method :" + Integer.toBinaryString(4)); + } +} + +// Contributed by Pramod Kumar diff --git a/src/geeksforgeeks/MaximumDifference.java b/src/geeksforgeeks/MaximumDifference.java index f5e8c00..3ad0403 100644 --- a/src/geeksforgeeks/MaximumDifference.java +++ b/src/geeksforgeeks/MaximumDifference.java @@ -15,19 +15,21 @@ static int maxDiff(int arr[], int n) { diff = arr[i + 1] - arr[i]; - if (previousSum > 0) + if (previousSum > 0) { previousSum += diff; - else + } else { previousSum = diff; + } - if (previousSum > maxSum) + if (previousSum > maxSum) { maxSum = previousSum; + } } return maxSum; } public static void main(String[] args) { - int arr[] = {2, 4, 1, 3, 10, 8, 5}; + int arr[] = { 2, 4, 1, 3, 10, 8, 5 }; int n = arr.length; System.out.print("Maximum difference is " + maxDiff(arr, n)); diff --git a/src/geeksforgeeks/MaximumSubarray.java b/src/geeksforgeeks/MaximumSubarray.java index 8d7a333..1407118 100644 --- a/src/geeksforgeeks/MaximumSubarray.java +++ b/src/geeksforgeeks/MaximumSubarray.java @@ -36,9 +36,8 @@ public static int maxSumSubArray(int[] nums) { return maxSoFar; } - public static void main(String[] args) { - int arr[] = {1, -2, -3, 0, 8, 7, -2}; + int arr[] = { 1, -2, -3, 0, 8, 7, -2 }; System.out.println("Maximum Sub array product is " + maxSumSubArray(arr)); } From fe37e758b99e5abe6717cccb7cd21ad279901700 Mon Sep 17 00:00:00 2001 From: Thangaraj A Date: Wed, 11 Mar 2020 22:23:06 +0530 Subject: [PATCH 21/51] Adding some problems --- src/geeksforgeeks/FirstMissingPositive.java | 89 ++++++++++--------- .../FirstNonRepeatedCharacter.java | 38 ++++---- src/geeksforgeeks/FlattenLinkedList.java | 16 ++-- .../FlattenMultiLevelLinkedList.java | 8 +- .../FlipMaximizeZeroesSubarrayKadane.java | 19 ++-- ...lipZeroesToFormConsecutiveMaximumOnes.java | 8 +- src/geeksforgeeks/GameOfLife.java | 2 + src/geeksforgeeks/GrammarMistake.java | 3 + src/geeksforgeeks/GraphSplitwiseSimplify.java | 5 +- src/geeksforgeeks/HappyNumber.java | 3 + src/geeksforgeeks/HouseRobber.java | 8 +- src/geeksforgeeks/MaximumSubarray.java | 22 +++-- 12 files changed, 130 insertions(+), 91 deletions(-) diff --git a/src/geeksforgeeks/FirstMissingPositive.java b/src/geeksforgeeks/FirstMissingPositive.java index 67e5dfb..4074221 100644 --- a/src/geeksforgeeks/FirstMissingPositive.java +++ b/src/geeksforgeeks/FirstMissingPositive.java @@ -2,55 +2,56 @@ /** * https://leetcode.com/problems/first-missing-positive/ - * */ public class FirstMissingPositive { - public int firstMissingPositive(int[] A) { - int i = 0; - while (i < A.length) { - if (A[i] == i + 1 || A[i] <= 0 || A[i] > A.length) - i++; - else if (A[A[i] - 1] != A[i]) - swap(A, i, A[i] - 1); - else - i++; - } - i = 0; - while (i < A.length && A[i] == i + 1) - i++; - return i + 1; - } + public int firstMissingPositive(int[] A) { + int i = 0; + while (i < A.length) { + if (A[i] == i + 1 || A[i] <= 0 || A[i] > A.length) { + i++; + } else if (A[A[i] - 1] != A[i]) { + swap(A, i, A[i] - 1); + } else { + i++; + } + } + i = 0; + while (i < A.length && A[i] == i + 1) + i++; + return i + 1; + } - private void swap(int[] A, int i, int j) { - int temp = A[i]; - A[i] = A[j]; - A[j] = temp; - } + private void swap(int[] A, int i, int j) { + int temp = A[i]; + A[i] = A[j]; + A[j] = temp; + } - public int firstMissingPositiveWithExtraSpace(int[] nums) { - if (nums == null || nums.length == 0) - return 1; - int length = nums.length; - int[] arr = new int[length + 1]; - for (int i = 0; i < length; i++) { - if (nums[i] <= length && nums[i] > 0) { - arr[--nums[i]] = -1; - } - } + public int firstMissingPositiveWithExtraSpace(int[] nums) { + if (nums == null || nums.length == 0) { + return 1; + } + int length = nums.length; + int[] arr = new int[length + 1]; + for (int i = 0; i < length; i++) { + if (nums[i] <= length && nums[i] > 0) { + arr[--nums[i]] = -1; + } + } - for (int i = 0; i < arr.length; i++) { - if (arr[i] != -1) { - return ++i; - } - } - return -1; - } + for (int i = 0; i < arr.length; i++) { + if (arr[i] != -1) { + return ++i; + } + } + return -1; + } - public static void main(String[] args) { - int[] arr = { 3, 4, -1, 1 }; - FirstMissingPositive fmp = new FirstMissingPositive(); - System.out.println(fmp.firstMissingPositive(arr)); - System.out.println(fmp.firstMissingPositiveWithExtraSpace(arr)); - } + public static void main(String[] args) { + int[] arr = { 3, 4, -1, 1 }; + FirstMissingPositive fmp = new FirstMissingPositive(); + System.out.println(fmp.firstMissingPositive(arr)); + System.out.println(fmp.firstMissingPositiveWithExtraSpace(arr)); + } } \ No newline at end of file diff --git a/src/geeksforgeeks/FirstNonRepeatedCharacter.java b/src/geeksforgeeks/FirstNonRepeatedCharacter.java index 43a90e3..d68d349 100644 --- a/src/geeksforgeeks/FirstNonRepeatedCharacter.java +++ b/src/geeksforgeeks/FirstNonRepeatedCharacter.java @@ -1,24 +1,26 @@ package geeksforgeeks; public class FirstNonRepeatedCharacter { - public static int firstUniqChar(String s) { - int freq[] = new int[26]; - for (int i = 0; i < s.length(); i++) - freq[s.charAt(i) - 'a']++; - // loop the same string again to find first occurrence not freq array - for (int i = 0; i < s.length(); i++) - if (freq[s.charAt(i) - 'a'] == 1) - return i; - return -1; - } + public static int firstUniqChar(String s) { + int freq[] = new int[26]; + for (int i = 0; i < s.length(); i++) + freq[s.charAt(i) - 'a']++; + // loop the same string again to find first occurrence not freq array + for (int i = 0; i < s.length(); i++) + if (freq[s.charAt(i) - 'a'] == 1) { + return i; + } + return -1; + } - public static void main(String args[]) { - String str = "geeksforgeeks"; + public static void main(String args[]) { + String str = "geeksforgeeks"; - int index = firstUniqChar(str); - if (index == -1) - System.out.print("Either all characters are " + "repeating or string is empty"); - else - System.out.print("First non-repeating character" + " is " + str.charAt(index)); - } + int index = firstUniqChar(str); + if (index == -1) { + System.out.print("Either all characters are repeating or string is empty"); + } else { + System.out.print("First non-repeating character" + " is " + str.charAt(index)); + } + } } diff --git a/src/geeksforgeeks/FlattenLinkedList.java b/src/geeksforgeeks/FlattenLinkedList.java index 1e2e95c..9fbbcbe 100644 --- a/src/geeksforgeeks/FlattenLinkedList.java +++ b/src/geeksforgeeks/FlattenLinkedList.java @@ -1,5 +1,8 @@ package geeksforgeeks; +/** + * https://www.techiedelight.com/flatten-linked-list/ + */ class FlattenLinkedList { Node head; @@ -19,7 +22,6 @@ public String toString() { } } - Node mergeIterative(Node a, Node b) { Node dummy = new Node(0); Node result = dummy; @@ -49,8 +51,9 @@ Node mergeIterative(Node a, Node b) { } Node flatten(Node root) { - if (root == null || root.right == null) + if (root == null || root.right == null) { return root; + } root.right = flatten(root.right); @@ -59,7 +62,6 @@ Node flatten(Node root) { return root; } - public static void main(String args[]) { flattenList(); } @@ -120,9 +122,13 @@ void printList() { } Node merge(Node a, Node b) { - if (a == null) return b; + if (a == null) { + return b; + } - if (b == null) return a; + if (b == null) { + return a; + } Node result; diff --git a/src/geeksforgeeks/FlattenMultiLevelLinkedList.java b/src/geeksforgeeks/FlattenMultiLevelLinkedList.java index f054faa..f1db59b 100644 --- a/src/geeksforgeeks/FlattenMultiLevelLinkedList.java +++ b/src/geeksforgeeks/FlattenMultiLevelLinkedList.java @@ -4,7 +4,9 @@ class FlattenMultiLevelLinkedList { public Node flatten(Node head) { - if (head == null) return head; + if (head == null) { + return head; + } // Pointer Node p = head; while (p != null) { @@ -19,7 +21,9 @@ public Node flatten(Node head) { temp = temp.next; // Connect tail with p.next, if it is not null temp.next = p.next; - if (p.next != null) p.next.prev = temp; + if (p.next != null) { + p.next.prev = temp; + } // Connect p with p.child, and remove p.child p.next = p.child; p.child.prev = p; diff --git a/src/geeksforgeeks/FlipMaximizeZeroesSubarrayKadane.java b/src/geeksforgeeks/FlipMaximizeZeroesSubarrayKadane.java index 1f10903..115d9b2 100644 --- a/src/geeksforgeeks/FlipMaximizeZeroesSubarrayKadane.java +++ b/src/geeksforgeeks/FlipMaximizeZeroesSubarrayKadane.java @@ -2,23 +2,30 @@ /** * https://www.geeksforgeeks.org/maximize-number-0s-flipping-subarray/ + *

+ * Problem : flip 1's to 0's so that total no.of 0's in array is maximized */ class FlipMaximizeZeroesSubarrayKadane { public static int findMaxZeroCount(int arr[], int n) { int zeroCount = 0; - int maxSoFar = 0; - int maxEndingHere = 0; + int maxSoFar = Integer.MIN_VALUE; + int sum = 0; for (int i = 0; i < n; i++) { - if (arr[i] == 0) + if (arr[i] == 0) { zeroCount++; + } int val = (arr[i] == 1) ? 1 : -1; - maxEndingHere = Math.max(val, maxEndingHere + val); - maxSoFar = Math.max(maxSoFar, maxEndingHere); + sum = sum + val; + + if (sum < 0) { + sum = 0; + } + maxSoFar = Math.max(maxSoFar, sum); } maxSoFar = Math.max(0, maxSoFar); @@ -26,7 +33,7 @@ public static int findMaxZeroCount(int arr[], int n) { } public static void main(String[] args) { - int arr[] = {0, 1, 0, 0, 1, 1, 0}; + int arr[] = { 0, 1, 0, 0, 1, 1, 0 }; System.out.println(findMaxZeroCount(arr, arr.length)); } diff --git a/src/geeksforgeeks/FlipZeroesToFormConsecutiveMaximumOnes.java b/src/geeksforgeeks/FlipZeroesToFormConsecutiveMaximumOnes.java index 535afdb..66590b7 100644 --- a/src/geeksforgeeks/FlipZeroesToFormConsecutiveMaximumOnes.java +++ b/src/geeksforgeeks/FlipZeroesToFormConsecutiveMaximumOnes.java @@ -30,7 +30,6 @@ public static void longestSeq(int[] A, int k) { if (A[left] == 0) { count--; } - left++; } @@ -43,13 +42,14 @@ public static void longestSeq(int[] A, int k) { } } - System.out.println("The longest sequence has length " + window + " from index " + leftIndex + " to " - + (leftIndex + window - 1)); + System.out.println( + "The longest sequence has length " + window + " from index " + leftIndex + " to " + (leftIndex + window + - 1)); } // main function public static void main(String[] args) { - int[] A = {1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0}; + int[] A = { 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0 }; int k = 1; longestSeq(A, k); diff --git a/src/geeksforgeeks/GameOfLife.java b/src/geeksforgeeks/GameOfLife.java index cca3480..c44b7e3 100644 --- a/src/geeksforgeeks/GameOfLife.java +++ b/src/geeksforgeeks/GameOfLife.java @@ -4,6 +4,8 @@ /** * https://forum.letstalkalgorithms.com/t/game-of-life/516/2 + *

+ * https://leetcode.com/problems/game-of-life/ */ public class GameOfLife { diff --git a/src/geeksforgeeks/GrammarMistake.java b/src/geeksforgeeks/GrammarMistake.java index e5f290c..97efea5 100644 --- a/src/geeksforgeeks/GrammarMistake.java +++ b/src/geeksforgeeks/GrammarMistake.java @@ -1,5 +1,8 @@ package geeksforgeeks; +/** + * https://www.geeksforgeeks.org/check-given-sentence-given-set-simple-grammer-rules/ + */ class GrammarMistake { // Method to check a given sentence for given rules diff --git a/src/geeksforgeeks/GraphSplitwiseSimplify.java b/src/geeksforgeeks/GraphSplitwiseSimplify.java index 068b8b4..64d9f12 100644 --- a/src/geeksforgeeks/GraphSplitwiseSimplify.java +++ b/src/geeksforgeeks/GraphSplitwiseSimplify.java @@ -33,10 +33,11 @@ public AdjNode(int adjV, int debt) { @Override public boolean equals(Object o) { - if (this.adjV == ((AdjNode) o).adjV) + if (this.adjV == ((AdjNode) o).adjV) { return true; - else + } else { return false; + } } public String toString() { diff --git a/src/geeksforgeeks/HappyNumber.java b/src/geeksforgeeks/HappyNumber.java index c8af4a7..b852b5a 100644 --- a/src/geeksforgeeks/HappyNumber.java +++ b/src/geeksforgeeks/HappyNumber.java @@ -3,6 +3,9 @@ import java.util.HashSet; import java.util.Set; +/** + * https://leetcode.com/problems/happy-number/ + */ class HappyNumber { public boolean isHappy(int n) { diff --git a/src/geeksforgeeks/HouseRobber.java b/src/geeksforgeeks/HouseRobber.java index 6cd604f..6c4fcd9 100644 --- a/src/geeksforgeeks/HouseRobber.java +++ b/src/geeksforgeeks/HouseRobber.java @@ -5,7 +5,7 @@ import java.util.Queue; /** - * @author i312458 + * https://leetcode.com/problems/house-robber/ */ public class HouseRobber { @@ -22,4 +22,10 @@ public int rob(int[] nums) { } return incl; } + + public static void main(String[] args) { + int[] arr = { 2, 7, 9, 3, 1 }; + HouseRobber houseRobber = new HouseRobber(); + System.out.println(houseRobber.rob(arr)); + } } diff --git a/src/geeksforgeeks/MaximumSubarray.java b/src/geeksforgeeks/MaximumSubarray.java index 1407118..0da7679 100644 --- a/src/geeksforgeeks/MaximumSubarray.java +++ b/src/geeksforgeeks/MaximumSubarray.java @@ -24,16 +24,20 @@ public static int maxProductSubArray(int[] A) { return maxsofar; } - public static int maxSumSubArray(int[] nums) { - - int maxSoFar = nums[0]; - int maxEndingHere = nums[0]; - - for (int i = 1; i < nums.length; i++) { - maxEndingHere = Math.max(maxEndingHere + nums[i], nums[i]); - maxSoFar = Math.max(maxSoFar, maxEndingHere); + public static int maxSumSubArray(int[] arr) { + + int max = Integer.MIN_VALUE; + int sum = 0; + + for (int i = 1; i < arr.length; i++) { + sum = sum + arr[i]; + if (sum < 0) { + //get i if you want to get index of subarray + sum = 0; + } + max = Math.max(sum, max); } - return maxSoFar; + return sum; } public static void main(String[] args) { From 7ad045274b939430538b225613d462c375027060 Mon Sep 17 00:00:00 2001 From: Thangaraj A Date: Thu, 19 Mar 2020 22:19:01 +0530 Subject: [PATCH 22/51] Adding more problems --- src/geeksforgeeks/HappyNumber.java | 6 +- src/geeksforgeeks/HouseRobber.java | 4 - .../InorderSuccessorPredecessor.java | 27 ++- src/geeksforgeeks/IntegerToBinary.java | 17 +- src/geeksforgeeks/IntersectionOfArrays.java | 14 +- src/geeksforgeeks/Islands.java | 8 +- src/geeksforgeeks/IsomorphicArray.java | 14 +- src/geeksforgeeks/IsomorphicString.java | 3 +- src/geeksforgeeks/KthClosestOrigin.java | 179 +++++++++--------- .../KthSmallestFromTwoSortedArrays.java | 12 +- src/geeksforgeeks/KthSmallestMatrix.java | 7 +- src/geeksforgeeks/LargestPossibleNumber.java | 13 +- ... => LargestSubArrayWithZeroesAndOnes.java} | 9 +- src/geeksforgeeks/LiveCellDeadCellGame.java | 38 ++++ src/geeksforgeeks/LivecellDeadCellGame.java | 28 --- src/geeksforgeeks/LongestIncreasingPath.java | 7 +- .../LongestSpanWithSameSumArray.java | 15 +- .../LongestSubArraySumUtmostK.java | 8 +- .../MedianOfTwoSortedArrays.java | 57 ++++++ src/geeksforgeeks/MergeIntervals.java | 1 - src/geeksforgeeks/UniqueElementsInArray.java | 29 +++ 21 files changed, 319 insertions(+), 177 deletions(-) rename src/geeksforgeeks/{LargestSubArray.java => LargestSubArrayWithZeroesAndOnes.java} (84%) create mode 100644 src/geeksforgeeks/LiveCellDeadCellGame.java delete mode 100644 src/geeksforgeeks/LivecellDeadCellGame.java create mode 100644 src/geeksforgeeks/MedianOfTwoSortedArrays.java create mode 100644 src/geeksforgeeks/UniqueElementsInArray.java diff --git a/src/geeksforgeeks/HappyNumber.java b/src/geeksforgeeks/HappyNumber.java index b852b5a..4192512 100644 --- a/src/geeksforgeeks/HappyNumber.java +++ b/src/geeksforgeeks/HappyNumber.java @@ -9,18 +9,18 @@ class HappyNumber { public boolean isHappy(int n) { - Set set = new HashSet<>(); + Set visited = new HashSet<>(); int sum = String.valueOf(n).chars().map(Character::getNumericValue).map(val -> val * val).sum() == 1 ? 1 : n; while (true) { if (sum == 1) { return true; } sum = String.valueOf(sum).chars().map(Character::getNumericValue).map(val -> val * val).sum(); - if (set.contains(sum)) { + if (visited.contains(sum)) { return false; } - set.add(sum); + visited.add(sum); } } diff --git a/src/geeksforgeeks/HouseRobber.java b/src/geeksforgeeks/HouseRobber.java index 6c4fcd9..67b8bef 100644 --- a/src/geeksforgeeks/HouseRobber.java +++ b/src/geeksforgeeks/HouseRobber.java @@ -1,9 +1,5 @@ package geeksforgeeks; -import java.util.Collections; -import java.util.PriorityQueue; -import java.util.Queue; - /** * https://leetcode.com/problems/house-robber/ */ diff --git a/src/geeksforgeeks/InorderSuccessorPredecessor.java b/src/geeksforgeeks/InorderSuccessorPredecessor.java index 76f1bda..31fd36e 100644 --- a/src/geeksforgeeks/InorderSuccessorPredecessor.java +++ b/src/geeksforgeeks/InorderSuccessorPredecessor.java @@ -45,6 +45,26 @@ public void successorPredecessor(TNode root, int val) { } } + public void shortSolution(TNode root, int val) { + if (root != null) { + if (root.data > val) { + // we make the root as successor because we might have a + // situation when value matches with the root, it wont have + // right subtree to find the successor, in that case we need + // parent to be the successor + successor = root.data; + successorPredecessor(root.left, val); + } else if (root.data < val) { + // we make the root as predecessor because we might have a + // situation when value matches with the root, it wont have + // left subtree to find the predecessor, in that case we need + // parent to be the predecessor. + predecessor = root.data; + successorPredecessor(root.right, val); + } + } + } + public static void main(String args[]) { TNode root = new TNode(25); root.left = new TNode(15); @@ -57,7 +77,12 @@ public static void main(String args[]) { root.left.right.left = new TNode(19); root.left.right.right = new TNode(20); InorderSuccessorPredecessor i = new InorderSuccessorPredecessor(); - i.successorPredecessor(root, 20); + + // i.successorPredecessor(root, 20); +/* TNode tempSuccessor = root.right; + TNode successor = i.findSuccessor(tempSuccessor); + successor = successor==null?tempSuccessor:successor;*/ + System.out.println("Inorder Successor of 10 is : " + successor + " and predecessor is : " + predecessor); } diff --git a/src/geeksforgeeks/IntegerToBinary.java b/src/geeksforgeeks/IntegerToBinary.java index 96135a7..c16ffc3 100644 --- a/src/geeksforgeeks/IntegerToBinary.java +++ b/src/geeksforgeeks/IntegerToBinary.java @@ -1,5 +1,4 @@ -package geeksforgeeks;// Java program to convert a decimal -// number to binary number +package geeksforgeeks; class IntegerToBinary { // function to convert decimal to binary @@ -23,9 +22,17 @@ static void decToBinary(int n) { public static void main(String[] args) { int n = 4; - decToBinary(n); + // decToBinary(n); // System.out.println("Default method :" + Integer.toBinaryString(4)); + System.out.println(intToBinary(4)); } -} -// Contributed by Pramod Kumar + public static String intToBinary(int n) { + String s = ""; + while (n > 0) { + s = ((n % 2) == 0 ? "0" : "1") + s; + n = n / 2; + } + return s; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/IntersectionOfArrays.java b/src/geeksforgeeks/IntersectionOfArrays.java index a0dad5c..fac00d3 100644 --- a/src/geeksforgeeks/IntersectionOfArrays.java +++ b/src/geeksforgeeks/IntersectionOfArrays.java @@ -1,6 +1,7 @@ package geeksforgeeks; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; /** @@ -16,15 +17,18 @@ * Output: [4,9] */ public class IntersectionOfArrays { + public static void main(String[] args) { + IntersectionOfArrays intersectionOfArrays = new IntersectionOfArrays(); + int[] nums1 = { 4, 4, 9, 5 }; + int[] nums2 = { 9, 4, 9, 4, 2, 3 }; + System.out.println(Arrays.toString(intersectionOfArrays.intersect(nums1, nums2))); + } + public int[] intersect(int[] nums1, int[] nums2) { HashMap map = new HashMap<>(); ArrayList result = new ArrayList<>(); for (int i = 0; i < nums1.length; i++) { - if (map.containsKey(nums1[i])) { - map.put(nums1[i], map.get(nums1[i]) + 1); - } else { - map.put(nums1[i], 1); - } + map.put(nums1[i], map.getOrDefault(nums1[i], 1)); } for (int i = 0; i < nums2.length; i++) { diff --git a/src/geeksforgeeks/Islands.java b/src/geeksforgeeks/Islands.java index 948f3bb..49a8bad 100644 --- a/src/geeksforgeeks/Islands.java +++ b/src/geeksforgeeks/Islands.java @@ -11,8 +11,9 @@ class Islands { public int numIslands(int[][] grid) { int count = 0; n = grid.length; - if (n == 0) + if (n == 0) { return 0; + } m = grid[0].length; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) @@ -25,8 +26,9 @@ public int numIslands(int[][] grid) { } private void DFSMarking(int[][] grid, int i, int j) { - if (i < 0 || j < 0 || i >= n || j >= m || grid[i][j] != 1) + if (i < 0 || j < 0 || i >= n || j >= m || grid[i][j] != 1) { return; + } grid[i][j] = 0; DFSMarking(grid, i + 1, j); DFSMarking(grid, i - 1, j); @@ -35,7 +37,7 @@ private void DFSMarking(int[][] grid, int i, int j) { } public static void main(String[] args) { - int M[][] = new int[][]{{1, 1, 1, 1, 0}, {1, 1, 0, 1, 0}, {1, 1, 0, 0, 0}, {0, 0, 0, 0, 0}}; + int M[][] = new int[][] { { 1, 1, 1, 1, 0 }, { 1, 1, 0, 1, 0 }, { 1, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0 } }; Islands I = new Islands(); System.out.println("Number of islands is: " + I.numIslands(M)); } diff --git a/src/geeksforgeeks/IsomorphicArray.java b/src/geeksforgeeks/IsomorphicArray.java index f0ded5e..9064cfe 100644 --- a/src/geeksforgeeks/IsomorphicArray.java +++ b/src/geeksforgeeks/IsomorphicArray.java @@ -7,18 +7,21 @@ import java.util.List; import java.util.Map; +// unresolved public class IsomorphicArray { public Collection> groupIsomorphicStrings(List strings) { - if (strings == null || strings.isEmpty()) + if (strings == null || strings.isEmpty()) { return Collections.EMPTY_LIST; + } Map> hashToList = new HashMap<>(); for (String string : strings) { String hash = hash(string); - if (!hashToList.containsKey(hash)) + if (!hashToList.containsKey(hash)) { hashToList.put(hash, new ArrayList<>()); + } hashToList.get(hash).add(string); } @@ -26,8 +29,9 @@ public Collection> groupIsomorphicStrings(List strings) { } private String hash(String s) { - if (s.isEmpty()) + if (s.isEmpty()) { return ""; + } int count = 1; StringBuilder hash = new StringBuilder(); @@ -36,9 +40,9 @@ private String hash(String s) { for (char c : s.toCharArray()) { - if (map.containsKey(c)) + if (map.containsKey(c)) { hash.append(map.get(c)); - else { + } else { map.put(c, count++); hash.append(map.get(c)); } diff --git a/src/geeksforgeeks/IsomorphicString.java b/src/geeksforgeeks/IsomorphicString.java index 3fae7d5..a953099 100644 --- a/src/geeksforgeeks/IsomorphicString.java +++ b/src/geeksforgeeks/IsomorphicString.java @@ -13,8 +13,9 @@ static boolean isIsomorphic(String s, String t) { for (int i = 0; i < n; ++i) { // it checks the count of the character in the array ; // for 'g' -> a[103] is 2 and 'd' -> a[100] is 2 - if (m1[s.charAt(i)] != m2[t.charAt(i)]) + if (m1[s.charAt(i)] != m2[t.charAt(i)]) { return false; + } m1[s.charAt(i)] = i + 1; m2[t.charAt(i)] = i + 1; } diff --git a/src/geeksforgeeks/KthClosestOrigin.java b/src/geeksforgeeks/KthClosestOrigin.java index 323ebef..fb4967c 100644 --- a/src/geeksforgeeks/KthClosestOrigin.java +++ b/src/geeksforgeeks/KthClosestOrigin.java @@ -5,95 +5,98 @@ /** * https://leetcode.com/problems/k-closest-points-to-origin/solution/ - * */ class KthClosestOrigin { - static int[][] points = new int[3][2]; - - // quick select - public int[][] kClosest(int[][] points, int K) { - sort(0, points.length - 1, K); - return Arrays.copyOfRange(points, 0, K); - } - - public void sort(int i, int j, int K) { - if (i >= j) - return; - int k = new Random().nextInt(j - i + 1) + i; - swap(i, k); - - int mid = partition(i, j); - int leftLength = mid - i + 1; - if (K < leftLength) - sort(i, mid - 1, K); - else if (K > leftLength) - sort(mid + 1, j, K - leftLength); - } - - public int partition(int i, int j) { - int oi = i; - int pivot = dist(i); - i++; - - while (true) { - while (i < j && dist(i) < pivot) - i++; - while (i <= j && dist(j) > pivot) - j--; - if (i >= j) - break; - swap(i, j); - } - swap(oi, j); - return j; - } - - public int dist(int i) { - return points[i][0] * points[i][0] + points[i][1] * points[i][1]; - } - - public void swap(int i, int j) { - int t0 = points[i][0], t1 = points[i][1]; - points[i][0] = points[j][0]; - points[i][1] = points[j][1]; - points[j][0] = t0; - points[j][1] = t1; - } - - public int[][] kClosestOLogN(int[][] points, int K) { - int N = points.length; - int[] dists = new int[N]; - for (int i = 0; i < N; ++i) - dists[i] = distOLogN(points[i]); - - Arrays.sort(dists); - int distK = dists[K - 1]; - - int[][] ans = new int[K][2]; - int t = 0; - for (int i = 0; i < N; ++i) - if (distOLogN(points[i]) <= distK) - ans[t++] = points[i]; - return ans; - } - - public int distOLogN(int[] point) { - return point[0] * point[0] + point[1] * point[1]; - } - - public static void main(String[] args) { - KthClosestOrigin kth = new KthClosestOrigin(); - points[0][0] = 3; - points[0][1] = 3; - - points[1][0] = 5; - points[1][1] = -1; - - points[2][0] = 2; - points[2][1] = 4; - - // System.out.println(Arrays.deepToString(kth.kClosestOLogN(points, 1))); - System.out.println(Arrays.deepToString(kth.kClosest(points, 2))); - } + static int[][] points = new int[3][2]; + + // quick select + public int[][] kClosest(int[][] points, int K) { + sort(0, points.length - 1, K); + return Arrays.copyOfRange(points, 0, K); + } + + public void sort(int i, int j, int K) { + if (i >= j) { + return; + } + int k = new Random().nextInt(j - i + 1) + i; + swap(i, k); + + int mid = partition(i, j); + int leftLength = mid - i + 1; + if (K < leftLength) { + sort(i, mid - 1, K); + } else if (K > leftLength) { + sort(mid + 1, j, K - leftLength); + } + } + + public int partition(int i, int j) { + int oi = i; + int pivot = dist(i); + i++; + + while (true) { + while (i < j && dist(i) < pivot) + i++; + while (i <= j && dist(j) > pivot) + j--; + if (i >= j) { + break; + } + swap(i, j); + } + swap(oi, j); + return j; + } + + public int dist(int i) { + return points[i][0] * points[i][0] + points[i][1] * points[i][1]; + } + + public void swap(int i, int j) { + int t0 = points[i][0], t1 = points[i][1]; + points[i][0] = points[j][0]; + points[i][1] = points[j][1]; + points[j][0] = t0; + points[j][1] = t1; + } + + public int[][] kClosestOLogN(int[][] points, int K) { + int N = points.length; + int[] dists = new int[N]; + for (int i = 0; i < N; ++i) + dists[i] = distOLogN(points[i]); + + Arrays.sort(dists); + int distK = dists[K - 1]; + + int[][] ans = new int[K][2]; + int t = 0; + for (int i = 0; i < N; ++i) + if (distOLogN(points[i]) <= distK) { + ans[t++] = points[i]; + } + return ans; + } + + public int distOLogN(int[] point) { + return point[0] * point[0] + point[1] * point[1]; + } + + public static void main(String[] args) { + KthClosestOrigin kth = new KthClosestOrigin(); + points[0][0] = 3; + points[0][1] = 3; + + points[1][0] = 5; + points[1][1] = -1; + + points[2][0] = 2; + points[2][1] = 4; + + // System.out.println(Arrays.deepToString(kth.kClosestOLogN(points, 1))); + System.out.println(Arrays.deepToString(kth.kClosest(points, 2))); + } } diff --git a/src/geeksforgeeks/KthSmallestFromTwoSortedArrays.java b/src/geeksforgeeks/KthSmallestFromTwoSortedArrays.java index b27bf5d..d62166f 100644 --- a/src/geeksforgeeks/KthSmallestFromTwoSortedArrays.java +++ b/src/geeksforgeeks/KthSmallestFromTwoSortedArrays.java @@ -1,5 +1,8 @@ package geeksforgeeks; +/** + * https://www.geeksforgeeks.org/k-th-element-two-sorted-arrays/ + */ class KthSmallestFromTwoSortedArrays { public static int findKth(int[] A, int i, int[] B, int j, int k) { @@ -26,14 +29,15 @@ public static int findKth(int[] A, int i, int[] B, int j, int k) { } public static void main(String[] args) { - int arr1[] = {1,6,8,9,15}; - int arr2[] = {3,5,10,14,20}; + int arr1[] = { 1, 6, 8, 9, 15 }; + int arr2[] = { 3, 5, 10, 14, 20 }; int k = 6; int ans = findKth(arr1, 0, arr2, 0, k); - if (ans == -1) + if (ans == -1) { System.out.println("Invalid query"); - else + } else { System.out.println(ans); + } } } diff --git a/src/geeksforgeeks/KthSmallestMatrix.java b/src/geeksforgeeks/KthSmallestMatrix.java index ac71a24..29bebcb 100644 --- a/src/geeksforgeeks/KthSmallestMatrix.java +++ b/src/geeksforgeeks/KthSmallestMatrix.java @@ -13,17 +13,16 @@ public static int kthSmallest(int[][] matrix, int k) { for (int i = 0; i < k - 1; i++) { Points t = pq.poll(); System.out.println(t.x); - if (t.x == n - 1) + if (t.x == n - 1) { continue; + } pq.offer(new Points(t.x + 1, t.y, matrix[t.x + 1][t.y])); } return pq.poll().val; } public static void main(String[] args) { - int[][] matrix = {{1, 2, 9}, - {3, 11, 13}, - {4, 13, 15}}; + int[][] matrix = { { 1, 2, 9 }, { 3, 11, 13 }, { 4, 13, 15 } }; int k = 4; System.out.println(kthSmallest(matrix, k)); diff --git a/src/geeksforgeeks/LargestPossibleNumber.java b/src/geeksforgeeks/LargestPossibleNumber.java index 9f349c3..4540eae 100644 --- a/src/geeksforgeeks/LargestPossibleNumber.java +++ b/src/geeksforgeeks/LargestPossibleNumber.java @@ -5,9 +5,13 @@ import java.util.Comparator; import java.util.List; +/** + * https://www.geeksforgeeks.org/given-an-array-of-numbers-arrange-the-numbers-to-form-the-biggest-number/ + */ class LargestPossibleNumber { + public static void main(String[] args) { - int nums[] = {10, 68, 97, 9, 21, 12}; + int nums[] = { 10, 68, 97, 9, 21, 12 }; List numbers = Arrays.asList("10", "68", "97", "9", "21", "12"); Collections.sort(numbers, (a, b) -> (b + a).compareTo(a + b)); @@ -21,10 +25,9 @@ public String largestNumber(int[] nums) { arr[i] = String.valueOf(nums[i]); } - Arrays.sort(arr, - (a, b) -> { - return (b + a).compareTo(a + b); - }); + Arrays.sort(arr, (a, b) -> { + return (b + a).compareTo(a + b); + }); StringBuilder sb = new StringBuilder(); for (String s : arr) { diff --git a/src/geeksforgeeks/LargestSubArray.java b/src/geeksforgeeks/LargestSubArrayWithZeroesAndOnes.java similarity index 84% rename from src/geeksforgeeks/LargestSubArray.java rename to src/geeksforgeeks/LargestSubArrayWithZeroesAndOnes.java index 6abddb7..caae00e 100644 --- a/src/geeksforgeeks/LargestSubArray.java +++ b/src/geeksforgeeks/LargestSubArrayWithZeroesAndOnes.java @@ -3,7 +3,7 @@ import java.util.HashMap; /*https://www.geeksforgeeks.org/largest-subarray-with-equal-number-of-0s-and-1s/*/ -class LargestSubArray { +class LargestSubArrayWithZeroesAndOnes { int maxLen(int arr[], int n) { @@ -29,8 +29,9 @@ int maxLen(int arr[], int n) { maxLength = i - map.get(sum); endingIndex = i; } - } else + } else { map.put(sum, i); + } } for (int i = 0; i < n; i++) { @@ -44,8 +45,8 @@ int maxLen(int arr[], int n) { } public static void main(String[] args) { - LargestSubArray sub = new LargestSubArray(); - int arr[] = {0, 0, 0, 1, 0, 1, 1}; + LargestSubArrayWithZeroesAndOnes sub = new LargestSubArrayWithZeroesAndOnes(); + int arr[] = { 0, 0, 0, 1, 0, 1, 1 }; int n = arr.length; sub.maxLen(arr, n); diff --git a/src/geeksforgeeks/LiveCellDeadCellGame.java b/src/geeksforgeeks/LiveCellDeadCellGame.java new file mode 100644 index 0000000..2aecedc --- /dev/null +++ b/src/geeksforgeeks/LiveCellDeadCellGame.java @@ -0,0 +1,38 @@ +package geeksforgeeks; + +//https://leetcode.com/problems/game-of-life/discuss/73366/Clean-O(1)-space-O(mn)-time-Java-Solution +public class LiveCellDeadCellGame { + + public void gameOfLife(int[][] board) { + int[][] dir = { { 1, -1 }, { 1, 0 }, { 1, 1 }, { 0, -1 }, { 0, 1 }, { -1, -1 }, { -1, 0 }, { -1, 1 } }; + int row = board.length; + int col = board[0].length; + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + int liveCells = 0; + for (int k = 0; k < dir.length; k++) { + if (i + dir[k][0] >= row || j + dir[k][1] >= col || i + dir[k][0] < 0 || j + dir[k][1] < 0) { + continue; + } + if (board[i + dir[k][0]][j + dir[k][1]] == 1 || board[i + dir[k][0]][j + dir[k][1]] == 2) { + liveCells++; + } + } + + if (board[i][j] == 0 && liveCells == 3) { + board[i][j] = 3; + } + if (board[i][j] == 1 && (liveCells < 2 || liveCells > 3)) { + board[i][j] = 2; + } + } + } + + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + board[i][j] %= 2; + } + } + + } +} diff --git a/src/geeksforgeeks/LivecellDeadCellGame.java b/src/geeksforgeeks/LivecellDeadCellGame.java deleted file mode 100644 index 6641214..0000000 --- a/src/geeksforgeeks/LivecellDeadCellGame.java +++ /dev/null @@ -1,28 +0,0 @@ -package geeksforgeeks; -public class LivecellDeadCellGame { - //https://leetcode.com/problems/game-of-life/discuss/73366/Clean-O(1)-space-O(mn)-time-Java-Solution - public void gameOfLife(int[][] board) { - int[][] dir ={{1,-1},{1,0},{1,1},{0,-1},{0,1},{-1,-1},{-1,0},{-1,1}}; - int row=board.length; - int col=board[0].length; - for(int i=0; i=row || j+dir[k][1]>=col || i+dir[k][0]<0 || j+dir[k][1]<0) continue; - if(board[i+dir[k][0]][j+dir[k][1]]==1 || board[i+dir[k][0]][j+dir[k][1]]==2) liveCells++; - } - - if(board[i][j]==0 && liveCells==3) board[i][j]=3; - if(board[i][j]==1 && (liveCells<2 || liveCells>3)) board[i][j]=2; - } - } - - for(int i=0; i= matrix.length || j < 0 || j >= matrix[0].length || data >= matrix[i][j]) { return 0; } @@ -43,7 +44,7 @@ public static int dfsUtil(int[][] matrix, int i, int j, Integer[][] cache, int d return cache[i][j]; } - int max = 1; + int currLength = 1; for (int[] dir : dirs) { @@ -51,9 +52,9 @@ public static int dfsUtil(int[][] matrix, int i, int j, Integer[][] cache, int d int y = j + dir[1]; int count = 1 + dfsUtil(matrix, x, y, cache, matrix[i][j]); - max = Math.max(count, max); + currLength = Math.max(count, currLength); } - cache[i][j] = max; + cache[i][j] = currLength; return cache[i][j]; } diff --git a/src/geeksforgeeks/LongestSpanWithSameSumArray.java b/src/geeksforgeeks/LongestSpanWithSameSumArray.java index 71fe75b..9fca542 100644 --- a/src/geeksforgeeks/LongestSpanWithSameSumArray.java +++ b/src/geeksforgeeks/LongestSpanWithSameSumArray.java @@ -16,18 +16,17 @@ static int longestCommonSum(int[] arr1, int[] arr2, int n) { int maxLength = 0; for (int i = 0; i < n; i++) { - sum += arr[i]; - - if (sum == 0) + if (sum == 0) { maxLength = i + 1; + } - if (map.containsKey(sum)) + if (map.containsKey(sum)) { maxLength = Math.max(maxLength, i - map.get(sum)); - - else + } else { map.put(sum, i); + } } return maxLength; } @@ -35,8 +34,8 @@ static int longestCommonSum(int[] arr1, int[] arr2, int n) { public static void main(String args[]) { /* int[] arr1 = {0, 1, 0, 1, 1, 1, 1}; int[] arr2 = {1, 1, 1, 1, 1, 0, 1};*/ - int arr1[] = {0, 1, 0, 0, 1, 1, 1, 0}; - int arr2[] = {1, 1, 1, 1, 1, 1, 0, 1}; + int arr1[] = { 0, 1, 0, 0, 1, 1, 1, 0 }; + int arr2[] = { 1, 1, 1, 1, 1, 1, 0, 1 }; //{-1,0,-1,0,0,1,0} int n = arr1.length; System.out.println(longestCommonSum(arr1, arr2, n)); diff --git a/src/geeksforgeeks/LongestSubArraySumUtmostK.java b/src/geeksforgeeks/LongestSubArraySumUtmostK.java index 43e306e..c30dba7 100644 --- a/src/geeksforgeeks/LongestSubArraySumUtmostK.java +++ b/src/geeksforgeeks/LongestSubArraySumUtmostK.java @@ -6,31 +6,29 @@ // array is non-negative class LongestSubArraySumUtmostK { - public static int atMostSum(int arr[], int n, int target) { + public static int utMostSum(int arr[], int n, int target) { int sum = 0; int count = 0; int maxCount = 0; for (int i = 0; i < n; i++) { - //7 if ((sum + arr[i]) <= target) { sum += arr[i]; count++; } else if (sum != 0) { sum = sum - arr[i - count] + arr[i]; } - maxCount = Math.max(count, maxCount); } return maxCount; } public static void main(String[] args) { - int arr[] = {1, 2, 1, 0, 1, 1, 0}; + int arr[] = { 1, 2, 1, 0, 1, 1, 0 }; int n = arr.length; int k = 4; - System.out.print(atMostSum(arr, n, k)); + System.out.print(utMostSum(arr, n, k)); } } diff --git a/src/geeksforgeeks/MedianOfTwoSortedArrays.java b/src/geeksforgeeks/MedianOfTwoSortedArrays.java new file mode 100644 index 0000000..7eae057 --- /dev/null +++ b/src/geeksforgeeks/MedianOfTwoSortedArrays.java @@ -0,0 +1,57 @@ +package geeksforgeeks; + +/** + * https://github.com/mission-peace/interview/blob/master/src/com/interview/binarysearch/MedianOfTwoSortedArrayOfDifferentLength.java + */ +public class MedianOfTwoSortedArrays { + + public double findMedianSortedArrays(int input1[], int input2[]) { + //if input1 length is greater than switch them so that input1 is smaller than input2. + if (input1.length > input2.length) { + return findMedianSortedArrays(input2, input1); + } + int x = input1.length; + int y = input2.length; + + int low = 0; + int high = x; + while (low <= high) { + int partitionX = (low + high) / 2; + int partitionY = (x + y + 1) / 2 - partitionX; + + //if partitionX is 0 it means nothing is there on left side. Use -INF for maxLeftX + //if partitionX is length of input then there is nothing on right side. Use +INF for minRightX + int maxLeftX = (partitionX == 0) ? Integer.MIN_VALUE : input1[partitionX - 1]; + int minRightX = (partitionX == x) ? Integer.MAX_VALUE : input1[partitionX]; + + int maxLeftY = (partitionY == 0) ? Integer.MIN_VALUE : input2[partitionY - 1]; + int minRightY = (partitionY == y) ? Integer.MAX_VALUE : input2[partitionY]; + + if (maxLeftX <= minRightY && maxLeftY <= minRightX) { + //We have partitioned array at correct place + // Now get max of left elements and min of right elements to get the median in case of even length combined array size + // or get max of left for odd length combined array size. + if ((x + y) % 2 == 0) { + return ((double) Math.max(maxLeftX, maxLeftY) + Math.min(minRightX, minRightY)) / 2; + } else { + return Math.max(maxLeftX, maxLeftY); + } + } else if (maxLeftX > minRightY) { //we are too far on right side for partitionX. Go on left side. + high = partitionX - 1; + } else { //we are too far on left side for partitionX. Go on right side. + low = partitionX + 1; + } + } + + //Only we we can come here is if input arrays were not sorted. Throw in that scenario. + throw new IllegalArgumentException(); + } + + public static void main(String[] args) { + int[] x = { 1, 3, 8, 9, 15, 17 }; + int[] y = { 7, 11, 18, 19, 21, 25 }; + // 1,3,7,8,9,11,15,18,19,21,25 + MedianOfTwoSortedArrays mm = new MedianOfTwoSortedArrays(); + System.out.println(mm.findMedianSortedArrays(x, y)); + } +} diff --git a/src/geeksforgeeks/MergeIntervals.java b/src/geeksforgeeks/MergeIntervals.java index e6ab538..3e03701 100644 --- a/src/geeksforgeeks/MergeIntervals.java +++ b/src/geeksforgeeks/MergeIntervals.java @@ -24,7 +24,6 @@ public static int[][] merge(int[][] intervals) { result.add(prevInterval); } } - return result.toArray(new int[result.size()][]); } diff --git a/src/geeksforgeeks/UniqueElementsInArray.java b/src/geeksforgeeks/UniqueElementsInArray.java new file mode 100644 index 0000000..1b8fca6 --- /dev/null +++ b/src/geeksforgeeks/UniqueElementsInArray.java @@ -0,0 +1,29 @@ +package geeksforgeeks; + +/** + * https://codepumpkin.com/find-unique-array-element/#XORApproach + */ +public class UniqueElementsInArray { + + /** + * @param inputArray + * + * @return returns unique Element in the array. + * -1 if no unique element is available in the array. + */ + // 0 0 : 0 || 1 1 : 0 + // returns 0 if both are same + public static int xorApproach(int[] inputArray) { + int result = 0; + for (int i = 0; i < inputArray.length; i++) { + result ^= inputArray[i]; + } + + return (result > 0 ? result : -1); + } + + public static void main(String[] args) { + int[] nums = { 1, 2, 3, 2, 1, 4, 3 }; + xorApproach(nums); + } +} From 4a97d18ac5d1b45a4e82ddd52325368ec7ec1d20 Mon Sep 17 00:00:00 2001 From: vignesh Date: Thu, 19 Mar 2020 22:19:03 +0530 Subject: [PATCH 23/51] new problems march --- src/geeksforgeeks/.vscode/UrlEncode.java | 0 .../CountAllPathsFrom2DMatrix.java | 2 +- src/geeksforgeeks/FirstMissingPositive.java | 8 ++-- src/geeksforgeeks/IsEditOneDistanceAway.java | 44 +++++++++++++++++++ .../LinkedListRemoveDuplicates.java | 36 +++++++++++++++ src/geeksforgeeks/PalindromicSubSequence.java | 7 ++- src/geeksforgeeks/Pow.java | 29 ++++++++++++ src/geeksforgeeks/QueensAttackKing.java | 35 +++++++++++++++ src/geeksforgeeks/RaceCarMinSteps.java | 43 ++++++++++++++++++ src/geeksforgeeks/RotateMatrixInPlace.java | 30 +++++++++++++ src/geeksforgeeks/ShipPackageWithNDays.java | 36 +++++++++++++++ src/geeksforgeeks/SortStack.java | 27 ++++++++++++ src/geeksforgeeks/StockSpanner.java | 20 +++++++++ src/geeksforgeeks/UrlEncode.java | 33 ++++++++++++++ 14 files changed, 344 insertions(+), 6 deletions(-) create mode 100644 src/geeksforgeeks/.vscode/UrlEncode.java create mode 100644 src/geeksforgeeks/IsEditOneDistanceAway.java create mode 100644 src/geeksforgeeks/LinkedListRemoveDuplicates.java create mode 100644 src/geeksforgeeks/Pow.java create mode 100644 src/geeksforgeeks/QueensAttackKing.java create mode 100644 src/geeksforgeeks/RaceCarMinSteps.java create mode 100644 src/geeksforgeeks/ShipPackageWithNDays.java create mode 100644 src/geeksforgeeks/SortStack.java create mode 100644 src/geeksforgeeks/StockSpanner.java create mode 100644 src/geeksforgeeks/UrlEncode.java diff --git a/src/geeksforgeeks/.vscode/UrlEncode.java b/src/geeksforgeeks/.vscode/UrlEncode.java new file mode 100644 index 0000000..e69de29 diff --git a/src/geeksforgeeks/CountAllPathsFrom2DMatrix.java b/src/geeksforgeeks/CountAllPathsFrom2DMatrix.java index dd13894..9594a64 100644 --- a/src/geeksforgeeks/CountAllPathsFrom2DMatrix.java +++ b/src/geeksforgeeks/CountAllPathsFrom2DMatrix.java @@ -13,7 +13,7 @@ static int numberOfPaths(int m, int n) { int count[][] = new int[m][n]; // Count of paths to reach any cell in - // first column is 1 + // first row is 1 for (int i = 0; i < m; i++) count[i][0] = 1; diff --git a/src/geeksforgeeks/FirstMissingPositive.java b/src/geeksforgeeks/FirstMissingPositive.java index 67e5dfb..1bf437f 100644 --- a/src/geeksforgeeks/FirstMissingPositive.java +++ b/src/geeksforgeeks/FirstMissingPositive.java @@ -11,8 +11,10 @@ public int firstMissingPositive(int[] A) { while (i < A.length) { if (A[i] == i + 1 || A[i] <= 0 || A[i] > A.length) i++; - else if (A[A[i] - 1] != A[i]) + else if (A[A[i] - 1] != A[i]){ + System.out.println(A[A[i] - 1]+" "+A[i]); swap(A, i, A[i] - 1); + } else i++; } @@ -50,7 +52,7 @@ public int firstMissingPositiveWithExtraSpace(int[] nums) { public static void main(String[] args) { int[] arr = { 3, 4, -1, 1 }; FirstMissingPositive fmp = new FirstMissingPositive(); - System.out.println(fmp.firstMissingPositive(arr)); - System.out.println(fmp.firstMissingPositiveWithExtraSpace(arr)); + System.out.println("result "+fmp.firstMissingPositive(arr)); + //System.out.println(fmp.firstMissingPositiveWithExtraSpace(arr)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/IsEditOneDistanceAway.java b/src/geeksforgeeks/IsEditOneDistanceAway.java new file mode 100644 index 0000000..ad443e8 --- /dev/null +++ b/src/geeksforgeeks/IsEditOneDistanceAway.java @@ -0,0 +1,44 @@ +package geeksforgeeks; + +class IsEditOneDistanceAway { + static boolean isOneEdit(String first, String second) { + // if the input string are same + if (first.equals(second)) + return false; + + int len1 = first.length(); + int len2 = second.length(); + // If the length difference of the stings is more than 1, return false. + if ((len1 - len2) > 1 || (len2 - len1) > 1) { + return false; + } + int i = 0, j = 0; + int diff = 0; + while (i < len1 && j < len2) { + char f = first.charAt(i); + char s = second.charAt(j); + if (f != s) { + diff++; + if (len1 > len2) + i++; + if (len2 > len1) + j++; + if (len1 == len2) + i++; + j++; + } else { + i++; + j++; + } + if (diff > 1) { + return false; + } + } + // If the length of the string is not same. ex. "abc" and "abde" are not one + // edit distance. + if (diff == 1 && len1 != len2 && (i != len1 || j != len2)) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/LinkedListRemoveDuplicates.java b/src/geeksforgeeks/LinkedListRemoveDuplicates.java new file mode 100644 index 0000000..029e418 --- /dev/null +++ b/src/geeksforgeeks/LinkedListRemoveDuplicates.java @@ -0,0 +1,36 @@ +package geeksforgeeks; + +class LinkedListRemoveDuplicate{ + /** + * Method to remove duplicates from Linked list + * when no additional buffer is allowed. + * + * Time Complexity : O(n^2) + * Space Complexity : O(1) + * + * @param head + */ + public static void removeDuplicatesWithoutBuffer(LinkedListNode head) { + /* If head is null, stop processing */ + if (head == null) { + return; + } + /* We will need two pointers here i.e current and runner. + * When current is pointing to a node, move runner through + * rest of the list, checking for duplicates */ + LinkedListNode current = head; + while (current != null) { + /* Have runner point to current node */ + LinkedListNode runner = current; + while (runner.next != null) { + /* If it is duplicate, jump runner over the node */ + if (runner.next.data == current.data) { + runner.next = runner.next.next; + } else { + runner = runner.next; + } + } + current = current.next; + } + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/PalindromicSubSequence.java b/src/geeksforgeeks/PalindromicSubSequence.java index 3392f11..02fe5e7 100644 --- a/src/geeksforgeeks/PalindromicSubSequence.java +++ b/src/geeksforgeeks/PalindromicSubSequence.java @@ -8,9 +8,12 @@ public int longestPalindromeSubseq(String s) { for(int i=s.length()-1;i>=0;i--){ for(int j=i;j> queensAttacktheKing(int[][] queens, int[] king) { + List> result= new ArrayList<>(); + boolean[][] visited= new boolean[8][8]; + int[][]dirs= {{1,0},{-1,0},{0,1},{0,-1},{-1,-1},{1,1},{1,-1},{-1,1}}; + + for(int[] qu:queens){ + visited[qu[0]][qu[1]]=true; + } + + for(int[] dir: dirs){ + List temp= findQueensPosistions(king,dir[0],dir[1],visited); + if(temp!=null) result.add(temp); + } + + return result; + + } + + public List findQueensPosistions(int[] king, int x, int y, boolean[][] visited){ + int newX= x+king[0]; + int newY= y+king[1]; + + while(newX<8 && newY<8 && newX>=0 && newY>=0){ + if(visited[newX][newY]) return Arrays.asList(newX,newY); + newX+=x; + newY+=y; + + } + + return null; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/RaceCarMinSteps.java b/src/geeksforgeeks/RaceCarMinSteps.java new file mode 100644 index 0000000..1a5f293 --- /dev/null +++ b/src/geeksforgeeks/RaceCarMinSteps.java @@ -0,0 +1,43 @@ +package geeksforgeeks; +class RaceCarMinSteps { + public int racecar(int target) { + Set visited = new HashSet<>(); + Queue queue = new LinkedList<>(); + queue.add(new StateNode(1, 0)); + int distance = 0; + while (!queue.isEmpty()) { + int levelSize = queue.size(); + for (int i = 0; i < levelSize; i++) { + StateNode cur = queue.poll(); + if (cur.position == target) { + return distance; + } + // if A + int nextPosition = cur.position + cur.speed; + int nextSpeed = cur.speed * 2; + if (!visited.contains(nextSpeed + "," + nextPosition) && Math.abs(target - nextPosition) < target) { + visited.add(nextSpeed + "," + nextPosition); + queue.offer(new StateNode(nextSpeed, nextPosition)); + } + // if R + nextPosition = cur.position; + nextSpeed = cur.speed > 0 ? -1 : 1; + if (!visited.contains(nextSpeed + "," + nextPosition) && Math.abs(target - nextPosition) < target) { + visited.add(nextSpeed + "," + nextPosition); + queue.offer(new StateNode(nextSpeed, nextPosition)); + } + } + distance++; + } + return -1; + } +} + class StateNode { + int speed; + int position; + + public StateNode(int speed, int position) { + this.speed = speed; + this.position = position; + } + } \ No newline at end of file diff --git a/src/geeksforgeeks/RotateMatrixInPlace.java b/src/geeksforgeeks/RotateMatrixInPlace.java index 950813b..88879d9 100644 --- a/src/geeksforgeeks/RotateMatrixInPlace.java +++ b/src/geeksforgeeks/RotateMatrixInPlace.java @@ -43,6 +43,36 @@ static void rotateMatrix(int N, int mat[][]) { } } + public void rotate(int[][] matrix) { + if(matrix == null || matrix.length == 0 || matrix[0].length == 0)return; + int n= matrix.length-1; + + for(int i=0; imid){ + currentDay+=1; + sum=0; + + } + sum+=weight; + } + + return currentDay>D; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/SortStack.java b/src/geeksforgeeks/SortStack.java new file mode 100644 index 0000000..6efe7c2 --- /dev/null +++ b/src/geeksforgeeks/SortStack.java @@ -0,0 +1,27 @@ +package geeksforgeeks; + +class SortStack { + public static Stack sortStack(Stack input) { + /* If input is null, no processing needed */ + if (input == null) { + return null; + } + /* Create a temp stack */ + Stack tempStack = new Stack<>(); + /* Keep going until input is not empty */ + while (!input.isEmpty()) { + /* Pop value from input */ + int tempValue = input.pop(); + /* + * We want smallest one at the bottom. So keep comparing and if temp stack has + * bigger item, pop it and push it to input stack + */ + while (!tempStack.isEmpty() && tempStack.peek() > tempValue) { + input.push(tempStack.pop()); + } + /* Push temp value to the temp stack */ + tempStack.push(tempValue); + } + return tempStack; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/StockSpanner.java b/src/geeksforgeeks/StockSpanner.java new file mode 100644 index 0000000..fa9b77a --- /dev/null +++ b/src/geeksforgeeks/StockSpanner.java @@ -0,0 +1,20 @@ +package geeksforgeeks; + +class StockSpanner { + + Deque> stack; + public StockSpanner() { + this.stack= new ArrayDeque<>(); + } + + public int next(int price) { + int value=1; + while(!stack.isEmpty() && stack.peek().getKey()<=price){ + value+=stack.pop().getValue(); + } + + stack.push(new Pair(price,value)); + + return stack.peek().getValue(); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/UrlEncode.java b/src/geeksforgeeks/UrlEncode.java new file mode 100644 index 0000000..f950a13 --- /dev/null +++ b/src/geeksforgeeks/UrlEncode.java @@ -0,0 +1,33 @@ +package geeksforgeeks; + +class UrlEncode { + char[] replaceSpaces(char[] str, int truelength) { + int spaceCount = 0, index, i = 0; + for (i = 0; i < truelength; i++) { + if (str[i] == ' ') { + spaceCount++; + } + } + + index = truelength + spaceCount * 2; + if (truelength < str.length) + str[truelength] = ' '; + for (i = truelength - 1; i >= 0; i--) { + if (str[i] == ' ') { + str[index - 1] = '0'; + str[index - 2] = '2'; + str[index - 3] = '%'; + index = index - 3; + } else { + str[index - 1] = str[i]; + index--; + } + } + + return str; + } + + public static void main(String[] args) { + System.out.println(new UrlEncode().replaceSpaces("Mr John Smith ".toCharArray(), 13)); + } +} \ No newline at end of file From c7192830f95cd71fc099caddb61ebf3d7e1c8d8f Mon Sep 17 00:00:00 2001 From: Thangaraj A Date: Sun, 22 Mar 2020 22:33:24 +0530 Subject: [PATCH 24/51] Adding more problems --- src/geeksforgeeks/CelebrityProblem.java | 33 ++++---- .../CountNumbersLessThanSelf.java | 56 ++++++++------ src/geeksforgeeks/CourseSchedule.java | 61 +++++++++------ src/geeksforgeeks/DutchNationalFlag.java | 35 +++++---- src/geeksforgeeks/Flatten2DVector.java | 28 ++++--- src/geeksforgeeks/IslandBFS.java | 72 +++++++++-------- src/geeksforgeeks/LRUCache.java | 12 +-- .../LengthOfLongestSubstringKDistinct.java | 42 +++++----- .../LongestConsequtiveSequence.java | 37 +++++---- .../LongestSubArraySumUtmostK.java | 1 - src/geeksforgeeks/LongestUniqueSubstring.java | 11 ++- src/geeksforgeeks/MajorityVoting.java | 12 +-- src/geeksforgeeks/MakeAnArrayPalindrome.java | 2 +- src/geeksforgeeks/MatrixRowWithMax1.java | 14 ++-- src/geeksforgeeks/MaxHistogram.java | 1 + src/geeksforgeeks/MaximumDifference.java | 31 +++----- src/geeksforgeeks/MaximumSubarray.java | 8 +- .../MaximumSubstringWithKDistinctChar.java | 44 +++++++---- .../MaximumUnsortedSubarray.java | 73 ------------------ src/geeksforgeeks/MeetingRoomsII.java | 27 ++++--- src/geeksforgeeks/PascalsTriangle.java | 3 + src/geeksforgeeks/PreOrderInOrderTree.java | 49 +++++++----- src/geeksforgeeks/StockBuySellManyTimes.java | 18 +++-- src/geeksforgeeks/TestFreshWork.java | 77 +++++++++++++++++++ .../UnsortedSubarrayProblems.java | 51 ++++++++++++ src/geeksforgeeks/WordBreak.java | 27 ++++--- 26 files changed, 480 insertions(+), 345 deletions(-) delete mode 100644 src/geeksforgeeks/MaximumUnsortedSubarray.java create mode 100644 src/geeksforgeeks/TestFreshWork.java create mode 100644 src/geeksforgeeks/UnsortedSubarrayProblems.java diff --git a/src/geeksforgeeks/CelebrityProblem.java b/src/geeksforgeeks/CelebrityProblem.java index 68f1962..01ac872 100644 --- a/src/geeksforgeeks/CelebrityProblem.java +++ b/src/geeksforgeeks/CelebrityProblem.java @@ -3,22 +3,27 @@ public class CelebrityProblem { /** * @param n a party with n people + * * @return the celebrity's label or -1 */ public int findCelebrity(int n) { - int candidate=0; - for(int i=1;i countSmaller(int[] nums) { - if(nums.length==0) return new ArrayList<>(); - - Integer[] result= new Integer[nums.length]; - Node root=null; - for(int i=nums.length-1;i>=0;i--){ // build tree from end so that end is root and has sum 0 - root=buildBSTHelper(nums[i],root,result,i,0); + if (nums.length == 0) { + return new ArrayList<>(); + } + + Integer[] result = new Integer[nums.length]; + Node root = null; + for (int i = nums.length - 1; i >= 0; i--) { // build tree from end so that end is root and has sum 0 + root = buildBSTHelper(nums[i], root, result, i, 0); } return Arrays.asList(result); } - - public Node buildBSTHelper(int val, Node root, Integer[] result, int index, int sum){ - if(root==null){ - root= new Node(val,0); - result[index]=sum; - } - else if(root.val==val){ + + public Node buildBSTHelper(int val, Node root, Integer[] result, int index, int sum) { + if (root == null) { + root = new Node(val, 0); + result[index] = sum; + } else if (root.val == val) { root.dup++; - result[index]=sum+root.sum; - } - else if(root.val>val){ + result[index] = sum + root.sum; + } else if (root.val > val) { root.sum++; - root.left=buildBSTHelper(val,root.left,result,index,sum); - }else{ - root.right=buildBSTHelper(val,root.right,result,index,root.sum+root.dup+sum); + root.left = buildBSTHelper(val, root.left, result, index, sum); + } else { + root.right = buildBSTHelper(val, root.right, result, index, root.sum + root.dup + sum); } return root; } - - private class Node{ + + private class Node { int val; int sum; Node right; Node left; - int dup=1; - public Node(int val, int sum){ - this.val=val; - this.sum=sum; + int dup = 1; + + public Node(int val, int sum) { + this.val = val; + this.sum = sum; } } } \ No newline at end of file diff --git a/src/geeksforgeeks/CourseSchedule.java b/src/geeksforgeeks/CourseSchedule.java index 3bd531b..d0aed1d 100644 --- a/src/geeksforgeeks/CourseSchedule.java +++ b/src/geeksforgeeks/CourseSchedule.java @@ -1,35 +1,48 @@ package geeksforgeeks; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Queue; + class CourseSchedule { public boolean canFinish(int numCourses, int[][] prerequisites) { - - Map> map= new HashMap<>(); // Courses that depend on the key - int[] degrees= new int[numCourses]; // # of prerequisites for course i - Queue queue= new ArrayDeque<>(); // Used to find dependants and decrease their outdegree - - for(int[] pre: prerequisites){ - List tempList= map.getOrDefault(pre[1],new ArrayList<>()); + + Map> map = new HashMap<>(); // Courses that depend on the key + int[] degrees = new int[numCourses]; // # of prerequisites for course i + Queue queue = new ArrayDeque<>(); // Used to find dependants and decrease their outdegree + + for (int[] pre : prerequisites) { + List tempList = map.getOrDefault(pre[1], new ArrayList<>()); tempList.add(pre[0]); degrees[pre[0]]++; - map.put(pre[1],tempList); + map.put(pre[1], tempList); } - - for(int i=0;ipivot){ - swap(arr,i,j); + if (arr.length == 0) { + return; + } + int pivot = 1; + int i = 0; + int j = arr.length - 1; + int zeroPos = 0; + while (i <= j) { + if (arr[i] > pivot) { + swap(arr, i, j); j--; - }else if(arr[i]==pivot){ + } else if (arr[i] == pivot) { i++; - }else{ - swap(arr,zeroPos,i); + } else { + swap(arr, zeroPos, i); zeroPos++; i++; } } } - - public void swap(int[] arr, int i, int j){ - int temp=arr[j]; - arr[j]=arr[i]; - arr[i]=temp; + + public void swap(int[] arr, int i, int j) { + int temp = arr[j]; + arr[j] = arr[i]; + arr[i] = temp; } } \ No newline at end of file diff --git a/src/geeksforgeeks/Flatten2DVector.java b/src/geeksforgeeks/Flatten2DVector.java index 77141f2..38e6359 100644 --- a/src/geeksforgeeks/Flatten2DVector.java +++ b/src/geeksforgeeks/Flatten2DVector.java @@ -1,4 +1,7 @@ package geeksforgeeks; + +import java.util.List; + /* Thoughts: As hint indicates: use 2 pointers to hold position. @@ -6,12 +9,13 @@ Use hasNext to validate (x,y) and move x. Use next() to return (x,y) and move it(regardless of correctness, which is determined by hasNext()) */ public class Flatten2DVector { - private int x; - private int y; - private List> list; - public Vector2D(List> vec2d) { + private int x; + private int y; + private List> list; + + public Flatten2DVector(List> vec2d) { if (vec2d == null) { - return; + return; } this.x = 0; this.y = 0; @@ -21,10 +25,10 @@ public Vector2D(List> vec2d) { public int next() { int rst = list.get(x).get(y); if (y + 1 >= list.get(x).size()) { - y = 0; - x++; + y = 0; + x++; } else { - y++; + y++; } return rst; } @@ -34,14 +38,14 @@ public boolean hasNext() { return false; } while (x < list.size() && list.get(x).size() == 0) { - x++; - y = 0; + x++; + y = 0; } if (x >= list.size()) { - return false; + return false; } if (y >= list.get(x).size()) { - return false; + return false; } return true; } diff --git a/src/geeksforgeeks/IslandBFS.java b/src/geeksforgeeks/IslandBFS.java index de0a2f5..c7ae4b7 100644 --- a/src/geeksforgeeks/IslandBFS.java +++ b/src/geeksforgeeks/IslandBFS.java @@ -1,53 +1,59 @@ package geeksforgeeks; +import java.util.ArrayDeque; +import java.util.Queue; + class IslandBFS { - private class Pair{ + private class Pair { int x; int y; - Pair(int x, int y){ - this.x=x; - this.y=y; + + Pair(int x, int y) { + this.x = x; + this.y = y; } } + public int numIslands(char[][] grid) { - int result=0; + int result = 0; //i-1,j i+1,j i,j-1 j,j+1 - int[][] directions= new int[][]{{-1,0},{1,0},{0,-1},{0,1}}; - for(int i=0;i queue= new ArrayDeque<>(); + + public void bfsUtil(char[][] grid, int i, int j, int[][] directions) { + grid[i][j] = '0'; + Pair root = new Pair(i, j); + + Queue queue = new ArrayDeque<>(); queue.offer(root); - while(!queue.isEmpty()){ - Pair temp= queue.poll(); - for(int[] dir: directions){ - - int x= temp.x+dir[0]; - int y= temp.y+dir[1]; - if(isvalid(grid,x,y)){ - grid[x][y]='0'; - queue.offer(new Pair(x,y)); - } - } - } + while (!queue.isEmpty()) { + Pair temp = queue.poll(); + for (int[] dir : directions) { + + int x = temp.x + dir[0]; + int y = temp.y + dir[1]; + if (isvalid(grid, x, y)) { + grid[x][y] = '0'; + queue.offer(new Pair(x, y)); + } + } + } } - - public boolean isvalid(char[][] grid,int x, int y){ - if(x<0 || x>=grid.length || y<0 || y>=grid[0].length || grid[x][y]=='0') return false; + + public boolean isvalid(char[][] grid, int x, int y) { + if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] == '0') { + return false; + } return true; } } \ No newline at end of file diff --git a/src/geeksforgeeks/LRUCache.java b/src/geeksforgeeks/LRUCache.java index a4acbc6..e45202c 100644 --- a/src/geeksforgeeks/LRUCache.java +++ b/src/geeksforgeeks/LRUCache.java @@ -26,12 +26,10 @@ private class DNode { private Map hashtable = new HashMap<>(); private DNode head, tail; - private int totalItemsInCache; private int maxCapacity; public LRUCache(int maxCapacity) { - totalItemsInCache = 0; this.maxCapacity = maxCapacity; head = new DNode(); @@ -61,9 +59,8 @@ public int get(int key) { public void put(int key, int value) { DNode node = hashtable.get(key); - boolean itemFoundInCache = node != null; - if (!itemFoundInCache) { + if (node != null) { DNode newNode = new DNode(); newNode.key = key; @@ -72,9 +69,7 @@ public void put(int key, int value) { hashtable.put(key, newNode); addNode(newNode); - totalItemsInCache++; - - if (totalItemsInCache > maxCapacity) { + if (hashtable.size() > maxCapacity) { removeLRUEntryFromStructure(); } @@ -87,7 +82,6 @@ public void put(int key, int value) { private void removeLRUEntryFromStructure() { DNode tail = popTail(); hashtable.remove(tail.key); - --totalItemsInCache; } private void addNode(DNode node) { @@ -124,7 +118,7 @@ public static void main(String[] args) { lru.put(1, 1); lru.put(2, 2); lru.put(3, 3); - lru.put(2, 2); + lru.get(2); lru.put(4, 4); lru.put(2, 2); lru.put(3, 3); diff --git a/src/geeksforgeeks/LengthOfLongestSubstringKDistinct.java b/src/geeksforgeeks/LengthOfLongestSubstringKDistinct.java index c83854f..f832355 100644 --- a/src/geeksforgeeks/LengthOfLongestSubstringKDistinct.java +++ b/src/geeksforgeeks/LengthOfLongestSubstringKDistinct.java @@ -1,36 +1,40 @@ - package geeksforgeeks; + +import java.util.HashMap; +import java.util.Map; + public class LengthOfLongestSubstringKDistinct { /** * @param s: A string * @param k: An integer + * * @return: An integer */ public int lengthOfLongestSubstringKDistinct(String s, int k) { - if(s==null || k==0) return 0; - Map map= new HashMap<>(); - - - int result=0; - int left=0; - int right=0; - - while(leftk){ - char chright= s.charAt(right); - map.put(chright, map.get(chright)-1); - if(map.get(chright)<=0){ + if (s == null || k == 0) { + return 0; + } + Map map = new HashMap<>(); + + int result = 0; + int left = 0; + int right = 0; + + while (left < s.length()) { + char ch = s.charAt(left); + map.put(ch, map.getOrDefault(ch, 0) + 1); + while (map.size() > k) { + char chright = s.charAt(right); + map.put(chright, map.get(chright) - 1); + if (map.get(chright) <= 0) { map.remove(chright); } right++; } left++; - result= Math.max(result,left-right); + result = Math.max(result, left - right); } - + return result; } } \ No newline at end of file diff --git a/src/geeksforgeeks/LongestConsequtiveSequence.java b/src/geeksforgeeks/LongestConsequtiveSequence.java index 09b3a20..7542c7f 100644 --- a/src/geeksforgeeks/LongestConsequtiveSequence.java +++ b/src/geeksforgeeks/LongestConsequtiveSequence.java @@ -1,31 +1,36 @@ package geeksforgeeks; +import java.util.HashSet; +import java.util.Set; + class LongestConsequtiveSequence { public int longestConsecutive(int[] nums) { - if(nums.length==0) return 0; - int max=1; - Set set= new HashSet<>(); - for(int i: nums){ + if (nums.length == 0) { + return 0; + } + int max = 1; + Set set = new HashSet<>(); + for (int i : nums) { set.add(i); } - - for(Integer i: nums){ - int num=i; - int count=1; + + for (Integer i : nums) { + int num = i; + int count = 1; // looking left; - while(set.contains(--num)){ + while (set.contains(--num)) { count++; set.remove(num); } - num=i; - while(set.contains(++num)){ - count++; - set.remove(num); + num = i; + while (set.contains(++num)) { + count++; + set.remove(num); } - - max=Math.max(max,count); + + max = Math.max(max, count); } - + return max; } } \ No newline at end of file diff --git a/src/geeksforgeeks/LongestSubArraySumUtmostK.java b/src/geeksforgeeks/LongestSubArraySumUtmostK.java index c30dba7..093bb04 100644 --- a/src/geeksforgeeks/LongestSubArraySumUtmostK.java +++ b/src/geeksforgeeks/LongestSubArraySumUtmostK.java @@ -29,6 +29,5 @@ public static void main(String[] args) { int k = 4; System.out.print(utMostSum(arr, n, k)); - } } diff --git a/src/geeksforgeeks/LongestUniqueSubstring.java b/src/geeksforgeeks/LongestUniqueSubstring.java index 289e2b0..477f8ed 100644 --- a/src/geeksforgeeks/LongestUniqueSubstring.java +++ b/src/geeksforgeeks/LongestUniqueSubstring.java @@ -5,6 +5,7 @@ /*https://leetcode.com/problems/longest-substring-without-repeating-characters/*/ public class LongestUniqueSubstring { + public static int lengthOfLongestSubstring(String s) { Map map = new HashMap<>(); int begin = 0; @@ -15,12 +16,16 @@ public static int lengthOfLongestSubstring(String s) { while (end < s.length()) { char c = s.charAt(end); map.put(c, map.getOrDefault(c, 0) + 1); - if (map.get(c) > 1) counter++; + if (map.get(c) > 1) { + counter++; + } end++; while (counter > 0) { char charTemp = s.charAt(begin); - if (map.get(charTemp) > 1) counter--; + if (map.get(charTemp) > 1) { + counter--; + } map.put(charTemp, map.get(charTemp) - 1); begin++; } @@ -30,6 +35,6 @@ public static int lengthOfLongestSubstring(String s) { } public static void main(String[] args) { - System.out.println(lengthOfLongestSubstring("abccbcbb")); + System.out.println(lengthOfLongestSubstring("pwwkew")); } } \ No newline at end of file diff --git a/src/geeksforgeeks/MajorityVoting.java b/src/geeksforgeeks/MajorityVoting.java index d53cfa0..291132a 100644 --- a/src/geeksforgeeks/MajorityVoting.java +++ b/src/geeksforgeeks/MajorityVoting.java @@ -56,17 +56,16 @@ public static int majorityElementI(int[] nums) { int majority = nums.length / 2; for (int i = 1; i < nums.length; i++) { - if (count == 0) { + if (candidate == nums[i]) { count++; - candidate = nums[i]; - } else if (candidate == nums[i]) { + } else if (count == 0) { count++; + candidate = nums[i]; } else { count--; } - } - + //what if array is even and it has many elements count = 0; for (int num : nums) { if (num == candidate) { @@ -82,9 +81,6 @@ public static void main(String[] args) { System.out.println(majorityElementI(arr)); System.out.println(majorityElementII(arr)); - } - - } diff --git a/src/geeksforgeeks/MakeAnArrayPalindrome.java b/src/geeksforgeeks/MakeAnArrayPalindrome.java index 775cb12..8234a81 100644 --- a/src/geeksforgeeks/MakeAnArrayPalindrome.java +++ b/src/geeksforgeeks/MakeAnArrayPalindrome.java @@ -34,7 +34,7 @@ else if (arr[i] > arr[j]) { } public static void main(String[] args) { - int arr[] = new int[]{1, 4, 5, 9, 1}; + int arr[] = new int[] { 1, 4, 5, 9, 1 }; System.out.println("Count of minimum operations is " + findMinOps(arr, arr.length)); } diff --git a/src/geeksforgeeks/MatrixRowWithMax1.java b/src/geeksforgeeks/MatrixRowWithMax1.java index c71f828..0a278e9 100644 --- a/src/geeksforgeeks/MatrixRowWithMax1.java +++ b/src/geeksforgeeks/MatrixRowWithMax1.java @@ -6,7 +6,7 @@ public class MatrixRowWithMax1 { public static void main(String[] args) { - int[][] mat = {{0, 0, 0, 1}, {0, 1, 1, 1}, {1, 1, 1, 1}, {0, 0, 0, 0}}; + int[][] mat = { { 0, 0, 0, 1 }, { 0, 1, 1, 1 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 } }; System.out.println(rowWithMax1s(mat)); } @@ -17,8 +17,9 @@ static int rowWithMax1s(int mat[][]) { int max_row_index = 0; int j = findFirstIndex(mat[0], 0, C - 1); - if (j == -1) + if (j == -1) { j = C - 1; + } for (int i = 1; i < R; i++) { while (j >= 0 && mat[i][j] == 1) { @@ -33,14 +34,13 @@ static int findFirstIndex(int arr[], int low, int high) { if (high >= low) { int mid = low + (high - low) / 2; - if ((mid == 0 || (arr[mid - 1] == 0)) && arr[mid] == 1) + if ((mid == 0 || (arr[mid - 1] == 0)) && arr[mid] == 1) { return mid; - - else if (arr[mid] == 0) + } else if (arr[mid] == 0) { return findFirstIndex(arr, (mid + 1), high); - - else + } else { return findFirstIndex(arr, low, (mid - 1)); + } } return -1; } diff --git a/src/geeksforgeeks/MaxHistogram.java b/src/geeksforgeeks/MaxHistogram.java index ed23515..97077db 100644 --- a/src/geeksforgeeks/MaxHistogram.java +++ b/src/geeksforgeeks/MaxHistogram.java @@ -5,6 +5,7 @@ /** * https://leetcode.com/problems/largest-rectangle-in-histogram/ */ +//unsolved public class MaxHistogram { public static int largestRectangleArea(int[] heights) { diff --git a/src/geeksforgeeks/MaximumDifference.java b/src/geeksforgeeks/MaximumDifference.java index 3ad0403..cf1dcca 100644 --- a/src/geeksforgeeks/MaximumDifference.java +++ b/src/geeksforgeeks/MaximumDifference.java @@ -5,33 +5,22 @@ */ class MaximumDifference { - static int maxDiff(int arr[], int n) { - - int diff = arr[1] - arr[0]; - int previousSum = diff; - int maxSum = diff; - - for (int i = 1; i < n - 1; i++) { - - diff = arr[i + 1] - arr[i]; - - if (previousSum > 0) { - previousSum += diff; - } else { - previousSum = diff; + static int maxDiff(int arr[], int arr_size) { + int maxDiff = 0; + int minElement = arr[0]; + for (int i = 1; i < arr_size; i++) { + if (arr[i] - minElement > maxDiff) { + maxDiff = arr[i] - minElement; } - - if (previousSum > maxSum) { - maxSum = previousSum; + if (arr[i] < minElement) { + minElement = arr[i]; } } - return maxSum; + return maxDiff; } public static void main(String[] args) { int arr[] = { 2, 4, 1, 3, 10, 8, 5 }; - int n = arr.length; - - System.out.print("Maximum difference is " + maxDiff(arr, n)); + System.out.println("Maximum difference is " + maxDiff(arr, arr.length)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/MaximumSubarray.java b/src/geeksforgeeks/MaximumSubarray.java index 0da7679..3b01743 100644 --- a/src/geeksforgeeks/MaximumSubarray.java +++ b/src/geeksforgeeks/MaximumSubarray.java @@ -5,7 +5,9 @@ */ public class MaximumSubarray { + // 1, -2, -3, 0, 8, 7, -2 public static int maxProductSubArray(int[] A) { + if (A.length == 0) { return 0; } @@ -29,7 +31,7 @@ public static int maxSumSubArray(int[] arr) { int max = Integer.MIN_VALUE; int sum = 0; - for (int i = 1; i < arr.length; i++) { + for (int i = 0; i < arr.length; i++) { sum = sum + arr[i]; if (sum < 0) { //get i if you want to get index of subarray @@ -42,7 +44,7 @@ public static int maxSumSubArray(int[] arr) { public static void main(String[] args) { int arr[] = { 1, -2, -3, 0, 8, 7, -2 }; - System.out.println("Maximum Sub array product is " + maxSumSubArray(arr)); + System.out.println("Maximum Sub array sum is " + maxSumSubArray(arr)); + System.out.println("Maximum Sub array product is " + maxProductSubArray(arr)); } - } diff --git a/src/geeksforgeeks/MaximumSubstringWithKDistinctChar.java b/src/geeksforgeeks/MaximumSubstringWithKDistinctChar.java index 5ef5e8a..65963f7 100644 --- a/src/geeksforgeeks/MaximumSubstringWithKDistinctChar.java +++ b/src/geeksforgeeks/MaximumSubstringWithKDistinctChar.java @@ -3,11 +3,16 @@ import java.util.HashMap; import java.util.Map; +/** + * https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/ + *

+ * https://www.lintcode.com/problem/longest-substring-with-at-most-two-distinct-characters/description + */ public class MaximumSubstringWithKDistinctChar { public static void main(String[] args) { - // System.out.println(lengthOfLongestSubstringTwoDistinct("abaaaaacccddcc", 2)); - System.out.println(lengthOfLongestSubstringKDistinct("eqgkcwGFvjjmxutystqdfhuMblWbylgjxsxgnoh", 16)); + System.out.println(lengthOfLongestSubstringTwoDistinct("abaaaaacccddcc", 2)); + //System.out.println(lengthOfLongestSubstringKDistinct("eqgkcwGFvjjmxutystqdfhuMblWbylgjxsxgnoh", 2)); } public static int lengthOfLongestSubstringTwoDistinct(String s, int k) { @@ -36,28 +41,35 @@ public static int lengthOfLongestSubstringTwoDistinct(String s, int k) { return length; } + // improvised solution public static int lengthOfLongestSubstringKDistinct(String s, int k) { - if(s==null || s.isEmpty()) return 0; - if(k==0) return 0; - int start=0; - int maxCount=0; + if (s == null || s.isEmpty()) { + return 0; + } + if (k == 0) { + return 0; + } + int start = 0; + int maxCount = 0; int[] arr = new int[26]; s = s.toLowerCase(); - for(int i=0;i subarraySort(ArrayList A) { - - ArrayList list = new ArrayList<>(); - int start = -1; - int end = -1; - - // from left - for (int i = 1; i < A.size(); ++i) { - if (A.get(i) < A.get(i - 1)) { - start = i - 1; - break; - } - } - - // fully sorted - if (start == -1) { - list.add(-1); - return list; - } - - // from right - for (int i = A.size() - 2; i >= 0; --i) { - if (A.get(i) > A.get(i + 1)) { - end = i + 1; - break; - } - } - - // find min and max in the range [start, end] - int min = A.get(start); - int max = A.get(start); - for (int i = start; i <= end; ++i) { - min = Math.min(min, A.get(i)); - max = Math.max(max, A.get(i)); - } - - for (int i = 0; i < start; ++i) { - if (A.get(i) > min) { - start = i; - break; - } - } - - for (int i = A.size() - 1; i >= end + 1; --i) { - if (A.get(i) < max) { - end = i; - break; - } - } - - list.add(start); - list.add(end); - - return list; - } - - public static void main(String[] args) { - //1, 1, 10, 10, 15, 10, 15, 10,10, 15, 10, 15 - //(1, 3, 2, 4, 5))); - //4, 15, 4, 4, 15, 18, 20 - List result = subarraySort(new ArrayList<>(Arrays.asList(4, 15, 4, 4, 15, 18, 20))); - result.stream().forEach(System.out::println); - } -} diff --git a/src/geeksforgeeks/MeetingRoomsII.java b/src/geeksforgeeks/MeetingRoomsII.java index 7998378..31530b8 100644 --- a/src/geeksforgeeks/MeetingRoomsII.java +++ b/src/geeksforgeeks/MeetingRoomsII.java @@ -1,22 +1,31 @@ package geeksforgeeks; +import java.util.Collections; +import java.util.List; +import java.util.PriorityQueue; + public class MeetingRoomsII { /** * @param intervals: an array of meeting time intervals + * * @return: the minimum number of conference rooms required */ public int minMeetingRooms(List intervals) { - if(intervals==null || intervals.size()==0) return -1; - - Collections.sort(intervals,(a,b)->Integer.compare(a.start,b.start)); - PriorityQueue queue= new PriorityQueue<>(); + if (intervals == null || intervals.size() == 0) { + return -1; + } + + Collections.sort(intervals, (a, b) -> Integer.compare(a.start, b.start)); + PriorityQueue queue = new PriorityQueue<>(); //Interval max= intervals.get(0); queue.offer(intervals.get(0).end); - for(int i=1;i> generate(int numRows) { diff --git a/src/geeksforgeeks/PreOrderInOrderTree.java b/src/geeksforgeeks/PreOrderInOrderTree.java index 4376269..28b460d 100644 --- a/src/geeksforgeeks/PreOrderInOrderTree.java +++ b/src/geeksforgeeks/PreOrderInOrderTree.java @@ -1,31 +1,40 @@ package geeksforgeeks; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + class PreOrderInOrderTree { public TreeNode buildTree(int[] preorder, int[] inorder) { - Map map= new HashMap<>(); - List set= new ArrayList<>(); - - for(int i=0;i map = new HashMap<>(); + List set = new ArrayList<>(); + + for (int i = 0; i < inorder.length; i++) { + map.put(inorder[i], i); } - - for(int i=0;i map, List set,int start,int end){ - if(start>end) return null; - if(set.isEmpty()) return null; - int rootval= set.get(0); - set.remove(0); - TreeNode root= new TreeNode(rootval); - int inorderIndex= map.get(rootval); - root.left=buildTreeUtil(map,set,start,inorderIndex-1); - root.right=buildTreeUtil(map,set,inorderIndex+1,end); + + public TreeNode buildTreeUtil(Map map, List set, int start, int end) { + if (start > end) { + return null; + } + if (set.isEmpty()) { + return null; + } + int rootval = set.get(0); + set.remove(0); + TreeNode root = new TreeNode(rootval); + int inorderIndex = map.get(rootval); + root.left = buildTreeUtil(map, set, start, inorderIndex - 1); + root.right = buildTreeUtil(map, set, inorderIndex + 1, end); return root; } } \ No newline at end of file diff --git a/src/geeksforgeeks/StockBuySellManyTimes.java b/src/geeksforgeeks/StockBuySellManyTimes.java index c4a4587..990a5ce 100644 --- a/src/geeksforgeeks/StockBuySellManyTimes.java +++ b/src/geeksforgeeks/StockBuySellManyTimes.java @@ -5,6 +5,8 @@ class Interval { int buy, sell; + int start; // for meeting problem + int end; } /** @@ -16,8 +18,9 @@ class StockBuySellManyTimes { //200, 180, 260, 310, 40, 535, 695 void stockBuySell(int price[], int n) { // Prices must be given for at least two days - if (n == 1) + if (n == 1) { return; + } int count = 0; @@ -31,8 +34,9 @@ void stockBuySell(int price[], int n) { i++; // If we reached the end, break as no further solution possible - if (i == n - 1) + if (i == n - 1) { break; + } Interval e = new Interval(); e.buy = i++; @@ -51,11 +55,13 @@ void stockBuySell(int price[], int n) { count++; } - if (count == 0) + if (count == 0) { System.out.println("There is no day when buying the stock " + "will make profit"); - else + } else { for (int j = 0; j < count; j++) - System.out.println("Buy on day: " + result.get(j).buy + " " + "Sell on day : " + result.get(j).sell); + System.out.println( + "Buy on day: " + result.get(j).buy + " " + "Sell on day : " + result.get(j).sell); + } return; } @@ -63,7 +69,7 @@ void stockBuySell(int price[], int n) { public static void main(String args[]) { StockBuySellManyTimes stock = new StockBuySellManyTimes(); - int price[] = {200, 180, 260, 310, 40, 535, 695}; + int price[] = { 200, 180, 260, 310, 40, 535, 695 }; int n = price.length; stock.stockBuySell(price, n); diff --git a/src/geeksforgeeks/TestFreshWork.java b/src/geeksforgeeks/TestFreshWork.java new file mode 100644 index 0000000..2ac5b8f --- /dev/null +++ b/src/geeksforgeeks/TestFreshWork.java @@ -0,0 +1,77 @@ +package geeksforgeeks; + +import java.util.Random; + +/** + * + */ + +//unsorted array : 8,1,6,2,4,5 k=3 +// output : 4 + +// bruteforce : sort : o n log n +// priority queue : n log k +// n --> --> n log k -> n log n -> n2 +// Quick select : o (n) worst case : o (n2) +// worst case : o (n) +public class TestFreshWork { + + public static void main(String[] args) { + int[] arr = { 8, 1, 6, 2, 4, 5 }; + TestFreshWork testFreshWork = new TestFreshWork(); + System.out.println(testFreshWork.sort(arr, 3, 0, arr.length - 1)); + + } + + private int sort(int[] arr, int k, int start, int end) { + + if (start < end) { + + int pivot = new Random().nextInt(((end - start) / 2) + start); + // pivot = 4 + int value = partition(arr, start, end, pivot); + if (k == value) { + return arr[k]; + } else if (k < value) { + sort(arr, k, start, value - 1); + } else { + sort(arr, k, value, end); + } + } + return -1; + } + + //{ 8, 1, 6, 2, 4, 5 }; + // 1,2,4,6,8,5 + // 1,2,4,5,6,8 + private int partition(int[] arr, int start, int end, int pivot) { + + int iPivot = arr[pivot]; + int i = start; + int j = end - 1; + swap(end, pivot, arr); + + /* while (arr[i] <) { + + } + + while (arr[j] <) { + }*/ + + // 8,1,6,2,5,4 + // 1,8,6,2,5,4 + // 1,6,8,2,5,4 + // 1,2,8,6,5,4 + + // 1,2,4,6,5,8 + + return 0; + + } + + private void swap(int start, int pivot, int[] arr) { + int temp = arr[start]; + arr[start] = arr[pivot]; + arr[pivot] = temp; + } +} diff --git a/src/geeksforgeeks/UnsortedSubarrayProblems.java b/src/geeksforgeeks/UnsortedSubarrayProblems.java new file mode 100644 index 0000000..cfc36b1 --- /dev/null +++ b/src/geeksforgeeks/UnsortedSubarrayProblems.java @@ -0,0 +1,51 @@ +package geeksforgeeks; + +//https://leetcode.com/problems/shortest-unsorted-continuous-subarray/submissions/ +public class UnsortedSubarrayProblems { + + public static int findUnsortedSubarray(int[] nums) { + + int i = 0; + int j = nums.length - 1; + + while (i < nums.length - 1) { + if (nums[i] > nums[i + 1]) { + break; + } + i++; + } + if (i >= j) { + return 0; + } + + while (j > 0) { + if (nums[j] < nums[j - 1]) { + break; + } + j--; + } + int min = Integer.MAX_VALUE; + int max = Integer.MIN_VALUE; + for (int k = i; k <= j; k++) { + min = Math.min(min, nums[k]); + max = Math.max(max, nums[k]); + } + + while (i >= 0 && min < nums[i]) + i--; + while (j < nums.length && max > nums[j]) + j++; + + return j - i - 1; + + } + + public static void main(String[] args) { + //(1, 3, 2, 4, 5))); + //4, 15, 4, 4, 15, 18, 20 + + // 2,6,4,8,10,9,15 + int[] arr = { 2, 6, 1, 8, 10, 9, 15 }; + System.out.println(findUnsortedSubarray(arr)); + } +} diff --git a/src/geeksforgeeks/WordBreak.java b/src/geeksforgeeks/WordBreak.java index 14d35ef..598a5d1 100644 --- a/src/geeksforgeeks/WordBreak.java +++ b/src/geeksforgeeks/WordBreak.java @@ -1,4 +1,9 @@ package geeksforgeeks; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + class WordBreak { /* @@ -58,18 +63,22 @@ class WordBreak { 0 1 2 3 4 5 6 7 8 */ public boolean wordBreak(String s, List wordDict) { - if(s==null) return false; - boolean[] dp= new boolean[s.length()+1]; - dp[0]=true; - Set set= new HashSet<>(wordDict); + if (s == null) { + return false; + } + boolean[] dp = new boolean[s.length() + 1]; + dp[0] = true; + Set set = new HashSet<>(wordDict); - for(int i=1;i<=s.length();i++){ - for(int j=0;j Date: Wed, 25 Mar 2020 00:21:27 +0530 Subject: [PATCH 25/51] Adding more problems --- src/geeksforgeeks/FileSystem.java | 81 +++++++++ src/geeksforgeeks/FileSystemI.java | 78 +++++++++ src/geeksforgeeks/LRUCache.java | 9 +- .../MedianOfRunningIntegers.java | 11 +- src/geeksforgeeks/MeetingRoomsII.java | 12 +- src/geeksforgeeks/MergeIntervals.java | 12 +- src/geeksforgeeks/MergeSortLinkedList.java | 9 + src/geeksforgeeks/MergeTwoLinkedList.java | 4 +- src/geeksforgeeks/MinCostRopeConnect.java | 39 +++-- .../MinimumDistanceBetweenTwoNumbers.java | 17 +- .../MinimumIndexDistanceOfMaximumNumbers.java | 43 +++-- src/geeksforgeeks/MinimumStack.java | 35 ++-- src/geeksforgeeks/MinimumStepsKnight.java | 161 +++++++++--------- src/geeksforgeeks/TestFreshWork.java | 77 --------- 14 files changed, 353 insertions(+), 235 deletions(-) create mode 100644 src/geeksforgeeks/FileSystem.java create mode 100644 src/geeksforgeeks/FileSystemI.java delete mode 100644 src/geeksforgeeks/TestFreshWork.java diff --git a/src/geeksforgeeks/FileSystem.java b/src/geeksforgeeks/FileSystem.java new file mode 100644 index 0000000..849db22 --- /dev/null +++ b/src/geeksforgeeks/FileSystem.java @@ -0,0 +1,81 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +public class FileSystem { + class File { + boolean isfile = false; + HashMap files = new HashMap<>(); + String content = ""; + } + + File root; + + public FileSystem() { + root = new File(); + } + + public List ls(String path) { + File t = root; + List files = new ArrayList<>(); + if (!path.equals("/")) { + String[] d = path.split("/"); + for (int i = 1; i < d.length; i++) { + t = t.files.get(d[i]); + } + if (t.isfile) { + files.add(d[d.length - 1]); + return files; + } + } + List res_files = new ArrayList<>(t.files.keySet()); + Collections.sort(res_files); + return res_files; + } + + public void mkdir(String path) { + File t = root; + String[] d = path.split("/"); + for (int i = 1; i < d.length; i++) { + if (!t.files.containsKey(d[i])) { + t.files.put(d[i], new File()); + } + t = t.files.get(d[i]); + } + } + + public void addContentToFile(String filePath, String content) { + File t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.files.get(d[i]); + } + if (!t.files.containsKey(d[d.length - 1])) { + t.files.put(d[d.length - 1], new File()); + } + t = t.files.get(d[d.length - 1]); + t.isfile = true; + t.content = t.content + content; + } + + public String readContentFromFile(String filePath) { + File t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.files.get(d[i]); + } + return t.files.get(d[d.length - 1]).content; + } +} + +/** + * Your FileSystem object will be instantiated and called as such: + * FileSystem obj = new FileSystem(); + * List param_1 = obj.ls(path); + * obj.mkdir(path); + * obj.addContentToFile(filePath,content); + * String param_4 = obj.readContentFromFile(filePath); + */ \ No newline at end of file diff --git a/src/geeksforgeeks/FileSystemI.java b/src/geeksforgeeks/FileSystemI.java new file mode 100644 index 0000000..eb65ef3 --- /dev/null +++ b/src/geeksforgeeks/FileSystemI.java @@ -0,0 +1,78 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +public class FileSystemI { + class Dir { + HashMap dirs = new HashMap<>(); + HashMap files = new HashMap<>(); + } + + Dir root; + + public FileSystemI() { + root = new Dir(); + } + + public List ls(String path) { + Dir t = root; + List files = new ArrayList<>(); + if (!path.equals("/")) { + String[] d = path.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.dirs.get(d[i]); + } + if (t.files.containsKey(d[d.length - 1])) { + files.add(d[d.length - 1]); + return files; + } else { + t = t.dirs.get(d[d.length - 1]); + } + } + files.addAll(new ArrayList<>(t.dirs.keySet())); + files.addAll(new ArrayList<>(t.files.keySet())); + Collections.sort(files); + return files; + } + + public void mkdir(String path) { + Dir t = root; + String[] d = path.split("/"); + for (int i = 1; i < d.length; i++) { + if (!t.dirs.containsKey(d[i])) { + t.dirs.put(d[i], new Dir()); + } + t = t.dirs.get(d[i]); + } + } + + public void addContentToFile(String filePath, String content) { + Dir t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.dirs.get(d[i]); + } + t.files.put(d[d.length - 1], t.files.getOrDefault(d[d.length - 1], "") + content); + } + + public String readContentFromFile(String filePath) { + Dir t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.dirs.get(d[i]); + } + return t.files.get(d[d.length - 1]); + } +} + +/** + * Your FileSystem object will be instantiated and called as such: + * FileSystem obj = new FileSystem(); + * List param_1 = obj.ls(path); + * obj.mkdir(path); + * obj.addContentToFile(filePath,content); + * String param_4 = obj.readContentFromFile(filePath); + */ \ No newline at end of file diff --git a/src/geeksforgeeks/LRUCache.java b/src/geeksforgeeks/LRUCache.java index e45202c..6e38eb2 100644 --- a/src/geeksforgeeks/LRUCache.java +++ b/src/geeksforgeeks/LRUCache.java @@ -33,10 +33,7 @@ public LRUCache(int maxCapacity) { this.maxCapacity = maxCapacity; head = new DNode(); - head.prev = null; - tail = new DNode(); - tail.next = null; head.next = tail; tail.prev = head; @@ -45,14 +42,11 @@ public LRUCache(int maxCapacity) { public int get(int key) { DNode node = hashtable.get(key); - boolean itemFoundInCache = node != null; - if (!itemFoundInCache) { + if (node == null) { return -1; } - moveToHead(node); - return node.value; } @@ -61,7 +55,6 @@ public void put(int key, int value) { DNode node = hashtable.get(key); if (node != null) { - DNode newNode = new DNode(); newNode.key = key; newNode.value = value; diff --git a/src/geeksforgeeks/MedianOfRunningIntegers.java b/src/geeksforgeeks/MedianOfRunningIntegers.java index cef851b..fc0ec7e 100644 --- a/src/geeksforgeeks/MedianOfRunningIntegers.java +++ b/src/geeksforgeeks/MedianOfRunningIntegers.java @@ -3,11 +3,15 @@ import java.util.Collections; import java.util.PriorityQueue; +/** + * https://leetcode.com/problems/find-median-from-data-stream/ + */ public class MedianOfRunningIntegers { PriorityQueue min = new PriorityQueue<>(); PriorityQueue max = new PriorityQueue<>(Collections.reverseOrder()); + // 6,8,1,4,9,2,3,5 public void addNum(int num) { max.offer(num); min.offer(max.poll()); @@ -17,15 +21,16 @@ public void addNum(int num) { } public double findMedian() { - if (max.size() == min.size()) + if (max.size() == min.size()) { return (max.peek() + min.peek()) / 2.0; - else + } else { return max.peek(); + } } public static void main(String[] args) { MedianOfRunningIntegers median = new MedianOfRunningIntegers(); - int A[] = {5, 15, 1, 3, 2, 8, 7, 9, 10, 6, 11, 4}; + int A[] = { 5, 15, 1, 3, 2, 8, 7, 9, 10, 6, 11, 4 }; for (int num : A) { median.addNum(num); System.out.println(median.findMedian()); diff --git a/src/geeksforgeeks/MeetingRoomsII.java b/src/geeksforgeeks/MeetingRoomsII.java index 31530b8..abff5e9 100644 --- a/src/geeksforgeeks/MeetingRoomsII.java +++ b/src/geeksforgeeks/MeetingRoomsII.java @@ -1,23 +1,29 @@ package geeksforgeeks; import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.PriorityQueue; +/** + * https://www.lintcode.com/problem/meeting-rooms-ii/ + */ + public class MeetingRoomsII { /** * @param intervals: an array of meeting time intervals * * @return: the minimum number of conference rooms required */ + // [(0,30),(5,10),(15,20)] public int minMeetingRooms(List intervals) { if (intervals == null || intervals.size() == 0) { return -1; } - Collections.sort(intervals, (a, b) -> Integer.compare(a.start, b.start)); + Collections.sort(intervals, Comparator.comparingInt(a -> a.start)); + PriorityQueue queue = new PriorityQueue<>(); - //Interval max= intervals.get(0); queue.offer(intervals.get(0).end); for (int i = 1; i < intervals.size(); i++) { Interval temp = intervals.get(i); @@ -26,6 +32,8 @@ public int minMeetingRooms(List intervals) { } queue.offer(temp.end); } + return queue.size(); + } } diff --git a/src/geeksforgeeks/MergeIntervals.java b/src/geeksforgeeks/MergeIntervals.java index 3e03701..06ef12f 100644 --- a/src/geeksforgeeks/MergeIntervals.java +++ b/src/geeksforgeeks/MergeIntervals.java @@ -2,15 +2,22 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Comparator; import java.util.List; +/** + * https://leetcode.com/problems/merge-intervals/ + */ class MergeIntervals { public static int[][] merge(int[][] intervals) { if (intervals.length <= 1) { return intervals; } - Arrays.sort(intervals, (i1, i2) -> Integer.compare(i1[0], i2[0])); + + /* Arrays.sort(intervals, (a, b) -> a[0] - b[0]); + Arrays.sort(intervals, (i1, i2) -> Integer.compare(i1[0], i2[0]));*/ + Arrays.sort(intervals, Comparator.comparingInt(i -> i[0])); List result = new ArrayList<>(); int[] prevInterval = intervals[0]; @@ -29,7 +36,8 @@ public static int[][] merge(int[][] intervals) { public static void main(String[] args) { // [[1,3],[2,6],[8,10],[15,18]] - int[][] arr = { { 1, 3 }, { 2, 4 }, { 5, 7 }, { 6, 8 } }; + int[][] arr = { { 1, 9 }, { 6, 8 }, { 2, 4 }, { 4, 7 } }; + //{ { 1, 3 }, { 2, 4 }, { 5, 7 }, { 6, 8 } }; //{{1, 9}, {2, 4}, {4, 7}, {6, 8}}; System.out.println(Arrays.deepToString(merge(arr))); } diff --git a/src/geeksforgeeks/MergeSortLinkedList.java b/src/geeksforgeeks/MergeSortLinkedList.java index ca29b2c..d9eaf1b 100644 --- a/src/geeksforgeeks/MergeSortLinkedList.java +++ b/src/geeksforgeeks/MergeSortLinkedList.java @@ -1,5 +1,8 @@ package geeksforgeeks; +/** + * https://www.geeksforgeeks.org/merge-sort-for-linked-list/ + */ public class MergeSortLinkedList { public static ListNode sortList(ListNode head) { @@ -23,6 +26,7 @@ public static ListNode sortList(ListNode head) { // step 3. merge l1 and l2 return merge(l1, l2); } + static ListNode merge(ListNode l1, ListNode l2) { ListNode node = new ListNode(0); ListNode temp = node; @@ -68,4 +72,9 @@ class ListNode { public ListNode(int val) { this.val = val; } + + @Override + public String toString() { + return "ListNode{val=" + val + '}'; + } } \ No newline at end of file diff --git a/src/geeksforgeeks/MergeTwoLinkedList.java b/src/geeksforgeeks/MergeTwoLinkedList.java index 3d4912a..8e879ea 100644 --- a/src/geeksforgeeks/MergeTwoLinkedList.java +++ b/src/geeksforgeeks/MergeTwoLinkedList.java @@ -1,7 +1,7 @@ package geeksforgeeks; /** - * @author i312458 + * https://www.geeksforgeeks.org/merge-two-sorted-linked-lists/ */ public class MergeTwoLinkedList { @@ -34,7 +34,7 @@ public static void main(String[] args) { l1.next.next.next = new ListNode(4); ListNode l2 = new ListNode(1); -// l2.next = new ListNode(7); + // l2.next = new ListNode(7); ListNode head = mergeTwoLists(l1, l2); diff --git a/src/geeksforgeeks/MinCostRopeConnect.java b/src/geeksforgeeks/MinCostRopeConnect.java index 1297fff..cab85b9 100644 --- a/src/geeksforgeeks/MinCostRopeConnect.java +++ b/src/geeksforgeeks/MinCostRopeConnect.java @@ -2,26 +2,33 @@ import java.util.PriorityQueue; +/** + * https://www.geeksforgeeks.org/connect-n-ropes-minimum-cost/ + */ public class MinCostRopeConnect { - public static void main(String[] args) { - int arr[] = { 4, 3, 2, 6 }; + // 6 + 4 = 10 .. 10 + 3 = 13 .. 13 +2 = 15 - MinCostRopeConnect rope = new MinCostRopeConnect(); - rope.connectRopes(arr); - } + // 2+3 = 5 .. 5 + 4 = 9 .. 9 + 6 = 15 .. - private void connectRopes(int[] arr) { - PriorityQueue pq = new PriorityQueue<>(); - for (int i : arr) - pq.add(i); + public static void main(String[] args) { + int arr[] = { 4, 3, 2, 6 }; - while (pq.size() > 1) { - Integer remove = pq.remove(); - Integer remove2 = pq.remove(); + MinCostRopeConnect rope = new MinCostRopeConnect(); + rope.connectRopes(arr); + } - System.out.println("cost" + (remove + remove2)); - pq.add(remove + remove2); - } - } + private void connectRopes(int[] arr) { + PriorityQueue pq = new PriorityQueue<>(); + for (int i : arr) + pq.add(i); + + while (pq.size() > 1) { + Integer remove = pq.remove(); + Integer remove2 = pq.remove(); + + System.out.println("cost" + (remove + remove2)); + pq.add(remove + remove2); + } + } } diff --git a/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java b/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java index 38b0d2d..8bb2642 100644 --- a/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java +++ b/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java @@ -1,15 +1,18 @@ package geeksforgeeks; + + /*https://www.geeksforgeeks.org/find-the-minimum-distance-between-two-numbers/*/ class MinimumDistanceBetweenTwoNumbers { + int minDist(int arr[], int n, int x, int y) { int i = 0; int minDist = Integer.MAX_VALUE; int prev = 0; - // Find the first occurence of any of the two numbers (x or y) - // and store the index of this occurence in prev + // Find the first occurrence of any of the two numbers (x or y) + // and store the index of this occurrence in prev for (i = 0; i < n; i++) { if (arr[i] == x || arr[i] == y) { prev = i; @@ -17,10 +20,8 @@ int minDist(int arr[], int n, int x, int y) { } } - // Traverse after the first occurrence for (; i < n; i++) { if (arr[i] == x || arr[i] == y) { - // If the current element matches with any of the two then // check if current element and prev element are different // Also check if this value is smaller than minimum distance // so far @@ -30,18 +31,16 @@ int minDist(int arr[], int n, int x, int y) { prev = i; } } - return minDist; } public static void main(String[] args) { MinimumDistanceBetweenTwoNumbers min = new MinimumDistanceBetweenTwoNumbers(); - int arr[] = {2, 5, 3, 5, 4, 4, 2, 3}; + int arr[] = { 3, 5, 4, 3, 1, 2, 4, 6, 5, 6, 6, 5, 4, 8, 3 }; int n = arr.length; int x = 3; - int y = 2; + int y = 6; - System.out.println("Minimum distance between " + x + " and " + y - + " is " + min.minDist(arr, n, x, y)); + System.out.println("Minimum distance between " + x + " and " + y + " is " + min.minDist(arr, n, x, y)); } } diff --git a/src/geeksforgeeks/MinimumIndexDistanceOfMaximumNumbers.java b/src/geeksforgeeks/MinimumIndexDistanceOfMaximumNumbers.java index fd3ed21..f05449b 100644 --- a/src/geeksforgeeks/MinimumIndexDistanceOfMaximumNumbers.java +++ b/src/geeksforgeeks/MinimumIndexDistanceOfMaximumNumbers.java @@ -2,31 +2,30 @@ /** * https://www.geeksforgeeks.org/minimum-distance-between-two-occurrences-of-maximum/ - * */ class MinimumIndexDistanceOfMaximumNumbers { - static int minDistance(int arr[], int n) { - int maximumElement = arr[0]; - int minDist = n; - int index = 0; + static int minDistance(int arr[], int n) { + int maximumElement = arr[0]; + int minDist = n; + int index = 0; - for (int i = 1; i < n; i++) { - if (maximumElement == arr[i]) { - minDist = Math.min(minDist, (i - index)); - index = i; - } else if (maximumElement < arr[i]) { - maximumElement = arr[i]; - minDist = n; - index = i; - } - } - return minDist - 1; - } + for (int i = 1; i < n; i++) { + if (maximumElement == arr[i]) { + minDist = Math.min(minDist, (i - index)); + index = i; + } else if (maximumElement < arr[i]) { + maximumElement = arr[i]; + minDist = n; + index = i; + } + } + return minDist - 1; + } - public static void main(String[] args) { - int arr[] = { 6, 3, 1, 3, 6, 5, 4, 1 }; - int n = arr.length; - System.out.print("Minimum distance = " + minDistance(arr, n)); - } + public static void main(String[] args) { + int arr[] = { 6, 3, 1, 3, 6, 5, 4, 1 }; + int n = arr.length; + System.out.print("Minimum distance = " + minDistance(arr, n)); + } } \ No newline at end of file diff --git a/src/geeksforgeeks/MinimumStack.java b/src/geeksforgeeks/MinimumStack.java index cd4ddb8..73cb65e 100644 --- a/src/geeksforgeeks/MinimumStack.java +++ b/src/geeksforgeeks/MinimumStack.java @@ -4,15 +4,15 @@ class MyStack { - Stack s; + Stack stack; Integer minEle; MyStack() { - s = new Stack<>(); + stack = new Stack<>(); } void getMin() { - if (s.isEmpty()) { + if (stack.isEmpty()) { System.out.println("Stack is empty"); } else { System.out.println("Minimum Element in the " + " stack is: " + minEle); @@ -20,12 +20,12 @@ void getMin() { } void peek() { - if (s.isEmpty()) { + if (stack.isEmpty()) { System.out.println("Stack is empty "); return; } - Integer t = s.peek(); + Integer t = stack.peek(); System.out.print("Top Most Element is: "); if (t < minEle) { @@ -36,13 +36,13 @@ void peek() { } void pop() { - if (s.isEmpty()) { + if (stack.isEmpty()) { System.out.println("Stack is empty"); return; } System.out.print("Top Most Element Removed: "); - Integer t = s.pop(); + Integer t = stack.pop(); if (t < minEle) { System.out.println(minEle); @@ -53,9 +53,9 @@ void pop() { } void push(Integer x) { - if (s.isEmpty()) { + if (stack.isEmpty()) { minEle = x; - s.push(x); + stack.push(x); System.out.println("Number Inserted: " + x); return; } @@ -64,10 +64,10 @@ void push(Integer x) { // x-minEle<0 // x-minEle+x<0+x // 2x-minEle + * https://www.techiedelight.com/chess-knight-problem-find-shortest-path-source-destination/ + */ class MinimumStepsKnight { - static class Cell { - int x; - int y; - int dis; - - public Cell(int x, int y, int dis) { - this.x = x; - this.y = y; - this.dis = dis; - } - - } - - // Utility method returns true if (x, y) lies - // inside Board - static boolean isInside(int x, int y, int N) { - if (x >= 1 && x <= N && y >= 1 && y <= N) - return true; - return false; - } - - // Method returns minimum step - // to reach target position - static int minStepToReachTarget(int knightPos[], int targetPos[], int N) { - // x and y direction, where a knight can move - int dx[] = { -2, -1, 1, 2, -2, -1, 1, 2 }; - int dy[] = { -1, -2, -2, -1, 1, 2, 2, 1 }; - - // queue for storing states of knight in board - Queue q = new LinkedList<>(); - - // push starting position of knight with 0 distance - q.add(new Cell(knightPos[0], knightPos[1], 0)); - - Cell t; - int x, y; - boolean visit[][] = new boolean[N + 1][N + 1]; - - // make all cell unvisited - for (int i = 1; i <= N; i++) - for (int j = 1; j <= N; j++) - visit[i][j] = false; - - // visit starting state - visit[knightPos[0]][knightPos[1]] = true; - - // loop untill we have one element in queue - while (!q.isEmpty()) { - t = q.remove(); - - // if current cell is equal to target cell, - // return its distance - if (t.x == targetPos[0] && t.y == targetPos[1]) - return t.dis; - - // loop for all reachable states - for (int i = 0; i < 8; i++) { - x = t.x + dx[i]; - y = t.y + dy[i]; - - // If reachable state is not yet visited and - // inside board, push that state into queue - if (isInside(x, y, N) && !visit[x][y]) { - visit[x][y] = true; - q.add(new Cell(x, y, t.dis + 1)); - } - } - } - return Integer.MAX_VALUE; - } - - public static void main(String[] args) { - int N = 30; - int[] knightPos = { 1, 1 }; - int[] targetPos = { 30, 30 }; - System.out.println(minStepToReachTarget(knightPos, targetPos, N)); - } + static class Cell { + int x; + int y; + int steps; + + public Cell(int x, int y, int steps) { + this.x = x; + this.y = y; + this.steps = steps; + } + + } + + // Utility method returns true if (x, y) lies + // inside Board + static boolean isInside(int x, int y, int N) { + if (x >= 1 && x <= N && y >= 1 && y <= N) { + return true; + } + return false; + } + + // Method returns minimum step + // to reach target position + static int minStepToReachTarget(int knightPos[], int targetPos[], int N) { + // x and y direction, where a knight can move + int dx[] = { -2, -1, 1, 2, -2, -1, 1, 2 }; + int dy[] = { -1, -2, -2, -1, 1, 2, 2, 1 }; + + // queue for storing states of knight in board + Queue q = new LinkedList<>(); + + // push starting position of knight with 0 distance + q.add(new Cell(knightPos[0], knightPos[1], 0)); + + Cell cell; + int x, y; + boolean visit[][] = new boolean[N + 1][N + 1]; + + // make all cell unvisited + for (int i = 1; i <= N; i++) + for (int j = 1; j <= N; j++) + visit[i][j] = false; + + // visit starting state + visit[knightPos[0]][knightPos[1]] = true; + + // loop untill we have one element in queue + while (!q.isEmpty()) { + cell = q.remove(); + + // if current cell is equal to target cell, + // return its distance + if (cell.x == targetPos[0] && cell.y == targetPos[1]) { + return cell.steps; + } + + // loop for all reachable states + for (int i = 0; i < 8; i++) { + x = cell.x + dx[i]; + y = cell.y + dy[i]; + + // If reachable state is not yet visited and + // inside board, push that state into queue + if (isInside(x, y, N) && !visit[x][y]) { + visit[x][y] = true; + q.add(new Cell(x, y, cell.steps + 1)); + } + } + } + return Integer.MAX_VALUE; + } + + public static void main(String[] args) { + int N = 30; + int[] knightPos = { 1, 1 }; + int[] targetPos = { 30, 30 }; + System.out.println(minStepToReachTarget(knightPos, targetPos, N)); + } } \ No newline at end of file diff --git a/src/geeksforgeeks/TestFreshWork.java b/src/geeksforgeeks/TestFreshWork.java deleted file mode 100644 index 2ac5b8f..0000000 --- a/src/geeksforgeeks/TestFreshWork.java +++ /dev/null @@ -1,77 +0,0 @@ -package geeksforgeeks; - -import java.util.Random; - -/** - * - */ - -//unsorted array : 8,1,6,2,4,5 k=3 -// output : 4 - -// bruteforce : sort : o n log n -// priority queue : n log k -// n --> --> n log k -> n log n -> n2 -// Quick select : o (n) worst case : o (n2) -// worst case : o (n) -public class TestFreshWork { - - public static void main(String[] args) { - int[] arr = { 8, 1, 6, 2, 4, 5 }; - TestFreshWork testFreshWork = new TestFreshWork(); - System.out.println(testFreshWork.sort(arr, 3, 0, arr.length - 1)); - - } - - private int sort(int[] arr, int k, int start, int end) { - - if (start < end) { - - int pivot = new Random().nextInt(((end - start) / 2) + start); - // pivot = 4 - int value = partition(arr, start, end, pivot); - if (k == value) { - return arr[k]; - } else if (k < value) { - sort(arr, k, start, value - 1); - } else { - sort(arr, k, value, end); - } - } - return -1; - } - - //{ 8, 1, 6, 2, 4, 5 }; - // 1,2,4,6,8,5 - // 1,2,4,5,6,8 - private int partition(int[] arr, int start, int end, int pivot) { - - int iPivot = arr[pivot]; - int i = start; - int j = end - 1; - swap(end, pivot, arr); - - /* while (arr[i] <) { - - } - - while (arr[j] <) { - }*/ - - // 8,1,6,2,5,4 - // 1,8,6,2,5,4 - // 1,6,8,2,5,4 - // 1,2,8,6,5,4 - - // 1,2,4,6,5,8 - - return 0; - - } - - private void swap(int start, int pivot, int[] arr) { - int temp = arr[start]; - arr[start] = arr[pivot]; - arr[pivot] = temp; - } -} From 68ac18053ba771e98528165ca121f4cd1c2fa0bf Mon Sep 17 00:00:00 2001 From: Thangaraj A Date: Wed, 25 Mar 2020 00:22:48 +0530 Subject: [PATCH 26/51] Adding more problems --- src/geeksforgeeks/LiveCellDeadCellGame.java | 3 +-- src/geeksforgeeks/LivecellDeadCellGame.java | 28 --------------------- 2 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 src/geeksforgeeks/LivecellDeadCellGame.java diff --git a/src/geeksforgeeks/LiveCellDeadCellGame.java b/src/geeksforgeeks/LiveCellDeadCellGame.java index 2aecedc..9ec83b4 100644 --- a/src/geeksforgeeks/LiveCellDeadCellGame.java +++ b/src/geeksforgeeks/LiveCellDeadCellGame.java @@ -2,7 +2,6 @@ //https://leetcode.com/problems/game-of-life/discuss/73366/Clean-O(1)-space-O(mn)-time-Java-Solution public class LiveCellDeadCellGame { - public void gameOfLife(int[][] board) { int[][] dir = { { 1, -1 }, { 1, 0 }, { 1, 1 }, { 0, -1 }, { 0, 1 }, { -1, -1 }, { -1, 0 }, { -1, 1 } }; int row = board.length; @@ -35,4 +34,4 @@ public void gameOfLife(int[][] board) { } } -} +} \ No newline at end of file diff --git a/src/geeksforgeeks/LivecellDeadCellGame.java b/src/geeksforgeeks/LivecellDeadCellGame.java deleted file mode 100644 index 46bee19..0000000 --- a/src/geeksforgeeks/LivecellDeadCellGame.java +++ /dev/null @@ -1,28 +0,0 @@ -package geeksforgeeks; -public class LivecellDeadCellGame { - //https://leetcode.com/problems/game-of-life/discuss/73366/Clean-O(1)-space-O(mn)-time-Java-Solution - public void gameOfLife(int[][] board) { - int[][] dir ={{1,-1},{1,0},{1,1},{0,-1},{0,1},{-1,-1},{-1,0},{-1,1}}; - int row=board.length; - int col=board[0].length; - for(int i=0; i=row || j+dir[k][1]>=col || i+dir[k][0]<0 || j+dir[k][1]<0) continue; - if(board[i+dir[k][0]][j+dir[k][1]]==1 || board[i+dir[k][0]][j+dir[k][1]]==2) liveCells++; - } - - if(board[i][j]==0 && liveCells==3) board[i][j]=3; - if(board[i][j]==1 && (liveCells<2 || liveCells>3)) board[i][j]=2; - } - } - - for(int i=0; i Date: Wed, 25 Mar 2020 21:15:35 +0530 Subject: [PATCH 27/51] Adding more problems --- src/geeksforgeeks/MinTimeRotOranges.java | 22 ++- src/geeksforgeeks/MinimumSwapSortArray.java | 70 ++++--- src/geeksforgeeks/MinimumWindowSubstring.java | 80 ++++---- src/geeksforgeeks/MirrorBinaryTree.java | 34 ++-- .../MobileKeyPadCombinations.java | 17 +- src/geeksforgeeks/MoveZeroes.java | 3 + src/geeksforgeeks/NewRoadsMST.java | 174 +++++++++--------- src/geeksforgeeks/NextGreaterElement.java | 2 +- src/geeksforgeeks/NextGreaterNumber.java | 7 +- src/geeksforgeeks/NextLargestList.java | 58 ++++++ src/geeksforgeeks/Node.java | 35 ++-- src/geeksforgeeks/NonDecreasingArray.java | 5 +- src/geeksforgeeks/NutsAndBoltsMatch.java | 19 +- src/geeksforgeeks/OwnDataStructureUtil.java | 85 +++++---- src/geeksforgeeks/PalindromePartion.java | 49 ----- src/geeksforgeeks/PalindromePartitioning.java | 3 + .../PalindromeSinglyLinkedList.java | 15 +- src/geeksforgeeks/PalindromicSubSequence.java | 45 +++++ src/geeksforgeeks/PartitionLabel.java | 17 +- src/geeksforgeeks/PascalsTriangle.java | 39 +++- src/geeksforgeeks/Pattern132.java | 18 +- src/geeksforgeeks/PeakElement.java | 31 +++- src/geeksforgeeks/PerfectSquare.java | 5 +- 23 files changed, 486 insertions(+), 347 deletions(-) create mode 100644 src/geeksforgeeks/NextLargestList.java delete mode 100644 src/geeksforgeeks/PalindromePartion.java create mode 100644 src/geeksforgeeks/PalindromicSubSequence.java diff --git a/src/geeksforgeeks/MinTimeRotOranges.java b/src/geeksforgeeks/MinTimeRotOranges.java index a020b8a..5b1dfac 100644 --- a/src/geeksforgeeks/MinTimeRotOranges.java +++ b/src/geeksforgeeks/MinTimeRotOranges.java @@ -30,8 +30,9 @@ public String toString() { private boolean hasFreshOrange(int[][] grid) { for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[0].length; j++) { - if (grid[i][j] == 1) + if (grid[i][j] == 1) { return true; + } } } return false; @@ -48,8 +49,8 @@ private boolean isValidFresh(int row, int col, int[][] grid) { } private void rotOranges(Queue queue, Pair p, int[][] grid) { - int[] xMoves = {1, -1, 0, 0}; - int[] yMoves = {0, 0, 1, -1}; + int[] xMoves = { 1, -1, 0, 0 }; + int[] yMoves = { 0, 0, 1, -1 }; for (int k = 0; k < xMoves.length; k++) { int x = p.x + xMoves[k]; int y = p.y + yMoves[k]; @@ -65,33 +66,36 @@ public int findMinTime(int[][] grid) { Queue queue = new LinkedList<>(); for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[0].length; j++) { - if (grid[i][j] == 2) + if (grid[i][j] == 2) { queue.add(new Pair(i, j)); + } } } - if (queue.isEmpty()) + if (queue.isEmpty()) { return -1; + } queue.add(new Pair(-1, -1)); while (!queue.isEmpty()) { Pair p = queue.poll(); - if (!isDelimiter(p)) + if (!isDelimiter(p)) { rotOranges(queue, p, grid); - else if (!queue.isEmpty()) { + } else if (!queue.isEmpty()) { queue.add(p); // add back delimiter result += 1; } } - if (hasFreshOrange(grid)) + if (hasFreshOrange(grid)) { return -1; + } return result; } public static void main(String[] args) { - int grid[][] = {{2, 1, 0, 1, 1}, {1, 0, 2, 1, 1}, {1, 1, 1, 1, 1}}; + int grid[][] = { { 2, 1, 0, 1, 1 }, { 1, 0, 2, 1, 1 }, { 1, 1, 1, 1, 1 } }; System.out.println(new MinTimeRotOranges().findMinTime(grid)); } diff --git a/src/geeksforgeeks/MinimumSwapSortArray.java b/src/geeksforgeeks/MinimumSwapSortArray.java index ebea898..26d3d1b 100644 --- a/src/geeksforgeeks/MinimumSwapSortArray.java +++ b/src/geeksforgeeks/MinimumSwapSortArray.java @@ -5,44 +5,42 @@ /** * https://www.geeksforgeeks.org/minimum-number-swaps-required-sort-array/ - * */ class MinimumSwapSortArray { - public int minSwaps(int[] A, int N) { - int i = 0; - // Tree map sorts the order - Map resMap = new TreeMap<>(); - for (; i < N; i++) { - System.out.print(A[i] + " --> " + i + " "); - resMap.put(A[i], i); + public int minSwaps(int[] A, int N) { + int i = 0; + // Tree map sorts the order + Map treeMap = new TreeMap<>(); + for (; i < N; i++) { + System.out.print(A[i] + " --> " + i + " "); + treeMap.put(A[i], i); + } + System.out.println(); + i = 0; + for (Map.Entry entry : treeMap.entrySet()) { + System.out.print(entry.getKey() + " --> " + i + " "); + entry.setValue(i++); + } + int swap = 0; + for (i = 0; i < N; ) { + System.out.println(A[i] + "--" + treeMap.get(A[i]) + "--" + i); + // check if array position is same as treeMap's index + if (treeMap.get(A[i]) != i) { + int temp = A[i]; + A[i] = A[treeMap.get(temp)]; + A[treeMap.get(temp)] = temp; + swap++; + } else { + i++; + } + } + return swap; + } - } - System.out.println(); - i = 0; - for (Map.Entry entry : resMap.entrySet()) { - System.out.print(entry.getKey() + " --> " + i + " "); - entry.setValue(i++); - } - int swap = 0; - for (i = 0; i < N;) { - System.out.println(A[i] + "--" + resMap.get(A[i]) + "--" + i); - // check if array position is same as treeMap's index - if (resMap.get(A[i]) != i) { - int temp = A[i]; - A[i] = A[resMap.get(temp)]; - A[resMap.get(temp)] = temp; - swap++; - } else { - i++; - } - } - return swap; - } - - public static void main(String[] args) { - int[] a = { 1, 5, 4, 3, 2 }; - MinimumSwapSortArray g = new MinimumSwapSortArray(); - System.out.println(g.minSwaps(a, a.length)); - } + public static void main(String[] args) { + int[] a = { 1, 5, 4, 3, 2 }; + MinimumSwapSortArray g = new MinimumSwapSortArray(); + System.out.println(g.minSwaps(a, a.length)); + } } \ No newline at end of file diff --git a/src/geeksforgeeks/MinimumWindowSubstring.java b/src/geeksforgeeks/MinimumWindowSubstring.java index 64030c2..97b95a0 100644 --- a/src/geeksforgeeks/MinimumWindowSubstring.java +++ b/src/geeksforgeeks/MinimumWindowSubstring.java @@ -3,53 +3,59 @@ import java.util.HashMap; import java.util.Map; +/** + * https://leetcode.com/problems/minimum-window-substring/ + */ class MinimumWindowSubstring { - public static String minWindow(String s, String t) { + public static void main(String[] args) { + System.out.println(minWindow("AADOBECODEBANC", "ABC")); + System.out.println(minWindow("abcdebdde", "bde")); + } - if (s.length() == 0 || t.length() == 0) { + public static String minWindow(String s, String t) { + if (t.length() > s.length()) { return ""; } - - Map dictT = new HashMap<>(); - for (int i = 0; i < t.length(); i++) { - dictT.put(t.charAt(i), dictT.getOrDefault(t.charAt(i), 0) + 1); + Map map = new HashMap<>(); + for (char c : t.toCharArray()) { + map.put(c, map.getOrDefault(c, 0) + 1); } - - int required = dictT.size(); - int left = 0; - int right = 0; - int formed = 0; - Map windowCounts = new HashMap<>(); - int[] ans = {-1, 0, 0}; - - while (right < s.length()) { - char c = s.charAt(right); - windowCounts.put(c, windowCounts.getOrDefault(c, 0) + 1); - - if (dictT.containsKey(c) && windowCounts.get(c).intValue() == dictT.get(c).intValue()) { - formed++; + int counter = map.size(); + + int begin = 0, end = 0; + int head = 0; + int len = Integer.MAX_VALUE; + + while (end < s.length()) { + char c = s.charAt(end); + if (map.containsKey(c)) { + map.put(c, map.get(c) - 1); + if (map.get(c) == 0) { + counter--; + } } - while (left <= right && formed == required) { - c = s.charAt(left); - if (ans[0] == -1 || right - left + 1 < ans[0]) { - ans[0] = right - left + 1; - ans[1] = left; - ans[2] = right; + end++; + + while (counter == 0) { + char tempc = s.charAt(begin); + if (map.containsKey(tempc)) { + map.put(tempc, map.get(tempc) + 1); + if (map.get(tempc) > 0) { + counter++; + } } - windowCounts.put(c, windowCounts.get(c) - 1); - if (dictT.containsKey(c) && windowCounts.get(c).intValue() < dictT.get(c).intValue()) { - formed--; + if (end - begin < len) { + len = end - begin; + head = begin; } - left++; + begin++; } - right++; - } - return ans[0] == -1 ? "" : s.substring(ans[1], ans[2] + 1); - } - public static void main(String[] args) { - System.out.println(minWindow("AADOBECODEBANC", "ABC")); - System.out.println(minWindow("abcdebdde", "bde")); + } + if (len == Integer.MAX_VALUE) { + return ""; + } + return s.substring(head, head + len); } } \ No newline at end of file diff --git a/src/geeksforgeeks/MirrorBinaryTree.java b/src/geeksforgeeks/MirrorBinaryTree.java index 4b166ed..c75f255 100644 --- a/src/geeksforgeeks/MirrorBinaryTree.java +++ b/src/geeksforgeeks/MirrorBinaryTree.java @@ -1,8 +1,12 @@ -package geeksforgeeks;// Iterative Java program to convert a Binary -// Tree to its mirror +package geeksforgeeks; import java.util.*; +/** + * https://www.geeksforgeeks.org/write-an-efficient-c-function-to-convert-a-tree-into-its-mirror-tree/ + *

+ * Iterative Java program to convert a Binary Tree to its mirror + */ class MirrorBinaryTree { static class Node { @@ -11,7 +15,6 @@ static class Node { Node right; } - static Node newNode(int data) { Node node = new Node(); node.data = data; @@ -20,37 +23,40 @@ static Node newNode(int data) { } static void mirror(Node root) { - if (root == null) + if (root == null) { return; + } Queue q = new LinkedList<>(); q.add(root); while (q.size() > 0) { - Node curr = q.peek(); - q.remove(); + Node curr = q.remove(); + + // swap the elements Node temp = curr.left; curr.left = curr.right; curr.right = temp; - if (curr.left != null) + if (curr.left != null) { q.add(curr.left); - if (curr.right != null) + } + if (curr.right != null) { q.add(curr.right); + } } } - static void inOrder(Node node) { - if (node == null) + if (node == null) { return; + } inOrder(node.left); System.out.print(node.data + " "); inOrder(node.right); } - public static void main(String args[]) { Node root = newNode(1); root.left = newNode(2); @@ -58,14 +64,12 @@ public static void main(String args[]) { root.left.left = newNode(4); root.left.right = newNode(5); - System.out.print("\n Inorder traversal of the" - + " coned tree is \n"); + System.out.print("\n Inorder traversal of the" + " coned tree is \n"); inOrder(root); mirror(root); - System.out.print("\n Inorder traversal of the " + - "mirror tree is \n"); + System.out.print("\n Inorder traversal of the " + "mirror tree is \n"); inOrder(root); } } diff --git a/src/geeksforgeeks/MobileKeyPadCombinations.java b/src/geeksforgeeks/MobileKeyPadCombinations.java index 09ac8a4..f97c583 100644 --- a/src/geeksforgeeks/MobileKeyPadCombinations.java +++ b/src/geeksforgeeks/MobileKeyPadCombinations.java @@ -3,6 +3,9 @@ import java.util.ArrayList; import java.util.List; +/** + * https://www.geeksforgeeks.org/find-possible-words-phone-digits/ + */ public class MobileKeyPadCombinations { public List letterCombinations(String digits) { @@ -11,27 +14,27 @@ public List letterCombinations(String digits) { return result; } - String[] charsCombs = { "--", "00", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; + String[] keypad = { "--", "00", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; - generateCombinations(digits, charsCombs, digits.length(), 0, new StringBuilder(), result); + generateCombinations(digits, keypad, digits.length(), 0, new StringBuilder(), result); return result; } - public void generateCombinations(String digits, String[] charsCombos, int len, int start, StringBuilder sb, + public void generateCombinations(String digits, String[] keypad, int len, int startIndex, StringBuilder sb, List result) { - if (start == len) { + if (startIndex == len) { result.add(sb.toString()); return; } - for (char ch : charsCombos[digits.charAt(start) - '0'].toCharArray()) { + for (char ch : keypad[digits.charAt(startIndex) - '0'].toCharArray()) { sb.append(ch); - generateCombinations(digits, charsCombos, len, start + 1, sb, result); + generateCombinations(digits, keypad, len, startIndex + 1, sb, result); sb.deleteCharAt(sb.length() - 1); } } public static void main(String[] args) { - new MobileKeyPadCombinations().letterCombinations("23"); + new MobileKeyPadCombinations().letterCombinations("23").stream().forEach(System.out::println); } } \ No newline at end of file diff --git a/src/geeksforgeeks/MoveZeroes.java b/src/geeksforgeeks/MoveZeroes.java index 307f5ac..2dcdd93 100644 --- a/src/geeksforgeeks/MoveZeroes.java +++ b/src/geeksforgeeks/MoveZeroes.java @@ -2,6 +2,9 @@ import java.util.Arrays; +/** + * https://leetcode.com/problems/move-zeroes/ + */ class MoveZeroes { public static void main(String[] args) { diff --git a/src/geeksforgeeks/NewRoadsMST.java b/src/geeksforgeeks/NewRoadsMST.java index 2df9c93..1b2487b 100644 --- a/src/geeksforgeeks/NewRoadsMST.java +++ b/src/geeksforgeeks/NewRoadsMST.java @@ -10,104 +10,104 @@ public class NewRoadsMST { - public static void main(String[] args) { - Graph graph = new Graph(false); - graph.addEdge(1, 4, -1); - graph.addEdge(2, 3, -1); - graph.addEdge(4, 5, -1); - graph.addEdge(1, 2, 5); - graph.addEdge(1, 3, 10); - graph.addEdge(1, 6, 2); - graph.addEdge(5, 6, 5); - - NewRoadsMST newRoads = new NewRoadsMST(); - newRoads.mst(graph); - } - - private void mst(Graph graph) { - List edges = graph.allEdges; - EdgeComparator edgeComparator = new EdgeComparator(); - Collections.sort(edges, edgeComparator); - DisjointSet disjointSet = new DisjointSet(); - List resultEdges = new ArrayList<>(); - Collection allVertex = graph.getAllVertex(); - for (Object vertex : allVertex) { - disjointSet.makeNode((Vertex) vertex); - } - - for (Edge edge : edges) { - if (edge.weight < 0) { - if (disjointSet.unionSet(edge)) { - resultEdges.add(edge); - } - } - } - - for (Edge edge : edges) { - if (edge.weight > 0) { - if (disjointSet.unionSet(edge)) { - resultEdges.add(edge); - } - } - } - - for (Edge edge : resultEdges) { - System.out.println(edge.vertex1.data + "->" + edge.vertex2.data + "->" + edge.weight); - } - } + public static void main(String[] args) { + Graph graph = new Graph(false); + graph.addEdge(1, 4, -1); + graph.addEdge(2, 3, -1); + graph.addEdge(4, 5, -1); + graph.addEdge(1, 2, 5); + graph.addEdge(1, 3, 10); + graph.addEdge(1, 6, 2); + graph.addEdge(5, 6, 5); + + NewRoadsMST newRoads = new NewRoadsMST(); + newRoads.mst(graph); + } + + private void mst(Graph graph) { + List edges = graph.allEdges; + EdgeComparator edgeComparator = new EdgeComparator(); + Collections.sort(edges, edgeComparator); + DisjointSet disjointSet = new DisjointSet(); + List resultEdges = new ArrayList<>(); + Collection allVertex = graph.getAllVertex(); + for (Object vertex : allVertex) { + disjointSet.makeNode((Vertex) vertex); + } + + for (Edge edge : edges) { + if (edge.weight < 0) { + if (disjointSet.unionSet(edge)) { + resultEdges.add(edge); + } + } + } + + for (Edge edge : edges) { + if (edge.weight > 0) { + if (disjointSet.unionSet(edge)) { + resultEdges.add(edge); + } + } + } + + for (Edge edge : resultEdges) { + System.out.println(edge.vertex1.data + "->" + edge.vertex2.data + "->" + edge.weight); + } + } } class EdgeComparator implements Comparator { - @Override - public int compare(Edge e1, Edge e2) { - if (e1.weight < e2.weight) { - return -1; - } - return 1; - } + @Override + public int compare(Edge e1, Edge e2) { + if (e1.weight < e2.weight) { + return -1; + } + return 1; + } } class DisjointSet { - Map allNodes = new HashMap<>(); - - protected void makeNode(Vertex vertex) { - Node node = new Node(vertex.id); - node.parent = node; - allNodes.put(vertex.id, node); - } - - public boolean unionSet(Edge edge) { - Node srcNode = allNodes.get(edge.vertex1.data); - Node destNode = allNodes.get(edge.vertex2.data); - - Node parentSrcNode = findParent(srcNode); - Node parentDestNode = findParent(destNode); - - if (parentSrcNode != parentDestNode) { - parentDestNode.parent = parentSrcNode; - return true; - } - return false; - } - - public Node findParent(Node node) { - Node parent = node.parent; - if (parent == node) { - return node; - } - return findParent(node.parent); - } + Map allNodes = new HashMap<>(); + + protected void makeNode(Vertex vertex) { + Node node = new Node(vertex.id); + node.parent = node; + allNodes.put(vertex.id, node); + } + + public boolean unionSet(Edge edge) { + Node srcNode = allNodes.get(edge.vertex1.data); + Node destNode = allNodes.get(edge.vertex2.data); + + Node parentSrcNode = findParent(srcNode); + Node parentDestNode = findParent(destNode); + + if (parentSrcNode != parentDestNode) { + parentDestNode.parent = parentSrcNode; + return true; + } + return false; + } + + public Node findParent(Node node) { + Node parent = node.parent; + if (parent == node) { + return node; + } + return findParent(node.parent); + } } class Node { - long data; - Node parent; - Node child; + long data; + Node parent; + Node child; - public Node(long id) { - this.data = id; - } + public Node(long id) { + this.data = id; + } } diff --git a/src/geeksforgeeks/NextGreaterElement.java b/src/geeksforgeeks/NextGreaterElement.java index 6128470..41dea07 100644 --- a/src/geeksforgeeks/NextGreaterElement.java +++ b/src/geeksforgeeks/NextGreaterElement.java @@ -9,7 +9,7 @@ */ class NextGreaterElement { - static int arr[] = {4, 5, 2, 25}; + static int arr[] = { 4, 5, 2, 25 }; // 9,1,2,3,4,5,6,7 public static void printNGE() { diff --git a/src/geeksforgeeks/NextGreaterNumber.java b/src/geeksforgeeks/NextGreaterNumber.java index 7278dd9..c6bb20a 100644 --- a/src/geeksforgeeks/NextGreaterNumber.java +++ b/src/geeksforgeeks/NextGreaterNumber.java @@ -24,6 +24,7 @@ private void sortSubarray(int[] number, int i, int j) { } } + // 6, 9, 3, 8, 6, 5, 2 public void findNextGreaterNumber(int[] number) { int lastDigitSeen = number[number.length - 1]; int i; @@ -56,11 +57,7 @@ public void findNextGreaterNumber(int[] number) { public static void main(String[] args) { NextGreaterNumber solution = new NextGreaterNumber(); - int[] number = {6, 9, 3, 8, 6, 5, 2}; - // 6938652 - // 6983652 - // 6982356 - // i =3 + int[] number = { 6, 9, 3, 8, 6, 5, 2 }; solution.findNextGreaterNumber(number); diff --git a/src/geeksforgeeks/NextLargestList.java b/src/geeksforgeeks/NextLargestList.java new file mode 100644 index 0000000..735e08c --- /dev/null +++ b/src/geeksforgeeks/NextLargestList.java @@ -0,0 +1,58 @@ +package geeksforgeeks; + +import java.util.Stack; + +/** + * https://leetcode.com/problems/next-greater-node-in-linked-list/ + */ +class NextLargestList { + + public int[] nextLargerNodes(ListNode head) { + + if (head == null) { + return new int[0]; + } + int size = getSize(head); + int[] result = new int[size]; + head = reverse(head); + Stack stack = new Stack<>(); + stack.push(head.val); + head = head.next; + int i = size - 2; + result[size - 1] = 0; + while (head != null) { + + while (!stack.isEmpty() && stack.peek() <= head.val) { + stack.pop(); + } + result[i] = stack.isEmpty() ? 0 : stack.peek(); + stack.push(head.val); + head = head.next; + i--; + } + + return result; + } + + public int getSize(ListNode head) { + int size = 0; + ListNode root = head; + while (root != null) { + root = root.next; + size++; + } + return size; + } + + public ListNode reverse(ListNode head) { + ListNode root = head; + ListNode prev = null; + while (root != null) { + ListNode next = root.next; + root.next = prev; + prev = root; + root = next; + } + return prev; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/Node.java b/src/geeksforgeeks/Node.java index 68985c0..04e0bb8 100644 --- a/src/geeksforgeeks/Node.java +++ b/src/geeksforgeeks/Node.java @@ -1,10 +1,11 @@ package geeksforgeeks; - +/** + * https://www.geeksforgeeks.org/remove-bst-keys-outside-the-given-range/ + */ class RemoveBSTGivenOutsideRange { - private static BSTNode removeOutsideRange(BSTNode root, - int min, int max) { + private static BSTNode removeOutsideRange(BSTNode root, int min, int max) { if (root == null) { return null; } @@ -28,27 +29,20 @@ private static BSTNode removeOutsideRange(BSTNode root, public static BSTNode newNode(int num) { BSTNode temp = new BSTNode(); - temp.data - = num; + temp.data = num; temp.left = null; temp.right = null; return temp; } - public static BSTNode insert(BSTNode root, - int data) { + public static BSTNode insert(BSTNode root, int data) { if (root == null) { - return newNode(data - ); + return newNode(data); } - if (root.data - > data - ) { - root.left = insert(root.left, data - ); + if (root.data > data) { + root.left = insert(root.left, data); } else { - root.right = insert(root.right, data - ); + root.right = insert(root.right, data); } return root; } @@ -56,8 +50,7 @@ public static BSTNode insert(BSTNode root, private static void inorderTraversal(BSTNode root) { if (root != null) { inorderTraversal(root.left); - System.out.print(root.data - + " "); + System.out.print(root.data + " "); inorderTraversal(root.right); } } @@ -72,14 +65,12 @@ public static void main(String[] args) { root = insert(root, 13); root = insert(root, 7); - System.out.print("Inorder Traversal of " + - "the given tree is: "); + System.out.print("Inorder Traversal of " + "the given tree is: "); inorderTraversal(root); root = removeOutsideRange(root, -10, 13); - System.out.print("\nInorder traversal of " + - "the modified tree: "); + System.out.print("\nInorder traversal of " + "the modified tree: "); inorderTraversal(root); } } diff --git a/src/geeksforgeeks/NonDecreasingArray.java b/src/geeksforgeeks/NonDecreasingArray.java index b24d1f2..8c7bb2e 100644 --- a/src/geeksforgeeks/NonDecreasingArray.java +++ b/src/geeksforgeeks/NonDecreasingArray.java @@ -4,6 +4,7 @@ * https://leetcode.com/problems/non-decreasing-array/description/ */ class NonDecreasingArray { + public boolean checkPossibility(int[] nums) { int count = 0; @@ -22,8 +23,8 @@ public boolean checkPossibility(int[] nums) { public static void main(String[] args) { // 1,4,2,3 - //3,4,2,3 - int[] nums = {7, 8, 2, 3}; + // //3,4,2,3 + int[] nums = { 7, 8, 2, 3 }; NonDecreasingArray nda = new NonDecreasingArray(); System.out.println(nda.checkPossibility(nums)); } diff --git a/src/geeksforgeeks/NutsAndBoltsMatch.java b/src/geeksforgeeks/NutsAndBoltsMatch.java index 95800bb..43f609b 100644 --- a/src/geeksforgeeks/NutsAndBoltsMatch.java +++ b/src/geeksforgeeks/NutsAndBoltsMatch.java @@ -1,18 +1,22 @@ package geeksforgeeks; -// Java program to solve nut and bolt problem using Quick Sort -// unresolved +/** + * https://www.geeksforgeeks.org/nuts-bolts-problem-lock-key-problem/ + * Java program to solve nut and bolt problem using Quick Sort + */ public class NutsAndBoltsMatch { + public static void main(String[] args) { // Nuts and bolts are represented as array of characters - char nuts[] = {'@', '#', '$', '%', '^', '&'}; - char bolts[] = {'$', '%', '&', '^', '@', '#'}; + char nuts[] = { '@', '#', '$', '%', '^', '&' }; + char bolts[] = { '$', '%', '&', '^', '@', '#' }; // Method based on quick sort which matches nuts and bolts matchPairs(nuts, bolts, 0, 5); System.out.println("Matched nuts and bolts are : "); printArray(nuts); + System.out.println(); printArray(bolts); } @@ -25,14 +29,13 @@ private static void printArray(char[] arr) { } // Method which works just like quick sort - private static void matchPairs(char[] nuts, char[] bolts, int low, - int high) { + private static void matchPairs(char[] nuts, char[] bolts, int low, int high) { if (low < high) { + // Choose last character of bolts array for nuts partition. int pivot = partition(nuts, low, high, bolts[high]); - // Now using the partition of nuts choose that for bolts - // partition. + // Now using the partition of nuts choose that for bolts partition. partition(bolts, low, high, nuts[pivot]); // Recur for [low...pivot-1] & [pivot+1...high] for nuts and diff --git a/src/geeksforgeeks/OwnDataStructureUtil.java b/src/geeksforgeeks/OwnDataStructureUtil.java index 6ffe412..25693fb 100644 --- a/src/geeksforgeeks/OwnDataStructureUtil.java +++ b/src/geeksforgeeks/OwnDataStructureUtil.java @@ -2,50 +2,55 @@ import java.util.*; +/** + * https://leetcode.com/problems/insert-delete-getrandom-o1/ + */ class OwnDataStructureUtil { - ArrayList list; - HashMap map; - java.util.Random rand = new java.util.Random(); + ArrayList list; + HashMap map; + java.util.Random rand = new java.util.Random(); - public OwnDataStructureUtil() { - list = new ArrayList<>(); - map = new HashMap<>(); - } + public OwnDataStructureUtil() { + list = new ArrayList<>(); + map = new HashMap<>(); + } - public boolean insert(int val) { - if (map.containsKey(val)) - return false; - map.put(val, list.size()); - list.add(val); - return true; - } + public boolean insert(int val) { + if (map.containsKey(val)) { + return false; + } + map.put(val, list.size()); + list.add(val); + return true; + } - public boolean remove(int val) { - if (!map.containsKey(val)) - return false; - int loc = map.get(val); - if (loc < list.size() - 1) { // not the last one than swap the last one with this val - int lastOne = list.get(list.size() - 1); - list.set(loc, lastOne); - map.put(lastOne, loc); - } - map.remove(val); - list.remove(list.size() - 1); - return true; - } + public boolean remove(int val) { + if (!map.containsKey(val)) { + return false; + } + int loc = map.get(val); + if (loc < list.size() - 1) { // not the last one than swap the last one with this val + int lastOne = list.get(list.size() - 1); + list.set(loc, lastOne); + map.put(lastOne, loc); + } + map.remove(val); + list.remove(list.size() - 1); + return true; + } - public int getRandom() { - return list.get(rand.nextInt(list.size())); - } + public int getRandom() { + return list.get(rand.nextInt(list.size())); + } - public static void main(String[] args) { - OwnDataStructureUtil ds = new OwnDataStructureUtil(); - ds.insert(10); - ds.insert(20); - ds.insert(30); - ds.insert(40); - ds.remove(20); - ds.insert(50); - System.out.println(ds.getRandom()); - } + public static void main(String[] args) { + OwnDataStructureUtil ds = new OwnDataStructureUtil(); + ds.insert(10); + ds.insert(20); + ds.insert(30); + ds.insert(40); + ds.remove(20); + ds.insert(50); + System.out.println(ds.getRandom()); + } } diff --git a/src/geeksforgeeks/PalindromePartion.java b/src/geeksforgeeks/PalindromePartion.java deleted file mode 100644 index c23bf2f..0000000 --- a/src/geeksforgeeks/PalindromePartion.java +++ /dev/null @@ -1,49 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -class PalindromePartion { - public List> partition(String s) { - List> result= new ArrayList<>(); - if(s==null || s.length()==0) return result; - - backtrackingUtil(s, result, new ArrayList()); - - return result; - - } - - public void backtrackingUtil(String s, List> result, List tempList){ - if(s==null || s.length()==0){ - result.add(new ArrayList<>(tempList)); - return; - } - - for(int i=1;i<=s.length();i++){ - String temp= s.substring(0,i); - if(isPalin(temp)){ - tempList.add(temp); - backtrackingUtil(s.substring(i,s.length()),result,tempList); - tempList.remove(tempList.size()-1); - } - } - - } - - public boolean isPalin(String s){ - int start=0; - int end= s.length()-1; - while(start<=end){ - if(s.charAt(start)!=s.charAt(end)) return false; - start++; - end--; - } - return true; - } - - public static void main(String[] args) { - new PalindromePartion().partition("aab"); - } - - -} \ No newline at end of file diff --git a/src/geeksforgeeks/PalindromePartitioning.java b/src/geeksforgeeks/PalindromePartitioning.java index e0806b6..bc76432 100644 --- a/src/geeksforgeeks/PalindromePartitioning.java +++ b/src/geeksforgeeks/PalindromePartitioning.java @@ -4,6 +4,9 @@ import java.util.Collections; import java.util.List; +/** + * https://leetcode.com/problems/palindrome-partitioning/ + */ class PalindromePartitioning { public List> partition(String s) { diff --git a/src/geeksforgeeks/PalindromeSinglyLinkedList.java b/src/geeksforgeeks/PalindromeSinglyLinkedList.java index 9c51c27..2bee7a4 100644 --- a/src/geeksforgeeks/PalindromeSinglyLinkedList.java +++ b/src/geeksforgeeks/PalindromeSinglyLinkedList.java @@ -1,5 +1,8 @@ package geeksforgeeks; +/** + * https://leetcode.com/problems/palindrome-linked-list/ + */ public class PalindromeSinglyLinkedList { class Node { @@ -47,13 +50,13 @@ public boolean isPalindrome(Node head) { return true; } - public Node reverse(Node head) { + public Node reverse(Node slow) { Node prev = null; - while (head != null) { - Node next = head.next; - head.next = prev; - prev = head; - head = next; + while (slow != null) { + Node next = slow.next; + slow.next = prev; + prev = slow; + slow = next; } return prev; } diff --git a/src/geeksforgeeks/PalindromicSubSequence.java b/src/geeksforgeeks/PalindromicSubSequence.java new file mode 100644 index 0000000..4805382 --- /dev/null +++ b/src/geeksforgeeks/PalindromicSubSequence.java @@ -0,0 +1,45 @@ +package geeksforgeeks; + +class PalindromicSubSequence { + + public int longestPalindromeSubseq(String s) { + if (s == null || s.length() == 0) { + return 0; + } + + int[][] dp = new int[s.length()][s.length()]; + + for (int i = s.length() - 1; i >= 0; i--) { + for (int j = i; j < s.length(); j++) { + if (i == j) { + dp[i][j] = 1; + continue; + } + + dp[i][j] = s.charAt(i) == s.charAt(j) ? 2 + dp[i + 1][j - 1] : Math.max(dp[i + 1][j], dp[i][j - 1]); + } + } + + return dp[0][s.length() - 1]; + + } + + public int longestPalindromeSubseq1(String s) { + int[] dp = new int[s.length()]; + for (int i = s.length() - 1; i >= 0; i--) { + dp[i] = 1; + int pre = 0; + for (int j = i + 1; j < s.length(); j++) { + int tmp = dp[j]; + if (s.charAt(i) == s.charAt(j)) { + dp[j] = pre + 2; + } else { + dp[j] = Math.max(dp[j], dp[j - 1]); + } + pre = tmp; + } + } + + return dp[s.length() - 1]; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/PartitionLabel.java b/src/geeksforgeeks/PartitionLabel.java index c5f7d31..b7b06ee 100644 --- a/src/geeksforgeeks/PartitionLabel.java +++ b/src/geeksforgeeks/PartitionLabel.java @@ -3,17 +3,24 @@ import java.util.ArrayList; import java.util.List; +/** + * https://leetcode.com/problems/partition-labels/ + */ class PartitionLabel { - public List partitionLabels(String S) { + + public List partitionLabels(String str) { + int[] last = new int[26]; - for (int i = 0; i < S.length(); ++i) - last[S.charAt(i) - 'a'] = i; + for (int i = 0; i < str.length(); ++i) + // find last appearance of the char + last[str.charAt(i) - 'a'] = i; int j = 0; int anchor = 0; List ans = new ArrayList<>(); - for (int i = 0; i < S.length(); ++i) { - j = Math.max(j, last[S.charAt(i) - 'a']); + for (int i = 0; i < str.length(); ++i) { + // find the max of j and last appearance of str[i] + j = Math.max(j, last[str.charAt(i) - 'a']); if (i == j) { // it is (1+i-anchor) int length = i - anchor + 1; diff --git a/src/geeksforgeeks/PascalsTriangle.java b/src/geeksforgeeks/PascalsTriangle.java index 94aceb5..a061ae7 100644 --- a/src/geeksforgeeks/PascalsTriangle.java +++ b/src/geeksforgeeks/PascalsTriangle.java @@ -1,20 +1,43 @@ package geeksforgeeks; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; +/** + * https://leetcode.com/problems/pascals-triangle/ + */ public class PascalsTriangle { + public List> generate(int numRows) { - List> allrows = new ArrayList>(); - ArrayList row = new ArrayList(); - for (int i = 0; i < numRows; i++) { - row.add(0, 1); // append 1 at the end of each iteration - for (int j = 1; j < row.size() - 1; j++) - row.set(j, row.get(j) + row.get(j + 1)); // modify after adding 1 - allrows.add(new ArrayList(row));// take a copy of row and save it in result + if (numRows == 0) { + return Collections.emptyList(); } - return allrows; + List> result = new ArrayList<>(); + List first = Arrays.asList(1); + result.add(first); + if (numRows == 1) { + return result; + } + List second = Arrays.asList(1, 1); + result.add(second); + if (numRows == 2) { + return result; + } + + for (int i = 2; i < numRows; i++) { + List temp = new ArrayList<>(); + temp.add(1); + for (int k = 0; k < i - 1; k++) { + int j = k + 1; + temp.add(result.get(i - 1).get(k) + result.get(i - 1).get(j)); + } + temp.add(1); + result.add(temp); + } + return result; } } \ No newline at end of file diff --git a/src/geeksforgeeks/Pattern132.java b/src/geeksforgeeks/Pattern132.java index e2815e5..f4ee0a3 100644 --- a/src/geeksforgeeks/Pattern132.java +++ b/src/geeksforgeeks/Pattern132.java @@ -1,11 +1,12 @@ package geeksforgeeks; import java.util.Arrays; + /*https://leetcode.com/problems/132-pattern/discuss/94089/Java-solutions-from-O(n3)-to-O(n)-for-%22132%22-pattern-(updated-with-one-pass-slution)*/ public class Pattern132 { - public static boolean find132pattern(int[] arr) { + int[] temp = Arrays.copyOf(arr, arr.length); for (int i = 1; i < arr.length; i++) { @@ -14,18 +15,21 @@ public static boolean find132pattern(int[] arr) { //{3, 3, 3, 1, 1, 1, 1, 1} for (int j = arr.length - 1, top = arr.length; j >= 0; j--) { - if (arr[j] <= temp[j]) continue; - while (top < arr.length && temp[top] <= temp[j]) top++; - if (top < arr.length && arr[j] > temp[top]) return true; + if (arr[j] <= temp[j]) { + continue; + } + while (top < arr.length && temp[top] <= temp[j]) + top++; + if (top < arr.length && arr[j] > temp[top]) { + return true; + } temp[--top] = arr[j]; } - return false; } public static void main(String[] args) { - int[] arr = {3, 4, 1, 2, 9, 6, 7, 8}; - + int[] arr = { 3, 4, 1, 2, 9, 6, 7, 8 }; find132pattern(arr); } } diff --git a/src/geeksforgeeks/PeakElement.java b/src/geeksforgeeks/PeakElement.java index dfeedb9..dfc8c67 100644 --- a/src/geeksforgeeks/PeakElement.java +++ b/src/geeksforgeeks/PeakElement.java @@ -1,10 +1,11 @@ package geeksforgeeks; /** - * @author i312458 + * https://leetcode.com/problems/find-peak-element/ */ public class PeakElement { - public int findPeakElement(int[] nums) { + + public int findPeakElementOld(int[] nums) { int low = 0; int high = nums.length - 1; @@ -20,6 +21,32 @@ public int findPeakElement(int[] nums) { return low; } + int findPeakElement(int[] nums) { + int n = nums.length; + if (n == 0) { + return -1; + } + if (n == 1) { + return 0; + } + if (n == 2) { + return nums[0] > nums[1] ? 0 : 1; + } + int low = 0, high = n - 1; + while (low + 2 <= high) { + int mid = low + (high - low) / 2; + if (nums[mid - 1] < nums[mid] && nums[mid] > nums[mid + 1]) { + return mid; + } + if (nums[mid - 1] > nums[mid]) { + high = mid; + } else { + low = mid; + } + } + return nums[low] > nums[high] ? low : high; + } + public static void main(String[] args) { PeakElement pe = new PeakElement(); int[] arr = { 1, 1, 1, 3, 2, 1, 2 }; diff --git a/src/geeksforgeeks/PerfectSquare.java b/src/geeksforgeeks/PerfectSquare.java index 87e7913..ef2cbd8 100644 --- a/src/geeksforgeeks/PerfectSquare.java +++ b/src/geeksforgeeks/PerfectSquare.java @@ -5,6 +5,9 @@ import java.util.Queue; import java.util.Set; +/** + * https://leetcode.com/problems/perfect-squares/ + */ class PerfectSquare { public int numSquares(int n) { @@ -39,6 +42,6 @@ public int numSquares(int n) { public static void main(String[] args) { PerfectSquare ps = new PerfectSquare(); - System.out.println(ps.numSquares(12)); + System.out.println(ps.numSquares(13)); } } \ No newline at end of file From cb6982cfea7019ecc072cac5cceeb66a091104fb Mon Sep 17 00:00:00 2001 From: Thangaraj A Date: Fri, 27 Mar 2020 11:03:23 +0530 Subject: [PATCH 28/51] Adding more problems --- .../ConstructTreeFromInorderAndPreorder.java | 3 + src/geeksforgeeks/ConvertXToY.java | 22 ++-- ...enthesis.java => GenerateParenthesis.java} | 7 +- .../MobileKeyPadCombinations.java | 19 +++ src/geeksforgeeks/PetrolGasStation.java | 5 +- src/geeksforgeeks/PhoneLetterCombination.java | 34 ------ src/geeksforgeeks/PlusOne.java | 8 +- src/geeksforgeeks/Pow.java | 40 +++++++ src/geeksforgeeks/PreOrderInOrderTree.java | 40 ------- src/geeksforgeeks/PrisonAfterNDays.java | 6 +- src/geeksforgeeks/ProductExceptSelf.java | 26 ++--- src/geeksforgeeks/QueensAttacktheKing.java | 50 ++++++++ src/geeksforgeeks/RaceCar.java | 50 ++++++++ src/geeksforgeeks/RailwayPlatformProblem.java | 76 ------------ src/geeksforgeeks/RandomLinkedList.java | 110 +++++++++--------- src/geeksforgeeks/RemoveDuplicates.java | 5 +- src/geeksforgeeks/RemoveKDigits.java | 10 +- src/geeksforgeeks/ReorderLogs.java | 11 +- src/geeksforgeeks/RestoreIPAddress.java | 48 ++++---- src/geeksforgeeks/SearchAMaze.java | 17 +-- .../SearchAnElementInMatrix.java | 14 +-- .../SearchElementInSortedAndRotatedArray.java | 37 +++--- 22 files changed, 340 insertions(+), 298 deletions(-) rename src/geeksforgeeks/{PrintParenthesis.java => GenerateParenthesis.java} (84%) delete mode 100644 src/geeksforgeeks/PhoneLetterCombination.java create mode 100644 src/geeksforgeeks/Pow.java delete mode 100644 src/geeksforgeeks/PreOrderInOrderTree.java create mode 100644 src/geeksforgeeks/QueensAttacktheKing.java create mode 100644 src/geeksforgeeks/RaceCar.java delete mode 100644 src/geeksforgeeks/RailwayPlatformProblem.java diff --git a/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java b/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java index 011c059..44f50e0 100644 --- a/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java +++ b/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java @@ -4,6 +4,9 @@ import java.util.HashMap; import java.util.Map; +/** + * https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ + */ class ConstructTreeFromInorderAndPreorder { public TreeNode buildTree(int[] preorder, int[] inorder) { diff --git a/src/geeksforgeeks/ConvertXToY.java b/src/geeksforgeeks/ConvertXToY.java index 5c5ba14..7b0f137 100644 --- a/src/geeksforgeeks/ConvertXToY.java +++ b/src/geeksforgeeks/ConvertXToY.java @@ -10,15 +10,9 @@ import java.util.LinkedList; import java.util.Set; -class Steps { - int val; - int steps; - - public Steps(int val, int steps) { - this.val = val; - this.steps = steps; - } -} +/** + * https://www.geeksforgeeks.org/minimum-number-operation-required-convert-number-x-y/ + */ public class ConvertXToY { @@ -63,3 +57,13 @@ public static void main(String[] args) { System.out.println(minOperations(x, y)); } } + +class Steps { + int val; + int steps; + + public Steps(int val, int steps) { + this.val = val; + this.steps = steps; + } +} diff --git a/src/geeksforgeeks/PrintParenthesis.java b/src/geeksforgeeks/GenerateParenthesis.java similarity index 84% rename from src/geeksforgeeks/PrintParenthesis.java rename to src/geeksforgeeks/GenerateParenthesis.java index 869d054..dab0ec4 100644 --- a/src/geeksforgeeks/PrintParenthesis.java +++ b/src/geeksforgeeks/GenerateParenthesis.java @@ -1,8 +1,11 @@ package geeksforgeeks; -class PrintParenthesis { +/** + * https://leetcode.com/problems/generate-parentheses/ + */ +class GenerateParenthesis { - static void formParenthesis(char str[], int pos, int n, int open, int close) { + static void formParenthesis(char[] str, int pos, int n, int open, int close) { if (close == n) { for (int i = 0; i < str.length; i++) System.out.print(str[i]); diff --git a/src/geeksforgeeks/MobileKeyPadCombinations.java b/src/geeksforgeeks/MobileKeyPadCombinations.java index f97c583..a53ea51 100644 --- a/src/geeksforgeeks/MobileKeyPadCombinations.java +++ b/src/geeksforgeeks/MobileKeyPadCombinations.java @@ -1,6 +1,7 @@ package geeksforgeeks; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; /** @@ -37,4 +38,22 @@ public void generateCombinations(String digits, String[] keypad, int len, int st public static void main(String[] args) { new MobileKeyPadCombinations().letterCombinations("23").stream().forEach(System.out::println); } + + public List letterCombinationsIterative(String digits) { + LinkedList ans = new LinkedList<>(); + if (digits.isEmpty()) { + return ans; + } + String[] mapping = { "0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; + ans.add(""); + for (int i = 0; i < digits.length(); i++) { + int x = Character.getNumericValue(digits.charAt(i)); + while (ans.peek().length() == i) { + String t = ans.remove(); + for (char s : mapping[x].toCharArray()) + ans.add(t + s); + } + } + return ans; + } } \ No newline at end of file diff --git a/src/geeksforgeeks/PetrolGasStation.java b/src/geeksforgeeks/PetrolGasStation.java index fea857c..03a61f2 100644 --- a/src/geeksforgeeks/PetrolGasStation.java +++ b/src/geeksforgeeks/PetrolGasStation.java @@ -24,14 +24,13 @@ public static int canCompleteCircuit(int[] gas, int[] cost) { tank = 0; } } - return start; } public static void main(String[] args) { - int[] gas = {4, 6, 7, 4}; - int[] cost = {6, 5, 3, 5}; + int[] gas = { 4, 6, 7, 4 }; + int[] cost = { 6, 5, 3, 5 }; int start = canCompleteCircuit(gas, cost); System.out.println(start == -1 ? "No Solution" : "Start = " + start); } diff --git a/src/geeksforgeeks/PhoneLetterCombination.java b/src/geeksforgeeks/PhoneLetterCombination.java deleted file mode 100644 index 942fd06..0000000 --- a/src/geeksforgeeks/PhoneLetterCombination.java +++ /dev/null @@ -1,34 +0,0 @@ -package geeksforgeeks; - -import java.util.LinkedList; -import java.util.List; - -/** - * https://leetcode.com/problems/letter-combinations-of-a-phone-number/discuss/8064/My-java-solution-with-FIFO-queue - */ -public class PhoneLetterCombination { - - public List letterCombinations(String digits) { - LinkedList ans = new LinkedList<>(); - if (digits.isEmpty()) { - return ans; - } - String[] mapping = { "0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; - ans.add(""); - for (int i = 0; i < digits.length(); i++) { - int x = Character.getNumericValue(digits.charAt(i)); - while (ans.peek().length() == i) { - String t = ans.remove(); - for (char s : mapping[x].toCharArray()) - ans.add(t + s); - } - } - return ans; - } - - public static void main(String[] args) { - PhoneLetterCombination plc = new PhoneLetterCombination(); - List strings = plc.letterCombinations("2345"); - strings.forEach(System.out::println); - } -} diff --git a/src/geeksforgeeks/PlusOne.java b/src/geeksforgeeks/PlusOne.java index 3961917..2e59029 100644 --- a/src/geeksforgeeks/PlusOne.java +++ b/src/geeksforgeeks/PlusOne.java @@ -2,6 +2,9 @@ import java.util.Arrays; +/** + * https://leetcode.com/problems/plus-one/ + */ class PlusOne { public static int[] plusOne(int[] digits) { @@ -24,8 +27,11 @@ public static int[] plusOne(int[] digits) { sb.append(num); } } + if (remainder != 0) { + sb.append(remainder); + } - return sb.reverse().toString().chars().map(i -> i-'0').toArray(); + return sb.reverse().toString().chars().map(i -> i - '0').toArray(); } public static void main(String[] args) { diff --git a/src/geeksforgeeks/Pow.java b/src/geeksforgeeks/Pow.java new file mode 100644 index 0000000..08d2834 --- /dev/null +++ b/src/geeksforgeeks/Pow.java @@ -0,0 +1,40 @@ +package geeksforgeeks; + +/** + * https://leetcode.com/problems/powx-n/ + */ +public class Pow { + + public static void main(String[] args) { + Pow pow = new Pow(); + System.out.println(pow.pow(2.00000, 10)); + } + + public double pow(double x, int m) { + double temp = x; + if (m == 0) { + return 1; + } + temp = pow(x, m / 2); + if (m % 2 == 0) { + return temp * temp; + } else { + if (m > 0) { + return x * temp * temp; + } else { + return (temp * temp) / x; + } + } + } + + public double powIterative(double x, int n) { + double result = 1.0; + for (int i = n; i != 0; i /= 2, x *= x) { + if (i % 2 != 0) { + result *= x; + } + } + return n < 0 ? 1.0 / result : result; + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/PreOrderInOrderTree.java b/src/geeksforgeeks/PreOrderInOrderTree.java deleted file mode 100644 index 28b460d..0000000 --- a/src/geeksforgeeks/PreOrderInOrderTree.java +++ /dev/null @@ -1,40 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -class PreOrderInOrderTree { - public TreeNode buildTree(int[] preorder, int[] inorder) { - Map map = new HashMap<>(); - List set = new ArrayList<>(); - - for (int i = 0; i < inorder.length; i++) { - map.put(inorder[i], i); - } - - for (int i = 0; i < preorder.length; i++) { - set.add(preorder[i]); - } - - return buildTreeUtil(map, set, 0, inorder.length - 1); - - } - - public TreeNode buildTreeUtil(Map map, List set, int start, int end) { - if (start > end) { - return null; - } - if (set.isEmpty()) { - return null; - } - int rootval = set.get(0); - set.remove(0); - TreeNode root = new TreeNode(rootval); - int inorderIndex = map.get(rootval); - root.left = buildTreeUtil(map, set, start, inorderIndex - 1); - root.right = buildTreeUtil(map, set, inorderIndex + 1, end); - return root; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/PrisonAfterNDays.java b/src/geeksforgeeks/PrisonAfterNDays.java index db3c747..81327be 100644 --- a/src/geeksforgeeks/PrisonAfterNDays.java +++ b/src/geeksforgeeks/PrisonAfterNDays.java @@ -9,7 +9,9 @@ class PrisonAfterNDays { public static int[] prisonAfterNDays(int[] cells, int N) { - if (cells == null || cells.length == 0 || N <= 0) return cells; + if (cells == null || cells.length == 0 || N <= 0) { + return cells; + } boolean hasCycle = false; int cycle = 0; HashSet set = new HashSet<>(); @@ -43,7 +45,7 @@ private static int[] nextDay(int[] cells) { } public static void main(String[] args) { - int[] cells = {0, 1, 0, 1, 1, 0, 0, 1}; + int[] cells = { 0, 1, 0, 1, 1, 0, 0, 1 }; int N = 7; System.out.println(Arrays.toString(prisonAfterNDays(cells, N))); } diff --git a/src/geeksforgeeks/ProductExceptSelf.java b/src/geeksforgeeks/ProductExceptSelf.java index 494e9ba..e70c422 100644 --- a/src/geeksforgeeks/ProductExceptSelf.java +++ b/src/geeksforgeeks/ProductExceptSelf.java @@ -4,20 +4,20 @@ /** * https://leetcode.com/problems/product-of-array-except-self/ - * - * Given numbers [2, 3, 4, 5], regarding the third number 4, + *

+ * Given numbers [2, 3, 4, 5], regarding the third number 4, * the product of array except 4 is 2*3*5 which consists of two parts: left 2*3 and right 5. - * The product is left*right. We can get lefts and rights - * + * The product is left*right. We can get lefts and rights + *

* Numbers: 2 3 4 5 - Lefts: 2 2*3 2*3*4 - Rights: 3*4*5 4*5 5 - - Let’s fill the empty with 1: - -Numbers: 2 3 4 5 -Lefts: 1 2 2*3 2*3*4 -Rights: 3*4*5 4*5 5 1 + * Lefts: 2 2*3 2*3*4 + * Rights: 3*4*5 4*5 5 + *

+ * Let’s fill the empty with 1: + *

+ * Numbers: 2 3 4 5 + * Lefts: 1 2 2*3 2*3*4 + * Rights: 3*4*5 4*5 5 1 */ public class ProductExceptSelf { public static int[] productExceptSelf(int[] nums) { @@ -36,6 +36,6 @@ public static int[] productExceptSelf(int[] nums) { } public static void main(String[] args) { - System.out.println(Arrays.toString(productExceptSelf(new int[]{1, 2, 3, 4, 5}))); + System.out.println(Arrays.toString(productExceptSelf(new int[] { 1, 2, 3, 4, 5 }))); } } \ No newline at end of file diff --git a/src/geeksforgeeks/QueensAttacktheKing.java b/src/geeksforgeeks/QueensAttacktheKing.java new file mode 100644 index 0000000..7517485 --- /dev/null +++ b/src/geeksforgeeks/QueensAttacktheKing.java @@ -0,0 +1,50 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +class QueensAttacktheKing { + + public static List> queensAttacktheKing(int[][] queens, int[] king) { + List> result = new ArrayList<>(); + boolean[][] visited = new boolean[8][8]; + int[][] dirs = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 }, { -1, -1 }, { 1, 1 }, { 1, -1 }, { -1, 1 } }; + + for (int[] qu : queens) { + visited[qu[0]][qu[1]] = true; + } + + for (int[] dir : dirs) { + List temp = findQueensPositions(king, dir[0], dir[1], visited); + if (temp != null) { + result.add(temp); + } + } + + return result; + + } + + public static List findQueensPositions(int[] king, int x, int y, boolean[][] visited) { + int newX = x + king[0]; + int newY = y + king[1]; + + while (newX < 8 && newY < 8 && newX >= 0 && newY >= 0) { + if (visited[newX][newY]) { + return Arrays.asList(newX, newY); + } + newX += x; + newY += y; + + } + + return null; + } + + public static void main(String[] args) { + int[][] queens = { { 0, 1 }, { 1, 0 }, { 4, 0 }, { 0, 4 }, { 3, 3 }, { 2, 4 } }; + int[] king = { 0, 0 }; + System.out.println(queensAttacktheKing(queens, king)); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/RaceCar.java b/src/geeksforgeeks/RaceCar.java new file mode 100644 index 0000000..8449497 --- /dev/null +++ b/src/geeksforgeeks/RaceCar.java @@ -0,0 +1,50 @@ +package geeksforgeeks; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Queue; +import java.util.Set; + +class RaceCar { + + public int racecar(int target) { + Set visited = new HashSet<>(); + Queue queue = new LinkedList<>(); + queue.add(new StateNode(1, 0, 0)); + while (!queue.isEmpty()) { + + StateNode cur = queue.poll(); + if (cur.position == target) { + return cur.result; + } + // if A + int nextPosition = cur.position + cur.speed; + int nextSpeed = cur.speed * 2; + if (!visited.contains(nextSpeed + "," + nextPosition) && Math.abs(target - nextPosition) < target) { + visited.add(nextSpeed + "," + nextPosition); + queue.offer(new StateNode(nextSpeed, nextPosition, cur.result + 1)); + } + // if R + nextPosition = cur.position; + nextSpeed = cur.speed > 0 ? -1 : 1; + if (!visited.contains(nextSpeed + "," + nextPosition) && Math.abs(target - nextPosition) < target) { + visited.add(nextSpeed + "," + nextPosition); + queue.offer(new StateNode(nextSpeed, nextPosition, cur.result + 1)); + } + + } + return -1; + } +} + +class StateNode { + int speed; + int position; + int result; + + public StateNode(int speed, int position, int result) { + this.speed = speed; + this.position = position; + this.result = result; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/RailwayPlatformProblem.java b/src/geeksforgeeks/RailwayPlatformProblem.java deleted file mode 100644 index bad5b47..0000000 --- a/src/geeksforgeeks/RailwayPlatformProblem.java +++ /dev/null @@ -1,76 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.PriorityQueue; - -/** - * https://www.geeksforgeeks.org/minimum-number-platforms-required-railwaybus-station/ - */ -public class RailwayPlatformProblem { - - static int findPlatform(int[] arrival, int[] departure, int n) { - Arrays.sort(arrival); - Arrays.sort(departure); - - int platNeeded = 1; - int result = 1; - int i = 1; - int j = 0; - - while (i < n && j < n) { - if (arrival[i] <= departure[j]) { - platNeeded++; - i++; - - if (platNeeded > result) { - result = platNeeded; - } - } else { - platNeeded--; - j++; - } - } - return result; - } - - public int minMeetingRooms(List intervals) { - if (intervals == null || intervals.size() == 0) { - return -1; - } - //[(0,12),(5,10),(15,20)] - - Collections.sort(intervals, (a, b) -> Integer.compare(a.start, b.start)); - PriorityQueue queue = new PriorityQueue<>(); - queue.offer(intervals.get(0).end); - for (int i = 1; i < intervals.size(); i++) { - Interval temp = intervals.get(i); - if (queue.peek() <= temp.start) { - queue.poll(); - } - queue.offer(temp.end); - } - return queue.size(); - } - - public static void main(String[] args) { - - int[] arr = { 900, 940, 950, 1100, 1500, 1800 }; - int[] dep = { 910, 1200, 1120, 1130, 1900, 2000 }; - - int n = arr.length; - System.out.println("Minimum Number of Platforms Required = " + findPlatform(arr, dep, n)); - } - - class Interval { - int start, end; - - Interval(int start, int end) { - this.start = start; - this.end = end; - } - } - -} - diff --git a/src/geeksforgeeks/RandomLinkedList.java b/src/geeksforgeeks/RandomLinkedList.java index cd68a47..2e0070e 100644 --- a/src/geeksforgeeks/RandomLinkedList.java +++ b/src/geeksforgeeks/RandomLinkedList.java @@ -1,60 +1,62 @@ package geeksforgeeks; -class LLNode { - public int val; - public LLNode next; - public LLNode random; - - public LLNode() { - } +/** + * https://leetcode.com/problems/copy-list-with-random-pointer/ + */ +class RandomLinkedList { + + public LLNode copyRandomList(LLNode head) { + if (head == null) { + return null; + } + LLNode temp = head; + while (temp != null) { + LLNode LLNode = new LLNode(temp.val + 10, temp.next, null); + temp.next = LLNode; + temp = temp.next.next; + } + LLNode randomLLNode = head; + while (randomLLNode != null) { + randomLLNode.next.random = randomLLNode.random.next; + randomLLNode = randomLLNode.next.next; + } + LLNode copyHead = head.next; + LLNode tempHead = copyHead; + while (head != null && tempHead != null) { + head.next = head.next == null || head.next.next == null ? head.next : head.next.next; + tempHead.next = tempHead.next == null || tempHead.next.next == null ? tempHead.next : tempHead.next.next; + head = head.next; + tempHead = tempHead.next; + } + return copyHead; + } - public LLNode(int _val, LLNode _next, LLNode _random) { - val = _val; - next = _next; - random = _random; - } + public static void main(String[] args) { + LLNode head = new LLNode(1, null, null); + head.next = new LLNode(2, null, null); + head.next.next = new LLNode(3, null, null); + head.next.next.next = new LLNode(4, null, null); + head.random = head.next.next; + head.next.random = head.next.next.next; + head.next.next.random = head.next; + head.next.next.next.random = head; + RandomLinkedList solution = new RandomLinkedList(); + solution.copyRandomList(head); + } +} - public String toString() { - return "" + this.val; - } -}; +class LLNode { + public int val; + public LLNode next; + public LLNode random; -class RandomLinkedList { - public LLNode copyRandomList(LLNode head) { - if (head == null) - return null; - LLNode temp = head; - while (temp != null) { - LLNode LLNode = new LLNode(temp.val + 10, temp.next, null); - temp.next = LLNode; - temp = temp.next.next; - } - LLNode randomLLNode = head; - while (randomLLNode != null) { - randomLLNode.next.random = randomLLNode.random.next; - randomLLNode = randomLLNode.next.next; - } - LLNode copyHead = head.next; - LLNode tempHead = copyHead; - while (head != null && tempHead != null) { - head.next = head.next == null || head.next.next == null ? head.next : head.next.next; - tempHead.next = tempHead.next == null || tempHead.next.next == null ? tempHead.next : tempHead.next.next; - head = head.next; - tempHead = tempHead.next; - } - return copyHead; - } + public LLNode(int _val, LLNode _next, LLNode _random) { + val = _val; + next = _next; + random = _random; + } - public static void main(String[] args) { - LLNode head = new LLNode(1, null, null); - head.next = new LLNode(2, null, null); - head.next.next = new LLNode(3, null, null); - head.next.next.next = new LLNode(4, null, null); - head.random = head.next.next; - head.next.random = head.next.next.next; - head.next.next.random = head.next; - head.next.next.next.random = head; - RandomLinkedList solution = new RandomLinkedList(); - solution.copyRandomList(head); - } -} + public String toString() { + return "" + this.val; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/RemoveDuplicates.java b/src/geeksforgeeks/RemoveDuplicates.java index 7f2c5c3..328d15f 100644 --- a/src/geeksforgeeks/RemoveDuplicates.java +++ b/src/geeksforgeeks/RemoveDuplicates.java @@ -1,5 +1,8 @@ package geeksforgeeks; +/** + * https://leetcode.com/problems/remove-duplicates-from-sorted-array/ + */ class RemoveDuplicates { public int removeDuplicates(int[] nums) { @@ -18,7 +21,7 @@ public int removeDuplicates(int[] nums) { public static void main(String[] args) { RemoveDuplicates removeDuplicates = new RemoveDuplicates(); - int[] nums = { 1 , 1, 2 }; + int[] nums = { 1, 1, 2 }; removeDuplicates.removeDuplicates(nums); } } \ No newline at end of file diff --git a/src/geeksforgeeks/RemoveKDigits.java b/src/geeksforgeeks/RemoveKDigits.java index e9b14c3..01de51f 100644 --- a/src/geeksforgeeks/RemoveKDigits.java +++ b/src/geeksforgeeks/RemoveKDigits.java @@ -7,12 +7,14 @@ */ public class RemoveKDigits { - //1432219 - public static String removeKdigits(String num, int k) { + //143221999 + //121999 + public static String removeKDigits(String num, int k) { int len = num.length(); - if (k == len) + if (k == len) { return "0"; + } Stack stack = new Stack<>(); int i = 0; @@ -42,6 +44,6 @@ public static String removeKdigits(String num, int k) { } public static void main(String[] args) { - System.out.println(removeKdigits("14232191", 3)); + System.out.println(removeKDigits("14232191", 3)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/ReorderLogs.java b/src/geeksforgeeks/ReorderLogs.java index 2140cc1..6de581f 100644 --- a/src/geeksforgeeks/ReorderLogs.java +++ b/src/geeksforgeeks/ReorderLogs.java @@ -4,6 +4,10 @@ /*https://leetcode.com/articles/reorder-log-files/*/ class ReorderLogs { + + /* Input: logs = ["dig1 8 1 5 1","let1 art can","dig2 3 6","let2 own kit dig","let3 art zero"] + Output: ["let1 art can","let3 art zero","let2 own kit dig","dig1 8 1 5 1","dig2 3 6"]*/ + public static String[] reorderLogFiles(String[] logs) { Arrays.sort(logs, (s1, s2) -> { String[] split1 = s1.split(" ", 2); @@ -15,10 +19,11 @@ public static String[] reorderLogFiles(String[] logs) { if (!isDigit1 && !isDigit2) { // both letter-logs. int comp = split1[1].compareTo(split2[1]); - if (comp == 0) + if (comp == 0) { return split1[0].compareTo(split2[0]); - else + } else { return comp; + } } else if (isDigit1 && isDigit2) { // both digit-logs. So keep them in original order return 0; @@ -34,7 +39,7 @@ public static String[] reorderLogFiles(String[] logs) { } public static void main(String[] args) { - String[] string = {"dig1 8 1 5 1", "let1 art can", "dig2 3 6", "let2 own kit dig", "let3 art zero"}; + String[] string = { "dig1 8 1 5 1", "let1 art can", "dig2 3 6", "let2 own kit dig", "let3 art zero" }; System.out.println(Arrays.toString(reorderLogFiles(string))); } } \ No newline at end of file diff --git a/src/geeksforgeeks/RestoreIPAddress.java b/src/geeksforgeeks/RestoreIPAddress.java index 1ac6c71..452389c 100644 --- a/src/geeksforgeeks/RestoreIPAddress.java +++ b/src/geeksforgeeks/RestoreIPAddress.java @@ -1,32 +1,34 @@ package geeksforgeeks; import java.util.*; + //unresolved class RestoreIPAddress { - public List restoreIpAddresses(String s) { - List result = new ArrayList<>(); - doRestore(result, "", s, 0); - return result; - } + public List restoreIpAddresses(String s) { + List result = new ArrayList<>(); + doRestore(result, "", s, 0); + return result; + } - private void doRestore(List result, String path, String s, int k) { - if (s.isEmpty() || k == 4) { - if (s.isEmpty() && k == 4) - result.add(path.substring(1)); - return; - } - for (int i = 1; i <= (s.charAt(0) == '0' ? 1 : 3) && i <= s.length(); i++) { // Avoid leading 0 - String part = s.substring(0, i); - if (Integer.valueOf(part) <= 255) { - System.out.println(path); - doRestore(result, path + "." + part, s.substring(i), k + 1); - } - } - } + private void doRestore(List result, String path, String s, int k) { + if (s.isEmpty() || k == 4) { + if (s.isEmpty() && k == 4) { + result.add(path.substring(1)); + } + return; + } + for (int i = 1; i <= (s.charAt(0) == '0' ? 1 : 3) && i <= s.length(); i++) { // Avoid leading 0 + String part = s.substring(0, i); + if (Integer.valueOf(part) <= 255) { + System.out.println(path); + doRestore(result, path + "." + part, s.substring(i), k + 1); + } + } + } - public static void main(String[] args) { - RestoreIPAddress ip = new RestoreIPAddress(); - System.out.println(ip.restoreIpAddresses("25525511135").toString()); - } + public static void main(String[] args) { + RestoreIPAddress ip = new RestoreIPAddress(); + System.out.println(ip.restoreIpAddresses("25525511135").toString()); + } } diff --git a/src/geeksforgeeks/SearchAMaze.java b/src/geeksforgeeks/SearchAMaze.java index e810f2b..d7e19e1 100644 --- a/src/geeksforgeeks/SearchAMaze.java +++ b/src/geeksforgeeks/SearchAMaze.java @@ -1,6 +1,6 @@ package geeksforgeeks; -import java.util.ArrayDeque; +import java.util.LinkedList; import java.util.Queue; /** @@ -11,15 +11,16 @@ public class SearchAMaze { private static final int M = 10; private static final int N = 10; - private static final int row[] = {-1, 0, 0, 1}; - private static final int col[] = {0, -1, 1, 0}; + private static final int row[] = { -1, 0, 0, 1 }; + private static final int col[] = { 0, -1, 1, 0 }; private static boolean isValid(int mat[][], int row, int col) { return (row >= 0) && (row < M) && (col >= 0) && (col < N) && mat[row][col] == 1; } private static void BFS(int mat[][], int srcX, int srcY, int destX, int destY) { - Queue q = new ArrayDeque<>(); + + Queue q = new LinkedList<>(); q.add(new MazeNode(srcX, srcY, 0)); @@ -55,10 +56,10 @@ private static void BFS(int mat[][], int srcX, int srcY, int destX, int destY) { } public static void main(String[] args) { - int[][] mat = {{1, 1, 1, 1, 1, 0, 0, 1, 1, 1}, {0, 1, 1, 1, 1, 1, 0, 1, 0, 1}, - {0, 0, 1, 0, 1, 1, 1, 0, 0, 1}, {1, 0, 1, 1, 1, 0, 1, 1, 0, 1}, {0, 0, 0, 1, 0, 0, 0, 1, 0, 1}, - {1, 0, 1, 1, 1, 0, 0, 1, 1, 1}, {0, 0, 0, 0, 1, 0, 0, 1, 0, 1}, {0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, - {1, 1, 1, 1, 1, 0, 0, 1, 1, 1}, {0, 0, 1, 0, 0, 1, 1, 0, 0, 1}}; + int[][] mat = { { 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 }, { 0, 1, 1, 1, 1, 1, 0, 1, 0, 1 }, + { 0, 0, 1, 0, 1, 1, 1, 0, 0, 1 }, { 1, 0, 1, 1, 1, 0, 1, 1, 0, 1 }, { 0, 0, 0, 1, 0, 0, 0, 1, 0, 1 }, + { 1, 0, 1, 1, 1, 0, 0, 1, 1, 1 }, { 0, 0, 0, 0, 1, 0, 0, 1, 0, 1 }, { 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, + { 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 }, { 0, 0, 1, 0, 0, 1, 1, 0, 0, 1 } }; BFS(mat, 8, 0, 0, 9); } diff --git a/src/geeksforgeeks/SearchAnElementInMatrix.java b/src/geeksforgeeks/SearchAnElementInMatrix.java index 61bd8af..8ec6b96 100644 --- a/src/geeksforgeeks/SearchAnElementInMatrix.java +++ b/src/geeksforgeeks/SearchAnElementInMatrix.java @@ -1,9 +1,9 @@ package geeksforgeeks; + /*https://www.youtube.com/watch?v=FOa55B9Ikfg * https://leetcode.com/problems/search-a-2d-matrix-ii/ https://leetcode.com/problems/search-a-2d-matrix/*/ - public class SearchAnElementInMatrix { private static boolean searchII(int[][] mat, int n, int x) { @@ -16,10 +16,12 @@ private static boolean searchII(int[][] mat, int n, int x) { System.out.print("n Found at " + i + " " + j); return true; } - if (mat[i][j] > x) + if (mat[i][j] > x) { j--; - else // if mat[i][j] < x + } else // if mat[i][j] < x + { i++; + } } System.out.print("n Element not found"); @@ -51,11 +53,9 @@ public static boolean searchI(int[][] matrix, int target) { } public static void main(String[] args) { - int[][] mat = {{10, 20, 30, 40}, {15, 25, 35, 45}, {27, 29, 37, 48}, {32, 33, 39, 50}}; + int[][] mat = { { 10, 20, 30, 40 }, { 15, 25, 35, 45 }, { 27, 29, 37, 48 }, { 32, 33, 39, 50 } }; - int[][] matI = {{1, 3, 5, 7}, - {10, 11, 16, 20}, - {23, 30, 34, 50}}; + int[][] matI = { { 1, 3, 5, 7 }, { 10, 11, 16, 20 }, { 23, 30, 34, 50 } }; System.out.println(searchI(matI, 11)); System.out.println(searchII(mat, 4, 33)); diff --git a/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java b/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java index 64c5714..ac8ee6e 100644 --- a/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java +++ b/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java @@ -4,34 +4,35 @@ public class SearchElementInSortedAndRotatedArray { public static void main(String[] args) { - int[] arr = {4, 5, 6, 7, 0, 1, 2}; + int[] arr = { 4, 5, 6, 7, 0, 1, 2 }; SearchElementInSortedAndRotatedArray search = new SearchElementInSortedAndRotatedArray(); - System.out.println(search.searchInArray(arr, 1)); + System.out.println(search.searchInArray(arr, 0)); } // 4, 5, 6, 7, 0, 1, 2 - int searchInArray(int arr[], int key) { + int searchInArray(int nums[], int target) { - int left = 0; - int right = arr.length - 1; - - while (left < right) { - - int mid = (left + right) / 2; - if (arr[mid] == key) + int start = 0; + int end = nums.length - 1; + while (start <= end) { + int mid = (start + end) / 2; + if (nums[mid] == target) { return mid; + } - if (arr[left] < arr[mid]) { - if (key > arr[left] && key < arr[mid]) { - right = mid - 1; + if (nums[start] <= nums[mid]) { + if (target < nums[mid] && target >= nums[start]) { + end = mid - 1; } else { - left = mid + 1; + start = mid + 1; } - } else { - if (key > arr[mid] && key < arr[right]) { - left = mid + 1; + } + + if (nums[mid] <= nums[end]) { + if (target > nums[mid] && target <= nums[end]) { + start = mid + 1; } else { - right = mid - 1; + end = mid - 1; } } } From 99b246101eac2376ebdc991c690e1eca35987dd6 Mon Sep 17 00:00:00 2001 From: Thangaraj A Date: Fri, 27 Mar 2020 12:47:48 +0530 Subject: [PATCH 29/51] Adding more problems --- .../SearchElementInSortedAndRotatedArray.java | 50 +++++++- .../SerializeAndDeserialize.java | 119 +++++++++--------- src/geeksforgeeks/SetBitCount.java | 2 +- src/geeksforgeeks/ShuffleArray.java | 8 +- src/geeksforgeeks/SimilarExperssions.java | 56 --------- src/geeksforgeeks/SimilarExpressions.java | 55 ++++++++ src/geeksforgeeks/SlidingWindow.java | 66 +++++++--- src/geeksforgeeks/SnakeAndLadder.java | 91 +++++++------- 8 files changed, 268 insertions(+), 179 deletions(-) delete mode 100644 src/geeksforgeeks/SimilarExperssions.java create mode 100644 src/geeksforgeeks/SimilarExpressions.java diff --git a/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java b/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java index ac8ee6e..45fc25d 100644 --- a/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java +++ b/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java @@ -1,16 +1,22 @@ package geeksforgeeks; -/*https://leetcode.com/problems/search-in-rotated-sorted-array/*/ +/*https://leetcode.com/problems/search-in-rotated-sorted-array/ +https://leetcode.com/problems/search-in-rotated-sorted-array-ii/ + */ public class SearchElementInSortedAndRotatedArray { public static void main(String[] args) { int[] arr = { 4, 5, 6, 7, 0, 1, 2 }; + SearchElementInSortedAndRotatedArray search = new SearchElementInSortedAndRotatedArray(); - System.out.println(search.searchInArray(arr, 0)); + System.out.println(search.searchI(arr, 0)); + + int[] nums = { 2, 5, 6, 0, 0, 1, 2 }; + System.out.println(search.searchII(nums, 2)); } - // 4, 5, 6, 7, 0, 1, 2 - int searchInArray(int nums[], int target) { + // 4, 5, 0, 1, 2, 3 + int searchI(int[] nums, int target) { int start = 0; int end = nums.length - 1; @@ -39,4 +45,40 @@ int searchInArray(int nums[], int target) { return -1; } + //[2,5,6,0,0,1,2] + // 0 + //duplicates, we know nums[mid] != target, so nums[start] != target //based on current information, + // we can only move left pointer to skip one cell //thus in the worst case, we would have target: 2, and array like 11111111, + // then //the running time would be O(n) + public boolean searchII(int[] nums, int target) { + + int start = 0; + int end = nums.length - 1; + + while (start <= end) { + int mid = (start + end) / 2; + if (nums[mid] == target) { + return true; + } + + // the only difference from the first one, tricky case, just update start and end + if ((nums[start] == nums[mid]) && (nums[end] == nums[mid])) { + ++start; + --end; + } else if (nums[start] <= nums[mid]) { + if ((nums[start] <= target) && (nums[mid] > target)) { + end = mid - 1; + } else { + start = mid + 1; + } + } else { + if ((nums[mid] < target) && (nums[end] >= target)) { + start = mid + 1; + } else { + end = mid - 1; + } + } + } + return false; + } } diff --git a/src/geeksforgeeks/SerializeAndDeserialize.java b/src/geeksforgeeks/SerializeAndDeserialize.java index 336a088..c982e89 100644 --- a/src/geeksforgeeks/SerializeAndDeserialize.java +++ b/src/geeksforgeeks/SerializeAndDeserialize.java @@ -17,67 +17,64 @@ public class SerializeAndDeserialize { - private static final String NULL_SYMBOL = "X"; - private static final String DELIMITER = ","; - - public String serialize(TreeNode root) { - - if (root == null) { - return NULL_SYMBOL + DELIMITER; - } - - String leftSerialized = serialize(root.left); - String rightSerialized = serialize(root.right); - - return root.val + DELIMITER + leftSerialized + rightSerialized; - } - - public TreeNode deserialize(String data) { - Queue nodesLeftToMaterialize = new LinkedList<>(); - nodesLeftToMaterialize.addAll(Arrays.asList(data.split(DELIMITER))); - return deserializeHelper(nodesLeftToMaterialize); - } - - public TreeNode deserializeHelper(Queue nodesLeftToMaterialize) { - - String valueForNode = nodesLeftToMaterialize.poll(); - - if (valueForNode.equals(NULL_SYMBOL)) { - return null; - } - - TreeNode newNode = new TreeNode(Integer.valueOf(valueForNode)); - newNode.left = deserializeHelper(nodesLeftToMaterialize); - newNode.right = deserializeHelper(nodesLeftToMaterialize); - - return newNode; - } - - public static void main(String[] args) { - TreeNode root = new TreeNode(1); - root.left = new TreeNode(2); - root.right = new TreeNode(3); - root.left.right = new TreeNode(4); - root.right.left = new TreeNode(5); - root.right.right = new TreeNode(6); - root.right.left.left = new TreeNode(7); - root.right.left.right = new TreeNode(8); - SerializeAndDeserialize sede = new SerializeAndDeserialize(); - String serialize = sede.serialize(root); - System.out.println(serialize); - TreeNode deserialze = sede.deserialize(serialize); - sede.printTree(deserialze); - } - - public void printTree(TreeNode node) { - if (node == null) { - System.out.print("X,"); - return; - } - System.out.print(node.val + ","); - printTree(node.left); - printTree(node.right); - } + private static final String NULL_SYMBOL = "X"; + private static final String DELIMITER = ","; + + public String serialize(TreeNode root) { + + if (root == null) { + return NULL_SYMBOL + DELIMITER; + } + + String leftSerialized = serialize(root.left); + String rightSerialized = serialize(root.right); + + return root.val + DELIMITER + leftSerialized + rightSerialized; + } + + public TreeNode deserialize(String data) { + Queue nodesLeftToMaterialize = new LinkedList<>(); + nodesLeftToMaterialize.addAll(Arrays.asList(data.split(DELIMITER))); + return deserializeHelper(nodesLeftToMaterialize); + } + + public TreeNode deserializeHelper(Queue nodesLeftToMaterialize) { + + String valueForNode = nodesLeftToMaterialize.poll(); + + if (valueForNode.equals(NULL_SYMBOL)) { + return null; + } + + TreeNode newNode = new TreeNode(Integer.valueOf(valueForNode)); + newNode.left = deserializeHelper(nodesLeftToMaterialize); + newNode.right = deserializeHelper(nodesLeftToMaterialize); + + return newNode; + } + + public static void main(String[] args) { + TreeNode root = new TreeNode(1); + root.left = new TreeNode(2); + root.right = new TreeNode(3); + root.right.left = new TreeNode(4); + root.right.right = new TreeNode(5); + SerializeAndDeserialize sede = new SerializeAndDeserialize(); + String serialize = sede.serialize(root); + System.out.println(serialize); + TreeNode deserialze = sede.deserialize(serialize); + sede.printTree(deserialze); + } + + public void printTree(TreeNode node) { + if (node == null) { + System.out.print("X,"); + return; + } + System.out.print(node.val + ","); + printTree(node.left); + printTree(node.right); + } } diff --git a/src/geeksforgeeks/SetBitCount.java b/src/geeksforgeeks/SetBitCount.java index 2e056d3..47777b4 100644 --- a/src/geeksforgeeks/SetBitCount.java +++ b/src/geeksforgeeks/SetBitCount.java @@ -16,6 +16,6 @@ public int hammingWeight(int n) { } public static void main(String[] args) { - + int input = 00000000000000000000000000001011; } } diff --git a/src/geeksforgeeks/ShuffleArray.java b/src/geeksforgeeks/ShuffleArray.java index e052c5d..409995b 100644 --- a/src/geeksforgeeks/ShuffleArray.java +++ b/src/geeksforgeeks/ShuffleArray.java @@ -1,8 +1,13 @@ package geeksforgeeks; +import java.util.Arrays; import java.util.Random; +/** + * https://leetcode.com/problems/shuffle-an-array/ + */ public class ShuffleArray { + private int[] nums; private Random random; @@ -42,6 +47,7 @@ private void swap(int[] a, int i, int j) { public static void main(String[] args) { int[] arr = { 1, 2, 3 }; ShuffleArray sa = new ShuffleArray(arr); - sa.shuffle(); + System.out.println("After shuffling :" + Arrays.toString(sa.shuffle())); + System.out.println("Reset : " + Arrays.toString(sa.reset())); } } \ No newline at end of file diff --git a/src/geeksforgeeks/SimilarExperssions.java b/src/geeksforgeeks/SimilarExperssions.java deleted file mode 100644 index 37456b9..0000000 --- a/src/geeksforgeeks/SimilarExperssions.java +++ /dev/null @@ -1,56 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/check-two-expressions-brackets/ - * - */ -//unresolved -public class SimilarExperssions { - - public static void main(String[] args) { - - System.out.println('+' * '-'); - - String query = "-(a+b+c)"; - String response = "-a-b-c"; - - checkExpression(query.toCharArray(), response.toCharArray()); - } - - private static void checkExpression(char[] query, char[] response) { - - char symbol = 0; - int startIndex = 0; - int endIndex = 0; - for (int i = 0; i < query.length; i++) { - if (query[i] == '(') { - symbol = query[i - 1]; - startIndex = i + 1; - } else if (query[i] == ')') { - endIndex = i - 1; - solve(symbol, startIndex, endIndex, query); - - } - } - } - - private static void solve(char symbol, int startIndex, int endIndex, char[] query) { - - for (int i = startIndex; i <= endIndex; i++) { - char temp = 0; - if (query[startIndex] == '-') { - temp = '-' * '+'; - query[i] = temp; - } else if (symbol == '+') { - temp = '-'; - query[i] = temp; - } else if (Character.isLetter(query[startIndex])) { - if (startIndex == i) { - query[startIndex - 1] = temp; - } - System.out.print(query[startIndex]); - } - System.out.print(temp); - } - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/SimilarExpressions.java b/src/geeksforgeeks/SimilarExpressions.java new file mode 100644 index 0000000..5adab24 --- /dev/null +++ b/src/geeksforgeeks/SimilarExpressions.java @@ -0,0 +1,55 @@ +package geeksforgeeks; + +/** + * https://www.geeksforgeeks.org/check-two-expressions-brackets/ + */ +//unresolved +public class SimilarExpressions { + + public static void main(String[] args) { + + System.out.println('+' * '-'); + + String query = "-(a+b+c)"; + String response = "-a-b-c"; + + checkExpression(query.toCharArray(), response.toCharArray()); + } + + private static void checkExpression(char[] query, char[] response) { + + char symbol = 0; + int startIndex = 0; + int endIndex = 0; + for (int i = 0; i < query.length; i++) { + if (query[i] == '(') { + symbol = query[i - 1]; + startIndex = i + 1; + } else if (query[i] == ')') { + endIndex = i - 1; + solve(symbol, startIndex, endIndex, query); + + } + } + } + + private static void solve(char symbol, int startIndex, int endIndex, char[] query) { + + for (int i = startIndex; i <= endIndex; i++) { + char temp = 0; + if (query[startIndex] == '-') { + temp = '-' * '+'; + query[i] = temp; + } else if (symbol == '+') { + temp = '-'; + query[i] = temp; + } else if (Character.isLetter(query[startIndex])) { + if (startIndex == i) { + query[startIndex - 1] = temp; + } + System.out.print(query[startIndex]); + } + System.out.print(temp); + } + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/SlidingWindow.java b/src/geeksforgeeks/SlidingWindow.java index ace4668..4e11f6a 100644 --- a/src/geeksforgeeks/SlidingWindow.java +++ b/src/geeksforgeeks/SlidingWindow.java @@ -3,35 +3,73 @@ import java.util.Deque; import java.util.LinkedList; import java.util.*; + +/** + * https://leetcode.com/problems/sliding-window-maximum/ + */ public class SlidingWindow { public static void main(String[] args) { - int arr[] = {8, 5, 10, 7, 9, 4, 15, 12, 90, 13}; + int arr[] = { 8, 5, 10, 7, 9, 4, 15, 12, 90, 13 }; int k = 3; maxSlidingWindow(arr, k); } public static int[] maxSlidingWindow(int[] nums, int k) { - if(nums.length==0)return new int[0]; - List result= new ArrayList<>(); - - Deque queue= new ArrayDeque<>(); - // queue.offer(nums[0]); - for(int i=0;i list = new ArrayList<>(); + Deque deque = new ArrayDeque<>(); + int i = 0; + + while (i < k) { + + while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) { + deque.removeLast(); + } + deque.addLast(i); + i++; + } + + for (; i < nums.length; i++) { + + list.add(nums[deque.peekFirst()]); + + if (!deque.isEmpty() && deque.peekFirst() <= i - k) { + deque.removeFirst(); + } + + while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) + deque.removeLast(); + + deque.addLast(i); + } + list.add(nums[deque.peekFirst()]); + + return list.stream().mapToInt(Integer::new).toArray(); + } + + void maxSlidingVicky(int[] nums, int k) { + List result = new ArrayList<>(); + Deque queue = new ArrayDeque<>(); + for (int i = 0; i < nums.length; i++) { + while (!queue.isEmpty() && queue.peek() < i - k + 1) { queue.poll(); } - while(!queue.isEmpty() && nums[queue.peekLast()]=k-1){ + + if (i >= k - 1) { result.add(nums[queue.peekFirst()]); } } - //int[] res= new int[result.size()]; - return result.stream().mapToInt(Integer::intValue).toArray(); } } \ No newline at end of file diff --git a/src/geeksforgeeks/SnakeAndLadder.java b/src/geeksforgeeks/SnakeAndLadder.java index 599dc0e..bced3bc 100644 --- a/src/geeksforgeeks/SnakeAndLadder.java +++ b/src/geeksforgeeks/SnakeAndLadder.java @@ -13,55 +13,62 @@ static class QEntry { int noOfMoves; } - int getMinDiceThrows(int[][] board, int n) { - //int n = board.length; - Queue queue = new LinkedList<>(); - queue.offer(1); - boolean[] visited = new boolean[n * n + 1]; - for (int move = 0; !queue.isEmpty(); move++) { - for (int size = queue.size(); size > 0; size--) { - int num = queue.poll(); - if (visited[num]) continue; - visited[num] = true; - if (num == n * n) return move; - for (int i = 1; i <= 6 && num + i <= n * n; i++) { - int next = num + i; - int value = getBoardValue(board, next); - if (value > 0) next = value; - if (!visited[next]) queue.offer(next); + static int getMinDiceThrows(int board[], int n) { + Queue queue = new LinkedList<>(); + QEntry qEntry = new QEntry(); + qEntry.vertex = 0; + qEntry.noOfMoves = 0; + + board[0] = -21; + queue.add(qEntry); + + while (!queue.isEmpty()) { + qEntry = queue.remove(); + int v = qEntry.vertex; + + System.out.println(v); + + if (v == n - 1) { + break; + } + + for (int j = v + 1; j <= (v + 6) && j < n; j++) { + if (board[j] != -21) { + QEntry entry = new QEntry(); + entry.noOfMoves = (qEntry.noOfMoves + 1); + + if (board[j] != -1) { + entry.vertex = board[j]; + } else { + entry.vertex = j; + } + queue.add(entry); + board[j] = -21; } } } - return -1; + return qEntry.noOfMoves; } - private int getBoardValue(int[][] board, int num) { - int n = board.length; - int r = (num - 1) / n; - int x = n - 1 - r; - int y = r % 2 == 0 ? num - 1 - r * n : n + r * n - num; - return board[x][y]; - } + public static void main(String[] args) { - // public static void main(String[] args) { + int N = 30; + int moves[] = new int[N]; + for (int i = 0; i < N; i++) + moves[i] = -1; - // int N = 30; - // int moves[] = new int[N]; - // for (int i = 0; i < N; i++) - // moves[i] = -1; + // Ladders + moves[2] = 21; + moves[4] = 7; + moves[10] = 25; + moves[19] = 28; - // // Ladders - // moves[2] = 21; - // moves[4] = 7; - // moves[10] = 25; - // moves[19] = 28; + // Snakes + moves[3] = 1; + moves[23] = 8; + moves[16] = 3; + moves[18] = 6; - // // Snakes - // moves[3] = 1; - // moves[23] = 8; - // moves[16] = 3; - // moves[18] = 6; - - // System.out.println("Min Dice throws required is " + getMinDiceThrows(moves, N)); - // } + System.out.println("Min Dice throws required is " + getMinDiceThrows(moves, N)); + } } \ No newline at end of file From 45ea53ad2ae725b2e7d19a1ba83566b085c646ee Mon Sep 17 00:00:00 2001 From: vignesh Date: Sat, 18 Apr 2020 18:59:28 +0530 Subject: [PATCH 30/51] new and updated old problems --- src/geeksforgeeks/CombinationIterator.java | 44 ++++++ src/geeksforgeeks/CountAndSay.java | 32 +++++ .../CountDistinctKSubString.java | 2 +- .../CountNumbersLessThanSelf.java | 51 +++---- src/geeksforgeeks/DecodeString.java | 41 ++++++ src/geeksforgeeks/DesignTicTacToe.java | 60 ++++++++ src/geeksforgeeks/EvaluvateRPN.java | 44 ++++++ src/geeksforgeeks/GroupAnagrams.java | 26 ++++ src/geeksforgeeks/HitCounter.java | 24 ++++ src/geeksforgeeks/InMemeoryFIleSystem.java | 131 ++++++++++++++++++ .../InorderSuccessorPredecessor.java | 47 +++++++ src/geeksforgeeks/JumpsToReachEnd.java | 23 +++ src/geeksforgeeks/KmostFrequentLetters.java | 40 ++++++ src/geeksforgeeks/MaxProductString.java | 45 ++++++ src/geeksforgeeks/MaxSoldiers.java | 46 ++++++ src/geeksforgeeks/MaximumDifference.java | 14 +- ...array.java => MaximumProductSubarray.java} | 15 +- .../MaximumUnsortedSubarray.java | 14 +- .../MedianOfTwoSortedArrays.java | 54 ++++++++ src/geeksforgeeks/MeetingRoomsII.java | 20 +-- src/geeksforgeeks/MinStepsToConvertXtoY.java | 37 +++++ .../MinimumDistanceBetweenTwoNumbers.java | 4 +- src/geeksforgeeks/MinimumPathSum.java | 40 ++++++ src/geeksforgeeks/MinimumSwapSortArray.java | 20 ++- src/geeksforgeeks/MinimumWindowSubstring.java | 66 ++++----- src/geeksforgeeks/MirrorBinaryTree.java | 4 +- src/geeksforgeeks/NextGreaterNumber.java | 4 +- src/geeksforgeeks/NextLargestList.java | 62 +++++---- src/geeksforgeeks/Node.java | 2 +- src/geeksforgeeks/NonDecreasingArray.java | 4 +- src/geeksforgeeks/PalindromePartion.java | 1 + src/geeksforgeeks/PascalsTriangle.java | 29 ++++ src/geeksforgeeks/Pattern132.java | 15 +- src/geeksforgeeks/PerfectSquare.java | 33 +++++ src/geeksforgeeks/PlusOne.java | 28 ++++ src/geeksforgeeks/Pow.java | 13 +- src/geeksforgeeks/PreOrderInOrderTree.java | 42 +++--- src/geeksforgeeks/PrintParenthesis.java | 46 +++--- src/geeksforgeeks/QueensAttackKing.java | 13 +- src/geeksforgeeks/RaceCarMinSteps.java | 2 + src/geeksforgeeks/RemoveKDigits.java | 51 ++++--- src/geeksforgeeks/ReorderLogs.java | 2 +- src/geeksforgeeks/ReorganiseString.java | 49 +++++++ src/geeksforgeeks/RomanToInteger.java | 34 +++++ .../SearchAnElementInMatrix.java | 10 +- .../SearchElementInSortedAndRotatedArray.java | 62 ++++++--- .../SerializeDeserializeBST.java | 61 ++++++++ src/geeksforgeeks/ShuffleArray.java | 30 ++++ src/geeksforgeeks/SlidingWindow.java | 45 +++--- src/geeksforgeeks/SnakeAndLadder.java | 88 ++++++------ src/geeksforgeeks/SortStack.java | 2 + src/geeksforgeeks/SortedSquares.java | 28 ++++ src/geeksforgeeks/SpiralMatrix.java | 68 +++++---- src/geeksforgeeks/SplitLinkedList.java | 74 +++------- src/geeksforgeeks/StockBuySellManyTimes.java | 52 +------ src/geeksforgeeks/StringIterator.java | 37 +++++ src/geeksforgeeks/SwapRecoverBST.java | 12 +- src/geeksforgeeks/TimeMap.java | 43 ++++++ src/geeksforgeeks/TopKFrequentElement.java | 33 +++++ src/geeksforgeeks/TrailingZeroes.java | 1 - src/geeksforgeeks/TreasureIslandII.java | 10 +- src/geeksforgeeks/Twitter.java | 4 +- src/geeksforgeeks/TwoSumClosestToZero.java | 8 +- .../UnSortedContiguousSubArray.java | 40 ++++++ src/geeksforgeeks/UniquePath.java | 42 +++--- src/geeksforgeeks/ValidIpAddresses.java | 39 ++++++ src/geeksforgeeks/ValidSuduko.java | 21 +++ src/geeksforgeeks/VulgarDecimal.java | 88 +++++------- src/geeksforgeeks/WordLadder.java | 43 ++++++ 69 files changed, 1811 insertions(+), 504 deletions(-) create mode 100644 src/geeksforgeeks/CombinationIterator.java create mode 100644 src/geeksforgeeks/CountAndSay.java create mode 100644 src/geeksforgeeks/DecodeString.java create mode 100644 src/geeksforgeeks/DesignTicTacToe.java create mode 100644 src/geeksforgeeks/EvaluvateRPN.java create mode 100644 src/geeksforgeeks/GroupAnagrams.java create mode 100644 src/geeksforgeeks/HitCounter.java create mode 100644 src/geeksforgeeks/InMemeoryFIleSystem.java create mode 100644 src/geeksforgeeks/JumpsToReachEnd.java create mode 100644 src/geeksforgeeks/KmostFrequentLetters.java create mode 100644 src/geeksforgeeks/MaxProductString.java create mode 100644 src/geeksforgeeks/MaxSoldiers.java rename src/geeksforgeeks/{MaximumSubarray.java => MaximumProductSubarray.java} (69%) create mode 100644 src/geeksforgeeks/MedianOfTwoSortedArrays.java create mode 100644 src/geeksforgeeks/MinStepsToConvertXtoY.java create mode 100644 src/geeksforgeeks/MinimumPathSum.java create mode 100644 src/geeksforgeeks/PerfectSquare.java create mode 100644 src/geeksforgeeks/PlusOne.java create mode 100644 src/geeksforgeeks/ReorganiseString.java create mode 100644 src/geeksforgeeks/RomanToInteger.java create mode 100644 src/geeksforgeeks/SerializeDeserializeBST.java create mode 100644 src/geeksforgeeks/ShuffleArray.java create mode 100644 src/geeksforgeeks/SortedSquares.java create mode 100644 src/geeksforgeeks/StringIterator.java create mode 100644 src/geeksforgeeks/TimeMap.java create mode 100644 src/geeksforgeeks/TopKFrequentElement.java create mode 100644 src/geeksforgeeks/UnSortedContiguousSubArray.java create mode 100644 src/geeksforgeeks/ValidIpAddresses.java create mode 100644 src/geeksforgeeks/ValidSuduko.java create mode 100644 src/geeksforgeeks/WordLadder.java diff --git a/src/geeksforgeeks/CombinationIterator.java b/src/geeksforgeeks/CombinationIterator.java new file mode 100644 index 0000000..05a9095 --- /dev/null +++ b/src/geeksforgeeks/CombinationIterator.java @@ -0,0 +1,44 @@ +package geeksforgeeks; + +// CombinationIterator iterator = new CombinationIterator("abc", 2); // creates the iterator. + +// iterator.next(); // returns "ab" +// iterator.hasNext(); // returns true +// iterator.next(); // returns "ac" +// iterator.hasNext(); // returns true +// iterator.next(); // returns "bc" +// iterator.hasNext(); // returns false +public class CombinationIterator { + Deque deque; + boolean[] visited; + public CombinationIterator(String characters, int combinationLength) { + deque= new ArrayDeque<>(); + visited= new boolean[characters.length()]; + generateCombinations(characters,deque, new StringBuilder(), combinationLength, 0, visited); + } + + public String next() { + if(hasNext()) return deque.poll(); + + return ""; + } + + public boolean hasNext() { + return !deque.isEmpty(); + } + + public void generateCombinations(String characters, Deque deque,StringBuilder sb, int limit, int start, boolean[] visited){ + + if(sb.length()==limit){ + deque.offer(new String(sb.toString())); + return; + } + + for(int i=start; i countSmaller(int[] nums) { - if(nums.length==0) return new ArrayList<>(); - - Integer[] result= new Integer[nums.length]; - Node root=null; - for(int i=nums.length-1;i>=0;i--){ // build tree from end so that end is root and has sum 0 - root=buildBSTHelper(nums[i],root,result,i,0); + if (nums.length == 0) + return new ArrayList<>(); + + Integer[] result = new Integer[nums.length]; + Node root = null; + for (int i = nums.length - 1; i >= 0; i--) { // build tree from end so that end is root and has sum 0 + root = buildBSTHelper(nums[i], root, result, i, 0); } return Arrays.asList(result); } - - public Node buildBSTHelper(int val, Node root, Integer[] result, int index, int sum){ - if(root==null){ - root= new Node(val,0); - result[index]=sum; - } - else if(root.val==val){ + + public Node buildBSTHelper(int val, Node root, Integer[] result, int index, int sum) { + if (root == null) { + root = new Node(val, 0); + result[index] = sum; + } else if (root.val == val) { root.dup++; - result[index]=sum+root.sum; - } - else if(root.val>val){ + result[index] = sum + root.sum; + } else if (root.val > val) { root.sum++; - root.left=buildBSTHelper(val,root.left,result,index,sum); - }else{ - root.right=buildBSTHelper(val,root.right,result,index,root.sum+root.dup+sum); + root.left = buildBSTHelper(val, root.left, result, index, sum); + } else { + root.right = buildBSTHelper(val, root.right, result, index, root.sum + root.dup + sum); } return root; } - - private class Node{ + + private class Node { int val; int sum; Node right; Node left; - int dup=1; - public Node(int val, int sum){ - this.val=val; - this.sum=sum; + int dup = 1; + + public Node(int val, int sum) { + this.val = val; + this.sum = sum; } } } \ No newline at end of file diff --git a/src/geeksforgeeks/DecodeString.java b/src/geeksforgeeks/DecodeString.java new file mode 100644 index 0000000..96ec950 --- /dev/null +++ b/src/geeksforgeeks/DecodeString.java @@ -0,0 +1,41 @@ +package geeksforgeeks; + +// s = "3[a2[c]]", return "accaccacc". +// s = "2[abc]3[cd]ef", return "abcabccdcdcdef". +public class DecodeString { + public String decodeString(String s) { + if (s == null) + return ""; + + Deque count = new ArrayDeque<>(); + Deque result = new ArrayDeque<>(); + int start = 0; + StringBuilder tempRes = new StringBuilder(); + while (start < s.length()) { + if (Character.isDigit(s.charAt(start))) { + int num = 0; + while (Character.isDigit(s.charAt(start))) { + num = num * 10 + s.charAt(start) - '0'; + start++; + } + count.push(num); + } else if (s.charAt(start) == '[') { + result.push(tempRes.toString()); + tempRes = new StringBuilder(); + start++; + } else if (s.charAt(start) == ']') { + StringBuilder sb = new StringBuilder(result.pop()); + int tempCount = count.pop(); + for (int i = 0; i < tempCount; i++) { + sb.append(tempRes); + } + tempRes = sb; + start++; + } else { + tempRes.append(s.charAt(start++)); + } + } + + return tempRes.toString(); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/DesignTicTacToe.java b/src/geeksforgeeks/DesignTicTacToe.java new file mode 100644 index 0000000..087d06c --- /dev/null +++ b/src/geeksforgeeks/DesignTicTacToe.java @@ -0,0 +1,60 @@ +package geeksforgeeks; + +public class DesignTicTacToe { + private int[] rows; + private int[] cols; + private int diagonal; + private int antiDiagonal; + + /** Initialize your data structure here. */ + public DesignTicTacToe(int n) { + rows = new int[n]; + cols = new int[n]; + } + + /** Player {player} makes a move at ({row}, {col}). + @param row The row of the board. + @param col The column of the board. + @param player The player, can be either 1 or 2. + @return The current winning condition, can be either: + 0: No one wins. + 1: Player 1 wins. + 2: Player 2 wins. */ + public int move(int row, int col, int player) { + int toAdd = player == 1 ? 1 : -1; + // if A player makes a move on 0,0 we are going to increment index posistion of row and col at 0,- + // if B player makes a move on 0,2 we are going to decrement index posistion at row and col at 0,2 + // after that the count of row at 0 will be 0(balanced moves) like wise if a row or col has value n only + // a player can be adjudged a winner + rows[row] += toAdd; + cols[col] += toAdd; + if (row == col) { + diagonal += toAdd; + } + + if (col + row == cols.length - 1) { + antiDiagonal += toAdd; + } + + int size = rows.length; + if (Math.abs(rows[row]) == size || + Math.abs(cols[col]) == size || + Math.abs(diagonal) == size || + Math.abs(antiDiagonal) == size) { + return player; + } + + return 0; + } + + public static void main(String[] args) { + DesignTicTacToe toe=new DesignTicTacToe(3); + toe.move(0, 0, 1); + toe.move(0, 2, 2); + toe.move(2, 2, 1); + toe.move(1, 1, 2); + toe.move(2, 0, 1); + toe.move(1, 0, 2); + toe.move(2, 1, 1); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/EvaluvateRPN.java b/src/geeksforgeeks/EvaluvateRPN.java new file mode 100644 index 0000000..12e760f --- /dev/null +++ b/src/geeksforgeeks/EvaluvateRPN.java @@ -0,0 +1,44 @@ +package geeksforgeeks; + +// Input: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"] +// Output: 22 +// Explanation: +// ((10 * (6 / ((9 + 3) * -11))) + 17) + 5 +// = ((10 * (6 / (12 * -11))) + 17) + 5 +// = ((10 * (6 / -132)) + 17) + 5 +// = ((10 * 0) + 17) + 5 +// = (0 + 17) + 5 +// = 17 + 5 +// = 22 +public class EvaluvateRPN { + public int evalRPN(String[] tokens) { + if(tokens==null && tokens.length==0) return 0; + Deque deque= new ArrayDeque<>(); + for(String i: tokens){ + if(i.length()==1 && "+*-/".contains(i)){ + Integer second= deque.removeFirst(); + Integer first= deque.removeFirst(); + //System.out.println(first +" - "+ second +" "+i); + switch(i){ + case "+": + deque.addFirst(first+second); + break; + case "-": + deque.addFirst(first-second); + break; + case "*": + deque.addFirst(first*second); + break; + case "/": + deque.addFirst(first/second); + break; + + } + }else{ + deque.addFirst(Integer.parseInt(i)); + } + } + + return deque.removeFirst(); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/GroupAnagrams.java b/src/geeksforgeeks/GroupAnagrams.java new file mode 100644 index 0000000..a3d67b3 --- /dev/null +++ b/src/geeksforgeeks/GroupAnagrams.java @@ -0,0 +1,26 @@ +package geeksforgeeks; +public class GroupAnagrams { + public List> groupAnagrams(String[] strs) { + List> result= new ArrayList<>(); + + if(strs==null || strs.length==0) return result; + Map> map= new HashMap<>(); + + for(String s: strs){ + // int[] cache= new int[26]; + // for(char ch: s.toCharArray()){ + // cache[ch-'a']++; + // } + // String hash=Arrays.toString(cache); + char[] te=s.toCharArray(); + Arrays.sort(te); + String hash=new String(te); + + List list= map.getOrDefault(hash, new LinkedList<>()); + list.add(s); + map.put(hash,list); + } + + return new ArrayList(map.values()); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/HitCounter.java b/src/geeksforgeeks/HitCounter.java new file mode 100644 index 0000000..77d6368 --- /dev/null +++ b/src/geeksforgeeks/HitCounter.java @@ -0,0 +1,24 @@ +package geeksforgeeks; +public class HitCounter { + ArrayDeque trac; + /** Initialize your data structure here. */ + private final int FIVE_MINUTES = 300; + public HitCounter() { + trac = new ArrayDeque(); + } + + /** Record a hit. + @param timestamp - The current timestamp (in seconds granularity). */ + public void hit(int timestamp) { + trac.addLast(timestamp); + } + + /** Return the number of hits in the past 5 minutes. + @param timestamp - The current timestamp (in seconds granularity). */ + public int getHits(int timestamp) { + while(trac.size() > 0 && ( int) trac.getFirst() + FIVE_MINUTES <= timestamp) { + trac.removeFirst(); + } return trac.size(); + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/InMemeoryFIleSystem.java b/src/geeksforgeeks/InMemeoryFIleSystem.java new file mode 100644 index 0000000..c39f2de --- /dev/null +++ b/src/geeksforgeeks/InMemeoryFIleSystem.java @@ -0,0 +1,131 @@ +package geeksforgeeks; + +public class FileSystem { + class Dir { + HashMap < String, Dir > dirs = new HashMap < > (); + HashMap < String, String > files = new HashMap < > (); + } + Dir root; + public FileSystem() { + root = new Dir(); + } + public List < String > ls(String path) { + Dir t = root; + List < String > files = new ArrayList < > (); + if (!path.equals("/")) { + String[] d = path.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.dirs.get(d[i]); + } + if (t.files.containsKey(d[d.length - 1])) { + files.add(d[d.length - 1]); + return files; + } else { + t = t.dirs.get(d[d.length - 1]); + } + } + files.addAll(new ArrayList < > (t.dirs.keySet())); + files.addAll(new ArrayList < > (t.files.keySet())); + Collections.sort(files); + return files; + } + + public void mkdir(String path) { + Dir t = root; + String[] d = path.split("/"); + for (int i = 1; i < d.length; i++) { + if (!t.dirs.containsKey(d[i])) + t.dirs.put(d[i], new Dir()); + t = t.dirs.get(d[i]); + } + } + + public void addContentToFile(String filePath, String content) { + Dir t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.dirs.get(d[i]); + } + t.files.put(d[d.length - 1], t.files.getOrDefault(d[d.length - 1], "") + content); + } + + public String readContentFromFile(String filePath) { + Dir t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.dirs.get(d[i]); + } + return t.files.get(d[d.length - 1]); + } +} + +class FileSystem1 { + class File { + boolean isfile = false; + HashMap < String, File > files = new HashMap < > (); + String content = ""; + } + File root; + public FileSystem() { + root = new File(); + } + + public List < String > ls(String path) { + File t = root; + List < String > files = new ArrayList < > (); + if (!path.equals("/")) { + String[] d = path.split("/"); + for (int i = 1; i < d.length; i++) { + t = t.files.get(d[i]); + } + if (t.isfile) { + files.add(d[d.length - 1]); + return files; + } + } + List < String > res_files = new ArrayList < > (t.files.keySet()); + Collections.sort(res_files); + return res_files; + } + + public void mkdir(String path) { + File t = root; + String[] d = path.split("/"); + for (int i = 1; i < d.length; i++) { + if (!t.files.containsKey(d[i])) + t.files.put(d[i], new File()); + t = t.files.get(d[i]); + } + } + + public void addContentToFile(String filePath, String content) { + File t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.files.get(d[i]); + } + if (!t.files.containsKey(d[d.length - 1])) + t.files.put(d[d.length - 1], new File()); + t = t.files.get(d[d.length - 1]); + t.isfile = true; + t.content = t.content + content; + } + + public String readContentFromFile(String filePath) { + File t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.files.get(d[i]); + } + return t.files.get(d[d.length - 1]).content; + } +} + +/** + * Your FileSystem object will be instantiated and called as such: + * FileSystem obj = new FileSystem(); + * List param_1 = obj.ls(path); + * obj.mkdir(path); + * obj.addContentToFile(filePath,content); + * String param_4 = obj.readContentFromFile(filePath); + */ \ No newline at end of file diff --git a/src/geeksforgeeks/InorderSuccessorPredecessor.java b/src/geeksforgeeks/InorderSuccessorPredecessor.java index f7512e3..db0937e 100644 --- a/src/geeksforgeeks/InorderSuccessorPredecessor.java +++ b/src/geeksforgeeks/InorderSuccessorPredecessor.java @@ -62,6 +62,53 @@ public static void main(String args[]) { System.out.println("Inorder Successor of 10 is : " + successor + " and predecessor is : " + predecessor); } + + TreeNode result=null; + public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { + helperFn(root,p); + return result; + } + + public void helperFn(TreeNode root, TreeNode p){ + if(root==null) return; + + if(root.val>p.val){ + // System.out.println("greatre root"+root.val); + result=root; + helperFn(root.left,p); + }else{ + //System.out.println("smaller root"+root.val); + helperFn(root.right,p); + } + + } +} + +private TreeNode findPredecessor(TreeNode root, TreeNode node) { + TreeNode pre = null; + TreeNode cur = root; + while (cur != null) { + if (cur.val < node.val) { + pre = cur; + cur = cur.right; + } else { + cur = cur.left; + } + } + return pre; +} +private TreeNode findSuccessor(TreeNode root, TreeNode node) { + TreeNode succ = null; + TreeNode cur = root; + while (cur != null) { + if (cur.val > node.val) { + succ = cur; + cur = cur.left; + } else { + cur = cur.right; + } + } + return succ; } class TNode { diff --git a/src/geeksforgeeks/JumpsToReachEnd.java b/src/geeksforgeeks/JumpsToReachEnd.java new file mode 100644 index 0000000..643bc89 --- /dev/null +++ b/src/geeksforgeeks/JumpsToReachEnd.java @@ -0,0 +1,23 @@ +package geeksforgeeks; + +import java.util.*; + +public class JumpsToReachEnd { + public static boolean canReachEnd(List maxAdvanceSteps) { + int furthestReachSoFar = 0, lastlndex = maxAdvanceSteps.size() - 1; + + for (int i = 0; i <= furthestReachSoFar && furthestReachSoFar < lastlndex; ++i) { + // for every index store maxsteps it can take and i should be + // less than maxSteps to check if it can move further + // e.x (3, 2, 0, 0, 2, 0,1) when index i is 3 maxStpes is also 3, it cannot move further + furthestReachSoFar = Math.max(furthestReachSoFar, i + maxAdvanceSteps.get(i)); + } + return furthestReachSoFar >= lastlndex; + } + + public static void main(String[] args) { + + List list= Arrays.asList(new Integer[]{3,3,1,0, 2,0,1}); + System.out.println(canReachEnd(list)); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/KmostFrequentLetters.java b/src/geeksforgeeks/KmostFrequentLetters.java new file mode 100644 index 0000000..8286aec --- /dev/null +++ b/src/geeksforgeeks/KmostFrequentLetters.java @@ -0,0 +1,40 @@ +package geeksforgeeks; + +public class KmostFrequentLetters { + public static void main(String[] args) { + int k1 = 2; + String[] keywords1 = { "anacell", "cetracular", "betacellular" }; + String[] reviews1 = { "Anacell provides the best services in the city", "betacellular has awesome services", + "Best services provided by anacell, everyone should use anacell", }; + int k2 = 2; + String[] keywords2 = { "anacell", "betacellular", "cetracular", "deltacellular", "eurocell" }; + String[] reviews2 = { "I love anacell Best services; Best services provided by anacell", + "betacellular has great services", "deltacellular provides much better services than betacellular", + "cetracular is worse than anacell", "Betacellular is better than deltacellular.", }; + System.out.println(solve(k1, keywords1, reviews1)); + System.out.println(solve(k2, keywords2, reviews2)); + } + + private static List solve(int k, String[] keywords, String[] reviews) { + List res = new ArrayList<>(); + Set set = new HashSet<>(Arrays.asList(keywords)); + Map map = new HashMap<>(); + for(String r : reviews) { + String[] strs = r.split("\\W"); + Set added = new HashSet<>(); + for(String s : strs) { + s = s.toLowerCase(); + if(set.contains(s) && !added.contains(s)) { + map.put(s, map.getOrDefault(s, 0) + 1); + added.add(s); + } + } + } + Queue> maxHeap = new PriorityQueue<>((a, b)->a.getValue() == b.getValue() ? a.getKey().compareTo(b.getKey()) : b.getValue() - a.getValue()); + maxHeap.addAll(map.entrySet()); + while(!maxHeap.isEmpty() && k-- > 0) { + res.add(maxHeap.poll().getKey()); + } + return res; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MaxProductString.java b/src/geeksforgeeks/MaxProductString.java new file mode 100644 index 0000000..2306d75 --- /dev/null +++ b/src/geeksforgeeks/MaxProductString.java @@ -0,0 +1,45 @@ +package geeksforgeeks; + +public class MaxProductString { + public int maxProduct(String[] words) { + int[] checker = new int[words.length]; + int max = 0; + // populating the checker array with their respective numbers + for (int i = 0; i < checker.length; i++) { + int num = 0; + for (int j = 0; j < words[i].length(); j++) { + + // a 1->1 + // b 2->10 + // c 4->100 + // ab 3->11 + // ac 5->101 + // abc 7->111 + // az 33554433->10000000000000000000000001 + + num |= 1 << (words[i].charAt(j) - 'a'); + System.out.println(words[i].charAt(j)+"->"+num+ "->"+Integer.toBinaryString(num) ); + } + + checker[i] = num; + } + + for (int i = 0; i < words.length; i++) { + for (int j = i + 1; j < words.length; j++) { + // abcd efgd + // 11110000 -> abcd + // 00011110 -> efgd + // and-ing these two might say if even a single char is present in other + if ((checker[i] & checker[j]) == 0) //checking if the two strings have common character + max = Math.max(max, words[i].length() * words[j].length()); + } + } + System.out.println(max); + return max; + } + + + public static void main(String[] args) { + new MaxProductString().maxProduct(new String[]{"abcw", "baz", "foo", "bar", "xtfn", "abcdef"}); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MaxSoldiers.java b/src/geeksforgeeks/MaxSoldiers.java new file mode 100644 index 0000000..0866e7a --- /dev/null +++ b/src/geeksforgeeks/MaxSoldiers.java @@ -0,0 +1,46 @@ +package geeksforgeeks; + +public class MaxSoldiers { + class Pair{ + int row; + int soldiers; + Pair(int row, int soldiers){ + this.row=row; + this.soldiers=soldiers; + } + } + + public int[] kWeakestRows(int[][] mat, int k) { + int[] result= new int[k]; + PriorityQueue queue= new PriorityQueue<>((a,b)->a.soldiers==b.soldiers?Integer.compare(a.row,b.row):Integer.compare(a.soldiers,b.soldiers)); + int i=0; + int soldiers=0; + for(int []rows: mat){ + int temp= binarySearchUtil(rows, 0, rows.length); + queue.offer(new Pair(i,temp)); + i++; + } + int ind=0; + while(ind maxDiff) { + maxDiff = arr[i] - minElement; + } + if (arr[i] < minElement) { + minElement = arr[i]; + } + } + return maxDiff; + } public static void main(String[] args) { int arr[] = {2, 4, 1, 3, 10, 8, 5}; int n = arr.length; diff --git a/src/geeksforgeeks/MaximumSubarray.java b/src/geeksforgeeks/MaximumProductSubarray.java similarity index 69% rename from src/geeksforgeeks/MaximumSubarray.java rename to src/geeksforgeeks/MaximumProductSubarray.java index 8d7a333..c3832ab 100644 --- a/src/geeksforgeeks/MaximumSubarray.java +++ b/src/geeksforgeeks/MaximumProductSubarray.java @@ -3,7 +3,7 @@ /** * https://www.geeksforgeeks.org/maximum-product-subarray/ */ -public class MaximumSubarray { +public class MaximumProductSubarray { public static int maxProductSubArray(int[] A) { if (A.length == 0) { @@ -24,19 +24,6 @@ public static int maxProductSubArray(int[] A) { return maxsofar; } - public static int maxSumSubArray(int[] nums) { - - int maxSoFar = nums[0]; - int maxEndingHere = nums[0]; - - for (int i = 1; i < nums.length; i++) { - maxEndingHere = Math.max(maxEndingHere + nums[i], nums[i]); - maxSoFar = Math.max(maxSoFar, maxEndingHere); - } - return maxSoFar; - } - - public static void main(String[] args) { int arr[] = {1, -2, -3, 0, 8, 7, -2}; System.out.println("Maximum Sub array product is " + maxSumSubArray(arr)); diff --git a/src/geeksforgeeks/MaximumUnsortedSubarray.java b/src/geeksforgeeks/MaximumUnsortedSubarray.java index 8cc830a..3a12502 100644 --- a/src/geeksforgeeks/MaximumUnsortedSubarray.java +++ b/src/geeksforgeeks/MaximumUnsortedSubarray.java @@ -4,12 +4,13 @@ import java.util.Arrays; import java.util.List; -//https://www.interviewbit.com/problems/maximum-unsorted-subarray/# +//https://leetcode.com/problems/shortest-unsorted-continuous-subarray/ + public class MaximumUnsortedSubarray { - public static ArrayList subarraySort(ArrayList A) { + public static ArrayList subarraySort(final ArrayList A) { - ArrayList list = new ArrayList<>(); + final ArrayList list = new ArrayList<>(); int start = -1; int end = -1; @@ -63,11 +64,12 @@ public static ArrayList subarraySort(ArrayList A) { return list; } - public static void main(String[] args) { + public static void main(final String[] args) { //1, 1, 10, 10, 15, 10, 15, 10,10, 15, 10, 15 - //(1, 3, 2, 4, 5))); + //(1, 3, 2, 4, 5); //4, 15, 4, 4, 15, 18, 20 - List result = subarraySort(new ArrayList<>(Arrays.asList(4, 15, 4, 4, 15, 18, 20))); + //2, 6, 1, 8, 10, 9, 15 + final List result = subarraySort(new ArrayList<>(Arrays.asList(4, 15, 4, 4, 15, 18, 20))); result.stream().forEach(System.out::println); } } diff --git a/src/geeksforgeeks/MedianOfTwoSortedArrays.java b/src/geeksforgeeks/MedianOfTwoSortedArrays.java new file mode 100644 index 0000000..77bce9e --- /dev/null +++ b/src/geeksforgeeks/MedianOfTwoSortedArrays.java @@ -0,0 +1,54 @@ +package geeksforgeeks; + +class MedianOfTwoSortedArrays{ + + public double findMedianSortedArrays(int input1[], int input2[]) { + //if input1 length is greater than switch them so that input1 is smaller than input2. + if (input1.length > input2.length) { + return findMedianSortedArrays(input2, input1); + } + int x = input1.length; + int y = input2.length; + + int low = 0; + int high = x; + while (low <= high) { + int partitionX = (low + high)/2; + int partitionY = (x + y + 1)/2 - partitionX; + + //if partitionX is 0 it means nothing is there on left side. Use -INF for maxLeftX + //if partitionX is length of input then there is nothing on right side. Use +INF for minRightX + int maxLeftX = (partitionX == 0) ? Integer.MIN_VALUE : input1[partitionX - 1]; + int minRightX = (partitionX == x) ? Integer.MAX_VALUE : input1[partitionX]; + + int maxLeftY = (partitionY == 0) ? Integer.MIN_VALUE : input2[partitionY - 1]; + int minRightY = (partitionY == y) ? Integer.MAX_VALUE : input2[partitionY]; + + if (maxLeftX <= minRightY && maxLeftY <= minRightX) { + //We have partitioned array at correct place + // Now get max of left elements and min of right elements to get the median in case of even length combined array size + // or get max of left for odd length combined array size. + if ((x + y) % 2 == 0) { + return ((double)Math.max(maxLeftX, maxLeftY) + Math.min(minRightX, minRightY))/2; + } else { + return (double)Math.max(maxLeftX, maxLeftY); + } + } else if (maxLeftX > minRightY) { //we are too far on right side for partitionX. Go on left side. + high = partitionX - 1; + } else { //we are too far on left side for partitionX. Go on right side. + low = partitionX + 1; + } + } + + //Only we we can come here is if input arrays were not sorted. Throw in that scenario. + throw new IllegalArgumentException(); + } + + public static void main(String[] args) { + int[] x = {1, 3, 8, 9, 15}; + int[] y = {7, 11, 19, 21, 18, 25}; + + MedianOfTwoSortedArrayOfDifferentLength mm = new MedianOfTwoSortedArrayOfDifferentLength(); + mm.findMedianSortedArrays(x, y); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MeetingRoomsII.java b/src/geeksforgeeks/MeetingRoomsII.java index 7998378..eed4a51 100644 --- a/src/geeksforgeeks/MeetingRoomsII.java +++ b/src/geeksforgeeks/MeetingRoomsII.java @@ -6,16 +6,18 @@ public class MeetingRoomsII { * @return: the minimum number of conference rooms required */ public int minMeetingRooms(List intervals) { - if(intervals==null || intervals.size()==0) return -1; - - Collections.sort(intervals,(a,b)->Integer.compare(a.start,b.start)); - PriorityQueue queue= new PriorityQueue<>(); - //Interval max= intervals.get(0); + if (intervals == null || intervals.size() == 0) + return -1; + + Collections.sort(intervals, (a, b) -> Integer.compare(a.start, b.start)); + PriorityQueue queue = new PriorityQueue<>(); + // Interval max= intervals.get(0); queue.offer(intervals.get(0).end); - for(int i=1;i visited = new HashSet<>(1000); + LinkedList queue = new LinkedList(); + + GFG node = new GFG(src, 0); + + queue.offer(node); + visited.add(node); + + while (!queue.isEmpty()) { + GFG temp = queue.poll(); + visited.add(temp); + + if (temp.val == target) { + return temp.steps; + } + + int mul = temp.val * 2; + int sub = temp.val - 1; + + // given constraints + if (mul > 0 && mul < 1000) { + GFG nodeMul = new GFG(mul, temp.steps + 1); + queue.offer(nodeMul); + } + if (sub > 0 && sub < 1000) { + GFG nodeSub = new GFG(sub, temp.steps + 1); + queue.offer(nodeSub); + } + } + return -1; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java b/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java index 38b0d2d..55f03b4 100644 --- a/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java +++ b/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java @@ -36,10 +36,10 @@ int minDist(int arr[], int n, int x, int y) { public static void main(String[] args) { MinimumDistanceBetweenTwoNumbers min = new MinimumDistanceBetweenTwoNumbers(); - int arr[] = {2, 5, 3, 5, 4, 4, 2, 3}; + int arr[] = {3, 5, 4, 2, 6, 5, 6, 6, 5, 4, 8, 3}; int n = arr.length; int x = 3; - int y = 2; + int y = 6; System.out.println("Minimum distance between " + x + " and " + y + " is " + min.minDist(arr, n, x, y)); diff --git a/src/geeksforgeeks/MinimumPathSum.java b/src/geeksforgeeks/MinimumPathSum.java new file mode 100644 index 0000000..58b6da4 --- /dev/null +++ b/src/geeksforgeeks/MinimumPathSum.java @@ -0,0 +1,40 @@ +package geeksforgeeks; + +class MinPathSum { + public int minPathSum(int[][] grid) { + if (grid == null || grid.length == 0) + return 0; + int dp[][] = new int[grid.length][grid[0].length]; + return getMinPathSum(0, 0, grid, dp); + } + + public int getMinPathSum(int i, int j, int[][] grid, int[][] dp) { + if (i == grid.length - 1 && j == grid[0].length - 1) + return grid[i][j]; + else if (i > grid.length - 1 || j > grid[0].length - 1) + return Integer.MAX_VALUE; + else { + if (dp[i][j] != 0) + return dp[i][j]; + dp[i][j] = grid[i][j] + Math.min(getMinPathSum(i + 1, j, grid, dp), getMinPathSum(i, j + 1, grid, dp)); + } + return dp[i][j]; + } + + public int minPathSum1(int[][] grid) { + + for(int i=1;i resMap = new TreeMap<>(); for (; i < N; i++) { - System.out.print(A[i] + " --> " + i + " "); resMap.put(A[i], i); - } + System.out.println("After first loop end"); System.out.println(); + for (Map.Entry entry : resMap.entrySet()) { + System.out.println(entry.getKey() + " --> " + entry.getValue() + ", "); + } + System.out.println("second loop start"); i = 0; for (Map.Entry entry : resMap.entrySet()) { - System.out.print(entry.getKey() + " --> " + i + " "); + //System.out.print(entry.getKey() + " --> " + i + ", "); entry.setValue(i++); } + + System.out.println("second loop end"); + + for (Map.Entry entry : resMap.entrySet()) { + System.out.println(entry.getKey() + " --> " + entry.getValue() + ", "); + } + System.out.println(); int swap = 0; for (i = 0; i < N;) { - System.out.println(A[i] + "--" + resMap.get(A[i]) + "--" + i); + //System.out.println(A[i] + "--" + resMap.get(A[i]) + "--" + i); // check if array position is same as treeMap's index if (resMap.get(A[i]) != i) { int temp = A[i]; diff --git a/src/geeksforgeeks/MinimumWindowSubstring.java b/src/geeksforgeeks/MinimumWindowSubstring.java index 64030c2..2b7a5ae 100644 --- a/src/geeksforgeeks/MinimumWindowSubstring.java +++ b/src/geeksforgeeks/MinimumWindowSubstring.java @@ -6,46 +6,46 @@ class MinimumWindowSubstring { public static String minWindow(String s, String t) { - - if (s.length() == 0 || t.length() == 0) { + if (t.length() > s.length()) return ""; + Map map = new HashMap<>(); + for (char c : t.toCharArray()) { + map.put(c, map.getOrDefault(c, 0) + 1); } - - Map dictT = new HashMap<>(); - for (int i = 0; i < t.length(); i++) { - dictT.put(t.charAt(i), dictT.getOrDefault(t.charAt(i), 0) + 1); - } - - int required = dictT.size(); - int left = 0; - int right = 0; - int formed = 0; - Map windowCounts = new HashMap<>(); - int[] ans = {-1, 0, 0}; - - while (right < s.length()) { - char c = s.charAt(right); - windowCounts.put(c, windowCounts.getOrDefault(c, 0) + 1); - - if (dictT.containsKey(c) && windowCounts.get(c).intValue() == dictT.get(c).intValue()) { - formed++; + int counter = map.size(); + + int begin = 0, end = 0; + int head = 0; + int len = Integer.MAX_VALUE; + + while (end < s.length()) { + char c = s.charAt(end); + if (map.containsKey(c)) { + map.put(c, map.get(c) - 1); + if (map.get(c) == 0) + counter--; } - while (left <= right && formed == required) { - c = s.charAt(left); - if (ans[0] == -1 || right - left + 1 < ans[0]) { - ans[0] = right - left + 1; - ans[1] = left; - ans[2] = right; + end++; + + while (counter == 0) { + char tempc = s.charAt(begin); + if (map.containsKey(tempc)) { + map.put(tempc, map.get(tempc) + 1); + if (map.get(tempc) > 0) { + counter++; + } } - windowCounts.put(c, windowCounts.get(c) - 1); - if (dictT.containsKey(c) && windowCounts.get(c).intValue() < dictT.get(c).intValue()) { - formed--; + if (end - begin < len) { + len = end - begin; + head = begin; } - left++; + begin++; } - right++; + } - return ans[0] == -1 ? "" : s.substring(ans[1], ans[2] + 1); + if (len == Integer.MAX_VALUE) + return ""; + return s.substring(head, head + len); } public static void main(String[] args) { diff --git a/src/geeksforgeeks/MirrorBinaryTree.java b/src/geeksforgeeks/MirrorBinaryTree.java index 4b166ed..6a26b1e 100644 --- a/src/geeksforgeeks/MirrorBinaryTree.java +++ b/src/geeksforgeeks/MirrorBinaryTree.java @@ -27,9 +27,7 @@ static void mirror(Node root) { q.add(root); while (q.size() > 0) { - Node curr = q.peek(); - q.remove(); - + Node curr = q.poll(); Node temp = curr.left; curr.left = curr.right; curr.right = temp; diff --git a/src/geeksforgeeks/NextGreaterNumber.java b/src/geeksforgeeks/NextGreaterNumber.java index 7278dd9..72a613a 100644 --- a/src/geeksforgeeks/NextGreaterNumber.java +++ b/src/geeksforgeeks/NextGreaterNumber.java @@ -38,7 +38,7 @@ public void findNextGreaterNumber(int[] number) { if (i >= 0) // we found the digit breaking the sorted ordering { - // find the next greater digit in the right sub-array from number[i+1 to end] + // find the next smallest digit greater than num[i] in the right sub-array from number[i+1 to end] for (j = number.length - 1; j > i; j--) { if (number[j] > number[i]) { break; @@ -61,7 +61,7 @@ public static void main(String[] args) { // 6983652 // 6982356 // i =3 - + //534976 solution.findNextGreaterNumber(number); System.out.println("Next greater number is: "); diff --git a/src/geeksforgeeks/NextLargestList.java b/src/geeksforgeeks/NextLargestList.java index f8cdcf8..ec23478 100644 --- a/src/geeksforgeeks/NextLargestList.java +++ b/src/geeksforgeeks/NextLargestList.java @@ -1,48 +1,50 @@ package geeksforgeeks; + class NextLargestList { public int[] nextLargerNodes(ListNode head) { - - if(head==null) return new int[0]; - int size=getSize(head); - int[] result= new int[size]; - head=reverse(head); - Stack stack= new Stack<>(); + + if (head == null) + return new int[0]; + int size = getSize(head); + int[] result = new int[size]; + head = reverse(head); + Stack stack = new Stack<>(); stack.push(head.val); - head=head.next; - int i=size-2; - result[size-1]=0; - while(head!=null){ - - while(!stack.isEmpty() && stack.peek()<=head.val){ + head = head.next; + int i = size - 2; + result[size - 1] = 0; + while (head != null) { + + while (!stack.isEmpty() && stack.peek() <= head.val) { stack.pop(); } - result[i]=stack.isEmpty()?0:stack.peek(); + result[i] = stack.isEmpty() ? 0 : stack.peek(); stack.push(head.val); - head=head.next; + head = head.next; i--; } - + return result; } - - public int getSize(ListNode head){ - int size=0; - ListNode root=head; - while(root!=null){ - root=root.next; + + public int getSize(ListNode head) { + int size = 0; + ListNode root = head; + while (root != null) { + root = root.next; size++; } return size; } - - public ListNode reverse(ListNode head){ - ListNode root=head; - ListNode prev=null; - while(root!=null){ - ListNode next=root.next; - root.next=prev; - prev=root; - root=next; + + public ListNode reverse(ListNode head) { + ListNode root = head; + ListNode prev = null; + while (root != null) { + ListNode next = root.next; + root.next = prev; + prev = root; + root = next; } return prev; } diff --git a/src/geeksforgeeks/Node.java b/src/geeksforgeeks/Node.java index 68985c0..29c5774 100644 --- a/src/geeksforgeeks/Node.java +++ b/src/geeksforgeeks/Node.java @@ -1,6 +1,6 @@ package geeksforgeeks; - +//https://www.geeksforgeeks.org/remove-bst-keys-outside-the-given-range/ class RemoveBSTGivenOutsideRange { private static BSTNode removeOutsideRange(BSTNode root, diff --git a/src/geeksforgeeks/NonDecreasingArray.java b/src/geeksforgeeks/NonDecreasingArray.java index b24d1f2..2202f7e 100644 --- a/src/geeksforgeeks/NonDecreasingArray.java +++ b/src/geeksforgeeks/NonDecreasingArray.java @@ -22,8 +22,8 @@ public boolean checkPossibility(int[] nums) { public static void main(String[] args) { // 1,4,2,3 - //3,4,2,3 - int[] nums = {7, 8, 2, 3}; + // 3,4,2,3 + int[] nums = { 7, 8, 2, 3 }; NonDecreasingArray nda = new NonDecreasingArray(); System.out.println(nda.checkPossibility(nums)); } diff --git a/src/geeksforgeeks/PalindromePartion.java b/src/geeksforgeeks/PalindromePartion.java index c23bf2f..3d1f3d9 100644 --- a/src/geeksforgeeks/PalindromePartion.java +++ b/src/geeksforgeeks/PalindromePartion.java @@ -2,6 +2,7 @@ import java.util.*; +//https://leetcode.com/problems/palindrome-partitioning/ class PalindromePartion { public List> partition(String s) { List> result= new ArrayList<>(); diff --git a/src/geeksforgeeks/PascalsTriangle.java b/src/geeksforgeeks/PascalsTriangle.java index 741b065..ed96fa4 100644 --- a/src/geeksforgeeks/PascalsTriangle.java +++ b/src/geeksforgeeks/PascalsTriangle.java @@ -14,4 +14,33 @@ public List> generate(int numRows) { return allrows; } + + public List> generate1(int numRows) { + + if (numRows == 0) + return Collections.emptyList(); + + List> result = new ArrayList<>(); + List first = Arrays.asList(1); + result.add(first); + if (numRows == 1) + return result; + List second = Arrays.asList(1, 1); + result.add(second); + if (numRows == 2) + return result; + + for (int i = 2; i < numRows; i++) { + List temp = new ArrayList<>(); + temp.add(1); + for (int k = 0; k < i - 1; k++) { + int j = k + 1; + temp.add(result.get(i - 1).get(k) + result.get(i - 1).get(j)); + } + temp.add(1); + result.add(temp); + } + + return result; + } } \ No newline at end of file diff --git a/src/geeksforgeeks/Pattern132.java b/src/geeksforgeeks/Pattern132.java index e2815e5..6aa89bd 100644 --- a/src/geeksforgeeks/Pattern132.java +++ b/src/geeksforgeeks/Pattern132.java @@ -1,22 +1,25 @@ package geeksforgeeks; import java.util.Arrays; + /*https://leetcode.com/problems/132-pattern/discuss/94089/Java-solutions-from-O(n3)-to-O(n)-for-%22132%22-pattern-(updated-with-one-pass-slution)*/ public class Pattern132 { - public static boolean find132pattern(int[] arr) { int[] temp = Arrays.copyOf(arr, arr.length); for (int i = 1; i < arr.length; i++) { temp[i] = Math.min(arr[i - 1], temp[i - 1]); } - //{3, 3, 3, 1, 1, 1, 1, 1} + // {3, 3, 3, 1, 1, 1, 1, 1} for (int j = arr.length - 1, top = arr.length; j >= 0; j--) { - if (arr[j] <= temp[j]) continue; - while (top < arr.length && temp[top] <= temp[j]) top++; - if (top < arr.length && arr[j] > temp[top]) return true; + if (arr[j] <= temp[j]) + continue; + while (top < arr.length && temp[top] <= temp[j]) + top++; + if (top < arr.length && arr[j] > temp[top]) + return true; temp[--top] = arr[j]; } @@ -24,7 +27,7 @@ public static boolean find132pattern(int[] arr) { } public static void main(String[] args) { - int[] arr = {3, 4, 1, 2, 9, 6, 7, 8}; + int[] arr = { 3, 4, 1, 2, 9, 6, 7, 8 }; find132pattern(arr); } diff --git a/src/geeksforgeeks/PerfectSquare.java b/src/geeksforgeeks/PerfectSquare.java new file mode 100644 index 0000000..31b77b1 --- /dev/null +++ b/src/geeksforgeeks/PerfectSquare.java @@ -0,0 +1,33 @@ +package geeksforgeeks; + +class PerfectSquare { + public int numSquares(int n) { + Queue q = new LinkedList<>(); + Set visited = new HashSet<>(); + q.offer(0); + visited.add(0); + int depth = 0; + while (!q.isEmpty()) { + int size = q.size(); + depth++; + while (size > 0) { + int removed = q.poll(); + for (int i = 1; i * i <= n; i++) { + int v = removed + i * i; + if (v == n) { + return depth; + } + if (v > n) { + break; + } + if (!visited.contains(v)) { + q.offer(v); + visited.add(v); + } + } + size--; + } + } + return depth; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/PlusOne.java b/src/geeksforgeeks/PlusOne.java new file mode 100644 index 0000000..21cc426 --- /dev/null +++ b/src/geeksforgeeks/PlusOne.java @@ -0,0 +1,28 @@ +package geeksforgeeks; + +class PlusOne { + public static int[] plusOne(int[] digits) { + + StringBuilder sb = new StringBuilder(); + int remainder = 0; + for (int i = digits.length - 1; i >= 0; i--) { + int num = 0; + if (i == digits.length - 1) { + num = digits[i] + 1; + } else { + num = digits[i] + remainder; + } + int count = String.valueOf(num).length(); + if (count > 1) { + sb.append(num % 10); + remainder = num / 10; + } else { + remainder = 0; + sb.append(num); + } + } + if(remainder!=0) + sb.append(remainder); + return sb.reverse().toString().chars().map(i -> i - '0').toArray(); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/Pow.java b/src/geeksforgeeks/Pow.java index 2ce9273..b4e772f 100644 --- a/src/geeksforgeeks/Pow.java +++ b/src/geeksforgeeks/Pow.java @@ -1,10 +1,11 @@ package geeksforgeeks; +// https://leetcode.com/problems/powx-n/ public class Pow { public double myPow(double x, int n) { + if (n < 0) { - isNegative = true; n *= -1; x = 1 / x; } @@ -14,6 +15,7 @@ public double myPow(double x, int n) { return result; } + public double powerCalcUtil(double x, int n) { if (n == 0) return 1; @@ -26,4 +28,13 @@ public double powerCalcUtil(double x, int n) { } } + public double pow1(double x, int n) { + double result = 1.0; + for(int i = n; i != 0; i /= 2, x *= x) { + if( i % 2 != 0 ) { + result *= x; + } + } + return n < 0 ? 1.0 / result : result; + } } \ No newline at end of file diff --git a/src/geeksforgeeks/PreOrderInOrderTree.java b/src/geeksforgeeks/PreOrderInOrderTree.java index 4376269..82d30d7 100644 --- a/src/geeksforgeeks/PreOrderInOrderTree.java +++ b/src/geeksforgeeks/PreOrderInOrderTree.java @@ -2,30 +2,32 @@ class PreOrderInOrderTree { public TreeNode buildTree(int[] preorder, int[] inorder) { - Map map= new HashMap<>(); - List set= new ArrayList<>(); - - for(int i=0;i map = new HashMap<>(); + List set = new ArrayList<>(); + + for (int i = 0; i < inorder.length; i++) { + map.put(inorder[i], i); } - - for(int i=0;i map, List set,int start,int end){ - if(start>end) return null; - if(set.isEmpty()) return null; - int rootval= set.get(0); - set.remove(0); - TreeNode root= new TreeNode(rootval); - int inorderIndex= map.get(rootval); - root.left=buildTreeUtil(map,set,start,inorderIndex-1); - root.right=buildTreeUtil(map,set,inorderIndex+1,end); + + public TreeNode buildTreeUtil(Map map, List set, int start, int end) { + if (start > end) + return null; + if (set.isEmpty()) + return null; + int rootval = set.get(0); + set.remove(0); + TreeNode root = new TreeNode(rootval); + int inorderIndex = map.get(rootval); + root.left = buildTreeUtil(map, set, start, inorderIndex - 1); + root.right = buildTreeUtil(map, set, inorderIndex + 1, end); return root; } } \ No newline at end of file diff --git a/src/geeksforgeeks/PrintParenthesis.java b/src/geeksforgeeks/PrintParenthesis.java index 869d054..481e3fb 100644 --- a/src/geeksforgeeks/PrintParenthesis.java +++ b/src/geeksforgeeks/PrintParenthesis.java @@ -2,34 +2,34 @@ class PrintParenthesis { - static void formParenthesis(char str[], int pos, int n, int open, int close) { + public List generateParenthesis(int n) { + List result = new ArrayList<>(); + if (n == 0) + return result; + + generateUtil(n, new StringBuilder(), 0, 0, result); + + return result; + } + + public void generateUtil(int n, StringBuilder paran, int open, int close, List result) { if (close == n) { - for (int i = 0; i < str.length; i++) - System.out.print(str[i]); - System.out.println(); + result.add(paran.toString()); return; - } else { - if (open > close) { - str[pos] = '}'; - formParenthesis(str, pos + 1, n, open, close + 1); - } - if (open < n) { - str[pos] = '{'; - formParenthesis(str, pos + 1, n, open + 1, close); - } } - } - static void printParenthesis(char str[], int n) { - if (n > 0) { - formParenthesis(str, 0, n, 0, 0); + if (close < open) { + paran.append(")"); + generateUtil(n, paran, open, close + 1, result); + paran.deleteCharAt(paran.length() - 1); + } + if (open < n) { + paran.append("("); + generateUtil(n, paran, open + 1, close, result); + paran.deleteCharAt(paran.length() - 1); + } - return; - } - public static void main(String[] args) { - int n = 3; - char[] str = new char[2 * n]; - printParenthesis(str, n); } + } \ No newline at end of file diff --git a/src/geeksforgeeks/QueensAttackKing.java b/src/geeksforgeeks/QueensAttackKing.java index 9df7da0..70cd145 100644 --- a/src/geeksforgeeks/QueensAttackKing.java +++ b/src/geeksforgeeks/QueensAttackKing.java @@ -1,4 +1,6 @@ package geeksforgeeks; + +import java.util.*; //https://leetcode.com/problems/queens-that-can-attack-the-king/submissions/ class QueensAttackKing { public List> queensAttacktheKing(int[][] queens, int[] king) { @@ -22,9 +24,10 @@ public List> queensAttacktheKing(int[][] queens, int[] king) { public List findQueensPosistions(int[] king, int x, int y, boolean[][] visited){ int newX= x+king[0]; int newY= y+king[1]; - + // going to walk along x,y only not 8 directions at smae time; while(newX<8 && newY<8 && newX>=0 && newY>=0){ - if(visited[newX][newY]) return Arrays.asList(newX,newY); + if(visited[newX][newY]) return Arrays.asList(newX,newY); // returns when first queen is met in + // row or column newX+=x; newY+=y; @@ -32,4 +35,10 @@ public List findQueensPosistions(int[] king, int x, int y, boolean[][] return null; } + + public static void main(String[] args) { + int[][] queens= {{0,1},{1,0},{4,0},{0,4},{3,3},{2,4}}; + int[] king= {0,0}; + new QueensAttackKing().queensAttacktheKing(queens, king); + } } \ No newline at end of file diff --git a/src/geeksforgeeks/RaceCarMinSteps.java b/src/geeksforgeeks/RaceCarMinSteps.java index 1a5f293..0f26001 100644 --- a/src/geeksforgeeks/RaceCarMinSteps.java +++ b/src/geeksforgeeks/RaceCarMinSteps.java @@ -1,4 +1,6 @@ package geeksforgeeks; + +import java.util.*; class RaceCarMinSteps { public int racecar(int target) { Set visited = new HashSet<>(); diff --git a/src/geeksforgeeks/RemoveKDigits.java b/src/geeksforgeeks/RemoveKDigits.java index e9b14c3..f6dfb9c 100644 --- a/src/geeksforgeeks/RemoveKDigits.java +++ b/src/geeksforgeeks/RemoveKDigits.java @@ -8,40 +8,37 @@ public class RemoveKDigits { //1432219 - public static String removeKdigits(String num, int k) { - int len = num.length(); - - if (k == len) - return "0"; - - Stack stack = new Stack<>(); - int i = 0; - while (i < num.length()) { - while (k > 0 && !stack.isEmpty() && stack.peek() > num.charAt(i)) { - stack.pop(); + public static String removeKdigits(String num, int k) { + if(num==null || num.length()==0) return null; + + Deque queue= new ArrayDeque<>(); + for(char c: num.toCharArray()){ + + while(!queue.isEmpty() && queue.getLast()>c-'0' && k>0){ + queue.removeLast(); k--; } - stack.push(num.charAt(i)); - i++; + queue.addLast(c-'0'); } - - // corner case like "1111" - while (k > 0) { - stack.pop(); + + while(k>0){ + queue.removeLast(); k--; } - - StringBuilder sb = new StringBuilder(); - while (!stack.isEmpty()) - sb.append(stack.pop()); - sb.reverse(); - - while (sb.length() > 1 && sb.charAt(0) == '0') - sb.deleteCharAt(0); - return sb.toString(); + + StringBuilder result= new StringBuilder(); + while(!queue.isEmpty()){ + result.append(queue.removeFirst()); + } + + while(result.length()>0 && result.charAt(0)=='0'){ + result.deleteCharAt(0); + } + + return result.length()==0?"0":result.toString(); } public static void main(String[] args) { - System.out.println(removeKdigits("14232191", 3)); + System.out.println(removeKdigits("143221999", 3)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/ReorderLogs.java b/src/geeksforgeeks/ReorderLogs.java index 2140cc1..206c132 100644 --- a/src/geeksforgeeks/ReorderLogs.java +++ b/src/geeksforgeeks/ReorderLogs.java @@ -6,7 +6,7 @@ class ReorderLogs { public static String[] reorderLogFiles(String[] logs) { Arrays.sort(logs, (s1, s2) -> { - String[] split1 = s1.split(" ", 2); + String[] split1 = s1.split(" ", 2); // splits arr in to 2 parts String[] split2 = s2.split(" ", 2); boolean isDigit1 = Character.isDigit(split1[1].charAt(0)); diff --git a/src/geeksforgeeks/ReorganiseString.java b/src/geeksforgeeks/ReorganiseString.java new file mode 100644 index 0000000..6a0fcff --- /dev/null +++ b/src/geeksforgeeks/ReorganiseString.java @@ -0,0 +1,49 @@ +package geeksforgeeks; + +class ReorganiseString{ + public String reorganizeString(String s) { + if(s == null || s.length() < 1) return ""; + + int[] hash = new int[26]; + for(char c : s.toCharArray()) { + hash[c-'a']++; + } + + int max = 0; + int letter = 0; + + for(int i=0; i max) { + max = hash[i]; + letter = i; + } + } + + if(max > (s.length()+1)/2) return ""; + + char[] res = new char[s.length()]; + + int k=0; + while(hash[letter] > 0) { + res[k] = (char)(letter + 'a'); + k += 2; + hash[letter]--; + } + + for(int i=0; i 0) { + if(k >= res.length) k=1; + + res[k] = (char)(i + 'a'); + k += 2; + hash[i] --; + } + } + + return new String(res); + } + + public static void main(String[] args) { + new ReorganiseString().reorganizeString("aabccdeeee"); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/RomanToInteger.java b/src/geeksforgeeks/RomanToInteger.java new file mode 100644 index 0000000..1469c62 --- /dev/null +++ b/src/geeksforgeeks/RomanToInteger.java @@ -0,0 +1,34 @@ +package geeksforgeeks; + +import java.util.*; + +public class RomanToInteger { + + public int romanToInteger(String s) { + Map map = new HashMap(); + + map.put('I', 1); + map.put('V', 5); + map.put('X', 10); + map.put('L', 50); + map.put('C', 100); + map.put('D', 500); + map.put('M', 1000); + + int sum = map.get(s.charAt(s.length() - 1)); + for (int i = s.length() - 2; i >= 0; --i) { + if (map.get(s.charAt(i)) < map.get(s.charAt(i + 1))) { + sum -= map.get(s.charAt(i)); + } else { + sum += map.get(s.charAt(i)); + } + } + return sum; + + } + + public static void main(String[] args) { + new RomanToInteger().romanToInteger("LIX"); + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/SearchAnElementInMatrix.java b/src/geeksforgeeks/SearchAnElementInMatrix.java index 61bd8af..3a37b4f 100644 --- a/src/geeksforgeeks/SearchAnElementInMatrix.java +++ b/src/geeksforgeeks/SearchAnElementInMatrix.java @@ -10,7 +10,8 @@ private static boolean searchII(int[][] mat, int n, int x) { int i = 0; int j = n - 1; // set indexes for top right element - + // we can start from top right corner or bottom left corner, because from + // these points only we have 2 paths one increasing one decreasing while (i < n && j >= 0) { if (mat[i][j] == x) { System.out.print("n Found at " + i + " " + j); @@ -51,9 +52,12 @@ public static boolean searchI(int[][] matrix, int target) { } public static void main(String[] args) { - int[][] mat = {{10, 20, 30, 40}, {15, 25, 35, 45}, {27, 29, 37, 48}, {32, 33, 39, 50}}; + int[][] mat = {{10, 20, 30, 40}, + {15, 25, 35, 45}, + {27, 29, 37, 48}, + {32, 33, 39, 50}}; - int[][] matI = {{1, 3, 5, 7}, + int[][] matI = {{1, 3, 5, 7} , {10, 11, 16, 20}, {23, 30, 34, 50}}; diff --git a/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java b/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java index 64c5714..e3ab4e6 100644 --- a/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java +++ b/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java @@ -12,30 +12,60 @@ public static void main(String[] args) { // 4, 5, 6, 7, 0, 1, 2 int searchInArray(int arr[], int key) { - int left = 0; - int right = arr.length - 1; - - while (left < right) { - - int mid = (left + right) / 2; - if (arr[mid] == key) + int start = 0; + int end = nums.length - 1; + while (start <= end) { + int mid = (start + end) / 2; + if (nums[mid] == target) { return mid; - - if (arr[left] < arr[mid]) { - if (key > arr[left] && key < arr[mid]) { - right = mid - 1; + } + + if (nums[start] <= nums[mid]) { + if (target < nums[mid] && target >= nums[start]) { + end = mid - 1; } else { - left = mid + 1; + start = mid + 1; } - } else { - if (key > arr[mid] && key < arr[right]) { - left = mid + 1; + } + + if (nums[mid] <= nums[end]) { + if (target > nums[mid] && target <= nums[end]) { + start = mid + 1; } else { - right = mid - 1; + end = mid - 1; } } } return -1; } + // with duplicates + public boolean searchII(int[] nums, int target) { + int left = 0, right = nums.length-1, mid; + + while(left<=right) + { + mid = (left + right) >> 1; + if(nums[mid] == target) return true; + + // the only difference from the first one, trickly case, just updat left and right + if ((nums[left] == nums[mid]) && (nums[right] == nums[mid])) { + ++left; + --right; + } + + else if(nums[left] <= nums[mid]) + { + if( (nums[left]<=target) && (nums[mid] > target) ) right = mid-1; + else left = mid + 1; + } + else + { + if((nums[mid] < target) && (nums[right] >= target) ) left = mid+1; + else right = mid-1; + } + } + return false; + } + } diff --git a/src/geeksforgeeks/SerializeDeserializeBST.java b/src/geeksforgeeks/SerializeDeserializeBST.java new file mode 100644 index 0000000..6ca6222 --- /dev/null +++ b/src/geeksforgeeks/SerializeDeserializeBST.java @@ -0,0 +1,61 @@ +package geeksforgeeks; + +// Hi all, I think my solution is pretty straightforward and easy to understand, not that efficient though. And the serialized tree is compact. +// Pre order traversal of BST will output root node first, then left children, then right. + +// root left1 left2 leftX right1 rightX +// If we look at the value of the pre-order traversal we get this: + +// rootValue (rootValue) (>rootValue) +// Because of BST's property: before the |separate line| all the node values are less than root value, all the node values after |separate line| are greater than root value. We will utilize this to build left and right tree. + +class SerializeDeserializeBST{ + private static final String SEP = ","; + private static final String NULL = "null"; + // Encodes a tree to a single string. + public String serialize(TreeNode root) { + StringBuilder sb = new StringBuilder(); + if (root == null) return NULL; + //traverse it recursively if you want to, I am doing it iteratively here + Stack st = new Stack<>(); + st.push(root); + while (!st.empty()) { + root = st.pop(); + sb.append(root.val).append(SEP); + if (root.right != null) st.push(root.right); + if (root.left != null) st.push(root.left); + } + return sb.toString(); + } + + // Decodes your encoded data to tree. + // pre-order traversal + public TreeNode deserialize(String data) { + if (data.equals(NULL)) return null; + String[] strs = data.split(SEP); + Queue q = new LinkedList<>(); + for (String e : strs) { + q.offer(Integer.parseInt(e)); + } + return getNode(q); + } + + // some notes: + // 5 + // 3 6 + // 2 7 + private TreeNode getNode(Queue q) { //q: 5,3,2,6,7 + if (q.isEmpty()) return null; + TreeNode root = new TreeNode(q.poll());//root (5) + Queue samllerQueue = new LinkedList<>(); + while (!q.isEmpty() && q.peek() < root.val) { + samllerQueue.offer(q.poll()); + } + //smallerQueue : 3,2 storing elements smaller than 5 (root) + root.left = getNode(samllerQueue); + //q: 6,7 storing elements bigger than 5 (root) + root.right = getNode(q); + return root; + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/ShuffleArray.java b/src/geeksforgeeks/ShuffleArray.java new file mode 100644 index 0000000..a3dc714 --- /dev/null +++ b/src/geeksforgeeks/ShuffleArray.java @@ -0,0 +1,30 @@ +package geeksforgeeks; + +class ShuffleArray { + + int[] value; + int[] originalVal; + public Solution(int[] nums) { + value= nums; + originalVal=nums.clone(); + } + + /** Resets the array to its original configuration and return it. */ + public int[] reset() { + return originalVal; + } + + /** Returns a random shuffling of the array. */ + public int[] shuffle() { + // int index=value.length-1; + for(int i=value.length-1;i>0;i--){ + int randIndex= (int)Math.floor(new Double(i*Math.random())); + int temp=value[i]; + value[i]=value[randIndex]; + value[randIndex]=temp; + // index--; + } + + return value; + } +} diff --git a/src/geeksforgeeks/SlidingWindow.java b/src/geeksforgeeks/SlidingWindow.java index ace4668..6dfb1f3 100644 --- a/src/geeksforgeeks/SlidingWindow.java +++ b/src/geeksforgeeks/SlidingWindow.java @@ -12,26 +12,29 @@ public static void main(String[] args) { } public static int[] maxSlidingWindow(int[] nums, int k) { - if(nums.length==0)return new int[0]; - List result= new ArrayList<>(); + if(nums.length==0 || k==0) return new int[0]; + int[] result= new int[nums.length-k+1]; + int index=0; + Deque deque= new ArrayDeque<>(); - Deque queue= new ArrayDeque<>(); - // queue.offer(nums[0]); - for(int i=0;i=k-1){ - result.add(nums[queue.peekFirst()]); - } - } - //int[] res= new int[result.size()]; - return result.stream().mapToInt(Integer::intValue).toArray(); - } + for(int i=0;i=k-1){ + result[index++]=nums[deque.peekFirst()]; + } + } + + return result; + } } \ No newline at end of file diff --git a/src/geeksforgeeks/SnakeAndLadder.java b/src/geeksforgeeks/SnakeAndLadder.java index 599dc0e..e9bfa40 100644 --- a/src/geeksforgeeks/SnakeAndLadder.java +++ b/src/geeksforgeeks/SnakeAndLadder.java @@ -1,67 +1,69 @@ package geeksforgeeks; import java.util.Queue; -import java.util.LinkedList; +import java.util.*; /** * https://leetcode.com/problems/snakes-and-ladders/ */ public class SnakeAndLadder { + class BoardCells { + int pos; + int steps; - static class QEntry { - int vertex; - int noOfMoves; + public BoardCells(int pos, int steps) { + this.pos = pos; + this.steps = steps; + } } - int getMinDiceThrows(int[][] board, int n) { - //int n = board.length; - Queue queue = new LinkedList<>(); - queue.offer(1); + private int n; + + public int snakesAndLadders(int[][] board) { + n = board.length; boolean[] visited = new boolean[n * n + 1]; - for (int move = 0; !queue.isEmpty(); move++) { - for (int size = queue.size(); size > 0; size--) { - int num = queue.poll(); - if (visited[num]) continue; - visited[num] = true; - if (num == n * n) return move; - for (int i = 1; i <= 6 && num + i <= n * n; i++) { - int next = num + i; - int value = getBoardValue(board, next); - if (value > 0) next = value; - if (!visited[next]) queue.offer(next); + Queue queue = new LinkedList<>(); + queue.offer(new BoardCells(1, 1)); + visited[1] = true; + + while (!queue.isEmpty()) { + BoardCells cur = queue.poll(); + for (int i = 1; i <= 6; i++) { + int next = cur.pos + i; + int[] pos = numToPos(next); + if (board[pos[0]][pos[1]] > 0) { + next = board[pos[0]][pos[1]]; + } + if (next == n * n) { + return cur.steps; + } + if (!visited[next]) { + queue.offer(new BoardCells(next, cur.steps + 1)); + visited[next] = true; } } + } return -1; } - private int getBoardValue(int[][] board, int num) { - int n = board.length; - int r = (num - 1) / n; - int x = n - 1 - r; - int y = r % 2 == 0 ? num - 1 - r * n : n + r * n - num; - return board[x][y]; + private int[] numToPos(int target) { + int row = (target - 1) / n, col = (target - 1) % n; + int x = n - 1 - row, y = row % 2 == 0 ? col : n - 1 - col; + return new int[] { x, y }; } - // public static void main(String[] args) { - - // int N = 30; - // int moves[] = new int[N]; - // for (int i = 0; i < N; i++) - // moves[i] = -1; + private int posToNum(int[] position) { + int row = (n - 1 - position[0]); + int y = row % 2 == 0 ? position[1] + 1 : n - position[1]; + return row * n + y; + } - // // Ladders - // moves[2] = 21; - // moves[4] = 7; - // moves[10] = 25; - // moves[19] = 28; + public static void main(String[] args) { - // // Snakes - // moves[3] = 1; - // moves[23] = 8; - // moves[16] = 3; - // moves[18] = 6; + int[][] board = { { -1, -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1, -1 }, + { -1, 35, -1, -1, 13, -1 }, { -1, -1, -1, -1, -1, -1 }, { -1, 15, -1, -1, -1, -1 } }; - // System.out.println("Min Dice throws required is " + getMinDiceThrows(moves, N)); - // } + System.out.println("Min Dice throws required is " + new SnakeAndLadder().snakesAndLadders(board)); + } } \ No newline at end of file diff --git a/src/geeksforgeeks/SortStack.java b/src/geeksforgeeks/SortStack.java index 6efe7c2..2534453 100644 --- a/src/geeksforgeeks/SortStack.java +++ b/src/geeksforgeeks/SortStack.java @@ -1,6 +1,8 @@ package geeksforgeeks; class SortStack { + // Input : [34, 3, 31, 98, 92, 23] + // Output : [3, 23, 31, 34, 92, 98] public static Stack sortStack(Stack input) { /* If input is null, no processing needed */ if (input == null) { diff --git a/src/geeksforgeeks/SortedSquares.java b/src/geeksforgeeks/SortedSquares.java new file mode 100644 index 0000000..7af17cc --- /dev/null +++ b/src/geeksforgeeks/SortedSquares.java @@ -0,0 +1,28 @@ +package geeksforgeeks; + +public class SortedSquares { + // Input: [-7,-3,2,3,11] + // Output: [4,9,9,49,121] + public int[] sortedSquares(int[] A) { + if(A==null || A.length==0) return new int[0]; + + int[]result= new int[A.length]; + + int index= A.length-1; + int left=0; + int right=index; + + while(left<=right){ + if(Math.abs(A[left]) spiralOrder(int[][] matrix) { + + List res = new ArrayList(); + + if (matrix.length == 0) { + return res; + } + + int rowBegin = 0; + int rowEnd = matrix.length-1; + int colBegin = 0; + int colEnd = matrix[0].length - 1; + + while (rowBegin <= rowEnd && colBegin <= colEnd) { + // Traverse Right + for (int j = colBegin; j <= colEnd; j ++) { + res.add(matrix[rowBegin][j]); } - rowStart++; - - // Print the last column from the remaining colEnd - for (int i = rowStart; i < colEnd; ++i) { - System.out.print(a[i][rowEnd - 1] + " "); + rowBegin++; + + // Traverse Down + for (int j = rowBegin; j <= rowEnd; j ++) { + res.add(matrix[j][colEnd]); } - rowEnd--; - - // Print the last row from the remaining rowEnd */ - if (rowStart < colEnd) { - for (int i = rowEnd - 1; i >= colStart; --i) { - System.out.print(a[colEnd - 1][i] + " "); + colEnd--; + + if (rowBegin <= rowEnd) { + // Traverse Left + for (int j = colEnd; j >= colBegin; j --) { + res.add(matrix[rowEnd][j]); } - colEnd--; } - - // Print the first column from the remaining colEnd */ - if (colStart < rowEnd) { - for (int i = colEnd - 1; i >= rowStart; --i) { - System.out.print(a[i][colStart] + " "); + rowEnd--; + + if (colBegin <= colEnd) { + // Traver Up + for (int j = rowEnd; j >= rowBegin; j --) { + res.add(matrix[j][colBegin]); } - colStart++; } + colBegin ++; } + + return res; } public static void main(String[] args) { - int R = 4; - int C = 4; + int a[][] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}; - spiralPrint(R, C, a); + spiralOrder(a); } } \ No newline at end of file diff --git a/src/geeksforgeeks/SplitLinkedList.java b/src/geeksforgeeks/SplitLinkedList.java index fb3e4d5..c09c0d4 100644 --- a/src/geeksforgeeks/SplitLinkedList.java +++ b/src/geeksforgeeks/SplitLinkedList.java @@ -2,67 +2,33 @@ //https://leetcode.com/problems/split-linked-list-in-parts/ class SplitLinkedList { - public ListNode[] splitListToParts(ListNode root, int k) { - if (root == null) return null; - if (k == 0) return null; - - if (k == 1) { - ListNode[] node = new ListNode[1]; - node[0] = root; - return node; - } - - ListNode[] node = new ListNode[k]; - int length = getRootLength(root); - - if (k > length) { - ListNode temp = root; - int index = 0; - - while (temp != null) { - ListNode result = temp; - temp = temp.next; - result.next = null; - node[index] = result; - index++; - } - - for (; index < k; index++) { - node[index] = null; - } - return node; - } - - int remainder = length % k; - int quo = length / k; - - for (int i = 0; i < k; i++) { - int value = remainder > 0 ? quo + 1 : quo; - remainder--; - ListNode head = root; - ListNode prev = null; - for (int j = 0; j < value && root != null; j++) { - if (j == value - 1) { - prev = root; - prev.next = null; - } - root = root.next; + public ListNode[] splitListToParts(ListNode root, int k) { + ListNode[] partsOfRoot = new ListNode[k]; + ListNode head = root; + int len = size(root); + int minNoOfElements = len / k; + int extraRoomForElement = len % k; + ListNode prev = null; + for (int i = 0; i < k && head != null; i++, extraRoomForElement--) { + partsOfRoot[i] = head; + for (int j = 0; j < minNoOfElements + (extraRoomForElement > 0 ? 1 : 0); j++) { + prev = head; + head = head.next; } - node[i] = head; + prev.next = null; } + return partsOfRoot; - return node; } - public int getRootLength(ListNode root) { - ListNode temp = root; - int count = 0; - while (temp != null) { - count++; - temp = temp.next; + public int size(ListNode root) { + int len = 0; + while (root != null) { + root = root.next; + len++; } - return count; + return len; } public static void main(String[] args) { diff --git a/src/geeksforgeeks/StockBuySellManyTimes.java b/src/geeksforgeeks/StockBuySellManyTimes.java index c4a4587..d61bc1d 100644 --- a/src/geeksforgeeks/StockBuySellManyTimes.java +++ b/src/geeksforgeeks/StockBuySellManyTimes.java @@ -12,58 +12,20 @@ class Interval { */ // unresolved class StockBuySellManyTimes { - - //200, 180, 260, 310, 40, 535, 695 - void stockBuySell(int price[], int n) { - // Prices must be given for at least two days - if (n == 1) - return; - - int count = 0; - - List result = new ArrayList<>(); - - int i = 0; - while (i < n - 1) { - // Find Local Minima. Note that the limit is (n-2) as we are - // comparing present element to the next element. - while ((i < n - 1) && (price[i + 1] <= price[i])) - i++; - - // If we reached the end, break as no further solution possible - if (i == n - 1) - break; - - Interval e = new Interval(); - e.buy = i++; - // Store the index of minima - - // Find Local Maxima. Note that the limit is (n-1) as we are - // comparing to previous element - while ((i < n) && (price[i] >= price[i - 1])) - i++; - - // Store the index of maxima - e.sell = i - 1; - result.add(e); - - // Increment number of buy/sell - count++; + public int maxProfit(int[] prices) { + int total = 0; + for (int i = 0; i < prices.length - 1; i++) { + if (prices[i + 1] > prices[i]) + total += prices[i + 1] - prices[i]; } - if (count == 0) - System.out.println("There is no day when buying the stock " + "will make profit"); - else - for (int j = 0; j < count; j++) - System.out.println("Buy on day: " + result.get(j).buy + " " + "Sell on day : " + result.get(j).sell); - - return; + return total; } public static void main(String args[]) { StockBuySellManyTimes stock = new StockBuySellManyTimes(); - int price[] = {200, 180, 260, 310, 40, 535, 695}; + int price[] = { 200, 180, 260, 310, 40, 535, 695 }; int n = price.length; stock.stockBuySell(price, n); diff --git a/src/geeksforgeeks/StringIterator.java b/src/geeksforgeeks/StringIterator.java new file mode 100644 index 0000000..4afd362 --- /dev/null +++ b/src/geeksforgeeks/StringIterator.java @@ -0,0 +1,37 @@ +package geeksforgeeks; + +//StringIterator iterator = new StringIterator("L1e2t1C1o1d1e1"); +// iterator.next(); // return 'L' +// iterator.next(); // return 'e' +// iterator.next(); // return 'e' +// iterator.next(); // return 't' +// iterator.next(); // return 'C' +// iterator.next(); // return 'o' +// iterator.next(); // return 'd' +// iterator.hasNext(); // return true +// iterator.next(); // return 'e' +// iterator.hasNext(); // return false +// iterator.next(); // return ' ' +public class StringIterator { + String res; + int ptr = 0, num = 0; + char ch = ' '; + public StringIterator(String s) { + res = s; + } + public char next() { + if (!hasNext()) + return ' '; + if (num == 0) { + ch = res.charAt(ptr++); + while (ptr < res.length() && Character.isDigit(res.charAt(ptr))) { + num = num * 10 + res.charAt(ptr++) - '0'; + } + } + num--; + return ch; + } + public boolean hasNext() { + return ptr != res.length() || num != 0; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/SwapRecoverBST.java b/src/geeksforgeeks/SwapRecoverBST.java index 4de4707..7a34899 100644 --- a/src/geeksforgeeks/SwapRecoverBST.java +++ b/src/geeksforgeeks/SwapRecoverBST.java @@ -24,7 +24,17 @@ private void traverse(TreeNode root) { return; traverse(root.left); - + // Let's assume this is the original in-order traversal sequence of BST: 1 2 3 4 5 + // If 2 and 3 get swapped, it becomes 1 3 2 4 5 and + //there is only one time that you will have prev.val >= root.val + // If 2 and 4 get swapped, it becomes 1 4 3 2 5 and + //there are two times that you will have prev.val >= root.val + + // If during the first time when you find prev.val >= root.val, + //the previous node "prev" MUST be one of two nodes that get swapped. + //However, the current node MAY OR MAY NOT be another node that gets swapped, + //which will depend on whether later during in-order traversal, there is another prev.val >= root.val or not. + // If there is, then the current node "root" during the 2nd time of prev.val >= root.val will be the other node that gets swapped // Start of "do some business", // If first element has not been found, assign it to prevElement (refer to 6 in the example above) if (firstElement == null && prevElement.val >= root.val) { diff --git a/src/geeksforgeeks/TimeMap.java b/src/geeksforgeeks/TimeMap.java new file mode 100644 index 0000000..6a6d3ab --- /dev/null +++ b/src/geeksforgeeks/TimeMap.java @@ -0,0 +1,43 @@ +package geeksforgeeks; + +class TimeMap { + + class Node{ + String val; + int time; + Node next; + public Node(String value, int timestamp){ + val=value; + time=timestamp; + } + } + /** Initialize your data structure here. */ + HashMapmap; + + public TimeMap() { + map=new HashMap<>(); + } + + public void set(String key, String value, int timestamp) { + if(map.containsKey(key)){ + Node node=new Node(value,timestamp); + node.next=map.get(key); + map.put(key,node); + }else{ + Node temp=new Node(value,timestamp); + map.put(key,temp); + } + } + + public String get(String key, int timestamp) { + String vl=""; + if(map.containsKey(key)){ + Node y=map.get(key); + while(y.time>timestamp&&y.next!=null) + y=y.next; + if(y.time<=timestamp) + vl=y.val; + } + return vl; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/TopKFrequentElement.java b/src/geeksforgeeks/TopKFrequentElement.java new file mode 100644 index 0000000..e8882c4 --- /dev/null +++ b/src/geeksforgeeks/TopKFrequentElement.java @@ -0,0 +1,33 @@ +package geeksforgeeks; + +class TopKFrequentElement{ + public List topKFrequent(int[] nums, int k) { + List result = new ArrayList<>(); + + HashMap map = new HashMap<>(); //Key: val, Val: #of freq + for (int num : nums) { + if (map.containsKey(num)) { + map.put(num, map.get(num)+1); + }else { + map.put(num, 1); + } + } + + List[] bucks = new List[nums.length+1]; // index : freq; val: set of key + for (int key : map.keySet()) { + int freq = map.get(key); + if (bucks[freq] == null) { + bucks[freq] = new ArrayList<>(); + } + bucks[freq].add(key); + } + + for (int freq = nums.length; freq >=0 && k > 0; freq--) { + if (bucks[freq] != null) { + k -=bucks[freq].size(); + result.addAll(bucks[freq]); + } + } + return result; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/TrailingZeroes.java b/src/geeksforgeeks/TrailingZeroes.java index d77577e..87a2490 100644 --- a/src/geeksforgeeks/TrailingZeroes.java +++ b/src/geeksforgeeks/TrailingZeroes.java @@ -3,7 +3,6 @@ /*https://www.geeksforgeeks.org/count-trailing-zeroes-factorial-number/*/ class TrailingZeroes { public int trailingZeroes(int n) { - int count = 0; while (n != 0) { int tmp = n / 5; diff --git a/src/geeksforgeeks/TreasureIslandII.java b/src/geeksforgeeks/TreasureIslandII.java index 3d4237f..0525e5a 100644 --- a/src/geeksforgeeks/TreasureIslandII.java +++ b/src/geeksforgeeks/TreasureIslandII.java @@ -4,7 +4,7 @@ import java.util.Queue; /*https://leetcode.com/discuss/interview-question/356150/amazon-oa-2019-shortest-path-from-multiple-sources*/ -// unresolved + public class TreasureIslandII { private static final int[][] DIRS = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; @@ -61,8 +61,12 @@ public String toString() { } public static void main(String[] args) { - char[][] grid = {{'S', 'O', 'O', 'S', 'S'}, {'D', 'O', 'D', 'O', 'D'}, {'O', 'O', 'O', 'O', 'X'}, - {'X', 'D', 'D', 'O', 'O'}, {'X', 'D', 'D', 'D', 'O'}}; + char[][] grid = { + {'S', 'O', 'O', 'S', 'S'}, + {'D', 'O', 'D', 'O', 'D'}, + {'O', 'O', 'O', 'O', 'X'}, + {'X', 'D', 'D', 'O', 'O'}, + {'X', 'D', 'D', 'D', 'O'}}; test(minDist(grid), 3); } diff --git a/src/geeksforgeeks/Twitter.java b/src/geeksforgeeks/Twitter.java index 7441e4e..08ab297 100644 --- a/src/geeksforgeeks/Twitter.java +++ b/src/geeksforgeeks/Twitter.java @@ -6,7 +6,7 @@ public class Twitter { private static int timeStamp = 0; - private Map userMap; + private Map userMap; // Tweet link to next Tweet so that we can save a lot of time // when we execute getNewsFeed(userId) @@ -30,7 +30,7 @@ public class User { public User(int id) { this.id = id; followed = new HashSet<>(); - follow(id); // first follow itself + follow(id); // first follow yourself tweet_head = null; } diff --git a/src/geeksforgeeks/TwoSumClosestToZero.java b/src/geeksforgeeks/TwoSumClosestToZero.java index 49bf593..7ac29d4 100644 --- a/src/geeksforgeeks/TwoSumClosestToZero.java +++ b/src/geeksforgeeks/TwoSumClosestToZero.java @@ -1,22 +1,24 @@ package geeksforgeeks; import java.util.Arrays; - +import java.util.Collections; +import java.util.*; public class TwoSumClosestToZero { public static void main(String[] args) { - int arr[] = {-6, -5, -3, 0, 2, 4, 9, 5}; + Integer arr[] = {-6, -5, -3, 0, 2, 4, 9, 5}; findPair(arr); } - public static void findPair(int[] arr) { + public static void findPair(Integer[] arr) { if (arr.length < 2) { return; } Arrays.sort(arr); + System.out.println(Arrays.toString(arr)); int low = 0; int high = arr.length - 1; diff --git a/src/geeksforgeeks/UnSortedContiguousSubArray.java b/src/geeksforgeeks/UnSortedContiguousSubArray.java new file mode 100644 index 0000000..91b07de --- /dev/null +++ b/src/geeksforgeeks/UnSortedContiguousSubArray.java @@ -0,0 +1,40 @@ +package geeksforgeeks; + +class UnSortedContiguousSubArray { + public int findUnsortedSubarray(int[] nums) { + int i = 0; + int j = nums.length - 1; + + while (i < nums.length - 1) { + if (nums[i] > nums[i + 1]) { + break; + } + i++; + } + if (i >= j) + return 0; + + while (j > 0) { + if (nums[j] < nums[j - 1]) { + break; + } + j--; + } + int min = Integer.MAX_VALUE; + int max = Integer.MIN_VALUE; + + for (int k = i; k <= j; k++) { + min = Math.min(min, nums[k]); + max = Math.max(max, nums[k]); + } + + while (i >= 0 && min < nums[i]) + i--; + while (j < nums.length && max > nums[j]) + j++; + + return j - i - 1; + + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/UniquePath.java b/src/geeksforgeeks/UniquePath.java index c022223..5a47183 100644 --- a/src/geeksforgeeks/UniquePath.java +++ b/src/geeksforgeeks/UniquePath.java @@ -7,9 +7,7 @@ public class UniquePath { public static void main(String[] args) { System.out.println(uniquePathI(3, 2)); - int[][] matrix = {{0, 0, 0}, - {0, 1, 0}, - {0, 0, 0}}; + int[][] matrix = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } }; System.out.println(uniquePathII(matrix)); @@ -34,31 +32,43 @@ private static int uniquePathI(int row, int col) { return dp[row - 1][col - 1]; } - private static int uniquePathII(int[][] mat) { - int[][] dp = new int[mat.length][mat[0].length]; - for (int i = 0; i < mat[0].length; i++) { - if (mat[0][i] != 1) { - dp[0][i] = 1; + + if (obstacleGrid[0][0] == 1) + return 0; + int m = obstacleGrid.length; + int n = obstacleGrid[0].length; + + int[][] dp = new int[obstacleGrid.length][obstacleGrid[0].length]; + + for (int i = 0; i < m; i++) { + if (obstacleGrid[i][0] == 1) { + dp[i][0] = 0; + break; + } else { + dp[i][0] = 1; } } - for (int i = 0; i < mat.length; i++) { - if (mat[i][0] != 1) { - dp[i][0] = 1; + for (int j = 0; j < n; j++) { + if (obstacleGrid[0][j] == 1) { + dp[0][j] = 0; + break; + } else { + dp[0][j] = 1; } } - for (int i = 1; i < mat.length; i++) { - for (int j = 1; j < mat[0].length; j++) { - if (mat[i][j] == 1) { + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + if (obstacleGrid[i][j] == 1) { dp[i][j] = 0; } else { dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; } - } } - return dp[mat.length - 1][mat[0].length - 1]; + return dp[m - 1][n - 1]; + } } diff --git a/src/geeksforgeeks/ValidIpAddresses.java b/src/geeksforgeeks/ValidIpAddresses.java new file mode 100644 index 0000000..ff8f00d --- /dev/null +++ b/src/geeksforgeeks/ValidIpAddresses.java @@ -0,0 +1,39 @@ +package geeksforgeeks; + +import java.util.*; + +public class ValidIpAddresses { + public List restoreIpAddresses(String s) { + if(s==null) return Collections.emptyList(); + List result= new ArrayList<>(); + + for(int i=1; i<4 && i3) return false; + + if(part.charAt(0)=='0' && part.length()>1) return false; + + int address= Integer.parseInt(part); + + return address>=0 && address<=255; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/ValidSuduko.java b/src/geeksforgeeks/ValidSuduko.java new file mode 100644 index 0000000..095e9c1 --- /dev/null +++ b/src/geeksforgeeks/ValidSuduko.java @@ -0,0 +1,21 @@ +package geeksforgeeks; + +class VulgarSuduko { + public boolean isValidSudoku(char[][] board) { + Set seen = new HashSet<>(); + + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 9; j++) { + if (board[i][j] != '.') { + char number = board[i][j]; + if (!seen.add(number + "seen in row" + i) || !seen.add(number + "seen in col" + j) + || !seen.add(number + "seen in block" + i / 3 + "-" + j / 3)) { + return false; + } + } + } + } + + return true; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/VulgarDecimal.java b/src/geeksforgeeks/VulgarDecimal.java index 973665e..9a76c62 100644 --- a/src/geeksforgeeks/VulgarDecimal.java +++ b/src/geeksforgeeks/VulgarDecimal.java @@ -6,64 +6,46 @@ public class VulgarDecimal { - public static String fractionToDecimal(long num, long den) { - if (num == 0) { - return "0"; + public static String fractionToDecimal(long numerator, long denominator) { + if(denominator==0) return null; + boolean isNegative= (numerator < 0 && denominator > 0) || (numerator > 0 && denominator < 0) ? true : false; + + long denomiL= Math.abs((long)denominator); + long numerL= Math.abs((long)numerator); + + Map map= new HashMap<>(); + + StringBuilder sb= new StringBuilder(); + + sb.append((numerL/denomiL)); + + if(numerL%denomiL!=0){ + sb.append("."); } - StringBuilder result = new StringBuilder(); - - result.append(((num > 0) ^ (den > 0)) ? "-" : ""); - result.append(num / den); - num %= den; - if (num == 0) { - return result.toString(); - } - - result.append("."); - HashMap map = new HashMap<>(); - map.put(num, result.length()); - while (num != 0) { - num *= 10; - result.append(num / den); - num %= den; - if (map.containsKey(num)) { - int index = map.get(num); - result.insert(index, "("); - result.append(")"); + if(isNegative) sb.insert(0,"-"); + numerL%=denomiL; + if(numerL==0) return sb.toString(); + + map.put(numerL,sb.length()); + + while(numerL>0){ + + numerL*=10; + sb.append((numerL/denomiL)); + numerL= (numerL%denomiL); + + if(map.containsKey(numerL)){ + int index= map.get(numerL); + sb.insert(index,"("); + sb.append(")"); break; - } else { - map.put(num, result.length()); + }else{ + map.put(numerL,sb.length()); } } - return result.toString(); + + return sb.toString(); } - /** - * boolean doTestsPass() - * Returns true if all tests pass. Otherwise false - *

- * Consider adding more tests. - */ - public static boolean doTestsPass() { - boolean testsPassed = true; - - // testsPassed &= fractionToDecimal(1l, 2l).equals("0.5"); - //testsPassed &= fractionToDecimal(1l, 3l).equals("0.(3)"); - //testsPassed &= fractionToDecimal(1l, 30l).equals("0.0(3)"); - //testsPassed &= fractionToDecimal(1l, 75l).equals("0.01(3)"); - //testsPassed &= fractionToDecimal(4l, 7l).equals("0.(571428)"); - testsPassed &= fractionToDecimal(1l, 56l).equals("0.017(857142)"); - - if (testsPassed) { - System.out.println("Tests passes"); - } else { - System.out.println("Tests failed"); - } - return testsPassed; - } - - public static void main(String[] args) { - doTestsPass(); - } } diff --git a/src/geeksforgeeks/WordLadder.java b/src/geeksforgeeks/WordLadder.java new file mode 100644 index 0000000..2a69ea3 --- /dev/null +++ b/src/geeksforgeeks/WordLadder.java @@ -0,0 +1,43 @@ +package geeksforgeeks; + +public class WordLadder { + public int ladderLength(String beginWord, String endWord, List wordList) { + Set set = new HashSet(wordList); + if(!set.contains(endWord)) return 0; // end word itself not in set + Queue queue = new LinkedList(); + queue.add(beginWord); + int count = 1; + + while(!queue.isEmpty()) { + + int size = queue.size(); + for (int i =0; i Date: Fri, 8 May 2020 23:42:44 +0530 Subject: [PATCH 31/51] adding git ignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2a017ab..6fd6edf 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ .project AmazonProblems.iml +*.json From 025b466c4320bae3481fb1391e71fbe8cb8f7956 Mon Sep 17 00:00:00 2001 From: vignesh Date: Sat, 9 May 2020 13:29:25 +0530 Subject: [PATCH 32/51] resolved conflicts --- .../ConstructBSTFromPreorder.java | 1 + src/geeksforgeeks/MaximumProductSubarray.java | 3 - .../MedianOfTwoSortedArrays.java | 25 ----- src/geeksforgeeks/MeetingRoomsII.java | 14 --- .../MinimumDistanceBetweenTwoNumbers.java | 5 +- src/geeksforgeeks/MinimumSwapSortArray.java | 49 ---------- src/geeksforgeeks/MinimumWindowSubstring.java | 95 ++++++++----------- src/geeksforgeeks/MirrorBinaryTree.java | 7 -- src/geeksforgeeks/NextGreaterNumber.java | 5 - src/geeksforgeeks/NextLargestList.java | 8 -- src/geeksforgeeks/Node.java | 4 - src/geeksforgeeks/NonDecreasingArray.java | 4 - src/geeksforgeeks/PalindromicSubSequence.java | 35 ------- src/geeksforgeeks/Pattern132.java | 15 --- src/geeksforgeeks/PerfectSquare.java | 33 +++---- src/geeksforgeeks/PlusOne.java | 67 ++++--------- src/geeksforgeeks/Pow.java | 38 -------- src/geeksforgeeks/RemoveKDigits.java | 21 ---- .../SearchAnElementInMatrix.java | 11 --- 19 files changed, 73 insertions(+), 367 deletions(-) diff --git a/src/geeksforgeeks/ConstructBSTFromPreorder.java b/src/geeksforgeeks/ConstructBSTFromPreorder.java index 0534eca..2fcc5aa 100644 --- a/src/geeksforgeeks/ConstructBSTFromPreorder.java +++ b/src/geeksforgeeks/ConstructBSTFromPreorder.java @@ -41,6 +41,7 @@ public static TreeNode bstFromPreorder(int[] preorder) { Stack stack = new Stack<>(); TreeNode root = new TreeNode(preorder[0]); stack.push(root); + //8, 3, 1, 6, 4, 7, 10, 14, 13 for (int i = 1; i < preorder.length; i++) { TreeNode node = new TreeNode(preorder[i]); if (preorder[i] < stack.peek().val) { diff --git a/src/geeksforgeeks/MaximumProductSubarray.java b/src/geeksforgeeks/MaximumProductSubarray.java index 5325b97..272be81 100644 --- a/src/geeksforgeeks/MaximumProductSubarray.java +++ b/src/geeksforgeeks/MaximumProductSubarray.java @@ -26,8 +26,6 @@ public static int maxProductSubArray(int[] A) { return maxsofar; } -<<<<<<< HEAD:src/geeksforgeeks/MaximumProductSubarray.java -======= public static int maxSumSubArray(int[] arr) { int max = Integer.MIN_VALUE; @@ -44,7 +42,6 @@ public static int maxSumSubArray(int[] arr) { return sum; } ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163:src/geeksforgeeks/MaximumSubarray.java public static void main(String[] args) { int arr[] = { 1, -2, -3, 0, 8, 7, -2 }; System.out.println("Maximum Sub array sum is " + maxSumSubArray(arr)); diff --git a/src/geeksforgeeks/MedianOfTwoSortedArrays.java b/src/geeksforgeeks/MedianOfTwoSortedArrays.java index 69d5e78..7eae057 100644 --- a/src/geeksforgeeks/MedianOfTwoSortedArrays.java +++ b/src/geeksforgeeks/MedianOfTwoSortedArrays.java @@ -1,13 +1,9 @@ package geeksforgeeks; -<<<<<<< HEAD -class MedianOfTwoSortedArrays{ -======= /** * https://github.com/mission-peace/interview/blob/master/src/com/interview/binarysearch/MedianOfTwoSortedArrayOfDifferentLength.java */ public class MedianOfTwoSortedArrays { ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 public double findMedianSortedArrays(int input1[], int input2[]) { //if input1 length is greater than switch them so that input1 is smaller than input2. @@ -20,13 +16,8 @@ public double findMedianSortedArrays(int input1[], int input2[]) { int low = 0; int high = x; while (low <= high) { -<<<<<<< HEAD - int partitionX = (low + high)/2; - int partitionY = (x + y + 1)/2 - partitionX; -======= int partitionX = (low + high) / 2; int partitionY = (x + y + 1) / 2 - partitionX; ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 //if partitionX is 0 it means nothing is there on left side. Use -INF for maxLeftX //if partitionX is length of input then there is nothing on right side. Use +INF for minRightX @@ -41,15 +32,9 @@ public double findMedianSortedArrays(int input1[], int input2[]) { // Now get max of left elements and min of right elements to get the median in case of even length combined array size // or get max of left for odd length combined array size. if ((x + y) % 2 == 0) { -<<<<<<< HEAD - return ((double)Math.max(maxLeftX, maxLeftY) + Math.min(minRightX, minRightY))/2; - } else { - return (double)Math.max(maxLeftX, maxLeftY); -======= return ((double) Math.max(maxLeftX, maxLeftY) + Math.min(minRightX, minRightY)) / 2; } else { return Math.max(maxLeftX, maxLeftY); ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 } } else if (maxLeftX > minRightY) { //we are too far on right side for partitionX. Go on left side. high = partitionX - 1; @@ -63,15 +48,6 @@ public double findMedianSortedArrays(int input1[], int input2[]) { } public static void main(String[] args) { -<<<<<<< HEAD - int[] x = {1, 3, 8, 9, 15}; - int[] y = {7, 11, 19, 21, 18, 25}; - - MedianOfTwoSortedArrayOfDifferentLength mm = new MedianOfTwoSortedArrayOfDifferentLength(); - mm.findMedianSortedArrays(x, y); - } -} -======= int[] x = { 1, 3, 8, 9, 15, 17 }; int[] y = { 7, 11, 18, 19, 21, 25 }; // 1,3,7,8,9,11,15,18,19,21,25 @@ -79,4 +55,3 @@ public static void main(String[] args) { System.out.println(mm.findMedianSortedArrays(x, y)); } } ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 diff --git a/src/geeksforgeeks/MeetingRoomsII.java b/src/geeksforgeeks/MeetingRoomsII.java index f2642c9..abff5e9 100644 --- a/src/geeksforgeeks/MeetingRoomsII.java +++ b/src/geeksforgeeks/MeetingRoomsII.java @@ -17,19 +17,6 @@ public class MeetingRoomsII { */ // [(0,30),(5,10),(15,20)] public int minMeetingRooms(List intervals) { -<<<<<<< HEAD - if (intervals == null || intervals.size() == 0) - return -1; - - Collections.sort(intervals, (a, b) -> Integer.compare(a.start, b.start)); - PriorityQueue queue = new PriorityQueue<>(); - // Interval max= intervals.get(0); - queue.offer(intervals.get(0).end); - for (int i = 1; i < intervals.size(); i++) { - Interval temp = intervals.get(i); - if (queue.peek() <= temp.start) - queue.poll(); -======= if (intervals == null || intervals.size() == 0) { return -1; } @@ -43,7 +30,6 @@ public int minMeetingRooms(List intervals) { if (queue.peek() <= temp.start) { queue.poll(); } ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 queue.offer(temp.end); } diff --git a/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java b/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java index ae2a039..fc8651d 100644 --- a/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java +++ b/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java @@ -36,11 +36,8 @@ int minDist(int arr[], int n, int x, int y) { public static void main(String[] args) { MinimumDistanceBetweenTwoNumbers min = new MinimumDistanceBetweenTwoNumbers(); -<<<<<<< HEAD int arr[] = {3, 5, 4, 2, 6, 5, 6, 6, 5, 4, 8, 3}; -======= - int arr[] = { 3, 5, 4, 3, 1, 2, 4, 6, 5, 6, 6, 5, 4, 8, 3 }; ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 + int arr1[] = { 3, 5, 4, 3, 1, 2, 4, 6, 5, 6, 6, 5, 4, 8, 3 }; int n = arr.length; int x = 3; int y = 6; diff --git a/src/geeksforgeeks/MinimumSwapSortArray.java b/src/geeksforgeeks/MinimumSwapSortArray.java index 08d440f..26d3d1b 100644 --- a/src/geeksforgeeks/MinimumSwapSortArray.java +++ b/src/geeksforgeeks/MinimumSwapSortArray.java @@ -8,54 +8,6 @@ */ class MinimumSwapSortArray { -<<<<<<< HEAD - public int minSwaps(int[] A, int N) { - int i = 0; - // Tree map sorts the order - Map resMap = new TreeMap<>(); - for (; i < N; i++) { - resMap.put(A[i], i); - } - System.out.println("After first loop end"); - System.out.println(); - for (Map.Entry entry : resMap.entrySet()) { - System.out.println(entry.getKey() + " --> " + entry.getValue() + ", "); - } - System.out.println("second loop start"); - i = 0; - for (Map.Entry entry : resMap.entrySet()) { - //System.out.print(entry.getKey() + " --> " + i + ", "); - entry.setValue(i++); - } - - System.out.println("second loop end"); - - for (Map.Entry entry : resMap.entrySet()) { - System.out.println(entry.getKey() + " --> " + entry.getValue() + ", "); - } - System.out.println(); - int swap = 0; - for (i = 0; i < N;) { - //System.out.println(A[i] + "--" + resMap.get(A[i]) + "--" + i); - // check if array position is same as treeMap's index - if (resMap.get(A[i]) != i) { - int temp = A[i]; - A[i] = A[resMap.get(temp)]; - A[resMap.get(temp)] = temp; - swap++; - } else { - i++; - } - } - return swap; - } - - public static void main(String[] args) { - int[] a = { 1, 5, 4, 3, 2 }; - MinimumSwapSortArray g = new MinimumSwapSortArray(); - System.out.println(g.minSwaps(a, a.length)); - } -======= public int minSwaps(int[] A, int N) { int i = 0; // Tree map sorts the order @@ -91,5 +43,4 @@ public static void main(String[] args) { MinimumSwapSortArray g = new MinimumSwapSortArray(); System.out.println(g.minSwaps(a, a.length)); } ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 } \ No newline at end of file diff --git a/src/geeksforgeeks/MinimumWindowSubstring.java b/src/geeksforgeeks/MinimumWindowSubstring.java index a906185..71f839e 100644 --- a/src/geeksforgeeks/MinimumWindowSubstring.java +++ b/src/geeksforgeeks/MinimumWindowSubstring.java @@ -8,10 +8,6 @@ */ class MinimumWindowSubstring { -<<<<<<< HEAD - public static String minWindow(String s, String t) { - if (t.length() > s.length()) -======= public static void main(String[] args) { System.out.println(minWindow("AADOBECODEBANC", "ABC")); System.out.println(minWindow("abcdebdde", "bde")); @@ -19,68 +15,51 @@ public static void main(String[] args) { public static String minWindow(String s, String t) { if (t.length() > s.length()) { ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 return ""; - Map map = new HashMap<>(); - for (char c : t.toCharArray()) { - map.put(c, map.getOrDefault(c, 0) + 1); - } -<<<<<<< HEAD -======= - Map map = new HashMap<>(); - for (char c : t.toCharArray()) { - map.put(c, map.getOrDefault(c, 0) + 1); - } ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 - int counter = map.size(); + Map map = new HashMap<>(); + for (char c : t.toCharArray()) { + map.put(c, map.getOrDefault(c, 0) + 1); + } + Map map = new HashMap<>(); + for (char c : t.toCharArray()) { + map.put(c, map.getOrDefault(c, 0) + 1); + } + int counter = map.size(); - int begin = 0, end = 0; - int head = 0; - int len = Integer.MAX_VALUE; + int begin = 0, end = 0; + int head = 0; + int len = Integer.MAX_VALUE; - while (end < s.length()) { - char c = s.charAt(end); - if (map.containsKey(c)) { - map.put(c, map.get(c) - 1); -<<<<<<< HEAD - if (map.get(c) == 0) - counter--; -======= - if (map.get(c) == 0) { - counter--; + while (end < s.length()) { + char c = s.charAt(end); + if (map.containsKey(c)) { + map.put(c, map.get(c) - 1); + if (map.get(c) == 0) { + counter--; + } } ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 - } - end++; + end++; - while (counter == 0) { - char tempc = s.charAt(begin); - if (map.containsKey(tempc)) { - map.put(tempc, map.get(tempc) + 1); - if (map.get(tempc) > 0) { - counter++; + while (counter == 0) { + char tempc = s.charAt(begin); + if (map.containsKey(tempc)) { + map.put(tempc, map.get(tempc) + 1); + if (map.get(tempc) > 0) { + counter++; + } } + if (end - begin < len) { + len = end - begin; + head = begin; + } + begin++; } - if (end - begin < len) { - len = end - begin; - head = begin; - } - begin++; - } -<<<<<<< HEAD - - } - if (len == Integer.MAX_VALUE) - return ""; - return s.substring(head, head + len); - } -======= ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 + } + if (len == Integer.MAX_VALUE) { + return ""; + } + return s.substring(head, head + len); } - if (len == Integer.MAX_VALUE) { - return ""; - } - return s.substring(head, head + len); } } \ No newline at end of file diff --git a/src/geeksforgeeks/MirrorBinaryTree.java b/src/geeksforgeeks/MirrorBinaryTree.java index 1deefe2..8b1e8d2 100644 --- a/src/geeksforgeeks/MirrorBinaryTree.java +++ b/src/geeksforgeeks/MirrorBinaryTree.java @@ -31,14 +31,7 @@ static void mirror(Node root) { q.add(root); while (q.size() > 0) { -<<<<<<< HEAD Node curr = q.poll(); -======= - - Node curr = q.remove(); - - // swap the elements ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 Node temp = curr.left; curr.left = curr.right; curr.right = temp; diff --git a/src/geeksforgeeks/NextGreaterNumber.java b/src/geeksforgeeks/NextGreaterNumber.java index 2375d13..44507ef 100644 --- a/src/geeksforgeeks/NextGreaterNumber.java +++ b/src/geeksforgeeks/NextGreaterNumber.java @@ -57,17 +57,12 @@ public void findNextGreaterNumber(int[] number) { public static void main(String[] args) { NextGreaterNumber solution = new NextGreaterNumber(); -<<<<<<< HEAD int[] number = {6, 9, 3, 8, 6, 5, 2}; // 6938652 // 6983652 // 6982356 // i =3 //534976 -======= - int[] number = { 6, 9, 3, 8, 6, 5, 2 }; - ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 solution.findNextGreaterNumber(number); System.out.println("Next greater number is: "); diff --git a/src/geeksforgeeks/NextLargestList.java b/src/geeksforgeeks/NextLargestList.java index 28a8c0a..735e08c 100644 --- a/src/geeksforgeeks/NextLargestList.java +++ b/src/geeksforgeeks/NextLargestList.java @@ -1,12 +1,5 @@ package geeksforgeeks; -<<<<<<< HEAD -class NextLargestList { - public int[] nextLargerNodes(ListNode head) { - - if (head == null) - return new int[0]; -======= import java.util.Stack; /** @@ -19,7 +12,6 @@ public int[] nextLargerNodes(ListNode head) { if (head == null) { return new int[0]; } ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 int size = getSize(head); int[] result = new int[size]; head = reverse(head); diff --git a/src/geeksforgeeks/Node.java b/src/geeksforgeeks/Node.java index c64be64..04e0bb8 100644 --- a/src/geeksforgeeks/Node.java +++ b/src/geeksforgeeks/Node.java @@ -1,12 +1,8 @@ package geeksforgeeks; -<<<<<<< HEAD -//https://www.geeksforgeeks.org/remove-bst-keys-outside-the-given-range/ -======= /** * https://www.geeksforgeeks.org/remove-bst-keys-outside-the-given-range/ */ ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 class RemoveBSTGivenOutsideRange { private static BSTNode removeOutsideRange(BSTNode root, int min, int max) { diff --git a/src/geeksforgeeks/NonDecreasingArray.java b/src/geeksforgeeks/NonDecreasingArray.java index 3eeb4da..8c7bb2e 100644 --- a/src/geeksforgeeks/NonDecreasingArray.java +++ b/src/geeksforgeeks/NonDecreasingArray.java @@ -23,11 +23,7 @@ public boolean checkPossibility(int[] nums) { public static void main(String[] args) { // 1,4,2,3 -<<<<<<< HEAD - // 3,4,2,3 -======= // //3,4,2,3 ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 int[] nums = { 7, 8, 2, 3 }; NonDecreasingArray nda = new NonDecreasingArray(); System.out.println(nda.checkPossibility(nums)); diff --git a/src/geeksforgeeks/PalindromicSubSequence.java b/src/geeksforgeeks/PalindromicSubSequence.java index c82c5c0..9288b39 100644 --- a/src/geeksforgeeks/PalindromicSubSequence.java +++ b/src/geeksforgeeks/PalindromicSubSequence.java @@ -1,7 +1,6 @@ package geeksforgeeks; class PalindromicSubSequence { -<<<<<<< HEAD public int longestPalindromeSubseq(String s) { if(s==null || s.length()==0) return 0; @@ -23,30 +22,6 @@ public int longestPalindromeSubseq(String s) { } -======= - - public int longestPalindromeSubseq(String s) { - if (s == null || s.length() == 0) { - return 0; - } - - int[][] dp = new int[s.length()][s.length()]; - - for (int i = s.length() - 1; i >= 0; i--) { - for (int j = i; j < s.length(); j++) { - if (i == j) { - dp[i][j] = 1; - continue; - } - - dp[i][j] = s.charAt(i) == s.charAt(j) ? 2 + dp[i + 1][j - 1] : Math.max(dp[i + 1][j], dp[i][j - 1]); - } - } - - return dp[0][s.length() - 1]; - - } ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 public int longestPalindromeSubseq1(String s) { int[] dp = new int[s.length()]; @@ -57,22 +32,12 @@ public int longestPalindromeSubseq1(String s) { int tmp = dp[j]; if (s.charAt(i) == s.charAt(j)) { dp[j] = pre + 2; -<<<<<<< HEAD - } - else { -======= } else { ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 dp[j] = Math.max(dp[j], dp[j - 1]); } pre = tmp; } } -<<<<<<< HEAD - -======= - ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 return dp[s.length() - 1]; } } \ No newline at end of file diff --git a/src/geeksforgeeks/Pattern132.java b/src/geeksforgeeks/Pattern132.java index 92aed68..26a95cf 100644 --- a/src/geeksforgeeks/Pattern132.java +++ b/src/geeksforgeeks/Pattern132.java @@ -15,23 +15,12 @@ public static boolean find132pattern(int[] arr) { // {3, 3, 3, 1, 1, 1, 1, 1} for (int j = arr.length - 1, top = arr.length; j >= 0; j--) { -<<<<<<< HEAD if (arr[j] <= temp[j]) continue; while (top < arr.length && temp[top] <= temp[j]) top++; if (top < arr.length && arr[j] > temp[top]) return true; -======= - if (arr[j] <= temp[j]) { - continue; - } - while (top < arr.length && temp[top] <= temp[j]) - top++; - if (top < arr.length && arr[j] > temp[top]) { - return true; - } ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 temp[--top] = arr[j]; } return false; @@ -39,10 +28,6 @@ public static boolean find132pattern(int[] arr) { public static void main(String[] args) { int[] arr = { 3, 4, 1, 2, 9, 6, 7, 8 }; -<<<<<<< HEAD - -======= ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 find132pattern(arr); } } diff --git a/src/geeksforgeeks/PerfectSquare.java b/src/geeksforgeeks/PerfectSquare.java index db1b894..16370ec 100644 --- a/src/geeksforgeeks/PerfectSquare.java +++ b/src/geeksforgeeks/PerfectSquare.java @@ -1,19 +1,6 @@ package geeksforgeeks; -<<<<<<< HEAD class PerfectSquare { -======= -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Queue; -import java.util.Set; - -/** - * https://leetcode.com/problems/perfect-squares/ - */ -class PerfectSquare { - ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 public int numSquares(int n) { Queue q = new LinkedList<>(); Set visited = new HashSet<>(); @@ -43,12 +30,20 @@ public int numSquares(int n) { } return depth; } -<<<<<<< HEAD -======= - public static void main(String[] args) { - PerfectSquare ps = new PerfectSquare(); - System.out.println(ps.numSquares(13)); + public int numSquaresDp(int n) { + int[] ns = new int[n+1]; + Arrays.fill(ns , Integer.MAX_VALUE); + ns[0] = 0; + for(int i=1;i0;j--){ + int result = i - j*j; + min = Math.min(min, ns[result]+1); + } + ns[i] = min; + } + return ns[n]; } ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 } \ No newline at end of file diff --git a/src/geeksforgeeks/PlusOne.java b/src/geeksforgeeks/PlusOne.java index 40eb8dd..7c1f509 100644 --- a/src/geeksforgeeks/PlusOne.java +++ b/src/geeksforgeeks/PlusOne.java @@ -1,53 +1,26 @@ package geeksforgeeks; -<<<<<<< HEAD class PlusOne { -======= -import java.util.Arrays; - -/** - * https://leetcode.com/problems/plus-one/ - */ -class PlusOne { - ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 - public static int[] plusOne(int[] digits) { - - StringBuilder sb = new StringBuilder(); - int remainder = 0; - for (int i = digits.length - 1; i >= 0; i--) { - int num = 0; - if (i == digits.length - 1) { - num = digits[i] + 1; - } else { - num = digits[i] + remainder; - } - int count = String.valueOf(num).length(); - if (count > 1) { - sb.append(num % 10); - remainder = num / 10; - } else { - remainder = 0; - sb.append(num); - } + public static int[] plusOne(int[] digits) { + if(digits==null || digits.length==0) return digits; + int temp=digits[digits.length-1]+1; + + digits[digits.length-1]= temp%10; + int rem=temp/10; + for(int i=digits.length-2;i>=0;i--){ + int sum=digits[i]+rem; + digits[i]=(sum)%10; + rem=(sum)/10; } -<<<<<<< HEAD - if(remainder!=0) - sb.append(remainder); - return sb.reverse().toString().chars().map(i -> i - '0').toArray(); - } -======= - if (remainder != 0) { - sb.append(remainder); - } - - return sb.reverse().toString().chars().map(i -> i - '0').toArray(); - } - - public static void main(String[] args) { - int[] digits = { 1, 2, 9 }; - int[] endpointUrl = plusOne(digits); - Arrays.stream(endpointUrl).forEach(System.out::println); + + if(rem>0){ + int[] result= new int[digits.length+1]; + result[0]=1; + return result; + } + + + return digits; } ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 + } \ No newline at end of file diff --git a/src/geeksforgeeks/Pow.java b/src/geeksforgeeks/Pow.java index 9640061..4108096 100644 --- a/src/geeksforgeeks/Pow.java +++ b/src/geeksforgeeks/Pow.java @@ -1,6 +1,5 @@ package geeksforgeeks; -<<<<<<< HEAD // https://leetcode.com/problems/powx-n/ public class Pow { @@ -33,47 +32,10 @@ public double pow1(double x, int n) { double result = 1.0; for(int i = n; i != 0; i /= 2, x *= x) { if( i % 2 != 0 ) { -======= -/** - * https://leetcode.com/problems/powx-n/ - */ -public class Pow { - - public static void main(String[] args) { - Pow pow = new Pow(); - System.out.println(pow.pow(2.00000, 10)); - } - - public double pow(double x, int m) { - double temp = x; - if (m == 0) { - return 1; - } - temp = pow(x, m / 2); - if (m % 2 == 0) { - return temp * temp; - } else { - if (m > 0) { - return x * temp * temp; - } else { - return (temp * temp) / x; - } - } - } - - public double powIterative(double x, int n) { - double result = 1.0; - for (int i = n; i != 0; i /= 2, x *= x) { - if (i % 2 != 0) { ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 result *= x; } } return n < 0 ? 1.0 / result : result; -<<<<<<< HEAD - } -======= } ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 } \ No newline at end of file diff --git a/src/geeksforgeeks/RemoveKDigits.java b/src/geeksforgeeks/RemoveKDigits.java index 9e25965..d64c12f 100644 --- a/src/geeksforgeeks/RemoveKDigits.java +++ b/src/geeksforgeeks/RemoveKDigits.java @@ -7,7 +7,6 @@ */ public class RemoveKDigits { -<<<<<<< HEAD //1432219 public static String removeKdigits(String num, int k) { if(num==null || num.length()==0) return null; @@ -17,22 +16,6 @@ public static String removeKdigits(String num, int k) { while(!queue.isEmpty() && queue.getLast()>c-'0' && k>0){ queue.removeLast(); -======= - //143221999 - //121999 - public static String removeKDigits(String num, int k) { - int len = num.length(); - - if (k == len) { - return "0"; - } - - Stack stack = new Stack<>(); - int i = 0; - while (i < num.length()) { - while (k > 0 && !stack.isEmpty() && stack.peek() > num.charAt(i)) { - stack.pop(); ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 k--; } queue.addLast(c-'0'); @@ -56,10 +39,6 @@ public static String removeKDigits(String num, int k) { } public static void main(String[] args) { -<<<<<<< HEAD - System.out.println(removeKdigits("143221999", 3)); -======= System.out.println(removeKDigits("14232191", 3)); ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 } } \ No newline at end of file diff --git a/src/geeksforgeeks/SearchAnElementInMatrix.java b/src/geeksforgeeks/SearchAnElementInMatrix.java index 8d1e6b8..855a1b6 100644 --- a/src/geeksforgeeks/SearchAnElementInMatrix.java +++ b/src/geeksforgeeks/SearchAnElementInMatrix.java @@ -54,20 +54,9 @@ public static boolean searchI(int[][] matrix, int target) { } public static void main(String[] args) { -<<<<<<< HEAD - int[][] mat = {{10, 20, 30, 40}, - {15, 25, 35, 45}, - {27, 29, 37, 48}, - {32, 33, 39, 50}}; - - int[][] matI = {{1, 3, 5, 7} , - {10, 11, 16, 20}, - {23, 30, 34, 50}}; -======= int[][] mat = { { 10, 20, 30, 40 }, { 15, 25, 35, 45 }, { 27, 29, 37, 48 }, { 32, 33, 39, 50 } }; int[][] matI = { { 1, 3, 5, 7 }, { 10, 11, 16, 20 }, { 23, 30, 34, 50 } }; ->>>>>>> fa44d45e65bd24e807ebda00da7c1fd078295163 System.out.println(searchI(matI, 11)); System.out.println(searchII(mat, 4, 33)); From d788a3074b934727fdb29635d80259917d123574 Mon Sep 17 00:00:00 2001 From: vignesh Date: Mon, 15 Jun 2020 20:19:02 +0530 Subject: [PATCH 33/51] new problem challenges --- src/geeksforgeeks/ArrangeInQueue.java | 27 +++++ src/geeksforgeeks/BasicCalculator.java | 56 ++++++++++ src/geeksforgeeks/BitonicSearch.java | 16 +++ src/geeksforgeeks/CourseSchedule.java | 67 +++++++++++ src/geeksforgeeks/EvaluvateExpressions.java | 59 ++++++++++ src/geeksforgeeks/EvaluvateRPN.java | 2 +- .../FindMinimumInRotatedArray.java | 24 +++- src/geeksforgeeks/FindMissingNumbers.java | 40 +++++++ src/geeksforgeeks/FirstAndLastOccurence.java | 36 ++++++ src/geeksforgeeks/FirstMissingPositive.java | 38 +++++++ src/geeksforgeeks/FrequencySort.java | 26 +++++ src/geeksforgeeks/GenerateParenthesis.java | 12 +- src/geeksforgeeks/GraphBiPartite.java | 53 +++++++++ src/geeksforgeeks/IPOMaxProfit.java | 43 +++++++ src/geeksforgeeks/InserstionSortList.java | 26 +++++ src/geeksforgeeks/IsSubsequence.java | 22 ++++ src/geeksforgeeks/KClosestElements.java | 61 ++++++++++ src/geeksforgeeks/LargestDivisibleSubset.java | 59 ++++++++++ .../MaxDistinctElementAfterKRemoval.java | 57 ++++++++++ src/geeksforgeeks/MaxFreqStack.java | 46 ++++++++ src/geeksforgeeks/MaximumProductSubarray.java | 13 +++ .../MaximumUnsortedSubarray.java | 8 +- src/geeksforgeeks/MedianOfKWindow.java | 46 ++++++++ src/geeksforgeeks/MeetingRoomsII.java | 27 +++++ .../MergeIntervalIntersection.java | 39 +++++++ src/geeksforgeeks/MinimumWindowSubstring.java | 7 +- src/geeksforgeeks/NQueens.java | 69 ++++++++++++ src/geeksforgeeks/NextGreaterElement.java | 49 ++++++++ src/geeksforgeeks/NextGreaterNumber.java | 105 +++++++++--------- src/geeksforgeeks/PathSumIII.java | 24 ++++ src/geeksforgeeks/ProductExceptSelf.java | 11 ++ src/geeksforgeeks/RedundantConnection.java | 44 ++++++++ src/geeksforgeeks/ReorganiseString.java | 11 ++ .../SearchElementInSortedAndRotatedArray.java | 3 + .../SingleElementInSortedArray.java | 44 ++++++++ src/geeksforgeeks/TaskLeastInterval.java | 13 ++- src/geeksforgeeks/ThreeSum.java | 35 ++++++ src/geeksforgeeks/TwoCityScheduling.java | 47 ++++++++ src/geeksforgeeks/WordBreak.java | 7 +- src/geeksforgeeks/WordBreakII.java | 28 +++++ 40 files changed, 1333 insertions(+), 67 deletions(-) create mode 100644 src/geeksforgeeks/ArrangeInQueue.java create mode 100644 src/geeksforgeeks/BasicCalculator.java create mode 100644 src/geeksforgeeks/EvaluvateExpressions.java create mode 100644 src/geeksforgeeks/FindMissingNumbers.java create mode 100644 src/geeksforgeeks/FirstAndLastOccurence.java create mode 100644 src/geeksforgeeks/FrequencySort.java create mode 100644 src/geeksforgeeks/GraphBiPartite.java create mode 100644 src/geeksforgeeks/IPOMaxProfit.java create mode 100644 src/geeksforgeeks/InserstionSortList.java create mode 100644 src/geeksforgeeks/IsSubsequence.java create mode 100644 src/geeksforgeeks/KClosestElements.java create mode 100644 src/geeksforgeeks/LargestDivisibleSubset.java create mode 100644 src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java create mode 100644 src/geeksforgeeks/MaxFreqStack.java create mode 100644 src/geeksforgeeks/MedianOfKWindow.java create mode 100644 src/geeksforgeeks/MergeIntervalIntersection.java create mode 100644 src/geeksforgeeks/NQueens.java create mode 100644 src/geeksforgeeks/PathSumIII.java create mode 100644 src/geeksforgeeks/RedundantConnection.java create mode 100644 src/geeksforgeeks/SingleElementInSortedArray.java create mode 100644 src/geeksforgeeks/ThreeSum.java create mode 100644 src/geeksforgeeks/TwoCityScheduling.java create mode 100644 src/geeksforgeeks/WordBreakII.java diff --git a/src/geeksforgeeks/ArrangeInQueue.java b/src/geeksforgeeks/ArrangeInQueue.java new file mode 100644 index 0000000..a0a3054 --- /dev/null +++ b/src/geeksforgeeks/ArrangeInQueue.java @@ -0,0 +1,27 @@ +package geeksforgeeks; + +// Input: +// [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] + +// Output: +// [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]] +public class ArrangeInQueue { + +// 1. Sort people by their height, shortest to tallest +// 2. Iterate and put each person to the correct position +// 2.a When placing the shortest person, all person to his left will be taller or equal height, since you are iterating in height sorted array, so put it at a index equal to its k value +// 2.b When placing the next shortest person, find a position, where count of positions to the left unoccupied plus the ones where same height person is placed, is equal to its k value +// 2.c Keep repeating + public int[][] reconstructQueue(int[][] people) { + List result= new ArrayList<>(); + Arrays.sort(people,(a,b)->{ + if(a[0]==b[0]) return a[1]-b[1]; + return b[0]-a[0]; + }); + + for(int[] x: people){ + result.add(x[1],x); + } + return result.toArray(new int[people.length][2]); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/BasicCalculator.java b/src/geeksforgeeks/BasicCalculator.java new file mode 100644 index 0000000..75a5f7f --- /dev/null +++ b/src/geeksforgeeks/BasicCalculator.java @@ -0,0 +1,56 @@ +package geeksforgeeks; + +// Input: "(1+(4+5+2)-3)+(6+8)" +// Output: 23 +public class BasicCalculator { + + public int calculate(String s) { + if(s==null || s.length()==0) return -1; + Deque deque= new ArrayDeque<>(); + int sign=1; + int number=0; + int result=0; + // let's take an edge case 2-(5-6)=3; + // at i=0 number=2 + // i=1 char ='-' update with prev seen sign res=sign*number reset number we are looking for next operand + //i=2 char='(' and sign is '-', push prev result and sign and reset result for calclating + // subproblem inside braces + // i=3 update number to 5 + // i=4 char ='-' update result as sign*number = 5 reset number and sign =-1 + //i=5 update number to 6 + // i=6 char=')' update result with existing number(res=5=> 5+(-1*6)) and sign inside the braces + // then pop, which is last seen sign outside brace=> -1 and pop again to get result outside brace + // add all to result; + + for(int i=0;i key) { + // high = mid - 1; + // } else { + // low = mid + 1; + // } + //else if decending + // if (arr[mid] < key) { + // high = mid - 1; + // } else { + // low = mid + 1; + // } + + // -3,1,-2,-3,-4,-5,-6 static int findBitonicPoint(int arr[], int n, int l, int r) { int mid = ((r + l) / 2) + l; diff --git a/src/geeksforgeeks/CourseSchedule.java b/src/geeksforgeeks/CourseSchedule.java index d0aed1d..2edf54f 100644 --- a/src/geeksforgeeks/CourseSchedule.java +++ b/src/geeksforgeeks/CourseSchedule.java @@ -6,7 +6,18 @@ import java.util.List; import java.util.Map; import java.util.Queue; +/** + * Input: numCourses = 2, prerequisites = [[1,0]] +Output: true +Explanation: There are a total of 2 courses to take. +To take course 1 you should have finished course 0. So it is possible. +Input: numCourses = 2, prerequisites = [[1,0],[0,1]] +Output: false +Explanation: There are a total of 2 courses to take. + To take course 1 you should have finished course 0, and to take course 0 you should + also have finished course 1. So it is impossible. + */ class CourseSchedule { public boolean canFinish(int numCourses, int[][] prerequisites) { @@ -45,4 +56,60 @@ public boolean canFinish(int numCourses, int[][] prerequisites) { return count == numCourses; } + + public boolean canFinishDFS(int numCourses, int[][] prerequisites) { + // this method basically finds a back-edge between nodes + // backedge is when doing a node(A)'s dfs, it puts A to a temp state + // while traversing A's child, if any of child dosen't have anymore child it's marked as completed + // if there are children it put's the current child to temp state and visits it's children + // so when doing a dfs for a node if it encounters a temp state node rather than completed node + // then that means there's a cycle we cannot complete the course + // (T) A \ + // / / + // (T) B / + // / \ / + // (Co) C D (T) while doing DFS for D's components we encounter A, but A is still in temp state + // + ArrayList[] adjList= new ArrayList[numCourses]; + for(int i=0;i(); + } + for(int[] preReq:prerequisites){ + adjList[preReq[0]].add(preReq[1]); + } + + int[] visited= new int[numCourses]; + for(int i=0;i[] adjList, int[] visited, int vertex){ + if(visited[vertex]==1) return false; + visited[vertex]=1; + for(int adj: adjList[vertex]){ + if(!dfs(adjList, visited, adj)) return false; + } + visited[vertex]=2; + return true; + } + // this is to get the order of course as output + public boolean dfs( List[] adjList, int[] visited, Listresult, int node){ + if(visited[node]==1) return false; + if(visited[node]==2) return true; + + visited[node]=1; + for(int adj: adjList[node]){ + if(!dfs(adjList, visited, result, adj)){ + return false; + } + } + visited[node]=2; + result.add(node); // this will keep track of which to fininsh first and last + return true; + } } \ No newline at end of file diff --git a/src/geeksforgeeks/EvaluvateExpressions.java b/src/geeksforgeeks/EvaluvateExpressions.java new file mode 100644 index 0000000..3086f9b --- /dev/null +++ b/src/geeksforgeeks/EvaluvateExpressions.java @@ -0,0 +1,59 @@ +package geeksforgeeks; + +// Given a string of numbers and operators, +// return all possible results from computing all the different possible ways to group numbers +// and operators. The valid operators are +, - and *. + +// Input: "2*3-4*5" +// Output: [-34, -14, -10, -10, 10] +// Explanation: +// (2*(3-(4*5))) = -34 +// ((2*3)-(4*5)) = -14 +// ((2*(3-4))*5) = -10 +// (2*((3-4)*5)) = -10 +// (((2*3)-4)*5) = 10 +public class EvaluvateExpressions { + public List diffWaysToCompute(String input) { + if(input==null) return Collections.emptyList(); + + Map> map= new HashMap<>(); + return bfsHelper(input, map); + + } + + public List bfsHelper(String input, Map> map){ + + if(map.containsKey(input)){ + return map.get(input); + } + + List result= new ArrayList<>(); + if(!input.contains("+") && !input.contains("-") && !input.contains("*")){ + result.add(Integer.parseInt(input)); + }else{ + // Split input string into two parts and solve them recursively + // for ex input = 2*3-4 output=2,-2 + // 2* | 3-4 => this right and left expression returns a list + // 2*3| -4 => this right and left expression returns another list + for(int i=0;i firstList= bfsHelper(input.substring(0,i),map); + List secondList= bfsHelper(input.substring(i+1),map); + for(int first: firstList){ + for(int second: secondList){ + if(input.charAt(i)=='+'){ + result.add(first+second); + }else if(input.charAt(i)=='-'){ + result.add(first-second); + }else{ + result.add(first*second); + } + } + } + } + } + } + map.put(input,result); + return result; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/EvaluvateRPN.java b/src/geeksforgeeks/EvaluvateRPN.java index 12e760f..6ea7f30 100644 --- a/src/geeksforgeeks/EvaluvateRPN.java +++ b/src/geeksforgeeks/EvaluvateRPN.java @@ -11,7 +11,7 @@ // = 17 + 5 // = 22 public class EvaluvateRPN { - public int evalRPN(String[] tokens) { + public int reversePolishNotation(String[] tokens) { if(tokens==null && tokens.length==0) return 0; Deque deque= new ArrayDeque<>(); for(String i: tokens){ diff --git a/src/geeksforgeeks/FindMinimumInRotatedArray.java b/src/geeksforgeeks/FindMinimumInRotatedArray.java index 72ecb2e..b22d779 100644 --- a/src/geeksforgeeks/FindMinimumInRotatedArray.java +++ b/src/geeksforgeeks/FindMinimumInRotatedArray.java @@ -18,7 +18,7 @@ public static int findMin(int[] nums) { if (nums[start] <= nums[end]) { return nums[start]; } - + // mid is compared against end, if mid is high, then the rotated part is right of mid if (nums[mid] < nums[end]) { end = mid; } else { @@ -28,6 +28,28 @@ public static int findMin(int[] nums) { return -1; } + public int findMinWithDuplicate(int[] nums) { + if(nums.length==1) return nums[0]; + int start=0; + int end= nums.length-1; + while(startnums[end]){ + start=mid+1; + }else{ + end=mid; + } + } + + } + + return nums[start]; + } + public static void main(String[] args) { int[] arr = { 7, 1, 2, 3, 4, 5, 6 }; findMin(arr); diff --git a/src/geeksforgeeks/FindMissingNumbers.java b/src/geeksforgeeks/FindMissingNumbers.java new file mode 100644 index 0000000..a889568 --- /dev/null +++ b/src/geeksforgeeks/FindMissingNumbers.java @@ -0,0 +1,40 @@ +package geeksforgeeks; + +// Input: [2, 3, 1, 8, 2, 3, 5, 1] +// Output: 4, 6, 7 +public class FindMissingNumbers { + + //Brute Force + // Set set = new HashSet<>(); + // for (int i = 0; i < nums.length; i++) set.add(i + 1); + // for (int i = 0; i < nums.length; i++) set.remove(nums[i]); + // return new ArrayList<>(set); + public List findDisappearedNumbers(int[] nums) { + if(nums.length==0) return Collections.emptyList(); + int i=0; + // cyclic sort begins + while(i result= new ArrayList<>(); + i=0; + while(itarget){ + end=mid-1; + }else{ + key=mid; + if(findMaxIndex) start=mid+1; + else end=mid-1; + } + } + + return key; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/FirstMissingPositive.java b/src/geeksforgeeks/FirstMissingPositive.java index 4074221..1efb0e7 100644 --- a/src/geeksforgeeks/FirstMissingPositive.java +++ b/src/geeksforgeeks/FirstMissingPositive.java @@ -1,5 +1,10 @@ package geeksforgeeks; +import java.awt.List; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + /** * https://leetcode.com/problems/first-missing-positive/ */ @@ -8,6 +13,7 @@ public class FirstMissingPositive { public int firstMissingPositive(int[] A) { int i = 0; while (i < A.length) { + // same cyclic sort, as missing numbers if (A[i] == i + 1 || A[i] <= 0 || A[i] > A.length) { i++; } else if (A[A[i] - 1] != A[i]) { @@ -48,6 +54,38 @@ public int firstMissingPositiveWithExtraSpace(int[] nums) { return -1; } + public List findKMissingPossitiveNumber(int[] A){ + int i = 0; + while (i < A.length) { + // same cyclic sort, as missing numbers + if (A[i] == i + 1 || A[i] <= 0 || A[i] > A.length) { + i++; + } else if (A[A[i] - 1] != A[i]) { + swap(A, i, A[i] - 1); + } else { + i++; + } + } + + List missingNumber= new ArrayList<>(); + Set additionalNumber= new HashSet<>(); + + i=0; + while(i map = new HashMap<>(); + for (char c : s.toCharArray()) + map.put(c, map.getOrDefault(c, 0) + 1); + + List [] bucket = new List[s.length() + 1]; + for (char key : map.keySet()) { + int frequency = map.get(key); + if (bucket[frequency] == null) bucket[frequency] = new ArrayList<>(); + bucket[frequency].add(key); + } + + StringBuilder sb = new StringBuilder(); + for (int pos = bucket.length - 1; pos >= 0; pos--) + if (bucket[pos] != null) + for (char c : bucket[pos]) + for (int i = 0; i < map.get(c); i++) + sb.append(c); + + return sb.toString(); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/GenerateParenthesis.java b/src/geeksforgeeks/GenerateParenthesis.java index b232d98..6608454 100644 --- a/src/geeksforgeeks/GenerateParenthesis.java +++ b/src/geeksforgeeks/GenerateParenthesis.java @@ -5,7 +5,17 @@ */ class GenerateParenthesis { - static void formParenthesis(char[] str, int pos, int n, int open, int close) { + public List generateParenthesis(int n) { + List result = new ArrayList<>(); + if (n == 0) + return result; + + generateUtil(n, new StringBuilder(), 0, 0, result); + + return result; + } + + public void generateUtil(int n, StringBuilder paran, int open, int close, List result) { if (close == n) { result.add(paran.toString()); return; diff --git a/src/geeksforgeeks/GraphBiPartite.java b/src/geeksforgeeks/GraphBiPartite.java new file mode 100644 index 0000000..27da2f5 --- /dev/null +++ b/src/geeksforgeeks/GraphBiPartite.java @@ -0,0 +1,53 @@ +package geeksforgeeks; + +/** + * Recall that a graph is bipartite if we can split it's set of nodes into + * two independent subsets A and B such that every edge in the graph has one node in A and + * another node in B. + * Input: [[1,3], [0,2], [1,3], [0,2]] => 0th node connects to 1,3 .. +Output: true +Explanation: +The graph looks like this: +0----1 +| | +| | +3----2 +We can divide the vertices into two groups: {0, 2} and {1, 3}. +Input: [[1,2,3], [0,2], [0,1,3], [0,2]] +Output: false +Explanation: +The graph looks like this: +0----1 +| \ | +| \ | +3----2 +We cannot find a way to divide the set of nodes into two independent subsets. + */ +public class GraphBiPartite { + public boolean isBipartite(int[][] graph) { + int[] color= new int[graph.length]; + + for(int i=0;i minQueue= new PriorityQueue<>((a,b)->Integer.compare(a[0],b[0])); + PriorityQueue maxQueue= new PriorityQueue<>((a,b)->Integer.compare(b[1],a[1])); + + for(int i=0;i findClosestElements(int[] arr, int k, int x) { + // since this is sorted array we are making use of binary search to get index of X and + // fix the range between index-K to index+K and doing normal PQ solution + int index= binarySearch(arr,x); + //if(index==-1) return Collections.emptyList(); + + int low= Math.max(0,index-k); + int high= Math.min(index+k,arr.length-1); + + PriorityQueue queue= new PriorityQueue<>((a, b)->Integer.compare(a.key,b.key)); + + for(int i=low;i<=high;i++){ + // taking abs value because question is askin closest in both signs + queue.offer(new Entry(Math.abs(arr[i]-x),i)); + } + List result= new ArrayList<>(); + int i=0; + while(i0){ + start--; + } + return start; + } +} + +class Entry{ + int key; + int value; + public Entry(int key, int value){ + this.key=key; + this.value=value; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/LargestDivisibleSubset.java b/src/geeksforgeeks/LargestDivisibleSubset.java new file mode 100644 index 0000000..67f81cc --- /dev/null +++ b/src/geeksforgeeks/LargestDivisibleSubset.java @@ -0,0 +1,59 @@ +package geeksforgeeks; + +/** + * Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of elements in this subset satisfies: + Si % Sj = 0 or Sj % Si = 0. + If there are multiple solutions, return any subset is fine. + Input: [2,3,4,6,10,8,24] + Output: [2,4,8,24] each pair's modulo is 0 + */ +public class LargestDivisibleSubset { + + /** + * if a%b==0 means a>b, if b>a then the ans is b itself + *inorder to have that we need to sort the array in increasing order + at first each val is ans to itself, then we come from last so a is higher in a%b + [2, 3, 4, 6, 8, 10, 24] + {2} {3} {4} {6} {8} {10} {24} + {8,24} + + {6,24} + + {4,8,24} + + {3,6,24} + + {2,4,8,24} + * + */ + public List largestDivisibleSubset(int[] nums) { + if(nums==null || nums.length==0) return Collections.emptyList(); + + Arrays.sort(nums); + List[] result= new ArrayList[nums.length]; + + int maxLength=0; + int resIndex=-1; + List re; + + for(int i=nums.length-1;i>=0;i--){ + result[i]=new ArrayList<>(); + re= new ArrayList<>(); + result[i].add(nums[i]); + for(int j=i+1;j re.size()){ + re=result[j]; + } + } + } + result[i].addAll(re); + if(result[i].size()>maxLength){ + maxLength=result[i].size(); + resIndex=i; + } + } + Collections.sort(result[resIndex]); + return result[resIndex]; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java b/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java new file mode 100644 index 0000000..305b73f --- /dev/null +++ b/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java @@ -0,0 +1,57 @@ +package geeksforgeeks; + +public class MaxDistinctElementAfterKRemoval { + // after removing k elements + static int maxDistinctNum(int[] arr, int n, int k) + { + // hash map to store + // frequency of each element + HashMap map = new HashMap<>(); + + // priority_queue 'pq' implemented as + // max heap + PriorityQueue pq = + new PriorityQueue<>(Collections.reverseOrder()); + + // storing frequency of each element in map + for (int i = 0; i < n; i++) { + if(map.containsKey(arr[i])) { + int val = map.get(arr[i]); + val++; + map.remove(arr[i]); + map.put(arr[i], val); + } + + else + map.put(arr[i], 1); + } + + // inserting frequency of each element in 'pq' + for (Map.Entry entry : map.entrySet()) { + pq.add(entry.getValue()); + } + + while (k > 0) { + // get the top element of 'pq' + int temp = pq.poll(); + + // decrement the popped element by 1 + temp--; + + // if true, then push the element in 'pq' + if (temp > 0) + pq.add(temp); + k--; + } + + // Count all those elements that appear + // once after above operations. + int res = 0; + while (pq.size() != 0) { + pq.poll(); + res++; + } + + return res; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MaxFreqStack.java b/src/geeksforgeeks/MaxFreqStack.java new file mode 100644 index 0000000..e628b82 --- /dev/null +++ b/src/geeksforgeeks/MaxFreqStack.java @@ -0,0 +1,46 @@ +package geeksforgeeks; + +public class MaxFreqStack { + + PriorityQueue maxQueue; + Map hashMap; + int sequence = 0; + + public FreqStack() { + + maxQueue= new PriorityQueue<>((a,b)->{ + if(a.frequency==b.frequency){ + return Integer.compare(b.sequence,a.sequence); + } + return Integer.compare(b.frequency,a.frequency); + }); + hashMap= new HashMap<>(); + } + + public void push(int x) { + hashMap.put(x, hashMap.getOrDefault(x, 0) + 1); + maxQueue.offer(new Entry(x, hashMap.get(x), sequence++)); + } + + public int pop() { + Entry temp = maxQueue.poll(); + hashMap.put(temp.val, temp.frequency - 1); + + return temp.val; + } +} + +// 1. val // value of the number +// 2. frequency // current frequency of the number when it was pushed to the heap +// 3. sequenceNumber // a sequence number, to know what number came first +class Entry { + int val; + int frequency; + int sequence; + + public Entry(int val, int frequency, int sequence) { + this.val = val; + this.frequency = frequency; + this.sequence = sequence; + } +} diff --git a/src/geeksforgeeks/MaximumProductSubarray.java b/src/geeksforgeeks/MaximumProductSubarray.java index 272be81..025e49e 100644 --- a/src/geeksforgeeks/MaximumProductSubarray.java +++ b/src/geeksforgeeks/MaximumProductSubarray.java @@ -42,6 +42,19 @@ public static int maxSumSubArray(int[] arr) { return sum; } + public int maxSubArray(int[] nums) { + if(nums==null || nums.length==0) return 0; + + int maxHere=0; + int max=Integer.MIN_VALUE; + for(int i:nums){ + maxHere=Math.max(i,maxHere+i); + max= Math.max(maxHere, max); + } + + return max; + } + public static void main(String[] args) { int arr[] = { 1, -2, -3, 0, 8, 7, -2 }; System.out.println("Maximum Sub array sum is " + maxSumSubArray(arr)); diff --git a/src/geeksforgeeks/MaximumUnsortedSubarray.java b/src/geeksforgeeks/MaximumUnsortedSubarray.java index 3a12502..3c1b06f 100644 --- a/src/geeksforgeeks/MaximumUnsortedSubarray.java +++ b/src/geeksforgeeks/MaximumUnsortedSubarray.java @@ -35,7 +35,13 @@ public static ArrayList subarraySort(final ArrayList A) { break; } } - + // [1, 3, 2, 0, -1, 7, 10] + // the initial finding gives you 3 and -1 however the original sort array is + // [1, -1, 0, 2, 3, 7, 10], + //The problem here is that the smallest number of our subarray is ‘-1’ + // which dictates that we need to include more numbers from the beginning of the array + // We will have a similar problem + //if the maximum of the subarray is bigger than some elements at the end of the array // find min and max in the range [start, end] int min = A.get(start); int max = A.get(start); diff --git a/src/geeksforgeeks/MedianOfKWindow.java b/src/geeksforgeeks/MedianOfKWindow.java new file mode 100644 index 0000000..2e3ad95 --- /dev/null +++ b/src/geeksforgeeks/MedianOfKWindow.java @@ -0,0 +1,46 @@ +package geeksforgeeks; + +public class MedianOfKWindow { + public double[] medianSlidingWindow(int[] nums, int k) { + MedianQueue medianHeap= new MedianQueue(); + + double[] result= new double[nums.length-k+1]; + + int resultIndex=0; + + for( int i=0;i minQueue= new PriorityQueue<>(); + PriorityQueue maxQueue= new PriorityQueue<>(Collections.reverseOrder()); + + public void offer(int x){ + maxQueue.offer(x); + minQueue.offer(maxQueue.poll()); + if(maxQueue.size() minQueue.size() ? maxQueue.peek() : ((long)maxQueue.peek() + minQueue.peek()) * 0.5; + } + public int size(){ + return minQueue.size() + maxQueue.size(); + } + + public boolean remove(int x){ + return minQueue.remove(x) || maxQueue.remove(x); + } + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MeetingRoomsII.java b/src/geeksforgeeks/MeetingRoomsII.java index abff5e9..bdab7a8 100644 --- a/src/geeksforgeeks/MeetingRoomsII.java +++ b/src/geeksforgeeks/MeetingRoomsII.java @@ -36,4 +36,31 @@ public int minMeetingRooms(List intervals) { return queue.size(); } + + // Input: schedule = [[[1,2],[5,6]],[[1,3]],[[4,10]]] + // Output: [[3,4]] + + public List employeeFreeTime(List> schedule) { + PriorityQueue que = new PriorityQueue<>((a, b) -> a.start - b.start); + + for (List list : schedule) { + for (Interval i : list) { + que.add(i); + } + } + + List rt = new ArrayList<>(); + int max = -1; + while (!que.isEmpty()) { + Interval top = que.poll(); + if (max != -1 && top.start > max) { + rt.add(new Interval(max, top.start)); + } + max = Math.max(max, top.end); + } + + return rt; + } + + } diff --git a/src/geeksforgeeks/MergeIntervalIntersection.java b/src/geeksforgeeks/MergeIntervalIntersection.java new file mode 100644 index 0000000..a17ee6f --- /dev/null +++ b/src/geeksforgeeks/MergeIntervalIntersection.java @@ -0,0 +1,39 @@ +package geeksforgeeks; + +/** + * +Given two lists of closed intervals, each list of intervals is pairwise disjoint and in sorted order. +Return the intersection of these two interval lists. + +Input: A = [[0,2],[5,10],[13,23],[24,25]], B = [[1,5],[8,12],[15,24],[25,26]] +Output: [[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]] + */ +public class MergeIntervalIntersection { + + // inorder to find a overlapping part alone between two intervals + // we take + // start = max(a.start, b.start) + // end = min(a.end, b.end) + // That is, the highest start time and the lowest end time will be the overlapping interval. + public int[][] intervalIntersection(int[][] A, int[][] B) { + int i=0; + int j=0; + List result= new ArrayList<>(); + while(i=B[j][0] && A[i][0]<=B[j][1] || + B[j][0]>=A[i][0] && B[j][0]<=A[i][1]){ // this condition checks if there'a ovelapping + //A=>[0,2], B=> [1,5] + result.add(new int[]{Math.max(A[i][0],B[j][0]), Math.min(A[i][1],B[j][1])}); + } + // once added to result move the i or j based on lesser end time + if(A[i][1] s.length()) { return ""; + } Map map = new HashMap<>(); for (char c : t.toCharArray()) { map.put(c, map.getOrDefault(c, 0) + 1); } - Map map = new HashMap<>(); - for (char c : t.toCharArray()) { - map.put(c, map.getOrDefault(c, 0) + 1); - } + int counter = map.size(); int begin = 0, end = 0; @@ -62,4 +60,3 @@ public static String minWindow(String s, String t) { return s.substring(head, head + len); } } -} \ No newline at end of file diff --git a/src/geeksforgeeks/NQueens.java b/src/geeksforgeeks/NQueens.java new file mode 100644 index 0000000..c9aacf6 --- /dev/null +++ b/src/geeksforgeeks/NQueens.java @@ -0,0 +1,69 @@ +package geeksforgeeks; + +public class NQueens { + + public List> solveNQueens(int n) { + if(n==0) return Collections.emptyList(); + + List> result= new ArrayList<>(); + char[][] board= new char[n][n]; + for(int i=0;i> result) { + + if(row==board.length){ + result.add(construct(board)); + return; + } + for(int i=0;i= 0 && j < chess.length; i--, j++) { + if (chess[i][j] == 'Q') { + return false; + } + } + //check 135 + for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) { + if (chess[i][j] == 'Q') { + return false; + } + } + return true; + } + + private List construct(char[][] chess) { + List path = new ArrayList<>(); + for (int i = 0; i < chess.length; i++) { + path.add(new String(chess[i])); + } + return path; + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/NextGreaterElement.java b/src/geeksforgeeks/NextGreaterElement.java index 41dea07..a1f444a 100644 --- a/src/geeksforgeeks/NextGreaterElement.java +++ b/src/geeksforgeeks/NextGreaterElement.java @@ -30,6 +30,55 @@ public static void printNGE() { } +// Input: nums1 = [4,1,2], nums2 = [1,3,4,2]. +// Output: [-1,3,-1] +// Explanation: +// For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1. +// For number 1 in the first array, the next greater number for it in the second array is 3. +// For number 2 in the first array, there is no next greater number for it in the second array, so output -1. + public int[] nextGreaterElement(int[] findNums, int[] nums) { + int[] ret = new int[findNums.length]; + ArrayDeque stack = new ArrayDeque<>(); + HashMap map = new HashMap<>(); + for(int i = nums.length - 1; i >= 0; i--) { + while(!stack.isEmpty() && stack.peek() <= nums[i]) { + stack.pop(); + } + if(stack.isEmpty()) map.put(nums[i], -1); + else map.put(nums[i], stack.peek()); + stack.push(nums[i]); + } + for(int i = 0; i < findNums.length; i++) { + ret[i] = map.get(findNums[i]); + } + return ret; + } + +// Input: [1,2,1] +// Output: [2,-1,2] +// Explanation: The first 1's next greater number is 2; +// The number 2 can't find next greater number; +// The second 1's next greater number needs to search circularly, which is also 2. + public static int[] nextGreaterElementCircular(int[] arr){ + if(nums==null || nums.length==0) return new int[0]; + int[] result= new int[nums.length]; + int n= nums.length; + Arrays.fill(result, -1); + Deque deque= new ArrayDeque<>(); + // to mimic the circular array we iterate for 2*n because input [1,2,1] will be like [1,2,1,1,2,1] + // and we take mod of 'n' to update the correct index + for(int i=0;i<2*nums.length;i++){ + + while(!deque.isEmpty() && nums[deque.getLast()]= 0 && arr[i] >= arr[i + 1]) + i--; - // 6, 9, 3, 8, 6, 5, 2 - public void findNextGreaterNumber(int[] number) { - int lastDigitSeen = number[number.length - 1]; - int i; - int j; - for (i = number.length - 2; i >= 0; i--) { - // if this digit is where the sorted ordering breaks - if (lastDigitSeen > number[i]) { - break; - } - lastDigitSeen = number[i]; - } + // If no such digit is found, its the edge case 1. + if (i < 0) return -1; - if (i >= 0) // we found the digit breaking the sorted ordering - { - // find the next smallest digit greater than num[i] in the right sub-array from number[i+1 to end] - for (j = number.length - 1; j > i; j--) { - if (number[j] > number[i]) { - break; - } - } + // II) Find the smallest digit on right side of (i)'th + // digit that is greater than number[i] + int j = arr.length - 1; + while (arr[j] <= arr[i]) + j--; - // swap digits at indices 'i' and 'j' - swap(number, i, j); - System.out.println(Arrays.toString(number)); - // sort the sub-array - number[i+1 to end] - sortSubarray(number, i + 1, number.length - 1); - } + swap(arr, i, j); + reverse(arr, i + 1, arr.length - 1); + + try { + return Integer.valueOf(String.valueOf(arr)); + } catch (NumberFormatException e) { + return -1; } +} + +static void swap(char[] arr, int i, int j) { + arr[i] ^= arr[j]; + arr[j] ^= arr[i]; + arr[i] ^= arr[j]; +} + +static void reverse(char[] arr, int i, int j) { + int l = i, h = j; + while (l < h) + swap(arr, l++, h--); +} + public static void main(String[] args) { NextGreaterNumber solution = new NextGreaterNumber(); - int[] number = {6, 9, 3, 8, 6, 5, 2}; - // 6938652 - // 6983652 - // 6982356 - // i =3 - //534976 - solution.findNextGreaterNumber(number); - - System.out.println("Next greater number is: "); - for (int i = 0; i < number.length; i++) { - System.out.print(number[i]); - } + System.out.println("Next greater number is: "+solution.nextGreaterElement(6938652)); + } } diff --git a/src/geeksforgeeks/PathSumIII.java b/src/geeksforgeeks/PathSumIII.java new file mode 100644 index 0000000..0100122 --- /dev/null +++ b/src/geeksforgeeks/PathSumIII.java @@ -0,0 +1,24 @@ +package geeksforgeeks; +public class PathSumIII { + List list= new ArrayList<>(); + int count=0; + public int pathSum(TreeNode root, int sum) { + if(root==null) return 0; + list.add(root.val); + int left=pathSum(root.left,sum); + int right= pathSum(root.right,sum); + + int k=0; + for(int i=list.size()-1;i>=0;i--){ // coming in reverse order, inorder to avoid considering + // head node + k+=list.get(i); + if(sum==k){ + count++; + } + } + + list.remove(list.size()-1); + return count; + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/ProductExceptSelf.java b/src/geeksforgeeks/ProductExceptSelf.java index e70c422..d25d922 100644 --- a/src/geeksforgeeks/ProductExceptSelf.java +++ b/src/geeksforgeeks/ProductExceptSelf.java @@ -24,9 +24,20 @@ public static int[] productExceptSelf(int[] nums) { int n = nums.length; int[] res = new int[n]; res[0] = 1; + for (int i = 1; i < n; i++) { res[i] = res[i - 1] * nums[i - 1]; } + // once building the left product instead of having a new array to calculate rightsum + // we use a variable to store last seen value + // for number 2 3 4 5 + // the left product array is 1 2 2*3 2*3*4 + + // for rightProd during step1 2 3 4 5 right is 1 so last product value retained + // 2*3*4 + // during step 2 the right becomes 5(1*nums[i]=>5) + // so for value 4(length-2) the left product is 2*3 multiplying with 5 becomes 2*3*5 + // during step 3 the right is updated to (5*nums[i]=>4) 20 int right = 1; for (int i = n - 1; i >= 0; i--) { res[i] *= right; diff --git a/src/geeksforgeeks/RedundantConnection.java b/src/geeksforgeeks/RedundantConnection.java new file mode 100644 index 0000000..c122fed --- /dev/null +++ b/src/geeksforgeeks/RedundantConnection.java @@ -0,0 +1,44 @@ +package geeksforgeeks; + +public class RedundantConnection { + public int[] findRedundantConnection(int[][] edges) { + DisjointSet set= new DisjointSet(edges.length); + + for(int[]edge: edges){ + if(!set.union(edge[0]-1, edge[1]-1)) return edge; + } + return new int[]{-1,-1}; + } + + static class DisjointSet{ + int[] parent; + int[] rank; + + public DisjointSet(int n){ + this.parent= new int[n]; + this.rank= new int[n]; + } + + public int find(int x){ + if(parent[x]==0) return x; + return parent[x]=find(parent[x]); + } + + public boolean union(int x, int y){ + int rootX= find(x); + int rootY= find(y); + + if(rootX==rootY) return false; + + if(rank[rootX] 0) { if(k >= res.length) k=1; @@ -44,6 +54,7 @@ public String reorganizeString(String s) { } public static void main(String[] args) { + new ReorganiseString().reorganizeString("aabccdeeee"); } } \ No newline at end of file diff --git a/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java b/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java index 26d6095..9ee10b5 100644 --- a/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java +++ b/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java @@ -18,6 +18,8 @@ public static void main(String[] args) { // 4, 5, 0, 1, 2, 3 int searchI(int[] nums, int target) { + // If arr[start] <= arr[middle], the numbers from start to middle are sorted in ascending order. + // Else, the numbers from middle+1 to end are sorted in ascending order. int start = 0; int end = nums.length - 1; while (start <= end) { @@ -73,6 +75,7 @@ else if(nums[left] <= nums[mid]) else right = mid-1; } } + return false; } //[2,5,6,0,0,1,2] // 0 diff --git a/src/geeksforgeeks/SingleElementInSortedArray.java b/src/geeksforgeeks/SingleElementInSortedArray.java new file mode 100644 index 0000000..0b2d43a --- /dev/null +++ b/src/geeksforgeeks/SingleElementInSortedArray.java @@ -0,0 +1,44 @@ +package geeksforgeeks; + +/** + * You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once. + * Find this single element that appears only once. + */ +public class SingleElementInSortedArray { + public int singleNonDuplicate(int[] nums) { + if(nums==null || nums.length==0) return 0; + + int left=0; + int right= nums.length-1; + // for 1,1,2,3,3,4,4,8,8 + // when mid is at 4 and right-mid is even, means the rest elements are only pairs, so we check + // left side by right=mid-2 + // when mid is at 3 and right-mid is odd means the 3's duplicate is present in right and rest + //are all pairs only so we check left side by right=mid-1 + // when mid is 4 => nums[mid]==nums[mid-1] + // when mid is 3 => nums[mid]==nums[mid+1] + while(left 0. + // if al elements are done, we're done too. + // Move time forward by n + 1 + // Return time in the end. while (!queue.isEmpty()) { - int k = n + 1; + int k = n + 1; //each time fill k elements, if k is not full, that's the idle List tempList = new ArrayList<>(); while (k > 0 && !queue.isEmpty()) { Map.Entry top = queue.poll(); @@ -40,6 +47,6 @@ public static int leastInterval(char[] tasks, int n) { public static void main(String[] args) { char[] arr = "AAAAAABCDEFG".toCharArray(); - leastInterval(arr, 2); + System.out.println(leastInterval(arr, 2)); } } diff --git a/src/geeksforgeeks/ThreeSum.java b/src/geeksforgeeks/ThreeSum.java new file mode 100644 index 0000000..7f7b26b --- /dev/null +++ b/src/geeksforgeeks/ThreeSum.java @@ -0,0 +1,35 @@ +package geeksforgeeks; + +public class ThreeSum { + public List> threeSum(int[] nums) { + if(nums==null || nums.length==0) return Collections.emptyList(); + + Arrays.sort(nums); + List> result= new ArrayList<>(); + for(int i=0;isum){ + right--; + } + } + } + } + + return result; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/TwoCityScheduling.java b/src/geeksforgeeks/TwoCityScheduling.java new file mode 100644 index 0000000..12a088a --- /dev/null +++ b/src/geeksforgeeks/TwoCityScheduling.java @@ -0,0 +1,47 @@ +package geeksforgeeks; + +/** + * There are 2N people a company is planning to interview. + * The cost of flying the i-th person to city A is costs[i][0], and the cost of flying the i-th person to city B is costs[i][1]. + * Return the minimum cost to fly every person to a city such that exactly N people arrive in each city. + * Input: [[10,20],[30,200],[400,50],[30,20]] + * Output: 110 + * Explanation: + The first person goes to city A for a cost of 10. + The second person goes to city A for a cost of 30. + The third person goes to city B for a cost of 50. + The fourth person goes to city B for a cost of 20. + + * The total minimum cost is 10 + 30 + 50 + 20 = 110 to have half the people interviewing in each city + * + */ +public class TwoCityScheduling { + public int twoCitySchedCost(int[][] costs) { + // for input [[10,20],[30,200],[400,50],[30,20]] + // let's send all to A, the cost'd be => 10+30+400+30= 470 + // we need to remove one half to save some money + // what we can do is take the difference in each input + // (10-20) (30-200) (400-50) (30-20) + // [-10, -170, 350, 10] + // what the above array indicates is that for i'th candidate=>[10,20] we will save 10 in sending to A + // when i=2 we will have to spend 350 more to bring to A city so we sort by arr[0]-arr[1] + // greedily we take negative val candidates to A and rest to B for this input + PriorityQueue queue= new PriorityQueue<>((a,b)->(a[0] - a[1]) - (b[0] - b[1])); + + for(int[] cost: costs){ + queue.offer(cost); + } + int result=0; + int k=0; + while(k wordDict) { if (s == null) { diff --git a/src/geeksforgeeks/WordBreakII.java b/src/geeksforgeeks/WordBreakII.java new file mode 100644 index 0000000..1aa8a46 --- /dev/null +++ b/src/geeksforgeeks/WordBreakII.java @@ -0,0 +1,28 @@ +package geeksforgeeks; + +public class WordBreakII { + public List wordBreak(String s, List wordDict) { + Map> cache = new HashMap<>(); + backtrack(s,wordDict, cache); + return cache.get(s); + } + + public List backtrack(String s, List wordDict, Map> cache){ + + if(cache.containsKey(s)) return cache.get(s); + + List result = new ArrayList<>(); + for(String word: wordDict) { + if(!s.startsWith(word)) continue; // string does not start with this word? + String next = s.substring(word.length()); + if(next.isEmpty()) { // awesome! + result.add(word); + continue; + } + for(String sub: backtrack(next, wordDict, cache)) + result.add(word + " " + sub); + } + cache.put(s, result); + return result; + } +} \ No newline at end of file From d7052a5cecf68adc27e57679de92cb2cacb18869 Mon Sep 17 00:00:00 2001 From: vignesh Date: Mon, 15 Jun 2020 20:25:35 +0530 Subject: [PATCH 34/51] new branch --- src/geeksforgeeks/FindMinimumInRotatedArray.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/geeksforgeeks/FindMinimumInRotatedArray.java b/src/geeksforgeeks/FindMinimumInRotatedArray.java index b22d779..1ccb519 100644 --- a/src/geeksforgeeks/FindMinimumInRotatedArray.java +++ b/src/geeksforgeeks/FindMinimumInRotatedArray.java @@ -49,7 +49,6 @@ public int findMinWithDuplicate(int[] nums) { return nums[start]; } - public static void main(String[] args) { int[] arr = { 7, 1, 2, 3, 4, 5, 6 }; findMin(arr); From d06d85082c4ebed1468c6a8e2355d63bbb25b3b6 Mon Sep 17 00:00:00 2001 From: vignesh Date: Sun, 16 Aug 2020 23:00:19 +0530 Subject: [PATCH 35/51] updates and new problems --- src/geeksforgeeks/AdvantageShuffle.java | 4 + src/geeksforgeeks/AircraftOptimization.java | 13 ++ .../AlternateOddAndEvenNumbers.java | 20 ++- src/geeksforgeeks/AngleOfClock.java | 15 ++ .../BuyAndSellStockAtMostTwice.java | 91 ++++------- src/geeksforgeeks/Candy.java | 12 +- .../CheckPalindromePermutation.java | 14 ++ .../CheckPermutationContains.java | 14 ++ src/geeksforgeeks/ClosestNumbers.java | 9 ++ .../ConstructTreeFromInorderAndPreorder.java | 43 +++-- src/geeksforgeeks/ContainerWithMostWater.java | 36 +++++ src/geeksforgeeks/CountAndSay.java | 2 +- .../CountDistinctKSubString.java | 40 ----- .../CountNumbersLessThanSelf.java | 124 +++++++++++---- src/geeksforgeeks/CountOfSmallNumbers.java | 56 ------- src/geeksforgeeks/CountingInversion.java | 6 +- src/geeksforgeeks/CourseSchedule.java | 7 +- src/geeksforgeeks/CourseScheduling.java | 108 ------------- src/geeksforgeeks/DecodeString.java | 22 ++- src/geeksforgeeks/DesignTicTacToe.java | 49 +++++- src/geeksforgeeks/DungeonGame.java | 64 ++++++++ src/geeksforgeeks/FileSystem1166.java | 26 ++- src/geeksforgeeks/FileSystemI.java | 52 ++++-- .../FindNumberOfOccurrences.java | 43 ----- .../FirstNonReapeatingCharacterStream.java | 10 ++ src/geeksforgeeks/Flatten2DVector.java | 15 ++ src/geeksforgeeks/FrequencySort.java | 10 +- src/geeksforgeeks/GameOfLife.java | 89 +++++------ src/geeksforgeeks/GenerateParenthesis.java | 11 +- src/geeksforgeeks/GrammarMistake.java | 143 +++++++---------- src/geeksforgeeks/HouseRobber.java | 19 +++ src/geeksforgeeks/IPOMaxProfit.java | 17 +- src/geeksforgeeks/InOrderSuccessor.java | 4 +- src/geeksforgeeks/InserstionSortList.java | 39 ++--- src/geeksforgeeks/IntersectionOfArrays.java | 31 ++++ src/geeksforgeeks/IsomorphicArray.java | 30 ++-- src/geeksforgeeks/IsomorphicString.java | 5 +- src/geeksforgeeks/JumpsToReachEnd.java | 13 +- src/geeksforgeeks/KClosestElements.java | 5 + src/geeksforgeeks/KmostFrequentLetters.java | 6 +- src/geeksforgeeks/LIS2DMatrix.java | 94 ++++++----- src/geeksforgeeks/LargestDivisibleSubset.java | 11 +- .../LargestSubArrayWithZeroesAndOnes.java | 114 ++++++++------ .../LongestConsequtiveSequence.java | 37 ++++- src/geeksforgeeks/LongestIncreasingPath.java | 66 -------- .../LongestSpanWithSameSumArray.java | 64 +++++--- .../MaxDistinctElementAfterKRemoval.java | 92 +++++++++-- src/geeksforgeeks/MaxFreqStack.java | 46 ++++-- src/geeksforgeeks/MaxHistogram.java | 70 +++++--- src/geeksforgeeks/MaxProductString.java | 20 ++- src/geeksforgeeks/MaxWidthOfBinaryTree.java | 56 +++++++ src/geeksforgeeks/MaximumGap.java | 70 ++++++++ .../MaximumUnsortedSubarray.java | 11 +- src/geeksforgeeks/MinimumBribes.java | 50 ++++++ .../MinimumDistanceBetweenTwoNumbers.java | 19 ++- src/geeksforgeeks/MinimumSwapSortArray.java | 136 ++++++++++++---- .../MinimumWindowSubsequence.java | 97 ++++++++---- src/geeksforgeeks/NQueens.java | 25 ++- src/geeksforgeeks/NewRoadsMST.java | 149 +++++++----------- src/geeksforgeeks/NextGreaterElement.java | 23 +-- src/geeksforgeeks/OverlappingIntervals.java | 40 +++++ src/geeksforgeeks/PalindromePartion.java | 72 +++++---- src/geeksforgeeks/PalindromicSubSequence.java | 11 +- src/geeksforgeeks/PartitionLabel.java | 10 ++ src/geeksforgeeks/PascalsTriangle.java | 46 +++--- src/geeksforgeeks/PathSumIII.java | 41 ++++- src/geeksforgeeks/PeakElement.java | 58 +++---- src/geeksforgeeks/PerfectSquare.java | 52 ++++-- src/geeksforgeeks/PreOrderInOrderTree.java | 33 ---- src/geeksforgeeks/QueensAttackKing.java | 18 ++- src/geeksforgeeks/QueensAttacktheKing.java | 50 ------ src/geeksforgeeks/RaceCar.java | 50 ------ src/geeksforgeeks/ReconstructItenary.java | 43 +++++ src/geeksforgeeks/ReorderLogs.java | 19 ++- src/geeksforgeeks/ReorganiseString.java | 67 ++++---- src/geeksforgeeks/RestorepAddresses.java | 42 +++++ src/geeksforgeeks/ReverseWordsInString.java | 38 +++++ src/geeksforgeeks/SameTree.java | 60 +++++++ .../SubArraySumDivisibleByK.java | 42 +++++ src/geeksforgeeks/SurroundedRegions.java | 129 ++++++++++----- .../UnSortedContiguousSubArray.java | 40 ----- src/geeksforgeeks/UniquePath.java | 15 ++ .../UnsortedSubarrayProblems.java | 51 ------ src/geeksforgeeks/UrlEncode.java | 56 ++++--- src/geeksforgeeks/ValidIpAddresses.java | 39 ----- src/geeksforgeeks/ValidSuduko.java | 10 ++ src/geeksforgeeks/ValidateIpAddresses.java | 41 +++++ src/geeksforgeeks/WordDictionary.java | 66 ++++++++ src/geeksforgeeks/temp.xml | 0 89 files changed, 2358 insertions(+), 1448 deletions(-) create mode 100644 src/geeksforgeeks/AngleOfClock.java create mode 100644 src/geeksforgeeks/ContainerWithMostWater.java delete mode 100644 src/geeksforgeeks/CountDistinctKSubString.java delete mode 100644 src/geeksforgeeks/CountOfSmallNumbers.java delete mode 100644 src/geeksforgeeks/CourseScheduling.java create mode 100644 src/geeksforgeeks/DungeonGame.java delete mode 100644 src/geeksforgeeks/FindNumberOfOccurrences.java delete mode 100644 src/geeksforgeeks/LongestIncreasingPath.java create mode 100644 src/geeksforgeeks/MaxWidthOfBinaryTree.java create mode 100644 src/geeksforgeeks/MaximumGap.java create mode 100644 src/geeksforgeeks/MinimumBribes.java create mode 100644 src/geeksforgeeks/OverlappingIntervals.java delete mode 100644 src/geeksforgeeks/PreOrderInOrderTree.java delete mode 100644 src/geeksforgeeks/QueensAttacktheKing.java delete mode 100644 src/geeksforgeeks/RaceCar.java create mode 100644 src/geeksforgeeks/ReconstructItenary.java create mode 100644 src/geeksforgeeks/RestorepAddresses.java create mode 100644 src/geeksforgeeks/ReverseWordsInString.java create mode 100644 src/geeksforgeeks/SameTree.java create mode 100644 src/geeksforgeeks/SubArraySumDivisibleByK.java delete mode 100644 src/geeksforgeeks/UnSortedContiguousSubArray.java delete mode 100644 src/geeksforgeeks/UnsortedSubarrayProblems.java delete mode 100644 src/geeksforgeeks/ValidIpAddresses.java create mode 100644 src/geeksforgeeks/ValidateIpAddresses.java create mode 100644 src/geeksforgeeks/WordDictionary.java create mode 100644 src/geeksforgeeks/temp.xml diff --git a/src/geeksforgeeks/AdvantageShuffle.java b/src/geeksforgeeks/AdvantageShuffle.java index 79b57ec..6319ff8 100644 --- a/src/geeksforgeeks/AdvantageShuffle.java +++ b/src/geeksforgeeks/AdvantageShuffle.java @@ -5,6 +5,8 @@ // Return any permutation of A that maximizes its advantage with respect to B. //Input: A = [12,24,8,32], B = [13,25,32,11] //Output: [24,32,8,12] +// Input: A = [2,7,11,15], B = [1,10,4,11] +// Output: [2,11,7,15] public class AdvantageShuffle { public int[] advantageCount(int[] A, int[] B) { Arrays.sort(A); @@ -15,6 +17,8 @@ public int[] advantageCount(int[] A, int[] B) { } int[] result= new int[A.length]; // new placeholder for result; int lo=0; int hi= A.length-1; // start and end index + //B is transformed to [32,25,13,11] + //A is transformed to [8,12,24,32] while(!pq.isEmpty()){ Integer[] temp= pq.poll(); int index=temp[1]; diff --git a/src/geeksforgeeks/AircraftOptimization.java b/src/geeksforgeeks/AircraftOptimization.java index 8f5f2dc..ef0eb40 100644 --- a/src/geeksforgeeks/AircraftOptimization.java +++ b/src/geeksforgeeks/AircraftOptimization.java @@ -8,6 +8,19 @@ /** * https://leetcode.com/discuss/interview-question/373202 + * Given 2 lists a and b. Each element is a pair of integers where the first integer represents the unique id and the second integer represents a value. + * Your task is to find an element from a and an element form b such that the sum of their values is less or equal to target and as close to target as possible. + * Return a list of ids of selected elements. If no pair is possible, return an empty list. + * + * a = [[1, 2], [2, 4], [3, 6]] + b = [[1, 2]] + target = 7 + + Output: [[2, 1]] + + Explanation: + There are only three combinations [1, 1], [2, 1], and [3, 1], which have a total sum of 4, 6 and 8, respectively. + Since 6 is the largest sum that does not exceed 7, [2, 1] is the optimal pair. */ public class AircraftOptimization { diff --git a/src/geeksforgeeks/AlternateOddAndEvenNumbers.java b/src/geeksforgeeks/AlternateOddAndEvenNumbers.java index 027e347..28f12b7 100644 --- a/src/geeksforgeeks/AlternateOddAndEvenNumbers.java +++ b/src/geeksforgeeks/AlternateOddAndEvenNumbers.java @@ -3,31 +3,41 @@ // (0, 2, 4,..) and negative numbers at odd indexes (1, 3, // 5, ..) +import java.util.Arrays; + /** * https://www.geeksforgeeks.org/rearrange-positive-and-negative-numbers-publish/ + * An array contains both positive and negative numbers in random order. + * Rearrange the array elements so that positive and negative numbers are placed alternatively. + * If there are more positive numbers they appear at the end of the array. + * If there are more negative numbers, they too appear in the end of the array. + * [-1, 2, -3, 4, 5, 6, -7, 8, 9] + * output [9, -7, 8, -3, 5, -1, 2, 4, 6] or[4, -3, 5, -1, 6, -7, 2, 8, 9] */ class AlternateOddAndEvenNumbers { static void rearrange(int arr[], int n) { //-1, 2, -3, 4, 5, 6, -7, 8, 9 - int i = -1, temp = 0; + int i = 0, temp = 0; for (int j = 0; j < n; j++) { if (arr[j] < 0) { - i++; temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; + i++; } } - - int pos = i + 1, neg = 0; + // we have seggregated positive and negative elements + System.out.println(Arrays.toString(arr)); + int pos = i , neg = 0; + // pos indicates start of positive integer, neg starts from 0; while (pos < n && neg < pos && arr[neg] < 0) { temp = arr[neg]; arr[neg] = arr[pos]; arr[pos] = temp; pos++; - neg += 2; + neg += 2; // need to skip next element as output should be alternative } } diff --git a/src/geeksforgeeks/AngleOfClock.java b/src/geeksforgeeks/AngleOfClock.java new file mode 100644 index 0000000..874caef --- /dev/null +++ b/src/geeksforgeeks/AngleOfClock.java @@ -0,0 +1,15 @@ +package geeksforgeeks; + +public class AngleOfClock { + public double angleClock(int hours, int minutes) { + // every hour is 30* (360/12) because 12 hrs in clock + // every min is 6* (360/60) because 60 mins per hr + // we take mod of 12 because 12th hr needs to be 0* + double hour= (double) (hours%12 + (double)minutes/60)*30; + double min= minutes*6; + double absAngle= Math.abs(hour-min); + if(absAngle>180) absAngle= 360-absAngle; // this is because when time is 0.02 the angel will be 358 + + return absAngle; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java b/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java index 48c1fe1..02e5d09 100644 --- a/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java +++ b/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java @@ -4,51 +4,6 @@ * https://www.geeksforgeeks.org/maximum-profit-by-buying-and-selling-a-share-at-most-twice/ */ class BuyAndSellStockAtMostTwice { - // { 2, 30, 15, 10, 8, 25, 80 }; - // 78,72,72,72,72,55 - // - static int maxProfit(int price[], int n) { - - int profit[] = new int[n]; - /* - * Get the maximum profit with only one transaction allowed. After this loop, - * profit[i] contains maximum profit from price[i..n-1] using at most one trans. - */ - int max_price = price[n - 1]; - for (int i = n - 2; i >= 0; i--) { - // max_price has maximum of price[i..n-1] - if (price[i] > max_price) - max_price = price[i]; - - // we can get profit[i] by taking maximum of: - // a) previous maximum, i.e., profit[i+1] - // b) profit by buying at price[i] and selling at - // max_price - profit[i] = Math.max(profit[i + 1], max_price - price[i]); - } - - /* - * Get the maximum profit with two transactions allowed After this loop, - * profit[n-1] contains the result - */ - int min_price = price[0]; - for (int i = 1; i < n; i++) { - // min_price is minimum price in price[0..i] - if (price[i] < min_price) - min_price = price[i]; - - // Maximum profit is maximum of: - // a) previous maximum, i.e., profit[i-1] - // b) (Buy, Sell) at (min_price, price[i]) and add - // profit of other trans. stored in profit[i] - profit[i] = Math.max(profit[i - 1], profit[i] + (price[i] - min_price)); - - //1->28+72 - // - - } - return profit[n - 1]; - } public static void main(String args[]) { int price[] = { 2, 30, 15, 10, 8, 25, 80 }; @@ -56,20 +11,40 @@ public static void main(String args[]) { System.out.println("Maximum Profit = " + maxProfit(price, n)); } + /** + * the idea is when we find a profit which is from + * i to n, we can break it in to i to k, k+1 to n + * in this manner at each point we can calculate profit from + * (left min element to current element) and (current element to right max element) + * the second part of the above eq can be acieved by coming from right to left + * for input [3,3,5,0,0,3,1,4] + * profit from l->r [0,0,2,2,2,3,3,4] + * profit from r->l [4,4,4,4,4,3,3,0] + * this simply states that at index 2 if we come from left the profit is 2 + * and we can initiate another transaction to obtain another profit + */ public int maxProfit(int[] prices) { - int oneBuy = Integer.MIN_VALUE; - int oneBuyOneSell = 0; - int twoBuy = Integer.MIN_VALUE; - int twoBuyTwoSell = 0; - for(int i = 0; i < prices.length; i++){ - oneBuy = Math.min(oneBuy, prices[i]);//we set prices to negative, so the calculation of profit will be - // convenient - oneBuyOneSell = Math.max(oneBuyOneSell, prices[i] + oneBuy); - twoBuy = Math.min(twoBuy, prices[i] - oneBuyOneSell);//we can buy the second only after first is sold - twoBuyTwoSell = Math.max(twoBuyTwoSell, twoBuy + prices[i]); - } - - return Math.max(oneBuyOneSell, twoBuyTwoSell); + int ans = 0; + if (prices.length == 0 || prices.length == 1) + return ans; + int[] p = new int[prices.length]; + int minBuy = prices[0]; + int maxProfit = 0; + for (int i=1;i=0;i--) { + maxSell = Math.max(maxSell, prices[i]); + maxProfit = Math.max(maxProfit, maxSell - prices[i]); + p[i] += maxProfit; + ans = Math.max(p[i], ans); + } + return ans; } } diff --git a/src/geeksforgeeks/Candy.java b/src/geeksforgeeks/Candy.java index 4a7ff88..8405771 100644 --- a/src/geeksforgeeks/Candy.java +++ b/src/geeksforgeeks/Candy.java @@ -4,18 +4,28 @@ /** * https://www.hackerrank.com/challenges/candies/problem + * Alice wants to give at least 1 candy to each child. + * If two children sit next to each other, then + * the one with the higher rating must get more candies than neighbour (left and right). + * Alice wants to minimize the total number of candies she must buy. + +For example, assume her students' ratings are [4, 6, 4, 5, 6, 2]. +She gives the students candy in the following minimal amounts: [1, 2, 1, 2, 3, 1]. She must buy a minimum of 10 candies. */ class Candy { // 2, 4, 2, 6, 1, 7, 8, 3, 2, 1 // 1, 2, 1, 2, 1, 2, 3, 1, 1, 1 - // 1,2,4,3,2,1 + // 1, 2, 4, 3, 2, 1 int candy(int[] ratings) { int size = ratings.length; if (size <= 1) { return size; } + // ideally we should maintain 2 arrays 1)L->R 2) R->L + // then iterate both and check max b/w 2 items as result for each index + // we optimise it further for extra space and for loop int[] num = new int[size]; Arrays.fill(num, 1); // left to right diff --git a/src/geeksforgeeks/CheckPalindromePermutation.java b/src/geeksforgeeks/CheckPalindromePermutation.java index eb3d648..cd68680 100644 --- a/src/geeksforgeeks/CheckPalindromePermutation.java +++ b/src/geeksforgeeks/CheckPalindromePermutation.java @@ -1,13 +1,27 @@ package geeksforgeeks; + +/** + * Given a string, determine if a permutation of the string could form a palindrome. + * Input: "code" + * Output: false + * Input: "carerac" + Output: true + */ public class CheckPalindromePermutation { + // If a string with an even length is a palindrome, every character in the string must always occur an even number of times. + // If the string with an odd length is a palindrome, every character except one of the characters must always occur an even number of times. + // Thus, in case of a palindrome, the number of characters with odd number of occurrences can't exceed 1 + public boolean canPermutePalindrome(String s) { if(s==null || s.length()==0) return false; int[] cache= new int[128]; + for(char ch: s.toCharArray()){ cache[ch]++; } int oddCOunt=0; + for(int i=0;i<128;i++){ oddCOunt+= cache[i]%2; if(oddCOunt>1) return false; diff --git a/src/geeksforgeeks/CheckPermutationContains.java b/src/geeksforgeeks/CheckPermutationContains.java index 32f54d6..84699aa 100644 --- a/src/geeksforgeeks/CheckPermutationContains.java +++ b/src/geeksforgeeks/CheckPermutationContains.java @@ -1,6 +1,20 @@ package geeksforgeeks; +/** + * Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. + * In other words, one of the first string's permutations is the substring of the second string. + * Input:s1= "ab" s2 = "eidboaoo" + Output: False + */ public class CheckPermutationContains { + + // How do we know string p is a permutation of string s? Easy, each character in p is in s too. + // So we can abstract all permutation strings of s to a map (Character -> Count). i.e. abba -> {a:2, b:2}. + // Since there are only 26 lower case letters in this problem, we can just use an array to represent the map. + // How do we know string s2 contains a permutation of s1? We just need to create a sliding window with length of s1, move from beginning to the end of s2. + // When a character moves in from right of the window, we subtract 1 to that character count from the map. + // When a character moves out from left of the window, we add 1 to that character count. + // So once we see all zeros in the map, meaning equal numbers of every characters between s1 and the substring in the sliding window, we know the answer is true. public boolean checkInclusion(String s1, String s2) { if(s1.length()==0 || s2.length()==0) return false; int[] cache= new int[26]; diff --git a/src/geeksforgeeks/ClosestNumbers.java b/src/geeksforgeeks/ClosestNumbers.java index 311364a..ae55108 100644 --- a/src/geeksforgeeks/ClosestNumbers.java +++ b/src/geeksforgeeks/ClosestNumbers.java @@ -6,6 +6,15 @@ /** * https://www.geeksforgeeks.org/closest-numbers-list-unsorted-integers/ + * Given a list of distinct unsorted integers, + * find the pair of elements that have the smallest absolute difference between them? + * If there are multiple pairs, find them all. + * Input : arr[] = {10, 50, 12, 100} +Output : (10, 12) +The closest elements are 10 and 12 + +Input : arr[] = {5, 4, 3, 2} +Output : (2, 3), (3, 4), (4, 5) */ public class ClosestNumbers { diff --git a/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java b/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java index 2289a07..1a1694c 100644 --- a/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java +++ b/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java @@ -9,31 +9,40 @@ */ class ConstructTreeFromInorderAndPreorder { + // The basic idea is here: + // Say we have 2 arrays, PRE and IN. + // Preorder traversing implies that PRE[0] is the root node. + // Then we can find this PRE[0] in IN, say it's IN[5]. + // Now we know that IN[5] is root, so we know that IN[0] - IN[4] is on the left + // side, IN[6] to the end is on the right side. + // Recursively doing this on subarrays, we can build a tree out of it :) public TreeNode buildTree(int[] preorder, int[] inorder) { - Map inMap = new HashMap<>(); + Map map = new HashMap<>(); + List set = new LinkedList<>(); + for (int i = 0; i < inorder.length; i++) { - inMap.put(inorder[i], i); - } - List pre = new LinkedList<>(); - for (int i = 0; i < preorder.length; i++) { - pre.add(preorder[i]); + map.put(inorder[i], i); } - TreeNode root = buildTree(pre, 0, inorder.length - 1, inMap); - return root; - } - public TreeNode buildTree(ArrayList pre, int inStart, int inEnd, Map inMap) { - if (inStart > inEnd) { - return null; + for (int i = 0; i < preorder.length; i++) { + set.add(preorder[i]); } - TreeNode root = new TreeNode(pre.get(0)); - int inRoot = inMap.get(root.val); - pre.remove(0); + return buildTreeUtil(map, set, 0, inorder.length - 1); - root.left = buildTree(pre, inStart, inRoot - 1, inMap); - root.right = buildTree(pre, inRoot + 1, inEnd, inMap); + } + public TreeNode buildTreeUtil(Map map, List set, int start, int end) { + if (start > end) + return null; + if (set.isEmpty()) + return null; + int rootval = set.get(0); + set.remove(0); + TreeNode root = new TreeNode(rootval); + int inorderIndex = map.get(rootval); + root.left = buildTreeUtil(map, set, start, inorderIndex - 1); + root.right = buildTreeUtil(map, set, inorderIndex + 1, end); return root; } } \ No newline at end of file diff --git a/src/geeksforgeeks/ContainerWithMostWater.java b/src/geeksforgeeks/ContainerWithMostWater.java new file mode 100644 index 0000000..5bc747c --- /dev/null +++ b/src/geeksforgeeks/ContainerWithMostWater.java @@ -0,0 +1,36 @@ +package geeksforgeeks; + +/** + * Given n non-negative integers a1, a2, ..., an , + * where each represents a point at coordinate (i, ai). + * n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). + * Find two lines, which together with x-axis forms a container, such that the container contains the most water. + + Note: You may not slant the container and n is at least 2. + Input: [1,8,6,2,5,4,8,3,7] + Output: 49 + */ +public class ContainerWithMostWater { + + public int maxArea(int[] height) { + if(height==null || height.length==0) return 0; + int i=0; + int j= height.length-1; + int result=0; + + while(iheight[j]){ // the reason we are moving lesser side is + // j-i is going to be decreasing so we need to + // maintain higher side to have max value + j--; + }else{ + i++; + } + } + return result; + } +} diff --git a/src/geeksforgeeks/CountAndSay.java b/src/geeksforgeeks/CountAndSay.java index 7e1f6c8..b420233 100644 --- a/src/geeksforgeeks/CountAndSay.java +++ b/src/geeksforgeeks/CountAndSay.java @@ -24,7 +24,7 @@ private String build(String result) { char val = result.charAt(p); int count = 0; - while (p < result.length() && result.charAt(p) == val) { + while (p < result.length() && result.charAt(p) == val) { // note that p and val will be same in first run, to count single instance p++; count++; } diff --git a/src/geeksforgeeks/CountDistinctKSubString.java b/src/geeksforgeeks/CountDistinctKSubString.java deleted file mode 100644 index a302b66..0000000 --- a/src/geeksforgeeks/CountDistinctKSubString.java +++ /dev/null @@ -1,40 +0,0 @@ -package geeksforgeeks; - -// Java program to CountKSubStr number of substrings -// with exactly distinct characters in a given string - -import java.util.Arrays; - -/*https://www.geeksforgeeks.org/count-number-of-substrings-with-exactly-k-distinct-characters/*/ - -public class CountDistinctKSubString { - - private int countKDist(String str, int k) { - - int result = 0; - int n = str.length(); - int count[] = new int[26]; - - for (int i = 0; i < n; i++) { - int distinctCount = 0; - Arrays.fill(count, 0); - for (int j = i; j < n; j++) { - if (count[str.charAt(j) - 'a'] == 0) { - distinctCount++; - } - count[str.charAt(j) - 'a']++; - if (distinctCount == k) { - result++; - } - } - } - return result; - } - - public static void main(String[] args) { - CountDistinctKSubString ob = new CountDistinctKSubString(); - String ch = "abc"; - int k = 2; - System.out.println("Total substrings with exactly " + k + " distinct characters : " + ob.countKDist(ch, k)); - } -} diff --git a/src/geeksforgeeks/CountNumbersLessThanSelf.java b/src/geeksforgeeks/CountNumbersLessThanSelf.java index 2eb5d0a..447f314 100644 --- a/src/geeksforgeeks/CountNumbersLessThanSelf.java +++ b/src/geeksforgeeks/CountNumbersLessThanSelf.java @@ -1,49 +1,103 @@ package geeksforgeeks; -import java.util.ArrayList; -import java.util.Arrays; +import java.util.LinkedList; import java.util.List; +/** + * You are given an integer array nums and you have to return a new counts array. + * The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i]. + * Input: [5,2,6,1] + * Output: [2,1,1,0] + */ class CountNumbersLessThanSelf { - public List countSmaller(int[] nums) { - if (nums.length == 0) { - return new ArrayList<>(); - } + // Wrapper class for each and every value of the input array, +// to store the original index position of each value, before we merge sort the array + private class ArrayValWithOrigIdx { + int val; + int originalIdx; - Integer[] result = new Integer[nums.length]; - Node root = null; - for (int i = nums.length - 1; i >= 0; i--) { // build tree from end so that end is root and has sum 0 - root = buildBSTHelper(nums[i], root, result, i, 0); + public ArrayValWithOrigIdx(int val, int originalIdx) { + this.val = val; + this.originalIdx = originalIdx; } - return Arrays.asList(result); } - public Node buildBSTHelper(int val, Node root, Integer[] result, int index, int sum) { - if (root == null) { - root = new Node(val, 0); - result[index] = sum; - } else if (root.val == val) { - root.dup++; - result[index] = sum + root.sum; - } else if (root.val > val) { - root.sum++; - root.left = buildBSTHelper(val, root.left, result, index, sum); - } else { - root.right = buildBSTHelper(val, root.right, result, index, root.sum + root.dup + sum); - } - return root; + public List countSmaller(int[] nums) { + if (nums == null || nums.length == 0) return new LinkedList(); + int n = nums.length; + int[] result = new int[n]; + + ArrayValWithOrigIdx[] newNums = new ArrayValWithOrigIdx[n]; + for (int i = 0; i < n; ++i) newNums[i] = new ArrayValWithOrigIdx(nums[i], i); + + mergeSortAndCount(newNums, 0, n - 1, result); + + // notice we don't care about the sorted array after merge sort finishes. + // we only wanted the result counts, generated by running merge sort + List resultList = new LinkedList(); + for (int i : result) resultList.add(i); + return resultList; } - private class Node { - int val; - int sum; - Node right; - Node left; - int dup = 1; + private void mergeSortAndCount(ArrayValWithOrigIdx[] nums, int start, int end, int[] result) { + if (start >= end) return; - public Node(int val, int sum) { - this.val = val; - this.sum = sum; + int mid = (start + end) / 2; + mergeSortAndCount(nums, start, mid, result); + mergeSortAndCount(nums, mid + 1, end, result); + + // left subarray start...mid + // right subarray mid+1...end + int leftPos = start; + int rightPos = mid + 1; + LinkedList merged = new LinkedList(); + int numElemsRightArrayLessThanLeftArray = 0; + while (leftPos < mid + 1 && rightPos <= end) { + if (nums[leftPos].val > nums[rightPos].val) { + // this code block is exactly what the problem is asking us for: + // a number from the right side of the original input array, is smaller + // than a number from the left side + // + // within this code block, + // nums[rightPos] is smaller than the start of the left sub-array. + // Since left sub-array is already sorted, + // nums[rightPos] must also be smaller than the entire remaining left sub-array + ++numElemsRightArrayLessThanLeftArray; + + // continue with normal merge sort, merge + merged.add(nums[rightPos]); + ++rightPos; + } else { + // a number from left side of array, is smaller than a number from + // right side of array + result[nums[leftPos].originalIdx] += numElemsRightArrayLessThanLeftArray; + + // Continue with normal merge sort + merged.add(nums[leftPos]); + ++leftPos; + } + } + + // part of normal merge sort, if either left or right sub-array is not empty, + // move all remaining elements into merged result + while (leftPos < mid + 1) { + result[nums[leftPos].originalIdx] += numElemsRightArrayLessThanLeftArray; + + merged.add(nums[leftPos]); + ++leftPos; + } + while (rightPos <= end) { + merged.add(nums[rightPos]); + ++rightPos; + } + + // part of normal merge sort + // copy back merged result into array + int pos = start; + for (ArrayValWithOrigIdx m : merged) { + nums[pos] = m; + ++pos; } } -} \ No newline at end of file +} + diff --git a/src/geeksforgeeks/CountOfSmallNumbers.java b/src/geeksforgeeks/CountOfSmallNumbers.java deleted file mode 100644 index 12e1c16..0000000 --- a/src/geeksforgeeks/CountOfSmallNumbers.java +++ /dev/null @@ -1,56 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; -import java.util.List; - -/** - * https://leetcode.com/problems/count-of-smaller-numbers-after-self/ - */ -class CountOfSmallNumbers { - class Node { - Node left, right; - int val, sum, dup = 1; - - public Node(int v, int s) { - val = v; - sum = s; - } - - @Override - public String toString() { - return "Node{" + "left=" + left + ", right=" + right + ", val=" + val + ", sum=" + sum + ", dup=" + dup - + '}'; - } - } - - public List countSmaller(int[] nums) { - Integer[] ans = new Integer[nums.length]; - Node root = null; - for (int i = nums.length - 1; i >= 0; i--) { - root = insert(nums[i], root, ans, i, 0); - } - return Arrays.asList(ans); - } - - private Node insert(int num, Node node, Integer[] ans, int i, int preSum) { - if (node == null) { - node = new Node(num, 0); - ans[i] = preSum; - } else if (node.val == num) { - node.dup++; - ans[i] = preSum + node.sum; - } else if (node.val > num) { - node.sum++; - node.left = insert(num, node.left, ans, i, preSum); - } else { - node.right = insert(num, node.right, ans, i, preSum + node.dup + node.sum); - } - return node; - } - - public static void main(String[] args) { - CountOfSmallNumbers csn = new CountOfSmallNumbers(); - int[] arr = { 5, 2, 6, 1 }; - System.out.println(csn.countSmaller(arr)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/CountingInversion.java b/src/geeksforgeeks/CountingInversion.java index e3db597..b9b678b 100644 --- a/src/geeksforgeeks/CountingInversion.java +++ b/src/geeksforgeeks/CountingInversion.java @@ -35,7 +35,11 @@ static int merge(int[] arr, int[] temp, int left, int mid, int right) { temp[k++] = arr[i++]; } else { temp[k++] = arr[j++]; - + // the reason to put mid-i is take example of [1,3,5] [2,4,6] + // left is 0 and right is mid at start + // when i=1 and j=0 (value 3 and 2) we see an inversion, since + // the first part is sorted and values after i=1(3) will be greater than j=0(2) + // so we consider all elements after 3 as inversions invCount = invCount + (mid - i); } } diff --git a/src/geeksforgeeks/CourseSchedule.java b/src/geeksforgeeks/CourseSchedule.java index 2edf54f..19d6167 100644 --- a/src/geeksforgeeks/CourseSchedule.java +++ b/src/geeksforgeeks/CourseSchedule.java @@ -77,7 +77,8 @@ public boolean canFinishDFS(int numCourses, int[][] prerequisites) { for(int[] preReq:prerequisites){ adjList[preReq[0]].add(preReq[1]); } - + // this visited array will maintain 3 values 0,1 and 2 + // 0-unvisited, 1-being visited and 2 visited int[] visited= new int[numCourses]; for(int i=0;i[] adjList, int[] visited, int vertex){ - if(visited[vertex]==1) return false; + if(visited[vertex]==1) return false; // when a node comes with being visited state, we fail it visited[vertex]=1; for(int adj: adjList[vertex]){ if(!dfs(adjList, visited, adj)) return false; } - visited[vertex]=2; + visited[vertex]=2; // finally we set visited to true return true; } // this is to get the order of course as output diff --git a/src/geeksforgeeks/CourseScheduling.java b/src/geeksforgeeks/CourseScheduling.java deleted file mode 100644 index aa1460d..0000000 --- a/src/geeksforgeeks/CourseScheduling.java +++ /dev/null @@ -1,108 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.Set; - -/** - * https://leetcode.com/problems/course-schedule/ - */ -public class CourseScheduling { - - Map> graph = new HashMap<>(); - int[][] p; - int n; - - public boolean canFinishI(int numCourses, int[][] prerequisites) { - p = prerequisites; - for (int i = 0; i < p.length; i++) { - List l = graph.getOrDefault(p[i][1], new ArrayList<>()); - l.add(p[i][0]); - graph.put(p[i][1], l); - } - for (int i = 0; i < numCourses; i++) { - if (!vis.contains(i)) { - if (cycleExist(i)) { - return false; - } - } - } - - return true; - } - - Set vis = new HashSet<>(); - Set recur = new HashSet<>(); - - public boolean cycleExist(int u) { - if (!graph.containsKey(u)) { - return false; - } - if (recur.contains(u)) { - return true; - } - if (vis.contains(u)) { - return false; - } - recur.add(u); - for (int i : graph.get(u)) { - if (!vis.contains(i)) { - if (cycleExist(i)) { - return true; - } - } - } - recur.remove(u); - vis.add(u); - return false; - } - - int n1; - int[] indegree; - Map> adj = new HashMap<>(); - - public boolean canFinish(int numCourses, int[][] prerequisites) { - n1 = numCourses; - indegree = new int[n1]; - for (int[] pr : prerequisites) { - List l = adj.getOrDefault(pr[1], new ArrayList<>()); - l.add(pr[0]); - indegree[pr[0]]++; - adj.put(pr[1], l); - } - Queue q = new LinkedList<>(); - int count = 0; - for (int i = 0; i < indegree.length; i++) { - if (indegree[i] == 0) { - q.add(i); - } - } - while (!q.isEmpty()) { - int cur = q.poll(); - if (indegree[cur] == 0) { - count++; - } - if (!adj.containsKey(cur)) { - continue; - } - for (int nei : adj.get(cur)) { - indegree[nei]--; - if (indegree[nei] == 0) { - q.add(nei); - } - } - - } - - return count == n1; - } - - public static void main(String[] args) { - - } -} diff --git a/src/geeksforgeeks/DecodeString.java b/src/geeksforgeeks/DecodeString.java index 96ec950..4340ebd 100644 --- a/src/geeksforgeeks/DecodeString.java +++ b/src/geeksforgeeks/DecodeString.java @@ -1,5 +1,8 @@ package geeksforgeeks; +import java.util.ArrayDeque; +import java.util.Deque; + // s = "3[a2[c]]", return "accaccacc". // s = "2[abc]3[cd]ef", return "abcabccdcdcdef". public class DecodeString { @@ -10,8 +13,9 @@ public String decodeString(String s) { Deque count = new ArrayDeque<>(); Deque result = new ArrayDeque<>(); int start = 0; - StringBuilder tempRes = new StringBuilder(); + StringBuilder tempResult = new StringBuilder(); while (start < s.length()) { + // whenever we see number, we push to count queue if (Character.isDigit(s.charAt(start))) { int num = 0; while (Character.isDigit(s.charAt(start))) { @@ -20,22 +24,26 @@ public String decodeString(String s) { } count.push(num); } else if (s.charAt(start) == '[') { - result.push(tempRes.toString()); - tempRes = new StringBuilder(); + // whenever we see a open brace we push the string we have to result queue + result.push(tempResult.toString()); + tempResult = new StringBuilder(); start++; } else if (s.charAt(start) == ']') { + // whenever a closing brace comes, we pop the last seen count and last seen string + // and replicate that string and stores in temp result StringBuilder sb = new StringBuilder(result.pop()); int tempCount = count.pop(); for (int i = 0; i < tempCount; i++) { - sb.append(tempRes); + sb.append(tempResult); } - tempRes = sb; + tempResult = sb; start++; } else { - tempRes.append(s.charAt(start++)); + // whenever we see a char, we push to result string + tempResult.append(s.charAt(start++)); } } - return tempRes.toString(); + return tempResult.toString(); } } \ No newline at end of file diff --git a/src/geeksforgeeks/DesignTicTacToe.java b/src/geeksforgeeks/DesignTicTacToe.java index 087d06c..c0c16a0 100644 --- a/src/geeksforgeeks/DesignTicTacToe.java +++ b/src/geeksforgeeks/DesignTicTacToe.java @@ -1,5 +1,52 @@ package geeksforgeeks; +/* +Design a Tic-tac-toe game that is played between two players on a n x n grid. +You may assume the following rules: + +A move is guaranteed to be valid and is placed on an empty block. +Once a winning condition is reached, no more moves is allowed. +A player who succeeds in placing n of their marks in a horizontal, vertical, or diagonal row wins the game. + +Given n = 3, assume that player 1 is "X" and player 2 is "O" in the board. + +TicTacToe toe = new TicTacToe(3); + +toe.move(0, 0, 1); -> Returns 0 (no one wins) +|X| | | +| | | | // Player 1 makes a move at (0, 0). +| | | | + +toe.move(0, 2, 2); -> Returns 0 (no one wins) +|X| |O| +| | | | // Player 2 makes a move at (0, 2). +| | | | + +toe.move(2, 2, 1); -> Returns 0 (no one wins) +|X| |O| +| | | | // Player 1 makes a move at (2, 2). +| | |X| + +toe.move(1, 1, 2); -> Returns 0 (no one wins) +|X| |O| +| |O| | // Player 2 makes a move at (1, 1). +| | |X| + +toe.move(2, 0, 1); -> Returns 0 (no one wins) +|X| |O| +| |O| | // Player 1 makes a move at (2, 0). +|X| |X| + +toe.move(1, 0, 2); -> Returns 0 (no one wins) +|X| |O| +|O|O| | // Player 2 makes a move at (1, 0). +|X| |X| + +toe.move(2, 1, 1); -> Returns 1 (player 1 wins) +|X| |O| +|O|O| | // Player 1 makes a move at (2, 1). +|X|X|X| + */ public class DesignTicTacToe { private int[] rows; private int[] cols; @@ -22,7 +69,7 @@ public DesignTicTacToe(int n) { 2: Player 2 wins. */ public int move(int row, int col, int player) { int toAdd = player == 1 ? 1 : -1; - // if A player makes a move on 0,0 we are going to increment index posistion of row and col at 0,- + // if A player makes a move on 0,0 we are going to increment index posistion of row and col at 0,0 // if B player makes a move on 0,2 we are going to decrement index posistion at row and col at 0,2 // after that the count of row at 0 will be 0(balanced moves) like wise if a row or col has value n only // a player can be adjudged a winner diff --git a/src/geeksforgeeks/DungeonGame.java b/src/geeksforgeeks/DungeonGame.java new file mode 100644 index 0000000..7537453 --- /dev/null +++ b/src/geeksforgeeks/DungeonGame.java @@ -0,0 +1,64 @@ +package geeksforgeeks; + +// The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. +//The dungeon consists of M x N rooms laid out in a 2D grid. +//Our valiant knight (K) was initially positioned in the top-left room and must fight his way through the dungeon to rescue the princess. + +// The knight has an initial health point represented by a positive integer. +//If at any point his health point drops to 0 or below, he dies immediately. +//Input +// |-2 -3 3 | +// |-5 -10 1 | +// |10 30 -5 | + +//output 7 + +// the trick here is to go bottom up, start from the last cell, +// inorder to reach there he should have atleast 6 as health, so that +// when he reaches -5(energy is consumed) and he's left with +1 health +// likewise if we backtrack from end to start, we'll need +7 as min initial health to +// play the game +public class DungeonGame { + public int calculateMinimumHP(int[][] dungeon) { + + int[][] dp = new int[dungeon.length][dungeon[0].length]; + + int m = dungeon.length; + int n = dungeon[0].length; + + dp[m-1][n-1] = Math.max(1, 1-dungeon[m-1][n-1]); + + // Populate the last column + for(int i=m-2;i>=0;i--){ + dp[i][n-1] = Math.max(1, dp[i+1][n-1]-dungeon[i][n-1]); + } + + // Populate the last row + for(int i=n-2;i>=0;i--){ + dp[m-1][i] = Math.max(1, dp[m-1][i+1]-dungeon[m-1][i]); + } + + // to achieve the answer, we need to setup the last row and last column + // we know to reach last cell we need 6 as energy, let's say that comes + // from cell above it, that cell's original val is +1, so we must have + // 5 energy when we reach there and adding it up, it became 6 + // the reason to put 1 on last row is, the value in that cell is 30 + // so to reach last cell from that cell, we need only 6 energy(min) + // to have 6 from +30, player should have health of -24 and player cannot + // have neg val, so we put 1 as filler + // |* * 2 | + // |* * 5 | + // |1 1 6 | + + // Populate the rest by taking max of bottom and right (reverse of down and left) + + for(int i=m-2;i>=0;i--){ + for(int j=n-2;j>=0;j--){ + dp[i][j] = Math.max(1, Math.min(dp[i+1][j], dp[i][j+1])-dungeon[i][j]); + } + } + + + return dp[0][0]; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/FileSystem1166.java b/src/geeksforgeeks/FileSystem1166.java index 8125c9b..ed1331f 100644 --- a/src/geeksforgeeks/FileSystem1166.java +++ b/src/geeksforgeeks/FileSystem1166.java @@ -1,4 +1,28 @@ package geeksforgeeks; + +import java.util.HashMap; + +/** + * You are asked to design a file system which provides two functions: + * + * createPath(path, value): Creates a new path and associates a value to it if possible and returns True. + * Returns False if the path already exists or its parent path doesn't exist. + * + * get(path): Returns the value associated with a path or returns -1 if the path doesn't exist. + * + * ["FileSystem","createPath","createPath","get","createPath","get"] + * [[],["/leet",1],["/leet/code",2],["/leet/code"],["/c/d",1],["/c"]] + * Output: + * [null,true,true,2,false,-1] + * Explanation: + * FileSystem fileSystem = new FileSystem(); + * + * fileSystem.createPath("/leet", 1); // return true + * fileSystem.createPath("/leet/code", 2); // return true + * fileSystem.get("/leet/code"); // return 2 + * fileSystem.createPath("/c/d", 1); // return false because the parent path "/c" doesn't exist. + * fileSystem.get("/c"); // return -1 because this path doesn't exist. + */ public class FileSystem1166 { private HashMap m = new HashMap<>(); @@ -7,7 +31,7 @@ public class FileSystem1166 { * Initialization of class. * Use a hash map to store the path and value. */ - public FileSystem_1166() { + public FileSystem1166() { m.put("", -1); // avoid initially when path is "/a" regarded as false } diff --git a/src/geeksforgeeks/FileSystemI.java b/src/geeksforgeeks/FileSystemI.java index eb65ef3..51f3e19 100644 --- a/src/geeksforgeeks/FileSystemI.java +++ b/src/geeksforgeeks/FileSystemI.java @@ -1,5 +1,19 @@ package geeksforgeeks; - +/** + * Design an in-memory file system to simulate the following functions: + * + * ls: Given a path in string format. If it is a file path, return a list that only contains this file's name. + * If it is a directory path, return the list of file and directory names in this directory. Your output (file and directory names together) should in lexicographic order. + * + * mkdir: Given a directory path that does not exist, you should make a new directory according to the path. + * If the middle directories in the path don't exist either, you should create them as well. This function has void return type. + * + * addContentToFile: Given a file path and file content in string format. + * If the file doesn't exist, you need to create that file containing given content. + * If the file already exists, you need to append given content to original content. This function has void return type. + * + * readContentFromFile: Given a file path, return its content in string format. + */ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -7,7 +21,7 @@ public class FileSystemI { class Dir { - HashMap dirs = new HashMap<>(); + HashMap directory = new HashMap<>(); HashMap files = new HashMap<>(); } @@ -17,23 +31,29 @@ public FileSystemI() { root = new Dir(); } + public List ls(String path) { - Dir t = root; + Dir tempRoot = root; List files = new ArrayList<>(); if (!path.equals("/")) { - String[] d = path.split("/"); - for (int i = 1; i < d.length - 1; i++) { - t = t.dirs.get(d[i]); + String[] directoriesList = path.split("/"); + for (int i = 1; i < directoriesList.length - 1; i++) { + tempRoot = tempRoot.directory.get(directoriesList[i]); } - if (t.files.containsKey(d[d.length - 1])) { - files.add(d[d.length - 1]); + //If the last level in the input happens to be a file name, we simply need to return the file name. + // So, we directly return the last entry in the array. + if (tempRoot.files.containsKey(directoriesList[directoriesList.length - 1])) { + files.add(directoriesList[directoriesList.length - 1]); return files; } else { - t = t.dirs.get(d[d.length - 1]); + tempRoot = tempRoot.directory.get(directoriesList[directoriesList.length - 1]); } } - files.addAll(new ArrayList<>(t.dirs.keySet())); - files.addAll(new ArrayList<>(t.files.keySet())); + //If the last level entry happens to be a directory, + // we can obtain its subdirectory list from the list of keys in its hashmap. + // Similarly, we can obtain the list of files in the last directory from the keys in the corresponding hashmap. + files.addAll(new ArrayList<>(tempRoot.directory.keySet())); + files.addAll(new ArrayList<>(tempRoot.files.keySet())); Collections.sort(files); return files; } @@ -42,10 +62,8 @@ public void mkdir(String path) { Dir t = root; String[] d = path.split("/"); for (int i = 1; i < d.length; i++) { - if (!t.dirs.containsKey(d[i])) { - t.dirs.put(d[i], new Dir()); - } - t = t.dirs.get(d[i]); + t.directory.putIfAbsent(d[i], new Dir()); + t = t.directory.get(d[i]); } } @@ -53,7 +71,7 @@ public void addContentToFile(String filePath, String content) { Dir t = root; String[] d = filePath.split("/"); for (int i = 1; i < d.length - 1; i++) { - t = t.dirs.get(d[i]); + t = t.directory.get(d[i]); } t.files.put(d[d.length - 1], t.files.getOrDefault(d[d.length - 1], "") + content); } @@ -62,7 +80,7 @@ public String readContentFromFile(String filePath) { Dir t = root; String[] d = filePath.split("/"); for (int i = 1; i < d.length - 1; i++) { - t = t.dirs.get(d[i]); + t = t.directory.get(d[i]); } return t.files.get(d[d.length - 1]); } diff --git a/src/geeksforgeeks/FindNumberOfOccurrences.java b/src/geeksforgeeks/FindNumberOfOccurrences.java deleted file mode 100644 index 3e81c4c..0000000 --- a/src/geeksforgeeks/FindNumberOfOccurrences.java +++ /dev/null @@ -1,43 +0,0 @@ -package geeksforgeeks; - -/*https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/*/ -public class FindNumberOfOccurrences { - - public static void main(String[] args) { - int arr[] = { 1, 1, 2, 2, 2, 2, 3, 3 }; - System.out.println( - findLastOccurrence(arr, 0, arr.length - 1, 2) - findFirstOccurrence(arr, 0, arr.length - 1, 2) + 1); - - } - - private static int findFirstOccurrence(int[] arr, int left, int right, int key) { - if (left > right) { - return -1; - } - - int mid = (left + right) / 2; - if (arr[mid] == key && (mid == 0 || arr[mid - 1] != key)) { - return mid; - } else if (arr[mid] >= key) { - return findFirstOccurrence(arr, left, mid - 1, key); - } else { - return findFirstOccurrence(arr, mid + 1, right, key); - } - } - - private static int findLastOccurrence(int[] arr, int left, int right, int key) { - if (left > right) { - return 0; - } - - int mid = (left + right) / 2; - if (arr[mid] == key && (mid == right || arr[mid + 1] != key)) { - return mid; - } else if (arr[mid] <= key) { - return findLastOccurrence(arr, mid + 1, right, key); - } else { - return findLastOccurrence(arr, left, mid - 1, key); - } - } - -} diff --git a/src/geeksforgeeks/FirstNonReapeatingCharacterStream.java b/src/geeksforgeeks/FirstNonReapeatingCharacterStream.java index 54b3089..a4fbac5 100644 --- a/src/geeksforgeeks/FirstNonReapeatingCharacterStream.java +++ b/src/geeksforgeeks/FirstNonReapeatingCharacterStream.java @@ -9,6 +9,16 @@ public class FirstNonReapeatingCharacterStream { final static int MAX_CHAR = 256; + + // we need to maintain 2 array of size 26 and a doubly linkedlist where the hed element points to the first Non repeat + // 1) 1st array to store the corresponding node to the character position boolean[] visited= new boolean[26]; + // 2nd array is to check if the character occurred 2>= times DLLNode[] node= new DLLNode[26]; + // first condition whenever we see a value, we need to check it in visited array + // if(visited[c-'a']== true) do nothing because already added and deleted from the list(means this is 3rd occurrence of the array) + // else if(node[c-'a']!=null) removeNode(node[c-'a']); visited[c-'a']=true; 2nd occurrence we need to remove from list and set visited value to true + // else create a node and add head if head null or add to tail means we are seeing first time and need to create an entry in list + + // this uses arraylist so remove and contains are O(N) static void findFirstNonRepeating() { // inDLL[x] contains pointer to a DLL node if x is present // in DLL. If x is not present, then inDLL[x] is NULL diff --git a/src/geeksforgeeks/Flatten2DVector.java b/src/geeksforgeeks/Flatten2DVector.java index 38e6359..de40a3b 100644 --- a/src/geeksforgeeks/Flatten2DVector.java +++ b/src/geeksforgeeks/Flatten2DVector.java @@ -7,6 +7,19 @@ As hint indicates: use 2 pointers to hold position. Use hasNext to validate (x,y) and move x. Use next() to return (x,y) and move it(regardless of correctness, which is determined by hasNext()) + +Implement an iterator to flatten a 2d vector. + +For example, +Given 2d vector = + +[ + [1,2], + [3], + [4,5,6] +] +By calling next repeatedly until hasNext returns false, +the order of elements returned by next should be: [1,2,3,4,5,6]. */ public class Flatten2DVector { private int x; @@ -24,6 +37,7 @@ public Flatten2DVector(List> vec2d) { public int next() { int rst = list.get(x).get(y); + // when y(column) reaches end increment row(x) and reset y if (y + 1 >= list.get(x).size()) { y = 0; x++; @@ -37,6 +51,7 @@ public boolean hasNext() { if (list == null) { return false; } + // this condition is to check for empty rows while (x < list.size() && list.get(x).size() == 0) { x++; y = 0; diff --git a/src/geeksforgeeks/FrequencySort.java b/src/geeksforgeeks/FrequencySort.java index eb6a2ba..a01d6cc 100644 --- a/src/geeksforgeeks/FrequencySort.java +++ b/src/geeksforgeeks/FrequencySort.java @@ -1,5 +1,11 @@ package geeksforgeeks; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +// sort the string by character frequency from high to low public class FrequencySort { // this could be easily done with priority queue but this is ref for bucket sort public String frequencySort(String s) { @@ -7,7 +13,8 @@ public String frequencySort(String s) { for (char c : s.toCharArray()) map.put(c, map.getOrDefault(c, 0) + 1); - List [] bucket = new List[s.length() + 1]; + List[] bucket = new List[s.length() + 1]; + for (char key : map.keySet()) { int frequency = map.get(key); if (bucket[frequency] == null) bucket[frequency] = new ArrayList<>(); @@ -15,6 +22,7 @@ public String frequencySort(String s) { } StringBuilder sb = new StringBuilder(); + // since this is max frequency are iterating from last else we'd go from start for (int pos = bucket.length - 1; pos >= 0; pos--) if (bucket[pos] != null) for (char c : bucket[pos]) diff --git a/src/geeksforgeeks/GameOfLife.java b/src/geeksforgeeks/GameOfLife.java index c44b7e3..d2b6069 100644 --- a/src/geeksforgeeks/GameOfLife.java +++ b/src/geeksforgeeks/GameOfLife.java @@ -1,68 +1,61 @@ package geeksforgeeks; -import java.util.Arrays; - /** * https://forum.letstalkalgorithms.com/t/game-of-life/516/2 *

* https://leetcode.com/problems/game-of-life/ + * Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article): + * + * Any live cell with fewer than two live neighbors dies, as if caused by under-population. + * Any live cell with two or three live neighbors lives on to the next generation. + * Any live cell with more than three live neighbors dies, as if by over-population.. + * Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction. + * + * Input: + * [ + * [0,1,0], + * [0,0,1], + * [1,1,1], + * [0,0,0] + * ] + * Output: + * [ + * [0,0,0], + * [1,0,1], + * [0,1,1], + * [0,1,0] + * ] */ public class GameOfLife { - int[][] c = { { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, -1 }, { 0, 1 }, { 1, -1 }, { 1, 0 }, { 1, 1 } }; + public void gameOfLife(int[][] board) { - int die = 2; - int live = 3; + int[][] dir ={{1,-1},{1,0},{1,1},{0,-1},{0,1},{-1,-1},{-1,0},{-1,1}}; + int row=board.length; + int col=board[0].length; - void gameOfLife(int[][] board) { - for (int i = 0; i < board.length; i++) { - for (int j = 0; j < board[0].length; j++) { - int neighbors = getLiveNeigborCount(board, i, j); - if (board[i][j] == 0 && neighbors == 3) { - board[i][j] = live; - } else if (board[i][j] == 1) { - if (neighbors == 2 || neighbors == 3) { - continue; - } - if (neighbors < 2 || neighbors > 3) { - board[i][j] = die; - } - } - } - } + for(int i=0; i=row || j1>=col || i1<0 || j1<0) continue; // border conditions - for (int i = 0; i < board.length; i++) { - for (int j = 0; j < board[0].length; j++) { - if (board[i][j] == die) { - board[i][j] = 0; - } else if (board[i][j] == live) { - board[i][j] = 1; - } + if(board[i1][j1]==1 || board[i1][j1]==2) liveCells++; } - } - } - int getLiveNeigborCount(int[][] board, int i, int j) { + if(board[i][j]==0 && liveCells==3) board[i][j]=3; //Any dead cell with exactly three live neighbors becomes a live cell - int count = 0; - for (int m = 0; m < board.length; m++) { - int mx = c[m][0] + i; - int my = c[m][1] + j; - if (mx >= 0 && my >= 0 && mx < board.length && my < board[0].length) { - if (board[mx][my] == 1 || board[mx][my] == die) { - count++; - } - } + if(board[i][j]==1 && (liveCells<2 || liveCells>3)) board[i][j]=2; //live cell with fewer than two live neighbors dies || Any live cell with more than three live neighbors dies } - return count; } - public static void main(String[] args) { - GameOfLife gol = new GameOfLife(); - int[][] arr = { { 0, 1, 0 }, { 0, 0, 1 }, { 1, 1, 1 }, { 0, 0, 0 } }; - System.out.println(Arrays.deepToString(arr)); - gol.gameOfLife(arr); - - System.out.println(Arrays.deepToString(arr)); + for(int i=0; i generateParenthesis(int n) { List result = new ArrayList<>(); if (n == 0) return result; - + // initially we send empty string and target number of pairs needed generateUtil(n, new StringBuilder(), 0, 0, result); return result; } public void generateUtil(int n, StringBuilder paran, int open, int close, List result) { - if (close == n) { + if (close == n) { // when close reaches n, we know n pairs have been created result.add(paran.toString()); return; } - if (close < open) { + if (close < open) { // when close is less than open we add a close and proceed paran.append(")"); generateUtil(n, paran, open, close + 1, result); - paran.deleteCharAt(paran.length() - 1); + paran.deleteCharAt(paran.length() - 1); // backtracking to remove the last seen } if (open < n) { paran.append("("); diff --git a/src/geeksforgeeks/GrammarMistake.java b/src/geeksforgeeks/GrammarMistake.java index 97efea5..134fb1f 100644 --- a/src/geeksforgeeks/GrammarMistake.java +++ b/src/geeksforgeeks/GrammarMistake.java @@ -2,107 +2,82 @@ /** * https://www.geeksforgeeks.org/check-given-sentence-given-set-simple-grammer-rules/ + * A simple sentence if syntactically correct if it fulfills given rules. The following are given rules. + * + * 1. Sentence must start with a Uppercase character (e.g. Noun/ I/ We/ He etc.) + * 2. Then lowercase character follows. + * 3. There must be spaces between words. + * 4. Then the sentence must end with a full stop(.) after a word. + * 5. Two continuous spaces are not allowed. + * 6. Two continuous upper case characters are not allowed. + * 7. However, the sentence can end after an upper case character. + * + * */ -class GrammarMistake { - - // Method to check a given sentence for given rules - static boolean checkSentence(char[] str) { - - // Calculate the length of the string. - int len = str.length; - - // Check that the first character lies in [A-Z]. - // Otherwise return false. - if (str[0] < 'A' || str[0] > 'Z') { +import java.util.Arrays; +import java.util.List; + +class Main +{ + public static boolean validateSentence(char[] chars) + { + int index = 0; + if (Character.isLowerCase(chars[index])) { // 1st condition return false; } - // If the last character is not a full stop(.) - // no need to check further. - if (str[len - 1] != '.') { - return false; - } - - // Maintain 2 states. Previous and current state - // based on which vertex state you are. - // Initialise both with 0 = start state. - int prev_state = 0, curr_state = 0; - - // Keep the index to the next character in the string. - int index = 1; - - // Loop to go over the string. - while (index <= str.length) { - - // Set states according to the input characters - // in the string and the rule defined in the description. - // If current character is [A-Z]. Set current state as 0. - if (str[index] >= 'A' && str[index] <= 'Z') { - curr_state = 0; + while (index < chars.length) + { + if (Character.isUpperCase(chars[index])) + { + if (Character.isUpperCase(chars[index + 1])) { // 5th condition + return false; + } + + if (index - 1 >= 0 && chars[index - 1] != ' ') { // 2nd condition + return false; + } } - // If current character is a space. - // Set current state as 1. - else if (str[index] == ' ') { - curr_state = 1; + if (chars[index] == ' ' && chars[index + 1] == ' ') { // 4th condition + return false; } - // If current character is [a-z]. - // Set current state as 2. - else if (str[index] >= 'a' && str[index] <= 'z') { - curr_state = 2; - } + index++; + } - // If current state is a dot(.). - // Set current state as 3. - else if (str[index] == '.') { - curr_state = 3; - } + if (chars[index - 2] == ' ' || chars[index - 1] != '.') { // 3th condition + return false; + } - // Validates all current state with previous state - // for the rules in the description of the problem. - if (prev_state == curr_state && curr_state != 2) { - return false; - } + return true; + } - if (prev_state == 2 && curr_state == 0) { - return false; - } + public static void main(String[] args) + { + List list = Arrays.asList( + "This sentence is syntactically correct.", - // If we have reached last state and previous state - // is not 1, then check next character. If next character - // is '\0', then return true, else false - // "My name is Ram." - if (curr_state == 3 && prev_state != 1) { - return (index + 1 == str.length); - } + "This sentence is syntactically incorrect as two " + + "continuous spaces are not allowed.", - index++; + "This sentence is syntactically correct Y.", - // Set previous state as current state - // before going over to the next character. - prev_state = curr_state; - } - return false; - } + "This sentence is syntactically incorRect as uppercase " + + "character is not allowed midway of the String.", + + "THis sentence is syntactically incorrect as lowercase " + + "character don't follow the first uppercase character.", - // Driver Code - public static void main(String[] args) { - String[] str = { "I love cinema.", "The vertex is S.", "I am single.", "My name is KG.", "I lovE cinema.", - "GeeksQuiz. is a quiz site.", "I love Geeksquiz and Geeksforgeeks.", " You are my friend.", - "I love cinema" }; - int str_size = str.length; + "This sentence is syntactically incorrect as it doesn't " + + "end with a full stop" + ); - int i = 0; - for (i = 0; i < str_size; i++) { - if (checkSentence(str[i].toCharArray())) { - System.out.println("\"" + str[i] + "\"" + " is correct"); - } else { - System.out.println("\"" + str[i] + "\"" + " is incorrect"); + System.out.println("Valid sentences are -"); + for (String sentence: list) { + if (validateSentence(sentence.toCharArray())) { + System.out.println(sentence); } } } } - -// This code is contributed by -// sanjeev2552 diff --git a/src/geeksforgeeks/HouseRobber.java b/src/geeksforgeeks/HouseRobber.java index 67b8bef..b860ad0 100644 --- a/src/geeksforgeeks/HouseRobber.java +++ b/src/geeksforgeeks/HouseRobber.java @@ -19,6 +19,25 @@ public int rob(int[] nums) { return incl; } + public int robCircular(int[] nums) { + + if(nums.length==0) return 0; + if(nums.length==1) return nums[0]; + return Math.max(helperFn(nums,0,nums.length-2), helperFn(nums,1,nums.length-1)); + + } + + public int helperFn(int[] nums, int start, int end){ + int pre=0; int cur=0; + for(int i=start;i<=end;i++){ + int temp=Math.max(pre+nums[i],cur); + pre=cur; + cur=temp; + + } + return cur; + } + public static void main(String[] args) { int[] arr = { 2, 7, 9, 3, 1 }; HouseRobber houseRobber = new HouseRobber(); diff --git a/src/geeksforgeeks/IPOMaxProfit.java b/src/geeksforgeeks/IPOMaxProfit.java index 8fa9195..5338d09 100644 --- a/src/geeksforgeeks/IPOMaxProfit.java +++ b/src/geeksforgeeks/IPOMaxProfit.java @@ -1,8 +1,11 @@ package geeksforgeeks; + + +import java.util.PriorityQueue; //https://leetcode.com/problems/ipo/ -// Input: distinctProjToFind=2, capital=0, Profits=[1,2,3], Capital=[0,1,1]. +// Input: distinctProjToFind=2, capital=0, Profits=[1,2,3], Capital=[0,1,1]. // Output: 4 // Explanation: Since your initial capital is 0, you can only start the project indexed 0. @@ -19,25 +22,25 @@ public class IPOMaxProfit { // Poll one from pqPro, it's guaranteed to be the project with max profit and within current capital capability. //Add the profit to capital W. //Repeat step 2 and 3 till finish k steps or no suitable project (pqPro.isEmpty()). - public int findMaximizedCapital(int k, int W, int[] Profits, int[] Capital) { + public int findMaximizedCapital(int steps, int initialCapital, int[] Profits, int[] Capital) { - PriorityQueue minQueue= new PriorityQueue<>((a,b)->Integer.compare(a[0],b[0])); + PriorityQueue minQueue= new PriorityQueue<>((a, b)->Integer.compare(a[0],b[0])); PriorityQueue maxQueue= new PriorityQueue<>((a,b)->Integer.compare(b[1],a[1])); for(int i=0;i2->3->4 + while (head != null) { + ListNode temp = head.next; // at first run temp=2, second run temp=3 + + /* Before insert, the prev is at the last node of the sorted list. + Only the last node's value is larger than the current inserting node + should we move the temp back to the head*/ + if (prev.val >= head.val) prev = dummy; + + // during second run prev= 0->1->null + while (prev.next != null && prev.next.val < head.val) { + prev = prev.next; + } // after this loop, at first run prev=0 (0->null), second run prev=1 + + head.next = prev.next; // we set 1->null // second run 2->null + prev.next = head; // 0->1 // 0->1->2 + + head = temp; // head= 2->3->4 // head= 3->4 } - return dummy.next; } } \ No newline at end of file diff --git a/src/geeksforgeeks/IntersectionOfArrays.java b/src/geeksforgeeks/IntersectionOfArrays.java index fac00d3..f104dd9 100644 --- a/src/geeksforgeeks/IntersectionOfArrays.java +++ b/src/geeksforgeeks/IntersectionOfArrays.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.List; /** * https://leetcode.com/problems/intersection-of-two-arrays-ii/discuss/82241/AC-solution-using-Java-HashMap @@ -25,6 +26,9 @@ public static void main(String[] args) { } public int[] intersect(int[] nums1, int[] nums2) { + //The first question is relatively easy, create a hashmap base on number frequency of nums1(whichever one is longer). + + // Then for every element of nums2, look upon the hashmap. If we found an intersection, deduct by 1 to avoid duplicate. HashMap map = new HashMap<>(); ArrayList result = new ArrayList<>(); for (int i = 0; i < nums1.length; i++) { @@ -45,4 +49,31 @@ public int[] intersect(int[] nums1, int[] nums2) { return r; } + + //What if the given array is already sorted? How would you optimize your algorithm? + // Classic two pointer iteration, i points to nums1 and j points to nums2. + // Because a sorted array is in ascending order, so if nums1[i] > nums[j], we need to increment j, and vice versa. + // Only when nums1[i] == nums[j], we add it to the result array. Time Complexity O(max(N, M)) + public int[] intersectSorted(int[] nums1, int[] nums2) { + Arrays.sort(nums1); + Arrays.sort(nums2); + int n = nums1.length, m = nums2.length; + int i = 0, j = 0; + List list = new ArrayList<>(); + while(i < n && j < m){ + int a = nums1[i], b= nums2[j]; + if(a == b){ + list.add(a); + i++; + j++; + }else if(a < b){ + i++; + }else{ + j++; + } + } + int[] ret = new int[list.size()]; + for(int k = 0; k < list.size();k++) ret[k] = list.get(k); + return ret; + } } \ No newline at end of file diff --git a/src/geeksforgeeks/IsomorphicArray.java b/src/geeksforgeeks/IsomorphicArray.java index 9064cfe..8eacfe8 100644 --- a/src/geeksforgeeks/IsomorphicArray.java +++ b/src/geeksforgeeks/IsomorphicArray.java @@ -1,13 +1,7 @@ package geeksforgeeks; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -// unresolved +import java.util.*; + public class IsomorphicArray { public Collection> groupIsomorphicStrings(List strings) { if (strings == null || strings.isEmpty()) { @@ -27,7 +21,12 @@ public Collection> groupIsomorphicStrings(List strings) { } return hashToList.values(); } - + // this method returns a hash value for every string passed in + // apple = 12234 + // apply = 12234 + // dog = 123 + // cog = 123 + // romi = 1234 private String hash(String s) { if (s.isEmpty()) { return ""; @@ -40,13 +39,18 @@ private String hash(String s) { for (char c : s.toCharArray()) { - if (map.containsKey(c)) { - hash.append(map.get(c)); - } else { + if (!map.containsKey(c)) { map.put(c, count++); - hash.append(map.get(c)); } + hash.append(map.get(c)); } + System.out.println(s +" = "+hash.toString() ); return hash.toString(); } + + public static void main(String[] args) { + Collection> result = new IsomorphicArray() + .groupIsomorphicStrings(Arrays.asList("apple", "apply", "dog", "cog", "romi")); + result.stream().forEach(System.out::println); + } } diff --git a/src/geeksforgeeks/IsomorphicString.java b/src/geeksforgeeks/IsomorphicString.java index a953099..1f41f1e 100644 --- a/src/geeksforgeeks/IsomorphicString.java +++ b/src/geeksforgeeks/IsomorphicString.java @@ -7,12 +7,13 @@ */ class IsomorphicString { static boolean isIsomorphic(String s, String t) { - int m1[] = new int[256]; - int m2[] = new int[256]; + char m1[] = new int[256]; + char m2[] = new int[256]; int n = s.length(); for (int i = 0; i < n; ++i) { // it checks the count of the character in the array ; // for 'g' -> a[103] is 2 and 'd' -> a[100] is 2 + // if both are same both gets incremented together else return false if (m1[s.charAt(i)] != m2[t.charAt(i)]) { return false; } diff --git a/src/geeksforgeeks/JumpsToReachEnd.java b/src/geeksforgeeks/JumpsToReachEnd.java index 1715a1f..7f305c1 100644 --- a/src/geeksforgeeks/JumpsToReachEnd.java +++ b/src/geeksforgeeks/JumpsToReachEnd.java @@ -3,11 +3,13 @@ import java.util.*; public class JumpsToReachEnd { + public static boolean canReachEnd(List maxAdvanceSteps) { int furthestReachSoFar = 0, lastlndex = maxAdvanceSteps.size() - 1; + //i <= furthestReachSoFar && furthestReachSoFar < lastlndex this is the imp part of the solution for (int i = 0; i <= furthestReachSoFar && furthestReachSoFar < lastlndex; ++i) { - // for every index store maxsteps it can take and i should be + // for every index store max-steps it can take and i should be // less than maxSteps to check if it can move further // e.x (3, 2, 0, 0, 2, 0,1) when index i is 3 maxStpes is also 3, it cannot move further furthestReachSoFar = Math.max(furthestReachSoFar, i + maxAdvanceSteps.get(i)); @@ -15,10 +17,11 @@ public static boolean canReachEnd(List maxAdvanceSteps) { return furthestReachSoFar >= lastlndex; } + // Given an array of non-negative integers arr, you are initially positioned at start index of the array. // When you are at index i, you can jump to i + arr[i] or i - arr[i], // check if you can reach to any index with value 0. - public boolean canReachIII(int[] arr, int start) { + public boolean canReach(int[] arr, int start) { // visited check included if(start>=arr.length || start<0 || arr[start]>arr.length || arr[start]<0) return false; if(arr[start]==0 ) return true; @@ -27,7 +30,7 @@ public boolean canReachIII(int[] arr, int start) { } - public int jump(int[] nums) { + public int minJump(int[] nums) { if(nums==null || nums.length==0) return 0; int currentMax=0; int currentEnd=0; @@ -40,7 +43,9 @@ public int jump(int[] nums) { jumps++; break; } - + //Once the current point reaches curEnd, + //then trigger another jump, and set the new curEnd with curFarthest, + //then keep the above steps, as the following: if(currentEnd==i){ // when the current pick of ladder reached last step jumps++; currentEnd=currentMax; diff --git a/src/geeksforgeeks/KClosestElements.java b/src/geeksforgeeks/KClosestElements.java index 896af45..6ea0cd5 100644 --- a/src/geeksforgeeks/KClosestElements.java +++ b/src/geeksforgeeks/KClosestElements.java @@ -1,5 +1,10 @@ package geeksforgeeks; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.PriorityQueue; + /** * Given a sorted array arr, two integers k and x, find the k closest elements to x in the array. * Input: arr = [1,2,3,4,5], k = 4, x = 3 diff --git a/src/geeksforgeeks/KmostFrequentLetters.java b/src/geeksforgeeks/KmostFrequentLetters.java index 8286aec..a5d1022 100644 --- a/src/geeksforgeeks/KmostFrequentLetters.java +++ b/src/geeksforgeeks/KmostFrequentLetters.java @@ -1,5 +1,7 @@ package geeksforgeeks; +import java.util.*; + public class KmostFrequentLetters { public static void main(String[] args) { int k1 = 2; @@ -21,7 +23,7 @@ private static List solve(int k, String[] keywords, String[] reviews) { Map map = new HashMap<>(); for(String r : reviews) { String[] strs = r.split("\\W"); - Set added = new HashSet<>(); + Set added = new HashSet<>(); // creating a set per review to vaoid duplicate within a review for(String s : strs) { s = s.toLowerCase(); if(set.contains(s) && !added.contains(s)) { @@ -30,7 +32,7 @@ private static List solve(int k, String[] keywords, String[] reviews) { } } } - Queue> maxHeap = new PriorityQueue<>((a, b)->a.getValue() == b.getValue() ? a.getKey().compareTo(b.getKey()) : b.getValue() - a.getValue()); + PriorityQueue> maxHeap = new PriorityQueue<>((a, b)->a.getValue() == b.getValue() ? a.getKey().compareTo(b.getKey()) : b.getValue() - a.getValue()); maxHeap.addAll(map.entrySet()); while(!maxHeap.isEmpty() && k-- > 0) { res.add(maxHeap.poll().getKey()); diff --git a/src/geeksforgeeks/LIS2DMatrix.java b/src/geeksforgeeks/LIS2DMatrix.java index 96e5717..5ea3e62 100644 --- a/src/geeksforgeeks/LIS2DMatrix.java +++ b/src/geeksforgeeks/LIS2DMatrix.java @@ -1,54 +1,52 @@ package geeksforgeeks; -/** - * DFS + Memoization - * - * Traverse all points in matrix, use every point as starting point to do dfs traversal. DFS function returns max increasing - * path after comparing four max return distance from four directions. - * - * @param cache: cache[i][j] represents longest increasing path starts from point matrix[i][j] - * @param prev: previous value used by DFS traversal, to compare whether current value is greater than previous value - * */ +/** + * DFS + Memoization + *

+ * Traverse all points in matrix, use every point as starting point to do dfs traversal. DFS function returns max increasing + * path after comparing four max return distance from four directions. + */ class LIS2DMatrix { - int[][] dirs= new int[][] {{1,0},{-1,0},{0,1},{0,-1}}; - public int longestIncreasingPath(int[][] matrix) { - if(matrix.length == 0) return 0; - // i+1,j, i-1,j i,j+1 i,j-1 - Integer[][] cache= new Integer[matrix.length][matrix[0].length]; - //Arrays.fill(cache,-1); - int result=0; - for(int i=0;i=matrix.length || j<0 || j>=matrix[0].length|| data>=matrix[i][j]) return 0; - - - - if(cache[i][j]!=null) return cache[i][j]; - - int max=1; - - for(int[] dir: dirs){ - - int x=i+dir[0]; - int y=j+dir[1]; - - int count=1+dfsUtil(matrix,x,y,cache, matrix[i][j]); - max=Math.max(count,max); - } - cache[i][j]=max; - - return cache[i][j]; - - } - + int[][] dirs = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; + + public int longestIncreasingPath(int[][] matrix) { + + if (matrix.length == 0) return 0; + // i+1,j, i-1,j i,j+1 i,j-1 + Integer[][] cache = new Integer[matrix.length][matrix[0].length]; + //Arrays.fill(cache,-1); + int result = 0; + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix[0].length; j++) { + result = Math.max(dfsUtil(matrix, i, j, cache, Integer.MIN_VALUE), result); + } + } + + return result; + } + + public int dfsUtil(int[][] matrix, int i, int j, Integer[][] cache, int data) { + if (i < 0 || i >= matrix.length || j < 0 || j >= matrix[0].length || data >= matrix[i][j]) return 0; + + + if (cache[i][j] != null) return cache[i][j]; + + int max = 1; // every element is an answer to itself + + for (int[] dir : dirs) { + + int x = i + dir[0]; + int y = j + dir[1]; + + int count = 1 + dfsUtil(matrix, x, y, cache, matrix[i][j]); + max = Math.max(count, max); + } + cache[i][j] = max; + + return cache[i][j]; + + } + } \ No newline at end of file diff --git a/src/geeksforgeeks/LargestDivisibleSubset.java b/src/geeksforgeeks/LargestDivisibleSubset.java index 67f81cc..e52f5d2 100644 --- a/src/geeksforgeeks/LargestDivisibleSubset.java +++ b/src/geeksforgeeks/LargestDivisibleSubset.java @@ -1,5 +1,10 @@ package geeksforgeeks; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + /** * Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of elements in this subset satisfies: Si % Sj = 0 or Sj % Si = 0. @@ -37,13 +42,13 @@ public List largestDivisibleSubset(int[] nums) { List re; for(int i=nums.length-1;i>=0;i--){ - result[i]=new ArrayList<>(); + result[i]=new ArrayList<>(); // every element is an answer itself re= new ArrayList<>(); result[i].add(nums[i]); for(int j=i+1;j re.size()){ - re=result[j]; + if(result[j].size() > re.size()){ // this is to take even if 1 element is at j position + re=result[j]; // the reason we take list is consider 4,8,24 when i is at 4 and j is 8 mod is 0 means 4%24 is also zero } } } diff --git a/src/geeksforgeeks/LargestSubArrayWithZeroesAndOnes.java b/src/geeksforgeeks/LargestSubArrayWithZeroesAndOnes.java index caae00e..2d5e893 100644 --- a/src/geeksforgeeks/LargestSubArrayWithZeroesAndOnes.java +++ b/src/geeksforgeeks/LargestSubArrayWithZeroesAndOnes.java @@ -2,53 +2,67 @@ import java.util.HashMap; -/*https://www.geeksforgeeks.org/largest-subarray-with-equal-number-of-0s-and-1s/*/ -class LargestSubArrayWithZeroesAndOnes { - - int maxLen(int arr[], int n) { - - HashMap map = new HashMap<>(); - - int sum = 0; - int maxLength = 0; - int endingIndex = -1; - - for (int i = 0; i < n; i++) { - arr[i] = (arr[i] == 0) ? -1 : 1; - } - - for (int i = 0; i < n; i++) { - sum += arr[i]; - if (sum == 0) { - maxLength = i + 1; - endingIndex = i; - } - - if (map.containsKey(sum)) { - if (maxLength < i - map.get(sum)) { - maxLength = i - map.get(sum); - endingIndex = i; - } - } else { - map.put(sum, i); - } - } - - for (int i = 0; i < n; i++) { - arr[i] = (arr[i] == -1) ? 0 : 1; - } - - int start = endingIndex - maxLength + 1; - System.out.println(start + " to " + endingIndex); - - return maxLength; - } - - public static void main(String[] args) { - LargestSubArrayWithZeroesAndOnes sub = new LargestSubArrayWithZeroesAndOnes(); - int arr[] = { 0, 0, 0, 1, 0, 1, 1 }; - int n = arr.length; - - sub.maxLen(arr, n); - } -} +/*https://www.geeksforgeeks.org/largest-subarray-with-equal-number-of-0s-and-1s/ + Given an array containing only 0s and 1s, find the largest subarray which contains equal no of 0s and 1s. + Expected time complexity is O(n). +*/ +class LargestSubArrayWithZeroesAndOnes { + /** + * The concept of taking cumulative sum, taking 0’s as -1 will help us in optimising the approach. + * While taking the cumulative sum, there are two cases when there can be a sub-array with equal number of 0’s and 1’s + * When cumulative sum=0, which signifies that sub-array from index (0) till present index has equal number of 0’s and 1’s. + * + * When we encounter a cumulative sum value which we have already encountered before, + * which means that sub-array from the previous index+1 till the present index has equal number of 0’s and 1’s as they give a cumulative sum of 0 . + * @param arr + * @param n + * @return + */ + int maxLen(int arr[], int n) { + + HashMap map = new HashMap<>(); + + int sum = 0; + int maxLength = 0; + int endingIndex = -1; + + for (int i = 0; i < n; i++) { + arr[i] = (arr[i] == 0) ? -1 : 1; + } + + for (int i = 0; i < n; i++) { + sum += arr[i]; + + if (sum == 0) { // To handle sum=0 at last index + maxLength = i + 1; + endingIndex = i; + } + // If this sum is seen before, + // then update max_len if required + if (map.containsKey(sum)) { + if (maxLength < i - map.get(sum)) { + maxLength = i - map.get(sum); + endingIndex = i; + } + } else + map.put(sum, i); + } + + for (int i = 0; i < n; i++) { + arr[i] = (arr[i] == -1) ? 0 : 1; + } + + int start = endingIndex - maxLength + 1; + System.out.println(start + " to " + endingIndex); + + return maxLength; + } + + public static void main(String[] args) { + LargestSubArrayWithZeroesAndOnes sub = new LargestSubArrayWithZeroesAndOnes(); + int arr[] = {0, 0, 0, 1, 0, 1, 1}; + int n = arr.length; + + sub.maxLen(arr, n); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/LongestConsequtiveSequence.java b/src/geeksforgeeks/LongestConsequtiveSequence.java index 7542c7f..1eea844 100644 --- a/src/geeksforgeeks/LongestConsequtiveSequence.java +++ b/src/geeksforgeeks/LongestConsequtiveSequence.java @@ -1,9 +1,19 @@ package geeksforgeeks; +import java.util.Arrays; import java.util.HashSet; import java.util.Set; +/** + * Given an unsorted array of integers, find the length of the longest consecutive elements sequence. + * + * Your algorithm should run in O(n) complexity. + * Input: [100, 4, 200, 1, 3, 2] + * Output: 4 + * Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4. + */ class LongestConsequtiveSequence { + public int longestConsecutive(int[] nums) { if (nums.length == 0) { return 0; @@ -13,7 +23,8 @@ public int longestConsecutive(int[] nums) { for (int i : nums) { set.add(i); } - + // have a set, go backwards and remove entries, go forward remove entries and calculate Max + // without removing entries, runtime would be too much for (Integer i : nums) { int num = i; int count = 1; @@ -33,4 +44,28 @@ public int longestConsecutive(int[] nums) { return max; } + + public int longestConsecutiveSorting(int[] nums) { + if (nums == null || nums.length == 0) + return 0; + + Arrays.sort(nums); + + int longestStreak = 1; + int currentStreak = 1; + + for (int i = 0; i < nums.length - 1; i++) { + if (nums[i] != nums[i+1]) { // avoid duplicate + if (nums[i] + 1 == nums[i+1]) { // if increasing increase streak count else reset + currentStreak += 1; + } + else { + longestStreak = Math.max(longestStreak, currentStreak); + currentStreak = 1; + } + } + } + + return Math.max(longestStreak, currentStreak); + } } \ No newline at end of file diff --git a/src/geeksforgeeks/LongestIncreasingPath.java b/src/geeksforgeeks/LongestIncreasingPath.java deleted file mode 100644 index 3b8cbf5..0000000 --- a/src/geeksforgeeks/LongestIncreasingPath.java +++ /dev/null @@ -1,66 +0,0 @@ -package geeksforgeeks; - -/** - * https://leetcode.com/problems/longest-increasing-path-in-a-matrix/discuss/78308/15ms-Concise-Java-Solution - */ -public class LongestIncreasingPath { - - /** - * DFS + Memoization - *

- * Traverse all points in matrix, use every point as starting point to do dfs traversal. DFS function returns max increasing - * path after comparing four max return distance from four directions. - * - * @param cache: cache[i][j] represents longest increasing path starts from point matrix[i][j] - * @param prev: previous value used by DFS traversal, to compare whether current value is greater than previous value - */ - static final int[][] dirs = new int[][] { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }; - - public static int longestIncreasingPath(int[][] matrix) { - if (matrix.length == 0) { - return 0; - } - - int result = 0; - int n = matrix.length; - int m = matrix[0].length; - Integer[][] cache = new Integer[n][m]; - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) { - int curLen = dfsUtil(matrix, i, j, cache, -1); - result = Math.max(result, curLen); - } - } - return result; - } - - public static int dfsUtil(int[][] matrix, int i, int j, Integer[][] cache, int data) { - - if (i < 0 || i >= matrix.length || j < 0 || j >= matrix[0].length || data >= matrix[i][j]) { - return 0; - } - - if (cache[i][j] != null) { - return cache[i][j]; - } - - int currLength = 1; - - for (int[] dir : dirs) { - - int x = i + dir[0]; - int y = j + dir[1]; - - int count = 1 + dfsUtil(matrix, x, y, cache, matrix[i][j]); - currLength = Math.max(count, currLength); - } - cache[i][j] = currLength; - - return cache[i][j]; - } - - public static void main(String[] args) { - int[][] arr = { { 9, 9, 4 }, { 6, 6, 8 }, { 2, 1, 1 } }; - System.out.println(longestIncreasingPath(arr)); - } -} diff --git a/src/geeksforgeeks/LongestSpanWithSameSumArray.java b/src/geeksforgeeks/LongestSpanWithSameSumArray.java index 9fca542..dee75cb 100644 --- a/src/geeksforgeeks/LongestSpanWithSameSumArray.java +++ b/src/geeksforgeeks/LongestSpanWithSameSumArray.java @@ -1,34 +1,62 @@ package geeksforgeeks; -import java.util.HashMap; - /*https://www.geeksforgeeks.org/longest-span-sum-two-binary-arrays/*/ class LongestSpanWithSameSumArray { static int longestCommonSum(int[] arr1, int[] arr2, int n) { - int[] arr = new int[n]; - for (int i = 0; i < n; i++) - arr[i] = arr1[i] - arr2[i]; + int maxLen = 0; - HashMap map = new HashMap<>(); + // Initialize prefix sums of two arrays + int preSum1 = 0, preSum2 = 0; - int sum = 0; - int maxLength = 0; + // Create an array to store staring and ending + // indexes of all possible diff values. diff[i] + // would store starting and ending points for + // difference "i-n" - for (int i = 0; i < n; i++) { - sum += arr[i]; + int diff[] = new int[2*n+1]; - if (sum == 0) { - maxLength = i + 1; - } + // Initialize all starting and ending values as -1. + for (int i = 0; i < diff.length; i++) { + diff[i] = -1; + } + + // Traverse both arrays + for (int i=0; i maxLen) + maxLen = len; } } - return maxLength; + return maxLen; } public static void main(String args[]) { diff --git a/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java b/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java index 305b73f..97589ed 100644 --- a/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java +++ b/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java @@ -1,33 +1,52 @@ package geeksforgeeks; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * Given an array arr[] containing n elements. The problem is to find maximum number of distinct elements (non-repeating) after removing k elements from the array. + * Input : arr[] = {5, 7, 5, 5, 1, 2, 2}, k = 3 + * Output : 4 + * + * Remove 2 occurrences of element 5 and + * 1 occurrence of element 2. + * + * Input : arr[] = {1, 2, 3, 4, 5, 6, 7}, k = 5 + * Output : 2 + */ public class MaxDistinctElementAfterKRemoval { - // after removing k elements + // after removing k elements + + /** + * Create a hash table to store the frequency of each element. + * Insert frequency of each element in a max heap. + * Now, perform the following operation k times. + * Remove an element from the max heap. Decrement its value by 1. After this if element is not equal to 0, then again push the element in the max heap. + * @param arr + * @param n + * @param k + * @return + */ static int maxDistinctNum(int[] arr, int n, int k) { // hash map to store // frequency of each element - HashMap map = new HashMap<>(); + HashMap map = new HashMap<>(); // priority_queue 'pq' implemented as // max heap - PriorityQueue pq = - new PriorityQueue<>(Collections.reverseOrder()); + PriorityQueue pq = + new PriorityQueue<>(Collections.reverseOrder()); // storing frequency of each element in map - for (int i = 0; i < n; i++) { - if(map.containsKey(arr[i])) { - int val = map.get(arr[i]); - val++; - map.remove(arr[i]); - map.put(arr[i], val); - } - - else - map.put(arr[i], 1); + for (int i = 0; i < n; i++) { + map.put(arr[i], map.getOrDefault(arr[i],0)+1); } // inserting frequency of each element in 'pq' - for (Map.Entry entry : map.entrySet()) { + for (Map.Entry entry : map.entrySet()) { pq.add(entry.getValue()); } @@ -53,5 +72,46 @@ static int maxDistinctNum(int[] arr, int n, int k) } return res; - } + } + + /** + * Given an array of integers arr and an integer k. Find the least number of unique integers after removing exactly k elements. + * Input: arr = [5,5,4], k = 1 + * Output: 1 + * Explanation: Remove the single 4, only 5 is left. + * + * Input: arr = [4,3,1,1,3,3,2], k = 3 + * Output: 2 + * Explanation: Remove 4, 2 and either one of the two 1s or three 3s. 1 and 3 will be left. + * @param arr + * @param k + * @return + */ + public int findLeastNumOfUniqueInts(int[] arr, int k) { + if(arr.length==0) return 0; + Map frequencyMap= new HashMap<>(); + + for(int i: arr){ + frequencyMap.put(i,frequencyMap.getOrDefault(i,0)+1); + } + + PriorityQueue maxQueue= new PriorityQueue<>(); + + for(Map.Entry entry: frequencyMap.entrySet()){ + maxQueue.offer(entry.getValue()); + } + + while(k-- >0){ + int temp= maxQueue.poll(); + temp-=1; + if(temp>0) maxQueue.offer(temp); + + } + + int result=0; + while(!maxQueue.isEmpty()){ + result++; + } + return result; + } } \ No newline at end of file diff --git a/src/geeksforgeeks/MaxFreqStack.java b/src/geeksforgeeks/MaxFreqStack.java index e628b82..624051d 100644 --- a/src/geeksforgeeks/MaxFreqStack.java +++ b/src/geeksforgeeks/MaxFreqStack.java @@ -1,12 +1,40 @@ package geeksforgeeks; +import java.util.HashMap; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * FreqStack has two functions: + * + * push(int x), which pushes an integer x onto the stack. + * pop(), which removes and returns the most frequent element in the stack. + * If there is a tie for most frequent element, the element closest to the top of the stack is removed and returned. + * ["FreqStack","push","push","push","push","push","push","pop","pop","pop","pop"], + * [[],[5],[7],[5],[7],[4],[5],[],[],[],[]] + * Output: [null,null,null,null,null,null,null,5,7,5,4] + * Explanation: + * After making six .push operations, the stack is [5,7,5,7,4,5] from bottom to top. Then: + * + * pop() -> returns 5, as 5 is the most frequent. + * The stack becomes [5,7,5,7,4]. + * + * pop() -> returns 7, as 5 and 7 is the most frequent, but 7 is closest to the top. + * The stack becomes [5,7,5,4]. + * + * pop() -> returns 5. + * The stack becomes [5,7,4]. + * + * pop() -> returns 4. + * The stack becomes [5,7]. + */ public class MaxFreqStack { - PriorityQueue maxQueue; + PriorityQueue maxQueue; Map hashMap; int sequence = 0; - public FreqStack() { + public MaxFreqStack() { maxQueue= new PriorityQueue<>((a,b)->{ if(a.frequency==b.frequency){ @@ -19,26 +47,26 @@ public FreqStack() { public void push(int x) { hashMap.put(x, hashMap.getOrDefault(x, 0) + 1); - maxQueue.offer(new Entry(x, hashMap.get(x), sequence++)); + maxQueue.offer(new EntryStack(x, hashMap.get(x), sequence++)); } public int pop() { - Entry temp = maxQueue.poll(); + EntryStack temp = maxQueue.poll(); hashMap.put(temp.val, temp.frequency - 1); return temp.val; } } -// 1. val // value of the number -// 2. frequency // current frequency of the number when it was pushed to the heap -// 3. sequenceNumber // a sequence number, to know what number came first -class Entry { +// 1. val = value of the number +// 2. frequency = current frequency of the number when it was pushed to the heap +// 3. sequenceNumber = a sequence number, to know what number came first +class EntryStack { int val; int frequency; int sequence; - public Entry(int val, int frequency, int sequence) { + public EntryStack(int val, int frequency, int sequence) { this.val = val; this.frequency = frequency; this.sequence = sequence; diff --git a/src/geeksforgeeks/MaxHistogram.java b/src/geeksforgeeks/MaxHistogram.java index 97077db..a860ddd 100644 --- a/src/geeksforgeeks/MaxHistogram.java +++ b/src/geeksforgeeks/MaxHistogram.java @@ -1,38 +1,64 @@ package geeksforgeeks; -import java.util.Stack; +import java.util.Arrays; /** * https://leetcode.com/problems/largest-rectangle-in-histogram/ */ -//unsolved + public class MaxHistogram { - public static int largestRectangleArea(int[] heights) { - if (heights == null || heights.length == 0) { + //For any bar i the maximum rectangle is of width r - l - 1 + // where r - is the last coordinate of the bar to the right with height h[r] >= h[i] and + // l - is the last coordinate of the bar to the left which height h[l] >= h[i] + //So if for any i coordinate we know his utmost higher (or of the same height) neighbors to the right and to the left, + // we can easily find the largest rectangle: maxArea = Math.max(maxArea, height[i] * (lessFromRight[i] - lessFromLeft[i] - 1)); + + //The main trick is how to effectively calculate lessFromRight and lessFromLeft arrays. + // The trivial solution is to use O(n^2) solution and for each i element + // first find his left/right neighbour in the second inner loop just iterating back or forward: + public static int largestRectangleArea(int[] height) { + if (height == null || height.length == 0) { return 0; } - if (heights.length == 1) { - return heights[0]; - } - int result = 0; - Stack stack = new Stack(); - //i<=heights because it needs to cross the ith pos to calculate the right boundary - for (int i = 0; i <= heights.length; ) { - int h = (i == heights.length ? 0 : heights[i]); - if (stack.isEmpty() || h >= heights[stack.peek()]) { - stack.push(i); - i++; - } else { - int height = heights[stack.pop()]; - int rightboundary = i - 1; - int leftboundary = stack.isEmpty() ? 0 : stack.peek() + 1; - int width = rightboundary - leftboundary + 1; - result = Math.max(result, height * width); + int[] lessFromLeft = new int[height.length]; // idx of the first bar the left that is lower than current + int[] lessFromRight = new int[height.length]; // idx of the first bar the right that is lower than current + lessFromRight[height.length - 1] = height.length; + lessFromLeft[0] = -1; + + // for example in order to lessFromLeft[i]; if height[i - 1] < height[i] then left[i] = i - 1; + // other wise we do not need to start scan from i - 1; we can start the scan from lessFromLeft[i - 1], + // because since lessFromLeft[i - 1] is the first position to the left of i - 1 that have height less than height[i - 1], + // and we know height[i - 1] >= height[i]; so lessFromLeft[i] must be at the left or at lessFromLeft[i - 1]; similar for the right array; + for (int i = 1; i < height.length; i++) { + int p = i - 1; + + while (p >= 0 && height[p] >= height[i]) { + p = lessFromLeft[p]; } + lessFromLeft[i] = p; } - return result; + for (int i = height.length - 2; i >= 0; i--) { + int p = i + 1; + + while (p < height.length && height[p] >= height[i]) { + p = lessFromRight[p]; + } + lessFromRight[i] = p; + } + // after both the loop ends, this is the output of left and right + // input [2, 1, 5, 6, 2, 3] + // 0, 1, ,2 3, 4, 5 + // left [-1, -1, 1, 2, 1, 4] => indexes of elements + // right [1, 6, 4, 4, 6, 6] + int maxArea = 0; + for (int i = 0; i < height.length; i++) { + maxArea = Math.max(maxArea, height[i] * (lessFromRight[i] - lessFromLeft[i] - 1)); + } + System.out.println(Arrays.toString(lessFromLeft)); + System.out.println(Arrays.toString(lessFromRight)); + return maxArea; } public static void main(String[] args) { diff --git a/src/geeksforgeeks/MaxProductString.java b/src/geeksforgeeks/MaxProductString.java index 2306d75..54bb75d 100644 --- a/src/geeksforgeeks/MaxProductString.java +++ b/src/geeksforgeeks/MaxProductString.java @@ -1,5 +1,17 @@ package geeksforgeeks; +/** + * Given a string array words, find the maximum value of length(word[i]) * length(word[j]) + * where the two words do not share common letters. + * You may assume that each word will contain only lower case letters + * Input: ["abcw","baz","foo","bar","xtfn","abcdef"] + * Output: 16 + * Explanation: The two words can be "abcw", "xtfn". + * + * Input: ["a","aa","aaa","aaaa"] + * Output: 0 + * Explanation: No such pair of words. + */ public class MaxProductString { public int maxProduct(String[] words) { int[] checker = new int[words.length]; @@ -8,11 +20,11 @@ public int maxProduct(String[] words) { for (int i = 0; i < checker.length; i++) { int num = 0; for (int j = 0; j < words[i].length(); j++) { - - // a 1->1 - // b 2->10 + // we are making char index in bit to be set + // a 1->1 making first bit marked + // b 2->10 // c 4->100 - // ab 3->11 + // ab 3->11 // making first and secind marked // ac 5->101 // abc 7->111 // az 33554433->10000000000000000000000001 diff --git a/src/geeksforgeeks/MaxWidthOfBinaryTree.java b/src/geeksforgeeks/MaxWidthOfBinaryTree.java new file mode 100644 index 0000000..18d47bb --- /dev/null +++ b/src/geeksforgeeks/MaxWidthOfBinaryTree.java @@ -0,0 +1,56 @@ +package geeksforgeeks; + +/** + * Given a binary tree, write a function to get the maximum width of the given tree. + * The width of a tree is the maximum width among all levels. + * The binary tree has the same structure as a full binary tree, but some nodes are null + * + * Input: + + 1 + / \ + 3 2 + / \ + 5 9 + / \ + 6 7 +Output: 8 +The maximum width existing in the fourth level with the length 8 (6,null,null,null,null,null,null,7). + */ +public class MaxWidthOfBinaryTree { + + // Each time a node is traversed, the position of the node(as it is in a full binary tree) is stored in the HashMap. + //If the position of the parent node is 'n', then the left child is '2 * n' and the right child is '2 * n + 1'. + //The width of each level is the last node's position in this level subtracts the first node's position in this level plus 1. + public int widthOfBinaryTree(TreeNode root) { + if(root==null) return 0; + int maxWidth=0; + + Map map= new HashMap<>(); + Queue stack=new LinkedList(); + stack.offer(root); + map.put(root,1); // if we are assigning head as 0 then the fourmula is left=>2*n+1, right=> 2*n+2 + while(!stack.isEmpty()){ + int width= stack.size(); + int start=0; + int end=0; + for(int i=0;i Radix sort + */ +public class MaximumGap { + // The first step is to find the maximum value in nums array, it will + // be the threshold to end while loop. + // Then use the radix sort algorithm to sort based on each digit from Least Significant Bit + // (LSB) to Most Significant Bit (MSB), that's exactly what's showing + // in the link. + // (nums[i] / exp) % 10 is used to get the digit, for each digit, basically the digit itself serves as the index to + // access the count array. Count array stores the index to access aux + // array which stores the numbers after sorting based on the current + // digit. + // Finally, find the maximum gap from sorted array. + // Time and space complexities are both O(n). (Actually time is O(10n) at worst case for Integer.MAX_VALUE 2147483647) + public int maximumGap(int[] nums) { + if (nums == null || nums.length < 2) { + return 0; + } + + // m is the maximal number in nums + int m = nums[0]; + for (int i = 1; i < nums.length; i++) { + m = Math.max(m, nums[i]); + } + + int exp = 1; // 1, 10, 100, 1000 ... + int R = 10; // 10 digits + + int[] aux = new int[nums.length]; + + while (m / exp > 0) { // Go through all digits from LSB to MSB + int[] count = new int[R]; + + for (int i = 0; i < nums.length; i++) { + count[(nums[i] / exp) % 10]++; + } + + for (int i = 1; i < count.length; i++) { + count[i] += count[i - 1]; + } + + for (int i = nums.length - 1; i >= 0; i--) { + aux[--count[(nums[i] / exp) % 10]] = nums[i]; + } + + for (int i = 0; i < nums.length; i++) { + nums[i] = aux[i]; + } + exp *= 10; + } + + int max = 0; + for (int i = 1; i < aux.length; i++) { + max = Math.max(max, aux[i] - aux[i - 1]); + } + + return max; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MaximumUnsortedSubarray.java b/src/geeksforgeeks/MaximumUnsortedSubarray.java index 3c1b06f..b9a436e 100644 --- a/src/geeksforgeeks/MaximumUnsortedSubarray.java +++ b/src/geeksforgeeks/MaximumUnsortedSubarray.java @@ -5,7 +5,16 @@ import java.util.List; //https://leetcode.com/problems/shortest-unsorted-continuous-subarray/ - +/** + * Given an integer array, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order, too. + * + * You need to find the shortest such subarray and output its length. + * + * Example 1: + * Input: [2, 6, 4, 8, 10, 9, 15] + * Output: 5 + * Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order. + */ public class MaximumUnsortedSubarray { public static ArrayList subarraySort(final ArrayList A) { diff --git a/src/geeksforgeeks/MinimumBribes.java b/src/geeksforgeeks/MinimumBribes.java new file mode 100644 index 0000000..2107aa4 --- /dev/null +++ b/src/geeksforgeeks/MinimumBribes.java @@ -0,0 +1,50 @@ +package geeksforgeeks; +/** + * https://www.hackerrank.com/challenges/new-year-chaos/problem + * https://www.youtube.com/watch?v=UpmVTEvaXPE + * Any person in the queue can bribe the person directly in front of them to swap positions. + * If two people swap positions, they still wear the same sticker denoting their original place in line. + * One person can bribe at most two other persons. + * That is to say, if n = 8, and Person 5 bribes Person 4, the queue will look like this: 1,2,3,5,4,6,7,8. + * Fascinated by this chaotic queue, you decide you must know the minimum number of bribes that took place to get the queue into its current state! + * + * No person can bribe more than 2 persons if yes then print chaotic + * Input: 2 1 5 3 4 + * Output: 3 + * + * Input: 2 5 1 3 4 + * Output: Too chaotic + */ +public class MinimumBribes { + // input is 2 1 5 3 4, + // when index is at 2(val=>5) we see how many elements lesser than 5 is there + // if the value is greater that 2 we print too chaotic + // else we add it to result + void minimumBribes(int[] q) { + int bribes=0; + for(int i = q.length-1; i >= 0; i--) { + + if(i-1>=0 && q[i-1]==i+1){ + q[i-1]=q[i]; + q[i]=i+1; + bribes+=1; + } else if(i-2>=0 && q[i-2]==i+2){ + //2,1,5,3,4 we need to swap 2 elements to restore the array + q[i-2]=q[i-1]; + q[i-1]=q[i]; + q[i]=i+1; + bribes+=2; + }else{ + System.out.println("Too Chaotic"); + return; + } + } + System.out.println(bribes); + } + + public static void main(String[] args) { + // inputs 5,1,2,3,7,8,6,4 => too chaotic + // 1,2,5,3,7,8,6,4 => 7 + new MinimumBribes().minimumBribes(new int[]{2,1,5,3,4}); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java b/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java index fc8651d..c4c888a 100644 --- a/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java +++ b/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java @@ -1,7 +1,21 @@ package geeksforgeeks; -/*https://www.geeksforgeeks.org/find-the-minimum-distance-between-two-numbers/*/ +/* +https://www.geeksforgeeks.org/find-the-minimum-distance-between-two-numbers/ + +Given an unsorted array arr[] and two numbers x and y, find the minimum distance between x and y in arr[]. +The array might also contain duplicates. +You may assume that both x and y are different and present in arr[]. + +Input: arr[] = {2, 5, 3, 5, 4, 4, 2, 3}, +x = 3, y = 2 +Output: Minimum distance between 3 +and 2 is 1. +Explanation:3 is at index 7 and 2 is at +index 6, so the distance is 1 +*/ + class MinimumDistanceBetweenTwoNumbers { @@ -19,7 +33,8 @@ int minDist(int arr[], int n, int x, int y) { break; } } - + // sort of like sliding window tracks the first occurence + // of the element and check if both are not same and calculates the distance for (; i < n; i++) { if (arr[i] == x || arr[i] == y) { // check if current element and prev element are different diff --git a/src/geeksforgeeks/MinimumSwapSortArray.java b/src/geeksforgeeks/MinimumSwapSortArray.java index 26d3d1b..662e278 100644 --- a/src/geeksforgeeks/MinimumSwapSortArray.java +++ b/src/geeksforgeeks/MinimumSwapSortArray.java @@ -1,46 +1,124 @@ package geeksforgeeks; -import java.util.Map; -import java.util.TreeMap; +import java.util.Collections; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; + /** * https://www.geeksforgeeks.org/minimum-number-swaps-required-sort-array/ */ class MinimumSwapSortArray { + private static class Pair { + T key; + I value; + + public T getKey() { + return key; + } - public int minSwaps(int[] A, int N) { - int i = 0; - // Tree map sorts the order - Map treeMap = new TreeMap<>(); - for (; i < N; i++) { - System.out.print(A[i] + " --> " + i + " "); - treeMap.put(A[i], i); + public I getValue() { + return value; } - System.out.println(); - i = 0; - for (Map.Entry entry : treeMap.entrySet()) { - System.out.print(entry.getKey() + " --> " + i + " "); - entry.setValue(i++); + + public void setKey(T key) { + this.key = key; + } + + public void setValue(I value) { + this.value = value; } - int swap = 0; - for (i = 0; i < N; ) { - System.out.println(A[i] + "--" + treeMap.get(A[i]) + "--" + i); - // check if array position is same as treeMap's index - if (treeMap.get(A[i]) != i) { - int temp = A[i]; - A[i] = A[treeMap.get(temp)]; - A[treeMap.get(temp)] = temp; - swap++; - } else { - i++; + public Pair(T key, I value){ + this.key=key; + this.value=value; + } + + @Override + public String toString() { + return "Pair{" + + "key=" + key + + ", value=" + value + + '}'; + } + } + + public static int minSwaps(int[] arr) { + int n = arr.length; + + // Create two arrays and use as pairs where first + // array is element and second array + // is position of first element + ArrayList> arrpos = + new ArrayList>(); + for (int i = 0; i < n; i++) + arrpos.add(new Pair(arr[i], i)); + + // Sort the array by array element values to + // get right position of every element as the + // elements of second array. + Collections.sort(arrpos, (a,b)-> { + if (a.getKey() == b.getKey()) { + return 0; + } + return Integer.compare(b.getKey(), a.getKey()); + }); + // arrpos.sort(new Comparator>() { + // @Override + // public int compare(Pair o1, + // Pair o2) { + // if (o1.getKey() > o2.getKey()) + // return -1; + + // // We can change this to make it then look at the + // // words alphabetical order + // else if (o1.getKey().equals(o2.getKey())) + // return 0; + + // else + // return 1; + // } + // }); + System.out.println(arrpos); + // To keep track of visited elements. Initialize + // all elements as not visited or false. + Boolean[] vis = new Boolean[n]; + Arrays.fill(vis, false); + + // Initialize result + int ans = 0; + + // Traverse array elements + for (int i = 0; i < n; i++) { + // already swapped and corrected or + // already present at correct pos + if (vis[i] || arrpos.get(i).getValue() == i) + continue; + + // find out the number of node in + // this cycle and add in ans + int cycle_size = 0; + int j = i; + while (!vis[j]) { + vis[j] = true; + + // move to next node + j = arrpos.get(j).getValue(); + cycle_size++; + } + + // Update answer by adding current cycle. + if (cycle_size > 0) { + ans += (cycle_size - 1); } } - return swap; + + // Return result + return ans; } public static void main(String[] args) { - int[] a = { 1, 5, 4, 3, 2 }; - MinimumSwapSortArray g = new MinimumSwapSortArray(); - System.out.println(g.minSwaps(a, a.length)); + int[] a = {1, 5, 4, 3, 2}; + System.out.println(minSwaps(a)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/MinimumWindowSubsequence.java b/src/geeksforgeeks/MinimumWindowSubsequence.java index 2e4c2ca..4e67c90 100644 --- a/src/geeksforgeeks/MinimumWindowSubsequence.java +++ b/src/geeksforgeeks/MinimumWindowSubsequence.java @@ -1,45 +1,80 @@ package geeksforgeeks; -import java.util.Arrays; - -/*https://www.programcreek.com/2014/01/leetcode-minimum-window-subsequence-java/*/ +/** + * Input: + * S = "abcdebdde", T = "bde" + * Output: "bcde" + * Explanation: + * "bcde" is the answer because it occurs before "bdde" which has the same length. + * "deb" is not a smaller window because the elements of T in the window must occur in order. + */ // unresolved -public class MinimumWindowSubsequence { - - public static String minWindow(String S, String T) { - int m = T.length(), n = S.length(); - int[][] dp = new int[m + 1][n + 1]; - // fill first row with index values - for (int j = 0; j <= n; j++) { - dp[0][j] = j + 1; +public class MinimumWindowSubsequence { + public String minWindow(String S, String T) { + if (S.length() == 0 || T.length() == 0) { + return ""; } - // if any element is not present then it will set that row as zero so there wont - // be any valid values in last row - for (int i = 1; i <= m; i++) { - for (int j = 1; j <= n; j++) { - if (T.charAt(i - 1) == S.charAt(j - 1)) { - dp[i][j] = dp[i - 1][j - 1]; - } else { - dp[i][j] = dp[i][j - 1]; + + /** + * we can conduct two steps by using two pointers for this probelm: + * 1. check feasibility from left to right + * 2. check optimization from right to left + * we can traverse from left to right, find a possible candidate until reach the first ending character of T + * eg: for the string s = abcdebdde and t = bde, we should traverse s string until we find first e, + * i.e. abcde, then traverse back from current "e" to find if we have other combination of bde with smaller + * length. + * @param right: fast pointer that always points the last character of T in S + * @param left: slow pointer that used to traverse back when right pointer find the last character of T in S + * @param tIndex: third pointer used to scan string T + * @param minLen: current minimum length of subsequence + * */ + int right = 0; + int minLen = Integer.MAX_VALUE; + String result = ""; + + while (right < S.length()) { + int tIndex = 0; + // use fast pointer to find the last character of T in S + while (right < S.length()) { + if (S.charAt(right) == T.charAt(tIndex)) { + tIndex++; + } + if (tIndex == T.length()) { + break; } + right++; + } + + // if right pointer is over than boundary + if (right == S.length()) { + break; } - } - int start = 0; - int len = n + 1; - for (int j = 1; j <= n; j++) { - if (dp[m][j] != 0) { - if (j - dp[m][j] + 1 < len) { - start = dp[m][j] - 1; - len = j - dp[m][j] + 1; + // use another slow pointer to traverse from right to left until find first character of T in S + int left = right; + tIndex = T.length() - 1; + while (left >= 0) { + if (S.charAt(left) == T.charAt(tIndex)) { + tIndex--; } + if (tIndex < 0) { + break; + } + left--; + } + // if we found another subsequence with smaller length, update result + if (right - left + 1 < minLen) { + minLen = right - left + 1; + result = S.substring(left, right + 1); } + // WARNING: we have to move right pointer to the next position of left pointer, NOT the next position + // of right pointer + right = left + 1; } - System.out.println(Arrays.deepToString(dp)); - return len == n + 1 ? "" : S.substring(start, start + len); + return result; } - public static void main(String args[]) { - System.out.println(minWindow("abcdebdde", "bdd")); + public static void main(String[] args) { + System.out.printf(new MinimumWindowSubsequence().minWindow("abcdebdde","bcde")); } } diff --git a/src/geeksforgeeks/NQueens.java b/src/geeksforgeeks/NQueens.java index c9aacf6..3a34980 100644 --- a/src/geeksforgeeks/NQueens.java +++ b/src/geeksforgeeks/NQueens.java @@ -1,5 +1,26 @@ package geeksforgeeks; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * https://leetcode.com/problems/n-queens/ + * + * Input: 4 + * Output: [ + * [".Q..", // Solution 1 + * "...Q", + * "Q...", + * "..Q."], + * + * ["..Q.", // Solution 2 + * "Q...", + * "...Q", + * ".Q.."] + * ] + * Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above. + */ public class NQueens { public List> solveNQueens(int n) { @@ -25,9 +46,9 @@ public void nQueensHelper(int row, int n, char[][] board, List> res return; } for(int i=0;i edges = graph.allEdges; - EdgeComparator edgeComparator = new EdgeComparator(); - Collections.sort(edges, edgeComparator); - DisjointSet disjointSet = new DisjointSet(); - List resultEdges = new ArrayList<>(); - Collection allVertex = graph.getAllVertex(); - for (Object vertex : allVertex) { - disjointSet.makeNode((Vertex) vertex); + public static int minCost(int n, int[][] edges, int[][] newEdges) { + UF uf = new UF(n + 1); // + 1 because nodes are 1-based + for (int[] edge : edges) { + uf.union(edge[0], edge[1]); } - for (Edge edge : edges) { - if (edge.weight < 0) { - if (disjointSet.unionSet(edge)) { - resultEdges.add(edge); - } - } - } + Queue pq = new PriorityQueue<>(newEdges.length, (e1, e2) -> Integer.compare(e1[2], e2[2])); + pq.addAll(Arrays.asList(newEdges)); - for (Edge edge : edges) { - if (edge.weight > 0) { - if (disjointSet.unionSet(edge)) { - resultEdges.add(edge); - } + int totalCost = 0; + // 2 because nodes are 1-based and we have 1 unused component at index 0 + while (!pq.isEmpty() && uf.count != 2) { + int[] edge = pq.poll(); + if (!uf.connected(edge[0], edge[1])) { + uf.union(edge[0], edge[1]); + totalCost += edge[2]; } } - - for (Edge edge : resultEdges) { - System.out.println(edge.vertex1.data + "->" + edge.vertex2.data + "->" + edge.weight); - } + return totalCost; } - } -class EdgeComparator implements Comparator { - - @Override - public int compare(Edge e1, Edge e2) { - if (e1.weight < e2.weight) { - return -1; +class UF { + private int[] parent; // parent[i] = parent of i + private byte[] rank; // rank[i] = rank of subtree rooted at i (never more than 31) + public int count; // number of connected components + + public UF(int n) { + if (n < 0) throw new IllegalArgumentException(); + parent = new int[n]; + rank = new byte[n]; + for (int i = 0; i < n; i++) { + parent[i] = i; } - return 1; - } -} - -class DisjointSet { - - Map allNodes = new HashMap<>(); - - protected void makeNode(Vertex vertex) { - Node node = new Node(vertex.id); - node.parent = node; - allNodes.put(vertex.id, node); + count = n; } - public boolean unionSet(Edge edge) { - Node srcNode = allNodes.get(edge.vertex1.data); - Node destNode = allNodes.get(edge.vertex2.data); - - Node parentSrcNode = findParent(srcNode); - Node parentDestNode = findParent(destNode); - - if (parentSrcNode != parentDestNode) { - parentDestNode.parent = parentSrcNode; - return true; + public int find(int p) { + while (p != parent[p]) { + parent[p] = parent[parent[p]]; + p = parent[p]; } - return false; + return p; } - public Node findParent(Node node) { - Node parent = node.parent; - if (parent == node) { - return node; + public void union(int p, int q) { + int pr = find(p); + int qr = find(q); + if (pr == qr) return; + if (rank[pr] < rank[qr]) { + parent[pr] = qr; + } else { + parent[qr] = pr; + if (rank[pr] == rank[qr]) rank[pr]++; } - return findParent(node.parent); + count--; } -} - -class Node { - long data; - Node parent; - Node child; - public Node(long id) { - this.data = id; + public boolean connected(int p, int q) { + return find(p) == find(q); } } diff --git a/src/geeksforgeeks/NextGreaterElement.java b/src/geeksforgeeks/NextGreaterElement.java index a1f444a..78d4a42 100644 --- a/src/geeksforgeeks/NextGreaterElement.java +++ b/src/geeksforgeeks/NextGreaterElement.java @@ -1,6 +1,6 @@ package geeksforgeeks; -import java.util.Stack; +import java.util.*; /** * https://www.geeksforgeeks.org/next-greater-element/ @@ -9,7 +9,7 @@ */ class NextGreaterElement { - static int arr[] = { 4, 5, 2, 25 }; + static int arr[] = { 1,3,4,2 }; // 9,1,2,3,4,5,6,7 public static void printNGE() { @@ -59,7 +59,7 @@ public int[] nextGreaterElement(int[] findNums, int[] nums) { // Explanation: The first 1's next greater number is 2; // The number 2 can't find next greater number; // The second 1's next greater number needs to search circularly, which is also 2. - public static int[] nextGreaterElementCircular(int[] arr){ + public static int[] nextGreaterElementCircular(int[] nums){ if(nums==null || nums.length==0) return new int[0]; int[] result= new int[nums.length]; int n= nums.length; @@ -67,13 +67,18 @@ public static int[] nextGreaterElementCircular(int[] arr){ Deque deque= new ArrayDeque<>(); // to mimic the circular array we iterate for 2*n because input [1,2,1] will be like [1,2,1,1,2,1] // and we take mod of 'n' to update the correct index - for(int i=0;i<2*nums.length;i++){ - - while(!deque.isEmpty() && nums[deque.getLast()]= 0; --i) { + + while (!deque.isEmpty() && nums[deque.peek()] <= nums[i % nums.length]) { + deque.pop(); } - deque.addLast(i%n); - + // The stack is either empty, when no "greater element" is found to the right of nums[i], + // or contains the next greater element of nums[i] at the top. + result[i % nums.length] = deque.isEmpty() ? -1 : nums[deque.peek()]; + + // Push i into stack, so that nums[i-1] will compare with nums[i] first, before falling back to + // the next greater element of nums[i] + deque.push(i % nums.length); } return result; diff --git a/src/geeksforgeeks/OverlappingIntervals.java b/src/geeksforgeeks/OverlappingIntervals.java new file mode 100644 index 0000000..775690d --- /dev/null +++ b/src/geeksforgeeks/OverlappingIntervals.java @@ -0,0 +1,40 @@ +package geeksforgeeks; + +/** + * Given a collection of intervals, find the minimum number of intervals + * you need to remove to make the rest of the intervals non-overlapping. + * Input: [[1,2],[2,3],[3,4],[1,3]] + Output: 1 + Explanation: [1,3] can be removed and the rest of intervals are non-overlapping. + Input: [[1,2],[1,2],[1,2]] + Output: 2 + Explanation: You need to remove two [1,2] to make the rest of intervals non-overlapping. + */ + +public class OverlappingIntervals{ + + public int eraseOverlapIntervals(int[][] intervals) { + if(intervals.length==0) return 0; + + PriorityQueue queue = new PriorityQueue((a, b) -> Integer.compare(a[0],b[0])); + + for(int[] interval: intervals){ + queue.offer(interval); + } + int result=0; + + int end= queue.poll()[1]; + + while(!queue.isEmpty()){ + if(end>queue.peek()[0]) { + result++; + end=Math.min(end, queue.poll()[1]); + }else{ + end=queue.poll()[1]; + } + } + + return result; + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/PalindromePartion.java b/src/geeksforgeeks/PalindromePartion.java index 3d1f3d9..58ed043 100644 --- a/src/geeksforgeeks/PalindromePartion.java +++ b/src/geeksforgeeks/PalindromePartion.java @@ -3,48 +3,50 @@ import java.util.*; //https://leetcode.com/problems/palindrome-partitioning/ +/* +Given a string s, partition s such that every substring of the partition is a palindrome. + +Return all possible palindrome partitioning of s. + +Input: "aab" +Output: +[ + ["aa","b"], + ["a","a","b"] +] + */ class PalindromePartion { public List> partition(String s) { - List> result= new ArrayList<>(); - if(s==null || s.length()==0) return result; - - backtrackingUtil(s, result, new ArrayList()); - - return result; - + List> res = new ArrayList>(); + List list = new ArrayList(); + dfs(s, 0, list, res); + return res; } - - public void backtrackingUtil(String s, List> result, List tempList){ - if(s==null || s.length()==0){ - result.add(new ArrayList<>(tempList)); - return; - } - - for(int i=1;i<=s.length();i++){ - String temp= s.substring(0,i); - if(isPalin(temp)){ - tempList.add(temp); - backtrackingUtil(s.substring(i,s.length()),result,tempList); - tempList.remove(tempList.size()-1); + + public void dfs(String s, int pos, List list, List> res) { + if (pos == s.length()) { + res.add(new ArrayList(list)); + return; + } + + for (int i = pos; i < s.length(); i++) { + if (isPal(s, pos, i)) { + list.add(s.substring(pos, i + 1)); + dfs(s, i + 1, list, res); + list.remove(list.size() - 1); } } } - - public boolean isPalin(String s){ - int start=0; - int end= s.length()-1; - while(start<=end){ - if(s.charAt(start)!=s.charAt(end)) return false; - start++; - end--; - } + + public boolean isPal(String s, int low, int high) { + while (low < high) if (s.charAt(low++) != s.charAt(high--)) return false; return true; } - - public static void main(String[] args) { - new PalindromePartion().partition("aab"); - } - - + + public static void main(String[] args) { + new PalindromePartion().partition("aab"); + } + + } \ No newline at end of file diff --git a/src/geeksforgeeks/PalindromicSubSequence.java b/src/geeksforgeeks/PalindromicSubSequence.java index 9288b39..5a54ffc 100644 --- a/src/geeksforgeeks/PalindromicSubSequence.java +++ b/src/geeksforgeeks/PalindromicSubSequence.java @@ -1,6 +1,15 @@ package geeksforgeeks; +/** + * Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000. + * Input: "cbbd" + * Output: 2 + * + * + */ class PalindromicSubSequence { + // genral solution if s[l]==s[r] ? 2 + longestPalindromeSubseq(l+1,r-1, s) : + // max(longestPalindromeSubseq(l+1,r, s),longestPalindromeSubseq(l,r-1, s)); public int longestPalindromeSubseq(String s) { if(s==null || s.length()==0) return 0; @@ -9,7 +18,7 @@ public int longestPalindromeSubseq(String s) { for(int i=s.length()-1;i>=0;i--){ for(int j=i;j + * Input: 5 + * Output: + * [ + * [1], + * [1,1], + * [1,2,1], + * [1,3,3,1], + * [1,4,6,4,1] + * ] */ public class PascalsTriangle { @@ -42,31 +52,19 @@ public List> generate(int numRows) { } public List> generate1(int numRows) { - - if (numRows == 0) - return Collections.emptyList(); - - List> result = new ArrayList<>(); - List first = Arrays.asList(1); - result.add(first); - if (numRows == 1) - return result; - List second = Arrays.asList(1, 1); - result.add(second); - if (numRows == 2) - return result; - - for (int i = 2; i < numRows; i++) { - List temp = new ArrayList<>(); - temp.add(1); - for (int k = 0; k < i - 1; k++) { - int j = k + 1; - temp.add(result.get(i - 1).get(k) + result.get(i - 1).get(j)); - } - temp.add(1); - result.add(temp); + List> allrows = new ArrayList>(); + ArrayList row = new ArrayList(); + for (int i = 0; i < numRows; i++) { + // suppose if the row is [1,3,3,1] + // add 1 at start [1,1,3,3,1] + // then add together j and j+1 elements like below + // [1,4,3,3,1] => [1,4,6,3,1]=>[1,4,6,4,1] + row.add(0, 1); + for (int j = 1; j < row.size() - 1; j++) + row.set(j, row.get(j) + row.get(j + 1)); + allrows.add(new ArrayList(row));// every time the copy is only appended } + return allrows; - return result; } } \ No newline at end of file diff --git a/src/geeksforgeeks/PathSumIII.java b/src/geeksforgeeks/PathSumIII.java index 0100122..f189ad4 100644 --- a/src/geeksforgeeks/PathSumIII.java +++ b/src/geeksforgeeks/PathSumIII.java @@ -5,8 +5,8 @@ public class PathSumIII { public int pathSum(TreeNode root, int sum) { if(root==null) return 0; list.add(root.val); - int left=pathSum(root.left,sum); - int right= pathSum(root.right,sum); + pathSum(root.left,sum); + pathSum(root.right,sum); int k=0; for(int i=list.size()-1;i>=0;i--){ // coming in reverse order, inorder to avoid considering @@ -21,4 +21,41 @@ public int pathSum(TreeNode root, int sum) { return count; } + public void preorder(TreeNode node, int currSum) { + if (node == null) + return; + + // current prefix sum + currSum += node.val; + + // here is the sum we're looking for + if (currSum == k) + count++; + + // number of times the curr_sum − k has occured already, + // determines the number of times a path with sum k + // has occured upto the current node + count += h.getOrDefault(currSum - k, 0); + + // add the current sum into hashmap + // to use it during the child nodes processing + h.put(currSum, h.getOrDefault(currSum, 0) + 1); + + // process left subtree + preorder(node.left, currSum); + // process right subtree + preorder(node.right, currSum); + + // remove the current sum from the hashmap + // in order not to use it during + // the parallel subtree processing + h.put(currSum, h.get(currSum) - 1); + } + + public int pathSumAlter(TreeNode root, int sum) { + k = sum; + preorder(root, 0); + return count; + } + } \ No newline at end of file diff --git a/src/geeksforgeeks/PeakElement.java b/src/geeksforgeeks/PeakElement.java index dfc8c67..a1b35e3 100644 --- a/src/geeksforgeeks/PeakElement.java +++ b/src/geeksforgeeks/PeakElement.java @@ -2,54 +2,38 @@ /** * https://leetcode.com/problems/find-peak-element/ + * + * A peak element is an element that is greater than its neighbors. + * + * Given an input array nums, where nums[i] ≠ nums[i+1], find a peak element and return its index. + * + * The array may contain multiple peaks, in that case return the index to any one of the peaks is fine. + * + * You may imagine that nums[-1] = nums[n] = -∞. */ public class PeakElement { - public int findPeakElementOld(int[] nums) { + public int findPeakElement(int[] nums) { + if (nums == null || nums.length == 0) return -1; + int result = -1; - int low = 0; - int high = nums.length - 1; + int start = 0; + int end = nums.length - 1; + while (start <= end) { + int mid = start + (end - start) / 2; - while (low < high) { - int mid = (low + high) / 2; - if (nums[mid] < nums[mid + 1]) { - low = mid + 1; - } else { - high = mid; - } - } - return low; - } - - int findPeakElement(int[] nums) { - int n = nums.length; - if (n == 0) { - return -1; - } - if (n == 1) { - return 0; - } - if (n == 2) { - return nums[0] > nums[1] ? 0 : 1; - } - int low = 0, high = n - 1; - while (low + 2 <= high) { - int mid = low + (high - low) / 2; - if (nums[mid - 1] < nums[mid] && nums[mid] > nums[mid + 1]) { + if ((mid == 0 || nums[mid] > nums[mid - 1]) && (mid == nums.length - 1 || nums[mid] > nums[mid + 1])) return mid; - } - if (nums[mid - 1] > nums[mid]) { - high = mid; - } else { - low = mid; - } + else if (mid > 0 && nums[mid - 1] > nums[mid]) end = mid - 1; + else if (nums[mid + 1] > nums[mid]) start = mid + 1; + } - return nums[low] > nums[high] ? low : high; + return result; } public static void main(String[] args) { PeakElement pe = new PeakElement(); - int[] arr = { 1, 1, 1, 3, 2, 1, 2 }; + int[] arr = {1, 1, 1, 3, 2, 1, 2}; System.out.println(arr[pe.findPeakElement(arr)]); } diff --git a/src/geeksforgeeks/PerfectSquare.java b/src/geeksforgeeks/PerfectSquare.java index 16370ec..2f0e6f2 100644 --- a/src/geeksforgeeks/PerfectSquare.java +++ b/src/geeksforgeeks/PerfectSquare.java @@ -1,7 +1,41 @@ package geeksforgeeks; +import java.util.*; + class PerfectSquare { - public int numSquares(int n) { + // let's solve by dynamic programming approach + // if we take value 13, the number of perfect squares less than + // the input at any point is Sqrt(input)=>(sqrt(13)=3, so max it can have answer below) + // 3,because 4*4 is 16, so perfect squares below 13 are (1*1, 2*2, 3*3) + // 13 can be broken down into + // 1/ 4| \ 9 deducting 1^2 leaves with val 12 + // / | \ deducting 2^2 leaves with val 9 + // 12 9 4 deducting 3^2 leaves with val 4 + // /|\ /|\ /| + // / | \ 8 5 0 3 0 + // 11 7 3 + + public int numSquaresDp(int n) { + int[] ns = new int[n+1]; + Arrays.fill(ns , -1); + ns[0] = 0; + for(int i=1;i0;j--){ + int result = i - j*j; + // the reason to take min is for i=5 j=sqrt(5)=2 + // when subract 1 we are left with 4 + // when subract 4 we are left with 1 so minimum is 1 and add 1 to it + min = Math.min(min, ns[result]+1); + } + ns[i] = min; + System.out.println(Arrays.toString(ns)); + } + return ns[n]; + } + + public int numSquares(int n){ Queue q = new LinkedList<>(); Set visited = new HashSet<>(); q.offer(0); @@ -31,19 +65,7 @@ public int numSquares(int n) { return depth; } - public int numSquaresDp(int n) { - int[] ns = new int[n+1]; - Arrays.fill(ns , Integer.MAX_VALUE); - ns[0] = 0; - for(int i=1;i0;j--){ - int result = i - j*j; - min = Math.min(min, ns[result]+1); - } - ns[i] = min; - } - return ns[n]; + public static void main(String[] args) { + new PerfectSquare().numSquaresDp(13); } } \ No newline at end of file diff --git a/src/geeksforgeeks/PreOrderInOrderTree.java b/src/geeksforgeeks/PreOrderInOrderTree.java deleted file mode 100644 index 82d30d7..0000000 --- a/src/geeksforgeeks/PreOrderInOrderTree.java +++ /dev/null @@ -1,33 +0,0 @@ -package geeksforgeeks; - -class PreOrderInOrderTree { - public TreeNode buildTree(int[] preorder, int[] inorder) { - Map map = new HashMap<>(); - List set = new ArrayList<>(); - - for (int i = 0; i < inorder.length; i++) { - map.put(inorder[i], i); - } - - for (int i = 0; i < preorder.length; i++) { - set.add(preorder[i]); - } - - return buildTreeUtil(map, set, 0, inorder.length - 1); - - } - - public TreeNode buildTreeUtil(Map map, List set, int start, int end) { - if (start > end) - return null; - if (set.isEmpty()) - return null; - int rootval = set.get(0); - set.remove(0); - TreeNode root = new TreeNode(rootval); - int inorderIndex = map.get(rootval); - root.left = buildTreeUtil(map, set, start, inorderIndex - 1); - root.right = buildTreeUtil(map, set, inorderIndex + 1, end); - return root; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/QueensAttackKing.java b/src/geeksforgeeks/QueensAttackKing.java index 70cd145..4123789 100644 --- a/src/geeksforgeeks/QueensAttackKing.java +++ b/src/geeksforgeeks/QueensAttackKing.java @@ -2,12 +2,20 @@ import java.util.*; //https://leetcode.com/problems/queens-that-can-attack-the-king/submissions/ + +/** + * On an 8x8 chessboard, there can be multiple Black Queens and one White King. + * + * Given an array of integer coordinates queens that represents the positions of the Black Queens, + * and a pair of coordinates king that represent the position of the White King, + * return the coordinates of all the queens (in any order) that can attack the King. + */ class QueensAttackKing { public List> queensAttacktheKing(int[][] queens, int[] king) { List> result= new ArrayList<>(); boolean[][] visited= new boolean[8][8]; int[][]dirs= {{1,0},{-1,0},{0,1},{0,-1},{-1,-1},{1,1},{1,-1},{-1,1}}; - + // first marking all queen positions for(int[] qu:queens){ visited[qu[0]][qu[1]]=true; } @@ -24,10 +32,12 @@ public List> queensAttacktheKing(int[][] queens, int[] king) { public List findQueensPosistions(int[] king, int x, int y, boolean[][] visited){ int newX= x+king[0]; int newY= y+king[1]; - // going to walk along x,y only not 8 directions at smae time; + // going to walk along x,y only, not 8 directions at smae time; while(newX<8 && newY<8 && newX>=0 && newY>=0){ - if(visited[newX][newY]) return Arrays.asList(newX,newY); // returns when first queen is met in - // row or column + if(visited[newX][newY]){ + return Arrays.asList(newX,newY); // returns when first queen is met in row or column + } + newX+=x; newY+=y; diff --git a/src/geeksforgeeks/QueensAttacktheKing.java b/src/geeksforgeeks/QueensAttacktheKing.java deleted file mode 100644 index 7517485..0000000 --- a/src/geeksforgeeks/QueensAttacktheKing.java +++ /dev/null @@ -1,50 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -class QueensAttacktheKing { - - public static List> queensAttacktheKing(int[][] queens, int[] king) { - List> result = new ArrayList<>(); - boolean[][] visited = new boolean[8][8]; - int[][] dirs = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 }, { -1, -1 }, { 1, 1 }, { 1, -1 }, { -1, 1 } }; - - for (int[] qu : queens) { - visited[qu[0]][qu[1]] = true; - } - - for (int[] dir : dirs) { - List temp = findQueensPositions(king, dir[0], dir[1], visited); - if (temp != null) { - result.add(temp); - } - } - - return result; - - } - - public static List findQueensPositions(int[] king, int x, int y, boolean[][] visited) { - int newX = x + king[0]; - int newY = y + king[1]; - - while (newX < 8 && newY < 8 && newX >= 0 && newY >= 0) { - if (visited[newX][newY]) { - return Arrays.asList(newX, newY); - } - newX += x; - newY += y; - - } - - return null; - } - - public static void main(String[] args) { - int[][] queens = { { 0, 1 }, { 1, 0 }, { 4, 0 }, { 0, 4 }, { 3, 3 }, { 2, 4 } }; - int[] king = { 0, 0 }; - System.out.println(queensAttacktheKing(queens, king)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/RaceCar.java b/src/geeksforgeeks/RaceCar.java deleted file mode 100644 index 8449497..0000000 --- a/src/geeksforgeeks/RaceCar.java +++ /dev/null @@ -1,50 +0,0 @@ -package geeksforgeeks; - -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Queue; -import java.util.Set; - -class RaceCar { - - public int racecar(int target) { - Set visited = new HashSet<>(); - Queue queue = new LinkedList<>(); - queue.add(new StateNode(1, 0, 0)); - while (!queue.isEmpty()) { - - StateNode cur = queue.poll(); - if (cur.position == target) { - return cur.result; - } - // if A - int nextPosition = cur.position + cur.speed; - int nextSpeed = cur.speed * 2; - if (!visited.contains(nextSpeed + "," + nextPosition) && Math.abs(target - nextPosition) < target) { - visited.add(nextSpeed + "," + nextPosition); - queue.offer(new StateNode(nextSpeed, nextPosition, cur.result + 1)); - } - // if R - nextPosition = cur.position; - nextSpeed = cur.speed > 0 ? -1 : 1; - if (!visited.contains(nextSpeed + "," + nextPosition) && Math.abs(target - nextPosition) < target) { - visited.add(nextSpeed + "," + nextPosition); - queue.offer(new StateNode(nextSpeed, nextPosition, cur.result + 1)); - } - - } - return -1; - } -} - -class StateNode { - int speed; - int position; - int result; - - public StateNode(int speed, int position, int result) { - this.speed = speed; - this.position = position; - this.result = result; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/ReconstructItenary.java b/src/geeksforgeeks/ReconstructItenary.java new file mode 100644 index 0000000..7afb10b --- /dev/null +++ b/src/geeksforgeeks/ReconstructItenary.java @@ -0,0 +1,43 @@ +package geeksforgeeks; +/** + * Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], reconstruct the itinerary in order. + * All of the tickets belong to a man who departs from JFK. + * Thus, the itinerary must begin with JFK. + * + * Input: [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] + Output: ["JFK", "MUC", "LHR", "SFO", "SJC"] + + Input: [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]] + Output: ["JFK","ATL","JFK","SFO","ATL","SFO"] + */ +public class ReconstructItenary { + + class Solution { + public List findItinerary(List> tickets) { + if(tickets==null || tickets.size()==0) return Collections.emptyList(); + + Map > map= new HashMap<>(); + + for(List ticket: tickets){ + map.putIfAbsent(ticket.get(0), new PriorityQueue<>()); + map.get(ticket.get(0)).offer(ticket.get(1)); + } + List res = new ArrayList(); + dfs(map, res, "JFK"); + return res; + } + + public void dfs( Map> map, List res, String s){ + + PriorityQueue queue= map.get(s); + + while(queue!=null && !queue.isEmpty()){ + String temp= queue.poll(); + dfs(map, res, temp); + } + + res.add(0,s); + } + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/ReorderLogs.java b/src/geeksforgeeks/ReorderLogs.java index 5b0c0e3..ebda923 100644 --- a/src/geeksforgeeks/ReorderLogs.java +++ b/src/geeksforgeeks/ReorderLogs.java @@ -2,7 +2,24 @@ import java.util.Arrays; -/*https://leetcode.com/articles/reorder-log-files/*/ +/*https://leetcode.com/articles/reorder-log-files/ + +You have an array of logs. Each log is a space delimited string of words. + +For each log, the first word in each log is an alphanumeric identifier. Then, either: + +Each word after the identifier will consist only of lowercase letters, or; +Each word after the identifier will consist only of digits. +We will call these two varieties of logs letter-logs and digit-logs. It is guaranteed that each log has at least one word after its identifier. + +Reorder the logs so that all of the letter-logs come before any digit-log. +The letter-logs are ordered lexicographically ignoring identifier, with the identifier used in case of ties. +The digit-logs should be put in their original order. + +Input: logs = ["dig1 8 1 5 1","let1 art can","dig2 3 6","let2 own kit dig","let3 art zero"] +Output: ["let1 art can","let3 art zero","let2 own kit dig","dig1 8 1 5 1","dig2 3 6"] +*/ + class ReorderLogs { public static String[] reorderLogFiles(String[] logs) { Arrays.sort(logs, (s1, s2) -> { diff --git a/src/geeksforgeeks/ReorganiseString.java b/src/geeksforgeeks/ReorganiseString.java index 01e69a7..c8288f9 100644 --- a/src/geeksforgeeks/ReorganiseString.java +++ b/src/geeksforgeeks/ReorganiseString.java @@ -1,35 +1,46 @@ package geeksforgeeks; -class ReorganiseString{ +/** + * Given a string S, check if the letters can be rearranged so that two characters that are adjacent to each other are not the same. + * + * If possible, output any possible result. If not possible, return the empty string. + * + * Input: S = "aab" + * Output: "aba" + * + * Input: S = "aaab" + * Output: "" + */ +class ReorganiseString { public String reorganizeString(String s) { - if(s == null || s.length() < 1) return ""; - + if (s == null || s.length() < 1) return ""; + int[] hash = new int[26]; - for(char c : s.toCharArray()) { - hash[c-'a']++; + for (char c : s.toCharArray()) { + hash[c - 'a']++; } - + int max = 0; int letter = 0; - - for(int i=0; i max) { + + for (int i = 0; i < hash.length; i++) { + if (hash[i] > max) { max = hash[i]; letter = i; - } + } } - - if(max > (s.length()+1)/2) return ""; - + + if (max > (s.length() + 1) / 2) return ""; + char[] res = new char[s.length()]; - - int k=0; - while(hash[letter] > 0) { - res[k] = (char)(letter + 'a'); - k += 2; + + int pos = 0; + while (hash[letter] > 0) { + res[pos] = (char) (letter + 'a'); + pos += 2; hash[letter]--; } - + // We construct the resulting string in sequence: at position 0, 2, 4, ... and then 1, 3, 5, ... // In this way, we can make sure there is always a gap between the same characters @@ -39,17 +50,17 @@ public String reorganizeString(String s) { // a b a _ a _ b _ b // fill in "b" at position 6, 8, 1 // a b a c a _ b _ b // fill in "c" at position 3 // a b a c a d b d b // fill in "d" at position 5, 7 - - for(int i=0; i 0) { - if(k >= res.length) k=1; - - res[k] = (char)(i + 'a'); - k += 2; - hash[i] --; + + for (int i = 0; i < hash.length; i++) { + while (hash[i] > 0) { + if (pos >= res.length) pos = 1; + + res[pos] = (char) (i + 'a'); + pos += 2; + hash[i]--; } } - + return new String(res); } diff --git a/src/geeksforgeeks/RestorepAddresses.java b/src/geeksforgeeks/RestorepAddresses.java new file mode 100644 index 0000000..e85178e --- /dev/null +++ b/src/geeksforgeeks/RestorepAddresses.java @@ -0,0 +1,42 @@ +package geeksforgeeks; + +import java.util.*; + +public class RestorepAddresses { + public List restoreIpAddresses(String s) { + if (s == null) + return Collections.emptyList(); + List result = new ArrayList<>(); + + for (int i = 1; i < 4 && i < s.length(); i++) { + String first = s.substring(0, i); + if (isValid(first)) { + for (int j = 1; j < 4 && j + i < s.length(); j++) { + String second = s.substring(i, i + j); + if (isValid(second)) { + for (int k = 1; i + j + k < s.length() && k < 4; k++) { + String third = s.substring(i + j, i + j + k); + String fourth = s.substring(i + j + k); + if (isValid(third) && isValid(fourth)) { + result.add(first + "." + second + "." + third + "." + fourth); + } + } + } + } + } + } + return result; + } + + public boolean isValid(String part) { + if (part == null || part.length() > 3) + return false; + + if (part.charAt(0) == '0' && part.length() > 1) + return false; + + int address = Integer.parseInt(part); + + return address >= 0 && address <= 255; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/ReverseWordsInString.java b/src/geeksforgeeks/ReverseWordsInString.java new file mode 100644 index 0000000..0832f61 --- /dev/null +++ b/src/geeksforgeeks/ReverseWordsInString.java @@ -0,0 +1,38 @@ +package geeksforgeeks; + +public class ReverseWordsInString { + + public char[] reverse(char[] arr, int i, int j) { + while (i < j) { + char tmp = arr[i]; + arr[i++] = arr[j]; + arr[j--] = tmp; + } + return arr; + } + + public String reverseWords(String s) { + // reverse the whole string and convert to char array + char[] str = reverse(s.toCharArray(), 0, s.length()-1); + int start = 0, end = 0; // start and end positions of a current word + //for input "the sky is blue" + // the char arr contians + //[e u l b s i y k s e h t] + + System.out.println(Arrays.toString(str)); + for (int i = 0; i < str.length; i++) { + if (str[i] != ' ') { // if the current char is letter + str[end++] = str[i]; // just move this letter to the next free pos + } else if (i > 0 && str[i-1] != ' ') { // if the first space after word + reverse(str, start, end-1); // reverse the word + str[end++] = ' '; // and put the space after it + start = end; // move start position further for the next word + } + } + reverse(str, start, end-1); // reverse the tail word if it's there + // here's an ugly return just because we need to return Java's String + // also as there could be spaces at the end of original string + // we need to consider redundant space we have put there before + return new String(str, 0, end > 0 && str[end-1] == ' ' ? end-1 : end); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/SameTree.java b/src/geeksforgeeks/SameTree.java new file mode 100644 index 0000000..6db6fd9 --- /dev/null +++ b/src/geeksforgeeks/SameTree.java @@ -0,0 +1,60 @@ +package geeksforgeeks; + +/** + * Given two binary trees, write a function to check if they are the same or not. + * Two binary trees are considered the same if they are structurally identical and the nodes have the same value. +Input: 1 1 + / \ / \ + 2 1 1 2 + + [1,2,1], [1,1,2] + +Output: false + */ +public class SameTree { + public boolean check(TreeNode p, TreeNode q) { + // p and q are null + if (p == null || q == null) return p==q; + if (p.val != q.val) return false; + return true; + } + + public boolean isSameTree(TreeNode p, TreeNode q) { + if (p == null && q == null) return true; + if (!check(p, q)) return false; + + // init deques + ArrayDeque deqP = new ArrayDeque(); + ArrayDeque deqQ = new ArrayDeque(); + deqP.addLast(p); + deqQ.addLast(q); + + while (!deqP.isEmpty()) { + p = deqP.removeFirst(); + q = deqQ.removeFirst(); + + if (!check(p, q)) return false; + if (p != null) { + // in Java nulls are not allowed in Deque + if (!check(p.left, q.left)) return false; + if (p.left != null) { + deqP.addLast(p.left); + deqQ.addLast(q.left); + } + if (!check(p.right, q.right)) return false; + if (p.right != null) { + deqP.addLast(p.right); + deqQ.addLast(q.right); + } + } + } + return true; + } + + public boolean isSameTreeRecur(TreeNode p, TreeNode q){ + if(p==null || q==null) return p==q; + if(p.val==q.val) return true; + + return isSameTreeRecur(p.left, q.left) && isSameTreeRecur(p.right, q.right); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/SubArraySumDivisibleByK.java b/src/geeksforgeeks/SubArraySumDivisibleByK.java new file mode 100644 index 0000000..dbd73b8 --- /dev/null +++ b/src/geeksforgeeks/SubArraySumDivisibleByK.java @@ -0,0 +1,42 @@ +package geeksforgeeks; + +/** + * Given an array A of integers, return the number of (contiguous, non-empty) subarrays that have a sum divisible by K. + * Input: A = [4,5,0,-2,-3,1], K = 5 + Output: 7 +Explanation: There are 7 subarrays with a sum divisible by K = 5: +[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3] + */ +public class SubArraySumDivisibleByK{ + + public int subarraysDivByK(int[] A, int K) { + Map count = new HashMap<>(); + count.put(0, 1); //if the first prefix sum is 0, it need to be counted as a mod of K, right? Rest of prefix sum from 1 to K-1 don't include the first prefix sum + int prefix = 0, res = 0; + for (int a : A) { + //(prefix+a%K+K)%K is just a trick to make the remainder positive. + prefix = (prefix + a % K + K) % K; + res += count.getOrDefault(prefix, 0); + count.put(prefix, count.getOrDefault(prefix, 0) + 1); + } + return res; + } + // A = [4,5,0,-2,-3,1], K = 5 + // step 1 : {0:1} a=4 sum=4 mod=4 count = 0+0 =0 + // step 2 : {0:1,4:1} a=5 sum=9 mod=4 count = 0+1 =1 + // step 3 : {0:1,4:2} a=0 sum=9 mod=4 count = 1+2 =3 + // step 4 : {0:1,4:3} a=-2 sum=7 mod=2 count = 3+0 =3 + // step 6 : {0:1,4:3,2:1} a=-3 sum=4 mod=4 count = 3+3 =6 + // step 7 : {0:1,4:4,2:1} a=1 sum=5 mod=0 count = 6+1 =7 + public int subarraysDivByKOptimised(int[] A, int K) { + int[] map = new int[K]; + map[0]=1; + int prefix = 0, res = 0; + for (int a : A) { + prefix = (prefix + a % K + K) % K; + res +=map[prefix]; + map[prefix]++; + } + return res; + } +} diff --git a/src/geeksforgeeks/SurroundedRegions.java b/src/geeksforgeeks/SurroundedRegions.java index ee37925..2aa3c6a 100644 --- a/src/geeksforgeeks/SurroundedRegions.java +++ b/src/geeksforgeeks/SurroundedRegions.java @@ -1,62 +1,115 @@ package geeksforgeeks; + class Solution { public void solve(char[][] board) { - if(board==null || board.length==0) return; - - Queue queue= new ArrayDeque<>(); - int[][] dirs= { { -1, 0 }, { 1, 0 }, { 0, 1 }, { 0, -1 } }; - for(int i=0;i queue = new ArrayDeque<>(); + int[][] dirs = { { -1, 0 }, { 1, 0 }, { 0, 1 }, { 0, -1 } }; + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (board[i][j] == 'O') { + if (i == board.length - 1 || j == board[0].length - 1 || i == 0 || j == 0) { + board[i][j] = '1'; + queue.offer(new Pair(i, j, 0)); } } } } - - while(!queue.isEmpty()){ - Pair temp= queue.poll(); - - for(int[] dir: dirs){ - int newx=temp.x+dir[0]; - int newy= temp.y+dir[1]; - - if(isValid(newx,newy,board) && board[newx][newy]=='O'){ - board[newx][newy]='1'; - queue.offer(new Pair(newx, newy,0)); + + while (!queue.isEmpty()) { + Pair temp = queue.poll(); + + for (int[] dir : dirs) { + int newx = temp.x + dir[0]; + int newy = temp.y + dir[1]; + + if (isValid(newx, newy, board) && board[newx][newy] == 'O') { + board[newx][newy] = '1'; + queue.offer(new Pair(newx, newy, 0)); } } - + } - - for(int i=0;i=board.length || y<0 || y>=board[0].length) return false; + + public boolean isValid(int x, int y, char[][] board) { + if (x < 0 || x >= board.length || y < 0 || y >= board[0].length) + return false; return true; } + + public void solveDFS(char[][] board) { + if (board.length == 0 || board[0].length == 0) + return; + if (board.length < 2 || board[0].length < 2) + return; + int m = board.length, n = board[0].length; + // Any 'O' connected to a boundary can't be turned to 'X', so ... + // Start from first and last column, turn 'O' to '*'. + for (int i = 0; i < m; i++) { + if (board[i][0] == 'O') + boundaryDFS(board, i, 0); + if (board[i][n - 1] == 'O') + boundaryDFS(board, i, n - 1); + } + // Start from first and last row, turn '0' to '*' + for (int j = 0; j < n; j++) { + if (board[0][j] == 'O') + boundaryDFS(board, 0, j); + if (board[m - 1][j] == 'O') + boundaryDFS(board, m - 1, j); + } + // post-prcessing, turn 'O' to 'X', '*' back to 'O', keep 'X' intact. + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (board[i][j] == 'O') + board[i][j] = 'X'; + else if (board[i][j] == '*') + board[i][j] = 'O'; + } + } + } + + // Use DFS algo to turn internal however boundary-connected 'O' to '*'; + //Use DFS algo to turn internal however boundary-connected 'O' to '*'; +private void boundaryDFS(char[][] board, int i, int j) { + if (i < 0 || i > board.length - 1 || j <0 || j > board[0].length - 1 ) + return; + if (board[i][j] == 'O'){ + board[i][j] = '*'; + + boundaryDFS(board, i-1, j); + + boundaryDFS(board, i+1, j); + + boundaryDFS(board, i, j-1); + + boundaryDFS(board, i, j+1); + } +} } class Pair { int x; int y; int level; - - public Pair(int x, int y, int level){ - this.x=x; - this.y=y; - this.level=level; + + public Pair(int x, int y, int level) { + this.x = x; + this.y = y; + this.level = level; } } \ No newline at end of file diff --git a/src/geeksforgeeks/UnSortedContiguousSubArray.java b/src/geeksforgeeks/UnSortedContiguousSubArray.java deleted file mode 100644 index 91b07de..0000000 --- a/src/geeksforgeeks/UnSortedContiguousSubArray.java +++ /dev/null @@ -1,40 +0,0 @@ -package geeksforgeeks; - -class UnSortedContiguousSubArray { - public int findUnsortedSubarray(int[] nums) { - int i = 0; - int j = nums.length - 1; - - while (i < nums.length - 1) { - if (nums[i] > nums[i + 1]) { - break; - } - i++; - } - if (i >= j) - return 0; - - while (j > 0) { - if (nums[j] < nums[j - 1]) { - break; - } - j--; - } - int min = Integer.MAX_VALUE; - int max = Integer.MIN_VALUE; - - for (int k = i; k <= j; k++) { - min = Math.min(min, nums[k]); - max = Math.max(max, nums[k]); - } - - while (i >= 0 && min < nums[i]) - i--; - while (j < nums.length && max > nums[j]) - j++; - - return j - i - 1; - - } - -} \ No newline at end of file diff --git a/src/geeksforgeeks/UniquePath.java b/src/geeksforgeeks/UniquePath.java index 5a47183..88c2386 100644 --- a/src/geeksforgeeks/UniquePath.java +++ b/src/geeksforgeeks/UniquePath.java @@ -32,6 +32,21 @@ private static int uniquePathI(int row, int col) { return dp[row - 1][col - 1]; } + /** + * Now consider if some obstacles are added to the grids. How many unique paths would there be? + * Input: + * [ + * [0,0,0], + * [0,1,0], + * [0,0,0] + * ] + * Output: 2 + * Explanation: + * There is one obstacle in the middle of the 3x3 grid above. + * There are two ways to reach the bottom-right corner: + * 1. Right -> Right -> Down -> Down + * 2. Down -> Down -> Right -> Right + */ private static int uniquePathII(int[][] mat) { if (obstacleGrid[0][0] == 1) diff --git a/src/geeksforgeeks/UnsortedSubarrayProblems.java b/src/geeksforgeeks/UnsortedSubarrayProblems.java deleted file mode 100644 index cfc36b1..0000000 --- a/src/geeksforgeeks/UnsortedSubarrayProblems.java +++ /dev/null @@ -1,51 +0,0 @@ -package geeksforgeeks; - -//https://leetcode.com/problems/shortest-unsorted-continuous-subarray/submissions/ -public class UnsortedSubarrayProblems { - - public static int findUnsortedSubarray(int[] nums) { - - int i = 0; - int j = nums.length - 1; - - while (i < nums.length - 1) { - if (nums[i] > nums[i + 1]) { - break; - } - i++; - } - if (i >= j) { - return 0; - } - - while (j > 0) { - if (nums[j] < nums[j - 1]) { - break; - } - j--; - } - int min = Integer.MAX_VALUE; - int max = Integer.MIN_VALUE; - for (int k = i; k <= j; k++) { - min = Math.min(min, nums[k]); - max = Math.max(max, nums[k]); - } - - while (i >= 0 && min < nums[i]) - i--; - while (j < nums.length && max > nums[j]) - j++; - - return j - i - 1; - - } - - public static void main(String[] args) { - //(1, 3, 2, 4, 5))); - //4, 15, 4, 4, 15, 18, 20 - - // 2,6,4,8,10,9,15 - int[] arr = { 2, 6, 1, 8, 10, 9, 15 }; - System.out.println(findUnsortedSubarray(arr)); - } -} diff --git a/src/geeksforgeeks/UrlEncode.java b/src/geeksforgeeks/UrlEncode.java index f950a13..1c54391 100644 --- a/src/geeksforgeeks/UrlEncode.java +++ b/src/geeksforgeeks/UrlEncode.java @@ -1,33 +1,43 @@ package geeksforgeeks; -class UrlEncode { - char[] replaceSpaces(char[] str, int truelength) { - int spaceCount = 0, index, i = 0; - for (i = 0; i < truelength; i++) { - if (str[i] == ' ') { - spaceCount++; - } - } - - index = truelength + spaceCount * 2; - if (truelength < str.length) - str[truelength] = ' '; - for (i = truelength - 1; i >= 0; i--) { - if (str[i] == ' ') { - str[index - 1] = '0'; - str[index - 2] = '2'; - str[index - 3] = '%'; - index = index - 3; +/** + * Write a method to replace all the spaces in a string with ‘%20’. + * You may assume that the string has sufficient space at the end to hold the additional characters, + * and that you are given the “true” length of the string. + */ +public class UrlEncode { + public void replaceSpaces(char[] str, int trueLength) { + int i = str.length - 1; + int extra = str.length - trueLength; + int j = i - extra; + while (i != j) { + if (!Character.isSpaceChar(str[j])) { + str[i--] = str[j--]; } else { - str[index - 1] = str[i]; - index--; + str[i--] = '0'; + str[i--] = '2'; + str[i--] = '%'; + j--; } } - - return str; } public static void main(String[] args) { - System.out.println(new UrlEncode().replaceSpaces("Mr John Smith ".toCharArray(), 13)); + test(new char[17], "Mr John Smith"); + test(new char[12], "Mr John "); + test(new char[5], "Mr "); + test(new char[5], " Mr"); + test(new char[8], " Mr "); + test(new char[3], " "); + test(new char[20], "Mr John Smith"); + test(new char[0], ""); + } + + private static void test(char[] str, String s) { + IntStream.range(0, s.length()).forEach(i -> str[i] = s.charAt(i)); + System.out.print(new String(str) +" - "); + UrlEncode ob = new UrlEncode(); + ob.replaceSpaces(str, s.length()); + System.out.println(new String(str)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/ValidIpAddresses.java b/src/geeksforgeeks/ValidIpAddresses.java deleted file mode 100644 index ff8f00d..0000000 --- a/src/geeksforgeeks/ValidIpAddresses.java +++ /dev/null @@ -1,39 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -public class ValidIpAddresses { - public List restoreIpAddresses(String s) { - if(s==null) return Collections.emptyList(); - List result= new ArrayList<>(); - - for(int i=1; i<4 && i3) return false; - - if(part.charAt(0)=='0' && part.length()>1) return false; - - int address= Integer.parseInt(part); - - return address>=0 && address<=255; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/ValidSuduko.java b/src/geeksforgeeks/ValidSuduko.java index 095e9c1..d287cc3 100644 --- a/src/geeksforgeeks/ValidSuduko.java +++ b/src/geeksforgeeks/ValidSuduko.java @@ -18,4 +18,14 @@ public boolean isValidSudoku(char[][] board) { return true; } + public static void main(String[] args) { + char[][] board = { { '5', '3', '.', '.', '7', '.', '.', '.', '.' }, + { '6', '.', '.', '1', '9', '5', '.', '.', '.' }, { '.', '9', '8', '.', '.', '.', '.', '6', '.' }, + { '8', '.', '.', '.', '6', '.', '.', '.', '3' }, { '4', '.', '.', '8', '.', '3', '.', '.', '1' }, + { '7', '.', '.', '.', '2', '.', '.', '.', '6' }, { '.', '6', '.', '.', '.', '.', '2', '8', '.' }, + { '.', '.', '.', '4', '1', '9', '.', '.', '5' }, { '.', '.', '.', '.', '8', '.', '.', '7', '9' } }; + + ValidSudoku vs = new ValidSudoku(); + System.out.println(vs.isValidSudoku(board)); + } } \ No newline at end of file diff --git a/src/geeksforgeeks/ValidateIpAddresses.java b/src/geeksforgeeks/ValidateIpAddresses.java new file mode 100644 index 0000000..4a17752 --- /dev/null +++ b/src/geeksforgeeks/ValidateIpAddresses.java @@ -0,0 +1,41 @@ +package geeksforgeeks; + +public class ValidateIpAddresses { + // the condition for IPv4 is + // there should be 4 components separated by 3 dots + // each component should have value between 0-9 (base 10) + // + public String validIPAddress(String IP) { + if(IP==null || IP.length()==0) return "Neither"; + + if(IP.chars().filter(e->e=='.').count()==3){ + + for(String s: IP.split("\\.",-1)){ + if(s.length()==0 || s.length()>4) return "Neither"; + if(s.charAt(0)=='0' && s.length()!=1) return "Neither"; + for(char c:s.toCharArray()) if(!Character.isDigit(c)) return "Neither"; + if(Integer.parseInt(s)>255) return "Neither"; + } + + return "IPv4"; + + } + // the condition for IPv6 is + // it should have 8 components, separated by 7 ':'s + // each component should have hex-value i.e 0-9, a-f or A-F + else if(IP.chars().filter(e->e==':').count()==7){ + for(String s: IP.split(":",-1)){ + if(s.length()==0 || s.length()>4) return "Neither"; + for(char c: s.toCharArray()){ + if(!((c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F'))){ + return "Neither"; + } + } + } + + return "IPv6"; + } + + return "Neither"; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/WordDictionary.java b/src/geeksforgeeks/WordDictionary.java new file mode 100644 index 0000000..1571536 --- /dev/null +++ b/src/geeksforgeeks/WordDictionary.java @@ -0,0 +1,66 @@ +package geeksforgeeks; + +/** + * Design a data structure that supports the following two operations: + * void addWord(word) + * bool search(word) + * search(word) can search a literal word or + * a regular expression string containing only letters a-z or .. A . + * means it can represent any one letter. + * addWord("bad") + addWord("dad") + addWord("mad") + search("pad") -> false + search("bad") -> true + search(".ad") -> true + search("b..") -> true + */ +public class WordDictionary { + private TrieNode root; + + /** Initialize your data structure here. */ + private class TrieNode { + public Map children = new HashMap<>(); + public boolean isWord; + } + + public WordDictionary() { + root = new TrieNode(); + } + + /** Adds a word into the data structure. */ + public void addWord(String word) { + + TrieNode temp = root; + + for (char c : word.toCharArray()) { + if (temp.children.get(c) == null) + temp.children.put(c, new TrieNode()); + + temp = temp.children.get(c); + } + + temp.isWord = true; + } + + /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ + public boolean search(String word) { + return match(word.toCharArray(), 0, root); + } + + private boolean match(char[] chs, int k, TrieNode node) { + + if (k == chs.length) + return node.isWord; + + if (chs[k] == '.') { + for (Character curr: node.children.keySet()) { + if (node.children.get(curr) != null && match(chs, k+1, node.children.get(curr))) + return true; + } + } else + return node.children.get(chs[k]) != null && match(chs, k + 1, node.children.get(chs[k])); + + return false; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/temp.xml b/src/geeksforgeeks/temp.xml new file mode 100644 index 0000000..e69de29 From 3aac1fb8135b3151fbea3bee799ee1bc0722aaa0 Mon Sep 17 00:00:00 2001 From: vignesh Date: Tue, 15 Sep 2020 16:09:32 +0530 Subject: [PATCH 36/51] adding new problems under one repository --- .../Combinations.java | 67 +++++ .../Permutations.java | 63 +++++ src/CombinationsAndPermutations/SubSets.java | 67 +++++ src/common/sorting/ImplementABinaryHeap.java | 248 ++++++++++++++++++ src/common/sorting/InsertionSort.java | 30 +++ src/common/sorting/KthLargestElement.java | 62 +++++ src/common/sorting/MaxHeap.java | 51 ++++ src/common/sorting/MergeSort.java | 47 ++++ src/common/sorting/PractiseMergeSort.java | 48 ++++ src/common/sorting/QuickSelect.java | 50 ++++ src/common/sorting/QuickSort.java | 57 ++++ .../AssemblyLineScheduling.java | 55 ++++ .../BooleanParenthesization.java | 63 +++++ src/dynamicProgramming/BoxStacking.java | 122 +++++++++ .../CatalanNumberBinarySearchTree.java | 28 ++ src/dynamicProgramming/EggDropping.java | 59 +++++ .../MaxSumForNonAdjacentElements.java | 27 ++ src/dynamicProgramming/MaximumSquareDP.java | 23 ++ src/dynamicProgramming/MinCostTickets.java | 42 +++ src/dynamicProgramming/MinimumCoinChange.java | 28 ++ .../MinimumNumberOfJumpsToReachEnd.java | 64 +++++ .../NumberWithSameConsequtiveDifference.java | 56 ++++ src/dynamicProgramming/OptimalStratergy.java | 66 +++++ src/dynamicProgramming/OptimalTreeSearch.java | 47 ++++ .../StockBuySellKTransactions.java | 103 ++++++++ .../StockBuySellWithCoolDown.java | 53 ++++ src/dynamicProgramming/Sudoku.java | 162 ++++++++++++ src/dynamicProgramming/UniqueCoinChange.java | 25 ++ src/dynamicProgramming/WordBreak.java | 109 ++++++++ src/dynamicProgramming/WordBreakII.java | 34 +++ .../fibonacci/DecodeWays.java | 74 ++++++ .../fibonacci/DiceThrow.java | 40 +++ .../FibonacciStaircaseWaysToCoverDist.java | 74 ++++++ .../lcs/BitonicSequence.java | 52 ++++ src/dynamicProgramming/lcs/EditDistance.java | 113 ++++++++ .../lcs/LongestCommonSubsequence.java | 86 ++++++ .../lcs/LongestCommonSubstring.java | 37 +++ .../lcs/LongestIncreasingSubsequence.java | 112 ++++++++ .../lcs/MaximumContiguousSubarraySum.java | 28 ++ .../lcs/MaximumProductSubarray.java | 38 +++ .../lcs/MaximumSumIncreasingSubsequence.java | 32 +++ .../lcs/TwoStringInterleavingToFormThird.java | 45 ++++ .../lcs/WildCardMatching.java | 85 ++++++ .../matrix/MatrixMultiplicationCost.java | 43 +++ .../matrix/MaximumSizeSubMatrix.java | 57 ++++ .../matrix/MinCostPath.java | 41 +++ .../oiknapsack/EqualSubsetSumPartition.java | 76 ++++++ .../oiknapsack/MinPartition.java | 46 ++++ .../oiknapsack/MinimumSubsetSum.java | 17 ++ .../NumberOfUniqueWaysToMakeChange.java | 34 +++ .../oiknapsack/O1KnapsackSpaceOptimized.java | 107 ++++++++ .../oiknapsack/SubsetSumProblem.java | 99 +++++++ .../LongestPalindromicSubsequence.java | 87 ++++++ .../LongestPalindromicSubstring.java | 40 +++ .../CoinChangingMinimumCoin.java | 65 +++++ .../unboundedknapsack/CuttingRod.java | 31 +++ src/geeksforgeeks/FenwickTree.java | 112 ++++++++ src/geeksforgeeks/InsertIntervals.java | 33 +++ src/geeksforgeeks/LargestTimeFromDigits.java | 39 +++ src/geeksforgeeks/RollingHashRabinKarp.java | 134 ++++++++++ .../Combinations.java | 67 +++++ .../Permutations.java | 63 +++++ .../CombinationsAndPermutations/SubSets.java | 67 +++++ src/graph/adjacencyList/AdjacencyList.java | 47 ++++ .../adjacencyMatrix/AdjacencyMatrix.java | 42 +++ src/graph/bellmanFord/BellmanFord.java | 56 ++++ src/graph/bellmanFord/Edge.java | 15 ++ src/graph/bellmanFord/Graph.java | 35 +++ src/graph/bellmanFord/NegativeException.java | 10 + src/graph/bellmanFord/Vertex.java | 20 ++ .../BreadthFirstSearch.java | 53 ++++ src/graph/breadthFirstSearch/Graph.java | 18 ++ src/graph/cycle/CycleInDirectedGraph.java | 67 +++++ src/graph/cycle/CycleUndirectedGraph.java | 90 +++++++ src/graph/cycle/Graph.java | 240 +++++++++++++++++ .../depthFirstSearch/DepthFirstSearch.java | 55 ++++ src/graph/depthFirstSearch/Graph.java | 14 + src/graph/dijkstraAlgorithm/BinaryHeap.java | 125 +++++++++ .../dijkstraAlgorithm/DijkstraAlgorithm.java | 64 +++++ src/graph/dijkstraAlgorithm/Graph.java | 72 +++++ .../DisjointSetArrayImplementation.java | 42 +++ src/graph/disjoints/DisjointSetWithNode.java | 61 +++++ src/graph/disjoints/PredatorDisjointSet.java | 53 ++++ src/graph/floydwarshall/FloydWarshall.java | 29 ++ src/graph/interview/DisjointSet.java | 178 +++++++++++++ src/graph/kruskalAlgorithm/DisjointSet.java | 81 ++++++ src/graph/kruskalAlgorithm/Graph.java | 240 +++++++++++++++++ src/graph/kruskalAlgorithm/KruskalMST.java | 53 ++++ src/graph/leetcode/AllPathsInGraph.java | 47 ++++ src/graph/leetcode/CheapestFlightKStops.java | 72 +++++ src/graph/leetcode/ConnectCities.java | 64 +++++ src/graph/leetcode/ConnectMissingCities.java | 54 ++++ .../leetcode/ConnectedComponentsInGraph.java | 32 +++ src/graph/leetcode/CourseSchedule.java | 115 ++++++++ src/graph/leetcode/FindJudge.java | 30 +++ src/graph/leetcode/FriendCircles.java | 57 ++++ src/graph/leetcode/GraphBiPartite.java | 53 ++++ src/graph/leetcode/MinCostRepairEdges.java | 78 ++++++ src/graph/leetcode/NetworkDelayTime.java | 70 +++++ .../leetcode/NewRoadsMinimumSpanningTree.java | 87 ++++++ src/graph/leetcode/RedundantConnection.java | 59 +++++ src/graph/leetcode/SentenceSimilarityII.java | 95 +++++++ src/graph/leetcode/SnapShotUtil.java | 52 ++++ src/graph/primsAlgorithm/BinaryMinHeap.java | 145 ++++++++++ src/graph/primsAlgorithm/Graph.java | 243 +++++++++++++++++ src/graph/primsAlgorithm/PrimMST.java | 71 +++++ src/graph/primsAlgorithm/PrimsMSTArray.java | 54 ++++ src/graph/shortestPath/Graph.java | 53 ++++ src/graph/shortestPath/ShortestPath.java | 60 +++++ src/graph/topologicalsort/Graph.java | 245 +++++++++++++++++ .../topologicalsort/TopologicalSort.java | 51 ++++ .../topologicalsort/TopologicalSortList.java | 65 +++++ .../AutocompleteSystem.java | 33 +++ src/microsoftassesment/CropWords.java | 55 ++++ src/microsoftassesment/DLLNode.java | 180 +++++++++++++ .../LexicographicallySmallest.java | 52 ++++ ...gestSubStringWithout3ContiguousLetter.java | 99 +++++++ .../MinDeletionToMakeUniqueCount.java | 83 ++++++ .../MinStepsToMakePileSameHeight.java | 47 ++++ .../MinSwapsToGroupRedBalls.java | 36 +++ .../NumsWithEqualDigitSum.java | 87 ++++++ .../RemoveCharsMoreThanKOccurrence.java | 55 ++++ src/microsoftassesment/SnakeGame.java | 85 ++++++ .../StringWithout3ConsequitiveLetter.java | 34 +++ src/multithreading/barberProblem/Barber.java | 28 ++ .../barberProblem/Customer.java | 55 ++++ src/multithreading/barberProblem/Main.java | 37 +++ .../barberProblem/WaitingRoom.java | 21 ++ .../com/safecabs/Constants.java | 6 + src/multithreading/com/safecabs/Gender.java | 7 + .../com/safecabs/app/AssignCab.java | 30 +++ .../com/safecabs/app/CabProvider.java | 42 +++ .../com/safecabs/app/CabRequest.java | 30 +++ .../com/safecabs/app/CustomCyclicBarrier.java | 91 +++++++ src/multithreading/com/safecabs/cab/Cab.java | 49 ++++ .../com/safecabs/client/ClientTest.java | 38 +++ .../UnRegisteredPassengerException.java | 8 + .../com/safecabs/passenger/Passenger.java | 23 ++ .../passenger/RegisteredPassenger.java | 24 ++ .../educative/BarberShopProblem.java | 113 ++++++++ src/multithreading/educative/Barrier.java | 37 +++ .../educative/BlockingQueue.java | 121 +++++++++ .../educative/CountingSemaphore.java | 29 ++ .../educative/DeferredCallbackExecutor.java | 78 ++++++ .../educative/DemonstrationThreadLocal.java | 91 +++++++ .../educative/DiningPhilosophers.java | 44 ++++ .../educative/DiningPhilosophers2.java | 55 ++++ .../educative/MultiThreadedMergeSort.java | 105 ++++++++ .../educative/ReadWriteLock.java | 70 +++++ .../educative/TokenBucketFilter.java | 68 +++++ .../educative/UberSeatingProblem.java | 169 ++++++++++++ .../educative/UnisexBathroom.java | 70 +++++ .../educative/UnisexBathroom2.java | 139 ++++++++++ .../educative/companies/netflix/Callback.java | 6 + .../educative/companies/netflix/Executor.java | 17 ++ .../educative/companies/netflix/Run.java | 23 ++ .../netflix/SynchronousExecutor.java | 33 +++ .../educative/examples/CallableExample.java | 117 +++++++++ .../educative/examples/DaemonThreadSpawn.java | 21 ++ .../educative/examples/FutureTaskExample.java | 89 +++++++ .../educative/examples/StockOrder.java | 57 ++++ .../educative/examples/ThreadExample.java | 41 +++ .../examples/ThreadExecutorExample.java | 29 ++ .../examples/ThreadInterruptedException.java | 29 ++ .../examples/ThreadSleepExample.java | 24 ++ .../educative/examples/ThreadSpawn.java | 20 ++ .../educative/examples/TimerVsPool.java | 64 +++++ .../educative/superman/Superman.java | 28 ++ .../superman/SupermanNaiveButCorrect.java | 20 ++ .../superman/SupermanSlightlyBetter.java | 36 +++ .../educative/superman/SupermanWithFlaws.java | 30 +++ src/multithreading/executor/User.java | 32 +++ src/multithreading/practice/Addition.java | 52 ++++ .../practice/CountdownLatch.java | 38 +++ src/multithreading/practice/FizzBuzz.java | 62 +++++ src/multithreading/practice/Foo.java | 39 +++ src/multithreading/practice/FooBar.java | 32 +++ src/multithreading/practice/OddEven.java | 78 ++++++ .../practice/OddEvenSemaphore.java | 94 +++++++ .../practice/ProducerConsumer.java | 116 ++++++++ src/multithreading/practice/ZeroEvenOdd.java | 48 ++++ .../thread/BasicMultiThreading.java | 28 ++ src/multithreading/thread/DeadLock.java | 44 ++++ .../thread/PrintEvenOddTester.java | 68 +++++ .../thread/PrintOddEvenByTwoThreads.java | 60 +++++ .../thread/RaceConditionExample.java | 54 ++++ src/multithreading/thread/Tesst.java | 38 +++ src/multithreading/thread/TestForLocking.java | 51 ++++ .../thread/ThreadJoinExample.java | 57 ++++ src/multithreading/thread/ThreadRunnable.java | 32 +++ .../common/sorting/ImplementABinaryHeap.java | 248 ++++++++++++++++++ src/strings/common/sorting/InsertionSort.java | 30 +++ .../common/sorting/KthLargestElement.java | 62 +++++ src/strings/common/sorting/MaxHeap.java | 51 ++++ src/strings/common/sorting/MergeSort.java | 47 ++++ .../common/sorting/PractiseMergeSort.java | 48 ++++ src/strings/common/sorting/QuickSelect.java | 50 ++++ src/strings/common/sorting/QuickSort.java | 57 ++++ .../All_Possible_Combinatons.java | 28 ++ .../DynamicIntegerGenerator.java | 29 ++ .../dynamicProblems/FirstNonRepeating.java | 34 +++ .../dynamicProblems/PossibleCombinations.java | 29 ++ .../dynamicProblems/ReverseSentence.java | 17 ++ src/strings/dynamicProblems/Subsequence.java | 36 +++ src/strings/stringProblems/Combination.java | 54 ++++ .../stringProblems/DistinctSubstring.java | 33 +++ .../FindLongestStringInArray.java | 26 ++ .../stringProblems/MostCommonWord.java | 77 ++++++ .../PermutationAndCombination.java | 91 +++++++ .../RearrangeCharactersInString.java | 58 ++++ src/strings/stringmatching/KMP.java | 61 +++++ .../stringmatching/MaxProductString.java | 47 ++++ src/strings/stringmatching/RabinKarp.java | 84 ++++++ 213 files changed, 13270 insertions(+) create mode 100644 src/CombinationsAndPermutations/Combinations.java create mode 100644 src/CombinationsAndPermutations/Permutations.java create mode 100644 src/CombinationsAndPermutations/SubSets.java create mode 100644 src/common/sorting/ImplementABinaryHeap.java create mode 100644 src/common/sorting/InsertionSort.java create mode 100644 src/common/sorting/KthLargestElement.java create mode 100644 src/common/sorting/MaxHeap.java create mode 100644 src/common/sorting/MergeSort.java create mode 100644 src/common/sorting/PractiseMergeSort.java create mode 100644 src/common/sorting/QuickSelect.java create mode 100644 src/common/sorting/QuickSort.java create mode 100644 src/dynamicProgramming/AssemblyLineScheduling.java create mode 100644 src/dynamicProgramming/BooleanParenthesization.java create mode 100644 src/dynamicProgramming/BoxStacking.java create mode 100644 src/dynamicProgramming/CatalanNumberBinarySearchTree.java create mode 100644 src/dynamicProgramming/EggDropping.java create mode 100644 src/dynamicProgramming/MaxSumForNonAdjacentElements.java create mode 100644 src/dynamicProgramming/MaximumSquareDP.java create mode 100644 src/dynamicProgramming/MinCostTickets.java create mode 100644 src/dynamicProgramming/MinimumCoinChange.java create mode 100644 src/dynamicProgramming/MinimumNumberOfJumpsToReachEnd.java create mode 100644 src/dynamicProgramming/NumberWithSameConsequtiveDifference.java create mode 100644 src/dynamicProgramming/OptimalStratergy.java create mode 100644 src/dynamicProgramming/OptimalTreeSearch.java create mode 100644 src/dynamicProgramming/StockBuySellKTransactions.java create mode 100644 src/dynamicProgramming/StockBuySellWithCoolDown.java create mode 100644 src/dynamicProgramming/Sudoku.java create mode 100644 src/dynamicProgramming/UniqueCoinChange.java create mode 100644 src/dynamicProgramming/WordBreak.java create mode 100644 src/dynamicProgramming/WordBreakII.java create mode 100644 src/dynamicProgramming/fibonacci/DecodeWays.java create mode 100644 src/dynamicProgramming/fibonacci/DiceThrow.java create mode 100644 src/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java create mode 100644 src/dynamicProgramming/lcs/BitonicSequence.java create mode 100644 src/dynamicProgramming/lcs/EditDistance.java create mode 100644 src/dynamicProgramming/lcs/LongestCommonSubsequence.java create mode 100644 src/dynamicProgramming/lcs/LongestCommonSubstring.java create mode 100644 src/dynamicProgramming/lcs/LongestIncreasingSubsequence.java create mode 100644 src/dynamicProgramming/lcs/MaximumContiguousSubarraySum.java create mode 100644 src/dynamicProgramming/lcs/MaximumProductSubarray.java create mode 100644 src/dynamicProgramming/lcs/MaximumSumIncreasingSubsequence.java create mode 100644 src/dynamicProgramming/lcs/TwoStringInterleavingToFormThird.java create mode 100644 src/dynamicProgramming/lcs/WildCardMatching.java create mode 100644 src/dynamicProgramming/matrix/MatrixMultiplicationCost.java create mode 100644 src/dynamicProgramming/matrix/MaximumSizeSubMatrix.java create mode 100644 src/dynamicProgramming/matrix/MinCostPath.java create mode 100644 src/dynamicProgramming/oiknapsack/EqualSubsetSumPartition.java create mode 100644 src/dynamicProgramming/oiknapsack/MinPartition.java create mode 100644 src/dynamicProgramming/oiknapsack/MinimumSubsetSum.java create mode 100644 src/dynamicProgramming/oiknapsack/NumberOfUniqueWaysToMakeChange.java create mode 100644 src/dynamicProgramming/oiknapsack/O1KnapsackSpaceOptimized.java create mode 100644 src/dynamicProgramming/oiknapsack/SubsetSumProblem.java create mode 100644 src/dynamicProgramming/palindrome/LongestPalindromicSubsequence.java create mode 100644 src/dynamicProgramming/palindrome/LongestPalindromicSubstring.java create mode 100644 src/dynamicProgramming/unboundedknapsack/CoinChangingMinimumCoin.java create mode 100644 src/dynamicProgramming/unboundedknapsack/CuttingRod.java create mode 100644 src/geeksforgeeks/FenwickTree.java create mode 100644 src/geeksforgeeks/InsertIntervals.java create mode 100644 src/geeksforgeeks/LargestTimeFromDigits.java create mode 100644 src/geeksforgeeks/RollingHashRabinKarp.java create mode 100644 src/graph/CombinationsAndPermutations/Combinations.java create mode 100644 src/graph/CombinationsAndPermutations/Permutations.java create mode 100644 src/graph/CombinationsAndPermutations/SubSets.java create mode 100644 src/graph/adjacencyList/AdjacencyList.java create mode 100644 src/graph/adjacencyMatrix/AdjacencyMatrix.java create mode 100644 src/graph/bellmanFord/BellmanFord.java create mode 100644 src/graph/bellmanFord/Edge.java create mode 100644 src/graph/bellmanFord/Graph.java create mode 100644 src/graph/bellmanFord/NegativeException.java create mode 100644 src/graph/bellmanFord/Vertex.java create mode 100644 src/graph/breadthFirstSearch/BreadthFirstSearch.java create mode 100644 src/graph/breadthFirstSearch/Graph.java create mode 100644 src/graph/cycle/CycleInDirectedGraph.java create mode 100644 src/graph/cycle/CycleUndirectedGraph.java create mode 100644 src/graph/cycle/Graph.java create mode 100644 src/graph/depthFirstSearch/DepthFirstSearch.java create mode 100644 src/graph/depthFirstSearch/Graph.java create mode 100644 src/graph/dijkstraAlgorithm/BinaryHeap.java create mode 100644 src/graph/dijkstraAlgorithm/DijkstraAlgorithm.java create mode 100644 src/graph/dijkstraAlgorithm/Graph.java create mode 100644 src/graph/disjoints/DisjointSetArrayImplementation.java create mode 100644 src/graph/disjoints/DisjointSetWithNode.java create mode 100644 src/graph/disjoints/PredatorDisjointSet.java create mode 100644 src/graph/floydwarshall/FloydWarshall.java create mode 100644 src/graph/interview/DisjointSet.java create mode 100644 src/graph/kruskalAlgorithm/DisjointSet.java create mode 100644 src/graph/kruskalAlgorithm/Graph.java create mode 100644 src/graph/kruskalAlgorithm/KruskalMST.java create mode 100644 src/graph/leetcode/AllPathsInGraph.java create mode 100644 src/graph/leetcode/CheapestFlightKStops.java create mode 100644 src/graph/leetcode/ConnectCities.java create mode 100644 src/graph/leetcode/ConnectMissingCities.java create mode 100644 src/graph/leetcode/ConnectedComponentsInGraph.java create mode 100644 src/graph/leetcode/CourseSchedule.java create mode 100644 src/graph/leetcode/FindJudge.java create mode 100644 src/graph/leetcode/FriendCircles.java create mode 100644 src/graph/leetcode/GraphBiPartite.java create mode 100644 src/graph/leetcode/MinCostRepairEdges.java create mode 100644 src/graph/leetcode/NetworkDelayTime.java create mode 100644 src/graph/leetcode/NewRoadsMinimumSpanningTree.java create mode 100644 src/graph/leetcode/RedundantConnection.java create mode 100644 src/graph/leetcode/SentenceSimilarityII.java create mode 100644 src/graph/leetcode/SnapShotUtil.java create mode 100644 src/graph/primsAlgorithm/BinaryMinHeap.java create mode 100644 src/graph/primsAlgorithm/Graph.java create mode 100644 src/graph/primsAlgorithm/PrimMST.java create mode 100644 src/graph/primsAlgorithm/PrimsMSTArray.java create mode 100644 src/graph/shortestPath/Graph.java create mode 100644 src/graph/shortestPath/ShortestPath.java create mode 100644 src/graph/topologicalsort/Graph.java create mode 100644 src/graph/topologicalsort/TopologicalSort.java create mode 100644 src/graph/topologicalsort/TopologicalSortList.java create mode 100644 src/microsoftassesment/AutocompleteSystem.java create mode 100644 src/microsoftassesment/CropWords.java create mode 100644 src/microsoftassesment/DLLNode.java create mode 100644 src/microsoftassesment/LexicographicallySmallest.java create mode 100644 src/microsoftassesment/LongestSubStringWithout3ContiguousLetter.java create mode 100644 src/microsoftassesment/MinDeletionToMakeUniqueCount.java create mode 100644 src/microsoftassesment/MinStepsToMakePileSameHeight.java create mode 100644 src/microsoftassesment/MinSwapsToGroupRedBalls.java create mode 100644 src/microsoftassesment/NumsWithEqualDigitSum.java create mode 100644 src/microsoftassesment/RemoveCharsMoreThanKOccurrence.java create mode 100644 src/microsoftassesment/SnakeGame.java create mode 100644 src/microsoftassesment/StringWithout3ConsequitiveLetter.java create mode 100755 src/multithreading/barberProblem/Barber.java create mode 100755 src/multithreading/barberProblem/Customer.java create mode 100755 src/multithreading/barberProblem/Main.java create mode 100755 src/multithreading/barberProblem/WaitingRoom.java create mode 100644 src/multithreading/com/safecabs/Constants.java create mode 100644 src/multithreading/com/safecabs/Gender.java create mode 100644 src/multithreading/com/safecabs/app/AssignCab.java create mode 100644 src/multithreading/com/safecabs/app/CabProvider.java create mode 100644 src/multithreading/com/safecabs/app/CabRequest.java create mode 100644 src/multithreading/com/safecabs/app/CustomCyclicBarrier.java create mode 100644 src/multithreading/com/safecabs/cab/Cab.java create mode 100644 src/multithreading/com/safecabs/client/ClientTest.java create mode 100644 src/multithreading/com/safecabs/exceptions/UnRegisteredPassengerException.java create mode 100644 src/multithreading/com/safecabs/passenger/Passenger.java create mode 100644 src/multithreading/com/safecabs/passenger/RegisteredPassenger.java create mode 100644 src/multithreading/educative/BarberShopProblem.java create mode 100644 src/multithreading/educative/Barrier.java create mode 100644 src/multithreading/educative/BlockingQueue.java create mode 100644 src/multithreading/educative/CountingSemaphore.java create mode 100644 src/multithreading/educative/DeferredCallbackExecutor.java create mode 100644 src/multithreading/educative/DemonstrationThreadLocal.java create mode 100644 src/multithreading/educative/DiningPhilosophers.java create mode 100644 src/multithreading/educative/DiningPhilosophers2.java create mode 100644 src/multithreading/educative/MultiThreadedMergeSort.java create mode 100644 src/multithreading/educative/ReadWriteLock.java create mode 100644 src/multithreading/educative/TokenBucketFilter.java create mode 100644 src/multithreading/educative/UberSeatingProblem.java create mode 100644 src/multithreading/educative/UnisexBathroom.java create mode 100644 src/multithreading/educative/UnisexBathroom2.java create mode 100644 src/multithreading/educative/companies/netflix/Callback.java create mode 100644 src/multithreading/educative/companies/netflix/Executor.java create mode 100644 src/multithreading/educative/companies/netflix/Run.java create mode 100644 src/multithreading/educative/companies/netflix/SynchronousExecutor.java create mode 100644 src/multithreading/educative/examples/CallableExample.java create mode 100644 src/multithreading/educative/examples/DaemonThreadSpawn.java create mode 100644 src/multithreading/educative/examples/FutureTaskExample.java create mode 100644 src/multithreading/educative/examples/StockOrder.java create mode 100644 src/multithreading/educative/examples/ThreadExample.java create mode 100644 src/multithreading/educative/examples/ThreadExecutorExample.java create mode 100644 src/multithreading/educative/examples/ThreadInterruptedException.java create mode 100644 src/multithreading/educative/examples/ThreadSleepExample.java create mode 100644 src/multithreading/educative/examples/ThreadSpawn.java create mode 100644 src/multithreading/educative/examples/TimerVsPool.java create mode 100644 src/multithreading/educative/superman/Superman.java create mode 100644 src/multithreading/educative/superman/SupermanNaiveButCorrect.java create mode 100644 src/multithreading/educative/superman/SupermanSlightlyBetter.java create mode 100644 src/multithreading/educative/superman/SupermanWithFlaws.java create mode 100644 src/multithreading/executor/User.java create mode 100644 src/multithreading/practice/Addition.java create mode 100644 src/multithreading/practice/CountdownLatch.java create mode 100644 src/multithreading/practice/FizzBuzz.java create mode 100644 src/multithreading/practice/Foo.java create mode 100644 src/multithreading/practice/FooBar.java create mode 100644 src/multithreading/practice/OddEven.java create mode 100644 src/multithreading/practice/OddEvenSemaphore.java create mode 100644 src/multithreading/practice/ProducerConsumer.java create mode 100644 src/multithreading/practice/ZeroEvenOdd.java create mode 100644 src/multithreading/thread/BasicMultiThreading.java create mode 100644 src/multithreading/thread/DeadLock.java create mode 100644 src/multithreading/thread/PrintEvenOddTester.java create mode 100644 src/multithreading/thread/PrintOddEvenByTwoThreads.java create mode 100644 src/multithreading/thread/RaceConditionExample.java create mode 100644 src/multithreading/thread/Tesst.java create mode 100644 src/multithreading/thread/TestForLocking.java create mode 100644 src/multithreading/thread/ThreadJoinExample.java create mode 100644 src/multithreading/thread/ThreadRunnable.java create mode 100644 src/strings/common/sorting/ImplementABinaryHeap.java create mode 100644 src/strings/common/sorting/InsertionSort.java create mode 100644 src/strings/common/sorting/KthLargestElement.java create mode 100644 src/strings/common/sorting/MaxHeap.java create mode 100644 src/strings/common/sorting/MergeSort.java create mode 100644 src/strings/common/sorting/PractiseMergeSort.java create mode 100644 src/strings/common/sorting/QuickSelect.java create mode 100644 src/strings/common/sorting/QuickSort.java create mode 100644 src/strings/dynamicProblems/All_Possible_Combinatons.java create mode 100644 src/strings/dynamicProblems/DynamicIntegerGenerator.java create mode 100644 src/strings/dynamicProblems/FirstNonRepeating.java create mode 100644 src/strings/dynamicProblems/PossibleCombinations.java create mode 100644 src/strings/dynamicProblems/ReverseSentence.java create mode 100644 src/strings/dynamicProblems/Subsequence.java create mode 100644 src/strings/stringProblems/Combination.java create mode 100644 src/strings/stringProblems/DistinctSubstring.java create mode 100644 src/strings/stringProblems/FindLongestStringInArray.java create mode 100644 src/strings/stringProblems/MostCommonWord.java create mode 100644 src/strings/stringProblems/PermutationAndCombination.java create mode 100644 src/strings/stringProblems/RearrangeCharactersInString.java create mode 100644 src/strings/stringmatching/KMP.java create mode 100644 src/strings/stringmatching/MaxProductString.java create mode 100644 src/strings/stringmatching/RabinKarp.java diff --git a/src/CombinationsAndPermutations/Combinations.java b/src/CombinationsAndPermutations/Combinations.java new file mode 100644 index 0000000..6cae079 --- /dev/null +++ b/src/CombinationsAndPermutations/Combinations.java @@ -0,0 +1,67 @@ +package CombinationsAndPermutations; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class Combinations { + + public List> combinationSum(int[] candidates, int target) { + if(candidates==null || candidates.length==0) return Collections.emptyList(); + List> result= new ArrayList<>(); + + combinationSumUtil(candidates, target, result, new ArrayList<>(), 0); + + return result; + + } + + public void combinationSumUtil(int[] candidates, int target, List> result, List tempList, int start ){ + if(target<0) return; + if(target==0){ + result.add(new ArrayList(tempList)); + + } + + for(int i=start; i> combinationSum2(int[] candidates, int target) { + if(candidates==null || candidates.length==0) return Collections.emptyList(); + List> result= new ArrayList<>(); + Arrays.sort(candidates); + combinationSumUtil1(candidates, target, result, new ArrayList<>(), 0); + + return result; + } + + public void combinationSumUtil1(int[] candidates, int target, List> result, List tempList, int start){ + if(target<0) return; + + if(target==0){ + result.add(new ArrayList<>(tempList)); + return; + } + + for(int i=start; i cur means cand[i - 1] is not added to the path (you should know why if you understand the algorithm), so if cand[i] == cand[i-1], then we shouldn't add cand[i]. +// +// This tricky is very smart. + if(i>start && candidates[i]==candidates[i-1]) continue; + if (target - candidates[i] < 0) break; + tempList.add(candidates[i]); + combinationSumUtil1(candidates, target-candidates[i], result, tempList, i+1); + tempList.remove(tempList.size()-1); + } + } +} diff --git a/src/CombinationsAndPermutations/Permutations.java b/src/CombinationsAndPermutations/Permutations.java new file mode 100644 index 0000000..bd906b4 --- /dev/null +++ b/src/CombinationsAndPermutations/Permutations.java @@ -0,0 +1,63 @@ +package CombinationsAndPermutations; + +import java.util.*; + +public class Permutations { + + public List> permute(int[] nums) { + if(nums==null || nums.length==0) return Collections.emptyList(); + List> result= new ArrayList<>(); + permuteUtils(nums, result, new ArrayList<>()); + + return result; + } + + public void permuteUtils(int[] nums, List> result, List tempList){ + + if(tempList.size()==nums.length){ + result.add(new ArrayList(tempList)); + return; + } + + for(int i=0; i> permuteUnique(int[] nums) { + List> list = new ArrayList<>(); + Arrays.sort(nums); + backtrack(list, new ArrayList<>(), nums, new boolean[nums.length]); + return list; + } + + private void backtrack(List> list, List tempList, int [] nums, boolean [] used){ + if(tempList.size() == nums.length){ + list.add(new ArrayList<>(tempList)); + } else{ + for(int i = 0; i < nums.length; i++){ + //[1, 1, 2][1, 2, 1][2, 1, 1] + //[1, 2, 3][1, 3, 2][2, 1, 3][2, 3, 1][3, 1, 2][3, 2, 1] + if(used[i] || i > 0 && nums[i] == nums[i-1] && !used[i - 1]) continue; + used[i] = true; + tempList.add(nums[i]); + backtrack(list, tempList, nums, used); + used[i] = false; + tempList.remove(tempList.size() - 1); + } + } + } + +} + + diff --git a/src/CombinationsAndPermutations/SubSets.java b/src/CombinationsAndPermutations/SubSets.java new file mode 100644 index 0000000..160c74f --- /dev/null +++ b/src/CombinationsAndPermutations/SubSets.java @@ -0,0 +1,67 @@ +package CombinationsAndPermutations; + +import java.util.*; + +public class SubSets { + + public List> subsets(int[] nums) { + if(nums==null || nums.length==0) return Collections.emptyList(); + + List> result= new ArrayList<>(); + subSetGenerationUtil(nums, result, new ArrayList<>(), 0); + return result; + } + + public void subSetGenerationUtil(int[] nums, List> result, List tempList, int start){ + + result.add(new ArrayList<>(tempList)); + + for(int i=start;i> subsetsWithDup(int[] nums) { + if(nums==null || nums.length==0) return Collections.emptyList(); + + List> result= new ArrayList<>(); + Arrays.sort(nums); + //subsetsWithDupUtil(nums, result, new ArrayList<>(), 0); + dfs(nums,0,result, new ArrayList<>()); + return result; + } + + public void subsetsWithDupUtil(int[] nums, List> result, List tempList, int start){ + result.add(new ArrayList<>(tempList)); + + for(int i=start; istart && nums[i]==nums[i-1]) continue; + tempList.add(nums[i]); + subsetsWithDupUtil(nums, result, tempList, i+1); + tempList.remove(tempList.size()-1); + } + } + + private void dfs(int[] nums, int index, List> res, List curr){ + res.add(new ArrayList<>(curr)); + if(index == nums.length){ + return; + } + Set visited = new HashSet(); + for(int i = index; i < nums.length; i++){ + if(visited.add(nums[i])){ + curr.add(nums[i]); + dfs(nums, i + 1, res, curr); + curr.remove(curr.size() - 1); + } + } + } + + public static void main(String[] args) { + new SubSets().subsetsWithDup(new int[]{1,1,2,4}); + } +} + diff --git a/src/common/sorting/ImplementABinaryHeap.java b/src/common/sorting/ImplementABinaryHeap.java new file mode 100644 index 0000000..9db2639 --- /dev/null +++ b/src/common/sorting/ImplementABinaryHeap.java @@ -0,0 +1,248 @@ +package common.sorting; +/* + A min heap implementation + + Array Form: [ 5, 7, 6, 10, 15, 17, 12 ] + + Complete Binary Tree Form: + 5 + / \ + 7 6 + / \ / \ + 10 15 17 12 + + Mappings: + Parent -> (childIndex - 1) / 2 + Left Child -> 2 * parentIndex + 1 + Right Child -> 2 * parentIndex + 2 + + YouTube explanation: https://www.youtube.com/watch?v=g9YK6sftDi0 + Heap Sort explanation: https://www.youtube.com/watch?v=k72DtCnY4MU +*/ +import java.util.*; + +public class ImplementABinaryHeap { + int[] insertItems = new int[]{ 0, 1, 3, 2, -4, 9, 1, 2 }; + public static void main(String args[]) { + MinHeap minHeap = new MinHeap(); + int[] insertItems = new int[]{ 0, 1, 3, 2, -4, 9, 1, 2 }; + + for (int i = 0; i < insertItems.length; i++) { + minHeap.add(insertItems[i]); + System.out.println("Add " + insertItems[i]); + System.out.println("Min is " + minHeap.peek()); + + minHeap.printUnderlyingArray(); + + System.out.println("\n"); + } + + System.out.println("\n\n"); + + for (int i = 0; i < insertItems.length; i++) { + System.out.println("Remove " + minHeap.remove()); + System.out.println("Min is " + minHeap.peek()); + + minHeap.printUnderlyingArray(); + + System.out.println("\n"); + } + } + + private static class MinHeap { + private int capacity = 5; + private int heap[]; + private int size; + // int[] temp= new ImplementABinaryHeap().insertItems; + public MinHeap() { + heap = new int[capacity]; + } + + public boolean isEmpty() { + return size == 0; + } + + public int peek() { + if (isEmpty()) { + throw new NoSuchElementException("Heap is empty."); + } + + return heap[0]; + } + + public int remove() { + if (isEmpty()) { + throw new NoSuchElementException("Heap is empty."); + } + + /* + -> Grab the min item. It is at index 0. + -> Move the last item in the heap to the "top" of the + heap at index 0. + -> Reduce size. + */ + int minItem = heap[0]; + heap[0] = heap[size - 1]; + size--; + + /* + Restore the heap since it is very likely messed up now + by bubbling down the element we swapped up to index 0 + */ + heapifyDown(); + + return minItem; + } + + public void add(int itemToAdd) { + ensureExtraCapacity(); + + /* + -> Place the item at the bottom, far right, of the + conceptual binary heap structure + -> Increment size + */ + heap[size] = itemToAdd; + size++; + + /* + Restore the heap since it is very likely messed up now + by bubbling up the element we just put in the last empty + position of the conceptual complete binary tree + */ + siftUp(); + } + + /*********************************** + Heap restoration helpers + ***********************************/ + + private void heapifyDown() { + /* + We will bubble down the item just swapped to the "top" of the heap + after a removal operation to restore the heap + */ + int index = 0; + + /* + Since a binary heap is a complete binary tree, if we have no left child + then we have no right child. So we continue to bubble down as long as + there is a left child. + + A non-existent left child immediately tells us that a right child does + not exist. + */ + while (hasLeftChild(index)) { + /* + By default assume that left child is smaller. If a right + child exists see if it can overtake the left child by + being smaller + */ + int smallerChildIndex = getLeftChildIndex(index); + if (hasRightChild(index) && rightChild(index) < leftChild(index)) { + smallerChildIndex = getRightChildIndex(index); + } + + /* + If the item we are sitting on is < the smaller child then + nothing needs to happen & sifting down is finished. + + But if the smaller child is smaller than the node we are + holding, we should swap and continue sifting down. + */ + if (heap[index] < heap[smallerChildIndex]) { + break; + } else { + swap(index, smallerChildIndex); + } + + // Move to the node we just swapped down + index = smallerChildIndex; + } + } + + // Bubble up the item we inserted at the "end" of the heap + private void siftUp() { + /* + We will bubble up the item just inserted into to the "bottom" + of the heap after an insert operation. It will be at the last index + so index 'size' - 1 + */ + int index = size - 1; + + /* + While the item has a parent and the item beats its parent in + smallness, bubble this item up. + */ + while (hasParent(index) && heap[index] < parent(index)) { + swap(getParentIndex(index), index); + index = getParentIndex(index); + } + } + + /************************************************ + Helpers to access our array easily, perform + rudimentary operations, and manipulate capacity + ************************************************/ + + private void swap(int indexOne, int indexTwo) { + int temp = heap[indexOne]; + heap[indexOne] = heap[indexTwo]; + heap[indexTwo] = temp; + } + + // If heap is full then double capacity + private void ensureExtraCapacity() { + if (size == capacity) { + heap = Arrays.copyOf(heap, capacity * 2); + capacity *= 2; + } + } + + private int getLeftChildIndex(int parentIndex) { + return 2 * parentIndex + 1; + } + + private int getRightChildIndex(int parentIndex) { + return 2 * parentIndex + 2; + } + + private int getParentIndex(int childIndex) { + return (childIndex - 1) / 2; + } + + private boolean hasLeftChild(int index) { + return getLeftChildIndex(index) < size; + } + + private boolean hasRightChild(int index) { + return getRightChildIndex(index) < size; + } + + private boolean hasParent(int index) { + return index != 0 && getParentIndex(index) >= 0; + } + + private int leftChild(int index) { + return heap[getLeftChildIndex(index)]; + } + + private int rightChild(int index) { + return heap[getRightChildIndex(index)]; + } + + private int parent(int index) { + return heap[getParentIndex(index)]; + } + + /***********************************************/ + + private void printUnderlyingArray() { + System.out.print("[ "); + for (int item: heap) { + System.out.print(item + " "); + } + System.out.print("]"); + } + } +} \ No newline at end of file diff --git a/src/common/sorting/InsertionSort.java b/src/common/sorting/InsertionSort.java new file mode 100644 index 0000000..985edc8 --- /dev/null +++ b/src/common/sorting/InsertionSort.java @@ -0,0 +1,30 @@ +package common.sorting; + +public class InsertionSort { + + public static void main(String[] args) { + int[] arr = { 12, 11, 13, 5, 6 }; +System.out.println(System.currentTimeMillis()); + + for (int i = 1; i < arr.length; i++) { + int index =i; + for (int j = i-1; j >= 0; j--) { + int value = arr[index]; + if (arr[index] < arr[j]) { + int temp = arr[j]; + arr[j] = value; + arr[index] = temp; + index--; + }else{ + continue; + } + } + } + System.out.println(System.currentTimeMillis()); + + for (int i = 0; i < arr.length; i++) { + System.out.println(arr[i]); + } + } + +} diff --git a/src/common/sorting/KthLargestElement.java b/src/common/sorting/KthLargestElement.java new file mode 100644 index 0000000..4c2f8d3 --- /dev/null +++ b/src/common/sorting/KthLargestElement.java @@ -0,0 +1,62 @@ +package common.sorting; + +import java.util.*; + +public class KthLargestElement { + class Solution { + public int findKthLargest(int[] nums, int k) { + + return quickSelect(nums, 0, nums.length-1,nums.length-k); + } + + public void swap(int[] A, int i, int j) { + int temp = A[i]; + A[i] = A[j]; + A[j] = temp; + } + + public int partition(int[] nums, int start, int end) { + Random rand= new Random(); + //Get a random pivot between beg and end + int pivotIndex= start+rand.nextInt(Math.abs(end-start)); + + //New position of pivot element + int last=end; + + //Move the pivot element to right edge of the array + swap(nums,pivotIndex,end); + + end--; + + while(start<=end){ + if(nums[start]= 0; i--) + heapify(arr, i, n); + + for (int i = 0; i < n; i++) + System.out.print(arr[i] + " "); + + System.out.println(); + for (int i = n - 1; i >= 0; i--) { + int temp = arr[0]; + arr[0] = arr[i]; + arr[i] = temp; + + heapify(arr, 0, i); + } + + for (int i = 0; i < n; i++) + System.out.print(arr[i] + " "); + } + + private void heapify(int[] arr, int i, int n) { + int largest = i; + int left = 2 * i + 1; + int right = 2 * i + 2; + + if (left < n && arr[left] > arr[largest]) + largest = left; + if (right < n && arr[right] > arr[largest]) + largest = right; + if (largest != i) { + int temp = arr[largest]; + arr[largest] = arr[i]; + arr[i] = temp; + + heapify(arr, largest, n); + } + } +} \ No newline at end of file diff --git a/src/common/sorting/MergeSort.java b/src/common/sorting/MergeSort.java new file mode 100644 index 0000000..811f016 --- /dev/null +++ b/src/common/sorting/MergeSort.java @@ -0,0 +1,47 @@ +package common.sorting; + +import java.util.Arrays; + +class MergeSort { + + static void mergeSort(int arr[], int temp[], int left, int right) { + if (left < right) { + int mid = ((right - left) / 2) + left; + + mergeSort(arr, temp, left, mid); + mergeSort(arr, temp, mid + 1, right); + + merge(arr, temp, left, mid, right); + } + } + + static void merge(int arr[], int temp[], int left, int mid, int right) { + + int i = left; + int j = mid + 1; + int k = left; + while ((i <= mid) && (j <= right)) { + if (arr[i] < arr[j]) { + temp[k++] = arr[i++]; + } else { + temp[k++] = arr[j++]; + } + } + + while (i <= mid) + temp[k++] = arr[i++]; + while (j <= right) + temp[k++] = arr[j++]; + + for (i = left; i <= right; i++) + arr[i] = temp[i]; + + } + + public static void main(String[] args) { + int arr[] = new int[] { 8, 4, 1, 2 }; + int temp[] = new int[arr.length]; + mergeSort(arr, temp, 0, arr.length - 1); + System.out.println(Arrays.toString(arr)); + } +} diff --git a/src/common/sorting/PractiseMergeSort.java b/src/common/sorting/PractiseMergeSort.java new file mode 100644 index 0000000..78c6cae --- /dev/null +++ b/src/common/sorting/PractiseMergeSort.java @@ -0,0 +1,48 @@ +package common.sorting; + +import java.util.Arrays; + +public class PractiseMergeSort { + + public static void main(String[] args) { + int[] arr = { 9, 3, -1, 5, 2, 7 }; + int n = arr.length; + int[] temp = new int[n]; + mergeSort(arr, temp, 0, n - 1); + System.out.println(Arrays.toString(arr)); + } + + private static void mergeSort(int arr[], int temp[], int left, int right) { + while (left < right) { + int mid = ((right - left) / 2) + left; + mergeSort(arr, temp, left, mid); + mergeSort(arr, temp, mid + 1, right); + mergeUtil(arr, temp, left, mid, right); + } + } + + private static void mergeUtil(int[] arr, int[] temp, int left, int mid, int right) { + int i = left; + int j = mid + 1; + int k = left; + + while (i <= mid && j <= right) { + if (arr[i] < arr[j]) { + temp[k++] = arr[i++]; + } else { + temp[k++] = arr[j++]; + } + } + + while (i <= mid) { + temp[k++] = arr[i++]; + } + while (j <= right) { + temp[k++] = arr[j++]; + } + + for (int index = left; index <= right; index++) { + arr[index] = temp[index]; + } + } +} diff --git a/src/common/sorting/QuickSelect.java b/src/common/sorting/QuickSelect.java new file mode 100644 index 0000000..b407d67 --- /dev/null +++ b/src/common/sorting/QuickSelect.java @@ -0,0 +1,50 @@ +package common.sorting; + +import java.util.Random; + +class QuickSelect { + + public static void swap(int[] A, int i, int j) { + int temp = A[i]; + A[i] = A[j]; + A[j] = temp; + } + + public static int partition(int[] A, int low, int high, int pivotIndex) { + int pivot = A[pivotIndex]; + swap(A, pivotIndex, high); + int iLow = low; + for (int i = low; i < high; i++) { + if (A[i] <= pivot) { + swap(A, i, iLow); + iLow++; + } + } + swap(A, iLow, high); + return iLow; + } + + public static int quickSelect(int[] A, int left, int right, int k) { + if (left == right) { + return A[left]; + } + int pivotIndex = new Random().nextInt(right - left + 1) + left; + pivotIndex = partition(A, left, right, pivotIndex); + if (k == pivotIndex) { + return A[k]; + } else if (k < pivotIndex) { + return quickSelect(A, left, pivotIndex - 1, k); + } else { + return quickSelect(A, pivotIndex + 1, right, k); + } + } + + public static void main(String[] args) { + int[] A = { 7, 4, 6, 3, 9, 1 }; + int k = 2; + + System.out.print("K'th smallest element is " + quickSelect(A, 0, A.length - 1, k)); + } +} + + diff --git a/src/common/sorting/QuickSort.java b/src/common/sorting/QuickSort.java new file mode 100644 index 0000000..25691d7 --- /dev/null +++ b/src/common/sorting/QuickSort.java @@ -0,0 +1,57 @@ +package common.sorting; + +import java.util.Random; + +public class QuickSort { + + public int[] sortArray(int[] nums) { + + quickSort(nums, 0, nums.length-1); + + return nums; +} + + public void quickSort(int[] nums, int start, int end){ + if(start T[i]) { + T[i] = T[j] + allRotationInput[i].height; + result[i] = j; + } + } + } + } + + int max = Integer.MIN_VALUE; + for (int i = 0; i < T.length; i++) { + if (T[i] > max) { + max = T[i]; + } + } + + return max; + } + + private void createAllRotation(Dimension[] input, Dimension[] allRotationInput) { + int index = 0; + for (int i = 0; i < input.length; i++) { + allRotationInput[index++] = Dimension.createDimension(input[i].height, input[i].length, input[i].width); + allRotationInput[index++] = Dimension.createDimension(input[i].length, input[i].height, input[i].width); + allRotationInput[index++] = Dimension.createDimension(input[i].width, input[i].length, input[i].height); + + } + } + + public static void main(String args[]) { + BoxStacking bs = new BoxStacking(); + Dimension[] input = { new Dimension(3, 2, 5), new Dimension(1, 2, 4) }; + int maxHeight = bs.maxHeight(input); + System.out.println("Max height is " + maxHeight); + assert 11 == maxHeight; + } +} + +class Dimension implements Comparable { + int height; + int length; + int width; + + Dimension(int height, int length, int width) { + this.height = height; + this.length = length; + this.width = width; + } + + Dimension() { + } + + static Dimension createDimension(int height, int side1, int side2) { + Dimension d = new Dimension(); + d.height = height; + if (side1 >= side2) { + d.length = side1; + d.width = side2; + } else { + d.length = side2; + d.width = side1; + } + return d; + } + + @Override + public int compareTo(Dimension d) { + if (this.length * this.width >= d.length * d.width) { + return 1; + } else { + return -1; + } + } + + @Override + public String toString() { + return "Dimension [height=" + height + ", length=" + length + ", width=" + width + "]"; + } +} \ No newline at end of file diff --git a/src/dynamicProgramming/CatalanNumberBinarySearchTree.java b/src/dynamicProgramming/CatalanNumberBinarySearchTree.java new file mode 100644 index 0000000..f4fe053 --- /dev/null +++ b/src/dynamicProgramming/CatalanNumberBinarySearchTree.java @@ -0,0 +1,28 @@ +package dynamicProgramming; + +/** + * @author i312458 + * + * https://www.youtube.com/watch?v=YDf982Lb84o&t=277s + */ +public class CatalanNumberBinarySearchTree { + public int countTrees(int n) { + int[] T = new int[n + 1]; + T[0] = 1; + T[1] = 1; + for (int i = 2; i <= n; i++) { + for (int j = 0; j < i; j++) { + System.out.println("T[" + j + "]" + "*" + "T[" + (i - j - 1) + "] :: " + T[j] * T[i - j - 1]); + + T[i] += T[j] * T[i - j - 1]; + } + } + return T[n]; + } + + public static void main(String args[]) { + CatalanNumberBinarySearchTree cnt = new CatalanNumberBinarySearchTree(); + System.out.println(); + System.out.println(cnt.countTrees(3)); + } +} diff --git a/src/dynamicProgramming/EggDropping.java b/src/dynamicProgramming/EggDropping.java new file mode 100644 index 0000000..8d2bb77 --- /dev/null +++ b/src/dynamicProgramming/EggDropping.java @@ -0,0 +1,59 @@ +package dynamicProgramming; + +/** + * http://www.geeksforgeeks.org/dynamic-programming-set-11-egg-dropping-puzzle/ + *

+ * https://www.youtube.com/watch?v=3hcaVyX00_4&t=258s + */ +public class EggDropping { + // calculate minimum tries to try to find the floor which breaks the egg + public int calculate(int eggs, int floors) { + + int[][] T = new int[eggs + 1][floors + 1]; + int c = 0; + // We need one trial for one floor + for (int i = 0; i <= floors; i++) { + T[1][i] = i; + } + + for (int e = 2; e <= eggs; e++) { + for (int f = 1; f <= floors; f++) { + T[e][f] = Integer.MAX_VALUE; + for (int k = 1; k <= f; k++) { // for loop to go from 0-f floor + // if egg breaks then egg-1 and floor -1 ==> T[e - 1][k - 1] + // else no change in egg count and remaining floors which is f-k ==> T[e][f - k] + // k means which floor we are in -- > first floor , second floor + // 2 Eggs -> 3 Floors + // • 2 Eggs -> 1 Floor-> 1,0 ,, 2,2(remaining floors) + // • 2 Eggs -> 2nd Floor -> 1,1 ,, 2,1 (remaining floors) + // 2 Eggs -> 3rd Floor -> 1,2 ,, 2,0 (remaining floors) + System.out.println("e - " + e + " :: f - " + f + " :: k - " + k); + System.out.println("T[" + (e - 1) + "][" + (k - 1) + "],T[" + e + "][" + (f - k) + "]"); + c = 1 + Math.max(T[e - 1][k - 1], T[e][f - k]); + if (c < T[e][f]) { + T[e][f] = c; + } + } + } + } + return T[eggs][floors]; + } + + public static int superEggDrop(int K, int N) { + int[][] dp = new int[N + 1][K + 1]; + int m = 0; + while (dp[m][K] < N) { + ++m; + for (int k = 1; k <= K; ++k) + dp[m][k] = dp[m - 1][k - 1] + dp[m - 1][k] + 1; + } + return m; + } + + public static void main(String args[]) { + EggDropping ed = new EggDropping(); + // System.out.println(ed.calculate(2, 6)); + System.out.println(superEggDrop(2, 6)); + } + +} \ No newline at end of file diff --git a/src/dynamicProgramming/MaxSumForNonAdjacentElements.java b/src/dynamicProgramming/MaxSumForNonAdjacentElements.java new file mode 100644 index 0000000..684486b --- /dev/null +++ b/src/dynamicProgramming/MaxSumForNonAdjacentElements.java @@ -0,0 +1,27 @@ +package dynamicProgramming; + +/** + * @author Tushar Roy + * + * https://www.geeksforgeeks.org/maximum-sum-such-that-no-two-elements-are-adjacent/ + */ +public class MaxSumForNonAdjacentElements { + + public int maxSum(int arr[]) { + int excl = 0; + int incl = arr[0]; + for (int i = 1; i < arr.length; i++) { + int oldResult = incl; + incl = Math.max(excl + arr[i], incl); + excl = oldResult; + } + return incl; + } + + public static void main(String args[]) { + MaxSumForNonAdjacentElements msn = new MaxSumForNonAdjacentElements(); + int arr[] = { 4, 1, 1, 4, 2, 1 }; + System.out.println(msn.maxSum(arr)); + + } +} \ No newline at end of file diff --git a/src/dynamicProgramming/MaximumSquareDP.java b/src/dynamicProgramming/MaximumSquareDP.java new file mode 100644 index 0000000..fe46420 --- /dev/null +++ b/src/dynamicProgramming/MaximumSquareDP.java @@ -0,0 +1,23 @@ +package dynamicProgramming; + +class MaximumSquareDP { + public int maximalSquare(char[][] matrix) { + if(matrix==null || matrix.length==0) return 0; + + int[][]dp= new int[matrix.length+1][matrix[0].length+1]; + int result=0; + + + for(int i=1;i<=matrix.length;i++){ + for(int j=1; j<=matrix[0].length;j++){ + if(matrix[i-1][j-1]=='1') { + dp[i][j]=1+Math.min(dp[i-1][j], Math.min(dp[i][j-1],dp[i-1][j-1])); + result=Math.max(result, dp[i][j]); + } + } + } + + return result*result; + } +} + diff --git a/src/dynamicProgramming/MinCostTickets.java b/src/dynamicProgramming/MinCostTickets.java new file mode 100644 index 0000000..119b7de --- /dev/null +++ b/src/dynamicProgramming/MinCostTickets.java @@ -0,0 +1,42 @@ +package dynamicProgramming; + +public class MinCostTickets { + + //1,4,6,7,8,20 + //2,7,50 + public int mincostTickets(int[] days, int[] costs) { + if(days.length==0) return 0; + + boolean[] travelledDays= new boolean [366]; + + for(int i=0; i< days.length;i++){ + travelledDays[days[i]]=true; + } + + int[] result= new int[366]; + result[0]=0; + for(int i=1; ii) continue; + int change =i-coins[j]; // when i is 5 and coins =[1,2,5] and j=1(first coin)we subtract 5-1=4 we need ans for 4, which we'd have calculated when i=4 + int temp=result[change]+1; // when found a coin we add 1 to the position + result[i]=Math.min(result[i],temp); + + } + + } + + return result[amount] > amount ? -1 : result[amount]; + } +} diff --git a/src/dynamicProgramming/MinimumNumberOfJumpsToReachEnd.java b/src/dynamicProgramming/MinimumNumberOfJumpsToReachEnd.java new file mode 100644 index 0000000..667a039 --- /dev/null +++ b/src/dynamicProgramming/MinimumNumberOfJumpsToReachEnd.java @@ -0,0 +1,64 @@ +package dynamicProgramming; + +/** + * Date 06/12/2014 + * + * @author tusroy + * + * Space complexity O(n) to maintain result and min jumps Time + * complexity O(n^2) + * + * http://www.geeksforgeeks.org/minimum-number-of-jumps-to-reach-end-of-a-given-array/ + * https://www.youtube.com/watch?v=cETfFsSTGJI + */ +public class MinimumNumberOfJumpsToReachEnd { + + public int minJump(int arr[], int result[]) { + + int[] jump = new int[arr.length]; + jump[0] = 0; + for (int i = 1; i < arr.length; i++) { + jump[i] = Integer.MAX_VALUE - 1; + } + + for (int i = 1; i < arr.length; i++) { + for (int j = 0; j < i; j++) { + if (arr[j] + j >= i) { + if (jump[i] > jump[j] + 1) { + result[i] = j; + jump[i] = jump[j] + 1; + } + } + } + } + + return jump[jump.length - 1]; + } + + public static void main(String args[]) { + MinimumNumberOfJumpsToReachEnd mj = new MinimumNumberOfJumpsToReachEnd(); + int arr[] = { 2, 3, 1, 1, 2, 4, 2, 0, 1, 1 }; + int r[] = new int[arr.length]; + int result = mj.minJump(arr, r); + System.out.println(result); + } + + + public int jump(int[] A) { + int jumps = 0, curEnd = 0, curFarthest = 0; + for (int i = 0; i < A.length - 1; i++) { + curFarthest = Math.max(curFarthest, i + A[i]); + // for this input { 1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9 } + // when i is at 1[3] farthest one can jump is till 4(farthest) and end is also updated, means till i reaches 4 if the farthest reaches the array end we break out of loop; + if (i == curEnd) { + jumps++; + curEnd = curFarthest; + + if (curEnd >= A.length - 1) { + break; + } + } + } + return jumps; + } +} \ No newline at end of file diff --git a/src/dynamicProgramming/NumberWithSameConsequtiveDifference.java b/src/dynamicProgramming/NumberWithSameConsequtiveDifference.java new file mode 100644 index 0000000..f754de4 --- /dev/null +++ b/src/dynamicProgramming/NumberWithSameConsequtiveDifference.java @@ -0,0 +1,56 @@ +package dynamicProgramming; + +import java.util.ArrayList; +import java.util.List; + +/** + * Return all non-negative integers of length N such that the absolute difference between every two consecutive digits is K. + * + * Note that every number in the answer must not have leading zeros except for the number 0 itself. For example, 01 has one leading zero and is invalid, but 0 is valid. + * + * You may return the answer in any order. + * + * Input: N = 3, K = 7 + * Output: [181,292,707,818,929] + * Explanation: Note that 070 is not a valid number, because it has leading zeroes. + * + * Input: N = 2, K = 1 + * Output: [10,12,21,23,32,34,43,45,54,56,65,67,76,78,87,89,98] + */ +public class NumberWithSameConsequtiveDifference { + + // the idea is to create a tree with dfs of depth N and in each step(level) we add and subract the K to + // the last element and check if it falls under the boundray (0> && <10) + // for N=3 and K=2 + // 1 + // -K / \ +K + // -2 3 + // / \ + // 1 5 --> end of tree because N=3 + + public int[] numsSameConsecDiff(int N, int K) { + List result= new ArrayList<>(); + if(N==1) result.add(0); + + for(int i=1;i<10;i++){ + dfs(N-1, K, result, i); + } + int[] ret = new int[result.size()]; + for(int i = 0;i < ret.length;i++) + ret[i] = result.get(i); + return ret; + } + + public void dfs(int N, int K, List result, int num){ + if(N==0) { + result.add(num); + return; + } + int last_digit= num%10; + + if(last_digit>=K) dfs(N-1,K,result,num*10+last_digit-K); + if(K>0 && K+last_digit<10) dfs(N-1,K,result,num*10+last_digit+K); + } + + +} diff --git a/src/dynamicProgramming/OptimalStratergy.java b/src/dynamicProgramming/OptimalStratergy.java new file mode 100644 index 0000000..77b6548 --- /dev/null +++ b/src/dynamicProgramming/OptimalStratergy.java @@ -0,0 +1,66 @@ +package dynamicProgramming; + +/** + * http://www.glassdoor.com/Interview/N-pots-each-with-some-number-of-gold-coins-are-arranged-in-a-line-You-are-playing-a-game-against-another-player-You-tak-QTN_350584.htm + * + * https://www.techiedelight.com/pots-gold-game-dynamic-programming/ + */ +public class OptimalStratergy { + // Function to maximize the number of coins collected by a player, + // assuming that opponent also plays optimally + public static int optimalStrategy(int[] coin, int i, int j, + int[][] lookup) + { + // base case: one pot left, only one choice possible + if (i == j) { + return coin[i]; + } + + // if we're left with only two pots, choose one with maximum coins + if (i + 1 == j) { + return Integer.max(coin[i], coin[j]); + } + + // if sub-problem is seen for the first time, solve it and + // store its result in a lookup table + if (lookup[i][j] == 0) + { + // if player chooses front coin i, opponent is left to choose + // from [i+1, j]. + // 1. if opponent chooses front coin i+1, recur for [i+2, j] + // 2. if opponent chooses rear coin j, recur for [i+1, j-1] + + int start = coin[i] + Integer.min(optimalStrategy(coin, i + 2, + j, lookup), + optimalStrategy(coin, i + 1, j - 1, lookup)); + + // if player chooses rear coin j, opponent is left to choose + // from [i, j-1]. + // 1. if opponent chooses front coin i, recur for [i+1, j-1] + // 2. if opponent chooses rear coin j-1, recur for [i, j-2] + + int end = coin[j] + Integer.min(optimalStrategy(coin, i + 1, + j - 1, lookup), + optimalStrategy(coin, i, j - 2, lookup)); + + // assign maximum of two choices + lookup[i][j] = Integer.max(start, end); + } + + // return the subproblem solution from the map + return lookup[i][j]; + } + + // main function + public static void main(String[] args) + { + // pots of gold arranged in a line + int[] coin = { 4, 6, 2, 3 }; + + // Create a table to store solutions of subproblems + int[][] lookup = new int[coin.length][coin.length]; + + System.out.println("Maximum coins collected by player is " + + optimalStrategy(coin, 0, coin.length - 1, lookup)); + } +} \ No newline at end of file diff --git a/src/dynamicProgramming/OptimalTreeSearch.java b/src/dynamicProgramming/OptimalTreeSearch.java new file mode 100644 index 0000000..5f7412f --- /dev/null +++ b/src/dynamicProgramming/OptimalTreeSearch.java @@ -0,0 +1,47 @@ +package dynamicProgramming; +/** + * http://www.geeksforgeeks.org/dynamic-programming-set-24-optimal-binary-search-tree/ + */ +public class OptimalTreeSearch { + + public int minCost(int input[], int freq[]){ + int T[][] = new int[input.length][input.length]; + + for(int i=0; i < T.length; i++){ + T[i][i] = freq[i]; + } + + for(int l = 2; l <= input.length; l++){ + for(int i=0; i <= input.length-l; i++){ + int j = i + l -1; + T[i][j] = Integer.MAX_VALUE; + int sum = getSum(freq, i, j); + + for(int k=i; k <= j; k++){ + int val = sum + (k-1 < i ? 0 : T[i][k-1]) + + (k+1 > j ? 0 : T[k+1][j]) ; + if(val < T[i][j]){ + T[i][j] = val; + } + } + } + } + return T[0][input.length-1]; + } + + private int getSum(int freq[], int i, int j){ + int sum = 0; + for(int x = i; x <= j; x++){ + sum += freq[x]; + } + return sum; + } + + + public static void main(String args[]){ + int input[] = {10,12,20,35,46}; + int freq[] = {34,8,50,21,16}; + OptimalTreeSearch ots = new OptimalTreeSearch(); + System.out.println(ots.minCost(input, freq)); + } +} \ No newline at end of file diff --git a/src/dynamicProgramming/StockBuySellKTransactions.java b/src/dynamicProgramming/StockBuySellKTransactions.java new file mode 100644 index 0000000..28df38a --- /dev/null +++ b/src/dynamicProgramming/StockBuySellKTransactions.java @@ -0,0 +1,103 @@ +package dynamicProgramming; + +import java.util.Arrays; +import java.util.Deque; +import java.util.LinkedList; + +/** + * Date 12/22/2015 + * + * @author Tushar Roy + * + * Time complexity - O(number of transactions * number of days) Space + * complexity - O(number of transactions * number of days) + * + * https://leetcode.com/discuss/15153/a-clean-dp-solution-which-generalizes-to-k-transactions + * https://www.youtube.com/watch?v=Pw6lrYANjz4&t=1228s + */ +public class StockBuySellKTransactions { + + public int maxProfit(int prices[], int K) { + if (K == 0 || prices.length == 0) { + return 0; + } + int T[][] = new int[K + 1][prices.length]; + + for (int i = 1; i < T.length; i++) { + int maxDiff = -prices[0]; + for (int j = 1; j < T[0].length; j++) { + T[i][j] = Math.max(T[i][j - 1], prices[j] + maxDiff); + maxDiff = Math.max(maxDiff, T[i - 1][j] - prices[j]); + } + } + + System.out.println(Arrays.deepToString(T)); + printActualSolution(T, prices); + return T[K][prices.length - 1]; + } + public int maxProfit(int k, int[] prices) { + if(prices.length==0 || k==0) return 0; + + if(k>prices.length/2) return quickSolve(prices); + + int[][] maxProfit= new int[k+1][prices.length]; + //int diff=0; + for(int i=1;i<=k;i++){ + int diff = -prices[0]; + for(int j=1; j prices[i - 1]) profit += prices[i] - prices[i - 1]; + return profit; + } + public void printActualSolution(int T[][], int prices[]) { + int i = T.length - 1; + int j = T[0].length - 1; + + Deque stack = new LinkedList<>(); + while (true) { + if (i == 0 || j == 0) { + break; + } + if (T[i][j] == T[i][j - 1]) { + j = j - 1; + } else { + stack.addFirst(j); + int maxDiff = T[i][j] - prices[j]; + for (int k = j - 1; k >= 0; k--) { + if (T[i - 1][k] - prices[k] == maxDiff) { + i = i - 1; + j = k; + stack.addFirst(j); + break; + } + } + } + } + + while (!stack.isEmpty()) { + System.out.println("Buy at price " + prices[stack.pollFirst()]); + System.out.println("Sell at price " + prices[stack.pollFirst()]); + } + + } + + public static void main(String args[]) { + StockBuySellKTransactions sbt = new StockBuySellKTransactions(); + int prices[] = { 2, 5, 7, 1, 4, 3, 1, 3 }; + + System.out.println("Max profit fast solution " + sbt.maxProfit(prices, 3)); + } +} diff --git a/src/dynamicProgramming/StockBuySellWithCoolDown.java b/src/dynamicProgramming/StockBuySellWithCoolDown.java new file mode 100644 index 0000000..e8db2b0 --- /dev/null +++ b/src/dynamicProgramming/StockBuySellWithCoolDown.java @@ -0,0 +1,53 @@ +package dynamicProgramming; + +public class StockBuySellWithCoolDown { + + public int maxProfit(int[] prices) { + + if (prices == null || prices.length < 2) return 0; + int buy = 0, sell = -prices[0], rest = 0; + + // Assume the buy, sell and rest are states + // the transistions would be + // 1) from Rest you have to come to buy + // 2) from buy you can rest/hold or you can sell + // 3) from sell you can hold or sell and go to Rest + + // state 1=> first transistion max(buy, rest) we can either buy or rest at this point + // state 2=> we can either hold what was there in previous state or buy so '-' price[i] + // state 3=> to come to rest we have to sell and make profit so only the '+' sign + + for (int i = 1; i < prices.length; i++) { + int tmp = buy; + buy = Math.max(buy, rest); + rest = sell+prices[i]; + sell = Math.max(sell,tmp -prices[i]); + } + return Math.max(buy,rest); + } + + public static int maxProfit1(int[] prices){ + if(prices==null || prices.length<=1){ + return 0; + } + /** + there can be two types of profit we need to track + sellProf[i] - profit earned by selling on ith day + restProf[i] - profit earned by resting on ith day + */ + int sellProf = 0; + int restProf = 0; + int lastProf = 0; + for(int i = 1;i=0) + dp[i][j]+= dp[i][j-coins[i-1]]; + } + } + + + return dp[coins.length][amount]; + } +} diff --git a/src/dynamicProgramming/WordBreak.java b/src/dynamicProgramming/WordBreak.java new file mode 100644 index 0000000..2def948 --- /dev/null +++ b/src/dynamicProgramming/WordBreak.java @@ -0,0 +1,109 @@ +package dynamicProgramming; + +import java.util.*; + +/** + * Date 08/01/2014 + * + * @author tusroy + * + * Given a string and a dictionary, split this string into multiple + * words such that each word belongs in dictionary. + * + * e.g peanutbutter -> pea nut butter e.g Iliketoplay -> I like to play + * + * Solution DP solution to this problem if( input[i...j] belongs in + * dictionary) T[i][j] = i else{ T[i][j] = k if T[i][k-1] != -1 && + * T[k][j] != -1 + * + * Test cases 1) Empty string 2) String where entire string is in + * dictionary 3) String which cannot be split into words which are in + * dictionary 3) String which can be split into words which are in + * dictionary + * + */ +public class WordBreak { + + public String breakWordDP(String word, Set dict) { + int[][] T = new int[word.length()][word.length()]; + + for (int i = 0; i < T.length; i++) { + for (int j = 0; j < T[i].length; j++) { + T[i][j] = -1; + } + } + + for (int l = 1; l <= word.length(); l++) { + for (int i = 0; i < word.length() - l + 1; i++) { + int j = i + l - 1; + String str = word.substring(i, j + 1); + + if (dict.contains(str)) { + T[i][j] = i; + continue; + } + // find a k between i+1 to j such that T[i][k-1] && T[k][j] are both true + for (int k = i + 1; k <= j; k++) { + if (T[i][k - 1] != -1 && T[k][j] != -1) { + T[i][j] = k; + break; + } + } + } + } + if (T[0][word.length() - 1] == -1) { + return null; + } + + // create space separate word from string is possible + StringBuffer buffer = new StringBuffer(); + int i = 0; + int j = word.length() - 1; + while (i < j) { + int k = T[i][j]; + if (i == k) { + buffer.append(word.substring(i, j + 1)); + break; + } + buffer.append(word.substring(i, k) + " "); + i = k; + } + + return buffer.toString(); + } + + public static void main(String args[]) { + Set dictionary = new HashSet(); + dictionary.add("I"); + dictionary.add("am"); + dictionary.add("ace"); + String str = "Iamace"; + WordBreak bmw = new WordBreak(); + String result1 = bmw.breakWordDP(str, dictionary); + System.out.println(bmw.wordBreakBottomUp(str, dictionary)); + + //System.out.print(result1); + } + + /** + * to find out it has all the words + */ + public boolean wordBreakBottomUp(String s, Set set) { + //s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"] ans=false + boolean[] f = new boolean[s.length() + 1]; + //f[i] stands for whether subarray(0, i) can be segmented into words from the dictionary. + // So f[0] means whether subarray(0, 0) (which is an empty string) can be segmented, and of course the answer is yes. + //The default value for boolean array is false. Therefore we need to set f[0] to be true. + + f[0] = true; + for (int i = 1; i <= s.length(); i++) { + for (int j = i - 1; j >= 0; j--) { + System.out.println(s.substring(j, i)); + f[i] = f[j] && set.contains(s.substring(j, i)); + if (f[i]) break; + } + } + return f[s.length()]; + } + +} \ No newline at end of file diff --git a/src/dynamicProgramming/WordBreakII.java b/src/dynamicProgramming/WordBreakII.java new file mode 100644 index 0000000..4e327f9 --- /dev/null +++ b/src/dynamicProgramming/WordBreakII.java @@ -0,0 +1,34 @@ +package dynamicProgramming; + +import java.util.*; + +public class WordBreakII { + + public List wordBreak(String s, List wordDict) { + Map> cache = new HashMap<>(); + return backtrack(s,wordDict, cache); + } + + public List backtrack(String s, List wordDict, Map> cache){ + + if(cache.containsKey(s)) return cache.get(s); + + List result = new ArrayList<>(); + for(String word: wordDict) { + if(!s.startsWith(word)) continue; // string does not start with this word? + String next = s.substring(word.length()); + if(next.isEmpty()) { // awesome! + result.add(word); + continue; + } + for(String sub: backtrack(next, wordDict, cache)) + result.add(word + " " + sub); + } + cache.put(s, result); + return result; + } + + public static void main(String[] args) { + new WordBreakII().wordBreak( "catsanddog",Arrays.asList("cat", "cats", "and", "sand", "dog")); + } +} diff --git a/src/dynamicProgramming/fibonacci/DecodeWays.java b/src/dynamicProgramming/fibonacci/DecodeWays.java new file mode 100644 index 0000000..9903e3f --- /dev/null +++ b/src/dynamicProgramming/fibonacci/DecodeWays.java @@ -0,0 +1,74 @@ +package dynamicProgramming.fibonacci; + +/** + * https://www.youtube.com/watch?v=YcJTyrG3bZs + * https://www.geeksforgeeks.org/count-possible-decodings-given-digit-sequence/ + * + */ +public class DecodeWays { + + public int numDecodings(String s) { + if (s == null || s.length() == 0) { + return 0; + } + int n = s.length(); + int[] dp = new int[n + 1]; + dp[0] = 1; // initialize the base case means an empty string will have one way to decode + dp[1] = s.charAt(0) != '0' ? 1 : 0; // means the way to decode a string of size 1 + for (int i = 2; i <= n; i++) { + int first = Integer.parseInt(s.substring(i - 1, i)); + int second = Integer.parseInt(s.substring(i - 2, i)); + if (first >= 1 && first <= 9) { + dp[i] += dp[i - 1]; + } + if (second >= 10 && second <= 26) { + dp[i] += dp[i - 2]; + } + } + return dp[n]; + } + public int numDecodings1(String s) { + if(s==null|| s.length()==0) return 0; + Integer [] cache= new Integer[s.length()+1]; + return helperFn(s,0,cache); + // cache[s.length()]; + + } + + public int helperFn(String s, int index, Integer[] cache){ + if( index>=s.length()) return 1; + + if(cache[index]!=null) return cache[index]; + int total=0; + if(index+1<=s.length()){ + String temp1= s.substring(index,index+1); + if(valid(temp1)){ + total+=helperFn(s,index+1,cache); + } + } + + if(index+2 <= s.length()){ + String temp2= s.substring(index, index+2); + if(valid(temp2)){ + total+=helperFn(s,index+2,cache); + } + } + + cache[index]=total; + return cache[index]; + + } + + public boolean valid(String s1){ + if(s1.length()==0) return false; + if(s1.charAt(0)=='0') return false; + + int val=Integer.parseInt(s1); + + return val>=1 && val<=26; + } + public static void main(String[] args) { + DecodeWays decode = new DecodeWays(); + System.out.println(decode.numDecodings("1210")); + } +} diff --git a/src/dynamicProgramming/fibonacci/DiceThrow.java b/src/dynamicProgramming/fibonacci/DiceThrow.java new file mode 100644 index 0000000..24d29d9 --- /dev/null +++ b/src/dynamicProgramming/fibonacci/DiceThrow.java @@ -0,0 +1,40 @@ +package dynamicProgramming.fibonacci; + +/** + * Time Complexity: O(m * n * x) + * + */ +class DiceThrow { + // m-> faces + // n->dices + // x->sum + public static long findWays(int m, int n, int x) { + + long[][] T = new long[n + 1][x + 1]; + + for (int j = 1; j <= m && j <= x; j++) + T[1][j] = 1; + + for (int i = 2; i <= n; i++) { + System.out.println("i=" + i); + for (int j = 1; j <= x; j++) { + System.out.println("j =" + j); + for (int k = 1; k < j && k <= m; k++) { + System.out.println("T[" + (i - 1) + "][" + (j - k) + "]"); + T[i][j] += T[i - 1][j - k]; + } + } + } + + for (int i = 0; i < n + 1; i++) { + for (int j = 0; j < x + 1; j++) + System.out.print(T[i][j] + " "); + System.out.println(); + } + return T[n][x]; + } + + public static void main(String[] args) { + System.out.println(findWays(6, 3, 6)); + } +} \ No newline at end of file diff --git a/src/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java b/src/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java new file mode 100644 index 0000000..96ec079 --- /dev/null +++ b/src/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java @@ -0,0 +1,74 @@ +package dynamicProgramming.fibonacci; + +import java.util.Arrays; + +public class FibonacciStaircaseWaysToCoverDist { + + public int fibonacciSeriesRecursive(int n) { + if (n == 1) + return 2; + if (n == 2) + return 3; + return fibonacciSeriesRecursive(n - 1) + fibonacciSeriesRecursive(n - 2); + } + + public static void main(String args[]) { + FibonacciStaircaseWaysToCoverDist fs = new FibonacciStaircaseWaysToCoverDist(); + System.out.println(fs.fibonacciSeries(4)); + System.out.println(fs.fibonacciSeriesRecursive(3)); + } + + public int fibonacciSeries(int n) { + int n1 = 0; + int n2 = 1; + int sum; + + if (n == n1 || n == n2) { + return n; + } + + for (int i = 1; i <= n; i++) { + sum = n1 + n2; + n1 = n2; + n2 = sum; + } + return n2; + } + + public int climbStairs(int N) { + int[] cache= new int[N+1]; + Arrays.fill(cache,-1); + return fibUtil(N,0,cache); + } + + public int fibUtil(int N, int start, int [] cache){ + if(start>N) return 0; + + if(N==start) return 1; + + if(cache[start]!=-1) return cache[start]; + + cache[start]= fibUtil(N,start+1, cache)+fibUtil(N,start+2, cache); + + return cache[start]; + } + + + public int minCostClimbingStairs(int[] cost) { + int res = 0; + //dp[i] = cost[i] + Math.min(dp[i-1], dp[i-2]) + int[] dp = new int[cost.length]; + + dp[0] = Math.min(cost[0], cost[1]); + dp[1] = Math.min(cost[1] + dp[0], cost[1]); + for(int i = 2; i < cost.length; i++){ + dp[i] = cost[i] + Math.min(dp[i-1], dp[i-2]); + } + int n = cost.length; + System.out.println(Arrays.toString(dp)); + return Math.min(dp[n-1], dp[n-2]); + } + +} + + diff --git a/src/dynamicProgramming/lcs/BitonicSequence.java b/src/dynamicProgramming/lcs/BitonicSequence.java new file mode 100644 index 0000000..989f821 --- /dev/null +++ b/src/dynamicProgramming/lcs/BitonicSequence.java @@ -0,0 +1,52 @@ +package dynamicProgramming.lcs; + +/** + * http://www.geeksforgeeks.org/dynamic-programming-set-15-longest-bitonic-subsequence/ + * + */ +public class BitonicSequence { + + public int longestSequence(int arr[]) { + int lis[] = new int[arr.length]; + int lds[] = new int[arr.length]; + for (int i = 0; i < arr.length; i++) { + lis[i] = 1; + lds[i] = 1; + } + for (int i = 1; i < arr.length; i++) { + for (int j = 0; j < i; j++) { + if (arr[i] > arr[j]) { + lis[i] = Math.max(lis[i], lis[j] + 1); + } + } + } + + for (int i = arr.length - 2; i >= 0; i--) { + for (int j = arr.length - 1; j > i; j--) { + if (arr[i] > arr[j]) { + lds[i] = Math.max(lds[i], lds[j] + 1); + } + } + } + // because that middle element is common in both sequence .. for example, + // increasing subsequence 2,8,20 .. decreasing one 20,13,14 .. each of them has + // length 3 .. but bitonic subsequence 2,8,20,13,14 .. length= 3+3-1=5 + int max = 0; + for (int i = 0; i < arr.length; i++) { + System.out.print(lis[i] + lds[i] - 1 + " "); + if (max < lis[i] + lds[i] - 1) { + max = lis[i] + lds[i] - 1; + } + } + System.out.println(); + return max; + } + + public static void main(String args[]) { + BitonicSequence bs = new BitonicSequence(); + int[] arr = { 1, 4, 3, 7, 2, 1, 8, 11, 13, 0 }; + int r = bs.longestSequence(arr); + System.out.println(r); + + } +} \ No newline at end of file diff --git a/src/dynamicProgramming/lcs/EditDistance.java b/src/dynamicProgramming/lcs/EditDistance.java new file mode 100644 index 0000000..c7e4a4f --- /dev/null +++ b/src/dynamicProgramming/lcs/EditDistance.java @@ -0,0 +1,113 @@ +package dynamicProgramming.lcs; + +/** + * Date 07/07/2014 + * + * @author Tushar Roy + * + * Given two strings how many minimum edits(update, delete or add) is + * needed to convert one string to another + * + * Time complexity is O(m*n) Space complexity is O(m*n) + * + * References: + * http://www.geeksforgeeks.org/dynamic-programming-set-5-edit-distance/ + * https://en.wikipedia.org/wiki/Edit_distance + */ +public class EditDistance { + + + /** + * Uses bottom up DP to find the edit distance + */ + public int dynamicEditDistance(char[] str1, char[] str2) { + int temp[][] = new int[str1.length + 1][str2.length + 1]; + + for (int i = 0; i < temp[0].length; i++) { + temp[0][i] = i; // it's number of edits to make top row empty, remember dp[0][0]="" empty char + } + + for (int i = 0; i < temp.length; i++) { + temp[i][0] = i; // it's number of edits to make empty char into first col values, remember dp[0][0]="" empty char + } + + for (int i = 1; i <= str1.length; i++) { + for (int j = 1; j <= str2.length; j++) { + if (str1[i - 1] == str2[j - 1]) { + temp[i][j] = temp[i - 1][j - 1]; + } else { + temp[i][j] = 1 + min(temp[i - 1][j - 1], temp[i - 1][j], temp[i][j - 1]); + } + } + } + printActualEdits(temp, str1, str2); + return temp[str1.length][str2.length]; + + } + + /** + * Prints the actual edits which needs to be done. + */ + public void printActualEdits(int T[][], char[] str1, char[] str2) { + int i = T.length - 1; + int j = T[0].length - 1; + while (true) { + if (i == 0 || j == 0) { + break; + } + if (str1[i - 1] == str2[j - 1]) { + i = i - 1; + j = j - 1; + } else if (T[i][j] == T[i - 1][j - 1] + 1) { + System.out.println("Edit " + str2[j - 1] + " in string2 to " + str1[i - 1] + " in string1"); + i = i - 1; + j = j - 1; + } else if (T[i][j] == T[i - 1][j] + 1) { + System.out.println("Delete in string1 " + str1[i - 1]); + i = i - 1; + } else if (T[i][j] == T[i][j - 1] + 1) { + System.out.println("Delete in string2 " + str2[j - 1]); + j = j - 1; + } else { + throw new IllegalArgumentException("Some wrong with given data"); + } + } + } + + public int minDistance(String word1, String word2) { + if(word1==null) return word2.length(); + if(word2==null) return word1.length(); + + int[][] dp= new int[word1.length()+1][word2.length()+1]; + + for(int i = 0;i<=word1.length();i++) dp[i][0] = i; + for(int j = 0;j<=word2.length();j++) dp[0][j] = j; + + for(int i=1;i<=word1.length();i++){ + for(int j=1; j<= word2.length(); j++){ + if(word1.charAt(i-1)==word2.charAt(j-1)){ + dp[i][j]=dp[i-1][j-1]; + }else{ + dp[i][j]= 1+Math.min(dp[i-1][j-1], Math.min(dp[i-1][j], dp[i][j-1])); + } + } + } + + return dp[word1.length()][word2.length()]; + } + private int min(int a, int b, int c) { + int l = Math.min(a, b); + return Math.min(l, c); + } + + public static void main(String args[]) { + String str1 = "abcd"; + String str2 = "bcad"; + EditDistance editDistance = new EditDistance(); + int result = editDistance.dynamicEditDistance(str1.toCharArray(), str2.toCharArray()); + System.out.print(result); + } + +} + + diff --git a/src/dynamicProgramming/lcs/LongestCommonSubsequence.java b/src/dynamicProgramming/lcs/LongestCommonSubsequence.java new file mode 100644 index 0000000..342382f --- /dev/null +++ b/src/dynamicProgramming/lcs/LongestCommonSubsequence.java @@ -0,0 +1,86 @@ +package dynamicProgramming.lcs; + +public class LongestCommonSubsequence { + + public static void main(String[] args) { + String str1 = "ABCD"; + String str2 = "AEDB"; + + System.out.println(getLCS(str1.toCharArray(), str2.toCharArray())); + + // System.out.println(lcs(str1.toCharArray(), str2.toCharArray(), str1.length(), str2.length())); + } + + private static int getLCS(char[] str1, char[] str2) { + + int temp[][] = new int[str1.length + 1][str2.length + 1]; + int max = 0; + for (int i = 1; i < temp.length; i++) { + for (int j = 1; j < temp[i].length; j++) { + if (str1[i - 1] == str2[j - 1]) { + temp[i][j] = temp[i - 1][j - 1] + 1; + } else { + temp[i][j] = Math.max(temp[i][j - 1], temp[i - 1][j]); + } + if (temp[i][j] > max) { + max = temp[i][j]; + } + } + } + return max; + } + + public int longestCommonSubsequence(String text1, String text2) { + if(text1==null || text2==null) return 0; + + int[][] dp= new int[text1.length()+1][text2.length()+1]; + + for(int i=1;i<=text1.length();i++){ + for(int j=1; j<=text2.length(); j++){ + if(text1.charAt(i-1)==text2.charAt(j-1)){ + dp[i][j]= 1+dp[i-1][j-1]; // previously matched characters + }else{ + dp[i][j]= Math.max(dp[i][j-1],dp[i-1][j]); + } + } + } + + return dp[text1.length()][text2.length()]; + } + + static int lcs(char[] X, char[] Y, int m, int n) { + if (m == 0 || n == 0) + return 0; + if (X[m - 1] == Y[n - 1]) + return 1 + lcs(X, Y, m - 1, n - 1); + else + return Math.max(lcs(X, Y, m, n - 1), lcs(X, Y, m - 1, n)); + } + + public int longestCommonSubsequenceRec(String text1, String text2) { + if(text1==null || text2==null) return 0; + + Integer[][] dp= new Integer[text1.length()+1][text2.length()+1]; + + longestCommonSubsequenceUtil(text1, text1.length(), text2, text2.length(), dp); + + return dp[text1.length()][text2.length()]; + } + + public int longestCommonSubsequenceUtil(String text1,int i, String text2,int j, Integer[][] dp ){ + if(i<=0 || j<=0) return 0; + + if(dp[i][j]!=null) return dp[i][j]; + + if(text1.charAt(i-1)==text2.charAt(j-1)){ + dp[i][j]=1+longestCommonSubsequenceUtil(text1, i-1, text2, j-1, dp); + }else{ + dp[i][j]= Math.max(longestCommonSubsequenceUtil(text1, i, text2, j-1, dp), longestCommonSubsequenceUtil(text1, i-1, text2, j, dp)); + } + + return dp[i][j]; + } + +} + + diff --git a/src/dynamicProgramming/lcs/LongestCommonSubstring.java b/src/dynamicProgramming/lcs/LongestCommonSubstring.java new file mode 100644 index 0000000..245c1bd --- /dev/null +++ b/src/dynamicProgramming/lcs/LongestCommonSubstring.java @@ -0,0 +1,37 @@ +package dynamicProgramming.lcs; + +import java.util.Deque; +import java.util.LinkedList; +import java.util.Queue; + +/** + * http://en.wikipedia.org/wiki/Longest_common_substring_problem + */ +public class LongestCommonSubstring { + + public int longestCommonSubstring(char str1[], char str2[]) { + int T[][] = new int[str1.length + 1][str2.length + 1]; + + int max = 0; + for (int i = 1; i <= str1.length; i++) { + for (int j = 1; j <= str2.length; j++) { + if (str1[i - 1] == str2[j - 1]) { + T[i][j] = T[i - 1][j - 1] + 1; + if (max < T[i][j]) { + max = T[i][j]; + } + } + } + } + + return max; + } + + public static void main(String args[]) { + LongestCommonSubstring lcs = new LongestCommonSubstring(); + char str1[] = "abcdef".toCharArray(); + char str2[] = "zcdemf".toCharArray(); + System.out.println(lcs.longestCommonSubstring(str1, str2)); + } + +} \ No newline at end of file diff --git a/src/dynamicProgramming/lcs/LongestIncreasingSubsequence.java b/src/dynamicProgramming/lcs/LongestIncreasingSubsequence.java new file mode 100644 index 0000000..7379630 --- /dev/null +++ b/src/dynamicProgramming/lcs/LongestIncreasingSubsequence.java @@ -0,0 +1,112 @@ +package dynamicProgramming.lcs; + +import java.util.Arrays; +import java.util.PriorityQueue; + +/** + * Solve the LIS subproblem for each snippet of the array ending between 1, 2, + * 3, ... and so on until nums.length - 1 (inclusive) + * + * Ex: + * + * [-2, 1, 2, 3] + * + * [-2] from index 0 to index 0 [-2, 1] from index 0 to index 1 [-2, 1, 2] from + * index 0 to index 2 [-2, 1, 2, 3] from index 0 to index 3 + * + * Our answer is the maximum LNDS found between all subproblems we solve along + * the way. + * + * Time complexity is O(n^2). + */ +public class LongestIncreasingSubsequence { + + public static void main(String[] args) { + int[] nums = { 10, 22, 9, 33, 21, 50, 41, 60, 80 }; + + + lengthOfLIS(nums); + } + + private static void lisLength(int[] nums) { + int[] result = new int[nums.length]; + Arrays.fill(result, 1); + + int maximumSoFar = 1; + + for (int i = 1; i < nums.length; i++) { + for (int j = 0; j < i; j++) { + if (nums[i] > nums[j]) { + result[i] = Math.max(result[i], result[j] + 1); + } + } + maximumSoFar = Math.max(maximumSoFar, result[i]); + } + System.out.println(maximumSoFar); + } + + public static int findPositionToReplace(int[] a, int low, int high, int x) { + int mid; + while (low <= high) { + mid = low + (high - low) / 2; + if (a[mid] == x) + return mid; + else if (a[mid] > x) + high = mid - 1; + else + low = mid + 1; + } + return low; + } + + public static int lengthOfLIS(int[] nums) { + if (nums == null | nums.length == 0) + return 0; + //Set hash= new HashSet(Arrays.asList(nums)); + int n = nums.length, len = 0; + int[] increasingSequence = new int[n]; + increasingSequence[len++] = nums[0]; + for (int i = 1; i < n; i++) { + if (nums[i] > increasingSequence[len - 1]) + increasingSequence[len++] = nums[i]; + else { + int position = findPositionToReplace(increasingSequence, 0, len - 1, nums[i]); + increasingSequence[position] = nums[i]; + } + } + return len; + } + public int eraseOverlapIntervals(int[][] intervals) { + if(intervals.length==0) return 0; + +// PriorityQueue queue= new PriorityQueue()((a, b)->{ +// if(a[0]==b[0]) return Integer.compare(a[1],b[1]); +// return Integer.compare(a[0],b[0]); +// }); + + PriorityQueue queue = new PriorityQueue((a, b) -> { + if(a[0]==b[0]) return Integer.compare(a[1],b[1]); + return Integer.compare(a[0],b[0]); + }); + + for(int[] interval: intervals){ + queue.offer(interval); + } + int result=0; + int[] temp= queue.poll(); + int start= temp[0]; + int end= temp[1]; + + while(!queue.isEmpty()){ + if(end>queue.peek()[0]) { + result++; + queue.poll(); + }else{ + end=Math.max(end,queue.poll()[1]); + } + } + + return result; + } + +} diff --git a/src/dynamicProgramming/lcs/MaximumContiguousSubarraySum.java b/src/dynamicProgramming/lcs/MaximumContiguousSubarraySum.java new file mode 100644 index 0000000..83170fe --- /dev/null +++ b/src/dynamicProgramming/lcs/MaximumContiguousSubarraySum.java @@ -0,0 +1,28 @@ +package dynamicProgramming.lcs; + +/** + * + * http://tinyurl.com/y4mffrn7 + */ +public class MaximumContiguousSubarraySum { + + public static void main(String[] args) { + int[] arr2 = { -6, 2, -4, 1, 3, -1, 5, -1 }; + MaximumContiguousSubarraySum mcs = new MaximumContiguousSubarraySum(); + System.out.println(mcs.maxSubArray(arr2)); + + } + + public int maxSubArray(int[] nums) { + + int maxSoFar = nums[0]; + int maxEndingHere = nums[0]; + + for (int i = 1; i < nums.length; i++) { + maxEndingHere = Math.max(maxEndingHere + nums[i], nums[i]); + maxSoFar = Math.max(maxSoFar, maxEndingHere); + } + return maxSoFar; + } + +} diff --git a/src/dynamicProgramming/lcs/MaximumProductSubarray.java b/src/dynamicProgramming/lcs/MaximumProductSubarray.java new file mode 100644 index 0000000..87fe425 --- /dev/null +++ b/src/dynamicProgramming/lcs/MaximumProductSubarray.java @@ -0,0 +1,38 @@ +package dynamicProgramming.lcs; + +public class MaximumProductSubarray { + + static int maxSubarrayProduct(int arr[], int n) { + int max_ending_here = 1; + int min_ending_here = 1; + + int max_so_far = 1; + int flag = 0; + for (int i = 0; i < n; i++) { + if (arr[i] > 0) { + max_ending_here = max_ending_here * arr[i]; + min_ending_here = Math.min(min_ending_here * arr[i], 1); + flag = 1; + } else if (arr[i] == 0) { + max_ending_here = 1; + min_ending_here = 1; + } else { + int temp = max_ending_here; + max_ending_here = Math.max(min_ending_here * arr[i], 1); + min_ending_here = temp * arr[i]; + } + if (max_so_far < max_ending_here) + max_so_far = max_ending_here; + } + if (flag == 0 && max_so_far == 1) + return 0; + return max_so_far; + } + + public static void main(String[] args) { + int arr[] = { 1, -2, -3, 0, 8, 7, -2 }; + int n = arr.length; + System.out.println("Maximum Sub array product is " + maxSubarrayProduct(arr, n)); + } + +} diff --git a/src/dynamicProgramming/lcs/MaximumSumIncreasingSubsequence.java b/src/dynamicProgramming/lcs/MaximumSumIncreasingSubsequence.java new file mode 100644 index 0000000..d947a54 --- /dev/null +++ b/src/dynamicProgramming/lcs/MaximumSumIncreasingSubsequence.java @@ -0,0 +1,32 @@ +package dynamicProgramming.lcs; + +class MaximumSumIncreasingSubsequence { + + static int maxSumIS(int arr[], int n) { + int i, j, max = 0; + int msis[] = new int[n]; + + for (i = 0; i < n; i++) + msis[i] = arr[i]; + + for (i = 1; i < n; i++) { + for (j = 0; j < i; j++) { + System.out.println(arr[i] + ">" + arr[j] + "&&" + msis[i] + "<" + (msis[j] + arr[i])); + if (arr[i] > arr[j] && msis[i] < msis[j] + arr[i]) + msis[i] = msis[j] + arr[i]; + } + } + // Pick maximum of all msis values + for (i = 0; i < n; i++) + if (max < msis[i]) + max = msis[i]; + + return max; + } + + public static void main(String args[]) { + int arr[] = new int[] { 1, 1001, 2, 3, 100, 4, 5 }; + int n = arr.length; + System.out.println("Sum of maximum sum " + "increasing subsequence is " + maxSumIS(arr, n)); + } +} \ No newline at end of file diff --git a/src/dynamicProgramming/lcs/TwoStringInterleavingToFormThird.java b/src/dynamicProgramming/lcs/TwoStringInterleavingToFormThird.java new file mode 100644 index 0000000..75e0d18 --- /dev/null +++ b/src/dynamicProgramming/lcs/TwoStringInterleavingToFormThird.java @@ -0,0 +1,45 @@ +package dynamicProgramming.lcs; + +/** + * + * http://www.geeksforgeeks.org/check-whether-a-given-string-is-an-interleaving-of-two-other-given-strings-set-2/ + */ +public class TwoStringInterleavingToFormThird { + + public boolean isInterleaved(char str1[], char str2[], char str3[]) { + boolean T[][] = new boolean[str1.length + 1][str2.length + 1]; + + if (str1.length + str2.length != str3.length) { + return false; + } + + for (int i = 0; i < T.length; i++) { + for (int j = 0; j < T[i].length; j++) { + int l = i + j - 1; + if (i == 0 && j == 0) { + T[0][0] = true; + } else if (i == 0) { + if (str1[j - 1] == str3[l]) { + T[i][j] = T[i][j - 1]; + } + } else if (j == 0) { + if (str2[i - 1] == str3[l]) { + T[i][j] = T[i - 1][j]; + } + } else { + T[i][j] = (str1[i - 1] == str3[l] ? T[i - 1][j] : false) + || (str2[j - 1] == str3[l] ? T[i][j - 1] : false); + } + } + } + return T[str1.length][str2.length]; + } + + public static void main(String args[]) { + String str1 = "aab"; + String str2 = "axy"; + String str3 = "aaxaby"; + TwoStringInterleavingToFormThird sti = new TwoStringInterleavingToFormThird(); + System.out.println(sti.isInterleaved(str1.toCharArray(), str2.toCharArray(), str3.toCharArray())); + } +} diff --git a/src/dynamicProgramming/lcs/WildCardMatching.java b/src/dynamicProgramming/lcs/WildCardMatching.java new file mode 100644 index 0000000..9b78d68 --- /dev/null +++ b/src/dynamicProgramming/lcs/WildCardMatching.java @@ -0,0 +1,85 @@ +package dynamicProgramming.lcs; + +/** + * Date 02/11/2016 + * + * @author Tushar Roy + * + * Reference https://leetcode.com/problems/wildcard-matching/ + */ +public class WildCardMatching { + + public boolean isMatch(String s, String p) { + char[] str = s.toCharArray(); + char[] pattern = p.toCharArray(); + + // replace multiple * with one * + // e.g a**b***c --> a*b*c + int writeIndex = 0; + boolean isFirst = true; + for (int i = 0; i < pattern.length; i++) { + if (pattern[i] == '*') { + if (isFirst) { + pattern[writeIndex++] = pattern[i]; + isFirst = false; + } + } else { + pattern[writeIndex++] = pattern[i]; + isFirst = true; + } + } + boolean[][] T = new boolean[str.length + 1][writeIndex + 1]; + if (writeIndex > 0 && pattern[0] == '*') { + T[0][1] = true; + } + + T[0][0] = true; + for (int i = 1; i < T.length; i++) { + for (int j = 1; j <= writeIndex; j++) { + if (pattern[j - 1] == '?' || str[i - 1] == pattern[j - 1]) { + T[i][j] = T[i - 1][j - 1]; + } else if (pattern[j - 1] == '*') { + T[i][j] = T[i - 1][j] || T[i][j - 1]; + } + } + } + + return T[str.length][writeIndex]; + } + + public boolean isMatchint(String s, String p) { + if(s==null || p==null) return false; + + + boolean[][] dp= new boolean[s.length()+1][p.length()+1]; + + dp[0][0]= true; + + for(int j=1; j<=p.length(); j++) { + if(p.charAt(j-1)=='*'){ + dp[0][j] = true; + } else { + break; + } + } + + for(int i=1; i<=s.length();i++){ + for(int j=1; j<=p.length(); j++){ + if(p.charAt(j-1)=='?' || p.charAt(j-1)==s.charAt(i-1)){ + dp[i][j]=dp[i-1][j-1]; + } + else if(p.charAt(j-1)=='*'){ + dp[i][j]=dp[i-1][j] || dp[i][j-1]; + } + } + } + + return dp[s.length()][p.length()]; + } + + public static void main(String args[]) { + WildCardMatching wcm = new WildCardMatching(); + System.out.println(wcm.isMatch("xbylmz", "x?y***z")); + + } +} \ No newline at end of file diff --git a/src/dynamicProgramming/matrix/MatrixMultiplicationCost.java b/src/dynamicProgramming/matrix/MatrixMultiplicationCost.java new file mode 100644 index 0000000..83ff551 --- /dev/null +++ b/src/dynamicProgramming/matrix/MatrixMultiplicationCost.java @@ -0,0 +1,43 @@ +package dynamicProgramming.matrix; + +/** + * http://www.geeksforgeeks.org/dynamic-programming-set-8-matrix-chain-multiplication/ + * https://www.youtube.com/watch?v=vgLJZMUfnsU&t=316s + */ +public class MatrixMultiplicationCost { + + public int findCost(int arr[]) { + int[][] T = new int[arr.length][arr.length]; + int q = 0; + for (int l = 2; l < arr.length; l++) { + for (int i = 0; i < arr.length - l; i++) { + int j = i + l; + T[i][j] = 1000000; + for (int k = i + 1; k < j; k++) { + System.out.println("T[" + i + "][" + j + "] :: T[" + i + "][" + k + "] * T[" + k + "][" + j + "] *" + + arr[i] + "*" + arr[k] + "*" + arr[j]); + q = T[i][k] + T[k][j] + arr[i] * arr[k] * arr[j]; + if (q < T[i][j]) { + T[i][j] = q; + } + } + } + } + System.out.println(); + for (int i = 0; i < arr.length; i++) { + for (int j = 0; j < arr.length; j++) { + System.out.print(T[i][j] + " "); + } + System.out.println(); + } + + return T[0][arr.length - 1]; + } + + public static void main(String args[]) { + MatrixMultiplicationCost mmc = new MatrixMultiplicationCost(); + int arr[] = { 2, 3, 6, 4, 5 }; + int cost = mmc.findCost(arr); + System.out.print(cost); + } +} \ No newline at end of file diff --git a/src/dynamicProgramming/matrix/MaximumSizeSubMatrix.java b/src/dynamicProgramming/matrix/MaximumSizeSubMatrix.java new file mode 100644 index 0000000..bfcab99 --- /dev/null +++ b/src/dynamicProgramming/matrix/MaximumSizeSubMatrix.java @@ -0,0 +1,57 @@ +package dynamicProgramming.matrix; + +/** + * http://www.geeksforgeeks.org/maximum-size-sub-matrix-with-all-1s-in-a-binary-matrix/ + * + * https://www.youtube.com/watch?v=_Lf1looyJMU&t=2s + */ +public class MaximumSizeSubMatrix { + + private int min(int a, int b, int c) { + int l = Math.min(a, b); + return Math.min(l, c); + } + + public int maxSize(int arr[][]) { + + int result[][] = new int[arr.length][arr[0].length]; + int max = 0; + for (int i = 0; i < arr.length; i++) { + result[i][0] = arr[i][0]; + if (result[i][0] == 1) { + max = 1; + } + } + + for (int i = 0; i < arr[0].length; i++) { + result[0][i] = arr[0][i]; + if (result[0][i] == 1) { + max = 1; + } + + } + + for (int i = 1; i < arr.length; i++) { + for (int j = 1; j < arr[i].length; j++) { + if (arr[i][j] == 0) { + continue; + } + int t = min(result[i - 1][j], result[i - 1][j - 1], result[i][j - 1]); + result[i][j] = t + 1; + if (result[i][j] > max) { + max = result[i][j]; + } + } + } + return max; + } + + public static void main(String args[]) { + + int arr[][] = { { 0, 1, 1, 0, 1 }, { 1, 1, 1, 0, 0 }, { 1, 1, 1, 1, 0 }, { 1, 1, 1, 0, 1 } }; + MaximumSizeSubMatrix mssm = new MaximumSizeSubMatrix(); + int result = mssm.maxSize(arr); + System.out.print(result); + } + +} \ No newline at end of file diff --git a/src/dynamicProgramming/matrix/MinCostPath.java b/src/dynamicProgramming/matrix/MinCostPath.java new file mode 100644 index 0000000..e2c216a --- /dev/null +++ b/src/dynamicProgramming/matrix/MinCostPath.java @@ -0,0 +1,41 @@ +package dynamicProgramming.matrix; + +/** + * http://www.geeksforgeeks.org/dynamic-programming-set-6-min-cost-path/ + */ +public class MinCostPath { + + public int minCost(int[][] cost, int m, int n) { + + int temp[][] = new int[m + 1][n + 1]; + int sum = 0; + for (int i = 0; i <= n; i++) { + temp[0][i] = sum + cost[0][i]; + sum = temp[0][i]; + } + sum = 0; + for (int i = 0; i <= m; i++) { + temp[i][0] = sum + cost[i][0]; + sum = temp[i][0]; + } + + for (int i = 1; i <= m; i++) { + for (int j = 1; j <= n; j++) { + temp[i][j] = cost[i][j] + min(temp[i - 1][j - 1], temp[i - 1][j], temp[i][j - 1]); + } + } + return temp[m][n]; + } + + private int min(int a, int b, int c) { + int l = Math.min(a, b); + return Math.min(l, c); + } + + public static void main(String args[]) { + MinCostPath mcp = new MinCostPath(); + int cost[][] = { { 1, 2, 3 }, { 4, 8, 2 }, { 1, 5, 3 }, { 6, 2, 9 } }; + int result = mcp.minCost(cost, 3, 2); + System.out.println(result); + } +} \ No newline at end of file diff --git a/src/dynamicProgramming/oiknapsack/EqualSubsetSumPartition.java b/src/dynamicProgramming/oiknapsack/EqualSubsetSumPartition.java new file mode 100644 index 0000000..dc26347 --- /dev/null +++ b/src/dynamicProgramming/oiknapsack/EqualSubsetSumPartition.java @@ -0,0 +1,76 @@ +package dynamicProgramming.oiknapsack; + +import java.util.Arrays; + +/** + * https://www.educative.io/collection/page/5668639101419520/5633779737559040/5752754626625536 + * + * Given a non-empty array containing only positive integers, + * find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal. + * + * Input: [1, 5, 11, 5] + * + * Output: true + * + * Explanation: The array can be partitioned as [1, 5, 5] and [11]. + */ +class EqualSubsetSumPartition { + + +// 0 1 2 3 4 5 +// +---+---+---+---+---+---+ +// {1} | T | T | F | F | F | F | +// +---+---+---+---+---+---+ +// {1,2} | T | T | T | T | F | F | +// +---+---+---+---+---+---+ +// {1,2,3} | T | T | T | T | T | T | +// +---+---+---+---+---+---+ +//{1,2,3,4} | T | T | T | T | T | T | +// +---+---+---+---+---+---+ + public boolean canPartition(int[] num) { + int n = num.length; + + int sum = 0; + for (int i = 0; i < n; i++) + sum += num[i]; + + // if sum is odd we cannot divide into 2 parts + if (sum % 2 != 0) + return false; + + sum /= 2; + + boolean[][] dp = new boolean[n][sum + 1]; + + for (int i = 0; i < n; i++) + dp[i][0] = true; + + // with only one number, we can form a subset only when the required sum is + // equal to its value + for (int s = 1; s <= sum; s++) { + System.out.println(num[0] + "-" + s); + dp[0][s] = (num[0] == s ? true : false); + } + + for (int i = 1; i < n; i++) { + for (int j = 1; j <= sum; j++) { + // if we can get the sum 's' without the number at index 'i' + if (dp[i - 1][j]) { + dp[i][j] = dp[i - 1][j]; + } else if (j >= num[i]) { // else if we can find a subset to get the remaining sum + dp[i][j] = dp[i - 1][j - num[i]]; + } + } + } + + System.out.println(Arrays.deepToString(dp)); + + return dp[n - 1][sum]; + } + + public static void main(String[] args) { + EqualSubsetSumPartition ps = new EqualSubsetSumPartition(); + int[] num = { 2, 3, 4, 5 }; + System.out.println(ps.canPartition(num)); + } +} diff --git a/src/dynamicProgramming/oiknapsack/MinPartition.java b/src/dynamicProgramming/oiknapsack/MinPartition.java new file mode 100644 index 0000000..189cc40 --- /dev/null +++ b/src/dynamicProgramming/oiknapsack/MinPartition.java @@ -0,0 +1,46 @@ +package dynamicProgramming.oiknapsack; + +import java.util.HashMap; +import java.util.Map; + +class MinPartition +{ + + public static int minPartition(int[] S, int n, int S1, int S2, + Map lookup) + { + if (n < 0) { + return Math.abs(S1 - S2); + } + + // construct a unique map key from dynamic elements of the input + // Note that can uniquely identify the subproblem with n & S1 only, + // as S2 is nothing but S - S1 where S is sum of all elements + String key = n + "|" + S1; + + // if sub-problem is seen for the first time, solve it and + // store its result in a map + if (!lookup.containsKey(key)) + { + // Case 1. include current item in the subset S1 and recurse + // for remaining items (n - 1) + int inc = minPartition(S, n - 1, S1 + S[n], S2, lookup); + + // Case 2. exclude current item from subset S1 and recurse for + // remaining items (n - 1) + int exc = minPartition(S, n - 1, S1, S2 + S[n], lookup); + + lookup.put(key, Integer.min(inc, exc)); + } + + return lookup.get(key); + } + + public static void main(String[] args) + { + int[] S = { 10, 20, 15, 5, 25 }; + Map lookup = new HashMap<>(); + System.out.println("The minimum difference is " + + minPartition(S, S.length - 1, 0, 0, lookup)); + } +} \ No newline at end of file diff --git a/src/dynamicProgramming/oiknapsack/MinimumSubsetSum.java b/src/dynamicProgramming/oiknapsack/MinimumSubsetSum.java new file mode 100644 index 0000000..afbc06d --- /dev/null +++ b/src/dynamicProgramming/oiknapsack/MinimumSubsetSum.java @@ -0,0 +1,17 @@ +package dynamicProgramming.oiknapsack; + +/** + * Given a set of positive numbers, partition the set into two subsets with minimum difference between their subset sums. + * Input: {1, 2, 3, 9} + * Output: 3 + * Explanation: We can partition the given set into two subsets where minimum absolute difference + * between the sum of numbers is '3'. Following are the two subsets: {1, 2, 3} & {9}. + * + * Input: {1, 3, 100, 4} + * Output: 92 + * Explanation: We can partition the given set into two subsets where minimum absolute difference + * between the sum of numbers is '92'. Here are the two subsets: {1, 3, 4} & {100}. + */ +public class MinimumSubsetSum { + +} diff --git a/src/dynamicProgramming/oiknapsack/NumberOfUniqueWaysToMakeChange.java b/src/dynamicProgramming/oiknapsack/NumberOfUniqueWaysToMakeChange.java new file mode 100644 index 0000000..3c4db76 --- /dev/null +++ b/src/dynamicProgramming/oiknapsack/NumberOfUniqueWaysToMakeChange.java @@ -0,0 +1,34 @@ +package dynamicProgramming.oiknapsack; + +import java.util.Arrays; + +/* + * Java-solution-with-thinking-process-O(nm)-Time-and-O(m)-Space Note: This code + * shows the use of O(mn) space. This problem can be solved using only O(m) + * space. https://www.youtube.com/watch?v=DJ4a7cmjZY0 + */ +public class NumberOfUniqueWaysToMakeChange { + + public int numberOfSolutions(int total, int coins[]) { + int[][] temp = new int[coins.length + 1][total + 1]; + for (int i = 0; i <= coins.length; i++) { + temp[i][0] = 1; + } + for (int i = 1; i <= coins.length; i++) { + for (int j = 1; j <= total; j++) { + if (coins[i - 1] > j) { + temp[i][j] = temp[i - 1][j]; + } else { + temp[i][j] = temp[i][j - coins[i - 1]] + temp[i - 1][j]; + } + } + System.out.println(Arrays.toString(temp[i])); + } + return temp[coins.length][total]; + } + + public static void main(String[] args) { + int[] coins = { 1, 2, 5 }; + System.out.println(new NumberOfUniqueWaysToMakeChange().numberOfSolutions(5, coins)); + } +} diff --git a/src/dynamicProgramming/oiknapsack/O1KnapsackSpaceOptimized.java b/src/dynamicProgramming/oiknapsack/O1KnapsackSpaceOptimized.java new file mode 100644 index 0000000..90633f8 --- /dev/null +++ b/src/dynamicProgramming/oiknapsack/O1KnapsackSpaceOptimized.java @@ -0,0 +1,107 @@ +package dynamicProgramming.oiknapsack; + +class O1KnapsackSpaceOptimized { + + public static void main(String[] args) { + int wt[] = { 2, 3, 4, 5 }; + int val[] = { 1, 2, 4, 6 }; + int W = 7; + int n = 4; + //System.out.println(knapSack(val, wt, n, W)); + } + + public int findProfit(int val[], int wt[], int W) { + int profits[][] = new int[val.length + 1][W + 1]; + for (int i = 0; i <= val.length; i++) { + for (int j = 0; j <= W; j++) { + if (i == 0 || j == 0) { + profits[i][j] = 0; + continue; + } +// So, for each item at index ‘i’ (0 <= i < items.length) and capacity ‘c’ (0 <= c <= capacity), we have two options: +// Include the item at index ‘i’ if its weight is not more than the capacity. +// In this case, we include its profit plus whatever profit we get from the remaining capacity +// and from remaining items => profit[i] + dp[i-1][c-weight[i]] + if (j - wt[i - 1] >= 0) { + profits[i][j] = Math.max(profits[i - 1][j], profits[i - 1][j - wt[i - 1]] + val[i - 1]); + } +// Exclude the item at index ‘i’. +// In this case, we will take whatever profit we get from the sub-array excluding this item => dp[i-1][c] + else { + profits[i][j] = profits[i - 1][j]; + } + } + } + return profits[val.length][W]; + } + +// 1) When we access dp[j], it has not been overridden yet for the current iteration, so it should be fine. +// 2) dp[j-weight[i]] might be overridden if “weight[i] > 0”. Therefore we can’t use this value for the current iteration. + +// To solve the second case, we can change our inner loop to process in the reverse direction: c:capacity-->0. +// This will ensure that whenever we change a value in dp[], we will not need it again in the current iteration. + + public int findProfitSpaceOptimised(int val[], int wt[], int W){ + int profits[] = new int[W + 1]; + // if we have only one weight we take if it's not more than the capacity + for (int c=0; c<=W;c++){ + if(wt[0]= 0; j--){ + int profit1 = 0, profit2=0; + if(wt[i-1]<=j){ + profit1= val[i-1]+profits[j-wt[i-1]]; + } + profit2=profits[j]; + profits[j]= Math.max(profit1,profit2); + } + } + return profits[W]; + } + +// Input: m = 10, A = [2, 3, 5, 7], V = [1, 5, 2, 4] +// Output: 9 +// Explanation: Put A[1] and A[3] into backpack, getting the maximum value V[1] + V[3] = 9 + + public int backPackII(int m, int[] A, int[] V) { + + int[][] dp= new int[A.length+1][m+1]; + + for(int i=1;i<=A.length;i++) { + for (int j = 1; j <= m; j++) { + if (A[i - 1] > m) { + dp[i][j] = dp[i - 1][j]; + } else { + int prevVal = j >= m ? dp[i - 1][j - m] : 0; + dp[i][j] = Math.max(dp[i - 1][j], + V[i - 1] + prevVal); + } + } + } + return dp[A.length][m]; + + } + + public int backPackUnBounded(int m, int[] A) { + if(m==0 || A==null) return 0; + + int[] dp= new int[m+1]; + //dp[0]=0; + + // in 0-1 knapsack we check max with previous row item, here since we can take multiple of + // same item, we can take from same row itself, so only 1-D array + // we take the item A[i]+ we take another item in same row after reducing weight A[i] => dp[j-A[i]] + for(int i=0; i=A[i]; j--){ + + dp[j]= Math.max(dp[j],A[i]+dp[j-A[i]]); + + } + } + + return dp[m]; + } + +} \ No newline at end of file diff --git a/src/dynamicProgramming/oiknapsack/SubsetSumProblem.java b/src/dynamicProgramming/oiknapsack/SubsetSumProblem.java new file mode 100644 index 0000000..ba8b0ad --- /dev/null +++ b/src/dynamicProgramming/oiknapsack/SubsetSumProblem.java @@ -0,0 +1,99 @@ +package dynamicProgramming.oiknapsack; + +import java.util.ArrayList; + +//Given a set of positive numbers, determine if a subset exists whose sum is equal to a given number ‘S’. + +/** + * Input: {1, 2, 3, 7}, S=6 + * Output: True + * The given set has a subset whose sum is '6': {1, 2, 3} + * + * Input: {1, 2, 7, 1, 5}, S=10 + * Output: True + * The given set has a subset whose sum is '10': {1, 2, 7} + */ + +// 0 1 2 3 4 5 6 +// +---+---+---+---+---+---+---+ +// {1} | T | T | F | F | F | F | F | +// +---+---+---+---+---+---+---+ +// {1,2} | T | T | T | T | F | F | F | +// +---+---+---+---+---+---+---+ +// {1,2,3} | T | T | T | T | T | T | T | +// +---+---+---+---+---+---+---+ +// {1,2,3,7} | T | T | T | T | T | T | T | +// +---+---+---+---+---+---+---+ +public class SubsetSumProblem { + + static boolean[][] dp; + + static void printAllSubsets(int arr[], int n, int sum) { + if (n == 0 || sum < 0) + return; + + dp = new boolean[n][sum + 1]; + for (int i = 0; i < n; ++i) { + dp[i][0] = true; + } + + if (arr[0] <= sum) + dp[0][arr[0]] = true; + + for (int i = 1; i < n; ++i) { + for (int j = 0; j <= sum; j++) { + if (arr[i] <= j) { + dp[i][j] = (dp[i - 1][j] || dp[i - 1][j - arr[i]]); + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + if (dp[n - 1][sum] == false) { + System.out.println("There are no subsets with" + " sum " + sum); + return; + } + + ArrayList p = new ArrayList<>(); + } + + public boolean canPartition(int[] nums) { + if(nums==null || nums.length==0) return false; + + int sum=0; + for(int i: nums){ + sum+=i; + } + // odd numbers cannot be partitioned + if ((sum & 1) == 1) { + return false; + } + sum/=2; // checking for half of the the sum + boolean[][] dp= new boolean[nums.length+1][sum+1]; + + for(int i=0; i<=nums.length;i++){ + dp[i][0]= true; // first index of all rows are true because 0 is present in 0,0 + } + for(int i=1;i<=nums.length; i++){ + for(int j=1; j<=sum;j++){ + + if(nums[i-1]>j){ + dp[i][j]= dp[i-1][j]; + }else{ + dp[i][j]= (dp[i - 1][j] || dp[i-1][j-nums[i-1]]); + } + } + } + + + + return dp[nums.length][sum]; + } + + public static void main(String args[]) { + int arr[] = { 2, 3, 5, 8, 10 }; + int n = arr.length; + int sum = 10; + printAllSubsets(arr, n, sum); + } +} \ No newline at end of file diff --git a/src/dynamicProgramming/palindrome/LongestPalindromicSubsequence.java b/src/dynamicProgramming/palindrome/LongestPalindromicSubsequence.java new file mode 100644 index 0000000..aed5311 --- /dev/null +++ b/src/dynamicProgramming/palindrome/LongestPalindromicSubsequence.java @@ -0,0 +1,87 @@ +package dynamicProgramming.palindrome; + +/** + * Date 08/01/2014 + * + * @author Tushar Roy + * + * Time complexity - O(n2) Space complexity - O(n2) + * + * Youtube link - https://youtu.be/_nCsPn7_OgI + * + * References + * http://www.geeksforgeeks.org/dynamic-programming-set-12-longest-palindromic-subsequence/ + */ +public class LongestPalindromicSubsequence { + + public int calculate1(char[] str) { + int T[][] = new int[str.length][str.length]; + for (int i = 0; i < str.length; i++) { + T[i][i] = 1; + } + for (int l = 2; l <= str.length; l++) { + for (int i = 0; i < str.length - l + 1; i++) { + int j = i + l - 1; + if (l == 2 && str[i] == str[j]) { + T[i][j] = 2; + } else if (str[i] == str[j]) { + T[i][j] = T[i + 1][j - 1] + 2; + } else { + T[i][j] = Math.max(T[i + 1][j], T[i][j - 1]); + } + } + } + return T[0][str.length - 1]; + } + + public int longestPalindromeSubseq(String s) { + char[] chars = s.toCharArray(); + int n = s.length(); + int[][] dp = new int[n][n]; + for (int i = n - 1; i >= 0; i--) { + dp[i][i] = 1; + for (int j = i + 1; j < n; ++j) { + if (chars[i] == chars[j]) { + dp[i][j] = dp[i + 1][j - 1] + 2; + } else { + dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]); + } + } + } + for (int i=0; i j) return 0; + if (i == j) return 1; + + if (s.charAt(i) == s.charAt(j)) { + memo[i][j] = helper(s, i + 1, j - 1, memo) + 2; + } else { + memo[i][j] = Math.max(helper(s, i + 1, j, memo), helper(s, i, j - 1, memo)); + } + return memo[i][j]; + } + + public static void main(String args[]) { + LongestPalindromicSubsequence lps = new LongestPalindromicSubsequence(); + String str = "agbdba"; + int r2 = lps.longestPalindromeSubseq(str); + System.out.print(r2); + } + +} \ No newline at end of file diff --git a/src/dynamicProgramming/palindrome/LongestPalindromicSubstring.java b/src/dynamicProgramming/palindrome/LongestPalindromicSubstring.java new file mode 100644 index 0000000..1901e8e --- /dev/null +++ b/src/dynamicProgramming/palindrome/LongestPalindromicSubstring.java @@ -0,0 +1,40 @@ +package dynamicProgramming.palindrome; + +/** + * https://leetcode.com/problems/longest-palindromic-substring/ + */ +public class LongestPalindromicSubstring { + + // leetcode solution + private static int lo, maxLen; + + public static String longestPalindrome(String s) { + int len = s.length(); + if (len < 2) + return s; + // odd length ababc => here we start j and k at same position say index 2 and go left and right + // even length cbbd=> here let's say we're at index 1, we need to take 1 and 2 index to check for palindrome + // the above cases are the reason for sending i and i+1 + for (int i = 0; i < len - 1; i++) { + extendPalindrome(s, i, i); //assume odd length, try to extend Palindrome as possible + extendPalindrome(s, i, i + 1); //assume even length. + } + return s.substring(lo, lo + maxLen); + } + + private static void extendPalindrome(String s, int j, int k) { + while (j >= 0 && k < s.length() && s.charAt(j) == s.charAt(k)) { + j--; + k++; + } + if (maxLen < k - j - 1) { + lo = j + 1; + maxLen = k - j - 1; + } + } + + public static void main(String args[]) { + + System.out.println(longestPalindrome("bananas")); + } +} \ No newline at end of file diff --git a/src/dynamicProgramming/unboundedknapsack/CoinChangingMinimumCoin.java b/src/dynamicProgramming/unboundedknapsack/CoinChangingMinimumCoin.java new file mode 100644 index 0000000..c202ed4 --- /dev/null +++ b/src/dynamicProgramming/unboundedknapsack/CoinChangingMinimumCoin.java @@ -0,0 +1,65 @@ +package dynamicProgramming.unboundedknapsack; + +import java.util.Arrays; + +/** + * + * + * Time complexity - O(coins.size * total) Space complexity - O(coins.size * + * total) + * + * https://www.youtube.com/watch?v=NJuKJ8sasGk&t=324s + */ +public class CoinChangingMinimumCoin { + + public int minimumCoinBottomUp(int total, int coins[]) { + // where we calculate results + int T[] = new int[total + 1]; + // to extract combination + int R[] = new int[total + 1]; + T[0] = 0; + for (int i = 1; i <= total; i++) { + T[i] = Integer.MAX_VALUE - 1; + R[i] = -1; + } + for (int j = 0; j < coins.length; j++) { + for (int i = 1; i <= total; i++) { + if (i >= coins[j]) { + if (T[i - coins[j]] + 1 < T[i]) { + T[i] = 1 + T[i - coins[j]]; + R[i] = j; + } + } + } + } + System.out.println(Arrays.toString(T)); + System.out.println(Arrays.toString(R)); + printCoinCombination(R, coins); + return T[total]; + } + + private void printCoinCombination(int R[], int coins[]) { + if (R[R.length - 1] == -1) { + System.out.print("No solution is possible"); + return; + } + int start = R.length - 1; + System.out.print("Coins used to form total "); + while (start != 0) { + int j = R[start]; + System.out.print(coins[j] + " "); + start = start - coins[j]; + } + System.out.print("\n"); + } + + public static void main(String args[]) { + int total = 11; + int coins[] = { 1, 5, 6, 8 }; + CoinChangingMinimumCoin cc = new CoinChangingMinimumCoin(); + int bottomUpValue = cc.minimumCoinBottomUp(total, coins); + + System.out.print(bottomUpValue); + + } +} \ No newline at end of file diff --git a/src/dynamicProgramming/unboundedknapsack/CuttingRod.java b/src/dynamicProgramming/unboundedknapsack/CuttingRod.java new file mode 100644 index 0000000..f01377d --- /dev/null +++ b/src/dynamicProgramming/unboundedknapsack/CuttingRod.java @@ -0,0 +1,31 @@ +package dynamicProgramming.unboundedknapsack; + +import java.util.Arrays; + +/** + * http://www.geeksforgeeks.org/dynamic-programming-set-13-cutting-a-rod/ + */ +public class CuttingRod { + + public int maxValue(int price[]) { + int[] max = new int[price.length + 1]; // 2-D is not needed beacuse no include exclude is considered + int n = price.length; + // i is no.of.cuts + // price is value + for (int i = 1; i <= n; i++) { // starting at i + for (int j = i; j <= n; j++) { // traverses from i->n every time + System.out.println("max[" + j + "] : " + max[j] + " , max[" + (j - i) + "] : " + max[j - i] + + "+ price[" + (i - 1) + "] : " + price[i - 1]); + max[j] = Math.max(max[j], max[j - i] + price[i - 1]); + System.out.println(Arrays.toString(max)); + } + } + return max[price.length]; + } + + public static void main(String args[]) { + CuttingRod cr = new CuttingRod(); + int[] price = { 1, 5, 3, 6 }; + System.out.println(cr.maxValue(price)); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/FenwickTree.java b/src/geeksforgeeks/FenwickTree.java new file mode 100644 index 0000000..f67b1fe --- /dev/null +++ b/src/geeksforgeeks/FenwickTree.java @@ -0,0 +1,112 @@ +package geeksforgeeks; + +/** + * https://codeforces.com/blog/entry/61364 + * + * Fenwick trees are binary indexed trees, when asked for a range queries for an array + * ex [1,3,4,1,2] print the sum for range (0,4), (1,2) etc.. sum, difference, product, division can be asked + * one way is to pre-compute the prefix sums like [1,4,8,9,11] + * when asked for sum between 0 to 4 return 9 + * when asked sum between 2 to 4 we can return sum of (0,1) - (0,4) + * the retrival is O(1), but if the original array is updated we need to compute + * the prefix sum which will take O(N). + * Fenwick tree solves this by making both get and update as O(log n) + */ +public class FenwickTree{ + + // the array size is always incremented by 1, because the first entry is + // a dummy entry, the trees are arranges in set bits of each array's index + // we consider 4 pos of the bit representation + /** + * for array [1,-7,15,9,4,2,0,10] + * 0=> [0/0000] (index/ bit val of index) + * / | \ \ + * 1=> [1/0001] [2/0010] [4/0100] [8/1000] + * / / \ + * 2=> [3/0011] [5/0101] [6/0110] + * / + * 3=> [7/0111] + * + * so from the above tree we can infer that to get to a parent node, we need to + * remove the right most set bit + * [7/0111] => [6/0110]=> [4/0100]=> [0/0000] + * and the formula for that is parent = i - (i & -i); + * + * before populating fenwick tree with values, calculate the prefix sum for the array + * [1,-7,15,9,4,2,0,10]=> [1,-6,9,18,22,24,24,34] and update in it's posistion in fenwick tree + * + * [0/0000] + * / | \ \ + * [1/0001] [-6/0010] [18/0100] [34/1000] + * / / \ + * [9/0011] [22/0101] [24/0110] + * / + * [24/0111] + * the we need to subract each cell's value to it's immediate parent's value, then the tree would look like + * we can use the above formula parent = i - (i & -i); + * + * [0/0000] + * / | \ \ + * [1/0001] [-6/0010] [18/0100] [34/1000] + * / / \ + * [15/0011] [4/0101] [6/0110] + * / + * [0/0111] + * in array's representation it'd look like + * [0,1,-6,15,18,4,6,0,34] + */ + + int[] fen; int[] arr; + int n; + public NumArray(int[] nums) { + arr = nums; + n = nums.length; + fen = new int[n+1]; + init(); + } + + public void init(){ + if(n == 0) return; + + fen[1] = arr[0]; + for(int i = 1; i < n; i++){ + fen[i+1] = fen[i] + arr[i]; + } + for(int i = n; i >0 ; i--){ + int parent = i - (i & -i); + if(parent >= 0) fen[i] -= fen[parent]; + } + //System.out.println(Arrays.toString(fen)); + } + + + + // for update we need to come from parent to children + // to get children do opposite of i-(i&-i) + public void update(int i, int val) { + int extra = val - arr[i]; + arr[i] = val; + increment(i, extra); + } + + public int sum(int i){ + int res = 0; + while(i > 0){ + res += fen[i]; + i = i - (i & -i); + } + return res; + } + public void increment(int i, int val){ + i++; + while(i <= n){ + fen[i] += val; + i = i + (i & -i); + } + } + //sum(1,4)=> sum(0,4)-(0,1) the sum function will calculate from 4->0(parent) + public int sumRange(int i, int j) { + return sum(j+1) - sum(i); + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/InsertIntervals.java b/src/geeksforgeeks/InsertIntervals.java new file mode 100644 index 0000000..091396d --- /dev/null +++ b/src/geeksforgeeks/InsertIntervals.java @@ -0,0 +1,33 @@ +package geeksforgeeks; + +/** + * Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). + + You may assume that the intervals were initially sorted according to their start times. + Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] + Output: [[1,2],[3,10],[12,16]] + Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10]. + */ +public class InsertIntervals{ + public int[][] insert(int[][] intervals, int[] newInterval) { + List result= new ArrayList<>(); + int i=0; int n= intervals.length; + + while(i [c*p0 + d*p1+ e*p2] + * hash(cde)= hash(R)-hash(L-1)/P^L R= Right, L=Left + * + * Hash[3,6]= (Hash(6)- Hash(2)/ p^3)%M + * + * hash([L...R]) =(hash[R] - hash[L - 1]/PL)% M + hash(s[L...R]) =(hash[R] - hash[L - 1]) * P^-L % M + + hash(s[L...R]) =(hash[R] - hash[L - 1])*(P^-1)L % M + hash(s[L...R]) =(hash[R] - hash[L - 1])% M*(P-1)L %M% M + + (A * B) % M =( (A % M) * (B % M)) % M + X = P^-1= P^M-2% M + hash(s[L...R]) =(((hash[R] - hash[L - 1])% M *X^L )% M) + */ + + + public static void main(String[] args) { + String givenValue = "abaaab"; + String input = "aaa"; + +// char[] givenArr = givenValue.toCharArray(); +// char[] inputArr = input.toCharArray(); +// +// int inputHash = createHash(inputArr, inputArr.length); +// int previousValue = 0; +// for (int i = 0; i < (givenArr.length - inputArr.length + 1); i++) { +// previousValue = givenHash(givenArr, i, previousValue); +// if (inputHash == previousValue && matchString(inputArr, givenArr, i)) { +// System.out.println("It exists"); +// } +// } + + rabinKarp(givenValue, input); + } + + private static int givenHash(char[] givenArr, int i, int previousValue) { + + if (previousValue == 0) { + return createHash(givenArr, 3); + } + + int currentValue = previousValue - givenArr[i - 1]; + System.out.println(currentValue + givenArr[i + 2] * 100); + return currentValue + givenArr[i + 2] * 100; + + } + + private static int createHash(char[] inputArr, int length) { + int hash = 0; + double power = 0; + for (int i = 0; i < length; i++) { + hash = hash + (int) Math.pow(10, power++) * inputArr[i]; + } + return hash; + } + + private static boolean matchString(char[] inputArr, char[] givenArr, int i) { + int index = 0; + for (int j = i; j < inputArr.length; j++) { + if (inputArr[index++] != givenArr[j]) { + return false; + } + } + return true; + } + + //the time complexity is O(m + n) + public static int rabinKarp(String t, String s) { + if (s.length() > t.length()) { + return -1; // s is not a substring of t. + } + final int BASE = 26; + int tHash = 0, sHash = 0; // Hash codes for the substring of t and s. + int powerS = 1; // this will be used to calculate the rolling hash when current window moves out + for (int i = 0; i < s.length(); i++) { + powerS = i > 0 ? powerS * BASE : 1; + tHash = tHash * BASE + t.charAt(i); + sHash = sHash * BASE + s.charAt(i); + } + for (int i = s.length(); i < t.length(); i++) { +// Checks the two substrings are actually equal or not, to protect +// against hash collision. + if (tHash == sHash ){ //&& t.substring(i - s.length(), i).equals(s)) { + return i - s.length(); // Found a match. + } +// Uses rolling hash to compute the new hash code. + tHash -= t.charAt(i - s.length()) * powerS; + tHash = tHash * BASE + t.charAt(i); + } +// Tries to match s and t.substring(t.length() - s.lengthO). + if (tHash == sHash){ // && t .substring(t.length() - s.length()).equals(s)){ + return t.length() - s.length(); + } + return -1; + } +} \ No newline at end of file diff --git a/src/graph/CombinationsAndPermutations/Combinations.java b/src/graph/CombinationsAndPermutations/Combinations.java new file mode 100644 index 0000000..6cae079 --- /dev/null +++ b/src/graph/CombinationsAndPermutations/Combinations.java @@ -0,0 +1,67 @@ +package CombinationsAndPermutations; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class Combinations { + + public List> combinationSum(int[] candidates, int target) { + if(candidates==null || candidates.length==0) return Collections.emptyList(); + List> result= new ArrayList<>(); + + combinationSumUtil(candidates, target, result, new ArrayList<>(), 0); + + return result; + + } + + public void combinationSumUtil(int[] candidates, int target, List> result, List tempList, int start ){ + if(target<0) return; + if(target==0){ + result.add(new ArrayList(tempList)); + + } + + for(int i=start; i> combinationSum2(int[] candidates, int target) { + if(candidates==null || candidates.length==0) return Collections.emptyList(); + List> result= new ArrayList<>(); + Arrays.sort(candidates); + combinationSumUtil1(candidates, target, result, new ArrayList<>(), 0); + + return result; + } + + public void combinationSumUtil1(int[] candidates, int target, List> result, List tempList, int start){ + if(target<0) return; + + if(target==0){ + result.add(new ArrayList<>(tempList)); + return; + } + + for(int i=start; i cur means cand[i - 1] is not added to the path (you should know why if you understand the algorithm), so if cand[i] == cand[i-1], then we shouldn't add cand[i]. +// +// This tricky is very smart. + if(i>start && candidates[i]==candidates[i-1]) continue; + if (target - candidates[i] < 0) break; + tempList.add(candidates[i]); + combinationSumUtil1(candidates, target-candidates[i], result, tempList, i+1); + tempList.remove(tempList.size()-1); + } + } +} diff --git a/src/graph/CombinationsAndPermutations/Permutations.java b/src/graph/CombinationsAndPermutations/Permutations.java new file mode 100644 index 0000000..bd906b4 --- /dev/null +++ b/src/graph/CombinationsAndPermutations/Permutations.java @@ -0,0 +1,63 @@ +package CombinationsAndPermutations; + +import java.util.*; + +public class Permutations { + + public List> permute(int[] nums) { + if(nums==null || nums.length==0) return Collections.emptyList(); + List> result= new ArrayList<>(); + permuteUtils(nums, result, new ArrayList<>()); + + return result; + } + + public void permuteUtils(int[] nums, List> result, List tempList){ + + if(tempList.size()==nums.length){ + result.add(new ArrayList(tempList)); + return; + } + + for(int i=0; i> permuteUnique(int[] nums) { + List> list = new ArrayList<>(); + Arrays.sort(nums); + backtrack(list, new ArrayList<>(), nums, new boolean[nums.length]); + return list; + } + + private void backtrack(List> list, List tempList, int [] nums, boolean [] used){ + if(tempList.size() == nums.length){ + list.add(new ArrayList<>(tempList)); + } else{ + for(int i = 0; i < nums.length; i++){ + //[1, 1, 2][1, 2, 1][2, 1, 1] + //[1, 2, 3][1, 3, 2][2, 1, 3][2, 3, 1][3, 1, 2][3, 2, 1] + if(used[i] || i > 0 && nums[i] == nums[i-1] && !used[i - 1]) continue; + used[i] = true; + tempList.add(nums[i]); + backtrack(list, tempList, nums, used); + used[i] = false; + tempList.remove(tempList.size() - 1); + } + } + } + +} + + diff --git a/src/graph/CombinationsAndPermutations/SubSets.java b/src/graph/CombinationsAndPermutations/SubSets.java new file mode 100644 index 0000000..160c74f --- /dev/null +++ b/src/graph/CombinationsAndPermutations/SubSets.java @@ -0,0 +1,67 @@ +package CombinationsAndPermutations; + +import java.util.*; + +public class SubSets { + + public List> subsets(int[] nums) { + if(nums==null || nums.length==0) return Collections.emptyList(); + + List> result= new ArrayList<>(); + subSetGenerationUtil(nums, result, new ArrayList<>(), 0); + return result; + } + + public void subSetGenerationUtil(int[] nums, List> result, List tempList, int start){ + + result.add(new ArrayList<>(tempList)); + + for(int i=start;i> subsetsWithDup(int[] nums) { + if(nums==null || nums.length==0) return Collections.emptyList(); + + List> result= new ArrayList<>(); + Arrays.sort(nums); + //subsetsWithDupUtil(nums, result, new ArrayList<>(), 0); + dfs(nums,0,result, new ArrayList<>()); + return result; + } + + public void subsetsWithDupUtil(int[] nums, List> result, List tempList, int start){ + result.add(new ArrayList<>(tempList)); + + for(int i=start; istart && nums[i]==nums[i-1]) continue; + tempList.add(nums[i]); + subsetsWithDupUtil(nums, result, tempList, i+1); + tempList.remove(tempList.size()-1); + } + } + + private void dfs(int[] nums, int index, List> res, List curr){ + res.add(new ArrayList<>(curr)); + if(index == nums.length){ + return; + } + Set visited = new HashSet(); + for(int i = index; i < nums.length; i++){ + if(visited.add(nums[i])){ + curr.add(nums[i]); + dfs(nums, i + 1, res, curr); + curr.remove(curr.size() - 1); + } + } + } + + public static void main(String[] args) { + new SubSets().subsetsWithDup(new int[]{1,1,2,4}); + } +} + diff --git a/src/graph/adjacencyList/AdjacencyList.java b/src/graph/adjacencyList/AdjacencyList.java new file mode 100644 index 0000000..fad66ff --- /dev/null +++ b/src/graph/adjacencyList/AdjacencyList.java @@ -0,0 +1,47 @@ + +package adjacencyList; + +import java.util.LinkedList; +import java.util.List; + +public class AdjacencyList { + + public static void main(String[] args) { + List adjListArray[] = new LinkedList[5]; + AdjacencyList list = new AdjacencyList(); + list.add(1, 3, adjListArray); + list.add(1, 2, adjListArray); + list.add(2, 3, adjListArray); + list.add(3, 4, adjListArray); + list.add(4, 2, adjListArray); + list.add(5, 4, adjListArray); + + list.printList(adjListArray); + } + + private void printList(List[] adjListArray) { + for (int i = 0; i < adjListArray.length; i++) { + List list = adjListArray[i]; + System.out.print((i + 1) + "-->"); + boolean firstTime = true; + for (Integer val : list) { + if (!firstTime) + System.out.print(" - "); + else + firstTime = false; + System.out.print(val); + } + System.out.println(); + } + } + + private void add(int src, int dest, List[] adjListArray) { + int val = src - 1; + List list = adjListArray[val]; + if (null == list) + list = new LinkedList(); + list.add(dest); + adjListArray[val] = list; + } + +} diff --git a/src/graph/adjacencyMatrix/AdjacencyMatrix.java b/src/graph/adjacencyMatrix/AdjacencyMatrix.java new file mode 100644 index 0000000..e2fe366 --- /dev/null +++ b/src/graph/adjacencyMatrix/AdjacencyMatrix.java @@ -0,0 +1,42 @@ +package adjacencyMatrix; + +public class AdjacencyMatrix { + + public static void main(String[] args) { + AdjacencyMatrix am = new AdjacencyMatrix(); + + int[][] arr = new int[5][5]; + am.add(1, 2, arr); + am.add(1, 5, arr); + am.add(1, 4, arr); + am.add(3, 2, arr); + am.add(5, 2, arr); + am.add(3, 4, arr); + am.add(4, 5, arr); + + am.printMatrix(arr); + am.removeLink(3, 4, arr); + System.out.println("*******"); + am.printMatrix(arr); + + } + + private void removeLink(int i, int j, int[][] arr) { + arr[i - 1][j - 1] = 0; + } + + private void printMatrix(int[][] arr) { + for (int i = 0; i < arr.length; i++) { + for (int j = 0; j < arr.length; j++) { + System.out.print(arr[i][j] + " "); + } + System.out.println(); + } + + } + + private void add(int i, int j, int[][] arr) { + arr[i - 1][j - 1] = 1; + } + +} diff --git a/src/graph/bellmanFord/BellmanFord.java b/src/graph/bellmanFord/BellmanFord.java new file mode 100644 index 0000000..9dd9e04 --- /dev/null +++ b/src/graph/bellmanFord/BellmanFord.java @@ -0,0 +1,56 @@ +package bellmanFord; + +import java.util.HashMap; +import java.util.Map; + +public class BellmanFord { + + private static int INFINITY = 10000000; + + public static void main(String[] args) { + Graph graph = new Graph(); + graph.addEdges(0, 1, 4); + graph.addEdges(0, 2, 5); + graph.addEdges(0, 3, 8); + graph.addEdges(1, 2, -3); + graph.addEdges(2, 4, 4); + graph.addEdges(3, 4, 2); + graph.addEdges(4, 3, 1); + + BellmanFord bf = new BellmanFord(); + Vertex startVertex = graph.vertexMap.values().iterator().next(); + bf.shortestPath(graph, startVertex); + } + + private void shortestPath(Graph graph, Vertex startVertex) { + Map, Integer> distance = new HashMap<>(); + Map, Vertex> parent = new HashMap<>(); + + for (Vertex vertex : graph.vertexMap.values()) { + distance.put(vertex, BellmanFord.INFINITY); + parent.put(vertex, null); + } + distance.put(startVertex, 0); + + for (int i = 0; i < graph.vertexMap.size() - 1; i++) { + for (Edge edge : graph.allEdges) { + int j = distance.get(edge.u) + edge.weight; + if (j < distance.get(edge.v)) { + distance.put(edge.v, j); + parent.put(edge.v, edge.u); + } + } + } + + for (Edge edge : graph.allEdges) { + int j = distance.get(edge.u) + edge.weight; + if (j < distance.get(edge.v)) { + throw new NegativeException(); + } + } + for (Map.Entry, Integer> map : distance.entrySet()) { + System.out.println(map.getKey().key + "-->" + map.getValue()); + } + } + +} diff --git a/src/graph/bellmanFord/Edge.java b/src/graph/bellmanFord/Edge.java new file mode 100644 index 0000000..ed56b0c --- /dev/null +++ b/src/graph/bellmanFord/Edge.java @@ -0,0 +1,15 @@ +package bellmanFord; + +public class Edge { + + Vertex u; + Vertex v; + int weight; + + public Edge(Vertex u, Vertex v, int weight) { + this.u = u; + this.v = v; + this.weight = weight; + } + +} diff --git a/src/graph/bellmanFord/Graph.java b/src/graph/bellmanFord/Graph.java new file mode 100644 index 0000000..290696f --- /dev/null +++ b/src/graph/bellmanFord/Graph.java @@ -0,0 +1,35 @@ +package bellmanFord; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class Graph { + + HashMap> vertexMap = new HashMap>(); + List> allEdges = new ArrayList>(); + + public void addEdges(T u, T v, int weight) { + Vertex vertex1 = null; + if (vertexMap.containsKey(u)) { + vertex1 = vertexMap.get(u); + } else { + vertex1 = new Vertex(u); + vertexMap.put(u, vertex1); + } + + Vertex vertex2 = null; + if (vertexMap.containsKey(v)) { + vertex2 = vertexMap.get(v); + } else { + vertex2 = new Vertex(v); + vertexMap.put(v, vertex2); + } + + Edge edge = new Edge(vertex1, vertex2, weight); + allEdges.add(edge); + + vertex1.addAdjacentVertex(vertex2, edge); + } + +} diff --git a/src/graph/bellmanFord/NegativeException.java b/src/graph/bellmanFord/NegativeException.java new file mode 100644 index 0000000..fc27bc0 --- /dev/null +++ b/src/graph/bellmanFord/NegativeException.java @@ -0,0 +1,10 @@ +package bellmanFord; + +public class NegativeException extends RuntimeException { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/src/graph/bellmanFord/Vertex.java b/src/graph/bellmanFord/Vertex.java new file mode 100644 index 0000000..c1c5bba --- /dev/null +++ b/src/graph/bellmanFord/Vertex.java @@ -0,0 +1,20 @@ +package bellmanFord; + +import java.util.ArrayList; +import java.util.List; + +class Vertex { + T key; + List> adjacentVertex = new ArrayList>(); + List> edges = new ArrayList>(); + + public Vertex(T key) { + this.key = key; + } + + public void addAdjacentVertex(Vertex vertex2, Edge edge) { + adjacentVertex.add(vertex2); + edges.add(edge); + } + +} \ No newline at end of file diff --git a/src/graph/breadthFirstSearch/BreadthFirstSearch.java b/src/graph/breadthFirstSearch/BreadthFirstSearch.java new file mode 100644 index 0000000..7dbe19f --- /dev/null +++ b/src/graph/breadthFirstSearch/BreadthFirstSearch.java @@ -0,0 +1,53 @@ +package breadthFirstSearch; + +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +public class BreadthFirstSearch { + + public static void main(String[] args) { + BreadthFirstSearch bfs = new BreadthFirstSearch(); + Graph graph = new Graph(5); + bfs.addEdges(1, 2, graph); + bfs.addEdges(2, 3, graph); + bfs.addEdges(3, 4, graph); + bfs.addEdges(4, 5, graph); + bfs.addEdges(2, 4, graph); + bfs.addEdges(1, 5, graph); + + bfs.print(1, graph); + + } + + private void print(int i, Graph graph) { + Queue queue = new LinkedList(); + queue.add(i); + Queue clone = new LinkedList(queue); + exploreVertex(queue, clone, graph); + + for (Integer val : clone) { + System.out.print(val + 1 + "->"); + } + } + + private void exploreVertex(Queue queue, Queue clone, Graph graph) { + while (!queue.isEmpty()) { + Integer poll = queue.poll(); + List list = graph.adjacentList[poll]; + for (Integer value : list) { + if (!clone.contains(value)) { + clone.add(value); + queue.add(value); + } + } + } + } + + private void addEdges(int src, int dest, Graph graph) { + int srcVal = src - 1; + int destVal = dest - 1; + graph.adjacentList[srcVal].add(destVal); + graph.adjacentList[destVal].add(srcVal); + } +} diff --git a/src/graph/breadthFirstSearch/Graph.java b/src/graph/breadthFirstSearch/Graph.java new file mode 100644 index 0000000..42fb580 --- /dev/null +++ b/src/graph/breadthFirstSearch/Graph.java @@ -0,0 +1,18 @@ +package breadthFirstSearch; + +import java.util.LinkedList; +import java.util.List; + +public class Graph { + + List adjacentList[]; + int vertices; + + public Graph(int v) { + vertices = v; + adjacentList = new LinkedList[vertices]; + for (int i = 0; i < adjacentList.length; i++) { + adjacentList[i] = new LinkedList<>(); + } + } +} diff --git a/src/graph/cycle/CycleInDirectedGraph.java b/src/graph/cycle/CycleInDirectedGraph.java new file mode 100644 index 0000000..ae11824 --- /dev/null +++ b/src/graph/cycle/CycleInDirectedGraph.java @@ -0,0 +1,67 @@ +package cycle; + +import java.util.HashSet; +import java.util.Set; + +/** + * http://www.geeksforgeeks.org/detect-cycle-in-a-graph/ + */ +public class CycleInDirectedGraph { + + public boolean hasCycle(Graph graph) { + Set> whiteSet = new HashSet<>(); + Set> graySet = new HashSet<>(); + Set> blackSet = new HashSet<>(); + + graph.getAllVertex().forEach(vertex -> whiteSet.add(vertex)); + + while (whiteSet.size() > 0) { + Vertex current = whiteSet.iterator().next(); + if (dfs(current, whiteSet, graySet, blackSet)) { + return true; + } + } + return false; + } + + private boolean dfs(Vertex current, Set> whiteSet, Set> graySet, + Set> blackSet) { + // move current to gray set from white set and then explore it. + moveVertex(current, whiteSet, graySet); + for (Vertex neighbor : current.getAdjacentVertexes()) { + // if in black set means already explored so continue. + if (blackSet.contains(neighbor)) { + continue; + } + // if in gray set then cycle found. + if (graySet.contains(neighbor)) { + return true; + } + if (dfs(neighbor, whiteSet, graySet, blackSet)) { + return true; + } + } + // move vertex from gray set to black set when done exploring. + moveVertex(current, graySet, blackSet); + return false; + } + + private void moveVertex(Vertex vertex, Set> sourceSet, + Set> destinationSet) { + sourceSet.remove(vertex); + destinationSet.add(vertex); + } + + public static void main(String args[]) { + Graph graph = new Graph<>(true); + graph.addEdge(1, 2); + graph.addEdge(1, 3); + graph.addEdge(2, 3); + graph.addEdge(4, 1); + graph.addEdge(4, 5); + graph.addEdge(5, 6); + graph.addEdge(6, 4); + CycleInDirectedGraph cdg = new CycleInDirectedGraph(); + System.out.println(cdg.hasCycle(graph)); + } +} \ No newline at end of file diff --git a/src/graph/cycle/CycleUndirectedGraph.java b/src/graph/cycle/CycleUndirectedGraph.java new file mode 100644 index 0000000..f1e5482 --- /dev/null +++ b/src/graph/cycle/CycleUndirectedGraph.java @@ -0,0 +1,90 @@ +package cycle; + +import java.util.HashSet; +import java.util.Set; + +import kruskalAlgorithm.DisjointSet; + +/** + * Date 10/11/2014 + * + * @author Tushar Roy + * + * Given an undirected graph find cycle in this graph. + * + * Solution This can be solved in many ways. Below is the code to solve + * it using disjoint sets and DFS. + * + * Runtime and space complexity for both the techniques is O(v) where v + * is total number of vertices in the graph. + */ +public class CycleUndirectedGraph { + + public boolean hasCycleUsingDisjointSets(Graph graph) { + DisjointSet disjointSet = new DisjointSet(); + + for (Vertex vertex : graph.getAllVertex()) { + disjointSet.makeSet(vertex.getId()); + } + + for (Edge edge : graph.getAllEdges()) { + long parent1 = disjointSet.findSet(edge.getVertex1().getId()); + long parent2 = disjointSet.findSet(edge.getVertex2().getId()); + if (parent1 == parent2) { + return true; + } + disjointSet.union(edge.getVertex1().getId(), edge.getVertex2().getId()); + } + return false; + } + + public boolean hasCycleDFS(Graph graph) { + Set> visited = new HashSet>(); + for (Vertex vertex : graph.getAllVertex()) { + if (visited.contains(vertex)) { + continue; + } + boolean flag = hasCycleDFSUtil(vertex, visited, null); + if (flag) { + return true; + } + } + return false; + } + + public boolean hasCycleDFSUtil(Vertex vertex, Set> visited, Vertex parent) { + visited.add(vertex); + for (Vertex adj : vertex.getAdjacentVertexes()) { + if (!adj.equals(parent)) { + + if (visited.contains(adj)) { + return true; + } + boolean hasCycle = hasCycleDFSUtil(adj, visited, vertex); + if (hasCycle) { + return true; + } + } + } + return false; + } + + public static void main(String args[]) { + + CycleUndirectedGraph cycle = new CycleUndirectedGraph(); + Graph graph = new Graph(false); + + graph.addEdge(0, 1); + graph.addEdge(1, 2); + graph.addEdge(0, 3); + graph.addEdge(3, 4); + graph.addEdge(4, 5); + graph.addEdge(5, 1); + boolean isCycle = cycle.hasCycleDFS(graph); + System.out.println(isCycle); + isCycle = cycle.hasCycleUsingDisjointSets(graph); + System.out.print(isCycle); + + } + +} \ No newline at end of file diff --git a/src/graph/cycle/Graph.java b/src/graph/cycle/Graph.java new file mode 100644 index 0000000..fc145fa --- /dev/null +++ b/src/graph/cycle/Graph.java @@ -0,0 +1,240 @@ +package cycle; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Graph { + + private List> allEdges; + private Map> allVertex; + boolean isDirected = false; + + public Graph(boolean isDirected) { + allEdges = new ArrayList>(); + allVertex = new HashMap>(); + this.isDirected = isDirected; + } + + public void addEdge(long id1, long id2) { + addEdge(id1, id2, 0); + } + + public void addVertex(Vertex vertex) { + if (allVertex.containsKey(vertex.getId())) { + return; + } + allVertex.put(vertex.getId(), vertex); + for (Edge edge : vertex.getEdges()) { + allEdges.add(edge); + } + } + + public Vertex addSingleVertex(long id) { + if (allVertex.containsKey(id)) { + return allVertex.get(id); + } + Vertex v = new Vertex(id); + allVertex.put(id, v); + return v; + } + + public Vertex getVertex(long id) { + return allVertex.get(id); + } + + public void addEdge(long id1, long id2, int weight) { + Vertex vertex1 = null; + if (allVertex.containsKey(id1)) { + vertex1 = allVertex.get(id1); + } else { + vertex1 = new Vertex(id1); + allVertex.put(id1, vertex1); + } + Vertex vertex2 = null; + if (allVertex.containsKey(id2)) { + vertex2 = allVertex.get(id2); + } else { + vertex2 = new Vertex(id2); + allVertex.put(id2, vertex2); + } + + Edge edge = new Edge(vertex1, vertex2, isDirected, weight); + allEdges.add(edge); + vertex1.addAdjacentVertex(edge, vertex2); + if (!isDirected) { + vertex2.addAdjacentVertex(edge, vertex1); + } + } + + public List> getAllEdges() { + return allEdges; + } + + public Collection> getAllVertex() { + return allVertex.values(); + } + + public void setDataForVertex(long id, T data) { + if (allVertex.containsKey(id)) { + Vertex vertex = allVertex.get(id); + vertex.setData(data); + } + } + + @Override + public String toString() { + StringBuffer buffer = new StringBuffer(); + for (Edge edge : getAllEdges()) { + buffer.append(edge.getVertex1() + " " + edge.getVertex2() + " " + edge.getWeight()); + buffer.append("\n"); + } + return buffer.toString(); + } +} + +class Vertex { + long id; + private T data; + private List> edges = new ArrayList<>(); + private List> adjacentVertex = new ArrayList<>(); + + Vertex(long id) { + this.id = id; + } + + public long getId() { + return id; + } + + public void setData(T data) { + this.data = data; + } + + public T getData() { + return data; + } + + public void addAdjacentVertex(Edge e, Vertex v) { + edges.add(e); + adjacentVertex.add(v); + } + + public String toString() { + return String.valueOf(id); + } + + public List> getAdjacentVertexes() { + return adjacentVertex; + } + + public List> getEdges() { + return edges; + } + + public int getDegree() { + return edges.size(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (int) (id ^ (id >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Vertex other = (Vertex) obj; + if (id != other.id) + return false; + return true; + } +} + +class Edge { + private boolean isDirected = false; + private Vertex vertex1; + private Vertex vertex2; + private int weight; + + Edge(Vertex vertex1, Vertex vertex2) { + this.vertex1 = vertex1; + this.vertex2 = vertex2; + } + + Edge(Vertex vertex1, Vertex vertex2, boolean isDirected, int weight) { + this.vertex1 = vertex1; + this.vertex2 = vertex2; + this.weight = weight; + this.isDirected = isDirected; + } + + Edge(Vertex vertex1, Vertex vertex2, boolean isDirected) { + this.vertex1 = vertex1; + this.vertex2 = vertex2; + this.isDirected = isDirected; + } + + Vertex getVertex1() { + return vertex1; + } + + Vertex getVertex2() { + return vertex2; + } + + int getWeight() { + return weight; + } + + public boolean isDirected() { + return isDirected; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((vertex1 == null) ? 0 : vertex1.hashCode()); + result = prime * result + ((vertex2 == null) ? 0 : vertex2.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Edge other = (Edge) obj; + if (vertex1 == null) { + if (other.vertex1 != null) + return false; + } else if (!vertex1.equals(other.vertex1)) + return false; + if (vertex2 == null) { + if (other.vertex2 != null) + return false; + } else if (!vertex2.equals(other.vertex2)) + return false; + return true; + } + + @Override + public String toString() { + return "Edge [isDirected=" + isDirected + ", vertex1=" + vertex1 + ", vertex2=" + vertex2 + ", weight=" + weight + + "]"; + } +} diff --git a/src/graph/depthFirstSearch/DepthFirstSearch.java b/src/graph/depthFirstSearch/DepthFirstSearch.java new file mode 100644 index 0000000..7a19c1a --- /dev/null +++ b/src/graph/depthFirstSearch/DepthFirstSearch.java @@ -0,0 +1,55 @@ +package depthFirstSearch; + +import java.util.LinkedList; +import java.util.Stack; + +public class DepthFirstSearch { + + public static void main(String[] args) { + DepthFirstSearch dfs = new DepthFirstSearch(); + Graph graph = new Graph(); + + dfs.addEdges('A', 'B', graph); + dfs.addEdges('C', 'B', graph); + dfs.addEdges('C', 'D', graph); + dfs.addEdges('D', 'E', graph); + dfs.addEdges('A', 'E', graph); + dfs.addEdges('D', 'B', graph); + + dfs.print(graph, 'B'); + } + + private void addEdges(char src, char dest, Graph graph) { + checkAndAdd(src, dest, graph); + checkAndAdd(dest, src, graph); + } + + private void checkAndAdd(char src, char dest, Graph graph) { + graph.adjacentMap.getOrDefault(src,new LinkedList<>()).add(dest); + + } + + private void print(Graph graph, Character src) { + Stack stack = new Stack(); + stack.push(src); + LinkedList list = new LinkedList(); + list.add(src); + + while (!stack.isEmpty()) { + Character pop = stack.pop(); + LinkedList linkedList = graph.adjacentMap.get(pop); + if (!linkedList.isEmpty()) { + Character removeFirst = linkedList.removeFirst(); + stack.push(removeFirst); + if (!list.contains(removeFirst)) + list.add(removeFirst); + } + } + + for (Character ch : list) { + System.out.println(ch); + } + + } + +} diff --git a/src/graph/depthFirstSearch/Graph.java b/src/graph/depthFirstSearch/Graph.java new file mode 100644 index 0000000..0cd0017 --- /dev/null +++ b/src/graph/depthFirstSearch/Graph.java @@ -0,0 +1,14 @@ +package depthFirstSearch; + +import java.util.HashMap; +import java.util.LinkedList; + +public class Graph { + + HashMap> adjacentMap; + + public Graph() { + adjacentMap = new HashMap>(); + } + +} diff --git a/src/graph/dijkstraAlgorithm/BinaryHeap.java b/src/graph/dijkstraAlgorithm/BinaryHeap.java new file mode 100644 index 0000000..754da5e --- /dev/null +++ b/src/graph/dijkstraAlgorithm/BinaryHeap.java @@ -0,0 +1,125 @@ +package dijkstraAlgorithm; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class BinaryHeap { + + List allNodes = new ArrayList(); + Map positionMap = new HashMap(); + + class Node { + long key; + int weight; + + public Node(long key, int weight) { + this.key = key; + this.weight = weight; + } + + @Override + public String toString() { + return this.key + " " + this.weight; + } + + } + + protected Node extractMin() { + BinaryHeap.Node node = allNodes.get(0); + int size = allNodes.size() - 1; + allNodes.set(0, allNodes.get(size)); + positionMap.remove(node.key); + positionMap.put(allNodes.get(size).key, 0); + allNodes.remove(size); + + int currentPosition = 0; + int left = 1; + int right = 2; + + if (size > 1) { + Node currentNode = allNodes.get(0); + Node leftNode = null; + Node rightNode = null; + + if (left < size) { + leftNode = allNodes.get(left); + } + if (right < size) { + rightNode = allNodes.get(right); + } + int smallValuePosition = ((rightNode != null) && (rightNode.weight < leftNode.weight)) ? right : left; + + BinaryHeap.Node parentNode = allNodes.get(smallValuePosition); + swapNodes(currentPosition, currentNode, smallValuePosition, parentNode); + updatePositionMap(currentPosition, smallValuePosition, currentNode.key, parentNode.key); + + left = 2 * smallValuePosition + 1; + right = 2 * smallValuePosition + 2; + currentNode = allNodes.get(smallValuePosition); + } + return node; + } + + protected void addNode(int i, long key) { + Node node = new Node(key, i); + allNodes.add(node); + int currentPosition = allNodes.size() - 1; + int parentPosition = (currentPosition - 1) / 2; + + positionMap.put(key, currentPosition); + + BinaryHeap.Node parentNode = allNodes.get(parentPosition); + BinaryHeap.Node currentNode = allNodes.get(currentPosition); + while (parentNode.weight > currentNode.weight) { + swapNodes(currentPosition, currentNode, parentPosition, parentNode); + updatePositionMap(currentPosition, parentPosition, currentNode.key, parentNode.key); + + currentPosition = parentPosition; + parentPosition = (currentPosition - 1) / 2; + + currentNode = allNodes.get(currentPosition); + parentNode = allNodes.get(parentPosition); + } + } + + private void updatePositionMap(int currentPosition, int parentPosition, long current, long parent) { + positionMap.put(current, parentPosition); + positionMap.put(parent, currentPosition); + } + + private void swapNodes(int currentPosition, BinaryHeap.Node currentNode, int parentPosition, + BinaryHeap.Node parentNode) { + allNodes.set(currentPosition, parentNode); + allNodes.set(parentPosition, currentNode); + } + + public void decrease(long vertex, int i) { + + Integer position = positionMap.get(vertex); + allNodes.get(position).weight = i; + + int parent = (position - 1) / 2; + + while (parent >= 0) { + if (allNodes.get(parent).weight > allNodes.get(position).weight) { + swapNodes(position, allNodes.get(position), parent, allNodes.get(parent)); + updatePositionMap(position, parent, allNodes.get(parent).key, allNodes.get(position).key); + position = parent; + parent = (parent - 1) / 2; + } else { + break; + } + } + + } + + public boolean isEmpty() { + return allNodes.size() == 0; + } + + public boolean containsData(Vertex adjacentVertex) { + return positionMap.containsKey(adjacentVertex.key); + } +} diff --git a/src/graph/dijkstraAlgorithm/DijkstraAlgorithm.java b/src/graph/dijkstraAlgorithm/DijkstraAlgorithm.java new file mode 100644 index 0000000..f929185 --- /dev/null +++ b/src/graph/dijkstraAlgorithm/DijkstraAlgorithm.java @@ -0,0 +1,64 @@ +package dijkstraAlgorithm; + +import java.util.HashMap; +import java.util.List; + +public class DijkstraAlgorithm { + + public static void main(String[] args) { + Graph graph = new Graph(); + graph.addEdge(1, 2, 5); + graph.addEdge(1, 5, 2); + graph.addEdge(1, 4, 9); + graph.addEdge(2, 3, 2); + graph.addEdge(3, 4, 3); + graph.addEdge(4, 6, 2); + graph.addEdge(5, 6, 3); + + DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(); + dijkstra.singleSourceShortestPath(graph); + } + + private void singleSourceShortestPath(Graph graph) { + BinaryHeap heap = new BinaryHeap(); + HashMap distanceMap = new HashMap(); + HashMap parentMap = new HashMap(); + + Vertex vertex = graph.vertexMap.get((long) 1); + + for (Vertex ver : graph.vertexMap.values()) { + heap.addNode(Integer.MAX_VALUE, ver.key); + } + heap.decrease(vertex.key, 0); + distanceMap.put(vertex, 0); + while (!heap.isEmpty()) { + long currentKey = heap.extractMin().key; + Vertex currentVertex = graph.vertexMap.get(currentKey); + + System.out.println(currentVertex.key); + List allEdges = currentVertex.allEdges; + + for (Edge edge : allEdges) { + Vertex adjacentVertex = getAdjacentVertex(currentVertex, edge); + if (heap.containsData(adjacentVertex)) { + int weight = 0; + if (distanceMap.containsKey(adjacentVertex)) { + weight = distanceMap.get(adjacentVertex); + } + weight = edge.weight + weight; + if (heap.allNodes.get(heap.positionMap.get(adjacentVertex.key)).weight > weight) { + heap.decrease(adjacentVertex.key, weight); + parentMap.put(adjacentVertex, currentVertex); + distanceMap.put(adjacentVertex, weight); + } + } + } + } + } + + private Vertex getAdjacentVertex(Vertex currentVertex, Edge edge) { + return edge.vertex1.key == currentVertex.key ? edge.vertex2 : edge.vertex1; + + } + +} diff --git a/src/graph/dijkstraAlgorithm/Graph.java b/src/graph/dijkstraAlgorithm/Graph.java new file mode 100644 index 0000000..50c804d --- /dev/null +++ b/src/graph/dijkstraAlgorithm/Graph.java @@ -0,0 +1,72 @@ +package dijkstraAlgorithm; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Graph { + + Map vertexMap = new HashMap(); + List allEdges = new ArrayList(); + + public void addEdge(long v1, long v2, int weight) { + Vertex vertex1 = null; + if (vertexMap.containsKey(v1)) { + vertex1 = vertexMap.get(v1); + } else { + vertex1 = new Vertex(v1); + vertexMap.put(v1, vertex1); + } + + Vertex vertex2 = null; + if (vertexMap.containsKey(v2)) { + vertex2 = vertexMap.get(v2); + } else { + vertex2 = new Vertex(v2); + vertexMap.put(v2, vertex2); + } + + Edge edge = new Edge(vertex1, vertex2, weight); + allEdges.add(edge); + vertex1.adjacentVertexAndEdge(vertex2, edge); + vertex2.adjacentVertexAndEdge(vertex1, edge); + } +} + +class Vertex { + long key; + List adjacentVertex = new ArrayList(); + List allEdges = new ArrayList(); + + public Vertex(long key) { + this.key = key; + } + + public void adjacentVertexAndEdge(Vertex vertex, Edge edge) { + allEdges.add(edge); + adjacentVertex.add(vertex); + } + + @Override + public String toString() { + return this.key + ""; + } +} + +class Edge { + Vertex vertex1; + Vertex vertex2; + int weight; + + public Edge(Vertex vertex1, Vertex vertex2, int weight) { + this.vertex1 = vertex1; + this.vertex2 = vertex2; + this.weight = weight; + } + + @Override + public String toString() { + return this.vertex1 + "-->" + this.vertex2; + } +} \ No newline at end of file diff --git a/src/graph/disjoints/DisjointSetArrayImplementation.java b/src/graph/disjoints/DisjointSetArrayImplementation.java new file mode 100644 index 0000000..ef0a53b --- /dev/null +++ b/src/graph/disjoints/DisjointSetArrayImplementation.java @@ -0,0 +1,42 @@ +package com.disjoints; + +public class DisjointSetArrayImplementation { + + static int[] arr = { -1, -1, -1, -1, -1, -1, -1, -1 }; + + public static void main(String[] args) { + DisjointSetArrayImplementation dsai = new DisjointSetArrayImplementation(); + + dsai.unionSet(0, 1); + dsai.unionSet(2, 3); + dsai.unionSet(4, 5); + dsai.unionSet(6, 7); + dsai.unionSet(1, 3); + dsai.unionSet(5, 6); + dsai.unionSet(1, 4); + dsai.unionSet(0, 2); + + for (int i = 0; i < arr.length; i++) { + System.out.print(arr[i] + " "); + } + } + + + private void unionSet(int src, int dest) { + src = findParent(src); + dest = findParent(dest); + if (src >= 0 && src == dest) { + System.out.println("found cycle"); + } + arr[src] = arr[src] - Math.abs(arr[dest]); + arr[dest] = src; + } + + private int findParent(int src) { + + if (arr[src] < 0) { + return src; + } + return findParent(arr[src]); + } +} diff --git a/src/graph/disjoints/DisjointSetWithNode.java b/src/graph/disjoints/DisjointSetWithNode.java new file mode 100644 index 0000000..5c2fe4c --- /dev/null +++ b/src/graph/disjoints/DisjointSetWithNode.java @@ -0,0 +1,61 @@ +package com.disjoints; + +import java.util.HashMap; +import java.util.Map; + +public class DisjointSetWithNode { + + Map map = new HashMap(); + + public class Node { + int rank; + Node parent; + int data; + } + + private void makeSet(int data) { + Node node = new Node(); + node.data = data; + node.parent = node; + map.put(data, node); + } + + private void unionSet(int src, int dest) { + Node srcNode = findSet(src); + Node destNode = findSet(dest); + + if (srcNode.rank >= destNode.rank) { + srcNode.rank = srcNode.rank + (destNode.rank == 0 ? 1 : destNode.rank); + destNode.parent = srcNode; + } else { + srcNode.parent = destNode; + } + } + + private Node findSet(int src) { + Node node = map.get(src); + + if (node == node.parent) + return node; + + return findSet(node.parent.data); + } + + public static void main(String[] args) { + DisjointSetWithNode ds = new DisjointSetWithNode(); + ds.makeSet(1); + ds.makeSet(2); + ds.makeSet(3); + ds.makeSet(4); + ds.makeSet(5); + ds.makeSet(6); + ds.makeSet(7); + + ds.unionSet(1, 2); + ds.unionSet(3, 4); + ds.unionSet(2, 3); + + System.out.println(ds.findSet(4).data); + + } +} diff --git a/src/graph/disjoints/PredatorDisjointSet.java b/src/graph/disjoints/PredatorDisjointSet.java new file mode 100644 index 0000000..7f56cf6 --- /dev/null +++ b/src/graph/disjoints/PredatorDisjointSet.java @@ -0,0 +1,53 @@ +package com.disjoints; + +import java.util.ArrayList; +import java.util.List; + +public class PredatorDisjointSet { + + public static int minimumGroups(List predators) { + int[] arr = new int[predators.size()]; + int index = 0; + int result = 0; + for (Integer val : predators) { + if (val == -1) { + arr[index] = 0; + } else { + result = makeSet(val, arr, result); + arr[index] = result; + } + index++; + } + return 0; + } + + public static int makeSet(int val, int[] arr, int result) { + int parent = findParent(val, arr); + if (parent == 0) { + return result + 1; + } + return result; + } + + public static int findParent(int val, int[] arr) { + if (val == 0) { + return 0; + } + return findParent(arr[val], arr); + } + + public static void main(String[] args) { + List list = new ArrayList(); + list.add(-1); + list.add(8); + list.add(6); + list.add(0); + list.add(7); + list.add(3); + list.add(8); + list.add(9); + list.add(-1); + list.add(6); + minimumGroups(list); + } +} diff --git a/src/graph/floydwarshall/FloydWarshall.java b/src/graph/floydwarshall/FloydWarshall.java new file mode 100644 index 0000000..ea3ac1f --- /dev/null +++ b/src/graph/floydwarshall/FloydWarshall.java @@ -0,0 +1,29 @@ + package floydwarshall; + +public class FloydWarshall { + + private static int INF = 100000; + + public static void main(String[] args) { + int[][] graph = { { 0, 3, INF, 7 }, { 8, 0, 2, INF }, { 5, INF, 0, 1 }, { 2, INF, INF, 0 } }; + FloydWarshall floyd = new FloydWarshall(); + floyd.shortestPath(graph); + } + + private void shortestPath(int[][] graph) { + for (int k = 0; k < graph.length; k++) { + for (int i = 0; i < graph.length; i++) { + for (int j = 0; j < graph[i].length; j++) { + if (i != k && j != k && i != j) { + if (graph[i][j] > graph[i][k] + graph[k][j]) { + graph[i][j] = graph[i][k] + graph[k][j]; + } + } + System.out.print(graph[i][j] + " "); + } + System.out.println(); + } + System.out.println(); + } + } +} diff --git a/src/graph/interview/DisjointSet.java b/src/graph/interview/DisjointSet.java new file mode 100644 index 0000000..f3639f1 --- /dev/null +++ b/src/graph/interview/DisjointSet.java @@ -0,0 +1,178 @@ +package com.interview; + +import java.util.HashMap; +import java.util.Map; + +public class DisjointSet { + + private Map map = new HashMap<>(); + + class Node { + long data; + Node parent; + int rank; + } + + /** + * Create a set with only one element. + */ + public void makeSet(long data) { + Node node = new Node(); + node.data = data; + node.parent = node; + node.rank = 0; + map.put(data, node); + } + + /** + * Combines two sets together to one. Does union by rank + * + * @return true if data1 and data2 are in different set before union else false. + */ + public boolean union(long data1, long data2) { + Node node1 = map.get(data1); + Node node2 = map.get(data2); + + Node parent1 = findParent(node1); + Node parent2 = findParent(node2); + + // if they are part of same set do nothing + if (parent1.data == parent2.data) { + return false; + } + + // else whoever's rank is higher becomes parent of other + if (parent1.rank >= parent2.rank) { + // increment rank only if both sets have same rank + parent1.rank = (parent1.rank == parent2.rank) ? parent1.rank + 1 : parent1.rank; + parent2.parent = parent1; + } else { + parent1.parent = parent2; + } + return true; + } + + /** + * Finds the representative of this set + */ + public long findParent(long data) { + return findParent(map.get(data)).data; + } + + /** + * Find the representative recursively and does path compression as well. + */ + private Node findParent(Node node) { + Node parent = node.parent; + if (parent == node) { + return parent; + } + node.parent = findParent(node.parent); + return node.parent; + } + + public static void main(String args[]) { + DisjointSet ds = new DisjointSet(); + ds.makeSet(1); + ds.makeSet(2); + ds.makeSet(3); + ds.makeSet(4); + ds.makeSet(5); + ds.makeSet(6); + ds.makeSet(7); + + ds.union(1, 2); + ds.union(2, 3); + ds.union(4, 5); + ds.union(6, 7); + ds.union(5, 6); + ds.union(3, 7); + + System.out.println(ds.findParent(1)); + System.out.println(ds.findParent(2)); + System.out.println(ds.findParent(3)); + System.out.println(ds.findParent(4)); + System.out.println(ds.findParent(5)); + System.out.println(ds.findParent(6)); + System.out.println(ds.findParent(7)); + } + + +} + + class DisjointSetLeetcode { + + private int[] parent; + private byte[] rank; + + public DisjointSetLeetcode(int n) { + if (n < 0) throw new IllegalArgumentException(); + parent = new int[n]; + rank = new byte[n]; + } + + public int find(int x) { + if (parent[x] == 0) return x; + return parent[x] = find(parent[x]); // Path compression by halving. + } + + // Return false if x, y are connected. + public boolean union(int x, int y) { + int rootX = find(x); + int rootY = find(y); + if (rootX == rootY) return false; + + // Make root of smaller rank point to root of larger rank. + if (rank[rootX] < rank[rootY]) parent[rootX] = rootY; + else if (rank[rootX] > rank[rootY]) parent[rootY] = rootX; + else { + parent[rootX] = rootY; + rank[rootY]++; + } + + return true; + } + } + +class UnionFind { + int[] sets; + int[] size; + int count; + + public UnionFind(int n) { + sets = new int[n]; + size = new int[n]; + count = n; + + for (int i = 0; i < n; i++) { + sets[i] = i; + size[i] = 1; + } + } + + public int find(int node) { + while (node != sets[node]) { + node = sets[node]; + } + return node; + } + + public void union(int i, int j) { + int node1 = find(i); + int node2 = find(j); + + if (node1 == node2) { + return; + } + + if (size[node1] < size[node2]) { + sets[node1] = node2; + size[node2] += size[node1]; + } + else { + sets[node2] = node1; + size[node1] += size[node2]; + } + --count; + } +} \ No newline at end of file diff --git a/src/graph/kruskalAlgorithm/DisjointSet.java b/src/graph/kruskalAlgorithm/DisjointSet.java new file mode 100644 index 0000000..8e5aaac --- /dev/null +++ b/src/graph/kruskalAlgorithm/DisjointSet.java @@ -0,0 +1,81 @@ +package kruskalAlgorithm; + +import java.util.HashMap; +import java.util.Map; + +public class DisjointSet { + + private Map map = new HashMap<>(); + + class Node { + long data; + Node parent; + int rank; + } + + public void makeSet(long data) { + Node node = new Node(); + node.data = data; + node.parent = node; + node.rank = 0; + map.put(data, node); + } + + public boolean union(long data1, long data2) { + Node node1 = map.get(data1); + Node node2 = map.get(data2); + + Node parent1 = findSet(node1); + Node parent2 = findSet(node2); + + if (parent1.data == parent2.data) { + return false; + } + + if (parent1.rank >= parent2.rank) { + parent1.rank = (parent1.rank == parent2.rank) ? parent1.rank + 1 : parent1.rank; + parent2.parent = parent1; + } else { + parent1.parent = parent2; + } + return true; + } + + public long findSet(long data) { + return findSet(map.get(data)).data; + } + + private Node findSet(Node node) { + Node parent = node.parent; + if (parent == node) { + return parent; + } + return findSet(node.parent); + } + + public static void main(String args[]) { + DisjointSet ds = new DisjointSet(); + ds.makeSet(1); + ds.makeSet(2); + ds.makeSet(3); + ds.makeSet(4); + ds.makeSet(5); + ds.makeSet(6); + ds.makeSet(7); + + ds.union(1, 2); + ds.union(2, 3); + ds.union(4, 5); + ds.union(6, 7); + ds.union(5, 6); + ds.union(3, 7); + + System.out.println(ds.findSet(1)); + System.out.println(ds.findSet(2)); + System.out.println(ds.findSet(3)); + System.out.println(ds.findSet(4)); + System.out.println(ds.findSet(5)); + System.out.println(ds.findSet(6)); + System.out.println(ds.findSet(7)); + } +} \ No newline at end of file diff --git a/src/graph/kruskalAlgorithm/Graph.java b/src/graph/kruskalAlgorithm/Graph.java new file mode 100644 index 0000000..7197f7b --- /dev/null +++ b/src/graph/kruskalAlgorithm/Graph.java @@ -0,0 +1,240 @@ +package kruskalAlgorithm; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Graph { + + private List> allEdges; + private Map> allVertex; + boolean isDirected = false; + + public Graph(boolean isDirected) { + allEdges = new ArrayList>(); + allVertex = new HashMap>(); + this.isDirected = isDirected; + } + + public void addEdge(long id1, long id2) { + addEdge(id1, id2, 0); + } + + public void addVertex(Vertex vertex) { + if (allVertex.containsKey(vertex.getId())) { + return; + } + allVertex.put(vertex.getId(), vertex); + for (Edge edge : vertex.getEdges()) { + allEdges.add(edge); + } + } + + public Vertex addSingleVertex(long id) { + if (allVertex.containsKey(id)) { + return allVertex.get(id); + } + Vertex v = new Vertex(id); + allVertex.put(id, v); + return v; + } + + public Vertex getVertex(long id) { + return allVertex.get(id); + } + + public void addEdge(long id1, long id2, int weight) { + Vertex vertex1 = null; + if (allVertex.containsKey(id1)) { + vertex1 = allVertex.get(id1); + } else { + vertex1 = new Vertex(id1); + allVertex.put(id1, vertex1); + } + Vertex vertex2 = null; + if (allVertex.containsKey(id2)) { + vertex2 = allVertex.get(id2); + } else { + vertex2 = new Vertex(id2); + allVertex.put(id2, vertex2); + } + + Edge edge = new Edge(vertex1, vertex2, isDirected, weight); + allEdges.add(edge); + vertex1.addAdjacentVertex(edge, vertex2); + if (!isDirected) { + vertex2.addAdjacentVertex(edge, vertex1); + } + } + + public List> getAllEdges() { + return allEdges; + } + + public Collection> getAllVertex() { + return allVertex.values(); + } + + public void setDataForVertex(long id, T data) { + if (allVertex.containsKey(id)) { + Vertex vertex = allVertex.get(id); + vertex.setData(data); + } + } + + @Override + public String toString() { + StringBuffer buffer = new StringBuffer(); + for (Edge edge : getAllEdges()) { + buffer.append(edge.getVertex1() + " " + edge.getVertex2() + " " + edge.getWeight()); + buffer.append("\n"); + } + return buffer.toString(); + } +} + +class Vertex { + long id; + private T data; + private List> edges = new ArrayList<>(); + private List> adjacentVertex = new ArrayList<>(); + + Vertex(long id) { + this.id = id; + } + + public long getId() { + return id; + } + + public void setData(T data) { + this.data = data; + } + + public T getData() { + return data; + } + + public void addAdjacentVertex(Edge e, Vertex v) { + edges.add(e); + adjacentVertex.add(v); + } + + public String toString() { + return String.valueOf(id); + } + + public List> getAdjacentVertexes() { + return adjacentVertex; + } + + public List> getEdges() { + return edges; + } + + public int getDegree() { + return edges.size(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (int) (id ^ (id >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Vertex other = (Vertex) obj; + if (id != other.id) + return false; + return true; + } +} + +class Edge { + private boolean isDirected = false; + private Vertex vertex1; + private Vertex vertex2; + private int weight; + + Edge(Vertex vertex1, Vertex vertex2) { + this.vertex1 = vertex1; + this.vertex2 = vertex2; + } + + Edge(Vertex vertex1, Vertex vertex2, boolean isDirected, int weight) { + this.vertex1 = vertex1; + this.vertex2 = vertex2; + this.weight = weight; + this.isDirected = isDirected; + } + + Edge(Vertex vertex1, Vertex vertex2, boolean isDirected) { + this.vertex1 = vertex1; + this.vertex2 = vertex2; + this.isDirected = isDirected; + } + + Vertex getVertex1() { + return vertex1; + } + + Vertex getVertex2() { + return vertex2; + } + + int getWeight() { + return weight; + } + + public boolean isDirected() { + return isDirected; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((vertex1 == null) ? 0 : vertex1.hashCode()); + result = prime * result + ((vertex2 == null) ? 0 : vertex2.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Edge other = (Edge) obj; + if (vertex1 == null) { + if (other.vertex1 != null) + return false; + } else if (!vertex1.equals(other.vertex1)) + return false; + if (vertex2 == null) { + if (other.vertex2 != null) + return false; + } else if (!vertex2.equals(other.vertex2)) + return false; + return true; + } + + @Override + public String toString() { + return "Edge [isDirected=" + isDirected + ", vertex1=" + vertex1 + ", vertex2=" + vertex2 + ", weight=" + weight + + "]"; + } +} diff --git a/src/graph/kruskalAlgorithm/KruskalMST.java b/src/graph/kruskalAlgorithm/KruskalMST.java new file mode 100644 index 0000000..2f2c785 --- /dev/null +++ b/src/graph/kruskalAlgorithm/KruskalMST.java @@ -0,0 +1,53 @@ +package kruskalAlgorithm; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class KruskalMST { + + public List> getMST(Graph graph) { + List> allEdges = graph.getAllEdges(); + + Collections.sort(allEdges, (edge1, edge2) -> edge1.getWeight() <= edge2.getWeight() ? -1 : 1); + DisjointSet disjointSet = new DisjointSet(); + + for (Vertex vertex : graph.getAllVertex()) { + disjointSet.makeSet(vertex.getId()); + } + + List> resultEdge = new ArrayList>(); + for (Edge edge : allEdges) { + long root1 = disjointSet.findSet(edge.getVertex1().getId()); + long root2 = disjointSet.findSet(edge.getVertex2().getId()); + + if (root1 != root2) { + resultEdge.add(edge); + disjointSet.union(edge.getVertex1().getId(), edge.getVertex2().getId()); + } + } + return resultEdge; + } + + public static void main(String args[]) { + Graph graph = new Graph(false); + graph.addEdge(1, 2, 4); + graph.addEdge(1, 3, 1); + graph.addEdge(2, 5, 1); + graph.addEdge(2, 6, 3); + graph.addEdge(2, 4, 2); + graph.addEdge(6, 5, 2); + graph.addEdge(6, 4, 3); + graph.addEdge(4, 7, 2); + graph.addEdge(3, 4, 5); + graph.addEdge(3, 7, 8); + + KruskalMST mst = new KruskalMST(); + List> result = mst.getMST(graph); + int count = 0; + for (Edge edge : result) { + count += edge.getWeight(); + System.out.println(edge.getVertex1() + " " + edge.getVertex2() + "-> " + count); + } + } +} \ No newline at end of file diff --git a/src/graph/leetcode/AllPathsInGraph.java b/src/graph/leetcode/AllPathsInGraph.java new file mode 100644 index 0000000..380bddd --- /dev/null +++ b/src/graph/leetcode/AllPathsInGraph.java @@ -0,0 +1,47 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Given a directed, acyclic graph of N nodes. Find all possible paths from node 0 to node N-1, and return them in any order. + * + * The graph is given as follows: the nodes are 0, 1, ..., graph.length - 1. + * graph[i] is a list of all nodes j for which the edge (i, j) exists. + * + * Example: + * Input: [[1,2], [3], [3], []] + * Output: [[0,1,3],[0,2,3]] + * Explanation: The graph looks like this: + * 0--->1 + * | | + * v v + * 2--->3 + * There are two paths: 0 -> 1 -> 3 and 0 -> 2 -> 3. + */ +public class AllPathsInGraph { + public List> allPathsSourceTarget(int[][] graph) { + boolean[] visited=new boolean[graph.length]; + List path=new ArrayList(); + List> ans=new ArrayList>(); + visited[0]=true; + path.add(0); + dfs(graph,visited,0,path, ans); + return ans; + } + public void dfs(int[][] graph,boolean[] visited,int u,List path, List> ans){ + if(u==graph.length-1){ + ans.add(new ArrayList<>(path)); + return; + } + for(int i=0;i> prices = new HashMap<>(); + for (int[] f : flights) { + if (!prices.containsKey(f[0])) prices.put(f[0], new HashMap<>()); + prices.get(f[0]).put(f[1], f[2]); + } + Queue pq = new PriorityQueue<>((a, b) -> (Integer.compare(a[0], b[0]))); + pq.add(new int[] {0, src, k + 1}); // the reason k+1 is put because the starting point is also considered as a step, refer above comment + while (!pq.isEmpty()) { + int[] top = pq.remove(); + int price = top[0]; + int city = top[1]; + int stops = top[2]; + if (city == dst) return price; + if (stops > 0) { + Map adj = prices.getOrDefault(city, new HashMap<>()); + for (int a : adj.keySet()) { + pq.add(new int[] {price + adj.get(a), a, stops - 1}); + } + } + } + return -1; + } + + public int findCheapestPriceAlter(int n, int[][] flights, int src, int dst, int K) + { + Map> map=new HashMap<>(); + for(int[] f:flights) + { + map.putIfAbsent(f[0],new ArrayList<>()); + map.get(f[0]).add(new int[]{f[1],f[2]}); + } + PriorityQueue q=new PriorityQueue<>(new Comparator() { + @Override + public int compare(int[] o1, int[] o2) { + return Integer.compare(o1[0],o2[0]); + } + }); + q.offer(new int[]{0,src,K+1}); + while(!q.isEmpty()) + { + int[] c=q.poll(); + int cost=c[0]; + int curr=c[1]; + int stop=c[2]; + if(curr==dst) + return cost; + if(stop>0) + { + if(!map.containsKey(curr)) + continue; + for(int[] next:map.get(curr)) + { + q.add(new int[]{cost+next[1],next[0],stop-1}); + } + } + } + return -1; + } + + +} diff --git a/src/graph/leetcode/ConnectCities.java b/src/graph/leetcode/ConnectCities.java new file mode 100644 index 0000000..695c1ca --- /dev/null +++ b/src/graph/leetcode/ConnectCities.java @@ -0,0 +1,64 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Input: N = 3, connections = [[1,2,5],[1,3,6],[2,3,1]] + * Output: 6 + * Explanation: + * Choosing any 2 edges will connect all cities so we choose the minimum 2. + */ +public class ConnectCities { + public int solve(int A, ArrayList> B) { + + // greedy-ly we looking from low cost roads to minimise the cost + Collections.sort(B,((a, b)->Integer.compare(a.get(2),b.get(2)))); + + UnionSet us= new UnionSet(A); + int result=0; + for(List row:B){ + if(us.union(row.get(0),row.get(1))) result+=row.get(2); + } + return result; + } + + static class UnionSet{ + int[] parent; + int [] rank; + int count; + public UnionSet(int n){ + this.count=count; + this.parent= new int[n+1]; + this.rank=new int[n+1]; + for(int i=0;i<=n;i++){ + this.parent[i]=i; + this.rank[i]=1; + } + } + + public int find(int n){ + if(parent[n]==n) return n; + parent[n]= find(parent[n]); + return parent[n]; + } + + public boolean union(int x, int y){ + int rootX= find(x); + int rootY= find(y); + if(rootX==rootY) return false; + + if(rank[rootX]rank[rootY]){ + parent[rootY]=rootX; + }else{ + parent[rootY]=rootX; + rank[rootX]++; + } + count--; + return true; + } + } +} diff --git a/src/graph/leetcode/ConnectMissingCities.java b/src/graph/leetcode/ConnectMissingCities.java new file mode 100644 index 0000000..95ebc5f --- /dev/null +++ b/src/graph/leetcode/ConnectMissingCities.java @@ -0,0 +1,54 @@ +package leetcode; + +import java.util.Arrays; + +/** + * Input: n = 6, edges = [[1, 4], [4, 5], [2, 3]], newEdges = [[1, 2, 5], [1, 3, 10], [1, 6, 2], [5, 6, 5]] + * Output: 7 + * Explanation: + * There are 3 connected components [1, 4, 5], [2, 3] and [6]. + * We can connect these components into a single component by connecting node 1 to node 2 and node 1 to node 6 at a minimum cost of 5 + 2 = 7. + */ +public class ConnectMissingCities { + + int[] parent; + int component; + + private int find(int v){ + if(parent[v] == v) return v; + return parent[v] = find(parent[v]); + } + + private void connect(int v1, int v2){ + if(find(v1) == find(v2)) return; + int root = find(v1); + while(v2 != parent[v2]){ + int temp = parent[v2]; + parent[v2] = root; + v2 = temp; + } + --component; + parent[v2] = root; + } + + private boolean isConnected(int v1, int v2){ + return find(v1) == find(v2); + } + + public int minCosttoConnectAllNodes(int n, int edges[][], int newEdges[][]){ + parent = new int[n + 1]; component = n; + for(int i = 0; i <= n; ++i) parent[i] = i; + for(int[] edge: edges) connect(edge[0], edge[1]); // same as connectcities + Arrays.sort(newEdges, (a, b) -> (a[2] - b[2])); + int cost = 0; + for(int i = 0; i < newEdges.length; ++i){ + if(!isConnected(newEdges[i][0], newEdges[i][1])){ + connect(newEdges[i][0], newEdges[i][1]); + cost += newEdges[i][2]; + if(component == 1) return cost; + } + } + return -1; + } + +} diff --git a/src/graph/leetcode/ConnectedComponentsInGraph.java b/src/graph/leetcode/ConnectedComponentsInGraph.java new file mode 100644 index 0000000..322d774 --- /dev/null +++ b/src/graph/leetcode/ConnectedComponentsInGraph.java @@ -0,0 +1,32 @@ +package leetcode; + +public class ConnectedComponentsInGraph { + + public int countComponents(int n, int[][] edges) { + int[] roots = new int[n]; + + for (int i = 0; i < n; i++) { + roots[i] = i; + } + + for (int i = 0; i < edges.length; i++) { + int r1 = find(roots, edges[i][0]); + int r2 = find(roots, edges[i][1]); + + if (r1 != r2) { + roots[r1] = r2; + n--; + } + } + + return n; + } + + private int find(int[] roots, int key) { + while (roots[key] != key) { + key = roots[key]; + } + + return key; + } +} diff --git a/src/graph/leetcode/CourseSchedule.java b/src/graph/leetcode/CourseSchedule.java new file mode 100644 index 0000000..37f22d0 --- /dev/null +++ b/src/graph/leetcode/CourseSchedule.java @@ -0,0 +1,115 @@ +package leetcode; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Queue; +/** + * Input: numCourses = 2, prerequisites = [[1,0]] +Output: true +Explanation: There are a total of 2 courses to take. +To take course 1 you should have finished course 0. So it is possible. + +Input: numCourses = 2, prerequisites = [[1,0],[0,1]] +Output: false +Explanation: There are a total of 2 courses to take. + To take course 1 you should have finished course 0, and to take course 0 you should + also have finished course 1. So it is impossible. + */ +class CourseSchedule { + public boolean canFinish(int numCourses, int[][] prerequisites) { + + Map> map = new HashMap<>(); // Courses that depend on the key + int[] degrees = new int[numCourses]; // # of prerequisites for course i + Queue queue = new ArrayDeque<>(); // Used to find dependants and decrease their outdegree + + for (int[] pre : prerequisites) { + List tempList = map.getOrDefault(pre[1], new ArrayList<>()); + tempList.add(pre[0]); + degrees[pre[0]]++; + map.put(pre[1], tempList); + } + + for (int i = 0; i < degrees.length; i++) { + if (degrees[i] == 0) { + queue.offer(i); + } + } + + int count = 0; + while (!queue.isEmpty()) { + int temp = queue.poll(); + if (degrees[temp] == 0) { + count++; // if cond for duplicates + } + if (!map.containsKey(temp)) { + continue; + } + for (int i : map.get(temp)) { + if (--degrees[i] == 0) { + queue.offer(i); + } + } + } + + return count == numCourses; + } + + public boolean canFinishDFS(int numCourses, int[][] prerequisites) { + // this method basically finds a back-edge between nodes + // backedge is when doing a node(A)'s dfs, it puts A to a temp state + // while traversing A's child, if any of child dosen't have anymore child it's marked as completed + // if there are children it put's the current child to temp state and visits it's children + // so when doing a dfs for a node if it encounters a temp state node rather than completed node + // then that means there's a cycle we cannot complete the course + // (T) A \ + // / / + // (T) B / + // / \ / + // (Co) C D (T) while doing DFS for D's components we encounter A, but A is still in temp state + // + ArrayList[] adjList= new ArrayList[numCourses]; + for(int i=0;i(); + } + for(int[] preReq:prerequisites){ + adjList[preReq[0]].add(preReq[1]); + } + + int[] visited= new int[numCourses]; + for(int i=0;i[] adjList, int[] visited, int vertex){ + if(visited[vertex]==1) return false; + visited[vertex]=1; + for(int adj: adjList[vertex]){ + if(!dfs(adjList, visited, adj)) return false; + } + visited[vertex]=2; + return true; + } + // this is to get the order of course as output + public boolean dfs( List[] adjList, int[] visited, Listresult, int node){ + if(visited[node]==1) return false; + if(visited[node]==2) return true; + + visited[node]=1; + for(int adj: adjList[node]){ + if(!dfs(adjList, visited, result, adj)){ + return false; + } + } + visited[node]=2; + result.add(node); // this will keep track of which to fininsh first and last + return true; + } +} \ No newline at end of file diff --git a/src/graph/leetcode/FindJudge.java b/src/graph/leetcode/FindJudge.java new file mode 100644 index 0000000..790cb51 --- /dev/null +++ b/src/graph/leetcode/FindJudge.java @@ -0,0 +1,30 @@ +package leetcode; + +/** + * In a town, there are N people labelled from 1 to N. There is a rumor that one of these people is secretly the town judge. + * + * If the town judge exists, then: + * + * The town judge trusts nobody. + * Everybody (except for the town judge) trusts the town judge. + * There is exactly one person that satisfies properties 1 and 2. + * You are given trust, an array of pairs trust[i] = [a, b] representing that the person labelled a trusts the person labelled b. + */ +public class FindJudge { + public int findJudge(int N, int[][] trust) { + if(trust.length==0 && N==1) return 1; + int[] inEdge= new int[N+1]; + int[] outEdge= new int[N+1]; + + for(int[] val: trust){ + outEdge[val[0]]++; + inEdge[val[1]]++; + } + + for(int i=1;i<=N;i++){ + if(outEdge[i]==0 && inEdge[i]==N-1) return i; + } + + return -1; + } +} diff --git a/src/graph/leetcode/FriendCircles.java b/src/graph/leetcode/FriendCircles.java new file mode 100644 index 0000000..24f41b6 --- /dev/null +++ b/src/graph/leetcode/FriendCircles.java @@ -0,0 +1,57 @@ +package leetcode; + +// similar to number of Islands +public class FriendCircles { + public int findCircleNum(int[][] M) { + UnionFind uf= new UnionFind(M.length); + for(int i=0;irank[rootY]){ + parent[rootY]=rootX; + }else if(rank[rootY]>rank[rootX]){ + parent[rootX]=rootY; + }else{ + parent[rootY]=rootX; + rank[rootX]++; + } + count--; + } + + public int getCount(){ + return count; + } + } +} diff --git a/src/graph/leetcode/GraphBiPartite.java b/src/graph/leetcode/GraphBiPartite.java new file mode 100644 index 0000000..39fdff3 --- /dev/null +++ b/src/graph/leetcode/GraphBiPartite.java @@ -0,0 +1,53 @@ +package leetcode; + +/** + * Recall that a graph is bipartite if we can split it's set of nodes into + * two independent subsets A and B such that every edge in the graph has one node in A and + * another node in B. + * Input: [[1,3], [0,2], [1,3], [0,2]] => 0th node connects to 1,3 .. +Output: true +Explanation: +The graph looks like this: +0----1 +| | +| | +3----2 +We can divide the vertices into two groups: {0, 2} and {1, 3}. +Input: [[1,2,3], [0,2], [0,1,3], [0,2]] +Output: false +Explanation: +The graph looks like this: +0----1 +| \ | +| \ | +3----2 +We cannot find a way to divide the set of nodes into two independent subsets. + */ +public class GraphBiPartite { + public boolean isBipartite(int[][] graph) { + int[] color= new int[graph.length]; + + for(int i=0;i + * Input: + *

+ * n, an int representing the total number of nodes. + * edges, a list of integer pair representing the nodes connected by an edge. + * edgesToRepair, a list where each element is a triplet representing the pair of nodes + * between which an edge is currently broken and the cost of repearing that edge, + * respectively (e.g. [1, 2, 12] means to repair an edge between nodes 1 and 2, the cost would be 12). + */ +public class MinCostRepairEdges { + public static void main(String[] args) { + int n = 5; + int[][] edges = {{1, 2}, {2, 3}, {3, 4}, {4, 5}, {1, 5}}; + int[][] edgesToRepair = {{1, 2, 12}, {3, 4, 30}, {1, 5, 8}}; + System.out.println(new MinCostRepairEdges().minCostToRepair(n, edges, edgesToRepair)); + } + + + public int minCostToRepair(int n, int[][] edges, int[][] edgesToRepair) { + Set hset = new HashSet<>(); + + PriorityQueue pq = new PriorityQueue<>((a, b) -> a[2] - b[2]); + for (int[] e : edgesToRepair) { + pq.add(e); + hset.add(e[0] + " " + e[1]); + } + + for (int[] e : edges) { + String s = e[0] + " " + e[1]; + if (hset.contains(s)) continue; + int[] ne = new int[]{e[0], e[1], 0}; + pq.add(ne); + } + + int[] parent = new int[n + 1]; + Arrays.fill(parent, -1); + + int sum = 0; + while (!pq.isEmpty()) { + int[] e = pq.poll(); + int u = e[0], v = e[1], w = e[2]; + int up = find(u, parent), vp = find(v, parent); + if (up != vp) { + union(up, vp, parent); + sum += w; + } + } + + System.out.println(sum + " result"); + return sum; + } + + public static void union(int x, int y, int[] parent) { + int xroot = find(x, parent); + int yroot = find(y, parent); + parent[yroot] = xroot; + } + + public static int find(int x, int[] parent) { + if (parent[x] < 0) { + return x; + } + int p = find(parent[x], parent); + parent[x] = p; + return p; + } +} + + diff --git a/src/graph/leetcode/NetworkDelayTime.java b/src/graph/leetcode/NetworkDelayTime.java new file mode 100644 index 0000000..7ee77e7 --- /dev/null +++ b/src/graph/leetcode/NetworkDelayTime.java @@ -0,0 +1,70 @@ +package leetcode; + +import java.util.*; +/** + * There are N network nodes, labelled 1 to N. + * + * Given times, a list of travel times as directed edges times[i] = (u, v, w), where u is the source node, v is the target node, and w is the time it takes for a signal to travel from source to target. + * + * Now, we send a signal from a certain node K. How long will it take for all nodes to receive the signal? If it is impossible, return -1. + */ +public class NetworkDelayTime { + + public int networkDelayTime(int[][] times, int N, int K) { + + Map> adjacencyMap = new HashMap<>(); + + PriorityQueue pq = new PriorityQueue<>((a, b) -> Integer.compare(a[1], b[1])); + + for (int[] row : times) { + // creating adjacency list where row[0] is start node, row[1] is destNode and row[2] is distance + List adjList = adjacencyMap.getOrDefault(row[0], new ArrayList<>()); + + adjList.add(new int[]{row[1], row[2]}); + + adjacencyMap.put(row[0], adjList); + } + // general set to keep track of visited nodes + Set visited = new HashSet<>(); + + // K is the node where we have to begin + pq.offer(new int[]{K, 0}); + + // this will track min distance to reach for current node + int[] distance = new int[N + 1]; + Arrays.fill(distance, Integer.MAX_VALUE); + // since we are starting at K, marking it's distance as 0 + distance[K] = 0; + distance[0] = 0; + int max = 0; + while (!pq.isEmpty()) { + int[] value = pq.poll(); + + int node = value[0]; + int distStartNode = value[1]; + + if (!visited.add(node)) continue; + + max = distStartNode; + N--; + if (!adjacencyMap.containsKey(node)) continue; + // going to traverse it's adjacent nodes + for (int[] adjList : adjacencyMap.get(node)) { + + int destNode = adjList[0]; + int distanceToDestination = adjList[1]; + + int newDist = Math.min(distanceToDestination + distStartNode, distance[destNode]); + distance[destNode] = newDist; + + if (!visited.contains(destNode)) { + pq.offer(new int[]{adjList[0], newDist}); + } + } + } + + return N == 0 ? max : -1; + } + +} + diff --git a/src/graph/leetcode/NewRoadsMinimumSpanningTree.java b/src/graph/leetcode/NewRoadsMinimumSpanningTree.java new file mode 100644 index 0000000..e0e74ea --- /dev/null +++ b/src/graph/leetcode/NewRoadsMinimumSpanningTree.java @@ -0,0 +1,87 @@ +package geeksforgeeks; + +import java.util.Arrays; +import java.util.PriorityQueue; +import java.util.Queue; + +/** + * Given an undirected graph with n nodes labeled 1..n. Some of the nodes are already connected. + * The i-th edge connects nodes edges[i][0] and edges[i][1] together. Your task is to augment this set of edges with additional edges to connect all the nodes. + * Find the minimum cost to add new edges between the nodes such that all the nodes are accessible from each other. + * Input: n = 6, edges = [[1, 4], [4, 5], [2, 3]], newEdges = [[1, 2, 5], [1, 3, 10], [1, 6, 2], [5, 6, 5]] + * Output: 7 + * Explanation: + * There are 3 connected components [1, 4, 5], [2, 3] and [6]. + * We can connect these components into a single component by connecting node 1 to node 2 and node 1 to node 6 at a minimum cost of 5 + 2 = 7. + */ +public class NewRoadsMinimumSpanningTree { + + public static void main(String[] args) { + int n = 6; + int[][] edges = {{1, 4}, {4, 5}, {2, 3}}; + int[][] newEdges = {{1, 2, 5}, {1, 3, 10}, {1, 6, 2}, {5, 6, 5}}; + System.out.println(minCost(n, edges, newEdges)); + } + + public static int minCost(int n, int[][] edges, int[][] newEdges) { + UF uf = new UF(n + 1); // + 1 because nodes are 1-based + for (int[] edge : edges) { + uf.union(edge[0], edge[1]); + } + + Queue pq = new PriorityQueue<>(newEdges.length, (e1, e2) -> Integer.compare(e1[2], e2[2])); + pq.addAll(Arrays.asList(newEdges)); + + int totalCost = 0; + // 2 because nodes are 1-based and we have 1 unused component at index 0 + while (!pq.isEmpty() && uf.count != 2) { + int[] edge = pq.poll(); + if (!uf.connected(edge[0], edge[1])) { + uf.union(edge[0], edge[1]); + totalCost += edge[2]; + } + } + return totalCost; + } +} + +class UF { + private int[] parent; // parent[i] = parent of i + private byte[] rank; // rank[i] = rank of subtree rooted at i (never more than 31) + public int count; // number of connected components + + public UF(int n) { + if (n < 0) throw new IllegalArgumentException(); + parent = new int[n]; + rank = new byte[n]; + for (int i = 0; i < n; i++) { + parent[i] = i; + } + count = n; + } + + public int find(int p) { + while (p != parent[p]) { + parent[p] = parent[parent[p]]; + p = parent[p]; + } + return p; + } + + public void union(int p, int q) { + int pr = find(p); + int qr = find(q); + if (pr == qr) return; + if (rank[pr] < rank[qr]) { + parent[pr] = qr; + } else { + parent[qr] = pr; + if (rank[pr] == rank[qr]) rank[pr]++; + } + count--; + } + + public boolean connected(int p, int q) { + return find(p) == find(q); + } +} diff --git a/src/graph/leetcode/RedundantConnection.java b/src/graph/leetcode/RedundantConnection.java new file mode 100644 index 0000000..a7353f2 --- /dev/null +++ b/src/graph/leetcode/RedundantConnection.java @@ -0,0 +1,59 @@ +package leetcode; + +/** + * Input: [[1,2], [1,3], [2,3]] + * Output: [2,3] + * Explanation: The given undirected graph will be like this: + * 1 + * / \ + * 2 - 3 + * + * Input: [[1,2], [2,3], [3,4], [1,4], [1,5]] + * Output: [1,4] + * Explanation: The given undirected graph will be like this: + * 5 - 1 - 2 + * | | + * 4 - 3 + */ +public class RedundantConnection { + public int[] findRedundantConnection(int[][] edges) { + DisjointSet set= new DisjointSet(edges.length); + + for(int[]edge: edges){ + if(!set.union(edge[0]-1, edge[1]-1)) return edge; + } + return new int[]{-1,-1}; + } + + static class DisjointSet{ + int[] parent; + int[] rank; + + public DisjointSet(int n){ + this.parent= new int[n]; + this.rank= new int[n]; + } + + public int find(int x){ + if(parent[x]==0) return x; + return parent[x]=find(parent[x]); + } + + public boolean union(int x, int y){ + int rootX= find(x); + int rootY= find(y); + + if(rootX==rootY) return false; + + if(rank[rootX] map = new HashMap<>(); + int id = 0; + + for (String[] pair : pairs) { + for (String word : pair) { + if (!map.containsKey(word)) { + map.put(word, id); + ++id; + } + } + + uf.union(map.get(pair[0]), map.get(pair[1])); + } + + + for (int i = 0; i < words1.length; i++) { + String word1 = words1[i]; + String word2 = words2[i]; + + if (word1.equals(word2)) { + continue; + } + + if (!map.containsKey(word1) || !map.containsKey(word2) || uf.find(map.get(word1)) != uf.find(map.get(word2))) { + return false; + } + } + return true; + } + + class UnionFind { + int[] sets; + int[] size; + int count; + + public UnionFind(int n) { + sets = new int[n]; + size = new int[n]; + count = n; + + for (int i = 0; i < n; i++) { + sets[i] = i; + size[i] = 1; + } + } + + public int find(int node) { + while (node != sets[node]) { + node = sets[node]; + } + return node; + } + + public void union(int i, int j) { + int node1 = find(i); + int node2 = find(j); + + if (node1 == node2) { + return; + } + + if (size[node1] < size[node2]) { + sets[node1] = node2; + size[node2] += size[node1]; + } else { + sets[node2] = node1; + size[node1] += size[node2]; + } + --count; + } + } + +} diff --git a/src/graph/leetcode/SnapShotUtil.java b/src/graph/leetcode/SnapShotUtil.java new file mode 100644 index 0000000..ff60082 --- /dev/null +++ b/src/graph/leetcode/SnapShotUtil.java @@ -0,0 +1,52 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +class SnapShotUtil{ + int[] arr; + int sequenceId; +Map> snapShots; +List updateTracker; + +public SnapShotUtil(int[] input){ + this.arr= input; + this.sequenceId=0; + snapShots= new HashMap<>(); + updateTracker= new ArrayList<>(); + + } + +public int get(int index){ + if(index>=this.arr.length) return -1; + return this.arr[index]; + } + +public void put(int index, int value){ + if(index>=this.arr.length) return ; + this.updateTracker.add(new Integer[]{index,value}); + this.arr[index]=value; + } + +public int createSnapShot(){ + snapShots.put(++sequenceId, this.updateTracker); + this.updateTracker= new ArrayList<>(); + return sequenceId; + } + +public int get(int snapShotId, int index){ + if(!snapShots.containsKey(snapShotId)) return -1; + + List updates= snapShots.get(snapShotId); + int[] tempArr= this.arr; + + for(Integer[] update: updates){ + tempArr[update[0]]=update[1]; + } + + return tempArr[index]; + } +} + diff --git a/src/graph/primsAlgorithm/BinaryMinHeap.java b/src/graph/primsAlgorithm/BinaryMinHeap.java new file mode 100644 index 0000000..1f53399 --- /dev/null +++ b/src/graph/primsAlgorithm/BinaryMinHeap.java @@ -0,0 +1,145 @@ +package primsAlgorithm; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class BinaryMinHeap { + + private List allNodes = new ArrayList<>(); + private Map nodePosition = new HashMap<>(); + + public class Node { + long weight; + long key; + } + + public boolean containsData(long id) { + return nodePosition.containsKey(id); + } + + public void add(int weight, long l) { + Node node = new Node(); + node.weight = weight; + node.key = l; + allNodes.add(node); + int size = allNodes.size(); + int current = size - 1; + int parentIndex = (current - 1) / 2; + nodePosition.put(node.key, current); + + while (parentIndex >= 0) { + Node parentNode = allNodes.get(parentIndex); + Node currentNode = allNodes.get(current); + if (parentNode.weight > currentNode.weight) { + swap(parentNode, currentNode); + updatePositionMap(parentNode.key, currentNode.key, parentIndex, current); + current = parentIndex; + parentIndex = (parentIndex - 1) / 2; + } else { + break; + } + } + } + + public Long min() { + return allNodes.get(0).key; + } + + public boolean empty() { + return allNodes.size() == 0; + } + + public void decrease(long data, int newWeight) { + Integer position = nodePosition.get(data); + allNodes.get(position).weight = newWeight; + int parent = (position - 1) / 2; + while (parent >= 0) { + if (allNodes.get(parent).weight > allNodes.get(position).weight) { + swap(allNodes.get(parent), allNodes.get(position)); + updatePositionMap(allNodes.get(parent).key, allNodes.get(position).key, parent, position); + position = parent; + parent = (parent - 1) / 2; + } else { + break; + } + } + } + + public Long getWeight(long key) { + Integer position = nodePosition.get(key); + if (position == null) { + return null; + } else { + return allNodes.get(position).weight; + } + } + + public Node extractMinNode() { + int size = allNodes.size() - 1; + Node minNode = new Node(); + minNode.key = allNodes.get(0).key; + minNode.weight = allNodes.get(0).weight; + + long lastNodeWeight = allNodes.get(size).weight; + allNodes.get(0).weight = lastNodeWeight; + allNodes.get(0).key = allNodes.get(size).key; + nodePosition.remove(minNode.key); + nodePosition.remove(allNodes.get(0)); + nodePosition.put(allNodes.get(0).key, 0); + allNodes.remove(size); + + int currentIndex = 0; + size--; + while (true) { + int left = 2 * currentIndex + 1; + int right = 2 * currentIndex + 2; + if (left > size) { + break; + } + if (right > size) { + right = left; + } + int smallerIndex = allNodes.get(left).weight <= allNodes.get(right).weight ? left : right; + if (allNodes.get(currentIndex).weight > allNodes.get(smallerIndex).weight) { + swap(allNodes.get(currentIndex), allNodes.get(smallerIndex)); + updatePositionMap(allNodes.get(currentIndex).key, allNodes.get(smallerIndex).key, currentIndex, + smallerIndex); + currentIndex = smallerIndex; + } else { + break; + } + } + return minNode; + } + + public long extractMin() { + return extractMinNode().key; + } + + private void swap(Node node1, Node node2) { + long weight = node1.weight; + long data = node1.key; + + node1.key = node2.key; + node1.weight = node2.weight; + + node2.key = data; + node2.weight = weight; + } + + private void updatePositionMap(long data1, long data2, int pos1, int pos2) { + nodePosition.remove(data1); + nodePosition.remove(data2); + nodePosition.put(data1, pos1); + nodePosition.put(data2, pos2); + } + + public void printHeap() { + for (Node n : allNodes) { + System.out.print(n.weight + " "); + } + } + +} \ No newline at end of file diff --git a/src/graph/primsAlgorithm/Graph.java b/src/graph/primsAlgorithm/Graph.java new file mode 100644 index 0000000..d651ee7 --- /dev/null +++ b/src/graph/primsAlgorithm/Graph.java @@ -0,0 +1,243 @@ +package primsAlgorithm; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Graph { + + private List allEdges; + private Map allVertex; + boolean isDirected = false; + + public Graph(boolean isDirected) { + allEdges = new ArrayList(); + allVertex = new HashMap(); + this.isDirected = isDirected; + } + + public void addEdge(long id1, long id2) { + addEdge(id1, id2, 0); + } + + // This works only for directed graph because for undirected graph we can end up + // adding edges two times to allEdges + public void addVertex(Vertex vertex) { + if (allVertex.containsKey(vertex.getId())) { + return; + } + allVertex.put(vertex.getId(), vertex); + for (Edge edge : vertex.getEdges()) { + allEdges.add(edge); + } + } + + public Vertex addSingleVertex(long id) { + if (allVertex.containsKey(id)) { + return allVertex.get(id); + } + Vertex v = new Vertex(id); + allVertex.put(id, v); + return v; + } + + public Vertex getVertex(long id) { + return allVertex.get(id); + } + + public void addEdge(long id1, long id2, int weight) { + Vertex vertex1 = null; + if (allVertex.containsKey(id1)) { + vertex1 = allVertex.get(id1); + } else { + vertex1 = new Vertex(id1); + allVertex.put(id1, vertex1); + } + Vertex vertex2 = null; + if (allVertex.containsKey(id2)) { + vertex2 = allVertex.get(id2); + } else { + vertex2 = new Vertex(id2); + allVertex.put(id2, vertex2); + } + + Edge edge = new Edge(vertex1, vertex2, isDirected, weight); + allEdges.add(edge); + vertex1.addAdjacentVertex(edge, vertex2); + if (!isDirected) { + vertex2.addAdjacentVertex(edge, vertex1); + } + + } + + public List getAllEdges() { + return allEdges; + } + + public Collection getAllVertex() { + return allVertex.values(); + } + + public void setDataForVertex(long id, int data) { + if (allVertex.containsKey(id)) { + Vertex vertex = allVertex.get(id); + vertex.setData(data); + } + } + + @Override + public String toString() { + StringBuffer buffer = new StringBuffer(); + for (Edge edge : getAllEdges()) { + buffer.append(edge.getVertex1() + " " + edge.getVertex2() + " " + edge.getWeight()); + buffer.append("\n"); + } + return buffer.toString(); + } +} + +class Vertex { + long id; + private int data; + private List edges = new ArrayList<>(); + private List adjacentVertex = new ArrayList<>(); + + Vertex(long id) { + this.id = id; + } + + public long getId() { + return id; + } + + public void setData(int data) { + this.data = data; + } + + public int getData() { + return data; + } + + public void addAdjacentVertex(Edge e, Vertex v) { + edges.add(e); + adjacentVertex.add(v); + } + + public String toString() { + return String.valueOf(id); + } + + public List getAdjacentVertexes() { + return adjacentVertex; + } + + public List getEdges() { + return edges; + } + + public int getDegree() { + return edges.size(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (int) (id ^ (id >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Vertex other = (Vertex) obj; + if (id != other.id) + return false; + return true; + } +} + +class Edge { + private boolean isDirected = false; + private Vertex vertex1; + private Vertex vertex2; + private int weight; + + Edge(Vertex vertex1, Vertex vertex2) { + this.vertex1 = vertex1; + this.vertex2 = vertex2; + } + + Edge(Vertex vertex1, Vertex vertex2, boolean isDirected, int weight) { + this.vertex1 = vertex1; + this.vertex2 = vertex2; + this.weight = weight; + this.isDirected = isDirected; + } + + Edge(Vertex vertex1, Vertex vertex2, boolean isDirected) { + this.vertex1 = vertex1; + this.vertex2 = vertex2; + this.isDirected = isDirected; + } + + Vertex getVertex1() { + return vertex1; + } + + Vertex getVertex2() { + return vertex2; + } + + int getWeight() { + return weight; + } + + public boolean isDirected() { + return isDirected; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((vertex1 == null) ? 0 : vertex1.hashCode()); + result = prime * result + ((vertex2 == null) ? 0 : vertex2.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Edge other = (Edge) obj; + if (vertex1 == null) { + if (other.vertex1 != null) + return false; + } else if (!vertex1.equals(other.vertex1)) + return false; + if (vertex2 == null) { + if (other.vertex2 != null) + return false; + } else if (!vertex2.equals(other.vertex2)) + return false; + return true; + } + + @Override + public String toString() { + return "Edge [isDirected=" + isDirected + ", vertex1=" + vertex1 + ", vertex2=" + vertex2 + ", weight=" + weight + + "]"; + } +} diff --git a/src/graph/primsAlgorithm/PrimMST.java b/src/graph/primsAlgorithm/PrimMST.java new file mode 100644 index 0000000..3955674 --- /dev/null +++ b/src/graph/primsAlgorithm/PrimMST.java @@ -0,0 +1,71 @@ +package primsAlgorithm; + +import java.util.*; + +/** + * + * Space complexity - O(E + V) Time complexity - O(ElogV) + * + */ +public class PrimMST { + + public List primMST(Graph graph) { + + BinaryMinHeap minHeap = new BinaryMinHeap(); + Map vertexToEdge = new HashMap<>(); + List result = new ArrayList<>(); + + for (Vertex v : graph.getAllVertex()) { + minHeap.add(Integer.MAX_VALUE, v.getId()); + } + + Vertex startVertex = graph.getAllVertex().iterator().next(); + minHeap.decrease(startVertex.id, 0); + + while (!minHeap.empty()) { + long currentId = minHeap.extractMin(); + Vertex current = graph.getVertex(currentId); + + Edge spanningTreeEdge = vertexToEdge.get(current); + + if (spanningTreeEdge != null) { + result.add(spanningTreeEdge); + } + + for (Edge edge : current.getEdges()) { + Vertex adjacent = getVertexForEdge(current, edge); + + if (minHeap.containsData(adjacent.id) && minHeap.getWeight(adjacent.id) > edge.getWeight()) { + minHeap.decrease(adjacent.id, edge.getWeight()); + vertexToEdge.put(adjacent, edge); + } + } + } + return result; + } + + private Vertex getVertexForEdge(Vertex v, Edge e) { + return e.getVertex1().equals(v) ? e.getVertex2() : e.getVertex1(); + } + + public static void main(String args[]) { + Graph graph = new Graph(false); + + graph.addEdge(1, 2, 3); + graph.addEdge(2, 3, 1); + graph.addEdge(3, 1, 1); + graph.addEdge(1, 4, 1); + graph.addEdge(2, 4, 3); + graph.addEdge(4, 5, 6); + graph.addEdge(5, 6, 2); + graph.addEdge(3, 5, 5); + graph.addEdge(3, 6, 4); + + PrimMST prims = new PrimMST(); + Collection edges = prims.primMST(graph); + for (Edge edge : edges) { + System.out.println(edge); + } + } + +} \ No newline at end of file diff --git a/src/graph/primsAlgorithm/PrimsMSTArray.java b/src/graph/primsAlgorithm/PrimsMSTArray.java new file mode 100644 index 0000000..25d39c9 --- /dev/null +++ b/src/graph/primsAlgorithm/PrimsMSTArray.java @@ -0,0 +1,54 @@ +package primsAlgorithm; + +class PrimsMSTArray { + + private static final int V = 5; + + int minKey(int key[], Boolean mstSet[]) { + int min = Integer.MAX_VALUE, min_index = -1; + + for (int v = 0; v < V; v++) + if (mstSet[v] == false && key[v] < min) { + min = key[v]; + min_index = v; + } + return min_index; + } + + void printMST(int parent[], int n, int graph[][]) { + System.out.println("Edge \tWeight"); + for (int i = 1; i < V; i++) + System.out.println(parent[i] + " - " + i + "\t" + graph[i][parent[i]]); + } + + void primMST(int graph[][]) { + int parent[] = new int[V]; + int key[] = new int[V]; + Boolean mstSet[] = new Boolean[V]; + for (int i = 0; i < V; i++) { + key[i] = Integer.MAX_VALUE; + mstSet[i] = false; + } + key[0] = 0; + parent[0] = -1; + for (int count = 0; count < V - 1; count++) { + int u = minKey(key, mstSet); + mstSet[u] = true; + for (int v = 0; v < V; v++) { + System.out.println(graph[u][v] + "--" + key[v]); + if (graph[u][v] != 0 && mstSet[v] == false && graph[u][v] < key[v]) { + parent[v] = u; + key[v] = graph[u][v]; + } + } + } + printMST(parent, V, graph); + } + + public static void main(String[] args) { + PrimsMSTArray t = new PrimsMSTArray(); + int graph[][] = new int[][] { { 0, 0, 0, 6, 2 }, { 0, 0, 3, 8, 5 }, { 0, 3, 0, 0, 7 }, { 6, 8, 0, 0, 9 }, + { 2, 5, 7, 9, 0 } }; + t.primMST(graph); + } +} diff --git a/src/graph/shortestPath/Graph.java b/src/graph/shortestPath/Graph.java new file mode 100644 index 0000000..799d170 --- /dev/null +++ b/src/graph/shortestPath/Graph.java @@ -0,0 +1,53 @@ +package shortestPath; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class Graph { + + List> allEdges = new ArrayList>(); + HashMap> adjacentList = new HashMap>(); + + public void addEdge(int src, int dest, int weight) { + Vertex vertex1 = null; + if (adjacentList.containsKey(src)) { + vertex1 = adjacentList.get(src); + } else { + vertex1 = new Vertex(src); + adjacentList.put(src, vertex1); + } + + Vertex vertex2 = null; + if (adjacentList.containsKey(dest)) { + vertex2 = adjacentList.get(dest); + } else { + vertex2 = new Vertex(src); + adjacentList.put(src, vertex2); + } + + allEdges.add(new Edge(vertex1, vertex2, weight)); + allEdges.add(new Edge(vertex2, vertex1, weight)); + } + + class Edge { + Vertex src; + Vertex dest; + int weight; + + public Edge(Vertex src, Vertex dest, int weight) { + this.src = src; + this.dest = dest; + this.weight = weight; + } + } + + class Vertex { + int id; + + public Vertex(int id) { + this.id = id; + } + } + +} diff --git a/src/graph/shortestPath/ShortestPath.java b/src/graph/shortestPath/ShortestPath.java new file mode 100644 index 0000000..984bf7b --- /dev/null +++ b/src/graph/shortestPath/ShortestPath.java @@ -0,0 +1,60 @@ +package shortestPath; + +import java.util.LinkedList; + +public class ShortestPath { + + class Graph { + int vertices; + LinkedList adjacentList[]; + + public Graph(int vertices) { + this.vertices = vertices; + adjacentList = new LinkedList[vertices]; + + for (int i = 0; i < vertices; i++) { + adjacentList[i] = new LinkedList(); + } + } + + void addEdge(int src, int dest) { + adjacentList[src].add(dest); + adjacentList[dest].add(src); + } + } + + public static void main(String[] args) { + ShortestPath sp = new ShortestPath(); + Graph graph = sp.new Graph(8); + graph.addEdge(1, 2); + graph.addEdge(1, 0); + graph.addEdge(0, 3); + graph.addEdge(7, 3); + graph.addEdge(7, 4); + graph.addEdge(4, 5); + graph.addEdge(6, 5); + graph.addEdge(3, 4); + + LinkedList visited = new LinkedList(); + sp.shortestPath(0, 7, graph, visited); + + } + + private void shortestPath(int src, int dest, Graph graph, LinkedList visited) { + + LinkedList linkedList = graph.adjacentList[src]; + if (visited.contains(src) || linkedList.isEmpty() ) { + return; + } + + visited.add(src); + for (Integer val : linkedList) { + if (dest == val) { + System.out.println(val); + return; + } + shortestPath(val, dest, graph,visited); + } + } + +} diff --git a/src/graph/topologicalsort/Graph.java b/src/graph/topologicalsort/Graph.java new file mode 100644 index 0000000..7ba49f3 --- /dev/null +++ b/src/graph/topologicalsort/Graph.java @@ -0,0 +1,245 @@ +package topologicalsort; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Graph{ + + private List> allEdges; + private Map> allVertex; + boolean isDirected = false; + + public Graph(boolean isDirected){ + allEdges = new ArrayList>(); + allVertex = new HashMap>(); + this.isDirected = isDirected; + } + + public void addEdge(long id1, long id2){ + addEdge(id1,id2,0); + } + + //This works only for directed graph because for undirected graph we can end up + //adding edges two times to allEdges + public void addVertex(Vertex vertex){ + if(allVertex.containsKey(vertex.getId())){ + return; + } + allVertex.put(vertex.getId(), vertex); + for(Edge edge : vertex.getEdges()){ + allEdges.add(edge); + } + } + + public Vertex addSingleVertex(long id){ + if(allVertex.containsKey(id)){ + return allVertex.get(id); + } + Vertex v = new Vertex(id); + allVertex.put(id, v); + return v; + } + + public Vertex getVertex(long id){ + return allVertex.get(id); + } + + public void addEdge(long id1,long id2, int weight){ + Vertex vertex1 = null; + if(allVertex.containsKey(id1)){ + vertex1 = allVertex.get(id1); + }else{ + vertex1 = new Vertex(id1); + allVertex.put(id1, vertex1); + } + Vertex vertex2 = null; + if(allVertex.containsKey(id2)){ + vertex2 = allVertex.get(id2); + }else{ + vertex2 = new Vertex(id2); + allVertex.put(id2, vertex2); + } + + Edge edge = new Edge(vertex1,vertex2,isDirected,weight); + allEdges.add(edge); + vertex1.addAdjacentVertex(edge, vertex2); + if(!isDirected){ + vertex2.addAdjacentVertex(edge, vertex1); + } + + } + + public List> getAllEdges(){ + return allEdges; + } + + public Collection> getAllVertex(){ + return allVertex.values(); + } + public void setDataForVertex(long id, T data){ + if(allVertex.containsKey(id)){ + Vertex vertex = allVertex.get(id); + vertex.setData(data); + } + } + + @Override + public String toString(){ + StringBuffer buffer = new StringBuffer(); + for(Edge edge : getAllEdges()){ + buffer.append(edge.getVertex1() + " " + edge.getVertex2() + " " + edge.getWeight()); + buffer.append("\n"); + } + return buffer.toString(); + } +} + + +class Vertex { + long id; + private T data; + private List> edges = new ArrayList<>(); + private List> adjacentVertex = new ArrayList<>(); + + Vertex(long id){ + this.id = id; + } + + public long getId(){ + return id; + } + + public void setData(T data){ + this.data = data; + } + + public T getData(){ + return data; + } + + public void addAdjacentVertex(Edge e, Vertex v){ + edges.add(e); + adjacentVertex.add(v); + } + + public String toString(){ + return String.valueOf(id); + } + + public List> getAdjacentVertexes(){ + return adjacentVertex; + } + + public List> getEdges(){ + return edges; + } + + public int getDegree(){ + return edges.size(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (int) (id ^ (id >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Vertex other = (Vertex) obj; + if (id != other.id) + return false; + return true; + } +} + +class Edge{ + private boolean isDirected = false; + private Vertex vertex1; + private Vertex vertex2; + private int weight; + + Edge(Vertex vertex1, Vertex vertex2){ + this.vertex1 = vertex1; + this.vertex2 = vertex2; + } + + Edge(Vertex vertex1, Vertex vertex2,boolean isDirected,int weight){ + this.vertex1 = vertex1; + this.vertex2 = vertex2; + this.weight = weight; + this.isDirected = isDirected; + } + + Edge(Vertex vertex1, Vertex vertex2,boolean isDirected){ + this.vertex1 = vertex1; + this.vertex2 = vertex2; + this.isDirected = isDirected; + } + + Vertex getVertex1(){ + return vertex1; + } + + Vertex getVertex2(){ + return vertex2; + } + + int getWeight(){ + return weight; + } + + public boolean isDirected(){ + return isDirected; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((vertex1 == null) ? 0 : vertex1.hashCode()); + result = prime * result + ((vertex2 == null) ? 0 : vertex2.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Edge other = (Edge) obj; + if (vertex1 == null) { + if (other.vertex1 != null) + return false; + } else if (!vertex1.equals(other.vertex1)) + return false; + if (vertex2 == null) { + if (other.vertex2 != null) + return false; + } else if (!vertex2.equals(other.vertex2)) + return false; + return true; + } + + @Override + public String toString() { + return "Edge [isDirected=" + isDirected + ", vertex1=" + vertex1 + + ", vertex2=" + vertex2 + ", weight=" + weight + "]"; + } +} + + \ No newline at end of file diff --git a/src/graph/topologicalsort/TopologicalSort.java b/src/graph/topologicalsort/TopologicalSort.java new file mode 100644 index 0000000..502109b --- /dev/null +++ b/src/graph/topologicalsort/TopologicalSort.java @@ -0,0 +1,51 @@ +package topologicalsort; + +import java.util.HashSet; +import java.util.Set; +import java.util.Stack; + +/** + * Space and time complexity is O(n). + */ +public class TopologicalSort { + + public Stack> topologicalSort(Graph graph) { + Stack> stack = new Stack<>(); + Set> visited = new HashSet<>(); + + for (Vertex vertex : graph.getAllVertex()) { + if (!visited.contains(vertex)) { + topSortUtil(stack, visited, vertex); + } + } + return stack; + } + + private void topSortUtil(Stack> stack, Set> visited, Vertex vertex) { + visited.add(vertex); + for (Vertex vert : vertex.getAdjacentVertexes()) { + if (!visited.contains(vert)) { + topSortUtil(stack, visited, vert); + } + } + stack.add(vertex); + } + + public static void main(String args[]) { + Graph graph = new Graph<>(true); + graph.addEdge(1, 3); + graph.addEdge(1, 2); + graph.addEdge(3, 4); + graph.addEdge(5, 6); + graph.addEdge(6, 3); + graph.addEdge(3, 8); + graph.addEdge(8, 11); + graph.addEdge(5, 3); + + TopologicalSort sort = new TopologicalSort<>(); + Stack> result = sort.topologicalSort(graph); + while (!result.isEmpty()) { + System.out.println(result.pop()); + } + } +} \ No newline at end of file diff --git a/src/graph/topologicalsort/TopologicalSortList.java b/src/graph/topologicalsort/TopologicalSortList.java new file mode 100644 index 0000000..046bb99 --- /dev/null +++ b/src/graph/topologicalsort/TopologicalSortList.java @@ -0,0 +1,65 @@ +package topologicalsort; + +import java.util.LinkedList; +import java.util.List; +import java.util.Stack; + +public class TopologicalSortList { + + class Graph { + List adjacentList[]; + int vertices; + + public Graph(int vertices) { + this.vertices = vertices; + adjacentList = new LinkedList[vertices]; + + for (int i = 0; i < vertices; i++) { + adjacentList[i] = new LinkedList(); + } + } + } + + public static void main(String[] args) { + TopologicalSortList ts = new TopologicalSortList(); + Graph graph = ts.new Graph(8); + ts.addEdge(0, 2, graph); + ts.addEdge(1, 2, graph); + ts.addEdge(1, 3, graph); + ts.addEdge(2, 4, graph); + ts.addEdge(4, 5, graph); + ts.addEdge(4, 7, graph); + ts.addEdge(5, 6, graph); + + Stack stack = new Stack(); + Stack visited = new Stack(); + + for (int i = 0; i < graph.vertices; i++) { + if (!visited.contains(i)) + ts.topologicalSort(graph, i, stack, visited); + } + + stack.forEach(System.out::println); + } + + private void topologicalSort(Graph graph, int i, Stack stack, Stack visited) { + if (visited.contains(i)) { + return; + } + visited.push(i); + List list = graph.adjacentList[i]; + if (list.isEmpty()) { + stack.push(i); + } + for (Integer node : list) { + topologicalSort(graph, node, stack, visited); + } + if (!list.isEmpty()) { + stack.push(i); + } + } + + private void addEdge(int i, int j, Graph graph) { + graph.adjacentList[i].add(j); + } +} diff --git a/src/microsoftassesment/AutocompleteSystem.java b/src/microsoftassesment/AutocompleteSystem.java new file mode 100644 index 0000000..3036215 --- /dev/null +++ b/src/microsoftassesment/AutocompleteSystem.java @@ -0,0 +1,33 @@ +package microsoftassesment; + +import java.util.*; +import java.util.stream.Collectors; + +class AutocompleteSystem { + private final Map cache = new HashMap<>(); + private String input = ""; + + public AutocompleteSystem(String[] sentences, int[] times) { + for (int i = 0; i < sentences.length; i++) { + cache.put(sentences[i], times[i]); + } + } + + public List input(char c) { + if (c == '#') { + Integer count = cache.getOrDefault(input, 0); + cache.put(input, ++count); + input = ""; + return Collections.emptyList(); + } + + input += c; + return cache.entrySet().stream() + .filter(e -> e.getKey().startsWith(input)) + .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()) + .thenComparing(Map.Entry.comparingByKey())) + .limit(3) + .map(Map.Entry::getKey) + .collect(Collectors.toCollection(ArrayList::new)); + } +} diff --git a/src/microsoftassesment/CropWords.java b/src/microsoftassesment/CropWords.java new file mode 100644 index 0000000..31c8cac --- /dev/null +++ b/src/microsoftassesment/CropWords.java @@ -0,0 +1,55 @@ +package microsoftassesment; + +public class CropWords { + + public static String cropWords(String message, int K){ + if (message == null || message.length() == 0){ + return ""; + } + // k greater than string, we return as it is; + if (message.length() <= K){ + return trim(message); + } + // we split at some point and move back wards till we meet a space, so that we can confirm that result has whole words only, then trim removes the space + StringBuilder sb = new StringBuilder(message.substring(0, K+1)); + while(sb.length() > 0 && sb.charAt(sb.length() - 1) != ' '){ + sb.deleteCharAt(sb.length() - 1); + } + + return trim(sb.toString()); + } + + private static String trim(String message){ + int i = message.length() - 1; + if (message.charAt(i) == ' '){ + while(i >= 0 && message.charAt(i) == ' '){ + i--; + } + if (i < 0){ + return ""; + } + return message.substring(0, i+1); + } + + + return message; + } + + public static void main(String[] args){ + System.out.println(cropWords("codility We test coders", 14).equals("codility We"));// === "codility We" + System.out.println(cropWords(" co de my", 5).equals(" co"));// === " co" + System.out.println(cropWords(" co de my", 7).equals(" co de"));// === " co de" + System.out.println(cropWords(" ", 2).equals(""));// === "" + System.out.println(cropWords(" re", 2).equals(""));// === "") //3 spaces before + System.out.println(cropWords(" c ", 3).equals(" c"));// === " c" + System.out.println(cropWords(" c d ", 5).equals(" c d"));// === " c d" + System.out.println(cropWords("co de my", 5).equals("co de"));// === "co de" + System.out.println(cropWords("Word", 4).equals("Word"));// === "Word" + System.out.println(cropWords("codility We test coders", 23).equals("codility We test coders"));// === "codility We test coders" + System.out.println(cropWords("withOutSpaces", 14).equals("withOutSpaces"));// === "withOutSpaces" + System.out.println(cropWords("", 14).equals(""));// === "" + System.out.println(cropWords("Separatedby hyphens", 14).equals("Separatedby"));// === "Separatedby" + System.out.println(cropWords(" Codility We test coders ", 14).equals(" Codility"));// === " Codility") //6 leading spaces + System.out.println(cropWords(" Codility We test coders ", 10).equals(""));// === "") //6 leading spaces + } +} diff --git a/src/microsoftassesment/DLLNode.java b/src/microsoftassesment/DLLNode.java new file mode 100644 index 0000000..9efbda4 --- /dev/null +++ b/src/microsoftassesment/DLLNode.java @@ -0,0 +1,180 @@ +package microsoftassesment; + +import java.util.HashMap; +import java.util.Map; + + class LFUCacahe { + /*.*/ + /* + * @param capacity: total capacity of LFU Cache + * @param curSize: current size of LFU cache + * @param minFrequency: frequency of the last linked list (the minimum frequency of entire LFU cache) + * @param cache: a hash map that has key to Node mapping, which used for storing all nodes by their keys + * @param frequencyMap: a hash map that has key to linked list mapping, which used for storing all + * double linked list by their frequencies + * */ + + + final int capacity; + int curSize; + int minFrequency; + Map cache; + Map frequencyMap; + + public LFUCacahe(int capacity) { + + this.capacity = capacity; + this.curSize = 0; + this.minFrequency = 0; + + this.cache = new HashMap<>(); + this.frequencyMap = new HashMap<>(); + } + + /** + * get node value by key, and then update node frequency as well as relocate that node + **/ + public int get(int key) { + DLLNode curNode = cache.get(key); + if (curNode == null) { + return -1; + } + updateNode(curNode); + return curNode.val; + } + + /** + * add new node into LFU cache, as well as double linked list + * condition 1: if LFU cache has input key, update node value and node position in list + * condition 2: if LFU cache does NOT have input key + * - sub condition 1: if LFU cache does NOT have enough space, remove the Least Recent Used node + * in minimum frequency list, then add new node + * - sub condition 2: if LFU cache has enough space, add new node directly + **/ + public void put(int key, int value) { + // corner case: check cache capacity initialization + if (capacity == 0) { + return; + } + + if (cache.containsKey(key)) { + DLLNode curNode = cache.get(key); + curNode.val = value; + updateNode(curNode); + } else { + curSize++; + if (curSize > capacity) { + // get minimum frequency list + DoubleLinkedList minFreqList = frequencyMap.get(minFrequency); + DLLNode deleteNode = minFreqList.removeTail(); + cache.remove(deleteNode.key); + curSize--; + } + // reset min frequency to 1 because of adding new node + minFrequency = 1; + DLLNode newNode = new DLLNode(key, value); + + // get the list with frequency 1, and then add new node into the list, as well as into LFU cache + DoubleLinkedList curList = frequencyMap.getOrDefault(1, new DoubleLinkedList()); + curList.addNode(newNode); + frequencyMap.put(1, curList); + cache.put(key, newNode); + } + } + + public void updateNode(DLLNode curNode) { + int curFreq = curNode.frequency; + DoubleLinkedList curList = frequencyMap.get(curFreq); + curList.removeNode(curNode); + + // if current list the the last list which has lowest frequency and current node is the only node in that list + // we need to remove the entire list and then increase min frequency value by 1 + if (curFreq == minFrequency && curList.listSize == 0) { + minFrequency++; + } + + curNode.frequency++; + // add current node to another list has current frequency + 1, + // if we do not have the list with this frequency, initialize it + DoubleLinkedList newList = frequencyMap.getOrDefault(curNode.frequency, new DoubleLinkedList()); + newList.addNode(curNode); + frequencyMap.put(curNode.frequency, newList); + } + + /* + * @param key: node key + * @param val: node value + * @param frequency: frequency count of current node + * (all nodes connected in same double linked list has same frequency) + * @param prev: previous pointer of current node + * @param next: next pointer of current node + * */ + public class DLLNode { + int key; + int val; + int frequency; + DLLNode prev; + DLLNode next; + + public DLLNode(int key, int val) { + this.key = key; + this.val = val; + this.frequency = 1; + } + } + + /* + * @param listSize: current size of double linked list + * @param head: head node of double linked list + * @param tail: tail node of double linked list + * */ + class DoubleLinkedList { + int listSize; + DLLNode head; + DLLNode tail; + + public DoubleLinkedList() { + this.listSize = 0; + this.head = new DLLNode(0, 0); + this.tail = new DLLNode(0, 0); + head.next = tail; + tail.prev = head; + } + + /** + * add new node into head of list and increase list size by 1 + **/ + public void addNode(DLLNode curNode) { + DLLNode nextNode = head.next; + curNode.next = nextNode; + curNode.prev = head; + head.next = curNode; + nextNode.prev = curNode; + listSize++; + } + + /** + * remove input node and decrease list size by 1 + **/ + public void removeNode(DLLNode curNode) { + DLLNode prevNode = curNode.prev; + DLLNode nextNode = curNode.next; + prevNode.next = nextNode; + nextNode.prev = prevNode; + listSize--; + } + + /** + * remove tail node + **/ + public DLLNode removeTail() { + // DO NOT FORGET to check list size + if (listSize > 0) { + DLLNode tailNode = tail.prev; + removeNode(tailNode); + return tailNode; + } + return null; + } + } + } \ No newline at end of file diff --git a/src/microsoftassesment/LexicographicallySmallest.java b/src/microsoftassesment/LexicographicallySmallest.java new file mode 100644 index 0000000..33827e3 --- /dev/null +++ b/src/microsoftassesment/LexicographicallySmallest.java @@ -0,0 +1,52 @@ +package microsoftassesment; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.LinkedList; + +//Lexicographically smallest string formed by removing at most one character. +// +// Example 1: +// +// Input: "abczd" +// Output: "abcd" + +public class LexicographicallySmallest { + + public String lexSmaller(String s){ + if(s==null || s.length()==0) return ""; + + Deque queue= new ArrayDeque<>(); + int k=1; + for(char c: s.toCharArray()){ + // k=1; + while (!queue.isEmpty() && queue.getLast()>=c && k>0){ + queue.removeLast(); + k--; + } + queue.addLast(c); + } + + StringBuilder sb= new StringBuilder(); + while (!queue.isEmpty()){ + sb.append(queue.removeFirst()); + } + + return sb.toString(); + } + + public String lexBuilder(String s ){ + StringBuilder str = new StringBuilder(s); + int i=0; + for(i=0; istr.charAt(i+1)){ + break; + } + } + + return str.deleteCharAt(i).toString(); + } + public static void main(String[] args) { + System.out.println(new LexicographicallySmallest().lexSmaller("abcde")); + } +} diff --git a/src/microsoftassesment/LongestSubStringWithout3ContiguousLetter.java b/src/microsoftassesment/LongestSubStringWithout3ContiguousLetter.java new file mode 100644 index 0000000..489f083 --- /dev/null +++ b/src/microsoftassesment/LongestSubStringWithout3ContiguousLetter.java @@ -0,0 +1,99 @@ +package microsoftassesment; + +import java.util.HashMap; +import java.util.Map; + + +//Given a string s containing only a and b, find longest substring of s such that s does not contain more than two contiguous occurrences of a and b. +// +// Example 1: +// +// Input: "aabbaaaaabb" +// Output: "aabbaa" +public class LongestSubStringWithout3ContiguousLetter { + + public String validLongestSubstring(String s) { + if (s.length() < 3) + return s; + int cur = 0, // current starting pointer for current substring + end = 1; // the look-ahead pointer that's at the end of substring + char c = s.charAt(0); // current character/letter + int count = 1; // counter for same letter consecutive appearance + int maxLen = 1; // result + int start = 0; // anchor pointer for the result's starting index + + while (end < s.length()) { + if (s.charAt(end) == c) { // saw the same letter again + count ++; + + // valid enough to consider to be a part of the substring + if (count == 2) { + if (end - cur + 1 > maxLen) { // length of the current substring is greater than maxlen + maxLen = end - cur + 1; // the "+1" is to include the full substring length + start = cur; // override to be the current maxlen's start index + } + } + else { + cur = end - 1; // count > 2 whenever we see 3 consec element, move the curr , therefore we need to start a new substring; reset curr + } + } + else { + c = s.charAt(end); // diff char/letter found; reset current char + count = 1; // reset same letter consecutive appearance counter + if (end - cur + 1 > maxLen) { // length of the current substring is greater than maxlen + maxLen = end - cur + 1; + start = cur; + } + } + end ++; + } + return s.substring(start, start + maxLen); + } + + public String slidingWindowPattern(String s){ + if(s==null) return null; + Map map= new HashMap<>(); + int left=0; + int right=0; + int count=0; + int start=0; + int result=0; + int end=0; + while(left=3){ + count++; + } + + while(count>0 ){ + char rightchar=s.charAt(right); + map.put(rightchar,map.getOrDefault(right,1)-1); + if(map.get(temp)<=2) count--; + right++; + //count--; + } + + if(result3 .... 4,3,3,2,1,1 -numdelete =1; +// i=2 +// freq[2]==freq1 so reduce freq[2]->2...4,3,2,2,1,1 numdelete=2; +// +// i=3 +// proceeding in a similar fashion the array would be 4.3.2,1,1,1 numdelete=3; +// +// i=4 +// 4,3,2,1,0,1 numdelete=4 +// +// i=5 +// we cannot have a frequency lesser than 0 ... it means that we would have to effectively delete that character making its frequency 0 +// 4,3,2,1,0,0 numdelete =5 +// +// and that's the solution + + + public int minDeletions(String str) { + Integer[] freqOfLetter; + // String str="qqqsaaaaadddddfafaafafeqqq"; + freqOfLetter = new Integer[26]; + + Arrays.fill(freqOfLetter,0); + + char[] s=str.toCharArray(); + for (int i = 0; i < s.length; i++) + { + freqOfLetter[s[i] - 'a']++; + } + + + int numDelete=0; + + Arrays.sort(freqOfLetter, Collections.reverseOrder()); + + for(int i=1;i=freqOfLetter[i-1]) { + if(freqOfLetter[i-1]==0) { + numDelete += freqOfLetter[i]; + freqOfLetter[i]=0; + } + else { + numDelete += freqOfLetter[i] - freqOfLetter[i - 1] + 1; + + freqOfLetter[i] = freqOfLetter[i - 1] - 1; + } + } + } + return numDelete; + } + + public static void main(String[] args) { + MinDeletionToMakeUniqueCount m = new MinDeletionToMakeUniqueCount(); + String[] testCases = new String[] {"qqqsaaaaadddddfafaafafeqqq", "aaaabbbb", "aabbbbcccdddd", "aaaaaabbbbbccccddddeeeeee", "abcdefghijkl", "aaaaaa", "aabbffddeaee", "llll", "example"}; + for (String test : testCases) System.out.println(test + ": " + m.minDeletions(test)); + } +} diff --git a/src/microsoftassesment/MinStepsToMakePileSameHeight.java b/src/microsoftassesment/MinStepsToMakePileSameHeight.java new file mode 100644 index 0000000..19241c5 --- /dev/null +++ b/src/microsoftassesment/MinStepsToMakePileSameHeight.java @@ -0,0 +1,47 @@ +package microsoftassesment; + +import java.util.Arrays; + +/** + * Alexa is given n piles of equal or unequal heights. In one step, Alexa can remove any number of boxes from the pile which has the maximum height and try to make it equal to the one which is just lower than the maximum height of the stack. + * Determine the minimum number of steps required to make all of the piles equal in height. + * + * Input: piles = [5, 2, 1] + * Output: 3 + * Explanation: + * Step 1: reducing 5 -> 2 [2, 2, 1] + * Step 2: reducing 2 -> 1 [2, 1, 1] + * Step 3: reducing 2 -> 1 [1, 1, 1] + * So final number of steps required is 3. + */ +public class MinStepsToMakePileSameHeight { + + public int minSteps(int[]arr){ + int result=0; + int distinctNumbers=0; + Arrays.sort(arr); + //1,2,5 + for(int i=1;i 1 != 2, i=2 => 2!=5 + distinctNumbers++; // else increase the distance count + } + + result+=distinctNumbers; // even if elements are same, we need to add it to result + } + return result; + } + + public static void main(String[] args) { + int[][] tests= new int[][]{ + {1, 2, 2, 2, 3, 4, 5, 6, 4, 12, 4}, + {1, 2, 3}, + {1, 2, 5}, + {1, 2, 3, 4, 5}}; + + for(int[] test: tests){ + System.out.println(new MinStepsToMakePileSameHeight().minSteps(test)); + } + } + + +} diff --git a/src/microsoftassesment/MinSwapsToGroupRedBalls.java b/src/microsoftassesment/MinSwapsToGroupRedBalls.java new file mode 100644 index 0000000..f2a7a7c --- /dev/null +++ b/src/microsoftassesment/MinSwapsToGroupRedBalls.java @@ -0,0 +1,36 @@ +package microsoftassesment; + +import java.util.ArrayList; +import java.util.List; + +public class MinSwapsToGroupRedBalls { + + public int solution(String s) { + List redIndices = getRedIndices(s); + int mid = redIndices.size() / 2; + int minSwaps = 0; + for (int i = 0; i < redIndices.size(); i++) { + // number of swaps for each R is the distance to mid, minus the number of R's between them + minSwaps += Math.abs(redIndices.get(mid) - redIndices.get(i)) - Math.abs(mid - i); + + } + return minSwaps; + } + + private static List getRedIndices(String s) { + List indices = new ArrayList<>(s.length()); + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == 'R') { + indices.add(i); + } + } + return indices; + } + + public static void main(String[] args) { + String[] inputs= new String[] { "RRRWRR", "WRRWWR", "WWRWWWRWR", "WWW"}; + for(String input: inputs){ + System.out.println(input+" - "+new MinSwapsToGroupRedBalls().solution(input)); + } + } +} diff --git a/src/microsoftassesment/NumsWithEqualDigitSum.java b/src/microsoftassesment/NumsWithEqualDigitSum.java new file mode 100644 index 0000000..a2ff812 --- /dev/null +++ b/src/microsoftassesment/NumsWithEqualDigitSum.java @@ -0,0 +1,87 @@ +package microsoftassesment; + +import java.util.*; + +class Pair{ + String value; + int digitSum; + + public Pair(String value, int digitSum) { + this.value = value; + this.digitSum = digitSum; + } +} + +public class NumsWithEqualDigitSum { + + // given an array of integers, return max sum of 2 values whose digits adds up to same value + // [51,71,17,42] => 93 (51+42)=>(5+1==4+2) + // [42,33,60] => 102 (42+60)=> (4+2== 6+0) + + public int findMaxSumWithEqualDigits(int[] nums){ + if(nums==null || nums.length==0) return 0; + List inputs= new ArrayList<>(); + for (int i = 0; i < nums.length; i++) { + int sum=0; + int val=nums[i]; + while(val>0){ + sum+=val%10; + val/=10; + } + inputs.add(new Pair(String.valueOf(nums[i]),sum)); + } + PriorityQueue queue= new PriorityQueue<>((a,b)->Integer.compare(a.digitSum,b.digitSum)); + + int result=0; + queue.addAll(inputs); + while (!queue.isEmpty()){ + Pair first=queue.poll(); + if(queue.isEmpty()) break; + Pair second= queue.peek(); + if(first.digitSum==second.digitSum){ + second=queue.poll(); + result= Math.max(result, Integer.parseInt(first.value)+Integer.parseInt(second.value)); + queue.offer(new Pair(String.valueOf(Math.max(Integer.parseInt(first.value),Integer.parseInt(second.value))),first.digitSum)); + } + } + return result; + } + + public static void main(String[] args) { + System.out.println(new NumsWithEqualDigitSum().findMaxSumWithEqualDigits(new int[]{51,71,17,42})); + System.out.println(new NumsWithEqualDigitSum().findMaxSumWithEqualDigits(new int[]{42,33,60})); + System.out.println(new NumsWithEqualDigitSum().findMaxSumWithEqualDigits( new int[] {2053, 280, 780, 505, 690, 730, 4730, 951, 8331, 5079, 7252, 3675, 8969, 6904, 1194})); + System.out.println(new NumsWithEqualDigitSum().findMaxSumWithEqualDigits( new int[] {2053, 280, 780, 505, 690, 730, 4730, 951, 8331, 5079, 7252, 3675, 8969, 6904, 1194})); + //[2053, 280, 780, 505, 690, 730, 4730, 951, 8331, 5079, 7252, 3675, 8969, 6904, 1194] + + } + + + private int computeDigitSum(int a){ + // supposed to be valid for negative numbers and the output must be non-negative integer. + a = Math.abs(a); + int res = 0; + while(a > 0){ + res += a % 10; + a /= 10; + } + return res; + } + public int maxSum(int[] A){ + int N = A.length; + if(N <= 1) return -1; + Map map = new HashMap<>(); + int res = -1; + for(int i = 0; i < N; ++i){ + int digitsum = computeDigitSum(A[i]); + if(!map.containsKey(digitsum)){ + map.put(digitsum, A[i]); + } + else{ + res = Math.max(res, map.get(digitsum) + A[i]); + map.put(digitsum, Math.max(A[i], map.get(digitsum))); + } + } + return res; + } +} diff --git a/src/microsoftassesment/RemoveCharsMoreThanKOccurrence.java b/src/microsoftassesment/RemoveCharsMoreThanKOccurrence.java new file mode 100644 index 0000000..8bc8b25 --- /dev/null +++ b/src/microsoftassesment/RemoveCharsMoreThanKOccurrence.java @@ -0,0 +1,55 @@ +package microsoftassesment; + + +// given eedaaad and k=3 return eedaad +public class RemoveCharsMoreThanKOccurrence { + + public static String removeKConsequtiveChars(String s, int k){ + if(s==null || s.length()==0) return null; + StringBuilder sb = new StringBuilder(); + sb.append(s.charAt(0)); + int cnt = 1; + for(int r=1;r snake; + LinkedList queue; + /** Initialize your data structure here. + @param width - screen width + @param height - screen height + @param food - A list of food positions + E.g food = [[1,1], [1,0]] means the first food is positioned at [1,1], the second is at [1,0]. */ + public SnakeGame(int width, int height, int[][] food) { + this.food=food; + snake = new HashSet(); + eaten = 0; + headX =0; + headY =0; + m = height; + n = width; + queue= new LinkedList(); + queue.offer(new int[]{0, 0}); + snake.add("0,0"); + } + + /** Moves the snake. + @param direction - 'U' = Up, 'L' = Left, 'R' = Right, 'D' = Down + @return The game's score after the move. Return -1 if game over. + Game over when snake crosses the screen boundary or bites its body. */ + public int move(String direction) { + if (direction.equals("U")) { + headX --; + } + else if (direction.equals("L")) { + headY --; + } + else if (direction.equals("R")) { + headY ++; + } + else if (direction.equals("D")) { + headX ++; + } + else { + System.out.println("Wrong move"); + } + + if(!isValid(headX,headY)){ + return -1; + } + + return process(headX, headY); + } + + public boolean isValid(int i, int j){ + if(i < 0 || i >= m || j < 0 || j >= n) + return false; + return true; + } + + public int process(int x, int y){ + if(eaten == food.length){ + snake.remove(queue.peek()[0] + "," + queue.peek()[1]); + queue.poll(); + }else if(food[eaten][0]==x && food[eaten][1]==y){ + eaten ++; + }else{ + snake.remove(queue.peek()[0] + "," + queue.peek()[1]); + queue.poll(); + } + + if (snake.contains(x + "," + y)) { + return -1; + } + + snake.add(x + "," + y); + queue.offer(new int[]{x,y}); + + return eaten; + } +} \ No newline at end of file diff --git a/src/microsoftassesment/StringWithout3ConsequitiveLetter.java b/src/microsoftassesment/StringWithout3ConsequitiveLetter.java new file mode 100644 index 0000000..7856443 --- /dev/null +++ b/src/microsoftassesment/StringWithout3ConsequitiveLetter.java @@ -0,0 +1,34 @@ +package microsoftassesment; + +public class StringWithout3ConsequitiveLetter { + + // Minimum number of swaps to make string without any instance of 3 contiguous identical letters, swaps permitted a transforms to b and vice versa + public int solution(String s) { + + + // Corner Cases: s === null, s.length < 3 - return 0 + + // Observations: for consecutive letter lengths divisible by 3 exactly, replace middle + // if in between lengths from numbers divisible by 3, then replace the position in the divisible by 3 position + // e.g. 3 consecutive - replace middle, 4 cons. - replace 3rd, 5 cons. - replace 3rd + // 6 cons. - turns back in the 3 cons. case, therefore, replace middle + + // Time Complexity: O(n) + // Space Complexity: O(1) + + if (s == null || s.length() < 3) { + return 0; + } + int moves = 0; + for (int i = 0 ; i < s.length(); i++) { + int runLength = 1; + for (; i + 1 < s.length() && s.charAt(i) == s.charAt(i + 1); i++) { + runLength++; + } + moves += runLength / 3; + } + return moves; + } + + +} diff --git a/src/multithreading/barberProblem/Barber.java b/src/multithreading/barberProblem/Barber.java new file mode 100755 index 0000000..b887a3c --- /dev/null +++ b/src/multithreading/barberProblem/Barber.java @@ -0,0 +1,28 @@ +package barberProblem; + +import java.util.concurrent.atomic.AtomicInteger; + +public class Barber implements Runnable { + private AtomicInteger id=null; + private final WaitingRoom waitingRoom; + + public Barber(WaitingRoom waitingRoom, AtomicInteger id) { + this.waitingRoom = waitingRoom; + this.id=id; + } + + @Override + public void run() { + try { + while (true) { + Customer customer = waitingRoom.nextCustomer(); + + System.out.println("barber "+ id+" called and shaven customer " + customer); + customer.callAndShave(); + } + + } catch (InterruptedException e) { + System.out.println("barber has finished his job"); + } + } +} diff --git a/src/multithreading/barberProblem/Customer.java b/src/multithreading/barberProblem/Customer.java new file mode 100755 index 0000000..0856fef --- /dev/null +++ b/src/multithreading/barberProblem/Customer.java @@ -0,0 +1,55 @@ +package barberProblem; + +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.atomic.AtomicInteger; + +public class Customer implements Runnable { + + private static final AtomicInteger idGenerator = new AtomicInteger(); + + private final int id; + + private final WaitingRoom waitingRoom; + + private final SynchronousQueue synchronousQueue; + + private volatile boolean shaved; + + public Customer(WaitingRoom waitingRoom) { + this.id = idGenerator.incrementAndGet(); + this.waitingRoom = waitingRoom; + this.synchronousQueue = new SynchronousQueue<>(); + } + + @Override + public void run() { + try { + waitingRoom.takeASeat(this); + + System.out.println("customer " + this + " wait to be called and shaved"); + waitToBeCalledAndShaved(); + + shaved = true; + + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void callAndShave() throws InterruptedException { + synchronousQueue.put(true); + } + + public void waitToBeCalledAndShaved() throws InterruptedException { + synchronousQueue.take(); + } + + public boolean isShaved() { + return shaved; + } + + @Override + public String toString() { + return Integer.toString(id); + } +} diff --git a/src/multithreading/barberProblem/Main.java b/src/multithreading/barberProblem/Main.java new file mode 100755 index 0000000..5b97b90 --- /dev/null +++ b/src/multithreading/barberProblem/Main.java @@ -0,0 +1,37 @@ +package barberProblem; + +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Stream; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.stream.Collectors.toList; + +public class Main { + + public static void main(String[] args) throws InterruptedException { + WaitingRoom waitingRoom = new WaitingRoom(10); + + ExecutorService executorService = Executors.newFixedThreadPool(100); + executorService.submit(new Barber(waitingRoom, new AtomicInteger(0))); + executorService.submit(new Barber(waitingRoom, new AtomicInteger(1))); + executorService.submit(new Barber(waitingRoom, new AtomicInteger(2))); + + List customers = Stream.generate(() -> new Customer(waitingRoom)) + .limit(100) + .peek(executorService::submit) + .collect(toList()); + + while (!customers.stream().allMatch(Customer::isShaved)) { + TimeUnit.SECONDS.sleep(1); + } + + System.out.println("all customers have been shaved"); + executorService.shutdownNow(); + executorService.awaitTermination(1, MINUTES); + } + +} diff --git a/src/multithreading/barberProblem/WaitingRoom.java b/src/multithreading/barberProblem/WaitingRoom.java new file mode 100755 index 0000000..0ea018c --- /dev/null +++ b/src/multithreading/barberProblem/WaitingRoom.java @@ -0,0 +1,21 @@ +package barberProblem; + +import java.util.concurrent.ArrayBlockingQueue; + +public class WaitingRoom { + + private final ArrayBlockingQueue waitingCustomers; + + public WaitingRoom(int capacity) { + waitingCustomers = new ArrayBlockingQueue<>(capacity); + } + + public void takeASeat(Customer customer) throws InterruptedException { + waitingCustomers.put(customer); + } + + public Customer nextCustomer() throws InterruptedException { + return waitingCustomers.take(); + } + +} diff --git a/src/multithreading/com/safecabs/Constants.java b/src/multithreading/com/safecabs/Constants.java new file mode 100644 index 0000000..ca68843 --- /dev/null +++ b/src/multithreading/com/safecabs/Constants.java @@ -0,0 +1,6 @@ +package com.safecabs; + +public class Constants { + public static int CAB_CAPACITY = 4; + public static int HALF_CAB_CAPACITY = CAB_CAPACITY/2; +} diff --git a/src/multithreading/com/safecabs/Gender.java b/src/multithreading/com/safecabs/Gender.java new file mode 100644 index 0000000..93d0ae8 --- /dev/null +++ b/src/multithreading/com/safecabs/Gender.java @@ -0,0 +1,7 @@ +package com.safecabs; + +public enum Gender { + MALE, + FEMALE; + /* OTHERS - not relavent for requirement*/ +} diff --git a/src/multithreading/com/safecabs/app/AssignCab.java b/src/multithreading/com/safecabs/app/AssignCab.java new file mode 100644 index 0000000..6536141 --- /dev/null +++ b/src/multithreading/com/safecabs/app/AssignCab.java @@ -0,0 +1,30 @@ +package com.safecabs.app; + +import com.safecabs.cab.Cab; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.Callable; + +public class AssignCab implements Callable { + + private ArrayBlockingQueue cabQueue; + + public AssignCab(ArrayBlockingQueue cabQueue) { + this.cabQueue = cabQueue; + } + + public Integer call() { + while (cabQueue.isEmpty()) { + try { + //All the cab requests should wait until a new cab appears + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + Cab assignedCab = cabQueue.poll(); + System.out.println("Assigned cab " + assignedCab.getId()); + return assignedCab.getId(); + } + +} diff --git a/src/multithreading/com/safecabs/app/CabProvider.java b/src/multithreading/com/safecabs/app/CabProvider.java new file mode 100644 index 0000000..ad496ec --- /dev/null +++ b/src/multithreading/com/safecabs/app/CabProvider.java @@ -0,0 +1,42 @@ +package com.safecabs.app; + +import com.safecabs.Constants; +import com.safecabs.cab.Cab; +import com.safecabs.exceptions.UnRegisteredPassengerException; +import com.safecabs.passenger.Passenger; +import com.safecabs.passenger.RegisteredPassenger; + +import java.util.concurrent.ArrayBlockingQueue; + +public class CabProvider { + + private RegisteredPassenger registeredPassenger; + + private ArrayBlockingQueue cabQueue = new ArrayBlockingQueue<>(10); + + CustomCyclicBarrier customCyclicBarrier = new CustomCyclicBarrier(Constants.CAB_CAPACITY, new AssignCab(cabQueue)); + + public CabProvider(RegisteredPassenger registeredPassenger){ + + this.registeredPassenger = registeredPassenger; + } + + public void requestCab(Passenger passenger) throws UnRegisteredPassengerException { + if(registeredPassenger.isRegistered(passenger)) { + provideCab(passenger); + }else{ + throw new UnRegisteredPassengerException("Passenger "+passenger.getId()+" is not registered"); + } + } + + public void addNewAvailableCab(Cab cab) { + //The Cab which is available first should move first, so adding to Queue + cabQueue.add(cab); + } + + public void provideCab(Passenger passenger) { + CabRequest cabRequest = new CabRequest(customCyclicBarrier, passenger); + cabRequest.start(); + } + +} diff --git a/src/multithreading/com/safecabs/app/CabRequest.java b/src/multithreading/com/safecabs/app/CabRequest.java new file mode 100644 index 0000000..49b3ec8 --- /dev/null +++ b/src/multithreading/com/safecabs/app/CabRequest.java @@ -0,0 +1,30 @@ +package com.safecabs.app; + +import com.safecabs.passenger.Passenger; + +public class CabRequest extends Thread { + + private Passenger passenger; + private CustomCyclicBarrier customCyclicBarrier; + + public CabRequest(CustomCyclicBarrier customCyclicBarrier, Passenger passenger) { + this.customCyclicBarrier = customCyclicBarrier; + this.passenger = passenger; + } + + @Override + public void run() { + try { + System.out.println("Passenger " + passenger.getId() + " requesting cab " + passenger.getGender()); + + customCyclicBarrier.await(passenger); + + System.out.println("Passenger " + passenger.getId() + " boarding Cab"); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/src/multithreading/com/safecabs/app/CustomCyclicBarrier.java b/src/multithreading/com/safecabs/app/CustomCyclicBarrier.java new file mode 100644 index 0000000..7b266b5 --- /dev/null +++ b/src/multithreading/com/safecabs/app/CustomCyclicBarrier.java @@ -0,0 +1,91 @@ +package com.safecabs.app; + +import com.safecabs.Constants; +import com.safecabs.Gender; +import com.safecabs.passenger.Passenger; + +import java.util.concurrent.*; +import java.util.concurrent.locks.ReentrantLock; + +public class CustomCyclicBarrier { + + Callable requestToAssignCab; + int malePassengerRequestCount = 0; + int femalePassengerRequestCount = 0; + CyclicBarrier barrier; + Semaphore maleWaitSemaphore = new Semaphore(0); + Semaphore femaleWaitSemaphore = new Semaphore(0); + ReentrantLock lock = new ReentrantLock(); + + public CustomCyclicBarrier(int cabCapacity, Callable requestToAssignCab) { + this.requestToAssignCab = requestToAssignCab; // Allocate Cab Request once passengers are ready + barrier = new CyclicBarrier(cabCapacity); // wait till cab capacity full + } + + public void await(Passenger passenger) throws Exception { + if (passenger.getGender() == Gender.MALE) { + seatMale(); + } else { + seatFemale(); + } + } + + private void seatFemale() throws Exception { + + lock.lock(); + + boolean leaderThread = false; + femalePassengerRequestCount++; + + if (femalePassengerRequestCount == Constants.CAB_CAPACITY) { + System.out.println("All Female Condition Meet"); + femaleWaitSemaphore.release(Constants.CAB_CAPACITY - 1); + femalePassengerRequestCount -= Constants.CAB_CAPACITY; + leaderThread = true; + } else if (femalePassengerRequestCount == Constants.HALF_CAB_CAPACITY && malePassengerRequestCount >= Constants.HALF_CAB_CAPACITY) { + System.out.println(Constants.HALF_CAB_CAPACITY+" Female And "+Constants.HALF_CAB_CAPACITY+" Male Condition Meet"); + femaleWaitSemaphore.release(Constants.HALF_CAB_CAPACITY - 1); + maleWaitSemaphore.release(Constants.HALF_CAB_CAPACITY); + malePassengerRequestCount -= Constants.HALF_CAB_CAPACITY; + femalePassengerRequestCount -= Constants.HALF_CAB_CAPACITY; + leaderThread = true; + } else { + lock.unlock(); + femaleWaitSemaphore.acquire(); + } + if (leaderThread) { + requestToAssignCab.call(); + lock.unlock(); + } + barrier.await(); + } + + private void seatMale() throws Exception { + lock.lock(); + boolean leaderThread = false; + malePassengerRequestCount++; + + if (malePassengerRequestCount == Constants.CAB_CAPACITY) { + System.out.println("All Male Condition Meet"); + maleWaitSemaphore.release(Constants.CAB_CAPACITY - 1); + malePassengerRequestCount -= Constants.CAB_CAPACITY; + leaderThread = true; + } else if (malePassengerRequestCount == Constants.HALF_CAB_CAPACITY && femalePassengerRequestCount >= Constants.HALF_CAB_CAPACITY) { + System.out.println(Constants.HALF_CAB_CAPACITY+" Male and "+Constants.HALF_CAB_CAPACITY+" Female Condition Meet"); + maleWaitSemaphore.release(Constants.HALF_CAB_CAPACITY - 1); + femaleWaitSemaphore.release(Constants.HALF_CAB_CAPACITY); + malePassengerRequestCount -= Constants.HALF_CAB_CAPACITY; + femalePassengerRequestCount -= Constants.HALF_CAB_CAPACITY; + leaderThread = true; + } else { + lock.unlock(); + maleWaitSemaphore.acquire(); + } + if (leaderThread) { + requestToAssignCab.call(); + lock.unlock(); + } + barrier.await(); + + } +} diff --git a/src/multithreading/com/safecabs/cab/Cab.java b/src/multithreading/com/safecabs/cab/Cab.java new file mode 100644 index 0000000..377d506 --- /dev/null +++ b/src/multithreading/com/safecabs/cab/Cab.java @@ -0,0 +1,49 @@ +package com.safecabs.cab; + +import com.safecabs.Constants; + +import java.util.Date; + +public class Cab { + + int id; + + int CAPACITY = Constants.CAB_CAPACITY; + + Date availableFrom; + + /* + Not required for current requirement + + Vehicle cab; // Vehicle made, model, year + + Driver owner; + */ + + public Cab(int id) { + this.id = id; + availableFrom = new Date(); + } + + public Cab(int id, Date availableFrom) { + this.id = id; + this.availableFrom = availableFrom; + } + + public int getId() { + return id; + } + + public int getCAPACITY() { + return CAPACITY; + } + + public Date getAvailableFrom() { + return availableFrom; + } + + public void setAvailableFrom(Date availableFrom) { + this.availableFrom = availableFrom; + } + +} diff --git a/src/multithreading/com/safecabs/client/ClientTest.java b/src/multithreading/com/safecabs/client/ClientTest.java new file mode 100644 index 0000000..73669c0 --- /dev/null +++ b/src/multithreading/com/safecabs/client/ClientTest.java @@ -0,0 +1,38 @@ +package com.safecabs.client; + +import com.safecabs.Gender; +import com.safecabs.app.CabProvider; +import com.safecabs.cab.Cab; +import com.safecabs.exceptions.UnRegisteredPassengerException; +import com.safecabs.passenger.Passenger; +import com.safecabs.passenger.RegisteredPassenger; + +import java.util.Random; + +public class ClientTest { + public static void main(String args[]) throws Exception { + + RegisteredPassenger registeredPassenger = new RegisteredPassenger(); + CabProvider cabProvider = new CabProvider(registeredPassenger); + + int cabId = 1; + for (int passengerId = 0; passengerId < 21; passengerId++) { + int rand = new Random().nextInt(2); + + Passenger passenger = new Passenger(passengerId, rand == 0 ? Gender.MALE : Gender.FEMALE); + + if (passengerId != 5) + registeredPassenger.register(passenger); // Passenger 5 not registered for testing + try { + cabProvider.requestCab(passenger); + } catch (UnRegisteredPassengerException e) { + System.out.println(e.getMessage()); + } + if (passengerId % 4 == 0) + cabProvider.addNewAvailableCab(new Cab(cabId++)); + + Thread.sleep(1000); + } + } + +} diff --git a/src/multithreading/com/safecabs/exceptions/UnRegisteredPassengerException.java b/src/multithreading/com/safecabs/exceptions/UnRegisteredPassengerException.java new file mode 100644 index 0000000..38d0add --- /dev/null +++ b/src/multithreading/com/safecabs/exceptions/UnRegisteredPassengerException.java @@ -0,0 +1,8 @@ +package com.safecabs.exceptions; + +public class UnRegisteredPassengerException extends Exception { + + public UnRegisteredPassengerException(String s){ + super(s); + } +} diff --git a/src/multithreading/com/safecabs/passenger/Passenger.java b/src/multithreading/com/safecabs/passenger/Passenger.java new file mode 100644 index 0000000..cde2263 --- /dev/null +++ b/src/multithreading/com/safecabs/passenger/Passenger.java @@ -0,0 +1,23 @@ +package com.safecabs.passenger; + +import com.safecabs.Gender; + +public class Passenger { + + private int id; + private Gender gender; + + public Passenger(int id, Gender gender) { + this.id = id; + this.gender = gender; + } + + public int getId() { + return id; + } + + public Gender getGender() { + return gender; + } + +} diff --git a/src/multithreading/com/safecabs/passenger/RegisteredPassenger.java b/src/multithreading/com/safecabs/passenger/RegisteredPassenger.java new file mode 100644 index 0000000..0cefd5b --- /dev/null +++ b/src/multithreading/com/safecabs/passenger/RegisteredPassenger.java @@ -0,0 +1,24 @@ +package com.safecabs.passenger; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +public class RegisteredPassenger { + private ConcurrentMap registeredPassengers; + + public RegisteredPassenger() { + + registeredPassengers = new ConcurrentHashMap<>(); + } + + public void register(Passenger passenger) { + + registeredPassengers.put(passenger.getId(), passenger); + } + + public boolean isRegistered(Passenger passenger) { + + return registeredPassengers.containsKey(passenger.getId()); + } + +} diff --git a/src/multithreading/educative/BarberShopProblem.java b/src/multithreading/educative/BarberShopProblem.java new file mode 100644 index 0000000..d200042 --- /dev/null +++ b/src/multithreading/educative/BarberShopProblem.java @@ -0,0 +1,113 @@ +package educative; + +import java.util.HashSet; +import java.util.concurrent.Semaphore; +import java.util.concurrent.locks.ReentrantLock; + +public class BarberShopProblem { + + final int CHAIRS = 3; + Semaphore waitForCustomerToEnter = new Semaphore(0); + Semaphore waitForBarberToGetReady = new Semaphore(0); + Semaphore waitForCustomerToLeave = new Semaphore(0); + Semaphore waitForBarberToCutHair = new Semaphore(0); + int waitingCustomers = 0; + ReentrantLock lock = new ReentrantLock(); + int hairCutsGiven = 0; + + void barber() throws InterruptedException { + + while (true) { + waitForCustomerToEnter.acquire(); + waitForBarberToGetReady.release(); + hairCutsGiven++; + System.out.println("Barber cutting hair..." + hairCutsGiven); + Thread.sleep(50); + waitForBarberToCutHair.release(); + waitForCustomerToLeave.acquire(); + } + } + + void customerWalksIn() throws InterruptedException { + + lock.lock(); + if (waitingCustomers == CHAIRS) { + System.out.println("Customer walks out, all waiting waitForCustomerToEnter occupied"); + lock.unlock(); + return; + } + waitingCustomers++; + lock.unlock(); + + waitForCustomerToEnter.release(); + waitForBarberToGetReady.acquire(); + + lock.lock(); + waitingCustomers--; + lock.unlock(); + + waitForBarberToCutHair.acquire(); + waitForCustomerToLeave.release(); + } + + public static void runTest() throws InterruptedException { + + HashSet set = new HashSet(); + final BarberShopProblem barberShopProblem = new BarberShopProblem(); + + Thread barberThread = new Thread(new Runnable() { + public void run() { + try { + barberShopProblem.barber(); + } catch (InterruptedException ie) { + + } + } + }); + barberThread.start(); + + for (int i = 0; i < 10; i++) { + Thread t = new Thread(new Runnable() { + public void run() { + try { + barberShopProblem.customerWalksIn(); + } catch (InterruptedException ie) { + + } + } + }); + set.add(t); + } + + for (Thread t : set) { + t.start(); + } + + for (Thread t : set) { + t.join(); + } + + set.clear(); + Thread.sleep(800); + + for (int i = 0; i < 5; i++) { + Thread t = new Thread(new Runnable() { + public void run() { + try { + barberShopProblem.customerWalksIn(); + } catch (InterruptedException ie) { + + } + } + }); + set.add(t); + } + for (Thread t : set) { + t.start(); + } + + barberThread.join(); + } + + +} diff --git a/src/multithreading/educative/Barrier.java b/src/multithreading/educative/Barrier.java new file mode 100644 index 0000000..32571f4 --- /dev/null +++ b/src/multithreading/educative/Barrier.java @@ -0,0 +1,37 @@ +package educative; + +public class Barrier { + + int count = 0; + int released = 0; + int totalThreads; + + public Barrier(int totalThreads) { + this.totalThreads = totalThreads; + } + + public synchronized void await() throws InterruptedException { + + while (count == totalThreads) + wait(); + + count++; + + if (count == totalThreads) { + notifyAll(); + released = totalThreads; + } else { + + while (count < totalThreads) + wait(); + } + + released--; + if (released == 0) { + count = 0; + // remember to wakeup any threads + // waiting on line + notifyAll(); + } + } +} diff --git a/src/multithreading/educative/BlockingQueue.java b/src/multithreading/educative/BlockingQueue.java new file mode 100644 index 0000000..e6eac44 --- /dev/null +++ b/src/multithreading/educative/BlockingQueue.java @@ -0,0 +1,121 @@ +package educative; + +class BlockingQueue { + + T[] array; + Object lock = new Object(); + int size = 0; + int capacity; + int head = 0; + int tail = 0; + + @SuppressWarnings("unchecked") + public BlockingQueue(int capacity) { + // The casting results in a warning + array = (T[]) new Object[capacity]; + this.capacity = capacity; + } + + public T dequeue() throws InterruptedException { + + T item = null; + synchronized (lock) { + + while (size == 0) { + lock.wait(); + } + + if (head == capacity) { + head = 0; + } + + item = array[head]; + array[head] = null; + head++; + size--; + + lock.notify(); + } + + return item; + } + + public void enqueue(T item) throws InterruptedException { + + synchronized (lock) { + + while (size == capacity) { + lock.wait(); + } + + if (tail == capacity) { + tail = 0; + } + + array[tail] = item; + size++; + tail++; + lock.notify(); + } + } +} + +class Demonstration1 { + public static void main( String args[] ) throws Exception{ + final BlockingQueue q = new BlockingQueue(5); + + Thread t1 = new Thread(new Runnable() { + + @Override + public void run() { + try { + for (int i = 0; i < 50; i++) { + q.enqueue(new Integer(i)); + System.out.println("enqueued " + i); + } + } catch (InterruptedException ie) { + + } + } + }); + + Thread t2 = new Thread(new Runnable() { + + @Override + public void run() { + try { + for (int i = 0; i < 25; i++) { + System.out.println("Thread 2 dequeued: " + q.dequeue()); + } + } catch (InterruptedException ie) { + + } + } + }); + + Thread t3 = new Thread(new Runnable() { + + @Override + public void run() { + try { + for (int i = 0; i < 25; i++) { + System.out.println("Thread 3 dequeued: " + q.dequeue()); + } + } catch (InterruptedException ie) { + + } + } + }); + + t1.start(); + Thread.sleep(4000); + t2.start(); + + t2.join(); + + t3.start(); + t1.join(); + t3.join(); + } +} + diff --git a/src/multithreading/educative/CountingSemaphore.java b/src/multithreading/educative/CountingSemaphore.java new file mode 100644 index 0000000..e3e534d --- /dev/null +++ b/src/multithreading/educative/CountingSemaphore.java @@ -0,0 +1,29 @@ +package educative; + +class CountingSemaphore { + + int usedPermits = 0; + int maxCount; + + public CountingSemaphore(int count) { + this.maxCount = count; + } + + public synchronized void acquire() throws InterruptedException { + + while (usedPermits == maxCount) + wait(); + + notify(); + usedPermits++; + } + + public synchronized void release() throws InterruptedException { + + while (usedPermits == 0) + wait(); + + usedPermits--; + notify(); + } +} diff --git a/src/multithreading/educative/DeferredCallbackExecutor.java b/src/multithreading/educative/DeferredCallbackExecutor.java new file mode 100644 index 0000000..028e7b5 --- /dev/null +++ b/src/multithreading/educative/DeferredCallbackExecutor.java @@ -0,0 +1,78 @@ +package educative; + +import java.util.Comparator; +import java.util.PriorityQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +// Problem +// Design and implement a thread-safe class that allows registration of callback methods that are executed after a user specified time interval in seconds has elapsed. + +public class DeferredCallbackExecutor { + + PriorityQueue q = new PriorityQueue(new Comparator() { + public int compare(CallBack o1, CallBack o2) { + return (int) (o1.executeAt - o2.executeAt); + } + }); + + ReentrantLock lock = new ReentrantLock(); + Condition newCallbackArrived = lock.newCondition(); + +// whenever a consumer thread requests a callback be registered, the caveat is to wake up the execution thread +// and recalculate the minimum duration it needs to sleep for before the earliest callback becomes due for execution. +// Consider this example: initially, the execution thread is sleeping for 30 mins before any callback in the min-heap is due. +// A consumer thread comes along and adds a callback to be executed after 5 minutes. +// The execution thread would need to wake up and reset itself to sleep for only 5 minutes instead of 30 minutes. +// Once we find an elegant way of capturing this logic our problem is pretty much solved. + public void registerCallback(CallBack callBack) { + lock.lock(); + q.add(callBack); + newCallbackArrived.signal(); + lock.unlock(); + } + private long findSleepDuration() { + long currentTime = System.currentTimeMillis(); + return q.peek().executeAt - currentTime; + } + public void start() throws InterruptedException { + long sleepFor = 0; + int lastSeenQSize = 0; + while (true) { + + lock.lock(); + + while (q.size() == 0) { + newCallbackArrived.await(); + } + + while (q.size() != 0) { + sleepFor = findSleepDuration(); + + if(sleepFor <=0) + break; + + newCallbackArrived.await(sleepFor, TimeUnit.MILLISECONDS); + } + + CallBack cb = q.poll(); + System.out.println( + "Executed at " + System.currentTimeMillis()/1000 + " required at " + cb.executeAt/1000 + + ": message:" + cb.message); + + lock.unlock(); + } + } + + static class CallBack { + + long executeAt; + String message; + + public CallBack(long executeAfter, String message) { + this.executeAt = System.currentTimeMillis() + executeAfter * 1000; + this.message = message; + } + } +} diff --git a/src/multithreading/educative/DemonstrationThreadLocal.java b/src/multithreading/educative/DemonstrationThreadLocal.java new file mode 100644 index 0000000..3799d11 --- /dev/null +++ b/src/multithreading/educative/DemonstrationThreadLocal.java @@ -0,0 +1,91 @@ +package educative; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +public class DemonstrationThreadLocal { + public static void main( String args[] ) throws Exception { + + usingThreads(); + usingSingleThreadPool(); + usingMultiThreadsPool(); + } + + static void usingThreads() throws Exception { + + Counter counter = new Counter(); + Thread[] tasks = new Thread[100]; + + for (int i = 0; i < 100; i++) { + Thread t = new Thread(() -> { + for (int j = 0; j < 100; j++) + counter.increment(); + }); + tasks[i] = t; + t.start(); + } + + for (int i = 0; i < 100; i++) { + tasks[i].join(); + } + + System.out.println(counter.counter.get()); + } + + @SuppressWarnings("unchecked") + static void usingSingleThreadPool() throws Exception { + + Counter counter = new Counter(); + ExecutorService es = Executors.newFixedThreadPool(1); + Future[] tasks = new Future[100]; + + for (int i = 0; i < 100; i++) { + tasks[i] = es.submit(() -> { + for (int j = 0; j < 100; j++) + counter.increment(); + + return counter.counter.get(); + }); + } + + System.out.println(tasks[99].get()); + + es.shutdown(); + } + + @SuppressWarnings("unchecked") + static void usingMultiThreadsPool() throws Exception { + + Counter counter = new Counter(); + ExecutorService es = Executors.newFixedThreadPool(20); + Future[] tasks = new Future[100]; + + for (int i = 0; i < 100; i++) { + tasks[i] = es.submit(() -> { + for (int j = 0; j < 100; j++) + counter.increment(); + + return counter.counter.get(); + }); + } + + System.out.println(tasks[99].get()); + + es.shutdown(); + } + +} + +class Counter { + + ThreadLocal counter = ThreadLocal.withInitial(() -> 0); + + public Counter() { + counter.set(0); + } + + void increment() { + counter.set(counter.get() + 1); + } +} diff --git a/src/multithreading/educative/DiningPhilosophers.java b/src/multithreading/educative/DiningPhilosophers.java new file mode 100644 index 0000000..743817d --- /dev/null +++ b/src/multithreading/educative/DiningPhilosophers.java @@ -0,0 +1,44 @@ +package educative; + +import java.util.Random; +import java.util.concurrent.Semaphore; + +public class DiningPhilosophers { + + private static Random random = new Random(System.currentTimeMillis()); + + private Semaphore[] forks = new Semaphore[5]; + private Semaphore maxDiners = new Semaphore(4); + + public DiningPhilosophers() { + forks[0] = new Semaphore(1); + forks[1] = new Semaphore(1); + forks[2] = new Semaphore(1); + forks[3] = new Semaphore(1); + forks[4] = new Semaphore(1); + } + + void contemplate() throws InterruptedException { + Thread.sleep(random.nextInt(500)); + } + + void eat(int id) throws InterruptedException { + maxDiners.acquire(); + + forks[id].acquire(); + forks[(id + 1) % 5].acquire(); + System.out.println("Philosipher " + id + " is eating"); + forks[id].release(); + forks[(id + 1) % 5].release(); + + maxDiners.release(); + } + + public void lifecycleOfPhilosopher(int id) throws InterruptedException { + + while (true) { + contemplate(); + eat(id); + } + } +} diff --git a/src/multithreading/educative/DiningPhilosophers2.java b/src/multithreading/educative/DiningPhilosophers2.java new file mode 100644 index 0000000..aa32d98 --- /dev/null +++ b/src/multithreading/educative/DiningPhilosophers2.java @@ -0,0 +1,55 @@ +package educative; + +import java.util.Random; +import java.util.concurrent.Semaphore; + +public class DiningPhilosophers2 { + + private static Random random = new Random(System.currentTimeMillis()); + + private Semaphore[] forks = new Semaphore[5]; + + public DiningPhilosophers2() { + forks[0] = new Semaphore(1); + forks[1] = new Semaphore(1); + forks[2] = new Semaphore(1); + forks[3] = new Semaphore(1); + forks[4] = new Semaphore(1); + } + + void acquireForkForRightHanded(int id) throws InterruptedException { + forks[id].acquire(); + forks[(id + 1) % 5].acquire(); + } + + void acquireForkLeftHanded(int id) throws InterruptedException { + forks[(id + 1) % 5].acquire(); + forks[id].acquire(); + } + + void contemplate() throws InterruptedException { + Thread.sleep(random.nextInt(500)); + } + + void eat(int id) throws InterruptedException { + + if (id == 3) { + acquireForkLeftHanded(3); + + } else { + acquireForkForRightHanded(id); + } + + System.out.println("Philosipher " + id + " is eating"); + forks[id].release(); + forks[(id + 1) % 5].release(); + } + + public void lifecycleOfPhilosopher(int id) throws InterruptedException { + + while (true) { + contemplate(); + eat(id); + } + } +} diff --git a/src/multithreading/educative/MultiThreadedMergeSort.java b/src/multithreading/educative/MultiThreadedMergeSort.java new file mode 100644 index 0000000..3c73f3b --- /dev/null +++ b/src/multithreading/educative/MultiThreadedMergeSort.java @@ -0,0 +1,105 @@ +package educative; + +import java.util.Random; + +public class MultiThreadedMergeSort { + + private static int SIZE = 1000; + private static Random random = new Random(System.currentTimeMillis()); + private int[] input = new int[SIZE]; + private int[] scratch = new int[SIZE]; + + private void printArray(int[] input) { + System.out.println(); + for (int i = 0; i < input.length; i++) + System.out.print(" " + input[i] + " "); + System.out.println(); + } + + private void createTestData() { + + for (int i = 0; i < SIZE; i++) { + input[i] = random.nextInt(10000); + } + } + + private void mergeSort(final int start, final int end, final int[] input) { + + if (start == end) { + return; + } + + final int mid = (start + end) / 2; + + // sort first half + Thread worker1 = new Thread(new Runnable() { + + public void run() { + mergeSort(start, mid, input); + } + }); + + // sort second half + Thread worker2 = new Thread(new Runnable() { + + public void run() { + mergeSort(mid + 1, end, input); + } + }); + + // start the threads + worker1.start(); + worker2.start(); + + try { + + worker1.join(); + worker2.join(); + } catch (InterruptedException ie) { + // swallow + } + + // merge the two sorted arrays + int i = start; + int j = mid + 1; + int k; + + for (k = start; k <= end; k++) { + scratch[k] = input[k]; + } + + k = start; + while (k <= end) { + + if (i <= mid && j <= end) { + input[k] = Math.min(scratch[i], scratch[j]); + + if (input[k] == scratch[i]) { + i++; + } else { + j++; + } + } else if (i <= mid && j > end) { + input[k] = scratch[i]; + i++; + } else { + input[k] = scratch[j]; + j++; + } + k++; + } + } + + public void test() { + createTestData(); + // int[] result = mergeSort(0, input.length - 1, input); + // printArray(input); + // printArray(result); + printArray(input); + long start = System.currentTimeMillis(); + mergeSort(0, input.length - 1, input); + long end = System.currentTimeMillis(); + System.out.println("Time taken = " + (end - start)); + printArray(input); + } +} diff --git a/src/multithreading/educative/ReadWriteLock.java b/src/multithreading/educative/ReadWriteLock.java new file mode 100644 index 0000000..bb4146a --- /dev/null +++ b/src/multithreading/educative/ReadWriteLock.java @@ -0,0 +1,70 @@ +package educative; + +public class ReadWriteLock { + + boolean isWriteLocked = false; + int readers = 0; + + public synchronized void acquireReadLock() throws InterruptedException { + + while (isWriteLocked) { + wait(); + } + + readers++; + } + + public synchronized void acquireWriteLock() throws InterruptedException { + + while (isWriteLocked || readers != 0) { + wait(); + } + + isWriteLocked = true; + } + + public synchronized void releaseReadLock() { + readers--; + notify(); + } + + public synchronized void releaseWriteLock() { + isWriteLocked = false; + notify(); + } +} + + class ReadWriteLock1{ + + private int readers = 0; + private int writers = 0; + private int writeRequests = 0; + + public synchronized void lockRead() throws InterruptedException{ + while(writers > 0 || writeRequests > 0){ + wait(); + } + readers++; + } + + public synchronized void unlockRead(){ + readers--; + notifyAll(); + } + + public synchronized void lockWrite() throws InterruptedException{ + writeRequests++; + + while(readers > 0 || writers > 0){ + wait(); + } + writeRequests--; + writers++; + } + + public synchronized void unlockWrite() throws InterruptedException{ + writers--; + notifyAll(); + } +} + diff --git a/src/multithreading/educative/TokenBucketFilter.java b/src/multithreading/educative/TokenBucketFilter.java new file mode 100644 index 0000000..184a164 --- /dev/null +++ b/src/multithreading/educative/TokenBucketFilter.java @@ -0,0 +1,68 @@ +package educative; + +import java.util.HashSet; +import java.util.Set; + +class Demonstration { + public static void main( String args[] ) throws InterruptedException { + TokenBucketFilter.runTestMaxTokenIsTen(); + } +} + +public class TokenBucketFilter { + + long possibleTokens = 0; + private int MAX_TOKENS; + private long lastRequestTime = System.currentTimeMillis(); + + public TokenBucketFilter(int maxTokens) { + MAX_TOKENS = maxTokens; + } + + synchronized void getToken() throws InterruptedException { + + possibleTokens += (System.currentTimeMillis() - lastRequestTime) / 1000; + + if (possibleTokens > MAX_TOKENS) { + possibleTokens = MAX_TOKENS; + } + + if (possibleTokens == 0) { + Thread.sleep(1000); + } else { + possibleTokens--; + } + lastRequestTime = System.currentTimeMillis(); + + System.out.println( + "Granting " + Thread.currentThread().getName() + " token at " + System.currentTimeMillis() / 1000); + } + + + public static void runTestMaxTokenIsTen() throws InterruptedException { + Set allThreads = new HashSet(); + final TokenBucketFilter tokenBucketFilter = new TokenBucketFilter(5); +// Sleep for 10 seconds. + Thread.sleep(10000); +// Generate 12 threads requesting tokens almost all at once. + for (int i = 0; i < 12; i++) { + Thread thread = new Thread(new Runnable() { + public void run() { + try { + tokenBucketFilter.getToken(); + } catch (InterruptedException ie) { + System.out.println("We have a problem"); + } + } + }); + thread.setName("Thread_" + (i + 1)); + allThreads.add(thread); + } + for (Thread t : allThreads) { + t.start(); + } + for (Thread t : allThreads) { + t.join(); + } + } +} diff --git a/src/multithreading/educative/UberSeatingProblem.java b/src/multithreading/educative/UberSeatingProblem.java new file mode 100644 index 0000000..cd98b1d --- /dev/null +++ b/src/multithreading/educative/UberSeatingProblem.java @@ -0,0 +1,169 @@ +package educative; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.Semaphore; +import java.util.concurrent.locks.ReentrantLock; + +public class UberSeatingProblem { + public static void main(String[] args) throws InterruptedException { + runTest(); + } + + CyclicBarrier barrier = new CyclicBarrier(4); + ReentrantLock lock = new ReentrantLock(); + private int republicans = 0; + private int democrats = 0; + private Semaphore demsWaiting = new Semaphore(0); + private Semaphore repubsWaiting = new Semaphore(0); + + void drive() { + System.out.println("Uber Ride on Its wayyyy... with ride leader " + Thread.currentThread().getName()); + System.out.flush(); + } + /** + * Flow goes like this: + * step 1: let's say democrat 1 comes, it gets lock on object, increases count, and goes directly to else state, releases lock and checks for semaphore, since it's + * not there it will be in blocked state (ready to proceed once acquiring semaphore) + * step 2: let's say 3 more democrats are waiting, fourth thread comes and goes into first if and releases 3 semaphores, the 3 previous waiting thread goes and + * wait's for current thread to join at the barrier, once it comes all goes into seating + * step 3: if more that 2 republicans are waiting and current democrat count is 2, this condition releases 1 democrat and 2 republican semaphore + * it releases 1 democrat because the current thread is also a democrat, and all will be waiting near the barrier till 4th comes + */ + + + void seatDemocrat() throws InterruptedException, BrokenBarrierException { + + boolean rideLeader = false; + + lock.lock(); + System.out.println("###### locked "+Thread.currentThread().getName()); + democrats++; + + if (democrats == 4) { + // Seat all the democrats in the Uber ride. + demsWaiting.release(3); + democrats -= 4; + rideLeader = true; + } else if (democrats == 2 && republicans >= 2) { + // Seat 2 democrats & 2 republicans + demsWaiting.release(1); + repubsWaiting.release(2); + rideLeader = true; + democrats -= 2; + republicans -= 2; + } else { + System.out.println("###### unlocking "+Thread.currentThread().getName() ); + lock.unlock(); + System.out.println("###### State of thread before acquire "+ Thread.currentThread().getName() +" "+Thread.currentThread().getState()); + demsWaiting.acquire(); // thread will be in blocked state not in wait state.. + //In the BLOCKED state, a thread is about to enter a synchronized block, + // but there is another thread currently running inside a synchronized block on the same object. + // The first thread must then wait for the second thread to exit its block. + System.out.println("###### State of thread after acquire "+ Thread.currentThread().getName() +" "+Thread.currentThread().getState()); + } + + seated(); + barrier.await(); + + if (rideLeader == true) { + drive(); + lock.unlock(); + } + } + + void seatRepublican() throws InterruptedException, BrokenBarrierException { + + boolean rideLeader = false; + lock.lock(); + + republicans++; + + if (republicans == 4) { + // Seat all the republicans in the Uber ride. + repubsWaiting.release(3); + rideLeader = true; + republicans -= 4; + } else if (republicans == 2 && democrats >= 2) { + // Seat 2 democrats & 2 republicans + repubsWaiting.release(1); + demsWaiting.release(2); + rideLeader = true; + republicans -= 2; + democrats -= 2; + } else { + lock.unlock(); + repubsWaiting.acquire(); + } + + seated(); + barrier.await(); + + if (rideLeader) { + drive(); + lock.unlock(); + } + } + + void seated() { + System.out.println(Thread.currentThread().getName() + " seated"); + System.out.flush(); + } + + public static void runTest() throws InterruptedException { + + + final UberSeatingProblem uberSeatingProblem = new UberSeatingProblem(); + Set allThreads = new HashSet(); + + for (int i = 0; i < 10; i++) { + + Thread thread = new Thread(new Runnable() { + public void run() { + try { + uberSeatingProblem.seatDemocrat(); + } catch (InterruptedException ie) { + System.out.println("We have a problem"); + + } catch (BrokenBarrierException bbe) { + System.out.println("We have a problem"); + } + + } + }); + thread.setName("Democrat_" + (i + 1)); + allThreads.add(thread); + + Thread.sleep(50); + } + + for (int i = 0; i < 14; i++) { + Thread thread = new Thread(new Runnable() { + public void run() { + try { + uberSeatingProblem.seatRepublican(); + } catch (InterruptedException ie) { + System.out.println("We have a problem"); + + } catch (BrokenBarrierException bbe) { + System.out.println("We have a problem"); + } + } + }); + thread.setName("Republican_" + (i + 1)); + allThreads.add(thread); + Thread.sleep(20); + } + + for (Thread t : allThreads) { + t.start(); + } + + for (Thread t : allThreads) { + t.join(); + } + } +} + diff --git a/src/multithreading/educative/UnisexBathroom.java b/src/multithreading/educative/UnisexBathroom.java new file mode 100644 index 0000000..d446fcf --- /dev/null +++ b/src/multithreading/educative/UnisexBathroom.java @@ -0,0 +1,70 @@ +package educative; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +public class UnisexBathroom { + + static String WOMEN = "women"; + static String MEN = "men"; + static String NONE = "none"; + + String inUseBy = NONE; + int empsInBathroom = 0; + ReentrantLock lock = new ReentrantLock(); + Condition cond = lock.newCondition(); + Semaphore maxEmps = new Semaphore(3); + + void femaleUseBathroom(String name) throws InterruptedException { + + lock.lock(); + while (inUseBy.equals(MEN)) { + cond.await(); + } + maxEmps.acquire(); + empsInBathroom++; + inUseBy = WOMEN; + lock.unlock(); + + useBathroom(name); + maxEmps.release(); + + lock.lock(); + empsInBathroom--; + + if (empsInBathroom == 0) + inUseBy = NONE; + cond.signalAll(); + lock.unlock(); + } + + void maleUseBathroom(String name) throws InterruptedException { + + lock.lock(); + while (inUseBy.equals(WOMEN)) { + cond.await(); + } + maxEmps.acquire(); + empsInBathroom++; + inUseBy = MEN; + lock.unlock(); + + useBathroom(name); + maxEmps.release(); + + lock.lock(); + empsInBathroom--; + + if (empsInBathroom == 0) + inUseBy = NONE; + cond.signalAll(); + lock.unlock(); + } + + void useBathroom(String name) throws InterruptedException { + System.out.println(name + " using bathroom. Current employees in bathroom = " + empsInBathroom); + Thread.sleep(10000); + System.out.println(name + " done using bathroom"); + } +} diff --git a/src/multithreading/educative/UnisexBathroom2.java b/src/multithreading/educative/UnisexBathroom2.java new file mode 100644 index 0000000..402e660 --- /dev/null +++ b/src/multithreading/educative/UnisexBathroom2.java @@ -0,0 +1,139 @@ +package educative; + +import java.util.concurrent.Semaphore; + +public class UnisexBathroom2 { + + static String WOMEN = "women"; + static String MEN = "men"; + static String NONE = "none"; + + String inUseBy = NONE; + int empsInBathroom = 0; + Semaphore maxEmps = new Semaphore(3); + + public static void runTest() throws InterruptedException { + + final UnisexBathroom2 unisexBathroom = new UnisexBathroom2(); + + Thread female1 = new Thread(new Runnable() { + + public void run() { + try { + unisexBathroom.femaleUseBathroom("Lisa"); + } catch (InterruptedException ie) { + + } + } + }); + + Thread male1 = new Thread(new Runnable() { + + public void run() { + try { + unisexBathroom.maleUseBathroom("John"); + } catch (InterruptedException ie) { + + } + } + }); + + Thread male2 = new Thread(new Runnable() { + + public void run() { + try { + unisexBathroom.maleUseBathroom("Bob"); + } catch (InterruptedException ie) { + + } + } + }); + + Thread male3 = new Thread(new Runnable() { + + public void run() { + try { + unisexBathroom.maleUseBathroom("Anil"); + } catch (InterruptedException ie) { + + } + } + }); + + Thread male4 = new Thread(new Runnable() { + + public void run() { + try { + unisexBathroom.maleUseBathroom("Wentao"); + } catch (InterruptedException ie) { + + } + } + }); + + female1.start(); + male1.start(); + male2.start(); + male3.start(); + male4.start(); + + female1.join(); + male1.join(); + male2.join(); + male3.join(); + male4.join(); + + } + + void femaleUseBathroom(String name) throws InterruptedException { + + synchronized (this) { + while (inUseBy.equals(MEN)) { + this.wait(); + } + maxEmps.acquire(); + empsInBathroom++; + inUseBy = WOMEN; + } + + useBathroom(name); + maxEmps.release(); + + synchronized (this) { + empsInBathroom--; + + if (empsInBathroom == 0) + inUseBy = NONE; + this.notifyAll(); + } + } + + void maleUseBathroom(String name) throws InterruptedException { + + synchronized (this) { + while (inUseBy.equals(WOMEN)) { + this.wait(); + } + maxEmps.acquire(); + empsInBathroom++; + inUseBy = MEN; + } + + useBathroom(name); + maxEmps.release(); + + synchronized (this) { + empsInBathroom--; + + if (empsInBathroom == 0) + inUseBy = NONE; + this.notifyAll(); + } + } + + void useBathroom(String name) throws InterruptedException { + System.out.println(name + " using bathroom. Current employees in bathroom = " + empsInBathroom); + Thread.sleep(10000); + System.out.println(name + " done using bathroom"); + } +} diff --git a/src/multithreading/educative/companies/netflix/Callback.java b/src/multithreading/educative/companies/netflix/Callback.java new file mode 100644 index 0000000..02eecff --- /dev/null +++ b/src/multithreading/educative/companies/netflix/Callback.java @@ -0,0 +1,6 @@ +package educative.companies.netflix; + +public interface Callback { + + public void done(); +} diff --git a/src/multithreading/educative/companies/netflix/Executor.java b/src/multithreading/educative/companies/netflix/Executor.java new file mode 100644 index 0000000..df72354 --- /dev/null +++ b/src/multithreading/educative/companies/netflix/Executor.java @@ -0,0 +1,17 @@ +package educative.companies.netflix; + +public class Executor { + + public void asynchronousExecution(Callback callback) throws Exception { + + Thread t = new Thread(() -> { + // Do some useful work + try { + Thread.sleep(5000); + } catch (InterruptedException ie) { + } + callback.done(); + }); + t.start(); + } +} diff --git a/src/multithreading/educative/companies/netflix/Run.java b/src/multithreading/educative/companies/netflix/Run.java new file mode 100644 index 0000000..a807080 --- /dev/null +++ b/src/multithreading/educative/companies/netflix/Run.java @@ -0,0 +1,23 @@ +package educative.companies.netflix; + +public class Run { + + public static void main(String[] args) throws Exception { + + SynchronousExecutor executor = new SynchronousExecutor(); + executor.asynchronousExecution(() -> { + System.out.println("I am done"); + }); + + System.out.println("main thread exiting..."); + } + + void runAsynchronously() throws Exception { + Executor executor = new Executor(); + executor.asynchronousExecution(() -> { + System.out.println("I am done"); + }); + + System.out.println("main thread exiting..."); + } +} diff --git a/src/multithreading/educative/companies/netflix/SynchronousExecutor.java b/src/multithreading/educative/companies/netflix/SynchronousExecutor.java new file mode 100644 index 0000000..7f54420 --- /dev/null +++ b/src/multithreading/educative/companies/netflix/SynchronousExecutor.java @@ -0,0 +1,33 @@ +package educative.companies.netflix; + +public class SynchronousExecutor extends Executor { + + @Override + public void asynchronousExecution(Callback callback) throws Exception { + + Object signal = new Object(); + final boolean[] isDone = new boolean[1]; + + Callback cb = new Callback() { + + @Override + public void done() { + callback.done(); + synchronized (signal) { + signal.notify(); + isDone[0] = true; + } + } + }; + + // Call the asynchronous executor + super.asynchronousExecution(cb); + + synchronized (signal) { + while (!isDone[0]) { + signal.wait(); + } + } + + } +} diff --git a/src/multithreading/educative/examples/CallableExample.java b/src/multithreading/educative/examples/CallableExample.java new file mode 100644 index 0000000..fee4f8d --- /dev/null +++ b/src/multithreading/educative/examples/CallableExample.java @@ -0,0 +1,117 @@ +package educative.examples; + +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +public class CallableExample { + + int example1(final int n) throws ExecutionException, InterruptedException { + + ExecutorService threadPool = Executors.newFixedThreadPool(5); + + Callable sumTask = new Callable() { + + public Integer call() throws Exception { + int sum = 0; + for (int i = 1; i <= n; i++) + sum += i; + System.out.println("Running"); + return sum; + } + }; + + Future f = threadPool.submit(sumTask); + int ans = f.get(); + + + f = threadPool.submit(sumTask); + f.get(); + + return ans; + } + + int example2(final int n) throws ExecutionException, InterruptedException { + + ExecutorService threadPool = Executors.newFixedThreadPool(5); + int result = -1; + + Callable sumTask = new Callable() { + + public Integer call() throws Exception { + throw new RuntimeException("something bad happened."); + } + }; + + Future f = threadPool.submit(sumTask); + + try { + result = f.get(); + } catch (ExecutionException ee) { + System.out.println("Something went wrong."); + } + + return result; + } + + int example3(final int n) throws ExecutionException, InterruptedException { + + ExecutorService threadPool = Executors.newSingleThreadExecutor(); + int result = -1; + + Callable sumTask1 = new Callable() { + + public Integer call() throws Exception { + + // wait for 2 seconds + Thread.sleep(1000); + + int sum = 0; + for (int i = 1; i <= n; i++) + sum += i; + return sum; + } + }; + + Callable randomTask = new Callable() { + + public Void call() throws Exception { + + // go to sleep for an hours + Thread.sleep(3600 * 1000); + return null; + } + }; + + Future f1 = threadPool.submit(sumTask1); + Future f2 = threadPool.submit(randomTask); + + // Poll for completion of first task + try { + + // Before we poll for completion of second task, + // cancel the second one + f2.cancel(true); + + while (!f1.isDone()) { + System.out.println("Waiting for first task to complete."); + } + result = f1.get(); + } catch (ExecutionException ee) { + System.out.println("Something went wrong."); + } + + System.out.println("Is second task cancelled : " + f2.isCancelled()); + + return result; + } + + void test() throws ExecutionException, InterruptedException { + // System.out.println(example1(10)); + + System.out.println(example1(10)); + } + +} diff --git a/src/multithreading/educative/examples/DaemonThreadSpawn.java b/src/multithreading/educative/examples/DaemonThreadSpawn.java new file mode 100644 index 0000000..c7193e2 --- /dev/null +++ b/src/multithreading/educative/examples/DaemonThreadSpawn.java @@ -0,0 +1,21 @@ +package educative.examples; + +public class DaemonThreadSpawn { + + public void spawnDaemonThread() { + + Thread innerThread = new Thread(new Runnable() { + + public void run() { + + for (int i = 0; i < 100; i++) { + System.out.println("I am a daemon thread !"); + } + } + }); + + innerThread.setDaemon(true); + innerThread.start(); + System.out.println("Main thread exiting"); + } +} diff --git a/src/multithreading/educative/examples/FutureTaskExample.java b/src/multithreading/educative/examples/FutureTaskExample.java new file mode 100644 index 0000000..997aa6c --- /dev/null +++ b/src/multithreading/educative/examples/FutureTaskExample.java @@ -0,0 +1,89 @@ +package educative.examples; + +import java.util.Random; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; + +public class FutureTaskExample { + + Random random = new Random(System.currentTimeMillis()); + + @SuppressWarnings("") + void example() throws Exception { + + FutureTask futureTask = new FutureTask(new Callable() { + + public Object call() throws Exception { + try{ + Thread.sleep(1); + } + catch(InterruptedException ie){ + // swallow exception + } + return 5; + } + }); + + ExecutorService threadPool = (Executors.newSingleThreadExecutor()); + Future duplicateFuture = threadPool.submit(futureTask); + + // Awful idea to busy wait + while (!futureTask.isDone()) { + System.out.println("Waiting"); + } + + if(duplicateFuture.isDone() != futureTask.isDone()){ + System.out.println("This should never happen."); + } + + System.out.println(futureTask.get()); + } + + void completionServiceExample() throws Exception { + + class TrivialTask implements Runnable { + + int n; + + public TrivialTask(int n) { + this.n = n; + } + + public void run() { + try { + // sleep for one second + Thread.sleep(random.nextInt(101)); + } catch (InterruptedException ie) { + // swallow exception + } + } + } + + ExecutorService threadPool = Executors.newFixedThreadPool(3); + ExecutorCompletionService service = + new ExecutorCompletionService(threadPool); + + // Submit 10 trivial tasks. + for (int i = 0; i < 10; i++) { + service.submit(new TrivialTask(i), new Integer(i)); + } + + // wait for all tasks to get done + int count = 10; + while (count != 0) { + Future f = service.poll(); + if (f != null) { + System.out.println("Thread" + f.get() + " got done."); + count--; + } + } + + threadPool.shutdown(); + + } + +} diff --git a/src/multithreading/educative/examples/StockOrder.java b/src/multithreading/educative/examples/StockOrder.java new file mode 100644 index 0000000..2e62f8b --- /dev/null +++ b/src/multithreading/educative/examples/StockOrder.java @@ -0,0 +1,57 @@ +package educative.examples; + +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class StockOrder { + + class Order { + void execute() {} + } + + Order waitForNextOrder() {return null;} + + void receiveAndExecuteClientOrders() { + + while (true) { + Order order = waitForNextOrder(); + order.execute(); + } + } + + void receiveAndExecuteClientOrdersBetter() { + + while (true) { + final Order order = waitForNextOrder(); + + Thread thread = new Thread(new Runnable() { + + public void run() { + order.execute(); + } + }); + + thread.start(); + } + } + + void receiveAndExecuteClientOrdersBest() { + + int expectedConcurrentOrders = 100; + Executor executor = Executors.newFixedThreadPool(expectedConcurrentOrders); + ((ExecutorService) executor).shutdown(); + ExecutorService s = Executors.newFixedThreadPool(5); + + while (true) { + final Order order = waitForNextOrder(); + + executor.execute(new Runnable() { + + public void run() { + order.execute(); + } + }); + } + } +} diff --git a/src/multithreading/educative/examples/ThreadExample.java b/src/multithreading/educative/examples/ThreadExample.java new file mode 100644 index 0000000..fc0f4bf --- /dev/null +++ b/src/multithreading/educative/examples/ThreadExample.java @@ -0,0 +1,41 @@ +package educative.examples; + +public class ThreadExample { + + class ExecuteMe implements Runnable { + + public void run() { + while (true) { + System.out.println("Say Hello over and over again."); + try { + Thread.sleep(1000); + } catch (InterruptedException ie) { + // swallow interrupted exception + + } + } + } + } + + class MyTask extends Thread { + + @Override + public void run() { + System.out.println("Hello World."); + } + + } + + public void main() throws InterruptedException { +// ExecuteMe executeMe = new ExecuteMe(); +// Thread innerThread = new Thread(executeMe); +// // innerThread.setDaemon(true); +// innerThread.start(); +// innerThread.join(); +// System.out.println("Main thread exits"); + + MyTask myTask = new MyTask(); + myTask.start(); + + } +} diff --git a/src/multithreading/educative/examples/ThreadExecutorExample.java b/src/multithreading/educative/examples/ThreadExecutorExample.java new file mode 100644 index 0000000..e9f04a0 --- /dev/null +++ b/src/multithreading/educative/examples/ThreadExecutorExample.java @@ -0,0 +1,29 @@ +package educative.examples; + +import java.util.concurrent.Executor; + +public class ThreadExecutorExample { + + public void main() throws InterruptedException { + + DumbExecutor dumbExecutor = new DumbExecutor(); + MyTask myTask = new MyTask(); + dumbExecutor.execute(myTask); + } + + static class MyTask implements Runnable { + + public void run() { + System.out.println("Mytask is running now ..."); + } + } + + static class DumbExecutor implements Executor { + + public void execute(Runnable runnable) { + Thread newThread = new Thread(runnable); + newThread.start(); + } + } + +} diff --git a/src/multithreading/educative/examples/ThreadInterruptedException.java b/src/multithreading/educative/examples/ThreadInterruptedException.java new file mode 100644 index 0000000..c5a625e --- /dev/null +++ b/src/multithreading/educative/examples/ThreadInterruptedException.java @@ -0,0 +1,29 @@ +package educative.examples; + +public class ThreadInterruptedException { + + class ExecuteMe implements Runnable { + + public void run() { + try { + // sleep for a thousand minutes + System.out.println("innerThread goes to sleep at " + System.currentTimeMillis() / 1000); + Thread.sleep(1000 * 1000); + } catch (InterruptedException ie) { + System.out.println("innerThread interrupted at " + +System.currentTimeMillis() / 1000); + } + } + } + + public void main() throws InterruptedException { + ExecuteMe executeMe = new ExecuteMe(); + Thread innerThread = new Thread(executeMe); + innerThread.start(); + + // Interrupt innerThread after waiting for 5 seconds + System.out.println("Main thread sleeping at " + +System.currentTimeMillis() / 1000); + Thread.sleep(5000); + innerThread.interrupt(); + System.out.println("Main thread exiting at " + +System.currentTimeMillis() / 1000); + } +} diff --git a/src/multithreading/educative/examples/ThreadSleepExample.java b/src/multithreading/educative/examples/ThreadSleepExample.java new file mode 100644 index 0000000..6dc2998 --- /dev/null +++ b/src/multithreading/educative/examples/ThreadSleepExample.java @@ -0,0 +1,24 @@ +package educative.examples; + +public class ThreadSleepExample { + + class ExecuteMe implements Runnable { + + public void run() { + System.out.println("Hello. innerThread going to sleep"); + try { + Thread.sleep(1000); + } catch (InterruptedException ie) { + // swallow interrupted exception + } + } + } + + public void main() throws InterruptedException { + ExecuteMe executeMe = new ExecuteMe(); + Thread innerThread = new Thread(executeMe); + innerThread.start(); + innerThread.join(); + System.out.println("Main thread exiting."); + } +} diff --git a/src/multithreading/educative/examples/ThreadSpawn.java b/src/multithreading/educative/examples/ThreadSpawn.java new file mode 100644 index 0000000..49af39b --- /dev/null +++ b/src/multithreading/educative/examples/ThreadSpawn.java @@ -0,0 +1,20 @@ +package educative.examples; + +public class ThreadSpawn { + + public void spawnThread() { + + Thread innerThread = new Thread(new Runnable() { + + public void run() { + + for (int i = 0; i < 100; i++) { + System.out.println("I am a new thread !"); + } + } + }); + + innerThread.start(); + System.out.println("Main thread exiting"); + } +} diff --git a/src/multithreading/educative/examples/TimerVsPool.java b/src/multithreading/educative/examples/TimerVsPool.java new file mode 100644 index 0000000..a0d3ac2 --- /dev/null +++ b/src/multithreading/educative/examples/TimerVsPool.java @@ -0,0 +1,64 @@ +package educative.examples; + +import java.util.Timer; +import java.util.TimerTask; + +public class TimerVsPool { + + void timer() throws Exception { + + Timer timer = new Timer(); + TimerTask badTask = new TimerTask() { + + @Override + public void run() { + + // run forever + while (true); + + } + }; + + TimerTask goodTask = new TimerTask() { + + @Override + public void run() { + + System.out.println("Hello I am a well-behaved task"); + + } + }; + + timer.schedule(badTask, 100); + timer.schedule(goodTask, 500); + + // By three seconds, both tasks are expected to have launched + Thread.sleep(3000); + } + + void timer2() throws Exception { + + Timer timer = new Timer(); + TimerTask badTask = new TimerTask() { + + @Override + public void run() { + throw new RuntimeException("Something Bad Happened"); + } + }; + + TimerTask goodTask = new TimerTask() { + + @Override + public void run() { + System.out.println("Hello I am a well-behaved task"); + } + }; + + timer.schedule(badTask, 10); + Thread.sleep(500); + timer.schedule(goodTask, 10); + } + + +} diff --git a/src/multithreading/educative/superman/Superman.java b/src/multithreading/educative/superman/Superman.java new file mode 100644 index 0000000..835aeef --- /dev/null +++ b/src/multithreading/educative/superman/Superman.java @@ -0,0 +1,28 @@ +package educative.superman; + +public class Superman { + + private static volatile Superman superman; + + private Superman() { + + } + + public static Superman getInstance() { + + if (superman == null) { + synchronized (SupermanSlightlyBetter.class) { + + if (superman == null) { + superman = new Superman(); + } + } + } + + return superman; + } + + public void fly() { + System.out.println("I am Superman & I can fly !"); + } +} diff --git a/src/multithreading/educative/superman/SupermanNaiveButCorrect.java b/src/multithreading/educative/superman/SupermanNaiveButCorrect.java new file mode 100644 index 0000000..334fb74 --- /dev/null +++ b/src/multithreading/educative/superman/SupermanNaiveButCorrect.java @@ -0,0 +1,20 @@ +package educative.superman; + +public class SupermanNaiveButCorrect { + + // We are initializing the object inline + private static SupermanNaiveButCorrect superman = new SupermanNaiveButCorrect(); + + // We have marked the constructor private + private SupermanNaiveButCorrect() { + } + + public static SupermanNaiveButCorrect getInstance() { + return superman; + } + + // Object method + public void fly() { + System.out.println("I am Superman & I can fly !"); + } +} diff --git a/src/multithreading/educative/superman/SupermanSlightlyBetter.java b/src/multithreading/educative/superman/SupermanSlightlyBetter.java new file mode 100644 index 0000000..95a9f71 --- /dev/null +++ b/src/multithreading/educative/superman/SupermanSlightlyBetter.java @@ -0,0 +1,36 @@ +package educative.superman; + +public class SupermanSlightlyBetter { + + private static SupermanSlightlyBetter superman; + + private SupermanSlightlyBetter() { + + } + + public static SupermanSlightlyBetter getInstance() { + + // Check if object is uninitialized + if (superman == null) { + + // Now synchronize on the class object, so that only + // 1 thread gets a chance to initialize the superman + // object. Note that multiple threads can actually find + // the superman object to be null and fall into the + // first if clause + synchronized (SupermanSlightlyBetter.class) { + + // Must check once more if the superman object is still + // null. It is possible that another thread might have + // intialized it already as multiple thread could have + // made past the first if check. + if (superman == null) { + superman = new SupermanSlightlyBetter(); + } + } + + } + + return superman; + } +} diff --git a/src/multithreading/educative/superman/SupermanWithFlaws.java b/src/multithreading/educative/superman/SupermanWithFlaws.java new file mode 100644 index 0000000..b0900c5 --- /dev/null +++ b/src/multithreading/educative/superman/SupermanWithFlaws.java @@ -0,0 +1,30 @@ +package educative.superman; + +public class SupermanWithFlaws { + + private static SupermanWithFlaws superman; + + private SupermanWithFlaws() { + + } + + // This will fail with multiple threads + public static SupermanWithFlaws getInstance() { + if (superman == null) { + // A thread can be context switched at this point and + // superman will evaluate to null for any other threads + // testing the if condition. Now multiple threads will + // fall into this if clause till the superman object is + // assigned a value. All these threads will intialize the + // superman object when it should have been initialized + // only one. + superman = new SupermanWithFlaws(); + } + return superman; + } + + // Object method + public void fly() { + System.out.println("I am Superman & I can fly !"); + } +} diff --git a/src/multithreading/executor/User.java b/src/multithreading/executor/User.java new file mode 100644 index 0000000..6bb5550 --- /dev/null +++ b/src/multithreading/executor/User.java @@ -0,0 +1,32 @@ +package executor; + +public class User { + + String userName; + String userId; + String emailAddress; + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getEmailAddress() { + return emailAddress; + } + + public void setEmailAddress(String emailAddress) { + this.emailAddress = emailAddress; + } +} diff --git a/src/multithreading/practice/Addition.java b/src/multithreading/practice/Addition.java new file mode 100644 index 0000000..936f1ac --- /dev/null +++ b/src/multithreading/practice/Addition.java @@ -0,0 +1,52 @@ +package practice; + + +class Demonstration { + public static void main( String args[] ) throws InterruptedException { + SumUpExample.runTest(); + } +} +class SumUpExample { + long startRange; + long endRange; + long counter = 0; + static long MAX_NUM = Integer.MAX_VALUE; + public SumUpExample(long startRange, long endRange) { + this.startRange = startRange; + this.endRange = endRange; + } + public void add() { + for (long i = startRange; i <= endRange; i++) { + counter += i; + } + } + static public void twoThreads() throws InterruptedException { + long start = System.currentTimeMillis(); + SumUpExample s1 = new SumUpExample(1, MAX_NUM / 2); + SumUpExample s2 = new SumUpExample(1 + (MAX_NUM / 2), MAX_NUM); + Thread t1 = new Thread(() -> { + s1.add(); + }); + Thread t2 = new Thread(() -> { + s2.add(); + }); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + long finalCount = s1.counter + s2.counter; + long end = System.currentTimeMillis(); + System.out.println("Two threads final count = " + finalCount + " took " + (end - start)); + } + static public void oneThread() { + long start = System.currentTimeMillis(); + SumUpExample s = new SumUpExample(1, MAX_NUM ); + s.add(); + long end = System.currentTimeMillis(); + System.out.println("Single thread final count = " + s.counter + " took " + (end- start)); + } + public static void runTest() throws InterruptedException { + oneThread(); + twoThreads(); + } +} \ No newline at end of file diff --git a/src/multithreading/practice/CountdownLatch.java b/src/multithreading/practice/CountdownLatch.java new file mode 100644 index 0000000..f185a8a --- /dev/null +++ b/src/multithreading/practice/CountdownLatch.java @@ -0,0 +1,38 @@ +package practice; + +import java.util.concurrent.CountDownLatch; + +public class CountdownLatch { + + public static void main(String[] args) { + final CountDownLatch countdown = new CountDownLatch(10); + for (int i = 0; i < 10; ++ i){ + Thread t= new Thread() { + public void run() { + try { + doSomething(); + countdown.countDown(); + System.out.printf("Waiting on %d other threads.",countdown.getCount()); + System.out.println(); + countdown.await(); //waits until everyone reaches this point + + } catch (InterruptedException e) { + e.printStackTrace(); + } + finish(); + } + }; + t.start(); + } + } + + public static void doSomething() throws InterruptedException { + Thread.sleep(1000); + } + + public static void finish(){ + System.out.println("Finished everything"); + } +} + + diff --git a/src/multithreading/practice/FizzBuzz.java b/src/multithreading/practice/FizzBuzz.java new file mode 100644 index 0000000..d225a57 --- /dev/null +++ b/src/multithreading/practice/FizzBuzz.java @@ -0,0 +1,62 @@ +package practice; + +import java.util.concurrent.Semaphore; +import java.util.function.IntConsumer; + +class FizzBuzz { + private int n; + Semaphore number= new Semaphore(1); + Semaphore fizz= new Semaphore(0); + Semaphore buzz= new Semaphore(0); + Semaphore fizzbuzz= new Semaphore(0); + + public FizzBuzz(int n) { + this.n = n; + } + + // printFizz.run() outputs "fizz". + public void fizz(Runnable printFizz) throws InterruptedException { + for(int i=3;i<=n;i=i+3){ + fizz.acquire(); + if((i+3)%5==0) i=i+3; + printFizz.run(); + number.release(); + } +} + + // printBuzz.run() outputs "buzz". + public void buzz(Runnable printBuzz) throws InterruptedException { + for(int i=5;i<=n;i=i+5){ + buzz.acquire(); + if((i+5)%3==0) i=i+5; + printBuzz.run(); + number.release(); + } + + + } + + // printFizzBuzz.run() outputs "fizzbuzz". + public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException { + for(int i=15;i<=n;i=i+15){ + fizzbuzz.acquire(); + printFizzBuzz.run(); + number.release(); + } + + } + + // printNumber.accept(x) outputs "x", where x is an integer. + public void number(IntConsumer printNumber) throws InterruptedException { + for(int i=1;i<=n;i++){ + number.acquire(); + if(i%3==0 && i%5==0) fizzbuzz.release(); + else if(i%3==0) fizz.release(); + else if(i%5==0) buzz.release(); + else { + printNumber.accept(i); + number.release(); + } + } + } +} \ No newline at end of file diff --git a/src/multithreading/practice/Foo.java b/src/multithreading/practice/Foo.java new file mode 100644 index 0000000..5e297ba --- /dev/null +++ b/src/multithreading/practice/Foo.java @@ -0,0 +1,39 @@ +package practice; + +import java.util.concurrent.Semaphore; + +class Foo { + Semaphore first= new Semaphore(0); + Semaphore second= new Semaphore(0); + Semaphore third= new Semaphore(0); + + public Foo() { + + } + + public void first(Runnable printFirst) throws InterruptedException { + first.acquire(); + + + printFirst.run(); + + second.release(); + } + + public void second(Runnable printSecond) throws InterruptedException { + first.release(); + second.acquire(); + + printSecond.run(); + third.release(); + } + + public void third(Runnable printThird) throws InterruptedException { + first.release(); + third.acquire(); + + printThird.run(); + + + } +} \ No newline at end of file diff --git a/src/multithreading/practice/FooBar.java b/src/multithreading/practice/FooBar.java new file mode 100644 index 0000000..cbc2c6f --- /dev/null +++ b/src/multithreading/practice/FooBar.java @@ -0,0 +1,32 @@ +package practice; + +import java.util.concurrent.Semaphore; + +class FooBar { + private int n; + Semaphore one= new Semaphore(0); + Semaphore two= new Semaphore(1); + public FooBar(int n) { + this.n = n; + } + + public void foo(Runnable printFoo) throws InterruptedException { + + for (int i = 0; i < n; i++) { + + two.acquire(); + printFoo.run(); + one.release(); + } + } + + public void bar(Runnable printBar) throws InterruptedException { + + for (int i = 0; i < n; i++) { + + one.acquire(); + printBar.run(); + two.release(); + } + } +} \ No newline at end of file diff --git a/src/multithreading/practice/OddEven.java b/src/multithreading/practice/OddEven.java new file mode 100644 index 0000000..24469c8 --- /dev/null +++ b/src/multithreading/practice/OddEven.java @@ -0,0 +1,78 @@ +package practice; + +import java.util.concurrent.Callable; + +public class OddEven { + + public static void main(String[] args) { + + Printer p= new Printer(); + Thread odd= new Thread(new Odd(p)); + Thread even= new Thread(new Even(p)); + + odd.start(); + even.start(); + + } + + +} + +class Even implements Runnable{ + Printer print; + + public Even(Printer p) { + this.print=p; + } + + @Override + public void run() { + try { + print.printEven(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + class Odd implements Runnable{ + + Printer print; + + public Odd(Printer p) { + this.print=p; + } + + @Override + public void run() { + try { + print.printOdd(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + class Printer { + boolean isOdd; + int max=20; + int start=1; + + public synchronized void printEven() throws InterruptedException { + while(start<=max){ + if(start%2!=0){ + wait(); + } + System.out.println("From thread "+Thread.currentThread().getName()+" value "+start++); + notify(); + } + } + + public synchronized void printOdd() throws InterruptedException { + while(start<=max){ + if(start%2==0){ + wait(); + } + System.out.println("From thread "+Thread.currentThread().getName()+" value "+start++); + notify(); + } + } +} diff --git a/src/multithreading/practice/OddEvenSemaphore.java b/src/multithreading/practice/OddEvenSemaphore.java new file mode 100644 index 0000000..baac66e --- /dev/null +++ b/src/multithreading/practice/OddEvenSemaphore.java @@ -0,0 +1,94 @@ +package practice; + +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Semaphore; + +public class OddEvenSemaphore { + public static void main(String[] args) { + //Odd odd= new Odd() + PrinterSemaphore print= new PrinterSemaphore(); +// Thread even= new Thread(new EvenSemaphore(print)); +// even.setName("From Even Thread"); +// Thread odd= new Thread(new OddSemaphore(print)); +// odd.setName("From odd Thread"); +// odd.start(); +// even.start(); + + + ExecutorService service= Executors.newFixedThreadPool(10); + service.submit(new OddSemaphore(print)); + service.submit(new EvenSemaphore(print)); + } +} + +class OddSemaphore implements Callable { + + PrinterSemaphore print; + + public OddSemaphore(PrinterSemaphore p) { + this.print=p; + } + + @Override + public Boolean call() throws Exception { + for(int i=1;i<20;i+=2){ + print.printOdd(i); + } + return true; + } +} + +class EvenSemaphore implements Callable{ + + PrinterSemaphore print; + + public EvenSemaphore(PrinterSemaphore p) { + this.print=p; + } + + @Override + public Boolean call() throws Exception { + for(int i=2;i<20;i+=2){ + try { + print.printEven(i); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + return true; + } +} + +class PrinterSemaphore { + Semaphore semOdd= new Semaphore(1); + Semaphore semEven= new Semaphore(0); + + public void printEven(int val) throws InterruptedException { + try{ + semEven.acquire(); + System.out.println(Thread.currentThread().getName()+" value :"+val); + } finally { + semOdd.release(); + } + + + } + + public void printOdd(int val){ + try { + semOdd.acquire(); + System.out.println(Thread.currentThread().getName()+" value :"+val); + } catch (InterruptedException e) { + e.printStackTrace(); + }finally { + semEven.release(); + } + + + + + } +} \ No newline at end of file diff --git a/src/multithreading/practice/ProducerConsumer.java b/src/multithreading/practice/ProducerConsumer.java new file mode 100644 index 0000000..1fe3cb3 --- /dev/null +++ b/src/multithreading/practice/ProducerConsumer.java @@ -0,0 +1,116 @@ +package practice; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.*; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +public class ProducerConsumer { + + + public static void main(String[] args) { + + + Lock lock = new ReentrantLock(); + Condition producerCond1 = lock.newCondition(); + Condition consumerCond1 = lock.newCondition(); + + List buffer1 = new ArrayList<>(20); + + class Producer implements Callable { + List buffer; + Condition producerCond; Condition consumerCond; + public Producer( List buffer, Condition producerCond, Condition consumerCond){ + this.buffer=buffer; + this.producerCond=producerCond; + this.consumerCond=consumerCond; + } + public String call() throws InterruptedException { + int count = 0; + try { + lock.lock(); + while (count++ < 50) { + + while (this.buffer.size() > 20) { + producerCond.await(); + } + this.buffer.add((int) (Math.random() * 10)); + consumerCond.signalAll(); + } + } + finally { + lock.unlock(); + } + return "Produced " + (count-1); + } + } + + class Consumer implements Callable { + List buffer; + Condition producerCond; Condition consumerCond; + public Consumer( List buffer, Condition producerCond, Condition consumerCond){ + this.buffer=buffer; + this.producerCond=producerCond; + this.consumerCond=consumerCond; + } + public String call() throws InterruptedException { + int count=0; + try { + lock.lock(); + + while (count++ <50) { + + while (this.buffer.size() == 0) { + consumerCond.await(); + } + this.buffer.remove(buffer.size() - 1); + producerCond.signalAll(); + + } + } + finally { + lock.unlock(); + } + return "consumer " + (count-1); + } + } + + ExecutorService service = Executors.newFixedThreadPool(8); + + ExecutorService service1 = Executors.newCachedThreadPool(); + + + List> listProds = new ArrayList<>(); + List> listCons = new ArrayList<>(); + for (int i = 0; i < 4; i++) { + listProds.add(new Producer(buffer1,producerCond1,consumerCond1)); + } + + for (int i = 0; i < 4; i++) { + listCons.add(new Consumer(buffer1,producerCond1,consumerCond1)); + } + + List> allCalls = new ArrayList<>(); + allCalls.addAll(listProds); + allCalls.addAll(listCons); + + try { + List> future = service.invokeAll(allCalls); + + future.forEach(e -> { + + try { + System.out.println("result:: " + e.get()); + } catch (ExecutionException | InterruptedException ex) { + System.out.println("error "+ex.getMessage()); + } + }); + + }catch ( InterruptedException ex ){ + System.out.println("error "+ex.getMessage()); + }finally { + service.shutdown(); + } + } +} diff --git a/src/multithreading/practice/ZeroEvenOdd.java b/src/multithreading/practice/ZeroEvenOdd.java new file mode 100644 index 0000000..1d5b510 --- /dev/null +++ b/src/multithreading/practice/ZeroEvenOdd.java @@ -0,0 +1,48 @@ +package practice; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.IntConsumer; + +class ZeroEvenOdd { + private int n; + + Semaphore zero= new Semaphore(1); + Semaphore one= new Semaphore(0); + Semaphore two= new Semaphore(0); + + AtomicInteger value= new AtomicInteger(1); + + public ZeroEvenOdd(int n) { + this.n = n; + } + + // printNumber.accept(x) outputs "x", where x is an integer. + public void zero(IntConsumer printNumber) throws InterruptedException { + + for(int i=1;i<=n;i++){ + zero.acquire(); + printNumber.accept(0); + if(i%2==0) two.release(); + if(i%2!=0) one.release(); + } + + } + + public void even(IntConsumer printNumber) throws InterruptedException { + + for(int i=2;i<=n;i=i+2){ + two.acquire(); + printNumber.accept(i); + zero.release(); + } + } + + public void odd(IntConsumer printNumber) throws InterruptedException { + for(int i=1;i<=n;i=i+2){ + one.acquire(); + printNumber.accept(i); + zero.release(); + } + } +} \ No newline at end of file diff --git a/src/multithreading/thread/BasicMultiThreading.java b/src/multithreading/thread/BasicMultiThreading.java new file mode 100644 index 0000000..b6864da --- /dev/null +++ b/src/multithreading/thread/BasicMultiThreading.java @@ -0,0 +1,28 @@ +package thread; + +public class BasicMultiThreading extends Thread { + + public static void main(String[] args) { + BasicMultiThreading thread = new BasicMultiThreading(); + BasicMultiThreading thread2 = new BasicMultiThreading(); + thread.start(); + thread2.start(); + + thread.run(); + thread2.run(); + + for (int i = 0; i < 5; i++) { + System.out.println("Thread is running on track :" + i + "-->" + thread.getName() + " " + thread.getState()); + System.out.println("Thread 2 is running : " + thread2.getName() + " " + thread2.getState()); + try { + thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public void printThread() { + + } +} diff --git a/src/multithreading/thread/DeadLock.java b/src/multithreading/thread/DeadLock.java new file mode 100644 index 0000000..2b4b3f7 --- /dev/null +++ b/src/multithreading/thread/DeadLock.java @@ -0,0 +1,44 @@ +package thread; + +public class DeadLock { + public static void main(String[] args) { + final String resource1 = "ratan jaiswal"; + final String resource2 = "vimal jaiswal"; + // t1 tries to lock resource1 then resource2 + Thread t1 = new Thread() { + public void run() { + synchronized (resource1) { + System.out.println("Thread 1: locked resource 1"); + + try { + Thread.sleep(100); + } catch (Exception e) { + } + // resource1.notify(); + + synchronized (resource2) { + System.out.println("Thread 1: locked resource 2"); + } + + } + } + }; + + // t2 tries to lock resource2 then resource1 + Thread t2 = new Thread() { + public void run() { + synchronized (resource2) { + System.out.println("Thread 2: locked resource 2"); + //resource2.notify(); + synchronized (resource1) { + System.out.println("Thread 2: locked resource 1"); + } + } + } + }; + + t1.start(); + t2.start(); + } + +} diff --git a/src/multithreading/thread/PrintEvenOddTester.java b/src/multithreading/thread/PrintEvenOddTester.java new file mode 100644 index 0000000..9b44370 --- /dev/null +++ b/src/multithreading/thread/PrintEvenOddTester.java @@ -0,0 +1,68 @@ +package thread; + +public class PrintEvenOddTester { + + public static void main(String... args) { + Printer print = new Printer(); + Thread t1 = new Thread(new TaskEvenOdd(print, 10, false)); + Thread t2 = new Thread(new TaskEvenOdd(print, 10, true)); + t1.start(); + t2.start(); + } +} + +class TaskEvenOdd implements Runnable { + + private int max; + private Printer print; + private boolean isEvenNumber; + + TaskEvenOdd(Printer print, int max, boolean isEvenNumber) { + this.print = print; + this.max = max; + this.isEvenNumber = isEvenNumber; + } + + @Override + public void run() { + int number = isEvenNumber == true ? 2 : 1; + while (number <= max) { + if (isEvenNumber) { + print.printEven(number); + } else { + print.printOdd(number); + } + number += 2; + } + } +} + +class Printer { + boolean isOdd = false; + + synchronized void printEven(int number) { + while (isOdd == false) { + try { + wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("Even:" + number + "::" + Thread.currentThread().getName()); + isOdd = false; + notifyAll(); + } + + synchronized void printOdd(int number) { + while (isOdd == true) { + try { + wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("Odd:" + number + "::" + Thread.currentThread().getName()); + isOdd = true; + notifyAll(); + } +} \ No newline at end of file diff --git a/src/multithreading/thread/PrintOddEvenByTwoThreads.java b/src/multithreading/thread/PrintOddEvenByTwoThreads.java new file mode 100644 index 0000000..3283214 --- /dev/null +++ b/src/multithreading/thread/PrintOddEvenByTwoThreads.java @@ -0,0 +1,60 @@ +package thread; +public class PrintOddEvenByTwoThreads { + static int number = 1; + static Thread odd; + static Thread even; + static int max = 10; + + static class OddThread extends Thread { + @Override + public void run() { + while (number <= max) { + if (number % 2 == 1) { + System.out.println(Thread.currentThread() + "" + number++); + } else { + + synchronized (odd) { + synchronized (even) { + even.notify(); + } + try { + wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + } + } + + static class EvenThread extends Thread { + @Override + public void run() { + while (number <= max) { + if (number % 2 == 0) { + System.out.println(Thread.currentThread() + "" + number++); + } else { + + synchronized (even) { + synchronized (odd) { + odd.notify(); + } + try { + wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + } + } + + public static void main(String[] args) throws InterruptedException { + odd = new OddThread(); + even = new EvenThread(); + odd.start(); + even.start(); + } +} \ No newline at end of file diff --git a/src/multithreading/thread/RaceConditionExample.java b/src/multithreading/thread/RaceConditionExample.java new file mode 100644 index 0000000..7137a6a --- /dev/null +++ b/src/multithreading/thread/RaceConditionExample.java @@ -0,0 +1,54 @@ +package thread; + +class Counter implements Runnable{ + private int c = 0; + + public void increment() { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + c++; + } + + public void decrement() { + c--; + } + + public int getValue() { + return c; + } + + @Override + public void run() { + //synchronized(this) { + // incrementing + for(int i=0;i<100;i++) { + this.increment(); +// System.out.println("Value for Thread After increment " +// + Thread.currentThread().getName() + " " + this.getValue()); + //decrementing + this.decrement(); +// System.out.println("Value for Thread at last " + Thread.currentThread().getName() +// + " " + this.getValue()); + //} + } + } +} + +public class RaceConditionExample { + public static void main(String[] args) { + Counter counter = new Counter(); + Thread t1 = new Thread(counter, "Thread-A"); + Thread t2 = new Thread(counter, "Thread-B"); + Thread t3 = new Thread(counter, "Thread-C"); + t1.start(); + t2.start(); + t3.start(); + + + + System.out.println("#### "+counter.getValue()); + } +} \ No newline at end of file diff --git a/src/multithreading/thread/Tesst.java b/src/multithreading/thread/Tesst.java new file mode 100644 index 0000000..c1ed20a --- /dev/null +++ b/src/multithreading/thread/Tesst.java @@ -0,0 +1,38 @@ +package thread; + +public class Tesst { + + static class ThreadA { + + public static void main(String [] args) { + ThreadB b = new ThreadB(); + b.setName("test1"); + b.start(); + + synchronized(b) { + System.out.println("inside sync"); + try { + b.wait(); + System.out.println("Waiting for b to complete..."); + + System.out.println("after "+" "+b.getState()); + } catch (InterruptedException e) {} + System.out.println("Total is: " + b.total); + } + } + } + + static class ThreadB extends Thread { + int total; + + public void run() { + System.out.println("total"+total); + synchronized(this) { + for(int i = 0; i < 100; i++) { + total += i; + } + notify(); + } + } + } +} diff --git a/src/multithreading/thread/TestForLocking.java b/src/multithreading/thread/TestForLocking.java new file mode 100644 index 0000000..65e782a --- /dev/null +++ b/src/multithreading/thread/TestForLocking.java @@ -0,0 +1,51 @@ +package thread; + +import java.util.Date; + +public class TestForLocking { + public static void main(String[] args) throws Exception { + testCuncurrency(); + } + + private static void testCuncurrency() throws InterruptedException { + Object lock = new Object(); + Thread t1 = new Thread(new WaitTester(lock)); + Thread t2 = new Thread(new WaitTester(lock)); + t1.start(); + t2.start(); + Thread.sleep(15 * 1000); + synchronized (lock) { + System.out.println("Time: " + new Date().toString()+ ";" + "Notifying all"); + lock.notifyAll(); + } + } + + private static class WaitTester implements Runnable { + private Object lock; + public WaitTester(Object lock) { + this.lock = lock; + } + + @Override + public void run() { + try { + synchronized (lock) { + System.out.println(getTimeAndThreadName() + ":only one thread can be in synchronized block"); + Thread.sleep(5 * 1000); + + System.out.println(getTimeAndThreadName() + ":thread goes into waiting state and releases the lock"); + lock.wait(); + + System.out.println(getTimeAndThreadName() + ":thread is awake and have reacquired the lock"); + + System.out.println(getTimeAndThreadName() + ":syncronized block have finished"); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + private static String getTimeAndThreadName() { + return "Time: " + new Date().toString() + ";" + Thread.currentThread().getName(); + } +} \ No newline at end of file diff --git a/src/multithreading/thread/ThreadJoinExample.java b/src/multithreading/thread/ThreadJoinExample.java new file mode 100644 index 0000000..7198756 --- /dev/null +++ b/src/multithreading/thread/ThreadJoinExample.java @@ -0,0 +1,57 @@ +package thread; + +public class ThreadJoinExample { + + public static void main(String[] args) { + Thread t1 = new Thread(new MyRunnable(), "t1"); + Thread t2 = new Thread(new MyRunnable(), "t2"); + Thread t3 = new Thread(new MyRunnable(), "t3"); + + t1.start(); + + //start second thread after waiting for 2 seconds or if it's dead + try { + t1.join(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + t2.start(); + + //start third thread only when first thread is dead + try { + t1.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + t3.start(); + + //let all threads finish execution before finishing main thread +// try { +// t1.join(); +// t2.join(); +// t3.join(); +// } catch (InterruptedException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } + + System.out.println("All threads are dead, exiting main thread"); + } + +} + +class MyRunnable implements Runnable { + + @Override + public void run() { + System.out.println("Thread started: "+Thread.currentThread().getName()); + try { + Thread.sleep(4000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("Thread ended: "+Thread.currentThread().getName()); + } +} \ No newline at end of file diff --git a/src/multithreading/thread/ThreadRunnable.java b/src/multithreading/thread/ThreadRunnable.java new file mode 100644 index 0000000..433ad68 --- /dev/null +++ b/src/multithreading/thread/ThreadRunnable.java @@ -0,0 +1,32 @@ +package thread; + +public class ThreadRunnable implements Runnable { + + public static void main(String[] args) throws InterruptedException { + ThreadRunnable runnableThread = new ThreadRunnable(); + Thread t1 = new Thread(runnableThread); + t1.setName("t1"); + Thread t2 = new Thread(runnableThread); + t2.setName("t2"); + + t1.setPriority(Thread.MIN_PRIORITY); + t1.start(); + + t2.setPriority(Thread.MAX_PRIORITY); + t2.start(); + } + + @Override + public void run() { + for (int i = 0; i < 5; i++) { + if (Thread.currentThread().getName().equals("t1")) + System.out.println(Thread.currentThread().getName() + "--" + i); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + +} diff --git a/src/strings/common/sorting/ImplementABinaryHeap.java b/src/strings/common/sorting/ImplementABinaryHeap.java new file mode 100644 index 0000000..9db2639 --- /dev/null +++ b/src/strings/common/sorting/ImplementABinaryHeap.java @@ -0,0 +1,248 @@ +package common.sorting; +/* + A min heap implementation + + Array Form: [ 5, 7, 6, 10, 15, 17, 12 ] + + Complete Binary Tree Form: + 5 + / \ + 7 6 + / \ / \ + 10 15 17 12 + + Mappings: + Parent -> (childIndex - 1) / 2 + Left Child -> 2 * parentIndex + 1 + Right Child -> 2 * parentIndex + 2 + + YouTube explanation: https://www.youtube.com/watch?v=g9YK6sftDi0 + Heap Sort explanation: https://www.youtube.com/watch?v=k72DtCnY4MU +*/ +import java.util.*; + +public class ImplementABinaryHeap { + int[] insertItems = new int[]{ 0, 1, 3, 2, -4, 9, 1, 2 }; + public static void main(String args[]) { + MinHeap minHeap = new MinHeap(); + int[] insertItems = new int[]{ 0, 1, 3, 2, -4, 9, 1, 2 }; + + for (int i = 0; i < insertItems.length; i++) { + minHeap.add(insertItems[i]); + System.out.println("Add " + insertItems[i]); + System.out.println("Min is " + minHeap.peek()); + + minHeap.printUnderlyingArray(); + + System.out.println("\n"); + } + + System.out.println("\n\n"); + + for (int i = 0; i < insertItems.length; i++) { + System.out.println("Remove " + minHeap.remove()); + System.out.println("Min is " + minHeap.peek()); + + minHeap.printUnderlyingArray(); + + System.out.println("\n"); + } + } + + private static class MinHeap { + private int capacity = 5; + private int heap[]; + private int size; + // int[] temp= new ImplementABinaryHeap().insertItems; + public MinHeap() { + heap = new int[capacity]; + } + + public boolean isEmpty() { + return size == 0; + } + + public int peek() { + if (isEmpty()) { + throw new NoSuchElementException("Heap is empty."); + } + + return heap[0]; + } + + public int remove() { + if (isEmpty()) { + throw new NoSuchElementException("Heap is empty."); + } + + /* + -> Grab the min item. It is at index 0. + -> Move the last item in the heap to the "top" of the + heap at index 0. + -> Reduce size. + */ + int minItem = heap[0]; + heap[0] = heap[size - 1]; + size--; + + /* + Restore the heap since it is very likely messed up now + by bubbling down the element we swapped up to index 0 + */ + heapifyDown(); + + return minItem; + } + + public void add(int itemToAdd) { + ensureExtraCapacity(); + + /* + -> Place the item at the bottom, far right, of the + conceptual binary heap structure + -> Increment size + */ + heap[size] = itemToAdd; + size++; + + /* + Restore the heap since it is very likely messed up now + by bubbling up the element we just put in the last empty + position of the conceptual complete binary tree + */ + siftUp(); + } + + /*********************************** + Heap restoration helpers + ***********************************/ + + private void heapifyDown() { + /* + We will bubble down the item just swapped to the "top" of the heap + after a removal operation to restore the heap + */ + int index = 0; + + /* + Since a binary heap is a complete binary tree, if we have no left child + then we have no right child. So we continue to bubble down as long as + there is a left child. + + A non-existent left child immediately tells us that a right child does + not exist. + */ + while (hasLeftChild(index)) { + /* + By default assume that left child is smaller. If a right + child exists see if it can overtake the left child by + being smaller + */ + int smallerChildIndex = getLeftChildIndex(index); + if (hasRightChild(index) && rightChild(index) < leftChild(index)) { + smallerChildIndex = getRightChildIndex(index); + } + + /* + If the item we are sitting on is < the smaller child then + nothing needs to happen & sifting down is finished. + + But if the smaller child is smaller than the node we are + holding, we should swap and continue sifting down. + */ + if (heap[index] < heap[smallerChildIndex]) { + break; + } else { + swap(index, smallerChildIndex); + } + + // Move to the node we just swapped down + index = smallerChildIndex; + } + } + + // Bubble up the item we inserted at the "end" of the heap + private void siftUp() { + /* + We will bubble up the item just inserted into to the "bottom" + of the heap after an insert operation. It will be at the last index + so index 'size' - 1 + */ + int index = size - 1; + + /* + While the item has a parent and the item beats its parent in + smallness, bubble this item up. + */ + while (hasParent(index) && heap[index] < parent(index)) { + swap(getParentIndex(index), index); + index = getParentIndex(index); + } + } + + /************************************************ + Helpers to access our array easily, perform + rudimentary operations, and manipulate capacity + ************************************************/ + + private void swap(int indexOne, int indexTwo) { + int temp = heap[indexOne]; + heap[indexOne] = heap[indexTwo]; + heap[indexTwo] = temp; + } + + // If heap is full then double capacity + private void ensureExtraCapacity() { + if (size == capacity) { + heap = Arrays.copyOf(heap, capacity * 2); + capacity *= 2; + } + } + + private int getLeftChildIndex(int parentIndex) { + return 2 * parentIndex + 1; + } + + private int getRightChildIndex(int parentIndex) { + return 2 * parentIndex + 2; + } + + private int getParentIndex(int childIndex) { + return (childIndex - 1) / 2; + } + + private boolean hasLeftChild(int index) { + return getLeftChildIndex(index) < size; + } + + private boolean hasRightChild(int index) { + return getRightChildIndex(index) < size; + } + + private boolean hasParent(int index) { + return index != 0 && getParentIndex(index) >= 0; + } + + private int leftChild(int index) { + return heap[getLeftChildIndex(index)]; + } + + private int rightChild(int index) { + return heap[getRightChildIndex(index)]; + } + + private int parent(int index) { + return heap[getParentIndex(index)]; + } + + /***********************************************/ + + private void printUnderlyingArray() { + System.out.print("[ "); + for (int item: heap) { + System.out.print(item + " "); + } + System.out.print("]"); + } + } +} \ No newline at end of file diff --git a/src/strings/common/sorting/InsertionSort.java b/src/strings/common/sorting/InsertionSort.java new file mode 100644 index 0000000..985edc8 --- /dev/null +++ b/src/strings/common/sorting/InsertionSort.java @@ -0,0 +1,30 @@ +package common.sorting; + +public class InsertionSort { + + public static void main(String[] args) { + int[] arr = { 12, 11, 13, 5, 6 }; +System.out.println(System.currentTimeMillis()); + + for (int i = 1; i < arr.length; i++) { + int index =i; + for (int j = i-1; j >= 0; j--) { + int value = arr[index]; + if (arr[index] < arr[j]) { + int temp = arr[j]; + arr[j] = value; + arr[index] = temp; + index--; + }else{ + continue; + } + } + } + System.out.println(System.currentTimeMillis()); + + for (int i = 0; i < arr.length; i++) { + System.out.println(arr[i]); + } + } + +} diff --git a/src/strings/common/sorting/KthLargestElement.java b/src/strings/common/sorting/KthLargestElement.java new file mode 100644 index 0000000..4c2f8d3 --- /dev/null +++ b/src/strings/common/sorting/KthLargestElement.java @@ -0,0 +1,62 @@ +package common.sorting; + +import java.util.*; + +public class KthLargestElement { + class Solution { + public int findKthLargest(int[] nums, int k) { + + return quickSelect(nums, 0, nums.length-1,nums.length-k); + } + + public void swap(int[] A, int i, int j) { + int temp = A[i]; + A[i] = A[j]; + A[j] = temp; + } + + public int partition(int[] nums, int start, int end) { + Random rand= new Random(); + //Get a random pivot between beg and end + int pivotIndex= start+rand.nextInt(Math.abs(end-start)); + + //New position of pivot element + int last=end; + + //Move the pivot element to right edge of the array + swap(nums,pivotIndex,end); + + end--; + + while(start<=end){ + if(nums[start]= 0; i--) + heapify(arr, i, n); + + for (int i = 0; i < n; i++) + System.out.print(arr[i] + " "); + + System.out.println(); + for (int i = n - 1; i >= 0; i--) { + int temp = arr[0]; + arr[0] = arr[i]; + arr[i] = temp; + + heapify(arr, 0, i); + } + + for (int i = 0; i < n; i++) + System.out.print(arr[i] + " "); + } + + private void heapify(int[] arr, int i, int n) { + int largest = i; + int left = 2 * i + 1; + int right = 2 * i + 2; + + if (left < n && arr[left] > arr[largest]) + largest = left; + if (right < n && arr[right] > arr[largest]) + largest = right; + if (largest != i) { + int temp = arr[largest]; + arr[largest] = arr[i]; + arr[i] = temp; + + heapify(arr, largest, n); + } + } +} \ No newline at end of file diff --git a/src/strings/common/sorting/MergeSort.java b/src/strings/common/sorting/MergeSort.java new file mode 100644 index 0000000..811f016 --- /dev/null +++ b/src/strings/common/sorting/MergeSort.java @@ -0,0 +1,47 @@ +package common.sorting; + +import java.util.Arrays; + +class MergeSort { + + static void mergeSort(int arr[], int temp[], int left, int right) { + if (left < right) { + int mid = ((right - left) / 2) + left; + + mergeSort(arr, temp, left, mid); + mergeSort(arr, temp, mid + 1, right); + + merge(arr, temp, left, mid, right); + } + } + + static void merge(int arr[], int temp[], int left, int mid, int right) { + + int i = left; + int j = mid + 1; + int k = left; + while ((i <= mid) && (j <= right)) { + if (arr[i] < arr[j]) { + temp[k++] = arr[i++]; + } else { + temp[k++] = arr[j++]; + } + } + + while (i <= mid) + temp[k++] = arr[i++]; + while (j <= right) + temp[k++] = arr[j++]; + + for (i = left; i <= right; i++) + arr[i] = temp[i]; + + } + + public static void main(String[] args) { + int arr[] = new int[] { 8, 4, 1, 2 }; + int temp[] = new int[arr.length]; + mergeSort(arr, temp, 0, arr.length - 1); + System.out.println(Arrays.toString(arr)); + } +} diff --git a/src/strings/common/sorting/PractiseMergeSort.java b/src/strings/common/sorting/PractiseMergeSort.java new file mode 100644 index 0000000..78c6cae --- /dev/null +++ b/src/strings/common/sorting/PractiseMergeSort.java @@ -0,0 +1,48 @@ +package common.sorting; + +import java.util.Arrays; + +public class PractiseMergeSort { + + public static void main(String[] args) { + int[] arr = { 9, 3, -1, 5, 2, 7 }; + int n = arr.length; + int[] temp = new int[n]; + mergeSort(arr, temp, 0, n - 1); + System.out.println(Arrays.toString(arr)); + } + + private static void mergeSort(int arr[], int temp[], int left, int right) { + while (left < right) { + int mid = ((right - left) / 2) + left; + mergeSort(arr, temp, left, mid); + mergeSort(arr, temp, mid + 1, right); + mergeUtil(arr, temp, left, mid, right); + } + } + + private static void mergeUtil(int[] arr, int[] temp, int left, int mid, int right) { + int i = left; + int j = mid + 1; + int k = left; + + while (i <= mid && j <= right) { + if (arr[i] < arr[j]) { + temp[k++] = arr[i++]; + } else { + temp[k++] = arr[j++]; + } + } + + while (i <= mid) { + temp[k++] = arr[i++]; + } + while (j <= right) { + temp[k++] = arr[j++]; + } + + for (int index = left; index <= right; index++) { + arr[index] = temp[index]; + } + } +} diff --git a/src/strings/common/sorting/QuickSelect.java b/src/strings/common/sorting/QuickSelect.java new file mode 100644 index 0000000..b407d67 --- /dev/null +++ b/src/strings/common/sorting/QuickSelect.java @@ -0,0 +1,50 @@ +package common.sorting; + +import java.util.Random; + +class QuickSelect { + + public static void swap(int[] A, int i, int j) { + int temp = A[i]; + A[i] = A[j]; + A[j] = temp; + } + + public static int partition(int[] A, int low, int high, int pivotIndex) { + int pivot = A[pivotIndex]; + swap(A, pivotIndex, high); + int iLow = low; + for (int i = low; i < high; i++) { + if (A[i] <= pivot) { + swap(A, i, iLow); + iLow++; + } + } + swap(A, iLow, high); + return iLow; + } + + public static int quickSelect(int[] A, int left, int right, int k) { + if (left == right) { + return A[left]; + } + int pivotIndex = new Random().nextInt(right - left + 1) + left; + pivotIndex = partition(A, left, right, pivotIndex); + if (k == pivotIndex) { + return A[k]; + } else if (k < pivotIndex) { + return quickSelect(A, left, pivotIndex - 1, k); + } else { + return quickSelect(A, pivotIndex + 1, right, k); + } + } + + public static void main(String[] args) { + int[] A = { 7, 4, 6, 3, 9, 1 }; + int k = 2; + + System.out.print("K'th smallest element is " + quickSelect(A, 0, A.length - 1, k)); + } +} + + diff --git a/src/strings/common/sorting/QuickSort.java b/src/strings/common/sorting/QuickSort.java new file mode 100644 index 0000000..25691d7 --- /dev/null +++ b/src/strings/common/sorting/QuickSort.java @@ -0,0 +1,57 @@ +package common.sorting; + +import java.util.Random; + +public class QuickSort { + + public int[] sortArray(int[] nums) { + + quickSort(nums, 0, nums.length-1); + + return nums; +} + + public void quickSort(int[] nums, int start, int end){ + if(start= (r - index)); i++) { + data[index] = sequence[i]; + combinations(sequence, data, i + 1, end, index + 1, r); + } + } + + public static void main(String args[]) { + char[] sequence = { 'a', 'b', 'c' }; + System.out.print("The combinations are: "); + printCombinations(sequence, sequence.length); + } +} \ No newline at end of file diff --git a/src/strings/dynamicProblems/DynamicIntegerGenerator.java b/src/strings/dynamicProblems/DynamicIntegerGenerator.java new file mode 100644 index 0000000..686332c --- /dev/null +++ b/src/strings/dynamicProblems/DynamicIntegerGenerator.java @@ -0,0 +1,29 @@ +package dynamicProblems; + +public class DynamicIntegerGenerator { + + public static void main(String[] args) { + + int[] arr = { 3, 4, 5, 6, 7, 8 }; + + for (int i = 1; i <= arr.length; i++) { + printDynamicIntegers(i, arr); + System.out.println(); + } + + } + + private static void printDynamicIntegers(int i, int[] arr) { + if (arr.length == i) { + for (int u = 0; u < arr.length; u++) { + System.out.print(arr[u]); + } + } + int[] intArr = new int[i]; + for (int j = 0; j < arr.length; j++) { + intArr[j] = arr[j]; + printDynamicIntegers(i, intArr); + } + } + +} diff --git a/src/strings/dynamicProblems/FirstNonRepeating.java b/src/strings/dynamicProblems/FirstNonRepeating.java new file mode 100644 index 0000000..e4e4893 --- /dev/null +++ b/src/strings/dynamicProblems/FirstNonRepeating.java @@ -0,0 +1,34 @@ +package dynamicProblems; + +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.Queue; + +public class FirstNonRepeating { + + public static void main(String[] args) { + String data = "GeeksforGeeks"; + char[] arr = data.toCharArray(); + Queue stack = new LinkedList(); + for (char d : arr) { + stack.add(d); + } + while (!stack.isEmpty()) { + Character pop = stack.remove(); + if (!stack.contains(pop)) { + System.out.println(pop); + } + } + + Integer[] arrVal = {23,87,5,36,90,65}; + Arrays.sort(arrVal,Collections.reverseOrder()); + + for(Integer in:arrVal){ + System.out.print(in+" "); + } + } + + + +} diff --git a/src/strings/dynamicProblems/PossibleCombinations.java b/src/strings/dynamicProblems/PossibleCombinations.java new file mode 100644 index 0000000..6ecd902 --- /dev/null +++ b/src/strings/dynamicProblems/PossibleCombinations.java @@ -0,0 +1,29 @@ +package dynamicProblems; + +public class PossibleCombinations { + + public static void main(String[] args) { + char[] arr = { 'a', 'b', 'c' }; + combinations(arr, arr.length); + } + + private static void combinations(char[] arr, int length) { + char[] duplicate = new char[length]; + for (int r = 1; r <= length; r++) { + printCombinations(arr, duplicate, 0, length, 0, r); + } + + } + + private static void printCombinations(char[] arr, char[] data, int start, int end, int index, int r) { + if (index == r) { + for (int i = 0; i < r; i++) + System.out.print(data[i] + " "); + System.out.println(); + } + for (int i = start; i < end; i++) { + data[index] = arr[i]; + printCombinations(arr, data, i + 1, end, index + 1, r); + } + } +} diff --git a/src/strings/dynamicProblems/ReverseSentence.java b/src/strings/dynamicProblems/ReverseSentence.java new file mode 100644 index 0000000..afa026c --- /dev/null +++ b/src/strings/dynamicProblems/ReverseSentence.java @@ -0,0 +1,17 @@ +package dynamicProblems; + +import java.util.StringTokenizer; + +public class ReverseSentence { + + public static void main(String[] args) { + String sentence = "This is a Career Monk String"; + StringTokenizer st = new StringTokenizer(sentence); + String reverse = ""; + while (st.hasMoreTokens()) { + reverse = st.nextToken() + " " + reverse; + } + System.out.println(reverse); + } + +} \ No newline at end of file diff --git a/src/strings/dynamicProblems/Subsequence.java b/src/strings/dynamicProblems/Subsequence.java new file mode 100644 index 0000000..3f5dfe7 --- /dev/null +++ b/src/strings/dynamicProblems/Subsequence.java @@ -0,0 +1,36 @@ +package dynamicProblems; + +import java.util.HashSet; + +public class Subsequence { + + static HashSet st = new HashSet<>(); + + static void subsequence(String str) { + for (int i = 0; i < str.length(); i++) { + + for (int j = str.length(); j > i; j--) { + String sub_str = str.substring(i, j); + + if (!st.contains(sub_str)) + st.add(sub_str); + + for (int k = 1; k < sub_str.length() - 1; k++) { + StringBuffer sb = new StringBuffer(sub_str); + + sb.deleteCharAt(k); + if (!st.contains(sb)) + ; + subsequence(sb.toString()); + } + } + } + } + + // Driver code + public static void main(String[] args) { + String s = "abc"; + subsequence(s); + System.out.println(st); + } +} \ No newline at end of file diff --git a/src/strings/stringProblems/Combination.java b/src/strings/stringProblems/Combination.java new file mode 100644 index 0000000..4c362b2 --- /dev/null +++ b/src/strings/stringProblems/Combination.java @@ -0,0 +1,54 @@ +package stringProblems; + +import java.util.*; + +public class Combination { + + public void combination(char input[]) { + Map countMap = new TreeMap<>(); + for (char ch : input) { + countMap.compute(ch, (key, val) -> { + if (val == null) { + return 1; + } else { + return val + 1; + } + }); + } + char str[] = new char[countMap.size()]; + int count[] = new int[countMap.size()]; + int index = 0; + for (Map.Entry entry : countMap.entrySet()) { + str[index] = entry.getKey(); + count[index] = entry.getValue(); + index++; + } + char[] output = new char[input.length]; + combination(str, count, 0, output, 0); + } + + private void combination(char[] str, int[] count, int level, char[] result, int pos) { + print(result, level); + for (int i = pos; i < str.length; i++) { + if (count[i] != 0) { + result[level] = str[i]; + count[i]--; + combination(str, count, level + 1, result, pos); + count[i]++; + } + } + } + + private void print(char result[], int pos) { + for (int i = 0; i < pos; i++) { + System.out.print(result[i] + " "); + } + System.out.println(); + } + + public static void main(String args[]) { + Combination c = new Combination(); + c.combination("abc".toCharArray()); + } + +} \ No newline at end of file diff --git a/src/strings/stringProblems/DistinctSubstring.java b/src/strings/stringProblems/DistinctSubstring.java new file mode 100644 index 0000000..c620315 --- /dev/null +++ b/src/strings/stringProblems/DistinctSubstring.java @@ -0,0 +1,33 @@ +package stringProblems; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +public class DistinctSubstring { + + public static List kSubstring(String s, int k) { + Set window = new LinkedHashSet<>(); + Set result = new LinkedHashSet<>(); + for (int start = 0, end = 0; end < s.length(); end++) { + while (window.contains(s.charAt(end))) { + window.remove(s.charAt(start)); + start++; + } + + window.add(s.charAt(end)); + + if (window.size() == k) { + result.add(s.substring(start, end + 1)); + window.remove(s.charAt(start)); + start++; + } + } + return new ArrayList<>(result); + } + + public static void main(String[] args) { + System.out.println(kSubstring("awaglknagawunagwkwagl", 4)); + } +} \ No newline at end of file diff --git a/src/strings/stringProblems/FindLongestStringInArray.java b/src/strings/stringProblems/FindLongestStringInArray.java new file mode 100644 index 0000000..3d649bd --- /dev/null +++ b/src/strings/stringProblems/FindLongestStringInArray.java @@ -0,0 +1,26 @@ +package stringProblems; + +import java.util.Arrays; +import java.util.Comparator; + +public class FindLongestStringInArray { + + public static void main(String[] args) { + String arr[] = { "geeks", "for", "geeksfor", "geeksforgeeks" }; + StringComparator str = new StringComparator(); + Arrays.sort(arr, str); + System.out.println(Arrays.toString(arr)); + } +} + +class StringComparator implements Comparator { + + @Override + public int compare(String o1, String o2) { + if (o1.length() > o2.length()) { + return -1; + } + return 0; + } + +} \ No newline at end of file diff --git a/src/strings/stringProblems/MostCommonWord.java b/src/strings/stringProblems/MostCommonWord.java new file mode 100644 index 0000000..27c8fd1 --- /dev/null +++ b/src/strings/stringProblems/MostCommonWord.java @@ -0,0 +1,77 @@ +package stringProblems; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +class MostCommonWord { + public String mostCommonWord(String paragraph, String[] banned) { + + String[] arr = paragraph.split("[\\s,]+"); + boolean isBanned = banned == null || banned.length == 0 ? true : false; + Map map = new HashMap(); + for (int i = 0; i < arr.length; i++) { + String val = arr[i].toLowerCase().trim().replaceAll("[^a-z]", ""); + map.put(val, map.getOrDefault(val, 0) + 1); + } + int max = 0; + String result = ""; + for (Map.Entry entry : map.entrySet()) { + boolean isBannedWord = false; + if (entry.getValue() > max) { + if (!isBanned) { + for (int i = 0; i < banned.length; i++) { + if (banned[i].equals(entry.getKey())) { + isBannedWord = true; + break; + } + } + } + if (!isBannedWord) { + max = entry.getValue(); + result = entry.getKey(); + } + } + } + return result; + } + + public String mostCommonWordLeetCode(String paragraph, String[] banned) { + paragraph += "."; + + Set banset = new HashSet(); + for (String word : banned) + banset.add(word); + Map count = new HashMap(); + + String ans = ""; + int ansfreq = 0; + + StringBuilder word = new StringBuilder(); + for (char c : paragraph.toCharArray()) { + if (Character.isLetter(c)) { + word.append(Character.toLowerCase(c)); + } else if (word.length() > 0) { + String finalword = word.toString(); + if (!banset.contains(finalword)) { + count.put(finalword, count.getOrDefault(finalword, 0) + 1); + if (count.get(finalword) > ansfreq) { + ans = finalword; + ansfreq = count.get(finalword); + } + } + word = new StringBuilder(); + } + } + + return ans; + } + + public static void main(String[] args) { + String paragraph = "Bob hit a ball, the hit BALL flew far after it was hit."; + String[] banned = { "hit" }; + MostCommonWord mcw = new MostCommonWord(); + System.out.println(mcw.mostCommonWord(paragraph, banned)); + } +} \ No newline at end of file diff --git a/src/strings/stringProblems/PermutationAndCombination.java b/src/strings/stringProblems/PermutationAndCombination.java new file mode 100644 index 0000000..9f77d55 --- /dev/null +++ b/src/strings/stringProblems/PermutationAndCombination.java @@ -0,0 +1,91 @@ +package stringProblems; + +import java.util.Map; +import java.util.TreeMap; + +public class PermutationAndCombination { + + public static void main(String args[]) { + PermutationAndCombination sp = new PermutationAndCombination(); + sp.permute("ABC".toCharArray()); + + } + + private void permute(char[] charArray) { + Map map = new TreeMap<>(); + for (char ch : charArray) { + map.compute(ch, (key, val) -> { + if (val == null) { + return 1; + } else { + return val + 1; + } + }); + } + + char[] str = new char[charArray.length]; + int[] count = new int[charArray.length]; + int index = 0; + for (Map.Entry ch : map.entrySet()) { + str[index] = ch.getKey(); + count[index] = ch.getValue(); + index++; + } + + char[] result = new char[charArray.length]; + + permutate(str, count, 0, result); + System.out.println("++++++++++++++++"); + combination(str, count, 0, new char[charArray.length], 0); + System.out.println("++++++++++++++++"); + permutationAndCombination(str, count, 0, result); + + } + + private void permutate(char[] str, int[] count, int level, char[] result) { + if (level == result.length) { + System.out.println(result); + return; + } + + for (int i = 0; i < str.length; i++) { + if (count[i] != 0) { + result[level] = str[i]; + count[i]--; + permutate(str, count, level + 1, result); + count[i]++; + } + } + } + + private void print(char[] result, int level) { + for (int i = 0; i < level; i++) { + System.out.print(result[i] + " "); + } + System.out.println(); + } + + private void permutationAndCombination(char[] str, int[] count, int level, char[] result) { + print(result, level); + for (int i = 0; i < str.length; i++) { + if (count[i] != 0) { + result[level] = str[i]; + count[i]--; + permutationAndCombination(str, count, level + 1, result); + count[i]++; + } + } + } + + private void combination(char[] str, int[] count, int level, char[] result, int pos) { + print(result, level); + for (int i = pos; i < str.length; i++) { + if (count[i] != 0) { + result[level] = str[i]; + count[i]--; + combination(str, count, level + 1, result, i); + count[i]++; + } + } + } +} diff --git a/src/strings/stringProblems/RearrangeCharactersInString.java b/src/strings/stringProblems/RearrangeCharactersInString.java new file mode 100644 index 0000000..dd8e01f --- /dev/null +++ b/src/strings/stringProblems/RearrangeCharactersInString.java @@ -0,0 +1,58 @@ +package stringProblems; + +import java.util.HashMap; +import java.util.Map; +import java.util.PriorityQueue; + +public class RearrangeCharactersInString { + + public static String rearrangeString(String S) { + if (S == null || S.length() == 0) { + return ""; + } + Map map = new HashMap<>(); + for (char c : S.toCharArray()) { + map.put(c, map.getOrDefault(c, 0) + 1); + } + + PriorityQueue> pq = new PriorityQueue<>((a, b) -> (b.getValue() - a.getValue())); + for (Map.Entry entry : map.entrySet()) { + pq.offer(entry); + } + + StringBuilder sb = new StringBuilder(); + while (!pq.isEmpty()) { + Map.Entry first = pq.poll(); + + if (sb.length() == 0 || first.getKey() != sb.charAt(sb.length() - 1)) { + sb.append(first.getKey()); + first.setValue(first.getValue() - 1); + + if (first.getValue() != 0) { + pq.offer(first); + } + } else { + Map.Entry second = pq.poll(); + // we do not have any other characters that different with current + // string tail + if (second == null) { + return ""; + } + sb.append(second.getKey()); + second.setValue(second.getValue() - 1); + + if (second.getValue() != 0) { + pq.offer(second); + } + // DO NOT FORGET to push top frequency entry into queue as well + pq.offer(first); + } + } + return sb.toString(); + } + + public static void main(String args[]) { + String str = "bbbaa"; + System.out.println(rearrangeString(str)); + } +} diff --git a/src/strings/stringmatching/KMP.java b/src/strings/stringmatching/KMP.java new file mode 100644 index 0000000..7b45321 --- /dev/null +++ b/src/strings/stringmatching/KMP.java @@ -0,0 +1,61 @@ +package stringmatching; + +import java.util.Arrays; + +public class KMP { + + public static void main(String[] args) { + String given = "abxabcabcabyasd"; + String pattern = "abcaby"; + int[] arr = formPrefixAndSuffixArray(pattern); + System.out.println(Arrays.toString(arr)); + System.out.println(kmp(arr, given.toCharArray(), pattern.toCharArray())); + } + + private static boolean kmp(int[] arr, char[] charArray, char[] cs) { + + int j = 0; + int i = 0; + for (; j < cs.length && i < charArray.length;) { + if (cs[j] == charArray[i]) { + j++; + i++; + } else { + if (j != 0) { + j = arr[j - 1]; + } else { + i++; + } + } + } + + if (j == arr.length) { + return true; + } + + return false; + } + + private static int[] formPrefixAndSuffixArray(String pattern) { + + char[] arr = pattern.toCharArray(); + int value = 0; + int[] valueArr = new int[arr.length]; + valueArr[0] = 0; + for (int i = 1; i < arr.length;) { + if (arr[value] == arr[i]) { + valueArr[i] = ++value; + i++; + } else { + if (value != 0) { + value = valueArr[value - 1]; + } else { + valueArr[i] = 0; + i++; + } + } + } + return valueArr; + } + +} diff --git a/src/strings/stringmatching/MaxProductString.java b/src/strings/stringmatching/MaxProductString.java new file mode 100644 index 0000000..c403614 --- /dev/null +++ b/src/strings/stringmatching/MaxProductString.java @@ -0,0 +1,47 @@ +package stringmatching; + +public class MaxProductString { + + public int maxProduct(String[] words) { + int[] checker = new int[words.length]; + int max = 0; + // populating the checker array with their respective numbers + for (int i = 0; i < checker.length; i++) { + int num = 0; + for (int j = 0; j < words[i].length(); j++) { + + // a 1->1 + // b 2->10 + // c 4->100 + // ab 3->11 + // ac 5->101 + // abc 7->111 + // az 33554433->10000000000000000000000001 + + num |= 1 << (words[i].charAt(j) - 'a'); + //System.out.println(words[i].charAt(j)+"->"+num+ "->"+Integer.toBinaryString(num) ); + } + + checker[i] = num; + } + + for (int i = 0; i < words.length; i++) { + for (int j = i + 1; j < words.length; j++) { + // abcd efgd + // 11110000 -> abcd + // and-ing these two might say if even a single char is present in other + if ((checker[i] & checker[j]) == 0) //checking if the two strings have common character + max = Math.max(max, words[i].length() * words[j].length()); + } + } + System.out.println(max); + return max; + } + + + public static void main(String[] args) { + // new MaxProductString().maxProduct(new String[]{"abcw", "baz", "foo", "bar", "xtfn", "abcdef"}); + + //new MaxProductString().backspaceCompare("isfcow#", "isfco#w#"); + } +} \ No newline at end of file diff --git a/src/strings/stringmatching/RabinKarp.java b/src/strings/stringmatching/RabinKarp.java new file mode 100644 index 0000000..53144a0 --- /dev/null +++ b/src/strings/stringmatching/RabinKarp.java @@ -0,0 +1,84 @@ +package stringmatching; + +public class RabinKarp { + + public static void main(String[] args) { + String givenValue = "abaaab"; + String input = "aaa"; + +// char[] givenArr = givenValue.toCharArray(); +// char[] inputArr = input.toCharArray(); +// +// int inputHash = createHash(inputArr, inputArr.length); +// int previousValue = 0; +// for (int i = 0; i < (givenArr.length - inputArr.length + 1); i++) { +// previousValue = givenHash(givenArr, i, previousValue); +// if (inputHash == previousValue && matchString(inputArr, givenArr, i)) { +// System.out.println("It exists"); +// } +// } + + rabinKarp(givenValue, input); + } + + private static int givenHash(char[] givenArr, int i, int previousValue) { + + if (previousValue == 0) { + return createHash(givenArr, 3); + } + + int currentValue = previousValue - givenArr[i - 1]; + System.out.println(currentValue + givenArr[i + 2] * 100); + return currentValue + givenArr[i + 2] * 100; + + } + + private static int createHash(char[] inputArr, int length) { + int hash = 0; + double power = 0; + for (int i = 0; i < length; i++) { + hash = hash + (int) Math.pow(10, power++) * inputArr[i]; + } + return hash; + } + + private static boolean matchString(char[] inputArr, char[] givenArr, int i) { + int index = 0; + for (int j = i; j < inputArr.length; j++) { + if (inputArr[index++] != givenArr[j]) { + return false; + } + } + return true; + } + + //the time complexity is O(m + n) + public static int rabinKarp(String t, String s) { + if (s.length() > t.length()) { + return -1; // s is not a substring of t. + } + final int BASE = 26; + int tHash = 0, sHash = 0; // Hash codes for the substring of t and s. + int powerS = 1; // this will be used to calculate the rolling hash when current window moves out + for (int i = 0; i < s.length(); i++) { + powerS = i > 0 ? powerS * BASE : 1; + tHash = tHash * BASE + t.charAt(i); + sHash = sHash * BASE + s.charAt(i); + } + for (int i = s.length(); i < t.length(); i++) { +// Checks the two substrings are actually equal or not, to protect +// against hash collision. + if (tHash == sHash ){ //&& t.substring(i - s.length(), i).equals(s)) { + return i - s.length(); // Found a match. + } +// Uses rolling hash to compute the new hash code. + tHash -= t.charAt(i - s.length()) * powerS; + tHash = tHash * BASE + t.charAt(i); + } +// Tries to match s and t.substring(t.length() - s.lengthO). + if (tHash == sHash){ // && t .substring(t.length() - s.length()).equals(s)){ + return t.length() - s.length(); + } + return -1; + } +} From cb60dd086ccf5eae3c66366943cb512460d54286 Mon Sep 17 00:00:00 2001 From: vignesh Date: Tue, 15 Sep 2020 17:07:30 +0530 Subject: [PATCH 37/51] refactoring codes --- src/SQL/AlterTableWithMonthName.sql | 35 +++ src/SQL/ClassHavingMoreStudents.sql | 29 ++ src/SQL/CustomersNerverOrders.sql | 24 ++ src/SQL/DeleteDuplicate.sql | 5 + src/SQL/DepartmentHighestSalary.sql | 50 ++++ src/SQL/DuplicateEmail.sql | 20 ++ src/SQL/EmployeeEarningHigherThanManagers.sql | 3 + src/SQL/ExchangeSeats.sql | 27 ++ src/SQL/FirstLoginDate.sql | 34 +++ src/SQL/ManagerHaving5OrMoreReport.sql | 22 ++ src/SQL/NthHighestSalary.sql | 10 + src/SQL/RisingTemperature.sql | 23 ++ src/SQL/SubjectRanks.sql | 36 +++ src/SQL/TeamSize.sql | 31 ++ src/SQL/Top3Salaries.sql | 19 ++ src/SQL/Top3SalaryDepartmentWise.sql | 22 ++ src/SQL/WinningCandidate.sql | 10 + src/geeksforgeeks/AdvantageShuffle.java | 7 +- src/geeksforgeeks/ArrangeInQueue.java | 6 +- src/geeksforgeeks/BasicCalculator.java | 3 + src/geeksforgeeks/BinaryTreeCousins.java | 3 + src/geeksforgeeks/BoatsToSave.java | 3 + .../BuyAndSellStockAtMostTwice.java | 4 +- src/geeksforgeeks/CloneGraph.java | 24 +- src/geeksforgeeks/CombinationIterator.java | 3 + .../ConstructTreeFromInorderAndPostorder.java | 5 +- .../ConstructTreeFromInorderAndPreorder.java | 3 +- src/geeksforgeeks/EvaluvateExpressions.java | 2 + src/geeksforgeeks/EvaluvateRPN.java | 3 + src/geeksforgeeks/FenwickTree.java | 2 +- src/geeksforgeeks/FindMissingNumbers.java | 4 + src/geeksforgeeks/FirstMissingPositive.java | 7 +- src/geeksforgeeks/GroupAnagrams.java | 3 + src/geeksforgeeks/HitCounter.java | 3 + src/geeksforgeeks/InMemeoryFIleSystem.java | 15 +- .../InorderSuccessorPredecessor.java | 49 +-- src/geeksforgeeks/InsertIntervals.java | 3 + src/geeksforgeeks/IsomorphicString.java | 8 +- src/geeksforgeeks/LRUCache.java | 7 +- src/geeksforgeeks/LargestPossibleNumber.java | 2 +- .../LinkedListRemoveDuplicates.java | 8 +- src/geeksforgeeks/MaxSoldiers.java | 4 +- src/geeksforgeeks/MaxWidthOfBinaryTree.java | 5 + src/geeksforgeeks/MedianOfKWindow.java | 3 + src/geeksforgeeks/MeetingRoomsII.java | 5 +- .../MergeIntervalIntersection.java | 3 + src/geeksforgeeks/MinStepsToConvertXtoY.java | 12 + src/geeksforgeeks/OverlappingIntervals.java | 2 + src/geeksforgeeks/OwnDataStructureUtil.java | 2 +- src/geeksforgeeks/PathSumIII.java | 76 ++--- src/geeksforgeeks/RangeSum.java | 2 +- src/geeksforgeeks/ReconstructItenary.java | 5 +- src/geeksforgeeks/RemoveKDigits.java | 5 +- src/geeksforgeeks/RemoveParanthesisValid.java | 5 +- src/geeksforgeeks/ReverseWordsInString.java | 2 + src/geeksforgeeks/SameTree.java | 2 + .../SerializeDeserializeBST.java | 4 + src/geeksforgeeks/ShipPackageWithNDays.java | 2 + src/geeksforgeeks/SnakeAndLadder.java | 2 +- src/geeksforgeeks/SortStack.java | 2 + src/geeksforgeeks/SpiralMatrix.java | 3 + src/geeksforgeeks/StockBuySellManyTimes.java | 7 + src/geeksforgeeks/StockSpanner.java | 15 +- .../SubArraySumDivisibleByK.java | 3 + src/geeksforgeeks/SubArraySumEqualsK.java | 4 + src/geeksforgeeks/SumSubArrayZero.java | 22 +- src/geeksforgeeks/SurroundedRegions.java | 25 +- src/geeksforgeeks/ThreeSum.java | 5 + src/geeksforgeeks/TimeMap.java | 4 +- src/geeksforgeeks/TopKFrequentElement.java | 7 +- src/geeksforgeeks/TwoCityScheduling.java | 4 +- src/geeksforgeeks/UniquePath.java | 2 +- src/geeksforgeeks/UrlEncode.java | 2 + src/geeksforgeeks/ValidSuduko.java | 5 +- src/geeksforgeeks/WordBreakII.java | 5 + src/geeksforgeeks/WordDictionary.java | 3 + src/geeksforgeeks/WordLadder.java | 2 + .../Combinations.java | 2 +- .../Permutations.java | 2 +- .../CombinationsAndPermutations/SubSets.java | 2 +- src/graph/adjacencyList/AdjacencyList.java | 2 +- .../adjacencyMatrix/AdjacencyMatrix.java | 2 +- src/graph/bellmanFord/BellmanFord.java | 2 +- src/graph/bellmanFord/Edge.java | 2 +- src/graph/bellmanFord/Graph.java | 2 +- src/graph/bellmanFord/NegativeException.java | 2 +- src/graph/bellmanFord/Vertex.java | 2 +- .../BreadthFirstSearch.java | 2 +- src/graph/breadthFirstSearch/Graph.java | 2 +- src/graph/cycle/CycleInDirectedGraph.java | 2 +- src/graph/cycle/CycleUndirectedGraph.java | 11 +- src/graph/cycle/Graph.java | 2 +- .../depthFirstSearch/DepthFirstSearch.java | 2 +- src/graph/depthFirstSearch/Graph.java | 2 +- src/graph/dijkstraAlgorithm/BinaryHeap.java | 14 +- .../dijkstraAlgorithm/DijkstraAlgorithm.java | 2 +- src/graph/dijkstraAlgorithm/Graph.java | 2 +- .../DisjointSetArrayImplementation.java | 2 +- src/graph/disjoints/DisjointSetWithNode.java | 2 +- src/graph/disjoints/PredatorDisjointSet.java | 2 +- src/graph/floydwarshall/FloydWarshall.java | 2 +- src/graph/interview/DisjointSet.java | 2 +- src/graph/kruskalAlgorithm/DisjointSet.java | 2 +- src/graph/kruskalAlgorithm/Graph.java | 2 +- src/graph/kruskalAlgorithm/KruskalMST.java | 2 +- src/graph/leetcode/AllPathsInGraph.java | 2 +- src/graph/leetcode/CheapestFlightKStops.java | 2 +- src/graph/leetcode/ConnectCities.java | 2 +- src/graph/leetcode/ConnectMissingCities.java | 2 +- .../leetcode/ConnectedComponentsInGraph.java | 2 +- src/graph/leetcode/CourseSchedule.java | 2 +- src/graph/leetcode/FindJudge.java | 2 +- src/graph/leetcode/FriendCircles.java | 2 +- src/graph/leetcode/GraphBiPartite.java | 2 +- src/graph/leetcode/MinCostRepairEdges.java | 2 +- src/graph/leetcode/NetworkDelayTime.java | 2 +- .../leetcode/NewRoadsMinimumSpanningTree.java | 2 +- src/graph/leetcode/RedundantConnection.java | 2 +- src/graph/leetcode/SentenceSimilarityII.java | 2 +- src/graph/leetcode/SnapShotUtil.java | 2 +- src/graph/primsAlgorithm/BinaryMinHeap.java | 2 +- src/graph/primsAlgorithm/Graph.java | 2 +- src/graph/primsAlgorithm/PrimMST.java | 2 +- src/graph/primsAlgorithm/PrimsMSTArray.java | 2 +- src/graph/shortestPath/Graph.java | 2 +- src/graph/shortestPath/ShortestPath.java | 2 +- src/graph/topologicalsort/Graph.java | 2 +- .../topologicalsort/TopologicalSort.java | 2 +- .../topologicalsort/TopologicalSortList.java | 2 +- src/internals/ConcurrentHashMap.java | 282 ++++++++++++++++++ src/internals/HashMap.java | 178 +++++++++++ src/internals/LinkedHashMap.java | 170 +++++++++++ src/internals/MyBlockingQueue.java | 49 +++ src/internals/SJUArrayList.java | 166 +++++++++++ src/linkedLists/Agoda.java | 117 ++++++++ src/linkedLists/AllProblems.java | 257 ++++++++++++++++ src/linkedLists/ArrayToBST.java | 34 +++ .../CloneRandomPointerLinkedList.java | 102 +++++++ src/linkedLists/DLLToBBST.java | 69 +++++ src/linkedLists/DLLToBBSTTimeEfficiency.java | 79 +++++ src/linkedLists/DetectAndRemoveLoop.java | 112 +++++++ src/linkedLists/FlattenDoublyLinkedList.java | 33 ++ src/linkedLists/FlattenLinkedList.java | 124 ++++++++ src/linkedLists/FlattenNestedIterator.java | 51 ++++ src/linkedLists/LinkedListToBST.java | 112 +++++++ src/linkedLists/ListNode.java | 15 + src/linkedLists/ListNode1.java | 15 + src/linkedLists/Main.java | 86 ++++++ src/linkedLists/MergeTwoLinkedLists.java | 111 +++++++ src/linkedLists/MiddleElement.java | 28 ++ src/linkedLists/Node.java | 54 ++++ .../PalindromeSinglyLinkedList.java | 53 ++++ src/linkedLists/RandomNode.java | 35 +++ src/linkedLists/ReverseKBlockNode.java | 78 +++++ src/linkedLists/ReverseLinkedList.java | 41 +++ .../ReverseLinkedListBetweenMandN.java | 36 +++ src/linkedLists/ReversePairs.java | 92 ++++++ src/linkedLists/ReversePairsNode.java | 47 +++ ...erseSinglyLinkedListWithoutExtraSpace.java | 42 +++ src/linkedLists/RotateList.java | 84 ++++++ src/linkedLists/SinglyLinkedListNode.java | 35 +++ src/linkedLists/StackImpl.java | 23 ++ .../StackOperationUsingLinkedList.java | 41 +++ src/linkedLists/Top20LinkedListQuestions.java | 162 ++++++++++ src/multithreading/barberProblem/Barber.java | 2 +- .../barberProblem/Customer.java | 2 +- src/multithreading/barberProblem/Main.java | 2 +- .../barberProblem/WaitingRoom.java | 2 +- .../com/safecabs/Constants.java | 2 +- src/multithreading/com/safecabs/Gender.java | 2 +- .../com/safecabs/app/AssignCab.java | 5 +- .../com/safecabs/app/CabProvider.java | 13 +- .../com/safecabs/app/CabRequest.java | 5 +- .../com/safecabs/app/CustomCyclicBarrier.java | 13 +- src/multithreading/com/safecabs/cab/Cab.java | 5 +- .../com/safecabs/client/ClientTest.java | 17 +- .../UnRegisteredPassengerException.java | 2 +- .../com/safecabs/passenger/Passenger.java | 5 +- .../passenger/RegisteredPassenger.java | 2 +- .../educative/BarberShopProblem.java | 2 +- src/multithreading/educative/Barrier.java | 2 +- .../educative/BlockingQueue.java | 2 +- .../educative/CountingSemaphore.java | 2 +- .../educative/DeferredCallbackExecutor.java | 2 +- .../educative/DemonstrationThreadLocal.java | 2 +- .../educative/DiningPhilosophers.java | 2 +- .../educative/DiningPhilosophers2.java | 2 +- .../educative/MultiThreadedMergeSort.java | 2 +- .../educative/ReadWriteLock.java | 2 +- .../educative/TokenBucketFilter.java | 2 +- .../educative/UberSeatingProblem.java | 2 +- .../educative/UnisexBathroom.java | 2 +- .../educative/UnisexBathroom2.java | 2 +- .../educative/companies/netflix/Callback.java | 2 +- .../educative/companies/netflix/Executor.java | 2 +- .../educative/companies/netflix/Run.java | 2 +- .../netflix/SynchronousExecutor.java | 2 +- .../educative/examples/CallableExample.java | 2 +- .../educative/examples/DaemonThreadSpawn.java | 2 +- .../educative/examples/FutureTaskExample.java | 2 +- .../educative/examples/StockOrder.java | 2 +- .../educative/examples/ThreadExample.java | 2 +- .../examples/ThreadExecutorExample.java | 2 +- .../examples/ThreadInterruptedException.java | 2 +- .../examples/ThreadSleepExample.java | 2 +- .../educative/examples/ThreadSpawn.java | 2 +- .../educative/examples/TimerVsPool.java | 2 +- .../educative/superman/Superman.java | 2 +- .../superman/SupermanNaiveButCorrect.java | 2 +- .../superman/SupermanSlightlyBetter.java | 2 +- .../educative/superman/SupermanWithFlaws.java | 2 +- src/multithreading/executor/User.java | 2 +- src/multithreading/practice/Addition.java | 2 +- .../practice/CountdownLatch.java | 2 +- src/multithreading/practice/FizzBuzz.java | 2 +- src/multithreading/practice/Foo.java | 2 +- src/multithreading/practice/FooBar.java | 2 +- src/multithreading/practice/OddEven.java | 2 +- .../practice/OddEvenSemaphore.java | 2 +- .../practice/ProducerConsumer.java | 2 +- src/multithreading/practice/ZeroEvenOdd.java | 2 +- .../thread/BasicMultiThreading.java | 2 +- src/multithreading/thread/DeadLock.java | 2 +- .../thread/PrintEvenOddTester.java | 2 +- .../thread/PrintOddEvenByTwoThreads.java | 2 +- .../thread/RaceConditionExample.java | 2 +- src/multithreading/thread/Tesst.java | 2 +- src/multithreading/thread/TestForLocking.java | 2 +- .../thread/ThreadJoinExample.java | 2 +- src/multithreading/thread/ThreadRunnable.java | 2 +- .../common/sorting/ImplementABinaryHeap.java | 2 +- src/strings/common/sorting/InsertionSort.java | 2 +- .../common/sorting/KthLargestElement.java | 2 +- src/strings/common/sorting/MaxHeap.java | 2 +- src/strings/common/sorting/MergeSort.java | 2 +- .../common/sorting/PractiseMergeSort.java | 2 +- src/strings/common/sorting/QuickSelect.java | 2 +- src/strings/common/sorting/QuickSort.java | 2 +- .../All_Possible_Combinatons.java | 2 +- .../DynamicIntegerGenerator.java | 2 +- .../dynamicProblems/FirstNonRepeating.java | 2 +- .../dynamicProblems/PossibleCombinations.java | 2 +- .../dynamicProblems/ReverseSentence.java | 2 +- src/strings/dynamicProblems/Subsequence.java | 2 +- src/strings/stringProblems/Combination.java | 2 +- .../stringProblems/DistinctSubstring.java | 2 +- .../FindLongestStringInArray.java | 2 +- .../stringProblems/MostCommonWord.java | 2 +- .../PermutationAndCombination.java | 2 +- .../RearrangeCharactersInString.java | 2 +- src/strings/stringmatching/KMP.java | 2 +- .../stringmatching/MaxProductString.java | 2 +- src/strings/stringmatching/RabinKarp.java | 2 +- 253 files changed, 3902 insertions(+), 301 deletions(-) create mode 100644 src/SQL/AlterTableWithMonthName.sql create mode 100644 src/SQL/ClassHavingMoreStudents.sql create mode 100644 src/SQL/CustomersNerverOrders.sql create mode 100644 src/SQL/DeleteDuplicate.sql create mode 100644 src/SQL/DepartmentHighestSalary.sql create mode 100644 src/SQL/DuplicateEmail.sql create mode 100644 src/SQL/EmployeeEarningHigherThanManagers.sql create mode 100644 src/SQL/ExchangeSeats.sql create mode 100644 src/SQL/FirstLoginDate.sql create mode 100644 src/SQL/ManagerHaving5OrMoreReport.sql create mode 100644 src/SQL/NthHighestSalary.sql create mode 100644 src/SQL/RisingTemperature.sql create mode 100644 src/SQL/SubjectRanks.sql create mode 100644 src/SQL/TeamSize.sql create mode 100644 src/SQL/Top3Salaries.sql create mode 100644 src/SQL/Top3SalaryDepartmentWise.sql create mode 100644 src/SQL/WinningCandidate.sql create mode 100644 src/internals/ConcurrentHashMap.java create mode 100644 src/internals/HashMap.java create mode 100644 src/internals/LinkedHashMap.java create mode 100644 src/internals/MyBlockingQueue.java create mode 100644 src/internals/SJUArrayList.java create mode 100644 src/linkedLists/Agoda.java create mode 100644 src/linkedLists/AllProblems.java create mode 100644 src/linkedLists/ArrayToBST.java create mode 100644 src/linkedLists/CloneRandomPointerLinkedList.java create mode 100644 src/linkedLists/DLLToBBST.java create mode 100644 src/linkedLists/DLLToBBSTTimeEfficiency.java create mode 100644 src/linkedLists/DetectAndRemoveLoop.java create mode 100644 src/linkedLists/FlattenDoublyLinkedList.java create mode 100644 src/linkedLists/FlattenLinkedList.java create mode 100644 src/linkedLists/FlattenNestedIterator.java create mode 100644 src/linkedLists/LinkedListToBST.java create mode 100644 src/linkedLists/ListNode.java create mode 100644 src/linkedLists/ListNode1.java create mode 100644 src/linkedLists/Main.java create mode 100644 src/linkedLists/MergeTwoLinkedLists.java create mode 100644 src/linkedLists/MiddleElement.java create mode 100644 src/linkedLists/Node.java create mode 100644 src/linkedLists/PalindromeSinglyLinkedList.java create mode 100644 src/linkedLists/RandomNode.java create mode 100644 src/linkedLists/ReverseKBlockNode.java create mode 100644 src/linkedLists/ReverseLinkedList.java create mode 100644 src/linkedLists/ReverseLinkedListBetweenMandN.java create mode 100644 src/linkedLists/ReversePairs.java create mode 100644 src/linkedLists/ReversePairsNode.java create mode 100644 src/linkedLists/ReverseSinglyLinkedListWithoutExtraSpace.java create mode 100644 src/linkedLists/RotateList.java create mode 100644 src/linkedLists/SinglyLinkedListNode.java create mode 100644 src/linkedLists/StackImpl.java create mode 100644 src/linkedLists/StackOperationUsingLinkedList.java create mode 100644 src/linkedLists/Top20LinkedListQuestions.java diff --git a/src/SQL/AlterTableWithMonthName.sql b/src/SQL/AlterTableWithMonthName.sql new file mode 100644 index 0000000..8541ba7 --- /dev/null +++ b/src/SQL/AlterTableWithMonthName.sql @@ -0,0 +1,35 @@ + +--when you give query like this +--SELECT id, +--CASE WHEN month = "Jan" THEN revenue END as "Jan_Revenue", +--CASE WHEN month = "Feb" THEN revenue END AS "Feb_Revenue" +--FROM Department; +--the output will be +--+----+-------------+-------------+ +--| id | Jan_Revenue | Feb_Revenue | +--+----+-------------+-------------+ +--| 1 | NULL | 7000 | +--| 1 | 8000 | NULL | +--| 1 | NULL | NULL | +--| 2 | 9000 | NULL | +--| 3 | NULL | 10000 | +--+----+-------------+-------------+ +--To get one row for each id we need to aggregate by id using GROUP BY. +--But since we have multiple rows with the same id but different values (e.g. for id=1 we have Jan_Revenues: +-- NULL, 8000 and NULL. When we merge these 3 together what value should be chosen? +--This is why we need either SUM (NULL+8000+NULL) or MAX, in both cases 8000 will be used + +SELECT id, +MAX(CASE WHEN month='Jan' then revenue else null end) Jan_Revenue, +MAX(CASE WHEN month='Feb' then revenue else null end) Feb_Revenue, +MAX(CASE WHEN month='Mar' then revenue else null end) Mar_Revenue, +MAX(CASE WHEN month='Apr' then revenue else null end) Apr_Revenue, +MAX(CASE WHEN month='May' then revenue else null end) May_Revenue, +MAX(CASE WHEN month='Jun' then revenue else null end) Jun_Revenue, +MAX(CASE WHEN month='Jul' then revenue else null end) Jul_Revenue, +MAX(CASE WHEN month='Aug' then revenue else null end) Aug_Revenue, +MAX(CASE WHEN month='Sep' then revenue else null end) Sep_Revenue, +MAX(CASE WHEN month='Oct' then revenue else null end) Oct_Revenue, +MAX(CASE WHEN month='Nov' then revenue else null end) Nov_Revenue, +MAX(CASE WHEN month='Dec' then revenue else null end) Dec_Revenue +FROM Department GROUP BY id \ No newline at end of file diff --git a/src/SQL/ClassHavingMoreStudents.sql b/src/SQL/ClassHavingMoreStudents.sql new file mode 100644 index 0000000..86808a4 --- /dev/null +++ b/src/SQL/ClassHavingMoreStudents.sql @@ -0,0 +1,29 @@ +--+---------+------------+ +--| student | class | +--+---------+------------+ +--| A | Math | +--| B | English | +--| C | Math | +--| D | Biology | +--| E | Math | +--| F | Computer | +--| G | Math | +--| H | Math | +--| I | Math | +--+---------+------------+ + +--output: +-- +--+---------+ +--| class | +--+---------+ +--| Math | +--+---------+ + + +SELECT + class +FROM + courses +GROUP BY class +HAVING COUNT(DISTINCT student) >= 5 \ No newline at end of file diff --git a/src/SQL/CustomersNerverOrders.sql b/src/SQL/CustomersNerverOrders.sql new file mode 100644 index 0000000..1bbd733 --- /dev/null +++ b/src/SQL/CustomersNerverOrders.sql @@ -0,0 +1,24 @@ +--Suppose that a website contains two tables, the Customers table and the Orders table. Write a SQL query to find all customers who never order anything. +-- +--Table: Customers. +-- +--+----+-------+ +--| Id | Name | +--+----+-------+ +--| 1 | Joe | +--| 2 | Henry | +--| 3 | Sam | +--| 4 | Max | +--+----+-------+ +--Table: Orders. +-- +--+----+------------+ +--| Id | CustomerId | +--+----+------------+ +--| 1 | 3 | +--| 2 | 1 | +--+----+------------+ + + +select cu.Name as Customers from Customers cu left join Orders od on cu.Id=od.CustomerId +where od.CustomerId is null \ No newline at end of file diff --git a/src/SQL/DeleteDuplicate.sql b/src/SQL/DeleteDuplicate.sql new file mode 100644 index 0000000..06ea0f8 --- /dev/null +++ b/src/SQL/DeleteDuplicate.sql @@ -0,0 +1,5 @@ + + +-- the below command will do cross product and generate all combinations of rows +-- we are selecting a row with same Email and Greater Id +DELETE p1 from Person p1, Person p2 where p1.Email=p2.Email and p1.Id>p2.Id \ No newline at end of file diff --git a/src/SQL/DepartmentHighestSalary.sql b/src/SQL/DepartmentHighestSalary.sql new file mode 100644 index 0000000..2589613 --- /dev/null +++ b/src/SQL/DepartmentHighestSalary.sql @@ -0,0 +1,50 @@ + +--+----+-------+--------+--------------+ +--| Id | Name | Salary | DepartmentId | +--+----+-------+--------+--------------+ +--| 1 | Joe | 70000 | 1 | +--| 2 | Jim | 90000 | 1 | +--| 3 | Henry | 80000 | 2 | +--| 4 | Sam | 60000 | 2 | +--| 5 | Max | 90000 | 1 | +--+----+-------+--------+--------------+ + +--+----+----------+ +--| Id | Name | +--+----+----------+ +--| 1 | IT | +--| 2 | Sales | +--+----+----------+ + +--OUTPUT +--+------------+----------+--------+ +--| Department | Employee | Salary | +--+------------+----------+--------+ +--| IT | Max | 90000 | +--| IT | Jim | 90000 | +--| Sales | Henry | 80000 | +--+------------+----------+--------+ + +--this inner query will give single top salaries for each dept, however if there are multiple people who gets the same salary? we do one more join +-- SELECT d.Id +-- , MAX(d.Name) AS Name +-- , MAX(e.Salary) AS Salary +-- FROM Department d +-- JOIN Employee e +-- ON e.DepartmentId = d.Id +-- GROUP BY d.Id + +SELECT d1.Name as Department + , e1.Name as Employee + , e1.Salary +FROM ( + SELECT d.Id + , MAX(d.Name) AS Name + , MAX(e.Salary) AS Salary + FROM Department d + JOIN Employee e + ON e.DepartmentId = d.Id + GROUP BY d.Id +) d1 +JOIN Employee e1 +ON d1.Id = e1.DepartmentId AND e1.Salary = d1.Salary \ No newline at end of file diff --git a/src/SQL/DuplicateEmail.sql b/src/SQL/DuplicateEmail.sql new file mode 100644 index 0000000..b635a55 --- /dev/null +++ b/src/SQL/DuplicateEmail.sql @@ -0,0 +1,20 @@ +--Write a SQL query to find all duplicate emails in a table named Person. +--+----+---------+ +--| Id | Email | +--+----+---------+ +--| 1 | a@b.com | +--| 2 | c@d.com | +--| 3 | a@b.com | +--+----+---------+ + +select distinct(t1.Email) as Email +from Person t1 +where 1<( + select count(t2.Email) + from Person t2 where t1.Email=t2.Email) + + -- Inner Join concept +select distinct p1.Email +from Person p1 +inner join Person p2 on p1.Email=P2.Email +where p1.Id <> p2.Id \ No newline at end of file diff --git a/src/SQL/EmployeeEarningHigherThanManagers.sql b/src/SQL/EmployeeEarningHigherThanManagers.sql new file mode 100644 index 0000000..f912bae --- /dev/null +++ b/src/SQL/EmployeeEarningHigherThanManagers.sql @@ -0,0 +1,3 @@ + + +select tb1.Name as Employee from Employee tb1 inner join Employee tb2 on tb1.ManagerId=tb2.Id where tb1.Salary>tb2.Salary diff --git a/src/SQL/ExchangeSeats.sql b/src/SQL/ExchangeSeats.sql new file mode 100644 index 0000000..3e425ec --- /dev/null +++ b/src/SQL/ExchangeSeats.sql @@ -0,0 +1,27 @@ +--Mary is a teacher in a middle school and she has a table seat storing students' names and their corresponding seat ids. +-- +--The column id is continuous increment. +-- +--+---------+---------+ +--| id | student | +--+---------+---------+ +--| 1 | Abbot | +--| 2 | Doris | +--| 3 | Emerson | +--| 4 | Green | +--| 5 | Jeames | +--+---------+---------+ + +--For students with odd id, the new id is (id+1) after switch unless it is the last seat. And for students with even id, the new id is (id-1). +--In order to know how many seats in total, we can use a subquery: +--gotcha is when we do id+1 we shouldn't exceed the row number so when id==count we leave as is + +select (case + when MOD(id,2)!=0 && id!=counts then id+1 + when MOD(id,2)!=0 && id=counts then id + else id-1 + end) as id, student + from + seat, + (select count(*) as counts from seat) as seat_counts + order by id asc \ No newline at end of file diff --git a/src/SQL/FirstLoginDate.sql b/src/SQL/FirstLoginDate.sql new file mode 100644 index 0000000..9d78cce --- /dev/null +++ b/src/SQL/FirstLoginDate.sql @@ -0,0 +1,34 @@ + +--Write an SQL query that reports the first login date for each player. +-- +--The query result format is in the following example: +-- +--Activity table: +--+-----------+-----------+------------+--------------+ +--| player_id | device_id | event_date | games_played | +--+-----------+-----------+------------+--------------+ +--| 1 | 2 | 2016-03-01 | 5 | +--| 1 | 2 | 2016-05-02 | 6 | +--| 2 | 3 | 2017-06-25 | 1 | +--| 3 | 1 | 2016-03-02 | 0 | +--| 3 | 4 | 2018-07-03 | 5 | +--+-----------+-----------+------------+--------------+ +-- +--Result table: +--+-----------+-------------+ +--| player_id | first_login | +--+-----------+-------------+ +--| 1 | 2016-03-01 | +--| 2 | 2017-06-25 | +--| 3 | 2016-03-02 | +--+-----------+-------------+ + + +select player_id, min(event_date) as first_login from Activity group by player_id + + +--the following query is to try and get first loggedin deviceId + +SELECT player_id, device_id FROM Activity +WHERE (player_id, event_date) IN +(SELECT player_id, MIN(event_date) first_date FROM Activity GROUP BY player_id) \ No newline at end of file diff --git a/src/SQL/ManagerHaving5OrMoreReport.sql b/src/SQL/ManagerHaving5OrMoreReport.sql new file mode 100644 index 0000000..988a525 --- /dev/null +++ b/src/SQL/ManagerHaving5OrMoreReport.sql @@ -0,0 +1,22 @@ + +--+------+----------+-----------+----------+ +--|Id |Name |Department |ManagerId | +--+------+----------+-----------+----------+ +--|101 |John |A |null | +--|102 |Dan |A |101 | +--|103 |James |A |101 | +--|104 |Amy |A |101 | +--|105 |Anne |A |101 | +--|106 |Ron |B |101 | +--+------+----------+-----------+----------+ +-- +--Given the Employee table, write a SQL query that finds out managers with at least 5 direct report. For the above table, your SQL query should return: +-- +--+-------+ +--| Name | +--+-------+ +--| John | +--+-------+ + + +select (e2.Name) from Employee e1 inner join Employee e2 on e1.ManagerId=e2.Id group by e1.managerid having count(*) >= 5 diff --git a/src/SQL/NthHighestSalary.sql b/src/SQL/NthHighestSalary.sql new file mode 100644 index 0000000..812e4cc --- /dev/null +++ b/src/SQL/NthHighestSalary.sql @@ -0,0 +1,10 @@ +--N is passed as parameter + +CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT +BEGIN +DECLARE M INT; #note variable declaration +SET M=N-1; + RETURN ( + select distinct(salary) from Employee order by Salary desc limit M,1 + ); +END \ No newline at end of file diff --git a/src/SQL/RisingTemperature.sql b/src/SQL/RisingTemperature.sql new file mode 100644 index 0000000..6e0492d --- /dev/null +++ b/src/SQL/RisingTemperature.sql @@ -0,0 +1,23 @@ + +--Given a Weather table, write a SQL query to find all dates' Ids with higher temperature compared to its previous (yesterday's) dates. +-- +--+---------+------------------+------------------+ +--| Id(INT) | RecordDate(DATE) | Temperature(INT) | +--+---------+------------------+------------------+ +--| 1 | 2015-01-01 | 10 | +--| 2 | 2015-01-02 | 25 | +--| 3 | 2015-01-03 | 20 | +--| 4 | 2015-01-04 | 30 | +--+---------+------------------+------------------+ + + +--+----+ +--| Id | +--+----+ +--| 2 | +--| 4 | +--+----+ +SELECT wt1.Id +FROM Weather wt1, Weather wt2 +WHERE wt1.Temperature > wt2.Temperature AND + TO_DAYS(wt1.RecordDate)-TO_DAYS(wt2.RecordDate)=1; \ No newline at end of file diff --git a/src/SQL/SubjectRanks.sql b/src/SQL/SubjectRanks.sql new file mode 100644 index 0000000..bae55fe --- /dev/null +++ b/src/SQL/SubjectRanks.sql @@ -0,0 +1,36 @@ + +--+----+-------+ +--| Id | Score | +--+----+-------+ +--| 1 | 3.50 | +--| 2 | 3.65 | +--| 3 | 4.00 | +--| 4 | 3.85 | +--| 5 | 4.00 | +--| 6 | 3.65 | +--+----+-------+ + +--+-------+---------+ +--| score | Rank | +--+-------+---------+ +--| 4.00 | 1 | +--| 4.00 | 1 | +--| 3.85 | 2 | +--| 3.65 | 3 | +--| 3.65 | 3 | +--| 3.50 | 4 | +--+-------+---------+ + + +SELECT + Score, + (SELECT count(distinct Score) FROM Scores WHERE Score >= s.Score) "Rank" -- inner for-loop +FROM Scores s +ORDER BY Score desc + + +SELECT + Score, + (SELECT count(distinct Score) FROM Scores WHERE Score >= s.Score) "Rank" +FROM Scores s +ORDER BY Score desc \ No newline at end of file diff --git a/src/SQL/TeamSize.sql b/src/SQL/TeamSize.sql new file mode 100644 index 0000000..37cb0c3 --- /dev/null +++ b/src/SQL/TeamSize.sql @@ -0,0 +1,31 @@ +--Employee Table: +--+-------------+------------+ +--| employee_id | team_id | +--+-------------+------------+ +--| 1 | 8 | +--| 2 | 8 | +--| 3 | 8 | +--| 4 | 7 | +--| 5 | 9 | +--| 6 | 9 | +--+-------------+------------+ +--Result table: +--+-------------+------------+ +--| employee_id | team_size | +--+-------------+------------+ +--| 1 | 3 | +--| 2 | 3 | +--| 3 | 3 | +--| 4 | 1 | +--| 5 | 2 | +--| 6 | 2 | +--+-------------+------------+ +--Employees with Id 1,2,3 are part of a team with team_id = 8. so team_size is 3 +--Employees with Id 4 is part of a team with team_id = 7. +--Employees with Id 5,6 are part of a team with team_id = 9. + + +# Write your MySQL query statement below + +select employee_id, (select count(*) from Employee tb2 where tb2.team_id=tb1.team_id) as team_size +from Employee tb1 \ No newline at end of file diff --git a/src/SQL/Top3Salaries.sql b/src/SQL/Top3Salaries.sql new file mode 100644 index 0000000..a5b0a95 --- /dev/null +++ b/src/SQL/Top3Salaries.sql @@ -0,0 +1,19 @@ +--to get to 3 salaries from a table +-- select * from Employee where salary >= {value} this value we need to calculate dynamically (some min value in top 3 salaries) +-- so select min(Salary) from (select distinct(salary) from Employee order by Salary DESC limit 3) this will fetch min of top 3 salaries +-- add this to original query +--+----+-------------+-------------+ +--| id | Name | Salary | +--+----+-------------+-------------+ +--| 1 | A | 7000 | +--| 2 | B | 6000 | +--| 3 | C | 6000 | +--| 4 | D | 6000 | +--| 5 | E | 4000 | +--| 6 | F | 3000 | +--| 7 | G | 3000 | +--| 8 | H | 2000 | +--| 9 | I | 1000 | +--+----+-------------+-------------+ + +select * from Employee where salary >= (select min(Salary) from (select distinct(salary) from Employee order by Salary DESC limit 3)) \ No newline at end of file diff --git a/src/SQL/Top3SalaryDepartmentWise.sql b/src/SQL/Top3SalaryDepartmentWise.sql new file mode 100644 index 0000000..6f59397 --- /dev/null +++ b/src/SQL/Top3SalaryDepartmentWise.sql @@ -0,0 +1,22 @@ +-- +--Now, for each row of the outer query: +--OuterDepartmentId, OuterEmployeeSalary is available to the inner query. +--The inner query will fetch all the salaries that are greater then OuterEmployeeSalary for department matching OuterDepartmentId +--and return a count of such distinct salaries +-- +--This count can be 0,1 or 2 +-- +--if 0 -> that means there are no salaries greater then the OuterDepartmentSalary in that department. Hence, it is the greatest salary for that department. And outer query will include that OuterDepartmentId, OuterEmployeeSalary in the output. +-- +--if 1 -> there is one salary bigger then OuterEmployeeSalary (it is the second largest salary) +-- +--similarly for count 2, there are two larger salaries. + +select d.Name Department, e1.Name Employee, e1.Salary +from Employee e1 +join Department d +on e1.DepartmentId = d.Id +where 3>(select count(distinct(e2.Salary)) + from Employee e2 + where e2.Salary > e1.Salary + and e1.DepartmentId = e2.DepartmentId) -- the inner query will act as inner for loop which get e.salary from outside O(n^2) \ No newline at end of file diff --git a/src/SQL/WinningCandidate.sql b/src/SQL/WinningCandidate.sql new file mode 100644 index 0000000..4313ba7 --- /dev/null +++ b/src/SQL/WinningCandidate.sql @@ -0,0 +1,10 @@ + + +SELECT Name +FROM Candidate c +INNER JOIN (SELECT CandidateId + FROM Vote + GROUP BY CandidateId + ORDER BY COUNT(CandidateId) DESC + LIMIT 0,1) v +ON c.id = v.CandidateId \ No newline at end of file diff --git a/src/geeksforgeeks/AdvantageShuffle.java b/src/geeksforgeeks/AdvantageShuffle.java index 6319ff8..f716e68 100644 --- a/src/geeksforgeeks/AdvantageShuffle.java +++ b/src/geeksforgeeks/AdvantageShuffle.java @@ -2,6 +2,9 @@ // the advantage of A with respect to B is the number of indices i for which A[i] > B[i]. +import java.util.Arrays; +import java.util.PriorityQueue; + // Return any permutation of A that maximizes its advantage with respect to B. //Input: A = [12,24,8,32], B = [13,25,32,11] //Output: [24,32,8,12] @@ -9,9 +12,9 @@ // Output: [2,11,7,15] public class AdvantageShuffle { public int[] advantageCount(int[] A, int[] B) { - Arrays.sort(A); + Arrays.sort(A); - PriorityQueue pq= new PriorityQueue<>((a,b)->Integer.compare(b[0],a[0])); + PriorityQueue pq= new PriorityQueue<>((a, b)->Integer.compare(b[0],a[0])); for(int i=0;i result= new ArrayList<>(); - Arrays.sort(people,(a,b)->{ + Arrays.sort(people,(a, b)->{ if(a[0]==b[0]) return a[1]-b[1]; return b[0]-a[0]; }); diff --git a/src/geeksforgeeks/BasicCalculator.java b/src/geeksforgeeks/BasicCalculator.java index 75a5f7f..a4cadac 100644 --- a/src/geeksforgeeks/BasicCalculator.java +++ b/src/geeksforgeeks/BasicCalculator.java @@ -1,5 +1,8 @@ package geeksforgeeks; +import java.util.ArrayDeque; +import java.util.Deque; + // Input: "(1+(4+5+2)-3)+(6+8)" // Output: 23 public class BasicCalculator { diff --git a/src/geeksforgeeks/BinaryTreeCousins.java b/src/geeksforgeeks/BinaryTreeCousins.java index 8d4fbb1..d3980cf 100644 --- a/src/geeksforgeeks/BinaryTreeCousins.java +++ b/src/geeksforgeeks/BinaryTreeCousins.java @@ -1,5 +1,8 @@ package geeksforgeeks; +import java.util.LinkedList; +import java.util.Queue; + public class BinaryTreeCousins { public boolean isCousins(TreeNode root, int x, int y) { Queue queue = new LinkedList<>(); diff --git a/src/geeksforgeeks/BoatsToSave.java b/src/geeksforgeeks/BoatsToSave.java index 1b495a5..b21a535 100644 --- a/src/geeksforgeeks/BoatsToSave.java +++ b/src/geeksforgeeks/BoatsToSave.java @@ -1,4 +1,7 @@ package geeksforgeeks; + +import java.util.Arrays; + class BoatsToSave { public int numRescueBoats(int[] people, int limit) { if(people.length==0 || limit==0) return 0; diff --git a/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java b/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java index 02e5d09..73f45ba 100644 --- a/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java +++ b/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java @@ -8,7 +8,7 @@ class BuyAndSellStockAtMostTwice { public static void main(String args[]) { int price[] = { 2, 30, 15, 10, 8, 25, 80 }; int n = price.length; - System.out.println("Maximum Profit = " + maxProfit(price, n)); + System.out.println("Maximum Profit = " + maxProfit(price)); } /** @@ -23,7 +23,7 @@ public static void main(String args[]) { * this simply states that at index 2 if we come from left the profit is 2 * and we can initiate another transaction to obtain another profit */ - public int maxProfit(int[] prices) { + public static int maxProfit(int[] prices) { int ans = 0; if (prices.length == 0 || prices.length == 1) return ans; diff --git a/src/geeksforgeeks/CloneGraph.java b/src/geeksforgeeks/CloneGraph.java index 4594889..5fc9f01 100644 --- a/src/geeksforgeeks/CloneGraph.java +++ b/src/geeksforgeeks/CloneGraph.java @@ -1,4 +1,7 @@ package geeksforgeeks; + +import java.util.*; + /* // Definition for a Node. class Node { @@ -21,7 +24,26 @@ public Node(int _val, ArrayList _neighbors) { } } */ -class Solution { +public class CloneGraph { + private class Node { + public int val; + public List neighbors; + + public Node() { + val = 0; + neighbors = new ArrayList(); + } + + public Node(int _val) { + val = _val; + neighbors = new ArrayList(); + } + + public Node(int _val, ArrayList _neighbors) { + val = _val; + neighbors = _neighbors; + } + } public Node cloneGraph(Node node) { if(node==null) return node; diff --git a/src/geeksforgeeks/CombinationIterator.java b/src/geeksforgeeks/CombinationIterator.java index 05a9095..ef3238f 100644 --- a/src/geeksforgeeks/CombinationIterator.java +++ b/src/geeksforgeeks/CombinationIterator.java @@ -2,6 +2,9 @@ // CombinationIterator iterator = new CombinationIterator("abc", 2); // creates the iterator. +import java.util.ArrayDeque; +import java.util.Deque; + // iterator.next(); // returns "ab" // iterator.hasNext(); // returns true // iterator.next(); // returns "ac" diff --git a/src/geeksforgeeks/ConstructTreeFromInorderAndPostorder.java b/src/geeksforgeeks/ConstructTreeFromInorderAndPostorder.java index cf7aed9..3c97db2 100644 --- a/src/geeksforgeeks/ConstructTreeFromInorderAndPostorder.java +++ b/src/geeksforgeeks/ConstructTreeFromInorderAndPostorder.java @@ -1,5 +1,8 @@ package geeksforgeeks; +import java.util.HashMap; +import java.util.Map; + public class ConstructTreeFromInorderAndPostorder { // idea is same as iorder preorder, but we take postOrder[lastIndex] as root; public TreeNode buildTree(int[] inorder, int[] postorder) { @@ -13,7 +16,7 @@ public TreeNode buildTree(int[] inorder, int[] postorder) { } public TreeNode helperFn(int[] inorder, int iStart, int iEnd, int[] postorder, int pstart, int pend, Map map){ - if(iStart>iEnd || ps>pe) return null; + if(iStart>iEnd || pstart>pend) return null; TreeNode root= new TreeNode(postorder[pend]); int divider=map.get(root.val); diff --git a/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java b/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java index 1a1694c..c3a46ce 100644 --- a/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java +++ b/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java @@ -1,7 +1,8 @@ package geeksforgeeks; -import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; import java.util.Map; /** diff --git a/src/geeksforgeeks/EvaluvateExpressions.java b/src/geeksforgeeks/EvaluvateExpressions.java index 3086f9b..0b769ab 100644 --- a/src/geeksforgeeks/EvaluvateExpressions.java +++ b/src/geeksforgeeks/EvaluvateExpressions.java @@ -4,6 +4,8 @@ // return all possible results from computing all the different possible ways to group numbers // and operators. The valid operators are +, - and *. +import java.util.*; + // Input: "2*3-4*5" // Output: [-34, -14, -10, -10, 10] // Explanation: diff --git a/src/geeksforgeeks/EvaluvateRPN.java b/src/geeksforgeeks/EvaluvateRPN.java index 6ea7f30..a389307 100644 --- a/src/geeksforgeeks/EvaluvateRPN.java +++ b/src/geeksforgeeks/EvaluvateRPN.java @@ -1,5 +1,8 @@ package geeksforgeeks; +import java.util.ArrayDeque; +import java.util.Deque; + // Input: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"] // Output: 22 // Explanation: diff --git a/src/geeksforgeeks/FenwickTree.java b/src/geeksforgeeks/FenwickTree.java index f67b1fe..645385c 100644 --- a/src/geeksforgeeks/FenwickTree.java +++ b/src/geeksforgeeks/FenwickTree.java @@ -58,7 +58,7 @@ public class FenwickTree{ int[] fen; int[] arr; int n; - public NumArray(int[] nums) { + public void NumArray(int[] nums) { arr = nums; n = nums.length; fen = new int[n+1]; diff --git a/src/geeksforgeeks/FindMissingNumbers.java b/src/geeksforgeeks/FindMissingNumbers.java index a889568..f996fe8 100644 --- a/src/geeksforgeeks/FindMissingNumbers.java +++ b/src/geeksforgeeks/FindMissingNumbers.java @@ -1,5 +1,9 @@ package geeksforgeeks; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + // Input: [2, 3, 1, 8, 2, 3, 5, 1] // Output: 4, 6, 7 public class FindMissingNumbers { diff --git a/src/geeksforgeeks/FirstMissingPositive.java b/src/geeksforgeeks/FirstMissingPositive.java index 1efb0e7..d23015e 100644 --- a/src/geeksforgeeks/FirstMissingPositive.java +++ b/src/geeksforgeeks/FirstMissingPositive.java @@ -1,8 +1,9 @@ package geeksforgeeks; -import java.awt.List; + import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -54,7 +55,7 @@ public int firstMissingPositiveWithExtraSpace(int[] nums) { return -1; } - public List findKMissingPossitiveNumber(int[] A){ + public List findKMissingPossitiveNumberOfSizeK(int[] A, int k){ int i = 0; while (i < A.length) { // same cyclic sort, as missing numbers @@ -74,7 +75,7 @@ public List findKMissingPossitiveNumber(int[] A){ while(i> groupAnagrams(String[] strs) { List> result= new ArrayList<>(); diff --git a/src/geeksforgeeks/HitCounter.java b/src/geeksforgeeks/HitCounter.java index 77d6368..ae93af5 100644 --- a/src/geeksforgeeks/HitCounter.java +++ b/src/geeksforgeeks/HitCounter.java @@ -1,4 +1,7 @@ package geeksforgeeks; + +import java.util.ArrayDeque; + public class HitCounter { ArrayDeque trac; /** Initialize your data structure here. */ diff --git a/src/geeksforgeeks/InMemeoryFIleSystem.java b/src/geeksforgeeks/InMemeoryFIleSystem.java index c39f2de..a38091a 100644 --- a/src/geeksforgeeks/InMemeoryFIleSystem.java +++ b/src/geeksforgeeks/InMemeoryFIleSystem.java @@ -1,12 +1,17 @@ package geeksforgeeks; -public class FileSystem { +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + + public class InMemeoryFIleSystem { class Dir { - HashMap < String, Dir > dirs = new HashMap < > (); + HashMap< String, Dir > dirs = new HashMap < > (); HashMap < String, String > files = new HashMap < > (); } Dir root; - public FileSystem() { + public InMemeoryFIleSystem() { root = new Dir(); } public List < String > ls(String path) { @@ -66,13 +71,13 @@ class File { String content = ""; } File root; - public FileSystem() { + public void FileSystem() { root = new File(); } public List < String > ls(String path) { File t = root; - List < String > files = new ArrayList < > (); + List< String > files = new ArrayList< >(); if (!path.equals("/")) { String[] d = path.split("/"); for (int i = 1; i < d.length; i++) { diff --git a/src/geeksforgeeks/InorderSuccessorPredecessor.java b/src/geeksforgeeks/InorderSuccessorPredecessor.java index 3c46754..6af6d0e 100644 --- a/src/geeksforgeeks/InorderSuccessorPredecessor.java +++ b/src/geeksforgeeks/InorderSuccessorPredecessor.java @@ -107,36 +107,37 @@ public void helperFn(TreeNode root, TreeNode p){ } } -} - -private TreeNode findPredecessor(TreeNode root, TreeNode node) { - TreeNode pre = null; - TreeNode cur = root; - while (cur != null) { - if (cur.val < node.val) { - pre = cur; - cur = cur.right; - } else { - cur = cur.left; + private TreeNode findPredecessor(TreeNode root, TreeNode node) { + TreeNode pre = null; + TreeNode cur = root; + while (cur != null) { + if (cur.val < node.val) { + pre = cur; + cur = cur.right; + } else { + cur = cur.left; + } } + return pre; } - return pre; -} -private TreeNode findSuccessor(TreeNode root, TreeNode node) { - TreeNode succ = null; - TreeNode cur = root; - while (cur != null) { - if (cur.val > node.val) { - succ = cur; - cur = cur.left; - } else { - cur = cur.right; + private TreeNode findSuccessor(TreeNode root, TreeNode node) { + TreeNode succ = null; + TreeNode cur = root; + while (cur != null) { + if (cur.val > node.val) { + succ = cur; + cur = cur.left; + } else { + cur = cur.right; + } } + return succ; } - return succ; } -class TNode { + + + class TNode { int data; TNode left; TNode right; diff --git a/src/geeksforgeeks/InsertIntervals.java b/src/geeksforgeeks/InsertIntervals.java index 091396d..f419cc2 100644 --- a/src/geeksforgeeks/InsertIntervals.java +++ b/src/geeksforgeeks/InsertIntervals.java @@ -1,5 +1,8 @@ package geeksforgeeks; +import java.util.ArrayList; +import java.util.List; + /** * Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). diff --git a/src/geeksforgeeks/IsomorphicString.java b/src/geeksforgeeks/IsomorphicString.java index 1f41f1e..f212aa5 100644 --- a/src/geeksforgeeks/IsomorphicString.java +++ b/src/geeksforgeeks/IsomorphicString.java @@ -7,8 +7,8 @@ */ class IsomorphicString { static boolean isIsomorphic(String s, String t) { - char m1[] = new int[256]; - char m2[] = new int[256]; + char[] m1 = new char[256]; + char[] m2 = new char[256]; int n = s.length(); for (int i = 0; i < n; ++i) { // it checks the count of the character in the array ; @@ -17,8 +17,8 @@ static boolean isIsomorphic(String s, String t) { if (m1[s.charAt(i)] != m2[t.charAt(i)]) { return false; } - m1[s.charAt(i)] = i + 1; - m2[t.charAt(i)] = i + 1; + m1[s.charAt(i)] = (char) (i + 1); + m2[t.charAt(i)] = (char) (i + 1); } System.out.println(Arrays.toString(m1)); System.out.println(Arrays.toString(m2)); diff --git a/src/geeksforgeeks/LRUCache.java b/src/geeksforgeeks/LRUCache.java index 5c99caf..a41f5ff 100644 --- a/src/geeksforgeeks/LRUCache.java +++ b/src/geeksforgeeks/LRUCache.java @@ -1,4 +1,9 @@ package geeksforgeeks; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + class LRUCache { class DLLNode{ @@ -76,7 +81,7 @@ public void update(DLLNode node){ class LRUCache1 { LinkedHashMap isbnToPrice; - LRUCache(final int capacity) { + public LRUCache1(final int capacity) { this.isbnToPrice = new LinkedHashMap(capacity, 1f, true) { @Override diff --git a/src/geeksforgeeks/LargestPossibleNumber.java b/src/geeksforgeeks/LargestPossibleNumber.java index 398815f..2848d67 100644 --- a/src/geeksforgeeks/LargestPossibleNumber.java +++ b/src/geeksforgeeks/LargestPossibleNumber.java @@ -2,7 +2,7 @@ import java.util.Arrays; import java.util.Collections; -import java.util.Comparator; +import java.util.LinkedList; import java.util.List; /** diff --git a/src/geeksforgeeks/LinkedListRemoveDuplicates.java b/src/geeksforgeeks/LinkedListRemoveDuplicates.java index 029e418..ae11537 100644 --- a/src/geeksforgeeks/LinkedListRemoveDuplicates.java +++ b/src/geeksforgeeks/LinkedListRemoveDuplicates.java @@ -10,7 +10,7 @@ class LinkedListRemoveDuplicate{ * * @param head */ - public static void removeDuplicatesWithoutBuffer(LinkedListNode head) { + public static void removeDuplicatesWithoutBuffer(ListNode head) { /* If head is null, stop processing */ if (head == null) { return; @@ -18,13 +18,13 @@ public static void removeDuplicatesWithoutBuffer(LinkedListNode head) { /* We will need two pointers here i.e current and runner. * When current is pointing to a node, move runner through * rest of the list, checking for duplicates */ - LinkedListNode current = head; + ListNode current = head; while (current != null) { /* Have runner point to current node */ - LinkedListNode runner = current; + ListNode runner = current; while (runner.next != null) { /* If it is duplicate, jump runner over the node */ - if (runner.next.data == current.data) { + if (runner.next.val == current.val) { runner.next = runner.next.next; } else { runner = runner.next; diff --git a/src/geeksforgeeks/MaxSoldiers.java b/src/geeksforgeeks/MaxSoldiers.java index 0866e7a..8194bad 100644 --- a/src/geeksforgeeks/MaxSoldiers.java +++ b/src/geeksforgeeks/MaxSoldiers.java @@ -1,5 +1,7 @@ package geeksforgeeks; +import java.util.PriorityQueue; + public class MaxSoldiers { class Pair{ int row; @@ -12,7 +14,7 @@ class Pair{ public int[] kWeakestRows(int[][] mat, int k) { int[] result= new int[k]; - PriorityQueue queue= new PriorityQueue<>((a,b)->a.soldiers==b.soldiers?Integer.compare(a.row,b.row):Integer.compare(a.soldiers,b.soldiers)); + PriorityQueue queue= new PriorityQueue<>((a, b)->a.soldiers==b.soldiers?Integer.compare(a.row,b.row):Integer.compare(a.soldiers,b.soldiers)); int i=0; int soldiers=0; for(int []rows: mat){ diff --git a/src/geeksforgeeks/MaxWidthOfBinaryTree.java b/src/geeksforgeeks/MaxWidthOfBinaryTree.java index 18d47bb..7512795 100644 --- a/src/geeksforgeeks/MaxWidthOfBinaryTree.java +++ b/src/geeksforgeeks/MaxWidthOfBinaryTree.java @@ -1,5 +1,10 @@ package geeksforgeeks; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Queue; + /** * Given a binary tree, write a function to get the maximum width of the given tree. * The width of a tree is the maximum width among all levels. diff --git a/src/geeksforgeeks/MedianOfKWindow.java b/src/geeksforgeeks/MedianOfKWindow.java index 2e3ad95..c07539b 100644 --- a/src/geeksforgeeks/MedianOfKWindow.java +++ b/src/geeksforgeeks/MedianOfKWindow.java @@ -1,5 +1,8 @@ package geeksforgeeks; +import java.util.Collections; +import java.util.PriorityQueue; + public class MedianOfKWindow { public double[] medianSlidingWindow(int[] nums, int k) { MedianQueue medianHeap= new MedianQueue(); diff --git a/src/geeksforgeeks/MeetingRoomsII.java b/src/geeksforgeeks/MeetingRoomsII.java index bdab7a8..ee6705e 100644 --- a/src/geeksforgeeks/MeetingRoomsII.java +++ b/src/geeksforgeeks/MeetingRoomsII.java @@ -1,9 +1,6 @@ package geeksforgeeks; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.PriorityQueue; +import java.util.*; /** * https://www.lintcode.com/problem/meeting-rooms-ii/ diff --git a/src/geeksforgeeks/MergeIntervalIntersection.java b/src/geeksforgeeks/MergeIntervalIntersection.java index a17ee6f..2282f95 100644 --- a/src/geeksforgeeks/MergeIntervalIntersection.java +++ b/src/geeksforgeeks/MergeIntervalIntersection.java @@ -1,5 +1,8 @@ package geeksforgeeks; +import java.util.ArrayList; +import java.util.List; + /** * Given two lists of closed intervals, each list of intervals is pairwise disjoint and in sorted order. diff --git a/src/geeksforgeeks/MinStepsToConvertXtoY.java b/src/geeksforgeeks/MinStepsToConvertXtoY.java index 44c0efa..bc520e2 100644 --- a/src/geeksforgeeks/MinStepsToConvertXtoY.java +++ b/src/geeksforgeeks/MinStepsToConvertXtoY.java @@ -1,6 +1,18 @@ package geeksforgeeks; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Set; + class MinStepsToConvertXtoY { + private static class GFG{ + int val; + int steps; + GFG(int source, int steps){ + this.val=source; + this.steps=steps; + } + } private static int minOperations(int src, int target) { Set visited = new HashSet<>(1000); diff --git a/src/geeksforgeeks/OverlappingIntervals.java b/src/geeksforgeeks/OverlappingIntervals.java index 775690d..f81b9f0 100644 --- a/src/geeksforgeeks/OverlappingIntervals.java +++ b/src/geeksforgeeks/OverlappingIntervals.java @@ -1,5 +1,7 @@ package geeksforgeeks; +import java.util.PriorityQueue; + /** * Given a collection of intervals, find the minimum number of intervals * you need to remove to make the rest of the intervals non-overlapping. diff --git a/src/geeksforgeeks/OwnDataStructureUtil.java b/src/geeksforgeeks/OwnDataStructureUtil.java index 25693fb..6ba7527 100644 --- a/src/geeksforgeeks/OwnDataStructureUtil.java +++ b/src/geeksforgeeks/OwnDataStructureUtil.java @@ -8,7 +8,7 @@ class OwnDataStructureUtil { ArrayList list; HashMap map; - java.util.Random rand = new java.util.Random(); + Random rand = new Random(); public OwnDataStructureUtil() { list = new ArrayList<>(); diff --git a/src/geeksforgeeks/PathSumIII.java b/src/geeksforgeeks/PathSumIII.java index f189ad4..6ba76c6 100644 --- a/src/geeksforgeeks/PathSumIII.java +++ b/src/geeksforgeeks/PathSumIII.java @@ -1,4 +1,8 @@ package geeksforgeeks; + +import java.util.ArrayList; +import java.util.List; + public class PathSumIII { List list= new ArrayList<>(); int count=0; @@ -21,41 +25,41 @@ public int pathSum(TreeNode root, int sum) { return count; } - public void preorder(TreeNode node, int currSum) { - if (node == null) - return; - - // current prefix sum - currSum += node.val; - - // here is the sum we're looking for - if (currSum == k) - count++; - - // number of times the curr_sum − k has occured already, - // determines the number of times a path with sum k - // has occured upto the current node - count += h.getOrDefault(currSum - k, 0); - - // add the current sum into hashmap - // to use it during the child nodes processing - h.put(currSum, h.getOrDefault(currSum, 0) + 1); - - // process left subtree - preorder(node.left, currSum); - // process right subtree - preorder(node.right, currSum); - - // remove the current sum from the hashmap - // in order not to use it during - // the parallel subtree processing - h.put(currSum, h.get(currSum) - 1); - } - - public int pathSumAlter(TreeNode root, int sum) { - k = sum; - preorder(root, 0); - return count; - } +// public void preorder(TreeNode node, int currSum, int k) { +// if (node == null) +// return; +// +// // current prefix sum +// currSum += node.val; +// +// // here is the sum we're looking for +// if (currSum == k) +// count++; +// +// // number of times the curr_sum − k has occured already, +// // determines the number of times a path with sum k +// // has occured upto the current node +// count += h.getOrDefault(currSum - k, 0); +// +// // add the current sum into hashmap +// // to use it during the child nodes processing +// h.put(currSum, h.getOrDefault(currSum, 0) + 1); +// +// // process left subtree +// preorder(node.left, currSum, k); +// // process right subtree +// preorder(node.right, currSum, k); +// +// // remove the current sum from the hashmap +// // in order not to use it during +// // the parallel subtree processing +// h.put(currSum, h.get(currSum) - 1); +// } +// +// public int pathSumAlter(TreeNode root, int sum) { +// int k = sum; +// preorder(root, 0, k); +// return count; +// } } \ No newline at end of file diff --git a/src/geeksforgeeks/RangeSum.java b/src/geeksforgeeks/RangeSum.java index 213f774..af58e6f 100644 --- a/src/geeksforgeeks/RangeSum.java +++ b/src/geeksforgeeks/RangeSum.java @@ -2,7 +2,7 @@ public class RangeSum { int[] dp; - public NumArray(int[] nums) { + public void NumArray(int[] nums) { if(nums.length==0) return ; dp= new int[nums.length]; dp[0]=nums[0]; diff --git a/src/geeksforgeeks/ReconstructItenary.java b/src/geeksforgeeks/ReconstructItenary.java index 7afb10b..b556401 100644 --- a/src/geeksforgeeks/ReconstructItenary.java +++ b/src/geeksforgeeks/ReconstructItenary.java @@ -1,4 +1,7 @@ package geeksforgeeks; + +import java.util.*; + /** * Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], reconstruct the itinerary in order. * All of the tickets belong to a man who departs from JFK. @@ -16,7 +19,7 @@ class Solution { public List findItinerary(List> tickets) { if(tickets==null || tickets.size()==0) return Collections.emptyList(); - Map > map= new HashMap<>(); + Map> map= new HashMap<>(); for(List ticket: tickets){ map.putIfAbsent(ticket.get(0), new PriorityQueue<>()); diff --git a/src/geeksforgeeks/RemoveKDigits.java b/src/geeksforgeeks/RemoveKDigits.java index d64c12f..ed07b21 100644 --- a/src/geeksforgeeks/RemoveKDigits.java +++ b/src/geeksforgeeks/RemoveKDigits.java @@ -1,6 +1,7 @@ package geeksforgeeks; -import java.util.Stack; +import java.util.ArrayDeque; +import java.util.Deque; /** * https://leetcode.com/problems/remove-k-digits/ @@ -39,6 +40,6 @@ public static String removeKdigits(String num, int k) { } public static void main(String[] args) { - System.out.println(removeKDigits("14232191", 3)); + System.out.println(removeKdigits("14232191", 3)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/RemoveParanthesisValid.java b/src/geeksforgeeks/RemoveParanthesisValid.java index 88982dc..ba9d28e 100644 --- a/src/geeksforgeeks/RemoveParanthesisValid.java +++ b/src/geeksforgeeks/RemoveParanthesisValid.java @@ -1,5 +1,8 @@ package geeksforgeeks; -class RemoveParanthesisValid { + +import java.util.*; + +public class RemoveParanthesisValid { public List removeInvalidParentheses(String s) { if (isValid(s)) diff --git a/src/geeksforgeeks/ReverseWordsInString.java b/src/geeksforgeeks/ReverseWordsInString.java index 0832f61..af5a14c 100644 --- a/src/geeksforgeeks/ReverseWordsInString.java +++ b/src/geeksforgeeks/ReverseWordsInString.java @@ -1,5 +1,7 @@ package geeksforgeeks; +import java.util.Arrays; + public class ReverseWordsInString { public char[] reverse(char[] arr, int i, int j) { diff --git a/src/geeksforgeeks/SameTree.java b/src/geeksforgeeks/SameTree.java index 6db6fd9..8882703 100644 --- a/src/geeksforgeeks/SameTree.java +++ b/src/geeksforgeeks/SameTree.java @@ -1,5 +1,7 @@ package geeksforgeeks; +import java.util.ArrayDeque; + /** * Given two binary trees, write a function to check if they are the same or not. * Two binary trees are considered the same if they are structurally identical and the nodes have the same value. diff --git a/src/geeksforgeeks/SerializeDeserializeBST.java b/src/geeksforgeeks/SerializeDeserializeBST.java index 6ca6222..f86c252 100644 --- a/src/geeksforgeeks/SerializeDeserializeBST.java +++ b/src/geeksforgeeks/SerializeDeserializeBST.java @@ -9,6 +9,10 @@ // rootValue (rootValue) (>rootValue) // Because of BST's property: before the |separate line| all the node values are less than root value, all the node values after |separate line| are greater than root value. We will utilize this to build left and right tree. +import java.util.LinkedList; +import java.util.Queue; +import java.util.Stack; + class SerializeDeserializeBST{ private static final String SEP = ","; private static final String NULL = "null"; diff --git a/src/geeksforgeeks/ShipPackageWithNDays.java b/src/geeksforgeeks/ShipPackageWithNDays.java index aabb35d..93c8a48 100644 --- a/src/geeksforgeeks/ShipPackageWithNDays.java +++ b/src/geeksforgeeks/ShipPackageWithNDays.java @@ -1,5 +1,7 @@ package geeksforgeeks; +import java.util.Arrays; + public class ShipPackageWithNDays{ public int shipWithinDays(int[] weights, int D) { if(weights.length==0 || D==0) return 0; diff --git a/src/geeksforgeeks/SnakeAndLadder.java b/src/geeksforgeeks/SnakeAndLadder.java index f5777b5..c1bc484 100644 --- a/src/geeksforgeeks/SnakeAndLadder.java +++ b/src/geeksforgeeks/SnakeAndLadder.java @@ -44,7 +44,7 @@ public int snakesAndLadders(int[][] board) { } } - return qEntry.noOfMoves; + return queue.peek().steps; } private int[] numToPos(int target) { diff --git a/src/geeksforgeeks/SortStack.java b/src/geeksforgeeks/SortStack.java index 2534453..ffaccf0 100644 --- a/src/geeksforgeeks/SortStack.java +++ b/src/geeksforgeeks/SortStack.java @@ -1,5 +1,7 @@ package geeksforgeeks; +import java.util.Stack; + class SortStack { // Input : [34, 3, 31, 98, 92, 23] // Output : [3, 23, 31, 34, 92, 98] diff --git a/src/geeksforgeeks/SpiralMatrix.java b/src/geeksforgeeks/SpiralMatrix.java index bffa31b..c8508cc 100644 --- a/src/geeksforgeeks/SpiralMatrix.java +++ b/src/geeksforgeeks/SpiralMatrix.java @@ -1,5 +1,8 @@ package geeksforgeeks; +import java.util.ArrayList; +import java.util.List; + class SpiralMatrix { public static List spiralOrder(int[][] matrix) { diff --git a/src/geeksforgeeks/StockBuySellManyTimes.java b/src/geeksforgeeks/StockBuySellManyTimes.java index 990a5ce..d3ac23f 100644 --- a/src/geeksforgeeks/StockBuySellManyTimes.java +++ b/src/geeksforgeeks/StockBuySellManyTimes.java @@ -7,6 +7,13 @@ class Interval { int buy, sell; int start; // for meeting problem int end; + Interval(int buy, int sell){ + this.buy=buy; + this.sell=sell; + } + Interval(){ + + } } /** diff --git a/src/geeksforgeeks/StockSpanner.java b/src/geeksforgeeks/StockSpanner.java index fa9b77a..0bc1415 100644 --- a/src/geeksforgeeks/StockSpanner.java +++ b/src/geeksforgeeks/StockSpanner.java @@ -1,20 +1,27 @@ package geeksforgeeks; +import com.sun.tools.javac.util.Pair; + +import java.util.ArrayDeque; +import java.util.Deque; + +; + class StockSpanner { - Deque> stack; + Deque> stack; public StockSpanner() { this.stack= new ArrayDeque<>(); } public int next(int price) { int value=1; - while(!stack.isEmpty() && stack.peek().getKey()<=price){ - value+=stack.pop().getValue(); + while(!stack.isEmpty() && stack.peek().fst<=price){ + value+=stack.pop().snd; } stack.push(new Pair(price,value)); - return stack.peek().getValue(); + return stack.peek().snd; } } \ No newline at end of file diff --git a/src/geeksforgeeks/SubArraySumDivisibleByK.java b/src/geeksforgeeks/SubArraySumDivisibleByK.java index dbd73b8..0b684b7 100644 --- a/src/geeksforgeeks/SubArraySumDivisibleByK.java +++ b/src/geeksforgeeks/SubArraySumDivisibleByK.java @@ -1,5 +1,8 @@ package geeksforgeeks; +import java.util.HashMap; +import java.util.Map; + /** * Given an array A of integers, return the number of (contiguous, non-empty) subarrays that have a sum divisible by K. * Input: A = [4,5,0,-2,-3,1], K = 5 diff --git a/src/geeksforgeeks/SubArraySumEqualsK.java b/src/geeksforgeeks/SubArraySumEqualsK.java index e8df984..fb0c80c 100644 --- a/src/geeksforgeeks/SubArraySumEqualsK.java +++ b/src/geeksforgeeks/SubArraySumEqualsK.java @@ -1,4 +1,8 @@ package geeksforgeeks; + +import java.util.HashMap; +import java.util.Map; + public class SubArraySumEqualsK { public int subarraySum(int[] nums, int k) { int left=0; diff --git a/src/geeksforgeeks/SumSubArrayZero.java b/src/geeksforgeeks/SumSubArrayZero.java index f8108de..5f30500 100644 --- a/src/geeksforgeeks/SumSubArrayZero.java +++ b/src/geeksforgeeks/SumSubArrayZero.java @@ -8,21 +8,21 @@ /** * https://www.geeksforgeeks.org/print-all-subarrays-with-0-sum/ */ -class Pair { - int first, second; - Pair(int a, int b) { - first = a; - second = b; - } - - public String toString() { - return this.first + "--" + this.second; - } -} public class SumSubArrayZero { + private static class Pair { + int first, second; + Pair(int a, int b) { + first = a; + second = b; + } + + public String toString() { + return this.first + "--" + this.second; + } + } static ArrayList findSubArrays(int[] arr, int n) { Map> map = new HashMap<>(); ArrayList result = new ArrayList<>(); diff --git a/src/geeksforgeeks/SurroundedRegions.java b/src/geeksforgeeks/SurroundedRegions.java index 2aa3c6a..7c76e12 100644 --- a/src/geeksforgeeks/SurroundedRegions.java +++ b/src/geeksforgeeks/SurroundedRegions.java @@ -1,6 +1,20 @@ package geeksforgeeks; +import java.util.ArrayDeque; +import java.util.Queue; + class Solution { + private static class Pair { + int x; + int y; + int level; + + public Pair(int x, int y, int level) { + this.x = x; + this.y = y; + this.level = level; + } + } public void solve(char[][] board) { if (board == null || board.length == 0) return; @@ -102,14 +116,3 @@ private void boundaryDFS(char[][] board, int i, int j) { } } -class Pair { - int x; - int y; - int level; - - public Pair(int x, int y, int level) { - this.x = x; - this.y = y; - this.level = level; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/ThreeSum.java b/src/geeksforgeeks/ThreeSum.java index 7f7b26b..a2950aa 100644 --- a/src/geeksforgeeks/ThreeSum.java +++ b/src/geeksforgeeks/ThreeSum.java @@ -1,5 +1,10 @@ package geeksforgeeks; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + public class ThreeSum { public List> threeSum(int[] nums) { if(nums==null || nums.length==0) return Collections.emptyList(); diff --git a/src/geeksforgeeks/TimeMap.java b/src/geeksforgeeks/TimeMap.java index 6a6d3ab..5918f2e 100644 --- a/src/geeksforgeeks/TimeMap.java +++ b/src/geeksforgeeks/TimeMap.java @@ -1,5 +1,7 @@ package geeksforgeeks; +import java.util.HashMap; + class TimeMap { class Node{ @@ -12,7 +14,7 @@ public Node(String value, int timestamp){ } } /** Initialize your data structure here. */ - HashMapmap; + HashMap map; public TimeMap() { map=new HashMap<>(); diff --git a/src/geeksforgeeks/TopKFrequentElement.java b/src/geeksforgeeks/TopKFrequentElement.java index e8882c4..b4bcd99 100644 --- a/src/geeksforgeeks/TopKFrequentElement.java +++ b/src/geeksforgeeks/TopKFrequentElement.java @@ -1,10 +1,15 @@ package geeksforgeeks; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + class TopKFrequentElement{ public List topKFrequent(int[] nums, int k) { List result = new ArrayList<>(); - HashMap map = new HashMap<>(); //Key: val, Val: #of freq + Map map = new HashMap<>(); //Key: val, Val: #of freq for (int num : nums) { if (map.containsKey(num)) { map.put(num, map.get(num)+1); diff --git a/src/geeksforgeeks/TwoCityScheduling.java b/src/geeksforgeeks/TwoCityScheduling.java index 12a088a..e24032f 100644 --- a/src/geeksforgeeks/TwoCityScheduling.java +++ b/src/geeksforgeeks/TwoCityScheduling.java @@ -1,5 +1,7 @@ package geeksforgeeks; +import java.util.PriorityQueue; + /** * There are 2N people a company is planning to interview. * The cost of flying the i-th person to city A is costs[i][0], and the cost of flying the i-th person to city B is costs[i][1]. @@ -26,7 +28,7 @@ public int twoCitySchedCost(int[][] costs) { // what the above array indicates is that for i'th candidate=>[10,20] we will save 10 in sending to A // when i=2 we will have to spend 350 more to bring to A city so we sort by arr[0]-arr[1] // greedily we take negative val candidates to A and rest to B for this input - PriorityQueue queue= new PriorityQueue<>((a,b)->(a[0] - a[1]) - (b[0] - b[1])); + PriorityQueue queue= new PriorityQueue<>((a, b)->(a[0] - a[1]) - (b[0] - b[1])); for(int[] cost: costs){ queue.offer(cost); diff --git a/src/geeksforgeeks/UniquePath.java b/src/geeksforgeeks/UniquePath.java index 88c2386..c8015a4 100644 --- a/src/geeksforgeeks/UniquePath.java +++ b/src/geeksforgeeks/UniquePath.java @@ -47,7 +47,7 @@ private static int uniquePathI(int row, int col) { * 1. Right -> Right -> Down -> Down * 2. Down -> Down -> Right -> Right */ - private static int uniquePathII(int[][] mat) { + private static int uniquePathII(int[][] obstacleGrid) { if (obstacleGrid[0][0] == 1) return 0; diff --git a/src/geeksforgeeks/UrlEncode.java b/src/geeksforgeeks/UrlEncode.java index 1c54391..d95694b 100644 --- a/src/geeksforgeeks/UrlEncode.java +++ b/src/geeksforgeeks/UrlEncode.java @@ -1,5 +1,7 @@ package geeksforgeeks; +import java.util.stream.IntStream; + /** * Write a method to replace all the spaces in a string with ‘%20’. * You may assume that the string has sufficient space at the end to hold the additional characters, diff --git a/src/geeksforgeeks/ValidSuduko.java b/src/geeksforgeeks/ValidSuduko.java index d287cc3..81f8ece 100644 --- a/src/geeksforgeeks/ValidSuduko.java +++ b/src/geeksforgeeks/ValidSuduko.java @@ -1,6 +1,9 @@ package geeksforgeeks; -class VulgarSuduko { +import java.util.HashSet; +import java.util.Set; + +public class ValidSuduko { public boolean isValidSudoku(char[][] board) { Set seen = new HashSet<>(); diff --git a/src/geeksforgeeks/WordBreakII.java b/src/geeksforgeeks/WordBreakII.java index 1aa8a46..2dc3ee1 100644 --- a/src/geeksforgeeks/WordBreakII.java +++ b/src/geeksforgeeks/WordBreakII.java @@ -1,5 +1,10 @@ package geeksforgeeks; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + public class WordBreakII { public List wordBreak(String s, List wordDict) { Map> cache = new HashMap<>(); diff --git a/src/geeksforgeeks/WordDictionary.java b/src/geeksforgeeks/WordDictionary.java index 1571536..446c210 100644 --- a/src/geeksforgeeks/WordDictionary.java +++ b/src/geeksforgeeks/WordDictionary.java @@ -1,5 +1,8 @@ package geeksforgeeks; +import java.util.HashMap; +import java.util.Map; + /** * Design a data structure that supports the following two operations: * void addWord(word) diff --git a/src/geeksforgeeks/WordLadder.java b/src/geeksforgeeks/WordLadder.java index 2a69ea3..74aa0d1 100644 --- a/src/geeksforgeeks/WordLadder.java +++ b/src/geeksforgeeks/WordLadder.java @@ -1,5 +1,7 @@ package geeksforgeeks; +import java.util.*; + public class WordLadder { public int ladderLength(String beginWord, String endWord, List wordList) { Set set = new HashSet(wordList); diff --git a/src/graph/CombinationsAndPermutations/Combinations.java b/src/graph/CombinationsAndPermutations/Combinations.java index 6cae079..1210a9c 100644 --- a/src/graph/CombinationsAndPermutations/Combinations.java +++ b/src/graph/CombinationsAndPermutations/Combinations.java @@ -1,4 +1,4 @@ -package CombinationsAndPermutations; +package graph.CombinationsAndPermutations; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/graph/CombinationsAndPermutations/Permutations.java b/src/graph/CombinationsAndPermutations/Permutations.java index bd906b4..15fc1c6 100644 --- a/src/graph/CombinationsAndPermutations/Permutations.java +++ b/src/graph/CombinationsAndPermutations/Permutations.java @@ -1,4 +1,4 @@ -package CombinationsAndPermutations; +package graph.CombinationsAndPermutations; import java.util.*; diff --git a/src/graph/CombinationsAndPermutations/SubSets.java b/src/graph/CombinationsAndPermutations/SubSets.java index 160c74f..52521a7 100644 --- a/src/graph/CombinationsAndPermutations/SubSets.java +++ b/src/graph/CombinationsAndPermutations/SubSets.java @@ -1,4 +1,4 @@ -package CombinationsAndPermutations; +package graph.CombinationsAndPermutations; import java.util.*; diff --git a/src/graph/adjacencyList/AdjacencyList.java b/src/graph/adjacencyList/AdjacencyList.java index fad66ff..5cbb663 100644 --- a/src/graph/adjacencyList/AdjacencyList.java +++ b/src/graph/adjacencyList/AdjacencyList.java @@ -1,5 +1,5 @@ -package adjacencyList; +package graph.adjacencyList; import java.util.LinkedList; import java.util.List; diff --git a/src/graph/adjacencyMatrix/AdjacencyMatrix.java b/src/graph/adjacencyMatrix/AdjacencyMatrix.java index e2fe366..0589973 100644 --- a/src/graph/adjacencyMatrix/AdjacencyMatrix.java +++ b/src/graph/adjacencyMatrix/AdjacencyMatrix.java @@ -1,4 +1,4 @@ -package adjacencyMatrix; +package graph.adjacencyMatrix; public class AdjacencyMatrix { diff --git a/src/graph/bellmanFord/BellmanFord.java b/src/graph/bellmanFord/BellmanFord.java index 9dd9e04..ffda9d0 100644 --- a/src/graph/bellmanFord/BellmanFord.java +++ b/src/graph/bellmanFord/BellmanFord.java @@ -1,4 +1,4 @@ -package bellmanFord; +package graph.bellmanFord; import java.util.HashMap; import java.util.Map; diff --git a/src/graph/bellmanFord/Edge.java b/src/graph/bellmanFord/Edge.java index ed56b0c..513013b 100644 --- a/src/graph/bellmanFord/Edge.java +++ b/src/graph/bellmanFord/Edge.java @@ -1,4 +1,4 @@ -package bellmanFord; +package graph.bellmanFord; public class Edge { diff --git a/src/graph/bellmanFord/Graph.java b/src/graph/bellmanFord/Graph.java index 290696f..517f46d 100644 --- a/src/graph/bellmanFord/Graph.java +++ b/src/graph/bellmanFord/Graph.java @@ -1,4 +1,4 @@ -package bellmanFord; +package graph.bellmanFord; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/graph/bellmanFord/NegativeException.java b/src/graph/bellmanFord/NegativeException.java index fc27bc0..3010279 100644 --- a/src/graph/bellmanFord/NegativeException.java +++ b/src/graph/bellmanFord/NegativeException.java @@ -1,4 +1,4 @@ -package bellmanFord; +package graph.bellmanFord; public class NegativeException extends RuntimeException { diff --git a/src/graph/bellmanFord/Vertex.java b/src/graph/bellmanFord/Vertex.java index c1c5bba..291b470 100644 --- a/src/graph/bellmanFord/Vertex.java +++ b/src/graph/bellmanFord/Vertex.java @@ -1,4 +1,4 @@ -package bellmanFord; +package graph.bellmanFord; import java.util.ArrayList; import java.util.List; diff --git a/src/graph/breadthFirstSearch/BreadthFirstSearch.java b/src/graph/breadthFirstSearch/BreadthFirstSearch.java index 7dbe19f..e07c57a 100644 --- a/src/graph/breadthFirstSearch/BreadthFirstSearch.java +++ b/src/graph/breadthFirstSearch/BreadthFirstSearch.java @@ -1,4 +1,4 @@ -package breadthFirstSearch; +package graph.breadthFirstSearch; import java.util.LinkedList; import java.util.List; diff --git a/src/graph/breadthFirstSearch/Graph.java b/src/graph/breadthFirstSearch/Graph.java index 42fb580..4b5b3c5 100644 --- a/src/graph/breadthFirstSearch/Graph.java +++ b/src/graph/breadthFirstSearch/Graph.java @@ -1,4 +1,4 @@ -package breadthFirstSearch; +package graph.breadthFirstSearch; import java.util.LinkedList; import java.util.List; diff --git a/src/graph/cycle/CycleInDirectedGraph.java b/src/graph/cycle/CycleInDirectedGraph.java index ae11824..2e823e9 100644 --- a/src/graph/cycle/CycleInDirectedGraph.java +++ b/src/graph/cycle/CycleInDirectedGraph.java @@ -1,4 +1,4 @@ -package cycle; +package graph.cycle; import java.util.HashSet; import java.util.Set; diff --git a/src/graph/cycle/CycleUndirectedGraph.java b/src/graph/cycle/CycleUndirectedGraph.java index f1e5482..66c7955 100644 --- a/src/graph/cycle/CycleUndirectedGraph.java +++ b/src/graph/cycle/CycleUndirectedGraph.java @@ -1,10 +1,11 @@ -package cycle; +package graph.cycle; + + +import graph.interview.DisjointSet; import java.util.HashSet; import java.util.Set; -import kruskalAlgorithm.DisjointSet; - /** * Date 10/11/2014 * @@ -28,8 +29,8 @@ public boolean hasCycleUsingDisjointSets(Graph graph) { } for (Edge edge : graph.getAllEdges()) { - long parent1 = disjointSet.findSet(edge.getVertex1().getId()); - long parent2 = disjointSet.findSet(edge.getVertex2().getId()); + long parent1 = disjointSet.findParent(edge.getVertex1().getId()); + long parent2 = disjointSet.findParent(edge.getVertex2().getId()); if (parent1 == parent2) { return true; } diff --git a/src/graph/cycle/Graph.java b/src/graph/cycle/Graph.java index fc145fa..28ad0cd 100644 --- a/src/graph/cycle/Graph.java +++ b/src/graph/cycle/Graph.java @@ -1,4 +1,4 @@ -package cycle; +package graph.cycle; import java.util.ArrayList; import java.util.Collection; diff --git a/src/graph/depthFirstSearch/DepthFirstSearch.java b/src/graph/depthFirstSearch/DepthFirstSearch.java index 7a19c1a..73b59a4 100644 --- a/src/graph/depthFirstSearch/DepthFirstSearch.java +++ b/src/graph/depthFirstSearch/DepthFirstSearch.java @@ -1,4 +1,4 @@ -package depthFirstSearch; +package graph.depthFirstSearch; import java.util.LinkedList; import java.util.Stack; diff --git a/src/graph/depthFirstSearch/Graph.java b/src/graph/depthFirstSearch/Graph.java index 0cd0017..9ba4180 100644 --- a/src/graph/depthFirstSearch/Graph.java +++ b/src/graph/depthFirstSearch/Graph.java @@ -1,4 +1,4 @@ -package depthFirstSearch; +package graph.depthFirstSearch; import java.util.HashMap; import java.util.LinkedList; diff --git a/src/graph/dijkstraAlgorithm/BinaryHeap.java b/src/graph/dijkstraAlgorithm/BinaryHeap.java index 754da5e..eef7b79 100644 --- a/src/graph/dijkstraAlgorithm/BinaryHeap.java +++ b/src/graph/dijkstraAlgorithm/BinaryHeap.java @@ -1,4 +1,4 @@ -package dijkstraAlgorithm; +package graph.dijkstraAlgorithm; import java.util.ArrayList; import java.util.HashMap; @@ -27,7 +27,7 @@ public String toString() { } protected Node extractMin() { - BinaryHeap.Node node = allNodes.get(0); + Node node = allNodes.get(0); int size = allNodes.size() - 1; allNodes.set(0, allNodes.get(size)); positionMap.remove(node.key); @@ -51,7 +51,7 @@ protected Node extractMin() { } int smallValuePosition = ((rightNode != null) && (rightNode.weight < leftNode.weight)) ? right : left; - BinaryHeap.Node parentNode = allNodes.get(smallValuePosition); + Node parentNode = allNodes.get(smallValuePosition); swapNodes(currentPosition, currentNode, smallValuePosition, parentNode); updatePositionMap(currentPosition, smallValuePosition, currentNode.key, parentNode.key); @@ -70,8 +70,8 @@ protected void addNode(int i, long key) { positionMap.put(key, currentPosition); - BinaryHeap.Node parentNode = allNodes.get(parentPosition); - BinaryHeap.Node currentNode = allNodes.get(currentPosition); + Node parentNode = allNodes.get(parentPosition); + Node currentNode = allNodes.get(currentPosition); while (parentNode.weight > currentNode.weight) { swapNodes(currentPosition, currentNode, parentPosition, parentNode); updatePositionMap(currentPosition, parentPosition, currentNode.key, parentNode.key); @@ -89,8 +89,8 @@ private void updatePositionMap(int currentPosition, int parentPosition, long cur positionMap.put(parent, currentPosition); } - private void swapNodes(int currentPosition, BinaryHeap.Node currentNode, int parentPosition, - BinaryHeap.Node parentNode) { + private void swapNodes(int currentPosition, Node currentNode, int parentPosition, + Node parentNode) { allNodes.set(currentPosition, parentNode); allNodes.set(parentPosition, currentNode); } diff --git a/src/graph/dijkstraAlgorithm/DijkstraAlgorithm.java b/src/graph/dijkstraAlgorithm/DijkstraAlgorithm.java index f929185..3371318 100644 --- a/src/graph/dijkstraAlgorithm/DijkstraAlgorithm.java +++ b/src/graph/dijkstraAlgorithm/DijkstraAlgorithm.java @@ -1,4 +1,4 @@ -package dijkstraAlgorithm; +package graph.dijkstraAlgorithm; import java.util.HashMap; import java.util.List; diff --git a/src/graph/dijkstraAlgorithm/Graph.java b/src/graph/dijkstraAlgorithm/Graph.java index 50c804d..2e32125 100644 --- a/src/graph/dijkstraAlgorithm/Graph.java +++ b/src/graph/dijkstraAlgorithm/Graph.java @@ -1,4 +1,4 @@ -package dijkstraAlgorithm; +package graph.dijkstraAlgorithm; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/graph/disjoints/DisjointSetArrayImplementation.java b/src/graph/disjoints/DisjointSetArrayImplementation.java index ef0a53b..a9cf451 100644 --- a/src/graph/disjoints/DisjointSetArrayImplementation.java +++ b/src/graph/disjoints/DisjointSetArrayImplementation.java @@ -1,4 +1,4 @@ -package com.disjoints; +package graph.disjoints; public class DisjointSetArrayImplementation { diff --git a/src/graph/disjoints/DisjointSetWithNode.java b/src/graph/disjoints/DisjointSetWithNode.java index 5c2fe4c..0908c44 100644 --- a/src/graph/disjoints/DisjointSetWithNode.java +++ b/src/graph/disjoints/DisjointSetWithNode.java @@ -1,4 +1,4 @@ -package com.disjoints; +package graph.disjoints; import java.util.HashMap; import java.util.Map; diff --git a/src/graph/disjoints/PredatorDisjointSet.java b/src/graph/disjoints/PredatorDisjointSet.java index 7f56cf6..44a03d7 100644 --- a/src/graph/disjoints/PredatorDisjointSet.java +++ b/src/graph/disjoints/PredatorDisjointSet.java @@ -1,4 +1,4 @@ -package com.disjoints; +package graph.disjoints; import java.util.ArrayList; import java.util.List; diff --git a/src/graph/floydwarshall/FloydWarshall.java b/src/graph/floydwarshall/FloydWarshall.java index ea3ac1f..6fe107e 100644 --- a/src/graph/floydwarshall/FloydWarshall.java +++ b/src/graph/floydwarshall/FloydWarshall.java @@ -1,4 +1,4 @@ - package floydwarshall; + package graph.floydwarshall; public class FloydWarshall { diff --git a/src/graph/interview/DisjointSet.java b/src/graph/interview/DisjointSet.java index f3639f1..fcfa221 100644 --- a/src/graph/interview/DisjointSet.java +++ b/src/graph/interview/DisjointSet.java @@ -1,4 +1,4 @@ -package com.interview; +package graph.interview; import java.util.HashMap; import java.util.Map; diff --git a/src/graph/kruskalAlgorithm/DisjointSet.java b/src/graph/kruskalAlgorithm/DisjointSet.java index 8e5aaac..46aca4e 100644 --- a/src/graph/kruskalAlgorithm/DisjointSet.java +++ b/src/graph/kruskalAlgorithm/DisjointSet.java @@ -1,4 +1,4 @@ -package kruskalAlgorithm; +package graph.kruskalAlgorithm; import java.util.HashMap; import java.util.Map; diff --git a/src/graph/kruskalAlgorithm/Graph.java b/src/graph/kruskalAlgorithm/Graph.java index 7197f7b..8acdf43 100644 --- a/src/graph/kruskalAlgorithm/Graph.java +++ b/src/graph/kruskalAlgorithm/Graph.java @@ -1,4 +1,4 @@ -package kruskalAlgorithm; +package graph.kruskalAlgorithm; import java.util.ArrayList; import java.util.Collection; diff --git a/src/graph/kruskalAlgorithm/KruskalMST.java b/src/graph/kruskalAlgorithm/KruskalMST.java index 2f2c785..9e17fe4 100644 --- a/src/graph/kruskalAlgorithm/KruskalMST.java +++ b/src/graph/kruskalAlgorithm/KruskalMST.java @@ -1,4 +1,4 @@ -package kruskalAlgorithm; +package graph.kruskalAlgorithm; import java.util.ArrayList; import java.util.Collections; diff --git a/src/graph/leetcode/AllPathsInGraph.java b/src/graph/leetcode/AllPathsInGraph.java index 380bddd..016f7c1 100644 --- a/src/graph/leetcode/AllPathsInGraph.java +++ b/src/graph/leetcode/AllPathsInGraph.java @@ -1,4 +1,4 @@ -package leetcode; +package graph.leetcode; import java.util.ArrayList; import java.util.List; diff --git a/src/graph/leetcode/CheapestFlightKStops.java b/src/graph/leetcode/CheapestFlightKStops.java index b040567..ed76cc7 100644 --- a/src/graph/leetcode/CheapestFlightKStops.java +++ b/src/graph/leetcode/CheapestFlightKStops.java @@ -1,4 +1,4 @@ -package leetcode; +package graph.leetcode; import java.util.*; diff --git a/src/graph/leetcode/ConnectCities.java b/src/graph/leetcode/ConnectCities.java index 695c1ca..184155f 100644 --- a/src/graph/leetcode/ConnectCities.java +++ b/src/graph/leetcode/ConnectCities.java @@ -1,4 +1,4 @@ -package leetcode; +package graph.leetcode; import java.util.ArrayList; import java.util.Collections; diff --git a/src/graph/leetcode/ConnectMissingCities.java b/src/graph/leetcode/ConnectMissingCities.java index 95ebc5f..f1ccd19 100644 --- a/src/graph/leetcode/ConnectMissingCities.java +++ b/src/graph/leetcode/ConnectMissingCities.java @@ -1,4 +1,4 @@ -package leetcode; +package graph.leetcode; import java.util.Arrays; diff --git a/src/graph/leetcode/ConnectedComponentsInGraph.java b/src/graph/leetcode/ConnectedComponentsInGraph.java index 322d774..e74203c 100644 --- a/src/graph/leetcode/ConnectedComponentsInGraph.java +++ b/src/graph/leetcode/ConnectedComponentsInGraph.java @@ -1,4 +1,4 @@ -package leetcode; +package graph.leetcode; public class ConnectedComponentsInGraph { diff --git a/src/graph/leetcode/CourseSchedule.java b/src/graph/leetcode/CourseSchedule.java index 37f22d0..5e9a63d 100644 --- a/src/graph/leetcode/CourseSchedule.java +++ b/src/graph/leetcode/CourseSchedule.java @@ -1,4 +1,4 @@ -package leetcode; +package graph.leetcode; import java.util.ArrayDeque; import java.util.ArrayList; diff --git a/src/graph/leetcode/FindJudge.java b/src/graph/leetcode/FindJudge.java index 790cb51..5017ee9 100644 --- a/src/graph/leetcode/FindJudge.java +++ b/src/graph/leetcode/FindJudge.java @@ -1,4 +1,4 @@ -package leetcode; +package graph.leetcode; /** * In a town, there are N people labelled from 1 to N. There is a rumor that one of these people is secretly the town judge. diff --git a/src/graph/leetcode/FriendCircles.java b/src/graph/leetcode/FriendCircles.java index 24f41b6..b6d715e 100644 --- a/src/graph/leetcode/FriendCircles.java +++ b/src/graph/leetcode/FriendCircles.java @@ -1,4 +1,4 @@ -package leetcode; +package graph.leetcode; // similar to number of Islands public class FriendCircles { diff --git a/src/graph/leetcode/GraphBiPartite.java b/src/graph/leetcode/GraphBiPartite.java index 39fdff3..d79fe27 100644 --- a/src/graph/leetcode/GraphBiPartite.java +++ b/src/graph/leetcode/GraphBiPartite.java @@ -1,4 +1,4 @@ -package leetcode; +package graph.leetcode; /** * Recall that a graph is bipartite if we can split it's set of nodes into diff --git a/src/graph/leetcode/MinCostRepairEdges.java b/src/graph/leetcode/MinCostRepairEdges.java index c39f84c..5973234 100644 --- a/src/graph/leetcode/MinCostRepairEdges.java +++ b/src/graph/leetcode/MinCostRepairEdges.java @@ -1,4 +1,4 @@ -package leetcode; +package graph.leetcode; import java.util.Arrays; import java.util.HashSet; diff --git a/src/graph/leetcode/NetworkDelayTime.java b/src/graph/leetcode/NetworkDelayTime.java index 7ee77e7..71dc982 100644 --- a/src/graph/leetcode/NetworkDelayTime.java +++ b/src/graph/leetcode/NetworkDelayTime.java @@ -1,4 +1,4 @@ -package leetcode; +package graph.leetcode; import java.util.*; /** diff --git a/src/graph/leetcode/NewRoadsMinimumSpanningTree.java b/src/graph/leetcode/NewRoadsMinimumSpanningTree.java index e0e74ea..452e482 100644 --- a/src/graph/leetcode/NewRoadsMinimumSpanningTree.java +++ b/src/graph/leetcode/NewRoadsMinimumSpanningTree.java @@ -1,4 +1,4 @@ -package geeksforgeeks; +package graph.leetcode; import java.util.Arrays; import java.util.PriorityQueue; diff --git a/src/graph/leetcode/RedundantConnection.java b/src/graph/leetcode/RedundantConnection.java index a7353f2..e4b9dd8 100644 --- a/src/graph/leetcode/RedundantConnection.java +++ b/src/graph/leetcode/RedundantConnection.java @@ -1,4 +1,4 @@ -package leetcode; +package graph.leetcode; /** * Input: [[1,2], [1,3], [2,3]] diff --git a/src/graph/leetcode/SentenceSimilarityII.java b/src/graph/leetcode/SentenceSimilarityII.java index 5e3d62f..3ae6e89 100644 --- a/src/graph/leetcode/SentenceSimilarityII.java +++ b/src/graph/leetcode/SentenceSimilarityII.java @@ -1,4 +1,4 @@ -package leetcode; +package graph.leetcode; import java.util.HashMap; import java.util.Map; diff --git a/src/graph/leetcode/SnapShotUtil.java b/src/graph/leetcode/SnapShotUtil.java index ff60082..4ffb4d5 100644 --- a/src/graph/leetcode/SnapShotUtil.java +++ b/src/graph/leetcode/SnapShotUtil.java @@ -1,4 +1,4 @@ -package leetcode; +package graph.leetcode; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/graph/primsAlgorithm/BinaryMinHeap.java b/src/graph/primsAlgorithm/BinaryMinHeap.java index 1f53399..831abaf 100644 --- a/src/graph/primsAlgorithm/BinaryMinHeap.java +++ b/src/graph/primsAlgorithm/BinaryMinHeap.java @@ -1,4 +1,4 @@ -package primsAlgorithm; +package graph.primsAlgorithm; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/graph/primsAlgorithm/Graph.java b/src/graph/primsAlgorithm/Graph.java index d651ee7..574019b 100644 --- a/src/graph/primsAlgorithm/Graph.java +++ b/src/graph/primsAlgorithm/Graph.java @@ -1,4 +1,4 @@ -package primsAlgorithm; +package graph.primsAlgorithm; import java.util.ArrayList; import java.util.Collection; diff --git a/src/graph/primsAlgorithm/PrimMST.java b/src/graph/primsAlgorithm/PrimMST.java index 3955674..e331709 100644 --- a/src/graph/primsAlgorithm/PrimMST.java +++ b/src/graph/primsAlgorithm/PrimMST.java @@ -1,4 +1,4 @@ -package primsAlgorithm; +package graph.primsAlgorithm; import java.util.*; diff --git a/src/graph/primsAlgorithm/PrimsMSTArray.java b/src/graph/primsAlgorithm/PrimsMSTArray.java index 25d39c9..a119093 100644 --- a/src/graph/primsAlgorithm/PrimsMSTArray.java +++ b/src/graph/primsAlgorithm/PrimsMSTArray.java @@ -1,4 +1,4 @@ -package primsAlgorithm; +package graph.primsAlgorithm; class PrimsMSTArray { diff --git a/src/graph/shortestPath/Graph.java b/src/graph/shortestPath/Graph.java index 799d170..78514e9 100644 --- a/src/graph/shortestPath/Graph.java +++ b/src/graph/shortestPath/Graph.java @@ -1,4 +1,4 @@ -package shortestPath; +package graph.shortestPath; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/graph/shortestPath/ShortestPath.java b/src/graph/shortestPath/ShortestPath.java index 984bf7b..99e208a 100644 --- a/src/graph/shortestPath/ShortestPath.java +++ b/src/graph/shortestPath/ShortestPath.java @@ -1,4 +1,4 @@ -package shortestPath; +package graph.shortestPath; import java.util.LinkedList; diff --git a/src/graph/topologicalsort/Graph.java b/src/graph/topologicalsort/Graph.java index 7ba49f3..30244d6 100644 --- a/src/graph/topologicalsort/Graph.java +++ b/src/graph/topologicalsort/Graph.java @@ -1,4 +1,4 @@ -package topologicalsort; +package graph.topologicalsort; import java.util.ArrayList; import java.util.Collection; diff --git a/src/graph/topologicalsort/TopologicalSort.java b/src/graph/topologicalsort/TopologicalSort.java index 502109b..6152b2a 100644 --- a/src/graph/topologicalsort/TopologicalSort.java +++ b/src/graph/topologicalsort/TopologicalSort.java @@ -1,4 +1,4 @@ -package topologicalsort; +package graph.topologicalsort; import java.util.HashSet; import java.util.Set; diff --git a/src/graph/topologicalsort/TopologicalSortList.java b/src/graph/topologicalsort/TopologicalSortList.java index 046bb99..b210b26 100644 --- a/src/graph/topologicalsort/TopologicalSortList.java +++ b/src/graph/topologicalsort/TopologicalSortList.java @@ -1,4 +1,4 @@ -package topologicalsort; +package graph.topologicalsort; import java.util.LinkedList; import java.util.List; diff --git a/src/internals/ConcurrentHashMap.java b/src/internals/ConcurrentHashMap.java new file mode 100644 index 0000000..7eccf84 --- /dev/null +++ b/src/internals/ConcurrentHashMap.java @@ -0,0 +1,282 @@ +package internals; + +import java.util.LinkedList; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +public class ConcurrentHashMap { + +// final Segment[] segments; +// // Other varialbes +// +// static final class HashEntry { +// final int hash; +// final K key; +// volatile V value; +// volatile HashEntry next; +// // Constructors + utility methods +// } +// +// static final class Segment extends ReentrantLock implements Serializable { +// // Implementations of methods like replace,clear,put etc. +// // Each such operation is handled by the particular Segment. +// } +// +// public boolean isEmpty() { +// // checks by iterating through all the segments. +// } +// +// public int size() { +// // Iterates through all the segments to get the count/size. +// } +// +// // Performed without acquiring the lock. +// public V get(Object key) { +// // Get segment +// // Get HashEntries for that Segment +// // itarate over the HashEntries to compare the Key. +// } +// +// public boolean containsValue(Object value) { +// // Iterates over all the Segments. +// // To check any Segment, locks it and then gets all HashEntries, and compare each of them. +// // Releases the lock for that segment after it. +// } +// +// public V put(K key, V value) { +// // Gets the Segment, and calls the put method implemented within that segment. +// } +// +// public V remove(Object key) { +// // Gets the Segment, and calls the remove method implemented within that segment. +// } +// +// @Override +// public boolean remove(Object key, Object value) { +// return false; +// } +// +// public boolean replace(K key, V oldValue, V newValue) { +// // Gets the Segment, and calls the replace method implemented within that segment. +// } +// +// public void clear() { +// // Gets the Segment, and calls the clear method implemented within that segment. +// } +// public V get(Object key) { +// Segment s; // manually integrate access methods to reduce overhead +// HashEntry[] tab; +// int h = hash(key.hashCode()); +// long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE; +// if ((s = (Segment)UNSAFE.getObjectVolatile(segments, u)) != null && +// (tab = s.table) != null) { +// for (HashEntry e = (HashEntry) UNSAFE.getObjectVolatile +// (tab, ((long)(((tab.length - 1) & h)) << TSHIFT) + TBASE); +// e != null; e = e.next) { +// K k; +// if ((k = e.key) == key || (e.hash == h && key.equals(k))) +// return e.value; +// } +// } +// return null; +// } +// +// +// @Override +// public Set> entrySet() { +// return null; +// } + + + private static final int DEFAULT_CONCURRENCY_LEVEL = 16; + + private static final int INITIAL_CAPACITY = 16; + + private float LOAD_FACTOR = 0.75f; + + private int capacity = INITIAL_CAPACITY; + + private int size; + + private Lock[] locks; + + private MyHashMap myHashMap = new MyHashMap(); + + private class MyHashMap { + private LinkedList[] lists = new LinkedList[INITIAL_CAPACITY]; + + private class MapEntry { + final Object key; + volatile Object value; + + MapEntry(Object key, Object value) { + this.key = key; + this.value = value; + } + } + + void put(Object key, Object value) { + if (key == null) + throw new IllegalArgumentException("Key Cannot be Null"); + int hash = key.hashCode(); + hash %= lists.length; + if (size >= LOAD_FACTOR * lists.length) { + capacity = lists.length * 2; + LinkedList[] tempLists = new LinkedList[capacity]; + System.arraycopy(lists, 0, tempLists, 0, lists.length); + lists = tempLists; + reHash(); + } + if (lists[hash] == null) { + lists[hash] = new LinkedList<>(); + size++; + } + int i = 0; + for (; i < lists[hash].size(); i++) { + MapEntry mapEntry = (MapEntry) (lists[hash].get(i)); + if (mapEntry != null && mapEntry.key.equals(key)) { + mapEntry.value = value; + break; + } + } + if (i == lists[hash].size()) { + lists[hash].addLast(new MapEntry(key, value)); + } + } + + Object get(Object key) { + int hash = key.hashCode(); + hash %= lists.length; + Object value = null; + if (lists[hash] != null) { + for (int i = 0; i < lists[hash].size(); i++) { + MapEntry mapEntry = (MapEntry) (lists[hash].get(i)); + if (mapEntry != null && mapEntry.key.equals(key)) { + value = mapEntry.value; + break; + } + } + } + return value; + } + + private void reHash() { + for (int i = 0; i < lists.length; i++) { + if (lists[i] != null) { + int hash = ((MapEntry) lists[i].getFirst()).key.hashCode(); + hash %= lists.length; + if (i != hash) { + lists[hash] = lists[i]; + lists[i] = null; + } + } + } + + } + + int size() { + return size; + } + + int capacity() { + return capacity; + } + } + + public ConcurrentHashMap(int concurrencyLevel) { + locks = new Lock[concurrencyLevel]; + for (int i = 0; i < concurrencyLevel; i++) { + locks[i] = new ReentrantLock(); + } + } + + public ConcurrentHashMap() { + this(DEFAULT_CONCURRENCY_LEVEL); + } + + public void put(Object key, Object value) { + int hash = key.hashCode(); + hash %= myHashMap.capacity(); + locks[hash].lock(); + myHashMap.put(key, value); + locks[hash].unlock(); + } + + public Object get(Object key) { + return myHashMap.get(key); + } + + public static void main(String[] args) { + ConcurrentHashMap myCCHashMap = new ConcurrentHashMap(); + myCCHashMap.put(1, "Thomas"); + myCCHashMap.put(9, "Mathew"); + myCCHashMap.put(17, "Tissa"); + myCCHashMap.put(9, "Mathew Thomas"); + System.out.println(myCCHashMap.get(1)); + System.out.println(myCCHashMap.get(9)); + System.out.println(myCCHashMap.get(17)); + } +} + +// final class Segment extends ReentrantLock implements Serializable { +// +// transient volatile HashEntry[] table; +// transient int threshold; +// final float loadFactor; +// +// Segment(float loadFactor) { +// this.loadFactor = loadFactor; +// } +// +// final V put(K key, int hash, V value, boolean onlyIfAbsent) { +// // Obtain the lock on the current Segment +// HashEntry node = tryLock() ? null : scanAndLockForPut(key, hash, value); +// try { +// // Do normal Put operation like in hashmap +// } finally { +// // Release the lock after put is finished. +// unlock(); +// } +// } +// +// /** +// * Remove; match on key only if value null, else match both. +// */ +// final V remove(Object key, int hash, Object value) { +// // Obtain the lock on the current Segment +// if (!tryLock()) +// scanAndLock(key, hash); +// +// try { +// // Normal Remove operation as in HashMap. +// } finally { +// // Release the lock once the remove is done. +// unlock(); +// } +// +// } +// +// final boolean replace(K key, int hash, V oldValue, V newValue) { +// // Obtain the lock on the current Segment +// if (!tryLock()) +// scanAndLock(key, hash); +// try { +// // Normal Replace operation as in HashMap. +// } finally { +// // Release the lock once the remove is done. +// unlock(); +// } +// return replaced; +// } +// +// final void clear() { +// // Obtain the lock on the current Segment +// lock(); +// try { +// // Normal clear operation as in HashMap. +// } finally { +// // Release the lock once the clear is done. +// unlock(); +// } +// } +//} \ No newline at end of file diff --git a/src/internals/HashMap.java b/src/internals/HashMap.java new file mode 100644 index 0000000..955f09f --- /dev/null +++ b/src/internals/HashMap.java @@ -0,0 +1,178 @@ +package internals; + +import java.util.Objects; + +class HashMap { + private int size = 0; + private int capacity = 16; + private Entry[] entries = new Entry[capacity]; + private double loadFactor = 0.75; + + private static class Entry { + private final K key; + private V value; + // Java initializes reference fields to null by default. + //private Entry next = null; + private Entry next; + + // No point in 'public' here: + /*public*/ Entry(K key, V value) { + this.key = key; + this.value = value; + } + } + + public HashMap() { + } + + public boolean isEmpty() { + return this.size == 0; + } + + public int getSize() { + return this.size; + } + + public boolean containsKey(K key) { + Entry matchingEntry = getMatchingEntry(key); + + return matchingEntry != null && matchingEntry.key == key; + } + + public boolean containsValue(V value) { + for (Entry entry : this.entries) { + while (entry != null && !matches(value, entry.value)) { + entry = entry.next; + } + + if (entry != null) { + return true; + } + } + + return false; + } + + public V get(K key) { + Entry matchingEntry = getMatchingEntry(key); + + return matchingEntry == null ? null : matchingEntry.value; + } + + public void put(K key, V value) { + if (this.shouldResize()) { + this.resize(); + } + + if (addEntry(new Entry<>(key, value), this.entries)) { + this.size++; + } + + } + + public void remove(K key) { + int index = indexOf(key); + Entry currentEntry = this.entries[index]; + + while (currentEntry != null && currentEntry.next != null && !matches(key, currentEntry.next.key)) { + currentEntry = currentEntry.next; + } + + if (currentEntry != null) { + // this case can only occur if there is only one non-null entry at the index + if (matches(key, currentEntry.key)) { + this.entries[index] = null; + // this case can only occur because the next entry's key matched + } else if (currentEntry.next != null) { + currentEntry.next = currentEntry.next.next; + } + + this.size--; + } + } + + private boolean shouldResize() { + return this.size > Math.ceil((double) this.capacity * this.loadFactor); + } + + private void resize() { + this.capacity = this.size * 2; + + Entry[] newEntries = new Entry[this.capacity]; + for (Entry entry : this.entries) { + if (entry != null) { + this.setEntry(entry, newEntries); + } + } + + this.entries = newEntries; + } + + private void setEntry(Entry entry, Entry[] entries){ + Entry nextEntry = entry.next; + entry.next = null; + + this.addEntry(entry, entries); + + if (nextEntry != null) { + this.setEntry(nextEntry, entries); + } + } + + private boolean addEntry(Entry entry, Entry[] entries) { + int index = indexOf(entry.key); + Entry existingEntry = entries[index]; + + if (existingEntry == null) { + entries[index] = entry; + return true; + } else { + while (!this.matches(entry.key, existingEntry.key) && existingEntry.next != null) { + existingEntry = existingEntry.next; + } + + if (this.matches(entry.key, existingEntry.key)) { + existingEntry.value = entry.value; + return false; + } + + existingEntry.next = entry; + return true; + + } + } + + private Entry getMatchingEntry(K key) { + Entry existingEntry = this.entries[indexOf(key)]; + + while (existingEntry != null && !matches(key, existingEntry.key)) { + existingEntry = existingEntry.next; + } + + return existingEntry; + } + + private int indexOf(K object) { + return object == null ? 0 : hash(object) & (this.capacity - 1); + } + + private boolean matches(Object o1, Object o2) { + return Objects.equals(o1, o2); + } + + /** + * Applies a supplemental hash function to a given hashCode, which + * defends against poor quality hash functions. This is critical + * because HashMap uses power-of-two length hash tables, that + * otherwise encounter collisions for hashCodes that do not differ + * in lower bits. Note: Null keys always map to hash 0, thus index 0. + */ + private static int hash(Object key) { + // This function ensures that hashCodes that differ only by + // constant multiples at each bit position have a bounded + // number of collisions (approximately 8 at default load factor). + int h; + return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); + } + } + diff --git a/src/internals/LinkedHashMap.java b/src/internals/LinkedHashMap.java new file mode 100644 index 0000000..9c119b6 --- /dev/null +++ b/src/internals/LinkedHashMap.java @@ -0,0 +1,170 @@ +package internals; + +public class LinkedHashMap { + private Entry[] buckets; + private int capacity=4; + private Entry head; + private Entrytail; + static class Entry + { + K key; + V value; + Entrynext; + Entrybefore; + Entryafter; + public Entry(K key ,V value,Entry next) + { + this.key=key; + this.value=value; + this.next=next; + } + } + public LinkedHashMap() + { + buckets=new Entry[capacity]; + } + public void put(K key,V value) + { + if(key==null)//not allow null key + { + return; + } + boolean replace=false; + int hash=hash(key); + Entry newEntry = new Entry(key, value, null); + //insert in bucket + // maintainOrderAfterInsert(newEntry); + Entrycurr=buckets[hash]; + + if(curr==null) + { + buckets[hash]=newEntry; + } + else + { + Entry prev=null; + while(curr!=null) + { + if(curr.key.equals(key)) + { + replace=true; + curr.value=value; + break; + } + prev=curr; + curr=curr.next; + } + if(prev!=null) + prev.next=newEntry; + } + //newEntry.next=curr; + //buckets[hash]=newEntry; + if(replace==false) + insertInList(newEntry); + //buckets[hash]=newEntry; + } + private void insertInList(Entry newEntry) + { + if(head==null) + { + head=newEntry; + tail=newEntry; + } + else + { + tail.after=newEntry; + newEntry.before=tail; + tail=newEntry; + } + } + public V get(K key) + { + int hash=hash(key); + Entry curr=buckets[hash]; + while(curr!=null) + { + if(curr.key.equals(key)) + { + return curr.value; + } + curr=curr.next; + } + return null; + } + + public void print() + { + Entrycurr=head; + while(curr!=null) + { + System.out.println("key is "+ curr.key+"val is "+ curr.value+"->"); + curr=curr.after; + } + } + private int hash(K key){ + return Math.abs(key.hashCode()) % capacity; + } + + public void remove(K key) + { + int hash=hash(key); + Entrycurr=buckets[hash]; + if(curr==null)//no exist + { + return; + } + Entryp=null; + Entryn; + while(curr!=null) + { + n=curr.next; + if(curr.key.equals(key)) + { + if(p==null)//first + { + buckets[hash]=buckets[hash].next; + } + else + { + p.next=n; + } + //adjust Linked List + adjustList(curr); + break; + } + p=curr; + curr=n; + } + + } + private void adjustList(Entry curr) + { + if(curr==head) + { + head=head.after; + if(head==null) + { + tail=null; + } + } + else if (curr==tail) + { + tail=tail.before; + tail.after=null; + } + else + { + curr.before.after=curr.after; + curr.after.before=curr.before; + } + } + public void deleteAll() + { + head=null; + tail=null; + for(int i=0;i { + private final Lock lock = new ReentrantLock(); + private final Condition notFull = lock.newCondition(); + private final Condition notEmpty = lock.newCondition(); + + private final Deque queue = new LinkedList(); + private final int limit; + + public MyBlockingQueue(int limit) { + if (limit < 1) throw new IllegalStateException("limit should be greater than 0"); + this.limit = limit; + } + + public synchronized void enqueue(T item) throws InterruptedException { + lock.lock(); + try { + while (queue.size() == limit) { + notFull.await(); + } + queue.addLast(item); + notEmpty.signal(); + } finally { + lock.unlock(); + } + } + + public synchronized T dequeue() throws InterruptedException { + lock.lock(); + try { + while (queue.isEmpty()) { + notEmpty.await(); + } + final T x = queue.removeFirst(); + notFull.signal(); + return x; + } finally { + lock.unlock(); + } + } +} \ No newline at end of file diff --git a/src/internals/SJUArrayList.java b/src/internals/SJUArrayList.java new file mode 100644 index 0000000..6a7d0c9 --- /dev/null +++ b/src/internals/SJUArrayList.java @@ -0,0 +1,166 @@ +package internals; + +public class SJUArrayList { + // Data fields + private E[] theData; + private int size = 0; + private int capacity = 0; + + // Constants + private static final int INIT_CAPACITY = 10; + + // Constructors + public SJUArrayList() { + this(INIT_CAPACITY); + } + + public SJUArrayList(int initCapacity) { + capacity = initCapacity; + theData = (E[]) new Object[capacity]; + } + + // Methods + public boolean add(E e) { + if(e == null) { + throw new NullPointerException(); + } + + if(size == capacity) { + reallocate(); + } + + theData[size] = e; + size++; + + return true; + } // End add(E e) method + + public void add(int index, E e) { + if(index < 0 || index > size) { + throw new ArrayIndexOutOfBoundsException(index); + } + + if(e == null) { + throw new NullPointerException(); + } + + if(size == capacity) { + reallocate(); + } + + for(int i = size; i > index; i--) { + theData[i] = theData[i - 1]; + } + + theData[index] = e; + size++; + } // End add(int index, E e) method + + public void clear() { + theData = (E[]) new Object[capacity]; + size = 0; + } // End clear() method + + public boolean equals(Object o) { + if(o == null) { + return false; + } + + if(getClass() != o.getClass()) { + return false; + } + + SJUArrayList otherO = (SJUArrayList) o; + + if(size != otherO.size) { + return false; + } + + for(int i = 0; i < size; i++) { + if(!theData[i].equals(otherO.theData[i])) { + return false; + } + } + + return true; + } // End equals(Object o) method + + public E get(int index) { + if(index < 0 || index >= size) { + throw new ArrayIndexOutOfBoundsException(index); + } + return theData[index]; + } // End get(int index) method + + public int indexOf(Object o) { + if(o == null) { + throw new NullPointerException(); + } + + for(int i = 0; i < size; i++) { + if(theData[i].equals(o)) { + return i; + } + } + + return -1; + } // End indexOf(Object o) method + + public boolean isEmpty() { + return size == 0; + } // End isEmpty() method + + public E remove(int index) { + if(index < 0 || index >= size) { + throw new ArrayIndexOutOfBoundsException(index); + } + + E temp = theData[index]; + + for(int i = index + 1; i < size; i++) { + theData[i - 1] = theData[i]; + } + + size--; + return temp; + } // End remove(int index) method + + public boolean remove(Object o) { + int indexOfO = indexOf(o); + + if(indexOfO == -1) { + return false; + } + + remove(indexOfO); + return true; + } // End remove(Object o) method + + public E set(int index, E e) { + if(index < 0 || index >= size) { + throw new ArrayIndexOutOfBoundsException(index); + } + + if(e == null) { + throw new NullPointerException(); + } + E temp = theData[index]; + theData[index] = e; + return temp; + } // End set(int index, E e) method + + public int size() { + return size; + } // End size() method + + private void reallocate() { + capacity *= 2; + E[] newArraylist = (E[]) new Object[capacity]; + + for(int i = 0; i < size; i++) { + newArraylist[i] = theData[i]; + } + + theData = newArraylist; + } // End reallocate() method +} \ No newline at end of file diff --git a/src/linkedLists/Agoda.java b/src/linkedLists/Agoda.java new file mode 100644 index 0000000..9fea7ac --- /dev/null +++ b/src/linkedLists/Agoda.java @@ -0,0 +1,117 @@ +package linkedLists; + +import java.util.Deque; +import java.util.LinkedList; + +public class Agoda { + + Node head; + + public static void main(String[] args) { + Node head = new Node(1); + head.next = new Node(2); + head.next.next = new Node(3); + head.next.next.next = new Node(4); + head.next.next.next.next = new Node(5); + head.next.next.next.next.next = new Node(6); + + Agoda agoda = new Agoda(); + + // agoda.findNthNodeFromEnd(head, 4); + // agoda.reversePairNodes(head); +// agoda.reverseKNode(head, null); + agoda.slidingWindow(); + } + + private void slidingWindow() { + int[] arr = { 6, 4, 5, 2, 1, 9, 8 }; + int index = 0; + int k = 3; + Deque deque = new LinkedList(); + for (; index < k; index++) { + while (!deque.isEmpty() && arr[deque.peekLast()] < arr[index]) + deque.removeLast(); + deque.addLast(index); + } + + for (; index < arr.length; index++) { + System.out.println(arr[deque.peekFirst()]); + while (!deque.isEmpty() && index - k >= deque.peekFirst()) + deque.removeFirst(); + + while (!deque.isEmpty() && arr[deque.peekLast()] < arr[index]) + deque.removeLast(); + + deque.addLast(index); + } + + } + + private void reverseKNode(Node node, Node link) { + + Node curr = node; + Node prev = null; + Node next = null; + + int index = 0; + while (curr != null && index < 3) { + next = curr.next; + curr.next = prev; + prev = curr; + curr = next; + index++; + } + + if (link == null) + head = prev; + else + link.next = prev; + + if (curr != null) + reverseKNode(curr, node); + + while (head != null) { + System.out.println(head.data); + head = head.next; + } + } + + private void reversePairNodes(Node head) { + Node temp = null; + Node realHead = null; + while (head != null && head.next != null) { + if (temp != null) + temp.next.next = head.next; + + temp = head.next; + head.next = head.next.next; + temp.next = head; + if (realHead == null) + realHead = temp; + head = head.next; + } + while (realHead != null) { + System.out.println(realHead.data); + realHead = realHead.next; + } + } + + private void findNthNodeFromEnd(Node head, int n) { + if (head == null || head.next == null) + return; + Node slowPointer = head; + Node fastPointer = head; + int index = 0; + while (n > index && fastPointer != null) { + fastPointer = fastPointer.next; + index++; + } + + while (fastPointer.next != null) { + slowPointer = slowPointer.next; + fastPointer = fastPointer.next; + } + System.out.println(slowPointer.data); + } + +} diff --git a/src/linkedLists/AllProblems.java b/src/linkedLists/AllProblems.java new file mode 100644 index 0000000..53cdd89 --- /dev/null +++ b/src/linkedLists/AllProblems.java @@ -0,0 +1,257 @@ +package linkedLists; + +public class AllProblems { + + static Node head; + static int size; + static RandomNode randomHead; + + public static void main(String[] args) { + addNode(2); + addNode(5); + addNode(8); + addNode(10); + addNode(12); + // findNthNode(3); + // findCyclic(); + // reverseLinkedList(); + // middleOfTheLinkedList(); + // printListInReverse(head); + // reversePairLinkedListIterative(); + // reverseLinkedListUsingRecursiveMethod(head); + // cloneRandomLinkedList(); + // printList(); + // reverseLinkedListPractise(); + Node head2 = new Node(1); + head2.next = new Node(4); + head2.next.next = new Node(7); + head2.next.next = new Node(9); + head2.next.next.next = new Node(19); + head2.next.next.next.next = new Node(29); + Node result = mergeList(head, head2); + + while (result != null) { + System.out.print(result.data + " "); + result = result.next; + } + } + + private static Node mergeList(Node a, Node b) { + System.out.println(a + "->" + b); + Node c = null; + if (a == null) + return b; + if (b == null) + return a; + + if (a.data < b.data) { + c = a; + c.next = mergeList(a.next, b); + } else { + c = b; + c.next = mergeList(b.next, a); + } + return c; + } + + private static void cloneRandomLinkedList() { + + RandomNode node1 = new RandomNode(1); + RandomNode node2 = new RandomNode(2); + RandomNode node3 = new RandomNode(3); + RandomNode node4 = new RandomNode(4); + RandomNode node5 = new RandomNode(5); + + randomHead = node1; + + node1.next = node2; + node2.next = node3; + node3.next = node4; + node4.next = node5; + + node1.random = node3; + node2.random = node1; + node3.random = node5; + node4.random = node3; + node5.random = node2; + + // create cloned node between original nodes + RandomNode temp = randomHead; + while (null != temp) { + RandomNode rn = new RandomNode(temp.data + 0.5); + rn.next = temp.next; + temp.next = rn; + temp = rn.next; + } + RandomNode assignTemp = randomHead; + while (null != assignTemp) { + assignTemp.next.random = assignTemp.random.next; + + assignTemp = assignTemp.next; + } + + temp = randomHead; + while (null != temp && null != temp.next) { + assignTemp.next.next = assignTemp.next.next.next; + + } + + RandomNode tempp = randomHead; + while (tempp != null) { + System.out.println(tempp.data); + tempp = tempp.next; + } + + } + + private static Node reverseLinkedListUsingRecursiveMethod(Node curr) { + + if (null == curr) + return null; + + Node prev = reverseLinkedListUsingRecursiveMethod(curr.next); + if (null != prev) + prev.next = curr; + else + head = curr; + return curr; + + } + + private static void reversePairLinkedListIterative() { + + Node temp1 = null; + Node realHead = null; + while (head != null && head.next != null) { + if (temp1 != null) + temp1.next.next = head.next; + + temp1 = head.next; + head.next = head.next.next; + temp1.next = head; + if (realHead == null) + realHead = temp1; + head = head.next; + } + while (realHead != null) { + System.out.println(realHead.data); + realHead = realHead.next; + } + } + + private static Object printListInReverse(Node temp) { + if (temp != null) { + printListInReverse(temp.getNode()); + System.out.println(temp.getData()); + } + return null; + } + + private static void middleOfTheLinkedList() { + + Node fastPointer = head; + Node slowPointer = head; + while (fastPointer.getNode() != null && fastPointer.getNode().getNode() != null) { + slowPointer = slowPointer.getNode(); + fastPointer = fastPointer.getNode().getNode(); + if (fastPointer.getNode() == null || fastPointer.getNode().getNode() == null) { + System.out.println(slowPointer.getData()); + } + } + } + + private static void reverseLinkedList() { + Node curr = head; + Node prev = curr; + if (head.getNode() != null) { + curr = curr.getNode(); + } + while (curr.getNode() != null) { + Node next = curr.getNode(); + curr.setNode(prev); + prev = curr; + curr = next; + } + curr.setNode(prev); + head = curr; + } + + private static void reverseLinkedListPractise() { + Node curr = head; + Node prev = null; + Node next = null; + while (curr != null) { + next = curr.next; + curr.next = prev; + prev = curr; + curr = next; + } + curr = prev; + while (curr != null) { + System.out.println(curr.data); + curr = curr.next; + } + } + + private static void findCyclic() { + Node slowPointer = head; + Node fastPointer = head; + System.out.println("slow pointer : " + slowPointer.getData() + "and Fast pointer :" + fastPointer.getData()); + while (fastPointer.getNode() != null && fastPointer.getNode().getNode() != null) { + slowPointer = slowPointer.getNode(); + fastPointer = fastPointer.getNode().getNode(); + if (slowPointer == fastPointer) { + System.out.println("Gotcha its cyclic" + slowPointer + "::" + fastPointer); + return; + } else { + System.out.println("slow pointer : " + slowPointer + "and Fast pointer :" + fastPointer); + } + } + } + + private static void findNthNode(int n) { + Node temp = head; + Node nthNode = head; + int index = 1; + while (index < n) { + temp = temp.getNode(); + index++; + } + + while (temp.getNode() != null) { + temp = temp.getNode(); + nthNode = nthNode.getNode(); + } + + System.out.println("Nth Node from end: " + nthNode.getData()); + + } + + private static void printList() { + Node temp = head; + int index = 0; + while (index < size) { + System.out.println(temp.getData()); + temp = temp.getNode(); + index++; + } + } + + private static void addNode(int data) { + Node node = new Node(data); + if (head == null) { + head = node; + node.setNode(null); + } else { + Node temp = head; + int index = 1; + while (index < size) { + temp = temp.getNode(); + index++; + } + temp.setNode(node); + node.setNode(null); + } + size++; + } +} diff --git a/src/linkedLists/ArrayToBST.java b/src/linkedLists/ArrayToBST.java new file mode 100644 index 0000000..c39029a --- /dev/null +++ b/src/linkedLists/ArrayToBST.java @@ -0,0 +1,34 @@ +package linkedLists; + +public class ArrayToBST { + + static int i; + static int[] arr = { 1, 2, 3, 4, 5, 6, 7 }; + + Node sortedArrayToBST(int arr[], int start, int end) { + + if (start > end) { + return null; + } + int mid = (start + end) / 2; + Node node = new Node(arr[mid]); + node.prev = sortedArrayToBST(arr, start, mid - 1); + node.next = sortedArrayToBST(arr, mid + 1, end); + + return node; + } + + public static void main(String[] args) { + ArrayToBST arrToBSt = new ArrayToBST(); + Node sortedArrayToBST = arrToBSt.sortedArrayToBST(arr, 0, 6); + preOrder(sortedArrayToBST); + } + + private static void preOrder(Node converArrayToBST) { + if (null == converArrayToBST) + return; + preOrder(converArrayToBST.prev); + System.out.print(converArrayToBST.getData() + " "); + preOrder(converArrayToBST.next); + } +} diff --git a/src/linkedLists/CloneRandomPointerLinkedList.java b/src/linkedLists/CloneRandomPointerLinkedList.java new file mode 100644 index 0000000..1f19ad2 --- /dev/null +++ b/src/linkedLists/CloneRandomPointerLinkedList.java @@ -0,0 +1,102 @@ +package linkedLists; + +// Java program to clone a linked list with next +// and arbit pointers in O(n) time +class CloneRandomPointerLinkedList { + + // Structure of linked list Node + static class Node { + int data; + Node next, random; + + Node(int x) { + data = x; + next = random = null; + } + } + + // Utility function to print the list. + static void print(Node start) { + Node ptr = start; + while (ptr != null) { + System.out.println("Data = " + ptr.data + ", Random = " + ptr.random.data); + ptr = ptr.next; + } + } + + // This function clones a given + // linked list in O(1) space + static Node clone(Node start) { + Node curr = start, temp = null; + + // insert additional node after + // every node of original list + while (curr != null) { + temp = curr.next; + + // Inserting node + curr.next = new Node(curr.data); + curr.next.next = temp; + curr = temp; + } + curr = start; + + // adjust the random pointers of the + // newly added nodes + while (curr != null) { + if (curr.next != null) + curr.next.random = (curr.random != null) ? curr.random.next : curr.random; + + // move to the next newly added node by + // skipping an original node + curr = (curr.next != null) ? curr.next.next : curr.next; + } + + Node original = start, copy = start.next; + + // save the start of copied linked list + temp = copy; + + // now separate the original list and copied list + while (original != null && copy != null) { + original.next = (original.next != null) ? original.next.next : original.next; + + copy.next = (copy.next != null) ? copy.next.next : copy.next; + original = original.next; + copy = copy.next; + } + return temp; + } + + // Driver code + public static void main(String[] args) { + Node start = new Node(1); + start.next = new Node(2); + start.next.next = new Node(3); + start.next.next.next = new Node(4); + start.next.next.next.next = new Node(5); + + // 1's random points to 3 + start.random = start.next.next; + + // 2's random points to 1 + start.next.random = start; + + // 3's and 4's random points to 5 + start.next.next.random = start.next.next.next.next; + start.next.next.next.random = start.next.next.next.next; + + // 5's random points to 2 + start.next.next.next.next.random = start.next; + + System.out.println("Original list : "); + print(start); + + System.out.println("Cloned list : "); + Node cloned_list = clone(start); + print(cloned_list); + + } +} + +// This code is contributed by Prerna Saini. diff --git a/src/linkedLists/DLLToBBST.java b/src/linkedLists/DLLToBBST.java new file mode 100644 index 0000000..d8b75fc --- /dev/null +++ b/src/linkedLists/DLLToBBST.java @@ -0,0 +1,69 @@ +package linkedLists; + +public class DLLToBBST { + + static Node head; + + public static void main(String[] args) { + addNode(7); + addNode(6); + addNode(5); + addNode(4); + addNode(3); + addNode(2); + addNode(1); + + DLLToBBST bst = new DLLToBBST(); + bst.preOrder(bst.sortedListToBST()); + } + + Node sortedListToBST() { + int n = countNodes(head); + return sortedListToBSTRecur(n); + } + + Node sortedListToBSTRecur(int n) { + if (n <= 0) + return null; + Node left = sortedListToBSTRecur(n / 2); + Node root = head; + root.prev = left; + head = head.next; + root.next = sortedListToBSTRecur(n - n / 2 - 1); + + return root; + } + + private static void addNode(int i) { + + Node node = new Node(i); + if (null == head) { + head = node; + } else { + Node temp = head; + while (null != temp.next) { + temp = temp.next; + } + temp.next = node; + node.prev = temp; + } + } + + int countNodes(Node head) { + int count = 0; + Node temp = head; + while (temp != null) { + temp = temp.next; + count++; + } + return count; + } + + void preOrder(Node node) { + if (node == null) + return; + System.out.print(node.data + " "); + preOrder(node.prev); + preOrder(node.next); + } +} diff --git a/src/linkedLists/DLLToBBSTTimeEfficiency.java b/src/linkedLists/DLLToBBSTTimeEfficiency.java new file mode 100644 index 0000000..095e97d --- /dev/null +++ b/src/linkedLists/DLLToBBSTTimeEfficiency.java @@ -0,0 +1,79 @@ +package linkedLists; + +public class DLLToBBSTTimeEfficiency { + + static Node head; + + private Node findMiddleNode(Node temp) { + Node fastPointer, slowPointer; + fastPointer = slowPointer = temp; + + while (null != fastPointer && null != fastPointer.next) { + fastPointer = fastPointer.next.next; + slowPointer = slowPointer.next; + } + return slowPointer; + } + + private Node formBBST(Node head) { + if (null == head) + return null; + if (null == head.next) { + head.prev = null; + return head; + } + + Node root = findMiddleNode(head); + Node temp = head; + + while (root != temp.next) { + temp = temp.next; + } + temp.next = null; + + Node rightStart = root.next; + root.prev = formBBST(head); + root.next = formBBST(rightStart); + + return root; + } + + private static void addNode(int i) { + + Node node = new Node(i); + if (null == head) { + head = node; + } else { + Node temp = head; + while (null != temp.next) { + temp = temp.next; + } + temp.next = node; + node.prev = temp; + } + } + + public static void main(String[] args) { + addNode(7); + addNode(6); + addNode(5); + addNode(4); + addNode(3); + addNode(2); + addNode(1); + + DLLToBBSTTimeEfficiency bst = new DLLToBBSTTimeEfficiency(); + bst.preOrder(bst.formBBST(head)); + + } + + private void preOrder(Node temp) { + if (null == temp) + return; + + System.out.print(temp.getData() + " "); + preOrder(temp.prev); + preOrder(temp.next); + + } +} diff --git a/src/linkedLists/DetectAndRemoveLoop.java b/src/linkedLists/DetectAndRemoveLoop.java new file mode 100644 index 0000000..67ad625 --- /dev/null +++ b/src/linkedLists/DetectAndRemoveLoop.java @@ -0,0 +1,112 @@ +package linkedLists; +class DetectAndRemoveLoop { + + static Node head; + + static class Node { + + int data; + Node next; + + Node(int d) { + data = d; + next = null; + } + } + + // Function that detects loop in the list + int detectAndRemoveLoop(Node node) { + Node slow = node, fast = node; + while (slow != null && fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + + // If slow and fast meet at same point then loop is present + if (slow == fast) { + removeLoop(slow, node); + return 1; + } + } + return 0; + } + + public Node detectCycle(Node head) { + if(head==null || head.next==null) return null; + + Node root=head; + Node slow=head; + Node fast=head; + + while(fast!=null && fast.next!=null){ + fast=fast.next.next; + slow=slow.next; + if(fast==slow){ + while(slow!=root){ + slow=slow.next; + root=root.next; + } + return slow; + } + + } + + return null; + + } + + // Function to remove loop + void removeLoop(Node loop, Node curr) { + Node ptr1 = null, ptr2 = null; + + /* Set a pointer to the beging of the Linked List and + move it one by one to find the first node which is + part of the Linked List */ + ptr1 = curr; + while (true) { + + /* Now start a pointer from loop_node and check if it ever + reaches ptr2 */ + ptr2 = loop; + while (ptr2.next != loop && ptr2.next != ptr1) { + ptr2 = ptr2.next; + } + + /* If ptr2 reahced ptr1 then there is a loop. So break the + loop */ + if (ptr2.next == ptr1) { + break; + } + + /* If ptr2 did't reach ptr1 then try the next node after ptr1 */ + ptr1 = ptr1.next; + } + + /* After the end of loop ptr2 is the last node of the loop. So + make next of ptr2 as NULL */ + ptr2.next = null; + } + + // Function to print the linked list + void printList(Node node) { + while (node != null) { + System.out.print(node.data + " "); + node = node.next; + } + } + + // Driver program to test above functions + public static void main(String[] args) { + DetectAndRemoveLoop list = new DetectAndRemoveLoop(); + list.head = new Node(1); + list.head.next = new Node(2); + list.head.next.next = new Node(3); + list.head.next.next.next = new Node(4); + list.head.next.next.next.next = new Node(5); + + // Creating a loop for testing + head.next.next.next.next.next = head.next; + list.detectAndRemoveLoop(head); + System.out.println("Linked List after removing loop : "); + list.printList(head); + } +} \ No newline at end of file diff --git a/src/linkedLists/FlattenDoublyLinkedList.java b/src/linkedLists/FlattenDoublyLinkedList.java new file mode 100644 index 0000000..fe09757 --- /dev/null +++ b/src/linkedLists/FlattenDoublyLinkedList.java @@ -0,0 +1,33 @@ +package linkedLists; + +public class FlattenDoublyLinkedList { + + public Node flatten(Node head) { + if(head==null) return head; + + Node root=head; + + while(root!=null){ + + if(root.child==null) { + root=root.next; + continue; + }else{ + Node temp=root.child; + while(temp.next!=null){ + temp=temp.next; + } + temp.next= root.next; + if(root.next!=null) root.next.prev=temp; + root.next=root.child; + root.child.prev=root; + root.child=null; + + } + + } + + return head; + + } +} diff --git a/src/linkedLists/FlattenLinkedList.java b/src/linkedLists/FlattenLinkedList.java new file mode 100644 index 0000000..ed21b40 --- /dev/null +++ b/src/linkedLists/FlattenLinkedList.java @@ -0,0 +1,124 @@ +package linkedLists; +class FlattenLinkedList +{ + Node head; + + class Node + { + int data; + Node right, down; + Node(int data) + { + this.data = data; + right = null; + down = null; + } + + @Override + public String toString() { + return "" + this.data; + } + } + + public Node flatten(Node root){ + if(root==null || root.right==null) return root; + Node right= flatten(root.right); + root= merge(root,right); + return root; + } + + public Node merge(Node root, Node right){ + Node dummy= new Node(0); + + Node head=dummy; + + while(root.down!=null && right.down!=null){ + if(root.data 10 -> 19 -> 28 + | | | | + V V V V + 7 20 22 35 + | | | + V V V + 8 50 40 + | | + V V + 30 45 + */ + + L.head = L.push(L.head, 30); + L.head = L.push(L.head, 8); + L.head = L.push(L.head, 7); + L.head = L.push(L.head, 5); + + L.head.right = L.push(L.head.right, 20); + L.head.right = L.push(L.head.right, 10); + + L.head.right.right = L.push(L.head.right.right, 50); + L.head.right.right = L.push(L.head.right.right, 22); + L.head.right.right = L.push(L.head.right.right, 19); + + L.head.right.right.right = L.push(L.head.right.right.right, 45); + L.head.right.right.right = L.push(L.head.right.right.right, 40); + L.head.right.right.right = L.push(L.head.right.right.right, 35); + + // flatten the list + L.head = L.flatten(L.head); + + L.printList(); + } +} \ No newline at end of file diff --git a/src/linkedLists/FlattenNestedIterator.java b/src/linkedLists/FlattenNestedIterator.java new file mode 100644 index 0000000..598099c --- /dev/null +++ b/src/linkedLists/FlattenNestedIterator.java @@ -0,0 +1,51 @@ +package linkedLists; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +class NestedIterator implements Iterator { + + + List flattenedList; + int index=0; + public NestedIterator(List nestedList) { + flattenedList= new ArrayList(); + populateList(nestedList); + } + + @Override + public Integer next() { + Integer temp=flattenedList.get(index); + index++; + return temp; + } + + @Override + public boolean hasNext() { + return flattenedList.size()>index; + } + + private void populateList(List nestedList){ + if(nestedList==null || nestedList.size()==0) return; + for(int i=0; i getList(); + } + + diff --git a/src/linkedLists/LinkedListToBST.java b/src/linkedLists/LinkedListToBST.java new file mode 100644 index 0000000..63a4974 --- /dev/null +++ b/src/linkedLists/LinkedListToBST.java @@ -0,0 +1,112 @@ +package linkedLists; + +class LinkedListToBST { + + static LNode head; + + class LNode { + int data; + LNode next, prev; + + LNode(int d) { + data = d; + next = prev = null; + } + } + + class TNode { + int data; + TNode left, right; + + TNode(int d) { + data = d; + left = right = null; + } + } + + TNode sortedListToBST() { + int n = countNodes(head); + return sortedListToBSTRecur(n); + } + + TNode sortedListToBSTRecur(int n) { + if (n <= 0) + return null; + + TNode left = sortedListToBSTRecur(n / 2); + TNode root = new TNode(head.data); + root.left = left; + head = head.next; + root.right = sortedListToBSTRecur(n - n / 2 - 1); + + return root; + } + + int countNodes(LNode head) { + int count = 0; + LNode temp = head; + while (temp != null) { + temp = temp.next; + count++; + } + return count; + } + + /* + * Function to insert a node at the beginging of the Doubly Linked List + */ + void push(int new_data) { + /* allocate node */ + LNode new_node = new LNode(new_data); + + /* + * since we are adding at the begining, prev is always NULL + */ + new_node.prev = null; + + /* link the old list off the new node */ + new_node.next = head; + + /* change prev of head node to new node */ + if (head != null) + head.prev = new_node; + + /* move the head to point to the new node */ + head = new_node; + } + + void printList(LNode node) { + while (node != null) { + System.out.print(node.data + " "); + node = node.next; + } + } + + void preOrder(TNode node) { + if (node == null) + return; + System.out.print(node.data + " "); + preOrder(node.left); + preOrder(node.right); + } + + public static void main(String[] args) { + LinkedListToBST llist = new LinkedListToBST(); + + llist.push(7); + llist.push(6); + llist.push(5); + llist.push(4); + llist.push(3); + llist.push(2); + llist.push(1); + + System.out.println("Given Linked List "); + llist.printList(head); + + TNode root = llist.sortedListToBST(); + System.out.println(""); + System.out.println("Pre-Order Traversal of constructed BST "); + llist.preOrder(root); + } +} \ No newline at end of file diff --git a/src/linkedLists/ListNode.java b/src/linkedLists/ListNode.java new file mode 100644 index 0000000..8401342 --- /dev/null +++ b/src/linkedLists/ListNode.java @@ -0,0 +1,15 @@ +package geeksforgeeks; + +public class ListNode { + public int val; + public ListNode next; + public ListNode(int x) { val = x; } + + @Override + public String toString() { + return "ListNode{" + + "val=" + val + + ", next=" + next + + '}'; + } +} diff --git a/src/linkedLists/ListNode1.java b/src/linkedLists/ListNode1.java new file mode 100644 index 0000000..2ad699f --- /dev/null +++ b/src/linkedLists/ListNode1.java @@ -0,0 +1,15 @@ +package linkedLists; + +public class ListNode1 { + public int val; + public ListNode next; + public ListNode1(int x) { val = x; } + + @Override + public String toString() { + return "ListNode{" + + "val=" + val + + ", next=" + next + + '}'; + } +} diff --git a/src/linkedLists/Main.java b/src/linkedLists/Main.java new file mode 100644 index 0000000..a75b6ba --- /dev/null +++ b/src/linkedLists/Main.java @@ -0,0 +1,86 @@ +package linkedLists; + +import java.util.*; + +class MyStack { + Stack s; + Integer minEle; + + MyStack() { + s = new Stack(); + } + + void getMin() { + if (s.isEmpty()) { + System.out.println("Stack is empty"); + } else { + System.out.println("Minimum Element in the " + " stack is: " + minEle); + } + } + + void peek() { + if (s.isEmpty()) { + System.out.println("Stack is empty "); + return; + } + + Integer t = s.peek(); + System.out.print("Top Most Element is: "); + + if (t < minEle) { + System.out.println(minEle); + } else { + System.out.println(t); + } + } + + void pop() { + if (s.isEmpty()) { + System.out.println("Stack is empty"); + return; + } + + System.out.print("Top Most Element Removed: "); + Integer t = s.pop(); + if (t < minEle) { + System.out.println(minEle); + minEle = 2 * minEle - t; + } else { + System.out.println(t); + } + } + + void push(Integer x) { + if (s.isEmpty()) { + minEle = x; + s.push(x); + System.out.println("Number Inserted: " + x); + return; + } + if (x < minEle) { + s.push(2 * x - minEle); + minEle = x; + } else { + s.push(x); + } + + System.out.println("Number Inserted: " + x); + } +}; + +public class Main { + public static void main(String[] args) { + MyStack s = new MyStack(); + s.push(7); + s.push(5); + s.push(2); + s.pop(); + s.push(4); + s.getMin(); + s.push(1); + s.pop(); + s.getMin(); + s.pop(); + s.peek(); + } +} \ No newline at end of file diff --git a/src/linkedLists/MergeTwoLinkedLists.java b/src/linkedLists/MergeTwoLinkedLists.java new file mode 100644 index 0000000..b116d47 --- /dev/null +++ b/src/linkedLists/MergeTwoLinkedLists.java @@ -0,0 +1,111 @@ +package linkedLists; + +public class MergeTwoLinkedLists { + + public static Node head_1; + public static Node head_2; + public static Node head; + + public static void main(String[] args) { + addNodeInList1(); + addNodeInList2(); + printLst(); + mergeLists(); + printList(); + } + + private static void printList() { + Node temp = head; + + while (temp != null) { + System.out.println(temp.getData()); + temp = temp.getNode(); + } + + } + + private static void mergeLists() { + Node temp_1 = head_1; + Node temp_2 = head_2; + Node temp = head; + + while (null != temp_1 && temp_2 != null) { + if (temp_1.getData() < temp_2.getData()) { + temp = insertNode(temp_1.getData(), temp); + temp_1 = temp_1.getNode(); + } else { + temp = insertNode(temp_2.getData(), temp); + temp_2 = temp_2.getNode(); + } + } + while (temp_1 != null && temp_2 == null) { + Node node = new Node(temp_1.getData()); + temp.setNode(node); + temp = temp.getNode(); + temp_1 = temp_1.getNode(); + } + while (temp_2 != null && temp_1 == null) { + Node node = new Node(temp_2.getData()); + temp.setNode(node); + temp = temp.getNode(); + temp_2 = temp_2.getNode(); + } + } + + private static Node insertNode(int data, Node temp) { + Node node = new Node(data); + if (temp == null) { + head = node; + temp = node; + } else { + temp.setNode(node); + temp = temp.getNode(); + } + return temp; + } + + private static void printLst() { + + Node temp_1 = head_1; + while (temp_1 != null) { + System.out.print(temp_1.getData() + " "); + temp_1 = temp_1.getNode(); + } + + System.out.println(); + + Node temp = head_2; + while (temp != null) { + System.out.print(temp.getData() + " "); + temp = temp.getNode(); + } + System.out.println(); + System.out.println(); + } + + private static void addNodeInList2() { + int n = 5; + Node node = new Node(2); + head_1 = node; + Node temp = head_1; + for (int i = 0; i < 5; i++) { + Node newNode = new Node(n); + temp.setNode(newNode); + temp = newNode; + n += 2; + } + } + + private static void addNodeInList1() { + int n = 2; + Node node = new Node(1); + head_2 = node; + Node temp = head_2; + for (int i = 0; i < 5; i++) { + Node newNode = new Node(n); + temp.setNode(newNode); + temp = newNode; + n += 3; + } + } +} diff --git a/src/linkedLists/MiddleElement.java b/src/linkedLists/MiddleElement.java new file mode 100644 index 0000000..b441c62 --- /dev/null +++ b/src/linkedLists/MiddleElement.java @@ -0,0 +1,28 @@ +package linkedLists; + +public class MiddleElement { + + static SinglyLinkedListNode head; + + public static void main(String[] args) { + head = new SinglyLinkedListNode(1); + head.next = new SinglyLinkedListNode(2); + head.next.next = new SinglyLinkedListNode(3); + head.next.next.next = new SinglyLinkedListNode(4); + head.next.next.next.next = new SinglyLinkedListNode(5); + + findMiddleElement(); + } + + private static void findMiddleElement() { + SinglyLinkedListNode temp = head; + SinglyLinkedListNode slowPointer = temp; + SinglyLinkedListNode fastPointer = temp; + while (fastPointer != null && fastPointer.next != null) { + slowPointer = slowPointer.next; + fastPointer = fastPointer.next.next; + } + System.out.println(slowPointer.data); + } + +} diff --git a/src/linkedLists/Node.java b/src/linkedLists/Node.java new file mode 100644 index 0000000..de06ce0 --- /dev/null +++ b/src/linkedLists/Node.java @@ -0,0 +1,54 @@ +package linkedLists; + +public class Node { + + Node left; + Node right; + public Node next; + public int data; + public Node child; + public Node prev; + + public Node(int data) { + this.data = data; + } + + public Node getLeft() { + return left; + } + + public void setLeft(Node left) { + this.left = left; + } + + public Node getRight() { + return right; + } + + public void setRight(Node right) { + this.right = right; + } + + public Node getNext() { + return next; + } + + public void setNext(Node next) { + this.next = next; + } + + public int getData() { + return data; + } + + public void setData(int data) { + this.data = data; + } + + public void setNode(Object o) { + } + + public Node getNode() { + return this; + } +} diff --git a/src/linkedLists/PalindromeSinglyLinkedList.java b/src/linkedLists/PalindromeSinglyLinkedList.java new file mode 100644 index 0000000..1095a6d --- /dev/null +++ b/src/linkedLists/PalindromeSinglyLinkedList.java @@ -0,0 +1,53 @@ +package linkedLists; + +import java.util.Stack; + +public class PalindromeSinglyLinkedList { + + class Node { + int data; + Node next; + + public Node(int data) { + this.data = data; + } + + } + + public static void main(String[] args) { + + PalindromeSinglyLinkedList palindrome = new PalindromeSinglyLinkedList(); + Node head = palindrome.new Node(1); + head.next = palindrome.new Node(2); + head.next.next = palindrome.new Node(3); + head.next.next.next = palindrome.new Node(2); + head.next.next.next.next = palindrome.new Node(1); + + System.out.println(palindrome.isPalindrome(head)); + + } + + private boolean isPalindrome(Node head) { + Node slow = head; + Node fast = head; + + Stack stack = new Stack(); + + while (fast != null && fast.next != null) { + stack.push(slow); + slow = slow.next; + fast = fast.next.next; + } + + while (!stack.isEmpty()) { + Node pop = stack.pop(); + if (pop.data != slow.next.data) { + return false; + } else { + slow = slow.next; + } + } + return true; + } + +} diff --git a/src/linkedLists/RandomNode.java b/src/linkedLists/RandomNode.java new file mode 100644 index 0000000..515e8ad --- /dev/null +++ b/src/linkedLists/RandomNode.java @@ -0,0 +1,35 @@ +package linkedLists; + +public class RandomNode { + RandomNode next; + RandomNode random; + double data; + + public RandomNode(double d) { + data = d; + } + + public RandomNode getNext() { + return next; + } + + public void setNext(RandomNode next) { + this.next = next; + } + + public RandomNode getRandom() { + return random; + } + + public void setRandom(RandomNode random) { + this.random = random; + } + + public double getData() { + return data; + } + + public void setData(double data) { + this.data = data; + } +} diff --git a/src/linkedLists/ReverseKBlockNode.java b/src/linkedLists/ReverseKBlockNode.java new file mode 100644 index 0000000..144bfb9 --- /dev/null +++ b/src/linkedLists/ReverseKBlockNode.java @@ -0,0 +1,78 @@ +package linkedLists; + +public class ReverseKBlockNode { + + static SinglyLinkedListNode head; + static int k = 3; + + public static void main(String[] args) { + head = new SinglyLinkedListNode(1); + head.next = new SinglyLinkedListNode(2); + head.next.next = new SinglyLinkedListNode(3); + head.next.next.next = new SinglyLinkedListNode(4); + head.next.next.next.next = new SinglyLinkedListNode(5); + head.next.next.next.next.next = new SinglyLinkedListNode(6); + head.next.next.next.next.next.next = new SinglyLinkedListNode(7); + head.next.next.next.next.next.next.next = new SinglyLinkedListNode(8); + head.next.next.next.next.next.next.next.next = new SinglyLinkedListNode(9); + head.next.next.next.next.next.next.next.next.next = new SinglyLinkedListNode(10); + + reverseBlocks(head, null); + print(head); + } + + private static void reverseBlocks(SinglyLinkedListNode temp, SinglyLinkedListNode link) { + + SinglyLinkedListNode current = temp; + SinglyLinkedListNode next = null; + SinglyLinkedListNode prev = null; + int count = 0; + while (current != null && count < k) { + next = current.next; + current.next = prev; + prev = current; + current = next; + count++; + } + if (link != null) { + link.next = prev; + } else { + head = prev; + } + if (current != null) { + reverseBlocks(current, temp); + } + + } + + private static void print(SinglyLinkedListNode current) { + SinglyLinkedListNode node = current; + while (node != null) { + System.out.println(node.data); + node = node.next; + } + } + + public ListNode reverseKNodes(ListNode head, int k){ + if(head==null) return head; + ListNode root= head; + int count=0; + while (count0){ + ListNode next= head.next; + head.next=prev; + prev=head; + head=next; + count--; + + } + + return prev; + } + +} diff --git a/src/linkedLists/ReverseLinkedList.java b/src/linkedLists/ReverseLinkedList.java new file mode 100644 index 0000000..4797a12 --- /dev/null +++ b/src/linkedLists/ReverseLinkedList.java @@ -0,0 +1,41 @@ +package linkedLists; + +public class ReverseLinkedList { + + public ListNode reverseList(ListNode head) { + if(head==null || head.next==null) return head; + // for 1->2->3->4->5->null + // 5 will be returned(5->null) when head is at 4 + // head.next.next means 4's next(5)'s next is 4=> 5->4->null for top recursion + // when head is 3, 5->4->null is returned as tmp at this point 3's->4 and 5's-> also 4 + // head.next.next means 3's next 4's(5->4->null) next is 3=> 5->4->3->null + ListNode temp= reverseList(head.next); + head.next.next= head; + head.next=null; + return temp; + + } + + public ListNode reverseList1(ListNode head) { + if(head==null) return null; + ListNode root=head; + ListNode prev=null; + while(root!=null){ + ListNode temp=root.next; + root.next=prev; + prev=root; + root=temp; + } + return prev; + + } + + public static void main(String[] args) { + ListNode node= new ListNode(1); + node.next= new ListNode(2); + node.next.next= new ListNode(3); + node.next.next.next= new ListNode(4); + node.next.next.next.next= new ListNode(5); + new ReverseLinkedList().reverseList(node); + } +} diff --git a/src/linkedLists/ReverseLinkedListBetweenMandN.java b/src/linkedLists/ReverseLinkedListBetweenMandN.java new file mode 100644 index 0000000..7282cb1 --- /dev/null +++ b/src/linkedLists/ReverseLinkedListBetweenMandN.java @@ -0,0 +1,36 @@ +package linkedLists; + + +public class ReverseLinkedListBetweenMandN { + + public ListNode reverseBetween(ListNode head, int m, int n) { + ListNode fakeHead = new ListNode(-1); + fakeHead.next = head; + ListNode prev = fakeHead; + ListNode curr = fakeHead.next; + int i = 1; + while (i < m) { // i travels till m-1 to store prev + prev = curr; + curr = curr.next; + i++; + } + ListNode node = prev; + while (i <= n) { // normal reverse linkedlist + ListNode tmp = curr.next; + curr.next = prev; + prev = curr; + curr = tmp; + i++; + } + + // for 1->2->3->4->5->null, m = 2, n = 4, + // after the second while, we got 1<->2<-3<-4 5->null + // now cur = 5, pre = 4, node = 1, + // so node.next = 2, node.next.next = cur means 2->5 + // node.next = pre means 1->4, then we get the result 1->4->3->2->5->null. + + node.next.next = curr; + node.next = prev; + return fakeHead.next; + } +} diff --git a/src/linkedLists/ReversePairs.java b/src/linkedLists/ReversePairs.java new file mode 100644 index 0000000..6806096 --- /dev/null +++ b/src/linkedLists/ReversePairs.java @@ -0,0 +1,92 @@ +package linkedLists; + +public class ReversePairs { + + static Node head; + + public static void main(String[] args) { + Node head = new Node(1); + head.next = new Node(2); + head.next.next = new Node(3); + head.next.next.next = new Node(4); + head.next.next.next.next = new Node(5); + head.next.next.next.next.next = new Node(6); + head.next.next.next.next.next.next = new Node(7); + + // Node reversePairs = reversePairs(head); + reverseKNodes(head, null); + printReversedPairs(ReversePairs.head); + } + + private static void reverseKNodes(Node node, Node temp) { + if (node == null) + return; + + Node curr = node; + Node prev = null; + Node next = null; + int index = 0; + + while (curr != null && index < 3) { + next = curr.next; + curr.next = prev; + prev = curr; + curr = next; + index++; + } + + if (temp == null) { + head = prev; + } else { + temp.next = prev; + } + + if (curr != null) + reverseKNodes(curr, node); + + } + + private static void printReversedPairs(Node node) { + if (node == null) + return; + while (node != null) { + System.out.println(node.data); + node = node.next; + } + + } + + private static Node reversePairs(Node node) { + + if (node == null || node.next == null) { + return null; + } + + // Initialize previous and current pointers + Node prev = node; + Node curr = node.next; + + node = curr; // Change head before proceeeding + + // Traverse the list + while (true) { + Node next = curr.next; + curr.next = prev; // Change next of current as previous node + + // If next NULL or next is the last node + if (next == null || next.next == null) { + prev.next = next; + break; + } + + // Change next of previous to next next + prev.next = next.next; + + // Update previous and curr + prev = next; + curr = prev.next; + } + return node; + } + +} diff --git a/src/linkedLists/ReversePairsNode.java b/src/linkedLists/ReversePairsNode.java new file mode 100644 index 0000000..8ef7716 --- /dev/null +++ b/src/linkedLists/ReversePairsNode.java @@ -0,0 +1,47 @@ +package linkedLists; + +public class ReversePairsNode { + public ListNode reversePairs(ListNode head){ + if(head==null) return head; + + ListNode dummy= new ListNode(-1); + dummy.next= head; + ListNode current= dummy; + + + // {dummy->1->2->3->4->null} + //explanation for one loop rest are same. + while(current.next!=null && current.next.next!=null){ + // current points to dummy in the beginning. + // first -> 1 + ListNode first= current.next; + //second -> 2 + ListNode second= current.next.next; + + ListNode temp= second.next; + + // dummy->2 + current.next=second; + + //1->3 + first.next=temp; + //2->1 + second.next=first; + // curr=1 + current=first; + // now { dummy->2->1->3->4 } + } + + return dummy.next; + } + + public ListNode reversePairsRecursion(ListNode head){ + if(head==null || head.next==null) return head; + ListNode next= head.next; + + head.next = reversePairsRecursion(head.next.next); + next.next = head; + return next; + + } +} diff --git a/src/linkedLists/ReverseSinglyLinkedListWithoutExtraSpace.java b/src/linkedLists/ReverseSinglyLinkedListWithoutExtraSpace.java new file mode 100644 index 0000000..2122e66 --- /dev/null +++ b/src/linkedLists/ReverseSinglyLinkedListWithoutExtraSpace.java @@ -0,0 +1,42 @@ +package linkedLists; + +public class ReverseSinglyLinkedListWithoutExtraSpace { + Node root; + + public static void main(String[] args) { + ReverseSinglyLinkedListWithoutExtraSpace list = new ReverseSinglyLinkedListWithoutExtraSpace(); + list.root = new Node(1); + list.root.next = new Node(2); + list.root.next.next = new Node(3); + list.root.next.next.next = new Node(4); + list.root.next.next.next.next = new Node(5); + + reverseLinkedList(list.root); + + } + + private static void printNode(Node root) { + while (root != null) { + System.out.println(root.data); + root = root.next; + } + + } + + private static void reverseLinkedList(Node root) { + if (null == root) { + return; + } + Node prev = root; + Node curr = prev.next; + prev.next = null; + + while (null != prev && null != curr) { + Node temp = curr.next; + curr.next = prev; + prev = curr; + curr = temp; + } + printNode(prev); + } +} diff --git a/src/linkedLists/RotateList.java b/src/linkedLists/RotateList.java new file mode 100644 index 0000000..79945a4 --- /dev/null +++ b/src/linkedLists/RotateList.java @@ -0,0 +1,84 @@ +package linkedLists; + +import java.util.Collections; +import java.util.PriorityQueue; + +public class RotateList { + public ListNode rotateRight(ListNode head, int k) { + if(k==0 || head==null) return head; + + ListNode tempHead= head; + int length=1; + while(tempHead.next!=null){ + length++; + tempHead=tempHead.next; + } + tempHead.next=head; + // if(k%length==0) return head; + k%=length; + for(int i=0;i minQueue= new PriorityQueue<>(); + PriorityQueue maxQueue= new PriorityQueue<>(Collections.reverseOrder()); + + public void offer(int x){ + maxQueue.offer(x); + minQueue.offer(maxQueue.poll()); + if(maxQueue.size() + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..1763e15 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..b9cb99a --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/0/2/02413cef30175a0fcd6eb85a234590f79bef6049 b/.idea/sonarlint/issuestore/0/2/02413cef30175a0fcd6eb85a234590f79bef6049 new file mode 100644 index 0000000..61b4b93 --- /dev/null +++ b/.idea/sonarlint/issuestore/0/2/02413cef30175a0fcd6eb85a234590f79bef6049 @@ -0,0 +1,6 @@ + +f java:S1173"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ŧ +S java:S1064"9Replace this use of System.out or System.err by a logger.( +k java:S117 "QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ȷ +X +java:S3518"=Make sure "cycle" can't be zero before doing this modulation.(܋ \ No newline at end of file diff --git a/src/geeksforgeeks/temp.xml b/.idea/sonarlint/issuestore/0/4/044ff579a2d425788b7a2f4e97a5a11953e8bae9 similarity index 100% rename from src/geeksforgeeks/temp.xml rename to .idea/sonarlint/issuestore/0/4/044ff579a2d425788b7a2f4e97a5a11953e8bae9 diff --git a/.idea/sonarlint/issuestore/0/5/05dbd5d32b30dbcdcf527591e456aaadba20f05e b/.idea/sonarlint/issuestore/0/5/05dbd5d32b30dbcdcf527591e456aaadba20f05e new file mode 100644 index 0000000..b70e6c2 --- /dev/null +++ b/.idea/sonarlint/issuestore/0/5/05dbd5d32b30dbcdcf527591e456aaadba20f05e @@ -0,0 +1,6 @@ + +m java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(8ŝ. +r java:S117 "QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(՞8ŝ. += +java:S16596" Declare "t1" on a separate line.(8ŝ. +] java:S125=""bRemove this useless assignment; "root" already holds the assigned value along all execution paths.( +x +java:S4165="bRemove this useless assignment; "root" already holds the assigned value along all execution paths.( +S +java:S1854"8Remove this useless assignment to local variable "root".( +S +java:S1854"8Remove this useless assignment to local variable "root".( +S java:S1065"9Replace this use of System.out or System.err by a logger.( +S java:S106D"9Replace this use of System.out or System.err by a logger.(ً +S java:S106I"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/0/9/0988901fea7348f562f6caa5844f5747b3e6f627 b/.idea/sonarlint/issuestore/0/9/0988901fea7348f562f6caa5844f5747b3e6f627 new file mode 100644 index 0000000..8aab8fc --- /dev/null +++ b/.idea/sonarlint/issuestore/0/9/0988901fea7348f562f6caa5844f5747b3e6f627 @@ -0,0 +1,4 @@ + +< +java:S1659"!Declare "cur" on a separate line.(ϡ +S java:S106,"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/0/9/09ab1198ac046440a03c191f646446b9b5e9e02a b/.idea/sonarlint/issuestore/0/9/09ab1198ac046440a03c191f646446b9b5e9e02a new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/0/b/0bd608b214d88a7df9591cbd80aa77a66d84224a b/.idea/sonarlint/issuestore/0/b/0bd608b214d88a7df9591cbd80aa77a66d84224a new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/0/c/0c0b971e3b43c9d312c9f5a2b8420b6ce6203452 b/.idea/sonarlint/issuestore/0/c/0c0b971e3b43c9d312c9f5a2b8420b6ce6203452 new file mode 100644 index 0000000..848c840 --- /dev/null +++ b/.idea/sonarlint/issuestore/0/c/0c0b971e3b43c9d312c9f5a2b8420b6ce6203452 @@ -0,0 +1,2 @@ + +S java:S106:"9Replace this use of System.out or System.err by a logger.(؎ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/0/c/0c38cd56b3993148cbbbe1d4cc8d30b6bbee6364 b/.idea/sonarlint/issuestore/0/c/0c38cd56b3993148cbbbe1d4cc8d30b6bbee6364 new file mode 100644 index 0000000..1296caa --- /dev/null +++ b/.idea/sonarlint/issuestore/0/c/0c38cd56b3993148cbbbe1d4cc8d30b6bbee6364 @@ -0,0 +1,13 @@ + +H +java:S1144"(Remove this unused private "map" method.(8҅/ +[ java:S125"Use isEmpty() to check whether the collection is empty or not.(8˓. +o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ƌ +k +java:S2272"NAdd a "NoSuchElementException" for iteration beyond the end of the collection.(8˓. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/1/4/143283ada55cac97af6684e5923a787979185de5 b/.idea/sonarlint/issuestore/1/4/143283ada55cac97af6684e5923a787979185de5 new file mode 100644 index 0000000..e422680 --- /dev/null +++ b/.idea/sonarlint/issuestore/1/4/143283ada55cac97af6684e5923a787979185de5 @@ -0,0 +1,5 @@ + +_ +java:S2259"IA "NullPointerException" could be thrown; "slowPointer" is nullable here.( +N java:S106"9Replace this use of System.out or System.err by a logger.( +o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ƌ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/1/4/149d38c68bc3c3be09cfde27a524344e1ceeaae4 b/.idea/sonarlint/issuestore/1/4/149d38c68bc3c3be09cfde27a524344e1ceeaae4 new file mode 100644 index 0000000..b657eeb --- /dev/null +++ b/.idea/sonarlint/issuestore/1/4/149d38c68bc3c3be09cfde27a524344e1ceeaae4 @@ -0,0 +1,3 @@ + +N java:S106+"9Replace this use of System.out or System.err by a logger.( +S java:S106("9Replace this use of System.out or System.err by a logger.(ߋ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/1/7/17844b9f60cd8c916af473597ad830d88f828b1b b/.idea/sonarlint/issuestore/1/7/17844b9f60cd8c916af473597ad830d88f828b1b new file mode 100644 index 0000000..112a5f7 --- /dev/null +++ b/.idea/sonarlint/issuestore/1/7/17844b9f60cd8c916af473597ad830d88f828b1b @@ -0,0 +1,4 @@ + +: +java:S1659%"Declare "n" on a separate line.(ŗ +N java:S1063"9Replace this use of System.out or System.err by a logger.(ς \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/1/7/1784874474953c47a3183aaecdd41c1979e1970a b/.idea/sonarlint/issuestore/1/7/1784874474953c47a3183aaecdd41c1979e1970a new file mode 100644 index 0000000..535a91c --- /dev/null +++ b/.idea/sonarlint/issuestore/1/7/1784874474953c47a3183aaecdd41c1979e1970a @@ -0,0 +1,3 @@ + +W +java:S1118":Add a private constructor to hide the implicit public one.(8ʵ. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/1/8/1896855b3288119d2470dac0551b72c37e234c2d b/.idea/sonarlint/issuestore/1/8/1896855b3288119d2470dac0551b72c37e234c2d new file mode 100644 index 0000000..faa45ec --- /dev/null +++ b/.idea/sonarlint/issuestore/1/8/1896855b3288119d2470dac0551b72c37e234c2d @@ -0,0 +1,3 @@ + +o +java:S3776"RRefactor this method to reduce its Cognitive Complexity from 30 to the 15 allowed.(܏8. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/1/9/19726d43c4ff09a5a7a4183f4d0cce6a15e37c21 b/.idea/sonarlint/issuestore/1/9/19726d43c4ff09a5a7a4183f4d0cce6a15e37c21 new file mode 100644 index 0000000..9b41109 --- /dev/null +++ b/.idea/sonarlint/issuestore/1/9/19726d43c4ff09a5a7a4183f4d0cce6a15e37c21 @@ -0,0 +1,4 @@ + +o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ƌ +N java:S106"9Replace this use of System.out or System.err by a logger.( +N java:S106"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/1/b/1b5154d0c6bef48d028ab65f8b64e00031c3fc2e b/.idea/sonarlint/issuestore/1/b/1b5154d0c6bef48d028ab65f8b64e00031c3fc2e new file mode 100644 index 0000000..2b36aa5 --- /dev/null +++ b/.idea/sonarlint/issuestore/1/b/1b5154d0c6bef48d028ab65f8b64e00031c3fc2e @@ -0,0 +1,3 @@ + +Q java:S125."Use isEmpty() to check whether the collection is empty or not.(ϗ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/2/4/2486e44c6f684742f89a502f40931a950f6a5402 b/.idea/sonarlint/issuestore/2/4/2486e44c6f684742f89a502f40931a950f6a5402 new file mode 100644 index 0000000..8629ce8 --- /dev/null +++ b/.idea/sonarlint/issuestore/2/4/2486e44c6f684742f89a502f40931a950f6a5402 @@ -0,0 +1,6 @@ + +V java:S125"").(Ӭ +t +java:S22938"YReplace the type specification in this constructor call with the diamond operator ("<>").( +t +java:S2293A"YReplace the type specification in this constructor call with the diamond operator ("<>").(€ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/2/7/276408c9b92328ab537152f09ab71103ec9ef723 b/.idea/sonarlint/issuestore/2/7/276408c9b92328ab537152f09ab71103ec9ef723 new file mode 100644 index 0000000..4ac79f2 --- /dev/null +++ b/.idea/sonarlint/issuestore/2/7/276408c9b92328ab537152f09ab71103ec9ef723 @@ -0,0 +1,3 @@ + +] +java:S1126C"AReplace this if-then-else statement by a single return statement.(ۗ^8. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/2/b/2be2c99de12581c3ed22c8c0da7ccec80c446528 b/.idea/sonarlint/issuestore/2/b/2be2c99de12581c3ed22c8c0da7ccec80c446528 new file mode 100644 index 0000000..6bf730f --- /dev/null +++ b/.idea/sonarlint/issuestore/2/b/2be2c99de12581c3ed22c8c0da7ccec80c446528 @@ -0,0 +1,13 @@ + +c java:S100;"NRename this method name to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ܳ +V java:S125R"").( +N java:S106""9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/2/f/2ff08299ef14157c3b869ec0d960486f9f3e8541 b/.idea/sonarlint/issuestore/2/f/2ff08299ef14157c3b869ec0d960486f9f3e8541 new file mode 100644 index 0000000..6d9ef0f --- /dev/null +++ b/.idea/sonarlint/issuestore/2/f/2ff08299ef14157c3b869ec0d960486f9f3e8541 @@ -0,0 +1,14 @@ + +S +java:S1197"8Move the array designator from the variable to the type.( +N java:S106,"9Replace this use of System.out or System.err by a logger.( +M +java:S1144N"2Remove this unused private "findSuccessor" method.( +? +java:S1659")Declare "predecessor" on a separate line.( +X +java:S2696"6Make the enclosing method "static" or remove this set.(8. +I +java:S1144A"4Remove this unused private "findPredecessor" method.(ϥ' +S +java:S2696"6Make the enclosing method "static" or remove this set.(8. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/0/302919d36f07a9e0021304b45ee4024daa606206 b/.idea/sonarlint/issuestore/3/0/302919d36f07a9e0021304b45ee4024daa606206 new file mode 100644 index 0000000..df2a551 --- /dev/null +++ b/.idea/sonarlint/issuestore/3/0/302919d36f07a9e0021304b45ee4024daa606206 @@ -0,0 +1,13 @@ + +9 +java:S16597"#Declare "right" on a separate line.( +7 +java:S16597"!Declare "mid" on a separate line.( +N java:S106 "9Replace this use of System.out or System.err by a logger.( +m +java:S3776Q"RRefactor this method to reduce its Cognitive Complexity from 18 to the 15 allowed.( +N java:S106"9Replace this use of System.out or System.err by a logger.(¸ +m +java:S3776"RRefactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.( +m +java:S37766"RRefactor this method to reduce its Cognitive Complexity from 18 to the 15 allowed.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/0/30b50f5172b58071ccf2af28c9acd212d6dbcb27 b/.idea/sonarlint/issuestore/3/0/30b50f5172b58071ccf2af28c9acd212d6dbcb27 new file mode 100644 index 0000000..7531bff --- /dev/null +++ b/.idea/sonarlint/issuestore/3/0/30b50f5172b58071ccf2af28c9acd212d6dbcb27 @@ -0,0 +1,3 @@ + +W +java:S1126'"AReplace this if-then-else statement by a single return statement.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/1/31108dcd9c0b903c6e9ed945d5eec698442dd540 b/.idea/sonarlint/issuestore/3/1/31108dcd9c0b903c6e9ed945d5eec698442dd540 new file mode 100644 index 0000000..049f596 --- /dev/null +++ b/.idea/sonarlint/issuestore/3/1/31108dcd9c0b903c6e9ed945d5eec698442dd540 @@ -0,0 +1,5 @@ + +m +java:S2234"WParameters to knows have the same names but not the same order as the method arguments.(ۋ +< +java:S1172"&Remove these unused method parameters.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/2/32e1641c502813055e829c1372417d5c18d22d1f b/.idea/sonarlint/issuestore/3/2/32e1641c502813055e829c1372417d5c18d22d1f new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/3/4/3429a973dee382fb3b8f5d1f3efa2287b2a05cf3 b/.idea/sonarlint/issuestore/3/4/3429a973dee382fb3b8f5d1f3efa2287b2a05cf3 new file mode 100644 index 0000000..2b4c78a --- /dev/null +++ b/.idea/sonarlint/issuestore/3/4/3429a973dee382fb3b8f5d1f3efa2287b2a05cf3 @@ -0,0 +1,6 @@ + +W +java:S1126"AReplace this if-then-else statement by a single return statement.(‡ +: +java:S1659 "Declare "j" on a separate line.( +S java:S106&"9Replace this use of System.out or System.err by a logger.(Ӑ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/4/3458c98caffa57eab71d6c70502a21e868d6e9a5 b/.idea/sonarlint/issuestore/3/4/3458c98caffa57eab71d6c70502a21e868d6e9a5 new file mode 100644 index 0000000..5899485 --- /dev/null +++ b/.idea/sonarlint/issuestore/3/4/3458c98caffa57eab71d6c70502a21e868d6e9a5 @@ -0,0 +1,9 @@ + +A +java:S1659b"Declare "n" on a separate line.(˜8. +o +java:S3776]"RRefactor this method to reduce its Cognitive Complexity from 21 to the 15 allowed.(톅8. +L +java:S10666"/Merge this if statement with the enclosing one.(ۃ8. +t +java:S3776-"RRefactor this method to reduce its Cognitive Complexity from 27 to the 15 allowed.(ǡ8. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/4/34a7a54cf20c62973ec28016242f38006ba857e4 b/.idea/sonarlint/issuestore/3/4/34a7a54cf20c62973ec28016242f38006ba857e4 new file mode 100644 index 0000000..1e74ed9 --- /dev/null +++ b/.idea/sonarlint/issuestore/3/4/34a7a54cf20c62973ec28016242f38006ba857e4 @@ -0,0 +1,4 @@ + +f java:S117&"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +o +java:S3012:"YUse "Arrays.copyOf", "Arrays.asList", "Collections.addAll" or "System.arraycopy" instead.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/5/35c8d23cac4fe0fffda07fbc83d36789d7c5c788 b/.idea/sonarlint/issuestore/3/5/35c8d23cac4fe0fffda07fbc83d36789d7c5c788 new file mode 100644 index 0000000..c7594b5 --- /dev/null +++ b/.idea/sonarlint/issuestore/3/5/35c8d23cac4fe0fffda07fbc83d36789d7c5c788 @@ -0,0 +1,2 @@ + +h java:S100"NRename this method name to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(‚ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/6/36d006c838fb7bc186cde26f70feca58e52dd69f b/.idea/sonarlint/issuestore/3/6/36d006c838fb7bc186cde26f70feca58e52dd69f new file mode 100644 index 0000000..3b913c3 --- /dev/null +++ b/.idea/sonarlint/issuestore/3/6/36d006c838fb7bc186cde26f70feca58e52dd69f @@ -0,0 +1,3 @@ + +c +java:S2184 "HCast one of the operands of this multiplication operation to a "double".(Ӻ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/9/39093e1d50a3cf8cc64623725b7f27af72c1ed01 b/.idea/sonarlint/issuestore/3/9/39093e1d50a3cf8cc64623725b7f27af72c1ed01 new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/3/9/39b54d4cb2dd4421ba9524848e0bc63b48c9cf98 b/.idea/sonarlint/issuestore/3/9/39b54d4cb2dd4421ba9524848e0bc63b48c9cf98 new file mode 100644 index 0000000..1d90f9c --- /dev/null +++ b/.idea/sonarlint/issuestore/3/9/39b54d4cb2dd4421ba9524848e0bc63b48c9cf98 @@ -0,0 +1,7 @@ + +N +java:S1197"8Move the array designator from the variable to the type.( +S java:S106"9Replace this use of System.out or System.err by a logger.( +S java:S106"9Replace this use of System.out or System.err by a logger.(Ú +i +java:S1602"SRemove useless curly braces around statement and then remove useless return keyword( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/c/3c68d7b88cda97740385959ea052cf26aaa21dbc b/.idea/sonarlint/issuestore/3/c/3c68d7b88cda97740385959ea052cf26aaa21dbc new file mode 100644 index 0000000..b2e8a5c --- /dev/null +++ b/.idea/sonarlint/issuestore/3/c/3c68d7b88cda97740385959ea052cf26aaa21dbc @@ -0,0 +1,2 @@ + +N java:S106 "9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/e/3eb9ebfd897a1628339b6eeefc615ebb5f41ac1c b/.idea/sonarlint/issuestore/3/e/3eb9ebfd897a1628339b6eeefc615ebb5f41ac1c new file mode 100644 index 0000000..70da440 --- /dev/null +++ b/.idea/sonarlint/issuestore/3/e/3eb9ebfd897a1628339b6eeefc615ebb5f41ac1c @@ -0,0 +1,7 @@ + +N java:S106"9Replace this use of System.out or System.err by a logger.( +S +java:S1197"8Move the array designator from the variable to the type.( +S +java:S1197"8Move the array designator from the variable to the type.( +N java:S106"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/f/3f87dcb80de796da40cadb298a96aa21955be4be b/.idea/sonarlint/issuestore/3/f/3f87dcb80de796da40cadb298a96aa21955be4be new file mode 100644 index 0000000..16e3f58 --- /dev/null +++ b/.idea/sonarlint/issuestore/3/f/3f87dcb80de796da40cadb298a96aa21955be4be @@ -0,0 +1,11 @@ + +k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +t +java:S2234 "YParameters to findKth have the same names but not the same order as the method arguments.( +S +java:S1197 "8Move the array designator from the variable to the type.(ľ +N +java:S1197!"8Move the array designator from the variable to the type.( +S java:S106&"9Replace this use of System.out or System.err by a logger.( +M java:S106("9Replace this use of System.out or System.err by a logger.(! \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/3/438b0c52f32af5295e4f3e7c4dabaec112d6707d b/.idea/sonarlint/issuestore/4/3/438b0c52f32af5295e4f3e7c4dabaec112d6707d new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/4/5/45b148a84d41dd79888ecd53fd4e2834aa693c10 b/.idea/sonarlint/issuestore/4/5/45b148a84d41dd79888ecd53fd4e2834aa693c10 new file mode 100644 index 0000000..29b3651 --- /dev/null +++ b/.idea/sonarlint/issuestore/4/5/45b148a84d41dd79888ecd53fd4e2834aa693c10 @@ -0,0 +1,4 @@ + +s java:S135"YReduce the total number of break and continue statements in this loop to use at most one.(΢ +m +java:S3776"RRefactor this method to reduce its Cognitive Complexity from 20 to the 15 allowed.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/6/46887d7f270c783142b33da323d806a9e2ffe305 b/.idea/sonarlint/issuestore/4/6/46887d7f270c783142b33da323d806a9e2ffe305 new file mode 100644 index 0000000..bde071e --- /dev/null +++ b/.idea/sonarlint/issuestore/4/6/46887d7f270c783142b33da323d806a9e2ffe305 @@ -0,0 +1,6 @@ + +S java:S106-"9Replace this use of System.out or System.err by a logger.( +N +java:S1197"8Move the array designator from the variable to the type.(ӫ +S +java:S1197)"8Move the array designator from the variable to the type.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/7/47597e75e2e16c44eb20b6960bcaa8547172dc4b b/.idea/sonarlint/issuestore/4/7/47597e75e2e16c44eb20b6960bcaa8547172dc4b new file mode 100644 index 0000000..26bcc4a --- /dev/null +++ b/.idea/sonarlint/issuestore/4/7/47597e75e2e16c44eb20b6960bcaa8547172dc4b @@ -0,0 +1,2 @@ + +Z java:S106$"9Replace this use of System.out or System.err by a logger.(8ڐ. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/9/490f534e6bcc2ebe698aeaa1304a9162e622886a b/.idea/sonarlint/issuestore/4/9/490f534e6bcc2ebe698aeaa1304a9162e622886a new file mode 100644 index 0000000..8c35272 --- /dev/null +++ b/.idea/sonarlint/issuestore/4/9/490f534e6bcc2ebe698aeaa1304a9162e622886a @@ -0,0 +1,9 @@ + +f java:S117:"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +k java:S117;"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ׅ +k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +k java:S1178"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +k java:S1179"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(捰 +k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/a/4a822dd10a07fe6c6df04aa6327ec5ea3bda4345 b/.idea/sonarlint/issuestore/4/a/4a822dd10a07fe6c6df04aa6327ec5ea3bda4345 new file mode 100644 index 0000000..cef50c8 --- /dev/null +++ b/.idea/sonarlint/issuestore/4/a/4a822dd10a07fe6c6df04aa6327ec5ea3bda4345 @@ -0,0 +1,5 @@ + +f java:S1174"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(Ҭ +e java:S117 +"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +N java:S106-"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/c/4c3d1d0048a930367d48920dc5922097f63016b2 b/.idea/sonarlint/issuestore/4/c/4c3d1d0048a930367d48920dc5922097f63016b2 new file mode 100644 index 0000000..2338d4c --- /dev/null +++ b/.idea/sonarlint/issuestore/4/c/4c3d1d0048a930367d48920dc5922097f63016b2 @@ -0,0 +1,14 @@ + +> +java:S1659 "#Declare "headY" on a separate line.( +t +java:S2293"YReplace the type specification in this constructor call with the diamond operator ("<>").( +\ +java:S1126?"AReplace this if-then-else statement by a single return statement.( +b +java:S1871J"LThis branch's code block is the same as the block for the branch on line 69.(奞 +: +java:S1659"Declare "n" on a separate line.( +t +java:S2293"YReplace the type specification in this constructor call with the diamond operator ("<>").( +N java:S1064"9Replace this use of System.out or System.err by a logger.(ą \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/c/4cf964bf0393956f630bdbf05a38fffcf83fbc43 b/.idea/sonarlint/issuestore/4/c/4cf964bf0393956f630bdbf05a38fffcf83fbc43 new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/4/d/4d7e0f54d1a7195f31d05b7e8468cbd75d031f6f b/.idea/sonarlint/issuestore/4/d/4d7e0f54d1a7195f31d05b7e8468cbd75d031f6f new file mode 100644 index 0000000..845c8c5 --- /dev/null +++ b/.idea/sonarlint/issuestore/4/d/4d7e0f54d1a7195f31d05b7e8468cbd75d031f6f @@ -0,0 +1,3 @@ + +h +java:S3776"RRefactor this method to reduce its Cognitive Complexity from 26 to the 15 allowed.(ʌ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/e/4e4edace1c90763d39f11d621742b8b7de97c312 b/.idea/sonarlint/issuestore/4/e/4e4edace1c90763d39f11d621742b8b7de97c312 new file mode 100644 index 0000000..a9b7527 --- /dev/null +++ b/.idea/sonarlint/issuestore/4/e/4e4edace1c90763d39f11d621742b8b7de97c312 @@ -0,0 +1,5 @@ + +Y +java:S1596">Replace "Collections.EMPTY_LIST" by "Collections.emptyList()".( +N java:S106/"9Replace this use of System.out or System.err by a logger.( +N java:S1066"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/e/4e7ced7d1c15914d46cab5b6abb4c88c23e2cf57 b/.idea/sonarlint/issuestore/4/e/4e7ced7d1c15914d46cab5b6abb4c88c23e2cf57 new file mode 100644 index 0000000..230de1f --- /dev/null +++ b/.idea/sonarlint/issuestore/4/e/4e7ced7d1c15914d46cab5b6abb4c88c23e2cf57 @@ -0,0 +1,17 @@ + +S java:S106"9Replace this use of System.out or System.err by a logger.(8/ +N +java:S1121".Extract the assignment out of this expression.(Ř8/ +L +java:S1612",Replace this lambda with a method reference.(8/ +r java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.( +I +java:S1121".Extract the assignment out of this expression.(nj8/ +X java:S106"9Replace this use of System.out or System.err by a logger.(8/ +X java:S106"9Replace this use of System.out or System.err by a logger.(8î/ +S java:S106"9Replace this use of System.out or System.err by a logger.(8/ +O +java:S3740"/Provide the parametrized type for this generic.(8/ +X java:S106"9Replace this use of System.out or System.err by a logger.(8/ +S +java:S1128"8Remove this unused import 'java.util.function.Function'.(͞8/ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/e/4eef3ea13ea12692aced2f83a04a1662a284a6cd b/.idea/sonarlint/issuestore/4/e/4eef3ea13ea12692aced2f83a04a1662a284a6cd new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/5/0/50853889753a88543f0b55734fa23f6c154fe0f2 b/.idea/sonarlint/issuestore/5/0/50853889753a88543f0b55734fa23f6c154fe0f2 new file mode 100644 index 0000000..aa4158a --- /dev/null +++ b/.idea/sonarlint/issuestore/5/0/50853889753a88543f0b55734fa23f6c154fe0f2 @@ -0,0 +1,4 @@ + +k +java:S1149 "PReplace the synchronized class "Stack" by an unsynchronized one such as "Deque".(ك +S java:S106"9Replace this use of System.out or System.err by a logger.(ޓ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/5/1/51bd15f852ec96bdc4756c19ba651dbb7c9c1e18 b/.idea/sonarlint/issuestore/5/1/51bd15f852ec96bdc4756c19ba651dbb7c9c1e18 new file mode 100644 index 0000000..7708d85 --- /dev/null +++ b/.idea/sonarlint/issuestore/5/1/51bd15f852ec96bdc4756c19ba651dbb7c9c1e18 @@ -0,0 +1,10 @@ + +S +java:S1197A"8Move the array designator from the variable to the type.( +f java:S117F"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(Ӡ +f java:S117l"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(낔 +8 +java:S1659 ""Declare "down" on a separate line.(Լ +k java:S117k"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +N java:S106v"9Replace this use of System.out or System.err by a logger.(젝 +S java:S106y"9Replace this use of System.out or System.err by a logger.(Ӽ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/5/2/521d253f22544d24e713bbf7b8e8117a32209d21 b/.idea/sonarlint/issuestore/5/2/521d253f22544d24e713bbf7b8e8117a32209d21 new file mode 100644 index 0000000..27db97b --- /dev/null +++ b/.idea/sonarlint/issuestore/5/2/521d253f22544d24e713bbf7b8e8117a32209d21 @@ -0,0 +1,33 @@ + +o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ƌ +< +java:S3010 "!Remove this assignment of "head".( +V java:S125"").( +t +java:S2293"YReplace the type specification in this constructor call with the diamond operator ("<>").( +t +java:S2293"YReplace the type specification in this constructor call with the diamond operator ("<>").( +D +java:S5413$")Verify that "remove()" is used correctly.(瓗 \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/5/8/584b2727291e811934e2ca890624015c5d5bc231 b/.idea/sonarlint/issuestore/5/8/584b2727291e811934e2ca890624015c5d5bc231 new file mode 100644 index 0000000..d4871d2 --- /dev/null +++ b/.idea/sonarlint/issuestore/5/8/584b2727291e811934e2ca890624015c5d5bc231 @@ -0,0 +1,7 @@ + +N +java:S1197"8Move the array designator from the variable to the type.( +m +java:S3776"RRefactor this method to reduce its Cognitive Complexity from 19 to the 15 allowed.(̨ +N java:S106A"9Replace this use of System.out or System.err by a logger.( +k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/5/9/59161909235cdf4eabc4ab47d281db816064e81d b/.idea/sonarlint/issuestore/5/9/59161909235cdf4eabc4ab47d281db816064e81d new file mode 100644 index 0000000..00b09c6 --- /dev/null +++ b/.idea/sonarlint/issuestore/5/9/59161909235cdf4eabc4ab47d281db816064e81d @@ -0,0 +1,3 @@ + +U +java:S1118":Add a private constructor to hide the implicit public one.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/5/9/59318629e72c767456e10c2de3879f3e83d441c5 b/.idea/sonarlint/issuestore/5/9/59318629e72c767456e10c2de3879f3e83d441c5 new file mode 100644 index 0000000..9f3e98c --- /dev/null +++ b/.idea/sonarlint/issuestore/5/9/59318629e72c767456e10c2de3879f3e83d441c5 @@ -0,0 +1,2 @@ + +S java:S106C"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/5/9/59e020674cdac25bf8b1271c924436bc5cd9f43b b/.idea/sonarlint/issuestore/5/9/59e020674cdac25bf8b1271c924436bc5cd9f43b new file mode 100644 index 0000000..57e9ffb --- /dev/null +++ b/.idea/sonarlint/issuestore/5/9/59e020674cdac25bf8b1271c924436bc5cd9f43b @@ -0,0 +1,3 @@ + +S +java:S1155F">Use isEmpty() to check whether the collection is empty or not.(k \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/5/b/5bbbdd7884856e2a6dd46cce750009b2553c147c b/.idea/sonarlint/issuestore/5/b/5bbbdd7884856e2a6dd46cce750009b2553c147c new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/5/c/5c69625eacf591022fd3879dc258f4d735549679 b/.idea/sonarlint/issuestore/5/c/5c69625eacf591022fd3879dc258f4d735549679 new file mode 100644 index 0000000..f96d173 --- /dev/null +++ b/.idea/sonarlint/issuestore/5/c/5c69625eacf591022fd3879dc258f4d735549679 @@ -0,0 +1,7 @@ + +S java:S106L"9Replace this use of System.out or System.err by a logger.(ш +h +java:S3776"RRefactor this method to reduce its Cognitive Complexity from 16 to the 15 allowed.(Ő +\ +java:S11261"AReplace this if-then-else statement by a single return statement.( +S java:S106O"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/5/d/5d67ce154ee6aca6392b698e2208eb223d7df71c b/.idea/sonarlint/issuestore/5/d/5d67ce154ee6aca6392b698e2208eb223d7df71c new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/5/e/5ec9c3ac94b5b6f04be9150f268bc126cce46e9d b/.idea/sonarlint/issuestore/5/e/5ec9c3ac94b5b6f04be9150f268bc126cce46e9d new file mode 100644 index 0000000..ab64dc5 --- /dev/null +++ b/.idea/sonarlint/issuestore/5/e/5ec9c3ac94b5b6f04be9150f268bc126cce46e9d @@ -0,0 +1,18 @@ + +Z java:S106,"9Replace this use of System.out or System.err by a logger.(8. +_ +java:S1854"=Remove this useless assignment to local variable "keywords1".(쫘8ѣ. +D +java:S1481"'Remove this unused "k1" local variable.(8ѣ. +O +java:S1481"-Remove this unused "reviews1" local variable.(񬰖8ѣ. +O +java:S4973*"9Use the "equals" method if value comparison was intended.(Ϝ +S +java:S1854"6Remove this useless assignment to local variable "k1".(8ѣ. +P +java:S1481".Remove this unused "keywords1" local variable.(쫘8ѣ. +S java:S106"9Replace this use of System.out or System.err by a logger.(أ +^ +java:S1854"").( +o +java:S2293""YReplace the type specification in this constructor call with the diamond operator ("<>").( + +java:S1319%"uThe type of the "_neighbors" object should be an interface such as "List" rather than the implementation "ArrayList".( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/8/78d3bfc8f08da07a8446e71a09c808dd472391cd b/.idea/sonarlint/issuestore/7/8/78d3bfc8f08da07a8446e71a09c808dd472391cd new file mode 100644 index 0000000..0fa9d25 --- /dev/null +++ b/.idea/sonarlint/issuestore/7/8/78d3bfc8f08da07a8446e71a09c808dd472391cd @@ -0,0 +1,3 @@ + +N java:S106O"9Replace this use of System.out or System.err by a logger.( +S java:S106M"9Replace this use of System.out or System.err by a logger.(ۡ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/8/78d5cf638c3900a8809f4c08fa05525ffc949d48 b/.idea/sonarlint/issuestore/7/8/78d5cf638c3900a8809f4c08fa05525ffc949d48 new file mode 100644 index 0000000..b9c98a1 --- /dev/null +++ b/.idea/sonarlint/issuestore/7/8/78d5cf638c3900a8809f4c08fa05525ffc949d48 @@ -0,0 +1,2 @@ + +V java:S125""Use isEmpty() to check whether the collection is empty or not.(堧 +S java:S106:"9Replace this use of System.out or System.err by a logger.(Ɲ +[ +java:S1124 +"EReorder the modifiers to comply with the Java Language Specification.( +N java:S106;"9Replace this use of System.out or System.err by a logger.( +S java:S106&"9Replace this use of System.out or System.err by a logger.( +] java:S125"").(֖ +M java:S106("9Replace this use of System.out or System.err by a logger.(s +E +java:S3740"/Provide the parametrized type for this generic.( +E +java:S3740"/Provide the parametrized type for this generic.( +S java:S106P"9Replace this use of System.out or System.err by a logger.( +\ +java:S2142"FEither re-interrupt this method or rethrow the "InterruptedException".(믒 +M java:S106+"9Replace this use of System.out or System.err by a logger.( +E +java:S3740 "/Provide the parametrized type for this generic.(ì +a +java:S2142<"FEither re-interrupt this method or rethrow the "InterruptedException".( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/c/7c412755c7d42401fc40386bc9745de5d37842b7 b/.idea/sonarlint/issuestore/7/c/7c412755c7d42401fc40386bc9745de5d37842b7 new file mode 100644 index 0000000..74a431c --- /dev/null +++ b/.idea/sonarlint/issuestore/7/c/7c412755c7d42401fc40386bc9745de5d37842b7 @@ -0,0 +1,4 @@ + +S java:S1065"9Replace this use of System.out or System.err by a logger.( +J +java:S3740 "/Provide the parametrized type for this generic.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/c/7c8d86a076f2b7efe379ba510fa19b44123fbc48 b/.idea/sonarlint/issuestore/7/c/7c8d86a076f2b7efe379ba510fa19b44123fbc48 new file mode 100644 index 0000000..75ca956 --- /dev/null +++ b/.idea/sonarlint/issuestore/7/c/7c8d86a076f2b7efe379ba510fa19b44123fbc48 @@ -0,0 +1,7 @@ + +N +java:S1197&"8Move the array designator from the variable to the type.( +D +java:S1121".Extract the assignment out of this expression.( +N +java:S1197&"8Move the array designator from the variable to the type.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/c/7cd521c281506d65676d30f1e5e6b10d61014bff b/.idea/sonarlint/issuestore/7/c/7cd521c281506d65676d30f1e5e6b10d61014bff new file mode 100644 index 0000000..fcd93dd --- /dev/null +++ b/.idea/sonarlint/issuestore/7/c/7cd521c281506d65676d30f1e5e6b10d61014bff @@ -0,0 +1,4 @@ + +Z java:S106 "9Replace this use of System.out or System.err by a logger.(ٸ8. +U java:S106 "9Replace this use of System.out or System.err by a logger.(8. +Q java:S125"").( +o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.( +D +java:S5413")Verify that "remove()" is used correctly.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/d/7ddf6872fd6bf4c1e7b1ae0fd344cf87b3d34390 b/.idea/sonarlint/issuestore/7/d/7ddf6872fd6bf4c1e7b1ae0fd344cf87b3d34390 new file mode 100644 index 0000000..3e09320 --- /dev/null +++ b/.idea/sonarlint/issuestore/7/d/7ddf6872fd6bf4c1e7b1ae0fd344cf87b3d34390 @@ -0,0 +1,4 @@ + +k java:S117 "QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +n java:S135("YReduce the total number of break and continue statements in this loop to use at most one.( +k java:S117 "QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/e/7e1eec49595d8bd917ef0502f3368f425e66d53f b/.idea/sonarlint/issuestore/7/e/7e1eec49595d8bd917ef0502f3368f425e66d53f new file mode 100644 index 0000000..73375bc --- /dev/null +++ b/.idea/sonarlint/issuestore/7/e/7e1eec49595d8bd917ef0502f3368f425e66d53f @@ -0,0 +1,3 @@ + +O +java:S2864"4Iterate over the "entrySet" instead of the "keySet".(婅 \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/f/7ff5c5295d63667ae68fd986dbb9d0cba7f89676 b/.idea/sonarlint/issuestore/7/f/7ff5c5295d63667ae68fd986dbb9d0cba7f89676 new file mode 100644 index 0000000..989462e --- /dev/null +++ b/.idea/sonarlint/issuestore/7/f/7ff5c5295d63667ae68fd986dbb9d0cba7f89676 @@ -0,0 +1,35 @@ + +o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ƌ +^ +java:S2259_"HA "NullPointerException" could be thrown; "assignTemp" is nullable here.(Ȕ +M +java:S2589^"7Remove this expression which always evaluates to "true"(ƙ +V java:S125"Remove this unused private "reverseLinkedListPractise" method.(ӑ +K +java:S1144"/Remove this unused private "findCyclic" method.( +G +java:S1144"0Remove this unused private "findNthNode" method.(礊 +E +java:S1144".Remove this unused private "printList" method.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/1/811bf5770f4b9a52cccbb8a2bc44cb9aea7006e1 b/.idea/sonarlint/issuestore/8/1/811bf5770f4b9a52cccbb8a2bc44cb9aea7006e1 new file mode 100644 index 0000000..b7fd246 --- /dev/null +++ b/.idea/sonarlint/issuestore/8/1/811bf5770f4b9a52cccbb8a2bc44cb9aea7006e1 @@ -0,0 +1,3 @@ + +J +java:S10664"/Merge this if statement with the enclosing one.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/1/81f6990775833bc7a1f3dc9cff576c7eeb337b30 b/.idea/sonarlint/issuestore/8/1/81f6990775833bc7a1f3dc9cff576c7eeb337b30 new file mode 100644 index 0000000..4d4b64d --- /dev/null +++ b/.idea/sonarlint/issuestore/8/1/81f6990775833bc7a1f3dc9cff576c7eeb337b30 @@ -0,0 +1,12 @@ + +S +java:S1197 "8Move the array designator from the variable to the type.(Ë +P +java:S1854 +"5Remove this useless assignment to local variable "n".( +S java:S106 "9Replace this use of System.out or System.err by a logger.( +S +java:S1197"8Move the array designator from the variable to the type.( +A +java:S1481 +"&Remove this unused "n" local variable.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/5/854bf6adae0c1b91abeb01f54d55e06f860ae611 b/.idea/sonarlint/issuestore/8/5/854bf6adae0c1b91abeb01f54d55e06f860ae611 new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/8/5/85a40d1fc6955c89664c72f9499d4e9d9ad52d12 b/.idea/sonarlint/issuestore/8/5/85a40d1fc6955c89664c72f9499d4e9d9ad52d12 new file mode 100644 index 0000000..5965ecc --- /dev/null +++ b/.idea/sonarlint/issuestore/8/5/85a40d1fc6955c89664c72f9499d4e9d9ad52d12 @@ -0,0 +1,3 @@ + +W +java:S11266"AReplace this if-then-else statement by a single return statement.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/6/86c65eefc86bd360c961dbfa76a30ee8e639600c b/.idea/sonarlint/issuestore/8/6/86c65eefc86bd360c961dbfa76a30ee8e639600c new file mode 100644 index 0000000..939c5cc --- /dev/null +++ b/.idea/sonarlint/issuestore/8/6/86c65eefc86bd360c961dbfa76a30ee8e639600c @@ -0,0 +1,4 @@ + +N java:S106]"9Replace this use of System.out or System.err by a logger.( +B +java:S1659"'Declare "lastlndex" on a separate line.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/7/8791d113c90b5eaaac31a3f73365f228ccab67a9 b/.idea/sonarlint/issuestore/8/7/8791d113c90b5eaaac31a3f73365f228ccab67a9 new file mode 100644 index 0000000..577336a --- /dev/null +++ b/.idea/sonarlint/issuestore/8/7/8791d113c90b5eaaac31a3f73365f228ccab67a9 @@ -0,0 +1,13 @@ + +P java:S125" +java:S1659"#Declare "right" on a separate line.( +Q +java:S2696'"6Make the enclosing method "static" or remove this set.( +Q +java:S2696K"6Make the enclosing method "static" or remove this set.( +S java:S106P"9Replace this use of System.out or System.err by a logger.(瑛 +S java:S106X"9Replace this use of System.out or System.err by a logger.(瑛 +N java:S106h"9Replace this use of System.out or System.err by a logger.( +S java:S106l"9Replace this use of System.out or System.err by a logger.(ޞҗ +S java:S106m"9Replace this use of System.out or System.err by a logger.(л \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/d/8d00cdd75ea020080139231991fe691f54829a6f b/.idea/sonarlint/issuestore/8/d/8d00cdd75ea020080139231991fe691f54829a6f new file mode 100644 index 0000000..a253c3f --- /dev/null +++ b/.idea/sonarlint/issuestore/8/d/8d00cdd75ea020080139231991fe691f54829a6f @@ -0,0 +1,7 @@ + +Q java:S106"9Replace this use of System.out or System.err by a logger.( +p java:S127"XRefactor the code in order to not assign to this loop counter from within the loop body.(ɉ +d java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +L java:S106"9Replace this use of System.out or System.err by a logger.(ɴ +i java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +i java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/d/8d432008c50bd81945c726fc4fa4011b5f3cdeb8 b/.idea/sonarlint/issuestore/8/d/8d432008c50bd81945c726fc4fa4011b5f3cdeb8 new file mode 100644 index 0000000..6b40d14 --- /dev/null +++ b/.idea/sonarlint/issuestore/8/d/8d432008c50bd81945c726fc4fa4011b5f3cdeb8 @@ -0,0 +1,5 @@ + +N java:S106"9Replace this use of System.out or System.err by a logger.( +N java:S106F"9Replace this use of System.out or System.err by a logger.(ߵ +S java:S106E"9Replace this use of System.out or System.err by a logger.( +S java:S106"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/d/8deb1250efdff63bc54eccf442a5d81017fb5a91 b/.idea/sonarlint/issuestore/8/d/8deb1250efdff63bc54eccf442a5d81017fb5a91 new file mode 100644 index 0000000..e572c77 --- /dev/null +++ b/.idea/sonarlint/issuestore/8/d/8deb1250efdff63bc54eccf442a5d81017fb5a91 @@ -0,0 +1,11 @@ + +f java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +f java:S1175"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +f java:S1175"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +f java:S1175"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +e +java:S11041"OMake val a static final constant or non-public and provide accessors if needed.(Ը +f +java:S11042"PMake next a static final constant or non-public and provide accessors if needed.( +m +java:S11043"RMake random a static final constant or non-public and provide accessors if needed.(ә \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/f/8f0c2c2e40c00e189a33e5a1efefb1f505d93e51 b/.idea/sonarlint/issuestore/8/f/8f0c2c2e40c00e189a33e5a1efefb1f505d93e51 new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/9/0/90fc93692a5f9497dd5e983b820a77af574b4f2d b/.idea/sonarlint/issuestore/9/0/90fc93692a5f9497dd5e983b820a77af574b4f2d new file mode 100644 index 0000000..e4225f7 --- /dev/null +++ b/.idea/sonarlint/issuestore/9/0/90fc93692a5f9497dd5e983b820a77af574b4f2d @@ -0,0 +1,3 @@ + +9 +java:S2119"Save and re-use this "Random".( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/9/3/93d8338afc0b4e089e1907278da7bf042677e038 b/.idea/sonarlint/issuestore/9/3/93d8338afc0b4e089e1907278da7bf042677e038 new file mode 100644 index 0000000..02cee5a --- /dev/null +++ b/.idea/sonarlint/issuestore/9/3/93d8338afc0b4e089e1907278da7bf042677e038 @@ -0,0 +1,6 @@ + +N java:S106<"9Replace this use of System.out or System.err by a logger.( +S java:S106="9Replace this use of System.out or System.err by a logger.( +k java:S117 "QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +N +java:S1197;"8Move the array designator from the variable to the type.(ږ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/9/4/943e4a327d3d604114b9d153e8fbc7f82140e972 b/.idea/sonarlint/issuestore/9/4/943e4a327d3d604114b9d153e8fbc7f82140e972 new file mode 100644 index 0000000..ab8854d --- /dev/null +++ b/.idea/sonarlint/issuestore/9/4/943e4a327d3d604114b9d153e8fbc7f82140e972 @@ -0,0 +1,2 @@ + +S java:S106@"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/9/4/94de9101791f300f5f045f7c1a6c683a04219238 b/.idea/sonarlint/issuestore/9/4/94de9101791f300f5f045f7c1a6c683a04219238 new file mode 100644 index 0000000..8e9625f --- /dev/null +++ b/.idea/sonarlint/issuestore/9/4/94de9101791f300f5f045f7c1a6c683a04219238 @@ -0,0 +1,6 @@ + +f java:S117 "QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ȿ +S java:S106."9Replace this use of System.out or System.err by a logger.( +k java:S117+"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +f java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/9/5/953e63705cfbbd4a09dfad3f29dea40ab5fe7ff2 b/.idea/sonarlint/issuestore/9/5/953e63705cfbbd4a09dfad3f29dea40ab5fe7ff2 new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/9/6/965b9e65f64f5874cdd3e9b20c2a4176b623aa66 b/.idea/sonarlint/issuestore/9/6/965b9e65f64f5874cdd3e9b20c2a4176b623aa66 new file mode 100644 index 0000000..97916d4 --- /dev/null +++ b/.idea/sonarlint/issuestore/9/6/965b9e65f64f5874cdd3e9b20c2a4176b623aa66 @@ -0,0 +1,2 @@ + +U java:S106"9Replace this use of System.out or System.err by a logger.(8. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/9/7/97322aeb00bdf644e441c930ac44ff2638e9c029 b/.idea/sonarlint/issuestore/9/7/97322aeb00bdf644e441c930ac44ff2638e9c029 new file mode 100644 index 0000000..6baa999 --- /dev/null +++ b/.idea/sonarlint/issuestore/9/7/97322aeb00bdf644e441c930ac44ff2638e9c029 @@ -0,0 +1,5 @@ + +U +java:S2184H"@Cast one of the operands of this integer division to a "double".(T +P java:S125"Use isEmpty() to check whether the collection is empty or not.( +7 +java:S1170"!Make this final field static too.(ҳ +l java:S116"WRename this field "FIVE_MINUTES" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ҳ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/b/2/b273fb7280da68b2da19101e0b89eacee9f04988 b/.idea/sonarlint/issuestore/b/2/b273fb7280da68b2da19101e0b89eacee9f04988 new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/b/4/b471983e4f82be2c21f03fda9fac9f82e002ef9a b/.idea/sonarlint/issuestore/b/4/b471983e4f82be2c21f03fda9fac9f82e002ef9a new file mode 100644 index 0000000..066f6a1 --- /dev/null +++ b/.idea/sonarlint/issuestore/b/4/b471983e4f82be2c21f03fda9fac9f82e002ef9a @@ -0,0 +1,2 @@ + +o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ƌ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/b/4/b4e4119d524d7351aebd531ec8cb53a23a1ac1e9 b/.idea/sonarlint/issuestore/b/4/b4e4119d524d7351aebd531ec8cb53a23a1ac1e9 new file mode 100644 index 0000000..8c5eeff --- /dev/null +++ b/.idea/sonarlint/issuestore/b/4/b4e4119d524d7351aebd531ec8cb53a23a1ac1e9 @@ -0,0 +1,18 @@ + +L java:S106"9Replace this use of System.out or System.err by a logger.(ŷ +Q +java:S1197"8Move the array designator from the variable to the type.(ģ +Q +java:S1197"8Move the array designator from the variable to the type.( +Q +java:S1197"8Move the array designator from the variable to the type.(܉ +Q java:S106"9Replace this use of System.out or System.err by a logger.( +L java:S106"9Replace this use of System.out or System.err by a logger.( +L +java:S1197"8Move the array designator from the variable to the type.( +Q java:S106"9Replace this use of System.out or System.err by a logger.(˦ +Q java:S106"9Replace this use of System.out or System.err by a logger.( +o +java:S1192"ODefine a constant instead of duplicating this literal "FINAL RESULT: " 4 times.(˦8. +L +java:S1197"8Move the array designator from the variable to the type.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/b/4/b4f39d67d9de4608cd87e4dcf9289d90e8426afa b/.idea/sonarlint/issuestore/b/4/b4f39d67d9de4608cd87e4dcf9289d90e8426afa new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/b/6/b6c1195fb748ab6c0ca41ce155a65aa4cb71f0de b/.idea/sonarlint/issuestore/b/6/b6c1195fb748ab6c0ca41ce155a65aa4cb71f0de new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/b/9/b941e0faf1b7bf5355e2fb091b588116886b2b1f b/.idea/sonarlint/issuestore/b/9/b941e0faf1b7bf5355e2fb091b588116886b2b1f new file mode 100644 index 0000000..bb4b059 --- /dev/null +++ b/.idea/sonarlint/issuestore/b/9/b941e0faf1b7bf5355e2fb091b588116886b2b1f @@ -0,0 +1,6 @@ + +Z java:S106)"9Replace this use of System.out or System.err by a logger.(8͵. +U java:S1062"9Replace this use of System.out or System.err by a logger.(8´. +Z java:S106,"9Replace this use of System.out or System.err by a logger.(8. +Q +java:S1128"4Remove this unused import 'java.lang.reflect.Array'.(ɘ8. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/b/9/b97ff9eace6e02d384c2a08508f266f49c98e7d7 b/.idea/sonarlint/issuestore/b/9/b97ff9eace6e02d384c2a08508f266f49c98e7d7 new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/b/a/bab1177aae82bae10cefebec36321b50cc9863dd b/.idea/sonarlint/issuestore/b/a/bab1177aae82bae10cefebec36321b50cc9863dd new file mode 100644 index 0000000..2cf73fc --- /dev/null +++ b/.idea/sonarlint/issuestore/b/a/bab1177aae82bae10cefebec36321b50cc9863dd @@ -0,0 +1,2 @@ + +m java:S1171"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(8ǯ. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/b/a/bacb4ca599e79973d65328cae755ba3d19118726 b/.idea/sonarlint/issuestore/b/a/bacb4ca599e79973d65328cae755ba3d19118726 new file mode 100644 index 0000000..137bb92 --- /dev/null +++ b/.idea/sonarlint/issuestore/b/a/bacb4ca599e79973d65328cae755ba3d19118726 @@ -0,0 +1,2 @@ + +N java:S106&"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/b/e/be2572a20f9be978d7a71d1287114fb4ff15b13d b/.idea/sonarlint/issuestore/b/e/be2572a20f9be978d7a71d1287114fb4ff15b13d new file mode 100644 index 0000000..cf09fd2 --- /dev/null +++ b/.idea/sonarlint/issuestore/b/e/be2572a20f9be978d7a71d1287114fb4ff15b13d @@ -0,0 +1,9 @@ + +W +java:S1126:"AReplace this if-then-else statement by a single return statement.( +h +java:S3776"RRefactor this method to reduce its Cognitive Complexity from 22 to the 15 allowed.(߽ +: +java:S1659"Declare "j" on a separate line.( +\ +java:S1118":Add a private constructor to hide the implicit public one.(8辘. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/b/e/be302c9a02a91127c1fdb0d06f31e040af135e0d b/.idea/sonarlint/issuestore/b/e/be302c9a02a91127c1fdb0d06f31e040af135e0d new file mode 100644 index 0000000..040946b --- /dev/null +++ b/.idea/sonarlint/issuestore/b/e/be302c9a02a91127c1fdb0d06f31e040af135e0d @@ -0,0 +1,2 @@ + +N java:S1068"9Replace this use of System.out or System.err by a logger.(۬ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/b/f/bfa96acc23a70c4176888cc734f0ed024d58cd11 b/.idea/sonarlint/issuestore/b/f/bfa96acc23a70c4176888cc734f0ed024d58cd11 new file mode 100644 index 0000000..066f6a1 --- /dev/null +++ b/.idea/sonarlint/issuestore/b/f/bfa96acc23a70c4176888cc734f0ed024d58cd11 @@ -0,0 +1,2 @@ + +o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ƌ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/c/0/c01934cb5fa257e80d4ca5b638e3368911554fa3 b/.idea/sonarlint/issuestore/c/0/c01934cb5fa257e80d4ca5b638e3368911554fa3 new file mode 100644 index 0000000..b0a3f43 --- /dev/null +++ b/.idea/sonarlint/issuestore/c/0/c01934cb5fa257e80d4ca5b638e3368911554fa3 @@ -0,0 +1,5 @@ + +S java:S1067"9Replace this use of System.out or System.err by a logger.( +Z java:S106-"9Replace this use of System.out or System.err by a logger.(8. +6 +java:S1659)" Declare "i2" on a separate line.(ո \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/c/1/c143649f5f79ee59eeaf759d7c59d30a04b1b2e4 b/.idea/sonarlint/issuestore/c/1/c143649f5f79ee59eeaf759d7c59d30a04b1b2e4 new file mode 100644 index 0000000..5761d81 --- /dev/null +++ b/.idea/sonarlint/issuestore/c/1/c143649f5f79ee59eeaf759d7c59d30a04b1b2e4 @@ -0,0 +1,11 @@ + +Z +java:S1197E"8Move the array designator from the variable to the type.(8. +S +java:S1197D"8Move the array designator from the variable to the type.( +r java:S117)"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(8Փ. +] java:S125B"").(ɝ +o +java:S3012Z"YUse "Arrays.copyOf", "Arrays.asList", "Collections.addAll" or "System.arraycopy" instead.( +t +java:S2293"YReplace the type specification in this constructor call with the diamond operator ("<>").(ϒ +o +java:S22935"YReplace the type specification in this constructor call with the diamond operator ("<>").( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/c/5/c5553fd280cb7748f9571fa19a14e95f31ea5799 b/.idea/sonarlint/issuestore/c/5/c5553fd280cb7748f9571fa19a14e95f31ea5799 new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/c/6/c62619dffb64c534668fe6a76e536cebc7988e75 b/.idea/sonarlint/issuestore/c/6/c62619dffb64c534668fe6a76e536cebc7988e75 new file mode 100644 index 0000000..9b5d5cd --- /dev/null +++ b/.idea/sonarlint/issuestore/c/6/c62619dffb64c534668fe6a76e536cebc7988e75 @@ -0,0 +1,16 @@ + +N +java:S1197"8Move the array designator from the variable to the type.( +S +java:S1197+"8Move the array designator from the variable to the type.( +o +java:S3012%"YUse "Arrays.copyOf", "Arrays.asList", "Collections.addAll" or "System.arraycopy" instead.(ڥ +N +java:S1197"8Move the array designator from the variable to the type.( +S +java:S1197"8Move the array designator from the variable to the type.(ٞ +S +java:S1197"8Move the array designator from the variable to the type.(ٞ +N +java:S1197*"8Move the array designator from the variable to the type.( +N java:S106-"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/c/6/c637172121bfc0463017c09b76d3e81352627086 b/.idea/sonarlint/issuestore/c/6/c637172121bfc0463017c09b76d3e81352627086 new file mode 100644 index 0000000..fa684e3 --- /dev/null +++ b/.idea/sonarlint/issuestore/c/6/c637172121bfc0463017c09b76d3e81352627086 @@ -0,0 +1,10 @@ + +L java:S106"9Replace this use of System.out or System.err by a logger.(˓ +L +java:S1197"8Move the array designator from the variable to the type.(Ѱ +Q java:S106"9Replace this use of System.out or System.err by a logger.( +L +java:S1197"8Move the array designator from the variable to the type.( +T java:S125"").(й \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/d/7/d7bd3c45b6dfed3dc0e2b67d0376422d497dd1a4 b/.idea/sonarlint/issuestore/d/7/d7bd3c45b6dfed3dc0e2b67d0376422d497dd1a4 new file mode 100644 index 0000000..e69de29 diff --git a/.idea/sonarlint/issuestore/d/9/d954c0b73e46581c8182dfca8d1e959c07609d11 b/.idea/sonarlint/issuestore/d/9/d954c0b73e46581c8182dfca8d1e959c07609d11 new file mode 100644 index 0000000..c5c09b4 --- /dev/null +++ b/.idea/sonarlint/issuestore/d/9/d954c0b73e46581c8182dfca8d1e959c07609d11 @@ -0,0 +1,2 @@ + +Z java:S1068"9Replace this use of System.out or System.err by a logger.(٨8ˀ. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/d/9/d989b7396837bd36056b8707b4397c3a195f9c12 b/.idea/sonarlint/issuestore/d/9/d989b7396837bd36056b8707b4397c3a195f9c12 new file mode 100644 index 0000000..a717fdc --- /dev/null +++ b/.idea/sonarlint/issuestore/d/9/d989b7396837bd36056b8707b4397c3a195f9c12 @@ -0,0 +1,31 @@ + +G +java:S1444",Make this "public static head_1" field final( +B +java:S1444",Make this "public static head_2" field final(ꮱ +@ +java:S1444"*Make this "public static head" field final( +k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +e java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +k java:S117E"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ƌ +m +java:S1104"RMake head_1 a static final constant or non-public and provide accessors if needed.( +h +java:S1104"RMake head_2 a static final constant or non-public and provide accessors if needed.(ꮱ +f +java:S1104"PMake head a static final constant or non-public and provide accessors if needed.( +M +java:S2589)"7Remove this expression which always evaluates to "true"( +R +java:S2589/"7Remove this expression which always evaluates to "true"(ф +l +java:S3008"QRename this field "head_1" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +g +java:S3008"QRename this field "head_2" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ꮱ +N java:S106"9Replace this use of System.out or System.err by a logger.( +N java:S106G"9Replace this use of System.out or System.err by a logger.( +S java:S106K"9Replace this use of System.out or System.err by a logger.(Ӽ +M java:S106O"9Replace this use of System.out or System.err by a logger.(ɺZ +S java:S106R"9Replace this use of System.out or System.err by a logger.(Ӽ +S java:S106S"9Replace this use of System.out or System.err by a logger.(Ӽ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/d/9/d9932abb4e3590d0146b1c8858c142b360773844 b/.idea/sonarlint/issuestore/d/9/d9932abb4e3590d0146b1c8858c142b360773844 new file mode 100644 index 0000000..eeb105d --- /dev/null +++ b/.idea/sonarlint/issuestore/d/9/d9932abb4e3590d0146b1c8858c142b360773844 @@ -0,0 +1,4 @@ + +r java:S127"XRefactor the code in order to not assign to this loop counter from within the loop body.(쒜 +m java:S127"XRefactor the code in order to not assign to this loop counter from within the loop body.( +V java:S125"").(ׅ +Q java:S125" +java:S1659#"!Declare "end" on a separate line.(8喝. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/f/1/f1260adfa38eb619d43afa7b7901782cdf4af7e1 b/.idea/sonarlint/issuestore/f/1/f1260adfa38eb619d43afa7b7901782cdf4af7e1 new file mode 100644 index 0000000..5e81f94 --- /dev/null +++ b/.idea/sonarlint/issuestore/f/1/f1260adfa38eb619d43afa7b7901782cdf4af7e1 @@ -0,0 +1,20 @@ + +V java:S125" + + + + + \ No newline at end of file diff --git a/Problems.iml b/Problems.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/Problems.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/out/production/Problems/SQL/AlterTableWithMonthName.sql b/out/production/Problems/SQL/AlterTableWithMonthName.sql new file mode 100644 index 0000000..8541ba7 --- /dev/null +++ b/out/production/Problems/SQL/AlterTableWithMonthName.sql @@ -0,0 +1,35 @@ + +--when you give query like this +--SELECT id, +--CASE WHEN month = "Jan" THEN revenue END as "Jan_Revenue", +--CASE WHEN month = "Feb" THEN revenue END AS "Feb_Revenue" +--FROM Department; +--the output will be +--+----+-------------+-------------+ +--| id | Jan_Revenue | Feb_Revenue | +--+----+-------------+-------------+ +--| 1 | NULL | 7000 | +--| 1 | 8000 | NULL | +--| 1 | NULL | NULL | +--| 2 | 9000 | NULL | +--| 3 | NULL | 10000 | +--+----+-------------+-------------+ +--To get one row for each id we need to aggregate by id using GROUP BY. +--But since we have multiple rows with the same id but different values (e.g. for id=1 we have Jan_Revenues: +-- NULL, 8000 and NULL. When we merge these 3 together what value should be chosen? +--This is why we need either SUM (NULL+8000+NULL) or MAX, in both cases 8000 will be used + +SELECT id, +MAX(CASE WHEN month='Jan' then revenue else null end) Jan_Revenue, +MAX(CASE WHEN month='Feb' then revenue else null end) Feb_Revenue, +MAX(CASE WHEN month='Mar' then revenue else null end) Mar_Revenue, +MAX(CASE WHEN month='Apr' then revenue else null end) Apr_Revenue, +MAX(CASE WHEN month='May' then revenue else null end) May_Revenue, +MAX(CASE WHEN month='Jun' then revenue else null end) Jun_Revenue, +MAX(CASE WHEN month='Jul' then revenue else null end) Jul_Revenue, +MAX(CASE WHEN month='Aug' then revenue else null end) Aug_Revenue, +MAX(CASE WHEN month='Sep' then revenue else null end) Sep_Revenue, +MAX(CASE WHEN month='Oct' then revenue else null end) Oct_Revenue, +MAX(CASE WHEN month='Nov' then revenue else null end) Nov_Revenue, +MAX(CASE WHEN month='Dec' then revenue else null end) Dec_Revenue +FROM Department GROUP BY id \ No newline at end of file diff --git a/out/production/Problems/SQL/ClassHavingMoreStudents.sql b/out/production/Problems/SQL/ClassHavingMoreStudents.sql new file mode 100644 index 0000000..86808a4 --- /dev/null +++ b/out/production/Problems/SQL/ClassHavingMoreStudents.sql @@ -0,0 +1,29 @@ +--+---------+------------+ +--| student | class | +--+---------+------------+ +--| A | Math | +--| B | English | +--| C | Math | +--| D | Biology | +--| E | Math | +--| F | Computer | +--| G | Math | +--| H | Math | +--| I | Math | +--+---------+------------+ + +--output: +-- +--+---------+ +--| class | +--+---------+ +--| Math | +--+---------+ + + +SELECT + class +FROM + courses +GROUP BY class +HAVING COUNT(DISTINCT student) >= 5 \ No newline at end of file diff --git a/out/production/Problems/SQL/CustomersNerverOrders.sql b/out/production/Problems/SQL/CustomersNerverOrders.sql new file mode 100644 index 0000000..1bbd733 --- /dev/null +++ b/out/production/Problems/SQL/CustomersNerverOrders.sql @@ -0,0 +1,24 @@ +--Suppose that a website contains two tables, the Customers table and the Orders table. Write a SQL query to find all customers who never order anything. +-- +--Table: Customers. +-- +--+----+-------+ +--| Id | Name | +--+----+-------+ +--| 1 | Joe | +--| 2 | Henry | +--| 3 | Sam | +--| 4 | Max | +--+----+-------+ +--Table: Orders. +-- +--+----+------------+ +--| Id | CustomerId | +--+----+------------+ +--| 1 | 3 | +--| 2 | 1 | +--+----+------------+ + + +select cu.Name as Customers from Customers cu left join Orders od on cu.Id=od.CustomerId +where od.CustomerId is null \ No newline at end of file diff --git a/out/production/Problems/SQL/DeleteDuplicate.sql b/out/production/Problems/SQL/DeleteDuplicate.sql new file mode 100644 index 0000000..06ea0f8 --- /dev/null +++ b/out/production/Problems/SQL/DeleteDuplicate.sql @@ -0,0 +1,5 @@ + + +-- the below command will do cross product and generate all combinations of rows +-- we are selecting a row with same Email and Greater Id +DELETE p1 from Person p1, Person p2 where p1.Email=p2.Email and p1.Id>p2.Id \ No newline at end of file diff --git a/out/production/Problems/SQL/DepartmentHighestSalary.sql b/out/production/Problems/SQL/DepartmentHighestSalary.sql new file mode 100644 index 0000000..2589613 --- /dev/null +++ b/out/production/Problems/SQL/DepartmentHighestSalary.sql @@ -0,0 +1,50 @@ + +--+----+-------+--------+--------------+ +--| Id | Name | Salary | DepartmentId | +--+----+-------+--------+--------------+ +--| 1 | Joe | 70000 | 1 | +--| 2 | Jim | 90000 | 1 | +--| 3 | Henry | 80000 | 2 | +--| 4 | Sam | 60000 | 2 | +--| 5 | Max | 90000 | 1 | +--+----+-------+--------+--------------+ + +--+----+----------+ +--| Id | Name | +--+----+----------+ +--| 1 | IT | +--| 2 | Sales | +--+----+----------+ + +--OUTPUT +--+------------+----------+--------+ +--| Department | Employee | Salary | +--+------------+----------+--------+ +--| IT | Max | 90000 | +--| IT | Jim | 90000 | +--| Sales | Henry | 80000 | +--+------------+----------+--------+ + +--this inner query will give single top salaries for each dept, however if there are multiple people who gets the same salary? we do one more join +-- SELECT d.Id +-- , MAX(d.Name) AS Name +-- , MAX(e.Salary) AS Salary +-- FROM Department d +-- JOIN Employee e +-- ON e.DepartmentId = d.Id +-- GROUP BY d.Id + +SELECT d1.Name as Department + , e1.Name as Employee + , e1.Salary +FROM ( + SELECT d.Id + , MAX(d.Name) AS Name + , MAX(e.Salary) AS Salary + FROM Department d + JOIN Employee e + ON e.DepartmentId = d.Id + GROUP BY d.Id +) d1 +JOIN Employee e1 +ON d1.Id = e1.DepartmentId AND e1.Salary = d1.Salary \ No newline at end of file diff --git a/out/production/Problems/SQL/DuplicateEmail.sql b/out/production/Problems/SQL/DuplicateEmail.sql new file mode 100644 index 0000000..b635a55 --- /dev/null +++ b/out/production/Problems/SQL/DuplicateEmail.sql @@ -0,0 +1,20 @@ +--Write a SQL query to find all duplicate emails in a table named Person. +--+----+---------+ +--| Id | Email | +--+----+---------+ +--| 1 | a@b.com | +--| 2 | c@d.com | +--| 3 | a@b.com | +--+----+---------+ + +select distinct(t1.Email) as Email +from Person t1 +where 1<( + select count(t2.Email) + from Person t2 where t1.Email=t2.Email) + + -- Inner Join concept +select distinct p1.Email +from Person p1 +inner join Person p2 on p1.Email=P2.Email +where p1.Id <> p2.Id \ No newline at end of file diff --git a/out/production/Problems/SQL/EmployeeEarningHigherThanManagers.sql b/out/production/Problems/SQL/EmployeeEarningHigherThanManagers.sql new file mode 100644 index 0000000..f912bae --- /dev/null +++ b/out/production/Problems/SQL/EmployeeEarningHigherThanManagers.sql @@ -0,0 +1,3 @@ + + +select tb1.Name as Employee from Employee tb1 inner join Employee tb2 on tb1.ManagerId=tb2.Id where tb1.Salary>tb2.Salary diff --git a/out/production/Problems/SQL/ExchangeSeats.sql b/out/production/Problems/SQL/ExchangeSeats.sql new file mode 100644 index 0000000..3e425ec --- /dev/null +++ b/out/production/Problems/SQL/ExchangeSeats.sql @@ -0,0 +1,27 @@ +--Mary is a teacher in a middle school and she has a table seat storing students' names and their corresponding seat ids. +-- +--The column id is continuous increment. +-- +--+---------+---------+ +--| id | student | +--+---------+---------+ +--| 1 | Abbot | +--| 2 | Doris | +--| 3 | Emerson | +--| 4 | Green | +--| 5 | Jeames | +--+---------+---------+ + +--For students with odd id, the new id is (id+1) after switch unless it is the last seat. And for students with even id, the new id is (id-1). +--In order to know how many seats in total, we can use a subquery: +--gotcha is when we do id+1 we shouldn't exceed the row number so when id==count we leave as is + +select (case + when MOD(id,2)!=0 && id!=counts then id+1 + when MOD(id,2)!=0 && id=counts then id + else id-1 + end) as id, student + from + seat, + (select count(*) as counts from seat) as seat_counts + order by id asc \ No newline at end of file diff --git a/out/production/Problems/SQL/FirstLoginDate.sql b/out/production/Problems/SQL/FirstLoginDate.sql new file mode 100644 index 0000000..9d78cce --- /dev/null +++ b/out/production/Problems/SQL/FirstLoginDate.sql @@ -0,0 +1,34 @@ + +--Write an SQL query that reports the first login date for each player. +-- +--The query result format is in the following example: +-- +--Activity table: +--+-----------+-----------+------------+--------------+ +--| player_id | device_id | event_date | games_played | +--+-----------+-----------+------------+--------------+ +--| 1 | 2 | 2016-03-01 | 5 | +--| 1 | 2 | 2016-05-02 | 6 | +--| 2 | 3 | 2017-06-25 | 1 | +--| 3 | 1 | 2016-03-02 | 0 | +--| 3 | 4 | 2018-07-03 | 5 | +--+-----------+-----------+------------+--------------+ +-- +--Result table: +--+-----------+-------------+ +--| player_id | first_login | +--+-----------+-------------+ +--| 1 | 2016-03-01 | +--| 2 | 2017-06-25 | +--| 3 | 2016-03-02 | +--+-----------+-------------+ + + +select player_id, min(event_date) as first_login from Activity group by player_id + + +--the following query is to try and get first loggedin deviceId + +SELECT player_id, device_id FROM Activity +WHERE (player_id, event_date) IN +(SELECT player_id, MIN(event_date) first_date FROM Activity GROUP BY player_id) \ No newline at end of file diff --git a/out/production/Problems/SQL/ManagerHaving5OrMoreReport.sql b/out/production/Problems/SQL/ManagerHaving5OrMoreReport.sql new file mode 100644 index 0000000..988a525 --- /dev/null +++ b/out/production/Problems/SQL/ManagerHaving5OrMoreReport.sql @@ -0,0 +1,22 @@ + +--+------+----------+-----------+----------+ +--|Id |Name |Department |ManagerId | +--+------+----------+-----------+----------+ +--|101 |John |A |null | +--|102 |Dan |A |101 | +--|103 |James |A |101 | +--|104 |Amy |A |101 | +--|105 |Anne |A |101 | +--|106 |Ron |B |101 | +--+------+----------+-----------+----------+ +-- +--Given the Employee table, write a SQL query that finds out managers with at least 5 direct report. For the above table, your SQL query should return: +-- +--+-------+ +--| Name | +--+-------+ +--| John | +--+-------+ + + +select (e2.Name) from Employee e1 inner join Employee e2 on e1.ManagerId=e2.Id group by e1.managerid having count(*) >= 5 diff --git a/out/production/Problems/SQL/NthHighestSalary.sql b/out/production/Problems/SQL/NthHighestSalary.sql new file mode 100644 index 0000000..812e4cc --- /dev/null +++ b/out/production/Problems/SQL/NthHighestSalary.sql @@ -0,0 +1,10 @@ +--N is passed as parameter + +CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT +BEGIN +DECLARE M INT; #note variable declaration +SET M=N-1; + RETURN ( + select distinct(salary) from Employee order by Salary desc limit M,1 + ); +END \ No newline at end of file diff --git a/out/production/Problems/SQL/RisingTemperature.sql b/out/production/Problems/SQL/RisingTemperature.sql new file mode 100644 index 0000000..6e0492d --- /dev/null +++ b/out/production/Problems/SQL/RisingTemperature.sql @@ -0,0 +1,23 @@ + +--Given a Weather table, write a SQL query to find all dates' Ids with higher temperature compared to its previous (yesterday's) dates. +-- +--+---------+------------------+------------------+ +--| Id(INT) | RecordDate(DATE) | Temperature(INT) | +--+---------+------------------+------------------+ +--| 1 | 2015-01-01 | 10 | +--| 2 | 2015-01-02 | 25 | +--| 3 | 2015-01-03 | 20 | +--| 4 | 2015-01-04 | 30 | +--+---------+------------------+------------------+ + + +--+----+ +--| Id | +--+----+ +--| 2 | +--| 4 | +--+----+ +SELECT wt1.Id +FROM Weather wt1, Weather wt2 +WHERE wt1.Temperature > wt2.Temperature AND + TO_DAYS(wt1.RecordDate)-TO_DAYS(wt2.RecordDate)=1; \ No newline at end of file diff --git a/out/production/Problems/SQL/SubjectRanks.sql b/out/production/Problems/SQL/SubjectRanks.sql new file mode 100644 index 0000000..bae55fe --- /dev/null +++ b/out/production/Problems/SQL/SubjectRanks.sql @@ -0,0 +1,36 @@ + +--+----+-------+ +--| Id | Score | +--+----+-------+ +--| 1 | 3.50 | +--| 2 | 3.65 | +--| 3 | 4.00 | +--| 4 | 3.85 | +--| 5 | 4.00 | +--| 6 | 3.65 | +--+----+-------+ + +--+-------+---------+ +--| score | Rank | +--+-------+---------+ +--| 4.00 | 1 | +--| 4.00 | 1 | +--| 3.85 | 2 | +--| 3.65 | 3 | +--| 3.65 | 3 | +--| 3.50 | 4 | +--+-------+---------+ + + +SELECT + Score, + (SELECT count(distinct Score) FROM Scores WHERE Score >= s.Score) "Rank" -- inner for-loop +FROM Scores s +ORDER BY Score desc + + +SELECT + Score, + (SELECT count(distinct Score) FROM Scores WHERE Score >= s.Score) "Rank" +FROM Scores s +ORDER BY Score desc \ No newline at end of file diff --git a/out/production/Problems/SQL/TeamSize.sql b/out/production/Problems/SQL/TeamSize.sql new file mode 100644 index 0000000..37cb0c3 --- /dev/null +++ b/out/production/Problems/SQL/TeamSize.sql @@ -0,0 +1,31 @@ +--Employee Table: +--+-------------+------------+ +--| employee_id | team_id | +--+-------------+------------+ +--| 1 | 8 | +--| 2 | 8 | +--| 3 | 8 | +--| 4 | 7 | +--| 5 | 9 | +--| 6 | 9 | +--+-------------+------------+ +--Result table: +--+-------------+------------+ +--| employee_id | team_size | +--+-------------+------------+ +--| 1 | 3 | +--| 2 | 3 | +--| 3 | 3 | +--| 4 | 1 | +--| 5 | 2 | +--| 6 | 2 | +--+-------------+------------+ +--Employees with Id 1,2,3 are part of a team with team_id = 8. so team_size is 3 +--Employees with Id 4 is part of a team with team_id = 7. +--Employees with Id 5,6 are part of a team with team_id = 9. + + +# Write your MySQL query statement below + +select employee_id, (select count(*) from Employee tb2 where tb2.team_id=tb1.team_id) as team_size +from Employee tb1 \ No newline at end of file diff --git a/out/production/Problems/SQL/Top3Salaries.sql b/out/production/Problems/SQL/Top3Salaries.sql new file mode 100644 index 0000000..a5b0a95 --- /dev/null +++ b/out/production/Problems/SQL/Top3Salaries.sql @@ -0,0 +1,19 @@ +--to get to 3 salaries from a table +-- select * from Employee where salary >= {value} this value we need to calculate dynamically (some min value in top 3 salaries) +-- so select min(Salary) from (select distinct(salary) from Employee order by Salary DESC limit 3) this will fetch min of top 3 salaries +-- add this to original query +--+----+-------------+-------------+ +--| id | Name | Salary | +--+----+-------------+-------------+ +--| 1 | A | 7000 | +--| 2 | B | 6000 | +--| 3 | C | 6000 | +--| 4 | D | 6000 | +--| 5 | E | 4000 | +--| 6 | F | 3000 | +--| 7 | G | 3000 | +--| 8 | H | 2000 | +--| 9 | I | 1000 | +--+----+-------------+-------------+ + +select * from Employee where salary >= (select min(Salary) from (select distinct(salary) from Employee order by Salary DESC limit 3)) \ No newline at end of file diff --git a/out/production/Problems/SQL/Top3SalaryDepartmentWise.sql b/out/production/Problems/SQL/Top3SalaryDepartmentWise.sql new file mode 100644 index 0000000..6f59397 --- /dev/null +++ b/out/production/Problems/SQL/Top3SalaryDepartmentWise.sql @@ -0,0 +1,22 @@ +-- +--Now, for each row of the outer query: +--OuterDepartmentId, OuterEmployeeSalary is available to the inner query. +--The inner query will fetch all the salaries that are greater then OuterEmployeeSalary for department matching OuterDepartmentId +--and return a count of such distinct salaries +-- +--This count can be 0,1 or 2 +-- +--if 0 -> that means there are no salaries greater then the OuterDepartmentSalary in that department. Hence, it is the greatest salary for that department. And outer query will include that OuterDepartmentId, OuterEmployeeSalary in the output. +-- +--if 1 -> there is one salary bigger then OuterEmployeeSalary (it is the second largest salary) +-- +--similarly for count 2, there are two larger salaries. + +select d.Name Department, e1.Name Employee, e1.Salary +from Employee e1 +join Department d +on e1.DepartmentId = d.Id +where 3>(select count(distinct(e2.Salary)) + from Employee e2 + where e2.Salary > e1.Salary + and e1.DepartmentId = e2.DepartmentId) -- the inner query will act as inner for loop which get e.salary from outside O(n^2) \ No newline at end of file diff --git a/out/production/Problems/SQL/WinningCandidate.sql b/out/production/Problems/SQL/WinningCandidate.sql new file mode 100644 index 0000000..4313ba7 --- /dev/null +++ b/out/production/Problems/SQL/WinningCandidate.sql @@ -0,0 +1,10 @@ + + +SELECT Name +FROM Candidate c +INNER JOIN (SELECT CandidateId + FROM Vote + GROUP BY CandidateId + ORDER BY COUNT(CandidateId) DESC + LIMIT 0,1) v +ON c.id = v.CandidateId \ No newline at end of file diff --git a/out/production/Problems/java8/Books.txt b/out/production/Problems/java8/Books.txt new file mode 100644 index 0000000..7d652e6 --- /dev/null +++ b/out/production/Problems/java8/Books.txt @@ -0,0 +1,24 @@ +Gulliver's Travels  +Jonathan Swift +Fantasy Fiction +4 +Frankenstein +Mary Shelley +Science Fiction +4 +The Woman in White  +Wilkie Collins +Mystery +4.1 +Alice's Adventures In Wonderland  +Lewis Carroll +Fairy tale +4.1 +Three Men in a Boat  +Jerome K. Jerome +Humorous Fiction +4 +Brave New World  +Aldous Huxley +Science Fiction +4.2 \ No newline at end of file diff --git a/src/CombinationsAndPermutations/Combinations.java b/src/CombinationsAndPermutations/CombinationSum.java similarity index 72% rename from src/CombinationsAndPermutations/Combinations.java rename to src/CombinationsAndPermutations/CombinationSum.java index 6cae079..ed47f5d 100644 --- a/src/CombinationsAndPermutations/Combinations.java +++ b/src/CombinationsAndPermutations/CombinationSum.java @@ -5,7 +5,7 @@ import java.util.Collections; import java.util.List; -public class Combinations { +public class CombinationSum { public List> combinationSum(int[] candidates, int target) { if(candidates==null || candidates.length==0) return Collections.emptyList(); @@ -20,7 +20,7 @@ public List> combinationSum(int[] candidates, int target) { public void combinationSumUtil(int[] candidates, int target, List> result, List tempList, int start ){ if(target<0) return; if(target==0){ - result.add(new ArrayList(tempList)); + result.add(new ArrayList<>(tempList)); } @@ -52,11 +52,20 @@ public void combinationSumUtil1(int[] candidates, int target, List cur means cand[i - 1] is not added to the path (you should know why if you understand the algorithm), so if cand[i] == cand[i-1], then we shouldn't add cand[i]. -// +// when we should skip a number? not just it's the same as previous number, +// but also when it's previous number haven't been added! +// i > cur means cand[i - 1] is not added +// to the path (you should know why if you understand the algorithm), +// so if cand[i] == cand[i-1], then we shouldn't add cand[i]. // This tricky is very smart. + + /** + * i>start && candidates[i]==candidates[i-1] : + * when input is like 1,1,2,4,7,8 and target is 9 + * the first iteration would run for all combinations starts with 1 ([1,1,7], [1,8]) + * the next number i=1 also starts with one which will run again for all combinations + * candidates[i]==candidates[i-1] this will eliminate the duplicate combinations(another [1,8]) + */ if(i>start && candidates[i]==candidates[i-1]) continue; if (target - candidates[i] < 0) break; tempList.add(candidates[i]); diff --git a/src/dynamicProgramming/CatalanNumberBinarySearchTree.java b/src/dynamicProgramming/CatalanNumberBinarySearchTree.java index f4fe053..f8a95aa 100644 --- a/src/dynamicProgramming/CatalanNumberBinarySearchTree.java +++ b/src/dynamicProgramming/CatalanNumberBinarySearchTree.java @@ -1,7 +1,6 @@ package dynamicProgramming; /** - * @author i312458 * * https://www.youtube.com/watch?v=YDf982Lb84o&t=277s */ diff --git a/src/geeksforgeeks/AircraftOptimization.java b/src/geeksforgeeks/AircraftOptimization.java index ef0eb40..0031a92 100644 --- a/src/geeksforgeeks/AircraftOptimization.java +++ b/src/geeksforgeeks/AircraftOptimization.java @@ -1,10 +1,6 @@ package geeksforgeeks; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; +import java.util.*; /** * https://leetcode.com/discuss/interview-question/373202 @@ -27,24 +23,24 @@ public class AircraftOptimization { public List> calculateOptimalRoute(final List> forwardList, final List> returnList, int capacity) { - Collections.sort(forwardList, (o1, o2) -> Integer.compare(o1.get(1), o2.get(1))); - Collections.sort(returnList, (o1, o2) -> Integer.compare(o1.get(1), o2.get(1))); + forwardList.sort(Comparator.comparingInt(o->o.get(1))); + returnList.sort(Comparator.comparingInt(o->o.get(1))); int max = 0; int i = 0; int j = returnList.size() - 1; - List> result = null; + List> result = new LinkedList<>(); while (i < forwardList.size() && j >= 0) { int currentSum = forwardList.get(i).get(1) + returnList.get(j).get(1); if (currentSum > max && currentSum <= capacity) { - max = forwardList.get(i).get(1) + returnList.get(j).get(1); + max = currentSum; // Initializing new list result = new LinkedList<>(); result.add(new ArrayList<>(Arrays.asList(forwardList.get(i).get(0), returnList.get(j).get(0)))); i++; - } else if (forwardList.get(i).get(1) + returnList.get(j).get(1) == max) { + } else if (currentSum == max) { // no need to reset result list result.add(new ArrayList<>(Arrays.asList(forwardList.get(i).get(0), returnList.get(j).get(0)))); i++; @@ -58,15 +54,15 @@ public List> calculateOptimalRoute(final List> forwa public static void main(String[] args) { AircraftOptimization aircraft = new AircraftOptimization(); List> returnList = new ArrayList<>(); - returnList.add(new ArrayList(Arrays.asList(1, 2000))); - returnList.add(new ArrayList(Arrays.asList(2, 3000))); - returnList.add(new ArrayList(Arrays.asList(3, 4000))); - returnList.add(new ArrayList(Arrays.asList(4, 5000))); + returnList.add(new ArrayList<>(Arrays.asList(1, 2000))); + returnList.add(new ArrayList<>(Arrays.asList(2, 3000))); + returnList.add(new ArrayList<>(Arrays.asList(3, 4000))); + returnList.add(new ArrayList<>(Arrays.asList(4, 5000))); List> forwardList = new ArrayList<>(); - forwardList.add(new ArrayList(Arrays.asList(1, 3000))); - forwardList.add(new ArrayList(Arrays.asList(2, 5000))); - forwardList.add(new ArrayList(Arrays.asList(3, 7000))); - forwardList.add(new ArrayList(Arrays.asList(4, 10000))); + forwardList.add(new ArrayList<>(Arrays.asList(1, 3000))); + forwardList.add(new ArrayList<>(Arrays.asList(2, 5000))); + forwardList.add(new ArrayList<>(Arrays.asList(3, 7000))); + forwardList.add(new ArrayList<>(Arrays.asList(4, 10000))); List> calculateOptimalRoute = aircraft.calculateOptimalRoute(forwardList, returnList, 10000); System.out.println(calculateOptimalRoute); } diff --git a/src/geeksforgeeks/AlternateOddAndEvenNumbers.java b/src/geeksforgeeks/AlternateOddAndEvenNumbers.java index 28f12b7..5cbbd3d 100644 --- a/src/geeksforgeeks/AlternateOddAndEvenNumbers.java +++ b/src/geeksforgeeks/AlternateOddAndEvenNumbers.java @@ -1,7 +1,4 @@ package geeksforgeeks; -// A JAVA program to put positive numbers at even indexes -// (0, 2, 4,..) and negative numbers at odd indexes (1, 3, -// 5, ..) import java.util.Arrays; @@ -27,10 +24,12 @@ static void rearrange(int arr[], int n) { i++; } } - // we have seggregated positive and negative elements - System.out.println(Arrays.toString(arr)); + // we have segregated positive and negative elements + System.out.println(Arrays.toString(arr)+" :i - "+i); + // now the 'pos' indicates start of positive integer, 'neg' starts from 0; int pos = i , neg = 0; - // pos indicates start of positive integer, neg starts from 0; + + while (pos < n && neg < pos && arr[neg] < 0) { temp = arr[neg]; @@ -38,19 +37,14 @@ static void rearrange(int arr[], int n) { arr[pos] = temp; pos++; neg += 2; // need to skip next element as output should be alternative + System.out.println(Arrays.toString(arr)); } } - static void printArray(int arr[], int n) { - for (int i = 0; i < n; i++) - System.out.print(arr[i] + " "); - } - public static void main(String[] args) { int arr[] = { -1, 2, -3, 4, 5, 6, -7, 8, 9 }; int n = arr.length; rearrange(arr, n); - System.out.println("Array after rearranging: "); - printArray(arr, n); + System.out.println("Array after rearranging: "+ Arrays.toString(arr)); } } diff --git a/src/geeksforgeeks/AngleOfClock.java b/src/geeksforgeeks/AngleOfClock.java index 874caef..567e2dd 100644 --- a/src/geeksforgeeks/AngleOfClock.java +++ b/src/geeksforgeeks/AngleOfClock.java @@ -2,12 +2,12 @@ public class AngleOfClock { public double angleClock(int hours, int minutes) { - // every hour is 30* (360/12) because 12 hrs in clock - // every min is 6* (360/60) because 60 mins per hr + // every hour is 30(deg) (360 (deg)/12) because 12 hrs in clock + // every min is 6(deg) (360(deg)/60) because 60 mins per hr // we take mod of 12 because 12th hr needs to be 0* - double hour= (double) (hours%12 + (double)minutes/60)*30; - double min= minutes*6; - double absAngle= Math.abs(hour-min); + double hourHand= (hours%12 + (double)minutes/60)*30; + double minHand= minutes*6; + double absAngle= Math.abs(hourHand-minHand); if(absAngle>180) absAngle= 360-absAngle; // this is because when time is 0.02 the angel will be 358 return absAngle; diff --git a/src/geeksforgeeks/ArrangeInQueue.java b/src/geeksforgeeks/ArrangeInQueue.java index ab3a919..1730147 100644 --- a/src/geeksforgeeks/ArrangeInQueue.java +++ b/src/geeksforgeeks/ArrangeInQueue.java @@ -1,14 +1,30 @@ package geeksforgeeks; - -// Input: -// [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] - +import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +//You are given an array of people, people, +// which are the attributes of some people in a queue (not necessarily in order). +// Each people[i] = [hi, ki] represents the ith person of height hi with exactly ki +// other people in front who have a height greater than or equal to hi. +//Reconstruct and return the queue that is represented by the input array people. +// The returned queue should be formatted as an array queue, +// where queue[j] = [hj, kj] is the attributes of the jth person in the +// queue (queue[0] is the person at the front of the queue). + +// Input: +// [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] // Output: // [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]] +//Explanation: +// Person 0 has height 5 with no other people taller or the same height in front. +// Person 1 has height 7 with no other people taller or the same height in front. +// Person 2 has height 5 with two persons taller or the same height in front, which is person 0 and 1. +// Person 3 has height 6 with one person taller or the same height in front, which is person 1. +// Person 4 has height 4 with four people taller or the same height in front, which are people 0, 1, 2, and 3. +// Person 5 has height 7 with one person taller or the same height in front, which is person 1. +// Hence [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] is the reconstructed queue. public class ArrangeInQueue { // 1. Sort people by their height, shortest to tallest @@ -16,16 +32,21 @@ public class ArrangeInQueue { // 2.a When placing the shortest person, all person to his left will be taller or equal height, since you are iterating in height sorted array, so put it at a index equal to its k value // 2.b When placing the next shortest person, find a position, where count of positions to the left unoccupied plus the ones where same height person is placed, is equal to its k value // 2.c Keep repeating - public int[][] reconstructQueue(int[][] people) { + public static int[][] reconstructQueue(int[][] people) { List result= new ArrayList<>(); Arrays.sort(people,(a, b)->{ if(a[0]==b[0]) return a[1]-b[1]; - return b[0]-a[0]; + else return b[0]-a[0]; }); - + System.out.println("Sorted values: "+ Arrays.deepToString(people)); for(int[] x: people){ result.add(x[1],x); + System.out.println(Arrays.deepToString(result.toArray(new int[people.length][2]))); } return result.toArray(new int[people.length][2]); } + + public static void main(String[] args) { + System.out.println(Arrays.deepToString(reconstructQueue(new int[][]{{7,0},{4,4},{7,1},{5,0},{6,1},{5,2}}))); + } } \ No newline at end of file diff --git a/src/geeksforgeeks/AutoCompleteSystem.java b/src/geeksforgeeks/AutoCompleteSystem.java new file mode 100644 index 0000000..bbd6b67 --- /dev/null +++ b/src/geeksforgeeks/AutoCompleteSystem.java @@ -0,0 +1,97 @@ +package geeksforgeeks; + +import java.util.*; + +/** + * https://cheonhyangzhang.gitbooks.io/leetcode-solutions/content/642-design-search-autocomplete-system.html + */ +class AutoCompleteSystem { + + static class TrieNode { + Map children; + Map counts; + boolean isWord; + + public TrieNode() { + children = new HashMap<>(); + counts = new HashMap<>(); + isWord = false; + } + } + + TrieNode root; // points to the root of the trie to be initialised + String prefix; // concat and stores the input char sequence from main function + + public AutoCompleteSystem(String[] sentences, int[] times) { + root = new TrieNode(); + prefix = ""; + // for the given word and freq value we proceed to add it to trie + for (int i = 0; i < sentences.length; i++) { + add(sentences[i], times[i]); + } + } + + private void add(String s, int count) { + TrieNode curr = root; + for (char c : s.toCharArray()) { + curr.children.putIfAbsent(c, new TrieNode()); + curr = curr.children.get(c); + // for every node in the trie(which has one char val) + //the counts map will store the original word along with it's freq value + // for the given input 'i love leetcode' and 'i love you' + // the trie Node(i) => Map(i love leetcode -> 2, i love you->5, island->3, ironman->2) + // / + // Node(' ') => Map(i love leetcode -> 2, i love you->5) + + // the trie Node(i) => Map(i love leetcode -> 2, i love you->5, island->3, ironman->2) + // \ + // Node('s') => Map(island->3) + curr.counts.put(s, curr.counts.getOrDefault(s, 0) + count); + } + curr.isWord = true; + } + + public List input(char c) { + if (c == '#') { + add(prefix, 1); + prefix = ""; + return new ArrayList<>(); + } + prefix = prefix + c; + + TrieNode curr = root; + + for (char ch : prefix.toCharArray()) { + if (!curr.children.containsKey(ch)) { + return new ArrayList<>(); + } + curr = curr.children.get(ch); + } + + Comparator> cmp = (a, b) -> a.getValue().equals(b.getValue()) ? + b.getKey().compareTo(a.getKey()) : + a.getValue() - b.getValue(); + PriorityQueue> pq = new PriorityQueue<>(cmp); + int k = 3; + for (Map.Entry entry : curr.counts.entrySet()) { + pq.offer(entry); + while (!pq.isEmpty() && pq.size() > k) { + pq.poll(); + } + } + + ArrayList res = new ArrayList<>(); + while (!pq.isEmpty()) { + res.add(0, pq.poll().getKey()); + } + return res; + } + + public static void main(String[] args) { + String[] sentences = { "i love you", "island", "ironman", "i love leetcode" }; + int[] times = { 5, 3, 2, 2 }; + AutoCompleteSystem autoCompleteSystem = new AutoCompleteSystem(sentences, times); + System.out.println(autoCompleteSystem.input('i')); + System.out.println(autoCompleteSystem.input(' ')); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/BackspaceCompare.java b/src/geeksforgeeks/BackspaceCompare.java new file mode 100644 index 0000000..e675a90 --- /dev/null +++ b/src/geeksforgeeks/BackspaceCompare.java @@ -0,0 +1,63 @@ +package geeksforgeeks; + +/** + * https://leetcode.com/problems/backspace-string-compare/ + * Given two strings S and T, return if they are equal when both are typed into empty text editors. # means a backspace character. + * + * Note that after backspacing an empty text, the text will continue empty. + * + * Input: S = "ab#c", T = "ad#c" + * Output: true + * Explanation: Both S and T become "ac". + * + * Input: S = "a##c", T = "#a#c" + * Output: true + * Explanation: Both S and T become "c". + */ +class BackspaceCompare { + + public static boolean backspaceCompare(String S, String T) { + + if (S == null || T == null) { + return S == T; + } + int i = S.length() - 1, j = T.length() - 1; + int cnt1 = 0, cnt2 = 0;//number of '#'; + while (i >= 0 || j >= 0) { + //this while loop is executed 2 times i) when it sees '#' it increments the count 'cnt1' + // ii) since 'cnt1'>0 + // the above logic is decrementing the 'i' i.e deleting the char before '#' + + while (i >= 0 && (S.charAt(i) == '#' || cnt1 > 0)) { + if (S.charAt(i) == '#') { + cnt1++; + } else { + cnt1--; + } + i--; + } + + // same as previous comment + while (j >= 0 && (T.charAt(j) == '#' || cnt2 > 0)) { + if (T.charAt(j) == '#') { + cnt2++; + } else { + cnt2--; + } + j--; + } + // if the non '#' char is not equal, then no need to proceed further + if (i >= 0 && j >= 0 && S.charAt(i) == T.charAt(j)) { + i--; + j--; + } else { + return i == -1 && j == -1; + } + } + return true; + } + + public static void main(String[] args) { + System.out.println(backspaceCompare("a##c", "#a#c")); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/BasicCalculator.java b/src/geeksforgeeks/BasicCalculator.java index a4cadac..305eae9 100644 --- a/src/geeksforgeeks/BasicCalculator.java +++ b/src/geeksforgeeks/BasicCalculator.java @@ -7,17 +7,22 @@ // Output: 23 public class BasicCalculator { - public int calculate(String s) { - if(s==null || s.length()==0) return -1; - Deque deque= new ArrayDeque<>(); - int sign=1; - int number=0; - int result=0; + public static void main(String[] args) { + System.out.println(calculate("-26-(5-6)")); + System.out.println(calculate("(1+(4+5+2)-3)+(6+8)")); + } + + public static int calculate(String s) { + if (s == null || s.length() == 0) return -1; + Deque deque = new ArrayDeque<>(); + int sign = 1; + int number = 0; + int result = 0; // let's take an edge case 2-(5-6)=3; // at i=0 number=2 // i=1 char ='-' update with prev seen sign res=sign*number reset number we are looking for next operand //i=2 char='(' and sign is '-', push prev result and sign and reset result for calclating - // subproblem inside braces + // sub problem inside braces // i=3 update number to 5 // i=4 char ='-' update result as sign*number = 5 reset number and sign =-1 //i=5 update number to 6 @@ -25,35 +30,35 @@ public int calculate(String s) { // then pop, which is last seen sign outside brace=> -1 and pop again to get result outside brace // add all to result; - for(int i=0;i queue = new LinkedList<>(); diff --git a/src/geeksforgeeks/BitonicSearch.java b/src/geeksforgeeks/BitonicSearch.java index ce5e156..362b317 100644 --- a/src/geeksforgeeks/BitonicSearch.java +++ b/src/geeksforgeeks/BitonicSearch.java @@ -3,7 +3,7 @@ /* A Bitonic Sequence is a sequence of numbers which is first strictly increasing then after a point strictly decreasing.*/ public class BitonicSearch { - static int ascendingBinarySearch(int arr[], int low, int high, int key) { + static int ascendingBinarySearch(int[] arr, int low, int high, int key) { while (low <= high) { int mid = low + (high - low) / 2; if (arr[mid] == key) { @@ -18,7 +18,7 @@ static int ascendingBinarySearch(int arr[], int low, int high, int key) { return -1; } - static int descendingBinarySearch(int arr[], int low, int high, int key) { + static int descendingBinarySearch(int[] arr, int low, int high, int key) { while (low <= high) { int mid = low + (high - low) / 2; if (arr[mid] == key) { @@ -33,7 +33,7 @@ static int descendingBinarySearch(int arr[], int low, int high, int key) { return -1; } - // instead of writing two methods, we can write a method which contains order aganostic + // instead of writing two methods, we can write a method which contains order agnostic // binary search, which compares the first and last element at first and inside while // if ascending add below // if (arr[mid] > key) { @@ -83,7 +83,7 @@ static int searchBitonic(int arr[], int n, int key, int index) { } public static void main(String args[]) { - int arr[] = { -3, 3, 9, 8, 20, 17, 5, 3, 1 }; + int[] arr = { -3, 3, 9, 8, 20, 17, 5, 3, 1 }; int key = 3; int n = arr.length; int l = 0; diff --git a/src/geeksforgeeks/BoatsToSave.java b/src/geeksforgeeks/BoatsToSave.java index b21a535..85e5588 100644 --- a/src/geeksforgeeks/BoatsToSave.java +++ b/src/geeksforgeeks/BoatsToSave.java @@ -2,6 +2,14 @@ import java.util.Arrays; +/** + * The i-th person has weight people[i], + * and each boat can carry a maximum weight of limit. + * Each boat carries at most 2 people at the same time, + * provided the sum of the weight of those people is at most limit. + * Return the minimum number of boats to carry every given person. + * (It is guaranteed each person can be carried by a boat.) + */ class BoatsToSave { public int numRescueBoats(int[] people, int limit) { if(people.length==0 || limit==0) return 0; diff --git a/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java b/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java index 73f45ba..35be29f 100644 --- a/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java +++ b/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java @@ -16,7 +16,7 @@ public static void main(String args[]) { * i to n, we can break it in to i to k, k+1 to n * in this manner at each point we can calculate profit from * (left min element to current element) and (current element to right max element) - * the second part of the above eq can be acieved by coming from right to left + * the second part of the above eq can be achieved by coming from right to left * for input [3,3,5,0,0,3,1,4] * profit from l->r [0,0,2,2,2,3,3,4] * profit from r->l [4,4,4,4,4,3,3,0] diff --git a/src/geeksforgeeks/Candy.java b/src/geeksforgeeks/Candy.java index 8405771..9d449bc 100644 --- a/src/geeksforgeeks/Candy.java +++ b/src/geeksforgeeks/Candy.java @@ -4,13 +4,13 @@ /** * https://www.hackerrank.com/challenges/candies/problem - * Alice wants to give at least 1 candy to each child. + * Alice wants to give at least 1 candy to each child. * If two children sit next to each other, then * the one with the higher rating must get more candies than neighbour (left and right). - * Alice wants to minimize the total number of candies she must buy. + * Alice wants to minimize the total number of candies she must buy. -For example, assume her students' ratings are [4, 6, 4, 5, 6, 2]. -She gives the students candy in the following minimal amounts: [1, 2, 1, 2, 3, 1]. She must buy a minimum of 10 candies. + For example, assume her students' ratings are [4, 6, 4, 5, 6, 2]. + She gives the students candy in the following minimal amounts: [1, 2, 1, 2, 3, 1]. She must buy a minimum of 10 candies. */ class Candy { diff --git a/src/geeksforgeeks/CheckPermutationContains.java b/src/geeksforgeeks/CheckPermutationContains.java deleted file mode 100644 index 84699aa..0000000 --- a/src/geeksforgeeks/CheckPermutationContains.java +++ /dev/null @@ -1,42 +0,0 @@ -package geeksforgeeks; - -/** - * Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. - * In other words, one of the first string's permutations is the substring of the second string. - * Input:s1= "ab" s2 = "eidboaoo" - Output: False - */ -public class CheckPermutationContains { - - // How do we know string p is a permutation of string s? Easy, each character in p is in s too. - // So we can abstract all permutation strings of s to a map (Character -> Count). i.e. abba -> {a:2, b:2}. - // Since there are only 26 lower case letters in this problem, we can just use an array to represent the map. - // How do we know string s2 contains a permutation of s1? We just need to create a sliding window with length of s1, move from beginning to the end of s2. - // When a character moves in from right of the window, we subtract 1 to that character count from the map. - // When a character moves out from left of the window, we add 1 to that character count. - // So once we see all zeros in the map, meaning equal numbers of every characters between s1 and the substring in the sliding window, we know the answer is true. - public boolean checkInclusion(String s1, String s2) { - if(s1.length()==0 || s2.length()==0) return false; - int[] cache= new int[26]; - for(char s: s1.toCharArray()){ - cache[s-'a']++; - } - - int right=0; - - while(right=s1.length()) cache[s2.charAt(right-s1.length())-'a']++; - if(allZero(cache)) return true; - right++; - } - return false; - } - - public boolean allZero(int[] cache){ - for(int i=0;i<26;i++){ - if(cache[i]>0) return false; - } - return true; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/CloneGraph.java b/src/geeksforgeeks/CloneGraph.java index 5fc9f01..566c4c0 100644 --- a/src/geeksforgeeks/CloneGraph.java +++ b/src/geeksforgeeks/CloneGraph.java @@ -2,30 +2,25 @@ import java.util.*; -/* -// Definition for a Node. -class Node { - public int val; - public List neighbors; - - public Node() { - val = 0; - neighbors = new ArrayList(); - } - - public Node(int _val) { - val = _val; - neighbors = new ArrayList(); - } - - public Node(int _val, ArrayList _neighbors) { - val = _val; - neighbors = _neighbors; - } -} -*/ +/** + * Given a reference of a node in a connected undirected graph. + * + * Return a deep copy (clone) of the graph. + * + * Each node in the graph contains a val (int) and a list (List[Node]) of its neighbors + * + * For simplicity sake, each node's value is the same as the node's index (1-indexed). + * For example, the first node with val = 1, the second node with val = 2, and so on. + * The graph is represented in the test case using an adjacency list. + * + * Adjacency list is a collection of unordered lists used to represent a finite graph. + * Each list describes the set of neighbors of a node in the graph. + * + * The given node will always be the first node with val = 1. + * You must return the copy of the given node as a reference to the cloned graph. + */ public class CloneGraph { - private class Node { + private static class Node { public int val; public List neighbors; @@ -51,7 +46,7 @@ public Node cloneGraph(Node node) { Queue queue= new ArrayDeque<>(); queue.offer(node); - map.put(node,new Node(node.val)); + map.put(node, new Node(node.val)); while(!queue.isEmpty()){ Node current= queue.poll(); @@ -62,7 +57,7 @@ public Node cloneGraph(Node node) { map.put(neighbors,neighborClone); queue.offer(neighbors); } - + map.get(current).neighbors.add(map.get(neighbors)); } } diff --git a/src/geeksforgeeks/CombinationIterator.java b/src/geeksforgeeks/CombinationIterator.java index ef3238f..b885767 100644 --- a/src/geeksforgeeks/CombinationIterator.java +++ b/src/geeksforgeeks/CombinationIterator.java @@ -17,7 +17,7 @@ public class CombinationIterator { public CombinationIterator(String characters, int combinationLength) { deque= new ArrayDeque<>(); visited= new boolean[characters.length()]; - generateCombinations(characters,deque, new StringBuilder(), combinationLength, 0, visited); + generateCombinations(characters,deque, new StringBuilder(), combinationLength, 0); } public String next() { @@ -30,18 +30,24 @@ public boolean hasNext() { return !deque.isEmpty(); } - public void generateCombinations(String characters, Deque deque,StringBuilder sb, int limit, int start, boolean[] visited){ + public void generateCombinations(String characters, Deque deque,StringBuilder sb, int limit, int start){ if(sb.length()==limit){ - deque.offer(new String(sb.toString())); + deque.offer(sb.toString()); return; } for(int i=start; i node.val. + * Also recall that a preorder traversal displays the value of the node first, + * then traverses node.left, then traverses node.right.) */ -class ConstructBSTFromPreorder { +public class ConstructBSTFromPreorder { public static void main(String[] args) { int[] arr = { 8, 3, 1, 6, 4, 7, 10, 14, 13 }; diff --git a/src/geeksforgeeks/ConstructTreeFromInorderAndPostorder.java b/src/geeksforgeeks/ConstructTreeFromInorderAndPostorder.java index 3c97db2..be1439f 100644 --- a/src/geeksforgeeks/ConstructTreeFromInorderAndPostorder.java +++ b/src/geeksforgeeks/ConstructTreeFromInorderAndPostorder.java @@ -4,7 +4,7 @@ import java.util.Map; public class ConstructTreeFromInorderAndPostorder { - // idea is same as iorder preorder, but we take postOrder[lastIndex] as root; + // idea is same as inorder-preorder, but we take postOrder[lastIndex] as root; public TreeNode buildTree(int[] inorder, int[] postorder) { if(inorder==null || postorder==null) return null; Map map= new HashMap(); diff --git a/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java b/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java index c3a46ce..a8008ab 100644 --- a/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java +++ b/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java @@ -16,7 +16,7 @@ class ConstructTreeFromInorderAndPreorder { // Then we can find this PRE[0] in IN, say it's IN[5]. // Now we know that IN[5] is root, so we know that IN[0] - IN[4] is on the left // side, IN[6] to the end is on the right side. - // Recursively doing this on subarrays, we can build a tree out of it :) + // Recursively doing this on sub arrays, we can build a tree out of it :) public TreeNode buildTree(int[] preorder, int[] inorder) { Map map = new HashMap<>(); List set = new LinkedList<>(); @@ -38,10 +38,10 @@ public TreeNode buildTreeUtil(Map map, List set, int return null; if (set.isEmpty()) return null; - int rootval = set.get(0); + int rootVal = set.get(0); set.remove(0); - TreeNode root = new TreeNode(rootval); - int inorderIndex = map.get(rootval); + TreeNode root = new TreeNode(rootVal); + int inorderIndex = map.get(rootVal); root.left = buildTreeUtil(map, set, start, inorderIndex - 1); root.right = buildTreeUtil(map, set, inorderIndex + 1, end); return root; diff --git a/src/geeksforgeeks/CountAndSay.java b/src/geeksforgeeks/CountAndSay.java index b420233..6b1edf9 100644 --- a/src/geeksforgeeks/CountAndSay.java +++ b/src/geeksforgeeks/CountAndSay.java @@ -28,7 +28,7 @@ private String build(String result) { p++; count++; } - builder.append(String.valueOf(count)); + builder.append(count); builder.append(val); } return builder.toString(); diff --git a/src/geeksforgeeks/CountElements.java b/src/geeksforgeeks/CountElements.java new file mode 100644 index 0000000..44e98af --- /dev/null +++ b/src/geeksforgeeks/CountElements.java @@ -0,0 +1,59 @@ +package geeksforgeeks; + +import java.util.HashMap; + +/** + * Given an integer array arr, count element x such that x + 1 is also in arr. + *

+ * If there're duplicates in arr, count them separetely. + *

+ *

+ *

+ * Example 1: + *

+ * Input: arr = [1,2,3] + * Output: 2 + * Explanation: 1 and 2 are counted cause 2 and 3 are in arr. + * Example 2: + *

+ * Input: arr = [1,1,3,3,5,5,7,7] + * Output: 0 + * Explanation: No numbers are counted, cause there's no 2, 4, 6, or 8 in arr. + * Example 3: + *

+ * Input: arr = [1,3,2,3,5,0] + * Output: 3 + * Explanation: 0, 1 and 2 are counted cause 1, 2 and 3 are in arr. + * Example 4: + *

+ * Input: arr = [1,1,2,2] + * Output: 2 + * Explanation: Two 1s are counted cause 2 is in arr. + */ +public class CountElements { + + public static int countElements(int[] arr) { + if (arr == null || arr.length == 0) { + return 0; + } + + HashMap freqMap = new HashMap<>(); + + for (int in : arr) { + freqMap.put(in, freqMap.getOrDefault(in, 0) + 1); + } + + int count = 0; + for (int i = 0; i < arr.length; i++) { + if (freqMap.containsKey(arr[i] - 1)) { + count = count + freqMap.get(arr[i] - 1); + freqMap.put(arr[i] - 1, 0); + } + } + return count; + } + + public static void main(String[] args) { + System.out.println(countElements(new int[]{1, 3, 2, 3, 5, 0})); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/DecodeString.java b/src/geeksforgeeks/DecodeString.java index 4340ebd..7539c8b 100644 --- a/src/geeksforgeeks/DecodeString.java +++ b/src/geeksforgeeks/DecodeString.java @@ -6,7 +6,7 @@ // s = "3[a2[c]]", return "accaccacc". // s = "2[abc]3[cd]ef", return "abcabccdcdcdef". public class DecodeString { - public String decodeString(String s) { + public static String decodeString(String s) { if (s == null) return ""; @@ -33,9 +33,7 @@ public String decodeString(String s) { // and replicate that string and stores in temp result StringBuilder sb = new StringBuilder(result.pop()); int tempCount = count.pop(); - for (int i = 0; i < tempCount; i++) { - sb.append(tempResult); - } + sb.append(tempResult.toString().repeat(tempCount)); tempResult = sb; start++; } else { @@ -46,4 +44,8 @@ public String decodeString(String s) { return tempResult.toString(); } + + public static void main(String[] args) { + System.out.println(decodeString("3[a2[c]]")); + } } \ No newline at end of file diff --git a/src/geeksforgeeks/DesignCompressedStringIterator.java b/src/geeksforgeeks/DesignCompressedStringIterator.java new file mode 100644 index 0000000..617ba19 --- /dev/null +++ b/src/geeksforgeeks/DesignCompressedStringIterator.java @@ -0,0 +1,59 @@ +package geeksforgeeks; + +/** + * https://leetcode.com/articles/desing-compressed-string-iterator/ + * 604. Design Compressed String Iterator + * Design and implement a data structure for a compressed string iterator. The given compressed string will be in the form of each letter followed by a positive integer representing the number of this letter existing in the original uncompressed string. + * Implement the StringIterator class: + * next() Returns the next character if the original string still has uncompressed characters, otherwise returns a white space. + * hasNext() Returns true if there is any letter needs to be uncompressed in the original string, otherwise returns false. + + * Example 1: + + * Input + * ["StringIterator", "next", "next", "next", "next", "next", "next", "hasNext", "next", "hasNext"] + * [["L1e2t1C1o1d1e1"], [], [], [], [], [], [], [], [], []] + * Output + * [null, "L", "e", "e", "t", "C", "o", true, "d", true] + * Explanation + * StringIterator stringIterator = new StringIterator("L1e2t1C1o1d1e1"); + * stringIterator.next(); // return "L" + * stringIterator.next(); // return "e" + * stringIterator.next(); // return "e" + * stringIterator.next(); // return "t" + * stringIterator.next(); // return "C" + * stringIterator.next(); // return "o" + * stringIterator.hasNext(); // return True + * stringIterator.next(); // return "d" + * stringIterator.hasNext(); // return True + */ +public class DesignCompressedStringIterator { + + String res; + + int ptr = 0; + int num = 0; + char ch = ' '; + + public DesignCompressedStringIterator(String s) { + res = s; + } + + public char next() { + if (!hasNext()) { + return ' '; + } + if (num == 0) { + ch = res.charAt(ptr++); + while (ptr < res.length() && Character.isDigit(res.charAt(ptr))) { + num = num * 10 + res.charAt(ptr++) - '0'; + } + } + num--; + return ch; + } + + public boolean hasNext() { + return ptr != res.length() || num != 0; + } +} diff --git a/src/geeksforgeeks/FileSystem1166.java b/src/geeksforgeeks/DesignFileSystem.java similarity index 97% rename from src/geeksforgeeks/FileSystem1166.java rename to src/geeksforgeeks/DesignFileSystem.java index ed1331f..d2f4b8d 100644 --- a/src/geeksforgeeks/FileSystem1166.java +++ b/src/geeksforgeeks/DesignFileSystem.java @@ -23,7 +23,7 @@ * fileSystem.createPath("/c/d", 1); // return false because the parent path "/c" doesn't exist. * fileSystem.get("/c"); // return -1 because this path doesn't exist. */ -public class FileSystem1166 { +public class DesignFileSystem { private HashMap m = new HashMap<>(); @@ -31,7 +31,7 @@ public class FileSystem1166 { * Initialization of class. * Use a hash map to store the path and value. */ - public FileSystem1166() { + public DesignFileSystem() { m.put("", -1); // avoid initially when path is "/a" regarded as false } diff --git a/src/geeksforgeeks/DesignInMemoryFileSystem.java b/src/geeksforgeeks/DesignInMemoryFileSystem.java new file mode 100644 index 0000000..2d85f20 --- /dev/null +++ b/src/geeksforgeeks/DesignInMemoryFileSystem.java @@ -0,0 +1,96 @@ +package geeksforgeeks; +/** + * Design an in-memory file system to simulate the following functions: + *

+ * ls: Given a path in string format. If it is a file path, return a list that only contains this file's name. + * If it is a directory path, return the list of file and directory names in this directory. Your output (file and directory names together) should in lexicographic order. + *

+ * mkdir: Given a directory path that does not exist, you should make a new directory according to the path. + * If the middle directories in the path don't exist either, you should create them as well. This function has void return type. + *

+ * addContentToFile: Given a file path and file content in string format. + * If the file doesn't exist, you need to create that file containing given content. + * If the file already exists, you need to append given content to original content. This function has void return type. + *

+ * readContentFromFile: Given a file path, return its content in string format. + */ + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +public class DesignInMemoryFileSystem { + class Trie { + boolean isFile = false; + HashMap folders = new HashMap<>(); + String content = ""; + } + + Trie root; + + public DesignInMemoryFileSystem() { + root = new Trie(); + } + + public List ls(String path) { + Trie trie = root; + List files = new ArrayList<>(); + if (!path.equals("/")) { + String[] arr = path.split("/"); + for (int i = 1; i < arr.length; i++) { + trie = trie.folders.get(arr[i]); + } + if (trie.isFile) { + files.add(arr[arr.length - 1]); + return files; + } + } + List res_files = new ArrayList<>(trie.folders.keySet()); + Collections.sort(res_files); + return res_files; + } + + public void mkdir(String path) { + Trie trie = root; + String[] arr = path.split("/"); + for (int i = 1; i < arr.length; i++) { + if (!trie.folders.containsKey(arr[i])) { + trie.folders.put(arr[i], new Trie()); + } + trie = trie.folders.get(arr[i]); + } + } + + public void addContentToFile(String filePath, String content) { + Trie trie = root; + String[] arr = filePath.split("/"); + for (int i = 1; i < arr.length - 1; i++) { + trie = trie.folders.get(arr[i]); + } + if (!trie.folders.containsKey(arr[arr.length - 1])) { + trie.folders.put(arr[arr.length - 1], new Trie()); + } + trie = trie.folders.get(arr[arr.length - 1]); + trie.isFile = true; + trie.content = trie.content + content; + } + + public String readContentFromFile(String filePath) { + Trie trie = root; + String[] arr = filePath.split("/"); + for (int i = 1; i < arr.length - 1; i++) { + trie = trie.folders.get(arr[i]); + } + return trie.folders.get(arr[arr.length - 1]).content; + } +} + +/** + * Your FileSystem object will be instantiated and called as such: + * FileSystem obj = new FileSystem(); + * List param_1 = obj.ls(path); + * obj.mkdir(path); + * obj.addContentToFile(filePath,content); + * String param_4 = obj.readContentFromFile(filePath); + */ \ No newline at end of file diff --git a/src/geeksforgeeks/DesignStackIncrement.java b/src/geeksforgeeks/DesignStackIncrement.java new file mode 100644 index 0000000..6ea7ef2 --- /dev/null +++ b/src/geeksforgeeks/DesignStackIncrement.java @@ -0,0 +1,101 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Stack; + +/** + * Design a stack which supports the following operations. + * + * Implement the CustomStack class: + * + * CustomStack(int maxSize) Initializes the object with maxSize which is the maximum number of elements in the stack or do nothing if the stack reached the maxSize. + * void push(int x) Adds x to the top of the stack if the stack hasn't reached the maxSize. + * int pop() Pops and returns the top of stack or -1 if the stack is empty. + * void inc(int k, int val) Increments the bottom k elements of the stack by val. + * If there are less than k elements in the stack, just increment all the elements in the stack. + * + * ["CustomStack","push","push","pop","push","push","push","increment","increment","pop","pop","pop","pop"] + * [[3],[1],[2],[],[2],[3],[4],[5,100],[2,100],[],[],[],[]] + * Output + * [null,null,null,2,null,null,null,null,null,103,202,201,-1] + * Explanation + * CustomStack customStack = new CustomStack(3); // Stack is Empty [] + * customStack.push(1); // stack becomes [1] + * customStack.push(2); // stack becomes [1, 2] + * customStack.pop(); // return 2 --> Return top of the stack 2, stack becomes [1] + * customStack.push(2); // stack becomes [1, 2] + * customStack.push(3); // stack becomes [1, 2, 3] + * customStack.push(4); // stack still [1, 2, 3], Don't add another elements as size is 4 + * customStack.increment(5, 100); // stack becomes [101, 102, 103] + * customStack.increment(2, 100); // stack becomes [201, 202, 103] + * customStack.pop(); // return 103 --> Return top of the stack 103, stack becomes [201, 202] + * customStack.pop(); // return 202 --> Return top of the stack 102, stack becomes [201] + * customStack.pop(); // return 201 --> Return top of the stack 101, stack becomes [] + * customStack.pop(); // return -1 --> Stack is empty return -1. + */ +public class DesignStackIncrement { + + int n; + int[] inc; + Stack stack; + + public DesignStackIncrement(int maxSize) { + n = maxSize; + inc = new int[n]; + stack = new Stack<>(); + } + + public void push(int x) { + if (stack.size() < n) { + stack.push(x); + } + } + + public int pop() { + /* + since array elements go forward(left -> right) and stack goes + top to bottom which translates to array as right->left + so when the increment operation happens for let's say last 4 elements + we set the array pos 4 to 'increment' value. Finally when the pop + is happened we need to set the array's 3rd posistion to the 4th's value inc[i - 1] += inc[i]; + since 3 is yet to be pop-ed from stack + */ + + int i = stack.size() - 1; + if (i < 0) { + return -1; + } + if (i > 0) { + inc[i - 1] += inc[i]; + } + int res = stack.pop() + inc[i]; + inc[i] = 0; + return res; + } + + public void increment(int k, int val) { + int i = Math.min(k, stack.size()) - 1; + if (i >= 0) { + inc[i] += val; + } + } + + public static void main(String[] args) { + DesignStackIncrement customStack = new DesignStackIncrement(4); + customStack.push(1); + customStack.push(2); + customStack.push(3); + customStack.push(4); + customStack.increment(5, 100); + customStack.increment(2, 100); + System.out.println(customStack.pop()); + System.out.println(customStack.pop()); + System.out.println(customStack.pop()); + System.out.println(customStack.pop()); + + List list = new ArrayList<>(Arrays.asList("hello".split(""))); + list.size(); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/EvaluvateExpressions.java b/src/geeksforgeeks/DifferentWaysToAddParenthesis.java similarity index 97% rename from src/geeksforgeeks/EvaluvateExpressions.java rename to src/geeksforgeeks/DifferentWaysToAddParenthesis.java index 0b769ab..0a0dff6 100644 --- a/src/geeksforgeeks/EvaluvateExpressions.java +++ b/src/geeksforgeeks/DifferentWaysToAddParenthesis.java @@ -14,7 +14,7 @@ // ((2*(3-4))*5) = -10 // (2*((3-4)*5)) = -10 // (((2*3)-4)*5) = 10 -public class EvaluvateExpressions { +public class DifferentWaysToAddParenthesis { public List diffWaysToCompute(String input) { if(input==null) return Collections.emptyList(); diff --git a/src/geeksforgeeks/DivideSubArrayAverage.java b/src/geeksforgeeks/DivideSubArrayAverage.java index dfdfa0f..937d628 100644 --- a/src/geeksforgeeks/DivideSubArrayAverage.java +++ b/src/geeksforgeeks/DivideSubArrayAverage.java @@ -2,6 +2,17 @@ /** * https://www.geeksforgeeks.org/divide-array-two-sub-arrays-averages-equal/ + * + * Given an integer array, the task is to divide an integer array into + * two sub-arrays to make their averages equal if possible. + * + * Input : arr[] = {1, 5, 7, 2, 0}; + * Output : (0 1) and (2 4) + * Subarrays arr[0..1] and arr[2..4] have + * same average. + * + * Input : arr[] = {4, 3, 5, 9, 11}; + * Output : Not possible */ class DivideSubArrayAverage { diff --git a/src/geeksforgeeks/DungeonGame.java b/src/geeksforgeeks/DungeonGame.java index 7537453..66b2803 100644 --- a/src/geeksforgeeks/DungeonGame.java +++ b/src/geeksforgeeks/DungeonGame.java @@ -14,7 +14,7 @@ //output 7 // the trick here is to go bottom up, start from the last cell, -// inorder to reach there he should have atleast 6 as health, so that +// inorder to reach there he should have at-least 6 as health, so that // when he reaches -5(energy is consumed) and he's left with +1 health // likewise if we backtrack from end to start, we'll need +7 as min initial health to // play the game diff --git a/src/geeksforgeeks/FileSystem.java b/src/geeksforgeeks/FileSystem.java deleted file mode 100644 index 09691c5..0000000 --- a/src/geeksforgeeks/FileSystem.java +++ /dev/null @@ -1,80 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; - -public class FileSystem { - - class Trie { - boolean isfile = false; - HashMap files = new HashMap<>(); - String content = ""; - } - - Trie root; - - public FileSystem() { - root = new Trie(); - } - - public List ls(String path) { - Trie trie = root; - List files = new ArrayList<>(); - if (!path.equals("/")) { - String[] arr = path.split("/"); - for (int i = 1; i < arr.length; i++) { - trie = trie.files.get(arr[i]); - } - if (trie.isfile) { - files.add(arr[arr.length - 1]); - return files; - } - } - List res_files = new ArrayList<>(trie.files.keySet()); - Collections.sort(res_files); - return res_files; - } - - public void mkdir(String path) { - Trie trie = root; - String[] arr = path.split("/"); - for (int i = 1; i < arr.length; i++) { - if (!trie.files.containsKey(arr[i])) { - trie.files.put(arr[i], new Trie()); - } - trie = trie.files.get(arr[i]); - } - } - - public void addContentToFile(String filePath, String content) { - Trie trie = root; - String[] arr = filePath.split("/"); - for (int i = 1; i < arr.length - 1; i++) { - trie = trie.files.get(arr[i]); - } - if (!trie.files.containsKey(arr[arr.length - 1])) { - trie.files.put(arr[arr.length - 1], new Trie()); - } - trie = trie.files.get(arr[arr.length - 1]); - trie.isfile = true; - trie.content = trie.content + content; - } - - public String readContentFromFile(String filePath) { - Trie trie = root; - String[] arr = filePath.split("/"); - for (int i = 1; i < arr.length - 1; i++) { - trie = trie.files.get(arr[i]); - } - return trie.files.get(arr[arr.length - 1]).content; - } -} - -/** - * Your FileSystem object will be instantiated and called as such: FileSystem - * obj = new FileSystem(); List param_1 = obj.ls(path); obj.mkdir(path); - * obj.addContentToFile(filePath,content); String param_4 = - * obj.readContentFromFile(filePath); - */ \ No newline at end of file diff --git a/src/geeksforgeeks/FileSystemI.java b/src/geeksforgeeks/FileSystemI.java deleted file mode 100644 index 51f3e19..0000000 --- a/src/geeksforgeeks/FileSystemI.java +++ /dev/null @@ -1,96 +0,0 @@ -package geeksforgeeks; -/** - * Design an in-memory file system to simulate the following functions: - * - * ls: Given a path in string format. If it is a file path, return a list that only contains this file's name. - * If it is a directory path, return the list of file and directory names in this directory. Your output (file and directory names together) should in lexicographic order. - * - * mkdir: Given a directory path that does not exist, you should make a new directory according to the path. - * If the middle directories in the path don't exist either, you should create them as well. This function has void return type. - * - * addContentToFile: Given a file path and file content in string format. - * If the file doesn't exist, you need to create that file containing given content. - * If the file already exists, you need to append given content to original content. This function has void return type. - * - * readContentFromFile: Given a file path, return its content in string format. - */ -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; - -public class FileSystemI { - class Dir { - HashMap directory = new HashMap<>(); - HashMap files = new HashMap<>(); - } - - Dir root; - - public FileSystemI() { - root = new Dir(); - } - - - public List ls(String path) { - Dir tempRoot = root; - List files = new ArrayList<>(); - if (!path.equals("/")) { - String[] directoriesList = path.split("/"); - for (int i = 1; i < directoriesList.length - 1; i++) { - tempRoot = tempRoot.directory.get(directoriesList[i]); - } - //If the last level in the input happens to be a file name, we simply need to return the file name. - // So, we directly return the last entry in the array. - if (tempRoot.files.containsKey(directoriesList[directoriesList.length - 1])) { - files.add(directoriesList[directoriesList.length - 1]); - return files; - } else { - tempRoot = tempRoot.directory.get(directoriesList[directoriesList.length - 1]); - } - } - //If the last level entry happens to be a directory, - // we can obtain its subdirectory list from the list of keys in its hashmap. - // Similarly, we can obtain the list of files in the last directory from the keys in the corresponding hashmap. - files.addAll(new ArrayList<>(tempRoot.directory.keySet())); - files.addAll(new ArrayList<>(tempRoot.files.keySet())); - Collections.sort(files); - return files; - } - - public void mkdir(String path) { - Dir t = root; - String[] d = path.split("/"); - for (int i = 1; i < d.length; i++) { - t.directory.putIfAbsent(d[i], new Dir()); - t = t.directory.get(d[i]); - } - } - - public void addContentToFile(String filePath, String content) { - Dir t = root; - String[] d = filePath.split("/"); - for (int i = 1; i < d.length - 1; i++) { - t = t.directory.get(d[i]); - } - t.files.put(d[d.length - 1], t.files.getOrDefault(d[d.length - 1], "") + content); - } - - public String readContentFromFile(String filePath) { - Dir t = root; - String[] d = filePath.split("/"); - for (int i = 1; i < d.length - 1; i++) { - t = t.directory.get(d[i]); - } - return t.files.get(d[d.length - 1]); - } -} - -/** - * Your FileSystem object will be instantiated and called as such: - * FileSystem obj = new FileSystem(); - * List param_1 = obj.ls(path); - * obj.mkdir(path); - * obj.addContentToFile(filePath,content); - * String param_4 = obj.readContentFromFile(filePath); - */ \ No newline at end of file diff --git a/src/geeksforgeeks/FindAllAnagram.java b/src/geeksforgeeks/FindAllAnagram.java new file mode 100644 index 0000000..e71072b --- /dev/null +++ b/src/geeksforgeeks/FindAllAnagram.java @@ -0,0 +1,60 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. + * + * Strings consists of lowercase English letters only and the length of + * both strings s and p will not be larger than 20,100. + * + * The order of output does not matter. + * + * Input: + * s: "cbaebabacd" p: "abc" + * + * Output: + * [0, 6] + * + * Explanation: + * The substring with start index = 0 is "cba", which is an anagram of "abc". + * The substring with start index = 6 is "bac", which is an anagram of "abc". + */ +public class FindAllAnagram { + + public List findAnagrams(String s, String p) { + Map map = new HashMap<>(); + for(char ch: p.toCharArray()){ + map.put(ch, map.getOrDefault(ch,0)+1); + } + int counter= map.size(); + + int start=0; int end=0; + List result= new ArrayList<>(); + while(end0) counter++; + } + if(end-start==p.length()) { + result.add(start); + } + start++; + } + } + + return result; + } +} diff --git a/src/geeksforgeeks/FindSmallestInteger.java b/src/geeksforgeeks/FindSmallestInteger.java index 8c3d88b..eb39c18 100644 --- a/src/geeksforgeeks/FindSmallestInteger.java +++ b/src/geeksforgeeks/FindSmallestInteger.java @@ -1,6 +1,13 @@ package geeksforgeeks; -/*https://www.geeksforgeeks.org/find-smallest-value-represented-sum-subset-given-array/*/ +/** + * https://www.geeksforgeeks.org/find-smallest-value-represented-sum-subset-given-array/ + * Given a sorted array (sorted in non-decreasing order) of positive numbers, + * find the smallest positive integer value + * that cannot be represented as sum of elements of any subset of given set. + * Expected time complexity is O(n). + * + * */ class FindSmallestInteger { int findSmallest(int arr[], int n) { @@ -9,7 +16,7 @@ int findSmallest(int arr[], int n) { // Traverse the array and increment 'result' if arr[i] is // smaller than or equal to 'result'. for (int i = 0; i < n && arr[i] <= result; i++) { - System.out.println("Result :" + result + ":: arr[" + i + "]" + arr[i]); + System.out.println("Result :" + result + ":: arr[" + i + "] " + arr[i]); result = result + arr[i]; } @@ -20,19 +27,19 @@ public static void main(String[] args) { FindSmallestInteger small = new FindSmallestInteger(); int arr1[] = { 1, 3, 4, 5 }; int n1 = arr1.length; - System.out.println(small.findSmallest(arr1, n1)); + System.out.println("FINAL RESULT: "+small.findSmallest(arr1, n1)); int arr2[] = { 1, 2, 6, 10, 11, 15 }; int n2 = arr2.length; - System.out.println(small.findSmallest(arr2, n2)); + System.out.println("FINAL RESULT: "+small.findSmallest(arr2, n2)); int arr3[] = { 1, 1, 1, 1 }; int n3 = arr3.length; - System.out.println(small.findSmallest(arr3, n3)); + System.out.println("FINAL RESULT: "+small.findSmallest(arr3, n3)); int arr4[] = { 1, 1, 3, 4 }; int n4 = arr4.length; - System.out.println(small.findSmallest(arr4, n4)); + System.out.println("FINAL RESULT: "+small.findSmallest(arr4, n4)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/FirstAndLastOccurence.java b/src/geeksforgeeks/FirstAndLastOccurence.java index e07a6c1..93c8207 100644 --- a/src/geeksforgeeks/FirstAndLastOccurence.java +++ b/src/geeksforgeeks/FirstAndLastOccurence.java @@ -1,6 +1,7 @@ package geeksforgeeks; public class FirstAndLastOccurence { + public int[] searchRange(int[] nums, int target) { if(nums.length==0) return new int[]{-1,-1}; int[] result= new int[2]; diff --git a/src/geeksforgeeks/FirstMissingPositive.java b/src/geeksforgeeks/FirstMissingPositive.java index d23015e..77efb0c 100644 --- a/src/geeksforgeeks/FirstMissingPositive.java +++ b/src/geeksforgeeks/FirstMissingPositive.java @@ -8,6 +8,16 @@ /** * https://leetcode.com/problems/first-missing-positive/ + * Given an unsorted integer array nums, find the smallest missing positive integer. + * + * Follow up: Could you implement an algorithm that runs in O(n) time + * and uses constant extra space.? + * + * Input: nums = [1,2,0] + * Output: 3 + * + * Input: nums = [7,8,9,11,12] + * Output: 1 */ public class FirstMissingPositive { @@ -55,7 +65,7 @@ public int firstMissingPositiveWithExtraSpace(int[] nums) { return -1; } - public List findKMissingPossitiveNumberOfSizeK(int[] A, int k){ + public List findKMissingPositiveNumberOfSizeK(int[] A, int k){ int i = 0; while (i < A.length) { // same cyclic sort, as missing numbers diff --git a/src/geeksforgeeks/FirstNonReapeatingCharacterStream.java b/src/geeksforgeeks/FirstNonRepeatingCharacterStream.java similarity index 68% rename from src/geeksforgeeks/FirstNonReapeatingCharacterStream.java rename to src/geeksforgeeks/FirstNonRepeatingCharacterStream.java index a4fbac5..e8ad54d 100644 --- a/src/geeksforgeeks/FirstNonReapeatingCharacterStream.java +++ b/src/geeksforgeeks/FirstNonRepeatingCharacterStream.java @@ -6,18 +6,20 @@ /** * https://www.geeksforgeeks.org/find-first-non-repeating-character-stream-characters/ */ -public class FirstNonReapeatingCharacterStream { +public class FirstNonRepeatingCharacterStream { final static int MAX_CHAR = 256; - // we need to maintain 2 array of size 26 and a doubly linkedlist where the hed element points to the first Non repeat - // 1) 1st array to store the corresponding node to the character position boolean[] visited= new boolean[26]; - // 2nd array is to check if the character occurred 2>= times DLLNode[] node= new DLLNode[26]; - // first condition whenever we see a value, we need to check it in visited array - // if(visited[c-'a']== true) do nothing because already added and deleted from the list(means this is 3rd occurrence of the array) - // else if(node[c-'a']!=null) removeNode(node[c-'a']); visited[c-'a']=true; 2nd occurrence we need to remove from list and set visited value to true - // else create a node and add head if head null or add to tail means we are seeing first time and need to create an entry in list - +/* + we need to maintain 2 array of size 26 and a doubly linkedlist where the hed element points to the first Non repeat + 1st array to store the corresponding node to the character position boolean[] visited= new boolean[26]; + 2nd array is to check if the character occurred 2>= times DLLNode[] node= new DLLNode[26]; + first condition whenever we see a value, we need to check it in visited array + if(visited[c-'a']== true) do nothing because already added and deleted from the list(means this is 3rd occurrence of the array) + else if(node[c-'a']!=null) removeNode(node[c-'a']); visited[c-'a']=true; 2nd occurrence we need to remove from list and set visited value to true + else create a node and add head if head null or add to tail means we are seeing first time and need to create an entry in list +*/ + // this uses arraylist so remove and contains are O(N) static void findFirstNonRepeating() { // inDLL[x] contains pointer to a DLL node if x is present diff --git a/src/geeksforgeeks/Flatten2DVector.java b/src/geeksforgeeks/Flatten2DVector.java index de40a3b..984b9fe 100644 --- a/src/geeksforgeeks/Flatten2DVector.java +++ b/src/geeksforgeeks/Flatten2DVector.java @@ -20,6 +20,11 @@ Use next() to return (x,y) and move it(regardless of correctness, which is deter ] By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,2,3,4,5,6]. + +Understand the problem: +The question itself is very easy to solve. Just several corner cases need to think of: + -- What if the 2d vector contains empty arrays, e.g. [ ], [ ], 1 2 3 ? In this case, the next() should not output anything, but the return type is int. There the hasNext() should be more complicated in which it handles this situation. + -- What if the 2d vector itself is empty? Again, handle it in hasNext() */ public class Flatten2DVector { private int x; @@ -52,7 +57,7 @@ public boolean hasNext() { return false; } // this condition is to check for empty rows - while (x < list.size() && list.get(x).size() == 0) { + while (x < list.size() && list.get(x).isEmpty()) { x++; y = 0; } diff --git a/src/geeksforgeeks/FlattenMultiLevelLinkedList.java b/src/geeksforgeeks/FlattenMultiLevelLinkedList.java index f1db59b..b040ff9 100644 --- a/src/geeksforgeeks/FlattenMultiLevelLinkedList.java +++ b/src/geeksforgeeks/FlattenMultiLevelLinkedList.java @@ -1,6 +1,8 @@ package geeksforgeeks; -/*https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list/discuss/150321/Easy-Understanding-Java-beat-95.7-with-Explanation*/ +/** + * https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list/discuss/150321/Easy-Understanding-Java-beat-95.7-with-Explanation +* */ class FlattenMultiLevelLinkedList { public Node flatten(Node head) { @@ -17,8 +19,9 @@ public Node flatten(Node head) { /* CASE 2: got child, find the tail of the child and link it to p.next */ Node temp = p.child; - while (temp.next != null) + while (temp.next != null) { temp = temp.next; + } // Connect tail with p.next, if it is not null temp.next = p.next; if (p.next != null) { @@ -32,7 +35,7 @@ public Node flatten(Node head) { return head; } - class Node { + static class Node { long data; Node next; Node prev; diff --git a/src/geeksforgeeks/FlipMaximizeZeroesSubarrayKadane.java b/src/geeksforgeeks/FlipMaximizeZeroesSubarrayKadane.java index 115d9b2..c030f69 100644 --- a/src/geeksforgeeks/FlipMaximizeZeroesSubarrayKadane.java +++ b/src/geeksforgeeks/FlipMaximizeZeroesSubarrayKadane.java @@ -2,12 +2,12 @@ /** * https://www.geeksforgeeks.org/maximize-number-0s-flipping-subarray/ - *

+ * * Problem : flip 1's to 0's so that total no.of 0's in array is maximized */ class FlipMaximizeZeroesSubarrayKadane { - public static int findMaxZeroCount(int arr[], int n) { + public static int findMaxZeroCount(int[] arr, int n) { int zeroCount = 0; int maxSoFar = Integer.MIN_VALUE; int sum = 0; @@ -33,7 +33,7 @@ public static int findMaxZeroCount(int arr[], int n) { } public static void main(String[] args) { - int arr[] = { 0, 1, 0, 0, 1, 1, 0 }; + int[] arr = { 0, 1, 0, 0, 1, 1, 0 }; System.out.println(findMaxZeroCount(arr, arr.length)); } diff --git a/src/geeksforgeeks/FlipZeroesToFormConsecutiveMaximumOnes.java b/src/geeksforgeeks/FlipZeroesToFormConsecutiveMaximumOnes.java index 66590b7..ea7cde1 100644 --- a/src/geeksforgeeks/FlipZeroesToFormConsecutiveMaximumOnes.java +++ b/src/geeksforgeeks/FlipZeroesToFormConsecutiveMaximumOnes.java @@ -2,7 +2,7 @@ /** * https://www.geeksforgeeks.org/find-zeroes-to-be-flipped-so-that-number-of-consecutive-1s-is-maximized/ - *

+ * https://www.techiedelight.com/find-maximum-sequence-of-continuous-1s-can-formed-replacing-k-zeroes-ones/ */ class FlipZeroesToFormConsecutiveMaximumOnes { @@ -50,7 +50,7 @@ public static void longestSeq(int[] A, int k) { // main function public static void main(String[] args) { int[] A = { 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0 }; - int k = 1; + int k = 2; longestSeq(A, k); } diff --git a/src/geeksforgeeks/FourSum.java b/src/geeksforgeeks/FourSum.java index 96a925c..3be42b8 100644 --- a/src/geeksforgeeks/FourSum.java +++ b/src/geeksforgeeks/FourSum.java @@ -5,27 +5,50 @@ /** * https://leetcode.com/problems/4sum-ii/ + * Given four lists A, B, C, D of integer values, + * compute how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero. + * To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. + * All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1. + * + * Input: + * A = [ 1, 2] + * B = [-2,-1] + * C = [-1, 2] + * D = [ 0, 2] + * + * Output: + * 2 + * + * Explanation: + * The two tuples are: + * 1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0 + * 2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0 */ public class FourSum { public int fourSumCount(int[] A, int[] B, int[] C, int[] D) { - Map sums = new HashMap<>(); - int count = 0; - for (int i = 0; i < A.length; i++) { - for (int j = 0; j < B.length; j++) { - int sum = A[i] + B[j]; - sums.put(sum, sums.getOrDefault(sum, 0) + 1); + Map sumMap = new HashMap<>(); + for(int i=0; i= 0; pos--) if (bucket[pos] != null) for (char c : bucket[pos]) diff --git a/src/geeksforgeeks/GameOfLife.java b/src/geeksforgeeks/GameOfLife.java index d2b6069..13118e2 100644 --- a/src/geeksforgeeks/GameOfLife.java +++ b/src/geeksforgeeks/GameOfLife.java @@ -4,8 +4,8 @@ * https://forum.letstalkalgorithms.com/t/game-of-life/516/2 *

* https://leetcode.com/problems/game-of-life/ - * Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article): - * + * Given a board with m by n cells, each cell has an initial state live (1) or dead (0). + * Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules * Any live cell with fewer than two live neighbors dies, as if caused by under-population. * Any live cell with two or three live neighbors lives on to the next generation. * Any live cell with more than three live neighbors dies, as if by over-population.. diff --git a/src/geeksforgeeks/GenerateParenthesis.java b/src/geeksforgeeks/GenerateParenthesis.java index 49a11b1..6b25cd0 100644 --- a/src/geeksforgeeks/GenerateParenthesis.java +++ b/src/geeksforgeeks/GenerateParenthesis.java @@ -5,6 +5,9 @@ /** * https://leetcode.com/problems/generate-parentheses/ + * Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. + * Input: n = 3 + * Output: ["((()))","(()())","(())()","()(())","()()()"] */ class GenerateParenthesis { diff --git a/src/geeksforgeeks/GraphBiPartite.java b/src/geeksforgeeks/GraphBiPartite.java index 27da2f5..bd29e8b 100644 --- a/src/geeksforgeeks/GraphBiPartite.java +++ b/src/geeksforgeeks/GraphBiPartite.java @@ -33,7 +33,6 @@ public boolean isBipartite(int[][] graph) { return false; } } - return true; } diff --git a/src/geeksforgeeks/GraphSplitwiseSimplify.java b/src/geeksforgeeks/GraphSplitwiseSimplify.java index 64d9f12..7c7eede 100644 --- a/src/geeksforgeeks/GraphSplitwiseSimplify.java +++ b/src/geeksforgeeks/GraphSplitwiseSimplify.java @@ -23,17 +23,17 @@ static class Graph { LinkedList[] adjNodesList; static class AdjNode { - int adjV; + int adjVertices; int debt; - public AdjNode(int adjV, int debt) { - this.adjV = adjV; + public AdjNode(int adjVertices, int debt) { + this.adjVertices = adjVertices; this.debt = debt; } @Override public boolean equals(Object o) { - if (this.adjV == ((AdjNode) o).adjV) { + if (this.adjVertices == ((AdjNode) o).adjVertices) { return true; } else { return false; @@ -41,7 +41,7 @@ public boolean equals(Object o) { } public String toString() { - return adjV + "->" + debt; + return adjVertices + "->" + debt; } } @@ -68,7 +68,7 @@ public void simplifyDebts() { for (int i = 0; i < V; i++) { for (AdjNode adjNode : adjNodesList[i]) { debts[i] -= adjNode.debt; - debts[adjNode.adjV] += adjNode.debt; + debts[adjNode.adjVertices] += adjNode.debt; } } for (int i = 0; i < V; i++) { @@ -107,7 +107,7 @@ public void printDebts() { System.out.println("depts are: "); for (int i = 0; i < V; i++) { for (AdjNode adjNode : adjNodesList[i]) { - System.out.println(i + " owes " + adjNode.adjV + " " + adjNode.debt + " bucks."); + System.out.println(i + " owes " + adjNode.adjVertices + " " + adjNode.debt + " bucks."); } } } diff --git a/src/geeksforgeeks/IsomorphicArray.java b/src/geeksforgeeks/GroupIsomorphicString.java similarity index 93% rename from src/geeksforgeeks/IsomorphicArray.java rename to src/geeksforgeeks/GroupIsomorphicString.java index 8eacfe8..278ee9c 100644 --- a/src/geeksforgeeks/IsomorphicArray.java +++ b/src/geeksforgeeks/GroupIsomorphicString.java @@ -2,7 +2,7 @@ import java.util.*; -public class IsomorphicArray { +public class GroupIsomorphicString { public Collection> groupIsomorphicStrings(List strings) { if (strings == null || strings.isEmpty()) { return Collections.EMPTY_LIST; @@ -49,7 +49,7 @@ private String hash(String s) { } public static void main(String[] args) { - Collection> result = new IsomorphicArray() + Collection> result = new GroupIsomorphicString() .groupIsomorphicStrings(Arrays.asList("apple", "apply", "dog", "cog", "romi")); result.stream().forEach(System.out::println); } diff --git a/src/geeksforgeeks/HappyNumber.java b/src/geeksforgeeks/HappyNumber.java index a8ff875..a251b8a 100644 --- a/src/geeksforgeeks/HappyNumber.java +++ b/src/geeksforgeeks/HappyNumber.java @@ -42,6 +42,7 @@ public boolean isHappyOpt(int n) while ( i2 != i1) { + System.out.println("i1: "+ i1+" i2: "+ i2); i1 = next(i1); i2 = next(next(i2)); } @@ -51,6 +52,6 @@ public boolean isHappyOpt(int n) public static void main(String[] args) { HappyNumber hn = new HappyNumber(); - System.out.println(hn.isHappy(19)); + System.out.println(hn.isHappyOpt(19)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/HitCounter.java b/src/geeksforgeeks/HitCounter.java index ae93af5..a8c7e26 100644 --- a/src/geeksforgeeks/HitCounter.java +++ b/src/geeksforgeeks/HitCounter.java @@ -10,14 +10,18 @@ public HitCounter() { trac = new ArrayDeque(); } - /** Record a hit. - @param timestamp - The current timestamp (in seconds granularity). */ + /** + * Record a hit. + @param timestamp - The current timestamp (in seconds granularity). + */ public void hit(int timestamp) { trac.addLast(timestamp); } - /** Return the number of hits in the past 5 minutes. - @param timestamp - The current timestamp (in seconds granularity). */ + /** + * Return the number of hits in the past 5 minutes. + @param timestamp - The current timestamp (in seconds granularity). + */ public int getHits(int timestamp) { while(trac.size() > 0 && ( int) trac.getFirst() + FIVE_MINUTES <= timestamp) { trac.removeFirst(); diff --git a/src/geeksforgeeks/InOrderSuccessor.java b/src/geeksforgeeks/InOrderSuccessor.java index d71489e..2216ac2 100644 --- a/src/geeksforgeeks/InOrderSuccessor.java +++ b/src/geeksforgeeks/InOrderSuccessor.java @@ -11,7 +11,7 @@ public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { return result; } // Inorder traversal is obtained by going right first and follow the left path till end - // while traversing right we record the right before taking left turn, incase the left path is null + // while traversing right we record the right before taking left turn, in case the left path is null public void helperFn(TreeNode root, TreeNode p){ if(root==null) return; @@ -21,7 +21,6 @@ public void helperFn(TreeNode root, TreeNode p){ result=root; helperFn(root.left,p); }else{ - helperFn(root.right,p); } diff --git a/src/geeksforgeeks/InorderSuccessorPredecessor.java b/src/geeksforgeeks/InorderSuccessorPredecessor.java index 6af6d0e..7e33f3a 100644 --- a/src/geeksforgeeks/InorderSuccessorPredecessor.java +++ b/src/geeksforgeeks/InorderSuccessorPredecessor.java @@ -7,47 +7,8 @@ public class InorderSuccessorPredecessor { static int successor, predecessor; public void successorPredecessor(TNode root, int val) { - // if (root.data == val) { - // // go to the right most element in the left subtree, it will be the - // // predecessor. - // if (root.left != null) { - // TNode t = root.left; - // while (t.right != null) { - // t = t.right; - // } - // predecessor = t.data; - // } - // if (root.right != null) { - // // go to the left most element in the right subtree, it will be - // // the successor. - // TNode t = root.right; - // while (t.left != null) { - // t = t.left; - // } - // successor = t.data; - // } - // } else - if (root != null) { - if (root.data > val) { - // we make the root as successor because we might have a - // situation when value matches with the root, it wont have - // right subtree to find the successor, in that case we need - // parent to be the successor - successor = root.data; - successorPredecessor(root.left, val); - } else if (root.data < val) { - // we make the root as predecessor because we might have a - // situation when value matches with the root, it wont have - // left subtree to find the predecessor, in that case we need - // parent to be the predecessor. - predecessor = root.data; - successorPredecessor(root.right, val); - } - } - } + if (root == null) return; - public void shortSolution(TNode root, int val) { - if (root != null) { if (root.data > val) { // we make the root as successor because we might have a // situation when value matches with the root, it wont have @@ -63,7 +24,6 @@ public void shortSolution(TNode root, int val) { predecessor = root.data; successorPredecessor(root.right, val); } - } } public static void main(String args[]) { @@ -79,12 +39,9 @@ public static void main(String args[]) { root.left.right.right = new TNode(20); InorderSuccessorPredecessor i = new InorderSuccessorPredecessor(); - // i.successorPredecessor(root, 20); -/* TNode tempSuccessor = root.right; - TNode successor = i.findSuccessor(tempSuccessor); - successor = successor==null?tempSuccessor:successor;*/ + i.successorPredecessor(root, 20); - System.out.println("Inorder Successor of 10 is : " + successor + " and predecessor is : " + predecessor); + System.out.println("Inorder Successor of 20 is : " + successor + " and predecessor is : " + predecessor); } @@ -98,11 +55,9 @@ public void helperFn(TreeNode root, TreeNode p){ if(root==null) return; if(root.val>p.val){ - // System.out.println("greatre root"+root.val); result=root; helperFn(root.left,p); }else{ - //System.out.println("smaller root"+root.val); helperFn(root.right,p); } diff --git a/src/geeksforgeeks/InserstionSortList.java b/src/geeksforgeeks/InserstionSortList.java deleted file mode 100644 index 8ed6bf7..0000000 --- a/src/geeksforgeeks/InserstionSortList.java +++ /dev/null @@ -1,29 +0,0 @@ -package geeksforgeeks; - -public class InserstionSortList { - public ListNode insertionSortList(ListNode head) { - ListNode dummy = new ListNode(0); - ListNode prev = dummy; - - // take 1->2->3->4 - while (head != null) { - ListNode temp = head.next; // at first run temp=2, second run temp=3 - - /* Before insert, the prev is at the last node of the sorted list. - Only the last node's value is larger than the current inserting node - should we move the temp back to the head*/ - if (prev.val >= head.val) prev = dummy; - - // during second run prev= 0->1->null - while (prev.next != null && prev.next.val < head.val) { - prev = prev.next; - } // after this loop, at first run prev=0 (0->null), second run prev=1 - - head.next = prev.next; // we set 1->null // second run 2->null - prev.next = head; // 0->1 // 0->1->2 - - head = temp; // head= 2->3->4 // head= 3->4 - } - return dummy.next; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/InsertionSortList.java b/src/geeksforgeeks/InsertionSortList.java new file mode 100644 index 0000000..40d73ed --- /dev/null +++ b/src/geeksforgeeks/InsertionSortList.java @@ -0,0 +1,38 @@ +package geeksforgeeks; + +/** + * Sort a linked list using insertion sort. + * Algorithm of Insertion Sort: + *

+ * Insertion sort iterates, + * consuming one input element each repetition, and growing a sorted output list. + * At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. + * It repeats until no input elements remain. + */ +public class InsertionSortList { + public ListNode insertionSortList(ListNode head) { + if (head == null) { + return head; + } + + ListNode helper = new ListNode(0); //new starter of the sorted list + ListNode cur = head; //the node will be inserted + ListNode pre = helper; //insert node between pre and pre.next + ListNode next; //the next node will be inserted + //not the end of input list + while (cur != null) { + next = cur.next; + //find the right place to insert + while (pre.next != null && pre.next.val < cur.val) { + pre = pre.next; + } + //insert between pre and pre.next + cur.next = pre.next; + pre.next = cur; + pre = helper; + cur = next; + } + + return helper.next; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/IsEditOneDistanceAway.java b/src/geeksforgeeks/IsEditOneDistanceAway.java index ad443e8..d8791f5 100644 --- a/src/geeksforgeeks/IsEditOneDistanceAway.java +++ b/src/geeksforgeeks/IsEditOneDistanceAway.java @@ -1,6 +1,22 @@ package geeksforgeeks; -class IsEditOneDistanceAway { +/** + * Given two strings first and second, determine if they are both one edit distance apart. + * One edit distance means doing one of these operation: + * + * insert one character in any position of S + * delete one character in S + * change one character in S to other character + * + * Input: s = "ab", t = "ab" + * Output: false + * Explanation: + * s=t ,so they aren't one edit distance apart + * + * Input: s = "aDb", t = "adb" + * Output: true + */ +public class IsEditOneDistanceAway { static boolean isOneEdit(String first, String second) { // if the input string are same if (first.equals(second)) @@ -19,10 +35,13 @@ static boolean isOneEdit(String first, String second) { char s = second.charAt(j); if (f != s) { diff++; + // delete a character if (len1 > len2) i++; + // add a character if (len2 > len1) j++; + // replace a character if (len1 == len2) i++; j++; diff --git a/src/geeksforgeeks/JumpsToReachEnd.java b/src/geeksforgeeks/JumpsToReachEnd.java index 7f305c1..82e32d1 100644 --- a/src/geeksforgeeks/JumpsToReachEnd.java +++ b/src/geeksforgeeks/JumpsToReachEnd.java @@ -4,6 +4,21 @@ public class JumpsToReachEnd { + /** + * Given an array of non-negative integers nums, + * you are initially positioned at the first index of the array. + * Each element in the array represents your maximum jump length at that position. + * + * Determine if you are able to reach the last index + * Input: nums = [2,3,1,1,4] + * Output: true + * Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index. + * + * Input: nums = [3,2,1,0,4] + * Output: false + * Explanation: You will always arrive at index 3 no matter what. + * Its maximum jump length is 0, which makes it impossible to reach the last index. + */ public static boolean canReachEnd(List maxAdvanceSteps) { int furthestReachSoFar = 0, lastlndex = maxAdvanceSteps.size() - 1; @@ -18,9 +33,26 @@ public static boolean canReachEnd(List maxAdvanceSteps) { } - // Given an array of non-negative integers arr, you are initially positioned at start index of the array. - // When you are at index i, you can jump to i + arr[i] or i - arr[i], - // check if you can reach to any index with value 0. + /** + *Given an array of non-negative integers arr, + * you are initially positioned at start index of the array. + * When you are at index i, you can jump to i + arr[i] or i - arr[i], + * check if you can reach to any index with value 0. + * Notice that you can not jump outside of the array at any time. + * + * Input: arr = [4,2,3,0,3,1,2], start = 5 + * Output: true + * Explanation: + * All possible ways to reach at index 3 with value 0 are: + * index 5 -> index 4 -> index 1 -> index 3 + * index 5 -> index 6 -> index 4 -> index 1 -> index 3 + * + * Input: arr = [4,2,3,0,3,1,2], start = 0 + * Output: true + * Explanation: + * One possible way to reach at index 3 with value 0 is: + * index 0 -> index 4 -> index 1 -> index 3 + */ public boolean canReach(int[] arr, int start) { // visited check included if(start>=arr.length || start<0 || arr[start]>arr.length || arr[start]<0) return false; @@ -30,6 +62,7 @@ public boolean canReach(int[] arr, int start) { } + public int minJump(int[] nums) { if(nums==null || nums.length==0) return 0; int currentMax=0; @@ -56,7 +89,7 @@ public int minJump(int[] nums) { public static void main(String[] args) { - List list= Arrays.asList(new Integer[]{3,3,1,0, 2,0,1}); + List list= Arrays.asList(3,3,1,0, 2,0,1); System.out.println(canReachEnd(list)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/KmostFrequentLetters.java b/src/geeksforgeeks/KmostFrequentLetters.java index a5d1022..19919bd 100644 --- a/src/geeksforgeeks/KmostFrequentLetters.java +++ b/src/geeksforgeeks/KmostFrequentLetters.java @@ -2,39 +2,47 @@ import java.util.*; +/** + * Given a list of reviews, a list of keywords and an integer k. + * Find the most popular k keywords in order of most to least frequently mentioned. + * The comparison of strings is case-insensitive. + * Multiple occurrences of a keyword in a review should be considered as a single mention. + * If keywords are mentioned an equal number of times in reviews, sort alphabetically. + */ public class KmostFrequentLetters { public static void main(String[] args) { int k1 = 2; - String[] keywords1 = { "anacell", "cetracular", "betacellular" }; - String[] reviews1 = { "Anacell provides the best services in the city", "betacellular has awesome services", - "Best services provided by anacell, everyone should use anacell", }; + String[] keywords1 = {"anacell", "cetracular", "betacellular"}; + String[] reviews1 = {"Anacell provides the best services in the city", "betacellular has awesome services", + "Best services provided by anacell, everyone should use anacell",}; int k2 = 2; - String[] keywords2 = { "anacell", "betacellular", "cetracular", "deltacellular", "eurocell" }; - String[] reviews2 = { "I love anacell Best services; Best services provided by anacell", + String[] keywords2 = {"anacell", "betacellular", "cetracular", "deltacellular", "eurocell"}; + String[] reviews2 = {"I love anacell Best services; Best services provided by anacell", "betacellular has great services", "deltacellular provides much better services than betacellular", - "cetracular is worse than anacell", "Betacellular is better than deltacellular.", }; - System.out.println(solve(k1, keywords1, reviews1)); + "cetracular is worse than anacell", "Betacellular is better than deltacellular.",}; + //System.out.println(solve(k1, keywords1, reviews1)); System.out.println(solve(k2, keywords2, reviews2)); } - + private static List solve(int k, String[] keywords, String[] reviews) { List res = new ArrayList<>(); Set set = new HashSet<>(Arrays.asList(keywords)); Map map = new HashMap<>(); - for(String r : reviews) { + for (String r : reviews) { String[] strs = r.split("\\W"); - Set added = new HashSet<>(); // creating a set per review to vaoid duplicate within a review - for(String s : strs) { + Set added = new HashSet<>(); // creating a set per review to avoid duplicate within a review + for (String s : strs) { s = s.toLowerCase(); - if(set.contains(s) && !added.contains(s)) { + if (set.contains(s) && !added.contains(s)) { map.put(s, map.getOrDefault(s, 0) + 1); added.add(s); } } } - PriorityQueue> maxHeap = new PriorityQueue<>((a, b)->a.getValue() == b.getValue() ? a.getKey().compareTo(b.getKey()) : b.getValue() - a.getValue()); + PriorityQueue> maxHeap = new PriorityQueue<>((a, b) -> a.getValue() == b.getValue() ? a.getKey().compareTo(b.getKey()) : b.getValue() - a.getValue()); maxHeap.addAll(map.entrySet()); - while(!maxHeap.isEmpty() && k-- > 0) { + map.entrySet().forEach(e-> System.out.println(e.getKey() +" "+e.getValue())); + while (!maxHeap.isEmpty() && k-- > 0) { res.add(maxHeap.poll().getKey()); } return res; diff --git a/src/geeksforgeeks/KthClosestOrigin.java b/src/geeksforgeeks/KthClosestOrigin.java index fb4967c..52c234a 100644 --- a/src/geeksforgeeks/KthClosestOrigin.java +++ b/src/geeksforgeeks/KthClosestOrigin.java @@ -7,11 +7,11 @@ * https://leetcode.com/problems/k-closest-points-to-origin/solution/ */ class KthClosestOrigin { - - static int[][] points = new int[3][2]; + int[][] points = new int[3][2]; // quick select public int[][] kClosest(int[][] points, int K) { + this.points= points; sort(0, points.length - 1, K); return Arrays.copyOfRange(points, 0, K); } @@ -33,22 +33,17 @@ public void sort(int i, int j, int K) { } public int partition(int i, int j) { - int oi = i; int pivot = dist(i); - i++; - - while (true) { - while (i < j && dist(i) < pivot) - i++; - while (i <= j && dist(j) > pivot) - j--; - if (i >= j) { - break; + swap(i, j); + int iLow = i; + for (int i1 = i; i1 < j; i1++) { + if (dist(i1) <= pivot) { + swap(i1, iLow); + iLow++; } - swap(i, j); } - swap(oi, j); - return j; + swap(iLow, j); + return iLow; } public int dist(int i) { @@ -62,41 +57,18 @@ public void swap(int i, int j) { points[j][0] = t0; points[j][1] = t1; } - - public int[][] kClosestOLogN(int[][] points, int K) { - int N = points.length; - int[] dists = new int[N]; - for (int i = 0; i < N; ++i) - dists[i] = distOLogN(points[i]); - - Arrays.sort(dists); - int distK = dists[K - 1]; - - int[][] ans = new int[K][2]; - int t = 0; - for (int i = 0; i < N; ++i) - if (distOLogN(points[i]) <= distK) { - ans[t++] = points[i]; - } - return ans; - } - - public int distOLogN(int[] point) { - return point[0] * point[0] + point[1] * point[1]; - } - public static void main(String[] args) { - KthClosestOrigin kth = new KthClosestOrigin(); - points[0][0] = 3; - points[0][1] = 3; - - points[1][0] = 5; - points[1][1] = -1; - - points[2][0] = 2; - points[2][1] = 4; - - // System.out.println(Arrays.deepToString(kth.kClosestOLogN(points, 1))); - System.out.println(Arrays.deepToString(kth.kClosest(points, 2))); +// KthClosestOrigin kth = new KthClosestOrigin(); +// points[0][0] = 3; +// points[0][1] = 3; +// +// points[1][0] = 5; +// points[1][1] = -1; +// +// points[2][0] = 2; +// points[2][1] = 4; +// +// // System.out.println(Arrays.deepToString(kth.kClosestOLogN(points, 1))); +// System.out.println(Arrays.deepToString(kth.kClosest(points, 2))); } } diff --git a/src/geeksforgeeks/LargestDivisibleSubset.java b/src/geeksforgeeks/LargestDivisibleSubset.java index e52f5d2..8bc5d88 100644 --- a/src/geeksforgeeks/LargestDivisibleSubset.java +++ b/src/geeksforgeeks/LargestDivisibleSubset.java @@ -6,7 +6,8 @@ import java.util.List; /** - * Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of elements in this subset satisfies: + * Given a set of distinct positive integers, + * find the largest subset such that every pair (Si, Sj) of elements in this subset satisfies: Si % Sj = 0 or Sj % Si = 0. If there are multiple solutions, return any subset is fine. Input: [2,3,4,6,10,8,24] @@ -17,7 +18,8 @@ public class LargestDivisibleSubset { /** * if a%b==0 means a>b, if b>a then the ans is b itself *inorder to have that we need to sort the array in increasing order - at first each val is ans to itself, then we come from last so a is higher in a%b + at first each val is ans to itself, then we come from last so a is higher in a%b + for ex if 2 is factor of 4 then include the set involve in available. This is DP problem [2, 3, 4, 6, 8, 10, 24] {2} {3} {4} {6} {8} {10} {24} {8,24} diff --git a/src/geeksforgeeks/LiveCellDeadCellGame.java b/src/geeksforgeeks/LiveCellDeadCellGame.java deleted file mode 100644 index 9ec83b4..0000000 --- a/src/geeksforgeeks/LiveCellDeadCellGame.java +++ /dev/null @@ -1,37 +0,0 @@ -package geeksforgeeks; - -//https://leetcode.com/problems/game-of-life/discuss/73366/Clean-O(1)-space-O(mn)-time-Java-Solution -public class LiveCellDeadCellGame { - public void gameOfLife(int[][] board) { - int[][] dir = { { 1, -1 }, { 1, 0 }, { 1, 1 }, { 0, -1 }, { 0, 1 }, { -1, -1 }, { -1, 0 }, { -1, 1 } }; - int row = board.length; - int col = board[0].length; - for (int i = 0; i < board.length; i++) { - for (int j = 0; j < board[0].length; j++) { - int liveCells = 0; - for (int k = 0; k < dir.length; k++) { - if (i + dir[k][0] >= row || j + dir[k][1] >= col || i + dir[k][0] < 0 || j + dir[k][1] < 0) { - continue; - } - if (board[i + dir[k][0]][j + dir[k][1]] == 1 || board[i + dir[k][0]][j + dir[k][1]] == 2) { - liveCells++; - } - } - - if (board[i][j] == 0 && liveCells == 3) { - board[i][j] = 3; - } - if (board[i][j] == 1 && (liveCells < 2 || liveCells > 3)) { - board[i][j] = 2; - } - } - } - - for (int i = 0; i < board.length; i++) { - for (int j = 0; j < board[0].length; j++) { - board[i][j] %= 2; - } - } - - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/LongestConsequtiveSequence.java b/src/geeksforgeeks/LongestConsequtiveSequence.java index 1eea844..d81010e 100644 --- a/src/geeksforgeeks/LongestConsequtiveSequence.java +++ b/src/geeksforgeeks/LongestConsequtiveSequence.java @@ -5,12 +5,14 @@ import java.util.Set; /** - * Given an unsorted array of integers, find the length of the longest consecutive elements sequence. + * Given an unsorted array of integers, + * find the length of the longest consecutive elements sequence. * * Your algorithm should run in O(n) complexity. * Input: [100, 4, 200, 1, 3, 2] * Output: 4 - * Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4. + * Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. + * Therefore its length is 4. */ class LongestConsequtiveSequence { @@ -28,7 +30,7 @@ public int longestConsecutive(int[] nums) { for (Integer i : nums) { int num = i; int count = 1; - // looking left; + // looking left while (set.contains(--num)) { count++; set.remove(num); diff --git a/src/geeksforgeeks/LongestSpanWithSameSumArray.java b/src/geeksforgeeks/LongestSpanWithSameSumArray.java index dee75cb..77476cc 100644 --- a/src/geeksforgeeks/LongestSpanWithSameSumArray.java +++ b/src/geeksforgeeks/LongestSpanWithSameSumArray.java @@ -1,64 +1,67 @@ package geeksforgeeks; -/*https://www.geeksforgeeks.org/longest-span-sum-two-binary-arrays/*/ -class LongestSpanWithSameSumArray { - - static int longestCommonSum(int[] arr1, int[] arr2, int n) { - int maxLen = 0; +import java.util.HashMap; +import java.util.Map; - // Initialize prefix sums of two arrays - int preSum1 = 0, preSum2 = 0; - - // Create an array to store staring and ending - // indexes of all possible diff values. diff[i] - // would store starting and ending points for - // difference "i-n" +/** + * Given two binary arrays arr1[] and arr2[] of same size n. + * Find length of the longest common span (i, j) + * where j >= i such that arr1[i] + arr1[i+1] + …. + arr1[j] = arr2[i] + arr2[i+1] + …. + arr2[j]. + * + * Expected time complexity is Θ(n). + * + * Input: arr1[] = {0, 1, 0, 0, 0, 0}; + * arr2[] = {1, 0, 1, 0, 0, 1}; + * Output: 4 + * The longest span with same sum is from index 1 to 4. + * + * Input: arr1[] = {0, 1, 0, 1, 1, 1, 1}; + * arr2[] = {1, 1, 1, 1, 1, 0, 1}; + * Output: 6 + * The longest span with same sum is from index 1 to 6. + * + * */ +class LongestSpanWithSameSumArray { + // Returns largest common subarray with equal + // number of 0s and 1s + static int longestCommonSum(int[] arr1, int[] arr2, int n) + { + // Find difference between the two + int[] arr = new int[n]; + // the reason we take the difference is, the resultant array + // will only contain 3 values 0,1,-1, checking for zero sum + // on the resultant array means we get the longest span where elements are same + for (int i = 0; i < n; i++) + arr[i] = arr1[i] - arr2[i]; - int diff[] = new int[2*n+1]; + // Creates an empty hashMap hM + Map hM = new HashMap<>(); - // Initialize all starting and ending values as -1. - for (int i = 0; i < diff.length; i++) { - diff[i] = -1; - } + int sum = 0; // Initialize sum of elements + int max_len = 0; // Initialize result - // Traverse both arrays - for (int i=0; i maxLen) - maxLen = len; - } + else // Else put this sum in hash table + hM.put(sum, i); } - return maxLen; + return max_len; } + public static void main(String args[]) { /* int[] arr1 = {0, 1, 0, 1, 1, 1, 1}; int[] arr2 = {1, 1, 1, 1, 1, 0, 1};*/ diff --git a/src/geeksforgeeks/LongestSubArraySumUtmostK.java b/src/geeksforgeeks/LongestSubArraySumUtmostK.java index 093bb04..11c82cb 100644 --- a/src/geeksforgeeks/LongestSubArraySumUtmostK.java +++ b/src/geeksforgeeks/LongestSubArraySumUtmostK.java @@ -2,6 +2,20 @@ /** * https://www.geeksforgeeks.org/longest-subarray-sum-elements-atmost-k/ + * + * Given an array of integers, + * our goal is to find the length of largest subarray + * having sum of its elements atmost ‘k’ where k>0. + * + * Examples: + * + * Input : arr[] = {1, 2, 1, 0, 1, 1, 0}, + * k = 4 + * Output : 5 + * Explanation: + * {1, 2, 1} => sum = 4, length = 3 + * {1, 2, 1, 0}, {2, 1, 0, 1} => sum = 4, length = 4 + * {1, 0, 1, 1, 0} =>5 sum = 3, length = 5 */ // array is non-negative class LongestSubArraySumUtmostK { diff --git a/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java b/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java index 97589ed..83ba315 100644 --- a/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java +++ b/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java @@ -6,7 +6,8 @@ import java.util.PriorityQueue; /** - * Given an array arr[] containing n elements. The problem is to find maximum number of distinct elements (non-repeating) after removing k elements from the array. + * Given an array arr[] containing n elements. + * The problem is to find maximum number of distinct elements (non-repeating) after removing k elements from the array. * Input : arr[] = {5, 7, 5, 5, 1, 2, 2}, k = 3 * Output : 4 * diff --git a/src/geeksforgeeks/MaxFreqStack.java b/src/geeksforgeeks/MaxFreqStack.java index 624051d..f786508 100644 --- a/src/geeksforgeeks/MaxFreqStack.java +++ b/src/geeksforgeeks/MaxFreqStack.java @@ -9,7 +9,8 @@ * * push(int x), which pushes an integer x onto the stack. * pop(), which removes and returns the most frequent element in the stack. - * If there is a tie for most frequent element, the element closest to the top of the stack is removed and returned. + * If there is a tie for most frequent element, + * the element closest to the top of the stack is removed and returned. * ["FreqStack","push","push","push","push","push","push","pop","pop","pop","pop"], * [[],[5],[7],[5],[7],[4],[5],[],[],[],[]] * Output: [null,null,null,null,null,null,null,5,7,5,4] diff --git a/src/geeksforgeeks/MaxSoldiers.java b/src/geeksforgeeks/MaxSoldiers.java index 8194bad..8229286 100644 --- a/src/geeksforgeeks/MaxSoldiers.java +++ b/src/geeksforgeeks/MaxSoldiers.java @@ -3,10 +3,10 @@ import java.util.PriorityQueue; public class MaxSoldiers { - class Pair{ - int row; - int soldiers; - Pair(int row, int soldiers){ + class Pair { + T row; + S soldiers; + Pair(T row, S soldiers){ this.row=row; this.soldiers=soldiers; } @@ -14,17 +14,17 @@ class Pair{ public int[] kWeakestRows(int[][] mat, int k) { int[] result= new int[k]; - PriorityQueue queue= new PriorityQueue<>((a, b)->a.soldiers==b.soldiers?Integer.compare(a.row,b.row):Integer.compare(a.soldiers,b.soldiers)); + PriorityQueue> queue= new PriorityQueue<>((a, b)->a.soldiers==b.soldiers?Integer.compare(a.row,b.row):Integer.compare(a.soldiers,b.soldiers)); int i=0; int soldiers=0; for(int []rows: mat){ int temp= binarySearchUtil(rows, 0, rows.length); - queue.offer(new Pair(i,temp)); + queue.offer(new Pair<>(i,temp)); i++; } int ind=0; while(ind { - T key; - I value; +public class MinimumSwapSortArray { + // Return the minimum number + // of swaps required to sort the array + public int minSwaps(int[] arr, int N) { - public T getKey() { - return key; - } - - public I getValue() { - return value; - } - - public void setKey(T key) { - this.key = key; - } - - public void setValue(I value) { - this.value = value; - } - public Pair(T key, I value){ - this.key=key; - this.value=value; - } - - @Override - public String toString() { - return "Pair{" + - "key=" + key + - ", value=" + value + - '}'; - } - } - - public static int minSwaps(int[] arr) { - int n = arr.length; - - // Create two arrays and use as pairs where first - // array is element and second array - // is position of first element - ArrayList> arrpos = - new ArrayList>(); - for (int i = 0; i < n; i++) - arrpos.add(new Pair(arr[i], i)); - - // Sort the array by array element values to - // get right position of every element as the - // elements of second array. - Collections.sort(arrpos, (a,b)-> { - if (a.getKey() == b.getKey()) { - return 0; - } - return Integer.compare(b.getKey(), a.getKey()); - }); - // arrpos.sort(new Comparator>() { - // @Override - // public int compare(Pair o1, - // Pair o2) { - // if (o1.getKey() > o2.getKey()) - // return -1; - - // // We can change this to make it then look at the - // // words alphabetical order - // else if (o1.getKey().equals(o2.getKey())) - // return 0; - - // else - // return 1; - // } - // }); - System.out.println(arrpos); - // To keep track of visited elements. Initialize - // all elements as not visited or false. - Boolean[] vis = new Boolean[n]; - Arrays.fill(vis, false); - - // Initialize result int ans = 0; + int[] temp = Arrays.copyOfRange(arr, 0, N); - // Traverse array elements - for (int i = 0; i < n; i++) { - // already swapped and corrected or - // already present at correct pos - if (vis[i] || arrpos.get(i).getValue() == i) - continue; - - // find out the number of node in - // this cycle and add in ans - int cycle_size = 0; - int j = i; - while (!vis[j]) { - vis[j] = true; + // Hashmap which stores the + // indexes of the input array + Map h + = new HashMap<>(); - // move to next node - j = arrpos.get(j).getValue(); - cycle_size++; - } - - // Update answer by adding current cycle. - if (cycle_size > 0) { - ans += (cycle_size - 1); + Arrays.sort(temp); + for (int i = 0; i < N; i++) { + h.put(arr[i], i); + } + for (int i = 0; i < N; i++) { + + // This is checking whether + // the current element is + // at the right place or not + if (arr[i] != temp[i]) { + ans++; + int init = arr[i]; + + // If not, swap this element + // with the index of the + // element which should come here + swap(arr, i, h.get(temp[i])); + + // Update the indexes in + // the hashmap accordingly + h.put(init, h.get(temp[i])); + h.put(temp[i], i); } } - - // Return result return ans; } + public void swap(int[] arr, int i, int j) { + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + public static void main(String[] args) { - int[] a = {1, 5, 4, 3, 2}; - System.out.println(minSwaps(a)); + //nums = {10, 19, 6, 3, 5} + //nums = {2, 8, 5, 4} } } \ No newline at end of file diff --git a/src/geeksforgeeks/MoveZeroes.java b/src/geeksforgeeks/MoveZeroes.java index 2dcdd93..8cd4f4c 100644 --- a/src/geeksforgeeks/MoveZeroes.java +++ b/src/geeksforgeeks/MoveZeroes.java @@ -4,6 +4,7 @@ /** * https://leetcode.com/problems/move-zeroes/ + * [[4,2,4,0,0,3,0,5,1,0]] */ class MoveZeroes { diff --git a/src/geeksforgeeks/PathSumIII.java b/src/geeksforgeeks/PathSumIII.java index 6ba76c6..cbf173a 100644 --- a/src/geeksforgeeks/PathSumIII.java +++ b/src/geeksforgeeks/PathSumIII.java @@ -1,65 +1,48 @@ package geeksforgeeks; -import java.util.ArrayList; -import java.util.List; + +import java.util.HashMap; +import java.util.Map; public class PathSumIII { - List list= new ArrayList<>(); + Map h= new HashMap<>(); int count=0; - public int pathSum(TreeNode root, int sum) { - if(root==null) return 0; - list.add(root.val); - pathSum(root.left,sum); - pathSum(root.right,sum); - - int k=0; - for(int i=list.size()-1;i>=0;i--){ // coming in reverse order, inorder to avoid considering - // head node - k+=list.get(i); - if(sum==k){ - count++; - } - } - - list.remove(list.size()-1); - return count; + + public void preorder(TreeNode node, int currSum, int k) { + if (node == null) + return; + + // current prefix sum + currSum += node.val; + + // here is the sum we're looking for + if (currSum == k) + count++; + + // number of times the curr_sum − k has occured already, + // determines the number of times a path with sum k + // has occurred upto the current node + count += h.getOrDefault(currSum - k, 0); + + // add the current sum into hashmap + // to use it during the child nodes processing + h.put(currSum, h.getOrDefault(currSum, 0) + 1); + + // process left subtree + preorder(node.left, currSum, k); + // process right subtree + preorder(node.right, currSum, k); + + // remove the current sum from the hashmap + // in order not to use it during + // the parallel subtree processing + h.put(currSum, h.get(currSum) - 1); } -// public void preorder(TreeNode node, int currSum, int k) { -// if (node == null) -// return; -// -// // current prefix sum -// currSum += node.val; -// -// // here is the sum we're looking for -// if (currSum == k) -// count++; -// -// // number of times the curr_sum − k has occured already, -// // determines the number of times a path with sum k -// // has occured upto the current node -// count += h.getOrDefault(currSum - k, 0); -// -// // add the current sum into hashmap -// // to use it during the child nodes processing -// h.put(currSum, h.getOrDefault(currSum, 0) + 1); -// -// // process left subtree -// preorder(node.left, currSum, k); -// // process right subtree -// preorder(node.right, currSum, k); -// -// // remove the current sum from the hashmap -// // in order not to use it during -// // the parallel subtree processing -// h.put(currSum, h.get(currSum) - 1); -// } -// -// public int pathSumAlter(TreeNode root, int sum) { -// int k = sum; -// preorder(root, 0, k); -// return count; -// } + public int pathSumAlter(TreeNode root, int sum) { + int k = sum; + preorder(root, 0, k); + return count; + } } \ No newline at end of file diff --git a/src/geeksforgeeks/PerfectSquare.java b/src/geeksforgeeks/PerfectSquare.java index 2f0e6f2..78f9b80 100644 --- a/src/geeksforgeeks/PerfectSquare.java +++ b/src/geeksforgeeks/PerfectSquare.java @@ -24,9 +24,12 @@ public int numSquaresDp(int n) { int sqrt = (int)Math.sqrt(i); // because i can have max of sqrt(i) perfect squares for(int j=sqrt;j>0;j--){ int result = i - j*j; - // the reason to take min is for i=5 j=sqrt(5)=2 - // when subract 1 we are left with 4 - // when subract 4 we are left with 1 so minimum is 1 and add 1 to it + // the reason to add 1 to the ns[result] is, we take away + // a square from 'i' initially (j*j) and check for best answer in the 1-D arr + // we add back the 'taken out' square to min value + // for e.x if i=13, sqrt is 3, while iterating + // we subtract 1*1 from 13 and check for best possible answer for 12 ns[result] + // finally we add back the 1*1 as +1 (ns[result]+1) min = Math.min(min, ns[result]+1); } ns[i] = min; diff --git a/src/geeksforgeeks/PermutationInString.java b/src/geeksforgeeks/PermutationInString.java new file mode 100644 index 0000000..cbda049 --- /dev/null +++ b/src/geeksforgeeks/PermutationInString.java @@ -0,0 +1,62 @@ +package geeksforgeeks; + +/** + * Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. + * In other words, one of the first string's permutations is the substring of the second string. + * Input:s1= "ab" s2 = "eidboaoo" + * Output: False + *

+ * https://leetcode.com/problems/permutation-in-string/ + */ +public class PermutationInString { + + // How do we know string p is a permutation of string s? Easy, each character in p is in s too. + // So we can abstract all permutation strings of s to a map (Character -> Count). i.e. abba -> {a:2, b:2}. + // Since there are only 26 lower case letters in this problem, + // we can just use an array to represent the map. + // How do we know string s2 contains a permutation of s1? + // We just need to create a sliding window with length of s1, + // move from beginning to the end of s2. + // When a character moves in from right of the window, + // we subtract 1 to that character count from the map. + // When a character moves out from left of the window, we add 1 to that character count. + // So once we see all zeros in the map, + // meaning equal numbers of every characters between s1 and + // the substring in the sliding window, we know the answer is true. + public static boolean checkInclusion(String s1, String s2) { + if (s1.length() == 0 || s2.length() == 0) { + return false; + } + int[] cache = new int[26]; + for (char s : s1.toCharArray()) { + cache[s - 'a']++; + } + + int right = 0; + + while (right < s2.length()) { + cache[s2.charAt(right) - 'a']--; + if (right >= s1.length()) { + cache[s2.charAt(right - s1.length()) - 'a']++; // sliding the window + } + if (allZero(cache)) { + return true; + } + right++; + } + return false; + } + + public static boolean allZero(int[] cache) { + for (int i = 0; i < 26; i++) { + if (cache[i] > 0) { + return false; + } + } + return true; + } + + public static void main(String[] args) { + System.out.println(checkInclusion("ab", "eidbaoo")); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/PlusOne.java b/src/geeksforgeeks/PlusOne.java index 7c1f509..ba4b78c 100644 --- a/src/geeksforgeeks/PlusOne.java +++ b/src/geeksforgeeks/PlusOne.java @@ -1,26 +1,38 @@ package geeksforgeeks; +import java.util.Arrays; + +/** + * https://leetcode.com/problems/plus-one/ + */ class PlusOne { - public static int[] plusOne(int[] digits) { - if(digits==null || digits.length==0) return digits; - int temp=digits[digits.length-1]+1; - - digits[digits.length-1]= temp%10; - int rem=temp/10; - for(int i=digits.length-2;i>=0;i--){ - int sum=digits[i]+rem; - digits[i]=(sum)%10; - rem=(sum)/10; + + public static int[] plusOne(int[] digits) { + + int n = digits.length; + // move along the input array starting from the end + for (int idx = n - 1; idx >= 0; --idx) { + // set all the nines at the end of array to zeros + if (digits[idx] == 9) { + digits[idx] = 0; + } + // here we have the rightmost not-nine + else { + // increase this rightmost not-nine by 1 + digits[idx]++; + // and the job is done + return digits; + } } - - if(rem>0){ - int[] result= new int[digits.length+1]; - result[0]=1; - return result; - } - - - return digits; + // we're here because all the digits are nines + digits = new int[n + 1]; + digits[0] = 1; + return digits; + } + + public static void main(String[] args) { + int[] digits = { 1, 2, 9 }; + int[] endpointUrl = plusOne(digits); + Arrays.stream(endpointUrl).forEach(System.out::println); } - } \ No newline at end of file diff --git a/src/geeksforgeeks/Pow.java b/src/geeksforgeeks/Pow.java index 4108096..829f624 100644 --- a/src/geeksforgeeks/Pow.java +++ b/src/geeksforgeeks/Pow.java @@ -1,6 +1,17 @@ package geeksforgeeks; -// https://leetcode.com/problems/powx-n/ +/** + * Implement pow(x, n), which calculates x raised to the power n (i.e. xn). + * + * Example 1: + * + * Input: x = 2.00000, n = 10 + * Output: 1024.00000 + * Example 2: + * + * Input: x = 2.10000, n = 3 + * Output: 9.26100 + */ public class Pow { public double myPow(double x, int n) { diff --git a/src/geeksforgeeks/PrisonAfterNDays.java b/src/geeksforgeeks/PrisonAfterNDays.java index 81327be..5436dd0 100644 --- a/src/geeksforgeeks/PrisonAfterNDays.java +++ b/src/geeksforgeeks/PrisonAfterNDays.java @@ -28,7 +28,9 @@ public static int[] prisonAfterNDays(int[] cells, int N) { cells = next; } if (hasCycle) { - N %= cycle; + N %= cycle; // calculating the reminder day after excluding the cycle + // let's say N=10 and we hit cycle at 3, we need 10%3=1 remaining calculation + // to be done for (int i = 0; i < N; i++) { cells = nextDay(cells); } diff --git a/src/geeksforgeeks/QueensAttackKing.java b/src/geeksforgeeks/QueensAttackKing.java index 4123789..88a6860 100644 --- a/src/geeksforgeeks/QueensAttackKing.java +++ b/src/geeksforgeeks/QueensAttackKing.java @@ -21,7 +21,7 @@ public List> queensAttacktheKing(int[][] queens, int[] king) { } for(int[] dir: dirs){ - List temp= findQueensPosistions(king,dir[0],dir[1],visited); + List temp= findQueensPositions(king,dir[0],dir[1],visited); if(temp!=null) result.add(temp); } @@ -29,17 +29,17 @@ public List> queensAttacktheKing(int[][] queens, int[] king) { } - public List findQueensPosistions(int[] king, int x, int y, boolean[][] visited){ - int newX= x+king[0]; - int newY= y+king[1]; - // going to walk along x,y only, not 8 directions at smae time; + public List findQueensPositions(int[] king, int xDir, int yDir, boolean[][] visited){ + int newX= xDir+king[0]; + int newY= yDir+king[1]; + // going to walk along x,y only not 8 directions at same time while(newX<8 && newY<8 && newX>=0 && newY>=0){ if(visited[newX][newY]){ return Arrays.asList(newX,newY); // returns when first queen is met in row or column } - newX+=x; - newY+=y; + newX+=xDir; + newY+=yDir; } diff --git a/src/geeksforgeeks/RandomPickWithWeight.java b/src/geeksforgeeks/RandomPickWithWeight.java new file mode 100644 index 0000000..afd51fe --- /dev/null +++ b/src/geeksforgeeks/RandomPickWithWeight.java @@ -0,0 +1,54 @@ +package geeksforgeeks; + +import java.util.stream.IntStream; + +/** + * https://leetcode.com/problems/random-pick-with-weight/ + */ +class RandomPickWithWeight { + private int sum; + private int[] sumArr; + + public RandomPickWithWeight(int[] w) { + sum = 0; + sumArr = new int[w.length]; + for (int i = 0; i < w.length; ++i) { + sum += w[i]; + sumArr[i] = sum; + } + } + + public int pickIndex() { + int idx = (int) (Math.random() * sum); + return binarySearch(idx + 1); // +1 is because the rand will lie between 0-14 + } + + public int binarySearch(int idx) { + int left = 0; + int right = sumArr.length - 1; + + while (left < right) { + int mid = ((right - left) / 2) + left; + if (sumArr[mid] < idx) { + left = mid + 1; + } else { + right = mid; + } + } + return left; + } + + public static void main(String[] args) { + RandomPickWithWeight randomPickWithWeight = new RandomPickWithWeight(new int[]{1, 3, 5, 4, 2}); + randomPickWithWeight.pickIndex(); + + //IntStream.range(0, 10).forEach(i -> System.out.println((int) (Math.random() * 3))); + } + +} + +/** + * Your Solution object will be instantiated and called as such: + * Solution obj = new Solution(w); + * int param_1 = obj.pickIndex(); + */ \ No newline at end of file diff --git a/src/geeksforgeeks/RangeSum.java b/src/geeksforgeeks/RangeSum.java index af58e6f..32194a2 100644 --- a/src/geeksforgeeks/RangeSum.java +++ b/src/geeksforgeeks/RangeSum.java @@ -1,5 +1,28 @@ package geeksforgeeks; +/** + * 303. Range Sum Query - Immutable + * + * Given an integer array nums, + * find the sum of the elements between indices i and j (i ≤ j), inclusive. + * + * Implement the NumArray class: + * + * NumArray(int[] nums) Initializes the object with the integer array nums. + * int sumRange(int i, int j) Return the sum of the elements of the nums array in the range [i, j] + * inclusive (i.e., sum(nums[i], nums[i + 1], ... , nums[j])) + * + * ["NumArray", "sumRange", "sumRange", "sumRange"] + * [[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]] + * Output + * [null, 1, -1, -3] + * + * Explanation + * NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]); + * numArray.sumRange(0, 2); // return 1 ((-2) + 0 + 3) + * numArray.sumRange(2, 5); // return -1 (3 + (-5) + 2 + (-1)) + * numArray.sumRange(0, 5); // return -3 ((-2) + 0 + 3 + (-5) + 2 + (-1)) + */ public class RangeSum { int[] dp; public void NumArray(int[] nums) { diff --git a/src/geeksforgeeks/RemoveAdjacentDuplicates.java b/src/geeksforgeeks/RemoveAdjacentDuplicates.java new file mode 100644 index 0000000..b517171 --- /dev/null +++ b/src/geeksforgeeks/RemoveAdjacentDuplicates.java @@ -0,0 +1,29 @@ +package geeksforgeeks; + +import java.util.Arrays; + +/** + * https://www.geeksforgeeks.org/recursively-remove-adjacent-duplicates-given-string/ + */ +public class RemoveAdjacentDuplicates { + + + public static void main(String[] args) { + System.out.println(removeDuplicatesLee("azxxzy")); + System.out.println(removeDuplicatesLee("aaaa")); + System.out.println(removeDuplicatesLee("abbaca")); + } + + public static String removeDuplicatesLee(String s) { + int i = 0; + int n = s.length(); + char[] res = s.toCharArray(); + for (int j = 0; j < n; j++, i++) { + res[i] = res[j]; + if (i > 0 && res[i - 1] == res[i]) { + i -= 2; + } + } + return new String(res, 0, i); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/RemoveParanthesisValid.java b/src/geeksforgeeks/RemoveInvalidParentheses.java similarity index 97% rename from src/geeksforgeeks/RemoveParanthesisValid.java rename to src/geeksforgeeks/RemoveInvalidParentheses.java index ba9d28e..f9f0e59 100644 --- a/src/geeksforgeeks/RemoveParanthesisValid.java +++ b/src/geeksforgeeks/RemoveInvalidParentheses.java @@ -2,7 +2,7 @@ import java.util.*; -public class RemoveParanthesisValid { +public class RemoveInvalidParentheses { public List removeInvalidParentheses(String s) { if (isValid(s)) diff --git a/src/geeksforgeeks/RemoveKDigits.java b/src/geeksforgeeks/RemoveKDigits.java index ed07b21..d5a2cc0 100644 --- a/src/geeksforgeeks/RemoveKDigits.java +++ b/src/geeksforgeeks/RemoveKDigits.java @@ -5,6 +5,21 @@ /** * https://leetcode.com/problems/remove-k-digits/ + * + * Given a non-negative integer num represented as a string, + * remove k digits from the number so that the new number is the smallest possible. + * + * Note: + * The length of num is less than 10002 and will be ≥ k. + * The given num does not contain any leading zero. + * + * Input: num = "1432219", k = 3 + * Output: "1219" + * Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest. + * + * Input: num = "10", k = 2 + * Output: "0" + * Explanation: Remove all the digits from the number and it is left with nothing which is 0. */ public class RemoveKDigits { diff --git a/src/geeksforgeeks/ReorderLogs.java b/src/geeksforgeeks/ReorderLogs.java index ebda923..b71a435 100644 --- a/src/geeksforgeeks/ReorderLogs.java +++ b/src/geeksforgeeks/ReorderLogs.java @@ -2,13 +2,14 @@ import java.util.Arrays; -/*https://leetcode.com/articles/reorder-log-files/ +/** + * https://leetcode.com/problems/reorder-data-in-log-files/ You have an array of logs. Each log is a space delimited string of words. For each log, the first word in each log is an alphanumeric identifier. Then, either: -Each word after the identifier will consist only of lowercase letters, or; +Each word after the identifier will consist only of lowercase letters, or Each word after the identifier will consist only of digits. We will call these two varieties of logs letter-logs and digit-logs. It is guaranteed that each log has at least one word after its identifier. diff --git a/src/geeksforgeeks/RestoreIPAddress.java b/src/geeksforgeeks/RestoreIPAddress.java deleted file mode 100644 index 452389c..0000000 --- a/src/geeksforgeeks/RestoreIPAddress.java +++ /dev/null @@ -1,34 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -//unresolved -class RestoreIPAddress { - - public List restoreIpAddresses(String s) { - List result = new ArrayList<>(); - doRestore(result, "", s, 0); - return result; - } - - private void doRestore(List result, String path, String s, int k) { - if (s.isEmpty() || k == 4) { - if (s.isEmpty() && k == 4) { - result.add(path.substring(1)); - } - return; - } - for (int i = 1; i <= (s.charAt(0) == '0' ? 1 : 3) && i <= s.length(); i++) { // Avoid leading 0 - String part = s.substring(0, i); - if (Integer.valueOf(part) <= 255) { - System.out.println(path); - doRestore(result, path + "." + part, s.substring(i), k + 1); - } - } - } - - public static void main(String[] args) { - RestoreIPAddress ip = new RestoreIPAddress(); - System.out.println(ip.restoreIpAddresses("25525511135").toString()); - } -} diff --git a/src/geeksforgeeks/RestorepAddresses.java b/src/geeksforgeeks/RestoreIpAddresses.java similarity index 73% rename from src/geeksforgeeks/RestorepAddresses.java rename to src/geeksforgeeks/RestoreIpAddresses.java index e85178e..1aa2660 100644 --- a/src/geeksforgeeks/RestorepAddresses.java +++ b/src/geeksforgeeks/RestoreIpAddresses.java @@ -2,7 +2,18 @@ import java.util.*; -public class RestorepAddresses { +/** + *Given a string s containing only digits, + * return all possible valid IP addresses that can be obtained from s. + * You can return them in any order. + * + * A valid IP address consists of exactly four integers, + * each integer is between 0 and 255, separated by single dots and cannot have leading zeros. + * For example, "0.1.2.201" and "192.168.1.1" are valid IP addresses and "0.011.255.245", + * "192.168.1.312" and "192.168@1.1" are invalid IP addresses. + */ + +public class RestoreIpAddresses { public List restoreIpAddresses(String s) { if (s == null) return Collections.emptyList(); diff --git a/src/geeksforgeeks/RotateArray.java b/src/geeksforgeeks/RotateArray.java new file mode 100644 index 0000000..fac0e62 --- /dev/null +++ b/src/geeksforgeeks/RotateArray.java @@ -0,0 +1,30 @@ +package geeksforgeeks; +/** + * Given an array, rotate the array to the right by k steps, where k is + * non-negative Could you do it in-place with O(1) extra space? + * + * + * Example 1: + * + * Input: nums = [1,2,3,4,5,6,7], k = 3 Output: [5,6,7,1,2,3,4] Explanation: + * rotate 1 steps to the right: [7,1,2,3,4,5,6] rotate 2 steps to the right: + * [6,7,1,2,3,4,5] rotate 3 steps to the right: [5,6,7,1,2,3,4] + */ +public class RotateArray { + public void rotate(int[] nums, int k) { + k %= nums.length; + reverse(nums, 0, nums.length - 1); + reverse(nums, 0, k - 1); + reverse(nums, k, nums.length - 1); + } + + public void reverse(int[] nums, int start, int end) { + while (start < end) { + int temp = nums[start]; + nums[start] = nums[end]; + nums[end] = temp; + start++; + end--; + } + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/SearchAnElementInMatrix.java b/src/geeksforgeeks/SearchAnElementInMatrix.java index 855a1b6..a8381b7 100644 --- a/src/geeksforgeeks/SearchAnElementInMatrix.java +++ b/src/geeksforgeeks/SearchAnElementInMatrix.java @@ -1,8 +1,10 @@ package geeksforgeeks; -/*https://www.youtube.com/watch?v=FOa55B9Ikfg -* https://leetcode.com/problems/search-a-2d-matrix-ii/ -https://leetcode.com/problems/search-a-2d-matrix/*/ +/** + * https://www.youtube.com/watch?v=FOa55B9Ikfg + * https://leetcode.com/problems/search-a-2d-matrix-ii/ + * https://leetcode.com/problems/search-a-2d-matrix/ + */ public class SearchAnElementInMatrix { @@ -10,8 +12,8 @@ private static boolean searchII(int[][] mat, int n, int x) { int i = 0; int j = n - 1; // set indexes for top right element - // we can start from top right corner or bottom left corner, because from - // these points only we have 2 paths one increasing one decreasing + // we can start from top right corner or bottom left corner, because from + // these points only we have 2 paths one increasing one decreasing while (i < n && j >= 0) { if (mat[i][j] == x) { System.out.print("n Found at " + i + " " + j); @@ -30,7 +32,6 @@ private static boolean searchII(int[][] mat, int n, int x) { } - // why column : no.of.columns define the row correctly and rows wont help us to find the exact row public static boolean searchI(int[][] matrix, int target) { if (matrix == null || matrix.length == 0) { return false; @@ -41,6 +42,13 @@ public static boolean searchI(int[][] matrix, int target) { int end = rows * cols - 1; while (start <= end) { int mid = (start + end) / 2; + /** + * Another way to took at it is: lets say you have a matrix M with 4 rows and 3 columns. + * When we want to access M[2][1], the way the memory address is calculated is 2*3+1 = 7. + * so you are just reversing the calculation , row number is given by 7/3 = 2, + * and column is the offset in that row so for 7th element it is 7%3 = 1. + * This link helped me understand it. https://www.youtube.com/watch?v=n5KNdUAftC4 + */ if (matrix[mid / cols][mid % cols] == target) { return true; } @@ -54,9 +62,9 @@ public static boolean searchI(int[][] matrix, int target) { } public static void main(String[] args) { - int[][] mat = { { 10, 20, 30, 40 }, { 15, 25, 35, 45 }, { 27, 29, 37, 48 }, { 32, 33, 39, 50 } }; + int[][] mat = {{10, 20, 30, 40}, {15, 25, 35, 45}, {27, 29, 37, 48}, {32, 33, 39, 50}}; - int[][] matI = { { 1, 3, 5, 7 }, { 10, 11, 16, 20 }, { 23, 30, 34, 50 } }; + int[][] matI = {{1, 3, 5, 7}, {10, 11, 16, 20}, {23, 30, 34, 50}}; System.out.println(searchI(matI, 11)); System.out.println(searchII(mat, 4, 33)); diff --git a/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java b/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java index 9ee10b5..8d5e4d2 100644 --- a/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java +++ b/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java @@ -1,25 +1,26 @@ package geeksforgeeks; -/*https://leetcode.com/problems/search-in-rotated-sorted-array/ -https://leetcode.com/problems/search-in-rotated-sorted-array-ii/ +/** + * https://leetcode.com/problems/search-in-rotated-sorted-array/ + * https://leetcode.com/problems/search-in-rotated-sorted-array-ii/ */ public class SearchElementInSortedAndRotatedArray { public static void main(String[] args) { - int[] arr = { 4, 5, 6, 7, 0, 1, 2 }; + int[] arr = {4, 5, 6, 7, 0, 1, 2}; SearchElementInSortedAndRotatedArray search = new SearchElementInSortedAndRotatedArray(); System.out.println(search.searchI(arr, 0)); - int[] nums = { 2, 5, 6, 0, 0, 1, 2 }; + int[] nums = {2, 5, 6, 0, 0, 1, 2}; System.out.println(search.searchII(nums, 2)); } // 4, 5, 0, 1, 2, 3 int searchI(int[] nums, int target) { - // If arr[start] <= arr[middle], the numbers from start to middle are sorted in ascending order. - // Else, the numbers from middle+1 to end are sorted in ascending order. + // If arr[start] <= arr[middle], the numbers from start to middle are sorted in ascending order. + // Else, the numbers from middle+1 to end are sorted in ascending order. int start = 0; int end = nums.length - 1; while (start <= end) { @@ -27,7 +28,7 @@ int searchI(int[] nums, int target) { if (nums[mid] == target) { return mid; } - + if (nums[start] <= nums[mid]) { if (target < nums[mid] && target >= nums[start]) { @@ -36,7 +37,7 @@ int searchI(int[] nums, int target) { start = mid + 1; } } - + if (nums[mid] <= nums[end]) { if (target > nums[mid] && target <= nums[end]) { @@ -51,32 +52,27 @@ int searchI(int[] nums, int target) { // with duplicates public boolean searchII(int[] nums, int target) { - int left = 0, right = nums.length-1, mid; - - while(left<=right) - { + int left = 0, right = nums.length - 1, mid; + + while (left <= right) { mid = (left + right) >> 1; - if(nums[mid] == target) return true; + if (nums[mid] == target) return true; // the only difference from the first one, trickly case, just updat left and right if ((nums[left] == nums[mid]) && (nums[right] == nums[mid])) { ++left; --right; + } else if (nums[left] <= nums[mid]) { + if ((nums[left] <= target) && (nums[mid] > target)) right = mid - 1; + else left = mid + 1; + } else { + if ((nums[mid] < target) && (nums[right] >= target)) left = mid + 1; + else right = mid - 1; } - - else if(nums[left] <= nums[mid]) - { - if( (nums[left]<=target) && (nums[mid] > target) ) right = mid-1; - else left = mid + 1; - } - else - { - if((nums[mid] < target) && (nums[right] >= target) ) left = mid+1; - else right = mid-1; } + return false; } - return false; - } + //[2,5,6,0,0,1,2] // 0 //duplicates, we know nums[mid] != target, so nums[start] != target //based on current information, diff --git a/src/geeksforgeeks/SerializeAndDeserialize.java b/src/geeksforgeeks/SerializeAndDeserialize.java index c982e89..4984f4f 100644 --- a/src/geeksforgeeks/SerializeAndDeserialize.java +++ b/src/geeksforgeeks/SerializeAndDeserialize.java @@ -46,7 +46,7 @@ public TreeNode deserializeHelper(Queue nodesLeftToMaterialize) { return null; } - TreeNode newNode = new TreeNode(Integer.valueOf(valueForNode)); + TreeNode newNode = new TreeNode(Integer.parseInt(valueForNode)); newNode.left = deserializeHelper(nodesLeftToMaterialize); newNode.right = deserializeHelper(nodesLeftToMaterialize); diff --git a/src/geeksforgeeks/SerializeDeserializeBST.java b/src/geeksforgeeks/SerializeDeserializeBST.java index f86c252..235060e 100644 --- a/src/geeksforgeeks/SerializeDeserializeBST.java +++ b/src/geeksforgeeks/SerializeDeserializeBST.java @@ -9,57 +9,68 @@ // rootValue (rootValue) (>rootValue) // Because of BST's property: before the |separate line| all the node values are less than root value, all the node values after |separate line| are greater than root value. We will utilize this to build left and right tree. -import java.util.LinkedList; -import java.util.Queue; -import java.util.Stack; +import java.util.*; -class SerializeDeserializeBST{ - private static final String SEP = ","; - private static final String NULL = "null"; - // Encodes a tree to a single string. - public String serialize(TreeNode root) { - StringBuilder sb = new StringBuilder(); - if (root == null) return NULL; - //traverse it recursively if you want to, I am doing it iteratively here - Stack st = new Stack<>(); - st.push(root); - while (!st.empty()) { - root = st.pop(); - sb.append(root.val).append(SEP); - if (root.right != null) st.push(root.right); - if (root.left != null) st.push(root.left); - } - return sb.toString(); +class SerializeDeserializeBST { + private static final String SEP = ","; + private static final String NULL = "null"; + // Encodes a tree to a single string. + + public String serialize(TreeNode root) { + + if (root == null) { + return NULL + SEP; } - - // Decodes your encoded data to tree. - // pre-order traversal - public TreeNode deserialize(String data) { - if (data.equals(NULL)) return null; - String[] strs = data.split(SEP); - Queue q = new LinkedList<>(); - for (String e : strs) { - q.offer(Integer.parseInt(e)); - } - return getNode(q); + + String leftSerialized = serialize(root.left); + String rightSerialized = serialize(root.right); + + return root.val + SEP + leftSerialized + rightSerialized; + } + + public String serializeIterative(TreeNode root) { + StringBuilder sb = new StringBuilder(); + if (root == null) return NULL; + //traverse it recursively if you want to, I am doing it iteratively here + Deque st = new ArrayDeque<>(); + st.push(root); + while (!st.isEmpty()) { + root = st.pop(); + sb.append(root.val).append(SEP); + if (root.right != null) st.push(root.right); + if (root.left != null) st.push(root.left); } - - // some notes: - // 5 - // 3 6 - // 2 7 - private TreeNode getNode(Queue q) { //q: 5,3,2,6,7 - if (q.isEmpty()) return null; - TreeNode root = new TreeNode(q.poll());//root (5) - Queue samllerQueue = new LinkedList<>(); - while (!q.isEmpty() && q.peek() < root.val) { - samllerQueue.offer(q.poll()); - } - //smallerQueue : 3,2 storing elements smaller than 5 (root) - root.left = getNode(samllerQueue); - //q: 6,7 storing elements bigger than 5 (root) - root.right = getNode(q); - return root; + return sb.toString(); + } + + // Decodes your encoded data to tree. + // pre-order traversal + public TreeNode deserialize(String data) { + if (data.equals(NULL)) return null; + String[] strs = data.split(SEP); + Queue q = new LinkedList<>(); + for (String e : strs) { + q.offer(Integer.parseInt(e)); + } + return getNode(q); + } + + // some notes: + // 5 + // 3 6 + // 2 7 + private TreeNode getNode(Queue q) { //q: 5,3,2,6,7 + if (q.isEmpty()) return null; + TreeNode root = new TreeNode(q.poll());//root (5) + Queue samllerQueue = new LinkedList<>(); + while (!q.isEmpty() && q.peek() < root.val) { + samllerQueue.offer(q.poll()); } - + //smallerQueue : 3,2 storing elements smaller than 5 (root) + root.left = getNode(samllerQueue); + //q: 6,7 storing elements bigger than 5 (root) + root.right = getNode(q); + return root; + } + } \ No newline at end of file diff --git a/src/geeksforgeeks/SetBitCount.java b/src/geeksforgeeks/SetBitCount.java index 47777b4..d3cf7a4 100644 --- a/src/geeksforgeeks/SetBitCount.java +++ b/src/geeksforgeeks/SetBitCount.java @@ -4,11 +4,11 @@ * https://leetcode.com/problems/number-of-1-bits/discuss/55099/Simple-Java-Solution-Bit-Shifting */ public class SetBitCount { - public int hammingWeight(int n) { + public static int hammingWeight(int n) { int count = 0; while (n != 0) { - n = n & (n - 1); + n &= (n - 1); count++; } @@ -16,6 +16,6 @@ public int hammingWeight(int n) { } public static void main(String[] args) { - int input = 00000000000000000000000000001011; + System.out.println(hammingWeight(00000000000000000000000000001011)); } } diff --git a/src/geeksforgeeks/ShipPackageWithNDays.java b/src/geeksforgeeks/ShipPackageWithNDays.java index 93c8a48..a8eeb85 100644 --- a/src/geeksforgeeks/ShipPackageWithNDays.java +++ b/src/geeksforgeeks/ShipPackageWithNDays.java @@ -2,37 +2,65 @@ import java.util.Arrays; -public class ShipPackageWithNDays{ - public int shipWithinDays(int[] weights, int D) { - if(weights.length==0 || D==0) return 0; - - int lowerBound= Arrays.stream(weights).max().orElse(0); - int upperBound= Arrays.stream(weights).sum(); - int mid=0; - while(lowerBound + * The ith package on the conveyor belt has a weight of weights[i]. + * Each day, we load the ship with packages on the conveyor belt (in the order given by weights). + * We may not load more weight than the maximum weight capacity of the ship. + *

+ * Return the least weight capacity of the ship + * that will result in all the packages on the conveyor belt being shipped within D days. + * + * Input: weights = [1,2,3,4,5,6,7,8,9,10], D = 5 + * Output: 15 + * Explanation: A ship capacity of 15 is the minimum to ship all the packages in 5 days like this: + * 1st day: 1, 2, 3, 4, 5 + * 2nd day: 6, 7 + * 3rd day: 8 + * 4th day: 9 + * 5th day: 10 + * + * Note that the cargo must be shipped in the order given, + * so using a ship of capacity 14 and splitting the packages into parts like + * (2, 3, 4, 5), (1, 6, 7), (8), (9), (10) is not allowed. + */ +public class ShipPackageWithNDays { + public static int shipWithinDays(int[] weights, int D) { + if (weights.length == 0 || D == 0) return 0; + + int lowerBound = Arrays.stream(weights).max().orElse(0); + int upperBound = Arrays.stream(weights).sum(); + int mid = 0; + while (lowerBound < upperBound) { + mid = (lowerBound + upperBound) / 2; + int daysToCarry = binarySearchUtil(weights, mid); + // if mid can carry weight then increase the upperBound to mid + if (daysToCarry<=D) upperBound = mid; + else lowerBound = mid + 1; + } - + return lowerBound; } - - - public boolean binarySearchUtil(int[] weights, int mid, int D){ - int sum=0; - int currentDay=1; - for(int weight:weights){ - if(sum+weight>mid){ - currentDay+=1; - sum=0; - - } - sum+=weight; + + + public static int binarySearchUtil(int[] weights, int mid) { + int sum = 0; + int currentDay = 1; + for (int weight : weights) { + if (sum + weight > mid) { + currentDay += 1; + sum = 0; + + } + sum += weight; } - - return currentDay>D; + + return currentDay; + } + + public static void main(String[] args) { + System.out.println(shipWithinDays(new int[]{1,2,3,4,5,6,7,8,9,10}, 5)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/SingleElementInSortedArray.java b/src/geeksforgeeks/SingleElementInSortedArray.java index 0b2d43a..b2d5977 100644 --- a/src/geeksforgeeks/SingleElementInSortedArray.java +++ b/src/geeksforgeeks/SingleElementInSortedArray.java @@ -1,15 +1,15 @@ package geeksforgeeks; /** - * You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once. + * You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once. * Find this single element that appears only once. */ public class SingleElementInSortedArray { public int singleNonDuplicate(int[] nums) { - if(nums==null || nums.length==0) return 0; - - int left=0; - int right= nums.length-1; + if (nums == null || nums.length == 0) return 0; + + int left = 0; + int right = nums.length - 1; // for 1,1,2,3,3,4,4,8,8 // when mid is at 4 and right-mid is even, means the rest elements are only pairs, so we check // left side by right=mid-2 @@ -17,28 +17,28 @@ public int singleNonDuplicate(int[] nums) { //are all pairs only so we check left side by right=mid-1 // when mid is 4 => nums[mid]==nums[mid-1] // when mid is 3 => nums[mid]==nums[mid+1] - while(left snake; + LinkedList queue; + + /** + * Initialize your data structure here. + * + * @param width - screen width + * @param height - screen height + * @param food - A list of food positions + * E.g food = [[1,1], [1,0]] means the first food is positioned at [1,1], the second is at [1,0]. + */ + public SnakeGame(int width, int height, int[][] food) { + this.food = food; + snake = new HashSet(); + eaten = 0; + headX = 0; + headY = 0; + m = height; + n = width; + queue = new LinkedList(); + queue.offer(new int[]{0, 0}); + snake.add("0,0"); + } + + /** + * Moves the snake. + * + * @param direction - 'U' = Up, 'L' = Left, 'R' = Right, 'D' = Down + * @return The game's score after the move. Return -1 if game over. + * Game over when snake crosses the screen boundary or bites its body. + */ + public int move(String direction) { + if (direction.equals("U")) { + headX--; + } else if (direction.equals("L")) { + headY--; + } else if (direction.equals("R")) { + headY++; + } else if (direction.equals("D")) { + headX++; + } else { + System.out.println("Wrong move"); + } + + if (!isValid(headX, headY)) { + return -1; + } + + return process(headX, headY); + } + + public boolean isValid(int i, int j) { + if (i < 0 || i >= m || j < 0 || j >= n) + return false; + return true; + } + + public int process(int x, int y) { + if (eaten == food.length) { + snake.remove(queue.peek()[0] + "," + queue.peek()[1]); + queue.poll(); + } else if (food[eaten][0] == x && food[eaten][1] == y) { + eaten++; + } else { + snake.remove(queue.peek()[0] + "," + queue.peek()[1]); + queue.poll(); + } + + if (snake.contains(x + "," + y)) { + return -1; + } + + snake.add(x + "," + y); + queue.offer(new int[]{x, y}); + + return eaten; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/StockSpanner.java b/src/geeksforgeeks/StockSpanner.java index 0bc1415..a885ad5 100644 --- a/src/geeksforgeeks/StockSpanner.java +++ b/src/geeksforgeeks/StockSpanner.java @@ -1,6 +1,5 @@ package geeksforgeeks; -import com.sun.tools.javac.util.Pair; import java.util.ArrayDeque; import java.util.Deque; @@ -8,20 +7,20 @@ ; class StockSpanner { - - Deque> stack; - public StockSpanner() { - this.stack= new ArrayDeque<>(); - } - - public int next(int price) { - int value=1; - while(!stack.isEmpty() && stack.peek().fst<=price){ - value+=stack.pop().snd; - } - - stack.push(new Pair(price,value)); - - return stack.peek().snd; - } +// +// Deque> stack; +// public StockSpanner() { +// this.stack= new ArrayDeque<>(); +// } +// +// public int next(int price) { +// int value=1; +// while(!stack.isEmpty() && stack.peek().fst<=price){ +// value+=stack.pop().snd; +// } +// +// stack.push(new Pair(price,value)); +// +// return stack.peek().snd; +// } } \ No newline at end of file diff --git a/src/geeksforgeeks/SubArraySumDivisibleByK.java b/src/geeksforgeeks/SubArraySumDivisibleByK.java index 0b684b7..1db73bb 100644 --- a/src/geeksforgeeks/SubArraySumDivisibleByK.java +++ b/src/geeksforgeeks/SubArraySumDivisibleByK.java @@ -4,17 +4,19 @@ import java.util.Map; /** - * Given an array A of integers, return the number of (contiguous, non-empty) subarrays that have a sum divisible by K. + * Given an array A of integers, return the number of (contiguous, non-empty) + * subarrays that have a sum divisible by K. * Input: A = [4,5,0,-2,-3,1], K = 5 - Output: 7 -Explanation: There are 7 subarrays with a sum divisible by K = 5: -[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3] + * Output: 7 + * Explanation: There are 7 subarrays with a sum divisible by K = 5: + * [4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3] */ -public class SubArraySumDivisibleByK{ +public class SubArraySumDivisibleByK { public int subarraysDivByK(int[] A, int K) { Map count = new HashMap<>(); - count.put(0, 1); //if the first prefix sum is 0, it need to be counted as a mod of K, right? Rest of prefix sum from 1 to K-1 don't include the first prefix sum + count.put(0, 1); //if the first prefix sum is 0, it need to be counted as a mod of K, right? + // Rest of prefix sum from 1 to K-1 don't include the first prefix sum int prefix = 0, res = 0; for (int a : A) { //(prefix+a%K+K)%K is just a trick to make the remainder positive. @@ -22,8 +24,9 @@ public int subarraysDivByK(int[] A, int K) { res += count.getOrDefault(prefix, 0); count.put(prefix, count.getOrDefault(prefix, 0) + 1); } - return res; + return res; } + // A = [4,5,0,-2,-3,1], K = 5 // step 1 : {0:1} a=4 sum=4 mod=4 count = 0+0 =0 // step 2 : {0:1,4:1} a=5 sum=9 mod=4 count = 0+1 =1 @@ -33,13 +36,13 @@ public int subarraysDivByK(int[] A, int K) { // step 7 : {0:1,4:4,2:1} a=1 sum=5 mod=0 count = 6+1 =7 public int subarraysDivByKOptimised(int[] A, int K) { int[] map = new int[K]; - map[0]=1; + map[0] = 1; int prefix = 0, res = 0; for (int a : A) { prefix = (prefix + a % K + K) % K; - res +=map[prefix]; + res += map[prefix]; map[prefix]++; } - return res; + return res; } } diff --git a/src/geeksforgeeks/SurroundedRegions.java b/src/geeksforgeeks/SurroundedRegions.java index 7c76e12..5844136 100644 --- a/src/geeksforgeeks/SurroundedRegions.java +++ b/src/geeksforgeeks/SurroundedRegions.java @@ -3,6 +3,32 @@ import java.util.ArrayDeque; import java.util.Queue; +/** + * Given a 2D board containing 'X' and 'O' (the letter O), + * capture all regions surrounded by 'X'. + *

+ * A region is captured by flipping all 'O's into 'X's in that surrounded region. + *

+ * Example: + *

+ * X X X X + * X O O X + * X X O X + * X O X X + *

+ * After running your function, the board should be: + *

+ * X X X X + * X X X X + * X X X X + * X O X X + *

+ * Surrounded regions shouldn’t be on the border, + * which means that any 'O' on the border of the board are not flipped to 'X'. + * Any 'O' that is not on the border and + * it is not connected to an 'O' on the border will be flipped to 'X'. + * Two cells are connected if they are adjacent cells connected horizontally or vertically. + */ class Solution { private static class Pair { int x; @@ -15,12 +41,13 @@ public Pair(int x, int y, int level) { this.level = level; } } + public void solve(char[][] board) { if (board == null || board.length == 0) return; Queue queue = new ArrayDeque<>(); - int[][] dirs = { { -1, 0 }, { 1, 0 }, { 0, 1 }, { 0, -1 } }; + int[][] dirs = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}}; for (int i = 0; i < board.length; i++) { for (int j = 0; j < board[0].length; j++) { if (board[i][j] == 'O') { @@ -60,9 +87,7 @@ public void solve(char[][] board) { } public boolean isValid(int x, int y, char[][] board) { - if (x < 0 || x >= board.length || y < 0 || y >= board[0].length) - return false; - return true; + return x >= 0 && x < board.length && y >= 0 && y < board[0].length; } public void solveDFS(char[][] board) { @@ -86,7 +111,7 @@ public void solveDFS(char[][] board) { if (board[m - 1][j] == 'O') boundaryDFS(board, m - 1, j); } - // post-prcessing, turn 'O' to 'X', '*' back to 'O', keep 'X' intact. + // post-processing, turn 'O' to 'X', '*' back to 'O', keep 'X' intact. for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (board[i][j] == 'O') @@ -97,22 +122,21 @@ else if (board[i][j] == '*') } } - // Use DFS algo to turn internal however boundary-connected 'O' to '*'; - //Use DFS algo to turn internal however boundary-connected 'O' to '*'; -private void boundaryDFS(char[][] board, int i, int j) { - if (i < 0 || i > board.length - 1 || j <0 || j > board[0].length - 1 ) - return; - if (board[i][j] == 'O'){ - board[i][j] = '*'; - - boundaryDFS(board, i-1, j); - - boundaryDFS(board, i+1, j); - - boundaryDFS(board, i, j-1); - - boundaryDFS(board, i, j+1); + //Use DFS algo to turn internal however boundary-connected 'O' to '*' + private void boundaryDFS(char[][] board, int i, int j) { + if (i < 0 || i > board.length - 1 || j < 0 || j > board[0].length - 1) + return; + if (board[i][j] == 'O') { + board[i][j] = '*'; + + boundaryDFS(board, i - 1, j); + + boundaryDFS(board, i + 1, j); + + boundaryDFS(board, i, j - 1); + + boundaryDFS(board, i, j + 1); + } } } -} diff --git a/src/geeksforgeeks/TaskLeastInterval.java b/src/geeksforgeeks/TaskLeastInterval.java index 93f50ae..d43926d 100644 --- a/src/geeksforgeeks/TaskLeastInterval.java +++ b/src/geeksforgeeks/TaskLeastInterval.java @@ -2,14 +2,17 @@ import java.util.*; -/*https://leetcode.com/problems/task-scheduler/*/ +/** + * https://leetcode.com/problems/task-scheduler/ + */ + public class TaskLeastInterval { public static int leastInterval(char[] tasks, int n) { Map map = new HashMap<>(); - for (int i = 0; i < tasks.length; i++) { - map.put(tasks[i], map.getOrDefault(tasks[i], 0) + 1); + for (char task : tasks) { + map.put(task, map.getOrDefault(task, 0) + 1); } PriorityQueue> queue = new PriorityQueue<>( (a, b) -> Integer.compare(b.getValue(), a.getValue())); @@ -17,8 +20,8 @@ public static int leastInterval(char[] tasks, int n) { queue.addAll(map.entrySet()); int count = 0; - //At each iteration, we process at most 'n' elements, - //and move forwards exactly n+1 in time (regardless of how many elements we processed: + // At each iteration, we process at most 'n' elements, + // and move forwards exactly n+1 in time (regardless of how many elements we processed: // Read the topmost from the queue and increment the time. Add it to a temp list to be added later. // Add the element back to the queue from the temp list if count is > 0. // if al elements are done, we're done too. @@ -46,7 +49,7 @@ public static int leastInterval(char[] tasks, int n) { } public static void main(String[] args) { - char[] arr = "AAAAAABCDEFG".toCharArray(); + char[] arr = "A".toCharArray(); System.out.println(leastInterval(arr, 2)); } } diff --git a/src/geeksforgeeks/TimeMap.java b/src/geeksforgeeks/TimeMap.java index 5918f2e..df7ba19 100644 --- a/src/geeksforgeeks/TimeMap.java +++ b/src/geeksforgeeks/TimeMap.java @@ -2,6 +2,31 @@ import java.util.HashMap; +/** + * Create a time based key-value store class TimeMap, that supports two operations. + * + * 1. set(string key, string value, int timestamp) + * + * Stores the key and value, along with the given timestamp. + * 2. get(string key, int timestamp) + * + * Returns a value such that set(key, value, timestamp_prev) was called previously, + * with timestamp_prev <= timestamp. + * If there are multiple such values, it returns the one with the largest timestamp_prev. + * If there are no values, it returns the empty string (""). + * + * Input: inputs = ["TimeMap","set","get","get","set","get","get"], inputs = [[],["foo","bar",1],["foo",1],["foo",3],["foo","bar2",4],["foo",4],["foo",5]] + * Output: [null,null,"bar","bar",null,"bar2","bar2"] + * Explanation: + * TimeMap kv; + * kv.set("foo", "bar", 1); // store the key "foo" and value "bar" along with timestamp = 1 + * kv.get("foo", 1); // output "bar" + * kv.get("foo", 3); // output "bar" since there is no value corresponding to foo at timestamp 3 and timestamp 2, then the only value is at timestamp 1 ie "bar" + * kv.set("foo", "bar2", 4); + * kv.get("foo", 4); // output "bar2" + * kv.get("foo", 5); //output "bar2" + */ + class TimeMap { class Node{ @@ -21,14 +46,11 @@ public TimeMap() { } public void set(String key, String value, int timestamp) { + Node node =new Node(value,timestamp); if(map.containsKey(key)){ - Node node=new Node(value,timestamp); node.next=map.get(key); - map.put(key,node); - }else{ - Node temp=new Node(value,timestamp); - map.put(key,temp); } + map.put(key,node); } public String get(String key, int timestamp) { diff --git a/src/geeksforgeeks/TreasureIsland.java b/src/geeksforgeeks/TreasureIsland.java index 0f7c179..9c0fc04 100644 --- a/src/geeksforgeeks/TreasureIsland.java +++ b/src/geeksforgeeks/TreasureIsland.java @@ -3,7 +3,9 @@ import java.util.LinkedList; import java.util.Queue; -// https://leetcode.com/discuss/interview-question/347457/Amazon-or-OA-2019-or-Treasure-Island +/** + * https://leetcode.com/discuss/interview-question/347457/Amazon-or-OA-2019-or-Treasure-Island + */ public class TreasureIsland { private static final int[][] DIRS = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } }; diff --git a/src/geeksforgeeks/TreasureIslandII.java b/src/geeksforgeeks/TreasureIslandII.java index 0525e5a..422723f 100644 --- a/src/geeksforgeeks/TreasureIslandII.java +++ b/src/geeksforgeeks/TreasureIslandII.java @@ -3,7 +3,9 @@ import java.util.ArrayDeque; import java.util.Queue; -/*https://leetcode.com/discuss/interview-question/356150/amazon-oa-2019-shortest-path-from-multiple-sources*/ +/** + * https://leetcode.com/discuss/interview-question/356150/amazon-oa-2019-shortest-path-from-multiple-sources + * */ public class TreasureIslandII { private static final int[][] DIRS = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; diff --git a/src/geeksforgeeks/UnSortedSubArray.java b/src/geeksforgeeks/UnSortedSubArray.java new file mode 100644 index 0000000..a731ca0 --- /dev/null +++ b/src/geeksforgeeks/UnSortedSubArray.java @@ -0,0 +1,53 @@ +package geeksforgeeks; + +/** + * 581. Shortest Unsorted Continuous Subarray + * Given an integer array nums, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order. + * + * Return the shortest such subarray and output its length. + * + * + * + * Example 1: + * + * Input: nums = [2,6,4,8,10,9,15] + * Output: 5 + * Explanation: You need to sort [6, 4, 8, 10, 9] in ascending + * order to make the whole array sorted in ascending order. + */ +public class UnSortedSubArray { + + public static int findUnsortedSubarray(int[] nums) { + if (nums == null) { + return 0; + } + if (nums.length == 0 || nums.length == 1) { + return 0; + } + + int max = Integer.MIN_VALUE; + int end = -2; + //iterate from beginning of array + //find the last element which is smaller than the last seen max from + //its left side and mark it as end + for (int i = 0; i < nums.length; i++) { + max = Math.max(max, nums[i]); + if (nums[i] < max) { + end = i; + } + } + + int min = Integer.MAX_VALUE; + int begin = -1; + //iterate from end of array + //find the last element which is bigger than the last seen min from + //its right side and mark it as begin + for (int i = nums.length - 1; i >= 0; i--) { + min = Math.min(min, nums[i]); + if (nums[i] > min) { + begin = i; + } + } + return end - begin + 1; + } +} diff --git a/src/geeksforgeeks/ValidParenthesesString.java b/src/geeksforgeeks/ValidParenthesesString.java new file mode 100644 index 0000000..326dff9 --- /dev/null +++ b/src/geeksforgeeks/ValidParenthesesString.java @@ -0,0 +1,45 @@ +package geeksforgeeks; + +/** + * Given a string containing only three types of characters: '(', ')' and '*', + * write a function to check whether this string is valid. + * We define the validity of a string by these rules: + * + * Any left parenthesis '(' must have a corresponding right parenthesis ')'. + * Any right parenthesis ')' must have a corresponding left parenthesis '('. + * Left parenthesis '(' must go before the corresponding right parenthesis ')'. + * '*' could be treated as a single right parenthesis ')' or a single left parenthesis '(' or an empty string. + * An empty string is also valid. + * + * Input: "(*))" + * Output: True + * + * Input: "(*)" + * Output: True + */ +public class ValidParenthesesString { + public boolean checkValidString(String s) { + int cmin = 0; + int cmax = 0; // open parentheses count in range [cmin, cmax] + for (char c : s.toCharArray()) { + if (c == '(') { + cmax++; + cmin++; + } else if (c == ')') { + cmax--; + cmin--; + } else if (c == '*') { + cmax++; // if `*` become `(` then openCount++ + cmin--; // if `*` become `)` then openCount-- + // if `*` become `` then nothing happens + // So openCount will be in new range [cmin-1, cmax+1] + } + if (cmax < 0) { + return false; // Currently, don't have enough open parentheses to match close parentheses-> Invalid + } + // For example: ())( + cmin = Math.max(cmin, 0); // It's invalid if open parentheses count < 0 that's why cmin can't be negative + } + return cmin == 0; // Return true if can found `openCount == 0` in range [cmin, cmax] + } +} diff --git a/src/geeksforgeeks/ValidSudoku.java b/src/geeksforgeeks/ValidSudoku.java index e67d31d..5eb644e 100644 --- a/src/geeksforgeeks/ValidSudoku.java +++ b/src/geeksforgeeks/ValidSudoku.java @@ -3,27 +3,25 @@ import java.util.HashSet; import java.util.Set; -/** - * @author i312458 - */ -public class ValidSudoku { - +public class ValidSudoku +{ public boolean isValidSudoku(char[][] board) { - Set seen = new HashSet(); - for (int i = 0; i < 9; ++i) { - for (int j = 0; j < 9; ++j) { - char number = board[i][j]; - if (number != '.') { - if (!seen.add(number + " in row " + i) || !seen.add(number + " in column " + j) || !seen.add( - number + " in block " + i / 3 + '-' + j / 3)) { + Set seen = new HashSet<>(); + + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 9; j++) { + if (board[i][j] != '.') { + char number = board[i][j]; + if (!seen.add(number + "seen in row" + i) || !seen.add(number + "seen in col" + j) + || !seen.add(number + "seen in block" + i / 3 + "-" + j / 3)) { return false; } } } } + return true; } - public static void main(String[] args) { char[][] board = { { '5', '3', '.', '.', '7', '.', '.', '.', '.' }, { '6', '.', '.', '1', '9', '5', '.', '.', '.' }, { '.', '9', '8', '.', '.', '.', '.', '6', '.' }, @@ -34,4 +32,4 @@ public static void main(String[] args) { ValidSudoku vs = new ValidSudoku(); System.out.println(vs.isValidSudoku(board)); } -} +} \ No newline at end of file diff --git a/src/geeksforgeeks/ValidSuduko.java b/src/geeksforgeeks/ValidSuduko.java deleted file mode 100644 index 81f8ece..0000000 --- a/src/geeksforgeeks/ValidSuduko.java +++ /dev/null @@ -1,34 +0,0 @@ -package geeksforgeeks; - -import java.util.HashSet; -import java.util.Set; - -public class ValidSuduko { - public boolean isValidSudoku(char[][] board) { - Set seen = new HashSet<>(); - - for (int i = 0; i < 9; i++) { - for (int j = 0; j < 9; j++) { - if (board[i][j] != '.') { - char number = board[i][j]; - if (!seen.add(number + "seen in row" + i) || !seen.add(number + "seen in col" + j) - || !seen.add(number + "seen in block" + i / 3 + "-" + j / 3)) { - return false; - } - } - } - } - - return true; - } - public static void main(String[] args) { - char[][] board = { { '5', '3', '.', '.', '7', '.', '.', '.', '.' }, - { '6', '.', '.', '1', '9', '5', '.', '.', '.' }, { '.', '9', '8', '.', '.', '.', '.', '6', '.' }, - { '8', '.', '.', '.', '6', '.', '.', '.', '3' }, { '4', '.', '.', '8', '.', '3', '.', '.', '1' }, - { '7', '.', '.', '.', '2', '.', '.', '.', '6' }, { '.', '6', '.', '.', '.', '.', '2', '8', '.' }, - { '.', '.', '.', '4', '1', '9', '.', '.', '5' }, { '.', '.', '.', '.', '8', '.', '.', '7', '9' } }; - - ValidSudoku vs = new ValidSudoku(); - System.out.println(vs.isValidSudoku(board)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/ValidateIpAddresses.java b/src/geeksforgeeks/ValidateIpAddresses.java index 4a17752..e28a7df 100644 --- a/src/geeksforgeeks/ValidateIpAddresses.java +++ b/src/geeksforgeeks/ValidateIpAddresses.java @@ -1,16 +1,40 @@ package geeksforgeeks; +/** + * A valid IPv4 address is an IP in the form "x1.x2.x3.x4" + * where 0 <= xi <= 255 and xi cannot contain leading zeros. + * For example, "192.168.1.1" and "192.168.1.0" are valid IPv4 addresses but "192.168.01.1", + * while "192.168.1.00" and "192.168@1.1" are invalid IPv4 addresses. + * + * A valid IPv6 address is an IP in the form "x1:x2:x3:x4:x5:x6:x7:x8" where: + * + * 1 <= xi.length <= 4 + * xi is a hexadecimal string which may contain digits, + * lower-case English letter ('a' to 'f') and upper-case English letters ('A' to 'F'). + * Leading zeros are allowed in xi. + * For example, "2001:0db8:85a3:0000:0000:8a2e:0370:7334" + * and "2001:db8:85a3:0:0:8A2E:0370:7334" + * are valid IPv6 addresses, while "2001:0db8:85a3::8A2E:037j:7334" + * and "02001:0db8:85a3:0000:0000:8a2e:0370:7334" are invalid IPv6 addresses. + * + * Input: IP = "172.16.254.1" + * Output: "IPv4" + * Explanation: This is a valid IPv4 address, return "IPv4". + * + * Input: IP = "2001:0db8:85a3:0:0:8A2E:0370:7334" + * Output: "IPv6" + * Explanation: This is a valid IPv6 address, return "IPv6". + */ public class ValidateIpAddresses { // the condition for IPv4 is // there should be 4 components separated by 3 dots // each component should have value between 0-9 (base 10) - // public String validIPAddress(String IP) { if(IP==null || IP.length()==0) return "Neither"; if(IP.chars().filter(e->e=='.').count()==3){ - for(String s: IP.split("\\.",-1)){ + for(String s: IP.split("\\.",-1)){ //-1 is for edge case like "1.0.1." if(s.length()==0 || s.length()>4) return "Neither"; if(s.charAt(0)=='0' && s.length()!=1) return "Neither"; for(char c:s.toCharArray()) if(!Character.isDigit(c)) return "Neither"; diff --git a/src/geeksforgeeks/VulgarDecimal.java b/src/geeksforgeeks/VulgarDecimal.java index 9a76c62..f4d1018 100644 --- a/src/geeksforgeeks/VulgarDecimal.java +++ b/src/geeksforgeeks/VulgarDecimal.java @@ -1,6 +1,24 @@ package geeksforgeeks; -/*https://leetcode.com/problems/fraction-to-recurring-decimal/*/ +/** + * https://leetcode.com/problems/fraction-to-recurring-decimal/ + * + * Given two integers representing the numerator and denominator of a fraction, return the fraction in string format. + * + * If the fractional part is repeating, enclose the repeating part in parentheses. + * + * If multiple answers are possible, return any of them. + * + * It is guaranteed that the length of the answer string is less than 104 for all the given inputs. + * + * Input: numerator = 1, denominator = 2 + * Output: "0.5" + * + * Input: numerator = 2, denominator = 1 + * Output: "2" + */ + + import java.util.*; @@ -8,10 +26,10 @@ public class VulgarDecimal { public static String fractionToDecimal(long numerator, long denominator) { if(denominator==0) return null; - boolean isNegative= (numerator < 0 && denominator > 0) || (numerator > 0 && denominator < 0) ? true : false; + boolean isNegative= (numerator < 0 && denominator > 0) || (numerator > 0 && denominator < 0); - long denomiL= Math.abs((long)denominator); - long numerL= Math.abs((long)numerator); + long denomiL= Math.abs(denominator); + long numerL= Math.abs(numerator); Map map= new HashMap<>(); diff --git a/src/internals/HashMapJava8.java b/src/internals/HashMapJava8.java new file mode 100644 index 0000000..7b7a119 --- /dev/null +++ b/src/internals/HashMapJava8.java @@ -0,0 +1,82 @@ +package internals; + +public class HashMapJava8 { + private final Entry[] entries; + private Integer size; + + public HashMapJava8(Entry[] entries, Integer size) { + this.entries = entries; + this.size = size; + } + + public HashMapJava8(int size){ + this.size=size; + this.entries= new Entry[size]; + for(int i=0;i put(K key, V value){ + int hash= getHash(key); + Entry oldEntry= entries[hash]; + Entry newEntry= new Entry(key,value); + newEntry.next=oldEntry; + entries[hash]= newEntry; + size++; + return new HashMapJava8<>(entries,size); + } + +} + +class Entry{ + Object key; + Object value; + Entry next; + public Entry(){ + + } + + public Entry(Object key, Object value) { + this.key = key; + this.value = value; + this.next=null; + } + + public Object getKey() { + return key; + } + + public void setKey(Object key) { + this.key = key; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + public Entry getNext() { + return next; + } + + public void setNext(Entry next) { + this.next = next; + } + + @Override + public String toString() { + return "Entry{" + + "key=" + key + + ", value=" + value + + ", next=" + next + + '}'; + } +} diff --git a/src/java8/Books.txt b/src/java8/Books.txt new file mode 100644 index 0000000..7d652e6 --- /dev/null +++ b/src/java8/Books.txt @@ -0,0 +1,24 @@ +Gulliver's Travels  +Jonathan Swift +Fantasy Fiction +4 +Frankenstein +Mary Shelley +Science Fiction +4 +The Woman in White  +Wilkie Collins +Mystery +4.1 +Alice's Adventures In Wonderland  +Lewis Carroll +Fairy tale +4.1 +Three Men in a Boat  +Jerome K. Jerome +Humorous Fiction +4 +Brave New World  +Aldous Huxley +Science Fiction +4.2 \ No newline at end of file diff --git a/src/java8/CustomCollectors.java b/src/java8/CustomCollectors.java new file mode 100644 index 0000000..41ebacb --- /dev/null +++ b/src/java8/CustomCollectors.java @@ -0,0 +1,20 @@ +package java8; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collector; +import java.util.stream.Collectors; + +public class CustomCollectors { + public static void main(String[] args) { + List numbers = List.of(2,6,8,9,0,1,52,5,61,8,9,96,0,18,23); + + Collector,List> toList= Collector.of(ArrayList::new, //supplier + (list,e)->list.add(e), // Accumulator, List::add + (list1,list2)-> {list1.addAll(list2); return list1;}, // combiner + Collector.Characteristics.IDENTITY_FINISH + + ); + numbers.stream().filter(e->e%2==0).collect(toList); + } +} diff --git a/src/java8/CustomSpliterator.java b/src/java8/CustomSpliterator.java new file mode 100644 index 0000000..2cc3f71 --- /dev/null +++ b/src/java8/CustomSpliterator.java @@ -0,0 +1,314 @@ +package java8; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.sql.Date; +import java.util.*; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +public class CustomSpliterator { + public static void main(String[] args) throws IOException { + Path path = Paths.get("/Users/vignesh_rajarajan/Documents/learning/Problems/src/java8/Books.txt"); + try(Stream lines = Files.lines(path)){ + Spliterator baseSpliterator = lines.spliterator(); + Spliterator spliterator= new BookSpliterator(baseSpliterator); + Stream stream=StreamSupport.stream(spliterator,false); + stream.forEach(System.out::println); + + } + + Path path1 = Paths.get("/Users/vignesh_rajarajan/Documents/learning/Problems/src/java8/EmployeeData.txt"); + + try(Stream lines = Files.lines(path1)){ + Stream words= lines.flatMap(line-> Arrays.stream(line.split(","))); + Spliterator baseSpliterator = words.spliterator(); + Spliterator spliterator= new EmployeeSpliterator(baseSpliterator); + Stream empStream=StreamSupport.stream(spliterator,false); + + List employeeList= empStream.collect(Collectors.toList()); + + System.out.println(employeeList.stream().map(Employee::getName).collect(Collectors.joining(","+"\n"))); + + TreeSet tree=employeeList.stream().collect(Collectors.toCollection(TreeSet::new)); + + Map map=employeeList.stream().collect(Collectors.toMap(Employee::getId,Employee::getName)); + + Map> partitionedList=employeeList.stream().collect(Collectors.partitioningBy(e->e.getGender()=='M')); + + Map> groupByDesignation= employeeList.stream().collect(Collectors.groupingBy(Employee::getDesignation)); + } + } +} + +class Book{ + private String name; + private String author; + private String genre; + private Double rating; + + public Book(String name, String author, String genre, Double rating) { + this.name = name; + this.author = author; + this.genre = genre; + this.rating = rating; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getGenre() { + return genre; + } + + public void setGenre(String genre) { + this.genre = genre; + } + + public Double getRating() { + return rating; + } + + public void setRating(Double rating) { + this.rating = rating; + } + + @Override + public String toString() { + return "Book{" + + "name='" + name + '\'' + + ", author='" + author + '\'' + + ", genre='" + genre + '\'' + + ", rating=" + rating + + '}'; + } +} + +class BookSpliterator implements Spliterator{ + + private String name; + private String author; + private String genre; + private Double rating; + private Spliterator baseSpliterator; + + public BookSpliterator(Spliterator baseSpliterator) { + this.baseSpliterator = baseSpliterator; + } + + @Override + public boolean tryAdvance(Consumer action) { + if(this.baseSpliterator.tryAdvance(name ->this.name=name ) && + this.baseSpliterator.tryAdvance(author->this.author=author) && + this.baseSpliterator.tryAdvance(genre->this.genre=genre) && + this.baseSpliterator.tryAdvance(rating->this.rating=Double.valueOf(rating)) + ){ + action.accept(new Book(this.name, this.author,this.genre,this.rating)); + return true; + } + return false; + } + + @Override + public Spliterator trySplit() { + return null; + } + + @Override + public long estimateSize() { + return baseSpliterator.estimateSize()/4; // because the book txt has 4 lines for each book + } + + @Override + public int characteristics() { + return this.baseSpliterator.characteristics(); + } +} + + class Employee implements Comparable{ + + private int id; + private String name; + private char gender; + private Date dob; + private String city; + private String designation; + private Date joiningDate; + private double salary; + + public Employee(int id, String name, char gender, Date dob, String city, String designation, + Date joiningDate, double salary) { + this.id = id; + this.name = name; + this.gender = gender; + this.dob = dob; + this.city = city; + this.designation = designation; + this.joiningDate = joiningDate; + this.salary = salary; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public char getGender() { + return gender; + } + + public void setGender(char gender) { + this.gender = gender; + } + + public Date getDob() { + return dob; + } + + public void setDob(Date dob) { + this.dob = dob; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getDesignation() { + return designation; + } + + public void setDesignation(String designation) { + this.designation = designation; + } + + public Date getJoiningDate() { + return joiningDate; + } + + public void setJoiningDate(Date joiningDate) { + this.joiningDate = joiningDate; + } + + public double getSalary() { + return salary; + } + + public void setSalary(double salary) { + this.salary = salary; + } + + @Override + public String toString() { + return "Employee [id=" + id + ", name=" + name + ", gender=" + gender + ", dob=" + dob + ", city=" + city + + ", designation=" + designation + ", joiningDate=" + joiningDate + ", salary=" + salary + "]"; + } + + @Override + public int compareTo(Employee o) { + + if(this.id < o.id) + return -1; + else if(this.id > o.id) + return 1; + else + return 0; + } + +} + +class EmployeeSpliterator implements Spliterator { + + private Spliterator wordSpliterator; + private int id; + private String name; + private char gender; + private Date dob; + private String city; + private String designation; + private Date joiningDate; + private double salary; + + + + + public EmployeeSpliterator(Spliterator wordSpliterator) { + this.wordSpliterator = wordSpliterator; + } + + @Override + public boolean tryAdvance(Consumer action) { + + if(this.wordSpliterator.tryAdvance(word -> this.id = Integer.valueOf(word)) + && this.wordSpliterator.tryAdvance(word -> this.name = word) + && this.wordSpliterator.tryAdvance(word -> this.gender = word.charAt(0)) + && this.wordSpliterator.tryAdvance(word -> this.dob = Date.valueOf(word)) + && this.wordSpliterator.tryAdvance(word -> this.city = word) + && this.wordSpliterator.tryAdvance(word -> this.designation = word) + && this.wordSpliterator.tryAdvance(word -> this.joiningDate = Date.valueOf(word)) + && this.wordSpliterator.tryAdvance(word -> this.salary = Double.valueOf(word)) + ) { + action.accept(new Employee(this.id, + this.name, + this.gender, + this.dob, + this.city, + this.designation, + this.joiningDate, + this.salary + )); + return true; + } + + return false; + } + + @Override + public Spliterator trySplit() { + return null; + } + + @Override + public long estimateSize() { + return wordSpliterator.estimateSize()/8; + } + + @Override + public int characteristics() { + return wordSpliterator.characteristics(); + } + +} + + diff --git a/src/java8/DesignPatternJava8.java b/src/java8/DesignPatternJava8.java new file mode 100644 index 0000000..9ded820 --- /dev/null +++ b/src/java8/DesignPatternJava8.java @@ -0,0 +1,76 @@ +package java8; + +import java.util.function.Function; +import java.util.function.UnaryOperator; + +public class DesignPatternJava8 { + public static void main(String[] args) { + ArrayListIteratorPattern listFn= new ArrayListIteratorPattern(5); + listFn.setElements(new Object[]{1,2,3,4,5,6,7}); + listFn.forEach(System.out::println); + + Burger bur=new BurgerShop(burger -> burger.addCheese()).use(new BurgerShop(Burger::addVeggies).use(new Burger())); + System.out.println(bur); + } +} + +class ArrayListIteratorPattern { + Object[] elements ; + public ArrayListIteratorPattern(int n){ + elements = new Object[n]; + } + + public void setElements(Object[] elements){ + this.elements=elements; + } + + public void forEach(Consumer consumer){ + for (Object element : elements) { + consumer.accept(element); + } + } +} + + class Burger { + + private String burgerType; + + public Burger() { + + this.burgerType = ""; + } + + private Burger(String type) { + this.burgerType = type; + } + + public Burger addVeggies() { + System.out.println("Adding vegies to the burger"); + return new Burger(this.burgerType += " Veggie"); + } + + public Burger addCheese() { + System.out.println("Adding cheese to the burger"); + return new Burger(this.burgerType += " Cheese"); + } + + public String toString() { + return String.format("%s", burgerType + " burger"); + } + +} + +class BurgerShop { + + UnaryOperator< Burger> decoration; + + public BurgerShop(UnaryOperator decoration) { + this.decoration = decoration; + } + + public Burger use(Burger baseBurger) { + System.out.println("Base Burger : " + baseBurger); + return decoration.apply(baseBurger); + } + +} diff --git a/src/java8/EmployeeData.txt b/src/java8/EmployeeData.txt new file mode 100644 index 0000000..d752b0b --- /dev/null +++ b/src/java8/EmployeeData.txt @@ -0,0 +1,10 @@ +27827,Richard,M,1988-06-10,Boston,Developer,2017-12-12,60000.00 +27828,John,M,1978-07-11,Boston,Architect,2015-01-01,150000.00 +27829,David,M,1982-09-12,Newyork City,Manager,2015-01-19,145000.00 +27830,Meenal,F,1991-01-13,Austin,Developer,2018-07-05,65000.00 +27831,Ginni,F,1993-06-14,Delhi,Developer,2017-12-12,72000.00 +27832,Tom,M,1988-03-15,Banglore,Developer,2019-01-10,69000.00 +27833,Michael,M,1984-04-16,London,Lead,2018-09-21,87000.00 +27834,Alexa,F,1995-10-29,Newyork City,Developer,2019-10-11,65000.00 +27835,Peter,M,1993-02-09,London,Developer,2019-10-11,63000.00 +27836,Parvati,F,1991-12-14,Jaipur,Lead,2017-06-10,89000.00 \ No newline at end of file diff --git a/src/java8/FunctionalInterfaceExamples.java b/src/java8/FunctionalInterfaceExamples.java new file mode 100644 index 0000000..034db4a --- /dev/null +++ b/src/java8/FunctionalInterfaceExamples.java @@ -0,0 +1,107 @@ +package java8; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.function.Function; + +public class FunctionalInterfaceExamples { + + public static void main(String[] args) { +// FuncInter inter = s -> s.toLowerCase(Locale.ROOT); +// System.out.println(inter.execute("aDkle")); +// +// List names = List.of("anakjc", "cmnsd c", "bdcskjb"); +// Function intfn = String::length; +// List newList = map(names, intfn); +// System.out.println(newList); + +// System.out.println(createFactory(()->Math.random()*100, Double::intValue).create()) + + Consumer c1= s-> System.out.println(s+""+Math.random()*100); + Consumer c2= s-> System.out.println(s+""+Math.random()*99); + Consumer c3= c1.thenAccept(c2); + c3.accept("Hi : "); + + Functional f1= Square::getArea; + Functional f2= Math::sqrt; + + Functional f3= f2.compose(f1); + System.out.println(f3.apply(new Square(10))); + + //currying + Functional>> func= u->v->w->u+v+w; + System.out.println(func.apply(3).apply(4).apply(6)); + + + + } + + private static List map(List names, Function intfn) { + List newList = new ArrayList<>(); + for (T name : names) { + newList.add(intfn.apply(name)); + } + return newList; + } + + public static IFactory createFactory(IProducer producer, IConfigurator configurator) { + return () -> { + return configurator.configure(producer.produce()); + }; + } + +} + +interface FuncInter { + R execute(T t); +} + +interface IFactory { + T create(); +} + +interface IProducer { + T produce(); +} + +interface IConfigurator { + R configure(T t); + +} + +interface Consumer { + void accept(T t); + default Consumer thenAccept(Consumer next){ + return (T t)->{ + this.accept(t); + next.accept(t); + }; + } +} + +@FunctionalInterface +interface Functional{ + R apply(T t); + + default Functional compose(Functional before){ + return (V v)-> this.apply(before.apply(v)); + } +} + +class Square{ + private int area; + + Square(int area){ + this.area=area; + } + public int getArea() { + return area; + } + + public void setArea(int area) { + this.area = area; + } +} + diff --git a/src/linkedLists/Agoda.java b/src/linkedLists/Agoda.java index 9fea7ac..7095fc5 100644 --- a/src/linkedLists/Agoda.java +++ b/src/linkedLists/Agoda.java @@ -16,10 +16,6 @@ public static void main(String[] args) { head.next.next.next.next.next = new Node(6); Agoda agoda = new Agoda(); - - // agoda.findNthNodeFromEnd(head, 4); - // agoda.reversePairNodes(head); -// agoda.reverseKNode(head, null); agoda.slidingWindow(); } diff --git a/src/linkedLists/AllProblems.java b/src/linkedLists/AllProblems.java index 53cdd89..109679c 100644 --- a/src/linkedLists/AllProblems.java +++ b/src/linkedLists/AllProblems.java @@ -4,7 +4,7 @@ public class AllProblems { static Node head; static int size; - static RandomNode randomHead; + static RandomListNode randomHead; public static void main(String[] args) { addNode(2); @@ -56,11 +56,11 @@ private static Node mergeList(Node a, Node b) { private static void cloneRandomLinkedList() { - RandomNode node1 = new RandomNode(1); - RandomNode node2 = new RandomNode(2); - RandomNode node3 = new RandomNode(3); - RandomNode node4 = new RandomNode(4); - RandomNode node5 = new RandomNode(5); + RandomListNode node1 = new RandomListNode(1); + RandomListNode node2 = new RandomListNode(2); + RandomListNode node3 = new RandomListNode(3); + RandomListNode node4 = new RandomListNode(4); + RandomListNode node5 = new RandomListNode(5); randomHead = node1; @@ -76,14 +76,14 @@ private static void cloneRandomLinkedList() { node5.random = node2; // create cloned node between original nodes - RandomNode temp = randomHead; + RandomListNode temp = randomHead; while (null != temp) { - RandomNode rn = new RandomNode(temp.data + 0.5); + RandomListNode rn = new RandomListNode(temp.data + 0.5); rn.next = temp.next; temp.next = rn; temp = rn.next; } - RandomNode assignTemp = randomHead; + RandomListNode assignTemp = randomHead; while (null != assignTemp) { assignTemp.next.random = assignTemp.random.next; @@ -96,7 +96,7 @@ private static void cloneRandomLinkedList() { } - RandomNode tempp = randomHead; + RandomListNode tempp = randomHead; while (tempp != null) { System.out.println(tempp.data); tempp = tempp.next; diff --git a/src/linkedLists/CloneRandomPointerLinkedList.java b/src/linkedLists/CloneRandomPointerLinkedList.java index 1f19ad2..1bd7fed 100644 --- a/src/linkedLists/CloneRandomPointerLinkedList.java +++ b/src/linkedLists/CloneRandomPointerLinkedList.java @@ -1,6 +1,9 @@ package linkedLists; -// Java program to clone a linked list with next +import java.util.HashMap; +import java.util.Map; + +// Java program to clone a linked list with next // and arbit pointers in O(n) time class CloneRandomPointerLinkedList { @@ -27,6 +30,7 @@ static void print(Node start) { // This function clones a given // linked list in O(1) space static Node clone(Node start) { + if(start==null) return null; Node curr = start, temp = null; // insert additional node after @@ -43,13 +47,12 @@ static Node clone(Node start) { // adjust the random pointers of the // newly added nodes - while (curr != null) { - if (curr.next != null) - curr.next.random = (curr.random != null) ? curr.random.next : curr.random; - + while (curr != null && curr.next!=null) { + if (curr.random != null) + curr.next.random = curr.random.next; // move to the next newly added node by // skipping an original node - curr = (curr.next != null) ? curr.next.next : curr.next; + curr =curr.next.next; } Node original = start, copy = start.next; @@ -68,6 +71,28 @@ static Node clone(Node start) { return temp; } + public RandomListNode copyRandomList(RandomListNode head) { + if (head == null) { + return null; + } + + final Map map = new HashMap<>(); + + RandomListNode cur = head; + while(cur != null) { + map.put(cur, new RandomListNode(cur.data)); + cur = cur.next; + } + + for (Map.Entry entry : map.entrySet()) { + final RandomListNode newNode = entry.getValue(); + newNode.next = map.get(entry.getKey().next); + newNode.random = map.get(entry.getKey().random); + } + + return map.get(head); + } + // Driver code public static void main(String[] args) { Node start = new Node(1); @@ -98,5 +123,3 @@ public static void main(String[] args) { } } - -// This code is contributed by Prerna Saini. diff --git a/src/linkedLists/FlattenNestedIterator.java b/src/linkedLists/FlattenNestedIterator.java index 598099c..15c6b25 100644 --- a/src/linkedLists/FlattenNestedIterator.java +++ b/src/linkedLists/FlattenNestedIterator.java @@ -4,48 +4,49 @@ import java.util.Iterator; import java.util.List; -class NestedIterator implements Iterator { +public class FlattenNestedIterator implements Iterator { - List flattenedList; - int index=0; - public NestedIterator(List nestedList) { - flattenedList= new ArrayList(); - populateList(nestedList); - } + List flattenedList; + int index = 0; - @Override - public Integer next() { - Integer temp=flattenedList.get(index); - index++; - return temp; - } + public FlattenNestedIterator(List nestedList) { + flattenedList = new ArrayList<>(); + populateList(nestedList); + } - @Override - public boolean hasNext() { - return flattenedList.size()>index; - } + @Override + public Integer next() { + Integer temp = flattenedList.get(index); + index++; + return temp; + } + + @Override + public boolean hasNext() { + return flattenedList.size() > index; + } - private void populateList(List nestedList){ - if(nestedList==null || nestedList.size()==0) return; - for(int i=0; i nestedList) { + if (nestedList == null || nestedList.size() == 0) return; + for (int i = 0; i < nestedList.size(); i++) { + populateList(nestedList.get(i).getList()); + if (nestedList.get(i).getInteger() != null) flattenedList.add(nestedList.get(i).getInteger()); } } +} - interface NestedInteger { +interface NestedInteger { - public boolean isInteger(); + public boolean isInteger(); - // @return the single integer that this NestedInteger holds, if it holds a single integer - // Return null if this NestedInteger holds a nested list - public Integer getInteger(); + // @return the single integer that this NestedInteger holds, if it holds a single integer + // Return null if this NestedInteger holds a nested list + public Integer getInteger(); - // @return the nested list that this NestedInteger holds, if it holds a nested list - // Return null if this NestedInteger holds a single integer - public List getList(); - } + // @return the nested list that this NestedInteger holds, if it holds a nested list + // Return null if this NestedInteger holds a single integer + public List getList(); +} diff --git a/src/linkedLists/ListNode.java b/src/linkedLists/ListNode.java deleted file mode 100644 index 8401342..0000000 --- a/src/linkedLists/ListNode.java +++ /dev/null @@ -1,15 +0,0 @@ -package geeksforgeeks; - -public class ListNode { - public int val; - public ListNode next; - public ListNode(int x) { val = x; } - - @Override - public String toString() { - return "ListNode{" + - "val=" + val + - ", next=" + next + - '}'; - } -} diff --git a/src/linkedLists/ListNode1.java b/src/linkedLists/ListNode1.java deleted file mode 100644 index 2ad699f..0000000 --- a/src/linkedLists/ListNode1.java +++ /dev/null @@ -1,15 +0,0 @@ -package linkedLists; - -public class ListNode1 { - public int val; - public ListNode next; - public ListNode1(int x) { val = x; } - - @Override - public String toString() { - return "ListNode{" + - "val=" + val + - ", next=" + next + - '}'; - } -} diff --git a/src/linkedLists/RandomListNode.java b/src/linkedLists/RandomListNode.java new file mode 100644 index 0000000..63e1346 --- /dev/null +++ b/src/linkedLists/RandomListNode.java @@ -0,0 +1,35 @@ +package linkedLists; + +public class RandomListNode { + RandomListNode next; + RandomListNode random; + double data; + + public RandomListNode(double d) { + data = d; + } + + public RandomListNode getNext() { + return next; + } + + public void setNext(RandomListNode next) { + this.next = next; + } + + public RandomListNode getRandom() { + return random; + } + + public void setRandom(RandomListNode random) { + this.random = random; + } + + public double getData() { + return data; + } + + public void setData(double data) { + this.data = data; + } +} diff --git a/src/linkedLists/RandomNode.java b/src/linkedLists/RandomNode.java deleted file mode 100644 index 515e8ad..0000000 --- a/src/linkedLists/RandomNode.java +++ /dev/null @@ -1,35 +0,0 @@ -package linkedLists; - -public class RandomNode { - RandomNode next; - RandomNode random; - double data; - - public RandomNode(double d) { - data = d; - } - - public RandomNode getNext() { - return next; - } - - public void setNext(RandomNode next) { - this.next = next; - } - - public RandomNode getRandom() { - return random; - } - - public void setRandom(RandomNode random) { - this.random = random; - } - - public double getData() { - return data; - } - - public void setData(double data) { - this.data = data; - } -} diff --git a/src/linkedLists/ReversePairs.java b/src/linkedLists/ReversePairs.java deleted file mode 100644 index 6806096..0000000 --- a/src/linkedLists/ReversePairs.java +++ /dev/null @@ -1,92 +0,0 @@ -package linkedLists; - -public class ReversePairs { - - static Node head; - - public static void main(String[] args) { - Node head = new Node(1); - head.next = new Node(2); - head.next.next = new Node(3); - head.next.next.next = new Node(4); - head.next.next.next.next = new Node(5); - head.next.next.next.next.next = new Node(6); - head.next.next.next.next.next.next = new Node(7); - - // Node reversePairs = reversePairs(head); - reverseKNodes(head, null); - printReversedPairs(ReversePairs.head); - } - - private static void reverseKNodes(Node node, Node temp) { - if (node == null) - return; - - Node curr = node; - Node prev = null; - Node next = null; - int index = 0; - - while (curr != null && index < 3) { - next = curr.next; - curr.next = prev; - prev = curr; - curr = next; - index++; - } - - if (temp == null) { - head = prev; - } else { - temp.next = prev; - } - - if (curr != null) - reverseKNodes(curr, node); - - } - - private static void printReversedPairs(Node node) { - if (node == null) - return; - while (node != null) { - System.out.println(node.data); - node = node.next; - } - - } - - private static Node reversePairs(Node node) { - - if (node == null || node.next == null) { - return null; - } - - // Initialize previous and current pointers - Node prev = node; - Node curr = node.next; - - node = curr; // Change head before proceeeding - - // Traverse the list - while (true) { - Node next = curr.next; - curr.next = prev; // Change next of current as previous node - - // If next NULL or next is the last node - if (next == null || next.next == null) { - prev.next = next; - break; - } - - // Change next of previous to next next - prev.next = next.next; - - // Update previous and curr - prev = next; - curr = prev.next; - } - return node; - } - -} diff --git a/src/linkedLists/ReversePairsNode.java b/src/linkedLists/ReversePairsNode.java index 8ef7716..48af789 100644 --- a/src/linkedLists/ReversePairsNode.java +++ b/src/linkedLists/ReversePairsNode.java @@ -1,47 +1,54 @@ package linkedLists; public class ReversePairsNode { - public ListNode reversePairs(ListNode head){ - if(head==null) return head; + public ListNode reversePairs(ListNode head) { + if (head == null) return head; - ListNode dummy= new ListNode(-1); - dummy.next= head; - ListNode current= dummy; + ListNode dummy = new ListNode(-1); + dummy.next = head; + ListNode current = dummy; - // {dummy->1->2->3->4->null} + // dummy->1->2->3->4->null //explanation for one loop rest are same. - while(current.next!=null && current.next.next!=null){ + while (current.next != null && current.next.next != null) { // current points to dummy in the beginning. // first -> 1 - ListNode first= current.next; + ListNode first = current.next; //second -> 2 - ListNode second= current.next.next; - - ListNode temp= second.next; + ListNode second = current.next.next; + // temp-> 3 + ListNode third = second.next; // dummy->2 - current.next=second; + current.next = second; //1->3 - first.next=temp; + first.next = third; //2->1 - second.next=first; + second.next = first; // curr=1 - current=first; - // now { dummy->2->1->3->4 } + current = first; + // now dummy->2->1->3->4 } - return dummy.next; + return dummy.next; } + // 1->2->3->4->5->null + public Node reversePairsRec(Node head) { + + if (head == null || head.next == null) { + return head; + } - public ListNode reversePairsRecursion(ListNode head){ - if(head==null || head.next==null) return head; - ListNode next= head.next; + Node next = head.next; // next= 2 + Node temp = head.next.next; // temp= 3 - head.next = reversePairsRecursion(head.next.next); - next.next = head; - return next; + next.next = head; // 2->1 + head = next;// head=2->1 + head.next.next = reversePairsRec(temp); // the rest will be taken care by recursion + return head; } + } diff --git a/src/linkedLists/ReverseSinglyLinkedListWithoutExtraSpace.java b/src/linkedLists/ReverseSinglyLinkedListWithoutExtraSpace.java deleted file mode 100644 index 2122e66..0000000 --- a/src/linkedLists/ReverseSinglyLinkedListWithoutExtraSpace.java +++ /dev/null @@ -1,42 +0,0 @@ -package linkedLists; - -public class ReverseSinglyLinkedListWithoutExtraSpace { - Node root; - - public static void main(String[] args) { - ReverseSinglyLinkedListWithoutExtraSpace list = new ReverseSinglyLinkedListWithoutExtraSpace(); - list.root = new Node(1); - list.root.next = new Node(2); - list.root.next.next = new Node(3); - list.root.next.next.next = new Node(4); - list.root.next.next.next.next = new Node(5); - - reverseLinkedList(list.root); - - } - - private static void printNode(Node root) { - while (root != null) { - System.out.println(root.data); - root = root.next; - } - - } - - private static void reverseLinkedList(Node root) { - if (null == root) { - return; - } - Node prev = root; - Node curr = prev.next; - prev.next = null; - - while (null != prev && null != curr) { - Node temp = curr.next; - curr.next = prev; - prev = curr; - curr = temp; - } - printNode(prev); - } -} diff --git a/src/linkedLists/RotateList.java b/src/linkedLists/RotateList.java index 79945a4..47a2b24 100644 --- a/src/linkedLists/RotateList.java +++ b/src/linkedLists/RotateList.java @@ -14,7 +14,7 @@ public ListNode rotateRight(ListNode head, int k) { tempHead=tempHead.next; } tempHead.next=head; - // if(k%length==0) return head; + // if(k%length==0) return head k%=length; for(int i=0;i snake; - LinkedList queue; - /** Initialize your data structure here. - @param width - screen width - @param height - screen height - @param food - A list of food positions - E.g food = [[1,1], [1,0]] means the first food is positioned at [1,1], the second is at [1,0]. */ - public SnakeGame(int width, int height, int[][] food) { - this.food=food; - snake = new HashSet(); - eaten = 0; - headX =0; - headY =0; - m = height; - n = width; - queue= new LinkedList(); - queue.offer(new int[]{0, 0}); - snake.add("0,0"); - } - - /** Moves the snake. - @param direction - 'U' = Up, 'L' = Left, 'R' = Right, 'D' = Down - @return The game's score after the move. Return -1 if game over. - Game over when snake crosses the screen boundary or bites its body. */ - public int move(String direction) { - if (direction.equals("U")) { - headX --; - } - else if (direction.equals("L")) { - headY --; - } - else if (direction.equals("R")) { - headY ++; - } - else if (direction.equals("D")) { - headX ++; - } - else { - System.out.println("Wrong move"); - } - - if(!isValid(headX,headY)){ - return -1; - } - - return process(headX, headY); - } - - public boolean isValid(int i, int j){ - if(i < 0 || i >= m || j < 0 || j >= n) - return false; - return true; - } - - public int process(int x, int y){ - if(eaten == food.length){ - snake.remove(queue.peek()[0] + "," + queue.peek()[1]); - queue.poll(); - }else if(food[eaten][0]==x && food[eaten][1]==y){ - eaten ++; - }else{ - snake.remove(queue.peek()[0] + "," + queue.peek()[1]); - queue.poll(); - } - - if (snake.contains(x + "," + y)) { - return -1; - } - - snake.add(x + "," + y); - queue.offer(new int[]{x,y}); - - return eaten; - } -} \ No newline at end of file diff --git a/src/multithreading/educative/examples/FutureTaskExample.java b/src/multithreading/educative/examples/FutureTaskExample.java index 2305c3c..42e25af 100644 --- a/src/multithreading/educative/examples/FutureTaskExample.java +++ b/src/multithreading/educative/examples/FutureTaskExample.java @@ -69,7 +69,7 @@ public void run() { // Submit 10 trivial tasks. for (int i = 0; i < 10; i++) { - service.submit(new TrivialTask(i), new Integer(i)); + service.submit(new TrivialTask(i), (i)); } // wait for all tasks to get done diff --git a/src/strings/stringmatching/KMP.java b/src/strings/stringmatching/KMP.java index 64fea89..17a9609 100644 --- a/src/strings/stringmatching/KMP.java +++ b/src/strings/stringmatching/KMP.java @@ -12,11 +12,12 @@ public static void main(String[] args) { System.out.println(kmp(arr, given.toCharArray(), pattern.toCharArray())); } + private static boolean kmp(int[] arr, char[] charArray, char[] cs) { int j = 0; int i = 0; - for (; j < cs.length && i < charArray.length;) { + while (j < cs.length && i < charArray.length) { if (cs[j] == charArray[i]) { j++; i++; @@ -29,11 +30,7 @@ private static boolean kmp(int[] arr, char[] charArray, char[] cs) { } } - if (j == arr.length) { - return true; - } - - return false; + return j == arr.length; } private static int[] formPrefixAndSuffixArray(String pattern) { diff --git a/src/strings/stringmatching/RabinKarp.java b/src/strings/stringmatching/RabinKarp.java index 8fba5cb..e900d05 100644 --- a/src/strings/stringmatching/RabinKarp.java +++ b/src/strings/stringmatching/RabinKarp.java @@ -2,83 +2,59 @@ public class RabinKarp { - public static void main(String[] args) { - String givenValue = "abaaab"; - String input = "aaa"; - -// char[] givenArr = givenValue.toCharArray(); -// char[] inputArr = input.toCharArray(); -// -// int inputHash = createHash(inputArr, inputArr.length); -// int previousValue = 0; -// for (int i = 0; i < (givenArr.length - inputArr.length + 1); i++) { -// previousValue = givenHash(givenArr, i, previousValue); -// if (inputHash == previousValue && matchString(inputArr, givenArr, i)) { -// System.out.println("It exists"); -// } -// } - - rabinKarp(givenValue, input); - } - - private static int givenHash(char[] givenArr, int i, int previousValue) { - - if (previousValue == 0) { - return createHash(givenArr, 3); - } - - int currentValue = previousValue - givenArr[i - 1]; - System.out.println(currentValue + givenArr[i + 2] * 100); - return currentValue + givenArr[i + 2] * 100; - - } - - private static int createHash(char[] inputArr, int length) { - int hash = 0; - double power = 0; - for (int i = 0; i < length; i++) { - hash = hash + (int) Math.pow(10, power++) * inputArr[i]; - } - return hash; - } - - private static boolean matchString(char[] inputArr, char[] givenArr, int i) { - int index = 0; - for (int j = i; j < inputArr.length; j++) { - if (inputArr[index++] != givenArr[j]) { - return false; - } - } - return true; - } - - //the time complexity is O(m + n) - public static int rabinKarp(String t, String s) { - if (s.length() > t.length()) { - return -1; // s is not a substring of t. - } - final int BASE = 26; - int tHash = 0, sHash = 0; // Hash codes for the substring of t and s. - int powerS = 1; // this will be used to calculate the rolling hash when current window moves out - for (int i = 0; i < s.length(); i++) { - powerS = i > 0 ? powerS * BASE : 1; - tHash = tHash * BASE + t.charAt(i); - sHash = sHash * BASE + s.charAt(i); - } - for (int i = s.length(); i < t.length(); i++) { -// Checks the two substrings are actually equal or not, to protect -// against hash collision. - if (tHash == sHash ){ //&& t.substring(i - s.length(), i).equals(s)) { - return i - s.length(); // Found a match. - } -// Uses rolling hash to compute the new hash code. - tHash -= t.charAt(i - s.length()) * powerS; - tHash = tHash * BASE + t.charAt(i); - } -// Tries to match s and t.substring(t.length() - s.lengthO). - if (tHash == sHash){ // && t .substring(t.length() - s.length()).equals(s)){ - return t.length() - s.length(); - } - return -1; - } + private int prime = 101; + + public int patternSearch(char[] text, char[] pattern) { + int m = pattern.length; + int n = text.length; + long patternHash = createHash(pattern, m - 1); + long textHash = createHash(text, m - 1); + for (int i = 1; i <= n - m + 1; i++) { + if (patternHash == textHash && checkEqual(text, i - 1, i + m - 2, pattern, 0, m - 1)) { + return i - 1; + } + if (i < n - m + 1) { + textHash = recalculateHash(text, i - 1, i + m - 1, textHash, m); + } + } + return -1; + } + + private long recalculateHash(char[] str, int oldIndex, int newIndex, long oldHash, int patternLen) { + long newHash = oldHash - str[oldIndex]; + newHash = newHash / prime; + newHash += str[newIndex] * Math.pow(prime, patternLen - 1); + return newHash; + } + + private long createHash(char[] str, int end) { + long hash = 0; + for (int i = 0; i <= end; i++) { + hash += str[i] * Math.pow(prime, i); + } + return hash; + } + + private boolean checkEqual(char[] str1, int start1, int end1, char[] str2, int start2, int end2) { + if (end1 - start1 != end2 - start2) { + return false; + } + while (start1 <= end1 && start2 <= end2) { + if (str1[start1] != str2[start2]) { + return false; + } + start1++; + start2++; + } + return true; + } + + public static void main(String args[]) { + RabinKarp rks = new RabinKarp(); + // System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "sharRoy".toCharArray())); + System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "Roy".toCharArray())); +/* System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "shas".toCharArray())); + System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "usha".toCharArray())); + System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "Tus".toCharArray()));*/ + } } diff --git a/src/trees/BinaryTraversalIterative.java b/src/trees/BinaryTraversalIterative.java new file mode 100644 index 0000000..76a3442 --- /dev/null +++ b/src/trees/BinaryTraversalIterative.java @@ -0,0 +1,62 @@ +package trees; + +import java.util.*; + +/** + * https://leetcode.com/problems/binary-tree-inorder-traversal/ + * https://leetcode.com/problems/binary-tree-preorder-traversal/ + * + */ +public class BinaryTraversalIterative { + public List inorderTraversal(TreeNode root) { + List result = new ArrayList<>(); + if (root == null) return result; + + Deque stack = new ArrayDeque<>(); + TreeNode cur = root; + + while (cur != null || !stack.isEmpty()) { + while (cur != null) { + stack.add(cur); + cur = cur.left; + } + cur = stack.pop(); + result.add(cur.val); + cur = cur.right; + } + + + return result; + } + + + public List preorderTraversal(TreeNode root) { + if (root == null) return new ArrayList<>(); + Deque stack = new ArrayDeque<>(); + stack.push(root); + List list = new LinkedList<>(); + while (!stack.isEmpty()) { + TreeNode temp = stack.pop(); + list.add(temp.val); + if (temp.right != null) stack.push(temp.right); + if (temp.left != null) stack.push(temp.left); + } + + return list; + } + + public List postorderTraversal(TreeNode root) { + if(root==null) return new ArrayList<>(); + Deque stack = new ArrayDeque<>(); + LinkedList result= new LinkedList<>(); + stack.push(root); + while(!stack.isEmpty()){ + TreeNode temp= stack.pop(); + result.addFirst(temp.val); + if(temp.left!=null) stack.push(temp.left); + if(temp.right!=null) stack.push(temp.right); + } + + return result; + } +} \ No newline at end of file diff --git a/src/trees/LCA.java b/src/trees/LCA.java new file mode 100644 index 0000000..41e6503 --- /dev/null +++ b/src/trees/LCA.java @@ -0,0 +1,67 @@ +package trees; + +public class LCA { + + /** + *Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. + * + * According to the definition of LCA on Wikipedia: + * “The lowest common ancestor is defined between + * two nodes p and q as the lowest node in T that has both p and q as descendants + * (where we allow a node to be a descendant of itself).” + * p and q will exist in the tree. + */ + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if(root==null) return null; + if(root.val==p.val || root.val==q.val) return root; + + TreeNode left=lowestCommonAncestor( root.left, p,q); + TreeNode right= lowestCommonAncestor(root.right,p,q); + + if(left!=null && right!=null ) return root; + if(left!=null) return left; + return right; + + } + + /** + * the variation with the LCA is that + * It is guaranteed that both p and q are in the tree. + * A node can be a descendant of itself. + * In the case of p = 5 and q = 4: + * Because of the premises, we can return either p OR q as soon as we find one of them. + * But for this question, the premises are different: + * It is NOT guaranteed that both p and q are in the tree. + * A node can still be a descendant of itself. + * Hence, + * We need a way to record if we've seen both p and q + * We need to traverse the entire tree even after we've found one of them. + * Here are the differences in code. The rest is the same. + * Use either boolean or integers as flags + * Keep traversing down the entire tree. If you return early, the above example would be null, + * because the code stops when it finds 5 and does not keep searching for 4. + */ + + boolean pFound = false; + boolean qFound = false; + + public TreeNode lowestCommonAncestorII(TreeNode root, TreeNode p, TreeNode q) { + TreeNode LCA = LCA(root, p, q); + return pFound && qFound ? LCA : null; + } + + public TreeNode LCA(TreeNode root, TreeNode p, TreeNode q) { + if (root == null) return root; + TreeNode left = LCA(root.left, p, q); + TreeNode right = LCA(root.right, p, q); + if (root == p) { + pFound = true; + return root; + } + if (root == q) { + qFound = true; + return root; + } + return left == null ? right : right == null ? left : root; + } +} diff --git a/src/trees/PathSum.java b/src/trees/PathSum.java new file mode 100644 index 0000000..ed1fa37 --- /dev/null +++ b/src/trees/PathSum.java @@ -0,0 +1,85 @@ +package trees; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class PathSum { + + List list= new ArrayList<>(); + int count=0; + + /** + * Given the root of a binary tree and an integer targetSum, + * return true if the tree has a root-to-leaf + * path such that adding up all the values along the path equals targetSum. + * + * A leaf is a node with no children. + */ + public boolean hasPathSum(TreeNode root, int targetSum) { + if(root==null) return false; + if(root.left==null && root.right==null && targetSum-root.val==0) return true; + boolean left= hasPathSum(root.left, targetSum-root.val); + boolean right= hasPathSum(root.right, targetSum-root.val); + + return left||right; + } + + /** + * Given the root of a binary tree and an integer targetSum, + * return all root-to-leaf paths where each path's sum equals targetSum. + * + * A leaf is a node with no children. + * + * Input: root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22 + * Output: [[5,4,11,2],[5,8,4,5]] + */ + + public List> pathSum(TreeNode root, int targetSum) { + if(root==null) return Collections.emptyList(); + List> result= new ArrayList<>(); + pathSumUtil(root, result, targetSum, new ArrayList<>()); + return result; + } + + public void pathSumUtil(TreeNode root,List> result,int targetSum, List tempList){ + if(root==null) return ; + tempList.add(root.val); + if(root.left==null && root.right==null && targetSum-root.val==0){ + result.add(new ArrayList<>(tempList)); + } + + pathSumUtil(root.left,result,targetSum-root.val,tempList); + pathSumUtil(root.right,result,targetSum-root.val,tempList); + tempList.remove(tempList.size()-1); + } + + /** + * You are given a binary tree in which each node contains an integer value. + * + * Find the number of paths that sum to a given value. + * + * The path does not need to start or end at the root or a leaf, + * but it must go downwards (traveling only from parent nodes to child nodes). + * + * The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000. + */ + public int pathSumIII(TreeNode root, int sum) { + if(root==null) return 0; + list.add(root.val); + pathSumIII(root.left,sum); + pathSumIII(root.right,sum); + + int k=0; + for(int i=list.size()-1;i>=0;i--){ // coming in reverse order, inorder to avoid considering + // head node + k+=list.get(i); + if(sum==k){ + count++; + } + } + + list.remove(list.size()-1); + return count; + } +} diff --git a/src/trees/RootToLeafPaths.java b/src/trees/RootToLeafPaths.java new file mode 100644 index 0000000..4877342 --- /dev/null +++ b/src/trees/RootToLeafPaths.java @@ -0,0 +1,26 @@ +package trees; + +import java.util.LinkedList; +import java.util.List; + +public class RootToLeafPaths { + public void construct_paths(TreeNode root, String path, List paths) { + if (root != null) { + path += Integer.toString(root.val); + if ((root.left == null) && (root.right == null)) // if reach a leaf + paths.add(path); // update paths + else { + path += "->"; // extend the current path + construct_paths(root.left, path, paths); + construct_paths(root.right, path, paths); + } + } + } + + public List binaryTreePaths(TreeNode root) { + LinkedList paths = new LinkedList<>(); + construct_paths(root, "", paths); + return paths; + } +} + diff --git a/src/trees/TreeNode.java b/src/trees/TreeNode.java new file mode 100644 index 0000000..23d7fbd --- /dev/null +++ b/src/trees/TreeNode.java @@ -0,0 +1,15 @@ +package trees; + +class TreeNode { + TreeNode left; + TreeNode right; + int val; + + public TreeNode(int val) { + this.val = val; + } + + public String toString() { + return val + ""; + } +} \ No newline at end of file From 74b818b97814091cb7b51943a760e38d21093102 Mon Sep 17 00:00:00 2001 From: Vignesh Date: Thu, 8 Apr 2021 20:53:21 +0530 Subject: [PATCH 39/51] adding code comments --- src/geeksforgeeks/MedianOfTwoSortedArrays.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/geeksforgeeks/MedianOfTwoSortedArrays.java b/src/geeksforgeeks/MedianOfTwoSortedArrays.java index 7eae057..e0ae327 100644 --- a/src/geeksforgeeks/MedianOfTwoSortedArrays.java +++ b/src/geeksforgeeks/MedianOfTwoSortedArrays.java @@ -5,7 +5,7 @@ */ public class MedianOfTwoSortedArrays { - public double findMedianSortedArrays(int input1[], int input2[]) { + public double findMedianSortedArrays(int[] input1, int[] input2) { //if input1 length is greater than switch them so that input1 is smaller than input2. if (input1.length > input2.length) { return findMedianSortedArrays(input2, input1); @@ -13,13 +13,23 @@ public double findMedianSortedArrays(int input1[], int input2[]) { int x = input1.length; int y = input2.length; + // the whole idea is to partition the 2 arrays so that the left side and right side has same number of elements + // let's take example A= 1,3,7 and B= 2,6,8,9,10 + // so if we assume both are combined the median would be at 6(6+7/2= 6.5 to be exact) + + // first take (low + high) / 2 for A it'd be 1 in this example. we partition at 1, [1 ||, 3,7] (1 element on left and 2 on right) + // for B we need to do this, {(x + y + 1) / 2 - partitionX} = (3+5+1/2)-1=3 [2,6,8||,9,10] (3 elements on left and 2 on right) + // add the total left and right elements for both arrays would come to be equal 3+1(left partition) and 2+2(right partition) + + // the reason to add 1 ((x + y + 1) / 2 ) is to account for both odd and even lengths + int low = 0; int high = x; while (low <= high) { int partitionX = (low + high) / 2; int partitionY = (x + y + 1) / 2 - partitionX; - //if partitionX is 0 it means nothing is there on left side. Use -INF for maxLeftX + //if partitionX is 0 it means nothing is there on left side to partition. [|| 1] Use -INF for maxLeftX //if partitionX is length of input then there is nothing on right side. Use +INF for minRightX int maxLeftX = (partitionX == 0) ? Integer.MIN_VALUE : input1[partitionX - 1]; int minRightX = (partitionX == x) ? Integer.MAX_VALUE : input1[partitionX]; From 43c1c1089dee39fdc8f8db3609710fee381263c8 Mon Sep 17 00:00:00 2001 From: Vignesh Date: Sun, 18 Apr 2021 18:07:14 +0530 Subject: [PATCH 40/51] binarysearch and java8 --- .../02413cef30175a0fcd6eb85a234590f79bef6049 | 6 - .../044ff579a2d425788b7a2f4e97a5a11953e8bae9 | 0 .../05dbd5d32b30dbcdcf527591e456aaadba20f05e | 6 - .../060822f06d6133b5784cd821cfdf48511478825e | 3 - .../0676228bbbac4c42074e1ff4ba97c1249fb513b2 | 3 - .../06f176bb3d3787688cb5c09cd7a3e45d5133ebfa | 0 .../08a17553ce3a52ef850905abd15ae11cc363cacc | 2 - .../08cc8c659f4e7340223fad18c70b6ca361f089b8 | 4 - .../0954673de04aee8706da6ed743640cb2a00c8b81 | 20 - .../0988901fea7348f562f6caa5844f5747b3e6f627 | 4 - .../09ab1198ac046440a03c191f646446b9b5e9e02a | 0 .../0bd608b214d88a7df9591cbd80aa77a66d84224a | 0 .../0c0b971e3b43c9d312c9f5a2b8420b6ce6203452 | 2 - .../0c38cd56b3993148cbbbe1d4cc8d30b6bbee6364 | 13 - .../0ca2f0ebdc3a048436c667e83b6a27ca328a3656 | 6 - .../0d3c556755d898705ec3fd39cc6837dcc37cdba7 | 10 - .../0d7fed125f73c15dd458f820c3a989243e4b0990 | 0 .../0d9aa29935b4c0023ecc2c8eb842d0f05f290cb1 | 2 - .../0ec296eab96f653bc5f85768989b68b555e09bb8 | 6 - .../1059720e42680dda43bfbeed95eb5996010f5739 | 3 - .../136a47780b7199e061979e001c460d3e209e46f4 | 6 - .../143283ada55cac97af6684e5923a787979185de5 | 5 - .../149d38c68bc3c3be09cfde27a524344e1ceeaae4 | 3 - .../17844b9f60cd8c916af473597ad830d88f828b1b | 4 - .../1784874474953c47a3183aaecdd41c1979e1970a | 3 - .../1896855b3288119d2470dac0551b72c37e234c2d | 3 - .../19726d43c4ff09a5a7a4183f4d0cce6a15e37c21 | 4 - .../1b5154d0c6bef48d028ab65f8b64e00031c3fc2e | 3 - .../1bf885e7a42885c41ea6628016c433a14a11509c | 7 - .../1c42de5e03790a3691af13f522c2a51bfdfc33d7 | 8 - .../1eb2c750c1401c3d80059dffe1f753034408319e | 4 - .../1f17cf221af79c7767ef1d58d48e7ab6e5664680 | 5 - .../217b987a9060d5b8386906eb594c8ab10c0302d9 | 2 - .../21c2b8af8c133e12bb2326a53f0b3fe11e0d56c5 | 0 .../23e587be6e8d0093bfd7b2d4e96bd90bbf7e9f0c | 5 - .../2486e44c6f684742f89a502f40931a950f6a5402 | 6 - .../24cda00756423a40f9efddbbbbb3ffff855ab235 | 3 - .../25cd0275e3f465af71e5993e50d4360d585e04a8 | 7 - .../276408c9b92328ab537152f09ab71103ec9ef723 | 3 - .../2be2c99de12581c3ed22c8c0da7ccec80c446528 | 13 - .../2d2d46322237e79439f834b509745cf228facad6 | 4 - .../2de1b6553a47fdeff9be170ae123424625902f7e | 0 .../2e2af48417f73df2ea3d6a696f60860c55603e50 | 13 - .../2f10ae1afe497d3ab46d2aeef7eb864a7c4f71b0 | 14 - .../2ff08299ef14157c3b869ec0d960486f9f3e8541 | 14 - .../302919d36f07a9e0021304b45ee4024daa606206 | 13 - .../30b50f5172b58071ccf2af28c9acd212d6dbcb27 | 3 - .../31108dcd9c0b903c6e9ed945d5eec698442dd540 | 5 - .../32e1641c502813055e829c1372417d5c18d22d1f | 0 .../3429a973dee382fb3b8f5d1f3efa2287b2a05cf3 | 6 - .../3458c98caffa57eab71d6c70502a21e868d6e9a5 | 9 - .../34a7a54cf20c62973ec28016242f38006ba857e4 | 4 - .../35c8d23cac4fe0fffda07fbc83d36789d7c5c788 | 2 - .../36d006c838fb7bc186cde26f70feca58e52dd69f | 3 - .../39093e1d50a3cf8cc64623725b7f27af72c1ed01 | 0 .../39b54d4cb2dd4421ba9524848e0bc63b48c9cf98 | 7 - .../3c68d7b88cda97740385959ea052cf26aaa21dbc | 2 - .../3eb9ebfd897a1628339b6eeefc615ebb5f41ac1c | 7 - .../3f87dcb80de796da40cadb298a96aa21955be4be | 11 - .../438b0c52f32af5295e4f3e7c4dabaec112d6707d | 0 .../45b148a84d41dd79888ecd53fd4e2834aa693c10 | 4 - .../46887d7f270c783142b33da323d806a9e2ffe305 | 6 - .../47597e75e2e16c44eb20b6960bcaa8547172dc4b | 2 - .../490f534e6bcc2ebe698aeaa1304a9162e622886a | 9 - .../4a822dd10a07fe6c6df04aa6327ec5ea3bda4345 | 5 - .../4c3d1d0048a930367d48920dc5922097f63016b2 | 14 - .../4cf964bf0393956f630bdbf05a38fffcf83fbc43 | 0 .../4d7e0f54d1a7195f31d05b7e8468cbd75d031f6f | 3 - .../4e4edace1c90763d39f11d621742b8b7de97c312 | 5 - .../4e7ced7d1c15914d46cab5b6abb4c88c23e2cf57 | 17 - .../4eef3ea13ea12692aced2f83a04a1662a284a6cd | 0 .../50853889753a88543f0b55734fa23f6c154fe0f2 | 4 - .../51bd15f852ec96bdc4756c19ba651dbb7c9c1e18 | 10 - .../521d253f22544d24e713bbf7b8e8117a32209d21 | 33 -- .../5315826bdd49da230f66d7c14cdcedc66b430c8d | 4 - .../54902737e82750bad416aa831d0660dcaa60cb9f | 2 - .../55a1ffb661d42d82d63b5f0de1548505de2c9ab7 | 2 - .../55dd33c94fff3e8e0dc5bda81e1d9e450722c3ed | 9 - .../584b2727291e811934e2ca890624015c5d5bc231 | 7 - .../59161909235cdf4eabc4ab47d281db816064e81d | 3 - .../59318629e72c767456e10c2de3879f3e83d441c5 | 2 - .../59e020674cdac25bf8b1271c924436bc5cd9f43b | 3 - .../5bbbdd7884856e2a6dd46cce750009b2553c147c | 0 .../5c69625eacf591022fd3879dc258f4d735549679 | 7 - .../5d67ce154ee6aca6392b698e2208eb223d7df71c | 0 .../5ec9c3ac94b5b6f04be9150f268bc126cce46e9d | 18 - .../5fe9adfda999b02670bffd85ef6df9f221ca222c | 8 - .../60423a51e0098d9646492d1bd079122c5f54dffb | 5 - .../60609595fefb9506dceda14dc104f2591e82872c | 12 - .../62d313fe7096f3a77115fed2fe9f83d5926fc58d | 3 - .../64b221a66f1496003a5d8aea4c84fd01d5103cf2 | 3 - .../670420e71db85c57c9598cf90bfbf68d55486289 | 0 .../67c560deb798bf508a2658b752804d6e646a04ac | 0 .../69e07df6c10aaa52d6ab9202728935187d4d14c1 | 6 - .../69f02f3300af17ee88fd70190ba44deb5e66022f | 2 - .../6cafccccbfb9a042d66b7d8bdea3accf3d93ec10 | 7 - .../6d86d886bd98341bd15e4e9d19a95e62ba6f5310 | 7 - .../6dd807d1e87d9d35862b6ef10b4a9d0be786061f | 3 - .../6e2c8faac8ddadeac7a904aa2fa610f2b84c4d1d | 4 - .../6eb84760361c7035c7217a2cd038360dde7d232a | 12 - .../6f55ab504bd6aafa1105e8877129534284d98ec5 | 3 - .../70380012b3eac984a54b37d3a598185ea1b57051 | 2 - .../708e8a902e314d073a0e87ef445a04a96d86b1cb | 4 - .../71e925c1a83276b4786a85afd698c45c38424527 | 0 .../72e0ca1cee0b977b2b344fd5a79b341235f5fdea | 3 - .../75609b2382f37e28838a2752e2799514ac77b1b7 | 0 .../75c2deec75c0c6f2ccf099d39375f45a4350b31d | 0 .../7637119ca0c7e7513315888e4b74b0d9f9ea09f8 | 23 - .../7693171164aea4689cdbd1bf37dec710418e27bd | 7 - .../76b8a06086472bdb49b025ab167e84fef86f4a3b | 14 - .../78d3bfc8f08da07a8446e71a09c808dd472391cd | 3 - .../78d5cf638c3900a8809f4c08fa05525ffc949d48 | 2 - .../7915b6ad787ff08fb14ae1de2020ae03f9f88ce1 | 2 - .../797ddbdc19d41832f821798ea9d5cec505a8c6ed | 6 - .../79f0810ffdf1de3e9a0d984b5498027cccac4ab7 | 10 - .../7a8a1c44c6b0563a04200fef9e40927e0f1271d7 | 10 - .../7ad7d4ced5997f6767524238a9b3c7dd79e0edc7 | 2 - .../7c156ecd69407c49ae6a0e3fb43c7282b5208870 | 19 - .../7c412755c7d42401fc40386bc9745de5d37842b7 | 4 - .../7c8d86a076f2b7efe379ba510fa19b44123fbc48 | 7 - .../7cd521c281506d65676d30f1e5e6b10d61014bff | 4 - .../7d5d49b4053294734a93120987f5e14834d39c03 | 0 .../7d8b3138576e69d6ae4a13883a2d2c2acf9dcbda | 4 - .../7ddeccb03f5aaf2732135b1293415dca7e5202ba | 9 - .../7ddf6872fd6bf4c1e7b1ae0fd344cf87b3d34390 | 4 - .../7e1eec49595d8bd917ef0502f3368f425e66d53f | 3 - .../7ff5c5295d63667ae68fd986dbb9d0cba7f89676 | 35 -- .../811bf5770f4b9a52cccbb8a2bc44cb9aea7006e1 | 3 - .../81f6990775833bc7a1f3dc9cff576c7eeb337b30 | 12 - .../854bf6adae0c1b91abeb01f54d55e06f860ae611 | 0 .../85a40d1fc6955c89664c72f9499d4e9d9ad52d12 | 3 - .../86c65eefc86bd360c961dbfa76a30ee8e639600c | 4 - .../8791d113c90b5eaaac31a3f73365f228ccab67a9 | 13 - .../87b7e577000487846e8cf343b51a4785895b5284 | 17 - .../8d00cdd75ea020080139231991fe691f54829a6f | 7 - .../8d432008c50bd81945c726fc4fa4011b5f3cdeb8 | 5 - .../8deb1250efdff63bc54eccf442a5d81017fb5a91 | 11 - .../8f0c2c2e40c00e189a33e5a1efefb1f505d93e51 | 0 .../90fc93692a5f9497dd5e983b820a77af574b4f2d | 3 - .../93d8338afc0b4e089e1907278da7bf042677e038 | 6 - .../943e4a327d3d604114b9d153e8fbc7f82140e972 | 2 - .../94de9101791f300f5f045f7c1a6c683a04219238 | 6 - .../953e63705cfbbd4a09dfad3f29dea40ab5fe7ff2 | 0 .../965b9e65f64f5874cdd3e9b20c2a4176b623aa66 | 2 - .../97322aeb00bdf644e441c930ac44ff2638e9c029 | 5 - .../9a1445284accdd0dba931043e9ade05710eba02a | 5 - .../9abfcca74229ce228ecb787ef734190cd947b551 | 2 - .../9bc14aa00d10fe023b2b8d177b0e82500595950f | 2 - .../9cdb02ac233c38ebddceb77d619aeb63b1d9f375 | 4 - .../9d23d4925c24d78878928266297f3a210403bc62 | 5 - .../9fb08af16a5cfd6245213adb4c42fb567a3c9efc | 3 - .../a22b2aaaab602853f378409c46ff3fc2ea67f4f9 | 5 - .../a26c7f2d6488200d04dda1879fa7cf1a591938fc | 6 - .../a7d8f39c4fb7dd38248b39e94a72d635a9de8663 | 3 - .../a8b8e2ec0c9608fc4d71e432a87bd11aa2260bc1 | 14 - .../a9daa9cfd2e7140e183972abd81f24e28474d666 | 0 .../aa09ec4fc101259d9891db26466cfedddd2389c7 | 3 - .../ab040245dbd6fc7a725a13c517d1af253cbf35ca | 11 - .../acbcff90fe83bcccdf5648be0b80bf5c42dcd9f6 | 8 - .../b03a5054228f65413aa1d15e490c3e97e1abb04c | 8 - .../b273fb7280da68b2da19101e0b89eacee9f04988 | 0 .../b471983e4f82be2c21f03fda9fac9f82e002ef9a | 2 - .../b4e4119d524d7351aebd531ec8cb53a23a1ac1e9 | 18 - .../b4f39d67d9de4608cd87e4dcf9289d90e8426afa | 0 .../b6c1195fb748ab6c0ca41ce155a65aa4cb71f0de | 0 .../b941e0faf1b7bf5355e2fb091b588116886b2b1f | 6 - .../b97ff9eace6e02d384c2a08508f266f49c98e7d7 | 0 .../bab1177aae82bae10cefebec36321b50cc9863dd | 2 - .../bacb4ca599e79973d65328cae755ba3d19118726 | 2 - .../be2572a20f9be978d7a71d1287114fb4ff15b13d | 9 - .../be302c9a02a91127c1fdb0d06f31e040af135e0d | 2 - .../bfa96acc23a70c4176888cc734f0ed024d58cd11 | 2 - .../c01934cb5fa257e80d4ca5b638e3368911554fa3 | 5 - .../c143649f5f79ee59eeaf759d7c59d30a04b1b2e4 | 11 - .../c3032b48e4ef1bd96f5a6b5edc7b3be667771ef4 | 12 - .../c3787c9e8a12aefd03ab77af47b5e791b11a17cd | 2 - .../c3efcf971bcd2594a5f97c390f85e00b33cd9cae | 3 - .../c52b8e9da047be598f23f84cc46450905debb33e | 9 - .../c5553fd280cb7748f9571fa19a14e95f31ea5799 | 0 .../c62619dffb64c534668fe6a76e536cebc7988e75 | 16 - .../c637172121bfc0463017c09b76d3e81352627086 | 10 - .../ce2102ba5222e19900b98ffba7e9ba9da80dc924 | 4 - .../d1d27f5dd4e699d3dfb94068a3ef5d1f93b3593f | 8 - .../d4f429b6f338057cd98477ca53041510e7d37436 | 17 - .../d7bd3c45b6dfed3dc0e2b67d0376422d497dd1a4 | 0 .../d954c0b73e46581c8182dfca8d1e959c07609d11 | 2 - .../d989b7396837bd36056b8707b4397c3a195f9c12 | 31 -- .../d9932abb4e3590d0146b1c8858c142b360773844 | 4 - .../db0f3d0ef5fbacb1e5c3ab0eb0619194f3332129 | 5 - .../db4b11301e549a2c72d807c8857af1deec98e2a7 | 0 .../dc030f50752c7f549aeae82890f609dcfae221ac | 2 - .../dc1097e5c073dec15c0cd5af906111b9bdc373fc | 12 - .../dc40ea7af000bed4c55ded349d0715bcaf5c04ac | 0 .../dc6ab85997e0d512ee3a215b7164b62abe40a57f | 3 - .../de7d0cef265da93878f6b5f7cfe01f6e2880505c | 0 .../decaeda6f65351241e9bce93272d380c4694934c | 6 - .../dfb461b9b8b626be5fb94112460ae18e7daec236 | 7 - .../e09739bd56c779220e18584ab36c320d95e95971 | 5 - .../e0e9ede19d8a334ff1c389586fef1e956eba66e8 | 0 .../e2d72fcabf2c4213dd335cf7fcc762deba66ed5f | 2 - .../e695a046b0a098e84e8767a8fc6ed1ca2a854b65 | 0 .../eb88c9c7f6822ddf49c763288a97bc1044f6d440 | 9 - .../ebdaf2cd52164235faab36df015081b94c41f09d | 0 .../ecbb925aa85dc41936e15fb40f6a580210c2c7ba | 5 - .../ed068b20b77c39811b1beca2b16bf1526b38cca4 | 9 - .../ef665a8ed88dd9525d0bc4d83e12b72473a64063 | 2 - .../f0b5a2c268bd0886cd59cea8039c9eba0c2a0c4b | 5 - .../f1260adfa38eb619d43afa7b7901782cdf4af7e1 | 20 - .../f20814b512e3cf21ac88f5a590e0f9a23ee09329 | 6 - .../fb8124c186a26d8804a2503a458d4dcc2ae4ca28 | 3 - .idea/sonarlint/issuestore/index.pb | 421 ------------------ .../Problems/java8/EmployeeData.txt | 10 + src/RandomProblemGenerator.java | 28 ++ src/binarysearch/BinarySearchTemplate.java | 19 + src/binarysearch/FirstBadVersion.java | 25 ++ src/binarysearch/KokoEatingBananas.java | 44 ++ .../KthSmallestInMultiplicationTable.java | 72 +++ .../NumberOfDaysToMakeMBouquets.java | 46 ++ src/binarysearch/SearchInsertPosition.java | 23 + .../ShipPackageWithNDays.java | 0 src/binarysearch/Sqrt.java | 22 + src/binarysearch/SubArraySplitSum.java | 72 +++ .../LongestIncreasingPathInMatrix.java | 64 +++ 223 files changed, 425 insertions(+), 1599 deletions(-) delete mode 100644 .idea/sonarlint/issuestore/0/2/02413cef30175a0fcd6eb85a234590f79bef6049 delete mode 100644 .idea/sonarlint/issuestore/0/4/044ff579a2d425788b7a2f4e97a5a11953e8bae9 delete mode 100644 .idea/sonarlint/issuestore/0/5/05dbd5d32b30dbcdcf527591e456aaadba20f05e delete mode 100644 .idea/sonarlint/issuestore/0/6/060822f06d6133b5784cd821cfdf48511478825e delete mode 100644 .idea/sonarlint/issuestore/0/6/0676228bbbac4c42074e1ff4ba97c1249fb513b2 delete mode 100644 .idea/sonarlint/issuestore/0/6/06f176bb3d3787688cb5c09cd7a3e45d5133ebfa delete mode 100644 .idea/sonarlint/issuestore/0/8/08a17553ce3a52ef850905abd15ae11cc363cacc delete mode 100644 .idea/sonarlint/issuestore/0/8/08cc8c659f4e7340223fad18c70b6ca361f089b8 delete mode 100644 .idea/sonarlint/issuestore/0/9/0954673de04aee8706da6ed743640cb2a00c8b81 delete mode 100644 .idea/sonarlint/issuestore/0/9/0988901fea7348f562f6caa5844f5747b3e6f627 delete mode 100644 .idea/sonarlint/issuestore/0/9/09ab1198ac046440a03c191f646446b9b5e9e02a delete mode 100644 .idea/sonarlint/issuestore/0/b/0bd608b214d88a7df9591cbd80aa77a66d84224a delete mode 100644 .idea/sonarlint/issuestore/0/c/0c0b971e3b43c9d312c9f5a2b8420b6ce6203452 delete mode 100644 .idea/sonarlint/issuestore/0/c/0c38cd56b3993148cbbbe1d4cc8d30b6bbee6364 delete mode 100644 .idea/sonarlint/issuestore/0/c/0ca2f0ebdc3a048436c667e83b6a27ca328a3656 delete mode 100644 .idea/sonarlint/issuestore/0/d/0d3c556755d898705ec3fd39cc6837dcc37cdba7 delete mode 100644 .idea/sonarlint/issuestore/0/d/0d7fed125f73c15dd458f820c3a989243e4b0990 delete mode 100644 .idea/sonarlint/issuestore/0/d/0d9aa29935b4c0023ecc2c8eb842d0f05f290cb1 delete mode 100644 .idea/sonarlint/issuestore/0/e/0ec296eab96f653bc5f85768989b68b555e09bb8 delete mode 100644 .idea/sonarlint/issuestore/1/0/1059720e42680dda43bfbeed95eb5996010f5739 delete mode 100644 .idea/sonarlint/issuestore/1/3/136a47780b7199e061979e001c460d3e209e46f4 delete mode 100644 .idea/sonarlint/issuestore/1/4/143283ada55cac97af6684e5923a787979185de5 delete mode 100644 .idea/sonarlint/issuestore/1/4/149d38c68bc3c3be09cfde27a524344e1ceeaae4 delete mode 100644 .idea/sonarlint/issuestore/1/7/17844b9f60cd8c916af473597ad830d88f828b1b delete mode 100644 .idea/sonarlint/issuestore/1/7/1784874474953c47a3183aaecdd41c1979e1970a delete mode 100644 .idea/sonarlint/issuestore/1/8/1896855b3288119d2470dac0551b72c37e234c2d delete mode 100644 .idea/sonarlint/issuestore/1/9/19726d43c4ff09a5a7a4183f4d0cce6a15e37c21 delete mode 100644 .idea/sonarlint/issuestore/1/b/1b5154d0c6bef48d028ab65f8b64e00031c3fc2e delete mode 100644 .idea/sonarlint/issuestore/1/b/1bf885e7a42885c41ea6628016c433a14a11509c delete mode 100644 .idea/sonarlint/issuestore/1/c/1c42de5e03790a3691af13f522c2a51bfdfc33d7 delete mode 100644 .idea/sonarlint/issuestore/1/e/1eb2c750c1401c3d80059dffe1f753034408319e delete mode 100644 .idea/sonarlint/issuestore/1/f/1f17cf221af79c7767ef1d58d48e7ab6e5664680 delete mode 100644 .idea/sonarlint/issuestore/2/1/217b987a9060d5b8386906eb594c8ab10c0302d9 delete mode 100644 .idea/sonarlint/issuestore/2/1/21c2b8af8c133e12bb2326a53f0b3fe11e0d56c5 delete mode 100644 .idea/sonarlint/issuestore/2/3/23e587be6e8d0093bfd7b2d4e96bd90bbf7e9f0c delete mode 100644 .idea/sonarlint/issuestore/2/4/2486e44c6f684742f89a502f40931a950f6a5402 delete mode 100644 .idea/sonarlint/issuestore/2/4/24cda00756423a40f9efddbbbbb3ffff855ab235 delete mode 100644 .idea/sonarlint/issuestore/2/5/25cd0275e3f465af71e5993e50d4360d585e04a8 delete mode 100644 .idea/sonarlint/issuestore/2/7/276408c9b92328ab537152f09ab71103ec9ef723 delete mode 100644 .idea/sonarlint/issuestore/2/b/2be2c99de12581c3ed22c8c0da7ccec80c446528 delete mode 100644 .idea/sonarlint/issuestore/2/d/2d2d46322237e79439f834b509745cf228facad6 delete mode 100644 .idea/sonarlint/issuestore/2/d/2de1b6553a47fdeff9be170ae123424625902f7e delete mode 100644 .idea/sonarlint/issuestore/2/e/2e2af48417f73df2ea3d6a696f60860c55603e50 delete mode 100644 .idea/sonarlint/issuestore/2/f/2f10ae1afe497d3ab46d2aeef7eb864a7c4f71b0 delete mode 100644 .idea/sonarlint/issuestore/2/f/2ff08299ef14157c3b869ec0d960486f9f3e8541 delete mode 100644 .idea/sonarlint/issuestore/3/0/302919d36f07a9e0021304b45ee4024daa606206 delete mode 100644 .idea/sonarlint/issuestore/3/0/30b50f5172b58071ccf2af28c9acd212d6dbcb27 delete mode 100644 .idea/sonarlint/issuestore/3/1/31108dcd9c0b903c6e9ed945d5eec698442dd540 delete mode 100644 .idea/sonarlint/issuestore/3/2/32e1641c502813055e829c1372417d5c18d22d1f delete mode 100644 .idea/sonarlint/issuestore/3/4/3429a973dee382fb3b8f5d1f3efa2287b2a05cf3 delete mode 100644 .idea/sonarlint/issuestore/3/4/3458c98caffa57eab71d6c70502a21e868d6e9a5 delete mode 100644 .idea/sonarlint/issuestore/3/4/34a7a54cf20c62973ec28016242f38006ba857e4 delete mode 100644 .idea/sonarlint/issuestore/3/5/35c8d23cac4fe0fffda07fbc83d36789d7c5c788 delete mode 100644 .idea/sonarlint/issuestore/3/6/36d006c838fb7bc186cde26f70feca58e52dd69f delete mode 100644 .idea/sonarlint/issuestore/3/9/39093e1d50a3cf8cc64623725b7f27af72c1ed01 delete mode 100644 .idea/sonarlint/issuestore/3/9/39b54d4cb2dd4421ba9524848e0bc63b48c9cf98 delete mode 100644 .idea/sonarlint/issuestore/3/c/3c68d7b88cda97740385959ea052cf26aaa21dbc delete mode 100644 .idea/sonarlint/issuestore/3/e/3eb9ebfd897a1628339b6eeefc615ebb5f41ac1c delete mode 100644 .idea/sonarlint/issuestore/3/f/3f87dcb80de796da40cadb298a96aa21955be4be delete mode 100644 .idea/sonarlint/issuestore/4/3/438b0c52f32af5295e4f3e7c4dabaec112d6707d delete mode 100644 .idea/sonarlint/issuestore/4/5/45b148a84d41dd79888ecd53fd4e2834aa693c10 delete mode 100644 .idea/sonarlint/issuestore/4/6/46887d7f270c783142b33da323d806a9e2ffe305 delete mode 100644 .idea/sonarlint/issuestore/4/7/47597e75e2e16c44eb20b6960bcaa8547172dc4b delete mode 100644 .idea/sonarlint/issuestore/4/9/490f534e6bcc2ebe698aeaa1304a9162e622886a delete mode 100644 .idea/sonarlint/issuestore/4/a/4a822dd10a07fe6c6df04aa6327ec5ea3bda4345 delete mode 100644 .idea/sonarlint/issuestore/4/c/4c3d1d0048a930367d48920dc5922097f63016b2 delete mode 100644 .idea/sonarlint/issuestore/4/c/4cf964bf0393956f630bdbf05a38fffcf83fbc43 delete mode 100644 .idea/sonarlint/issuestore/4/d/4d7e0f54d1a7195f31d05b7e8468cbd75d031f6f delete mode 100644 .idea/sonarlint/issuestore/4/e/4e4edace1c90763d39f11d621742b8b7de97c312 delete mode 100644 .idea/sonarlint/issuestore/4/e/4e7ced7d1c15914d46cab5b6abb4c88c23e2cf57 delete mode 100644 .idea/sonarlint/issuestore/4/e/4eef3ea13ea12692aced2f83a04a1662a284a6cd delete mode 100644 .idea/sonarlint/issuestore/5/0/50853889753a88543f0b55734fa23f6c154fe0f2 delete mode 100644 .idea/sonarlint/issuestore/5/1/51bd15f852ec96bdc4756c19ba651dbb7c9c1e18 delete mode 100644 .idea/sonarlint/issuestore/5/2/521d253f22544d24e713bbf7b8e8117a32209d21 delete mode 100644 .idea/sonarlint/issuestore/5/3/5315826bdd49da230f66d7c14cdcedc66b430c8d delete mode 100644 .idea/sonarlint/issuestore/5/4/54902737e82750bad416aa831d0660dcaa60cb9f delete mode 100644 .idea/sonarlint/issuestore/5/5/55a1ffb661d42d82d63b5f0de1548505de2c9ab7 delete mode 100644 .idea/sonarlint/issuestore/5/5/55dd33c94fff3e8e0dc5bda81e1d9e450722c3ed delete mode 100644 .idea/sonarlint/issuestore/5/8/584b2727291e811934e2ca890624015c5d5bc231 delete mode 100644 .idea/sonarlint/issuestore/5/9/59161909235cdf4eabc4ab47d281db816064e81d delete mode 100644 .idea/sonarlint/issuestore/5/9/59318629e72c767456e10c2de3879f3e83d441c5 delete mode 100644 .idea/sonarlint/issuestore/5/9/59e020674cdac25bf8b1271c924436bc5cd9f43b delete mode 100644 .idea/sonarlint/issuestore/5/b/5bbbdd7884856e2a6dd46cce750009b2553c147c delete mode 100644 .idea/sonarlint/issuestore/5/c/5c69625eacf591022fd3879dc258f4d735549679 delete mode 100644 .idea/sonarlint/issuestore/5/d/5d67ce154ee6aca6392b698e2208eb223d7df71c delete mode 100644 .idea/sonarlint/issuestore/5/e/5ec9c3ac94b5b6f04be9150f268bc126cce46e9d delete mode 100644 .idea/sonarlint/issuestore/5/f/5fe9adfda999b02670bffd85ef6df9f221ca222c delete mode 100644 .idea/sonarlint/issuestore/6/0/60423a51e0098d9646492d1bd079122c5f54dffb delete mode 100644 .idea/sonarlint/issuestore/6/0/60609595fefb9506dceda14dc104f2591e82872c delete mode 100644 .idea/sonarlint/issuestore/6/2/62d313fe7096f3a77115fed2fe9f83d5926fc58d delete mode 100644 .idea/sonarlint/issuestore/6/4/64b221a66f1496003a5d8aea4c84fd01d5103cf2 delete mode 100644 .idea/sonarlint/issuestore/6/7/670420e71db85c57c9598cf90bfbf68d55486289 delete mode 100644 .idea/sonarlint/issuestore/6/7/67c560deb798bf508a2658b752804d6e646a04ac delete mode 100644 .idea/sonarlint/issuestore/6/9/69e07df6c10aaa52d6ab9202728935187d4d14c1 delete mode 100644 .idea/sonarlint/issuestore/6/9/69f02f3300af17ee88fd70190ba44deb5e66022f delete mode 100644 .idea/sonarlint/issuestore/6/c/6cafccccbfb9a042d66b7d8bdea3accf3d93ec10 delete mode 100644 .idea/sonarlint/issuestore/6/d/6d86d886bd98341bd15e4e9d19a95e62ba6f5310 delete mode 100644 .idea/sonarlint/issuestore/6/d/6dd807d1e87d9d35862b6ef10b4a9d0be786061f delete mode 100644 .idea/sonarlint/issuestore/6/e/6e2c8faac8ddadeac7a904aa2fa610f2b84c4d1d delete mode 100644 .idea/sonarlint/issuestore/6/e/6eb84760361c7035c7217a2cd038360dde7d232a delete mode 100644 .idea/sonarlint/issuestore/6/f/6f55ab504bd6aafa1105e8877129534284d98ec5 delete mode 100644 .idea/sonarlint/issuestore/7/0/70380012b3eac984a54b37d3a598185ea1b57051 delete mode 100644 .idea/sonarlint/issuestore/7/0/708e8a902e314d073a0e87ef445a04a96d86b1cb delete mode 100644 .idea/sonarlint/issuestore/7/1/71e925c1a83276b4786a85afd698c45c38424527 delete mode 100644 .idea/sonarlint/issuestore/7/2/72e0ca1cee0b977b2b344fd5a79b341235f5fdea delete mode 100644 .idea/sonarlint/issuestore/7/5/75609b2382f37e28838a2752e2799514ac77b1b7 delete mode 100644 .idea/sonarlint/issuestore/7/5/75c2deec75c0c6f2ccf099d39375f45a4350b31d delete mode 100644 .idea/sonarlint/issuestore/7/6/7637119ca0c7e7513315888e4b74b0d9f9ea09f8 delete mode 100644 .idea/sonarlint/issuestore/7/6/7693171164aea4689cdbd1bf37dec710418e27bd delete mode 100644 .idea/sonarlint/issuestore/7/6/76b8a06086472bdb49b025ab167e84fef86f4a3b delete mode 100644 .idea/sonarlint/issuestore/7/8/78d3bfc8f08da07a8446e71a09c808dd472391cd delete mode 100644 .idea/sonarlint/issuestore/7/8/78d5cf638c3900a8809f4c08fa05525ffc949d48 delete mode 100644 .idea/sonarlint/issuestore/7/9/7915b6ad787ff08fb14ae1de2020ae03f9f88ce1 delete mode 100644 .idea/sonarlint/issuestore/7/9/797ddbdc19d41832f821798ea9d5cec505a8c6ed delete mode 100644 .idea/sonarlint/issuestore/7/9/79f0810ffdf1de3e9a0d984b5498027cccac4ab7 delete mode 100644 .idea/sonarlint/issuestore/7/a/7a8a1c44c6b0563a04200fef9e40927e0f1271d7 delete mode 100644 .idea/sonarlint/issuestore/7/a/7ad7d4ced5997f6767524238a9b3c7dd79e0edc7 delete mode 100644 .idea/sonarlint/issuestore/7/c/7c156ecd69407c49ae6a0e3fb43c7282b5208870 delete mode 100644 .idea/sonarlint/issuestore/7/c/7c412755c7d42401fc40386bc9745de5d37842b7 delete mode 100644 .idea/sonarlint/issuestore/7/c/7c8d86a076f2b7efe379ba510fa19b44123fbc48 delete mode 100644 .idea/sonarlint/issuestore/7/c/7cd521c281506d65676d30f1e5e6b10d61014bff delete mode 100644 .idea/sonarlint/issuestore/7/d/7d5d49b4053294734a93120987f5e14834d39c03 delete mode 100644 .idea/sonarlint/issuestore/7/d/7d8b3138576e69d6ae4a13883a2d2c2acf9dcbda delete mode 100644 .idea/sonarlint/issuestore/7/d/7ddeccb03f5aaf2732135b1293415dca7e5202ba delete mode 100644 .idea/sonarlint/issuestore/7/d/7ddf6872fd6bf4c1e7b1ae0fd344cf87b3d34390 delete mode 100644 .idea/sonarlint/issuestore/7/e/7e1eec49595d8bd917ef0502f3368f425e66d53f delete mode 100644 .idea/sonarlint/issuestore/7/f/7ff5c5295d63667ae68fd986dbb9d0cba7f89676 delete mode 100644 .idea/sonarlint/issuestore/8/1/811bf5770f4b9a52cccbb8a2bc44cb9aea7006e1 delete mode 100644 .idea/sonarlint/issuestore/8/1/81f6990775833bc7a1f3dc9cff576c7eeb337b30 delete mode 100644 .idea/sonarlint/issuestore/8/5/854bf6adae0c1b91abeb01f54d55e06f860ae611 delete mode 100644 .idea/sonarlint/issuestore/8/5/85a40d1fc6955c89664c72f9499d4e9d9ad52d12 delete mode 100644 .idea/sonarlint/issuestore/8/6/86c65eefc86bd360c961dbfa76a30ee8e639600c delete mode 100644 .idea/sonarlint/issuestore/8/7/8791d113c90b5eaaac31a3f73365f228ccab67a9 delete mode 100644 .idea/sonarlint/issuestore/8/7/87b7e577000487846e8cf343b51a4785895b5284 delete mode 100644 .idea/sonarlint/issuestore/8/d/8d00cdd75ea020080139231991fe691f54829a6f delete mode 100644 .idea/sonarlint/issuestore/8/d/8d432008c50bd81945c726fc4fa4011b5f3cdeb8 delete mode 100644 .idea/sonarlint/issuestore/8/d/8deb1250efdff63bc54eccf442a5d81017fb5a91 delete mode 100644 .idea/sonarlint/issuestore/8/f/8f0c2c2e40c00e189a33e5a1efefb1f505d93e51 delete mode 100644 .idea/sonarlint/issuestore/9/0/90fc93692a5f9497dd5e983b820a77af574b4f2d delete mode 100644 .idea/sonarlint/issuestore/9/3/93d8338afc0b4e089e1907278da7bf042677e038 delete mode 100644 .idea/sonarlint/issuestore/9/4/943e4a327d3d604114b9d153e8fbc7f82140e972 delete mode 100644 .idea/sonarlint/issuestore/9/4/94de9101791f300f5f045f7c1a6c683a04219238 delete mode 100644 .idea/sonarlint/issuestore/9/5/953e63705cfbbd4a09dfad3f29dea40ab5fe7ff2 delete mode 100644 .idea/sonarlint/issuestore/9/6/965b9e65f64f5874cdd3e9b20c2a4176b623aa66 delete mode 100644 .idea/sonarlint/issuestore/9/7/97322aeb00bdf644e441c930ac44ff2638e9c029 delete mode 100644 .idea/sonarlint/issuestore/9/a/9a1445284accdd0dba931043e9ade05710eba02a delete mode 100644 .idea/sonarlint/issuestore/9/a/9abfcca74229ce228ecb787ef734190cd947b551 delete mode 100644 .idea/sonarlint/issuestore/9/b/9bc14aa00d10fe023b2b8d177b0e82500595950f delete mode 100644 .idea/sonarlint/issuestore/9/c/9cdb02ac233c38ebddceb77d619aeb63b1d9f375 delete mode 100644 .idea/sonarlint/issuestore/9/d/9d23d4925c24d78878928266297f3a210403bc62 delete mode 100644 .idea/sonarlint/issuestore/9/f/9fb08af16a5cfd6245213adb4c42fb567a3c9efc delete mode 100644 .idea/sonarlint/issuestore/a/2/a22b2aaaab602853f378409c46ff3fc2ea67f4f9 delete mode 100644 .idea/sonarlint/issuestore/a/2/a26c7f2d6488200d04dda1879fa7cf1a591938fc delete mode 100644 .idea/sonarlint/issuestore/a/7/a7d8f39c4fb7dd38248b39e94a72d635a9de8663 delete mode 100644 .idea/sonarlint/issuestore/a/8/a8b8e2ec0c9608fc4d71e432a87bd11aa2260bc1 delete mode 100644 .idea/sonarlint/issuestore/a/9/a9daa9cfd2e7140e183972abd81f24e28474d666 delete mode 100644 .idea/sonarlint/issuestore/a/a/aa09ec4fc101259d9891db26466cfedddd2389c7 delete mode 100644 .idea/sonarlint/issuestore/a/b/ab040245dbd6fc7a725a13c517d1af253cbf35ca delete mode 100644 .idea/sonarlint/issuestore/a/c/acbcff90fe83bcccdf5648be0b80bf5c42dcd9f6 delete mode 100644 .idea/sonarlint/issuestore/b/0/b03a5054228f65413aa1d15e490c3e97e1abb04c delete mode 100644 .idea/sonarlint/issuestore/b/2/b273fb7280da68b2da19101e0b89eacee9f04988 delete mode 100644 .idea/sonarlint/issuestore/b/4/b471983e4f82be2c21f03fda9fac9f82e002ef9a delete mode 100644 .idea/sonarlint/issuestore/b/4/b4e4119d524d7351aebd531ec8cb53a23a1ac1e9 delete mode 100644 .idea/sonarlint/issuestore/b/4/b4f39d67d9de4608cd87e4dcf9289d90e8426afa delete mode 100644 .idea/sonarlint/issuestore/b/6/b6c1195fb748ab6c0ca41ce155a65aa4cb71f0de delete mode 100644 .idea/sonarlint/issuestore/b/9/b941e0faf1b7bf5355e2fb091b588116886b2b1f delete mode 100644 .idea/sonarlint/issuestore/b/9/b97ff9eace6e02d384c2a08508f266f49c98e7d7 delete mode 100644 .idea/sonarlint/issuestore/b/a/bab1177aae82bae10cefebec36321b50cc9863dd delete mode 100644 .idea/sonarlint/issuestore/b/a/bacb4ca599e79973d65328cae755ba3d19118726 delete mode 100644 .idea/sonarlint/issuestore/b/e/be2572a20f9be978d7a71d1287114fb4ff15b13d delete mode 100644 .idea/sonarlint/issuestore/b/e/be302c9a02a91127c1fdb0d06f31e040af135e0d delete mode 100644 .idea/sonarlint/issuestore/b/f/bfa96acc23a70c4176888cc734f0ed024d58cd11 delete mode 100644 .idea/sonarlint/issuestore/c/0/c01934cb5fa257e80d4ca5b638e3368911554fa3 delete mode 100644 .idea/sonarlint/issuestore/c/1/c143649f5f79ee59eeaf759d7c59d30a04b1b2e4 delete mode 100644 .idea/sonarlint/issuestore/c/3/c3032b48e4ef1bd96f5a6b5edc7b3be667771ef4 delete mode 100644 .idea/sonarlint/issuestore/c/3/c3787c9e8a12aefd03ab77af47b5e791b11a17cd delete mode 100644 .idea/sonarlint/issuestore/c/3/c3efcf971bcd2594a5f97c390f85e00b33cd9cae delete mode 100644 .idea/sonarlint/issuestore/c/5/c52b8e9da047be598f23f84cc46450905debb33e delete mode 100644 .idea/sonarlint/issuestore/c/5/c5553fd280cb7748f9571fa19a14e95f31ea5799 delete mode 100644 .idea/sonarlint/issuestore/c/6/c62619dffb64c534668fe6a76e536cebc7988e75 delete mode 100644 .idea/sonarlint/issuestore/c/6/c637172121bfc0463017c09b76d3e81352627086 delete mode 100644 .idea/sonarlint/issuestore/c/e/ce2102ba5222e19900b98ffba7e9ba9da80dc924 delete mode 100644 .idea/sonarlint/issuestore/d/1/d1d27f5dd4e699d3dfb94068a3ef5d1f93b3593f delete mode 100644 .idea/sonarlint/issuestore/d/4/d4f429b6f338057cd98477ca53041510e7d37436 delete mode 100644 .idea/sonarlint/issuestore/d/7/d7bd3c45b6dfed3dc0e2b67d0376422d497dd1a4 delete mode 100644 .idea/sonarlint/issuestore/d/9/d954c0b73e46581c8182dfca8d1e959c07609d11 delete mode 100644 .idea/sonarlint/issuestore/d/9/d989b7396837bd36056b8707b4397c3a195f9c12 delete mode 100644 .idea/sonarlint/issuestore/d/9/d9932abb4e3590d0146b1c8858c142b360773844 delete mode 100644 .idea/sonarlint/issuestore/d/b/db0f3d0ef5fbacb1e5c3ab0eb0619194f3332129 delete mode 100644 .idea/sonarlint/issuestore/d/b/db4b11301e549a2c72d807c8857af1deec98e2a7 delete mode 100644 .idea/sonarlint/issuestore/d/c/dc030f50752c7f549aeae82890f609dcfae221ac delete mode 100644 .idea/sonarlint/issuestore/d/c/dc1097e5c073dec15c0cd5af906111b9bdc373fc delete mode 100644 .idea/sonarlint/issuestore/d/c/dc40ea7af000bed4c55ded349d0715bcaf5c04ac delete mode 100644 .idea/sonarlint/issuestore/d/c/dc6ab85997e0d512ee3a215b7164b62abe40a57f delete mode 100644 .idea/sonarlint/issuestore/d/e/de7d0cef265da93878f6b5f7cfe01f6e2880505c delete mode 100644 .idea/sonarlint/issuestore/d/e/decaeda6f65351241e9bce93272d380c4694934c delete mode 100644 .idea/sonarlint/issuestore/d/f/dfb461b9b8b626be5fb94112460ae18e7daec236 delete mode 100644 .idea/sonarlint/issuestore/e/0/e09739bd56c779220e18584ab36c320d95e95971 delete mode 100644 .idea/sonarlint/issuestore/e/0/e0e9ede19d8a334ff1c389586fef1e956eba66e8 delete mode 100644 .idea/sonarlint/issuestore/e/2/e2d72fcabf2c4213dd335cf7fcc762deba66ed5f delete mode 100644 .idea/sonarlint/issuestore/e/6/e695a046b0a098e84e8767a8fc6ed1ca2a854b65 delete mode 100644 .idea/sonarlint/issuestore/e/b/eb88c9c7f6822ddf49c763288a97bc1044f6d440 delete mode 100644 .idea/sonarlint/issuestore/e/b/ebdaf2cd52164235faab36df015081b94c41f09d delete mode 100644 .idea/sonarlint/issuestore/e/c/ecbb925aa85dc41936e15fb40f6a580210c2c7ba delete mode 100644 .idea/sonarlint/issuestore/e/d/ed068b20b77c39811b1beca2b16bf1526b38cca4 delete mode 100644 .idea/sonarlint/issuestore/e/f/ef665a8ed88dd9525d0bc4d83e12b72473a64063 delete mode 100644 .idea/sonarlint/issuestore/f/0/f0b5a2c268bd0886cd59cea8039c9eba0c2a0c4b delete mode 100644 .idea/sonarlint/issuestore/f/1/f1260adfa38eb619d43afa7b7901782cdf4af7e1 delete mode 100644 .idea/sonarlint/issuestore/f/2/f20814b512e3cf21ac88f5a590e0f9a23ee09329 delete mode 100644 .idea/sonarlint/issuestore/f/b/fb8124c186a26d8804a2503a458d4dcc2ae4ca28 delete mode 100644 .idea/sonarlint/issuestore/index.pb create mode 100644 out/production/Problems/java8/EmployeeData.txt create mode 100644 src/RandomProblemGenerator.java create mode 100644 src/binarysearch/BinarySearchTemplate.java create mode 100644 src/binarysearch/FirstBadVersion.java create mode 100644 src/binarysearch/KokoEatingBananas.java create mode 100644 src/binarysearch/KthSmallestInMultiplicationTable.java create mode 100644 src/binarysearch/NumberOfDaysToMakeMBouquets.java create mode 100644 src/binarysearch/SearchInsertPosition.java rename src/{geeksforgeeks => binarysearch}/ShipPackageWithNDays.java (100%) create mode 100644 src/binarysearch/Sqrt.java create mode 100644 src/binarysearch/SubArraySplitSum.java create mode 100644 src/geeksforgeeks/LongestIncreasingPathInMatrix.java diff --git a/.idea/sonarlint/issuestore/0/2/02413cef30175a0fcd6eb85a234590f79bef6049 b/.idea/sonarlint/issuestore/0/2/02413cef30175a0fcd6eb85a234590f79bef6049 deleted file mode 100644 index 61b4b93..0000000 --- a/.idea/sonarlint/issuestore/0/2/02413cef30175a0fcd6eb85a234590f79bef6049 +++ /dev/null @@ -1,6 +0,0 @@ - -f java:S1173"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ŧ -S java:S1064"9Replace this use of System.out or System.err by a logger.( -k java:S117 "QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ȷ -X -java:S3518"=Make sure "cycle" can't be zero before doing this modulation.(܋ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/0/4/044ff579a2d425788b7a2f4e97a5a11953e8bae9 b/.idea/sonarlint/issuestore/0/4/044ff579a2d425788b7a2f4e97a5a11953e8bae9 deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/0/5/05dbd5d32b30dbcdcf527591e456aaadba20f05e b/.idea/sonarlint/issuestore/0/5/05dbd5d32b30dbcdcf527591e456aaadba20f05e deleted file mode 100644 index b70e6c2..0000000 --- a/.idea/sonarlint/issuestore/0/5/05dbd5d32b30dbcdcf527591e456aaadba20f05e +++ /dev/null @@ -1,6 +0,0 @@ - -m java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(8ŝ. -r java:S117 "QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(՞8ŝ. -= -java:S16596" Declare "t1" on a separate line.(8ŝ. -] java:S125=""bRemove this useless assignment; "root" already holds the assigned value along all execution paths.( -x -java:S4165="bRemove this useless assignment; "root" already holds the assigned value along all execution paths.( -S -java:S1854"8Remove this useless assignment to local variable "root".( -S -java:S1854"8Remove this useless assignment to local variable "root".( -S java:S1065"9Replace this use of System.out or System.err by a logger.( -S java:S106D"9Replace this use of System.out or System.err by a logger.(ً -S java:S106I"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/0/9/0988901fea7348f562f6caa5844f5747b3e6f627 b/.idea/sonarlint/issuestore/0/9/0988901fea7348f562f6caa5844f5747b3e6f627 deleted file mode 100644 index 8aab8fc..0000000 --- a/.idea/sonarlint/issuestore/0/9/0988901fea7348f562f6caa5844f5747b3e6f627 +++ /dev/null @@ -1,4 +0,0 @@ - -< -java:S1659"!Declare "cur" on a separate line.(ϡ -S java:S106,"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/0/9/09ab1198ac046440a03c191f646446b9b5e9e02a b/.idea/sonarlint/issuestore/0/9/09ab1198ac046440a03c191f646446b9b5e9e02a deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/0/b/0bd608b214d88a7df9591cbd80aa77a66d84224a b/.idea/sonarlint/issuestore/0/b/0bd608b214d88a7df9591cbd80aa77a66d84224a deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/0/c/0c0b971e3b43c9d312c9f5a2b8420b6ce6203452 b/.idea/sonarlint/issuestore/0/c/0c0b971e3b43c9d312c9f5a2b8420b6ce6203452 deleted file mode 100644 index 848c840..0000000 --- a/.idea/sonarlint/issuestore/0/c/0c0b971e3b43c9d312c9f5a2b8420b6ce6203452 +++ /dev/null @@ -1,2 +0,0 @@ - -S java:S106:"9Replace this use of System.out or System.err by a logger.(؎ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/0/c/0c38cd56b3993148cbbbe1d4cc8d30b6bbee6364 b/.idea/sonarlint/issuestore/0/c/0c38cd56b3993148cbbbe1d4cc8d30b6bbee6364 deleted file mode 100644 index 1296caa..0000000 --- a/.idea/sonarlint/issuestore/0/c/0c38cd56b3993148cbbbe1d4cc8d30b6bbee6364 +++ /dev/null @@ -1,13 +0,0 @@ - -H -java:S1144"(Remove this unused private "map" method.(8҅/ -[ java:S125"Use isEmpty() to check whether the collection is empty or not.(8˓. -o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ƌ -k -java:S2272"NAdd a "NoSuchElementException" for iteration beyond the end of the collection.(8˓. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/1/4/143283ada55cac97af6684e5923a787979185de5 b/.idea/sonarlint/issuestore/1/4/143283ada55cac97af6684e5923a787979185de5 deleted file mode 100644 index e422680..0000000 --- a/.idea/sonarlint/issuestore/1/4/143283ada55cac97af6684e5923a787979185de5 +++ /dev/null @@ -1,5 +0,0 @@ - -_ -java:S2259"IA "NullPointerException" could be thrown; "slowPointer" is nullable here.( -N java:S106"9Replace this use of System.out or System.err by a logger.( -o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ƌ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/1/4/149d38c68bc3c3be09cfde27a524344e1ceeaae4 b/.idea/sonarlint/issuestore/1/4/149d38c68bc3c3be09cfde27a524344e1ceeaae4 deleted file mode 100644 index b657eeb..0000000 --- a/.idea/sonarlint/issuestore/1/4/149d38c68bc3c3be09cfde27a524344e1ceeaae4 +++ /dev/null @@ -1,3 +0,0 @@ - -N java:S106+"9Replace this use of System.out or System.err by a logger.( -S java:S106("9Replace this use of System.out or System.err by a logger.(ߋ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/1/7/17844b9f60cd8c916af473597ad830d88f828b1b b/.idea/sonarlint/issuestore/1/7/17844b9f60cd8c916af473597ad830d88f828b1b deleted file mode 100644 index 112a5f7..0000000 --- a/.idea/sonarlint/issuestore/1/7/17844b9f60cd8c916af473597ad830d88f828b1b +++ /dev/null @@ -1,4 +0,0 @@ - -: -java:S1659%"Declare "n" on a separate line.(ŗ -N java:S1063"9Replace this use of System.out or System.err by a logger.(ς \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/1/7/1784874474953c47a3183aaecdd41c1979e1970a b/.idea/sonarlint/issuestore/1/7/1784874474953c47a3183aaecdd41c1979e1970a deleted file mode 100644 index 535a91c..0000000 --- a/.idea/sonarlint/issuestore/1/7/1784874474953c47a3183aaecdd41c1979e1970a +++ /dev/null @@ -1,3 +0,0 @@ - -W -java:S1118":Add a private constructor to hide the implicit public one.(8ʵ. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/1/8/1896855b3288119d2470dac0551b72c37e234c2d b/.idea/sonarlint/issuestore/1/8/1896855b3288119d2470dac0551b72c37e234c2d deleted file mode 100644 index faa45ec..0000000 --- a/.idea/sonarlint/issuestore/1/8/1896855b3288119d2470dac0551b72c37e234c2d +++ /dev/null @@ -1,3 +0,0 @@ - -o -java:S3776"RRefactor this method to reduce its Cognitive Complexity from 30 to the 15 allowed.(܏8. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/1/9/19726d43c4ff09a5a7a4183f4d0cce6a15e37c21 b/.idea/sonarlint/issuestore/1/9/19726d43c4ff09a5a7a4183f4d0cce6a15e37c21 deleted file mode 100644 index 9b41109..0000000 --- a/.idea/sonarlint/issuestore/1/9/19726d43c4ff09a5a7a4183f4d0cce6a15e37c21 +++ /dev/null @@ -1,4 +0,0 @@ - -o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ƌ -N java:S106"9Replace this use of System.out or System.err by a logger.( -N java:S106"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/1/b/1b5154d0c6bef48d028ab65f8b64e00031c3fc2e b/.idea/sonarlint/issuestore/1/b/1b5154d0c6bef48d028ab65f8b64e00031c3fc2e deleted file mode 100644 index 2b36aa5..0000000 --- a/.idea/sonarlint/issuestore/1/b/1b5154d0c6bef48d028ab65f8b64e00031c3fc2e +++ /dev/null @@ -1,3 +0,0 @@ - -Q java:S125."Use isEmpty() to check whether the collection is empty or not.(ϗ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/2/4/2486e44c6f684742f89a502f40931a950f6a5402 b/.idea/sonarlint/issuestore/2/4/2486e44c6f684742f89a502f40931a950f6a5402 deleted file mode 100644 index 8629ce8..0000000 --- a/.idea/sonarlint/issuestore/2/4/2486e44c6f684742f89a502f40931a950f6a5402 +++ /dev/null @@ -1,6 +0,0 @@ - -V java:S125"").(Ӭ -t -java:S22938"YReplace the type specification in this constructor call with the diamond operator ("<>").( -t -java:S2293A"YReplace the type specification in this constructor call with the diamond operator ("<>").(€ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/2/7/276408c9b92328ab537152f09ab71103ec9ef723 b/.idea/sonarlint/issuestore/2/7/276408c9b92328ab537152f09ab71103ec9ef723 deleted file mode 100644 index 4ac79f2..0000000 --- a/.idea/sonarlint/issuestore/2/7/276408c9b92328ab537152f09ab71103ec9ef723 +++ /dev/null @@ -1,3 +0,0 @@ - -] -java:S1126C"AReplace this if-then-else statement by a single return statement.(ۗ^8. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/2/b/2be2c99de12581c3ed22c8c0da7ccec80c446528 b/.idea/sonarlint/issuestore/2/b/2be2c99de12581c3ed22c8c0da7ccec80c446528 deleted file mode 100644 index 6bf730f..0000000 --- a/.idea/sonarlint/issuestore/2/b/2be2c99de12581c3ed22c8c0da7ccec80c446528 +++ /dev/null @@ -1,13 +0,0 @@ - -c java:S100;"NRename this method name to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ܳ -V java:S125R"").( -N java:S106""9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/2/f/2ff08299ef14157c3b869ec0d960486f9f3e8541 b/.idea/sonarlint/issuestore/2/f/2ff08299ef14157c3b869ec0d960486f9f3e8541 deleted file mode 100644 index 6d9ef0f..0000000 --- a/.idea/sonarlint/issuestore/2/f/2ff08299ef14157c3b869ec0d960486f9f3e8541 +++ /dev/null @@ -1,14 +0,0 @@ - -S -java:S1197"8Move the array designator from the variable to the type.( -N java:S106,"9Replace this use of System.out or System.err by a logger.( -M -java:S1144N"2Remove this unused private "findSuccessor" method.( -? -java:S1659")Declare "predecessor" on a separate line.( -X -java:S2696"6Make the enclosing method "static" or remove this set.(8. -I -java:S1144A"4Remove this unused private "findPredecessor" method.(ϥ' -S -java:S2696"6Make the enclosing method "static" or remove this set.(8. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/0/302919d36f07a9e0021304b45ee4024daa606206 b/.idea/sonarlint/issuestore/3/0/302919d36f07a9e0021304b45ee4024daa606206 deleted file mode 100644 index df2a551..0000000 --- a/.idea/sonarlint/issuestore/3/0/302919d36f07a9e0021304b45ee4024daa606206 +++ /dev/null @@ -1,13 +0,0 @@ - -9 -java:S16597"#Declare "right" on a separate line.( -7 -java:S16597"!Declare "mid" on a separate line.( -N java:S106 "9Replace this use of System.out or System.err by a logger.( -m -java:S3776Q"RRefactor this method to reduce its Cognitive Complexity from 18 to the 15 allowed.( -N java:S106"9Replace this use of System.out or System.err by a logger.(¸ -m -java:S3776"RRefactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.( -m -java:S37766"RRefactor this method to reduce its Cognitive Complexity from 18 to the 15 allowed.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/0/30b50f5172b58071ccf2af28c9acd212d6dbcb27 b/.idea/sonarlint/issuestore/3/0/30b50f5172b58071ccf2af28c9acd212d6dbcb27 deleted file mode 100644 index 7531bff..0000000 --- a/.idea/sonarlint/issuestore/3/0/30b50f5172b58071ccf2af28c9acd212d6dbcb27 +++ /dev/null @@ -1,3 +0,0 @@ - -W -java:S1126'"AReplace this if-then-else statement by a single return statement.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/1/31108dcd9c0b903c6e9ed945d5eec698442dd540 b/.idea/sonarlint/issuestore/3/1/31108dcd9c0b903c6e9ed945d5eec698442dd540 deleted file mode 100644 index 049f596..0000000 --- a/.idea/sonarlint/issuestore/3/1/31108dcd9c0b903c6e9ed945d5eec698442dd540 +++ /dev/null @@ -1,5 +0,0 @@ - -m -java:S2234"WParameters to knows have the same names but not the same order as the method arguments.(ۋ -< -java:S1172"&Remove these unused method parameters.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/2/32e1641c502813055e829c1372417d5c18d22d1f b/.idea/sonarlint/issuestore/3/2/32e1641c502813055e829c1372417d5c18d22d1f deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/3/4/3429a973dee382fb3b8f5d1f3efa2287b2a05cf3 b/.idea/sonarlint/issuestore/3/4/3429a973dee382fb3b8f5d1f3efa2287b2a05cf3 deleted file mode 100644 index 2b4c78a..0000000 --- a/.idea/sonarlint/issuestore/3/4/3429a973dee382fb3b8f5d1f3efa2287b2a05cf3 +++ /dev/null @@ -1,6 +0,0 @@ - -W -java:S1126"AReplace this if-then-else statement by a single return statement.(‡ -: -java:S1659 "Declare "j" on a separate line.( -S java:S106&"9Replace this use of System.out or System.err by a logger.(Ӑ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/4/3458c98caffa57eab71d6c70502a21e868d6e9a5 b/.idea/sonarlint/issuestore/3/4/3458c98caffa57eab71d6c70502a21e868d6e9a5 deleted file mode 100644 index 5899485..0000000 --- a/.idea/sonarlint/issuestore/3/4/3458c98caffa57eab71d6c70502a21e868d6e9a5 +++ /dev/null @@ -1,9 +0,0 @@ - -A -java:S1659b"Declare "n" on a separate line.(˜8. -o -java:S3776]"RRefactor this method to reduce its Cognitive Complexity from 21 to the 15 allowed.(톅8. -L -java:S10666"/Merge this if statement with the enclosing one.(ۃ8. -t -java:S3776-"RRefactor this method to reduce its Cognitive Complexity from 27 to the 15 allowed.(ǡ8. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/4/34a7a54cf20c62973ec28016242f38006ba857e4 b/.idea/sonarlint/issuestore/3/4/34a7a54cf20c62973ec28016242f38006ba857e4 deleted file mode 100644 index 1e74ed9..0000000 --- a/.idea/sonarlint/issuestore/3/4/34a7a54cf20c62973ec28016242f38006ba857e4 +++ /dev/null @@ -1,4 +0,0 @@ - -f java:S117&"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -o -java:S3012:"YUse "Arrays.copyOf", "Arrays.asList", "Collections.addAll" or "System.arraycopy" instead.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/5/35c8d23cac4fe0fffda07fbc83d36789d7c5c788 b/.idea/sonarlint/issuestore/3/5/35c8d23cac4fe0fffda07fbc83d36789d7c5c788 deleted file mode 100644 index c7594b5..0000000 --- a/.idea/sonarlint/issuestore/3/5/35c8d23cac4fe0fffda07fbc83d36789d7c5c788 +++ /dev/null @@ -1,2 +0,0 @@ - -h java:S100"NRename this method name to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(‚ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/6/36d006c838fb7bc186cde26f70feca58e52dd69f b/.idea/sonarlint/issuestore/3/6/36d006c838fb7bc186cde26f70feca58e52dd69f deleted file mode 100644 index 3b913c3..0000000 --- a/.idea/sonarlint/issuestore/3/6/36d006c838fb7bc186cde26f70feca58e52dd69f +++ /dev/null @@ -1,3 +0,0 @@ - -c -java:S2184 "HCast one of the operands of this multiplication operation to a "double".(Ӻ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/9/39093e1d50a3cf8cc64623725b7f27af72c1ed01 b/.idea/sonarlint/issuestore/3/9/39093e1d50a3cf8cc64623725b7f27af72c1ed01 deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/3/9/39b54d4cb2dd4421ba9524848e0bc63b48c9cf98 b/.idea/sonarlint/issuestore/3/9/39b54d4cb2dd4421ba9524848e0bc63b48c9cf98 deleted file mode 100644 index 1d90f9c..0000000 --- a/.idea/sonarlint/issuestore/3/9/39b54d4cb2dd4421ba9524848e0bc63b48c9cf98 +++ /dev/null @@ -1,7 +0,0 @@ - -N -java:S1197"8Move the array designator from the variable to the type.( -S java:S106"9Replace this use of System.out or System.err by a logger.( -S java:S106"9Replace this use of System.out or System.err by a logger.(Ú -i -java:S1602"SRemove useless curly braces around statement and then remove useless return keyword( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/c/3c68d7b88cda97740385959ea052cf26aaa21dbc b/.idea/sonarlint/issuestore/3/c/3c68d7b88cda97740385959ea052cf26aaa21dbc deleted file mode 100644 index b2e8a5c..0000000 --- a/.idea/sonarlint/issuestore/3/c/3c68d7b88cda97740385959ea052cf26aaa21dbc +++ /dev/null @@ -1,2 +0,0 @@ - -N java:S106 "9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/e/3eb9ebfd897a1628339b6eeefc615ebb5f41ac1c b/.idea/sonarlint/issuestore/3/e/3eb9ebfd897a1628339b6eeefc615ebb5f41ac1c deleted file mode 100644 index 70da440..0000000 --- a/.idea/sonarlint/issuestore/3/e/3eb9ebfd897a1628339b6eeefc615ebb5f41ac1c +++ /dev/null @@ -1,7 +0,0 @@ - -N java:S106"9Replace this use of System.out or System.err by a logger.( -S -java:S1197"8Move the array designator from the variable to the type.( -S -java:S1197"8Move the array designator from the variable to the type.( -N java:S106"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/3/f/3f87dcb80de796da40cadb298a96aa21955be4be b/.idea/sonarlint/issuestore/3/f/3f87dcb80de796da40cadb298a96aa21955be4be deleted file mode 100644 index 16e3f58..0000000 --- a/.idea/sonarlint/issuestore/3/f/3f87dcb80de796da40cadb298a96aa21955be4be +++ /dev/null @@ -1,11 +0,0 @@ - -k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -t -java:S2234 "YParameters to findKth have the same names but not the same order as the method arguments.( -S -java:S1197 "8Move the array designator from the variable to the type.(ľ -N -java:S1197!"8Move the array designator from the variable to the type.( -S java:S106&"9Replace this use of System.out or System.err by a logger.( -M java:S106("9Replace this use of System.out or System.err by a logger.(! \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/3/438b0c52f32af5295e4f3e7c4dabaec112d6707d b/.idea/sonarlint/issuestore/4/3/438b0c52f32af5295e4f3e7c4dabaec112d6707d deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/4/5/45b148a84d41dd79888ecd53fd4e2834aa693c10 b/.idea/sonarlint/issuestore/4/5/45b148a84d41dd79888ecd53fd4e2834aa693c10 deleted file mode 100644 index 29b3651..0000000 --- a/.idea/sonarlint/issuestore/4/5/45b148a84d41dd79888ecd53fd4e2834aa693c10 +++ /dev/null @@ -1,4 +0,0 @@ - -s java:S135"YReduce the total number of break and continue statements in this loop to use at most one.(΢ -m -java:S3776"RRefactor this method to reduce its Cognitive Complexity from 20 to the 15 allowed.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/6/46887d7f270c783142b33da323d806a9e2ffe305 b/.idea/sonarlint/issuestore/4/6/46887d7f270c783142b33da323d806a9e2ffe305 deleted file mode 100644 index bde071e..0000000 --- a/.idea/sonarlint/issuestore/4/6/46887d7f270c783142b33da323d806a9e2ffe305 +++ /dev/null @@ -1,6 +0,0 @@ - -S java:S106-"9Replace this use of System.out or System.err by a logger.( -N -java:S1197"8Move the array designator from the variable to the type.(ӫ -S -java:S1197)"8Move the array designator from the variable to the type.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/7/47597e75e2e16c44eb20b6960bcaa8547172dc4b b/.idea/sonarlint/issuestore/4/7/47597e75e2e16c44eb20b6960bcaa8547172dc4b deleted file mode 100644 index 26bcc4a..0000000 --- a/.idea/sonarlint/issuestore/4/7/47597e75e2e16c44eb20b6960bcaa8547172dc4b +++ /dev/null @@ -1,2 +0,0 @@ - -Z java:S106$"9Replace this use of System.out or System.err by a logger.(8ڐ. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/9/490f534e6bcc2ebe698aeaa1304a9162e622886a b/.idea/sonarlint/issuestore/4/9/490f534e6bcc2ebe698aeaa1304a9162e622886a deleted file mode 100644 index 8c35272..0000000 --- a/.idea/sonarlint/issuestore/4/9/490f534e6bcc2ebe698aeaa1304a9162e622886a +++ /dev/null @@ -1,9 +0,0 @@ - -f java:S117:"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -k java:S117;"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ׅ -k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -k java:S1178"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -k java:S1179"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(捰 -k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/a/4a822dd10a07fe6c6df04aa6327ec5ea3bda4345 b/.idea/sonarlint/issuestore/4/a/4a822dd10a07fe6c6df04aa6327ec5ea3bda4345 deleted file mode 100644 index cef50c8..0000000 --- a/.idea/sonarlint/issuestore/4/a/4a822dd10a07fe6c6df04aa6327ec5ea3bda4345 +++ /dev/null @@ -1,5 +0,0 @@ - -f java:S1174"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(Ҭ -e java:S117 -"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -N java:S106-"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/c/4c3d1d0048a930367d48920dc5922097f63016b2 b/.idea/sonarlint/issuestore/4/c/4c3d1d0048a930367d48920dc5922097f63016b2 deleted file mode 100644 index 2338d4c..0000000 --- a/.idea/sonarlint/issuestore/4/c/4c3d1d0048a930367d48920dc5922097f63016b2 +++ /dev/null @@ -1,14 +0,0 @@ - -> -java:S1659 "#Declare "headY" on a separate line.( -t -java:S2293"YReplace the type specification in this constructor call with the diamond operator ("<>").( -\ -java:S1126?"AReplace this if-then-else statement by a single return statement.( -b -java:S1871J"LThis branch's code block is the same as the block for the branch on line 69.(奞 -: -java:S1659"Declare "n" on a separate line.( -t -java:S2293"YReplace the type specification in this constructor call with the diamond operator ("<>").( -N java:S1064"9Replace this use of System.out or System.err by a logger.(ą \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/c/4cf964bf0393956f630bdbf05a38fffcf83fbc43 b/.idea/sonarlint/issuestore/4/c/4cf964bf0393956f630bdbf05a38fffcf83fbc43 deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/4/d/4d7e0f54d1a7195f31d05b7e8468cbd75d031f6f b/.idea/sonarlint/issuestore/4/d/4d7e0f54d1a7195f31d05b7e8468cbd75d031f6f deleted file mode 100644 index 845c8c5..0000000 --- a/.idea/sonarlint/issuestore/4/d/4d7e0f54d1a7195f31d05b7e8468cbd75d031f6f +++ /dev/null @@ -1,3 +0,0 @@ - -h -java:S3776"RRefactor this method to reduce its Cognitive Complexity from 26 to the 15 allowed.(ʌ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/e/4e4edace1c90763d39f11d621742b8b7de97c312 b/.idea/sonarlint/issuestore/4/e/4e4edace1c90763d39f11d621742b8b7de97c312 deleted file mode 100644 index a9b7527..0000000 --- a/.idea/sonarlint/issuestore/4/e/4e4edace1c90763d39f11d621742b8b7de97c312 +++ /dev/null @@ -1,5 +0,0 @@ - -Y -java:S1596">Replace "Collections.EMPTY_LIST" by "Collections.emptyList()".( -N java:S106/"9Replace this use of System.out or System.err by a logger.( -N java:S1066"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/e/4e7ced7d1c15914d46cab5b6abb4c88c23e2cf57 b/.idea/sonarlint/issuestore/4/e/4e7ced7d1c15914d46cab5b6abb4c88c23e2cf57 deleted file mode 100644 index 230de1f..0000000 --- a/.idea/sonarlint/issuestore/4/e/4e7ced7d1c15914d46cab5b6abb4c88c23e2cf57 +++ /dev/null @@ -1,17 +0,0 @@ - -S java:S106"9Replace this use of System.out or System.err by a logger.(8/ -N -java:S1121".Extract the assignment out of this expression.(Ř8/ -L -java:S1612",Replace this lambda with a method reference.(8/ -r java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.( -I -java:S1121".Extract the assignment out of this expression.(nj8/ -X java:S106"9Replace this use of System.out or System.err by a logger.(8/ -X java:S106"9Replace this use of System.out or System.err by a logger.(8î/ -S java:S106"9Replace this use of System.out or System.err by a logger.(8/ -O -java:S3740"/Provide the parametrized type for this generic.(8/ -X java:S106"9Replace this use of System.out or System.err by a logger.(8/ -S -java:S1128"8Remove this unused import 'java.util.function.Function'.(͞8/ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/e/4eef3ea13ea12692aced2f83a04a1662a284a6cd b/.idea/sonarlint/issuestore/4/e/4eef3ea13ea12692aced2f83a04a1662a284a6cd deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/5/0/50853889753a88543f0b55734fa23f6c154fe0f2 b/.idea/sonarlint/issuestore/5/0/50853889753a88543f0b55734fa23f6c154fe0f2 deleted file mode 100644 index aa4158a..0000000 --- a/.idea/sonarlint/issuestore/5/0/50853889753a88543f0b55734fa23f6c154fe0f2 +++ /dev/null @@ -1,4 +0,0 @@ - -k -java:S1149 "PReplace the synchronized class "Stack" by an unsynchronized one such as "Deque".(ك -S java:S106"9Replace this use of System.out or System.err by a logger.(ޓ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/5/1/51bd15f852ec96bdc4756c19ba651dbb7c9c1e18 b/.idea/sonarlint/issuestore/5/1/51bd15f852ec96bdc4756c19ba651dbb7c9c1e18 deleted file mode 100644 index 7708d85..0000000 --- a/.idea/sonarlint/issuestore/5/1/51bd15f852ec96bdc4756c19ba651dbb7c9c1e18 +++ /dev/null @@ -1,10 +0,0 @@ - -S -java:S1197A"8Move the array designator from the variable to the type.( -f java:S117F"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(Ӡ -f java:S117l"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(낔 -8 -java:S1659 ""Declare "down" on a separate line.(Լ -k java:S117k"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -N java:S106v"9Replace this use of System.out or System.err by a logger.(젝 -S java:S106y"9Replace this use of System.out or System.err by a logger.(Ӽ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/5/2/521d253f22544d24e713bbf7b8e8117a32209d21 b/.idea/sonarlint/issuestore/5/2/521d253f22544d24e713bbf7b8e8117a32209d21 deleted file mode 100644 index 27db97b..0000000 --- a/.idea/sonarlint/issuestore/5/2/521d253f22544d24e713bbf7b8e8117a32209d21 +++ /dev/null @@ -1,33 +0,0 @@ - -o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ƌ -< -java:S3010 "!Remove this assignment of "head".( -V java:S125"").( -t -java:S2293"YReplace the type specification in this constructor call with the diamond operator ("<>").( -t -java:S2293"YReplace the type specification in this constructor call with the diamond operator ("<>").( -D -java:S5413$")Verify that "remove()" is used correctly.(瓗 \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/5/8/584b2727291e811934e2ca890624015c5d5bc231 b/.idea/sonarlint/issuestore/5/8/584b2727291e811934e2ca890624015c5d5bc231 deleted file mode 100644 index d4871d2..0000000 --- a/.idea/sonarlint/issuestore/5/8/584b2727291e811934e2ca890624015c5d5bc231 +++ /dev/null @@ -1,7 +0,0 @@ - -N -java:S1197"8Move the array designator from the variable to the type.( -m -java:S3776"RRefactor this method to reduce its Cognitive Complexity from 19 to the 15 allowed.(̨ -N java:S106A"9Replace this use of System.out or System.err by a logger.( -k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/5/9/59161909235cdf4eabc4ab47d281db816064e81d b/.idea/sonarlint/issuestore/5/9/59161909235cdf4eabc4ab47d281db816064e81d deleted file mode 100644 index 00b09c6..0000000 --- a/.idea/sonarlint/issuestore/5/9/59161909235cdf4eabc4ab47d281db816064e81d +++ /dev/null @@ -1,3 +0,0 @@ - -U -java:S1118":Add a private constructor to hide the implicit public one.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/5/9/59318629e72c767456e10c2de3879f3e83d441c5 b/.idea/sonarlint/issuestore/5/9/59318629e72c767456e10c2de3879f3e83d441c5 deleted file mode 100644 index 9f3e98c..0000000 --- a/.idea/sonarlint/issuestore/5/9/59318629e72c767456e10c2de3879f3e83d441c5 +++ /dev/null @@ -1,2 +0,0 @@ - -S java:S106C"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/5/9/59e020674cdac25bf8b1271c924436bc5cd9f43b b/.idea/sonarlint/issuestore/5/9/59e020674cdac25bf8b1271c924436bc5cd9f43b deleted file mode 100644 index 57e9ffb..0000000 --- a/.idea/sonarlint/issuestore/5/9/59e020674cdac25bf8b1271c924436bc5cd9f43b +++ /dev/null @@ -1,3 +0,0 @@ - -S -java:S1155F">Use isEmpty() to check whether the collection is empty or not.(k \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/5/b/5bbbdd7884856e2a6dd46cce750009b2553c147c b/.idea/sonarlint/issuestore/5/b/5bbbdd7884856e2a6dd46cce750009b2553c147c deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/5/c/5c69625eacf591022fd3879dc258f4d735549679 b/.idea/sonarlint/issuestore/5/c/5c69625eacf591022fd3879dc258f4d735549679 deleted file mode 100644 index f96d173..0000000 --- a/.idea/sonarlint/issuestore/5/c/5c69625eacf591022fd3879dc258f4d735549679 +++ /dev/null @@ -1,7 +0,0 @@ - -S java:S106L"9Replace this use of System.out or System.err by a logger.(ш -h -java:S3776"RRefactor this method to reduce its Cognitive Complexity from 16 to the 15 allowed.(Ő -\ -java:S11261"AReplace this if-then-else statement by a single return statement.( -S java:S106O"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/5/d/5d67ce154ee6aca6392b698e2208eb223d7df71c b/.idea/sonarlint/issuestore/5/d/5d67ce154ee6aca6392b698e2208eb223d7df71c deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/5/e/5ec9c3ac94b5b6f04be9150f268bc126cce46e9d b/.idea/sonarlint/issuestore/5/e/5ec9c3ac94b5b6f04be9150f268bc126cce46e9d deleted file mode 100644 index ab64dc5..0000000 --- a/.idea/sonarlint/issuestore/5/e/5ec9c3ac94b5b6f04be9150f268bc126cce46e9d +++ /dev/null @@ -1,18 +0,0 @@ - -Z java:S106,"9Replace this use of System.out or System.err by a logger.(8. -_ -java:S1854"=Remove this useless assignment to local variable "keywords1".(쫘8ѣ. -D -java:S1481"'Remove this unused "k1" local variable.(8ѣ. -O -java:S1481"-Remove this unused "reviews1" local variable.(񬰖8ѣ. -O -java:S4973*"9Use the "equals" method if value comparison was intended.(Ϝ -S -java:S1854"6Remove this useless assignment to local variable "k1".(8ѣ. -P -java:S1481".Remove this unused "keywords1" local variable.(쫘8ѣ. -S java:S106"9Replace this use of System.out or System.err by a logger.(أ -^ -java:S1854"").( -o -java:S2293""YReplace the type specification in this constructor call with the diamond operator ("<>").( - -java:S1319%"uThe type of the "_neighbors" object should be an interface such as "List" rather than the implementation "ArrayList".( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/8/78d3bfc8f08da07a8446e71a09c808dd472391cd b/.idea/sonarlint/issuestore/7/8/78d3bfc8f08da07a8446e71a09c808dd472391cd deleted file mode 100644 index 0fa9d25..0000000 --- a/.idea/sonarlint/issuestore/7/8/78d3bfc8f08da07a8446e71a09c808dd472391cd +++ /dev/null @@ -1,3 +0,0 @@ - -N java:S106O"9Replace this use of System.out or System.err by a logger.( -S java:S106M"9Replace this use of System.out or System.err by a logger.(ۡ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/8/78d5cf638c3900a8809f4c08fa05525ffc949d48 b/.idea/sonarlint/issuestore/7/8/78d5cf638c3900a8809f4c08fa05525ffc949d48 deleted file mode 100644 index b9c98a1..0000000 --- a/.idea/sonarlint/issuestore/7/8/78d5cf638c3900a8809f4c08fa05525ffc949d48 +++ /dev/null @@ -1,2 +0,0 @@ - -V java:S125""Use isEmpty() to check whether the collection is empty or not.(堧 -S java:S106:"9Replace this use of System.out or System.err by a logger.(Ɲ -[ -java:S1124 -"EReorder the modifiers to comply with the Java Language Specification.( -N java:S106;"9Replace this use of System.out or System.err by a logger.( -S java:S106&"9Replace this use of System.out or System.err by a logger.( -] java:S125"").(֖ -M java:S106("9Replace this use of System.out or System.err by a logger.(s -E -java:S3740"/Provide the parametrized type for this generic.( -E -java:S3740"/Provide the parametrized type for this generic.( -S java:S106P"9Replace this use of System.out or System.err by a logger.( -\ -java:S2142"FEither re-interrupt this method or rethrow the "InterruptedException".(믒 -M java:S106+"9Replace this use of System.out or System.err by a logger.( -E -java:S3740 "/Provide the parametrized type for this generic.(ì -a -java:S2142<"FEither re-interrupt this method or rethrow the "InterruptedException".( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/c/7c412755c7d42401fc40386bc9745de5d37842b7 b/.idea/sonarlint/issuestore/7/c/7c412755c7d42401fc40386bc9745de5d37842b7 deleted file mode 100644 index 74a431c..0000000 --- a/.idea/sonarlint/issuestore/7/c/7c412755c7d42401fc40386bc9745de5d37842b7 +++ /dev/null @@ -1,4 +0,0 @@ - -S java:S1065"9Replace this use of System.out or System.err by a logger.( -J -java:S3740 "/Provide the parametrized type for this generic.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/c/7c8d86a076f2b7efe379ba510fa19b44123fbc48 b/.idea/sonarlint/issuestore/7/c/7c8d86a076f2b7efe379ba510fa19b44123fbc48 deleted file mode 100644 index 75ca956..0000000 --- a/.idea/sonarlint/issuestore/7/c/7c8d86a076f2b7efe379ba510fa19b44123fbc48 +++ /dev/null @@ -1,7 +0,0 @@ - -N -java:S1197&"8Move the array designator from the variable to the type.( -D -java:S1121".Extract the assignment out of this expression.( -N -java:S1197&"8Move the array designator from the variable to the type.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/c/7cd521c281506d65676d30f1e5e6b10d61014bff b/.idea/sonarlint/issuestore/7/c/7cd521c281506d65676d30f1e5e6b10d61014bff deleted file mode 100644 index fcd93dd..0000000 --- a/.idea/sonarlint/issuestore/7/c/7cd521c281506d65676d30f1e5e6b10d61014bff +++ /dev/null @@ -1,4 +0,0 @@ - -Z java:S106 "9Replace this use of System.out or System.err by a logger.(ٸ8. -U java:S106 "9Replace this use of System.out or System.err by a logger.(8. -Q java:S125"").( -o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.( -D -java:S5413")Verify that "remove()" is used correctly.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/d/7ddf6872fd6bf4c1e7b1ae0fd344cf87b3d34390 b/.idea/sonarlint/issuestore/7/d/7ddf6872fd6bf4c1e7b1ae0fd344cf87b3d34390 deleted file mode 100644 index 3e09320..0000000 --- a/.idea/sonarlint/issuestore/7/d/7ddf6872fd6bf4c1e7b1ae0fd344cf87b3d34390 +++ /dev/null @@ -1,4 +0,0 @@ - -k java:S117 "QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -n java:S135("YReduce the total number of break and continue statements in this loop to use at most one.( -k java:S117 "QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/e/7e1eec49595d8bd917ef0502f3368f425e66d53f b/.idea/sonarlint/issuestore/7/e/7e1eec49595d8bd917ef0502f3368f425e66d53f deleted file mode 100644 index 73375bc..0000000 --- a/.idea/sonarlint/issuestore/7/e/7e1eec49595d8bd917ef0502f3368f425e66d53f +++ /dev/null @@ -1,3 +0,0 @@ - -O -java:S2864"4Iterate over the "entrySet" instead of the "keySet".(婅 \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/f/7ff5c5295d63667ae68fd986dbb9d0cba7f89676 b/.idea/sonarlint/issuestore/7/f/7ff5c5295d63667ae68fd986dbb9d0cba7f89676 deleted file mode 100644 index 989462e..0000000 --- a/.idea/sonarlint/issuestore/7/f/7ff5c5295d63667ae68fd986dbb9d0cba7f89676 +++ /dev/null @@ -1,35 +0,0 @@ - -o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ƌ -^ -java:S2259_"HA "NullPointerException" could be thrown; "assignTemp" is nullable here.(Ȕ -M -java:S2589^"7Remove this expression which always evaluates to "true"(ƙ -V java:S125"Remove this unused private "reverseLinkedListPractise" method.(ӑ -K -java:S1144"/Remove this unused private "findCyclic" method.( -G -java:S1144"0Remove this unused private "findNthNode" method.(礊 -E -java:S1144".Remove this unused private "printList" method.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/1/811bf5770f4b9a52cccbb8a2bc44cb9aea7006e1 b/.idea/sonarlint/issuestore/8/1/811bf5770f4b9a52cccbb8a2bc44cb9aea7006e1 deleted file mode 100644 index b7fd246..0000000 --- a/.idea/sonarlint/issuestore/8/1/811bf5770f4b9a52cccbb8a2bc44cb9aea7006e1 +++ /dev/null @@ -1,3 +0,0 @@ - -J -java:S10664"/Merge this if statement with the enclosing one.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/1/81f6990775833bc7a1f3dc9cff576c7eeb337b30 b/.idea/sonarlint/issuestore/8/1/81f6990775833bc7a1f3dc9cff576c7eeb337b30 deleted file mode 100644 index 4d4b64d..0000000 --- a/.idea/sonarlint/issuestore/8/1/81f6990775833bc7a1f3dc9cff576c7eeb337b30 +++ /dev/null @@ -1,12 +0,0 @@ - -S -java:S1197 "8Move the array designator from the variable to the type.(Ë -P -java:S1854 -"5Remove this useless assignment to local variable "n".( -S java:S106 "9Replace this use of System.out or System.err by a logger.( -S -java:S1197"8Move the array designator from the variable to the type.( -A -java:S1481 -"&Remove this unused "n" local variable.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/5/854bf6adae0c1b91abeb01f54d55e06f860ae611 b/.idea/sonarlint/issuestore/8/5/854bf6adae0c1b91abeb01f54d55e06f860ae611 deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/8/5/85a40d1fc6955c89664c72f9499d4e9d9ad52d12 b/.idea/sonarlint/issuestore/8/5/85a40d1fc6955c89664c72f9499d4e9d9ad52d12 deleted file mode 100644 index 5965ecc..0000000 --- a/.idea/sonarlint/issuestore/8/5/85a40d1fc6955c89664c72f9499d4e9d9ad52d12 +++ /dev/null @@ -1,3 +0,0 @@ - -W -java:S11266"AReplace this if-then-else statement by a single return statement.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/6/86c65eefc86bd360c961dbfa76a30ee8e639600c b/.idea/sonarlint/issuestore/8/6/86c65eefc86bd360c961dbfa76a30ee8e639600c deleted file mode 100644 index 939c5cc..0000000 --- a/.idea/sonarlint/issuestore/8/6/86c65eefc86bd360c961dbfa76a30ee8e639600c +++ /dev/null @@ -1,4 +0,0 @@ - -N java:S106]"9Replace this use of System.out or System.err by a logger.( -B -java:S1659"'Declare "lastlndex" on a separate line.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/7/8791d113c90b5eaaac31a3f73365f228ccab67a9 b/.idea/sonarlint/issuestore/8/7/8791d113c90b5eaaac31a3f73365f228ccab67a9 deleted file mode 100644 index 577336a..0000000 --- a/.idea/sonarlint/issuestore/8/7/8791d113c90b5eaaac31a3f73365f228ccab67a9 +++ /dev/null @@ -1,13 +0,0 @@ - -P java:S125" -java:S1659"#Declare "right" on a separate line.( -Q -java:S2696'"6Make the enclosing method "static" or remove this set.( -Q -java:S2696K"6Make the enclosing method "static" or remove this set.( -S java:S106P"9Replace this use of System.out or System.err by a logger.(瑛 -S java:S106X"9Replace this use of System.out or System.err by a logger.(瑛 -N java:S106h"9Replace this use of System.out or System.err by a logger.( -S java:S106l"9Replace this use of System.out or System.err by a logger.(ޞҗ -S java:S106m"9Replace this use of System.out or System.err by a logger.(л \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/d/8d00cdd75ea020080139231991fe691f54829a6f b/.idea/sonarlint/issuestore/8/d/8d00cdd75ea020080139231991fe691f54829a6f deleted file mode 100644 index a253c3f..0000000 --- a/.idea/sonarlint/issuestore/8/d/8d00cdd75ea020080139231991fe691f54829a6f +++ /dev/null @@ -1,7 +0,0 @@ - -Q java:S106"9Replace this use of System.out or System.err by a logger.( -p java:S127"XRefactor the code in order to not assign to this loop counter from within the loop body.(ɉ -d java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -L java:S106"9Replace this use of System.out or System.err by a logger.(ɴ -i java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -i java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/d/8d432008c50bd81945c726fc4fa4011b5f3cdeb8 b/.idea/sonarlint/issuestore/8/d/8d432008c50bd81945c726fc4fa4011b5f3cdeb8 deleted file mode 100644 index 6b40d14..0000000 --- a/.idea/sonarlint/issuestore/8/d/8d432008c50bd81945c726fc4fa4011b5f3cdeb8 +++ /dev/null @@ -1,5 +0,0 @@ - -N java:S106"9Replace this use of System.out or System.err by a logger.( -N java:S106F"9Replace this use of System.out or System.err by a logger.(ߵ -S java:S106E"9Replace this use of System.out or System.err by a logger.( -S java:S106"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/d/8deb1250efdff63bc54eccf442a5d81017fb5a91 b/.idea/sonarlint/issuestore/8/d/8deb1250efdff63bc54eccf442a5d81017fb5a91 deleted file mode 100644 index e572c77..0000000 --- a/.idea/sonarlint/issuestore/8/d/8deb1250efdff63bc54eccf442a5d81017fb5a91 +++ /dev/null @@ -1,11 +0,0 @@ - -f java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -f java:S1175"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -f java:S1175"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -f java:S1175"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -e -java:S11041"OMake val a static final constant or non-public and provide accessors if needed.(Ը -f -java:S11042"PMake next a static final constant or non-public and provide accessors if needed.( -m -java:S11043"RMake random a static final constant or non-public and provide accessors if needed.(ә \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/f/8f0c2c2e40c00e189a33e5a1efefb1f505d93e51 b/.idea/sonarlint/issuestore/8/f/8f0c2c2e40c00e189a33e5a1efefb1f505d93e51 deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/9/0/90fc93692a5f9497dd5e983b820a77af574b4f2d b/.idea/sonarlint/issuestore/9/0/90fc93692a5f9497dd5e983b820a77af574b4f2d deleted file mode 100644 index e4225f7..0000000 --- a/.idea/sonarlint/issuestore/9/0/90fc93692a5f9497dd5e983b820a77af574b4f2d +++ /dev/null @@ -1,3 +0,0 @@ - -9 -java:S2119"Save and re-use this "Random".( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/9/3/93d8338afc0b4e089e1907278da7bf042677e038 b/.idea/sonarlint/issuestore/9/3/93d8338afc0b4e089e1907278da7bf042677e038 deleted file mode 100644 index 02cee5a..0000000 --- a/.idea/sonarlint/issuestore/9/3/93d8338afc0b4e089e1907278da7bf042677e038 +++ /dev/null @@ -1,6 +0,0 @@ - -N java:S106<"9Replace this use of System.out or System.err by a logger.( -S java:S106="9Replace this use of System.out or System.err by a logger.( -k java:S117 "QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -N -java:S1197;"8Move the array designator from the variable to the type.(ږ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/9/4/943e4a327d3d604114b9d153e8fbc7f82140e972 b/.idea/sonarlint/issuestore/9/4/943e4a327d3d604114b9d153e8fbc7f82140e972 deleted file mode 100644 index ab8854d..0000000 --- a/.idea/sonarlint/issuestore/9/4/943e4a327d3d604114b9d153e8fbc7f82140e972 +++ /dev/null @@ -1,2 +0,0 @@ - -S java:S106@"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/9/4/94de9101791f300f5f045f7c1a6c683a04219238 b/.idea/sonarlint/issuestore/9/4/94de9101791f300f5f045f7c1a6c683a04219238 deleted file mode 100644 index 8e9625f..0000000 --- a/.idea/sonarlint/issuestore/9/4/94de9101791f300f5f045f7c1a6c683a04219238 +++ /dev/null @@ -1,6 +0,0 @@ - -f java:S117 "QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ȿ -S java:S106."9Replace this use of System.out or System.err by a logger.( -k java:S117+"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -f java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/9/5/953e63705cfbbd4a09dfad3f29dea40ab5fe7ff2 b/.idea/sonarlint/issuestore/9/5/953e63705cfbbd4a09dfad3f29dea40ab5fe7ff2 deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/9/6/965b9e65f64f5874cdd3e9b20c2a4176b623aa66 b/.idea/sonarlint/issuestore/9/6/965b9e65f64f5874cdd3e9b20c2a4176b623aa66 deleted file mode 100644 index 97916d4..0000000 --- a/.idea/sonarlint/issuestore/9/6/965b9e65f64f5874cdd3e9b20c2a4176b623aa66 +++ /dev/null @@ -1,2 +0,0 @@ - -U java:S106"9Replace this use of System.out or System.err by a logger.(8. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/9/7/97322aeb00bdf644e441c930ac44ff2638e9c029 b/.idea/sonarlint/issuestore/9/7/97322aeb00bdf644e441c930ac44ff2638e9c029 deleted file mode 100644 index 6baa999..0000000 --- a/.idea/sonarlint/issuestore/9/7/97322aeb00bdf644e441c930ac44ff2638e9c029 +++ /dev/null @@ -1,5 +0,0 @@ - -U -java:S2184H"@Cast one of the operands of this integer division to a "double".(T -P java:S125"Use isEmpty() to check whether the collection is empty or not.( -7 -java:S1170"!Make this final field static too.(ҳ -l java:S116"WRename this field "FIVE_MINUTES" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ҳ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/b/2/b273fb7280da68b2da19101e0b89eacee9f04988 b/.idea/sonarlint/issuestore/b/2/b273fb7280da68b2da19101e0b89eacee9f04988 deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/b/4/b471983e4f82be2c21f03fda9fac9f82e002ef9a b/.idea/sonarlint/issuestore/b/4/b471983e4f82be2c21f03fda9fac9f82e002ef9a deleted file mode 100644 index 066f6a1..0000000 --- a/.idea/sonarlint/issuestore/b/4/b471983e4f82be2c21f03fda9fac9f82e002ef9a +++ /dev/null @@ -1,2 +0,0 @@ - -o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ƌ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/b/4/b4e4119d524d7351aebd531ec8cb53a23a1ac1e9 b/.idea/sonarlint/issuestore/b/4/b4e4119d524d7351aebd531ec8cb53a23a1ac1e9 deleted file mode 100644 index 8c5eeff..0000000 --- a/.idea/sonarlint/issuestore/b/4/b4e4119d524d7351aebd531ec8cb53a23a1ac1e9 +++ /dev/null @@ -1,18 +0,0 @@ - -L java:S106"9Replace this use of System.out or System.err by a logger.(ŷ -Q -java:S1197"8Move the array designator from the variable to the type.(ģ -Q -java:S1197"8Move the array designator from the variable to the type.( -Q -java:S1197"8Move the array designator from the variable to the type.(܉ -Q java:S106"9Replace this use of System.out or System.err by a logger.( -L java:S106"9Replace this use of System.out or System.err by a logger.( -L -java:S1197"8Move the array designator from the variable to the type.( -Q java:S106"9Replace this use of System.out or System.err by a logger.(˦ -Q java:S106"9Replace this use of System.out or System.err by a logger.( -o -java:S1192"ODefine a constant instead of duplicating this literal "FINAL RESULT: " 4 times.(˦8. -L -java:S1197"8Move the array designator from the variable to the type.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/b/4/b4f39d67d9de4608cd87e4dcf9289d90e8426afa b/.idea/sonarlint/issuestore/b/4/b4f39d67d9de4608cd87e4dcf9289d90e8426afa deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/b/6/b6c1195fb748ab6c0ca41ce155a65aa4cb71f0de b/.idea/sonarlint/issuestore/b/6/b6c1195fb748ab6c0ca41ce155a65aa4cb71f0de deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/b/9/b941e0faf1b7bf5355e2fb091b588116886b2b1f b/.idea/sonarlint/issuestore/b/9/b941e0faf1b7bf5355e2fb091b588116886b2b1f deleted file mode 100644 index bb4b059..0000000 --- a/.idea/sonarlint/issuestore/b/9/b941e0faf1b7bf5355e2fb091b588116886b2b1f +++ /dev/null @@ -1,6 +0,0 @@ - -Z java:S106)"9Replace this use of System.out or System.err by a logger.(8͵. -U java:S1062"9Replace this use of System.out or System.err by a logger.(8´. -Z java:S106,"9Replace this use of System.out or System.err by a logger.(8. -Q -java:S1128"4Remove this unused import 'java.lang.reflect.Array'.(ɘ8. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/b/9/b97ff9eace6e02d384c2a08508f266f49c98e7d7 b/.idea/sonarlint/issuestore/b/9/b97ff9eace6e02d384c2a08508f266f49c98e7d7 deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/b/a/bab1177aae82bae10cefebec36321b50cc9863dd b/.idea/sonarlint/issuestore/b/a/bab1177aae82bae10cefebec36321b50cc9863dd deleted file mode 100644 index 2cf73fc..0000000 --- a/.idea/sonarlint/issuestore/b/a/bab1177aae82bae10cefebec36321b50cc9863dd +++ /dev/null @@ -1,2 +0,0 @@ - -m java:S1171"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(8ǯ. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/b/a/bacb4ca599e79973d65328cae755ba3d19118726 b/.idea/sonarlint/issuestore/b/a/bacb4ca599e79973d65328cae755ba3d19118726 deleted file mode 100644 index 137bb92..0000000 --- a/.idea/sonarlint/issuestore/b/a/bacb4ca599e79973d65328cae755ba3d19118726 +++ /dev/null @@ -1,2 +0,0 @@ - -N java:S106&"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/b/e/be2572a20f9be978d7a71d1287114fb4ff15b13d b/.idea/sonarlint/issuestore/b/e/be2572a20f9be978d7a71d1287114fb4ff15b13d deleted file mode 100644 index cf09fd2..0000000 --- a/.idea/sonarlint/issuestore/b/e/be2572a20f9be978d7a71d1287114fb4ff15b13d +++ /dev/null @@ -1,9 +0,0 @@ - -W -java:S1126:"AReplace this if-then-else statement by a single return statement.( -h -java:S3776"RRefactor this method to reduce its Cognitive Complexity from 22 to the 15 allowed.(߽ -: -java:S1659"Declare "j" on a separate line.( -\ -java:S1118":Add a private constructor to hide the implicit public one.(8辘. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/b/e/be302c9a02a91127c1fdb0d06f31e040af135e0d b/.idea/sonarlint/issuestore/b/e/be302c9a02a91127c1fdb0d06f31e040af135e0d deleted file mode 100644 index 040946b..0000000 --- a/.idea/sonarlint/issuestore/b/e/be302c9a02a91127c1fdb0d06f31e040af135e0d +++ /dev/null @@ -1,2 +0,0 @@ - -N java:S1068"9Replace this use of System.out or System.err by a logger.(۬ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/b/f/bfa96acc23a70c4176888cc734f0ed024d58cd11 b/.idea/sonarlint/issuestore/b/f/bfa96acc23a70c4176888cc734f0ed024d58cd11 deleted file mode 100644 index 066f6a1..0000000 --- a/.idea/sonarlint/issuestore/b/f/bfa96acc23a70c4176888cc734f0ed024d58cd11 +++ /dev/null @@ -1,2 +0,0 @@ - -o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ƌ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/c/0/c01934cb5fa257e80d4ca5b638e3368911554fa3 b/.idea/sonarlint/issuestore/c/0/c01934cb5fa257e80d4ca5b638e3368911554fa3 deleted file mode 100644 index b0a3f43..0000000 --- a/.idea/sonarlint/issuestore/c/0/c01934cb5fa257e80d4ca5b638e3368911554fa3 +++ /dev/null @@ -1,5 +0,0 @@ - -S java:S1067"9Replace this use of System.out or System.err by a logger.( -Z java:S106-"9Replace this use of System.out or System.err by a logger.(8. -6 -java:S1659)" Declare "i2" on a separate line.(ո \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/c/1/c143649f5f79ee59eeaf759d7c59d30a04b1b2e4 b/.idea/sonarlint/issuestore/c/1/c143649f5f79ee59eeaf759d7c59d30a04b1b2e4 deleted file mode 100644 index 5761d81..0000000 --- a/.idea/sonarlint/issuestore/c/1/c143649f5f79ee59eeaf759d7c59d30a04b1b2e4 +++ /dev/null @@ -1,11 +0,0 @@ - -Z -java:S1197E"8Move the array designator from the variable to the type.(8. -S -java:S1197D"8Move the array designator from the variable to the type.( -r java:S117)"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(8Փ. -] java:S125B"").(ɝ -o -java:S3012Z"YUse "Arrays.copyOf", "Arrays.asList", "Collections.addAll" or "System.arraycopy" instead.( -t -java:S2293"YReplace the type specification in this constructor call with the diamond operator ("<>").(ϒ -o -java:S22935"YReplace the type specification in this constructor call with the diamond operator ("<>").( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/c/5/c5553fd280cb7748f9571fa19a14e95f31ea5799 b/.idea/sonarlint/issuestore/c/5/c5553fd280cb7748f9571fa19a14e95f31ea5799 deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/c/6/c62619dffb64c534668fe6a76e536cebc7988e75 b/.idea/sonarlint/issuestore/c/6/c62619dffb64c534668fe6a76e536cebc7988e75 deleted file mode 100644 index 9b5d5cd..0000000 --- a/.idea/sonarlint/issuestore/c/6/c62619dffb64c534668fe6a76e536cebc7988e75 +++ /dev/null @@ -1,16 +0,0 @@ - -N -java:S1197"8Move the array designator from the variable to the type.( -S -java:S1197+"8Move the array designator from the variable to the type.( -o -java:S3012%"YUse "Arrays.copyOf", "Arrays.asList", "Collections.addAll" or "System.arraycopy" instead.(ڥ -N -java:S1197"8Move the array designator from the variable to the type.( -S -java:S1197"8Move the array designator from the variable to the type.(ٞ -S -java:S1197"8Move the array designator from the variable to the type.(ٞ -N -java:S1197*"8Move the array designator from the variable to the type.( -N java:S106-"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/c/6/c637172121bfc0463017c09b76d3e81352627086 b/.idea/sonarlint/issuestore/c/6/c637172121bfc0463017c09b76d3e81352627086 deleted file mode 100644 index fa684e3..0000000 --- a/.idea/sonarlint/issuestore/c/6/c637172121bfc0463017c09b76d3e81352627086 +++ /dev/null @@ -1,10 +0,0 @@ - -L java:S106"9Replace this use of System.out or System.err by a logger.(˓ -L -java:S1197"8Move the array designator from the variable to the type.(Ѱ -Q java:S106"9Replace this use of System.out or System.err by a logger.( -L -java:S1197"8Move the array designator from the variable to the type.( -T java:S125"").(й \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/d/7/d7bd3c45b6dfed3dc0e2b67d0376422d497dd1a4 b/.idea/sonarlint/issuestore/d/7/d7bd3c45b6dfed3dc0e2b67d0376422d497dd1a4 deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/d/9/d954c0b73e46581c8182dfca8d1e959c07609d11 b/.idea/sonarlint/issuestore/d/9/d954c0b73e46581c8182dfca8d1e959c07609d11 deleted file mode 100644 index c5c09b4..0000000 --- a/.idea/sonarlint/issuestore/d/9/d954c0b73e46581c8182dfca8d1e959c07609d11 +++ /dev/null @@ -1,2 +0,0 @@ - -Z java:S1068"9Replace this use of System.out or System.err by a logger.(٨8ˀ. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/d/9/d989b7396837bd36056b8707b4397c3a195f9c12 b/.idea/sonarlint/issuestore/d/9/d989b7396837bd36056b8707b4397c3a195f9c12 deleted file mode 100644 index a717fdc..0000000 --- a/.idea/sonarlint/issuestore/d/9/d989b7396837bd36056b8707b4397c3a195f9c12 +++ /dev/null @@ -1,31 +0,0 @@ - -G -java:S1444",Make this "public static head_1" field final( -B -java:S1444",Make this "public static head_2" field final(ꮱ -@ -java:S1444"*Make this "public static head" field final( -k java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -e java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -k java:S117E"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ƌ -m -java:S1104"RMake head_1 a static final constant or non-public and provide accessors if needed.( -h -java:S1104"RMake head_2 a static final constant or non-public and provide accessors if needed.(ꮱ -f -java:S1104"PMake head a static final constant or non-public and provide accessors if needed.( -M -java:S2589)"7Remove this expression which always evaluates to "true"( -R -java:S2589/"7Remove this expression which always evaluates to "true"(ф -l -java:S3008"QRename this field "head_1" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -g -java:S3008"QRename this field "head_2" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ꮱ -N java:S106"9Replace this use of System.out or System.err by a logger.( -N java:S106G"9Replace this use of System.out or System.err by a logger.( -S java:S106K"9Replace this use of System.out or System.err by a logger.(Ӽ -M java:S106O"9Replace this use of System.out or System.err by a logger.(ɺZ -S java:S106R"9Replace this use of System.out or System.err by a logger.(Ӽ -S java:S106S"9Replace this use of System.out or System.err by a logger.(Ӽ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/d/9/d9932abb4e3590d0146b1c8858c142b360773844 b/.idea/sonarlint/issuestore/d/9/d9932abb4e3590d0146b1c8858c142b360773844 deleted file mode 100644 index eeb105d..0000000 --- a/.idea/sonarlint/issuestore/d/9/d9932abb4e3590d0146b1c8858c142b360773844 +++ /dev/null @@ -1,4 +0,0 @@ - -r java:S127"XRefactor the code in order to not assign to this loop counter from within the loop body.(쒜 -m java:S127"XRefactor the code in order to not assign to this loop counter from within the loop body.( -V java:S125"").(ׅ -Q java:S125" -java:S1659#"!Declare "end" on a separate line.(8喝. \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/f/1/f1260adfa38eb619d43afa7b7901782cdf4af7e1 b/.idea/sonarlint/issuestore/f/1/f1260adfa38eb619d43afa7b7901782cdf4af7e1 deleted file mode 100644 index 5e81f94..0000000 --- a/.idea/sonarlint/issuestore/f/1/f1260adfa38eb619d43afa7b7901782cdf4af7e1 +++ /dev/null @@ -1,20 +0,0 @@ - -V java:S125" filesInFolder = Files.walk(Paths.get("/Users/vignesh_rajarajan/Documents/learning/Problems/src")) + .filter(Files::isRegularFile) + .map(Path::toFile) + .filter(file -> file.getName().contains(".java")) + .collect(Collectors.toList()); + int rand= (new Random().nextInt(filesInFolder.size())); + System.out.println(rand+" "+filesInFolder.get(rand).getName()); + try (BufferedReader reader = + new BufferedReader(new FileReader(filesInFolder.get(rand)))){ + reader.lines().filter(e->e.contains("http") || e.contains("https")).forEach(System.out::println); + } + + //filesInFolder.forEach(System.out::println); + } +} diff --git a/src/binarysearch/BinarySearchTemplate.java b/src/binarysearch/BinarySearchTemplate.java new file mode 100644 index 0000000..72400e7 --- /dev/null +++ b/src/binarysearch/BinarySearchTemplate.java @@ -0,0 +1,19 @@ +package binarysearch; + +public class BinarySearchTemplate { + /** + public T template(int n) { + + int left= min_val; + int right= max_val; + + while(left=k if yes adjust the right side + int temp= Math.min(mid/i,n); + System.out.println("I :: "+i+" N:: "+n+" MID/N ::"+temp); + count+=temp; + } + System.out.println("isFeasible end:: "+count); + System.out.println(); + return count>=k; + } + + public static void main(String[] args) { + System.out.println(new KthSmallestInMultiplicationTable().findKthNumber(4,4,6)); + } +} diff --git a/src/binarysearch/NumberOfDaysToMakeMBouquets.java b/src/binarysearch/NumberOfDaysToMakeMBouquets.java new file mode 100644 index 0000000..372c8e2 --- /dev/null +++ b/src/binarysearch/NumberOfDaysToMakeMBouquets.java @@ -0,0 +1,46 @@ +package binarysearch; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/minimum-number-of-days-to-make-m-bouquets/ + */ +public class NumberOfDaysToMakeMBouquets { + + public int minDays(int[] bloomDay, int m, int k) { + if(bloomDay.length< m*k) return -1; + + int left=1; + int right= Arrays.stream(bloomDay).max().orElse(0); + + while(leftmid){ // if the day is greater then break the window + adj=0; + }else{ + adj++; // increase the window size + if(adj==k){ // if the window size is equal to K end the window, we get one bouquet and reset the window for next + bouquets++; + adj=0; + } + } + } + return bouquets>=m; + } +} diff --git a/src/binarysearch/SearchInsertPosition.java b/src/binarysearch/SearchInsertPosition.java new file mode 100644 index 0000000..0c8d633 --- /dev/null +++ b/src/binarysearch/SearchInsertPosition.java @@ -0,0 +1,23 @@ +package binarysearch; + +/** + * https://leetcode.com/problems/search-insert-position/ + * + */ +public class SearchInsertPosition { + + public int searchInsert(int[] nums, int target) { + int left=0; + //Also notice that the input target might be larger than all elements in nums and therefore needs to placed at the end of the array. + // That's why we should initialize right = len(nums) instead of right = len(nums) - 1. + int right= nums.length; + + while(left= target) right=mid; + else left=mid+1; + } + + return left; + } +} diff --git a/src/geeksforgeeks/ShipPackageWithNDays.java b/src/binarysearch/ShipPackageWithNDays.java similarity index 100% rename from src/geeksforgeeks/ShipPackageWithNDays.java rename to src/binarysearch/ShipPackageWithNDays.java diff --git a/src/binarysearch/Sqrt.java b/src/binarysearch/Sqrt.java new file mode 100644 index 0000000..ffbdc9d --- /dev/null +++ b/src/binarysearch/Sqrt.java @@ -0,0 +1,22 @@ +package binarysearch; + +/** + * https://leetcode.com/problems/sqrtx + */ +public class Sqrt { + + public int mySqrt(int x) { + if(x==0 || x==1) return x; + + long left= 0L; + long right= x; + + while(leftx) right=mid; + else left=mid+1; + } + left--; + return (int)left; + } +} diff --git a/src/binarysearch/SubArraySplitSum.java b/src/binarysearch/SubArraySplitSum.java new file mode 100644 index 0000000..9fcb554 --- /dev/null +++ b/src/binarysearch/SubArraySplitSum.java @@ -0,0 +1,72 @@ +package binarysearch; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/split-array-largest-sum/ + * + * concept is same as shipContainer in D days problem + */ +public class SubArraySplitSum { + + public int splitArray(int[] nums, int m) { + int left= Arrays.stream(nums).max().orElse(0); + int right= Arrays.stream(nums).sum(); + + while(leftlimit){ + partition++; + System.out.println("isFeasible limit is:: "+ limit +" "+ "but sum is " + sum + " so increasing partition "+partition); + sum=num; + } + + } + System.out.println("End of isFeasible:: sum is "+ sum + " and partition is "+partition); + return partition<=m; + } + + public static void main(String[] args) { + System.out.println(new SubArraySplitSum().splitArray(new int[]{7,2,5,10,8}, 2)); + //System.out.println(new SubArraySplitSum().splitArray(new int[]{1,4,4}, 3)); + } +} diff --git a/src/geeksforgeeks/LongestIncreasingPathInMatrix.java b/src/geeksforgeeks/LongestIncreasingPathInMatrix.java new file mode 100644 index 0000000..fc668a2 --- /dev/null +++ b/src/geeksforgeeks/LongestIncreasingPathInMatrix.java @@ -0,0 +1,64 @@ +package geeksforgeeks; + +/** + * https://leetcode.com/problems/longest-increasing-path-in-a-matrix + * + * Do DFS from every cell + * Compare every 4 direction and skip cells that are out of boundary or smaller + * Get matrix max from every cell's max + * Use matrix[x][y] <= matrix[i][j] so we don't need a visited[m][n] array + * The key is to cache the distance because it's highly possible to revisit a cell + * + * DFS + Memoization + * + * Traverse all points in matrix, use every point as starting point to do dfs traversal. DFS function returns max increasing + * path after comparing four max return distance from four directions. + * + * */ +public class LongestIncreasingPathInMatrix { + + int[][] dirs= new int[][] {{1,0},{-1,0},{0,1},{0,-1}}; + public int longestIncreasingPath(int[][] matrix) { + if(matrix.length == 0) return 0; + // i+1,j, i-1,j i,j+1 i,j-1 + Integer[][] cache= new Integer[matrix.length][matrix[0].length]; + + int result=0; + for(int i=0;i=matrix.length || j<0 || j>=matrix[0].length|| data>=matrix[i][j]) return 0; + + + + if(cache[i][j]!=null) return cache[i][j]; + + // initialize max distance as 1 since the path includes starting point itself + int max=1; + + for(int[] dir: dirs){ + + int x=i+dir[0]; + int y=j+dir[1]; + // if next point is a valid point, add curLen by 1 and continue DFS traversal + int count=1+dfsUtil(matrix,x,y,cache, matrix[i][j]); + max=Math.max(count,max); + } + // update max increasing path value starting from current point in cache + cache[i][j]=max; + + return cache[i][j]; + + } + + public boolean isValid(int[][] matrix, int i, int j, int data){ + return i >= 0 && i < matrix.length && j >= 0 && j < matrix[0].length; + } +} From 1ede06017b906021d2023d88d7d189c2c649ce43 Mon Sep 17 00:00:00 2001 From: Vignesh Date: Sun, 18 Apr 2021 18:07:45 +0530 Subject: [PATCH 41/51] binarysearch and java8 --- .gitignore | 2 + src/binarysearch/ShipPackageWithNDays.java | 2 +- .../FirstNonRepeatingCharacterStream.java | 151 +++++++++++------- src/geeksforgeeks/JumpsToReachEnd.java | 25 +-- src/geeksforgeeks/MaximumDifference.java | 14 +- .../MedianOfTwoSortedArrays.java | 12 ++ src/geeksforgeeks/SpiralMatrix.java | 10 +- src/geeksforgeeks/SubArraySumEqualsK.java | 84 ++++++---- src/geeksforgeeks/UnSortedSubArray.java | 23 +-- src/geeksforgeeks/VulgarDecimal.java | 118 +++++++++----- 10 files changed, 276 insertions(+), 165 deletions(-) diff --git a/.gitignore b/.gitignore index 6fd6edf..079aeb3 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ AmazonProblems.iml *.json +/.idea/* +/.idea/ diff --git a/src/binarysearch/ShipPackageWithNDays.java b/src/binarysearch/ShipPackageWithNDays.java index a8eeb85..4005986 100644 --- a/src/binarysearch/ShipPackageWithNDays.java +++ b/src/binarysearch/ShipPackageWithNDays.java @@ -1,4 +1,4 @@ -package geeksforgeeks; +package binarysearch; import java.util.Arrays; diff --git a/src/geeksforgeeks/FirstNonRepeatingCharacterStream.java b/src/geeksforgeeks/FirstNonRepeatingCharacterStream.java index e8ad54d..8730b10 100644 --- a/src/geeksforgeeks/FirstNonRepeatingCharacterStream.java +++ b/src/geeksforgeeks/FirstNonRepeatingCharacterStream.java @@ -1,67 +1,108 @@ package geeksforgeeks; -import java.util.ArrayList; -import java.util.List; +import java.util.*; /** - * https://www.geeksforgeeks.org/find-first-non-repeating-character-stream-characters/ + * https://www.interviewbit.com/problems/first-non-repeating-character-in-a-stream-of-characters/ */ public class FirstNonRepeatingCharacterStream { - final static int MAX_CHAR = 256; - - -/* - we need to maintain 2 array of size 26 and a doubly linkedlist where the hed element points to the first Non repeat - 1st array to store the corresponding node to the character position boolean[] visited= new boolean[26]; - 2nd array is to check if the character occurred 2>= times DLLNode[] node= new DLLNode[26]; - first condition whenever we see a value, we need to check it in visited array - if(visited[c-'a']== true) do nothing because already added and deleted from the list(means this is 3rd occurrence of the array) - else if(node[c-'a']!=null) removeNode(node[c-'a']); visited[c-'a']=true; 2nd occurrence we need to remove from list and set visited value to true - else create a node and add head if head null or add to tail means we are seeing first time and need to create an entry in list -*/ - - // this uses arraylist so remove and contains are O(N) - static void findFirstNonRepeating() { - // inDLL[x] contains pointer to a DLL node if x is present - // in DLL. If x is not present, then inDLL[x] is NULL - List inDLL = new ArrayList<>(); - - // repeated[x] is true if x is repeated two or more times. - // If x is not seen so far or x is seen only once. then - // repeated[x] is false - boolean[] repeated = new boolean[MAX_CHAR]; - - // Let us consider following stream and see the process - String stream = "geeksforgeeksandgeeksquizfor"; - for (int i = 0; i < stream.length(); i++) { - char x = stream.charAt(i); - System.out.println("Reading " + x + " from stream n"); - - // We process this character only if it has not occurred - // or occurred only once. repeated[x] is true if x is - // repeated twice or more.s - if (!repeated[x]) { - // If the character is not in DLL, then add this at - // the end of DLL. - if (!(inDLL.contains(x))) { - inDLL.add(x); - } else // Otherwise remove this character from DLL - { - inDLL.remove((Character) x); - repeated[x] = true; // Also mark it as repeated - } - } - - // Print the current first non-repeating character from - // stream - if (inDLL.size() != 0) { - System.out.print("First non-repeating character so far is "); - System.out.println(inDLL.get(0)); - } + Set isSeen = new HashSet<>(); + DLList linkedList = new DLList(); + Map map = new HashMap<>(); + + public String solve(String A) { + StringBuilder sb = new StringBuilder(); + for (String s : A.split("")) { + sb.append(uniqueStream(s)); + } + return sb.toString(); + } + + public String uniqueStream(String A) { + Node node = new Node(A); + + if (isSeen.contains(A) && map.get(A) != null) { + Node temp = map.get(A); + linkedList.remove(temp); + map.put(A, null); + } else if (!isSeen.contains(A)) { + isSeen.add(A); + linkedList.add(node); + map.put(A, node); } + + return linkedList.head.next.val; + } + + public String solveEfficient(String A) { + // we can use two pointer approach to solve this problem. + // First count the occurences of the characters in the stream in the charCounts array + int[] charCounts = new int[26]; + // Keep a start pointer at the start index which will denote the first non-repeating character, if any + int s = 0; + char[] charArr = A.toCharArray(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < charArr.length; i++) { + // increment the count of the current character + charCounts[charArr[i] - 'a']++; + // move the start pointer ahead either till the current index + // or until we see another non-repeating character + while (s < i && charCounts[charArr[s] - 'a'] > 1) s++; + // If the character at start index is a non repeating character, add it the string otherwise add '#'' + if (charCounts[charArr[s] - 'a'] == 1) sb.append(charArr[s]); + else sb.append('#'); + } + + return sb.toString(); } public static void main(String[] args) { - findFirstNonRepeating(); + String[] vals= "jpxvxivxkkthvpqhhhjuzhkegnzqriokhsgea".split(""); + FirstNonRepeatingCharacterStream solution= new FirstNonRepeatingCharacterStream(); + for(String s:vals){ + System.out.println("ans:: "+solution.solve(s)); + } + } +} + + + + + + +class DLList { + Node head; + Node tail; + + public DLList() { + head = new Node("#"); + tail = new Node("#"); + head.next = tail; + tail.prev = head; + } + + public void add(Node node) { + Node prev = tail.prev; + prev.next = node; + node.prev = prev; + + node.next = tail; + tail.prev = node; + } + + public void remove(Node temp) { + Node next = temp.next; + temp.prev.next = next; + next.prev = temp.prev; + } +} + +class Node { + Node prev; + Node next; + String val; + + public Node(String val) { + this.val = val; } } diff --git a/src/geeksforgeeks/JumpsToReachEnd.java b/src/geeksforgeeks/JumpsToReachEnd.java index 82e32d1..e4157b1 100644 --- a/src/geeksforgeeks/JumpsToReachEnd.java +++ b/src/geeksforgeeks/JumpsToReachEnd.java @@ -19,17 +19,14 @@ public class JumpsToReachEnd { * Explanation: You will always arrive at index 3 no matter what. * Its maximum jump length is 0, which makes it impossible to reach the last index. */ - public static boolean canReachEnd(List maxAdvanceSteps) { - int furthestReachSoFar = 0, lastlndex = maxAdvanceSteps.size() - 1; - - //i <= furthestReachSoFar && furthestReachSoFar < lastlndex this is the imp part of the solution - for (int i = 0; i <= furthestReachSoFar && furthestReachSoFar < lastlndex; ++i) { - // for every index store max-steps it can take and i should be - // less than maxSteps to check if it can move further - // e.x (3, 2, 0, 0, 2, 0,1) when index i is 3 maxStpes is also 3, it cannot move further - furthestReachSoFar = Math.max(furthestReachSoFar, i + maxAdvanceSteps.get(i)); + public static boolean canReachEnd(Integer[] nums) { + + int curMax = nums[0]; + for (int i = 1; i < nums.length; i++) { + if (curMax < i) return false; //means we are not able to reach position i + curMax = Math.max(curMax, i + nums[i]); } - return furthestReachSoFar >= lastlndex; + return true; } @@ -78,7 +75,11 @@ public int minJump(int[] nums) { } //Once the current point reaches curEnd, //then trigger another jump, and set the new curEnd with curFarthest, - //then keep the above steps, as the following: + //then keep the above steps, as the following + + //This is an implicit bfs solution. i == curEnd means you visited all the items on the current level. + // Incrementing jumps++ is like incrementing the level you are on. + // And curEnd = curFarthest is like getting the queue size (level size) for the next level you are traversing. if(currentEnd==i){ // when the current pick of ladder reached last step jumps++; currentEnd=currentMax; @@ -90,6 +91,6 @@ public int minJump(int[] nums) { public static void main(String[] args) { List list= Arrays.asList(3,3,1,0, 2,0,1); - System.out.println(canReachEnd(list)); + System.out.println(canReachEnd(list.toArray(new Integer[list.size()]))); } } \ No newline at end of file diff --git a/src/geeksforgeeks/MaximumDifference.java b/src/geeksforgeeks/MaximumDifference.java index 0f98073..cf1dcca 100644 --- a/src/geeksforgeeks/MaximumDifference.java +++ b/src/geeksforgeeks/MaximumDifference.java @@ -18,19 +18,7 @@ static int maxDiff(int arr[], int arr_size) { } return maxDiff; } - static int maxDiff1(int arr[], int arr_size) { - int maxDiff = 0; - int minElement = arr[0]; - for (int i = 1; i < arr_size; i++) { - if (arr[i] - minElement > maxDiff) { - maxDiff = arr[i] - minElement; - } - if (arr[i] < minElement) { - minElement = arr[i]; - } - } - return maxDiff; - } + public static void main(String[] args) { int arr[] = { 2, 4, 1, 3, 10, 8, 5 }; System.out.println("Maximum difference is " + maxDiff(arr, arr.length)); diff --git a/src/geeksforgeeks/MedianOfTwoSortedArrays.java b/src/geeksforgeeks/MedianOfTwoSortedArrays.java index e0ae327..7bd3ce0 100644 --- a/src/geeksforgeeks/MedianOfTwoSortedArrays.java +++ b/src/geeksforgeeks/MedianOfTwoSortedArrays.java @@ -22,6 +22,7 @@ public double findMedianSortedArrays(int[] input1, int[] input2) { // add the total left and right elements for both arrays would come to be equal 3+1(left partition) and 2+2(right partition) // the reason to add 1 ((x + y + 1) / 2 ) is to account for both odd and even lengths + // for odd length the left half should be greater, the +1 is to adjust for that int low = 0; int high = x; @@ -31,12 +32,23 @@ public double findMedianSortedArrays(int[] input1, int[] input2) { //if partitionX is 0 it means nothing is there on left side to partition. [|| 1] Use -INF for maxLeftX //if partitionX is length of input then there is nothing on right side. Use +INF for minRightX + + // to understand it further let's take an edge case A=[2] B=[1,3] + // partitionX=0+1/2 => 0 + // partitionY= 1+2+1/2 - 0 => 2 , the partition would look like this + // A= [-inf || 2] + // B= [2,3 || +inf] int maxLeftX = (partitionX == 0) ? Integer.MIN_VALUE : input1[partitionX - 1]; int minRightX = (partitionX == x) ? Integer.MAX_VALUE : input1[partitionX]; int maxLeftY = (partitionY == 0) ? Integer.MIN_VALUE : input2[partitionY - 1]; int minRightY = (partitionY == y) ? Integer.MAX_VALUE : input2[partitionY]; + // for the example given above, at right partition the elements would be grouped like below + // A=> 1,3 || 7 + // B=> 2,6 || 8,9,10 + // 3<8 and 6<7 so we take max of left and min of right + if (maxLeftX <= minRightY && maxLeftY <= minRightX) { //We have partitioned array at correct place // Now get max of left elements and min of right elements to get the median in case of even length combined array size diff --git a/src/geeksforgeeks/SpiralMatrix.java b/src/geeksforgeeks/SpiralMatrix.java index c8508cc..60716dc 100644 --- a/src/geeksforgeeks/SpiralMatrix.java +++ b/src/geeksforgeeks/SpiralMatrix.java @@ -21,27 +21,33 @@ public static List spiralOrder(int[][] matrix) { while (rowBegin <= rowEnd && colBegin <= colEnd) { // Traverse Right for (int j = colBegin; j <= colEnd; j ++) { + System.out.println(" Right "+matrix[rowBegin][j]); res.add(matrix[rowBegin][j]); } rowBegin++; // Traverse Down for (int j = rowBegin; j <= rowEnd; j ++) { + System.out.println(" Down "+matrix[j][colEnd]); res.add(matrix[j][colEnd]); } colEnd--; - if (rowBegin <= rowEnd) { + if (rowBegin <= rowEnd) { // without this condition, this corner test case [[2,3]] would print [2,3,2] // Traverse Left for (int j = colEnd; j >= colBegin; j --) { + System.out.println(" Left "+matrix[rowEnd][j]); res.add(matrix[rowEnd][j]); } } rowEnd--; - + + // this block's work is to move 1 row up from bottom + // the rest of the work will be done by first 'Right' loop again if (colBegin <= colEnd) { // Traver Up for (int j = rowEnd; j >= rowBegin; j --) { + System.out.println(" uppp "+matrix[j][colBegin]); res.add(matrix[j][colBegin]); } } diff --git a/src/geeksforgeeks/SubArraySumEqualsK.java b/src/geeksforgeeks/SubArraySumEqualsK.java index fb0c80c..4cc6972 100644 --- a/src/geeksforgeeks/SubArraySumEqualsK.java +++ b/src/geeksforgeeks/SubArraySumEqualsK.java @@ -5,39 +5,53 @@ public class SubArraySumEqualsK { public int subarraySum(int[] nums, int k) { - int left=0; - int right=0; - int sum=0; - int result=0; - - Map map= new HashMap<>(); - map.put(0,1); - // Let’s assume (D+E+3=k) - // sum =A+B+C+D+E+3 - // preSum = A+B+C - // Thus, we can compose critical equation - // sum - preSum = k - // Since we’re looking for specific preSum to compose value k - // What specific preSum were looking? - // Some math operation results in - // sum - k = preSum - // For multiple matching counts - // Ex: - // input [0,-1,1,2,3] k=5 - // We notice that it’s necessary to record occurrence of specific preSum. - // In this case, we need to know preSum 2 occur three times. [0,-1,1,2], [-1,1,2], [2] - // This indicate that it's necessary to record preSum counts - - while(left map = new HashMap<>(); + map.put(0, 1); + // Let’s assume (D+E+3=k) + // sum =A+B+C+D+E+3 + // preSum = A+B+C + // Thus, we can compose critical equation + // sum - preSum = k + // Since we’re looking for specific preSum to compose value k + // we can re-arrange the above equation like below + // sum - k = preSum + // For multiple matching counts + // Ex: + // input [0,-1,1,2,3] k=5 + // We notice that it’s necessary to record occurrence of specific preSum. + // In this case, we need to know preSum 2 occur three times. [0,-1,1,2], [-1,1,2], [2] + // This indicate that it's necessary to record preSum counts + + while (left < nums.length) { + sum += nums[left]; + if (map.get(sum - k) != null) { + result += map.get(sum - k); + } + map.put(sum, map.getOrDefault(sum, 0) + 1); + left++; + + } + return result; + + } + + public static int subarraySumDivByK(int[] nums, int K) { + int prefix = 0; + int result = 0; + Map count = new HashMap<>(); + count.put(0, 1); + + for (int a : nums) { + //(prefix+a%K+K)%K is just a trick to make the remainder positive. + prefix = (prefix + (a % K) + K) % K; + result += count.getOrDefault(prefix, 0); + count.put(prefix, count.getOrDefault(prefix, 0) + 1); + } + return result; + } } \ No newline at end of file diff --git a/src/geeksforgeeks/UnSortedSubArray.java b/src/geeksforgeeks/UnSortedSubArray.java index a731ca0..ec2cae1 100644 --- a/src/geeksforgeeks/UnSortedSubArray.java +++ b/src/geeksforgeeks/UnSortedSubArray.java @@ -25,17 +25,6 @@ public static int findUnsortedSubarray(int[] nums) { return 0; } - int max = Integer.MIN_VALUE; - int end = -2; - //iterate from beginning of array - //find the last element which is smaller than the last seen max from - //its left side and mark it as end - for (int i = 0; i < nums.length; i++) { - max = Math.max(max, nums[i]); - if (nums[i] < max) { - end = i; - } - } int min = Integer.MAX_VALUE; int begin = -1; @@ -48,6 +37,18 @@ public static int findUnsortedSubarray(int[] nums) { begin = i; } } + + int max = Integer.MIN_VALUE; + int end = -2; + //iterate from beginning of array + //find the last element which is smaller than the last seen max from + //its left side and mark it as end + for (int i = 0; i < nums.length; i++) { + max = Math.max(max, nums[i]); + if (nums[i] < max) { + end = i; + } + } return end - begin + 1; } } diff --git a/src/geeksforgeeks/VulgarDecimal.java b/src/geeksforgeeks/VulgarDecimal.java index f4d1018..6ec577b 100644 --- a/src/geeksforgeeks/VulgarDecimal.java +++ b/src/geeksforgeeks/VulgarDecimal.java @@ -2,66 +2,112 @@ /** * https://leetcode.com/problems/fraction-to-recurring-decimal/ - * + *

* Given two integers representing the numerator and denominator of a fraction, return the fraction in string format. - * + *

* If the fractional part is repeating, enclose the repeating part in parentheses. - * + *

* If multiple answers are possible, return any of them. - * + *

* It is guaranteed that the length of the answer string is less than 104 for all the given inputs. - * + *

* Input: numerator = 1, denominator = 2 * Output: "0.5" - * + *

* Input: numerator = 2, denominator = 1 * Output: "2" */ - import java.util.*; public class VulgarDecimal { public static String fractionToDecimal(long numerator, long denominator) { - if(denominator==0) return null; - boolean isNegative= (numerator < 0 && denominator > 0) || (numerator > 0 && denominator < 0); - - long denomiL= Math.abs(denominator); - long numerL= Math.abs(numerator); - - Map map= new HashMap<>(); - + if (denominator == 0) return null; + // if both are negative then the ans would be positive + boolean isNegative = (numerator < 0 && denominator > 0) || (numerator > 0 && denominator < 0); + + long denomiL = Math.abs(denominator); + long numerL = Math.abs(numerator); + + Map map = new HashMap<>(); + + StringBuilder sb = new StringBuilder(); + + sb.append((numerL / denomiL)); + + if (numerL % denomiL != 0) { + sb.append("."); + } + if (isNegative) sb.insert(0, "-"); + + numerL %= denomiL; + + if (numerL == 0) return sb.toString(); + + map.put(numerL, sb.length()); + + while (numerL > 0) { + + numerL *= 10; + sb.append((numerL / denomiL)); + numerL = (numerL % denomiL); + + if (map.containsKey(numerL)) { + int index = map.get(numerL); + sb.insert(index, "("); + sb.append(")"); + break; + } else { + map.put(numerL, sb.length()); + } + } + + return sb.toString(); + } + + public String fractionToDecimal(int numerator, int denominator) { + + boolean isNegative= numerator<0 && denominator>0 || numerator>0 && denominator<0; + StringBuilder sb= new StringBuilder(); - - sb.append((numerL/denomiL)); - - if(numerL%denomiL!=0){ + Map map= new HashMap<>(); + long numeratorL= Math.abs(Long.valueOf(numerator)); + long denominatorL= Math.abs(Long.valueOf(denominator)); + + long rem=numeratorL/denominatorL; + sb.append(rem); + + + + if(isNegative) sb.insert(0,'-'); + + if(numeratorL%denominatorL>0){ sb.append("."); + }else{ + return sb.toString(); } - if(isNegative) sb.insert(0,"-"); - numerL%=denomiL; - if(numerL==0) return sb.toString(); - - map.put(numerL,sb.length()); - - while(numerL>0){ - - numerL*=10; - sb.append((numerL/denomiL)); - numerL= (numerL%denomiL); - - if(map.containsKey(numerL)){ - int index= map.get(numerL); - sb.insert(index,"("); + numeratorL%=denominatorL; + map.put(numeratorL,sb.length()); + + while(numeratorL>0){ + numeratorL*=10; + + rem=numeratorL/denominatorL; + sb.append(rem); + numeratorL%=denominatorL; + if(map.containsKey(numeratorL)){ + int pos= map.get(numeratorL); + sb.insert(pos,"("); sb.append(")"); break; }else{ - map.put(numerL,sb.length()); + map.put(numeratorL,sb.length()); } + } - + return sb.toString(); } From 4f6284549baedfe606883744257f19c925252e17 Mon Sep 17 00:00:00 2001 From: Vignesh Date: Sun, 25 Apr 2021 11:41:06 +0530 Subject: [PATCH 42/51] refactored packages --- .../FindMinimumInRotatedArray.java | 0 src/binarysearch/FindSmallestDivisor.java | 32 ++ .../FirstAndLastOccurence.java | 0 .../MagneticForceBetweenTwoBalls.java | 68 ++++ src/binarysearch/MaxSoldiers.java | 49 +++ .../PeakElement.java | 0 .../SearchElementInSortedAndRotatedArray.java | 2 +- src/geeksforgeeks/MaxSoldiers.java | 48 --- src/practiceproblems/.vscode/UrlEncode.java | 0 src/practiceproblems/AdvantageShuffle.java | 40 ++ .../AircraftOptimization.java | 69 ++++ .../AlternateOddAndEvenNumbers.java | 50 +++ src/practiceproblems/AngleOfClock.java | 15 + src/practiceproblems/ArrangeInQueue.java | 51 +++ src/practiceproblems/ArticulationPoint.java | 369 ++++++++++++++++++ src/practiceproblems/AutoCompleteSystem.java | 97 +++++ src/practiceproblems/BackspaceCompare.java | 63 +++ src/practiceproblems/BasicCalculator.java | 64 +++ src/practiceproblems/BinaryTreeCousins.java | 51 +++ src/practiceproblems/BitonicSearch.java | 102 +++++ src/practiceproblems/BoatsToSave.java | 36 ++ .../BuyAndSellStockAnytime.java | 23 ++ .../BuyAndSellStockAtMostTwice.java | 50 +++ src/practiceproblems/Candy.java | 58 +++ src/practiceproblems/CelebrityProblem.java | 29 ++ .../CheckPalindromePermutation.java | 32 ++ src/practiceproblems/CloneGraph.java | 70 ++++ src/practiceproblems/ClosestNumbers.java | 45 +++ src/practiceproblems/CombinationIterator.java | 53 +++ src/practiceproblems/CompareVersions.java | 31 ++ .../ConstructBSTFromPreorder.java | 81 ++++ .../ConstructTreeFromInorderAndPostorder.java | 31 ++ .../ConstructTreeFromInorderAndPreorder.java | 49 +++ .../ContainerWithMostWater.java | 36 ++ src/practiceproblems/ConvertXToY.java | 69 ++++ .../CountAllPathsFrom2DMatrix.java | 43 ++ src/practiceproblems/CountAndSay.java | 41 ++ src/practiceproblems/CountElements.java | 59 +++ ...ntMinimumStepsToFormDesiredInputArray.java | 70 ++++ .../CountNumbersLessThanSelf.java | 103 +++++ src/practiceproblems/CountingInversion.java | 62 +++ src/practiceproblems/CourseSchedule.java | 116 ++++++ src/practiceproblems/DecodeString.java | 51 +++ .../DesignCompressedStringIterator.java | 59 +++ src/practiceproblems/DesignFileSystem.java | 64 +++ .../DesignInMemoryFileSystem.java | 96 +++++ .../DesignStackIncrement.java | 101 +++++ src/practiceproblems/DesignTicTacToe.java | 107 +++++ .../DifferentWaysToAddParenthesis.java | 61 +++ .../DivideSubArrayAverage.java | 47 +++ src/practiceproblems/DungeonGame.java | 64 +++ src/practiceproblems/DutchNationalFlag.java | 31 ++ src/practiceproblems/EvaluvateRPN.java | 47 +++ src/practiceproblems/FenwickTree.java | 112 ++++++ src/practiceproblems/FindAllAnagram.java | 60 +++ src/practiceproblems/FindMissingNumbers.java | 44 +++ src/practiceproblems/FindSmallestInteger.java | 45 +++ .../FirstMissingPositive.java | 106 +++++ .../FirstNonRepeatedCharacter.java | 26 ++ .../FirstNonRepeatingCharacterStream.java | 108 +++++ src/practiceproblems/Flatten2DVector.java | 72 ++++ src/practiceproblems/FlattenLinkedList.java | 145 +++++++ .../FlattenMultiLevelLinkedList.java | 48 +++ .../FlipMaximizeZeroesSubarrayKadane.java | 40 ++ ...lipZeroesToFormConsecutiveMaximumOnes.java | 57 +++ src/practiceproblems/FourSum.java | 64 +++ src/practiceproblems/FrequencySort.java | 34 ++ src/practiceproblems/GameOfLife.java | 61 +++ src/practiceproblems/GenerateParenthesis.java | 44 +++ src/practiceproblems/GrammarMistake.java | 83 ++++ src/practiceproblems/GraphBiPartite.java | 52 +++ .../GraphSplitwiseSimplify.java | 141 +++++++ src/practiceproblems/GroupAnagrams.java | 29 ++ .../GroupIsomorphicString.java | 56 +++ src/practiceproblems/HappyNumber.java | 57 +++ src/practiceproblems/HitCounter.java | 31 ++ src/practiceproblems/HouseRobber.java | 46 +++ src/practiceproblems/IPOMaxProfit.java | 46 +++ src/practiceproblems/InMemeoryFIleSystem.java | 136 +++++++ src/practiceproblems/InOrderSuccessor.java | 28 ++ .../InorderSuccessorPredecessor.java | 105 +++++ src/practiceproblems/InsertIntervals.java | 36 ++ src/practiceproblems/InsertionSortList.java | 38 ++ src/practiceproblems/IntegerToBinary.java | 38 ++ .../IntersectionOfArrays.java | 79 ++++ .../IsEditOneDistanceAway.java | 63 +++ src/practiceproblems/IsSubsequence.java | 22 ++ src/practiceproblems/IslandBFS.java | 59 +++ src/practiceproblems/Islands.java | 44 +++ src/practiceproblems/IsomorphicString.java | 31 ++ src/practiceproblems/JumpsToReachEnd.java | 96 +++++ src/practiceproblems/KClosestElements.java | 66 ++++ .../KmostFrequentLetters.java | 50 +++ src/practiceproblems/KthClosestOrigin.java | 74 ++++ .../KthSmallestFromTwoSortedArrays.java | 43 ++ src/practiceproblems/KthSmallestMatrix.java | 51 +++ src/practiceproblems/LIS2DMatrix.java | 52 +++ src/practiceproblems/LRUCache.java | 123 ++++++ .../LargestDivisibleSubset.java | 66 ++++ .../LargestPossibleNumber.java | 55 +++ .../LargestSubArrayWithZeroesAndOnes.java | 68 ++++ .../LargestTimeFromDigits.java | 39 ++ .../LeftMostColumnWithOne.java | 42 ++ .../LengthOfLongestSubstringKDistinct.java | 90 +++++ .../LinkedListRemoveDuplicates.java | 36 ++ .../LongestConsequtiveSequence.java | 73 ++++ .../LongestIncreasingPathInMatrix.java | 64 +++ .../LongestRepeatCharReplace.java | 47 +++ .../LongestSpanWithSameSumArray.java | 74 ++++ .../LongestSubArraySumUtmostK.java | 47 +++ .../LongestUniqueSubstring.java | 53 +++ src/practiceproblems/MajorityVoting.java | 86 ++++ .../MakeAnArrayPalindrome.java | 41 ++ src/practiceproblems/MatrixRowWithMax1.java | 48 +++ .../MaxDistinctElementAfterKRemoval.java | 118 ++++++ src/practiceproblems/MaxFreqStack.java | 75 ++++ src/practiceproblems/MaxHistogram.java | 68 ++++ src/practiceproblems/MaxProductString.java | 57 +++ .../MaxWidthOfBinaryTree.java | 61 +++ src/practiceproblems/MaximumDifference.java | 26 ++ src/practiceproblems/MaximumGap.java | 70 ++++ .../MaximumProductSubarray.java | 63 +++ .../MaximumSubstringWithKDistinctChar.java | 85 ++++ .../MaximumUnsortedSubarray.java | 90 +++++ src/practiceproblems/MedianOfKWindow.java | 49 +++ .../MedianOfRunningIntegers.java | 45 +++ .../MedianOfTwoSortedArrays.java | 79 ++++ src/practiceproblems/MeetingRoomsII.java | 63 +++ .../MergeIntervalIntersection.java | 42 ++ src/practiceproblems/MergeIntervals.java | 44 +++ src/practiceproblems/MergeSortLinkedList.java | 80 ++++ src/practiceproblems/MergeTwoLinkedList.java | 46 +++ .../MinAdjSwapsToMakePalindrome.java | 58 +++ src/practiceproblems/MinCostRopeConnect.java | 34 ++ .../MinStepsToConvertXtoY.java | 49 +++ src/practiceproblems/MinTimeRotOranges.java | 102 +++++ src/practiceproblems/MinimumBribes.java | 50 +++ .../MinimumDistanceBetweenTwoNumbers.java | 52 +++ .../MinimumIndexDistanceOfMaximumNumbers.java | 31 ++ src/practiceproblems/MinimumPathSum.java | 40 ++ src/practiceproblems/MinimumStack.java | 131 +++++++ src/practiceproblems/MinimumStepsKnight.java | 91 +++++ .../MinimumSwapSortArray.java | 59 +++ .../MinimumWindowSubsequence.java | 80 ++++ .../MinimumWindowSubstring.java | 62 +++ src/practiceproblems/MirrorBinaryTree.java | 72 ++++ .../MobileKeyPadCombinations.java | 59 +++ src/practiceproblems/MoveZeroes.java | 34 ++ src/practiceproblems/NQueens.java | 90 +++++ src/practiceproblems/NewRoadsMST.java | 86 ++++ src/practiceproblems/NextGreaterElement.java | 90 +++++ src/practiceproblems/NextGreaterNumber.java | 74 ++++ src/practiceproblems/NextLargestList.java | 58 +++ src/practiceproblems/Node.java | 82 ++++ src/practiceproblems/NonDecreasingArray.java | 31 ++ src/practiceproblems/NumberOfBallons.java | 24 ++ src/practiceproblems/NutsAndBoltsMatch.java | 74 ++++ .../OverlappingIntervals.java | 42 ++ .../OwnDataStructureUtil.java | 56 +++ src/practiceproblems/PalindromePartion.java | 52 +++ .../PalindromePartitioning.java | 57 +++ .../PalindromeSinglyLinkedList.java | 64 +++ .../PalindromicSubSequence.java | 52 +++ src/practiceproblems/PartitionLabel.java | 50 +++ src/practiceproblems/PascalsTriangle.java | 70 ++++ src/practiceproblems/PathSumIII.java | 48 +++ src/practiceproblems/Pattern132.java | 33 ++ src/practiceproblems/PerfectSquare.java | 74 ++++ src/practiceproblems/PermutationInString.java | 62 +++ src/practiceproblems/PetrolGasStation.java | 37 ++ src/practiceproblems/PlusOne.java | 38 ++ src/practiceproblems/Pow.java | 52 +++ src/practiceproblems/PrisonAfterNDays.java | 54 +++ src/practiceproblems/ProductExceptSelf.java | 52 +++ src/practiceproblems/QueensAttackKing.java | 54 +++ src/practiceproblems/RaceCarMinSteps.java | 45 +++ src/practiceproblems/RandomLinkedList.java | 62 +++ .../RandomPickWithWeight.java | 52 +++ src/practiceproblems/RangeSum.java | 41 ++ src/practiceproblems/ReconstructItenary.java | 46 +++ src/practiceproblems/RedundantConnection.java | 44 +++ .../RemoveAdjacentDuplicates.java | 27 ++ src/practiceproblems/RemoveDuplicates.java | 27 ++ .../RemoveInvalidParentheses.java | 61 +++ src/practiceproblems/RemoveKDigits.java | 60 +++ src/practiceproblems/ReorderLogs.java | 58 +++ src/practiceproblems/ReorganiseString.java | 71 ++++ src/practiceproblems/RestoreIpAddresses.java | 53 +++ .../ReverseWordsInString.java | 40 ++ .../RollingHashRabinKarp.java | 134 +++++++ src/practiceproblems/RomanToInteger.java | 34 ++ src/practiceproblems/RotateArray.java | 30 ++ src/practiceproblems/RotateMatrixInPlace.java | 102 +++++ .../RotateMatrixInPlaceAntiClockwise.java | 63 +++ src/practiceproblems/SameTree.java | 62 +++ src/practiceproblems/SearchAMaze.java | 80 ++++ .../SearchAnElementInMatrix.java | 74 ++++ .../SerializeAndDeserialize.java | 80 ++++ .../SerializeDeserializeBST.java | 76 ++++ src/practiceproblems/SetBitCount.java | 21 + src/practiceproblems/ShuffleArray.java | 53 +++ src/practiceproblems/SimilarExpressions.java | 55 +++ .../SingleElementInSortedArray.java | 44 +++ src/practiceproblems/SlidingWindow.java | 74 ++++ src/practiceproblems/SnakeAndLadder.java | 70 ++++ src/practiceproblems/SnakeGame.java | 88 +++++ .../SortANearlySortedArray.java | 40 ++ src/practiceproblems/SortStack.java | 31 ++ src/practiceproblems/SortedArrayToBST.java | 39 ++ src/practiceproblems/SortedSquares.java | 28 ++ src/practiceproblems/SpiralMatrix.java | 68 ++++ src/practiceproblems/SpiralMatrixII.java | 56 +++ src/practiceproblems/SplitLinkedList.java | 47 +++ .../StockBuySellManyTimes.java | 84 ++++ src/practiceproblems/StockSpanner.java | 21 + src/practiceproblems/StringIterator.java | 37 ++ .../SubArraySumDivisibleByK.java | 48 +++ src/practiceproblems/SubArraySumEqualsK.java | 57 +++ .../SubstringWindowTemplate.java | 62 +++ src/practiceproblems/SumOfThreeElements.java | 39 ++ src/practiceproblems/SumSubArrayZero.java | 65 +++ src/practiceproblems/SurroundedRegions.java | 142 +++++++ src/practiceproblems/SwapRecoverBST.java | 54 +++ src/practiceproblems/SymmetricTree.java | 21 + src/practiceproblems/TaskLeastInterval.java | 55 +++ src/practiceproblems/ThreeSum.java | 40 ++ src/practiceproblems/TimeMap.java | 67 ++++ src/practiceproblems/TopKFrequentElement.java | 38 ++ .../TopKFrequentElements.java | 38 ++ src/practiceproblems/TrailingZeroes.java | 19 + src/practiceproblems/TreasureIsland.java | 66 ++++ src/practiceproblems/TreasureIslandII.java | 82 ++++ src/practiceproblems/Trie.java | 65 +++ src/practiceproblems/Twitter.java | 140 +++++++ src/practiceproblems/TwoCityScheduling.java | 49 +++ src/practiceproblems/TwoSumClosestToZero.java | 48 +++ src/practiceproblems/UnSortedSubArray.java | 54 +++ .../UniqueElementsInArray.java | 29 ++ src/practiceproblems/UniquePath.java | 89 +++++ src/practiceproblems/UniquePathMaximum.java | 46 +++ src/practiceproblems/UrlEncode.java | 45 +++ src/practiceproblems/ValidPalindromeII.java | 40 ++ src/practiceproblems/ValidParentheses.java | 26 ++ .../ValidParenthesesString.java | 45 +++ src/practiceproblems/ValidSudoku.java | 35 ++ src/practiceproblems/ValidateIpAddresses.java | 65 +++ src/practiceproblems/VulgarDecimal.java | 115 ++++++ src/practiceproblems/WaterTrapping.java | 37 ++ src/practiceproblems/WordBreak.java | 83 ++++ src/practiceproblems/WordBreakII.java | 33 ++ src/practiceproblems/WordDictionary.java | 69 ++++ src/practiceproblems/WordLadder.java | 45 +++ src/practiceproblems/WordSearch.java | 47 +++ .../sorting/ImplementABinaryHeap.java | 0 .../common => }/sorting/InsertionSort.java | 0 .../sorting/KthLargestElement.java | 0 src/{strings/common => }/sorting/MaxHeap.java | 0 .../common => }/sorting/MergeSort.java | 0 .../sorting/PractiseMergeSort.java | 0 .../common => }/sorting/QuickSelect.java | 0 .../common => }/sorting/QuickSort.java | 0 .../All_Possible_Combinatons.java | 28 -- .../DynamicIntegerGenerator.java | 29 -- .../dynamicProblems/FirstNonRepeating.java | 34 -- .../dynamicProblems/PossibleCombinations.java | 29 -- .../dynamicProblems/ReverseSentence.java | 17 - src/strings/dynamicProblems/Subsequence.java | 36 -- 267 files changed, 14903 insertions(+), 222 deletions(-) rename src/{geeksforgeeks => binarysearch}/FindMinimumInRotatedArray.java (100%) create mode 100644 src/binarysearch/FindSmallestDivisor.java rename src/{geeksforgeeks => binarysearch}/FirstAndLastOccurence.java (100%) create mode 100644 src/binarysearch/MagneticForceBetweenTwoBalls.java create mode 100644 src/binarysearch/MaxSoldiers.java rename src/{geeksforgeeks => binarysearch}/PeakElement.java (100%) rename src/{geeksforgeeks => binarysearch}/SearchElementInSortedAndRotatedArray.java (97%) delete mode 100644 src/geeksforgeeks/MaxSoldiers.java create mode 100644 src/practiceproblems/.vscode/UrlEncode.java create mode 100644 src/practiceproblems/AdvantageShuffle.java create mode 100644 src/practiceproblems/AircraftOptimization.java create mode 100644 src/practiceproblems/AlternateOddAndEvenNumbers.java create mode 100644 src/practiceproblems/AngleOfClock.java create mode 100644 src/practiceproblems/ArrangeInQueue.java create mode 100644 src/practiceproblems/ArticulationPoint.java create mode 100644 src/practiceproblems/AutoCompleteSystem.java create mode 100644 src/practiceproblems/BackspaceCompare.java create mode 100644 src/practiceproblems/BasicCalculator.java create mode 100644 src/practiceproblems/BinaryTreeCousins.java create mode 100644 src/practiceproblems/BitonicSearch.java create mode 100644 src/practiceproblems/BoatsToSave.java create mode 100644 src/practiceproblems/BuyAndSellStockAnytime.java create mode 100644 src/practiceproblems/BuyAndSellStockAtMostTwice.java create mode 100644 src/practiceproblems/Candy.java create mode 100644 src/practiceproblems/CelebrityProblem.java create mode 100644 src/practiceproblems/CheckPalindromePermutation.java create mode 100644 src/practiceproblems/CloneGraph.java create mode 100644 src/practiceproblems/ClosestNumbers.java create mode 100644 src/practiceproblems/CombinationIterator.java create mode 100644 src/practiceproblems/CompareVersions.java create mode 100644 src/practiceproblems/ConstructBSTFromPreorder.java create mode 100644 src/practiceproblems/ConstructTreeFromInorderAndPostorder.java create mode 100644 src/practiceproblems/ConstructTreeFromInorderAndPreorder.java create mode 100644 src/practiceproblems/ContainerWithMostWater.java create mode 100644 src/practiceproblems/ConvertXToY.java create mode 100644 src/practiceproblems/CountAllPathsFrom2DMatrix.java create mode 100644 src/practiceproblems/CountAndSay.java create mode 100644 src/practiceproblems/CountElements.java create mode 100644 src/practiceproblems/CountMinimumStepsToFormDesiredInputArray.java create mode 100644 src/practiceproblems/CountNumbersLessThanSelf.java create mode 100644 src/practiceproblems/CountingInversion.java create mode 100644 src/practiceproblems/CourseSchedule.java create mode 100644 src/practiceproblems/DecodeString.java create mode 100644 src/practiceproblems/DesignCompressedStringIterator.java create mode 100644 src/practiceproblems/DesignFileSystem.java create mode 100644 src/practiceproblems/DesignInMemoryFileSystem.java create mode 100644 src/practiceproblems/DesignStackIncrement.java create mode 100644 src/practiceproblems/DesignTicTacToe.java create mode 100644 src/practiceproblems/DifferentWaysToAddParenthesis.java create mode 100644 src/practiceproblems/DivideSubArrayAverage.java create mode 100644 src/practiceproblems/DungeonGame.java create mode 100644 src/practiceproblems/DutchNationalFlag.java create mode 100644 src/practiceproblems/EvaluvateRPN.java create mode 100644 src/practiceproblems/FenwickTree.java create mode 100644 src/practiceproblems/FindAllAnagram.java create mode 100644 src/practiceproblems/FindMissingNumbers.java create mode 100644 src/practiceproblems/FindSmallestInteger.java create mode 100644 src/practiceproblems/FirstMissingPositive.java create mode 100644 src/practiceproblems/FirstNonRepeatedCharacter.java create mode 100644 src/practiceproblems/FirstNonRepeatingCharacterStream.java create mode 100644 src/practiceproblems/Flatten2DVector.java create mode 100644 src/practiceproblems/FlattenLinkedList.java create mode 100644 src/practiceproblems/FlattenMultiLevelLinkedList.java create mode 100644 src/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java create mode 100644 src/practiceproblems/FlipZeroesToFormConsecutiveMaximumOnes.java create mode 100644 src/practiceproblems/FourSum.java create mode 100644 src/practiceproblems/FrequencySort.java create mode 100644 src/practiceproblems/GameOfLife.java create mode 100644 src/practiceproblems/GenerateParenthesis.java create mode 100644 src/practiceproblems/GrammarMistake.java create mode 100644 src/practiceproblems/GraphBiPartite.java create mode 100644 src/practiceproblems/GraphSplitwiseSimplify.java create mode 100644 src/practiceproblems/GroupAnagrams.java create mode 100644 src/practiceproblems/GroupIsomorphicString.java create mode 100644 src/practiceproblems/HappyNumber.java create mode 100644 src/practiceproblems/HitCounter.java create mode 100644 src/practiceproblems/HouseRobber.java create mode 100644 src/practiceproblems/IPOMaxProfit.java create mode 100644 src/practiceproblems/InMemeoryFIleSystem.java create mode 100644 src/practiceproblems/InOrderSuccessor.java create mode 100644 src/practiceproblems/InorderSuccessorPredecessor.java create mode 100644 src/practiceproblems/InsertIntervals.java create mode 100644 src/practiceproblems/InsertionSortList.java create mode 100644 src/practiceproblems/IntegerToBinary.java create mode 100644 src/practiceproblems/IntersectionOfArrays.java create mode 100644 src/practiceproblems/IsEditOneDistanceAway.java create mode 100644 src/practiceproblems/IsSubsequence.java create mode 100644 src/practiceproblems/IslandBFS.java create mode 100644 src/practiceproblems/Islands.java create mode 100644 src/practiceproblems/IsomorphicString.java create mode 100644 src/practiceproblems/JumpsToReachEnd.java create mode 100644 src/practiceproblems/KClosestElements.java create mode 100644 src/practiceproblems/KmostFrequentLetters.java create mode 100644 src/practiceproblems/KthClosestOrigin.java create mode 100644 src/practiceproblems/KthSmallestFromTwoSortedArrays.java create mode 100644 src/practiceproblems/KthSmallestMatrix.java create mode 100644 src/practiceproblems/LIS2DMatrix.java create mode 100644 src/practiceproblems/LRUCache.java create mode 100644 src/practiceproblems/LargestDivisibleSubset.java create mode 100644 src/practiceproblems/LargestPossibleNumber.java create mode 100644 src/practiceproblems/LargestSubArrayWithZeroesAndOnes.java create mode 100644 src/practiceproblems/LargestTimeFromDigits.java create mode 100644 src/practiceproblems/LeftMostColumnWithOne.java create mode 100644 src/practiceproblems/LengthOfLongestSubstringKDistinct.java create mode 100644 src/practiceproblems/LinkedListRemoveDuplicates.java create mode 100644 src/practiceproblems/LongestConsequtiveSequence.java create mode 100644 src/practiceproblems/LongestIncreasingPathInMatrix.java create mode 100644 src/practiceproblems/LongestRepeatCharReplace.java create mode 100644 src/practiceproblems/LongestSpanWithSameSumArray.java create mode 100644 src/practiceproblems/LongestSubArraySumUtmostK.java create mode 100644 src/practiceproblems/LongestUniqueSubstring.java create mode 100644 src/practiceproblems/MajorityVoting.java create mode 100644 src/practiceproblems/MakeAnArrayPalindrome.java create mode 100644 src/practiceproblems/MatrixRowWithMax1.java create mode 100644 src/practiceproblems/MaxDistinctElementAfterKRemoval.java create mode 100644 src/practiceproblems/MaxFreqStack.java create mode 100644 src/practiceproblems/MaxHistogram.java create mode 100644 src/practiceproblems/MaxProductString.java create mode 100644 src/practiceproblems/MaxWidthOfBinaryTree.java create mode 100644 src/practiceproblems/MaximumDifference.java create mode 100644 src/practiceproblems/MaximumGap.java create mode 100644 src/practiceproblems/MaximumProductSubarray.java create mode 100644 src/practiceproblems/MaximumSubstringWithKDistinctChar.java create mode 100644 src/practiceproblems/MaximumUnsortedSubarray.java create mode 100644 src/practiceproblems/MedianOfKWindow.java create mode 100644 src/practiceproblems/MedianOfRunningIntegers.java create mode 100644 src/practiceproblems/MedianOfTwoSortedArrays.java create mode 100644 src/practiceproblems/MeetingRoomsII.java create mode 100644 src/practiceproblems/MergeIntervalIntersection.java create mode 100644 src/practiceproblems/MergeIntervals.java create mode 100644 src/practiceproblems/MergeSortLinkedList.java create mode 100644 src/practiceproblems/MergeTwoLinkedList.java create mode 100644 src/practiceproblems/MinAdjSwapsToMakePalindrome.java create mode 100644 src/practiceproblems/MinCostRopeConnect.java create mode 100644 src/practiceproblems/MinStepsToConvertXtoY.java create mode 100644 src/practiceproblems/MinTimeRotOranges.java create mode 100644 src/practiceproblems/MinimumBribes.java create mode 100644 src/practiceproblems/MinimumDistanceBetweenTwoNumbers.java create mode 100644 src/practiceproblems/MinimumIndexDistanceOfMaximumNumbers.java create mode 100644 src/practiceproblems/MinimumPathSum.java create mode 100644 src/practiceproblems/MinimumStack.java create mode 100644 src/practiceproblems/MinimumStepsKnight.java create mode 100644 src/practiceproblems/MinimumSwapSortArray.java create mode 100644 src/practiceproblems/MinimumWindowSubsequence.java create mode 100644 src/practiceproblems/MinimumWindowSubstring.java create mode 100644 src/practiceproblems/MirrorBinaryTree.java create mode 100644 src/practiceproblems/MobileKeyPadCombinations.java create mode 100644 src/practiceproblems/MoveZeroes.java create mode 100644 src/practiceproblems/NQueens.java create mode 100644 src/practiceproblems/NewRoadsMST.java create mode 100644 src/practiceproblems/NextGreaterElement.java create mode 100644 src/practiceproblems/NextGreaterNumber.java create mode 100644 src/practiceproblems/NextLargestList.java create mode 100644 src/practiceproblems/Node.java create mode 100644 src/practiceproblems/NonDecreasingArray.java create mode 100644 src/practiceproblems/NumberOfBallons.java create mode 100644 src/practiceproblems/NutsAndBoltsMatch.java create mode 100644 src/practiceproblems/OverlappingIntervals.java create mode 100644 src/practiceproblems/OwnDataStructureUtil.java create mode 100644 src/practiceproblems/PalindromePartion.java create mode 100644 src/practiceproblems/PalindromePartitioning.java create mode 100644 src/practiceproblems/PalindromeSinglyLinkedList.java create mode 100644 src/practiceproblems/PalindromicSubSequence.java create mode 100644 src/practiceproblems/PartitionLabel.java create mode 100644 src/practiceproblems/PascalsTriangle.java create mode 100644 src/practiceproblems/PathSumIII.java create mode 100644 src/practiceproblems/Pattern132.java create mode 100644 src/practiceproblems/PerfectSquare.java create mode 100644 src/practiceproblems/PermutationInString.java create mode 100644 src/practiceproblems/PetrolGasStation.java create mode 100644 src/practiceproblems/PlusOne.java create mode 100644 src/practiceproblems/Pow.java create mode 100644 src/practiceproblems/PrisonAfterNDays.java create mode 100644 src/practiceproblems/ProductExceptSelf.java create mode 100644 src/practiceproblems/QueensAttackKing.java create mode 100644 src/practiceproblems/RaceCarMinSteps.java create mode 100644 src/practiceproblems/RandomLinkedList.java create mode 100644 src/practiceproblems/RandomPickWithWeight.java create mode 100644 src/practiceproblems/RangeSum.java create mode 100644 src/practiceproblems/ReconstructItenary.java create mode 100644 src/practiceproblems/RedundantConnection.java create mode 100644 src/practiceproblems/RemoveAdjacentDuplicates.java create mode 100644 src/practiceproblems/RemoveDuplicates.java create mode 100644 src/practiceproblems/RemoveInvalidParentheses.java create mode 100644 src/practiceproblems/RemoveKDigits.java create mode 100644 src/practiceproblems/ReorderLogs.java create mode 100644 src/practiceproblems/ReorganiseString.java create mode 100644 src/practiceproblems/RestoreIpAddresses.java create mode 100644 src/practiceproblems/ReverseWordsInString.java create mode 100644 src/practiceproblems/RollingHashRabinKarp.java create mode 100644 src/practiceproblems/RomanToInteger.java create mode 100644 src/practiceproblems/RotateArray.java create mode 100644 src/practiceproblems/RotateMatrixInPlace.java create mode 100644 src/practiceproblems/RotateMatrixInPlaceAntiClockwise.java create mode 100644 src/practiceproblems/SameTree.java create mode 100644 src/practiceproblems/SearchAMaze.java create mode 100644 src/practiceproblems/SearchAnElementInMatrix.java create mode 100644 src/practiceproblems/SerializeAndDeserialize.java create mode 100644 src/practiceproblems/SerializeDeserializeBST.java create mode 100644 src/practiceproblems/SetBitCount.java create mode 100644 src/practiceproblems/ShuffleArray.java create mode 100644 src/practiceproblems/SimilarExpressions.java create mode 100644 src/practiceproblems/SingleElementInSortedArray.java create mode 100644 src/practiceproblems/SlidingWindow.java create mode 100644 src/practiceproblems/SnakeAndLadder.java create mode 100644 src/practiceproblems/SnakeGame.java create mode 100644 src/practiceproblems/SortANearlySortedArray.java create mode 100644 src/practiceproblems/SortStack.java create mode 100644 src/practiceproblems/SortedArrayToBST.java create mode 100644 src/practiceproblems/SortedSquares.java create mode 100644 src/practiceproblems/SpiralMatrix.java create mode 100644 src/practiceproblems/SpiralMatrixII.java create mode 100644 src/practiceproblems/SplitLinkedList.java create mode 100644 src/practiceproblems/StockBuySellManyTimes.java create mode 100644 src/practiceproblems/StockSpanner.java create mode 100644 src/practiceproblems/StringIterator.java create mode 100644 src/practiceproblems/SubArraySumDivisibleByK.java create mode 100644 src/practiceproblems/SubArraySumEqualsK.java create mode 100644 src/practiceproblems/SubstringWindowTemplate.java create mode 100644 src/practiceproblems/SumOfThreeElements.java create mode 100644 src/practiceproblems/SumSubArrayZero.java create mode 100644 src/practiceproblems/SurroundedRegions.java create mode 100644 src/practiceproblems/SwapRecoverBST.java create mode 100644 src/practiceproblems/SymmetricTree.java create mode 100644 src/practiceproblems/TaskLeastInterval.java create mode 100644 src/practiceproblems/ThreeSum.java create mode 100644 src/practiceproblems/TimeMap.java create mode 100644 src/practiceproblems/TopKFrequentElement.java create mode 100644 src/practiceproblems/TopKFrequentElements.java create mode 100644 src/practiceproblems/TrailingZeroes.java create mode 100644 src/practiceproblems/TreasureIsland.java create mode 100644 src/practiceproblems/TreasureIslandII.java create mode 100644 src/practiceproblems/Trie.java create mode 100644 src/practiceproblems/Twitter.java create mode 100644 src/practiceproblems/TwoCityScheduling.java create mode 100644 src/practiceproblems/TwoSumClosestToZero.java create mode 100644 src/practiceproblems/UnSortedSubArray.java create mode 100644 src/practiceproblems/UniqueElementsInArray.java create mode 100644 src/practiceproblems/UniquePath.java create mode 100644 src/practiceproblems/UniquePathMaximum.java create mode 100644 src/practiceproblems/UrlEncode.java create mode 100644 src/practiceproblems/ValidPalindromeII.java create mode 100644 src/practiceproblems/ValidParentheses.java create mode 100644 src/practiceproblems/ValidParenthesesString.java create mode 100644 src/practiceproblems/ValidSudoku.java create mode 100644 src/practiceproblems/ValidateIpAddresses.java create mode 100644 src/practiceproblems/VulgarDecimal.java create mode 100644 src/practiceproblems/WaterTrapping.java create mode 100644 src/practiceproblems/WordBreak.java create mode 100644 src/practiceproblems/WordBreakII.java create mode 100644 src/practiceproblems/WordDictionary.java create mode 100644 src/practiceproblems/WordLadder.java create mode 100644 src/practiceproblems/WordSearch.java rename src/{strings/common => }/sorting/ImplementABinaryHeap.java (100%) rename src/{strings/common => }/sorting/InsertionSort.java (100%) rename src/{strings/common => }/sorting/KthLargestElement.java (100%) rename src/{strings/common => }/sorting/MaxHeap.java (100%) rename src/{strings/common => }/sorting/MergeSort.java (100%) rename src/{strings/common => }/sorting/PractiseMergeSort.java (100%) rename src/{strings/common => }/sorting/QuickSelect.java (100%) rename src/{strings/common => }/sorting/QuickSort.java (100%) delete mode 100644 src/strings/dynamicProblems/All_Possible_Combinatons.java delete mode 100644 src/strings/dynamicProblems/DynamicIntegerGenerator.java delete mode 100644 src/strings/dynamicProblems/FirstNonRepeating.java delete mode 100644 src/strings/dynamicProblems/PossibleCombinations.java delete mode 100644 src/strings/dynamicProblems/ReverseSentence.java delete mode 100644 src/strings/dynamicProblems/Subsequence.java diff --git a/src/geeksforgeeks/FindMinimumInRotatedArray.java b/src/binarysearch/FindMinimumInRotatedArray.java similarity index 100% rename from src/geeksforgeeks/FindMinimumInRotatedArray.java rename to src/binarysearch/FindMinimumInRotatedArray.java diff --git a/src/binarysearch/FindSmallestDivisor.java b/src/binarysearch/FindSmallestDivisor.java new file mode 100644 index 0000000..df2cf2e --- /dev/null +++ b/src/binarysearch/FindSmallestDivisor.java @@ -0,0 +1,32 @@ +package binarysearch; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/find-the-smallest-divisor-given-a-threshold/ + */ +public class FindSmallestDivisor { + public int smallestDivisor(int[] nums, int threshold) { + int left = 1; + int right = Arrays.stream(nums).max().orElse(0); + + while (left < right) { + int mid = left + (right - left) / 2; + if (isFeasible(nums, mid, threshold)) { + right = mid; + } else { + left = mid + 1; + } + } + + return left; + } + + public boolean isFeasible(int[] nums, int mid, int threshold) { + int total = 0; + for (int num : nums) { + total += (int) Math.ceil((double) num / mid); + } + return total <= threshold; + } +} diff --git a/src/geeksforgeeks/FirstAndLastOccurence.java b/src/binarysearch/FirstAndLastOccurence.java similarity index 100% rename from src/geeksforgeeks/FirstAndLastOccurence.java rename to src/binarysearch/FirstAndLastOccurence.java diff --git a/src/binarysearch/MagneticForceBetweenTwoBalls.java b/src/binarysearch/MagneticForceBetweenTwoBalls.java new file mode 100644 index 0000000..0300d22 --- /dev/null +++ b/src/binarysearch/MagneticForceBetweenTwoBalls.java @@ -0,0 +1,68 @@ +package binarysearch; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/magnetic-force-between-two-balls/ + * + */ +public class MagneticForceBetweenTwoBalls { + + /** + - First, might as well consider the placements in sorted order. + - We only really need to check the forces of balls immediately to their left and right. + - Say our target is D. We want all balls to be at least D units apart. + - We can check if D is doable, by trying a greedy approach. Put the very + first ball at the first available position, place the next ball at the + first position rightwards that is sufficiently distant, etc. + + - We can do a binary search for what minimum distance is achievable. + - With this we have an O(n*log(L/m)) solution. Where L is the largest distance between + baskets, and m is the number of balls we're trying to place, n is number of possible positions. + */ + public int maxDistance(int[] position, int m) { + + Arrays.sort(position); + + int left = 1; + int right = position[position.length - 1]; + + while (left < right) { + int mid = left + (right - left) / 2; + System.out.println("before isFeasible:: left "+left+" right "+right+" mid "+mid); + if (isFeasible(position, m, mid)) { + System.out.println("condition is Feasible so changing right to mid"); + right = mid; + } else { + System.out.println("condition is not Feasible so changing left to mid+1"); + left = mid + 1; + } + System.out.println(); + } + + return left - 1; + } + + public boolean isFeasible(int[] position, int noOfBalls, int minDistance) { + int lastPos = position[0]; // first ball at 0 position - keep track of last position + int idx = 1; + noOfBalls--; // we have placed first ball at 0 position + System.out.println("begin isFeasible:: remaining noOfBalls after placing first "+noOfBalls+" minDistance "+minDistance); + while (idx < position.length && noOfBalls > 0) { + /* if minDistance between last position and position at idx is greater then or equal to minDistance + * then place the ball else skip + * */ + if (position[idx] - lastPos >= minDistance) { + lastPos = position[idx]; + noOfBalls--; + } + idx++; + } + System.out.println("closing isFeasible:: noOfBalls "+noOfBalls); + return noOfBalls != 0; /*if all balls have been placed then return true else false*/ + } + + public static void main(String[] args) { + new MagneticForceBetweenTwoBalls().maxDistance(new int[]{1,2,3,4,7}, 3); + } +} diff --git a/src/binarysearch/MaxSoldiers.java b/src/binarysearch/MaxSoldiers.java new file mode 100644 index 0000000..510bbce --- /dev/null +++ b/src/binarysearch/MaxSoldiers.java @@ -0,0 +1,49 @@ +package geeksforgeeks; + +import java.util.PriorityQueue; + +public class MaxSoldiers { + class Pair { + T row; + S soldiers; + + Pair(T row, S soldiers) { + this.row = row; + this.soldiers = soldiers; + } + } + + public int[] kWeakestRows(int[][] mat, int k) { + int[] result = new int[k]; + PriorityQueue> queue = new PriorityQueue<>((a, b) -> a.soldiers == b.soldiers ? Integer.compare(a.row, b.row) : Integer.compare(a.soldiers, b.soldiers)); + int i = 0; + int soldiers = 0; + for (int[] rows : mat) { + int temp = binarySearchUtil(rows, 0, rows.length); + queue.offer(new Pair<>(i, temp)); + i++; + } + int ind = 0; + while (ind < k) { + result[ind++] = (int) queue.poll().row; + } + return result; + + } + + public int binarySearchUtil(int[] row, int start, int end) { + int lo = 0; + int hi = row.length; + + while (lo < hi) { + int mid = lo + (hi - lo) / 2; + + if (row[mid] == 1) + lo = mid + 1; + else + hi = mid; + } + + return lo; + } +} diff --git a/src/geeksforgeeks/PeakElement.java b/src/binarysearch/PeakElement.java similarity index 100% rename from src/geeksforgeeks/PeakElement.java rename to src/binarysearch/PeakElement.java diff --git a/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java b/src/binarysearch/SearchElementInSortedAndRotatedArray.java similarity index 97% rename from src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java rename to src/binarysearch/SearchElementInSortedAndRotatedArray.java index 8d5e4d2..9ef73ba 100644 --- a/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java +++ b/src/binarysearch/SearchElementInSortedAndRotatedArray.java @@ -58,7 +58,7 @@ public boolean searchII(int[] nums, int target) { mid = (left + right) >> 1; if (nums[mid] == target) return true; - // the only difference from the first one, trickly case, just updat left and right + // the only difference from the first one, tricky case, just update left and right if ((nums[left] == nums[mid]) && (nums[right] == nums[mid])) { ++left; --right; diff --git a/src/geeksforgeeks/MaxSoldiers.java b/src/geeksforgeeks/MaxSoldiers.java deleted file mode 100644 index 8229286..0000000 --- a/src/geeksforgeeks/MaxSoldiers.java +++ /dev/null @@ -1,48 +0,0 @@ -package geeksforgeeks; - -import java.util.PriorityQueue; - -public class MaxSoldiers { - class Pair { - T row; - S soldiers; - Pair(T row, S soldiers){ - this.row=row; - this.soldiers=soldiers; - } - } - - public int[] kWeakestRows(int[][] mat, int k) { - int[] result= new int[k]; - PriorityQueue> queue= new PriorityQueue<>((a, b)->a.soldiers==b.soldiers?Integer.compare(a.row,b.row):Integer.compare(a.soldiers,b.soldiers)); - int i=0; - int soldiers=0; - for(int []rows: mat){ - int temp= binarySearchUtil(rows, 0, rows.length); - queue.offer(new Pair<>(i,temp)); - i++; - } - int ind=0; - while(ind B[i]. + +import java.util.Arrays; +import java.util.PriorityQueue; + +// Return any permutation of A that maximizes its advantage with respect to B. +//Input: A = [12,24,8,32], B = [13,25,32,11] +//Output: [24,32,8,12] +// Input: A = [2,7,11,15], B = [1,10,4,11] +// Output: [2,11,7,15] +public class AdvantageShuffle { + public int[] advantageCount(int[] A, int[] B) { + Arrays.sort(A); + + PriorityQueue pq= new PriorityQueue<>((a, b)->Integer.compare(b[0],a[0])); + for(int i=0;ival){ // if polled element is lesser thar A[hi], put A[hi] at index of + // queued elements index, means, equal to B's current index we are putting + // a value greater that B's in result arrays + result[index]=A[hi--]; + }else{ + result[index]=A[lo++]; + } + } + return result; + } +} \ No newline at end of file diff --git a/src/practiceproblems/AircraftOptimization.java b/src/practiceproblems/AircraftOptimization.java new file mode 100644 index 0000000..f9d859a --- /dev/null +++ b/src/practiceproblems/AircraftOptimization.java @@ -0,0 +1,69 @@ +package practiceproblems; + +import java.util.*; + +/** + * https://leetcode.com/discuss/interview-question/373202 + * Given 2 lists a and b. Each element is a pair of integers where the first integer represents the unique id and the second integer represents a value. + * Your task is to find an element from a and an element form b such that the sum of their values is less or equal to target and as close to target as possible. + * Return a list of ids of selected elements. If no pair is possible, return an empty list. + * + * a = [[1, 2], [2, 4], [3, 6]] + b = [[1, 2]] + target = 7 + + Output: [[2, 1]] + + Explanation: + There are only three combinations [1, 1], [2, 1], and [3, 1], which have a total sum of 4, 6 and 8, respectively. + Since 6 is the largest sum that does not exceed 7, [2, 1] is the optimal pair. + */ +public class AircraftOptimization { + + public List> calculateOptimalRoute(final List> forwardList, + final List> returnList, int capacity) { + + forwardList.sort(Comparator.comparingInt(o->o.get(1))); + returnList.sort(Comparator.comparingInt(o->o.get(1))); + + int max = 0; + int i = 0; + int j = returnList.size() - 1; + + List> result = new LinkedList<>(); + while (i < forwardList.size() && j >= 0) { + int currentSum = forwardList.get(i).get(1) + returnList.get(j).get(1); + + if (currentSum > max && currentSum <= capacity) { + max = currentSum; + // Initializing new list + result = new LinkedList<>(); + result.add(new ArrayList<>(Arrays.asList(forwardList.get(i).get(0), returnList.get(j).get(0)))); + i++; + } else if (currentSum == max) { + // no need to reset result list + result.add(new ArrayList<>(Arrays.asList(forwardList.get(i).get(0), returnList.get(j).get(0)))); + i++; + } else { + j--; + } + } + return result; + } + + public static void main(String[] args) { + AircraftOptimization aircraft = new AircraftOptimization(); + List> returnList = new ArrayList<>(); + returnList.add(new ArrayList<>(Arrays.asList(1, 2000))); + returnList.add(new ArrayList<>(Arrays.asList(2, 3000))); + returnList.add(new ArrayList<>(Arrays.asList(3, 4000))); + returnList.add(new ArrayList<>(Arrays.asList(4, 5000))); + List> forwardList = new ArrayList<>(); + forwardList.add(new ArrayList<>(Arrays.asList(1, 3000))); + forwardList.add(new ArrayList<>(Arrays.asList(2, 5000))); + forwardList.add(new ArrayList<>(Arrays.asList(3, 7000))); + forwardList.add(new ArrayList<>(Arrays.asList(4, 10000))); + List> calculateOptimalRoute = aircraft.calculateOptimalRoute(forwardList, returnList, 10000); + System.out.println(calculateOptimalRoute); + } +} diff --git a/src/practiceproblems/AlternateOddAndEvenNumbers.java b/src/practiceproblems/AlternateOddAndEvenNumbers.java new file mode 100644 index 0000000..8b66205 --- /dev/null +++ b/src/practiceproblems/AlternateOddAndEvenNumbers.java @@ -0,0 +1,50 @@ +package practiceproblems; + +import java.util.Arrays; + +/** + * https://www.geeksforgeeks.org/rearrange-positive-and-negative-numbers-publish/ + * An array contains both positive and negative numbers in random order. + * Rearrange the array elements so that positive and negative numbers are placed alternatively. + * If there are more positive numbers they appear at the end of the array. + * If there are more negative numbers, they too appear in the end of the array. + * [-1, 2, -3, 4, 5, 6, -7, 8, 9] + * output [9, -7, 8, -3, 5, -1, 2, 4, 6] or[4, -3, 5, -1, 6, -7, 2, 8, 9] + */ +class AlternateOddAndEvenNumbers { + + static void rearrange(int arr[], int n) { + //-1, 2, -3, 4, 5, 6, -7, 8, 9 + int i = 0, temp = 0; + for (int j = 0; j < n; j++) { + if (arr[j] < 0) { + temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + i++; + } + } + // we have segregated positive and negative elements + System.out.println(Arrays.toString(arr)+" :i - "+i); + // now the 'pos' indicates start of positive integer, 'neg' starts from 0; + int pos = i , neg = 0; + + + + while (pos < n && neg < pos && arr[neg] < 0) { + temp = arr[neg]; + arr[neg] = arr[pos]; + arr[pos] = temp; + pos++; + neg += 2; // need to skip next element as output should be alternative + System.out.println(Arrays.toString(arr)); + } + } + + public static void main(String[] args) { + int arr[] = { -1, 2, -3, 4, 5, 6, -7, 8, 9 }; + int n = arr.length; + rearrange(arr, n); + System.out.println("Array after rearranging: "+ Arrays.toString(arr)); + } +} diff --git a/src/practiceproblems/AngleOfClock.java b/src/practiceproblems/AngleOfClock.java new file mode 100644 index 0000000..3404e00 --- /dev/null +++ b/src/practiceproblems/AngleOfClock.java @@ -0,0 +1,15 @@ +package practiceproblems; + +public class AngleOfClock { + public double angleClock(int hours, int minutes) { + // every hour is 30(deg) (360 (deg)/12) because 12 hrs in clock + // every min is 6(deg) (360(deg)/60) because 60 mins per hr + // we take mod of 12 because 12th hr needs to be 0* + double hourHand= (hours%12 + (double)minutes/60)*30; + double minHand= minutes*6; + double absAngle= Math.abs(hourHand-minHand); + if(absAngle>180) absAngle= 360-absAngle; // this is because when time is 0.02 the angel will be 358 + + return absAngle; + } +} \ No newline at end of file diff --git a/src/practiceproblems/ArrangeInQueue.java b/src/practiceproblems/ArrangeInQueue.java new file mode 100644 index 0000000..2ea3c8b --- /dev/null +++ b/src/practiceproblems/ArrangeInQueue.java @@ -0,0 +1,51 @@ +package practiceproblems; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +//You are given an array of people, people, +// which are the attributes of some people in a queue (not necessarily in order). +// Each people[i] = [hi, ki] represents the ith person of height hi with exactly ki +// other people in front who have a height greater than or equal to hi. +//Reconstruct and return the queue that is represented by the input array people. +// The returned queue should be formatted as an array queue, +// where queue[j] = [hj, kj] is the attributes of the jth person in the +// queue (queue[0] is the person at the front of the queue). + +// Input: +// [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] +// Output: +// [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]] +//Explanation: +// Person 0 has height 5 with no other people taller or the same height in front. +// Person 1 has height 7 with no other people taller or the same height in front. +// Person 2 has height 5 with two persons taller or the same height in front, which is person 0 and 1. +// Person 3 has height 6 with one person taller or the same height in front, which is person 1. +// Person 4 has height 4 with four people taller or the same height in front, which are people 0, 1, 2, and 3. +// Person 5 has height 7 with one person taller or the same height in front, which is person 1. +// Hence [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] is the reconstructed queue. +public class ArrangeInQueue { + +// 1. Sort people by their height, shortest to tallest +// 2. Iterate and put each person to the correct position +// 2.a When placing the shortest person, all person to his left will be taller or equal height, since you are iterating in height sorted array, so put it at a index equal to its k value +// 2.b When placing the next shortest person, find a position, where count of positions to the left unoccupied plus the ones where same height person is placed, is equal to its k value +// 2.c Keep repeating + public static int[][] reconstructQueue(int[][] people) { + List result= new ArrayList<>(); + Arrays.sort(people,(a, b)->{ + if(a[0]==b[0]) return a[1]-b[1]; + else return b[0]-a[0]; + }); + System.out.println("Sorted values: "+ Arrays.deepToString(people)); + for(int[] x: people){ + result.add(x[1],x); + System.out.println(Arrays.deepToString(result.toArray(new int[people.length][2]))); + } + return result.toArray(new int[people.length][2]); + } + + public static void main(String[] args) { + System.out.println(Arrays.deepToString(reconstructQueue(new int[][]{{7,0},{4,4},{7,1},{5,0},{6,1},{5,2}}))); + } +} \ No newline at end of file diff --git a/src/practiceproblems/ArticulationPoint.java b/src/practiceproblems/ArticulationPoint.java new file mode 100644 index 0000000..c552acf --- /dev/null +++ b/src/practiceproblems/ArticulationPoint.java @@ -0,0 +1,369 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Date 08/22/2015 + * + * @author Tushar Roy + * + * Find articulation points in connected undirected graph. Articulation + * points are vertices such that removing any one of them disconnects + * the graph. + * + * We need to do DFS of this graph and keep visitedTime and lowTime for + * each vertex. lowTime is keeps track of back edges. + * + * If any one of following condition meets then vertex is articulation + * point. + * + * 1) If vertex is root of DFS and has atlesat 2 independent + * children.(By independent it means they are not connected to each + * other except via this vertex). This condition is needed because if we + * started from corner vertex it will meet condition 2 but still is not + * an articulation point. To filter out those vertices we need this + * condition. + * + * 2) It is not root of DFS and if visitedTime of vertex <= lowTime of + * any adjacent vertex then its articulation point. + * + * Time complexity is O(E + V) Space complexity is O(V) + * + * References: https://en.wikipedia.org/wiki/Biconnected_component + * http://www.geeksforgeeks.org/articulation-points-or-cut-vertices-in-a-graph/ + */ +public class ArticulationPoint { + + private int time; + + public Set> findarticulationPoints(Graph graph) { + time = 0; + Set> visited = new HashSet<>(); + Set> articulationPoints = new HashSet<>(); + Vertex startVertex = graph.getAllVertex().iterator().next(); + + Map, Integer> visitedTime = new HashMap<>(); + Map, Integer> lowTime = new HashMap<>(); + Map, Vertex> parent = new HashMap<>(); + + DFS(visited, articulationPoints, startVertex, visitedTime, lowTime, parent); + return articulationPoints; + } + + private void DFS(Set> visited, Set> articulationPoints, Vertex vertex, + Map, Integer> visitedTime, Map, Integer> lowTime, Map, Vertex> parent) { + visited.add(vertex); + visitedTime.put(vertex, time); + lowTime.put(vertex, time); + time++; + int childCount = 0; + boolean isArticulationPoint = false; + for (Vertex adj : vertex.getAdjacentVertexes()) { + // if adj is same as parent then just ignore this vertex. + if (adj.equals(parent.get(vertex))) { + continue; + } + // if adj has not been visited then visit it. + if (!visited.contains(adj)) { + parent.put(adj, vertex); + childCount++; + DFS(visited, articulationPoints, adj, visitedTime, lowTime, parent); + + if (visitedTime.get(vertex) <= lowTime.get(adj)) { + isArticulationPoint = true; + } else { + // below operation basically does lowTime[vertex] = min(lowTime[vertex], + // lowTime[adj]); + lowTime.compute(vertex, (currentVertex, time) -> Math.min(time, lowTime.get(adj))); + } + + } else { // if adj is already visited see if you can get better low time. + // below operation basically does lowTime[vertex] = min(lowTime[vertex], + // visitedTime[adj]); + lowTime.compute(vertex, (currentVertex, time) -> Math.min(time, visitedTime.get(adj))); + } + } + + // checks if either condition 1 or condition 2 meets). If yes then it is + // articulation point. + if ((parent.get(vertex) == null && childCount >= 2) || parent.get(vertex) != null && isArticulationPoint) { + articulationPoints.add(vertex); + } + + } + + public static void main(String args[]) { + Graph graph = new Graph<>(false); + /* graph.addEdge(1, 2); + graph.addEdge(2, 3); + graph.addEdge(1, 3); + graph.addEdge(1, 4); + graph.addEdge(4, 5); + graph.addEdge(5, 6); + graph.addEdge(6, 7); + graph.addEdge(7, 5); + graph.addEdge(6, 8);*/ + + graph.addEdge(4, 3); + graph.addEdge(1, 2); + graph.addEdge(2, 3); + graph.addEdge(3, 4); + + + // bigger example + /* + * graph.addEdge(0, 1); graph.addEdge(0, 2); graph.addEdge(0, 3); + * graph.addEdge(0, 4); graph.addEdge(4, 2); graph.addEdge(3, 5); + * graph.addEdge(4, 6); graph.addEdge(6, 3); graph.addEdge(6, 7); + * graph.addEdge(6, 8); graph.addEdge(7, 9); graph.addEdge(9, 10); + * graph.addEdge(8, 10); + */ + + ArticulationPoint ap = new ArticulationPoint<>(); + Set> aPoints = ap.findarticulationPoints(graph); + aPoints.forEach(System.out::println); + } + +} + +class Graph { + + List> allEdges; + Map> allVertex; + boolean isDirected = false; + + public Graph(boolean isDirected) { + allEdges = new ArrayList<>(); + allVertex = new HashMap<>(); + this.isDirected = isDirected; + } + + public void addEdge(long id1, long id2) { + addEdge(id1, id2, 0); + } + + public void addVertex(Vertex vertex) { + if (allVertex.containsKey(vertex.getId())) { + return; + } + allVertex.put(vertex.getId(), vertex); + for (Edge edge : vertex.getEdges()) { + allEdges.add(edge); + } + } + + public Vertex addSingleVertex(long id) { + if (allVertex.containsKey(id)) { + return allVertex.get(id); + } + Vertex v = new Vertex<>(id); + allVertex.put(id, v); + return v; + } + + public Vertex getVertex(long id) { + return allVertex.get(id); + } + + public void addEdge(long id1, long id2, int weight) { + Vertex vertex1 = null; + if (allVertex.containsKey(id1)) { + vertex1 = allVertex.get(id1); + } else { + vertex1 = new Vertex<>(id1); + allVertex.put(id1, vertex1); + } + Vertex vertex2 = null; + if (allVertex.containsKey(id2)) { + vertex2 = allVertex.get(id2); + } else { + vertex2 = new Vertex<>(id2); + allVertex.put(id2, vertex2); + } + + Edge edge = new Edge<>(vertex1, vertex2, isDirected, weight); + allEdges.add(edge); + vertex1.addAdjacentVertex(edge, vertex2); + if (!isDirected) { + vertex2.addAdjacentVertex(edge, vertex1); + } + } + + public List> getAllEdges() { + return allEdges; + } + + public Collection> getAllVertex() { + return allVertex.values(); + } + + public void setDataForVertex(long id, T data) { + if (allVertex.containsKey(id)) { + Vertex vertex = allVertex.get(id); + vertex.setData(data); + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for (Edge edge : getAllEdges()) { + sb.append(edge.getVertex1() + " " + edge.getVertex2() + " " + edge.getWeight()); + sb.append("\n"); + } + return sb.toString(); + } +} + +class Vertex { + long id; + T data; + List> edges = new ArrayList<>(); + List> adjacentVertex = new ArrayList<>(); + + Vertex(long id) { + this.id = id; + } + + public long getId() { + return id; + } + + public void setData(T data) { + this.data = data; + } + + public T getData() { + return data; + } + + public void addAdjacentVertex(Edge e, Vertex v) { + edges.add(e); + adjacentVertex.add(v); + } + + public String toString() { + return String.valueOf(id); + } + + public List> getAdjacentVertexes() { + return adjacentVertex; + } + + public List> getEdges() { + return edges; + } + + public int getDegree() { + return edges.size(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (int) (id ^ (id >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Vertex other = (Vertex) obj; + + return id != other.id; + } +} + +class Edge { + boolean isDirected = false; + Vertex vertex1; + Vertex vertex2; + int weight; + + Edge(Vertex vertex1, Vertex vertex2) { + this.vertex1 = vertex1; + this.vertex2 = vertex2; + } + + Edge(Vertex vertex1, Vertex vertex2, boolean isDirected, int weight) { + this.vertex1 = vertex1; + this.vertex2 = vertex2; + this.weight = weight; + this.isDirected = isDirected; + } + + Edge(Vertex vertex1, Vertex vertex2, boolean isDirected) { + this.vertex1 = vertex1; + this.vertex2 = vertex2; + this.isDirected = isDirected; + } + + Vertex getVertex1() { + return vertex1; + } + + Vertex getVertex2() { + return vertex2; + } + + int getWeight() { + return weight; + } + + public boolean isDirected() { + return isDirected; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((vertex1 == null) ? 0 : vertex1.hashCode()); + result = prime * result + ((vertex2 == null) ? 0 : vertex2.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Edge other = (Edge) obj; + if (vertex1 == null) { + if (other.vertex1 != null) { + return false; + } + } else if (!vertex1.equals(other.vertex1)) { + return false; + } + if (vertex2 == null) { + if (other.vertex2 != null) { + return false; + } + } else if (!vertex2.equals(other.vertex2)) { + return false; + } + return true; + } + + @Override + public String toString() { + return "Edge [isDirected=" + isDirected + ", vertex1=" + vertex1 + ", vertex2=" + vertex2 + ", weight=" + weight + + "]"; + } +} \ No newline at end of file diff --git a/src/practiceproblems/AutoCompleteSystem.java b/src/practiceproblems/AutoCompleteSystem.java new file mode 100644 index 0000000..1a8efdb --- /dev/null +++ b/src/practiceproblems/AutoCompleteSystem.java @@ -0,0 +1,97 @@ +package practiceproblems; + +import java.util.*; + +/** + * https://cheonhyangzhang.gitbooks.io/leetcode-solutions/content/642-design-search-autocomplete-system.html + */ +class AutoCompleteSystem { + + static class TrieNode { + Map children; + Map counts; + boolean isWord; + + public TrieNode() { + children = new HashMap<>(); + counts = new HashMap<>(); + isWord = false; + } + } + + TrieNode root; // points to the root of the trie to be initialised + String prefix; // concat and stores the input char sequence from main function + + public AutoCompleteSystem(String[] sentences, int[] times) { + root = new TrieNode(); + prefix = ""; + // for the given word and freq value we proceed to add it to trie + for (int i = 0; i < sentences.length; i++) { + add(sentences[i], times[i]); + } + } + + private void add(String s, int count) { + TrieNode curr = root; + for (char c : s.toCharArray()) { + curr.children.putIfAbsent(c, new TrieNode()); + curr = curr.children.get(c); + // for every node in the trie(which has one char val) + //the counts map will store the original word along with it's freq value + // for the given input 'i love leetcode' and 'i love you' + // the trie Node(i) => Map(i love leetcode -> 2, i love you->5, island->3, ironman->2) + // / + // Node(' ') => Map(i love leetcode -> 2, i love you->5) + + // the trie Node(i) => Map(i love leetcode -> 2, i love you->5, island->3, ironman->2) + // \ + // Node('s') => Map(island->3) + curr.counts.put(s, curr.counts.getOrDefault(s, 0) + count); + } + curr.isWord = true; + } + + public List input(char c) { + if (c == '#') { + add(prefix, 1); + prefix = ""; + return new ArrayList<>(); + } + prefix = prefix + c; + + TrieNode curr = root; + + for (char ch : prefix.toCharArray()) { + if (!curr.children.containsKey(ch)) { + return new ArrayList<>(); + } + curr = curr.children.get(ch); + } + + Comparator> cmp = (a, b) -> a.getValue().equals(b.getValue()) ? + b.getKey().compareTo(a.getKey()) : + a.getValue() - b.getValue(); + PriorityQueue> pq = new PriorityQueue<>(cmp); + int k = 3; + for (Map.Entry entry : curr.counts.entrySet()) { + pq.offer(entry); + while (!pq.isEmpty() && pq.size() > k) { + pq.poll(); + } + } + + ArrayList res = new ArrayList<>(); + while (!pq.isEmpty()) { + res.add(0, pq.poll().getKey()); + } + return res; + } + + public static void main(String[] args) { + String[] sentences = { "i love you", "island", "ironman", "i love leetcode" }; + int[] times = { 5, 3, 2, 2 }; + AutoCompleteSystem autoCompleteSystem = new AutoCompleteSystem(sentences, times); + System.out.println(autoCompleteSystem.input('i')); + System.out.println(autoCompleteSystem.input(' ')); + } +} \ No newline at end of file diff --git a/src/practiceproblems/BackspaceCompare.java b/src/practiceproblems/BackspaceCompare.java new file mode 100644 index 0000000..151c4c0 --- /dev/null +++ b/src/practiceproblems/BackspaceCompare.java @@ -0,0 +1,63 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/backspace-string-compare/ + * Given two strings S and T, return if they are equal when both are typed into empty text editors. # means a backspace character. + * + * Note that after backspacing an empty text, the text will continue empty. + * + * Input: S = "ab#c", T = "ad#c" + * Output: true + * Explanation: Both S and T become "ac". + * + * Input: S = "a##c", T = "#a#c" + * Output: true + * Explanation: Both S and T become "c". + */ +class BackspaceCompare { + + public static boolean backspaceCompare(String S, String T) { + + if (S == null || T == null) { + return S == T; + } + int i = S.length() - 1, j = T.length() - 1; + int cnt1 = 0, cnt2 = 0;//number of '#'; + while (i >= 0 || j >= 0) { + //this while loop is executed 2 times i) when it sees '#' it increments the count 'cnt1' + // ii) since 'cnt1'>0 + // the above logic is decrementing the 'i' i.e deleting the char before '#' + + while (i >= 0 && (S.charAt(i) == '#' || cnt1 > 0)) { + if (S.charAt(i) == '#') { + cnt1++; + } else { + cnt1--; + } + i--; + } + + // same as previous comment + while (j >= 0 && (T.charAt(j) == '#' || cnt2 > 0)) { + if (T.charAt(j) == '#') { + cnt2++; + } else { + cnt2--; + } + j--; + } + // if the non '#' char is not equal, then no need to proceed further + if (i >= 0 && j >= 0 && S.charAt(i) == T.charAt(j)) { + i--; + j--; + } else { + return i == -1 && j == -1; + } + } + return true; + } + + public static void main(String[] args) { + System.out.println(backspaceCompare("a##c", "#a#c")); + } +} \ No newline at end of file diff --git a/src/practiceproblems/BasicCalculator.java b/src/practiceproblems/BasicCalculator.java new file mode 100644 index 0000000..53e1ac3 --- /dev/null +++ b/src/practiceproblems/BasicCalculator.java @@ -0,0 +1,64 @@ +package practiceproblems; + +import java.util.ArrayDeque; +import java.util.Deque; + +// Input: "(1+(4+5+2)-3)+(6+8)" +// Output: 23 +public class BasicCalculator { + + public static void main(String[] args) { + System.out.println(calculate("-26-(5-6)")); + System.out.println(calculate("(1+(4+5+2)-3)+(6+8)")); + } + + public static int calculate(String s) { + if (s == null || s.length() == 0) return -1; + Deque deque = new ArrayDeque<>(); + int sign = 1; + int number = 0; + int result = 0; + // let's take an edge case 2-(5-6)=3; + // at i=0 number=2 + // i=1 char ='-' update with prev seen sign res=sign*number reset number we are looking for next operand + //i=2 char='(' and sign is '-', push prev result and sign and reset result for calclating + // sub problem inside braces + // i=3 update number to 5 + // i=4 char ='-' update result as sign*number = 5 reset number and sign =-1 + //i=5 update number to 6 + // i=6 char=')' update result with existing number(res=5=> 5+(-1*6)) and sign inside the braces + // then pop, which is last seen sign outside brace=> -1 and pop again to get result outside brace + // add all to result; + + for (int i = 0; i < s.length(); i++) { + char temp = s.charAt(i); + if (Character.isDigit(temp)) { + number = number * 10 + temp - '0'; + } else if (temp == '+') { + result += sign * number; + number = 0; + sign = 1; + } else if (temp == '-') { + result += sign * number; + number = 0; + sign = -1; + } else if (temp == '(') { + deque.addLast(result); + deque.addLast(sign); + + result = 0; + sign = 1; + } else if (temp == ')') { + result += sign * number; + number = 0; + result *= deque.removeLast(); + result += deque.removeLast(); + + } + } + if (number != 0) result += sign * number; + return result; + } + + +} \ No newline at end of file diff --git a/src/practiceproblems/BinaryTreeCousins.java b/src/practiceproblems/BinaryTreeCousins.java new file mode 100644 index 0000000..a9859fe --- /dev/null +++ b/src/practiceproblems/BinaryTreeCousins.java @@ -0,0 +1,51 @@ +package practiceproblems; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * In a binary tree, the root node is at depth 0, + * and children of each depth k node are at depth k+1. + * Two nodes of a binary tree are cousins if they have the same depth, + * but have different parents. + * We are given the root of a binary tree with unique values, + * and the values x and y of two different nodes in the tree. + * Return true if and only if the nodes corresponding to the values x and y are cousins. + * + * Input: root = [1,2,3,null,4,null,5], x = 5, y = 4 + * Output: true + * 1 + * / \ + * 2 3 + * \ \ + * 4 5 + * + */ +public class BinaryTreeCousins { + public boolean isCousins(TreeNode root, int x, int y) { + Queue queue = new LinkedList<>(); + if(root == null) return false; + queue.add(root); + int depthY = -1; + int depthX = -2; + int level = 0; + while(!queue.isEmpty()){ + int size = queue.size(); + for(int i = 0 ; i < size ; i++){ + TreeNode node = queue.remove(); + // eagerly checking if both vales are of same parent + if(node.left != null && node.right != null){ + if(node.left.val == x && node.right.val == y) return false; + if(node.left.val == y && node.right.val == x) return false; + } + //now checking if any of x or y matches with current node and records the level + if(node.val == x) depthX = level; + if(node.val == y) depthY = level; + if(node.left != null) queue.add(node.left); + if(node.right != null) queue.add(node.right); + } + level++; + } + return depthX == depthY; + } +} \ No newline at end of file diff --git a/src/practiceproblems/BitonicSearch.java b/src/practiceproblems/BitonicSearch.java new file mode 100644 index 0000000..6461359 --- /dev/null +++ b/src/practiceproblems/BitonicSearch.java @@ -0,0 +1,102 @@ +package practiceproblems; + +/* A Bitonic Sequence is a sequence of numbers which is first strictly increasing then after a point strictly decreasing.*/ +public class BitonicSearch { + + static int ascendingBinarySearch(int[] arr, int low, int high, int key) { + while (low <= high) { + int mid = low + (high - low) / 2; + if (arr[mid] == key) { + return mid; + } + if (arr[mid] > key) { + high = mid - 1; + } else { + low = mid + 1; + } + } + return -1; + } + + static int descendingBinarySearch(int[] arr, int low, int high, int key) { + while (low <= high) { + int mid = low + (high - low) / 2; + if (arr[mid] == key) { + return mid; + } + if (arr[mid] < key) { + high = mid - 1; + } else { + low = mid + 1; + } + } + return -1; + } + + // instead of writing two methods, we can write a method which contains order agnostic + // binary search, which compares the first and last element at first and inside while + // if ascending add below + // if (arr[mid] > key) { + // high = mid - 1; + // } else { + // low = mid + 1; + // } + //else if decending + // if (arr[mid] < key) { + // high = mid - 1; + // } else { + // low = mid + 1; + // } + + + // -3,1,-2,-3,-4,-5,-6 + static int findBitonicPoint(int arr[], int n, int l, int r) { + int mid = ((r + l) / 2) + l; + if (arr[mid] > arr[mid - 1] && arr[mid] > arr[mid + 1]) { + return mid; + } else { + // towards right if next number is greater + if (arr[mid] > arr[mid - 1] && arr[mid] < arr[mid + 1]) { + mid = findBitonicPoint(arr, n, mid, r); + } else { + // towards left if next number is smaller + if (arr[mid] < arr[mid - 1] && arr[mid] > arr[mid + 1]) { + mid = findBitonicPoint(arr, n, l, mid); + } + } + } + return mid; + } + + static int searchBitonic(int arr[], int n, int key, int index) { + if (key > arr[index]) { + return -1; + } else if (key == arr[index]) { + return index; + } else { + int temp = ascendingBinarySearch(arr, 0, index - 1, key); + if (temp != -1) { + return temp; + } + return descendingBinarySearch(arr, index + 1, n - 1, key); + } + } + + public static void main(String args[]) { + int[] arr = { -3, 3, 9, 8, 20, 17, 5, 3, 1 }; + int key = 3; + int n = arr.length; + int l = 0; + int r = n - 1; + int index = findBitonicPoint(arr, n, l, r); + + int x = searchBitonic(arr, n, key, index); + + if (x == -1) { + System.out.println("Element Not Found"); + } else { + System.out.println("Element Found at index " + x); + } + + } +} \ No newline at end of file diff --git a/src/practiceproblems/BoatsToSave.java b/src/practiceproblems/BoatsToSave.java new file mode 100644 index 0000000..58c1e93 --- /dev/null +++ b/src/practiceproblems/BoatsToSave.java @@ -0,0 +1,36 @@ +package practiceproblems; + +import java.util.Arrays; + +/** + * The i-th person has weight people[i], + * and each boat can carry a maximum weight of limit. + * Each boat carries at most 2 people at the same time, + * provided the sum of the weight of those people is at most limit. + * Return the minimum number of boats to carry every given person. + * (It is guaranteed each person can be carried by a boat.) + */ +class BoatsToSave { + public int numRescueBoats(int[] people, int limit) { + if(people.length==0 || limit==0) return 0; + + Arrays.sort(people); + + int i=0; + int j=people.length-1; + int res=0; + while(i<=j){ + if(people[i]+people[j]<=limit){ + res++; + i++; + j--; + }else{ + res++; + j--;// neglecting people with more weight + } + + } + + return res; + } +} \ No newline at end of file diff --git a/src/practiceproblems/BuyAndSellStockAnytime.java b/src/practiceproblems/BuyAndSellStockAnytime.java new file mode 100644 index 0000000..9b96c88 --- /dev/null +++ b/src/practiceproblems/BuyAndSellStockAnytime.java @@ -0,0 +1,23 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ + */ +public class BuyAndSellStockAnytime { + + public int maxProfit(int[] prices) { + int total = 0; + for (int i = 0; i < prices.length - 1; i++) { + if (prices[i + 1] > prices[i]) { + total += prices[i + 1] - prices[i]; + } + } + return total; + } + + public static void main(String[] args) { + BuyAndSellStockAnytime stock = new BuyAndSellStockAnytime(); + int[] arr = { 7, 1, 5, 6, 4 }; + System.out.println(stock.maxProfit(arr)); + } +} diff --git a/src/practiceproblems/BuyAndSellStockAtMostTwice.java b/src/practiceproblems/BuyAndSellStockAtMostTwice.java new file mode 100644 index 0000000..96153e1 --- /dev/null +++ b/src/practiceproblems/BuyAndSellStockAtMostTwice.java @@ -0,0 +1,50 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/maximum-profit-by-buying-and-selling-a-share-at-most-twice/ + */ +class BuyAndSellStockAtMostTwice { + + public static void main(String args[]) { + int price[] = { 2, 30, 15, 10, 8, 25, 80 }; + int n = price.length; + System.out.println("Maximum Profit = " + maxProfit(price)); + } + + /** + * the idea is when we find a profit which is from + * i to n, we can break it in to i to k, k+1 to n + * in this manner at each point we can calculate profit from + * (left min element to current element) and (current element to right max element) + * the second part of the above eq can be achieved by coming from right to left + * for input [3,3,5,0,0,3,1,4] + * profit from l->r [0,0,2,2,2,3,3,4] + * profit from r->l [4,4,4,4,4,3,3,0] + * this simply states that at index 2 if we come from left the profit is 2 + * and we can initiate another transaction to obtain another profit + */ + public static int maxProfit(int[] prices) { + int ans = 0; + if (prices.length == 0 || prices.length == 1) + return ans; + int[] p = new int[prices.length]; + int minBuy = prices[0]; + int maxProfit = 0; + for (int i=1;i=0;i--) { + maxSell = Math.max(maxSell, prices[i]); + maxProfit = Math.max(maxProfit, maxSell - prices[i]); + p[i] += maxProfit; + ans = Math.max(p[i], ans); + } + return ans; + } + +} diff --git a/src/practiceproblems/Candy.java b/src/practiceproblems/Candy.java new file mode 100644 index 0000000..0e804ef --- /dev/null +++ b/src/practiceproblems/Candy.java @@ -0,0 +1,58 @@ +package practiceproblems; + +import java.util.Arrays; + +/** + * https://www.hackerrank.com/challenges/candies/problem + * Alice wants to give at least 1 candy to each child. + * If two children sit next to each other, then + * the one with the higher rating must get more candies than neighbour (left and right). + * Alice wants to minimize the total number of candies she must buy. + + For example, assume her students' ratings are [4, 6, 4, 5, 6, 2]. + She gives the students candy in the following minimal amounts: [1, 2, 1, 2, 3, 1]. She must buy a minimum of 10 candies. + */ +class Candy { + + // 2, 4, 2, 6, 1, 7, 8, 3, 2, 1 + // 1, 2, 1, 2, 1, 2, 3, 1, 1, 1 + // 1, 2, 4, 3, 2, 1 + int candy(int[] ratings) { + int size = ratings.length; + if (size <= 1) { + return size; + } + + // ideally we should maintain 2 arrays 1)L->R 2) R->L + // then iterate both and check max b/w 2 items as result for each index + // we optimise it further for extra space and for loop + int[] num = new int[size]; + Arrays.fill(num, 1); + // left to right + for (int i = 1; i < size; i++) { + if (ratings[i] > ratings[i - 1]) { + num[i] = num[i - 1] + 1; + } + } + + // right to left + for (int i = size - 1; i > 0; i--) { + if (ratings[i - 1] > ratings[i]) { + // check curr index + 1 or existing value + num[i - 1] = Math.max(num[i] + 1, num[i - 1]); + } + } + int result = 0; + for (int i = 0; i < size; i++) { + result += num[i]; + } + return result; + } + + public static void main(String[] args) { + Candy candy = new Candy(); + + int[] ratings = { 2, 4, 2, 6, 1, 7, 8, 9, 2, 1 }; + System.out.println(candy.candy(ratings)); + } +} \ No newline at end of file diff --git a/src/practiceproblems/CelebrityProblem.java b/src/practiceproblems/CelebrityProblem.java new file mode 100644 index 0000000..91a464b --- /dev/null +++ b/src/practiceproblems/CelebrityProblem.java @@ -0,0 +1,29 @@ +package practiceproblems; + +public class CelebrityProblem { + /** + * @param n a party with n people + * + * @return the celebrity's label or -1 + */ + public int findCelebrity(int n) { + int candidate = 0; + for (int i = 1; i < n; i++) { + if (knows(candidate, i)) { + candidate = i; + } + } + + for (int i = 0; i < n; i++) { + if (i != candidate && (knows(candidate, i) || !knows(i, candidate))) { + return -1; + } + } + + return candidate; + } + + public boolean knows(int candidate, int i) { + return false; + } +} \ No newline at end of file diff --git a/src/practiceproblems/CheckPalindromePermutation.java b/src/practiceproblems/CheckPalindromePermutation.java new file mode 100644 index 0000000..2e1e057 --- /dev/null +++ b/src/practiceproblems/CheckPalindromePermutation.java @@ -0,0 +1,32 @@ +package practiceproblems; + +/** + * Given a string, determine if a permutation of the string could form a palindrome. + * Input: "code" + * Output: false + * Input: "carerac" + Output: true + */ +public class CheckPalindromePermutation { + // If a string with an even length is a palindrome, every character in the string must always occur an even number of times. + // If the string with an odd length is a palindrome, every character except one of the characters must always occur an even number of times. + // Thus, in case of a palindrome, the number of characters with odd number of occurrences can't exceed 1 + + public boolean canPermutePalindrome(String s) { + if(s==null || s.length()==0) return false; + int[] cache= new int[128]; + + for(char ch: s.toCharArray()){ + cache[ch]++; + } + + int oddCOunt=0; + + for(int i=0;i<128;i++){ + oddCOunt+= cache[i]%2; + if(oddCOunt>1) return false; + } + + return true; + } +} \ No newline at end of file diff --git a/src/practiceproblems/CloneGraph.java b/src/practiceproblems/CloneGraph.java new file mode 100644 index 0000000..ba1569b --- /dev/null +++ b/src/practiceproblems/CloneGraph.java @@ -0,0 +1,70 @@ +package practiceproblems; + +import java.util.*; + +/** + * Given a reference of a node in a connected undirected graph. + * + * Return a deep copy (clone) of the graph. + * + * Each node in the graph contains a val (int) and a list (List[Node]) of its neighbors + * + * For simplicity sake, each node's value is the same as the node's index (1-indexed). + * For example, the first node with val = 1, the second node with val = 2, and so on. + * The graph is represented in the test case using an adjacency list. + * + * Adjacency list is a collection of unordered lists used to represent a finite graph. + * Each list describes the set of neighbors of a node in the graph. + * + * The given node will always be the first node with val = 1. + * You must return the copy of the given node as a reference to the cloned graph. + */ +public class CloneGraph { + private static class Node { + public int val; + public List neighbors; + + public Node() { + val = 0; + neighbors = new ArrayList(); + } + + public Node(int _val) { + val = _val; + neighbors = new ArrayList(); + } + + public Node(int _val, ArrayList _neighbors) { + val = _val; + neighbors = _neighbors; + } + } + public Node cloneGraph(Node node) { + if(node==null) return node; + + Map map= new HashMap<>(); + + Queue queue= new ArrayDeque<>(); + queue.offer(node); + map.put(node, new Node(node.val)); + + while(!queue.isEmpty()){ + Node current= queue.poll(); + + for(Node neighbors: current.neighbors){ + if(!map.containsKey(neighbors)){ + Node neighborClone= new Node(neighbors.val); + map.put(neighbors,neighborClone); + queue.offer(neighbors); + } + + map.get(current).neighbors.add(map.get(neighbors)); + } + } + + return map.get(node); + + } + + +} \ No newline at end of file diff --git a/src/practiceproblems/ClosestNumbers.java b/src/practiceproblems/ClosestNumbers.java new file mode 100644 index 0000000..fffed1e --- /dev/null +++ b/src/practiceproblems/ClosestNumbers.java @@ -0,0 +1,45 @@ +package practiceproblems; + +import java.util.Arrays; + +/** + * https://www.geeksforgeeks.org/closest-numbers-list-unsorted-integers/ + * Given a list of distinct unsorted integers, + * find the pair of elements that have the smallest absolute difference between them? + * If there are multiple pairs, find them all. + * Input : arr[] = {10, 50, 12, 100} +Output : (10, 12) +The closest elements are 10 and 12 + +Input : arr[] = {5, 4, 3, 2} +Output : (2, 3), (3, 4), (4, 5) + */ +public class ClosestNumbers { + + public static void main(String[] args) { + //10, 50, 12, 100 + int[] arr = new int[] { 10, 50, 12, 100 }; + int n = arr.length; + if (n <= 1) { + return; + } + + // Sort array elements + Arrays.sort(arr); + + // Compare differences of adjacent + // pairs to find the minimum difference. + int minDiff = arr[1] - arr[0]; + for (int i = 2; i < n; i++) + minDiff = Math.min(minDiff, arr[i] - arr[i - 1]); + + // Traverse array again and print all pairs + // with difference as minDiff. + for (int i = 1; i < n; i++) { + if ((arr[i] - arr[i - 1]) == minDiff) { + System.out.print("(" + arr[i - 1] + ", " + arr[i] + "),"); + } + } + } + +} diff --git a/src/practiceproblems/CombinationIterator.java b/src/practiceproblems/CombinationIterator.java new file mode 100644 index 0000000..6f80177 --- /dev/null +++ b/src/practiceproblems/CombinationIterator.java @@ -0,0 +1,53 @@ +package practiceproblems; + +// CombinationIterator iterator = new CombinationIterator("abc", 2); // creates the iterator. + +import java.util.ArrayDeque; +import java.util.Deque; + +// iterator.next(); // returns "ab" +// iterator.hasNext(); // returns true +// iterator.next(); // returns "ac" +// iterator.hasNext(); // returns true +// iterator.next(); // returns "bc" +// iterator.hasNext(); // returns false +public class CombinationIterator { + Deque deque; + boolean[] visited; + public CombinationIterator(String characters, int combinationLength) { + deque= new ArrayDeque<>(); + visited= new boolean[characters.length()]; + generateCombinations(characters,deque, new StringBuilder(), combinationLength, 0); + } + + public String next() { + if(hasNext()) return deque.poll(); + + return ""; + } + + public boolean hasNext() { + return !deque.isEmpty(); + } + + public void generateCombinations(String characters, Deque deque,StringBuilder sb, int limit, int start){ + + if(sb.length()==limit){ + deque.offer(sb.toString()); + return; + } + + for(int i=start; i node.val. + * Also recall that a preorder traversal displays the value of the node first, + * then traverses node.left, then traverses node.right.) + */ +public class ConstructBSTFromPreorder { + + public static void main(String[] args) { + int[] arr = { 8, 3, 1, 6, 4, 7, 10, 14, 13 }; + bstFromPreorder(arr); + } + + public TreeNode bstFromPreorderRecursive(int[] preorder) { + return helper(preorder, 0, preorder.length - 1); + } + + private TreeNode helper(int[] preorder, int start, int end) { + if(start > end) return null; + + TreeNode node = new TreeNode(preorder[start]); + int i; + for(i=start;i<=end;i++) { + if(preorder[i] > node.val) + break; + } + + node.left = helper(preorder, start+1, i-1); + node.right = helper(preorder, i, end); + return node; + + + + } + + public static TreeNode bstFromPreorder(int[] preorder) { + if (preorder == null || preorder.length == 0) { + return null; + } + Stack stack = new Stack<>(); + TreeNode root = new TreeNode(preorder[0]); + stack.push(root); + //8, 3, 1, 6, 4, 7, 10, 14, 13 + for (int i = 1; i < preorder.length; i++) { + TreeNode node = new TreeNode(preorder[i]); + if (preorder[i] < stack.peek().val) { + stack.peek().left = node; + } else { + TreeNode parent = stack.peek(); + while (!stack.isEmpty() && preorder[i] > stack.peek().val) { + parent = stack.pop(); + } + parent.right = node; + } + stack.push(node); + } + return root; + } +} + +class TreeNode { + TreeNode left; + TreeNode right; + int val; + + public TreeNode(int val) { + this.val = val; + } + + public String toString() { + return val + ""; + } +} \ No newline at end of file diff --git a/src/practiceproblems/ConstructTreeFromInorderAndPostorder.java b/src/practiceproblems/ConstructTreeFromInorderAndPostorder.java new file mode 100644 index 0000000..f0eb91a --- /dev/null +++ b/src/practiceproblems/ConstructTreeFromInorderAndPostorder.java @@ -0,0 +1,31 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.Map; + +public class ConstructTreeFromInorderAndPostorder { + // idea is same as inorder-preorder, but we take postOrder[lastIndex] as root; + public TreeNode buildTree(int[] inorder, int[] postorder) { + if(inorder==null || postorder==null) return null; + Map map= new HashMap(); + for(int i=0;i map){ + if(iStart>iEnd || pstart>pend) return null; + + TreeNode root= new TreeNode(postorder[pend]); + int divider=map.get(root.val); + // one more change is, since we need to take last element as root + // we have to carefully pass the right index to recursive calls + // pstart, pstart+divider-iStart-1-> left subarray + //pstart+divider-iStart, pend -> right sub array + root.left= helperFn(inorder, iStart,divider-1,postorder,pstart,pstart+divider-iStart-1,map); + root.right=helperFn(inorder,divider+1,iEnd,postorder,pstart+divider-iStart,pend-1,map); + return root; + } +} \ No newline at end of file diff --git a/src/practiceproblems/ConstructTreeFromInorderAndPreorder.java b/src/practiceproblems/ConstructTreeFromInorderAndPreorder.java new file mode 100644 index 0000000..ffbb34d --- /dev/null +++ b/src/practiceproblems/ConstructTreeFromInorderAndPreorder.java @@ -0,0 +1,49 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ + */ +class ConstructTreeFromInorderAndPreorder { + + // The basic idea is here: + // Say we have 2 arrays, PRE and IN. + // Preorder traversing implies that PRE[0] is the root node. + // Then we can find this PRE[0] in IN, say it's IN[5]. + // Now we know that IN[5] is root, so we know that IN[0] - IN[4] is on the left + // side, IN[6] to the end is on the right side. + // Recursively doing this on sub arrays, we can build a tree out of it :) + public TreeNode buildTree(int[] preorder, int[] inorder) { + Map map = new HashMap<>(); + List set = new LinkedList<>(); + + for (int i = 0; i < inorder.length; i++) { + map.put(inorder[i], i); + } + + for (int i = 0; i < preorder.length; i++) { + set.add(preorder[i]); + } + + return buildTreeUtil(map, set, 0, inorder.length - 1); + + } + + public TreeNode buildTreeUtil(Map map, List set, int start, int end) { + if (start > end) + return null; + if (set.isEmpty()) + return null; + int rootVal = set.get(0); + set.remove(0); + TreeNode root = new TreeNode(rootVal); + int inorderIndex = map.get(rootVal); + root.left = buildTreeUtil(map, set, start, inorderIndex - 1); + root.right = buildTreeUtil(map, set, inorderIndex + 1, end); + return root; + } +} \ No newline at end of file diff --git a/src/practiceproblems/ContainerWithMostWater.java b/src/practiceproblems/ContainerWithMostWater.java new file mode 100644 index 0000000..c2fc13f --- /dev/null +++ b/src/practiceproblems/ContainerWithMostWater.java @@ -0,0 +1,36 @@ +package practiceproblems; + +/** + * Given n non-negative integers a1, a2, ..., an , + * where each represents a point at coordinate (i, ai). + * n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). + * Find two lines, which together with x-axis forms a container, such that the container contains the most water. + + Note: You may not slant the container and n is at least 2. + Input: [1,8,6,2,5,4,8,3,7] + Output: 49 + */ +public class ContainerWithMostWater { + + public int maxArea(int[] height) { + if(height==null || height.length==0) return 0; + int i=0; + int j= height.length-1; + int result=0; + + while(iheight[j]){ // the reason we are moving lesser side is + // j-i is going to be decreasing so we need to + // maintain higher side to have max value + j--; + }else{ + i++; + } + } + return result; + } +} diff --git a/src/practiceproblems/ConvertXToY.java b/src/practiceproblems/ConvertXToY.java new file mode 100644 index 0000000..e39b336 --- /dev/null +++ b/src/practiceproblems/ConvertXToY.java @@ -0,0 +1,69 @@ +package practiceproblems; +// Java program to find minimum +// number of steps needed to +// convert a number x into y +// with two operations allowed : +// (1) multiplication with 2 +// (2) subtraction with 1. + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Set; + +/** + * https://www.geeksforgeeks.org/minimum-number-operation-required-convert-number-x-y/ + */ + +public class ConvertXToY { + + private static int minOperations(int src, int target) { + + Set visited = new HashSet<>(); + LinkedList queue = new LinkedList<>(); + + Steps node = new Steps(src, 0); + + queue.offer(node); + visited.add(node); + + while (!queue.isEmpty()) { + Steps temp = queue.poll(); + visited.add(temp); + + if (temp.val == target) { + return temp.steps; + } + + int mul = temp.val * 2; + int sub = temp.val - 1; + + // given constraints + if (mul > 0 && mul < 1000) { + Steps nodeMul = new Steps(mul, temp.steps + 1); + queue.offer(nodeMul); + } + if (sub > 0 && sub < 1000) { + Steps nodeSub = new Steps(sub, temp.steps + 1); + queue.offer(nodeSub); + } + } + return -1; + } + + public static void main(String[] args) { + // int x = 2, y = 5; + int x = 4, y = 7; + Steps src = new Steps(x, y); + System.out.println(minOperations(x, y)); + } +} + +class Steps { + int val; + int steps; + + public Steps(int val, int steps) { + this.val = val; + this.steps = steps; + } +} diff --git a/src/practiceproblems/CountAllPathsFrom2DMatrix.java b/src/practiceproblems/CountAllPathsFrom2DMatrix.java new file mode 100644 index 0000000..1b5bc0c --- /dev/null +++ b/src/practiceproblems/CountAllPathsFrom2DMatrix.java @@ -0,0 +1,43 @@ +package practiceproblems; + +/*https://www.geeksforgeeks.org/count-possible-paths-top-left-bottom-right-nxm-matrix/*/ +class CountAllPathsFrom2DMatrix { + // A Java program to count all possible paths + // from top left to bottom right + // Returns count of possible paths to reach + // cell at row number m and column number n from + // the topmost leftmost cell (cell at 1, 1) + static int numberOfPaths(int m, int n) { + // Create a 2D table to store results + // of subproblems + int count[][] = new int[m][n]; + + // Count of paths to reach any cell in + // first row is 1 + for (int i = 0; i < m; i++) + count[i][0] = 1; + + // Count of paths to reach any cell in + // first column is 1 + for (int j = 0; j < n; j++) + count[0][j] = 1; + + // Calculate count of paths for other + // cells in bottom-up manner using + // the recursive solution + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) + + // By uncommenting the last part the + // code calculatest he total possible paths + // if the diagonal Movements are allowed + count[i][j] = count[i - 1][j] + count[i][j - 1]; //+ count[i-1][j-1]; + } + return count[m - 1][n - 1]; + } + + // Driver program to test above function + public static void main(String args[]) { + System.out.println(numberOfPaths(3, 3)); + } +} diff --git a/src/practiceproblems/CountAndSay.java b/src/practiceproblems/CountAndSay.java new file mode 100644 index 0000000..28ed6ff --- /dev/null +++ b/src/practiceproblems/CountAndSay.java @@ -0,0 +1,41 @@ +package practiceproblems; + + +/** + * https://leetcode.com/problems/count-and-say/ + */ +public class CountAndSay { + public String countAndSay(int n) { + if (n <= 0) { + return "-1"; + } + String result = "1"; + + for (int i = 1; i < n; i++) { + result = build(result); + } + return result; + } + + private String build(String result) { + StringBuilder builder = new StringBuilder(); + int p = 0; + while (p < result.length()) { + char val = result.charAt(p); + int count = 0; + + while (p < result.length() && result.charAt(p) == val) { // note that p and val will be same in first run, to count single instance + p++; + count++; + } + builder.append(count); + builder.append(val); + } + return builder.toString(); + } + + public static void main(String[] args) { + CountAndSay countAndSay = new CountAndSay(); + System.out.println(countAndSay.countAndSay(4)); + } +} \ No newline at end of file diff --git a/src/practiceproblems/CountElements.java b/src/practiceproblems/CountElements.java new file mode 100644 index 0000000..e65132b --- /dev/null +++ b/src/practiceproblems/CountElements.java @@ -0,0 +1,59 @@ +package practiceproblems; + +import java.util.HashMap; + +/** + * Given an integer array arr, count element x such that x + 1 is also in arr. + *

+ * If there're duplicates in arr, count them separetely. + *

+ *

+ *

+ * Example 1: + *

+ * Input: arr = [1,2,3] + * Output: 2 + * Explanation: 1 and 2 are counted cause 2 and 3 are in arr. + * Example 2: + *

+ * Input: arr = [1,1,3,3,5,5,7,7] + * Output: 0 + * Explanation: No numbers are counted, cause there's no 2, 4, 6, or 8 in arr. + * Example 3: + *

+ * Input: arr = [1,3,2,3,5,0] + * Output: 3 + * Explanation: 0, 1 and 2 are counted cause 1, 2 and 3 are in arr. + * Example 4: + *

+ * Input: arr = [1,1,2,2] + * Output: 2 + * Explanation: Two 1s are counted cause 2 is in arr. + */ +public class CountElements { + + public static int countElements(int[] arr) { + if (arr == null || arr.length == 0) { + return 0; + } + + HashMap freqMap = new HashMap<>(); + + for (int in : arr) { + freqMap.put(in, freqMap.getOrDefault(in, 0) + 1); + } + + int count = 0; + for (int i = 0; i < arr.length; i++) { + if (freqMap.containsKey(arr[i] - 1)) { + count = count + freqMap.get(arr[i] - 1); + freqMap.put(arr[i] - 1, 0); + } + } + return count; + } + + public static void main(String[] args) { + System.out.println(countElements(new int[]{1, 3, 2, 3, 5, 0})); + } +} \ No newline at end of file diff --git a/src/practiceproblems/CountMinimumStepsToFormDesiredInputArray.java b/src/practiceproblems/CountMinimumStepsToFormDesiredInputArray.java new file mode 100644 index 0000000..629487a --- /dev/null +++ b/src/practiceproblems/CountMinimumStepsToFormDesiredInputArray.java @@ -0,0 +1,70 @@ +package practiceproblems;/* Java program to count minimum number of operations +to get the given arr array */ + +/*https://www.geeksforgeeks.org/count-minimum-steps-get-given-desired-array/*/ +// unsolved +class CountMinimumStepsToFormDesiredInputArray { + static int arr[] = new int[] { 16, 16, 16 }; + + // Returns count of minimum operations to covert a + // zero array to arr array with increment and + // doubling operations. + // This function computes count by doing reverse + // steps, i.e., convert arr to zero array. + static int countMinOperations(int n) { + // Initialize result (Count of minimum moves) + int result = 0; + + // Keep looping while all elements of arr + // don't become 0. + while (true) { + // To store count of zeroes in current + // arr array + int zero_count = 0; + + int i; // To find first odd element + for (i = 0; i < n; i++) { + // If odd number found + if (arr[i] % 2 == 1) { + break; + } + + // If 0, then increment zero_count + else if (arr[i] == 0) { + zero_count++; + } + } + + // All numbers are 0 + if (zero_count == n) { + return result; + } + + // All numbers are even + if (i == n) { + // Divide the whole array by 2 + // and increment result + for (int j = 0; j < n; j++) + arr[j] = arr[j] / 2; + result++; + } + + // Make all odd numbers even by subtracting + // one and increment result. + for (int j = i; j < n; j++) { + if (arr[j] % 2 == 1) { + arr[j]--; + result++; + } + } + } + } + + public static void main(String[] args) { + + System.out.println( + "Minimum number of steps required to \n" + "get the given target array is " + countMinOperations( + arr.length)); + + } +} diff --git a/src/practiceproblems/CountNumbersLessThanSelf.java b/src/practiceproblems/CountNumbersLessThanSelf.java new file mode 100644 index 0000000..4197b67 --- /dev/null +++ b/src/practiceproblems/CountNumbersLessThanSelf.java @@ -0,0 +1,103 @@ +package practiceproblems; + +import java.util.LinkedList; +import java.util.List; + +/** + * You are given an integer array nums and you have to return a new counts array. + * The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i]. + * Input: [5,2,6,1] + * Output: [2,1,1,0] + */ +class CountNumbersLessThanSelf { + // Wrapper class for each and every value of the input array, +// to store the original index position of each value, before we merge sort the array + private class ArrayValWithOrigIdx { + int val; + int originalIdx; + + public ArrayValWithOrigIdx(int val, int originalIdx) { + this.val = val; + this.originalIdx = originalIdx; + } + } + + public List countSmaller(int[] nums) { + if (nums == null || nums.length == 0) return new LinkedList(); + int n = nums.length; + int[] result = new int[n]; + + ArrayValWithOrigIdx[] newNums = new ArrayValWithOrigIdx[n]; + for (int i = 0; i < n; ++i) newNums[i] = new ArrayValWithOrigIdx(nums[i], i); + + mergeSortAndCount(newNums, 0, n - 1, result); + + // notice we don't care about the sorted array after merge sort finishes. + // we only wanted the result counts, generated by running merge sort + List resultList = new LinkedList(); + for (int i : result) resultList.add(i); + return resultList; + } + + private void mergeSortAndCount(ArrayValWithOrigIdx[] nums, int start, int end, int[] result) { + if (start >= end) return; + + int mid = (start + end) / 2; + mergeSortAndCount(nums, start, mid, result); + mergeSortAndCount(nums, mid + 1, end, result); + + // left subarray start...mid + // right subarray mid+1...end + int leftPos = start; + int rightPos = mid + 1; + LinkedList merged = new LinkedList(); + int numElemsRightArrayLessThanLeftArray = 0; + while (leftPos < mid + 1 && rightPos <= end) { + if (nums[leftPos].val > nums[rightPos].val) { + // this code block is exactly what the problem is asking us for: + // a number from the right side of the original input array, is smaller + // than a number from the left side + // + // within this code block, + // nums[rightPos] is smaller than the start of the left sub-array. + // Since left sub-array is already sorted, + // nums[rightPos] must also be smaller than the entire remaining left sub-array + ++numElemsRightArrayLessThanLeftArray; + + // continue with normal merge sort, merge + merged.add(nums[rightPos]); + ++rightPos; + } else { + // a number from left side of array, is smaller than a number from + // right side of array + result[nums[leftPos].originalIdx] += numElemsRightArrayLessThanLeftArray; + + // Continue with normal merge sort + merged.add(nums[leftPos]); + ++leftPos; + } + } + + // part of normal merge sort, if either left or right sub-array is not empty, + // move all remaining elements into merged result + while (leftPos < mid + 1) { + result[nums[leftPos].originalIdx] += numElemsRightArrayLessThanLeftArray; + + merged.add(nums[leftPos]); + ++leftPos; + } + while (rightPos <= end) { + merged.add(nums[rightPos]); + ++rightPos; + } + + // part of normal merge sort + // copy back merged result into array + int pos = start; + for (ArrayValWithOrigIdx m : merged) { + nums[pos] = m; + ++pos; + } + } +} + diff --git a/src/practiceproblems/CountingInversion.java b/src/practiceproblems/CountingInversion.java new file mode 100644 index 0000000..771cda7 --- /dev/null +++ b/src/practiceproblems/CountingInversion.java @@ -0,0 +1,62 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/counting-inversions/ + */ +class CountingInversion { + + static int mergeSort(int[] arr, int arrSize) { + int[] temp = new int[arrSize]; + return mergeSort(arr, temp, 0, arrSize - 1); + } + + static int mergeSort(int[] arr, int[] temp, int left, int right) { + int mid; + int invCount = 0; + if (left < right) { + mid = ((right - left) / 2) + left; + + invCount = mergeSort(arr, temp, left, mid); + invCount += mergeSort(arr, temp, mid + 1, right); + + invCount += merge(arr, temp, left, mid + 1, right); + } + return invCount; + } + + static int merge(int[] arr, int[] temp, int left, int mid, int right) { + int invCount = 0; + + int i = left; + int j = mid; + int k = left; + while ((i <= mid - 1) && (j <= right)) { + if (arr[i] <= arr[j]) { + temp[k++] = arr[i++]; + } else { + temp[k++] = arr[j++]; + // the reason to put mid-i is take example of [1,3,5] [2,4,6] + // left is 0 and right is mid at start + // when i=1 and j=0 (value 3 and 2) we see an inversion, since + // the first part is sorted and values after i=1(3) will be greater than j=0(2) + // so we consider all elements after 3 as inversions + invCount = invCount + (mid - i); + } + } + + while (i <= mid - 1) + temp[k++] = arr[i++]; + while (j <= right) + temp[k++] = arr[j++]; + + for (i = left; i <= right; i++) + arr[i] = temp[i]; + + return invCount; + } + + public static void main(String[] args) { + int arr[] = new int[] { 4, 6, 2, 1, 9, 7 }; + System.out.println("Number of inversions are " + mergeSort(arr, arr.length)); + } +} diff --git a/src/practiceproblems/CourseSchedule.java b/src/practiceproblems/CourseSchedule.java new file mode 100644 index 0000000..e943097 --- /dev/null +++ b/src/practiceproblems/CourseSchedule.java @@ -0,0 +1,116 @@ +package practiceproblems; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Queue; +/** + * Input: numCourses = 2, prerequisites = [[1,0]] +Output: true +Explanation: There are a total of 2 courses to take. +To take course 1 you should have finished course 0. So it is possible. + +Input: numCourses = 2, prerequisites = [[1,0],[0,1]] +Output: false +Explanation: There are a total of 2 courses to take. + To take course 1 you should have finished course 0, and to take course 0 you should + also have finished course 1. So it is impossible. + */ +class CourseSchedule { + public boolean canFinish(int numCourses, int[][] prerequisites) { + + Map> map = new HashMap<>(); // Courses that depend on the key + int[] degrees = new int[numCourses]; // # of prerequisites for course i + Queue queue = new ArrayDeque<>(); // Used to find dependants and decrease their outdegree + + for (int[] pre : prerequisites) { + List tempList = map.getOrDefault(pre[1], new ArrayList<>()); + tempList.add(pre[0]); + degrees[pre[0]]++; + map.put(pre[1], tempList); + } + + for (int i = 0; i < degrees.length; i++) { + if (degrees[i] == 0) { + queue.offer(i); + } + } + + int count = 0; + while (!queue.isEmpty()) { + int temp = queue.poll(); + if (degrees[temp] == 0) { + count++; // if cond for duplicates + } + if (!map.containsKey(temp)) { + continue; + } + for (int i : map.get(temp)) { + if (--degrees[i] == 0) { + queue.offer(i); + } + } + } + + return count == numCourses; + } + + public boolean canFinishDFS(int numCourses, int[][] prerequisites) { + // this method basically finds a back-edge between nodes + // backedge is when doing a node(A)'s dfs, it puts A to a temp state + // while traversing A's child, if any of child dosen't have anymore child it's marked as completed + // if there are children it put's the current child to temp state and visits it's children + // so when doing a dfs for a node if it encounters a temp state node rather than completed node + // then that means there's a cycle we cannot complete the course + // (T) A \ + // / / + // (T) B / + // / \ / + // (Co) C D (T) while doing DFS for D's components we encounter A, but A is still in temp state + // + ArrayList[] adjList= new ArrayList[numCourses]; + for(int i=0;i(); + } + for(int[] preReq:prerequisites){ + adjList[preReq[0]].add(preReq[1]); + } + // this visited array will maintain 3 values 0,1 and 2 + // 0-unvisited, 1-being visited and 2 visited + int[] visited= new int[numCourses]; + for(int i=0;i[] adjList, int[] visited, int vertex){ + if(visited[vertex]==1) return false; // when a node comes with being visited state, we fail it + visited[vertex]=1; + for(int adj: adjList[vertex]){ + if(!dfs(adjList, visited, adj)) return false; + } + visited[vertex]=2; // finally we set visited to true + return true; + } + // this is to get the order of course as output + public boolean dfs( List[] adjList, int[] visited, Listresult, int node){ + if(visited[node]==1) return false; + if(visited[node]==2) return true; + + visited[node]=1; + for(int adj: adjList[node]){ + if(!dfs(adjList, visited, result, adj)){ + return false; + } + } + visited[node]=2; + result.add(node); // this will keep track of which to fininsh first and last + return true; + } +} \ No newline at end of file diff --git a/src/practiceproblems/DecodeString.java b/src/practiceproblems/DecodeString.java new file mode 100644 index 0000000..55058a9 --- /dev/null +++ b/src/practiceproblems/DecodeString.java @@ -0,0 +1,51 @@ +package practiceproblems; + +import java.util.ArrayDeque; +import java.util.Deque; + +// s = "3[a2[c]]", return "accaccacc". +// s = "2[abc]3[cd]ef", return "abcabccdcdcdef". +public class DecodeString { + public static String decodeString(String s) { + if (s == null) + return ""; + + Deque count = new ArrayDeque<>(); + Deque result = new ArrayDeque<>(); + int start = 0; + StringBuilder tempResult = new StringBuilder(); + while (start < s.length()) { + // whenever we see number, we push to count queue + if (Character.isDigit(s.charAt(start))) { + int num = 0; + while (Character.isDigit(s.charAt(start))) { + num = num * 10 + s.charAt(start) - '0'; + start++; + } + count.push(num); + } else if (s.charAt(start) == '[') { + // whenever we see a open brace we push the string we have to result queue + result.push(tempResult.toString()); + tempResult = new StringBuilder(); + start++; + } else if (s.charAt(start) == ']') { + // whenever a closing brace comes, we pop the last seen count and last seen string + // and replicate that string and stores in temp result + StringBuilder sb = new StringBuilder(result.pop()); + int tempCount = count.pop(); + sb.append(tempResult.toString().repeat(tempCount)); + tempResult = sb; + start++; + } else { + // whenever we see a char, we push to result string + tempResult.append(s.charAt(start++)); + } + } + + return tempResult.toString(); + } + + public static void main(String[] args) { + System.out.println(decodeString("3[a2[c]]")); + } +} \ No newline at end of file diff --git a/src/practiceproblems/DesignCompressedStringIterator.java b/src/practiceproblems/DesignCompressedStringIterator.java new file mode 100644 index 0000000..1edc6b1 --- /dev/null +++ b/src/practiceproblems/DesignCompressedStringIterator.java @@ -0,0 +1,59 @@ +package practiceproblems; + +/** + * https://leetcode.com/articles/desing-compressed-string-iterator/ + * 604. Design Compressed String Iterator + * Design and implement a data structure for a compressed string iterator. The given compressed string will be in the form of each letter followed by a positive integer representing the number of this letter existing in the original uncompressed string. + * Implement the StringIterator class: + * next() Returns the next character if the original string still has uncompressed characters, otherwise returns a white space. + * hasNext() Returns true if there is any letter needs to be uncompressed in the original string, otherwise returns false. + + * Example 1: + + * Input + * ["StringIterator", "next", "next", "next", "next", "next", "next", "hasNext", "next", "hasNext"] + * [["L1e2t1C1o1d1e1"], [], [], [], [], [], [], [], [], []] + * Output + * [null, "L", "e", "e", "t", "C", "o", true, "d", true] + * Explanation + * StringIterator stringIterator = new StringIterator("L1e2t1C1o1d1e1"); + * stringIterator.next(); // return "L" + * stringIterator.next(); // return "e" + * stringIterator.next(); // return "e" + * stringIterator.next(); // return "t" + * stringIterator.next(); // return "C" + * stringIterator.next(); // return "o" + * stringIterator.hasNext(); // return True + * stringIterator.next(); // return "d" + * stringIterator.hasNext(); // return True + */ +public class DesignCompressedStringIterator { + + String res; + + int ptr = 0; + int num = 0; + char ch = ' '; + + public DesignCompressedStringIterator(String s) { + res = s; + } + + public char next() { + if (!hasNext()) { + return ' '; + } + if (num == 0) { + ch = res.charAt(ptr++); + while (ptr < res.length() && Character.isDigit(res.charAt(ptr))) { + num = num * 10 + res.charAt(ptr++) - '0'; + } + } + num--; + return ch; + } + + public boolean hasNext() { + return ptr != res.length() || num != 0; + } +} diff --git a/src/practiceproblems/DesignFileSystem.java b/src/practiceproblems/DesignFileSystem.java new file mode 100644 index 0000000..aecb906 --- /dev/null +++ b/src/practiceproblems/DesignFileSystem.java @@ -0,0 +1,64 @@ +package practiceproblems; + +import java.util.HashMap; + +/** + * You are asked to design a file system which provides two functions: + * + * createPath(path, value): Creates a new path and associates a value to it if possible and returns True. + * Returns False if the path already exists or its parent path doesn't exist. + * + * get(path): Returns the value associated with a path or returns -1 if the path doesn't exist. + * + * ["FileSystem","createPath","createPath","get","createPath","get"] + * [[],["/leet",1],["/leet/code",2],["/leet/code"],["/c/d",1],["/c"]] + * Output: + * [null,true,true,2,false,-1] + * Explanation: + * FileSystem fileSystem = new FileSystem(); + * + * fileSystem.createPath("/leet", 1); // return true + * fileSystem.createPath("/leet/code", 2); // return true + * fileSystem.get("/leet/code"); // return 2 + * fileSystem.createPath("/c/d", 1); // return false because the parent path "/c" doesn't exist. + * fileSystem.get("/c"); // return -1 because this path doesn't exist. + */ +public class DesignFileSystem { + + private HashMap m = new HashMap<>(); + + /** + * Initialization of class. + * Use a hash map to store the path and value. + */ + public DesignFileSystem() { + m.put("", -1); // avoid initially when path is "/a" regarded as false + } + + /** + * Creates a new path and associates a value to it if possible and returns True. + * The valid path's parent is the path before the last "/". + * Hence, check parent and then put the path into map if it is valid. + * If the path has already exist, return false. + * + * @param path given path + * @param value given value + * @return true to create a new path with value, false if the path already exists or its parent path doesn't exist + */ + public boolean create(String path, int value) { + if (path.charAt(0) != '/') { + return false; + } + String parent = path.substring(0, path.lastIndexOf("/")); + if (!m.containsKey(parent)) { + return false; + } + + return m.putIfAbsent(path, value) == null; // if the path exist, m.putIfAbsent(path, value) will be null + } + + public int get(String path) { + return m.getOrDefault(path, -1); + } + +} \ No newline at end of file diff --git a/src/practiceproblems/DesignInMemoryFileSystem.java b/src/practiceproblems/DesignInMemoryFileSystem.java new file mode 100644 index 0000000..84eb5c0 --- /dev/null +++ b/src/practiceproblems/DesignInMemoryFileSystem.java @@ -0,0 +1,96 @@ +package practiceproblems; +/** + * Design an in-memory file system to simulate the following functions: + *

+ * ls: Given a path in string format. If it is a file path, return a list that only contains this file's name. + * If it is a directory path, return the list of file and directory names in this directory. Your output (file and directory names together) should in lexicographic order. + *

+ * mkdir: Given a directory path that does not exist, you should make a new directory according to the path. + * If the middle directories in the path don't exist either, you should create them as well. This function has void return type. + *

+ * addContentToFile: Given a file path and file content in string format. + * If the file doesn't exist, you need to create that file containing given content. + * If the file already exists, you need to append given content to original content. This function has void return type. + *

+ * readContentFromFile: Given a file path, return its content in string format. + */ + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +public class DesignInMemoryFileSystem { + class Trie { + boolean isFile = false; + HashMap folders = new HashMap<>(); + String content = ""; + } + + Trie root; + + public DesignInMemoryFileSystem() { + root = new Trie(); + } + + public List ls(String path) { + Trie trie = root; + List files = new ArrayList<>(); + if (!path.equals("/")) { + String[] arr = path.split("/"); + for (int i = 1; i < arr.length; i++) { + trie = trie.folders.get(arr[i]); + } + if (trie.isFile) { + files.add(arr[arr.length - 1]); + return files; + } + } + List res_files = new ArrayList<>(trie.folders.keySet()); + Collections.sort(res_files); + return res_files; + } + + public void mkdir(String path) { + Trie trie = root; + String[] arr = path.split("/"); + for (int i = 1; i < arr.length; i++) { + if (!trie.folders.containsKey(arr[i])) { + trie.folders.put(arr[i], new Trie()); + } + trie = trie.folders.get(arr[i]); + } + } + + public void addContentToFile(String filePath, String content) { + Trie trie = root; + String[] arr = filePath.split("/"); + for (int i = 1; i < arr.length - 1; i++) { + trie = trie.folders.get(arr[i]); + } + if (!trie.folders.containsKey(arr[arr.length - 1])) { + trie.folders.put(arr[arr.length - 1], new Trie()); + } + trie = trie.folders.get(arr[arr.length - 1]); + trie.isFile = true; + trie.content = trie.content + content; + } + + public String readContentFromFile(String filePath) { + Trie trie = root; + String[] arr = filePath.split("/"); + for (int i = 1; i < arr.length - 1; i++) { + trie = trie.folders.get(arr[i]); + } + return trie.folders.get(arr[arr.length - 1]).content; + } +} + +/** + * Your FileSystem object will be instantiated and called as such: + * FileSystem obj = new FileSystem(); + * List param_1 = obj.ls(path); + * obj.mkdir(path); + * obj.addContentToFile(filePath,content); + * String param_4 = obj.readContentFromFile(filePath); + */ \ No newline at end of file diff --git a/src/practiceproblems/DesignStackIncrement.java b/src/practiceproblems/DesignStackIncrement.java new file mode 100644 index 0000000..9c0b6cf --- /dev/null +++ b/src/practiceproblems/DesignStackIncrement.java @@ -0,0 +1,101 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Stack; + +/** + * Design a stack which supports the following operations. + * + * Implement the CustomStack class: + * + * CustomStack(int maxSize) Initializes the object with maxSize which is the maximum number of elements in the stack or do nothing if the stack reached the maxSize. + * void push(int x) Adds x to the top of the stack if the stack hasn't reached the maxSize. + * int pop() Pops and returns the top of stack or -1 if the stack is empty. + * void inc(int k, int val) Increments the bottom k elements of the stack by val. + * If there are less than k elements in the stack, just increment all the elements in the stack. + * + * ["CustomStack","push","push","pop","push","push","push","increment","increment","pop","pop","pop","pop"] + * [[3],[1],[2],[],[2],[3],[4],[5,100],[2,100],[],[],[],[]] + * Output + * [null,null,null,2,null,null,null,null,null,103,202,201,-1] + * Explanation + * CustomStack customStack = new CustomStack(3); // Stack is Empty [] + * customStack.push(1); // stack becomes [1] + * customStack.push(2); // stack becomes [1, 2] + * customStack.pop(); // return 2 --> Return top of the stack 2, stack becomes [1] + * customStack.push(2); // stack becomes [1, 2] + * customStack.push(3); // stack becomes [1, 2, 3] + * customStack.push(4); // stack still [1, 2, 3], Don't add another elements as size is 4 + * customStack.increment(5, 100); // stack becomes [101, 102, 103] + * customStack.increment(2, 100); // stack becomes [201, 202, 103] + * customStack.pop(); // return 103 --> Return top of the stack 103, stack becomes [201, 202] + * customStack.pop(); // return 202 --> Return top of the stack 102, stack becomes [201] + * customStack.pop(); // return 201 --> Return top of the stack 101, stack becomes [] + * customStack.pop(); // return -1 --> Stack is empty return -1. + */ +public class DesignStackIncrement { + + int n; + int[] inc; + Stack stack; + + public DesignStackIncrement(int maxSize) { + n = maxSize; + inc = new int[n]; + stack = new Stack<>(); + } + + public void push(int x) { + if (stack.size() < n) { + stack.push(x); + } + } + + public int pop() { + /* + since array elements go forward(left -> right) and stack goes + top to bottom which translates to array as right->left + so when the increment operation happens for let's say last 4 elements + we set the array pos 4 to 'increment' value. Finally when the pop + is happened we need to set the array's 3rd posistion to the 4th's value inc[i - 1] += inc[i]; + since 3 is yet to be pop-ed from stack + */ + + int i = stack.size() - 1; + if (i < 0) { + return -1; + } + if (i > 0) { + inc[i - 1] += inc[i]; + } + int res = stack.pop() + inc[i]; + inc[i] = 0; + return res; + } + + public void increment(int k, int val) { + int i = Math.min(k, stack.size()) - 1; + if (i >= 0) { + inc[i] += val; + } + } + + public static void main(String[] args) { + DesignStackIncrement customStack = new DesignStackIncrement(4); + customStack.push(1); + customStack.push(2); + customStack.push(3); + customStack.push(4); + customStack.increment(5, 100); + customStack.increment(2, 100); + System.out.println(customStack.pop()); + System.out.println(customStack.pop()); + System.out.println(customStack.pop()); + System.out.println(customStack.pop()); + + List list = new ArrayList<>(Arrays.asList("hello".split(""))); + list.size(); + } +} \ No newline at end of file diff --git a/src/practiceproblems/DesignTicTacToe.java b/src/practiceproblems/DesignTicTacToe.java new file mode 100644 index 0000000..3a4fff9 --- /dev/null +++ b/src/practiceproblems/DesignTicTacToe.java @@ -0,0 +1,107 @@ +package practiceproblems; +/* +Design a Tic-tac-toe game that is played between two players on a n x n grid. + +You may assume the following rules: + +A move is guaranteed to be valid and is placed on an empty block. +Once a winning condition is reached, no more moves is allowed. +A player who succeeds in placing n of their marks in a horizontal, vertical, or diagonal row wins the game. + +Given n = 3, assume that player 1 is "X" and player 2 is "O" in the board. + +TicTacToe toe = new TicTacToe(3); + +toe.move(0, 0, 1); -> Returns 0 (no one wins) +|X| | | +| | | | // Player 1 makes a move at (0, 0). +| | | | + +toe.move(0, 2, 2); -> Returns 0 (no one wins) +|X| |O| +| | | | // Player 2 makes a move at (0, 2). +| | | | + +toe.move(2, 2, 1); -> Returns 0 (no one wins) +|X| |O| +| | | | // Player 1 makes a move at (2, 2). +| | |X| + +toe.move(1, 1, 2); -> Returns 0 (no one wins) +|X| |O| +| |O| | // Player 2 makes a move at (1, 1). +| | |X| + +toe.move(2, 0, 1); -> Returns 0 (no one wins) +|X| |O| +| |O| | // Player 1 makes a move at (2, 0). +|X| |X| + +toe.move(1, 0, 2); -> Returns 0 (no one wins) +|X| |O| +|O|O| | // Player 2 makes a move at (1, 0). +|X| |X| + +toe.move(2, 1, 1); -> Returns 1 (player 1 wins) +|X| |O| +|O|O| | // Player 1 makes a move at (2, 1). +|X|X|X| + */ +public class DesignTicTacToe { + private int[] rows; + private int[] cols; + private int diagonal; + private int antiDiagonal; + + /** Initialize your data structure here. */ + public DesignTicTacToe(int n) { + rows = new int[n]; + cols = new int[n]; + } + + /** Player {player} makes a move at ({row}, {col}). + @param row The row of the board. + @param col The column of the board. + @param player The player, can be either 1 or 2. + @return The current winning condition, can be either: + 0: No one wins. + 1: Player 1 wins. + 2: Player 2 wins. */ + public int move(int row, int col, int player) { + int toAdd = player == 1 ? 1 : -1; + // if A player makes a move on 0,0 we are going to increment index posistion of row and col at 0,0 + // if B player makes a move on 0,2 we are going to decrement index posistion at row and col at 0,2 + // after that the count of row at 0 will be 0(balanced moves) like wise if a row or col has value n only + // a player can be adjudged a winner + rows[row] += toAdd; + cols[col] += toAdd; + if (row == col) { + diagonal += toAdd; + } + + if (col + row == cols.length - 1) { + antiDiagonal += toAdd; + } + + int size = rows.length; + if (Math.abs(rows[row]) == size || + Math.abs(cols[col]) == size || + Math.abs(diagonal) == size || + Math.abs(antiDiagonal) == size) { + return player; + } + + return 0; + } + + public static void main(String[] args) { + DesignTicTacToe toe=new DesignTicTacToe(3); + toe.move(0, 0, 1); + toe.move(0, 2, 2); + toe.move(2, 2, 1); + toe.move(1, 1, 2); + toe.move(2, 0, 1); + toe.move(1, 0, 2); + toe.move(2, 1, 1); + } +} \ No newline at end of file diff --git a/src/practiceproblems/DifferentWaysToAddParenthesis.java b/src/practiceproblems/DifferentWaysToAddParenthesis.java new file mode 100644 index 0000000..22039f6 --- /dev/null +++ b/src/practiceproblems/DifferentWaysToAddParenthesis.java @@ -0,0 +1,61 @@ +package practiceproblems; + +// Given a string of numbers and operators, +// return all possible results from computing all the different possible ways to group numbers +// and operators. The valid operators are +, - and *. + +import java.util.*; + +// Input: "2*3-4*5" +// Output: [-34, -14, -10, -10, 10] +// Explanation: +// (2*(3-(4*5))) = -34 +// ((2*3)-(4*5)) = -14 +// ((2*(3-4))*5) = -10 +// (2*((3-4)*5)) = -10 +// (((2*3)-4)*5) = 10 +public class DifferentWaysToAddParenthesis { + public List diffWaysToCompute(String input) { + if(input==null) return Collections.emptyList(); + + Map> map= new HashMap<>(); + return bfsHelper(input, map); + + } + + public List bfsHelper(String input, Map> map){ + + if(map.containsKey(input)){ + return map.get(input); + } + + List result= new ArrayList<>(); + if(!input.contains("+") && !input.contains("-") && !input.contains("*")){ + result.add(Integer.parseInt(input)); + }else{ + // Split input string into two parts and solve them recursively + // for ex input = 2*3-4 output=2,-2 + // 2* | 3-4 => this right and left expression returns a list + // 2*3| -4 => this right and left expression returns another list + for(int i=0;i firstList= bfsHelper(input.substring(0,i),map); + List secondList= bfsHelper(input.substring(i+1),map); + for(int first: firstList){ + for(int second: secondList){ + if(input.charAt(i)=='+'){ + result.add(first+second); + }else if(input.charAt(i)=='-'){ + result.add(first-second); + }else{ + result.add(first*second); + } + } + } + } + } + } + map.put(input,result); + return result; + } +} \ No newline at end of file diff --git a/src/practiceproblems/DivideSubArrayAverage.java b/src/practiceproblems/DivideSubArrayAverage.java new file mode 100644 index 0000000..9ca26e8 --- /dev/null +++ b/src/practiceproblems/DivideSubArrayAverage.java @@ -0,0 +1,47 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/divide-array-two-sub-arrays-averages-equal/ + * + * Given an integer array, the task is to divide an integer array into + * two sub-arrays to make their averages equal if possible. + * + * Input : arr[] = {1, 5, 7, 2, 0}; + * Output : (0 1) and (2 4) + * Subarrays arr[0..1] and arr[2..4] have + * same average. + * + * Input : arr[] = {4, 3, 5, 9, 11}; + * Output : Not possible + */ +class DivideSubArrayAverage { + + static void findSubarrays(int arr[], int n) { + int sum = 0; + for (int i = 0; i < n; i++) + sum += arr[i]; + + boolean found = false; + int lsum = 0; + for (int i = 0; i < n - 1; i++) { + lsum += arr[i]; + int rsum = sum - lsum; + + if (lsum * (n - i - 1) == rsum * (i + 1)) { + System.out.println("found"); + found = true; + } + } + + // If no subarrays found + if (!found) { + System.out.println("Not found"); + } + } + + public static void main(String[] args) { + int[] arr = { 1, 5, 7, 2, 0 }; + int n = arr.length; + findSubarrays(arr, n); + } +} diff --git a/src/practiceproblems/DungeonGame.java b/src/practiceproblems/DungeonGame.java new file mode 100644 index 0000000..7e24344 --- /dev/null +++ b/src/practiceproblems/DungeonGame.java @@ -0,0 +1,64 @@ +package practiceproblems; + +// The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. +//The dungeon consists of M x N rooms laid out in a 2D grid. +//Our valiant knight (K) was initially positioned in the top-left room and must fight his way through the dungeon to rescue the princess. + +// The knight has an initial health point represented by a positive integer. +//If at any point his health point drops to 0 or below, he dies immediately. +//Input +// |-2 -3 3 | +// |-5 -10 1 | +// |10 30 -5 | + +//output 7 + +// the trick here is to go bottom up, start from the last cell, +// inorder to reach there he should have at-least 6 as health, so that +// when he reaches -5(energy is consumed) and he's left with +1 health +// likewise if we backtrack from end to start, we'll need +7 as min initial health to +// play the game +public class DungeonGame { + public int calculateMinimumHP(int[][] dungeon) { + + int[][] dp = new int[dungeon.length][dungeon[0].length]; + + int m = dungeon.length; + int n = dungeon[0].length; + + dp[m-1][n-1] = Math.max(1, 1-dungeon[m-1][n-1]); + + // Populate the last column + for(int i=m-2;i>=0;i--){ + dp[i][n-1] = Math.max(1, dp[i+1][n-1]-dungeon[i][n-1]); + } + + // Populate the last row + for(int i=n-2;i>=0;i--){ + dp[m-1][i] = Math.max(1, dp[m-1][i+1]-dungeon[m-1][i]); + } + + // to achieve the answer, we need to setup the last row and last column + // we know to reach last cell we need 6 as energy, let's say that comes + // from cell above it, that cell's original val is +1, so we must have + // 5 energy when we reach there and adding it up, it became 6 + // the reason to put 1 on last row is, the value in that cell is 30 + // so to reach last cell from that cell, we need only 6 energy(min) + // to have 6 from +30, player should have health of -24 and player cannot + // have neg val, so we put 1 as filler + // |* * 2 | + // |* * 5 | + // |1 1 6 | + + // Populate the rest by taking max of bottom and right (reverse of down and left) + + for(int i=m-2;i>=0;i--){ + for(int j=n-2;j>=0;j--){ + dp[i][j] = Math.max(1, Math.min(dp[i+1][j], dp[i][j+1])-dungeon[i][j]); + } + } + + + return dp[0][0]; + } +} \ No newline at end of file diff --git a/src/practiceproblems/DutchNationalFlag.java b/src/practiceproblems/DutchNationalFlag.java new file mode 100644 index 0000000..f8a6c53 --- /dev/null +++ b/src/practiceproblems/DutchNationalFlag.java @@ -0,0 +1,31 @@ +package practiceproblems; + +class DutchNationalFlag { + public void sortColors(int[] arr) { + if (arr.length == 0) { + return; + } + int pivot = 1; + int i = 0; + int j = arr.length - 1; + int zeroPos = 0; + while (i <= j) { + if (arr[i] > pivot) { + swap(arr, i, j); + j--; + } else if (arr[i] == pivot) { + i++; + } else { + swap(arr, zeroPos, i); + zeroPos++; + i++; + } + } + } + + public void swap(int[] arr, int i, int j) { + int temp = arr[j]; + arr[j] = arr[i]; + arr[i] = temp; + } +} \ No newline at end of file diff --git a/src/practiceproblems/EvaluvateRPN.java b/src/practiceproblems/EvaluvateRPN.java new file mode 100644 index 0000000..033e295 --- /dev/null +++ b/src/practiceproblems/EvaluvateRPN.java @@ -0,0 +1,47 @@ +package practiceproblems; + +import java.util.ArrayDeque; +import java.util.Deque; + +// Input: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"] +// Output: 22 +// Explanation: +// ((10 * (6 / ((9 + 3) * -11))) + 17) + 5 +// = ((10 * (6 / (12 * -11))) + 17) + 5 +// = ((10 * (6 / -132)) + 17) + 5 +// = ((10 * 0) + 17) + 5 +// = (0 + 17) + 5 +// = 17 + 5 +// = 22 +public class EvaluvateRPN { + public int reversePolishNotation(String[] tokens) { + if(tokens==null && tokens.length==0) return 0; + Deque deque= new ArrayDeque<>(); + for(String i: tokens){ + if(i.length()==1 && "+*-/".contains(i)){ + Integer second= deque.removeFirst(); + Integer first= deque.removeFirst(); + //System.out.println(first +" - "+ second +" "+i); + switch(i){ + case "+": + deque.addFirst(first+second); + break; + case "-": + deque.addFirst(first-second); + break; + case "*": + deque.addFirst(first*second); + break; + case "/": + deque.addFirst(first/second); + break; + + } + }else{ + deque.addFirst(Integer.parseInt(i)); + } + } + + return deque.removeFirst(); + } +} \ No newline at end of file diff --git a/src/practiceproblems/FenwickTree.java b/src/practiceproblems/FenwickTree.java new file mode 100644 index 0000000..aaa07e5 --- /dev/null +++ b/src/practiceproblems/FenwickTree.java @@ -0,0 +1,112 @@ +package practiceproblems; + +/** + * https://codeforces.com/blog/entry/61364 + * + * Fenwick trees are binary indexed trees, when asked for a range queries for an array + * ex [1,3,4,1,2] print the sum for range (0,4), (1,2) etc.. sum, difference, product, division can be asked + * one way is to pre-compute the prefix sums like [1,4,8,9,11] + * when asked for sum between 0 to 4 return 9 + * when asked sum between 2 to 4 we can return sum of (0,1) - (0,4) + * the retrival is O(1), but if the original array is updated we need to compute + * the prefix sum which will take O(N). + * Fenwick tree solves this by making both get and update as O(log n) + */ +public class FenwickTree{ + + // the array size is always incremented by 1, because the first entry is + // a dummy entry, the trees are arranges in set bits of each array's index + // we consider 4 pos of the bit representation + /** + * for array [1,-7,15,9,4,2,0,10] + * 0=> [0/0000] (index/ bit val of index) + * / | \ \ + * 1=> [1/0001] [2/0010] [4/0100] [8/1000] + * / / \ + * 2=> [3/0011] [5/0101] [6/0110] + * / + * 3=> [7/0111] + * + * so from the above tree we can infer that to get to a parent node, we need to + * remove the right most set bit + * [7/0111] => [6/0110]=> [4/0100]=> [0/0000] + * and the formula for that is parent = i - (i & -i); + * + * before populating fenwick tree with values, calculate the prefix sum for the array + * [1,-7,15,9,4,2,0,10]=> [1,-6,9,18,22,24,24,34] and update in it's posistion in fenwick tree + * + * [0/0000] + * / | \ \ + * [1/0001] [-6/0010] [18/0100] [34/1000] + * / / \ + * [9/0011] [22/0101] [24/0110] + * / + * [24/0111] + * the we need to subract each cell's value to it's immediate parent's value, then the tree would look like + * we can use the above formula parent = i - (i & -i); + * + * [0/0000] + * / | \ \ + * [1/0001] [-6/0010] [18/0100] [34/1000] + * / / \ + * [15/0011] [4/0101] [6/0110] + * / + * [0/0111] + * in array's representation it'd look like + * [0,1,-6,15,18,4,6,0,34] + */ + + int[] fen; int[] arr; + int n; + public void NumArray(int[] nums) { + arr = nums; + n = nums.length; + fen = new int[n+1]; + init(); + } + + public void init(){ + if(n == 0) return; + + fen[1] = arr[0]; + for(int i = 1; i < n; i++){ + fen[i+1] = fen[i] + arr[i]; + } + for(int i = n; i >0 ; i--){ + int parent = i - (i & -i); + if(parent >= 0) fen[i] -= fen[parent]; + } + //System.out.println(Arrays.toString(fen)); + } + + + + // for update we need to come from parent to children + // to get children do opposite of i-(i&-i) + public void update(int i, int val) { + int extra = val - arr[i]; + arr[i] = val; + increment(i, extra); + } + + public int sum(int i){ + int res = 0; + while(i > 0){ + res += fen[i]; + i = i - (i & -i); + } + return res; + } + public void increment(int i, int val){ + i++; + while(i <= n){ + fen[i] += val; + i = i + (i & -i); + } + } + //sum(1,4)=> sum(0,4)-(0,1) the sum function will calculate from 4->0(parent) + public int sumRange(int i, int j) { + return sum(j+1) - sum(i); + } + +} \ No newline at end of file diff --git a/src/practiceproblems/FindAllAnagram.java b/src/practiceproblems/FindAllAnagram.java new file mode 100644 index 0000000..0ae0fbf --- /dev/null +++ b/src/practiceproblems/FindAllAnagram.java @@ -0,0 +1,60 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. + * + * Strings consists of lowercase English letters only and the length of + * both strings s and p will not be larger than 20,100. + * + * The order of output does not matter. + * + * Input: + * s: "cbaebabacd" p: "abc" + * + * Output: + * [0, 6] + * + * Explanation: + * The substring with start index = 0 is "cba", which is an anagram of "abc". + * The substring with start index = 6 is "bac", which is an anagram of "abc". + */ +public class FindAllAnagram { + + public List findAnagrams(String s, String p) { + Map map = new HashMap<>(); + for(char ch: p.toCharArray()){ + map.put(ch, map.getOrDefault(ch,0)+1); + } + int counter= map.size(); + + int start=0; int end=0; + List result= new ArrayList<>(); + while(end0) counter++; + } + if(end-start==p.length()) { + result.add(start); + } + start++; + } + } + + return result; + } +} diff --git a/src/practiceproblems/FindMissingNumbers.java b/src/practiceproblems/FindMissingNumbers.java new file mode 100644 index 0000000..50326d3 --- /dev/null +++ b/src/practiceproblems/FindMissingNumbers.java @@ -0,0 +1,44 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +// Input: [2, 3, 1, 8, 2, 3, 5, 1] +// Output: 4, 6, 7 +public class FindMissingNumbers { + + //Brute Force + // Set set = new HashSet<>(); + // for (int i = 0; i < nums.length; i++) set.add(i + 1); + // for (int i = 0; i < nums.length; i++) set.remove(nums[i]); + // return new ArrayList<>(set); + public List findDisappearedNumbers(int[] nums) { + if(nums.length==0) return Collections.emptyList(); + int i=0; + // cyclic sort begins + while(i result= new ArrayList<>(); + i=0; + while(i A.length) { + i++; + } else if (A[A[i] - 1] != A[i]) { + swap(A, i, A[i] - 1); + } else { + i++; + } + } + i = 0; + while (i < A.length && A[i] == i + 1) + i++; + return i + 1; + } + + private void swap(int[] A, int i, int j) { + int temp = A[i]; + A[i] = A[j]; + A[j] = temp; + } + + public int firstMissingPositiveWithExtraSpace(int[] nums) { + if (nums == null || nums.length == 0) { + return 1; + } + int length = nums.length; + int[] arr = new int[length + 1]; + for (int i = 0; i < length; i++) { + if (nums[i] <= length && nums[i] > 0) { + arr[--nums[i]] = -1; + } + } + + for (int i = 0; i < arr.length; i++) { + if (arr[i] != -1) { + return ++i; + } + } + return -1; + } + + public List findKMissingPositiveNumberOfSizeK(int[] A, int k){ + int i = 0; + while (i < A.length) { + // same cyclic sort, as missing numbers + if (A[i] == i + 1 || A[i] <= 0 || A[i] > A.length) { + i++; + } else if (A[A[i] - 1] != A[i]) { + swap(A, i, A[i] - 1); + } else { + i++; + } + } + + List missingNumber= new ArrayList<>(); + Set additionalNumber= new HashSet<>(); + + i=0; + while(i isSeen = new HashSet<>(); + DLList linkedList = new DLList(); + Map map = new HashMap<>(); + + public String solve(String A) { + StringBuilder sb = new StringBuilder(); + for (String s : A.split("")) { + sb.append(uniqueStream(s)); + } + return sb.toString(); + } + + public String uniqueStream(String A) { + Node node = new Node(A); + + if (isSeen.contains(A) && map.get(A) != null) { + Node temp = map.get(A); + linkedList.remove(temp); + map.put(A, null); + } else if (!isSeen.contains(A)) { + isSeen.add(A); + linkedList.add(node); + map.put(A, node); + } + + return linkedList.head.next.val; + } + + public String solveEfficient(String A) { + // we can use two pointer approach to solve this problem. + // First count the occurences of the characters in the stream in the charCounts array + int[] charCounts = new int[26]; + // Keep a start pointer at the start index which will denote the first non-repeating character, if any + int s = 0; + char[] charArr = A.toCharArray(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < charArr.length; i++) { + // increment the count of the current character + charCounts[charArr[i] - 'a']++; + // move the start pointer ahead either till the current index + // or until we see another non-repeating character + while (s < i && charCounts[charArr[s] - 'a'] > 1) s++; + // If the character at start index is a non repeating character, add it the string otherwise add '#'' + if (charCounts[charArr[s] - 'a'] == 1) sb.append(charArr[s]); + else sb.append('#'); + } + + return sb.toString(); + } + + public static void main(String[] args) { + String[] vals= "jpxvxivxkkthvpqhhhjuzhkegnzqriokhsgea".split(""); + FirstNonRepeatingCharacterStream solution= new FirstNonRepeatingCharacterStream(); + for(String s:vals){ + System.out.println("ans:: "+solution.solve(s)); + } + } +} + + + + + + +class DLList { + Node head; + Node tail; + + public DLList() { + head = new Node("#"); + tail = new Node("#"); + head.next = tail; + tail.prev = head; + } + + public void add(Node node) { + Node prev = tail.prev; + prev.next = node; + node.prev = prev; + + node.next = tail; + tail.prev = node; + } + + public void remove(Node temp) { + Node next = temp.next; + temp.prev.next = next; + next.prev = temp.prev; + } +} + +class Node { + Node prev; + Node next; + String val; + + public Node(String val) { + this.val = val; + } +} diff --git a/src/practiceproblems/Flatten2DVector.java b/src/practiceproblems/Flatten2DVector.java new file mode 100644 index 0000000..250ac0f --- /dev/null +++ b/src/practiceproblems/Flatten2DVector.java @@ -0,0 +1,72 @@ +package practiceproblems; + +import java.util.List; + +/* +Thoughts: +As hint indicates: use 2 pointers to hold position. +Use hasNext to validate (x,y) and move x. +Use next() to return (x,y) and move it(regardless of correctness, which is determined by hasNext()) + +Implement an iterator to flatten a 2d vector. + +For example, +Given 2d vector = + +[ + [1,2], + [3], + [4,5,6] +] +By calling next repeatedly until hasNext returns false, +the order of elements returned by next should be: [1,2,3,4,5,6]. + +Understand the problem: +The question itself is very easy to solve. Just several corner cases need to think of: + -- What if the 2d vector contains empty arrays, e.g. [ ], [ ], 1 2 3 ? In this case, the next() should not output anything, but the return type is int. There the hasNext() should be more complicated in which it handles this situation. + -- What if the 2d vector itself is empty? Again, handle it in hasNext() +*/ +public class Flatten2DVector { + private int x; + private int y; + private List> list; + + public Flatten2DVector(List> vec2d) { + if (vec2d == null) { + return; + } + this.x = 0; + this.y = 0; + this.list = vec2d; + } + + public int next() { + int rst = list.get(x).get(y); + // when y(column) reaches end increment row(x) and reset y + if (y + 1 >= list.get(x).size()) { + y = 0; + x++; + } else { + y++; + } + return rst; + } + + public boolean hasNext() { + if (list == null) { + return false; + } + // this condition is to check for empty rows + while (x < list.size() && list.get(x).isEmpty()) { + x++; + y = 0; + } + if (x >= list.size()) { + return false; + } + if (y >= list.get(x).size()) { + return false; + } + return true; + } +} diff --git a/src/practiceproblems/FlattenLinkedList.java b/src/practiceproblems/FlattenLinkedList.java new file mode 100644 index 0000000..b5e8414 --- /dev/null +++ b/src/practiceproblems/FlattenLinkedList.java @@ -0,0 +1,145 @@ +package practiceproblems; + +/** + * https://www.techiedelight.com/flatten-linked-list/ + */ +class FlattenLinkedList { + Node head; + + class Node { + int data; + Node right, down; + + Node(int data) { + this.data = data; + right = null; + down = null; + } + + @Override + public String toString() { + return "" + this.data; + } + } + + Node mergeIterative(Node a, Node b) { + Node dummy = new Node(0); + Node result = dummy; + + while (a != null && b != null) { + if (a.data < b.data) { + result.down = a; + a = a.down; + } else { + result.down = b; + b = b.down; + } + result = result.down; + } + while (a != null) { + result.down = a; + result = result.down; + a = a.down; + } + + while (b != null) { + result.down = b; + result = result.down; + b = b.down; + } + return dummy.down; + } + + Node flatten(Node root) { + if (root == null || root.right == null) { + return root; + } + + root.right = flatten(root.right); + + root = mergeIterative(root, root.right); + + return root; + } + + public static void main(String args[]) { + flattenList(); + } + + protected static void flattenList() { + FlattenLinkedList L = new FlattenLinkedList(); + + /* Let us create the following linked list + 5 -> 10 -> 19 -> 28 + | | | | + V V V V + 7 20 22 35 + | | | + V V V + 8 50 40 + | | + V V + 30 45 + */ + + L.head = L.push(L.head, 30); + L.head = L.push(L.head, 8); + L.head = L.push(L.head, 7); + L.head = L.push(L.head, 5); + + L.head.right = L.push(L.head.right, 20); + L.head.right = L.push(L.head.right, 10); + + L.head.right.right = L.push(L.head.right.right, 50); + L.head.right.right = L.push(L.head.right.right, 22); + L.head.right.right = L.push(L.head.right.right, 19); + + L.head.right.right.right = L.push(L.head.right.right.right, 45); + L.head.right.right.right = L.push(L.head.right.right.right, 40); + L.head.right.right.right = L.push(L.head.right.right.right, 35); + + // flatten the list + L.head = L.flatten(L.head); + + L.printList(); + } + + Node push(Node head_ref, int data) { + Node new_node = new Node(data); + new_node.down = head_ref; + head_ref = new_node; + + return head_ref; + } + + void printList() { + Node temp = head; + while (temp != null) { + System.out.print(temp.data + " "); + temp = temp.down; + } + System.out.println(); + } + + Node merge(Node a, Node b) { + if (a == null) { + return b; + } + + if (b == null) { + return a; + } + + Node result; + + if (a.data < b.data) { + result = a; + result.down = merge(a.down, b); + } else { + result = b; + result.down = merge(a, b.down); + } + + return result; + } +} \ No newline at end of file diff --git a/src/practiceproblems/FlattenMultiLevelLinkedList.java b/src/practiceproblems/FlattenMultiLevelLinkedList.java new file mode 100644 index 0000000..3fce5e6 --- /dev/null +++ b/src/practiceproblems/FlattenMultiLevelLinkedList.java @@ -0,0 +1,48 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list/discuss/150321/Easy-Understanding-Java-beat-95.7-with-Explanation +* */ +class FlattenMultiLevelLinkedList { + + public Node flatten(Node head) { + if (head == null) { + return head; + } + // Pointer + Node p = head; + while (p != null) { + if (p.child == null) { + p = p.next; + continue; + } + /* CASE 2: got child, find the tail of the child and link it to p.next */ + Node temp = p.child; + + while (temp.next != null) { + temp = temp.next; + } + // Connect tail with p.next, if it is not null + temp.next = p.next; + if (p.next != null) { + p.next.prev = temp; + } + // Connect p with p.child, and remove p.child + p.next = p.child; + p.child.prev = p; + p.child = null; + } + return head; + } + + static class Node { + long data; + Node next; + Node prev; + Node child; + + public Node(long id) { + this.data = id; + } + } +} \ No newline at end of file diff --git a/src/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java b/src/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java new file mode 100644 index 0000000..beb009a --- /dev/null +++ b/src/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java @@ -0,0 +1,40 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/maximize-number-0s-flipping-subarray/ + * + * Problem : flip 1's to 0's so that total no.of 0's in array is maximized + */ +class FlipMaximizeZeroesSubarrayKadane { + + public static int findMaxZeroCount(int[] arr, int n) { + int zeroCount = 0; + int maxSoFar = Integer.MIN_VALUE; + int sum = 0; + + for (int i = 0; i < n; i++) { + + if (arr[i] == 0) { + zeroCount++; + } + + int val = (arr[i] == 1) ? 1 : -1; + + sum = sum + val; + + if (sum < 0) { + sum = 0; + } + maxSoFar = Math.max(maxSoFar, sum); + } + maxSoFar = Math.max(0, maxSoFar); + + return zeroCount + maxSoFar; + } + + public static void main(String[] args) { + int[] arr = { 0, 1, 0, 0, 1, 1, 0 }; + + System.out.println(findMaxZeroCount(arr, arr.length)); + } +} \ No newline at end of file diff --git a/src/practiceproblems/FlipZeroesToFormConsecutiveMaximumOnes.java b/src/practiceproblems/FlipZeroesToFormConsecutiveMaximumOnes.java new file mode 100644 index 0000000..fe63cb4 --- /dev/null +++ b/src/practiceproblems/FlipZeroesToFormConsecutiveMaximumOnes.java @@ -0,0 +1,57 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/find-zeroes-to-be-flipped-so-that-number-of-consecutive-1s-is-maximized/ + + * https://www.techiedelight.com/find-maximum-sequence-of-continuous-1s-can-formed-replacing-k-zeroes-ones/ + */ +class FlipZeroesToFormConsecutiveMaximumOnes { + + public static void longestSeq(int[] A, int k) { + int left = 0; + int count = 0; + int window = 0; + + int leftIndex = 0; + + // 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0 + for (int right = 0; right < A.length; right++) { + // if current element is 0, increase count of zeros in the + // current window by 1 + if (A[right] == 0) { + count++; + } + + // window becomes unstable if number of zeros in it becomes + // more than + while (count > k) { + // if we have found zero, decrement number of zeros in the + // current window by 1 + if (A[left] == 0) { + count--; + } + left++; + } + + // when we reach here, the window [left..right] contains at-most + // k zeroes and we update max window size and leftmost index + // of the window + if (right - left + 1 > window) { + window = right - left + 1; + leftIndex = left; + } + } + + System.out.println( + "The longest sequence has length " + window + " from index " + leftIndex + " to " + (leftIndex + window + - 1)); + } + + // main function + public static void main(String[] args) { + int[] A = { 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0 }; + int k = 2; + + longestSeq(A, k); + } +} diff --git a/src/practiceproblems/FourSum.java b/src/practiceproblems/FourSum.java new file mode 100644 index 0000000..0e55219 --- /dev/null +++ b/src/practiceproblems/FourSum.java @@ -0,0 +1,64 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.Map; + +/** + * https://leetcode.com/problems/4sum-ii/ + * Given four lists A, B, C, D of integer values, + * compute how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero. + * To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. + * All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1. + * + * Input: + * A = [ 1, 2] + * B = [-2,-1] + * C = [-1, 2] + * D = [ 0, 2] + * + * Output: + * 2 + * + * Explanation: + * The two tuples are: + * 1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0 + * 2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0 + */ +public class FourSum { + + public int fourSumCount(int[] A, int[] B, int[] C, int[] D) { + Map sumMap = new HashMap<>(); + + for(int i=0; i map = new HashMap<>(); + for (char c : s.toCharArray()) + map.put(c, map.getOrDefault(c, 0) + 1); + + List[] bucket = new List[s.length() + 1]; + + for (char key : map.keySet()) { + int frequency = map.get(key); + if (bucket[frequency] == null) bucket[frequency] = new ArrayList<>(); + bucket[frequency].add(key); + } + + StringBuilder sb = new StringBuilder(); + // since this is max frequency we are iterating from last else we'd go from start + for (int pos = bucket.length - 1; pos >= 0; pos--) + if (bucket[pos] != null) + for (char c : bucket[pos]) + for (int i = 0; i < map.get(c); i++) + sb.append(c); + + return sb.toString(); + } +} \ No newline at end of file diff --git a/src/practiceproblems/GameOfLife.java b/src/practiceproblems/GameOfLife.java new file mode 100644 index 0000000..06bb79f --- /dev/null +++ b/src/practiceproblems/GameOfLife.java @@ -0,0 +1,61 @@ +package practiceproblems; + +/** + * https://forum.letstalkalgorithms.com/t/game-of-life/516/2 + *

+ * https://leetcode.com/problems/game-of-life/ + * Given a board with m by n cells, each cell has an initial state live (1) or dead (0). + * Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules + * Any live cell with fewer than two live neighbors dies, as if caused by under-population. + * Any live cell with two or three live neighbors lives on to the next generation. + * Any live cell with more than three live neighbors dies, as if by over-population.. + * Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction. + * + * Input: + * [ + * [0,1,0], + * [0,0,1], + * [1,1,1], + * [0,0,0] + * ] + * Output: + * [ + * [0,0,0], + * [1,0,1], + * [0,1,1], + * [0,1,0] + * ] + */ +public class GameOfLife { + + public void gameOfLife(int[][] board) { + + int[][] dir ={{1,-1},{1,0},{1,1},{0,-1},{0,1},{-1,-1},{-1,0},{-1,1}}; + int row=board.length; + int col=board[0].length; + + for(int i=0; i=row || j1>=col || i1<0 || j1<0) continue; // border conditions + + if(board[i1][j1]==1 || board[i1][j1]==2) liveCells++; + } + + if(board[i][j]==0 && liveCells==3) board[i][j]=3; //Any dead cell with exactly three live neighbors becomes a live cell + + if(board[i][j]==1 && (liveCells<2 || liveCells>3)) board[i][j]=2; //live cell with fewer than two live neighbors dies || Any live cell with more than three live neighbors dies + } + } + + for(int i=0; i generateParenthesis(int n) { + List result = new ArrayList<>(); + if (n == 0) + return result; + // initially we send empty string and target number of pairs needed + generateUtil(n, new StringBuilder(), 0, 0, result); + + return result; + } + + public void generateUtil(int n, StringBuilder paran, int open, int close, List result) { + if (close == n) { // when close reaches n, we know n pairs have been created + result.add(paran.toString()); + return; + } + + if (close < open) { // when close is less than open we add a close and proceed + paran.append(")"); + generateUtil(n, paran, open, close + 1, result); + paran.deleteCharAt(paran.length() - 1); // backtracking to remove the last seen + } + if (open < n) { + paran.append("("); + generateUtil(n, paran, open + 1, close, result); + paran.deleteCharAt(paran.length() - 1); + + } + + } + +} \ No newline at end of file diff --git a/src/practiceproblems/GrammarMistake.java b/src/practiceproblems/GrammarMistake.java new file mode 100644 index 0000000..65706d1 --- /dev/null +++ b/src/practiceproblems/GrammarMistake.java @@ -0,0 +1,83 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/check-given-sentence-given-set-simple-grammer-rules/ + * A simple sentence if syntactically correct if it fulfills given rules. The following are given rules. + * + * 1. Sentence must start with a Uppercase character (e.g. Noun/ I/ We/ He etc.) + * 2. Then lowercase character follows. + * 3. There must be spaces between words. + * 4. Then the sentence must end with a full stop(.) after a word. + * 5. Two continuous spaces are not allowed. + * 6. Two continuous upper case characters are not allowed. + * 7. However, the sentence can end after an upper case character. + * + * + */ +import java.util.Arrays; +import java.util.List; + +class Main +{ + public static boolean validateSentence(char[] chars) + { + int index = 0; + if (Character.isLowerCase(chars[index])) { // 1st condition + return false; + } + + while (index < chars.length) + { + if (Character.isUpperCase(chars[index])) + { + if (Character.isUpperCase(chars[index + 1])) { // 5th condition + return false; + } + + if (index - 1 >= 0 && chars[index - 1] != ' ') { // 2nd condition + return false; + } + } + + if (chars[index] == ' ' && chars[index + 1] == ' ') { // 4th condition + return false; + } + + index++; + } + + if (chars[index - 2] == ' ' || chars[index - 1] != '.') { // 3th condition + return false; + } + + return true; + } + + public static void main(String[] args) + { + List list = Arrays.asList( + "This sentence is syntactically correct.", + + "This sentence is syntactically incorrect as two " + + "continuous spaces are not allowed.", + + "This sentence is syntactically correct Y.", + + "This sentence is syntactically incorRect as uppercase " + + "character is not allowed midway of the String.", + + "THis sentence is syntactically incorrect as lowercase " + + "character don't follow the first uppercase character.", + + "This sentence is syntactically incorrect as it doesn't " + + "end with a full stop" + ); + + System.out.println("Valid sentences are -"); + for (String sentence: list) { + if (validateSentence(sentence.toCharArray())) { + System.out.println(sentence); + } + } + } +} diff --git a/src/practiceproblems/GraphBiPartite.java b/src/practiceproblems/GraphBiPartite.java new file mode 100644 index 0000000..fe8b080 --- /dev/null +++ b/src/practiceproblems/GraphBiPartite.java @@ -0,0 +1,52 @@ +package practiceproblems; + +/** + * Recall that a graph is bipartite if we can split it's set of nodes into + * two independent subsets A and B such that every edge in the graph has one node in A and + * another node in B. + * Input: [[1,3], [0,2], [1,3], [0,2]] => 0th node connects to 1,3 .. +Output: true +Explanation: +The graph looks like this: +0----1 +| | +| | +3----2 +We can divide the vertices into two groups: {0, 2} and {1, 3}. +Input: [[1,2,3], [0,2], [0,1,3], [0,2]] +Output: false +Explanation: +The graph looks like this: +0----1 +| \ | +| \ | +3----2 +We cannot find a way to divide the set of nodes into two independent subsets. + */ +public class GraphBiPartite { + public boolean isBipartite(int[][] graph) { + int[] color= new int[graph.length]; + + for(int i=0;i + * https://github.com/UtkarshBehre/InterviewQuestionsPracticeInJava/blob/master/src/popularQuestionSet/GraphSplitwiseSimplify.java + */ +public class GraphSplitwiseSimplify { + + static class Graph { + int V; + LinkedList[] adjNodesList; + + static class AdjNode { + int adjVertices; + int debt; + + public AdjNode(int adjVertices, int debt) { + this.adjVertices = adjVertices; + this.debt = debt; + } + + @Override + public boolean equals(Object o) { + if (this.adjVertices == ((AdjNode) o).adjVertices) { + return true; + } else { + return false; + } + } + + public String toString() { + return adjVertices + "->" + debt; + } + } + + public Graph(int v) { + this.V = v; + adjNodesList = new LinkedList[V]; + for (int i = 0; i < V; i++) { + adjNodesList[i] = new LinkedList(); + } + } + + public void addEdge(int src, int dest, int debt) { + AdjNode adjNode = new AdjNode(dest, debt); + adjNodesList[src].add(adjNode); + } + + /** + * Runtime: O(VE) + */ + public void simplifyDebts() { + HashMap takers = new HashMap<>(); + HashMap givers = new HashMap<>(); + int[] debts = new int[V]; + for (int i = 0; i < V; i++) { + for (AdjNode adjNode : adjNodesList[i]) { + debts[i] -= adjNode.debt; + debts[adjNode.adjVertices] += adjNode.debt; + } + } + for (int i = 0; i < V; i++) { + if (debts[i] < 0) { + givers.put(i, Math.abs(debts[i])); + } else if (debts[i] > 0) { + takers.put(i, debts[i]); + } + } + + adjNodesList = new LinkedList[V]; + for (int i = 0; i < V; i++) { + adjNodesList[i] = new LinkedList<>(); + } + for (Entry giver : givers.entrySet()) { + int amountToGive = giver.getValue(); + for (Entry taker : takers.entrySet()) { + int amountToTake = taker.getValue(); + if (amountToTake > 0) { + if (amountToTake < amountToGive) { + taker.setValue(0); + amountToGive -= amountToTake; + addEdge(giver.getKey(), taker.getKey(), amountToTake); + } else { + taker.setValue(amountToTake - amountToGive); + addEdge(giver.getKey(), taker.getKey(), amountToGive); + break; + } + } + } + giver.setValue(amountToGive); + } + } + + public void printDebts() { + System.out.println("depts are: "); + for (int i = 0; i < V; i++) { + for (AdjNode adjNode : adjNodesList[i]) { + System.out.println(i + " owes " + adjNode.adjVertices + " " + adjNode.debt + " bucks."); + } + } + } + } + + public static void main(String[] args) { + Graph g = new Graph(3); + g.addEdge(0, 1, 1000); + g.addEdge(1, 2, 1000); + g.addEdge(0, 2, 2000); + g.printDebts(); + g.simplifyDebts(); + System.out.print("After simplification, "); + g.printDebts(); + + System.out.println("\nTest set 2"); + g = new Graph(5); + g.addEdge(0, 1, 1000); + g.addEdge(0, 2, 5000); + g.addEdge(1, 3, 2000); + g.addEdge(1, 4, 1500); + g.addEdge(2, 1, 3000); + g.addEdge(2, 3, 4000); + g.addEdge(3, 0, 500); + g.addEdge(4, 3, 500); + g.printDebts(); + g.simplifyDebts(); + System.out.print("After simplification, "); + g.printDebts(); + } +} \ No newline at end of file diff --git a/src/practiceproblems/GroupAnagrams.java b/src/practiceproblems/GroupAnagrams.java new file mode 100644 index 0000000..43b3ddd --- /dev/null +++ b/src/practiceproblems/GroupAnagrams.java @@ -0,0 +1,29 @@ +package practiceproblems; + +import java.util.*; + +public class GroupAnagrams { + public List> groupAnagrams(String[] strs) { + List> result= new ArrayList<>(); + + if(strs==null || strs.length==0) return result; + Map> map= new HashMap<>(); + + for(String s: strs){ + // int[] cache= new int[26]; + // for(char ch: s.toCharArray()){ + // cache[ch-'a']++; + // } + // String hash=Arrays.toString(cache); + char[] te=s.toCharArray(); + Arrays.sort(te); + String hash=new String(te); + + List list= map.getOrDefault(hash, new LinkedList<>()); + list.add(s); + map.put(hash,list); + } + + return new ArrayList(map.values()); + } +} \ No newline at end of file diff --git a/src/practiceproblems/GroupIsomorphicString.java b/src/practiceproblems/GroupIsomorphicString.java new file mode 100644 index 0000000..234e771 --- /dev/null +++ b/src/practiceproblems/GroupIsomorphicString.java @@ -0,0 +1,56 @@ +package practiceproblems; + +import java.util.*; + +public class GroupIsomorphicString { + public Collection> groupIsomorphicStrings(List strings) { + if (strings == null || strings.isEmpty()) { + return Collections.EMPTY_LIST; + } + + Map> hashToList = new HashMap<>(); + + for (String string : strings) { + String hash = hash(string); + + if (!hashToList.containsKey(hash)) { + hashToList.put(hash, new ArrayList<>()); + } + + hashToList.get(hash).add(string); + } + return hashToList.values(); + } + // this method returns a hash value for every string passed in + // apple = 12234 + // apply = 12234 + // dog = 123 + // cog = 123 + // romi = 1234 + private String hash(String s) { + if (s.isEmpty()) { + return ""; + } + + int count = 1; + StringBuilder hash = new StringBuilder(); + + Map map = new HashMap<>(); + + for (char c : s.toCharArray()) { + + if (!map.containsKey(c)) { + map.put(c, count++); + } + hash.append(map.get(c)); + } + System.out.println(s +" = "+hash.toString() ); + return hash.toString(); + } + + public static void main(String[] args) { + Collection> result = new GroupIsomorphicString() + .groupIsomorphicStrings(Arrays.asList("apple", "apply", "dog", "cog", "romi")); + result.stream().forEach(System.out::println); + } +} diff --git a/src/practiceproblems/HappyNumber.java b/src/practiceproblems/HappyNumber.java new file mode 100644 index 0000000..8f66d07 --- /dev/null +++ b/src/practiceproblems/HappyNumber.java @@ -0,0 +1,57 @@ +package practiceproblems; + +import java.util.HashSet; +import java.util.Set; + +/** + * https://leetcode.com/problems/happy-number/ + */ +class HappyNumber { + public boolean isHappy(int n) { + + Set visited = new HashSet<>(); + int sum = String.valueOf(n).chars().map(Character::getNumericValue).map(val -> val * val).sum() == 1 ? 1 : n; + while (true) { + if (sum == 1) { + return true; + } + sum = String.valueOf(sum).chars().map(Character::getNumericValue).map(val -> val * val).sum(); + if (visited.contains(sum)) { + return false; + } + + visited.add(sum); + } + } + + public int next(int n) + { + int res=0; + while (n>0) + { + int t = n % 10; + res += t*t; + n/=10; + } + return res; + } + + public boolean isHappyOpt(int n) + { + int i1=n, i2=next(n); + + while ( i2 != i1) + { + System.out.println("i1: "+ i1+" i2: "+ i2); + i1 = next(i1); + i2 = next(next(i2)); + } + + return i1==1; + } + + public static void main(String[] args) { + HappyNumber hn = new HappyNumber(); + System.out.println(hn.isHappyOpt(19)); + } +} \ No newline at end of file diff --git a/src/practiceproblems/HitCounter.java b/src/practiceproblems/HitCounter.java new file mode 100644 index 0000000..81440fb --- /dev/null +++ b/src/practiceproblems/HitCounter.java @@ -0,0 +1,31 @@ +package practiceproblems; + +import java.util.ArrayDeque; + +public class HitCounter { + ArrayDeque trac; + /** Initialize your data structure here. */ + private final int FIVE_MINUTES = 300; + public HitCounter() { + trac = new ArrayDeque(); + } + + /** + * Record a hit. + @param timestamp - The current timestamp (in seconds granularity). + */ + public void hit(int timestamp) { + trac.addLast(timestamp); + } + + /** + * Return the number of hits in the past 5 minutes. + @param timestamp - The current timestamp (in seconds granularity). + */ + public int getHits(int timestamp) { + while(trac.size() > 0 && ( int) trac.getFirst() + FIVE_MINUTES <= timestamp) { + trac.removeFirst(); + } return trac.size(); + } + +} \ No newline at end of file diff --git a/src/practiceproblems/HouseRobber.java b/src/practiceproblems/HouseRobber.java new file mode 100644 index 0000000..eff9b8d --- /dev/null +++ b/src/practiceproblems/HouseRobber.java @@ -0,0 +1,46 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/house-robber/ + */ +public class HouseRobber { + + public int rob(int[] nums) { + if (nums.length == 0) { + return 0; + } + int incl = nums[0]; + int excl = 0; + for (int i = 1; i < nums.length; i++) { + int temp = incl; + incl = Math.max(incl, excl + nums[i]); + excl = temp; + } + return incl; + } + + public int robCircular(int[] nums) { + + if(nums.length==0) return 0; + if(nums.length==1) return nums[0]; + return Math.max(helperFn(nums,0,nums.length-2), helperFn(nums,1,nums.length-1)); + + } + + public int helperFn(int[] nums, int start, int end){ + int pre=0; int cur=0; + for(int i=start;i<=end;i++){ + int temp=Math.max(pre+nums[i],cur); + pre=cur; + cur=temp; + + } + return cur; + } + + public static void main(String[] args) { + int[] arr = { 2, 7, 9, 3, 1 }; + HouseRobber houseRobber = new HouseRobber(); + System.out.println(houseRobber.rob(arr)); + } +} diff --git a/src/practiceproblems/IPOMaxProfit.java b/src/practiceproblems/IPOMaxProfit.java new file mode 100644 index 0000000..8d0b08a --- /dev/null +++ b/src/practiceproblems/IPOMaxProfit.java @@ -0,0 +1,46 @@ +package practiceproblems; + + + +import java.util.PriorityQueue; +//https://leetcode.com/problems/ipo/ + +// Input: distinctProjToFind=2, capital=0, Profits=[1,2,3], Capital=[0,1,1]. +// Output: 4 + +// Explanation: Since your initial capital is 0, you can only start the project indexed 0. +// After finishing it you will obtain profit 1 and your capital becomes 1. +// With capital 1, you can either start the project indexed 1 or the project indexed 2. +// Since you can choose at most 2 projects, you need to finish the project indexed 2 to get the maximum capital. +// Therefore, output the final maximized capital, which is 0 + 1 + 3 = 4. +public class IPOMaxProfit { + + // Create (capital, profit) pairs and put them into PriorityQueue pqCap. + // This PriorityQueue sort by capital increasingly. + // Keep polling pairs from pqCap until the project out of current capital capability. Put them into + // PriorityQueue pqPro which sort by profit decreasingly. + // Poll one from pqPro, it's guaranteed to be the project with max profit and within current capital capability. + //Add the profit to capital W. + //Repeat step 2 and 3 till finish k steps or no suitable project (pqPro.isEmpty()). + public int findMaximizedCapital(int steps, int initialCapital, int[] Profits, int[] Capital) { + + PriorityQueue minQueue= new PriorityQueue<>((a, b)->Integer.compare(a[0],b[0])); + PriorityQueue maxQueue= new PriorityQueue<>((a,b)->Integer.compare(b[1],a[1])); + + for(int i=0;i dirs = new HashMap < > (); + HashMap < String, String > files = new HashMap < > (); + } + Dir root; + public InMemeoryFIleSystem() { + root = new Dir(); + } + public List < String > ls(String path) { + Dir t = root; + List < String > files = new ArrayList < > (); + if (!path.equals("/")) { + String[] d = path.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.dirs.get(d[i]); + } + if (t.files.containsKey(d[d.length - 1])) { + files.add(d[d.length - 1]); + return files; + } else { + t = t.dirs.get(d[d.length - 1]); + } + } + files.addAll(new ArrayList < > (t.dirs.keySet())); + files.addAll(new ArrayList < > (t.files.keySet())); + Collections.sort(files); + return files; + } + + public void mkdir(String path) { + Dir t = root; + String[] d = path.split("/"); + for (int i = 1; i < d.length; i++) { + if (!t.dirs.containsKey(d[i])) + t.dirs.put(d[i], new Dir()); + t = t.dirs.get(d[i]); + } + } + + public void addContentToFile(String filePath, String content) { + Dir t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.dirs.get(d[i]); + } + t.files.put(d[d.length - 1], t.files.getOrDefault(d[d.length - 1], "") + content); + } + + public String readContentFromFile(String filePath) { + Dir t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.dirs.get(d[i]); + } + return t.files.get(d[d.length - 1]); + } +} + +class FileSystem1 { + class File { + boolean isfile = false; + HashMap < String, File > files = new HashMap < > (); + String content = ""; + } + File root; + public void FileSystem() { + root = new File(); + } + + public List < String > ls(String path) { + File t = root; + List< String > files = new ArrayList< >(); + if (!path.equals("/")) { + String[] d = path.split("/"); + for (int i = 1; i < d.length; i++) { + t = t.files.get(d[i]); + } + if (t.isfile) { + files.add(d[d.length - 1]); + return files; + } + } + List < String > res_files = new ArrayList < > (t.files.keySet()); + Collections.sort(res_files); + return res_files; + } + + public void mkdir(String path) { + File t = root; + String[] d = path.split("/"); + for (int i = 1; i < d.length; i++) { + if (!t.files.containsKey(d[i])) + t.files.put(d[i], new File()); + t = t.files.get(d[i]); + } + } + + public void addContentToFile(String filePath, String content) { + File t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.files.get(d[i]); + } + if (!t.files.containsKey(d[d.length - 1])) + t.files.put(d[d.length - 1], new File()); + t = t.files.get(d[d.length - 1]); + t.isfile = true; + t.content = t.content + content; + } + + public String readContentFromFile(String filePath) { + File t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.files.get(d[i]); + } + return t.files.get(d[d.length - 1]).content; + } +} + +/** + * Your FileSystem object will be instantiated and called as such: + * FileSystem obj = new FileSystem(); + * List param_1 = obj.ls(path); + * obj.mkdir(path); + * obj.addContentToFile(filePath,content); + * String param_4 = obj.readContentFromFile(filePath); + */ \ No newline at end of file diff --git a/src/practiceproblems/InOrderSuccessor.java b/src/practiceproblems/InOrderSuccessor.java new file mode 100644 index 0000000..809ae1c --- /dev/null +++ b/src/practiceproblems/InOrderSuccessor.java @@ -0,0 +1,28 @@ +package practiceproblems; +public class InOrderSuccessor { + /* + * @param root: The root of the BST. + * @param p: You need find the successor node of p. + * @return: Successor of p. + */ + TreeNode result=null; + public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { + helperFn(root,p); + return result; + } + // Inorder traversal is obtained by going right first and follow the left path till end + // while traversing right we record the right before taking left turn, in case the left path is null + + public void helperFn(TreeNode root, TreeNode p){ + if(root==null) return; + + if(root.val>p.val){ + + result=root; + helperFn(root.left,p); + }else{ + helperFn(root.right,p); + } + + } +} \ No newline at end of file diff --git a/src/practiceproblems/InorderSuccessorPredecessor.java b/src/practiceproblems/InorderSuccessorPredecessor.java new file mode 100644 index 0000000..243e131 --- /dev/null +++ b/src/practiceproblems/InorderSuccessorPredecessor.java @@ -0,0 +1,105 @@ +package practiceproblems; + +/** + * https://algorithms.tutorialhorizon.com/inorder-predecessor-and-successor-in-binary-search-tree/ + */ +public class InorderSuccessorPredecessor { + static int successor, predecessor; + + public void successorPredecessor(TNode root, int val) { + if (root == null) return; + + if (root.data > val) { + // we make the root as successor because we might have a + // situation when value matches with the root, it wont have + // right subtree to find the successor, in that case we need + // parent to be the successor + successor = root.data; + successorPredecessor(root.left, val); + } else if (root.data < val) { + // we make the root as predecessor because we might have a + // situation when value matches with the root, it wont have + // left subtree to find the predecessor, in that case we need + // parent to be the predecessor. + predecessor = root.data; + successorPredecessor(root.right, val); + } + } + + public static void main(String args[]) { + TNode root = new TNode(25); + root.left = new TNode(15); + root.right = new TNode(40); + root.left.left = new TNode(10); + root.left.left.left = new TNode(5); + root.left.right = new TNode(18); + root.right.left = new TNode(35); + root.right.right = new TNode(45); + root.left.right.left = new TNode(19); + root.left.right.right = new TNode(20); + InorderSuccessorPredecessor i = new InorderSuccessorPredecessor(); + + i.successorPredecessor(root, 20); + + System.out.println("Inorder Successor of 20 is : " + successor + " and predecessor is : " + predecessor); + + } + + TreeNode result=null; + public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { + helperFn(root,p); + return result; + } + + public void helperFn(TreeNode root, TreeNode p){ + if(root==null) return; + + if(root.val>p.val){ + result=root; + helperFn(root.left,p); + }else{ + helperFn(root.right,p); + } + + } + private TreeNode findPredecessor(TreeNode root, TreeNode node) { + TreeNode pre = null; + TreeNode cur = root; + while (cur != null) { + if (cur.val < node.val) { + pre = cur; + cur = cur.right; + } else { + cur = cur.left; + } + } + return pre; + } + private TreeNode findSuccessor(TreeNode root, TreeNode node) { + TreeNode succ = null; + TreeNode cur = root; + while (cur != null) { + if (cur.val > node.val) { + succ = cur; + cur = cur.left; + } else { + cur = cur.right; + } + } + return succ; + } +} + + + + class TNode { + int data; + TNode left; + TNode right; + + public TNode(int data) { + this.data = data; + left = null; + right = null; + } +} \ No newline at end of file diff --git a/src/practiceproblems/InsertIntervals.java b/src/practiceproblems/InsertIntervals.java new file mode 100644 index 0000000..2f78c11 --- /dev/null +++ b/src/practiceproblems/InsertIntervals.java @@ -0,0 +1,36 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.List; + +/** + * Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). + + You may assume that the intervals were initially sorted according to their start times. + Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] + Output: [[1,2],[3,10],[12,16]] + Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10]. + */ +public class InsertIntervals{ + public int[][] insert(int[][] intervals, int[] newInterval) { + List result= new ArrayList<>(); + int i=0; int n= intervals.length; + + while(i + * Insertion sort iterates, + * consuming one input element each repetition, and growing a sorted output list. + * At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. + * It repeats until no input elements remain. + */ +public class InsertionSortList { + public ListNode insertionSortList(ListNode head) { + if (head == null) { + return head; + } + + ListNode helper = new ListNode(0); //new starter of the sorted list + ListNode cur = head; //the node will be inserted + ListNode pre = helper; //insert node between pre and pre.next + ListNode next; //the next node will be inserted + //not the end of input list + while (cur != null) { + next = cur.next; + //find the right place to insert + while (pre.next != null && pre.next.val < cur.val) { + pre = pre.next; + } + //insert between pre and pre.next + cur.next = pre.next; + pre.next = cur; + pre = helper; + cur = next; + } + + return helper.next; + } +} \ No newline at end of file diff --git a/src/practiceproblems/IntegerToBinary.java b/src/practiceproblems/IntegerToBinary.java new file mode 100644 index 0000000..1554270 --- /dev/null +++ b/src/practiceproblems/IntegerToBinary.java @@ -0,0 +1,38 @@ +package practiceproblems; + +class IntegerToBinary { + // function to convert decimal to binary + static void decToBinary(int n) { + // array to store binary number + int[] binaryNum = new int[1000]; + + // counter for binary array + int i = 0; + while (n > 0) { + // storing remainder in binary array + binaryNum[i] = n % 2; + n = n / 2; + i++; + } + + // printing binary array in reverse order + for (int j = i - 1; j >= 0; j--) + System.out.print(binaryNum[j]); + } + + public static void main(String[] args) { + int n = 4; + // decToBinary(n); + // System.out.println("Default method :" + Integer.toBinaryString(4)); + System.out.println(intToBinary(4)); + } + + public static String intToBinary(int n) { + String s = ""; + while (n > 0) { + s = ((n % 2) == 0 ? "0" : "1") + s; + n = n / 2; + } + return s; + } +} \ No newline at end of file diff --git a/src/practiceproblems/IntersectionOfArrays.java b/src/practiceproblems/IntersectionOfArrays.java new file mode 100644 index 0000000..c7992e1 --- /dev/null +++ b/src/practiceproblems/IntersectionOfArrays.java @@ -0,0 +1,79 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +/** + * https://leetcode.com/problems/intersection-of-two-arrays-ii/discuss/82241/AC-solution-using-Java-HashMap + *

+ * Example 1: + *

+ * Input: nums1 = [1,2,2,1], nums2 = [2,2] + * Output: [2,2] + * Example 2: + *

+ * Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] + * Output: [4,9] + */ +public class IntersectionOfArrays { + public static void main(String[] args) { + IntersectionOfArrays intersectionOfArrays = new IntersectionOfArrays(); + int[] nums1 = { 4, 4, 9, 5 }; + int[] nums2 = { 9, 4, 9, 4, 2, 3 }; + System.out.println(Arrays.toString(intersectionOfArrays.intersect(nums1, nums2))); + } + + public int[] intersect(int[] nums1, int[] nums2) { + //The first question is relatively easy, create a hashmap base on number frequency of nums1(whichever one is longer). + + // Then for every element of nums2, look upon the hashmap. If we found an intersection, deduct by 1 to avoid duplicate. + HashMap map = new HashMap<>(); + ArrayList result = new ArrayList<>(); + for (int i = 0; i < nums1.length; i++) { + map.put(nums1[i], map.getOrDefault(nums1[i], 1)); + } + + for (int i = 0; i < nums2.length; i++) { + if (map.containsKey(nums2[i]) && map.get(nums2[i]) > 0) { + result.add(nums2[i]); + map.put(nums2[i], map.get(nums2[i]) - 1); + } + } + + int[] r = new int[result.size()]; + for (int i = 0; i < result.size(); i++) { + r[i] = result.get(i); + } + + return r; + } + + //What if the given array is already sorted? How would you optimize your algorithm? + // Classic two pointer iteration, i points to nums1 and j points to nums2. + // Because a sorted array is in ascending order, so if nums1[i] > nums[j], we need to increment j, and vice versa. + // Only when nums1[i] == nums[j], we add it to the result array. Time Complexity O(max(N, M)) + public int[] intersectSorted(int[] nums1, int[] nums2) { + Arrays.sort(nums1); + Arrays.sort(nums2); + int n = nums1.length, m = nums2.length; + int i = 0, j = 0; + List list = new ArrayList<>(); + while(i < n && j < m){ + int a = nums1[i], b= nums2[j]; + if(a == b){ + list.add(a); + i++; + j++; + }else if(a < b){ + i++; + }else{ + j++; + } + } + int[] ret = new int[list.size()]; + for(int k = 0; k < list.size();k++) ret[k] = list.get(k); + return ret; + } +} \ No newline at end of file diff --git a/src/practiceproblems/IsEditOneDistanceAway.java b/src/practiceproblems/IsEditOneDistanceAway.java new file mode 100644 index 0000000..f85ecce --- /dev/null +++ b/src/practiceproblems/IsEditOneDistanceAway.java @@ -0,0 +1,63 @@ +package practiceproblems; + +/** + * Given two strings first and second, determine if they are both one edit distance apart. + * One edit distance means doing one of these operation: + * + * insert one character in any position of S + * delete one character in S + * change one character in S to other character + * + * Input: s = "ab", t = "ab" + * Output: false + * Explanation: + * s=t ,so they aren't one edit distance apart + * + * Input: s = "aDb", t = "adb" + * Output: true + */ +public class IsEditOneDistanceAway { + static boolean isOneEdit(String first, String second) { + // if the input string are same + if (first.equals(second)) + return false; + + int len1 = first.length(); + int len2 = second.length(); + // If the length difference of the stings is more than 1, return false. + if ((len1 - len2) > 1 || (len2 - len1) > 1) { + return false; + } + int i = 0, j = 0; + int diff = 0; + while (i < len1 && j < len2) { + char f = first.charAt(i); + char s = second.charAt(j); + if (f != s) { + diff++; + // delete a character + if (len1 > len2) + i++; + // add a character + if (len2 > len1) + j++; + // replace a character + if (len1 == len2) + i++; + j++; + } else { + i++; + j++; + } + if (diff > 1) { + return false; + } + } + // If the length of the string is not same. ex. "abc" and "abde" are not one + // edit distance. + if (diff == 1 && len1 != len2 && (i != len1 || j != len2)) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/src/practiceproblems/IsSubsequence.java b/src/practiceproblems/IsSubsequence.java new file mode 100644 index 0000000..6491928 --- /dev/null +++ b/src/practiceproblems/IsSubsequence.java @@ -0,0 +1,22 @@ +package practiceproblems; + +public class IsSubsequence { + // Input: s = "abc", t = "ahbgdc" + // Output: true + // Input: s = "axc", t = "ahbgdc" + // Output: false + public boolean isSubsequence(String s, String t) { + if(s==null || t==null) return false; + int i=0; int j=0; + + while(i queue = new ArrayDeque<>(); + queue.offer(root); + while (!queue.isEmpty()) { + Pair temp = queue.poll(); + for (int[] dir : directions) { + + int x = temp.x + dir[0]; + int y = temp.y + dir[1]; + if (isvalid(grid, x, y)) { + grid[x][y] = '0'; + queue.offer(new Pair(x, y)); + } + } + } + } + + public boolean isvalid(char[][] grid, int x, int y) { + if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] == '0') { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/src/practiceproblems/Islands.java b/src/practiceproblems/Islands.java new file mode 100644 index 0000000..05ff0f1 --- /dev/null +++ b/src/practiceproblems/Islands.java @@ -0,0 +1,44 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/find-number-of-islands/ + */ +class Islands { + + private int n; + private int m; + + public int numIslands(int[][] grid) { + int count = 0; + n = grid.length; + if (n == 0) { + return 0; + } + m = grid[0].length; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) + if (grid[i][j] == 1) { + DFSMarking(grid, i, j); + ++count; + } + } + return count; + } + + private void DFSMarking(int[][] grid, int i, int j) { + if (i < 0 || j < 0 || i >= n || j >= m || grid[i][j] != 1) { + return; + } + grid[i][j] = 0; + DFSMarking(grid, i + 1, j); + DFSMarking(grid, i - 1, j); + DFSMarking(grid, i, j + 1); + DFSMarking(grid, i, j - 1); + } + + public static void main(String[] args) { + int M[][] = new int[][] { { 1, 1, 1, 1, 0 }, { 1, 1, 0, 1, 0 }, { 1, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0 } }; + Islands I = new Islands(); + System.out.println("Number of islands is: " + I.numIslands(M)); + } +} diff --git a/src/practiceproblems/IsomorphicString.java b/src/practiceproblems/IsomorphicString.java new file mode 100644 index 0000000..cc08bae --- /dev/null +++ b/src/practiceproblems/IsomorphicString.java @@ -0,0 +1,31 @@ +package practiceproblems; + +import java.util.Arrays; + +/** + * https://www.geeksforgeeks.org/check-if-two-given-strings-are-isomorphic-to-each-other/ + */ +class IsomorphicString { + static boolean isIsomorphic(String s, String t) { + char[] m1 = new char[256]; + char[] m2 = new char[256]; + int n = s.length(); + for (int i = 0; i < n; ++i) { + // it checks the count of the character in the array ; + // for 'g' -> a[103] is 2 and 'd' -> a[100] is 2 + // if both are same both gets incremented together else return false + if (m1[s.charAt(i)] != m2[t.charAt(i)]) { + return false; + } + m1[s.charAt(i)] = (char) (i + 1); + m2[t.charAt(i)] = (char) (i + 1); + } + System.out.println(Arrays.toString(m1)); + System.out.println(Arrays.toString(m2)); + return true; + } + + public static void main(String[] args) { + System.out.println(isIsomorphic("egg", "add")); + } +}; \ No newline at end of file diff --git a/src/practiceproblems/JumpsToReachEnd.java b/src/practiceproblems/JumpsToReachEnd.java new file mode 100644 index 0000000..609b96b --- /dev/null +++ b/src/practiceproblems/JumpsToReachEnd.java @@ -0,0 +1,96 @@ +package practiceproblems; + +import java.util.*; + +public class JumpsToReachEnd { + + /** + * Given an array of non-negative integers nums, + * you are initially positioned at the first index of the array. + * Each element in the array represents your maximum jump length at that position. + * + * Determine if you are able to reach the last index + * Input: nums = [2,3,1,1,4] + * Output: true + * Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index. + * + * Input: nums = [3,2,1,0,4] + * Output: false + * Explanation: You will always arrive at index 3 no matter what. + * Its maximum jump length is 0, which makes it impossible to reach the last index. + */ + public static boolean canReachEnd(Integer[] nums) { + + int curMax = nums[0]; + for (int i = 1; i < nums.length; i++) { + if (curMax < i) return false; //means we are not able to reach position i + curMax = Math.max(curMax, i + nums[i]); + } + return true; + } + + + /** + *Given an array of non-negative integers arr, + * you are initially positioned at start index of the array. + * When you are at index i, you can jump to i + arr[i] or i - arr[i], + * check if you can reach to any index with value 0. + * Notice that you can not jump outside of the array at any time. + * + * Input: arr = [4,2,3,0,3,1,2], start = 5 + * Output: true + * Explanation: + * All possible ways to reach at index 3 with value 0 are: + * index 5 -> index 4 -> index 1 -> index 3 + * index 5 -> index 6 -> index 4 -> index 1 -> index 3 + * + * Input: arr = [4,2,3,0,3,1,2], start = 0 + * Output: true + * Explanation: + * One possible way to reach at index 3 with value 0 is: + * index 0 -> index 4 -> index 1 -> index 3 + */ + public boolean canReach(int[] arr, int start) { + // visited check included + if(start>=arr.length || start<0 || arr[start]>arr.length || arr[start]<0) return false; + if(arr[start]==0 ) return true; + arr[start]=-arr[start]; // visited marking + return canReach(arr, start+arr[start]) || canReach(arr, start-arr[start]); + + } + + + public int minJump(int[] nums) { + if(nums==null || nums.length==0) return 0; + int currentMax=0; + int currentEnd=0; + int jumps=0; + + for(int i=0;i=nums.length-1){ // if the current pick solves the issue + jumps++; + break; + } + //Once the current point reaches curEnd, + //then trigger another jump, and set the new curEnd with curFarthest, + //then keep the above steps, as the following + + //This is an implicit bfs solution. i == curEnd means you visited all the items on the current level. + // Incrementing jumps++ is like incrementing the level you are on. + // And curEnd = curFarthest is like getting the queue size (level size) for the next level you are traversing. + if(currentEnd==i){ // when the current pick of ladder reached last step + jumps++; + currentEnd=currentMax; + } + } + return jumps; + } + + public static void main(String[] args) { + + List list= Arrays.asList(3,3,1,0, 2,0,1); + System.out.println(canReachEnd(list.toArray(new Integer[list.size()]))); + } +} \ No newline at end of file diff --git a/src/practiceproblems/KClosestElements.java b/src/practiceproblems/KClosestElements.java new file mode 100644 index 0000000..629be41 --- /dev/null +++ b/src/practiceproblems/KClosestElements.java @@ -0,0 +1,66 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.PriorityQueue; + +/** + * Given a sorted array arr, two integers k and x, find the k closest elements to x in the array. + * Input: arr = [1,2,3,4,5], k = 4, x = 3 +Output: [1,2,3,4] + */ +public class KClosestElements { + public List findClosestElements(int[] arr, int k, int x) { + // since this is sorted array we are making use of binary search to get index of X and + // fix the range between index-K to index+K and doing normal PQ solution + int index= binarySearch(arr,x); + //if(index==-1) return Collections.emptyList(); + + int low= Math.max(0,index-k); + int high= Math.min(index+k,arr.length-1); + + PriorityQueue queue= new PriorityQueue<>((a, b)->Integer.compare(a.key,b.key)); + + for(int i=low;i<=high;i++){ + // taking abs value because question is askin closest in both signs + queue.offer(new Entry(Math.abs(arr[i]-x),i)); + } + List result= new ArrayList<>(); + int i=0; + while(i0){ + start--; + } + return start; + } +} + +class Entry{ + int key; + int value; + public Entry(int key, int value){ + this.key=key; + this.value=value; + } +} \ No newline at end of file diff --git a/src/practiceproblems/KmostFrequentLetters.java b/src/practiceproblems/KmostFrequentLetters.java new file mode 100644 index 0000000..9dacc7f --- /dev/null +++ b/src/practiceproblems/KmostFrequentLetters.java @@ -0,0 +1,50 @@ +package practiceproblems; + +import java.util.*; + +/** + * Given a list of reviews, a list of keywords and an integer k. + * Find the most popular k keywords in order of most to least frequently mentioned. + * The comparison of strings is case-insensitive. + * Multiple occurrences of a keyword in a review should be considered as a single mention. + * If keywords are mentioned an equal number of times in reviews, sort alphabetically. + */ +public class KmostFrequentLetters { + public static void main(String[] args) { + int k1 = 2; + String[] keywords1 = {"anacell", "cetracular", "betacellular"}; + String[] reviews1 = {"Anacell provides the best services in the city", "betacellular has awesome services", + "Best services provided by anacell, everyone should use anacell",}; + int k2 = 2; + String[] keywords2 = {"anacell", "betacellular", "cetracular", "deltacellular", "eurocell"}; + String[] reviews2 = {"I love anacell Best services; Best services provided by anacell", + "betacellular has great services", "deltacellular provides much better services than betacellular", + "cetracular is worse than anacell", "Betacellular is better than deltacellular.",}; + //System.out.println(solve(k1, keywords1, reviews1)); + System.out.println(solve(k2, keywords2, reviews2)); + } + + private static List solve(int k, String[] keywords, String[] reviews) { + List res = new ArrayList<>(); + Set set = new HashSet<>(Arrays.asList(keywords)); + Map map = new HashMap<>(); + for (String r : reviews) { + String[] strs = r.split("\\W"); + Set added = new HashSet<>(); // creating a set per review to avoid duplicate within a review + for (String s : strs) { + s = s.toLowerCase(); + if (set.contains(s) && !added.contains(s)) { + map.put(s, map.getOrDefault(s, 0) + 1); + added.add(s); + } + } + } + PriorityQueue> maxHeap = new PriorityQueue<>((a, b) -> a.getValue() == b.getValue() ? a.getKey().compareTo(b.getKey()) : b.getValue() - a.getValue()); + maxHeap.addAll(map.entrySet()); + map.entrySet().forEach(e-> System.out.println(e.getKey() +" "+e.getValue())); + while (!maxHeap.isEmpty() && k-- > 0) { + res.add(maxHeap.poll().getKey()); + } + return res; + } +} \ No newline at end of file diff --git a/src/practiceproblems/KthClosestOrigin.java b/src/practiceproblems/KthClosestOrigin.java new file mode 100644 index 0000000..ce4bf58 --- /dev/null +++ b/src/practiceproblems/KthClosestOrigin.java @@ -0,0 +1,74 @@ +package practiceproblems; + +import java.util.Arrays; +import java.util.Random; + +/** + * https://leetcode.com/problems/k-closest-points-to-origin/solution/ + */ +class KthClosestOrigin { + int[][] points = new int[3][2]; + + // quick select + public int[][] kClosest(int[][] points, int K) { + this.points= points; + sort(0, points.length - 1, K); + return Arrays.copyOfRange(points, 0, K); + } + + public void sort(int i, int j, int K) { + if (i >= j) { + return; + } + int k = new Random().nextInt(j - i + 1) + i; + swap(i, k); + + int mid = partition(i, j); + int leftLength = mid - i + 1; + if (K < leftLength) { + sort(i, mid - 1, K); + } else if (K > leftLength) { + sort(mid + 1, j, K - leftLength); + } + } + + public int partition(int i, int j) { + int pivot = dist(i); + swap(i, j); + int iLow = i; + for (int i1 = i; i1 < j; i1++) { + if (dist(i1) <= pivot) { + swap(i1, iLow); + iLow++; + } + } + swap(iLow, j); + return iLow; + } + + public int dist(int i) { + return points[i][0] * points[i][0] + points[i][1] * points[i][1]; + } + + public void swap(int i, int j) { + int t0 = points[i][0], t1 = points[i][1]; + points[i][0] = points[j][0]; + points[i][1] = points[j][1]; + points[j][0] = t0; + points[j][1] = t1; + } + public static void main(String[] args) { +// KthClosestOrigin kth = new KthClosestOrigin(); +// points[0][0] = 3; +// points[0][1] = 3; +// +// points[1][0] = 5; +// points[1][1] = -1; +// +// points[2][0] = 2; +// points[2][1] = 4; +// +// // System.out.println(Arrays.deepToString(kth.kClosestOLogN(points, 1))); +// System.out.println(Arrays.deepToString(kth.kClosest(points, 2))); + } +} diff --git a/src/practiceproblems/KthSmallestFromTwoSortedArrays.java b/src/practiceproblems/KthSmallestFromTwoSortedArrays.java new file mode 100644 index 0000000..425377e --- /dev/null +++ b/src/practiceproblems/KthSmallestFromTwoSortedArrays.java @@ -0,0 +1,43 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/k-th-element-two-sorted-arrays/ + */ +class KthSmallestFromTwoSortedArrays { + + public static int findKth(int[] A, int i, int[] B, int j, int k) { + + if ((A.length - i) > (B.length - j)) { + return findKth(B, j, A, i, k); + } + + if (i >= A.length) { + return B[j + k - 1]; + } + if (k == 1) { + return Math.min(A[i], B[j]); + } + + int aMid = Math.min(k / 2, A.length - i); + int bMid = k - aMid; + + if (A[i + aMid - 1] <= B[j + bMid - 1]) { + return findKth(A, i + aMid, B, j, k - aMid); + } + + return findKth(A, i, B, j + bMid, k - bMid); + } + + public static void main(String[] args) { + int arr1[] = { 1, 6, 8, 9, 15 }; + int arr2[] = { 3, 5, 10, 14, 20 }; + + int k = 6; + int ans = findKth(arr1, 0, arr2, 0, k); + if (ans == -1) { + System.out.println("Invalid query"); + } else { + System.out.println(ans); + } + } +} diff --git a/src/practiceproblems/KthSmallestMatrix.java b/src/practiceproblems/KthSmallestMatrix.java new file mode 100644 index 0000000..b0a21a6 --- /dev/null +++ b/src/practiceproblems/KthSmallestMatrix.java @@ -0,0 +1,51 @@ +package practiceproblems; + +import java.util.PriorityQueue; + +/*https://www.geeksforgeeks.org/kth-smallest-element-in-a-row-wise-and-column-wise-sorted-2d-array-set-1/*/ +public class KthSmallestMatrix { + public static int kthSmallest(int[][] matrix, int k) { + int n = matrix.length; + PriorityQueue pq = new PriorityQueue<>(); + // add first row elements + for (int j = 0; j <= n - 1; j++) + pq.offer(new Points(0, j, matrix[0][j])); + for (int i = 0; i < k - 1; i++) { + Points t = pq.poll(); + System.out.println(t.x); + if (t.x == n - 1) { + continue; + } + pq.offer(new Points(t.x + 1, t.y, matrix[t.x + 1][t.y])); + } + return pq.poll().val; + } + + public static void main(String[] args) { + int[][] matrix = { { 1, 2, 9 }, { 3, 11, 13 }, { 4, 13, 15 } }; + int k = 4; + + System.out.println(kthSmallest(matrix, k)); + } +} + +class Points implements Comparable { + int x; + int y; + int val; + + public Points(int x, int y, int val) { + this.x = x; + this.y = y; + this.val = val; + } + + @Override + public int compareTo(Points that) { + return this.val - that.val; + } + + public String toString() { + return this.val + ""; + } +} \ No newline at end of file diff --git a/src/practiceproblems/LIS2DMatrix.java b/src/practiceproblems/LIS2DMatrix.java new file mode 100644 index 0000000..abae2bf --- /dev/null +++ b/src/practiceproblems/LIS2DMatrix.java @@ -0,0 +1,52 @@ +package practiceproblems; + +/** + * DFS + Memoization + *

+ * Traverse all points in matrix, use every point as starting point to do dfs traversal. DFS function returns max increasing + * path after comparing four max return distance from four directions. + */ + +class LIS2DMatrix { + int[][] dirs = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; + + public int longestIncreasingPath(int[][] matrix) { + + if (matrix.length == 0) return 0; + // i+1,j, i-1,j i,j+1 i,j-1 + Integer[][] cache = new Integer[matrix.length][matrix[0].length]; + //Arrays.fill(cache,-1); + int result = 0; + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix[0].length; j++) { + result = Math.max(dfsUtil(matrix, i, j, cache, Integer.MIN_VALUE), result); + } + } + + return result; + } + + public int dfsUtil(int[][] matrix, int i, int j, Integer[][] cache, int data) { + if (i < 0 || i >= matrix.length || j < 0 || j >= matrix[0].length || data >= matrix[i][j]) return 0; + + + if (cache[i][j] != null) return cache[i][j]; + + int max = 1; // every element is an answer to itself + + for (int[] dir : dirs) { + + int x = i + dir[0]; + int y = j + dir[1]; + + int count = 1 + dfsUtil(matrix, x, y, cache, matrix[i][j]); + max = Math.max(count, max); + } + cache[i][j] = max; + + return cache[i][j]; + + } + + +} \ No newline at end of file diff --git a/src/practiceproblems/LRUCache.java b/src/practiceproblems/LRUCache.java new file mode 100644 index 0000000..a96554b --- /dev/null +++ b/src/practiceproblems/LRUCache.java @@ -0,0 +1,123 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +class LRUCache { + + class DLLNode{ + DLLNode prev; + DLLNode next; + int val; + int key; + public DLLNode(int key, int val){ + this.val=val; + this.key=key; + } + } + Map map; + DLLNode head; + DLLNode tail; + int capacity=0; + public LRUCache(int capacity) { + map= new HashMap<>(); + head= new DLLNode(-1,-1); + tail= new DLLNode(-1,-1); + head.next=tail; + tail.prev=head; + this.capacity=capacity; + } + + public int get(int key) { + if(!map.containsKey(key)) return -1; + DLLNode node= map.get(key); + update(node); + return node.val; + } + + public void put(int key, int value) { + if(map.containsKey(key)){ + DLLNode node= map.get(key); + node.val=value; + update(node); + }else{ + if(map.size()>=capacity){ + removeTail(); + } + DLLNode newNode= new DLLNode(key,value); + map.put(key, newNode); + + updateHead(newNode); + } + } + + public void removeTail(){ + DLLNode tailNode=tail.prev; + remove(tailNode); + map.remove(tailNode.key); + } + + public void updateHead(DLLNode node){ + node.prev = head; + node.next = head.next; + head.next.prev = node; + head.next = node; + } + + public void remove(DLLNode node){ + DLLNode next= node.next; + DLLNode prev= node.prev; + prev.next=next; + next.prev=prev; + } + public void update(DLLNode node){ + remove(node); + updateHead(node); + } + } + + + class LRUCache1 { + LinkedHashMap isbnToPrice; + + public LRUCache1(final int capacity) { + this.isbnToPrice + = new LinkedHashMap(capacity, 1f, true) { + @Override + protected boolean removeEldestEntry(Map.Entry e) { + return this.size() > capacity; + } + }; + } + + public Integer lookup(Integer key) { + if (!isbnToPrice.containsKey(key)) { + return null; + } + return isbnToPrice.get(key); + } + + public Integer insert(Integer key, Integer value) { + // We add the value for key only if key is not present - we don’t update + // existing values. + Integer currentValue = isbnToPrice.get(key); + if (!isbnToPrice.containsKey(key)) { + isbnToPrice.put(key, value); + return currentValue; + } else { + return null; + } + } + + public Integer erase(Object key) { + return isbnToPrice.remove(key); + } + + } + /** + * Your LRUCache object will be instantiated and called as such: + * LRUCache obj = new LRUCache(capacity); + * int param_1 = obj.get(key); + * obj.put(key,value); + */ \ No newline at end of file diff --git a/src/practiceproblems/LargestDivisibleSubset.java b/src/practiceproblems/LargestDivisibleSubset.java new file mode 100644 index 0000000..d38fa2a --- /dev/null +++ b/src/practiceproblems/LargestDivisibleSubset.java @@ -0,0 +1,66 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Given a set of distinct positive integers, + * find the largest subset such that every pair (Si, Sj) of elements in this subset satisfies: + Si % Sj = 0 or Sj % Si = 0. + If there are multiple solutions, return any subset is fine. + Input: [2,3,4,6,10,8,24] + Output: [2,4,8,24] each pair's modulo is 0 + */ +public class LargestDivisibleSubset { + + /** + * if a%b==0 means a>b, if b>a then the ans is b itself + *inorder to have that we need to sort the array in increasing order + at first each val is ans to itself, then we come from last so a is higher in a%b + for ex if 2 is factor of 4 then include the set involve in available. This is DP problem + [2, 3, 4, 6, 8, 10, 24] + {2} {3} {4} {6} {8} {10} {24} + {8,24} + + {6,24} + + {4,8,24} + + {3,6,24} + + {2,4,8,24} + * + */ + public List largestDivisibleSubset(int[] nums) { + if(nums==null || nums.length==0) return Collections.emptyList(); + + Arrays.sort(nums); + List[] result= new ArrayList[nums.length]; + + int maxLength=0; + int resIndex=-1; + List re; + + for(int i=nums.length-1;i>=0;i--){ + result[i]=new ArrayList<>(); // every element is an answer itself + re= new ArrayList<>(); + result[i].add(nums[i]); + for(int j=i+1;j re.size()){ // this is to take even if 1 element is at j position + re=result[j]; // the reason we take list is consider 4,8,24 when i is at 4 and j is 8 mod is 0 means 4%24 is also zero + } + } + } + result[i].addAll(re); + if(result[i].size()>maxLength){ + maxLength=result[i].size(); + resIndex=i; + } + } + Collections.sort(result[resIndex]); + return result[resIndex]; + } +} \ No newline at end of file diff --git a/src/practiceproblems/LargestPossibleNumber.java b/src/practiceproblems/LargestPossibleNumber.java new file mode 100644 index 0000000..0acbc49 --- /dev/null +++ b/src/practiceproblems/LargestPossibleNumber.java @@ -0,0 +1,55 @@ +package practiceproblems; + +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +/** + * https://www.geeksforgeeks.org/given-an-array-of-numbers-arrange-the-numbers-to-form-the-biggest-number/ + */ +class LargestPossibleNumber { + + public static void main(String[] args) { + int nums[] = { 10, 68, 97, 9, 21, 12 }; + List numbers = Arrays.asList("10", "68", "97", "9", "21", "12"); + + Collections.sort(numbers, (a, b) -> (b + a).compareTo(a + b)); + numbers.stream().forEach(System.out::print); + System.out.println(new LargestPossibleNumber().largestNumber(nums)); + } + + public String largestNumber(int[] nums) { + String[] arr = new String[nums.length]; + for (int i = 0; i < nums.length; i++) { + arr[i] = String.valueOf(nums[i]); + } + + Arrays.sort(arr, (a, b) -> { + return (b + a).compareTo(a + b); + }); + + StringBuilder sb = new StringBuilder(); + for (String s : arr) { + sb.append(s); + } + + while (sb.charAt(0) == '0' && sb.length() > 1) + sb.deleteCharAt(0); + + return sb.toString(); + } + + public String largestNumber1(int[] nums) { + if(nums==null || nums.length==0) return null; + List list= new LinkedList<>(); + for(int i: nums){ + list.add(String.valueOf(i)); + } + + Collections.sort(list, (a,b)->(int)(Long.parseLong(b+a)-Long.parseLong(a+b))); + + return String.join("",list).replaceFirst("^0+(?!$)", ""); + + } +} \ No newline at end of file diff --git a/src/practiceproblems/LargestSubArrayWithZeroesAndOnes.java b/src/practiceproblems/LargestSubArrayWithZeroesAndOnes.java new file mode 100644 index 0000000..5ceeb3b --- /dev/null +++ b/src/practiceproblems/LargestSubArrayWithZeroesAndOnes.java @@ -0,0 +1,68 @@ +package practiceproblems; + +import java.util.HashMap; + +/*https://www.geeksforgeeks.org/largest-subarray-with-equal-number-of-0s-and-1s/ + Given an array containing only 0s and 1s, find the largest subarray which contains equal no of 0s and 1s. + Expected time complexity is O(n). +*/ +class LargestSubArrayWithZeroesAndOnes { + /** + * The concept of taking cumulative sum, taking 0’s as -1 will help us in optimising the approach. + * While taking the cumulative sum, there are two cases when there can be a sub-array with equal number of 0’s and 1’s + * When cumulative sum=0, which signifies that sub-array from index (0) till present index has equal number of 0’s and 1’s. + * + * When we encounter a cumulative sum value which we have already encountered before, + * which means that sub-array from the previous index+1 till the present index has equal number of 0’s and 1’s as they give a cumulative sum of 0 . + * @param arr + * @param n + * @return + */ + int maxLen(int arr[], int n) { + + HashMap map = new HashMap<>(); + + int sum = 0; + int maxLength = 0; + int endingIndex = -1; + + for (int i = 0; i < n; i++) { + arr[i] = (arr[i] == 0) ? -1 : 1; + } + + for (int i = 0; i < n; i++) { + sum += arr[i]; + + if (sum == 0) { // To handle sum=0 at last index + maxLength = i + 1; + endingIndex = i; + } + // If this sum is seen before, + // then update max_len if required + if (map.containsKey(sum)) { + if (maxLength < i - map.get(sum)) { + maxLength = i - map.get(sum); + endingIndex = i; + } + } else + map.put(sum, i); + } + + for (int i = 0; i < n; i++) { + arr[i] = (arr[i] == -1) ? 0 : 1; + } + + int start = endingIndex - maxLength + 1; + System.out.println(start + " to " + endingIndex); + + return maxLength; + } + + public static void main(String[] args) { + LargestSubArrayWithZeroesAndOnes sub = new LargestSubArrayWithZeroesAndOnes(); + int arr[] = {0, 0, 0, 1, 0, 1, 1}; + int n = arr.length; + + sub.maxLen(arr, n); + } +} \ No newline at end of file diff --git a/src/practiceproblems/LargestTimeFromDigits.java b/src/practiceproblems/LargestTimeFromDigits.java new file mode 100644 index 0000000..9767d04 --- /dev/null +++ b/src/practiceproblems/LargestTimeFromDigits.java @@ -0,0 +1,39 @@ +package practiceproblems; + +/** + * Given an array of 4 digits, return the largest 24 hour time that can be made. + +The smallest 24 hour time is 00:00, and the largest is 23:59. Starting from 00:00, a time is larger if more time has elapsed since midnight. + +Return the answer as a string of length 5. If no valid time can be made, return an empty string. + */ +public class LargestTimeFromDigits{ + public String largestTimeFromDigits(int[] A) { + if(A==null || A.length==0) return ""; + String result=""; + // because A.length == 4 + for(int i=0;i<4;i++){ + for(int j=0;j<4;j++){ + for(int k=0;k<4;k++){ + //We cannot take a number twice. i, j, k and (6-i-j-k) denoting the indices of 4 numbers should be distinct. + if(i==j || j==k|| k==i) continue; + String hrs= A[i]+""+A[j]; + //We are trying out all possible ordering, + //indices of 4 numbers are 0, 1, 2, and 3. + //sum of indices = 0 + 1 + 2 + 3= 6 + //i, j and k denote 3 indices. + //So, if we know 3 numbers, + //the 4th number will be the remaining index, i.e., 6-i-j-k + + String mins= A[k]+""+A[6-i-j-k]; + + if(hrs.compareTo("24")<0 && mins.compareTo("59")<0 && result.compareTo(hrs+":"+mins)<0){ + result=hrs+":"+mins; + } + + } + } + } + return result; + } +} \ No newline at end of file diff --git a/src/practiceproblems/LeftMostColumnWithOne.java b/src/practiceproblems/LeftMostColumnWithOne.java new file mode 100644 index 0000000..fbbfe27 --- /dev/null +++ b/src/practiceproblems/LeftMostColumnWithOne.java @@ -0,0 +1,42 @@ +package practiceproblems; + +import java.util.List; + +/** + * A binary matrix means that all elements are 0 or 1. For each individual row of the matrix, this row is sorted in non-decreasing order. + * + * Given a row-sorted binary matrix binaryMatrix, return leftmost column index(0-indexed) with at least a 1 in it. If such index doesn’t exist, return -1. + * + * You can’t access the Binary Matrix directly. You may only access the matrix using a BinaryMatrix interface: + * + * BinaryMatrix.get(row, col) returns the element of the matrix at index (row, col) (0-indexed). + * BinaryMatrix.dimensions() returns a list of 2 elements [rows, cols], which means the matrix is rows * cols. + * Submissions making more than 1000 calls to BinaryMatrix.get will be judged Wrong Answer. + * Also, any solutions that attempt to circumvent the judge will result in disqualification + */ +interface BinaryMatrix { + public int get(int row, int col); + public List dimensions(); + } +public class LeftMostColumnWithOne { + + public int leftMostColumnWithOne(BinaryMatrix binaryMatrix) { + List dimension=binaryMatrix.dimensions(); + int n=dimension.get(0); + int m=dimension.get(1); + + int i=0,j=m-1,leftMostOne=-1; // start from 0th row and last column + + while(i=0) + { + int result=binaryMatrix.get(i,j); + if(result==0) + i++; + else{ + leftMostOne=j; + j--; + } + } + return leftMostOne; + } +} diff --git a/src/practiceproblems/LengthOfLongestSubstringKDistinct.java b/src/practiceproblems/LengthOfLongestSubstringKDistinct.java new file mode 100644 index 0000000..ca45e65 --- /dev/null +++ b/src/practiceproblems/LengthOfLongestSubstringKDistinct.java @@ -0,0 +1,90 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class LengthOfLongestSubstringKDistinct { + + public static final int CHAR_RANGE = 128; + /** + * @param s: A string + * @param k: An integer + * @return: An integer + */ + public static int lengthOfLongestSubstringKDistinct(String s, int k) { + if (s == null || k == 0) { + return 0; + } + Map map = new HashMap<>(); + + int result = 0; + int left = 0; + int right = 0; + + while (left < s.length()) { + char ch = s.charAt(left); + map.put(ch, map.getOrDefault(ch, 0) + 1); + while (map.size() > k) { + char chright = s.charAt(right); + map.put(chright, map.get(chright) - 1); + if (map.get(chright) <= 0) { + map.remove(chright); + } + right++; + } + left++; + result = Math.max(result, left - right); + } + + return result; + } + + public static void main(String[] args) { + System.out.println(lengthOfLongestSubstringKDistinct("aaaaaa", 2)); + } + + public static String findLongestSubstring(String str, int k) + { + // stores the longest substring boundaries + int end = 0, begin = 0; + + // set to store distinct characters in a window + Set window = new HashSet<>(); + + // Count array `freq` stores the frequency of characters present in the + // current window. We can also use a map instead of a count array. + int[] freq = new int[CHAR_RANGE]; + + // `[low…high]` maintains the sliding window boundaries + for (int low = 0, high = 0; high < str.length(); high++) + { + window.add(str.charAt(high)); + freq[str.charAt(high)]++; + + // if the window size is more than `k`, remove characters from the left + while (window.size() > k) + { + // If the leftmost character's frequency becomes 0 after + // removing it in the window, remove it from the set as well + if (--freq[str.charAt(low)] == 0) { + window.remove(str.charAt(low)); + } + + low++; // reduce window size + } + + // update the maximum window size if necessary + if (end - begin < high - low) + { + end = high; + begin = low; + } + } + + // return the longest substring found at `str[begin…end]` + return str.substring(begin, end + 1); + } + +} \ No newline at end of file diff --git a/src/practiceproblems/LinkedListRemoveDuplicates.java b/src/practiceproblems/LinkedListRemoveDuplicates.java new file mode 100644 index 0000000..18c5e52 --- /dev/null +++ b/src/practiceproblems/LinkedListRemoveDuplicates.java @@ -0,0 +1,36 @@ +package practiceproblems; + +class LinkedListRemoveDuplicate{ + /** + * Method to remove duplicates from Linked list + * when no additional buffer is allowed. + * + * Time Complexity : O(n^2) + * Space Complexity : O(1) + * + * @param head + */ + public static void removeDuplicatesWithoutBuffer(ListNode head) { + /* If head is null, stop processing */ + if (head == null) { + return; + } + /* We will need two pointers here i.e current and runner. + * When current is pointing to a node, move runner through + * rest of the list, checking for duplicates */ + ListNode current = head; + while (current != null) { + /* Have runner point to current node */ + ListNode runner = current; + while (runner.next != null) { + /* If it is duplicate, jump runner over the node */ + if (runner.next.val == current.val) { + runner.next = runner.next.next; + } else { + runner = runner.next; + } + } + current = current.next; + } + } +} \ No newline at end of file diff --git a/src/practiceproblems/LongestConsequtiveSequence.java b/src/practiceproblems/LongestConsequtiveSequence.java new file mode 100644 index 0000000..5ee2e4a --- /dev/null +++ b/src/practiceproblems/LongestConsequtiveSequence.java @@ -0,0 +1,73 @@ +package practiceproblems; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * Given an unsorted array of integers, + * find the length of the longest consecutive elements sequence. + * + * Your algorithm should run in O(n) complexity. + * Input: [100, 4, 200, 1, 3, 2] + * Output: 4 + * Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. + * Therefore its length is 4. + */ +class LongestConsequtiveSequence { + + public int longestConsecutive(int[] nums) { + if (nums.length == 0) { + return 0; + } + int max = 1; + Set set = new HashSet<>(); + for (int i : nums) { + set.add(i); + } + // have a set, go backwards and remove entries, go forward remove entries and calculate Max + // without removing entries, runtime would be too much + for (Integer i : nums) { + int num = i; + int count = 1; + // looking left + while (set.contains(--num)) { + count++; + set.remove(num); + } + num = i; + while (set.contains(++num)) { + count++; + set.remove(num); + } + + max = Math.max(max, count); + } + + return max; + } + + public int longestConsecutiveSorting(int[] nums) { + if (nums == null || nums.length == 0) + return 0; + + Arrays.sort(nums); + + int longestStreak = 1; + int currentStreak = 1; + + for (int i = 0; i < nums.length - 1; i++) { + if (nums[i] != nums[i+1]) { // avoid duplicate + if (nums[i] + 1 == nums[i+1]) { // if increasing increase streak count else reset + currentStreak += 1; + } + else { + longestStreak = Math.max(longestStreak, currentStreak); + currentStreak = 1; + } + } + } + + return Math.max(longestStreak, currentStreak); + } +} \ No newline at end of file diff --git a/src/practiceproblems/LongestIncreasingPathInMatrix.java b/src/practiceproblems/LongestIncreasingPathInMatrix.java new file mode 100644 index 0000000..83e49e3 --- /dev/null +++ b/src/practiceproblems/LongestIncreasingPathInMatrix.java @@ -0,0 +1,64 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/longest-increasing-path-in-a-matrix + * + * Do DFS from every cell + * Compare every 4 direction and skip cells that are out of boundary or smaller + * Get matrix max from every cell's max + * Use matrix[x][y] <= matrix[i][j] so we don't need a visited[m][n] array + * The key is to cache the distance because it's highly possible to revisit a cell + * + * DFS + Memoization + * + * Traverse all points in matrix, use every point as starting point to do dfs traversal. DFS function returns max increasing + * path after comparing four max return distance from four directions. + * + * */ +public class LongestIncreasingPathInMatrix { + + int[][] dirs= new int[][] {{1,0},{-1,0},{0,1},{0,-1}}; + public int longestIncreasingPath(int[][] matrix) { + if(matrix.length == 0) return 0; + // i+1,j, i-1,j i,j+1 i,j-1 + Integer[][] cache= new Integer[matrix.length][matrix[0].length]; + + int result=0; + for(int i=0;i=matrix.length || j<0 || j>=matrix[0].length|| data>=matrix[i][j]) return 0; + + + + if(cache[i][j]!=null) return cache[i][j]; + + // initialize max distance as 1 since the path includes starting point itself + int max=1; + + for(int[] dir: dirs){ + + int x=i+dir[0]; + int y=j+dir[1]; + // if next point is a valid point, add curLen by 1 and continue DFS traversal + int count=1+dfsUtil(matrix,x,y,cache, matrix[i][j]); + max=Math.max(count,max); + } + // update max increasing path value starting from current point in cache + cache[i][j]=max; + + return cache[i][j]; + + } + + public boolean isValid(int[][] matrix, int i, int j, int data){ + return i >= 0 && i < matrix.length && j >= 0 && j < matrix[0].length; + } +} diff --git a/src/practiceproblems/LongestRepeatCharReplace.java b/src/practiceproblems/LongestRepeatCharReplace.java new file mode 100644 index 0000000..f5ab7df --- /dev/null +++ b/src/practiceproblems/LongestRepeatCharReplace.java @@ -0,0 +1,47 @@ +package practiceproblems; + +// you can perform at most k operations on that string. +// In one operation, you can choose any character of the string and change it to any other uppercase English character. +// Find the length of the longest sub-string containing all repeating letters +// s = "ABAB", k = 2 +// Output: +// 4 +// Explanation: +// Replace the two 'A's with two 'B's or vice versa. +public class LongestRepeatCharReplace { + public int characterReplacement(String s, int k) { + if(s==null || s.length()==0) return 0; + + int[] cache= new int[26]; + int left=0; + int right=0; + int result=0; + int maxOccured=0; + while(right 0, then we have characters in the window that are NOT the character that occurs the most. + // end-start+1-maxCount is equal to exactly the # of characters that are NOT the character that occurs the most in that window. + //Example: For a window "xxxyz", end-start+1-maxCount would equal 2. (maxCount is 3 and there are 2 characters here, "y" and "z" that are not "x" in the window.) + // We are allowed to have at most k replacements in the window, so when end-start+1-maxCount > k, + //then there are more characters in the window than we can replace, and we need to shrink the window. + // If we have window with "xxxy" and k = 1, that's fine because end-start+1-maxCount = 1, which is not > k. maxLength gets updated to 4. + // But if we then find a "z" after, like "xxxyz", then we need to shrink the window because now end-start+1-maxCount = 2, and 2 > 1. The window becomes "xxyz". + if(right-left+1-maxOccured > k){ + char leftchr= s.charAt(left); + --cache[leftchr-'A']; + left++; + } + result=Math.max(result, right-left+1); + right++; + } + + return result; + } +} \ No newline at end of file diff --git a/src/practiceproblems/LongestSpanWithSameSumArray.java b/src/practiceproblems/LongestSpanWithSameSumArray.java new file mode 100644 index 0000000..ef73db9 --- /dev/null +++ b/src/practiceproblems/LongestSpanWithSameSumArray.java @@ -0,0 +1,74 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.Map; + +/** + * Given two binary arrays arr1[] and arr2[] of same size n. + * Find length of the longest common span (i, j) + * where j >= i such that arr1[i] + arr1[i+1] + …. + arr1[j] = arr2[i] + arr2[i+1] + …. + arr2[j]. + * + * Expected time complexity is Θ(n). + * + * Input: arr1[] = {0, 1, 0, 0, 0, 0}; + * arr2[] = {1, 0, 1, 0, 0, 1}; + * Output: 4 + * The longest span with same sum is from index 1 to 4. + * + * Input: arr1[] = {0, 1, 0, 1, 1, 1, 1}; + * arr2[] = {1, 1, 1, 1, 1, 0, 1}; + * Output: 6 + * The longest span with same sum is from index 1 to 6. + * + * */ +class LongestSpanWithSameSumArray { + // Returns largest common subarray with equal + // number of 0s and 1s + static int longestCommonSum(int[] arr1, int[] arr2, int n) + { + // Find difference between the two + int[] arr = new int[n]; + // the reason we take the difference is, the resultant array + // will only contain 3 values 0,1,-1, checking for zero sum + // on the resultant array means we get the longest span where elements are same + for (int i = 0; i < n; i++) + arr[i] = arr1[i] - arr2[i]; + + // Creates an empty hashMap hM + Map hM = new HashMap<>(); + + int sum = 0; // Initialize sum of elements + int max_len = 0; // Initialize result + + // Traverse through the given array + for (int i = 0; i < n; i++) + { + // Add current element to sum + sum += arr[i]; + + // To handle sum=0 at last index + if (sum == 0) + max_len = i + 1; + + // If this sum is seen before, + // then update max_len if required + if (hM.containsKey(sum)) + max_len = Math.max(max_len, i - hM.get(sum)); + + else // Else put this sum in hash table + hM.put(sum, i); + } + return max_len; + } + + + public static void main(String args[]) { + /* int[] arr1 = {0, 1, 0, 1, 1, 1, 1}; + int[] arr2 = {1, 1, 1, 1, 1, 0, 1};*/ + int arr1[] = { 0, 1, 0, 0, 1, 1, 1, 0 }; + int arr2[] = { 1, 1, 1, 1, 1, 1, 0, 1 }; + //{-1,0,-1,0,0,1,0} + int n = arr1.length; + System.out.println(longestCommonSum(arr1, arr2, n)); + } +} \ No newline at end of file diff --git a/src/practiceproblems/LongestSubArraySumUtmostK.java b/src/practiceproblems/LongestSubArraySumUtmostK.java new file mode 100644 index 0000000..fe9f864 --- /dev/null +++ b/src/practiceproblems/LongestSubArraySumUtmostK.java @@ -0,0 +1,47 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/longest-subarray-sum-elements-atmost-k/ + * + * Given an array of integers, + * our goal is to find the length of largest subarray + * having sum of its elements atmost ‘k’ where k>0. + * + * Examples: + * + * Input : arr[] = {1, 2, 1, 0, 1, 1, 0}, + * k = 4 + * Output : 5 + * Explanation: + * {1, 2, 1} => sum = 4, length = 3 + * {1, 2, 1, 0}, {2, 1, 0, 1} => sum = 4, length = 4 + * {1, 0, 1, 1, 0} =>5 sum = 3, length = 5 + */ +// array is non-negative +class LongestSubArraySumUtmostK { + + public static int utMostSum(int arr[], int n, int target) { + int sum = 0; + int count = 0; + int maxCount = 0; + + for (int i = 0; i < n; i++) { + if ((sum + arr[i]) <= target) { + sum += arr[i]; + count++; + } else if (sum != 0) { + sum = sum - arr[i - count] + arr[i]; + } + maxCount = Math.max(count, maxCount); + } + return maxCount; + } + + public static void main(String[] args) { + int arr[] = { 1, 2, 1, 0, 1, 1, 0 }; + int n = arr.length; + int k = 4; + + System.out.print(utMostSum(arr, n, k)); + } +} diff --git a/src/practiceproblems/LongestUniqueSubstring.java b/src/practiceproblems/LongestUniqueSubstring.java new file mode 100644 index 0000000..3fc1f5f --- /dev/null +++ b/src/practiceproblems/LongestUniqueSubstring.java @@ -0,0 +1,53 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.Map; + +/*https://leetcode.com/problems/longest-substring-without-repeating-characters/*/ +public class LongestUniqueSubstring { + + public static int lengthOfLongestSubstring(String s) { + Map map = new HashMap<>(); + int begin = 0; + int end = 0; + int counter = 0; + int result = 0; + + while (end < s.length()) { + char c = s.charAt(end); + map.put(c, map.getOrDefault(c, 0) + 1); + if (map.get(c) > 1) { + counter++; + } + end++; + + while (counter > 0) { + char charTemp = s.charAt(begin); + if (map.get(charTemp) > 1) { + counter--; + } + map.put(charTemp, map.get(charTemp) - 1); + begin++; + } + result = Math.max(result, end - begin); + } + return result; + } + public static int lengthOfLongestSubstringOpt(String s) { + int res = 0, n = s.length(); + int[] arr = new int[256]; + int startIndex=0; + for(int curr=0;curr next index, so that we can start from here + arr[s.charAt(curr)] = curr+1; + } + return res; + } + public static void main(String[] args) { + System.out.println(lengthOfLongestSubstringOpt("pwwkew")); + } +} \ No newline at end of file diff --git a/src/practiceproblems/MajorityVoting.java b/src/practiceproblems/MajorityVoting.java new file mode 100644 index 0000000..fc5b390 --- /dev/null +++ b/src/practiceproblems/MajorityVoting.java @@ -0,0 +1,86 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.List; + +/*https://leetcode.com/problems/majority-element/*/ +public class MajorityVoting { + + public static List majorityElementII(int[] nums) { + if (nums == null || nums.length == 0) { + return new ArrayList<>(); + } + List result = new ArrayList<>(); + int candidate1 = nums[0]; + int candidate2 = nums[0]; + int count1 = 0; + int count2 = 0; + int len = nums.length; + for (int i = 0; i < len; i++) { + if (nums[i] == candidate1) { + count1++; + } else if (nums[i] == candidate2) { + count2++; + } else if (count1 == 0) { + candidate1 = nums[i]; + count1 = 1; + } else if (count2 == 0) { + candidate2 = nums[i]; + count2 = 1; + } else { + count1--; + count2--; + } + } + count1 = 0; + count2 = 0; + for (int i = 0; i < len; i++) { + if (nums[i] == candidate1) { + count1++; + } else if (nums[i] == candidate2) { + count2++; + } + } + if (count1 > len / 3) { + result.add(candidate1); + } + if (count2 > len / 3) { + result.add(candidate2); + } + return result; + } + + public static int majorityElementI(int[] nums) { + int count = 1; + int candidate = nums[0]; + int majority = nums.length / 2; + + for (int i = 1; i < nums.length; i++) { + if (candidate == nums[i]) { + count++; + } else if (count == 0) { + count++; + candidate = nums[i]; + } else { + count--; + } + } + //what if array is even and it has many elements + count = 0; + for (int num : nums) { + if (num == candidate) { + count++; + } + } + + return count > majority ? candidate : 0; + } + + public static void main(String[] args) { + int[] arr = { 1, 1, 1, 1, 1, 2, 2, 4, 4, 4, 4, 4, 2, 2 }; + System.out.println(majorityElementI(arr)); + System.out.println(majorityElementII(arr)); + + } + +} diff --git a/src/practiceproblems/MakeAnArrayPalindrome.java b/src/practiceproblems/MakeAnArrayPalindrome.java new file mode 100644 index 0000000..25210c1 --- /dev/null +++ b/src/practiceproblems/MakeAnArrayPalindrome.java @@ -0,0 +1,41 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/find-minimum-number-of-merge-operations-to-make-an-array-palindrome/ + */ +class MakeAnArrayPalindrome { + + static int findMinOps(int[] arr, int n) { + int ans = 0; + + // Start from two corners + for (int i = 0, j = n - 1; i <= j; ) { + // If corner elements are same, problem reduces arr[i+1..j-1] + if (arr[i] == arr[j]) { + i++; + j--; + } + // If left element is greater, then we merge right two elements + else if (arr[i] > arr[j]) { + // need to merge from tail. + j--; + arr[j] += arr[j + 1]; + ans++; + } + // Else we merge left two elements + else { + i++; + arr[i] += arr[i - 1]; + ans++; + } + } + + return ans; + } + + public static void main(String[] args) { + int arr[] = new int[] { 1, 4, 5, 9, 1 }; + System.out.println("Count of minimum operations is " + findMinOps(arr, arr.length)); + + } +} \ No newline at end of file diff --git a/src/practiceproblems/MatrixRowWithMax1.java b/src/practiceproblems/MatrixRowWithMax1.java new file mode 100644 index 0000000..4f6e33c --- /dev/null +++ b/src/practiceproblems/MatrixRowWithMax1.java @@ -0,0 +1,48 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/find-the-row-with-maximum-number-1s/ + */ +public class MatrixRowWithMax1 { + + public static void main(String[] args) { + int[][] mat = { { 0, 0, 0, 1 }, { 0, 1, 1, 1 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 } }; + System.out.println(rowWithMax1s(mat)); + } + + static int rowWithMax1s(int mat[][]) { + + int R = mat.length; + int C = mat[0].length; + int max_row_index = 0; + + int j = findFirstIndex(mat[0], 0, C - 1); + if (j == -1) { + j = C - 1; + } + + for (int i = 1; i < R; i++) { + while (j >= 0 && mat[i][j] == 1) { + j = j - 1; + max_row_index = i; + } + } + return max_row_index; + } + + static int findFirstIndex(int arr[], int low, int high) { + if (high >= low) { + int mid = low + (high - low) / 2; + + if ((mid == 0 || (arr[mid - 1] == 0)) && arr[mid] == 1) { + return mid; + } else if (arr[mid] == 0) { + return findFirstIndex(arr, (mid + 1), high); + } else { + return findFirstIndex(arr, low, (mid - 1)); + } + } + return -1; + } + +} diff --git a/src/practiceproblems/MaxDistinctElementAfterKRemoval.java b/src/practiceproblems/MaxDistinctElementAfterKRemoval.java new file mode 100644 index 0000000..3e2c2d2 --- /dev/null +++ b/src/practiceproblems/MaxDistinctElementAfterKRemoval.java @@ -0,0 +1,118 @@ +package practiceproblems; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * Given an array arr[] containing n elements. + * The problem is to find maximum number of distinct elements (non-repeating) after removing k elements from the array. + * Input : arr[] = {5, 7, 5, 5, 1, 2, 2}, k = 3 + * Output : 4 + * + * Remove 2 occurrences of element 5 and + * 1 occurrence of element 2. + * + * Input : arr[] = {1, 2, 3, 4, 5, 6, 7}, k = 5 + * Output : 2 + */ +public class MaxDistinctElementAfterKRemoval { + // after removing k elements + + /** + * Create a hash table to store the frequency of each element. + * Insert frequency of each element in a max heap. + * Now, perform the following operation k times. + * Remove an element from the max heap. Decrement its value by 1. After this if element is not equal to 0, then again push the element in the max heap. + * @param arr + * @param n + * @param k + * @return + */ + static int maxDistinctNum(int[] arr, int n, int k) + { + // hash map to store + // frequency of each element + HashMap map = new HashMap<>(); + + // priority_queue 'pq' implemented as + // max heap + PriorityQueue pq = + new PriorityQueue<>(Collections.reverseOrder()); + + // storing frequency of each element in map + for (int i = 0; i < n; i++) { + map.put(arr[i], map.getOrDefault(arr[i],0)+1); + } + + // inserting frequency of each element in 'pq' + for (Map.Entry entry : map.entrySet()) { + pq.add(entry.getValue()); + } + + while (k > 0) { + // get the top element of 'pq' + int temp = pq.poll(); + + // decrement the popped element by 1 + temp--; + + // if true, then push the element in 'pq' + if (temp > 0) + pq.add(temp); + k--; + } + + // Count all those elements that appear + // once after above operations. + int res = 0; + while (pq.size() != 0) { + pq.poll(); + res++; + } + + return res; + } + + /** + * Given an array of integers arr and an integer k. Find the least number of unique integers after removing exactly k elements. + * Input: arr = [5,5,4], k = 1 + * Output: 1 + * Explanation: Remove the single 4, only 5 is left. + * + * Input: arr = [4,3,1,1,3,3,2], k = 3 + * Output: 2 + * Explanation: Remove 4, 2 and either one of the two 1s or three 3s. 1 and 3 will be left. + * @param arr + * @param k + * @return + */ + public int findLeastNumOfUniqueInts(int[] arr, int k) { + if(arr.length==0) return 0; + Map frequencyMap= new HashMap<>(); + + for(int i: arr){ + frequencyMap.put(i,frequencyMap.getOrDefault(i,0)+1); + } + + PriorityQueue maxQueue= new PriorityQueue<>(); + + for(Map.Entry entry: frequencyMap.entrySet()){ + maxQueue.offer(entry.getValue()); + } + + while(k-- >0){ + int temp= maxQueue.poll(); + temp-=1; + if(temp>0) maxQueue.offer(temp); + + } + + int result=0; + while(!maxQueue.isEmpty()){ + result++; + } + return result; + } +} \ No newline at end of file diff --git a/src/practiceproblems/MaxFreqStack.java b/src/practiceproblems/MaxFreqStack.java new file mode 100644 index 0000000..fe087e2 --- /dev/null +++ b/src/practiceproblems/MaxFreqStack.java @@ -0,0 +1,75 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * FreqStack has two functions: + * + * push(int x), which pushes an integer x onto the stack. + * pop(), which removes and returns the most frequent element in the stack. + * If there is a tie for most frequent element, + * the element closest to the top of the stack is removed and returned. + * ["FreqStack","push","push","push","push","push","push","pop","pop","pop","pop"], + * [[],[5],[7],[5],[7],[4],[5],[],[],[],[]] + * Output: [null,null,null,null,null,null,null,5,7,5,4] + * Explanation: + * After making six .push operations, the stack is [5,7,5,7,4,5] from bottom to top. Then: + * + * pop() -> returns 5, as 5 is the most frequent. + * The stack becomes [5,7,5,7,4]. + * + * pop() -> returns 7, as 5 and 7 is the most frequent, but 7 is closest to the top. + * The stack becomes [5,7,5,4]. + * + * pop() -> returns 5. + * The stack becomes [5,7,4]. + * + * pop() -> returns 4. + * The stack becomes [5,7]. + */ +public class MaxFreqStack { + + PriorityQueue maxQueue; + Map hashMap; + int sequence = 0; + + public MaxFreqStack() { + + maxQueue= new PriorityQueue<>((a,b)->{ + if(a.frequency==b.frequency){ + return Integer.compare(b.sequence,a.sequence); + } + return Integer.compare(b.frequency,a.frequency); + }); + hashMap= new HashMap<>(); + } + + public void push(int x) { + hashMap.put(x, hashMap.getOrDefault(x, 0) + 1); + maxQueue.offer(new EntryStack(x, hashMap.get(x), sequence++)); + } + + public int pop() { + EntryStack temp = maxQueue.poll(); + hashMap.put(temp.val, temp.frequency - 1); + + return temp.val; + } +} + +// 1. val = value of the number +// 2. frequency = current frequency of the number when it was pushed to the heap +// 3. sequenceNumber = a sequence number, to know what number came first +class EntryStack { + int val; + int frequency; + int sequence; + + public EntryStack(int val, int frequency, int sequence) { + this.val = val; + this.frequency = frequency; + this.sequence = sequence; + } +} diff --git a/src/practiceproblems/MaxHistogram.java b/src/practiceproblems/MaxHistogram.java new file mode 100644 index 0000000..841008b --- /dev/null +++ b/src/practiceproblems/MaxHistogram.java @@ -0,0 +1,68 @@ +package practiceproblems; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/largest-rectangle-in-histogram/ + */ + +public class MaxHistogram { + + //For any bar i the maximum rectangle is of width r - l - 1 + // where r - is the last coordinate of the bar to the right with height h[r] >= h[i] and + // l - is the last coordinate of the bar to the left which height h[l] >= h[i] + //So if for any i coordinate we know his utmost higher (or of the same height) neighbors to the right and to the left, + // we can easily find the largest rectangle: maxArea = Math.max(maxArea, height[i] * (lessFromRight[i] - lessFromLeft[i] - 1)); + + //The main trick is how to effectively calculate lessFromRight and lessFromLeft arrays. + // The trivial solution is to use O(n^2) solution and for each i element + // first find his left/right neighbour in the second inner loop just iterating back or forward: + public static int largestRectangleArea(int[] height) { + if (height == null || height.length == 0) { + return 0; + } + int[] lessFromLeft = new int[height.length]; // idx of the first bar the left that is lower than current + int[] lessFromRight = new int[height.length]; // idx of the first bar the right that is lower than current + lessFromRight[height.length - 1] = height.length; + lessFromLeft[0] = -1; + + // for example in order to lessFromLeft[i]; if height[i - 1] < height[i] then left[i] = i - 1; + // other wise we do not need to start scan from i - 1; we can start the scan from lessFromLeft[i - 1], + // because since lessFromLeft[i - 1] is the first position to the left of i - 1 that have height less than height[i - 1], + // and we know height[i - 1] >= height[i]; so lessFromLeft[i] must be at the left or at lessFromLeft[i - 1]; similar for the right array; + for (int i = 1; i < height.length; i++) { + int p = i - 1; + + while (p >= 0 && height[p] >= height[i]) { + p = lessFromLeft[p]; + } + lessFromLeft[i] = p; + } + + for (int i = height.length - 2; i >= 0; i--) { + int p = i + 1; + + while (p < height.length && height[p] >= height[i]) { + p = lessFromRight[p]; + } + lessFromRight[i] = p; + } + // after both the loop ends, this is the output of left and right + // input [2, 1, 5, 6, 2, 3] + // 0, 1, ,2 3, 4, 5 + // left [-1, -1, 1, 2, 1, 4] => indexes of elements + // right [1, 6, 4, 4, 6, 6] + int maxArea = 0; + for (int i = 0; i < height.length; i++) { + maxArea = Math.max(maxArea, height[i] * (lessFromRight[i] - lessFromLeft[i] - 1)); + } + System.out.println(Arrays.toString(lessFromLeft)); + System.out.println(Arrays.toString(lessFromRight)); + return maxArea; + } + + public static void main(String[] args) { + int[] arr = new int[] { 2, 1, 5, 6, 2, 3 }; + System.out.println(largestRectangleArea(arr)); + } +} \ No newline at end of file diff --git a/src/practiceproblems/MaxProductString.java b/src/practiceproblems/MaxProductString.java new file mode 100644 index 0000000..5474c06 --- /dev/null +++ b/src/practiceproblems/MaxProductString.java @@ -0,0 +1,57 @@ +package practiceproblems; + +/** + * Given a string array words, find the maximum value of length(word[i]) * length(word[j]) + * where the two words do not share common letters. + * You may assume that each word will contain only lower case letters + * Input: ["abcw","baz","foo","bar","xtfn","abcdef"] + * Output: 16 + * Explanation: The two words can be "abcw", "xtfn". + * + * Input: ["a","aa","aaa","aaaa"] + * Output: 0 + * Explanation: No such pair of words. + */ +public class MaxProductString { + public int maxProduct(String[] words) { + int[] checker = new int[words.length]; + int max = 0; + // populating the checker array with their respective numbers + for (int i = 0; i < checker.length; i++) { + int num = 0; + for (int j = 0; j < words[i].length(); j++) { + // we are making char index in bit to be set + // a 1->1 making first bit marked + // b 2->10 + // c 4->100 + // ab 3->11 // making first and secind marked + // ac 5->101 + // abc 7->111 + // az 33554433->10000000000000000000000001 + + num |= 1 << (words[i].charAt(j) - 'a'); + System.out.println(words[i].charAt(j)+"->"+num+ "->"+Integer.toBinaryString(num) ); + } + + checker[i] = num; + } + + for (int i = 0; i < words.length; i++) { + for (int j = i + 1; j < words.length; j++) { + // abcd efgd + // 11110000 -> abcd + // 00011110 -> efgd + // and-ing these two might say if even a single char is present in other + if ((checker[i] & checker[j]) == 0) //checking if the two strings have common character + max = Math.max(max, words[i].length() * words[j].length()); + } + } + System.out.println(max); + return max; + } + + + public static void main(String[] args) { + new MaxProductString().maxProduct(new String[]{"abcw", "baz", "foo", "bar", "xtfn", "abcdef"}); + } +} \ No newline at end of file diff --git a/src/practiceproblems/MaxWidthOfBinaryTree.java b/src/practiceproblems/MaxWidthOfBinaryTree.java new file mode 100644 index 0000000..53699eb --- /dev/null +++ b/src/practiceproblems/MaxWidthOfBinaryTree.java @@ -0,0 +1,61 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Queue; + +/** + * Given a binary tree, write a function to get the maximum width of the given tree. + * The width of a tree is the maximum width among all levels. + * The binary tree has the same structure as a full binary tree, but some nodes are null + * + * Input: + + 1 + / \ + 3 2 + / \ + 5 9 + / \ + 6 7 +Output: 8 +The maximum width existing in the fourth level with the length 8 (6,null,null,null,null,null,null,7). + */ +public class MaxWidthOfBinaryTree { + + // Each time a node is traversed, the position of the node(as it is in a full binary tree) is stored in the HashMap. + //If the position of the parent node is 'n', then the left child is '2 * n' and the right child is '2 * n + 1'. + //The width of each level is the last node's position in this level subtracts the first node's position in this level plus 1. + public int widthOfBinaryTree(TreeNode root) { + if(root==null) return 0; + int maxWidth=0; + + Map map= new HashMap<>(); + Queue stack=new LinkedList(); + stack.offer(root); + map.put(root,1); // if we are assigning head as 0 then the fourmula is left=>2*n+1, right=> 2*n+2 + while(!stack.isEmpty()){ + int width= stack.size(); + int start=0; + int end=0; + for(int i=0;i maxDiff) { + maxDiff = arr[i] - minElement; + } + if (arr[i] < minElement) { + minElement = arr[i]; + } + } + return maxDiff; + } + + public static void main(String[] args) { + int arr[] = { 2, 4, 1, 3, 10, 8, 5 }; + System.out.println("Maximum difference is " + maxDiff(arr, arr.length)); + } +} \ No newline at end of file diff --git a/src/practiceproblems/MaximumGap.java b/src/practiceproblems/MaximumGap.java new file mode 100644 index 0000000..dd35b24 --- /dev/null +++ b/src/practiceproblems/MaximumGap.java @@ -0,0 +1,70 @@ +package practiceproblems; + +/** + * Given an unsorted array, find the maximum difference between the successive elements in its sorted form. +Return 0 if the array contains less than 2 elements. +Input: [3,6,9,1] +Output: 3 +Explanation: The sorted form of the array is [1,3,6,9], either + (3,6) or (6,9) has the maximum difference 3. + + +trick is to do in O(N)= > Radix sort + */ +public class MaximumGap { + // The first step is to find the maximum value in nums array, it will + // be the threshold to end while loop. + // Then use the radix sort algorithm to sort based on each digit from Least Significant Bit + // (LSB) to Most Significant Bit (MSB), that's exactly what's showing + // in the link. + // (nums[i] / exp) % 10 is used to get the digit, for each digit, basically the digit itself serves as the index to + // access the count array. Count array stores the index to access aux + // array which stores the numbers after sorting based on the current + // digit. + // Finally, find the maximum gap from sorted array. + // Time and space complexities are both O(n). (Actually time is O(10n) at worst case for Integer.MAX_VALUE 2147483647) + public int maximumGap(int[] nums) { + if (nums == null || nums.length < 2) { + return 0; + } + + // m is the maximal number in nums + int m = nums[0]; + for (int i = 1; i < nums.length; i++) { + m = Math.max(m, nums[i]); + } + + int exp = 1; // 1, 10, 100, 1000 ... + int R = 10; // 10 digits + + int[] aux = new int[nums.length]; + + while (m / exp > 0) { // Go through all digits from LSB to MSB + int[] count = new int[R]; + + for (int i = 0; i < nums.length; i++) { + count[(nums[i] / exp) % 10]++; + } + + for (int i = 1; i < count.length; i++) { + count[i] += count[i - 1]; + } + + for (int i = nums.length - 1; i >= 0; i--) { + aux[--count[(nums[i] / exp) % 10]] = nums[i]; + } + + for (int i = 0; i < nums.length; i++) { + nums[i] = aux[i]; + } + exp *= 10; + } + + int max = 0; + for (int i = 1; i < aux.length; i++) { + max = Math.max(max, aux[i] - aux[i - 1]); + } + + return max; + } +} \ No newline at end of file diff --git a/src/practiceproblems/MaximumProductSubarray.java b/src/practiceproblems/MaximumProductSubarray.java new file mode 100644 index 0000000..9a8c374 --- /dev/null +++ b/src/practiceproblems/MaximumProductSubarray.java @@ -0,0 +1,63 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/maximum-product-subarray/ + */ +public class MaximumProductSubarray { + + // 1, -2, -3, 0, 8, 7, -2 + public static int maxProductSubArray(int[] A) { + + if (A.length == 0) { + return 0; + } + + int maxHerePre = A[0]; + int minHerePre = A[0]; + int maxsofar = A[0]; + + for (int i = 1; i < A.length; i++) { + int maxHere = Math.max(Math.max(maxHerePre * A[i], minHerePre * A[i]), A[i]); + int minHere = Math.min(Math.min(maxHerePre * A[i], minHerePre * A[i]), A[i]); + maxsofar = Math.max(maxHere, maxsofar); + maxHerePre = maxHere; + minHerePre = minHere; + } + return maxsofar; + } + + public static int maxSumSubArray(int[] arr) { + + int max = Integer.MIN_VALUE; + int sum = 0; + + for (int i = 0; i < arr.length; i++) { + sum = sum + arr[i]; + if (sum < 0) { + //get i if you want to get index of subarray + sum = 0; + } + max = Math.max(sum, max); + } + return sum; + } + + public int maxSubArray(int[] nums) { + if(nums==null || nums.length==0) return 0; + + int maxHere=0; + int max=Integer.MIN_VALUE; + for(int i:nums){ + maxHere=Math.max(i,maxHere+i); + max= Math.max(maxHere, max); + } + + return max; + } + + public static void main(String[] args) { + int arr[] = { 1, -2, -3, 0, 8, 7, -2 }; + System.out.println("Maximum Sub array sum is " + maxSumSubArray(arr)); + System.out.println("Maximum Sub array product is " + maxProductSubArray(arr)); + } +} diff --git a/src/practiceproblems/MaximumSubstringWithKDistinctChar.java b/src/practiceproblems/MaximumSubstringWithKDistinctChar.java new file mode 100644 index 0000000..a633f7d --- /dev/null +++ b/src/practiceproblems/MaximumSubstringWithKDistinctChar.java @@ -0,0 +1,85 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.Map; + +/** + * https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/ + *

+ * https://www.lintcode.com/problem/longest-substring-with-at-most-two-distinct-characters/description + */ +public class MaximumSubstringWithKDistinctChar { + + public static void main(String[] args) { + System.out.println(lengthOfLongestSubstringTwoDistinct("aaaaaaaa", 2)); + System.out.println(""); + // System.out.println(lengthOfLongestSubstringKDistinct("eqgkcwGFvjjmxutystqdfhuMblWbylgjxsxgnoh", 2)); + } + + public static int lengthOfLongestSubstringTwoDistinct(String s, int k) { + Map map = new HashMap<>(); + int start = 0; + int end = 0; + int counter = 0; + int length = 0; + int startIndex=0; + while (end < s.length()) { + char c = s.charAt(end); + map.put(c, map.getOrDefault(c, 0) + 1); + if (map.get(c) == 1) { + counter++;//new char + } + end++; + while (counter > k) { + char cTemp = s.charAt(start); + map.put(cTemp, map.get(cTemp) - 1); + if (map.get(cTemp) == 0) { + counter--; + } + start++; + } + if(end - start>length){ + startIndex=start; + length= end-start; + } + + } + + System.out.println(s.substring(startIndex,startIndex+length)); + return length; + } + + // improvised solution + public static int lengthOfLongestSubstringKDistinct(String s, int k) { + if (s == null || s.isEmpty()) { + return 0; + } + if (k == 0) { + return 0; + } + int start = 0; + int maxCount = 0; + int[] arr = new int[26]; + s = s.toLowerCase(); + for (int i = 0; i < s.length(); i++) { + + if (arr[s.charAt(i) - 'a'] == 0) { + k--; + } + + arr[s.charAt(i) - 'a']++; + while (k == -1) { + + arr[s.charAt(start) - 'a']--; + if (arr[s.charAt(start) - 'a'] == 0) { + k++; + } + start++; + } + maxCount = Math.max(maxCount, i - start); + } + return maxCount + 1; + } + + +} diff --git a/src/practiceproblems/MaximumUnsortedSubarray.java b/src/practiceproblems/MaximumUnsortedSubarray.java new file mode 100644 index 0000000..9edf559 --- /dev/null +++ b/src/practiceproblems/MaximumUnsortedSubarray.java @@ -0,0 +1,90 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +//https://leetcode.com/problems/shortest-unsorted-continuous-subarray/ +/** + * Given an integer array, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order, too. + * + * You need to find the shortest such subarray and output its length. + * + * Example 1: + * Input: [2, 6, 4, 8, 10, 9, 15] + * Output: 5 + * Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order. + */ +public class MaximumUnsortedSubarray { + + public static ArrayList subarraySort(final ArrayList A) { + + final ArrayList list = new ArrayList<>(); + int start = -1; + int end = -1; + + // from left + for (int i = 1; i < A.size(); ++i) { + if (A.get(i) < A.get(i - 1)) { + start = i - 1; + break; + } + } + + // fully sorted + if (start == -1) { + list.add(-1); + return list; + } + + // from right + for (int i = A.size() - 2; i >= 0; --i) { + if (A.get(i) > A.get(i + 1)) { + end = i + 1; + break; + } + } + // [1, 3, 2, 0, -1, 7, 10] + // the initial finding gives you 3 and -1 however the original sort array is + // [1, -1, 0, 2, 3, 7, 10], + //The problem here is that the smallest number of our subarray is ‘-1’ + // which dictates that we need to include more numbers from the beginning of the array + // We will have a similar problem + //if the maximum of the subarray is bigger than some elements at the end of the array + // find min and max in the range [start, end] + int min = A.get(start); + int max = A.get(start); + for (int i = start; i <= end; ++i) { + min = Math.min(min, A.get(i)); + max = Math.max(max, A.get(i)); + } + + for (int i = 0; i < start; ++i) { + if (A.get(i) > min) { + start = i; + break; + } + } + + for (int i = A.size() - 1; i >= end + 1; --i) { + if (A.get(i) < max) { + end = i; + break; + } + } + + list.add(start); + list.add(end); + + return list; + } + + public static void main(final String[] args) { + //1, 1, 10, 10, 15, 10, 15, 10,10, 15, 10, 15 + //(1, 3, 2, 4, 5); + //4, 15, 4, 4, 15, 18, 20 + //2, 6, 1, 8, 10, 9, 15 + final List result = subarraySort(new ArrayList<>(Arrays.asList(4, 15, 4, 4, 15, 18, 20))); + result.stream().forEach(System.out::println); + } +} diff --git a/src/practiceproblems/MedianOfKWindow.java b/src/practiceproblems/MedianOfKWindow.java new file mode 100644 index 0000000..aaaa66d --- /dev/null +++ b/src/practiceproblems/MedianOfKWindow.java @@ -0,0 +1,49 @@ +package practiceproblems; + +import java.util.Collections; +import java.util.PriorityQueue; + +public class MedianOfKWindow { + public double[] medianSlidingWindow(int[] nums, int k) { + MedianQueue medianHeap= new MedianQueue(); + + double[] result= new double[nums.length-k+1]; + + int resultIndex=0; + + for( int i=0;i minQueue= new PriorityQueue<>(); + PriorityQueue maxQueue= new PriorityQueue<>(Collections.reverseOrder()); + + public void offer(int x){ + maxQueue.offer(x); + minQueue.offer(maxQueue.poll()); + if(maxQueue.size() minQueue.size() ? maxQueue.peek() : ((long)maxQueue.peek() + minQueue.peek()) * 0.5; + } + public int size(){ + return minQueue.size() + maxQueue.size(); + } + + public boolean remove(int x){ + return minQueue.remove(x) || maxQueue.remove(x); + } + } +} \ No newline at end of file diff --git a/src/practiceproblems/MedianOfRunningIntegers.java b/src/practiceproblems/MedianOfRunningIntegers.java new file mode 100644 index 0000000..2a961d0 --- /dev/null +++ b/src/practiceproblems/MedianOfRunningIntegers.java @@ -0,0 +1,45 @@ +package practiceproblems; + +import java.util.Collections; +import java.util.PriorityQueue; + +/** + * https://leetcode.com/problems/find-median-from-data-stream/ + */ +public class MedianOfRunningIntegers { + + PriorityQueue min = new PriorityQueue<>(); + PriorityQueue max = new PriorityQueue<>(Collections.reverseOrder()); + + // 6,8,1,4,9,2,3,5 + // median is a middle element in sorted array + // in a sorted array if we choose a point the immediate left to that point is maxLeft (max of all left) + // the immediate right to that point is minRight (min of all right) + // to mimic that here the right(max) values are stored in min heap + // the left(min) values are stored in maxheap + public void addNum(int num) { + max.offer(num); + min.offer(max.poll()); + if (max.size() < min.size()) { + max.offer(min.poll()); + } + } + + public double findMedian() { + if (max.size() == min.size()) { + return (max.peek() + min.peek()) / 2.0; + } else { + return max.peek(); + } + } + + public static void main(String[] args) { + MedianOfRunningIntegers median = new MedianOfRunningIntegers(); + int A[] = { 5, 15, 1, 3, 2, 8, 7, 9, 10, 6, 11, 4 }; + for (int num : A) { + median.addNum(num); + System.out.println(median.findMedian()); + } + } + +} diff --git a/src/practiceproblems/MedianOfTwoSortedArrays.java b/src/practiceproblems/MedianOfTwoSortedArrays.java new file mode 100644 index 0000000..250bb64 --- /dev/null +++ b/src/practiceproblems/MedianOfTwoSortedArrays.java @@ -0,0 +1,79 @@ +package practiceproblems; + +/** + * https://github.com/mission-peace/interview/blob/master/src/com/interview/binarysearch/MedianOfTwoSortedArrayOfDifferentLength.java + */ +public class MedianOfTwoSortedArrays { + + public double findMedianSortedArrays(int[] input1, int[] input2) { + //if input1 length is greater than switch them so that input1 is smaller than input2. + if (input1.length > input2.length) { + return findMedianSortedArrays(input2, input1); + } + int x = input1.length; + int y = input2.length; + + // the whole idea is to partition the 2 arrays so that the left side and right side has same number of elements + // let's take example A= 1,3,7 and B= 2,6,8,9,10 + // so if we assume both are combined the median would be at 6(6+7/2= 6.5 to be exact) + + // first take (low + high) / 2 for A it'd be 1 in this example. we partition at 1, [1 ||, 3,7] (1 element on left and 2 on right) + // for B we need to do this, {(x + y + 1) / 2 - partitionX} = (3+5+1/2)-1=3 [2,6,8||,9,10] (3 elements on left and 2 on right) + // add the total left and right elements for both arrays would come to be equal 3+1(left partition) and 2+2(right partition) + + // the reason to add 1 ((x + y + 1) / 2 ) is to account for both odd and even lengths + // for odd length the left half should be greater, the +1 is to adjust for that + + int low = 0; + int high = x; + while (low <= high) { + int partitionX = (low + high) / 2; + int partitionY = (x + y + 1) / 2 - partitionX; + + //if partitionX is 0 it means nothing is there on left side to partition. [|| 1] Use -INF for maxLeftX + //if partitionX is length of input then there is nothing on right side. Use +INF for minRightX + + // to understand it further let's take an edge case A=[2] B=[1,3] + // partitionX=0+1/2 => 0 + // partitionY= 1+2+1/2 - 0 => 2 , the partition would look like this + // A= [-inf || 2] + // B= [2,3 || +inf] + int maxLeftX = (partitionX == 0) ? Integer.MIN_VALUE : input1[partitionX - 1]; + int minRightX = (partitionX == x) ? Integer.MAX_VALUE : input1[partitionX]; + + int maxLeftY = (partitionY == 0) ? Integer.MIN_VALUE : input2[partitionY - 1]; + int minRightY = (partitionY == y) ? Integer.MAX_VALUE : input2[partitionY]; + + // for the example given above, at right partition the elements would be grouped like below + // A=> 1,3 || 7 + // B=> 2,6 || 8,9,10 + // 3<8 and 6<7 so we take max of left and min of right + + if (maxLeftX <= minRightY && maxLeftY <= minRightX) { + //We have partitioned array at correct place + // Now get max of left elements and min of right elements to get the median in case of even length combined array size + // or get max of left for odd length combined array size. + if ((x + y) % 2 == 0) { + return ((double) Math.max(maxLeftX, maxLeftY) + Math.min(minRightX, minRightY)) / 2; + } else { + return Math.max(maxLeftX, maxLeftY); + } + } else if (maxLeftX > minRightY) { //we are too far on right side for partitionX. Go on left side. + high = partitionX - 1; + } else { //we are too far on left side for partitionX. Go on right side. + low = partitionX + 1; + } + } + + //Only we we can come here is if input arrays were not sorted. Throw in that scenario. + throw new IllegalArgumentException(); + } + + public static void main(String[] args) { + int[] x = { 1, 3, 8, 9, 15, 17 }; + int[] y = { 7, 11, 18, 19, 21, 25 }; + // 1,3,7,8,9,11,15,18,19,21,25 + MedianOfTwoSortedArrays mm = new MedianOfTwoSortedArrays(); + System.out.println(mm.findMedianSortedArrays(x, y)); + } +} diff --git a/src/practiceproblems/MeetingRoomsII.java b/src/practiceproblems/MeetingRoomsII.java new file mode 100644 index 0000000..3bba853 --- /dev/null +++ b/src/practiceproblems/MeetingRoomsII.java @@ -0,0 +1,63 @@ +package practiceproblems; + +import java.util.*; + +/** + * https://www.lintcode.com/problem/meeting-rooms-ii/ + */ + +public class MeetingRoomsII { + /** + * @param intervals: an array of meeting time intervals + * + * @return: the minimum number of conference rooms required + */ + // [(0,30),(5,10),(15,20)] + public int minMeetingRooms(List intervals) { + if (intervals == null || intervals.size() == 0) { + return -1; + } + + Collections.sort(intervals, Comparator.comparingInt(a -> a.start)); + + PriorityQueue queue = new PriorityQueue<>(); + queue.offer(intervals.get(0).end); + for (int i = 1; i < intervals.size(); i++) { + Interval temp = intervals.get(i); + if (queue.peek() <= temp.start) { + queue.poll(); + } + queue.offer(temp.end); + } + + return queue.size(); + + } + + // Input: schedule = [[[1,2],[5,6]],[[1,3]],[[4,10]]] + // Output: [[3,4]] + + public List employeeFreeTime(List> schedule) { + PriorityQueue que = new PriorityQueue<>((a, b) -> a.start - b.start); + + for (List list : schedule) { + for (Interval i : list) { + que.add(i); + } + } + + List rt = new ArrayList<>(); + int max = -1; + while (!que.isEmpty()) { + Interval top = que.poll(); + if (max != -1 && top.start > max) { + rt.add(new Interval(max, top.start)); + } + max = Math.max(max, top.end); + } + + return rt; + } + + +} diff --git a/src/practiceproblems/MergeIntervalIntersection.java b/src/practiceproblems/MergeIntervalIntersection.java new file mode 100644 index 0000000..690469a --- /dev/null +++ b/src/practiceproblems/MergeIntervalIntersection.java @@ -0,0 +1,42 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.List; + +/** + * +Given two lists of closed intervals, each list of intervals is pairwise disjoint and in sorted order. +Return the intersection of these two interval lists. + +Input: A = [[0,2],[5,10],[13,23],[24,25]], B = [[1,5],[8,12],[15,24],[25,26]] +Output: [[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]] + */ +public class MergeIntervalIntersection { + + // inorder to find a overlapping part alone between two intervals + // we take + // start = max(a.start, b.start) + // end = min(a.end, b.end) + // That is, the highest start time and the lowest end time will be the overlapping interval. + public int[][] intervalIntersection(int[][] A, int[][] B) { + int i=0; + int j=0; + List result= new ArrayList<>(); + while(i=B[j][0] && A[i][0]<=B[j][1] || + B[j][0]>=A[i][0] && B[j][0]<=A[i][1]){ // this condition checks if there'a ovelapping + //A=>[0,2], B=> [1,5] + result.add(new int[]{Math.max(A[i][0],B[j][0]), Math.min(A[i][1],B[j][1])}); + } + // once added to result move the i or j based on lesser end time + if(A[i][1] a[0] - b[0]); + Arrays.sort(intervals, (i1, i2) -> Integer.compare(i1[0], i2[0]));*/ + Arrays.sort(intervals, Comparator.comparingInt(i -> i[0])); + + List result = new ArrayList<>(); + int[] prevInterval = intervals[0]; + result.add(prevInterval); + for (int[] currInterval : intervals) { + if (currInterval[0] <= prevInterval[1]) // Overlapping intervals, move the end if needed + { + prevInterval[1] = Math.max(prevInterval[1], currInterval[1]); + } else { // Disjoint intervals, add the new interval to the list + prevInterval = currInterval; + result.add(prevInterval); + } + } + return result.toArray(new int[result.size()][]); + } + + public static void main(String[] args) { + // [[1,3],[2,6],[8,10],[15,18]] + int[][] arr = { { 1, 9 }, { 6, 8 }, { 2, 4 }, { 4, 7 } }; + //{ { 1, 3 }, { 2, 4 }, { 5, 7 }, { 6, 8 } }; + //{{1, 9}, {2, 4}, {4, 7}, {6, 8}}; + System.out.println(Arrays.deepToString(merge(arr))); + } +} \ No newline at end of file diff --git a/src/practiceproblems/MergeSortLinkedList.java b/src/practiceproblems/MergeSortLinkedList.java new file mode 100644 index 0000000..c380f29 --- /dev/null +++ b/src/practiceproblems/MergeSortLinkedList.java @@ -0,0 +1,80 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/merge-sort-for-linked-list/ + */ +public class MergeSortLinkedList { + + public static ListNode sortList(ListNode head) { + if (head == null || head.next == null) { + return head; + } + // step 1. cut the list to two halves + ListNode prev = null; + ListNode slow = head; + ListNode fast = head; + // find the mid node + while (fast != null && fast.next != null) { + prev = slow; + slow = slow.next; + fast = fast.next.next; + } + prev.next = null; + // step 2. sort each half + ListNode l1 = sortList(head); + ListNode l2 = sortList(slow); + // step 3. merge l1 and l2 + return merge(l1, l2); + } + + static ListNode merge(ListNode l1, ListNode l2) { + ListNode node = new ListNode(0); + ListNode temp = node; + while (l1 != null && l2 != null) { + if (l1.val < l2.val) { + temp.next = l1; + l1 = l1.next; + } else { + temp.next = l2; + l2 = l2.next; + } + temp = temp.next; + } + if (l1 != null) { + temp.next = l1; + } + if (l2 != null) { + temp.next = l2; + } + return node.next; + } + + public static void main(String[] args) { + ListNode head = new ListNode(1); + head.next = new ListNode(5); + head.next.next = new ListNode(3); + head.next.next.next = new ListNode(2); + head.next.next.next.next = new ListNode(4); + ListNode listNode = sortList(head); + while (listNode != null) { + System.out.println(listNode.val); + listNode = listNode.next; + } + } + +} + +class ListNode { + + ListNode next; + int val; + + public ListNode(int val) { + this.val = val; + } + + @Override + public String toString() { + return "ListNode{val=" + val + '}'; + } +} \ No newline at end of file diff --git a/src/practiceproblems/MergeTwoLinkedList.java b/src/practiceproblems/MergeTwoLinkedList.java new file mode 100644 index 0000000..518b600 --- /dev/null +++ b/src/practiceproblems/MergeTwoLinkedList.java @@ -0,0 +1,46 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/merge-two-sorted-linked-lists/ + */ +public class MergeTwoLinkedList { + + public static ListNode mergeTwoLists(ListNode l1, ListNode l2) { + if (l1 == null) { + return l2; + } else if (l2 == null) { + return l1; + } + ListNode dummy = new ListNode(0); + ListNode curr = dummy; + while (l1 != null && l2 != null) { + if (l1.val <= l2.val) { + curr.next = l1; + l1 = l1.next; + } else { + curr.next = l2; + l2 = l2.next; + } + curr = curr.next; + } + curr.next = l1 == null ? l2 : l1; + return dummy.next; + } + + public static void main(String[] args) { + ListNode l1 = new ListNode(1); + l1.next = new ListNode(2); + l1.next.next = new ListNode(3); + l1.next.next.next = new ListNode(4); + + ListNode l2 = new ListNode(1); + // l2.next = new ListNode(7); + + ListNode head = mergeTwoLists(l1, l2); + + while (head != null) { + System.out.println(head.val); + head = head.next; + } + } +} diff --git a/src/practiceproblems/MinAdjSwapsToMakePalindrome.java b/src/practiceproblems/MinAdjSwapsToMakePalindrome.java new file mode 100644 index 0000000..67f0966 --- /dev/null +++ b/src/practiceproblems/MinAdjSwapsToMakePalindrome.java @@ -0,0 +1,58 @@ +package practiceproblems; + +/** + * https://leetcode.com/discuss/interview-question/351783/ + * https://www.youtube.com/watch?v=zXpYs8j5oI8&ab_channel=Insidecode + */ +public class MinAdjSwapsToMakePalindrome { + + private int getNoOfSwaps(String s) { + if (s == null || s.length() == 0) return -1; + int totalSwaps = 0; + + if (isShuffledPalindrome(s)) { + char[] chars = s.toCharArray(); + int p1 = 0, p2 = chars.length - 1; + + while (p2 > p1) { + if (chars[p1] != chars[p2]) { + int k = p2; + while (k > p1 && chars[k] != chars[p1]) k--; + + if (k == p1) { //When no matching character found + swap(chars, p1, p1 + 1); + totalSwaps++; + + } else { //When Matching character found swap until K reaches p2 position + while (k < p2) { + swap(chars, k, k + 1); + totalSwaps++; + k++; + } + p1++; + p2--; + } + } else { + p1++; + p2--; //When the characters are equal move on + } + } + return totalSwaps; + } else return -1; + } + + private static void swap(char[] chars, int k, int i) { + char temp = chars[k]; + chars[k] = chars[i]; + chars[i] = temp; + } + + private boolean isShuffledPalindrome(String s) { + int[] occurrence = new int[26]; + int oddCount = 0; + + for (int i = 0; i < s.length(); i++) occurrence[s.charAt(i) - 'a']++; + for (int value : occurrence) if (value % 2 != 0) oddCount++; + return oddCount <= 1; + } +} diff --git a/src/practiceproblems/MinCostRopeConnect.java b/src/practiceproblems/MinCostRopeConnect.java new file mode 100644 index 0000000..f23c350 --- /dev/null +++ b/src/practiceproblems/MinCostRopeConnect.java @@ -0,0 +1,34 @@ +package practiceproblems; + +import java.util.PriorityQueue; + +/** + * https://www.geeksforgeeks.org/connect-n-ropes-minimum-cost/ + */ +public class MinCostRopeConnect { + + // 6 + 4 = 10 .. 10 + 3 = 13 .. 13 +2 = 15 + + // 2+3 = 5 .. 5 + 4 = 9 .. 9 + 6 = 15 .. + + public static void main(String[] args) { + int arr[] = { 4, 3, 2, 6 }; + + MinCostRopeConnect rope = new MinCostRopeConnect(); + rope.connectRopes(arr); + } + + private void connectRopes(int[] arr) { + PriorityQueue pq = new PriorityQueue<>(); + for (int i : arr) + pq.add(i); + + while (pq.size() > 1) { + Integer remove = pq.remove(); + Integer remove2 = pq.remove(); + + System.out.println("cost" + (remove + remove2)); + pq.add(remove + remove2); + } + } +} diff --git a/src/practiceproblems/MinStepsToConvertXtoY.java b/src/practiceproblems/MinStepsToConvertXtoY.java new file mode 100644 index 0000000..2fc12d7 --- /dev/null +++ b/src/practiceproblems/MinStepsToConvertXtoY.java @@ -0,0 +1,49 @@ +package practiceproblems; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Set; + +class MinStepsToConvertXtoY { + private static class GFG{ + int val; + int steps; + GFG(int source, int steps){ + this.val=source; + this.steps=steps; + } + } + private static int minOperations(int src, int target) { + + Set visited = new HashSet<>(1000); + LinkedList queue = new LinkedList(); + + GFG node = new GFG(src, 0); + + queue.offer(node); + visited.add(node); + + while (!queue.isEmpty()) { + GFG temp = queue.poll(); + visited.add(temp); + + if (temp.val == target) { + return temp.steps; + } + + int mul = temp.val * 2; + int sub = temp.val - 1; + + // given constraints + if (mul > 0 && mul < 1000) { + GFG nodeMul = new GFG(mul, temp.steps + 1); + queue.offer(nodeMul); + } + if (sub > 0 && sub < 1000) { + GFG nodeSub = new GFG(sub, temp.steps + 1); + queue.offer(nodeSub); + } + } + return -1; + } +} \ No newline at end of file diff --git a/src/practiceproblems/MinTimeRotOranges.java b/src/practiceproblems/MinTimeRotOranges.java new file mode 100644 index 0000000..7e878fe --- /dev/null +++ b/src/practiceproblems/MinTimeRotOranges.java @@ -0,0 +1,102 @@ +package practiceproblems; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * https://github.com/bibhas-abhishek/projects/tree/master/MinTimeRotOranges + * https://www.geeksforgeeks.org/minimum-time-required-so-that-all-oranges-become-rotten/ + */ + +public class MinTimeRotOranges { + + private class Pair { + + private int x; + private int y; + + public Pair(int x, int y) { + this.x = x; + this.y = y; + } + + @Override + public String toString() { + return x + "" + y; + } + + } + + private boolean hasFreshOrange(int[][] grid) { + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 1) { + return true; + } + } + } + return false; + } + + private boolean isDelimiter(Pair p) { + return p.x == -1 && p.y == -1; + } + + private boolean isValidFresh(int row, int col, int[][] grid) { + int maxRow = grid.length; + int maxCol = grid[0].length; + return row >= 0 && row < maxRow && col >= 0 && col < maxCol && grid[row][col] == 1; + } + + private void rotOranges(Queue queue, Pair p, int[][] grid) { + int[] xMoves = { 1, -1, 0, 0 }; + int[] yMoves = { 0, 0, 1, -1 }; + for (int k = 0; k < xMoves.length; k++) { + int x = p.x + xMoves[k]; + int y = p.y + yMoves[k]; + if (isValidFresh(x, y, grid)) { + grid[x][y] = 2; + queue.add(new Pair(x, y)); + } + } + } + + public int findMinTime(int[][] grid) { + int result = 0; + Queue queue = new LinkedList<>(); + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 2) { + queue.add(new Pair(i, j)); + } + } + } + + if (queue.isEmpty()) { + return -1; + } + + queue.add(new Pair(-1, -1)); + while (!queue.isEmpty()) { + Pair p = queue.poll(); + if (!isDelimiter(p)) { + rotOranges(queue, p, grid); + } else if (!queue.isEmpty()) { + queue.add(p); // add back delimiter + result += 1; + } + } + + if (hasFreshOrange(grid)) { + return -1; + } + + return result; + } + + public static void main(String[] args) { + int grid[][] = { { 2, 1, 0, 1, 1 }, { 1, 0, 2, 1, 1 }, { 1, 1, 1, 1, 1 } }; + System.out.println(new MinTimeRotOranges().findMinTime(grid)); + } + +} \ No newline at end of file diff --git a/src/practiceproblems/MinimumBribes.java b/src/practiceproblems/MinimumBribes.java new file mode 100644 index 0000000..2e1c427 --- /dev/null +++ b/src/practiceproblems/MinimumBribes.java @@ -0,0 +1,50 @@ +package practiceproblems; +/** + * https://www.hackerrank.com/challenges/new-year-chaos/problem + * https://www.youtube.com/watch?v=UpmVTEvaXPE + * Any person in the queue can bribe the person directly in front of them to swap positions. + * If two people swap positions, they still wear the same sticker denoting their original place in line. + * One person can bribe at most two other persons. + * That is to say, if n = 8, and Person 5 bribes Person 4, the queue will look like this: 1,2,3,5,4,6,7,8. + * Fascinated by this chaotic queue, you decide you must know the minimum number of bribes that took place to get the queue into its current state! + * + * No person can bribe more than 2 persons if yes then print chaotic + * Input: 2 1 5 3 4 + * Output: 3 + * + * Input: 2 5 1 3 4 + * Output: Too chaotic + */ +public class MinimumBribes { + // input is 2 1 5 3 4, + // when index is at 2(val=>5) we see how many elements lesser than 5 is there + // if the value is greater that 2 we print too chaotic + // else we add it to result + void minimumBribes(int[] q) { + int bribes=0; + for(int i = q.length-1; i >= 0; i--) { + + if(i-1>=0 && q[i-1]==i+1){ + q[i-1]=q[i]; + q[i]=i+1; + bribes+=1; + } else if(i-2>=0 && q[i-2]==i+2){ + //2,1,5,3,4 we need to swap 2 elements to restore the array + q[i-2]=q[i-1]; + q[i-1]=q[i]; + q[i]=i+1; + bribes+=2; + }else{ + System.out.println("Too Chaotic"); + return; + } + } + System.out.println(bribes); + } + + public static void main(String[] args) { + // inputs 5,1,2,3,7,8,6,4 => too chaotic + // 1,2,5,3,7,8,6,4 => 7 + new MinimumBribes().minimumBribes(new int[]{2,1,5,3,4}); + } +} \ No newline at end of file diff --git a/src/practiceproblems/MinimumDistanceBetweenTwoNumbers.java b/src/practiceproblems/MinimumDistanceBetweenTwoNumbers.java new file mode 100644 index 0000000..d99a887 --- /dev/null +++ b/src/practiceproblems/MinimumDistanceBetweenTwoNumbers.java @@ -0,0 +1,52 @@ +package practiceproblems; + + +/* +https://www.geeksforgeeks.org/find-the-minimum-distance-between-two-numbers/ + +Given an unsorted array arr[] and two numbers x and y, find the minimum distance between x and y in arr[]. +The array might also contain duplicates. +You may assume that both x and y are different and present in arr[]. + +Input: arr[] = {2, 5, 3, 5, 4, 4, 2, 3}, +x = 3, y = 2 +Output: Minimum distance between 3 +and 2 is 1. +Explanation:3 is at index 7 and 2 is at +index 6, so the distance is 1 +*/ + + +class MinimumDistanceBetweenTwoNumbers { + + int minDist(int arr[], int n, int x, int y) { + Integer xIndex = null; + Integer yIndex = null; + int minDist = Integer.MAX_VALUE; + + for (int i = 0; i < n; i++) { + if (arr[i] == x) { + xIndex = i; + } + if (arr[i] == y) { + yIndex = i; + } + + if (xIndex != null && yIndex != null) { + minDist = Math.min(minDist, Math.abs(xIndex - yIndex)); + } + } + return minDist == Integer.MAX_VALUE ? -1 : minDist; + } + + public static void main(String[] args) { + MinimumDistanceBetweenTwoNumbers min = new MinimumDistanceBetweenTwoNumbers(); + int arr[] = {3, 5, 4, 2, 6, 5, 6, 6, 5, 4, 8, 3}; + int arr1[] = { 3, 5, 4, 3, 1, 2, 4, 6, 5, 6, 6, 5, 4, 8, 3 }; + int n = arr.length; + int x = 3; + int y = 6; + + System.out.println("Minimum distance between " + x + " and " + y + " is " + min.minDist(arr, n, x, y)); + } +} diff --git a/src/practiceproblems/MinimumIndexDistanceOfMaximumNumbers.java b/src/practiceproblems/MinimumIndexDistanceOfMaximumNumbers.java new file mode 100644 index 0000000..1c9ef2e --- /dev/null +++ b/src/practiceproblems/MinimumIndexDistanceOfMaximumNumbers.java @@ -0,0 +1,31 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/minimum-distance-between-two-occurrences-of-maximum/ + */ +class MinimumIndexDistanceOfMaximumNumbers { + + static int minDistance(int arr[], int n) { + int maximumElement = arr[0]; + int minDist = n; + int index = 0; + + for (int i = 1; i < n; i++) { + if (maximumElement == arr[i]) { + minDist = Math.min(minDist, (i - index)); + index = i; + } else if (maximumElement < arr[i]) { + maximumElement = arr[i]; + minDist = n; + index = i; + } + } + return minDist - 1; + } + + public static void main(String[] args) { + int arr[] = { 6, 3, 1, 3, 6, 5, 4, 1 }; + int n = arr.length; + System.out.print("Minimum distance = " + minDistance(arr, n)); + } +} \ No newline at end of file diff --git a/src/practiceproblems/MinimumPathSum.java b/src/practiceproblems/MinimumPathSum.java new file mode 100644 index 0000000..825e208 --- /dev/null +++ b/src/practiceproblems/MinimumPathSum.java @@ -0,0 +1,40 @@ +package practiceproblems; + +class MinPathSum { + public int minPathSum(int[][] grid) { + if (grid == null || grid.length == 0) + return 0; + int dp[][] = new int[grid.length][grid[0].length]; + return getMinPathSum(0, 0, grid, dp); + } + + public int getMinPathSum(int i, int j, int[][] grid, int[][] dp) { + if (i == grid.length - 1 && j == grid[0].length - 1) + return grid[i][j]; + else if (i > grid.length - 1 || j > grid[0].length - 1) + return Integer.MAX_VALUE; + else { + if (dp[i][j] != 0) + return dp[i][j]; + dp[i][j] = grid[i][j] + Math.min(getMinPathSum(i + 1, j, grid, dp), getMinPathSum(i, j + 1, grid, dp)); + } + return dp[i][j]; + } + + public int minPathSum1(int[][] grid) { + + for(int i=1;i stack; + Integer minEle; + + MyStack() { + stack = new Stack<>(); + } + + void getMin() { + if (stack.isEmpty()) { + System.out.println("Stack is empty"); + } else { + System.out.println("Minimum Element in the " + " stack is: " + minEle); + } + } + + void peek() { + if (stack.isEmpty()) { + System.out.println("Stack is empty "); + return; + } + + Integer t = stack.peek(); + System.out.print("Top Most Element is: "); + + if (t < minEle) { + System.out.println(minEle); + } else { + System.out.println(t); + } + } + + void pop() { + if (stack.isEmpty()) { + System.out.println("Stack is empty"); + return; + } + + System.out.print("Top Most Element Removed: "); + Integer t = stack.pop(); + + if (t < minEle) { + System.out.println(minEle); + minEle = 2 * minEle - t; + } else { + System.out.println(t); + } + } + + void push(Integer x) { + if (stack.isEmpty()) { + minEle = x; + stack.push(x); + System.out.println("Number Inserted: " + x); + return; + } + + if (x < minEle) { + // x-minEle<0 + // x-minEle+x<0+x + // 2x-minEle + * https://www.techiedelight.com/chess-knight-problem-find-shortest-path-source-destination/ + */ +class MinimumStepsKnight { + + static class Cell { + int x; + int y; + int steps; + + public Cell(int x, int y, int steps) { + this.x = x; + this.y = y; + this.steps = steps; + } + + } + + // Utility method returns true if (x, y) lies + // inside Board + static boolean isInside(int x, int y, int N) { + if (x >= 1 && x <= N && y >= 1 && y <= N) { + return true; + } + return false; + } + + // Method returns minimum step + // to reach target position + static int minStepToReachTarget(int knightPos[], int targetPos[], int N) { + // x and y direction, where a knight can move + int dx[] = { -2, -1, 1, 2, -2, -1, 1, 2 }; + int dy[] = { -1, -2, -2, -1, 1, 2, 2, 1 }; + + // queue for storing states of knight in board + Queue q = new LinkedList<>(); + + // push starting position of knight with 0 distance + q.add(new Cell(knightPos[0], knightPos[1], 0)); + + Cell cell; + int x, y; + boolean visit[][] = new boolean[N + 1][N + 1]; + + // make all cell unvisited + for (int i = 1; i <= N; i++) + for (int j = 1; j <= N; j++) + visit[i][j] = false; + + // visit starting state + visit[knightPos[0]][knightPos[1]] = true; + + // loop untill we have one element in queue + while (!q.isEmpty()) { + cell = q.remove(); + + // if current cell is equal to target cell, + // return its distance + if (cell.x == targetPos[0] && cell.y == targetPos[1]) { + return cell.steps; + } + + // loop for all reachable states + for (int i = 0; i < 8; i++) { + x = cell.x + dx[i]; + y = cell.y + dy[i]; + + // If reachable state is not yet visited and + // inside board, push that state into queue + if (isInside(x, y, N) && !visit[x][y]) { + visit[x][y] = true; + q.add(new Cell(x, y, cell.steps + 1)); + } + } + } + return Integer.MAX_VALUE; + } + + public static void main(String[] args) { + int N = 30; + int[] knightPos = { 1, 1 }; + int[] targetPos = { 30, 30 }; + System.out.println(minStepToReachTarget(knightPos, targetPos, N)); + } +} \ No newline at end of file diff --git a/src/practiceproblems/MinimumSwapSortArray.java b/src/practiceproblems/MinimumSwapSortArray.java new file mode 100644 index 0000000..d3e5e88 --- /dev/null +++ b/src/practiceproblems/MinimumSwapSortArray.java @@ -0,0 +1,59 @@ +package practiceproblems; + +import java.util.*; + + +/** + * https://www.geeksforgeeks.org/minimum-number-swaps-required-sort-array/ + */ +public class MinimumSwapSortArray { + // Return the minimum number + // of swaps required to sort the array + public int minSwaps(int[] arr, int N) { + + int ans = 0; + int[] temp = Arrays.copyOfRange(arr, 0, N); + + // Hashmap which stores the + // indexes of the input array + Map h + = new HashMap<>(); + + Arrays.sort(temp); + for (int i = 0; i < N; i++) { + h.put(arr[i], i); + } + for (int i = 0; i < N; i++) { + + // This is checking whether + // the current element is + // at the right place or not + if (arr[i] != temp[i]) { + ans++; + int init = arr[i]; + + // If not, swap this element + // with the index of the + // element which should come here + swap(arr, i, h.get(temp[i])); + + // Update the indexes in + // the hashmap accordingly + h.put(init, h.get(temp[i])); + h.put(temp[i], i); + } + } + return ans; + } + + public void swap(int[] arr, int i, int j) { + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + + public static void main(String[] args) { + //nums = {10, 19, 6, 3, 5} + //nums = {2, 8, 5, 4} + } +} \ No newline at end of file diff --git a/src/practiceproblems/MinimumWindowSubsequence.java b/src/practiceproblems/MinimumWindowSubsequence.java new file mode 100644 index 0000000..cf40447 --- /dev/null +++ b/src/practiceproblems/MinimumWindowSubsequence.java @@ -0,0 +1,80 @@ +package practiceproblems; + +/** + * Input: + * S = "abcdebdde", T = "bde" + * Output: "bcde" + * Explanation: + * "bcde" is the answer because it occurs before "bdde" which has the same length. + * "deb" is not a smaller window because the elements of T in the window must occur in order. + */ +// unresolved +public class MinimumWindowSubsequence { + public String minWindow(String S, String T) { + if (S.length() == 0 || T.length() == 0) { + return ""; + } + + /** + * we can conduct two steps by using two pointers for this probelm: + * 1. check feasibility from left to right + * 2. check optimization from right to left + * we can traverse from left to right, find a possible candidate until reach the first ending character of T + * eg: for the string s = abcdebdde and t = bde, we should traverse s string until we find first e, + * i.e. abcde, then traverse back from current "e" to find if we have other combination of bde with smaller + * length. + * @param right: fast pointer that always points the last character of T in S + * @param left: slow pointer that used to traverse back when right pointer find the last character of T in S + * @param tIndex: third pointer used to scan string T + * @param minLen: current minimum length of subsequence + * */ + int right = 0; + int minLen = Integer.MAX_VALUE; + String result = ""; + + while (right < S.length()) { + int tIndex = 0; + // use fast pointer to find the last character of T in S + while (right < S.length()) { + if (S.charAt(right) == T.charAt(tIndex)) { + tIndex++; + } + if (tIndex == T.length()) { + break; + } + right++; + } + + // if right pointer is over than boundary + if (right == S.length()) { + break; + } + + // use another slow pointer to traverse from right to left until find first character of T in S + int left = right; + tIndex = T.length() - 1; + while (left >= 0) { + if (S.charAt(left) == T.charAt(tIndex)) { + tIndex--; + } + if (tIndex < 0) { + break; + } + left--; + } + // if we found another subsequence with smaller length, update result + if (right - left + 1 < minLen) { + minLen = right - left + 1; + result = S.substring(left, right + 1); + } + // WARNING: we have to move right pointer to the next position of left pointer, NOT the next position + // of right pointer + right = left + 1; + } + return result; + } + + public static void main(String[] args) { + System.out.printf(new MinimumWindowSubsequence().minWindow("abcdebdde","bcde")); + } +} diff --git a/src/practiceproblems/MinimumWindowSubstring.java b/src/practiceproblems/MinimumWindowSubstring.java new file mode 100644 index 0000000..67a0ae5 --- /dev/null +++ b/src/practiceproblems/MinimumWindowSubstring.java @@ -0,0 +1,62 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.Map; + +/** + * https://leetcode.com/problems/minimum-window-substring/ + */ +class MinimumWindowSubstring { + + public static void main(String[] args) { + System.out.println(minWindow("AADOBECODEBANC", "ABC")); + System.out.println(minWindow("abcdebdde", "bde")); + } + + public static String minWindow(String s, String t) { + if (t.length() > s.length()) { + return ""; + } + Map map = new HashMap<>(); + for (char c : t.toCharArray()) { + map.put(c, map.getOrDefault(c, 0) + 1); + } + + int counter = map.size(); + + int begin = 0, end = 0; + int head = 0; + int len = Integer.MAX_VALUE; + + while (end < s.length()) { + char c = s.charAt(end); + if (map.containsKey(c)) { + map.put(c, map.get(c) - 1); + if (map.get(c) == 0) { + counter--; + } + } + end++; + + while (counter == 0) { + char tempc = s.charAt(begin); + if (map.containsKey(tempc)) { + map.put(tempc, map.get(tempc) + 1); + if (map.get(tempc) > 0) { + counter++; + } + } + if (end - begin < len) { + len = end - begin; + head = begin; + } + begin++; + } + + } + if (len == Integer.MAX_VALUE) { + return ""; + } + return s.substring(head, head + len); + } + } diff --git a/src/practiceproblems/MirrorBinaryTree.java b/src/practiceproblems/MirrorBinaryTree.java new file mode 100644 index 0000000..b4c9e68 --- /dev/null +++ b/src/practiceproblems/MirrorBinaryTree.java @@ -0,0 +1,72 @@ +package practiceproblems; + +import java.util.*; + +/** + * https://www.geeksforgeeks.org/write-an-efficient-c-function-to-convert-a-tree-into-its-mirror-tree/ + *

+ * Iterative Java program to convert a Binary Tree to its mirror + */ +class MirrorBinaryTree { + + static class Node { + int data; + Node left; + Node right; + } + + static Node newNode(int data) { + Node node = new Node(); + node.data = data; + node.left = node.right = null; + return (node); + } + + static void mirror(Node root) { + if (root == null) { + return; + } + + Queue q = new LinkedList<>(); + q.add(root); + + while (q.size() > 0) { + Node curr = q.poll(); + Node temp = curr.left; + curr.left = curr.right; + curr.right = temp; + + if (curr.left != null) { + q.add(curr.left); + } + if (curr.right != null) { + q.add(curr.right); + } + } + } + + static void inOrder(Node node) { + if (node == null) { + return; + } + inOrder(node.left); + System.out.print(node.data + " "); + inOrder(node.right); + } + + public static void main(String args[]) { + Node root = newNode(1); + root.left = newNode(2); + root.right = newNode(3); + root.left.left = newNode(4); + root.left.right = newNode(5); + + System.out.print("\n Inorder traversal of the" + " coned tree is \n"); + inOrder(root); + + mirror(root); + + System.out.print("\n Inorder traversal of the " + "mirror tree is \n"); + inOrder(root); + } +} diff --git a/src/practiceproblems/MobileKeyPadCombinations.java b/src/practiceproblems/MobileKeyPadCombinations.java new file mode 100644 index 0000000..91d075b --- /dev/null +++ b/src/practiceproblems/MobileKeyPadCombinations.java @@ -0,0 +1,59 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * https://www.geeksforgeeks.org/find-possible-words-phone-digits/ + */ +public class MobileKeyPadCombinations { + + public List letterCombinations(String digits) { + List result = new ArrayList<>(); + if (digits == null || digits.length() == 0) { + return result; + } + + String[] keypad = { "--", "00", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; + + generateCombinations(digits, keypad, digits.length(), 0, new StringBuilder(), result); + return result; + } + + public void generateCombinations(String digits, String[] keypad, int len, int startIndex, StringBuilder sb, + List result) { + if (startIndex == len) { + result.add(sb.toString()); + return; + } + + for (char ch : keypad[digits.charAt(startIndex) - '0'].toCharArray()) { + sb.append(ch); + generateCombinations(digits, keypad, len, startIndex + 1, sb, result); + sb.deleteCharAt(sb.length() - 1); + } + } + + public static void main(String[] args) { + new MobileKeyPadCombinations().letterCombinations("23").stream().forEach(System.out::println); + } + + public List letterCombinationsIterative(String digits) { + LinkedList ans = new LinkedList<>(); + if (digits.isEmpty()) { + return ans; + } + String[] mapping = { "0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; + ans.add(""); + for (int i = 0; i < digits.length(); i++) { + int x = Character.getNumericValue(digits.charAt(i)); + while (ans.peek().length() == i) { + String t = ans.remove(); + for (char s : mapping[x].toCharArray()) + ans.add(t + s); + } + } + return ans; + } +} \ No newline at end of file diff --git a/src/practiceproblems/MoveZeroes.java b/src/practiceproblems/MoveZeroes.java new file mode 100644 index 0000000..b347165 --- /dev/null +++ b/src/practiceproblems/MoveZeroes.java @@ -0,0 +1,34 @@ +package practiceproblems; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/move-zeroes/ + * [[4,2,4,0,0,3,0,5,1,0]] + */ +class MoveZeroes { + + public static void main(String[] args) { + MoveZeroes mz = new MoveZeroes(); + int[] arr = { 0, 1, 0, 3, 12 }; + mz.moveZeroes(arr); + System.out.println(Arrays.toString(arr)); + } + + public void moveZeroes(int[] nums) { + if (nums == null || nums.length == 0) { + return; + } + + int insertPos = 0; + for (int num : nums) { + if (num != 0) { + nums[insertPos++] = num; + } + } + + while (insertPos < nums.length) { + nums[insertPos++] = 0; + } + } +} \ No newline at end of file diff --git a/src/practiceproblems/NQueens.java b/src/practiceproblems/NQueens.java new file mode 100644 index 0000000..3a192ad --- /dev/null +++ b/src/practiceproblems/NQueens.java @@ -0,0 +1,90 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * https://leetcode.com/problems/n-queens/ + * + * Input: 4 + * Output: [ + * [".Q..", // Solution 1 + * "...Q", + * "Q...", + * "..Q."], + * + * ["..Q.", // Solution 2 + * "Q...", + * "...Q", + * ".Q.."] + * ] + * Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above. + */ +public class NQueens { + + public List> solveNQueens(int n) { + if(n==0) return Collections.emptyList(); + + List> result= new ArrayList<>(); + char[][] board= new char[n][n]; + for(int i=0;i> result) { + + if(row==board.length){ + result.add(construct(board)); + return; + } + for(int i=0;i= 0 && j < chess.length; i--, j++) { + if (chess[i][j] == 'Q') { + return false; + } + } + //check 135 + for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) { + if (chess[i][j] == 'Q') { + return false; + } + } + return true; + } + + private List construct(char[][] chess) { + List path = new ArrayList<>(); + for (int i = 0; i < chess.length; i++) { + path.add(new String(chess[i])); + } + return path; + } + +} \ No newline at end of file diff --git a/src/practiceproblems/NewRoadsMST.java b/src/practiceproblems/NewRoadsMST.java new file mode 100644 index 0000000..fb048e6 --- /dev/null +++ b/src/practiceproblems/NewRoadsMST.java @@ -0,0 +1,86 @@ +package practiceproblems; + +import java.util.Arrays; +import java.util.PriorityQueue; +import java.util.Queue; + +/** + * Given an undirected graph with n nodes labeled 1..n. Some of the nodes are already connected. + * The i-th edge connects nodes edges[i][0] and edges[i][1] together. Your task is to augment this set of edges with additional edges to connect all the nodes. + * Find the minimum cost to add new edges between the nodes such that all the nodes are accessible from each other. + * Input: n = 6, edges = [[1, 4], [4, 5], [2, 3]], newEdges = [[1, 2, 5], [1, 3, 10], [1, 6, 2], [5, 6, 5]] + * Output: 7 + * Explanation: + * There are 3 connected components [1, 4, 5], [2, 3] and [6]. + * We can connect these components into a single component by connecting node 1 to node 2 and node 1 to node 6 at a minimum cost of 5 + 2 = 7. + */ +public class NewRoadsMST { + public static void main(String[] args) { + int n = 6; + int[][] edges = {{1, 4}, {4, 5}, {2, 3}}; + int[][] newEdges = {{1, 2, 5}, {1, 3, 10}, {1, 6, 2}, {5, 6, 5}}; + System.out.println(minCost(n, edges, newEdges)); + } + + public static int minCost(int n, int[][] edges, int[][] newEdges) { + UF uf = new UF(n + 1); // + 1 because nodes are 1-based + for (int[] edge : edges) { + uf.union(edge[0], edge[1]); + } + + Queue pq = new PriorityQueue<>(newEdges.length, (e1, e2) -> Integer.compare(e1[2], e2[2])); + pq.addAll(Arrays.asList(newEdges)); + + int totalCost = 0; + // 2 because nodes are 1-based and we have 1 unused component at index 0 + while (!pq.isEmpty() && uf.count != 2) { + int[] edge = pq.poll(); + if (!uf.connected(edge[0], edge[1])) { + uf.union(edge[0], edge[1]); + totalCost += edge[2]; + } + } + return totalCost; + } +} + +class UF { + private int[] parent; // parent[i] = parent of i + private byte[] rank; // rank[i] = rank of subtree rooted at i (never more than 31) + public int count; // number of connected components + + public UF(int n) { + if (n < 0) throw new IllegalArgumentException(); + parent = new int[n]; + rank = new byte[n]; + for (int i = 0; i < n; i++) { + parent[i] = i; + } + count = n; + } + + public int find(int p) { + while (p != parent[p]) { + parent[p] = parent[parent[p]]; + p = parent[p]; + } + return p; + } + + public void union(int p, int q) { + int pr = find(p); + int qr = find(q); + if (pr == qr) return; + if (rank[pr] < rank[qr]) { + parent[pr] = qr; + } else { + parent[qr] = pr; + if (rank[pr] == rank[qr]) rank[pr]++; + } + count--; + } + + public boolean connected(int p, int q) { + return find(p) == find(q); + } +} diff --git a/src/practiceproblems/NextGreaterElement.java b/src/practiceproblems/NextGreaterElement.java new file mode 100644 index 0000000..7c422bb --- /dev/null +++ b/src/practiceproblems/NextGreaterElement.java @@ -0,0 +1,90 @@ +package practiceproblems; + +import java.util.*; + +/** + * https://www.geeksforgeeks.org/next-greater-element/ + *

+ * https://www.geeksforgeeks.org/find-next-greater-number-set-digits/ + */ +class NextGreaterElement { + + static int arr[] = { 1,3,4,2 }; + + // 9,1,2,3,4,5,6,7 + public static void printNGE() { + Stack s = new Stack<>(); + int[] nge = new int[arr.length]; + + for (int i = arr.length - 1; i >= 0; i--) { + + while (!s.empty() && s.peek() <= arr[i]) { + s.pop(); + } + nge[i] = s.empty() ? -1 : s.peek(); + s.push(arr[i]); + + } + for (int i = 0; i < arr.length; i++) + System.out.println(arr[i] + " --> " + nge[i]); + + } + +// Input: nums1 = [4,1,2], nums2 = [1,3,4,2]. +// Output: [-1,3,-1] +// Explanation: +// For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1. +// For number 1 in the first array, the next greater number for it in the second array is 3. +// For number 2 in the first array, there is no next greater number for it in the second array, so output -1. + public int[] nextGreaterElement(int[] findNums, int[] nums) { + int[] ret = new int[findNums.length]; + ArrayDeque stack = new ArrayDeque<>(); + HashMap map = new HashMap<>(); + for(int i = nums.length - 1; i >= 0; i--) { + while(!stack.isEmpty() && stack.peek() <= nums[i]) { + stack.pop(); + } + if(stack.isEmpty()) map.put(nums[i], -1); + else map.put(nums[i], stack.peek()); + stack.push(nums[i]); + } + for(int i = 0; i < findNums.length; i++) { + ret[i] = map.get(findNums[i]); + } + return ret; + } + +// Input: [1,2,1] +// Output: [2,-1,2] +// Explanation: The first 1's next greater number is 2; +// The number 2 can't find next greater number; +// The second 1's next greater number needs to search circularly, which is also 2. + public static int[] nextGreaterElementCircular(int[] nums){ + if(nums==null || nums.length==0) return new int[0]; + int[] result= new int[nums.length]; + int n= nums.length; + Arrays.fill(result, -1); + Deque deque= new ArrayDeque<>(); + // to mimic the circular array we iterate for 2*n because input [1,2,1] will be like [1,2,1,1,2,1] + // and we take mod of 'n' to update the correct index + for (int i = 2 * nums.length - 1; i >= 0; --i) { + + while (!deque.isEmpty() && nums[deque.peek()] <= nums[i % nums.length]) { + deque.pop(); + } + // The stack is either empty, when no "greater element" is found to the right of nums[i], + // or contains the next greater element of nums[i] at the top. + result[i % nums.length] = deque.isEmpty() ? -1 : nums[deque.peek()]; + + // Push i into stack, so that nums[i-1] will compare with nums[i] first, before falling back to + // the next greater element of nums[i] + deque.push(i % nums.length); + } + + return result; + } + + public static void main(String[] args) { + printNGE(); + } +} diff --git a/src/practiceproblems/NextGreaterNumber.java b/src/practiceproblems/NextGreaterNumber.java new file mode 100644 index 0000000..b3de1d8 --- /dev/null +++ b/src/practiceproblems/NextGreaterNumber.java @@ -0,0 +1,74 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/find-next-greater-number-set-digits/ + *

+ * https://www.ideserve.co.in/learn/next-greater-number-using-same-digits + */ +public class NextGreaterNumber { + + // If all digits sorted in descending order, then output is always “Not Possible”. For example, 4321. + // If all digits are sorted in ascending order, then we need to swap last two digits. For example, 1234. + // For other cases, we need to process the number from rightmost side + //(why? because we need to find the smallest of all greater numbers) + + // Traverse the given number from rightmost digit, + //keep traversing till you find a digit which is smaller than the previously traversed digit. + //For example, if the input number is “534976”, we stop at 4 because 4 is smaller than next digit 9. + // If we do not find such a digit, then output is “Not Possible”. + // II) Now search the right side of above found digit ‘d’ for the smallest digit greater than ‘d’. + // For “534976″, the right side of 4 contains “976”. The smallest digit greater than 4 is 6. + // III) Swap the above found two digits, we get 536974 in above example. + // IV) Now sort all digits from position next to ‘d’ to the end of number. + //The number that we get after sorting is the output. + //For above example, we sort digits in bold 536974. We get “536479” which is the next greater number for input 534976. + public int nextGreaterElement(int n) { + + char[] arr = String.valueOf(n).toCharArray(); + + int i = arr.length - 2; + // I) Start from the right most digit and + // find the first digit that is + // smaller than the digit next to it. + while (i >= 0 && arr[i] >= arr[i + 1]) + i--; + + // If no such digit is found, its the edge case 1. + if (i < 0) return -1; + + // II) Find the smallest digit on right side of (i)'th + // digit that is greater than number[i] + int j = arr.length - 1; + while (arr[j] <= arr[i]) + j--; + + swap(arr, i, j); + reverse(arr, i + 1, arr.length - 1); + + try { + return Integer.valueOf(String.valueOf(arr)); + } catch (NumberFormatException e) { + return -1; + } +} + +static void swap(char[] arr, int i, int j) { + arr[i] ^= arr[j]; + arr[j] ^= arr[i]; + arr[i] ^= arr[j]; +} + +static void reverse(char[] arr, int i, int j) { + int l = i, h = j; + while (l < h) + swap(arr, l++, h--); +} + + + public static void main(String[] args) { + NextGreaterNumber solution = new NextGreaterNumber(); + + System.out.println("Next greater number is: "+solution.nextGreaterElement(6938652)); + + } +} diff --git a/src/practiceproblems/NextLargestList.java b/src/practiceproblems/NextLargestList.java new file mode 100644 index 0000000..9e639ef --- /dev/null +++ b/src/practiceproblems/NextLargestList.java @@ -0,0 +1,58 @@ +package practiceproblems; + +import java.util.Stack; + +/** + * https://leetcode.com/problems/next-greater-node-in-linked-list/ + */ +class NextLargestList { + + public int[] nextLargerNodes(ListNode head) { + + if (head == null) { + return new int[0]; + } + int size = getSize(head); + int[] result = new int[size]; + head = reverse(head); + Stack stack = new Stack<>(); + stack.push(head.val); + head = head.next; + int i = size - 2; + result[size - 1] = 0; + while (head != null) { + + while (!stack.isEmpty() && stack.peek() <= head.val) { + stack.pop(); + } + result[i] = stack.isEmpty() ? 0 : stack.peek(); + stack.push(head.val); + head = head.next; + i--; + } + + return result; + } + + public int getSize(ListNode head) { + int size = 0; + ListNode root = head; + while (root != null) { + root = root.next; + size++; + } + return size; + } + + public ListNode reverse(ListNode head) { + ListNode root = head; + ListNode prev = null; + while (root != null) { + ListNode next = root.next; + root.next = prev; + prev = root; + root = next; + } + return prev; + } +} \ No newline at end of file diff --git a/src/practiceproblems/Node.java b/src/practiceproblems/Node.java new file mode 100644 index 0000000..c79b622 --- /dev/null +++ b/src/practiceproblems/Node.java @@ -0,0 +1,82 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/remove-bst-keys-outside-the-given-range/ + */ +class RemoveBSTGivenOutsideRange { + + private static BSTNode removeOutsideRange(BSTNode root, int min, int max) { + if (root == null) { + return null; + } + + root.left = removeOutsideRange(root.left, min, max); + root.right = removeOutsideRange(root.right, min, max); + + if (root.data < min) { + BSTNode rchild = root.right; + root = null; + return rchild; + } + + if (root.data > max) { + BSTNode lchild = root.left; + root = null; + return lchild; + } + return root; + } + + public static BSTNode newNode(int num) { + BSTNode temp = new BSTNode(); + temp.data = num; + temp.left = null; + temp.right = null; + return temp; + } + + public static BSTNode insert(BSTNode root, int data) { + if (root == null) { + return newNode(data); + } + if (root.data > data) { + root.left = insert(root.left, data); + } else { + root.right = insert(root.right, data); + } + return root; + } + + private static void inorderTraversal(BSTNode root) { + if (root != null) { + inorderTraversal(root.left); + System.out.print(root.data + " "); + inorderTraversal(root.right); + } + } + + public static void main(String[] args) { + BSTNode root = null; + root = insert(root, 6); + root = insert(root, -13); + root = insert(root, 14); + root = insert(root, -8); + root = insert(root, 15); + root = insert(root, 13); + root = insert(root, 7); + + System.out.print("Inorder Traversal of " + "the given tree is: "); + inorderTraversal(root); + + root = removeOutsideRange(root, -10, 13); + + System.out.print("\nInorder traversal of " + "the modified tree: "); + inorderTraversal(root); + } +} + +class BSTNode { + int data; + BSTNode left; + BSTNode right; +} diff --git a/src/practiceproblems/NonDecreasingArray.java b/src/practiceproblems/NonDecreasingArray.java new file mode 100644 index 0000000..24ee76c --- /dev/null +++ b/src/practiceproblems/NonDecreasingArray.java @@ -0,0 +1,31 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/non-decreasing-array/description/ + */ +class NonDecreasingArray { + + public boolean checkPossibility(int[] nums) { + + int count = 0; + for (int i = 1; i < nums.length && count <= 1; i++) { + if (nums[i - 1] > nums[i]) { + count++; + if ((i - 2 < 0) || nums[i - 2] <= nums[i]) { + nums[i - 1] = nums[i]; + } else { + nums[i] = nums[i - 1]; + } + } + } + return count <= 1; + } + + public static void main(String[] args) { + // 1,4,2,3 + // //3,4,2,3 + int[] nums = { 7, 8, 2, 3 }; + NonDecreasingArray nda = new NonDecreasingArray(); + System.out.println(nda.checkPossibility(nums)); + } +} diff --git a/src/practiceproblems/NumberOfBallons.java b/src/practiceproblems/NumberOfBallons.java new file mode 100644 index 0000000..4e1be80 --- /dev/null +++ b/src/practiceproblems/NumberOfBallons.java @@ -0,0 +1,24 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/maximum-number-of-balloons/discuss/382401/WithComments-StraightForward-Java-Simple-count-of-chars + */ +public class NumberOfBallons { + + public static int maxNumberOfBalloons(String text) { + int[] chars = new int[26]; //count all letters + for (char c : text.toCharArray()) { + chars[c - 'a']++; + } + int min = chars[1];//for b + min = Math.min(min, chars[0]);//for a + min = Math.min(min, chars[11] / 2);// for l /2 + min = Math.min(min, chars[14] / 2);//similarly for o/2 + min = Math.min(min, chars[13]);//for n + return min; + } + + public static void main(String[] args) { + maxNumberOfBalloons("llonbioan"); + } +} diff --git a/src/practiceproblems/NutsAndBoltsMatch.java b/src/practiceproblems/NutsAndBoltsMatch.java new file mode 100644 index 0000000..85adc90 --- /dev/null +++ b/src/practiceproblems/NutsAndBoltsMatch.java @@ -0,0 +1,74 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/nuts-bolts-problem-lock-key-problem/ + * Java program to solve nut and bolt problem using Quick Sort + */ +public class NutsAndBoltsMatch { + + public static void main(String[] args) { + // Nuts and bolts are represented as array of characters + char nuts[] = { '@', '#', '$', '%', '^', '&' }; + char bolts[] = { '$', '%', '&', '^', '@', '#' }; + + // Method based on quick sort which matches nuts and bolts + matchPairs(nuts, bolts, 0, 5); + + System.out.println("Matched nuts and bolts are : "); + printArray(nuts); + System.out.println(); + printArray(bolts); + } + + // Method to print the array + private static void printArray(char[] arr) { + for (char ch : arr) { + System.out.print(ch + " "); + } + System.out.print("n"); + } + + // Method which works just like quick sort + private static void matchPairs(char[] nuts, char[] bolts, int low, int high) { + if (low < high) { + + // Choose last character of bolts array for nuts partition. + int pivot = partition(nuts, low, high, bolts[high]); + + // Now using the partition of nuts choose that for bolts partition. + partition(bolts, low, high, nuts[pivot]); + + // Recur for [low...pivot-1] & [pivot+1...high] for nuts and + // bolts array. + matchPairs(nuts, bolts, low, pivot - 1); + matchPairs(nuts, bolts, pivot + 1, high); + } + } + + // Similar to standard partition method. Here we pass the pivot element + // too instead of choosing it inside the method. + private static int partition(char[] arr, int low, int high, char pivot) { + int i = low; + char temp1, temp2; + for (int j = low; j < high; j++) { + if (arr[j] < pivot) { + temp1 = arr[i]; + arr[i] = arr[j]; + arr[j] = temp1; + i++; + } else if (arr[j] == pivot) { + temp1 = arr[j]; + arr[j] = arr[high]; + arr[high] = temp1; + j--; + } + } + temp2 = arr[i]; + arr[i] = arr[high]; + arr[high] = temp2; + + // Return the partition index of an array based on the pivot + // element of other array. + return i; + } +} diff --git a/src/practiceproblems/OverlappingIntervals.java b/src/practiceproblems/OverlappingIntervals.java new file mode 100644 index 0000000..1efac77 --- /dev/null +++ b/src/practiceproblems/OverlappingIntervals.java @@ -0,0 +1,42 @@ +package practiceproblems; + +import java.util.PriorityQueue; + +/** + * Given a collection of intervals, find the minimum number of intervals + * you need to remove to make the rest of the intervals non-overlapping. + * Input: [[1,2],[2,3],[3,4],[1,3]] + Output: 1 + Explanation: [1,3] can be removed and the rest of intervals are non-overlapping. + Input: [[1,2],[1,2],[1,2]] + Output: 2 + Explanation: You need to remove two [1,2] to make the rest of intervals non-overlapping. + */ + +public class OverlappingIntervals{ + + public int eraseOverlapIntervals(int[][] intervals) { + if(intervals.length==0) return 0; + + PriorityQueue queue = new PriorityQueue((a, b) -> Integer.compare(a[0],b[0])); + + for(int[] interval: intervals){ + queue.offer(interval); + } + int result=0; + + int end= queue.poll()[1]; + + while(!queue.isEmpty()){ + if(end>queue.peek()[0]) { + result++; + end=Math.min(end, queue.poll()[1]); + }else{ + end=queue.poll()[1]; + } + } + + return result; + } + +} \ No newline at end of file diff --git a/src/practiceproblems/OwnDataStructureUtil.java b/src/practiceproblems/OwnDataStructureUtil.java new file mode 100644 index 0000000..e0ace52 --- /dev/null +++ b/src/practiceproblems/OwnDataStructureUtil.java @@ -0,0 +1,56 @@ +package practiceproblems; + +import java.util.*; + +/** + * https://leetcode.com/problems/insert-delete-getrandom-o1/ + */ +class OwnDataStructureUtil { + ArrayList list; + HashMap map; + Random rand = new Random(); + + public OwnDataStructureUtil() { + list = new ArrayList<>(); + map = new HashMap<>(); + } + + public boolean insert(int val) { + if (map.containsKey(val)) { + return false; + } + map.put(val, list.size()); + list.add(val); + return true; + } + + public boolean remove(int val) { + if (!map.containsKey(val)) { + return false; + } + int loc = map.get(val); + if (loc < list.size() - 1) { // not the last one than swap the last one with this val + int lastOne = list.get(list.size() - 1); + list.set(loc, lastOne); + map.put(lastOne, loc); + } + map.remove(val); + list.remove(list.size() - 1); + return true; + } + + public int getRandom() { + return list.get(rand.nextInt(list.size())); + } + + public static void main(String[] args) { + OwnDataStructureUtil ds = new OwnDataStructureUtil(); + ds.insert(10); + ds.insert(20); + ds.insert(30); + ds.insert(40); + ds.remove(20); + ds.insert(50); + System.out.println(ds.getRandom()); + } +} diff --git a/src/practiceproblems/PalindromePartion.java b/src/practiceproblems/PalindromePartion.java new file mode 100644 index 0000000..61c34be --- /dev/null +++ b/src/practiceproblems/PalindromePartion.java @@ -0,0 +1,52 @@ +package practiceproblems; + +import java.util.*; + +//https://leetcode.com/problems/palindrome-partitioning/ +/* +Given a string s, partition s such that every substring of the partition is a palindrome. + +Return all possible palindrome partitioning of s. + +Input: "aab" +Output: +[ + ["aa","b"], + ["a","a","b"] +] + */ +class PalindromePartion { + public List> partition(String s) { + List> res = new ArrayList>(); + List list = new ArrayList(); + dfs(s, 0, list, res); + return res; + } + + public void dfs(String s, int pos, List list, List> res) { + if (pos == s.length()) { + res.add(new ArrayList(list)); + return; + } + + for (int i = pos; i < s.length(); i++) { + if (isPal(s, pos, i)) { + list.add(s.substring(pos, i + 1)); + dfs(s, i + 1, list, res); + list.remove(list.size() - 1); + } + } + + } + + public boolean isPal(String s, int low, int high) { + while (low < high) if (s.charAt(low++) != s.charAt(high--)) return false; + return true; + } + + public static void main(String[] args) { + new PalindromePartion().partition("aab"); + } + + +} \ No newline at end of file diff --git a/src/practiceproblems/PalindromePartitioning.java b/src/practiceproblems/PalindromePartitioning.java new file mode 100644 index 0000000..0f31ac8 --- /dev/null +++ b/src/practiceproblems/PalindromePartitioning.java @@ -0,0 +1,57 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * https://leetcode.com/problems/palindrome-partitioning/ + */ +class PalindromePartitioning { + + public List> partition(String s) { + + if (s == null || s.length() == 0) { + return Collections.emptyList(); + } + + List> result = new ArrayList<>(); + backtrackingUtil(s, result, new ArrayList<>()); + + return result; + } + + public void backtrackingUtil(String s, List> result, List tempList) { + if (s == null || s.length() == 0) { + result.add(new ArrayList<>(tempList)); + return; + } + + for (int i = 1; i <= s.length(); i++) { + String temp = s.substring(0, i); + if (isPalindrome(temp)) { + tempList.add(temp); + backtrackingUtil(s.substring(i, s.length()), result, tempList); + tempList.remove(tempList.size() - 1); + } + } + } + + public boolean isPalindrome(String s) { + int start = 0; + int end = s.length() - 1; + while (start <= end) { + if (s.charAt(start) != s.charAt(end)) { + return false; + } + start++; + end--; + } + return true; + } + + public static void main(String[] args) { + PalindromePartitioning partitioning = new PalindromePartitioning(); + partitioning.partition("aab"); + } +} \ No newline at end of file diff --git a/src/practiceproblems/PalindromeSinglyLinkedList.java b/src/practiceproblems/PalindromeSinglyLinkedList.java new file mode 100644 index 0000000..770eb9f --- /dev/null +++ b/src/practiceproblems/PalindromeSinglyLinkedList.java @@ -0,0 +1,64 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/palindrome-linked-list/ + */ +public class PalindromeSinglyLinkedList { + + class Node { + int data; + Node next; + + public Node(int data) { + this.data = data; + } + + } + + public static void main(String[] args) { + + PalindromeSinglyLinkedList palindrome = new PalindromeSinglyLinkedList(); + Node head = palindrome.new Node(1); + head.next = palindrome.new Node(2); + head.next.next = palindrome.new Node(3); + head.next.next.next = palindrome.new Node(2); + head.next.next.next.next = palindrome.new Node(1); + + System.out.println(palindrome.isPalindrome(head)); + + } + + public boolean isPalindrome(Node head) { + Node fast = head, slow = head; + while (fast != null && fast.next != null) { + fast = fast.next.next; + slow = slow.next; + } + if (fast != null) { // odd nodes: let right half smaller + slow = slow.next; + } + slow = reverse(slow); + fast = head; + + while (slow != null) { + if (fast.data != slow.data) { + return false; + } + fast = fast.next; + slow = slow.next; + } + return true; + } + + public Node reverse(Node slow) { + Node prev = null; + while (slow != null) { + Node next = slow.next; + slow.next = prev; + prev = slow; + slow = next; + } + return prev; + } + +} diff --git a/src/practiceproblems/PalindromicSubSequence.java b/src/practiceproblems/PalindromicSubSequence.java new file mode 100644 index 0000000..df1b1f5 --- /dev/null +++ b/src/practiceproblems/PalindromicSubSequence.java @@ -0,0 +1,52 @@ +package practiceproblems; + +/** + * Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000. + * Input: "cbbd" + * Output: 2 + * + * + */ +class PalindromicSubSequence { + // genral solution if s[l]==s[r] ? 2 + longestPalindromeSubseq(l+1,r-1, s) : + // max(longestPalindromeSubseq(l+1,r, s),longestPalindromeSubseq(l,r-1, s)); + public int longestPalindromeSubseq(String s) { + if(s==null || s.length()==0) return 0; + + int[][] dp= new int[s.length()][s.length()]; + + for(int i=s.length()-1;i>=0;i--){ + for(int j=i;j= 0; i--) { + dp[i] = 1; + int pre = 0; + for (int j = i + 1; j < s.length(); j++) { + int tmp = dp[j]; + if (s.charAt(i) == s.charAt(j)) { + dp[j] = pre + 2; + } else { + dp[j] = Math.max(dp[j], dp[j - 1]); + } + pre = tmp; + } + } + return dp[s.length() - 1]; + } +} \ No newline at end of file diff --git a/src/practiceproblems/PartitionLabel.java b/src/practiceproblems/PartitionLabel.java new file mode 100644 index 0000000..7975ab3 --- /dev/null +++ b/src/practiceproblems/PartitionLabel.java @@ -0,0 +1,50 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.List; + +/** + * https://leetcode.com/problems/partition-labels/ + * A string S of lowercase English letters is given. + * We want to partition this string into as many parts as possible + * so that each letter appears in at most one part, and return a list of integers representing the size of these parts. + * + * Input: S = "ababcbacadefegdehijhklij" + * Output: [9,7,8] + * Explanation: + * The partition is "ababcbaca", "defegde", "hijhklij". + * This is a partition so that each letter appears in at most one part. + * A partition like "ababcbacadefegde", "hijhklij" is incorrect, because it splits S into less parts. + */ +class PartitionLabel { + + public List partitionLabels(String str) { + + int[] last = new int[26]; + for (int i = 0; i < str.length(); ++i) + // find last appearance of the char + last[str.charAt(i) - 'a'] = i; + + int j = 0; + int anchor = 0; + List ans = new ArrayList<>(); + for (int i = 0; i < str.length(); ++i) { + // find the max of j and last appearance of str[i] + j = Math.max(j, last[str.charAt(i) - 'a']); + if (i == j) { + // it is (1+i-anchor) + int length = i - anchor + 1; + ans.add(length); + anchor = i + 1; + } + } + return ans; + } + + public static void main(String[] args) { + String S = "ababcbacadefegdehijhklij"; + PartitionLabel partition = new PartitionLabel(); + System.out.println(partition.partitionLabels(S)); + + } +} \ No newline at end of file diff --git a/src/practiceproblems/PascalsTriangle.java b/src/practiceproblems/PascalsTriangle.java new file mode 100644 index 0000000..643ec7b --- /dev/null +++ b/src/practiceproblems/PascalsTriangle.java @@ -0,0 +1,70 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * https://leetcode.com/problems/pascals-triangle/ + *

+ * Input: 5 + * Output: + * [ + * [1], + * [1,1], + * [1,2,1], + * [1,3,3,1], + * [1,4,6,4,1] + * ] + */ +public class PascalsTriangle { + + public List> generate(int numRows) { + + if (numRows == 0) { + return Collections.emptyList(); + } + + List> result = new ArrayList<>(); + List first = Arrays.asList(1); + result.add(first); + if (numRows == 1) { + return result; + } + List second = Arrays.asList(1, 1); + result.add(second); + if (numRows == 2) { + return result; + } + + for (int i = 2; i < numRows; i++) { + List temp = new ArrayList<>(); + temp.add(1); + for (int k = 0; k < i - 1; k++) { + int j = k + 1; + temp.add(result.get(i - 1).get(k) + result.get(i - 1).get(j)); + } + temp.add(1); + result.add(temp); + } + return result; + } + + public List> generate1(int numRows) { + List> allrows = new ArrayList>(); + ArrayList row = new ArrayList(); + for (int i = 0; i < numRows; i++) { + // suppose if the row is [1,3,3,1] + // add 1 at start [1,1,3,3,1] + // then add together j and j+1 elements like below + // [1,4,3,3,1] => [1,4,6,3,1]=>[1,4,6,4,1] + row.add(0, 1); + for (int j = 1; j < row.size() - 1; j++) + row.set(j, row.get(j) + row.get(j + 1)); + allrows.add(new ArrayList(row));// every time the copy is only appended + } + return allrows; + + } +} \ No newline at end of file diff --git a/src/practiceproblems/PathSumIII.java b/src/practiceproblems/PathSumIII.java new file mode 100644 index 0000000..1ee3bf9 --- /dev/null +++ b/src/practiceproblems/PathSumIII.java @@ -0,0 +1,48 @@ +package practiceproblems; + + +import java.util.HashMap; +import java.util.Map; + +public class PathSumIII { + Map h= new HashMap<>(); + int count=0; + + public void preorder(TreeNode node, int currSum, int k) { + if (node == null) + return; + + // current prefix sum + currSum += node.val; + + // here is the sum we're looking for + if (currSum == k) + count++; + + // number of times the curr_sum − k has occured already, + // determines the number of times a path with sum k + // has occurred upto the current node + count += h.getOrDefault(currSum - k, 0); + + // add the current sum into hashmap + // to use it during the child nodes processing + h.put(currSum, h.getOrDefault(currSum, 0) + 1); + + // process left subtree + preorder(node.left, currSum, k); + // process right subtree + preorder(node.right, currSum, k); + + // remove the current sum from the hashmap + // in order not to use it during + // the parallel subtree processing + h.put(currSum, h.get(currSum) - 1); + } + + public int pathSumAlter(TreeNode root, int sum) { + int k = sum; + preorder(root, 0, k); + return count; + } + +} \ No newline at end of file diff --git a/src/practiceproblems/Pattern132.java b/src/practiceproblems/Pattern132.java new file mode 100644 index 0000000..c1bd5ca --- /dev/null +++ b/src/practiceproblems/Pattern132.java @@ -0,0 +1,33 @@ +package practiceproblems; + +import java.util.Arrays; + +/*https://leetcode.com/problems/132-pattern/discuss/94089/Java-solutions-from-O(n3)-to-O(n)-for-%22132%22-pattern-(updated-with-one-pass-slution)*/ +public class Pattern132 { + + public static boolean find132pattern(int[] arr) { + + int[] temp = Arrays.copyOf(arr, arr.length); + + for (int i = 1; i < arr.length; i++) { + temp[i] = Math.min(arr[i - 1], temp[i - 1]); + } + // {3, 3, 3, 1, 1, 1, 1, 1} + + for (int j = arr.length - 1, top = arr.length; j >= 0; j--) { + if (arr[j] <= temp[j]) + continue; + while (top < arr.length && temp[top] <= temp[j]) + top++; + if (top < arr.length && arr[j] > temp[top]) + return true; + temp[--top] = arr[j]; + } + return false; + } + + public static void main(String[] args) { + int[] arr = { 3, 4, 1, 2, 9, 6, 7, 8 }; + find132pattern(arr); + } +} diff --git a/src/practiceproblems/PerfectSquare.java b/src/practiceproblems/PerfectSquare.java new file mode 100644 index 0000000..dc47adf --- /dev/null +++ b/src/practiceproblems/PerfectSquare.java @@ -0,0 +1,74 @@ +package practiceproblems; + +import java.util.*; + +class PerfectSquare { + // let's solve by dynamic programming approach + // if we take value 13, the number of perfect squares less than + // the input at any point is Sqrt(input)=>(sqrt(13)=3, so max it can have answer below) + // 3,because 4*4 is 16, so perfect squares below 13 are (1*1, 2*2, 3*3) + // 13 can be broken down into + // 1/ 4| \ 9 deducting 1^2 leaves with val 12 + // / | \ deducting 2^2 leaves with val 9 + // 12 9 4 deducting 3^2 leaves with val 4 + // /|\ /|\ /| + // / | \ 8 5 0 3 0 + // 11 7 3 + + public int numSquaresDp(int n) { + int[] ns = new int[n+1]; + Arrays.fill(ns , -1); + ns[0] = 0; + for(int i=1;i0;j--){ + int result = i - j*j; + // the reason to add 1 to the ns[result] is, we take away + // a square from 'i' initially (j*j) and check for best answer in the 1-D arr + // we add back the 'taken out' square to min value + // for e.x if i=13, sqrt is 3, while iterating + // we subtract 1*1 from 13 and check for best possible answer for 12 ns[result] + // finally we add back the 1*1 as +1 (ns[result]+1) + min = Math.min(min, ns[result]+1); + } + ns[i] = min; + System.out.println(Arrays.toString(ns)); + } + return ns[n]; + } + + public int numSquares(int n){ + Queue q = new LinkedList<>(); + Set visited = new HashSet<>(); + q.offer(0); + visited.add(0); + int depth = 0; + while (!q.isEmpty()) { + int size = q.size(); + depth++; + while (size > 0) { + int removed = q.poll(); + for (int i = 1; i * i <= n; i++) { + int v = removed + i * i; + if (v == n) { + return depth; + } + if (v > n) { + break; + } + if (!visited.contains(v)) { + q.offer(v); + visited.add(v); + } + } + size--; + } + } + return depth; + } + + public static void main(String[] args) { + new PerfectSquare().numSquaresDp(13); + } +} \ No newline at end of file diff --git a/src/practiceproblems/PermutationInString.java b/src/practiceproblems/PermutationInString.java new file mode 100644 index 0000000..0054d4a --- /dev/null +++ b/src/practiceproblems/PermutationInString.java @@ -0,0 +1,62 @@ +package practiceproblems; + +/** + * Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. + * In other words, one of the first string's permutations is the substring of the second string. + * Input:s1= "ab" s2 = "eidboaoo" + * Output: False + *

+ * https://leetcode.com/problems/permutation-in-string/ + */ +public class PermutationInString { + + // How do we know string p is a permutation of string s? Easy, each character in p is in s too. + // So we can abstract all permutation strings of s to a map (Character -> Count). i.e. abba -> {a:2, b:2}. + // Since there are only 26 lower case letters in this problem, + // we can just use an array to represent the map. + // How do we know string s2 contains a permutation of s1? + // We just need to create a sliding window with length of s1, + // move from beginning to the end of s2. + // When a character moves in from right of the window, + // we subtract 1 to that character count from the map. + // When a character moves out from left of the window, we add 1 to that character count. + // So once we see all zeros in the map, + // meaning equal numbers of every characters between s1 and + // the substring in the sliding window, we know the answer is true. + public static boolean checkInclusion(String s1, String s2) { + if (s1.length() == 0 || s2.length() == 0) { + return false; + } + int[] cache = new int[26]; + for (char s : s1.toCharArray()) { + cache[s - 'a']++; + } + + int right = 0; + + while (right < s2.length()) { + cache[s2.charAt(right) - 'a']--; + if (right >= s1.length()) { + cache[s2.charAt(right - s1.length()) - 'a']++; // sliding the window + } + if (allZero(cache)) { + return true; + } + right++; + } + return false; + } + + public static boolean allZero(int[] cache) { + for (int i = 0; i < 26; i++) { + if (cache[i] > 0) { + return false; + } + } + return true; + } + + public static void main(String[] args) { + System.out.println(checkInclusion("ab", "eidbaoo")); + } +} \ No newline at end of file diff --git a/src/practiceproblems/PetrolGasStation.java b/src/practiceproblems/PetrolGasStation.java new file mode 100644 index 0000000..14d5854 --- /dev/null +++ b/src/practiceproblems/PetrolGasStation.java @@ -0,0 +1,37 @@ +package practiceproblems; + +public class PetrolGasStation { + + // gas means amount of gas which we have in our car + // cost means amount of gas to reach next station + public static int canCompleteCircuit(int[] gas, int[] cost) { + int sumGas = 0; + int sumCost = 0; + int start = 0; + int tank = 0; + for (int i = 0; i < gas.length; i++) { + sumGas += gas[i]; + sumCost += cost[i]; + } + if (sumGas < sumCost) { + return -1; + } + + for (int i = 0; i < gas.length; i++) { + tank += gas[i] - cost[i]; + if (tank < 0) { + start = i + 1; + tank = 0; + } + } + return start; + } + + public static void main(String[] args) { + + int[] gas = { 4, 6, 7, 4 }; + int[] cost = { 6, 5, 3, 5 }; + int start = canCompleteCircuit(gas, cost); + System.out.println(start == -1 ? "No Solution" : "Start = " + start); + } +} diff --git a/src/practiceproblems/PlusOne.java b/src/practiceproblems/PlusOne.java new file mode 100644 index 0000000..6096b5f --- /dev/null +++ b/src/practiceproblems/PlusOne.java @@ -0,0 +1,38 @@ +package practiceproblems; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/plus-one/ + */ +class PlusOne { + + public static int[] plusOne(int[] digits) { + + int n = digits.length; + // move along the input array starting from the end + for (int idx = n - 1; idx >= 0; --idx) { + // set all the nines at the end of array to zeros + if (digits[idx] == 9) { + digits[idx] = 0; + } + // here we have the rightmost not-nine + else { + // increase this rightmost not-nine by 1 + digits[idx]++; + // and the job is done + return digits; + } + } + // we're here because all the digits are nines + digits = new int[n + 1]; + digits[0] = 1; + return digits; + } + + public static void main(String[] args) { + int[] digits = { 1, 2, 9 }; + int[] endpointUrl = plusOne(digits); + Arrays.stream(endpointUrl).forEach(System.out::println); + } +} \ No newline at end of file diff --git a/src/practiceproblems/Pow.java b/src/practiceproblems/Pow.java new file mode 100644 index 0000000..b4be8fc --- /dev/null +++ b/src/practiceproblems/Pow.java @@ -0,0 +1,52 @@ +package practiceproblems; + +/** + * Implement pow(x, n), which calculates x raised to the power n (i.e. xn). + * + * Example 1: + * + * Input: x = 2.00000, n = 10 + * Output: 1024.00000 + * Example 2: + * + * Input: x = 2.10000, n = 3 + * Output: 9.26100 + */ +public class Pow { + + public double myPow(double x, int n) { + + if (n < 0) { + n *= -1; + x = 1 / x; + } + double result = 1; + + result = powerCalcUtil(x, n); + return result; + } + + + public double powerCalcUtil(double x, int n) { + if (n == 0) + return 1; + + double half = powerCalcUtil(x, n / 2); + if (n % 2 == 0) { + return half * half; + } else { + return half * half * x; + } + } + + public double pow1(double x, int n) { + double result = 1.0; + for(int i = n; i != 0; i /= 2, x *= x) { + if( i % 2 != 0 ) { + result *= x; + } + } + return n < 0 ? 1.0 / result : result; + } + +} \ No newline at end of file diff --git a/src/practiceproblems/PrisonAfterNDays.java b/src/practiceproblems/PrisonAfterNDays.java new file mode 100644 index 0000000..dd7dd40 --- /dev/null +++ b/src/practiceproblems/PrisonAfterNDays.java @@ -0,0 +1,54 @@ +package practiceproblems; + +import java.util.Arrays; +import java.util.HashSet; +/* +https://leetcode.com/problems/prison-cells-after-n-days/ + */ + +class PrisonAfterNDays { + + public static int[] prisonAfterNDays(int[] cells, int N) { + if (cells == null || cells.length == 0 || N <= 0) { + return cells; + } + boolean hasCycle = false; + int cycle = 0; + HashSet set = new HashSet<>(); + for (int i = 0; i < N; i++) { + int[] next = nextDay(cells); + String key = Arrays.toString(next); + if (!set.contains(key)) { //store cell state + set.add(key); + cycle++; + } else { //hit a cycle + hasCycle = true; + break; + } + cells = next; + } + if (hasCycle) { + N %= cycle; // calculating the reminder day after excluding the cycle + // let's say N=10 and we hit cycle at 3, we need 10%3=1 remaining calculation + // to be done + for (int i = 0; i < N; i++) { + cells = nextDay(cells); + } + } + return cells; + } + + private static int[] nextDay(int[] cells) { + int[] tmp = new int[cells.length]; + for (int i = 1; i < cells.length - 1; i++) { + tmp[i] = cells[i - 1] == cells[i + 1] ? 1 : 0; + } + return tmp; + } + + public static void main(String[] args) { + int[] cells = { 0, 1, 0, 1, 1, 0, 0, 1 }; + int N = 7; + System.out.println(Arrays.toString(prisonAfterNDays(cells, N))); + } +} \ No newline at end of file diff --git a/src/practiceproblems/ProductExceptSelf.java b/src/practiceproblems/ProductExceptSelf.java new file mode 100644 index 0000000..842dd35 --- /dev/null +++ b/src/practiceproblems/ProductExceptSelf.java @@ -0,0 +1,52 @@ +package practiceproblems; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/product-of-array-except-self/ + *

+ * Given numbers [2, 3, 4, 5], regarding the third number 4, + * the product of array except 4 is 2*3*5 which consists of two parts: left 2*3 and right 5. + * The product is left*right. We can get lefts and rights + *

+ * Numbers: 2 3 4 5 + * Lefts: 2 2*3 2*3*4 + * Rights: 3*4*5 4*5 5 + *

+ * Let’s fill the empty with 1: + *

+ * Numbers: 2 3 4 5 + * Lefts: 1 2 2*3 2*3*4 + * Rights: 3*4*5 4*5 5 1 + */ +public class ProductExceptSelf { + public static int[] productExceptSelf(int[] nums) { + int n = nums.length; + int[] res = new int[n]; + res[0] = 1; + + for (int i = 1; i < n; i++) { + res[i] = res[i - 1] * nums[i - 1]; + } + // once building the left product instead of having a new array to calculate rightsum + // we use a variable to store last seen value + // for number 2 3 4 5 + // the left product array is 1 2 2*3 2*3*4 + + // for rightProd during step1 2 3 4 5 right is 1 so last product value retained + // 2*3*4 + // during step 2 the right becomes 5(1*nums[i]=>5) + // so for value 4(length-2) the left product is 2*3 multiplying with 5 becomes 2*3*5 + // during step 3 the right is updated to (5*nums[i]=>4) 20 + int right = 1; + for (int i = n - 1; i >= 0; i--) { + res[i] *= right; + right *= nums[i]; + } + return res; + } + + public static void main(String[] args) { + System.out.println(Arrays.toString(productExceptSelf(new int[] { 1, 2, 3, 4, 5 }))); + } +} \ No newline at end of file diff --git a/src/practiceproblems/QueensAttackKing.java b/src/practiceproblems/QueensAttackKing.java new file mode 100644 index 0000000..4ca1848 --- /dev/null +++ b/src/practiceproblems/QueensAttackKing.java @@ -0,0 +1,54 @@ +package practiceproblems; + +import java.util.*; +//https://leetcode.com/problems/queens-that-can-attack-the-king/submissions/ + +/** + * On an 8x8 chessboard, there can be multiple Black Queens and one White King. + * + * Given an array of integer coordinates queens that represents the positions of the Black Queens, + * and a pair of coordinates king that represent the position of the White King, + * return the coordinates of all the queens (in any order) that can attack the King. + */ +class QueensAttackKing { + public List> queensAttacktheKing(int[][] queens, int[] king) { + List> result= new ArrayList<>(); + boolean[][] visited= new boolean[8][8]; + int[][]dirs= {{1,0},{-1,0},{0,1},{0,-1},{-1,-1},{1,1},{1,-1},{-1,1}}; + // first marking all queen positions + for(int[] qu:queens){ + visited[qu[0]][qu[1]]=true; + } + + for(int[] dir: dirs){ + List temp= findQueensPositions(king,dir[0],dir[1],visited); + if(temp!=null) result.add(temp); + } + + return result; + + } + + public List findQueensPositions(int[] king, int xDir, int yDir, boolean[][] visited){ + int newX= xDir+king[0]; + int newY= yDir+king[1]; + // going to walk along x,y only not 8 directions at same time + while(newX<8 && newY<8 && newX>=0 && newY>=0){ + if(visited[newX][newY]){ + return Arrays.asList(newX,newY); // returns when first queen is met in row or column + } + + newX+=xDir; + newY+=yDir; + + } + + return null; + } + + public static void main(String[] args) { + int[][] queens= {{0,1},{1,0},{4,0},{0,4},{3,3},{2,4}}; + int[] king= {0,0}; + new QueensAttackKing().queensAttacktheKing(queens, king); + } +} \ No newline at end of file diff --git a/src/practiceproblems/RaceCarMinSteps.java b/src/practiceproblems/RaceCarMinSteps.java new file mode 100644 index 0000000..6794359 --- /dev/null +++ b/src/practiceproblems/RaceCarMinSteps.java @@ -0,0 +1,45 @@ +package practiceproblems; + +import java.util.*; +class RaceCarMinSteps { + public int racecar(int target) { + Set visited = new HashSet<>(); + Queue queue = new LinkedList<>(); + queue.add(new StateNode(1, 0)); + int distance = 0; + while (!queue.isEmpty()) { + int levelSize = queue.size(); + for (int i = 0; i < levelSize; i++) { + StateNode cur = queue.poll(); + if (cur.position == target) { + return distance; + } + // if A + int nextPosition = cur.position + cur.speed; + int nextSpeed = cur.speed * 2; + if (!visited.contains(nextSpeed + "," + nextPosition) && Math.abs(target - nextPosition) < target) { + visited.add(nextSpeed + "," + nextPosition); + queue.offer(new StateNode(nextSpeed, nextPosition)); + } + // if R + nextPosition = cur.position; + nextSpeed = cur.speed > 0 ? -1 : 1; + if (!visited.contains(nextSpeed + "," + nextPosition) && Math.abs(target - nextPosition) < target) { + visited.add(nextSpeed + "," + nextPosition); + queue.offer(new StateNode(nextSpeed, nextPosition)); + } + } + distance++; + } + return -1; + } +} + class StateNode { + int speed; + int position; + + public StateNode(int speed, int position) { + this.speed = speed; + this.position = position; + } + } \ No newline at end of file diff --git a/src/practiceproblems/RandomLinkedList.java b/src/practiceproblems/RandomLinkedList.java new file mode 100644 index 0000000..32fd33a --- /dev/null +++ b/src/practiceproblems/RandomLinkedList.java @@ -0,0 +1,62 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/copy-list-with-random-pointer/ + */ +class RandomLinkedList { + + public LLNode copyRandomList(LLNode head) { + if (head == null) { + return null; + } + LLNode temp = head; + while (temp != null) { + LLNode LLNode = new LLNode(temp.val + 10, temp.next, null); + temp.next = LLNode; + temp = temp.next.next; + } + LLNode randomLLNode = head; + while (randomLLNode != null) { + randomLLNode.next.random = randomLLNode.random.next; + randomLLNode = randomLLNode.next.next; + } + LLNode copyHead = head.next; + LLNode tempHead = copyHead; + while (head != null && tempHead != null) { + head.next = head.next == null || head.next.next == null ? head.next : head.next.next; + tempHead.next = tempHead.next == null || tempHead.next.next == null ? tempHead.next : tempHead.next.next; + head = head.next; + tempHead = tempHead.next; + } + return copyHead; + } + + public static void main(String[] args) { + LLNode head = new LLNode(1, null, null); + head.next = new LLNode(2, null, null); + head.next.next = new LLNode(3, null, null); + head.next.next.next = new LLNode(4, null, null); + head.random = head.next.next; + head.next.random = head.next.next.next; + head.next.next.random = head.next; + head.next.next.next.random = head; + RandomLinkedList solution = new RandomLinkedList(); + solution.copyRandomList(head); + } +} + +class LLNode { + public int val; + public LLNode next; + public LLNode random; + + public LLNode(int _val, LLNode _next, LLNode _random) { + val = _val; + next = _next; + random = _random; + } + + public String toString() { + return "" + this.val; + } +} \ No newline at end of file diff --git a/src/practiceproblems/RandomPickWithWeight.java b/src/practiceproblems/RandomPickWithWeight.java new file mode 100644 index 0000000..bf38a9c --- /dev/null +++ b/src/practiceproblems/RandomPickWithWeight.java @@ -0,0 +1,52 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/random-pick-with-weight/ + */ +class RandomPickWithWeight { + private int sum; + private int[] sumArr; + + public RandomPickWithWeight(int[] w) { + sum = 0; + sumArr = new int[w.length]; + for (int i = 0; i < w.length; ++i) { + sum += w[i]; + sumArr[i] = sum; + } + } + + public int pickIndex() { + int idx = (int) (Math.random() * sum); + return binarySearch(idx + 1); // +1 is because the rand will lie between 0-14 + } + + public int binarySearch(int idx) { + int left = 0; + int right = sumArr.length - 1; + + while (left < right) { + int mid = ((right - left) / 2) + left; + if (sumArr[mid] < idx) { + left = mid + 1; + } else { + right = mid; + } + } + return left; + } + + public static void main(String[] args) { + RandomPickWithWeight randomPickWithWeight = new RandomPickWithWeight(new int[]{1, 3, 5, 4, 2}); + randomPickWithWeight.pickIndex(); + + //IntStream.range(0, 10).forEach(i -> System.out.println((int) (Math.random() * 3))); + } + +} + +/** + * Your Solution object will be instantiated and called as such: + * Solution obj = new Solution(w); + * int param_1 = obj.pickIndex(); + */ \ No newline at end of file diff --git a/src/practiceproblems/RangeSum.java b/src/practiceproblems/RangeSum.java new file mode 100644 index 0000000..75f1df5 --- /dev/null +++ b/src/practiceproblems/RangeSum.java @@ -0,0 +1,41 @@ +package practiceproblems; + +/** + * 303. Range Sum Query - Immutable + * + * Given an integer array nums, + * find the sum of the elements between indices i and j (i ≤ j), inclusive. + * + * Implement the NumArray class: + * + * NumArray(int[] nums) Initializes the object with the integer array nums. + * int sumRange(int i, int j) Return the sum of the elements of the nums array in the range [i, j] + * inclusive (i.e., sum(nums[i], nums[i + 1], ... , nums[j])) + * + * ["NumArray", "sumRange", "sumRange", "sumRange"] + * [[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]] + * Output + * [null, 1, -1, -3] + * + * Explanation + * NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]); + * numArray.sumRange(0, 2); // return 1 ((-2) + 0 + 3) + * numArray.sumRange(2, 5); // return -1 (3 + (-5) + 2 + (-1)) + * numArray.sumRange(0, 5); // return -3 ((-2) + 0 + 3 + (-5) + 2 + (-1)) + */ +public class RangeSum { + int[] dp; + public void NumArray(int[] nums) { + if(nums.length==0) return ; + dp= new int[nums.length]; + dp[0]=nums[0]; + for(int i=1;i findItinerary(List> tickets) { + if(tickets==null || tickets.size()==0) return Collections.emptyList(); + + Map> map= new HashMap<>(); + + for(List ticket: tickets){ + map.putIfAbsent(ticket.get(0), new PriorityQueue<>()); + map.get(ticket.get(0)).offer(ticket.get(1)); + } + List res = new ArrayList(); + dfs(map, res, "JFK"); + return res; + } + + public void dfs( Map> map, List res, String s){ + + PriorityQueue queue= map.get(s); + + while(queue!=null && !queue.isEmpty()){ + String temp= queue.poll(); + dfs(map, res, temp); + } + + res.add(0,s); + } + } + +} \ No newline at end of file diff --git a/src/practiceproblems/RedundantConnection.java b/src/practiceproblems/RedundantConnection.java new file mode 100644 index 0000000..f5f2f0a --- /dev/null +++ b/src/practiceproblems/RedundantConnection.java @@ -0,0 +1,44 @@ +package practiceproblems; + +public class RedundantConnection { + public int[] findRedundantConnection(int[][] edges) { + DisjointSet set= new DisjointSet(edges.length); + + for(int[]edge: edges){ + if(!set.union(edge[0]-1, edge[1]-1)) return edge; + } + return new int[]{-1,-1}; + } + + static class DisjointSet{ + int[] parent; + int[] rank; + + public DisjointSet(int n){ + this.parent= new int[n]; + this.rank= new int[n]; + } + + public int find(int x){ + if(parent[x]==0) return x; + return parent[x]=find(parent[x]); + } + + public boolean union(int x, int y){ + int rootX= find(x); + int rootY= find(y); + + if(rootX==rootY) return false; + + if(rank[rootX] 0 && res[i - 1] == res[i]) { + i -= 2; + } + } + return new String(res, 0, i); + } +} \ No newline at end of file diff --git a/src/practiceproblems/RemoveDuplicates.java b/src/practiceproblems/RemoveDuplicates.java new file mode 100644 index 0000000..6292653 --- /dev/null +++ b/src/practiceproblems/RemoveDuplicates.java @@ -0,0 +1,27 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/remove-duplicates-from-sorted-array/ + */ +class RemoveDuplicates { + + public int removeDuplicates(int[] nums) { + if (nums == null || nums.length == 0) { + return 0; + } + int i = 0; + nums[i++] = nums[0]; + for (int j = 1; j < nums.length; j++) { + if (nums[j] != nums[j - 1]) { + nums[i++] = nums[j]; + } + } + return i; + } + + public static void main(String[] args) { + RemoveDuplicates removeDuplicates = new RemoveDuplicates(); + int[] nums = { 1, 1, 2 }; + removeDuplicates.removeDuplicates(nums); + } +} \ No newline at end of file diff --git a/src/practiceproblems/RemoveInvalidParentheses.java b/src/practiceproblems/RemoveInvalidParentheses.java new file mode 100644 index 0000000..f92c7fd --- /dev/null +++ b/src/practiceproblems/RemoveInvalidParentheses.java @@ -0,0 +1,61 @@ +package practiceproblems; + +import java.util.*; + +public class RemoveInvalidParentheses { + + public List removeInvalidParentheses(String s) { + if (isValid(s)) + return Collections.singletonList(s); + List ans = new ArrayList<>(); + //The queue only contains invalid middle steps + Queue queue = new LinkedList<>(); + //The 3-Tuple is (string, startIndex, lastRemovedChar) + queue.add(new Tuple(s, 0, ')')); + while (!queue.isEmpty()) { + Tuple x = queue.poll(); + //Observation 2, start from last removal position + for (int i = x.start; i < x.string.length(); ++i) { + char ch = x.string.charAt(i); + //Not parentheses + if (ch != '(' && ch != ')') continue; + //Observation 1, do not repeatedly remove from consecutive ones + if (i != x.start && x.string.charAt(i - 1) == ch) continue; + //Observation 3, do not remove a pair of valid parentheses + if (x.removed == '(' && ch == ')') continue; + String t = x.string.substring(0, i) + x.string.substring(i + 1); + //Check isValid before add + if (isValid(t)) + ans.add(t); + //Avoid adding leaf level strings + else if (ans.isEmpty()) + queue.add(new Tuple(t, i, ch)); + } + } + return ans; +} + +public static boolean isValid(String s) { + int count = 0; + for (int i = 0; i < s.length(); ++i) { + char c = s.charAt(i); + if (c == '(') ++count; + if (c == ')' && count-- == 0) return false; + } + return count == 0; +} + +} + + class Tuple { + public final String string; + public final int start; + public final char removed; + + public Tuple(String string, int start, char removed) { + this.string = string; + this.start = start; + this.removed = removed; + +} +} \ No newline at end of file diff --git a/src/practiceproblems/RemoveKDigits.java b/src/practiceproblems/RemoveKDigits.java new file mode 100644 index 0000000..d218206 --- /dev/null +++ b/src/practiceproblems/RemoveKDigits.java @@ -0,0 +1,60 @@ +package practiceproblems; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * https://leetcode.com/problems/remove-k-digits/ + * + * Given a non-negative integer num represented as a string, + * remove k digits from the number so that the new number is the smallest possible. + * + * Note: + * The length of num is less than 10002 and will be ≥ k. + * The given num does not contain any leading zero. + * + * Input: num = "1432219", k = 3 + * Output: "1219" + * Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest. + * + * Input: num = "10", k = 2 + * Output: "0" + * Explanation: Remove all the digits from the number and it is left with nothing which is 0. + */ + +public class RemoveKDigits { + //1432219 + public static String removeKdigits(String num, int k) { + if(num==null || num.length()==0) return null; + + Deque queue= new ArrayDeque<>(); + for(char c: num.toCharArray()){ + + while(!queue.isEmpty() && queue.getLast()>c-'0' && k>0){ + queue.removeLast(); + k--; + } + queue.addLast(c-'0'); + } + + while(k>0){ + queue.removeLast(); + k--; + } + + StringBuilder result= new StringBuilder(); + while(!queue.isEmpty()){ + result.append(queue.removeFirst()); + } + + while(result.length()>0 && result.charAt(0)=='0'){ + result.deleteCharAt(0); + } + + return result.length()==0?"0":result.toString(); + } + + public static void main(String[] args) { + System.out.println(removeKdigits("14232191", 3)); + } +} \ No newline at end of file diff --git a/src/practiceproblems/ReorderLogs.java b/src/practiceproblems/ReorderLogs.java new file mode 100644 index 0000000..9cfc64b --- /dev/null +++ b/src/practiceproblems/ReorderLogs.java @@ -0,0 +1,58 @@ +package practiceproblems; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/reorder-data-in-log-files/ + +You have an array of logs. Each log is a space delimited string of words. + +For each log, the first word in each log is an alphanumeric identifier. Then, either: + +Each word after the identifier will consist only of lowercase letters, or +Each word after the identifier will consist only of digits. +We will call these two varieties of logs letter-logs and digit-logs. It is guaranteed that each log has at least one word after its identifier. + +Reorder the logs so that all of the letter-logs come before any digit-log. +The letter-logs are ordered lexicographically ignoring identifier, with the identifier used in case of ties. +The digit-logs should be put in their original order. + +Input: logs = ["dig1 8 1 5 1","let1 art can","dig2 3 6","let2 own kit dig","let3 art zero"] +Output: ["let1 art can","let3 art zero","let2 own kit dig","dig1 8 1 5 1","dig2 3 6"] +*/ + +class ReorderLogs { + public static String[] reorderLogFiles(String[] logs) { + Arrays.sort(logs, (s1, s2) -> { + String[] split1 = s1.split(" ", 2); // splits arr in to 2 parts + String[] split2 = s2.split(" ", 2); + + boolean isDigit1 = Character.isDigit(split1[1].charAt(0)); + boolean isDigit2 = Character.isDigit(split2[1].charAt(0)); + + if (!isDigit1 && !isDigit2) { + // both letter-logs. + int comp = split1[1].compareTo(split2[1]); + if (comp == 0) + return split1[0].compareTo(split2[0]); + else + return comp; + } else if (isDigit1 && isDigit2) { + // both digit-logs. So keep them in original order + return 0; + } else if (isDigit1 && !isDigit2) { + // first is digit, second is letter. bring letter to forward. + return 1; + } else { + // first is letter, second is digit. keep them in this order. + return -1; + } + }); + return logs; + } + + public static void main(String[] args) { + String[] string = {"dig1 8 1 5 1", "yet1 art can", "dig2 3 6", "let2 own kit dig", "let3 art zero"}; + System.out.println(Arrays.toString(reorderLogFiles(string))); + } +} \ No newline at end of file diff --git a/src/practiceproblems/ReorganiseString.java b/src/practiceproblems/ReorganiseString.java new file mode 100644 index 0000000..a2b77b1 --- /dev/null +++ b/src/practiceproblems/ReorganiseString.java @@ -0,0 +1,71 @@ +package practiceproblems; + +/** + * Given a string S, check if the letters can be rearranged so that two characters that are adjacent to each other are not the same. + * + * If possible, output any possible result. If not possible, return the empty string. + * + * Input: S = "aab" + * Output: "aba" + * + * Input: S = "aaab" + * Output: "" + */ +class ReorganiseString { + public String reorganizeString(String s) { + if (s == null || s.length() < 1) return ""; + + int[] hash = new int[26]; + for (char c : s.toCharArray()) { + hash[c - 'a']++; + } + + int max = 0; + int letter = 0; + + for (int i = 0; i < hash.length; i++) { + if (hash[i] > max) { + max = hash[i]; + letter = i; + } + } + + if (max > (s.length() + 1) / 2) return ""; + + char[] res = new char[s.length()]; + + int pos = 0; + while (hash[letter] > 0) { + res[pos] = (char) (letter + 'a'); + pos += 2; + hash[letter]--; + } + + // We construct the resulting string in sequence: at position 0, 2, 4, ... and then 1, 3, 5, ... + // In this way, we can make sure there is always a gap between the same characters + + // Consider this example: "aaabbbcdd", we will construct the string in this way: + + // a _ a _ a _ _ _ _ // fill in "a" at position 0, 2, 4 + // a b a _ a _ b _ b // fill in "b" at position 6, 8, 1 + // a b a c a _ b _ b // fill in "c" at position 3 + // a b a c a d b d b // fill in "d" at position 5, 7 + + for (int i = 0; i < hash.length; i++) { + while (hash[i] > 0) { + if (pos >= res.length) pos = 1; + + res[pos] = (char) (i + 'a'); + pos += 2; + hash[i]--; + } + } + + return new String(res); + } + + public static void main(String[] args) { + + new ReorganiseString().reorganizeString("aabccdeeee"); + } +} \ No newline at end of file diff --git a/src/practiceproblems/RestoreIpAddresses.java b/src/practiceproblems/RestoreIpAddresses.java new file mode 100644 index 0000000..db628f7 --- /dev/null +++ b/src/practiceproblems/RestoreIpAddresses.java @@ -0,0 +1,53 @@ +package practiceproblems; + +import java.util.*; + +/** + *Given a string s containing only digits, + * return all possible valid IP addresses that can be obtained from s. + * You can return them in any order. + * + * A valid IP address consists of exactly four integers, + * each integer is between 0 and 255, separated by single dots and cannot have leading zeros. + * For example, "0.1.2.201" and "192.168.1.1" are valid IP addresses and "0.011.255.245", + * "192.168.1.312" and "192.168@1.1" are invalid IP addresses. + */ + +public class RestoreIpAddresses { + public List restoreIpAddresses(String s) { + if (s == null) + return Collections.emptyList(); + List result = new ArrayList<>(); + + for (int i = 1; i < 4 && i < s.length(); i++) { + String first = s.substring(0, i); + if (isValid(first)) { + for (int j = 1; j < 4 && j + i < s.length(); j++) { + String second = s.substring(i, i + j); + if (isValid(second)) { + for (int k = 1; i + j + k < s.length() && k < 4; k++) { + String third = s.substring(i + j, i + j + k); + String fourth = s.substring(i + j + k); + if (isValid(third) && isValid(fourth)) { + result.add(first + "." + second + "." + third + "." + fourth); + } + } + } + } + } + } + return result; + } + + public boolean isValid(String part) { + if (part == null || part.length() > 3) + return false; + + if (part.charAt(0) == '0' && part.length() > 1) + return false; + + int address = Integer.parseInt(part); + + return address >= 0 && address <= 255; + } +} \ No newline at end of file diff --git a/src/practiceproblems/ReverseWordsInString.java b/src/practiceproblems/ReverseWordsInString.java new file mode 100644 index 0000000..f848084 --- /dev/null +++ b/src/practiceproblems/ReverseWordsInString.java @@ -0,0 +1,40 @@ +package practiceproblems; + +import java.util.Arrays; + +public class ReverseWordsInString { + + public char[] reverse(char[] arr, int i, int j) { + while (i < j) { + char tmp = arr[i]; + arr[i++] = arr[j]; + arr[j--] = tmp; + } + return arr; + } + + public String reverseWords(String s) { + // reverse the whole string and convert to char array + char[] str = reverse(s.toCharArray(), 0, s.length()-1); + int start = 0, end = 0; // start and end positions of a current word + //for input "the sky is blue" + // the char arr contians + //[e u l b s i y k s e h t] + + System.out.println(Arrays.toString(str)); + for (int i = 0; i < str.length; i++) { + if (str[i] != ' ') { // if the current char is letter + str[end++] = str[i]; // just move this letter to the next free pos + } else if (i > 0 && str[i-1] != ' ') { // if the first space after word + reverse(str, start, end-1); // reverse the word + str[end++] = ' '; // and put the space after it + start = end; // move start position further for the next word + } + } + reverse(str, start, end-1); // reverse the tail word if it's there + // here's an ugly return just because we need to return Java's String + // also as there could be spaces at the end of original string + // we need to consider redundant space we have put there before + return new String(str, 0, end > 0 && str[end-1] == ' ' ? end-1 : end); + } +} \ No newline at end of file diff --git a/src/practiceproblems/RollingHashRabinKarp.java b/src/practiceproblems/RollingHashRabinKarp.java new file mode 100644 index 0000000..bafdac5 --- /dev/null +++ b/src/practiceproblems/RollingHashRabinKarp.java @@ -0,0 +1,134 @@ +package practiceproblems; + +public class RollingHashRabinKarp{ + /** + * the normal way to calculate an hash from a string would be through the following method + * for String S="abcdef" we chose a prime number which is greater that the no.of chars(26) + * we choose P=31 + * + * total hash(abcdef)= (a*P^0+ b*P^1 + c*P^2 + d*P^3 + e*P^4 + f*P^5) % M; + * %(mod) is taken to avoid overflow of values + * hash at each point is [h0, h1, h2, h3, h4, h5] + * + * this is anlogus to prefix sum, the hash at each index i is hash calculated from 0 to 'i' + * + * for h2 is hash from (a-c), in order to calculate prefix sum from index 2-4 + * + * sum(2-4)= sum(4)-sum(2) [sum 0-4 - sum 0-2], likewise we can calulate rolling hash + * + * in order to find contains subString for String size M and N, the time complexity would be O(MN) + * + * if we find the hash of String M and N seperately and somehow find if substring of size N in String M + * hashes to hash(N) we will have our result in O(M) + * + * M= SDESKILLS + * N= SKILLS + * Note: p0 or p1= P^number + * + * hash of M= [(S*p0)+(D*p1)+(E*p2)+(S*p4)+(K*p5)+(I*p6)+(L*p7)+(L*p8)+(S*p9)] % M + * + * in hashing no matter how many times/ at what posistion a string comes, it has to hash to same value + * + * if we have a hash(abcdef)= a*p0+ b*p1+ c*p2+ d*p3+ e*p4+ f*p5 + * and i need hash(cde) i need to do prefix sum analogy + * hash(cde)= hash(R)-hash(L-1) R= Right, L=Left + * but the above equation comes down to [c*p2 + d*p3+ e*p4] this is not going to yeild correct + * result for cde every time if 'cde' occurs at different index then the eq would be [c*p8+d*p9+e*p10] + * + * so what we need is to add one more part to the eq ([c*p2 + d*p3+ e*p4]/ p2) => [c*p0 + d*p1+ e*p2] + * hash(cde)= hash(R)-hash(L-1)/P^L R= Right, L=Left + * + * Hash[3,6]= (Hash(6)- Hash(2)/ p^3)%M + * + * hash([L...R]) =(hash[R] - hash[L - 1]/PL)% M + hash(s[L...R]) =(hash[R] - hash[L - 1]) * P^-L % M + + hash(s[L...R]) =(hash[R] - hash[L - 1])*(P^-1)L % M + hash(s[L...R]) =(hash[R] - hash[L - 1])% M*(P-1)L %M% M + + (A * B) % M =( (A % M) * (B % M)) % M + X = P^-1= P^M-2% M + hash(s[L...R]) =(((hash[R] - hash[L - 1])% M *X^L )% M) + */ + + + public static void main(String[] args) { + String givenValue = "abaaab"; + String input = "aaa"; + +// char[] givenArr = givenValue.toCharArray(); +// char[] inputArr = input.toCharArray(); +// +// int inputHash = createHash(inputArr, inputArr.length); +// int previousValue = 0; +// for (int i = 0; i < (givenArr.length - inputArr.length + 1); i++) { +// previousValue = givenHash(givenArr, i, previousValue); +// if (inputHash == previousValue && matchString(inputArr, givenArr, i)) { +// System.out.println("It exists"); +// } +// } + + rabinKarp(givenValue, input); + } + + private static int givenHash(char[] givenArr, int i, int previousValue) { + + if (previousValue == 0) { + return createHash(givenArr, 3); + } + + int currentValue = previousValue - givenArr[i - 1]; + System.out.println(currentValue + givenArr[i + 2] * 100); + return currentValue + givenArr[i + 2] * 100; + + } + + private static int createHash(char[] inputArr, int length) { + int hash = 0; + double power = 0; + for (int i = 0; i < length; i++) { + hash = hash + (int) Math.pow(10, power++) * inputArr[i]; + } + return hash; + } + + private static boolean matchString(char[] inputArr, char[] givenArr, int i) { + int index = 0; + for (int j = i; j < inputArr.length; j++) { + if (inputArr[index++] != givenArr[j]) { + return false; + } + } + return true; + } + + //the time complexity is O(m + n) + public static int rabinKarp(String t, String s) { + if (s.length() > t.length()) { + return -1; // s is not a substring of t. + } + final int BASE = 26; + int tHash = 0, sHash = 0; // Hash codes for the substring of t and s. + int powerS = 1; // this will be used to calculate the rolling hash when current window moves out + for (int i = 0; i < s.length(); i++) { + powerS = i > 0 ? powerS * BASE : 1; + tHash = tHash * BASE + t.charAt(i); + sHash = sHash * BASE + s.charAt(i); + } + for (int i = s.length(); i < t.length(); i++) { +// Checks the two substrings are actually equal or not, to protect +// against hash collision. + if (tHash == sHash ){ //&& t.substring(i - s.length(), i).equals(s)) { + return i - s.length(); // Found a match. + } +// Uses rolling hash to compute the new hash code. + tHash -= t.charAt(i - s.length()) * powerS; + tHash = tHash * BASE + t.charAt(i); + } +// Tries to match s and t.substring(t.length() - s.lengthO). + if (tHash == sHash){ // && t .substring(t.length() - s.length()).equals(s)){ + return t.length() - s.length(); + } + return -1; + } +} \ No newline at end of file diff --git a/src/practiceproblems/RomanToInteger.java b/src/practiceproblems/RomanToInteger.java new file mode 100644 index 0000000..8abd50c --- /dev/null +++ b/src/practiceproblems/RomanToInteger.java @@ -0,0 +1,34 @@ +package practiceproblems; + +import java.util.*; + +public class RomanToInteger { + + public int romanToInteger(String s) { + Map map = new HashMap(); + + map.put('I', 1); + map.put('V', 5); + map.put('X', 10); + map.put('L', 50); + map.put('C', 100); + map.put('D', 500); + map.put('M', 1000); + + int sum = map.get(s.charAt(s.length() - 1)); + for (int i = s.length() - 2; i >= 0; --i) { + if (map.get(s.charAt(i)) < map.get(s.charAt(i + 1))) { + sum -= map.get(s.charAt(i)); + } else { + sum += map.get(s.charAt(i)); + } + } + return sum; + + } + + public static void main(String[] args) { + new RomanToInteger().romanToInteger("LIX"); + } + +} \ No newline at end of file diff --git a/src/practiceproblems/RotateArray.java b/src/practiceproblems/RotateArray.java new file mode 100644 index 0000000..7eb85af --- /dev/null +++ b/src/practiceproblems/RotateArray.java @@ -0,0 +1,30 @@ +package practiceproblems; +/** + * Given an array, rotate the array to the right by k steps, where k is + * non-negative Could you do it in-place with O(1) extra space? + * + * + * Example 1: + * + * Input: nums = [1,2,3,4,5,6,7], k = 3 Output: [5,6,7,1,2,3,4] Explanation: + * rotate 1 steps to the right: [7,1,2,3,4,5,6] rotate 2 steps to the right: + * [6,7,1,2,3,4,5] rotate 3 steps to the right: [5,6,7,1,2,3,4] + */ +public class RotateArray { + public void rotate(int[] nums, int k) { + k %= nums.length; + reverse(nums, 0, nums.length - 1); + reverse(nums, 0, k - 1); + reverse(nums, k, nums.length - 1); + } + + public void reverse(int[] nums, int start, int end) { + while (start < end) { + int temp = nums[start]; + nums[start] = nums[end]; + nums[end] = temp; + start++; + end--; + } + } +} \ No newline at end of file diff --git a/src/practiceproblems/RotateMatrixInPlace.java b/src/practiceproblems/RotateMatrixInPlace.java new file mode 100644 index 0000000..e6bf289 --- /dev/null +++ b/src/practiceproblems/RotateMatrixInPlace.java @@ -0,0 +1,102 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/inplace-rotate-square-matrix-by-90-degrees/ + */ +// looking for easy solution +class RotateMatrixInPlace { + + /** + * N/2 for time complexity o(n) + *

+ * get all the corners first and swap ( rotate 90 degree) + * + * @param N + * @param mat + */ + static void rotateMatrix(int N, int mat[][]) { + // Consider all squares one by one + for (int x = 0; x < N / 2; x++) { + // Consider elements in group of 4 in + // current square + for (int y = x; y < N - x - 1; y++) { + // store current cell in temp variable + System.out.println("mat[" + x + "][" + y + "] = " + mat[x][y]); + int temp = mat[x][y]; + + // move values from right to top + System.out.println("mat[" + y + "][" + (N - 1 - x) + "] = " + mat[y][N - 1 - x]); + mat[x][y] = mat[y][N - 1 - x]; + + // move values from bottom to right + System.out.println("mat[" + (N - 1 - x) + "][" + (N - 1 - y) + "] = " + mat[N - 1 - x][N - 1 - y]); + mat[y][N - 1 - x] = mat[N - 1 - x][N - 1 - y]; + + // move values from left to bottom + System.out.println("mat[" + (N - 1 - y) + "][" + (x) + "] = " + mat[N - 1 - y][x]); + mat[N - 1 - x][N - 1 - y] = mat[N - 1 - y][x]; + + // assign temp to left + System.out.println("mat[" + (N - 1 - y) + "][" + (x) + "] = " + temp); + mat[N - 1 - y][x] = temp; + } + } + } + + public void rotate(int[][] matrix) { + if(matrix == null || matrix.length == 0 || matrix[0].length == 0)return; + int n= matrix.length-1; + + for(int i=0; i + * https://leetcode.com/problems/rotate-image/discuss/298719/A-Java-one-pass-solution-with-detailed-explanation + *

+ * //x,y1=x2,y2 + * // x1=y2 + */ +class RotateMatrixInPlaceAntiClockwise { + + static void rotateMatrix(int N, int mat[][]) { + + for (int x = 0; x < N / 2; x++) { + + for (int y = x; y < N - x; y++) { + + // store current cell in temp variable + int temp = mat[x][y]; + + // move values from right to top + mat[x][y] = mat[y][N - x]; + + // move values from bottom to right + mat[y][N - x] = mat[N - x][N - y]; + + // move values from left to bottom + mat[N - x][N - y] = mat[N - y][x]; + + // assign temp to left + mat[N - y][x] = temp; + } + } + } + + static void displayMatrix(int N, int mat[][]) { + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) + System.out.print(" " + mat[i][j]); + + System.out.print("\n"); + } + System.out.print("\n"); + } + + public static void main(String[] args) { + int N = 4; + + // Test Case 1 + int mat[][] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } }; + + // int mat[][] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; + // int mat[][] = { {1, 2}, {4, 5} }; + + // displayMatrix(mat); + + rotateMatrix(N - 1, mat); + + // Print rotated matrix + displayMatrix(N, mat); + } +} \ No newline at end of file diff --git a/src/practiceproblems/SameTree.java b/src/practiceproblems/SameTree.java new file mode 100644 index 0000000..72b456d --- /dev/null +++ b/src/practiceproblems/SameTree.java @@ -0,0 +1,62 @@ +package practiceproblems; + +import java.util.ArrayDeque; + +/** + * Given two binary trees, write a function to check if they are the same or not. + * Two binary trees are considered the same if they are structurally identical and the nodes have the same value. +Input: 1 1 + / \ / \ + 2 1 1 2 + + [1,2,1], [1,1,2] + +Output: false + */ +public class SameTree { + public boolean check(TreeNode p, TreeNode q) { + // p and q are null + if (p == null || q == null) return p==q; + if (p.val != q.val) return false; + return true; + } + + public boolean isSameTree(TreeNode p, TreeNode q) { + if (p == null && q == null) return true; + if (!check(p, q)) return false; + + // init deques + ArrayDeque deqP = new ArrayDeque(); + ArrayDeque deqQ = new ArrayDeque(); + deqP.addLast(p); + deqQ.addLast(q); + + while (!deqP.isEmpty()) { + p = deqP.removeFirst(); + q = deqQ.removeFirst(); + + if (!check(p, q)) return false; + if (p != null) { + // in Java nulls are not allowed in Deque + if (!check(p.left, q.left)) return false; + if (p.left != null) { + deqP.addLast(p.left); + deqQ.addLast(q.left); + } + if (!check(p.right, q.right)) return false; + if (p.right != null) { + deqP.addLast(p.right); + deqQ.addLast(q.right); + } + } + } + return true; + } + + public boolean isSameTreeRecur(TreeNode p, TreeNode q){ + if(p==null || q==null) return p==q; + if(p.val==q.val) return true; + + return isSameTreeRecur(p.left, q.left) && isSameTreeRecur(p.right, q.right); + } +} \ No newline at end of file diff --git a/src/practiceproblems/SearchAMaze.java b/src/practiceproblems/SearchAMaze.java new file mode 100644 index 0000000..c701597 --- /dev/null +++ b/src/practiceproblems/SearchAMaze.java @@ -0,0 +1,80 @@ +package practiceproblems; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * https://www.techiedelight.com/lee-algorithm-shortest-path-in-a-maze/ + */ +public class SearchAMaze { + + private static final int M = 10; + private static final int N = 10; + + private static final int row[] = { -1, 0, 0, 1 }; + private static final int col[] = { 0, -1, 1, 0 }; + + private static boolean isValid(int mat[][], int row, int col) { + return (row >= 0) && (row < M) && (col >= 0) && (col < N) && mat[row][col] == 1; + } + + private static void BFS(int mat[][], int srcX, int srcY, int destX, int destY) { + + Queue q = new LinkedList<>(); + + q.add(new MazeNode(srcX, srcY, 0)); + + int minDist = Integer.MAX_VALUE; + + while (!q.isEmpty()) { + MazeNode node = q.poll(); + + srcX = node.x; + srcY = node.y; + int dist = node.dist; + + if (srcX == destX && srcY == destY) { + minDist = dist; + break; + } + + for (int k = 0; k < 4; k++) { + if (isValid(mat, srcX + row[k], srcY + col[k])) { + mat[srcX][srcY] = 0; + MazeNode e = new MazeNode(srcX + row[k], srcY + col[k], dist + 1); + q.add(e); + System.out.println(" Adding to the queue :" + e); + } + } + } + + if (minDist != Integer.MAX_VALUE) { + System.out.print("The shortest path from source to destination " + "has length " + minDist); + } else { + System.out.print("Destination can't be reached from source"); + } + } + + public static void main(String[] args) { + int[][] mat = { { 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 }, { 0, 1, 1, 1, 1, 1, 0, 1, 0, 1 }, + { 0, 0, 1, 0, 1, 1, 1, 0, 0, 1 }, { 1, 0, 1, 1, 1, 0, 1, 1, 0, 1 }, { 0, 0, 0, 1, 0, 0, 0, 1, 0, 1 }, + { 1, 0, 1, 1, 1, 0, 0, 1, 1, 1 }, { 0, 0, 0, 0, 1, 0, 0, 1, 0, 1 }, { 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, + { 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 }, { 0, 0, 1, 0, 0, 1, 1, 0, 0, 1 } }; + + BFS(mat, 8, 0, 0, 9); + } +} + +class MazeNode { + int x, y, dist; + + MazeNode(int x, int y, int dist) { + this.x = x; + this.y = y; + this.dist = dist; + } + + public String toString() { + return "(" + x + "," + y + ") -> " + dist; + } +}; \ No newline at end of file diff --git a/src/practiceproblems/SearchAnElementInMatrix.java b/src/practiceproblems/SearchAnElementInMatrix.java new file mode 100644 index 0000000..cd6fc4a --- /dev/null +++ b/src/practiceproblems/SearchAnElementInMatrix.java @@ -0,0 +1,74 @@ +package practiceproblems; + +/** + * https://www.youtube.com/watch?v=FOa55B9Ikfg + * https://leetcode.com/problems/search-a-2d-matrix-ii/ + * https://leetcode.com/problems/search-a-2d-matrix/ + */ + +public class SearchAnElementInMatrix { + + private static boolean searchII(int[][] mat, int n, int x) { + + int i = 0; + int j = n - 1; // set indexes for top right element + // we can start from top right corner or bottom left corner, because from + // these points only we have 2 paths one increasing one decreasing + while (i < n && j >= 0) { + if (mat[i][j] == x) { + System.out.print("n Found at " + i + " " + j); + return true; + } + if (mat[i][j] > x) { + j--; + } else // if mat[i][j] < x + { + i++; + } + } + + System.out.print("n Element not found"); + return false; + + } + + public static boolean searchI(int[][] matrix, int target) { + if (matrix == null || matrix.length == 0) { + return false; + } + int start = 0; + int rows = matrix.length; + int cols = matrix[0].length; + int end = rows * cols - 1; + while (start <= end) { + int mid = (start + end) / 2; + /** + * Another way to took at it is: lets say you have a matrix M with 4 rows and 3 columns. + * When we want to access M[2][1], the way the memory address is calculated is 2*3+1 = 7. + * so you are just reversing the calculation , row number is given by 7/3 = 2, + * and column is the offset in that row so for 7th element it is 7%3 = 1. + * This link helped me understand it. https://www.youtube.com/watch?v=n5KNdUAftC4 + */ + if (matrix[mid / cols][mid % cols] == target) { + return true; + } + if (matrix[mid / cols][mid % cols] < target) { + start = mid + 1; + } else { + end = mid - 1; + } + } + return false; + } + + public static void main(String[] args) { + int[][] mat = {{10, 20, 30, 40}, {15, 25, 35, 45}, {27, 29, 37, 48}, {32, 33, 39, 50}}; + + int[][] matI = {{1, 3, 5, 7}, {10, 11, 16, 20}, {23, 30, 34, 50}}; + + System.out.println(searchI(matI, 11)); + System.out.println(searchII(mat, 4, 33)); + + } + +} diff --git a/src/practiceproblems/SerializeAndDeserialize.java b/src/practiceproblems/SerializeAndDeserialize.java new file mode 100644 index 0000000..607ba6b --- /dev/null +++ b/src/practiceproblems/SerializeAndDeserialize.java @@ -0,0 +1,80 @@ +package practiceproblems; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.Queue; + +/* + Serialize and Deserialize Binary Tree - LeetCode: + https://leetcode.com/problems/serialize-and-deserialize-binary-tree/ + + This code passes all Leetcode test cases as of April 26 2019 + Runtime: 12 ms, faster than 62.25% of Java online submissions for Serialize and Deserialize Binary Tree. + Memory Usage: 39.4 MB, less than 71.37% of Java online submissions for Serialize and Deserialize Binary Tree. + + The video to explain this code is here: https://www.youtube.com/watch?v=suj1ro8TIVY +*/ + +public class SerializeAndDeserialize { + + private static final String NULL_SYMBOL = "X"; + private static final String DELIMITER = ","; + + public String serialize(TreeNode root) { + + if (root == null) { + return NULL_SYMBOL + DELIMITER; + } + + String leftSerialized = serialize(root.left); + String rightSerialized = serialize(root.right); + + return root.val + DELIMITER + leftSerialized + rightSerialized; + } + + public TreeNode deserialize(String data) { + Queue nodesLeftToMaterialize = new LinkedList<>(); + nodesLeftToMaterialize.addAll(Arrays.asList(data.split(DELIMITER))); + return deserializeHelper(nodesLeftToMaterialize); + } + + public TreeNode deserializeHelper(Queue nodesLeftToMaterialize) { + + String valueForNode = nodesLeftToMaterialize.poll(); + + if (valueForNode.equals(NULL_SYMBOL)) { + return null; + } + + TreeNode newNode = new TreeNode(Integer.parseInt(valueForNode)); + newNode.left = deserializeHelper(nodesLeftToMaterialize); + newNode.right = deserializeHelper(nodesLeftToMaterialize); + + return newNode; + } + + public static void main(String[] args) { + TreeNode root = new TreeNode(1); + root.left = new TreeNode(2); + root.right = new TreeNode(3); + root.right.left = new TreeNode(4); + root.right.right = new TreeNode(5); + SerializeAndDeserialize sede = new SerializeAndDeserialize(); + String serialize = sede.serialize(root); + System.out.println(serialize); + TreeNode deserialze = sede.deserialize(serialize); + sede.printTree(deserialze); + } + + public void printTree(TreeNode node) { + if (node == null) { + System.out.print("X,"); + return; + } + System.out.print(node.val + ","); + printTree(node.left); + printTree(node.right); + } + +} + diff --git a/src/practiceproblems/SerializeDeserializeBST.java b/src/practiceproblems/SerializeDeserializeBST.java new file mode 100644 index 0000000..a970bb5 --- /dev/null +++ b/src/practiceproblems/SerializeDeserializeBST.java @@ -0,0 +1,76 @@ +package practiceproblems; + +// Hi all, I think my solution is pretty straightforward and easy to understand, not that efficient though. And the serialized tree is compact. +// Pre order traversal of BST will output root node first, then left children, then right. + +// root left1 left2 leftX right1 rightX +// If we look at the value of the pre-order traversal we get this: + +// rootValue (rootValue) (>rootValue) +// Because of BST's property: before the |separate line| all the node values are less than root value, all the node values after |separate line| are greater than root value. We will utilize this to build left and right tree. + +import java.util.*; + +class SerializeDeserializeBST { + private static final String SEP = ","; + private static final String NULL = "null"; + // Encodes a tree to a single string. + + public String serialize(TreeNode root) { + + if (root == null) { + return NULL + SEP; + } + + String leftSerialized = serialize(root.left); + String rightSerialized = serialize(root.right); + + return root.val + SEP + leftSerialized + rightSerialized; + } + + public String serializeIterative(TreeNode root) { + StringBuilder sb = new StringBuilder(); + if (root == null) return NULL; + //traverse it recursively if you want to, I am doing it iteratively here + Deque st = new ArrayDeque<>(); + st.push(root); + while (!st.isEmpty()) { + root = st.pop(); + sb.append(root.val).append(SEP); + if (root.right != null) st.push(root.right); + if (root.left != null) st.push(root.left); + } + return sb.toString(); + } + + // Decodes your encoded data to tree. + // pre-order traversal + public TreeNode deserialize(String data) { + if (data.equals(NULL)) return null; + String[] strs = data.split(SEP); + Queue q = new LinkedList<>(); + for (String e : strs) { + q.offer(Integer.parseInt(e)); + } + return getNode(q); + } + + // some notes: + // 5 + // 3 6 + // 2 7 + private TreeNode getNode(Queue q) { //q: 5,3,2,6,7 + if (q.isEmpty()) return null; + TreeNode root = new TreeNode(q.poll());//root (5) + Queue samllerQueue = new LinkedList<>(); + while (!q.isEmpty() && q.peek() < root.val) { + samllerQueue.offer(q.poll()); + } + //smallerQueue : 3,2 storing elements smaller than 5 (root) + root.left = getNode(samllerQueue); + //q: 6,7 storing elements bigger than 5 (root) + root.right = getNode(q); + return root; + } + +} \ No newline at end of file diff --git a/src/practiceproblems/SetBitCount.java b/src/practiceproblems/SetBitCount.java new file mode 100644 index 0000000..e7872bd --- /dev/null +++ b/src/practiceproblems/SetBitCount.java @@ -0,0 +1,21 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/number-of-1-bits/discuss/55099/Simple-Java-Solution-Bit-Shifting + */ +public class SetBitCount { + public static int hammingWeight(int n) { + int count = 0; + + while (n != 0) { + n &= (n - 1); + count++; + } + + return count; + } + + public static void main(String[] args) { + System.out.println(hammingWeight(00000000000000000000000000001011)); + } +} diff --git a/src/practiceproblems/ShuffleArray.java b/src/practiceproblems/ShuffleArray.java new file mode 100644 index 0000000..ddf9ee0 --- /dev/null +++ b/src/practiceproblems/ShuffleArray.java @@ -0,0 +1,53 @@ +package practiceproblems; + +import java.util.Arrays; +import java.util.Random; + +/** + * https://leetcode.com/problems/shuffle-an-array/ + */ +public class ShuffleArray { + + private int[] nums; + private Random random; + + public ShuffleArray(int[] nums) { + this.nums = nums; + random = new Random(); + } + + /** + * Resets the array to its original configuration and return it. + */ + public int[] reset() { + return nums; + } + + /** + * Returns a random shuffling of the array. + */ + public int[] shuffle() { + if (nums == null) { + return null; + } + int[] a = nums.clone(); + for (int j = 1; j < a.length; j++) { + int i = random.nextInt(j + 1); + swap(a, i, j); + } + return a; + } + + private void swap(int[] a, int i, int j) { + int t = a[i]; + a[i] = a[j]; + a[j] = t; + } + + public static void main(String[] args) { + int[] arr = { 1, 2, 3 }; + ShuffleArray sa = new ShuffleArray(arr); + System.out.println("After shuffling :" + Arrays.toString(sa.shuffle())); + System.out.println("Reset : " + Arrays.toString(sa.reset())); + } +} diff --git a/src/practiceproblems/SimilarExpressions.java b/src/practiceproblems/SimilarExpressions.java new file mode 100644 index 0000000..b224769 --- /dev/null +++ b/src/practiceproblems/SimilarExpressions.java @@ -0,0 +1,55 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/check-two-expressions-brackets/ + */ +//unresolved +public class SimilarExpressions { + + public static void main(String[] args) { + + System.out.println('+' * '-'); + + String query = "-(a+b+c)"; + String response = "-a-b-c"; + + checkExpression(query.toCharArray(), response.toCharArray()); + } + + private static void checkExpression(char[] query, char[] response) { + + char symbol = 0; + int startIndex = 0; + int endIndex = 0; + for (int i = 0; i < query.length; i++) { + if (query[i] == '(') { + symbol = query[i - 1]; + startIndex = i + 1; + } else if (query[i] == ')') { + endIndex = i - 1; + solve(symbol, startIndex, endIndex, query); + + } + } + } + + private static void solve(char symbol, int startIndex, int endIndex, char[] query) { + + for (int i = startIndex; i <= endIndex; i++) { + char temp = 0; + if (query[startIndex] == '-') { + temp = '-' * '+'; + query[i] = temp; + } else if (symbol == '+') { + temp = '-'; + query[i] = temp; + } else if (Character.isLetter(query[startIndex])) { + if (startIndex == i) { + query[startIndex - 1] = temp; + } + System.out.print(query[startIndex]); + } + System.out.print(temp); + } + } +} \ No newline at end of file diff --git a/src/practiceproblems/SingleElementInSortedArray.java b/src/practiceproblems/SingleElementInSortedArray.java new file mode 100644 index 0000000..a9ba2f3 --- /dev/null +++ b/src/practiceproblems/SingleElementInSortedArray.java @@ -0,0 +1,44 @@ +package practiceproblems; + +/** + * You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once. + * Find this single element that appears only once. + */ +public class SingleElementInSortedArray { + public int singleNonDuplicate(int[] nums) { + if (nums == null || nums.length == 0) return 0; + + int left = 0; + int right = nums.length - 1; + // for 1,1,2,3,3,4,4,8,8 + // when mid is at 4 and right-mid is even, means the rest elements are only pairs, so we check + // left side by right=mid-2 + // when mid is at 3 and right-mid is odd means the 3's duplicate is present in right and rest + //are all pairs only so we check left side by right=mid-1 + // when mid is 4 => nums[mid]==nums[mid-1] + // when mid is 3 => nums[mid]==nums[mid+1] + while (left < right) { + int mid = left + (right - left) / 2; + boolean isEven = (right - mid) % 2 == 0; + + if (nums[mid] == nums[mid - 1]) { + if (isEven) { + right = mid - 2; + } else { + left = mid + 1; + } + } else if (nums[mid] == nums[mid + 1]) { + if (isEven) { + left = mid + 2; + } else { + right = mid - 1; + } + } else { + return nums[mid]; + } + + } + + return nums[left]; + } +} \ No newline at end of file diff --git a/src/practiceproblems/SlidingWindow.java b/src/practiceproblems/SlidingWindow.java new file mode 100644 index 0000000..4377ea0 --- /dev/null +++ b/src/practiceproblems/SlidingWindow.java @@ -0,0 +1,74 @@ +package practiceproblems; + +import java.util.Deque; +import java.util.*; + +/** + * https://leetcode.com/problems/sliding-window-maximum/ + */ +public class SlidingWindow { + + public static void main(String[] args) { + int arr[] = { 8, 5, 10, 7, 9, 4, 15, 12, 90, 13 }; + int k = 3; + maxSlidingWindow(arr, k); + } + + public static int[] maxSlidingWindow(int[] nums, int k) { + if (nums.length == 0) { + return new int[0]; + } + if (nums.length == 1) { + return nums; + } + + List list = new ArrayList<>(); + Deque deque = new ArrayDeque<>(); + int i = 0; + + while (i < k) { + + while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) { + deque.removeLast(); + } + deque.addLast(i); + i++; + } + + for (; i < nums.length; i++) { + + list.add(nums[deque.peekFirst()]); + + if (!deque.isEmpty() && deque.peekFirst() <= i - k) { + deque.removeFirst(); + } + + while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) + deque.removeLast(); + + deque.addLast(i); + } + list.add(nums[deque.peekFirst()]); + + return list.stream().mapToInt(Integer::new).toArray(); + } + + void maxSlidingVicky(int[] nums, int k) { + List result = new ArrayList<>(); + Deque queue = new ArrayDeque<>(); + for (int i = 0; i < nums.length; i++) { + while (!queue.isEmpty() && queue.peek() < i - k + 1) { + queue.poll(); + } + while (!queue.isEmpty() && nums[queue.peekLast()] < nums[i]) { + queue.pollLast(); + } + + queue.offer(i); + + if (i >= k - 1) { + result.add(nums[queue.peekFirst()]); + } + } + } +} \ No newline at end of file diff --git a/src/practiceproblems/SnakeAndLadder.java b/src/practiceproblems/SnakeAndLadder.java new file mode 100644 index 0000000..2973bd6 --- /dev/null +++ b/src/practiceproblems/SnakeAndLadder.java @@ -0,0 +1,70 @@ +package practiceproblems; + +import java.util.Queue; +import java.util.*; + +/** + * https://leetcode.com/problems/snakes-and-ladders/ + */ +public class SnakeAndLadder { + class BoardCells { + int pos; + int steps; + + public BoardCells(int pos, int steps) { + this.pos = pos; + this.steps = steps; + } + } + + private int n; + + public int snakesAndLadders(int[][] board) { + n = board.length; + boolean[] visited = new boolean[n * n + 1]; + Queue queue = new LinkedList<>(); + queue.offer(new BoardCells(1, 1)); + visited[1] = true; + + while (!queue.isEmpty()) { + BoardCells cur = queue.poll(); + for (int i = 1; i <= 6; i++) { + int next = cur.pos + i; + int[] pos = numToPos(next); + if (board[pos[0]][pos[1]] > 0) { + next = board[pos[0]][pos[1]]; + } + if (next == n * n) { + return cur.steps; + } + if (!visited[next]) { + queue.offer(new BoardCells(next, cur.steps + 1)); + visited[next] = true; + } + } + + } + return queue.peek().steps; + } + + private int[] numToPos(int target) { + int row = (target - 1) / n, col = (target - 1) % n; + int x = n - 1 - row, y = row % 2 == 0 ? col : n - 1 - col; + return new int[] { x, y }; + } + + private int posToNum(int[] position) { + int row = (n - 1 - position[0]); + int y = row % 2 == 0 ? position[1] + 1 : n - position[1]; + return row * n + y; + } + + public static void main(String[] args) { + + int[][] board = { { -1, -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1, -1 }, + { -1, 35, -1, -1, 13, -1 }, { -1, -1, -1, -1, -1, -1 }, { -1, 15, -1, -1, -1, -1 } }; + + System.out.println("Min Dice throws required is " + new SnakeAndLadder().snakesAndLadders(board)); + + } +} \ No newline at end of file diff --git a/src/practiceproblems/SnakeGame.java b/src/practiceproblems/SnakeGame.java new file mode 100644 index 0000000..bb6a32a --- /dev/null +++ b/src/practiceproblems/SnakeGame.java @@ -0,0 +1,88 @@ +package practiceproblems; + +import java.util.HashSet; +import java.util.LinkedList; + +public class SnakeGame { + int[][] food; + int m, n; + int headX, headY; + int eaten; + private HashSet snake; + LinkedList queue; + + /** + * Initialize your data structure here. + * + * @param width - screen width + * @param height - screen height + * @param food - A list of food positions + * E.g food = [[1,1], [1,0]] means the first food is positioned at [1,1], the second is at [1,0]. + */ + public SnakeGame(int width, int height, int[][] food) { + this.food = food; + snake = new HashSet(); + eaten = 0; + headX = 0; + headY = 0; + m = height; + n = width; + queue = new LinkedList(); + queue.offer(new int[]{0, 0}); + snake.add("0,0"); + } + + /** + * Moves the snake. + * + * @param direction - 'U' = Up, 'L' = Left, 'R' = Right, 'D' = Down + * @return The game's score after the move. Return -1 if game over. + * Game over when snake crosses the screen boundary or bites its body. + */ + public int move(String direction) { + if (direction.equals("U")) { + headX--; + } else if (direction.equals("L")) { + headY--; + } else if (direction.equals("R")) { + headY++; + } else if (direction.equals("D")) { + headX++; + } else { + System.out.println("Wrong move"); + } + + if (!isValid(headX, headY)) { + return -1; + } + + return process(headX, headY); + } + + public boolean isValid(int i, int j) { + if (i < 0 || i >= m || j < 0 || j >= n) + return false; + return true; + } + + public int process(int x, int y) { + if (eaten == food.length) { + snake.remove(queue.peek()[0] + "," + queue.peek()[1]); + queue.poll(); + } else if (food[eaten][0] == x && food[eaten][1] == y) { + eaten++; + } else { + snake.remove(queue.peek()[0] + "," + queue.peek()[1]); + queue.poll(); + } + + if (snake.contains(x + "," + y)) { + return -1; + } + + snake.add(x + "," + y); + queue.offer(new int[]{x, y}); + + return eaten; + } +} \ No newline at end of file diff --git a/src/practiceproblems/SortANearlySortedArray.java b/src/practiceproblems/SortANearlySortedArray.java new file mode 100644 index 0000000..4f8c092 --- /dev/null +++ b/src/practiceproblems/SortANearlySortedArray.java @@ -0,0 +1,40 @@ +package practiceproblems; + +import java.util.Arrays; +import java.util.List; +import java.util.PriorityQueue; + +/*https://www.techiedelight.com/sort-k-sorted-array/*/ +class SortANearlySortedArray { + + public static void sortKSortedArray(List list, int k) { + // create an empty min heap and insert first k+1 elements in the heap + PriorityQueue pq = new PriorityQueue<>(list.subList(0, k + 1)); + + int index = 0; + + for (int i = k + 1; i < list.size(); i++) { + // pop top element from min-heap and assign it to + // next available array index + list.set(index++, pq.poll()); + + // push next array element into min-heap + pq.add(list.get(i)); + } + + // pop all remaining elements from the min heap and assign it to + // next available array index + while (!pq.isEmpty()) { + list.set(index++, pq.poll()); + } + } + + + public static void main(String[] args) { + List list = Arrays.asList(1, 4, 5, 2, 3, 7, 8, 6, 10, 9); + int k = 2; + + sortKSortedArray(list, k); + System.out.println(list); + } +} \ No newline at end of file diff --git a/src/practiceproblems/SortStack.java b/src/practiceproblems/SortStack.java new file mode 100644 index 0000000..b5146e7 --- /dev/null +++ b/src/practiceproblems/SortStack.java @@ -0,0 +1,31 @@ +package practiceproblems; + +import java.util.Stack; + +class SortStack { + // Input : [34, 3, 31, 98, 92, 23] + // Output : [3, 23, 31, 34, 92, 98] + public static Stack sortStack(Stack input) { + /* If input is null, no processing needed */ + if (input == null) { + return null; + } + /* Create a temp stack */ + Stack tempStack = new Stack<>(); + /* Keep going until input is not empty */ + while (!input.isEmpty()) { + /* Pop value from input */ + int tempValue = input.pop(); + /* + * We want smallest one at the bottom. So keep comparing and if temp stack has + * bigger item, pop it and push it to input stack + */ + while (!tempStack.isEmpty() && tempStack.peek() > tempValue) { + input.push(tempStack.pop()); + } + /* Push temp value to the temp stack */ + tempStack.push(tempValue); + } + return tempStack; + } +} \ No newline at end of file diff --git a/src/practiceproblems/SortedArrayToBST.java b/src/practiceproblems/SortedArrayToBST.java new file mode 100644 index 0000000..9071bcf --- /dev/null +++ b/src/practiceproblems/SortedArrayToBST.java @@ -0,0 +1,39 @@ +package practiceproblems; + +public class SortedArrayToBST { + + static class Node { + int data; + Node left; + Node right; + + public Node(int data) { + this.data = data; + } + } + + public static void main(String[] args) { + int[] arr = {1, 2, 3, 4, 5, 6}; + Node node = bst(arr, 0, arr.length - 1); + printTree(node); + } + + public static Node bst(int[] arr, int start, int end) { + if (end < start) + return null; + int mid = start + ((end - start) / 2); + Node root = new Node(arr[mid]); + root.left = bst(arr, start, mid - 1); + root.right = bst(arr, mid + 1, end); + return root; + } + + public static void printTree(Node node) { + if (node == null) + return; + printTree(node.left); + System.out.println(node.data); + printTree(node.right); + + } +} \ No newline at end of file diff --git a/src/practiceproblems/SortedSquares.java b/src/practiceproblems/SortedSquares.java new file mode 100644 index 0000000..abd3aa8 --- /dev/null +++ b/src/practiceproblems/SortedSquares.java @@ -0,0 +1,28 @@ +package practiceproblems; + +public class SortedSquares { + // Input: [-7,-3,2,3,11] + // Output: [4,9,9,49,121] + public int[] sortedSquares(int[] A) { + if(A==null || A.length==0) return new int[0]; + + int[]result= new int[A.length]; + + int index= A.length-1; + int left=0; + int right=index; + + while(left<=right){ + if(Math.abs(A[left]) spiralOrder(int[][] matrix) { + + List res = new ArrayList(); + + if (matrix.length == 0) { + return res; + } + + int rowBegin = 0; + int rowEnd = matrix.length-1; + int colBegin = 0; + int colEnd = matrix[0].length - 1; + + while (rowBegin <= rowEnd && colBegin <= colEnd) { + // Traverse Right + for (int j = colBegin; j <= colEnd; j ++) { + System.out.println(" Right "+matrix[rowBegin][j]); + res.add(matrix[rowBegin][j]); + } + rowBegin++; + + // Traverse Down + for (int j = rowBegin; j <= rowEnd; j ++) { + System.out.println(" Down "+matrix[j][colEnd]); + res.add(matrix[j][colEnd]); + } + colEnd--; + + if (rowBegin <= rowEnd) { // without this condition, this corner test case [[2,3]] would print [2,3,2] + // Traverse Left + for (int j = colEnd; j >= colBegin; j --) { + System.out.println(" Left "+matrix[rowEnd][j]); + res.add(matrix[rowEnd][j]); + } + } + rowEnd--; + + // this block's work is to move 1 row up from bottom + // the rest of the work will be done by first 'Right' loop again + if (colBegin <= colEnd) { + // Traver Up + for (int j = rowEnd; j >= rowBegin; j --) { + System.out.println(" uppp "+matrix[j][colBegin]); + res.add(matrix[j][colBegin]); + } + } + colBegin ++; + } + + return res; + } + + public static void main(String[] args) { + + int a[][] = {{1, 2, 3, 4}, + {5, 6, 7, 8}, + {9, 10, 11, 12}, + {13, 14, 15, 16}}; + spiralOrder(a); + } +} \ No newline at end of file diff --git a/src/practiceproblems/SpiralMatrixII.java b/src/practiceproblems/SpiralMatrixII.java new file mode 100644 index 0000000..8b37806 --- /dev/null +++ b/src/practiceproblems/SpiralMatrixII.java @@ -0,0 +1,56 @@ +package practiceproblems; + +import java.util.Arrays; + +public class SpiralMatrixII { + + public static int[][] generateMatrix(int n) { + // Declaration + int[][] matrix = new int[n][n]; + + // Edge Case + if (n == 0) { + return matrix; + } + + + // Normal Case + int rowStart = 0; + int rowEnd = n - 1; + int colStart = 0; + int colEnd = n - 1; + int num = 1; // change + + while (rowStart <= rowEnd && colStart <= colEnd) { + for (int i = colStart; i <= colEnd; i++) { + matrix[rowStart][i] = num++; // change + } + rowStart++; + + for (int i = rowStart; i <= rowEnd; i++) { + matrix[i][colEnd] = num++; // change + } + colEnd--; + + for (int i = colEnd; i >= colStart; i--) { + if (rowStart <= rowEnd) + matrix[rowEnd][i] = num++; // change + } + rowEnd--; + + for (int i = rowEnd; i >= rowStart; i--) { + if (colStart <= colEnd) + matrix[i][colStart] = num++; // change + } + colStart++; + + System.out.println(Arrays.deepToString(matrix)); + } + + return matrix; + } + + public static void main(String[] args) { + generateMatrix(4); + } +} diff --git a/src/practiceproblems/SplitLinkedList.java b/src/practiceproblems/SplitLinkedList.java new file mode 100644 index 0000000..696170f --- /dev/null +++ b/src/practiceproblems/SplitLinkedList.java @@ -0,0 +1,47 @@ +package practiceproblems; + +//https://leetcode.com/problems/split-linked-list-in-parts/ +class SplitLinkedList { + + public ListNode[] splitListToParts(ListNode root, int k) { + ListNode[] partsOfRoot = new ListNode[k]; + ListNode head = root; + int len = size(root); + int minNoOfElements = len / k; + int extraRoomForElement = len % k; + ListNode prev = null; + for (int i = 0; i < k && head != null; i++, extraRoomForElement--) { + partsOfRoot[i] = head; + for (int j = 0; j < minNoOfElements + (extraRoomForElement > 0 ? 1 : 0); j++) { + prev = head; + head = head.next; + } + prev.next = null; + } + return partsOfRoot; + + } + + public int size(ListNode root) { + int len = 0; + while (root != null) { + root = root.next; + len++; + } + return len; + } + + public static void main(String[] args) { + ListNode root = new ListNode(1); + root.next = new ListNode(2); + root.next.next = new ListNode(3); + root.next.next.next = new ListNode(4); + root.next.next.next.next = new ListNode(5); + root.next.next.next.next.next = new ListNode(6); + root.next.next.next.next.next.next = new ListNode(7); + root.next.next.next.next.next.next.next = new ListNode(8); + root.next.next.next.next.next.next.next.next = new ListNode(9); + root.next.next.next.next.next.next.next.next.next = new ListNode(10); + new SplitLinkedList().splitListToParts(root, 3); + } +} diff --git a/src/practiceproblems/StockBuySellManyTimes.java b/src/practiceproblems/StockBuySellManyTimes.java new file mode 100644 index 0000000..103ea0d --- /dev/null +++ b/src/practiceproblems/StockBuySellManyTimes.java @@ -0,0 +1,84 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.List; + +class Interval { + int buy, sell; + int start; // for meeting problem + int end; + Interval(int buy, int sell){ + this.buy=buy; + this.sell=sell; + } + Interval(){ + + } +} + +/** + * https://www.geeksforgeeks.org/stock-buy-sell/ + */ +// unresolved +class StockBuySellManyTimes { + + //200, 180, 260, 310, 40, 535, 695 + void stockBuySell(int price[], int n) { + // Prices must be given for at least two days + if (n == 1) { + return; + } + + int count = 0; + + List result = new ArrayList<>(); + + int i = 0; + while (i < n - 1) { + // Find Local Minima. Note that the limit is (n-2) as we are + // comparing present element to the next element. + while ((i < n - 1) && (price[i + 1] <= price[i])) + i++; + + // If we reached the end, break as no further solution possible + if (i == n - 1) { + break; + } + + Interval e = new Interval(); + e.buy = i++; + // Store the index of minima + + // Find Local Maxima. Note that the limit is (n-1) as we are + // comparing to previous element + while ((i < n) && (price[i] >= price[i - 1])) + i++; + + // Store the index of maxima + e.sell = i - 1; + result.add(e); + + // Increment number of buy/sell + count++; + } + + if (count == 0) { + System.out.println("There is no day when buying the stock " + "will make profit"); + } else { + for (int j = 0; j < count; j++) + System.out.println( + "Buy on day: " + result.get(j).buy + " " + "Sell on day : " + result.get(j).sell); + } + + return; + } + + public static void main(String args[]) { + StockBuySellManyTimes stock = new StockBuySellManyTimes(); + + int price[] = { 200, 180, 260, 310, 40, 535, 695 }; + int n = price.length; + + stock.stockBuySell(price, n); + } +} diff --git a/src/practiceproblems/StockSpanner.java b/src/practiceproblems/StockSpanner.java new file mode 100644 index 0000000..58babe4 --- /dev/null +++ b/src/practiceproblems/StockSpanner.java @@ -0,0 +1,21 @@ +package practiceproblems; + + +class StockSpanner { +// +// Deque> stack; +// public StockSpanner() { +// this.stack= new ArrayDeque<>(); +// } +// +// public int next(int price) { +// int value=1; +// while(!stack.isEmpty() && stack.peek().fst<=price){ +// value+=stack.pop().snd; +// } +// +// stack.push(new Pair(price,value)); +// +// return stack.peek().snd; +// } +} \ No newline at end of file diff --git a/src/practiceproblems/StringIterator.java b/src/practiceproblems/StringIterator.java new file mode 100644 index 0000000..f7ecb37 --- /dev/null +++ b/src/practiceproblems/StringIterator.java @@ -0,0 +1,37 @@ +package practiceproblems; + +//StringIterator iterator = new StringIterator("L1e2t1C1o1d1e1"); +// iterator.next(); // return 'L' +// iterator.next(); // return 'e' +// iterator.next(); // return 'e' +// iterator.next(); // return 't' +// iterator.next(); // return 'C' +// iterator.next(); // return 'o' +// iterator.next(); // return 'd' +// iterator.hasNext(); // return true +// iterator.next(); // return 'e' +// iterator.hasNext(); // return false +// iterator.next(); // return ' ' +public class StringIterator { + String res; + int ptr = 0, num = 0; + char ch = ' '; + public StringIterator(String s) { + res = s; + } + public char next() { + if (!hasNext()) + return ' '; + if (num == 0) { + ch = res.charAt(ptr++); + while (ptr < res.length() && Character.isDigit(res.charAt(ptr))) { + num = num * 10 + res.charAt(ptr++) - '0'; + } + } + num--; + return ch; + } + public boolean hasNext() { + return ptr != res.length() || num != 0; + } +} \ No newline at end of file diff --git a/src/practiceproblems/SubArraySumDivisibleByK.java b/src/practiceproblems/SubArraySumDivisibleByK.java new file mode 100644 index 0000000..04057a1 --- /dev/null +++ b/src/practiceproblems/SubArraySumDivisibleByK.java @@ -0,0 +1,48 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.Map; + +/** + * Given an array A of integers, return the number of (contiguous, non-empty) + * subarrays that have a sum divisible by K. + * Input: A = [4,5,0,-2,-3,1], K = 5 + * Output: 7 + * Explanation: There are 7 subarrays with a sum divisible by K = 5: + * [4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3] + */ +public class SubArraySumDivisibleByK { + + public int subarraysDivByK(int[] A, int K) { + Map count = new HashMap<>(); + count.put(0, 1); //if the first prefix sum is 0, it need to be counted as a mod of K, right? + // Rest of prefix sum from 1 to K-1 don't include the first prefix sum + int prefix = 0, res = 0; + for (int a : A) { + //(prefix+a%K+K)%K is just a trick to make the remainder positive. + prefix = (prefix + a % K + K) % K; + res += count.getOrDefault(prefix, 0); + count.put(prefix, count.getOrDefault(prefix, 0) + 1); + } + return res; + } + + // A = [4,5,0,-2,-3,1], K = 5 + // step 1 : {0:1} a=4 sum=4 mod=4 count = 0+0 =0 + // step 2 : {0:1,4:1} a=5 sum=9 mod=4 count = 0+1 =1 + // step 3 : {0:1,4:2} a=0 sum=9 mod=4 count = 1+2 =3 + // step 4 : {0:1,4:3} a=-2 sum=7 mod=2 count = 3+0 =3 + // step 6 : {0:1,4:3,2:1} a=-3 sum=4 mod=4 count = 3+3 =6 + // step 7 : {0:1,4:4,2:1} a=1 sum=5 mod=0 count = 6+1 =7 + public int subarraysDivByKOptimised(int[] A, int K) { + int[] map = new int[K]; + map[0] = 1; + int prefix = 0, res = 0; + for (int a : A) { + prefix = (prefix + a % K + K) % K; + res += map[prefix]; + map[prefix]++; + } + return res; + } +} diff --git a/src/practiceproblems/SubArraySumEqualsK.java b/src/practiceproblems/SubArraySumEqualsK.java new file mode 100644 index 0000000..7dafb03 --- /dev/null +++ b/src/practiceproblems/SubArraySumEqualsK.java @@ -0,0 +1,57 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.Map; + +public class SubArraySumEqualsK { + public int subarraySum(int[] nums, int k) { + int left = 0; + + int sum = 0; + int result = 0; + + Map map = new HashMap<>(); + map.put(0, 1); + // Let’s assume (D+E+3=k) + // sum =A+B+C+D+E+3 + // preSum = A+B+C + // Thus, we can compose critical equation + // sum - preSum = k + // Since we’re looking for specific preSum to compose value k + // we can re-arrange the above equation like below + // sum - k = preSum + // For multiple matching counts + // Ex: + // input [0,-1,1,2,3] k=5 + // We notice that it’s necessary to record occurrence of specific preSum. + // In this case, we need to know preSum 2 occur three times. [0,-1,1,2], [-1,1,2], [2] + // This indicate that it's necessary to record preSum counts + + while (left < nums.length) { + sum += nums[left]; + if (map.get(sum - k) != null) { + result += map.get(sum - k); + } + map.put(sum, map.getOrDefault(sum, 0) + 1); + left++; + + } + return result; + + } + + public static int subarraySumDivByK(int[] nums, int K) { + int prefix = 0; + int result = 0; + Map count = new HashMap<>(); + count.put(0, 1); + + for (int a : nums) { + //(prefix+a%K+K)%K is just a trick to make the remainder positive. + prefix = (prefix + (a % K) + K) % K; + result += count.getOrDefault(prefix, 0); + count.put(prefix, count.getOrDefault(prefix, 0) + 1); + } + return result; + } +} \ No newline at end of file diff --git a/src/practiceproblems/SubstringWindowTemplate.java b/src/practiceproblems/SubstringWindowTemplate.java new file mode 100644 index 0000000..abc7a81 --- /dev/null +++ b/src/practiceproblems/SubstringWindowTemplate.java @@ -0,0 +1,62 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/*https://leetcode.com/problems/find-all-anagrams-in-a-string/discuss/92007/Sliding-Window-algorithm-template-to-solve-all-the-Leetcode-substring-search-problem*/ +public class SubstringWindowTemplate { + + public static List slidingWindowTemplateByHarryChaoyangHe(String s, String t) { + //init a collection or int value to save the result according the question. + List result = new LinkedList<>(); + if (t.length() > s.length()) return result; + + //create a hashmap to save the Characters of the target substring. + //(K, V) = (Character, Frequence of the Characters) + Map map = new HashMap<>(); + for (char c : t.toCharArray()) { + map.put(c, map.getOrDefault(c, 0) + 1); + } + //maintain a counter to check whether match the target string. + int counter = map.size();//must be the map size, NOT the string size because the char may be duplicate. + + //Two Pointers: begin - left pointer of the window; end - right pointer of the window + int begin = 0; + int end = 0; + + //loop at the begining of the source string + while (end < s.length()) { + + char c = s.charAt(end);//get a character + + if (map.containsKey(c)) { + map.put(c, map.get(c) - 1);// plus or minus one + if (map.get(c) == 0) counter--;//modify the counter according the requirement(different condition). + } + end++; + + //increase begin pointer to make it invalid/valid again + while (counter == 0 /* counter condition. different question may have different condition */) { + + char tempc = s.charAt(begin);//***be careful here: choose the char at begin pointer, NOT the end pointer + if (map.containsKey(tempc)) { + map.put(tempc, map.get(tempc) + 1);//plus or minus one + if (map.get(tempc) > 0) + counter++;//modify the counter according the requirement(different condition). + } + + /* save / update(min/max) the result if find a target*/ + // result collections or result int value + + begin++; + } + } + return result; + } + + public static void main(String[] args) { + System.out.println(slidingWindowTemplateByHarryChaoyangHe("ADOBECODEBANC", "ABC")); + } +} diff --git a/src/practiceproblems/SumOfThreeElements.java b/src/practiceproblems/SumOfThreeElements.java new file mode 100644 index 0000000..1a604fc --- /dev/null +++ b/src/practiceproblems/SumOfThreeElements.java @@ -0,0 +1,39 @@ +package practiceproblems; + +import java.util.Arrays; + +public class SumOfThreeElements { + + public static void main(String[] args) { + int arr[] = {1, 4, 45, 6, 10, 8}; + int sum = 22; + SumOfThreeElements ste = new SumOfThreeElements(); + ste.findTriplets(arr, sum); + } + + private boolean findTriplets(int[] arr, int sum) { + + int arrSize = arr.length; + Arrays.sort(arr); + + for (int i = 0; i < arrSize; i++) { + + int left = i + 1; + int right = arrSize - 1; + + while (left < right) { + int result = arr[i] + arr[left] + arr[right]; + if (result == sum) { + System.out.println("triplet found" + i + "+" + left + "+" + right); + break; + } else if (result < sum) { + left++; + } else { + right--; + } + } + } + + return false; + } +} diff --git a/src/practiceproblems/SumSubArrayZero.java b/src/practiceproblems/SumSubArrayZero.java new file mode 100644 index 0000000..cde354d --- /dev/null +++ b/src/practiceproblems/SumSubArrayZero.java @@ -0,0 +1,65 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * https://www.geeksforgeeks.org/print-all-subarrays-with-0-sum/ + */ + + +public class SumSubArrayZero { + private static class Pair { + int first, second; + + Pair(int a, int b) { + first = a; + second = b; + } + + public String toString() { + return this.first + "--" + this.second; + } + } + static ArrayList findSubArrays(int[] arr, int n) { + Map> map = new HashMap<>(); + ArrayList result = new ArrayList<>(); + int sum = 0; + for (int i = 0; i < n; i++) { + sum += arr[i]; + if (sum == 0) + result.add(new Pair(0, i)); + List al = new ArrayList<>(); + if (map.containsKey(sum)) { + al = map.get(sum); + for (int it = 0; it < al.size(); it++) { + result.add(new Pair(al.get(it) + 1, i)); + } + } + al.add(i); + map.put(sum, al); + } + return result; + } + + public static void main(String args[]) { + int[] arr = {6, 3, -1, -3, 4, -2, 2, 4, 6, -12, -7}; + int n = arr.length; + + ArrayList out = findSubArrays(arr, n); + + if (out.size() == 0) + System.out.println("No subarray exists"); + else + print(out); + } + + static void print(ArrayList out) { + for (int i = 0; i < out.size(); i++) { + Pair p = out.get(i); + System.out.println("Subarray found from Index " + p.first + " to " + p.second); + } + } +} diff --git a/src/practiceproblems/SurroundedRegions.java b/src/practiceproblems/SurroundedRegions.java new file mode 100644 index 0000000..2799e9a --- /dev/null +++ b/src/practiceproblems/SurroundedRegions.java @@ -0,0 +1,142 @@ +package practiceproblems; + +import java.util.ArrayDeque; +import java.util.Queue; + +/** + * Given a 2D board containing 'X' and 'O' (the letter O), + * capture all regions surrounded by 'X'. + *

+ * A region is captured by flipping all 'O's into 'X's in that surrounded region. + *

+ * Example: + *

+ * X X X X + * X O O X + * X X O X + * X O X X + *

+ * After running your function, the board should be: + *

+ * X X X X + * X X X X + * X X X X + * X O X X + *

+ * Surrounded regions shouldn’t be on the border, + * which means that any 'O' on the border of the board are not flipped to 'X'. + * Any 'O' that is not on the border and + * it is not connected to an 'O' on the border will be flipped to 'X'. + * Two cells are connected if they are adjacent cells connected horizontally or vertically. + */ +class Solution { + private static class Pair { + int x; + int y; + int level; + + public Pair(int x, int y, int level) { + this.x = x; + this.y = y; + this.level = level; + } + } + + public void solve(char[][] board) { + if (board == null || board.length == 0) + return; + + Queue queue = new ArrayDeque<>(); + int[][] dirs = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}}; + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (board[i][j] == 'O') { + if (i == board.length - 1 || j == board[0].length - 1 || i == 0 || j == 0) { + board[i][j] = '1'; + queue.offer(new Pair(i, j, 0)); + } + } + } + } + + while (!queue.isEmpty()) { + Pair temp = queue.poll(); + + for (int[] dir : dirs) { + int newx = temp.x + dir[0]; + int newy = temp.y + dir[1]; + + if (isValid(newx, newy, board) && board[newx][newy] == 'O') { + board[newx][newy] = '1'; + queue.offer(new Pair(newx, newy, 0)); + } + } + + } + + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (board[i][j] == '1') { + board[i][j] = 'O'; + } else if (board[i][j] == 'O') { + board[i][j] = 'X'; + } + } + } + + } + + public boolean isValid(int x, int y, char[][] board) { + return x >= 0 && x < board.length && y >= 0 && y < board[0].length; + } + + public void solveDFS(char[][] board) { + if (board.length == 0 || board[0].length == 0) + return; + if (board.length < 2 || board[0].length < 2) + return; + int m = board.length, n = board[0].length; + // Any 'O' connected to a boundary can't be turned to 'X', so ... + // Start from first and last column, turn 'O' to '*'. + for (int i = 0; i < m; i++) { + if (board[i][0] == 'O') + boundaryDFS(board, i, 0); + if (board[i][n - 1] == 'O') + boundaryDFS(board, i, n - 1); + } + // Start from first and last row, turn '0' to '*' + for (int j = 0; j < n; j++) { + if (board[0][j] == 'O') + boundaryDFS(board, 0, j); + if (board[m - 1][j] == 'O') + boundaryDFS(board, m - 1, j); + } + // post-processing, turn 'O' to 'X', '*' back to 'O', keep 'X' intact. + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (board[i][j] == 'O') + board[i][j] = 'X'; + else if (board[i][j] == '*') + board[i][j] = 'O'; + } + } + } + + //Use DFS algo to turn internal however boundary-connected 'O' to '*' + private void boundaryDFS(char[][] board, int i, int j) { + if (i < 0 || i > board.length - 1 || j < 0 || j > board[0].length - 1) + return; + if (board[i][j] == 'O') { + board[i][j] = '*'; + + boundaryDFS(board, i - 1, j); + + boundaryDFS(board, i + 1, j); + + boundaryDFS(board, i, j - 1); + + boundaryDFS(board, i, j + 1); + } + } +} + diff --git a/src/practiceproblems/SwapRecoverBST.java b/src/practiceproblems/SwapRecoverBST.java new file mode 100644 index 0000000..053a225 --- /dev/null +++ b/src/practiceproblems/SwapRecoverBST.java @@ -0,0 +1,54 @@ +package practiceproblems; + +public class SwapRecoverBST { + + TreeNode firstElement = null; + TreeNode secondElement = null; + // The reason for this initialization is to avoid null pointer exception in the first comparison when prevElement has not been initialized + TreeNode prevElement = new TreeNode(Integer.MIN_VALUE); + + public void recoverTree(TreeNode root) { + + // In order traversal to find the two elements + traverse(root); + + // Swap the values of the two nodes + int temp = firstElement.val; + firstElement.val = secondElement.val; + secondElement.val = temp; + } + + private void traverse(TreeNode root) { + + if (root == null) + return; + + traverse(root.left); + // Let's assume this is the original in-order traversal sequence of BST: 1 2 3 4 5 + // If 2 and 3 get swapped, it becomes 1 3 2 4 5 and + //there is only one time that you will have prev.val >= root.val + // If 2 and 4 get swapped, it becomes 1 4 3 2 5 and + //there are two times that you will have prev.val >= root.val + + // If during the first time when you find prev.val >= root.val, + //the previous node "prev" MUST be one of two nodes that get swapped. + //However, the current node MAY OR MAY NOT be another node that gets swapped, + //which will depend on whether later during in-order traversal, there is another prev.val >= root.val or not. + // If there is, then the current node "root" during the 2nd time of prev.val >= root.val will be the other node that gets swapped + // Start of "do some business", + // If first element has not been found, assign it to prevElement (refer to 6 in the example above) + if (firstElement == null && prevElement.val >= root.val) { + firstElement = prevElement; + } + + // If first element is found, assign the second element to the root (refer to 2 in the example above) + if (firstElement != null && prevElement.val >= root.val) { + secondElement = root; + } + prevElement = root; + + // End of "do some business" + + traverse(root.right); + } +} \ No newline at end of file diff --git a/src/practiceproblems/SymmetricTree.java b/src/practiceproblems/SymmetricTree.java new file mode 100644 index 0000000..fc72385 --- /dev/null +++ b/src/practiceproblems/SymmetricTree.java @@ -0,0 +1,21 @@ +package practiceproblems; + +class SymmetricTree { + public boolean isSymmetric(TreeNode root) { + if (root == null) { + return true; + } + + return isSymmetricHelp(root.left, root.right); + } + + private boolean isSymmetricHelp(TreeNode left, TreeNode right) { + if (left == null || right == null) { + return left == right; + } + if (left.val != right.val) { + return false; + } + return isSymmetricHelp(left.left, right.right) && isSymmetricHelp(left.right, right.left); + } +} \ No newline at end of file diff --git a/src/practiceproblems/TaskLeastInterval.java b/src/practiceproblems/TaskLeastInterval.java new file mode 100644 index 0000000..fa43bcb --- /dev/null +++ b/src/practiceproblems/TaskLeastInterval.java @@ -0,0 +1,55 @@ +package practiceproblems; + +import java.util.*; + +/** + * https://leetcode.com/problems/task-scheduler/ + */ + + +public class TaskLeastInterval { + + public static int leastInterval(char[] tasks, int n) { + Map map = new HashMap<>(); + for (char task : tasks) { + map.put(task, map.getOrDefault(task, 0) + 1); + } + PriorityQueue> queue = new PriorityQueue<>( + (a, b) -> Integer.compare(b.getValue(), a.getValue())); + + queue.addAll(map.entrySet()); + + int count = 0; + // At each iteration, we process at most 'n' elements, + // and move forwards exactly n+1 in time (regardless of how many elements we processed: + // Read the topmost from the queue and increment the time. Add it to a temp list to be added later. + // Add the element back to the queue from the temp list if count is > 0. + // if al elements are done, we're done too. + // Move time forward by n + 1 + // Return time in the end. + while (!queue.isEmpty()) { + int k = n + 1; //each time fill k elements, if k is not full, that's the idle + List tempList = new ArrayList<>(); + while (k > 0 && !queue.isEmpty()) { + Map.Entry top = queue.poll(); + top.setValue(top.getValue() - 1); + tempList.add(top); + k--; + count++; + } + + for (Map.Entry e : tempList) { + if (e.getValue() > 0) queue.add(e); // add valid tasks + } + + if (queue.isEmpty()) break; + count = count + k; // if k > 0, then it means we need to be idle + } + return count; + } + + public static void main(String[] args) { + char[] arr = "A".toCharArray(); + System.out.println(leastInterval(arr, 2)); + } +} diff --git a/src/practiceproblems/ThreeSum.java b/src/practiceproblems/ThreeSum.java new file mode 100644 index 0000000..4932aea --- /dev/null +++ b/src/practiceproblems/ThreeSum.java @@ -0,0 +1,40 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class ThreeSum { + public List> threeSum(int[] nums) { + if(nums==null || nums.length==0) return Collections.emptyList(); + + Arrays.sort(nums); + List> result= new ArrayList<>(); + for(int i=0;isum){ + right--; + } + } + } + } + + return result; + } +} \ No newline at end of file diff --git a/src/practiceproblems/TimeMap.java b/src/practiceproblems/TimeMap.java new file mode 100644 index 0000000..a9dc333 --- /dev/null +++ b/src/practiceproblems/TimeMap.java @@ -0,0 +1,67 @@ +package practiceproblems; + +import java.util.HashMap; + +/** + * Create a time based key-value store class TimeMap, that supports two operations. + * + * 1. set(string key, string value, int timestamp) + * + * Stores the key and value, along with the given timestamp. + * 2. get(string key, int timestamp) + * + * Returns a value such that set(key, value, timestamp_prev) was called previously, + * with timestamp_prev <= timestamp. + * If there are multiple such values, it returns the one with the largest timestamp_prev. + * If there are no values, it returns the empty string (""). + * + * Input: inputs = ["TimeMap","set","get","get","set","get","get"], inputs = [[],["foo","bar",1],["foo",1],["foo",3],["foo","bar2",4],["foo",4],["foo",5]] + * Output: [null,null,"bar","bar",null,"bar2","bar2"] + * Explanation: + * TimeMap kv; + * kv.set("foo", "bar", 1); // store the key "foo" and value "bar" along with timestamp = 1 + * kv.get("foo", 1); // output "bar" + * kv.get("foo", 3); // output "bar" since there is no value corresponding to foo at timestamp 3 and timestamp 2, then the only value is at timestamp 1 ie "bar" + * kv.set("foo", "bar2", 4); + * kv.get("foo", 4); // output "bar2" + * kv.get("foo", 5); //output "bar2" + */ + +class TimeMap { + + class Node{ + String val; + int time; + Node next; + public Node(String value, int timestamp){ + val=value; + time=timestamp; + } + } + /** Initialize your data structure here. */ + HashMap map; + + public TimeMap() { + map=new HashMap<>(); + } + + public void set(String key, String value, int timestamp) { + Node node =new Node(value,timestamp); + if(map.containsKey(key)){ + node.next=map.get(key); + } + map.put(key,node); + } + + public String get(String key, int timestamp) { + String vl=""; + if(map.containsKey(key)){ + Node y=map.get(key); + while(y.time>timestamp&&y.next!=null) + y=y.next; + if(y.time<=timestamp) + vl=y.val; + } + return vl; + } +} \ No newline at end of file diff --git a/src/practiceproblems/TopKFrequentElement.java b/src/practiceproblems/TopKFrequentElement.java new file mode 100644 index 0000000..bcda327 --- /dev/null +++ b/src/practiceproblems/TopKFrequentElement.java @@ -0,0 +1,38 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +class TopKFrequentElement{ + public List topKFrequent(int[] nums, int k) { + List result = new ArrayList<>(); + + Map map = new HashMap<>(); //Key: val, Val: #of freq + for (int num : nums) { + if (map.containsKey(num)) { + map.put(num, map.get(num)+1); + }else { + map.put(num, 1); + } + } + + List[] bucks = new List[nums.length+1]; // index : freq; val: set of key + for (int key : map.keySet()) { + int freq = map.get(key); + if (bucks[freq] == null) { + bucks[freq] = new ArrayList<>(); + } + bucks[freq].add(key); + } + + for (int freq = nums.length; freq >=0 && k > 0; freq--) { + if (bucks[freq] != null) { + k -=bucks[freq].size(); + result.addAll(bucks[freq]); + } + } + return result; + } +} \ No newline at end of file diff --git a/src/practiceproblems/TopKFrequentElements.java b/src/practiceproblems/TopKFrequentElements.java new file mode 100644 index 0000000..8e0c563 --- /dev/null +++ b/src/practiceproblems/TopKFrequentElements.java @@ -0,0 +1,38 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * https://leetcode.com/problems/top-k-frequent-elements/discuss/445815/Java8-Lambda-solution-3-lines-code + */ +public class TopKFrequentElements { + + public List topKFrequent(int[] nums, int k) { + if (nums.length == 0) { + return Collections.emptyList(); + } + + PriorityQueue> pq = new PriorityQueue<>( + (obj1, obj2) -> obj2.getValue() - obj1.getValue()); + Map map = new HashMap<>(); + + for (int i : nums) { + map.put(i, map.getOrDefault(i, 0) + 1); + } + + for (Map.Entry mapEntry : map.entrySet()) { + pq.add(mapEntry); + } + + List result = new ArrayList<>(); + for (int i = 0; i < k; i++) { + result.add(pq.remove().getKey()); + } + return result; + } +} diff --git a/src/practiceproblems/TrailingZeroes.java b/src/practiceproblems/TrailingZeroes.java new file mode 100644 index 0000000..6494c51 --- /dev/null +++ b/src/practiceproblems/TrailingZeroes.java @@ -0,0 +1,19 @@ +package practiceproblems; + +/*https://www.geeksforgeeks.org/count-trailing-zeroes-factorial-number/*/ +class TrailingZeroes { + public int trailingZeroes(int n) { + int count = 0; + while (n != 0) { + int tmp = n / 5; + count += tmp; + n = tmp; + } + return count; + } + + public static void main(String[] args) { + TrailingZeroes solution = new TrailingZeroes(); + System.out.println(solution.trailingZeroes(30)); + } +} \ No newline at end of file diff --git a/src/practiceproblems/TreasureIsland.java b/src/practiceproblems/TreasureIsland.java new file mode 100644 index 0000000..95da6c0 --- /dev/null +++ b/src/practiceproblems/TreasureIsland.java @@ -0,0 +1,66 @@ +package practiceproblems; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * https://leetcode.com/discuss/interview-question/347457/Amazon-or-OA-2019-or-Treasure-Island + */ +public class TreasureIsland { + private static final int[][] DIRS = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } }; + + public static int minSteps(char[][] grid) { + Queue q = new LinkedList<>(); + q.add(new Point(0, 0, 0)); + grid[0][0] = 'D'; + while (!q.isEmpty()) { + Point p = q.poll(); + + for (int[] dir : DIRS) { + int r = p.r + dir[0]; + int c = p.c + dir[1]; + + if (isSafe(grid, r, c)) { + if (grid[r][c] == 'X') { + return p.steps + 1; + } + grid[r][c] = 'D'; + q.add(new Point(r, c, p.steps + 1)); + } + } + } + return -1; + } + + private static boolean isSafe(char[][] grid, int r, int c) { + return r >= 0 && r < grid.length && c >= 0 && c < grid[0].length && grid[r][c] != 'D'; + } + + private static class Point { + int r; + int c; + int steps; + + Point(int r, int c, int steps) { + this.r = r; + this.c = c; + this.steps = steps; + } + + public String toString() { + return this.r + "-" + this.c; + } + } + + public static void main(String[] args) { + + char[][] grid = + {{'O', 'O', 'O', 'O'}, + {'D', 'O', 'D', 'O'}, + {'O', 'O', 'O', 'O'}, + {'X', 'D', 'D', 'O'}}; + + + System.out.println(minSteps(grid)); + } +} \ No newline at end of file diff --git a/src/practiceproblems/TreasureIslandII.java b/src/practiceproblems/TreasureIslandII.java new file mode 100644 index 0000000..80538ad --- /dev/null +++ b/src/practiceproblems/TreasureIslandII.java @@ -0,0 +1,82 @@ +package practiceproblems; + +import java.util.ArrayDeque; +import java.util.Queue; + +/** + * https://leetcode.com/discuss/interview-question/356150/amazon-oa-2019-shortest-path-from-multiple-sources + * */ + +public class TreasureIslandII { + private static final int[][] DIRS = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; + + public static int minDist(char[][] grid) { + Queue q = collectSources(grid); + for (int dist = 0; !q.isEmpty(); dist++) { + for (int sz = q.size(); sz > 0; sz--) { + Point p = q.poll(); + + if (grid[p.r][p.c] == 'X') + return dist; + grid[p.r][p.c] = 'D'; // mark as visited + + for (int[] dir : DIRS) { + int r = p.r + dir[0]; + int c = p.c + dir[1]; + if (isSafe(grid, r, c)) { + q.add(new Point(r, c)); + } + } + } + } + return -1; + } + + private static Queue collectSources(char[][] grid) { + Queue sources = new ArrayDeque<>(); + for (int r = 0; r < grid.length; r++) { + for (int c = 0; c < grid[0].length; c++) { + if (grid[r][c] == 'S') { + sources.add(new Point(r, c)); + } + } + } + return sources; + } + + private static boolean isSafe(char[][] grid, int r, int c) { + return r >= 0 && r < grid.length && c >= 0 && c < grid[0].length && grid[r][c] != 'D'; + } + + private static class Point { + int r; + int c; + + Point(int r, int c) { + this.r = r; + this.c = c; + } + + public String toString() { + return r + "-" + c; + } + } + + public static void main(String[] args) { + char[][] grid = { + {'S', 'O', 'O', 'S', 'S'}, + {'D', 'O', 'D', 'O', 'D'}, + {'O', 'O', 'O', 'O', 'X'}, + {'X', 'D', 'D', 'O', 'O'}, + {'X', 'D', 'D', 'D', 'O'}}; + test(minDist(grid), 3); + } + + private static void test(int actual, int expected) { + if (actual == expected) { + System.out.println("PASSED!"); + } else { + System.out.println(String.format("FAILED! Expected: %d, but got: %d", expected, actual)); + } + } +} \ No newline at end of file diff --git a/src/practiceproblems/Trie.java b/src/practiceproblems/Trie.java new file mode 100644 index 0000000..aed8c68 --- /dev/null +++ b/src/practiceproblems/Trie.java @@ -0,0 +1,65 @@ +package practiceproblems; + +class Trie { + + class TrieNode{ + char data; + TrieNode[] children; + boolean isWord; + TrieNode(char data){ + this.data=data; + this.children= new TrieNode[26]; + } + } + + + TrieNode root; + public Trie() { + this.root=new TrieNode(' '); + } + + + public void insert(String word) { + TrieNode head=root; + + for(int i=0;i userMap; + + // Tweet link to next Tweet so that we can save a lot of time + // when we execute getNewsFeed(userId) + private class Tweet { + public int id; + public int time; + public Tweet next; + + public Tweet(int id) { + this.id = id; + time = timeStamp++; + next = null; + } + } + + public class User { + public int id; + public Set followed; + public Tweet tweet_head; + + public User(int id) { + this.id = id; + followed = new HashSet<>(); + follow(id); // first follow yourself + tweet_head = null; + } + + public void follow(int id) { + followed.add(id); + } + + public void unfollow(int id) { + followed.remove(id); + } + + // everytime user post a new tweet, add it to the head of tweet list. + public void post(int id) { + Tweet t = new Tweet(id); + t.next = tweet_head; + tweet_head = t; + } + } + + /** + * Initialize your data structure here. + */ + public Twitter() { + userMap = new HashMap<>(); + } + + /** + * Compose a new tweet. + */ + public void postTweet(int userId, int tweetId) { + if (!userMap.containsKey(userId)) { + User u = new User(userId); + userMap.put(userId, u); + } + userMap.get(userId).post(tweetId); + + } + + // Best part of this. + // first get all tweets lists from one user including itself and all people it followed. + // Second add all heads into a max heap. Every time we poll a tweet with + // largest time stamp from the heap, then we add its next tweet into the heap. + // So after adding all heads we only need to add 9 tweets at most into this + // heap before we get the 10 most recent tweet. + public List getNewsFeed(int userId) { + List result = new LinkedList<>(); + + if (!userMap.containsKey(userId)) { + return result; + } + + Set users = userMap.get(userId).followed; + PriorityQueue q = new PriorityQueue<>(users.size(), (a, b) -> (b.time - a.time)); + for (int user : users) { + Tweet t = userMap.get(user).tweet_head; + // very important! If we add null to the head we are screwed. + if (t != null) { + q.add(t); + } + } + int n = 0; + while (!q.isEmpty() && n < 10) { + Tweet t = q.poll(); + result.add(t.id); + n++; + if (t.next != null) { + q.add(t.next); + } + } + + return result; + + } + + /** + * Follower follows a followee. If the operation is invalid, it should be a no-op. + */ + public void follow(int followerId, int followeeId) { + if (!userMap.containsKey(followerId)) { + User u = new User(followerId); + userMap.put(followerId, u); + } + if (!userMap.containsKey(followeeId)) { + User u = new User(followeeId); + userMap.put(followeeId, u); + } + userMap.get(followerId).follow(followeeId); + } + + /** + * Follower unfollows a followee. If the operation is invalid, it should be a no-op. + */ + public void unfollow(int followerId, int followeeId) { + if (!userMap.containsKey(followerId) || followerId == followeeId) { + return; + } + userMap.get(followerId).unfollow(followeeId); + } + + public static void main(String[] args) { + Twitter obj = new Twitter(); + obj.postTweet(1, 5); + List param_2 = obj.getNewsFeed(1); + obj.follow(1, 2); + obj.unfollow(1, 2); + } +} \ No newline at end of file diff --git a/src/practiceproblems/TwoCityScheduling.java b/src/practiceproblems/TwoCityScheduling.java new file mode 100644 index 0000000..7815435 --- /dev/null +++ b/src/practiceproblems/TwoCityScheduling.java @@ -0,0 +1,49 @@ +package practiceproblems; + +import java.util.PriorityQueue; + +/** + * There are 2N people a company is planning to interview. + * The cost of flying the i-th person to city A is costs[i][0], and the cost of flying the i-th person to city B is costs[i][1]. + * Return the minimum cost to fly every person to a city such that exactly N people arrive in each city. + * Input: [[10,20],[30,200],[400,50],[30,20]] + * Output: 110 + * Explanation: + The first person goes to city A for a cost of 10. + The second person goes to city A for a cost of 30. + The third person goes to city B for a cost of 50. + The fourth person goes to city B for a cost of 20. + + * The total minimum cost is 10 + 30 + 50 + 20 = 110 to have half the people interviewing in each city + * + */ +public class TwoCityScheduling { + public int twoCitySchedCost(int[][] costs) { + // for input [[10,20],[30,200],[400,50],[30,20]] + // let's send all to A, the cost'd be => 10+30+400+30= 470 + // we need to remove one half to save some money + // what we can do is take the difference in each input + // (10-20) (30-200) (400-50) (30-20) + // [-10, -170, 350, 10] + // what the above array indicates is that for i'th candidate=>[10,20] we will save 10 in sending to A + // when i=2 we will have to spend 350 more to bring to A city so we sort by arr[0]-arr[1] + // greedily we take negative val candidates to A and rest to B for this input + PriorityQueue queue= new PriorityQueue<>((a, b)->(a[0] - a[1]) - (b[0] - b[1])); + + for(int[] cost: costs){ + queue.offer(cost); + } + int result=0; + int k=0; + while(k= 0; i--) { + min = Math.min(min, nums[i]); + if (nums[i] > min) { + begin = i; + } + } + + int max = Integer.MIN_VALUE; + int end = -2; + //iterate from beginning of array + //find the last element which is smaller than the last seen max from + //its left side and mark it as end + for (int i = 0; i < nums.length; i++) { + max = Math.max(max, nums[i]); + if (nums[i] < max) { + end = i; + } + } + return end - begin + 1; + } +} diff --git a/src/practiceproblems/UniqueElementsInArray.java b/src/practiceproblems/UniqueElementsInArray.java new file mode 100644 index 0000000..24e7622 --- /dev/null +++ b/src/practiceproblems/UniqueElementsInArray.java @@ -0,0 +1,29 @@ +package practiceproblems; + +/** + * https://codepumpkin.com/find-unique-array-element/#XORApproach + */ +public class UniqueElementsInArray { + + /** + * @param inputArray + * + * @return returns unique Element in the array. + * -1 if no unique element is available in the array. + */ + // 0 0 : 0 || 1 1 : 0 + // returns 0 if both are same + public static int xorApproach(int[] inputArray) { + int result = 0; + for (int i = 0; i < inputArray.length; i++) { + result ^= inputArray[i]; + } + + return (result > 0 ? result : -1); + } + + public static void main(String[] args) { + int[] nums = { 1, 2, 3, 2, 1, 4, 3 }; + xorApproach(nums); + } +} diff --git a/src/practiceproblems/UniquePath.java b/src/practiceproblems/UniquePath.java new file mode 100644 index 0000000..4b99c71 --- /dev/null +++ b/src/practiceproblems/UniquePath.java @@ -0,0 +1,89 @@ +package practiceproblems; + +/*https://leetcode.com/problems/unique-paths-ii/ + https://leetcode.com/problems/unique-paths/*/ +public class UniquePath { + + public static void main(String[] args) { + System.out.println(uniquePathI(3, 2)); + + int[][] matrix = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } }; + + System.out.println(uniquePathII(matrix)); + + } + + private static int uniquePathI(int row, int col) { + int[][] dp = new int[row][col]; + + for (int i = 0; i < col; i++) { + dp[0][i] = 1; + } + + for (int j = 0; j < row; j++) { + dp[j][0] = 1; + } + + for (int i = 1; i < row; i++) { + for (int j = 1; j < col; j++) { + dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; + } + } + return dp[row - 1][col - 1]; + } + + /** + * Now consider if some obstacles are added to the grids. How many unique paths would there be? + * Input: + * [ + * [0,0,0], + * [0,1,0], + * [0,0,0] + * ] + * Output: 2 + * Explanation: + * There is one obstacle in the middle of the 3x3 grid above. + * There are two ways to reach the bottom-right corner: + * 1. Right -> Right -> Down -> Down + * 2. Down -> Down -> Right -> Right + */ + private static int uniquePathII(int[][] obstacleGrid) { + + if (obstacleGrid[0][0] == 1) + return 0; + int m = obstacleGrid.length; + int n = obstacleGrid[0].length; + + int[][] dp = new int[obstacleGrid.length][obstacleGrid[0].length]; + + for (int i = 0; i < m; i++) { + if (obstacleGrid[i][0] == 1) { + dp[i][0] = 0; + break; + } else { + dp[i][0] = 1; + } + } + + for (int j = 0; j < n; j++) { + if (obstacleGrid[0][j] == 1) { + dp[0][j] = 0; + break; + } else { + dp[0][j] = 1; + } + } + + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + if (obstacleGrid[i][j] == 1) { + dp[i][j] = 0; + } else { + dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; + } + } + } + return dp[m - 1][n - 1]; + + } +} diff --git a/src/practiceproblems/UniquePathMaximum.java b/src/practiceproblems/UniquePathMaximum.java new file mode 100644 index 0000000..ef28cac --- /dev/null +++ b/src/practiceproblems/UniquePathMaximum.java @@ -0,0 +1,46 @@ +package practiceproblems; + +/* +https://leetcode.com/discuss/interview-question/383669/ +*/ + +/** + * find the maximum score of a path starting at [0, 0] and ending at [r-1, c-1]. The score of a path is the minimum value in that path. + *

+ * Input: + * [[1, 2, 3] + * [4, 5, 1]] + *

+ * Output: 4 + * Explanation: + * Possible paths: + * 1-> 2 -> 3 -> 1 + * 1-> 2 -> 5 -> 1 + * 1-> 4 -> 5 -> 1 + * So min of all the paths = [2, 2, 4]. Note that we don't include the first and final entry. + */ +public class UniquePathMaximum { + + public static void main(String[] args) { + int[][] matrix = { { 6, 7, 8 }, { 5, 4, 2 }, { 8, 7, 6 } }; + System.out.println(findMaximumOfUniquePath(matrix)); + } + + private static int findMaximumOfUniquePath(int[][] matrix) { + for (int i = 1; i < matrix[0].length; i++) { + matrix[0][i] = Math.min(matrix[0][i], matrix[0][i - 1]); + } + + for (int j = 1; j < matrix.length; j++) { + matrix[j][0] = Math.min(matrix[j][0], matrix[j - 1][0]); + } + + for (int i = 1; i < matrix.length; i++) { + for (int j = 1; j < matrix[i].length; j++) { + matrix[i][j] = Math.max(Math.min(matrix[i - 1][j], matrix[i][j]), + Math.min(matrix[i][j - 1], matrix[i][j])); + } + } + return matrix[matrix.length - 1][matrix[0].length - 1]; + } +} \ No newline at end of file diff --git a/src/practiceproblems/UrlEncode.java b/src/practiceproblems/UrlEncode.java new file mode 100644 index 0000000..c081ea3 --- /dev/null +++ b/src/practiceproblems/UrlEncode.java @@ -0,0 +1,45 @@ +package practiceproblems; + +import java.util.stream.IntStream; + +/** + * Write a method to replace all the spaces in a string with ‘%20’. + * You may assume that the string has sufficient space at the end to hold the additional characters, + * and that you are given the “true” length of the string. + */ +public class UrlEncode { + public void replaceSpaces(char[] str, int trueLength) { + int i = str.length - 1; + int extra = str.length - trueLength; + int j = i - extra; + while (i != j) { + if (!Character.isSpaceChar(str[j])) { + str[i--] = str[j--]; + } else { + str[i--] = '0'; + str[i--] = '2'; + str[i--] = '%'; + j--; + } + } + } + + public static void main(String[] args) { + test(new char[17], "Mr John Smith"); + test(new char[12], "Mr John "); + test(new char[5], "Mr "); + test(new char[5], " Mr"); + test(new char[8], " Mr "); + test(new char[3], " "); + test(new char[20], "Mr John Smith"); + test(new char[0], ""); + } + + private static void test(char[] str, String s) { + IntStream.range(0, s.length()).forEach(i -> str[i] = s.charAt(i)); + System.out.print(new String(str) +" - "); + UrlEncode ob = new UrlEncode(); + ob.replaceSpaces(str, s.length()); + System.out.println(new String(str)); + } +} \ No newline at end of file diff --git a/src/practiceproblems/ValidPalindromeII.java b/src/practiceproblems/ValidPalindromeII.java new file mode 100644 index 0000000..714abb4 --- /dev/null +++ b/src/practiceproblems/ValidPalindromeII.java @@ -0,0 +1,40 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/valid-palindrome-ii/ + */ +class ValidPalindromeII { + + public static boolean validPalindrome(String s) { + int i = 0, j = s.length() - 1; + while (i < j && s.charAt(i) == s.charAt(j)) { + i++; + j--; + } + + if (i >= j) { + return true; + } + + if (isPalindrome(s, i + 1, j) || isPalindrome(s, i, j - 1)) { + return true; + } + return false; + } + + private static boolean isPalindrome(String s, int i, int j) { + while (i < j) { + if (s.charAt(i) == s.charAt(j)) { + i++; + j--; + } else { + return false; + } + } + return true; + } + + public static void main(String[] args) { + System.out.println(validPalindrome("ddeeeef")); + } +} \ No newline at end of file diff --git a/src/practiceproblems/ValidParentheses.java b/src/practiceproblems/ValidParentheses.java new file mode 100644 index 0000000..f44a828 --- /dev/null +++ b/src/practiceproblems/ValidParentheses.java @@ -0,0 +1,26 @@ +package practiceproblems; + +import java.util.Stack; + +public class ValidParentheses { + + public static boolean isValid(String s) { + + Stack stack = new Stack<>(); + for (char c : s.toCharArray()) { + if (c == '(') + stack.push(')'); + else if (c == '{') + stack.push('}'); + else if (c == '[') + stack.push(']'); + else if (stack.isEmpty() || stack.pop() != c) + return false; + } + return stack.isEmpty(); + } + + public static void main(String[] args) { + System.out.println(isValid("({[])}")); + } +} diff --git a/src/practiceproblems/ValidParenthesesString.java b/src/practiceproblems/ValidParenthesesString.java new file mode 100644 index 0000000..2a47e06 --- /dev/null +++ b/src/practiceproblems/ValidParenthesesString.java @@ -0,0 +1,45 @@ +package practiceproblems; + +/** + * Given a string containing only three types of characters: '(', ')' and '*', + * write a function to check whether this string is valid. + * We define the validity of a string by these rules: + * + * Any left parenthesis '(' must have a corresponding right parenthesis ')'. + * Any right parenthesis ')' must have a corresponding left parenthesis '('. + * Left parenthesis '(' must go before the corresponding right parenthesis ')'. + * '*' could be treated as a single right parenthesis ')' or a single left parenthesis '(' or an empty string. + * An empty string is also valid. + * + * Input: "(*))" + * Output: True + * + * Input: "(*)" + * Output: True + */ +public class ValidParenthesesString { + public boolean checkValidString(String s) { + int cmin = 0; + int cmax = 0; // open parentheses count in range [cmin, cmax] + for (char c : s.toCharArray()) { + if (c == '(') { + cmax++; + cmin++; + } else if (c == ')') { + cmax--; + cmin--; + } else if (c == '*') { + cmax++; // if `*` become `(` then openCount++ + cmin--; // if `*` become `)` then openCount-- + // if `*` become `` then nothing happens + // So openCount will be in new range [cmin-1, cmax+1] + } + if (cmax < 0) { + return false; // Currently, don't have enough open parentheses to match close parentheses-> Invalid + } + // For example: ())( + cmin = Math.max(cmin, 0); // It's invalid if open parentheses count < 0 that's why cmin can't be negative + } + return cmin == 0; // Return true if can found `openCount == 0` in range [cmin, cmax] + } +} diff --git a/src/practiceproblems/ValidSudoku.java b/src/practiceproblems/ValidSudoku.java new file mode 100644 index 0000000..955dff0 --- /dev/null +++ b/src/practiceproblems/ValidSudoku.java @@ -0,0 +1,35 @@ +package practiceproblems; + +import java.util.HashSet; +import java.util.Set; + +public class ValidSudoku +{ + public boolean isValidSudoku(char[][] board) { + Set seen = new HashSet<>(); + + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 9; j++) { + if (board[i][j] != '.') { + char number = board[i][j]; + if (!seen.add(number + "seen in row" + i) || !seen.add(number + "seen in col" + j) + || !seen.add(number + "seen in block" + i / 3 + "-" + j / 3)) { + return false; + } + } + } + } + + return true; + } + public static void main(String[] args) { + char[][] board = { { '5', '3', '.', '.', '7', '.', '.', '.', '.' }, + { '6', '.', '.', '1', '9', '5', '.', '.', '.' }, { '.', '9', '8', '.', '.', '.', '.', '6', '.' }, + { '8', '.', '.', '.', '6', '.', '.', '.', '3' }, { '4', '.', '.', '8', '.', '3', '.', '.', '1' }, + { '7', '.', '.', '.', '2', '.', '.', '.', '6' }, { '.', '6', '.', '.', '.', '.', '2', '8', '.' }, + { '.', '.', '.', '4', '1', '9', '.', '.', '5' }, { '.', '.', '.', '.', '8', '.', '.', '7', '9' } }; + + ValidSudoku vs = new ValidSudoku(); + System.out.println(vs.isValidSudoku(board)); + } +} \ No newline at end of file diff --git a/src/practiceproblems/ValidateIpAddresses.java b/src/practiceproblems/ValidateIpAddresses.java new file mode 100644 index 0000000..17aa32b --- /dev/null +++ b/src/practiceproblems/ValidateIpAddresses.java @@ -0,0 +1,65 @@ +package practiceproblems; + +/** + * A valid IPv4 address is an IP in the form "x1.x2.x3.x4" + * where 0 <= xi <= 255 and xi cannot contain leading zeros. + * For example, "192.168.1.1" and "192.168.1.0" are valid IPv4 addresses but "192.168.01.1", + * while "192.168.1.00" and "192.168@1.1" are invalid IPv4 addresses. + * + * A valid IPv6 address is an IP in the form "x1:x2:x3:x4:x5:x6:x7:x8" where: + * + * 1 <= xi.length <= 4 + * xi is a hexadecimal string which may contain digits, + * lower-case English letter ('a' to 'f') and upper-case English letters ('A' to 'F'). + * Leading zeros are allowed in xi. + * For example, "2001:0db8:85a3:0000:0000:8a2e:0370:7334" + * and "2001:db8:85a3:0:0:8A2E:0370:7334" + * are valid IPv6 addresses, while "2001:0db8:85a3::8A2E:037j:7334" + * and "02001:0db8:85a3:0000:0000:8a2e:0370:7334" are invalid IPv6 addresses. + * + * Input: IP = "172.16.254.1" + * Output: "IPv4" + * Explanation: This is a valid IPv4 address, return "IPv4". + * + * Input: IP = "2001:0db8:85a3:0:0:8A2E:0370:7334" + * Output: "IPv6" + * Explanation: This is a valid IPv6 address, return "IPv6". + */ +public class ValidateIpAddresses { + // the condition for IPv4 is + // there should be 4 components separated by 3 dots + // each component should have value between 0-9 (base 10) + public String validIPAddress(String IP) { + if(IP==null || IP.length()==0) return "Neither"; + + if(IP.chars().filter(e->e=='.').count()==3){ + + for(String s: IP.split("\\.",-1)){ //-1 is for edge case like "1.0.1." + if(s.length()==0 || s.length()>4) return "Neither"; + if(s.charAt(0)=='0' && s.length()!=1) return "Neither"; + for(char c:s.toCharArray()) if(!Character.isDigit(c)) return "Neither"; + if(Integer.parseInt(s)>255) return "Neither"; + } + + return "IPv4"; + + } + // the condition for IPv6 is + // it should have 8 components, separated by 7 ':'s + // each component should have hex-value i.e 0-9, a-f or A-F + else if(IP.chars().filter(e->e==':').count()==7){ + for(String s: IP.split(":",-1)){ + if(s.length()==0 || s.length()>4) return "Neither"; + for(char c: s.toCharArray()){ + if(!((c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F'))){ + return "Neither"; + } + } + } + + return "IPv6"; + } + + return "Neither"; + } +} \ No newline at end of file diff --git a/src/practiceproblems/VulgarDecimal.java b/src/practiceproblems/VulgarDecimal.java new file mode 100644 index 0000000..f767a12 --- /dev/null +++ b/src/practiceproblems/VulgarDecimal.java @@ -0,0 +1,115 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/fraction-to-recurring-decimal/ + *

+ * Given two integers representing the numerator and denominator of a fraction, return the fraction in string format. + *

+ * If the fractional part is repeating, enclose the repeating part in parentheses. + *

+ * If multiple answers are possible, return any of them. + *

+ * It is guaranteed that the length of the answer string is less than 104 for all the given inputs. + *

+ * Input: numerator = 1, denominator = 2 + * Output: "0.5" + *

+ * Input: numerator = 2, denominator = 1 + * Output: "2" + */ + + +import java.util.*; + +public class VulgarDecimal { + + public static String fractionToDecimal(long numerator, long denominator) { + if (denominator == 0) return null; + // if both are negative then the ans would be positive + boolean isNegative = (numerator < 0 && denominator > 0) || (numerator > 0 && denominator < 0); + + long denomiL = Math.abs(denominator); + long numerL = Math.abs(numerator); + + Map map = new HashMap<>(); + + StringBuilder sb = new StringBuilder(); + + sb.append((numerL / denomiL)); + + if (numerL % denomiL != 0) { + sb.append("."); + } + if (isNegative) sb.insert(0, "-"); + + numerL %= denomiL; + + if (numerL == 0) return sb.toString(); + + map.put(numerL, sb.length()); + + while (numerL > 0) { + + numerL *= 10; + sb.append((numerL / denomiL)); + numerL = (numerL % denomiL); + + if (map.containsKey(numerL)) { + int index = map.get(numerL); + sb.insert(index, "("); + sb.append(")"); + break; + } else { + map.put(numerL, sb.length()); + } + } + + return sb.toString(); + } + + public String fractionToDecimal(int numerator, int denominator) { + + boolean isNegative= numerator<0 && denominator>0 || numerator>0 && denominator<0; + + StringBuilder sb= new StringBuilder(); + Map map= new HashMap<>(); + long numeratorL= Math.abs(Long.valueOf(numerator)); + long denominatorL= Math.abs(Long.valueOf(denominator)); + + long rem=numeratorL/denominatorL; + sb.append(rem); + + + + if(isNegative) sb.insert(0,'-'); + + if(numeratorL%denominatorL>0){ + sb.append("."); + }else{ + return sb.toString(); + } + numeratorL%=denominatorL; + map.put(numeratorL,sb.length()); + + while(numeratorL>0){ + numeratorL*=10; + + rem=numeratorL/denominatorL; + sb.append(rem); + numeratorL%=denominatorL; + if(map.containsKey(numeratorL)){ + int pos= map.get(numeratorL); + sb.insert(pos,"("); + sb.append(")"); + break; + }else{ + map.put(numeratorL,sb.length()); + } + + } + + return sb.toString(); + } + + +} diff --git a/src/practiceproblems/WaterTrapping.java b/src/practiceproblems/WaterTrapping.java new file mode 100644 index 0000000..1df9f1b --- /dev/null +++ b/src/practiceproblems/WaterTrapping.java @@ -0,0 +1,37 @@ +package practiceproblems; + +class WaterTrapping { + + static int findWater(int arr[], int n) { + int result = 0; + int leftMax = 0; + int rightMax = 0; + int low = 0; + int high = n - 1; + + while (low < high) { + if (arr[low] < arr[high]) { + if (arr[low] > leftMax) { + leftMax = arr[low]; + } else { + result += leftMax - arr[low]; + } + low++; + } else { + if (arr[high] > rightMax) { + rightMax = arr[high]; + } else { + result += rightMax - arr[high]; + } + high--; + } + } + return result; + } + + public static void main(String[] args) { + int arr[] = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1}; + int n = arr.length; + System.out.println("Maximum water that " + "can be accumulated is " + findWater(arr, n)); + } +} \ No newline at end of file diff --git a/src/practiceproblems/WordBreak.java b/src/practiceproblems/WordBreak.java new file mode 100644 index 0000000..653dadb --- /dev/null +++ b/src/practiceproblems/WordBreak.java @@ -0,0 +1,83 @@ +package practiceproblems; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +class WordBreak { + + /* +|T| | | | | | | | | + 0 1 2 3 4 5 6 7 8 + +i = 1 +j = o sub = l + +i = 2 +j = 0 sub = le +j = 1 sub = e + +i = 3 +j = 0 sub = lee +j = 1 sub = ee +j = 2 sub = e + +i = 4 +j = 0 sub = leet && T[0] and then break, no need to check for rest +|T | | | |T| | | | | +0 1 2 3 4 5 6 7 8 + +i = 5 +j = 0 sub = leetc +j = 1 sub = eetc +j = 2 sub = etc +j = 3 sub = tc +j = 4 sub = c + +i = 6 +j = 0 sub = leetco +j = 1 sub = eetco +j = 2 sub = etco +j = 3 sub = tco +j = 4 sub = co +j = 5 sub = o + +i = 7 +j = 0 sub = leetcod +j = 1 sub = eetcod +j = 2 sub = etcod +j = 3 sub = tcod +j = 4 sub = cod +j = 5 sub = od +j = 6 sub = d + +i = 8 +j = 0 sub = leetcode +j = 1 sub = eetcode +j = 2 sub = etcode +j = 3 sub = tcode +j = 4 sub = code && T[4] and then break + +|T| | | |T| | | |T| + 0 1 2 3 4 5 6 7 8 +*/ + public boolean wordBreak(String s, List wordDict) { + if (s == null) { + return false; + } + boolean[] dp = new boolean[s.length() + 1]; + dp[0] = true; + Set set = new HashSet<>(wordDict); + + for (int i = 1; i <= s.length(); i++) { + for (int j = 0; j < i; j++) { + dp[i] = dp[j] && set.contains(s.substring(j, i)); + if (dp[i]) { + break; + } + } + } + + return dp[s.length()]; + } +} \ No newline at end of file diff --git a/src/practiceproblems/WordBreakII.java b/src/practiceproblems/WordBreakII.java new file mode 100644 index 0000000..3b043e9 --- /dev/null +++ b/src/practiceproblems/WordBreakII.java @@ -0,0 +1,33 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class WordBreakII { + public List wordBreak(String s, List wordDict) { + Map> cache = new HashMap<>(); + backtrack(s,wordDict, cache); + return cache.get(s); + } + + public List backtrack(String s, List wordDict, Map> cache){ + + if(cache.containsKey(s)) return cache.get(s); + + List result = new ArrayList<>(); + for(String word: wordDict) { + if(!s.startsWith(word)) continue; // string does not start with this word? + String next = s.substring(word.length()); + if(next.isEmpty()) { // awesome! + result.add(word); + continue; + } + for(String sub: backtrack(next, wordDict, cache)) + result.add(word + " " + sub); + } + cache.put(s, result); + return result; + } +} \ No newline at end of file diff --git a/src/practiceproblems/WordDictionary.java b/src/practiceproblems/WordDictionary.java new file mode 100644 index 0000000..ef50133 --- /dev/null +++ b/src/practiceproblems/WordDictionary.java @@ -0,0 +1,69 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.Map; + +/** + * Design a data structure that supports the following two operations: + * void addWord(word) + * bool search(word) + * search(word) can search a literal word or + * a regular expression string containing only letters a-z or .. A . + * means it can represent any one letter. + * addWord("bad") + addWord("dad") + addWord("mad") + search("pad") -> false + search("bad") -> true + search(".ad") -> true + search("b..") -> true + */ +public class WordDictionary { + private TrieNode root; + + /** Initialize your data structure here. */ + private class TrieNode { + public Map children = new HashMap<>(); + public boolean isWord; + } + + public WordDictionary() { + root = new TrieNode(); + } + + /** Adds a word into the data structure. */ + public void addWord(String word) { + + TrieNode temp = root; + + for (char c : word.toCharArray()) { + if (temp.children.get(c) == null) + temp.children.put(c, new TrieNode()); + + temp = temp.children.get(c); + } + + temp.isWord = true; + } + + /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ + public boolean search(String word) { + return match(word.toCharArray(), 0, root); + } + + private boolean match(char[] chs, int k, TrieNode node) { + + if (k == chs.length) + return node.isWord; + + if (chs[k] == '.') { + for (Character curr: node.children.keySet()) { + if (node.children.get(curr) != null && match(chs, k+1, node.children.get(curr))) + return true; + } + } else + return node.children.get(chs[k]) != null && match(chs, k + 1, node.children.get(chs[k])); + + return false; + } +} \ No newline at end of file diff --git a/src/practiceproblems/WordLadder.java b/src/practiceproblems/WordLadder.java new file mode 100644 index 0000000..1627fb8 --- /dev/null +++ b/src/practiceproblems/WordLadder.java @@ -0,0 +1,45 @@ +package practiceproblems; + +import java.util.*; + +public class WordLadder { + public int ladderLength(String beginWord, String endWord, List wordList) { + Set set = new HashSet(wordList); + if(!set.contains(endWord)) return 0; // end word itself not in set + Queue queue = new LinkedList(); + queue.add(beginWord); + int count = 1; + + while(!queue.isEmpty()) { + + int size = queue.size(); + for (int i =0; i= board.length || i < 0 || j >= board[i].length || j < 0 || board[i][j] != word.charAt(index)) { + return false; + } + + board[i][j] = ' '; + if (search(board, word, i - 1, j, index + 1) || search(board, word, i + 1, j, index + 1) + || search(board, word, i, j - 1, index + 1) || search(board, word, i, j + 1, index + 1)) { + return true; + } + // resetting to old char since its DFS + + board[i][j] = word.charAt(index); + return false; + } + + public static void main(String[] args) { + char[][] board = {{'C', 'A', 'A'}, + {'A', 'A', 'A'}, + {'B', 'C', 'D'}}; + + System.out.println(exist(board, "AAB")); + } +} diff --git a/src/strings/common/sorting/ImplementABinaryHeap.java b/src/sorting/ImplementABinaryHeap.java similarity index 100% rename from src/strings/common/sorting/ImplementABinaryHeap.java rename to src/sorting/ImplementABinaryHeap.java diff --git a/src/strings/common/sorting/InsertionSort.java b/src/sorting/InsertionSort.java similarity index 100% rename from src/strings/common/sorting/InsertionSort.java rename to src/sorting/InsertionSort.java diff --git a/src/strings/common/sorting/KthLargestElement.java b/src/sorting/KthLargestElement.java similarity index 100% rename from src/strings/common/sorting/KthLargestElement.java rename to src/sorting/KthLargestElement.java diff --git a/src/strings/common/sorting/MaxHeap.java b/src/sorting/MaxHeap.java similarity index 100% rename from src/strings/common/sorting/MaxHeap.java rename to src/sorting/MaxHeap.java diff --git a/src/strings/common/sorting/MergeSort.java b/src/sorting/MergeSort.java similarity index 100% rename from src/strings/common/sorting/MergeSort.java rename to src/sorting/MergeSort.java diff --git a/src/strings/common/sorting/PractiseMergeSort.java b/src/sorting/PractiseMergeSort.java similarity index 100% rename from src/strings/common/sorting/PractiseMergeSort.java rename to src/sorting/PractiseMergeSort.java diff --git a/src/strings/common/sorting/QuickSelect.java b/src/sorting/QuickSelect.java similarity index 100% rename from src/strings/common/sorting/QuickSelect.java rename to src/sorting/QuickSelect.java diff --git a/src/strings/common/sorting/QuickSort.java b/src/sorting/QuickSort.java similarity index 100% rename from src/strings/common/sorting/QuickSort.java rename to src/sorting/QuickSort.java diff --git a/src/strings/dynamicProblems/All_Possible_Combinatons.java b/src/strings/dynamicProblems/All_Possible_Combinatons.java deleted file mode 100644 index f2cdc01..0000000 --- a/src/strings/dynamicProblems/All_Possible_Combinatons.java +++ /dev/null @@ -1,28 +0,0 @@ -package strings.dynamicProblems; - -public class All_Possible_Combinatons { - - static void printCombinations(char[] sequence, int N) { - char[] data = new char[N]; - for (int r = 0; r <= sequence.length; r++) - combinations(sequence, data, 0, N - 1, 0, r); - } - - static void combinations(char[] sequence, char[] data, int start, int end, int index, int r) { - if (index == r) { - for (int j = 0; j < r; j++) - System.out.print(data[j] + " "); - System.out.println(); - } - for (int i = start; i <= end && ((end - i + 1) >= (r - index)); i++) { - data[index] = sequence[i]; - combinations(sequence, data, i + 1, end, index + 1, r); - } - } - - public static void main(String args[]) { - char[] sequence = { 'a', 'b', 'c' }; - System.out.print("The combinations are: "); - printCombinations(sequence, sequence.length); - } -} \ No newline at end of file diff --git a/src/strings/dynamicProblems/DynamicIntegerGenerator.java b/src/strings/dynamicProblems/DynamicIntegerGenerator.java deleted file mode 100644 index dff340c..0000000 --- a/src/strings/dynamicProblems/DynamicIntegerGenerator.java +++ /dev/null @@ -1,29 +0,0 @@ -package strings.dynamicProblems; - -public class DynamicIntegerGenerator { - - public static void main(String[] args) { - - int[] arr = { 3, 4, 5, 6, 7, 8 }; - - for (int i = 1; i <= arr.length; i++) { - printDynamicIntegers(i, arr); - System.out.println(); - } - - } - - private static void printDynamicIntegers(int i, int[] arr) { - if (arr.length == i) { - for (int u = 0; u < arr.length; u++) { - System.out.print(arr[u]); - } - } - int[] intArr = new int[i]; - for (int j = 0; j < arr.length; j++) { - intArr[j] = arr[j]; - printDynamicIntegers(i, intArr); - } - } - -} diff --git a/src/strings/dynamicProblems/FirstNonRepeating.java b/src/strings/dynamicProblems/FirstNonRepeating.java deleted file mode 100644 index d1a04c4..0000000 --- a/src/strings/dynamicProblems/FirstNonRepeating.java +++ /dev/null @@ -1,34 +0,0 @@ -package strings.dynamicProblems; - -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedList; -import java.util.Queue; - -public class FirstNonRepeating { - - public static void main(String[] args) { - String data = "GeeksforGeeks"; - char[] arr = data.toCharArray(); - Queue stack = new LinkedList(); - for (char d : arr) { - stack.add(d); - } - while (!stack.isEmpty()) { - Character pop = stack.remove(); - if (!stack.contains(pop)) { - System.out.println(pop); - } - } - - Integer[] arrVal = {23,87,5,36,90,65}; - Arrays.sort(arrVal,Collections.reverseOrder()); - - for(Integer in:arrVal){ - System.out.print(in+" "); - } - } - - - -} diff --git a/src/strings/dynamicProblems/PossibleCombinations.java b/src/strings/dynamicProblems/PossibleCombinations.java deleted file mode 100644 index 24d8424..0000000 --- a/src/strings/dynamicProblems/PossibleCombinations.java +++ /dev/null @@ -1,29 +0,0 @@ -package strings.dynamicProblems; - -public class PossibleCombinations { - - public static void main(String[] args) { - char[] arr = { 'a', 'b', 'c' }; - combinations(arr, arr.length); - } - - private static void combinations(char[] arr, int length) { - char[] duplicate = new char[length]; - for (int r = 1; r <= length; r++) { - printCombinations(arr, duplicate, 0, length, 0, r); - } - - } - - private static void printCombinations(char[] arr, char[] data, int start, int end, int index, int r) { - if (index == r) { - for (int i = 0; i < r; i++) - System.out.print(data[i] + " "); - System.out.println(); - } - for (int i = start; i < end; i++) { - data[index] = arr[i]; - printCombinations(arr, data, i + 1, end, index + 1, r); - } - } -} diff --git a/src/strings/dynamicProblems/ReverseSentence.java b/src/strings/dynamicProblems/ReverseSentence.java deleted file mode 100644 index 60362a6..0000000 --- a/src/strings/dynamicProblems/ReverseSentence.java +++ /dev/null @@ -1,17 +0,0 @@ -package strings.dynamicProblems; - -import java.util.StringTokenizer; - -public class ReverseSentence { - - public static void main(String[] args) { - String sentence = "This is a Career Monk String"; - StringTokenizer st = new StringTokenizer(sentence); - String reverse = ""; - while (st.hasMoreTokens()) { - reverse = st.nextToken() + " " + reverse; - } - System.out.println(reverse); - } - -} \ No newline at end of file diff --git a/src/strings/dynamicProblems/Subsequence.java b/src/strings/dynamicProblems/Subsequence.java deleted file mode 100644 index b261983..0000000 --- a/src/strings/dynamicProblems/Subsequence.java +++ /dev/null @@ -1,36 +0,0 @@ -package strings.dynamicProblems; - -import java.util.HashSet; - -public class Subsequence { - - static HashSet st = new HashSet<>(); - - static void subsequence(String str) { - for (int i = 0; i < str.length(); i++) { - - for (int j = str.length(); j > i; j--) { - String sub_str = str.substring(i, j); - - if (!st.contains(sub_str)) - st.add(sub_str); - - for (int k = 1; k < sub_str.length() - 1; k++) { - StringBuffer sb = new StringBuffer(sub_str); - - sb.deleteCharAt(k); - if (!st.contains(sb)) - ; - subsequence(sb.toString()); - } - } - } - } - - // Driver code - public static void main(String[] args) { - String s = "abc"; - subsequence(s); - System.out.println(st); - } -} \ No newline at end of file From 2ab36ebb097453dc37a9af51da0bd79ff7e73d1d Mon Sep 17 00:00:00 2001 From: Vignesh Date: Sun, 25 Apr 2021 11:44:48 +0530 Subject: [PATCH 43/51] refactored packages --- .../Problems/SQL/AlterTableWithMonthName.sql | 35 ------------- .../Problems/SQL/ClassHavingMoreStudents.sql | 29 ----------- .../Problems/SQL/CustomersNerverOrders.sql | 24 --------- .../Problems/SQL/DeleteDuplicate.sql | 5 -- .../Problems/SQL/DepartmentHighestSalary.sql | 50 ------------------- .../Problems/SQL/DuplicateEmail.sql | 20 -------- .../SQL/EmployeeEarningHigherThanManagers.sql | 3 -- out/production/Problems/SQL/ExchangeSeats.sql | 27 ---------- .../Problems/SQL/FirstLoginDate.sql | 34 ------------- .../SQL/ManagerHaving5OrMoreReport.sql | 22 -------- .../Problems/SQL/NthHighestSalary.sql | 10 ---- .../Problems/SQL/RisingTemperature.sql | 23 --------- out/production/Problems/SQL/SubjectRanks.sql | 36 ------------- out/production/Problems/SQL/TeamSize.sql | 31 ------------ out/production/Problems/SQL/Top3Salaries.sql | 19 ------- .../Problems/SQL/Top3SalaryDepartmentWise.sql | 22 -------- .../Problems/SQL/WinningCandidate.sql | 10 ---- out/production/Problems/java8/Books.txt | 24 --------- .../Problems/java8/EmployeeData.txt | 10 ---- 19 files changed, 434 deletions(-) delete mode 100644 out/production/Problems/SQL/AlterTableWithMonthName.sql delete mode 100644 out/production/Problems/SQL/ClassHavingMoreStudents.sql delete mode 100644 out/production/Problems/SQL/CustomersNerverOrders.sql delete mode 100644 out/production/Problems/SQL/DeleteDuplicate.sql delete mode 100644 out/production/Problems/SQL/DepartmentHighestSalary.sql delete mode 100644 out/production/Problems/SQL/DuplicateEmail.sql delete mode 100644 out/production/Problems/SQL/EmployeeEarningHigherThanManagers.sql delete mode 100644 out/production/Problems/SQL/ExchangeSeats.sql delete mode 100644 out/production/Problems/SQL/FirstLoginDate.sql delete mode 100644 out/production/Problems/SQL/ManagerHaving5OrMoreReport.sql delete mode 100644 out/production/Problems/SQL/NthHighestSalary.sql delete mode 100644 out/production/Problems/SQL/RisingTemperature.sql delete mode 100644 out/production/Problems/SQL/SubjectRanks.sql delete mode 100644 out/production/Problems/SQL/TeamSize.sql delete mode 100644 out/production/Problems/SQL/Top3Salaries.sql delete mode 100644 out/production/Problems/SQL/Top3SalaryDepartmentWise.sql delete mode 100644 out/production/Problems/SQL/WinningCandidate.sql delete mode 100644 out/production/Problems/java8/Books.txt delete mode 100644 out/production/Problems/java8/EmployeeData.txt diff --git a/out/production/Problems/SQL/AlterTableWithMonthName.sql b/out/production/Problems/SQL/AlterTableWithMonthName.sql deleted file mode 100644 index 8541ba7..0000000 --- a/out/production/Problems/SQL/AlterTableWithMonthName.sql +++ /dev/null @@ -1,35 +0,0 @@ - ---when you give query like this ---SELECT id, ---CASE WHEN month = "Jan" THEN revenue END as "Jan_Revenue", ---CASE WHEN month = "Feb" THEN revenue END AS "Feb_Revenue" ---FROM Department; ---the output will be ---+----+-------------+-------------+ ---| id | Jan_Revenue | Feb_Revenue | ---+----+-------------+-------------+ ---| 1 | NULL | 7000 | ---| 1 | 8000 | NULL | ---| 1 | NULL | NULL | ---| 2 | 9000 | NULL | ---| 3 | NULL | 10000 | ---+----+-------------+-------------+ ---To get one row for each id we need to aggregate by id using GROUP BY. ---But since we have multiple rows with the same id but different values (e.g. for id=1 we have Jan_Revenues: --- NULL, 8000 and NULL. When we merge these 3 together what value should be chosen? ---This is why we need either SUM (NULL+8000+NULL) or MAX, in both cases 8000 will be used - -SELECT id, -MAX(CASE WHEN month='Jan' then revenue else null end) Jan_Revenue, -MAX(CASE WHEN month='Feb' then revenue else null end) Feb_Revenue, -MAX(CASE WHEN month='Mar' then revenue else null end) Mar_Revenue, -MAX(CASE WHEN month='Apr' then revenue else null end) Apr_Revenue, -MAX(CASE WHEN month='May' then revenue else null end) May_Revenue, -MAX(CASE WHEN month='Jun' then revenue else null end) Jun_Revenue, -MAX(CASE WHEN month='Jul' then revenue else null end) Jul_Revenue, -MAX(CASE WHEN month='Aug' then revenue else null end) Aug_Revenue, -MAX(CASE WHEN month='Sep' then revenue else null end) Sep_Revenue, -MAX(CASE WHEN month='Oct' then revenue else null end) Oct_Revenue, -MAX(CASE WHEN month='Nov' then revenue else null end) Nov_Revenue, -MAX(CASE WHEN month='Dec' then revenue else null end) Dec_Revenue -FROM Department GROUP BY id \ No newline at end of file diff --git a/out/production/Problems/SQL/ClassHavingMoreStudents.sql b/out/production/Problems/SQL/ClassHavingMoreStudents.sql deleted file mode 100644 index 86808a4..0000000 --- a/out/production/Problems/SQL/ClassHavingMoreStudents.sql +++ /dev/null @@ -1,29 +0,0 @@ ---+---------+------------+ ---| student | class | ---+---------+------------+ ---| A | Math | ---| B | English | ---| C | Math | ---| D | Biology | ---| E | Math | ---| F | Computer | ---| G | Math | ---| H | Math | ---| I | Math | ---+---------+------------+ - ---output: --- ---+---------+ ---| class | ---+---------+ ---| Math | ---+---------+ - - -SELECT - class -FROM - courses -GROUP BY class -HAVING COUNT(DISTINCT student) >= 5 \ No newline at end of file diff --git a/out/production/Problems/SQL/CustomersNerverOrders.sql b/out/production/Problems/SQL/CustomersNerverOrders.sql deleted file mode 100644 index 1bbd733..0000000 --- a/out/production/Problems/SQL/CustomersNerverOrders.sql +++ /dev/null @@ -1,24 +0,0 @@ ---Suppose that a website contains two tables, the Customers table and the Orders table. Write a SQL query to find all customers who never order anything. --- ---Table: Customers. --- ---+----+-------+ ---| Id | Name | ---+----+-------+ ---| 1 | Joe | ---| 2 | Henry | ---| 3 | Sam | ---| 4 | Max | ---+----+-------+ ---Table: Orders. --- ---+----+------------+ ---| Id | CustomerId | ---+----+------------+ ---| 1 | 3 | ---| 2 | 1 | ---+----+------------+ - - -select cu.Name as Customers from Customers cu left join Orders od on cu.Id=od.CustomerId -where od.CustomerId is null \ No newline at end of file diff --git a/out/production/Problems/SQL/DeleteDuplicate.sql b/out/production/Problems/SQL/DeleteDuplicate.sql deleted file mode 100644 index 06ea0f8..0000000 --- a/out/production/Problems/SQL/DeleteDuplicate.sql +++ /dev/null @@ -1,5 +0,0 @@ - - --- the below command will do cross product and generate all combinations of rows --- we are selecting a row with same Email and Greater Id -DELETE p1 from Person p1, Person p2 where p1.Email=p2.Email and p1.Id>p2.Id \ No newline at end of file diff --git a/out/production/Problems/SQL/DepartmentHighestSalary.sql b/out/production/Problems/SQL/DepartmentHighestSalary.sql deleted file mode 100644 index 2589613..0000000 --- a/out/production/Problems/SQL/DepartmentHighestSalary.sql +++ /dev/null @@ -1,50 +0,0 @@ - ---+----+-------+--------+--------------+ ---| Id | Name | Salary | DepartmentId | ---+----+-------+--------+--------------+ ---| 1 | Joe | 70000 | 1 | ---| 2 | Jim | 90000 | 1 | ---| 3 | Henry | 80000 | 2 | ---| 4 | Sam | 60000 | 2 | ---| 5 | Max | 90000 | 1 | ---+----+-------+--------+--------------+ - ---+----+----------+ ---| Id | Name | ---+----+----------+ ---| 1 | IT | ---| 2 | Sales | ---+----+----------+ - ---OUTPUT ---+------------+----------+--------+ ---| Department | Employee | Salary | ---+------------+----------+--------+ ---| IT | Max | 90000 | ---| IT | Jim | 90000 | ---| Sales | Henry | 80000 | ---+------------+----------+--------+ - ---this inner query will give single top salaries for each dept, however if there are multiple people who gets the same salary? we do one more join --- SELECT d.Id --- , MAX(d.Name) AS Name --- , MAX(e.Salary) AS Salary --- FROM Department d --- JOIN Employee e --- ON e.DepartmentId = d.Id --- GROUP BY d.Id - -SELECT d1.Name as Department - , e1.Name as Employee - , e1.Salary -FROM ( - SELECT d.Id - , MAX(d.Name) AS Name - , MAX(e.Salary) AS Salary - FROM Department d - JOIN Employee e - ON e.DepartmentId = d.Id - GROUP BY d.Id -) d1 -JOIN Employee e1 -ON d1.Id = e1.DepartmentId AND e1.Salary = d1.Salary \ No newline at end of file diff --git a/out/production/Problems/SQL/DuplicateEmail.sql b/out/production/Problems/SQL/DuplicateEmail.sql deleted file mode 100644 index b635a55..0000000 --- a/out/production/Problems/SQL/DuplicateEmail.sql +++ /dev/null @@ -1,20 +0,0 @@ ---Write a SQL query to find all duplicate emails in a table named Person. ---+----+---------+ ---| Id | Email | ---+----+---------+ ---| 1 | a@b.com | ---| 2 | c@d.com | ---| 3 | a@b.com | ---+----+---------+ - -select distinct(t1.Email) as Email -from Person t1 -where 1<( - select count(t2.Email) - from Person t2 where t1.Email=t2.Email) - - -- Inner Join concept -select distinct p1.Email -from Person p1 -inner join Person p2 on p1.Email=P2.Email -where p1.Id <> p2.Id \ No newline at end of file diff --git a/out/production/Problems/SQL/EmployeeEarningHigherThanManagers.sql b/out/production/Problems/SQL/EmployeeEarningHigherThanManagers.sql deleted file mode 100644 index f912bae..0000000 --- a/out/production/Problems/SQL/EmployeeEarningHigherThanManagers.sql +++ /dev/null @@ -1,3 +0,0 @@ - - -select tb1.Name as Employee from Employee tb1 inner join Employee tb2 on tb1.ManagerId=tb2.Id where tb1.Salary>tb2.Salary diff --git a/out/production/Problems/SQL/ExchangeSeats.sql b/out/production/Problems/SQL/ExchangeSeats.sql deleted file mode 100644 index 3e425ec..0000000 --- a/out/production/Problems/SQL/ExchangeSeats.sql +++ /dev/null @@ -1,27 +0,0 @@ ---Mary is a teacher in a middle school and she has a table seat storing students' names and their corresponding seat ids. --- ---The column id is continuous increment. --- ---+---------+---------+ ---| id | student | ---+---------+---------+ ---| 1 | Abbot | ---| 2 | Doris | ---| 3 | Emerson | ---| 4 | Green | ---| 5 | Jeames | ---+---------+---------+ - ---For students with odd id, the new id is (id+1) after switch unless it is the last seat. And for students with even id, the new id is (id-1). ---In order to know how many seats in total, we can use a subquery: ---gotcha is when we do id+1 we shouldn't exceed the row number so when id==count we leave as is - -select (case - when MOD(id,2)!=0 && id!=counts then id+1 - when MOD(id,2)!=0 && id=counts then id - else id-1 - end) as id, student - from - seat, - (select count(*) as counts from seat) as seat_counts - order by id asc \ No newline at end of file diff --git a/out/production/Problems/SQL/FirstLoginDate.sql b/out/production/Problems/SQL/FirstLoginDate.sql deleted file mode 100644 index 9d78cce..0000000 --- a/out/production/Problems/SQL/FirstLoginDate.sql +++ /dev/null @@ -1,34 +0,0 @@ - ---Write an SQL query that reports the first login date for each player. --- ---The query result format is in the following example: --- ---Activity table: ---+-----------+-----------+------------+--------------+ ---| player_id | device_id | event_date | games_played | ---+-----------+-----------+------------+--------------+ ---| 1 | 2 | 2016-03-01 | 5 | ---| 1 | 2 | 2016-05-02 | 6 | ---| 2 | 3 | 2017-06-25 | 1 | ---| 3 | 1 | 2016-03-02 | 0 | ---| 3 | 4 | 2018-07-03 | 5 | ---+-----------+-----------+------------+--------------+ --- ---Result table: ---+-----------+-------------+ ---| player_id | first_login | ---+-----------+-------------+ ---| 1 | 2016-03-01 | ---| 2 | 2017-06-25 | ---| 3 | 2016-03-02 | ---+-----------+-------------+ - - -select player_id, min(event_date) as first_login from Activity group by player_id - - ---the following query is to try and get first loggedin deviceId - -SELECT player_id, device_id FROM Activity -WHERE (player_id, event_date) IN -(SELECT player_id, MIN(event_date) first_date FROM Activity GROUP BY player_id) \ No newline at end of file diff --git a/out/production/Problems/SQL/ManagerHaving5OrMoreReport.sql b/out/production/Problems/SQL/ManagerHaving5OrMoreReport.sql deleted file mode 100644 index 988a525..0000000 --- a/out/production/Problems/SQL/ManagerHaving5OrMoreReport.sql +++ /dev/null @@ -1,22 +0,0 @@ - ---+------+----------+-----------+----------+ ---|Id |Name |Department |ManagerId | ---+------+----------+-----------+----------+ ---|101 |John |A |null | ---|102 |Dan |A |101 | ---|103 |James |A |101 | ---|104 |Amy |A |101 | ---|105 |Anne |A |101 | ---|106 |Ron |B |101 | ---+------+----------+-----------+----------+ --- ---Given the Employee table, write a SQL query that finds out managers with at least 5 direct report. For the above table, your SQL query should return: --- ---+-------+ ---| Name | ---+-------+ ---| John | ---+-------+ - - -select (e2.Name) from Employee e1 inner join Employee e2 on e1.ManagerId=e2.Id group by e1.managerid having count(*) >= 5 diff --git a/out/production/Problems/SQL/NthHighestSalary.sql b/out/production/Problems/SQL/NthHighestSalary.sql deleted file mode 100644 index 812e4cc..0000000 --- a/out/production/Problems/SQL/NthHighestSalary.sql +++ /dev/null @@ -1,10 +0,0 @@ ---N is passed as parameter - -CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT -BEGIN -DECLARE M INT; #note variable declaration -SET M=N-1; - RETURN ( - select distinct(salary) from Employee order by Salary desc limit M,1 - ); -END \ No newline at end of file diff --git a/out/production/Problems/SQL/RisingTemperature.sql b/out/production/Problems/SQL/RisingTemperature.sql deleted file mode 100644 index 6e0492d..0000000 --- a/out/production/Problems/SQL/RisingTemperature.sql +++ /dev/null @@ -1,23 +0,0 @@ - ---Given a Weather table, write a SQL query to find all dates' Ids with higher temperature compared to its previous (yesterday's) dates. --- ---+---------+------------------+------------------+ ---| Id(INT) | RecordDate(DATE) | Temperature(INT) | ---+---------+------------------+------------------+ ---| 1 | 2015-01-01 | 10 | ---| 2 | 2015-01-02 | 25 | ---| 3 | 2015-01-03 | 20 | ---| 4 | 2015-01-04 | 30 | ---+---------+------------------+------------------+ - - ---+----+ ---| Id | ---+----+ ---| 2 | ---| 4 | ---+----+ -SELECT wt1.Id -FROM Weather wt1, Weather wt2 -WHERE wt1.Temperature > wt2.Temperature AND - TO_DAYS(wt1.RecordDate)-TO_DAYS(wt2.RecordDate)=1; \ No newline at end of file diff --git a/out/production/Problems/SQL/SubjectRanks.sql b/out/production/Problems/SQL/SubjectRanks.sql deleted file mode 100644 index bae55fe..0000000 --- a/out/production/Problems/SQL/SubjectRanks.sql +++ /dev/null @@ -1,36 +0,0 @@ - ---+----+-------+ ---| Id | Score | ---+----+-------+ ---| 1 | 3.50 | ---| 2 | 3.65 | ---| 3 | 4.00 | ---| 4 | 3.85 | ---| 5 | 4.00 | ---| 6 | 3.65 | ---+----+-------+ - ---+-------+---------+ ---| score | Rank | ---+-------+---------+ ---| 4.00 | 1 | ---| 4.00 | 1 | ---| 3.85 | 2 | ---| 3.65 | 3 | ---| 3.65 | 3 | ---| 3.50 | 4 | ---+-------+---------+ - - -SELECT - Score, - (SELECT count(distinct Score) FROM Scores WHERE Score >= s.Score) "Rank" -- inner for-loop -FROM Scores s -ORDER BY Score desc - - -SELECT - Score, - (SELECT count(distinct Score) FROM Scores WHERE Score >= s.Score) "Rank" -FROM Scores s -ORDER BY Score desc \ No newline at end of file diff --git a/out/production/Problems/SQL/TeamSize.sql b/out/production/Problems/SQL/TeamSize.sql deleted file mode 100644 index 37cb0c3..0000000 --- a/out/production/Problems/SQL/TeamSize.sql +++ /dev/null @@ -1,31 +0,0 @@ ---Employee Table: ---+-------------+------------+ ---| employee_id | team_id | ---+-------------+------------+ ---| 1 | 8 | ---| 2 | 8 | ---| 3 | 8 | ---| 4 | 7 | ---| 5 | 9 | ---| 6 | 9 | ---+-------------+------------+ ---Result table: ---+-------------+------------+ ---| employee_id | team_size | ---+-------------+------------+ ---| 1 | 3 | ---| 2 | 3 | ---| 3 | 3 | ---| 4 | 1 | ---| 5 | 2 | ---| 6 | 2 | ---+-------------+------------+ ---Employees with Id 1,2,3 are part of a team with team_id = 8. so team_size is 3 ---Employees with Id 4 is part of a team with team_id = 7. ---Employees with Id 5,6 are part of a team with team_id = 9. - - -# Write your MySQL query statement below - -select employee_id, (select count(*) from Employee tb2 where tb2.team_id=tb1.team_id) as team_size -from Employee tb1 \ No newline at end of file diff --git a/out/production/Problems/SQL/Top3Salaries.sql b/out/production/Problems/SQL/Top3Salaries.sql deleted file mode 100644 index a5b0a95..0000000 --- a/out/production/Problems/SQL/Top3Salaries.sql +++ /dev/null @@ -1,19 +0,0 @@ ---to get to 3 salaries from a table --- select * from Employee where salary >= {value} this value we need to calculate dynamically (some min value in top 3 salaries) --- so select min(Salary) from (select distinct(salary) from Employee order by Salary DESC limit 3) this will fetch min of top 3 salaries --- add this to original query ---+----+-------------+-------------+ ---| id | Name | Salary | ---+----+-------------+-------------+ ---| 1 | A | 7000 | ---| 2 | B | 6000 | ---| 3 | C | 6000 | ---| 4 | D | 6000 | ---| 5 | E | 4000 | ---| 6 | F | 3000 | ---| 7 | G | 3000 | ---| 8 | H | 2000 | ---| 9 | I | 1000 | ---+----+-------------+-------------+ - -select * from Employee where salary >= (select min(Salary) from (select distinct(salary) from Employee order by Salary DESC limit 3)) \ No newline at end of file diff --git a/out/production/Problems/SQL/Top3SalaryDepartmentWise.sql b/out/production/Problems/SQL/Top3SalaryDepartmentWise.sql deleted file mode 100644 index 6f59397..0000000 --- a/out/production/Problems/SQL/Top3SalaryDepartmentWise.sql +++ /dev/null @@ -1,22 +0,0 @@ --- ---Now, for each row of the outer query: ---OuterDepartmentId, OuterEmployeeSalary is available to the inner query. ---The inner query will fetch all the salaries that are greater then OuterEmployeeSalary for department matching OuterDepartmentId ---and return a count of such distinct salaries --- ---This count can be 0,1 or 2 --- ---if 0 -> that means there are no salaries greater then the OuterDepartmentSalary in that department. Hence, it is the greatest salary for that department. And outer query will include that OuterDepartmentId, OuterEmployeeSalary in the output. --- ---if 1 -> there is one salary bigger then OuterEmployeeSalary (it is the second largest salary) --- ---similarly for count 2, there are two larger salaries. - -select d.Name Department, e1.Name Employee, e1.Salary -from Employee e1 -join Department d -on e1.DepartmentId = d.Id -where 3>(select count(distinct(e2.Salary)) - from Employee e2 - where e2.Salary > e1.Salary - and e1.DepartmentId = e2.DepartmentId) -- the inner query will act as inner for loop which get e.salary from outside O(n^2) \ No newline at end of file diff --git a/out/production/Problems/SQL/WinningCandidate.sql b/out/production/Problems/SQL/WinningCandidate.sql deleted file mode 100644 index 4313ba7..0000000 --- a/out/production/Problems/SQL/WinningCandidate.sql +++ /dev/null @@ -1,10 +0,0 @@ - - -SELECT Name -FROM Candidate c -INNER JOIN (SELECT CandidateId - FROM Vote - GROUP BY CandidateId - ORDER BY COUNT(CandidateId) DESC - LIMIT 0,1) v -ON c.id = v.CandidateId \ No newline at end of file diff --git a/out/production/Problems/java8/Books.txt b/out/production/Problems/java8/Books.txt deleted file mode 100644 index 7d652e6..0000000 --- a/out/production/Problems/java8/Books.txt +++ /dev/null @@ -1,24 +0,0 @@ -Gulliver's Travels  -Jonathan Swift -Fantasy Fiction -4 -Frankenstein -Mary Shelley -Science Fiction -4 -The Woman in White  -Wilkie Collins -Mystery -4.1 -Alice's Adventures In Wonderland  -Lewis Carroll -Fairy tale -4.1 -Three Men in a Boat  -Jerome K. Jerome -Humorous Fiction -4 -Brave New World  -Aldous Huxley -Science Fiction -4.2 \ No newline at end of file diff --git a/out/production/Problems/java8/EmployeeData.txt b/out/production/Problems/java8/EmployeeData.txt deleted file mode 100644 index d752b0b..0000000 --- a/out/production/Problems/java8/EmployeeData.txt +++ /dev/null @@ -1,10 +0,0 @@ -27827,Richard,M,1988-06-10,Boston,Developer,2017-12-12,60000.00 -27828,John,M,1978-07-11,Boston,Architect,2015-01-01,150000.00 -27829,David,M,1982-09-12,Newyork City,Manager,2015-01-19,145000.00 -27830,Meenal,F,1991-01-13,Austin,Developer,2018-07-05,65000.00 -27831,Ginni,F,1993-06-14,Delhi,Developer,2017-12-12,72000.00 -27832,Tom,M,1988-03-15,Banglore,Developer,2019-01-10,69000.00 -27833,Michael,M,1984-04-16,London,Lead,2018-09-21,87000.00 -27834,Alexa,F,1995-10-29,Newyork City,Developer,2019-10-11,65000.00 -27835,Peter,M,1993-02-09,London,Developer,2019-10-11,63000.00 -27836,Parvati,F,1991-12-14,Jaipur,Lead,2017-06-10,89000.00 \ No newline at end of file From 0a638ba81053e631cf4710e65cb42e246ca0d93a Mon Sep 17 00:00:00 2001 From: Vignesh Date: Fri, 21 May 2021 15:51:43 +0530 Subject: [PATCH 44/51] binarysearch and java8 --- .gitignore | 3 +- .../FindMinimumInRotatedArray.java | 41 +- src/binarysearch/FirstAndLastOccurence.java | 59 +-- src/binarysearch/MaxSoldiers.java | 13 +- src/binarysearch/PeakElement.java | 53 +-- .../SearchElementInSortedAndRotatedArray.java | 2 +- .../FibonacciStaircaseWaysToCoverDist.java | 20 +- src/geeksforgeeks/.vscode/UrlEncode.java | 0 src/geeksforgeeks/.vscode/launch.json | 178 --------- src/geeksforgeeks/.vscode/settings.json | 9 - src/geeksforgeeks/AdvantageShuffle.java | 40 -- src/geeksforgeeks/AircraftOptimization.java | 69 ---- .../AlternateOddAndEvenNumbers.java | 50 --- src/geeksforgeeks/AngleOfClock.java | 15 - src/geeksforgeeks/ArrangeInQueue.java | 52 --- src/geeksforgeeks/ArticulationPoint.java | 369 ------------------ src/geeksforgeeks/AutoCompleteSystem.java | 97 ----- src/geeksforgeeks/BackspaceCompare.java | 63 --- src/geeksforgeeks/BasicCalculator.java | 64 --- src/geeksforgeeks/BinaryTreeCousins.java | 51 --- src/geeksforgeeks/BitonicSearch.java | 102 ----- src/geeksforgeeks/BoatsToSave.java | 36 -- src/geeksforgeeks/BuyAndSellStockAnytime.java | 23 -- .../BuyAndSellStockAtMostTwice.java | 50 --- src/geeksforgeeks/Candy.java | 58 --- src/geeksforgeeks/CelebrityProblem.java | 29 -- .../CheckPalindromePermutation.java | 32 -- src/geeksforgeeks/CloneGraph.java | 70 ---- src/geeksforgeeks/ClosestNumbers.java | 47 --- src/geeksforgeeks/CombinationIterator.java | 53 --- src/geeksforgeeks/CompareVersions.java | 31 -- .../ConstructBSTFromPreorder.java | 81 ---- .../ConstructTreeFromInorderAndPostorder.java | 31 -- .../ConstructTreeFromInorderAndPreorder.java | 49 --- src/geeksforgeeks/ContainerWithMostWater.java | 36 -- src/geeksforgeeks/ConvertXToY.java | 69 ---- .../CountAllPathsFrom2DMatrix.java | 43 -- src/geeksforgeeks/CountAndSay.java | 41 -- src/geeksforgeeks/CountElements.java | 59 --- ...ntMinimumStepsToFormDesiredInputArray.java | 70 ---- .../CountNumbersLessThanSelf.java | 103 ----- src/geeksforgeeks/CountingInversion.java | 62 --- src/geeksforgeeks/CourseSchedule.java | 116 ------ src/geeksforgeeks/DecodeString.java | 51 --- .../DesignCompressedStringIterator.java | 59 --- src/geeksforgeeks/DesignFileSystem.java | 64 --- .../DesignInMemoryFileSystem.java | 96 ----- src/geeksforgeeks/DesignStackIncrement.java | 101 ----- src/geeksforgeeks/DesignTicTacToe.java | 107 ----- .../DifferentWaysToAddParenthesis.java | 61 --- src/geeksforgeeks/DivideSubArrayAverage.java | 47 --- src/geeksforgeeks/DungeonGame.java | 64 --- src/geeksforgeeks/DutchNationalFlag.java | 31 -- src/geeksforgeeks/EvaluvateRPN.java | 47 --- src/geeksforgeeks/FenwickTree.java | 112 ------ src/geeksforgeeks/FindAllAnagram.java | 60 --- src/geeksforgeeks/FindMissingNumbers.java | 44 --- src/geeksforgeeks/FindSmallestInteger.java | 45 --- src/geeksforgeeks/FirstMissingPositive.java | 106 ----- .../FirstNonRepeatedCharacter.java | 26 -- .../FirstNonRepeatingCharacterStream.java | 108 ----- src/geeksforgeeks/Flatten2DVector.java | 72 ---- src/geeksforgeeks/FlattenLinkedList.java | 145 ------- .../FlattenMultiLevelLinkedList.java | 48 --- .../FlipMaximizeZeroesSubarrayKadane.java | 40 -- ...lipZeroesToFormConsecutiveMaximumOnes.java | 57 --- src/geeksforgeeks/FourSum.java | 64 --- src/geeksforgeeks/FrequencySort.java | 34 -- src/geeksforgeeks/GameOfLife.java | 61 --- src/geeksforgeeks/GenerateParenthesis.java | 44 --- src/geeksforgeeks/GrammarMistake.java | 83 ---- src/geeksforgeeks/GraphBiPartite.java | 52 --- src/geeksforgeeks/GraphSplitwiseSimplify.java | 141 ------- src/geeksforgeeks/GroupAnagrams.java | 29 -- src/geeksforgeeks/GroupIsomorphicString.java | 56 --- src/geeksforgeeks/HappyNumber.java | 57 --- src/geeksforgeeks/HitCounter.java | 31 -- src/geeksforgeeks/HouseRobber.java | 46 --- src/geeksforgeeks/IPOMaxProfit.java | 46 --- src/geeksforgeeks/InMemeoryFIleSystem.java | 136 ------- src/geeksforgeeks/InOrderSuccessor.java | 28 -- .../InorderSuccessorPredecessor.java | 105 ----- src/geeksforgeeks/InsertIntervals.java | 36 -- src/geeksforgeeks/InsertionSortList.java | 38 -- src/geeksforgeeks/IntegerToBinary.java | 38 -- src/geeksforgeeks/IntersectionOfArrays.java | 79 ---- src/geeksforgeeks/IsEditOneDistanceAway.java | 63 --- src/geeksforgeeks/IsSubsequence.java | 22 -- src/geeksforgeeks/IslandBFS.java | 59 --- src/geeksforgeeks/Islands.java | 44 --- src/geeksforgeeks/IsomorphicString.java | 31 -- src/geeksforgeeks/JumpsToReachEnd.java | 96 ----- src/geeksforgeeks/KClosestElements.java | 66 ---- src/geeksforgeeks/KmostFrequentLetters.java | 50 --- src/geeksforgeeks/KthClosestOrigin.java | 74 ---- .../KthSmallestFromTwoSortedArrays.java | 43 -- src/geeksforgeeks/KthSmallestMatrix.java | 51 --- src/geeksforgeeks/LIS2DMatrix.java | 52 --- src/geeksforgeeks/LRUCache.java | 123 ------ src/geeksforgeeks/LargestDivisibleSubset.java | 66 ---- src/geeksforgeeks/LargestPossibleNumber.java | 55 --- .../LargestSubArrayWithZeroesAndOnes.java | 68 ---- src/geeksforgeeks/LargestTimeFromDigits.java | 39 -- .../LengthOfLongestSubstringKDistinct.java | 40 -- .../LinkedListRemoveDuplicates.java | 36 -- .../LongestConsequtiveSequence.java | 73 ---- .../LongestIncreasingPathInMatrix.java | 64 --- .../LongestRepeatCharReplace.java | 47 --- .../LongestSpanWithSameSumArray.java | 74 ---- .../LongestSubArraySumUtmostK.java | 47 --- src/geeksforgeeks/LongestUniqueSubstring.java | 53 --- src/geeksforgeeks/MajorityVoting.java | 86 ---- src/geeksforgeeks/MakeAnArrayPalindrome.java | 41 -- src/geeksforgeeks/MatrixRowWithMax1.java | 48 --- .../MaxDistinctElementAfterKRemoval.java | 118 ------ src/geeksforgeeks/MaxFreqStack.java | 75 ---- src/geeksforgeeks/MaxHistogram.java | 68 ---- src/geeksforgeeks/MaxProductString.java | 57 --- src/geeksforgeeks/MaxWidthOfBinaryTree.java | 61 --- src/geeksforgeeks/MaximumDifference.java | 26 -- src/geeksforgeeks/MaximumGap.java | 70 ---- src/geeksforgeeks/MaximumProductSubarray.java | 63 --- .../MaximumSubstringWithKDistinctChar.java | 75 ---- .../MaximumUnsortedSubarray.java | 90 ----- src/geeksforgeeks/MedianOfKWindow.java | 49 --- .../MedianOfRunningIntegers.java | 45 --- .../MedianOfTwoSortedArrays.java | 79 ---- src/geeksforgeeks/MeetingRoomsII.java | 63 --- .../MergeIntervalIntersection.java | 42 -- src/geeksforgeeks/MergeIntervals.java | 44 --- src/geeksforgeeks/MergeSortLinkedList.java | 80 ---- src/geeksforgeeks/MergeTwoLinkedList.java | 46 --- src/geeksforgeeks/MinCostRopeConnect.java | 34 -- src/geeksforgeeks/MinStepsToConvertXtoY.java | 49 --- src/geeksforgeeks/MinTimeRotOranges.java | 102 ----- src/geeksforgeeks/MinimumBribes.java | 50 --- .../MinimumDistanceBetweenTwoNumbers.java | 52 --- .../MinimumIndexDistanceOfMaximumNumbers.java | 31 -- src/geeksforgeeks/MinimumPathSum.java | 40 -- src/geeksforgeeks/MinimumStack.java | 131 ------- src/geeksforgeeks/MinimumStepsKnight.java | 91 ----- src/geeksforgeeks/MinimumSwapSortArray.java | 59 --- .../MinimumWindowSubsequence.java | 80 ---- src/geeksforgeeks/MinimumWindowSubstring.java | 62 --- src/geeksforgeeks/MirrorBinaryTree.java | 72 ---- .../MobileKeyPadCombinations.java | 59 --- src/geeksforgeeks/MoveZeroes.java | 34 -- src/geeksforgeeks/NQueens.java | 90 ----- src/geeksforgeeks/NewRoadsMST.java | 86 ---- src/geeksforgeeks/NextGreaterElement.java | 90 ----- src/geeksforgeeks/NextGreaterNumber.java | 76 ---- src/geeksforgeeks/NextLargestList.java | 58 --- src/geeksforgeeks/Node.java | 82 ---- src/geeksforgeeks/NonDecreasingArray.java | 31 -- src/geeksforgeeks/NumberOfBallons.java | 24 -- src/geeksforgeeks/NutsAndBoltsMatch.java | 74 ---- src/geeksforgeeks/OverlappingIntervals.java | 42 -- src/geeksforgeeks/OwnDataStructureUtil.java | 56 --- src/geeksforgeeks/PalindromePartion.java | 52 --- src/geeksforgeeks/PalindromePartitioning.java | 57 --- .../PalindromeSinglyLinkedList.java | 64 --- src/geeksforgeeks/PalindromicSubSequence.java | 52 --- src/geeksforgeeks/PartitionLabel.java | 50 --- src/geeksforgeeks/PascalsTriangle.java | 70 ---- src/geeksforgeeks/PathSumIII.java | 48 --- src/geeksforgeeks/Pattern132.java | 33 -- src/geeksforgeeks/PerfectSquare.java | 74 ---- src/geeksforgeeks/PermutationInString.java | 62 --- src/geeksforgeeks/PetrolGasStation.java | 37 -- src/geeksforgeeks/PlusOne.java | 38 -- src/geeksforgeeks/Pow.java | 52 --- src/geeksforgeeks/PrisonAfterNDays.java | 54 --- src/geeksforgeeks/ProductExceptSelf.java | 52 --- src/geeksforgeeks/QueensAttackKing.java | 54 --- src/geeksforgeeks/RaceCarMinSteps.java | 45 --- src/geeksforgeeks/RandomLinkedList.java | 62 --- src/geeksforgeeks/RandomPickWithWeight.java | 54 --- src/geeksforgeeks/RangeSum.java | 41 -- src/geeksforgeeks/ReconstructItenary.java | 46 --- src/geeksforgeeks/RedundantConnection.java | 44 --- .../RemoveAdjacentDuplicates.java | 29 -- src/geeksforgeeks/RemoveDuplicates.java | 27 -- .../RemoveInvalidParentheses.java | 61 --- src/geeksforgeeks/RemoveKDigits.java | 60 --- src/geeksforgeeks/ReorderLogs.java | 58 --- src/geeksforgeeks/ReorganiseString.java | 71 ---- src/geeksforgeeks/RestoreIpAddresses.java | 53 --- src/geeksforgeeks/ReverseWordsInString.java | 40 -- src/geeksforgeeks/RollingHashRabinKarp.java | 134 ------- src/geeksforgeeks/RomanToInteger.java | 34 -- src/geeksforgeeks/RotateArray.java | 30 -- src/geeksforgeeks/RotateMatrixInPlace.java | 102 ----- .../RotateMatrixInPlaceAntiClockwise.java | 63 --- src/geeksforgeeks/SameTree.java | 62 --- src/geeksforgeeks/SearchAMaze.java | 80 ---- .../SearchAnElementInMatrix.java | 74 ---- .../SerializeAndDeserialize.java | 80 ---- .../SerializeDeserializeBST.java | 76 ---- src/geeksforgeeks/SetBitCount.java | 21 - src/geeksforgeeks/ShuffleArray.java | 53 --- src/geeksforgeeks/SimilarExpressions.java | 55 --- .../SingleElementInSortedArray.java | 44 --- src/geeksforgeeks/SlidingWindow.java | 75 ---- src/geeksforgeeks/SnakeAndLadder.java | 70 ---- src/geeksforgeeks/SnakeGame.java | 88 ----- src/geeksforgeeks/SortANearlySortedArray.java | 41 -- src/geeksforgeeks/SortStack.java | 31 -- src/geeksforgeeks/SortedArrayToBST.java | 39 -- src/geeksforgeeks/SortedSquares.java | 28 -- src/geeksforgeeks/SpiralMatrix.java | 68 ---- src/geeksforgeeks/SpiralMatrixII.java | 56 --- src/geeksforgeeks/SplitLinkedList.java | 47 --- src/geeksforgeeks/StockBuySellManyTimes.java | 84 ---- src/geeksforgeeks/StockSpanner.java | 26 -- src/geeksforgeeks/StringIterator.java | 37 -- .../SubArraySumDivisibleByK.java | 48 --- src/geeksforgeeks/SubArraySumEqualsK.java | 57 --- .../SubstringWindowTemplate.java | 62 --- src/geeksforgeeks/SumOfThreeElements.java | 39 -- src/geeksforgeeks/SumSubArrayZero.java | 65 --- src/geeksforgeeks/SurroundedRegions.java | 142 ------- src/geeksforgeeks/SwapRecoverBST.java | 54 --- src/geeksforgeeks/SymmetricTree.java | 21 - src/geeksforgeeks/TaskLeastInterval.java | 55 --- src/geeksforgeeks/ThreeSum.java | 40 -- src/geeksforgeeks/TimeMap.java | 67 ---- src/geeksforgeeks/TopKFrequentElement.java | 38 -- src/geeksforgeeks/TopKFrequentElements.java | 38 -- src/geeksforgeeks/TrailingZeroes.java | 19 - src/geeksforgeeks/TreasureIsland.java | 66 ---- src/geeksforgeeks/TreasureIslandII.java | 82 ---- src/geeksforgeeks/Trie.java | 65 --- src/geeksforgeeks/Twitter.java | 140 ------- src/geeksforgeeks/TwoCityScheduling.java | 49 --- src/geeksforgeeks/TwoSumClosestToZero.java | 49 --- src/geeksforgeeks/UnSortedSubArray.java | 54 --- src/geeksforgeeks/UniqueElementsInArray.java | 29 -- src/geeksforgeeks/UniquePath.java | 89 ----- src/geeksforgeeks/UniquePathMaximum.java | 46 --- src/geeksforgeeks/UrlEncode.java | 45 --- src/geeksforgeeks/ValidPalindromeII.java | 40 -- src/geeksforgeeks/ValidParentheses.java | 26 -- src/geeksforgeeks/ValidParenthesesString.java | 45 --- src/geeksforgeeks/ValidSudoku.java | 35 -- src/geeksforgeeks/ValidateIpAddresses.java | 65 --- src/geeksforgeeks/VulgarDecimal.java | 115 ------ src/geeksforgeeks/WaterTrapping.java | 37 -- src/geeksforgeeks/WordBreak.java | 83 ---- src/geeksforgeeks/WordBreakII.java | 33 -- src/geeksforgeeks/WordDictionary.java | 69 ---- src/geeksforgeeks/WordLadder.java | 45 --- src/geeksforgeeks/WordSearch.java | 47 --- src/practiceproblems/CountingInversion.java | 3 +- src/practiceproblems/PascalsTriangle.java | 37 +- src/sorting/ImplementABinaryHeap.java | 2 +- src/sorting/InsertionSort.java | 2 +- src/sorting/KthLargestElement.java | 2 +- src/sorting/MaxHeap.java | 2 +- src/sorting/MergeSort.java | 2 +- src/sorting/PractiseMergeSort.java | 2 +- src/sorting/QuickSelect.java | 2 +- src/sorting/QuickSort.java | 2 +- .../FindLongestStringInArray.java | 2 +- 263 files changed, 118 insertions(+), 14928 deletions(-) delete mode 100644 src/geeksforgeeks/.vscode/UrlEncode.java delete mode 100644 src/geeksforgeeks/.vscode/launch.json delete mode 100644 src/geeksforgeeks/.vscode/settings.json delete mode 100644 src/geeksforgeeks/AdvantageShuffle.java delete mode 100644 src/geeksforgeeks/AircraftOptimization.java delete mode 100644 src/geeksforgeeks/AlternateOddAndEvenNumbers.java delete mode 100644 src/geeksforgeeks/AngleOfClock.java delete mode 100644 src/geeksforgeeks/ArrangeInQueue.java delete mode 100644 src/geeksforgeeks/ArticulationPoint.java delete mode 100644 src/geeksforgeeks/AutoCompleteSystem.java delete mode 100644 src/geeksforgeeks/BackspaceCompare.java delete mode 100644 src/geeksforgeeks/BasicCalculator.java delete mode 100644 src/geeksforgeeks/BinaryTreeCousins.java delete mode 100644 src/geeksforgeeks/BitonicSearch.java delete mode 100644 src/geeksforgeeks/BoatsToSave.java delete mode 100644 src/geeksforgeeks/BuyAndSellStockAnytime.java delete mode 100644 src/geeksforgeeks/BuyAndSellStockAtMostTwice.java delete mode 100644 src/geeksforgeeks/Candy.java delete mode 100644 src/geeksforgeeks/CelebrityProblem.java delete mode 100644 src/geeksforgeeks/CheckPalindromePermutation.java delete mode 100644 src/geeksforgeeks/CloneGraph.java delete mode 100644 src/geeksforgeeks/ClosestNumbers.java delete mode 100644 src/geeksforgeeks/CombinationIterator.java delete mode 100644 src/geeksforgeeks/CompareVersions.java delete mode 100644 src/geeksforgeeks/ConstructBSTFromPreorder.java delete mode 100644 src/geeksforgeeks/ConstructTreeFromInorderAndPostorder.java delete mode 100644 src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java delete mode 100644 src/geeksforgeeks/ContainerWithMostWater.java delete mode 100644 src/geeksforgeeks/ConvertXToY.java delete mode 100644 src/geeksforgeeks/CountAllPathsFrom2DMatrix.java delete mode 100644 src/geeksforgeeks/CountAndSay.java delete mode 100644 src/geeksforgeeks/CountElements.java delete mode 100644 src/geeksforgeeks/CountMinimumStepsToFormDesiredInputArray.java delete mode 100644 src/geeksforgeeks/CountNumbersLessThanSelf.java delete mode 100644 src/geeksforgeeks/CountingInversion.java delete mode 100644 src/geeksforgeeks/CourseSchedule.java delete mode 100644 src/geeksforgeeks/DecodeString.java delete mode 100644 src/geeksforgeeks/DesignCompressedStringIterator.java delete mode 100644 src/geeksforgeeks/DesignFileSystem.java delete mode 100644 src/geeksforgeeks/DesignInMemoryFileSystem.java delete mode 100644 src/geeksforgeeks/DesignStackIncrement.java delete mode 100644 src/geeksforgeeks/DesignTicTacToe.java delete mode 100644 src/geeksforgeeks/DifferentWaysToAddParenthesis.java delete mode 100644 src/geeksforgeeks/DivideSubArrayAverage.java delete mode 100644 src/geeksforgeeks/DungeonGame.java delete mode 100644 src/geeksforgeeks/DutchNationalFlag.java delete mode 100644 src/geeksforgeeks/EvaluvateRPN.java delete mode 100644 src/geeksforgeeks/FenwickTree.java delete mode 100644 src/geeksforgeeks/FindAllAnagram.java delete mode 100644 src/geeksforgeeks/FindMissingNumbers.java delete mode 100644 src/geeksforgeeks/FindSmallestInteger.java delete mode 100644 src/geeksforgeeks/FirstMissingPositive.java delete mode 100644 src/geeksforgeeks/FirstNonRepeatedCharacter.java delete mode 100644 src/geeksforgeeks/FirstNonRepeatingCharacterStream.java delete mode 100644 src/geeksforgeeks/Flatten2DVector.java delete mode 100644 src/geeksforgeeks/FlattenLinkedList.java delete mode 100644 src/geeksforgeeks/FlattenMultiLevelLinkedList.java delete mode 100644 src/geeksforgeeks/FlipMaximizeZeroesSubarrayKadane.java delete mode 100644 src/geeksforgeeks/FlipZeroesToFormConsecutiveMaximumOnes.java delete mode 100644 src/geeksforgeeks/FourSum.java delete mode 100644 src/geeksforgeeks/FrequencySort.java delete mode 100644 src/geeksforgeeks/GameOfLife.java delete mode 100644 src/geeksforgeeks/GenerateParenthesis.java delete mode 100644 src/geeksforgeeks/GrammarMistake.java delete mode 100644 src/geeksforgeeks/GraphBiPartite.java delete mode 100644 src/geeksforgeeks/GraphSplitwiseSimplify.java delete mode 100644 src/geeksforgeeks/GroupAnagrams.java delete mode 100644 src/geeksforgeeks/GroupIsomorphicString.java delete mode 100644 src/geeksforgeeks/HappyNumber.java delete mode 100644 src/geeksforgeeks/HitCounter.java delete mode 100644 src/geeksforgeeks/HouseRobber.java delete mode 100644 src/geeksforgeeks/IPOMaxProfit.java delete mode 100644 src/geeksforgeeks/InMemeoryFIleSystem.java delete mode 100644 src/geeksforgeeks/InOrderSuccessor.java delete mode 100644 src/geeksforgeeks/InorderSuccessorPredecessor.java delete mode 100644 src/geeksforgeeks/InsertIntervals.java delete mode 100644 src/geeksforgeeks/InsertionSortList.java delete mode 100644 src/geeksforgeeks/IntegerToBinary.java delete mode 100644 src/geeksforgeeks/IntersectionOfArrays.java delete mode 100644 src/geeksforgeeks/IsEditOneDistanceAway.java delete mode 100644 src/geeksforgeeks/IsSubsequence.java delete mode 100644 src/geeksforgeeks/IslandBFS.java delete mode 100644 src/geeksforgeeks/Islands.java delete mode 100644 src/geeksforgeeks/IsomorphicString.java delete mode 100644 src/geeksforgeeks/JumpsToReachEnd.java delete mode 100644 src/geeksforgeeks/KClosestElements.java delete mode 100644 src/geeksforgeeks/KmostFrequentLetters.java delete mode 100644 src/geeksforgeeks/KthClosestOrigin.java delete mode 100644 src/geeksforgeeks/KthSmallestFromTwoSortedArrays.java delete mode 100644 src/geeksforgeeks/KthSmallestMatrix.java delete mode 100644 src/geeksforgeeks/LIS2DMatrix.java delete mode 100644 src/geeksforgeeks/LRUCache.java delete mode 100644 src/geeksforgeeks/LargestDivisibleSubset.java delete mode 100644 src/geeksforgeeks/LargestPossibleNumber.java delete mode 100644 src/geeksforgeeks/LargestSubArrayWithZeroesAndOnes.java delete mode 100644 src/geeksforgeeks/LargestTimeFromDigits.java delete mode 100644 src/geeksforgeeks/LengthOfLongestSubstringKDistinct.java delete mode 100644 src/geeksforgeeks/LinkedListRemoveDuplicates.java delete mode 100644 src/geeksforgeeks/LongestConsequtiveSequence.java delete mode 100644 src/geeksforgeeks/LongestIncreasingPathInMatrix.java delete mode 100644 src/geeksforgeeks/LongestRepeatCharReplace.java delete mode 100644 src/geeksforgeeks/LongestSpanWithSameSumArray.java delete mode 100644 src/geeksforgeeks/LongestSubArraySumUtmostK.java delete mode 100644 src/geeksforgeeks/LongestUniqueSubstring.java delete mode 100644 src/geeksforgeeks/MajorityVoting.java delete mode 100644 src/geeksforgeeks/MakeAnArrayPalindrome.java delete mode 100644 src/geeksforgeeks/MatrixRowWithMax1.java delete mode 100644 src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java delete mode 100644 src/geeksforgeeks/MaxFreqStack.java delete mode 100644 src/geeksforgeeks/MaxHistogram.java delete mode 100644 src/geeksforgeeks/MaxProductString.java delete mode 100644 src/geeksforgeeks/MaxWidthOfBinaryTree.java delete mode 100644 src/geeksforgeeks/MaximumDifference.java delete mode 100644 src/geeksforgeeks/MaximumGap.java delete mode 100644 src/geeksforgeeks/MaximumProductSubarray.java delete mode 100644 src/geeksforgeeks/MaximumSubstringWithKDistinctChar.java delete mode 100644 src/geeksforgeeks/MaximumUnsortedSubarray.java delete mode 100644 src/geeksforgeeks/MedianOfKWindow.java delete mode 100644 src/geeksforgeeks/MedianOfRunningIntegers.java delete mode 100644 src/geeksforgeeks/MedianOfTwoSortedArrays.java delete mode 100644 src/geeksforgeeks/MeetingRoomsII.java delete mode 100644 src/geeksforgeeks/MergeIntervalIntersection.java delete mode 100644 src/geeksforgeeks/MergeIntervals.java delete mode 100644 src/geeksforgeeks/MergeSortLinkedList.java delete mode 100644 src/geeksforgeeks/MergeTwoLinkedList.java delete mode 100644 src/geeksforgeeks/MinCostRopeConnect.java delete mode 100644 src/geeksforgeeks/MinStepsToConvertXtoY.java delete mode 100644 src/geeksforgeeks/MinTimeRotOranges.java delete mode 100644 src/geeksforgeeks/MinimumBribes.java delete mode 100644 src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java delete mode 100644 src/geeksforgeeks/MinimumIndexDistanceOfMaximumNumbers.java delete mode 100644 src/geeksforgeeks/MinimumPathSum.java delete mode 100644 src/geeksforgeeks/MinimumStack.java delete mode 100644 src/geeksforgeeks/MinimumStepsKnight.java delete mode 100644 src/geeksforgeeks/MinimumSwapSortArray.java delete mode 100644 src/geeksforgeeks/MinimumWindowSubsequence.java delete mode 100644 src/geeksforgeeks/MinimumWindowSubstring.java delete mode 100644 src/geeksforgeeks/MirrorBinaryTree.java delete mode 100644 src/geeksforgeeks/MobileKeyPadCombinations.java delete mode 100644 src/geeksforgeeks/MoveZeroes.java delete mode 100644 src/geeksforgeeks/NQueens.java delete mode 100644 src/geeksforgeeks/NewRoadsMST.java delete mode 100644 src/geeksforgeeks/NextGreaterElement.java delete mode 100644 src/geeksforgeeks/NextGreaterNumber.java delete mode 100644 src/geeksforgeeks/NextLargestList.java delete mode 100644 src/geeksforgeeks/Node.java delete mode 100644 src/geeksforgeeks/NonDecreasingArray.java delete mode 100644 src/geeksforgeeks/NumberOfBallons.java delete mode 100644 src/geeksforgeeks/NutsAndBoltsMatch.java delete mode 100644 src/geeksforgeeks/OverlappingIntervals.java delete mode 100644 src/geeksforgeeks/OwnDataStructureUtil.java delete mode 100644 src/geeksforgeeks/PalindromePartion.java delete mode 100644 src/geeksforgeeks/PalindromePartitioning.java delete mode 100644 src/geeksforgeeks/PalindromeSinglyLinkedList.java delete mode 100644 src/geeksforgeeks/PalindromicSubSequence.java delete mode 100644 src/geeksforgeeks/PartitionLabel.java delete mode 100644 src/geeksforgeeks/PascalsTriangle.java delete mode 100644 src/geeksforgeeks/PathSumIII.java delete mode 100644 src/geeksforgeeks/Pattern132.java delete mode 100644 src/geeksforgeeks/PerfectSquare.java delete mode 100644 src/geeksforgeeks/PermutationInString.java delete mode 100644 src/geeksforgeeks/PetrolGasStation.java delete mode 100644 src/geeksforgeeks/PlusOne.java delete mode 100644 src/geeksforgeeks/Pow.java delete mode 100644 src/geeksforgeeks/PrisonAfterNDays.java delete mode 100644 src/geeksforgeeks/ProductExceptSelf.java delete mode 100644 src/geeksforgeeks/QueensAttackKing.java delete mode 100644 src/geeksforgeeks/RaceCarMinSteps.java delete mode 100644 src/geeksforgeeks/RandomLinkedList.java delete mode 100644 src/geeksforgeeks/RandomPickWithWeight.java delete mode 100644 src/geeksforgeeks/RangeSum.java delete mode 100644 src/geeksforgeeks/ReconstructItenary.java delete mode 100644 src/geeksforgeeks/RedundantConnection.java delete mode 100644 src/geeksforgeeks/RemoveAdjacentDuplicates.java delete mode 100644 src/geeksforgeeks/RemoveDuplicates.java delete mode 100644 src/geeksforgeeks/RemoveInvalidParentheses.java delete mode 100644 src/geeksforgeeks/RemoveKDigits.java delete mode 100644 src/geeksforgeeks/ReorderLogs.java delete mode 100644 src/geeksforgeeks/ReorganiseString.java delete mode 100644 src/geeksforgeeks/RestoreIpAddresses.java delete mode 100644 src/geeksforgeeks/ReverseWordsInString.java delete mode 100644 src/geeksforgeeks/RollingHashRabinKarp.java delete mode 100644 src/geeksforgeeks/RomanToInteger.java delete mode 100644 src/geeksforgeeks/RotateArray.java delete mode 100644 src/geeksforgeeks/RotateMatrixInPlace.java delete mode 100644 src/geeksforgeeks/RotateMatrixInPlaceAntiClockwise.java delete mode 100644 src/geeksforgeeks/SameTree.java delete mode 100644 src/geeksforgeeks/SearchAMaze.java delete mode 100644 src/geeksforgeeks/SearchAnElementInMatrix.java delete mode 100644 src/geeksforgeeks/SerializeAndDeserialize.java delete mode 100644 src/geeksforgeeks/SerializeDeserializeBST.java delete mode 100644 src/geeksforgeeks/SetBitCount.java delete mode 100644 src/geeksforgeeks/ShuffleArray.java delete mode 100644 src/geeksforgeeks/SimilarExpressions.java delete mode 100644 src/geeksforgeeks/SingleElementInSortedArray.java delete mode 100644 src/geeksforgeeks/SlidingWindow.java delete mode 100644 src/geeksforgeeks/SnakeAndLadder.java delete mode 100644 src/geeksforgeeks/SnakeGame.java delete mode 100644 src/geeksforgeeks/SortANearlySortedArray.java delete mode 100644 src/geeksforgeeks/SortStack.java delete mode 100644 src/geeksforgeeks/SortedArrayToBST.java delete mode 100644 src/geeksforgeeks/SortedSquares.java delete mode 100644 src/geeksforgeeks/SpiralMatrix.java delete mode 100644 src/geeksforgeeks/SpiralMatrixII.java delete mode 100644 src/geeksforgeeks/SplitLinkedList.java delete mode 100644 src/geeksforgeeks/StockBuySellManyTimes.java delete mode 100644 src/geeksforgeeks/StockSpanner.java delete mode 100644 src/geeksforgeeks/StringIterator.java delete mode 100644 src/geeksforgeeks/SubArraySumDivisibleByK.java delete mode 100644 src/geeksforgeeks/SubArraySumEqualsK.java delete mode 100644 src/geeksforgeeks/SubstringWindowTemplate.java delete mode 100644 src/geeksforgeeks/SumOfThreeElements.java delete mode 100644 src/geeksforgeeks/SumSubArrayZero.java delete mode 100644 src/geeksforgeeks/SurroundedRegions.java delete mode 100644 src/geeksforgeeks/SwapRecoverBST.java delete mode 100644 src/geeksforgeeks/SymmetricTree.java delete mode 100644 src/geeksforgeeks/TaskLeastInterval.java delete mode 100644 src/geeksforgeeks/ThreeSum.java delete mode 100644 src/geeksforgeeks/TimeMap.java delete mode 100644 src/geeksforgeeks/TopKFrequentElement.java delete mode 100644 src/geeksforgeeks/TopKFrequentElements.java delete mode 100644 src/geeksforgeeks/TrailingZeroes.java delete mode 100644 src/geeksforgeeks/TreasureIsland.java delete mode 100644 src/geeksforgeeks/TreasureIslandII.java delete mode 100644 src/geeksforgeeks/Trie.java delete mode 100644 src/geeksforgeeks/Twitter.java delete mode 100644 src/geeksforgeeks/TwoCityScheduling.java delete mode 100644 src/geeksforgeeks/TwoSumClosestToZero.java delete mode 100644 src/geeksforgeeks/UnSortedSubArray.java delete mode 100644 src/geeksforgeeks/UniqueElementsInArray.java delete mode 100644 src/geeksforgeeks/UniquePath.java delete mode 100644 src/geeksforgeeks/UniquePathMaximum.java delete mode 100644 src/geeksforgeeks/UrlEncode.java delete mode 100644 src/geeksforgeeks/ValidPalindromeII.java delete mode 100644 src/geeksforgeeks/ValidParentheses.java delete mode 100644 src/geeksforgeeks/ValidParenthesesString.java delete mode 100644 src/geeksforgeeks/ValidSudoku.java delete mode 100644 src/geeksforgeeks/ValidateIpAddresses.java delete mode 100644 src/geeksforgeeks/VulgarDecimal.java delete mode 100644 src/geeksforgeeks/WaterTrapping.java delete mode 100644 src/geeksforgeeks/WordBreak.java delete mode 100644 src/geeksforgeeks/WordBreakII.java delete mode 100644 src/geeksforgeeks/WordDictionary.java delete mode 100644 src/geeksforgeeks/WordLadder.java delete mode 100644 src/geeksforgeeks/WordSearch.java diff --git a/.gitignore b/.gitignore index 079aeb3..de410e2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,8 @@ .classpath .project AmazonProblems.iml - +out/ *.json /.idea/* /.idea/ +/out/*.class diff --git a/src/binarysearch/FindMinimumInRotatedArray.java b/src/binarysearch/FindMinimumInRotatedArray.java index 1ccb519..481f74a 100644 --- a/src/binarysearch/FindMinimumInRotatedArray.java +++ b/src/binarysearch/FindMinimumInRotatedArray.java @@ -1,6 +1,8 @@ -package geeksforgeeks; +package binarysearch; -/*https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/*/ +/** + * https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/ + */ public class FindMinimumInRotatedArray { public static int findMin(int[] nums) { @@ -12,7 +14,7 @@ public static int findMin(int[] nums) { } int start = 0; int end = nums.length - 1; - while (start <= end) { + while (start < end) { int mid = ((end - start) / 2) + start; if (nums[start] <= nums[end]) { @@ -29,28 +31,29 @@ public static int findMin(int[] nums) { } public int findMinWithDuplicate(int[] nums) { - if(nums.length==1) return nums[0]; - int start=0; - int end= nums.length-1; - while(startnums[end]){ - start=mid+1; - }else{ - end=mid; - } + } else { + int mid = start + (end - start) / 2; + if (nums[mid] > nums[end]) { + start = mid + 1; + } else { + end = mid; + } } - + } - + return nums[start]; } + public static void main(String[] args) { - int[] arr = { 7, 1, 2, 3, 4, 5, 6 }; + int[] arr = {7, 1, 2, 3, 4, 5, 6}; findMin(arr); } } \ No newline at end of file diff --git a/src/binarysearch/FirstAndLastOccurence.java b/src/binarysearch/FirstAndLastOccurence.java index 93c8207..3a04a56 100644 --- a/src/binarysearch/FirstAndLastOccurence.java +++ b/src/binarysearch/FirstAndLastOccurence.java @@ -1,37 +1,42 @@ -package geeksforgeeks; +package binarysearch; +/** + * https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/submissions/ + */ public class FirstAndLastOccurence { public int[] searchRange(int[] nums, int target) { - if(nums.length==0) return new int[]{-1,-1}; - int[] result= new int[2]; - result[0]=binarySearch(nums,target,false); - if(result[0]==-1){ - result[1]=-1; - return result; - } - result[1]=binarySearch(nums,target,true); + int[] result = new int[]{-1, -1}; + if (nums.length == 0) return result; + + int first = binarySearch(nums, target); + + if (first == nums.length || nums[first] != target) return result; + + result[0] = first; + int last = binarySearch(nums, target + 1); + + result[1] = nums[last] == target ? last : last - 1; + return result; + } - - public int binarySearch(int[]nums, int target, boolean findMaxIndex){ - int start=0; - int end=nums.length-1; - int key=-1; - while(start<=end){ - int mid= start + (end-start)/2; - - if(nums[mid]target){ - end=mid-1; - }else{ - key=mid; - if(findMaxIndex) start=mid+1; - else end=mid-1; + + public int binarySearch(int[] nums, int target) { + int left = 0; + int right = nums.length - 1; + + while (left < right) { + int mid = left + (right - left) / 2; + + if (nums[mid] >= target) { + right = mid; + } else { + left = mid + 1; + } } - - return key; + + return left; } } \ No newline at end of file diff --git a/src/binarysearch/MaxSoldiers.java b/src/binarysearch/MaxSoldiers.java index 510bbce..aabe091 100644 --- a/src/binarysearch/MaxSoldiers.java +++ b/src/binarysearch/MaxSoldiers.java @@ -1,9 +1,13 @@ -package geeksforgeeks; +package binarysearch; +import java.util.Objects; import java.util.PriorityQueue; +/** + * https://leetcode.com/problems/the-k-weakest-rows-in-a-matrix/ + */ public class MaxSoldiers { - class Pair { + static class Pair { T row; S soldiers; @@ -15,9 +19,8 @@ class Pair { public int[] kWeakestRows(int[][] mat, int k) { int[] result = new int[k]; - PriorityQueue> queue = new PriorityQueue<>((a, b) -> a.soldiers == b.soldiers ? Integer.compare(a.row, b.row) : Integer.compare(a.soldiers, b.soldiers)); + PriorityQueue> queue = new PriorityQueue<>((a, b) -> a.soldiers.equals(b.soldiers) ? Integer.compare(a.row, b.row) : Integer.compare(a.soldiers, b.soldiers)); int i = 0; - int soldiers = 0; for (int[] rows : mat) { int temp = binarySearchUtil(rows, 0, rows.length); queue.offer(new Pair<>(i, temp)); @@ -25,7 +28,7 @@ public int[] kWeakestRows(int[][] mat, int k) { } int ind = 0; while (ind < k) { - result[ind++] = (int) queue.poll().row; + result[ind++] = Objects.requireNonNull(queue.poll()).row; } return result; diff --git a/src/binarysearch/PeakElement.java b/src/binarysearch/PeakElement.java index a1b35e3..7924960 100644 --- a/src/binarysearch/PeakElement.java +++ b/src/binarysearch/PeakElement.java @@ -1,40 +1,47 @@ -package geeksforgeeks; +package binarysearch; + +import java.util.Map; +import java.util.TreeMap; /** * https://leetcode.com/problems/find-peak-element/ - * + *

* A peak element is an element that is greater than its neighbors. - * + *

* Given an input array nums, where nums[i] ≠ nums[i+1], find a peak element and return its index. - * + *

* The array may contain multiple peaks, in that case return the index to any one of the peaks is fine. - * + *

* You may imagine that nums[-1] = nums[n] = -∞. */ public class PeakElement { - public int findPeakElement(int[] nums) { - if (nums == null || nums.length == 0) return -1; - int result = -1; - - int start = 0; - int end = nums.length - 1; - while (start <= end) { - int mid = start + (end - start) / 2; - if ((mid == 0 || nums[mid] > nums[mid - 1]) && (mid == nums.length - 1 || nums[mid] > nums[mid + 1])) - return mid; - else if (mid > 0 && nums[mid - 1] > nums[mid]) end = mid - 1; - else if (nums[mid + 1] > nums[mid]) start = mid + 1; + public static void main(String[] args) { + Map map= new TreeMap<>(); + map.put(new Employee(9,"aaa"),""); + map.put(new Employee(2,"ttt"),"sd"); + for (Map.Entry entry: map.entrySet()){ + System.out.println(entry.getKey()); } - return result; - } - public static void main(String[] args) { - PeakElement pe = new PeakElement(); - int[] arr = {1, 1, 1, 3, 2, 1, 2}; - System.out.println(arr[pe.findPeakElement(arr)]); } } +class Employee { + int id; + String name; + Employee (int id, String name){ + this.id=id; + this.name=name; + } + + @Override + public String toString() { + return "Employee{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/src/binarysearch/SearchElementInSortedAndRotatedArray.java b/src/binarysearch/SearchElementInSortedAndRotatedArray.java index 9ef73ba..8531de8 100644 --- a/src/binarysearch/SearchElementInSortedAndRotatedArray.java +++ b/src/binarysearch/SearchElementInSortedAndRotatedArray.java @@ -1,4 +1,4 @@ -package geeksforgeeks; +package binarysearch; /** * https://leetcode.com/problems/search-in-rotated-sorted-array/ diff --git a/src/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java b/src/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java index 96ec079..67f2d08 100644 --- a/src/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java +++ b/src/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java @@ -55,18 +55,16 @@ public int fibUtil(int N, int start, int [] cache){ public int minCostClimbingStairs(int[] cost) { - int res = 0; - //dp[i] = cost[i] + Math.min(dp[i-1], dp[i-2]) - int[] dp = new int[cost.length]; - - dp[0] = Math.min(cost[0], cost[1]); - dp[1] = Math.min(cost[1] + dp[0], cost[1]); - for(int i = 2; i < cost.length; i++){ - dp[i] = cost[i] + Math.min(dp[i-1], dp[i-2]); + if(cost.length==2) return Math.min(cost[0],cost[1]); + int[] dp= new int[cost.length+1]; + dp[0]=cost[0]; + dp[1]=cost[1]; + + for(int i=2;i B[i]. - -import java.util.Arrays; -import java.util.PriorityQueue; - -// Return any permutation of A that maximizes its advantage with respect to B. -//Input: A = [12,24,8,32], B = [13,25,32,11] -//Output: [24,32,8,12] -// Input: A = [2,7,11,15], B = [1,10,4,11] -// Output: [2,11,7,15] -public class AdvantageShuffle { - public int[] advantageCount(int[] A, int[] B) { - Arrays.sort(A); - - PriorityQueue pq= new PriorityQueue<>((a, b)->Integer.compare(b[0],a[0])); - for(int i=0;ival){ // if polled element is lesser thar A[hi], put A[hi] at index of - // queued elements index, means, equal to B's current index we are putting - // a value greater that B's in result arrays - result[index]=A[hi--]; - }else{ - result[index]=A[lo++]; - } - } - return result; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/AircraftOptimization.java b/src/geeksforgeeks/AircraftOptimization.java deleted file mode 100644 index 0031a92..0000000 --- a/src/geeksforgeeks/AircraftOptimization.java +++ /dev/null @@ -1,69 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -/** - * https://leetcode.com/discuss/interview-question/373202 - * Given 2 lists a and b. Each element is a pair of integers where the first integer represents the unique id and the second integer represents a value. - * Your task is to find an element from a and an element form b such that the sum of their values is less or equal to target and as close to target as possible. - * Return a list of ids of selected elements. If no pair is possible, return an empty list. - * - * a = [[1, 2], [2, 4], [3, 6]] - b = [[1, 2]] - target = 7 - - Output: [[2, 1]] - - Explanation: - There are only three combinations [1, 1], [2, 1], and [3, 1], which have a total sum of 4, 6 and 8, respectively. - Since 6 is the largest sum that does not exceed 7, [2, 1] is the optimal pair. - */ -public class AircraftOptimization { - - public List> calculateOptimalRoute(final List> forwardList, - final List> returnList, int capacity) { - - forwardList.sort(Comparator.comparingInt(o->o.get(1))); - returnList.sort(Comparator.comparingInt(o->o.get(1))); - - int max = 0; - int i = 0; - int j = returnList.size() - 1; - - List> result = new LinkedList<>(); - while (i < forwardList.size() && j >= 0) { - int currentSum = forwardList.get(i).get(1) + returnList.get(j).get(1); - - if (currentSum > max && currentSum <= capacity) { - max = currentSum; - // Initializing new list - result = new LinkedList<>(); - result.add(new ArrayList<>(Arrays.asList(forwardList.get(i).get(0), returnList.get(j).get(0)))); - i++; - } else if (currentSum == max) { - // no need to reset result list - result.add(new ArrayList<>(Arrays.asList(forwardList.get(i).get(0), returnList.get(j).get(0)))); - i++; - } else { - j--; - } - } - return result; - } - - public static void main(String[] args) { - AircraftOptimization aircraft = new AircraftOptimization(); - List> returnList = new ArrayList<>(); - returnList.add(new ArrayList<>(Arrays.asList(1, 2000))); - returnList.add(new ArrayList<>(Arrays.asList(2, 3000))); - returnList.add(new ArrayList<>(Arrays.asList(3, 4000))); - returnList.add(new ArrayList<>(Arrays.asList(4, 5000))); - List> forwardList = new ArrayList<>(); - forwardList.add(new ArrayList<>(Arrays.asList(1, 3000))); - forwardList.add(new ArrayList<>(Arrays.asList(2, 5000))); - forwardList.add(new ArrayList<>(Arrays.asList(3, 7000))); - forwardList.add(new ArrayList<>(Arrays.asList(4, 10000))); - List> calculateOptimalRoute = aircraft.calculateOptimalRoute(forwardList, returnList, 10000); - System.out.println(calculateOptimalRoute); - } -} diff --git a/src/geeksforgeeks/AlternateOddAndEvenNumbers.java b/src/geeksforgeeks/AlternateOddAndEvenNumbers.java deleted file mode 100644 index 5cbbd3d..0000000 --- a/src/geeksforgeeks/AlternateOddAndEvenNumbers.java +++ /dev/null @@ -1,50 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; - -/** - * https://www.geeksforgeeks.org/rearrange-positive-and-negative-numbers-publish/ - * An array contains both positive and negative numbers in random order. - * Rearrange the array elements so that positive and negative numbers are placed alternatively. - * If there are more positive numbers they appear at the end of the array. - * If there are more negative numbers, they too appear in the end of the array. - * [-1, 2, -3, 4, 5, 6, -7, 8, 9] - * output [9, -7, 8, -3, 5, -1, 2, 4, 6] or[4, -3, 5, -1, 6, -7, 2, 8, 9] - */ -class AlternateOddAndEvenNumbers { - - static void rearrange(int arr[], int n) { - //-1, 2, -3, 4, 5, 6, -7, 8, 9 - int i = 0, temp = 0; - for (int j = 0; j < n; j++) { - if (arr[j] < 0) { - temp = arr[i]; - arr[i] = arr[j]; - arr[j] = temp; - i++; - } - } - // we have segregated positive and negative elements - System.out.println(Arrays.toString(arr)+" :i - "+i); - // now the 'pos' indicates start of positive integer, 'neg' starts from 0; - int pos = i , neg = 0; - - - - while (pos < n && neg < pos && arr[neg] < 0) { - temp = arr[neg]; - arr[neg] = arr[pos]; - arr[pos] = temp; - pos++; - neg += 2; // need to skip next element as output should be alternative - System.out.println(Arrays.toString(arr)); - } - } - - public static void main(String[] args) { - int arr[] = { -1, 2, -3, 4, 5, 6, -7, 8, 9 }; - int n = arr.length; - rearrange(arr, n); - System.out.println("Array after rearranging: "+ Arrays.toString(arr)); - } -} diff --git a/src/geeksforgeeks/AngleOfClock.java b/src/geeksforgeeks/AngleOfClock.java deleted file mode 100644 index 567e2dd..0000000 --- a/src/geeksforgeeks/AngleOfClock.java +++ /dev/null @@ -1,15 +0,0 @@ -package geeksforgeeks; - -public class AngleOfClock { - public double angleClock(int hours, int minutes) { - // every hour is 30(deg) (360 (deg)/12) because 12 hrs in clock - // every min is 6(deg) (360(deg)/60) because 60 mins per hr - // we take mod of 12 because 12th hr needs to be 0* - double hourHand= (hours%12 + (double)minutes/60)*30; - double minHand= minutes*6; - double absAngle= Math.abs(hourHand-minHand); - if(absAngle>180) absAngle= 360-absAngle; // this is because when time is 0.02 the angel will be 358 - - return absAngle; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/ArrangeInQueue.java b/src/geeksforgeeks/ArrangeInQueue.java deleted file mode 100644 index 1730147..0000000 --- a/src/geeksforgeeks/ArrangeInQueue.java +++ /dev/null @@ -1,52 +0,0 @@ -package geeksforgeeks; -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -//You are given an array of people, people, -// which are the attributes of some people in a queue (not necessarily in order). -// Each people[i] = [hi, ki] represents the ith person of height hi with exactly ki -// other people in front who have a height greater than or equal to hi. -//Reconstruct and return the queue that is represented by the input array people. -// The returned queue should be formatted as an array queue, -// where queue[j] = [hj, kj] is the attributes of the jth person in the -// queue (queue[0] is the person at the front of the queue). - -// Input: -// [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] -// Output: -// [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]] -//Explanation: -// Person 0 has height 5 with no other people taller or the same height in front. -// Person 1 has height 7 with no other people taller or the same height in front. -// Person 2 has height 5 with two persons taller or the same height in front, which is person 0 and 1. -// Person 3 has height 6 with one person taller or the same height in front, which is person 1. -// Person 4 has height 4 with four people taller or the same height in front, which are people 0, 1, 2, and 3. -// Person 5 has height 7 with one person taller or the same height in front, which is person 1. -// Hence [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] is the reconstructed queue. -public class ArrangeInQueue { - -// 1. Sort people by their height, shortest to tallest -// 2. Iterate and put each person to the correct position -// 2.a When placing the shortest person, all person to his left will be taller or equal height, since you are iterating in height sorted array, so put it at a index equal to its k value -// 2.b When placing the next shortest person, find a position, where count of positions to the left unoccupied plus the ones where same height person is placed, is equal to its k value -// 2.c Keep repeating - public static int[][] reconstructQueue(int[][] people) { - List result= new ArrayList<>(); - Arrays.sort(people,(a, b)->{ - if(a[0]==b[0]) return a[1]-b[1]; - else return b[0]-a[0]; - }); - System.out.println("Sorted values: "+ Arrays.deepToString(people)); - for(int[] x: people){ - result.add(x[1],x); - System.out.println(Arrays.deepToString(result.toArray(new int[people.length][2]))); - } - return result.toArray(new int[people.length][2]); - } - - public static void main(String[] args) { - System.out.println(Arrays.deepToString(reconstructQueue(new int[][]{{7,0},{4,4},{7,1},{5,0},{6,1},{5,2}}))); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/ArticulationPoint.java b/src/geeksforgeeks/ArticulationPoint.java deleted file mode 100644 index 20df9d4..0000000 --- a/src/geeksforgeeks/ArticulationPoint.java +++ /dev/null @@ -1,369 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Date 08/22/2015 - * - * @author Tushar Roy - * - * Find articulation points in connected undirected graph. Articulation - * points are vertices such that removing any one of them disconnects - * the graph. - * - * We need to do DFS of this graph and keep visitedTime and lowTime for - * each vertex. lowTime is keeps track of back edges. - * - * If any one of following condition meets then vertex is articulation - * point. - * - * 1) If vertex is root of DFS and has atlesat 2 independent - * children.(By independent it means they are not connected to each - * other except via this vertex). This condition is needed because if we - * started from corner vertex it will meet condition 2 but still is not - * an articulation point. To filter out those vertices we need this - * condition. - * - * 2) It is not root of DFS and if visitedTime of vertex <= lowTime of - * any adjacent vertex then its articulation point. - * - * Time complexity is O(E + V) Space complexity is O(V) - * - * References: https://en.wikipedia.org/wiki/Biconnected_component - * http://www.geeksforgeeks.org/articulation-points-or-cut-vertices-in-a-graph/ - */ -public class ArticulationPoint { - - private int time; - - public Set> findarticulationPoints(Graph graph) { - time = 0; - Set> visited = new HashSet<>(); - Set> articulationPoints = new HashSet<>(); - Vertex startVertex = graph.getAllVertex().iterator().next(); - - Map, Integer> visitedTime = new HashMap<>(); - Map, Integer> lowTime = new HashMap<>(); - Map, Vertex> parent = new HashMap<>(); - - DFS(visited, articulationPoints, startVertex, visitedTime, lowTime, parent); - return articulationPoints; - } - - private void DFS(Set> visited, Set> articulationPoints, Vertex vertex, - Map, Integer> visitedTime, Map, Integer> lowTime, Map, Vertex> parent) { - visited.add(vertex); - visitedTime.put(vertex, time); - lowTime.put(vertex, time); - time++; - int childCount = 0; - boolean isArticulationPoint = false; - for (Vertex adj : vertex.getAdjacentVertexes()) { - // if adj is same as parent then just ignore this vertex. - if (adj.equals(parent.get(vertex))) { - continue; - } - // if adj has not been visited then visit it. - if (!visited.contains(adj)) { - parent.put(adj, vertex); - childCount++; - DFS(visited, articulationPoints, adj, visitedTime, lowTime, parent); - - if (visitedTime.get(vertex) <= lowTime.get(adj)) { - isArticulationPoint = true; - } else { - // below operation basically does lowTime[vertex] = min(lowTime[vertex], - // lowTime[adj]); - lowTime.compute(vertex, (currentVertex, time) -> Math.min(time, lowTime.get(adj))); - } - - } else { // if adj is already visited see if you can get better low time. - // below operation basically does lowTime[vertex] = min(lowTime[vertex], - // visitedTime[adj]); - lowTime.compute(vertex, (currentVertex, time) -> Math.min(time, visitedTime.get(adj))); - } - } - - // checks if either condition 1 or condition 2 meets). If yes then it is - // articulation point. - if ((parent.get(vertex) == null && childCount >= 2) || parent.get(vertex) != null && isArticulationPoint) { - articulationPoints.add(vertex); - } - - } - - public static void main(String args[]) { - Graph graph = new Graph<>(false); - /* graph.addEdge(1, 2); - graph.addEdge(2, 3); - graph.addEdge(1, 3); - graph.addEdge(1, 4); - graph.addEdge(4, 5); - graph.addEdge(5, 6); - graph.addEdge(6, 7); - graph.addEdge(7, 5); - graph.addEdge(6, 8);*/ - - graph.addEdge(4, 3); - graph.addEdge(1, 2); - graph.addEdge(2, 3); - graph.addEdge(3, 4); - - - // bigger example - /* - * graph.addEdge(0, 1); graph.addEdge(0, 2); graph.addEdge(0, 3); - * graph.addEdge(0, 4); graph.addEdge(4, 2); graph.addEdge(3, 5); - * graph.addEdge(4, 6); graph.addEdge(6, 3); graph.addEdge(6, 7); - * graph.addEdge(6, 8); graph.addEdge(7, 9); graph.addEdge(9, 10); - * graph.addEdge(8, 10); - */ - - ArticulationPoint ap = new ArticulationPoint<>(); - Set> aPoints = ap.findarticulationPoints(graph); - aPoints.forEach(System.out::println); - } - -} - -class Graph { - - List> allEdges; - Map> allVertex; - boolean isDirected = false; - - public Graph(boolean isDirected) { - allEdges = new ArrayList<>(); - allVertex = new HashMap<>(); - this.isDirected = isDirected; - } - - public void addEdge(long id1, long id2) { - addEdge(id1, id2, 0); - } - - public void addVertex(Vertex vertex) { - if (allVertex.containsKey(vertex.getId())) { - return; - } - allVertex.put(vertex.getId(), vertex); - for (Edge edge : vertex.getEdges()) { - allEdges.add(edge); - } - } - - public Vertex addSingleVertex(long id) { - if (allVertex.containsKey(id)) { - return allVertex.get(id); - } - Vertex v = new Vertex<>(id); - allVertex.put(id, v); - return v; - } - - public Vertex getVertex(long id) { - return allVertex.get(id); - } - - public void addEdge(long id1, long id2, int weight) { - Vertex vertex1 = null; - if (allVertex.containsKey(id1)) { - vertex1 = allVertex.get(id1); - } else { - vertex1 = new Vertex<>(id1); - allVertex.put(id1, vertex1); - } - Vertex vertex2 = null; - if (allVertex.containsKey(id2)) { - vertex2 = allVertex.get(id2); - } else { - vertex2 = new Vertex<>(id2); - allVertex.put(id2, vertex2); - } - - Edge edge = new Edge<>(vertex1, vertex2, isDirected, weight); - allEdges.add(edge); - vertex1.addAdjacentVertex(edge, vertex2); - if (!isDirected) { - vertex2.addAdjacentVertex(edge, vertex1); - } - } - - public List> getAllEdges() { - return allEdges; - } - - public Collection> getAllVertex() { - return allVertex.values(); - } - - public void setDataForVertex(long id, T data) { - if (allVertex.containsKey(id)) { - Vertex vertex = allVertex.get(id); - vertex.setData(data); - } - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - for (Edge edge : getAllEdges()) { - sb.append(edge.getVertex1() + " " + edge.getVertex2() + " " + edge.getWeight()); - sb.append("\n"); - } - return sb.toString(); - } -} - -class Vertex { - long id; - T data; - List> edges = new ArrayList<>(); - List> adjacentVertex = new ArrayList<>(); - - Vertex(long id) { - this.id = id; - } - - public long getId() { - return id; - } - - public void setData(T data) { - this.data = data; - } - - public T getData() { - return data; - } - - public void addAdjacentVertex(Edge e, Vertex v) { - edges.add(e); - adjacentVertex.add(v); - } - - public String toString() { - return String.valueOf(id); - } - - public List> getAdjacentVertexes() { - return adjacentVertex; - } - - public List> getEdges() { - return edges; - } - - public int getDegree() { - return edges.size(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (int) (id ^ (id >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Vertex other = (Vertex) obj; - - return id != other.id; - } -} - -class Edge { - boolean isDirected = false; - Vertex vertex1; - Vertex vertex2; - int weight; - - Edge(Vertex vertex1, Vertex vertex2) { - this.vertex1 = vertex1; - this.vertex2 = vertex2; - } - - Edge(Vertex vertex1, Vertex vertex2, boolean isDirected, int weight) { - this.vertex1 = vertex1; - this.vertex2 = vertex2; - this.weight = weight; - this.isDirected = isDirected; - } - - Edge(Vertex vertex1, Vertex vertex2, boolean isDirected) { - this.vertex1 = vertex1; - this.vertex2 = vertex2; - this.isDirected = isDirected; - } - - Vertex getVertex1() { - return vertex1; - } - - Vertex getVertex2() { - return vertex2; - } - - int getWeight() { - return weight; - } - - public boolean isDirected() { - return isDirected; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((vertex1 == null) ? 0 : vertex1.hashCode()); - result = prime * result + ((vertex2 == null) ? 0 : vertex2.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Edge other = (Edge) obj; - if (vertex1 == null) { - if (other.vertex1 != null) { - return false; - } - } else if (!vertex1.equals(other.vertex1)) { - return false; - } - if (vertex2 == null) { - if (other.vertex2 != null) { - return false; - } - } else if (!vertex2.equals(other.vertex2)) { - return false; - } - return true; - } - - @Override - public String toString() { - return "Edge [isDirected=" + isDirected + ", vertex1=" + vertex1 + ", vertex2=" + vertex2 + ", weight=" + weight - + "]"; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/AutoCompleteSystem.java b/src/geeksforgeeks/AutoCompleteSystem.java deleted file mode 100644 index bbd6b67..0000000 --- a/src/geeksforgeeks/AutoCompleteSystem.java +++ /dev/null @@ -1,97 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -/** - * https://cheonhyangzhang.gitbooks.io/leetcode-solutions/content/642-design-search-autocomplete-system.html - */ -class AutoCompleteSystem { - - static class TrieNode { - Map children; - Map counts; - boolean isWord; - - public TrieNode() { - children = new HashMap<>(); - counts = new HashMap<>(); - isWord = false; - } - } - - TrieNode root; // points to the root of the trie to be initialised - String prefix; // concat and stores the input char sequence from main function - - public AutoCompleteSystem(String[] sentences, int[] times) { - root = new TrieNode(); - prefix = ""; - // for the given word and freq value we proceed to add it to trie - for (int i = 0; i < sentences.length; i++) { - add(sentences[i], times[i]); - } - } - - private void add(String s, int count) { - TrieNode curr = root; - for (char c : s.toCharArray()) { - curr.children.putIfAbsent(c, new TrieNode()); - curr = curr.children.get(c); - // for every node in the trie(which has one char val) - //the counts map will store the original word along with it's freq value - // for the given input 'i love leetcode' and 'i love you' - // the trie Node(i) => Map(i love leetcode -> 2, i love you->5, island->3, ironman->2) - // / - // Node(' ') => Map(i love leetcode -> 2, i love you->5) - - // the trie Node(i) => Map(i love leetcode -> 2, i love you->5, island->3, ironman->2) - // \ - // Node('s') => Map(island->3) - curr.counts.put(s, curr.counts.getOrDefault(s, 0) + count); - } - curr.isWord = true; - } - - public List input(char c) { - if (c == '#') { - add(prefix, 1); - prefix = ""; - return new ArrayList<>(); - } - prefix = prefix + c; - - TrieNode curr = root; - - for (char ch : prefix.toCharArray()) { - if (!curr.children.containsKey(ch)) { - return new ArrayList<>(); - } - curr = curr.children.get(ch); - } - - Comparator> cmp = (a, b) -> a.getValue().equals(b.getValue()) ? - b.getKey().compareTo(a.getKey()) : - a.getValue() - b.getValue(); - PriorityQueue> pq = new PriorityQueue<>(cmp); - int k = 3; - for (Map.Entry entry : curr.counts.entrySet()) { - pq.offer(entry); - while (!pq.isEmpty() && pq.size() > k) { - pq.poll(); - } - } - - ArrayList res = new ArrayList<>(); - while (!pq.isEmpty()) { - res.add(0, pq.poll().getKey()); - } - return res; - } - - public static void main(String[] args) { - String[] sentences = { "i love you", "island", "ironman", "i love leetcode" }; - int[] times = { 5, 3, 2, 2 }; - AutoCompleteSystem autoCompleteSystem = new AutoCompleteSystem(sentences, times); - System.out.println(autoCompleteSystem.input('i')); - System.out.println(autoCompleteSystem.input(' ')); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/BackspaceCompare.java b/src/geeksforgeeks/BackspaceCompare.java deleted file mode 100644 index e675a90..0000000 --- a/src/geeksforgeeks/BackspaceCompare.java +++ /dev/null @@ -1,63 +0,0 @@ -package geeksforgeeks; - -/** - * https://leetcode.com/problems/backspace-string-compare/ - * Given two strings S and T, return if they are equal when both are typed into empty text editors. # means a backspace character. - * - * Note that after backspacing an empty text, the text will continue empty. - * - * Input: S = "ab#c", T = "ad#c" - * Output: true - * Explanation: Both S and T become "ac". - * - * Input: S = "a##c", T = "#a#c" - * Output: true - * Explanation: Both S and T become "c". - */ -class BackspaceCompare { - - public static boolean backspaceCompare(String S, String T) { - - if (S == null || T == null) { - return S == T; - } - int i = S.length() - 1, j = T.length() - 1; - int cnt1 = 0, cnt2 = 0;//number of '#'; - while (i >= 0 || j >= 0) { - //this while loop is executed 2 times i) when it sees '#' it increments the count 'cnt1' - // ii) since 'cnt1'>0 - // the above logic is decrementing the 'i' i.e deleting the char before '#' - - while (i >= 0 && (S.charAt(i) == '#' || cnt1 > 0)) { - if (S.charAt(i) == '#') { - cnt1++; - } else { - cnt1--; - } - i--; - } - - // same as previous comment - while (j >= 0 && (T.charAt(j) == '#' || cnt2 > 0)) { - if (T.charAt(j) == '#') { - cnt2++; - } else { - cnt2--; - } - j--; - } - // if the non '#' char is not equal, then no need to proceed further - if (i >= 0 && j >= 0 && S.charAt(i) == T.charAt(j)) { - i--; - j--; - } else { - return i == -1 && j == -1; - } - } - return true; - } - - public static void main(String[] args) { - System.out.println(backspaceCompare("a##c", "#a#c")); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/BasicCalculator.java b/src/geeksforgeeks/BasicCalculator.java deleted file mode 100644 index 305eae9..0000000 --- a/src/geeksforgeeks/BasicCalculator.java +++ /dev/null @@ -1,64 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayDeque; -import java.util.Deque; - -// Input: "(1+(4+5+2)-3)+(6+8)" -// Output: 23 -public class BasicCalculator { - - public static void main(String[] args) { - System.out.println(calculate("-26-(5-6)")); - System.out.println(calculate("(1+(4+5+2)-3)+(6+8)")); - } - - public static int calculate(String s) { - if (s == null || s.length() == 0) return -1; - Deque deque = new ArrayDeque<>(); - int sign = 1; - int number = 0; - int result = 0; - // let's take an edge case 2-(5-6)=3; - // at i=0 number=2 - // i=1 char ='-' update with prev seen sign res=sign*number reset number we are looking for next operand - //i=2 char='(' and sign is '-', push prev result and sign and reset result for calclating - // sub problem inside braces - // i=3 update number to 5 - // i=4 char ='-' update result as sign*number = 5 reset number and sign =-1 - //i=5 update number to 6 - // i=6 char=')' update result with existing number(res=5=> 5+(-1*6)) and sign inside the braces - // then pop, which is last seen sign outside brace=> -1 and pop again to get result outside brace - // add all to result; - - for (int i = 0; i < s.length(); i++) { - char temp = s.charAt(i); - if (Character.isDigit(temp)) { - number = number * 10 + temp - '0'; - } else if (temp == '+') { - result += sign * number; - number = 0; - sign = 1; - } else if (temp == '-') { - result += sign * number; - number = 0; - sign = -1; - } else if (temp == '(') { - deque.addLast(result); - deque.addLast(sign); - - result = 0; - sign = 1; - } else if (temp == ')') { - result += sign * number; - number = 0; - result *= deque.removeLast(); - result += deque.removeLast(); - - } - } - if (number != 0) result += sign * number; - return result; - } - - -} \ No newline at end of file diff --git a/src/geeksforgeeks/BinaryTreeCousins.java b/src/geeksforgeeks/BinaryTreeCousins.java deleted file mode 100644 index 177d32c..0000000 --- a/src/geeksforgeeks/BinaryTreeCousins.java +++ /dev/null @@ -1,51 +0,0 @@ -package geeksforgeeks; - -import java.util.LinkedList; -import java.util.Queue; - -/** - * In a binary tree, the root node is at depth 0, - * and children of each depth k node are at depth k+1. - * Two nodes of a binary tree are cousins if they have the same depth, - * but have different parents. - * We are given the root of a binary tree with unique values, - * and the values x and y of two different nodes in the tree. - * Return true if and only if the nodes corresponding to the values x and y are cousins. - * - * Input: root = [1,2,3,null,4,null,5], x = 5, y = 4 - * Output: true - * 1 - * / \ - * 2 3 - * \ \ - * 4 5 - * - */ -public class BinaryTreeCousins { - public boolean isCousins(TreeNode root, int x, int y) { - Queue queue = new LinkedList<>(); - if(root == null) return false; - queue.add(root); - int depthY = -1; - int depthX = -2; - int level = 0; - while(!queue.isEmpty()){ - int size = queue.size(); - for(int i = 0 ; i < size ; i++){ - TreeNode node = queue.remove(); - // eagerly checking if both vales are of same parent - if(node.left != null && node.right != null){ - if(node.left.val == x && node.right.val == y) return false; - if(node.left.val == y && node.right.val == x) return false; - } - //now checking if any of x or y matches with current node and records the level - if(node.val == x) depthX = level; - if(node.val == y) depthY = level; - if(node.left != null) queue.add(node.left); - if(node.right != null) queue.add(node.right); - } - level++; - } - return depthX == depthY; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/BitonicSearch.java b/src/geeksforgeeks/BitonicSearch.java deleted file mode 100644 index 362b317..0000000 --- a/src/geeksforgeeks/BitonicSearch.java +++ /dev/null @@ -1,102 +0,0 @@ -package geeksforgeeks; - -/* A Bitonic Sequence is a sequence of numbers which is first strictly increasing then after a point strictly decreasing.*/ -public class BitonicSearch { - - static int ascendingBinarySearch(int[] arr, int low, int high, int key) { - while (low <= high) { - int mid = low + (high - low) / 2; - if (arr[mid] == key) { - return mid; - } - if (arr[mid] > key) { - high = mid - 1; - } else { - low = mid + 1; - } - } - return -1; - } - - static int descendingBinarySearch(int[] arr, int low, int high, int key) { - while (low <= high) { - int mid = low + (high - low) / 2; - if (arr[mid] == key) { - return mid; - } - if (arr[mid] < key) { - high = mid - 1; - } else { - low = mid + 1; - } - } - return -1; - } - - // instead of writing two methods, we can write a method which contains order agnostic - // binary search, which compares the first and last element at first and inside while - // if ascending add below - // if (arr[mid] > key) { - // high = mid - 1; - // } else { - // low = mid + 1; - // } - //else if decending - // if (arr[mid] < key) { - // high = mid - 1; - // } else { - // low = mid + 1; - // } - - - // -3,1,-2,-3,-4,-5,-6 - static int findBitonicPoint(int arr[], int n, int l, int r) { - int mid = ((r + l) / 2) + l; - if (arr[mid] > arr[mid - 1] && arr[mid] > arr[mid + 1]) { - return mid; - } else { - // towards right if next number is greater - if (arr[mid] > arr[mid - 1] && arr[mid] < arr[mid + 1]) { - mid = findBitonicPoint(arr, n, mid, r); - } else { - // towards left if next number is smaller - if (arr[mid] < arr[mid - 1] && arr[mid] > arr[mid + 1]) { - mid = findBitonicPoint(arr, n, l, mid); - } - } - } - return mid; - } - - static int searchBitonic(int arr[], int n, int key, int index) { - if (key > arr[index]) { - return -1; - } else if (key == arr[index]) { - return index; - } else { - int temp = ascendingBinarySearch(arr, 0, index - 1, key); - if (temp != -1) { - return temp; - } - return descendingBinarySearch(arr, index + 1, n - 1, key); - } - } - - public static void main(String args[]) { - int[] arr = { -3, 3, 9, 8, 20, 17, 5, 3, 1 }; - int key = 3; - int n = arr.length; - int l = 0; - int r = n - 1; - int index = findBitonicPoint(arr, n, l, r); - - int x = searchBitonic(arr, n, key, index); - - if (x == -1) { - System.out.println("Element Not Found"); - } else { - System.out.println("Element Found at index " + x); - } - - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/BoatsToSave.java b/src/geeksforgeeks/BoatsToSave.java deleted file mode 100644 index 85e5588..0000000 --- a/src/geeksforgeeks/BoatsToSave.java +++ /dev/null @@ -1,36 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; - -/** - * The i-th person has weight people[i], - * and each boat can carry a maximum weight of limit. - * Each boat carries at most 2 people at the same time, - * provided the sum of the weight of those people is at most limit. - * Return the minimum number of boats to carry every given person. - * (It is guaranteed each person can be carried by a boat.) - */ -class BoatsToSave { - public int numRescueBoats(int[] people, int limit) { - if(people.length==0 || limit==0) return 0; - - Arrays.sort(people); - - int i=0; - int j=people.length-1; - int res=0; - while(i<=j){ - if(people[i]+people[j]<=limit){ - res++; - i++; - j--; - }else{ - res++; - j--;// neglecting people with more weight - } - - } - - return res; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/BuyAndSellStockAnytime.java b/src/geeksforgeeks/BuyAndSellStockAnytime.java deleted file mode 100644 index a3a6e46..0000000 --- a/src/geeksforgeeks/BuyAndSellStockAnytime.java +++ /dev/null @@ -1,23 +0,0 @@ -package geeksforgeeks; - -/** - * https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ - */ -public class BuyAndSellStockAnytime { - - public int maxProfit(int[] prices) { - int total = 0; - for (int i = 0; i < prices.length - 1; i++) { - if (prices[i + 1] > prices[i]) { - total += prices[i + 1] - prices[i]; - } - } - return total; - } - - public static void main(String[] args) { - BuyAndSellStockAnytime stock = new BuyAndSellStockAnytime(); - int[] arr = { 7, 1, 5, 6, 4 }; - System.out.println(stock.maxProfit(arr)); - } -} diff --git a/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java b/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java deleted file mode 100644 index 35be29f..0000000 --- a/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java +++ /dev/null @@ -1,50 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/maximum-profit-by-buying-and-selling-a-share-at-most-twice/ - */ -class BuyAndSellStockAtMostTwice { - - public static void main(String args[]) { - int price[] = { 2, 30, 15, 10, 8, 25, 80 }; - int n = price.length; - System.out.println("Maximum Profit = " + maxProfit(price)); - } - - /** - * the idea is when we find a profit which is from - * i to n, we can break it in to i to k, k+1 to n - * in this manner at each point we can calculate profit from - * (left min element to current element) and (current element to right max element) - * the second part of the above eq can be achieved by coming from right to left - * for input [3,3,5,0,0,3,1,4] - * profit from l->r [0,0,2,2,2,3,3,4] - * profit from r->l [4,4,4,4,4,3,3,0] - * this simply states that at index 2 if we come from left the profit is 2 - * and we can initiate another transaction to obtain another profit - */ - public static int maxProfit(int[] prices) { - int ans = 0; - if (prices.length == 0 || prices.length == 1) - return ans; - int[] p = new int[prices.length]; - int minBuy = prices[0]; - int maxProfit = 0; - for (int i=1;i=0;i--) { - maxSell = Math.max(maxSell, prices[i]); - maxProfit = Math.max(maxProfit, maxSell - prices[i]); - p[i] += maxProfit; - ans = Math.max(p[i], ans); - } - return ans; - } - -} diff --git a/src/geeksforgeeks/Candy.java b/src/geeksforgeeks/Candy.java deleted file mode 100644 index 9d449bc..0000000 --- a/src/geeksforgeeks/Candy.java +++ /dev/null @@ -1,58 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; - -/** - * https://www.hackerrank.com/challenges/candies/problem - * Alice wants to give at least 1 candy to each child. - * If two children sit next to each other, then - * the one with the higher rating must get more candies than neighbour (left and right). - * Alice wants to minimize the total number of candies she must buy. - - For example, assume her students' ratings are [4, 6, 4, 5, 6, 2]. - She gives the students candy in the following minimal amounts: [1, 2, 1, 2, 3, 1]. She must buy a minimum of 10 candies. - */ -class Candy { - - // 2, 4, 2, 6, 1, 7, 8, 3, 2, 1 - // 1, 2, 1, 2, 1, 2, 3, 1, 1, 1 - // 1, 2, 4, 3, 2, 1 - int candy(int[] ratings) { - int size = ratings.length; - if (size <= 1) { - return size; - } - - // ideally we should maintain 2 arrays 1)L->R 2) R->L - // then iterate both and check max b/w 2 items as result for each index - // we optimise it further for extra space and for loop - int[] num = new int[size]; - Arrays.fill(num, 1); - // left to right - for (int i = 1; i < size; i++) { - if (ratings[i] > ratings[i - 1]) { - num[i] = num[i - 1] + 1; - } - } - - // right to left - for (int i = size - 1; i > 0; i--) { - if (ratings[i - 1] > ratings[i]) { - // check curr index + 1 or existing value - num[i - 1] = Math.max(num[i] + 1, num[i - 1]); - } - } - int result = 0; - for (int i = 0; i < size; i++) { - result += num[i]; - } - return result; - } - - public static void main(String[] args) { - Candy candy = new Candy(); - - int[] ratings = { 2, 4, 2, 6, 1, 7, 8, 9, 2, 1 }; - System.out.println(candy.candy(ratings)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/CelebrityProblem.java b/src/geeksforgeeks/CelebrityProblem.java deleted file mode 100644 index 01ac872..0000000 --- a/src/geeksforgeeks/CelebrityProblem.java +++ /dev/null @@ -1,29 +0,0 @@ -package geeksforgeeks; - -public class CelebrityProblem { - /** - * @param n a party with n people - * - * @return the celebrity's label or -1 - */ - public int findCelebrity(int n) { - int candidate = 0; - for (int i = 1; i < n; i++) { - if (knows(candidate, i)) { - candidate = i; - } - } - - for (int i = 0; i < n; i++) { - if (i != candidate && (knows(candidate, i) || !knows(i, candidate))) { - return -1; - } - } - - return candidate; - } - - public boolean knows(int candidate, int i) { - return false; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/CheckPalindromePermutation.java b/src/geeksforgeeks/CheckPalindromePermutation.java deleted file mode 100644 index cd68680..0000000 --- a/src/geeksforgeeks/CheckPalindromePermutation.java +++ /dev/null @@ -1,32 +0,0 @@ -package geeksforgeeks; - -/** - * Given a string, determine if a permutation of the string could form a palindrome. - * Input: "code" - * Output: false - * Input: "carerac" - Output: true - */ -public class CheckPalindromePermutation { - // If a string with an even length is a palindrome, every character in the string must always occur an even number of times. - // If the string with an odd length is a palindrome, every character except one of the characters must always occur an even number of times. - // Thus, in case of a palindrome, the number of characters with odd number of occurrences can't exceed 1 - - public boolean canPermutePalindrome(String s) { - if(s==null || s.length()==0) return false; - int[] cache= new int[128]; - - for(char ch: s.toCharArray()){ - cache[ch]++; - } - - int oddCOunt=0; - - for(int i=0;i<128;i++){ - oddCOunt+= cache[i]%2; - if(oddCOunt>1) return false; - } - - return true; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/CloneGraph.java b/src/geeksforgeeks/CloneGraph.java deleted file mode 100644 index 566c4c0..0000000 --- a/src/geeksforgeeks/CloneGraph.java +++ /dev/null @@ -1,70 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -/** - * Given a reference of a node in a connected undirected graph. - * - * Return a deep copy (clone) of the graph. - * - * Each node in the graph contains a val (int) and a list (List[Node]) of its neighbors - * - * For simplicity sake, each node's value is the same as the node's index (1-indexed). - * For example, the first node with val = 1, the second node with val = 2, and so on. - * The graph is represented in the test case using an adjacency list. - * - * Adjacency list is a collection of unordered lists used to represent a finite graph. - * Each list describes the set of neighbors of a node in the graph. - * - * The given node will always be the first node with val = 1. - * You must return the copy of the given node as a reference to the cloned graph. - */ -public class CloneGraph { - private static class Node { - public int val; - public List neighbors; - - public Node() { - val = 0; - neighbors = new ArrayList(); - } - - public Node(int _val) { - val = _val; - neighbors = new ArrayList(); - } - - public Node(int _val, ArrayList _neighbors) { - val = _val; - neighbors = _neighbors; - } - } - public Node cloneGraph(Node node) { - if(node==null) return node; - - Map map= new HashMap<>(); - - Queue queue= new ArrayDeque<>(); - queue.offer(node); - map.put(node, new Node(node.val)); - - while(!queue.isEmpty()){ - Node current= queue.poll(); - - for(Node neighbors: current.neighbors){ - if(!map.containsKey(neighbors)){ - Node neighborClone= new Node(neighbors.val); - map.put(neighbors,neighborClone); - queue.offer(neighbors); - } - - map.get(current).neighbors.add(map.get(neighbors)); - } - } - - return map.get(node); - - } - - -} \ No newline at end of file diff --git a/src/geeksforgeeks/ClosestNumbers.java b/src/geeksforgeeks/ClosestNumbers.java deleted file mode 100644 index ae55108..0000000 --- a/src/geeksforgeeks/ClosestNumbers.java +++ /dev/null @@ -1,47 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -/** - * https://www.geeksforgeeks.org/closest-numbers-list-unsorted-integers/ - * Given a list of distinct unsorted integers, - * find the pair of elements that have the smallest absolute difference between them? - * If there are multiple pairs, find them all. - * Input : arr[] = {10, 50, 12, 100} -Output : (10, 12) -The closest elements are 10 and 12 - -Input : arr[] = {5, 4, 3, 2} -Output : (2, 3), (3, 4), (4, 5) - */ -public class ClosestNumbers { - - public static void main(String[] args) { - //10, 50, 12, 100 - int[] arr = new int[] { 10, 50, 12, 100 }; - int n = arr.length; - if (n <= 1) { - return; - } - - // Sort array elements - Arrays.sort(arr); - - // Compare differences of adjacent - // pairs to find the minimum difference. - int minDiff = arr[1] - arr[0]; - for (int i = 2; i < n; i++) - minDiff = Math.min(minDiff, arr[i] - arr[i - 1]); - - // Traverse array again and print all pairs - // with difference as minDiff. - for (int i = 1; i < n; i++) { - if ((arr[i] - arr[i - 1]) == minDiff) { - System.out.print("(" + arr[i - 1] + ", " + arr[i] + "),"); - } - } - } - -} diff --git a/src/geeksforgeeks/CombinationIterator.java b/src/geeksforgeeks/CombinationIterator.java deleted file mode 100644 index b885767..0000000 --- a/src/geeksforgeeks/CombinationIterator.java +++ /dev/null @@ -1,53 +0,0 @@ -package geeksforgeeks; - -// CombinationIterator iterator = new CombinationIterator("abc", 2); // creates the iterator. - -import java.util.ArrayDeque; -import java.util.Deque; - -// iterator.next(); // returns "ab" -// iterator.hasNext(); // returns true -// iterator.next(); // returns "ac" -// iterator.hasNext(); // returns true -// iterator.next(); // returns "bc" -// iterator.hasNext(); // returns false -public class CombinationIterator { - Deque deque; - boolean[] visited; - public CombinationIterator(String characters, int combinationLength) { - deque= new ArrayDeque<>(); - visited= new boolean[characters.length()]; - generateCombinations(characters,deque, new StringBuilder(), combinationLength, 0); - } - - public String next() { - if(hasNext()) return deque.poll(); - - return ""; - } - - public boolean hasNext() { - return !deque.isEmpty(); - } - - public void generateCombinations(String characters, Deque deque,StringBuilder sb, int limit, int start){ - - if(sb.length()==limit){ - deque.offer(sb.toString()); - return; - } - - for(int i=start; i node.val. - * Also recall that a preorder traversal displays the value of the node first, - * then traverses node.left, then traverses node.right.) - */ -public class ConstructBSTFromPreorder { - - public static void main(String[] args) { - int[] arr = { 8, 3, 1, 6, 4, 7, 10, 14, 13 }; - bstFromPreorder(arr); - } - - public TreeNode bstFromPreorderRecursive(int[] preorder) { - return helper(preorder, 0, preorder.length - 1); - } - - private TreeNode helper(int[] preorder, int start, int end) { - if(start > end) return null; - - TreeNode node = new TreeNode(preorder[start]); - int i; - for(i=start;i<=end;i++) { - if(preorder[i] > node.val) - break; - } - - node.left = helper(preorder, start+1, i-1); - node.right = helper(preorder, i, end); - return node; - - - - } - - public static TreeNode bstFromPreorder(int[] preorder) { - if (preorder == null || preorder.length == 0) { - return null; - } - Stack stack = new Stack<>(); - TreeNode root = new TreeNode(preorder[0]); - stack.push(root); - //8, 3, 1, 6, 4, 7, 10, 14, 13 - for (int i = 1; i < preorder.length; i++) { - TreeNode node = new TreeNode(preorder[i]); - if (preorder[i] < stack.peek().val) { - stack.peek().left = node; - } else { - TreeNode parent = stack.peek(); - while (!stack.isEmpty() && preorder[i] > stack.peek().val) { - parent = stack.pop(); - } - parent.right = node; - } - stack.push(node); - } - return root; - } -} - -class TreeNode { - TreeNode left; - TreeNode right; - int val; - - public TreeNode(int val) { - this.val = val; - } - - public String toString() { - return val + ""; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/ConstructTreeFromInorderAndPostorder.java b/src/geeksforgeeks/ConstructTreeFromInorderAndPostorder.java deleted file mode 100644 index be1439f..0000000 --- a/src/geeksforgeeks/ConstructTreeFromInorderAndPostorder.java +++ /dev/null @@ -1,31 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; -import java.util.Map; - -public class ConstructTreeFromInorderAndPostorder { - // idea is same as inorder-preorder, but we take postOrder[lastIndex] as root; - public TreeNode buildTree(int[] inorder, int[] postorder) { - if(inorder==null || postorder==null) return null; - Map map= new HashMap(); - for(int i=0;i map){ - if(iStart>iEnd || pstart>pend) return null; - - TreeNode root= new TreeNode(postorder[pend]); - int divider=map.get(root.val); - // one more change is, since we need to take last element as root - // we have to carefully pass the right index to recursive calls - // pstart, pstart+divider-iStart-1-> left subarray - //pstart+divider-iStart, pend -> right sub array - root.left= helperFn(inorder, iStart,divider-1,postorder,pstart,pstart+divider-iStart-1,map); - root.right=helperFn(inorder,divider+1,iEnd,postorder,pstart+divider-iStart,pend-1,map); - return root; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java b/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java deleted file mode 100644 index a8008ab..0000000 --- a/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java +++ /dev/null @@ -1,49 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ - */ -class ConstructTreeFromInorderAndPreorder { - - // The basic idea is here: - // Say we have 2 arrays, PRE and IN. - // Preorder traversing implies that PRE[0] is the root node. - // Then we can find this PRE[0] in IN, say it's IN[5]. - // Now we know that IN[5] is root, so we know that IN[0] - IN[4] is on the left - // side, IN[6] to the end is on the right side. - // Recursively doing this on sub arrays, we can build a tree out of it :) - public TreeNode buildTree(int[] preorder, int[] inorder) { - Map map = new HashMap<>(); - List set = new LinkedList<>(); - - for (int i = 0; i < inorder.length; i++) { - map.put(inorder[i], i); - } - - for (int i = 0; i < preorder.length; i++) { - set.add(preorder[i]); - } - - return buildTreeUtil(map, set, 0, inorder.length - 1); - - } - - public TreeNode buildTreeUtil(Map map, List set, int start, int end) { - if (start > end) - return null; - if (set.isEmpty()) - return null; - int rootVal = set.get(0); - set.remove(0); - TreeNode root = new TreeNode(rootVal); - int inorderIndex = map.get(rootVal); - root.left = buildTreeUtil(map, set, start, inorderIndex - 1); - root.right = buildTreeUtil(map, set, inorderIndex + 1, end); - return root; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/ContainerWithMostWater.java b/src/geeksforgeeks/ContainerWithMostWater.java deleted file mode 100644 index 5bc747c..0000000 --- a/src/geeksforgeeks/ContainerWithMostWater.java +++ /dev/null @@ -1,36 +0,0 @@ -package geeksforgeeks; - -/** - * Given n non-negative integers a1, a2, ..., an , - * where each represents a point at coordinate (i, ai). - * n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). - * Find two lines, which together with x-axis forms a container, such that the container contains the most water. - - Note: You may not slant the container and n is at least 2. - Input: [1,8,6,2,5,4,8,3,7] - Output: 49 - */ -public class ContainerWithMostWater { - - public int maxArea(int[] height) { - if(height==null || height.length==0) return 0; - int i=0; - int j= height.length-1; - int result=0; - - while(iheight[j]){ // the reason we are moving lesser side is - // j-i is going to be decreasing so we need to - // maintain higher side to have max value - j--; - }else{ - i++; - } - } - return result; - } -} diff --git a/src/geeksforgeeks/ConvertXToY.java b/src/geeksforgeeks/ConvertXToY.java deleted file mode 100644 index 7b0f137..0000000 --- a/src/geeksforgeeks/ConvertXToY.java +++ /dev/null @@ -1,69 +0,0 @@ -package geeksforgeeks; -// Java program to find minimum -// number of steps needed to -// convert a number x into y -// with two operations allowed : -// (1) multiplication with 2 -// (2) subtraction with 1. - -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Set; - -/** - * https://www.geeksforgeeks.org/minimum-number-operation-required-convert-number-x-y/ - */ - -public class ConvertXToY { - - private static int minOperations(int src, int target) { - - Set visited = new HashSet<>(); - LinkedList queue = new LinkedList<>(); - - Steps node = new Steps(src, 0); - - queue.offer(node); - visited.add(node); - - while (!queue.isEmpty()) { - Steps temp = queue.poll(); - visited.add(temp); - - if (temp.val == target) { - return temp.steps; - } - - int mul = temp.val * 2; - int sub = temp.val - 1; - - // given constraints - if (mul > 0 && mul < 1000) { - Steps nodeMul = new Steps(mul, temp.steps + 1); - queue.offer(nodeMul); - } - if (sub > 0 && sub < 1000) { - Steps nodeSub = new Steps(sub, temp.steps + 1); - queue.offer(nodeSub); - } - } - return -1; - } - - public static void main(String[] args) { - // int x = 2, y = 5; - int x = 4, y = 7; - Steps src = new Steps(x, y); - System.out.println(minOperations(x, y)); - } -} - -class Steps { - int val; - int steps; - - public Steps(int val, int steps) { - this.val = val; - this.steps = steps; - } -} diff --git a/src/geeksforgeeks/CountAllPathsFrom2DMatrix.java b/src/geeksforgeeks/CountAllPathsFrom2DMatrix.java deleted file mode 100644 index 8d99fea..0000000 --- a/src/geeksforgeeks/CountAllPathsFrom2DMatrix.java +++ /dev/null @@ -1,43 +0,0 @@ -package geeksforgeeks; - -/*https://www.geeksforgeeks.org/count-possible-paths-top-left-bottom-right-nxm-matrix/*/ -class CountAllPathsFrom2DMatrix { - // A Java program to count all possible paths - // from top left to bottom right - // Returns count of possible paths to reach - // cell at row number m and column number n from - // the topmost leftmost cell (cell at 1, 1) - static int numberOfPaths(int m, int n) { - // Create a 2D table to store results - // of subproblems - int count[][] = new int[m][n]; - - // Count of paths to reach any cell in - // first row is 1 - for (int i = 0; i < m; i++) - count[i][0] = 1; - - // Count of paths to reach any cell in - // first column is 1 - for (int j = 0; j < n; j++) - count[0][j] = 1; - - // Calculate count of paths for other - // cells in bottom-up manner using - // the recursive solution - for (int i = 1; i < m; i++) { - for (int j = 1; j < n; j++) - - // By uncommenting the last part the - // code calculatest he total possible paths - // if the diagonal Movements are allowed - count[i][j] = count[i - 1][j] + count[i][j - 1]; //+ count[i-1][j-1]; - } - return count[m - 1][n - 1]; - } - - // Driver program to test above function - public static void main(String args[]) { - System.out.println(numberOfPaths(3, 3)); - } -} diff --git a/src/geeksforgeeks/CountAndSay.java b/src/geeksforgeeks/CountAndSay.java deleted file mode 100644 index 6b1edf9..0000000 --- a/src/geeksforgeeks/CountAndSay.java +++ /dev/null @@ -1,41 +0,0 @@ -package geeksforgeeks; - - -/** - * https://leetcode.com/problems/count-and-say/ - */ -public class CountAndSay { - public String countAndSay(int n) { - if (n <= 0) { - return "-1"; - } - String result = "1"; - - for (int i = 1; i < n; i++) { - result = build(result); - } - return result; - } - - private String build(String result) { - StringBuilder builder = new StringBuilder(); - int p = 0; - while (p < result.length()) { - char val = result.charAt(p); - int count = 0; - - while (p < result.length() && result.charAt(p) == val) { // note that p and val will be same in first run, to count single instance - p++; - count++; - } - builder.append(count); - builder.append(val); - } - return builder.toString(); - } - - public static void main(String[] args) { - CountAndSay countAndSay = new CountAndSay(); - System.out.println(countAndSay.countAndSay(4)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/CountElements.java b/src/geeksforgeeks/CountElements.java deleted file mode 100644 index 44e98af..0000000 --- a/src/geeksforgeeks/CountElements.java +++ /dev/null @@ -1,59 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; - -/** - * Given an integer array arr, count element x such that x + 1 is also in arr. - *

- * If there're duplicates in arr, count them separetely. - *

- *

- *

- * Example 1: - *

- * Input: arr = [1,2,3] - * Output: 2 - * Explanation: 1 and 2 are counted cause 2 and 3 are in arr. - * Example 2: - *

- * Input: arr = [1,1,3,3,5,5,7,7] - * Output: 0 - * Explanation: No numbers are counted, cause there's no 2, 4, 6, or 8 in arr. - * Example 3: - *

- * Input: arr = [1,3,2,3,5,0] - * Output: 3 - * Explanation: 0, 1 and 2 are counted cause 1, 2 and 3 are in arr. - * Example 4: - *

- * Input: arr = [1,1,2,2] - * Output: 2 - * Explanation: Two 1s are counted cause 2 is in arr. - */ -public class CountElements { - - public static int countElements(int[] arr) { - if (arr == null || arr.length == 0) { - return 0; - } - - HashMap freqMap = new HashMap<>(); - - for (int in : arr) { - freqMap.put(in, freqMap.getOrDefault(in, 0) + 1); - } - - int count = 0; - for (int i = 0; i < arr.length; i++) { - if (freqMap.containsKey(arr[i] - 1)) { - count = count + freqMap.get(arr[i] - 1); - freqMap.put(arr[i] - 1, 0); - } - } - return count; - } - - public static void main(String[] args) { - System.out.println(countElements(new int[]{1, 3, 2, 3, 5, 0})); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/CountMinimumStepsToFormDesiredInputArray.java b/src/geeksforgeeks/CountMinimumStepsToFormDesiredInputArray.java deleted file mode 100644 index 9b0310a..0000000 --- a/src/geeksforgeeks/CountMinimumStepsToFormDesiredInputArray.java +++ /dev/null @@ -1,70 +0,0 @@ -package geeksforgeeks;/* Java program to count minimum number of operations -to get the given arr array */ - -/*https://www.geeksforgeeks.org/count-minimum-steps-get-given-desired-array/*/ -// unsolved -class CountMinimumStepsToFormDesiredInputArray { - static int arr[] = new int[] { 16, 16, 16 }; - - // Returns count of minimum operations to covert a - // zero array to arr array with increment and - // doubling operations. - // This function computes count by doing reverse - // steps, i.e., convert arr to zero array. - static int countMinOperations(int n) { - // Initialize result (Count of minimum moves) - int result = 0; - - // Keep looping while all elements of arr - // don't become 0. - while (true) { - // To store count of zeroes in current - // arr array - int zero_count = 0; - - int i; // To find first odd element - for (i = 0; i < n; i++) { - // If odd number found - if (arr[i] % 2 == 1) { - break; - } - - // If 0, then increment zero_count - else if (arr[i] == 0) { - zero_count++; - } - } - - // All numbers are 0 - if (zero_count == n) { - return result; - } - - // All numbers are even - if (i == n) { - // Divide the whole array by 2 - // and increment result - for (int j = 0; j < n; j++) - arr[j] = arr[j] / 2; - result++; - } - - // Make all odd numbers even by subtracting - // one and increment result. - for (int j = i; j < n; j++) { - if (arr[j] % 2 == 1) { - arr[j]--; - result++; - } - } - } - } - - public static void main(String[] args) { - - System.out.println( - "Minimum number of steps required to \n" + "get the given target array is " + countMinOperations( - arr.length)); - - } -} diff --git a/src/geeksforgeeks/CountNumbersLessThanSelf.java b/src/geeksforgeeks/CountNumbersLessThanSelf.java deleted file mode 100644 index 447f314..0000000 --- a/src/geeksforgeeks/CountNumbersLessThanSelf.java +++ /dev/null @@ -1,103 +0,0 @@ -package geeksforgeeks; - -import java.util.LinkedList; -import java.util.List; - -/** - * You are given an integer array nums and you have to return a new counts array. - * The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i]. - * Input: [5,2,6,1] - * Output: [2,1,1,0] - */ -class CountNumbersLessThanSelf { - // Wrapper class for each and every value of the input array, -// to store the original index position of each value, before we merge sort the array - private class ArrayValWithOrigIdx { - int val; - int originalIdx; - - public ArrayValWithOrigIdx(int val, int originalIdx) { - this.val = val; - this.originalIdx = originalIdx; - } - } - - public List countSmaller(int[] nums) { - if (nums == null || nums.length == 0) return new LinkedList(); - int n = nums.length; - int[] result = new int[n]; - - ArrayValWithOrigIdx[] newNums = new ArrayValWithOrigIdx[n]; - for (int i = 0; i < n; ++i) newNums[i] = new ArrayValWithOrigIdx(nums[i], i); - - mergeSortAndCount(newNums, 0, n - 1, result); - - // notice we don't care about the sorted array after merge sort finishes. - // we only wanted the result counts, generated by running merge sort - List resultList = new LinkedList(); - for (int i : result) resultList.add(i); - return resultList; - } - - private void mergeSortAndCount(ArrayValWithOrigIdx[] nums, int start, int end, int[] result) { - if (start >= end) return; - - int mid = (start + end) / 2; - mergeSortAndCount(nums, start, mid, result); - mergeSortAndCount(nums, mid + 1, end, result); - - // left subarray start...mid - // right subarray mid+1...end - int leftPos = start; - int rightPos = mid + 1; - LinkedList merged = new LinkedList(); - int numElemsRightArrayLessThanLeftArray = 0; - while (leftPos < mid + 1 && rightPos <= end) { - if (nums[leftPos].val > nums[rightPos].val) { - // this code block is exactly what the problem is asking us for: - // a number from the right side of the original input array, is smaller - // than a number from the left side - // - // within this code block, - // nums[rightPos] is smaller than the start of the left sub-array. - // Since left sub-array is already sorted, - // nums[rightPos] must also be smaller than the entire remaining left sub-array - ++numElemsRightArrayLessThanLeftArray; - - // continue with normal merge sort, merge - merged.add(nums[rightPos]); - ++rightPos; - } else { - // a number from left side of array, is smaller than a number from - // right side of array - result[nums[leftPos].originalIdx] += numElemsRightArrayLessThanLeftArray; - - // Continue with normal merge sort - merged.add(nums[leftPos]); - ++leftPos; - } - } - - // part of normal merge sort, if either left or right sub-array is not empty, - // move all remaining elements into merged result - while (leftPos < mid + 1) { - result[nums[leftPos].originalIdx] += numElemsRightArrayLessThanLeftArray; - - merged.add(nums[leftPos]); - ++leftPos; - } - while (rightPos <= end) { - merged.add(nums[rightPos]); - ++rightPos; - } - - // part of normal merge sort - // copy back merged result into array - int pos = start; - for (ArrayValWithOrigIdx m : merged) { - nums[pos] = m; - ++pos; - } - } -} - diff --git a/src/geeksforgeeks/CountingInversion.java b/src/geeksforgeeks/CountingInversion.java deleted file mode 100644 index b9b678b..0000000 --- a/src/geeksforgeeks/CountingInversion.java +++ /dev/null @@ -1,62 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/counting-inversions/ - */ -class CountingInversion { - - static int mergeSort(int[] arr, int arrSize) { - int[] temp = new int[arrSize]; - return mergeSort(arr, temp, 0, arrSize - 1); - } - - static int mergeSort(int[] arr, int[] temp, int left, int right) { - int mid; - int invCount = 0; - if (left < right) { - mid = ((right - left) / 2) + left; - - invCount = mergeSort(arr, temp, left, mid); - invCount += mergeSort(arr, temp, mid + 1, right); - - invCount += merge(arr, temp, left, mid + 1, right); - } - return invCount; - } - - static int merge(int[] arr, int[] temp, int left, int mid, int right) { - int invCount = 0; - - int i = left; - int j = mid; - int k = left; - while ((i <= mid - 1) && (j <= right)) { - if (arr[i] <= arr[j]) { - temp[k++] = arr[i++]; - } else { - temp[k++] = arr[j++]; - // the reason to put mid-i is take example of [1,3,5] [2,4,6] - // left is 0 and right is mid at start - // when i=1 and j=0 (value 3 and 2) we see an inversion, since - // the first part is sorted and values after i=1(3) will be greater than j=0(2) - // so we consider all elements after 3 as inversions - invCount = invCount + (mid - i); - } - } - - while (i <= mid - 1) - temp[k++] = arr[i++]; - while (j <= right) - temp[k++] = arr[j++]; - - for (i = left; i <= right; i++) - arr[i] = temp[i]; - - return invCount; - } - - public static void main(String[] args) { - int arr[] = new int[] { 4, 6, 2, 1, 9, 7 }; - System.out.println("Number of inversions are " + mergeSort(arr, arr.length)); - } -} diff --git a/src/geeksforgeeks/CourseSchedule.java b/src/geeksforgeeks/CourseSchedule.java deleted file mode 100644 index 19d6167..0000000 --- a/src/geeksforgeeks/CourseSchedule.java +++ /dev/null @@ -1,116 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Queue; -/** - * Input: numCourses = 2, prerequisites = [[1,0]] -Output: true -Explanation: There are a total of 2 courses to take. -To take course 1 you should have finished course 0. So it is possible. - -Input: numCourses = 2, prerequisites = [[1,0],[0,1]] -Output: false -Explanation: There are a total of 2 courses to take. - To take course 1 you should have finished course 0, and to take course 0 you should - also have finished course 1. So it is impossible. - */ -class CourseSchedule { - public boolean canFinish(int numCourses, int[][] prerequisites) { - - Map> map = new HashMap<>(); // Courses that depend on the key - int[] degrees = new int[numCourses]; // # of prerequisites for course i - Queue queue = new ArrayDeque<>(); // Used to find dependants and decrease their outdegree - - for (int[] pre : prerequisites) { - List tempList = map.getOrDefault(pre[1], new ArrayList<>()); - tempList.add(pre[0]); - degrees[pre[0]]++; - map.put(pre[1], tempList); - } - - for (int i = 0; i < degrees.length; i++) { - if (degrees[i] == 0) { - queue.offer(i); - } - } - - int count = 0; - while (!queue.isEmpty()) { - int temp = queue.poll(); - if (degrees[temp] == 0) { - count++; // if cond for duplicates - } - if (!map.containsKey(temp)) { - continue; - } - for (int i : map.get(temp)) { - if (--degrees[i] == 0) { - queue.offer(i); - } - } - } - - return count == numCourses; - } - - public boolean canFinishDFS(int numCourses, int[][] prerequisites) { - // this method basically finds a back-edge between nodes - // backedge is when doing a node(A)'s dfs, it puts A to a temp state - // while traversing A's child, if any of child dosen't have anymore child it's marked as completed - // if there are children it put's the current child to temp state and visits it's children - // so when doing a dfs for a node if it encounters a temp state node rather than completed node - // then that means there's a cycle we cannot complete the course - // (T) A \ - // / / - // (T) B / - // / \ / - // (Co) C D (T) while doing DFS for D's components we encounter A, but A is still in temp state - // - ArrayList[] adjList= new ArrayList[numCourses]; - for(int i=0;i(); - } - for(int[] preReq:prerequisites){ - adjList[preReq[0]].add(preReq[1]); - } - // this visited array will maintain 3 values 0,1 and 2 - // 0-unvisited, 1-being visited and 2 visited - int[] visited= new int[numCourses]; - for(int i=0;i[] adjList, int[] visited, int vertex){ - if(visited[vertex]==1) return false; // when a node comes with being visited state, we fail it - visited[vertex]=1; - for(int adj: adjList[vertex]){ - if(!dfs(adjList, visited, adj)) return false; - } - visited[vertex]=2; // finally we set visited to true - return true; - } - // this is to get the order of course as output - public boolean dfs( List[] adjList, int[] visited, Listresult, int node){ - if(visited[node]==1) return false; - if(visited[node]==2) return true; - - visited[node]=1; - for(int adj: adjList[node]){ - if(!dfs(adjList, visited, result, adj)){ - return false; - } - } - visited[node]=2; - result.add(node); // this will keep track of which to fininsh first and last - return true; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/DecodeString.java b/src/geeksforgeeks/DecodeString.java deleted file mode 100644 index 7539c8b..0000000 --- a/src/geeksforgeeks/DecodeString.java +++ /dev/null @@ -1,51 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayDeque; -import java.util.Deque; - -// s = "3[a2[c]]", return "accaccacc". -// s = "2[abc]3[cd]ef", return "abcabccdcdcdef". -public class DecodeString { - public static String decodeString(String s) { - if (s == null) - return ""; - - Deque count = new ArrayDeque<>(); - Deque result = new ArrayDeque<>(); - int start = 0; - StringBuilder tempResult = new StringBuilder(); - while (start < s.length()) { - // whenever we see number, we push to count queue - if (Character.isDigit(s.charAt(start))) { - int num = 0; - while (Character.isDigit(s.charAt(start))) { - num = num * 10 + s.charAt(start) - '0'; - start++; - } - count.push(num); - } else if (s.charAt(start) == '[') { - // whenever we see a open brace we push the string we have to result queue - result.push(tempResult.toString()); - tempResult = new StringBuilder(); - start++; - } else if (s.charAt(start) == ']') { - // whenever a closing brace comes, we pop the last seen count and last seen string - // and replicate that string and stores in temp result - StringBuilder sb = new StringBuilder(result.pop()); - int tempCount = count.pop(); - sb.append(tempResult.toString().repeat(tempCount)); - tempResult = sb; - start++; - } else { - // whenever we see a char, we push to result string - tempResult.append(s.charAt(start++)); - } - } - - return tempResult.toString(); - } - - public static void main(String[] args) { - System.out.println(decodeString("3[a2[c]]")); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/DesignCompressedStringIterator.java b/src/geeksforgeeks/DesignCompressedStringIterator.java deleted file mode 100644 index 617ba19..0000000 --- a/src/geeksforgeeks/DesignCompressedStringIterator.java +++ /dev/null @@ -1,59 +0,0 @@ -package geeksforgeeks; - -/** - * https://leetcode.com/articles/desing-compressed-string-iterator/ - * 604. Design Compressed String Iterator - * Design and implement a data structure for a compressed string iterator. The given compressed string will be in the form of each letter followed by a positive integer representing the number of this letter existing in the original uncompressed string. - * Implement the StringIterator class: - * next() Returns the next character if the original string still has uncompressed characters, otherwise returns a white space. - * hasNext() Returns true if there is any letter needs to be uncompressed in the original string, otherwise returns false. - - * Example 1: - - * Input - * ["StringIterator", "next", "next", "next", "next", "next", "next", "hasNext", "next", "hasNext"] - * [["L1e2t1C1o1d1e1"], [], [], [], [], [], [], [], [], []] - * Output - * [null, "L", "e", "e", "t", "C", "o", true, "d", true] - * Explanation - * StringIterator stringIterator = new StringIterator("L1e2t1C1o1d1e1"); - * stringIterator.next(); // return "L" - * stringIterator.next(); // return "e" - * stringIterator.next(); // return "e" - * stringIterator.next(); // return "t" - * stringIterator.next(); // return "C" - * stringIterator.next(); // return "o" - * stringIterator.hasNext(); // return True - * stringIterator.next(); // return "d" - * stringIterator.hasNext(); // return True - */ -public class DesignCompressedStringIterator { - - String res; - - int ptr = 0; - int num = 0; - char ch = ' '; - - public DesignCompressedStringIterator(String s) { - res = s; - } - - public char next() { - if (!hasNext()) { - return ' '; - } - if (num == 0) { - ch = res.charAt(ptr++); - while (ptr < res.length() && Character.isDigit(res.charAt(ptr))) { - num = num * 10 + res.charAt(ptr++) - '0'; - } - } - num--; - return ch; - } - - public boolean hasNext() { - return ptr != res.length() || num != 0; - } -} diff --git a/src/geeksforgeeks/DesignFileSystem.java b/src/geeksforgeeks/DesignFileSystem.java deleted file mode 100644 index d2f4b8d..0000000 --- a/src/geeksforgeeks/DesignFileSystem.java +++ /dev/null @@ -1,64 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; - -/** - * You are asked to design a file system which provides two functions: - * - * createPath(path, value): Creates a new path and associates a value to it if possible and returns True. - * Returns False if the path already exists or its parent path doesn't exist. - * - * get(path): Returns the value associated with a path or returns -1 if the path doesn't exist. - * - * ["FileSystem","createPath","createPath","get","createPath","get"] - * [[],["/leet",1],["/leet/code",2],["/leet/code"],["/c/d",1],["/c"]] - * Output: - * [null,true,true,2,false,-1] - * Explanation: - * FileSystem fileSystem = new FileSystem(); - * - * fileSystem.createPath("/leet", 1); // return true - * fileSystem.createPath("/leet/code", 2); // return true - * fileSystem.get("/leet/code"); // return 2 - * fileSystem.createPath("/c/d", 1); // return false because the parent path "/c" doesn't exist. - * fileSystem.get("/c"); // return -1 because this path doesn't exist. - */ -public class DesignFileSystem { - - private HashMap m = new HashMap<>(); - - /** - * Initialization of class. - * Use a hash map to store the path and value. - */ - public DesignFileSystem() { - m.put("", -1); // avoid initially when path is "/a" regarded as false - } - - /** - * Creates a new path and associates a value to it if possible and returns True. - * The valid path's parent is the path before the last "/". - * Hence, check parent and then put the path into map if it is valid. - * If the path has already exist, return false. - * - * @param path given path - * @param value given value - * @return true to create a new path with value, false if the path already exists or its parent path doesn't exist - */ - public boolean create(String path, int value) { - if (path.charAt(0) != '/') { - return false; - } - String parent = path.substring(0, path.lastIndexOf("/")); - if (!m.containsKey(parent)) { - return false; - } - - return m.putIfAbsent(path, value) == null; // if the path exist, m.putIfAbsent(path, value) will be null - } - - public int get(String path) { - return m.getOrDefault(path, -1); - } - -} \ No newline at end of file diff --git a/src/geeksforgeeks/DesignInMemoryFileSystem.java b/src/geeksforgeeks/DesignInMemoryFileSystem.java deleted file mode 100644 index 2d85f20..0000000 --- a/src/geeksforgeeks/DesignInMemoryFileSystem.java +++ /dev/null @@ -1,96 +0,0 @@ -package geeksforgeeks; -/** - * Design an in-memory file system to simulate the following functions: - *

- * ls: Given a path in string format. If it is a file path, return a list that only contains this file's name. - * If it is a directory path, return the list of file and directory names in this directory. Your output (file and directory names together) should in lexicographic order. - *

- * mkdir: Given a directory path that does not exist, you should make a new directory according to the path. - * If the middle directories in the path don't exist either, you should create them as well. This function has void return type. - *

- * addContentToFile: Given a file path and file content in string format. - * If the file doesn't exist, you need to create that file containing given content. - * If the file already exists, you need to append given content to original content. This function has void return type. - *

- * readContentFromFile: Given a file path, return its content in string format. - */ - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; - -public class DesignInMemoryFileSystem { - class Trie { - boolean isFile = false; - HashMap folders = new HashMap<>(); - String content = ""; - } - - Trie root; - - public DesignInMemoryFileSystem() { - root = new Trie(); - } - - public List ls(String path) { - Trie trie = root; - List files = new ArrayList<>(); - if (!path.equals("/")) { - String[] arr = path.split("/"); - for (int i = 1; i < arr.length; i++) { - trie = trie.folders.get(arr[i]); - } - if (trie.isFile) { - files.add(arr[arr.length - 1]); - return files; - } - } - List res_files = new ArrayList<>(trie.folders.keySet()); - Collections.sort(res_files); - return res_files; - } - - public void mkdir(String path) { - Trie trie = root; - String[] arr = path.split("/"); - for (int i = 1; i < arr.length; i++) { - if (!trie.folders.containsKey(arr[i])) { - trie.folders.put(arr[i], new Trie()); - } - trie = trie.folders.get(arr[i]); - } - } - - public void addContentToFile(String filePath, String content) { - Trie trie = root; - String[] arr = filePath.split("/"); - for (int i = 1; i < arr.length - 1; i++) { - trie = trie.folders.get(arr[i]); - } - if (!trie.folders.containsKey(arr[arr.length - 1])) { - trie.folders.put(arr[arr.length - 1], new Trie()); - } - trie = trie.folders.get(arr[arr.length - 1]); - trie.isFile = true; - trie.content = trie.content + content; - } - - public String readContentFromFile(String filePath) { - Trie trie = root; - String[] arr = filePath.split("/"); - for (int i = 1; i < arr.length - 1; i++) { - trie = trie.folders.get(arr[i]); - } - return trie.folders.get(arr[arr.length - 1]).content; - } -} - -/** - * Your FileSystem object will be instantiated and called as such: - * FileSystem obj = new FileSystem(); - * List param_1 = obj.ls(path); - * obj.mkdir(path); - * obj.addContentToFile(filePath,content); - * String param_4 = obj.readContentFromFile(filePath); - */ \ No newline at end of file diff --git a/src/geeksforgeeks/DesignStackIncrement.java b/src/geeksforgeeks/DesignStackIncrement.java deleted file mode 100644 index 6ea7ef2..0000000 --- a/src/geeksforgeeks/DesignStackIncrement.java +++ /dev/null @@ -1,101 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Stack; - -/** - * Design a stack which supports the following operations. - * - * Implement the CustomStack class: - * - * CustomStack(int maxSize) Initializes the object with maxSize which is the maximum number of elements in the stack or do nothing if the stack reached the maxSize. - * void push(int x) Adds x to the top of the stack if the stack hasn't reached the maxSize. - * int pop() Pops and returns the top of stack or -1 if the stack is empty. - * void inc(int k, int val) Increments the bottom k elements of the stack by val. - * If there are less than k elements in the stack, just increment all the elements in the stack. - * - * ["CustomStack","push","push","pop","push","push","push","increment","increment","pop","pop","pop","pop"] - * [[3],[1],[2],[],[2],[3],[4],[5,100],[2,100],[],[],[],[]] - * Output - * [null,null,null,2,null,null,null,null,null,103,202,201,-1] - * Explanation - * CustomStack customStack = new CustomStack(3); // Stack is Empty [] - * customStack.push(1); // stack becomes [1] - * customStack.push(2); // stack becomes [1, 2] - * customStack.pop(); // return 2 --> Return top of the stack 2, stack becomes [1] - * customStack.push(2); // stack becomes [1, 2] - * customStack.push(3); // stack becomes [1, 2, 3] - * customStack.push(4); // stack still [1, 2, 3], Don't add another elements as size is 4 - * customStack.increment(5, 100); // stack becomes [101, 102, 103] - * customStack.increment(2, 100); // stack becomes [201, 202, 103] - * customStack.pop(); // return 103 --> Return top of the stack 103, stack becomes [201, 202] - * customStack.pop(); // return 202 --> Return top of the stack 102, stack becomes [201] - * customStack.pop(); // return 201 --> Return top of the stack 101, stack becomes [] - * customStack.pop(); // return -1 --> Stack is empty return -1. - */ -public class DesignStackIncrement { - - int n; - int[] inc; - Stack stack; - - public DesignStackIncrement(int maxSize) { - n = maxSize; - inc = new int[n]; - stack = new Stack<>(); - } - - public void push(int x) { - if (stack.size() < n) { - stack.push(x); - } - } - - public int pop() { - /* - since array elements go forward(left -> right) and stack goes - top to bottom which translates to array as right->left - so when the increment operation happens for let's say last 4 elements - we set the array pos 4 to 'increment' value. Finally when the pop - is happened we need to set the array's 3rd posistion to the 4th's value inc[i - 1] += inc[i]; - since 3 is yet to be pop-ed from stack - */ - - int i = stack.size() - 1; - if (i < 0) { - return -1; - } - if (i > 0) { - inc[i - 1] += inc[i]; - } - int res = stack.pop() + inc[i]; - inc[i] = 0; - return res; - } - - public void increment(int k, int val) { - int i = Math.min(k, stack.size()) - 1; - if (i >= 0) { - inc[i] += val; - } - } - - public static void main(String[] args) { - DesignStackIncrement customStack = new DesignStackIncrement(4); - customStack.push(1); - customStack.push(2); - customStack.push(3); - customStack.push(4); - customStack.increment(5, 100); - customStack.increment(2, 100); - System.out.println(customStack.pop()); - System.out.println(customStack.pop()); - System.out.println(customStack.pop()); - System.out.println(customStack.pop()); - - List list = new ArrayList<>(Arrays.asList("hello".split(""))); - list.size(); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/DesignTicTacToe.java b/src/geeksforgeeks/DesignTicTacToe.java deleted file mode 100644 index c0c16a0..0000000 --- a/src/geeksforgeeks/DesignTicTacToe.java +++ /dev/null @@ -1,107 +0,0 @@ -package geeksforgeeks; -/* -Design a Tic-tac-toe game that is played between two players on a n x n grid. - -You may assume the following rules: - -A move is guaranteed to be valid and is placed on an empty block. -Once a winning condition is reached, no more moves is allowed. -A player who succeeds in placing n of their marks in a horizontal, vertical, or diagonal row wins the game. - -Given n = 3, assume that player 1 is "X" and player 2 is "O" in the board. - -TicTacToe toe = new TicTacToe(3); - -toe.move(0, 0, 1); -> Returns 0 (no one wins) -|X| | | -| | | | // Player 1 makes a move at (0, 0). -| | | | - -toe.move(0, 2, 2); -> Returns 0 (no one wins) -|X| |O| -| | | | // Player 2 makes a move at (0, 2). -| | | | - -toe.move(2, 2, 1); -> Returns 0 (no one wins) -|X| |O| -| | | | // Player 1 makes a move at (2, 2). -| | |X| - -toe.move(1, 1, 2); -> Returns 0 (no one wins) -|X| |O| -| |O| | // Player 2 makes a move at (1, 1). -| | |X| - -toe.move(2, 0, 1); -> Returns 0 (no one wins) -|X| |O| -| |O| | // Player 1 makes a move at (2, 0). -|X| |X| - -toe.move(1, 0, 2); -> Returns 0 (no one wins) -|X| |O| -|O|O| | // Player 2 makes a move at (1, 0). -|X| |X| - -toe.move(2, 1, 1); -> Returns 1 (player 1 wins) -|X| |O| -|O|O| | // Player 1 makes a move at (2, 1). -|X|X|X| - */ -public class DesignTicTacToe { - private int[] rows; - private int[] cols; - private int diagonal; - private int antiDiagonal; - - /** Initialize your data structure here. */ - public DesignTicTacToe(int n) { - rows = new int[n]; - cols = new int[n]; - } - - /** Player {player} makes a move at ({row}, {col}). - @param row The row of the board. - @param col The column of the board. - @param player The player, can be either 1 or 2. - @return The current winning condition, can be either: - 0: No one wins. - 1: Player 1 wins. - 2: Player 2 wins. */ - public int move(int row, int col, int player) { - int toAdd = player == 1 ? 1 : -1; - // if A player makes a move on 0,0 we are going to increment index posistion of row and col at 0,0 - // if B player makes a move on 0,2 we are going to decrement index posistion at row and col at 0,2 - // after that the count of row at 0 will be 0(balanced moves) like wise if a row or col has value n only - // a player can be adjudged a winner - rows[row] += toAdd; - cols[col] += toAdd; - if (row == col) { - diagonal += toAdd; - } - - if (col + row == cols.length - 1) { - antiDiagonal += toAdd; - } - - int size = rows.length; - if (Math.abs(rows[row]) == size || - Math.abs(cols[col]) == size || - Math.abs(diagonal) == size || - Math.abs(antiDiagonal) == size) { - return player; - } - - return 0; - } - - public static void main(String[] args) { - DesignTicTacToe toe=new DesignTicTacToe(3); - toe.move(0, 0, 1); - toe.move(0, 2, 2); - toe.move(2, 2, 1); - toe.move(1, 1, 2); - toe.move(2, 0, 1); - toe.move(1, 0, 2); - toe.move(2, 1, 1); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/DifferentWaysToAddParenthesis.java b/src/geeksforgeeks/DifferentWaysToAddParenthesis.java deleted file mode 100644 index 0a0dff6..0000000 --- a/src/geeksforgeeks/DifferentWaysToAddParenthesis.java +++ /dev/null @@ -1,61 +0,0 @@ -package geeksforgeeks; - -// Given a string of numbers and operators, -// return all possible results from computing all the different possible ways to group numbers -// and operators. The valid operators are +, - and *. - -import java.util.*; - -// Input: "2*3-4*5" -// Output: [-34, -14, -10, -10, 10] -// Explanation: -// (2*(3-(4*5))) = -34 -// ((2*3)-(4*5)) = -14 -// ((2*(3-4))*5) = -10 -// (2*((3-4)*5)) = -10 -// (((2*3)-4)*5) = 10 -public class DifferentWaysToAddParenthesis { - public List diffWaysToCompute(String input) { - if(input==null) return Collections.emptyList(); - - Map> map= new HashMap<>(); - return bfsHelper(input, map); - - } - - public List bfsHelper(String input, Map> map){ - - if(map.containsKey(input)){ - return map.get(input); - } - - List result= new ArrayList<>(); - if(!input.contains("+") && !input.contains("-") && !input.contains("*")){ - result.add(Integer.parseInt(input)); - }else{ - // Split input string into two parts and solve them recursively - // for ex input = 2*3-4 output=2,-2 - // 2* | 3-4 => this right and left expression returns a list - // 2*3| -4 => this right and left expression returns another list - for(int i=0;i firstList= bfsHelper(input.substring(0,i),map); - List secondList= bfsHelper(input.substring(i+1),map); - for(int first: firstList){ - for(int second: secondList){ - if(input.charAt(i)=='+'){ - result.add(first+second); - }else if(input.charAt(i)=='-'){ - result.add(first-second); - }else{ - result.add(first*second); - } - } - } - } - } - } - map.put(input,result); - return result; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/DivideSubArrayAverage.java b/src/geeksforgeeks/DivideSubArrayAverage.java deleted file mode 100644 index 937d628..0000000 --- a/src/geeksforgeeks/DivideSubArrayAverage.java +++ /dev/null @@ -1,47 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/divide-array-two-sub-arrays-averages-equal/ - * - * Given an integer array, the task is to divide an integer array into - * two sub-arrays to make their averages equal if possible. - * - * Input : arr[] = {1, 5, 7, 2, 0}; - * Output : (0 1) and (2 4) - * Subarrays arr[0..1] and arr[2..4] have - * same average. - * - * Input : arr[] = {4, 3, 5, 9, 11}; - * Output : Not possible - */ -class DivideSubArrayAverage { - - static void findSubarrays(int arr[], int n) { - int sum = 0; - for (int i = 0; i < n; i++) - sum += arr[i]; - - boolean found = false; - int lsum = 0; - for (int i = 0; i < n - 1; i++) { - lsum += arr[i]; - int rsum = sum - lsum; - - if (lsum * (n - i - 1) == rsum * (i + 1)) { - System.out.println("found"); - found = true; - } - } - - // If no subarrays found - if (!found) { - System.out.println("Not found"); - } - } - - public static void main(String[] args) { - int[] arr = { 1, 5, 7, 2, 0 }; - int n = arr.length; - findSubarrays(arr, n); - } -} diff --git a/src/geeksforgeeks/DungeonGame.java b/src/geeksforgeeks/DungeonGame.java deleted file mode 100644 index 66b2803..0000000 --- a/src/geeksforgeeks/DungeonGame.java +++ /dev/null @@ -1,64 +0,0 @@ -package geeksforgeeks; - -// The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. -//The dungeon consists of M x N rooms laid out in a 2D grid. -//Our valiant knight (K) was initially positioned in the top-left room and must fight his way through the dungeon to rescue the princess. - -// The knight has an initial health point represented by a positive integer. -//If at any point his health point drops to 0 or below, he dies immediately. -//Input -// |-2 -3 3 | -// |-5 -10 1 | -// |10 30 -5 | - -//output 7 - -// the trick here is to go bottom up, start from the last cell, -// inorder to reach there he should have at-least 6 as health, so that -// when he reaches -5(energy is consumed) and he's left with +1 health -// likewise if we backtrack from end to start, we'll need +7 as min initial health to -// play the game -public class DungeonGame { - public int calculateMinimumHP(int[][] dungeon) { - - int[][] dp = new int[dungeon.length][dungeon[0].length]; - - int m = dungeon.length; - int n = dungeon[0].length; - - dp[m-1][n-1] = Math.max(1, 1-dungeon[m-1][n-1]); - - // Populate the last column - for(int i=m-2;i>=0;i--){ - dp[i][n-1] = Math.max(1, dp[i+1][n-1]-dungeon[i][n-1]); - } - - // Populate the last row - for(int i=n-2;i>=0;i--){ - dp[m-1][i] = Math.max(1, dp[m-1][i+1]-dungeon[m-1][i]); - } - - // to achieve the answer, we need to setup the last row and last column - // we know to reach last cell we need 6 as energy, let's say that comes - // from cell above it, that cell's original val is +1, so we must have - // 5 energy when we reach there and adding it up, it became 6 - // the reason to put 1 on last row is, the value in that cell is 30 - // so to reach last cell from that cell, we need only 6 energy(min) - // to have 6 from +30, player should have health of -24 and player cannot - // have neg val, so we put 1 as filler - // |* * 2 | - // |* * 5 | - // |1 1 6 | - - // Populate the rest by taking max of bottom and right (reverse of down and left) - - for(int i=m-2;i>=0;i--){ - for(int j=n-2;j>=0;j--){ - dp[i][j] = Math.max(1, Math.min(dp[i+1][j], dp[i][j+1])-dungeon[i][j]); - } - } - - - return dp[0][0]; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/DutchNationalFlag.java b/src/geeksforgeeks/DutchNationalFlag.java deleted file mode 100644 index 74c3d4f..0000000 --- a/src/geeksforgeeks/DutchNationalFlag.java +++ /dev/null @@ -1,31 +0,0 @@ -package geeksforgeeks; - -class DutchNationalFlag { - public void sortColors(int[] arr) { - if (arr.length == 0) { - return; - } - int pivot = 1; - int i = 0; - int j = arr.length - 1; - int zeroPos = 0; - while (i <= j) { - if (arr[i] > pivot) { - swap(arr, i, j); - j--; - } else if (arr[i] == pivot) { - i++; - } else { - swap(arr, zeroPos, i); - zeroPos++; - i++; - } - } - } - - public void swap(int[] arr, int i, int j) { - int temp = arr[j]; - arr[j] = arr[i]; - arr[i] = temp; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/EvaluvateRPN.java b/src/geeksforgeeks/EvaluvateRPN.java deleted file mode 100644 index a389307..0000000 --- a/src/geeksforgeeks/EvaluvateRPN.java +++ /dev/null @@ -1,47 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayDeque; -import java.util.Deque; - -// Input: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"] -// Output: 22 -// Explanation: -// ((10 * (6 / ((9 + 3) * -11))) + 17) + 5 -// = ((10 * (6 / (12 * -11))) + 17) + 5 -// = ((10 * (6 / -132)) + 17) + 5 -// = ((10 * 0) + 17) + 5 -// = (0 + 17) + 5 -// = 17 + 5 -// = 22 -public class EvaluvateRPN { - public int reversePolishNotation(String[] tokens) { - if(tokens==null && tokens.length==0) return 0; - Deque deque= new ArrayDeque<>(); - for(String i: tokens){ - if(i.length()==1 && "+*-/".contains(i)){ - Integer second= deque.removeFirst(); - Integer first= deque.removeFirst(); - //System.out.println(first +" - "+ second +" "+i); - switch(i){ - case "+": - deque.addFirst(first+second); - break; - case "-": - deque.addFirst(first-second); - break; - case "*": - deque.addFirst(first*second); - break; - case "/": - deque.addFirst(first/second); - break; - - } - }else{ - deque.addFirst(Integer.parseInt(i)); - } - } - - return deque.removeFirst(); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/FenwickTree.java b/src/geeksforgeeks/FenwickTree.java deleted file mode 100644 index 645385c..0000000 --- a/src/geeksforgeeks/FenwickTree.java +++ /dev/null @@ -1,112 +0,0 @@ -package geeksforgeeks; - -/** - * https://codeforces.com/blog/entry/61364 - * - * Fenwick trees are binary indexed trees, when asked for a range queries for an array - * ex [1,3,4,1,2] print the sum for range (0,4), (1,2) etc.. sum, difference, product, division can be asked - * one way is to pre-compute the prefix sums like [1,4,8,9,11] - * when asked for sum between 0 to 4 return 9 - * when asked sum between 2 to 4 we can return sum of (0,1) - (0,4) - * the retrival is O(1), but if the original array is updated we need to compute - * the prefix sum which will take O(N). - * Fenwick tree solves this by making both get and update as O(log n) - */ -public class FenwickTree{ - - // the array size is always incremented by 1, because the first entry is - // a dummy entry, the trees are arranges in set bits of each array's index - // we consider 4 pos of the bit representation - /** - * for array [1,-7,15,9,4,2,0,10] - * 0=> [0/0000] (index/ bit val of index) - * / | \ \ - * 1=> [1/0001] [2/0010] [4/0100] [8/1000] - * / / \ - * 2=> [3/0011] [5/0101] [6/0110] - * / - * 3=> [7/0111] - * - * so from the above tree we can infer that to get to a parent node, we need to - * remove the right most set bit - * [7/0111] => [6/0110]=> [4/0100]=> [0/0000] - * and the formula for that is parent = i - (i & -i); - * - * before populating fenwick tree with values, calculate the prefix sum for the array - * [1,-7,15,9,4,2,0,10]=> [1,-6,9,18,22,24,24,34] and update in it's posistion in fenwick tree - * - * [0/0000] - * / | \ \ - * [1/0001] [-6/0010] [18/0100] [34/1000] - * / / \ - * [9/0011] [22/0101] [24/0110] - * / - * [24/0111] - * the we need to subract each cell's value to it's immediate parent's value, then the tree would look like - * we can use the above formula parent = i - (i & -i); - * - * [0/0000] - * / | \ \ - * [1/0001] [-6/0010] [18/0100] [34/1000] - * / / \ - * [15/0011] [4/0101] [6/0110] - * / - * [0/0111] - * in array's representation it'd look like - * [0,1,-6,15,18,4,6,0,34] - */ - - int[] fen; int[] arr; - int n; - public void NumArray(int[] nums) { - arr = nums; - n = nums.length; - fen = new int[n+1]; - init(); - } - - public void init(){ - if(n == 0) return; - - fen[1] = arr[0]; - for(int i = 1; i < n; i++){ - fen[i+1] = fen[i] + arr[i]; - } - for(int i = n; i >0 ; i--){ - int parent = i - (i & -i); - if(parent >= 0) fen[i] -= fen[parent]; - } - //System.out.println(Arrays.toString(fen)); - } - - - - // for update we need to come from parent to children - // to get children do opposite of i-(i&-i) - public void update(int i, int val) { - int extra = val - arr[i]; - arr[i] = val; - increment(i, extra); - } - - public int sum(int i){ - int res = 0; - while(i > 0){ - res += fen[i]; - i = i - (i & -i); - } - return res; - } - public void increment(int i, int val){ - i++; - while(i <= n){ - fen[i] += val; - i = i + (i & -i); - } - } - //sum(1,4)=> sum(0,4)-(0,1) the sum function will calculate from 4->0(parent) - public int sumRange(int i, int j) { - return sum(j+1) - sum(i); - } - -} \ No newline at end of file diff --git a/src/geeksforgeeks/FindAllAnagram.java b/src/geeksforgeeks/FindAllAnagram.java deleted file mode 100644 index e71072b..0000000 --- a/src/geeksforgeeks/FindAllAnagram.java +++ /dev/null @@ -1,60 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. - * - * Strings consists of lowercase English letters only and the length of - * both strings s and p will not be larger than 20,100. - * - * The order of output does not matter. - * - * Input: - * s: "cbaebabacd" p: "abc" - * - * Output: - * [0, 6] - * - * Explanation: - * The substring with start index = 0 is "cba", which is an anagram of "abc". - * The substring with start index = 6 is "bac", which is an anagram of "abc". - */ -public class FindAllAnagram { - - public List findAnagrams(String s, String p) { - Map map = new HashMap<>(); - for(char ch: p.toCharArray()){ - map.put(ch, map.getOrDefault(ch,0)+1); - } - int counter= map.size(); - - int start=0; int end=0; - List result= new ArrayList<>(); - while(end0) counter++; - } - if(end-start==p.length()) { - result.add(start); - } - start++; - } - } - - return result; - } -} diff --git a/src/geeksforgeeks/FindMissingNumbers.java b/src/geeksforgeeks/FindMissingNumbers.java deleted file mode 100644 index f996fe8..0000000 --- a/src/geeksforgeeks/FindMissingNumbers.java +++ /dev/null @@ -1,44 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -// Input: [2, 3, 1, 8, 2, 3, 5, 1] -// Output: 4, 6, 7 -public class FindMissingNumbers { - - //Brute Force - // Set set = new HashSet<>(); - // for (int i = 0; i < nums.length; i++) set.add(i + 1); - // for (int i = 0; i < nums.length; i++) set.remove(nums[i]); - // return new ArrayList<>(set); - public List findDisappearedNumbers(int[] nums) { - if(nums.length==0) return Collections.emptyList(); - int i=0; - // cyclic sort begins - while(i result= new ArrayList<>(); - i=0; - while(i A.length) { - i++; - } else if (A[A[i] - 1] != A[i]) { - swap(A, i, A[i] - 1); - } else { - i++; - } - } - i = 0; - while (i < A.length && A[i] == i + 1) - i++; - return i + 1; - } - - private void swap(int[] A, int i, int j) { - int temp = A[i]; - A[i] = A[j]; - A[j] = temp; - } - - public int firstMissingPositiveWithExtraSpace(int[] nums) { - if (nums == null || nums.length == 0) { - return 1; - } - int length = nums.length; - int[] arr = new int[length + 1]; - for (int i = 0; i < length; i++) { - if (nums[i] <= length && nums[i] > 0) { - arr[--nums[i]] = -1; - } - } - - for (int i = 0; i < arr.length; i++) { - if (arr[i] != -1) { - return ++i; - } - } - return -1; - } - - public List findKMissingPositiveNumberOfSizeK(int[] A, int k){ - int i = 0; - while (i < A.length) { - // same cyclic sort, as missing numbers - if (A[i] == i + 1 || A[i] <= 0 || A[i] > A.length) { - i++; - } else if (A[A[i] - 1] != A[i]) { - swap(A, i, A[i] - 1); - } else { - i++; - } - } - - List missingNumber= new ArrayList<>(); - Set additionalNumber= new HashSet<>(); - - i=0; - while(i isSeen = new HashSet<>(); - DLList linkedList = new DLList(); - Map map = new HashMap<>(); - - public String solve(String A) { - StringBuilder sb = new StringBuilder(); - for (String s : A.split("")) { - sb.append(uniqueStream(s)); - } - return sb.toString(); - } - - public String uniqueStream(String A) { - Node node = new Node(A); - - if (isSeen.contains(A) && map.get(A) != null) { - Node temp = map.get(A); - linkedList.remove(temp); - map.put(A, null); - } else if (!isSeen.contains(A)) { - isSeen.add(A); - linkedList.add(node); - map.put(A, node); - } - - return linkedList.head.next.val; - } - - public String solveEfficient(String A) { - // we can use two pointer approach to solve this problem. - // First count the occurences of the characters in the stream in the charCounts array - int[] charCounts = new int[26]; - // Keep a start pointer at the start index which will denote the first non-repeating character, if any - int s = 0; - char[] charArr = A.toCharArray(); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < charArr.length; i++) { - // increment the count of the current character - charCounts[charArr[i] - 'a']++; - // move the start pointer ahead either till the current index - // or until we see another non-repeating character - while (s < i && charCounts[charArr[s] - 'a'] > 1) s++; - // If the character at start index is a non repeating character, add it the string otherwise add '#'' - if (charCounts[charArr[s] - 'a'] == 1) sb.append(charArr[s]); - else sb.append('#'); - } - - return sb.toString(); - } - - public static void main(String[] args) { - String[] vals= "jpxvxivxkkthvpqhhhjuzhkegnzqriokhsgea".split(""); - FirstNonRepeatingCharacterStream solution= new FirstNonRepeatingCharacterStream(); - for(String s:vals){ - System.out.println("ans:: "+solution.solve(s)); - } - } -} - - - - - - -class DLList { - Node head; - Node tail; - - public DLList() { - head = new Node("#"); - tail = new Node("#"); - head.next = tail; - tail.prev = head; - } - - public void add(Node node) { - Node prev = tail.prev; - prev.next = node; - node.prev = prev; - - node.next = tail; - tail.prev = node; - } - - public void remove(Node temp) { - Node next = temp.next; - temp.prev.next = next; - next.prev = temp.prev; - } -} - -class Node { - Node prev; - Node next; - String val; - - public Node(String val) { - this.val = val; - } -} diff --git a/src/geeksforgeeks/Flatten2DVector.java b/src/geeksforgeeks/Flatten2DVector.java deleted file mode 100644 index 984b9fe..0000000 --- a/src/geeksforgeeks/Flatten2DVector.java +++ /dev/null @@ -1,72 +0,0 @@ -package geeksforgeeks; - -import java.util.List; - -/* -Thoughts: -As hint indicates: use 2 pointers to hold position. -Use hasNext to validate (x,y) and move x. -Use next() to return (x,y) and move it(regardless of correctness, which is determined by hasNext()) - -Implement an iterator to flatten a 2d vector. - -For example, -Given 2d vector = - -[ - [1,2], - [3], - [4,5,6] -] -By calling next repeatedly until hasNext returns false, -the order of elements returned by next should be: [1,2,3,4,5,6]. - -Understand the problem: -The question itself is very easy to solve. Just several corner cases need to think of: - -- What if the 2d vector contains empty arrays, e.g. [ ], [ ], 1 2 3 ? In this case, the next() should not output anything, but the return type is int. There the hasNext() should be more complicated in which it handles this situation. - -- What if the 2d vector itself is empty? Again, handle it in hasNext() -*/ -public class Flatten2DVector { - private int x; - private int y; - private List> list; - - public Flatten2DVector(List> vec2d) { - if (vec2d == null) { - return; - } - this.x = 0; - this.y = 0; - this.list = vec2d; - } - - public int next() { - int rst = list.get(x).get(y); - // when y(column) reaches end increment row(x) and reset y - if (y + 1 >= list.get(x).size()) { - y = 0; - x++; - } else { - y++; - } - return rst; - } - - public boolean hasNext() { - if (list == null) { - return false; - } - // this condition is to check for empty rows - while (x < list.size() && list.get(x).isEmpty()) { - x++; - y = 0; - } - if (x >= list.size()) { - return false; - } - if (y >= list.get(x).size()) { - return false; - } - return true; - } -} diff --git a/src/geeksforgeeks/FlattenLinkedList.java b/src/geeksforgeeks/FlattenLinkedList.java deleted file mode 100644 index 9fbbcbe..0000000 --- a/src/geeksforgeeks/FlattenLinkedList.java +++ /dev/null @@ -1,145 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.techiedelight.com/flatten-linked-list/ - */ -class FlattenLinkedList { - Node head; - - class Node { - int data; - Node right, down; - - Node(int data) { - this.data = data; - right = null; - down = null; - } - - @Override - public String toString() { - return "" + this.data; - } - } - - Node mergeIterative(Node a, Node b) { - Node dummy = new Node(0); - Node result = dummy; - - while (a != null && b != null) { - if (a.data < b.data) { - result.down = a; - a = a.down; - } else { - result.down = b; - b = b.down; - } - result = result.down; - } - while (a != null) { - result.down = a; - result = result.down; - a = a.down; - } - - while (b != null) { - result.down = b; - result = result.down; - b = b.down; - } - return dummy.down; - } - - Node flatten(Node root) { - if (root == null || root.right == null) { - return root; - } - - root.right = flatten(root.right); - - root = mergeIterative(root, root.right); - - return root; - } - - public static void main(String args[]) { - flattenList(); - } - - protected static void flattenList() { - FlattenLinkedList L = new FlattenLinkedList(); - - /* Let us create the following linked list - 5 -> 10 -> 19 -> 28 - | | | | - V V V V - 7 20 22 35 - | | | - V V V - 8 50 40 - | | - V V - 30 45 - */ - - L.head = L.push(L.head, 30); - L.head = L.push(L.head, 8); - L.head = L.push(L.head, 7); - L.head = L.push(L.head, 5); - - L.head.right = L.push(L.head.right, 20); - L.head.right = L.push(L.head.right, 10); - - L.head.right.right = L.push(L.head.right.right, 50); - L.head.right.right = L.push(L.head.right.right, 22); - L.head.right.right = L.push(L.head.right.right, 19); - - L.head.right.right.right = L.push(L.head.right.right.right, 45); - L.head.right.right.right = L.push(L.head.right.right.right, 40); - L.head.right.right.right = L.push(L.head.right.right.right, 35); - - // flatten the list - L.head = L.flatten(L.head); - - L.printList(); - } - - Node push(Node head_ref, int data) { - Node new_node = new Node(data); - new_node.down = head_ref; - head_ref = new_node; - - return head_ref; - } - - void printList() { - Node temp = head; - while (temp != null) { - System.out.print(temp.data + " "); - temp = temp.down; - } - System.out.println(); - } - - Node merge(Node a, Node b) { - if (a == null) { - return b; - } - - if (b == null) { - return a; - } - - Node result; - - if (a.data < b.data) { - result = a; - result.down = merge(a.down, b); - } else { - result = b; - result.down = merge(a, b.down); - } - - return result; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/FlattenMultiLevelLinkedList.java b/src/geeksforgeeks/FlattenMultiLevelLinkedList.java deleted file mode 100644 index b040ff9..0000000 --- a/src/geeksforgeeks/FlattenMultiLevelLinkedList.java +++ /dev/null @@ -1,48 +0,0 @@ -package geeksforgeeks; - -/** - * https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list/discuss/150321/Easy-Understanding-Java-beat-95.7-with-Explanation -* */ -class FlattenMultiLevelLinkedList { - - public Node flatten(Node head) { - if (head == null) { - return head; - } - // Pointer - Node p = head; - while (p != null) { - if (p.child == null) { - p = p.next; - continue; - } - /* CASE 2: got child, find the tail of the child and link it to p.next */ - Node temp = p.child; - - while (temp.next != null) { - temp = temp.next; - } - // Connect tail with p.next, if it is not null - temp.next = p.next; - if (p.next != null) { - p.next.prev = temp; - } - // Connect p with p.child, and remove p.child - p.next = p.child; - p.child.prev = p; - p.child = null; - } - return head; - } - - static class Node { - long data; - Node next; - Node prev; - Node child; - - public Node(long id) { - this.data = id; - } - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/FlipMaximizeZeroesSubarrayKadane.java b/src/geeksforgeeks/FlipMaximizeZeroesSubarrayKadane.java deleted file mode 100644 index c030f69..0000000 --- a/src/geeksforgeeks/FlipMaximizeZeroesSubarrayKadane.java +++ /dev/null @@ -1,40 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/maximize-number-0s-flipping-subarray/ - * - * Problem : flip 1's to 0's so that total no.of 0's in array is maximized - */ -class FlipMaximizeZeroesSubarrayKadane { - - public static int findMaxZeroCount(int[] arr, int n) { - int zeroCount = 0; - int maxSoFar = Integer.MIN_VALUE; - int sum = 0; - - for (int i = 0; i < n; i++) { - - if (arr[i] == 0) { - zeroCount++; - } - - int val = (arr[i] == 1) ? 1 : -1; - - sum = sum + val; - - if (sum < 0) { - sum = 0; - } - maxSoFar = Math.max(maxSoFar, sum); - } - maxSoFar = Math.max(0, maxSoFar); - - return zeroCount + maxSoFar; - } - - public static void main(String[] args) { - int[] arr = { 0, 1, 0, 0, 1, 1, 0 }; - - System.out.println(findMaxZeroCount(arr, arr.length)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/FlipZeroesToFormConsecutiveMaximumOnes.java b/src/geeksforgeeks/FlipZeroesToFormConsecutiveMaximumOnes.java deleted file mode 100644 index ea7cde1..0000000 --- a/src/geeksforgeeks/FlipZeroesToFormConsecutiveMaximumOnes.java +++ /dev/null @@ -1,57 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/find-zeroes-to-be-flipped-so-that-number-of-consecutive-1s-is-maximized/ - - * https://www.techiedelight.com/find-maximum-sequence-of-continuous-1s-can-formed-replacing-k-zeroes-ones/ - */ -class FlipZeroesToFormConsecutiveMaximumOnes { - - public static void longestSeq(int[] A, int k) { - int left = 0; - int count = 0; - int window = 0; - - int leftIndex = 0; - - // 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0 - for (int right = 0; right < A.length; right++) { - // if current element is 0, increase count of zeros in the - // current window by 1 - if (A[right] == 0) { - count++; - } - - // window becomes unstable if number of zeros in it becomes - // more than - while (count > k) { - // if we have found zero, decrement number of zeros in the - // current window by 1 - if (A[left] == 0) { - count--; - } - left++; - } - - // when we reach here, the window [left..right] contains at-most - // k zeroes and we update max window size and leftmost index - // of the window - if (right - left + 1 > window) { - window = right - left + 1; - leftIndex = left; - } - } - - System.out.println( - "The longest sequence has length " + window + " from index " + leftIndex + " to " + (leftIndex + window - - 1)); - } - - // main function - public static void main(String[] args) { - int[] A = { 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0 }; - int k = 2; - - longestSeq(A, k); - } -} diff --git a/src/geeksforgeeks/FourSum.java b/src/geeksforgeeks/FourSum.java deleted file mode 100644 index 3be42b8..0000000 --- a/src/geeksforgeeks/FourSum.java +++ /dev/null @@ -1,64 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; -import java.util.Map; - -/** - * https://leetcode.com/problems/4sum-ii/ - * Given four lists A, B, C, D of integer values, - * compute how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero. - * To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. - * All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1. - * - * Input: - * A = [ 1, 2] - * B = [-2,-1] - * C = [-1, 2] - * D = [ 0, 2] - * - * Output: - * 2 - * - * Explanation: - * The two tuples are: - * 1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0 - * 2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0 - */ -public class FourSum { - - public int fourSumCount(int[] A, int[] B, int[] C, int[] D) { - Map sumMap = new HashMap<>(); - - for(int i=0; i map = new HashMap<>(); - for (char c : s.toCharArray()) - map.put(c, map.getOrDefault(c, 0) + 1); - - List[] bucket = new List[s.length() + 1]; - - for (char key : map.keySet()) { - int frequency = map.get(key); - if (bucket[frequency] == null) bucket[frequency] = new ArrayList<>(); - bucket[frequency].add(key); - } - - StringBuilder sb = new StringBuilder(); - // since this is max frequency we are iterating from last else we'd go from start - for (int pos = bucket.length - 1; pos >= 0; pos--) - if (bucket[pos] != null) - for (char c : bucket[pos]) - for (int i = 0; i < map.get(c); i++) - sb.append(c); - - return sb.toString(); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/GameOfLife.java b/src/geeksforgeeks/GameOfLife.java deleted file mode 100644 index 13118e2..0000000 --- a/src/geeksforgeeks/GameOfLife.java +++ /dev/null @@ -1,61 +0,0 @@ -package geeksforgeeks; - -/** - * https://forum.letstalkalgorithms.com/t/game-of-life/516/2 - *

- * https://leetcode.com/problems/game-of-life/ - * Given a board with m by n cells, each cell has an initial state live (1) or dead (0). - * Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules - * Any live cell with fewer than two live neighbors dies, as if caused by under-population. - * Any live cell with two or three live neighbors lives on to the next generation. - * Any live cell with more than three live neighbors dies, as if by over-population.. - * Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction. - * - * Input: - * [ - * [0,1,0], - * [0,0,1], - * [1,1,1], - * [0,0,0] - * ] - * Output: - * [ - * [0,0,0], - * [1,0,1], - * [0,1,1], - * [0,1,0] - * ] - */ -public class GameOfLife { - - public void gameOfLife(int[][] board) { - - int[][] dir ={{1,-1},{1,0},{1,1},{0,-1},{0,1},{-1,-1},{-1,0},{-1,1}}; - int row=board.length; - int col=board[0].length; - - for(int i=0; i=row || j1>=col || i1<0 || j1<0) continue; // border conditions - - if(board[i1][j1]==1 || board[i1][j1]==2) liveCells++; - } - - if(board[i][j]==0 && liveCells==3) board[i][j]=3; //Any dead cell with exactly three live neighbors becomes a live cell - - if(board[i][j]==1 && (liveCells<2 || liveCells>3)) board[i][j]=2; //live cell with fewer than two live neighbors dies || Any live cell with more than three live neighbors dies - } - } - - for(int i=0; i generateParenthesis(int n) { - List result = new ArrayList<>(); - if (n == 0) - return result; - // initially we send empty string and target number of pairs needed - generateUtil(n, new StringBuilder(), 0, 0, result); - - return result; - } - - public void generateUtil(int n, StringBuilder paran, int open, int close, List result) { - if (close == n) { // when close reaches n, we know n pairs have been created - result.add(paran.toString()); - return; - } - - if (close < open) { // when close is less than open we add a close and proceed - paran.append(")"); - generateUtil(n, paran, open, close + 1, result); - paran.deleteCharAt(paran.length() - 1); // backtracking to remove the last seen - } - if (open < n) { - paran.append("("); - generateUtil(n, paran, open + 1, close, result); - paran.deleteCharAt(paran.length() - 1); - - } - - } - -} \ No newline at end of file diff --git a/src/geeksforgeeks/GrammarMistake.java b/src/geeksforgeeks/GrammarMistake.java deleted file mode 100644 index 134fb1f..0000000 --- a/src/geeksforgeeks/GrammarMistake.java +++ /dev/null @@ -1,83 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/check-given-sentence-given-set-simple-grammer-rules/ - * A simple sentence if syntactically correct if it fulfills given rules. The following are given rules. - * - * 1. Sentence must start with a Uppercase character (e.g. Noun/ I/ We/ He etc.) - * 2. Then lowercase character follows. - * 3. There must be spaces between words. - * 4. Then the sentence must end with a full stop(.) after a word. - * 5. Two continuous spaces are not allowed. - * 6. Two continuous upper case characters are not allowed. - * 7. However, the sentence can end after an upper case character. - * - * - */ -import java.util.Arrays; -import java.util.List; - -class Main -{ - public static boolean validateSentence(char[] chars) - { - int index = 0; - if (Character.isLowerCase(chars[index])) { // 1st condition - return false; - } - - while (index < chars.length) - { - if (Character.isUpperCase(chars[index])) - { - if (Character.isUpperCase(chars[index + 1])) { // 5th condition - return false; - } - - if (index - 1 >= 0 && chars[index - 1] != ' ') { // 2nd condition - return false; - } - } - - if (chars[index] == ' ' && chars[index + 1] == ' ') { // 4th condition - return false; - } - - index++; - } - - if (chars[index - 2] == ' ' || chars[index - 1] != '.') { // 3th condition - return false; - } - - return true; - } - - public static void main(String[] args) - { - List list = Arrays.asList( - "This sentence is syntactically correct.", - - "This sentence is syntactically incorrect as two " + - "continuous spaces are not allowed.", - - "This sentence is syntactically correct Y.", - - "This sentence is syntactically incorRect as uppercase " + - "character is not allowed midway of the String.", - - "THis sentence is syntactically incorrect as lowercase " + - "character don't follow the first uppercase character.", - - "This sentence is syntactically incorrect as it doesn't " + - "end with a full stop" - ); - - System.out.println("Valid sentences are -"); - for (String sentence: list) { - if (validateSentence(sentence.toCharArray())) { - System.out.println(sentence); - } - } - } -} diff --git a/src/geeksforgeeks/GraphBiPartite.java b/src/geeksforgeeks/GraphBiPartite.java deleted file mode 100644 index bd29e8b..0000000 --- a/src/geeksforgeeks/GraphBiPartite.java +++ /dev/null @@ -1,52 +0,0 @@ -package geeksforgeeks; - -/** - * Recall that a graph is bipartite if we can split it's set of nodes into - * two independent subsets A and B such that every edge in the graph has one node in A and - * another node in B. - * Input: [[1,3], [0,2], [1,3], [0,2]] => 0th node connects to 1,3 .. -Output: true -Explanation: -The graph looks like this: -0----1 -| | -| | -3----2 -We can divide the vertices into two groups: {0, 2} and {1, 3}. -Input: [[1,2,3], [0,2], [0,1,3], [0,2]] -Output: false -Explanation: -The graph looks like this: -0----1 -| \ | -| \ | -3----2 -We cannot find a way to divide the set of nodes into two independent subsets. - */ -public class GraphBiPartite { - public boolean isBipartite(int[][] graph) { - int[] color= new int[graph.length]; - - for(int i=0;i - * https://github.com/UtkarshBehre/InterviewQuestionsPracticeInJava/blob/master/src/popularQuestionSet/GraphSplitwiseSimplify.java - */ -public class GraphSplitwiseSimplify { - - static class Graph { - int V; - LinkedList[] adjNodesList; - - static class AdjNode { - int adjVertices; - int debt; - - public AdjNode(int adjVertices, int debt) { - this.adjVertices = adjVertices; - this.debt = debt; - } - - @Override - public boolean equals(Object o) { - if (this.adjVertices == ((AdjNode) o).adjVertices) { - return true; - } else { - return false; - } - } - - public String toString() { - return adjVertices + "->" + debt; - } - } - - public Graph(int v) { - this.V = v; - adjNodesList = new LinkedList[V]; - for (int i = 0; i < V; i++) { - adjNodesList[i] = new LinkedList(); - } - } - - public void addEdge(int src, int dest, int debt) { - AdjNode adjNode = new AdjNode(dest, debt); - adjNodesList[src].add(adjNode); - } - - /** - * Runtime: O(VE) - */ - public void simplifyDebts() { - HashMap takers = new HashMap<>(); - HashMap givers = new HashMap<>(); - int[] debts = new int[V]; - for (int i = 0; i < V; i++) { - for (AdjNode adjNode : adjNodesList[i]) { - debts[i] -= adjNode.debt; - debts[adjNode.adjVertices] += adjNode.debt; - } - } - for (int i = 0; i < V; i++) { - if (debts[i] < 0) { - givers.put(i, Math.abs(debts[i])); - } else if (debts[i] > 0) { - takers.put(i, debts[i]); - } - } - - adjNodesList = new LinkedList[V]; - for (int i = 0; i < V; i++) { - adjNodesList[i] = new LinkedList<>(); - } - for (Entry giver : givers.entrySet()) { - int amountToGive = giver.getValue(); - for (Entry taker : takers.entrySet()) { - int amountToTake = taker.getValue(); - if (amountToTake > 0) { - if (amountToTake < amountToGive) { - taker.setValue(0); - amountToGive -= amountToTake; - addEdge(giver.getKey(), taker.getKey(), amountToTake); - } else { - taker.setValue(amountToTake - amountToGive); - addEdge(giver.getKey(), taker.getKey(), amountToGive); - break; - } - } - } - giver.setValue(amountToGive); - } - } - - public void printDebts() { - System.out.println("depts are: "); - for (int i = 0; i < V; i++) { - for (AdjNode adjNode : adjNodesList[i]) { - System.out.println(i + " owes " + adjNode.adjVertices + " " + adjNode.debt + " bucks."); - } - } - } - } - - public static void main(String[] args) { - Graph g = new Graph(3); - g.addEdge(0, 1, 1000); - g.addEdge(1, 2, 1000); - g.addEdge(0, 2, 2000); - g.printDebts(); - g.simplifyDebts(); - System.out.print("After simplification, "); - g.printDebts(); - - System.out.println("\nTest set 2"); - g = new Graph(5); - g.addEdge(0, 1, 1000); - g.addEdge(0, 2, 5000); - g.addEdge(1, 3, 2000); - g.addEdge(1, 4, 1500); - g.addEdge(2, 1, 3000); - g.addEdge(2, 3, 4000); - g.addEdge(3, 0, 500); - g.addEdge(4, 3, 500); - g.printDebts(); - g.simplifyDebts(); - System.out.print("After simplification, "); - g.printDebts(); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/GroupAnagrams.java b/src/geeksforgeeks/GroupAnagrams.java deleted file mode 100644 index a979cd4..0000000 --- a/src/geeksforgeeks/GroupAnagrams.java +++ /dev/null @@ -1,29 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -public class GroupAnagrams { - public List> groupAnagrams(String[] strs) { - List> result= new ArrayList<>(); - - if(strs==null || strs.length==0) return result; - Map> map= new HashMap<>(); - - for(String s: strs){ - // int[] cache= new int[26]; - // for(char ch: s.toCharArray()){ - // cache[ch-'a']++; - // } - // String hash=Arrays.toString(cache); - char[] te=s.toCharArray(); - Arrays.sort(te); - String hash=new String(te); - - List list= map.getOrDefault(hash, new LinkedList<>()); - list.add(s); - map.put(hash,list); - } - - return new ArrayList(map.values()); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/GroupIsomorphicString.java b/src/geeksforgeeks/GroupIsomorphicString.java deleted file mode 100644 index 278ee9c..0000000 --- a/src/geeksforgeeks/GroupIsomorphicString.java +++ /dev/null @@ -1,56 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -public class GroupIsomorphicString { - public Collection> groupIsomorphicStrings(List strings) { - if (strings == null || strings.isEmpty()) { - return Collections.EMPTY_LIST; - } - - Map> hashToList = new HashMap<>(); - - for (String string : strings) { - String hash = hash(string); - - if (!hashToList.containsKey(hash)) { - hashToList.put(hash, new ArrayList<>()); - } - - hashToList.get(hash).add(string); - } - return hashToList.values(); - } - // this method returns a hash value for every string passed in - // apple = 12234 - // apply = 12234 - // dog = 123 - // cog = 123 - // romi = 1234 - private String hash(String s) { - if (s.isEmpty()) { - return ""; - } - - int count = 1; - StringBuilder hash = new StringBuilder(); - - Map map = new HashMap<>(); - - for (char c : s.toCharArray()) { - - if (!map.containsKey(c)) { - map.put(c, count++); - } - hash.append(map.get(c)); - } - System.out.println(s +" = "+hash.toString() ); - return hash.toString(); - } - - public static void main(String[] args) { - Collection> result = new GroupIsomorphicString() - .groupIsomorphicStrings(Arrays.asList("apple", "apply", "dog", "cog", "romi")); - result.stream().forEach(System.out::println); - } -} diff --git a/src/geeksforgeeks/HappyNumber.java b/src/geeksforgeeks/HappyNumber.java deleted file mode 100644 index a251b8a..0000000 --- a/src/geeksforgeeks/HappyNumber.java +++ /dev/null @@ -1,57 +0,0 @@ -package geeksforgeeks; - -import java.util.HashSet; -import java.util.Set; - -/** - * https://leetcode.com/problems/happy-number/ - */ -class HappyNumber { - public boolean isHappy(int n) { - - Set visited = new HashSet<>(); - int sum = String.valueOf(n).chars().map(Character::getNumericValue).map(val -> val * val).sum() == 1 ? 1 : n; - while (true) { - if (sum == 1) { - return true; - } - sum = String.valueOf(sum).chars().map(Character::getNumericValue).map(val -> val * val).sum(); - if (visited.contains(sum)) { - return false; - } - - visited.add(sum); - } - } - - public int next(int n) - { - int res=0; - while (n>0) - { - int t = n % 10; - res += t*t; - n/=10; - } - return res; - } - - public boolean isHappyOpt(int n) - { - int i1=n, i2=next(n); - - while ( i2 != i1) - { - System.out.println("i1: "+ i1+" i2: "+ i2); - i1 = next(i1); - i2 = next(next(i2)); - } - - return i1==1; - } - - public static void main(String[] args) { - HappyNumber hn = new HappyNumber(); - System.out.println(hn.isHappyOpt(19)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/HitCounter.java b/src/geeksforgeeks/HitCounter.java deleted file mode 100644 index a8c7e26..0000000 --- a/src/geeksforgeeks/HitCounter.java +++ /dev/null @@ -1,31 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayDeque; - -public class HitCounter { - ArrayDeque trac; - /** Initialize your data structure here. */ - private final int FIVE_MINUTES = 300; - public HitCounter() { - trac = new ArrayDeque(); - } - - /** - * Record a hit. - @param timestamp - The current timestamp (in seconds granularity). - */ - public void hit(int timestamp) { - trac.addLast(timestamp); - } - - /** - * Return the number of hits in the past 5 minutes. - @param timestamp - The current timestamp (in seconds granularity). - */ - public int getHits(int timestamp) { - while(trac.size() > 0 && ( int) trac.getFirst() + FIVE_MINUTES <= timestamp) { - trac.removeFirst(); - } return trac.size(); - } - -} \ No newline at end of file diff --git a/src/geeksforgeeks/HouseRobber.java b/src/geeksforgeeks/HouseRobber.java deleted file mode 100644 index b860ad0..0000000 --- a/src/geeksforgeeks/HouseRobber.java +++ /dev/null @@ -1,46 +0,0 @@ -package geeksforgeeks; - -/** - * https://leetcode.com/problems/house-robber/ - */ -public class HouseRobber { - - public int rob(int[] nums) { - if (nums.length == 0) { - return 0; - } - int incl = nums[0]; - int excl = 0; - for (int i = 1; i < nums.length; i++) { - int temp = incl; - incl = Math.max(incl, excl + nums[i]); - excl = temp; - } - return incl; - } - - public int robCircular(int[] nums) { - - if(nums.length==0) return 0; - if(nums.length==1) return nums[0]; - return Math.max(helperFn(nums,0,nums.length-2), helperFn(nums,1,nums.length-1)); - - } - - public int helperFn(int[] nums, int start, int end){ - int pre=0; int cur=0; - for(int i=start;i<=end;i++){ - int temp=Math.max(pre+nums[i],cur); - pre=cur; - cur=temp; - - } - return cur; - } - - public static void main(String[] args) { - int[] arr = { 2, 7, 9, 3, 1 }; - HouseRobber houseRobber = new HouseRobber(); - System.out.println(houseRobber.rob(arr)); - } -} diff --git a/src/geeksforgeeks/IPOMaxProfit.java b/src/geeksforgeeks/IPOMaxProfit.java deleted file mode 100644 index 5338d09..0000000 --- a/src/geeksforgeeks/IPOMaxProfit.java +++ /dev/null @@ -1,46 +0,0 @@ -package geeksforgeeks; - - - -import java.util.PriorityQueue; -//https://leetcode.com/problems/ipo/ - -// Input: distinctProjToFind=2, capital=0, Profits=[1,2,3], Capital=[0,1,1]. -// Output: 4 - -// Explanation: Since your initial capital is 0, you can only start the project indexed 0. -// After finishing it you will obtain profit 1 and your capital becomes 1. -// With capital 1, you can either start the project indexed 1 or the project indexed 2. -// Since you can choose at most 2 projects, you need to finish the project indexed 2 to get the maximum capital. -// Therefore, output the final maximized capital, which is 0 + 1 + 3 = 4. -public class IPOMaxProfit { - - // Create (capital, profit) pairs and put them into PriorityQueue pqCap. - // This PriorityQueue sort by capital increasingly. - // Keep polling pairs from pqCap until the project out of current capital capability. Put them into - // PriorityQueue pqPro which sort by profit decreasingly. - // Poll one from pqPro, it's guaranteed to be the project with max profit and within current capital capability. - //Add the profit to capital W. - //Repeat step 2 and 3 till finish k steps or no suitable project (pqPro.isEmpty()). - public int findMaximizedCapital(int steps, int initialCapital, int[] Profits, int[] Capital) { - - PriorityQueue minQueue= new PriorityQueue<>((a, b)->Integer.compare(a[0],b[0])); - PriorityQueue maxQueue= new PriorityQueue<>((a,b)->Integer.compare(b[1],a[1])); - - for(int i=0;i dirs = new HashMap < > (); - HashMap < String, String > files = new HashMap < > (); - } - Dir root; - public InMemeoryFIleSystem() { - root = new Dir(); - } - public List < String > ls(String path) { - Dir t = root; - List < String > files = new ArrayList < > (); - if (!path.equals("/")) { - String[] d = path.split("/"); - for (int i = 1; i < d.length - 1; i++) { - t = t.dirs.get(d[i]); - } - if (t.files.containsKey(d[d.length - 1])) { - files.add(d[d.length - 1]); - return files; - } else { - t = t.dirs.get(d[d.length - 1]); - } - } - files.addAll(new ArrayList < > (t.dirs.keySet())); - files.addAll(new ArrayList < > (t.files.keySet())); - Collections.sort(files); - return files; - } - - public void mkdir(String path) { - Dir t = root; - String[] d = path.split("/"); - for (int i = 1; i < d.length; i++) { - if (!t.dirs.containsKey(d[i])) - t.dirs.put(d[i], new Dir()); - t = t.dirs.get(d[i]); - } - } - - public void addContentToFile(String filePath, String content) { - Dir t = root; - String[] d = filePath.split("/"); - for (int i = 1; i < d.length - 1; i++) { - t = t.dirs.get(d[i]); - } - t.files.put(d[d.length - 1], t.files.getOrDefault(d[d.length - 1], "") + content); - } - - public String readContentFromFile(String filePath) { - Dir t = root; - String[] d = filePath.split("/"); - for (int i = 1; i < d.length - 1; i++) { - t = t.dirs.get(d[i]); - } - return t.files.get(d[d.length - 1]); - } -} - -class FileSystem1 { - class File { - boolean isfile = false; - HashMap < String, File > files = new HashMap < > (); - String content = ""; - } - File root; - public void FileSystem() { - root = new File(); - } - - public List < String > ls(String path) { - File t = root; - List< String > files = new ArrayList< >(); - if (!path.equals("/")) { - String[] d = path.split("/"); - for (int i = 1; i < d.length; i++) { - t = t.files.get(d[i]); - } - if (t.isfile) { - files.add(d[d.length - 1]); - return files; - } - } - List < String > res_files = new ArrayList < > (t.files.keySet()); - Collections.sort(res_files); - return res_files; - } - - public void mkdir(String path) { - File t = root; - String[] d = path.split("/"); - for (int i = 1; i < d.length; i++) { - if (!t.files.containsKey(d[i])) - t.files.put(d[i], new File()); - t = t.files.get(d[i]); - } - } - - public void addContentToFile(String filePath, String content) { - File t = root; - String[] d = filePath.split("/"); - for (int i = 1; i < d.length - 1; i++) { - t = t.files.get(d[i]); - } - if (!t.files.containsKey(d[d.length - 1])) - t.files.put(d[d.length - 1], new File()); - t = t.files.get(d[d.length - 1]); - t.isfile = true; - t.content = t.content + content; - } - - public String readContentFromFile(String filePath) { - File t = root; - String[] d = filePath.split("/"); - for (int i = 1; i < d.length - 1; i++) { - t = t.files.get(d[i]); - } - return t.files.get(d[d.length - 1]).content; - } -} - -/** - * Your FileSystem object will be instantiated and called as such: - * FileSystem obj = new FileSystem(); - * List param_1 = obj.ls(path); - * obj.mkdir(path); - * obj.addContentToFile(filePath,content); - * String param_4 = obj.readContentFromFile(filePath); - */ \ No newline at end of file diff --git a/src/geeksforgeeks/InOrderSuccessor.java b/src/geeksforgeeks/InOrderSuccessor.java deleted file mode 100644 index 2216ac2..0000000 --- a/src/geeksforgeeks/InOrderSuccessor.java +++ /dev/null @@ -1,28 +0,0 @@ -package geeksforgeeks; -public class InOrderSuccessor { - /* - * @param root: The root of the BST. - * @param p: You need find the successor node of p. - * @return: Successor of p. - */ - TreeNode result=null; - public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { - helperFn(root,p); - return result; - } - // Inorder traversal is obtained by going right first and follow the left path till end - // while traversing right we record the right before taking left turn, in case the left path is null - - public void helperFn(TreeNode root, TreeNode p){ - if(root==null) return; - - if(root.val>p.val){ - - result=root; - helperFn(root.left,p); - }else{ - helperFn(root.right,p); - } - - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/InorderSuccessorPredecessor.java b/src/geeksforgeeks/InorderSuccessorPredecessor.java deleted file mode 100644 index 7e33f3a..0000000 --- a/src/geeksforgeeks/InorderSuccessorPredecessor.java +++ /dev/null @@ -1,105 +0,0 @@ -package geeksforgeeks; - -/** - * https://algorithms.tutorialhorizon.com/inorder-predecessor-and-successor-in-binary-search-tree/ - */ -public class InorderSuccessorPredecessor { - static int successor, predecessor; - - public void successorPredecessor(TNode root, int val) { - if (root == null) return; - - if (root.data > val) { - // we make the root as successor because we might have a - // situation when value matches with the root, it wont have - // right subtree to find the successor, in that case we need - // parent to be the successor - successor = root.data; - successorPredecessor(root.left, val); - } else if (root.data < val) { - // we make the root as predecessor because we might have a - // situation when value matches with the root, it wont have - // left subtree to find the predecessor, in that case we need - // parent to be the predecessor. - predecessor = root.data; - successorPredecessor(root.right, val); - } - } - - public static void main(String args[]) { - TNode root = new TNode(25); - root.left = new TNode(15); - root.right = new TNode(40); - root.left.left = new TNode(10); - root.left.left.left = new TNode(5); - root.left.right = new TNode(18); - root.right.left = new TNode(35); - root.right.right = new TNode(45); - root.left.right.left = new TNode(19); - root.left.right.right = new TNode(20); - InorderSuccessorPredecessor i = new InorderSuccessorPredecessor(); - - i.successorPredecessor(root, 20); - - System.out.println("Inorder Successor of 20 is : " + successor + " and predecessor is : " + predecessor); - - } - - TreeNode result=null; - public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { - helperFn(root,p); - return result; - } - - public void helperFn(TreeNode root, TreeNode p){ - if(root==null) return; - - if(root.val>p.val){ - result=root; - helperFn(root.left,p); - }else{ - helperFn(root.right,p); - } - - } - private TreeNode findPredecessor(TreeNode root, TreeNode node) { - TreeNode pre = null; - TreeNode cur = root; - while (cur != null) { - if (cur.val < node.val) { - pre = cur; - cur = cur.right; - } else { - cur = cur.left; - } - } - return pre; - } - private TreeNode findSuccessor(TreeNode root, TreeNode node) { - TreeNode succ = null; - TreeNode cur = root; - while (cur != null) { - if (cur.val > node.val) { - succ = cur; - cur = cur.left; - } else { - cur = cur.right; - } - } - return succ; - } -} - - - - class TNode { - int data; - TNode left; - TNode right; - - public TNode(int data) { - this.data = data; - left = null; - right = null; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/InsertIntervals.java b/src/geeksforgeeks/InsertIntervals.java deleted file mode 100644 index f419cc2..0000000 --- a/src/geeksforgeeks/InsertIntervals.java +++ /dev/null @@ -1,36 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.List; - -/** - * Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). - - You may assume that the intervals were initially sorted according to their start times. - Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] - Output: [[1,2],[3,10],[12,16]] - Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10]. - */ -public class InsertIntervals{ - public int[][] insert(int[][] intervals, int[] newInterval) { - List result= new ArrayList<>(); - int i=0; int n= intervals.length; - - while(i - * Insertion sort iterates, - * consuming one input element each repetition, and growing a sorted output list. - * At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. - * It repeats until no input elements remain. - */ -public class InsertionSortList { - public ListNode insertionSortList(ListNode head) { - if (head == null) { - return head; - } - - ListNode helper = new ListNode(0); //new starter of the sorted list - ListNode cur = head; //the node will be inserted - ListNode pre = helper; //insert node between pre and pre.next - ListNode next; //the next node will be inserted - //not the end of input list - while (cur != null) { - next = cur.next; - //find the right place to insert - while (pre.next != null && pre.next.val < cur.val) { - pre = pre.next; - } - //insert between pre and pre.next - cur.next = pre.next; - pre.next = cur; - pre = helper; - cur = next; - } - - return helper.next; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/IntegerToBinary.java b/src/geeksforgeeks/IntegerToBinary.java deleted file mode 100644 index c16ffc3..0000000 --- a/src/geeksforgeeks/IntegerToBinary.java +++ /dev/null @@ -1,38 +0,0 @@ -package geeksforgeeks; - -class IntegerToBinary { - // function to convert decimal to binary - static void decToBinary(int n) { - // array to store binary number - int[] binaryNum = new int[1000]; - - // counter for binary array - int i = 0; - while (n > 0) { - // storing remainder in binary array - binaryNum[i] = n % 2; - n = n / 2; - i++; - } - - // printing binary array in reverse order - for (int j = i - 1; j >= 0; j--) - System.out.print(binaryNum[j]); - } - - public static void main(String[] args) { - int n = 4; - // decToBinary(n); - // System.out.println("Default method :" + Integer.toBinaryString(4)); - System.out.println(intToBinary(4)); - } - - public static String intToBinary(int n) { - String s = ""; - while (n > 0) { - s = ((n % 2) == 0 ? "0" : "1") + s; - n = n / 2; - } - return s; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/IntersectionOfArrays.java b/src/geeksforgeeks/IntersectionOfArrays.java deleted file mode 100644 index f104dd9..0000000 --- a/src/geeksforgeeks/IntersectionOfArrays.java +++ /dev/null @@ -1,79 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; - -/** - * https://leetcode.com/problems/intersection-of-two-arrays-ii/discuss/82241/AC-solution-using-Java-HashMap - *

- * Example 1: - *

- * Input: nums1 = [1,2,2,1], nums2 = [2,2] - * Output: [2,2] - * Example 2: - *

- * Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] - * Output: [4,9] - */ -public class IntersectionOfArrays { - public static void main(String[] args) { - IntersectionOfArrays intersectionOfArrays = new IntersectionOfArrays(); - int[] nums1 = { 4, 4, 9, 5 }; - int[] nums2 = { 9, 4, 9, 4, 2, 3 }; - System.out.println(Arrays.toString(intersectionOfArrays.intersect(nums1, nums2))); - } - - public int[] intersect(int[] nums1, int[] nums2) { - //The first question is relatively easy, create a hashmap base on number frequency of nums1(whichever one is longer). - - // Then for every element of nums2, look upon the hashmap. If we found an intersection, deduct by 1 to avoid duplicate. - HashMap map = new HashMap<>(); - ArrayList result = new ArrayList<>(); - for (int i = 0; i < nums1.length; i++) { - map.put(nums1[i], map.getOrDefault(nums1[i], 1)); - } - - for (int i = 0; i < nums2.length; i++) { - if (map.containsKey(nums2[i]) && map.get(nums2[i]) > 0) { - result.add(nums2[i]); - map.put(nums2[i], map.get(nums2[i]) - 1); - } - } - - int[] r = new int[result.size()]; - for (int i = 0; i < result.size(); i++) { - r[i] = result.get(i); - } - - return r; - } - - //What if the given array is already sorted? How would you optimize your algorithm? - // Classic two pointer iteration, i points to nums1 and j points to nums2. - // Because a sorted array is in ascending order, so if nums1[i] > nums[j], we need to increment j, and vice versa. - // Only when nums1[i] == nums[j], we add it to the result array. Time Complexity O(max(N, M)) - public int[] intersectSorted(int[] nums1, int[] nums2) { - Arrays.sort(nums1); - Arrays.sort(nums2); - int n = nums1.length, m = nums2.length; - int i = 0, j = 0; - List list = new ArrayList<>(); - while(i < n && j < m){ - int a = nums1[i], b= nums2[j]; - if(a == b){ - list.add(a); - i++; - j++; - }else if(a < b){ - i++; - }else{ - j++; - } - } - int[] ret = new int[list.size()]; - for(int k = 0; k < list.size();k++) ret[k] = list.get(k); - return ret; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/IsEditOneDistanceAway.java b/src/geeksforgeeks/IsEditOneDistanceAway.java deleted file mode 100644 index d8791f5..0000000 --- a/src/geeksforgeeks/IsEditOneDistanceAway.java +++ /dev/null @@ -1,63 +0,0 @@ -package geeksforgeeks; - -/** - * Given two strings first and second, determine if they are both one edit distance apart. - * One edit distance means doing one of these operation: - * - * insert one character in any position of S - * delete one character in S - * change one character in S to other character - * - * Input: s = "ab", t = "ab" - * Output: false - * Explanation: - * s=t ,so they aren't one edit distance apart - * - * Input: s = "aDb", t = "adb" - * Output: true - */ -public class IsEditOneDistanceAway { - static boolean isOneEdit(String first, String second) { - // if the input string are same - if (first.equals(second)) - return false; - - int len1 = first.length(); - int len2 = second.length(); - // If the length difference of the stings is more than 1, return false. - if ((len1 - len2) > 1 || (len2 - len1) > 1) { - return false; - } - int i = 0, j = 0; - int diff = 0; - while (i < len1 && j < len2) { - char f = first.charAt(i); - char s = second.charAt(j); - if (f != s) { - diff++; - // delete a character - if (len1 > len2) - i++; - // add a character - if (len2 > len1) - j++; - // replace a character - if (len1 == len2) - i++; - j++; - } else { - i++; - j++; - } - if (diff > 1) { - return false; - } - } - // If the length of the string is not same. ex. "abc" and "abde" are not one - // edit distance. - if (diff == 1 && len1 != len2 && (i != len1 || j != len2)) { - return false; - } - return true; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/IsSubsequence.java b/src/geeksforgeeks/IsSubsequence.java deleted file mode 100644 index 53df8e0..0000000 --- a/src/geeksforgeeks/IsSubsequence.java +++ /dev/null @@ -1,22 +0,0 @@ -package geeksforgeeks; - -public class IsSubsequence { - // Input: s = "abc", t = "ahbgdc" - // Output: true - // Input: s = "axc", t = "ahbgdc" - // Output: false - public boolean isSubsequence(String s, String t) { - if(s==null || t==null) return false; - int i=0; int j=0; - - while(i queue = new ArrayDeque<>(); - queue.offer(root); - while (!queue.isEmpty()) { - Pair temp = queue.poll(); - for (int[] dir : directions) { - - int x = temp.x + dir[0]; - int y = temp.y + dir[1]; - if (isvalid(grid, x, y)) { - grid[x][y] = '0'; - queue.offer(new Pair(x, y)); - } - } - } - } - - public boolean isvalid(char[][] grid, int x, int y) { - if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] == '0') { - return false; - } - return true; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/Islands.java b/src/geeksforgeeks/Islands.java deleted file mode 100644 index 49a8bad..0000000 --- a/src/geeksforgeeks/Islands.java +++ /dev/null @@ -1,44 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/find-number-of-islands/ - */ -class Islands { - - private int n; - private int m; - - public int numIslands(int[][] grid) { - int count = 0; - n = grid.length; - if (n == 0) { - return 0; - } - m = grid[0].length; - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) - if (grid[i][j] == 1) { - DFSMarking(grid, i, j); - ++count; - } - } - return count; - } - - private void DFSMarking(int[][] grid, int i, int j) { - if (i < 0 || j < 0 || i >= n || j >= m || grid[i][j] != 1) { - return; - } - grid[i][j] = 0; - DFSMarking(grid, i + 1, j); - DFSMarking(grid, i - 1, j); - DFSMarking(grid, i, j + 1); - DFSMarking(grid, i, j - 1); - } - - public static void main(String[] args) { - int M[][] = new int[][] { { 1, 1, 1, 1, 0 }, { 1, 1, 0, 1, 0 }, { 1, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0 } }; - Islands I = new Islands(); - System.out.println("Number of islands is: " + I.numIslands(M)); - } -} diff --git a/src/geeksforgeeks/IsomorphicString.java b/src/geeksforgeeks/IsomorphicString.java deleted file mode 100644 index f212aa5..0000000 --- a/src/geeksforgeeks/IsomorphicString.java +++ /dev/null @@ -1,31 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; - -/** - * https://www.geeksforgeeks.org/check-if-two-given-strings-are-isomorphic-to-each-other/ - */ -class IsomorphicString { - static boolean isIsomorphic(String s, String t) { - char[] m1 = new char[256]; - char[] m2 = new char[256]; - int n = s.length(); - for (int i = 0; i < n; ++i) { - // it checks the count of the character in the array ; - // for 'g' -> a[103] is 2 and 'd' -> a[100] is 2 - // if both are same both gets incremented together else return false - if (m1[s.charAt(i)] != m2[t.charAt(i)]) { - return false; - } - m1[s.charAt(i)] = (char) (i + 1); - m2[t.charAt(i)] = (char) (i + 1); - } - System.out.println(Arrays.toString(m1)); - System.out.println(Arrays.toString(m2)); - return true; - } - - public static void main(String[] args) { - System.out.println(isIsomorphic("egg", "add")); - } -}; \ No newline at end of file diff --git a/src/geeksforgeeks/JumpsToReachEnd.java b/src/geeksforgeeks/JumpsToReachEnd.java deleted file mode 100644 index e4157b1..0000000 --- a/src/geeksforgeeks/JumpsToReachEnd.java +++ /dev/null @@ -1,96 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -public class JumpsToReachEnd { - - /** - * Given an array of non-negative integers nums, - * you are initially positioned at the first index of the array. - * Each element in the array represents your maximum jump length at that position. - * - * Determine if you are able to reach the last index - * Input: nums = [2,3,1,1,4] - * Output: true - * Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index. - * - * Input: nums = [3,2,1,0,4] - * Output: false - * Explanation: You will always arrive at index 3 no matter what. - * Its maximum jump length is 0, which makes it impossible to reach the last index. - */ - public static boolean canReachEnd(Integer[] nums) { - - int curMax = nums[0]; - for (int i = 1; i < nums.length; i++) { - if (curMax < i) return false; //means we are not able to reach position i - curMax = Math.max(curMax, i + nums[i]); - } - return true; - } - - - /** - *Given an array of non-negative integers arr, - * you are initially positioned at start index of the array. - * When you are at index i, you can jump to i + arr[i] or i - arr[i], - * check if you can reach to any index with value 0. - * Notice that you can not jump outside of the array at any time. - * - * Input: arr = [4,2,3,0,3,1,2], start = 5 - * Output: true - * Explanation: - * All possible ways to reach at index 3 with value 0 are: - * index 5 -> index 4 -> index 1 -> index 3 - * index 5 -> index 6 -> index 4 -> index 1 -> index 3 - * - * Input: arr = [4,2,3,0,3,1,2], start = 0 - * Output: true - * Explanation: - * One possible way to reach at index 3 with value 0 is: - * index 0 -> index 4 -> index 1 -> index 3 - */ - public boolean canReach(int[] arr, int start) { - // visited check included - if(start>=arr.length || start<0 || arr[start]>arr.length || arr[start]<0) return false; - if(arr[start]==0 ) return true; - arr[start]=-arr[start]; // visited marking - return canReach(arr, start+arr[start]) || canReach(arr, start-arr[start]); - - } - - - public int minJump(int[] nums) { - if(nums==null || nums.length==0) return 0; - int currentMax=0; - int currentEnd=0; - int jumps=0; - - for(int i=0;i=nums.length-1){ // if the current pick solves the issue - jumps++; - break; - } - //Once the current point reaches curEnd, - //then trigger another jump, and set the new curEnd with curFarthest, - //then keep the above steps, as the following - - //This is an implicit bfs solution. i == curEnd means you visited all the items on the current level. - // Incrementing jumps++ is like incrementing the level you are on. - // And curEnd = curFarthest is like getting the queue size (level size) for the next level you are traversing. - if(currentEnd==i){ // when the current pick of ladder reached last step - jumps++; - currentEnd=currentMax; - } - } - return jumps; - } - - public static void main(String[] args) { - - List list= Arrays.asList(3,3,1,0, 2,0,1); - System.out.println(canReachEnd(list.toArray(new Integer[list.size()]))); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/KClosestElements.java b/src/geeksforgeeks/KClosestElements.java deleted file mode 100644 index 6ea0cd5..0000000 --- a/src/geeksforgeeks/KClosestElements.java +++ /dev/null @@ -1,66 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.PriorityQueue; - -/** - * Given a sorted array arr, two integers k and x, find the k closest elements to x in the array. - * Input: arr = [1,2,3,4,5], k = 4, x = 3 -Output: [1,2,3,4] - */ -public class KClosestElements { - public List findClosestElements(int[] arr, int k, int x) { - // since this is sorted array we are making use of binary search to get index of X and - // fix the range between index-K to index+K and doing normal PQ solution - int index= binarySearch(arr,x); - //if(index==-1) return Collections.emptyList(); - - int low= Math.max(0,index-k); - int high= Math.min(index+k,arr.length-1); - - PriorityQueue queue= new PriorityQueue<>((a, b)->Integer.compare(a.key,b.key)); - - for(int i=low;i<=high;i++){ - // taking abs value because question is askin closest in both signs - queue.offer(new Entry(Math.abs(arr[i]-x),i)); - } - List result= new ArrayList<>(); - int i=0; - while(i0){ - start--; - } - return start; - } -} - -class Entry{ - int key; - int value; - public Entry(int key, int value){ - this.key=key; - this.value=value; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/KmostFrequentLetters.java b/src/geeksforgeeks/KmostFrequentLetters.java deleted file mode 100644 index 19919bd..0000000 --- a/src/geeksforgeeks/KmostFrequentLetters.java +++ /dev/null @@ -1,50 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -/** - * Given a list of reviews, a list of keywords and an integer k. - * Find the most popular k keywords in order of most to least frequently mentioned. - * The comparison of strings is case-insensitive. - * Multiple occurrences of a keyword in a review should be considered as a single mention. - * If keywords are mentioned an equal number of times in reviews, sort alphabetically. - */ -public class KmostFrequentLetters { - public static void main(String[] args) { - int k1 = 2; - String[] keywords1 = {"anacell", "cetracular", "betacellular"}; - String[] reviews1 = {"Anacell provides the best services in the city", "betacellular has awesome services", - "Best services provided by anacell, everyone should use anacell",}; - int k2 = 2; - String[] keywords2 = {"anacell", "betacellular", "cetracular", "deltacellular", "eurocell"}; - String[] reviews2 = {"I love anacell Best services; Best services provided by anacell", - "betacellular has great services", "deltacellular provides much better services than betacellular", - "cetracular is worse than anacell", "Betacellular is better than deltacellular.",}; - //System.out.println(solve(k1, keywords1, reviews1)); - System.out.println(solve(k2, keywords2, reviews2)); - } - - private static List solve(int k, String[] keywords, String[] reviews) { - List res = new ArrayList<>(); - Set set = new HashSet<>(Arrays.asList(keywords)); - Map map = new HashMap<>(); - for (String r : reviews) { - String[] strs = r.split("\\W"); - Set added = new HashSet<>(); // creating a set per review to avoid duplicate within a review - for (String s : strs) { - s = s.toLowerCase(); - if (set.contains(s) && !added.contains(s)) { - map.put(s, map.getOrDefault(s, 0) + 1); - added.add(s); - } - } - } - PriorityQueue> maxHeap = new PriorityQueue<>((a, b) -> a.getValue() == b.getValue() ? a.getKey().compareTo(b.getKey()) : b.getValue() - a.getValue()); - maxHeap.addAll(map.entrySet()); - map.entrySet().forEach(e-> System.out.println(e.getKey() +" "+e.getValue())); - while (!maxHeap.isEmpty() && k-- > 0) { - res.add(maxHeap.poll().getKey()); - } - return res; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/KthClosestOrigin.java b/src/geeksforgeeks/KthClosestOrigin.java deleted file mode 100644 index 52c234a..0000000 --- a/src/geeksforgeeks/KthClosestOrigin.java +++ /dev/null @@ -1,74 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; -import java.util.Random; - -/** - * https://leetcode.com/problems/k-closest-points-to-origin/solution/ - */ -class KthClosestOrigin { - int[][] points = new int[3][2]; - - // quick select - public int[][] kClosest(int[][] points, int K) { - this.points= points; - sort(0, points.length - 1, K); - return Arrays.copyOfRange(points, 0, K); - } - - public void sort(int i, int j, int K) { - if (i >= j) { - return; - } - int k = new Random().nextInt(j - i + 1) + i; - swap(i, k); - - int mid = partition(i, j); - int leftLength = mid - i + 1; - if (K < leftLength) { - sort(i, mid - 1, K); - } else if (K > leftLength) { - sort(mid + 1, j, K - leftLength); - } - } - - public int partition(int i, int j) { - int pivot = dist(i); - swap(i, j); - int iLow = i; - for (int i1 = i; i1 < j; i1++) { - if (dist(i1) <= pivot) { - swap(i1, iLow); - iLow++; - } - } - swap(iLow, j); - return iLow; - } - - public int dist(int i) { - return points[i][0] * points[i][0] + points[i][1] * points[i][1]; - } - - public void swap(int i, int j) { - int t0 = points[i][0], t1 = points[i][1]; - points[i][0] = points[j][0]; - points[i][1] = points[j][1]; - points[j][0] = t0; - points[j][1] = t1; - } - public static void main(String[] args) { -// KthClosestOrigin kth = new KthClosestOrigin(); -// points[0][0] = 3; -// points[0][1] = 3; -// -// points[1][0] = 5; -// points[1][1] = -1; -// -// points[2][0] = 2; -// points[2][1] = 4; -// -// // System.out.println(Arrays.deepToString(kth.kClosestOLogN(points, 1))); -// System.out.println(Arrays.deepToString(kth.kClosest(points, 2))); - } -} diff --git a/src/geeksforgeeks/KthSmallestFromTwoSortedArrays.java b/src/geeksforgeeks/KthSmallestFromTwoSortedArrays.java deleted file mode 100644 index d62166f..0000000 --- a/src/geeksforgeeks/KthSmallestFromTwoSortedArrays.java +++ /dev/null @@ -1,43 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/k-th-element-two-sorted-arrays/ - */ -class KthSmallestFromTwoSortedArrays { - - public static int findKth(int[] A, int i, int[] B, int j, int k) { - - if ((A.length - i) > (B.length - j)) { - return findKth(B, j, A, i, k); - } - - if (i >= A.length) { - return B[j + k - 1]; - } - if (k == 1) { - return Math.min(A[i], B[j]); - } - - int aMid = Math.min(k / 2, A.length - i); - int bMid = k - aMid; - - if (A[i + aMid - 1] <= B[j + bMid - 1]) { - return findKth(A, i + aMid, B, j, k - aMid); - } - - return findKth(A, i, B, j + bMid, k - bMid); - } - - public static void main(String[] args) { - int arr1[] = { 1, 6, 8, 9, 15 }; - int arr2[] = { 3, 5, 10, 14, 20 }; - - int k = 6; - int ans = findKth(arr1, 0, arr2, 0, k); - if (ans == -1) { - System.out.println("Invalid query"); - } else { - System.out.println(ans); - } - } -} diff --git a/src/geeksforgeeks/KthSmallestMatrix.java b/src/geeksforgeeks/KthSmallestMatrix.java deleted file mode 100644 index 29bebcb..0000000 --- a/src/geeksforgeeks/KthSmallestMatrix.java +++ /dev/null @@ -1,51 +0,0 @@ -package geeksforgeeks; - -import java.util.PriorityQueue; - -/*https://www.geeksforgeeks.org/kth-smallest-element-in-a-row-wise-and-column-wise-sorted-2d-array-set-1/*/ -public class KthSmallestMatrix { - public static int kthSmallest(int[][] matrix, int k) { - int n = matrix.length; - PriorityQueue pq = new PriorityQueue<>(); - // add first row elements - for (int j = 0; j <= n - 1; j++) - pq.offer(new Points(0, j, matrix[0][j])); - for (int i = 0; i < k - 1; i++) { - Points t = pq.poll(); - System.out.println(t.x); - if (t.x == n - 1) { - continue; - } - pq.offer(new Points(t.x + 1, t.y, matrix[t.x + 1][t.y])); - } - return pq.poll().val; - } - - public static void main(String[] args) { - int[][] matrix = { { 1, 2, 9 }, { 3, 11, 13 }, { 4, 13, 15 } }; - int k = 4; - - System.out.println(kthSmallest(matrix, k)); - } -} - -class Points implements Comparable { - int x; - int y; - int val; - - public Points(int x, int y, int val) { - this.x = x; - this.y = y; - this.val = val; - } - - @Override - public int compareTo(Points that) { - return this.val - that.val; - } - - public String toString() { - return this.val + ""; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/LIS2DMatrix.java b/src/geeksforgeeks/LIS2DMatrix.java deleted file mode 100644 index 5ea3e62..0000000 --- a/src/geeksforgeeks/LIS2DMatrix.java +++ /dev/null @@ -1,52 +0,0 @@ -package geeksforgeeks; - -/** - * DFS + Memoization - *

- * Traverse all points in matrix, use every point as starting point to do dfs traversal. DFS function returns max increasing - * path after comparing four max return distance from four directions. - */ - -class LIS2DMatrix { - int[][] dirs = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; - - public int longestIncreasingPath(int[][] matrix) { - - if (matrix.length == 0) return 0; - // i+1,j, i-1,j i,j+1 i,j-1 - Integer[][] cache = new Integer[matrix.length][matrix[0].length]; - //Arrays.fill(cache,-1); - int result = 0; - for (int i = 0; i < matrix.length; i++) { - for (int j = 0; j < matrix[0].length; j++) { - result = Math.max(dfsUtil(matrix, i, j, cache, Integer.MIN_VALUE), result); - } - } - - return result; - } - - public int dfsUtil(int[][] matrix, int i, int j, Integer[][] cache, int data) { - if (i < 0 || i >= matrix.length || j < 0 || j >= matrix[0].length || data >= matrix[i][j]) return 0; - - - if (cache[i][j] != null) return cache[i][j]; - - int max = 1; // every element is an answer to itself - - for (int[] dir : dirs) { - - int x = i + dir[0]; - int y = j + dir[1]; - - int count = 1 + dfsUtil(matrix, x, y, cache, matrix[i][j]); - max = Math.max(count, max); - } - cache[i][j] = max; - - return cache[i][j]; - - } - - -} \ No newline at end of file diff --git a/src/geeksforgeeks/LRUCache.java b/src/geeksforgeeks/LRUCache.java deleted file mode 100644 index a41f5ff..0000000 --- a/src/geeksforgeeks/LRUCache.java +++ /dev/null @@ -1,123 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; - -class LRUCache { - - class DLLNode{ - DLLNode prev; - DLLNode next; - int val; - int key; - public DLLNode(int key, int val){ - this.val=val; - this.key=key; - } - } - Map map; - DLLNode head; - DLLNode tail; - int capacity=0; - public LRUCache(int capacity) { - map= new HashMap<>(); - head= new DLLNode(-1,-1); - tail= new DLLNode(-1,-1); - head.next=tail; - tail.prev=head; - this.capacity=capacity; - } - - public int get(int key) { - if(!map.containsKey(key)) return -1; - DLLNode node= map.get(key); - update(node); - return node.val; - } - - public void put(int key, int value) { - if(map.containsKey(key)){ - DLLNode node= map.get(key); - node.val=value; - update(node); - }else{ - if(map.size()>=capacity){ - removeTail(); - } - DLLNode newNode= new DLLNode(key,value); - map.put(key, newNode); - - updateHead(newNode); - } - } - - public void removeTail(){ - DLLNode tailNode=tail.prev; - remove(tailNode); - map.remove(tailNode.key); - } - - public void updateHead(DLLNode node){ - node.prev = head; - node.next = head.next; - head.next.prev = node; - head.next = node; - } - - public void remove(DLLNode node){ - DLLNode next= node.next; - DLLNode prev= node.prev; - prev.next=next; - next.prev=prev; - } - public void update(DLLNode node){ - remove(node); - updateHead(node); - } - } - - - class LRUCache1 { - LinkedHashMap isbnToPrice; - - public LRUCache1(final int capacity) { - this.isbnToPrice - = new LinkedHashMap(capacity, 1f, true) { - @Override - protected boolean removeEldestEntry(Map.Entry e) { - return this.size() > capacity; - } - }; - } - - public Integer lookup(Integer key) { - if (!isbnToPrice.containsKey(key)) { - return null; - } - return isbnToPrice.get(key); - } - - public Integer insert(Integer key, Integer value) { - // We add the value for key only if key is not present - we don’t update - // existing values. - Integer currentValue = isbnToPrice.get(key); - if (!isbnToPrice.containsKey(key)) { - isbnToPrice.put(key, value); - return currentValue; - } else { - return null; - } - } - - public Integer erase(Object key) { - return isbnToPrice.remove(key); - } - - } - /** - * Your LRUCache object will be instantiated and called as such: - * LRUCache obj = new LRUCache(capacity); - * int param_1 = obj.get(key); - * obj.put(key,value); - */ \ No newline at end of file diff --git a/src/geeksforgeeks/LargestDivisibleSubset.java b/src/geeksforgeeks/LargestDivisibleSubset.java deleted file mode 100644 index 8bc5d88..0000000 --- a/src/geeksforgeeks/LargestDivisibleSubset.java +++ /dev/null @@ -1,66 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * Given a set of distinct positive integers, - * find the largest subset such that every pair (Si, Sj) of elements in this subset satisfies: - Si % Sj = 0 or Sj % Si = 0. - If there are multiple solutions, return any subset is fine. - Input: [2,3,4,6,10,8,24] - Output: [2,4,8,24] each pair's modulo is 0 - */ -public class LargestDivisibleSubset { - - /** - * if a%b==0 means a>b, if b>a then the ans is b itself - *inorder to have that we need to sort the array in increasing order - at first each val is ans to itself, then we come from last so a is higher in a%b - for ex if 2 is factor of 4 then include the set involve in available. This is DP problem - [2, 3, 4, 6, 8, 10, 24] - {2} {3} {4} {6} {8} {10} {24} - {8,24} - - {6,24} - - {4,8,24} - - {3,6,24} - - {2,4,8,24} - * - */ - public List largestDivisibleSubset(int[] nums) { - if(nums==null || nums.length==0) return Collections.emptyList(); - - Arrays.sort(nums); - List[] result= new ArrayList[nums.length]; - - int maxLength=0; - int resIndex=-1; - List re; - - for(int i=nums.length-1;i>=0;i--){ - result[i]=new ArrayList<>(); // every element is an answer itself - re= new ArrayList<>(); - result[i].add(nums[i]); - for(int j=i+1;j re.size()){ // this is to take even if 1 element is at j position - re=result[j]; // the reason we take list is consider 4,8,24 when i is at 4 and j is 8 mod is 0 means 4%24 is also zero - } - } - } - result[i].addAll(re); - if(result[i].size()>maxLength){ - maxLength=result[i].size(); - resIndex=i; - } - } - Collections.sort(result[resIndex]); - return result[resIndex]; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/LargestPossibleNumber.java b/src/geeksforgeeks/LargestPossibleNumber.java deleted file mode 100644 index 2848d67..0000000 --- a/src/geeksforgeeks/LargestPossibleNumber.java +++ /dev/null @@ -1,55 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -/** - * https://www.geeksforgeeks.org/given-an-array-of-numbers-arrange-the-numbers-to-form-the-biggest-number/ - */ -class LargestPossibleNumber { - - public static void main(String[] args) { - int nums[] = { 10, 68, 97, 9, 21, 12 }; - List numbers = Arrays.asList("10", "68", "97", "9", "21", "12"); - - Collections.sort(numbers, (a, b) -> (b + a).compareTo(a + b)); - numbers.stream().forEach(System.out::print); - System.out.println(new LargestPossibleNumber().largestNumber(nums)); - } - - public String largestNumber(int[] nums) { - String[] arr = new String[nums.length]; - for (int i = 0; i < nums.length; i++) { - arr[i] = String.valueOf(nums[i]); - } - - Arrays.sort(arr, (a, b) -> { - return (b + a).compareTo(a + b); - }); - - StringBuilder sb = new StringBuilder(); - for (String s : arr) { - sb.append(s); - } - - while (sb.charAt(0) == '0' && sb.length() > 1) - sb.deleteCharAt(0); - - return sb.toString(); - } - - public String largestNumber1(int[] nums) { - if(nums==null || nums.length==0) return null; - List list= new LinkedList<>(); - for(int i: nums){ - list.add(String.valueOf(i)); - } - - Collections.sort(list, (a,b)->(int)(Long.parseLong(b+a)-Long.parseLong(a+b))); - - return String.join("",list).replaceFirst("^0+(?!$)", ""); - - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/LargestSubArrayWithZeroesAndOnes.java b/src/geeksforgeeks/LargestSubArrayWithZeroesAndOnes.java deleted file mode 100644 index 2d5e893..0000000 --- a/src/geeksforgeeks/LargestSubArrayWithZeroesAndOnes.java +++ /dev/null @@ -1,68 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; - -/*https://www.geeksforgeeks.org/largest-subarray-with-equal-number-of-0s-and-1s/ - Given an array containing only 0s and 1s, find the largest subarray which contains equal no of 0s and 1s. - Expected time complexity is O(n). -*/ -class LargestSubArrayWithZeroesAndOnes { - /** - * The concept of taking cumulative sum, taking 0’s as -1 will help us in optimising the approach. - * While taking the cumulative sum, there are two cases when there can be a sub-array with equal number of 0’s and 1’s - * When cumulative sum=0, which signifies that sub-array from index (0) till present index has equal number of 0’s and 1’s. - * - * When we encounter a cumulative sum value which we have already encountered before, - * which means that sub-array from the previous index+1 till the present index has equal number of 0’s and 1’s as they give a cumulative sum of 0 . - * @param arr - * @param n - * @return - */ - int maxLen(int arr[], int n) { - - HashMap map = new HashMap<>(); - - int sum = 0; - int maxLength = 0; - int endingIndex = -1; - - for (int i = 0; i < n; i++) { - arr[i] = (arr[i] == 0) ? -1 : 1; - } - - for (int i = 0; i < n; i++) { - sum += arr[i]; - - if (sum == 0) { // To handle sum=0 at last index - maxLength = i + 1; - endingIndex = i; - } - // If this sum is seen before, - // then update max_len if required - if (map.containsKey(sum)) { - if (maxLength < i - map.get(sum)) { - maxLength = i - map.get(sum); - endingIndex = i; - } - } else - map.put(sum, i); - } - - for (int i = 0; i < n; i++) { - arr[i] = (arr[i] == -1) ? 0 : 1; - } - - int start = endingIndex - maxLength + 1; - System.out.println(start + " to " + endingIndex); - - return maxLength; - } - - public static void main(String[] args) { - LargestSubArrayWithZeroesAndOnes sub = new LargestSubArrayWithZeroesAndOnes(); - int arr[] = {0, 0, 0, 1, 0, 1, 1}; - int n = arr.length; - - sub.maxLen(arr, n); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/LargestTimeFromDigits.java b/src/geeksforgeeks/LargestTimeFromDigits.java deleted file mode 100644 index 7839e43..0000000 --- a/src/geeksforgeeks/LargestTimeFromDigits.java +++ /dev/null @@ -1,39 +0,0 @@ -package geeksforgeeks; - -/** - * Given an array of 4 digits, return the largest 24 hour time that can be made. - -The smallest 24 hour time is 00:00, and the largest is 23:59. Starting from 00:00, a time is larger if more time has elapsed since midnight. - -Return the answer as a string of length 5. If no valid time can be made, return an empty string. - */ -public class LargestTimeFromDigits{ - public String largestTimeFromDigits(int[] A) { - if(A==null || A.length==0) return ""; - String result=""; - // because A.length == 4 - for(int i=0;i<4;i++){ - for(int j=0;j<4;j++){ - for(int k=0;k<4;k++){ - //We cannot take a number twice. i, j, k and (6-i-j-k) denoting the indices of 4 numbers should be distinct. - if(i==j || j==k|| k==i) continue; - String hrs= A[i]+""+A[j]; - //We are trying out all possible ordering, - //indices of 4 numbers are 0, 1, 2, and 3. - //sum of indices = 0 + 1 + 2 + 3= 6 - //i, j and k denote 3 indices. - //So, if we know 3 numbers, - //the 4th number will be the remaining index, i.e., 6-i-j-k - - String mins= A[k]+""+A[6-i-j-k]; - - if(hrs.compareTo("24")<0 && mins.compareTo("59")<0 && result.compareTo(hrs+":"+mins)<0){ - result=hrs+":"+mins; - } - - } - } - } - return result; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/LengthOfLongestSubstringKDistinct.java b/src/geeksforgeeks/LengthOfLongestSubstringKDistinct.java deleted file mode 100644 index f832355..0000000 --- a/src/geeksforgeeks/LengthOfLongestSubstringKDistinct.java +++ /dev/null @@ -1,40 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; -import java.util.Map; - -public class LengthOfLongestSubstringKDistinct { - /** - * @param s: A string - * @param k: An integer - * - * @return: An integer - */ - public int lengthOfLongestSubstringKDistinct(String s, int k) { - if (s == null || k == 0) { - return 0; - } - Map map = new HashMap<>(); - - int result = 0; - int left = 0; - int right = 0; - - while (left < s.length()) { - char ch = s.charAt(left); - map.put(ch, map.getOrDefault(ch, 0) + 1); - while (map.size() > k) { - char chright = s.charAt(right); - map.put(chright, map.get(chright) - 1); - if (map.get(chright) <= 0) { - map.remove(chright); - } - right++; - } - left++; - result = Math.max(result, left - right); - } - - return result; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/LinkedListRemoveDuplicates.java b/src/geeksforgeeks/LinkedListRemoveDuplicates.java deleted file mode 100644 index ae11537..0000000 --- a/src/geeksforgeeks/LinkedListRemoveDuplicates.java +++ /dev/null @@ -1,36 +0,0 @@ -package geeksforgeeks; - -class LinkedListRemoveDuplicate{ - /** - * Method to remove duplicates from Linked list - * when no additional buffer is allowed. - * - * Time Complexity : O(n^2) - * Space Complexity : O(1) - * - * @param head - */ - public static void removeDuplicatesWithoutBuffer(ListNode head) { - /* If head is null, stop processing */ - if (head == null) { - return; - } - /* We will need two pointers here i.e current and runner. - * When current is pointing to a node, move runner through - * rest of the list, checking for duplicates */ - ListNode current = head; - while (current != null) { - /* Have runner point to current node */ - ListNode runner = current; - while (runner.next != null) { - /* If it is duplicate, jump runner over the node */ - if (runner.next.val == current.val) { - runner.next = runner.next.next; - } else { - runner = runner.next; - } - } - current = current.next; - } - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/LongestConsequtiveSequence.java b/src/geeksforgeeks/LongestConsequtiveSequence.java deleted file mode 100644 index d81010e..0000000 --- a/src/geeksforgeeks/LongestConsequtiveSequence.java +++ /dev/null @@ -1,73 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** - * Given an unsorted array of integers, - * find the length of the longest consecutive elements sequence. - * - * Your algorithm should run in O(n) complexity. - * Input: [100, 4, 200, 1, 3, 2] - * Output: 4 - * Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. - * Therefore its length is 4. - */ -class LongestConsequtiveSequence { - - public int longestConsecutive(int[] nums) { - if (nums.length == 0) { - return 0; - } - int max = 1; - Set set = new HashSet<>(); - for (int i : nums) { - set.add(i); - } - // have a set, go backwards and remove entries, go forward remove entries and calculate Max - // without removing entries, runtime would be too much - for (Integer i : nums) { - int num = i; - int count = 1; - // looking left - while (set.contains(--num)) { - count++; - set.remove(num); - } - num = i; - while (set.contains(++num)) { - count++; - set.remove(num); - } - - max = Math.max(max, count); - } - - return max; - } - - public int longestConsecutiveSorting(int[] nums) { - if (nums == null || nums.length == 0) - return 0; - - Arrays.sort(nums); - - int longestStreak = 1; - int currentStreak = 1; - - for (int i = 0; i < nums.length - 1; i++) { - if (nums[i] != nums[i+1]) { // avoid duplicate - if (nums[i] + 1 == nums[i+1]) { // if increasing increase streak count else reset - currentStreak += 1; - } - else { - longestStreak = Math.max(longestStreak, currentStreak); - currentStreak = 1; - } - } - } - - return Math.max(longestStreak, currentStreak); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/LongestIncreasingPathInMatrix.java b/src/geeksforgeeks/LongestIncreasingPathInMatrix.java deleted file mode 100644 index fc668a2..0000000 --- a/src/geeksforgeeks/LongestIncreasingPathInMatrix.java +++ /dev/null @@ -1,64 +0,0 @@ -package geeksforgeeks; - -/** - * https://leetcode.com/problems/longest-increasing-path-in-a-matrix - * - * Do DFS from every cell - * Compare every 4 direction and skip cells that are out of boundary or smaller - * Get matrix max from every cell's max - * Use matrix[x][y] <= matrix[i][j] so we don't need a visited[m][n] array - * The key is to cache the distance because it's highly possible to revisit a cell - * - * DFS + Memoization - * - * Traverse all points in matrix, use every point as starting point to do dfs traversal. DFS function returns max increasing - * path after comparing four max return distance from four directions. - * - * */ -public class LongestIncreasingPathInMatrix { - - int[][] dirs= new int[][] {{1,0},{-1,0},{0,1},{0,-1}}; - public int longestIncreasingPath(int[][] matrix) { - if(matrix.length == 0) return 0; - // i+1,j, i-1,j i,j+1 i,j-1 - Integer[][] cache= new Integer[matrix.length][matrix[0].length]; - - int result=0; - for(int i=0;i=matrix.length || j<0 || j>=matrix[0].length|| data>=matrix[i][j]) return 0; - - - - if(cache[i][j]!=null) return cache[i][j]; - - // initialize max distance as 1 since the path includes starting point itself - int max=1; - - for(int[] dir: dirs){ - - int x=i+dir[0]; - int y=j+dir[1]; - // if next point is a valid point, add curLen by 1 and continue DFS traversal - int count=1+dfsUtil(matrix,x,y,cache, matrix[i][j]); - max=Math.max(count,max); - } - // update max increasing path value starting from current point in cache - cache[i][j]=max; - - return cache[i][j]; - - } - - public boolean isValid(int[][] matrix, int i, int j, int data){ - return i >= 0 && i < matrix.length && j >= 0 && j < matrix[0].length; - } -} diff --git a/src/geeksforgeeks/LongestRepeatCharReplace.java b/src/geeksforgeeks/LongestRepeatCharReplace.java deleted file mode 100644 index 4cf5039..0000000 --- a/src/geeksforgeeks/LongestRepeatCharReplace.java +++ /dev/null @@ -1,47 +0,0 @@ -package geeksforgeeks; - -// you can perform at most k operations on that string. -// In one operation, you can choose any character of the string and change it to any other uppercase English character. -// Find the length of the longest sub-string containing all repeating letters -// s = "ABAB", k = 2 -// Output: -// 4 -// Explanation: -// Replace the two 'A's with two 'B's or vice versa. -public class LongestRepeatCharReplace { - public int characterReplacement(String s, int k) { - if(s==null || s.length()==0) return 0; - - int[] cache= new int[26]; - int left=0; - int right=0; - int result=0; - int maxOccured=0; - while(right 0, then we have characters in the window that are NOT the character that occurs the most. - // end-start+1-maxCount is equal to exactly the # of characters that are NOT the character that occurs the most in that window. - //Example: For a window "xxxyz", end-start+1-maxCount would equal 2. (maxCount is 3 and there are 2 characters here, "y" and "z" that are not "x" in the window.) - // We are allowed to have at most k replacements in the window, so when end-start+1-maxCount > k, - //then there are more characters in the window than we can replace, and we need to shrink the window. - // If we have window with "xxxy" and k = 1, that's fine because end-start+1-maxCount = 1, which is not > k. maxLength gets updated to 4. - // But if we then find a "z" after, like "xxxyz", then we need to shrink the window because now end-start+1-maxCount = 2, and 2 > 1. The window becomes "xxyz". - if(right-left+1-maxOccured > k){ - char leftchr= s.charAt(left); - --cache[leftchr-'A']; - left++; - } - result=Math.max(result, right-left+1); - right++; - } - - return result; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/LongestSpanWithSameSumArray.java b/src/geeksforgeeks/LongestSpanWithSameSumArray.java deleted file mode 100644 index 77476cc..0000000 --- a/src/geeksforgeeks/LongestSpanWithSameSumArray.java +++ /dev/null @@ -1,74 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; -import java.util.Map; - -/** - * Given two binary arrays arr1[] and arr2[] of same size n. - * Find length of the longest common span (i, j) - * where j >= i such that arr1[i] + arr1[i+1] + …. + arr1[j] = arr2[i] + arr2[i+1] + …. + arr2[j]. - * - * Expected time complexity is Θ(n). - * - * Input: arr1[] = {0, 1, 0, 0, 0, 0}; - * arr2[] = {1, 0, 1, 0, 0, 1}; - * Output: 4 - * The longest span with same sum is from index 1 to 4. - * - * Input: arr1[] = {0, 1, 0, 1, 1, 1, 1}; - * arr2[] = {1, 1, 1, 1, 1, 0, 1}; - * Output: 6 - * The longest span with same sum is from index 1 to 6. - * - * */ -class LongestSpanWithSameSumArray { - // Returns largest common subarray with equal - // number of 0s and 1s - static int longestCommonSum(int[] arr1, int[] arr2, int n) - { - // Find difference between the two - int[] arr = new int[n]; - // the reason we take the difference is, the resultant array - // will only contain 3 values 0,1,-1, checking for zero sum - // on the resultant array means we get the longest span where elements are same - for (int i = 0; i < n; i++) - arr[i] = arr1[i] - arr2[i]; - - // Creates an empty hashMap hM - Map hM = new HashMap<>(); - - int sum = 0; // Initialize sum of elements - int max_len = 0; // Initialize result - - // Traverse through the given array - for (int i = 0; i < n; i++) - { - // Add current element to sum - sum += arr[i]; - - // To handle sum=0 at last index - if (sum == 0) - max_len = i + 1; - - // If this sum is seen before, - // then update max_len if required - if (hM.containsKey(sum)) - max_len = Math.max(max_len, i - hM.get(sum)); - - else // Else put this sum in hash table - hM.put(sum, i); - } - return max_len; - } - - - public static void main(String args[]) { - /* int[] arr1 = {0, 1, 0, 1, 1, 1, 1}; - int[] arr2 = {1, 1, 1, 1, 1, 0, 1};*/ - int arr1[] = { 0, 1, 0, 0, 1, 1, 1, 0 }; - int arr2[] = { 1, 1, 1, 1, 1, 1, 0, 1 }; - //{-1,0,-1,0,0,1,0} - int n = arr1.length; - System.out.println(longestCommonSum(arr1, arr2, n)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/LongestSubArraySumUtmostK.java b/src/geeksforgeeks/LongestSubArraySumUtmostK.java deleted file mode 100644 index 11c82cb..0000000 --- a/src/geeksforgeeks/LongestSubArraySumUtmostK.java +++ /dev/null @@ -1,47 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/longest-subarray-sum-elements-atmost-k/ - * - * Given an array of integers, - * our goal is to find the length of largest subarray - * having sum of its elements atmost ‘k’ where k>0. - * - * Examples: - * - * Input : arr[] = {1, 2, 1, 0, 1, 1, 0}, - * k = 4 - * Output : 5 - * Explanation: - * {1, 2, 1} => sum = 4, length = 3 - * {1, 2, 1, 0}, {2, 1, 0, 1} => sum = 4, length = 4 - * {1, 0, 1, 1, 0} =>5 sum = 3, length = 5 - */ -// array is non-negative -class LongestSubArraySumUtmostK { - - public static int utMostSum(int arr[], int n, int target) { - int sum = 0; - int count = 0; - int maxCount = 0; - - for (int i = 0; i < n; i++) { - if ((sum + arr[i]) <= target) { - sum += arr[i]; - count++; - } else if (sum != 0) { - sum = sum - arr[i - count] + arr[i]; - } - maxCount = Math.max(count, maxCount); - } - return maxCount; - } - - public static void main(String[] args) { - int arr[] = { 1, 2, 1, 0, 1, 1, 0 }; - int n = arr.length; - int k = 4; - - System.out.print(utMostSum(arr, n, k)); - } -} diff --git a/src/geeksforgeeks/LongestUniqueSubstring.java b/src/geeksforgeeks/LongestUniqueSubstring.java deleted file mode 100644 index 21b6f58..0000000 --- a/src/geeksforgeeks/LongestUniqueSubstring.java +++ /dev/null @@ -1,53 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; -import java.util.Map; - -/*https://leetcode.com/problems/longest-substring-without-repeating-characters/*/ -public class LongestUniqueSubstring { - - public static int lengthOfLongestSubstring(String s) { - Map map = new HashMap<>(); - int begin = 0; - int end = 0; - int counter = 0; - int result = 0; - - while (end < s.length()) { - char c = s.charAt(end); - map.put(c, map.getOrDefault(c, 0) + 1); - if (map.get(c) > 1) { - counter++; - } - end++; - - while (counter > 0) { - char charTemp = s.charAt(begin); - if (map.get(charTemp) > 1) { - counter--; - } - map.put(charTemp, map.get(charTemp) - 1); - begin++; - } - result = Math.max(result, end - begin); - } - return result; - } - public static int lengthOfLongestSubstringOpt(String s) { - int res = 0, n = s.length(); - int[] arr = new int[256]; - int startIndex=0; - for(int curr=0;curr next index, so that we can start from here - arr[s.charAt(curr)] = curr+1; - } - return res; - } - public static void main(String[] args) { - System.out.println(lengthOfLongestSubstringOpt("pwwkew")); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MajorityVoting.java b/src/geeksforgeeks/MajorityVoting.java deleted file mode 100644 index 291132a..0000000 --- a/src/geeksforgeeks/MajorityVoting.java +++ /dev/null @@ -1,86 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.List; - -/*https://leetcode.com/problems/majority-element/*/ -public class MajorityVoting { - - public static List majorityElementII(int[] nums) { - if (nums == null || nums.length == 0) { - return new ArrayList<>(); - } - List result = new ArrayList<>(); - int candidate1 = nums[0]; - int candidate2 = nums[0]; - int count1 = 0; - int count2 = 0; - int len = nums.length; - for (int i = 0; i < len; i++) { - if (nums[i] == candidate1) { - count1++; - } else if (nums[i] == candidate2) { - count2++; - } else if (count1 == 0) { - candidate1 = nums[i]; - count1 = 1; - } else if (count2 == 0) { - candidate2 = nums[i]; - count2 = 1; - } else { - count1--; - count2--; - } - } - count1 = 0; - count2 = 0; - for (int i = 0; i < len; i++) { - if (nums[i] == candidate1) { - count1++; - } else if (nums[i] == candidate2) { - count2++; - } - } - if (count1 > len / 3) { - result.add(candidate1); - } - if (count2 > len / 3) { - result.add(candidate2); - } - return result; - } - - public static int majorityElementI(int[] nums) { - int count = 1; - int candidate = nums[0]; - int majority = nums.length / 2; - - for (int i = 1; i < nums.length; i++) { - if (candidate == nums[i]) { - count++; - } else if (count == 0) { - count++; - candidate = nums[i]; - } else { - count--; - } - } - //what if array is even and it has many elements - count = 0; - for (int num : nums) { - if (num == candidate) { - count++; - } - } - - return count > majority ? candidate : 0; - } - - public static void main(String[] args) { - int[] arr = { 1, 1, 1, 1, 1, 2, 2, 4, 4, 4, 4, 4, 2, 2 }; - System.out.println(majorityElementI(arr)); - System.out.println(majorityElementII(arr)); - - } - -} diff --git a/src/geeksforgeeks/MakeAnArrayPalindrome.java b/src/geeksforgeeks/MakeAnArrayPalindrome.java deleted file mode 100644 index 8234a81..0000000 --- a/src/geeksforgeeks/MakeAnArrayPalindrome.java +++ /dev/null @@ -1,41 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/find-minimum-number-of-merge-operations-to-make-an-array-palindrome/ - */ -class MakeAnArrayPalindrome { - - static int findMinOps(int[] arr, int n) { - int ans = 0; - - // Start from two corners - for (int i = 0, j = n - 1; i <= j; ) { - // If corner elements are same, problem reduces arr[i+1..j-1] - if (arr[i] == arr[j]) { - i++; - j--; - } - // If left element is greater, then we merge right two elements - else if (arr[i] > arr[j]) { - // need to merge from tail. - j--; - arr[j] += arr[j + 1]; - ans++; - } - // Else we merge left two elements - else { - i++; - arr[i] += arr[i - 1]; - ans++; - } - } - - return ans; - } - - public static void main(String[] args) { - int arr[] = new int[] { 1, 4, 5, 9, 1 }; - System.out.println("Count of minimum operations is " + findMinOps(arr, arr.length)); - - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MatrixRowWithMax1.java b/src/geeksforgeeks/MatrixRowWithMax1.java deleted file mode 100644 index 0a278e9..0000000 --- a/src/geeksforgeeks/MatrixRowWithMax1.java +++ /dev/null @@ -1,48 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/find-the-row-with-maximum-number-1s/ - */ -public class MatrixRowWithMax1 { - - public static void main(String[] args) { - int[][] mat = { { 0, 0, 0, 1 }, { 0, 1, 1, 1 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 } }; - System.out.println(rowWithMax1s(mat)); - } - - static int rowWithMax1s(int mat[][]) { - - int R = mat.length; - int C = mat[0].length; - int max_row_index = 0; - - int j = findFirstIndex(mat[0], 0, C - 1); - if (j == -1) { - j = C - 1; - } - - for (int i = 1; i < R; i++) { - while (j >= 0 && mat[i][j] == 1) { - j = j - 1; - max_row_index = i; - } - } - return max_row_index; - } - - static int findFirstIndex(int arr[], int low, int high) { - if (high >= low) { - int mid = low + (high - low) / 2; - - if ((mid == 0 || (arr[mid - 1] == 0)) && arr[mid] == 1) { - return mid; - } else if (arr[mid] == 0) { - return findFirstIndex(arr, (mid + 1), high); - } else { - return findFirstIndex(arr, low, (mid - 1)); - } - } - return -1; - } - -} diff --git a/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java b/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java deleted file mode 100644 index 83ba315..0000000 --- a/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java +++ /dev/null @@ -1,118 +0,0 @@ -package geeksforgeeks; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.PriorityQueue; - -/** - * Given an array arr[] containing n elements. - * The problem is to find maximum number of distinct elements (non-repeating) after removing k elements from the array. - * Input : arr[] = {5, 7, 5, 5, 1, 2, 2}, k = 3 - * Output : 4 - * - * Remove 2 occurrences of element 5 and - * 1 occurrence of element 2. - * - * Input : arr[] = {1, 2, 3, 4, 5, 6, 7}, k = 5 - * Output : 2 - */ -public class MaxDistinctElementAfterKRemoval { - // after removing k elements - - /** - * Create a hash table to store the frequency of each element. - * Insert frequency of each element in a max heap. - * Now, perform the following operation k times. - * Remove an element from the max heap. Decrement its value by 1. After this if element is not equal to 0, then again push the element in the max heap. - * @param arr - * @param n - * @param k - * @return - */ - static int maxDistinctNum(int[] arr, int n, int k) - { - // hash map to store - // frequency of each element - HashMap map = new HashMap<>(); - - // priority_queue 'pq' implemented as - // max heap - PriorityQueue pq = - new PriorityQueue<>(Collections.reverseOrder()); - - // storing frequency of each element in map - for (int i = 0; i < n; i++) { - map.put(arr[i], map.getOrDefault(arr[i],0)+1); - } - - // inserting frequency of each element in 'pq' - for (Map.Entry entry : map.entrySet()) { - pq.add(entry.getValue()); - } - - while (k > 0) { - // get the top element of 'pq' - int temp = pq.poll(); - - // decrement the popped element by 1 - temp--; - - // if true, then push the element in 'pq' - if (temp > 0) - pq.add(temp); - k--; - } - - // Count all those elements that appear - // once after above operations. - int res = 0; - while (pq.size() != 0) { - pq.poll(); - res++; - } - - return res; - } - - /** - * Given an array of integers arr and an integer k. Find the least number of unique integers after removing exactly k elements. - * Input: arr = [5,5,4], k = 1 - * Output: 1 - * Explanation: Remove the single 4, only 5 is left. - * - * Input: arr = [4,3,1,1,3,3,2], k = 3 - * Output: 2 - * Explanation: Remove 4, 2 and either one of the two 1s or three 3s. 1 and 3 will be left. - * @param arr - * @param k - * @return - */ - public int findLeastNumOfUniqueInts(int[] arr, int k) { - if(arr.length==0) return 0; - Map frequencyMap= new HashMap<>(); - - for(int i: arr){ - frequencyMap.put(i,frequencyMap.getOrDefault(i,0)+1); - } - - PriorityQueue maxQueue= new PriorityQueue<>(); - - for(Map.Entry entry: frequencyMap.entrySet()){ - maxQueue.offer(entry.getValue()); - } - - while(k-- >0){ - int temp= maxQueue.poll(); - temp-=1; - if(temp>0) maxQueue.offer(temp); - - } - - int result=0; - while(!maxQueue.isEmpty()){ - result++; - } - return result; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MaxFreqStack.java b/src/geeksforgeeks/MaxFreqStack.java deleted file mode 100644 index f786508..0000000 --- a/src/geeksforgeeks/MaxFreqStack.java +++ /dev/null @@ -1,75 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; -import java.util.Map; -import java.util.PriorityQueue; - -/** - * FreqStack has two functions: - * - * push(int x), which pushes an integer x onto the stack. - * pop(), which removes and returns the most frequent element in the stack. - * If there is a tie for most frequent element, - * the element closest to the top of the stack is removed and returned. - * ["FreqStack","push","push","push","push","push","push","pop","pop","pop","pop"], - * [[],[5],[7],[5],[7],[4],[5],[],[],[],[]] - * Output: [null,null,null,null,null,null,null,5,7,5,4] - * Explanation: - * After making six .push operations, the stack is [5,7,5,7,4,5] from bottom to top. Then: - * - * pop() -> returns 5, as 5 is the most frequent. - * The stack becomes [5,7,5,7,4]. - * - * pop() -> returns 7, as 5 and 7 is the most frequent, but 7 is closest to the top. - * The stack becomes [5,7,5,4]. - * - * pop() -> returns 5. - * The stack becomes [5,7,4]. - * - * pop() -> returns 4. - * The stack becomes [5,7]. - */ -public class MaxFreqStack { - - PriorityQueue maxQueue; - Map hashMap; - int sequence = 0; - - public MaxFreqStack() { - - maxQueue= new PriorityQueue<>((a,b)->{ - if(a.frequency==b.frequency){ - return Integer.compare(b.sequence,a.sequence); - } - return Integer.compare(b.frequency,a.frequency); - }); - hashMap= new HashMap<>(); - } - - public void push(int x) { - hashMap.put(x, hashMap.getOrDefault(x, 0) + 1); - maxQueue.offer(new EntryStack(x, hashMap.get(x), sequence++)); - } - - public int pop() { - EntryStack temp = maxQueue.poll(); - hashMap.put(temp.val, temp.frequency - 1); - - return temp.val; - } -} - -// 1. val = value of the number -// 2. frequency = current frequency of the number when it was pushed to the heap -// 3. sequenceNumber = a sequence number, to know what number came first -class EntryStack { - int val; - int frequency; - int sequence; - - public EntryStack(int val, int frequency, int sequence) { - this.val = val; - this.frequency = frequency; - this.sequence = sequence; - } -} diff --git a/src/geeksforgeeks/MaxHistogram.java b/src/geeksforgeeks/MaxHistogram.java deleted file mode 100644 index a860ddd..0000000 --- a/src/geeksforgeeks/MaxHistogram.java +++ /dev/null @@ -1,68 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; - -/** - * https://leetcode.com/problems/largest-rectangle-in-histogram/ - */ - -public class MaxHistogram { - - //For any bar i the maximum rectangle is of width r - l - 1 - // where r - is the last coordinate of the bar to the right with height h[r] >= h[i] and - // l - is the last coordinate of the bar to the left which height h[l] >= h[i] - //So if for any i coordinate we know his utmost higher (or of the same height) neighbors to the right and to the left, - // we can easily find the largest rectangle: maxArea = Math.max(maxArea, height[i] * (lessFromRight[i] - lessFromLeft[i] - 1)); - - //The main trick is how to effectively calculate lessFromRight and lessFromLeft arrays. - // The trivial solution is to use O(n^2) solution and for each i element - // first find his left/right neighbour in the second inner loop just iterating back or forward: - public static int largestRectangleArea(int[] height) { - if (height == null || height.length == 0) { - return 0; - } - int[] lessFromLeft = new int[height.length]; // idx of the first bar the left that is lower than current - int[] lessFromRight = new int[height.length]; // idx of the first bar the right that is lower than current - lessFromRight[height.length - 1] = height.length; - lessFromLeft[0] = -1; - - // for example in order to lessFromLeft[i]; if height[i - 1] < height[i] then left[i] = i - 1; - // other wise we do not need to start scan from i - 1; we can start the scan from lessFromLeft[i - 1], - // because since lessFromLeft[i - 1] is the first position to the left of i - 1 that have height less than height[i - 1], - // and we know height[i - 1] >= height[i]; so lessFromLeft[i] must be at the left or at lessFromLeft[i - 1]; similar for the right array; - for (int i = 1; i < height.length; i++) { - int p = i - 1; - - while (p >= 0 && height[p] >= height[i]) { - p = lessFromLeft[p]; - } - lessFromLeft[i] = p; - } - - for (int i = height.length - 2; i >= 0; i--) { - int p = i + 1; - - while (p < height.length && height[p] >= height[i]) { - p = lessFromRight[p]; - } - lessFromRight[i] = p; - } - // after both the loop ends, this is the output of left and right - // input [2, 1, 5, 6, 2, 3] - // 0, 1, ,2 3, 4, 5 - // left [-1, -1, 1, 2, 1, 4] => indexes of elements - // right [1, 6, 4, 4, 6, 6] - int maxArea = 0; - for (int i = 0; i < height.length; i++) { - maxArea = Math.max(maxArea, height[i] * (lessFromRight[i] - lessFromLeft[i] - 1)); - } - System.out.println(Arrays.toString(lessFromLeft)); - System.out.println(Arrays.toString(lessFromRight)); - return maxArea; - } - - public static void main(String[] args) { - int[] arr = new int[] { 2, 1, 5, 6, 2, 3 }; - System.out.println(largestRectangleArea(arr)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MaxProductString.java b/src/geeksforgeeks/MaxProductString.java deleted file mode 100644 index 54bb75d..0000000 --- a/src/geeksforgeeks/MaxProductString.java +++ /dev/null @@ -1,57 +0,0 @@ -package geeksforgeeks; - -/** - * Given a string array words, find the maximum value of length(word[i]) * length(word[j]) - * where the two words do not share common letters. - * You may assume that each word will contain only lower case letters - * Input: ["abcw","baz","foo","bar","xtfn","abcdef"] - * Output: 16 - * Explanation: The two words can be "abcw", "xtfn". - * - * Input: ["a","aa","aaa","aaaa"] - * Output: 0 - * Explanation: No such pair of words. - */ -public class MaxProductString { - public int maxProduct(String[] words) { - int[] checker = new int[words.length]; - int max = 0; - // populating the checker array with their respective numbers - for (int i = 0; i < checker.length; i++) { - int num = 0; - for (int j = 0; j < words[i].length(); j++) { - // we are making char index in bit to be set - // a 1->1 making first bit marked - // b 2->10 - // c 4->100 - // ab 3->11 // making first and secind marked - // ac 5->101 - // abc 7->111 - // az 33554433->10000000000000000000000001 - - num |= 1 << (words[i].charAt(j) - 'a'); - System.out.println(words[i].charAt(j)+"->"+num+ "->"+Integer.toBinaryString(num) ); - } - - checker[i] = num; - } - - for (int i = 0; i < words.length; i++) { - for (int j = i + 1; j < words.length; j++) { - // abcd efgd - // 11110000 -> abcd - // 00011110 -> efgd - // and-ing these two might say if even a single char is present in other - if ((checker[i] & checker[j]) == 0) //checking if the two strings have common character - max = Math.max(max, words[i].length() * words[j].length()); - } - } - System.out.println(max); - return max; - } - - - public static void main(String[] args) { - new MaxProductString().maxProduct(new String[]{"abcw", "baz", "foo", "bar", "xtfn", "abcdef"}); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MaxWidthOfBinaryTree.java b/src/geeksforgeeks/MaxWidthOfBinaryTree.java deleted file mode 100644 index 7512795..0000000 --- a/src/geeksforgeeks/MaxWidthOfBinaryTree.java +++ /dev/null @@ -1,61 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.Map; -import java.util.Queue; - -/** - * Given a binary tree, write a function to get the maximum width of the given tree. - * The width of a tree is the maximum width among all levels. - * The binary tree has the same structure as a full binary tree, but some nodes are null - * - * Input: - - 1 - / \ - 3 2 - / \ - 5 9 - / \ - 6 7 -Output: 8 -The maximum width existing in the fourth level with the length 8 (6,null,null,null,null,null,null,7). - */ -public class MaxWidthOfBinaryTree { - - // Each time a node is traversed, the position of the node(as it is in a full binary tree) is stored in the HashMap. - //If the position of the parent node is 'n', then the left child is '2 * n' and the right child is '2 * n + 1'. - //The width of each level is the last node's position in this level subtracts the first node's position in this level plus 1. - public int widthOfBinaryTree(TreeNode root) { - if(root==null) return 0; - int maxWidth=0; - - Map map= new HashMap<>(); - Queue stack=new LinkedList(); - stack.offer(root); - map.put(root,1); // if we are assigning head as 0 then the fourmula is left=>2*n+1, right=> 2*n+2 - while(!stack.isEmpty()){ - int width= stack.size(); - int start=0; - int end=0; - for(int i=0;i maxDiff) { - maxDiff = arr[i] - minElement; - } - if (arr[i] < minElement) { - minElement = arr[i]; - } - } - return maxDiff; - } - - public static void main(String[] args) { - int arr[] = { 2, 4, 1, 3, 10, 8, 5 }; - System.out.println("Maximum difference is " + maxDiff(arr, arr.length)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MaximumGap.java b/src/geeksforgeeks/MaximumGap.java deleted file mode 100644 index 64342fd..0000000 --- a/src/geeksforgeeks/MaximumGap.java +++ /dev/null @@ -1,70 +0,0 @@ -package geeksforgeeks; - -/** - * Given an unsorted array, find the maximum difference between the successive elements in its sorted form. -Return 0 if the array contains less than 2 elements. -Input: [3,6,9,1] -Output: 3 -Explanation: The sorted form of the array is [1,3,6,9], either - (3,6) or (6,9) has the maximum difference 3. - - -trick is to do in O(N)= > Radix sort - */ -public class MaximumGap { - // The first step is to find the maximum value in nums array, it will - // be the threshold to end while loop. - // Then use the radix sort algorithm to sort based on each digit from Least Significant Bit - // (LSB) to Most Significant Bit (MSB), that's exactly what's showing - // in the link. - // (nums[i] / exp) % 10 is used to get the digit, for each digit, basically the digit itself serves as the index to - // access the count array. Count array stores the index to access aux - // array which stores the numbers after sorting based on the current - // digit. - // Finally, find the maximum gap from sorted array. - // Time and space complexities are both O(n). (Actually time is O(10n) at worst case for Integer.MAX_VALUE 2147483647) - public int maximumGap(int[] nums) { - if (nums == null || nums.length < 2) { - return 0; - } - - // m is the maximal number in nums - int m = nums[0]; - for (int i = 1; i < nums.length; i++) { - m = Math.max(m, nums[i]); - } - - int exp = 1; // 1, 10, 100, 1000 ... - int R = 10; // 10 digits - - int[] aux = new int[nums.length]; - - while (m / exp > 0) { // Go through all digits from LSB to MSB - int[] count = new int[R]; - - for (int i = 0; i < nums.length; i++) { - count[(nums[i] / exp) % 10]++; - } - - for (int i = 1; i < count.length; i++) { - count[i] += count[i - 1]; - } - - for (int i = nums.length - 1; i >= 0; i--) { - aux[--count[(nums[i] / exp) % 10]] = nums[i]; - } - - for (int i = 0; i < nums.length; i++) { - nums[i] = aux[i]; - } - exp *= 10; - } - - int max = 0; - for (int i = 1; i < aux.length; i++) { - max = Math.max(max, aux[i] - aux[i - 1]); - } - - return max; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MaximumProductSubarray.java b/src/geeksforgeeks/MaximumProductSubarray.java deleted file mode 100644 index 025e49e..0000000 --- a/src/geeksforgeeks/MaximumProductSubarray.java +++ /dev/null @@ -1,63 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/maximum-product-subarray/ - */ -public class MaximumProductSubarray { - - // 1, -2, -3, 0, 8, 7, -2 - public static int maxProductSubArray(int[] A) { - - if (A.length == 0) { - return 0; - } - - int maxHerePre = A[0]; - int minHerePre = A[0]; - int maxsofar = A[0]; - - for (int i = 1; i < A.length; i++) { - int maxHere = Math.max(Math.max(maxHerePre * A[i], minHerePre * A[i]), A[i]); - int minHere = Math.min(Math.min(maxHerePre * A[i], minHerePre * A[i]), A[i]); - maxsofar = Math.max(maxHere, maxsofar); - maxHerePre = maxHere; - minHerePre = minHere; - } - return maxsofar; - } - - public static int maxSumSubArray(int[] arr) { - - int max = Integer.MIN_VALUE; - int sum = 0; - - for (int i = 0; i < arr.length; i++) { - sum = sum + arr[i]; - if (sum < 0) { - //get i if you want to get index of subarray - sum = 0; - } - max = Math.max(sum, max); - } - return sum; - } - - public int maxSubArray(int[] nums) { - if(nums==null || nums.length==0) return 0; - - int maxHere=0; - int max=Integer.MIN_VALUE; - for(int i:nums){ - maxHere=Math.max(i,maxHere+i); - max= Math.max(maxHere, max); - } - - return max; - } - - public static void main(String[] args) { - int arr[] = { 1, -2, -3, 0, 8, 7, -2 }; - System.out.println("Maximum Sub array sum is " + maxSumSubArray(arr)); - System.out.println("Maximum Sub array product is " + maxProductSubArray(arr)); - } -} diff --git a/src/geeksforgeeks/MaximumSubstringWithKDistinctChar.java b/src/geeksforgeeks/MaximumSubstringWithKDistinctChar.java deleted file mode 100644 index 65963f7..0000000 --- a/src/geeksforgeeks/MaximumSubstringWithKDistinctChar.java +++ /dev/null @@ -1,75 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; -import java.util.Map; - -/** - * https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/ - *

- * https://www.lintcode.com/problem/longest-substring-with-at-most-two-distinct-characters/description - */ -public class MaximumSubstringWithKDistinctChar { - - public static void main(String[] args) { - System.out.println(lengthOfLongestSubstringTwoDistinct("abaaaaacccddcc", 2)); - //System.out.println(lengthOfLongestSubstringKDistinct("eqgkcwGFvjjmxutystqdfhuMblWbylgjxsxgnoh", 2)); - } - - public static int lengthOfLongestSubstringTwoDistinct(String s, int k) { - Map map = new HashMap<>(); - int start = 0; - int end = 0; - int counter = 0; - int length = 0; - while (end < s.length()) { - char c = s.charAt(end); - map.put(c, map.getOrDefault(c, 0) + 1); - if (map.get(c) == 1) { - counter++;//new char - } - end++; - while (counter > k) { - char cTemp = s.charAt(start); - map.put(cTemp, map.get(cTemp) - 1); - if (map.get(cTemp) == 0) { - counter--; - } - start++; - } - length = Math.max(length, end - start); - } - return length; - } - - // improvised solution - public static int lengthOfLongestSubstringKDistinct(String s, int k) { - if (s == null || s.isEmpty()) { - return 0; - } - if (k == 0) { - return 0; - } - int start = 0; - int maxCount = 0; - int[] arr = new int[26]; - s = s.toLowerCase(); - for (int i = 0; i < s.length(); i++) { - - if (arr[s.charAt(i) - 'a'] == 0) { - k--; - } - - arr[s.charAt(i) - 'a']++; - while (k == -1) { - - arr[s.charAt(start) - 'a']--; - if (arr[s.charAt(start) - 'a'] == 0) { - k++; - } - start++; - } - maxCount = Math.max(maxCount, i - start); - } - return maxCount + 1; - } -} diff --git a/src/geeksforgeeks/MaximumUnsortedSubarray.java b/src/geeksforgeeks/MaximumUnsortedSubarray.java deleted file mode 100644 index b9a436e..0000000 --- a/src/geeksforgeeks/MaximumUnsortedSubarray.java +++ /dev/null @@ -1,90 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -//https://leetcode.com/problems/shortest-unsorted-continuous-subarray/ -/** - * Given an integer array, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order, too. - * - * You need to find the shortest such subarray and output its length. - * - * Example 1: - * Input: [2, 6, 4, 8, 10, 9, 15] - * Output: 5 - * Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order. - */ -public class MaximumUnsortedSubarray { - - public static ArrayList subarraySort(final ArrayList A) { - - final ArrayList list = new ArrayList<>(); - int start = -1; - int end = -1; - - // from left - for (int i = 1; i < A.size(); ++i) { - if (A.get(i) < A.get(i - 1)) { - start = i - 1; - break; - } - } - - // fully sorted - if (start == -1) { - list.add(-1); - return list; - } - - // from right - for (int i = A.size() - 2; i >= 0; --i) { - if (A.get(i) > A.get(i + 1)) { - end = i + 1; - break; - } - } - // [1, 3, 2, 0, -1, 7, 10] - // the initial finding gives you 3 and -1 however the original sort array is - // [1, -1, 0, 2, 3, 7, 10], - //The problem here is that the smallest number of our subarray is ‘-1’ - // which dictates that we need to include more numbers from the beginning of the array - // We will have a similar problem - //if the maximum of the subarray is bigger than some elements at the end of the array - // find min and max in the range [start, end] - int min = A.get(start); - int max = A.get(start); - for (int i = start; i <= end; ++i) { - min = Math.min(min, A.get(i)); - max = Math.max(max, A.get(i)); - } - - for (int i = 0; i < start; ++i) { - if (A.get(i) > min) { - start = i; - break; - } - } - - for (int i = A.size() - 1; i >= end + 1; --i) { - if (A.get(i) < max) { - end = i; - break; - } - } - - list.add(start); - list.add(end); - - return list; - } - - public static void main(final String[] args) { - //1, 1, 10, 10, 15, 10, 15, 10,10, 15, 10, 15 - //(1, 3, 2, 4, 5); - //4, 15, 4, 4, 15, 18, 20 - //2, 6, 1, 8, 10, 9, 15 - final List result = subarraySort(new ArrayList<>(Arrays.asList(4, 15, 4, 4, 15, 18, 20))); - result.stream().forEach(System.out::println); - } -} diff --git a/src/geeksforgeeks/MedianOfKWindow.java b/src/geeksforgeeks/MedianOfKWindow.java deleted file mode 100644 index c07539b..0000000 --- a/src/geeksforgeeks/MedianOfKWindow.java +++ /dev/null @@ -1,49 +0,0 @@ -package geeksforgeeks; - -import java.util.Collections; -import java.util.PriorityQueue; - -public class MedianOfKWindow { - public double[] medianSlidingWindow(int[] nums, int k) { - MedianQueue medianHeap= new MedianQueue(); - - double[] result= new double[nums.length-k+1]; - - int resultIndex=0; - - for( int i=0;i minQueue= new PriorityQueue<>(); - PriorityQueue maxQueue= new PriorityQueue<>(Collections.reverseOrder()); - - public void offer(int x){ - maxQueue.offer(x); - minQueue.offer(maxQueue.poll()); - if(maxQueue.size() minQueue.size() ? maxQueue.peek() : ((long)maxQueue.peek() + minQueue.peek()) * 0.5; - } - public int size(){ - return minQueue.size() + maxQueue.size(); - } - - public boolean remove(int x){ - return minQueue.remove(x) || maxQueue.remove(x); - } - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MedianOfRunningIntegers.java b/src/geeksforgeeks/MedianOfRunningIntegers.java deleted file mode 100644 index d9f05ca..0000000 --- a/src/geeksforgeeks/MedianOfRunningIntegers.java +++ /dev/null @@ -1,45 +0,0 @@ -package geeksforgeeks; - -import java.util.Collections; -import java.util.PriorityQueue; - -/** - * https://leetcode.com/problems/find-median-from-data-stream/ - */ -public class MedianOfRunningIntegers { - - PriorityQueue min = new PriorityQueue<>(); - PriorityQueue max = new PriorityQueue<>(Collections.reverseOrder()); - - // 6,8,1,4,9,2,3,5 - // median is a middle element in sorted array - // in a sorted array if we choose a point the immediate left to that point is maxLeft (max of all left) - // the immediate right to that point is minRight (min of all right) - // to mimic that here the right(max) values are stored in min heap - // the left(min) values are stored in maxheap - public void addNum(int num) { - max.offer(num); - min.offer(max.poll()); - if (max.size() < min.size()) { - max.offer(min.poll()); - } - } - - public double findMedian() { - if (max.size() == min.size()) { - return (max.peek() + min.peek()) / 2.0; - } else { - return max.peek(); - } - } - - public static void main(String[] args) { - MedianOfRunningIntegers median = new MedianOfRunningIntegers(); - int A[] = { 5, 15, 1, 3, 2, 8, 7, 9, 10, 6, 11, 4 }; - for (int num : A) { - median.addNum(num); - System.out.println(median.findMedian()); - } - } - -} diff --git a/src/geeksforgeeks/MedianOfTwoSortedArrays.java b/src/geeksforgeeks/MedianOfTwoSortedArrays.java deleted file mode 100644 index 7bd3ce0..0000000 --- a/src/geeksforgeeks/MedianOfTwoSortedArrays.java +++ /dev/null @@ -1,79 +0,0 @@ -package geeksforgeeks; - -/** - * https://github.com/mission-peace/interview/blob/master/src/com/interview/binarysearch/MedianOfTwoSortedArrayOfDifferentLength.java - */ -public class MedianOfTwoSortedArrays { - - public double findMedianSortedArrays(int[] input1, int[] input2) { - //if input1 length is greater than switch them so that input1 is smaller than input2. - if (input1.length > input2.length) { - return findMedianSortedArrays(input2, input1); - } - int x = input1.length; - int y = input2.length; - - // the whole idea is to partition the 2 arrays so that the left side and right side has same number of elements - // let's take example A= 1,3,7 and B= 2,6,8,9,10 - // so if we assume both are combined the median would be at 6(6+7/2= 6.5 to be exact) - - // first take (low + high) / 2 for A it'd be 1 in this example. we partition at 1, [1 ||, 3,7] (1 element on left and 2 on right) - // for B we need to do this, {(x + y + 1) / 2 - partitionX} = (3+5+1/2)-1=3 [2,6,8||,9,10] (3 elements on left and 2 on right) - // add the total left and right elements for both arrays would come to be equal 3+1(left partition) and 2+2(right partition) - - // the reason to add 1 ((x + y + 1) / 2 ) is to account for both odd and even lengths - // for odd length the left half should be greater, the +1 is to adjust for that - - int low = 0; - int high = x; - while (low <= high) { - int partitionX = (low + high) / 2; - int partitionY = (x + y + 1) / 2 - partitionX; - - //if partitionX is 0 it means nothing is there on left side to partition. [|| 1] Use -INF for maxLeftX - //if partitionX is length of input then there is nothing on right side. Use +INF for minRightX - - // to understand it further let's take an edge case A=[2] B=[1,3] - // partitionX=0+1/2 => 0 - // partitionY= 1+2+1/2 - 0 => 2 , the partition would look like this - // A= [-inf || 2] - // B= [2,3 || +inf] - int maxLeftX = (partitionX == 0) ? Integer.MIN_VALUE : input1[partitionX - 1]; - int minRightX = (partitionX == x) ? Integer.MAX_VALUE : input1[partitionX]; - - int maxLeftY = (partitionY == 0) ? Integer.MIN_VALUE : input2[partitionY - 1]; - int minRightY = (partitionY == y) ? Integer.MAX_VALUE : input2[partitionY]; - - // for the example given above, at right partition the elements would be grouped like below - // A=> 1,3 || 7 - // B=> 2,6 || 8,9,10 - // 3<8 and 6<7 so we take max of left and min of right - - if (maxLeftX <= minRightY && maxLeftY <= minRightX) { - //We have partitioned array at correct place - // Now get max of left elements and min of right elements to get the median in case of even length combined array size - // or get max of left for odd length combined array size. - if ((x + y) % 2 == 0) { - return ((double) Math.max(maxLeftX, maxLeftY) + Math.min(minRightX, minRightY)) / 2; - } else { - return Math.max(maxLeftX, maxLeftY); - } - } else if (maxLeftX > minRightY) { //we are too far on right side for partitionX. Go on left side. - high = partitionX - 1; - } else { //we are too far on left side for partitionX. Go on right side. - low = partitionX + 1; - } - } - - //Only we we can come here is if input arrays were not sorted. Throw in that scenario. - throw new IllegalArgumentException(); - } - - public static void main(String[] args) { - int[] x = { 1, 3, 8, 9, 15, 17 }; - int[] y = { 7, 11, 18, 19, 21, 25 }; - // 1,3,7,8,9,11,15,18,19,21,25 - MedianOfTwoSortedArrays mm = new MedianOfTwoSortedArrays(); - System.out.println(mm.findMedianSortedArrays(x, y)); - } -} diff --git a/src/geeksforgeeks/MeetingRoomsII.java b/src/geeksforgeeks/MeetingRoomsII.java deleted file mode 100644 index ee6705e..0000000 --- a/src/geeksforgeeks/MeetingRoomsII.java +++ /dev/null @@ -1,63 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -/** - * https://www.lintcode.com/problem/meeting-rooms-ii/ - */ - -public class MeetingRoomsII { - /** - * @param intervals: an array of meeting time intervals - * - * @return: the minimum number of conference rooms required - */ - // [(0,30),(5,10),(15,20)] - public int minMeetingRooms(List intervals) { - if (intervals == null || intervals.size() == 0) { - return -1; - } - - Collections.sort(intervals, Comparator.comparingInt(a -> a.start)); - - PriorityQueue queue = new PriorityQueue<>(); - queue.offer(intervals.get(0).end); - for (int i = 1; i < intervals.size(); i++) { - Interval temp = intervals.get(i); - if (queue.peek() <= temp.start) { - queue.poll(); - } - queue.offer(temp.end); - } - - return queue.size(); - - } - - // Input: schedule = [[[1,2],[5,6]],[[1,3]],[[4,10]]] - // Output: [[3,4]] - - public List employeeFreeTime(List> schedule) { - PriorityQueue que = new PriorityQueue<>((a, b) -> a.start - b.start); - - for (List list : schedule) { - for (Interval i : list) { - que.add(i); - } - } - - List rt = new ArrayList<>(); - int max = -1; - while (!que.isEmpty()) { - Interval top = que.poll(); - if (max != -1 && top.start > max) { - rt.add(new Interval(max, top.start)); - } - max = Math.max(max, top.end); - } - - return rt; - } - - -} diff --git a/src/geeksforgeeks/MergeIntervalIntersection.java b/src/geeksforgeeks/MergeIntervalIntersection.java deleted file mode 100644 index 2282f95..0000000 --- a/src/geeksforgeeks/MergeIntervalIntersection.java +++ /dev/null @@ -1,42 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.List; - -/** - * -Given two lists of closed intervals, each list of intervals is pairwise disjoint and in sorted order. -Return the intersection of these two interval lists. - -Input: A = [[0,2],[5,10],[13,23],[24,25]], B = [[1,5],[8,12],[15,24],[25,26]] -Output: [[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]] - */ -public class MergeIntervalIntersection { - - // inorder to find a overlapping part alone between two intervals - // we take - // start = max(a.start, b.start) - // end = min(a.end, b.end) - // That is, the highest start time and the lowest end time will be the overlapping interval. - public int[][] intervalIntersection(int[][] A, int[][] B) { - int i=0; - int j=0; - List result= new ArrayList<>(); - while(i=B[j][0] && A[i][0]<=B[j][1] || - B[j][0]>=A[i][0] && B[j][0]<=A[i][1]){ // this condition checks if there'a ovelapping - //A=>[0,2], B=> [1,5] - result.add(new int[]{Math.max(A[i][0],B[j][0]), Math.min(A[i][1],B[j][1])}); - } - // once added to result move the i or j based on lesser end time - if(A[i][1] a[0] - b[0]); - Arrays.sort(intervals, (i1, i2) -> Integer.compare(i1[0], i2[0]));*/ - Arrays.sort(intervals, Comparator.comparingInt(i -> i[0])); - - List result = new ArrayList<>(); - int[] prevInterval = intervals[0]; - result.add(prevInterval); - for (int[] currInterval : intervals) { - if (currInterval[0] <= prevInterval[1]) // Overlapping intervals, move the end if needed - { - prevInterval[1] = Math.max(prevInterval[1], currInterval[1]); - } else { // Disjoint intervals, add the new interval to the list - prevInterval = currInterval; - result.add(prevInterval); - } - } - return result.toArray(new int[result.size()][]); - } - - public static void main(String[] args) { - // [[1,3],[2,6],[8,10],[15,18]] - int[][] arr = { { 1, 9 }, { 6, 8 }, { 2, 4 }, { 4, 7 } }; - //{ { 1, 3 }, { 2, 4 }, { 5, 7 }, { 6, 8 } }; - //{{1, 9}, {2, 4}, {4, 7}, {6, 8}}; - System.out.println(Arrays.deepToString(merge(arr))); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MergeSortLinkedList.java b/src/geeksforgeeks/MergeSortLinkedList.java deleted file mode 100644 index d9eaf1b..0000000 --- a/src/geeksforgeeks/MergeSortLinkedList.java +++ /dev/null @@ -1,80 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/merge-sort-for-linked-list/ - */ -public class MergeSortLinkedList { - - public static ListNode sortList(ListNode head) { - if (head == null || head.next == null) { - return head; - } - // step 1. cut the list to two halves - ListNode prev = null; - ListNode slow = head; - ListNode fast = head; - // find the mid node - while (fast != null && fast.next != null) { - prev = slow; - slow = slow.next; - fast = fast.next.next; - } - prev.next = null; - // step 2. sort each half - ListNode l1 = sortList(head); - ListNode l2 = sortList(slow); - // step 3. merge l1 and l2 - return merge(l1, l2); - } - - static ListNode merge(ListNode l1, ListNode l2) { - ListNode node = new ListNode(0); - ListNode temp = node; - while (l1 != null && l2 != null) { - if (l1.val < l2.val) { - temp.next = l1; - l1 = l1.next; - } else { - temp.next = l2; - l2 = l2.next; - } - temp = temp.next; - } - if (l1 != null) { - temp.next = l1; - } - if (l2 != null) { - temp.next = l2; - } - return node.next; - } - - public static void main(String[] args) { - ListNode head = new ListNode(1); - head.next = new ListNode(5); - head.next.next = new ListNode(3); - head.next.next.next = new ListNode(2); - head.next.next.next.next = new ListNode(4); - ListNode listNode = sortList(head); - while (listNode != null) { - System.out.println(listNode.val); - listNode = listNode.next; - } - } - -} - -class ListNode { - - ListNode next; - int val; - - public ListNode(int val) { - this.val = val; - } - - @Override - public String toString() { - return "ListNode{val=" + val + '}'; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MergeTwoLinkedList.java b/src/geeksforgeeks/MergeTwoLinkedList.java deleted file mode 100644 index 8e879ea..0000000 --- a/src/geeksforgeeks/MergeTwoLinkedList.java +++ /dev/null @@ -1,46 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/merge-two-sorted-linked-lists/ - */ -public class MergeTwoLinkedList { - - public static ListNode mergeTwoLists(ListNode l1, ListNode l2) { - if (l1 == null) { - return l2; - } else if (l2 == null) { - return l1; - } - ListNode dummy = new ListNode(0); - ListNode curr = dummy; - while (l1 != null && l2 != null) { - if (l1.val <= l2.val) { - curr.next = l1; - l1 = l1.next; - } else { - curr.next = l2; - l2 = l2.next; - } - curr = curr.next; - } - curr.next = l1 == null ? l2 : l1; - return dummy.next; - } - - public static void main(String[] args) { - ListNode l1 = new ListNode(1); - l1.next = new ListNode(2); - l1.next.next = new ListNode(3); - l1.next.next.next = new ListNode(4); - - ListNode l2 = new ListNode(1); - // l2.next = new ListNode(7); - - ListNode head = mergeTwoLists(l1, l2); - - while (head != null) { - System.out.println(head.val); - head = head.next; - } - } -} diff --git a/src/geeksforgeeks/MinCostRopeConnect.java b/src/geeksforgeeks/MinCostRopeConnect.java deleted file mode 100644 index cab85b9..0000000 --- a/src/geeksforgeeks/MinCostRopeConnect.java +++ /dev/null @@ -1,34 +0,0 @@ -package geeksforgeeks; - -import java.util.PriorityQueue; - -/** - * https://www.geeksforgeeks.org/connect-n-ropes-minimum-cost/ - */ -public class MinCostRopeConnect { - - // 6 + 4 = 10 .. 10 + 3 = 13 .. 13 +2 = 15 - - // 2+3 = 5 .. 5 + 4 = 9 .. 9 + 6 = 15 .. - - public static void main(String[] args) { - int arr[] = { 4, 3, 2, 6 }; - - MinCostRopeConnect rope = new MinCostRopeConnect(); - rope.connectRopes(arr); - } - - private void connectRopes(int[] arr) { - PriorityQueue pq = new PriorityQueue<>(); - for (int i : arr) - pq.add(i); - - while (pq.size() > 1) { - Integer remove = pq.remove(); - Integer remove2 = pq.remove(); - - System.out.println("cost" + (remove + remove2)); - pq.add(remove + remove2); - } - } -} diff --git a/src/geeksforgeeks/MinStepsToConvertXtoY.java b/src/geeksforgeeks/MinStepsToConvertXtoY.java deleted file mode 100644 index bc520e2..0000000 --- a/src/geeksforgeeks/MinStepsToConvertXtoY.java +++ /dev/null @@ -1,49 +0,0 @@ -package geeksforgeeks; - -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Set; - -class MinStepsToConvertXtoY { - private static class GFG{ - int val; - int steps; - GFG(int source, int steps){ - this.val=source; - this.steps=steps; - } - } - private static int minOperations(int src, int target) { - - Set visited = new HashSet<>(1000); - LinkedList queue = new LinkedList(); - - GFG node = new GFG(src, 0); - - queue.offer(node); - visited.add(node); - - while (!queue.isEmpty()) { - GFG temp = queue.poll(); - visited.add(temp); - - if (temp.val == target) { - return temp.steps; - } - - int mul = temp.val * 2; - int sub = temp.val - 1; - - // given constraints - if (mul > 0 && mul < 1000) { - GFG nodeMul = new GFG(mul, temp.steps + 1); - queue.offer(nodeMul); - } - if (sub > 0 && sub < 1000) { - GFG nodeSub = new GFG(sub, temp.steps + 1); - queue.offer(nodeSub); - } - } - return -1; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MinTimeRotOranges.java b/src/geeksforgeeks/MinTimeRotOranges.java deleted file mode 100644 index 5b1dfac..0000000 --- a/src/geeksforgeeks/MinTimeRotOranges.java +++ /dev/null @@ -1,102 +0,0 @@ -package geeksforgeeks; - -import java.util.LinkedList; -import java.util.Queue; - -/** - * https://github.com/bibhas-abhishek/projects/tree/master/MinTimeRotOranges - * https://www.geeksforgeeks.org/minimum-time-required-so-that-all-oranges-become-rotten/ - */ - -public class MinTimeRotOranges { - - private class Pair { - - private int x; - private int y; - - public Pair(int x, int y) { - this.x = x; - this.y = y; - } - - @Override - public String toString() { - return x + "" + y; - } - - } - - private boolean hasFreshOrange(int[][] grid) { - for (int i = 0; i < grid.length; i++) { - for (int j = 0; j < grid[0].length; j++) { - if (grid[i][j] == 1) { - return true; - } - } - } - return false; - } - - private boolean isDelimiter(Pair p) { - return p.x == -1 && p.y == -1; - } - - private boolean isValidFresh(int row, int col, int[][] grid) { - int maxRow = grid.length; - int maxCol = grid[0].length; - return row >= 0 && row < maxRow && col >= 0 && col < maxCol && grid[row][col] == 1; - } - - private void rotOranges(Queue queue, Pair p, int[][] grid) { - int[] xMoves = { 1, -1, 0, 0 }; - int[] yMoves = { 0, 0, 1, -1 }; - for (int k = 0; k < xMoves.length; k++) { - int x = p.x + xMoves[k]; - int y = p.y + yMoves[k]; - if (isValidFresh(x, y, grid)) { - grid[x][y] = 2; - queue.add(new Pair(x, y)); - } - } - } - - public int findMinTime(int[][] grid) { - int result = 0; - Queue queue = new LinkedList<>(); - for (int i = 0; i < grid.length; i++) { - for (int j = 0; j < grid[0].length; j++) { - if (grid[i][j] == 2) { - queue.add(new Pair(i, j)); - } - } - } - - if (queue.isEmpty()) { - return -1; - } - - queue.add(new Pair(-1, -1)); - while (!queue.isEmpty()) { - Pair p = queue.poll(); - if (!isDelimiter(p)) { - rotOranges(queue, p, grid); - } else if (!queue.isEmpty()) { - queue.add(p); // add back delimiter - result += 1; - } - } - - if (hasFreshOrange(grid)) { - return -1; - } - - return result; - } - - public static void main(String[] args) { - int grid[][] = { { 2, 1, 0, 1, 1 }, { 1, 0, 2, 1, 1 }, { 1, 1, 1, 1, 1 } }; - System.out.println(new MinTimeRotOranges().findMinTime(grid)); - } - -} \ No newline at end of file diff --git a/src/geeksforgeeks/MinimumBribes.java b/src/geeksforgeeks/MinimumBribes.java deleted file mode 100644 index 2107aa4..0000000 --- a/src/geeksforgeeks/MinimumBribes.java +++ /dev/null @@ -1,50 +0,0 @@ -package geeksforgeeks; -/** - * https://www.hackerrank.com/challenges/new-year-chaos/problem - * https://www.youtube.com/watch?v=UpmVTEvaXPE - * Any person in the queue can bribe the person directly in front of them to swap positions. - * If two people swap positions, they still wear the same sticker denoting their original place in line. - * One person can bribe at most two other persons. - * That is to say, if n = 8, and Person 5 bribes Person 4, the queue will look like this: 1,2,3,5,4,6,7,8. - * Fascinated by this chaotic queue, you decide you must know the minimum number of bribes that took place to get the queue into its current state! - * - * No person can bribe more than 2 persons if yes then print chaotic - * Input: 2 1 5 3 4 - * Output: 3 - * - * Input: 2 5 1 3 4 - * Output: Too chaotic - */ -public class MinimumBribes { - // input is 2 1 5 3 4, - // when index is at 2(val=>5) we see how many elements lesser than 5 is there - // if the value is greater that 2 we print too chaotic - // else we add it to result - void minimumBribes(int[] q) { - int bribes=0; - for(int i = q.length-1; i >= 0; i--) { - - if(i-1>=0 && q[i-1]==i+1){ - q[i-1]=q[i]; - q[i]=i+1; - bribes+=1; - } else if(i-2>=0 && q[i-2]==i+2){ - //2,1,5,3,4 we need to swap 2 elements to restore the array - q[i-2]=q[i-1]; - q[i-1]=q[i]; - q[i]=i+1; - bribes+=2; - }else{ - System.out.println("Too Chaotic"); - return; - } - } - System.out.println(bribes); - } - - public static void main(String[] args) { - // inputs 5,1,2,3,7,8,6,4 => too chaotic - // 1,2,5,3,7,8,6,4 => 7 - new MinimumBribes().minimumBribes(new int[]{2,1,5,3,4}); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java b/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java deleted file mode 100644 index 2f63898..0000000 --- a/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java +++ /dev/null @@ -1,52 +0,0 @@ -package geeksforgeeks; - - -/* -https://www.geeksforgeeks.org/find-the-minimum-distance-between-two-numbers/ - -Given an unsorted array arr[] and two numbers x and y, find the minimum distance between x and y in arr[]. -The array might also contain duplicates. -You may assume that both x and y are different and present in arr[]. - -Input: arr[] = {2, 5, 3, 5, 4, 4, 2, 3}, -x = 3, y = 2 -Output: Minimum distance between 3 -and 2 is 1. -Explanation:3 is at index 7 and 2 is at -index 6, so the distance is 1 -*/ - - -class MinimumDistanceBetweenTwoNumbers { - - int minDist(int arr[], int n, int x, int y) { - Integer xIndex = null; - Integer yIndex = null; - int minDist = Integer.MAX_VALUE; - - for (int i = 0; i < n; i++) { - if (arr[i] == x) { - xIndex = i; - } - if (arr[i] == y) { - yIndex = i; - } - - if (xIndex != null && yIndex != null) { - minDist = Math.min(minDist, Math.abs(xIndex - yIndex)); - } - } - return minDist == Integer.MAX_VALUE ? -1 : minDist; - } - - public static void main(String[] args) { - MinimumDistanceBetweenTwoNumbers min = new MinimumDistanceBetweenTwoNumbers(); - int arr[] = {3, 5, 4, 2, 6, 5, 6, 6, 5, 4, 8, 3}; - int arr1[] = { 3, 5, 4, 3, 1, 2, 4, 6, 5, 6, 6, 5, 4, 8, 3 }; - int n = arr.length; - int x = 3; - int y = 6; - - System.out.println("Minimum distance between " + x + " and " + y + " is " + min.minDist(arr, n, x, y)); - } -} diff --git a/src/geeksforgeeks/MinimumIndexDistanceOfMaximumNumbers.java b/src/geeksforgeeks/MinimumIndexDistanceOfMaximumNumbers.java deleted file mode 100644 index f05449b..0000000 --- a/src/geeksforgeeks/MinimumIndexDistanceOfMaximumNumbers.java +++ /dev/null @@ -1,31 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/minimum-distance-between-two-occurrences-of-maximum/ - */ -class MinimumIndexDistanceOfMaximumNumbers { - - static int minDistance(int arr[], int n) { - int maximumElement = arr[0]; - int minDist = n; - int index = 0; - - for (int i = 1; i < n; i++) { - if (maximumElement == arr[i]) { - minDist = Math.min(minDist, (i - index)); - index = i; - } else if (maximumElement < arr[i]) { - maximumElement = arr[i]; - minDist = n; - index = i; - } - } - return minDist - 1; - } - - public static void main(String[] args) { - int arr[] = { 6, 3, 1, 3, 6, 5, 4, 1 }; - int n = arr.length; - System.out.print("Minimum distance = " + minDistance(arr, n)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MinimumPathSum.java b/src/geeksforgeeks/MinimumPathSum.java deleted file mode 100644 index 58b6da4..0000000 --- a/src/geeksforgeeks/MinimumPathSum.java +++ /dev/null @@ -1,40 +0,0 @@ -package geeksforgeeks; - -class MinPathSum { - public int minPathSum(int[][] grid) { - if (grid == null || grid.length == 0) - return 0; - int dp[][] = new int[grid.length][grid[0].length]; - return getMinPathSum(0, 0, grid, dp); - } - - public int getMinPathSum(int i, int j, int[][] grid, int[][] dp) { - if (i == grid.length - 1 && j == grid[0].length - 1) - return grid[i][j]; - else if (i > grid.length - 1 || j > grid[0].length - 1) - return Integer.MAX_VALUE; - else { - if (dp[i][j] != 0) - return dp[i][j]; - dp[i][j] = grid[i][j] + Math.min(getMinPathSum(i + 1, j, grid, dp), getMinPathSum(i, j + 1, grid, dp)); - } - return dp[i][j]; - } - - public int minPathSum1(int[][] grid) { - - for(int i=1;i stack; - Integer minEle; - - MyStack() { - stack = new Stack<>(); - } - - void getMin() { - if (stack.isEmpty()) { - System.out.println("Stack is empty"); - } else { - System.out.println("Minimum Element in the " + " stack is: " + minEle); - } - } - - void peek() { - if (stack.isEmpty()) { - System.out.println("Stack is empty "); - return; - } - - Integer t = stack.peek(); - System.out.print("Top Most Element is: "); - - if (t < minEle) { - System.out.println(minEle); - } else { - System.out.println(t); - } - } - - void pop() { - if (stack.isEmpty()) { - System.out.println("Stack is empty"); - return; - } - - System.out.print("Top Most Element Removed: "); - Integer t = stack.pop(); - - if (t < minEle) { - System.out.println(minEle); - minEle = 2 * minEle - t; - } else { - System.out.println(t); - } - } - - void push(Integer x) { - if (stack.isEmpty()) { - minEle = x; - stack.push(x); - System.out.println("Number Inserted: " + x); - return; - } - - if (x < minEle) { - // x-minEle<0 - // x-minEle+x<0+x - // 2x-minEle - * https://www.techiedelight.com/chess-knight-problem-find-shortest-path-source-destination/ - */ -class MinimumStepsKnight { - - static class Cell { - int x; - int y; - int steps; - - public Cell(int x, int y, int steps) { - this.x = x; - this.y = y; - this.steps = steps; - } - - } - - // Utility method returns true if (x, y) lies - // inside Board - static boolean isInside(int x, int y, int N) { - if (x >= 1 && x <= N && y >= 1 && y <= N) { - return true; - } - return false; - } - - // Method returns minimum step - // to reach target position - static int minStepToReachTarget(int knightPos[], int targetPos[], int N) { - // x and y direction, where a knight can move - int dx[] = { -2, -1, 1, 2, -2, -1, 1, 2 }; - int dy[] = { -1, -2, -2, -1, 1, 2, 2, 1 }; - - // queue for storing states of knight in board - Queue q = new LinkedList<>(); - - // push starting position of knight with 0 distance - q.add(new Cell(knightPos[0], knightPos[1], 0)); - - Cell cell; - int x, y; - boolean visit[][] = new boolean[N + 1][N + 1]; - - // make all cell unvisited - for (int i = 1; i <= N; i++) - for (int j = 1; j <= N; j++) - visit[i][j] = false; - - // visit starting state - visit[knightPos[0]][knightPos[1]] = true; - - // loop untill we have one element in queue - while (!q.isEmpty()) { - cell = q.remove(); - - // if current cell is equal to target cell, - // return its distance - if (cell.x == targetPos[0] && cell.y == targetPos[1]) { - return cell.steps; - } - - // loop for all reachable states - for (int i = 0; i < 8; i++) { - x = cell.x + dx[i]; - y = cell.y + dy[i]; - - // If reachable state is not yet visited and - // inside board, push that state into queue - if (isInside(x, y, N) && !visit[x][y]) { - visit[x][y] = true; - q.add(new Cell(x, y, cell.steps + 1)); - } - } - } - return Integer.MAX_VALUE; - } - - public static void main(String[] args) { - int N = 30; - int[] knightPos = { 1, 1 }; - int[] targetPos = { 30, 30 }; - System.out.println(minStepToReachTarget(knightPos, targetPos, N)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MinimumSwapSortArray.java b/src/geeksforgeeks/MinimumSwapSortArray.java deleted file mode 100644 index 993d9ec..0000000 --- a/src/geeksforgeeks/MinimumSwapSortArray.java +++ /dev/null @@ -1,59 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - - -/** - * https://www.geeksforgeeks.org/minimum-number-swaps-required-sort-array/ - */ -public class MinimumSwapSortArray { - // Return the minimum number - // of swaps required to sort the array - public int minSwaps(int[] arr, int N) { - - int ans = 0; - int[] temp = Arrays.copyOfRange(arr, 0, N); - - // Hashmap which stores the - // indexes of the input array - Map h - = new HashMap<>(); - - Arrays.sort(temp); - for (int i = 0; i < N; i++) { - h.put(arr[i], i); - } - for (int i = 0; i < N; i++) { - - // This is checking whether - // the current element is - // at the right place or not - if (arr[i] != temp[i]) { - ans++; - int init = arr[i]; - - // If not, swap this element - // with the index of the - // element which should come here - swap(arr, i, h.get(temp[i])); - - // Update the indexes in - // the hashmap accordingly - h.put(init, h.get(temp[i])); - h.put(temp[i], i); - } - } - return ans; - } - - public void swap(int[] arr, int i, int j) { - int temp = arr[i]; - arr[i] = arr[j]; - arr[j] = temp; - } - - public static void main(String[] args) { - //nums = {10, 19, 6, 3, 5} - //nums = {2, 8, 5, 4} - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MinimumWindowSubsequence.java b/src/geeksforgeeks/MinimumWindowSubsequence.java deleted file mode 100644 index 4e67c90..0000000 --- a/src/geeksforgeeks/MinimumWindowSubsequence.java +++ /dev/null @@ -1,80 +0,0 @@ -package geeksforgeeks; - -/** - * Input: - * S = "abcdebdde", T = "bde" - * Output: "bcde" - * Explanation: - * "bcde" is the answer because it occurs before "bdde" which has the same length. - * "deb" is not a smaller window because the elements of T in the window must occur in order. - */ -// unresolved -public class MinimumWindowSubsequence { - public String minWindow(String S, String T) { - if (S.length() == 0 || T.length() == 0) { - return ""; - } - - /** - * we can conduct two steps by using two pointers for this probelm: - * 1. check feasibility from left to right - * 2. check optimization from right to left - * we can traverse from left to right, find a possible candidate until reach the first ending character of T - * eg: for the string s = abcdebdde and t = bde, we should traverse s string until we find first e, - * i.e. abcde, then traverse back from current "e" to find if we have other combination of bde with smaller - * length. - * @param right: fast pointer that always points the last character of T in S - * @param left: slow pointer that used to traverse back when right pointer find the last character of T in S - * @param tIndex: third pointer used to scan string T - * @param minLen: current minimum length of subsequence - * */ - int right = 0; - int minLen = Integer.MAX_VALUE; - String result = ""; - - while (right < S.length()) { - int tIndex = 0; - // use fast pointer to find the last character of T in S - while (right < S.length()) { - if (S.charAt(right) == T.charAt(tIndex)) { - tIndex++; - } - if (tIndex == T.length()) { - break; - } - right++; - } - - // if right pointer is over than boundary - if (right == S.length()) { - break; - } - - // use another slow pointer to traverse from right to left until find first character of T in S - int left = right; - tIndex = T.length() - 1; - while (left >= 0) { - if (S.charAt(left) == T.charAt(tIndex)) { - tIndex--; - } - if (tIndex < 0) { - break; - } - left--; - } - // if we found another subsequence with smaller length, update result - if (right - left + 1 < minLen) { - minLen = right - left + 1; - result = S.substring(left, right + 1); - } - // WARNING: we have to move right pointer to the next position of left pointer, NOT the next position - // of right pointer - right = left + 1; - } - return result; - } - - public static void main(String[] args) { - System.out.printf(new MinimumWindowSubsequence().minWindow("abcdebdde","bcde")); - } -} diff --git a/src/geeksforgeeks/MinimumWindowSubstring.java b/src/geeksforgeeks/MinimumWindowSubstring.java deleted file mode 100644 index d36878a..0000000 --- a/src/geeksforgeeks/MinimumWindowSubstring.java +++ /dev/null @@ -1,62 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; -import java.util.Map; - -/** - * https://leetcode.com/problems/minimum-window-substring/ - */ -class MinimumWindowSubstring { - - public static void main(String[] args) { - System.out.println(minWindow("AADOBECODEBANC", "ABC")); - System.out.println(minWindow("abcdebdde", "bde")); - } - - public static String minWindow(String s, String t) { - if (t.length() > s.length()) { - return ""; - } - Map map = new HashMap<>(); - for (char c : t.toCharArray()) { - map.put(c, map.getOrDefault(c, 0) + 1); - } - - int counter = map.size(); - - int begin = 0, end = 0; - int head = 0; - int len = Integer.MAX_VALUE; - - while (end < s.length()) { - char c = s.charAt(end); - if (map.containsKey(c)) { - map.put(c, map.get(c) - 1); - if (map.get(c) == 0) { - counter--; - } - } - end++; - - while (counter == 0) { - char tempc = s.charAt(begin); - if (map.containsKey(tempc)) { - map.put(tempc, map.get(tempc) + 1); - if (map.get(tempc) > 0) { - counter++; - } - } - if (end - begin < len) { - len = end - begin; - head = begin; - } - begin++; - } - - } - if (len == Integer.MAX_VALUE) { - return ""; - } - return s.substring(head, head + len); - } - } diff --git a/src/geeksforgeeks/MirrorBinaryTree.java b/src/geeksforgeeks/MirrorBinaryTree.java deleted file mode 100644 index 8b1e8d2..0000000 --- a/src/geeksforgeeks/MirrorBinaryTree.java +++ /dev/null @@ -1,72 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -/** - * https://www.geeksforgeeks.org/write-an-efficient-c-function-to-convert-a-tree-into-its-mirror-tree/ - *

- * Iterative Java program to convert a Binary Tree to its mirror - */ -class MirrorBinaryTree { - - static class Node { - int data; - Node left; - Node right; - } - - static Node newNode(int data) { - Node node = new Node(); - node.data = data; - node.left = node.right = null; - return (node); - } - - static void mirror(Node root) { - if (root == null) { - return; - } - - Queue q = new LinkedList<>(); - q.add(root); - - while (q.size() > 0) { - Node curr = q.poll(); - Node temp = curr.left; - curr.left = curr.right; - curr.right = temp; - - if (curr.left != null) { - q.add(curr.left); - } - if (curr.right != null) { - q.add(curr.right); - } - } - } - - static void inOrder(Node node) { - if (node == null) { - return; - } - inOrder(node.left); - System.out.print(node.data + " "); - inOrder(node.right); - } - - public static void main(String args[]) { - Node root = newNode(1); - root.left = newNode(2); - root.right = newNode(3); - root.left.left = newNode(4); - root.left.right = newNode(5); - - System.out.print("\n Inorder traversal of the" + " coned tree is \n"); - inOrder(root); - - mirror(root); - - System.out.print("\n Inorder traversal of the " + "mirror tree is \n"); - inOrder(root); - } -} diff --git a/src/geeksforgeeks/MobileKeyPadCombinations.java b/src/geeksforgeeks/MobileKeyPadCombinations.java deleted file mode 100644 index a53ea51..0000000 --- a/src/geeksforgeeks/MobileKeyPadCombinations.java +++ /dev/null @@ -1,59 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - -/** - * https://www.geeksforgeeks.org/find-possible-words-phone-digits/ - */ -public class MobileKeyPadCombinations { - - public List letterCombinations(String digits) { - List result = new ArrayList<>(); - if (digits == null || digits.length() == 0) { - return result; - } - - String[] keypad = { "--", "00", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; - - generateCombinations(digits, keypad, digits.length(), 0, new StringBuilder(), result); - return result; - } - - public void generateCombinations(String digits, String[] keypad, int len, int startIndex, StringBuilder sb, - List result) { - if (startIndex == len) { - result.add(sb.toString()); - return; - } - - for (char ch : keypad[digits.charAt(startIndex) - '0'].toCharArray()) { - sb.append(ch); - generateCombinations(digits, keypad, len, startIndex + 1, sb, result); - sb.deleteCharAt(sb.length() - 1); - } - } - - public static void main(String[] args) { - new MobileKeyPadCombinations().letterCombinations("23").stream().forEach(System.out::println); - } - - public List letterCombinationsIterative(String digits) { - LinkedList ans = new LinkedList<>(); - if (digits.isEmpty()) { - return ans; - } - String[] mapping = { "0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; - ans.add(""); - for (int i = 0; i < digits.length(); i++) { - int x = Character.getNumericValue(digits.charAt(i)); - while (ans.peek().length() == i) { - String t = ans.remove(); - for (char s : mapping[x].toCharArray()) - ans.add(t + s); - } - } - return ans; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MoveZeroes.java b/src/geeksforgeeks/MoveZeroes.java deleted file mode 100644 index 8cd4f4c..0000000 --- a/src/geeksforgeeks/MoveZeroes.java +++ /dev/null @@ -1,34 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; - -/** - * https://leetcode.com/problems/move-zeroes/ - * [[4,2,4,0,0,3,0,5,1,0]] - */ -class MoveZeroes { - - public static void main(String[] args) { - MoveZeroes mz = new MoveZeroes(); - int[] arr = { 0, 1, 0, 3, 12 }; - mz.moveZeroes(arr); - System.out.println(Arrays.toString(arr)); - } - - public void moveZeroes(int[] nums) { - if (nums == null || nums.length == 0) { - return; - } - - int insertPos = 0; - for (int num : nums) { - if (num != 0) { - nums[insertPos++] = num; - } - } - - while (insertPos < nums.length) { - nums[insertPos++] = 0; - } - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/NQueens.java b/src/geeksforgeeks/NQueens.java deleted file mode 100644 index 3a34980..0000000 --- a/src/geeksforgeeks/NQueens.java +++ /dev/null @@ -1,90 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * https://leetcode.com/problems/n-queens/ - * - * Input: 4 - * Output: [ - * [".Q..", // Solution 1 - * "...Q", - * "Q...", - * "..Q."], - * - * ["..Q.", // Solution 2 - * "Q...", - * "...Q", - * ".Q.."] - * ] - * Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above. - */ -public class NQueens { - - public List> solveNQueens(int n) { - if(n==0) return Collections.emptyList(); - - List> result= new ArrayList<>(); - char[][] board= new char[n][n]; - for(int i=0;i> result) { - - if(row==board.length){ - result.add(construct(board)); - return; - } - for(int i=0;i= 0 && j < chess.length; i--, j++) { - if (chess[i][j] == 'Q') { - return false; - } - } - //check 135 - for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) { - if (chess[i][j] == 'Q') { - return false; - } - } - return true; - } - - private List construct(char[][] chess) { - List path = new ArrayList<>(); - for (int i = 0; i < chess.length; i++) { - path.add(new String(chess[i])); - } - return path; - } - -} \ No newline at end of file diff --git a/src/geeksforgeeks/NewRoadsMST.java b/src/geeksforgeeks/NewRoadsMST.java deleted file mode 100644 index 507b751..0000000 --- a/src/geeksforgeeks/NewRoadsMST.java +++ /dev/null @@ -1,86 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; -import java.util.PriorityQueue; -import java.util.Queue; - -/** - * Given an undirected graph with n nodes labeled 1..n. Some of the nodes are already connected. - * The i-th edge connects nodes edges[i][0] and edges[i][1] together. Your task is to augment this set of edges with additional edges to connect all the nodes. - * Find the minimum cost to add new edges between the nodes such that all the nodes are accessible from each other. - * Input: n = 6, edges = [[1, 4], [4, 5], [2, 3]], newEdges = [[1, 2, 5], [1, 3, 10], [1, 6, 2], [5, 6, 5]] - * Output: 7 - * Explanation: - * There are 3 connected components [1, 4, 5], [2, 3] and [6]. - * We can connect these components into a single component by connecting node 1 to node 2 and node 1 to node 6 at a minimum cost of 5 + 2 = 7. - */ -public class NewRoadsMST { - public static void main(String[] args) { - int n = 6; - int[][] edges = {{1, 4}, {4, 5}, {2, 3}}; - int[][] newEdges = {{1, 2, 5}, {1, 3, 10}, {1, 6, 2}, {5, 6, 5}}; - System.out.println(minCost(n, edges, newEdges)); - } - - public static int minCost(int n, int[][] edges, int[][] newEdges) { - UF uf = new UF(n + 1); // + 1 because nodes are 1-based - for (int[] edge : edges) { - uf.union(edge[0], edge[1]); - } - - Queue pq = new PriorityQueue<>(newEdges.length, (e1, e2) -> Integer.compare(e1[2], e2[2])); - pq.addAll(Arrays.asList(newEdges)); - - int totalCost = 0; - // 2 because nodes are 1-based and we have 1 unused component at index 0 - while (!pq.isEmpty() && uf.count != 2) { - int[] edge = pq.poll(); - if (!uf.connected(edge[0], edge[1])) { - uf.union(edge[0], edge[1]); - totalCost += edge[2]; - } - } - return totalCost; - } -} - -class UF { - private int[] parent; // parent[i] = parent of i - private byte[] rank; // rank[i] = rank of subtree rooted at i (never more than 31) - public int count; // number of connected components - - public UF(int n) { - if (n < 0) throw new IllegalArgumentException(); - parent = new int[n]; - rank = new byte[n]; - for (int i = 0; i < n; i++) { - parent[i] = i; - } - count = n; - } - - public int find(int p) { - while (p != parent[p]) { - parent[p] = parent[parent[p]]; - p = parent[p]; - } - return p; - } - - public void union(int p, int q) { - int pr = find(p); - int qr = find(q); - if (pr == qr) return; - if (rank[pr] < rank[qr]) { - parent[pr] = qr; - } else { - parent[qr] = pr; - if (rank[pr] == rank[qr]) rank[pr]++; - } - count--; - } - - public boolean connected(int p, int q) { - return find(p) == find(q); - } -} diff --git a/src/geeksforgeeks/NextGreaterElement.java b/src/geeksforgeeks/NextGreaterElement.java deleted file mode 100644 index 78d4a42..0000000 --- a/src/geeksforgeeks/NextGreaterElement.java +++ /dev/null @@ -1,90 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -/** - * https://www.geeksforgeeks.org/next-greater-element/ - *

- * https://www.geeksforgeeks.org/find-next-greater-number-set-digits/ - */ -class NextGreaterElement { - - static int arr[] = { 1,3,4,2 }; - - // 9,1,2,3,4,5,6,7 - public static void printNGE() { - Stack s = new Stack<>(); - int[] nge = new int[arr.length]; - - for (int i = arr.length - 1; i >= 0; i--) { - - while (!s.empty() && s.peek() <= arr[i]) { - s.pop(); - } - nge[i] = s.empty() ? -1 : s.peek(); - s.push(arr[i]); - - } - for (int i = 0; i < arr.length; i++) - System.out.println(arr[i] + " --> " + nge[i]); - - } - -// Input: nums1 = [4,1,2], nums2 = [1,3,4,2]. -// Output: [-1,3,-1] -// Explanation: -// For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1. -// For number 1 in the first array, the next greater number for it in the second array is 3. -// For number 2 in the first array, there is no next greater number for it in the second array, so output -1. - public int[] nextGreaterElement(int[] findNums, int[] nums) { - int[] ret = new int[findNums.length]; - ArrayDeque stack = new ArrayDeque<>(); - HashMap map = new HashMap<>(); - for(int i = nums.length - 1; i >= 0; i--) { - while(!stack.isEmpty() && stack.peek() <= nums[i]) { - stack.pop(); - } - if(stack.isEmpty()) map.put(nums[i], -1); - else map.put(nums[i], stack.peek()); - stack.push(nums[i]); - } - for(int i = 0; i < findNums.length; i++) { - ret[i] = map.get(findNums[i]); - } - return ret; - } - -// Input: [1,2,1] -// Output: [2,-1,2] -// Explanation: The first 1's next greater number is 2; -// The number 2 can't find next greater number; -// The second 1's next greater number needs to search circularly, which is also 2. - public static int[] nextGreaterElementCircular(int[] nums){ - if(nums==null || nums.length==0) return new int[0]; - int[] result= new int[nums.length]; - int n= nums.length; - Arrays.fill(result, -1); - Deque deque= new ArrayDeque<>(); - // to mimic the circular array we iterate for 2*n because input [1,2,1] will be like [1,2,1,1,2,1] - // and we take mod of 'n' to update the correct index - for (int i = 2 * nums.length - 1; i >= 0; --i) { - - while (!deque.isEmpty() && nums[deque.peek()] <= nums[i % nums.length]) { - deque.pop(); - } - // The stack is either empty, when no "greater element" is found to the right of nums[i], - // or contains the next greater element of nums[i] at the top. - result[i % nums.length] = deque.isEmpty() ? -1 : nums[deque.peek()]; - - // Push i into stack, so that nums[i-1] will compare with nums[i] first, before falling back to - // the next greater element of nums[i] - deque.push(i % nums.length); - } - - return result; - } - - public static void main(String[] args) { - printNGE(); - } -} diff --git a/src/geeksforgeeks/NextGreaterNumber.java b/src/geeksforgeeks/NextGreaterNumber.java deleted file mode 100644 index 94d532d..0000000 --- a/src/geeksforgeeks/NextGreaterNumber.java +++ /dev/null @@ -1,76 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; - -/** - * https://www.geeksforgeeks.org/find-next-greater-number-set-digits/ - *

- * https://www.ideserve.co.in/learn/next-greater-number-using-same-digits - */ -public class NextGreaterNumber { - - // If all digits sorted in descending order, then output is always “Not Possible”. For example, 4321. - // If all digits are sorted in ascending order, then we need to swap last two digits. For example, 1234. - // For other cases, we need to process the number from rightmost side - //(why? because we need to find the smallest of all greater numbers) - - // Traverse the given number from rightmost digit, - //keep traversing till you find a digit which is smaller than the previously traversed digit. - //For example, if the input number is “534976”, we stop at 4 because 4 is smaller than next digit 9. - // If we do not find such a digit, then output is “Not Possible”. - // II) Now search the right side of above found digit ‘d’ for the smallest digit greater than ‘d’. - // For “534976″, the right side of 4 contains “976”. The smallest digit greater than 4 is 6. - // III) Swap the above found two digits, we get 536974 in above example. - // IV) Now sort all digits from position next to ‘d’ to the end of number. - //The number that we get after sorting is the output. - //For above example, we sort digits in bold 536974. We get “536479” which is the next greater number for input 534976. - public int nextGreaterElement(int n) { - - char[] arr = String.valueOf(n).toCharArray(); - - int i = arr.length - 2; - // I) Start from the right most digit and - // find the first digit that is - // smaller than the digit next to it. - while (i >= 0 && arr[i] >= arr[i + 1]) - i--; - - // If no such digit is found, its the edge case 1. - if (i < 0) return -1; - - // II) Find the smallest digit on right side of (i)'th - // digit that is greater than number[i] - int j = arr.length - 1; - while (arr[j] <= arr[i]) - j--; - - swap(arr, i, j); - reverse(arr, i + 1, arr.length - 1); - - try { - return Integer.valueOf(String.valueOf(arr)); - } catch (NumberFormatException e) { - return -1; - } -} - -static void swap(char[] arr, int i, int j) { - arr[i] ^= arr[j]; - arr[j] ^= arr[i]; - arr[i] ^= arr[j]; -} - -static void reverse(char[] arr, int i, int j) { - int l = i, h = j; - while (l < h) - swap(arr, l++, h--); -} - - - public static void main(String[] args) { - NextGreaterNumber solution = new NextGreaterNumber(); - - System.out.println("Next greater number is: "+solution.nextGreaterElement(6938652)); - - } -} diff --git a/src/geeksforgeeks/NextLargestList.java b/src/geeksforgeeks/NextLargestList.java deleted file mode 100644 index 735e08c..0000000 --- a/src/geeksforgeeks/NextLargestList.java +++ /dev/null @@ -1,58 +0,0 @@ -package geeksforgeeks; - -import java.util.Stack; - -/** - * https://leetcode.com/problems/next-greater-node-in-linked-list/ - */ -class NextLargestList { - - public int[] nextLargerNodes(ListNode head) { - - if (head == null) { - return new int[0]; - } - int size = getSize(head); - int[] result = new int[size]; - head = reverse(head); - Stack stack = new Stack<>(); - stack.push(head.val); - head = head.next; - int i = size - 2; - result[size - 1] = 0; - while (head != null) { - - while (!stack.isEmpty() && stack.peek() <= head.val) { - stack.pop(); - } - result[i] = stack.isEmpty() ? 0 : stack.peek(); - stack.push(head.val); - head = head.next; - i--; - } - - return result; - } - - public int getSize(ListNode head) { - int size = 0; - ListNode root = head; - while (root != null) { - root = root.next; - size++; - } - return size; - } - - public ListNode reverse(ListNode head) { - ListNode root = head; - ListNode prev = null; - while (root != null) { - ListNode next = root.next; - root.next = prev; - prev = root; - root = next; - } - return prev; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/Node.java b/src/geeksforgeeks/Node.java deleted file mode 100644 index 04e0bb8..0000000 --- a/src/geeksforgeeks/Node.java +++ /dev/null @@ -1,82 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/remove-bst-keys-outside-the-given-range/ - */ -class RemoveBSTGivenOutsideRange { - - private static BSTNode removeOutsideRange(BSTNode root, int min, int max) { - if (root == null) { - return null; - } - - root.left = removeOutsideRange(root.left, min, max); - root.right = removeOutsideRange(root.right, min, max); - - if (root.data < min) { - BSTNode rchild = root.right; - root = null; - return rchild; - } - - if (root.data > max) { - BSTNode lchild = root.left; - root = null; - return lchild; - } - return root; - } - - public static BSTNode newNode(int num) { - BSTNode temp = new BSTNode(); - temp.data = num; - temp.left = null; - temp.right = null; - return temp; - } - - public static BSTNode insert(BSTNode root, int data) { - if (root == null) { - return newNode(data); - } - if (root.data > data) { - root.left = insert(root.left, data); - } else { - root.right = insert(root.right, data); - } - return root; - } - - private static void inorderTraversal(BSTNode root) { - if (root != null) { - inorderTraversal(root.left); - System.out.print(root.data + " "); - inorderTraversal(root.right); - } - } - - public static void main(String[] args) { - BSTNode root = null; - root = insert(root, 6); - root = insert(root, -13); - root = insert(root, 14); - root = insert(root, -8); - root = insert(root, 15); - root = insert(root, 13); - root = insert(root, 7); - - System.out.print("Inorder Traversal of " + "the given tree is: "); - inorderTraversal(root); - - root = removeOutsideRange(root, -10, 13); - - System.out.print("\nInorder traversal of " + "the modified tree: "); - inorderTraversal(root); - } -} - -class BSTNode { - int data; - BSTNode left; - BSTNode right; -} diff --git a/src/geeksforgeeks/NonDecreasingArray.java b/src/geeksforgeeks/NonDecreasingArray.java deleted file mode 100644 index 8c7bb2e..0000000 --- a/src/geeksforgeeks/NonDecreasingArray.java +++ /dev/null @@ -1,31 +0,0 @@ -package geeksforgeeks; - -/** - * https://leetcode.com/problems/non-decreasing-array/description/ - */ -class NonDecreasingArray { - - public boolean checkPossibility(int[] nums) { - - int count = 0; - for (int i = 1; i < nums.length && count <= 1; i++) { - if (nums[i - 1] > nums[i]) { - count++; - if ((i - 2 < 0) || nums[i - 2] <= nums[i]) { - nums[i - 1] = nums[i]; - } else { - nums[i] = nums[i - 1]; - } - } - } - return count <= 1; - } - - public static void main(String[] args) { - // 1,4,2,3 - // //3,4,2,3 - int[] nums = { 7, 8, 2, 3 }; - NonDecreasingArray nda = new NonDecreasingArray(); - System.out.println(nda.checkPossibility(nums)); - } -} diff --git a/src/geeksforgeeks/NumberOfBallons.java b/src/geeksforgeeks/NumberOfBallons.java deleted file mode 100644 index 1923824..0000000 --- a/src/geeksforgeeks/NumberOfBallons.java +++ /dev/null @@ -1,24 +0,0 @@ -package geeksforgeeks; - -/** - * https://leetcode.com/problems/maximum-number-of-balloons/discuss/382401/WithComments-StraightForward-Java-Simple-count-of-chars - */ -public class NumberOfBallons { - - public static int maxNumberOfBalloons(String text) { - int[] chars = new int[26]; //count all letters - for (char c : text.toCharArray()) { - chars[c - 'a']++; - } - int min = chars[1];//for b - min = Math.min(min, chars[0]);//for a - min = Math.min(min, chars[11] / 2);// for l /2 - min = Math.min(min, chars[14] / 2);//similarly for o/2 - min = Math.min(min, chars[13]);//for n - return min; - } - - public static void main(String[] args) { - maxNumberOfBalloons("llonbioan"); - } -} diff --git a/src/geeksforgeeks/NutsAndBoltsMatch.java b/src/geeksforgeeks/NutsAndBoltsMatch.java deleted file mode 100644 index 43f609b..0000000 --- a/src/geeksforgeeks/NutsAndBoltsMatch.java +++ /dev/null @@ -1,74 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/nuts-bolts-problem-lock-key-problem/ - * Java program to solve nut and bolt problem using Quick Sort - */ -public class NutsAndBoltsMatch { - - public static void main(String[] args) { - // Nuts and bolts are represented as array of characters - char nuts[] = { '@', '#', '$', '%', '^', '&' }; - char bolts[] = { '$', '%', '&', '^', '@', '#' }; - - // Method based on quick sort which matches nuts and bolts - matchPairs(nuts, bolts, 0, 5); - - System.out.println("Matched nuts and bolts are : "); - printArray(nuts); - System.out.println(); - printArray(bolts); - } - - // Method to print the array - private static void printArray(char[] arr) { - for (char ch : arr) { - System.out.print(ch + " "); - } - System.out.print("n"); - } - - // Method which works just like quick sort - private static void matchPairs(char[] nuts, char[] bolts, int low, int high) { - if (low < high) { - - // Choose last character of bolts array for nuts partition. - int pivot = partition(nuts, low, high, bolts[high]); - - // Now using the partition of nuts choose that for bolts partition. - partition(bolts, low, high, nuts[pivot]); - - // Recur for [low...pivot-1] & [pivot+1...high] for nuts and - // bolts array. - matchPairs(nuts, bolts, low, pivot - 1); - matchPairs(nuts, bolts, pivot + 1, high); - } - } - - // Similar to standard partition method. Here we pass the pivot element - // too instead of choosing it inside the method. - private static int partition(char[] arr, int low, int high, char pivot) { - int i = low; - char temp1, temp2; - for (int j = low; j < high; j++) { - if (arr[j] < pivot) { - temp1 = arr[i]; - arr[i] = arr[j]; - arr[j] = temp1; - i++; - } else if (arr[j] == pivot) { - temp1 = arr[j]; - arr[j] = arr[high]; - arr[high] = temp1; - j--; - } - } - temp2 = arr[i]; - arr[i] = arr[high]; - arr[high] = temp2; - - // Return the partition index of an array based on the pivot - // element of other array. - return i; - } -} diff --git a/src/geeksforgeeks/OverlappingIntervals.java b/src/geeksforgeeks/OverlappingIntervals.java deleted file mode 100644 index f81b9f0..0000000 --- a/src/geeksforgeeks/OverlappingIntervals.java +++ /dev/null @@ -1,42 +0,0 @@ -package geeksforgeeks; - -import java.util.PriorityQueue; - -/** - * Given a collection of intervals, find the minimum number of intervals - * you need to remove to make the rest of the intervals non-overlapping. - * Input: [[1,2],[2,3],[3,4],[1,3]] - Output: 1 - Explanation: [1,3] can be removed and the rest of intervals are non-overlapping. - Input: [[1,2],[1,2],[1,2]] - Output: 2 - Explanation: You need to remove two [1,2] to make the rest of intervals non-overlapping. - */ - -public class OverlappingIntervals{ - - public int eraseOverlapIntervals(int[][] intervals) { - if(intervals.length==0) return 0; - - PriorityQueue queue = new PriorityQueue((a, b) -> Integer.compare(a[0],b[0])); - - for(int[] interval: intervals){ - queue.offer(interval); - } - int result=0; - - int end= queue.poll()[1]; - - while(!queue.isEmpty()){ - if(end>queue.peek()[0]) { - result++; - end=Math.min(end, queue.poll()[1]); - }else{ - end=queue.poll()[1]; - } - } - - return result; - } - -} \ No newline at end of file diff --git a/src/geeksforgeeks/OwnDataStructureUtil.java b/src/geeksforgeeks/OwnDataStructureUtil.java deleted file mode 100644 index 6ba7527..0000000 --- a/src/geeksforgeeks/OwnDataStructureUtil.java +++ /dev/null @@ -1,56 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -/** - * https://leetcode.com/problems/insert-delete-getrandom-o1/ - */ -class OwnDataStructureUtil { - ArrayList list; - HashMap map; - Random rand = new Random(); - - public OwnDataStructureUtil() { - list = new ArrayList<>(); - map = new HashMap<>(); - } - - public boolean insert(int val) { - if (map.containsKey(val)) { - return false; - } - map.put(val, list.size()); - list.add(val); - return true; - } - - public boolean remove(int val) { - if (!map.containsKey(val)) { - return false; - } - int loc = map.get(val); - if (loc < list.size() - 1) { // not the last one than swap the last one with this val - int lastOne = list.get(list.size() - 1); - list.set(loc, lastOne); - map.put(lastOne, loc); - } - map.remove(val); - list.remove(list.size() - 1); - return true; - } - - public int getRandom() { - return list.get(rand.nextInt(list.size())); - } - - public static void main(String[] args) { - OwnDataStructureUtil ds = new OwnDataStructureUtil(); - ds.insert(10); - ds.insert(20); - ds.insert(30); - ds.insert(40); - ds.remove(20); - ds.insert(50); - System.out.println(ds.getRandom()); - } -} diff --git a/src/geeksforgeeks/PalindromePartion.java b/src/geeksforgeeks/PalindromePartion.java deleted file mode 100644 index 58ed043..0000000 --- a/src/geeksforgeeks/PalindromePartion.java +++ /dev/null @@ -1,52 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -//https://leetcode.com/problems/palindrome-partitioning/ -/* -Given a string s, partition s such that every substring of the partition is a palindrome. - -Return all possible palindrome partitioning of s. - -Input: "aab" -Output: -[ - ["aa","b"], - ["a","a","b"] -] - */ -class PalindromePartion { - public List> partition(String s) { - List> res = new ArrayList>(); - List list = new ArrayList(); - dfs(s, 0, list, res); - return res; - } - - public void dfs(String s, int pos, List list, List> res) { - if (pos == s.length()) { - res.add(new ArrayList(list)); - return; - } - - for (int i = pos; i < s.length(); i++) { - if (isPal(s, pos, i)) { - list.add(s.substring(pos, i + 1)); - dfs(s, i + 1, list, res); - list.remove(list.size() - 1); - } - } - - } - - public boolean isPal(String s, int low, int high) { - while (low < high) if (s.charAt(low++) != s.charAt(high--)) return false; - return true; - } - - public static void main(String[] args) { - new PalindromePartion().partition("aab"); - } - - -} \ No newline at end of file diff --git a/src/geeksforgeeks/PalindromePartitioning.java b/src/geeksforgeeks/PalindromePartitioning.java deleted file mode 100644 index bc76432..0000000 --- a/src/geeksforgeeks/PalindromePartitioning.java +++ /dev/null @@ -1,57 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * https://leetcode.com/problems/palindrome-partitioning/ - */ -class PalindromePartitioning { - - public List> partition(String s) { - - if (s == null || s.length() == 0) { - return Collections.emptyList(); - } - - List> result = new ArrayList<>(); - backtrackingUtil(s, result, new ArrayList<>()); - - return result; - } - - public void backtrackingUtil(String s, List> result, List tempList) { - if (s == null || s.length() == 0) { - result.add(new ArrayList<>(tempList)); - return; - } - - for (int i = 1; i <= s.length(); i++) { - String temp = s.substring(0, i); - if (isPalindrome(temp)) { - tempList.add(temp); - backtrackingUtil(s.substring(i, s.length()), result, tempList); - tempList.remove(tempList.size() - 1); - } - } - } - - public boolean isPalindrome(String s) { - int start = 0; - int end = s.length() - 1; - while (start <= end) { - if (s.charAt(start) != s.charAt(end)) { - return false; - } - start++; - end--; - } - return true; - } - - public static void main(String[] args) { - PalindromePartitioning partitioning = new PalindromePartitioning(); - partitioning.partition("aab"); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/PalindromeSinglyLinkedList.java b/src/geeksforgeeks/PalindromeSinglyLinkedList.java deleted file mode 100644 index 2bee7a4..0000000 --- a/src/geeksforgeeks/PalindromeSinglyLinkedList.java +++ /dev/null @@ -1,64 +0,0 @@ -package geeksforgeeks; - -/** - * https://leetcode.com/problems/palindrome-linked-list/ - */ -public class PalindromeSinglyLinkedList { - - class Node { - int data; - Node next; - - public Node(int data) { - this.data = data; - } - - } - - public static void main(String[] args) { - - PalindromeSinglyLinkedList palindrome = new PalindromeSinglyLinkedList(); - Node head = palindrome.new Node(1); - head.next = palindrome.new Node(2); - head.next.next = palindrome.new Node(3); - head.next.next.next = palindrome.new Node(2); - head.next.next.next.next = palindrome.new Node(1); - - System.out.println(palindrome.isPalindrome(head)); - - } - - public boolean isPalindrome(Node head) { - Node fast = head, slow = head; - while (fast != null && fast.next != null) { - fast = fast.next.next; - slow = slow.next; - } - if (fast != null) { // odd nodes: let right half smaller - slow = slow.next; - } - slow = reverse(slow); - fast = head; - - while (slow != null) { - if (fast.data != slow.data) { - return false; - } - fast = fast.next; - slow = slow.next; - } - return true; - } - - public Node reverse(Node slow) { - Node prev = null; - while (slow != null) { - Node next = slow.next; - slow.next = prev; - prev = slow; - slow = next; - } - return prev; - } - -} diff --git a/src/geeksforgeeks/PalindromicSubSequence.java b/src/geeksforgeeks/PalindromicSubSequence.java deleted file mode 100644 index 5a54ffc..0000000 --- a/src/geeksforgeeks/PalindromicSubSequence.java +++ /dev/null @@ -1,52 +0,0 @@ -package geeksforgeeks; - -/** - * Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000. - * Input: "cbbd" - * Output: 2 - * - * - */ -class PalindromicSubSequence { - // genral solution if s[l]==s[r] ? 2 + longestPalindromeSubseq(l+1,r-1, s) : - // max(longestPalindromeSubseq(l+1,r, s),longestPalindromeSubseq(l,r-1, s)); - public int longestPalindromeSubseq(String s) { - if(s==null || s.length()==0) return 0; - - int[][] dp= new int[s.length()][s.length()]; - - for(int i=s.length()-1;i>=0;i--){ - for(int j=i;j= 0; i--) { - dp[i] = 1; - int pre = 0; - for (int j = i + 1; j < s.length(); j++) { - int tmp = dp[j]; - if (s.charAt(i) == s.charAt(j)) { - dp[j] = pre + 2; - } else { - dp[j] = Math.max(dp[j], dp[j - 1]); - } - pre = tmp; - } - } - return dp[s.length() - 1]; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/PartitionLabel.java b/src/geeksforgeeks/PartitionLabel.java deleted file mode 100644 index 0be26c0..0000000 --- a/src/geeksforgeeks/PartitionLabel.java +++ /dev/null @@ -1,50 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.List; - -/** - * https://leetcode.com/problems/partition-labels/ - * A string S of lowercase English letters is given. - * We want to partition this string into as many parts as possible - * so that each letter appears in at most one part, and return a list of integers representing the size of these parts. - * - * Input: S = "ababcbacadefegdehijhklij" - * Output: [9,7,8] - * Explanation: - * The partition is "ababcbaca", "defegde", "hijhklij". - * This is a partition so that each letter appears in at most one part. - * A partition like "ababcbacadefegde", "hijhklij" is incorrect, because it splits S into less parts. - */ -class PartitionLabel { - - public List partitionLabels(String str) { - - int[] last = new int[26]; - for (int i = 0; i < str.length(); ++i) - // find last appearance of the char - last[str.charAt(i) - 'a'] = i; - - int j = 0; - int anchor = 0; - List ans = new ArrayList<>(); - for (int i = 0; i < str.length(); ++i) { - // find the max of j and last appearance of str[i] - j = Math.max(j, last[str.charAt(i) - 'a']); - if (i == j) { - // it is (1+i-anchor) - int length = i - anchor + 1; - ans.add(length); - anchor = i + 1; - } - } - return ans; - } - - public static void main(String[] args) { - String S = "ababcbacadefegdehijhklij"; - PartitionLabel partition = new PartitionLabel(); - System.out.println(partition.partitionLabels(S)); - - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/PascalsTriangle.java b/src/geeksforgeeks/PascalsTriangle.java deleted file mode 100644 index 5ec7791..0000000 --- a/src/geeksforgeeks/PascalsTriangle.java +++ /dev/null @@ -1,70 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * https://leetcode.com/problems/pascals-triangle/ - *

- * Input: 5 - * Output: - * [ - * [1], - * [1,1], - * [1,2,1], - * [1,3,3,1], - * [1,4,6,4,1] - * ] - */ -public class PascalsTriangle { - - public List> generate(int numRows) { - - if (numRows == 0) { - return Collections.emptyList(); - } - - List> result = new ArrayList<>(); - List first = Arrays.asList(1); - result.add(first); - if (numRows == 1) { - return result; - } - List second = Arrays.asList(1, 1); - result.add(second); - if (numRows == 2) { - return result; - } - - for (int i = 2; i < numRows; i++) { - List temp = new ArrayList<>(); - temp.add(1); - for (int k = 0; k < i - 1; k++) { - int j = k + 1; - temp.add(result.get(i - 1).get(k) + result.get(i - 1).get(j)); - } - temp.add(1); - result.add(temp); - } - return result; - } - - public List> generate1(int numRows) { - List> allrows = new ArrayList>(); - ArrayList row = new ArrayList(); - for (int i = 0; i < numRows; i++) { - // suppose if the row is [1,3,3,1] - // add 1 at start [1,1,3,3,1] - // then add together j and j+1 elements like below - // [1,4,3,3,1] => [1,4,6,3,1]=>[1,4,6,4,1] - row.add(0, 1); - for (int j = 1; j < row.size() - 1; j++) - row.set(j, row.get(j) + row.get(j + 1)); - allrows.add(new ArrayList(row));// every time the copy is only appended - } - return allrows; - - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/PathSumIII.java b/src/geeksforgeeks/PathSumIII.java deleted file mode 100644 index cbf173a..0000000 --- a/src/geeksforgeeks/PathSumIII.java +++ /dev/null @@ -1,48 +0,0 @@ -package geeksforgeeks; - - -import java.util.HashMap; -import java.util.Map; - -public class PathSumIII { - Map h= new HashMap<>(); - int count=0; - - public void preorder(TreeNode node, int currSum, int k) { - if (node == null) - return; - - // current prefix sum - currSum += node.val; - - // here is the sum we're looking for - if (currSum == k) - count++; - - // number of times the curr_sum − k has occured already, - // determines the number of times a path with sum k - // has occurred upto the current node - count += h.getOrDefault(currSum - k, 0); - - // add the current sum into hashmap - // to use it during the child nodes processing - h.put(currSum, h.getOrDefault(currSum, 0) + 1); - - // process left subtree - preorder(node.left, currSum, k); - // process right subtree - preorder(node.right, currSum, k); - - // remove the current sum from the hashmap - // in order not to use it during - // the parallel subtree processing - h.put(currSum, h.get(currSum) - 1); - } - - public int pathSumAlter(TreeNode root, int sum) { - int k = sum; - preorder(root, 0, k); - return count; - } - -} \ No newline at end of file diff --git a/src/geeksforgeeks/Pattern132.java b/src/geeksforgeeks/Pattern132.java deleted file mode 100644 index 26a95cf..0000000 --- a/src/geeksforgeeks/Pattern132.java +++ /dev/null @@ -1,33 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; - -/*https://leetcode.com/problems/132-pattern/discuss/94089/Java-solutions-from-O(n3)-to-O(n)-for-%22132%22-pattern-(updated-with-one-pass-slution)*/ -public class Pattern132 { - - public static boolean find132pattern(int[] arr) { - - int[] temp = Arrays.copyOf(arr, arr.length); - - for (int i = 1; i < arr.length; i++) { - temp[i] = Math.min(arr[i - 1], temp[i - 1]); - } - // {3, 3, 3, 1, 1, 1, 1, 1} - - for (int j = arr.length - 1, top = arr.length; j >= 0; j--) { - if (arr[j] <= temp[j]) - continue; - while (top < arr.length && temp[top] <= temp[j]) - top++; - if (top < arr.length && arr[j] > temp[top]) - return true; - temp[--top] = arr[j]; - } - return false; - } - - public static void main(String[] args) { - int[] arr = { 3, 4, 1, 2, 9, 6, 7, 8 }; - find132pattern(arr); - } -} diff --git a/src/geeksforgeeks/PerfectSquare.java b/src/geeksforgeeks/PerfectSquare.java deleted file mode 100644 index 78f9b80..0000000 --- a/src/geeksforgeeks/PerfectSquare.java +++ /dev/null @@ -1,74 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -class PerfectSquare { - // let's solve by dynamic programming approach - // if we take value 13, the number of perfect squares less than - // the input at any point is Sqrt(input)=>(sqrt(13)=3, so max it can have answer below) - // 3,because 4*4 is 16, so perfect squares below 13 are (1*1, 2*2, 3*3) - // 13 can be broken down into - // 1/ 4| \ 9 deducting 1^2 leaves with val 12 - // / | \ deducting 2^2 leaves with val 9 - // 12 9 4 deducting 3^2 leaves with val 4 - // /|\ /|\ /| - // / | \ 8 5 0 3 0 - // 11 7 3 - - public int numSquaresDp(int n) { - int[] ns = new int[n+1]; - Arrays.fill(ns , -1); - ns[0] = 0; - for(int i=1;i0;j--){ - int result = i - j*j; - // the reason to add 1 to the ns[result] is, we take away - // a square from 'i' initially (j*j) and check for best answer in the 1-D arr - // we add back the 'taken out' square to min value - // for e.x if i=13, sqrt is 3, while iterating - // we subtract 1*1 from 13 and check for best possible answer for 12 ns[result] - // finally we add back the 1*1 as +1 (ns[result]+1) - min = Math.min(min, ns[result]+1); - } - ns[i] = min; - System.out.println(Arrays.toString(ns)); - } - return ns[n]; - } - - public int numSquares(int n){ - Queue q = new LinkedList<>(); - Set visited = new HashSet<>(); - q.offer(0); - visited.add(0); - int depth = 0; - while (!q.isEmpty()) { - int size = q.size(); - depth++; - while (size > 0) { - int removed = q.poll(); - for (int i = 1; i * i <= n; i++) { - int v = removed + i * i; - if (v == n) { - return depth; - } - if (v > n) { - break; - } - if (!visited.contains(v)) { - q.offer(v); - visited.add(v); - } - } - size--; - } - } - return depth; - } - - public static void main(String[] args) { - new PerfectSquare().numSquaresDp(13); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/PermutationInString.java b/src/geeksforgeeks/PermutationInString.java deleted file mode 100644 index cbda049..0000000 --- a/src/geeksforgeeks/PermutationInString.java +++ /dev/null @@ -1,62 +0,0 @@ -package geeksforgeeks; - -/** - * Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. - * In other words, one of the first string's permutations is the substring of the second string. - * Input:s1= "ab" s2 = "eidboaoo" - * Output: False - *

- * https://leetcode.com/problems/permutation-in-string/ - */ -public class PermutationInString { - - // How do we know string p is a permutation of string s? Easy, each character in p is in s too. - // So we can abstract all permutation strings of s to a map (Character -> Count). i.e. abba -> {a:2, b:2}. - // Since there are only 26 lower case letters in this problem, - // we can just use an array to represent the map. - // How do we know string s2 contains a permutation of s1? - // We just need to create a sliding window with length of s1, - // move from beginning to the end of s2. - // When a character moves in from right of the window, - // we subtract 1 to that character count from the map. - // When a character moves out from left of the window, we add 1 to that character count. - // So once we see all zeros in the map, - // meaning equal numbers of every characters between s1 and - // the substring in the sliding window, we know the answer is true. - public static boolean checkInclusion(String s1, String s2) { - if (s1.length() == 0 || s2.length() == 0) { - return false; - } - int[] cache = new int[26]; - for (char s : s1.toCharArray()) { - cache[s - 'a']++; - } - - int right = 0; - - while (right < s2.length()) { - cache[s2.charAt(right) - 'a']--; - if (right >= s1.length()) { - cache[s2.charAt(right - s1.length()) - 'a']++; // sliding the window - } - if (allZero(cache)) { - return true; - } - right++; - } - return false; - } - - public static boolean allZero(int[] cache) { - for (int i = 0; i < 26; i++) { - if (cache[i] > 0) { - return false; - } - } - return true; - } - - public static void main(String[] args) { - System.out.println(checkInclusion("ab", "eidbaoo")); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/PetrolGasStation.java b/src/geeksforgeeks/PetrolGasStation.java deleted file mode 100644 index 03a61f2..0000000 --- a/src/geeksforgeeks/PetrolGasStation.java +++ /dev/null @@ -1,37 +0,0 @@ -package geeksforgeeks; - -public class PetrolGasStation { - - // gas means amount of gas which we have in our car - // cost means amount of gas to reach next station - public static int canCompleteCircuit(int[] gas, int[] cost) { - int sumGas = 0; - int sumCost = 0; - int start = 0; - int tank = 0; - for (int i = 0; i < gas.length; i++) { - sumGas += gas[i]; - sumCost += cost[i]; - } - if (sumGas < sumCost) { - return -1; - } - - for (int i = 0; i < gas.length; i++) { - tank += gas[i] - cost[i]; - if (tank < 0) { - start = i + 1; - tank = 0; - } - } - return start; - } - - public static void main(String[] args) { - - int[] gas = { 4, 6, 7, 4 }; - int[] cost = { 6, 5, 3, 5 }; - int start = canCompleteCircuit(gas, cost); - System.out.println(start == -1 ? "No Solution" : "Start = " + start); - } -} diff --git a/src/geeksforgeeks/PlusOne.java b/src/geeksforgeeks/PlusOne.java deleted file mode 100644 index ba4b78c..0000000 --- a/src/geeksforgeeks/PlusOne.java +++ /dev/null @@ -1,38 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; - -/** - * https://leetcode.com/problems/plus-one/ - */ -class PlusOne { - - public static int[] plusOne(int[] digits) { - - int n = digits.length; - // move along the input array starting from the end - for (int idx = n - 1; idx >= 0; --idx) { - // set all the nines at the end of array to zeros - if (digits[idx] == 9) { - digits[idx] = 0; - } - // here we have the rightmost not-nine - else { - // increase this rightmost not-nine by 1 - digits[idx]++; - // and the job is done - return digits; - } - } - // we're here because all the digits are nines - digits = new int[n + 1]; - digits[0] = 1; - return digits; - } - - public static void main(String[] args) { - int[] digits = { 1, 2, 9 }; - int[] endpointUrl = plusOne(digits); - Arrays.stream(endpointUrl).forEach(System.out::println); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/Pow.java b/src/geeksforgeeks/Pow.java deleted file mode 100644 index 829f624..0000000 --- a/src/geeksforgeeks/Pow.java +++ /dev/null @@ -1,52 +0,0 @@ -package geeksforgeeks; - -/** - * Implement pow(x, n), which calculates x raised to the power n (i.e. xn). - * - * Example 1: - * - * Input: x = 2.00000, n = 10 - * Output: 1024.00000 - * Example 2: - * - * Input: x = 2.10000, n = 3 - * Output: 9.26100 - */ -public class Pow { - - public double myPow(double x, int n) { - - if (n < 0) { - n *= -1; - x = 1 / x; - } - double result = 1; - - result = powerCalcUtil(x, n); - return result; - } - - - public double powerCalcUtil(double x, int n) { - if (n == 0) - return 1; - - double half = powerCalcUtil(x, n / 2); - if (n % 2 == 0) { - return half * half; - } else { - return half * half * x; - } - } - - public double pow1(double x, int n) { - double result = 1.0; - for(int i = n; i != 0; i /= 2, x *= x) { - if( i % 2 != 0 ) { - result *= x; - } - } - return n < 0 ? 1.0 / result : result; - } - -} \ No newline at end of file diff --git a/src/geeksforgeeks/PrisonAfterNDays.java b/src/geeksforgeeks/PrisonAfterNDays.java deleted file mode 100644 index 5436dd0..0000000 --- a/src/geeksforgeeks/PrisonAfterNDays.java +++ /dev/null @@ -1,54 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; -import java.util.HashSet; -/* -https://leetcode.com/problems/prison-cells-after-n-days/ - */ - -class PrisonAfterNDays { - - public static int[] prisonAfterNDays(int[] cells, int N) { - if (cells == null || cells.length == 0 || N <= 0) { - return cells; - } - boolean hasCycle = false; - int cycle = 0; - HashSet set = new HashSet<>(); - for (int i = 0; i < N; i++) { - int[] next = nextDay(cells); - String key = Arrays.toString(next); - if (!set.contains(key)) { //store cell state - set.add(key); - cycle++; - } else { //hit a cycle - hasCycle = true; - break; - } - cells = next; - } - if (hasCycle) { - N %= cycle; // calculating the reminder day after excluding the cycle - // let's say N=10 and we hit cycle at 3, we need 10%3=1 remaining calculation - // to be done - for (int i = 0; i < N; i++) { - cells = nextDay(cells); - } - } - return cells; - } - - private static int[] nextDay(int[] cells) { - int[] tmp = new int[cells.length]; - for (int i = 1; i < cells.length - 1; i++) { - tmp[i] = cells[i - 1] == cells[i + 1] ? 1 : 0; - } - return tmp; - } - - public static void main(String[] args) { - int[] cells = { 0, 1, 0, 1, 1, 0, 0, 1 }; - int N = 7; - System.out.println(Arrays.toString(prisonAfterNDays(cells, N))); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/ProductExceptSelf.java b/src/geeksforgeeks/ProductExceptSelf.java deleted file mode 100644 index d25d922..0000000 --- a/src/geeksforgeeks/ProductExceptSelf.java +++ /dev/null @@ -1,52 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; - -/** - * https://leetcode.com/problems/product-of-array-except-self/ - *

- * Given numbers [2, 3, 4, 5], regarding the third number 4, - * the product of array except 4 is 2*3*5 which consists of two parts: left 2*3 and right 5. - * The product is left*right. We can get lefts and rights - *

- * Numbers: 2 3 4 5 - * Lefts: 2 2*3 2*3*4 - * Rights: 3*4*5 4*5 5 - *

- * Let’s fill the empty with 1: - *

- * Numbers: 2 3 4 5 - * Lefts: 1 2 2*3 2*3*4 - * Rights: 3*4*5 4*5 5 1 - */ -public class ProductExceptSelf { - public static int[] productExceptSelf(int[] nums) { - int n = nums.length; - int[] res = new int[n]; - res[0] = 1; - - for (int i = 1; i < n; i++) { - res[i] = res[i - 1] * nums[i - 1]; - } - // once building the left product instead of having a new array to calculate rightsum - // we use a variable to store last seen value - // for number 2 3 4 5 - // the left product array is 1 2 2*3 2*3*4 - - // for rightProd during step1 2 3 4 5 right is 1 so last product value retained - // 2*3*4 - // during step 2 the right becomes 5(1*nums[i]=>5) - // so for value 4(length-2) the left product is 2*3 multiplying with 5 becomes 2*3*5 - // during step 3 the right is updated to (5*nums[i]=>4) 20 - int right = 1; - for (int i = n - 1; i >= 0; i--) { - res[i] *= right; - right *= nums[i]; - } - return res; - } - - public static void main(String[] args) { - System.out.println(Arrays.toString(productExceptSelf(new int[] { 1, 2, 3, 4, 5 }))); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/QueensAttackKing.java b/src/geeksforgeeks/QueensAttackKing.java deleted file mode 100644 index 88a6860..0000000 --- a/src/geeksforgeeks/QueensAttackKing.java +++ /dev/null @@ -1,54 +0,0 @@ -package geeksforgeeks; - -import java.util.*; -//https://leetcode.com/problems/queens-that-can-attack-the-king/submissions/ - -/** - * On an 8x8 chessboard, there can be multiple Black Queens and one White King. - * - * Given an array of integer coordinates queens that represents the positions of the Black Queens, - * and a pair of coordinates king that represent the position of the White King, - * return the coordinates of all the queens (in any order) that can attack the King. - */ -class QueensAttackKing { - public List> queensAttacktheKing(int[][] queens, int[] king) { - List> result= new ArrayList<>(); - boolean[][] visited= new boolean[8][8]; - int[][]dirs= {{1,0},{-1,0},{0,1},{0,-1},{-1,-1},{1,1},{1,-1},{-1,1}}; - // first marking all queen positions - for(int[] qu:queens){ - visited[qu[0]][qu[1]]=true; - } - - for(int[] dir: dirs){ - List temp= findQueensPositions(king,dir[0],dir[1],visited); - if(temp!=null) result.add(temp); - } - - return result; - - } - - public List findQueensPositions(int[] king, int xDir, int yDir, boolean[][] visited){ - int newX= xDir+king[0]; - int newY= yDir+king[1]; - // going to walk along x,y only not 8 directions at same time - while(newX<8 && newY<8 && newX>=0 && newY>=0){ - if(visited[newX][newY]){ - return Arrays.asList(newX,newY); // returns when first queen is met in row or column - } - - newX+=xDir; - newY+=yDir; - - } - - return null; - } - - public static void main(String[] args) { - int[][] queens= {{0,1},{1,0},{4,0},{0,4},{3,3},{2,4}}; - int[] king= {0,0}; - new QueensAttackKing().queensAttacktheKing(queens, king); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/RaceCarMinSteps.java b/src/geeksforgeeks/RaceCarMinSteps.java deleted file mode 100644 index 0f26001..0000000 --- a/src/geeksforgeeks/RaceCarMinSteps.java +++ /dev/null @@ -1,45 +0,0 @@ -package geeksforgeeks; - -import java.util.*; -class RaceCarMinSteps { - public int racecar(int target) { - Set visited = new HashSet<>(); - Queue queue = new LinkedList<>(); - queue.add(new StateNode(1, 0)); - int distance = 0; - while (!queue.isEmpty()) { - int levelSize = queue.size(); - for (int i = 0; i < levelSize; i++) { - StateNode cur = queue.poll(); - if (cur.position == target) { - return distance; - } - // if A - int nextPosition = cur.position + cur.speed; - int nextSpeed = cur.speed * 2; - if (!visited.contains(nextSpeed + "," + nextPosition) && Math.abs(target - nextPosition) < target) { - visited.add(nextSpeed + "," + nextPosition); - queue.offer(new StateNode(nextSpeed, nextPosition)); - } - // if R - nextPosition = cur.position; - nextSpeed = cur.speed > 0 ? -1 : 1; - if (!visited.contains(nextSpeed + "," + nextPosition) && Math.abs(target - nextPosition) < target) { - visited.add(nextSpeed + "," + nextPosition); - queue.offer(new StateNode(nextSpeed, nextPosition)); - } - } - distance++; - } - return -1; - } -} - class StateNode { - int speed; - int position; - - public StateNode(int speed, int position) { - this.speed = speed; - this.position = position; - } - } \ No newline at end of file diff --git a/src/geeksforgeeks/RandomLinkedList.java b/src/geeksforgeeks/RandomLinkedList.java deleted file mode 100644 index 2e0070e..0000000 --- a/src/geeksforgeeks/RandomLinkedList.java +++ /dev/null @@ -1,62 +0,0 @@ -package geeksforgeeks; - -/** - * https://leetcode.com/problems/copy-list-with-random-pointer/ - */ -class RandomLinkedList { - - public LLNode copyRandomList(LLNode head) { - if (head == null) { - return null; - } - LLNode temp = head; - while (temp != null) { - LLNode LLNode = new LLNode(temp.val + 10, temp.next, null); - temp.next = LLNode; - temp = temp.next.next; - } - LLNode randomLLNode = head; - while (randomLLNode != null) { - randomLLNode.next.random = randomLLNode.random.next; - randomLLNode = randomLLNode.next.next; - } - LLNode copyHead = head.next; - LLNode tempHead = copyHead; - while (head != null && tempHead != null) { - head.next = head.next == null || head.next.next == null ? head.next : head.next.next; - tempHead.next = tempHead.next == null || tempHead.next.next == null ? tempHead.next : tempHead.next.next; - head = head.next; - tempHead = tempHead.next; - } - return copyHead; - } - - public static void main(String[] args) { - LLNode head = new LLNode(1, null, null); - head.next = new LLNode(2, null, null); - head.next.next = new LLNode(3, null, null); - head.next.next.next = new LLNode(4, null, null); - head.random = head.next.next; - head.next.random = head.next.next.next; - head.next.next.random = head.next; - head.next.next.next.random = head; - RandomLinkedList solution = new RandomLinkedList(); - solution.copyRandomList(head); - } -} - -class LLNode { - public int val; - public LLNode next; - public LLNode random; - - public LLNode(int _val, LLNode _next, LLNode _random) { - val = _val; - next = _next; - random = _random; - } - - public String toString() { - return "" + this.val; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/RandomPickWithWeight.java b/src/geeksforgeeks/RandomPickWithWeight.java deleted file mode 100644 index afd51fe..0000000 --- a/src/geeksforgeeks/RandomPickWithWeight.java +++ /dev/null @@ -1,54 +0,0 @@ -package geeksforgeeks; - -import java.util.stream.IntStream; - -/** - * https://leetcode.com/problems/random-pick-with-weight/ - */ -class RandomPickWithWeight { - private int sum; - private int[] sumArr; - - public RandomPickWithWeight(int[] w) { - sum = 0; - sumArr = new int[w.length]; - for (int i = 0; i < w.length; ++i) { - sum += w[i]; - sumArr[i] = sum; - } - } - - public int pickIndex() { - int idx = (int) (Math.random() * sum); - return binarySearch(idx + 1); // +1 is because the rand will lie between 0-14 - } - - public int binarySearch(int idx) { - int left = 0; - int right = sumArr.length - 1; - - while (left < right) { - int mid = ((right - left) / 2) + left; - if (sumArr[mid] < idx) { - left = mid + 1; - } else { - right = mid; - } - } - return left; - } - - public static void main(String[] args) { - RandomPickWithWeight randomPickWithWeight = new RandomPickWithWeight(new int[]{1, 3, 5, 4, 2}); - randomPickWithWeight.pickIndex(); - - //IntStream.range(0, 10).forEach(i -> System.out.println((int) (Math.random() * 3))); - } - -} - -/** - * Your Solution object will be instantiated and called as such: - * Solution obj = new Solution(w); - * int param_1 = obj.pickIndex(); - */ \ No newline at end of file diff --git a/src/geeksforgeeks/RangeSum.java b/src/geeksforgeeks/RangeSum.java deleted file mode 100644 index 32194a2..0000000 --- a/src/geeksforgeeks/RangeSum.java +++ /dev/null @@ -1,41 +0,0 @@ -package geeksforgeeks; - -/** - * 303. Range Sum Query - Immutable - * - * Given an integer array nums, - * find the sum of the elements between indices i and j (i ≤ j), inclusive. - * - * Implement the NumArray class: - * - * NumArray(int[] nums) Initializes the object with the integer array nums. - * int sumRange(int i, int j) Return the sum of the elements of the nums array in the range [i, j] - * inclusive (i.e., sum(nums[i], nums[i + 1], ... , nums[j])) - * - * ["NumArray", "sumRange", "sumRange", "sumRange"] - * [[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]] - * Output - * [null, 1, -1, -3] - * - * Explanation - * NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]); - * numArray.sumRange(0, 2); // return 1 ((-2) + 0 + 3) - * numArray.sumRange(2, 5); // return -1 (3 + (-5) + 2 + (-1)) - * numArray.sumRange(0, 5); // return -3 ((-2) + 0 + 3 + (-5) + 2 + (-1)) - */ -public class RangeSum { - int[] dp; - public void NumArray(int[] nums) { - if(nums.length==0) return ; - dp= new int[nums.length]; - dp[0]=nums[0]; - for(int i=1;i findItinerary(List> tickets) { - if(tickets==null || tickets.size()==0) return Collections.emptyList(); - - Map> map= new HashMap<>(); - - for(List ticket: tickets){ - map.putIfAbsent(ticket.get(0), new PriorityQueue<>()); - map.get(ticket.get(0)).offer(ticket.get(1)); - } - List res = new ArrayList(); - dfs(map, res, "JFK"); - return res; - } - - public void dfs( Map> map, List res, String s){ - - PriorityQueue queue= map.get(s); - - while(queue!=null && !queue.isEmpty()){ - String temp= queue.poll(); - dfs(map, res, temp); - } - - res.add(0,s); - } - } - -} \ No newline at end of file diff --git a/src/geeksforgeeks/RedundantConnection.java b/src/geeksforgeeks/RedundantConnection.java deleted file mode 100644 index c122fed..0000000 --- a/src/geeksforgeeks/RedundantConnection.java +++ /dev/null @@ -1,44 +0,0 @@ -package geeksforgeeks; - -public class RedundantConnection { - public int[] findRedundantConnection(int[][] edges) { - DisjointSet set= new DisjointSet(edges.length); - - for(int[]edge: edges){ - if(!set.union(edge[0]-1, edge[1]-1)) return edge; - } - return new int[]{-1,-1}; - } - - static class DisjointSet{ - int[] parent; - int[] rank; - - public DisjointSet(int n){ - this.parent= new int[n]; - this.rank= new int[n]; - } - - public int find(int x){ - if(parent[x]==0) return x; - return parent[x]=find(parent[x]); - } - - public boolean union(int x, int y){ - int rootX= find(x); - int rootY= find(y); - - if(rootX==rootY) return false; - - if(rank[rootX] 0 && res[i - 1] == res[i]) { - i -= 2; - } - } - return new String(res, 0, i); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/RemoveDuplicates.java b/src/geeksforgeeks/RemoveDuplicates.java deleted file mode 100644 index 328d15f..0000000 --- a/src/geeksforgeeks/RemoveDuplicates.java +++ /dev/null @@ -1,27 +0,0 @@ -package geeksforgeeks; - -/** - * https://leetcode.com/problems/remove-duplicates-from-sorted-array/ - */ -class RemoveDuplicates { - - public int removeDuplicates(int[] nums) { - if (nums == null || nums.length == 0) { - return 0; - } - int i = 0; - nums[i++] = nums[0]; - for (int j = 1; j < nums.length; j++) { - if (nums[j] != nums[j - 1]) { - nums[i++] = nums[j]; - } - } - return i; - } - - public static void main(String[] args) { - RemoveDuplicates removeDuplicates = new RemoveDuplicates(); - int[] nums = { 1, 1, 2 }; - removeDuplicates.removeDuplicates(nums); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/RemoveInvalidParentheses.java b/src/geeksforgeeks/RemoveInvalidParentheses.java deleted file mode 100644 index f9f0e59..0000000 --- a/src/geeksforgeeks/RemoveInvalidParentheses.java +++ /dev/null @@ -1,61 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -public class RemoveInvalidParentheses { - - public List removeInvalidParentheses(String s) { - if (isValid(s)) - return Collections.singletonList(s); - List ans = new ArrayList<>(); - //The queue only contains invalid middle steps - Queue queue = new LinkedList<>(); - //The 3-Tuple is (string, startIndex, lastRemovedChar) - queue.add(new Tuple(s, 0, ')')); - while (!queue.isEmpty()) { - Tuple x = queue.poll(); - //Observation 2, start from last removal position - for (int i = x.start; i < x.string.length(); ++i) { - char ch = x.string.charAt(i); - //Not parentheses - if (ch != '(' && ch != ')') continue; - //Observation 1, do not repeatedly remove from consecutive ones - if (i != x.start && x.string.charAt(i - 1) == ch) continue; - //Observation 3, do not remove a pair of valid parentheses - if (x.removed == '(' && ch == ')') continue; - String t = x.string.substring(0, i) + x.string.substring(i + 1); - //Check isValid before add - if (isValid(t)) - ans.add(t); - //Avoid adding leaf level strings - else if (ans.isEmpty()) - queue.add(new Tuple(t, i, ch)); - } - } - return ans; -} - -public static boolean isValid(String s) { - int count = 0; - for (int i = 0; i < s.length(); ++i) { - char c = s.charAt(i); - if (c == '(') ++count; - if (c == ')' && count-- == 0) return false; - } - return count == 0; -} - -} - - class Tuple { - public final String string; - public final int start; - public final char removed; - - public Tuple(String string, int start, char removed) { - this.string = string; - this.start = start; - this.removed = removed; - -} -} \ No newline at end of file diff --git a/src/geeksforgeeks/RemoveKDigits.java b/src/geeksforgeeks/RemoveKDigits.java deleted file mode 100644 index d5a2cc0..0000000 --- a/src/geeksforgeeks/RemoveKDigits.java +++ /dev/null @@ -1,60 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayDeque; -import java.util.Deque; - -/** - * https://leetcode.com/problems/remove-k-digits/ - * - * Given a non-negative integer num represented as a string, - * remove k digits from the number so that the new number is the smallest possible. - * - * Note: - * The length of num is less than 10002 and will be ≥ k. - * The given num does not contain any leading zero. - * - * Input: num = "1432219", k = 3 - * Output: "1219" - * Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest. - * - * Input: num = "10", k = 2 - * Output: "0" - * Explanation: Remove all the digits from the number and it is left with nothing which is 0. - */ - -public class RemoveKDigits { - //1432219 - public static String removeKdigits(String num, int k) { - if(num==null || num.length()==0) return null; - - Deque queue= new ArrayDeque<>(); - for(char c: num.toCharArray()){ - - while(!queue.isEmpty() && queue.getLast()>c-'0' && k>0){ - queue.removeLast(); - k--; - } - queue.addLast(c-'0'); - } - - while(k>0){ - queue.removeLast(); - k--; - } - - StringBuilder result= new StringBuilder(); - while(!queue.isEmpty()){ - result.append(queue.removeFirst()); - } - - while(result.length()>0 && result.charAt(0)=='0'){ - result.deleteCharAt(0); - } - - return result.length()==0?"0":result.toString(); - } - - public static void main(String[] args) { - System.out.println(removeKdigits("14232191", 3)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/ReorderLogs.java b/src/geeksforgeeks/ReorderLogs.java deleted file mode 100644 index b71a435..0000000 --- a/src/geeksforgeeks/ReorderLogs.java +++ /dev/null @@ -1,58 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; - -/** - * https://leetcode.com/problems/reorder-data-in-log-files/ - -You have an array of logs. Each log is a space delimited string of words. - -For each log, the first word in each log is an alphanumeric identifier. Then, either: - -Each word after the identifier will consist only of lowercase letters, or -Each word after the identifier will consist only of digits. -We will call these two varieties of logs letter-logs and digit-logs. It is guaranteed that each log has at least one word after its identifier. - -Reorder the logs so that all of the letter-logs come before any digit-log. -The letter-logs are ordered lexicographically ignoring identifier, with the identifier used in case of ties. -The digit-logs should be put in their original order. - -Input: logs = ["dig1 8 1 5 1","let1 art can","dig2 3 6","let2 own kit dig","let3 art zero"] -Output: ["let1 art can","let3 art zero","let2 own kit dig","dig1 8 1 5 1","dig2 3 6"] -*/ - -class ReorderLogs { - public static String[] reorderLogFiles(String[] logs) { - Arrays.sort(logs, (s1, s2) -> { - String[] split1 = s1.split(" ", 2); // splits arr in to 2 parts - String[] split2 = s2.split(" ", 2); - - boolean isDigit1 = Character.isDigit(split1[1].charAt(0)); - boolean isDigit2 = Character.isDigit(split2[1].charAt(0)); - - if (!isDigit1 && !isDigit2) { - // both letter-logs. - int comp = split1[1].compareTo(split2[1]); - if (comp == 0) - return split1[0].compareTo(split2[0]); - else - return comp; - } else if (isDigit1 && isDigit2) { - // both digit-logs. So keep them in original order - return 0; - } else if (isDigit1 && !isDigit2) { - // first is digit, second is letter. bring letter to forward. - return 1; - } else { - // first is letter, second is digit. keep them in this order. - return -1; - } - }); - return logs; - } - - public static void main(String[] args) { - String[] string = {"dig1 8 1 5 1", "yet1 art can", "dig2 3 6", "let2 own kit dig", "let3 art zero"}; - System.out.println(Arrays.toString(reorderLogFiles(string))); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/ReorganiseString.java b/src/geeksforgeeks/ReorganiseString.java deleted file mode 100644 index c8288f9..0000000 --- a/src/geeksforgeeks/ReorganiseString.java +++ /dev/null @@ -1,71 +0,0 @@ -package geeksforgeeks; - -/** - * Given a string S, check if the letters can be rearranged so that two characters that are adjacent to each other are not the same. - * - * If possible, output any possible result. If not possible, return the empty string. - * - * Input: S = "aab" - * Output: "aba" - * - * Input: S = "aaab" - * Output: "" - */ -class ReorganiseString { - public String reorganizeString(String s) { - if (s == null || s.length() < 1) return ""; - - int[] hash = new int[26]; - for (char c : s.toCharArray()) { - hash[c - 'a']++; - } - - int max = 0; - int letter = 0; - - for (int i = 0; i < hash.length; i++) { - if (hash[i] > max) { - max = hash[i]; - letter = i; - } - } - - if (max > (s.length() + 1) / 2) return ""; - - char[] res = new char[s.length()]; - - int pos = 0; - while (hash[letter] > 0) { - res[pos] = (char) (letter + 'a'); - pos += 2; - hash[letter]--; - } - - // We construct the resulting string in sequence: at position 0, 2, 4, ... and then 1, 3, 5, ... - // In this way, we can make sure there is always a gap between the same characters - - // Consider this example: "aaabbbcdd", we will construct the string in this way: - - // a _ a _ a _ _ _ _ // fill in "a" at position 0, 2, 4 - // a b a _ a _ b _ b // fill in "b" at position 6, 8, 1 - // a b a c a _ b _ b // fill in "c" at position 3 - // a b a c a d b d b // fill in "d" at position 5, 7 - - for (int i = 0; i < hash.length; i++) { - while (hash[i] > 0) { - if (pos >= res.length) pos = 1; - - res[pos] = (char) (i + 'a'); - pos += 2; - hash[i]--; - } - } - - return new String(res); - } - - public static void main(String[] args) { - - new ReorganiseString().reorganizeString("aabccdeeee"); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/RestoreIpAddresses.java b/src/geeksforgeeks/RestoreIpAddresses.java deleted file mode 100644 index 1aa2660..0000000 --- a/src/geeksforgeeks/RestoreIpAddresses.java +++ /dev/null @@ -1,53 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -/** - *Given a string s containing only digits, - * return all possible valid IP addresses that can be obtained from s. - * You can return them in any order. - * - * A valid IP address consists of exactly four integers, - * each integer is between 0 and 255, separated by single dots and cannot have leading zeros. - * For example, "0.1.2.201" and "192.168.1.1" are valid IP addresses and "0.011.255.245", - * "192.168.1.312" and "192.168@1.1" are invalid IP addresses. - */ - -public class RestoreIpAddresses { - public List restoreIpAddresses(String s) { - if (s == null) - return Collections.emptyList(); - List result = new ArrayList<>(); - - for (int i = 1; i < 4 && i < s.length(); i++) { - String first = s.substring(0, i); - if (isValid(first)) { - for (int j = 1; j < 4 && j + i < s.length(); j++) { - String second = s.substring(i, i + j); - if (isValid(second)) { - for (int k = 1; i + j + k < s.length() && k < 4; k++) { - String third = s.substring(i + j, i + j + k); - String fourth = s.substring(i + j + k); - if (isValid(third) && isValid(fourth)) { - result.add(first + "." + second + "." + third + "." + fourth); - } - } - } - } - } - } - return result; - } - - public boolean isValid(String part) { - if (part == null || part.length() > 3) - return false; - - if (part.charAt(0) == '0' && part.length() > 1) - return false; - - int address = Integer.parseInt(part); - - return address >= 0 && address <= 255; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/ReverseWordsInString.java b/src/geeksforgeeks/ReverseWordsInString.java deleted file mode 100644 index af5a14c..0000000 --- a/src/geeksforgeeks/ReverseWordsInString.java +++ /dev/null @@ -1,40 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; - -public class ReverseWordsInString { - - public char[] reverse(char[] arr, int i, int j) { - while (i < j) { - char tmp = arr[i]; - arr[i++] = arr[j]; - arr[j--] = tmp; - } - return arr; - } - - public String reverseWords(String s) { - // reverse the whole string and convert to char array - char[] str = reverse(s.toCharArray(), 0, s.length()-1); - int start = 0, end = 0; // start and end positions of a current word - //for input "the sky is blue" - // the char arr contians - //[e u l b s i y k s e h t] - - System.out.println(Arrays.toString(str)); - for (int i = 0; i < str.length; i++) { - if (str[i] != ' ') { // if the current char is letter - str[end++] = str[i]; // just move this letter to the next free pos - } else if (i > 0 && str[i-1] != ' ') { // if the first space after word - reverse(str, start, end-1); // reverse the word - str[end++] = ' '; // and put the space after it - start = end; // move start position further for the next word - } - } - reverse(str, start, end-1); // reverse the tail word if it's there - // here's an ugly return just because we need to return Java's String - // also as there could be spaces at the end of original string - // we need to consider redundant space we have put there before - return new String(str, 0, end > 0 && str[end-1] == ' ' ? end-1 : end); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/RollingHashRabinKarp.java b/src/geeksforgeeks/RollingHashRabinKarp.java deleted file mode 100644 index 21ff3a9..0000000 --- a/src/geeksforgeeks/RollingHashRabinKarp.java +++ /dev/null @@ -1,134 +0,0 @@ -package geeksforgeeks; - -public class RollingHashRabinKarp{ - /** - * the normal way to calculate an hash from a string would be through the following method - * for String S="abcdef" we chose a prime number which is greater that the no.of chars(26) - * we choose P=31 - * - * total hash(abcdef)= (a*P^0+ b*P^1 + c*P^2 + d*P^3 + e*P^4 + f*P^5) % M; - * %(mod) is taken to avoid overflow of values - * hash at each point is [h0, h1, h2, h3, h4, h5] - * - * this is anlogus to prefix sum, the hash at each index i is hash calculated from 0 to 'i' - * - * for h2 is hash from (a-c), in order to calculate prefix sum from index 2-4 - * - * sum(2-4)= sum(4)-sum(2) [sum 0-4 - sum 0-2], likewise we can calulate rolling hash - * - * in order to find contains subString for String size M and N, the time complexity would be O(MN) - * - * if we find the hash of String M and N seperately and somehow find if substring of size N in String M - * hashes to hash(N) we will have our result in O(M) - * - * M= SDESKILLS - * N= SKILLS - * Note: p0 or p1= P^number - * - * hash of M= [(S*p0)+(D*p1)+(E*p2)+(S*p4)+(K*p5)+(I*p6)+(L*p7)+(L*p8)+(S*p9)] % M - * - * in hashing no matter how many times/ at what posistion a string comes, it has to hash to same value - * - * if we have a hash(abcdef)= a*p0+ b*p1+ c*p2+ d*p3+ e*p4+ f*p5 - * and i need hash(cde) i need to do prefix sum analogy - * hash(cde)= hash(R)-hash(L-1) R= Right, L=Left - * but the above equation comes down to [c*p2 + d*p3+ e*p4] this is not going to yeild correct - * result for cde every time if 'cde' occurs at different index then the eq would be [c*p8+d*p9+e*p10] - * - * so what we need is to add one more part to the eq ([c*p2 + d*p3+ e*p4]/ p2) => [c*p0 + d*p1+ e*p2] - * hash(cde)= hash(R)-hash(L-1)/P^L R= Right, L=Left - * - * Hash[3,6]= (Hash(6)- Hash(2)/ p^3)%M - * - * hash([L...R]) =(hash[R] - hash[L - 1]/PL)% M - hash(s[L...R]) =(hash[R] - hash[L - 1]) * P^-L % M - - hash(s[L...R]) =(hash[R] - hash[L - 1])*(P^-1)L % M - hash(s[L...R]) =(hash[R] - hash[L - 1])% M*(P-1)L %M% M - - (A * B) % M =( (A % M) * (B % M)) % M - X = P^-1= P^M-2% M - hash(s[L...R]) =(((hash[R] - hash[L - 1])% M *X^L )% M) - */ - - - public static void main(String[] args) { - String givenValue = "abaaab"; - String input = "aaa"; - -// char[] givenArr = givenValue.toCharArray(); -// char[] inputArr = input.toCharArray(); -// -// int inputHash = createHash(inputArr, inputArr.length); -// int previousValue = 0; -// for (int i = 0; i < (givenArr.length - inputArr.length + 1); i++) { -// previousValue = givenHash(givenArr, i, previousValue); -// if (inputHash == previousValue && matchString(inputArr, givenArr, i)) { -// System.out.println("It exists"); -// } -// } - - rabinKarp(givenValue, input); - } - - private static int givenHash(char[] givenArr, int i, int previousValue) { - - if (previousValue == 0) { - return createHash(givenArr, 3); - } - - int currentValue = previousValue - givenArr[i - 1]; - System.out.println(currentValue + givenArr[i + 2] * 100); - return currentValue + givenArr[i + 2] * 100; - - } - - private static int createHash(char[] inputArr, int length) { - int hash = 0; - double power = 0; - for (int i = 0; i < length; i++) { - hash = hash + (int) Math.pow(10, power++) * inputArr[i]; - } - return hash; - } - - private static boolean matchString(char[] inputArr, char[] givenArr, int i) { - int index = 0; - for (int j = i; j < inputArr.length; j++) { - if (inputArr[index++] != givenArr[j]) { - return false; - } - } - return true; - } - - //the time complexity is O(m + n) - public static int rabinKarp(String t, String s) { - if (s.length() > t.length()) { - return -1; // s is not a substring of t. - } - final int BASE = 26; - int tHash = 0, sHash = 0; // Hash codes for the substring of t and s. - int powerS = 1; // this will be used to calculate the rolling hash when current window moves out - for (int i = 0; i < s.length(); i++) { - powerS = i > 0 ? powerS * BASE : 1; - tHash = tHash * BASE + t.charAt(i); - sHash = sHash * BASE + s.charAt(i); - } - for (int i = s.length(); i < t.length(); i++) { -// Checks the two substrings are actually equal or not, to protect -// against hash collision. - if (tHash == sHash ){ //&& t.substring(i - s.length(), i).equals(s)) { - return i - s.length(); // Found a match. - } -// Uses rolling hash to compute the new hash code. - tHash -= t.charAt(i - s.length()) * powerS; - tHash = tHash * BASE + t.charAt(i); - } -// Tries to match s and t.substring(t.length() - s.lengthO). - if (tHash == sHash){ // && t .substring(t.length() - s.length()).equals(s)){ - return t.length() - s.length(); - } - return -1; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/RomanToInteger.java b/src/geeksforgeeks/RomanToInteger.java deleted file mode 100644 index 1469c62..0000000 --- a/src/geeksforgeeks/RomanToInteger.java +++ /dev/null @@ -1,34 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -public class RomanToInteger { - - public int romanToInteger(String s) { - Map map = new HashMap(); - - map.put('I', 1); - map.put('V', 5); - map.put('X', 10); - map.put('L', 50); - map.put('C', 100); - map.put('D', 500); - map.put('M', 1000); - - int sum = map.get(s.charAt(s.length() - 1)); - for (int i = s.length() - 2; i >= 0; --i) { - if (map.get(s.charAt(i)) < map.get(s.charAt(i + 1))) { - sum -= map.get(s.charAt(i)); - } else { - sum += map.get(s.charAt(i)); - } - } - return sum; - - } - - public static void main(String[] args) { - new RomanToInteger().romanToInteger("LIX"); - } - -} \ No newline at end of file diff --git a/src/geeksforgeeks/RotateArray.java b/src/geeksforgeeks/RotateArray.java deleted file mode 100644 index fac0e62..0000000 --- a/src/geeksforgeeks/RotateArray.java +++ /dev/null @@ -1,30 +0,0 @@ -package geeksforgeeks; -/** - * Given an array, rotate the array to the right by k steps, where k is - * non-negative Could you do it in-place with O(1) extra space? - * - * - * Example 1: - * - * Input: nums = [1,2,3,4,5,6,7], k = 3 Output: [5,6,7,1,2,3,4] Explanation: - * rotate 1 steps to the right: [7,1,2,3,4,5,6] rotate 2 steps to the right: - * [6,7,1,2,3,4,5] rotate 3 steps to the right: [5,6,7,1,2,3,4] - */ -public class RotateArray { - public void rotate(int[] nums, int k) { - k %= nums.length; - reverse(nums, 0, nums.length - 1); - reverse(nums, 0, k - 1); - reverse(nums, k, nums.length - 1); - } - - public void reverse(int[] nums, int start, int end) { - while (start < end) { - int temp = nums[start]; - nums[start] = nums[end]; - nums[end] = temp; - start++; - end--; - } - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/RotateMatrixInPlace.java b/src/geeksforgeeks/RotateMatrixInPlace.java deleted file mode 100644 index 88879d9..0000000 --- a/src/geeksforgeeks/RotateMatrixInPlace.java +++ /dev/null @@ -1,102 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/inplace-rotate-square-matrix-by-90-degrees/ - */ -// looking for easy solution -class RotateMatrixInPlace { - - /** - * N/2 for time complexity o(n) - *

- * get all the corners first and swap ( rotate 90 degree) - * - * @param N - * @param mat - */ - static void rotateMatrix(int N, int mat[][]) { - // Consider all squares one by one - for (int x = 0; x < N / 2; x++) { - // Consider elements in group of 4 in - // current square - for (int y = x; y < N - x - 1; y++) { - // store current cell in temp variable - System.out.println("mat[" + x + "][" + y + "] = " + mat[x][y]); - int temp = mat[x][y]; - - // move values from right to top - System.out.println("mat[" + y + "][" + (N - 1 - x) + "] = " + mat[y][N - 1 - x]); - mat[x][y] = mat[y][N - 1 - x]; - - // move values from bottom to right - System.out.println("mat[" + (N - 1 - x) + "][" + (N - 1 - y) + "] = " + mat[N - 1 - x][N - 1 - y]); - mat[y][N - 1 - x] = mat[N - 1 - x][N - 1 - y]; - - // move values from left to bottom - System.out.println("mat[" + (N - 1 - y) + "][" + (x) + "] = " + mat[N - 1 - y][x]); - mat[N - 1 - x][N - 1 - y] = mat[N - 1 - y][x]; - - // assign temp to left - System.out.println("mat[" + (N - 1 - y) + "][" + (x) + "] = " + temp); - mat[N - 1 - y][x] = temp; - } - } - } - - public void rotate(int[][] matrix) { - if(matrix == null || matrix.length == 0 || matrix[0].length == 0)return; - int n= matrix.length-1; - - for(int i=0; i - * https://leetcode.com/problems/rotate-image/discuss/298719/A-Java-one-pass-solution-with-detailed-explanation - *

- * //x,y1=x2,y2 - * // x1=y2 - */ -class RotateMatrixInPlaceAntiClockwise { - - static void rotateMatrix(int N, int mat[][]) { - - for (int x = 0; x < N / 2; x++) { - - for (int y = x; y < N - x; y++) { - - // store current cell in temp variable - int temp = mat[x][y]; - - // move values from right to top - mat[x][y] = mat[y][N - x]; - - // move values from bottom to right - mat[y][N - x] = mat[N - x][N - y]; - - // move values from left to bottom - mat[N - x][N - y] = mat[N - y][x]; - - // assign temp to left - mat[N - y][x] = temp; - } - } - } - - static void displayMatrix(int N, int mat[][]) { - for (int i = 0; i < N; i++) { - for (int j = 0; j < N; j++) - System.out.print(" " + mat[i][j]); - - System.out.print("\n"); - } - System.out.print("\n"); - } - - public static void main(String[] args) { - int N = 4; - - // Test Case 1 - int mat[][] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } }; - - // int mat[][] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; - // int mat[][] = { {1, 2}, {4, 5} }; - - // displayMatrix(mat); - - rotateMatrix(N - 1, mat); - - // Print rotated matrix - displayMatrix(N, mat); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/SameTree.java b/src/geeksforgeeks/SameTree.java deleted file mode 100644 index 8882703..0000000 --- a/src/geeksforgeeks/SameTree.java +++ /dev/null @@ -1,62 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayDeque; - -/** - * Given two binary trees, write a function to check if they are the same or not. - * Two binary trees are considered the same if they are structurally identical and the nodes have the same value. -Input: 1 1 - / \ / \ - 2 1 1 2 - - [1,2,1], [1,1,2] - -Output: false - */ -public class SameTree { - public boolean check(TreeNode p, TreeNode q) { - // p and q are null - if (p == null || q == null) return p==q; - if (p.val != q.val) return false; - return true; - } - - public boolean isSameTree(TreeNode p, TreeNode q) { - if (p == null && q == null) return true; - if (!check(p, q)) return false; - - // init deques - ArrayDeque deqP = new ArrayDeque(); - ArrayDeque deqQ = new ArrayDeque(); - deqP.addLast(p); - deqQ.addLast(q); - - while (!deqP.isEmpty()) { - p = deqP.removeFirst(); - q = deqQ.removeFirst(); - - if (!check(p, q)) return false; - if (p != null) { - // in Java nulls are not allowed in Deque - if (!check(p.left, q.left)) return false; - if (p.left != null) { - deqP.addLast(p.left); - deqQ.addLast(q.left); - } - if (!check(p.right, q.right)) return false; - if (p.right != null) { - deqP.addLast(p.right); - deqQ.addLast(q.right); - } - } - } - return true; - } - - public boolean isSameTreeRecur(TreeNode p, TreeNode q){ - if(p==null || q==null) return p==q; - if(p.val==q.val) return true; - - return isSameTreeRecur(p.left, q.left) && isSameTreeRecur(p.right, q.right); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/SearchAMaze.java b/src/geeksforgeeks/SearchAMaze.java deleted file mode 100644 index d7e19e1..0000000 --- a/src/geeksforgeeks/SearchAMaze.java +++ /dev/null @@ -1,80 +0,0 @@ -package geeksforgeeks; - -import java.util.LinkedList; -import java.util.Queue; - -/** - * https://www.techiedelight.com/lee-algorithm-shortest-path-in-a-maze/ - */ -public class SearchAMaze { - - private static final int M = 10; - private static final int N = 10; - - private static final int row[] = { -1, 0, 0, 1 }; - private static final int col[] = { 0, -1, 1, 0 }; - - private static boolean isValid(int mat[][], int row, int col) { - return (row >= 0) && (row < M) && (col >= 0) && (col < N) && mat[row][col] == 1; - } - - private static void BFS(int mat[][], int srcX, int srcY, int destX, int destY) { - - Queue q = new LinkedList<>(); - - q.add(new MazeNode(srcX, srcY, 0)); - - int minDist = Integer.MAX_VALUE; - - while (!q.isEmpty()) { - MazeNode node = q.poll(); - - srcX = node.x; - srcY = node.y; - int dist = node.dist; - - if (srcX == destX && srcY == destY) { - minDist = dist; - break; - } - - for (int k = 0; k < 4; k++) { - if (isValid(mat, srcX + row[k], srcY + col[k])) { - mat[srcX][srcY] = 0; - MazeNode e = new MazeNode(srcX + row[k], srcY + col[k], dist + 1); - q.add(e); - System.out.println(" Adding to the queue :" + e); - } - } - } - - if (minDist != Integer.MAX_VALUE) { - System.out.print("The shortest path from source to destination " + "has length " + minDist); - } else { - System.out.print("Destination can't be reached from source"); - } - } - - public static void main(String[] args) { - int[][] mat = { { 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 }, { 0, 1, 1, 1, 1, 1, 0, 1, 0, 1 }, - { 0, 0, 1, 0, 1, 1, 1, 0, 0, 1 }, { 1, 0, 1, 1, 1, 0, 1, 1, 0, 1 }, { 0, 0, 0, 1, 0, 0, 0, 1, 0, 1 }, - { 1, 0, 1, 1, 1, 0, 0, 1, 1, 1 }, { 0, 0, 0, 0, 1, 0, 0, 1, 0, 1 }, { 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, - { 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 }, { 0, 0, 1, 0, 0, 1, 1, 0, 0, 1 } }; - - BFS(mat, 8, 0, 0, 9); - } -} - -class MazeNode { - int x, y, dist; - - MazeNode(int x, int y, int dist) { - this.x = x; - this.y = y; - this.dist = dist; - } - - public String toString() { - return "(" + x + "," + y + ") -> " + dist; - } -}; \ No newline at end of file diff --git a/src/geeksforgeeks/SearchAnElementInMatrix.java b/src/geeksforgeeks/SearchAnElementInMatrix.java deleted file mode 100644 index a8381b7..0000000 --- a/src/geeksforgeeks/SearchAnElementInMatrix.java +++ /dev/null @@ -1,74 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.youtube.com/watch?v=FOa55B9Ikfg - * https://leetcode.com/problems/search-a-2d-matrix-ii/ - * https://leetcode.com/problems/search-a-2d-matrix/ - */ - -public class SearchAnElementInMatrix { - - private static boolean searchII(int[][] mat, int n, int x) { - - int i = 0; - int j = n - 1; // set indexes for top right element - // we can start from top right corner or bottom left corner, because from - // these points only we have 2 paths one increasing one decreasing - while (i < n && j >= 0) { - if (mat[i][j] == x) { - System.out.print("n Found at " + i + " " + j); - return true; - } - if (mat[i][j] > x) { - j--; - } else // if mat[i][j] < x - { - i++; - } - } - - System.out.print("n Element not found"); - return false; - - } - - public static boolean searchI(int[][] matrix, int target) { - if (matrix == null || matrix.length == 0) { - return false; - } - int start = 0; - int rows = matrix.length; - int cols = matrix[0].length; - int end = rows * cols - 1; - while (start <= end) { - int mid = (start + end) / 2; - /** - * Another way to took at it is: lets say you have a matrix M with 4 rows and 3 columns. - * When we want to access M[2][1], the way the memory address is calculated is 2*3+1 = 7. - * so you are just reversing the calculation , row number is given by 7/3 = 2, - * and column is the offset in that row so for 7th element it is 7%3 = 1. - * This link helped me understand it. https://www.youtube.com/watch?v=n5KNdUAftC4 - */ - if (matrix[mid / cols][mid % cols] == target) { - return true; - } - if (matrix[mid / cols][mid % cols] < target) { - start = mid + 1; - } else { - end = mid - 1; - } - } - return false; - } - - public static void main(String[] args) { - int[][] mat = {{10, 20, 30, 40}, {15, 25, 35, 45}, {27, 29, 37, 48}, {32, 33, 39, 50}}; - - int[][] matI = {{1, 3, 5, 7}, {10, 11, 16, 20}, {23, 30, 34, 50}}; - - System.out.println(searchI(matI, 11)); - System.out.println(searchII(mat, 4, 33)); - - } - -} diff --git a/src/geeksforgeeks/SerializeAndDeserialize.java b/src/geeksforgeeks/SerializeAndDeserialize.java deleted file mode 100644 index 4984f4f..0000000 --- a/src/geeksforgeeks/SerializeAndDeserialize.java +++ /dev/null @@ -1,80 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; -import java.util.LinkedList; -import java.util.Queue; - -/* - Serialize and Deserialize Binary Tree - LeetCode: - https://leetcode.com/problems/serialize-and-deserialize-binary-tree/ - - This code passes all Leetcode test cases as of April 26 2019 - Runtime: 12 ms, faster than 62.25% of Java online submissions for Serialize and Deserialize Binary Tree. - Memory Usage: 39.4 MB, less than 71.37% of Java online submissions for Serialize and Deserialize Binary Tree. - - The video to explain this code is here: https://www.youtube.com/watch?v=suj1ro8TIVY -*/ - -public class SerializeAndDeserialize { - - private static final String NULL_SYMBOL = "X"; - private static final String DELIMITER = ","; - - public String serialize(TreeNode root) { - - if (root == null) { - return NULL_SYMBOL + DELIMITER; - } - - String leftSerialized = serialize(root.left); - String rightSerialized = serialize(root.right); - - return root.val + DELIMITER + leftSerialized + rightSerialized; - } - - public TreeNode deserialize(String data) { - Queue nodesLeftToMaterialize = new LinkedList<>(); - nodesLeftToMaterialize.addAll(Arrays.asList(data.split(DELIMITER))); - return deserializeHelper(nodesLeftToMaterialize); - } - - public TreeNode deserializeHelper(Queue nodesLeftToMaterialize) { - - String valueForNode = nodesLeftToMaterialize.poll(); - - if (valueForNode.equals(NULL_SYMBOL)) { - return null; - } - - TreeNode newNode = new TreeNode(Integer.parseInt(valueForNode)); - newNode.left = deserializeHelper(nodesLeftToMaterialize); - newNode.right = deserializeHelper(nodesLeftToMaterialize); - - return newNode; - } - - public static void main(String[] args) { - TreeNode root = new TreeNode(1); - root.left = new TreeNode(2); - root.right = new TreeNode(3); - root.right.left = new TreeNode(4); - root.right.right = new TreeNode(5); - SerializeAndDeserialize sede = new SerializeAndDeserialize(); - String serialize = sede.serialize(root); - System.out.println(serialize); - TreeNode deserialze = sede.deserialize(serialize); - sede.printTree(deserialze); - } - - public void printTree(TreeNode node) { - if (node == null) { - System.out.print("X,"); - return; - } - System.out.print(node.val + ","); - printTree(node.left); - printTree(node.right); - } - -} - diff --git a/src/geeksforgeeks/SerializeDeserializeBST.java b/src/geeksforgeeks/SerializeDeserializeBST.java deleted file mode 100644 index 235060e..0000000 --- a/src/geeksforgeeks/SerializeDeserializeBST.java +++ /dev/null @@ -1,76 +0,0 @@ -package geeksforgeeks; - -// Hi all, I think my solution is pretty straightforward and easy to understand, not that efficient though. And the serialized tree is compact. -// Pre order traversal of BST will output root node first, then left children, then right. - -// root left1 left2 leftX right1 rightX -// If we look at the value of the pre-order traversal we get this: - -// rootValue (rootValue) (>rootValue) -// Because of BST's property: before the |separate line| all the node values are less than root value, all the node values after |separate line| are greater than root value. We will utilize this to build left and right tree. - -import java.util.*; - -class SerializeDeserializeBST { - private static final String SEP = ","; - private static final String NULL = "null"; - // Encodes a tree to a single string. - - public String serialize(TreeNode root) { - - if (root == null) { - return NULL + SEP; - } - - String leftSerialized = serialize(root.left); - String rightSerialized = serialize(root.right); - - return root.val + SEP + leftSerialized + rightSerialized; - } - - public String serializeIterative(TreeNode root) { - StringBuilder sb = new StringBuilder(); - if (root == null) return NULL; - //traverse it recursively if you want to, I am doing it iteratively here - Deque st = new ArrayDeque<>(); - st.push(root); - while (!st.isEmpty()) { - root = st.pop(); - sb.append(root.val).append(SEP); - if (root.right != null) st.push(root.right); - if (root.left != null) st.push(root.left); - } - return sb.toString(); - } - - // Decodes your encoded data to tree. - // pre-order traversal - public TreeNode deserialize(String data) { - if (data.equals(NULL)) return null; - String[] strs = data.split(SEP); - Queue q = new LinkedList<>(); - for (String e : strs) { - q.offer(Integer.parseInt(e)); - } - return getNode(q); - } - - // some notes: - // 5 - // 3 6 - // 2 7 - private TreeNode getNode(Queue q) { //q: 5,3,2,6,7 - if (q.isEmpty()) return null; - TreeNode root = new TreeNode(q.poll());//root (5) - Queue samllerQueue = new LinkedList<>(); - while (!q.isEmpty() && q.peek() < root.val) { - samllerQueue.offer(q.poll()); - } - //smallerQueue : 3,2 storing elements smaller than 5 (root) - root.left = getNode(samllerQueue); - //q: 6,7 storing elements bigger than 5 (root) - root.right = getNode(q); - return root; - } - -} \ No newline at end of file diff --git a/src/geeksforgeeks/SetBitCount.java b/src/geeksforgeeks/SetBitCount.java deleted file mode 100644 index d3cf7a4..0000000 --- a/src/geeksforgeeks/SetBitCount.java +++ /dev/null @@ -1,21 +0,0 @@ -package geeksforgeeks; - -/** - * https://leetcode.com/problems/number-of-1-bits/discuss/55099/Simple-Java-Solution-Bit-Shifting - */ -public class SetBitCount { - public static int hammingWeight(int n) { - int count = 0; - - while (n != 0) { - n &= (n - 1); - count++; - } - - return count; - } - - public static void main(String[] args) { - System.out.println(hammingWeight(00000000000000000000000000001011)); - } -} diff --git a/src/geeksforgeeks/ShuffleArray.java b/src/geeksforgeeks/ShuffleArray.java deleted file mode 100644 index def7ad7..0000000 --- a/src/geeksforgeeks/ShuffleArray.java +++ /dev/null @@ -1,53 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; -import java.util.Random; - -/** - * https://leetcode.com/problems/shuffle-an-array/ - */ -public class ShuffleArray { - - private int[] nums; - private Random random; - - public ShuffleArray(int[] nums) { - this.nums = nums; - random = new Random(); - } - - /** - * Resets the array to its original configuration and return it. - */ - public int[] reset() { - return nums; - } - - /** - * Returns a random shuffling of the array. - */ - public int[] shuffle() { - if (nums == null) { - return null; - } - int[] a = nums.clone(); - for (int j = 1; j < a.length; j++) { - int i = random.nextInt(j + 1); - swap(a, i, j); - } - return a; - } - - private void swap(int[] a, int i, int j) { - int t = a[i]; - a[i] = a[j]; - a[j] = t; - } - - public static void main(String[] args) { - int[] arr = { 1, 2, 3 }; - ShuffleArray sa = new ShuffleArray(arr); - System.out.println("After shuffling :" + Arrays.toString(sa.shuffle())); - System.out.println("Reset : " + Arrays.toString(sa.reset())); - } -} diff --git a/src/geeksforgeeks/SimilarExpressions.java b/src/geeksforgeeks/SimilarExpressions.java deleted file mode 100644 index 5adab24..0000000 --- a/src/geeksforgeeks/SimilarExpressions.java +++ /dev/null @@ -1,55 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/check-two-expressions-brackets/ - */ -//unresolved -public class SimilarExpressions { - - public static void main(String[] args) { - - System.out.println('+' * '-'); - - String query = "-(a+b+c)"; - String response = "-a-b-c"; - - checkExpression(query.toCharArray(), response.toCharArray()); - } - - private static void checkExpression(char[] query, char[] response) { - - char symbol = 0; - int startIndex = 0; - int endIndex = 0; - for (int i = 0; i < query.length; i++) { - if (query[i] == '(') { - symbol = query[i - 1]; - startIndex = i + 1; - } else if (query[i] == ')') { - endIndex = i - 1; - solve(symbol, startIndex, endIndex, query); - - } - } - } - - private static void solve(char symbol, int startIndex, int endIndex, char[] query) { - - for (int i = startIndex; i <= endIndex; i++) { - char temp = 0; - if (query[startIndex] == '-') { - temp = '-' * '+'; - query[i] = temp; - } else if (symbol == '+') { - temp = '-'; - query[i] = temp; - } else if (Character.isLetter(query[startIndex])) { - if (startIndex == i) { - query[startIndex - 1] = temp; - } - System.out.print(query[startIndex]); - } - System.out.print(temp); - } - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/SingleElementInSortedArray.java b/src/geeksforgeeks/SingleElementInSortedArray.java deleted file mode 100644 index b2d5977..0000000 --- a/src/geeksforgeeks/SingleElementInSortedArray.java +++ /dev/null @@ -1,44 +0,0 @@ -package geeksforgeeks; - -/** - * You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once. - * Find this single element that appears only once. - */ -public class SingleElementInSortedArray { - public int singleNonDuplicate(int[] nums) { - if (nums == null || nums.length == 0) return 0; - - int left = 0; - int right = nums.length - 1; - // for 1,1,2,3,3,4,4,8,8 - // when mid is at 4 and right-mid is even, means the rest elements are only pairs, so we check - // left side by right=mid-2 - // when mid is at 3 and right-mid is odd means the 3's duplicate is present in right and rest - //are all pairs only so we check left side by right=mid-1 - // when mid is 4 => nums[mid]==nums[mid-1] - // when mid is 3 => nums[mid]==nums[mid+1] - while (left < right) { - int mid = left + (right - left) / 2; - boolean isEven = (right - mid) % 2 == 0; - - if (nums[mid] == nums[mid - 1]) { - if (isEven) { - right = mid - 2; - } else { - left = mid + 1; - } - } else if (nums[mid] == nums[mid + 1]) { - if (isEven) { - left = mid + 2; - } else { - right = mid - 1; - } - } else { - return nums[mid]; - } - - } - - return nums[left]; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/SlidingWindow.java b/src/geeksforgeeks/SlidingWindow.java deleted file mode 100644 index 4e11f6a..0000000 --- a/src/geeksforgeeks/SlidingWindow.java +++ /dev/null @@ -1,75 +0,0 @@ -package geeksforgeeks; - -import java.util.Deque; -import java.util.LinkedList; -import java.util.*; - -/** - * https://leetcode.com/problems/sliding-window-maximum/ - */ -public class SlidingWindow { - - public static void main(String[] args) { - int arr[] = { 8, 5, 10, 7, 9, 4, 15, 12, 90, 13 }; - int k = 3; - maxSlidingWindow(arr, k); - } - - public static int[] maxSlidingWindow(int[] nums, int k) { - if (nums.length == 0) { - return new int[0]; - } - if (nums.length == 1) { - return nums; - } - - List list = new ArrayList<>(); - Deque deque = new ArrayDeque<>(); - int i = 0; - - while (i < k) { - - while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) { - deque.removeLast(); - } - deque.addLast(i); - i++; - } - - for (; i < nums.length; i++) { - - list.add(nums[deque.peekFirst()]); - - if (!deque.isEmpty() && deque.peekFirst() <= i - k) { - deque.removeFirst(); - } - - while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) - deque.removeLast(); - - deque.addLast(i); - } - list.add(nums[deque.peekFirst()]); - - return list.stream().mapToInt(Integer::new).toArray(); - } - - void maxSlidingVicky(int[] nums, int k) { - List result = new ArrayList<>(); - Deque queue = new ArrayDeque<>(); - for (int i = 0; i < nums.length; i++) { - while (!queue.isEmpty() && queue.peek() < i - k + 1) { - queue.poll(); - } - while (!queue.isEmpty() && nums[queue.peekLast()] < nums[i]) { - queue.pollLast(); - } - - queue.offer(i); - - if (i >= k - 1) { - result.add(nums[queue.peekFirst()]); - } - } - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/SnakeAndLadder.java b/src/geeksforgeeks/SnakeAndLadder.java deleted file mode 100644 index c1bc484..0000000 --- a/src/geeksforgeeks/SnakeAndLadder.java +++ /dev/null @@ -1,70 +0,0 @@ -package geeksforgeeks; - -import java.util.Queue; -import java.util.*; - -/** - * https://leetcode.com/problems/snakes-and-ladders/ - */ -public class SnakeAndLadder { - class BoardCells { - int pos; - int steps; - - public BoardCells(int pos, int steps) { - this.pos = pos; - this.steps = steps; - } - } - - private int n; - - public int snakesAndLadders(int[][] board) { - n = board.length; - boolean[] visited = new boolean[n * n + 1]; - Queue queue = new LinkedList<>(); - queue.offer(new BoardCells(1, 1)); - visited[1] = true; - - while (!queue.isEmpty()) { - BoardCells cur = queue.poll(); - for (int i = 1; i <= 6; i++) { - int next = cur.pos + i; - int[] pos = numToPos(next); - if (board[pos[0]][pos[1]] > 0) { - next = board[pos[0]][pos[1]]; - } - if (next == n * n) { - return cur.steps; - } - if (!visited[next]) { - queue.offer(new BoardCells(next, cur.steps + 1)); - visited[next] = true; - } - } - - } - return queue.peek().steps; - } - - private int[] numToPos(int target) { - int row = (target - 1) / n, col = (target - 1) % n; - int x = n - 1 - row, y = row % 2 == 0 ? col : n - 1 - col; - return new int[] { x, y }; - } - - private int posToNum(int[] position) { - int row = (n - 1 - position[0]); - int y = row % 2 == 0 ? position[1] + 1 : n - position[1]; - return row * n + y; - } - - public static void main(String[] args) { - - int[][] board = { { -1, -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1, -1 }, - { -1, 35, -1, -1, 13, -1 }, { -1, -1, -1, -1, -1, -1 }, { -1, 15, -1, -1, -1, -1 } }; - - System.out.println("Min Dice throws required is " + new SnakeAndLadder().snakesAndLadders(board)); - - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/SnakeGame.java b/src/geeksforgeeks/SnakeGame.java deleted file mode 100644 index 9f7b999..0000000 --- a/src/geeksforgeeks/SnakeGame.java +++ /dev/null @@ -1,88 +0,0 @@ -package geeksforgeeks; - -import java.util.HashSet; -import java.util.LinkedList; - -public class SnakeGame { - int[][] food; - int m, n; - int headX, headY; - int eaten; - private HashSet snake; - LinkedList queue; - - /** - * Initialize your data structure here. - * - * @param width - screen width - * @param height - screen height - * @param food - A list of food positions - * E.g food = [[1,1], [1,0]] means the first food is positioned at [1,1], the second is at [1,0]. - */ - public SnakeGame(int width, int height, int[][] food) { - this.food = food; - snake = new HashSet(); - eaten = 0; - headX = 0; - headY = 0; - m = height; - n = width; - queue = new LinkedList(); - queue.offer(new int[]{0, 0}); - snake.add("0,0"); - } - - /** - * Moves the snake. - * - * @param direction - 'U' = Up, 'L' = Left, 'R' = Right, 'D' = Down - * @return The game's score after the move. Return -1 if game over. - * Game over when snake crosses the screen boundary or bites its body. - */ - public int move(String direction) { - if (direction.equals("U")) { - headX--; - } else if (direction.equals("L")) { - headY--; - } else if (direction.equals("R")) { - headY++; - } else if (direction.equals("D")) { - headX++; - } else { - System.out.println("Wrong move"); - } - - if (!isValid(headX, headY)) { - return -1; - } - - return process(headX, headY); - } - - public boolean isValid(int i, int j) { - if (i < 0 || i >= m || j < 0 || j >= n) - return false; - return true; - } - - public int process(int x, int y) { - if (eaten == food.length) { - snake.remove(queue.peek()[0] + "," + queue.peek()[1]); - queue.poll(); - } else if (food[eaten][0] == x && food[eaten][1] == y) { - eaten++; - } else { - snake.remove(queue.peek()[0] + "," + queue.peek()[1]); - queue.poll(); - } - - if (snake.contains(x + "," + y)) { - return -1; - } - - snake.add(x + "," + y); - queue.offer(new int[]{x, y}); - - return eaten; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/SortANearlySortedArray.java b/src/geeksforgeeks/SortANearlySortedArray.java deleted file mode 100644 index 0924886..0000000 --- a/src/geeksforgeeks/SortANearlySortedArray.java +++ /dev/null @@ -1,41 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.PriorityQueue; - -/*https://www.techiedelight.com/sort-k-sorted-array/*/ -class SortANearlySortedArray { - - public static void sortKSortedArray(List list, int k) { - // create an empty min heap and insert first k+1 elements in the heap - PriorityQueue pq = new PriorityQueue<>(list.subList(0, k + 1)); - - int index = 0; - - for (int i = k + 1; i < list.size(); i++) { - // pop top element from min-heap and assign it to - // next available array index - list.set(index++, pq.poll()); - - // push next array element into min-heap - pq.add(list.get(i)); - } - - // pop all remaining elements from the min heap and assign it to - // next available array index - while (!pq.isEmpty()) { - list.set(index++, pq.poll()); - } - } - - - public static void main(String[] args) { - List list = Arrays.asList(1, 4, 5, 2, 3, 7, 8, 6, 10, 9); - int k = 2; - - sortKSortedArray(list, k); - System.out.println(list); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/SortStack.java b/src/geeksforgeeks/SortStack.java deleted file mode 100644 index ffaccf0..0000000 --- a/src/geeksforgeeks/SortStack.java +++ /dev/null @@ -1,31 +0,0 @@ -package geeksforgeeks; - -import java.util.Stack; - -class SortStack { - // Input : [34, 3, 31, 98, 92, 23] - // Output : [3, 23, 31, 34, 92, 98] - public static Stack sortStack(Stack input) { - /* If input is null, no processing needed */ - if (input == null) { - return null; - } - /* Create a temp stack */ - Stack tempStack = new Stack<>(); - /* Keep going until input is not empty */ - while (!input.isEmpty()) { - /* Pop value from input */ - int tempValue = input.pop(); - /* - * We want smallest one at the bottom. So keep comparing and if temp stack has - * bigger item, pop it and push it to input stack - */ - while (!tempStack.isEmpty() && tempStack.peek() > tempValue) { - input.push(tempStack.pop()); - } - /* Push temp value to the temp stack */ - tempStack.push(tempValue); - } - return tempStack; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/SortedArrayToBST.java b/src/geeksforgeeks/SortedArrayToBST.java deleted file mode 100644 index 742aacd..0000000 --- a/src/geeksforgeeks/SortedArrayToBST.java +++ /dev/null @@ -1,39 +0,0 @@ -package geeksforgeeks; - -public class SortedArrayToBST { - - static class Node { - int data; - Node left; - Node right; - - public Node(int data) { - this.data = data; - } - } - - public static void main(String[] args) { - int[] arr = {1, 2, 3, 4, 5, 6}; - Node node = bst(arr, 0, arr.length - 1); - printTree(node); - } - - public static Node bst(int[] arr, int start, int end) { - if (end < start) - return null; - int mid = start + ((end - start) / 2); - Node root = new Node(arr[mid]); - root.left = bst(arr, start, mid - 1); - root.right = bst(arr, mid + 1, end); - return root; - } - - public static void printTree(Node node) { - if (node == null) - return; - printTree(node.left); - System.out.println(node.data); - printTree(node.right); - - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/SortedSquares.java b/src/geeksforgeeks/SortedSquares.java deleted file mode 100644 index 7af17cc..0000000 --- a/src/geeksforgeeks/SortedSquares.java +++ /dev/null @@ -1,28 +0,0 @@ -package geeksforgeeks; - -public class SortedSquares { - // Input: [-7,-3,2,3,11] - // Output: [4,9,9,49,121] - public int[] sortedSquares(int[] A) { - if(A==null || A.length==0) return new int[0]; - - int[]result= new int[A.length]; - - int index= A.length-1; - int left=0; - int right=index; - - while(left<=right){ - if(Math.abs(A[left]) spiralOrder(int[][] matrix) { - - List res = new ArrayList(); - - if (matrix.length == 0) { - return res; - } - - int rowBegin = 0; - int rowEnd = matrix.length-1; - int colBegin = 0; - int colEnd = matrix[0].length - 1; - - while (rowBegin <= rowEnd && colBegin <= colEnd) { - // Traverse Right - for (int j = colBegin; j <= colEnd; j ++) { - System.out.println(" Right "+matrix[rowBegin][j]); - res.add(matrix[rowBegin][j]); - } - rowBegin++; - - // Traverse Down - for (int j = rowBegin; j <= rowEnd; j ++) { - System.out.println(" Down "+matrix[j][colEnd]); - res.add(matrix[j][colEnd]); - } - colEnd--; - - if (rowBegin <= rowEnd) { // without this condition, this corner test case [[2,3]] would print [2,3,2] - // Traverse Left - for (int j = colEnd; j >= colBegin; j --) { - System.out.println(" Left "+matrix[rowEnd][j]); - res.add(matrix[rowEnd][j]); - } - } - rowEnd--; - - // this block's work is to move 1 row up from bottom - // the rest of the work will be done by first 'Right' loop again - if (colBegin <= colEnd) { - // Traver Up - for (int j = rowEnd; j >= rowBegin; j --) { - System.out.println(" uppp "+matrix[j][colBegin]); - res.add(matrix[j][colBegin]); - } - } - colBegin ++; - } - - return res; - } - - public static void main(String[] args) { - - int a[][] = {{1, 2, 3, 4}, - {5, 6, 7, 8}, - {9, 10, 11, 12}, - {13, 14, 15, 16}}; - spiralOrder(a); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/SpiralMatrixII.java b/src/geeksforgeeks/SpiralMatrixII.java deleted file mode 100644 index 7cb1b22..0000000 --- a/src/geeksforgeeks/SpiralMatrixII.java +++ /dev/null @@ -1,56 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; - -public class SpiralMatrixII { - - public static int[][] generateMatrix(int n) { - // Declaration - int[][] matrix = new int[n][n]; - - // Edge Case - if (n == 0) { - return matrix; - } - - - // Normal Case - int rowStart = 0; - int rowEnd = n - 1; - int colStart = 0; - int colEnd = n - 1; - int num = 1; // change - - while (rowStart <= rowEnd && colStart <= colEnd) { - for (int i = colStart; i <= colEnd; i++) { - matrix[rowStart][i] = num++; // change - } - rowStart++; - - for (int i = rowStart; i <= rowEnd; i++) { - matrix[i][colEnd] = num++; // change - } - colEnd--; - - for (int i = colEnd; i >= colStart; i--) { - if (rowStart <= rowEnd) - matrix[rowEnd][i] = num++; // change - } - rowEnd--; - - for (int i = rowEnd; i >= rowStart; i--) { - if (colStart <= colEnd) - matrix[i][colStart] = num++; // change - } - colStart++; - - System.out.println(Arrays.deepToString(matrix)); - } - - return matrix; - } - - public static void main(String[] args) { - generateMatrix(4); - } -} diff --git a/src/geeksforgeeks/SplitLinkedList.java b/src/geeksforgeeks/SplitLinkedList.java deleted file mode 100644 index c09c0d4..0000000 --- a/src/geeksforgeeks/SplitLinkedList.java +++ /dev/null @@ -1,47 +0,0 @@ -package geeksforgeeks; - -//https://leetcode.com/problems/split-linked-list-in-parts/ -class SplitLinkedList { - - public ListNode[] splitListToParts(ListNode root, int k) { - ListNode[] partsOfRoot = new ListNode[k]; - ListNode head = root; - int len = size(root); - int minNoOfElements = len / k; - int extraRoomForElement = len % k; - ListNode prev = null; - for (int i = 0; i < k && head != null; i++, extraRoomForElement--) { - partsOfRoot[i] = head; - for (int j = 0; j < minNoOfElements + (extraRoomForElement > 0 ? 1 : 0); j++) { - prev = head; - head = head.next; - } - prev.next = null; - } - return partsOfRoot; - - } - - public int size(ListNode root) { - int len = 0; - while (root != null) { - root = root.next; - len++; - } - return len; - } - - public static void main(String[] args) { - ListNode root = new ListNode(1); - root.next = new ListNode(2); - root.next.next = new ListNode(3); - root.next.next.next = new ListNode(4); - root.next.next.next.next = new ListNode(5); - root.next.next.next.next.next = new ListNode(6); - root.next.next.next.next.next.next = new ListNode(7); - root.next.next.next.next.next.next.next = new ListNode(8); - root.next.next.next.next.next.next.next.next = new ListNode(9); - root.next.next.next.next.next.next.next.next.next = new ListNode(10); - new SplitLinkedList().splitListToParts(root, 3); - } -} diff --git a/src/geeksforgeeks/StockBuySellManyTimes.java b/src/geeksforgeeks/StockBuySellManyTimes.java deleted file mode 100644 index d3ac23f..0000000 --- a/src/geeksforgeeks/StockBuySellManyTimes.java +++ /dev/null @@ -1,84 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.List; - -class Interval { - int buy, sell; - int start; // for meeting problem - int end; - Interval(int buy, int sell){ - this.buy=buy; - this.sell=sell; - } - Interval(){ - - } -} - -/** - * https://www.geeksforgeeks.org/stock-buy-sell/ - */ -// unresolved -class StockBuySellManyTimes { - - //200, 180, 260, 310, 40, 535, 695 - void stockBuySell(int price[], int n) { - // Prices must be given for at least two days - if (n == 1) { - return; - } - - int count = 0; - - List result = new ArrayList<>(); - - int i = 0; - while (i < n - 1) { - // Find Local Minima. Note that the limit is (n-2) as we are - // comparing present element to the next element. - while ((i < n - 1) && (price[i + 1] <= price[i])) - i++; - - // If we reached the end, break as no further solution possible - if (i == n - 1) { - break; - } - - Interval e = new Interval(); - e.buy = i++; - // Store the index of minima - - // Find Local Maxima. Note that the limit is (n-1) as we are - // comparing to previous element - while ((i < n) && (price[i] >= price[i - 1])) - i++; - - // Store the index of maxima - e.sell = i - 1; - result.add(e); - - // Increment number of buy/sell - count++; - } - - if (count == 0) { - System.out.println("There is no day when buying the stock " + "will make profit"); - } else { - for (int j = 0; j < count; j++) - System.out.println( - "Buy on day: " + result.get(j).buy + " " + "Sell on day : " + result.get(j).sell); - } - - return; - } - - public static void main(String args[]) { - StockBuySellManyTimes stock = new StockBuySellManyTimes(); - - int price[] = { 200, 180, 260, 310, 40, 535, 695 }; - int n = price.length; - - stock.stockBuySell(price, n); - } -} diff --git a/src/geeksforgeeks/StockSpanner.java b/src/geeksforgeeks/StockSpanner.java deleted file mode 100644 index a885ad5..0000000 --- a/src/geeksforgeeks/StockSpanner.java +++ /dev/null @@ -1,26 +0,0 @@ -package geeksforgeeks; - - -import java.util.ArrayDeque; -import java.util.Deque; - -; - -class StockSpanner { -// -// Deque> stack; -// public StockSpanner() { -// this.stack= new ArrayDeque<>(); -// } -// -// public int next(int price) { -// int value=1; -// while(!stack.isEmpty() && stack.peek().fst<=price){ -// value+=stack.pop().snd; -// } -// -// stack.push(new Pair(price,value)); -// -// return stack.peek().snd; -// } -} \ No newline at end of file diff --git a/src/geeksforgeeks/StringIterator.java b/src/geeksforgeeks/StringIterator.java deleted file mode 100644 index 4afd362..0000000 --- a/src/geeksforgeeks/StringIterator.java +++ /dev/null @@ -1,37 +0,0 @@ -package geeksforgeeks; - -//StringIterator iterator = new StringIterator("L1e2t1C1o1d1e1"); -// iterator.next(); // return 'L' -// iterator.next(); // return 'e' -// iterator.next(); // return 'e' -// iterator.next(); // return 't' -// iterator.next(); // return 'C' -// iterator.next(); // return 'o' -// iterator.next(); // return 'd' -// iterator.hasNext(); // return true -// iterator.next(); // return 'e' -// iterator.hasNext(); // return false -// iterator.next(); // return ' ' -public class StringIterator { - String res; - int ptr = 0, num = 0; - char ch = ' '; - public StringIterator(String s) { - res = s; - } - public char next() { - if (!hasNext()) - return ' '; - if (num == 0) { - ch = res.charAt(ptr++); - while (ptr < res.length() && Character.isDigit(res.charAt(ptr))) { - num = num * 10 + res.charAt(ptr++) - '0'; - } - } - num--; - return ch; - } - public boolean hasNext() { - return ptr != res.length() || num != 0; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/SubArraySumDivisibleByK.java b/src/geeksforgeeks/SubArraySumDivisibleByK.java deleted file mode 100644 index 1db73bb..0000000 --- a/src/geeksforgeeks/SubArraySumDivisibleByK.java +++ /dev/null @@ -1,48 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; -import java.util.Map; - -/** - * Given an array A of integers, return the number of (contiguous, non-empty) - * subarrays that have a sum divisible by K. - * Input: A = [4,5,0,-2,-3,1], K = 5 - * Output: 7 - * Explanation: There are 7 subarrays with a sum divisible by K = 5: - * [4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3] - */ -public class SubArraySumDivisibleByK { - - public int subarraysDivByK(int[] A, int K) { - Map count = new HashMap<>(); - count.put(0, 1); //if the first prefix sum is 0, it need to be counted as a mod of K, right? - // Rest of prefix sum from 1 to K-1 don't include the first prefix sum - int prefix = 0, res = 0; - for (int a : A) { - //(prefix+a%K+K)%K is just a trick to make the remainder positive. - prefix = (prefix + a % K + K) % K; - res += count.getOrDefault(prefix, 0); - count.put(prefix, count.getOrDefault(prefix, 0) + 1); - } - return res; - } - - // A = [4,5,0,-2,-3,1], K = 5 - // step 1 : {0:1} a=4 sum=4 mod=4 count = 0+0 =0 - // step 2 : {0:1,4:1} a=5 sum=9 mod=4 count = 0+1 =1 - // step 3 : {0:1,4:2} a=0 sum=9 mod=4 count = 1+2 =3 - // step 4 : {0:1,4:3} a=-2 sum=7 mod=2 count = 3+0 =3 - // step 6 : {0:1,4:3,2:1} a=-3 sum=4 mod=4 count = 3+3 =6 - // step 7 : {0:1,4:4,2:1} a=1 sum=5 mod=0 count = 6+1 =7 - public int subarraysDivByKOptimised(int[] A, int K) { - int[] map = new int[K]; - map[0] = 1; - int prefix = 0, res = 0; - for (int a : A) { - prefix = (prefix + a % K + K) % K; - res += map[prefix]; - map[prefix]++; - } - return res; - } -} diff --git a/src/geeksforgeeks/SubArraySumEqualsK.java b/src/geeksforgeeks/SubArraySumEqualsK.java deleted file mode 100644 index 4cc6972..0000000 --- a/src/geeksforgeeks/SubArraySumEqualsK.java +++ /dev/null @@ -1,57 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; -import java.util.Map; - -public class SubArraySumEqualsK { - public int subarraySum(int[] nums, int k) { - int left = 0; - - int sum = 0; - int result = 0; - - Map map = new HashMap<>(); - map.put(0, 1); - // Let’s assume (D+E+3=k) - // sum =A+B+C+D+E+3 - // preSum = A+B+C - // Thus, we can compose critical equation - // sum - preSum = k - // Since we’re looking for specific preSum to compose value k - // we can re-arrange the above equation like below - // sum - k = preSum - // For multiple matching counts - // Ex: - // input [0,-1,1,2,3] k=5 - // We notice that it’s necessary to record occurrence of specific preSum. - // In this case, we need to know preSum 2 occur three times. [0,-1,1,2], [-1,1,2], [2] - // This indicate that it's necessary to record preSum counts - - while (left < nums.length) { - sum += nums[left]; - if (map.get(sum - k) != null) { - result += map.get(sum - k); - } - map.put(sum, map.getOrDefault(sum, 0) + 1); - left++; - - } - return result; - - } - - public static int subarraySumDivByK(int[] nums, int K) { - int prefix = 0; - int result = 0; - Map count = new HashMap<>(); - count.put(0, 1); - - for (int a : nums) { - //(prefix+a%K+K)%K is just a trick to make the remainder positive. - prefix = (prefix + (a % K) + K) % K; - result += count.getOrDefault(prefix, 0); - count.put(prefix, count.getOrDefault(prefix, 0) + 1); - } - return result; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/SubstringWindowTemplate.java b/src/geeksforgeeks/SubstringWindowTemplate.java deleted file mode 100644 index 9ba395d..0000000 --- a/src/geeksforgeeks/SubstringWindowTemplate.java +++ /dev/null @@ -1,62 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/*https://leetcode.com/problems/find-all-anagrams-in-a-string/discuss/92007/Sliding-Window-algorithm-template-to-solve-all-the-Leetcode-substring-search-problem*/ -public class SubstringWindowTemplate { - - public static List slidingWindowTemplateByHarryChaoyangHe(String s, String t) { - //init a collection or int value to save the result according the question. - List result = new LinkedList<>(); - if (t.length() > s.length()) return result; - - //create a hashmap to save the Characters of the target substring. - //(K, V) = (Character, Frequence of the Characters) - Map map = new HashMap<>(); - for (char c : t.toCharArray()) { - map.put(c, map.getOrDefault(c, 0) + 1); - } - //maintain a counter to check whether match the target string. - int counter = map.size();//must be the map size, NOT the string size because the char may be duplicate. - - //Two Pointers: begin - left pointer of the window; end - right pointer of the window - int begin = 0; - int end = 0; - - //loop at the begining of the source string - while (end < s.length()) { - - char c = s.charAt(end);//get a character - - if (map.containsKey(c)) { - map.put(c, map.get(c) - 1);// plus or minus one - if (map.get(c) == 0) counter--;//modify the counter according the requirement(different condition). - } - end++; - - //increase begin pointer to make it invalid/valid again - while (counter == 0 /* counter condition. different question may have different condition */) { - - char tempc = s.charAt(begin);//***be careful here: choose the char at begin pointer, NOT the end pointer - if (map.containsKey(tempc)) { - map.put(tempc, map.get(tempc) + 1);//plus or minus one - if (map.get(tempc) > 0) - counter++;//modify the counter according the requirement(different condition). - } - - /* save / update(min/max) the result if find a target*/ - // result collections or result int value - - begin++; - } - } - return result; - } - - public static void main(String[] args) { - System.out.println(slidingWindowTemplateByHarryChaoyangHe("ADOBECODEBANC", "ABC")); - } -} diff --git a/src/geeksforgeeks/SumOfThreeElements.java b/src/geeksforgeeks/SumOfThreeElements.java deleted file mode 100644 index 108825a..0000000 --- a/src/geeksforgeeks/SumOfThreeElements.java +++ /dev/null @@ -1,39 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; - -public class SumOfThreeElements { - - public static void main(String[] args) { - int arr[] = {1, 4, 45, 6, 10, 8}; - int sum = 22; - SumOfThreeElements ste = new SumOfThreeElements(); - ste.findTriplets(arr, sum); - } - - private boolean findTriplets(int[] arr, int sum) { - - int arrSize = arr.length; - Arrays.sort(arr); - - for (int i = 0; i < arrSize; i++) { - - int left = i + 1; - int right = arrSize - 1; - - while (left < right) { - int result = arr[i] + arr[left] + arr[right]; - if (result == sum) { - System.out.println("triplet found" + i + "+" + left + "+" + right); - break; - } else if (result < sum) { - left++; - } else { - right--; - } - } - } - - return false; - } -} diff --git a/src/geeksforgeeks/SumSubArrayZero.java b/src/geeksforgeeks/SumSubArrayZero.java deleted file mode 100644 index 5f30500..0000000 --- a/src/geeksforgeeks/SumSubArrayZero.java +++ /dev/null @@ -1,65 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * https://www.geeksforgeeks.org/print-all-subarrays-with-0-sum/ - */ - - -public class SumSubArrayZero { - private static class Pair { - int first, second; - - Pair(int a, int b) { - first = a; - second = b; - } - - public String toString() { - return this.first + "--" + this.second; - } - } - static ArrayList findSubArrays(int[] arr, int n) { - Map> map = new HashMap<>(); - ArrayList result = new ArrayList<>(); - int sum = 0; - for (int i = 0; i < n; i++) { - sum += arr[i]; - if (sum == 0) - result.add(new Pair(0, i)); - List al = new ArrayList<>(); - if (map.containsKey(sum)) { - al = map.get(sum); - for (int it = 0; it < al.size(); it++) { - result.add(new Pair(al.get(it) + 1, i)); - } - } - al.add(i); - map.put(sum, al); - } - return result; - } - - public static void main(String args[]) { - int[] arr = {6, 3, -1, -3, 4, -2, 2, 4, 6, -12, -7}; - int n = arr.length; - - ArrayList out = findSubArrays(arr, n); - - if (out.size() == 0) - System.out.println("No subarray exists"); - else - print(out); - } - - static void print(ArrayList out) { - for (int i = 0; i < out.size(); i++) { - Pair p = out.get(i); - System.out.println("Subarray found from Index " + p.first + " to " + p.second); - } - } -} diff --git a/src/geeksforgeeks/SurroundedRegions.java b/src/geeksforgeeks/SurroundedRegions.java deleted file mode 100644 index 5844136..0000000 --- a/src/geeksforgeeks/SurroundedRegions.java +++ /dev/null @@ -1,142 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayDeque; -import java.util.Queue; - -/** - * Given a 2D board containing 'X' and 'O' (the letter O), - * capture all regions surrounded by 'X'. - *

- * A region is captured by flipping all 'O's into 'X's in that surrounded region. - *

- * Example: - *

- * X X X X - * X O O X - * X X O X - * X O X X - *

- * After running your function, the board should be: - *

- * X X X X - * X X X X - * X X X X - * X O X X - *

- * Surrounded regions shouldn’t be on the border, - * which means that any 'O' on the border of the board are not flipped to 'X'. - * Any 'O' that is not on the border and - * it is not connected to an 'O' on the border will be flipped to 'X'. - * Two cells are connected if they are adjacent cells connected horizontally or vertically. - */ -class Solution { - private static class Pair { - int x; - int y; - int level; - - public Pair(int x, int y, int level) { - this.x = x; - this.y = y; - this.level = level; - } - } - - public void solve(char[][] board) { - if (board == null || board.length == 0) - return; - - Queue queue = new ArrayDeque<>(); - int[][] dirs = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}}; - for (int i = 0; i < board.length; i++) { - for (int j = 0; j < board[0].length; j++) { - if (board[i][j] == 'O') { - if (i == board.length - 1 || j == board[0].length - 1 || i == 0 || j == 0) { - board[i][j] = '1'; - queue.offer(new Pair(i, j, 0)); - } - } - } - } - - while (!queue.isEmpty()) { - Pair temp = queue.poll(); - - for (int[] dir : dirs) { - int newx = temp.x + dir[0]; - int newy = temp.y + dir[1]; - - if (isValid(newx, newy, board) && board[newx][newy] == 'O') { - board[newx][newy] = '1'; - queue.offer(new Pair(newx, newy, 0)); - } - } - - } - - for (int i = 0; i < board.length; i++) { - for (int j = 0; j < board[0].length; j++) { - if (board[i][j] == '1') { - board[i][j] = 'O'; - } else if (board[i][j] == 'O') { - board[i][j] = 'X'; - } - } - } - - } - - public boolean isValid(int x, int y, char[][] board) { - return x >= 0 && x < board.length && y >= 0 && y < board[0].length; - } - - public void solveDFS(char[][] board) { - if (board.length == 0 || board[0].length == 0) - return; - if (board.length < 2 || board[0].length < 2) - return; - int m = board.length, n = board[0].length; - // Any 'O' connected to a boundary can't be turned to 'X', so ... - // Start from first and last column, turn 'O' to '*'. - for (int i = 0; i < m; i++) { - if (board[i][0] == 'O') - boundaryDFS(board, i, 0); - if (board[i][n - 1] == 'O') - boundaryDFS(board, i, n - 1); - } - // Start from first and last row, turn '0' to '*' - for (int j = 0; j < n; j++) { - if (board[0][j] == 'O') - boundaryDFS(board, 0, j); - if (board[m - 1][j] == 'O') - boundaryDFS(board, m - 1, j); - } - // post-processing, turn 'O' to 'X', '*' back to 'O', keep 'X' intact. - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - if (board[i][j] == 'O') - board[i][j] = 'X'; - else if (board[i][j] == '*') - board[i][j] = 'O'; - } - } - } - - //Use DFS algo to turn internal however boundary-connected 'O' to '*' - private void boundaryDFS(char[][] board, int i, int j) { - if (i < 0 || i > board.length - 1 || j < 0 || j > board[0].length - 1) - return; - if (board[i][j] == 'O') { - board[i][j] = '*'; - - boundaryDFS(board, i - 1, j); - - boundaryDFS(board, i + 1, j); - - boundaryDFS(board, i, j - 1); - - boundaryDFS(board, i, j + 1); - } - } -} - diff --git a/src/geeksforgeeks/SwapRecoverBST.java b/src/geeksforgeeks/SwapRecoverBST.java deleted file mode 100644 index 7a34899..0000000 --- a/src/geeksforgeeks/SwapRecoverBST.java +++ /dev/null @@ -1,54 +0,0 @@ -package geeksforgeeks; - -public class SwapRecoverBST { - - TreeNode firstElement = null; - TreeNode secondElement = null; - // The reason for this initialization is to avoid null pointer exception in the first comparison when prevElement has not been initialized - TreeNode prevElement = new TreeNode(Integer.MIN_VALUE); - - public void recoverTree(TreeNode root) { - - // In order traversal to find the two elements - traverse(root); - - // Swap the values of the two nodes - int temp = firstElement.val; - firstElement.val = secondElement.val; - secondElement.val = temp; - } - - private void traverse(TreeNode root) { - - if (root == null) - return; - - traverse(root.left); - // Let's assume this is the original in-order traversal sequence of BST: 1 2 3 4 5 - // If 2 and 3 get swapped, it becomes 1 3 2 4 5 and - //there is only one time that you will have prev.val >= root.val - // If 2 and 4 get swapped, it becomes 1 4 3 2 5 and - //there are two times that you will have prev.val >= root.val - - // If during the first time when you find prev.val >= root.val, - //the previous node "prev" MUST be one of two nodes that get swapped. - //However, the current node MAY OR MAY NOT be another node that gets swapped, - //which will depend on whether later during in-order traversal, there is another prev.val >= root.val or not. - // If there is, then the current node "root" during the 2nd time of prev.val >= root.val will be the other node that gets swapped - // Start of "do some business", - // If first element has not been found, assign it to prevElement (refer to 6 in the example above) - if (firstElement == null && prevElement.val >= root.val) { - firstElement = prevElement; - } - - // If first element is found, assign the second element to the root (refer to 2 in the example above) - if (firstElement != null && prevElement.val >= root.val) { - secondElement = root; - } - prevElement = root; - - // End of "do some business" - - traverse(root.right); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/SymmetricTree.java b/src/geeksforgeeks/SymmetricTree.java deleted file mode 100644 index 8ef690c..0000000 --- a/src/geeksforgeeks/SymmetricTree.java +++ /dev/null @@ -1,21 +0,0 @@ -package geeksforgeeks; - -class SymmetricTree { - public boolean isSymmetric(TreeNode root) { - if (root == null) { - return true; - } - - return isSymmetricHelp(root.left, root.right); - } - - private boolean isSymmetricHelp(TreeNode left, TreeNode right) { - if (left == null || right == null) { - return left == right; - } - if (left.val != right.val) { - return false; - } - return isSymmetricHelp(left.left, right.right) && isSymmetricHelp(left.right, right.left); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/TaskLeastInterval.java b/src/geeksforgeeks/TaskLeastInterval.java deleted file mode 100644 index d43926d..0000000 --- a/src/geeksforgeeks/TaskLeastInterval.java +++ /dev/null @@ -1,55 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -/** - * https://leetcode.com/problems/task-scheduler/ - */ - - -public class TaskLeastInterval { - - public static int leastInterval(char[] tasks, int n) { - Map map = new HashMap<>(); - for (char task : tasks) { - map.put(task, map.getOrDefault(task, 0) + 1); - } - PriorityQueue> queue = new PriorityQueue<>( - (a, b) -> Integer.compare(b.getValue(), a.getValue())); - - queue.addAll(map.entrySet()); - - int count = 0; - // At each iteration, we process at most 'n' elements, - // and move forwards exactly n+1 in time (regardless of how many elements we processed: - // Read the topmost from the queue and increment the time. Add it to a temp list to be added later. - // Add the element back to the queue from the temp list if count is > 0. - // if al elements are done, we're done too. - // Move time forward by n + 1 - // Return time in the end. - while (!queue.isEmpty()) { - int k = n + 1; //each time fill k elements, if k is not full, that's the idle - List tempList = new ArrayList<>(); - while (k > 0 && !queue.isEmpty()) { - Map.Entry top = queue.poll(); - top.setValue(top.getValue() - 1); - tempList.add(top); - k--; - count++; - } - - for (Map.Entry e : tempList) { - if (e.getValue() > 0) queue.add(e); // add valid tasks - } - - if (queue.isEmpty()) break; - count = count + k; // if k > 0, then it means we need to be idle - } - return count; - } - - public static void main(String[] args) { - char[] arr = "A".toCharArray(); - System.out.println(leastInterval(arr, 2)); - } -} diff --git a/src/geeksforgeeks/ThreeSum.java b/src/geeksforgeeks/ThreeSum.java deleted file mode 100644 index a2950aa..0000000 --- a/src/geeksforgeeks/ThreeSum.java +++ /dev/null @@ -1,40 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class ThreeSum { - public List> threeSum(int[] nums) { - if(nums==null || nums.length==0) return Collections.emptyList(); - - Arrays.sort(nums); - List> result= new ArrayList<>(); - for(int i=0;isum){ - right--; - } - } - } - } - - return result; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/TimeMap.java b/src/geeksforgeeks/TimeMap.java deleted file mode 100644 index df7ba19..0000000 --- a/src/geeksforgeeks/TimeMap.java +++ /dev/null @@ -1,67 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; - -/** - * Create a time based key-value store class TimeMap, that supports two operations. - * - * 1. set(string key, string value, int timestamp) - * - * Stores the key and value, along with the given timestamp. - * 2. get(string key, int timestamp) - * - * Returns a value such that set(key, value, timestamp_prev) was called previously, - * with timestamp_prev <= timestamp. - * If there are multiple such values, it returns the one with the largest timestamp_prev. - * If there are no values, it returns the empty string (""). - * - * Input: inputs = ["TimeMap","set","get","get","set","get","get"], inputs = [[],["foo","bar",1],["foo",1],["foo",3],["foo","bar2",4],["foo",4],["foo",5]] - * Output: [null,null,"bar","bar",null,"bar2","bar2"] - * Explanation: - * TimeMap kv; - * kv.set("foo", "bar", 1); // store the key "foo" and value "bar" along with timestamp = 1 - * kv.get("foo", 1); // output "bar" - * kv.get("foo", 3); // output "bar" since there is no value corresponding to foo at timestamp 3 and timestamp 2, then the only value is at timestamp 1 ie "bar" - * kv.set("foo", "bar2", 4); - * kv.get("foo", 4); // output "bar2" - * kv.get("foo", 5); //output "bar2" - */ - -class TimeMap { - - class Node{ - String val; - int time; - Node next; - public Node(String value, int timestamp){ - val=value; - time=timestamp; - } - } - /** Initialize your data structure here. */ - HashMap map; - - public TimeMap() { - map=new HashMap<>(); - } - - public void set(String key, String value, int timestamp) { - Node node =new Node(value,timestamp); - if(map.containsKey(key)){ - node.next=map.get(key); - } - map.put(key,node); - } - - public String get(String key, int timestamp) { - String vl=""; - if(map.containsKey(key)){ - Node y=map.get(key); - while(y.time>timestamp&&y.next!=null) - y=y.next; - if(y.time<=timestamp) - vl=y.val; - } - return vl; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/TopKFrequentElement.java b/src/geeksforgeeks/TopKFrequentElement.java deleted file mode 100644 index b4bcd99..0000000 --- a/src/geeksforgeeks/TopKFrequentElement.java +++ /dev/null @@ -1,38 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -class TopKFrequentElement{ - public List topKFrequent(int[] nums, int k) { - List result = new ArrayList<>(); - - Map map = new HashMap<>(); //Key: val, Val: #of freq - for (int num : nums) { - if (map.containsKey(num)) { - map.put(num, map.get(num)+1); - }else { - map.put(num, 1); - } - } - - List[] bucks = new List[nums.length+1]; // index : freq; val: set of key - for (int key : map.keySet()) { - int freq = map.get(key); - if (bucks[freq] == null) { - bucks[freq] = new ArrayList<>(); - } - bucks[freq].add(key); - } - - for (int freq = nums.length; freq >=0 && k > 0; freq--) { - if (bucks[freq] != null) { - k -=bucks[freq].size(); - result.addAll(bucks[freq]); - } - } - return result; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/TopKFrequentElements.java b/src/geeksforgeeks/TopKFrequentElements.java deleted file mode 100644 index 9084b2d..0000000 --- a/src/geeksforgeeks/TopKFrequentElements.java +++ /dev/null @@ -1,38 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.PriorityQueue; - -/** - * https://leetcode.com/problems/top-k-frequent-elements/discuss/445815/Java8-Lambda-solution-3-lines-code - */ -public class TopKFrequentElements { - - public List topKFrequent(int[] nums, int k) { - if (nums.length == 0) { - return Collections.emptyList(); - } - - PriorityQueue> pq = new PriorityQueue<>( - (obj1, obj2) -> obj2.getValue() - obj1.getValue()); - Map map = new HashMap<>(); - - for (int i : nums) { - map.put(i, map.getOrDefault(i, 0) + 1); - } - - for (Map.Entry mapEntry : map.entrySet()) { - pq.add(mapEntry); - } - - List result = new ArrayList<>(); - for (int i = 0; i < k; i++) { - result.add(pq.remove().getKey()); - } - return result; - } -} diff --git a/src/geeksforgeeks/TrailingZeroes.java b/src/geeksforgeeks/TrailingZeroes.java deleted file mode 100644 index 87a2490..0000000 --- a/src/geeksforgeeks/TrailingZeroes.java +++ /dev/null @@ -1,19 +0,0 @@ -package geeksforgeeks; - -/*https://www.geeksforgeeks.org/count-trailing-zeroes-factorial-number/*/ -class TrailingZeroes { - public int trailingZeroes(int n) { - int count = 0; - while (n != 0) { - int tmp = n / 5; - count += tmp; - n = tmp; - } - return count; - } - - public static void main(String[] args) { - TrailingZeroes solution = new TrailingZeroes(); - System.out.println(solution.trailingZeroes(30)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/TreasureIsland.java b/src/geeksforgeeks/TreasureIsland.java deleted file mode 100644 index 9c0fc04..0000000 --- a/src/geeksforgeeks/TreasureIsland.java +++ /dev/null @@ -1,66 +0,0 @@ -package geeksforgeeks; - -import java.util.LinkedList; -import java.util.Queue; - -/** - * https://leetcode.com/discuss/interview-question/347457/Amazon-or-OA-2019-or-Treasure-Island - */ -public class TreasureIsland { - private static final int[][] DIRS = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } }; - - public static int minSteps(char[][] grid) { - Queue q = new LinkedList<>(); - q.add(new Point(0, 0, 0)); - grid[0][0] = 'D'; - while (!q.isEmpty()) { - Point p = q.poll(); - - for (int[] dir : DIRS) { - int r = p.r + dir[0]; - int c = p.c + dir[1]; - - if (isSafe(grid, r, c)) { - if (grid[r][c] == 'X') { - return p.steps + 1; - } - grid[r][c] = 'D'; - q.add(new Point(r, c, p.steps + 1)); - } - } - } - return -1; - } - - private static boolean isSafe(char[][] grid, int r, int c) { - return r >= 0 && r < grid.length && c >= 0 && c < grid[0].length && grid[r][c] != 'D'; - } - - private static class Point { - int r; - int c; - int steps; - - Point(int r, int c, int steps) { - this.r = r; - this.c = c; - this.steps = steps; - } - - public String toString() { - return this.r + "-" + this.c; - } - } - - public static void main(String[] args) { - - char[][] grid = - {{'O', 'O', 'O', 'O'}, - {'D', 'O', 'D', 'O'}, - {'O', 'O', 'O', 'O'}, - {'X', 'D', 'D', 'O'}}; - - - System.out.println(minSteps(grid)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/TreasureIslandII.java b/src/geeksforgeeks/TreasureIslandII.java deleted file mode 100644 index 422723f..0000000 --- a/src/geeksforgeeks/TreasureIslandII.java +++ /dev/null @@ -1,82 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayDeque; -import java.util.Queue; - -/** - * https://leetcode.com/discuss/interview-question/356150/amazon-oa-2019-shortest-path-from-multiple-sources - * */ - -public class TreasureIslandII { - private static final int[][] DIRS = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; - - public static int minDist(char[][] grid) { - Queue q = collectSources(grid); - for (int dist = 0; !q.isEmpty(); dist++) { - for (int sz = q.size(); sz > 0; sz--) { - Point p = q.poll(); - - if (grid[p.r][p.c] == 'X') - return dist; - grid[p.r][p.c] = 'D'; // mark as visited - - for (int[] dir : DIRS) { - int r = p.r + dir[0]; - int c = p.c + dir[1]; - if (isSafe(grid, r, c)) { - q.add(new Point(r, c)); - } - } - } - } - return -1; - } - - private static Queue collectSources(char[][] grid) { - Queue sources = new ArrayDeque<>(); - for (int r = 0; r < grid.length; r++) { - for (int c = 0; c < grid[0].length; c++) { - if (grid[r][c] == 'S') { - sources.add(new Point(r, c)); - } - } - } - return sources; - } - - private static boolean isSafe(char[][] grid, int r, int c) { - return r >= 0 && r < grid.length && c >= 0 && c < grid[0].length && grid[r][c] != 'D'; - } - - private static class Point { - int r; - int c; - - Point(int r, int c) { - this.r = r; - this.c = c; - } - - public String toString() { - return r + "-" + c; - } - } - - public static void main(String[] args) { - char[][] grid = { - {'S', 'O', 'O', 'S', 'S'}, - {'D', 'O', 'D', 'O', 'D'}, - {'O', 'O', 'O', 'O', 'X'}, - {'X', 'D', 'D', 'O', 'O'}, - {'X', 'D', 'D', 'D', 'O'}}; - test(minDist(grid), 3); - } - - private static void test(int actual, int expected) { - if (actual == expected) { - System.out.println("PASSED!"); - } else { - System.out.println(String.format("FAILED! Expected: %d, but got: %d", expected, actual)); - } - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/Trie.java b/src/geeksforgeeks/Trie.java deleted file mode 100644 index 3483d59..0000000 --- a/src/geeksforgeeks/Trie.java +++ /dev/null @@ -1,65 +0,0 @@ -package geeksforgeeks; - -class Trie { - - class TrieNode{ - char data; - TrieNode[] children; - boolean isWord; - TrieNode(char data){ - this.data=data; - this.children= new TrieNode[26]; - } - } - - - TrieNode root; - public Trie() { - this.root=new TrieNode(' '); - } - - - public void insert(String word) { - TrieNode head=root; - - for(int i=0;i userMap; - - // Tweet link to next Tweet so that we can save a lot of time - // when we execute getNewsFeed(userId) - private class Tweet { - public int id; - public int time; - public Tweet next; - - public Tweet(int id) { - this.id = id; - time = timeStamp++; - next = null; - } - } - - public class User { - public int id; - public Set followed; - public Tweet tweet_head; - - public User(int id) { - this.id = id; - followed = new HashSet<>(); - follow(id); // first follow yourself - tweet_head = null; - } - - public void follow(int id) { - followed.add(id); - } - - public void unfollow(int id) { - followed.remove(id); - } - - // everytime user post a new tweet, add it to the head of tweet list. - public void post(int id) { - Tweet t = new Tweet(id); - t.next = tweet_head; - tweet_head = t; - } - } - - /** - * Initialize your data structure here. - */ - public Twitter() { - userMap = new HashMap<>(); - } - - /** - * Compose a new tweet. - */ - public void postTweet(int userId, int tweetId) { - if (!userMap.containsKey(userId)) { - User u = new User(userId); - userMap.put(userId, u); - } - userMap.get(userId).post(tweetId); - - } - - // Best part of this. - // first get all tweets lists from one user including itself and all people it followed. - // Second add all heads into a max heap. Every time we poll a tweet with - // largest time stamp from the heap, then we add its next tweet into the heap. - // So after adding all heads we only need to add 9 tweets at most into this - // heap before we get the 10 most recent tweet. - public List getNewsFeed(int userId) { - List result = new LinkedList<>(); - - if (!userMap.containsKey(userId)) { - return result; - } - - Set users = userMap.get(userId).followed; - PriorityQueue q = new PriorityQueue<>(users.size(), (a, b) -> (b.time - a.time)); - for (int user : users) { - Tweet t = userMap.get(user).tweet_head; - // very important! If we add null to the head we are screwed. - if (t != null) { - q.add(t); - } - } - int n = 0; - while (!q.isEmpty() && n < 10) { - Tweet t = q.poll(); - result.add(t.id); - n++; - if (t.next != null) { - q.add(t.next); - } - } - - return result; - - } - - /** - * Follower follows a followee. If the operation is invalid, it should be a no-op. - */ - public void follow(int followerId, int followeeId) { - if (!userMap.containsKey(followerId)) { - User u = new User(followerId); - userMap.put(followerId, u); - } - if (!userMap.containsKey(followeeId)) { - User u = new User(followeeId); - userMap.put(followeeId, u); - } - userMap.get(followerId).follow(followeeId); - } - - /** - * Follower unfollows a followee. If the operation is invalid, it should be a no-op. - */ - public void unfollow(int followerId, int followeeId) { - if (!userMap.containsKey(followerId) || followerId == followeeId) { - return; - } - userMap.get(followerId).unfollow(followeeId); - } - - public static void main(String[] args) { - Twitter obj = new Twitter(); - obj.postTweet(1, 5); - List param_2 = obj.getNewsFeed(1); - obj.follow(1, 2); - obj.unfollow(1, 2); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/TwoCityScheduling.java b/src/geeksforgeeks/TwoCityScheduling.java deleted file mode 100644 index e24032f..0000000 --- a/src/geeksforgeeks/TwoCityScheduling.java +++ /dev/null @@ -1,49 +0,0 @@ -package geeksforgeeks; - -import java.util.PriorityQueue; - -/** - * There are 2N people a company is planning to interview. - * The cost of flying the i-th person to city A is costs[i][0], and the cost of flying the i-th person to city B is costs[i][1]. - * Return the minimum cost to fly every person to a city such that exactly N people arrive in each city. - * Input: [[10,20],[30,200],[400,50],[30,20]] - * Output: 110 - * Explanation: - The first person goes to city A for a cost of 10. - The second person goes to city A for a cost of 30. - The third person goes to city B for a cost of 50. - The fourth person goes to city B for a cost of 20. - - * The total minimum cost is 10 + 30 + 50 + 20 = 110 to have half the people interviewing in each city - * - */ -public class TwoCityScheduling { - public int twoCitySchedCost(int[][] costs) { - // for input [[10,20],[30,200],[400,50],[30,20]] - // let's send all to A, the cost'd be => 10+30+400+30= 470 - // we need to remove one half to save some money - // what we can do is take the difference in each input - // (10-20) (30-200) (400-50) (30-20) - // [-10, -170, 350, 10] - // what the above array indicates is that for i'th candidate=>[10,20] we will save 10 in sending to A - // when i=2 we will have to spend 350 more to bring to A city so we sort by arr[0]-arr[1] - // greedily we take negative val candidates to A and rest to B for this input - PriorityQueue queue= new PriorityQueue<>((a, b)->(a[0] - a[1]) - (b[0] - b[1])); - - for(int[] cost: costs){ - queue.offer(cost); - } - int result=0; - int k=0; - while(k= 0; i--) { - min = Math.min(min, nums[i]); - if (nums[i] > min) { - begin = i; - } - } - - int max = Integer.MIN_VALUE; - int end = -2; - //iterate from beginning of array - //find the last element which is smaller than the last seen max from - //its left side and mark it as end - for (int i = 0; i < nums.length; i++) { - max = Math.max(max, nums[i]); - if (nums[i] < max) { - end = i; - } - } - return end - begin + 1; - } -} diff --git a/src/geeksforgeeks/UniqueElementsInArray.java b/src/geeksforgeeks/UniqueElementsInArray.java deleted file mode 100644 index 1b8fca6..0000000 --- a/src/geeksforgeeks/UniqueElementsInArray.java +++ /dev/null @@ -1,29 +0,0 @@ -package geeksforgeeks; - -/** - * https://codepumpkin.com/find-unique-array-element/#XORApproach - */ -public class UniqueElementsInArray { - - /** - * @param inputArray - * - * @return returns unique Element in the array. - * -1 if no unique element is available in the array. - */ - // 0 0 : 0 || 1 1 : 0 - // returns 0 if both are same - public static int xorApproach(int[] inputArray) { - int result = 0; - for (int i = 0; i < inputArray.length; i++) { - result ^= inputArray[i]; - } - - return (result > 0 ? result : -1); - } - - public static void main(String[] args) { - int[] nums = { 1, 2, 3, 2, 1, 4, 3 }; - xorApproach(nums); - } -} diff --git a/src/geeksforgeeks/UniquePath.java b/src/geeksforgeeks/UniquePath.java deleted file mode 100644 index c8015a4..0000000 --- a/src/geeksforgeeks/UniquePath.java +++ /dev/null @@ -1,89 +0,0 @@ -package geeksforgeeks; - -/*https://leetcode.com/problems/unique-paths-ii/ - https://leetcode.com/problems/unique-paths/*/ -public class UniquePath { - - public static void main(String[] args) { - System.out.println(uniquePathI(3, 2)); - - int[][] matrix = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } }; - - System.out.println(uniquePathII(matrix)); - - } - - private static int uniquePathI(int row, int col) { - int[][] dp = new int[row][col]; - - for (int i = 0; i < col; i++) { - dp[0][i] = 1; - } - - for (int j = 0; j < row; j++) { - dp[j][0] = 1; - } - - for (int i = 1; i < row; i++) { - for (int j = 1; j < col; j++) { - dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; - } - } - return dp[row - 1][col - 1]; - } - - /** - * Now consider if some obstacles are added to the grids. How many unique paths would there be? - * Input: - * [ - * [0,0,0], - * [0,1,0], - * [0,0,0] - * ] - * Output: 2 - * Explanation: - * There is one obstacle in the middle of the 3x3 grid above. - * There are two ways to reach the bottom-right corner: - * 1. Right -> Right -> Down -> Down - * 2. Down -> Down -> Right -> Right - */ - private static int uniquePathII(int[][] obstacleGrid) { - - if (obstacleGrid[0][0] == 1) - return 0; - int m = obstacleGrid.length; - int n = obstacleGrid[0].length; - - int[][] dp = new int[obstacleGrid.length][obstacleGrid[0].length]; - - for (int i = 0; i < m; i++) { - if (obstacleGrid[i][0] == 1) { - dp[i][0] = 0; - break; - } else { - dp[i][0] = 1; - } - } - - for (int j = 0; j < n; j++) { - if (obstacleGrid[0][j] == 1) { - dp[0][j] = 0; - break; - } else { - dp[0][j] = 1; - } - } - - for (int i = 1; i < m; i++) { - for (int j = 1; j < n; j++) { - if (obstacleGrid[i][j] == 1) { - dp[i][j] = 0; - } else { - dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; - } - } - } - return dp[m - 1][n - 1]; - - } -} diff --git a/src/geeksforgeeks/UniquePathMaximum.java b/src/geeksforgeeks/UniquePathMaximum.java deleted file mode 100644 index ceef295..0000000 --- a/src/geeksforgeeks/UniquePathMaximum.java +++ /dev/null @@ -1,46 +0,0 @@ -package geeksforgeeks; - -/* -https://leetcode.com/discuss/interview-question/383669/ -*/ - -/** - * find the maximum score of a path starting at [0, 0] and ending at [r-1, c-1]. The score of a path is the minimum value in that path. - *

- * Input: - * [[1, 2, 3] - * [4, 5, 1]] - *

- * Output: 4 - * Explanation: - * Possible paths: - * 1-> 2 -> 3 -> 1 - * 1-> 2 -> 5 -> 1 - * 1-> 4 -> 5 -> 1 - * So min of all the paths = [2, 2, 4]. Note that we don't include the first and final entry. - */ -public class UniquePathMaximum { - - public static void main(String[] args) { - int[][] matrix = { { 6, 7, 8 }, { 5, 4, 2 }, { 8, 7, 6 } }; - System.out.println(findMaximumOfUniquePath(matrix)); - } - - private static int findMaximumOfUniquePath(int[][] matrix) { - for (int i = 1; i < matrix[0].length; i++) { - matrix[0][i] = Math.min(matrix[0][i], matrix[0][i - 1]); - } - - for (int j = 1; j < matrix.length; j++) { - matrix[j][0] = Math.min(matrix[j][0], matrix[j - 1][0]); - } - - for (int i = 1; i < matrix.length; i++) { - for (int j = 1; j < matrix[i].length; j++) { - matrix[i][j] = Math.max(Math.min(matrix[i - 1][j], matrix[i][j]), - Math.min(matrix[i][j - 1], matrix[i][j])); - } - } - return matrix[matrix.length - 1][matrix[0].length - 1]; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/UrlEncode.java b/src/geeksforgeeks/UrlEncode.java deleted file mode 100644 index d95694b..0000000 --- a/src/geeksforgeeks/UrlEncode.java +++ /dev/null @@ -1,45 +0,0 @@ -package geeksforgeeks; - -import java.util.stream.IntStream; - -/** - * Write a method to replace all the spaces in a string with ‘%20’. - * You may assume that the string has sufficient space at the end to hold the additional characters, - * and that you are given the “true” length of the string. - */ -public class UrlEncode { - public void replaceSpaces(char[] str, int trueLength) { - int i = str.length - 1; - int extra = str.length - trueLength; - int j = i - extra; - while (i != j) { - if (!Character.isSpaceChar(str[j])) { - str[i--] = str[j--]; - } else { - str[i--] = '0'; - str[i--] = '2'; - str[i--] = '%'; - j--; - } - } - } - - public static void main(String[] args) { - test(new char[17], "Mr John Smith"); - test(new char[12], "Mr John "); - test(new char[5], "Mr "); - test(new char[5], " Mr"); - test(new char[8], " Mr "); - test(new char[3], " "); - test(new char[20], "Mr John Smith"); - test(new char[0], ""); - } - - private static void test(char[] str, String s) { - IntStream.range(0, s.length()).forEach(i -> str[i] = s.charAt(i)); - System.out.print(new String(str) +" - "); - UrlEncode ob = new UrlEncode(); - ob.replaceSpaces(str, s.length()); - System.out.println(new String(str)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/ValidPalindromeII.java b/src/geeksforgeeks/ValidPalindromeII.java deleted file mode 100644 index 84768c8..0000000 --- a/src/geeksforgeeks/ValidPalindromeII.java +++ /dev/null @@ -1,40 +0,0 @@ -package geeksforgeeks; - -/** - * https://leetcode.com/problems/valid-palindrome-ii/ - */ -class ValidPalindromeII { - - public static boolean validPalindrome(String s) { - int i = 0, j = s.length() - 1; - while (i < j && s.charAt(i) == s.charAt(j)) { - i++; - j--; - } - - if (i >= j) { - return true; - } - - if (isPalindrome(s, i + 1, j) || isPalindrome(s, i, j - 1)) { - return true; - } - return false; - } - - private static boolean isPalindrome(String s, int i, int j) { - while (i < j) { - if (s.charAt(i) == s.charAt(j)) { - i++; - j--; - } else { - return false; - } - } - return true; - } - - public static void main(String[] args) { - System.out.println(validPalindrome("ddeeeef")); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/ValidParentheses.java b/src/geeksforgeeks/ValidParentheses.java deleted file mode 100644 index 9ba20a0..0000000 --- a/src/geeksforgeeks/ValidParentheses.java +++ /dev/null @@ -1,26 +0,0 @@ -package geeksforgeeks; - -import java.util.Stack; - -public class ValidParentheses { - - public static boolean isValid(String s) { - - Stack stack = new Stack<>(); - for (char c : s.toCharArray()) { - if (c == '(') - stack.push(')'); - else if (c == '{') - stack.push('}'); - else if (c == '[') - stack.push(']'); - else if (stack.isEmpty() || stack.pop() != c) - return false; - } - return stack.isEmpty(); - } - - public static void main(String[] args) { - System.out.println(isValid("({[])}")); - } -} diff --git a/src/geeksforgeeks/ValidParenthesesString.java b/src/geeksforgeeks/ValidParenthesesString.java deleted file mode 100644 index 326dff9..0000000 --- a/src/geeksforgeeks/ValidParenthesesString.java +++ /dev/null @@ -1,45 +0,0 @@ -package geeksforgeeks; - -/** - * Given a string containing only three types of characters: '(', ')' and '*', - * write a function to check whether this string is valid. - * We define the validity of a string by these rules: - * - * Any left parenthesis '(' must have a corresponding right parenthesis ')'. - * Any right parenthesis ')' must have a corresponding left parenthesis '('. - * Left parenthesis '(' must go before the corresponding right parenthesis ')'. - * '*' could be treated as a single right parenthesis ')' or a single left parenthesis '(' or an empty string. - * An empty string is also valid. - * - * Input: "(*))" - * Output: True - * - * Input: "(*)" - * Output: True - */ -public class ValidParenthesesString { - public boolean checkValidString(String s) { - int cmin = 0; - int cmax = 0; // open parentheses count in range [cmin, cmax] - for (char c : s.toCharArray()) { - if (c == '(') { - cmax++; - cmin++; - } else if (c == ')') { - cmax--; - cmin--; - } else if (c == '*') { - cmax++; // if `*` become `(` then openCount++ - cmin--; // if `*` become `)` then openCount-- - // if `*` become `` then nothing happens - // So openCount will be in new range [cmin-1, cmax+1] - } - if (cmax < 0) { - return false; // Currently, don't have enough open parentheses to match close parentheses-> Invalid - } - // For example: ())( - cmin = Math.max(cmin, 0); // It's invalid if open parentheses count < 0 that's why cmin can't be negative - } - return cmin == 0; // Return true if can found `openCount == 0` in range [cmin, cmax] - } -} diff --git a/src/geeksforgeeks/ValidSudoku.java b/src/geeksforgeeks/ValidSudoku.java deleted file mode 100644 index 5eb644e..0000000 --- a/src/geeksforgeeks/ValidSudoku.java +++ /dev/null @@ -1,35 +0,0 @@ -package geeksforgeeks; - -import java.util.HashSet; -import java.util.Set; - -public class ValidSudoku -{ - public boolean isValidSudoku(char[][] board) { - Set seen = new HashSet<>(); - - for (int i = 0; i < 9; i++) { - for (int j = 0; j < 9; j++) { - if (board[i][j] != '.') { - char number = board[i][j]; - if (!seen.add(number + "seen in row" + i) || !seen.add(number + "seen in col" + j) - || !seen.add(number + "seen in block" + i / 3 + "-" + j / 3)) { - return false; - } - } - } - } - - return true; - } - public static void main(String[] args) { - char[][] board = { { '5', '3', '.', '.', '7', '.', '.', '.', '.' }, - { '6', '.', '.', '1', '9', '5', '.', '.', '.' }, { '.', '9', '8', '.', '.', '.', '.', '6', '.' }, - { '8', '.', '.', '.', '6', '.', '.', '.', '3' }, { '4', '.', '.', '8', '.', '3', '.', '.', '1' }, - { '7', '.', '.', '.', '2', '.', '.', '.', '6' }, { '.', '6', '.', '.', '.', '.', '2', '8', '.' }, - { '.', '.', '.', '4', '1', '9', '.', '.', '5' }, { '.', '.', '.', '.', '8', '.', '.', '7', '9' } }; - - ValidSudoku vs = new ValidSudoku(); - System.out.println(vs.isValidSudoku(board)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/ValidateIpAddresses.java b/src/geeksforgeeks/ValidateIpAddresses.java deleted file mode 100644 index e28a7df..0000000 --- a/src/geeksforgeeks/ValidateIpAddresses.java +++ /dev/null @@ -1,65 +0,0 @@ -package geeksforgeeks; - -/** - * A valid IPv4 address is an IP in the form "x1.x2.x3.x4" - * where 0 <= xi <= 255 and xi cannot contain leading zeros. - * For example, "192.168.1.1" and "192.168.1.0" are valid IPv4 addresses but "192.168.01.1", - * while "192.168.1.00" and "192.168@1.1" are invalid IPv4 addresses. - * - * A valid IPv6 address is an IP in the form "x1:x2:x3:x4:x5:x6:x7:x8" where: - * - * 1 <= xi.length <= 4 - * xi is a hexadecimal string which may contain digits, - * lower-case English letter ('a' to 'f') and upper-case English letters ('A' to 'F'). - * Leading zeros are allowed in xi. - * For example, "2001:0db8:85a3:0000:0000:8a2e:0370:7334" - * and "2001:db8:85a3:0:0:8A2E:0370:7334" - * are valid IPv6 addresses, while "2001:0db8:85a3::8A2E:037j:7334" - * and "02001:0db8:85a3:0000:0000:8a2e:0370:7334" are invalid IPv6 addresses. - * - * Input: IP = "172.16.254.1" - * Output: "IPv4" - * Explanation: This is a valid IPv4 address, return "IPv4". - * - * Input: IP = "2001:0db8:85a3:0:0:8A2E:0370:7334" - * Output: "IPv6" - * Explanation: This is a valid IPv6 address, return "IPv6". - */ -public class ValidateIpAddresses { - // the condition for IPv4 is - // there should be 4 components separated by 3 dots - // each component should have value between 0-9 (base 10) - public String validIPAddress(String IP) { - if(IP==null || IP.length()==0) return "Neither"; - - if(IP.chars().filter(e->e=='.').count()==3){ - - for(String s: IP.split("\\.",-1)){ //-1 is for edge case like "1.0.1." - if(s.length()==0 || s.length()>4) return "Neither"; - if(s.charAt(0)=='0' && s.length()!=1) return "Neither"; - for(char c:s.toCharArray()) if(!Character.isDigit(c)) return "Neither"; - if(Integer.parseInt(s)>255) return "Neither"; - } - - return "IPv4"; - - } - // the condition for IPv6 is - // it should have 8 components, separated by 7 ':'s - // each component should have hex-value i.e 0-9, a-f or A-F - else if(IP.chars().filter(e->e==':').count()==7){ - for(String s: IP.split(":",-1)){ - if(s.length()==0 || s.length()>4) return "Neither"; - for(char c: s.toCharArray()){ - if(!((c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F'))){ - return "Neither"; - } - } - } - - return "IPv6"; - } - - return "Neither"; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/VulgarDecimal.java b/src/geeksforgeeks/VulgarDecimal.java deleted file mode 100644 index 6ec577b..0000000 --- a/src/geeksforgeeks/VulgarDecimal.java +++ /dev/null @@ -1,115 +0,0 @@ -package geeksforgeeks; - -/** - * https://leetcode.com/problems/fraction-to-recurring-decimal/ - *

- * Given two integers representing the numerator and denominator of a fraction, return the fraction in string format. - *

- * If the fractional part is repeating, enclose the repeating part in parentheses. - *

- * If multiple answers are possible, return any of them. - *

- * It is guaranteed that the length of the answer string is less than 104 for all the given inputs. - *

- * Input: numerator = 1, denominator = 2 - * Output: "0.5" - *

- * Input: numerator = 2, denominator = 1 - * Output: "2" - */ - - -import java.util.*; - -public class VulgarDecimal { - - public static String fractionToDecimal(long numerator, long denominator) { - if (denominator == 0) return null; - // if both are negative then the ans would be positive - boolean isNegative = (numerator < 0 && denominator > 0) || (numerator > 0 && denominator < 0); - - long denomiL = Math.abs(denominator); - long numerL = Math.abs(numerator); - - Map map = new HashMap<>(); - - StringBuilder sb = new StringBuilder(); - - sb.append((numerL / denomiL)); - - if (numerL % denomiL != 0) { - sb.append("."); - } - if (isNegative) sb.insert(0, "-"); - - numerL %= denomiL; - - if (numerL == 0) return sb.toString(); - - map.put(numerL, sb.length()); - - while (numerL > 0) { - - numerL *= 10; - sb.append((numerL / denomiL)); - numerL = (numerL % denomiL); - - if (map.containsKey(numerL)) { - int index = map.get(numerL); - sb.insert(index, "("); - sb.append(")"); - break; - } else { - map.put(numerL, sb.length()); - } - } - - return sb.toString(); - } - - public String fractionToDecimal(int numerator, int denominator) { - - boolean isNegative= numerator<0 && denominator>0 || numerator>0 && denominator<0; - - StringBuilder sb= new StringBuilder(); - Map map= new HashMap<>(); - long numeratorL= Math.abs(Long.valueOf(numerator)); - long denominatorL= Math.abs(Long.valueOf(denominator)); - - long rem=numeratorL/denominatorL; - sb.append(rem); - - - - if(isNegative) sb.insert(0,'-'); - - if(numeratorL%denominatorL>0){ - sb.append("."); - }else{ - return sb.toString(); - } - numeratorL%=denominatorL; - map.put(numeratorL,sb.length()); - - while(numeratorL>0){ - numeratorL*=10; - - rem=numeratorL/denominatorL; - sb.append(rem); - numeratorL%=denominatorL; - if(map.containsKey(numeratorL)){ - int pos= map.get(numeratorL); - sb.insert(pos,"("); - sb.append(")"); - break; - }else{ - map.put(numeratorL,sb.length()); - } - - } - - return sb.toString(); - } - - -} diff --git a/src/geeksforgeeks/WaterTrapping.java b/src/geeksforgeeks/WaterTrapping.java deleted file mode 100644 index e76f6eb..0000000 --- a/src/geeksforgeeks/WaterTrapping.java +++ /dev/null @@ -1,37 +0,0 @@ -package geeksforgeeks; - -class WaterTrapping { - - static int findWater(int arr[], int n) { - int result = 0; - int leftMax = 0; - int rightMax = 0; - int low = 0; - int high = n - 1; - - while (low < high) { - if (arr[low] < arr[high]) { - if (arr[low] > leftMax) { - leftMax = arr[low]; - } else { - result += leftMax - arr[low]; - } - low++; - } else { - if (arr[high] > rightMax) { - rightMax = arr[high]; - } else { - result += rightMax - arr[high]; - } - high--; - } - } - return result; - } - - public static void main(String[] args) { - int arr[] = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1}; - int n = arr.length; - System.out.println("Maximum water that " + "can be accumulated is " + findWater(arr, n)); - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/WordBreak.java b/src/geeksforgeeks/WordBreak.java deleted file mode 100644 index 87d0ecb..0000000 --- a/src/geeksforgeeks/WordBreak.java +++ /dev/null @@ -1,83 +0,0 @@ -package geeksforgeeks; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -class WordBreak { - - /* -|T| | | | | | | | | - 0 1 2 3 4 5 6 7 8 - -i = 1 -j = o sub = l - -i = 2 -j = 0 sub = le -j = 1 sub = e - -i = 3 -j = 0 sub = lee -j = 1 sub = ee -j = 2 sub = e - -i = 4 -j = 0 sub = leet && T[0] and then break, no need to check for rest -|T | | | |T| | | | | -0 1 2 3 4 5 6 7 8 - -i = 5 -j = 0 sub = leetc -j = 1 sub = eetc -j = 2 sub = etc -j = 3 sub = tc -j = 4 sub = c - -i = 6 -j = 0 sub = leetco -j = 1 sub = eetco -j = 2 sub = etco -j = 3 sub = tco -j = 4 sub = co -j = 5 sub = o - -i = 7 -j = 0 sub = leetcod -j = 1 sub = eetcod -j = 2 sub = etcod -j = 3 sub = tcod -j = 4 sub = cod -j = 5 sub = od -j = 6 sub = d - -i = 8 -j = 0 sub = leetcode -j = 1 sub = eetcode -j = 2 sub = etcode -j = 3 sub = tcode -j = 4 sub = code && T[4] and then break - -|T| | | |T| | | |T| - 0 1 2 3 4 5 6 7 8 -*/ - public boolean wordBreak(String s, List wordDict) { - if (s == null) { - return false; - } - boolean[] dp = new boolean[s.length() + 1]; - dp[0] = true; - Set set = new HashSet<>(wordDict); - - for (int i = 1; i <= s.length(); i++) { - for (int j = 0; j < i; j++) { - dp[i] = dp[j] && set.contains(s.substring(j, i)); - if (dp[i]) { - break; - } - } - } - - return dp[s.length()]; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/WordBreakII.java b/src/geeksforgeeks/WordBreakII.java deleted file mode 100644 index 2dc3ee1..0000000 --- a/src/geeksforgeeks/WordBreakII.java +++ /dev/null @@ -1,33 +0,0 @@ -package geeksforgeeks; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class WordBreakII { - public List wordBreak(String s, List wordDict) { - Map> cache = new HashMap<>(); - backtrack(s,wordDict, cache); - return cache.get(s); - } - - public List backtrack(String s, List wordDict, Map> cache){ - - if(cache.containsKey(s)) return cache.get(s); - - List result = new ArrayList<>(); - for(String word: wordDict) { - if(!s.startsWith(word)) continue; // string does not start with this word? - String next = s.substring(word.length()); - if(next.isEmpty()) { // awesome! - result.add(word); - continue; - } - for(String sub: backtrack(next, wordDict, cache)) - result.add(word + " " + sub); - } - cache.put(s, result); - return result; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/WordDictionary.java b/src/geeksforgeeks/WordDictionary.java deleted file mode 100644 index 446c210..0000000 --- a/src/geeksforgeeks/WordDictionary.java +++ /dev/null @@ -1,69 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; -import java.util.Map; - -/** - * Design a data structure that supports the following two operations: - * void addWord(word) - * bool search(word) - * search(word) can search a literal word or - * a regular expression string containing only letters a-z or .. A . - * means it can represent any one letter. - * addWord("bad") - addWord("dad") - addWord("mad") - search("pad") -> false - search("bad") -> true - search(".ad") -> true - search("b..") -> true - */ -public class WordDictionary { - private TrieNode root; - - /** Initialize your data structure here. */ - private class TrieNode { - public Map children = new HashMap<>(); - public boolean isWord; - } - - public WordDictionary() { - root = new TrieNode(); - } - - /** Adds a word into the data structure. */ - public void addWord(String word) { - - TrieNode temp = root; - - for (char c : word.toCharArray()) { - if (temp.children.get(c) == null) - temp.children.put(c, new TrieNode()); - - temp = temp.children.get(c); - } - - temp.isWord = true; - } - - /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ - public boolean search(String word) { - return match(word.toCharArray(), 0, root); - } - - private boolean match(char[] chs, int k, TrieNode node) { - - if (k == chs.length) - return node.isWord; - - if (chs[k] == '.') { - for (Character curr: node.children.keySet()) { - if (node.children.get(curr) != null && match(chs, k+1, node.children.get(curr))) - return true; - } - } else - return node.children.get(chs[k]) != null && match(chs, k + 1, node.children.get(chs[k])); - - return false; - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/WordLadder.java b/src/geeksforgeeks/WordLadder.java deleted file mode 100644 index 74aa0d1..0000000 --- a/src/geeksforgeeks/WordLadder.java +++ /dev/null @@ -1,45 +0,0 @@ -package geeksforgeeks; - -import java.util.*; - -public class WordLadder { - public int ladderLength(String beginWord, String endWord, List wordList) { - Set set = new HashSet(wordList); - if(!set.contains(endWord)) return 0; // end word itself not in set - Queue queue = new LinkedList(); - queue.add(beginWord); - int count = 1; - - while(!queue.isEmpty()) { - - int size = queue.size(); - for (int i =0; i= board.length || i < 0 || j >= board[i].length || j < 0 || board[i][j] != word.charAt(index)) { - return false; - } - - board[i][j] = ' '; - if (search(board, word, i - 1, j, index + 1) || search(board, word, i + 1, j, index + 1) - || search(board, word, i, j - 1, index + 1) || search(board, word, i, j + 1, index + 1)) { - return true; - } - // resetting to old char since its DFS - - board[i][j] = word.charAt(index); - return false; - } - - public static void main(String[] args) { - char[][] board = {{'C', 'A', 'A'}, - {'A', 'A', 'A'}, - {'B', 'C', 'D'}}; - - System.out.println(exist(board, "AAB")); - } -} diff --git a/src/practiceproblems/CountingInversion.java b/src/practiceproblems/CountingInversion.java index 771cda7..eb81ddd 100644 --- a/src/practiceproblems/CountingInversion.java +++ b/src/practiceproblems/CountingInversion.java @@ -56,7 +56,8 @@ static int merge(int[] arr, int[] temp, int left, int mid, int right) { } public static void main(String[] args) { - int arr[] = new int[] { 4, 6, 2, 1, 9, 7 }; + //int arr[] = new int[] { 4, 6, 2, 1, 9, 7 }; + int arr[] = new int[]{5, 1, 4, 2}; System.out.println("Number of inversions are " + mergeSort(arr, arr.length)); } } diff --git a/src/practiceproblems/PascalsTriangle.java b/src/practiceproblems/PascalsTriangle.java index 643ec7b..532be23 100644 --- a/src/practiceproblems/PascalsTriangle.java +++ b/src/practiceproblems/PascalsTriangle.java @@ -20,40 +20,9 @@ */ public class PascalsTriangle { - public List> generate(int numRows) { - - if (numRows == 0) { - return Collections.emptyList(); - } - - List> result = new ArrayList<>(); - List first = Arrays.asList(1); - result.add(first); - if (numRows == 1) { - return result; - } - List second = Arrays.asList(1, 1); - result.add(second); - if (numRows == 2) { - return result; - } - - for (int i = 2; i < numRows; i++) { - List temp = new ArrayList<>(); - temp.add(1); - for (int k = 0; k < i - 1; k++) { - int j = k + 1; - temp.add(result.get(i - 1).get(k) + result.get(i - 1).get(j)); - } - temp.add(1); - result.add(temp); - } - return result; - } - public List> generate1(int numRows) { - List> allrows = new ArrayList>(); - ArrayList row = new ArrayList(); + List> allrows = new ArrayList<>(); + ArrayList row = new ArrayList<>(); for (int i = 0; i < numRows; i++) { // suppose if the row is [1,3,3,1] // add 1 at start [1,1,3,3,1] @@ -62,7 +31,7 @@ public List> generate1(int numRows) { row.add(0, 1); for (int j = 1; j < row.size() - 1; j++) row.set(j, row.get(j) + row.get(j + 1)); - allrows.add(new ArrayList(row));// every time the copy is only appended + allrows.add(new ArrayList<>(row));// every time the copy is only appended } return allrows; diff --git a/src/sorting/ImplementABinaryHeap.java b/src/sorting/ImplementABinaryHeap.java index b15289c..f016563 100644 --- a/src/sorting/ImplementABinaryHeap.java +++ b/src/sorting/ImplementABinaryHeap.java @@ -1,4 +1,4 @@ -package strings.common.sorting; +package sorting; /* A min heap implementation diff --git a/src/sorting/InsertionSort.java b/src/sorting/InsertionSort.java index 2c2bb37..2eafe7e 100644 --- a/src/sorting/InsertionSort.java +++ b/src/sorting/InsertionSort.java @@ -1,4 +1,4 @@ -package strings.common.sorting; +package sorting; public class InsertionSort { diff --git a/src/sorting/KthLargestElement.java b/src/sorting/KthLargestElement.java index dde0566..8d8434c 100644 --- a/src/sorting/KthLargestElement.java +++ b/src/sorting/KthLargestElement.java @@ -1,4 +1,4 @@ -package strings.common.sorting; +package sorting; import java.util.*; diff --git a/src/sorting/MaxHeap.java b/src/sorting/MaxHeap.java index d4c8532..577bcfe 100644 --- a/src/sorting/MaxHeap.java +++ b/src/sorting/MaxHeap.java @@ -1,4 +1,4 @@ -package strings.common.sorting; +package sorting; public class MaxHeap { diff --git a/src/sorting/MergeSort.java b/src/sorting/MergeSort.java index 9e3c8e1..b2d046d 100644 --- a/src/sorting/MergeSort.java +++ b/src/sorting/MergeSort.java @@ -1,4 +1,4 @@ -package strings.common.sorting; +package sorting; import java.util.Arrays; diff --git a/src/sorting/PractiseMergeSort.java b/src/sorting/PractiseMergeSort.java index 20330d8..07970f4 100644 --- a/src/sorting/PractiseMergeSort.java +++ b/src/sorting/PractiseMergeSort.java @@ -1,4 +1,4 @@ -package strings.common.sorting; +package sorting; import java.util.Arrays; diff --git a/src/sorting/QuickSelect.java b/src/sorting/QuickSelect.java index e8e251b..1866b44 100644 --- a/src/sorting/QuickSelect.java +++ b/src/sorting/QuickSelect.java @@ -1,4 +1,4 @@ -package strings.common.sorting; +package sorting; import java.util.Random; diff --git a/src/sorting/QuickSort.java b/src/sorting/QuickSort.java index b585d25..d067654 100644 --- a/src/sorting/QuickSort.java +++ b/src/sorting/QuickSort.java @@ -1,4 +1,4 @@ -package strings.common.sorting; +package sorting; import java.util.Random; diff --git a/src/strings/stringProblems/FindLongestStringInArray.java b/src/strings/stringProblems/FindLongestStringInArray.java index 703c784..357b31b 100644 --- a/src/strings/stringProblems/FindLongestStringInArray.java +++ b/src/strings/stringProblems/FindLongestStringInArray.java @@ -6,7 +6,7 @@ public class FindLongestStringInArray { public static void main(String[] args) { - String arr[] = { "geeks", "for", "geeksfor", "geeksforgeeks" }; + String arr[] = { "geeks", "for", "geeksfor", "practiceproblems"}; StringComparator str = new StringComparator(); Arrays.sort(arr, str); System.out.println(Arrays.toString(arr)); From 0df6bc82c5cf3eb605bf9ee029d23237261fad91 Mon Sep 17 00:00:00 2001 From: vickey290 Date: Sat, 23 Jul 2022 16:12:12 +0530 Subject: [PATCH 45/51] 2022 problem set --- pom.xml | 33 + .../CombinationSum.java | 76 -- .../MagneticForceBetweenTwoBalls.java | 68 -- src/binarysearch/PeakElement.java | 47 - src/binarysearch/Sqrt.java | 22 - src/common/sorting/ImplementABinaryHeap.java | 248 ----- src/common/sorting/InsertionSort.java | 30 - src/common/sorting/KthLargestElement.java | 62 -- src/common/sorting/MaxHeap.java | 51 - src/common/sorting/MergeSort.java | 47 - src/common/sorting/PractiseMergeSort.java | 48 - src/common/sorting/QuickSelect.java | 50 - src/common/sorting/QuickSort.java | 57 - .../CatalanNumberBinarySearchTree.java | 27 - src/dynamicProgramming/MaximumSquareDP.java | 23 - src/dynamicProgramming/MinCostTickets.java | 42 - src/dynamicProgramming/MinimumCoinChange.java | 28 - .../MinimumNumberOfJumpsToReachEnd.java | 64 -- src/dynamicProgramming/OptimalStratergy.java | 66 -- .../StockBuySellKTransactions.java | 103 -- .../StockBuySellWithCoolDown.java | 53 - src/dynamicProgramming/Sudoku.java | 162 --- src/dynamicProgramming/UniqueCoinChange.java | 25 - src/dynamicProgramming/WordBreak.java | 109 -- src/dynamicProgramming/WordBreakII.java | 34 - .../fibonacci/DecodeWays.java | 74 -- .../fibonacci/DiceThrow.java | 40 - .../FibonacciStaircaseWaysToCoverDist.java | 72 -- .../lcs/BitonicSequence.java | 52 - .../lcs/LongestCommonSubsequence.java | 86 -- .../lcs/LongestIncreasingSubsequence.java | 112 -- .../lcs/MaximumProductSubarray.java | 38 - .../lcs/TwoStringInterleavingToFormThird.java | 45 - .../lcs/WildCardMatching.java | 85 -- .../matrix/MatrixMultiplicationCost.java | 43 - .../matrix/MaximumSizeSubMatrix.java | 57 - .../matrix/MinCostPath.java | 41 - .../oiknapsack/EqualSubsetSumPartition.java | 76 -- .../CoinChangingMinimumCoin.java | 65 -- .../unboundedknapsack/CuttingRod.java | 31 - .../Combinations.java | 67 -- .../Permutations.java | 63 -- .../CombinationsAndPermutations/SubSets.java | 67 -- src/graph/leetcode/CheapestFlightKStops.java | 72 -- src/graph/leetcode/ConnectCities.java | 64 -- src/graph/leetcode/ConnectMissingCities.java | 54 - src/graph/leetcode/CourseSchedule.java | 115 -- src/graph/leetcode/GraphBiPartite.java | 53 - src/graph/leetcode/NetworkDelayTime.java | 70 -- .../leetcode/NewRoadsMinimumSpanningTree.java | 87 -- src/graph/leetcode/RedundantConnection.java | 59 -- src/graph/leetcode/SnapShotUtil.java | 52 - src/linkedLists/FlattenDoublyLinkedList.java | 33 - src/linkedLists/ReverseKBlockNode.java | 78 -- src/linkedLists/RotateList.java | 84 -- .../java}/RandomProblemGenerator.java | 8 +- .../java}/SQL/AlterTableWithMonthName.sql | 0 .../java}/SQL/ClassHavingMoreStudents.sql | 0 .../java}/SQL/CustomersNerverOrders.sql | 0 src/{ => main/java}/SQL/DeleteDuplicate.sql | 0 .../java}/SQL/DepartmentHighestSalary.sql | 0 src/{ => main/java}/SQL/DuplicateEmail.sql | 0 .../SQL/EmployeeEarningHigherThanManagers.sql | 0 src/{ => main/java}/SQL/ExchangeSeats.sql | 0 src/{ => main/java}/SQL/FirstLoginDate.sql | 0 .../java}/SQL/ManagerHaving5OrMoreReport.sql | 0 src/{ => main/java}/SQL/NthHighestSalary.sql | 0 src/{ => main/java}/SQL/RisingTemperature.sql | 0 src/{ => main/java}/SQL/SubjectRanks.sql | 0 src/{ => main/java}/SQL/TeamSize.sql | 0 src/{ => main/java}/SQL/Top3Salaries.sql | 0 .../java}/SQL/Top3SalaryDepartmentWise.sql | 0 src/main/java/SQL/TopKthSalary.sql | 5 + src/{ => main/java}/SQL/WinningCandidate.sql | 0 .../binarysearch/BinarySearchTemplate.java | 0 .../java/binarysearch}/BoatsToSave.java | 26 +- .../FindMinimumInRotatedArray.java | 0 .../java/binarysearch/FindPeakElement.java | 27 + .../binarysearch/FindSmallestDivisor.java | 0 .../binarysearch/FirstAndLastOccurence.java | 0 .../java}/binarysearch/FirstBadVersion.java | 0 .../java/binarysearch/KClosestElements.java | 113 ++ .../java}/binarysearch/KokoEatingBananas.java | 0 .../KthSmallestInMultiplicationTable.java | 0 .../MagneticForceBetweenTwoBalls.java | 65 ++ .../java}/binarysearch/MaxSoldiers.java | 7 +- .../NumberOfDaysToMakeMBouquets.java | 12 +- .../SearchElementInSortedAndRotatedArray.java | 77 +- .../binarysearch/SearchInsertPosition.java | 13 +- .../binarysearch/ShipPackageWithNDays.java | 32 +- .../SingleElementInSortedArray.java | 118 +++ src/main/java/binarysearch/Sqrt.java | 26 + .../java}/binarysearch/SubArraySplitSum.java | 2 +- .../SumMutatedArrayCloseTarget.java | 44 + .../BeautifulArrangements.java | 26 + .../CanPartitionKSubSets.java | 37 + .../CombinationIterator.java | 39 +- .../CombinationSum.java | 125 +++ .../FactorCombinations.java | 33 + .../Permutations.java | 44 +- .../SplitUniqueSubstring.java | 42 + .../combinationsandpermutations}/SubSets.java | 0 .../AssemblyLineScheduling.java | 18 +- .../BooleanParenthesization.java | 6 +- .../java}/dynamicProgramming/BoxStacking.java | 107 +- .../CatalanNumberBinarySearchTree.java | 81 ++ .../java}/dynamicProgramming/EggDropping.java | 0 .../java/dynamicProgramming/KnightDialer.java | 73 ++ .../dynamicProgramming/LastStoneWeight.java | 111 ++ .../MakeArrayStrictlyIncreasing.java | 32 + .../MaxGoldAMinerCanGet.java | 48 + .../MaxSumForNonAdjacentElements.java | 0 .../dynamicProgramming/MaximumRectangle.java | 99 ++ .../dynamicProgramming/MinCoinChange.java | 50 + .../dynamicProgramming/MinCostTickets.java | 67 ++ .../MinSwapsToMakeArrayIncreasing.java | 113 ++ .../MonotoneIncreasingString.java | 78 ++ .../NumberWithSameConsequtiveDifference.java | 9 +- .../dynamicProgramming/OnesAndZeroes.java | 45 + .../dynamicProgramming/OptimalStratergy.java | 130 +++ .../dynamicProgramming/OptimalTreeSearch.java | 0 .../java/dynamicProgramming/OutOfBounds.java | 32 + .../java/dynamicProgramming/PaintHouses.java | 27 + .../dynamicProgramming}/PerfectSquare.java | 20 +- .../java/dynamicProgramming/StoneGame.java | 78 ++ .../java/dynamicProgramming/TargetSum.java | 111 ++ .../java/dynamicProgramming/TriangleSum.java | 64 ++ .../dynamicProgramming/TwoKeysKeyBoard.java | 49 + .../dynamicProgramming/UniqueCoinChange.java | 36 + .../fibonacci/DecodeWays.java | 83 ++ .../fibonacci/DiceThrow.java | 38 + .../FibonacciStaircaseWaysToCoverDist.java | 110 ++ .../lcs/BitonicSequence.java | 70 ++ .../dynamicProgramming/lcs/DeleteAndEarn.java | 70 ++ .../dynamicProgramming/lcs/EditDistance.java | 24 +- .../lcs/LongestCommonSubsequence.java | 72 ++ .../lcs/LongestCommonSubstring.java | 0 .../lcs/LongestIncreasingSubsequence.java | 133 +++ .../lcs/LongestStringChain.java | 89 ++ .../lcs/MaximumContiguousSubarraySum.java | 0 .../lcs/MaximumLengthRepeatedSubarray.java | 25 + .../lcs/MaximumSumIncreasingSubsequence.java | 8 +- .../lcs/MinimumAsciiDelete.java | 96 ++ .../lcs/NumberOfDistinctSubSequence.java | 56 + .../dynamicProgramming/lcs/NumberOfLIS.java | 76 ++ .../lcs/RussianDollEnvelope.java | 63 ++ .../lcs/ShortestCommonSupersequence.java | 65 ++ .../lcs/TwoStringInterleavingToFormThird.java | 71 ++ .../lcs/WildCardMatching.java | 123 +++ .../matrix/MatrixMultiplicationCost.java | 43 + .../matrix/MaximumSquareDP.java | 51 + .../matrix/MinCostPath.java | 52 + .../matrix/MinimumFallingPathMatrix.java | 36 + .../oiknapsack/EqualSubsetSumPartition.java | 108 ++ .../oiknapsack/MinPartition.java | 0 .../oiknapsack/MinimumSubsetSum.java | 0 .../NumberOfUniqueWaysToMakeChange.java | 0 .../oiknapsack/O1KnapsackSpaceOptimized.java | 52 +- .../oiknapsack/SubsetSumProblem.java | 2 +- .../palindrome/CountSubStrings.java | 57 + .../LongestPalindromicSubsequence.java | 17 +- .../LongestPalindromicSubstring.java | 33 +- .../palindrome}/PalindromePartitioning.java | 26 +- .../palindrome/PalindromePartitioningII.java | 111 ++ .../stocks}/BuyAndSellStockAnytime.java | 10 +- .../stocks/BuyAndSellStockAtMostTwice.java | 74 ++ .../stocks/BuyAndSellWithTransactionFee.java | 48 + .../stocks/StockBuySellKTransactions.java | 157 +++ .../stocks/StockBuySellWithCoolDown.java | 82 ++ .../unboundedknapsack/CuttingRod.java | 80 ++ .../java/graph}/ArticulationPoint.java | 2 +- .../graph/adjacencyList/AdjacencyList.java | 0 .../adjacencyMatrix/AdjacencyMatrix.java | 0 .../java}/graph/bellmanFord/BellmanFord.java | 0 .../java}/graph/bellmanFord/Edge.java | 0 .../java}/graph/bellmanFord/Graph.java | 0 .../graph/bellmanFord/NegativeException.java | 0 .../java}/graph/bellmanFord/Vertex.java | 0 .../BreadthFirstSearch.java | 0 .../java}/graph/breadthFirstSearch/Graph.java | 0 .../graph/cycle/CycleInDirectedGraph.java | 0 .../graph/cycle/CycleUndirectedGraph.java | 0 src/{ => main/java}/graph/cycle/Graph.java | 0 .../depthFirstSearch/DepthFirstSearch.java | 0 .../java}/graph/depthFirstSearch/Graph.java | 0 .../graph/dijkstraAlgorithm/BinaryHeap.java | 2 +- .../dijkstraAlgorithm/DijkstraAlgorithm.java | 0 .../java}/graph/dijkstraAlgorithm/Graph.java | 0 .../DisjointSetArrayImplementation.java | 0 .../graph/disjoints/DisjointSetWithNode.java | 0 .../graph/disjoints/PredatorDisjointSet.java | 0 .../graph/disjoints/RankTransformMatrix.java | 147 +++ .../graph/floydwarshall/FloydWarshall.java | 0 .../java}/graph/interview/DisjointSet.java | 0 .../graph/kruskalAlgorithm/DisjointSet.java | 0 .../java}/graph/kruskalAlgorithm/Graph.java | 0 .../graph/kruskalAlgorithm/KruskalMST.java | 0 .../java/graph/leetcode/AccountsMerge.java | 130 +++ .../java/graph/leetcode/AlienDictionary.java | 110 ++ .../java}/graph/leetcode/AllPathsInGraph.java | 6 +- .../java/graph/leetcode/ArrayNesting.java | 89 ++ .../java/graph/leetcode/CanVisitAllRooms.java | 42 + .../graph/leetcode/CheapestFlightKStops.java | 104 ++ .../java/graph/leetcode/ClosedIsland.java | 49 + .../java/graph/leetcode/ConnectCities.java | 68 ++ .../leetcode/ConnectCitiesWithDiscount.java | 72 ++ .../leetcode/ConnectedComponentsInGraph.java | 6 +- .../java/graph/leetcode/CourseSchedule.java | 170 +++ .../java/graph/leetcode/CourseScheduleII.java | 211 ++++ .../leetcode/CriticalConnectionInGraph.java | 86 ++ .../graph/leetcode/EmployeeImportance.java | 50 + .../java/graph/leetcode/EquationEquality.java | 91 ++ .../graph/leetcode/FindAllSafeStates.java | 43 + .../java}/graph/leetcode/FindJudge.java | 0 src/main/java/graph/leetcode/FindTheCity.java | 126 +++ .../java}/graph/leetcode/FriendCircles.java | 1 + .../java/graph/leetcode/GraphBiPartite.java | 32 + .../leetcode/GraphBiPartitePossiblity.java | 40 + .../java/graph/leetcode/GraphValidTree.java | 60 ++ .../java/graph/leetcode}/IslandBFS.java | 2 +- .../java/graph/leetcode/MakeIslandLarger.java | 129 +++ .../graph/leetcode/MatrixStoneRemoval.java | 71 ++ .../graph/leetcode/MaxDistanceFromWater.java | 39 + .../graph/leetcode/MaxProbabilityPath.java | 47 + .../leetcode/MinCostConnectAllPipes.java | 82 ++ .../graph/leetcode/MinCostConnectCities.java | 74 ++ .../graph/leetcode/MinCostConnectPoints.java | 90 ++ .../graph/leetcode/MinCostRepairEdges.java | 3 +- .../leetcode/MinPathHavingMaxDifference.java | 89 ++ .../graph/leetcode/MinStepsToCutTrees.java | 94 ++ .../graph/leetcode/MinimumHeightTrees.java | 63 ++ .../graph/leetcode/NetworkConnection.java | 62 ++ .../java/graph/leetcode/NetworkDelayTime.java | 94 ++ .../java/graph/leetcode}/NewRoadsMST.java | 73 +- .../java/graph/leetcode/PacificAtlantic.java | 71 ++ .../graph/leetcode/ReconstructItenary.java | 62 ++ .../graph/leetcode/RedundantConnection.java | 65 ++ .../graph/leetcode/RedundantConnectionII.java | 126 +++ src/main/java/graph/leetcode/RoadsToRome.java | 59 ++ .../graph/leetcode/SentenceSimilarityII.java | 6 +- .../java/graph/leetcode/ShortestBridge.java | 76 ++ .../graph/leetcode/ShortestPathToGetFood.java | 66 ++ .../graph/leetcode/TimeToInformEmployee.java | 45 + .../graph/primsAlgorithm/BinaryMinHeap.java | 0 .../java}/graph/primsAlgorithm/Graph.java | 0 .../java}/graph/primsAlgorithm/PrimMST.java | 0 .../graph/primsAlgorithm/PrimsMSTArray.java | 0 .../java}/graph/shortestPath/Graph.java | 0 .../graph/shortestPath/ShortestPath.java | 0 .../java}/graph/topologicalsort/Graph.java | 0 .../topologicalsort/TopologicalSort.java | 0 .../topologicalsort/TopologicalSortList.java | 0 .../java}/internals/ConcurrentHashMap.java | 0 src/{ => main/java}/internals/HashMap.java | 0 .../java}/internals/HashMapJava8.java | 0 .../java}/internals/LinkedHashMap.java | 0 .../java}/internals/MyBlockingQueue.java | 0 src/main/java/internals/QuadTree.java | 95 ++ .../java}/internals/SJUArrayList.java | 0 src/main/java/internals/SkipList.java | 189 ++++ src/main/java/internals/ThreadPool.java | 106 ++ .../java/internals/TwitterSnowflakeUUID.java | 119 +++ src/{ => main/java}/java8/Books.txt | 0 .../java}/java8/CustomCollectors.java | 0 .../java}/java8/CustomSpliterator.java | 0 .../java}/java8/DesignPatternJava8.java | 0 src/{ => main/java}/java8/EmployeeData.txt | 0 .../java8/FunctionalInterfaceExamples.java | 0 src/{ => main/java}/linkedLists/Agoda.java | 0 .../java}/linkedLists/AllProblems.java | 0 .../java}/linkedLists/ArrayToBST.java | 0 .../CloneRandomPointerLinkedList.java | 0 .../java}/linkedLists/DLLToBBST.java | 0 .../linkedLists/DLLToBBSTTimeEfficiency.java | 0 .../linkedLists/DetectAndRemoveLoop.java | 0 .../java}/linkedLists/FlattenLinkedList.java | 0 .../FlattenMultiLevelLinkedList.java | 35 +- .../linkedLists/FlattenNestedIterator.java | 0 .../java/linkedLists/InsertionSortList.java | 52 + .../LinkedListRemoveDuplicates.java | 4 +- .../java}/linkedLists/LinkedListToBST.java | 0 src/{ => main/java}/linkedLists/Main.java | 0 .../java/linkedLists/MergeKSortedLists.java | 65 ++ .../linkedLists}/MergeSortLinkedList.java | 19 +- .../java/linkedLists}/MergeTwoLinkedList.java | 2 +- .../linkedLists/MergeTwoLinkedLists.java | 0 .../java}/linkedLists/MiddleElement.java | 0 .../java/linkedLists}/NextLargestList.java | 2 +- src/{ => main/java}/linkedLists/Node.java | 0 .../PalindromeSinglyLinkedList.java | 0 .../java}/linkedLists/RandomListNode.java | 0 .../java/linkedLists/RemoveDuplicates.java | 80 ++ .../java/linkedLists/ReverseKBlockNode.java | 117 +++ .../java}/linkedLists/ReverseLinkedList.java | 0 .../ReverseLinkedListBetweenMandN.java | 0 .../java}/linkedLists/ReversePairsNode.java | 0 src/main/java/linkedLists/RotateList.java | 29 + .../linkedLists/SinglyLinkedListNode.java | 0 .../java/linkedLists}/SplitLinkedList.java | 4 +- .../java}/linkedLists/StackImpl.java | 0 .../StackOperationUsingLinkedList.java | 0 .../linkedLists/Top20LinkedListQuestions.java | 0 .../enums/AuctionProductState.java | 8 + .../lld/auctionSystem/enums/AuctionState.java | 9 + .../java/lld/auctionSystem/enums/Channel.java | 8 + .../lld/auctionSystem/enums/ObserverType.java | 7 + .../enums/PublisherEventType.java | 7 + .../lld/auctionSystem/models/Auction.java | 81 ++ .../auctionSystem/models/AuctionProduct.java | 75 ++ .../java/lld/auctionSystem/models/Buyer.java | 18 + .../java/lld/auctionSystem/models/Event.java | 36 + .../auctionSystem/models/Notification.java | 34 + .../lld/auctionSystem/models/Observer.java | 4 + .../lld/auctionSystem/models/Product.java | 53 + .../lld/auctionSystem/models/Publisher.java | 23 + .../java/lld/auctionSystem/models/Seller.java | 16 + .../java/lld/auctionSystem/models/User.java | 70 ++ .../repository/AuctionRepository.java | 34 + .../repository/BuyerRepository.java | 36 + .../repository/ProductRepository.java | 34 + .../repository/SellerRepository.java | 38 + .../services/AuctionService.java | 342 ++++++ .../auctionSystem/services/BuyerService.java | 164 +++ .../services/ObserverService.java | 11 + .../services/PublisherService.java | 16 + .../auctionSystem/services/SellerService.java | 94 ++ .../services/strategies/AuctionDetails.java | 5 + .../strategies/BuyerViewAuctionDetails.java | 45 + .../strategies/SellerViewAuctionDetails.java | 46 + .../java/lld/auctionSystem/utils/Utils.java | 15 + .../java/lld/billsharing/BillSharingMain.java | 110 ++ .../ContributionExceededException.java | 12 + .../ExpenseDoesNotExistsException.java | 13 + .../exceptions/ExpenseSettledException.java | 12 + .../exceptions/InvalidExpenseState.java | 13 + .../lld/billsharing/model/Contribution.java | 16 + .../java/lld/billsharing/model/Expense.java | 22 + .../lld/billsharing/model/ExpenseGroup.java | 26 + .../lld/billsharing/model/ExpenseStatus.java | 7 + src/main/java/lld/billsharing/model/User.java | 23 + .../java/lld/billsharing/model/UserShare.java | 19 + .../repository/ExpenseRepository.java | 14 + .../repository/UserRepository.java | 14 + .../billsharing/service/ExpenseService.java | 88 ++ .../service/NotificationService.java | 8 + .../service/NotificationServiceImpl.java | 12 + .../lld/billsharing/service/UserService.java | 61 ++ src/main/java/lld/elevator/TestElevator.java | 413 ++++++++ .../lld/vendingmachine/HasMoneyState.java | 34 + src/main/java/lld/vendingmachine/Main.java | 50 + .../java/lld/vendingmachine/NoMoneyState.java | 35 + .../java/lld/vendingmachine/SoldOutState.java | 33 + .../java/lld/vendingmachine/SoldState.java | 43 + src/main/java/lld/vendingmachine/State.java | 8 + .../lld/vendingmachine/VendingMachine.java | 87 ++ .../vendingmachine/VendingMachineState.java | 11 + .../snakesandladder/DiceService.java | 9 + .../machinecoding/snakesandladder/Driver.java | 36 + .../machinecoding/snakesandladder/Ladder.java | 20 + .../machinecoding/snakesandladder/Player.java | 21 + .../machinecoding/snakesandladder/Snake.java | 20 + .../snakesandladder/SnakeAndLadderBoard.java | 48 + .../SnakeAndLadderService.java | 148 +++ .../java/machinecoding/splitwise/Driver.java | 64 ++ .../machinecoding/splitwise/EqualExpense.java | 20 + .../machinecoding/splitwise/EqualSplit.java | 8 + .../machinecoding/splitwise/ExactExpense.java | 31 + .../machinecoding/splitwise/ExactSplit.java | 9 + .../java/machinecoding/splitwise/Expense.java | 60 ++ .../splitwise/ExpenseManager.java | 78 ++ .../splitwise/ExpenseMetadata.java | 37 + .../splitwise/ExpenseService.java | 28 + .../machinecoding/splitwise/ExpenseType.java | 7 + .../splitwise/PercentExpense.java | 27 + .../machinecoding/splitwise/PercentSplit.java | 18 + .../java/machinecoding/splitwise/Split.java | 26 + .../java/machinecoding/splitwise/User.java | 47 + .../machinecoding/uditagarwal/chess/Main.java | 8 + .../chess/conditions/MoveBaseCondition.java | 12 + .../MoveBaseConditionFirstMove.java | 14 + .../chess/conditions/NoMoveBaseCondition.java | 13 + .../conditions/PieceCellOccupyBlocker.java | 15 + .../PieceCellOccupyBlockerFactory.java | 22 + .../PieceCellOccupyBlockerKingCheck.java | 22 + .../PieceCellOccupyBlockerSelfPiece.java | 21 + .../conditions/PieceMoveFurtherCondition.java | 14 + .../PieceMoveFurtherConditionDefault.java | 18 + .../exceptions/InvalidMoveException.java | 7 + .../exceptions/PieceNotFoundException.java | 7 + .../chess/helpers/ListHelpers.java | 26 + .../uditagarwal/chess/model/Board.java | 95 ++ .../uditagarwal/chess/model/Cell.java | 28 + .../uditagarwal/chess/model/Color.java | 6 + .../uditagarwal/chess/model/Piece.java | 94 ++ .../uditagarwal/chess/model/PieceType.java | 10 + .../uditagarwal/chess/model/Player.java | 33 + .../chess/moves/NextCellProvider.java | 11 + .../chess/moves/PossibleMovesProvider.java | 85 ++ .../moves/PossibleMovesProviderDiagonal.java | 26 + .../PossibleMovesProviderHorizontal.java | 28 + .../moves/PossibleMovesProviderVertical.java | 39 + .../chess/moves/VerticalMoveDirection.java | 7 + .../uditagarwal/gameplay/GameController.java | 24 + .../gameplay/contracts/PlayerMove.java | 13 + .../AutocompleteSystem.java | 0 .../java}/microsoftassesment/CropWords.java | 0 .../LexicographicallySmallest.java | 2 +- ...gestSubStringWithout3ContiguousLetter.java | 0 .../MinDeletionToMakeUniqueCount.java | 0 .../MinStepsToMakePileSameHeight.java | 0 .../MinSwapsToGroupRedBalls.java | 0 .../NumsWithEqualDigitSum.java | 0 .../RemoveCharsMoreThanKOccurrence.java | 55 + .../StringWithout3ConsequitiveLetter.java | 0 .../com/safecabs/Constants.java | 0 .../multithreading/com/safecabs/Gender.java | 0 .../com/safecabs/app/AssignCab.java | 0 .../com/safecabs/app/CabProvider.java | 0 .../com/safecabs/app/CabRequest.java | 0 .../com/safecabs/app/CustomCyclicBarrier.java | 0 .../multithreading/com/safecabs/cab/Cab.java | 0 .../com/safecabs/client/ClientTest.java | 0 .../UnRegisteredPassengerException.java | 0 .../com/safecabs/passenger/Passenger.java | 0 .../passenger/RegisteredPassenger.java | 0 .../educative/AsyncToSyncConverter.java | 60 ++ .../educative/BarberShopProblem.java | 58 +- .../multithreading/educative/Barrier.java | 12 +- .../educative/BlockingQueue.java | 34 +- .../educative/CountingSemaphore.java | 0 .../educative/DeferredCallbackExecutor.java | 30 +- .../educative/DemonstrationThreadLocal.java | 40 +- .../educative/DiningPhilosophers.java | 0 .../educative/DiningPhilosophers2.java | 0 .../educative/MultiThreadedMergeSort.java | 0 .../educative/ReadWriteLock.java | 22 +- .../educative/TokenBucketFilter.java | 16 +- .../educative/UberSeatingProblem.java | 53 +- .../educative/UnisexBathroom.java | 4 +- .../educative/UnisexBathroom2.java | 137 ++- .../educative/companies/netflix/Callback.java | 0 .../educative/companies/netflix/Executor.java | 0 .../educative/companies/netflix/Run.java | 0 .../netflix/SynchronousExecutor.java | 0 .../educative/examples/CallableExample.java | 0 .../educative/examples/DaemonThreadSpawn.java | 0 .../educative/examples/FutureTaskExample.java | 0 .../educative/examples/StockOrder.java | 14 +- .../educative/examples/ThreadExample.java | 0 .../examples/ThreadExecutorExample.java | 0 .../examples/ThreadInterruptedException.java | 0 .../examples/ThreadSleepExample.java | 0 .../educative/examples/ThreadSpawn.java | 0 .../educative/examples/TimerVsPool.java | 0 .../educative/superman/Superman.java | 0 .../superman/SupermanNaiveButCorrect.java | 0 .../superman/SupermanSlightlyBetter.java | 0 .../educative/superman/SupermanWithFlaws.java | 0 .../multithreading/practice/Addition.java | 0 .../practice/CountdownLatch.java | 38 + .../practice/DiningPhilosophers.java | 39 + .../multithreading/practice/FizzBuzz.java | 0 .../java/multithreading/practice/Foo.java | 124 +++ .../java}/multithreading/practice/FooBar.java | 0 .../java/multithreading/practice/H2O.java | 27 + .../practice/NonReentrantLock.java | 36 + .../multithreading/practice/OddEven.java | 0 .../practice/OddEvenSemaphore.java | 0 .../practice/ProducerConsumer.java | 2 +- .../practice/RealTimeCounter.java | 99 ++ .../multithreading/practice/WebCrawler.java | 107 ++ .../multithreading/practice/ZeroEvenOdd.java | 0 .../multithreading/producerconsumer/Main.java | 26 + .../producerconsumer/ProducerConsumer.java | 97 ++ src/main/java/multithreading/thread/Bank.java | 74 ++ .../thread/BasicMultiThreading.java | 0 .../java}/multithreading/thread/DeadLock.java | 0 .../thread/PrintEvenOddTester.java | 0 .../thread/PrintOddEvenByTwoThreads.java | 0 .../thread/RaceConditionExample.java | 0 .../java}/multithreading/thread/Tesst.java | 0 .../multithreading/thread/TestForLocking.java | 0 .../thread/ThreadJoinExample.java | 0 .../multithreading/thread/ThreadRunnable.java | 0 .../practiceproblems/AdvantageShuffle.java | 59 ++ .../AircraftMovieDuration.java | 61 ++ .../AircraftOptimization.java | 0 .../AlternateOddAndEvenNumbers.java | 19 +- .../java}/practiceproblems/AngleOfClock.java | 13 +- .../java/practiceproblems/ArrangeInQueue.java | 31 + .../practiceproblems/BackspaceCompare.java | 33 + .../practiceproblems/BasicCalculator.java | 4 +- .../practiceproblems/BinaryTreeCousins.java | 45 + .../java}/practiceproblems/BitonicSearch.java | 5 +- .../java/practiceproblems/BuildArray.java | 62 ++ .../java/practiceproblems/CanPlaceFlower.java | 61 ++ .../java}/practiceproblems/Candy.java | 12 +- .../practiceproblems/CelebrityProblem.java | 27 +- .../CheckPalindromePermutation.java | 26 +- .../java/practiceproblems/CloneGraph.java | 53 + .../practiceproblems/ClosestNumbers.java | 0 .../practiceproblems/CompareVersions.java | 0 .../CompleteBinaryTreeInserter.java | 59 ++ .../ComplexNumberMultiply.java | 22 + .../ConstructBSTFromPreorder.java | 71 +- .../ConstructTreeFromInorderAndPostorder.java | 70 ++ .../ConstructTreeFromInorderAndPreorder.java | 76 ++ .../ContainerWithMostWater.java | 30 + .../java}/practiceproblems/ConvertXToY.java | 17 +- .../CountAllPathsFrom2DMatrix.java | 2 +- .../java}/practiceproblems/CountAndSay.java | 1 + .../practiceproblems/CountBinaryStrings.java | 56 + .../java/practiceproblems/CountElements.java | 25 + ...ntMinimumStepsToFormDesiredInputArray.java | 10 +- .../DivideSubArrayAverage.java | 0 .../practiceproblems/DoubledPairArray.java | 108 ++ .../java/practiceproblems/DungeonGame.java | 104 ++ .../practiceproblems/DutchNationalFlag.java | 14 + .../java/practiceproblems/EvaluateRPN.java | 41 + src/main/java/practiceproblems/Fenwick2D.java | 74 ++ .../java}/practiceproblems/FenwickTree.java | 22 +- .../java/practiceproblems/FindAllAnagram.java | 50 + .../FindAllPossibleRecipes.java | 147 +++ .../java/practiceproblems/FindHeaters.java | 39 + .../practiceproblems/FindMissingNumbers.java | 74 ++ src/main/java/practiceproblems/FindPairs.java | 32 + .../practiceproblems/FindSmallestInteger.java | 31 +- .../FirstMissingPositive.java | 67 +- .../FirstNonRepeatedCharacter.java | 16 +- .../FirstNonRepeatingCharacterStream.java | 82 +- .../practiceproblems/Flatten2DVector.java | 5 +- .../practiceproblems/FlattenLinkedList.java | 0 .../FlipMaximizeZeroesSubarrayKadane.java | 7 +- ...lipZeroesToFormConsecutiveMaximumOnes.java | 6 +- src/main/java/practiceproblems/FourSum.java | 105 ++ .../java}/practiceproblems/FrequencySort.java | 31 +- .../FurthestBuildingJump.java | 46 + .../java/practiceproblems/GameOfLife.java | 64 ++ .../practiceproblems/GrammarMistake.java | 28 +- .../GraphSplitwiseSimplify.java | 11 +- .../java/practiceproblems/GroupAnagrams.java | 21 + .../GroupIsomorphicString.java | 29 +- .../java/practiceproblems/HappyNumber.java | 56 + .../java/practiceproblems/HouseRobber.java | 78 ++ .../java/practiceproblems/IPOMaxProfit.java | 41 + .../practiceproblems/InOrderSuccessor.java | 30 +- .../InorderSuccessorPredecessor.java | 143 +++ .../practiceproblems/IntegerToBinary.java | 0 .../IntersectionOfArrays.java | 57 +- .../IsEditOneDistanceAway.java | 89 ++ .../java}/practiceproblems/IsSubsequence.java | 17 +- .../practiceproblems/IsomorphicString.java | 71 ++ .../practiceproblems/KSmallestPairSum.java | 33 + .../KmostFrequentLetters.java | 12 +- .../KthCharacterInString.java | 41 + .../practiceproblems/KthClosestOrigin.java | 86 ++ .../KthSmallestFromTwoSortedArrays.java | 4 + .../practiceproblems/KthSmallestMatrix.java | 48 + .../LargestDivisibleSubset.java | 10 +- .../LargestPossibleNumber.java | 10 +- .../LargestSubArrayWithZeroesAndOnes.java | 67 ++ .../LargestTimeFromDigits.java | 40 + .../LeftMostColumnWithOne.java | 35 +- .../LengthOfLongestSubstringKDistinct.java | 21 +- .../LongestConsequtiveSequence.java | 12 +- .../LongestDiverseString.java | 72 ++ .../LongestIncreasingPathInMatrix.java} | 26 +- .../LongestRepeatCharReplace.java | 49 +- .../LongestSpanWithSameSumArray.java | 23 +- .../LongestSubArraySumUtmostK.java | 20 +- .../LongestUniqueSubstring.java | 19 +- .../practiceproblems/MajorityVoting.java | 43 +- .../MakeAnArrayPalindrome.java | 7 +- .../practiceproblems/MatrixRowWithMax1.java | 2 +- .../MaxDistinctElementAfterKRemoval.java | 6 +- .../practiceproblems/MaxPointsInLine.java | 116 +++ .../MaxSumTwoNonOverlappingSubArray.java | 109 ++ .../practiceproblems/MaximumDifference.java | 0 .../java}/practiceproblems/MaximumGap.java | 25 +- .../MaximumProductSubarray.java | 149 +++ .../MaximumSubstringWithKDistinctChar.java | 0 .../MaximumUnsortedSubarray.java} | 33 +- .../practiceproblems/MedianOfKWindow.java | 51 + .../MedianOfRunningIntegers.java | 60 ++ .../MedianOfTwoSortedArrays.java | 49 +- .../MinAdjSwapsToMakePalindrome.java | 30 +- .../practiceproblems/MinCostRopeConnect.java | 2 +- .../MinIncrementToMakeArrayUnique.java | 106 ++ .../MinOperationToMakeArrayIncreasing.java | 26 + .../java/practiceproblems/MinRefuelStops.java | 35 + .../MinStepsToConvertXtoY.java | 0 .../practiceproblems/MinTimeRotOranges.java | 61 ++ .../java}/practiceproblems/MinimumBribes.java | 36 +- .../MinimumDistanceBetweenTwoNumbers.java | 2 +- .../MinimumIndexDistanceOfMaximumNumbers.java | 0 .../practiceproblems/MinimumStepsKnight.java | 45 +- .../MinimumSubArrayLength.java | 31 + .../MinimumSwapSortArray.java | 110 ++ .../MinimumWindowSubsequence.java | 0 .../MinimumWindowSubstring.java | 0 .../practiceproblems/MirrorBinaryTree.java | 2 +- .../MobileKeyPadCombinations.java | 2 +- .../java}/practiceproblems/MoveZeroes.java | 0 .../practiceproblems/MultiplyTwoNumbers.java | 59 ++ .../practiceproblems/NextGreaterNumber.java | 65 +- .../practiceproblems/NextPermutation.java | 63 ++ .../practiceproblems/NonDecreasingArray.java | 47 + .../practiceproblems/NumberOfBallons.java | 56 + .../practiceproblems/NumberOfSubMatrices.java | 53 + .../practiceproblems/NutsAndBoltsMatch.java | 78 ++ .../practiceproblems/PairDivisibleBy60.java | 33 + .../practiceproblems/PalindromePartition.java | 58 ++ .../PartitionArrayDisjoint.java | 63 ++ .../practiceproblems/PartitionLabel.java | 0 .../practiceproblems/PascalsTriangle.java | 67 ++ .../practiceproblems/PermutationInString.java | 13 +- .../practiceproblems/PetrolGasStation.java | 0 .../java}/practiceproblems/PlusOne.java | 0 src/{ => main/java}/practiceproblems/Pow.java | 3 + .../practiceproblems/PrisonAfterNDays.java | 7 +- .../practiceproblems/ProductExceptSelf.java | 3 + .../practiceproblems/QueensAttackKing.java | 56 + .../practiceproblems/RaceCarMinSteps.java | 18 +- .../practiceproblems/RandomLinkedList.java | 61 ++ .../RandomPickWithWeight.java | 90 ++ src/main/java/practiceproblems/RangeSum.java | 37 + .../java/practiceproblems/RangeSum2D.java | 90 ++ .../ReArrangeStringKDistanceApart.java | 47 + .../RemoveAdjacentDuplicates.java | 0 .../RemoveBSTGivenOutsideRange.java} | 22 +- .../practiceproblems/RemoveDuplicates.java | 2 +- .../java}/practiceproblems/ReorderLogs.java | 4 +- .../practiceproblems/ReorganiseString.java | 0 .../practiceproblems/RestoreIpAddresses.java | 32 +- .../java/practiceproblems/ReverseString.java | 67 ++ .../RollingHashRabinKarp.java | 113 ++ .../practiceproblems/RomanToInteger.java | 23 +- .../java}/practiceproblems/RotateArray.java | 11 +- .../practiceproblems/RotateMatrixInPlace.java | 91 ++ .../java/practiceproblems/SearchAMaze.java | 86 ++ .../SearchAnElementInMatrix.java | 0 .../SerializeAndDeserialize.java | 30 +- .../SerializeDeserializeBST.java | 60 ++ .../java}/practiceproblems/SetBitCount.java | 0 .../practiceproblems/SetZeroesMatrix.java | 52 + .../ShortestPathBinaryMatrix.java | 51 + .../java}/practiceproblems/ShuffleArray.java | 6 +- .../practiceproblems/SimilarExpressions.java | 0 .../java/practiceproblems/SlidingWindow.java | 46 + .../java/practiceproblems/SnakeAndLadder.java | 70 ++ .../SortANearlySortedArray.java | 8 +- .../java/practiceproblems/SortedSquares.java | 34 + .../java}/practiceproblems/SpiralMatrix.java | 11 +- .../practiceproblems/SpiralMatrixII.java | 0 .../java/practiceproblems/StringJustify.java | 99 ++ .../SubstringWindowTemplate.java | 0 .../java/practiceproblems/SumOfSquares.java | 19 + .../practiceproblems/SumSubArrayZero.java | 15 +- .../practiceproblems/SurroundedRegions.java | 6 +- .../practiceproblems/TaskLeastInterval.java | 77 ++ src/main/java/practiceproblems/ThreeSum.java | 68 ++ .../TopKFrequentElements.java | 27 + .../practiceproblems/TrailingZeroes.java | 0 .../practiceproblems/TreasureIsland.java | 0 .../practiceproblems/TreasureIslandII.java | 0 .../java}/practiceproblems/Trie.java | 5 +- .../practiceproblems/TwoCityScheduling.java | 4 +- .../practiceproblems/TwoSumClosestToZero.java | 1 - .../UniqueElementsInArray.java | 0 .../java}/practiceproblems/UniquePath.java | 28 +- .../practiceproblems/UniquePathMaximum.java | 8 + .../java/practiceproblems/UpdateMatrix.java | 116 +++ .../java}/practiceproblems/UrlEncode.java | 2 +- .../practiceproblems/ValidPalindromeII.java | 5 +- .../java}/practiceproblems/ValidSudoku.java | 0 .../practiceproblems/ValidateIpAddresses.java | 0 .../java/practiceproblems/VulgarDecimal.java | 56 + src/main/java/practiceproblems/WordBreak.java | 117 +++ .../java/practiceproblems/WordBreakII.java | 37 + .../java/practiceproblems/WordLadder.java | 49 + .../java}/practiceproblems/WordSearch.java | 2 + .../java/practiceproblems/WordSearchII.java | 57 + .../design/AllOneDataStructure.java | 112 ++ .../design/AuthenticationManager.java | 54 + .../design}/AutoCompleteSystem.java | 3 +- .../design/BrowserHistory.java | 69 ++ .../DesignCompressedStringIterator.java | 9 +- .../design/DesignFileSystem.java | 46 + .../design/DesignHashMap.java | 85 ++ .../design}/DesignInMemoryFileSystem.java | 36 +- .../design/DesignStackIncrement.java | 35 + .../design}/DesignTicTacToe.java | 8 +- .../design/GetRandomWithDuplicates.java | 70 ++ .../practiceproblems/design/HitCounter.java | 38 + .../practiceproblems/design/LFUCache.java | 181 ++++ .../practiceproblems/design/LRUCache.java | 112 ++ .../practiceproblems/design/LeaderBoard.java | 66 ++ .../practiceproblems/design/LogSystem.java | 62 ++ .../design}/MaxFreqStack.java | 58 +- .../practiceproblems/design/MaxStack.java | 58 ++ .../practiceproblems/design/MinimumStack.java | 43 + .../design/MyCircularQueue.java | 58 ++ .../design}/OwnDataStructureUtil.java | 6 +- .../practiceproblems/design/RangeModule.java | 65 ++ .../design/ShortestWordDistance.java | 83 ++ .../practiceproblems/design/SnakeGame.java | 87 ++ .../practiceproblems/design/SnapShotUtil.java | 72 ++ .../practiceproblems/design/StockPrice.java | 77 ++ .../design/SubRectangleQueries.java | 37 + .../design/SummaryRanges.java | 88 ++ .../practiceproblems/design}/TimeMap.java | 54 +- .../practiceproblems/design/TweetCounts.java | 60 ++ .../practiceproblems/design}/Twitter.java | 54 +- .../java/practiceproblems/design/TwoSum.java | 56 + .../design/UndergroundSystem.java | 91 ++ .../design/ValidTicTacToeState.java | 58 ++ .../intervals/BalloonBurst.java | 55 + .../intervals/InsertIntervals.java | 80 ++ .../intervals/MaxProfitJobScheduling.java | 112 ++ .../intervals/MeetingRoomsII.java | 82 ++ .../intervals/MergeIntervalIntersection.java | 84 ++ .../intervals}/MergeIntervals.java | 5 +- .../intervals/OverlappingIntervals.java | 49 + .../intervals/RectangleComputeArea.java | 33 + .../intervals/RectangleOverlap.java | 62 ++ .../practiceproblems/jumpGame/JumpGameV.java | 68 ++ .../jumpGame/JumpsToReachEnd.java | 124 +++ .../jumpGame/MinTapsToFillGarden.java | 38 + .../jumpGame/VideoStitching.java | 47 + .../mergesort}/CountNumbersLessThanSelf.java | 23 +- .../mergesort/CountOfRanges.java | 61 ++ .../mergesort}/CountingInversion.java | 4 +- .../mergesort/ReversePairs.java | 85 ++ .../parentheses/BalancedSmiley.java | 62 ++ .../parentheses/CanBeValid.java | 60 ++ .../DifferentWaysToAddParenthesis.java | 61 ++ .../parentheses}/GenerateParenthesis.java | 2 +- .../parentheses/LongestValidParentheses.java | 51 + .../parentheses/MinSwapsToBalance.java | 75 ++ .../parentheses/RemoveInvalidParentheses.java | 100 ++ .../parentheses/ScoreOfParentheses.java | 43 + .../parentheses}/ValidParentheses.java | 2 +- .../parentheses}/ValidParenthesesString.java | 30 +- .../IntervalsBetweenIdenticalElements.java | 54 + .../prefixsum/SubArrayDivisibleByP.java | 52 + .../prefixsum}/SubArraySumDivisibleByK.java | 23 +- .../prefixsum}/SubArraySumEqualsK.java | 19 +- .../practiceproblems/recursion/NQueens.java | 86 ++ .../recursion/SudokuSolver.java | 87 ++ .../stack/AsteroidCollision.java | 35 + .../stack/BasicCalculatorII.java | 49 + .../stack/DailyTemperature.java | 62 ++ .../practiceproblems/stack}/DecodeString.java | 36 +- .../practiceproblems/stack/ExclusiveTIme.java | 46 + .../practiceproblems/stack/MaxHistogram.java | 104 ++ .../stack/MaxSubarrMinProduct.java | 99 ++ .../stack/NextGreaterElement.java | 133 +++ .../practiceproblems/stack/Pattern132.java | 74 ++ .../stack}/RemoveKDigits.java | 2 +- .../stack/SmallestLexicoSubSeq.java | 46 + .../practiceproblems/stack/SortStack.java | 19 + .../practiceproblems/stack/StockSpanner.java | 27 + .../stack/SumOfMinSubArrays.java | 112 ++ .../practiceproblems/stack/WaterTrapping.java | 91 ++ .../sweepline/MaxSumRangeQuery.java | 75 ++ .../sweepline/ModifyArray.java | 42 + .../tries/LongestRepeatingSubstring.java | 37 + .../java/practiceproblems/tries/MapSum.java | 102 ++ .../tries/WordDictionary.java | 67 ++ .../java/reflections/annotation/Main.java | 137 +++ .../annotation/annotations/Annotations.java | 33 + .../reflections/annotation/loaders/Cache.java | 17 + src/main/java/reflections/arrays/Main.java | 129 +++ .../java/reflections/arrays/data/Actor.java | 13 + .../java/reflections/arrays/data/Movie.java | 17 + .../configloader/ConfigLoaderLibrary.java | 102 ++ .../configparser/data/GameConfig.java | 38 + .../data/UserInterfaceConfig.java | 32 + .../resources/game-properties.cfg | 7 + .../configparser/resources/user-interface.cfg | 3 + .../customMockito/ExternalService.java | 9 + .../customMockito/OurMockTest.java | 26 + .../reflections/customMockito/OurMockito.java | 50 + .../java/reflections/dynamicProxy/Main.java | 92 ++ .../external/impl/DatabaseReader.java | 12 + .../external/impl/DatabaseReaderImpl.java | 22 + .../external/impl/HttpClient.java | 10 + .../external/impl/HttpClientImpl.java | 27 + src/main/java/reflections/game/Game.java | 8 + .../java/reflections/game/internal/Board.java | 123 +++ .../game/internal/BoardDimensions.java | 17 + .../game/internal/BoardLocation.java | 21 + .../game/internal/BoardPrinter.java | 36 + .../java/reflections/game/internal/Cell.java | 23 + .../game/internal/ComputerInputProvider.java | 33 + .../game/internal/ComputerPlayer.java | 23 + .../game/internal/HumanPlayer.java | 23 + .../game/internal/InputProvider.java | 7 + .../game/internal/KeyboardInputProvider.java | 31 + .../reflections/game/internal/Player.java | 10 + .../java/reflections/game/internal/Sign.java | 19 + .../game/internal/TicTacToeGame.java | 57 + src/main/java/reflections/init/Main.java | 40 + .../reflections/methodDiscovery/Address.java | 19 + .../methodDiscovery/ClothingProduct.java | 26 + .../reflections/methodDiscovery/Product.java | 54 + .../methodDiscovery/ProductTest.java | 94 ++ .../reflections/methodDiscovery/Size.java | 9 + src/main/java/reflections/retries/Main.java | 140 +++ .../retries/annotations/InitializerClass.java | 13 + .../annotations/InitializerMethod.java | 13 + .../retries/annotations/RetryOperation.java | 20 + .../retries/annotations/ScanPackages.java | 14 + .../reflections/retries/app/AutoSaver.java | 15 + .../retries/app/configs/ConfigsLoader.java | 15 + .../retries/app/databases/CacheLoader.java | 19 + .../app/databases/DatabaseConnection.java | 36 + .../retries/app/http/ServiceRegistry.java | 15 + .../topologicalsort/BestGamesFinder.java | 44 + .../reflections/topologicalsort/Main.java | 105 ++ .../topologicalsort/SqlQueryBuilder.java | 55 + .../annotations/Annotations.java | 34 + .../topologicalsort/databases/Database.java | 38 + src/main/java/sorting/InsertionSort.java | 23 + .../java}/sorting/KthLargestElement.java | 0 src/main/java/sorting/MaxHeap.java | 51 + src/{ => main/java}/sorting/MergeSort.java | 0 src/main/java/sorting/MinHeap.java | 225 ++++ src/main/java/sorting/MinHeapTest.java | 107 ++ .../java}/sorting/PractiseMergeSort.java | 0 src/{ => main/java}/sorting/QuickSelect.java | 0 src/{ => main/java}/sorting/QuickSort.java | 4 +- .../strings/stringProblems/Combination.java | 0 .../stringProblems/CustomSortString.java | 54 + .../stringProblems/DistinctSubstring.java | 0 .../FindLongestStringInArray.java | 0 .../stringProblems/LongestCommonPrefix.java | 39 + .../stringProblems/MostCommonWord.java | 0 .../PermutationAndCombination.java | 0 .../strings/stringProblems/PushDominoes.java | 112 ++ .../RearrangeCharactersInString.java | 3 + .../stringProblems/ShiftingLetters.java | 36 + .../ShortDistanceBetweenChars.java | 31 + .../strings/stringProblems/SlowestKey.java | 27 + src/main/java/strings/stringmatching/KMP.java | 60 ++ .../stringmatching/MaxProductString.java | 0 src/main/java/trees/AVLTree.java | 178 ++++ src/main/java/trees/BinaryTreeCamera.java | 55 + .../java/trees/BinaryTreesUpsideDown.java | 41 + src/main/java/trees/ClosestValue.java | 51 + src/main/java/trees/CountGoodNodes.java | 108 ++ src/main/java/trees/DeleteBST.java | 35 + src/main/java/trees/DepthOfTree.java | 46 + src/main/java/trees/DiameterTree.java | 21 + src/main/java/trees/FindLeaves.java | 49 + .../java/trees/GenerateAllPossibleBST.java | 90 ++ src/main/java/trees/HouseRobberTree.java | 64 ++ src/main/java/trees/InsertBST.java | 35 + src/main/java/trees/IsValidBST.java | 27 + src/main/java/trees/LargestBST.java | 68 ++ src/main/java/trees/LowestCommonAncestor.java | 153 +++ src/main/java/trees/MaxPathSum.java | 33 + .../java/trees/MaxProductSplitBinaryTree.java | 66 ++ src/main/java/trees/MaxWidthOfBinaryTree.java | 65 ++ src/main/java/trees/Node.java | 52 + src/main/java/trees/NodesAtDistanceK.java | 65 ++ src/main/java/trees/PathSum.java | 55 + src/main/java/trees/PathSumIII.java | 91 ++ src/main/java/trees/PruneBinaryTree.java | 28 + .../java}/trees/RootToLeafPaths.java | 2 +- src/main/java/trees/SameTree.java | 47 + .../trees/SecondMinValueInSpecialTree.java | 40 + .../java/trees}/SortedArrayToBST.java | 2 +- .../java/trees}/SwapRecoverBST.java | 4 +- .../java/trees}/SymmetricTree.java | 3 +- src/main/java/trees/Tree.java | 17 + src/{ => main/java}/trees/TreeNode.java | 8 +- src/main/java/trees/TreeToDLL.java | 65 ++ src/main/java/trees/TreeTraversals.java | 155 +++ src/main/java/trees/TrimBst.java | 37 + src/main/java/trees/TwoSumTree.java | 88 ++ src/main/java/trees/UniqueTreePath.java | 35 + .../trees/isValidPreOrderSerialisation.java | 55 + src/microsoftassesment/DLLNode.java | 180 ---- .../RemoveCharsMoreThanKOccurrence.java | 55 - src/multithreading/barberProblem/Barber.java | 28 - .../barberProblem/Customer.java | 55 - src/multithreading/barberProblem/Main.java | 37 - .../barberProblem/WaitingRoom.java | 21 - src/multithreading/executor/User.java | 32 - .../practice/CountdownLatch.java | 38 - src/multithreading/practice/Foo.java | 39 - src/practiceproblems/.vscode/UrlEncode.java | 0 src/practiceproblems/AdvantageShuffle.java | 40 - src/practiceproblems/ArrangeInQueue.java | 51 - src/practiceproblems/BackspaceCompare.java | 63 -- src/practiceproblems/BinaryTreeCousins.java | 51 - .../BuyAndSellStockAtMostTwice.java | 50 - src/practiceproblems/CloneGraph.java | 70 -- .../ConstructTreeFromInorderAndPostorder.java | 31 - .../ConstructTreeFromInorderAndPreorder.java | 49 - .../ContainerWithMostWater.java | 36 - src/practiceproblems/CountElements.java | 59 -- src/practiceproblems/CourseSchedule.java | 116 --- src/practiceproblems/DesignFileSystem.java | 64 -- .../DesignStackIncrement.java | 101 -- .../DifferentWaysToAddParenthesis.java | 61 -- src/practiceproblems/DungeonGame.java | 64 -- src/practiceproblems/EvaluvateRPN.java | 47 - src/practiceproblems/FindAllAnagram.java | 60 -- src/practiceproblems/FindMissingNumbers.java | 44 - src/practiceproblems/FourSum.java | 64 -- src/practiceproblems/GameOfLife.java | 61 -- src/practiceproblems/GraphBiPartite.java | 52 - src/practiceproblems/GroupAnagrams.java | 29 - src/practiceproblems/HappyNumber.java | 57 - src/practiceproblems/HitCounter.java | 31 - src/practiceproblems/HouseRobber.java | 46 - src/practiceproblems/IPOMaxProfit.java | 46 - src/practiceproblems/InMemeoryFIleSystem.java | 136 --- .../InorderSuccessorPredecessor.java | 105 -- src/practiceproblems/InsertIntervals.java | 36 - src/practiceproblems/InsertionSortList.java | 38 - .../IsEditOneDistanceAway.java | 63 -- src/practiceproblems/Islands.java | 44 - src/practiceproblems/IsomorphicString.java | 31 - src/practiceproblems/JumpsToReachEnd.java | 96 -- src/practiceproblems/KClosestElements.java | 66 -- src/practiceproblems/KthClosestOrigin.java | 74 -- src/practiceproblems/KthSmallestMatrix.java | 51 - src/practiceproblems/LRUCache.java | 123 --- .../LargestSubArrayWithZeroesAndOnes.java | 68 -- .../LargestTimeFromDigits.java | 39 - .../LongestIncreasingPathInMatrix.java | 64 -- src/practiceproblems/MaxHistogram.java | 68 -- src/practiceproblems/MaxProductString.java | 57 - .../MaxWidthOfBinaryTree.java | 61 -- .../MaximumProductSubarray.java | 63 -- .../MaximumUnsortedSubarray.java | 90 -- src/practiceproblems/MedianOfKWindow.java | 49 - .../MedianOfRunningIntegers.java | 45 - src/practiceproblems/MeetingRoomsII.java | 63 -- .../MergeIntervalIntersection.java | 42 - src/practiceproblems/MinTimeRotOranges.java | 102 -- src/practiceproblems/MinimumPathSum.java | 40 - src/practiceproblems/MinimumStack.java | 131 --- .../MinimumSwapSortArray.java | 59 -- src/practiceproblems/NQueens.java | 90 -- src/practiceproblems/NextGreaterElement.java | 90 -- src/practiceproblems/NonDecreasingArray.java | 31 - src/practiceproblems/NumberOfBallons.java | 24 - src/practiceproblems/NutsAndBoltsMatch.java | 74 -- .../OverlappingIntervals.java | 42 - src/practiceproblems/PalindromePartion.java | 52 - .../PalindromeSinglyLinkedList.java | 64 -- .../PalindromicSubSequence.java | 52 - src/practiceproblems/PascalsTriangle.java | 39 - src/practiceproblems/PathSumIII.java | 48 - src/practiceproblems/Pattern132.java | 33 - src/practiceproblems/QueensAttackKing.java | 54 - src/practiceproblems/RandomLinkedList.java | 62 -- .../RandomPickWithWeight.java | 52 - src/practiceproblems/RangeSum.java | 41 - src/practiceproblems/ReconstructItenary.java | 46 - src/practiceproblems/RedundantConnection.java | 44 - .../RemoveInvalidParentheses.java | 61 -- .../ReverseWordsInString.java | 40 - .../RollingHashRabinKarp.java | 134 --- src/practiceproblems/RotateMatrixInPlace.java | 102 -- .../RotateMatrixInPlaceAntiClockwise.java | 63 -- src/practiceproblems/SameTree.java | 62 -- src/practiceproblems/SearchAMaze.java | 80 -- .../SerializeDeserializeBST.java | 76 -- .../SingleElementInSortedArray.java | 44 - src/practiceproblems/SlidingWindow.java | 74 -- src/practiceproblems/SnakeAndLadder.java | 70 -- src/practiceproblems/SnakeGame.java | 88 -- src/practiceproblems/SortStack.java | 31 - src/practiceproblems/SortedSquares.java | 28 - .../StockBuySellManyTimes.java | 84 -- src/practiceproblems/StockSpanner.java | 21 - src/practiceproblems/StringIterator.java | 37 - src/practiceproblems/SumOfThreeElements.java | 39 - src/practiceproblems/TaskLeastInterval.java | 55 - src/practiceproblems/ThreeSum.java | 40 - src/practiceproblems/TopKFrequentElement.java | 38 - src/practiceproblems/VulgarDecimal.java | 115 -- src/practiceproblems/WaterTrapping.java | 37 - src/practiceproblems/WordBreak.java | 83 -- src/practiceproblems/WordBreakII.java | 33 - src/practiceproblems/WordDictionary.java | 69 -- src/practiceproblems/WordLadder.java | 45 - src/sorting/ImplementABinaryHeap.java | 248 ----- src/sorting/InsertionSort.java | 30 - src/sorting/MaxHeap.java | 51 - src/strings/stringmatching/KMP.java | 58 -- src/strings/stringmatching/RabinKarp.java | 60 -- src/trees/BinaryTraversalIterative.java | 62 -- src/trees/LCA.java | 67 -- src/trees/PathSum.java | 85 -- .../compile/default-compile/createdFiles.lst | 985 ++++++++++++++++++ .../compile/default-compile/inputFiles.lst | 763 ++++++++++++++ 1002 files changed, 31764 insertions(+), 11947 deletions(-) create mode 100644 pom.xml delete mode 100644 src/CombinationsAndPermutations/CombinationSum.java delete mode 100644 src/binarysearch/MagneticForceBetweenTwoBalls.java delete mode 100644 src/binarysearch/PeakElement.java delete mode 100644 src/binarysearch/Sqrt.java delete mode 100644 src/common/sorting/ImplementABinaryHeap.java delete mode 100644 src/common/sorting/InsertionSort.java delete mode 100644 src/common/sorting/KthLargestElement.java delete mode 100644 src/common/sorting/MaxHeap.java delete mode 100644 src/common/sorting/MergeSort.java delete mode 100644 src/common/sorting/PractiseMergeSort.java delete mode 100644 src/common/sorting/QuickSelect.java delete mode 100644 src/common/sorting/QuickSort.java delete mode 100644 src/dynamicProgramming/CatalanNumberBinarySearchTree.java delete mode 100644 src/dynamicProgramming/MaximumSquareDP.java delete mode 100644 src/dynamicProgramming/MinCostTickets.java delete mode 100644 src/dynamicProgramming/MinimumCoinChange.java delete mode 100644 src/dynamicProgramming/MinimumNumberOfJumpsToReachEnd.java delete mode 100644 src/dynamicProgramming/OptimalStratergy.java delete mode 100644 src/dynamicProgramming/StockBuySellKTransactions.java delete mode 100644 src/dynamicProgramming/StockBuySellWithCoolDown.java delete mode 100644 src/dynamicProgramming/Sudoku.java delete mode 100644 src/dynamicProgramming/UniqueCoinChange.java delete mode 100644 src/dynamicProgramming/WordBreak.java delete mode 100644 src/dynamicProgramming/WordBreakII.java delete mode 100644 src/dynamicProgramming/fibonacci/DecodeWays.java delete mode 100644 src/dynamicProgramming/fibonacci/DiceThrow.java delete mode 100644 src/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java delete mode 100644 src/dynamicProgramming/lcs/BitonicSequence.java delete mode 100644 src/dynamicProgramming/lcs/LongestCommonSubsequence.java delete mode 100644 src/dynamicProgramming/lcs/LongestIncreasingSubsequence.java delete mode 100644 src/dynamicProgramming/lcs/MaximumProductSubarray.java delete mode 100644 src/dynamicProgramming/lcs/TwoStringInterleavingToFormThird.java delete mode 100644 src/dynamicProgramming/lcs/WildCardMatching.java delete mode 100644 src/dynamicProgramming/matrix/MatrixMultiplicationCost.java delete mode 100644 src/dynamicProgramming/matrix/MaximumSizeSubMatrix.java delete mode 100644 src/dynamicProgramming/matrix/MinCostPath.java delete mode 100644 src/dynamicProgramming/oiknapsack/EqualSubsetSumPartition.java delete mode 100644 src/dynamicProgramming/unboundedknapsack/CoinChangingMinimumCoin.java delete mode 100644 src/dynamicProgramming/unboundedknapsack/CuttingRod.java delete mode 100644 src/graph/CombinationsAndPermutations/Combinations.java delete mode 100644 src/graph/CombinationsAndPermutations/Permutations.java delete mode 100644 src/graph/CombinationsAndPermutations/SubSets.java delete mode 100644 src/graph/leetcode/CheapestFlightKStops.java delete mode 100644 src/graph/leetcode/ConnectCities.java delete mode 100644 src/graph/leetcode/ConnectMissingCities.java delete mode 100644 src/graph/leetcode/CourseSchedule.java delete mode 100644 src/graph/leetcode/GraphBiPartite.java delete mode 100644 src/graph/leetcode/NetworkDelayTime.java delete mode 100644 src/graph/leetcode/NewRoadsMinimumSpanningTree.java delete mode 100644 src/graph/leetcode/RedundantConnection.java delete mode 100644 src/graph/leetcode/SnapShotUtil.java delete mode 100644 src/linkedLists/FlattenDoublyLinkedList.java delete mode 100644 src/linkedLists/ReverseKBlockNode.java delete mode 100644 src/linkedLists/RotateList.java rename src/{ => main/java}/RandomProblemGenerator.java (74%) rename src/{ => main/java}/SQL/AlterTableWithMonthName.sql (100%) rename src/{ => main/java}/SQL/ClassHavingMoreStudents.sql (100%) rename src/{ => main/java}/SQL/CustomersNerverOrders.sql (100%) rename src/{ => main/java}/SQL/DeleteDuplicate.sql (100%) rename src/{ => main/java}/SQL/DepartmentHighestSalary.sql (100%) rename src/{ => main/java}/SQL/DuplicateEmail.sql (100%) rename src/{ => main/java}/SQL/EmployeeEarningHigherThanManagers.sql (100%) rename src/{ => main/java}/SQL/ExchangeSeats.sql (100%) rename src/{ => main/java}/SQL/FirstLoginDate.sql (100%) rename src/{ => main/java}/SQL/ManagerHaving5OrMoreReport.sql (100%) rename src/{ => main/java}/SQL/NthHighestSalary.sql (100%) rename src/{ => main/java}/SQL/RisingTemperature.sql (100%) rename src/{ => main/java}/SQL/SubjectRanks.sql (100%) rename src/{ => main/java}/SQL/TeamSize.sql (100%) rename src/{ => main/java}/SQL/Top3Salaries.sql (100%) rename src/{ => main/java}/SQL/Top3SalaryDepartmentWise.sql (100%) create mode 100644 src/main/java/SQL/TopKthSalary.sql rename src/{ => main/java}/SQL/WinningCandidate.sql (100%) rename src/{ => main/java}/binarysearch/BinarySearchTemplate.java (100%) rename src/{practiceproblems => main/java/binarysearch}/BoatsToSave.java (69%) rename src/{ => main/java}/binarysearch/FindMinimumInRotatedArray.java (100%) create mode 100644 src/main/java/binarysearch/FindPeakElement.java rename src/{ => main/java}/binarysearch/FindSmallestDivisor.java (100%) rename src/{ => main/java}/binarysearch/FirstAndLastOccurence.java (100%) rename src/{ => main/java}/binarysearch/FirstBadVersion.java (100%) create mode 100644 src/main/java/binarysearch/KClosestElements.java rename src/{ => main/java}/binarysearch/KokoEatingBananas.java (100%) rename src/{ => main/java}/binarysearch/KthSmallestInMultiplicationTable.java (100%) create mode 100644 src/main/java/binarysearch/MagneticForceBetweenTwoBalls.java rename src/{ => main/java}/binarysearch/MaxSoldiers.java (83%) rename src/{ => main/java}/binarysearch/NumberOfDaysToMakeMBouquets.java (71%) rename src/{ => main/java}/binarysearch/SearchElementInSortedAndRotatedArray.java (50%) rename src/{ => main/java}/binarysearch/SearchInsertPosition.java (60%) rename src/{ => main/java}/binarysearch/ShipPackageWithNDays.java (53%) create mode 100644 src/main/java/binarysearch/SingleElementInSortedArray.java create mode 100644 src/main/java/binarysearch/Sqrt.java rename src/{ => main/java}/binarysearch/SubArraySplitSum.java (98%) create mode 100644 src/main/java/binarysearch/SumMutatedArrayCloseTarget.java create mode 100644 src/main/java/combinationsandpermutations/BeautifulArrangements.java create mode 100644 src/main/java/combinationsandpermutations/CanPartitionKSubSets.java rename src/{practiceproblems => main/java/combinationsandpermutations}/CombinationIterator.java (57%) create mode 100644 src/main/java/combinationsandpermutations/CombinationSum.java create mode 100644 src/main/java/combinationsandpermutations/FactorCombinations.java rename src/{CombinationsAndPermutations => main/java/combinationsandpermutations}/Permutations.java (51%) create mode 100644 src/main/java/combinationsandpermutations/SplitUniqueSubstring.java rename src/{CombinationsAndPermutations => main/java/combinationsandpermutations}/SubSets.java (100%) rename src/{ => main/java}/dynamicProgramming/AssemblyLineScheduling.java (76%) rename src/{ => main/java}/dynamicProgramming/BooleanParenthesization.java (93%) rename src/{ => main/java}/dynamicProgramming/BoxStacking.java (55%) create mode 100644 src/main/java/dynamicProgramming/CatalanNumberBinarySearchTree.java rename src/{ => main/java}/dynamicProgramming/EggDropping.java (100%) create mode 100644 src/main/java/dynamicProgramming/KnightDialer.java create mode 100644 src/main/java/dynamicProgramming/LastStoneWeight.java create mode 100644 src/main/java/dynamicProgramming/MakeArrayStrictlyIncreasing.java create mode 100644 src/main/java/dynamicProgramming/MaxGoldAMinerCanGet.java rename src/{ => main/java}/dynamicProgramming/MaxSumForNonAdjacentElements.java (100%) create mode 100644 src/main/java/dynamicProgramming/MaximumRectangle.java create mode 100644 src/main/java/dynamicProgramming/MinCoinChange.java create mode 100644 src/main/java/dynamicProgramming/MinCostTickets.java create mode 100644 src/main/java/dynamicProgramming/MinSwapsToMakeArrayIncreasing.java create mode 100644 src/main/java/dynamicProgramming/MonotoneIncreasingString.java rename src/{ => main/java}/dynamicProgramming/NumberWithSameConsequtiveDifference.java (84%) create mode 100644 src/main/java/dynamicProgramming/OnesAndZeroes.java create mode 100644 src/main/java/dynamicProgramming/OptimalStratergy.java rename src/{ => main/java}/dynamicProgramming/OptimalTreeSearch.java (100%) create mode 100644 src/main/java/dynamicProgramming/OutOfBounds.java create mode 100644 src/main/java/dynamicProgramming/PaintHouses.java rename src/{practiceproblems => main/java/dynamicProgramming}/PerfectSquare.java (86%) create mode 100644 src/main/java/dynamicProgramming/StoneGame.java create mode 100644 src/main/java/dynamicProgramming/TargetSum.java create mode 100644 src/main/java/dynamicProgramming/TriangleSum.java create mode 100644 src/main/java/dynamicProgramming/TwoKeysKeyBoard.java create mode 100644 src/main/java/dynamicProgramming/UniqueCoinChange.java create mode 100644 src/main/java/dynamicProgramming/fibonacci/DecodeWays.java create mode 100644 src/main/java/dynamicProgramming/fibonacci/DiceThrow.java create mode 100644 src/main/java/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java create mode 100644 src/main/java/dynamicProgramming/lcs/BitonicSequence.java create mode 100644 src/main/java/dynamicProgramming/lcs/DeleteAndEarn.java rename src/{ => main/java}/dynamicProgramming/lcs/EditDistance.java (80%) create mode 100644 src/main/java/dynamicProgramming/lcs/LongestCommonSubsequence.java rename src/{ => main/java}/dynamicProgramming/lcs/LongestCommonSubstring.java (100%) create mode 100644 src/main/java/dynamicProgramming/lcs/LongestIncreasingSubsequence.java create mode 100644 src/main/java/dynamicProgramming/lcs/LongestStringChain.java rename src/{ => main/java}/dynamicProgramming/lcs/MaximumContiguousSubarraySum.java (100%) create mode 100644 src/main/java/dynamicProgramming/lcs/MaximumLengthRepeatedSubarray.java rename src/{ => main/java}/dynamicProgramming/lcs/MaximumSumIncreasingSubsequence.java (80%) create mode 100644 src/main/java/dynamicProgramming/lcs/MinimumAsciiDelete.java create mode 100644 src/main/java/dynamicProgramming/lcs/NumberOfDistinctSubSequence.java create mode 100644 src/main/java/dynamicProgramming/lcs/NumberOfLIS.java create mode 100644 src/main/java/dynamicProgramming/lcs/RussianDollEnvelope.java create mode 100644 src/main/java/dynamicProgramming/lcs/ShortestCommonSupersequence.java create mode 100644 src/main/java/dynamicProgramming/lcs/TwoStringInterleavingToFormThird.java create mode 100644 src/main/java/dynamicProgramming/lcs/WildCardMatching.java create mode 100644 src/main/java/dynamicProgramming/matrix/MatrixMultiplicationCost.java create mode 100644 src/main/java/dynamicProgramming/matrix/MaximumSquareDP.java create mode 100644 src/main/java/dynamicProgramming/matrix/MinCostPath.java create mode 100644 src/main/java/dynamicProgramming/matrix/MinimumFallingPathMatrix.java create mode 100644 src/main/java/dynamicProgramming/oiknapsack/EqualSubsetSumPartition.java rename src/{ => main/java}/dynamicProgramming/oiknapsack/MinPartition.java (100%) rename src/{ => main/java}/dynamicProgramming/oiknapsack/MinimumSubsetSum.java (100%) rename src/{ => main/java}/dynamicProgramming/oiknapsack/NumberOfUniqueWaysToMakeChange.java (100%) rename src/{ => main/java}/dynamicProgramming/oiknapsack/O1KnapsackSpaceOptimized.java (71%) rename src/{ => main/java}/dynamicProgramming/oiknapsack/SubsetSumProblem.java (98%) create mode 100644 src/main/java/dynamicProgramming/palindrome/CountSubStrings.java rename src/{ => main/java}/dynamicProgramming/palindrome/LongestPalindromicSubsequence.java (86%) rename src/{ => main/java}/dynamicProgramming/palindrome/LongestPalindromicSubstring.java (52%) rename src/{practiceproblems => main/java/dynamicProgramming/palindrome}/PalindromePartitioning.java (62%) create mode 100644 src/main/java/dynamicProgramming/palindrome/PalindromePartitioningII.java rename src/{practiceproblems => main/java/dynamicProgramming/stocks}/BuyAndSellStockAnytime.java (69%) create mode 100644 src/main/java/dynamicProgramming/stocks/BuyAndSellStockAtMostTwice.java create mode 100644 src/main/java/dynamicProgramming/stocks/BuyAndSellWithTransactionFee.java create mode 100644 src/main/java/dynamicProgramming/stocks/StockBuySellKTransactions.java create mode 100644 src/main/java/dynamicProgramming/stocks/StockBuySellWithCoolDown.java create mode 100644 src/main/java/dynamicProgramming/unboundedknapsack/CuttingRod.java rename src/{practiceproblems => main/java/graph}/ArticulationPoint.java (99%) rename src/{ => main/java}/graph/adjacencyList/AdjacencyList.java (100%) rename src/{ => main/java}/graph/adjacencyMatrix/AdjacencyMatrix.java (100%) rename src/{ => main/java}/graph/bellmanFord/BellmanFord.java (100%) rename src/{ => main/java}/graph/bellmanFord/Edge.java (100%) rename src/{ => main/java}/graph/bellmanFord/Graph.java (100%) rename src/{ => main/java}/graph/bellmanFord/NegativeException.java (100%) rename src/{ => main/java}/graph/bellmanFord/Vertex.java (100%) rename src/{ => main/java}/graph/breadthFirstSearch/BreadthFirstSearch.java (100%) rename src/{ => main/java}/graph/breadthFirstSearch/Graph.java (100%) rename src/{ => main/java}/graph/cycle/CycleInDirectedGraph.java (100%) rename src/{ => main/java}/graph/cycle/CycleUndirectedGraph.java (100%) rename src/{ => main/java}/graph/cycle/Graph.java (100%) rename src/{ => main/java}/graph/depthFirstSearch/DepthFirstSearch.java (100%) rename src/{ => main/java}/graph/depthFirstSearch/Graph.java (100%) rename src/{ => main/java}/graph/dijkstraAlgorithm/BinaryHeap.java (99%) rename src/{ => main/java}/graph/dijkstraAlgorithm/DijkstraAlgorithm.java (100%) rename src/{ => main/java}/graph/dijkstraAlgorithm/Graph.java (100%) rename src/{ => main/java}/graph/disjoints/DisjointSetArrayImplementation.java (100%) rename src/{ => main/java}/graph/disjoints/DisjointSetWithNode.java (100%) rename src/{ => main/java}/graph/disjoints/PredatorDisjointSet.java (100%) create mode 100644 src/main/java/graph/disjoints/RankTransformMatrix.java rename src/{ => main/java}/graph/floydwarshall/FloydWarshall.java (100%) rename src/{ => main/java}/graph/interview/DisjointSet.java (100%) rename src/{ => main/java}/graph/kruskalAlgorithm/DisjointSet.java (100%) rename src/{ => main/java}/graph/kruskalAlgorithm/Graph.java (100%) rename src/{ => main/java}/graph/kruskalAlgorithm/KruskalMST.java (100%) create mode 100644 src/main/java/graph/leetcode/AccountsMerge.java create mode 100644 src/main/java/graph/leetcode/AlienDictionary.java rename src/{ => main/java}/graph/leetcode/AllPathsInGraph.java (91%) create mode 100644 src/main/java/graph/leetcode/ArrayNesting.java create mode 100644 src/main/java/graph/leetcode/CanVisitAllRooms.java create mode 100644 src/main/java/graph/leetcode/CheapestFlightKStops.java create mode 100644 src/main/java/graph/leetcode/ClosedIsland.java create mode 100644 src/main/java/graph/leetcode/ConnectCities.java create mode 100644 src/main/java/graph/leetcode/ConnectCitiesWithDiscount.java rename src/{ => main/java}/graph/leetcode/ConnectedComponentsInGraph.java (78%) create mode 100644 src/main/java/graph/leetcode/CourseSchedule.java create mode 100644 src/main/java/graph/leetcode/CourseScheduleII.java create mode 100644 src/main/java/graph/leetcode/CriticalConnectionInGraph.java create mode 100644 src/main/java/graph/leetcode/EmployeeImportance.java create mode 100644 src/main/java/graph/leetcode/EquationEquality.java create mode 100644 src/main/java/graph/leetcode/FindAllSafeStates.java rename src/{ => main/java}/graph/leetcode/FindJudge.java (100%) create mode 100644 src/main/java/graph/leetcode/FindTheCity.java rename src/{ => main/java}/graph/leetcode/FriendCircles.java (99%) create mode 100644 src/main/java/graph/leetcode/GraphBiPartite.java create mode 100644 src/main/java/graph/leetcode/GraphBiPartitePossiblity.java create mode 100644 src/main/java/graph/leetcode/GraphValidTree.java rename src/{practiceproblems => main/java/graph/leetcode}/IslandBFS.java (98%) create mode 100644 src/main/java/graph/leetcode/MakeIslandLarger.java create mode 100644 src/main/java/graph/leetcode/MatrixStoneRemoval.java create mode 100644 src/main/java/graph/leetcode/MaxDistanceFromWater.java create mode 100644 src/main/java/graph/leetcode/MaxProbabilityPath.java create mode 100644 src/main/java/graph/leetcode/MinCostConnectAllPipes.java create mode 100644 src/main/java/graph/leetcode/MinCostConnectCities.java create mode 100644 src/main/java/graph/leetcode/MinCostConnectPoints.java rename src/{ => main/java}/graph/leetcode/MinCostRepairEdges.java (92%) create mode 100644 src/main/java/graph/leetcode/MinPathHavingMaxDifference.java create mode 100644 src/main/java/graph/leetcode/MinStepsToCutTrees.java create mode 100644 src/main/java/graph/leetcode/MinimumHeightTrees.java create mode 100644 src/main/java/graph/leetcode/NetworkConnection.java create mode 100644 src/main/java/graph/leetcode/NetworkDelayTime.java rename src/{practiceproblems => main/java/graph/leetcode}/NewRoadsMST.java (55%) create mode 100644 src/main/java/graph/leetcode/PacificAtlantic.java create mode 100644 src/main/java/graph/leetcode/ReconstructItenary.java create mode 100644 src/main/java/graph/leetcode/RedundantConnection.java create mode 100644 src/main/java/graph/leetcode/RedundantConnectionII.java create mode 100644 src/main/java/graph/leetcode/RoadsToRome.java rename src/{ => main/java}/graph/leetcode/SentenceSimilarityII.java (95%) create mode 100644 src/main/java/graph/leetcode/ShortestBridge.java create mode 100644 src/main/java/graph/leetcode/ShortestPathToGetFood.java create mode 100644 src/main/java/graph/leetcode/TimeToInformEmployee.java rename src/{ => main/java}/graph/primsAlgorithm/BinaryMinHeap.java (100%) rename src/{ => main/java}/graph/primsAlgorithm/Graph.java (100%) rename src/{ => main/java}/graph/primsAlgorithm/PrimMST.java (100%) rename src/{ => main/java}/graph/primsAlgorithm/PrimsMSTArray.java (100%) rename src/{ => main/java}/graph/shortestPath/Graph.java (100%) rename src/{ => main/java}/graph/shortestPath/ShortestPath.java (100%) rename src/{ => main/java}/graph/topologicalsort/Graph.java (100%) rename src/{ => main/java}/graph/topologicalsort/TopologicalSort.java (100%) rename src/{ => main/java}/graph/topologicalsort/TopologicalSortList.java (100%) rename src/{ => main/java}/internals/ConcurrentHashMap.java (100%) rename src/{ => main/java}/internals/HashMap.java (100%) rename src/{ => main/java}/internals/HashMapJava8.java (100%) rename src/{ => main/java}/internals/LinkedHashMap.java (100%) rename src/{ => main/java}/internals/MyBlockingQueue.java (100%) create mode 100644 src/main/java/internals/QuadTree.java rename src/{ => main/java}/internals/SJUArrayList.java (100%) create mode 100644 src/main/java/internals/SkipList.java create mode 100644 src/main/java/internals/ThreadPool.java create mode 100644 src/main/java/internals/TwitterSnowflakeUUID.java rename src/{ => main/java}/java8/Books.txt (100%) rename src/{ => main/java}/java8/CustomCollectors.java (100%) rename src/{ => main/java}/java8/CustomSpliterator.java (100%) rename src/{ => main/java}/java8/DesignPatternJava8.java (100%) rename src/{ => main/java}/java8/EmployeeData.txt (100%) rename src/{ => main/java}/java8/FunctionalInterfaceExamples.java (100%) rename src/{ => main/java}/linkedLists/Agoda.java (100%) rename src/{ => main/java}/linkedLists/AllProblems.java (100%) rename src/{ => main/java}/linkedLists/ArrayToBST.java (100%) rename src/{ => main/java}/linkedLists/CloneRandomPointerLinkedList.java (100%) rename src/{ => main/java}/linkedLists/DLLToBBST.java (100%) rename src/{ => main/java}/linkedLists/DLLToBBSTTimeEfficiency.java (100%) rename src/{ => main/java}/linkedLists/DetectAndRemoveLoop.java (100%) rename src/{ => main/java}/linkedLists/FlattenLinkedList.java (100%) rename src/{practiceproblems => main/java/linkedLists}/FlattenMultiLevelLinkedList.java (61%) rename src/{ => main/java}/linkedLists/FlattenNestedIterator.java (100%) create mode 100644 src/main/java/linkedLists/InsertionSortList.java rename src/{practiceproblems => main/java/linkedLists}/LinkedListRemoveDuplicates.java (89%) rename src/{ => main/java}/linkedLists/LinkedListToBST.java (100%) rename src/{ => main/java}/linkedLists/Main.java (100%) create mode 100644 src/main/java/linkedLists/MergeKSortedLists.java rename src/{practiceproblems => main/java/linkedLists}/MergeSortLinkedList.java (88%) rename src/{practiceproblems => main/java/linkedLists}/MergeTwoLinkedList.java (97%) rename src/{ => main/java}/linkedLists/MergeTwoLinkedLists.java (100%) rename src/{ => main/java}/linkedLists/MiddleElement.java (100%) rename src/{practiceproblems => main/java/linkedLists}/NextLargestList.java (98%) rename src/{ => main/java}/linkedLists/Node.java (100%) rename src/{ => main/java}/linkedLists/PalindromeSinglyLinkedList.java (100%) rename src/{ => main/java}/linkedLists/RandomListNode.java (100%) create mode 100644 src/main/java/linkedLists/RemoveDuplicates.java create mode 100644 src/main/java/linkedLists/ReverseKBlockNode.java rename src/{ => main/java}/linkedLists/ReverseLinkedList.java (100%) rename src/{ => main/java}/linkedLists/ReverseLinkedListBetweenMandN.java (100%) rename src/{ => main/java}/linkedLists/ReversePairsNode.java (100%) create mode 100644 src/main/java/linkedLists/RotateList.java rename src/{ => main/java}/linkedLists/SinglyLinkedListNode.java (100%) rename src/{practiceproblems => main/java/linkedLists}/SplitLinkedList.java (95%) rename src/{ => main/java}/linkedLists/StackImpl.java (100%) rename src/{ => main/java}/linkedLists/StackOperationUsingLinkedList.java (100%) rename src/{ => main/java}/linkedLists/Top20LinkedListQuestions.java (100%) create mode 100644 src/main/java/lld/auctionSystem/enums/AuctionProductState.java create mode 100644 src/main/java/lld/auctionSystem/enums/AuctionState.java create mode 100644 src/main/java/lld/auctionSystem/enums/Channel.java create mode 100644 src/main/java/lld/auctionSystem/enums/ObserverType.java create mode 100644 src/main/java/lld/auctionSystem/enums/PublisherEventType.java create mode 100644 src/main/java/lld/auctionSystem/models/Auction.java create mode 100644 src/main/java/lld/auctionSystem/models/AuctionProduct.java create mode 100644 src/main/java/lld/auctionSystem/models/Buyer.java create mode 100644 src/main/java/lld/auctionSystem/models/Event.java create mode 100644 src/main/java/lld/auctionSystem/models/Notification.java create mode 100644 src/main/java/lld/auctionSystem/models/Observer.java create mode 100644 src/main/java/lld/auctionSystem/models/Product.java create mode 100644 src/main/java/lld/auctionSystem/models/Publisher.java create mode 100644 src/main/java/lld/auctionSystem/models/Seller.java create mode 100644 src/main/java/lld/auctionSystem/models/User.java create mode 100644 src/main/java/lld/auctionSystem/repository/AuctionRepository.java create mode 100644 src/main/java/lld/auctionSystem/repository/BuyerRepository.java create mode 100644 src/main/java/lld/auctionSystem/repository/ProductRepository.java create mode 100644 src/main/java/lld/auctionSystem/repository/SellerRepository.java create mode 100644 src/main/java/lld/auctionSystem/services/AuctionService.java create mode 100644 src/main/java/lld/auctionSystem/services/BuyerService.java create mode 100644 src/main/java/lld/auctionSystem/services/ObserverService.java create mode 100644 src/main/java/lld/auctionSystem/services/PublisherService.java create mode 100644 src/main/java/lld/auctionSystem/services/SellerService.java create mode 100644 src/main/java/lld/auctionSystem/services/strategies/AuctionDetails.java create mode 100644 src/main/java/lld/auctionSystem/services/strategies/BuyerViewAuctionDetails.java create mode 100644 src/main/java/lld/auctionSystem/services/strategies/SellerViewAuctionDetails.java create mode 100644 src/main/java/lld/auctionSystem/utils/Utils.java create mode 100644 src/main/java/lld/billsharing/BillSharingMain.java create mode 100644 src/main/java/lld/billsharing/exceptions/ContributionExceededException.java create mode 100644 src/main/java/lld/billsharing/exceptions/ExpenseDoesNotExistsException.java create mode 100644 src/main/java/lld/billsharing/exceptions/ExpenseSettledException.java create mode 100644 src/main/java/lld/billsharing/exceptions/InvalidExpenseState.java create mode 100644 src/main/java/lld/billsharing/model/Contribution.java create mode 100644 src/main/java/lld/billsharing/model/Expense.java create mode 100644 src/main/java/lld/billsharing/model/ExpenseGroup.java create mode 100644 src/main/java/lld/billsharing/model/ExpenseStatus.java create mode 100644 src/main/java/lld/billsharing/model/User.java create mode 100644 src/main/java/lld/billsharing/model/UserShare.java create mode 100644 src/main/java/lld/billsharing/repository/ExpenseRepository.java create mode 100644 src/main/java/lld/billsharing/repository/UserRepository.java create mode 100644 src/main/java/lld/billsharing/service/ExpenseService.java create mode 100644 src/main/java/lld/billsharing/service/NotificationService.java create mode 100644 src/main/java/lld/billsharing/service/NotificationServiceImpl.java create mode 100644 src/main/java/lld/billsharing/service/UserService.java create mode 100644 src/main/java/lld/elevator/TestElevator.java create mode 100644 src/main/java/lld/vendingmachine/HasMoneyState.java create mode 100644 src/main/java/lld/vendingmachine/Main.java create mode 100644 src/main/java/lld/vendingmachine/NoMoneyState.java create mode 100644 src/main/java/lld/vendingmachine/SoldOutState.java create mode 100644 src/main/java/lld/vendingmachine/SoldState.java create mode 100644 src/main/java/lld/vendingmachine/State.java create mode 100644 src/main/java/lld/vendingmachine/VendingMachine.java create mode 100644 src/main/java/lld/vendingmachine/VendingMachineState.java create mode 100644 src/main/java/machinecoding/snakesandladder/DiceService.java create mode 100644 src/main/java/machinecoding/snakesandladder/Driver.java create mode 100644 src/main/java/machinecoding/snakesandladder/Ladder.java create mode 100644 src/main/java/machinecoding/snakesandladder/Player.java create mode 100644 src/main/java/machinecoding/snakesandladder/Snake.java create mode 100644 src/main/java/machinecoding/snakesandladder/SnakeAndLadderBoard.java create mode 100644 src/main/java/machinecoding/snakesandladder/SnakeAndLadderService.java create mode 100644 src/main/java/machinecoding/splitwise/Driver.java create mode 100644 src/main/java/machinecoding/splitwise/EqualExpense.java create mode 100644 src/main/java/machinecoding/splitwise/EqualSplit.java create mode 100644 src/main/java/machinecoding/splitwise/ExactExpense.java create mode 100644 src/main/java/machinecoding/splitwise/ExactSplit.java create mode 100644 src/main/java/machinecoding/splitwise/Expense.java create mode 100644 src/main/java/machinecoding/splitwise/ExpenseManager.java create mode 100644 src/main/java/machinecoding/splitwise/ExpenseMetadata.java create mode 100644 src/main/java/machinecoding/splitwise/ExpenseService.java create mode 100644 src/main/java/machinecoding/splitwise/ExpenseType.java create mode 100644 src/main/java/machinecoding/splitwise/PercentExpense.java create mode 100644 src/main/java/machinecoding/splitwise/PercentSplit.java create mode 100644 src/main/java/machinecoding/splitwise/Split.java create mode 100644 src/main/java/machinecoding/splitwise/User.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/Main.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/conditions/MoveBaseCondition.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/conditions/MoveBaseConditionFirstMove.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/conditions/NoMoveBaseCondition.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/conditions/PieceCellOccupyBlocker.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/conditions/PieceCellOccupyBlockerFactory.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/conditions/PieceCellOccupyBlockerKingCheck.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/conditions/PieceCellOccupyBlockerSelfPiece.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/conditions/PieceMoveFurtherCondition.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/conditions/PieceMoveFurtherConditionDefault.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/exceptions/InvalidMoveException.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/exceptions/PieceNotFoundException.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/helpers/ListHelpers.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/model/Board.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/model/Cell.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/model/Color.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/model/Piece.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/model/PieceType.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/model/Player.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/moves/NextCellProvider.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/moves/PossibleMovesProvider.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/moves/PossibleMovesProviderDiagonal.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/moves/PossibleMovesProviderHorizontal.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/moves/PossibleMovesProviderVertical.java create mode 100644 src/main/java/machinecoding/uditagarwal/chess/moves/VerticalMoveDirection.java create mode 100644 src/main/java/machinecoding/uditagarwal/gameplay/GameController.java create mode 100644 src/main/java/machinecoding/uditagarwal/gameplay/contracts/PlayerMove.java rename src/{ => main/java}/microsoftassesment/AutocompleteSystem.java (100%) rename src/{ => main/java}/microsoftassesment/CropWords.java (100%) rename src/{ => main/java}/microsoftassesment/LexicographicallySmallest.java (93%) rename src/{ => main/java}/microsoftassesment/LongestSubStringWithout3ContiguousLetter.java (100%) rename src/{ => main/java}/microsoftassesment/MinDeletionToMakeUniqueCount.java (100%) rename src/{ => main/java}/microsoftassesment/MinStepsToMakePileSameHeight.java (100%) rename src/{ => main/java}/microsoftassesment/MinSwapsToGroupRedBalls.java (100%) rename src/{ => main/java}/microsoftassesment/NumsWithEqualDigitSum.java (100%) create mode 100644 src/main/java/microsoftassesment/RemoveCharsMoreThanKOccurrence.java rename src/{ => main/java}/microsoftassesment/StringWithout3ConsequitiveLetter.java (100%) rename src/{ => main/java}/multithreading/com/safecabs/Constants.java (100%) rename src/{ => main/java}/multithreading/com/safecabs/Gender.java (100%) rename src/{ => main/java}/multithreading/com/safecabs/app/AssignCab.java (100%) rename src/{ => main/java}/multithreading/com/safecabs/app/CabProvider.java (100%) rename src/{ => main/java}/multithreading/com/safecabs/app/CabRequest.java (100%) rename src/{ => main/java}/multithreading/com/safecabs/app/CustomCyclicBarrier.java (100%) rename src/{ => main/java}/multithreading/com/safecabs/cab/Cab.java (100%) rename src/{ => main/java}/multithreading/com/safecabs/client/ClientTest.java (100%) rename src/{ => main/java}/multithreading/com/safecabs/exceptions/UnRegisteredPassengerException.java (100%) rename src/{ => main/java}/multithreading/com/safecabs/passenger/Passenger.java (100%) rename src/{ => main/java}/multithreading/com/safecabs/passenger/RegisteredPassenger.java (100%) create mode 100644 src/main/java/multithreading/educative/AsyncToSyncConverter.java rename src/{ => main/java}/multithreading/educative/BarberShopProblem.java (59%) rename src/{ => main/java}/multithreading/educative/Barrier.java (62%) rename src/{ => main/java}/multithreading/educative/BlockingQueue.java (73%) rename src/{ => main/java}/multithreading/educative/CountingSemaphore.java (100%) rename src/{ => main/java}/multithreading/educative/DeferredCallbackExecutor.java (67%) rename src/{ => main/java}/multithreading/educative/DemonstrationThreadLocal.java (80%) rename src/{ => main/java}/multithreading/educative/DiningPhilosophers.java (100%) rename src/{ => main/java}/multithreading/educative/DiningPhilosophers2.java (100%) rename src/{ => main/java}/multithreading/educative/MultiThreadedMergeSort.java (100%) rename src/{ => main/java}/multithreading/educative/ReadWriteLock.java (77%) rename src/{ => main/java}/multithreading/educative/TokenBucketFilter.java (77%) rename src/{ => main/java}/multithreading/educative/UberSeatingProblem.java (74%) rename src/{ => main/java}/multithreading/educative/UnisexBathroom.java (94%) rename src/{ => main/java}/multithreading/educative/UnisexBathroom2.java (62%) rename src/{ => main/java}/multithreading/educative/companies/netflix/Callback.java (100%) rename src/{ => main/java}/multithreading/educative/companies/netflix/Executor.java (100%) rename src/{ => main/java}/multithreading/educative/companies/netflix/Run.java (100%) rename src/{ => main/java}/multithreading/educative/companies/netflix/SynchronousExecutor.java (100%) rename src/{ => main/java}/multithreading/educative/examples/CallableExample.java (100%) rename src/{ => main/java}/multithreading/educative/examples/DaemonThreadSpawn.java (100%) rename src/{ => main/java}/multithreading/educative/examples/FutureTaskExample.java (100%) rename src/{ => main/java}/multithreading/educative/examples/StockOrder.java (75%) rename src/{ => main/java}/multithreading/educative/examples/ThreadExample.java (100%) rename src/{ => main/java}/multithreading/educative/examples/ThreadExecutorExample.java (100%) rename src/{ => main/java}/multithreading/educative/examples/ThreadInterruptedException.java (100%) rename src/{ => main/java}/multithreading/educative/examples/ThreadSleepExample.java (100%) rename src/{ => main/java}/multithreading/educative/examples/ThreadSpawn.java (100%) rename src/{ => main/java}/multithreading/educative/examples/TimerVsPool.java (100%) rename src/{ => main/java}/multithreading/educative/superman/Superman.java (100%) rename src/{ => main/java}/multithreading/educative/superman/SupermanNaiveButCorrect.java (100%) rename src/{ => main/java}/multithreading/educative/superman/SupermanSlightlyBetter.java (100%) rename src/{ => main/java}/multithreading/educative/superman/SupermanWithFlaws.java (100%) rename src/{ => main/java}/multithreading/practice/Addition.java (100%) create mode 100644 src/main/java/multithreading/practice/CountdownLatch.java create mode 100644 src/main/java/multithreading/practice/DiningPhilosophers.java rename src/{ => main/java}/multithreading/practice/FizzBuzz.java (100%) create mode 100644 src/main/java/multithreading/practice/Foo.java rename src/{ => main/java}/multithreading/practice/FooBar.java (100%) create mode 100644 src/main/java/multithreading/practice/H2O.java create mode 100644 src/main/java/multithreading/practice/NonReentrantLock.java rename src/{ => main/java}/multithreading/practice/OddEven.java (100%) rename src/{ => main/java}/multithreading/practice/OddEvenSemaphore.java (100%) rename src/{ => main/java}/multithreading/practice/ProducerConsumer.java (98%) create mode 100644 src/main/java/multithreading/practice/RealTimeCounter.java create mode 100644 src/main/java/multithreading/practice/WebCrawler.java rename src/{ => main/java}/multithreading/practice/ZeroEvenOdd.java (100%) create mode 100644 src/main/java/multithreading/producerconsumer/Main.java create mode 100644 src/main/java/multithreading/producerconsumer/ProducerConsumer.java create mode 100644 src/main/java/multithreading/thread/Bank.java rename src/{ => main/java}/multithreading/thread/BasicMultiThreading.java (100%) rename src/{ => main/java}/multithreading/thread/DeadLock.java (100%) rename src/{ => main/java}/multithreading/thread/PrintEvenOddTester.java (100%) rename src/{ => main/java}/multithreading/thread/PrintOddEvenByTwoThreads.java (100%) rename src/{ => main/java}/multithreading/thread/RaceConditionExample.java (100%) rename src/{ => main/java}/multithreading/thread/Tesst.java (100%) rename src/{ => main/java}/multithreading/thread/TestForLocking.java (100%) rename src/{ => main/java}/multithreading/thread/ThreadJoinExample.java (100%) rename src/{ => main/java}/multithreading/thread/ThreadRunnable.java (100%) create mode 100644 src/main/java/practiceproblems/AdvantageShuffle.java create mode 100644 src/main/java/practiceproblems/AircraftMovieDuration.java rename src/{ => main/java}/practiceproblems/AircraftOptimization.java (100%) rename src/{ => main/java}/practiceproblems/AlternateOddAndEvenNumbers.java (75%) rename src/{ => main/java}/practiceproblems/AngleOfClock.java (54%) create mode 100644 src/main/java/practiceproblems/ArrangeInQueue.java create mode 100644 src/main/java/practiceproblems/BackspaceCompare.java rename src/{ => main/java}/practiceproblems/BasicCalculator.java (96%) create mode 100644 src/main/java/practiceproblems/BinaryTreeCousins.java rename src/{ => main/java}/practiceproblems/BitonicSearch.java (97%) create mode 100644 src/main/java/practiceproblems/BuildArray.java create mode 100644 src/main/java/practiceproblems/CanPlaceFlower.java rename src/{ => main/java}/practiceproblems/Candy.java (84%) rename src/{ => main/java}/practiceproblems/CelebrityProblem.java (53%) rename src/{ => main/java}/practiceproblems/CheckPalindromePermutation.java (67%) create mode 100644 src/main/java/practiceproblems/CloneGraph.java rename src/{ => main/java}/practiceproblems/ClosestNumbers.java (100%) rename src/{ => main/java}/practiceproblems/CompareVersions.java (100%) create mode 100644 src/main/java/practiceproblems/CompleteBinaryTreeInserter.java create mode 100644 src/main/java/practiceproblems/ComplexNumberMultiply.java rename src/{ => main/java}/practiceproblems/ConstructBSTFromPreorder.java (63%) create mode 100644 src/main/java/practiceproblems/ConstructTreeFromInorderAndPostorder.java create mode 100644 src/main/java/practiceproblems/ConstructTreeFromInorderAndPreorder.java create mode 100644 src/main/java/practiceproblems/ContainerWithMostWater.java rename src/{ => main/java}/practiceproblems/ConvertXToY.java (89%) rename src/{ => main/java}/practiceproblems/CountAllPathsFrom2DMatrix.java (95%) rename src/{ => main/java}/practiceproblems/CountAndSay.java (99%) create mode 100644 src/main/java/practiceproblems/CountBinaryStrings.java create mode 100644 src/main/java/practiceproblems/CountElements.java rename src/{ => main/java}/practiceproblems/CountMinimumStepsToFormDesiredInputArray.java (88%) rename src/{ => main/java}/practiceproblems/DivideSubArrayAverage.java (100%) create mode 100644 src/main/java/practiceproblems/DoubledPairArray.java create mode 100644 src/main/java/practiceproblems/DungeonGame.java rename src/{ => main/java}/practiceproblems/DutchNationalFlag.java (51%) create mode 100644 src/main/java/practiceproblems/EvaluateRPN.java create mode 100644 src/main/java/practiceproblems/Fenwick2D.java rename src/{ => main/java}/practiceproblems/FenwickTree.java (79%) create mode 100644 src/main/java/practiceproblems/FindAllAnagram.java create mode 100644 src/main/java/practiceproblems/FindAllPossibleRecipes.java create mode 100644 src/main/java/practiceproblems/FindHeaters.java create mode 100644 src/main/java/practiceproblems/FindMissingNumbers.java create mode 100644 src/main/java/practiceproblems/FindPairs.java rename src/{ => main/java}/practiceproblems/FindSmallestInteger.java (65%) rename src/{ => main/java}/practiceproblems/FirstMissingPositive.java (57%) rename src/{ => main/java}/practiceproblems/FirstNonRepeatedCharacter.java (61%) rename src/{ => main/java}/practiceproblems/FirstNonRepeatingCharacterStream.java (61%) rename src/{ => main/java}/practiceproblems/Flatten2DVector.java (94%) rename src/{ => main/java}/practiceproblems/FlattenLinkedList.java (100%) rename src/{ => main/java}/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java (92%) rename src/{ => main/java}/practiceproblems/FlipZeroesToFormConsecutiveMaximumOnes.java (92%) create mode 100644 src/main/java/practiceproblems/FourSum.java rename src/{ => main/java}/practiceproblems/FrequencySort.java (53%) create mode 100644 src/main/java/practiceproblems/FurthestBuildingJump.java create mode 100644 src/main/java/practiceproblems/GameOfLife.java rename src/{ => main/java}/practiceproblems/GrammarMistake.java (83%) rename src/{ => main/java}/practiceproblems/GraphSplitwiseSimplify.java (93%) create mode 100644 src/main/java/practiceproblems/GroupAnagrams.java rename src/{ => main/java}/practiceproblems/GroupIsomorphicString.java (77%) create mode 100644 src/main/java/practiceproblems/HappyNumber.java create mode 100644 src/main/java/practiceproblems/HouseRobber.java create mode 100644 src/main/java/practiceproblems/IPOMaxProfit.java rename src/{ => main/java}/practiceproblems/InOrderSuccessor.java (58%) create mode 100644 src/main/java/practiceproblems/InorderSuccessorPredecessor.java rename src/{ => main/java}/practiceproblems/IntegerToBinary.java (100%) rename src/{ => main/java}/practiceproblems/IntersectionOfArrays.java (62%) create mode 100644 src/main/java/practiceproblems/IsEditOneDistanceAway.java rename src/{ => main/java}/practiceproblems/IsSubsequence.java (51%) create mode 100644 src/main/java/practiceproblems/IsomorphicString.java create mode 100644 src/main/java/practiceproblems/KSmallestPairSum.java rename src/{ => main/java}/practiceproblems/KmostFrequentLetters.java (77%) create mode 100644 src/main/java/practiceproblems/KthCharacterInString.java create mode 100644 src/main/java/practiceproblems/KthClosestOrigin.java rename src/{ => main/java}/practiceproblems/KthSmallestFromTwoSortedArrays.java (94%) create mode 100644 src/main/java/practiceproblems/KthSmallestMatrix.java rename src/{ => main/java}/practiceproblems/LargestDivisibleSubset.java (84%) rename src/{ => main/java}/practiceproblems/LargestPossibleNumber.java (81%) create mode 100644 src/main/java/practiceproblems/LargestSubArrayWithZeroesAndOnes.java create mode 100644 src/main/java/practiceproblems/LargestTimeFromDigits.java rename src/{ => main/java}/practiceproblems/LeftMostColumnWithOne.java (69%) rename src/{ => main/java}/practiceproblems/LengthOfLongestSubstringKDistinct.java (91%) rename src/{ => main/java}/practiceproblems/LongestConsequtiveSequence.java (88%) create mode 100644 src/main/java/practiceproblems/LongestDiverseString.java rename src/{practiceproblems/LIS2DMatrix.java => main/java/practiceproblems/LongestIncreasingPathInMatrix.java} (64%) rename src/{ => main/java}/practiceproblems/LongestRepeatCharReplace.java (58%) rename src/{ => main/java}/practiceproblems/LongestSpanWithSameSumArray.java (86%) rename src/{ => main/java}/practiceproblems/LongestSubArraySumUtmostK.java (77%) rename src/{ => main/java}/practiceproblems/LongestUniqueSubstring.java (80%) rename src/{ => main/java}/practiceproblems/MajorityVoting.java (62%) rename src/{ => main/java}/practiceproblems/MakeAnArrayPalindrome.java (88%) rename src/{ => main/java}/practiceproblems/MatrixRowWithMax1.java (92%) rename src/{ => main/java}/practiceproblems/MaxDistinctElementAfterKRemoval.java (97%) create mode 100644 src/main/java/practiceproblems/MaxPointsInLine.java create mode 100644 src/main/java/practiceproblems/MaxSumTwoNonOverlappingSubArray.java rename src/{ => main/java}/practiceproblems/MaximumDifference.java (100%) rename src/{ => main/java}/practiceproblems/MaximumGap.java (81%) create mode 100644 src/main/java/practiceproblems/MaximumProductSubarray.java rename src/{ => main/java}/practiceproblems/MaximumSubstringWithKDistinctChar.java (100%) rename src/{practiceproblems/UnSortedSubArray.java => main/java/practiceproblems/MaximumUnsortedSubarray.java} (55%) create mode 100644 src/main/java/practiceproblems/MedianOfKWindow.java create mode 100644 src/main/java/practiceproblems/MedianOfRunningIntegers.java rename src/{ => main/java}/practiceproblems/MedianOfTwoSortedArrays.java (73%) rename src/{ => main/java}/practiceproblems/MinAdjSwapsToMakePalindrome.java (62%) rename src/{ => main/java}/practiceproblems/MinCostRopeConnect.java (95%) create mode 100644 src/main/java/practiceproblems/MinIncrementToMakeArrayUnique.java create mode 100644 src/main/java/practiceproblems/MinOperationToMakeArrayIncreasing.java create mode 100644 src/main/java/practiceproblems/MinRefuelStops.java rename src/{ => main/java}/practiceproblems/MinStepsToConvertXtoY.java (100%) create mode 100644 src/main/java/practiceproblems/MinTimeRotOranges.java rename src/{ => main/java}/practiceproblems/MinimumBribes.java (70%) rename src/{ => main/java}/practiceproblems/MinimumDistanceBetweenTwoNumbers.java (95%) rename src/{ => main/java}/practiceproblems/MinimumIndexDistanceOfMaximumNumbers.java (100%) rename src/{ => main/java}/practiceproblems/MinimumStepsKnight.java (57%) create mode 100644 src/main/java/practiceproblems/MinimumSubArrayLength.java create mode 100644 src/main/java/practiceproblems/MinimumSwapSortArray.java rename src/{ => main/java}/practiceproblems/MinimumWindowSubsequence.java (100%) rename src/{ => main/java}/practiceproblems/MinimumWindowSubstring.java (100%) rename src/{ => main/java}/practiceproblems/MirrorBinaryTree.java (98%) rename src/{ => main/java}/practiceproblems/MobileKeyPadCombinations.java (98%) rename src/{ => main/java}/practiceproblems/MoveZeroes.java (100%) create mode 100644 src/main/java/practiceproblems/MultiplyTwoNumbers.java rename src/{ => main/java}/practiceproblems/NextGreaterNumber.java (64%) create mode 100644 src/main/java/practiceproblems/NextPermutation.java create mode 100644 src/main/java/practiceproblems/NonDecreasingArray.java create mode 100644 src/main/java/practiceproblems/NumberOfBallons.java create mode 100644 src/main/java/practiceproblems/NumberOfSubMatrices.java create mode 100644 src/main/java/practiceproblems/NutsAndBoltsMatch.java create mode 100644 src/main/java/practiceproblems/PairDivisibleBy60.java create mode 100644 src/main/java/practiceproblems/PalindromePartition.java create mode 100644 src/main/java/practiceproblems/PartitionArrayDisjoint.java rename src/{ => main/java}/practiceproblems/PartitionLabel.java (100%) create mode 100644 src/main/java/practiceproblems/PascalsTriangle.java rename src/{ => main/java}/practiceproblems/PermutationInString.java (89%) rename src/{ => main/java}/practiceproblems/PetrolGasStation.java (100%) rename src/{ => main/java}/practiceproblems/PlusOne.java (100%) rename src/{ => main/java}/practiceproblems/Pow.java (98%) rename src/{ => main/java}/practiceproblems/PrisonAfterNDays.java (88%) rename src/{ => main/java}/practiceproblems/ProductExceptSelf.java (98%) create mode 100644 src/main/java/practiceproblems/QueensAttackKing.java rename src/{ => main/java}/practiceproblems/RaceCarMinSteps.java (88%) create mode 100644 src/main/java/practiceproblems/RandomLinkedList.java create mode 100644 src/main/java/practiceproblems/RandomPickWithWeight.java create mode 100644 src/main/java/practiceproblems/RangeSum.java create mode 100644 src/main/java/practiceproblems/RangeSum2D.java create mode 100644 src/main/java/practiceproblems/ReArrangeStringKDistanceApart.java rename src/{ => main/java}/practiceproblems/RemoveAdjacentDuplicates.java (100%) rename src/{practiceproblems/Node.java => main/java/practiceproblems/RemoveBSTGivenOutsideRange.java} (86%) rename src/{ => main/java}/practiceproblems/RemoveDuplicates.java (95%) rename src/{ => main/java}/practiceproblems/ReorderLogs.java (97%) rename src/{ => main/java}/practiceproblems/ReorganiseString.java (100%) rename src/{ => main/java}/practiceproblems/RestoreIpAddresses.java (66%) create mode 100644 src/main/java/practiceproblems/ReverseString.java create mode 100644 src/main/java/practiceproblems/RollingHashRabinKarp.java rename src/{ => main/java}/practiceproblems/RomanToInteger.java (51%) rename src/{ => main/java}/practiceproblems/RotateArray.java (57%) create mode 100644 src/main/java/practiceproblems/RotateMatrixInPlace.java create mode 100644 src/main/java/practiceproblems/SearchAMaze.java rename src/{ => main/java}/practiceproblems/SearchAnElementInMatrix.java (100%) rename src/{ => main/java}/practiceproblems/SerializeAndDeserialize.java (66%) create mode 100644 src/main/java/practiceproblems/SerializeDeserializeBST.java rename src/{ => main/java}/practiceproblems/SetBitCount.java (100%) create mode 100644 src/main/java/practiceproblems/SetZeroesMatrix.java create mode 100644 src/main/java/practiceproblems/ShortestPathBinaryMatrix.java rename src/{ => main/java}/practiceproblems/ShuffleArray.java (92%) rename src/{ => main/java}/practiceproblems/SimilarExpressions.java (100%) create mode 100644 src/main/java/practiceproblems/SlidingWindow.java create mode 100644 src/main/java/practiceproblems/SnakeAndLadder.java rename src/{ => main/java}/practiceproblems/SortANearlySortedArray.java (92%) create mode 100644 src/main/java/practiceproblems/SortedSquares.java rename src/{ => main/java}/practiceproblems/SpiralMatrix.java (88%) rename src/{ => main/java}/practiceproblems/SpiralMatrixII.java (100%) create mode 100644 src/main/java/practiceproblems/StringJustify.java rename src/{ => main/java}/practiceproblems/SubstringWindowTemplate.java (100%) create mode 100644 src/main/java/practiceproblems/SumOfSquares.java rename src/{ => main/java}/practiceproblems/SumSubArrayZero.java (85%) rename src/{ => main/java}/practiceproblems/SurroundedRegions.java (98%) create mode 100644 src/main/java/practiceproblems/TaskLeastInterval.java create mode 100644 src/main/java/practiceproblems/ThreeSum.java rename src/{ => main/java}/practiceproblems/TopKFrequentElements.java (55%) rename src/{ => main/java}/practiceproblems/TrailingZeroes.java (100%) rename src/{ => main/java}/practiceproblems/TreasureIsland.java (100%) rename src/{ => main/java}/practiceproblems/TreasureIslandII.java (100%) rename src/{ => main/java}/practiceproblems/Trie.java (93%) rename src/{ => main/java}/practiceproblems/TwoCityScheduling.java (98%) rename src/{ => main/java}/practiceproblems/TwoSumClosestToZero.java (95%) rename src/{ => main/java}/practiceproblems/UniqueElementsInArray.java (100%) rename src/{ => main/java}/practiceproblems/UniquePath.java (75%) rename src/{ => main/java}/practiceproblems/UniquePathMaximum.java (90%) create mode 100644 src/main/java/practiceproblems/UpdateMatrix.java rename src/{ => main/java}/practiceproblems/UrlEncode.java (96%) rename src/{ => main/java}/practiceproblems/ValidPalindromeII.java (85%) rename src/{ => main/java}/practiceproblems/ValidSudoku.java (100%) rename src/{ => main/java}/practiceproblems/ValidateIpAddresses.java (100%) create mode 100644 src/main/java/practiceproblems/VulgarDecimal.java create mode 100644 src/main/java/practiceproblems/WordBreak.java create mode 100644 src/main/java/practiceproblems/WordBreakII.java create mode 100644 src/main/java/practiceproblems/WordLadder.java rename src/{ => main/java}/practiceproblems/WordSearch.java (98%) create mode 100644 src/main/java/practiceproblems/WordSearchII.java create mode 100644 src/main/java/practiceproblems/design/AllOneDataStructure.java create mode 100644 src/main/java/practiceproblems/design/AuthenticationManager.java rename src/{practiceproblems => main/java/practiceproblems/design}/AutoCompleteSystem.java (98%) create mode 100644 src/main/java/practiceproblems/design/BrowserHistory.java rename src/{practiceproblems => main/java/practiceproblems/design}/DesignCompressedStringIterator.java (69%) create mode 100644 src/main/java/practiceproblems/design/DesignFileSystem.java create mode 100644 src/main/java/practiceproblems/design/DesignHashMap.java rename src/{practiceproblems => main/java/practiceproblems/design}/DesignInMemoryFileSystem.java (54%) create mode 100644 src/main/java/practiceproblems/design/DesignStackIncrement.java rename src/{practiceproblems => main/java/practiceproblems/design}/DesignTicTacToe.java (95%) create mode 100644 src/main/java/practiceproblems/design/GetRandomWithDuplicates.java create mode 100644 src/main/java/practiceproblems/design/HitCounter.java create mode 100644 src/main/java/practiceproblems/design/LFUCache.java create mode 100644 src/main/java/practiceproblems/design/LRUCache.java create mode 100644 src/main/java/practiceproblems/design/LeaderBoard.java create mode 100644 src/main/java/practiceproblems/design/LogSystem.java rename src/{practiceproblems => main/java/practiceproblems/design}/MaxFreqStack.java (61%) create mode 100644 src/main/java/practiceproblems/design/MaxStack.java create mode 100644 src/main/java/practiceproblems/design/MinimumStack.java create mode 100644 src/main/java/practiceproblems/design/MyCircularQueue.java rename src/{practiceproblems => main/java/practiceproblems/design}/OwnDataStructureUtil.java (92%) create mode 100644 src/main/java/practiceproblems/design/RangeModule.java create mode 100644 src/main/java/practiceproblems/design/ShortestWordDistance.java create mode 100644 src/main/java/practiceproblems/design/SnakeGame.java create mode 100644 src/main/java/practiceproblems/design/SnapShotUtil.java create mode 100644 src/main/java/practiceproblems/design/StockPrice.java create mode 100644 src/main/java/practiceproblems/design/SubRectangleQueries.java create mode 100644 src/main/java/practiceproblems/design/SummaryRanges.java rename src/{practiceproblems => main/java/practiceproblems/design}/TimeMap.java (67%) create mode 100644 src/main/java/practiceproblems/design/TweetCounts.java rename src/{practiceproblems => main/java/practiceproblems/design}/Twitter.java (70%) create mode 100644 src/main/java/practiceproblems/design/TwoSum.java create mode 100644 src/main/java/practiceproblems/design/UndergroundSystem.java create mode 100644 src/main/java/practiceproblems/design/ValidTicTacToeState.java create mode 100644 src/main/java/practiceproblems/intervals/BalloonBurst.java create mode 100644 src/main/java/practiceproblems/intervals/InsertIntervals.java create mode 100644 src/main/java/practiceproblems/intervals/MaxProfitJobScheduling.java create mode 100644 src/main/java/practiceproblems/intervals/MeetingRoomsII.java create mode 100644 src/main/java/practiceproblems/intervals/MergeIntervalIntersection.java rename src/{practiceproblems => main/java/practiceproblems/intervals}/MergeIntervals.java (89%) create mode 100644 src/main/java/practiceproblems/intervals/OverlappingIntervals.java create mode 100644 src/main/java/practiceproblems/intervals/RectangleComputeArea.java create mode 100644 src/main/java/practiceproblems/intervals/RectangleOverlap.java create mode 100644 src/main/java/practiceproblems/jumpGame/JumpGameV.java create mode 100644 src/main/java/practiceproblems/jumpGame/JumpsToReachEnd.java create mode 100644 src/main/java/practiceproblems/jumpGame/MinTapsToFillGarden.java create mode 100644 src/main/java/practiceproblems/jumpGame/VideoStitching.java rename src/{practiceproblems => main/java/practiceproblems/mergesort}/CountNumbersLessThanSelf.java (86%) create mode 100644 src/main/java/practiceproblems/mergesort/CountOfRanges.java rename src/{practiceproblems => main/java/practiceproblems/mergesort}/CountingInversion.java (96%) create mode 100644 src/main/java/practiceproblems/mergesort/ReversePairs.java create mode 100644 src/main/java/practiceproblems/parentheses/BalancedSmiley.java create mode 100644 src/main/java/practiceproblems/parentheses/CanBeValid.java create mode 100644 src/main/java/practiceproblems/parentheses/DifferentWaysToAddParenthesis.java rename src/{practiceproblems => main/java/practiceproblems/parentheses}/GenerateParenthesis.java (97%) create mode 100644 src/main/java/practiceproblems/parentheses/LongestValidParentheses.java create mode 100644 src/main/java/practiceproblems/parentheses/MinSwapsToBalance.java create mode 100644 src/main/java/practiceproblems/parentheses/RemoveInvalidParentheses.java create mode 100644 src/main/java/practiceproblems/parentheses/ScoreOfParentheses.java rename src/{practiceproblems => main/java/practiceproblems/parentheses}/ValidParentheses.java (94%) rename src/{practiceproblems => main/java/practiceproblems/parentheses}/ValidParenthesesString.java (73%) create mode 100644 src/main/java/practiceproblems/prefixsum/IntervalsBetweenIdenticalElements.java create mode 100644 src/main/java/practiceproblems/prefixsum/SubArrayDivisibleByP.java rename src/{practiceproblems => main/java/practiceproblems/prefixsum}/SubArraySumDivisibleByK.java (70%) rename src/{practiceproblems => main/java/practiceproblems/prefixsum}/SubArraySumEqualsK.java (69%) create mode 100644 src/main/java/practiceproblems/recursion/NQueens.java create mode 100644 src/main/java/practiceproblems/recursion/SudokuSolver.java create mode 100644 src/main/java/practiceproblems/stack/AsteroidCollision.java create mode 100644 src/main/java/practiceproblems/stack/BasicCalculatorII.java create mode 100644 src/main/java/practiceproblems/stack/DailyTemperature.java rename src/{practiceproblems => main/java/practiceproblems/stack}/DecodeString.java (55%) create mode 100644 src/main/java/practiceproblems/stack/ExclusiveTIme.java create mode 100644 src/main/java/practiceproblems/stack/MaxHistogram.java create mode 100644 src/main/java/practiceproblems/stack/MaxSubarrMinProduct.java create mode 100644 src/main/java/practiceproblems/stack/NextGreaterElement.java create mode 100644 src/main/java/practiceproblems/stack/Pattern132.java rename src/{practiceproblems => main/java/practiceproblems/stack}/RemoveKDigits.java (98%) create mode 100644 src/main/java/practiceproblems/stack/SmallestLexicoSubSeq.java create mode 100644 src/main/java/practiceproblems/stack/SortStack.java create mode 100644 src/main/java/practiceproblems/stack/StockSpanner.java create mode 100644 src/main/java/practiceproblems/stack/SumOfMinSubArrays.java create mode 100644 src/main/java/practiceproblems/stack/WaterTrapping.java create mode 100644 src/main/java/practiceproblems/sweepline/MaxSumRangeQuery.java create mode 100644 src/main/java/practiceproblems/sweepline/ModifyArray.java create mode 100644 src/main/java/practiceproblems/tries/LongestRepeatingSubstring.java create mode 100644 src/main/java/practiceproblems/tries/MapSum.java create mode 100644 src/main/java/practiceproblems/tries/WordDictionary.java create mode 100644 src/main/java/reflections/annotation/Main.java create mode 100644 src/main/java/reflections/annotation/annotations/Annotations.java create mode 100644 src/main/java/reflections/annotation/loaders/Cache.java create mode 100644 src/main/java/reflections/arrays/Main.java create mode 100644 src/main/java/reflections/arrays/data/Actor.java create mode 100644 src/main/java/reflections/arrays/data/Movie.java create mode 100644 src/main/java/reflections/configparser/configloader/ConfigLoaderLibrary.java create mode 100644 src/main/java/reflections/configparser/data/GameConfig.java create mode 100644 src/main/java/reflections/configparser/data/UserInterfaceConfig.java create mode 100644 src/main/java/reflections/configparser/resources/game-properties.cfg create mode 100644 src/main/java/reflections/configparser/resources/user-interface.cfg create mode 100644 src/main/java/reflections/customMockito/ExternalService.java create mode 100644 src/main/java/reflections/customMockito/OurMockTest.java create mode 100644 src/main/java/reflections/customMockito/OurMockito.java create mode 100644 src/main/java/reflections/dynamicProxy/Main.java create mode 100644 src/main/java/reflections/dynamicProxy/external/impl/DatabaseReader.java create mode 100644 src/main/java/reflections/dynamicProxy/external/impl/DatabaseReaderImpl.java create mode 100644 src/main/java/reflections/dynamicProxy/external/impl/HttpClient.java create mode 100644 src/main/java/reflections/dynamicProxy/external/impl/HttpClientImpl.java create mode 100644 src/main/java/reflections/game/Game.java create mode 100644 src/main/java/reflections/game/internal/Board.java create mode 100644 src/main/java/reflections/game/internal/BoardDimensions.java create mode 100644 src/main/java/reflections/game/internal/BoardLocation.java create mode 100644 src/main/java/reflections/game/internal/BoardPrinter.java create mode 100644 src/main/java/reflections/game/internal/Cell.java create mode 100644 src/main/java/reflections/game/internal/ComputerInputProvider.java create mode 100644 src/main/java/reflections/game/internal/ComputerPlayer.java create mode 100644 src/main/java/reflections/game/internal/HumanPlayer.java create mode 100644 src/main/java/reflections/game/internal/InputProvider.java create mode 100644 src/main/java/reflections/game/internal/KeyboardInputProvider.java create mode 100644 src/main/java/reflections/game/internal/Player.java create mode 100644 src/main/java/reflections/game/internal/Sign.java create mode 100644 src/main/java/reflections/game/internal/TicTacToeGame.java create mode 100644 src/main/java/reflections/init/Main.java create mode 100644 src/main/java/reflections/methodDiscovery/Address.java create mode 100644 src/main/java/reflections/methodDiscovery/ClothingProduct.java create mode 100644 src/main/java/reflections/methodDiscovery/Product.java create mode 100644 src/main/java/reflections/methodDiscovery/ProductTest.java create mode 100644 src/main/java/reflections/methodDiscovery/Size.java create mode 100644 src/main/java/reflections/retries/Main.java create mode 100644 src/main/java/reflections/retries/annotations/InitializerClass.java create mode 100644 src/main/java/reflections/retries/annotations/InitializerMethod.java create mode 100644 src/main/java/reflections/retries/annotations/RetryOperation.java create mode 100644 src/main/java/reflections/retries/annotations/ScanPackages.java create mode 100644 src/main/java/reflections/retries/app/AutoSaver.java create mode 100644 src/main/java/reflections/retries/app/configs/ConfigsLoader.java create mode 100644 src/main/java/reflections/retries/app/databases/CacheLoader.java create mode 100644 src/main/java/reflections/retries/app/databases/DatabaseConnection.java create mode 100644 src/main/java/reflections/retries/app/http/ServiceRegistry.java create mode 100644 src/main/java/reflections/topologicalsort/BestGamesFinder.java create mode 100644 src/main/java/reflections/topologicalsort/Main.java create mode 100644 src/main/java/reflections/topologicalsort/SqlQueryBuilder.java create mode 100644 src/main/java/reflections/topologicalsort/annotations/Annotations.java create mode 100644 src/main/java/reflections/topologicalsort/databases/Database.java create mode 100644 src/main/java/sorting/InsertionSort.java rename src/{ => main/java}/sorting/KthLargestElement.java (100%) create mode 100644 src/main/java/sorting/MaxHeap.java rename src/{ => main/java}/sorting/MergeSort.java (100%) create mode 100644 src/main/java/sorting/MinHeap.java create mode 100644 src/main/java/sorting/MinHeapTest.java rename src/{ => main/java}/sorting/PractiseMergeSort.java (100%) rename src/{ => main/java}/sorting/QuickSelect.java (100%) rename src/{ => main/java}/sorting/QuickSort.java (91%) rename src/{ => main/java}/strings/stringProblems/Combination.java (100%) create mode 100644 src/main/java/strings/stringProblems/CustomSortString.java rename src/{ => main/java}/strings/stringProblems/DistinctSubstring.java (100%) rename src/{ => main/java}/strings/stringProblems/FindLongestStringInArray.java (100%) create mode 100644 src/main/java/strings/stringProblems/LongestCommonPrefix.java rename src/{ => main/java}/strings/stringProblems/MostCommonWord.java (100%) rename src/{ => main/java}/strings/stringProblems/PermutationAndCombination.java (100%) create mode 100644 src/main/java/strings/stringProblems/PushDominoes.java rename src/{ => main/java}/strings/stringProblems/RearrangeCharactersInString.java (99%) create mode 100644 src/main/java/strings/stringProblems/ShiftingLetters.java create mode 100644 src/main/java/strings/stringProblems/ShortDistanceBetweenChars.java create mode 100644 src/main/java/strings/stringProblems/SlowestKey.java create mode 100644 src/main/java/strings/stringmatching/KMP.java rename src/{ => main/java}/strings/stringmatching/MaxProductString.java (100%) create mode 100644 src/main/java/trees/AVLTree.java create mode 100644 src/main/java/trees/BinaryTreeCamera.java create mode 100644 src/main/java/trees/BinaryTreesUpsideDown.java create mode 100644 src/main/java/trees/ClosestValue.java create mode 100644 src/main/java/trees/CountGoodNodes.java create mode 100644 src/main/java/trees/DeleteBST.java create mode 100644 src/main/java/trees/DepthOfTree.java create mode 100644 src/main/java/trees/DiameterTree.java create mode 100644 src/main/java/trees/FindLeaves.java create mode 100644 src/main/java/trees/GenerateAllPossibleBST.java create mode 100644 src/main/java/trees/HouseRobberTree.java create mode 100644 src/main/java/trees/InsertBST.java create mode 100644 src/main/java/trees/IsValidBST.java create mode 100644 src/main/java/trees/LargestBST.java create mode 100644 src/main/java/trees/LowestCommonAncestor.java create mode 100644 src/main/java/trees/MaxPathSum.java create mode 100644 src/main/java/trees/MaxProductSplitBinaryTree.java create mode 100644 src/main/java/trees/MaxWidthOfBinaryTree.java create mode 100644 src/main/java/trees/Node.java create mode 100644 src/main/java/trees/NodesAtDistanceK.java create mode 100644 src/main/java/trees/PathSum.java create mode 100644 src/main/java/trees/PathSumIII.java create mode 100644 src/main/java/trees/PruneBinaryTree.java rename src/{ => main/java}/trees/RootToLeafPaths.java (93%) create mode 100644 src/main/java/trees/SameTree.java create mode 100644 src/main/java/trees/SecondMinValueInSpecialTree.java rename src/{practiceproblems => main/java/trees}/SortedArrayToBST.java (97%) rename src/{practiceproblems => main/java/trees}/SwapRecoverBST.java (98%) rename src/{practiceproblems => main/java/trees}/SymmetricTree.java (95%) create mode 100644 src/main/java/trees/Tree.java rename src/{ => main/java}/trees/TreeNode.java (59%) create mode 100644 src/main/java/trees/TreeToDLL.java create mode 100644 src/main/java/trees/TreeTraversals.java create mode 100644 src/main/java/trees/TrimBst.java create mode 100644 src/main/java/trees/TwoSumTree.java create mode 100644 src/main/java/trees/UniqueTreePath.java create mode 100644 src/main/java/trees/isValidPreOrderSerialisation.java delete mode 100644 src/microsoftassesment/DLLNode.java delete mode 100644 src/microsoftassesment/RemoveCharsMoreThanKOccurrence.java delete mode 100755 src/multithreading/barberProblem/Barber.java delete mode 100755 src/multithreading/barberProblem/Customer.java delete mode 100755 src/multithreading/barberProblem/Main.java delete mode 100755 src/multithreading/barberProblem/WaitingRoom.java delete mode 100644 src/multithreading/executor/User.java delete mode 100644 src/multithreading/practice/CountdownLatch.java delete mode 100644 src/multithreading/practice/Foo.java delete mode 100644 src/practiceproblems/.vscode/UrlEncode.java delete mode 100644 src/practiceproblems/AdvantageShuffle.java delete mode 100644 src/practiceproblems/ArrangeInQueue.java delete mode 100644 src/practiceproblems/BackspaceCompare.java delete mode 100644 src/practiceproblems/BinaryTreeCousins.java delete mode 100644 src/practiceproblems/BuyAndSellStockAtMostTwice.java delete mode 100644 src/practiceproblems/CloneGraph.java delete mode 100644 src/practiceproblems/ConstructTreeFromInorderAndPostorder.java delete mode 100644 src/practiceproblems/ConstructTreeFromInorderAndPreorder.java delete mode 100644 src/practiceproblems/ContainerWithMostWater.java delete mode 100644 src/practiceproblems/CountElements.java delete mode 100644 src/practiceproblems/CourseSchedule.java delete mode 100644 src/practiceproblems/DesignFileSystem.java delete mode 100644 src/practiceproblems/DesignStackIncrement.java delete mode 100644 src/practiceproblems/DifferentWaysToAddParenthesis.java delete mode 100644 src/practiceproblems/DungeonGame.java delete mode 100644 src/practiceproblems/EvaluvateRPN.java delete mode 100644 src/practiceproblems/FindAllAnagram.java delete mode 100644 src/practiceproblems/FindMissingNumbers.java delete mode 100644 src/practiceproblems/FourSum.java delete mode 100644 src/practiceproblems/GameOfLife.java delete mode 100644 src/practiceproblems/GraphBiPartite.java delete mode 100644 src/practiceproblems/GroupAnagrams.java delete mode 100644 src/practiceproblems/HappyNumber.java delete mode 100644 src/practiceproblems/HitCounter.java delete mode 100644 src/practiceproblems/HouseRobber.java delete mode 100644 src/practiceproblems/IPOMaxProfit.java delete mode 100644 src/practiceproblems/InMemeoryFIleSystem.java delete mode 100644 src/practiceproblems/InorderSuccessorPredecessor.java delete mode 100644 src/practiceproblems/InsertIntervals.java delete mode 100644 src/practiceproblems/InsertionSortList.java delete mode 100644 src/practiceproblems/IsEditOneDistanceAway.java delete mode 100644 src/practiceproblems/Islands.java delete mode 100644 src/practiceproblems/IsomorphicString.java delete mode 100644 src/practiceproblems/JumpsToReachEnd.java delete mode 100644 src/practiceproblems/KClosestElements.java delete mode 100644 src/practiceproblems/KthClosestOrigin.java delete mode 100644 src/practiceproblems/KthSmallestMatrix.java delete mode 100644 src/practiceproblems/LRUCache.java delete mode 100644 src/practiceproblems/LargestSubArrayWithZeroesAndOnes.java delete mode 100644 src/practiceproblems/LargestTimeFromDigits.java delete mode 100644 src/practiceproblems/LongestIncreasingPathInMatrix.java delete mode 100644 src/practiceproblems/MaxHistogram.java delete mode 100644 src/practiceproblems/MaxProductString.java delete mode 100644 src/practiceproblems/MaxWidthOfBinaryTree.java delete mode 100644 src/practiceproblems/MaximumProductSubarray.java delete mode 100644 src/practiceproblems/MaximumUnsortedSubarray.java delete mode 100644 src/practiceproblems/MedianOfKWindow.java delete mode 100644 src/practiceproblems/MedianOfRunningIntegers.java delete mode 100644 src/practiceproblems/MeetingRoomsII.java delete mode 100644 src/practiceproblems/MergeIntervalIntersection.java delete mode 100644 src/practiceproblems/MinTimeRotOranges.java delete mode 100644 src/practiceproblems/MinimumPathSum.java delete mode 100644 src/practiceproblems/MinimumStack.java delete mode 100644 src/practiceproblems/MinimumSwapSortArray.java delete mode 100644 src/practiceproblems/NQueens.java delete mode 100644 src/practiceproblems/NextGreaterElement.java delete mode 100644 src/practiceproblems/NonDecreasingArray.java delete mode 100644 src/practiceproblems/NumberOfBallons.java delete mode 100644 src/practiceproblems/NutsAndBoltsMatch.java delete mode 100644 src/practiceproblems/OverlappingIntervals.java delete mode 100644 src/practiceproblems/PalindromePartion.java delete mode 100644 src/practiceproblems/PalindromeSinglyLinkedList.java delete mode 100644 src/practiceproblems/PalindromicSubSequence.java delete mode 100644 src/practiceproblems/PascalsTriangle.java delete mode 100644 src/practiceproblems/PathSumIII.java delete mode 100644 src/practiceproblems/Pattern132.java delete mode 100644 src/practiceproblems/QueensAttackKing.java delete mode 100644 src/practiceproblems/RandomLinkedList.java delete mode 100644 src/practiceproblems/RandomPickWithWeight.java delete mode 100644 src/practiceproblems/RangeSum.java delete mode 100644 src/practiceproblems/ReconstructItenary.java delete mode 100644 src/practiceproblems/RedundantConnection.java delete mode 100644 src/practiceproblems/RemoveInvalidParentheses.java delete mode 100644 src/practiceproblems/ReverseWordsInString.java delete mode 100644 src/practiceproblems/RollingHashRabinKarp.java delete mode 100644 src/practiceproblems/RotateMatrixInPlace.java delete mode 100644 src/practiceproblems/RotateMatrixInPlaceAntiClockwise.java delete mode 100644 src/practiceproblems/SameTree.java delete mode 100644 src/practiceproblems/SearchAMaze.java delete mode 100644 src/practiceproblems/SerializeDeserializeBST.java delete mode 100644 src/practiceproblems/SingleElementInSortedArray.java delete mode 100644 src/practiceproblems/SlidingWindow.java delete mode 100644 src/practiceproblems/SnakeAndLadder.java delete mode 100644 src/practiceproblems/SnakeGame.java delete mode 100644 src/practiceproblems/SortStack.java delete mode 100644 src/practiceproblems/SortedSquares.java delete mode 100644 src/practiceproblems/StockBuySellManyTimes.java delete mode 100644 src/practiceproblems/StockSpanner.java delete mode 100644 src/practiceproblems/StringIterator.java delete mode 100644 src/practiceproblems/SumOfThreeElements.java delete mode 100644 src/practiceproblems/TaskLeastInterval.java delete mode 100644 src/practiceproblems/ThreeSum.java delete mode 100644 src/practiceproblems/TopKFrequentElement.java delete mode 100644 src/practiceproblems/VulgarDecimal.java delete mode 100644 src/practiceproblems/WaterTrapping.java delete mode 100644 src/practiceproblems/WordBreak.java delete mode 100644 src/practiceproblems/WordBreakII.java delete mode 100644 src/practiceproblems/WordDictionary.java delete mode 100644 src/practiceproblems/WordLadder.java delete mode 100644 src/sorting/ImplementABinaryHeap.java delete mode 100644 src/sorting/InsertionSort.java delete mode 100644 src/sorting/MaxHeap.java delete mode 100644 src/strings/stringmatching/KMP.java delete mode 100644 src/strings/stringmatching/RabinKarp.java delete mode 100644 src/trees/BinaryTraversalIterative.java delete mode 100644 src/trees/LCA.java delete mode 100644 src/trees/PathSum.java create mode 100644 target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst create mode 100644 target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..3420731 --- /dev/null +++ b/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + + groupId + Problems + 1.0-SNAPSHOT + + + 11 + 11 + + + + + + org.projectlombok + lombok + 1.18.24 + provided + + + + junit + junit + 4.13.2 + test + + + + \ No newline at end of file diff --git a/src/CombinationsAndPermutations/CombinationSum.java b/src/CombinationsAndPermutations/CombinationSum.java deleted file mode 100644 index ed47f5d..0000000 --- a/src/CombinationsAndPermutations/CombinationSum.java +++ /dev/null @@ -1,76 +0,0 @@ -package CombinationsAndPermutations; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class CombinationSum { - - public List> combinationSum(int[] candidates, int target) { - if(candidates==null || candidates.length==0) return Collections.emptyList(); - List> result= new ArrayList<>(); - - combinationSumUtil(candidates, target, result, new ArrayList<>(), 0); - - return result; - - } - - public void combinationSumUtil(int[] candidates, int target, List> result, List tempList, int start ){ - if(target<0) return; - if(target==0){ - result.add(new ArrayList<>(tempList)); - - } - - for(int i=start; i> combinationSum2(int[] candidates, int target) { - if(candidates==null || candidates.length==0) return Collections.emptyList(); - List> result= new ArrayList<>(); - Arrays.sort(candidates); - combinationSumUtil1(candidates, target, result, new ArrayList<>(), 0); - - return result; - } - - public void combinationSumUtil1(int[] candidates, int target, List> result, List tempList, int start){ - if(target<0) return; - - if(target==0){ - result.add(new ArrayList<>(tempList)); - return; - } - - for(int i=start; i cur means cand[i - 1] is not added -// to the path (you should know why if you understand the algorithm), -// so if cand[i] == cand[i-1], then we shouldn't add cand[i]. -// This tricky is very smart. - - /** - * i>start && candidates[i]==candidates[i-1] : - * when input is like 1,1,2,4,7,8 and target is 9 - * the first iteration would run for all combinations starts with 1 ([1,1,7], [1,8]) - * the next number i=1 also starts with one which will run again for all combinations - * candidates[i]==candidates[i-1] this will eliminate the duplicate combinations(another [1,8]) - */ - if(i>start && candidates[i]==candidates[i-1]) continue; - if (target - candidates[i] < 0) break; - tempList.add(candidates[i]); - combinationSumUtil1(candidates, target-candidates[i], result, tempList, i+1); - tempList.remove(tempList.size()-1); - } - } -} diff --git a/src/binarysearch/MagneticForceBetweenTwoBalls.java b/src/binarysearch/MagneticForceBetweenTwoBalls.java deleted file mode 100644 index 0300d22..0000000 --- a/src/binarysearch/MagneticForceBetweenTwoBalls.java +++ /dev/null @@ -1,68 +0,0 @@ -package binarysearch; - -import java.util.Arrays; - -/** - * https://leetcode.com/problems/magnetic-force-between-two-balls/ - * - */ -public class MagneticForceBetweenTwoBalls { - - /** - - First, might as well consider the placements in sorted order. - - We only really need to check the forces of balls immediately to their left and right. - - Say our target is D. We want all balls to be at least D units apart. - - We can check if D is doable, by trying a greedy approach. Put the very - first ball at the first available position, place the next ball at the - first position rightwards that is sufficiently distant, etc. - - - We can do a binary search for what minimum distance is achievable. - - With this we have an O(n*log(L/m)) solution. Where L is the largest distance between - baskets, and m is the number of balls we're trying to place, n is number of possible positions. - */ - public int maxDistance(int[] position, int m) { - - Arrays.sort(position); - - int left = 1; - int right = position[position.length - 1]; - - while (left < right) { - int mid = left + (right - left) / 2; - System.out.println("before isFeasible:: left "+left+" right "+right+" mid "+mid); - if (isFeasible(position, m, mid)) { - System.out.println("condition is Feasible so changing right to mid"); - right = mid; - } else { - System.out.println("condition is not Feasible so changing left to mid+1"); - left = mid + 1; - } - System.out.println(); - } - - return left - 1; - } - - public boolean isFeasible(int[] position, int noOfBalls, int minDistance) { - int lastPos = position[0]; // first ball at 0 position - keep track of last position - int idx = 1; - noOfBalls--; // we have placed first ball at 0 position - System.out.println("begin isFeasible:: remaining noOfBalls after placing first "+noOfBalls+" minDistance "+minDistance); - while (idx < position.length && noOfBalls > 0) { - /* if minDistance between last position and position at idx is greater then or equal to minDistance - * then place the ball else skip - * */ - if (position[idx] - lastPos >= minDistance) { - lastPos = position[idx]; - noOfBalls--; - } - idx++; - } - System.out.println("closing isFeasible:: noOfBalls "+noOfBalls); - return noOfBalls != 0; /*if all balls have been placed then return true else false*/ - } - - public static void main(String[] args) { - new MagneticForceBetweenTwoBalls().maxDistance(new int[]{1,2,3,4,7}, 3); - } -} diff --git a/src/binarysearch/PeakElement.java b/src/binarysearch/PeakElement.java deleted file mode 100644 index 7924960..0000000 --- a/src/binarysearch/PeakElement.java +++ /dev/null @@ -1,47 +0,0 @@ -package binarysearch; - -import java.util.Map; -import java.util.TreeMap; - -/** - * https://leetcode.com/problems/find-peak-element/ - *

- * A peak element is an element that is greater than its neighbors. - *

- * Given an input array nums, where nums[i] ≠ nums[i+1], find a peak element and return its index. - *

- * The array may contain multiple peaks, in that case return the index to any one of the peaks is fine. - *

- * You may imagine that nums[-1] = nums[n] = -∞. - */ -public class PeakElement { - - - public static void main(String[] args) { - Map map= new TreeMap<>(); - map.put(new Employee(9,"aaa"),""); - map.put(new Employee(2,"ttt"),"sd"); - - for (Map.Entry entry: map.entrySet()){ - System.out.println(entry.getKey()); - } - - } - -} -class Employee { - int id; - String name; - Employee (int id, String name){ - this.id=id; - this.name=name; - } - - @Override - public String toString() { - return "Employee{" + - "id=" + id + - ", name='" + name + '\'' + - '}'; - } -} \ No newline at end of file diff --git a/src/binarysearch/Sqrt.java b/src/binarysearch/Sqrt.java deleted file mode 100644 index ffbdc9d..0000000 --- a/src/binarysearch/Sqrt.java +++ /dev/null @@ -1,22 +0,0 @@ -package binarysearch; - -/** - * https://leetcode.com/problems/sqrtx - */ -public class Sqrt { - - public int mySqrt(int x) { - if(x==0 || x==1) return x; - - long left= 0L; - long right= x; - - while(leftx) right=mid; - else left=mid+1; - } - left--; - return (int)left; - } -} diff --git a/src/common/sorting/ImplementABinaryHeap.java b/src/common/sorting/ImplementABinaryHeap.java deleted file mode 100644 index 9db2639..0000000 --- a/src/common/sorting/ImplementABinaryHeap.java +++ /dev/null @@ -1,248 +0,0 @@ -package common.sorting; -/* - A min heap implementation - - Array Form: [ 5, 7, 6, 10, 15, 17, 12 ] - - Complete Binary Tree Form: - 5 - / \ - 7 6 - / \ / \ - 10 15 17 12 - - Mappings: - Parent -> (childIndex - 1) / 2 - Left Child -> 2 * parentIndex + 1 - Right Child -> 2 * parentIndex + 2 - - YouTube explanation: https://www.youtube.com/watch?v=g9YK6sftDi0 - Heap Sort explanation: https://www.youtube.com/watch?v=k72DtCnY4MU -*/ -import java.util.*; - -public class ImplementABinaryHeap { - int[] insertItems = new int[]{ 0, 1, 3, 2, -4, 9, 1, 2 }; - public static void main(String args[]) { - MinHeap minHeap = new MinHeap(); - int[] insertItems = new int[]{ 0, 1, 3, 2, -4, 9, 1, 2 }; - - for (int i = 0; i < insertItems.length; i++) { - minHeap.add(insertItems[i]); - System.out.println("Add " + insertItems[i]); - System.out.println("Min is " + minHeap.peek()); - - minHeap.printUnderlyingArray(); - - System.out.println("\n"); - } - - System.out.println("\n\n"); - - for (int i = 0; i < insertItems.length; i++) { - System.out.println("Remove " + minHeap.remove()); - System.out.println("Min is " + minHeap.peek()); - - minHeap.printUnderlyingArray(); - - System.out.println("\n"); - } - } - - private static class MinHeap { - private int capacity = 5; - private int heap[]; - private int size; - // int[] temp= new ImplementABinaryHeap().insertItems; - public MinHeap() { - heap = new int[capacity]; - } - - public boolean isEmpty() { - return size == 0; - } - - public int peek() { - if (isEmpty()) { - throw new NoSuchElementException("Heap is empty."); - } - - return heap[0]; - } - - public int remove() { - if (isEmpty()) { - throw new NoSuchElementException("Heap is empty."); - } - - /* - -> Grab the min item. It is at index 0. - -> Move the last item in the heap to the "top" of the - heap at index 0. - -> Reduce size. - */ - int minItem = heap[0]; - heap[0] = heap[size - 1]; - size--; - - /* - Restore the heap since it is very likely messed up now - by bubbling down the element we swapped up to index 0 - */ - heapifyDown(); - - return minItem; - } - - public void add(int itemToAdd) { - ensureExtraCapacity(); - - /* - -> Place the item at the bottom, far right, of the - conceptual binary heap structure - -> Increment size - */ - heap[size] = itemToAdd; - size++; - - /* - Restore the heap since it is very likely messed up now - by bubbling up the element we just put in the last empty - position of the conceptual complete binary tree - */ - siftUp(); - } - - /*********************************** - Heap restoration helpers - ***********************************/ - - private void heapifyDown() { - /* - We will bubble down the item just swapped to the "top" of the heap - after a removal operation to restore the heap - */ - int index = 0; - - /* - Since a binary heap is a complete binary tree, if we have no left child - then we have no right child. So we continue to bubble down as long as - there is a left child. - - A non-existent left child immediately tells us that a right child does - not exist. - */ - while (hasLeftChild(index)) { - /* - By default assume that left child is smaller. If a right - child exists see if it can overtake the left child by - being smaller - */ - int smallerChildIndex = getLeftChildIndex(index); - if (hasRightChild(index) && rightChild(index) < leftChild(index)) { - smallerChildIndex = getRightChildIndex(index); - } - - /* - If the item we are sitting on is < the smaller child then - nothing needs to happen & sifting down is finished. - - But if the smaller child is smaller than the node we are - holding, we should swap and continue sifting down. - */ - if (heap[index] < heap[smallerChildIndex]) { - break; - } else { - swap(index, smallerChildIndex); - } - - // Move to the node we just swapped down - index = smallerChildIndex; - } - } - - // Bubble up the item we inserted at the "end" of the heap - private void siftUp() { - /* - We will bubble up the item just inserted into to the "bottom" - of the heap after an insert operation. It will be at the last index - so index 'size' - 1 - */ - int index = size - 1; - - /* - While the item has a parent and the item beats its parent in - smallness, bubble this item up. - */ - while (hasParent(index) && heap[index] < parent(index)) { - swap(getParentIndex(index), index); - index = getParentIndex(index); - } - } - - /************************************************ - Helpers to access our array easily, perform - rudimentary operations, and manipulate capacity - ************************************************/ - - private void swap(int indexOne, int indexTwo) { - int temp = heap[indexOne]; - heap[indexOne] = heap[indexTwo]; - heap[indexTwo] = temp; - } - - // If heap is full then double capacity - private void ensureExtraCapacity() { - if (size == capacity) { - heap = Arrays.copyOf(heap, capacity * 2); - capacity *= 2; - } - } - - private int getLeftChildIndex(int parentIndex) { - return 2 * parentIndex + 1; - } - - private int getRightChildIndex(int parentIndex) { - return 2 * parentIndex + 2; - } - - private int getParentIndex(int childIndex) { - return (childIndex - 1) / 2; - } - - private boolean hasLeftChild(int index) { - return getLeftChildIndex(index) < size; - } - - private boolean hasRightChild(int index) { - return getRightChildIndex(index) < size; - } - - private boolean hasParent(int index) { - return index != 0 && getParentIndex(index) >= 0; - } - - private int leftChild(int index) { - return heap[getLeftChildIndex(index)]; - } - - private int rightChild(int index) { - return heap[getRightChildIndex(index)]; - } - - private int parent(int index) { - return heap[getParentIndex(index)]; - } - - /***********************************************/ - - private void printUnderlyingArray() { - System.out.print("[ "); - for (int item: heap) { - System.out.print(item + " "); - } - System.out.print("]"); - } - } -} \ No newline at end of file diff --git a/src/common/sorting/InsertionSort.java b/src/common/sorting/InsertionSort.java deleted file mode 100644 index 985edc8..0000000 --- a/src/common/sorting/InsertionSort.java +++ /dev/null @@ -1,30 +0,0 @@ -package common.sorting; - -public class InsertionSort { - - public static void main(String[] args) { - int[] arr = { 12, 11, 13, 5, 6 }; -System.out.println(System.currentTimeMillis()); - - for (int i = 1; i < arr.length; i++) { - int index =i; - for (int j = i-1; j >= 0; j--) { - int value = arr[index]; - if (arr[index] < arr[j]) { - int temp = arr[j]; - arr[j] = value; - arr[index] = temp; - index--; - }else{ - continue; - } - } - } - System.out.println(System.currentTimeMillis()); - - for (int i = 0; i < arr.length; i++) { - System.out.println(arr[i]); - } - } - -} diff --git a/src/common/sorting/KthLargestElement.java b/src/common/sorting/KthLargestElement.java deleted file mode 100644 index 4c2f8d3..0000000 --- a/src/common/sorting/KthLargestElement.java +++ /dev/null @@ -1,62 +0,0 @@ -package common.sorting; - -import java.util.*; - -public class KthLargestElement { - class Solution { - public int findKthLargest(int[] nums, int k) { - - return quickSelect(nums, 0, nums.length-1,nums.length-k); - } - - public void swap(int[] A, int i, int j) { - int temp = A[i]; - A[i] = A[j]; - A[j] = temp; - } - - public int partition(int[] nums, int start, int end) { - Random rand= new Random(); - //Get a random pivot between beg and end - int pivotIndex= start+rand.nextInt(Math.abs(end-start)); - - //New position of pivot element - int last=end; - - //Move the pivot element to right edge of the array - swap(nums,pivotIndex,end); - - end--; - - while(start<=end){ - if(nums[start]= 0; i--) - heapify(arr, i, n); - - for (int i = 0; i < n; i++) - System.out.print(arr[i] + " "); - - System.out.println(); - for (int i = n - 1; i >= 0; i--) { - int temp = arr[0]; - arr[0] = arr[i]; - arr[i] = temp; - - heapify(arr, 0, i); - } - - for (int i = 0; i < n; i++) - System.out.print(arr[i] + " "); - } - - private void heapify(int[] arr, int i, int n) { - int largest = i; - int left = 2 * i + 1; - int right = 2 * i + 2; - - if (left < n && arr[left] > arr[largest]) - largest = left; - if (right < n && arr[right] > arr[largest]) - largest = right; - if (largest != i) { - int temp = arr[largest]; - arr[largest] = arr[i]; - arr[i] = temp; - - heapify(arr, largest, n); - } - } -} \ No newline at end of file diff --git a/src/common/sorting/MergeSort.java b/src/common/sorting/MergeSort.java deleted file mode 100644 index 811f016..0000000 --- a/src/common/sorting/MergeSort.java +++ /dev/null @@ -1,47 +0,0 @@ -package common.sorting; - -import java.util.Arrays; - -class MergeSort { - - static void mergeSort(int arr[], int temp[], int left, int right) { - if (left < right) { - int mid = ((right - left) / 2) + left; - - mergeSort(arr, temp, left, mid); - mergeSort(arr, temp, mid + 1, right); - - merge(arr, temp, left, mid, right); - } - } - - static void merge(int arr[], int temp[], int left, int mid, int right) { - - int i = left; - int j = mid + 1; - int k = left; - while ((i <= mid) && (j <= right)) { - if (arr[i] < arr[j]) { - temp[k++] = arr[i++]; - } else { - temp[k++] = arr[j++]; - } - } - - while (i <= mid) - temp[k++] = arr[i++]; - while (j <= right) - temp[k++] = arr[j++]; - - for (i = left; i <= right; i++) - arr[i] = temp[i]; - - } - - public static void main(String[] args) { - int arr[] = new int[] { 8, 4, 1, 2 }; - int temp[] = new int[arr.length]; - mergeSort(arr, temp, 0, arr.length - 1); - System.out.println(Arrays.toString(arr)); - } -} diff --git a/src/common/sorting/PractiseMergeSort.java b/src/common/sorting/PractiseMergeSort.java deleted file mode 100644 index 78c6cae..0000000 --- a/src/common/sorting/PractiseMergeSort.java +++ /dev/null @@ -1,48 +0,0 @@ -package common.sorting; - -import java.util.Arrays; - -public class PractiseMergeSort { - - public static void main(String[] args) { - int[] arr = { 9, 3, -1, 5, 2, 7 }; - int n = arr.length; - int[] temp = new int[n]; - mergeSort(arr, temp, 0, n - 1); - System.out.println(Arrays.toString(arr)); - } - - private static void mergeSort(int arr[], int temp[], int left, int right) { - while (left < right) { - int mid = ((right - left) / 2) + left; - mergeSort(arr, temp, left, mid); - mergeSort(arr, temp, mid + 1, right); - mergeUtil(arr, temp, left, mid, right); - } - } - - private static void mergeUtil(int[] arr, int[] temp, int left, int mid, int right) { - int i = left; - int j = mid + 1; - int k = left; - - while (i <= mid && j <= right) { - if (arr[i] < arr[j]) { - temp[k++] = arr[i++]; - } else { - temp[k++] = arr[j++]; - } - } - - while (i <= mid) { - temp[k++] = arr[i++]; - } - while (j <= right) { - temp[k++] = arr[j++]; - } - - for (int index = left; index <= right; index++) { - arr[index] = temp[index]; - } - } -} diff --git a/src/common/sorting/QuickSelect.java b/src/common/sorting/QuickSelect.java deleted file mode 100644 index b407d67..0000000 --- a/src/common/sorting/QuickSelect.java +++ /dev/null @@ -1,50 +0,0 @@ -package common.sorting; - -import java.util.Random; - -class QuickSelect { - - public static void swap(int[] A, int i, int j) { - int temp = A[i]; - A[i] = A[j]; - A[j] = temp; - } - - public static int partition(int[] A, int low, int high, int pivotIndex) { - int pivot = A[pivotIndex]; - swap(A, pivotIndex, high); - int iLow = low; - for (int i = low; i < high; i++) { - if (A[i] <= pivot) { - swap(A, i, iLow); - iLow++; - } - } - swap(A, iLow, high); - return iLow; - } - - public static int quickSelect(int[] A, int left, int right, int k) { - if (left == right) { - return A[left]; - } - int pivotIndex = new Random().nextInt(right - left + 1) + left; - pivotIndex = partition(A, left, right, pivotIndex); - if (k == pivotIndex) { - return A[k]; - } else if (k < pivotIndex) { - return quickSelect(A, left, pivotIndex - 1, k); - } else { - return quickSelect(A, pivotIndex + 1, right, k); - } - } - - public static void main(String[] args) { - int[] A = { 7, 4, 6, 3, 9, 1 }; - int k = 2; - - System.out.print("K'th smallest element is " + quickSelect(A, 0, A.length - 1, k)); - } -} - - diff --git a/src/common/sorting/QuickSort.java b/src/common/sorting/QuickSort.java deleted file mode 100644 index 25691d7..0000000 --- a/src/common/sorting/QuickSort.java +++ /dev/null @@ -1,57 +0,0 @@ -package common.sorting; - -import java.util.Random; - -public class QuickSort { - - public int[] sortArray(int[] nums) { - - quickSort(nums, 0, nums.length-1); - - return nums; -} - - public void quickSort(int[] nums, int start, int end){ - if(starti) continue; - int change =i-coins[j]; // when i is 5 and coins =[1,2,5] and j=1(first coin)we subtract 5-1=4 we need ans for 4, which we'd have calculated when i=4 - int temp=result[change]+1; // when found a coin we add 1 to the position - result[i]=Math.min(result[i],temp); - - } - - } - - return result[amount] > amount ? -1 : result[amount]; - } -} diff --git a/src/dynamicProgramming/MinimumNumberOfJumpsToReachEnd.java b/src/dynamicProgramming/MinimumNumberOfJumpsToReachEnd.java deleted file mode 100644 index 667a039..0000000 --- a/src/dynamicProgramming/MinimumNumberOfJumpsToReachEnd.java +++ /dev/null @@ -1,64 +0,0 @@ -package dynamicProgramming; - -/** - * Date 06/12/2014 - * - * @author tusroy - * - * Space complexity O(n) to maintain result and min jumps Time - * complexity O(n^2) - * - * http://www.geeksforgeeks.org/minimum-number-of-jumps-to-reach-end-of-a-given-array/ - * https://www.youtube.com/watch?v=cETfFsSTGJI - */ -public class MinimumNumberOfJumpsToReachEnd { - - public int minJump(int arr[], int result[]) { - - int[] jump = new int[arr.length]; - jump[0] = 0; - for (int i = 1; i < arr.length; i++) { - jump[i] = Integer.MAX_VALUE - 1; - } - - for (int i = 1; i < arr.length; i++) { - for (int j = 0; j < i; j++) { - if (arr[j] + j >= i) { - if (jump[i] > jump[j] + 1) { - result[i] = j; - jump[i] = jump[j] + 1; - } - } - } - } - - return jump[jump.length - 1]; - } - - public static void main(String args[]) { - MinimumNumberOfJumpsToReachEnd mj = new MinimumNumberOfJumpsToReachEnd(); - int arr[] = { 2, 3, 1, 1, 2, 4, 2, 0, 1, 1 }; - int r[] = new int[arr.length]; - int result = mj.minJump(arr, r); - System.out.println(result); - } - - - public int jump(int[] A) { - int jumps = 0, curEnd = 0, curFarthest = 0; - for (int i = 0; i < A.length - 1; i++) { - curFarthest = Math.max(curFarthest, i + A[i]); - // for this input { 1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9 } - // when i is at 1[3] farthest one can jump is till 4(farthest) and end is also updated, means till i reaches 4 if the farthest reaches the array end we break out of loop; - if (i == curEnd) { - jumps++; - curEnd = curFarthest; - - if (curEnd >= A.length - 1) { - break; - } - } - } - return jumps; - } -} \ No newline at end of file diff --git a/src/dynamicProgramming/OptimalStratergy.java b/src/dynamicProgramming/OptimalStratergy.java deleted file mode 100644 index 77b6548..0000000 --- a/src/dynamicProgramming/OptimalStratergy.java +++ /dev/null @@ -1,66 +0,0 @@ -package dynamicProgramming; - -/** - * http://www.glassdoor.com/Interview/N-pots-each-with-some-number-of-gold-coins-are-arranged-in-a-line-You-are-playing-a-game-against-another-player-You-tak-QTN_350584.htm - * - * https://www.techiedelight.com/pots-gold-game-dynamic-programming/ - */ -public class OptimalStratergy { - // Function to maximize the number of coins collected by a player, - // assuming that opponent also plays optimally - public static int optimalStrategy(int[] coin, int i, int j, - int[][] lookup) - { - // base case: one pot left, only one choice possible - if (i == j) { - return coin[i]; - } - - // if we're left with only two pots, choose one with maximum coins - if (i + 1 == j) { - return Integer.max(coin[i], coin[j]); - } - - // if sub-problem is seen for the first time, solve it and - // store its result in a lookup table - if (lookup[i][j] == 0) - { - // if player chooses front coin i, opponent is left to choose - // from [i+1, j]. - // 1. if opponent chooses front coin i+1, recur for [i+2, j] - // 2. if opponent chooses rear coin j, recur for [i+1, j-1] - - int start = coin[i] + Integer.min(optimalStrategy(coin, i + 2, - j, lookup), - optimalStrategy(coin, i + 1, j - 1, lookup)); - - // if player chooses rear coin j, opponent is left to choose - // from [i, j-1]. - // 1. if opponent chooses front coin i, recur for [i+1, j-1] - // 2. if opponent chooses rear coin j-1, recur for [i, j-2] - - int end = coin[j] + Integer.min(optimalStrategy(coin, i + 1, - j - 1, lookup), - optimalStrategy(coin, i, j - 2, lookup)); - - // assign maximum of two choices - lookup[i][j] = Integer.max(start, end); - } - - // return the subproblem solution from the map - return lookup[i][j]; - } - - // main function - public static void main(String[] args) - { - // pots of gold arranged in a line - int[] coin = { 4, 6, 2, 3 }; - - // Create a table to store solutions of subproblems - int[][] lookup = new int[coin.length][coin.length]; - - System.out.println("Maximum coins collected by player is " - + optimalStrategy(coin, 0, coin.length - 1, lookup)); - } -} \ No newline at end of file diff --git a/src/dynamicProgramming/StockBuySellKTransactions.java b/src/dynamicProgramming/StockBuySellKTransactions.java deleted file mode 100644 index 28df38a..0000000 --- a/src/dynamicProgramming/StockBuySellKTransactions.java +++ /dev/null @@ -1,103 +0,0 @@ -package dynamicProgramming; - -import java.util.Arrays; -import java.util.Deque; -import java.util.LinkedList; - -/** - * Date 12/22/2015 - * - * @author Tushar Roy - * - * Time complexity - O(number of transactions * number of days) Space - * complexity - O(number of transactions * number of days) - * - * https://leetcode.com/discuss/15153/a-clean-dp-solution-which-generalizes-to-k-transactions - * https://www.youtube.com/watch?v=Pw6lrYANjz4&t=1228s - */ -public class StockBuySellKTransactions { - - public int maxProfit(int prices[], int K) { - if (K == 0 || prices.length == 0) { - return 0; - } - int T[][] = new int[K + 1][prices.length]; - - for (int i = 1; i < T.length; i++) { - int maxDiff = -prices[0]; - for (int j = 1; j < T[0].length; j++) { - T[i][j] = Math.max(T[i][j - 1], prices[j] + maxDiff); - maxDiff = Math.max(maxDiff, T[i - 1][j] - prices[j]); - } - } - - System.out.println(Arrays.deepToString(T)); - printActualSolution(T, prices); - return T[K][prices.length - 1]; - } - public int maxProfit(int k, int[] prices) { - if(prices.length==0 || k==0) return 0; - - if(k>prices.length/2) return quickSolve(prices); - - int[][] maxProfit= new int[k+1][prices.length]; - //int diff=0; - for(int i=1;i<=k;i++){ - int diff = -prices[0]; - for(int j=1; j prices[i - 1]) profit += prices[i] - prices[i - 1]; - return profit; - } - public void printActualSolution(int T[][], int prices[]) { - int i = T.length - 1; - int j = T[0].length - 1; - - Deque stack = new LinkedList<>(); - while (true) { - if (i == 0 || j == 0) { - break; - } - if (T[i][j] == T[i][j - 1]) { - j = j - 1; - } else { - stack.addFirst(j); - int maxDiff = T[i][j] - prices[j]; - for (int k = j - 1; k >= 0; k--) { - if (T[i - 1][k] - prices[k] == maxDiff) { - i = i - 1; - j = k; - stack.addFirst(j); - break; - } - } - } - } - - while (!stack.isEmpty()) { - System.out.println("Buy at price " + prices[stack.pollFirst()]); - System.out.println("Sell at price " + prices[stack.pollFirst()]); - } - - } - - public static void main(String args[]) { - StockBuySellKTransactions sbt = new StockBuySellKTransactions(); - int prices[] = { 2, 5, 7, 1, 4, 3, 1, 3 }; - - System.out.println("Max profit fast solution " + sbt.maxProfit(prices, 3)); - } -} diff --git a/src/dynamicProgramming/StockBuySellWithCoolDown.java b/src/dynamicProgramming/StockBuySellWithCoolDown.java deleted file mode 100644 index e8db2b0..0000000 --- a/src/dynamicProgramming/StockBuySellWithCoolDown.java +++ /dev/null @@ -1,53 +0,0 @@ -package dynamicProgramming; - -public class StockBuySellWithCoolDown { - - public int maxProfit(int[] prices) { - - if (prices == null || prices.length < 2) return 0; - int buy = 0, sell = -prices[0], rest = 0; - - // Assume the buy, sell and rest are states - // the transistions would be - // 1) from Rest you have to come to buy - // 2) from buy you can rest/hold or you can sell - // 3) from sell you can hold or sell and go to Rest - - // state 1=> first transistion max(buy, rest) we can either buy or rest at this point - // state 2=> we can either hold what was there in previous state or buy so '-' price[i] - // state 3=> to come to rest we have to sell and make profit so only the '+' sign - - for (int i = 1; i < prices.length; i++) { - int tmp = buy; - buy = Math.max(buy, rest); - rest = sell+prices[i]; - sell = Math.max(sell,tmp -prices[i]); - } - return Math.max(buy,rest); - } - - public static int maxProfit1(int[] prices){ - if(prices==null || prices.length<=1){ - return 0; - } - /** - there can be two types of profit we need to track - sellProf[i] - profit earned by selling on ith day - restProf[i] - profit earned by resting on ith day - */ - int sellProf = 0; - int restProf = 0; - int lastProf = 0; - for(int i = 1;i=0) - dp[i][j]+= dp[i][j-coins[i-1]]; - } - } - - - return dp[coins.length][amount]; - } -} diff --git a/src/dynamicProgramming/WordBreak.java b/src/dynamicProgramming/WordBreak.java deleted file mode 100644 index 2def948..0000000 --- a/src/dynamicProgramming/WordBreak.java +++ /dev/null @@ -1,109 +0,0 @@ -package dynamicProgramming; - -import java.util.*; - -/** - * Date 08/01/2014 - * - * @author tusroy - * - * Given a string and a dictionary, split this string into multiple - * words such that each word belongs in dictionary. - * - * e.g peanutbutter -> pea nut butter e.g Iliketoplay -> I like to play - * - * Solution DP solution to this problem if( input[i...j] belongs in - * dictionary) T[i][j] = i else{ T[i][j] = k if T[i][k-1] != -1 && - * T[k][j] != -1 - * - * Test cases 1) Empty string 2) String where entire string is in - * dictionary 3) String which cannot be split into words which are in - * dictionary 3) String which can be split into words which are in - * dictionary - * - */ -public class WordBreak { - - public String breakWordDP(String word, Set dict) { - int[][] T = new int[word.length()][word.length()]; - - for (int i = 0; i < T.length; i++) { - for (int j = 0; j < T[i].length; j++) { - T[i][j] = -1; - } - } - - for (int l = 1; l <= word.length(); l++) { - for (int i = 0; i < word.length() - l + 1; i++) { - int j = i + l - 1; - String str = word.substring(i, j + 1); - - if (dict.contains(str)) { - T[i][j] = i; - continue; - } - // find a k between i+1 to j such that T[i][k-1] && T[k][j] are both true - for (int k = i + 1; k <= j; k++) { - if (T[i][k - 1] != -1 && T[k][j] != -1) { - T[i][j] = k; - break; - } - } - } - } - if (T[0][word.length() - 1] == -1) { - return null; - } - - // create space separate word from string is possible - StringBuffer buffer = new StringBuffer(); - int i = 0; - int j = word.length() - 1; - while (i < j) { - int k = T[i][j]; - if (i == k) { - buffer.append(word.substring(i, j + 1)); - break; - } - buffer.append(word.substring(i, k) + " "); - i = k; - } - - return buffer.toString(); - } - - public static void main(String args[]) { - Set dictionary = new HashSet(); - dictionary.add("I"); - dictionary.add("am"); - dictionary.add("ace"); - String str = "Iamace"; - WordBreak bmw = new WordBreak(); - String result1 = bmw.breakWordDP(str, dictionary); - System.out.println(bmw.wordBreakBottomUp(str, dictionary)); - - //System.out.print(result1); - } - - /** - * to find out it has all the words - */ - public boolean wordBreakBottomUp(String s, Set set) { - //s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"] ans=false - boolean[] f = new boolean[s.length() + 1]; - //f[i] stands for whether subarray(0, i) can be segmented into words from the dictionary. - // So f[0] means whether subarray(0, 0) (which is an empty string) can be segmented, and of course the answer is yes. - //The default value for boolean array is false. Therefore we need to set f[0] to be true. - - f[0] = true; - for (int i = 1; i <= s.length(); i++) { - for (int j = i - 1; j >= 0; j--) { - System.out.println(s.substring(j, i)); - f[i] = f[j] && set.contains(s.substring(j, i)); - if (f[i]) break; - } - } - return f[s.length()]; - } - -} \ No newline at end of file diff --git a/src/dynamicProgramming/WordBreakII.java b/src/dynamicProgramming/WordBreakII.java deleted file mode 100644 index 4e327f9..0000000 --- a/src/dynamicProgramming/WordBreakII.java +++ /dev/null @@ -1,34 +0,0 @@ -package dynamicProgramming; - -import java.util.*; - -public class WordBreakII { - - public List wordBreak(String s, List wordDict) { - Map> cache = new HashMap<>(); - return backtrack(s,wordDict, cache); - } - - public List backtrack(String s, List wordDict, Map> cache){ - - if(cache.containsKey(s)) return cache.get(s); - - List result = new ArrayList<>(); - for(String word: wordDict) { - if(!s.startsWith(word)) continue; // string does not start with this word? - String next = s.substring(word.length()); - if(next.isEmpty()) { // awesome! - result.add(word); - continue; - } - for(String sub: backtrack(next, wordDict, cache)) - result.add(word + " " + sub); - } - cache.put(s, result); - return result; - } - - public static void main(String[] args) { - new WordBreakII().wordBreak( "catsanddog",Arrays.asList("cat", "cats", "and", "sand", "dog")); - } -} diff --git a/src/dynamicProgramming/fibonacci/DecodeWays.java b/src/dynamicProgramming/fibonacci/DecodeWays.java deleted file mode 100644 index 9903e3f..0000000 --- a/src/dynamicProgramming/fibonacci/DecodeWays.java +++ /dev/null @@ -1,74 +0,0 @@ -package dynamicProgramming.fibonacci; - -/** - * https://www.youtube.com/watch?v=YcJTyrG3bZs - * https://www.geeksforgeeks.org/count-possible-decodings-given-digit-sequence/ - * - */ -public class DecodeWays { - - public int numDecodings(String s) { - if (s == null || s.length() == 0) { - return 0; - } - int n = s.length(); - int[] dp = new int[n + 1]; - dp[0] = 1; // initialize the base case means an empty string will have one way to decode - dp[1] = s.charAt(0) != '0' ? 1 : 0; // means the way to decode a string of size 1 - for (int i = 2; i <= n; i++) { - int first = Integer.parseInt(s.substring(i - 1, i)); - int second = Integer.parseInt(s.substring(i - 2, i)); - if (first >= 1 && first <= 9) { - dp[i] += dp[i - 1]; - } - if (second >= 10 && second <= 26) { - dp[i] += dp[i - 2]; - } - } - return dp[n]; - } - public int numDecodings1(String s) { - if(s==null|| s.length()==0) return 0; - Integer [] cache= new Integer[s.length()+1]; - return helperFn(s,0,cache); - // cache[s.length()]; - - } - - public int helperFn(String s, int index, Integer[] cache){ - if( index>=s.length()) return 1; - - if(cache[index]!=null) return cache[index]; - int total=0; - if(index+1<=s.length()){ - String temp1= s.substring(index,index+1); - if(valid(temp1)){ - total+=helperFn(s,index+1,cache); - } - } - - if(index+2 <= s.length()){ - String temp2= s.substring(index, index+2); - if(valid(temp2)){ - total+=helperFn(s,index+2,cache); - } - } - - cache[index]=total; - return cache[index]; - - } - - public boolean valid(String s1){ - if(s1.length()==0) return false; - if(s1.charAt(0)=='0') return false; - - int val=Integer.parseInt(s1); - - return val>=1 && val<=26; - } - public static void main(String[] args) { - DecodeWays decode = new DecodeWays(); - System.out.println(decode.numDecodings("1210")); - } -} diff --git a/src/dynamicProgramming/fibonacci/DiceThrow.java b/src/dynamicProgramming/fibonacci/DiceThrow.java deleted file mode 100644 index 24d29d9..0000000 --- a/src/dynamicProgramming/fibonacci/DiceThrow.java +++ /dev/null @@ -1,40 +0,0 @@ -package dynamicProgramming.fibonacci; - -/** - * Time Complexity: O(m * n * x) - * - */ -class DiceThrow { - // m-> faces - // n->dices - // x->sum - public static long findWays(int m, int n, int x) { - - long[][] T = new long[n + 1][x + 1]; - - for (int j = 1; j <= m && j <= x; j++) - T[1][j] = 1; - - for (int i = 2; i <= n; i++) { - System.out.println("i=" + i); - for (int j = 1; j <= x; j++) { - System.out.println("j =" + j); - for (int k = 1; k < j && k <= m; k++) { - System.out.println("T[" + (i - 1) + "][" + (j - k) + "]"); - T[i][j] += T[i - 1][j - k]; - } - } - } - - for (int i = 0; i < n + 1; i++) { - for (int j = 0; j < x + 1; j++) - System.out.print(T[i][j] + " "); - System.out.println(); - } - return T[n][x]; - } - - public static void main(String[] args) { - System.out.println(findWays(6, 3, 6)); - } -} \ No newline at end of file diff --git a/src/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java b/src/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java deleted file mode 100644 index 67f2d08..0000000 --- a/src/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java +++ /dev/null @@ -1,72 +0,0 @@ -package dynamicProgramming.fibonacci; - -import java.util.Arrays; - -public class FibonacciStaircaseWaysToCoverDist { - - public int fibonacciSeriesRecursive(int n) { - if (n == 1) - return 2; - if (n == 2) - return 3; - return fibonacciSeriesRecursive(n - 1) + fibonacciSeriesRecursive(n - 2); - } - - public static void main(String args[]) { - FibonacciStaircaseWaysToCoverDist fs = new FibonacciStaircaseWaysToCoverDist(); - System.out.println(fs.fibonacciSeries(4)); - System.out.println(fs.fibonacciSeriesRecursive(3)); - } - - public int fibonacciSeries(int n) { - int n1 = 0; - int n2 = 1; - int sum; - - if (n == n1 || n == n2) { - return n; - } - - for (int i = 1; i <= n; i++) { - sum = n1 + n2; - n1 = n2; - n2 = sum; - } - return n2; - } - - public int climbStairs(int N) { - int[] cache= new int[N+1]; - Arrays.fill(cache,-1); - return fibUtil(N,0,cache); - } - - public int fibUtil(int N, int start, int [] cache){ - if(start>N) return 0; - - if(N==start) return 1; - - if(cache[start]!=-1) return cache[start]; - - cache[start]= fibUtil(N,start+1, cache)+fibUtil(N,start+2, cache); - - return cache[start]; - } - - - public int minCostClimbingStairs(int[] cost) { - if(cost.length==2) return Math.min(cost[0],cost[1]); - int[] dp= new int[cost.length+1]; - dp[0]=cost[0]; - dp[1]=cost[1]; - - for(int i=2;i arr[j]) { - lis[i] = Math.max(lis[i], lis[j] + 1); - } - } - } - - for (int i = arr.length - 2; i >= 0; i--) { - for (int j = arr.length - 1; j > i; j--) { - if (arr[i] > arr[j]) { - lds[i] = Math.max(lds[i], lds[j] + 1); - } - } - } - // because that middle element is common in both sequence .. for example, - // increasing subsequence 2,8,20 .. decreasing one 20,13,14 .. each of them has - // length 3 .. but bitonic subsequence 2,8,20,13,14 .. length= 3+3-1=5 - int max = 0; - for (int i = 0; i < arr.length; i++) { - System.out.print(lis[i] + lds[i] - 1 + " "); - if (max < lis[i] + lds[i] - 1) { - max = lis[i] + lds[i] - 1; - } - } - System.out.println(); - return max; - } - - public static void main(String args[]) { - BitonicSequence bs = new BitonicSequence(); - int[] arr = { 1, 4, 3, 7, 2, 1, 8, 11, 13, 0 }; - int r = bs.longestSequence(arr); - System.out.println(r); - - } -} \ No newline at end of file diff --git a/src/dynamicProgramming/lcs/LongestCommonSubsequence.java b/src/dynamicProgramming/lcs/LongestCommonSubsequence.java deleted file mode 100644 index 342382f..0000000 --- a/src/dynamicProgramming/lcs/LongestCommonSubsequence.java +++ /dev/null @@ -1,86 +0,0 @@ -package dynamicProgramming.lcs; - -public class LongestCommonSubsequence { - - public static void main(String[] args) { - String str1 = "ABCD"; - String str2 = "AEDB"; - - System.out.println(getLCS(str1.toCharArray(), str2.toCharArray())); - - // System.out.println(lcs(str1.toCharArray(), str2.toCharArray(), str1.length(), str2.length())); - } - - private static int getLCS(char[] str1, char[] str2) { - - int temp[][] = new int[str1.length + 1][str2.length + 1]; - int max = 0; - for (int i = 1; i < temp.length; i++) { - for (int j = 1; j < temp[i].length; j++) { - if (str1[i - 1] == str2[j - 1]) { - temp[i][j] = temp[i - 1][j - 1] + 1; - } else { - temp[i][j] = Math.max(temp[i][j - 1], temp[i - 1][j]); - } - if (temp[i][j] > max) { - max = temp[i][j]; - } - } - } - return max; - } - - public int longestCommonSubsequence(String text1, String text2) { - if(text1==null || text2==null) return 0; - - int[][] dp= new int[text1.length()+1][text2.length()+1]; - - for(int i=1;i<=text1.length();i++){ - for(int j=1; j<=text2.length(); j++){ - if(text1.charAt(i-1)==text2.charAt(j-1)){ - dp[i][j]= 1+dp[i-1][j-1]; // previously matched characters - }else{ - dp[i][j]= Math.max(dp[i][j-1],dp[i-1][j]); - } - } - } - - return dp[text1.length()][text2.length()]; - } - - static int lcs(char[] X, char[] Y, int m, int n) { - if (m == 0 || n == 0) - return 0; - if (X[m - 1] == Y[n - 1]) - return 1 + lcs(X, Y, m - 1, n - 1); - else - return Math.max(lcs(X, Y, m, n - 1), lcs(X, Y, m - 1, n)); - } - - public int longestCommonSubsequenceRec(String text1, String text2) { - if(text1==null || text2==null) return 0; - - Integer[][] dp= new Integer[text1.length()+1][text2.length()+1]; - - longestCommonSubsequenceUtil(text1, text1.length(), text2, text2.length(), dp); - - return dp[text1.length()][text2.length()]; - } - - public int longestCommonSubsequenceUtil(String text1,int i, String text2,int j, Integer[][] dp ){ - if(i<=0 || j<=0) return 0; - - if(dp[i][j]!=null) return dp[i][j]; - - if(text1.charAt(i-1)==text2.charAt(j-1)){ - dp[i][j]=1+longestCommonSubsequenceUtil(text1, i-1, text2, j-1, dp); - }else{ - dp[i][j]= Math.max(longestCommonSubsequenceUtil(text1, i, text2, j-1, dp), longestCommonSubsequenceUtil(text1, i-1, text2, j, dp)); - } - - return dp[i][j]; - } - -} - - diff --git a/src/dynamicProgramming/lcs/LongestIncreasingSubsequence.java b/src/dynamicProgramming/lcs/LongestIncreasingSubsequence.java deleted file mode 100644 index 7379630..0000000 --- a/src/dynamicProgramming/lcs/LongestIncreasingSubsequence.java +++ /dev/null @@ -1,112 +0,0 @@ -package dynamicProgramming.lcs; - -import java.util.Arrays; -import java.util.PriorityQueue; - -/** - * Solve the LIS subproblem for each snippet of the array ending between 1, 2, - * 3, ... and so on until nums.length - 1 (inclusive) - * - * Ex: - * - * [-2, 1, 2, 3] - * - * [-2] from index 0 to index 0 [-2, 1] from index 0 to index 1 [-2, 1, 2] from - * index 0 to index 2 [-2, 1, 2, 3] from index 0 to index 3 - * - * Our answer is the maximum LNDS found between all subproblems we solve along - * the way. - * - * Time complexity is O(n^2). - */ -public class LongestIncreasingSubsequence { - - public static void main(String[] args) { - int[] nums = { 10, 22, 9, 33, 21, 50, 41, 60, 80 }; - - - lengthOfLIS(nums); - } - - private static void lisLength(int[] nums) { - int[] result = new int[nums.length]; - Arrays.fill(result, 1); - - int maximumSoFar = 1; - - for (int i = 1; i < nums.length; i++) { - for (int j = 0; j < i; j++) { - if (nums[i] > nums[j]) { - result[i] = Math.max(result[i], result[j] + 1); - } - } - maximumSoFar = Math.max(maximumSoFar, result[i]); - } - System.out.println(maximumSoFar); - } - - public static int findPositionToReplace(int[] a, int low, int high, int x) { - int mid; - while (low <= high) { - mid = low + (high - low) / 2; - if (a[mid] == x) - return mid; - else if (a[mid] > x) - high = mid - 1; - else - low = mid + 1; - } - return low; - } - - public static int lengthOfLIS(int[] nums) { - if (nums == null | nums.length == 0) - return 0; - //Set hash= new HashSet(Arrays.asList(nums)); - int n = nums.length, len = 0; - int[] increasingSequence = new int[n]; - increasingSequence[len++] = nums[0]; - for (int i = 1; i < n; i++) { - if (nums[i] > increasingSequence[len - 1]) - increasingSequence[len++] = nums[i]; - else { - int position = findPositionToReplace(increasingSequence, 0, len - 1, nums[i]); - increasingSequence[position] = nums[i]; - } - } - return len; - } - public int eraseOverlapIntervals(int[][] intervals) { - if(intervals.length==0) return 0; - -// PriorityQueue queue= new PriorityQueue()((a, b)->{ -// if(a[0]==b[0]) return Integer.compare(a[1],b[1]); -// return Integer.compare(a[0],b[0]); -// }); - - PriorityQueue queue = new PriorityQueue((a, b) -> { - if(a[0]==b[0]) return Integer.compare(a[1],b[1]); - return Integer.compare(a[0],b[0]); - }); - - for(int[] interval: intervals){ - queue.offer(interval); - } - int result=0; - int[] temp= queue.poll(); - int start= temp[0]; - int end= temp[1]; - - while(!queue.isEmpty()){ - if(end>queue.peek()[0]) { - result++; - queue.poll(); - }else{ - end=Math.max(end,queue.poll()[1]); - } - } - - return result; - } - -} diff --git a/src/dynamicProgramming/lcs/MaximumProductSubarray.java b/src/dynamicProgramming/lcs/MaximumProductSubarray.java deleted file mode 100644 index 87fe425..0000000 --- a/src/dynamicProgramming/lcs/MaximumProductSubarray.java +++ /dev/null @@ -1,38 +0,0 @@ -package dynamicProgramming.lcs; - -public class MaximumProductSubarray { - - static int maxSubarrayProduct(int arr[], int n) { - int max_ending_here = 1; - int min_ending_here = 1; - - int max_so_far = 1; - int flag = 0; - for (int i = 0; i < n; i++) { - if (arr[i] > 0) { - max_ending_here = max_ending_here * arr[i]; - min_ending_here = Math.min(min_ending_here * arr[i], 1); - flag = 1; - } else if (arr[i] == 0) { - max_ending_here = 1; - min_ending_here = 1; - } else { - int temp = max_ending_here; - max_ending_here = Math.max(min_ending_here * arr[i], 1); - min_ending_here = temp * arr[i]; - } - if (max_so_far < max_ending_here) - max_so_far = max_ending_here; - } - if (flag == 0 && max_so_far == 1) - return 0; - return max_so_far; - } - - public static void main(String[] args) { - int arr[] = { 1, -2, -3, 0, 8, 7, -2 }; - int n = arr.length; - System.out.println("Maximum Sub array product is " + maxSubarrayProduct(arr, n)); - } - -} diff --git a/src/dynamicProgramming/lcs/TwoStringInterleavingToFormThird.java b/src/dynamicProgramming/lcs/TwoStringInterleavingToFormThird.java deleted file mode 100644 index 75e0d18..0000000 --- a/src/dynamicProgramming/lcs/TwoStringInterleavingToFormThird.java +++ /dev/null @@ -1,45 +0,0 @@ -package dynamicProgramming.lcs; - -/** - * - * http://www.geeksforgeeks.org/check-whether-a-given-string-is-an-interleaving-of-two-other-given-strings-set-2/ - */ -public class TwoStringInterleavingToFormThird { - - public boolean isInterleaved(char str1[], char str2[], char str3[]) { - boolean T[][] = new boolean[str1.length + 1][str2.length + 1]; - - if (str1.length + str2.length != str3.length) { - return false; - } - - for (int i = 0; i < T.length; i++) { - for (int j = 0; j < T[i].length; j++) { - int l = i + j - 1; - if (i == 0 && j == 0) { - T[0][0] = true; - } else if (i == 0) { - if (str1[j - 1] == str3[l]) { - T[i][j] = T[i][j - 1]; - } - } else if (j == 0) { - if (str2[i - 1] == str3[l]) { - T[i][j] = T[i - 1][j]; - } - } else { - T[i][j] = (str1[i - 1] == str3[l] ? T[i - 1][j] : false) - || (str2[j - 1] == str3[l] ? T[i][j - 1] : false); - } - } - } - return T[str1.length][str2.length]; - } - - public static void main(String args[]) { - String str1 = "aab"; - String str2 = "axy"; - String str3 = "aaxaby"; - TwoStringInterleavingToFormThird sti = new TwoStringInterleavingToFormThird(); - System.out.println(sti.isInterleaved(str1.toCharArray(), str2.toCharArray(), str3.toCharArray())); - } -} diff --git a/src/dynamicProgramming/lcs/WildCardMatching.java b/src/dynamicProgramming/lcs/WildCardMatching.java deleted file mode 100644 index 9b78d68..0000000 --- a/src/dynamicProgramming/lcs/WildCardMatching.java +++ /dev/null @@ -1,85 +0,0 @@ -package dynamicProgramming.lcs; - -/** - * Date 02/11/2016 - * - * @author Tushar Roy - * - * Reference https://leetcode.com/problems/wildcard-matching/ - */ -public class WildCardMatching { - - public boolean isMatch(String s, String p) { - char[] str = s.toCharArray(); - char[] pattern = p.toCharArray(); - - // replace multiple * with one * - // e.g a**b***c --> a*b*c - int writeIndex = 0; - boolean isFirst = true; - for (int i = 0; i < pattern.length; i++) { - if (pattern[i] == '*') { - if (isFirst) { - pattern[writeIndex++] = pattern[i]; - isFirst = false; - } - } else { - pattern[writeIndex++] = pattern[i]; - isFirst = true; - } - } - boolean[][] T = new boolean[str.length + 1][writeIndex + 1]; - if (writeIndex > 0 && pattern[0] == '*') { - T[0][1] = true; - } - - T[0][0] = true; - for (int i = 1; i < T.length; i++) { - for (int j = 1; j <= writeIndex; j++) { - if (pattern[j - 1] == '?' || str[i - 1] == pattern[j - 1]) { - T[i][j] = T[i - 1][j - 1]; - } else if (pattern[j - 1] == '*') { - T[i][j] = T[i - 1][j] || T[i][j - 1]; - } - } - } - - return T[str.length][writeIndex]; - } - - public boolean isMatchint(String s, String p) { - if(s==null || p==null) return false; - - - boolean[][] dp= new boolean[s.length()+1][p.length()+1]; - - dp[0][0]= true; - - for(int j=1; j<=p.length(); j++) { - if(p.charAt(j-1)=='*'){ - dp[0][j] = true; - } else { - break; - } - } - - for(int i=1; i<=s.length();i++){ - for(int j=1; j<=p.length(); j++){ - if(p.charAt(j-1)=='?' || p.charAt(j-1)==s.charAt(i-1)){ - dp[i][j]=dp[i-1][j-1]; - } - else if(p.charAt(j-1)=='*'){ - dp[i][j]=dp[i-1][j] || dp[i][j-1]; - } - } - } - - return dp[s.length()][p.length()]; - } - - public static void main(String args[]) { - WildCardMatching wcm = new WildCardMatching(); - System.out.println(wcm.isMatch("xbylmz", "x?y***z")); - - } -} \ No newline at end of file diff --git a/src/dynamicProgramming/matrix/MatrixMultiplicationCost.java b/src/dynamicProgramming/matrix/MatrixMultiplicationCost.java deleted file mode 100644 index 83ff551..0000000 --- a/src/dynamicProgramming/matrix/MatrixMultiplicationCost.java +++ /dev/null @@ -1,43 +0,0 @@ -package dynamicProgramming.matrix; - -/** - * http://www.geeksforgeeks.org/dynamic-programming-set-8-matrix-chain-multiplication/ - * https://www.youtube.com/watch?v=vgLJZMUfnsU&t=316s - */ -public class MatrixMultiplicationCost { - - public int findCost(int arr[]) { - int[][] T = new int[arr.length][arr.length]; - int q = 0; - for (int l = 2; l < arr.length; l++) { - for (int i = 0; i < arr.length - l; i++) { - int j = i + l; - T[i][j] = 1000000; - for (int k = i + 1; k < j; k++) { - System.out.println("T[" + i + "][" + j + "] :: T[" + i + "][" + k + "] * T[" + k + "][" + j + "] *" - + arr[i] + "*" + arr[k] + "*" + arr[j]); - q = T[i][k] + T[k][j] + arr[i] * arr[k] * arr[j]; - if (q < T[i][j]) { - T[i][j] = q; - } - } - } - } - System.out.println(); - for (int i = 0; i < arr.length; i++) { - for (int j = 0; j < arr.length; j++) { - System.out.print(T[i][j] + " "); - } - System.out.println(); - } - - return T[0][arr.length - 1]; - } - - public static void main(String args[]) { - MatrixMultiplicationCost mmc = new MatrixMultiplicationCost(); - int arr[] = { 2, 3, 6, 4, 5 }; - int cost = mmc.findCost(arr); - System.out.print(cost); - } -} \ No newline at end of file diff --git a/src/dynamicProgramming/matrix/MaximumSizeSubMatrix.java b/src/dynamicProgramming/matrix/MaximumSizeSubMatrix.java deleted file mode 100644 index bfcab99..0000000 --- a/src/dynamicProgramming/matrix/MaximumSizeSubMatrix.java +++ /dev/null @@ -1,57 +0,0 @@ -package dynamicProgramming.matrix; - -/** - * http://www.geeksforgeeks.org/maximum-size-sub-matrix-with-all-1s-in-a-binary-matrix/ - * - * https://www.youtube.com/watch?v=_Lf1looyJMU&t=2s - */ -public class MaximumSizeSubMatrix { - - private int min(int a, int b, int c) { - int l = Math.min(a, b); - return Math.min(l, c); - } - - public int maxSize(int arr[][]) { - - int result[][] = new int[arr.length][arr[0].length]; - int max = 0; - for (int i = 0; i < arr.length; i++) { - result[i][0] = arr[i][0]; - if (result[i][0] == 1) { - max = 1; - } - } - - for (int i = 0; i < arr[0].length; i++) { - result[0][i] = arr[0][i]; - if (result[0][i] == 1) { - max = 1; - } - - } - - for (int i = 1; i < arr.length; i++) { - for (int j = 1; j < arr[i].length; j++) { - if (arr[i][j] == 0) { - continue; - } - int t = min(result[i - 1][j], result[i - 1][j - 1], result[i][j - 1]); - result[i][j] = t + 1; - if (result[i][j] > max) { - max = result[i][j]; - } - } - } - return max; - } - - public static void main(String args[]) { - - int arr[][] = { { 0, 1, 1, 0, 1 }, { 1, 1, 1, 0, 0 }, { 1, 1, 1, 1, 0 }, { 1, 1, 1, 0, 1 } }; - MaximumSizeSubMatrix mssm = new MaximumSizeSubMatrix(); - int result = mssm.maxSize(arr); - System.out.print(result); - } - -} \ No newline at end of file diff --git a/src/dynamicProgramming/matrix/MinCostPath.java b/src/dynamicProgramming/matrix/MinCostPath.java deleted file mode 100644 index e2c216a..0000000 --- a/src/dynamicProgramming/matrix/MinCostPath.java +++ /dev/null @@ -1,41 +0,0 @@ -package dynamicProgramming.matrix; - -/** - * http://www.geeksforgeeks.org/dynamic-programming-set-6-min-cost-path/ - */ -public class MinCostPath { - - public int minCost(int[][] cost, int m, int n) { - - int temp[][] = new int[m + 1][n + 1]; - int sum = 0; - for (int i = 0; i <= n; i++) { - temp[0][i] = sum + cost[0][i]; - sum = temp[0][i]; - } - sum = 0; - for (int i = 0; i <= m; i++) { - temp[i][0] = sum + cost[i][0]; - sum = temp[i][0]; - } - - for (int i = 1; i <= m; i++) { - for (int j = 1; j <= n; j++) { - temp[i][j] = cost[i][j] + min(temp[i - 1][j - 1], temp[i - 1][j], temp[i][j - 1]); - } - } - return temp[m][n]; - } - - private int min(int a, int b, int c) { - int l = Math.min(a, b); - return Math.min(l, c); - } - - public static void main(String args[]) { - MinCostPath mcp = new MinCostPath(); - int cost[][] = { { 1, 2, 3 }, { 4, 8, 2 }, { 1, 5, 3 }, { 6, 2, 9 } }; - int result = mcp.minCost(cost, 3, 2); - System.out.println(result); - } -} \ No newline at end of file diff --git a/src/dynamicProgramming/oiknapsack/EqualSubsetSumPartition.java b/src/dynamicProgramming/oiknapsack/EqualSubsetSumPartition.java deleted file mode 100644 index dc26347..0000000 --- a/src/dynamicProgramming/oiknapsack/EqualSubsetSumPartition.java +++ /dev/null @@ -1,76 +0,0 @@ -package dynamicProgramming.oiknapsack; - -import java.util.Arrays; - -/** - * https://www.educative.io/collection/page/5668639101419520/5633779737559040/5752754626625536 - * - * Given a non-empty array containing only positive integers, - * find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal. - * - * Input: [1, 5, 11, 5] - * - * Output: true - * - * Explanation: The array can be partitioned as [1, 5, 5] and [11]. - */ -class EqualSubsetSumPartition { - - -// 0 1 2 3 4 5 -// +---+---+---+---+---+---+ -// {1} | T | T | F | F | F | F | -// +---+---+---+---+---+---+ -// {1,2} | T | T | T | T | F | F | -// +---+---+---+---+---+---+ -// {1,2,3} | T | T | T | T | T | T | -// +---+---+---+---+---+---+ -//{1,2,3,4} | T | T | T | T | T | T | -// +---+---+---+---+---+---+ - public boolean canPartition(int[] num) { - int n = num.length; - - int sum = 0; - for (int i = 0; i < n; i++) - sum += num[i]; - - // if sum is odd we cannot divide into 2 parts - if (sum % 2 != 0) - return false; - - sum /= 2; - - boolean[][] dp = new boolean[n][sum + 1]; - - for (int i = 0; i < n; i++) - dp[i][0] = true; - - // with only one number, we can form a subset only when the required sum is - // equal to its value - for (int s = 1; s <= sum; s++) { - System.out.println(num[0] + "-" + s); - dp[0][s] = (num[0] == s ? true : false); - } - - for (int i = 1; i < n; i++) { - for (int j = 1; j <= sum; j++) { - // if we can get the sum 's' without the number at index 'i' - if (dp[i - 1][j]) { - dp[i][j] = dp[i - 1][j]; - } else if (j >= num[i]) { // else if we can find a subset to get the remaining sum - dp[i][j] = dp[i - 1][j - num[i]]; - } - } - } - - System.out.println(Arrays.deepToString(dp)); - - return dp[n - 1][sum]; - } - - public static void main(String[] args) { - EqualSubsetSumPartition ps = new EqualSubsetSumPartition(); - int[] num = { 2, 3, 4, 5 }; - System.out.println(ps.canPartition(num)); - } -} diff --git a/src/dynamicProgramming/unboundedknapsack/CoinChangingMinimumCoin.java b/src/dynamicProgramming/unboundedknapsack/CoinChangingMinimumCoin.java deleted file mode 100644 index c202ed4..0000000 --- a/src/dynamicProgramming/unboundedknapsack/CoinChangingMinimumCoin.java +++ /dev/null @@ -1,65 +0,0 @@ -package dynamicProgramming.unboundedknapsack; - -import java.util.Arrays; - -/** - * - * - * Time complexity - O(coins.size * total) Space complexity - O(coins.size * - * total) - * - * https://www.youtube.com/watch?v=NJuKJ8sasGk&t=324s - */ -public class CoinChangingMinimumCoin { - - public int minimumCoinBottomUp(int total, int coins[]) { - // where we calculate results - int T[] = new int[total + 1]; - // to extract combination - int R[] = new int[total + 1]; - T[0] = 0; - for (int i = 1; i <= total; i++) { - T[i] = Integer.MAX_VALUE - 1; - R[i] = -1; - } - for (int j = 0; j < coins.length; j++) { - for (int i = 1; i <= total; i++) { - if (i >= coins[j]) { - if (T[i - coins[j]] + 1 < T[i]) { - T[i] = 1 + T[i - coins[j]]; - R[i] = j; - } - } - } - } - System.out.println(Arrays.toString(T)); - System.out.println(Arrays.toString(R)); - printCoinCombination(R, coins); - return T[total]; - } - - private void printCoinCombination(int R[], int coins[]) { - if (R[R.length - 1] == -1) { - System.out.print("No solution is possible"); - return; - } - int start = R.length - 1; - System.out.print("Coins used to form total "); - while (start != 0) { - int j = R[start]; - System.out.print(coins[j] + " "); - start = start - coins[j]; - } - System.out.print("\n"); - } - - public static void main(String args[]) { - int total = 11; - int coins[] = { 1, 5, 6, 8 }; - CoinChangingMinimumCoin cc = new CoinChangingMinimumCoin(); - int bottomUpValue = cc.minimumCoinBottomUp(total, coins); - - System.out.print(bottomUpValue); - - } -} \ No newline at end of file diff --git a/src/dynamicProgramming/unboundedknapsack/CuttingRod.java b/src/dynamicProgramming/unboundedknapsack/CuttingRod.java deleted file mode 100644 index f01377d..0000000 --- a/src/dynamicProgramming/unboundedknapsack/CuttingRod.java +++ /dev/null @@ -1,31 +0,0 @@ -package dynamicProgramming.unboundedknapsack; - -import java.util.Arrays; - -/** - * http://www.geeksforgeeks.org/dynamic-programming-set-13-cutting-a-rod/ - */ -public class CuttingRod { - - public int maxValue(int price[]) { - int[] max = new int[price.length + 1]; // 2-D is not needed beacuse no include exclude is considered - int n = price.length; - // i is no.of.cuts - // price is value - for (int i = 1; i <= n; i++) { // starting at i - for (int j = i; j <= n; j++) { // traverses from i->n every time - System.out.println("max[" + j + "] : " + max[j] + " , max[" + (j - i) + "] : " + max[j - i] - + "+ price[" + (i - 1) + "] : " + price[i - 1]); - max[j] = Math.max(max[j], max[j - i] + price[i - 1]); - System.out.println(Arrays.toString(max)); - } - } - return max[price.length]; - } - - public static void main(String args[]) { - CuttingRod cr = new CuttingRod(); - int[] price = { 1, 5, 3, 6 }; - System.out.println(cr.maxValue(price)); - } -} \ No newline at end of file diff --git a/src/graph/CombinationsAndPermutations/Combinations.java b/src/graph/CombinationsAndPermutations/Combinations.java deleted file mode 100644 index 1210a9c..0000000 --- a/src/graph/CombinationsAndPermutations/Combinations.java +++ /dev/null @@ -1,67 +0,0 @@ -package graph.CombinationsAndPermutations; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class Combinations { - - public List> combinationSum(int[] candidates, int target) { - if(candidates==null || candidates.length==0) return Collections.emptyList(); - List> result= new ArrayList<>(); - - combinationSumUtil(candidates, target, result, new ArrayList<>(), 0); - - return result; - - } - - public void combinationSumUtil(int[] candidates, int target, List> result, List tempList, int start ){ - if(target<0) return; - if(target==0){ - result.add(new ArrayList(tempList)); - - } - - for(int i=start; i> combinationSum2(int[] candidates, int target) { - if(candidates==null || candidates.length==0) return Collections.emptyList(); - List> result= new ArrayList<>(); - Arrays.sort(candidates); - combinationSumUtil1(candidates, target, result, new ArrayList<>(), 0); - - return result; - } - - public void combinationSumUtil1(int[] candidates, int target, List> result, List tempList, int start){ - if(target<0) return; - - if(target==0){ - result.add(new ArrayList<>(tempList)); - return; - } - - for(int i=start; i cur means cand[i - 1] is not added to the path (you should know why if you understand the algorithm), so if cand[i] == cand[i-1], then we shouldn't add cand[i]. -// -// This tricky is very smart. - if(i>start && candidates[i]==candidates[i-1]) continue; - if (target - candidates[i] < 0) break; - tempList.add(candidates[i]); - combinationSumUtil1(candidates, target-candidates[i], result, tempList, i+1); - tempList.remove(tempList.size()-1); - } - } -} diff --git a/src/graph/CombinationsAndPermutations/Permutations.java b/src/graph/CombinationsAndPermutations/Permutations.java deleted file mode 100644 index 15fc1c6..0000000 --- a/src/graph/CombinationsAndPermutations/Permutations.java +++ /dev/null @@ -1,63 +0,0 @@ -package graph.CombinationsAndPermutations; - -import java.util.*; - -public class Permutations { - - public List> permute(int[] nums) { - if(nums==null || nums.length==0) return Collections.emptyList(); - List> result= new ArrayList<>(); - permuteUtils(nums, result, new ArrayList<>()); - - return result; - } - - public void permuteUtils(int[] nums, List> result, List tempList){ - - if(tempList.size()==nums.length){ - result.add(new ArrayList(tempList)); - return; - } - - for(int i=0; i> permuteUnique(int[] nums) { - List> list = new ArrayList<>(); - Arrays.sort(nums); - backtrack(list, new ArrayList<>(), nums, new boolean[nums.length]); - return list; - } - - private void backtrack(List> list, List tempList, int [] nums, boolean [] used){ - if(tempList.size() == nums.length){ - list.add(new ArrayList<>(tempList)); - } else{ - for(int i = 0; i < nums.length; i++){ - //[1, 1, 2][1, 2, 1][2, 1, 1] - //[1, 2, 3][1, 3, 2][2, 1, 3][2, 3, 1][3, 1, 2][3, 2, 1] - if(used[i] || i > 0 && nums[i] == nums[i-1] && !used[i - 1]) continue; - used[i] = true; - tempList.add(nums[i]); - backtrack(list, tempList, nums, used); - used[i] = false; - tempList.remove(tempList.size() - 1); - } - } - } - -} - - diff --git a/src/graph/CombinationsAndPermutations/SubSets.java b/src/graph/CombinationsAndPermutations/SubSets.java deleted file mode 100644 index 52521a7..0000000 --- a/src/graph/CombinationsAndPermutations/SubSets.java +++ /dev/null @@ -1,67 +0,0 @@ -package graph.CombinationsAndPermutations; - -import java.util.*; - -public class SubSets { - - public List> subsets(int[] nums) { - if(nums==null || nums.length==0) return Collections.emptyList(); - - List> result= new ArrayList<>(); - subSetGenerationUtil(nums, result, new ArrayList<>(), 0); - return result; - } - - public void subSetGenerationUtil(int[] nums, List> result, List tempList, int start){ - - result.add(new ArrayList<>(tempList)); - - for(int i=start;i> subsetsWithDup(int[] nums) { - if(nums==null || nums.length==0) return Collections.emptyList(); - - List> result= new ArrayList<>(); - Arrays.sort(nums); - //subsetsWithDupUtil(nums, result, new ArrayList<>(), 0); - dfs(nums,0,result, new ArrayList<>()); - return result; - } - - public void subsetsWithDupUtil(int[] nums, List> result, List tempList, int start){ - result.add(new ArrayList<>(tempList)); - - for(int i=start; istart && nums[i]==nums[i-1]) continue; - tempList.add(nums[i]); - subsetsWithDupUtil(nums, result, tempList, i+1); - tempList.remove(tempList.size()-1); - } - } - - private void dfs(int[] nums, int index, List> res, List curr){ - res.add(new ArrayList<>(curr)); - if(index == nums.length){ - return; - } - Set visited = new HashSet(); - for(int i = index; i < nums.length; i++){ - if(visited.add(nums[i])){ - curr.add(nums[i]); - dfs(nums, i + 1, res, curr); - curr.remove(curr.size() - 1); - } - } - } - - public static void main(String[] args) { - new SubSets().subsetsWithDup(new int[]{1,1,2,4}); - } -} - diff --git a/src/graph/leetcode/CheapestFlightKStops.java b/src/graph/leetcode/CheapestFlightKStops.java deleted file mode 100644 index ed76cc7..0000000 --- a/src/graph/leetcode/CheapestFlightKStops.java +++ /dev/null @@ -1,72 +0,0 @@ -package graph.leetcode; - -import java.util.*; - -public class CheapestFlightKStops { - -// For example consider the following graph. Let source ‘u’ be vertex 0, destination ‘v’ be 3 and k be 2. -// There are two walks of length 2, the walks are {0, 2, 3} and {0, 1, 3}. -// The shortest among the two is {0, 2, 3} and weight of path is 3+6 = 9. - - public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k) { - Map> prices = new HashMap<>(); - for (int[] f : flights) { - if (!prices.containsKey(f[0])) prices.put(f[0], new HashMap<>()); - prices.get(f[0]).put(f[1], f[2]); - } - Queue pq = new PriorityQueue<>((a, b) -> (Integer.compare(a[0], b[0]))); - pq.add(new int[] {0, src, k + 1}); // the reason k+1 is put because the starting point is also considered as a step, refer above comment - while (!pq.isEmpty()) { - int[] top = pq.remove(); - int price = top[0]; - int city = top[1]; - int stops = top[2]; - if (city == dst) return price; - if (stops > 0) { - Map adj = prices.getOrDefault(city, new HashMap<>()); - for (int a : adj.keySet()) { - pq.add(new int[] {price + adj.get(a), a, stops - 1}); - } - } - } - return -1; - } - - public int findCheapestPriceAlter(int n, int[][] flights, int src, int dst, int K) - { - Map> map=new HashMap<>(); - for(int[] f:flights) - { - map.putIfAbsent(f[0],new ArrayList<>()); - map.get(f[0]).add(new int[]{f[1],f[2]}); - } - PriorityQueue q=new PriorityQueue<>(new Comparator() { - @Override - public int compare(int[] o1, int[] o2) { - return Integer.compare(o1[0],o2[0]); - } - }); - q.offer(new int[]{0,src,K+1}); - while(!q.isEmpty()) - { - int[] c=q.poll(); - int cost=c[0]; - int curr=c[1]; - int stop=c[2]; - if(curr==dst) - return cost; - if(stop>0) - { - if(!map.containsKey(curr)) - continue; - for(int[] next:map.get(curr)) - { - q.add(new int[]{cost+next[1],next[0],stop-1}); - } - } - } - return -1; - } - - -} diff --git a/src/graph/leetcode/ConnectCities.java b/src/graph/leetcode/ConnectCities.java deleted file mode 100644 index 184155f..0000000 --- a/src/graph/leetcode/ConnectCities.java +++ /dev/null @@ -1,64 +0,0 @@ -package graph.leetcode; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Input: N = 3, connections = [[1,2,5],[1,3,6],[2,3,1]] - * Output: 6 - * Explanation: - * Choosing any 2 edges will connect all cities so we choose the minimum 2. - */ -public class ConnectCities { - public int solve(int A, ArrayList> B) { - - // greedy-ly we looking from low cost roads to minimise the cost - Collections.sort(B,((a, b)->Integer.compare(a.get(2),b.get(2)))); - - UnionSet us= new UnionSet(A); - int result=0; - for(List row:B){ - if(us.union(row.get(0),row.get(1))) result+=row.get(2); - } - return result; - } - - static class UnionSet{ - int[] parent; - int [] rank; - int count; - public UnionSet(int n){ - this.count=count; - this.parent= new int[n+1]; - this.rank=new int[n+1]; - for(int i=0;i<=n;i++){ - this.parent[i]=i; - this.rank[i]=1; - } - } - - public int find(int n){ - if(parent[n]==n) return n; - parent[n]= find(parent[n]); - return parent[n]; - } - - public boolean union(int x, int y){ - int rootX= find(x); - int rootY= find(y); - if(rootX==rootY) return false; - - if(rank[rootX]rank[rootY]){ - parent[rootY]=rootX; - }else{ - parent[rootY]=rootX; - rank[rootX]++; - } - count--; - return true; - } - } -} diff --git a/src/graph/leetcode/ConnectMissingCities.java b/src/graph/leetcode/ConnectMissingCities.java deleted file mode 100644 index f1ccd19..0000000 --- a/src/graph/leetcode/ConnectMissingCities.java +++ /dev/null @@ -1,54 +0,0 @@ -package graph.leetcode; - -import java.util.Arrays; - -/** - * Input: n = 6, edges = [[1, 4], [4, 5], [2, 3]], newEdges = [[1, 2, 5], [1, 3, 10], [1, 6, 2], [5, 6, 5]] - * Output: 7 - * Explanation: - * There are 3 connected components [1, 4, 5], [2, 3] and [6]. - * We can connect these components into a single component by connecting node 1 to node 2 and node 1 to node 6 at a minimum cost of 5 + 2 = 7. - */ -public class ConnectMissingCities { - - int[] parent; - int component; - - private int find(int v){ - if(parent[v] == v) return v; - return parent[v] = find(parent[v]); - } - - private void connect(int v1, int v2){ - if(find(v1) == find(v2)) return; - int root = find(v1); - while(v2 != parent[v2]){ - int temp = parent[v2]; - parent[v2] = root; - v2 = temp; - } - --component; - parent[v2] = root; - } - - private boolean isConnected(int v1, int v2){ - return find(v1) == find(v2); - } - - public int minCosttoConnectAllNodes(int n, int edges[][], int newEdges[][]){ - parent = new int[n + 1]; component = n; - for(int i = 0; i <= n; ++i) parent[i] = i; - for(int[] edge: edges) connect(edge[0], edge[1]); // same as connectcities - Arrays.sort(newEdges, (a, b) -> (a[2] - b[2])); - int cost = 0; - for(int i = 0; i < newEdges.length; ++i){ - if(!isConnected(newEdges[i][0], newEdges[i][1])){ - connect(newEdges[i][0], newEdges[i][1]); - cost += newEdges[i][2]; - if(component == 1) return cost; - } - } - return -1; - } - -} diff --git a/src/graph/leetcode/CourseSchedule.java b/src/graph/leetcode/CourseSchedule.java deleted file mode 100644 index 5e9a63d..0000000 --- a/src/graph/leetcode/CourseSchedule.java +++ /dev/null @@ -1,115 +0,0 @@ -package graph.leetcode; - -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Queue; -/** - * Input: numCourses = 2, prerequisites = [[1,0]] -Output: true -Explanation: There are a total of 2 courses to take. -To take course 1 you should have finished course 0. So it is possible. - -Input: numCourses = 2, prerequisites = [[1,0],[0,1]] -Output: false -Explanation: There are a total of 2 courses to take. - To take course 1 you should have finished course 0, and to take course 0 you should - also have finished course 1. So it is impossible. - */ -class CourseSchedule { - public boolean canFinish(int numCourses, int[][] prerequisites) { - - Map> map = new HashMap<>(); // Courses that depend on the key - int[] degrees = new int[numCourses]; // # of prerequisites for course i - Queue queue = new ArrayDeque<>(); // Used to find dependants and decrease their outdegree - - for (int[] pre : prerequisites) { - List tempList = map.getOrDefault(pre[1], new ArrayList<>()); - tempList.add(pre[0]); - degrees[pre[0]]++; - map.put(pre[1], tempList); - } - - for (int i = 0; i < degrees.length; i++) { - if (degrees[i] == 0) { - queue.offer(i); - } - } - - int count = 0; - while (!queue.isEmpty()) { - int temp = queue.poll(); - if (degrees[temp] == 0) { - count++; // if cond for duplicates - } - if (!map.containsKey(temp)) { - continue; - } - for (int i : map.get(temp)) { - if (--degrees[i] == 0) { - queue.offer(i); - } - } - } - - return count == numCourses; - } - - public boolean canFinishDFS(int numCourses, int[][] prerequisites) { - // this method basically finds a back-edge between nodes - // backedge is when doing a node(A)'s dfs, it puts A to a temp state - // while traversing A's child, if any of child dosen't have anymore child it's marked as completed - // if there are children it put's the current child to temp state and visits it's children - // so when doing a dfs for a node if it encounters a temp state node rather than completed node - // then that means there's a cycle we cannot complete the course - // (T) A \ - // / / - // (T) B / - // / \ / - // (Co) C D (T) while doing DFS for D's components we encounter A, but A is still in temp state - // - ArrayList[] adjList= new ArrayList[numCourses]; - for(int i=0;i(); - } - for(int[] preReq:prerequisites){ - adjList[preReq[0]].add(preReq[1]); - } - - int[] visited= new int[numCourses]; - for(int i=0;i[] adjList, int[] visited, int vertex){ - if(visited[vertex]==1) return false; - visited[vertex]=1; - for(int adj: adjList[vertex]){ - if(!dfs(adjList, visited, adj)) return false; - } - visited[vertex]=2; - return true; - } - // this is to get the order of course as output - public boolean dfs( List[] adjList, int[] visited, Listresult, int node){ - if(visited[node]==1) return false; - if(visited[node]==2) return true; - - visited[node]=1; - for(int adj: adjList[node]){ - if(!dfs(adjList, visited, result, adj)){ - return false; - } - } - visited[node]=2; - result.add(node); // this will keep track of which to fininsh first and last - return true; - } -} \ No newline at end of file diff --git a/src/graph/leetcode/GraphBiPartite.java b/src/graph/leetcode/GraphBiPartite.java deleted file mode 100644 index d79fe27..0000000 --- a/src/graph/leetcode/GraphBiPartite.java +++ /dev/null @@ -1,53 +0,0 @@ -package graph.leetcode; - -/** - * Recall that a graph is bipartite if we can split it's set of nodes into - * two independent subsets A and B such that every edge in the graph has one node in A and - * another node in B. - * Input: [[1,3], [0,2], [1,3], [0,2]] => 0th node connects to 1,3 .. -Output: true -Explanation: -The graph looks like this: -0----1 -| | -| | -3----2 -We can divide the vertices into two groups: {0, 2} and {1, 3}. -Input: [[1,2,3], [0,2], [0,1,3], [0,2]] -Output: false -Explanation: -The graph looks like this: -0----1 -| \ | -| \ | -3----2 -We cannot find a way to divide the set of nodes into two independent subsets. - */ -public class GraphBiPartite { - public boolean isBipartite(int[][] graph) { - int[] color= new int[graph.length]; - - for(int i=0;i> adjacencyMap = new HashMap<>(); - - PriorityQueue pq = new PriorityQueue<>((a, b) -> Integer.compare(a[1], b[1])); - - for (int[] row : times) { - // creating adjacency list where row[0] is start node, row[1] is destNode and row[2] is distance - List adjList = adjacencyMap.getOrDefault(row[0], new ArrayList<>()); - - adjList.add(new int[]{row[1], row[2]}); - - adjacencyMap.put(row[0], adjList); - } - // general set to keep track of visited nodes - Set visited = new HashSet<>(); - - // K is the node where we have to begin - pq.offer(new int[]{K, 0}); - - // this will track min distance to reach for current node - int[] distance = new int[N + 1]; - Arrays.fill(distance, Integer.MAX_VALUE); - // since we are starting at K, marking it's distance as 0 - distance[K] = 0; - distance[0] = 0; - int max = 0; - while (!pq.isEmpty()) { - int[] value = pq.poll(); - - int node = value[0]; - int distStartNode = value[1]; - - if (!visited.add(node)) continue; - - max = distStartNode; - N--; - if (!adjacencyMap.containsKey(node)) continue; - // going to traverse it's adjacent nodes - for (int[] adjList : adjacencyMap.get(node)) { - - int destNode = adjList[0]; - int distanceToDestination = adjList[1]; - - int newDist = Math.min(distanceToDestination + distStartNode, distance[destNode]); - distance[destNode] = newDist; - - if (!visited.contains(destNode)) { - pq.offer(new int[]{adjList[0], newDist}); - } - } - } - - return N == 0 ? max : -1; - } - -} - diff --git a/src/graph/leetcode/NewRoadsMinimumSpanningTree.java b/src/graph/leetcode/NewRoadsMinimumSpanningTree.java deleted file mode 100644 index 452e482..0000000 --- a/src/graph/leetcode/NewRoadsMinimumSpanningTree.java +++ /dev/null @@ -1,87 +0,0 @@ -package graph.leetcode; - -import java.util.Arrays; -import java.util.PriorityQueue; -import java.util.Queue; - -/** - * Given an undirected graph with n nodes labeled 1..n. Some of the nodes are already connected. - * The i-th edge connects nodes edges[i][0] and edges[i][1] together. Your task is to augment this set of edges with additional edges to connect all the nodes. - * Find the minimum cost to add new edges between the nodes such that all the nodes are accessible from each other. - * Input: n = 6, edges = [[1, 4], [4, 5], [2, 3]], newEdges = [[1, 2, 5], [1, 3, 10], [1, 6, 2], [5, 6, 5]] - * Output: 7 - * Explanation: - * There are 3 connected components [1, 4, 5], [2, 3] and [6]. - * We can connect these components into a single component by connecting node 1 to node 2 and node 1 to node 6 at a minimum cost of 5 + 2 = 7. - */ -public class NewRoadsMinimumSpanningTree { - - public static void main(String[] args) { - int n = 6; - int[][] edges = {{1, 4}, {4, 5}, {2, 3}}; - int[][] newEdges = {{1, 2, 5}, {1, 3, 10}, {1, 6, 2}, {5, 6, 5}}; - System.out.println(minCost(n, edges, newEdges)); - } - - public static int minCost(int n, int[][] edges, int[][] newEdges) { - UF uf = new UF(n + 1); // + 1 because nodes are 1-based - for (int[] edge : edges) { - uf.union(edge[0], edge[1]); - } - - Queue pq = new PriorityQueue<>(newEdges.length, (e1, e2) -> Integer.compare(e1[2], e2[2])); - pq.addAll(Arrays.asList(newEdges)); - - int totalCost = 0; - // 2 because nodes are 1-based and we have 1 unused component at index 0 - while (!pq.isEmpty() && uf.count != 2) { - int[] edge = pq.poll(); - if (!uf.connected(edge[0], edge[1])) { - uf.union(edge[0], edge[1]); - totalCost += edge[2]; - } - } - return totalCost; - } -} - -class UF { - private int[] parent; // parent[i] = parent of i - private byte[] rank; // rank[i] = rank of subtree rooted at i (never more than 31) - public int count; // number of connected components - - public UF(int n) { - if (n < 0) throw new IllegalArgumentException(); - parent = new int[n]; - rank = new byte[n]; - for (int i = 0; i < n; i++) { - parent[i] = i; - } - count = n; - } - - public int find(int p) { - while (p != parent[p]) { - parent[p] = parent[parent[p]]; - p = parent[p]; - } - return p; - } - - public void union(int p, int q) { - int pr = find(p); - int qr = find(q); - if (pr == qr) return; - if (rank[pr] < rank[qr]) { - parent[pr] = qr; - } else { - parent[qr] = pr; - if (rank[pr] == rank[qr]) rank[pr]++; - } - count--; - } - - public boolean connected(int p, int q) { - return find(p) == find(q); - } -} diff --git a/src/graph/leetcode/RedundantConnection.java b/src/graph/leetcode/RedundantConnection.java deleted file mode 100644 index e4b9dd8..0000000 --- a/src/graph/leetcode/RedundantConnection.java +++ /dev/null @@ -1,59 +0,0 @@ -package graph.leetcode; - -/** - * Input: [[1,2], [1,3], [2,3]] - * Output: [2,3] - * Explanation: The given undirected graph will be like this: - * 1 - * / \ - * 2 - 3 - * - * Input: [[1,2], [2,3], [3,4], [1,4], [1,5]] - * Output: [1,4] - * Explanation: The given undirected graph will be like this: - * 5 - 1 - 2 - * | | - * 4 - 3 - */ -public class RedundantConnection { - public int[] findRedundantConnection(int[][] edges) { - DisjointSet set= new DisjointSet(edges.length); - - for(int[]edge: edges){ - if(!set.union(edge[0]-1, edge[1]-1)) return edge; - } - return new int[]{-1,-1}; - } - - static class DisjointSet{ - int[] parent; - int[] rank; - - public DisjointSet(int n){ - this.parent= new int[n]; - this.rank= new int[n]; - } - - public int find(int x){ - if(parent[x]==0) return x; - return parent[x]=find(parent[x]); - } - - public boolean union(int x, int y){ - int rootX= find(x); - int rootY= find(y); - - if(rootX==rootY) return false; - - if(rank[rootX]> snapShots; -List updateTracker; - -public SnapShotUtil(int[] input){ - this.arr= input; - this.sequenceId=0; - snapShots= new HashMap<>(); - updateTracker= new ArrayList<>(); - - } - -public int get(int index){ - if(index>=this.arr.length) return -1; - return this.arr[index]; - } - -public void put(int index, int value){ - if(index>=this.arr.length) return ; - this.updateTracker.add(new Integer[]{index,value}); - this.arr[index]=value; - } - -public int createSnapShot(){ - snapShots.put(++sequenceId, this.updateTracker); - this.updateTracker= new ArrayList<>(); - return sequenceId; - } - -public int get(int snapShotId, int index){ - if(!snapShots.containsKey(snapShotId)) return -1; - - List updates= snapShots.get(snapShotId); - int[] tempArr= this.arr; - - for(Integer[] update: updates){ - tempArr[update[0]]=update[1]; - } - - return tempArr[index]; - } -} - diff --git a/src/linkedLists/FlattenDoublyLinkedList.java b/src/linkedLists/FlattenDoublyLinkedList.java deleted file mode 100644 index fe09757..0000000 --- a/src/linkedLists/FlattenDoublyLinkedList.java +++ /dev/null @@ -1,33 +0,0 @@ -package linkedLists; - -public class FlattenDoublyLinkedList { - - public Node flatten(Node head) { - if(head==null) return head; - - Node root=head; - - while(root!=null){ - - if(root.child==null) { - root=root.next; - continue; - }else{ - Node temp=root.child; - while(temp.next!=null){ - temp=temp.next; - } - temp.next= root.next; - if(root.next!=null) root.next.prev=temp; - root.next=root.child; - root.child.prev=root; - root.child=null; - - } - - } - - return head; - - } -} diff --git a/src/linkedLists/ReverseKBlockNode.java b/src/linkedLists/ReverseKBlockNode.java deleted file mode 100644 index 144bfb9..0000000 --- a/src/linkedLists/ReverseKBlockNode.java +++ /dev/null @@ -1,78 +0,0 @@ -package linkedLists; - -public class ReverseKBlockNode { - - static SinglyLinkedListNode head; - static int k = 3; - - public static void main(String[] args) { - head = new SinglyLinkedListNode(1); - head.next = new SinglyLinkedListNode(2); - head.next.next = new SinglyLinkedListNode(3); - head.next.next.next = new SinglyLinkedListNode(4); - head.next.next.next.next = new SinglyLinkedListNode(5); - head.next.next.next.next.next = new SinglyLinkedListNode(6); - head.next.next.next.next.next.next = new SinglyLinkedListNode(7); - head.next.next.next.next.next.next.next = new SinglyLinkedListNode(8); - head.next.next.next.next.next.next.next.next = new SinglyLinkedListNode(9); - head.next.next.next.next.next.next.next.next.next = new SinglyLinkedListNode(10); - - reverseBlocks(head, null); - print(head); - } - - private static void reverseBlocks(SinglyLinkedListNode temp, SinglyLinkedListNode link) { - - SinglyLinkedListNode current = temp; - SinglyLinkedListNode next = null; - SinglyLinkedListNode prev = null; - int count = 0; - while (current != null && count < k) { - next = current.next; - current.next = prev; - prev = current; - current = next; - count++; - } - if (link != null) { - link.next = prev; - } else { - head = prev; - } - if (current != null) { - reverseBlocks(current, temp); - } - - } - - private static void print(SinglyLinkedListNode current) { - SinglyLinkedListNode node = current; - while (node != null) { - System.out.println(node.data); - node = node.next; - } - } - - public ListNode reverseKNodes(ListNode head, int k){ - if(head==null) return head; - ListNode root= head; - int count=0; - while (count0){ - ListNode next= head.next; - head.next=prev; - prev=head; - head=next; - count--; - - } - - return prev; - } - -} diff --git a/src/linkedLists/RotateList.java b/src/linkedLists/RotateList.java deleted file mode 100644 index 47a2b24..0000000 --- a/src/linkedLists/RotateList.java +++ /dev/null @@ -1,84 +0,0 @@ -package linkedLists; - -import java.util.Collections; -import java.util.PriorityQueue; - -public class RotateList { - public ListNode rotateRight(ListNode head, int k) { - if(k==0 || head==null) return head; - - ListNode tempHead= head; - int length=1; - while(tempHead.next!=null){ - length++; - tempHead=tempHead.next; - } - tempHead.next=head; - // if(k%length==0) return head - k%=length; - for(int i=0;i minQueue= new PriorityQueue<>(); - PriorityQueue maxQueue= new PriorityQueue<>(Collections.reverseOrder()); - - public void offer(int x){ - maxQueue.offer(x); - minQueue.offer(maxQueue.poll()); - if(maxQueue.size() filesInFolder = Files.walk(Paths.get("/Users/vignesh_rajarajan/Documents/learning/Problems/src")) .filter(Files::isRegularFile) .map(Path::toFile) + .filter(file -> !(file.getPath().contains("lld") || + file.getPath().contains("java8") || + file.getPath().contains("reflections") || + file.getPath().contains("multithreading") || + file.getPath().contains("internals"))) .filter(file -> file.getName().contains(".java")) .collect(Collectors.toList()); int rand= (new Random().nextInt(filesInFolder.size())); @@ -23,6 +28,7 @@ public static void main(String[] args) throws IOException { reader.lines().filter(e->e.contains("http") || e.contains("https")).forEach(System.out::println); } - //filesInFolder.forEach(System.out::println); + System.out.println(filesInFolder.size()); } + } diff --git a/src/SQL/AlterTableWithMonthName.sql b/src/main/java/SQL/AlterTableWithMonthName.sql similarity index 100% rename from src/SQL/AlterTableWithMonthName.sql rename to src/main/java/SQL/AlterTableWithMonthName.sql diff --git a/src/SQL/ClassHavingMoreStudents.sql b/src/main/java/SQL/ClassHavingMoreStudents.sql similarity index 100% rename from src/SQL/ClassHavingMoreStudents.sql rename to src/main/java/SQL/ClassHavingMoreStudents.sql diff --git a/src/SQL/CustomersNerverOrders.sql b/src/main/java/SQL/CustomersNerverOrders.sql similarity index 100% rename from src/SQL/CustomersNerverOrders.sql rename to src/main/java/SQL/CustomersNerverOrders.sql diff --git a/src/SQL/DeleteDuplicate.sql b/src/main/java/SQL/DeleteDuplicate.sql similarity index 100% rename from src/SQL/DeleteDuplicate.sql rename to src/main/java/SQL/DeleteDuplicate.sql diff --git a/src/SQL/DepartmentHighestSalary.sql b/src/main/java/SQL/DepartmentHighestSalary.sql similarity index 100% rename from src/SQL/DepartmentHighestSalary.sql rename to src/main/java/SQL/DepartmentHighestSalary.sql diff --git a/src/SQL/DuplicateEmail.sql b/src/main/java/SQL/DuplicateEmail.sql similarity index 100% rename from src/SQL/DuplicateEmail.sql rename to src/main/java/SQL/DuplicateEmail.sql diff --git a/src/SQL/EmployeeEarningHigherThanManagers.sql b/src/main/java/SQL/EmployeeEarningHigherThanManagers.sql similarity index 100% rename from src/SQL/EmployeeEarningHigherThanManagers.sql rename to src/main/java/SQL/EmployeeEarningHigherThanManagers.sql diff --git a/src/SQL/ExchangeSeats.sql b/src/main/java/SQL/ExchangeSeats.sql similarity index 100% rename from src/SQL/ExchangeSeats.sql rename to src/main/java/SQL/ExchangeSeats.sql diff --git a/src/SQL/FirstLoginDate.sql b/src/main/java/SQL/FirstLoginDate.sql similarity index 100% rename from src/SQL/FirstLoginDate.sql rename to src/main/java/SQL/FirstLoginDate.sql diff --git a/src/SQL/ManagerHaving5OrMoreReport.sql b/src/main/java/SQL/ManagerHaving5OrMoreReport.sql similarity index 100% rename from src/SQL/ManagerHaving5OrMoreReport.sql rename to src/main/java/SQL/ManagerHaving5OrMoreReport.sql diff --git a/src/SQL/NthHighestSalary.sql b/src/main/java/SQL/NthHighestSalary.sql similarity index 100% rename from src/SQL/NthHighestSalary.sql rename to src/main/java/SQL/NthHighestSalary.sql diff --git a/src/SQL/RisingTemperature.sql b/src/main/java/SQL/RisingTemperature.sql similarity index 100% rename from src/SQL/RisingTemperature.sql rename to src/main/java/SQL/RisingTemperature.sql diff --git a/src/SQL/SubjectRanks.sql b/src/main/java/SQL/SubjectRanks.sql similarity index 100% rename from src/SQL/SubjectRanks.sql rename to src/main/java/SQL/SubjectRanks.sql diff --git a/src/SQL/TeamSize.sql b/src/main/java/SQL/TeamSize.sql similarity index 100% rename from src/SQL/TeamSize.sql rename to src/main/java/SQL/TeamSize.sql diff --git a/src/SQL/Top3Salaries.sql b/src/main/java/SQL/Top3Salaries.sql similarity index 100% rename from src/SQL/Top3Salaries.sql rename to src/main/java/SQL/Top3Salaries.sql diff --git a/src/SQL/Top3SalaryDepartmentWise.sql b/src/main/java/SQL/Top3SalaryDepartmentWise.sql similarity index 100% rename from src/SQL/Top3SalaryDepartmentWise.sql rename to src/main/java/SQL/Top3SalaryDepartmentWise.sql diff --git a/src/main/java/SQL/TopKthSalary.sql b/src/main/java/SQL/TopKthSalary.sql new file mode 100644 index 0000000..0f3fe91 --- /dev/null +++ b/src/main/java/SQL/TopKthSalary.sql @@ -0,0 +1,5 @@ +SELECT IFNULL((SELECT DISTINCT Salary + FROM Employee + ORDER BY Salary DESC + LIMIT 1,N-1),NULL) AS NthHighestSalary + diff --git a/src/SQL/WinningCandidate.sql b/src/main/java/SQL/WinningCandidate.sql similarity index 100% rename from src/SQL/WinningCandidate.sql rename to src/main/java/SQL/WinningCandidate.sql diff --git a/src/binarysearch/BinarySearchTemplate.java b/src/main/java/binarysearch/BinarySearchTemplate.java similarity index 100% rename from src/binarysearch/BinarySearchTemplate.java rename to src/main/java/binarysearch/BinarySearchTemplate.java diff --git a/src/practiceproblems/BoatsToSave.java b/src/main/java/binarysearch/BoatsToSave.java similarity index 69% rename from src/practiceproblems/BoatsToSave.java rename to src/main/java/binarysearch/BoatsToSave.java index 58c1e93..fa5a759 100644 --- a/src/practiceproblems/BoatsToSave.java +++ b/src/main/java/binarysearch/BoatsToSave.java @@ -1,4 +1,4 @@ -package practiceproblems; +package binarysearch; import java.util.Arrays; @@ -12,25 +12,25 @@ */ class BoatsToSave { public int numRescueBoats(int[] people, int limit) { - if(people.length==0 || limit==0) return 0; - + if (people.length == 0 || limit == 0) return 0; + Arrays.sort(people); - - int i=0; - int j=people.length-1; - int res=0; - while(i<=j){ - if(people[i]+people[j]<=limit){ - res++; + + int i = 0; + int j = people.length - 1; + int res = 0; + while (i <= j) { + if (people[i] + people[j] <= limit) { + res++; i++; j--; - }else{ + } else { res++; j--;// neglecting people with more weight } - + } - + return res; } } \ No newline at end of file diff --git a/src/binarysearch/FindMinimumInRotatedArray.java b/src/main/java/binarysearch/FindMinimumInRotatedArray.java similarity index 100% rename from src/binarysearch/FindMinimumInRotatedArray.java rename to src/main/java/binarysearch/FindMinimumInRotatedArray.java diff --git a/src/main/java/binarysearch/FindPeakElement.java b/src/main/java/binarysearch/FindPeakElement.java new file mode 100644 index 0000000..0ef027d --- /dev/null +++ b/src/main/java/binarysearch/FindPeakElement.java @@ -0,0 +1,27 @@ +package binarysearch; + +/** + * https://leetcode.com/problems/find-peak-element/ + */ +public class FindPeakElement { + public int findPeakElement(int[] nums) { + int left = 0; + int right = nums.length - 1; + + while (left <= right) { + int mid = (left + right) / 2; + // if the mid element is the peak + if ((mid == 0 || nums[mid - 1] < nums[mid]) && (mid == nums.length - 1 || nums[mid + 1] < nums[mid])) { + return mid; + } + // if the mid element is in middle of increasing sub-arr we move towards the peak of increasing sub-arr + // mid==0 is for edge case [1,2] + else if (mid == 0 || nums[mid - 1] < nums[mid] && nums[mid + 1] > nums[mid]) { + left = mid + 1; + } else { // else we move back + right = mid - 1; + } + } + return -1; + } +} diff --git a/src/binarysearch/FindSmallestDivisor.java b/src/main/java/binarysearch/FindSmallestDivisor.java similarity index 100% rename from src/binarysearch/FindSmallestDivisor.java rename to src/main/java/binarysearch/FindSmallestDivisor.java diff --git a/src/binarysearch/FirstAndLastOccurence.java b/src/main/java/binarysearch/FirstAndLastOccurence.java similarity index 100% rename from src/binarysearch/FirstAndLastOccurence.java rename to src/main/java/binarysearch/FirstAndLastOccurence.java diff --git a/src/binarysearch/FirstBadVersion.java b/src/main/java/binarysearch/FirstBadVersion.java similarity index 100% rename from src/binarysearch/FirstBadVersion.java rename to src/main/java/binarysearch/FirstBadVersion.java diff --git a/src/main/java/binarysearch/KClosestElements.java b/src/main/java/binarysearch/KClosestElements.java new file mode 100644 index 0000000..3326822 --- /dev/null +++ b/src/main/java/binarysearch/KClosestElements.java @@ -0,0 +1,113 @@ +package binarysearch; + +import java.util.ArrayList; +import java.util.List; + +/** + * https://leetcode.com/problems/find-k-closest-elements/ + * Revise + */ +public class KClosestElements { + /** + * Now let's see how x - arr[mid] > arr[mid + k] - x works: + * Say this array is sorted from small to large: [x1, arr[mid], x2, arr[mid + k], x3] + * + * Case x1: + * x1 is smaller than both arr[mid] and arr[mid + k]. We should recurse into the left. + * x - arr[mid] is negative and arr[mid + k] - x is positive. + * The condition is false and we recurse to left. + * + * Case x2: + * x2 is in between arr[mid] and arr[mid + k]. We should recurse to the side that is closer to x. + * x - arr[mid] and arr[mid + k] - x are both positive. + * The comparison works the same as using abs(); we recursive to the closer side. + * (When in the case of arr[mid] == arr[mid + k], the condition is false and we recurse to the left.) + * + * Case x3: + * x3 is larger than both arr[mid] and arr[mid + k]. We should recurse into the right. + * x - arr[mid] is positive and arr[mid + k] - x is negative. + * The condition is true and we recurse to right. + * Now the previously failed corner case arr[mid] == arr[mid + k] < x3 doesn't cause a problem anymore + * because the positivity of the numbers we're comparing is still the same. + */ + public List findClosestElements(int[] arr, int k, int x) { + // Initialize binary search bounds + // we need to find the left most element which will be the start of the result set + int left = 0; + // the farthest it can go is array-k + int right = arr.length - k; // else the mid+k will go out of bound + + // Binary search against the criteria described + while (left < right) { + int mid = (left + right) / 2; + // If the element at arr[mid] is closer to x than arr[mid + k], + // then that means arr[mid + k], as well as every element to the right of it can never be in the answer. + // This means we should move our right pointer to avoid considering them + if (x - arr[mid] > arr[mid + k] - x) { + left = mid + 1; + } else { + right = mid; + } + } + + // Create output in correct format + List result = new ArrayList<>(); + for (int i = left; i < left + k; i++) { + result.add(arr[i]); + } + + return result; + } + + public List findClosestElementsIntuitive(int[] arr, int k, int x) { + int left = 0, right = arr.length - 1, mid; + List res = new ArrayList<>(); + + while (left < right) { + mid = (left + right) / 2; + if (arr[mid] >= x) { + right = mid; + } else { + left = mid + 1; + } + } + int leftPointer = left - 1; + int rightPointer = left; + + while (rightPointer - leftPointer <= k) { + if (leftPointer < 0) { + rightPointer += 1; + continue; + } + if (rightPointer == arr.length || Math.abs(arr[leftPointer] - x) <= Math.abs(arr[rightPointer] - x)) { + leftPointer -= 1; + } else { + rightPointer += 1; + } + } + + for (int i = leftPointer + 1; i < rightPointer; i++) { + res.add(arr[i]); + } + + return res; + } + + public List findClosestElementsTwoPointers(int[] arr, int k, int x) { + int lo = 0; + int hi = arr.length - 1; + while (hi - lo >= k) { + if (Math.abs(arr[lo] - x) > Math.abs(arr[hi] - x)) { + lo++; + } else { + hi--; + } + } + List result = new ArrayList<>(k); + for (int i = lo; i <= hi; i++) { + result.add(arr[i]); + } + return result; + } + +} \ No newline at end of file diff --git a/src/binarysearch/KokoEatingBananas.java b/src/main/java/binarysearch/KokoEatingBananas.java similarity index 100% rename from src/binarysearch/KokoEatingBananas.java rename to src/main/java/binarysearch/KokoEatingBananas.java diff --git a/src/binarysearch/KthSmallestInMultiplicationTable.java b/src/main/java/binarysearch/KthSmallestInMultiplicationTable.java similarity index 100% rename from src/binarysearch/KthSmallestInMultiplicationTable.java rename to src/main/java/binarysearch/KthSmallestInMultiplicationTable.java diff --git a/src/main/java/binarysearch/MagneticForceBetweenTwoBalls.java b/src/main/java/binarysearch/MagneticForceBetweenTwoBalls.java new file mode 100644 index 0000000..6d0f993 --- /dev/null +++ b/src/main/java/binarysearch/MagneticForceBetweenTwoBalls.java @@ -0,0 +1,65 @@ +package binarysearch; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/magnetic-force-between-two-balls/ + * + * Revise + */ +public class MagneticForceBetweenTwoBalls { + + /** + * - First, might as well consider the placements in sorted order. + * - We only really need to check the forces of balls immediately to their left and right. + * - Say our target is D. We want all balls to be at least D units apart. + * - We can check if D is doable, by trying a greedy approach. Put the very + * first ball at the first available position, place the next ball at the + * first position rightwards that is sufficiently distant, etc. + *

+ * - We can do a binary search for what minimum distance is achievable. + * - With this we have an O(n*log(L/m)) solution. Where L is the largest distance between + * baskets, and m is the number of balls we're trying to place, n is number of possible positions. + */ + public int maxDistance(int[] position, int m) { + int n = position.length; + Arrays.sort(position); + int left = 0, right = position[n - 1] - position[0]; + while (left < right) { + int mid = right - (right - left) / 2; + if (check( position,mid, m)) + left = mid+1; + else + right = mid; + } + return left; + } + + /** + * Define function count(d) that counts the number of balls can be placed in to baskets, + * under the condition that the minimum distance between any two balls is d. + */ + private boolean check(int[] position, int minimumDistance, int m) { + // Always place first object at position[0] + int lastBallPosition = position[0]; + int ballsLeftToBePlaced = m - 1; // we have placed first ball at 0 position + for (int i = 1; i < position.length && ballsLeftToBePlaced != 0; ) { + /** if minDistance between last position and position at idx is greater than or equal to minDistance + * then place the ball else skip + * */ + if (position[i] - lastBallPosition < minimumDistance) { + // Try to place the next ball, since this ball isn't minimumDistance away from lastBall + i++; + } else { + // Place the ball only if this ball is farther than the previous ball by minimumDistance + lastBallPosition = position[i]; + ballsLeftToBePlaced--; + } + } + return ballsLeftToBePlaced == 0; /*if all balls have been placed then return true else false*/ + } + + public static void main(String[] args) { + new MagneticForceBetweenTwoBalls().maxDistance(new int[]{1, 2, 3, 4, 7}, 3); + } +} diff --git a/src/binarysearch/MaxSoldiers.java b/src/main/java/binarysearch/MaxSoldiers.java similarity index 83% rename from src/binarysearch/MaxSoldiers.java rename to src/main/java/binarysearch/MaxSoldiers.java index aabe091..1e1d0c9 100644 --- a/src/binarysearch/MaxSoldiers.java +++ b/src/main/java/binarysearch/MaxSoldiers.java @@ -1,6 +1,5 @@ package binarysearch; -import java.util.Objects; import java.util.PriorityQueue; /** @@ -19,7 +18,9 @@ static class Pair { public int[] kWeakestRows(int[][] mat, int k) { int[] result = new int[k]; - PriorityQueue> queue = new PriorityQueue<>((a, b) -> a.soldiers.equals(b.soldiers) ? Integer.compare(a.row, b.row) : Integer.compare(a.soldiers, b.soldiers)); + PriorityQueue> queue = new PriorityQueue<>( + (a, b) -> a.soldiers.equals(b.soldiers) ? Integer.compare(a.row, b.row) + : Integer.compare(a.soldiers, b.soldiers)); int i = 0; for (int[] rows : mat) { int temp = binarySearchUtil(rows, 0, rows.length); @@ -28,7 +29,7 @@ public int[] kWeakestRows(int[][] mat, int k) { } int ind = 0; while (ind < k) { - result[ind++] = Objects.requireNonNull(queue.poll()).row; + result[ind++] = queue.poll().row; } return result; diff --git a/src/binarysearch/NumberOfDaysToMakeMBouquets.java b/src/main/java/binarysearch/NumberOfDaysToMakeMBouquets.java similarity index 71% rename from src/binarysearch/NumberOfDaysToMakeMBouquets.java rename to src/main/java/binarysearch/NumberOfDaysToMakeMBouquets.java index 372c8e2..4d52ae0 100644 --- a/src/binarysearch/NumberOfDaysToMakeMBouquets.java +++ b/src/main/java/binarysearch/NumberOfDaysToMakeMBouquets.java @@ -27,17 +27,17 @@ public int minDays(int[] bloomDay, int m, int k) { public boolean isFeasible(int[] bloomDay, int mid, int m, int k){ int bouquets=0; - int adj=0; + int window=0; for(int day:bloomDay){ - if(day>mid){ // if the day is greater then break the window - adj=0; + if(day>mid){ // if the day is greater, then break the window + window=0; }else{ - adj++; // increase the window size - if(adj==k){ // if the window size is equal to K end the window, we get one bouquet and reset the window for next + window++; // increase the window size + if(window==k){ // if the window size is equal to K end the window, we get one bouquet and reset the window for next bouquets++; - adj=0; + window=0; } } } diff --git a/src/binarysearch/SearchElementInSortedAndRotatedArray.java b/src/main/java/binarysearch/SearchElementInSortedAndRotatedArray.java similarity index 50% rename from src/binarysearch/SearchElementInSortedAndRotatedArray.java rename to src/main/java/binarysearch/SearchElementInSortedAndRotatedArray.java index 8531de8..e65aa9c 100644 --- a/src/binarysearch/SearchElementInSortedAndRotatedArray.java +++ b/src/main/java/binarysearch/SearchElementInSortedAndRotatedArray.java @@ -17,32 +17,25 @@ public static void main(String[] args) { } // 4, 5, 0, 1, 2, 3 - int searchI(int[] nums, int target) { - - // If arr[start] <= arr[middle], the numbers from start to middle are sorted in ascending order. - // Else, the numbers from middle+1 to end are sorted in ascending order. - int start = 0; - int end = nums.length - 1; + public int searchI(int[] nums, int target) { + int start = 0, end = nums.length - 1; while (start <= end) { - int mid = (start + end) / 2; - if (nums[mid] == target) { - return mid; - } + int mid = start + (end - start) / 2; + if (nums[mid] == target) return mid; - - if (nums[start] <= nums[mid]) { - if (target < nums[mid] && target >= nums[start]) { + else if (nums[mid] >= nums[start]) { + if (target >= nums[start] && target < nums[mid]) { end = mid - 1; - } else { + } + else { start = mid + 1; } } - - - if (nums[mid] <= nums[end]) { - if (target > nums[mid] && target <= nums[end]) { + else { + if (target <= nums[end] && target > nums[mid]) { start = mid + 1; - } else { + } + else { end = mid - 1; } } @@ -51,11 +44,18 @@ int searchI(int[] nums, int target) { } // with duplicates + //[2,5,6,0,0,1,2] + // 0 + //duplicates, we know nums[mid] != target, so nums[start] != target //based on current information, + // we can only move left pointer to skip one cell + // thus in the worst case, we would have target: 2, and array like 11111111, + // then the running time would be O(n) + public boolean searchII(int[] nums, int target) { int left = 0, right = nums.length - 1, mid; while (left <= right) { - mid = (left + right) >> 1; + mid = (left + right) / 2; if (nums[mid] == target) return true; // the only difference from the first one, tricky case, just update left and right @@ -73,41 +73,4 @@ public boolean searchII(int[] nums, int target) { return false; } - //[2,5,6,0,0,1,2] - // 0 - //duplicates, we know nums[mid] != target, so nums[start] != target //based on current information, - // we can only move left pointer to skip one cell //thus in the worst case, we would have target: 2, and array like 11111111, - // then //the running time would be O(n) - public boolean searchIIEff(int[] nums, int target) { - - int start = 0; - int end = nums.length - 1; - - while (start <= end) { - int mid = (start + end) / 2; - if (nums[mid] == target) { - return true; - } - - // the only difference from the first one, tricky case, just update start and end - if ((nums[start] == nums[mid]) && (nums[end] == nums[mid])) { - ++start; - --end; - } else if (nums[start] <= nums[mid]) { - if ((nums[start] <= target) && (nums[mid] > target)) { - end = mid - 1; - } else { - start = mid + 1; - } - } else { - if ((nums[mid] < target) && (nums[end] >= target)) { - start = mid + 1; - } else { - end = mid - 1; - } - } - } - return false; - } - } diff --git a/src/binarysearch/SearchInsertPosition.java b/src/main/java/binarysearch/SearchInsertPosition.java similarity index 60% rename from src/binarysearch/SearchInsertPosition.java rename to src/main/java/binarysearch/SearchInsertPosition.java index 0c8d633..0d68572 100644 --- a/src/binarysearch/SearchInsertPosition.java +++ b/src/main/java/binarysearch/SearchInsertPosition.java @@ -2,20 +2,19 @@ /** * https://leetcode.com/problems/search-insert-position/ - * */ public class SearchInsertPosition { public int searchInsert(int[] nums, int target) { - int left=0; + int left = 0; //Also notice that the input target might be larger than all elements in nums and therefore needs to placed at the end of the array. // That's why we should initialize right = len(nums) instead of right = len(nums) - 1. - int right= nums.length; + int right = nums.length; // search space is [0, len] since insert index could be after last element - while(left= target) right=mid; - else left=mid+1; + while (left < right) { + int mid = left + (right - left) / 2; + if (nums[mid] >= target) right = mid; + else left = mid + 1; } return left; diff --git a/src/binarysearch/ShipPackageWithNDays.java b/src/main/java/binarysearch/ShipPackageWithNDays.java similarity index 53% rename from src/binarysearch/ShipPackageWithNDays.java rename to src/main/java/binarysearch/ShipPackageWithNDays.java index 4005986..27887ef 100644 --- a/src/binarysearch/ShipPackageWithNDays.java +++ b/src/main/java/binarysearch/ShipPackageWithNDays.java @@ -3,27 +3,7 @@ import java.util.Arrays; /** - * A conveyor belt has packages that must be shipped from one port to another within D days. - *

- * The ith package on the conveyor belt has a weight of weights[i]. - * Each day, we load the ship with packages on the conveyor belt (in the order given by weights). - * We may not load more weight than the maximum weight capacity of the ship. - *

- * Return the least weight capacity of the ship - * that will result in all the packages on the conveyor belt being shipped within D days. - * - * Input: weights = [1,2,3,4,5,6,7,8,9,10], D = 5 - * Output: 15 - * Explanation: A ship capacity of 15 is the minimum to ship all the packages in 5 days like this: - * 1st day: 1, 2, 3, 4, 5 - * 2nd day: 6, 7 - * 3rd day: 8 - * 4th day: 9 - * 5th day: 10 - * - * Note that the cargo must be shipped in the order given, - * so using a ship of capacity 14 and splitting the packages into parts like - * (2, 3, 4, 5), (1, 6, 7), (8), (9), (10) is not allowed. + * https://leetcode.com/problems/capacity-to-ship-packages-within-d-days */ public class ShipPackageWithNDays { public static int shipWithinDays(int[] weights, int D) { @@ -46,8 +26,8 @@ public static int shipWithinDays(int[] weights, int D) { public static int binarySearchUtil(int[] weights, int mid) { - int sum = 0; - int currentDay = 1; + int sum = 0; // weight of current ship + int currentDay = 1; // number of days estimated for (int weight : weights) { if (sum + weight > mid) { currentDay += 1; @@ -55,6 +35,12 @@ public static int binarySearchUtil(int[] weights, int mid) { } sum += weight; + + // currentWeight += weight + //if (currentWeight > estimatedCapacity) { + // estimatedDays += 1 // current weight on the ship over estimated capacity so we need one more day + // currentWeight = weight // move the latest over weighted package to the ship on the following day + // } } return currentDay; diff --git a/src/main/java/binarysearch/SingleElementInSortedArray.java b/src/main/java/binarysearch/SingleElementInSortedArray.java new file mode 100644 index 0000000..dc2b404 --- /dev/null +++ b/src/main/java/binarysearch/SingleElementInSortedArray.java @@ -0,0 +1,118 @@ +package binarysearch; + +/** + * https://leetcode.com/problems/single-element-in-a-sorted-array + * + * You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once. + * Find this single element that appears only once. + */ +public class SingleElementInSortedArray { + + /** + * The single element is at the first even index not followed by its pair. We used this property in the linear search algorithm, + * where we iterated over all the even indexes until we encountered the first one not followed by its pair. + * + * for (int i = 0; i < nums.length - 1; i+=2) { + * if (nums[i] != nums[i + 1]) { + * return nums[i]; + * } + * } + * + * After the single element, the pattern changes to being odd indexes followed by their pair. + * This means that the single element (an even index) and all elements after it are even indexes not followed by their pair. + * Therefore, given any even index in the array, we can easily determine whether the single element is to the left or to the right. + * + * + * @param nums + * @return + */ + public int singleNonDuplicateElegant(int[] nums) { + int lo = 0; + int hi = nums.length - 1; + while (lo < hi) { + int mid = lo + (hi - lo) / 2; + + //We need to make sure our mid index is even. + // We can do this by dividing lo and hi in the usual way, but then decrementing it by 1 if it is odd. + // This also ensures that if we have an even number of even indexes to search, + // that we are getting the lower middle (incrementing by 1 here would not work, + // it'd lead to an infinite loop as the search space would not be reduced in some cases). + if (mid % 2 == 1) mid--; + + //Then we check whether the mid-index is the same as the one after it. + //If it is, then we know that mid is not the single element, and that the single element must be at an even index after mid. + //Therefore, we set lo to be mid + 2. It is +2 rather than the usual +1 because we want it to point at an even index. + if (nums[mid] == nums[mid + 1]) { + lo = mid + 2; + } else { + //If it is not, then we know that the single element is either at mid, or at some index before mid. + // Therefore, we set hi to be mid. + hi = mid; + } + } + return nums[lo]; + } + + + + /** + * The key observation to make is that the starting array must always have an odd number of elements (be odd-lengthed), + * because it has one element appearing once, and all the other elements appearing twice. + * [1,1,4,4,5,5,6,6,8,9,9] + * Here is what happens when we remove a pair(5,5) from the center. We are left with a left subarray and a right subarray. + * [1,1,4,4]**[6,6,8,9,9] + *

+ * Like the original array, the subarray containing the single element must be odd-length-ed. + * The subarray not containing it must be even-length-ed. + * So by taking a pair out of the middle and then calculating which side is now odd-length-ed, + * we have the information needed for binary search. + * + * @param nums + * @return + */ + public int singleNonDuplicate(int[] nums) { + if (nums == null || nums.length == 0) return 0; + + int left = 0; + int right = nums.length - 1; + + while (left < right) { + int mid = left + (right - left) / 2; + + boolean halvesAreEven = (right - mid) % 2 == 0; + + + if (nums[mid] == nums[mid + 1]) { + //Case 1: Mid’s partner is to the right, and the halves were originally even. + //The right side becomes odd-lengthed because we removed mid's partner from it. + // We need to set left to mid + 2 so that the remaining array is the part above mid's partner. + //[1,1,4,4,$5,$5,6,8,8] $=removed item + if (halvesAreEven) { + left = mid + 2; + } else { + //Case 2: Mid’s partner is to the right, and the halves were originally odd. + //The left side remains odd-lengthed. We need to set hi to mid - 1 so that the remaining array is the part below mid. + //[1,1,4,5,5,$6,$6,8,8,9,9] $=removed item + right = mid - 1; + } + } else if (nums[mid] == nums[mid - 1]) { + //Case 3: Mid’s partner is to the left, and the halves were originally even. + //The left side becomes odd-lengthed because we removed mid's partner from it. + // We need to set hi to mid - 2 so that the remaining array is the part below mid's partner. + //[1,1,4,$5,$5,6,6,8,8] $=removed item + if (halvesAreEven) { + right = mid - 2; + } else { + //Case 4: Mid’s partner is to the left, and the halves were originally odd. + //The right side remains odd-lengthed. We need to set lo to mid + 1 so that the remaining array is the part above mid. + //[1,1,4,4,$5,$5,6,6,8,9,9] + left = mid + 1; + } + } else { + return nums[mid]; + } + + } + return nums[left]; + } +} \ No newline at end of file diff --git a/src/main/java/binarysearch/Sqrt.java b/src/main/java/binarysearch/Sqrt.java new file mode 100644 index 0000000..7015716 --- /dev/null +++ b/src/main/java/binarysearch/Sqrt.java @@ -0,0 +1,26 @@ +package binarysearch; + +/** + * https://leetcode.com/problems/sqrtx + */ +public class Sqrt { + + /** + * square root of any number can not be greater than half of the number + * since 3 is a number but sqrt 3 is greater than its half. + */ + public int mySqrt(int x) { + if (x <= 0) return 0; + int left = 1, right = x, res = 1; + while (left < right) { + int mid = (left + right) / 2; + if (mid > x / mid) { + right = mid; + } else { + res = mid; + left = mid + 1; + } + } + return res; + } +} diff --git a/src/binarysearch/SubArraySplitSum.java b/src/main/java/binarysearch/SubArraySplitSum.java similarity index 98% rename from src/binarysearch/SubArraySplitSum.java rename to src/main/java/binarysearch/SubArraySplitSum.java index 9fcb554..803f5b1 100644 --- a/src/binarysearch/SubArraySplitSum.java +++ b/src/main/java/binarysearch/SubArraySplitSum.java @@ -61,7 +61,7 @@ private boolean isFeasible(int[] nums, int limit, int m){ } } - System.out.println("End of isFeasible:: sum is "+ sum + " and partition is "+partition); + System.out.println("End of isFeasible:: sum is "+ sum + " and partition is "+partition+" and m is "+m); return partition<=m; } diff --git a/src/main/java/binarysearch/SumMutatedArrayCloseTarget.java b/src/main/java/binarysearch/SumMutatedArrayCloseTarget.java new file mode 100644 index 0000000..ce37e24 --- /dev/null +++ b/src/main/java/binarysearch/SumMutatedArrayCloseTarget.java @@ -0,0 +1,44 @@ +package binarysearch; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/sum-of-mutated-array-closest-to-target/ + */ +public class SumMutatedArrayCloseTarget { + Integer closest = Integer.MAX_VALUE; + Integer minElem = 0; + + public int findBestValue(int[] arr, int target) { + int left = 0; + int right = Arrays.stream(arr).max().orElse(0) + 1; // +1 is to extend the window slightly to overcome edge cases + + while (left < right) { + int mid = left + (right - left) / 2; + if (isConditionSatisfies(mid, arr, target)) { + right = mid; + } else { + left = mid + 1; + + } + } + + return minElem; + } + + public boolean isConditionSatisfies(int mid, int[] arr, int target) { + int total = 0; + for (int j : arr) { + total += Math.min(j, mid); + + } + if (Math.abs(target - total) < closest) { + closest = Math.abs(target - total); + minElem = mid; + } else if (Math.abs(target - total) == closest) { + minElem = Math.min(minElem, mid); + } + + return total >= target; + } +} diff --git a/src/main/java/combinationsandpermutations/BeautifulArrangements.java b/src/main/java/combinationsandpermutations/BeautifulArrangements.java new file mode 100644 index 0000000..34cb4ea --- /dev/null +++ b/src/main/java/combinationsandpermutations/BeautifulArrangements.java @@ -0,0 +1,26 @@ +package combinationsandpermutations; + +/** + * https://leetcode.com/problems/beautiful-arrangement + */ +public class BeautifulArrangements { + public int countArrangement(int n) { + boolean[] visited = new boolean[n + 1]; + return count(visited, n, n); + } + + private int count(boolean[] visited, int index, int n) { + if (index == 0) { + return 1; + } + int count = 0; + for (int i = 1; i <= n; i++) { + if ((index % i == 0 || i % index == 0) && !visited[i]) { + visited[i] = true; + count += count(visited, index - 1, n); + visited[i] = false; + } + } + return count; + } +} diff --git a/src/main/java/combinationsandpermutations/CanPartitionKSubSets.java b/src/main/java/combinationsandpermutations/CanPartitionKSubSets.java new file mode 100644 index 0000000..8f49efa --- /dev/null +++ b/src/main/java/combinationsandpermutations/CanPartitionKSubSets.java @@ -0,0 +1,37 @@ +package combinationsandpermutations; + +import java.util.Arrays; + +/** + * Tricky TODO revise + * https://leetcode.com/problems/partition-to-k-equal-sum-subsets/ + * + * Ref: http://www.geeksforgeeks.org/partition-set-k-subsets-equal-sum/ + */ +public class CanPartitionKSubSets { + public boolean canPartitionKSubsets(int[] A, int k) { + if (k > A.length) return false; + int sum = 0; + for (int num : A) sum += num; + if (sum % k != 0) return false; + boolean[] visited = new boolean[A.length]; + Arrays.sort(A); + return dfs(A, 0, A.length - 1, visited, sum / k, k); + } + + public boolean dfs(int[] A, int sum, int st, boolean[] visited, int target, int round) { + if (round == 0) return true; + + if (sum == target && dfs(A, 0, A.length - 1, visited, target, round - 1)) + return true; + for (int i = st; i >= 0; --i) { + if (!visited[i] && sum + A[i] <= target) { + visited[i] = true; + if (dfs(A, sum + A[i], i - 1, visited, target, round)) + return true; + visited[i] = false; + } + } + return false; + } +} diff --git a/src/practiceproblems/CombinationIterator.java b/src/main/java/combinationsandpermutations/CombinationIterator.java similarity index 57% rename from src/practiceproblems/CombinationIterator.java rename to src/main/java/combinationsandpermutations/CombinationIterator.java index 6f80177..647c22a 100644 --- a/src/practiceproblems/CombinationIterator.java +++ b/src/main/java/combinationsandpermutations/CombinationIterator.java @@ -1,4 +1,4 @@ -package practiceproblems; +package CombinationsAndPermutations; // CombinationIterator iterator = new CombinationIterator("abc", 2); // creates the iterator. @@ -14,38 +14,39 @@ public class CombinationIterator { Deque deque; boolean[] visited; + public CombinationIterator(String characters, int combinationLength) { - deque= new ArrayDeque<>(); - visited= new boolean[characters.length()]; - generateCombinations(characters,deque, new StringBuilder(), combinationLength, 0); + deque = new ArrayDeque<>(); + visited = new boolean[characters.length()]; + generateCombinations(characters, deque, new StringBuilder(), combinationLength, 0); } - + public String next() { - if(hasNext()) return deque.poll(); - + if (hasNext()) return deque.poll(); + return ""; } - + public boolean hasNext() { return !deque.isEmpty(); } - - public void generateCombinations(String characters, Deque deque,StringBuilder sb, int limit, int start){ - - if(sb.length()==limit){ + + public void generateCombinations(String characters, Deque deque, StringBuilder sb, int limit, int start) { + + if (sb.length() == limit) { deque.offer(sb.toString()); return; } - - for(int i=start; i> combinationSum(int[] candidates, int target) { + if (candidates == null || candidates.length == 0) return Collections.emptyList(); + List> result = new ArrayList<>(); + + combinationSumUtil(candidates, target, result, new ArrayList<>(), 0); + + return result; + + } + + public void combinationSumUtil(int[] candidates, int target, List> result, List tempList, int start) { + if (target < 0) return; + if (target == 0) { + result.add(new ArrayList<>(tempList)); + + } + + for (int i = start; i < candidates.length; i++) { + if (target - candidates[i] < 0) break; + tempList.add(candidates[i]); + // The same repeated number may be chosen from candidates unlimited number of times. + // that's the reason of using i not i+1 + combinationSumUtil(candidates, target - candidates[i], result, tempList, i); + + tempList.remove(tempList.size() - 1); + } + } + + public List> combinationSum2(int[] candidates, int target) { + if (candidates == null || candidates.length == 0) return Collections.emptyList(); + List> result = new ArrayList<>(); + Arrays.sort(candidates); + combinationSumUtil2(candidates, target, result, new ArrayList<>(), 0); + + return result; + } + + public void combinationSumUtil2(int[] candidates, int target, List> result, List tempList, int start) { + if (target < 0) return; + + if (target == 0) { + result.add(new ArrayList<>(tempList)); + return; + } + + for (int i = start; i < candidates.length; i++) { +// when we should skip a number? not just it's the same as previous number, +// but also when it's previous number haven't been added! +// i > cur means cand[i - 1] is not added +// to the path (you should know why if you understand the algorithm), +// so if cand[i] == cand[i-1], then we shouldn't add cand[i]. +// This tricky is very smart. + + /** + * i>start && candidates[i]==candidates[i-1] : + * when input is like 1,1,2,4,7,8 and target is 9 + * the first iteration would run for all combinations starts with 1 ([1,1,7], [1,8]) + * the next number i=1 also starts with one which will run again for all combinations + * candidates[i]==candidates[i-1] this will eliminate the duplicate combinations(another [1,8]) + */ + if (i > start && candidates[i] == candidates[i - 1]) continue; + if (target - candidates[i] < 0) break; + tempList.add(candidates[i]); + combinationSumUtil2(candidates, target - candidates[i], result, tempList, i + 1); + tempList.remove(tempList.size() - 1); + } + } + + public int combinationSum4BottomUp(int[] nums, int target) { + int[] dp = new int[target + 1]; + dp[0] = 1; + + // the difference with coin change is in coin change we see unique combination + // so outer loop is coins i.e we start with coins, but here we care about + // the number of permutations, so we start from target + // if you treat the nums as coins then we have unlimited number of coins + // that's the reason for the change in order + // For e.g. the classic coin change will exclude {2,1,1} after considering {1,1,2} as a solution. + /* + Coin change-2 + for (int coin : coins) { + for (int i = 1; i <= amount; i++) { + if (i >= coin) { + dp[i] += dp[i - coin]; + } + */ + for (int i = 1; i <= target; i++) { + for (int num : nums) { + if (i - num >= 0) dp[i] += dp[i - num]; + } + } + //System.out.println(Arrays.toString(dp)); + return dp[target]; + } + + Integer[] cache; + + public int combinationSum4(int[] nums, int target) { + return recursionHelper(nums, target, 0, new Integer[target + 1]); + } + + private int recursionHelper(int[] nums, int target, int pos, Integer[] cache) { + if (pos == nums.length || target <= 0) { + return (target == 0) ? 1 : 0; + } + + if (cache[target] != null) { + return cache[target]; + } + + int take = recursionHelper(nums, target - nums[pos], 0, cache); + int skip = recursionHelper(nums, target, pos + 1, cache); + + return cache[target] = take + skip; + } +} diff --git a/src/main/java/combinationsandpermutations/FactorCombinations.java b/src/main/java/combinationsandpermutations/FactorCombinations.java new file mode 100644 index 0000000..489681e --- /dev/null +++ b/src/main/java/combinationsandpermutations/FactorCombinations.java @@ -0,0 +1,33 @@ +package combinationsandpermutations; + +import java.util.ArrayList; +import java.util.List; + +/** + * https://leetcode.com/problems/factor-combinations + */ +public class FactorCombinations { + + public List> getFactors(int n) { + List> result = new ArrayList<>(); + helper(result, new ArrayList(), n, 2); + return result; + } + + public void helper(List> result, List item, int n, int start) { + if (n <= 1) { + if (item.size() > 1) { + result.add(new ArrayList<>(item)); + } + return; + } + + for (int i = start; i <= n; ++i) { + if (n % i == 0) { + item.add(i); + helper(result, item, n / i, i); + item.remove(item.size() - 1); + } + } + } +} diff --git a/src/CombinationsAndPermutations/Permutations.java b/src/main/java/combinationsandpermutations/Permutations.java similarity index 51% rename from src/CombinationsAndPermutations/Permutations.java rename to src/main/java/combinationsandpermutations/Permutations.java index bd906b4..37bb265 100644 --- a/src/CombinationsAndPermutations/Permutations.java +++ b/src/main/java/combinationsandpermutations/Permutations.java @@ -1,25 +1,33 @@ package CombinationsAndPermutations; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +/** + * https://leetcode.com/problems/permutations/ + */ public class Permutations { public List> permute(int[] nums) { - if(nums==null || nums.length==0) return Collections.emptyList(); - List> result= new ArrayList<>(); - permuteUtils(nums, result, new ArrayList<>()); + if (nums == null || nums.length == 0) return Collections.emptyList(); + List> result = new ArrayList<>(); + permuteUtils(nums, result, new ArrayList<>(), new HashSet<>()); return result; } - public void permuteUtils(int[] nums, List> result, List tempList){ + public void permuteUtils(int[] nums, List> result, List tempList, Set set) { - if(tempList.size()==nums.length){ - result.add(new ArrayList(tempList)); + if (tempList.size() == nums.length) { + result.add(new ArrayList<>(tempList)); return; } - for(int i=0; i> result, List t // 3 + (permutations of 1, 2, 4) // // 4 + (permutations of 1, 2, 3) - if(tempList.contains(nums[i])) continue; - tempList.add(nums[i]); - permuteUtils(nums, result, tempList); - tempList.remove(tempList.size()-1); + if (set.contains(num)) continue; + tempList.add(num); + set.add(num); + permuteUtils(nums, result, tempList, set); + set.remove(tempList.get(tempList.size() - 1)); + tempList.remove(tempList.size() - 1); } } @@ -41,14 +51,14 @@ public List> permuteUnique(int[] nums) { return list; } - private void backtrack(List> list, List tempList, int [] nums, boolean [] used){ - if(tempList.size() == nums.length){ + private void backtrack(List> list, List tempList, int[] nums, boolean[] used) { + if (tempList.size() == nums.length) { list.add(new ArrayList<>(tempList)); - } else{ - for(int i = 0; i < nums.length; i++){ + } else { + for (int i = 0; i < nums.length; i++) { //[1, 1, 2][1, 2, 1][2, 1, 1] //[1, 2, 3][1, 3, 2][2, 1, 3][2, 3, 1][3, 1, 2][3, 2, 1] - if(used[i] || i > 0 && nums[i] == nums[i-1] && !used[i - 1]) continue; + if (used[i] || i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) continue; used[i] = true; tempList.add(nums[i]); backtrack(list, tempList, nums, used); diff --git a/src/main/java/combinationsandpermutations/SplitUniqueSubstring.java b/src/main/java/combinationsandpermutations/SplitUniqueSubstring.java new file mode 100644 index 0000000..cf4306f --- /dev/null +++ b/src/main/java/combinationsandpermutations/SplitUniqueSubstring.java @@ -0,0 +1,42 @@ +package CombinationsAndPermutations; + +import java.util.HashSet; +import java.util.Set; + +public class SplitUniqueSubstring { + public int maxUniqueSplit(String s) { + int[] result= new int[]{0}; + recursionHelper(s, 0, new HashSet<>(), result); + return result[0]; + } + + /** + * if(start == s.length()) { + * max = Math.max(max, h.size()); + * } + * String res = ""; + * + * for(int i = start;i < s.length();i++) { + * res += s.charAt(i); + * if(h.contains(res)) continue; + * h.add(res); + * backtrack(s, i+1, h); + * h.remove(res); + * } + * } + */ + public void recursionHelper(String s, int index, Set cache, int[] result){ + if(index==s.length()) { + result[0]=Math.max(result[0],cache.size()); + return; + } + + for(int i= index;i + * You can place cuboid i on cuboid j, + * we have + * width[i] <= width[j] and length[i] <= length[j] and height[i] <= height[j]. + *

+ * This condition will hold, after we sort each cuboid length, + * that is, + * small[i] <= small[j] and mid[i] <= mid[j] and big[i] <= big[j]. + */ + public int maxHeight(int[][] cuboids) { + for (int[] cube : cuboids) Arrays.sort(cube); + Arrays.sort(cuboids, (a, b) -> (a[0] + a[1] + a[2]) - (b[0] + b[1] + b[2])); + int N = cuboids.length, res = 0; + int[] dp = new int[N]; + for (int i = 0; i < N; i++) { + dp[i] = cuboids[i][2]; + res = Math.max(res, dp[i]); + } + for (int i = 1; i < N; i++) + for (int j = 0; j < i; j++) + if (cuboids[j][0] <= cuboids[i][0] && + cuboids[j][1] <= cuboids[i][1] && + cuboids[j][2] <= cuboids[i][2]) { + dp[i] = Math.max(dp[i], dp[j] + cuboids[i][2]); + res = Math.max(res, dp[i]); + } + return res; + } + public int maxHeight(Dimension[] input) { Dimension[] allRotationInput = new Dimension[input.length * 3]; createAllRotation(input, allRotationInput); @@ -51,9 +83,9 @@ public int maxHeight(Dimension[] input) { } int max = Integer.MIN_VALUE; - for (int i = 0; i < T.length; i++) { - if (T[i] > max) { - max = T[i]; + for (int j : T) { + if (j > max) { + max = j; } } @@ -72,51 +104,52 @@ private void createAllRotation(Dimension[] input, Dimension[] allRotationInput) public static void main(String args[]) { BoxStacking bs = new BoxStacking(); - Dimension[] input = { new Dimension(3, 2, 5), new Dimension(1, 2, 4) }; + Dimension[] input = {new Dimension(3, 2, 5), new Dimension(1, 2, 4)}; int maxHeight = bs.maxHeight(input); System.out.println("Max height is " + maxHeight); assert 11 == maxHeight; } -} -class Dimension implements Comparable { - int height; - int length; - int width; - Dimension(int height, int length, int width) { - this.height = height; - this.length = length; - this.width = width; - } + static class Dimension implements Comparable { + int height; + int length; + int width; - Dimension() { - } + Dimension(int height, int length, int width) { + this.height = height; + this.length = length; + this.width = width; + } - static Dimension createDimension(int height, int side1, int side2) { - Dimension d = new Dimension(); - d.height = height; - if (side1 >= side2) { - d.length = side1; - d.width = side2; - } else { - d.length = side2; - d.width = side1; + Dimension() { } - return d; - } - @Override - public int compareTo(Dimension d) { - if (this.length * this.width >= d.length * d.width) { - return 1; - } else { - return -1; + static Dimension createDimension(int height, int side1, int side2) { + Dimension d = new Dimension(); + d.height = height; + if (side1 >= side2) { + d.length = side1; + d.width = side2; + } else { + d.length = side2; + d.width = side1; + } + return d; } - } - @Override - public String toString() { - return "Dimension [height=" + height + ", length=" + length + ", width=" + width + "]"; + @Override + public int compareTo(Dimension d) { + if (this.length * this.width >= d.length * d.width) { + return 1; + } else { + return -1; + } + } + + @Override + public String toString() { + return "Dimension [height=" + height + ", length=" + length + ", width=" + width + "]"; + } } } \ No newline at end of file diff --git a/src/main/java/dynamicProgramming/CatalanNumberBinarySearchTree.java b/src/main/java/dynamicProgramming/CatalanNumberBinarySearchTree.java new file mode 100644 index 0000000..f439f1a --- /dev/null +++ b/src/main/java/dynamicProgramming/CatalanNumberBinarySearchTree.java @@ -0,0 +1,81 @@ +package dynamicProgramming; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * https://www.youtube.com/watch?v=0pTN0qzpt-Y + */ +public class CatalanNumberBinarySearchTree { + public int countTrees(int n) { + int[] T = new int[n + 1]; + T[0] = 1; + T[1] = 1; + for (int i = 2; i <= n; i++) { + for (int j = 0; j < i; j++) { + int i1 = T[j] * T[i - j - 1]; + System.out.println("T[" + j + "]" + "*" + "T[" + (i - j - 1) + "] :: " + i1); + T[i] += i1; + } + } + return T[n]; + } + + Integer[] cache = new Integer[20]; + + public int numTrees(int n) { + if (n < 0) return 0; + if (n == 0) return 1; + if (n == 1) return 1; + int result = 0; + if (cache[n] != null) return cache[n]; + for (int k = 1; k <= n; k++) { + result += numTrees(k - 1) * numTrees(n - k); + } + return cache[n] = result; + } + + /** + * Given a sequence 1…n, to construct a Binary Search Tree (BST) out of the sequence, + * we could enumerate each number i in the sequence, and use the number as the root, + * naturally, the subsequence 1…(i-1) on its left side would lay on the left branch of the root, + * and similarly the right subsequence (i+1)…n lay on the right branch of the root. + * We then can construct the subtree from the subsequence recursively. + * Through the above approach, we could ensure that the BST that we construct are all unique, + * since they have unique roots. + * + * G(n) = F(1, n) + F(2, n) + ... + F(n, n). + * + * For example, F(3, 7): the number of unique BST tree with number 3 as its root. + * To construct an unique BST out of the entire sequence [1, 2, 3, 4, 5, 6, 7] with 3 as the root, + * which is to say, we need to construct an unique BST out of its left subsequence [1, 2] + * and another BST out of the right subsequence [4, 5, 6, 7], and then combine them together (i.e. cartesian product). + * The tricky part is that we could consider the number of unique BST out of sequence [1,2] as G(2), + * and the number of of unique BST out of sequence [4, 5, 6, 7] as G(4). Therefore, F(3,7) = G(2) * G(4). + * + * F(i, n) = G(i-1) * G(n-i) 1 <= i <= n + * @param n + * @return + */ + public int numTreesBottomUp(int n) { + if (n < 0) return 0; + int[] cache = new int[20]; + cache[0] = 1; + cache[1] = 1; + for (int i = 2; i <= n; i++) { + for (int j = 1; j <= i; j++) { + System.out.println(j - 1+" : "+(i - j)); + cache[i] += cache[j - 1] * cache[i - j]; + } + } + return cache[n]; + } + + public static void main(String[] args) { + CatalanNumberBinarySearchTree cnt = new CatalanNumberBinarySearchTree(); + System.out.println(); + System.out.println(cnt.numTreesBottomUp(5)); + } + +} diff --git a/src/dynamicProgramming/EggDropping.java b/src/main/java/dynamicProgramming/EggDropping.java similarity index 100% rename from src/dynamicProgramming/EggDropping.java rename to src/main/java/dynamicProgramming/EggDropping.java diff --git a/src/main/java/dynamicProgramming/KnightDialer.java b/src/main/java/dynamicProgramming/KnightDialer.java new file mode 100644 index 0000000..d6e8332 --- /dev/null +++ b/src/main/java/dynamicProgramming/KnightDialer.java @@ -0,0 +1,73 @@ +package dynamicProgramming; + +import java.util.HashMap; +import java.util.Map; + +/** + * https://leetcode.com/problems/knight-dialer/ + */ +public class KnightDialer { + int[][] pos = new int[][]{{2, -1}, {2, 1}, {1, -2}, {1, 2}, {-1, 2}, {-1, -2}, {-2, -1}, {-2, 1}}; + int max = (int) Math.pow(10, 9) + 7; + Map cache = new HashMap<>(); + + public int knightDialer(int n) { + long s = 0; + //do n hops from every i, j index (the very requirement of the problem) + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + s = (s + recursionHelper(n, i, j)) % max; + } + } + return (int) s; + } + + public int recursionHelper(int n, int i, int j) { + if (i < 0 || j < 0 || i >= 4 || j >= 3 || (i == 3 && j != 1)) return 0; + + if (1 == n) return 1; + String key = i + "" + j + "" + n; + if (cache.containsKey(key)) return cache.get(key); + + int res = 0; + for (int[] p : pos) { + res += recursionHelper(n - 1, i + p[0], j + p[1]); + res %= max; + } + cache.put(key, res); + return cache.get(key); + } + + public static int knightDialerBottomUp(int n) { + int MOD = 1000000007; + int[][] paths = {{4, 6}, {6, 8}, {7, 9}, {4, 8}, {0, 3, 9}, {}, {0, 1, 7}, {2, 6}, {1, 3}, {2, 4}}; // Previous moves of knight-> For instance, if a knight is at 0, it reached from either 4 or 6. Similarly if it is at 1, it is reached from 7 or 9 & so on + int[][] dp = new int[n + 1][10]; // rows -> no of steps taken to reach row i cols-> no of digits + for (int j = 0; j < 10; j++) + dp[1][j] = 1; //populate the base case for n =1 + + for (int i = 2; i <=n ; i++) { // no of steps taken by knight to reach i + for (int j = 0; j < 10; j++) { // no of digits + for (int p : paths[j]) { // Previous move of knight in order to reach digit j + dp[i][j] += dp[i - 1][p]; // cumulatively add from the previous knight move. For instance., F(2, 0) -> F(1,4) + F(1,6) F(2,6) -> F(1,0) + F(1,1) + F(1,7) + } + dp[i][j] %= MOD; + } + } + + for (int i = 0; i <=n ; i++) { // no of steps taken by knight to reach i + for (int j = 0; j < 10; j++) { + System.out.print(dp[i][j] +" "); + } + System.out.println(); + } + + double sum = 0d; + for (int j = 0; j < 10; j++) + sum += dp[n][j]; + return (int) (sum % MOD); + } + + public static void main(String[] args) { + System.out.println(knightDialerBottomUp(3)); + } +} diff --git a/src/main/java/dynamicProgramming/LastStoneWeight.java b/src/main/java/dynamicProgramming/LastStoneWeight.java new file mode 100644 index 0000000..48bdf55 --- /dev/null +++ b/src/main/java/dynamicProgramming/LastStoneWeight.java @@ -0,0 +1,111 @@ +package dynamicProgramming; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * https://leetcode.com/problems/last-stone-weight-ii/ + *

+ * https://www.youtube.com/watch?v=TaZxJt4-FHk + *

+ * For example, we take array [2,3,3,2,5]. We partition it into two sets [2,3,2] and [3,5], with sum 7 and 8 respectively. + * If we have collision with numbers from set 1 with those of set 2, only 7~8=1 will remain. + * so this becomes subset sum with min difference + *

+ * So the problem asks us to accumulate stones such the result is minimum, + * but it really is this problem in disguise, divide the array into two subsets such that their sum is minimum. Why? + * Suppose given array is [1,5,3,2] and you go about solving the problem as given you would take the following steps right? + *

+ * 5 - 3 = 2 + * 2 - 2 = 0 (or) 2 - (5 - 3) + * 1 - 0 = 1 (or) 1 - (2 - (5 - 3)) => sum{1,5} - sum{2,3} + * So do you see why we want the minimum difference between two subsets?(this is just intuition not exact mathematical proof) + */ +public class LastStoneWeight { + static Map cache = new HashMap<>(); + + public static int lastStoneWeightIIRecur(int[] stones) { + + int ans = recursionHelper(stones, 0, 0, 0); + cache.forEach((key, value) -> System.out.print(key + " :: " + value + "")); + return ans; + } + + public static int recursionHelper(int[] stones, int index, int sum1, int sum2) { + if (index == stones.length) { + return Math.abs(sum1 - sum2); + } + String uniqueKey = index+"-"+sum1 + "-" + sum2; + + if (cache.containsKey(uniqueKey)) { + return cache.get(uniqueKey); + } + int leftPath = recursionHelper(stones, index + 1, sum1 + stones[index], sum2); + int rightPath = recursionHelper(stones, index + 1, sum1, sum2 + stones[index]); + + cache.put(uniqueKey, Math.min(leftPath, rightPath)); + return cache.get(uniqueKey); + + } + + public static void main(String[] args) { + lastStoneWeightII2D(new int[]{31,26,33,21,40}); + } + + public static int lastStoneWeightII(int[] stones) { + + int total = 0; + for (int stone : stones) total += stone; + int S2 = 0; + int target = total/2; + boolean[] dp = new boolean[target + 1]; // use only 1D array to store the status + dp[0] = true; + for (int s : stones) { + boolean[] cur = dp.clone(); + for (int i = s; i <= target; i++) { // wont affect the value that is smaller than current stone's weight + if (dp[i - s]) { // checks if the subset sum is there if i=9 and s=7 at 9th pos true entry + // will be present because the 9-7=2 is there, like wise it checks for all combinations + cur[i] = true; + S2 = Math.max(S2, i); + } + } + dp = cur; + } + return total - 2 * S2; + } + public static int lastStoneWeightII2D(int[] stones) { + int n = stones.length, sum = 0; + for (int s : stones) sum += s; + int target = sum/2; + + int[][] dp = new int[n + 1][target + 1]; + for (int i = 1; i <= n; i++) { + int currStone = stones[i-1]; + for (int j = 0; j <= target; j++) { + if (j >= currStone) { + dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - currStone] + currStone); + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + + System.out.println("Sum is :: "+sum); + for(int []d:dp){ + System.out.println(Arrays.toString(d)); + } + System.out.println(sum +" - "+ 2 * dp[n][target]); + + /** dp[n][target] -> this is closest we can partition to sum/2 + * //notice that in general I can say that + * //answer = S1-S2 + * //where S1 is sum of some numbers and S2 is sum of rest of numbers + * //also note that S1+S2 = SUM (sum of all numbers) + * //S1 >= S2 because negative answer is not possible + * //now we have to minimise answer + * //answer = (SUM-S2)-S2 = > SUM-2*S2 (Just substituting S1 by SUM-S2) + */ + return sum - 2 * dp[n][target]; + } +} diff --git a/src/main/java/dynamicProgramming/MakeArrayStrictlyIncreasing.java b/src/main/java/dynamicProgramming/MakeArrayStrictlyIncreasing.java new file mode 100644 index 0000000..03a7769 --- /dev/null +++ b/src/main/java/dynamicProgramming/MakeArrayStrictlyIncreasing.java @@ -0,0 +1,32 @@ +package dynamicProgramming; + +/** + * https://leetcode.com/problems/remove-one-element-to-make-the-array-strictly-increasing + */ +public class MakeArrayStrictlyIncreasing { + public boolean canBeIncreasing(int[] nums) { + int numberOfDeletionsNeededToMakeStrictlyIncreasing = 0; + for (int i = 1; i < nums.length; i++) { + if (nums[i - 1] >= nums[i]) { + + int iMinusTwoValue = i - 2 < 0 ? Integer.MIN_VALUE : nums[i - 2]; + int iPlusOneValue = i + 1 == nums.length ? Integer.MAX_VALUE : nums[i + 1]; + + //[1,2,10,5,7] + //[2,3,1,2] -- false + //[1,1,1] -- false + //[100,21,100] + //[1,2,3] + //[105,924,32,968] + if ((nums[i] > iMinusTwoValue && nums[i] < iPlusOneValue) || + (nums[i - 1] > iMinusTwoValue && nums[i - 1] < iPlusOneValue)) { + ++numberOfDeletionsNeededToMakeStrictlyIncreasing; + } else { + return false; // found an unfixable non-increase + } + + } + } + return numberOfDeletionsNeededToMakeStrictlyIncreasing <= 1; + } +} diff --git a/src/main/java/dynamicProgramming/MaxGoldAMinerCanGet.java b/src/main/java/dynamicProgramming/MaxGoldAMinerCanGet.java new file mode 100644 index 0000000..9948d0c --- /dev/null +++ b/src/main/java/dynamicProgramming/MaxGoldAMinerCanGet.java @@ -0,0 +1,48 @@ +package dynamicProgramming; + +import java.util.Arrays; + +/** + * Freshworks interview question: + * Miner can start at any of the i,j in first column + * miner can move in right, right upper diagonal and right lower diagonal + */ +public class MaxGoldAMinerCanGet { + + public static int getMaxGoldMinerCanGet(int[][] matrix) { + if (matrix.length == 0) return 0; + + int m = matrix.length; + int n = matrix[0].length; + int result = -1; + for (int j = 1; j < n; j++) { + for (int i = 0; i < m; i++) { + int left = matrix[i][j - 1]; + int leftUpperDiagonal = i - 1 >= 0 ? matrix[i - 1][j - 1] : 0; + int leftLowerDiagonal = i + 1 < m ? matrix[i + 1][j - 1] : 0; + + matrix[i][j] = Math.max(left, Math.max(leftUpperDiagonal, leftLowerDiagonal)) + matrix[i][j]; + result = Math.max(result, matrix[i][j]); + } + } + + for (int[] ints : matrix) { + System.out.println(Arrays.toString(ints)); + } + + return result; + + } + + public static void main(String[] args) { + System.out.println(getMaxGoldMinerCanGet(new int[][]{{1, 3, 1, 5}, + {2, 2, 4, 1}, + {5, 0, 2, 3}, + {0, 6, 1, 2}} + )); + System.out.println(getMaxGoldMinerCanGet(new int[][]{{1, 3, 3}, + {2, 1, 4}, + {0, 6, 4}} + )); + } +} diff --git a/src/dynamicProgramming/MaxSumForNonAdjacentElements.java b/src/main/java/dynamicProgramming/MaxSumForNonAdjacentElements.java similarity index 100% rename from src/dynamicProgramming/MaxSumForNonAdjacentElements.java rename to src/main/java/dynamicProgramming/MaxSumForNonAdjacentElements.java diff --git a/src/main/java/dynamicProgramming/MaximumRectangle.java b/src/main/java/dynamicProgramming/MaximumRectangle.java new file mode 100644 index 0000000..b866d13 --- /dev/null +++ b/src/main/java/dynamicProgramming/MaximumRectangle.java @@ -0,0 +1,99 @@ +package dynamicProgramming; + +import practiceproblems.stack.MaxHistogram; + +import java.util.Arrays; + +/** + * At every row the height and area of rectangle varies, if the last row(base) is having a zero value + * then that portion have to be avoided, this is the reason we take maxHistogram after every row + *

+ * matrix + * 0 0 0 1 0 0 0 + * 0 0 1 1 1 0 0 + * 0 1 1 1 1 1 0 + *

+ * height + * 0 0 0 1 0 0 0 + * 0 0 1 2 1 0 0 + * 0 1 2 3 2 1 0 + */ +public class MaximumRectangle { + + public static int maximalRectangle(char[][] matrix) { + if (matrix.length == 0) return 0; + int[] row = new int[matrix[0].length]; + int result = 0; + for (char[] arr : matrix) { + int i = 0; + // for each cell with value=1, we look upward (north), the number of continuous '1' is the height of cell + //First initiate the height array as 1 1 0 1 0 1, which is just a copy of the first row. Then we can easily calculate the max area is 2. + //Then update the array. We scan the second row, when the matrix[1][i] is 0, set the height[i] to 0 + //else height[i] += 1, which means the height has increased by 1. So the height array again becomes 0 2 0 0 1 2. + // The max area now is also 2. + for (char c : arr) { + if (c - '0' > 0) { + row[i] += c - '0'; + } else { + row[i] = 0; + } + + i++; + } + /** The result row for every iteration + * [1, 0, 1, 0, 0] + * [2, 0, 2, 1, 1] + * [3, 1, 3, 2, 2] + * [4, 0, 0, 3, 0] + */ + System.out.println(Arrays.toString(row)); + result = Math.max(result, MaxHistogram.largestRectangleArea(row)); + } + + return result; + } + + public static void main(String[] args) { + maximalRectangle(new char[][]{{'1', '0', '1', '0', '0'}, + {'1', '0', '1', '1', '1'}, + {'1', '1', '1', '1', '1'}, + {'1', '0', '0', '1', '0'}}); + } + + /** + * https://www.youtube.com/watch?v=-FgseNO-6Gk + */ + public int maximalRectangleBruteForce(char[][] matrix) { + int rowLength = matrix.length; + if (rowLength == 0) return 0; + int colLength = matrix[0].length; + if (colLength == 0) return 0; + + int maxA = Integer.MIN_VALUE; + + for (int row = 0; row < rowLength; row++) { + for (int col = 0; col < colLength; col++) { + if (matrix[row][col] == '0') continue; + // consider the rectangle whose upper left corner is at [r, c]: + + int rightMostCol = colLength - 1;// the right most column that we should check, initially it's w-1 + + // iterate from i,j till row and col end + for (int r1 = row; r1 < rowLength; r1++) { + for (int c1 = col; c1 <= rightMostCol; c1++) { + + if (matrix[r1][c1] == '0') { + rightMostCol = c1 - 1; // update the rightMostCol when we encounter '0', no use in proceeding after + break; // go to next row + } + // r1 - row + 1, c1 - col + 1 are rectangle size relative to i,j where the inner loop started + maxA = Math.max(maxA, (r1 - row + 1) * (c1 - col + 1)); // + } + } + } + } + + return Math.max(maxA, 0); + } + +} diff --git a/src/main/java/dynamicProgramming/MinCoinChange.java b/src/main/java/dynamicProgramming/MinCoinChange.java new file mode 100644 index 0000000..dfedffb --- /dev/null +++ b/src/main/java/dynamicProgramming/MinCoinChange.java @@ -0,0 +1,50 @@ +package dynamicProgramming; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/coin-change-2/ + */ +public class MinCoinChange { + + Integer[] cache; + + public int coinChange(int[] coins, int amount) { + cache = new Integer[amount + 1]; + return recursionHelper(amount, coins); + } + + public int recursionHelper(int amount, int[] coins) { + if (amount == 0) return 0; + if (amount < 0) return -1; + + if (cache[amount] != null) return cache[amount]; + + int minCount = Integer.MAX_VALUE; + + for (int coin : coins) { + int count = recursionHelper(amount - coin, coins); + if (count == -1) continue; + minCount = Math.min(minCount, count + 1); + } + + return cache[amount] = minCount == Integer.MAX_VALUE ? -1 : minCount; + + } + + + public int coinChangeBottomUp(int[] coins, int amount) { + Integer[] cache = new Integer[amount + 1]; + Arrays.fill(cache, amount + 1); + cache[0] = 0; + for (int coin : coins) { + for (int i = 1; i <= amount; i++) { + if (i - coin >= 0) { + cache[i] = Math.min(cache[i], cache[i - coin] + 1); + } + } + } + + return cache[amount] == amount + 1 ? -1 : cache[amount]; + } +} diff --git a/src/main/java/dynamicProgramming/MinCostTickets.java b/src/main/java/dynamicProgramming/MinCostTickets.java new file mode 100644 index 0000000..0d7a584 --- /dev/null +++ b/src/main/java/dynamicProgramming/MinCostTickets.java @@ -0,0 +1,67 @@ +package dynamicProgramming; + +public class MinCostTickets { + + //1,4,6,7,8,20 + //2,7,50 + public int mincostTickets(int[] days, int[] cost) { + int lastDayTravel = days[days.length - 1]; + + int[] daysDp = new int[lastDayTravel + 1]; + boolean[] travelDays = new boolean[lastDayTravel + 1]; + + for (int day : days) { + travelDays[day] = true; + } + + for (int i = 1; i <= lastDayTravel; i++) { + + if (!travelDays[i]) { + daysDp[i] = daysDp[i - 1]; + } else { + int oneDayPass = daysDp[i - 1] + cost[0]; + int sevenDaysPass = daysDp[Math.max(0, i - 7)] + cost[1]; + int thirtyDayPass = daysDp[Math.max(0, i - 30)] + cost[2]; + + daysDp[i] = Math.min(oneDayPass, Math.min(sevenDaysPass, thirtyDayPass)); + } + } + + return daysDp[lastDayTravel]; + } + + + private int recursionUtil(int totalDaysOfTravel, boolean[] willTravel, int[] costs, Integer[] dp) { + if (totalDaysOfTravel <= 0) return 0; + + if (dp[totalDaysOfTravel] != null) return dp[totalDaysOfTravel]; + + int daily; + if (willTravel[totalDaysOfTravel]) { + daily = recursionUtil(totalDaysOfTravel - 1, willTravel, costs, dp) + costs[0];// Corresponding to daily package + } else { + daily = recursionUtil(totalDaysOfTravel - 1, willTravel, costs, dp);// This is the case when we cant take daily package but still we need to make recursive call to change the state + } + + int weekly = recursionUtil(totalDaysOfTravel - 7, willTravel, costs, dp) + costs[1];// Corresponding to weekly package + int monthly = recursionUtil(totalDaysOfTravel - 30, willTravel, costs, dp) + costs[2];// Corresponding to monthly package + dp[totalDaysOfTravel] = Math.min(daily, Math.min(weekly, monthly)); + return dp[totalDaysOfTravel]; + + } + + // Time Complexity-: O(N) Space Complexity -: O(366) + public int mincostTicketsRecur(int[] days, int[] costs) { + int totalDaysOfTravel = days[days.length - 1]; + boolean[] willTravel = new boolean[totalDaysOfTravel+1]; + for (int day : days) { + willTravel[day] = true; + } + + Integer[] dp = new Integer[totalDaysOfTravel+1]; + recursionUtil(totalDaysOfTravel, willTravel, costs, dp); + return dp[totalDaysOfTravel]; + } + + +} diff --git a/src/main/java/dynamicProgramming/MinSwapsToMakeArrayIncreasing.java b/src/main/java/dynamicProgramming/MinSwapsToMakeArrayIncreasing.java new file mode 100644 index 0000000..85061bc --- /dev/null +++ b/src/main/java/dynamicProgramming/MinSwapsToMakeArrayIncreasing.java @@ -0,0 +1,113 @@ +package dynamicProgramming; + +/** + * https://leetcode.com/problems/minimum-swaps-to-make-sequences-increasing/ + */ +public class MinSwapsToMakeArrayIncreasing { + Integer[][] dp; + final int MAX = 10_000; + + /** + * There are two states possible, + *

+ * Don't swap elements at the current index + * Swap elements at the current index + *

+ * We just have to find out which one gives the minimum number of swaps for the rest of the array. + * That is, we will compute answer for both the states. + * The answer for the current state is dependent on the relation between the element at the current index + * and the previous index. + *

+ * If they are already in increasing order, t + * hen the state for the current index is applied to the previous index + * (that is, no swap remains no swap, swap remains swap). + * Else, the state for the current index is reversed for the previous index. + * But, what if swap and no swap both achieve the increasing order? In this case, + * we take the minimum of both states from the previous index. + * + * @param A + * @param B + * @return + */ + public int minSwapTopDown(int[] A, int[] B) { + dp = new Integer[A.length][2]; + return minSwapHelper(A, B, 0, -1, -1, 0); + } + + private int minSwapHelper(int[] A, int[] B, int i, int prevA, int prevB, int swapped) { + + if (i == A.length) return 0; + if (dp[i][swapped] != null) return dp[i][swapped]; + + int minSwaps = MAX; + + if (A[i] > prevA && B[i] > prevB) { // with-no-swap + minSwaps = minSwapHelper(A, B, i + 1, A[i], B[i], 0); + } + + if (B[i] > prevA && A[i] > prevB) { // with-swap + minSwaps = Math.min(minSwaps, minSwapHelper(A, B, i + 1, B[i], A[i], 1) + 1); + } + + dp[i][swapped] = minSwaps; + return minSwaps; + } + + /** + * https://www.youtube.com/watch?v=mLTF2UXkd2o + * @return + */ + public static int minSwap(int[] A, int[] B) { + + int[] noSwap = new int[A.length]; + int[] swap = new int[A.length]; + swap[0] = 1; + for (int i = 1; i < A.length; ++i) { + + /** // This is max value, could be anything as long as they are higher + // than max possible value (which would be A.length-1, since max + // swaps you can do is A.length-1)*/ + noSwap[i] = A.length; + swap[i] = A.length; + + if (A[i] > A[i - 1] && B[i] > B[i - 1]) { + /** + * We are here because this index does not need to swap. + // Great, what would be the cost to reach here and not swap? + // It'll be same as cost of not swapping for prev. index. + // Why dont we rather take min(noSwap[i-1], swap[i-1]), because + // in that case noSwap[i-1] will be min anyway. + */ + noSwap[i] = noSwap[i - 1]; + + + /** // what would be the cost to reach here and swap? + // It'll be cost of swapping for prev. index + 1. + // Why dont we rather take min(noSwap[i-1], swap[i-1]) + 1, because + // we are tracking optimistic swaps and if we do min, we will lose + // track of swaps that were needed and done in past. + */ + swap[i] = swap[i - 1] + 1; + + } + /** + * In this case, if we want to keep A and B increasing before the index i, can only have two choices. + * -> 2.1 swap at (i-1) and do not swap at i, we can get notswap[i] = Math.min(swap[i-1], notswap[i] ) + * -> 2.2 do not swap at (i-1) and swap at i, we can get swap[i]=Math.min(notswap[i-1]+1, swap[i]) + */ + if (A[i] > B[i - 1] && B[i] > A[i - 1]) { + noSwap[i] = Math.min(noSwap[i], swap[i - 1]); + swap[i] = Math.min(noSwap[i - 1] + 1, swap[i]); + } + } + + // Now that we cost of swapping and not swapping each index, + // answer is: + return Math.min(noSwap[A.length - 1], swap[A.length - 1]); + } + + public static void main(String[] args) { + + System.out.println(minSwap(new int[]{0, 4, 4, 5, 9}, new int[]{0, 1, 6, 8, 10})); + } +} diff --git a/src/main/java/dynamicProgramming/MonotoneIncreasingString.java b/src/main/java/dynamicProgramming/MonotoneIncreasingString.java new file mode 100644 index 0000000..45eaabb --- /dev/null +++ b/src/main/java/dynamicProgramming/MonotoneIncreasingString.java @@ -0,0 +1,78 @@ +package dynamicProgramming; + +/** + * https://leetcode.com/problems/flip-string-to-monotone-increasing + */ +public class MonotoneIncreasingString { + + /** + * * Algorithm: + * * + * * Skip 0's until we encounter the first 1. + * * Keep track of number of 1's in onesCount (Prefix). + * * Any 0 that comes after we encounter 1 can be a potential candidate for flip. Keep track of it in flipCount. + * * If flipCount exceeds oneCount - (Prefix 1's flipped to 0's) + * * a. Then we are trying to flip more 0's (suffix) than number of 1's (prefix) we have. + * * b. Its better to flip the 1's instead. + * @param s + * @return + */ + public int minFlipsMonoIncr(String s) { + char[] ch = s.toCharArray(); + int onescount = 0; + int flipcount = 0; + + for (int i = 0; i < s.length(); i++) { + if (ch[i] == '0') { + if (onescount == 0) continue; // if all beginning char is zero, no need to flip + flipcount++; // flip 0 -> 1 + } else { + onescount++; // flip 1 -> 0 + } + if (flipcount > onescount) { // if flip 0-> 1 greater than flip 1 -> 0 then + flipcount = onescount; // then we choose flip 1 -> 0 for the left part + } + } + + return flipcount; + } + + /** + * LIS variation + * Thought: + * Since s is a binary string, so an increasing subsequence will either: + * + * end at '0' + * end at '1' + * For number of changes(flips) to be minimum + * we need to find the longest part of the string which can be left untouched (i.e which is already increasing). + * + * Implementation Details: + * + * So if s[i]=='0': + * + * current element can extend an increasing subsequence ending at '0'. + * else if s[i]=='1' current element can extend: + * + * an increasing subsequence ending at a '0' + * an increasing subsequence ending at a '1' + * which one to choose ? the one which is the largest out of 1) and 2). + * answer=s.size() - max(lis ending at 0, lis ending at 1) + */ + public int MinFlipsMonoIncrLIS(String S) + { + int zeros = 0, increasingSeq = 0; + + for(int i = 0; i < S.length(); i++) + { + if((S.charAt(i) - '0') == 0) + zeros++; + else + increasingSeq++; + // it can extend both lis ending at 0 and ending at 1 so will choose the best of 2 + increasingSeq = Math.max(increasingSeq, zeros); + } + + return S.length() - increasingSeq; + } +} diff --git a/src/dynamicProgramming/NumberWithSameConsequtiveDifference.java b/src/main/java/dynamicProgramming/NumberWithSameConsequtiveDifference.java similarity index 84% rename from src/dynamicProgramming/NumberWithSameConsequtiveDifference.java rename to src/main/java/dynamicProgramming/NumberWithSameConsequtiveDifference.java index f754de4..7ab5a1f 100644 --- a/src/dynamicProgramming/NumberWithSameConsequtiveDifference.java +++ b/src/main/java/dynamicProgramming/NumberWithSameConsequtiveDifference.java @@ -6,7 +6,8 @@ /** * Return all non-negative integers of length N such that the absolute difference between every two consecutive digits is K. * - * Note that every number in the answer must not have leading zeros except for the number 0 itself. For example, 01 has one leading zero and is invalid, but 0 is valid. + * Note that every number in the answer must not have leading zeros except for the number 0 itself. + * For example, 01 has one leading zero and is invalid, but 0 is valid. * * You may return the answer in any order. * @@ -46,10 +47,10 @@ public void dfs(int N, int K, List result, int num){ result.add(num); return; } - int last_digit= num%10; + int lastDigit= num%10; - if(last_digit>=K) dfs(N-1,K,result,num*10+last_digit-K); - if(K>0 && K+last_digit<10) dfs(N-1,K,result,num*10+last_digit+K); + if(lastDigit>=K) dfs(N-1,K,result,num*10+lastDigit-K); + if(K>0 && K+lastDigit<10) dfs(N-1,K,result,num*10+lastDigit+K); } diff --git a/src/main/java/dynamicProgramming/OnesAndZeroes.java b/src/main/java/dynamicProgramming/OnesAndZeroes.java new file mode 100644 index 0000000..49e16a7 --- /dev/null +++ b/src/main/java/dynamicProgramming/OnesAndZeroes.java @@ -0,0 +1,45 @@ +package dynamicProgramming; + +/** + * https://leetcode.com/problems/ones-and-zeroes/ + */ +public class OnesAndZeroes { + private int[][][] memo; + + public int findMaxForm(String[] strs, int m, int n) { + memo = new int[m + 1][n + 1][strs.length]; + return findMaxFormFrom(strs, m, n, 0); + } + + private int findMaxFormFrom(String[] strs, int m, int n, int si) { + if (si == strs.length || (m == 0 && n == 0)) { + return 0; + } + if (memo[m][n][si] > 0) { + return memo[m][n][si]; + } + int cntIncludeStr = 0; + int zeros = countZeros(strs[si]); + int ones = strs[si].length() - zeros; + //for each string, we count the zeroes in it by countZeroesIn(String str) and see if there are enough 0s and 1s for it. + // If so, we accumulate that string and proceed with the remaining strings, 0s and 1s by means of the following code: + if (m >= zeros && n >= ones) { + cntIncludeStr = 1 + findMaxFormFrom(strs, m - zeros, n - ones, si + 1); + } + //We also take the other route, which simply skips the string and does not use any 0s and 1s. + int cntExcludeStr = findMaxFormFrom(strs, m, n, si + 1); + //Whichever is bigger, is that the result. + memo[m][n][si] = Math.max(cntIncludeStr, cntExcludeStr); + return memo[m][n][si]; + } + + private int countZeros(String s) { + int cntZero = 0; + for (char c : s.toCharArray()) { + if (c == '0') { + cntZero++; + } + } + return cntZero; + } +} diff --git a/src/main/java/dynamicProgramming/OptimalStratergy.java b/src/main/java/dynamicProgramming/OptimalStratergy.java new file mode 100644 index 0000000..5b47eb4 --- /dev/null +++ b/src/main/java/dynamicProgramming/OptimalStratergy.java @@ -0,0 +1,130 @@ +package dynamicProgramming; + +import java.util.Arrays; + +/** + * http://www.glassdoor.com/Interview/N-pots-each-with-some-number-of-gold-coins-are-arranged-in-a-line-You-are-playing-a-game-against-another-player-You-tak-QTN_350584.htm + *

+ * https://www.techiedelight.com/pots-gold-game-dynamic-programming/ + */ +public class OptimalStratergy { + // Function to maximize the number of coins collected by a player, + // assuming that opponent also plays optimally + public static int optimalStrategy(int[] coin, int i, int j, + int[][] lookup) { + // base case: one pot left, only one choice possible + if (i == j) { + return coin[i]; + } + + // if we're left with only two pots, choose one with maximum coins + if (i + 1 == j) { + return Integer.max(coin[i], coin[j]); + } + + // if sub-problem is seen for the first time, solve it and + // store its result in a lookup table + if (lookup[i][j] == 0) { + // if player chooses front coin i, opponent is left to choose + // from [i+1, j]. + // 1. if opponent chooses front coin i+1, recur for [i+2, j] + // 2. if opponent chooses rear coin j, recur for [i+1, j-1] + + int start = coin[i] + Integer.min(optimalStrategy(coin, i + 2, + j, lookup), + optimalStrategy(coin, i + 1, j - 1, lookup)); + + // if player chooses rear coin j, opponent is left to choose + // from [i, j-1]. + // 1. if opponent chooses front coin i, recur for [i+1, j-1] + // 2. if opponent chooses rear coin j-1, recur for [i, j-2] + + int end = coin[j] + Integer.min(optimalStrategy(coin, i + 1, + j - 1, lookup), + optimalStrategy(coin, i, j - 2, lookup)); + + // assign maximum of two choices + lookup[i][j] = Integer.max(start, end); + } + + // return the subproblem solution from the map + return lookup[i][j]; + } + + // main function + public static void main(String[] args) { + // pots of gold arranged in a line + int[] coin = {4, 6, 2, 3}; + + // Create a table to store solutions of subproblems + int[][] lookup = new int[coin.length][coin.length]; + + System.out.println("Maximum coins collected by player is " + + optimalStrategy(coin, 0, coin.length - 1, lookup)); + } + + public boolean PredictTheWinner(int[] nums) { + Integer[][] dp = new Integer[nums.length + 1][nums.length + 1]; + int playerA = recursionHelper(nums, 0, nums.length - 1, dp); + int playerB = Arrays.stream(nums).sum() - playerA; + + return playerA >= playerB; + } + + public int recursionHelper(int[] nums, int i, int j, Integer[][] dp) { + + if (i > j) return 0; + if (i == j) return nums[i]; + if (dp[i][j] != null) return dp[i][j]; + + int takeFront = nums[i] + Math.min(recursionHelper(nums, i + 2, j, dp), recursionHelper(nums, i + 1, j - 1, dp)); + int takeBack = nums[j] + Math.min(recursionHelper(nums, i + 1, j - 1, dp), recursionHelper(nums, i, j - 2, dp)); + return dp[i][j] = Math.max(takeFront, takeBack); + } + + public boolean PredictTheWinnerBottomUp(int[] nums) { + int n = nums.length; + + /* + dp[i][j] -> score of the first player for picks between nums[i..j] + */ + int[][] dp = new int[n][n]; + + // total of nums + int total = 0; + for (int num : nums) { + total += num; + } + + for (int len = 1; len <= n; len++) { + for (int i = 0; i + len <= n; i++) { + int j = i + len - 1; + + /* + First player has option to choose i or j + If he chooses i then 2nd player to choose in (i+1, j) + - if 2nd player chooses i+1, then player 1 will next choose from (i+2,j) + - if 2nd player chooses j, then player 1 will next choose from (i+1,j-1) + If he chooses j then 2nd player to choose in (i, j-1) + - if 2nd player chooses i, then player 1 will next choose from (i+1,j-1) + - if 2nd player chooses j-1, then player 1 will next choose from (i,j-2) + + We know that player 2 would have played wisely and player 1 will get the the minimum in the next move. + We choose the best(Max) of the above 2 scenarios + */ + int a = (i + 1 < n && j - 1 >= 0) ? dp[i + 1][j - 1] : 0; + int b = (i + 2 < n) ? dp[i + 2][j] : 0; + int c = (j - 2 >= 0) ? dp[i][j - 2] : 0; + + dp[i][j] = Math.max(nums[i] + Math.min(a, b), nums[j] + Math.min(a, c)); + } + } + + /* + dp[0][n-1] will have the score for the first player. + */ + int player1Score = dp[0][n - 1]; + int player2Score = total - player1Score; + return player1Score >= player2Score; + } +} \ No newline at end of file diff --git a/src/dynamicProgramming/OptimalTreeSearch.java b/src/main/java/dynamicProgramming/OptimalTreeSearch.java similarity index 100% rename from src/dynamicProgramming/OptimalTreeSearch.java rename to src/main/java/dynamicProgramming/OptimalTreeSearch.java diff --git a/src/main/java/dynamicProgramming/OutOfBounds.java b/src/main/java/dynamicProgramming/OutOfBounds.java new file mode 100644 index 0000000..50ddb73 --- /dev/null +++ b/src/main/java/dynamicProgramming/OutOfBounds.java @@ -0,0 +1,32 @@ +package dynamicProgramming; + +/** + * https://leetcode.com/problems/out-of-boundary-paths/ + */ +public class OutOfBounds { + int [][] dirs= new int[][]{{-1,0},{1,0},{0,-1},{0,1}}; + int mod = 1000000000 + 7; + Integer[][][] cache; + public int findPaths(int m, int n, int maxMove, int startRow, int startColumn) { + cache= new Integer[m+1][n+1][maxMove+1]; + return recursionHelper(m,n,maxMove,startRow,startColumn); + } + + public int recursionHelper(int m, int n, int maxMove, int startRow, int startColumn){ + + if(startRow<0 || startRow>=m || startColumn<0 || startColumn>=n) return 1; + if(maxMove==0) return 0; + + if(cache[startRow][startColumn][maxMove]!=null) return cache[startRow][startColumn][maxMove]; + + int result=0; + + for(int[] dir:dirs){ + result= result+recursionHelper(m,n,maxMove-1,startRow+dir[0],startColumn+dir[1]) %mod; + result%=mod; + } + + return cache[startRow][startColumn][maxMove]= result; + + } +} diff --git a/src/main/java/dynamicProgramming/PaintHouses.java b/src/main/java/dynamicProgramming/PaintHouses.java new file mode 100644 index 0000000..1ea1bc3 --- /dev/null +++ b/src/main/java/dynamicProgramming/PaintHouses.java @@ -0,0 +1,27 @@ +package dynamicProgramming; + +/** + * TODO + * https://leetcode.com/problems/paint-house/ + */ +public class PaintHouses { + + public int minCost(int[][] costs) { + if (costs == null || costs.length == 0) return 0; + // Assume all costs are positive + int n = costs.length; // number of houses + int[][] dp = new int[n][3]; + // Init + dp[0][0] = costs[0][0]; + dp[0][1] = costs[0][1]; + dp[0][2] = costs[0][2]; + // DP + for (int i = 1; i < n; ++i) { + dp[i][0] = Math.min(dp[i - 1][1], dp[i - 1][2]) + costs[i][0]; + dp[i][1] = Math.min(dp[i - 1][0], dp[i - 1][2]) + costs[i][1]; + dp[i][2] = Math.min(dp[i - 1][0], dp[i - 1][1]) + costs[i][2]; + } + return Math.min(dp[n - 1][0], Math.min(dp[n - 1][1], dp[n - 1][2])); + } + +} diff --git a/src/practiceproblems/PerfectSquare.java b/src/main/java/dynamicProgramming/PerfectSquare.java similarity index 86% rename from src/practiceproblems/PerfectSquare.java rename to src/main/java/dynamicProgramming/PerfectSquare.java index dc47adf..4c5e01d 100644 --- a/src/practiceproblems/PerfectSquare.java +++ b/src/main/java/dynamicProgramming/PerfectSquare.java @@ -1,4 +1,4 @@ -package practiceproblems; +package dynamicProgramming; import java.util.*; @@ -17,9 +17,8 @@ class PerfectSquare { public int numSquaresDp(int n) { int[] ns = new int[n+1]; - Arrays.fill(ns , -1); - ns[0] = 0; - for(int i=1;i0;j--){ @@ -68,6 +67,19 @@ public int numSquares(int n){ return depth; } + Integer[]dp= new Integer[10000]; + public int numSquaresRecur(int n) { + if(n<=0) return 0; + if(n==1) return 1; + if(dp[n]!=null) return dp[n]; + int count=100000; + for(int i=1;i<=Math.sqrt(n);i++){ + count= Math.min(count, 1+numSquaresRecur(n-i*i)); + } + dp[n]=count; + return dp[n]; + } + public static void main(String[] args) { new PerfectSquare().numSquaresDp(13); } diff --git a/src/main/java/dynamicProgramming/StoneGame.java b/src/main/java/dynamicProgramming/StoneGame.java new file mode 100644 index 0000000..d65c68f --- /dev/null +++ b/src/main/java/dynamicProgramming/StoneGame.java @@ -0,0 +1,78 @@ +package dynamicProgramming; + +/** + * Pots of Gold + * https://leetcode.com/problems/stone-game + * + * Player A B A + * + * - pick index i+2 + * - pick index i+1 + * - pick index j + * - pick index i + * - pick index i + * - pick index j + * - pick index j-1 + * + * - pick index i+2 + * - pick index i + * - pick index j-1 + * - pick index j + * - pick index i + * - pick index j-1 + * - pick index j-2 + * + * For example, stones = [5, 3, 4, 5] + * + * If A picks left most stone 5, remain stones are [3, 4, 5]. + * + * B with choices to take left most stone 3 or right most stone 5, + * and B's best choice is to take right most stone 5 because 5 > 3 & 5 > 4. + * Then A has choice to make among remaining stones [3, 4]. + * + * From above decisions, what A can get for next to next round? + * If B takes left most stone 3, A's selectable range are [4, 5] + * If B takes right most stone 5, A's selectable range are [3, 4] + * + * And since B make choice to maximum B's score, + * choices A can have is not max of([4, 5], [3, 4]) which is [4, 5], but min([4, 5], [3, 4]), which is [3, 4]. + * + * This is a little complicated, + * but since B also wants to get maximum score, remaining choices for A is not max but min. + * + * Use memo for recursion, memo[i][j] means maximum score can get form index i ~j. + * The condition for A to win is to make sure either of one condition follows: + * memo[0][size-1] > max(memo[1][size-1], memo[0][size-2]). + */ +public class StoneGame { + + Integer[][] cache; + + public boolean stoneGame(int[] piles) { + cache = new Integer[piles.length + 2][piles.length + 2]; + int totalSum = 0; + for (int pile : piles) { + totalSum += pile; + } + + return dfsHelper(piles, 0, piles.length - 1) > totalSum / 2; + } + + public int dfsHelper(int[] piles, int startIndex, int endIndex) { + if (startIndex >= piles.length || endIndex < 0) return 0; + + if (cache[startIndex][endIndex] != null) return cache[startIndex][endIndex]; + + int maxStonesPickedFromStart= piles[startIndex] + Math.min( + dfsHelper(piles,startIndex+2,endIndex), + dfsHelper(piles,startIndex+1,endIndex-1) + ); + + int maxStonesPickedFromEnd = piles[endIndex] + Math.min( + dfsHelper(piles,startIndex,endIndex-2), + dfsHelper(piles,startIndex+1,endIndex-1) + ); + + return Math.max(maxStonesPickedFromEnd,maxStonesPickedFromStart); + } +} diff --git a/src/main/java/dynamicProgramming/TargetSum.java b/src/main/java/dynamicProgramming/TargetSum.java new file mode 100644 index 0000000..2a24d86 --- /dev/null +++ b/src/main/java/dynamicProgramming/TargetSum.java @@ -0,0 +1,111 @@ +package dynamicProgramming; + +/** + * https://leetcode.com/problems/target-sum/ + *

+ * Why 0/1 Knapsack? Our 'Capacity' is the target we want to reach 'S'. + * Our 'Items' are the numbers in the input subset and the 'Weights' of the items are the values of the numbers itself. + * This question follows 0/1 and not unbounded knapsack because we can use each number ONCE. + *

+ * What is the variation? The twist on this problem from standard knapsack is that + * we must add ALL items in the subset to our knapsack. + * We can reframe the question into adding the positive or negative + * value of the current number to our knapsack in order to reach the target capacity 'S'. + *

+ * What is the variation? The twist on this problem from standard knapsack is that + * we must add ALL items in the subset to our knapsack. + * We can reframe the question into adding the positive or negative value of the current number to our knapsack + * in order to reach the target capacity 'S'. + *

+ * We need 2 base cases. One for when the current state is valid and one for when the current state is invalid. + *

+ * Valid: Index is out of bounds AND current sum is equal to target 'S' + * Invalid: Index is out of bounds + *

+ *

+ * Given nums = [1, 2, 3, 4, 5] and target = 3 then one possible solution is +1-2+3-4+5 = 3 + * Here positive subset is P = [1, 3, 5] and negative subset is N = [2, 4] + *

+ * Then let's see how this can be converted to a subset sum problem: + *

+ * sum(P) - sum(N) = target + * sum(P) + sum(N) + sum(P) - sum(N) = target + sum(P) + sum(N) + * 2 * sum(P) = target + sum(nums) + */ +public class TargetSum { + Integer[][] cache; + + public int findTargetSumWays(int[] nums, int target) { + int sum = 0; + for (int i : nums) sum += i; + cache = new Integer[1001][2 * sum + 1]; + + // the reason we send target+sum and sum instead of target and 0 is + // sum-nums[index] will produce negative values which will throw index out of bound exception at cache[index][sum] + return recursionHelper(nums, target + sum, 0, sum); + } + + public int recursionHelper(int[] nums, int target, int index, int sum) { + + if (index >= nums.length) { + return target == sum ? 1 : 0; + } + + if (cache[index][sum] != null) return cache[index][sum]; + + int left = recursionHelper(nums, target, index + 1, sum + nums[index]); + + int right = recursionHelper(nums, target, index + 1, sum - nums[index]); + + return cache[index][sum] = left + right; + } + + /** solution 2: DP (0/1 knapsack) - Time: O(n^2), Space: O(n^2) Thanks @jerry */ + /** + * sub-problem: dp[i][j] represents number of possible ways to reach sum j by using first ith items + * base case: dp[0][sum], position sum represents sum 0 + * recurrence relation: + * dp[i][j] += dp[i - 1][j + nums[i - 1]] if j + nums[i - 1] <= sum * 2 + * dp[i][j] += dp[i - 1][j - nums[i - 1]] if j - nums[i - 1] >= 0 + *

+ * explanation: if j + nums[i - 1] or j - nums[i - 1] is in correct range, we can use the number nums[i - 1] + * to generate next state of dp array + */ + public static int findTargetSumWaysBottomUp(int[] nums, int S) { + if (nums.length == 0) { + return 0; + } + + int sum = 0; + for (int num : nums) { + sum += num; + } + + // corner case: when S is out of range [-sum, sum] + if (S < -sum || S > sum) { + return 0; + } + + int[][] dp = new int[nums.length + 1][sum * 2 + 1]; + dp[0][sum] = 1; + int leftBound = 0; + int rightBound = sum * 2; + for (int i = 1; i <= nums.length; i++) { + for (int j = leftBound; j < rightBound + 1; j++) { + // try all possible sum of (previous sum j + current number nums[i - 1]) and all possible difference of + // (previous sum j - current number nums[i - 1]) + if (j + nums[i - 1] <= rightBound) { + dp[i][j] += dp[i - 1][j + nums[i - 1]]; + } + if (j - nums[i - 1] >= leftBound) { + dp[i][j] += dp[i - 1][j - nums[i - 1]]; + } + } + } + return dp[nums.length][sum + S]; + } + + public static void main(String[] args) { + System.out.println(findTargetSumWaysBottomUp(new int[]{1, 1, 1, 1, 1}, 3)); + } +} diff --git a/src/main/java/dynamicProgramming/TriangleSum.java b/src/main/java/dynamicProgramming/TriangleSum.java new file mode 100644 index 0000000..65dd427 --- /dev/null +++ b/src/main/java/dynamicProgramming/TriangleSum.java @@ -0,0 +1,64 @@ +package dynamicProgramming; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * https://leetcode.com/problems/triangle/ + */ +public class TriangleSum { + static Integer[][] cache = null; + + public static int minimumTotal(List> triangle) { + cache = new Integer[triangle.size()][triangle.size()]; + + return recursionUtil(triangle, 0, 0); + } + + public static int recursionUtil(List> triangle, int triangleIndex, int subIndex) { + if (triangleIndex >= triangle.size()) return 0; + + if (cache[triangleIndex][subIndex] != null) return cache[triangleIndex][subIndex]; + + // recursively take from next rom same column + int left = recursionUtil(triangle, triangleIndex + 1, subIndex); + + // recursively take for next row, next column + int right = recursionUtil(triangle, triangleIndex + 1, subIndex + 1); + + cache[triangleIndex][subIndex] = Math.min(left, right) + triangle.get(triangleIndex).get(subIndex); + + return cache[triangleIndex][subIndex]; + } + + public static int minimumTotalBottomUp(List> triangle) { + + int[][] dp = new int[triangle.size()][triangle.size()]; + // the commented code is to optimise the O(N^2) space + // int[]dp = new int[triangle.size()]; + // int[]dp1 = new int[triangle.size()]; + + //Remember base case is just returning leaf nodes + for (int i = 0; i < triangle.size(); i++) { + dp[triangle.size() - 1][i] = triangle.get(triangle.size() - 1).get(i); + } + + for (int row = triangle.size() - 2; row >= 0; row--) { + for (int pos = 0; pos < triangle.get(row).size(); pos++) { + //dp1[pos] = triangle.get(row).get(pos) + Math.min(dp[pos+1], dp[pos]); + dp[row][pos] = triangle.get(row).get(pos) + Math.min(dp[row + 1][pos], dp[row + 1][pos + 1]); + } + //dp = dp1; + } + + return dp[0][0]; + } + + public static void main(String[] args) { + List> triangle = Arrays.stream(new Integer[][]{{2}, {3, 4}, {6, 5, 7}, {4, 1, 8, 3}}) + .map(Arrays::asList) + .collect(Collectors.toList()); + minimumTotalBottomUp(triangle); + } +} diff --git a/src/main/java/dynamicProgramming/TwoKeysKeyBoard.java b/src/main/java/dynamicProgramming/TwoKeysKeyBoard.java new file mode 100644 index 0000000..7a0b434 --- /dev/null +++ b/src/main/java/dynamicProgramming/TwoKeysKeyBoard.java @@ -0,0 +1,49 @@ +package dynamicProgramming; + +public class TwoKeysKeyBoard { + + /** + * the idea is if i is even(i%2), go to the i/2 position and add 2 (1- for copy and 1- for paste) + * if i is odd, we need to check what other odd is factor of i, initialise j and iterate till sqrt(i) + * if we find i%j==0 then we go to i%j position and add 1-for copy and j-1 for paste + * for e.x if i=9 we find j=3 (i%3==0), we go to i/j (3rd position which has 'AAA') and copy and paste it 2 times + * i=3(AAA), copy and paste 2 times (AAA-AAA-AAA) we get 9 items + * + */ + public static int minSteps(int n) { + int[] dp = new int[n+1]; + dp[1]=0; + for(int i=2;i<=n;i++){ + dp[i] = i; // this is for prime numbers + if(i%2==0){ + dp[i] = dp[i/2]+1+1; // 1 for copy + 1 for paste + }else{ + for(int j=2;j<=Math.sqrt(i);j++){ + if(i%j==0){ + dp[i] = Math.min(dp[i], dp[i/j] + 1 + j-1); //1 for copy and (j-1) for paste + } + } + } + + } + return dp[n]; + } + + int[] dp = new int[1001]; + public int minStepRecurs(int n) { + if(n==1) return 0; + if(dp[n]!=0) return dp[n]; + int min=n; + for(int i=2;i<=Math.sqrt(n);i++){ + if(n%i==0){ + min = Math.min(min, minStepRecurs(n/i) + 1 + i-1); //1 for copy and (i-1) for paste + } + } + dp[n] = min; + return min; + } + + public static void main(String[] args) { + System.out.println(minSteps(9)); + } +} diff --git a/src/main/java/dynamicProgramming/UniqueCoinChange.java b/src/main/java/dynamicProgramming/UniqueCoinChange.java new file mode 100644 index 0000000..aefecff --- /dev/null +++ b/src/main/java/dynamicProgramming/UniqueCoinChange.java @@ -0,0 +1,36 @@ +package dynamicProgramming; + + +/** + * https://leetcode.com/problems/coin-change + */ +public class UniqueCoinChange { + + public int changeSpaceOptimised(int amount, int[] coins) { + int[] combi = new int[amount + 1]; + combi[0] = 1; + for (int coin : coins) { + for (int j = 1; j <= amount; j++) { + if (j - coin >= 0) + combi[j]+= combi[j - coin]; + } + } + for (int a : combi) + System.out.print(a + " "); + return combi[amount]; + } + + public int changeRecursion(int amount, int[] coins) { + Integer[][] dp = new Integer[amount+1][coins.length+1]; + return recursionHelper(amount,0,coins,dp); + } + + public int recursionHelper(int amount, int idx, int[] coins,Integer[][] dp){ + if(amount==0) return 1; + if(amount<=0 || idx>=coins.length) return 0; + if(dp[amount][idx]!=null) return dp[amount][idx]; + + return dp[amount][idx]=recursionHelper(amount-coins[idx],idx,coins,dp)+recursionHelper(amount,idx+1,coins,dp); + } + +} diff --git a/src/main/java/dynamicProgramming/fibonacci/DecodeWays.java b/src/main/java/dynamicProgramming/fibonacci/DecodeWays.java new file mode 100644 index 0000000..c6d1fdc --- /dev/null +++ b/src/main/java/dynamicProgramming/fibonacci/DecodeWays.java @@ -0,0 +1,83 @@ +package dynamicProgramming.fibonacci; + + +/** + Case 1 : Pick single element, so in this we pick current and call for index + 1. + note : In case of single pick, element should not be '0' as it is invalid + + -> ways = decode(s, idx+1, n) + : elements in range [1,9] is covered here in this case + + Case 2 : Pick couple, so that we can get elements in range [10, 26] . + Catch here is that we need to check and validate values so that we do not exceed the range. + + */ +public class DecodeWays { + + public int numDecodings(String s) { + if (s == null || s.length() == 0) { + return 0; + } + int n = s.length(); + int[] dp = new int[n + 1]; + dp[0] = 1; // an empty string can only be decoded as an empty string + dp[1] = s.charAt(0) != '0' ? 1 : 0; // If current element is 0, we simply return 0 as it is not possible to get a character using 0. + for (int i = 2; i <= n; i++) { + int first = Integer.parseInt(s.substring(i - 1, i)); + int second = Integer.parseInt(s.substring(i - 2, i)); + if (first >= 1 && first <= 9) { + dp[i] += dp[i - 1]; + } + if (second >= 10 && second <= 26) { + dp[i] += dp[i - 2]; + } + } + return dp[n]; + } + + public int numDecodings1(String s) { + if (s == null || s.length() == 0) return 0; + Integer[] cache = new Integer[s.length() + 1]; + return helperFn(s, 0, cache); + } + + public int helperFn(String s, int index, Integer[] cache) { +// When we reach the end of the string this means that we have found a possible way to decode. +// Thus, this will contribute to answer and return 1. + if (index >= s.length()) return 0; + + if (cache[index] != null) return cache[index]; + int total = 0; + if (index + 1 <= s.length()) { + String temp1 = s.substring(index, index + 1); + if (valid(temp1)) { + total += 1+helperFn(s, index + 1, cache); + } + } + + if (index + 2 <= s.length()) { + String temp2 = s.substring(index, index + 2); + if (valid(temp2)) { + total += 1+helperFn(s, index + 2, cache); + } + } + + cache[index] = total; + return cache[index]; + + } + + public boolean valid(String s1) { + if (s1.length() == 0) return false; + if (s1.charAt(0) == '0') return false; //If current element is 0, we simply return 0 as it is not possible to get a character using 0. + + int val = Integer.parseInt(s1); + + return val >= 1 && val <= 26; + } + + public static void main(String[] args) { + DecodeWays decode = new DecodeWays(); + System.out.println(decode.numDecodings("1210")); + } +} diff --git a/src/main/java/dynamicProgramming/fibonacci/DiceThrow.java b/src/main/java/dynamicProgramming/fibonacci/DiceThrow.java new file mode 100644 index 0000000..b176233 --- /dev/null +++ b/src/main/java/dynamicProgramming/fibonacci/DiceThrow.java @@ -0,0 +1,38 @@ +package dynamicProgramming.fibonacci; + +/** + * Time Complexity: O(m * n * x) + * https://leetcode.com/problems/number-of-dice-rolls-with-target-sum + */ +class DiceThrow { + // f-> faces + // d->dices + // target->sum + static Integer[][] cache = new Integer[31][1001]; + + public static int numRollsToTarget(int d, int f, int target) { + if (d <= 0 || target < 0) return target == 0 ? 1 : 0; + if (cache[d][target] != null) return cache[d][target]; + int ways = 0; + for (int i = 1; i <= f; i++) { + ways += numRollsToTarget(d - 1, f, target - i); + ways %= 1000000007; + } + + return cache[d][target] = ways; + } + + public int numRollsToTargetBottomUp(int d, int f, int target) { + int[][] dp = new int[d + 1][target + 1]; + dp[0][0] = 1; + for (int i = 1; i <= d; i++) + for (int j = 1; j <= target; j++) + for (int k = 1; k <= f; k++) + dp[i][j] = (dp[i][j] + (k <= j ? dp[i - 1][j - k] : 0)) % 1000000007; + return dp[d][target]; + } + + public static void main(String[] args) { + System.out.println(numRollsToTarget(6, 3, 6)); + } +} \ No newline at end of file diff --git a/src/main/java/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java b/src/main/java/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java new file mode 100644 index 0000000..09a0502 --- /dev/null +++ b/src/main/java/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java @@ -0,0 +1,110 @@ +package dynamicProgramming.fibonacci; + +import java.util.Arrays; +import java.util.HashMap; + +public class FibonacciStaircaseWaysToCoverDist { + + public int fibonacciSeriesRecursive(int n) { + if (n == 1) + return 2; + if (n == 2) + return 3; + return fibonacciSeriesRecursive(n - 1) + fibonacciSeriesRecursive(n - 2); + } + + public static void main(String args[]) { + FibonacciStaircaseWaysToCoverDist fs = new FibonacciStaircaseWaysToCoverDist(); + System.out.println(fs.fibonacciSeries(4)); + System.out.println(fs.fibonacciSeriesRecursive(3)); + } + + public int fibonacciSeries(int n) { + int n1 = 0; + int n2 = 1; + int sum; + + if (n == n1 || n == n2) { + return n; + } + + for (int i = 1; i <= n; i++) { + sum = n1 + n2; + n1 = n2; + n2 = sum; + } + return n2; + } + + + public int climbStairsBottomUp(int n) { + int[] dp = new int[n + 1]; + dp[0] = 0; + dp[1] = 1; + dp[2] = 2; + for (int stair = 3; stair <= n; ++stair) { + dp[stair] += dp[stair - 1] + dp[stair - 2]; + } + + return dp[n]; + } + + public int climbStairs(int N) { + int[] cache = new int[N + 1]; + Arrays.fill(cache, -1); + return fibUtil(N, 0, cache); + } + + public int fibUtil(int N, int start, int[] cache) { + if (start > N) return 0; + + if (N == start) return 1; + + if (cache[start] != -1) return cache[start]; + + cache[start] = fibUtil(N, start + 1, cache) + fibUtil(N, start + 2, cache); + + return cache[start]; + } + + + public int minCostClimbingStairs(int[] cost) { + if (cost.length == 2) return Math.min(cost[0], cost[1]); + int[] dp = new int[cost.length + 1]; + dp[0] = cost[0]; + dp[1] = cost[1]; + + for (int i = 2; i < cost.length; i++) { + dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i]; + } + + return Math.min(dp[cost.length - 1], dp[cost.length - 2]); + } + + private HashMap memo = new HashMap<>(); + + public int minCostClimbingStairsRecursion(int[] cost) { + return minimumCost(cost.length, cost); + } + + private int minimumCost(int i, int[] cost) { + // Base case, we are allowed to start at either step 0 or step 1 + if (i <= 1) { + return 0; + } + + // Check if we have already calculated minimumCost(i) + if (memo.containsKey(i)) { + return memo.get(i); + } + + // If not, cache the result in our hash map and return it + int downOne = cost[i - 1] + minimumCost(i - 1, cost); + int downTwo = cost[i - 2] + minimumCost(i - 2, cost); + memo.put(i, Math.min(downOne, downTwo)); + return memo.get(i); + } + +} + + diff --git a/src/main/java/dynamicProgramming/lcs/BitonicSequence.java b/src/main/java/dynamicProgramming/lcs/BitonicSequence.java new file mode 100644 index 0000000..b0a0959 --- /dev/null +++ b/src/main/java/dynamicProgramming/lcs/BitonicSequence.java @@ -0,0 +1,70 @@ +package dynamicProgramming.lcs; + +/** + * https://leetcode.com/problems/minimum-number-of-removals-to-make-mountain-array/ + * + * tricky LIS + */ +public class BitonicSequence { + /** + * Concept: We need to find the maximum number of elements of the array that can be + * involved in a mountain array. We know, that a mountain array contains a peak element + * and there is an increasing subsequence in the left of the peak and a decreasing subsequence in the right. + * So, we need to find out the element(peak), for which the total number of elements from the + * original array involved in the left increasing subsequence and the right decreasing + * subsequence, in maximum. This will create a mountain array with the peak element. + * Then, we can delete the rest of the elements of the array not involved in this mountain array. + */ + public int longestSequence(int arr[]) { + int[] lis = new int[arr.length]; + int[] lds = new int[arr.length]; + for (int i = 0; i < arr.length; i++) { + lis[i] = 1; + lds[i] = 1; + } + for (int i = 1; i < arr.length; i++) { + for (int j = 0; j < i; j++) { + if (arr[i] > arr[j]) { + lis[i] = Math.max(lis[i], lis[j] + 1); + } + } + } + + for (int i = arr.length - 2; i >= 0; i--) { + for (int j = arr.length - 1; j > i; j--) { + if (arr[i] > arr[j]) { + lds[i] = Math.max(lds[i], lds[j] + 1); + } + } + } + // because that middle element is common in both sequence .. for example, + // increasing subsequence 2,8,20 .. decreasing one 20,13,14 .. each of them has + // length 3 .. but bitonic subsequence 2,8,20,13,14 .. length= 3+3-1=5 + int max = 0; + for (int i = 0; i < arr.length; i++) { + /* + If the below conditional statement is not given, then strictly increasing or strictly + decreasing sequences will also be considered. It will hence fail in, + Test case: [10, 9, 8, 7, 6, 5, 4, 5, 4]. + ---Thanks to @chejianchao for suggesting the test case. + We need to make sure both the LIS on the left and right, ending at index i, + has length > 1. + */ + int max1 = lis[i] + lds[i] - 1; //Peak is counted twice in lis[] and lsd[] so -1 + System.out.print(max1 + " "); + if (max < max1) { + max = max1; + } + } + + return max; + } + + public static void main(String args[]) { + BitonicSequence bs = new BitonicSequence(); + int[] arr = {1, 4, 3, 7, 2, 1, 8, 11, 13, 0}; + int r = bs.longestSequence(arr); + System.out.println(r); + + } +} \ No newline at end of file diff --git a/src/main/java/dynamicProgramming/lcs/DeleteAndEarn.java b/src/main/java/dynamicProgramming/lcs/DeleteAndEarn.java new file mode 100644 index 0000000..a0f4123 --- /dev/null +++ b/src/main/java/dynamicProgramming/lcs/DeleteAndEarn.java @@ -0,0 +1,70 @@ +package dynamicProgramming.lcs; + +import java.util.Arrays; + +public class DeleteAndEarn { + + public int deleteAndEarn(int[] nums) { + // if we sort the array, we do not need to delete elements smaller than nums[idx] (ie nums[idx] - 1) because they are already computed + // and saved in memo, we only need to delete nums[idx] + 1 and we can do this simply by skipping them since the array is sorted + Arrays.sort(nums); + Integer[] dp = new Integer[nums.length]; + return recursionUtil(nums, 0, dp); + } + + private int recursionUtil(int[] nums, int idx, Integer[] dp) { + // if we reached the end of the array, we can not earn anymore, return 0 + if (idx == nums.length) + return 0; + + if (dp[idx] != null) return dp[idx]; + // delete and earn this element + int earned = nums[idx]; + int skip = idx + 1; + + // simply add all similar values of nums[idx] to earned at once + while (skip < nums.length && nums[skip] == nums[idx]) { + earned += nums[idx]; + skip++; + } + + // skip all elements = nums[idx] + 1 + // this is instead of deleting the elements = nums[idx] + 1 + // which does not alter the array and make the solution work + while (skip < nums.length && nums[skip] == nums[idx] + 1) + skip++; + + // recurse + earned += recursionUtil(nums, skip, dp); + + // skip deleting and earning this element + int skipped = recursionUtil(nums, idx + 1, dp); + + // return the max of the 2 values + dp[idx] = Math.max(earned, skipped); + + + return dp[idx]; + } + + /** + * for numbers from [1 - 10000], each has a total sum sums[i]; if you earn sums[i], you cannot earn sums[i-1] and sums[i+1] + * kind of like house robbing. you cannot rob 2 connected houses. + */ + + public int deleteAndEarnBottomUp(int[] nums) { + int n = 10001; + int[] values = new int[n]; + for (int num : nums) + values[num] += num; + + int take = 0, skip = 0; + for (final int value : values) { + + final int temp = Math.max(skip + value, take); + skip = take; + take = temp; + } + return take; + } +} diff --git a/src/dynamicProgramming/lcs/EditDistance.java b/src/main/java/dynamicProgramming/lcs/EditDistance.java similarity index 80% rename from src/dynamicProgramming/lcs/EditDistance.java rename to src/main/java/dynamicProgramming/lcs/EditDistance.java index c7e4a4f..a84ee9b 100644 --- a/src/dynamicProgramming/lcs/EditDistance.java +++ b/src/main/java/dynamicProgramming/lcs/EditDistance.java @@ -1,7 +1,6 @@ package dynamicProgramming.lcs; /** - * Date 07/07/2014 * * @author Tushar Roy * @@ -95,6 +94,29 @@ public int minDistance(String word1, String word2) { return dp[word1.length()][word2.length()]; } + + Integer[][] cache; + public int minDistanceTopDown(String word1, String word2) { + cache= new Integer[word1.length()][word2.length()]; + return recursionHelper(word1,word2,0,0); + } + + public int recursionHelper(String word1, String word2, int idx1, int idx2){ + if(idx1>=word1.length()) return word2.length()-idx2; + if(idx2>=word2.length()) return word1.length()-idx1; + + if(cache[idx1][idx2]!=null) return cache[idx1][idx2]; + + int result=0; + if(word1.charAt(idx1)==word2.charAt(idx2)){ + result+= recursionHelper(word1,word2,idx1+1,idx2+1); + }else{ + result+= 1+ Math.min(recursionHelper(word1,word2,idx1+1,idx2+1), + Math.min(recursionHelper(word1,word2,idx1+1,idx2),recursionHelper(word1,word2,idx1,idx2+1))); + } + + return cache[idx1][idx2]=result; + } private int min(int a, int b, int c) { int l = Math.min(a, b); return Math.min(l, c); diff --git a/src/main/java/dynamicProgramming/lcs/LongestCommonSubsequence.java b/src/main/java/dynamicProgramming/lcs/LongestCommonSubsequence.java new file mode 100644 index 0000000..302a9ab --- /dev/null +++ b/src/main/java/dynamicProgramming/lcs/LongestCommonSubsequence.java @@ -0,0 +1,72 @@ +package dynamicProgramming.lcs; + +import java.util.Arrays; + +public class LongestCommonSubsequence { + + // mistake i normally would assume is dp[0][0]=1, but actually it's not + + public static void main(String[] args) { + String str1 = "ABCD"; + String str2 = "AEDB"; + + System.out.println(longestCommonSubSeqPrint(str1, str2)); + + } + + public static int longestCommonSubsequence(String text1, String text2) { + if (text1 == null || text2 == null) return 0; + + int[][] dp = new int[text1.length() + 1][text2.length() + 1]; + + for (int i = 1; i <= text1.length(); i++) { + for (int j = 1; j <= text2.length(); j++) { + if (text1.charAt(i - 1) == text2.charAt(j - 1)) { + dp[i][j] = 1 + dp[i - 1][j - 1]; // previously matched characters + } else { + dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]); + } + } + } + + return dp[text1.length()][text2.length()]; + } + + Integer[][] cache; + + public int longestCommonSubsequenceTopDown(String text1, String text2) { + cache = new Integer[text1.length() + 1][text2.length() + 1]; + return recursionHelper(text1, text2, text1.length() - 1, text2.length() - 1); + } + + public int recursionHelper(String text1, String text2, int index1, int index2) { + if (index1 < 0 || index2 < 0) return 0; + if (cache[index1][index2] != null) return cache[index1][index2]; + + if (text1.charAt(index1) == text2.charAt(index2)) { + return cache[index1][index2] = 1 + recursionHelper(text1, text2, index1 - 1, index2 - 1); + } else { + return cache[index1][index2] = Math.max(recursionHelper(text1, text2, index1 - 1, index2),recursionHelper(text1, text2, index1, index2 - 1)); + } + } + + private static String longestCommonSubSeqPrint(String str1, String str2) { + String[][] dp = new String[str1.length() + 1][str2.length() + 1]; + for (String[] strings : dp) { + Arrays.fill(strings, ""); + } + for (int i = 1; i <= str1.length(); i++) { + for (int j = 1; j <= str2.length(); j++) { + if (str1.charAt(i - 1) == str2.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1] + str1.charAt(i - 1); + } else { + dp[i][j] = dp[i - 1][j].length() > dp[i][j - 1].length() ? dp[i - 1][j] : dp[i][j - 1]; + } + } + } + return dp[str1.length()][str2.length()]; + } + +} + + diff --git a/src/dynamicProgramming/lcs/LongestCommonSubstring.java b/src/main/java/dynamicProgramming/lcs/LongestCommonSubstring.java similarity index 100% rename from src/dynamicProgramming/lcs/LongestCommonSubstring.java rename to src/main/java/dynamicProgramming/lcs/LongestCommonSubstring.java diff --git a/src/main/java/dynamicProgramming/lcs/LongestIncreasingSubsequence.java b/src/main/java/dynamicProgramming/lcs/LongestIncreasingSubsequence.java new file mode 100644 index 0000000..d841989 --- /dev/null +++ b/src/main/java/dynamicProgramming/lcs/LongestIncreasingSubsequence.java @@ -0,0 +1,133 @@ +package dynamicProgramming.lcs; + +import java.util.Arrays; + +/** + * Solve the LIS subproblem for each snippet of the array ending between 1, 2, + * 3, ... and so on until nums.length - 1 (inclusive) + *

+ * Ex: + *

+ * [-2, 1, 2, 3] + *

+ * [-2] from index 0 to index 0 [-2, 1] from index 0 to index 1 [-2, 1, 2] from + * index 0 to index 2 [-2, 1, 2, 3] from index 0 to index 3 + *

+ * Our answer is the maximum LNDS found between all subproblems we solve along + * the way. + *

+ * Time complexity is O(n^2). + */ +public class LongestIncreasingSubsequence { + + public static void main(String[] args) { + int[] nums = {10, 22, 9, 33, 21, 50, 41, 60, 80}; + lisLength(nums); + } + + private static void lisLength(int[] nums) { + int[] result = new int[nums.length]; + Arrays.fill(result, 1); + int maximumSoFar = 1; + for (int i = 1; i < nums.length; i++) { + for (int j = 0; j < i; j++) { + if (nums[i] > nums[j]) { + result[i] = Math.max(result[i], result[j] + 1); + } + } + maximumSoFar = Math.max(maximumSoFar, result[i]); + } + System.out.println(Arrays.toString(result)); + System.out.println(maximumSoFar); + } + + public int lengthOfLISBottomUp(int[] nums) { + //there were two chaning variable in recursive solution curr and prev + //so we need a 2d matrix + //length decision:-prev will go max upto nums.length so will take nums.length+1 + // curr will go max upto nums.length-1 so will take nums.length + //for initialization of dp matrix initialize it with -1 + + int[][] dp = new int[nums.length + 1][nums.length]; + for (int[] x : dp) { + Arrays.fill(x, -1); + } + return solve(nums, -1, 0, dp); + } + + public int solve(int[] nums, int prevIndex, int curr, int[][] dp) { + if (curr == nums.length) { + return 0; + } + + if (dp[prevIndex + 1][curr] != -1) { + return dp[prevIndex + 1][curr]; + } + + if (prevIndex < 0 || nums[curr] > nums[prevIndex]) { + dp[prevIndex + 1][curr] = Math.max(1 + solve(nums, curr, curr + 1, dp), + solve(nums, prevIndex, curr + 1, dp)); + } else { + dp[prevIndex + 1][curr] = solve(nums, prevIndex, curr + 1, dp); + } + return dp[prevIndex + 1][curr]; + } + + /** + * https://www.youtube.com/watch?v=qW1O1a40-No&ab_channel=AryanMittal + *

+ * Idea is to prepare a result array, the result array will be sorted obviously because, we are looking for + * LIS. + * case i) if current element arr[i] is greater that result[result.length-1] append to result + * case ii) else we need to look for a suitable position in the result arr for that element arr[i] + * which has arr[i-1]>=arr[i]= + * arr[]= {2,5,3,7,11,8,10,13,6} + * result[]={} + * when i=2(arr[i]=3) + * result=[2,5] + * we need to see a position for 3 to accommodate, do a binary search in [2,5], we'll get index 1 + * so we modify the result = [2,3] *Note the length is not changed + *

+ * when i=6 (arr[i]=8) + * result=[2,3,7,11] we need to check for a position, do a binary search in [2,3,6,7], we'll get index 3 + * result=[2,3,7,8] + *

+ * when i=8(arr[i]=6) + * result=[2,3,7,8,10,13] or [2,5,7,8,10,13] do a binary search , we'll get index 2 + * result=[2,3,6,8,10,13] at this point we are not bothered about the correctness of result + * all we need is the length + */ + public static int lengthOfLIS(int[] nums) { + if (nums == null || nums.length == 0) + return 0; + + int n = nums.length, len = 0; + int[] increasingSequence = new int[n]; + increasingSequence[len++] = nums[0]; + for (int i = 1; i < n; i++) { + if (nums[i] > increasingSequence[len - 1]) + increasingSequence[len++] = nums[i]; + else { + int position = findPositionToReplace(increasingSequence, 0, len - 1, nums[i]); + increasingSequence[position] = nums[i]; + } + } + return len; + } + + public static int findPositionToReplace(int[] a, int low, int high, int x) { + int mid; + while (low < high) { + mid = low + (high - low) / 2; + if (a[mid] < x) { + low = mid + 1; + } else { + high = mid; + } + } + return low; + } + +} diff --git a/src/main/java/dynamicProgramming/lcs/LongestStringChain.java b/src/main/java/dynamicProgramming/lcs/LongestStringChain.java new file mode 100644 index 0000000..c46305a --- /dev/null +++ b/src/main/java/dynamicProgramming/lcs/LongestStringChain.java @@ -0,0 +1,89 @@ +package dynamicProgramming.lcs; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * https://leetcode.com/problems/longest-string-chain/ + */ +public class LongestStringChain { + + /** + * Algorithm + * Initialize a set (wordsPresent) and add all the words in the list to the set. This set will be used to check if a word is present in the list. + * Initialize a map (memo) having key type as String and value type as Integer. This map will store the length of the longest possible word sequence where the key is the last word in the sequence. + * Iterate over the list. For each word in the list perform a depth-first search. + * In the DFS, consider the current word (currentWord) as the last word in the word sequence. + * If currentWord was encountered previously we just return its corresponding value in the map memo. + * Initialize maxLength to 1. + * Iterate over the entire length of the currentWord. + * Create all possible words (newWord) by taking out one character at a time. + * If newWord is present in the set perform a DFS with this word and store the intermediate result in a variable currentLength. + * Update the maxLength so that it contains the length of the longest sequence possible where the currentWord is the end word. + * Set the maxLength as the value for currentWord (key) in the map. + * Return maxLength. + */ + private int dfs(Set words, Map memo, String currentWord) { + // If the word is encountered previously we just return its value present in the map (memoization). + if (memo.containsKey(currentWord)) { + return memo.get(currentWord); + } + // This stores the maximum length of word sequence possible with the 'currentWord' as the + int maxLength = 1; + StringBuilder sb = new StringBuilder(currentWord); + + // creating all possible strings taking out one character at a time from the `currentWord` + for (int i = 0; i < currentWord.length(); i++) { + sb.deleteCharAt(i); + String newWord = sb.toString(); + // If the new word formed is present in the list, we do a dfs search with this newWord. + if (words.contains(newWord)) { + int currentLength = 1 + dfs(words, memo, newWord); + maxLength = Math.max(maxLength, currentLength); + } + sb.insert(i, currentWord.charAt(i)); + } + memo.put(currentWord, maxLength); + + return maxLength; + } + + public int longestStrChain(String[] words) { + Map memo = new HashMap<>(); + Set wordsPresent = new HashSet<>(); + Collections.addAll(wordsPresent, words); + int ans = 0; + for (String word : words) { + ans = Math.max(ans, dfs(wordsPresent, memo, word)); + } + return ans; + } + + public int longestStrChainBottomUp(String[] words) { + Map cache = new HashMap<>(); + + + Arrays.sort(words, (a, b) -> Integer.compare(a.length(), b.length())); + + int result = 0; + + for (String word : words) { + int count = 0; + + for (int i = 0; i < word.length(); i++) { + String temp = new StringBuilder(word).deleteCharAt(i).toString(); + count = Math.max(count, cache.getOrDefault(temp, 0) + 1); + + } + + cache.put(word, count); + result = Math.max(result, count); + } + + return result; + } +} diff --git a/src/dynamicProgramming/lcs/MaximumContiguousSubarraySum.java b/src/main/java/dynamicProgramming/lcs/MaximumContiguousSubarraySum.java similarity index 100% rename from src/dynamicProgramming/lcs/MaximumContiguousSubarraySum.java rename to src/main/java/dynamicProgramming/lcs/MaximumContiguousSubarraySum.java diff --git a/src/main/java/dynamicProgramming/lcs/MaximumLengthRepeatedSubarray.java b/src/main/java/dynamicProgramming/lcs/MaximumLengthRepeatedSubarray.java new file mode 100644 index 0000000..c961272 --- /dev/null +++ b/src/main/java/dynamicProgramming/lcs/MaximumLengthRepeatedSubarray.java @@ -0,0 +1,25 @@ +package dynamicProgramming.lcs; + +/** + * https://leetcode.com/problems/maximum-length-of-repeated-subarray/ + * + * Idea is same as Longest common substring, in case of subsequence only we'll do if(nums1[i-1]!=nums2[j-1]) + */ +public class MaximumLengthRepeatedSubarray { + + public int findLength(int[] nums1, int[] nums2) { + int[][] dp = new int[nums1.length + 1][nums2.length + 1]; + + int result = 0; + for (int i = 1; i <= nums1.length; i++) { + for (int j = 1; j <= nums2.length; j++) { + if (nums1[i - 1] == nums2[j - 1]) { + dp[i][j] = 1 + dp[i - 1][j - 1]; + result = Math.max(result, dp[i][j]); + } + } + } + + return result; + } +} diff --git a/src/dynamicProgramming/lcs/MaximumSumIncreasingSubsequence.java b/src/main/java/dynamicProgramming/lcs/MaximumSumIncreasingSubsequence.java similarity index 80% rename from src/dynamicProgramming/lcs/MaximumSumIncreasingSubsequence.java rename to src/main/java/dynamicProgramming/lcs/MaximumSumIncreasingSubsequence.java index d947a54..7001da6 100644 --- a/src/dynamicProgramming/lcs/MaximumSumIncreasingSubsequence.java +++ b/src/main/java/dynamicProgramming/lcs/MaximumSumIncreasingSubsequence.java @@ -14,18 +14,14 @@ static int maxSumIS(int arr[], int n) { System.out.println(arr[i] + ">" + arr[j] + "&&" + msis[i] + "<" + (msis[j] + arr[i])); if (arr[i] > arr[j] && msis[i] < msis[j] + arr[i]) msis[i] = msis[j] + arr[i]; + max = Math.max(max,msis[i]); } } - // Pick maximum of all msis values - for (i = 0; i < n; i++) - if (max < msis[i]) - max = msis[i]; - return max; } public static void main(String args[]) { - int arr[] = new int[] { 1, 1001, 2, 3, 100, 4, 5 }; + int[] arr = new int[] { 1, 1001, 2, 3, 100, 4, 5 }; int n = arr.length; System.out.println("Sum of maximum sum " + "increasing subsequence is " + maxSumIS(arr, n)); } diff --git a/src/main/java/dynamicProgramming/lcs/MinimumAsciiDelete.java b/src/main/java/dynamicProgramming/lcs/MinimumAsciiDelete.java new file mode 100644 index 0000000..098262d --- /dev/null +++ b/src/main/java/dynamicProgramming/lcs/MinimumAsciiDelete.java @@ -0,0 +1,96 @@ +package dynamicProgramming.lcs; + +/** + * https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/ + *

+ * In this question we are given two strings , and asked to get the sum of ASCII values, to make string same, + * RE-WORDING question : get the sum of all characters which do not form longest Common Subsequence. + *

+ * +------+-----+-------+------+------+ + * | | "" | s (1) | e(2) | e(3) | + * +------+-----+-------+------+------+ + * | "" | 0 | 101 | 198 | 314 | + * +------+-----+-------+------+------+ + * | t(1) | 115 | 216 | 313 | 429 | + * +------+-----+-------+------+------+ + * | e(2) | 216 | 115 | 212 | 328 | + * +------+-----+-------+------+------+ + * | e(3) | 313 | | | | + * +------+-----+-------+------+------+ + */ +public class MinimumAsciiDelete { + + + public int minimumDeleteSumTopDown(String s1, String s2) { + int[][] dp = new int[s1.length() + 1][s2.length() + 1]; + + // see first row and col, in order to equate chars to "", we need to delete chars + // so we add all chars + //if string_A or string_B is empty : then our ans is sum of all ASCII of non empty string + for (int i = 1; i <= s2.length(); i++) { + dp[0][i] = dp[0][i - 1] + s2.charAt(i - 1); + } + // refer above comment + for (int i = 1; i <= s1.length(); i++) { + dp[i][0] = dp[i - 1][0] + s1.charAt(i - 1); + } + + for (int i = 1; i <= s1.length(); i++) { + for (int j = 1; j <= s2.length(); j++) { + //Of the two strings, if both of their last characters match + // then certainly the answer comes from skipping those characters. + //i.e. Answer("zca","bza") = Answer("zc","bz") + if (s1.charAt(i - 1) == s2.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1]; + } else { + //if the last characters are different then its one of the three situations: + //drop s1's last character (ASCII(s1's last) + dp[i-1][j]) + //drop s2's last character (ASCII(s2's last) + dp[i][j-1]) + // min of above 2 + //One is to delete s1.charAt(i-1) ,based on the condition that s1[0:i-1] and s2[0:j] is already the same. + //The other is to delete s2.charAt(j-1),based on the condition that s1[0:i] and s2[0:j-1] is already the same. + dp[i][j] = Math.min(dp[i - 1][j] + s1.charAt(i - 1), dp[i][j - 1] + s2.charAt(j - 1)); + } + } + } + + return dp[s1.length()][s2.length()]; + } + + + Integer[][] cache; + + public int minimumDeleteSum(String s1, String s2) { + cache = new Integer[s1.length() + 1][s2.length() + 1]; + + return recursionHelper(s1, s2, 0, 0); + + } + + public int recursionHelper(String s1, String s2, int i, int j) { + if (i >= s1.length() && j >= s2.length()) return 0; + if (cache[i][j] != null) return cache[i][j]; + if (i >= s1.length()) return getAscii(s2.substring(j)); + if (j >= s2.length()) return getAscii(s1.substring(i)); + + int result = 0; + + if (s1.charAt(i) == s2.charAt(j)) { + result += recursionHelper(s1, s2, i + 1, j + 1); + } else { + result += Math.min(recursionHelper(s1, s2, i + 1, j) + s1.charAt(i), recursionHelper(s1, s2, i, j + 1) + s2.charAt(j)); + } + + return cache[i][j] = result; + + } + + public int getAscii(String str) { + int res = 0; + for (char s : str.toCharArray()) { + res += s; + } + return res; + } + +} diff --git a/src/main/java/dynamicProgramming/lcs/NumberOfDistinctSubSequence.java b/src/main/java/dynamicProgramming/lcs/NumberOfDistinctSubSequence.java new file mode 100644 index 0000000..22f967c --- /dev/null +++ b/src/main/java/dynamicProgramming/lcs/NumberOfDistinctSubSequence.java @@ -0,0 +1,56 @@ +package dynamicProgramming.lcs; + +public class NumberOfDistinctSubSequence { + + Integer[][] cache; + + public int numDistinct(String s, String t) { + cache = new Integer[s.length() + 1][t.length() + 1]; + return recursionHelper(s, t, 0, 0); + } + + public int recursionHelper(String s, String t, int idx1, int idx2) { + + if (cache[idx1][idx2] != null) return cache[idx1][idx2]; + + if (idx1 == s.length() && idx2 < t.length()) return 0; + if (idx2 == t.length()) return 1; + + int result = 0; + // if both chars are same we skip both, and also we explore by skipping the source index to find the target char elsewhere + if (s.charAt(idx1) == t.charAt(idx2)) { + result = recursionHelper(s, t, idx1 + 1, idx2 + 1) + recursionHelper(s, t, idx1 + 1, idx2); + }else{ + // else we explore by skipping source index only because it's total ways + result += recursionHelper(s, t, idx1 + 1, idx2); + } + + + return cache[idx1][idx2] = result; + } + + /** + * Copy the recurrence relation into tabulation that's all is the trick + */ + public int numDistinctTopDown(String s, String t) { + + int[][] dp = new int[s.length()+1][t.length()+1]; + + for(int i=0;i<=s.length();i++){ + dp[i][0]=1; + } + + for(int i=1;i<=s.length();i++){ + for(int j=1;j<=t.length();j++){ + + if(s.charAt(i-1)==t.charAt(j-1)){ + dp[i][j] = dp[i-1][j-1]+dp[i-1][j]; + }else{ + dp[i][j] = dp[i-1][j]; + } + } + } + + return dp[s.length()][t.length()]; + } +} diff --git a/src/main/java/dynamicProgramming/lcs/NumberOfLIS.java b/src/main/java/dynamicProgramming/lcs/NumberOfLIS.java new file mode 100644 index 0000000..7d56c21 --- /dev/null +++ b/src/main/java/dynamicProgramming/lcs/NumberOfLIS.java @@ -0,0 +1,76 @@ +package dynamicProgramming.lcs; + +import java.util.Arrays; + +/** + * tricky lis + * https://www.youtube.com/watch?v=_eHbuLHo6pM&ab_channel=LearnCodeRepeat + * + * While you're iterating over all the elements from '0' to 'i-1', + * + * First check whether the addition of the current element will form a LIS or not. + * (This statements denotes to check condition of nums[i] > nums[j]) + * + * If a LIS is forming with the inclusion of element nums[i], then only a simple problem remains - Whether a subsequece of an equal length is already present or not. + * + * To resolve this problem, check whether you've already acheived a LIS of that length or not by simply comparing with the count[i]. + * + * If yes, the count all the subsequences that have been formed at index 'j' and add them to the subsequences formed without subsequences ending at nums[j]. + * (This statement denotes - dp[j] + 1 == dp[i]) + * + * If not, then count all the subsequences formed with the subsequences ending at nums[j] + * (This statement denotes - dp[j] + 1 > dp[i]) + * + * Arr => 1, 3, 5, 4, 7 + * dp => 1, 2, 3, 3, 4 + * cnt=> 1, 1, 1, 1, 2 when i at 7 and j at 4 dp[j] + 1 == dp[i] so count is 2 + */ +public class NumberOfLIS { + public int findNumberOfLIS(int[] nums) { + int n = nums.length; + //dp[i] will store the length of Longest Increasing Subsequence, ending at nums[i]. + int[] dp = new int[n]; + //count[i] will store the total number of Longest Increasing Subsequences, ending at nums[i]. + int[] count = new int[n]; + + Arrays.fill(dp,1); + Arrays.fill(count,1); + //lis : length of Longest Increasing Subsequence. + int lis = 0; + //res : total number of subsequences of length lis. + int res = 0; + for (int i = 1; i < n; i++) { + //Checking it's previous values. + for (int j = 0; j < i; j++) { + //If any previous value of nums[i] is less than it, then only it can be appended(as we know the + //subsequence would have ended at nums[j]). + if (nums[j] < nums[i]) { + //If dp[i] is equal to dp[j] + 1, meaning a different sequence has been found of same + //length, so increase count[i] by count[j]. + if (dp[i] == dp[j] + 1) { + count[i] += count[j]; + } + //Else, if dp[i] is less than dp[j] + 1, meaning length will increase as sequence will have a + //new element, so store dp[j] + 1 in dp[i] and count[j] in count[i]. + else if (dp[i] < dp[j] + 1) { + dp[i] = dp[j] + 1; + count[i] = count[j]; + } + } + } + + //If lis is equal to dp[i], meaning a new sequence is found of same length, so add count[i] in res. + if (lis == dp[i]) { + res += count[i]; + } + //Else if lis is less than dp[i], meaning a new sequence is formed of greater length, so store the + //new increased length in lis and count[i] in res. + else if (lis < dp[i]) { + lis = dp[i]; + res = count[i]; + } + } + + return res; + } +} diff --git a/src/main/java/dynamicProgramming/lcs/RussianDollEnvelope.java b/src/main/java/dynamicProgramming/lcs/RussianDollEnvelope.java new file mode 100644 index 0000000..318277e --- /dev/null +++ b/src/main/java/dynamicProgramming/lcs/RussianDollEnvelope.java @@ -0,0 +1,63 @@ +package dynamicProgramming.lcs; + +import java.util.Arrays; + +public class RussianDollEnvelope { + + public int maxEnvelopes(int[][] envelopes) { + + /** + * sort envelopes by width (envelopes[i][0]), then we only need to consider height + * //if two envelopes have same width, sort them by descending order + * //because [3, 4] cannot contains [3, 3], so we need to put [3, 4] before [3, 3] when sorting, + * //otherwise it will be counted as an increasing number if the order is [3, 3], [3, 4] + * //but we actually do not want to count them as valid russian doll envelopes + * + * prevent calculating the envelope with the same width? For example [3, 1] [3, 2] [3, 3] will get 3, but [3, 3], [3, 2], [3, 1] will get 1. + */ + Arrays.sort(envelopes, (a, b) -> { + if (a[0] == b[0]) return Integer.compare(b[1], a[1]); + return Integer.compare(a[0], b[0]); + }); + int result = 0; + + /** + * //KEY POINTS: after sorting them by width with increasing order, we need to find Longest Increasing Subsequence + * //by traversing height of each envelope, then we get the final result + * //store tails of each increasing subsequence with different length + * /*eg: 3, 5, 1, 8, 2, 12 + * * 1 + * * 1, 2 + * * 3, 5, 8 + * * 3, 5, 8, 12 + * * tails = {1, 2, 8, 12} + * + * //we do not care about what elements are in each subsequence, we only care about + * //tails of them, because every time we only compare with their tails to decide + * //which subsequence could we add new item and update the entire structure + */ + int[] increasingHeight = new int[envelopes.length]; + + for (int[] envelope : envelopes) { + + int left = 0; + int right = result; + while (left < right) { + + int mid = left + (right - left) / 2; + if (increasingHeight[mid] < envelope[1]) { + left = mid + 1; + } else { + right = mid; + } + } + + increasingHeight[left] = envelope[1]; + if (left == result) { + result++; + } + } + + return result; + } +} diff --git a/src/main/java/dynamicProgramming/lcs/ShortestCommonSupersequence.java b/src/main/java/dynamicProgramming/lcs/ShortestCommonSupersequence.java new file mode 100644 index 0000000..d608268 --- /dev/null +++ b/src/main/java/dynamicProgramming/lcs/ShortestCommonSupersequence.java @@ -0,0 +1,65 @@ +package dynamicProgramming.lcs; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/shortest-common-supersequence/ + *

+ *The idea is very simple. The result string should contain all characters of s1 and s2 discarding the common ones. + * -> S1+S2-LCS + * because characters appearing in LCS are coming twice in the result. So count them only once. + * + * O(MN) *O(String len) if we store string in DP + * else O(MN) + * + * Input: str1 = "abac", str2 = "cab" + * Output: "cabac" + * Explanation: + * str1 = "abac" is a subsequence of "cabac" because we can delete the first "c". + * str2 = "cab" is a subsequence of "cabac" because we can delete the last "ac". + * The answer provided is the shortest such string that satisfies these properties. + */ +public class ShortestCommonSupersequence { + + public String shortestCommonSuperSequence(String str1, String str2) { + + String lcs = longestCommonSubSeq(str1, str2); + int i = 0; + int j = 0; + + StringBuilder sb = new StringBuilder(); + for (char c : lcs.toCharArray()) { + while (i < str1.length() && str1.charAt(i) != c) sb.append(str1.charAt(i++)); + while (j < str2.length() && str2.charAt(j) != c) sb.append(str2.charAt(j++)); + sb.append(c); + i++; + j++; + } + sb.append(str1.substring(i)); + sb.append(str2.substring(j)); + + return sb.toString(); + } + + public static void main(String[] args) { + new ShortestCommonSupersequence().shortestCommonSuperSequence("abac","cab"); + } + + public String longestCommonSubSeq(String str1, String str2) { + String[][] dp = new String[str1.length() + 1][str2.length() + 1]; + for (String[] s : dp) { + Arrays.fill(s, ""); + } + for (int i = 1; i < dp.length; i++) { + for (int j = 1; j < dp[0].length; j++) { + if (str1.charAt(i - 1) == str2.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1] + str1.charAt(i - 1); + } else { + dp[i][j] = dp[i - 1][j].length() > dp[i][j - 1].length() ? dp[i - 1][j] : dp[i][j - 1]; + } + } + } + + return dp[str1.length()][str2.length()]; + } +} diff --git a/src/main/java/dynamicProgramming/lcs/TwoStringInterleavingToFormThird.java b/src/main/java/dynamicProgramming/lcs/TwoStringInterleavingToFormThird.java new file mode 100644 index 0000000..7a9abdf --- /dev/null +++ b/src/main/java/dynamicProgramming/lcs/TwoStringInterleavingToFormThird.java @@ -0,0 +1,71 @@ +package dynamicProgramming.lcs; + +import java.util.Arrays; + +/** + * http://www.geeksforgeeks.org/check-whether-a-given-string-is-an-interleaving-of-two-other-given-strings-set-2/ + */ +public class TwoStringInterleavingToFormThird { + + public boolean isInterleave(String s1, String s2, String s3) { + int m = s1.length(); + int n = s2.length(); + if (m + n != s3.length()) return false; + boolean[][] dp = new boolean[m + 1][n + 1]; + dp[0][0] = true; + for (int i = 1; i <= m; i++) { + if (dp[i - 1][0] && s1.charAt(i - 1) == s3.charAt(i - 1)) { + dp[i][0] = true; + } + } + for (int i = 1; i <= n; i++) { + if (dp[0][i - 1] && s2.charAt(i - 1) == s3.charAt(i - 1)) { + dp[0][i] = true; + } + } + for (int i = 1; i <= m; i++) { + for (int j = 1; j <= n; j++) { + if (s1.charAt(i - 1) == s3.charAt(i + j - 1) && dp[i - 1][j]) { + dp[i][j] = true; + } + if (s2.charAt(j - 1) == s3.charAt(i + j - 1) && dp[i][j - 1]) { + dp[i][j] = true; + } + } + } + return dp[m][n]; + } + + public static void main(String args[]) { + String str1 = "aab"; + String str2 = "axy"; + String str3 = "aaxaby"; + TwoStringInterleavingToFormThird sti = new TwoStringInterleavingToFormThird(); + System.out.println(sti.isInterleave(str1, str2, str3)); + } + + public boolean isInterleave(String s1, int i, String s2, int j, String s3, int k, Integer[][] memo) { + if (i == s1.length()) { + return s2.substring(j).equals(s3.substring(k)); + } + if (j == s2.length()) { + return s1.substring(i).equals(s3.substring(k)); + } + if (memo[i][j] !=null) { + return memo[i][j] == 1; + } + boolean ans = s3.charAt(k) == s1.charAt(i) && isInterleave(s1, i + 1, s2, j, s3, k + 1, memo) + || s3.charAt(k) == s2.charAt(j) && isInterleave(s1, i, s2, j + 1, s3, k + 1, memo); + + memo[i][j] = ans ? 1 : 0; + return ans; + } + public boolean isInterleaveRecursive(String s1, String s2, String s3) { + if (s1.length() + s2.length() != s3.length()) { + return false; + } + Integer[][] memo= new Integer[s1.length()][s2.length()]; + + return isInterleave(s1, 0, s2, 0, s3, 0, memo); + } +} diff --git a/src/main/java/dynamicProgramming/lcs/WildCardMatching.java b/src/main/java/dynamicProgramming/lcs/WildCardMatching.java new file mode 100644 index 0000000..b054e03 --- /dev/null +++ b/src/main/java/dynamicProgramming/lcs/WildCardMatching.java @@ -0,0 +1,123 @@ +package dynamicProgramming.lcs; + +/** + * General Idea: Credit: https://leetcode.com/problems/wildcard-matching/discuss/370736/Detailed-Intuition-From-Brute-force-to-Bottom-up-DP + * The idea is pretty straightforward : scan S and P while there is a match between the current character of S and the current character of P. + * If we reach the end of both strings while there is still a match, return True, otherwise return False. + * The scan is done by having a pointer in S and a pointer in P. + + Example: S="code" + The character 'c' of S matches the first character of P if the first character of P is: + + 'c' + '?' + '*' + + Case 1: + When the first character of P is a lowercase letter different from 'c', return False. + + Case 2: + If the first character of P is 'c' or '?', we move both pointers one step to the right. + + Case 3: + If the first character of P is '*', we have 2 possibilities: + + - '*' matches 0 character : in this case we move the pointer in P one step, ie will ignore the whole pattern + - '*' matches 1 or more characters : in this case we move the pointer in S one step, ie we consider pattern + And we continue like this for each two positions taken by the two pointers. + + - If we reach the end of P but there is still characters from S, simply return .. False ! + - If we reach the end of S and there is still characters from P, the only case when there is a match is that all the remaining characters in P are '*', + in this case these stars will be matched with the empty string. + **/ +public class WildCardMatching { + + public boolean isMatch(String s, String p) { + + return isMatchApproach1Helper(0, 0, s, p); + } + + public boolean isMatchApproach1Helper(int tIdx, int pIdx, String text, String pattern) { + + // reached the end of both S and P + if (tIdx == text.length() && pIdx == pattern.length()) { + return true; + } + // there are still characters in S => there is no match + else if (pIdx == pattern.length()) { + return false; // Can't have a non-empty s match an empty p. + } + // if we reached end of text and pattern is still left. + // Try to see if p at or after this stage is only * or ** or *** etc. Only way to match an empty text. + else if (tIdx == text.length()) { + return pattern.charAt(pIdx) == '*' && isMatchApproach1Helper(tIdx, pIdx + 1, text, pattern); + } + // Here cuz text & pattern match atleast a char + else if (text.charAt(tIdx) == pattern.charAt(pIdx) || pattern.charAt(pIdx) == '?') { + // Match here if strs from next index onward also are a match. Delegate job to recursive func for latter. + return isMatchApproach1Helper(tIdx + 1, pIdx + 1, text, pattern); + } + + // star either matches 0 or >=1 character + else if (pattern.charAt(pIdx) == '*') { + // 1: When * matches an empty seq, it's work is done. Hence, the next stage to check match for is w/o *. + // Also, there could be *s in line. So, consuming this *, could exhibit new p with next fresh *. + // 2: '*' can match seq of chars. Hence, * kept. Further rec stages could use it to match more chars/empty. + return isMatchApproach1Helper(tIdx, pIdx + 1, text, pattern) + || isMatchApproach1Helper(tIdx + 1, pIdx, text, pattern); + } + + return false; + } + + /******************* + * Approach 3: Bottom Up Tabulation: https://www.youtube.com/watch?v=3ZDZ-N0EPV0 + * Bottom-up the smallest is (0, 0) + * + * | dp[i-1][j-1] if str[i] == pattern[j] || pattern[j] == '?' + * | + * | if pattern[j-1] == '*' + * dp[i][j] = | dp[i][j-1] || dp[i-1][j] + * | + * | False + * + * Time Complexity : O(m * n) + * Space Complexity : O(m * n) + **********************************/ + public boolean isMatchBottomUp(String s, String t) { + //First, we need to create a 2d dp table dp. The size of this table is (s.size() + 1) * (p.size() + 1). + // We introduce +1 here to better handle the edge cases where we have an empty string or an empty pattern. + boolean[][] dp= new boolean[s.length()+1][t.length()+1]; + + //When both the string and the pattern are empty. + //Always match. dp[0][0] = true + dp[0][0]= true; + + for(int i=1;i<=t.length();i++){ + if(t.charAt(i-1)=='*') + dp[0][i]= dp[0][i-1]; + } + + for(int i=1;i<=s.length();i++){ + for(int j=1;j<=t.length();j++){ + + if(t.charAt(j-1)=='?' || s.charAt(i-1)==t.charAt(j-1)){ + dp[i][j]=dp[i-1][j-1]; + + }else if(t.charAt(j-1)=='*'){ + dp[i][j]= dp[i-1][j] || dp[i][j-1]; + }else{ + dp[i][j]=false; + } + } + } + return dp[s.length()][t.length()]; + } + + public static void main(String args[]) { + WildCardMatching wcm = new WildCardMatching(); + System.out.println(wcm.isMatch("xbylmz", "x?y***z")); + + } + +} \ No newline at end of file diff --git a/src/main/java/dynamicProgramming/matrix/MatrixMultiplicationCost.java b/src/main/java/dynamicProgramming/matrix/MatrixMultiplicationCost.java new file mode 100644 index 0000000..bd53dd9 --- /dev/null +++ b/src/main/java/dynamicProgramming/matrix/MatrixMultiplicationCost.java @@ -0,0 +1,43 @@ +package dynamicProgramming.matrix; + +/** + * http://www.geeksforgeeks.org/dynamic-programming-set-8-matrix-chain-multiplication/ + * https://www.youtube.com/watch?v=vgLJZMUfnsU&t=316s + */ +public class MatrixMultiplicationCost { + + + public static int matrixMultiplication(int[] arr, int N) { + Integer[][] dp = new Integer[N + 1][N + 1]; + return recursionHelper(arr, 1, N - 1, dp); + } + + public static int recursionHelper(int[] arr, int i, int j, Integer[][] dp) { + if (i == j) return 0; + if (dp[i][j] != null) return dp[i][j]; + int min = Integer.MAX_VALUE; +// Run a loop from 'i' to 'j' - 1 and calculate for all possible combination + for (int k = i; k < j; k++) { + min = Math.min(min, arr[i - 1] * arr[k] * arr[j] + recursionHelper(arr, i, k, dp) + recursionHelper(arr, k + 1, j, dp)); + } + + return dp[i][j] = min; + } + + public static int matrixMultiplicationTabulation(int[] arr, int N) { + int[][] dp = new int[N][N]; + + for (int i = N - 1; i > 0; i--) { + for (int j = i + 1; j < N; j++) { + + int min = Integer.MAX_VALUE; + for (int k = i; k < j; k++) { + min = Math.min(min, arr[i - 1] * arr[k] * arr[j] + dp[i][k] + dp[k + 1][j]); + } + dp[i][j] = min; + } + } + + return dp[1][N - 1]; + } +} \ No newline at end of file diff --git a/src/main/java/dynamicProgramming/matrix/MaximumSquareDP.java b/src/main/java/dynamicProgramming/matrix/MaximumSquareDP.java new file mode 100644 index 0000000..b5a4a1c --- /dev/null +++ b/src/main/java/dynamicProgramming/matrix/MaximumSquareDP.java @@ -0,0 +1,51 @@ +package dynamicProgramming.matrix; + +class MaximumSquareDP { + public int maximalSquare(char[][] matrix) { + int[][] dp = new int[matrix.length][matrix[0].length]; + int result = 0; + for (int i = 0; i < matrix[0].length; i++) { + dp[0][i] = matrix[0][i] == '1' ? 1 : 0; + result = Math.max(result, dp[0][i]); + } + for (int i = 0; i < matrix.length; i++) { + dp[i][0] = matrix[i][0] == '1' ? 1 : 0; + result = Math.max(result, dp[i][0]); + } + + for (int i = 1; i < matrix.length; i++) { + for (int j = 1; j < matrix[0].length; j++) { + if (matrix[i][j] == '0') continue; + + dp[i][j] = 1 + Math.min(dp[i - 1][j], Math.min(dp[i - 1][j - 1], dp[i][j - 1])); + result = Math.max(result, dp[i][j]); + } + } + + return result * result; + } + + public int maximalSquareRecursion(char[][] matrix) { + Integer[][] cache = new Integer[matrix.length][matrix[0].length]; + int result = 0; + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix[0].length; j++) { + if (matrix[i][j] == '1') { + result = Math.max(result, dfs(matrix, cache, i, j)); + } + } + } + + return result * result; + } + + public int dfs(char[][] matrix, Integer[][] cache, int i, int j) { + if (i >= matrix.length || j >= matrix[0].length || i < 0 || j < 0 || matrix[i][j] == '0') return 0; + + if (cache[i][j] != null) return cache[i][j]; + + cache[i][j] = 1 + Math.min(dfs(matrix, cache, i + 1, j), Math.min(dfs(matrix, cache, i + 1, j + 1), dfs(matrix, cache, i, j + 1))); + return cache[i][j]; + } +} + diff --git a/src/main/java/dynamicProgramming/matrix/MinCostPath.java b/src/main/java/dynamicProgramming/matrix/MinCostPath.java new file mode 100644 index 0000000..f1d04e1 --- /dev/null +++ b/src/main/java/dynamicProgramming/matrix/MinCostPath.java @@ -0,0 +1,52 @@ +package dynamicProgramming.matrix; + +/** + * http://www.geeksforgeeks.org/dynamic-programming-set-6-min-cost-path/ + */ +public class MinCostPath { + + public int minPathSum1(int[][] grid) { + + for(int i=1;i 0) { + min = Math.min(min, matrix[i - 1][j - 1]); + } + + if (j < n - 1) { + min = Math.min(min, matrix[i - 1][j + 1]); + } + + matrix[i][j] += min; + } + } + + return Arrays.stream(matrix[m - 1]).min().getAsInt(); + } + + public static void main(String[] args) { + minFallingPathSum(new int[][]{{2, 1, 3}, + {6, 5, 4}, + {7, 8, 9}}); + } +} diff --git a/src/main/java/dynamicProgramming/oiknapsack/EqualSubsetSumPartition.java b/src/main/java/dynamicProgramming/oiknapsack/EqualSubsetSumPartition.java new file mode 100644 index 0000000..e1676c6 --- /dev/null +++ b/src/main/java/dynamicProgramming/oiknapsack/EqualSubsetSumPartition.java @@ -0,0 +1,108 @@ +package dynamicProgramming.oiknapsack; + +import java.util.Arrays; + +/** + * https://www.educative.io/collection/page/5668639101419520/5633779737559040/5752754626625536 + *

+ * Given a non-empty array containing only positive integers, + * find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal. + *

+ * Input: [1, 5, 11, 5] + *

+ * Output: true + *

+ * Explanation: The array can be partitioned as [1, 5, 5] and [11]. + */ +class EqualSubsetSumPartition { + +// 0 1 2 3 4 5 +// +---+---+---+---+---+---+ +// {1} | T | T | F | F | F | F | +// +---+---+---+---+---+---+ +// {1,2} | T | T | T | T | F | F | +// +---+---+---+---+---+---+ +// {1,2,3} | T | T | T | T | T | T | +// +---+---+---+---+---+---+ +//{1,2,3,4} | T | T | T | T | T | T | +// +---+---+---+---+---+---+ + + public boolean canPartition(int[] nums) { + int totalSum = 0; + // find sum of all array elements + for (int num : nums) { + totalSum += num; + } + // if totalSum is odd, it cannot be partitioned into equal sum subset + if (totalSum % 2 != 0) return false; + int subSetSum = totalSum / 2; + int n = nums.length; + boolean dp[][] = new boolean[n + 1][subSetSum + 1]; + dp[0][0] = true; + for (int i = 1; i <= n; i++) { + int curr = nums[i - 1]; + for (int j = 0; j <= subSetSum; j++) { + if (j < curr) + dp[i][j] = dp[i - 1][j]; + else + dp[i][j] = dp[i - 1][j] || (dp[i - 1][j - curr]); + } + } + return dp[n][subSetSum]; + } + + Boolean[][] cache; + + public boolean canPartitionBottomUp(int[] nums) { + + int sum = 0; + for (int num : nums) { + sum += num; + } + if (sum % 2 == 1) return false; + int target = sum / 2; + cache = new Boolean[nums.length + 1][target + 1]; + return sumPossible(nums, 0, target); + } + + public boolean sumPossible(int[] nums, int i, int target) { + if (target < 0) return false; + if (target == 0) return true; + if (i >= nums.length) return false; + if (cache[i][target] != null) return cache[i][target]; + + return cache[i][target] = sumPossible(nums, i + 1, target - nums[i]) || sumPossible(nums, i + 1, target); + } + + public boolean canPartitionSpace(int[] nums) { + int sum = 0; + for (int i : nums) { + sum += i; + } + + if (sum % 2 == 1) return false; + int target = sum / 2; + boolean[] dp = new boolean[target + 1]; + dp[0] = true; + + for (int num : nums) { + for (int i = target; i > 0; i--) { + + // Go from behind to preserve data! + // We only need data from the previous number + // being looked at, that means the previous row. + // If we go from behind, that information is preserved. + + if (i - num >= 0) dp[i] = dp[i] || dp[i - num]; + } + } + + return dp[target]; + } + + public static void main(String[] args) { + EqualSubsetSumPartition ps = new EqualSubsetSumPartition(); + int[] num = {2, 3, 4, 5}; + System.out.println(ps.canPartition(num)); + } +} diff --git a/src/dynamicProgramming/oiknapsack/MinPartition.java b/src/main/java/dynamicProgramming/oiknapsack/MinPartition.java similarity index 100% rename from src/dynamicProgramming/oiknapsack/MinPartition.java rename to src/main/java/dynamicProgramming/oiknapsack/MinPartition.java diff --git a/src/dynamicProgramming/oiknapsack/MinimumSubsetSum.java b/src/main/java/dynamicProgramming/oiknapsack/MinimumSubsetSum.java similarity index 100% rename from src/dynamicProgramming/oiknapsack/MinimumSubsetSum.java rename to src/main/java/dynamicProgramming/oiknapsack/MinimumSubsetSum.java diff --git a/src/dynamicProgramming/oiknapsack/NumberOfUniqueWaysToMakeChange.java b/src/main/java/dynamicProgramming/oiknapsack/NumberOfUniqueWaysToMakeChange.java similarity index 100% rename from src/dynamicProgramming/oiknapsack/NumberOfUniqueWaysToMakeChange.java rename to src/main/java/dynamicProgramming/oiknapsack/NumberOfUniqueWaysToMakeChange.java diff --git a/src/dynamicProgramming/oiknapsack/O1KnapsackSpaceOptimized.java b/src/main/java/dynamicProgramming/oiknapsack/O1KnapsackSpaceOptimized.java similarity index 71% rename from src/dynamicProgramming/oiknapsack/O1KnapsackSpaceOptimized.java rename to src/main/java/dynamicProgramming/oiknapsack/O1KnapsackSpaceOptimized.java index 90633f8..13c4396 100644 --- a/src/dynamicProgramming/oiknapsack/O1KnapsackSpaceOptimized.java +++ b/src/main/java/dynamicProgramming/oiknapsack/O1KnapsackSpaceOptimized.java @@ -7,23 +7,20 @@ public static void main(String[] args) { int val[] = { 1, 2, 4, 6 }; int W = 7; int n = 4; - //System.out.println(knapSack(val, wt, n, W)); + System.out.println(findProfit(val, wt, W)); } - public int findProfit(int val[], int wt[], int W) { - int profits[][] = new int[val.length + 1][W + 1]; - for (int i = 0; i <= val.length; i++) { - for (int j = 0; j <= W; j++) { - if (i == 0 || j == 0) { - profits[i][j] = 0; - continue; - } + public static int findProfit(int[] val, int[] wt, int W) { + int[][] profits = new int[val.length + 1][W + 1]; + for (int i = 1; i <= val.length; i++) { + int currWeight = wt[i - 1]; + for (int j = 1; j <= W; j++) { // So, for each item at index ‘i’ (0 <= i < items.length) and capacity ‘c’ (0 <= c <= capacity), we have two options: // Include the item at index ‘i’ if its weight is not more than the capacity. // In this case, we include its profit plus whatever profit we get from the remaining capacity // and from remaining items => profit[i] + dp[i-1][c-weight[i]] - if (j - wt[i - 1] >= 0) { - profits[i][j] = Math.max(profits[i - 1][j], profits[i - 1][j - wt[i - 1]] + val[i - 1]); + if (j - currWeight >= 0) { + profits[i][j] = Math.max(profits[i - 1][j], profits[i - 1][j - currWeight] + val[i - 1]); } // Exclude the item at index ‘i’. // In this case, we will take whatever profit we get from the sub-array excluding this item => dp[i-1][c] @@ -41,8 +38,8 @@ public int findProfit(int val[], int wt[], int W) { // To solve the second case, we can change our inner loop to process in the reverse direction: c:capacity-->0. // This will ensure that whenever we change a value in dp[], we will not need it again in the current iteration. - public int findProfitSpaceOptimised(int val[], int wt[], int W){ - int profits[] = new int[W + 1]; + public int findProfitSpaceOptimised(int[] val, int[] wt, int W){ + int[] profits = new int[W + 1]; // if we have only one weight we take if it's not more than the capacity for (int c=0; c<=W;c++){ if(wt[0] dp[j-A[i]] - for(int i=0; i=A[i]; j--){ + private static int unboundedKnapsack(int W, int n, + int[] val, int[] wt) + { - dp[j]= Math.max(dp[j],A[i]+dp[j-A[i]]); + // dp[i] is going to store maximum value + // with knapsack capacity i. + int dp[] = new int[W + 1]; + // Fill dp[] using above recursive formula + for(int i = 0; i <= W; i++){ + for(int j = 0; j < n; j++){ + if(wt[j] <= i){ + dp[i] = Math.max(dp[i], dp[i - wt[j]] + + val[j]); + } } } - - return dp[m]; + return dp[W]; } + } \ No newline at end of file diff --git a/src/dynamicProgramming/oiknapsack/SubsetSumProblem.java b/src/main/java/dynamicProgramming/oiknapsack/SubsetSumProblem.java similarity index 98% rename from src/dynamicProgramming/oiknapsack/SubsetSumProblem.java rename to src/main/java/dynamicProgramming/oiknapsack/SubsetSumProblem.java index ba8b0ad..22b620a 100644 --- a/src/dynamicProgramming/oiknapsack/SubsetSumProblem.java +++ b/src/main/java/dynamicProgramming/oiknapsack/SubsetSumProblem.java @@ -49,7 +49,7 @@ static void printAllSubsets(int arr[], int n, int sum) { } } } - if (dp[n - 1][sum] == false) { + if (!dp[n - 1][sum]) { System.out.println("There are no subsets with" + " sum " + sum); return; } diff --git a/src/main/java/dynamicProgramming/palindrome/CountSubStrings.java b/src/main/java/dynamicProgramming/palindrome/CountSubStrings.java new file mode 100644 index 0000000..17f918f --- /dev/null +++ b/src/main/java/dynamicProgramming/palindrome/CountSubStrings.java @@ -0,0 +1,57 @@ +package dynamicProgramming.palindrome; + +public class CountSubStrings { + public int countSubstrings(String s) { + int count = 0; + for (int i = 0; i < s.length(); i++) + count += countSubstrings(s, i, i) + countSubstrings(s, i, i + 1); + return count; + } + + private int countSubstrings(String s, int start, int end) { + int count = 0; + while (start >= 0 && end < s.length() && s.charAt(start--) == s.charAt(end++)) + count++; + return count; + } + + public static int countSubstring(String s) { + int n = s.length(); + if (n < 2) + return n; + int count = n; + boolean[][] dp = new boolean[n][n]; + + // size 1 substrings are palindromes + for (int i = 0; i < n; i++) + dp[i][i] = true; + + // for size 2 substrings, check first and last char + for (int i = 0; i + 1 < n; i++) + if (s.charAt(i) == s.charAt(i + 1)) { + dp[i][i + 1] = true; + count++; + } + + // for size = 3+ + for (int len = 2; len < n; len++) // controls the size of the substring + for (int i = 0; i + len < n; i++) { // controls the start index + int j = i + len; // end index + System.out.print(i + " - " + j + " "); + // if s.charAt(i) == s.charAt(j) means the substring's first and last are equal letters + // we don't have to check the contents, we just have to check if lower diagonal is true + // lower diagonal is the result of the content in between s.charAt(i) == s.charAt(j) + + if ((s.charAt(i) == s.charAt(j)) && dp[i + 1][j - 1]) { + dp[i][j] = true; + count++; + } + System.out.println(); + } + return count; + } + + public static void main(String[] args) { + System.out.println(countSubstring("aaaa")); + } +} diff --git a/src/dynamicProgramming/palindrome/LongestPalindromicSubsequence.java b/src/main/java/dynamicProgramming/palindrome/LongestPalindromicSubsequence.java similarity index 86% rename from src/dynamicProgramming/palindrome/LongestPalindromicSubsequence.java rename to src/main/java/dynamicProgramming/palindrome/LongestPalindromicSubsequence.java index aed5311..cadc967 100644 --- a/src/dynamicProgramming/palindrome/LongestPalindromicSubsequence.java +++ b/src/main/java/dynamicProgramming/palindrome/LongestPalindromicSubsequence.java @@ -1,5 +1,7 @@ package dynamicProgramming.palindrome; +import java.util.Arrays; + /** * Date 08/01/2014 * @@ -15,13 +17,13 @@ public class LongestPalindromicSubsequence { public int calculate1(char[] str) { - int T[][] = new int[str.length][str.length]; + int[][] T = new int[str.length][str.length]; for (int i = 0; i < str.length; i++) { T[i][i] = 1; } - for (int l = 2; l <= str.length; l++) { - for (int i = 0; i < str.length - l + 1; i++) { - int j = i + l - 1; + for (int l = 2; l < str.length; l++) { + for (int i = 0; i+l < str.length ; i++) { + int j = i + l; if (l == 2 && str[i] == str[j]) { T[i][j] = 2; } else if (str[i] == str[j]) { @@ -48,11 +50,8 @@ public int longestPalindromeSubseq(String s) { } } } - for (int i=0; i here we start j and k at same position say index 2 and go left and right // even length cbbd=> here let's say we're at index 1, we need to take 1 and 2 index to check for palindrome // the above cases are the reason for sending i and i+1 - for (int i = 0; i < len - 1; i++) { - extendPalindrome(s, i, i); //assume odd length, try to extend Palindrome as possible - extendPalindrome(s, i, i + 1); //assume even length. + for (int i = 0; i < s.length() - 1; i++) { + extend(s, i, i, maxStart, maxEnd); + extend(s, i, i + 1, maxStart, maxEnd); } - return s.substring(lo, lo + maxLen); + + return s.substring(maxStart[0], maxEnd[0] + 1); } - private static void extendPalindrome(String s, int j, int k) { - while (j >= 0 && k < s.length() && s.charAt(j) == s.charAt(k)) { - j--; - k++; + private static void extend(String s, int i, int j, int[] maxStart, int[] maxEnd) { + // loop until meet invalid match + while (i >= 0 && j < s.length() && s.charAt(i) == s.charAt(j)) { + i--; + j++; } - if (maxLen < k - j - 1) { - lo = j + 1; - maxLen = k - j - 1; + + i++; + j--; // back to the last valid match + + if (j - i + 1 > maxEnd[0] - maxStart[0] + 1) { + maxStart[0] = i; + maxEnd[0] = j; } } + public static void main(String args[]) { System.out.println(longestPalindrome("bananas")); diff --git a/src/practiceproblems/PalindromePartitioning.java b/src/main/java/dynamicProgramming/palindrome/PalindromePartitioning.java similarity index 62% rename from src/practiceproblems/PalindromePartitioning.java rename to src/main/java/dynamicProgramming/palindrome/PalindromePartitioning.java index 0f31ac8..3280e12 100644 --- a/src/practiceproblems/PalindromePartitioning.java +++ b/src/main/java/dynamicProgramming/palindrome/PalindromePartitioning.java @@ -1,4 +1,4 @@ -package practiceproblems; +package dynamicProgramming.palindrome; import java.util.ArrayList; import java.util.Collections; @@ -6,32 +6,36 @@ /** * https://leetcode.com/problems/palindrome-partitioning/ + * The aim to partition the string into all possible palindrome combinations. + * To achieve this, we must generate all possible substrings of a string by partitioning at every index + * until we reach the end of the string. + * Example, abba can be partitioned as ["a","ab","abb","abba"]. + * Each generated substring is considered as a potential candidate if it's a Palindrome */ class PalindromePartitioning { public List> partition(String s) { - if (s == null || s.length() == 0) { return Collections.emptyList(); } List> result = new ArrayList<>(); - backtrackingUtil(s, result, new ArrayList<>()); + backtrackingUtil(s, result, new ArrayList<>(), 0); return result; } - public void backtrackingUtil(String s, List> result, List tempList) { - if (s == null || s.length() == 0) { + public void backtrackingUtil(String s, List> result, List tempList, int start) { + if (start >= s.length()) { result.add(new ArrayList<>(tempList)); return; } - for (int i = 1; i <= s.length(); i++) { - String temp = s.substring(0, i); + for (int i = start; i < s.length(); i++) { + String temp = s.substring(start, i + 1); if (isPalindrome(temp)) { tempList.add(temp); - backtrackingUtil(s.substring(i, s.length()), result, tempList); + backtrackingUtil(s, result, tempList, i + 1); tempList.remove(tempList.size() - 1); } } @@ -54,4 +58,8 @@ public static void main(String[] args) { PalindromePartitioning partitioning = new PalindromePartitioning(); partitioning.partition("aab"); } -} \ No newline at end of file +} + + + + diff --git a/src/main/java/dynamicProgramming/palindrome/PalindromePartitioningII.java b/src/main/java/dynamicProgramming/palindrome/PalindromePartitioningII.java new file mode 100644 index 0000000..d227e5e --- /dev/null +++ b/src/main/java/dynamicProgramming/palindrome/PalindromePartitioningII.java @@ -0,0 +1,111 @@ +package dynamicProgramming.palindrome; + +/** + * revise + * https://leetcode.com/problems/palindrome-partitioning-ii + */ +public class PalindromePartitioningII { + + public static int minCutPalindromicSubstringVariant(String s) { + int[] cutsDp = new int[s.length()]; + for (int i = 1; i < s.length(); i++) { + cutsDp[i] = i; + } + + for (int mid = 0; mid < s.length(); mid++) { + findMin(mid, mid, cutsDp, s); + findMin(mid, mid + 1, cutsDp, s); + } + + return cutsDp[s.length() - 1]; + } + + public static void findMin(int start, int end, int[] cutsDp, String s) { + for (int i = start, j = end; i >= 0 && j < s.length() && s.charAt(i) == s.charAt(j); i--, j++) { + int newCut = i == 0 ? 0 : cutsDp[i - 1] + 1; + cutsDp[j] = Math.min(cutsDp[j], newCut); + } + } + + public static void main(String[] args) { + minCutPalindromicSubstringVariant("nooradars"); + } + + public int minCut(String s) { + int n, min; + n = s.length(); + + //cut[i] represents minimum number of cuts from String 0 to i + int[] cut = new int[n]; + + //p[i][j] represents String i to j is a palindrome or not + boolean[][] p = new boolean[n][n]; + + for (int i = 0; i < n; i++) { + min = i; // Max number of cuts is i for string length i+1 + for (int j = 0; j <= i; j++) { + // Why i - j < 3 ? + // 1. String of length 1 is always palindrome so no need to check in boolean table + // 2. String of length 2 is palindrome if Ci == Cj which is already checked in first part so no need to check again + // 3. String of length 3 is palindrome if Ci == Cj which is already checked in first part and Ci+1 and Cj-1 is same character which is always a palindrome + + // If String length >=4 + // then check if Ci == Cj and if they are equal check if String[j+1 .. i-1] is a palindrome from the boolean table + /** + * a b a | c c + * j i + * j-1 | [j, i] is palindrome + * cut(j-1) + 1 + */ + if (s.charAt(j) == s.charAt(i) && (i - j < 3 || p[j + 1][i - 1])) { + // Its a palindrome as Ci == Cj and String[j+1...i-1] is a palindrome + p[j][i] = true; + // j == 0 because String from j to i is a palindrome and it starts from first character so means no cuts needed + // Else I need a cut at jth location and it will be cuts encountered till j-1 + 1 + min = j == 0 ? 0 : Math.min(min, cut[j - 1] + 1); + } + } + cut[i] = min; + } + return cut[n - 1]; + } + + + Integer[][] cache; + + public int minCutRecursive(String s) { + cache = new Integer[s.length() + 1][s.length() + 1]; + + return recursionHelper(s, 0, s.length() - 1); + } + + public int recursionHelper(String s, int start, int end) { + if (start == end || isPalin(s, start, end)) { + return 0; + } + if (cache[start][end] != null) return cache[start][end]; + + int minCuts = end - start; + for (int i = start; i <= end; i++) { + if (isPalin(s, start, i)) { + minCuts = Math.min(minCuts, 1 + recursionHelper(s, i + 1, end)); + } + } + + return cache[start][end] = minCuts; + } + + public boolean isPalin(String s, int start, int end) { + if (start > end) return false; + + while (start < end) { + if (s.charAt(start) != s.charAt(end)) return false; + + start++; + end--; + } + + return true; + + } +} diff --git a/src/practiceproblems/BuyAndSellStockAnytime.java b/src/main/java/dynamicProgramming/stocks/BuyAndSellStockAnytime.java similarity index 69% rename from src/practiceproblems/BuyAndSellStockAnytime.java rename to src/main/java/dynamicProgramming/stocks/BuyAndSellStockAnytime.java index 9b96c88..c2388f8 100644 --- a/src/practiceproblems/BuyAndSellStockAnytime.java +++ b/src/main/java/dynamicProgramming/stocks/BuyAndSellStockAnytime.java @@ -1,4 +1,7 @@ -package practiceproblems; +package dynamicProgramming.stocks; + +import java.util.ArrayList; +import java.util.List; /** * https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ @@ -10,14 +13,17 @@ public int maxProfit(int[] prices) { for (int i = 0; i < prices.length - 1; i++) { if (prices[i + 1] > prices[i]) { total += prices[i + 1] - prices[i]; + System.out.println(prices[i + 1] +" - "+ prices[i] +" = "+(prices[i + 1] - prices[i])); } } return total; } + + public static void main(String[] args) { BuyAndSellStockAnytime stock = new BuyAndSellStockAnytime(); - int[] arr = { 7, 1, 5, 6, 4 }; + int[] arr = {200, 180, 260, 310, 40, 535, 695}; System.out.println(stock.maxProfit(arr)); } } diff --git a/src/main/java/dynamicProgramming/stocks/BuyAndSellStockAtMostTwice.java b/src/main/java/dynamicProgramming/stocks/BuyAndSellStockAtMostTwice.java new file mode 100644 index 0000000..5d19e78 --- /dev/null +++ b/src/main/java/dynamicProgramming/stocks/BuyAndSellStockAtMostTwice.java @@ -0,0 +1,74 @@ +package dynamicProgramming.stocks; + +/** + * https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/ + */ +class BuyAndSellStockAtMostTwice { + + public static void main(String args[]) { + System.out.println("Maximum Profit = " + maxProfit(new int[]{2, 30, 15, 10, 8, 25, 80})); + } + + /** + * the idea is when we find a profit which is from + * i to n, we can break it in to i to k, k+1 to n + * in this manner at each point we can calculate profit from + * (left min element to current element) and (current element to right max element) + * the second part of the above eq can be achieved by coming from right to left + * for input [3,3,5,0,0,3,1,4] + * profit from l->r [0,0,2,2,2,3,3,4] + * profit from r->l [4,4,4,4,4,3,3,0] + * this simply states that at index 2 if we come from left the profit is 2 + * and we can initiate another transaction to obtain another profit + */ + public static int maxProfit(int[] prices) { + int[] profit1 = new int[prices.length]; + int[] profit2 = new int[prices.length]; + + int min = prices[0]; + for (int i = 1; i < prices.length; i++) { + min = Math.min(min, prices[i]); + profit1[i] = Math.max(profit1[i - 1], prices[i] - min); + } + + + int max = prices[prices.length - 1]; + + for (int i = prices.length - 2; i >= 0; i--) { + max = Math.max(max, prices[i]); + profit2[i] = Math.max(profit2[i + 1], max - prices[i]); + } + //at any pos 'i' profit1[i] denotes profit upto 0 to i + // at any pos 'i' profit2[i] denotes profit upto i+1 to n + int result = 0; + for (int i = 0; i < prices.length; i++) { + result = Math.max(result, profit2[i] + profit1[i]); + } + return result; + } + + /** + * Buy sell recursive template + */ + public int maxProfitRecursive(int[] prices) { + Integer[][][] dp = new Integer[prices.length + 1][2][3]; + return recursionHelper(prices, 0, 0, 2, dp); + } + + public int recursionHelper(int[] prices, int idx, int canSell, int txn, Integer[][][] dp) { + + if (txn == 0) return 0; + if (idx >= prices.length) return 0; + if (dp[idx][canSell][txn] != null) return dp[idx][canSell][txn]; + if (canSell == 0) { + int buy = -prices[idx] + recursionHelper(prices, idx + 1, 1, txn, dp); + int notBuy = recursionHelper(prices, idx + 1, 0, txn, dp); + return dp[idx][canSell][txn] = Math.max(buy, notBuy); + } else { + int sell = prices[idx] + recursionHelper(prices, idx + 1, 0, txn - 1, dp); + int notSell = recursionHelper(prices, idx + 1, 1, txn, dp); + return dp[idx][canSell][txn] = Math.max(sell, notSell); + } + } + +} diff --git a/src/main/java/dynamicProgramming/stocks/BuyAndSellWithTransactionFee.java b/src/main/java/dynamicProgramming/stocks/BuyAndSellWithTransactionFee.java new file mode 100644 index 0000000..109229e --- /dev/null +++ b/src/main/java/dynamicProgramming/stocks/BuyAndSellWithTransactionFee.java @@ -0,0 +1,48 @@ +package dynamicProgramming.stocks; + +/** + * https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee + */ +public class BuyAndSellWithTransactionFee { + + public int maxProfit(int[] prices, int fee) { + if (prices == null || prices.length == 0) { + return 0; + } + + int days = prices.length; + int[] buy = new int[days]; // the max profit in ith day when the last operation is buy + int[] sell = new int[days]; // the max profit in ith day when the last operation is sell + + buy[0] = -prices[0]; + + for (int i = 1; i < days; i++) { + buy[i] = Math.max(buy[i - 1], sell[i - 1] - prices[i]); + sell[i] = Math.max(sell[i - 1], buy[i - 1] + prices[i] - fee); + } + + return sell[days - 1]; + } + + public int maxProfitRecursive(int[] prices, int fee) { + Integer[][] dp = new Integer[prices.length + 1][2]; + return recursionHelper(prices, 0, 0, fee, dp); + } + + public int recursionHelper(int[] prices, int idx, int canSell, int fee, Integer[][] dp) { + + if (idx >= prices.length) return 0; + if (dp[idx][canSell] != null) return dp[idx][canSell]; + if (canSell == 0) { + + int buy = -prices[idx] + recursionHelper(prices, idx + 1, 1, fee, dp); + int notBuy = recursionHelper(prices, idx + 1, 0, fee, dp); + return dp[idx][canSell] = Math.max(buy, notBuy); + } else { + int sell = prices[idx] + recursionHelper(prices, idx + 1, 0, fee, dp) - fee; + int notSell = recursionHelper(prices, idx + 1, 1, fee, dp); + return dp[idx][canSell] = Math.max(sell, notSell); + } + } + +} diff --git a/src/main/java/dynamicProgramming/stocks/StockBuySellKTransactions.java b/src/main/java/dynamicProgramming/stocks/StockBuySellKTransactions.java new file mode 100644 index 0000000..c3d956b --- /dev/null +++ b/src/main/java/dynamicProgramming/stocks/StockBuySellKTransactions.java @@ -0,0 +1,157 @@ +package dynamicProgramming.stocks; + +import java.util.Arrays; +import java.util.Deque; +import java.util.LinkedList; + +/** + * Date 12/22/2015 + * + * @author Tushar Roy + *

+ * Time complexity - O(number of transactions * number of days) Space + * complexity - O(number of transactions * number of days) + *

+ * https://leetcode.com/discuss/15153/a-clean-dp-solution-which-generalizes-to-k-transactions + * https://www.youtube.com/watch?v=Pw6lrYANjz4&t=1228s + */ +public class StockBuySellKTransactions { + + public int maxProfit(int prices[], int K) { + if (K == 0 || prices.length == 0) { + return 0; + } + int[][] T = new int[K + 1][prices.length]; + + for (int i = 1; i < T.length; i++) { + int maxDiff = -prices[0]; + for (int j = 1; j < T[0].length; j++) { + T[i][j] = Math.max(T[i][j - 1], prices[j] + maxDiff); + maxDiff = Math.max(maxDiff, T[i - 1][j] - prices[j]); + } + } + + System.out.println(Arrays.deepToString(T)); + printActualSolution(T, prices); + return T[K][prices.length - 1]; + } + + public int maxProfitSpaceEfficient(int k, int[] prices) { + int n = prices.length; + if (k >= n / 2) { //if k >= n/2, then you can make maximum number of transactions + int maxProfit = 0; + for (int i = 1; i < n; i++) { + if (prices[i] > prices[i - 1]) { + maxProfit += prices[i] - prices[i - 1]; + } + } + return maxProfit; + } + int[] buy = new int[k + 1], sell = new int[k + 1]; + Arrays.fill(buy, Integer.MIN_VALUE); + for (int price : prices) { + for (int i = 1; i <= k; i++) { + buy[i] = Math.max(buy[i], sell[i - 1] - price); + sell[i] = Math.max(sell[i], buy[i] + price); + } + } + return sell[k]; + } + + public int maxProfit(int k, int[] prices) { + int[][] dp = new int[k + 1][prices.length + 1]; + + int n = prices.length; + if (n <= 1) { + return 0; + } + if (k >= n / 2) { //if k >= n/2, then you can make maximum number of transactions + int maxProfit = 0; + for (int i = 1; i < n; i++) { + if (prices[i] > prices[i - 1]) { + maxProfit += prices[i] - prices[i - 1]; + } + } + return maxProfit; + } + + for (int i = 1; i <= k; i++) { + for (int priceDay = 1; priceDay <= prices.length; priceDay++) { + + int notTransactingAtPriceDay = dp[i][priceDay - 1]; + + for (int m = 0; m < priceDay; m++) { + int transactionTillPriceDay = prices[priceDay - 1] - prices[m]; //[priceDay-1] because priceday begins at 1 + /* + * previous transaction till m, + * because if we are buy at m '(prices[priceDay - 1] - prices[m])', + * we should've completed transaction till m 'dp[i - 1][m]' + */ + int previousTransactionTillM = dp[i - 1][m]; + int temp = Math.max(notTransactingAtPriceDay, transactionTillPriceDay + previousTransactionTillM); + dp[i][priceDay] = Math.max(dp[i][priceDay], temp); + } + } + } + return dp[k][prices.length]; + } + + + public void printActualSolution(int T[][], int prices[]) { + int i = T.length - 1; + int j = T[0].length - 1; + + Deque stack = new LinkedList<>(); + while (true) { + if (i == 0 || j == 0) { + break; + } + if (T[i][j] == T[i][j - 1]) { + j = j - 1; + } else { + stack.addFirst(j); + int maxDiff = T[i][j] - prices[j]; + for (int k = j - 1; k >= 0; k--) { + if (T[i - 1][k] - prices[k] == maxDiff) { + i = i - 1; + j = k; + stack.addFirst(j); + break; + } + } + } + } + + while (!stack.isEmpty()) { + System.out.println("Buy at price " + prices[stack.pollFirst()]); + System.out.println("Sell at price " + prices[stack.pollFirst()]); + } + + } + public int maxProfitRecursive(int k, int[] prices) { + Integer[][][] dp = new Integer[prices.length+1][2][k+1]; + return recursionHelper(prices,0,0,k,dp); + } + + public int recursionHelper(int[] prices, int idx,int canSell, int txn,Integer[][][] dp){ + if(idx>=prices.length || txn==0 ) return 0; + if(dp[idx][canSell][txn]!=null) return dp[idx][canSell][txn]; + if(canSell==0){ + + int buy = -prices[idx]+recursionHelper(prices,idx+1,1,txn,dp); + int notBuy = recursionHelper(prices,idx+1,0,txn,dp); + return dp[idx][canSell][txn]=Math.max(buy,notBuy); + }else{ + int sell = prices[idx]+recursionHelper(prices,idx+1,0,txn-1,dp); + int notSell = recursionHelper(prices,idx+1,1,txn,dp); + return dp[idx][canSell][txn]=Math.max(sell,notSell); + } + } + + public static void main(String args[]) { + StockBuySellKTransactions sbt = new StockBuySellKTransactions(); + int prices[] = {2, 5, 7, 1, 4, 3, 1, 3}; + + System.out.println("Max profit fast solution " + sbt.maxProfit(prices, 3)); + } +} diff --git a/src/main/java/dynamicProgramming/stocks/StockBuySellWithCoolDown.java b/src/main/java/dynamicProgramming/stocks/StockBuySellWithCoolDown.java new file mode 100644 index 0000000..2e3595e --- /dev/null +++ b/src/main/java/dynamicProgramming/stocks/StockBuySellWithCoolDown.java @@ -0,0 +1,82 @@ +package dynamicProgramming.stocks; + +public class StockBuySellWithCoolDown { + + public int maxProfit(int[] prices) { + + if (prices == null || prices.length < 2) return 0; + int buy = 0, sell = -prices[0], rest = 0; + + // Assume the buy, sell and rest are states + // the transistions would be + // 1) from Rest you have to come to buy + // 2) from buy you can rest/hold or you can sell + // 3) from sell you can hold or sell and go to Rest + + // state 1=> first transistion max(buy, rest) we can either buy or rest at this point + // state 2=> we can either hold what was there in previous state or buy so '-' price[i] + // state 3=> to come to rest we have to sell and make profit so only the '+' sign + + for (int i = 1; i < prices.length; i++) { + int tmp = buy; + buy = Math.max(buy, rest); + rest = sell + prices[i]; + sell = Math.max(sell, tmp - prices[i]); + } + return Math.max(buy, rest); + } + + /** + * cooldown[i] = max(cooldown[i - 1], sell[i - 1]); // Stay at cooldown, or rest from sell + * proceed to buy, ie, we have no stock now, and the max profit should be ''last no stock profit'' or ''last rest profit'' + *

+ * buy[i] = max(buy[i - 1], cooldown[i - 1] - prices[i]); // Stay at buy, or buy from cooldown + * //can proceed to sell, ie, we now have stock, and the profit should be ''last stock profit'' or ''last no stock but buy this time'' + *

+ * sell[i] = buy[i - 1] + prices[i]; // Only one way from s1 + * //we should sell then take a rest + */ + public int maxProfitExtraSpace(int[] prices) { + + int n = prices.length; + int[] buy = new int[prices.length + 1]; + int[] sell = new int[prices.length + 1]; + + buy[1] = -prices[0]; + sell[1] = 0; + if (n == 1) { + return sell[0]; + } + + for (int i = 2; i <= n; i++) { + buy[i] = Math.max(buy[i - 1], sell[i - 2] - prices[i - 1]); + + sell[i] = Math.max(sell[i - 1], buy[i - 1] + prices[i - 1]); + } + return sell[n]; + + } + + public static void main(String[] args) { + new StockBuySellWithCoolDown().maxProfitExtraSpace(new int[]{1, 2, 3, 0, 2}); + } + + public int maxProfitRecursive(int[] prices) { + Integer[][] dp = new Integer[prices.length][2]; + return recursionHelper(prices, 0, 0, dp); + } + + public int recursionHelper(int[] prices, int idx, int canSell, Integer[][] dp) { + if (idx >= prices.length) return 0; + if (dp[idx][canSell] != null) return dp[idx][canSell]; + if (canSell == 0) { + int buy = -prices[idx] + recursionHelper(prices, idx + 1, 1, dp); + int notBuy = recursionHelper(prices, idx + 1, 0, dp); + return dp[idx][canSell] = Math.max(buy, notBuy); + } else { + int sell = prices[idx] + recursionHelper(prices, idx + 2, 0, dp); + int notSell = recursionHelper(prices, idx + 1, 1, dp); + return dp[idx][canSell] = Math.max(sell, notSell); + } + } +} diff --git a/src/main/java/dynamicProgramming/unboundedknapsack/CuttingRod.java b/src/main/java/dynamicProgramming/unboundedknapsack/CuttingRod.java new file mode 100644 index 0000000..3b3b8e9 --- /dev/null +++ b/src/main/java/dynamicProgramming/unboundedknapsack/CuttingRod.java @@ -0,0 +1,80 @@ +package dynamicProgramming.unboundedknapsack; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/minimum-cost-to-cut-a-stick + * https://www.youtube.com/watch?v=xwomavsC86c + */ +public class CuttingRod { + + public int minCost(int n, int[] cuts) { + int len = cuts.length + 2; + + int[] endpoints = new int[len]; + endpoints[0] = 0; + for (int i = 1; i < len - 1; i++) endpoints[i] = cuts[i - 1]; + endpoints[len - 1] = n; + Arrays.sort(endpoints); + + + int[][] dp = new int[len][len]; + + // d : dist between i & j, the starting & ending position of stick + for (int d = 2; d < len; d++) { + for (int i = 0, j = i + d; j < len; i++, j++) { + dp[i][j] = Integer.MAX_VALUE; + + int curr = endpoints[j] - endpoints[i]; + for (int k = i + 1; k < j; k++) { + dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j] + curr); + } + } + } + return dp[0][len - 1]; + } + + /** + * The algorithm is quite Brute Force, we would try to generate all possible permutations of cuts, + * and would try to know what permutation would lead to best result, i.e. minimize our cost for cutting. + *

+ * Let us suppose we are currently having a wood piece from index l to index r (i.e. the length of the wood is r - l, indexing is done as illustrated in the problem). + * Now, we try every possible cut that we could perform in the range from l to r. + *

+ * Since a cut (let's say, cut is at i index) results in our original piece to further split into 2 parts (one from [l, i], and second from [i, r]). + * Also, lets suppose the minimum cost of cutting, the segment [l, i] is minLeft and similarly for [i, r] is minRight. + * Hence the cost to cut the rod segment [l, r] would be cost_i = minLeft + minRight + (r - l) (r - l is the cost to perform the cut at i). + * Similarly, a cut at j index would cost in total, say, cost_j, similarly at k be cost_k and so on... + *

+ * The minimum cost to cut the rod from index l to r hence would be min(cost_i, cost_j, cost_k, ...). + */ + public int minCostRecursive(int n, int[] cuts) { + Integer[][] dp = new Integer[101][101]; + int[] cutsWithLengthOfRodAppendedToEnds = Arrays.copyOf(cuts, cuts.length + 2); + cutsWithLengthOfRodAppendedToEnds[cutsWithLengthOfRodAppendedToEnds.length - 1] = n; + Arrays.sort(cutsWithLengthOfRodAppendedToEnds); + return recursionHelper(cutsWithLengthOfRodAppendedToEnds, 1, cutsWithLengthOfRodAppendedToEnds.length - 2, dp); + } + + public int recursionHelper(int[] cutsWithLengthOfRod, int i, int j, Integer[][] dp) { + if (i > j) return 0; + if (dp[i][j] != null) return dp[i][j]; + int min = Integer.MAX_VALUE; + + for (int mid = i; mid <= j; mid++) { + + int cost = cutsWithLengthOfRod[j + 1] - cutsWithLengthOfRod[i - 1] + recursionHelper(cutsWithLengthOfRod, i, mid - 1, dp) + + recursionHelper(cutsWithLengthOfRod, mid + 1, j, dp); + min = Math.min(cost, min); + } + + return dp[i][j] = min; + + } + + public static void main(String args[]) { + CuttingRod cr = new CuttingRod(); + int[] price = {1, 5, 3, 6}; + System.out.println(cr.minCost(9, price)); + } +} \ No newline at end of file diff --git a/src/practiceproblems/ArticulationPoint.java b/src/main/java/graph/ArticulationPoint.java similarity index 99% rename from src/practiceproblems/ArticulationPoint.java rename to src/main/java/graph/ArticulationPoint.java index c552acf..8710fce 100644 --- a/src/practiceproblems/ArticulationPoint.java +++ b/src/main/java/graph/ArticulationPoint.java @@ -1,4 +1,4 @@ -package practiceproblems; +package graph; import java.util.ArrayList; import java.util.Collection; diff --git a/src/graph/adjacencyList/AdjacencyList.java b/src/main/java/graph/adjacencyList/AdjacencyList.java similarity index 100% rename from src/graph/adjacencyList/AdjacencyList.java rename to src/main/java/graph/adjacencyList/AdjacencyList.java diff --git a/src/graph/adjacencyMatrix/AdjacencyMatrix.java b/src/main/java/graph/adjacencyMatrix/AdjacencyMatrix.java similarity index 100% rename from src/graph/adjacencyMatrix/AdjacencyMatrix.java rename to src/main/java/graph/adjacencyMatrix/AdjacencyMatrix.java diff --git a/src/graph/bellmanFord/BellmanFord.java b/src/main/java/graph/bellmanFord/BellmanFord.java similarity index 100% rename from src/graph/bellmanFord/BellmanFord.java rename to src/main/java/graph/bellmanFord/BellmanFord.java diff --git a/src/graph/bellmanFord/Edge.java b/src/main/java/graph/bellmanFord/Edge.java similarity index 100% rename from src/graph/bellmanFord/Edge.java rename to src/main/java/graph/bellmanFord/Edge.java diff --git a/src/graph/bellmanFord/Graph.java b/src/main/java/graph/bellmanFord/Graph.java similarity index 100% rename from src/graph/bellmanFord/Graph.java rename to src/main/java/graph/bellmanFord/Graph.java diff --git a/src/graph/bellmanFord/NegativeException.java b/src/main/java/graph/bellmanFord/NegativeException.java similarity index 100% rename from src/graph/bellmanFord/NegativeException.java rename to src/main/java/graph/bellmanFord/NegativeException.java diff --git a/src/graph/bellmanFord/Vertex.java b/src/main/java/graph/bellmanFord/Vertex.java similarity index 100% rename from src/graph/bellmanFord/Vertex.java rename to src/main/java/graph/bellmanFord/Vertex.java diff --git a/src/graph/breadthFirstSearch/BreadthFirstSearch.java b/src/main/java/graph/breadthFirstSearch/BreadthFirstSearch.java similarity index 100% rename from src/graph/breadthFirstSearch/BreadthFirstSearch.java rename to src/main/java/graph/breadthFirstSearch/BreadthFirstSearch.java diff --git a/src/graph/breadthFirstSearch/Graph.java b/src/main/java/graph/breadthFirstSearch/Graph.java similarity index 100% rename from src/graph/breadthFirstSearch/Graph.java rename to src/main/java/graph/breadthFirstSearch/Graph.java diff --git a/src/graph/cycle/CycleInDirectedGraph.java b/src/main/java/graph/cycle/CycleInDirectedGraph.java similarity index 100% rename from src/graph/cycle/CycleInDirectedGraph.java rename to src/main/java/graph/cycle/CycleInDirectedGraph.java diff --git a/src/graph/cycle/CycleUndirectedGraph.java b/src/main/java/graph/cycle/CycleUndirectedGraph.java similarity index 100% rename from src/graph/cycle/CycleUndirectedGraph.java rename to src/main/java/graph/cycle/CycleUndirectedGraph.java diff --git a/src/graph/cycle/Graph.java b/src/main/java/graph/cycle/Graph.java similarity index 100% rename from src/graph/cycle/Graph.java rename to src/main/java/graph/cycle/Graph.java diff --git a/src/graph/depthFirstSearch/DepthFirstSearch.java b/src/main/java/graph/depthFirstSearch/DepthFirstSearch.java similarity index 100% rename from src/graph/depthFirstSearch/DepthFirstSearch.java rename to src/main/java/graph/depthFirstSearch/DepthFirstSearch.java diff --git a/src/graph/depthFirstSearch/Graph.java b/src/main/java/graph/depthFirstSearch/Graph.java similarity index 100% rename from src/graph/depthFirstSearch/Graph.java rename to src/main/java/graph/depthFirstSearch/Graph.java diff --git a/src/graph/dijkstraAlgorithm/BinaryHeap.java b/src/main/java/graph/dijkstraAlgorithm/BinaryHeap.java similarity index 99% rename from src/graph/dijkstraAlgorithm/BinaryHeap.java rename to src/main/java/graph/dijkstraAlgorithm/BinaryHeap.java index eef7b79..07b7e80 100644 --- a/src/graph/dijkstraAlgorithm/BinaryHeap.java +++ b/src/main/java/graph/dijkstraAlgorithm/BinaryHeap.java @@ -116,7 +116,7 @@ public void decrease(long vertex, int i) { } public boolean isEmpty() { - return allNodes.size() == 0; + return allNodes.isEmpty(); } public boolean containsData(Vertex adjacentVertex) { diff --git a/src/graph/dijkstraAlgorithm/DijkstraAlgorithm.java b/src/main/java/graph/dijkstraAlgorithm/DijkstraAlgorithm.java similarity index 100% rename from src/graph/dijkstraAlgorithm/DijkstraAlgorithm.java rename to src/main/java/graph/dijkstraAlgorithm/DijkstraAlgorithm.java diff --git a/src/graph/dijkstraAlgorithm/Graph.java b/src/main/java/graph/dijkstraAlgorithm/Graph.java similarity index 100% rename from src/graph/dijkstraAlgorithm/Graph.java rename to src/main/java/graph/dijkstraAlgorithm/Graph.java diff --git a/src/graph/disjoints/DisjointSetArrayImplementation.java b/src/main/java/graph/disjoints/DisjointSetArrayImplementation.java similarity index 100% rename from src/graph/disjoints/DisjointSetArrayImplementation.java rename to src/main/java/graph/disjoints/DisjointSetArrayImplementation.java diff --git a/src/graph/disjoints/DisjointSetWithNode.java b/src/main/java/graph/disjoints/DisjointSetWithNode.java similarity index 100% rename from src/graph/disjoints/DisjointSetWithNode.java rename to src/main/java/graph/disjoints/DisjointSetWithNode.java diff --git a/src/graph/disjoints/PredatorDisjointSet.java b/src/main/java/graph/disjoints/PredatorDisjointSet.java similarity index 100% rename from src/graph/disjoints/PredatorDisjointSet.java rename to src/main/java/graph/disjoints/PredatorDisjointSet.java diff --git a/src/main/java/graph/disjoints/RankTransformMatrix.java b/src/main/java/graph/disjoints/RankTransformMatrix.java new file mode 100644 index 0000000..4643c0f --- /dev/null +++ b/src/main/java/graph/disjoints/RankTransformMatrix.java @@ -0,0 +1,147 @@ +package graph.disjoints; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class RankTransformMatrix { + static class Position { + int index; // the index is just the index in a list of positions, it is needed for union-find + int row; + int column; + + Position(int index, int row, int column) { + this.index = index; + this.row = row; + this.column = column; + } + } + + public int[][] matrixRankTransform(int[][] matrix) { + + int[][] ans = new int[matrix.length][matrix[0].length]; + int[] maxRankInCol = new int[matrix[0].length]; + int[] maxRankInRow = new int[matrix.length]; + Map> map = new HashMap<>(); + List uniqueNumbers = new ArrayList<>(); + + // populate map and the list of unique numbers + for (int i = 0; i < matrix.length; i++) + for (int j = 0; j < matrix[0].length; j++) { + if (!map.containsKey(matrix[i][j])) uniqueNumbers.add(matrix[i][j]); + map.putIfAbsent(matrix[i][j], new ArrayList<>()); + map.get(matrix[i][j]).add(new Position(map.get(matrix[i][j]).size(), i, j)); + } + + // sort the unique numbers to iterate from the smallest to the largest + + Collections.sort(uniqueNumbers); + + // For every unique number, we split the positions with this number into groups of non-adjacent ones using union-find. + // Then for each group set the rank of the elements in the group to be (the largest rank among all the rows and columns + // that contain elements of that group) + 1. + // Then update max ranks of those rows and columns to be the new rank. + + for (int n : uniqueNumbers) { + List positions = map.get(n); + UnionFind uf = new UnionFind(positions.size()); + + // union all the positions that have the same row or column + // for this I sorted by row/column and took union of adjacent positions + + positions.sort(Comparator.comparingInt(p -> p.row)); + for (int i = 0; i < positions.size() - 1; i++) + if (positions.get(i).row == positions.get(i + 1).row) + uf.union(positions.get(i).index, positions.get(i + 1).index); + + positions.sort(Comparator.comparingInt(p -> p.column)); + for (int i = 0; i < positions.size() - 1; i++) + if (positions.get(i).column == positions.get(i + 1).column) + uf.union(positions.get(i).index, positions.get(i + 1).index); + + // for every group (positions with the same parent), make a separate entry in a map + + HashMap> posMap = new HashMap<>(); + for (Position position : positions) { + int parent = uf.find(position.index); + if (!posMap.containsKey(parent)) posMap.put(parent, new ArrayList<>()); + posMap.get(parent).add(position); + } + + // for every list in our map (which are the groups), find the rank and update the ranks of rows/columns + + for (List list : posMap.values()) { + + // find max rank among rows/columns that contain elements of this group + + int max = 0; + for (Position pos : list) { + max = Math.max(maxRankInRow[pos.row], max); + max = Math.max(maxRankInCol[pos.column], max); + } + + // update maximums to the new rank + + int rank = max + 1; + for (Position pos : list) { + ans[pos.row][pos.column] = rank; + maxRankInRow[pos.row] = rank; + maxRankInCol[pos.column] = rank; + } + } + } + + return ans; + } + + /*** + /* The rest is Union-Find class (rank + path compression) + ***/ + + private static class UnionFind { + private int[] parent; + private int[] rank; + + UnionFind(int n) { + parent = new int[n]; + rank = new int[n]; + for (int i = 0; i < n; i++) { + parent[i] = i; + rank[i] = 0; + } + } + + int find(int p) { + if (p == parent[p]) return p; + parent[p] = find(parent[p]); + return parent[p]; + } + + void union(int p, int q) { + int rootP = find(p), rootQ = find(q); + if (rootP == rootQ) return; + if (rank[rootP] < rank[rootQ]) + parent[rootP] = rootQ; + else if (rank[rootP] > rank[rootQ]) + parent[rootQ] = rootP; + else { + parent[rootQ] = rootP; + rank[rootP]++; + } + } + } + + public static void main(String[] args) { + new RankTransformMatrix().matrixRankTransform(new int[][]{ {20, -21, 14}, + {-19, 4, 19}, + {22, -47, 24}, + {-19, 4, 19}}); + //new int[][]{{7,3,6},{1,4,5},{9,8,2}}; + } + +} + + diff --git a/src/graph/floydwarshall/FloydWarshall.java b/src/main/java/graph/floydwarshall/FloydWarshall.java similarity index 100% rename from src/graph/floydwarshall/FloydWarshall.java rename to src/main/java/graph/floydwarshall/FloydWarshall.java diff --git a/src/graph/interview/DisjointSet.java b/src/main/java/graph/interview/DisjointSet.java similarity index 100% rename from src/graph/interview/DisjointSet.java rename to src/main/java/graph/interview/DisjointSet.java diff --git a/src/graph/kruskalAlgorithm/DisjointSet.java b/src/main/java/graph/kruskalAlgorithm/DisjointSet.java similarity index 100% rename from src/graph/kruskalAlgorithm/DisjointSet.java rename to src/main/java/graph/kruskalAlgorithm/DisjointSet.java diff --git a/src/graph/kruskalAlgorithm/Graph.java b/src/main/java/graph/kruskalAlgorithm/Graph.java similarity index 100% rename from src/graph/kruskalAlgorithm/Graph.java rename to src/main/java/graph/kruskalAlgorithm/Graph.java diff --git a/src/graph/kruskalAlgorithm/KruskalMST.java b/src/main/java/graph/kruskalAlgorithm/KruskalMST.java similarity index 100% rename from src/graph/kruskalAlgorithm/KruskalMST.java rename to src/main/java/graph/kruskalAlgorithm/KruskalMST.java diff --git a/src/main/java/graph/leetcode/AccountsMerge.java b/src/main/java/graph/leetcode/AccountsMerge.java new file mode 100644 index 0000000..b61e9fd --- /dev/null +++ b/src/main/java/graph/leetcode/AccountsMerge.java @@ -0,0 +1,130 @@ +package graph.leetcode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * tricky union find + * + * https://www.youtube.com/watch?v=QHniHFvxAl8&ab_channel=ShiranAfergan + * https://leetcode.com/problems/accounts-merge/ + * Here, we use disjoint set union data structure to keep track of same user accounts. + * We use a hash map to map emails to account's indices (index of the account in accounts list). + * Note that different accounts (equivalently account ids) may belong to the same user. + * We perform union operation on account ids. This might reduce the number of union operations, compared to when we perform union on all emails. + * We start by iterating all email ids linked to all the accounts. + * If we observe that an email has been observed before, we know that both email ids must belong to different accounts which belong to the same user. + * Thus, we fetch the account ids corresponding to this email id, one is the current account's index, and the other is the account index from the map. + * We then perform union on the account indices. + * + * In the end, all account ids which belong to the same user get grouped together and return the same account id on calling findSet. + * For each email, we check which account id it belongs to, get that account's parent's id from the union structure, and add the email to that id in a new map. + * + * a b c // now b, c have parent a + * d e f // now e, f have parent d + * g a d // now abc, def all merged to group g + * + * parents populated after parsing 1st account: a b c + * a->a + * b->a + * c->a + * + * parents populated after parsing 2nd account: d e f + * d->d + * e->d + * f->d + * + * parents populated after parsing 3rd account: g a d + * g->g + * a->g + * d->g + */ +public class AccountsMerge { + public List> accountsMerge(List> accounts) { + + UnionFind uf = new UnionFind(accounts.size()); + + Map emailsToIdMapper = new TreeMap<>(); + + + for (int i = 0; i < accounts.size(); i++) { + + List emails = accounts.get(i); + // Step 1: traverse all emails except names, if we have not seen an email before, put it with its index into map. + // Otherwise, union the email to its parent index. + for(int j=1;j> result = new HashMap<>(); + + for (String email : emailsToIdMapper.keySet()) { + + int id = emailsToIdMapper.get(email); + + int parentId = uf.find(id); + if (!result.containsKey(parentId)) { + result.putIfAbsent(parentId, new ArrayList<>()); + result.get(parentId).add(accounts.get(parentId).get(0)); + } + + result.get(parentId).add(email); + } + + return new ArrayList<>(result.values()); + } + + static class UnionFind { + int[] parent; + int[] rank; + + public UnionFind(int n) { + this.parent = new int[n]; + this.rank = new int[n]; + + for (int i = 0; i < n; i++) { + this.parent[i] = i; + } + } + + public boolean union(int x, int y) { + + int parentX = find(x); + int parentY = find(y); + + if (parentX == parentY) return false; + + if (rank[parentX] > rank[parentY]) { + parent[parentY] = parentX; + } else if (rank[parentY] > rank[parentX]) { + parent[parentX] = parentY; + } else { + parent[parentY] = parentX; + rank[parentX]++; + } + + return true; + } + + public int find(int x) { + if (parent[x] == x) return x; + + parent[x] = find(parent[x]); + return parent[x]; + } + + public boolean isSameComponent(int p, int q) { + return find(p) == find(q); + } + } +} \ No newline at end of file diff --git a/src/main/java/graph/leetcode/AlienDictionary.java b/src/main/java/graph/leetcode/AlienDictionary.java new file mode 100644 index 0000000..23ce21e --- /dev/null +++ b/src/main/java/graph/leetcode/AlienDictionary.java @@ -0,0 +1,110 @@ +package graph.leetcode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; + +/** + * tricky topological sort + * + * https://leetcode.com/problems/alien-dictionary + * + * Really nice solution! Let me try to explain the code with example in the problem description: + * + * First, build a degree map for each character in all the words: + * + * w:0 + * r:0 + * t:0 + * f:0 + * e:0 + * + * Then build the hashmap by comparing the adjacent words, the first character that is different between two adjacent words reflect the lexicographical order. For example: + * + * "wrt", + * "wrf", + * first different character is 3rd letter, so t comes before f + * + * "wrf", + * "er", + * first different character is 1rd letter, so w comes before e + * + * The characters in set come after the key. x->y means letter x comes before letter y. x -> set: y,z,t,w means x comes before all the letters in the set. The final HashMap "map" looks like. + * + * t -> set: f + * w -> set: e + * r -> set: t + * e -> set: r + * + * and final HashMap "degree" looks like, the number means "how many letters come before the key": + * + * w:0 + * r:1 + * t:1 + * f:1 + * e:1 + * + * Then use Kahn's algorithm to do topological sort. This is essentially BFS. + */ + +public class AlienDictionary { + public String alienOrder(String[] words) { + // Step 0: Create data structures and find all unique letters. + Map> adjList = new HashMap<>(); + Map counts = new HashMap<>(); + for (String word : words) { + for (char c : word.toCharArray()) { + counts.put(c, 0); + adjList.put(c, new ArrayList<>()); + } + } + + // Step 1: Find all edges. + for (int i = 0; i < words.length - 1; i++) { + String word1 = words[i]; + String word2 = words[i + 1]; + // Check that word2 is not a prefix of word1. + // One edge case is when the second word is the prefix of the first word, for example: ["abc", "ab"] + // Because the prefix should always be at the front. + // check for cases like, ["wrtkj","wrt"]; it's invalid, because this input is not in sorted lexicographical order + if (word1.length() > word2.length() && word1.startsWith(word2)) { + return ""; + } + // Find the first non match and insert the corresponding relation. + for (int j = 0; j < Math.min(word1.length(), word2.length()); j++) { + if (word1.charAt(j) != word2.charAt(j)) { + adjList.get(word1.charAt(j)).add(word2.charAt(j)); + counts.put(word2.charAt(j), counts.get(word2.charAt(j)) + 1); + break; + } + } + } + + // Step 2: Breadth-first search. + StringBuilder sb = new StringBuilder(); + Queue queue = new LinkedList<>(); + for (Character c : counts.keySet()) { + if (counts.get(c)==0) { + queue.add(c); + } + } + while (!queue.isEmpty()) { + Character c = queue.remove(); + sb.append(c); + for (Character next : adjList.get(c)) { + counts.put(next, counts.get(next) - 1); + if (counts.get(next)==0) { + queue.add(next); + } + } + } + + if (sb.length() < counts.size()) { + return ""; + } + return sb.toString(); + } +} diff --git a/src/graph/leetcode/AllPathsInGraph.java b/src/main/java/graph/leetcode/AllPathsInGraph.java similarity index 91% rename from src/graph/leetcode/AllPathsInGraph.java rename to src/main/java/graph/leetcode/AllPathsInGraph.java index 016f7c1..9b2d336 100644 --- a/src/graph/leetcode/AllPathsInGraph.java +++ b/src/main/java/graph/leetcode/AllPathsInGraph.java @@ -4,6 +4,8 @@ import java.util.List; /** + * tricky graph traversal + * * Given a directed, acyclic graph of N nodes. Find all possible paths from node 0 to node N-1, and return them in any order. * * The graph is given as follows: the nodes are 0, 1, ..., graph.length - 1. @@ -22,8 +24,8 @@ public class AllPathsInGraph { public List> allPathsSourceTarget(int[][] graph) { boolean[] visited=new boolean[graph.length]; - List path=new ArrayList(); - List> ans=new ArrayList>(); + List path=new ArrayList<>(); + List> ans=new ArrayList<>(); visited[0]=true; path.add(0); dfs(graph,visited,0,path, ans); diff --git a/src/main/java/graph/leetcode/ArrayNesting.java b/src/main/java/graph/leetcode/ArrayNesting.java new file mode 100644 index 0000000..c8aa107 --- /dev/null +++ b/src/main/java/graph/leetcode/ArrayNesting.java @@ -0,0 +1,89 @@ +package graph.leetcode; + +/** + * TODO + * + * https://leetcode.com/problems/array-nesting/solution/ + * + * Elements in the same set will form a cycle. + * We just traverse elements x in nums: + * If x is not visited then we dfs(x) to find elements in the same cycle with node x. + * Update the ans if the current cycle has length greater than ans. + * Check the following picture for more clearly. + * + * nums = [5,4,0,3,1,6,2] + * + * curr = 5, nums[curr] = 6 + * make edge between 5 and 6 in paper, change curr to 6 + * + * curr = 6, nums[curr] = 2 + * make edge between 6 and 2, change curr to 2 + * + * curr = 2, nums[curr] = 0 + * make edge between 2 and 0, change curr to 0 + * + * curr = 0, nums[curr] = 5 + * make edge between 0 and 5, change curr to 5 + * + * now as 5 is already visited hence component is complete + * component is => (5, 6, 2, 0) + * + * Now when i = 1, curr = 4 + * component is => (1, 4) + * + * i = 2, this number is already used in a component + * i = 3 already used + * i = 4 already used...... and so on + * + * so we have two components + * (5, 6, 2, 0) and (1, 4) + * + * The largest size component is (5, 6, 2, 0) + * Hence out ans for this test case is 4. + */ +public class ArrayNesting { + + public int arrayNesting(int[] nums) { + boolean[] visited = new boolean[nums.length]; + int result = 0; + for (int i = 0; i < nums.length; i++) { + if (!visited[i]) { + int start = i; + int count = 0; + while (!visited[start]) { + count++; + visited[start] = true; + start = nums[start]; + } + if (result < count) { + result = count; + } + } + } + return result; + } + + public int arrayNestingDFS(int[] nums) { + int max = Integer.MIN_VALUE; + + for (int i = 0; i < nums.length; i++) { + if (nums[i]<0) + continue; + max = Math.max(max, calcLength(nums, i)); + } + return max; + } + + private int calcLength(int[] nums, int start) { + + if(start<0 || start==nums.length || nums[start]<0){ + return 0; + } + + int nextValue = nums[start]; + nums[start] = Integer.MIN_VALUE; + + return 1 + calcLength(nums, nextValue); + + } +} diff --git a/src/main/java/graph/leetcode/CanVisitAllRooms.java b/src/main/java/graph/leetcode/CanVisitAllRooms.java new file mode 100644 index 0000000..0835ff8 --- /dev/null +++ b/src/main/java/graph/leetcode/CanVisitAllRooms.java @@ -0,0 +1,42 @@ +package graph.leetcode; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * https://leetcode.com/problems/keys-and-rooms/ + * Input: rooms = [[1],[2],[3],[]] + * Output: true + * Explanation: + * We visit room 0 and pick up key 1. + * We then visit room 1 and pick up key 2. + * We then visit room 2 and pick up key 3. + * We then visit room 3. + * Since we were able to visit every room, we return true. + */ +public class CanVisitAllRooms { + + public boolean canVisitAllRooms(List> rooms) { + Set set = new HashSet<>(); + + set.add(0); + Deque stack = new ArrayDeque<>(); + stack.push(0); + while (!stack.isEmpty()) { + int i = stack.pop(); + + for (int keys : rooms.get(i)) { + if (!set.contains(keys)) { + set.add(keys); + stack.push(keys); + } + if (set.size() == rooms.size()) return true; + } + } + + return set.size() == rooms.size(); + } +} diff --git a/src/main/java/graph/leetcode/CheapestFlightKStops.java b/src/main/java/graph/leetcode/CheapestFlightKStops.java new file mode 100644 index 0000000..8b36bcb --- /dev/null +++ b/src/main/java/graph/leetcode/CheapestFlightKStops.java @@ -0,0 +1,104 @@ +package graph.leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * https://leetcode.com/problems/cheapest-flights-within-k-stops/ + */ +public class CheapestFlightKStops { + +// For example consider the following graph. Let source ‘u’ be vertex 0, destination ‘v’ be 3 and k be 2. +// There are two walks of length 2, the walks are {0, 2, 3} and {0, 1, 3}. +// The shortest among the two is {0, 2, 3} and weight of path is 3+6 = 9. + + public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k) { + + // K doesn't include destination, because that's how it is for flights, hence K++ to account a hop for destination + k++; + Map> adjList = new HashMap<>(); + + for (int[] flight : flights) { + adjList.computeIfAbsent(flight[0], x -> new ArrayList<>()).add(new int[]{flight[1], flight[2]}); + } + + int[] costs = new int[n]; + int[] stops = new int[n]; + + Arrays.fill(costs,Integer.MAX_VALUE); + Arrays.fill(stops,Integer.MAX_VALUE); + + PriorityQueue queue = new PriorityQueue<>(Comparator.comparingInt(a -> a[1])); + + costs[src]=0; + stops[src]=0; + + queue.offer(new int[]{src,0,0}); + + while(!queue.isEmpty()){ + + int[] node = queue.poll(); + int current = node[0], cost = node[1], stop = node[2]; + + //System.out.println(currNode+" - "+cost+" - "+stop); + if(current==dst) return cost; + + + if(stop==k) continue; + + for(int[] adj: adjList.getOrDefault(current,new ArrayList<>())){ + + int next = adj[0]; + int costNext = adj[1]; + + // Add for better cost, or stop + if (cost + costNext < costs[next] || stop + 1 < stops[next]) { + queue.offer(new int[]{next, cost + costNext, stop + 1}); + costs[next] = cost + costNext; + stops[next] = stop + 1; + } + } + + } + return -1; + } + + /** + * // BELLMON FORD: Relax all edges |V| - 1 times. A simple shortest path from src to any other vertex can have + * // at-most |V| - 1 edges since there will not be any multiple flights between two cities. + * // Here we will relax K times. + * // Much like BFS, run the algorithm K times, if the answer exists, it should be stored in the helper matrix + * // O(K⋅E) + */ + public int findCheapestPriceBellman(int n, int[][] flights, int src, int dst, int k) { + int[] cheapestPrices = new int[n]; + Arrays.fill(cheapestPrices, Integer.MAX_VALUE); + cheapestPrices[src] = 0; + + for (int i = 0; i < k + 1; i++) { // k = 1 means # edges <= 2 + + // Copy to ensure one vertex doesn't go through multiple relaxation in same iteration + // If there was not a limit on K stops (intermediary nodes), then we DO NOT need copy + // other way would be to use 2D array to track K as well which won't require copy. + int[] prevCheapestPrices = cheapestPrices.clone(); + + for (int[] flight : flights) { + int source = flight[0]; + int dest = flight[1]; + int price = flight[2]; + + if (prevCheapestPrices[source] != Integer.MAX_VALUE) { + cheapestPrices[dest] = Math.min(cheapestPrices[dest], prevCheapestPrices[source] + price); + } + } + } + + return cheapestPrices[dst] == Integer.MAX_VALUE ? -1 : cheapestPrices[dst]; + } + +} diff --git a/src/main/java/graph/leetcode/ClosedIsland.java b/src/main/java/graph/leetcode/ClosedIsland.java new file mode 100644 index 0000000..31eadef --- /dev/null +++ b/src/main/java/graph/leetcode/ClosedIsland.java @@ -0,0 +1,49 @@ +package graph.leetcode; + +/** + * https://leetcode.com/problems/number-of-closed-islands/ + */ +public class ClosedIsland { + + public int closedIsland(int[][] grid) { + + int VISITED = 2; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + + if (i == 0 || j == 0 || i == grid.length - 1 || j == grid[0].length - 1) { + if (grid[i][j] == 0) { + dfs(grid, i, j, VISITED); + } + } + } + } + + int result = 0; + + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + + if (grid[i][j] == 0) { + dfs(grid, i, j, VISITED); + result++; + } + } + } + + return result; + } + + public void dfs(int[][] grid, int i, int j, int VISITED) { + if (i < 0 || j < 0 || j >= grid[0].length || i >= grid.length) return; + + if (grid[i][j] == 1 || grid[i][j] == VISITED) return; + + grid[i][j] = VISITED; + + dfs(grid, i + 1, j, VISITED); + dfs(grid, i, j + 1, VISITED); + dfs(grid, i - 1, j, VISITED); + dfs(grid, i, j - 1, VISITED); + } +} diff --git a/src/main/java/graph/leetcode/ConnectCities.java b/src/main/java/graph/leetcode/ConnectCities.java new file mode 100644 index 0000000..7e49dca --- /dev/null +++ b/src/main/java/graph/leetcode/ConnectCities.java @@ -0,0 +1,68 @@ +package graph.leetcode; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * Input: N = 3, connections = [[1,2,5],[1,3,6],[2,3,1]] + * Output: 6 + * Explanation: + * Choosing any 2 edges will connect all cities so we choose the minimum 2. + */ +public class ConnectCities { + public int solve(int A, ArrayList> B) { + + // greedy-ly we're looking from low-cost roads to minimise the cost + B.sort((Comparator.comparingInt(a -> a.get(2)))); + + UnionSet us = new UnionSet(A); + int result = 0; + for (List row : B) { + if (us.union(row.get(0), row.get(1))) { + result += row.get(2); + } + } + return result; + } + + static class UnionSet { + int[] parent; + int[] rank; + int count; + + public UnionSet(int n) { + this.count = count; + this.parent = new int[n + 1]; + this.rank = new int[n + 1]; + for (int i = 0; i <= n; i++) { + this.parent[i] = i; + this.rank[i] = 1; + } + } + + public int find(int n) { + if (parent[n] == n) return n; + parent[n] = find(parent[n]); + return parent[n]; + } + + public boolean union(int x, int y) { + int rootX = find(x); + int rootY = find(y); + if (rootX == rootY) return false; + + if (rank[rootX] < rank[rootY]) { + parent[rootX] = rootY; + } else if (rank[rootX] > rank[rootY]) { + parent[rootY] = rootX; + } else { + parent[rootY] = rootX; + rank[rootX]++; + } + count--; + return true; + } + } +} diff --git a/src/main/java/graph/leetcode/ConnectCitiesWithDiscount.java b/src/main/java/graph/leetcode/ConnectCitiesWithDiscount.java new file mode 100644 index 0000000..1a03de4 --- /dev/null +++ b/src/main/java/graph/leetcode/ConnectCitiesWithDiscount.java @@ -0,0 +1,72 @@ +package graph.leetcode; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.PriorityQueue; + +/** + * https://leetcode.com/problems/minimum-cost-to-reach-city-with-discounts + * highways[i] = [city1i, city2i, tolli] + * + * Input: n = 5, highways = [[0,1,4],[2,1,3],[1,4,11],[3,2,3],[3,4,2]], discounts = 1 + * Output: 9 + * Explanation: + * Go from 0 to 1 for a cost of 4. + * Go from 1 to 4 and use a discount for a cost of 11 / 2 = 5. + * The minimum cost to go from 0 to 4 is 4 + 5 = 9. + */ +public class ConnectCitiesWithDiscount { + + /** + * Dijkstra is used to solve single source, positive weight and minimum path questions like this. + * The only trick here is to use 2D visited array to check and do the pruning work when the next city is put into the PriorityQueue, + * one for city and one for the amount of discounts used. + * The principle of Dijkstra Algorithm determines the fact that the first time the destination is reached, it will be the optimal solution. + */ + public int minimumCost(int n, int[][] highways, int discounts) { + + List[] graph = new List[n]; + for (int i = 0; i < n; i++) graph[i] = new ArrayList<>(); + + for (int[] x : highways) { + int cityA = x[0], cityB = x[1], cost = x[2]; + graph[cityA].add(new int[]{cityB, cost}); + graph[cityB].add(new int[]{cityA, cost}); + } + + PriorityQueue pq = new PriorityQueue<>(Comparator.comparingInt(o -> o[0])); + pq.offer(new int[]{0, 0, 0}); // {cost, node, discount} + boolean[] visited = new boolean[n]; + + /** + * # Because of how djikstra works, when we reach this node the first time, + * # we will reach there with the lowest cost. However, we may reach this node + * # again with a highest cost, but more discount tickets, which can lead to a + * # more optimal soln at the end. If we ever come back to this node with the same or + * # fewer discounts, the soln is not optimal. + */ + while (!pq.isEmpty()) { + int[] cur = pq.poll(); + int cost = cur[0], city = cur[1], dis = cur[2]; + + /* We dont have to push it back into the heap, we have already found the shortest path to this city. + this holds true as we storing the cost from source in the minHeap, this would not be valid if we are just storing the curr cost + */ + visited[city] = true; + + if (city == n - 1) return cost; + + for (int[] x : graph[city]) { + int next = x[0], weight = x[1]; + if (!visited[next]) { + pq.offer(new int[]{cost + weight, next, dis}); + if (dis < discounts) { + pq.offer(new int[]{cost + weight / 2, next, dis + 1}); + } + } + } + } + return -1; + } +} diff --git a/src/graph/leetcode/ConnectedComponentsInGraph.java b/src/main/java/graph/leetcode/ConnectedComponentsInGraph.java similarity index 78% rename from src/graph/leetcode/ConnectedComponentsInGraph.java rename to src/main/java/graph/leetcode/ConnectedComponentsInGraph.java index e74203c..ce312ef 100644 --- a/src/graph/leetcode/ConnectedComponentsInGraph.java +++ b/src/main/java/graph/leetcode/ConnectedComponentsInGraph.java @@ -9,9 +9,9 @@ public int countComponents(int n, int[][] edges) { roots[i] = i; } - for (int i = 0; i < edges.length; i++) { - int r1 = find(roots, edges[i][0]); - int r2 = find(roots, edges[i][1]); + for (int[] edge : edges) { + int r1 = find(roots, edge[0]); + int r2 = find(roots, edge[1]); if (r1 != r2) { roots[r1] = r2; diff --git a/src/main/java/graph/leetcode/CourseSchedule.java b/src/main/java/graph/leetcode/CourseSchedule.java new file mode 100644 index 0000000..23ebc6b --- /dev/null +++ b/src/main/java/graph/leetcode/CourseSchedule.java @@ -0,0 +1,170 @@ +package graph.leetcode; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.Set; + +/** + * Input: numCourses = 2, prerequisites = [[1,0]] + * Output: true + * Explanation: There are a total of 2 courses to take. + * To take course 1 you should have finished course 0. So it is possible. + *

+ * Input: numCourses = 2, prerequisites = [[1,0],[0,1]] + * Output: false + * Explanation: There are a total of 2 courses to take. + * To take course 1 you should have finished course 0, and to take course 0 you should + * also have finished course 1. So it is impossible. + */ +class CourseSchedule { + public boolean canFinish(int numCourses, int[][] prerequisites) { + + Map> map = new HashMap<>(); // Courses that depend on the key + int[] indegree = new int[numCourses]; // # of prerequisites for course i + Queue queue = new ArrayDeque<>(); // Used to find dependants and decrease their outdegree + + for (int[] pre : prerequisites) { + map.getOrDefault(pre[1], new ArrayList<>()).add(pre[0]); + indegree[pre[0]]++; + } + + for (int i = 0; i < indegree.length; i++) { + if (indegree[i] == 0) { + queue.offer(i); + } + } + + int count = 0; + while (!queue.isEmpty()) { + int temp = queue.poll(); + if (indegree[temp] == 0) { + count++; // if cond for duplicates + } + if (!map.containsKey(temp)) { + continue; + } + for (int i : map.get(temp)) { + if (--indegree[i] == 0) { + queue.offer(i); + } + } + } + + return count == numCourses; + } + + public List checkIfPrerequisite(int numCourses, int[][] prerequisites, int[][] queries) { + int[] indegree = new int[numCourses]; + Map> adj = new HashMap<>(); + Map> prerequisitesMap = new HashMap<>(); + + for (int i = 0; i < numCourses; i++) { + prerequisitesMap.put(i, new HashSet<>()); + adj.put(i, new HashSet<>()); + } + + for (int[] pre : prerequisites) { + int dst = pre[0]; + int src = pre[1]; + + indegree[dst]++; + adj.get(src).add(dst); + } + + Queue q = new LinkedList<>(); + for (int i = 0; i < numCourses; i++) { + if (indegree[i] == 0) { + q.offer(i); + } + } + + while (!q.isEmpty()) { + int node = q.poll(); + Set adjset = adj.get(node); + for (int depcrs : adjset) { + prerequisitesMap.get(depcrs).add(node); + prerequisitesMap.get(depcrs).addAll(prerequisitesMap.get(node)); + indegree[depcrs]--; + if (indegree[depcrs] == 0) { + q.offer(depcrs); + } + } + } + + List rslt = new ArrayList<>(); + for (int[] qry : queries) { + Set pset = prerequisitesMap.get(qry[0]); + if (pset.contains(qry[1])) { + rslt.add(true); + } else { + rslt.add(false); + } + } + return rslt; + } + + public boolean canFinishDFS(int numCourses, int[][] prerequisites) { + // this method basically finds a back-edge between nodes + // backedge is when doing a node(A)'s dfs, it puts A to a temp state + // while traversing A's child, if any of child dosen't have anymore child it's marked as completed + // if there are children it put's the current child to temp state and visits it's children + // so when doing a dfs for a node if it encounters a temp state node rather than completed node + // then that means there's a cycle we cannot complete the course + // (T) A \ + // / / + // (T) B / + // / \ / + // (Co) C D (T) while doing DFS for D's components we encounter A, but A is still in temp state + // + + ArrayList[] adjList = new ArrayList[numCourses]; + + for (int i = 0; i < numCourses; i++) { + adjList[i] = new ArrayList<>(); + } + for (int[] ints : prerequisites) { + adjList[ints[0]].add(ints[1]); + } + int[] color = new int[numCourses]; + + for (int i = 0; i < numCourses; i++) { + if (color[i] != 2 && dfs(adjList, i, color)) return false; + } + return true; + + } + + public boolean dfs(ArrayList[] al, int curr, int[] color) { + if (color[curr] == 1) return true; + color[curr] = 1; + for (int x : al[curr]) { + if (color[x] != 2 && dfs(al, x, color)) + return true; + } + color[curr] = 2; + return false; + } + + + // this is to get the order of course as output + public boolean dfs(List[] adjList, int[] visited, List result, int node) { + if (visited[node] == 1) return false; + if (visited[node] == 2) return true; + + visited[node] = 1; + for (int adj : adjList[node]) { + if (!dfs(adjList, visited, result, adj)) { + return false; + } + } + visited[node] = 2; + result.add(node); // this will keep track of which to fininsh first and last + return true; + } +} \ No newline at end of file diff --git a/src/main/java/graph/leetcode/CourseScheduleII.java b/src/main/java/graph/leetcode/CourseScheduleII.java new file mode 100644 index 0000000..fc491a5 --- /dev/null +++ b/src/main/java/graph/leetcode/CourseScheduleII.java @@ -0,0 +1,211 @@ +package graph.leetcode; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.Set; + +/** + * Input: numCourses = 2, prerequisites = [[1,0]] + * Output: true + * Explanation: There are a total of 2 courses to take. + * To take course 1 you should have finished course 0. So it is possible. + *

+ * Input: numCourses = 2, prerequisites = [[1,0],[0,1]] + * Output: false + * Explanation: There are a total of 2 courses to take. + * To take course 1 you should have finished course 0, and to take course 0 you should + * also have finished course 1. So it is impossible. + */ +public class CourseScheduleII { + public boolean canFinish(int numCourses, int[][] prerequisites) { + + Map> map = new HashMap<>(); // Courses that depend on the key + int[] indegrees = new int[numCourses]; // # of prerequisites for course i + Queue queue = new ArrayDeque<>(); // Used to find dependants and decrease their outdegree + + for (int[] pre : prerequisites) { + map.getOrDefault(pre[1], new ArrayList<>()).add(pre[0]); + indegrees[pre[0]]++; + } + + for (int i = 0; i < indegrees.length; i++) { + if (indegrees[i] == 0) { + queue.offer(i); + } + } + + int count = 0; + while (!queue.isEmpty()) { + int temp = queue.poll(); + if (indegrees[temp] == 0) { + count++; // if cond for duplicates + } + if (!map.containsKey(temp)) { + continue; + } + for (int i : map.get(temp)) { + if (--indegrees[i] == 0) { + queue.offer(i); + } + } + } + + return count == numCourses; + } + + public int[] findOrder(int numCourses, int[][] prerequisites) { + + Map> adjList = new HashMap<>(); + int[] indegree = new int[numCourses]; + int[] topologicalOrder = new int[numCourses]; + + // Create the adjacency list representation of the graph + for (int[] prerequisite : prerequisites) { + int dest = prerequisite[0]; + int src = prerequisite[1]; + adjList.computeIfAbsent(src, x -> new ArrayList<>()).add(dest); + indegree[dest] += 1; + } + + // Add all vertices with 0 in-degree to the queue + Queue q = new LinkedList<>(); + for (int i = 0; i < numCourses; i++) { + if (indegree[i] == 0) { + q.add(i); + } + } + + int i = 0; + // Process until the Q becomes empty + while (!q.isEmpty()) { + int node = q.remove(); + topologicalOrder[i++] = node; + + // Reduce the in-degree of each neighbor by 1 + if (adjList.containsKey(node)) { + for (Integer neighbor : adjList.get(node)) { + indegree[neighbor]--; + + // If in-degree of a neighbor becomes 0, add it to the Q + if (indegree[neighbor] == 0) { + q.add(neighbor); + } + } + } + } + + return i == numCourses ? topologicalOrder : new int[0]; + } + + public List checkIfPrerequisite(int numCourses, int[][] prerequisites, int[][] queries) { + int[] indegree = new int[numCourses]; + Map> adj = new HashMap<>(); + Map> prerequisitesMap = new HashMap<>(); + + for (int i = 0; i < numCourses; i++) { + prerequisitesMap.put(i, new HashSet<>()); + adj.put(i, new HashSet<>()); + } + + for (int[] pre : prerequisites) { + int dst = pre[0]; + int src = pre[1]; + + indegree[dst]++; + adj.get(src).add(dst); + } + + Queue q = new LinkedList<>(); + for (int i = 0; i < numCourses; i++) { + if (indegree[i] == 0) { + q.offer(i); + } + } + + while (!q.isEmpty()) { + int node = q.poll(); + Set adjset = adj.get(node); + for (int depcrs : adjset) { + prerequisitesMap.get(depcrs).add(node); + prerequisitesMap.get(depcrs).addAll(prerequisitesMap.get(node)); + indegree[depcrs]--; + if (indegree[depcrs] == 0) { + q.offer(depcrs); + } + } + } + + List rslt = new ArrayList<>(); + for (int[] qry : queries) { + Set pset = prerequisitesMap.get(qry[0]); + if (pset.contains(qry[1])) { + rslt.add(true); + } else { + rslt.add(false); + } + } + return rslt; + } + + public boolean canFinishDFS(int numCourses, int[][] prerequisites) { + // this method basically finds a back-edge between nodes + // backedge is when doing a node(A)'s dfs, it puts A to a temp state + // while traversing A's child, if any of child dosen't have anymore child it's marked as completed + // if there are children it put's the current child to temp state and visits it's children + // so when doing a dfs for a node if it encounters a temp state node rather than completed node + // then that means there's a cycle we cannot complete the course + // (T) A \ + // / / + // (T) B / + // / \ / + // (Co) C D (T) while doing DFS for D's components we encounter A, but A is still in temp state + // + + ArrayList[] adjList = new ArrayList[numCourses]; + + for (int i = 0; i < numCourses; i++) { + adjList[i] = new ArrayList<>(); + } + for (int[] ints : prerequisites) { + adjList[ints[0]].add(ints[1]); + } + int[] color = new int[numCourses]; + + for (int i = 0; i < numCourses; i++) { + if (color[i] != 2 && dfs(adjList, i, color)) return false; + } + return true; + + } + + public boolean dfs(ArrayList[] al, int curr, int[] color) { + if (color[curr] == 1) return true; + color[curr] = 1; + for (int x : al[curr]) if (color[x] != 2 && dfs(al, x, color)) return true; + color[curr] = 2; + return false; + } + + + // this is to get the order of course as output + public boolean dfs(List[] adjList, int[] visited, List result, int node) { + if (visited[node] == 1) return false; + if (visited[node] == 2) return true; + + visited[node] = 1; + for (int adj : adjList[node]) { + if (!dfs(adjList, visited, result, adj)) { + return false; + } + } + visited[node] = 2; + result.add(node); // this will keep track of which to fininsh first and last + return true; + } +} \ No newline at end of file diff --git a/src/main/java/graph/leetcode/CriticalConnectionInGraph.java b/src/main/java/graph/leetcode/CriticalConnectionInGraph.java new file mode 100644 index 0000000..1090d94 --- /dev/null +++ b/src/main/java/graph/leetcode/CriticalConnectionInGraph.java @@ -0,0 +1,86 @@ +package graph.leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * TODO revise + * Idea: An connection is critical if and only if it is not in a cycle. + * In other words, a connection (u, v) (u is parent of v in the DFS path) is critical if there is no way to reach u from v or the descendants of v. + * + * Use an array 'visitedAt[]' to store the timestamps when each node is visited. + * For each node, we will find the smallest 'visitedAt' of all its descendants. + * 2.1. If the smallest 'visitedAt' < current node's 'visitedAt', the node must be in a cycle since the smallest 'visitedAt' must be the 'visitedAt' of an ancestor of the current node. + * 2.2. If the smallest 'visitedAt' > the current node's 'visitedAt', the node must not be in a cycle, and the connection from its parent to it is critical. + * 2.3. If the smallest 'visitedAt' == the current node's 'visitedAt' the node must be in a cycle. However, + * If the current node has a valid parent, the connection from its parent to it is critical. For example, node 3 in n = 6 and connections = [[0,1],[1,2],[2,0],[1,3],[3,4],[4,5],[5,3]]. + * If the current node does not have a valid parent, it's not a node of a critical connection. For example, node 0 in n = 3 and connections = [[0,1], [1,2], [2,0]]. + * + * Complexity: + * Time = O(graph) + O(DFS) = O(|E| + |V|) + O(|E| + |V|) = O(|E| + |V|) + * Space = O(graph) + O(visitedAt) + O(DFS) = O(|E| + |V|) + O(|V|) + O(|V|) = O(|V| + |E|) + */ +public class CriticalConnectionInGraph { + int startTime=1; + public List> criticalConnections(int n, List> connections) { + if (connections == null) { + return Collections.emptyList(); + } + + List> criticalConns = new ArrayList<>(); + dfs(buildGraph(n, connections), new int[n], 0, -1, criticalConns); // -1 is a dummy parent of the server 0 + return criticalConns; + } + + /** + * The dfs method is basically trying to find the node with the minimum timestamp the current node is able to reach. + * By calling the dfs method with all of the current node's neighbors, + * we get a number of results representing the timestamps the current node can reach and we choose the minimal value from these results. + * Our purpose is to find out the cycle and the minimal value is used to do so. Taking a step back, if there is a cycle existing in the graph, + * we will eventually go back to a previous timestamp through the cycle; in another word, we will find a node that can reach to a previous timestamp. + * When we find such node, we will return the previous timestamp as the result of the dfs method and the caller (the parent node) + * who is calling the dfs method will get the previous timestamp as well. + * The minimal value among the results of the dfs invocations for a node's all child nodes will be larger than the previous timestamp + * until we get back to the beginning of the loop (technically there is no beginning of a loop but the beginning here is referring to the node that firstly detected the cycle). + * All the connections within a loop are not critical connections; in another word, we just need to return all the connections outside of any loops. + */ + private int dfs(List> graph, int[] visitedAt, int server, int parent, List> criticalConns) { + if (visitedAt[server] > 0) { // return immediately if a node has been visited before + return visitedAt[server]; + } + + visitedAt[server] = startTime++; + + int minVisitedAtOfAllNeighbors = Integer.MAX_VALUE; + for (int neighbor : graph.get(server)) { + if (neighbor == parent) { // skip parent as we only want to explore down, not up + continue; + } + + int neighborVisitedAt = dfs(graph, visitedAt, neighbor, server, criticalConns); + minVisitedAtOfAllNeighbors = Math.min(minVisitedAtOfAllNeighbors, neighborVisitedAt); + } + + if (visitedAt[server] <= minVisitedAtOfAllNeighbors && parent != -1) { // parent != 1 to avoid creating invalid critical connection, e.g., [-1, 0] + criticalConns.add(Arrays.asList(parent, server)); + } + + return Math.min(visitedAt[server], minVisitedAtOfAllNeighbors); + } + + private List> buildGraph(int n, List> connections) { + List> graph = new ArrayList<>(); + for (int i = 0; i < n; i++) { + graph.add(new ArrayList<>()); + } + + for (List conn : connections) { + graph.get(conn.get(0)).add(conn.get(1)); + graph.get(conn.get(1)).add(conn.get(0)); + } + + return graph; + } +} diff --git a/src/main/java/graph/leetcode/EmployeeImportance.java b/src/main/java/graph/leetcode/EmployeeImportance.java new file mode 100644 index 0000000..4b6a638 --- /dev/null +++ b/src/main/java/graph/leetcode/EmployeeImportance.java @@ -0,0 +1,50 @@ +package graph.leetcode; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * https://leetcode.com/problems/employee-importance/ + */ +public class EmployeeImportance { + + public int getImportance(List employees, int id) { + + Deque stack = new ArrayDeque<>(); + int result = 0; + Set set = new HashSet<>(); + + Map cache = new HashMap<>(); + for (Employee e : employees) { + cache.put(e.id, e); + } + + stack.push(cache.get(id)); + + while (!stack.isEmpty()) { + + Employee emp = stack.pop(); + if (set.contains(emp.id)) continue; + set.add(emp.id); + + result += emp.importance; + + for (Integer e : emp.subordinates) { + stack.push(cache.get(e)); + } + } + + return result; + } + + static class Employee { + public int id; + public int importance; + public List subordinates; + } +} diff --git a/src/main/java/graph/leetcode/EquationEquality.java b/src/main/java/graph/leetcode/EquationEquality.java new file mode 100644 index 0000000..0b0dd95 --- /dev/null +++ b/src/main/java/graph/leetcode/EquationEquality.java @@ -0,0 +1,91 @@ +package graph.leetcode; + +/** + * https://leetcode.com/problems/satisfiability-of-equality-equations/ + *

+ * Intuition: + * We have 26 nodes in the graph. + * All "==" equations actually represent the connection in the graph. + * The connected nodes should be in the same color/union/set. + *

+ * Then we check all inequations. + * Two inequal nodes should be in the different color/union/set. + *

+ * Explanation + * We can solve this problem by DFS or Union Find. + *

+ * Firt pass all "==" equations. + * Union equal letters together + * Now we know which letters must equal to the others. + *

+ * Second pass all "!=" inequations, + * Check if there are any contradict happens. + */ +public class EquationEquality { + + public boolean equationsPossible(String[] equations) { + + UnionFind uf = new UnionFind(26); + + for (String equation : equations) { + if (equation.charAt(1) == '=' && equation.charAt(2) == '=') { + uf.union(equation.charAt(0) - 'a', equation.charAt(3) - 'a'); + } + } + + for (String equation : equations) { + if (equation.charAt(1) == '!') { + if (uf.isSameComponent(equation.charAt(0) - 'a', equation.charAt(3) - 'a')) { + return false; + } + } + } + + return true; + } + + + static class UnionFind { + int[] parent; + int[] rank; + + public UnionFind(int n) { + this.parent = new int[n]; + this.rank = new int[n]; + + for (int i = 0; i < n; i++) { + this.parent[i] = i; + } + } + + public boolean union(int x, int y) { + + int parentX = find(x); + int parentY = find(y); + + if (parentX == parentY) return false; + + if (rank[parentX] > rank[parentY]) { + parent[parentY] = parentX; + } else if (rank[parentY] > rank[parentX]) { + parent[parentX] = parentY; + } else { + parent[parentY] = parentX; + rank[parentX]++; + } + + return true; + } + + public int find(int x) { + if (parent[x] == x) return x; + + parent[x] = find(parent[x]); + return parent[x]; + } + + public boolean isSameComponent(int p, int q) { + return find(p) == find(q); + } + } +} \ No newline at end of file diff --git a/src/main/java/graph/leetcode/FindAllSafeStates.java b/src/main/java/graph/leetcode/FindAllSafeStates.java new file mode 100644 index 0000000..3ba13f7 --- /dev/null +++ b/src/main/java/graph/leetcode/FindAllSafeStates.java @@ -0,0 +1,43 @@ +package graph.leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * https://leetcode.com/problems/find-eventual-safe-states + * + * similar to Topological sort, asks to remove cycles and return non cyclic paths + */ +public class FindAllSafeStates { + + enum State { + VISITED, + VISITING + } + + public List eventualSafeNodes(int[][] graph) { + List safeNodes = new ArrayList<>(graph.length); + State[] states = new State[graph.length]; + for (int node = 0; node < graph.length; node++) { + if (isSafe(graph, node, states)) { + safeNodes.add(node); + } + } + return safeNodes; + } + + private boolean isSafe(int[][] graph, int node, State[] states) { + if (states[node] != null) { + return states[node] == State.VISITED; + } + + states[node] = State.VISITING; + + for (int next : graph[node]) { + if (!isSafe(graph, next, states)) return false; + } + + states[node] = State.VISITED; + return true; + } +} diff --git a/src/graph/leetcode/FindJudge.java b/src/main/java/graph/leetcode/FindJudge.java similarity index 100% rename from src/graph/leetcode/FindJudge.java rename to src/main/java/graph/leetcode/FindJudge.java diff --git a/src/main/java/graph/leetcode/FindTheCity.java b/src/main/java/graph/leetcode/FindTheCity.java new file mode 100644 index 0000000..d5244d7 --- /dev/null +++ b/src/main/java/graph/leetcode/FindTheCity.java @@ -0,0 +1,126 @@ +package graph.leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; + +public class FindTheCity { + + /** + * This problem is path finding with positive weighted edges, + * so Dijkstras immediately pops into mind. Dijkstras is a smallest path finding algorithm that works on graphs with positive weights. + * Dijkstras is a SSSP (Single Source Shortest Path) algorithm, + * so that means we will need to perform Dijkstras on every single vertex and treat it as the start because every city is a potential answer. + * + * + Build the graph using the edges input + Iterate over all the vertices and perform Dijkstras on that vertex as the start node + Dijkstra will tell you how many cities are <= distanceThreshold + Keep a count of the smallest count + + */ + public int findTheCity(int n, int[][] edges, int distanceThreshold) { + Map> g = buildGraph(n ,edges); + int result = 0, reachableCities = n; + for(int city = 0; city < n; city++){ + int[] costs = dijsktra(city, g, n); + + int count = 0; + for(int cost : costs){ + if(cost <= distanceThreshold){ + count++; + } + } + if(count <= reachableCities){ + result = city; + reachableCities = count; + } + } + return result; + } + int[] dijsktra(int sourceCity, Map> g, int n){ + int[] costs = new int[n]; + Arrays.fill(costs, 10001); + + PriorityQueue queue = new PriorityQueue<>(Comparator.comparingInt(a->a[0])); + costs[sourceCity] = 0; + queue.add(new int[]{0,sourceCity}); + while (!queue.isEmpty()){ + int[] temp = queue.poll(); + int currentCity = temp[1]; + int currTime = temp[0]; + + if(costs[currentCity] neighbours = g.get(currentCity); + for(int[] c: neighbours){ + int toCity = c[0], distance = c[1]; + if(costs[toCity] > currTime + distance){ + costs[toCity] = currTime + distance; + queue.add(new int[]{costs[toCity],toCity}); + } + } + } + return costs; + } + + Map> buildGraph(int totalCities, int[][] edges){ + Map> g = new HashMap<>(); + + for(int city = 0; city < totalCities; city++){ + g.put(city, new ArrayList<>()); + } + + for(int[] e : edges){ + int cityA = e[0], cityB = e[1], distance = e[2]; + g.get(cityA).add(new int[]{cityB, distance}); + g.get(cityB).add(new int[]{cityA, distance}); + } + return g; + } + + public int findTheCityFloydWarshal(int n, int[][] edges, int distanceThreshold) { + + int[][] dis = new int[n][n]; + int res = 0, smallest = n; + + for (int[] row : dis) + Arrays.fill(row, 10001); + + for (int[] e : edges){ + int cityA = e[0]; + int cityB = e[1]; + int cost = e[2]; + + dis[cityA][cityB] = cost; + dis[cityB][cityA] = cost; + } + + + for (int i = 0; i < n; ++i) + dis[i][i] = 0; + + + for (int k = 0; k < n; ++k) + for (int i = 0; i < n; ++i) + for (int j = 0; j < n; ++j) + dis[i][j] = Math.min(dis[i][j], dis[i][k] + dis[k][j]); + + + for (int i = 0; i < n; i++) { + int count = 0; + for (int j = 0; j < n; ++j) + if (dis[i][j] <= distanceThreshold) + ++count; + if (count <= smallest) { + res = i; + smallest = count; + } + } + return res; + } + +} diff --git a/src/graph/leetcode/FriendCircles.java b/src/main/java/graph/leetcode/FriendCircles.java similarity index 99% rename from src/graph/leetcode/FriendCircles.java rename to src/main/java/graph/leetcode/FriendCircles.java index b6d715e..1a153e2 100644 --- a/src/graph/leetcode/FriendCircles.java +++ b/src/main/java/graph/leetcode/FriendCircles.java @@ -39,6 +39,7 @@ public void union(int x, int y){ int rootY= find(y); if(rootX==rootY) return; + if(rank[rootX]>rank[rootY]){ parent[rootY]=rootX; }else if(rank[rootY]>rank[rootX]){ diff --git a/src/main/java/graph/leetcode/GraphBiPartite.java b/src/main/java/graph/leetcode/GraphBiPartite.java new file mode 100644 index 0000000..790cb7f --- /dev/null +++ b/src/main/java/graph/leetcode/GraphBiPartite.java @@ -0,0 +1,32 @@ +package graph.leetcode; + +/** + * https://leetcode.com/problems/is-graph-bipartite/ + */ +public class GraphBiPartite { + public boolean isBipartite(int[][] graph) { + Integer[] color = new Integer[graph.length]; + + for (int i = 0; i < graph.length; i++) { //This graph might be a disconnected graph. So check each unvisited node. + if (color[i] == null && !dfs(graph, color, 1, i)) { + return false; + } + } + + return true; + } + + public boolean dfs(int[][] graph, Integer[] colors, int curColor, int node) { + colors[node] = curColor; + + for (int neighbor : graph[node]) { + if (colors[neighbor] == null ){ + if(!dfs(graph, colors, -curColor, neighbor)) // If this node hasn't been colored, Color it with a different color + return false; + } else if (colors[neighbor] == curColor) { + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/src/main/java/graph/leetcode/GraphBiPartitePossiblity.java b/src/main/java/graph/leetcode/GraphBiPartitePossiblity.java new file mode 100644 index 0000000..f688c85 --- /dev/null +++ b/src/main/java/graph/leetcode/GraphBiPartitePossiblity.java @@ -0,0 +1,40 @@ +package graph.leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * https://leetcode.com/problems/possible-bipartition/submissions/ + * https://www.youtube.com/watch?v=hWFqtlbnQV8&ab_channel=KnowledgeCenter + */ +public class GraphBiPartitePossiblity { + public boolean possibleBipartition(int N, int[][] dislikes) { + List[] graph = new List[N + 1]; + for (int i = 1; i <= N; ++i) graph[i] = new ArrayList<>(); + for (int[] dislike : dislikes) { + graph[dislike[0]].add(dislike[1]); + graph[dislike[1]].add(dislike[0]); + } + + Integer[] colors = new Integer[N + 1]; + for (int i = 1; i <= N; i++) { + // If the connected component that node i belongs to hasn't been colored yet then try coloring it. + if (colors[i] == null && !dfs(graph, colors, i, 1)) return false; + } + return true; + } + + private boolean dfs(List[] graph, Integer[] colors, int currNode, int currColor) { + colors[currNode] = currColor; + + // Color all uncolored adjacent nodes. + for (Integer adjacentNode : graph[currNode]) { + if (colors[adjacentNode] == null) { + if (!dfs(graph, colors, adjacentNode, currColor * -1)) return false; + } else if (colors[adjacentNode] == currColor) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/graph/leetcode/GraphValidTree.java b/src/main/java/graph/leetcode/GraphValidTree.java new file mode 100644 index 0000000..a18d4f1 --- /dev/null +++ b/src/main/java/graph/leetcode/GraphValidTree.java @@ -0,0 +1,60 @@ +package graph.leetcode; + +public class GraphValidTree { + + public boolean validTree(int n, int[][] edges) { + UnionFind uf = new UnionFind(n); + int M = edges.length; + for (int i = 0; i < M; i++) { + int p = edges[i][0], q = edges[i][1]; + if (uf.find(p) == uf.find(q)) { + return false; + } + uf.union(p, q); + } + + return uf.count == 1; + } + + class UnionFind { + int[] parent; + int[] rank; + int count; + + public UnionFind(int n) { + parent = new int[n]; + rank = new int[n]; + count = n; + for (int i = 0; i < n; i++) { + parent[i] = i; + } + } + + public int find(int n) { + if (parent[n] == n) return n; + parent[n] = find(parent[n]); + return parent[n]; + } + + public void union(int x, int y) { + int rootX = find(x); + int rootY = find(y); + + if (rootX == rootY) return; + + if (rank[rootX] > rank[rootY]) { + parent[rootY] = rootX; + } else if (rank[rootY] > rank[rootX]) { + parent[rootX] = rootY; + } else { + parent[rootY] = rootX; + rank[rootX]++; + } + count--; + } + + public int getCount() { + return count; + } + } +} diff --git a/src/practiceproblems/IslandBFS.java b/src/main/java/graph/leetcode/IslandBFS.java similarity index 98% rename from src/practiceproblems/IslandBFS.java rename to src/main/java/graph/leetcode/IslandBFS.java index c8f941a..74ff277 100644 --- a/src/practiceproblems/IslandBFS.java +++ b/src/main/java/graph/leetcode/IslandBFS.java @@ -1,4 +1,4 @@ -package practiceproblems; +package graph.leetcode; import java.util.ArrayDeque; import java.util.Queue; diff --git a/src/main/java/graph/leetcode/MakeIslandLarger.java b/src/main/java/graph/leetcode/MakeIslandLarger.java new file mode 100644 index 0000000..75b55de --- /dev/null +++ b/src/main/java/graph/leetcode/MakeIslandLarger.java @@ -0,0 +1,129 @@ +package graph.leetcode; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * https://leetcode.com/problems/making-a-large-island + * + * You are given an n x n binary matrix grid. You are allowed to change at most one 0 to be 1. + * + * Return the size of the largest island in grid after applying this operation. + */ +public class MakeIslandLarger { + + /** + * Worst time is O(M*N)^2 + * this is same as island problem but here we need to change any one of the index + * we change a water area to grid[i][j] = 1; and once calculated its size + * we revert to grid[i][j] = 0; + * so for every i,j we check all the entries. + * + * @param grid + * @return + */ + public int largestIslandBruteForce(int[][] grid) { + int result = 0; + int m = grid.length; + int n = grid[0].length; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 1) continue; + grid[i][j] = 1; + result = Math.max(result, dfs(i, j, new boolean[m][n], grid)); + grid[i][j] = 0; + } + } + + return result == 0 ? m * n : result; + } + + public int dfs(int i, int j, boolean[][] visited, int[][] grid) { + if (i < 0 || i >= visited.length || j < 0 || j >= visited[0].length || visited[i][j] || grid[i][j] == 0) + return 0; + + visited[i][j] = true; + + return 1 + dfs(i + 1, j, visited, grid) + dfs(i, j + 1, visited, grid) + dfs(i - 1, j, visited, grid) + dfs(i, j - 1, visited, grid); + + } + + /** + * https://www.youtube.com/watch?v=_426VVOB8Vo&ab_channel=MichaelMuinos + * time is O(M*N) + *

+ * For each 1 in the grid, we paint all connected 1 with the next available color (2, 3, and so on). + * We also remember the size of the island we just painted with that color. + *

+ * Then, we analyze all 0 in the grid, + * and sum sizes of connected islands (based on the island color). + * Note that the same island can connect to 0 more than once. + * The example below demonstrates this idea (the answer is highlighted): + * input: + * 0 1 0 1 0 + * 1 1 0 0 1 + * 0 0 1 1 0 + *

+ * transformed group: 2 is one group of island, 3 is one group, 4 is one group and 5 is another + * the length of each group is stored in map + * 0 2 0 3 0 + * 2 2 0 0 4 + * 0 0 5 5 0 + *

+ * we iterate the matrix back, whenever we find 0, we see all the neighbours group value + * for example at index grid[0][2] we have 2 and 3 as neighbours, we add both of the group's length + * to sum and add 1 to it because we are considering grid[0][2] is changed to land now + * sum = 1+ 3(2's length) + 1 (3's length) => 5 + * + * @param grid + * @return + */ + + public int largestIsland(int[][] grid) { + Map map = new HashMap<>(); //Key: color, Val: size of island painted of that color + map.put(0, 0); //We won't paint island 0, hence make its size 0, we will use this value later + int n = grid.length; + int colorIndex = 2; //0 and 1 is already used in grid, hence we start colorIndex from 2 + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == 1) { + int size = paint(grid, i, j, colorIndex); + map.put(colorIndex, size); + colorIndex++; + } + } + } + + //If there is no island 0 from grid, res should be the size of islands of first color + //If there is no island 1 from grid, res should be 0 + int res = map.getOrDefault(2, 0); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == 0) { + //We use a set to avoid repeatedly adding islands with the same color + Set set = new HashSet<>(); + //If current island is at the boundary, we add 0 to the set, whose value is 0 in the map + set.add(i > 0 ? grid[i - 1][j] : 0); + set.add(i < n - 1 ? grid[i + 1][j] : 0); + set.add(j > 0 ? grid[i][j - 1] : 0); + set.add(j < n - 1 ? grid[i][j + 1] : 0); + + int newSize = 1; //We need to count current island as well, hence we init newSize with 1 + for (int color : set) newSize += map.get(color); + res = Math.max(res, newSize); + } + } + } + return res; + } + + //Helper method to paint current island and all its connected neighbors + //Return the size of all painted islands at the end + private int paint(int[][] grid, int i, int j, int color) { + if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] != 1) return 0; + grid[i][j] = color; + return 1 + paint(grid, i + 1, j, color) + paint(grid, i - 1, j, color) + paint(grid, i, j + 1, color) + paint(grid, i, j - 1, color); + } +} diff --git a/src/main/java/graph/leetcode/MatrixStoneRemoval.java b/src/main/java/graph/leetcode/MatrixStoneRemoval.java new file mode 100644 index 0000000..ab436de --- /dev/null +++ b/src/main/java/graph/leetcode/MatrixStoneRemoval.java @@ -0,0 +1,71 @@ +package graph.leetcode; + +/** + * https://leetcode.com/problems/most-stones-removed-with-same-row-or-column + */ +public class MatrixStoneRemoval { + + public int removeStones(int[][] stones) { + + int n = stones.length; + UnionFind uf = new UnionFind(n); + for (int i = 0; i < stones.length; i++) { + for (int j = i + 1; j < stones.length; j++) { + // if any two points are on the same column or row, they are connected as a + // edge. + // find connected component, and remove all but one. + // count the number of disjoint components. + if (stones[i][0] == stones[j][0] || stones[i][1] == stones[j][1]) { + uf.union(i, j); + } + } + } + + /** + * For each island, there will be only 1 stone left after removing the stones on the same island. + * So the left stone after removing all stones is equal to the number of islands, + * and the maximum removed stone number (Note: maximum) will be equal to #stone - #islands. + * + * Why it is the maximum? Considering an island with connecting stone a-b-c. + * If you remove a and c, the maximum count you can remove is 2. However, if you remove 2 first, the remove count will be only 1. + */ + return n - uf.components; + } + + static class UnionFind { + int[] parent; + int[] rank; + int components = 0; + + public UnionFind(int size) { + parent = new int[size]; + for (int i = 0; i < size; i++) { + parent[i] = i; + } + rank = new int[size]; + this.components = size; + } + + public int find(int x) { + if (parent[x] != x) parent[x] = find(parent[x]); + return parent[x]; + } + + public boolean union(int x, int y) { + int xRank = find(x), yRank = find(y); + if (xRank == yRank) { + return false; + } else if (rank[xRank] < rank[yRank]) { + parent[xRank] = yRank; + } else if (rank[xRank] > rank[yRank]) { + parent[yRank] = xRank; + } else { + parent[yRank] = xRank; + rank[xRank]++; + } + components--; + return true; + + } + } +} diff --git a/src/main/java/graph/leetcode/MaxDistanceFromWater.java b/src/main/java/graph/leetcode/MaxDistanceFromWater.java new file mode 100644 index 0000000..81954df --- /dev/null +++ b/src/main/java/graph/leetcode/MaxDistanceFromWater.java @@ -0,0 +1,39 @@ +package graph.leetcode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * https://leetcode.com/problems/as-far-from-land-as-possible + */ +public class MaxDistanceFromWater { + + public int maxDistance(int[][] grid) { + int m = grid.length, n = grid[0].length; + Queue queue = new LinkedList<>(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == 1) queue.offer(new int[]{i, j}); + } + } + if (queue.isEmpty() || queue.size() == m * n) return -1; + int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; + int max = 0; + while (!queue.isEmpty()) { + int size = queue.size(); + for (int i = 0; i < size; i++) { + int[] point = queue.poll(); + for (int[] dir : dirs) { + int x = point[0] + dir[0]; + int y = point[1] + dir[1]; + if (x >= 0 && y >= 0 && x < m && y < n && grid[x][y] == 0) { + grid[x][y] = 1;// convert to mark as visited + queue.offer(new int[]{x, y}); + } + } + } + max++; + } + return max - 1; + } +} diff --git a/src/main/java/graph/leetcode/MaxProbabilityPath.java b/src/main/java/graph/leetcode/MaxProbabilityPath.java new file mode 100644 index 0000000..89644b7 --- /dev/null +++ b/src/main/java/graph/leetcode/MaxProbabilityPath.java @@ -0,0 +1,47 @@ +package graph.leetcode; + +import javafx.util.Pair; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * https://leetcode.com/problems/path-with-maximum-probability + */ +public class MaxProbabilityPath { + public double maxProbability(int n, int[][] edges, double[] succProb, int start, int end) { + // Create the weighted undirected graph (adjacency list). + Map>> graph = new HashMap<>(); // It's better to create a separate class instead of using Pair<> but this is leetcode. + for (int i = 0; i < n; ++i) graph.put(i, new ArrayList<>()); + for (int i = 0; i < edges.length; ++i) { + graph.get(edges[i][0]).add(new Pair<>(edges[i][1], succProb[i])); + graph.get(edges[i][1]).add(new Pair<>(edges[i][0], succProb[i])); + } + // Dijkstra to find max probability path from start to end node. + Double[] costs = new Double[n]; + // Order from greatest to lowest probability. + PriorityQueue> queue = new PriorityQueue<>((a, b) -> Double.compare(b.getValue(), a.getValue())); + queue.add(new Pair<>(start, 1.0)); // Initially we are at the start node with a probability of 1. + while (!queue.isEmpty()) { + Pair temp = queue.remove(); + int currNode = temp.getKey(); + double currProb = temp.getValue(); + + if (costs[currNode] != null) continue; + costs[currNode] = currProb; + if (currNode == end) break; + + for (Pair adjacentNode : graph.get(currNode)) { + int adjNode = adjacentNode.getKey(); + double adjProb = adjacentNode.getValue(); + if (costs[adjNode] == null) { + queue.add(new Pair<>(adjNode, currProb * adjProb)); + } + } + } + return costs[end] == null ? 0 : costs[end]; + } +} diff --git a/src/main/java/graph/leetcode/MinCostConnectAllPipes.java b/src/main/java/graph/leetcode/MinCostConnectAllPipes.java new file mode 100644 index 0000000..9996569 --- /dev/null +++ b/src/main/java/graph/leetcode/MinCostConnectAllPipes.java @@ -0,0 +1,82 @@ +package graph.leetcode; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class MinCostConnectAllPipes { + List graphEdges; + + public int minCostToSupplyWater(int n, int[] wells, int[][] pipes) { + graphEdges = new ArrayList<>(); + addEdges(n, wells, pipes); + return minCostKruskals(n); + } + + /// select edges based on Kruskals - with least edge node to be added first + private int minCostKruskals(int n) { + /// Sort edges in increasing order of edge value + graphEdges.sort(Comparator.comparingInt(a -> a[2])); + int minCost = 0, processedEdges = 0; + + DSU dsu = new DSU(n + 1); + for (int[] edge : graphEdges) { + /// check if this can be merged (in this case:`union`) to the existing graph component + if (dsu.union(edge[0], edge[1])) { + processedEdges++; + minCost += edge[2]; + /// Break processing once all edges are processed + if (processedEdges == n) break; + } + } + return minCost; + } + + private void addEdges(int n, int[] wells, int[][] pipes) { + // build an imaginary edge between node 0 to all other houses so that + // even the wells are converted into edges. Now it's a proper MST problem + for (int i = 0; i < n; i++) { + graphEdges.add(new int[]{0, i + 1, wells[i]}); + } + + Collections.addAll(graphEdges, pipes); + } + + /// Disjoint Set Union Implementation + static class DSU { + int[] parent; + int[] rank; + + DSU(int n) { + parent = new int[n]; + rank = new int[n]; + for (int i = 0; i < n; i++) parent[i] = i; + } + + public int find(int x) { + if (x != parent[x]) { + parent[x] = find(parent[x]); + } + return parent[x]; + } + + public boolean union(int x, int y) { + int rootX = find(x); + int rootY = find(y); + /// same root - no need to merge (since both are part of same tree) + if (rootX == rootY) return false; + + /// merge if they have different root + if (parent[rootX] > parent[rootY]) { + parent[rootY] = rootX; + } else if (parent[rootX] < parent[rootY]) { + parent[rootX] = rootY; + } else { + parent[rootY] = rootX; + rank[rootX]++; + } + return true; + } + } +} \ No newline at end of file diff --git a/src/main/java/graph/leetcode/MinCostConnectCities.java b/src/main/java/graph/leetcode/MinCostConnectCities.java new file mode 100644 index 0000000..79045e6 --- /dev/null +++ b/src/main/java/graph/leetcode/MinCostConnectCities.java @@ -0,0 +1,74 @@ +package graph.leetcode; + +import java.util.Arrays; +import java.util.Comparator; + +public class MinCostConnectCities { + public int minimumCost(int n, int[][] connections) { + // Check edge case, we need at least n - 1 connections to + // connect all cities + if (connections.length < n - 1) { + return -1; + } + // We need to first sort by the cost to ensure every time we join + // we are picking the minimum cost (Greedy Approach) + Arrays.sort(connections, Comparator.comparingInt(a -> a[2])); + + int result = 0; + + UnionFind uf = new UnionFind(n); + + // Since the connections are sorted with cost from min to max + // Every single time if we found we can union one connection, + // we add that optimal cost to our totalCost + // Whenever there is only one component left, a.k.a all cities are connected. + // then we are done, just return the totalCost. + for (int[] connection : connections) { + // Remember to subtract 1 since the cities are 1-indexed while our + // Uf class is 0-indexed. + if (uf.union(connection[0]-1, connection[1]-1)) { + result += connection[2]; + } + + if (uf.components == 1) return result; + } + + return -1; + } + + static class UnionFind { + int[] parent; + int[] rank; + int components; + + public UnionFind(int n) { + this.parent = new int[n]; + this.rank = new int[n]; + this.components = n ; + for (int i = 0; i < n; i++) { + this.parent[i] = i; + } + } + + public boolean union(int x, int y) { + int xRank = find(x), yRank = find(y); + if (xRank == yRank) { + return false; + } else if (rank[xRank] < rank[yRank]) { + parent[xRank] = yRank; + } else if (rank[xRank] > rank[yRank]) { + parent[yRank] = xRank; + } else { + parent[yRank] = xRank; + rank[xRank]++; + } + components--; + return true; + } + + public int find(int x) { + if (parent[x] != x) parent[x] = find(parent[x]); + return parent[x]; + } + } +} diff --git a/src/main/java/graph/leetcode/MinCostConnectPoints.java b/src/main/java/graph/leetcode/MinCostConnectPoints.java new file mode 100644 index 0000000..2b969e4 --- /dev/null +++ b/src/main/java/graph/leetcode/MinCostConnectPoints.java @@ -0,0 +1,90 @@ +package graph.leetcode; + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +/** + * https://leetcode.com/problems/min-cost-to-connect-all-points + */ +public class MinCostConnectPoints { + + public int minCostConnectPoints(int[][] points) { + List edges = new ArrayList<>(); + for (int i = 0; i < points.length; i++) { + for (int j = i + 1; j < points.length; j++) { + edges.add(new Edge(i, j, Math.abs(points[i][0] - points[j][0]) + Math.abs(points[i][1] - points[j][1]))); + } + } + + edges.sort(Comparator.comparingInt(e -> e.dist)); + + DSU dsu = new DSU(points.length); + int minCost = 0; + + for (Edge edge : edges) { + if (dsu.union(edge.p1, edge.p2)) { + minCost += edge.dist; + } + if (dsu.componentSize(edge.p1) == points.length) { + return minCost; + } + } + + return minCost; + } + + static class DSU { + int[] parent; + int[] rank; + + public DSU(int N) { + parent = new int[N]; + for (int i = 0; i < N; i++) { + parent[i] = i; + } + rank = new int[N]; + Arrays.fill(rank, 1); + } + + public int find(int x) { + if (x != parent[x]) parent[x] = find(parent[x]); + return parent[x]; + } + + public boolean union(int x, int y) { + int xp = find(x) ; + int yp = find(y); + + if (xp == yp) return false; + + if (rank[xp] < rank[yp]) { + int t = xp; + xp = yp; + yp = t; + } + + parent[yp] = xp; + rank[xp] += rank[yp]; + return true; + } + + public int componentSize(int x) { + return rank[find(x)]; + } + } + + static class Edge { + int p1; + int p2; + int dist; + + public Edge(int x, int y, int dist) { + this.p1 = x; + this.p2 = y; + this.dist = dist; + } + } +} diff --git a/src/graph/leetcode/MinCostRepairEdges.java b/src/main/java/graph/leetcode/MinCostRepairEdges.java similarity index 92% rename from src/graph/leetcode/MinCostRepairEdges.java rename to src/main/java/graph/leetcode/MinCostRepairEdges.java index 5973234..41551ab 100644 --- a/src/graph/leetcode/MinCostRepairEdges.java +++ b/src/main/java/graph/leetcode/MinCostRepairEdges.java @@ -6,7 +6,8 @@ import java.util.Set; /** - * There's an undirected connected graph with n nodes labeled 1..n. But some of the edges has been broken disconnecting the graph. Find the minimum cost to repair the edges so that all the nodes are once again accessible from each other. + * There's an undirected connected graph with n nodes labeled 1..n. + * But some of the edges has been broken disconnecting the graph. Find the minimum cost to repair the edges so that all the nodes are once again accessible from each other. *

* Input: *

diff --git a/src/main/java/graph/leetcode/MinPathHavingMaxDifference.java b/src/main/java/graph/leetcode/MinPathHavingMaxDifference.java new file mode 100644 index 0000000..3308822 --- /dev/null +++ b/src/main/java/graph/leetcode/MinPathHavingMaxDifference.java @@ -0,0 +1,89 @@ +package graph.leetcode; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.PriorityQueue; +import java.util.Set; + +/** + * https://leetcode.com/problems/path-with-minimum-effort/ + *

+ * https://leetcode.com/problems/swim-in-rising-water/ + *

+ * both are almost similar + */ +public class MinPathHavingMaxDifference { + public int minimumEffortPath(int[][] heights) { + + int m = heights.length; + int n = heights[0].length; + + int[][] dist = new int[m][n]; + + for (int[] d : dist) { + Arrays.fill(d, Integer.MAX_VALUE); + } + + PriorityQueue queue = new PriorityQueue<>((a, b) -> Integer.compare(a[2], b[2])); + + queue.offer(new int[]{0, 0, 0}); + dist[0][0] = 0; + Set set = new HashSet<>(); + int[][] dirs = new int[][]{{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + int result = 0; + while (!queue.isEmpty()) { + + int[] node = queue.poll(); + + int x = node[0]; + int y = node[1]; + int distance = node[2]; + + if (distance > dist[x][y]) continue; + + result = Math.max(result, distance); + if (x == m - 1 && y == n - 1) return result; + + if (!set.add(x + "-" + y)) continue; + for (int[] dir : dirs) { + + int newX = x + dir[0]; + int newY = y + dir[1]; + + if (newX < 0 || newY < 0 || newX >= m || newY >= n) continue; + + int diff = Math.abs(heights[x][y] - heights[newX][newY]); + dist[newX][newY] = diff; + queue.offer(new int[]{newX, newY, diff}); + } + } + + return -1; + } + + public int swimInWater(int[][] grid) { + int n = grid.length; + PriorityQueue pq = new PriorityQueue<>((a, b) -> a[2] - b[2]); + boolean[][] visited = new boolean[n][n]; + int[][] dirs = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}}; + + visited[0][0] = true; + pq.offer(new int[]{0, 0, grid[0][0]}); + while (!pq.isEmpty()) { + int[] info = pq.poll(); + int i = info[0], j = info[1], max = info[2]; + for (int[] dir : dirs) { + int newI = dir[0] + i, newJ = dir[1] + j; + if (newI < 0 || newI >= n || newJ < 0 || newJ >= n) continue; + if (!visited[newI][newJ]) { + visited[newI][newJ] = true; + int newmax = Math.max(max, grid[newI][newJ]); + if (newI == n - 1 && newJ == n - 1) return newmax; + pq.offer(new int[]{newI, newJ, newmax}); + } + } + } + + return 0; + } +} diff --git a/src/main/java/graph/leetcode/MinStepsToCutTrees.java b/src/main/java/graph/leetcode/MinStepsToCutTrees.java new file mode 100644 index 0000000..7d059f6 --- /dev/null +++ b/src/main/java/graph/leetcode/MinStepsToCutTrees.java @@ -0,0 +1,94 @@ +package graph.leetcode; + +import java.util.Comparator; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.PriorityQueue; +import java.util.Queue; +import java.util.Set; + +/** + * https://leetcode.com/problems/cut-off-trees-for-golf-event + */ +public class MinStepsToCutTrees { + public int cutOffTree(List> forest) { + int m = forest.size(); + if (m == 0) return 0; + int n = forest.get(0).size(); + PriorityQueue pq = new PriorityQueue<>(Comparator.comparingInt(a -> a.height)); + + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + int h = forest.get(i).get(j); + if (h > 1) { + pq.offer(new Node(i, j, h)); + } + } + } + + Node source = new Node(0, 0, 0); + Node target = null; + int res = 0; + while (!pq.isEmpty()) { + target = pq.poll(); + int distance = getMinDistance(forest, source, target); + if (distance == -1) return -1; + else res += distance; + source = target; + } + return res; + } + + int getMinDistance(List> forest, Node source, Node target) { + int m = forest.size(), n = forest.get(0).size(); + int[][] dir = new int[][]{{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; + Queue q = new LinkedList<>(); + Set visited = new HashSet<>(); + q.offer(source); + int step = 0; + while (!q.isEmpty()) { + int size = q.size(); + for (int i = 0; i < size; i++) { + Node node = q.poll(); + if (node.equals(target)) { + return step; + } + for (int[] row : dir) { + int x = node.x + row[0]; + int y = node.y + row[1]; + if (x < 0 || y < 0 || x >= m || y >= n || forest.get(x).get(y) == 0) { + continue; + } + Node newNode = new Node(x, y, forest.get(x).get(y)); + if (!visited.contains(newNode)) { + visited.add(newNode); + q.offer(newNode); + } + } + } + step++; + } + return -1; + } + + class Node { + int x, y; + int height; + + Node(int xx, int yy, int hh) { + x = xx; + y = yy; + height = hh; + } + + public int hashCode() { + return x * 31 + y; + } + + public boolean equals(Object obj) { + Node other = (Node) obj; + return (other.x == x) && (other.y == y); + } + } +} diff --git a/src/main/java/graph/leetcode/MinimumHeightTrees.java b/src/main/java/graph/leetcode/MinimumHeightTrees.java new file mode 100644 index 0000000..1f29aba --- /dev/null +++ b/src/main/java/graph/leetcode/MinimumHeightTrees.java @@ -0,0 +1,63 @@ +package graph.leetcode; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * Basically my code starts from the leaf nodes. + * + * For leaf nodes, their degree = 1, which means each of them is only connected to one node. + * + * In our loop, each time we delete the leaf nodes from our graph(just by putting their degrees to 0), + * and meanwhile we add the new leaf nodes after deleting them to the queue. + * + * So basically in the end, the nodes in the queue would be connected to no other nodes but each other. They should be the answer. + */ +public class MinimumHeightTrees { + + public List findMinHeightTrees(int n, int[][] edges) { + List res = new ArrayList<>(); + if (n <= 0) return res; + //this is needed...since when there is only 1 vertex... the indegree of it will be 0..this case is not included in the following discussion... + if (n == 1) { + res.add(0); + return res; + } + List[] graph = (ArrayList[]) new ArrayList[n]; + for (int i = 0; i < n; i++) { + graph[i] = new ArrayList<>(); + } + + for (int[] e : edges) { + graph[e[0]].add(e[1]); + graph[e[1]].add(e[0]); + } + + int[] indegree = new int[n]; + int cnt = n; + Queue leaves = new LinkedList<>(); + for (int i = 0; i < n; i++) { + indegree[i] = graph[i].size(); + if (indegree[i] == 1) { + leaves.add(i); + } + } + while (cnt > 2) { + int size = leaves.size(); + cnt -= size; + for (int i = 0; i < size; i++) { + int v = leaves.poll(); + for (int w : graph[v]) { + indegree[w]--; + if (indegree[w] == 1) { + leaves.add(w); + } + } + } + } + res.addAll(leaves); + return res; + } +} diff --git a/src/main/java/graph/leetcode/NetworkConnection.java b/src/main/java/graph/leetcode/NetworkConnection.java new file mode 100644 index 0000000..52dc48d --- /dev/null +++ b/src/main/java/graph/leetcode/NetworkConnection.java @@ -0,0 +1,62 @@ +package graph.leetcode; + +/** + * https://leetcode.com/problems/number-of-operations-to-make-network-connected + * + * + Perform union find during the traversal of the connections; deduct the number of components when merging any two components; + If there are less than n - 1 connections, no way to make the network connected; + Otherwise need number of components - 1 operations for the network to be fully connected. + + */ +public class NetworkConnection { + + public int makeConnected(int n, int[][] connections) { + + UnionFind uf = new UnionFind(n); + + for (int[] connection : connections) { + uf.union(connection[0], connection[1]); + } + + return connections.length < n - 1 ? -1 : uf.components - 1; + + } + + static class UnionFind { + int[] parent; + int[] rank; + int components = 0; + + public UnionFind(int size) { + parent = new int[size]; + for (int i = 0; i < size; i++) { + parent[i] = i; + } + rank = new int[size]; + this.components = size; + } + + public int find(int x) { + if (parent[x] != x) parent[x] = find(parent[x]); + return parent[x]; + } + + public boolean union(int x, int y) { + int xRank = find(x), yRank = find(y); + if (xRank == yRank) { + return false; + } else if (rank[xRank] < rank[yRank]) { + parent[xRank] = yRank; + } else if (rank[xRank] > rank[yRank]) { + parent[yRank] = xRank; + } else { + parent[yRank] = xRank; + rank[xRank]++; + } + components--; + return true; + + } + } +} diff --git a/src/main/java/graph/leetcode/NetworkDelayTime.java b/src/main/java/graph/leetcode/NetworkDelayTime.java new file mode 100644 index 0000000..a582e5d --- /dev/null +++ b/src/main/java/graph/leetcode/NetworkDelayTime.java @@ -0,0 +1,94 @@ +package graph.leetcode; + +import javafx.util.Pair; + +import java.util.*; +/** + * There are N network nodes, labelled 1 to N. + * + * Given times, a list of travel times as directed edges times[i] = (u, v, w), where u is the source node, v is the target node, + * and w is the time it takes for a signal to travel from source to target. + * + * Now, we send a signal from a certain node K. How long will it take for all nodes to receive the signal? If it is impossible, return -1. + */ +public class NetworkDelayTime { + + public int networkDelayTime(int[][] times, int N, int K) { + Map>> adj = new HashMap<>(); + for (int[] time : times) { + int source = time[0]; + int dest = time[1]; + int travelTime = time[2]; + + adj.putIfAbsent(source, new ArrayList<>()); + adj.get(source).add(new Pair<>(travelTime, dest)); + } + + + int[] signalReceivedAt = new int[N + 1]; + Arrays.fill(signalReceivedAt, Integer.MAX_VALUE); + //distance, node into pq + Queue pq = new PriorityQueue<>((a,b) -> (a[0] - b[0])); + + pq.add(new int[]{0, K}); + + signalReceivedAt[K] = 0; + Set visited = new HashSet<>(); + /** + * + Pop the top node currNode from the priority queue. + Traverse all outgoing edges connected to currNode. + Add the adjacent node neighborNode to the priority queue + only if the current path takes less time than the value at signalReceivedAt[neighborNode]. + Update the time at signalReceivedAt[neighborNode] to current path time. + */ + while(!pq.isEmpty()){ + int[] cur = pq.remove(); + + int currNode = cur[1]; + int currNodeTime = cur[0]; + + if (visited.contains(currNode)) { continue; } + if (currNodeTime > signalReceivedAt[currNode]) { + continue; + } + visited.add(currNode); + if(adj.containsKey(currNode)){ + for(Pair next : adj.get(currNode)){ + int time = next.getKey(); + int neighborNode = next.getValue(); + if (signalReceivedAt[neighborNode] > currNodeTime + time) { + signalReceivedAt[neighborNode] = currNodeTime + time; + pq.add(new int[]{signalReceivedAt[neighborNode], neighborNode}); + } + } + } + } + int answer = Integer.MIN_VALUE; + for (int i = 1; i <= N; i++) { + answer = Math.max(answer, signalReceivedAt[i]); + } + + // INT_MAX signifies atleat one node is unreachable + return answer == Integer.MAX_VALUE ? -1 : answer; + } + + public int networkDelayTime_BF(int[][] times, int N, int K) { + double[] disTo = new double[N+1]; + Arrays.fill(disTo, Double.POSITIVE_INFINITY); + disTo[K - 1] = 0; + for (int i = 1; i < N; i++) { + for (int[] edge : times) { + int u = edge[0] - 1, v = edge[1] - 1, w = edge[2]; + disTo[v] = Math.min(disTo[v], disTo[u] + w); + } + } + double res = Double.MIN_VALUE; + for (double i: disTo) { + res = Math.max(i, res); + } + return res == Double.POSITIVE_INFINITY ? -1 : (int) res; + } + +} + diff --git a/src/practiceproblems/NewRoadsMST.java b/src/main/java/graph/leetcode/NewRoadsMST.java similarity index 55% rename from src/practiceproblems/NewRoadsMST.java rename to src/main/java/graph/leetcode/NewRoadsMST.java index fb048e6..0911dce 100644 --- a/src/practiceproblems/NewRoadsMST.java +++ b/src/main/java/graph/leetcode/NewRoadsMST.java @@ -1,6 +1,7 @@ -package practiceproblems; +package graph.leetcode; import java.util.Arrays; +import java.util.Comparator; import java.util.PriorityQueue; import java.util.Queue; @@ -28,11 +29,11 @@ public static int minCost(int n, int[][] edges, int[][] newEdges) { uf.union(edge[0], edge[1]); } - Queue pq = new PriorityQueue<>(newEdges.length, (e1, e2) -> Integer.compare(e1[2], e2[2])); + Queue pq = new PriorityQueue<>(newEdges.length, Comparator.comparingInt(e -> e[2])); pq.addAll(Arrays.asList(newEdges)); int totalCost = 0; - // 2 because nodes are 1-based and we have 1 unused component at index 0 + // 2 because nodes are 1-based, and we have 1 unused component at index 0 while (!pq.isEmpty() && uf.count != 2) { int[] edge = pq.poll(); if (!uf.connected(edge[0], edge[1])) { @@ -42,45 +43,47 @@ public static int minCost(int n, int[][] edges, int[][] newEdges) { } return totalCost; } -} -class UF { - private int[] parent; // parent[i] = parent of i - private byte[] rank; // rank[i] = rank of subtree rooted at i (never more than 31) - public int count; // number of connected components + private static class UF { + private int[] parent; // parent[i] = parent of i + private byte[] rank; // rank[i] = rank of subtree rooted at i (never more than 31) + public int count; // number of connected components - public UF(int n) { - if (n < 0) throw new IllegalArgumentException(); - parent = new int[n]; - rank = new byte[n]; - for (int i = 0; i < n; i++) { - parent[i] = i; + public UF(int n) { + if (n < 0) throw new IllegalArgumentException(); + parent = new int[n]; + rank = new byte[n]; + for (int i = 0; i < n; i++) { + parent[i] = i; + } + count = n; } - count = n; - } - public int find(int p) { - while (p != parent[p]) { - parent[p] = parent[parent[p]]; - p = parent[p]; + public int find(int p) { + while (p != parent[p]) { + parent[p] = parent[parent[p]]; + p = parent[p]; + } + return p; } - return p; - } - public void union(int p, int q) { - int pr = find(p); - int qr = find(q); - if (pr == qr) return; - if (rank[pr] < rank[qr]) { - parent[pr] = qr; - } else { - parent[qr] = pr; - if (rank[pr] == rank[qr]) rank[pr]++; + public void union(int p, int q) { + int pr = find(p); + int qr = find(q); + if (pr == qr) return; + if (rank[pr] < rank[qr]) { + parent[pr] = qr; + } else { + parent[qr] = pr; + if (rank[pr] == rank[qr]) rank[pr]++; + } + count--; } - count--; - } - public boolean connected(int p, int q) { - return find(p) == find(q); + public boolean connected(int p, int q) { + return find(p) == find(q); + } } } + + diff --git a/src/main/java/graph/leetcode/PacificAtlantic.java b/src/main/java/graph/leetcode/PacificAtlantic.java new file mode 100644 index 0000000..c1ffa43 --- /dev/null +++ b/src/main/java/graph/leetcode/PacificAtlantic.java @@ -0,0 +1,71 @@ +package graph.leetcode; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * https://leetcode.com/problems/pacific-atlantic-water-flow/ + * + * tricky flood fill variant + * + * The matrix is the continent with water on it and the boundaries are the oceans. Left and top being Pacific and right and bottom being the Atlantic. + * The water on the continent (in the matrix) wants to flow out in the ocean. (Nature huh.) + * The numbers in the matrix is the height of the water for that point. + * For every point you have to ask the question. Can the water at this point and this height flow out in both the oceans + * under the constraints of flowing through only four(up, down, right, left) directions and flow into channels with same height or less height? + * If yes you return the coordinate of that point. Else you ignore it. + */ +public class PacificAtlantic { + + /** + * Now, if we start from the cells connected to altantic ocean and + * visit all cells having height greater than current cell (water can only flow from a cell to another one with height equal or lower), + * we are able to reach some subset of cells (let's call them A). + * + * Next, we start from the cells connected to pacific ocean and repeat the same process, we find another subset (let's call this one B). + * + * The final answer we get will be the intersection of sets A and B (A ∩ B). + */ + public List> pacificAtlantic(int[][] matrix) { + + List> res = new LinkedList<>(); + if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { + return res; + } + int n = matrix.length, m = matrix[0].length; + //We create a new boolean[][] matrix like above, all the beaches is marked as True (1) in the beginning, which means they can connect to the ocean, + // then we explore from the beach to find out all the paths. The idea is the same for Pacific and Atlantic. + + + boolean[][] pacific = new boolean[n][m]; + boolean[][] atlantic = new boolean[n][m]; + for (int i = 0; i < n; i++) { + dfs(matrix, pacific, Integer.MIN_VALUE, i, 0); + dfs(matrix, atlantic, Integer.MIN_VALUE, i, m - 1); + } + for (int i = 0; i < m; i++) { + dfs(matrix, pacific, Integer.MIN_VALUE, 0, i); + dfs(matrix, atlantic, Integer.MIN_VALUE, n - 1, i); + } + for (int i = 0; i < n; i++) + for (int j = 0; j < m; j++) + if (pacific[i][j] && atlantic[i][j]) + res.add(Arrays.asList(i, j)); + return res; + } + + int[][] dir = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; + + public void dfs(int[][] matrix, boolean[][] visited, int height, int x, int y) { + int n = matrix.length, m = matrix[0].length; + // since we start from ocean we check increasing height condition matrix[x][y] < height + // the problem asks decreasing height condition so that water can flow + if (x < 0 || x >= n || y < 0 || y >= m || visited[x][y] || matrix[x][y] < height) + return; + visited[x][y] = true; + for (int[] d : dir) { + dfs(matrix, visited, matrix[x][y], x + d[0], y + d[1]); + } + } +} diff --git a/src/main/java/graph/leetcode/ReconstructItenary.java b/src/main/java/graph/leetcode/ReconstructItenary.java new file mode 100644 index 0000000..71a0c1c --- /dev/null +++ b/src/main/java/graph/leetcode/ReconstructItenary.java @@ -0,0 +1,62 @@ +package graph.leetcode; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], reconstruct the itinerary in order. + * All of the tickets belong to a man who departs from JFK. + * Thus, the itinerary must begin with JFK. + *

+ * Input: [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] + * Output: ["JFK", "MUC", "LHR", "SFO", "SJC"] + *

+ * Input: [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]] + * Output: ["JFK","ATL","JFK","SFO","ATL","SFO"] + */ +public class ReconstructItenary { + + public List findItinerary(List> tickets) { + if (tickets == null || tickets.isEmpty()) return Collections.emptyList(); + + Map> map = new HashMap<>(); + + for (List ticket : tickets) { + map.putIfAbsent(ticket.get(0), new PriorityQueue<>()); + map.get(ticket.get(0)).offer(ticket.get(1)); + } + List res = new ArrayList<>(); + dfs(map, res, "JFK"); + return res; + } + + /** + * Once we construct the adj list + * JFK : [ATL,SFO] + * ATL : [JFK,SFO] + * SFO : [ATL] + * + * in this case we start at JFK we see the adj list, we take the first val 'ALT' and recurse + * ATL -> JFK + * JFK -> SFO // since we popped ALT we get SFO + * SFO -> ATL + * ATL -> SFO + * + * SFO is empty, so we add to stack + */ + public void dfs(Map> map, List res, String s) { + + PriorityQueue queue = map.get(s); + + while (!queue.isEmpty()) { + String temp = queue.poll(); + dfs(map, res, temp); + } + res.add(0, s); + } +} + diff --git a/src/main/java/graph/leetcode/RedundantConnection.java b/src/main/java/graph/leetcode/RedundantConnection.java new file mode 100644 index 0000000..1f8840c --- /dev/null +++ b/src/main/java/graph/leetcode/RedundantConnection.java @@ -0,0 +1,65 @@ +package graph.leetcode; + +/** + * Input: [[1,2], [1,3], [2,3]] + * Output: [2,3] + * Explanation: The given undirected graph will be like this: + * 1 + * / \ + * 2 - 3 + *

+ * Input: [[1,2], [2,3], [3,4], [1,4], [1,5]] + * Output: [1,4] + * Explanation: The given undirected graph will be like this: + * 5 - 1 - 2 + * | | + * 4 - 3 + */ +public class RedundantConnection { + public int[] findRedundantConnection(int[][] edges) { + + UnionFind uf = new UnionFind(edges.length + 1); + + for (int[] edge : edges) { + if (!uf.union(edge[0], edge[1])) { + return edge; + } + } + return new int[]{-1, -1}; + } + + static class UnionFind { + int[] parent; + int[] rank; + + public UnionFind(int size) { + parent = new int[size]; + for (int i = 0; i < size; i++) { + parent[i] = i; + } + rank = new int[size]; + } + + public int find(int x) { + if (parent[x] != x) parent[x] = find(parent[x]); + return parent[x]; + } + + public boolean union(int x, int y) { + int xRank = find(x), yRank = find(y); + if (xRank == yRank) { + return false; + } else if (rank[xRank] < rank[yRank]) { + parent[xRank] = yRank; + } else if (rank[xRank] > rank[yRank]) { + parent[yRank] = xRank; + } else { + parent[yRank] = xRank; + rank[xRank]++; + } + return true; + } + } +} + + diff --git a/src/main/java/graph/leetcode/RedundantConnectionII.java b/src/main/java/graph/leetcode/RedundantConnectionII.java new file mode 100644 index 0000000..d72d7cf --- /dev/null +++ b/src/main/java/graph/leetcode/RedundantConnectionII.java @@ -0,0 +1,126 @@ +package graph.leetcode; + +/** + * + There are 3 cases for Redundant Connection: + + case 1: two-parent problem such that an error node is with two parents + + 1 + / \ + v v + 2-->3 remove the second parentEdge of the node with two parents + + case 2: cyclic problem such that there is a cycle in the graph + + 1 + / ^ + v \ + 2-->3 remove the edge that forms the cycle + + case 3: two-parent and cyclic problem + + 1 + / ^ + v \ + 2-->3 <- 4 remove [2, 3] (to explain) + + Explanation for case 3: + We do union only if it is not the second parentEdge. Why? + We assume we always remove the second parentEdge. + If there is still cycle remained - that means we made the wrong choice, that is, + we should remove the first parentEdge instead. + + If [[1, 2], [2, 3], [4, 3], [3, 1]], [2, 3] comes before [4, 3], + we remove [4,3], then we union [1, 2], [2, 3], [3, 1], there is still cycle -- so we should remove [2, 3]. + + If [[1, 2], [4, 3], [2, 3], [3, 1]], [4, 3] comes before [2, 3], + we remove [2, 3], then we union [1, 2], [4, 3], [3, 1], there is not cycle -- so we should remove [2, 3]. + + + */ +public class RedundantConnectionII { + public int[] findRedundantDirectedConnection(int[][] edges) { + int numNodes = edges.length, edgeHasMultipleParent = -1, edgeMakesCycle = -1; + int[] parent = new int[numNodes + 1]; + + for (int i = 0; i < numNodes; i++) { + int u = edges[i][0]; + int v = edges[i][1]; + if (parent[v] != 0) { + + /* Assume we removed the second edge. */ + edgeHasMultipleParent = i; + break; + } else + parent[v] = u; + } + + UnionFind uf = new UnionFind(numNodes + 1); + for (int i = 0; i < numNodes; i++) { + if (i == edgeHasMultipleParent) // without this condition it might give a cyclic condition + continue; + int u = edges[i][0]; + int v = edges[i][1]; + if (!uf.union(u, v)) { + edgeMakesCycle = i; + break; + } + } + + /* Handle with the cyclic problem only. */ + if (edgeHasMultipleParent == -1) { + return edges[edgeMakesCycle]; + } + + /* Handle with the cyclic problem when we remove the wrong edge. */ + if (edgeMakesCycle != -1) { + int v = edges[edgeHasMultipleParent][1]; + int u = parent[v]; + return new int[]{u, v}; + } + + /* CHandle with the cyclic problem when we remove the right edge. */ + return edges[edgeHasMultipleParent]; + } + + static class UnionFind { + int[] parent; + int[] rank; + + public UnionFind(int n) { + this.parent = new int[n]; + this.rank = new int[n]; + + for (int i = 0; i < n; i++) { + this.parent[i] = i; + } + } + + public boolean union(int x, int y) { + + int parentX = find(x); + int parentY = find(y); + + if (parentX == parentY) return false; + + if (rank[parentX] > rank[parentY]) { + parent[parentY] = parentX; + } else if (rank[parentY] > rank[parentX]) { + parent[parentX] = parentY; + } else { + parent[parentY] = parentX; + rank[parentX]++; + } + + return true; + } + + public int find(int x) { + if (parent[x] == x) return x; + + parent[x] = find(parent[x]); + return parent[x]; + } + } +} diff --git a/src/main/java/graph/leetcode/RoadsToRome.java b/src/main/java/graph/leetcode/RoadsToRome.java new file mode 100644 index 0000000..2fb00f3 --- /dev/null +++ b/src/main/java/graph/leetcode/RoadsToRome.java @@ -0,0 +1,59 @@ +package graph.leetcode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; + +/** + * https://leetcode.com/discuss/interview-question/867806/q3-online-microsoft-interview-finding-rome + */ +public class RoadsToRome { + + public static int findRome(int[] A, int[] B) { + Map> adjList = new HashMap<>(); + int indegree[] = new int[A.length + 1]; + Queue queue = new LinkedList<>(); + + int outdegree[] = new int[A.length + 1]; + + for (int i = 0; i < A.length; i++) { + List list = adjList.getOrDefault(A[i], new ArrayList<>()); + list.add(B[i]); + adjList.put(A[i], list); + indegree[B[i]]++; + outdegree[A[i]]++; + } + + for (int i = 0; i < A.length + 1; i++) { + if (indegree[i] == 0) + queue.add(i); + } + int last = -1; + int secondLast = -1; + while (!queue.isEmpty()) { + int city = queue.remove(); + if (last == -1) + last = city; + else { + secondLast = last; + last = city; + } + for (int neighbour : adjList.getOrDefault(city, new ArrayList<>())) { + indegree[neighbour]--; + if (indegree[neighbour] == 0) + queue.add(neighbour); + } + + } + if (outdegree[secondLast] == 0 && outdegree[last] == 0) + return -1; + return last; + } + + public static void main(String[] args) { + findRome(new int[]{1,2,3},new int[]{0,0,0}); + } +} diff --git a/src/graph/leetcode/SentenceSimilarityII.java b/src/main/java/graph/leetcode/SentenceSimilarityII.java similarity index 95% rename from src/graph/leetcode/SentenceSimilarityII.java rename to src/main/java/graph/leetcode/SentenceSimilarityII.java index 3ae6e89..e822eac 100644 --- a/src/graph/leetcode/SentenceSimilarityII.java +++ b/src/main/java/graph/leetcode/SentenceSimilarityII.java @@ -25,12 +25,8 @@ public boolean areSentencesSimilarTwo(String[] words1, String[] words2, String[] for (String[] pair : pairs) { for (String word : pair) { - if (!map.containsKey(word)) { - map.put(word, id); - ++id; - } + map.putIfAbsent(word, id++); } - uf.union(map.get(pair[0]), map.get(pair[1])); } diff --git a/src/main/java/graph/leetcode/ShortestBridge.java b/src/main/java/graph/leetcode/ShortestBridge.java new file mode 100644 index 0000000..429453d --- /dev/null +++ b/src/main/java/graph/leetcode/ShortestBridge.java @@ -0,0 +1,76 @@ +package graph.leetcode; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * https://leetcode.com/problems/shortest-bridge/ + */ +public class ShortestBridge { + + // find one island location, add it to queue + // then from queue get the shortest distance to another island + public int shortestBridge(int[][] grid) { + + int m = grid.length; + int n=grid[0].length; + boolean[][] visited = new boolean[m][n]; + Deque queue = new ArrayDeque<>(); + boolean isFound = false; + for(int i=0;i=m || newY>=n || visited[newX][newY]) continue; + + if(grid[newX][newY] == 1) return steps; + visited[newX][newY]=true; + queue.offer(new int[]{newX,newY}); + } + } + steps++; + } + + return -1; + + } + + + public void dfs(int[][] grid, int i, int j, Deque queue, boolean[][] visited){ + + if(i<0 || j<0 || i>=grid.length || j>=grid[0].length || grid[i][j]==0 || visited[i][j]) return; + + queue.offer(new int[]{i,j}); + visited[i][j]=true; + dfs(grid, i,j+1,queue,visited); + dfs(grid, i+1,j,queue,visited); + dfs(grid, i-1,j,queue,visited); + dfs(grid, i,j-1,queue,visited); + } +} diff --git a/src/main/java/graph/leetcode/ShortestPathToGetFood.java b/src/main/java/graph/leetcode/ShortestPathToGetFood.java new file mode 100644 index 0000000..4bbc65c --- /dev/null +++ b/src/main/java/graph/leetcode/ShortestPathToGetFood.java @@ -0,0 +1,66 @@ +package graph.leetcode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * https://leetcode.com/problems/shortest-path-to-get-food/ + * + * You can save memory by changing the grid - when visiting a point, set it to X, so that "being an obstacle" it will not be visited again. + */ +public class ShortestPathToGetFood { + + int[][] dirs = new int[][]{{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + + public int getFood(char[][] grid) { + + int m = grid.length; + int n = grid[0].length; + + Queue q = new LinkedList<>(); + q.add(findStart(grid)); + + boolean[][] visited = new boolean[m][n]; + + int step = 0; + while (!q.isEmpty()) { + int len = q.size(); + for (int i = 0; i < len; i++) { + int[] pos = q.poll(); + + int x = pos[0]; + int y = pos[1]; + + if (grid[x][y] == '#') return step; + + for (int[] dir : dirs) { + int newX = x + dir[0]; + int newY = y + dir[1]; + + if (isValid(grid, newX, newY) && !visited[newX][newY]) { + visited[newX][newY] = true; + q.offer(new int[]{newX, newY}); + } + } + } + step++; + } + + return -1; + } + + private int[] findStart(char[][] grid) { + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == '*') { + return new int[]{i, j}; + } + } + } + throw new RuntimeException(); + } + + private boolean isValid(char[][] grid, int i, int j) { + return i >= 0 && i < grid.length && j >= 0 && j < grid[0].length && grid[i][j] != 'X'; + } +} diff --git a/src/main/java/graph/leetcode/TimeToInformEmployee.java b/src/main/java/graph/leetcode/TimeToInformEmployee.java new file mode 100644 index 0000000..5b769e4 --- /dev/null +++ b/src/main/java/graph/leetcode/TimeToInformEmployee.java @@ -0,0 +1,45 @@ +package graph.leetcode; + +import java.util.ArrayList; +import java.util.Deque; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * https://leetcode.com/problems/time-needed-to-inform-all-employees/submissions/ + */ +public class TimeToInformEmployee { + public int numOfMinutes(int n, int headID, int[] manager, int[] informTime) { + Map> map = new HashMap<>(); // Build the hierarchical tree + Deque queue = new LinkedList<>(); + int result = Integer.MIN_VALUE; + + for (int i = 0; i < manager.length; i++) { + if (!map.containsKey(manager[i])) + map.put(manager[i], new ArrayList<>()); + + map.get(manager[i]).add(i); // Map of manager and its subordinates given by the index i + } + + queue.offer(new int[]{headID, 0}); // head of organizer and corresponding informing time. + + while (!queue.isEmpty()) { + int[] temp = queue.poll(); + int managerAtGivenLevel = temp[0]; + int cumulativeTime = temp[1]; + + result = Math.max(result, cumulativeTime); + + if (map.containsKey(managerAtGivenLevel)) { // if the manager has subordinates + List subordinates = map.get(managerAtGivenLevel); // get the list of subordinates + + for (int i : subordinates) { + queue.offer(new int[]{i, informTime[managerAtGivenLevel] + cumulativeTime}); // add the subordinates as manager and the time taken to inform each of these subordinates + } + } + } + return result; + } +} diff --git a/src/graph/primsAlgorithm/BinaryMinHeap.java b/src/main/java/graph/primsAlgorithm/BinaryMinHeap.java similarity index 100% rename from src/graph/primsAlgorithm/BinaryMinHeap.java rename to src/main/java/graph/primsAlgorithm/BinaryMinHeap.java diff --git a/src/graph/primsAlgorithm/Graph.java b/src/main/java/graph/primsAlgorithm/Graph.java similarity index 100% rename from src/graph/primsAlgorithm/Graph.java rename to src/main/java/graph/primsAlgorithm/Graph.java diff --git a/src/graph/primsAlgorithm/PrimMST.java b/src/main/java/graph/primsAlgorithm/PrimMST.java similarity index 100% rename from src/graph/primsAlgorithm/PrimMST.java rename to src/main/java/graph/primsAlgorithm/PrimMST.java diff --git a/src/graph/primsAlgorithm/PrimsMSTArray.java b/src/main/java/graph/primsAlgorithm/PrimsMSTArray.java similarity index 100% rename from src/graph/primsAlgorithm/PrimsMSTArray.java rename to src/main/java/graph/primsAlgorithm/PrimsMSTArray.java diff --git a/src/graph/shortestPath/Graph.java b/src/main/java/graph/shortestPath/Graph.java similarity index 100% rename from src/graph/shortestPath/Graph.java rename to src/main/java/graph/shortestPath/Graph.java diff --git a/src/graph/shortestPath/ShortestPath.java b/src/main/java/graph/shortestPath/ShortestPath.java similarity index 100% rename from src/graph/shortestPath/ShortestPath.java rename to src/main/java/graph/shortestPath/ShortestPath.java diff --git a/src/graph/topologicalsort/Graph.java b/src/main/java/graph/topologicalsort/Graph.java similarity index 100% rename from src/graph/topologicalsort/Graph.java rename to src/main/java/graph/topologicalsort/Graph.java diff --git a/src/graph/topologicalsort/TopologicalSort.java b/src/main/java/graph/topologicalsort/TopologicalSort.java similarity index 100% rename from src/graph/topologicalsort/TopologicalSort.java rename to src/main/java/graph/topologicalsort/TopologicalSort.java diff --git a/src/graph/topologicalsort/TopologicalSortList.java b/src/main/java/graph/topologicalsort/TopologicalSortList.java similarity index 100% rename from src/graph/topologicalsort/TopologicalSortList.java rename to src/main/java/graph/topologicalsort/TopologicalSortList.java diff --git a/src/internals/ConcurrentHashMap.java b/src/main/java/internals/ConcurrentHashMap.java similarity index 100% rename from src/internals/ConcurrentHashMap.java rename to src/main/java/internals/ConcurrentHashMap.java diff --git a/src/internals/HashMap.java b/src/main/java/internals/HashMap.java similarity index 100% rename from src/internals/HashMap.java rename to src/main/java/internals/HashMap.java diff --git a/src/internals/HashMapJava8.java b/src/main/java/internals/HashMapJava8.java similarity index 100% rename from src/internals/HashMapJava8.java rename to src/main/java/internals/HashMapJava8.java diff --git a/src/internals/LinkedHashMap.java b/src/main/java/internals/LinkedHashMap.java similarity index 100% rename from src/internals/LinkedHashMap.java rename to src/main/java/internals/LinkedHashMap.java diff --git a/src/internals/MyBlockingQueue.java b/src/main/java/internals/MyBlockingQueue.java similarity index 100% rename from src/internals/MyBlockingQueue.java rename to src/main/java/internals/MyBlockingQueue.java diff --git a/src/main/java/internals/QuadTree.java b/src/main/java/internals/QuadTree.java new file mode 100644 index 0000000..ce0d590 --- /dev/null +++ b/src/main/java/internals/QuadTree.java @@ -0,0 +1,95 @@ +package internals; + +import java.util.HashSet; +import java.util.Set; + +public class QuadTree

{ + + Point topLeft; + Point bottomRight; + Set> nodes; + // children (this can also be used like Trie, where it is an Array of QuadTree) + QuadTree

topLeftTree; + QuadTree

topRightTree; + QuadTree

bottomLeftTree; + QuadTree

bottomRightTree; + int maxLen; + private Set> node; + + public QuadTree(Point topLeft, Point bottomRight, int maxLen) { + this.topLeft = topLeft; + this.bottomRight = bottomRight; + this.maxLen = maxLen; + nodes = new HashSet<>(); + } + + public Set> search(Point p) { + QuadTree

curr = this; + + while (!curr.isLeaf()) { + + // recurse by checking if it is within the boundary + if (p.x < (curr.topLeft.x + curr.bottomRight.x) / 2) { + if (p.y < (curr.topLeft.y + curr.bottomRight.y) / 2) { + curr = curr.topLeftTree; + } else { + curr = curr.bottomLeftTree; + } + } else { + if (p.y < (curr.topLeft.y + curr.bottomRight.y) / 2) { + curr = curr.topRightTree; + } else { + curr = curr.bottomRightTree; + } + + } + } + return curr.node; + } + + private boolean isLeaf() { + return true; + } + + + static class QuadNode { + T data; + Point point; + + public QuadNode(Point p, T data) { + this.data = data; + this.point = p; + } + + public QuadNode(int x, int y, T data) { + this.data = data; + this.point = new Point(x, y); + } + + @Override + public String toString() { + return "data " + data + " point " + point; + } + } + + static class Point { + int x; + int y; + + public Point(int x, int y) { + this.x = x; + this.y = y; + } + + // more like a deep clone + public Point(Point p) { + this.x = p.x; + this.y = p.y; + } + + @Override + public String toString() { + return "x: " + x + " y: " + y; + } + } +} diff --git a/src/internals/SJUArrayList.java b/src/main/java/internals/SJUArrayList.java similarity index 100% rename from src/internals/SJUArrayList.java rename to src/main/java/internals/SJUArrayList.java diff --git a/src/main/java/internals/SkipList.java b/src/main/java/internals/SkipList.java new file mode 100644 index 0000000..0baf132 --- /dev/null +++ b/src/main/java/internals/SkipList.java @@ -0,0 +1,189 @@ +package internals; + +import java.util.Random; + +interface SkippableList> { + + int LEVELS = 5; + + boolean delete(T target); + + void print(); + + void insert(T data); + + SkipNode search(T data); +} + +class SkipNode> { + + N data; + @SuppressWarnings("unchecked") + SkipNode[] next = (SkipNode[]) new SkipNode[SkippableList.LEVELS]; + + SkipNode(N data) { + this.data = data; + } + + void refreshAfterDelete(int level) { + SkipNode current = this; + while (current != null && current.getNext(level) != null) { + if (current.getNext(level).data == null) { + SkipNode successor = current.getNext(level).getNext(level); + current.setNext(successor, level); + return; + } + + current = current.getNext(level); + } + } + + void setNext(SkipNode next, int level) { + this.next[level] = next; + } + + SkipNode getNext(int level) { + return this.next[level]; + } + + SkipNode search(N data, int level, boolean print) { + if (print) { + System.out.print("Searching for: " + data + " at "); + print(level); + } + + SkipNode result = null; + SkipNode current = this.getNext(level); + while (current != null && current.data.compareTo(data) < 1) { + if (current.data.equals(data)) { + result = current; + break; + } + + current = current.getNext(level); + } + + return result; + } + + void insert(SkipNode skipNode, int level) { + SkipNode current = this.getNext(level); + if (current == null) { + this.setNext(skipNode, level); + return; + } + + if (skipNode.data.compareTo(current.data) < 1) { + this.setNext(skipNode, level); + skipNode.setNext(current, level); + return; + } + + while (current.getNext(level) != null && current.data.compareTo(skipNode.data) < 1 && + current.getNext(level).data.compareTo(skipNode.data) < 1) { + + current = current.getNext(level); + } + + SkipNode successor = current.getNext(level); + current.setNext(skipNode, level); + skipNode.setNext(successor, level); + } + + void print(int level) { + System.out.print("level " + level + ": [ "); + int length = 0; + SkipNode current = this.getNext(level); + while (current != null) { + length++; + System.out.print(current.data + " "); + current = current.getNext(level); + } + + System.out.println("], length: " + length); + } + +} + +public class SkipList> implements SkippableList { + + private final SkipNode head = new SkipNode<>(null); + private final Random rand = new Random(); + + @Override + public void insert(T data) { + SkipNode skipNode = new SkipNode<>(data); + for (int i = 0; i < LEVELS; i++) { + if (rand.nextInt((int) Math.pow(2, i)) == 0) { + //insert with prob = 1/(2^i) + insert(skipNode, i); + } + } + } + + @Override + public boolean delete(T target) { + System.out.println("Deleting " + target); + SkipNode victim = search(target, true); + if (victim == null) return false; + victim.data = null; + + for (int i = 0; i < LEVELS; i++) { + head.refreshAfterDelete(i); + } + + System.out.println("deleted..."); + return true; + } + + @Override + public SkipNode search(T data) { + return search(data, true); + } + + @Override + public void print() { + for (int i = LEVELS - 1; i >= 0; i--) { + head.print(i); + } + System.out.println(); + } + + private void insert(SkipNode SkipNode, int level) { + head.insert(SkipNode, level); + } + + private SkipNode search(T data, boolean print) { + SkipNode result = null; + for (int i = LEVELS - 1; i >= 0; i--) { + if ((result = head.search(data, i, print)) != null) { + if (print) { + System.out.println("Found " + data.toString() + " at level " + i + ", so stopped"); + System.out.println(); + } + break; + } + } + + return result; + } + + public static void main(String[] args) { + SkipList sl = new SkipList<>(); + int[] data = {4, 2, 7, 0, 9, 1, 3, 7, 3, 4, 5, 6, 0, 2, 8}; + for (int i : data) { + sl.insert(i); + } + + sl.print(); + sl.search(4); + + sl.delete(4); + + System.out.println("Inserting 10"); + sl.insert(10); + sl.print(); + sl.search(10); + } + +} diff --git a/src/main/java/internals/ThreadPool.java b/src/main/java/internals/ThreadPool.java new file mode 100644 index 0000000..751e9cd --- /dev/null +++ b/src/main/java/internals/ThreadPool.java @@ -0,0 +1,106 @@ +package internals; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +public class ThreadPool { + + private BlockingQueue taskQueue = null; + private final List runnables = new ArrayList<>(); + private boolean isStopped = false; + + public ThreadPool(int noOfThreads, int maxNoOfTasks) { + taskQueue = new ArrayBlockingQueue(maxNoOfTasks); + + for (int i = 0; i < noOfThreads; i++) { + PoolThreadRunnable poolThreadRunnable = + new PoolThreadRunnable(taskQueue); + + runnables.add(new PoolThreadRunnable(taskQueue)); + } + for (PoolThreadRunnable runnable : runnables) { + new Thread(runnable).start(); + } + } + + public synchronized void execute(Runnable task) throws Exception { + if (this.isStopped) throw + new IllegalStateException("ThreadPool is stopped"); + + this.taskQueue.offer(task); + } + + public synchronized void stop() { + this.isStopped = true; + for (PoolThreadRunnable runnable : runnables) { + runnable.doStop(); + } + } + + public synchronized void waitUntilAllTasksFinished() { + while (!this.taskQueue.isEmpty()) { + try { + Thread.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + static class PoolThreadRunnable implements Runnable { + + private Thread thread = null; + private BlockingQueue taskQueue = null; + private boolean isStopped = false; + + public PoolThreadRunnable(BlockingQueue queue) { + taskQueue = queue; + } + + public void run() { + this.thread = Thread.currentThread(); + while (!isStopped()) { + try { + Runnable runnable = (Runnable) taskQueue.take(); + runnable.run(); + } catch (Exception e) { + //log or otherwise report exception, + //but keep pool thread alive. + } + } + } + + public synchronized void doStop() { + isStopped = true; + //break pool thread out of dequeue() call. + this.thread.interrupt(); + } + + public synchronized boolean isStopped() { + return isStopped; + } + } + + + public static void main(String[] args) throws Exception { + + ThreadPool threadPool = new ThreadPool(3, 10); + + for (int i = 0; i < 10; i++) { + + int taskNo = i; + threadPool.execute(() -> { + String message = + Thread.currentThread().getName() + + ": Task " + taskNo; + System.out.println(message); + }); + } + + threadPool.waitUntilAllTasksFinished(); + threadPool.stop(); + + } +} \ No newline at end of file diff --git a/src/main/java/internals/TwitterSnowflakeUUID.java b/src/main/java/internals/TwitterSnowflakeUUID.java new file mode 100644 index 0000000..80982d7 --- /dev/null +++ b/src/main/java/internals/TwitterSnowflakeUUID.java @@ -0,0 +1,119 @@ +package internals; + +import java.net.NetworkInterface; +import java.security.SecureRandom; +import java.time.Instant; +import java.util.Enumeration; + +public class TwitterSnowflakeUUID { + + /** + * Distributed Sequence Generator. + * Inspired by Twitter snowflake: https://github.com/twitter/snowflake/tree/snowflake-2010 + *

+ * This class should be used as a Singleton. + * Make sure that you create and reuse a Single instance of SequenceGenerator per node in your distributed system cluster. + */ + private static final int UNUSED_BITS = 1; // Sign bit, Unused (always set to 0) + private static final int EPOCH_BITS = 41; + private static final int NODE_ID_BITS = 10; + private static final int SEQUENCE_BITS = 12; + + private static final int maxNodeId = (int) (Math.pow(2, NODE_ID_BITS) - 1); + private static final int maxSequence = (int) (Math.pow(2, SEQUENCE_BITS) - 1); + + // Custom Epoch (January 1, 2015 Midnight UTC = 2015-01-01T00:00:00Z) + private static final long CUSTOM_EPOCH = 1420070400000L; + + private final int nodeId; + + private volatile long lastTimestamp = -1L; + private volatile long sequence = 0L; + + // Create SequenceGenerator with a nodeId + public TwitterSnowflakeUUID(int nodeId) { + if (nodeId < 0 || nodeId > maxNodeId) { + throw new IllegalArgumentException(String.format("NodeId must be between %d and %d", 0, maxNodeId)); + } + this.nodeId = nodeId; + } + + // Let SequenceGenerator generate a nodeId + public TwitterSnowflakeUUID() { + this.nodeId = createNodeId(); + } + + public synchronized long nextId() { + long currentTimestamp = timestamp(); + + if (currentTimestamp < lastTimestamp) { + throw new IllegalStateException("Invalid System Clock!"); + } + + if (currentTimestamp == lastTimestamp) { + sequence = (sequence + 1) & maxSequence; + if (sequence == 0) { + // Sequence Exhausted, wait till next millisecond. + currentTimestamp = waitNextMillis(currentTimestamp); + } + } else { + // reset sequence to start with zero for the next millisecond + sequence = 0; + } + + lastTimestamp = currentTimestamp; + + //Now, the first 41 bits of the ID (after the signed bit) will be filled with the epoch timestamp. Let’s do that using a left-shift - + long id = currentTimestamp << (NODE_ID_BITS + SEQUENCE_BITS); + + //Next, we take the configured node ID and fill the next 10 bits with the node ID. Let’s say that the nodeId is 786 - + //id |= nodeId << 12 + id |= (nodeId << SEQUENCE_BITS); + + //Finally, we fill the last 12 bits with the local counter. + // Considering the counter’s next value is 3450, i.e. sequence = 3450, the final ID is obtained like so - + id |= sequence; + return id; + } + + + // Get current timestamp in milliseconds, adjust for the custom epoch. + private static long timestamp() { + /** + * Let’s now understand how it works. Let’s say it’s June 9, 2018 10:00:00 AM GMT. The epoch timestamp for this particular time is 1528538400000. + * First, we adjust our timestamp with respect to the custom epoch- + * currentTimestamp = 1528538400000 - 1420070400000 + */ + return Instant.now().toEpochMilli() - CUSTOM_EPOCH; + } + + // Block and wait till next millisecond + private long waitNextMillis(long currentTimestamp) { + while (currentTimestamp == lastTimestamp) { + currentTimestamp = timestamp(); + } + return currentTimestamp; + } + + private int createNodeId() { + int nodeId; + try { + StringBuilder sb = new StringBuilder(); + Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); + while (networkInterfaces.hasMoreElements()) { + NetworkInterface networkInterface = networkInterfaces.nextElement(); + byte[] mac = networkInterface.getHardwareAddress(); + if (mac != null) { + for (int i = 0; i < mac.length; i++) { + sb.append(String.format("%02X", mac[i])); + } + } + } + nodeId = sb.toString().hashCode(); + } catch (Exception ex) { + nodeId = (new SecureRandom().nextInt()); + } + nodeId = nodeId & maxNodeId; + return nodeId; + } +} diff --git a/src/java8/Books.txt b/src/main/java/java8/Books.txt similarity index 100% rename from src/java8/Books.txt rename to src/main/java/java8/Books.txt diff --git a/src/java8/CustomCollectors.java b/src/main/java/java8/CustomCollectors.java similarity index 100% rename from src/java8/CustomCollectors.java rename to src/main/java/java8/CustomCollectors.java diff --git a/src/java8/CustomSpliterator.java b/src/main/java/java8/CustomSpliterator.java similarity index 100% rename from src/java8/CustomSpliterator.java rename to src/main/java/java8/CustomSpliterator.java diff --git a/src/java8/DesignPatternJava8.java b/src/main/java/java8/DesignPatternJava8.java similarity index 100% rename from src/java8/DesignPatternJava8.java rename to src/main/java/java8/DesignPatternJava8.java diff --git a/src/java8/EmployeeData.txt b/src/main/java/java8/EmployeeData.txt similarity index 100% rename from src/java8/EmployeeData.txt rename to src/main/java/java8/EmployeeData.txt diff --git a/src/java8/FunctionalInterfaceExamples.java b/src/main/java/java8/FunctionalInterfaceExamples.java similarity index 100% rename from src/java8/FunctionalInterfaceExamples.java rename to src/main/java/java8/FunctionalInterfaceExamples.java diff --git a/src/linkedLists/Agoda.java b/src/main/java/linkedLists/Agoda.java similarity index 100% rename from src/linkedLists/Agoda.java rename to src/main/java/linkedLists/Agoda.java diff --git a/src/linkedLists/AllProblems.java b/src/main/java/linkedLists/AllProblems.java similarity index 100% rename from src/linkedLists/AllProblems.java rename to src/main/java/linkedLists/AllProblems.java diff --git a/src/linkedLists/ArrayToBST.java b/src/main/java/linkedLists/ArrayToBST.java similarity index 100% rename from src/linkedLists/ArrayToBST.java rename to src/main/java/linkedLists/ArrayToBST.java diff --git a/src/linkedLists/CloneRandomPointerLinkedList.java b/src/main/java/linkedLists/CloneRandomPointerLinkedList.java similarity index 100% rename from src/linkedLists/CloneRandomPointerLinkedList.java rename to src/main/java/linkedLists/CloneRandomPointerLinkedList.java diff --git a/src/linkedLists/DLLToBBST.java b/src/main/java/linkedLists/DLLToBBST.java similarity index 100% rename from src/linkedLists/DLLToBBST.java rename to src/main/java/linkedLists/DLLToBBST.java diff --git a/src/linkedLists/DLLToBBSTTimeEfficiency.java b/src/main/java/linkedLists/DLLToBBSTTimeEfficiency.java similarity index 100% rename from src/linkedLists/DLLToBBSTTimeEfficiency.java rename to src/main/java/linkedLists/DLLToBBSTTimeEfficiency.java diff --git a/src/linkedLists/DetectAndRemoveLoop.java b/src/main/java/linkedLists/DetectAndRemoveLoop.java similarity index 100% rename from src/linkedLists/DetectAndRemoveLoop.java rename to src/main/java/linkedLists/DetectAndRemoveLoop.java diff --git a/src/linkedLists/FlattenLinkedList.java b/src/main/java/linkedLists/FlattenLinkedList.java similarity index 100% rename from src/linkedLists/FlattenLinkedList.java rename to src/main/java/linkedLists/FlattenLinkedList.java diff --git a/src/practiceproblems/FlattenMultiLevelLinkedList.java b/src/main/java/linkedLists/FlattenMultiLevelLinkedList.java similarity index 61% rename from src/practiceproblems/FlattenMultiLevelLinkedList.java rename to src/main/java/linkedLists/FlattenMultiLevelLinkedList.java index 3fce5e6..3906f0f 100644 --- a/src/practiceproblems/FlattenMultiLevelLinkedList.java +++ b/src/main/java/linkedLists/FlattenMultiLevelLinkedList.java @@ -1,8 +1,8 @@ -package practiceproblems; +package linkedLists; /** * https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list/discuss/150321/Easy-Understanding-Java-beat-95.7-with-Explanation -* */ + */ class FlattenMultiLevelLinkedList { public Node flatten(Node head) { @@ -35,6 +35,37 @@ public Node flatten(Node head) { return head; } + /** + * tricky recursion + * + */ + public Node flattenRecur(Node head) { + if (head == null) return head; + + Node root = head; + while (root != null && root.child == null) { + root = root.next; + } + if (root == null) return head; + + Node transformedList = flattenRecur(root.child); + + Node next = root.next; + + root.next = transformedList; + transformedList.prev = root; + + while (transformedList.next != null) { + transformedList = transformedList.next; + } + transformedList.next = next; + + if (next != null) next.prev = transformedList; + root.child = null; + + return head; + } + static class Node { long data; Node next; diff --git a/src/linkedLists/FlattenNestedIterator.java b/src/main/java/linkedLists/FlattenNestedIterator.java similarity index 100% rename from src/linkedLists/FlattenNestedIterator.java rename to src/main/java/linkedLists/FlattenNestedIterator.java diff --git a/src/main/java/linkedLists/InsertionSortList.java b/src/main/java/linkedLists/InsertionSortList.java new file mode 100644 index 0000000..91f237f --- /dev/null +++ b/src/main/java/linkedLists/InsertionSortList.java @@ -0,0 +1,52 @@ +package linkedLists; + +/** + * tricky linked list sort + * + * Sort a linked list using insertion sort. + * Algorithm of Insertion Sort: + * Insertion sort iterates, + * consuming one input element each repetition, and growing a sorted output list. + * At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. + * It repeats until no input elements remain. + */ +public class InsertionSortList { + public static ListNode insertionSortList(ListNode head) { + ListNode dummy = new ListNode(0); + ListNode curr = head; + + while (curr != null) { + // At each iteration, we insert an element into the resulting list. + ListNode prev = dummy; + + // find the position to insert the current node + while (prev.next != null && prev.next.val < curr.val) { + prev = prev.next; + } + + ListNode next = curr.next; + + // this means given me what ever you have in next so that i(curr) can keep as next items + curr.next = prev.next; + // i(curr) got your next items, let me(curr) attach as your next item. + // this is the insertion part of the algo + prev.next = curr; + + // moving on to the next iteration + curr = next; + } + + return dummy.next; + } + + public static void main(String[] args) { + ListNode node = new ListNode(7); + node.next = new ListNode(3); + node.next.next = new ListNode(2); + node.next.next.next = new ListNode(8); + node.next.next.next.next = new ListNode(9); + node.next.next.next.next.next = new ListNode(1); + + insertionSortList(node); + } +} \ No newline at end of file diff --git a/src/practiceproblems/LinkedListRemoveDuplicates.java b/src/main/java/linkedLists/LinkedListRemoveDuplicates.java similarity index 89% rename from src/practiceproblems/LinkedListRemoveDuplicates.java rename to src/main/java/linkedLists/LinkedListRemoveDuplicates.java index 18c5e52..af31a85 100644 --- a/src/practiceproblems/LinkedListRemoveDuplicates.java +++ b/src/main/java/linkedLists/LinkedListRemoveDuplicates.java @@ -1,4 +1,4 @@ -package practiceproblems; +package linkedLists; class LinkedListRemoveDuplicate{ /** @@ -10,7 +10,7 @@ class LinkedListRemoveDuplicate{ * * @param head */ - public static void removeDuplicatesWithoutBuffer(ListNode head) { + public static void removeDuplicatesWithoutBuffer(ListNode head) { /* If head is null, stop processing */ if (head == null) { return; diff --git a/src/linkedLists/LinkedListToBST.java b/src/main/java/linkedLists/LinkedListToBST.java similarity index 100% rename from src/linkedLists/LinkedListToBST.java rename to src/main/java/linkedLists/LinkedListToBST.java diff --git a/src/linkedLists/Main.java b/src/main/java/linkedLists/Main.java similarity index 100% rename from src/linkedLists/Main.java rename to src/main/java/linkedLists/Main.java diff --git a/src/main/java/linkedLists/MergeKSortedLists.java b/src/main/java/linkedLists/MergeKSortedLists.java new file mode 100644 index 0000000..6533d9c --- /dev/null +++ b/src/main/java/linkedLists/MergeKSortedLists.java @@ -0,0 +1,65 @@ +package linkedLists; + +import java.util.PriorityQueue; + +public class MergeKSortedLists { + + public ListNode mergeKLists(ListNode[] lists) { + if (lists.length == 0) return null; + PriorityQueue queue = new PriorityQueue<>((a, b) -> Integer.compare(a.val, b.val)); + + for (ListNode list : lists) { + if (list != null) queue.offer(list); + } + + ListNode dummy = new ListNode(-1); + ListNode head = dummy; + + while (!queue.isEmpty()) { + ListNode temp = queue.poll(); + head.next = temp; + if (temp.next != null) queue.offer(temp.next); + head = head.next; + } + + return dummy.next; + } + + public ListNode mergeKListsEfficient(ListNode[] lists) { + return merge(lists, 0, lists.length - 1); + } + + public ListNode merge(ListNode[] lists, int start, int end) { + if (start == end) return lists[start]; + if (start > end) return null; + int mid = (start + end) / 2; + ListNode left = merge(lists, start, mid); + ListNode right = merge(lists, mid + 1, end); + return mergeTwo(left, right); + } + + public ListNode mergeTwo(ListNode node1, ListNode node2) { + if (node1 == null) return node2; + if (node2 == null) return node1; + + ListNode head = new ListNode(0), tail = head; + while (node1 != null && node2 != null) { + if (node1.val < node2.val) { + tail.next = node1; + node1 = node1.next; + } else { + tail.next = node2; + node2 = node2.next; + } + tail = tail.next; + } + + if (node1 != null) { + tail.next = node1; + } + if (node2 != null) { + tail.next = node2; + } + return head.next; + } +} diff --git a/src/practiceproblems/MergeSortLinkedList.java b/src/main/java/linkedLists/MergeSortLinkedList.java similarity index 88% rename from src/practiceproblems/MergeSortLinkedList.java rename to src/main/java/linkedLists/MergeSortLinkedList.java index c380f29..cac69ea 100644 --- a/src/practiceproblems/MergeSortLinkedList.java +++ b/src/main/java/linkedLists/MergeSortLinkedList.java @@ -1,6 +1,8 @@ -package practiceproblems; +package linkedLists; /** + * tricky linked list + * revise * https://www.geeksforgeeks.org/merge-sort-for-linked-list/ */ public class MergeSortLinkedList { @@ -61,20 +63,5 @@ public static void main(String[] args) { listNode = listNode.next; } } - } -class ListNode { - - ListNode next; - int val; - - public ListNode(int val) { - this.val = val; - } - - @Override - public String toString() { - return "ListNode{val=" + val + '}'; - } -} \ No newline at end of file diff --git a/src/practiceproblems/MergeTwoLinkedList.java b/src/main/java/linkedLists/MergeTwoLinkedList.java similarity index 97% rename from src/practiceproblems/MergeTwoLinkedList.java rename to src/main/java/linkedLists/MergeTwoLinkedList.java index 518b600..f5d1342 100644 --- a/src/practiceproblems/MergeTwoLinkedList.java +++ b/src/main/java/linkedLists/MergeTwoLinkedList.java @@ -1,4 +1,4 @@ -package practiceproblems; +package linkedLists; /** * https://www.geeksforgeeks.org/merge-two-sorted-linked-lists/ diff --git a/src/linkedLists/MergeTwoLinkedLists.java b/src/main/java/linkedLists/MergeTwoLinkedLists.java similarity index 100% rename from src/linkedLists/MergeTwoLinkedLists.java rename to src/main/java/linkedLists/MergeTwoLinkedLists.java diff --git a/src/linkedLists/MiddleElement.java b/src/main/java/linkedLists/MiddleElement.java similarity index 100% rename from src/linkedLists/MiddleElement.java rename to src/main/java/linkedLists/MiddleElement.java diff --git a/src/practiceproblems/NextLargestList.java b/src/main/java/linkedLists/NextLargestList.java similarity index 98% rename from src/practiceproblems/NextLargestList.java rename to src/main/java/linkedLists/NextLargestList.java index 9e639ef..8b2c300 100644 --- a/src/practiceproblems/NextLargestList.java +++ b/src/main/java/linkedLists/NextLargestList.java @@ -1,4 +1,4 @@ -package practiceproblems; +package linkedLists; import java.util.Stack; diff --git a/src/linkedLists/Node.java b/src/main/java/linkedLists/Node.java similarity index 100% rename from src/linkedLists/Node.java rename to src/main/java/linkedLists/Node.java diff --git a/src/linkedLists/PalindromeSinglyLinkedList.java b/src/main/java/linkedLists/PalindromeSinglyLinkedList.java similarity index 100% rename from src/linkedLists/PalindromeSinglyLinkedList.java rename to src/main/java/linkedLists/PalindromeSinglyLinkedList.java diff --git a/src/linkedLists/RandomListNode.java b/src/main/java/linkedLists/RandomListNode.java similarity index 100% rename from src/linkedLists/RandomListNode.java rename to src/main/java/linkedLists/RandomListNode.java diff --git a/src/main/java/linkedLists/RemoveDuplicates.java b/src/main/java/linkedLists/RemoveDuplicates.java new file mode 100644 index 0000000..1e3d892 --- /dev/null +++ b/src/main/java/linkedLists/RemoveDuplicates.java @@ -0,0 +1,80 @@ +package linkedLists; + +import java.util.HashMap; +import java.util.Map; + +/** + * https://leetcode.com/problems/remove-duplicates-from-an-unsorted-linked-list + */ +public class RemoveDuplicates { + + public ListNode deleteDuplicatesFromSorted(ListNode head) { + ListNode list = head; + + while(list != null) { + if (list.next == null) { + break; + } + if (list.val == list.next.val) { + list.next = list.next.next; + } else { + list = list.next; + } + } + + return head; + } + + public ListNode deleteDuplicatesFromSortedII(ListNode head) { + // sentinel + ListNode sentinel = new ListNode(0); + sentinel.next = head; + // predecessor = the last node before the sublist of duplicates + // this will be always one node behind + ListNode pred = sentinel; + + while (head != null) { + // if it's a beginning of duplicates sublist + // skip all duplicates + if (head.next != null && head.val == head.next.val) { + // move till the end of duplicates sublist + while (head.next != null && head.val == head.next.val) { + head = head.next; + } + // skip all duplicates + pred.next = head.next; + // otherwise, move predecessor + } else { + pred = pred.next; + } + + // move forward + head = head.next; + } + return sentinel.next; + } + + public ListNode deleteDuplicatesUnsorted(ListNode head) { + // Key: val Value: its frequency + Map map = new HashMap<>(); + ListNode curr = head; + while (curr != null) { + map.put(curr.val, map.getOrDefault(curr.val, 0) + 1); + curr = curr.next; + } + + ListNode dummy = new ListNode(0); + curr = dummy; + while (head != null) { + if (map.get(head.val) == 1) { + curr.next = head; + curr = curr.next; + } + + head = head.next; + } + + curr.next = null; + return dummy.next; + } +} diff --git a/src/main/java/linkedLists/ReverseKBlockNode.java b/src/main/java/linkedLists/ReverseKBlockNode.java new file mode 100644 index 0000000..812ce56 --- /dev/null +++ b/src/main/java/linkedLists/ReverseKBlockNode.java @@ -0,0 +1,117 @@ +package linkedLists; + +/** + * https://leetcode.com/problems/reverse-nodes-in-k-group/ + * + * tricky + */ +public class ReverseKBlockNode { + + static ListNode head; + static int k = 3; + + public static void main(String[] args) { + head = new ListNode(1); + head.next = new ListNode(2); + head.next.next = new ListNode(3); + head.next.next.next = new ListNode(4); + head.next.next.next.next = new ListNode(5); + head.next.next.next.next.next = new ListNode(6); + head.next.next.next.next.next.next = new ListNode(7); + head.next.next.next.next.next.next.next = new ListNode(8); + head.next.next.next.next.next.next.next.next = new ListNode(9); + head.next.next.next.next.next.next.next.next.next = new ListNode(10); + + reverseKNodes(head, 2); + print(head); + } + + + private static void print(ListNode current) { + ListNode node = current; + while (node != null) { + System.out.println(node.val); + node = node.next; + } + } + + public static ListNode reverseKNodes(ListNode head, int k) { + if (head == null) return null; + ListNode root = head; + int count = 0; + //1. test weather we have more then k node left, if less then k node left we just return head + while (count < k) { // && root!=null add this condition to reverse remaining elements + //base case: head listnode contains less than k nodes, + // in this case, return the original listnode(aka head) + if (root == null) return head; + root = root.next; + count++; + } + // 2.reverse k node at current level + ListNode prev = reverseKNodes(root, k); //prev node point to the answer of sub-problem + while (count > 0) { + ListNode next = head.next; + head.next = prev; + prev = head; + head = next; + count--; + + } + + return prev; + } + + /** + * Reverse a link list between begin and end exclusively + * an example: + * a linked list: + * 0->1->2->3->4->5->6 + * | | + * begin end + * after call begin = reverse(begin, end) + * + * 0->3->2->1->4->5->6 + * | | + * begin end + * @return the reversed list's 'begin' node, which is the precedence of node end + */ + + public ListNode reverseKGroup(ListNode head, int k) { + ListNode begin; + if (head == null || head.next == null || k == 1) + return head; + + ListNode dummyHead = new ListNode(-1); + dummyHead.next = head; + begin = dummyHead; + int i = 0; + + while (head != null) { + i++; + ListNode next = head.next; + if (i % k == 0) { + begin = reverse(begin, next); + } + head = next; + + } + return dummyHead.next; + + } + + public ListNode reverse(ListNode begin, ListNode end) { + ListNode curr = begin.next; + ListNode prev = begin; + ListNode first = curr; + while (curr != end) { + ListNode next = curr.next; + curr.next = prev; + prev = curr; + curr = next; + } + begin.next = prev; + first.next = curr; + return first; + } + +} diff --git a/src/linkedLists/ReverseLinkedList.java b/src/main/java/linkedLists/ReverseLinkedList.java similarity index 100% rename from src/linkedLists/ReverseLinkedList.java rename to src/main/java/linkedLists/ReverseLinkedList.java diff --git a/src/linkedLists/ReverseLinkedListBetweenMandN.java b/src/main/java/linkedLists/ReverseLinkedListBetweenMandN.java similarity index 100% rename from src/linkedLists/ReverseLinkedListBetweenMandN.java rename to src/main/java/linkedLists/ReverseLinkedListBetweenMandN.java diff --git a/src/linkedLists/ReversePairsNode.java b/src/main/java/linkedLists/ReversePairsNode.java similarity index 100% rename from src/linkedLists/ReversePairsNode.java rename to src/main/java/linkedLists/ReversePairsNode.java diff --git a/src/main/java/linkedLists/RotateList.java b/src/main/java/linkedLists/RotateList.java new file mode 100644 index 0000000..c726a53 --- /dev/null +++ b/src/main/java/linkedLists/RotateList.java @@ -0,0 +1,29 @@ +package linkedLists; + + +public class RotateList { + public ListNode rotateRight(ListNode head, int k) { + if(k==0 || head==null) return head; + + ListNode tempHead= head; + int length=1; + while(tempHead.next!=null){ + length++; + tempHead=tempHead.next; + } + tempHead.next=head; + k%=length; + for(int i=0;i products; //Singleton List + private AuctionState auctionState; + private Date startDate; + private Date endDate; + + public Auction( String auctionId) { + super(); + this.auctionId = auctionId; + this.auctionState = AuctionState.DRAFTED; + } + + public String getAuctionId() { + return auctionId; + } + + public void setAuctionId(String auctionId) { + this.auctionId = auctionId; + } + + public String getSellerId() { + return sellerId; + } + + public void setSellerId(String sellerId) { + this.sellerId = sellerId; + } + + public AuctionState getAuctionState() { + return auctionState; + } + + public void setAuctionState(AuctionState auctionState) { + this.auctionState = auctionState; + } + + public List getProducts() { + return products; + } + + public void setProducts(List products) { + this.products = products; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + @Override + public boolean equals(Object obj) { + if(obj==null) { + return false; + } + if(obj instanceof Auction) { + return this.getAuctionId().equals(((Auction) obj).getAuctionId()); + } + return false; + } +} diff --git a/src/main/java/lld/auctionSystem/models/AuctionProduct.java b/src/main/java/lld/auctionSystem/models/AuctionProduct.java new file mode 100644 index 0000000..202012d --- /dev/null +++ b/src/main/java/lld/auctionSystem/models/AuctionProduct.java @@ -0,0 +1,75 @@ +package lld.auctionSystem.models; + + +import lld.auctionSystem.enums.AuctionProductState; + +import java.util.Objects; + +public class AuctionProduct { + String productId; + Double basePrice; + AuctionProductState auctionProductState; + private Double currentBid; + private String currentWinningBuyerId; + + public AuctionProduct(String productId, double basePrice) { + this.productId = productId; + this.basePrice = basePrice; + this.auctionProductState = AuctionProductState.UNBID; + this.currentBid = 0.0; + this.currentWinningBuyerId = null; + } + + public String getProductId() { + return productId; + } + + public void setProductId(String productId) { + this.productId = productId; + } + + public Double getBasePrice() { + return basePrice; + } + + public void setBasePrice(Double basePrice) { + this.basePrice = basePrice; + } + + public AuctionProductState getAuctionProductState() { + return auctionProductState; + } + + public void setAuctionProductState(AuctionProductState auctionProductState) { + this.auctionProductState = auctionProductState; + } + + public Double getCurrentBid() { + return currentBid; + } + + public void setCurrentBid(Double currentBid) { + this.currentBid = currentBid; + } + + public String getCurrentWinningBuyerId() { + return currentWinningBuyerId; + } + + public void setCurrentWinningBuyerId(String currentWinningBuyerId) { + this.currentWinningBuyerId = currentWinningBuyerId; + } + + @Override + public int hashCode() { + return Objects.hash(getProductId()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof AuctionProduct)) return false; + AuctionProduct that = (AuctionProduct) o; + return Objects.equals(this.getProductId(), that.getProductId()); + } +} diff --git a/src/main/java/lld/auctionSystem/models/Buyer.java b/src/main/java/lld/auctionSystem/models/Buyer.java new file mode 100644 index 0000000..78eef18 --- /dev/null +++ b/src/main/java/lld/auctionSystem/models/Buyer.java @@ -0,0 +1,18 @@ +package lld.auctionSystem.models; + + +import java.util.HashMap; +import java.util.Map; + +public class Buyer extends User { + private Map> subscribedAuctions; + + public Buyer( String BuyerId, String username, String emailId, String phoneNo) { + super(BuyerId, username,emailId, phoneNo); + this.subscribedAuctions = new HashMap<>(); + } + + public Map> getSubscribedAuctions() { + return this.subscribedAuctions; + } +} diff --git a/src/main/java/lld/auctionSystem/models/Event.java b/src/main/java/lld/auctionSystem/models/Event.java new file mode 100644 index 0000000..b26fe50 --- /dev/null +++ b/src/main/java/lld/auctionSystem/models/Event.java @@ -0,0 +1,36 @@ +package lld.auctionSystem.models; + + +import lld.auctionSystem.enums.PublisherEventType; + +import java.util.Date; + +public class Event { + private PublisherEventType eventType; + private String message; + private Date dateTime; + + public PublisherEventType getEventType() { + return eventType; + } + + public void setEventType(PublisherEventType eventType) { + this.eventType = eventType; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public Date getDateTime() { + return dateTime; + } + + public void setDateTime(Date dateTime) { + this.dateTime = dateTime; + } +} diff --git a/src/main/java/lld/auctionSystem/models/Notification.java b/src/main/java/lld/auctionSystem/models/Notification.java new file mode 100644 index 0000000..12c3611 --- /dev/null +++ b/src/main/java/lld/auctionSystem/models/Notification.java @@ -0,0 +1,34 @@ +package lld.auctionSystem.models; + +import java.util.Date; + +public class Notification { + private String message; + private Date dateTime; + + public Notification(String message, Date dateTime) { + this.message = message; + this.dateTime = dateTime; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public Date getDateTime() { + return dateTime; + } + + public void setDateTime(Date dateTime) { + this.dateTime = dateTime; + } + + @Override + public String toString() { + return "Date: " + this.dateTime.toString() + ", " + "Message: " + this.message; + } +} diff --git a/src/main/java/lld/auctionSystem/models/Observer.java b/src/main/java/lld/auctionSystem/models/Observer.java new file mode 100644 index 0000000..45c8b6d --- /dev/null +++ b/src/main/java/lld/auctionSystem/models/Observer.java @@ -0,0 +1,4 @@ +package lld.auctionSystem.models; + +public class Observer { +} diff --git a/src/main/java/lld/auctionSystem/models/Product.java b/src/main/java/lld/auctionSystem/models/Product.java new file mode 100644 index 0000000..0929cad --- /dev/null +++ b/src/main/java/lld/auctionSystem/models/Product.java @@ -0,0 +1,53 @@ +package lld.auctionSystem.models; + + +import java.util.UUID; + +public class Product { + private String productId; + private String name; + private String description; + private String auctionId; + + public Product(){} + + public Product( String productId, String name, String description, String auctionId) { + this.productId = productId; + this.name = name; + this.description = description; + this.auctionId = auctionId; + } + + public String getProductId() { + return productId; + } + + public void setProductId(String productId) { + this.productId = productId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getAuctionId() { + return auctionId; + } + + public void setAuctionId(String auctionId) { + this.auctionId = auctionId; + } + +} diff --git a/src/main/java/lld/auctionSystem/models/Publisher.java b/src/main/java/lld/auctionSystem/models/Publisher.java new file mode 100644 index 0000000..d5cada8 --- /dev/null +++ b/src/main/java/lld/auctionSystem/models/Publisher.java @@ -0,0 +1,23 @@ +package lld.auctionSystem.models; + + +import lld.auctionSystem.enums.ObserverType; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public abstract class Publisher { + private Map> observers; + + public Publisher() { + this.observers = new HashMap<>(); + this.observers.put(ObserverType.SELLER, new LinkedList<>()); + this.observers.put(ObserverType.BUYER, new LinkedList<>()); + } + + public Map> getObservers() { + return this.observers; + } +} diff --git a/src/main/java/lld/auctionSystem/models/Seller.java b/src/main/java/lld/auctionSystem/models/Seller.java new file mode 100644 index 0000000..582ba68 --- /dev/null +++ b/src/main/java/lld/auctionSystem/models/Seller.java @@ -0,0 +1,16 @@ +package lld.auctionSystem.models; + + +import java.util.List; + +public class Seller extends User { + private List auctions; //List of AuctionId + + public Seller( String sellerId, String username, String emailId, String phoneNo) { + super(sellerId, username,emailId, phoneNo); + } + + public List getAuctions() { + return auctions; + } +} diff --git a/src/main/java/lld/auctionSystem/models/User.java b/src/main/java/lld/auctionSystem/models/User.java new file mode 100644 index 0000000..2d702e5 --- /dev/null +++ b/src/main/java/lld/auctionSystem/models/User.java @@ -0,0 +1,70 @@ +package lld.auctionSystem.models; + + +import java.util.LinkedList; +import java.util.List; + +public class User extends Observer { + private String userId; + private String username; + private String emailId; + private String phoneNo; + private List notifications; //Always insert latest data at the head of the list. + // TODO - private List bankAccountDetils; + // TODO - private List

addresses; + + public User( String userId, String username, String emailId, String phoneNo) { + this.userId = userId; + this.username = username; + this.emailId = emailId; + this.phoneNo = phoneNo; + this.notifications = new LinkedList<>(); + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getEmailId() { + return emailId; + } + + public void setEmailId(String emailId) { + this.emailId = emailId; + } + + public String getPhoneNo() { + return phoneNo; + } + + public void setPhoneNo(String phoneNo) { + this.phoneNo = phoneNo; + } + + public List getNotifications() { + return notifications; + } + + @Override + public boolean equals(Object obj) { + if(obj==null) { + return false; + } + if(obj instanceof User) { + return this.username.equals(((User) obj).getUsername()); + } + return false; + } +} \ No newline at end of file diff --git a/src/main/java/lld/auctionSystem/repository/AuctionRepository.java b/src/main/java/lld/auctionSystem/repository/AuctionRepository.java new file mode 100644 index 0000000..8fe432f --- /dev/null +++ b/src/main/java/lld/auctionSystem/repository/AuctionRepository.java @@ -0,0 +1,34 @@ +package lld.auctionSystem.repository; + + +import lld.auctionSystem.models.Auction; + +import java.util.HashMap; +import java.util.Map; + +public class AuctionRepository { + public Map auctions; + + // TODO - Implement thread safe lazy initialization singleton pattern. + private AuctionRepository() { + this.auctions = new HashMap<>(); + } + private static AuctionRepository single_instance = null; + public static AuctionRepository getInstance() { + if(single_instance==null) { + single_instance = new AuctionRepository(); + } + return single_instance; + } + + public void addDataToRepository(String key, Auction value) { + this.auctions.put(key, value); + } + + public Auction getData(String key) { + if(key==null) { + return null; + } + return this.auctions.get(key); + } +} diff --git a/src/main/java/lld/auctionSystem/repository/BuyerRepository.java b/src/main/java/lld/auctionSystem/repository/BuyerRepository.java new file mode 100644 index 0000000..99c5c00 --- /dev/null +++ b/src/main/java/lld/auctionSystem/repository/BuyerRepository.java @@ -0,0 +1,36 @@ +package lld.auctionSystem.repository; + + +import lld.auctionSystem.models.Buyer; + +import java.util.HashMap; +import java.util.Map; + +public class BuyerRepository { + + public static Map Buyers = new HashMap<>(); + + // TODO - Implement thread safe lazy initialization singleton pattern. + private BuyerRepository() { + this.Buyers = new HashMap<>(); + } + private static BuyerRepository single_instance = null; + public static BuyerRepository getInstance() { + if(single_instance==null) { + single_instance = new BuyerRepository(); + } + return single_instance; + } + + public void addDataToRepository(String key, Buyer value) { + this.Buyers.put(key, value); + } + + public Buyer getData(String key) { + if(key==null) { + return null; + } + return this.Buyers.get(key); + } + +} diff --git a/src/main/java/lld/auctionSystem/repository/ProductRepository.java b/src/main/java/lld/auctionSystem/repository/ProductRepository.java new file mode 100644 index 0000000..ffe49b0 --- /dev/null +++ b/src/main/java/lld/auctionSystem/repository/ProductRepository.java @@ -0,0 +1,34 @@ +package lld.auctionSystem.repository; + + +import lld.auctionSystem.models.Product; + +import java.util.HashMap; +import java.util.Map; + +public class ProductRepository { + public static Map products; + + // TODO - Implement thread safe lazy initialization singleton pattern. + private ProductRepository() { + this.products = new HashMap<>(); + } + private static ProductRepository single_instance = null; + public static ProductRepository getInstance() { + if(single_instance==null) { + single_instance = new ProductRepository(); + } + return single_instance; + } + + public void addDataToRepository(String key, Product value) { + this.products.put(key, value); + } + + public Product getData(String key) { + if(key==null) { + return null; + } + return this.products.get(key); + } +} diff --git a/src/main/java/lld/auctionSystem/repository/SellerRepository.java b/src/main/java/lld/auctionSystem/repository/SellerRepository.java new file mode 100644 index 0000000..1bc666f --- /dev/null +++ b/src/main/java/lld/auctionSystem/repository/SellerRepository.java @@ -0,0 +1,38 @@ +package lld.auctionSystem.repository; + + +import lld.auctionSystem.models.Seller; + +import java.util.HashMap; +import java.util.Map; + +public class SellerRepository { + + public Map sellers; + + // TODO - Implement thread safe lazy initialization singleton pattern. + private SellerRepository() { + this.sellers = new HashMap<>(); + } + + private static SellerRepository single_instance = null; + + public static SellerRepository getInstance() { + if (single_instance == null) { + single_instance = new SellerRepository(); + } + return single_instance; + } + + public void addDataToRepository(String key, Seller value) { + this.sellers.put(key, value); + } + + public Seller getData(String key) { + if (key == null) { + return null; + } + return this.sellers.get(key); + } + +} diff --git a/src/main/java/lld/auctionSystem/services/AuctionService.java b/src/main/java/lld/auctionSystem/services/AuctionService.java new file mode 100644 index 0000000..8b748d8 --- /dev/null +++ b/src/main/java/lld/auctionSystem/services/AuctionService.java @@ -0,0 +1,342 @@ +package lld.auctionSystem.services; + + +import lld.auctionSystem.enums.AuctionProductState; +import lld.auctionSystem.enums.AuctionState; +import lld.auctionSystem.enums.ObserverType; +import lld.auctionSystem.enums.PublisherEventType; +import lld.auctionSystem.models.Auction; +import lld.auctionSystem.models.AuctionProduct; +import lld.auctionSystem.models.Event; +import lld.auctionSystem.models.Product; +import lld.auctionSystem.models.Publisher; +import lld.auctionSystem.repository.AuctionRepository; +import lld.auctionSystem.repository.ProductRepository; +import lld.auctionSystem.services.strategies.AuctionDetails; +import lld.auctionSystem.services.strategies.BuyerViewAuctionDetails; +import lld.auctionSystem.services.strategies.SellerViewAuctionDetails; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +public class AuctionService implements PublisherService { + private final ProductRepository productRepository = ProductRepository.getInstance(); + private final AuctionRepository auctionRepository = AuctionRepository.getInstance(); + private final BuyerService buyerService = new BuyerService(); + private final SellerService sellerService = new SellerService(); + + private String generateAuctionId() { + return UUID.randomUUID().toString() + ".AI"; + } + + private String generateProductId() { + return UUID.randomUUID().toString() + ".PI"; + } + + private boolean validateSeller(String sellerId) { + return sellerService.validateSeller(sellerId); + } + + private boolean validateBuyer(String buyerId) { + return buyerService.validateBuyer(buyerId); + } + + public void draftAuction(String sellerId) { + boolean validate = this.validateSeller(sellerId); + if (!validate) { + System.out.println("Seller Id is invalid"); + return; + } + Auction auction = new Auction(this.generateAuctionId()); + auctionRepository.addDataToRepository(auction.getAuctionId(), auction); + System.out.println("Auction created. Auction is in DRAFT state."); + } + + public void updateAuctionProduct(String sellerId, String auctionId, String productName, String productDescription, double basePrice) { + boolean validate = this.validateSeller(sellerId); + if (!validate) { + System.out.println("Seller Id is invalid"); + return; + } + validate = this.validateAuction(auctionId); + if (!validate) { + System.out.println("Auction Id is invalid"); + return; + } + Auction auction = auctionRepository.getData(auctionId); + if (auction.getAuctionState() != AuctionState.DRAFTED) { + System.out.println("Auction is not in draft state. Making any change is not allowed."); + return; + } + Product product = new Product(this.generateProductId(), productName, productDescription, auctionId); + AuctionProduct auctionProduct = new AuctionProduct(product.getProductId(), basePrice); + auction.setProducts(Arrays.asList(new AuctionProduct[]{auctionProduct})); + System.out.println("Product Added"); + } + + // TODO - Add functions to update auction details, product details & auction base price. + + private final long MAX_START_TIME_DELAY = 3 * 3600; + private final long MIN_AUCTION_LIFE = 3600; + private final long MAX_AUCTION_LIFE = 3 * 3600; + + public void publishAuction(String sellerId, String auctionId, Date startTime, Date endTime) { + boolean validate = this.validateSeller(sellerId); + if (!validate) { + System.out.println("Seller Id is invalid"); + return; + } + validate = this.validateAuction(auctionId); + if (!validate) { + System.out.println("Auction Id is invalid"); + return; + } + Auction auction = auctionRepository.getData(auctionId); + if (auction.getProducts() == null || auction.getProducts().size() == 0) { + System.out.println("Add a product before publishing auction."); + return; + } + if (auction.getAuctionState() != AuctionState.DRAFTED) { + System.out.println("Auction is not in draft state. Make changes is not allowed."); + return; + } + Date currentTime = new Date(); + if (startTime == null) { + startTime = currentTime; + } + if (endTime == null) { + endTime = new Date(startTime.getTime() + MIN_AUCTION_LIFE); + } + if (endTime.compareTo(currentTime) < 0 || startTime.compareTo(currentTime) < 0) { + System.out.println("Invalid start date or end date. Start Date and End Date should be greater than current Date"); + return; + } else if (startTime.getTime() - currentTime.getTime() > MAX_START_TIME_DELAY) { + System.out.println("Start Date should be less than current Date + 3 hours"); + return; + } else if (endTime.getTime() - startTime.getTime() > MAX_AUCTION_LIFE) { + System.out.println("Auction cannot be organised for more than allowed time."); + return; + } else if (endTime.getTime() - startTime.getTime() < MIN_AUCTION_LIFE) { + System.out.println("Auction cannot be organised for less than threshold time."); + return; + } + auction.setAuctionState(AuctionState.PUBLISHED); + if (currentTime == startTime) { + startAuction(auctionId); + } else { + //TODO - Write logic + /* + Schedule auction in scheduler service. + Schedule the start and end of auction. For that we can have a Scheduler Service. + Scheduler Service will call the startAuction() api of AuctionService to start the auction when is it time. + Scheduler Service will call the endAuction() api of AuctionService to end the auction when it is time. + */ + } + + } + + //Will be called by the Scheduler Service. + public void startAuction(String auctionId) { + boolean validate = this.validateAuction(auctionId); + if (!validate) { + System.out.println("Auction Id is invalid"); + return; + } + Auction auction = auctionRepository.getData(auctionId); + auction.setAuctionState(AuctionState.STARTED); + updateObserversAboutAuctionStarted(auction); + } + + //Will be called by the Scheduler Service. + public void endAuction(String auctionId) { + boolean validate = this.validateAuction(auctionId); + if (!validate) { + System.out.println("Auction Id is invalid"); + return; + } + Auction auction = auctionRepository.getData(auctionId); + for (AuctionProduct auctionProduct : auction.getProducts()) { + if (auctionProduct.getAuctionProductState().equals(AuctionProductState.UNBID)) { + auctionProduct.setAuctionProductState(AuctionProductState.FAILED); + auction.setAuctionState(AuctionState.END_FAILED); + } else if (auctionProduct.getCurrentBid() >= auctionProduct.getBasePrice()) { + auctionProduct.setAuctionProductState(AuctionProductState.SOLD); + } else { + auctionProduct.setAuctionProductState(AuctionProductState.FAILED); + auction.setAuctionState(AuctionState.END_FAILED); + } + } + if (!auction.getAuctionState().equals(AuctionState.END_FAILED)) { + auction.setAuctionState(AuctionState.END_SUCCESS); + } + updateObserversAboutAuctionEnded(auction); + } + + public void placeBid(String auctionId, String productId, String buyerId, double bidValue) { + boolean validate = this.validateAuction(auctionId); + if (!validate) { + System.out.println("Auction Id is invalid"); + return; + } + validate = this.validateBuyer(buyerId); + if (!validate) { + System.out.println("Buyer Id is invalid"); + return; + } + Auction auction = auctionRepository.getData(auctionId); + AuctionProduct auctionProduct = auction.getProducts().stream().filter(ap -> ap.getProductId().equals(productId)).findFirst().orElse(null); + if (auctionProduct == null) { + System.out.println("productId given does not belong to this auction."); + return; + } + if (auction.getAuctionState() == AuctionState.STARTED && + auctionProduct.getAuctionProductState() != AuctionProductState.SOLD && + auctionProduct.getAuctionProductState() != AuctionProductState.FAILED) { + if (bidValue < auctionProduct.getCurrentBid()) { + System.out.println("Bid Value should be greater than current bid price."); + return; + } + if (auctionProduct.getAuctionProductState() == AuctionProductState.UNBID) { + auctionProduct.setAuctionProductState(AuctionProductState.UNSOLD); + } + buyerService.placeBid(buyerId, auctionId, productId, bidValue); + auctionProduct.setCurrentBid(bidValue); + auctionProduct.setCurrentWinningBuyerId(buyerId); + auctionProduct.setAuctionProductState(AuctionProductState.UNSOLD); + updateObserverAboutNewBidPrice(auction, bidValue); + } else { + System.out.println("Either auction is not started or auction is ended or product is sold."); + } + } + + @Override + // Will be called by the ObserverService only. + public boolean subscribe(String auctionId, String observerId, ObserverType type) { + boolean validate = this.validateAuction(auctionId); + if (!validate) { + System.out.println("Auction Id is invalid"); + return false; + } + Auction auction = auctionRepository.getData(auctionId); + auction.getObservers().get(type).add(observerId); + return true; + } + + @Override + //Will be called by the ObserverService only. + public boolean unsubscribe(String auctionId, String observerId, ObserverType type) { + boolean validate = this.validateAuction(auctionId); + if (!validate) { + System.out.println("Auction Id is invalid"); + return false; + } + if (ObserverType.SELLER == type) { + System.out.println("Seller not allowed to unsubscribe his auction"); + return false; + } + Auction auction = auctionRepository.getData(auctionId); + //If observer is a Buyer, check if current observers is not the current winning Buyer + if (ObserverType.BUYER == type) { + boolean eligible = eligibleToUnsubscribe(auction, observerId); + if (!eligible) { + return false; + } + } + auction.getObservers().get(type).remove(observerId); + return true; + } + + private boolean eligibleToUnsubscribe(Auction auction, String observerId) { + List auctionProductList = auction.getProducts(); + for (AuctionProduct auctionProduct : auctionProductList) { + if (auctionProduct.getCurrentWinningBuyerId().equals(observerId)) { + System.out.println("Buyer is current winning bidder for one of the product and so not allowed to unsubscribe."); + return false; + } + } + return true; + } + + private void updateObserversAboutAuctionStarted(Auction auction) { + Event event = new Event(); + event.setEventType(PublisherEventType.AUCTION_STARTED); + event.setMessage("Auction Started! - " + auction.getAuctionId()); + event.setDateTime(new Date()); + + updateObservers(auction, ObserverType.BOTH, event); + } + + private void updateObserversAboutAuctionEnded(Auction auction) { + Event event; + + event = new Event(); + event.setEventType(PublisherEventType.AUCTION_ENDED); + event.setMessage("Auction Ended! - " + auction.getAuctionId()); + event.setDateTime(new Date()); + + updateObservers(auction, ObserverType.BOTH, event); + + for (AuctionProduct auctionProduct : auction.getProducts()) { + if (auctionProduct.getAuctionProductState().equals(AuctionProductState.FAILED)) { + continue; + } + event = new Event(); + event.setEventType(PublisherEventType.AUCTION_ENDED); + event.setMessage("Auction Ended! - " + auction.getAuctionId() + + "Congrats! You bought the product - " + auctionProduct.getProductId()); + event.setDateTime(new Date()); + updateObservers(Arrays.asList(auctionProduct.getCurrentWinningBuyerId()), ObserverType.BUYER, event); + } + } + + private void updateObserverAboutNewBidPrice(Auction auction, double bidValue) { + Event event = new Event(); + event.setEventType(PublisherEventType.BID_VALUE_UPDATED); + event.setMessage("Bid Price updated! Auction - " + auction.getAuctionId() + "New Bid price is: " + bidValue); + event.setDateTime(new Date()); + + updateObservers(auction, ObserverType.BUYER, event); + } + + private void updateObservers(Publisher auction, ObserverType observerType, Event event) { + this.updateObservers(auction.getObservers().get(observerType), observerType, event); + } + + @Override + //Will be called by AuctionSerice class only when the state of auction changes. + public void updateObservers(List observerIds, ObserverType observerType, Event event) { + ObserverService observerService; + switch (observerType) { + case BUYER: + buyerService.updateObserver(observerIds, event); + break; + case SELLER: + sellerService.updateObserver(observerIds, event); + break; + case BOTH: + buyerService.updateObserver(observerIds, event); + sellerService.updateObserver(observerIds, event); + break; + default: + System.out.println("Observer Type not listed"); + } + } + + public String getAuctionDetails(String userId, String auctionId, String algorithm) { + AuctionDetails auctionDetailsObject = null; + if (algorithm.equals("SellerView")) { + auctionDetailsObject = new SellerViewAuctionDetails(); + } else { + auctionDetailsObject = new BuyerViewAuctionDetails(); + } + // Using Strategy Pattern + String response = auctionDetailsObject.getAuctionDetails(userId, auctionId); + return response; + } + + public boolean validateAuction(String auctionId) { + return auctionRepository.getData(auctionId) != null ? true : false; + } +} diff --git a/src/main/java/lld/auctionSystem/services/BuyerService.java b/src/main/java/lld/auctionSystem/services/BuyerService.java new file mode 100644 index 0000000..d1c297a --- /dev/null +++ b/src/main/java/lld/auctionSystem/services/BuyerService.java @@ -0,0 +1,164 @@ +package lld.auctionSystem.services; + + + +import lld.auctionSystem.enums.ObserverType; +import lld.auctionSystem.models.Buyer; +import lld.auctionSystem.models.Event; +import lld.auctionSystem.models.Notification; +import lld.auctionSystem.repository.BuyerRepository; +import lld.auctionSystem.utils.Utils; + +import java.util.*; + +public class BuyerService implements ObserverService { + private final BuyerRepository buyerRepository = BuyerRepository.getInstance(); + private final AuctionService auctionService = new AuctionService(); + private static final ObserverType BUYER_AS_OBSERVER = ObserverType.BUYER; + + private String generateBuyerId() { + return UUID.randomUUID().toString()+".BI"; + } + + public void addBuyer( String username, String emailId, String phoneNo) { + boolean validEmailId = Utils.validateEmailId(emailId); + if(!validEmailId) { + System.out.println("Please enter valid emailId."); + return; + } + boolean validPhoneNo = Utils.validatePhoneNo(phoneNo); + if(!validPhoneNo) { + System.out.println("Please enter valid phoneNo."); + return; + } + // TODO - Check username is not already used. If used, do not create new buyer and return. + String buyerId = this.generateBuyerId(); + Buyer buyer = new Buyer(buyerId, username, emailId, phoneNo); + buyerRepository.addDataToRepository(buyerId, buyer); + } + + public List viewAllBuyerBids(String buyerId) { + boolean validate = this.validateBuyer(buyerId); + if(!validate) { + System.out.println("Buyer Id not valid"); + return null; + } + Buyer buyer = buyerRepository.getData(buyerId); + List response = new LinkedList<>(); + Map> subscribedAuctions = buyer.getSubscribedAuctions(); + for(String auctionId : subscribedAuctions.keySet()) { + for(String productId : subscribedAuctions.get(auctionId).keySet()) { + String data = "AuctiondId: " + auctionId + ", " + + "ProductId: " + productId + ", " + + "BidValue: " + subscribedAuctions.get(auctionId).get(productId); + response.add(data); + } + } + return response; + } + + public void subscribeToAuction(String buyerId, String auctionId) { + boolean validate = this.validateBuyer(buyerId); + if(!validate) { + System.out.println("Buyer Id not valid"); + return; + } + Buyer buyer = buyerRepository.getData(buyerId); + if(buyer.getSubscribedAuctions().containsKey(auctionId)) { + System.out.println("Already subscribed to the auction."); + return; + } + boolean success = auctionService.subscribe(auctionId, buyerId, BUYER_AS_OBSERVER); + if(success) { + buyer.getSubscribedAuctions().put(auctionId, new HashMap<>()); + } + else { + System.out.println("Failed to subscribe."); + } + } + + public void unsubscribeToAuction(String buyerId, String auctionId) { + boolean validate = this.validateBuyer(buyerId); + if(!validate) { + System.out.println("Buyer Id not valid"); + return; + } + Buyer buyer = buyerRepository.getData(buyerId); + if(!buyer.getSubscribedAuctions().containsKey(auctionId)) { + System.out.println("Have not subscribed to the auction."); + return; + } + boolean success = auctionService.unsubscribe(auctionId, buyerId, BUYER_AS_OBSERVER); + if(success) { + buyer.getSubscribedAuctions().remove(auctionId); + } + else { + System.out.println("Failed to unsubscribe."); + } + } + + //Access only from AuctionService + public boolean placeBid(String buyerId, String auctionId, String productId, double bidValue) { + boolean validate = this.validateBuyer(buyerId); + if(!validate) { + System.out.println("Buyer Id not valid"); + return false; + } + subscribeToAuction(buyerId, auctionId); + Buyer buyer = buyerRepository.getData(buyerId); + Map> subscribedAuctions = buyer.getSubscribedAuctions(); + if(subscribedAuctions.containsKey(auctionId)) { + Map existingBids = subscribedAuctions.get(auctionId); + if(existingBids.containsKey(productId)) { + double exisitingBidValue = existingBids.get(productId); + if(exisitingBidValue <= bidValue) { + System.out.println("You have already bid with less/same amount. Increase bid."); + return false; + } + } + existingBids.put(productId, bidValue); + } + else { + System.out.println("subscribeToAuction call failed."); + return false; + } + return true; + } + + private static final int MAX_NOTIFICATION_COUNT = 10; //Maximum no. of notifications to return + + public List getNotifications(String buyerId) { + boolean validate = this.validateBuyer(buyerId); + if(!validate) { + System.out.println("Buyer Id not valid"); + return null; + } + Buyer buyer = buyerRepository.getData(buyerId); + List retval = new LinkedList<>(); + for(Notification notification : buyer.getNotifications()) { + retval.add(notification.toString()); + if(retval.size() == MAX_NOTIFICATION_COUNT) { + break; + } + } + return retval; + } + + public boolean validateBuyer(String buyerId) { + return buyerRepository.getData(buyerId) != null ? true : false; + } + + @Override + public void updateObserver(List buyerIds, Event event) { + for(String buyerId : buyerIds) { + boolean validate = this.validateBuyer(buyerId); + if(!validate) { + continue; + } + Buyer buyer = buyerRepository.getData(buyerId); + Notification notification = new Notification(event.getMessage(), event.getDateTime()); + buyer.getNotifications().add(0, notification); + } + } + +} diff --git a/src/main/java/lld/auctionSystem/services/ObserverService.java b/src/main/java/lld/auctionSystem/services/ObserverService.java new file mode 100644 index 0000000..5223802 --- /dev/null +++ b/src/main/java/lld/auctionSystem/services/ObserverService.java @@ -0,0 +1,11 @@ +package lld.auctionSystem.services; + +import lld.auctionSystem.models.Event; + +import java.util.List; + +public interface ObserverService { + + void updateObserver(List ids, Event event); + +} diff --git a/src/main/java/lld/auctionSystem/services/PublisherService.java b/src/main/java/lld/auctionSystem/services/PublisherService.java new file mode 100644 index 0000000..9343401 --- /dev/null +++ b/src/main/java/lld/auctionSystem/services/PublisherService.java @@ -0,0 +1,16 @@ +package lld.auctionSystem.services; + + +import lld.auctionSystem.enums.ObserverType; +import lld.auctionSystem.models.Event; + +import java.util.List; + +public interface PublisherService { + + void updateObservers(List observerIds, ObserverType type, Event event); + + boolean subscribe(String subjectId, String observerId, ObserverType type); + + boolean unsubscribe(String subjectId, String observerId, ObserverType type); +} diff --git a/src/main/java/lld/auctionSystem/services/SellerService.java b/src/main/java/lld/auctionSystem/services/SellerService.java new file mode 100644 index 0000000..e19a8cd --- /dev/null +++ b/src/main/java/lld/auctionSystem/services/SellerService.java @@ -0,0 +1,94 @@ +package lld.auctionSystem.services; + + +import lld.auctionSystem.models.Event; +import lld.auctionSystem.models.Notification; +import lld.auctionSystem.models.Seller; +import lld.auctionSystem.repository.SellerRepository; +import lld.auctionSystem.utils.Utils; + +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +public class SellerService implements ObserverService { + SellerRepository sellerRepository = SellerRepository.getInstance(); + AuctionService auctionService = new AuctionService(); + + private String generateSellerId() { + return UUID.randomUUID().toString()+".SI"; + } + + public void addSeller( String username, String emailId, String phoneNo) { + boolean validEmailId = Utils.validateEmailId(emailId); + if(!validEmailId) { + System.out.println("Please enter valid emailId."); + return; + } + boolean validPhoneNo = Utils.validatePhoneNo(phoneNo); + if(!validPhoneNo) { + System.out.println("Please enter valid phoneNo."); + return; + } + // TODO - Check username is not already used. If used, do not create new seller and return. + String sellerId = this.generateSellerId(); + Seller seller = new Seller(sellerId, username, emailId, phoneNo); + sellerRepository.addDataToRepository(sellerId, seller); + } + + public List viewAllSellerOwnedAuctions(String sellerId) { + boolean validate = this.validateSeller(sellerId); + if(!validate) { + System.out.println("Seller Id not valid"); + return null; + } + Seller seller = sellerRepository.getData(sellerId); + List response = new LinkedList<>(); + for(String auctionId : seller.getAuctions()) { + String auctionDetails = auctionService.getAuctionDetails(sellerId, auctionId, "SellerView"); + if(auctionDetails==null) { + continue; + } + response.add(auctionDetails); + } + return response; + } + + private static final int MAX_NOTIFICATION_COUNT = 10; //Maximum no. of notifications to return + + public List getNotifications(String sellerId) { + boolean validate = this.validateSeller(sellerId); + if(!validate) { + System.out.println("Seller Id not valid"); + return null; + } + Seller seller = sellerRepository.getData(sellerId); + List retval = new LinkedList<>(); + for(Notification notification : seller.getNotifications()) { + retval.add(notification.toString()); + if(retval.size() == MAX_NOTIFICATION_COUNT) { + break; + } + } + return retval; + } + + public boolean validateSeller(String sellerId) { + return sellerRepository.getData(sellerId) != null ? true : false; + } + + @Override + //This method will be called by the publisher to update the observer. + public void updateObserver(List sellerIds, Event event) { + for(String sellerId : sellerIds) { + boolean validate = this.validateSeller(sellerId); + if(!validate) { + continue; + } + Seller seller = sellerRepository.getData(sellerId); + Notification notification = new Notification(event.getMessage(), event.getDateTime()); + seller.getNotifications().add(0, notification); + } + } + +} diff --git a/src/main/java/lld/auctionSystem/services/strategies/AuctionDetails.java b/src/main/java/lld/auctionSystem/services/strategies/AuctionDetails.java new file mode 100644 index 0000000..21e6888 --- /dev/null +++ b/src/main/java/lld/auctionSystem/services/strategies/AuctionDetails.java @@ -0,0 +1,5 @@ +package lld.auctionSystem.services.strategies; + +public abstract class AuctionDetails { + public abstract String getAuctionDetails(String userId, String auctionId); +} diff --git a/src/main/java/lld/auctionSystem/services/strategies/BuyerViewAuctionDetails.java b/src/main/java/lld/auctionSystem/services/strategies/BuyerViewAuctionDetails.java new file mode 100644 index 0000000..c2c904b --- /dev/null +++ b/src/main/java/lld/auctionSystem/services/strategies/BuyerViewAuctionDetails.java @@ -0,0 +1,45 @@ +package lld.auctionSystem.services.strategies; + + +import lld.auctionSystem.enums.AuctionProductState; +import lld.auctionSystem.enums.AuctionState; +import lld.auctionSystem.models.Auction; +import lld.auctionSystem.models.AuctionProduct; +import lld.auctionSystem.models.Product; +import lld.auctionSystem.repository.AuctionRepository; +import lld.auctionSystem.repository.ProductRepository; + +public class BuyerViewAuctionDetails extends AuctionDetails{ + AuctionRepository auctionRepository = AuctionRepository.getInstance(); + ProductRepository productRepository = ProductRepository.getInstance(); + + public String getAuctionDetails(String buyerId, String auctionId) { + Auction auction = auctionRepository.getData(auctionId); + if(auction.getAuctionState()== AuctionState.STARTED) { + StringBuilder data = new StringBuilder(); + data.append("Auction start Date & Time" + auction.getStartDate().toString() + "\n"); + data.append("Auction end Date & Time" + auction.getEndDate().toString() + "\n"); + for (AuctionProduct auctionProduct : auction.getProducts()) { + Product product = productRepository.getData(auctionProduct.getProductId()); + data.append("Auction Product : " + product.getName() + ", " + + product.getDescription() + ", "); + if (auctionProduct.getAuctionProductState() == AuctionProductState.SOLD) { + data.append("State: SOLD"); + } else { + data.append("State: UNSOLD" + ", "); + if (auctionProduct.getAuctionProductState() == AuctionProductState.UNBID) { + data.append("Bid starts at: " + "No bid placed till now"); + } else { + data.append("Current Bid: " + auctionProduct.getCurrentBid()); + } + } + data.append("\n"); + } + return data.toString(); + } + else { + System.out.println("Error! Auction should not be visible to the user."); + return null; + } + } +} diff --git a/src/main/java/lld/auctionSystem/services/strategies/SellerViewAuctionDetails.java b/src/main/java/lld/auctionSystem/services/strategies/SellerViewAuctionDetails.java new file mode 100644 index 0000000..46f4687 --- /dev/null +++ b/src/main/java/lld/auctionSystem/services/strategies/SellerViewAuctionDetails.java @@ -0,0 +1,46 @@ +package lld.auctionSystem.services.strategies; + +import lld.auctionSystem.enums.AuctionProductState; +import lld.auctionSystem.models.Auction; +import lld.auctionSystem.models.AuctionProduct; +import lld.auctionSystem.models.Product; +import lld.auctionSystem.repository.AuctionRepository; +import lld.auctionSystem.repository.ProductRepository; + +public class SellerViewAuctionDetails extends AuctionDetails { + AuctionRepository auctionRepository = AuctionRepository.getInstance(); + ProductRepository productRepository = ProductRepository.getInstance(); + + public String getAuctionDetails(String sellerId, String auctionId) { + Auction auction = auctionRepository.getData(auctionId); + if (!auction.getSellerId().equals(sellerId)) { + // TODO - Throw Exception + System.out.println("This auction does not belong to the seller who requested auction data."); + return null; + } + StringBuilder data = new StringBuilder(""); + data.append("Auction State : " + auction.getAuctionState().toString() + "\n"); + data.append("Auction start Date & Time" + auction.getStartDate().toString() + "\n"); + data.append("Auction end Date & Time" + auction.getEndDate().toString() + "\n"); + if (auction.getProducts() != null) { + for (AuctionProduct auctionProduct : auction.getProducts()) { + Product product = productRepository.getData(auctionProduct.getProductId()); + data.append("Auction Product : " + product.getName() + ", " + + product.getDescription() + ", " + + auctionProduct.getBasePrice() + ", " + + auctionProduct.getAuctionProductState().toString() + ", "); + if(auctionProduct.getAuctionProductState() != AuctionProductState.UNBID) { + data.append(auctionProduct.getCurrentBid()); + } + else { + data.append("No bid on product yet"); + } + data.append("\n"); + } + } + else { + data.append("Auction Product : No product added\n"); + } + return data.toString(); + } +} diff --git a/src/main/java/lld/auctionSystem/utils/Utils.java b/src/main/java/lld/auctionSystem/utils/Utils.java new file mode 100644 index 0000000..bf6160d --- /dev/null +++ b/src/main/java/lld/auctionSystem/utils/Utils.java @@ -0,0 +1,15 @@ +package lld.auctionSystem.utils; + +public class Utils { + + public static boolean validateEmailId(String emailId) { + // TODO - Logic to validate emailId. + return true; + } + + public static boolean validatePhoneNo(String phoneNo) { + // TODO - Logic to validate phoneNo. + return true; + } + +} diff --git a/src/main/java/lld/billsharing/BillSharingMain.java b/src/main/java/lld/billsharing/BillSharingMain.java new file mode 100644 index 0000000..431fc3d --- /dev/null +++ b/src/main/java/lld/billsharing/BillSharingMain.java @@ -0,0 +1,110 @@ +package lld.billsharing; + +import lld.billsharing.exceptions.ContributionExceededException; +import lld.billsharing.exceptions.ExpenseDoesNotExistsException; +import lld.billsharing.exceptions.ExpenseSettledException; +import lld.billsharing.exceptions.InvalidExpenseState; +import lld.billsharing.model.Contribution; +import lld.billsharing.model.Expense; +import lld.billsharing.model.ExpenseGroup; +import lld.billsharing.model.ExpenseStatus; +import lld.billsharing.model.User; +import lld.billsharing.model.UserShare; +import lld.billsharing.repository.ExpenseRepository; +import lld.billsharing.service.ExpenseService; +import lld.billsharing.service.UserService; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.Month; +import java.util.Set; + +public class BillSharingMain { + + static ExpenseService expenseService; + static UserService userService; + + public static void main(String[] args) throws ContributionExceededException, InvalidExpenseState, + ExpenseSettledException { + expenseService = new ExpenseService(); + userService = new UserService(); + createTestUsers(); + + Expense expense = createLunchExpense(); + try { + bifurcateExpense(expense.getId()); + } catch (ExpenseDoesNotExistsException expenseDoesNotExistsException) { + System.out.println(expenseDoesNotExistsException.getMessage()); + } + expense.setExpenseStatus(ExpenseStatus.PENDING); + + Set users = expense.getExpenseGroup().getGroupMembers(); + for (User user : users) { + contributeToExpense(expense.getId(), user.getEmailId()); + } + if (expenseService.isExpenseSettled(expense.getId())) { + System.out.println("Expense Settled...."); + expenseService.setExpenseStatus(expense.getId(), ExpenseStatus.SETTLED); + } + System.out.println("Bye......"); + } + + private static void createTestUsers() { + User user1 = userService.createUser("bagesh@gmail.com", "bagesh", "3486199635"); + User user2 = userService.createUser("ajay@gmail.com", "ajay", "6112482630"); + User user3 = userService.createUser("amit@gmail.com", "amit", "2509699232"); + User user4 = userService.createUser("kamal@gmail.com", "kamal", "5816355154"); + User user5 = userService.createUser("neha@gmail.com", "neha", "7737316054"); + User user6 = userService.createUser("kajal@gmail.com", "kajal", "4813053349"); + User user7 = userService.createUser("jyothi@gmail.com", "jyothi", "3974178644"); + User user8 = userService.createUser("subin@gmail.com", "subin", "4768463294"); + User user9 = userService.createUser("deepak@gmail.com", "deepak", "4829338803"); + User user10 = userService.createUser("vishnu@gmail.com", "vishnu", "3384071602"); + User user11 = userService.createUser("mayank@gmail.com", "mayank", "2376951206"); + User user12 = userService.createUser("anu@gmail.com", "anu", "8478577491"); + User user13 = userService.createUser("kavya@gmail.com", "kavya", "7505888698"); + User user14 = userService.createUser("divya@gmail.com", "divya", "9587030077"); + User user15 = userService.createUser("prabhu@gmail.com", "prabhu", "3303167757"); + User user16 = userService.createUser("sangeeth@gmail.com", "sangeeth", "7409081739"); + User user17 = userService.createUser("rajesh@gmail.com", "rajesh", "2367659285"); + User user18 = userService.createUser("alamelu@gmail.com", "alamelu", "8938025834"); + User user19 = userService.createUser("aruna@gmail.com", "aruna", "8189506064"); + User user20 = userService.createUser("palani@gmail.com", "palani", "2973733105"); + } + + public static Expense createLunchExpense() { + Expense expense = expenseService.createExpense("Team Lunch", + "Friday 19Th June Lunch in Briyani zone" + , LocalDateTime.of(2020, Month.JUNE, 19, 12, 0), + 2000.00, "vishnu@gmail.com"); + return expense; + } + + private static void bifurcateExpense(String expenseId) throws ExpenseDoesNotExistsException { + expenseService.addUsersToExpense(expenseId, "bagesh@gmail.com"); + expenseService.addUsersToExpense(expenseId, "divya@gmail.com"); + expenseService.addUsersToExpense(expenseId, "palani@gmail.com"); + expenseService.addUsersToExpense(expenseId, "neha@gmail.com"); + + expenseService.assignExpenseShare(expenseId, + ExpenseRepository.expenseMap.get(expenseId).getUserId(), 400); + expenseService.assignExpenseShare(expenseId, "bagesh@gmail.com", 400); + expenseService.assignExpenseShare(expenseId, "divya@gmail.com", 400); + expenseService.assignExpenseShare(expenseId, "palani@gmail.com", 400); + expenseService.assignExpenseShare(expenseId, "neha@gmail.com", 400); + } + + private static void contributeToExpense(String expenseId, String userId) + throws ContributionExceededException, InvalidExpenseState, ExpenseSettledException { + Contribution contribution = new Contribution(); + Expense expense = ExpenseRepository.expenseMap.get(expenseId); + ExpenseGroup expenseGroup = expense.getExpenseGroup(); + UserShare userShare = expenseGroup.getUserContributions().get(userId); + contribution.setContributionValue(userShare.getShare()); + contribution.setContributionDate(LocalDateTime.now()); + contribution.setTransactionId("T" + Instant.EPOCH); + contribution.setTransactionDescription("Transferred from UPI"); + userService.contributeToExpense(expenseId, userId, contribution); + + } +} diff --git a/src/main/java/lld/billsharing/exceptions/ContributionExceededException.java b/src/main/java/lld/billsharing/exceptions/ContributionExceededException.java new file mode 100644 index 0000000..1d0bbff --- /dev/null +++ b/src/main/java/lld/billsharing/exceptions/ContributionExceededException.java @@ -0,0 +1,12 @@ +package lld.billsharing.exceptions; + +public class ContributionExceededException extends Exception { + public ContributionExceededException(String message) { + super(message); + } + + @Override + public String getMessage() { + return super.getMessage(); + } +} diff --git a/src/main/java/lld/billsharing/exceptions/ExpenseDoesNotExistsException.java b/src/main/java/lld/billsharing/exceptions/ExpenseDoesNotExistsException.java new file mode 100644 index 0000000..a935961 --- /dev/null +++ b/src/main/java/lld/billsharing/exceptions/ExpenseDoesNotExistsException.java @@ -0,0 +1,13 @@ +package lld.billsharing.exceptions; + +public class ExpenseDoesNotExistsException extends Exception { + + public ExpenseDoesNotExistsException(String message) { + super(message); + } + + @Override + public String getMessage() { + return this.getMessage(); + } +} diff --git a/src/main/java/lld/billsharing/exceptions/ExpenseSettledException.java b/src/main/java/lld/billsharing/exceptions/ExpenseSettledException.java new file mode 100644 index 0000000..761ba48 --- /dev/null +++ b/src/main/java/lld/billsharing/exceptions/ExpenseSettledException.java @@ -0,0 +1,12 @@ +package lld.billsharing.exceptions; + +public class ExpenseSettledException extends Exception { + public ExpenseSettledException(String s) { + super(s); + } + + @Override + public String getMessage() { + return super.getMessage(); + } +} diff --git a/src/main/java/lld/billsharing/exceptions/InvalidExpenseState.java b/src/main/java/lld/billsharing/exceptions/InvalidExpenseState.java new file mode 100644 index 0000000..1a01a90 --- /dev/null +++ b/src/main/java/lld/billsharing/exceptions/InvalidExpenseState.java @@ -0,0 +1,13 @@ +package lld.billsharing.exceptions; + +public class InvalidExpenseState extends Exception { + + public InvalidExpenseState(String message) { + super(message); + } + + @Override + public String getMessage() { + return super.getMessage(); + } +} diff --git a/src/main/java/lld/billsharing/model/Contribution.java b/src/main/java/lld/billsharing/model/Contribution.java new file mode 100644 index 0000000..716ba8d --- /dev/null +++ b/src/main/java/lld/billsharing/model/Contribution.java @@ -0,0 +1,16 @@ +package lld.billsharing.model; + +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; + +@Getter +@Setter +public class Contribution { + private String contributionId; + private double contributionValue; + private String transactionId; + private LocalDateTime contributionDate; + private String transactionDescription; +} \ No newline at end of file diff --git a/src/main/java/lld/billsharing/model/Expense.java b/src/main/java/lld/billsharing/model/Expense.java new file mode 100644 index 0000000..5ceeee2 --- /dev/null +++ b/src/main/java/lld/billsharing/model/Expense.java @@ -0,0 +1,22 @@ +package lld.billsharing.model; + + +import lombok.*; + +import java.time.LocalDateTime; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Expense { + private String id; + private String userId; + private String title; + private String description; + private LocalDateTime expenseDate; + private ExpenseStatus expenseStatus; + private double expenseAmount; + private ExpenseGroup expenseGroup; +} \ No newline at end of file diff --git a/src/main/java/lld/billsharing/model/ExpenseGroup.java b/src/main/java/lld/billsharing/model/ExpenseGroup.java new file mode 100644 index 0000000..18704b5 --- /dev/null +++ b/src/main/java/lld/billsharing/model/ExpenseGroup.java @@ -0,0 +1,26 @@ +package lld.billsharing.model; + +import lombok.Getter; +import lombok.Setter; + +import java.util.*; + +@Getter +public class ExpenseGroup { + + private Set groupMembers = new HashSet<>(); + + public ExpenseGroup() { + this.expenseGroupId = UUID.randomUUID().toString(); + this.groupMembers = new HashSet<>(); + this.userContributions = new HashMap<>(); + } + + private String expenseGroupId; + @Setter + private Map userContributions; + + public void ExpenseGroup() { + + } +} \ No newline at end of file diff --git a/src/main/java/lld/billsharing/model/ExpenseStatus.java b/src/main/java/lld/billsharing/model/ExpenseStatus.java new file mode 100644 index 0000000..88c7127 --- /dev/null +++ b/src/main/java/lld/billsharing/model/ExpenseStatus.java @@ -0,0 +1,7 @@ +package lld.billsharing.model; + +public enum ExpenseStatus { + CREATED, + PENDING, + SETTLED +} diff --git a/src/main/java/lld/billsharing/model/User.java b/src/main/java/lld/billsharing/model/User.java new file mode 100644 index 0000000..6ad2d2f --- /dev/null +++ b/src/main/java/lld/billsharing/model/User.java @@ -0,0 +1,23 @@ +package lld.billsharing.model; + +import lombok.Getter; +import lombok.NonNull; +import lombok.Setter; + +import java.util.UUID; + +@Getter +@Setter +public class User { + private String name; + private String userId; + private String emailId; + private String phoneNumber; + + public User(@NonNull String emailId, String name, String phoneNumber) { + userId = UUID.randomUUID().toString(); + this.emailId = emailId; + this.name = name; + this.phoneNumber = phoneNumber; + } +} \ No newline at end of file diff --git a/src/main/java/lld/billsharing/model/UserShare.java b/src/main/java/lld/billsharing/model/UserShare.java new file mode 100644 index 0000000..4c833e0 --- /dev/null +++ b/src/main/java/lld/billsharing/model/UserShare.java @@ -0,0 +1,19 @@ +package lld.billsharing.model; + +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +@Getter +public class UserShare { + public UserShare(String userId, double share) { + this.userId = userId; + this.share = share; + contributions = new ArrayList<>(); + } + + private String userId; + private double share; + List contributions; +} diff --git a/src/main/java/lld/billsharing/repository/ExpenseRepository.java b/src/main/java/lld/billsharing/repository/ExpenseRepository.java new file mode 100644 index 0000000..406b7c8 --- /dev/null +++ b/src/main/java/lld/billsharing/repository/ExpenseRepository.java @@ -0,0 +1,14 @@ +package lld.billsharing.repository; + +import lld.billsharing.model.Expense; +import lombok.Getter; +import lombok.Setter; + +import java.util.HashMap; +import java.util.Map; + +@Getter +@Setter +public class ExpenseRepository { + public static Map expenseMap = new HashMap<>(); +} diff --git a/src/main/java/lld/billsharing/repository/UserRepository.java b/src/main/java/lld/billsharing/repository/UserRepository.java new file mode 100644 index 0000000..833f3a9 --- /dev/null +++ b/src/main/java/lld/billsharing/repository/UserRepository.java @@ -0,0 +1,14 @@ +package lld.billsharing.repository; + +import lld.billsharing.model.User; +import lombok.Getter; +import lombok.Setter; + +import java.util.HashMap; +import java.util.Map; + +@Getter +@Setter +public class UserRepository { + public static Map userHashMap = new HashMap<>(); +} diff --git a/src/main/java/lld/billsharing/service/ExpenseService.java b/src/main/java/lld/billsharing/service/ExpenseService.java new file mode 100644 index 0000000..a3c588c --- /dev/null +++ b/src/main/java/lld/billsharing/service/ExpenseService.java @@ -0,0 +1,88 @@ +package lld.billsharing.service; + +import lld.billsharing.exceptions.ExpenseDoesNotExistsException; +import lld.billsharing.model.Contribution; +import lld.billsharing.model.Expense; +import lld.billsharing.model.ExpenseGroup; +import lld.billsharing.model.ExpenseStatus; +import lld.billsharing.model.UserShare; +import lld.billsharing.repository.ExpenseRepository; +import lld.billsharing.repository.UserRepository; + +import java.time.LocalDateTime; +import java.util.Map; +import java.util.UUID; + +//@Slf4j +public class ExpenseService { + private NotificationService notificationService = new NotificationServiceImpl(); + + public Expense createExpense(String title, String description, LocalDateTime expenseDate, double expenseAmount, + String userId) { + Expense expense = Expense.builder() + .id(UUID.randomUUID().toString()) + .title(title) + .description(description) + .expenseDate(expenseDate) + .expenseAmount(expenseAmount) + .userId(userId) + .expenseStatus(ExpenseStatus.CREATED) + .expenseGroup(new ExpenseGroup()) + .build(); + ExpenseRepository.expenseMap.putIfAbsent(expense.getId(), expense); + return expense; + } + + public void addUsersToExpense(String expenseId, String emailId) throws + ExpenseDoesNotExistsException { + if (!ExpenseRepository.expenseMap.containsKey(expenseId)) { + throw new + ExpenseDoesNotExistsException("Better create expense and come here...."); +// System.out.println("Better create expense and come here...."); + } + ExpenseRepository.expenseMap.get(expenseId) + .getExpenseGroup().getGroupMembers() + .add(UserRepository.userHashMap.get(emailId)); + + if (notificationService != null) { + notificationService.notifyUser(UserRepository.userHashMap.get(emailId), + ExpenseRepository.expenseMap.get(expenseId)); + } + } + + public void assignExpenseShare(String expenseId, String emailId, double share) + throws ExpenseDoesNotExistsException { + if (!ExpenseRepository.expenseMap.containsKey(expenseId)) { + throw new ExpenseDoesNotExistsException(String.format("Expense %s does not exists", expenseId)); + } + Expense expense = ExpenseRepository.expenseMap.get(expenseId); + expense.getExpenseGroup() + .getUserContributions().putIfAbsent(emailId, new UserShare(emailId, share)); + + } + + public void setExpenseStatus(String expenseId, ExpenseStatus expenseStatus) { + Expense expense = ExpenseRepository.expenseMap.get(expenseId); + expense.setExpenseStatus(expenseStatus); + } + + public boolean isExpenseSettled(String expenseId) { + Expense expense = ExpenseRepository.expenseMap.get(expenseId); + ExpenseGroup expenseGroup = expense.getExpenseGroup(); + Map userContributions = expenseGroup.getUserContributions(); + + double total = expense.getExpenseAmount(); + + for (Map.Entry entry : userContributions.entrySet()) { + UserShare userShare = entry.getValue(); + for (Contribution contribution : userShare.getContributions()) { + total -= contribution.getContributionValue(); + } + } + if (total <= 1) { + return true; + } + return false; + } + +} diff --git a/src/main/java/lld/billsharing/service/NotificationService.java b/src/main/java/lld/billsharing/service/NotificationService.java new file mode 100644 index 0000000..73abdda --- /dev/null +++ b/src/main/java/lld/billsharing/service/NotificationService.java @@ -0,0 +1,8 @@ +package lld.billsharing.service; + +import lld.billsharing.model.Expense; +import lld.billsharing.model.User; + +public interface NotificationService { + void notifyUser(User user, Expense expense); +} diff --git a/src/main/java/lld/billsharing/service/NotificationServiceImpl.java b/src/main/java/lld/billsharing/service/NotificationServiceImpl.java new file mode 100644 index 0000000..7f5bfbb --- /dev/null +++ b/src/main/java/lld/billsharing/service/NotificationServiceImpl.java @@ -0,0 +1,12 @@ +package lld.billsharing.service; + + +import lld.billsharing.model.Expense; +import lld.billsharing.model.User; + +public class NotificationServiceImpl implements NotificationService { + @Override + public void notifyUser(User user, Expense expense) { + System.out.println("Notified"); + } +} diff --git a/src/main/java/lld/billsharing/service/UserService.java b/src/main/java/lld/billsharing/service/UserService.java new file mode 100644 index 0000000..9a0ff99 --- /dev/null +++ b/src/main/java/lld/billsharing/service/UserService.java @@ -0,0 +1,61 @@ +package lld.billsharing.service; + +import lld.billsharing.exceptions.ContributionExceededException; +import lld.billsharing.exceptions.ExpenseSettledException; +import lld.billsharing.exceptions.InvalidExpenseState; +import lld.billsharing.model.Contribution; +import lld.billsharing.model.Expense; +import lld.billsharing.model.ExpenseGroup; +import lld.billsharing.model.ExpenseStatus; +import lld.billsharing.model.User; +import lld.billsharing.model.UserShare; +import lld.billsharing.repository.ExpenseRepository; +import lld.billsharing.repository.UserRepository; + +public class UserService { + public User createUser(String emailId, String name, String phoneNumber) { + User user = new User(emailId, name, phoneNumber); + UserRepository.userHashMap.putIfAbsent(emailId, user); + return user; + } + + public void contributeToExpense(String expenseId, String emailId, + Contribution contribution) + throws InvalidExpenseState, ExpenseSettledException, ContributionExceededException { + Expense expense = ExpenseRepository.expenseMap.get(expenseId); + ExpenseGroup expenseGroup = expense.getExpenseGroup(); + if (expense.getExpenseStatus() == ExpenseStatus.CREATED) { + throw new InvalidExpenseState("Invalid expense State"); + } + if (expense.getExpenseStatus() == ExpenseStatus.SETTLED) { + throw new ExpenseSettledException("Expense is already settled."); + } + UserShare userShare = expenseGroup.getUserContributions().get(emailId); + if (contribution.getContributionValue() > userShare.getShare()) { + throw new ContributionExceededException( + String.format("User %s contribution %d exceeded the share %d", + emailId, contribution.getContributionValue(), userShare.getShare())); + } + userShare.getContributions().add(contribution); + } + + public void contributeToExpense(String expenseId, String emailId, String toEmailId, + Contribution contribution) + throws InvalidExpenseState, ExpenseSettledException, ContributionExceededException { + Expense expense = ExpenseRepository.expenseMap.get(expenseId); + ExpenseGroup expenseGroup = expense.getExpenseGroup(); + if (expense.getExpenseStatus() == ExpenseStatus.CREATED) { + throw new InvalidExpenseState("Invalid expense State"); + } + if (expense.getExpenseStatus() == ExpenseStatus.SETTLED) { + throw new ExpenseSettledException("Expense is already settled."); + } + UserShare userShare = expenseGroup.getUserContributions().get(emailId); + if (contribution.getContributionValue() > userShare.getShare()) { + throw new ContributionExceededException( + String.format("User %s contribution %d exceeded the share %d", + emailId, contribution.getContributionValue(), userShare.getShare())); + } + userShare.getContributions().add(contribution); + } +} diff --git a/src/main/java/lld/elevator/TestElevator.java b/src/main/java/lld/elevator/TestElevator.java new file mode 100644 index 0000000..f39b091 --- /dev/null +++ b/src/main/java/lld/elevator/TestElevator.java @@ -0,0 +1,413 @@ +package lld.elevator; + +import java.util.TreeSet; + +class Elevator { + private Direction currentDirection = Direction.UP; + private State currentState = State.IDLE; + private int currentFloor = 0; + + /** + * jobs which are being processed + */ + private TreeSet currentJobs = new TreeSet<>(); + /** + * up jobs which cannot be processed now so put in pending queue + */ + private TreeSet upPendingJobs = new TreeSet<>(); + /** + * down jobs which cannot be processed now so put in pending queue + */ + private TreeSet downPendingJobs = new TreeSet<>(); + + public void startElevator() { + System.out.println("The Elevator has started functioning"); + while (true) { + + if (checkIfJob()) { + + if (currentDirection == Direction.UP) { + Request request = currentJobs.pollFirst(); + processUpRequest(request); + if (currentJobs.isEmpty()) { + addPendingDownJobsToCurrentJobs(); + + } + + } + if (currentDirection == Direction.DOWN) { + Request request = currentJobs.pollLast(); + processDownRequest(request); + if (currentJobs.isEmpty()) { + addPendingUpJobsToCurrentJobs(); + } + + } + } + } + } + + public boolean checkIfJob() { + + return !currentJobs.isEmpty(); + + } + + private void processUpRequest(Request request) { + + int startFloor = currentFloor; + // The elevator is not on the floor where the person has requested it i.e. source floor. So first bring it there. + if (startFloor < request.getExternalRequest().getSourceFloor()) { + for (int i = startFloor; i <= request.getExternalRequest().getSourceFloor(); i++) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + System.out.println("We have reached floor -- " + i); + currentFloor = i; + } + } + // The elevator is now on the floor where the person has requested it i.e. source floor. User can enter and go to the destination floor. + System.out.println("Reached Source Floor--opening door"); + + startFloor = currentFloor; + + for (int i = startFloor + 1; i <= request.getInternalRequest().getDestinationFloor(); i++) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + System.out.println("We have reached floor -- " + i); + currentFloor = i; + if (checkIfNewJobCanBeProcessed(request)) { + break; + } + } + + } + + private void processDownRequest(Request request) { + + int startFloor = currentFloor; + if (startFloor < request.getExternalRequest().getSourceFloor()) { + for (int i = startFloor; i <= request.getExternalRequest().getSourceFloor(); i++) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + System.out.println("We have reached floor -- " + i); + currentFloor = i; + } + } + + System.out.println("Reached Source Floor--opening door"); + + startFloor = currentFloor; + + for (int i = startFloor - 1; i >= request.getInternalRequest().getDestinationFloor(); i--) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + System.out.println("We have reached floor -- " + i); + currentFloor = i; + if (checkIfNewJobCanBeProcessed(request)) { + break; + } + } + + } + + private boolean checkIfNewJobCanBeProcessed(Request currentRequest) { + if (checkIfJob()) { + if (currentDirection == Direction.UP) { + Request request = currentJobs.pollLast(); + if (request.getInternalRequest().getDestinationFloor() < currentRequest.getInternalRequest() + .getDestinationFloor()) { + currentJobs.add(request); + currentJobs.add(currentRequest); + return true; + } + currentJobs.add(request); + + } + + if (currentDirection == Direction.DOWN) { + Request request = currentJobs.pollFirst(); + if (request.getInternalRequest().getDestinationFloor() > currentRequest.getInternalRequest() + .getDestinationFloor()) { + currentJobs.add(request); + currentJobs.add(currentRequest); + return true; + } + currentJobs.add(request); + + } + + } + return false; + + } + + private void addPendingDownJobsToCurrentJobs() { + if (!downPendingJobs.isEmpty()) { + System.out.println("Pick a pending down job and execute it by putting in current job"); + currentJobs = downPendingJobs; + currentDirection = Direction.DOWN; + } else { + currentState = State.IDLE; + System.out.println("The elevator is in Idle state"); + } + + } + + private void addPendingUpJobsToCurrentJobs() { + if (!upPendingJobs.isEmpty()) { + System.out.println("Pick a pending up job and execute it by putting in current job"); + + currentJobs = upPendingJobs; + currentDirection = Direction.UP; + } else { + currentState = State.IDLE; + System.out.println("The elevator is in Idle state"); + + } + + } + + public void addJob(Request request) { + if (currentState == State.IDLE) { + currentState = State.MOVING; + currentDirection = request.getExternalRequest().getDirectionToGo(); + currentJobs.add(request); + } else if (currentState == State.MOVING) { + + if (request.getExternalRequest().getDirectionToGo() != currentDirection) { + addtoPendingJobs(request); + } else if (request.getExternalRequest().getDirectionToGo() == currentDirection) { + if (currentDirection == Direction.UP + && request.getInternalRequest().getDestinationFloor() < currentFloor) { + addtoPendingJobs(request); + } else if (currentDirection == Direction.DOWN + && request.getInternalRequest().getDestinationFloor() > currentFloor) { + addtoPendingJobs(request); + } else { + currentJobs.add(request); + } + + } + + } + + } + + public void addtoPendingJobs(Request request) { + if (request.getExternalRequest().getDirectionToGo() == Direction.UP) { + System.out.println("Add to pending up jobs"); + upPendingJobs.add(request); + } else { + System.out.println("Add to pending down jobs"); + downPendingJobs.add(request); + } + } + +} + +enum State { + + MOVING, STOPPED, IDLE + +} + +enum Direction { + + UP, DOWN + +} + +class Request implements Comparable { + private InternalRequest internalRequest; + private ExternalRequest externalRequest; + + public Request(InternalRequest internalRequest, ExternalRequest externalRequest) { + this.internalRequest = internalRequest; + this.externalRequest = externalRequest; + } + + public InternalRequest getInternalRequest() { + return internalRequest; + } + + public void setInternalRequest(InternalRequest internalRequest) { + this.internalRequest = internalRequest; + } + + public ExternalRequest getExternalRequest() { + return externalRequest; + } + + public void setExternalRequest(ExternalRequest externalRequest) { + this.externalRequest = externalRequest; + } + + @Override + public int compareTo(Request req) { + if (this.getInternalRequest().getDestinationFloor() == req.getInternalRequest().getDestinationFloor()) + return 0; + else if (this.getInternalRequest().getDestinationFloor() > req.getInternalRequest().getDestinationFloor()) + return 1; + else + return -1; + } + +} + +class ProcessJobWorker implements Runnable { + + private Elevator elevator; + + ProcessJobWorker(Elevator elevator) { + this.elevator = elevator; + } + + @Override + public void run() { + /** + * start the elevator + */ + elevator.startElevator(); + } + +} + +class AddJobWorker implements Runnable { + + private Elevator elevator; + private Request request; + + AddJobWorker(Elevator elevator, Request request) { + this.elevator = elevator; + this.request = request; + } + + @Override + public void run() { + + try { + Thread.sleep(200); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + elevator.addJob(request); + } + +} + +class ExternalRequest { + + private Direction directionToGo; + private int sourceFloor; + + public ExternalRequest(Direction directionToGo, int sourceFloor) { + this.directionToGo = directionToGo; + this.sourceFloor = sourceFloor; + } + + public Direction getDirectionToGo() { + return directionToGo; + } + + public void setDirectionToGo(Direction directionToGo) { + this.directionToGo = directionToGo; + } + + public int getSourceFloor() { + return sourceFloor; + } + + public void setSourceFloor(int sourceFloor) { + this.sourceFloor = sourceFloor; + } + + @Override + public String toString() { + return " The Elevator has been requested on floor - " + sourceFloor + " and the person wants go in the - " + + directionToGo; + } + +} + +class InternalRequest { + private int destinationFloor; + + public InternalRequest(int destinationFloor) { + this.destinationFloor = destinationFloor; + } + + public int getDestinationFloor() { + return destinationFloor; + } + + public void setDestinationFloor(int destinationFloor) { + this.destinationFloor = destinationFloor; + } + + @Override + public String toString() { + return "The destinationFloor is - " + destinationFloor; + } + +} + +public class TestElevator { + + public static void main(String args[]) { + + Elevator elevator = new Elevator(); + + /** + * Thread for starting the elevator + */ + ProcessJobWorker processJobWorker = new ProcessJobWorker(elevator); + Thread t2 = new Thread(processJobWorker); + t2.start(); + + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + + ExternalRequest er = new ExternalRequest(Direction.UP, 0); + + InternalRequest ir = new InternalRequest(5); + + Request request1 = new Request(ir, er); + + + /** + * Pass job to the elevator + */ + new Thread(new AddJobWorker(elevator, request1)).start(); + + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + + + } + +} \ No newline at end of file diff --git a/src/main/java/lld/vendingmachine/HasMoneyState.java b/src/main/java/lld/vendingmachine/HasMoneyState.java new file mode 100644 index 0000000..3d9596c --- /dev/null +++ b/src/main/java/lld/vendingmachine/HasMoneyState.java @@ -0,0 +1,34 @@ +package lld.vendingmachine; + +public class HasMoneyState implements VendingMachineState { + private VendingMachine vendingMachine; + + public HasMoneyState(VendingMachine vendingMachine) { this.vendingMachine = vendingMachine; } + + @Override + public void insertMoney() { + System.out.println("\tMoney is Inserted."); + } + + @Override + public void ejectMoney() { + System.out.println("\tRejecting Money."); + vendingMachine.setState(vendingMachine.getNoMoneyState()); + } + + @Override + public void selectProduct() { + System.out.println("\tItem is Selected."); + vendingMachine.setState(vendingMachine.getSoldState()); + } + + @Override + public void dispenseProduct() { + System.out.println("\tDispensing Product."); + } + + @Override + public String toString() { + return "\tMoney Accepted State, Waiting for Product Selection."; + } +} \ No newline at end of file diff --git a/src/main/java/lld/vendingmachine/Main.java b/src/main/java/lld/vendingmachine/Main.java new file mode 100644 index 0000000..f9ba696 --- /dev/null +++ b/src/main/java/lld/vendingmachine/Main.java @@ -0,0 +1,50 @@ +package lld.vendingmachine; + +public class Main { + public static void main(String[] args) { + System.out.println("State Design Pattern Vending Machine."); + System.out.println("Vending Machine activated by Machine States (HasMoney, NoMoney, Sold, SoldOut).\n"); + + VendingMachine vendingMachine = new VendingMachine(2); + System.out.println(vendingMachine); + System.out.println(); + + vendingMachine.insertMoney(); + System.out.println(vendingMachine); + System.out.println(); + + vendingMachine.selectProduct(); + System.out.println(vendingMachine); + System.out.println(); + + vendingMachine.dispenseProduct(); + System.out.println(vendingMachine); + System.out.println(); + + + vendingMachine.insertMoney(); + System.out.println(vendingMachine); + System.out.println(); + + vendingMachine.selectProduct(); + System.out.println(vendingMachine); + System.out.println(); + + vendingMachine.dispenseProduct(); + System.out.println(vendingMachine); + System.out.println(); + + + vendingMachine.insertMoney(); + System.out.println(vendingMachine); + System.out.println(); + + vendingMachine.selectProduct(); + System.out.println(vendingMachine); + System.out.println(); + + vendingMachine.dispenseProduct(); + System.out.println(vendingMachine); + System.out.println(); + } +} \ No newline at end of file diff --git a/src/main/java/lld/vendingmachine/NoMoneyState.java b/src/main/java/lld/vendingmachine/NoMoneyState.java new file mode 100644 index 0000000..8dbac65 --- /dev/null +++ b/src/main/java/lld/vendingmachine/NoMoneyState.java @@ -0,0 +1,35 @@ +package lld.vendingmachine; + +public class NoMoneyState implements VendingMachineState { + private VendingMachine vendingMachine; + + public NoMoneyState(VendingMachine vendingMachine) { this.vendingMachine = vendingMachine; } + + @Override + public void insertMoney() { + System.out.println("\tMoney is Inserted."); + vendingMachine.setState(vendingMachine.getHasMoneyState()); + } + + @Override + public void ejectMoney() { + System.out.println("\tNo Money."); + vendingMachine.setState(vendingMachine.getNoMoneyState()); + } + + @Override + public void selectProduct() { + System.out.println("\tSelection Made. No Money."); + + } + + @Override + public void dispenseProduct() { + System.out.println("\tNo Disperse before Money Insertion."); + } + + @Override + public String toString() { + return "\tNo Money State, Waiting for Money."; + } +} \ No newline at end of file diff --git a/src/main/java/lld/vendingmachine/SoldOutState.java b/src/main/java/lld/vendingmachine/SoldOutState.java new file mode 100644 index 0000000..496afcc --- /dev/null +++ b/src/main/java/lld/vendingmachine/SoldOutState.java @@ -0,0 +1,33 @@ +package lld.vendingmachine; + +public class SoldOutState implements VendingMachineState { + @SuppressWarnings("unused") + private VendingMachine vendingMachine; + + public SoldOutState(VendingMachine vendingMachine) { this.vendingMachine = vendingMachine; } + + @Override + public void insertMoney() { + System.out.println("\tProducts Sold Out"); + } + + @Override + public void ejectMoney() { + System.out.println("\tMoney is Rejected Back to Customer."); + } + + @Override + public void selectProduct() { + System.out.println("\tProduct Not Available."); + } + + @Override + public void dispenseProduct() { + System.out.println("\tProduct Sold Out."); + } + + @Override + public String toString() { + return "\tProduct Sold Out State."; + } +} \ No newline at end of file diff --git a/src/main/java/lld/vendingmachine/SoldState.java b/src/main/java/lld/vendingmachine/SoldState.java new file mode 100644 index 0000000..fc8bb61 --- /dev/null +++ b/src/main/java/lld/vendingmachine/SoldState.java @@ -0,0 +1,43 @@ +package lld.vendingmachine; + +public class SoldState implements VendingMachineState { + private VendingMachine vendingMachine; + + public SoldState(VendingMachine vendingMachine) { this.vendingMachine = vendingMachine; } + + @Override + public void insertMoney() { + System.out.println("\tProduct is Ready."); + } + + @Override + public void ejectMoney() { + System.out.println("\tProduct is is Already Coming Out."); + + } + + @Override + public void selectProduct() { + System.out.println("\tProduct is Already Selected."); + } + + @Override + public void dispenseProduct() { + + if(vendingMachine.getNumberOfProducts() > 0) { + System.out.println("\tProduct is Being Dispensed."); + vendingMachine.setNumberOfProducts(vendingMachine.getNumberOfProducts()-1); + vendingMachine.setState(vendingMachine.getNoMoneyState()); + } + else { + System.out.println("\tOut of Products."); + vendingMachine.setState(vendingMachine.getSoldOutState()); + vendingMachine.ejectMoney(); + } + } + + @Override + public String toString() { + return "\tDispensing Product State."; + } +} \ No newline at end of file diff --git a/src/main/java/lld/vendingmachine/State.java b/src/main/java/lld/vendingmachine/State.java new file mode 100644 index 0000000..863da44 --- /dev/null +++ b/src/main/java/lld/vendingmachine/State.java @@ -0,0 +1,8 @@ +package lld.vendingmachine; + +public interface State { + public void collectCash(int cash); + public void dispenseChange(String productCode); + public void dispenseItem(String productCode); + public void cancelTransaction(); +} \ No newline at end of file diff --git a/src/main/java/lld/vendingmachine/VendingMachine.java b/src/main/java/lld/vendingmachine/VendingMachine.java new file mode 100644 index 0000000..e600974 --- /dev/null +++ b/src/main/java/lld/vendingmachine/VendingMachine.java @@ -0,0 +1,87 @@ +package lld.vendingmachine; + +public class VendingMachine { + private VendingMachineState hasMoneyState; + private VendingMachineState noMoneyState; + private VendingMachineState soldOutState; + private VendingMachineState soldState; + private VendingMachineState machineState; + + private int numberOfProducts; + + //Vending Machine Constructor: + public VendingMachine(int numberOfProducts) { + this.numberOfProducts = numberOfProducts; + hasMoneyState = new HasMoneyState(this); + noMoneyState = new NoMoneyState(this); + soldOutState = new SoldOutState(this); + soldState = new SoldState(this); + if (numberOfProducts > 0) { + machineState = noMoneyState; + } + } + + //Getters and Setters: + public int getNumberOfProducts() { + return numberOfProducts; + } + + public void setNumberOfProducts(int numberOfProducts) { + this.numberOfProducts = numberOfProducts; + } + + public VendingMachineState getHasMoneyState() { + return hasMoneyState; + } + + public VendingMachineState getNoMoneyState() { + return noMoneyState; + } + + public VendingMachineState getSoldOutState() { + return soldOutState; + } + + public VendingMachineState getSoldState() { + return soldState; + } + + public VendingMachineState getMachineState() { + return machineState; + } + + public void setState(VendingMachineState state) { + machineState = state; + } + + //Vending Machine Actions: + public void insertMoney() { + machineState.insertMoney(); + } + + public void ejectMoney() { + machineState.ejectMoney(); + } + + public void selectProduct() { + machineState.selectProduct(); + } + + public void dispenseProduct() { + machineState.dispenseProduct(); + } + + @Override + public String toString() { + StringBuffer result = new StringBuffer(); + result.append("Welcome to Vending Machine.\n"); + result.append("Inventory:\t" + numberOfProducts + " product"); + if (numberOfProducts != 1) { + result.append("s.\n"); + } else { + result.append(".\n"); + } + result.append("Vending Machine State:\t" + machineState + "\n"); + return result.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/lld/vendingmachine/VendingMachineState.java b/src/main/java/lld/vendingmachine/VendingMachineState.java new file mode 100644 index 0000000..487518e --- /dev/null +++ b/src/main/java/lld/vendingmachine/VendingMachineState.java @@ -0,0 +1,11 @@ +package lld.vendingmachine; + +public interface VendingMachineState { + public void insertMoney(); + + public void ejectMoney(); + + public void selectProduct(); + + public void dispenseProduct(); +} \ No newline at end of file diff --git a/src/main/java/machinecoding/snakesandladder/DiceService.java b/src/main/java/machinecoding/snakesandladder/DiceService.java new file mode 100644 index 0000000..62016cf --- /dev/null +++ b/src/main/java/machinecoding/snakesandladder/DiceService.java @@ -0,0 +1,9 @@ +package machinecoding.snakesandladder; + +import java.util.Random; + +public class DiceService { + public static int roll() { + return new Random().nextInt(6) + 1; // The game will have a six sided dice numbered from 1 to 6 and will always give a random number on rolling it. + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/snakesandladder/Driver.java b/src/main/java/machinecoding/snakesandladder/Driver.java new file mode 100644 index 0000000..4d5cac5 --- /dev/null +++ b/src/main/java/machinecoding/snakesandladder/Driver.java @@ -0,0 +1,36 @@ +package machinecoding.snakesandladder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class Driver { + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + + int noOfSnakes = scanner.nextInt(); + List snakes = new ArrayList(); + for (int i = 0; i < noOfSnakes; i++) { + snakes.add(new Snake(scanner.nextInt(), scanner.nextInt())); + } + + int noOfLadders = scanner.nextInt(); + List ladders = new ArrayList(); + for (int i = 0; i < noOfLadders; i++) { + ladders.add(new Ladder(scanner.nextInt(), scanner.nextInt())); + } + + int noOfPlayers = scanner.nextInt(); + List players = new ArrayList(); + for (int i = 0; i < noOfPlayers; i++) { + players.add(new Player(scanner.next())); + } + + SnakeAndLadderService snakeAndLadderService = new SnakeAndLadderService(); + snakeAndLadderService.setPlayers(players); + snakeAndLadderService.setSnakes(snakes); + snakeAndLadderService.setLadders(ladders); + + snakeAndLadderService.startGame(); + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/snakesandladder/Ladder.java b/src/main/java/machinecoding/snakesandladder/Ladder.java new file mode 100644 index 0000000..e5dc400 --- /dev/null +++ b/src/main/java/machinecoding/snakesandladder/Ladder.java @@ -0,0 +1,20 @@ +package machinecoding.snakesandladder; + +public class Ladder { + // Each ladder will have its start position at some number and end position at a larger number. + private int start; + private int end; + + public Ladder(int start, int end) { + this.start = start; + this.end = end; + } + + public int getStart() { + return start; + } + + public int getEnd() { + return end; + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/snakesandladder/Player.java b/src/main/java/machinecoding/snakesandladder/Player.java new file mode 100644 index 0000000..11f8f31 --- /dev/null +++ b/src/main/java/machinecoding/snakesandladder/Player.java @@ -0,0 +1,21 @@ +package machinecoding.snakesandladder; + +import java.util.UUID; + +public class Player { + private String name; + private String id; + + public Player(String name) { + this.name = name; + this.id = UUID.randomUUID().toString(); + } + + public String getName() { + return name; + } + + public String getId() { + return id; + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/snakesandladder/Snake.java b/src/main/java/machinecoding/snakesandladder/Snake.java new file mode 100644 index 0000000..ddbd515 --- /dev/null +++ b/src/main/java/machinecoding/snakesandladder/Snake.java @@ -0,0 +1,20 @@ +package machinecoding.snakesandladder; + +public class Snake { + // Each snake will have its head at some number and its tail at a smaller number. + private int start; + private int end; + + public Snake(int start, int end) { + this.start = start; + this.end = end; + } + + public int getStart() { + return start; + } + + public int getEnd() { + return end; + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/snakesandladder/SnakeAndLadderBoard.java b/src/main/java/machinecoding/snakesandladder/SnakeAndLadderBoard.java new file mode 100644 index 0000000..b0fdf7f --- /dev/null +++ b/src/main/java/machinecoding/snakesandladder/SnakeAndLadderBoard.java @@ -0,0 +1,48 @@ +package machinecoding.snakesandladder; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SnakeAndLadderBoard { + private int size; + private List snakes; // The board also contains some snakes and ladders. + private List ladders; + private Map playerPieces; + + public SnakeAndLadderBoard(int size) { + this.size = size; + this.snakes = new ArrayList(); + this.ladders = new ArrayList(); + this.playerPieces = new HashMap(); + } + + public int getSize() { + return size; + } + + public List getSnakes() { + return snakes; + } + + public void setSnakes(List snakes) { + this.snakes = snakes; + } + + public List getLadders() { + return ladders; + } + + public void setLadders(List ladders) { + this.ladders = ladders; + } + + public Map getPlayerPieces() { + return playerPieces; + } + + public void setPlayerPieces(Map playerPieces) { + this.playerPieces = playerPieces; + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/snakesandladder/SnakeAndLadderService.java b/src/main/java/machinecoding/snakesandladder/SnakeAndLadderService.java new file mode 100644 index 0000000..ec54192 --- /dev/null +++ b/src/main/java/machinecoding/snakesandladder/SnakeAndLadderService.java @@ -0,0 +1,148 @@ +package machinecoding.snakesandladder; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; + +public class SnakeAndLadderService { + private SnakeAndLadderBoard snakeAndLadderBoard; + private int initialNumberOfPlayers; + private Queue players; // Comment: Keeping players in game service as they are specific to this game and not the board. Keeping pieces in the board instead. + private boolean isGameCompleted; + + private int noOfDices; //Optional Rule 1 + private boolean shouldGameContinueTillLastPlayer; //Optional Rule 3 + private boolean shouldAllowMultipleDiceRollOnSix; //Optional Rule 4 + + private static final int DEFAULT_BOARD_SIZE = 100; //The board will have 100 cells numbered from 1 to 100. + private static final int DEFAULT_NO_OF_DICES = 1; + + public SnakeAndLadderService(int boardSize) { + this.snakeAndLadderBoard = new SnakeAndLadderBoard(boardSize); //Optional Rule 2 + this.players = new LinkedList<>(); + this.noOfDices = SnakeAndLadderService.DEFAULT_NO_OF_DICES; + } + + public SnakeAndLadderService() { + this(SnakeAndLadderService.DEFAULT_BOARD_SIZE); + } + + /** + * ====Setters for making the game more extensible==== + */ + + public void setNoOfDices(int noOfDices) { + this.noOfDices = noOfDices; + } + + public void setShouldGameContinueTillLastPlayer(boolean shouldGameContinueTillLastPlayer) { + this.shouldGameContinueTillLastPlayer = shouldGameContinueTillLastPlayer; + } + + public void setShouldAllowMultipleDiceRollOnSix(boolean shouldAllowMultipleDiceRollOnSix) { + this.shouldAllowMultipleDiceRollOnSix = shouldAllowMultipleDiceRollOnSix; + } + + /** + * ==================Initialize board================== + */ + + public void setPlayers(List players) { + this.players = new LinkedList(); + this.initialNumberOfPlayers = players.size(); + Map playerPieces = new HashMap(); + for (Player player : players) { + this.players.add(player); + playerPieces.put(player.getId(), 0); //Each player has a piece which is initially kept outside the board (i.e., at position 0). + } + snakeAndLadderBoard.setPlayerPieces(playerPieces); // Add pieces to board + } + + public void setSnakes(List snakes) { + snakeAndLadderBoard.setSnakes(snakes); // Add snakes to board + } + + public void setLadders(List ladders) { + snakeAndLadderBoard.setLadders(ladders); // Add ladders to board + } + + /** + * ==========Core business logic for the game========== + */ + + private int getNewPositionAfterGoingThroughSnakesAndLadders(int newPosition) { + int previousPosition; + + do { + previousPosition = newPosition; + for (Snake snake : snakeAndLadderBoard.getSnakes()) { + if (snake.getStart() == newPosition) { + newPosition = snake.getEnd(); // Whenever a piece ends up at a position with the head of the snake, the piece should go down to the position of the tail of that snake. + } + } + + for (Ladder ladder : snakeAndLadderBoard.getLadders()) { + if (ladder.getStart() == newPosition) { + newPosition = ladder.getEnd(); // Whenever a piece ends up at a position with the start of the ladder, the piece should go up to the position of the end of that ladder. + } + } + } while (newPosition != previousPosition); // There could be another snake/ladder at the tail of the snake or the end position of the ladder and the piece should go up/down accordingly. + return newPosition; + } + + private void movePlayer(Player player, int positions) { + int oldPosition = snakeAndLadderBoard.getPlayerPieces().get(player.getId()); + int newPosition = oldPosition + positions; // Based on the dice value, the player moves their piece forward that number of cells. + + int boardSize = snakeAndLadderBoard.getSize(); + + // Can modify this logic to handle side case when there are multiple dices (Optional requirements) + if (newPosition > boardSize) { + newPosition = oldPosition; // After the dice roll, if a piece is supposed to move outside position 100, it does not move. + } else { + newPosition = getNewPositionAfterGoingThroughSnakesAndLadders(newPosition); + } + + snakeAndLadderBoard.getPlayerPieces().put(player.getId(), newPosition); + + System.out.println(player.getName() + " rolled a " + positions + " and moved from " + oldPosition +" to " + newPosition); + } + + private int getTotalValueAfterDiceRolls() { + // Can use noOfDices and setShouldAllowMultipleDiceRollOnSix here to get total value (Optional requirements) + return DiceService.roll(); + } + + private boolean hasPlayerWon(Player player) { + // Can change the logic a bit to handle special cases when there are more than one dice (Optional requirements) + int playerPosition = snakeAndLadderBoard.getPlayerPieces().get(player.getId()); + int winningPosition = snakeAndLadderBoard.getSize(); + return playerPosition == winningPosition; // A player wins if it exactly reaches the position 100 and the game ends there. + } + + private boolean isGameCompleted() { + // Can use shouldGameContinueTillLastPlayer to change the logic of determining if game is completed (Optional requirements) + int currentNumberOfPlayers = players.size(); + return currentNumberOfPlayers < initialNumberOfPlayers; + } + + public void startGame() { + while (!isGameCompleted()) { + int totalDiceValue = getTotalValueAfterDiceRolls(); // Each player rolls the dice when their turn comes. + Player currentPlayer = players.poll(); + movePlayer(currentPlayer, totalDiceValue); + if (hasPlayerWon(currentPlayer)) { + System.out.println(currentPlayer.getName() + " wins the game"); + snakeAndLadderBoard.getPlayerPieces().remove(currentPlayer.getId()); + } else { + players.add(currentPlayer); + } + } + } + + /** + * ======================================================= + */ +} \ No newline at end of file diff --git a/src/main/java/machinecoding/splitwise/Driver.java b/src/main/java/machinecoding/splitwise/Driver.java new file mode 100644 index 0000000..0bf0206 --- /dev/null +++ b/src/main/java/machinecoding/splitwise/Driver.java @@ -0,0 +1,64 @@ +package machinecoding.splitwise; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class Driver { + public static void main(String[] args) { + ExpenseManager expenseManager = new ExpenseManager(); + + expenseManager.addUser(new User("u1", "User1", "gaurav@workat.tech", "9876543210")); + expenseManager.addUser(new User("u2", "User2", "sagar@workat.tech", "9876543210")); + expenseManager.addUser(new User("u3", "User3", "hi@workat.tech", "9876543210")); + expenseManager.addUser(new User("u4", "User4", "mock-interviews@workat.tech", "9876543210")); + + Scanner scanner = new Scanner(System.in); + while (true) { + String command = scanner.nextLine(); + String[] commands = command.split(" "); + String commandType = commands[0]; + + switch (commandType) { + case "SHOW": + if (commands.length == 1) { + expenseManager.showBalances(); + } else { + expenseManager.showBalance(commands[1]); + } + break; + case "EXPENSE": + //EXPENSE + String paidBy = commands[1]; + Double amount = Double.parseDouble(commands[2]); + int noOfUsers = Integer.parseInt(commands[3]); + String expenseType = commands[4 + noOfUsers]; + List splits = new ArrayList<>(); + switch (expenseType) { + case "EQUAL": + for (int i = 0; i < noOfUsers; i++) { + splits.add(new EqualSplit(expenseManager.userMap.get(commands[4 + i]))); + } + expenseManager.addExpense(ExpenseType.EQUAL, amount, paidBy, splits, null); + break; + case "EXACT": + for (int i = 0; i < noOfUsers; i++) { + splits.add(new ExactSplit(expenseManager.userMap.get(commands[4 + i]), Double.parseDouble(commands[5 + noOfUsers + i]))); + } + expenseManager.addExpense(ExpenseType.EXACT, amount, paidBy, splits, null); + break; + case "PERCENT": + for (int i = 0; i < noOfUsers; i++) { + splits.add(new PercentSplit(expenseManager.userMap.get(commands[4 + i]), Double.parseDouble(commands[5 + noOfUsers + i]))); + } + expenseManager.addExpense(ExpenseType.PERCENT, amount, paidBy, splits, null); + break; + } + break; + + default: + break; + } + } + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/splitwise/EqualExpense.java b/src/main/java/machinecoding/splitwise/EqualExpense.java new file mode 100644 index 0000000..05c1339 --- /dev/null +++ b/src/main/java/machinecoding/splitwise/EqualExpense.java @@ -0,0 +1,20 @@ +package machinecoding.splitwise; + +import java.util.List; + +public class EqualExpense extends Expense { + public EqualExpense(double amount, User paidBy, List splits, ExpenseMetadata expenseMetadata) { + super(amount, paidBy, splits, expenseMetadata); + } + + @Override + public boolean validate() { + for (Split split : getSplits()) { + if (!(split instanceof EqualSplit)) { + return false; + } + } + + return true; + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/splitwise/EqualSplit.java b/src/main/java/machinecoding/splitwise/EqualSplit.java new file mode 100644 index 0000000..e60b8e2 --- /dev/null +++ b/src/main/java/machinecoding/splitwise/EqualSplit.java @@ -0,0 +1,8 @@ +package machinecoding.splitwise; + +public class EqualSplit extends Split { + + public EqualSplit(User user) { + super(user); + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/splitwise/ExactExpense.java b/src/main/java/machinecoding/splitwise/ExactExpense.java new file mode 100644 index 0000000..dd92066 --- /dev/null +++ b/src/main/java/machinecoding/splitwise/ExactExpense.java @@ -0,0 +1,31 @@ +package machinecoding.splitwise; + +import java.util.List; + +public class ExactExpense extends Expense { + public ExactExpense(double amount, User paidBy, List splits, ExpenseMetadata expenseMetadata) { + super(amount, paidBy, splits, expenseMetadata); + } + + @Override + public boolean validate() { + for (Split split : getSplits()) { + if (!(split instanceof ExactSplit)) { + return false; + } + } + + double totalAmount = getAmount(); + double sumSplitAmount = 0; + for (Split split : getSplits()) { + ExactSplit exactSplit = (ExactSplit) split; + sumSplitAmount += exactSplit.getAmount(); + } + + if (totalAmount != sumSplitAmount) { + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/splitwise/ExactSplit.java b/src/main/java/machinecoding/splitwise/ExactSplit.java new file mode 100644 index 0000000..60b20c0 --- /dev/null +++ b/src/main/java/machinecoding/splitwise/ExactSplit.java @@ -0,0 +1,9 @@ +package machinecoding.splitwise; + +public class ExactSplit extends Split { + + public ExactSplit(User user, double amount) { + super(user); + this.amount = amount; + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/splitwise/Expense.java b/src/main/java/machinecoding/splitwise/Expense.java new file mode 100644 index 0000000..34e10e2 --- /dev/null +++ b/src/main/java/machinecoding/splitwise/Expense.java @@ -0,0 +1,60 @@ +package machinecoding.splitwise; + +import java.util.List; + +public abstract class Expense { + private String id; + private double amount; + private User paidBy; + private List splits; + private ExpenseMetadata metadata; + + public Expense(double amount, User paidBy, List splits, ExpenseMetadata metadata) { + this.amount = amount; + this.paidBy = paidBy; + this.splits = splits; + this.metadata = metadata; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public double getAmount() { + return amount; + } + + public void setAmount(double amount) { + this.amount = amount; + } + + public User getPaidBy() { + return paidBy; + } + + public void setPaidBy(User paidBy) { + this.paidBy = paidBy; + } + + public List getSplits() { + return splits; + } + + public void setSplits(List splits) { + this.splits = splits; + } + + public ExpenseMetadata getMetadata() { + return metadata; + } + + public void setMetadata(ExpenseMetadata metadata) { + this.metadata = metadata; + } + + public abstract boolean validate(); +} \ No newline at end of file diff --git a/src/main/java/machinecoding/splitwise/ExpenseManager.java b/src/main/java/machinecoding/splitwise/ExpenseManager.java new file mode 100644 index 0000000..c729e33 --- /dev/null +++ b/src/main/java/machinecoding/splitwise/ExpenseManager.java @@ -0,0 +1,78 @@ +package machinecoding.splitwise; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ExpenseManager { + List expenses; + Map userMap; + Map> balanceSheet; + + public ExpenseManager() { + expenses = new ArrayList<>(); + userMap = new HashMap<>(); + balanceSheet = new HashMap<>(); + } + + public void addUser(User user) { + userMap.put(user.getId(), user); + balanceSheet.put(user.getId(), new HashMap<>()); + } + + public void addExpense(ExpenseType expenseType, double amount, String paidBy, List splits, ExpenseMetadata expenseMetadata) { + Expense expense = ExpenseService.createExpense(expenseType, amount, userMap.get(paidBy), splits, expenseMetadata); + expenses.add(expense); + for (Split split : expense.getSplits()) { + String paidTo = split.getUser().getId(); + Map balances = balanceSheet.get(paidBy); + balances.putIfAbsent(paidTo, 0.0); + balances.put(paidTo, balances.get(paidTo) + split.getAmount()); + + balances = balanceSheet.get(paidTo); + balances.putIfAbsent(paidBy, 0.0); + balances.put(paidBy, balances.get(paidBy) - split.getAmount()); + } + } + + public void showBalance(String userId) { + boolean isEmpty = true; + for (Map.Entry userBalance : balanceSheet.get(userId).entrySet()) { + if (userBalance.getValue() != 0) { + isEmpty = false; + printBalance(userId, userBalance.getKey(), userBalance.getValue()); + } + } + + if (isEmpty) { + System.out.println("No balances"); + } + } + + public void showBalances() { + boolean isEmpty = true; + for (Map.Entry> allBalances : balanceSheet.entrySet()) { + for (Map.Entry userBalance : allBalances.getValue().entrySet()) { + if (userBalance.getValue() > 0) { + isEmpty = false; + printBalance(allBalances.getKey(), userBalance.getKey(), userBalance.getValue()); + } + } + } + + if (isEmpty) { + System.out.println("No balances"); + } + } + + private void printBalance(String user1, String user2, double amount) { + String user1Name = userMap.get(user1).getName(); + String user2Name = userMap.get(user2).getName(); + if (amount < 0) { + System.out.println(user1Name + " owes " + user2Name + ": " + Math.abs(amount)); + } else if (amount > 0) { + System.out.println(user2Name + " owes " + user1Name + ": " + Math.abs(amount)); + } + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/splitwise/ExpenseMetadata.java b/src/main/java/machinecoding/splitwise/ExpenseMetadata.java new file mode 100644 index 0000000..29ba868 --- /dev/null +++ b/src/main/java/machinecoding/splitwise/ExpenseMetadata.java @@ -0,0 +1,37 @@ +package machinecoding.splitwise; + +public class ExpenseMetadata { + private String name; + private String imgUrl; + private String notes; + + public ExpenseMetadata(String name, String imgUrl, String notes) { + this.name = name; + this.imgUrl = imgUrl; + this.notes = notes; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getImgUrl() { + return imgUrl; + } + + public void setImgUrl(String imgUrl) { + this.imgUrl = imgUrl; + } + + public String getNotes() { + return notes; + } + + public void setNotes(String notes) { + this.notes = notes; + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/splitwise/ExpenseService.java b/src/main/java/machinecoding/splitwise/ExpenseService.java new file mode 100644 index 0000000..79c75ba --- /dev/null +++ b/src/main/java/machinecoding/splitwise/ExpenseService.java @@ -0,0 +1,28 @@ +package machinecoding.splitwise; + +import java.util.List; + +public class ExpenseService { + public static Expense createExpense(ExpenseType expenseType, double amount, User paidBy, List splits, ExpenseMetadata expenseMetadata) { + switch (expenseType) { + case EXACT: + return new ExactExpense(amount, paidBy, splits, expenseMetadata); + case PERCENT: + for (Split split : splits) { + PercentSplit percentSplit = (PercentSplit) split; + split.setAmount((amount*percentSplit.getPercent())/100.0); + } + return new PercentExpense(amount, paidBy, splits, expenseMetadata); + case EQUAL: + int totalSplits = splits.size(); + double splitAmount = ((double) Math.round(amount*100/totalSplits))/100.0; + for (Split split : splits) { + split.setAmount(splitAmount); + } + splits.get(0).setAmount(splitAmount + (amount - splitAmount*totalSplits)); + return new EqualExpense(amount, paidBy, splits, expenseMetadata); + default: + return null; + } + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/splitwise/ExpenseType.java b/src/main/java/machinecoding/splitwise/ExpenseType.java new file mode 100644 index 0000000..837bbc0 --- /dev/null +++ b/src/main/java/machinecoding/splitwise/ExpenseType.java @@ -0,0 +1,7 @@ +package machinecoding.splitwise; + +public enum ExpenseType { + EQUAL, + EXACT, + PERCENT +} \ No newline at end of file diff --git a/src/main/java/machinecoding/splitwise/PercentExpense.java b/src/main/java/machinecoding/splitwise/PercentExpense.java new file mode 100644 index 0000000..f2e1012 --- /dev/null +++ b/src/main/java/machinecoding/splitwise/PercentExpense.java @@ -0,0 +1,27 @@ +package machinecoding.splitwise; + +import java.util.List; + +public class PercentExpense extends Expense { + public PercentExpense(double amount, User paidBy, List splits, ExpenseMetadata expenseMetadata) { + super(amount, paidBy, splits, expenseMetadata); + } + + @Override + public boolean validate() { + for (Split split : getSplits()) { + if (!(split instanceof PercentSplit)) { + return false; + } + } + + double totalPercent = 100; + double sumSplitPercent = 0; + for (Split split : getSplits()) { + PercentSplit exactSplit = (PercentSplit) split; + sumSplitPercent += exactSplit.getPercent(); + } + + return totalPercent == sumSplitPercent; + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/splitwise/PercentSplit.java b/src/main/java/machinecoding/splitwise/PercentSplit.java new file mode 100644 index 0000000..da65eb2 --- /dev/null +++ b/src/main/java/machinecoding/splitwise/PercentSplit.java @@ -0,0 +1,18 @@ +package machinecoding.splitwise; + +public class PercentSplit extends Split { + double percent; + + public PercentSplit(User user, double percent) { + super(user); + this.percent = percent; + } + + public double getPercent() { + return percent; + } + + public void setPercent(double percent) { + this.percent = percent; + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/splitwise/Split.java b/src/main/java/machinecoding/splitwise/Split.java new file mode 100644 index 0000000..239d5c4 --- /dev/null +++ b/src/main/java/machinecoding/splitwise/Split.java @@ -0,0 +1,26 @@ +package machinecoding.splitwise; + +public abstract class Split { + private User user; + double amount; + + public Split(User user) { + this.user = user; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public double getAmount() { + return amount; + } + + public void setAmount(double amount) { + this.amount = amount; + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/splitwise/User.java b/src/main/java/machinecoding/splitwise/User.java new file mode 100644 index 0000000..6c28510 --- /dev/null +++ b/src/main/java/machinecoding/splitwise/User.java @@ -0,0 +1,47 @@ +package machinecoding.splitwise; + +public class User { + private String id; + private String name; + private String email; + private String phone; + + public User(String id, String name, String email, String phone) { + this.id = id; + this.name = name; + this.email = email; + this.phone = phone; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } +} \ No newline at end of file diff --git a/src/main/java/machinecoding/uditagarwal/chess/Main.java b/src/main/java/machinecoding/uditagarwal/chess/Main.java new file mode 100644 index 0000000..e6aa31c --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/Main.java @@ -0,0 +1,8 @@ +package machinecoding.uditagarwal.chess; + +public class Main { + + public static void main(String args[]) { + + } +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/conditions/MoveBaseCondition.java b/src/main/java/machinecoding/uditagarwal/chess/conditions/MoveBaseCondition.java new file mode 100644 index 0000000..156a2e7 --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/conditions/MoveBaseCondition.java @@ -0,0 +1,12 @@ +package machinecoding.uditagarwal.chess.conditions; + + +import machinecoding.uditagarwal.chess.model.Piece; + +/** + * It provides the base condition for a piece to make a move. The piece would only be allowed to move from its current + * position if the condition fulfills. + */ +public interface MoveBaseCondition { + boolean isBaseConditionFullfilled(Piece piece); +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/conditions/MoveBaseConditionFirstMove.java b/src/main/java/machinecoding/uditagarwal/chess/conditions/MoveBaseConditionFirstMove.java new file mode 100644 index 0000000..c93e854 --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/conditions/MoveBaseConditionFirstMove.java @@ -0,0 +1,14 @@ +package machinecoding.uditagarwal.chess.conditions; + + +import machinecoding.uditagarwal.chess.model.Piece; + +/** + * This condition allows a move only if cell is making a move from its initial position. That is first move ever. + */ +public class MoveBaseConditionFirstMove implements MoveBaseCondition { + + public boolean isBaseConditionFullfilled(Piece piece) { + return piece.getNumMoves() == 0; + } +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/conditions/NoMoveBaseCondition.java b/src/main/java/machinecoding/uditagarwal/chess/conditions/NoMoveBaseCondition.java new file mode 100644 index 0000000..2c06b64 --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/conditions/NoMoveBaseCondition.java @@ -0,0 +1,13 @@ +package machinecoding.uditagarwal.chess.conditions; + + +import machinecoding.uditagarwal.chess.model.Piece; + +/** + * Helper implementation to use when there is no associated base condition with a move. + */ +public class NoMoveBaseCondition implements MoveBaseCondition { + public boolean isBaseConditionFullfilled(Piece piece) { + return true; + } +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceCellOccupyBlocker.java b/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceCellOccupyBlocker.java new file mode 100644 index 0000000..605759e --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceCellOccupyBlocker.java @@ -0,0 +1,15 @@ +package machinecoding.uditagarwal.chess.conditions; + + +import machinecoding.uditagarwal.chess.model.Board; +import machinecoding.uditagarwal.chess.model.Cell; +import machinecoding.uditagarwal.chess.model.Piece; +import machinecoding.uditagarwal.chess.model.Player; + +/** + * This check tells whether a piece can occupy a given cell in the board or not. + */ +public interface PieceCellOccupyBlocker { + + boolean isCellNonOccupiableForPiece(Cell cell, Piece piece, Board board, Player player); +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceCellOccupyBlockerFactory.java b/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceCellOccupyBlockerFactory.java new file mode 100644 index 0000000..2a0f3be --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceCellOccupyBlockerFactory.java @@ -0,0 +1,22 @@ +package machinecoding.uditagarwal.chess.conditions; + + +import java.util.List; + +/** + * Factory class to give cell occupy blockers for different scenarios. + */ +public class PieceCellOccupyBlockerFactory { + + public static PieceCellOccupyBlocker defaultBaseBlocker() { + return new PieceCellOccupyBlockerSelfPiece(); + } + + public static List defaultAdditionalBlockers() { + return List.of(new PieceCellOccupyBlockerKingCheck()); + } + + public static List kingCheckEvaluationBlockers() { + return List.of(); + } +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceCellOccupyBlockerKingCheck.java b/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceCellOccupyBlockerKingCheck.java new file mode 100644 index 0000000..5d5a630 --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceCellOccupyBlockerKingCheck.java @@ -0,0 +1,22 @@ +package machinecoding.uditagarwal.chess.conditions; + + +import machinecoding.uditagarwal.chess.model.Board; +import machinecoding.uditagarwal.chess.model.Cell; +import machinecoding.uditagarwal.chess.model.Piece; +import machinecoding.uditagarwal.chess.model.Player; + +/** + * This tells whether making piece move to a cell will attract check for king. + */ +public class PieceCellOccupyBlockerKingCheck implements PieceCellOccupyBlocker { + + @Override + public boolean isCellNonOccupiableForPiece(final Cell cell, final Piece piece, final Board board, Player player) { + Cell pieceOriginalCell = piece.getCurrentCell(); + piece.setCurrentCell(cell); + boolean playerGettingCheckByMove = board.isPlayerOnCheck(player); + piece.setCurrentCell(pieceOriginalCell); + return playerGettingCheckByMove; + } +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceCellOccupyBlockerSelfPiece.java b/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceCellOccupyBlockerSelfPiece.java new file mode 100644 index 0000000..6b78167 --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceCellOccupyBlockerSelfPiece.java @@ -0,0 +1,21 @@ +package machinecoding.uditagarwal.chess.conditions; + + +import machinecoding.uditagarwal.chess.model.Board; +import machinecoding.uditagarwal.chess.model.Cell; +import machinecoding.uditagarwal.chess.model.Piece; +import machinecoding.uditagarwal.chess.model.Player; + +/** + * This tells that a cell cannot occupy a cell if that cell already has any piece from the same player. + */ +public class PieceCellOccupyBlockerSelfPiece implements PieceCellOccupyBlocker { + + @Override + public boolean isCellNonOccupiableForPiece(Cell cell, Piece piece, Board board, Player player) { + if (cell.isFree()) { + return false; + } + return cell.getCurrentPiece().getColor() == piece.getColor(); + } +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceMoveFurtherCondition.java b/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceMoveFurtherCondition.java new file mode 100644 index 0000000..6a53e70 --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceMoveFurtherCondition.java @@ -0,0 +1,14 @@ +package machinecoding.uditagarwal.chess.conditions; + + +import machinecoding.uditagarwal.chess.model.Board; +import machinecoding.uditagarwal.chess.model.Cell; +import machinecoding.uditagarwal.chess.model.Piece; + +/** + * Condition interface to tell whether a piece can further move from a cell. + */ +public interface PieceMoveFurtherCondition { + + boolean canPieceMoveFurtherFromCell(Piece piece, Cell cell, Board board); +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceMoveFurtherConditionDefault.java b/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceMoveFurtherConditionDefault.java new file mode 100644 index 0000000..1d4686e --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/conditions/PieceMoveFurtherConditionDefault.java @@ -0,0 +1,18 @@ +package machinecoding.uditagarwal.chess.conditions; + + +import machinecoding.uditagarwal.chess.model.Board; +import machinecoding.uditagarwal.chess.model.Cell; +import machinecoding.uditagarwal.chess.model.Piece; + +/** + * Default condition for moving further. By default, a piece is allowed to move from a cell only if the cell was free + * when it came there. + */ +public class PieceMoveFurtherConditionDefault implements PieceMoveFurtherCondition { + + @Override + public boolean canPieceMoveFurtherFromCell(Piece piece, Cell cell, Board board) { + return cell.isFree(); + } +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/exceptions/InvalidMoveException.java b/src/main/java/machinecoding/uditagarwal/chess/exceptions/InvalidMoveException.java new file mode 100644 index 0000000..c23a170 --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/exceptions/InvalidMoveException.java @@ -0,0 +1,7 @@ +package machinecoding.uditagarwal.chess.exceptions; + +/** + * Exception when move done by a player for a piece is invalid. + */ +public class InvalidMoveException extends RuntimeException { +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/exceptions/PieceNotFoundException.java b/src/main/java/machinecoding/uditagarwal/chess/exceptions/PieceNotFoundException.java new file mode 100644 index 0000000..330a8a1 --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/exceptions/PieceNotFoundException.java @@ -0,0 +1,7 @@ +package machinecoding.uditagarwal.chess.exceptions; + +/** + * Exception if piece to be fetched is not present. + */ +public class PieceNotFoundException extends RuntimeException { +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/helpers/ListHelpers.java b/src/main/java/machinecoding/uditagarwal/chess/helpers/ListHelpers.java new file mode 100644 index 0000000..90d9fd7 --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/helpers/ListHelpers.java @@ -0,0 +1,26 @@ +package machinecoding.uditagarwal.chess.helpers; + +import java.util.ArrayList; +import java.util.List; + +/** + * Helper class related to {@link List}. + */ +public class ListHelpers { + + /** + * Helper method to remove duplicate objects from a list. + * + * @param list List from which duplicated have to be removed. + * @return List without duplicates. + */ + public static List removeDuplicates(List list) { + List newList = new ArrayList(); + for (T element : list) { + if (!newList.contains(element)) { + newList.add(element); + } + } + return newList; + } +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/model/Board.java b/src/main/java/machinecoding/uditagarwal/chess/model/Board.java new file mode 100644 index 0000000..3334bdc --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/model/Board.java @@ -0,0 +1,95 @@ +package machinecoding.uditagarwal.chess.model; + + +import lombok.Getter; +import machinecoding.uditagarwal.chess.conditions.PieceCellOccupyBlocker; + +import java.util.List; + +import static machinecoding.uditagarwal.chess.conditions.PieceCellOccupyBlockerFactory.kingCheckEvaluationBlockers; + +/** + * Model object for a board of chess game. A board has a size and a grid of cells. + */ +@Getter +public class Board { + int boardSize; + Cell[][] cells; + + public Board(int boardSize, Cell[][] cells) { + this.boardSize = boardSize; + this.cells = cells; + } + + /** + * Helper method to return cell to the left of current cell. + */ + public Cell getLeftCell(Cell cell) { + return getCellAtLocation(cell.getX(), cell.getY() - 1); + } + + /** + * Helper method to return cell to the right of current cell. + */ + public Cell getRightCell(Cell cell) { + return getCellAtLocation(cell.getX(), cell.getY() + 1); + } + + /** + * Helper method to return cell to the up of current cell. + */ + public Cell getUpCell(Cell cell) { + return getCellAtLocation(cell.getX() + 1, cell.getY()); + } + + /** + * Helper method to return cell to the down of current cell. + */ + public Cell getDownCell(Cell cell) { + return getCellAtLocation(cell.getX() - 1, cell.getY()); + } + + /** + * Helper method to return cell at a given location. + */ + public Cell getCellAtLocation(int x, int y) { + if (x >= boardSize || x < 0) { + return null; + } + if (y >= boardSize || y < 0) { + return null; + } + + return cells[x][y]; + } + + /** + * Helper method to determine whether the player is on check on the current board. + */ + public boolean isPlayerOnCheck(Player player) { + return checkIfPieceCanBeKilled(player.getPiece(PieceType.KING), kingCheckEvaluationBlockers(), player); + } + + /** + * Method to check if the piece can be killed currently by the opponent as per the current board configuration. + * + * @param targetPiece Piece which is to be checked. + * @param cellOccupyBlockers Blockers which make cell non occupiable. + * @param player Player whose piece has to be checked. + * @return Boolean indicating whether the piece is in danger or not. + */ + public boolean checkIfPieceCanBeKilled(Piece targetPiece, List cellOccupyBlockers, Player player) { + for (int i = 0; i < getBoardSize(); i++) { + for (int j = 0; j < getBoardSize(); j++) { + Piece currentPiece = getCellAtLocation(i, j).getCurrentPiece(); + if (currentPiece != null && !currentPiece.isPieceFromSamePlayer(targetPiece)) { + List nextPossibleCells = currentPiece.nextPossibleCells(this, cellOccupyBlockers, player); + if (nextPossibleCells.contains(targetPiece.getCurrentCell())) { + return true; + } + } + } + } + return false; + } +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/model/Cell.java b/src/main/java/machinecoding/uditagarwal/chess/model/Cell.java new file mode 100644 index 0000000..09435f1 --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/model/Cell.java @@ -0,0 +1,28 @@ +package machinecoding.uditagarwal.chess.model; + + +import lombok.Getter; +import lombok.Setter; + +/** + * Model class representing the single cell of a board. A cell has a location in the grid which is represented by x + * and y location. + */ +@Getter +public class Cell { + + private int x; + private int y; + + public Cell(int x, int y) { + this.x = x; + this.y = y; + } + + @Setter + private Piece currentPiece; + + public boolean isFree() { + return currentPiece == null; + } +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/model/Color.java b/src/main/java/machinecoding/uditagarwal/chess/model/Color.java new file mode 100644 index 0000000..5d8baf6 --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/model/Color.java @@ -0,0 +1,6 @@ +package machinecoding.uditagarwal.chess.model; + +public enum Color { + BLACK, + WHITE +} \ No newline at end of file diff --git a/src/main/java/machinecoding/uditagarwal/chess/model/Piece.java b/src/main/java/machinecoding/uditagarwal/chess/model/Piece.java new file mode 100644 index 0000000..0bbbe96 --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/model/Piece.java @@ -0,0 +1,94 @@ +package machinecoding.uditagarwal.chess.model; + + +import lombok.Getter; +import lombok.NonNull; +import lombok.Setter; +import machinecoding.uditagarwal.chess.conditions.PieceCellOccupyBlocker; +import machinecoding.uditagarwal.chess.exceptions.InvalidMoveException; +import machinecoding.uditagarwal.chess.moves.PossibleMovesProvider; + +import java.util.ArrayList; +import java.util.List; + +import static machinecoding.uditagarwal.chess.helpers.ListHelpers.removeDuplicates; + +/** + * Model class representing a single piece which can be moved on the board. + */ +@Getter +public class Piece { + private boolean isKilled = false; + private final Color color; + private final List movesProviders; + private Integer numMoves = 0; + PieceType pieceType; + + @Setter + @NonNull + private Cell currentCell; + + public Piece(@NonNull final Color color, @NonNull final List movesProviders, @NonNull final PieceType pieceType) { + this.color = color; + this.movesProviders = movesProviders; + this.pieceType = pieceType; + } + + public void killIt() { + this.isKilled = true; + } + + /** + * Method to move piece from current cell to a given cell. + */ + public void move(Player player, Cell toCell, Board board, List additionalBlockers) { + if (isKilled) { + throw new InvalidMoveException(); + } + List nextPossibleCells = nextPossibleCells(board, additionalBlockers, player); + if (!nextPossibleCells.contains(toCell)) { + throw new InvalidMoveException(); + } + + killPieceInCell(toCell); + this.currentCell.setCurrentPiece(null); + this.currentCell = toCell; + this.currentCell.setCurrentPiece(this); + this.numMoves++; + } + + /** + * Helper method to kill a piece in a given cell. + */ + private void killPieceInCell(Cell targetCell) { + if (targetCell.getCurrentPiece() != null) { + targetCell.getCurrentPiece().killIt(); + } + } + + /** + * Method which tells what are all next possible cells to which the current piece can move from the current cell. + * + * @param board Board on which the piece is present. + * @param additionalBlockers Blockers which make a cell non-occupiable for a piece. + * @param player Player who owns the piece. + * @return List of all next possible cells. + */ + public List nextPossibleCells(Board board, List additionalBlockers, Player player) { + List result = new ArrayList<>(); + for (PossibleMovesProvider movesProvider : this.movesProviders) { + List cells = movesProvider.possibleMoves(this, board, additionalBlockers, player); + if (cells != null) { + result.addAll(cells); + } + } + return removeDuplicates(result); + } + + /** + * Helper method to check if two pieces belong to same player. + */ + public boolean isPieceFromSamePlayer(Piece piece) { + return piece.getColor().equals(this.color); + } +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/model/PieceType.java b/src/main/java/machinecoding/uditagarwal/chess/model/PieceType.java new file mode 100644 index 0000000..8fac3fb --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/model/PieceType.java @@ -0,0 +1,10 @@ +package machinecoding.uditagarwal.chess.model; + +public enum PieceType { + KING, + QUEEN, + ROOK, + KNIGHT, + BISHOP, + PAWN +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/model/Player.java b/src/main/java/machinecoding/uditagarwal/chess/model/Player.java new file mode 100644 index 0000000..054cdcb --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/model/Player.java @@ -0,0 +1,33 @@ +package machinecoding.uditagarwal.chess.model; + + +import lombok.Getter; +import machinecoding.uditagarwal.chess.exceptions.PieceNotFoundException; +import machinecoding.uditagarwal.gameplay.contracts.PlayerMove; + +import java.util.List; + +/** + * Abstract model class representing a player. This is abstract because we are not sure how player is going to make his + * move. If the player is a local player, then he can move locally. A player can also be a network based player. + * So, depending on the type of player, he can make move in its own way. + */ +@Getter +public abstract class Player { + List pieces; + + public Player(List pieces) { + this.pieces = pieces; + } + + public Piece getPiece(PieceType pieceType) { + for (Piece piece : getPieces()) { + if (piece.getPieceType() == pieceType) { + return piece; + } + } + throw new PieceNotFoundException(); + } + + abstract public PlayerMove makeMove(); +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/moves/NextCellProvider.java b/src/main/java/machinecoding/uditagarwal/chess/moves/NextCellProvider.java new file mode 100644 index 0000000..db16d16 --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/moves/NextCellProvider.java @@ -0,0 +1,11 @@ +package machinecoding.uditagarwal.chess.moves; + + +import machinecoding.uditagarwal.chess.model.Cell; + +/** + * Given a cell, it will provide next cell which we can reach to. + */ +interface NextCellProvider { + Cell nextCell(Cell cell); +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/moves/PossibleMovesProvider.java b/src/main/java/machinecoding/uditagarwal/chess/moves/PossibleMovesProvider.java new file mode 100644 index 0000000..70dd6a2 --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/moves/PossibleMovesProvider.java @@ -0,0 +1,85 @@ +package machinecoding.uditagarwal.chess.moves; + + + +import machinecoding.uditagarwal.chess.conditions.MoveBaseCondition; +import machinecoding.uditagarwal.chess.conditions.PieceCellOccupyBlocker; +import machinecoding.uditagarwal.chess.conditions.PieceMoveFurtherCondition; +import machinecoding.uditagarwal.chess.model.Board; +import machinecoding.uditagarwal.chess.model.Cell; +import machinecoding.uditagarwal.chess.model.Piece; +import machinecoding.uditagarwal.chess.model.Player; + +import java.util.ArrayList; +import java.util.List; + +/** + * Provider class which returns all the possible cells for a given type of moves. For example, horizontal type of move + * will give all the cells which can be reached by making only horizontal moves. + */ +public abstract class PossibleMovesProvider { + int maxSteps; + MoveBaseCondition baseCondition; + PieceMoveFurtherCondition moveFurtherCondition; + PieceCellOccupyBlocker baseBlocker; + + public PossibleMovesProvider(int maxSteps, MoveBaseCondition baseCondition, PieceMoveFurtherCondition moveFurtherCondition, PieceCellOccupyBlocker baseBlocker) { + this.maxSteps = maxSteps; + this.baseCondition = baseCondition; + this.moveFurtherCondition = moveFurtherCondition; + this.baseBlocker = baseBlocker; + } + + /** + * Public method which actually gives all possible cells which can be reached via current type of move. + */ + public List possibleMoves(Piece piece, Board inBoard, List additionalBlockers, Player player) { + if (baseCondition.isBaseConditionFullfilled(piece)) { + return possibleMovesAsPerCurrentType(piece, inBoard, additionalBlockers, player); + } + return null; + } + + /** + * Abstract method which needs to be implemented by each type of move to give possible moves as per their behaviour. + */ + protected abstract List possibleMovesAsPerCurrentType(Piece piece, Board board, List additionalBlockers, Player player); + + /** + * Helper method used by all the sub types to create the list of cells which can be reached. + */ + protected List findAllNextMoves(Piece piece, NextCellProvider nextCellProvider, Board board, List cellOccupyBlockers, Player player) { + List result = new ArrayList<>(); + Cell nextCell = nextCellProvider.nextCell(piece.getCurrentCell()); + int numSteps = 1; + while (nextCell != null && numSteps <= maxSteps) { + if (checkIfCellCanBeOccupied(piece, nextCell, board, cellOccupyBlockers, player)) { + result.add(nextCell); + } + if (!moveFurtherCondition.canPieceMoveFurtherFromCell(piece, nextCell, board)) { + break; + } + + nextCell = nextCellProvider.nextCell(nextCell); + numSteps++; + } + return result; + } + + /** + * Helper method which checks if a given cell can be occupied by the piece or not. It makes use of list of + * {@link PieceCellOccupyBlocker}s passed to it while checking. Also each move has one base blocker which it should + * also check. + */ + private boolean checkIfCellCanBeOccupied(Piece piece, Cell cell, Board board, List additionalBlockers, Player player) { + if (baseBlocker != null && baseBlocker.isCellNonOccupiableForPiece(cell, piece, board, player)) { + return false; + } + for (PieceCellOccupyBlocker cellOccupyBlocker : additionalBlockers) { + if (cellOccupyBlocker.isCellNonOccupiableForPiece(cell, piece, board, player)) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/moves/PossibleMovesProviderDiagonal.java b/src/main/java/machinecoding/uditagarwal/chess/moves/PossibleMovesProviderDiagonal.java new file mode 100644 index 0000000..78ab858 --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/moves/PossibleMovesProviderDiagonal.java @@ -0,0 +1,26 @@ +package machinecoding.uditagarwal.chess.moves; + + +import machinecoding.uditagarwal.chess.conditions.MoveBaseCondition; +import machinecoding.uditagarwal.chess.conditions.PieceCellOccupyBlocker; +import machinecoding.uditagarwal.chess.conditions.PieceMoveFurtherCondition; +import machinecoding.uditagarwal.chess.model.Board; +import machinecoding.uditagarwal.chess.model.Cell; +import machinecoding.uditagarwal.chess.model.Piece; +import machinecoding.uditagarwal.chess.model.Player; + +import java.util.List; + +public class PossibleMovesProviderDiagonal extends PossibleMovesProvider { + + + public PossibleMovesProviderDiagonal(int maxSteps, MoveBaseCondition baseCondition, + PieceMoveFurtherCondition moveFurtherCondition, PieceCellOccupyBlocker baseBlocker) { + super(maxSteps, baseCondition, moveFurtherCondition, baseBlocker); + } + + @Override + protected List possibleMovesAsPerCurrentType(Piece piece, Board board, List additionalBlockers, Player player) { + return null; + } +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/moves/PossibleMovesProviderHorizontal.java b/src/main/java/machinecoding/uditagarwal/chess/moves/PossibleMovesProviderHorizontal.java new file mode 100644 index 0000000..b2ac8b9 --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/moves/PossibleMovesProviderHorizontal.java @@ -0,0 +1,28 @@ +package machinecoding.uditagarwal.chess.moves; + + +import machinecoding.uditagarwal.chess.conditions.MoveBaseCondition; +import machinecoding.uditagarwal.chess.conditions.PieceCellOccupyBlocker; +import machinecoding.uditagarwal.chess.conditions.PieceMoveFurtherCondition; +import machinecoding.uditagarwal.chess.model.Board; +import machinecoding.uditagarwal.chess.model.Cell; +import machinecoding.uditagarwal.chess.model.Piece; +import machinecoding.uditagarwal.chess.model.Player; + +import java.util.ArrayList; +import java.util.List; + +public class PossibleMovesProviderHorizontal extends PossibleMovesProvider { + + public PossibleMovesProviderHorizontal(int maxSteps, MoveBaseCondition baseCondition, + PieceMoveFurtherCondition moveFurtherCondition, PieceCellOccupyBlocker baseBlocker) { + super(maxSteps, baseCondition, moveFurtherCondition, baseBlocker); + } + + protected List possibleMovesAsPerCurrentType(Piece piece, final Board board, List additionalBlockers, Player player) { + List result = new ArrayList<>(); + result.addAll(findAllNextMoves(piece, board::getLeftCell, board, additionalBlockers, player)); + result.addAll(findAllNextMoves(piece, board::getRightCell, board, additionalBlockers, player)); + return result; + } +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/moves/PossibleMovesProviderVertical.java b/src/main/java/machinecoding/uditagarwal/chess/moves/PossibleMovesProviderVertical.java new file mode 100644 index 0000000..1a01eea --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/moves/PossibleMovesProviderVertical.java @@ -0,0 +1,39 @@ +package machinecoding.uditagarwal.chess.moves; + + +import machinecoding.uditagarwal.chess.conditions.MoveBaseCondition; +import machinecoding.uditagarwal.chess.conditions.PieceCellOccupyBlocker; +import machinecoding.uditagarwal.chess.conditions.PieceMoveFurtherCondition; +import machinecoding.uditagarwal.chess.model.Board; +import machinecoding.uditagarwal.chess.model.Cell; +import machinecoding.uditagarwal.chess.model.Piece; +import machinecoding.uditagarwal.chess.model.Player; + +import java.util.ArrayList; +import java.util.List; + +import static machinecoding.uditagarwal.chess.moves.VerticalMoveDirection.*; + +public class PossibleMovesProviderVertical extends PossibleMovesProvider { + private VerticalMoveDirection verticalMoveDirection; + + public PossibleMovesProviderVertical(int maxSteps, MoveBaseCondition baseCondition, + PieceMoveFurtherCondition moveFurtherCondition, PieceCellOccupyBlocker baseBlocker, + VerticalMoveDirection verticalMoveDirection) { + super(maxSteps, baseCondition, moveFurtherCondition, baseBlocker); + this.verticalMoveDirection = verticalMoveDirection; + } + + + @Override + protected List possibleMovesAsPerCurrentType(Piece piece, Board board, List additionalBlockers, Player player) { + List result = new ArrayList<>(); + if (this.verticalMoveDirection == UP || this.verticalMoveDirection == BOTH) { + result.addAll(findAllNextMoves(piece, board::getUpCell, board, additionalBlockers, player)); + } + if (this.verticalMoveDirection == DOWN || this.verticalMoveDirection == BOTH) { + result.addAll(findAllNextMoves(piece, board::getDownCell, board, additionalBlockers, player)); + } + return result; + } +} diff --git a/src/main/java/machinecoding/uditagarwal/chess/moves/VerticalMoveDirection.java b/src/main/java/machinecoding/uditagarwal/chess/moves/VerticalMoveDirection.java new file mode 100644 index 0000000..4bf9ded --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/chess/moves/VerticalMoveDirection.java @@ -0,0 +1,7 @@ +package machinecoding.uditagarwal.chess.moves; + +public enum VerticalMoveDirection { + UP, + DOWN, + BOTH +} diff --git a/src/main/java/machinecoding/uditagarwal/gameplay/GameController.java b/src/main/java/machinecoding/uditagarwal/gameplay/GameController.java new file mode 100644 index 0000000..3d3bfde --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/gameplay/GameController.java @@ -0,0 +1,24 @@ +package machinecoding.uditagarwal.gameplay; + + +import machinecoding.uditagarwal.chess.model.Board; +import machinecoding.uditagarwal.chess.model.Player; +import machinecoding.uditagarwal.gameplay.contracts.PlayerMove; + +import java.util.List; + +import static machinecoding.uditagarwal.chess.conditions.PieceCellOccupyBlockerFactory.defaultAdditionalBlockers; + +public class GameController { + + public static void gameplay(List players, Board board) { + int currentPlayer = 0; + while (true) { + Player player = players.get(currentPlayer); + //TODO: Check if current player has any move possible. If no move possible, then its checkmate. + PlayerMove playerMove = player.makeMove(); + playerMove.getPiece().move(player, playerMove.getToCell(), board, defaultAdditionalBlockers()); + currentPlayer = (currentPlayer + 1) % players.size(); + } + } +} diff --git a/src/main/java/machinecoding/uditagarwal/gameplay/contracts/PlayerMove.java b/src/main/java/machinecoding/uditagarwal/gameplay/contracts/PlayerMove.java new file mode 100644 index 0000000..f56ed3f --- /dev/null +++ b/src/main/java/machinecoding/uditagarwal/gameplay/contracts/PlayerMove.java @@ -0,0 +1,13 @@ +package machinecoding.uditagarwal.gameplay.contracts; + + +import lombok.Getter; +import machinecoding.uditagarwal.chess.model.Cell; +import machinecoding.uditagarwal.chess.model.Piece; + +@Getter +public class PlayerMove { + + Piece piece; + Cell toCell; +} diff --git a/src/microsoftassesment/AutocompleteSystem.java b/src/main/java/microsoftassesment/AutocompleteSystem.java similarity index 100% rename from src/microsoftassesment/AutocompleteSystem.java rename to src/main/java/microsoftassesment/AutocompleteSystem.java diff --git a/src/microsoftassesment/CropWords.java b/src/main/java/microsoftassesment/CropWords.java similarity index 100% rename from src/microsoftassesment/CropWords.java rename to src/main/java/microsoftassesment/CropWords.java diff --git a/src/microsoftassesment/LexicographicallySmallest.java b/src/main/java/microsoftassesment/LexicographicallySmallest.java similarity index 93% rename from src/microsoftassesment/LexicographicallySmallest.java rename to src/main/java/microsoftassesment/LexicographicallySmallest.java index 33827e3..8ad31df 100644 --- a/src/microsoftassesment/LexicographicallySmallest.java +++ b/src/main/java/microsoftassesment/LexicographicallySmallest.java @@ -4,7 +4,7 @@ import java.util.Deque; import java.util.LinkedList; -//Lexicographically smallest string formed by removing at most one character. +//Lexicographically the smallest string formed by removing at most one character. // // Example 1: // diff --git a/src/microsoftassesment/LongestSubStringWithout3ContiguousLetter.java b/src/main/java/microsoftassesment/LongestSubStringWithout3ContiguousLetter.java similarity index 100% rename from src/microsoftassesment/LongestSubStringWithout3ContiguousLetter.java rename to src/main/java/microsoftassesment/LongestSubStringWithout3ContiguousLetter.java diff --git a/src/microsoftassesment/MinDeletionToMakeUniqueCount.java b/src/main/java/microsoftassesment/MinDeletionToMakeUniqueCount.java similarity index 100% rename from src/microsoftassesment/MinDeletionToMakeUniqueCount.java rename to src/main/java/microsoftassesment/MinDeletionToMakeUniqueCount.java diff --git a/src/microsoftassesment/MinStepsToMakePileSameHeight.java b/src/main/java/microsoftassesment/MinStepsToMakePileSameHeight.java similarity index 100% rename from src/microsoftassesment/MinStepsToMakePileSameHeight.java rename to src/main/java/microsoftassesment/MinStepsToMakePileSameHeight.java diff --git a/src/microsoftassesment/MinSwapsToGroupRedBalls.java b/src/main/java/microsoftassesment/MinSwapsToGroupRedBalls.java similarity index 100% rename from src/microsoftassesment/MinSwapsToGroupRedBalls.java rename to src/main/java/microsoftassesment/MinSwapsToGroupRedBalls.java diff --git a/src/microsoftassesment/NumsWithEqualDigitSum.java b/src/main/java/microsoftassesment/NumsWithEqualDigitSum.java similarity index 100% rename from src/microsoftassesment/NumsWithEqualDigitSum.java rename to src/main/java/microsoftassesment/NumsWithEqualDigitSum.java diff --git a/src/main/java/microsoftassesment/RemoveCharsMoreThanKOccurrence.java b/src/main/java/microsoftassesment/RemoveCharsMoreThanKOccurrence.java new file mode 100644 index 0000000..635ec7b --- /dev/null +++ b/src/main/java/microsoftassesment/RemoveCharsMoreThanKOccurrence.java @@ -0,0 +1,55 @@ +package microsoftassesment; + + +// given eedaaad and k=3 return eedaad +public class RemoveCharsMoreThanKOccurrence { + + public static String removeKConsecutiveChars(String s, int k) { + if (s == null || s.length() == 0) return null; + StringBuilder sb = new StringBuilder(); + sb.append(s.charAt(0)); + int cnt = 1; + for (int r = 1; r < s.length(); r++) { + char c = s.charAt(r); + if (c == s.charAt(r - 1)) + cnt++; + else { + cnt = 1; + } + if (cnt < k) + sb.append(c); + } + return sb.toString(); + + + } + + public static void main(String[] args) { + String[] inputs = {"eedaaad", "xxxtxxxz", "uuuuxaaaaxuuu"}; + for (String i : inputs) { + System.out.println(removeKConsecutiveChars(i, 3)); + } + + System.out.println(removeDuplicates("aaabcd")); + } + + public static String removeDuplicates(String A) { + int stptr = -1; + char[] arr = A.toCharArray(); + for (int i = 0; i < A.length(); i++) { + if (stptr == -1 || arr[i] != arr[stptr]) { + stptr++; + arr[stptr] = arr[i]; + } else { + stptr--; + } + } + StringBuilder ans = new StringBuilder(); + for (int i = 0; i <= stptr; i++) { + ans.append(arr[i]); + } + return new String(ans); + } + + +} diff --git a/src/microsoftassesment/StringWithout3ConsequitiveLetter.java b/src/main/java/microsoftassesment/StringWithout3ConsequitiveLetter.java similarity index 100% rename from src/microsoftassesment/StringWithout3ConsequitiveLetter.java rename to src/main/java/microsoftassesment/StringWithout3ConsequitiveLetter.java diff --git a/src/multithreading/com/safecabs/Constants.java b/src/main/java/multithreading/com/safecabs/Constants.java similarity index 100% rename from src/multithreading/com/safecabs/Constants.java rename to src/main/java/multithreading/com/safecabs/Constants.java diff --git a/src/multithreading/com/safecabs/Gender.java b/src/main/java/multithreading/com/safecabs/Gender.java similarity index 100% rename from src/multithreading/com/safecabs/Gender.java rename to src/main/java/multithreading/com/safecabs/Gender.java diff --git a/src/multithreading/com/safecabs/app/AssignCab.java b/src/main/java/multithreading/com/safecabs/app/AssignCab.java similarity index 100% rename from src/multithreading/com/safecabs/app/AssignCab.java rename to src/main/java/multithreading/com/safecabs/app/AssignCab.java diff --git a/src/multithreading/com/safecabs/app/CabProvider.java b/src/main/java/multithreading/com/safecabs/app/CabProvider.java similarity index 100% rename from src/multithreading/com/safecabs/app/CabProvider.java rename to src/main/java/multithreading/com/safecabs/app/CabProvider.java diff --git a/src/multithreading/com/safecabs/app/CabRequest.java b/src/main/java/multithreading/com/safecabs/app/CabRequest.java similarity index 100% rename from src/multithreading/com/safecabs/app/CabRequest.java rename to src/main/java/multithreading/com/safecabs/app/CabRequest.java diff --git a/src/multithreading/com/safecabs/app/CustomCyclicBarrier.java b/src/main/java/multithreading/com/safecabs/app/CustomCyclicBarrier.java similarity index 100% rename from src/multithreading/com/safecabs/app/CustomCyclicBarrier.java rename to src/main/java/multithreading/com/safecabs/app/CustomCyclicBarrier.java diff --git a/src/multithreading/com/safecabs/cab/Cab.java b/src/main/java/multithreading/com/safecabs/cab/Cab.java similarity index 100% rename from src/multithreading/com/safecabs/cab/Cab.java rename to src/main/java/multithreading/com/safecabs/cab/Cab.java diff --git a/src/multithreading/com/safecabs/client/ClientTest.java b/src/main/java/multithreading/com/safecabs/client/ClientTest.java similarity index 100% rename from src/multithreading/com/safecabs/client/ClientTest.java rename to src/main/java/multithreading/com/safecabs/client/ClientTest.java diff --git a/src/multithreading/com/safecabs/exceptions/UnRegisteredPassengerException.java b/src/main/java/multithreading/com/safecabs/exceptions/UnRegisteredPassengerException.java similarity index 100% rename from src/multithreading/com/safecabs/exceptions/UnRegisteredPassengerException.java rename to src/main/java/multithreading/com/safecabs/exceptions/UnRegisteredPassengerException.java diff --git a/src/multithreading/com/safecabs/passenger/Passenger.java b/src/main/java/multithreading/com/safecabs/passenger/Passenger.java similarity index 100% rename from src/multithreading/com/safecabs/passenger/Passenger.java rename to src/main/java/multithreading/com/safecabs/passenger/Passenger.java diff --git a/src/multithreading/com/safecabs/passenger/RegisteredPassenger.java b/src/main/java/multithreading/com/safecabs/passenger/RegisteredPassenger.java similarity index 100% rename from src/multithreading/com/safecabs/passenger/RegisteredPassenger.java rename to src/main/java/multithreading/com/safecabs/passenger/RegisteredPassenger.java diff --git a/src/main/java/multithreading/educative/AsyncToSyncConverter.java b/src/main/java/multithreading/educative/AsyncToSyncConverter.java new file mode 100644 index 0000000..e221d9a --- /dev/null +++ b/src/main/java/multithreading/educative/AsyncToSyncConverter.java @@ -0,0 +1,60 @@ +package multithreading.educative; + +public class AsyncToSyncConverter { + public static void main(String args[]) throws Exception { + SynchronousExecutor executor = new SynchronousExecutor(); + executor.asynchronousExecution(() -> { + System.out.println("I am done"); + }); + + System.out.println("main thread exiting..."); + } +} + +interface Callback { + void done(); +} + +class SynchronousExecutor extends Executor { + + @Override + public void asynchronousExecution(Callback callback) throws Exception { + + Object signal = new Object(); + final boolean[] isDone = new boolean[1]; + + Callback cb = () -> { + callback.done(); + synchronized (signal) { + signal.notify(); + isDone[0] = true; + } + }; + + // Call the asynchronous executor + super.asynchronousExecution(cb); + + synchronized (signal) { + while (!isDone[0]) { + signal.wait(); + } + } + + } +} + +class Executor { + + public void asynchronousExecution(Callback callback) throws Exception { + + Thread t = new Thread(() -> { + // Do some useful work + try { + Thread.sleep(5000); + } catch (InterruptedException ie) { + } + callback.done(); + }); + t.start(); + } +} diff --git a/src/multithreading/educative/BarberShopProblem.java b/src/main/java/multithreading/educative/BarberShopProblem.java similarity index 59% rename from src/multithreading/educative/BarberShopProblem.java rename to src/main/java/multithreading/educative/BarberShopProblem.java index f9d0e4a..8b9c2e3 100644 --- a/src/multithreading/educative/BarberShopProblem.java +++ b/src/main/java/multithreading/educative/BarberShopProblem.java @@ -7,9 +7,9 @@ public class BarberShopProblem { final int CHAIRS = 3; - Semaphore waitForCustomerToEnter = new Semaphore(0); + Semaphore waitForCustomerToEnterShop = new Semaphore(0); Semaphore waitForBarberToGetReady = new Semaphore(0); - Semaphore waitForCustomerToLeave = new Semaphore(0); + Semaphore waitForCustomerToLeaveChair = new Semaphore(0); Semaphore waitForBarberToCutHair = new Semaphore(0); int waitingCustomers = 0; ReentrantLock lock = new ReentrantLock(); @@ -18,13 +18,23 @@ public class BarberShopProblem { void barber() throws InterruptedException { while (true) { - waitForCustomerToEnter.acquire(); + // wait till a customer enters a shop + waitForCustomerToEnterShop.acquire(); + // let the customer know barber is ready waitForBarberToGetReady.release(); + hairCutsGiven++; + // close the shop for the day + if (hairCutsGiven >= 100) return; + System.out.println("Barber cutting hair..." + hairCutsGiven); Thread.sleep(50); + + // let customer thread know, haircut is done waitForBarberToCutHair.release(); - waitForCustomerToLeave.acquire(); + + // wait for customer to leave the barber chair + waitForCustomerToLeaveChair.acquire(); } } @@ -39,41 +49,41 @@ void customerWalksIn() throws InterruptedException { waitingCustomers++; lock.unlock(); - waitForCustomerToEnter.release(); + // Let the barber know, there's atleast 1 customer + waitForCustomerToEnterShop.release(); + // Wait for the barber to come take you to the salon chair when its your turn waitForBarberToGetReady.acquire(); lock.lock(); waitingCustomers--; lock.unlock(); + // Wait for haircut to complete waitForBarberToCutHair.acquire(); - waitForCustomerToLeave.release(); + // Leave the barber chair and let barber thread know chair is vacant + waitForCustomerToLeaveChair.release(); } public static void runTest() throws InterruptedException { - HashSet set = new HashSet(); + HashSet set = new HashSet<>(); final BarberShopProblem barberShopProblem = new BarberShopProblem(); - Thread barberThread = new Thread(new Runnable() { - public void run() { - try { - barberShopProblem.barber(); - } catch (InterruptedException ie) { + Thread barberThread = new Thread(() -> { + try { + barberShopProblem.barber(); + } catch (InterruptedException ie) { - } } }); barberThread.start(); for (int i = 0; i < 10; i++) { - Thread t = new Thread(new Runnable() { - public void run() { - try { - barberShopProblem.customerWalksIn(); - } catch (InterruptedException ie) { + Thread t = new Thread(() -> { + try { + barberShopProblem.customerWalksIn(); + } catch (InterruptedException ie) { - } } }); set.add(t); @@ -91,13 +101,11 @@ public void run() { Thread.sleep(800); for (int i = 0; i < 5; i++) { - Thread t = new Thread(new Runnable() { - public void run() { - try { - barberShopProblem.customerWalksIn(); - } catch (InterruptedException ie) { + Thread t = new Thread(() -> { + try { + barberShopProblem.customerWalksIn(); + } catch (InterruptedException ie) { - } } }); set.add(t); diff --git a/src/multithreading/educative/Barrier.java b/src/main/java/multithreading/educative/Barrier.java similarity index 62% rename from src/multithreading/educative/Barrier.java rename to src/main/java/multithreading/educative/Barrier.java index ad21e8e..d427d6e 100644 --- a/src/multithreading/educative/Barrier.java +++ b/src/main/java/multithreading/educative/Barrier.java @@ -11,17 +11,22 @@ public Barrier(int totalThreads) { } public synchronized void await() throws InterruptedException { - + // block any new threads from proceeding till, + // all threads from previous barrier are released while (count == totalThreads) wait(); + // increment the counter whenever a thread arrives at the + // barrier. count++; if (count == totalThreads) { + // wake up all the threads. notifyAll(); + // remember to set released to totalThreads released = totalThreads; } else { - + // wait till all threads reach barrier while (count < totalThreads) wait(); } @@ -29,8 +34,7 @@ public synchronized void await() throws InterruptedException { released--; if (released == 0) { count = 0; - // remember to wakeup any threads - // waiting on line + // remember to wake up any threads notifyAll(); } } diff --git a/src/multithreading/educative/BlockingQueue.java b/src/main/java/multithreading/educative/BlockingQueue.java similarity index 73% rename from src/multithreading/educative/BlockingQueue.java rename to src/main/java/multithreading/educative/BlockingQueue.java index aa79a6d..8b17411 100644 --- a/src/multithreading/educative/BlockingQueue.java +++ b/src/main/java/multithreading/educative/BlockingQueue.java @@ -70,7 +70,7 @@ public static void main( String args[] ) throws Exception{ public void run() { try { for (int i = 0; i < 50; i++) { - q.enqueue(new Integer(i)); + q.enqueue(i); System.out.println("enqueued " + i); } } catch (InterruptedException ie) { @@ -79,31 +79,23 @@ public void run() { } }); - Thread t2 = new Thread(new Runnable() { - - @Override - public void run() { - try { - for (int i = 0; i < 25; i++) { - System.out.println("Thread 2 dequeued: " + q.dequeue()); - } - } catch (InterruptedException ie) { - + Thread t2 = new Thread(() -> { + try { + for (int i = 0; i < 25; i++) { + System.out.println("Thread 2 dequeued: " + q.dequeue()); } + } catch (InterruptedException ie) { + } }); - Thread t3 = new Thread(new Runnable() { - - @Override - public void run() { - try { - for (int i = 0; i < 25; i++) { - System.out.println("Thread 3 dequeued: " + q.dequeue()); - } - } catch (InterruptedException ie) { - + Thread t3 = new Thread(() -> { + try { + for (int i = 0; i < 25; i++) { + System.out.println("Thread 3 dequeued: " + q.dequeue()); } + } catch (InterruptedException ie) { + } }); diff --git a/src/multithreading/educative/CountingSemaphore.java b/src/main/java/multithreading/educative/CountingSemaphore.java similarity index 100% rename from src/multithreading/educative/CountingSemaphore.java rename to src/main/java/multithreading/educative/CountingSemaphore.java diff --git a/src/multithreading/educative/DeferredCallbackExecutor.java b/src/main/java/multithreading/educative/DeferredCallbackExecutor.java similarity index 67% rename from src/multithreading/educative/DeferredCallbackExecutor.java rename to src/main/java/multithreading/educative/DeferredCallbackExecutor.java index d1fa6bf..702ddd4 100644 --- a/src/multithreading/educative/DeferredCallbackExecutor.java +++ b/src/main/java/multithreading/educative/DeferredCallbackExecutor.java @@ -7,15 +7,12 @@ import java.util.concurrent.locks.ReentrantLock; // Problem -// Design and implement a thread-safe class that allows registration of callback methods that are executed after a user specified time interval in seconds has elapsed. +// Design and implement a thread-safe class that allows registration of callback methods that are +// executed after a user specified time interval in seconds has elapsed. public class DeferredCallbackExecutor { - PriorityQueue q = new PriorityQueue(new Comparator() { - public int compare(CallBack o1, CallBack o2) { - return (int) (o1.executeAt - o2.executeAt); - } - }); + PriorityQueue q = new PriorityQueue<>((o1, o2) -> (int) (o1.executeAt - o2.executeAt)); ReentrantLock lock = new ReentrantLock(); Condition newCallbackArrived = lock.newCondition(); @@ -38,21 +35,30 @@ private long findSleepDuration() { } public void start() throws InterruptedException { long sleepFor = 0; - int lastSeenQSize = 0; while (true) { lock.lock(); - - while (q.size() == 0) { + /** + * Initially the queue will be empty and the execution thread should just wait indefinitely on the condition variable to be signaled. + */ + while (q.isEmpty()) { newCallbackArrived.await(); } - while (q.size() != 0) { + while (!q.isEmpty()) { sleepFor = findSleepDuration(); if(sleepFor <=0) - break; - + return; + /** + * Now two things are possible at this point. + * No new callbacks arrive, in which case the executor thread completes waiting and + * polls the queue for tasks that should be executed and starts executing them. + * + * Or that another callback arrives, + * in which case the consumer thread will signal the condition variable newCallbackArrived to wake up the execution thread and + * have it re-evaluate the duration it can sleep for before the earliest callback becomes due. + */ newCallbackArrived.await(sleepFor, TimeUnit.MILLISECONDS); } diff --git a/src/multithreading/educative/DemonstrationThreadLocal.java b/src/main/java/multithreading/educative/DemonstrationThreadLocal.java similarity index 80% rename from src/multithreading/educative/DemonstrationThreadLocal.java rename to src/main/java/multithreading/educative/DemonstrationThreadLocal.java index c801df4..4836852 100644 --- a/src/multithreading/educative/DemonstrationThreadLocal.java +++ b/src/main/java/multithreading/educative/DemonstrationThreadLocal.java @@ -5,13 +5,13 @@ import java.util.concurrent.Future; public class DemonstrationThreadLocal { - public static void main( String args[] ) throws Exception { - - usingThreads(); - usingSingleThreadPool(); - usingMultiThreadsPool(); + public static void main(String args[]) throws Exception { + + usingThreads(); + usingSingleThreadPool(); + usingMultiThreadsPool(); } - + static void usingThreads() throws Exception { Counter counter = new Counter(); @@ -31,8 +31,8 @@ static void usingThreads() throws Exception { } System.out.println(counter.counter.get()); - } - + } + @SuppressWarnings("unchecked") static void usingSingleThreadPool() throws Exception { @@ -52,9 +52,9 @@ static void usingSingleThreadPool() throws Exception { System.out.println(tasks[99].get()); es.shutdown(); - } + } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") static void usingMultiThreadsPool() throws Exception { Counter counter = new Counter(); @@ -73,19 +73,19 @@ static void usingMultiThreadsPool() throws Exception { System.out.println(tasks[99].get()); es.shutdown(); - } - -} + } -class Counter { - ThreadLocal counter = ThreadLocal.withInitial(() -> 0); + static class Counter { - public Counter() { - counter.set(0); - } + ThreadLocal counter = ThreadLocal.withInitial(() -> 0); - void increment() { - counter.set(counter.get() + 1); + public Counter() { + counter.set(0); + } + + void increment() { + counter.set(counter.get() + 1); + } } } diff --git a/src/multithreading/educative/DiningPhilosophers.java b/src/main/java/multithreading/educative/DiningPhilosophers.java similarity index 100% rename from src/multithreading/educative/DiningPhilosophers.java rename to src/main/java/multithreading/educative/DiningPhilosophers.java diff --git a/src/multithreading/educative/DiningPhilosophers2.java b/src/main/java/multithreading/educative/DiningPhilosophers2.java similarity index 100% rename from src/multithreading/educative/DiningPhilosophers2.java rename to src/main/java/multithreading/educative/DiningPhilosophers2.java diff --git a/src/multithreading/educative/MultiThreadedMergeSort.java b/src/main/java/multithreading/educative/MultiThreadedMergeSort.java similarity index 100% rename from src/multithreading/educative/MultiThreadedMergeSort.java rename to src/main/java/multithreading/educative/MultiThreadedMergeSort.java diff --git a/src/multithreading/educative/ReadWriteLock.java b/src/main/java/multithreading/educative/ReadWriteLock.java similarity index 77% rename from src/multithreading/educative/ReadWriteLock.java rename to src/main/java/multithreading/educative/ReadWriteLock.java index 27cdb3c..a72b3c5 100644 --- a/src/multithreading/educative/ReadWriteLock.java +++ b/src/main/java/multithreading/educative/ReadWriteLock.java @@ -6,20 +6,16 @@ public class ReadWriteLock { int readers = 0; public synchronized void acquireReadLock() throws InterruptedException { - while (isWriteLocked) { wait(); } - readers++; } public synchronized void acquireWriteLock() throws InterruptedException { - while (isWriteLocked || readers != 0) { wait(); } - isWriteLocked = true; } @@ -34,35 +30,35 @@ public synchronized void releaseWriteLock() { } } - class ReadWriteLock1{ +class ReadWriteLock1 { - private int readers = 0; - private int writers = 0; + private int readers = 0; + private int writers = 0; private int writeRequests = 0; - public synchronized void lockRead() throws InterruptedException{ - while(writers > 0 || writeRequests > 0){ + public synchronized void lockRead() throws InterruptedException { + while (writers > 0 || writeRequests > 0) { wait(); } readers++; } - public synchronized void unlockRead(){ + public synchronized void unlockRead() { readers--; notifyAll(); } - public synchronized void lockWrite() throws InterruptedException{ + public synchronized void lockWrite() throws InterruptedException { writeRequests++; - while(readers > 0 || writers > 0){ + while (readers > 0 || writers > 0) { wait(); } writeRequests--; writers++; } - public synchronized void unlockWrite() throws InterruptedException{ + public synchronized void unlockWrite() { writers--; notifyAll(); } diff --git a/src/multithreading/educative/TokenBucketFilter.java b/src/main/java/multithreading/educative/TokenBucketFilter.java similarity index 77% rename from src/multithreading/educative/TokenBucketFilter.java rename to src/main/java/multithreading/educative/TokenBucketFilter.java index 9e2f6a2..b02fab2 100644 --- a/src/multithreading/educative/TokenBucketFilter.java +++ b/src/main/java/multithreading/educative/TokenBucketFilter.java @@ -4,7 +4,7 @@ import java.util.Set; class Demonstration { - public static void main( String args[] ) throws InterruptedException { + public static void main(String args[]) throws InterruptedException { TokenBucketFilter.runTestMaxTokenIsTen(); } } @@ -40,19 +40,17 @@ synchronized void getToken() throws InterruptedException { public static void runTestMaxTokenIsTen() throws InterruptedException { - Set allThreads = new HashSet(); + Set allThreads = new HashSet<>(); final TokenBucketFilter tokenBucketFilter = new TokenBucketFilter(5); // Sleep for 10 seconds. Thread.sleep(10000); // Generate 12 threads requesting tokens almost all at once. for (int i = 0; i < 12; i++) { - Thread thread = new Thread(new Runnable() { - public void run() { - try { - tokenBucketFilter.getToken(); - } catch (InterruptedException ie) { - System.out.println("We have a problem"); - } + Thread thread = new Thread(() -> { + try { + tokenBucketFilter.getToken(); + } catch (InterruptedException ie) { + System.out.println("We have a problem"); } }); thread.setName("Thread_" + (i + 1)); diff --git a/src/multithreading/educative/UberSeatingProblem.java b/src/main/java/multithreading/educative/UberSeatingProblem.java similarity index 74% rename from src/multithreading/educative/UberSeatingProblem.java rename to src/main/java/multithreading/educative/UberSeatingProblem.java index 4364075..a1e725e 100644 --- a/src/multithreading/educative/UberSeatingProblem.java +++ b/src/main/java/multithreading/educative/UberSeatingProblem.java @@ -21,15 +21,17 @@ public static void main(String[] args) throws InterruptedException { void drive() { System.out.println("Uber Ride on Its wayyyy... with ride leader " + Thread.currentThread().getName()); - System.out.flush(); } /** * Flow goes like this: - * step 1: let's say democrat 1 comes, it gets lock on object, increases count, and goes directly to else state, releases lock and checks for semaphore, since it's - * not there it will be in blocked state (ready to proceed once acquiring semaphore) - * step 2: let's say 3 more democrats are waiting, fourth thread comes and goes into first if and releases 3 semaphores, the 3 previous waiting thread goes and - * wait's for current thread to join at the barrier, once it comes all goes into seating - * step 3: if more that 2 republicans are waiting and current democrat count is 2, this condition releases 1 democrat and 2 republican semaphore + * step 1: let's say democrat 1 comes, it gets lock on object, increases count, and goes directly to else state, + * releases lock and checks for semaphore, + * since it's not there it will be in blocked state (ready to proceed once acquiring semaphore) + * + * step 2: let's say 3 more democrats are waiting, fourth thread comes and goes into first if block and releases 3 semaphores, + * the 3 previous waiting thread goes and wait's for current thread to join at the barrier, once it comes all goes into seating + * + * step 3: if more than 2 republicans are waiting and current democrat count is 2, this condition releases 1 democrat and 2 republican semaphore * it releases 1 democrat because the current thread is also a democrat, and all will be waiting near the barrier till 4th comes */ @@ -58,7 +60,7 @@ void seatDemocrat() throws InterruptedException, BrokenBarrierException { System.out.println("###### unlocking "+Thread.currentThread().getName() ); lock.unlock(); System.out.println("###### State of thread before acquire "+ Thread.currentThread().getName() +" "+Thread.currentThread().getState()); - demsWaiting.acquire(); // thread will be in blocked state not in wait state.. + demsWaiting.acquire(); // thread will be in blocked state not in wait state //In the BLOCKED state, a thread is about to enter a synchronized block, // but there is another thread currently running inside a synchronized block on the same object. // The first thread must then wait for the second thread to exit its block. @@ -68,7 +70,7 @@ void seatDemocrat() throws InterruptedException, BrokenBarrierException { seated(); barrier.await(); - if (rideLeader == true) { + if (rideLeader) { drive(); lock.unlock(); } @@ -109,29 +111,24 @@ void seatRepublican() throws InterruptedException, BrokenBarrierException { void seated() { System.out.println(Thread.currentThread().getName() + " seated"); - System.out.flush(); } public static void runTest() throws InterruptedException { final UberSeatingProblem uberSeatingProblem = new UberSeatingProblem(); - Set allThreads = new HashSet(); + Set allThreads = new HashSet<>(); for (int i = 0; i < 10; i++) { - Thread thread = new Thread(new Runnable() { - public void run() { - try { - uberSeatingProblem.seatDemocrat(); - } catch (InterruptedException ie) { - System.out.println("We have a problem"); - - } catch (BrokenBarrierException bbe) { - System.out.println("We have a problem"); - } + Thread thread = new Thread(() -> { + try { + uberSeatingProblem.seatDemocrat(); + } catch (InterruptedException | BrokenBarrierException ie) { + System.out.println("We have a problem"); } + }); thread.setName("Democrat_" + (i + 1)); allThreads.add(thread); @@ -140,16 +137,12 @@ public void run() { } for (int i = 0; i < 14; i++) { - Thread thread = new Thread(new Runnable() { - public void run() { - try { - uberSeatingProblem.seatRepublican(); - } catch (InterruptedException ie) { - System.out.println("We have a problem"); - - } catch (BrokenBarrierException bbe) { - System.out.println("We have a problem"); - } + Thread thread = new Thread(() -> { + try { + uberSeatingProblem.seatRepublican(); + } catch (InterruptedException | BrokenBarrierException ie) { + System.err.println("We have a problem"); + } }); thread.setName("Republican_" + (i + 1)); diff --git a/src/multithreading/educative/UnisexBathroom.java b/src/main/java/multithreading/educative/UnisexBathroom.java similarity index 94% rename from src/multithreading/educative/UnisexBathroom.java rename to src/main/java/multithreading/educative/UnisexBathroom.java index d41426a..b27e492 100644 --- a/src/multithreading/educative/UnisexBathroom.java +++ b/src/main/java/multithreading/educative/UnisexBathroom.java @@ -12,9 +12,9 @@ public class UnisexBathroom { String inUseBy = NONE; int empsInBathroom = 0; - ReentrantLock lock = new ReentrantLock(); + ReentrantLock lock = new ReentrantLock(true); Condition cond = lock.newCondition(); - Semaphore maxEmps = new Semaphore(3); + Semaphore maxEmps = new Semaphore(3, true); void femaleUseBathroom(String name) throws InterruptedException { diff --git a/src/multithreading/educative/UnisexBathroom2.java b/src/main/java/multithreading/educative/UnisexBathroom2.java similarity index 62% rename from src/multithreading/educative/UnisexBathroom2.java rename to src/main/java/multithreading/educative/UnisexBathroom2.java index 756ac37..051137b 100644 --- a/src/multithreading/educative/UnisexBathroom2.java +++ b/src/main/java/multithreading/educative/UnisexBathroom2.java @@ -8,82 +8,9 @@ public class UnisexBathroom2 { static String MEN = "men"; static String NONE = "none"; - String inUseBy = NONE; + volatile String inUseBy = NONE; int empsInBathroom = 0; - Semaphore maxEmps = new Semaphore(3); - - public static void runTest() throws InterruptedException { - - final UnisexBathroom2 unisexBathroom = new UnisexBathroom2(); - - Thread female1 = new Thread(new Runnable() { - - public void run() { - try { - unisexBathroom.femaleUseBathroom("Lisa"); - } catch (InterruptedException ie) { - - } - } - }); - - Thread male1 = new Thread(new Runnable() { - - public void run() { - try { - unisexBathroom.maleUseBathroom("John"); - } catch (InterruptedException ie) { - - } - } - }); - - Thread male2 = new Thread(new Runnable() { - - public void run() { - try { - unisexBathroom.maleUseBathroom("Bob"); - } catch (InterruptedException ie) { - - } - } - }); - - Thread male3 = new Thread(new Runnable() { - - public void run() { - try { - unisexBathroom.maleUseBathroom("Anil"); - } catch (InterruptedException ie) { - - } - } - }); - - Thread male4 = new Thread(new Runnable() { - - public void run() { - try { - unisexBathroom.maleUseBathroom("Wentao"); - } catch (InterruptedException ie) { - - } - } - }); - - female1.start(); - male1.start(); - male2.start(); - male3.start(); - male4.start(); - - female1.join(); - male1.join(); - male2.join(); - male3.join(); - male4.join(); - - } + Semaphore maxEmps = new Semaphore(3,true); void femaleUseBathroom(String name) throws InterruptedException { @@ -136,4 +63,64 @@ void useBathroom(String name) throws InterruptedException { Thread.sleep(10000); System.out.println(name + " done using bathroom"); } + + public static void runTest() throws InterruptedException { + + final UnisexBathroom2 unisexBathroom = new UnisexBathroom2(); + + Thread female1 = new Thread(() -> { + try { + unisexBathroom.femaleUseBathroom("Lisa"); + } catch (InterruptedException ie) { + + } + }); + + Thread male1 = new Thread(() -> { + + try { + unisexBathroom.maleUseBathroom("John"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + }); + + Thread male2 = new Thread(() -> { + try { + unisexBathroom.maleUseBathroom("Bob"); + } catch (InterruptedException ie) { + + } + }); + + Thread male3 = new Thread(() -> { + try { + unisexBathroom.maleUseBathroom("Anil"); + } catch (InterruptedException ie) { + + } + }); + + Thread male4 = new Thread(() -> { + try { + unisexBathroom.maleUseBathroom("Wentao"); + } catch (InterruptedException ie) { + + } + }); + + female1.start(); + male1.start(); + male2.start(); + male3.start(); + male4.start(); + + female1.join(); + male1.join(); + male2.join(); + male3.join(); + male4.join(); + + } } diff --git a/src/multithreading/educative/companies/netflix/Callback.java b/src/main/java/multithreading/educative/companies/netflix/Callback.java similarity index 100% rename from src/multithreading/educative/companies/netflix/Callback.java rename to src/main/java/multithreading/educative/companies/netflix/Callback.java diff --git a/src/multithreading/educative/companies/netflix/Executor.java b/src/main/java/multithreading/educative/companies/netflix/Executor.java similarity index 100% rename from src/multithreading/educative/companies/netflix/Executor.java rename to src/main/java/multithreading/educative/companies/netflix/Executor.java diff --git a/src/multithreading/educative/companies/netflix/Run.java b/src/main/java/multithreading/educative/companies/netflix/Run.java similarity index 100% rename from src/multithreading/educative/companies/netflix/Run.java rename to src/main/java/multithreading/educative/companies/netflix/Run.java diff --git a/src/multithreading/educative/companies/netflix/SynchronousExecutor.java b/src/main/java/multithreading/educative/companies/netflix/SynchronousExecutor.java similarity index 100% rename from src/multithreading/educative/companies/netflix/SynchronousExecutor.java rename to src/main/java/multithreading/educative/companies/netflix/SynchronousExecutor.java diff --git a/src/multithreading/educative/examples/CallableExample.java b/src/main/java/multithreading/educative/examples/CallableExample.java similarity index 100% rename from src/multithreading/educative/examples/CallableExample.java rename to src/main/java/multithreading/educative/examples/CallableExample.java diff --git a/src/multithreading/educative/examples/DaemonThreadSpawn.java b/src/main/java/multithreading/educative/examples/DaemonThreadSpawn.java similarity index 100% rename from src/multithreading/educative/examples/DaemonThreadSpawn.java rename to src/main/java/multithreading/educative/examples/DaemonThreadSpawn.java diff --git a/src/multithreading/educative/examples/FutureTaskExample.java b/src/main/java/multithreading/educative/examples/FutureTaskExample.java similarity index 100% rename from src/multithreading/educative/examples/FutureTaskExample.java rename to src/main/java/multithreading/educative/examples/FutureTaskExample.java diff --git a/src/multithreading/educative/examples/StockOrder.java b/src/main/java/multithreading/educative/examples/StockOrder.java similarity index 75% rename from src/multithreading/educative/examples/StockOrder.java rename to src/main/java/multithreading/educative/examples/StockOrder.java index e47d51b..914554e 100644 --- a/src/multithreading/educative/examples/StockOrder.java +++ b/src/main/java/multithreading/educative/examples/StockOrder.java @@ -25,12 +25,7 @@ void receiveAndExecuteClientOrdersBetter() { while (true) { final Order order = waitForNextOrder(); - Thread thread = new Thread(new Runnable() { - - public void run() { - order.execute(); - } - }); + Thread thread = new Thread(() -> order.execute()); thread.start(); } @@ -46,12 +41,7 @@ void receiveAndExecuteClientOrdersBest() { while (true) { final Order order = waitForNextOrder(); - executor.execute(new Runnable() { - - public void run() { - order.execute(); - } - }); + executor.execute(() -> order.execute()); } } } diff --git a/src/multithreading/educative/examples/ThreadExample.java b/src/main/java/multithreading/educative/examples/ThreadExample.java similarity index 100% rename from src/multithreading/educative/examples/ThreadExample.java rename to src/main/java/multithreading/educative/examples/ThreadExample.java diff --git a/src/multithreading/educative/examples/ThreadExecutorExample.java b/src/main/java/multithreading/educative/examples/ThreadExecutorExample.java similarity index 100% rename from src/multithreading/educative/examples/ThreadExecutorExample.java rename to src/main/java/multithreading/educative/examples/ThreadExecutorExample.java diff --git a/src/multithreading/educative/examples/ThreadInterruptedException.java b/src/main/java/multithreading/educative/examples/ThreadInterruptedException.java similarity index 100% rename from src/multithreading/educative/examples/ThreadInterruptedException.java rename to src/main/java/multithreading/educative/examples/ThreadInterruptedException.java diff --git a/src/multithreading/educative/examples/ThreadSleepExample.java b/src/main/java/multithreading/educative/examples/ThreadSleepExample.java similarity index 100% rename from src/multithreading/educative/examples/ThreadSleepExample.java rename to src/main/java/multithreading/educative/examples/ThreadSleepExample.java diff --git a/src/multithreading/educative/examples/ThreadSpawn.java b/src/main/java/multithreading/educative/examples/ThreadSpawn.java similarity index 100% rename from src/multithreading/educative/examples/ThreadSpawn.java rename to src/main/java/multithreading/educative/examples/ThreadSpawn.java diff --git a/src/multithreading/educative/examples/TimerVsPool.java b/src/main/java/multithreading/educative/examples/TimerVsPool.java similarity index 100% rename from src/multithreading/educative/examples/TimerVsPool.java rename to src/main/java/multithreading/educative/examples/TimerVsPool.java diff --git a/src/multithreading/educative/superman/Superman.java b/src/main/java/multithreading/educative/superman/Superman.java similarity index 100% rename from src/multithreading/educative/superman/Superman.java rename to src/main/java/multithreading/educative/superman/Superman.java diff --git a/src/multithreading/educative/superman/SupermanNaiveButCorrect.java b/src/main/java/multithreading/educative/superman/SupermanNaiveButCorrect.java similarity index 100% rename from src/multithreading/educative/superman/SupermanNaiveButCorrect.java rename to src/main/java/multithreading/educative/superman/SupermanNaiveButCorrect.java diff --git a/src/multithreading/educative/superman/SupermanSlightlyBetter.java b/src/main/java/multithreading/educative/superman/SupermanSlightlyBetter.java similarity index 100% rename from src/multithreading/educative/superman/SupermanSlightlyBetter.java rename to src/main/java/multithreading/educative/superman/SupermanSlightlyBetter.java diff --git a/src/multithreading/educative/superman/SupermanWithFlaws.java b/src/main/java/multithreading/educative/superman/SupermanWithFlaws.java similarity index 100% rename from src/multithreading/educative/superman/SupermanWithFlaws.java rename to src/main/java/multithreading/educative/superman/SupermanWithFlaws.java diff --git a/src/multithreading/practice/Addition.java b/src/main/java/multithreading/practice/Addition.java similarity index 100% rename from src/multithreading/practice/Addition.java rename to src/main/java/multithreading/practice/Addition.java diff --git a/src/main/java/multithreading/practice/CountdownLatch.java b/src/main/java/multithreading/practice/CountdownLatch.java new file mode 100644 index 0000000..4f13ea2 --- /dev/null +++ b/src/main/java/multithreading/practice/CountdownLatch.java @@ -0,0 +1,38 @@ +package multithreading.practice; + +import java.util.concurrent.CountDownLatch; + +public class CountdownLatch { + + public static void main(String[] args) throws InterruptedException { + final CountDownLatch countdown = new CountDownLatch(10); + for (int i = 0; i < 10; ++i) { + Thread t = new Thread(() -> { + try { + doSomething(); + countdown.countDown(); + System.out.printf("Waiting on %d other threads. Thread name %s", countdown.getCount(),Thread.currentThread().getName()); + System.out.println(); + //waits until everyone reaches this point + + } catch (InterruptedException e) { + e.printStackTrace(); + } + finish(); + }); + t.start(); + } + countdown.await(); + System.out.println("Main Thread finishing"); + } + + public static void doSomething() throws InterruptedException { + Thread.sleep(10000); + } + + public static void finish() { + System.out.println("Finished everything"); + } +} + + diff --git a/src/main/java/multithreading/practice/DiningPhilosophers.java b/src/main/java/multithreading/practice/DiningPhilosophers.java new file mode 100644 index 0000000..9ce01d4 --- /dev/null +++ b/src/main/java/multithreading/practice/DiningPhilosophers.java @@ -0,0 +1,39 @@ +package multithreading.practice; + +import java.util.concurrent.Semaphore; + +class DiningPhilosophers { + + Semaphore[] forks = new Semaphore[5]; + Semaphore eating = new Semaphore(4); + + public DiningPhilosophers() { + + for (int i = 0; i < 5; i++) { + forks[i] = new Semaphore(1); + } + + } + + // call the run() method of any runnable to execute its code + public void wantsToEat(int i, + Runnable pickLeftFork, + Runnable pickRightFork, + Runnable eat, + Runnable putLeftFork, + Runnable putRightFork) throws InterruptedException { + + eating.acquire(); + forks[i].acquire(); + forks[(i + 1) % 5].acquire(); + pickLeftFork.run(); + pickRightFork.run(); + + eat.run(); + putLeftFork.run(); + putRightFork.run(); + forks[i].release(); + forks[(i + 1) % 5].release(); + eating.release(); + } +} \ No newline at end of file diff --git a/src/multithreading/practice/FizzBuzz.java b/src/main/java/multithreading/practice/FizzBuzz.java similarity index 100% rename from src/multithreading/practice/FizzBuzz.java rename to src/main/java/multithreading/practice/FizzBuzz.java diff --git a/src/main/java/multithreading/practice/Foo.java b/src/main/java/multithreading/practice/Foo.java new file mode 100644 index 0000000..2bc81b6 --- /dev/null +++ b/src/main/java/multithreading/practice/Foo.java @@ -0,0 +1,124 @@ +package multithreading.practice; + +import org.junit.Test; + +import java.util.concurrent.Semaphore; + +/** + * "Semaphore is a bowl of marbles" - Professor Stark + *

+ * Semaphore is a bowl of marbles (or locks in this case). + * If you need a marble, and there are none, you wait. You wait until there is one marble and then you take it. + * If you release(), you will add one marble to the bowl (from thin air). + * If you release(100), you will add 100 marbles to the bowl. run2.release(); will add one "run2" marble to the "run2 bowl". + * The thread calling third() will wait until the end of second() when it releases a 'run3' marble. + * The second() will wait until the end of **first() **when it releases a 'run2' marble. + * Since first() never acquires anything, it will never wait. There is a forced wait ordering. + * With semaphores, you can start out with 1 marble or 0 marbles or 100 marbles. + * A thread can take marbles (up until it's empty) or put many marbles at a time. + **/ +class Foo { + Semaphore first = new Semaphore(0); + Semaphore second = new Semaphore(0); + Semaphore third = new Semaphore(0); + + public Foo() { + + } + + public void first(Runnable printFirst) throws InterruptedException { + first.acquire(); + printFirst.run(); + second.release(); + } + + public void second(Runnable printSecond) throws InterruptedException { + first.release(); + second.acquire(); + printSecond.run(); + third.release(); + } + + public void third(Runnable printThird) throws InterruptedException { + first.release(); + third.acquire(); + printThird.run(); + + + } + + private boolean printOneCompleted = false; + private boolean printTwoCompleted = false; + private final Object lock = new Object(); + + public void first(Runnable printFirst, Void tempToAvoidCompilationIssue) throws InterruptedException { + synchronized(lock) { + printFirst.run(); + printOneCompleted = true; + lock.notifyAll(); + } + } + + public synchronized void second(Runnable printSecond, Void tempToAvoidCompilationIssue) throws InterruptedException { + synchronized(lock) { + while (!printOneCompleted) { + lock.wait(); + } + printSecond.run(); + printTwoCompleted = true; + lock.notifyAll(); + } + } + + public synchronized void third(Runnable printThird, Void tempToAvoidCompilationIssue) throws InterruptedException { + synchronized(lock) { + while (!printTwoCompleted) { + lock.wait(); + } + printThird.run(); + } + } + +} + +class PrintInOrder { + private Thread createThread(Foo foo, int index) { + return new Thread(() -> { + try { + switch (index) { + case 1: + foo.first(() -> System.out.print("first")); + break; + case 2: + foo.second(() -> System.out.print("second")); + break; + case 3: + foo.third(() -> System.out.print("third")); + break; + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + } + + @Test + public void test0() throws InterruptedException { + Foo foo = new Foo(); + int[] input = {1, 2, 3}; + for (int i : input) { + Thread thread = createThread(foo, i); + thread.start(); + } + } + + @Test + public void test1() throws InterruptedException { + Foo foo = new Foo(); + int[] input = {1, 3, 2}; + for (int i : input) { + Thread thread = createThread(foo, i); + thread.start(); + } + } +} \ No newline at end of file diff --git a/src/multithreading/practice/FooBar.java b/src/main/java/multithreading/practice/FooBar.java similarity index 100% rename from src/multithreading/practice/FooBar.java rename to src/main/java/multithreading/practice/FooBar.java diff --git a/src/main/java/multithreading/practice/H2O.java b/src/main/java/multithreading/practice/H2O.java new file mode 100644 index 0000000..757323e --- /dev/null +++ b/src/main/java/multithreading/practice/H2O.java @@ -0,0 +1,27 @@ +package multithreading.practice; + +import java.util.concurrent.Semaphore; + +public class H2O { + + Semaphore s1 = new Semaphore(2); + Semaphore s2 = new Semaphore(0); + + public H2O() { + + } + + public void hydrogen(Runnable releaseHydrogen) throws InterruptedException { + s1.acquire(); + // releaseHydrogen.run() outputs "H". Do not change or remove this line. + releaseHydrogen.run(); + s2.release(); + } + + public void oxygen(Runnable releaseOxygen) throws InterruptedException { + s2.acquire(2); + // releaseOxygen.run() outputs "O". Do not change or remove this line. + releaseOxygen.run(); + s1.release(2); + } +} diff --git a/src/main/java/multithreading/practice/NonReentrantLock.java b/src/main/java/multithreading/practice/NonReentrantLock.java new file mode 100644 index 0000000..fbb1c0d --- /dev/null +++ b/src/main/java/multithreading/practice/NonReentrantLock.java @@ -0,0 +1,36 @@ +package multithreading.practice; + +class NonReentrantLock { + + boolean isLocked = false; + + public synchronized void lock() throws InterruptedException { + while (isLocked) { + wait(); + } + isLocked = true; + } + + public synchronized void unlock() { + isLocked = false; + notify(); + } + + + public NonReentrantLock() { + isLocked = false; + } + + public static void main(String args[]) throws Exception { + NonReentrantLock nreLock = new NonReentrantLock(); + + // First locking would be successful + nreLock.lock(); + System.out.println("Acquired first lock"); + + // Second locking results in a self deadlock + System.out.println("Trying to acquire second lock"); + nreLock.lock(); + System.out.println("Acquired second lock"); + } +} \ No newline at end of file diff --git a/src/multithreading/practice/OddEven.java b/src/main/java/multithreading/practice/OddEven.java similarity index 100% rename from src/multithreading/practice/OddEven.java rename to src/main/java/multithreading/practice/OddEven.java diff --git a/src/multithreading/practice/OddEvenSemaphore.java b/src/main/java/multithreading/practice/OddEvenSemaphore.java similarity index 100% rename from src/multithreading/practice/OddEvenSemaphore.java rename to src/main/java/multithreading/practice/OddEvenSemaphore.java diff --git a/src/multithreading/practice/ProducerConsumer.java b/src/main/java/multithreading/practice/ProducerConsumer.java similarity index 98% rename from src/multithreading/practice/ProducerConsumer.java rename to src/main/java/multithreading/practice/ProducerConsumer.java index d6bf5ae..e8ad8aa 100644 --- a/src/multithreading/practice/ProducerConsumer.java +++ b/src/main/java/multithreading/practice/ProducerConsumer.java @@ -61,7 +61,7 @@ public String call() throws InterruptedException { while (count++ <50) { - while (this.buffer.size() == 0) { + while (this.buffer.isEmpty()) { consumerCond.await(); } this.buffer.remove(buffer.size() - 1); diff --git a/src/main/java/multithreading/practice/RealTimeCounter.java b/src/main/java/multithreading/practice/RealTimeCounter.java new file mode 100644 index 0000000..c8f3682 --- /dev/null +++ b/src/main/java/multithreading/practice/RealTimeCounter.java @@ -0,0 +1,99 @@ +package multithreading.practice; + +import java.util.Random; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicLongArray; + +public class RealTimeCounter { + + private final static int GRANULARITY = 300; + private AtomicLongArray counter = new AtomicLongArray(GRANULARITY); + private volatile int pos = 0; + + private RealTimeCounter() { + PositionUpdater positionUpdater = new PositionUpdater(this); + positionUpdater.start(); + } + + private static volatile RealTimeCounter INSTANCE; + + public static RealTimeCounter getInstance() { + if (INSTANCE == null) { + synchronized (RealTimeCounter.class) { + if (INSTANCE == null) { + INSTANCE = new RealTimeCounter(); + } + } + } + return INSTANCE; + } + + public long getTotalEvents() { + int total = 0; + for (int i = 0; i < GRANULARITY; i++) { + total += counter.get(i); + } + return total; + } + + public void addEvent() { + counter.getAndIncrement(pos); + } + + void incrementPosition() { + //first reset the value to 0 at next counter location. + counter.set((pos + 1) % GRANULARITY, 0); + pos = (pos + 1) % GRANULARITY; + } + + public static void main(String args[]) { + ExecutorService executor = Executors.newFixedThreadPool(10); + RealTimeCounter realTimeCounter = new RealTimeCounter(); + final Random random = new Random(); + final int TOTAL_EVENTS = 10000; + CountDownLatch countDownLatch = new CountDownLatch(TOTAL_EVENTS); + for (int i = 0; i < TOTAL_EVENTS; i++) { + executor.execute(() -> { + realTimeCounter.addEvent(); + try { + Thread.sleep(random.nextInt(10)); + } catch (Exception e) { + e.printStackTrace(); + } + countDownLatch.countDown(); + } + ); + } + try { + countDownLatch.await(); + } catch (Exception e) { + e.printStackTrace(); + } + System.out.println(realTimeCounter.getTotalEvents()); + executor.shutdownNow(); + } +} + +class PositionUpdater extends TimerTask { + + private final RealTimeCounter realTimeCounter; + private final Timer timer = new Timer(true); + private static final int DELAY = 1000; + + PositionUpdater(RealTimeCounter realTimeCounter) { + this.realTimeCounter = realTimeCounter; + } + + public void start() { + timer.schedule(this, DELAY); + } + + @Override + public void run() { + realTimeCounter.incrementPosition(); + } +} \ No newline at end of file diff --git a/src/main/java/multithreading/practice/WebCrawler.java b/src/main/java/multithreading/practice/WebCrawler.java new file mode 100644 index 0000000..8056693 --- /dev/null +++ b/src/main/java/multithreading/practice/WebCrawler.java @@ -0,0 +1,107 @@ +package multithreading.practice; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class WebCrawler { + + Set visited = ConcurrentHashMap.newKeySet(); + Set result = ConcurrentHashMap.newKeySet(); + + public List crawl(String startUrl, HtmlParser htmlParser) { + + visited.add(startUrl); + result.add(startUrl); + List threads = new ArrayList<>(); + + for (String nextUrls : htmlParser.getUrls(startUrl)) { + + if (isUnderSameHost(startUrl, nextUrls) && visited.add(nextUrls)) { + Thread t = new Thread(() -> crawl(nextUrls, htmlParser)); + threads.add(t); + } + } + + for (Thread t : threads) { + t.start(); + } + + for (Thread t : threads) { + try { + t.join(); + } catch (Exception e) { + e.printStackTrace(); + } + } + return new ArrayList<>(result); + } + + private boolean isUnderSameHost(String u1, String u2) { + String[] arr1 = u1.split("/"); + String d1 = arr1[0] + "//" + arr1[2]; + return u2.startsWith(d1); + } + + interface HtmlParser { + List getUrls(String url); + } + + + + public List crawlUsingStreams(String startUrl, HtmlParser htmlParser) { + String hostname = getHostname(startUrl); + + // We don't want to re-crawl pages, so we're going to use a Set that can be modified concurrently + // The following link describes how it is implemented, if you're interested + // https://github.com/frohoff/jdk8u-jdk/blob/master/src/share/classes/java/util/concurrent/ConcurrentHashMap.java#L271 + Set visited = ConcurrentHashMap.newKeySet(); + visited.add(startUrl); + + // This is similar to map-reduce, but instead of reducing to a single value we collect the values + return crawl(startUrl, htmlParser, hostname, visited) + .collect(Collectors.toList()); + } + + private Stream crawl(String startUrl, HtmlParser htmlParser, String hostname, Set visited) { + // htmlParser#getUrls returns a List + Stream stream = htmlParser.getUrls(startUrl) + // We process each url in parallel. The number of threads (parallelism) is decided by the JDK. + .parallelStream() + // We filter out external urls, meaning we don't continue processing them and they're not a part of the result + // This method (isSameHostname) is thread-safe + .filter(url -> isSameHostname(url, hostname)) + // visited is the concurrent set. The add method returns false if the url is already in the set. In that case we ignore the url + // A Set is normally not thread-safe but the one we're using is. + .filter(visited::add) + // If the url passed both filters above, we call crawl on it (recursively). A url generates a Stream + // If we were to use .map we would get something like a List> + // but we need to return a single Stream so we can chain the calls. flatMap concat the multiple streams into a single one + .flatMap(url -> crawl(url, htmlParser, hostname, visited)); + + // We want to return the original crawled url as well as the url's we found by crawling it + // Since startUrl is not part of the stream, we need to add it + // + // Think about what happens to the original url in the flatMap phase: it gets replaced by the Stream of the crawl method + // To keep the startUrl we concat it to the stream. + return Stream.concat(Stream.of(startUrl), stream); + } + + /** Returns the url without the path. (method name wasn't the best) */ + private String getHostname(String url) { + // Start the search after the protocol (http:// is always in the url) + int idx = url.indexOf('/', 7); + // Return the url without the path + return (idx != -1) ? url.substring(0, idx) : url; + } + + private boolean isSameHostname(String url, String hostname) { + if (!url.startsWith(hostname)) { + return false; + } + return url.length() == hostname.length() || url.charAt(hostname.length()) == '/'; + } +} diff --git a/src/multithreading/practice/ZeroEvenOdd.java b/src/main/java/multithreading/practice/ZeroEvenOdd.java similarity index 100% rename from src/multithreading/practice/ZeroEvenOdd.java rename to src/main/java/multithreading/practice/ZeroEvenOdd.java diff --git a/src/main/java/multithreading/producerconsumer/Main.java b/src/main/java/multithreading/producerconsumer/Main.java new file mode 100644 index 0000000..9f3077e --- /dev/null +++ b/src/main/java/multithreading/producerconsumer/Main.java @@ -0,0 +1,26 @@ +package multithreading.producerconsumer; + +import java.util.Optional; + +public class Main { + public static void main(String[] args) { + new ProducerConsumer(/* numProducerThreads = */ 1, /* numConsumerThreads = */ 4, + /* queueCapacity = */ 10) { + @Override + public void producer() { + for (int i = 0; i < 100; i++) { + System.out.println("Producing " + i); + produce(i); + } + } + + @Override + public void consumer() { + for (Optional opt; (opt = consume()).isPresent(); ) { + int i = opt.get(); + System.out.println("Got " + i); + } + } + }; + } +} diff --git a/src/main/java/multithreading/producerconsumer/ProducerConsumer.java b/src/main/java/multithreading/producerconsumer/ProducerConsumer.java new file mode 100644 index 0000000..4b504e3 --- /dev/null +++ b/src/main/java/multithreading/producerconsumer/ProducerConsumer.java @@ -0,0 +1,97 @@ +package multithreading.producerconsumer; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; + +public abstract class ProducerConsumer { + + private final BlockingQueue> queue; + + public ProducerConsumer(int numProducerThreads, int numConsumerThreads, int queueCapacity) { + if (numProducerThreads < 1 || numConsumerThreads < 1 || queueCapacity < 1) { + throw new IllegalArgumentException(); + } + queue = new ArrayBlockingQueue<>(queueCapacity); + final ExecutorService executor = Executors.newFixedThreadPool(numProducerThreads + numConsumerThreads); + try { + // Start producer threads + final List> producerFutures = new ArrayList<>(); + final AtomicInteger numLiveProducers = new AtomicInteger(); + for (int i = 0; i < numProducerThreads; i++) { + producerFutures.add(executor.submit(() -> { + numLiveProducers.incrementAndGet(); + // Run producer + producer(); + // When last producer finishes, deliver poison pills to consumers + if (numLiveProducers.decrementAndGet() == 0) { + for (int j = 0; j < numConsumerThreads; j++) { + queue.put(Optional.empty()); + } + } + return null; + })); + } + // Start consumer threads + final List> consumerFutures = new ArrayList<>(); + for (int i = 0; i < numConsumerThreads; i++) { + consumerFutures.add(executor.submit(() -> { + // Run Consumer + consumer(); + return null; + })); + } + // Wait for all producers to complete + completionBarrier(producerFutures, false); + // Shut down any consumers that are still running after producers complete + completionBarrier(consumerFutures, false); + } finally { + executor.shutdownNow(); + } + } + + private static void completionBarrier(List> futures, boolean cancel) { + for (Future future : futures) { + try { + if (cancel) { + future.cancel(true); + } + future.get(); + } catch (CancellationException | InterruptedException e) { + // Ignore + } catch (ExecutionException e) { + throw new RuntimeException(e); + } + } + } + + protected void produce(E val) { + try { + queue.put(Optional.of(val)); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + protected Optional consume() { + try { + return queue.take(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + /** + * Producer loop. Call {@link #produce(E)} for each element. + */ + public abstract void producer(); + + /** + * Consumer thread. Call {@link #consume()} to get each successive element, + * until an empty {@link Optional} is returned. + */ + public abstract void consumer(); +} + diff --git a/src/main/java/multithreading/thread/Bank.java b/src/main/java/multithreading/thread/Bank.java new file mode 100644 index 0000000..846f8f4 --- /dev/null +++ b/src/main/java/multithreading/thread/Bank.java @@ -0,0 +1,74 @@ +package multithreading.thread; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +public class Bank { + private static int bankMoney = 0; + private volatile int account; + private Lock lock; + private Condition condition; + // write your code + + public Bank(int account) { + this.account = account; + // write your code + + lock = new ReentrantLock(); + condition = lock.newCondition(); + } + + public void saveMoney(int amount) throws Exception { + + try { + lock.lock(); + account = saveOperation(account, amount); + if (account >= amount) { + condition.signalAll(); + } + + } finally { + lock.unlock(); + } + + } + + public void withdrawMoney(int amount) throws Exception { + // write your code + + try { + lock.lock(); + while (amount > account) { + condition.await(); + } + account = withdrawOperation(account, amount); + + } finally { + lock.unlock(); + } + } + + public int checkAccount() { + return account; + } + + public static int saveOperation(int account, int amount) throws Exception { + if (bankMoney != account) { + throw new Exception("Don't cheat!\nYour money is " + account + ". The real money is " + bankMoney + "."); + } + bankMoney += amount; + return bankMoney; + } + + public static int withdrawOperation(int account, int amount) throws Exception { + if (bankMoney != account) { + throw new Exception("Don't cheat!\nYour money is " + account + ". The real money is " + bankMoney + "."); + } + if (bankMoney < amount) { + throw new Exception("Money" + bankMoney + " in bank is lowwer than what you want to withdraw(" + account + ")."); + } + bankMoney -= amount; + return bankMoney; + } +} \ No newline at end of file diff --git a/src/multithreading/thread/BasicMultiThreading.java b/src/main/java/multithreading/thread/BasicMultiThreading.java similarity index 100% rename from src/multithreading/thread/BasicMultiThreading.java rename to src/main/java/multithreading/thread/BasicMultiThreading.java diff --git a/src/multithreading/thread/DeadLock.java b/src/main/java/multithreading/thread/DeadLock.java similarity index 100% rename from src/multithreading/thread/DeadLock.java rename to src/main/java/multithreading/thread/DeadLock.java diff --git a/src/multithreading/thread/PrintEvenOddTester.java b/src/main/java/multithreading/thread/PrintEvenOddTester.java similarity index 100% rename from src/multithreading/thread/PrintEvenOddTester.java rename to src/main/java/multithreading/thread/PrintEvenOddTester.java diff --git a/src/multithreading/thread/PrintOddEvenByTwoThreads.java b/src/main/java/multithreading/thread/PrintOddEvenByTwoThreads.java similarity index 100% rename from src/multithreading/thread/PrintOddEvenByTwoThreads.java rename to src/main/java/multithreading/thread/PrintOddEvenByTwoThreads.java diff --git a/src/multithreading/thread/RaceConditionExample.java b/src/main/java/multithreading/thread/RaceConditionExample.java similarity index 100% rename from src/multithreading/thread/RaceConditionExample.java rename to src/main/java/multithreading/thread/RaceConditionExample.java diff --git a/src/multithreading/thread/Tesst.java b/src/main/java/multithreading/thread/Tesst.java similarity index 100% rename from src/multithreading/thread/Tesst.java rename to src/main/java/multithreading/thread/Tesst.java diff --git a/src/multithreading/thread/TestForLocking.java b/src/main/java/multithreading/thread/TestForLocking.java similarity index 100% rename from src/multithreading/thread/TestForLocking.java rename to src/main/java/multithreading/thread/TestForLocking.java diff --git a/src/multithreading/thread/ThreadJoinExample.java b/src/main/java/multithreading/thread/ThreadJoinExample.java similarity index 100% rename from src/multithreading/thread/ThreadJoinExample.java rename to src/main/java/multithreading/thread/ThreadJoinExample.java diff --git a/src/multithreading/thread/ThreadRunnable.java b/src/main/java/multithreading/thread/ThreadRunnable.java similarity index 100% rename from src/multithreading/thread/ThreadRunnable.java rename to src/main/java/multithreading/thread/ThreadRunnable.java diff --git a/src/main/java/practiceproblems/AdvantageShuffle.java b/src/main/java/practiceproblems/AdvantageShuffle.java new file mode 100644 index 0000000..b05aff7 --- /dev/null +++ b/src/main/java/practiceproblems/AdvantageShuffle.java @@ -0,0 +1,59 @@ +package practiceproblems; + +// the advantage of A with respect to B is the number of indices i for which A[i] > B[i]. +/** + * If the smallest card a in A beats the smallest card b in B, we should pair them. + * Otherwise, a is useless for our score, as it can't beat any cards. + * Why should we pair a and b if a > b? + * Because every card in A is larger than b, any card we place in front of b will score a point. + * We might as well use the weakest card to pair with b as it makes the rest of the cards in A strictly larger, + * and thus have more potential to score points. + */ + +import java.util.Arrays; +import java.util.PriorityQueue; + +// Return any permutation of A that maximizes its advantage with respect to B. +//Input: A = [12,24,8,32], B = [13,25,32,11] +//Output: [24,32,8,12] +// Input: A = [2,7,11,15], B = [1,10,4,11] +// Output: [2,11,7,15] +public class AdvantageShuffle { + public static int[] advantageCount(int[] A, int[] B) { + Arrays.sort(A); + + PriorityQueue pq = new PriorityQueue<>((a, b) -> Integer.compare(b[0], a[0])); + for (int i = 0; i < B.length; i++) { + pq.offer(new Integer[]{B[i], i}); // add elements of B along with its index to max queue + } + int[] result = new int[A.length]; // new placeholder for result + int lo = 0; + int hi = A.length - 1; // start and end index + //B is transformed to [32,25,13,11] + //A is transformed to [8,12,24,32] + while (!pq.isEmpty()) { + Integer[] temp = pq.poll(); + int index = temp[1]; + int val = temp[0]; + /** + * Two Rules: + * 1) we should satisfy the biggest element first, because that's the hardest to satisfy + * 2) If bigger element is not satisfiable we should put min element there and move on + */ + if (A[hi] > val) { // if polled element is lesser thar A[hi], put A[hi] at index of + // queued elements index, means, equal to B's current index we are putting + // a value greater that B's in result arrays + result[index] = A[hi--]; + } else { + // else we put the lowest value at this position because no matter we try + // we won't be getting a value larger than 'val' + result[index] = A[lo++]; + } + } + return result; + } + + public static void main(String[] args) { + advantageCount(new int[]{12,24,8,32}, new int[]{13,25,32,11}); + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/AircraftMovieDuration.java b/src/main/java/practiceproblems/AircraftMovieDuration.java new file mode 100644 index 0000000..517b470 --- /dev/null +++ b/src/main/java/practiceproblems/AircraftMovieDuration.java @@ -0,0 +1,61 @@ +package practiceproblems; + +import java.util.*; + +/** + * You are on a flight and wanna watch two movies during this flight. + * You are given List movieDurations which includes all the movie durations. + * You are also given the duration of the flight which is d in minutes. + * Now, you need to pick two movies and the total duration of the two movies is less than or equal to (d - 30min). + *

+ * Find the pair of movies with the longest total duration and return they indexes. If multiple found, return the pair with the longest movie. + */ +public class AircraftMovieDuration { + + public static void main(String[] args) { + int[] movie_duration1 = {90, 85, 75, 60, 120, 150, 125}; + int d1 = 250; + int[] movie_duration2 = {90, 85, 75, 60, 155, 150, 125}; + int d2 = 250; + int[] movie_duration3 = {90, 85, 75, 60, 120, 110, 110, 150, 125}; + int d3 = 250; + System.out.println(Arrays.toString(get2SumClosest(movie_duration1, d1 - 30))); + System.out.println(Arrays.toString(get2SumClosest(movie_duration2, d2 - 30))); + System.out.println(Arrays.toString(get2SumClosest(movie_duration3, d3 - 30))); + } + + private static int[] get2SumClosest(int[] movie_duration, int d) { + // we need to preserve the input order before sorting + //Noticed simply using hashmap does not work if you need to return the index of same value, + // we need to track all index with same value. + Map> map = new HashMap<>(); + for (int i = 0; i < movie_duration.length; i++) { + map.putIfAbsent(movie_duration[i], new ArrayList<>()); + map.get(movie_duration[i]).add(i); + } + Arrays.sort(movie_duration); + int l = 0, r = movie_duration.length - 1; + int max = 0; + int[] res = new int[]{-1, -1}; + while (l < r) { + int sum = movie_duration[l] + movie_duration[r]; + if ((sum > max || (sum == max && movie_duration[r] > res[1])) && sum <= d) { + max = sum; + res[0] = movie_duration[l]; + res[1] = movie_duration[r]; + } + if (sum > d) + r--; + else + l++; + } + if (map.get(res[0]) == map.get(res[1])) { // checking if both values contains same list, could improve a bit + res[0] = map.get(res[0]).get(0); + res[1] = map.get(res[1]).get(1); + } else { + res[0] = map.get(res[0]).get(0); + res[1] = map.get(res[1]).get(0); + } + return res; + } +} diff --git a/src/practiceproblems/AircraftOptimization.java b/src/main/java/practiceproblems/AircraftOptimization.java similarity index 100% rename from src/practiceproblems/AircraftOptimization.java rename to src/main/java/practiceproblems/AircraftOptimization.java diff --git a/src/practiceproblems/AlternateOddAndEvenNumbers.java b/src/main/java/practiceproblems/AlternateOddAndEvenNumbers.java similarity index 75% rename from src/practiceproblems/AlternateOddAndEvenNumbers.java rename to src/main/java/practiceproblems/AlternateOddAndEvenNumbers.java index 8b66205..6361814 100644 --- a/src/practiceproblems/AlternateOddAndEvenNumbers.java +++ b/src/main/java/practiceproblems/AlternateOddAndEvenNumbers.java @@ -6,10 +6,10 @@ * https://www.geeksforgeeks.org/rearrange-positive-and-negative-numbers-publish/ * An array contains both positive and negative numbers in random order. * Rearrange the array elements so that positive and negative numbers are placed alternatively. - * If there are more positive numbers they appear at the end of the array. + * If there are more positive numbers they appear at the end of the array. * If there are more negative numbers, they too appear in the end of the array. - * [-1, 2, -3, 4, 5, 6, -7, 8, 9] - * output [9, -7, 8, -3, 5, -1, 2, 4, 6] or[4, -3, 5, -1, 6, -7, 2, 8, 9] + * [-1, 2, -3, 4, 5, 6, -7, 8, 9] + * output [9, -7, 8, -3, 5, -1, 2, 4, 6] or[4, -3, 5, -1, 6, -7, 2, 8, 9] */ class AlternateOddAndEvenNumbers { @@ -24,11 +24,10 @@ static void rearrange(int arr[], int n) { i++; } } - // we have segregated positive and negative elements - System.out.println(Arrays.toString(arr)+" :i - "+i); - // now the 'pos' indicates start of positive integer, 'neg' starts from 0; - int pos = i , neg = 0; - + // we have segregated positive and negative elements + System.out.println(Arrays.toString(arr) + " :i - " + i); + // now the 'pos' indicates start of positive integer, 'neg' starts from 0 + int pos = i, neg = 0; while (pos < n && neg < pos && arr[neg] < 0) { @@ -42,9 +41,9 @@ static void rearrange(int arr[], int n) { } public static void main(String[] args) { - int arr[] = { -1, 2, -3, 4, 5, 6, -7, 8, 9 }; + int arr[] = {-1, 2, -3, 4, 5, 6, -7, 8, 9}; int n = arr.length; rearrange(arr, n); - System.out.println("Array after rearranging: "+ Arrays.toString(arr)); + System.out.println("Array after rearranging: " + Arrays.toString(arr)); } } diff --git a/src/practiceproblems/AngleOfClock.java b/src/main/java/practiceproblems/AngleOfClock.java similarity index 54% rename from src/practiceproblems/AngleOfClock.java rename to src/main/java/practiceproblems/AngleOfClock.java index 3404e00..a162592 100644 --- a/src/practiceproblems/AngleOfClock.java +++ b/src/main/java/practiceproblems/AngleOfClock.java @@ -1,15 +1,16 @@ package practiceproblems; public class AngleOfClock { + public double angleClock(int hours, int minutes) { // every hour is 30(deg) (360 (deg)/12) because 12 hrs in clock // every min is 6(deg) (360(deg)/60) because 60 mins per hr // we take mod of 12 because 12th hr needs to be 0* - double hourHand= (hours%12 + (double)minutes/60)*30; - double minHand= minutes*6; - double absAngle= Math.abs(hourHand-minHand); - if(absAngle>180) absAngle= 360-absAngle; // this is because when time is 0.02 the angel will be 358 - + double hourHand = (hours % 12 + (double) minutes / 60) * 30; + double minHand = minutes * 6; + double absAngle = Math.abs(hourHand - minHand); + if (absAngle > 180) absAngle = 360 - absAngle; // this is because when time is 0.02 the angel will be 358 + return absAngle; - } + } } \ No newline at end of file diff --git a/src/main/java/practiceproblems/ArrangeInQueue.java b/src/main/java/practiceproblems/ArrangeInQueue.java new file mode 100644 index 0000000..3ee25ac --- /dev/null +++ b/src/main/java/practiceproblems/ArrangeInQueue.java @@ -0,0 +1,31 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ArrangeInQueue { + + // 1. Sort people by their height, shortest to tallest +// 2. Iterate and put each person to the correct position +// 2.a When placing the shortest person, all person to his left will be taller or equal height, since you are iterating in height sorted array, so put it at a index equal to its k value +// 2.b When placing the next shortest person, find a position, where count of positions to the left unoccupied plus the ones where same height person is placed, is equal to its k value +// 2.c Keep repeating + public static int[][] reconstructQueue(int[][] people) { + List result = new ArrayList<>(); + Arrays.sort(people, (a, b) -> { + if (a[0] == b[0]) return a[1] - b[1]; + else return b[0] - a[0]; + }); + System.out.println("Sorted values: " + Arrays.deepToString(people)); + for (int[] x : people) { + result.add(x[1], x); + System.out.println(Arrays.deepToString(result.toArray(new int[people.length][2]))); + } + return result.toArray(new int[people.length][2]); + } + + public static void main(String[] args) { + System.out.println(Arrays.deepToString(reconstructQueue(new int[][]{{7, 0}, {4, 4}, {7, 1}, {5, 0}, {6, 1}, {5, 2}}))); + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/BackspaceCompare.java b/src/main/java/practiceproblems/BackspaceCompare.java new file mode 100644 index 0000000..9d9b108 --- /dev/null +++ b/src/main/java/practiceproblems/BackspaceCompare.java @@ -0,0 +1,33 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/backspace-string-compare/ + */ +class BackspaceCompare { + + public static boolean backspaceCompare(String S, String T) { + int count1 = 0; // stores the number of # in string 1 + int count2 = 0; // stores the number of # in string 2 + for (int p1 = S.length() - 1, p2 = T.length() - 1; p1 >= 0 || p2 >= 0; p1--, p2--) { + + while (p1 >= 0 && (count1 != 0 || S.charAt(p1) == '#')) { + if (S.charAt(p1) == '#') count1++; + else count1--; + p1--; + } + while (p2 >= 0 && (count2 != 0 || T.charAt(p2) == '#')) { + if (T.charAt(p2) == '#') count2++; + else count2--; + p2--; + } + if (p1 < 0 && p2 < 0) return true; + if (p1 < 0 || p2 < 0) return false; + if (S.charAt(p1) != T.charAt(p2)) return false; + } + return true; + } + + public static void main(String[] args) { + System.out.println(backspaceCompare("a##c", "#a#c")); + } +} \ No newline at end of file diff --git a/src/practiceproblems/BasicCalculator.java b/src/main/java/practiceproblems/BasicCalculator.java similarity index 96% rename from src/practiceproblems/BasicCalculator.java rename to src/main/java/practiceproblems/BasicCalculator.java index 53e1ac3..d7acc24 100644 --- a/src/practiceproblems/BasicCalculator.java +++ b/src/main/java/practiceproblems/BasicCalculator.java @@ -18,7 +18,7 @@ public static int calculate(String s) { int sign = 1; int number = 0; int result = 0; - // let's take an edge case 2-(5-6)=3; + // let's take an edge case 2-(5-6)=3 // at i=0 number=2 // i=1 char ='-' update with prev seen sign res=sign*number reset number we are looking for next operand //i=2 char='(' and sign is '-', push prev result and sign and reset result for calclating @@ -28,7 +28,7 @@ public static int calculate(String s) { //i=5 update number to 6 // i=6 char=')' update result with existing number(res=5=> 5+(-1*6)) and sign inside the braces // then pop, which is last seen sign outside brace=> -1 and pop again to get result outside brace - // add all to result; + // add all to result for (int i = 0; i < s.length(); i++) { char temp = s.charAt(i); diff --git a/src/main/java/practiceproblems/BinaryTreeCousins.java b/src/main/java/practiceproblems/BinaryTreeCousins.java new file mode 100644 index 0000000..461ce74 --- /dev/null +++ b/src/main/java/practiceproblems/BinaryTreeCousins.java @@ -0,0 +1,45 @@ +package practiceproblems; + +import trees.TreeNode; + +import java.util.ArrayDeque; +import java.util.Deque; +/** + * https://leetcode.com/problems/cousins-in-binary-tree + */ +public class BinaryTreeCousins { + + public boolean isCousins(TreeNode root, int x, int y) { + + Deque queue = new ArrayDeque<>(); + queue.offer(root); + + while (!queue.isEmpty()) { + int n = queue.size(); + boolean xFound = false; + boolean yFound = false; + + for (int i = 0; i < n; i++) { + TreeNode temp = queue.poll(); + + if (temp.left != null && temp.right != null) { + if (temp.left.val == x && temp.right.val == y) return false; + if (temp.left.val == y && temp.right.val == x) return false; + } + + if (temp.val == x) xFound = true; + if (temp.val == y) yFound = true; + + if (temp.left != null) + queue.addLast(temp.left); + if (temp.right != null) + queue.addLast(temp.right); + } + + if (xFound && yFound) return true; + if (yFound || xFound) return false; + } + + return true; + } +} \ No newline at end of file diff --git a/src/practiceproblems/BitonicSearch.java b/src/main/java/practiceproblems/BitonicSearch.java similarity index 97% rename from src/practiceproblems/BitonicSearch.java rename to src/main/java/practiceproblems/BitonicSearch.java index 6461359..91a6ac8 100644 --- a/src/practiceproblems/BitonicSearch.java +++ b/src/main/java/practiceproblems/BitonicSearch.java @@ -1,6 +1,7 @@ package practiceproblems; /* A Bitonic Sequence is a sequence of numbers which is first strictly increasing then after a point strictly decreasing.*/ + public class BitonicSearch { static int ascendingBinarySearch(int[] arr, int low, int high, int key) { @@ -41,7 +42,7 @@ static int descendingBinarySearch(int[] arr, int low, int high, int key) { // } else { // low = mid + 1; // } - //else if decending + //else if descending // if (arr[mid] < key) { // high = mid - 1; // } else { @@ -83,7 +84,7 @@ static int searchBitonic(int arr[], int n, int key, int index) { } public static void main(String args[]) { - int[] arr = { -3, 3, 9, 8, 20, 17, 5, 3, 1 }; + int[] arr = {-3, 3, 9, 8, 20, 17, 5, 3, 1}; int key = 3; int n = arr.length; int l = 0; diff --git a/src/main/java/practiceproblems/BuildArray.java b/src/main/java/practiceproblems/BuildArray.java new file mode 100644 index 0000000..5bd3ba1 --- /dev/null +++ b/src/main/java/practiceproblems/BuildArray.java @@ -0,0 +1,62 @@ +package practiceproblems; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/build-array-from-permutation/ + * + * tricky + */ +public class BuildArray { + + public static int[] buildArray(int[] nums) { + int n = nums.length; + int i = 0; + /** + * To achieve O(1) space complexicity ,we need to store two values i.e. nums[i] and nums[nums[i]] in the same spot . + * we can do this by + * nums[i] = nums[i] + n *(nums[nums[i]] % n); + * + * In this both values i.e. nums[i] and nums[nums[i]] are being stored + * For eg. + * + * input = [0,2,1,5,3,4] + * Output: [0,1,2,4,5,3] + * + * here, let i=3, + * then nums[3] = 5; + * and nums[nums[3]] = 4; + * + * Now we store both of them in nums[i] itself by + * nums[i] = nums[i] + n *(nums[nums[i]] % n); //Equation 1 + * + * nums[3] = 5 + 6 *(4 %6); + * nums[3] = 29 + * Now in Second loop we Can retrieve nums[nums[i]] by dividing by n, + * nums[i] = nums[i] + n *(nums[nums[i]] % n) / n; + * nums[i] = 0 + nums[nums[i]]; + * nums[i]= nums[nums[i]; + * + * nums[3]/n = 29/6 =4; + */ + + while (i < nums.length) { + int temp = nums[i] + n * (nums[nums[i]] % n); + nums[i] = temp; + i++; + } + + System.out.println(Arrays.toString(nums)); + + i = 0; + while (i < nums.length) { + nums[i] /= n; + i++; + } + return nums; + } + + public static void main(String[] args) { + System.out.println(Arrays.toString(buildArray(new int[]{5, 0, 1, 2, 3, 4}))); + } +} diff --git a/src/main/java/practiceproblems/CanPlaceFlower.java b/src/main/java/practiceproblems/CanPlaceFlower.java new file mode 100644 index 0000000..2c7afc5 --- /dev/null +++ b/src/main/java/practiceproblems/CanPlaceFlower.java @@ -0,0 +1,61 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/can-place-flowers/submissions/ + */ +public class CanPlaceFlower { + + public boolean canPlaceFlowers(int[] flowerbed, int n) { + + int flowerCounts = 0; + + for (int i = 0; i < flowerbed.length && flowerCounts < n; i++) { + if (flowerbed[i] == 0) { + int prev = i > 0 ? flowerbed[i - 1] : 0; + int next = i < flowerbed.length - 1 ? flowerbed[i + 1] : 0; + + if (prev == 0 && next == 0) { + flowerbed[i] = 1; + flowerCounts++; + } + } + } + + + return flowerCounts == n; + } + + /** + * This is the logic the code is using- + * + * If there are "count" zeroes in between two 1s, + * then how many 1s can we place in those zeroes without violating the given condition? + * Answer is "(count-1)/2". + * The only cases this doesn't apply are when there are zeroes(1 or more) + * At the beginning of the array. + * At the end of the array. + * + * For these 2 cases,the number of 1s that we can place is count/2. + * But to generalize the algorithm and to simplify code inside loop, + * count has been initialized to 1 for the first time and result += (count-1)/2 effectively becomes result += count/2 for the case 1. + * For case 2, result is updated outside the loop, again by count/2 times. + * + * Finally, we check if the number of possible 1s that we can place is greater than or equal to n. If so, we return true else false. + * + * smart to set count = 1 to solve the problem that the beginning of flowerbed is 0 + */ + public boolean canPlaceFlowersNonMutating(int[] flowerbed, int n) { + int count = 1; + int result = 0; + for (int j : flowerbed) { + if (j == 0) { + count++; + } else { + result += (count - 1) / 2; + count = 0; + } + } + if(count != 0) result += count/2; + return result>=n; + } +} diff --git a/src/practiceproblems/Candy.java b/src/main/java/practiceproblems/Candy.java similarity index 84% rename from src/practiceproblems/Candy.java rename to src/main/java/practiceproblems/Candy.java index 0e804ef..c8c04f6 100644 --- a/src/practiceproblems/Candy.java +++ b/src/main/java/practiceproblems/Candy.java @@ -3,14 +3,14 @@ import java.util.Arrays; /** - * https://www.hackerrank.com/challenges/candies/problem + * https://leetcode.com/problems/candy/ * Alice wants to give at least 1 candy to each child. - * If two children sit next to each other, then + * If two children sit next to each other, then * the one with the higher rating must get more candies than neighbour (left and right). * Alice wants to minimize the total number of candies she must buy. - - For example, assume her students' ratings are [4, 6, 4, 5, 6, 2]. - She gives the students candy in the following minimal amounts: [1, 2, 1, 2, 3, 1]. She must buy a minimum of 10 candies. + *

+ * For example, assume her students' ratings are [4, 6, 4, 5, 6, 2]. + * She gives the students candy in the following minimal amounts: [1, 2, 1, 2, 3, 1]. She must buy a minimum of 10 candies. */ class Candy { @@ -52,7 +52,7 @@ int candy(int[] ratings) { public static void main(String[] args) { Candy candy = new Candy(); - int[] ratings = { 2, 4, 2, 6, 1, 7, 8, 9, 2, 1 }; + int[] ratings = {2, 4, 2, 6, 1, 7, 8, 9, 2, 1}; System.out.println(candy.candy(ratings)); } } \ No newline at end of file diff --git a/src/practiceproblems/CelebrityProblem.java b/src/main/java/practiceproblems/CelebrityProblem.java similarity index 53% rename from src/practiceproblems/CelebrityProblem.java rename to src/main/java/practiceproblems/CelebrityProblem.java index 91a464b..1236cca 100644 --- a/src/practiceproblems/CelebrityProblem.java +++ b/src/main/java/practiceproblems/CelebrityProblem.java @@ -1,9 +1,11 @@ package practiceproblems; +/** + * tricky + */ public class CelebrityProblem { /** * @param n a party with n people - * * @return the celebrity's label or -1 */ public int findCelebrity(int n) { @@ -23,6 +25,29 @@ public int findCelebrity(int n) { return candidate; } + public int findCelebrityGraph(int n) { + int[] inDegree = new int[n]; + int[] outDegree = new int[n]; + + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (j == i) continue; + + if (knows(j, i)) { + outDegree[j]++; + inDegree[i]++; + } + } + } + + for (int i = 0; i < n; i++) { + if (inDegree[i] == n - 1 && outDegree[i] == 0) + return i; + } + + return -1; + } + public boolean knows(int candidate, int i) { return false; } diff --git a/src/practiceproblems/CheckPalindromePermutation.java b/src/main/java/practiceproblems/CheckPalindromePermutation.java similarity index 67% rename from src/practiceproblems/CheckPalindromePermutation.java rename to src/main/java/practiceproblems/CheckPalindromePermutation.java index 2e1e057..af22e51 100644 --- a/src/practiceproblems/CheckPalindromePermutation.java +++ b/src/main/java/practiceproblems/CheckPalindromePermutation.java @@ -1,5 +1,7 @@ package practiceproblems; +import java.util.Arrays; + /** * Given a string, determine if a permutation of the string could form a palindrome. * Input: "code" @@ -13,20 +15,18 @@ public class CheckPalindromePermutation { // Thus, in case of a palindrome, the number of characters with odd number of occurrences can't exceed 1 public boolean canPermutePalindrome(String s) { - if(s==null || s.length()==0) return false; - int[] cache= new int[128]; - - for(char ch: s.toCharArray()){ - cache[ch]++; - } - - int oddCOunt=0; + int[] cache = new int[26]; - for(int i=0;i<128;i++){ - oddCOunt+= cache[i]%2; - if(oddCOunt>1) return false; + for(char t: s.toCharArray()){ + if(cache[t-'a']>0){ + cache[t-'a']--; + }else{ + cache[t-'a']++; + } } - - return true; + + int result = Arrays.stream(cache).sum(); + + return result<=1; } } \ No newline at end of file diff --git a/src/main/java/practiceproblems/CloneGraph.java b/src/main/java/practiceproblems/CloneGraph.java new file mode 100644 index 0000000..d1de082 --- /dev/null +++ b/src/main/java/practiceproblems/CloneGraph.java @@ -0,0 +1,53 @@ +package practiceproblems; + +import java.util.*; + +/** + * https://leetcode.com/problems/clone-graph/ + */ +public class CloneGraph { + private static class Node { + public int val; + public List neighbors; + + public Node() { + val = 0; + neighbors = new ArrayList(); + } + + public Node(int _val) { + val = _val; + neighbors = new ArrayList(); + } + + public Node(int _val, ArrayList _neighbors) { + val = _val; + neighbors = _neighbors; + } + } + + public Node cloneGraph(Node node) { + if (node == null) { + return null; + } + Map cloned = new HashMap<>(); + Queue queue = new ArrayDeque<>(); + queue.offer(node); + Node clonedNode = new Node(node.val); + cloned.put(node, clonedNode); + while (!queue.isEmpty()) { + Node curr = queue.poll(); + for (Node nb : curr.neighbors) { + if (!cloned.containsKey(nb)) { + queue.offer(nb); + cloned.put(nb, new Node(nb.val)); + } + cloned.get(curr).neighbors.add(cloned.get(nb)); + } + } + return cloned.get(node); + + } + + +} \ No newline at end of file diff --git a/src/practiceproblems/ClosestNumbers.java b/src/main/java/practiceproblems/ClosestNumbers.java similarity index 100% rename from src/practiceproblems/ClosestNumbers.java rename to src/main/java/practiceproblems/ClosestNumbers.java diff --git a/src/practiceproblems/CompareVersions.java b/src/main/java/practiceproblems/CompareVersions.java similarity index 100% rename from src/practiceproblems/CompareVersions.java rename to src/main/java/practiceproblems/CompareVersions.java diff --git a/src/main/java/practiceproblems/CompleteBinaryTreeInserter.java b/src/main/java/practiceproblems/CompleteBinaryTreeInserter.java new file mode 100644 index 0000000..4ff17e1 --- /dev/null +++ b/src/main/java/practiceproblems/CompleteBinaryTreeInserter.java @@ -0,0 +1,59 @@ +package practiceproblems; + +import trees.TreeNode; + +import java.util.Deque; +import java.util.LinkedList; +import java.util.Queue; + +/** + * https://leetcode.com/problems/complete-binary-tree-inserter/ + * + * tricky + */ +public class CompleteBinaryTreeInserter { + + TreeNode root; + Deque queue; + + public CompleteBinaryTreeInserter(TreeNode root) { + this.root = root; + this.queue = new LinkedList<>(); + Queue tempQueue = new LinkedList<>(); + tempQueue.offer(root); + while (!tempQueue.isEmpty()) { + TreeNode temp = tempQueue.poll(); + + /** + * store only the nodes with incomplete children + */ + if (temp.right == null || temp.left == null) { + queue.offerLast(temp); + } + + + if (temp.left != null) tempQueue.offer(temp.left); + if (temp.right != null) tempQueue.offer(temp.right); + } + } + + public int insert(int v) { + + TreeNode deepNode = queue.peekFirst(); + queue.offerLast(new TreeNode(v)); + if (deepNode.left == null) { + deepNode.left = queue.peekLast(); + } else { + deepNode.right = queue.peekLast(); + queue.pollFirst(); + } + + return deepNode.val; + + } + + public TreeNode get_root() { + return root; + + } +} diff --git a/src/main/java/practiceproblems/ComplexNumberMultiply.java b/src/main/java/practiceproblems/ComplexNumberMultiply.java new file mode 100644 index 0000000..335645b --- /dev/null +++ b/src/main/java/practiceproblems/ComplexNumberMultiply.java @@ -0,0 +1,22 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/complex-number-multiplication/ + */ +public class ComplexNumberMultiply { + + public String complexNumberMultiply(String num1, String num2) { + String[] first = num1.split("\\+"); + String[] second = num2.split("\\+"); + int aSq = 0; + int bSq = -1; + int ab = 0; + + aSq += Integer.parseInt(first[0]) * Integer.parseInt(second[0]); + bSq *= Integer.parseInt(first[1].substring(0, first[1].length() - 1)) * Integer.parseInt(second[1].substring(0, second[1].length() - 1)); + ab += (Integer.parseInt(first[0]) * Integer.parseInt(second[1].substring(0, second[1].length() - 1))) + + (Integer.parseInt(second[0]) * Integer.parseInt(first[1].substring(0, first[1].length() - 1))); + + return (aSq + bSq) + "+" + ab + "i"; + } +} diff --git a/src/practiceproblems/ConstructBSTFromPreorder.java b/src/main/java/practiceproblems/ConstructBSTFromPreorder.java similarity index 63% rename from src/practiceproblems/ConstructBSTFromPreorder.java rename to src/main/java/practiceproblems/ConstructBSTFromPreorder.java index 11750ea..8dfe00d 100644 --- a/src/practiceproblems/ConstructBSTFromPreorder.java +++ b/src/main/java/practiceproblems/ConstructBSTFromPreorder.java @@ -1,11 +1,12 @@ package practiceproblems; -import java.util.Stack; +import java.util.ArrayDeque; +import java.util.Deque; /** * https://leetcode.com/problems/construct-binary-search-tree-from-preorder-traversal/ * Return the root node of a binary search tree that matches the given preorder traversal. - * + *

* (Recall that a binary search tree is a binary tree where for every node, * any descendant of node.left has a value < node.val, * and any descendant of node.right has a value > node.val. @@ -15,37 +16,36 @@ public class ConstructBSTFromPreorder { public static void main(String[] args) { - int[] arr = { 8, 3, 1, 6, 4, 7, 10, 14, 13 }; + int[] arr = {8, 3, 1, 6, 4, 7, 10, 14, 13}; bstFromPreorder(arr); } public TreeNode bstFromPreorderRecursive(int[] preorder) { - return helper(preorder, 0, preorder.length - 1); - } - - private TreeNode helper(int[] preorder, int start, int end) { - if(start > end) return null; - - TreeNode node = new TreeNode(preorder[start]); - int i; - for(i=start;i<=end;i++) { - if(preorder[i] > node.val) - break; - } - - node.left = helper(preorder, start+1, i-1); - node.right = helper(preorder, i, end); - return node; - - - - } + return helper(preorder, 0, preorder.length - 1); + } + + private TreeNode helper(int[] preorder, int start, int end) { + if (start > end) return null; + + TreeNode node = new TreeNode(preorder[start]); + int i; + for (i = start; i <= end; i++) { + if (preorder[i] > node.val) + break; + } + + node.left = helper(preorder, start + 1, i - 1); + node.right = helper(preorder, i, end); + return node; + + + } public static TreeNode bstFromPreorder(int[] preorder) { if (preorder == null || preorder.length == 0) { return null; } - Stack stack = new Stack<>(); + Deque stack = new ArrayDeque<>(); TreeNode root = new TreeNode(preorder[0]); stack.push(root); //8, 3, 1, 6, 4, 7, 10, 14, 13 @@ -64,18 +64,19 @@ public static TreeNode bstFromPreorder(int[] preorder) { } return root; } -} -class TreeNode { - TreeNode left; - TreeNode right; - int val; + static class TreeNode { + TreeNode left; + TreeNode right; + int val; - public TreeNode(int val) { - this.val = val; - } + public TreeNode(int val) { + this.val = val; + } - public String toString() { - return val + ""; + public String toString() { + return val + ""; + } } -} \ No newline at end of file +} + diff --git a/src/main/java/practiceproblems/ConstructTreeFromInorderAndPostorder.java b/src/main/java/practiceproblems/ConstructTreeFromInorderAndPostorder.java new file mode 100644 index 0000000..1180448 --- /dev/null +++ b/src/main/java/practiceproblems/ConstructTreeFromInorderAndPostorder.java @@ -0,0 +1,70 @@ +package practiceproblems; + +import trees.TreeNode; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; + +public class ConstructTreeFromInorderAndPostorder { + int postorderIndex; + + public TreeNode buildTree(int[] inorder, int[] postorder) { + + postorderIndex = postorder.length - 1; + // build a hashmap to store value -> its index relations + Map inorderIndexMap = new HashMap<>(); + for (int i = 0; i < inorder.length; i++) { + inorderIndexMap.put(inorder[i], i); + } + + return arrayToTree(postorder, 0, postorder.length - 1, inorderIndexMap); + } + + private TreeNode arrayToTree(int[] postorder, int left, int right, Map inorderIndexMap) { + // if there are no elements to construct the tree + if (left > right) return null; + + // select the preorder_index element as the root and increment it + int rootValue = postorder[postorderIndex]; + postorderIndex--; + TreeNode root = new TreeNode(rootValue); + + // build left and right subtree + // excluding inorderIndexMap[rootValue] element because it's the root + // right has to be built first + /** + * The intuition behind it is that since postorder: LEFT → RIGHT → ROOT, + * so when we go in reverse order, we must construct the tree in the order of: ROOT → RIGHT → LEFT + */ + root.right = arrayToTree(postorder, inorderIndexMap.get(rootValue) + 1, right, inorderIndexMap); + root.left = arrayToTree(postorder, left, inorderIndexMap.get(rootValue) - 1, inorderIndexMap); + return root; + } + + public TreeNode buildTreeIterative(int[] inorder, int[] postorder) { + if (inorder.length == 0) return null; + int j = postorder.length - 1; + Deque stack = new ArrayDeque<>(); + TreeNode root = new TreeNode(postorder[j--]); + stack.push(root); + TreeNode node = null; + for (int i = inorder.length - 1; j >= 0; j--) { + TreeNode cur = new TreeNode(postorder[j]); + while (!stack.isEmpty() && stack.peek().val == inorder[i]) { + node = stack.pop(); + i--; + } + if (node != null) { + node.left = cur; + node = null; + } else { + stack.peek().right = cur; + } + stack.push(cur); + } + return root; + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/ConstructTreeFromInorderAndPreorder.java b/src/main/java/practiceproblems/ConstructTreeFromInorderAndPreorder.java new file mode 100644 index 0000000..7d8976b --- /dev/null +++ b/src/main/java/practiceproblems/ConstructTreeFromInorderAndPreorder.java @@ -0,0 +1,76 @@ +package practiceproblems; + +import trees.TreeNode; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ + */ +class ConstructTreeFromInorderAndPreorder { + + // The basic idea is here: + // Say we have 2 arrays, PRE and IN. + // Preorder traversing implies that PRE[0] is the root node. + // Then we can find this PRE[0] in IN, say it's IN[5]. + // Now we know that IN[5] is root, so we know that IN[0] - IN[4] is on the left + // side, IN[6] to the end is on the right side. + // Recursively doing this on sub arrays, we can build a tree out of it :) + int index = 0; + + public TreeNode buildTree(int[] preorder, int[] inorder) { + Map hm = new HashMap<>(); + + if (preorder == null || preorder.length == 0) { + return null; + } + + for (int i = 0; i < inorder.length; i++) { + hm.put(inorder[i], i); + } + + return buildTreeHelper(preorder, 0, inorder.length - 1, hm); + } + + public TreeNode buildTreeHelper(int[] preorder, int left, int right, Map hm) { + if (right < left) { + return null; + } + if (index >= preorder.length) return null; + int currValue = preorder[index++]; + TreeNode node = new TreeNode(currValue); + node.left = buildTreeHelper(preorder, left, hm.get(currValue) - 1, hm); + node.right = buildTreeHelper(preorder, hm.get(currValue) + 1, right, hm); + + return node; + } + + public TreeNode buildTreeAlter(int[] preorder, int[] inorder) { + + if(preorder.length == 0 || inorder.length == 0) + return null; + + TreeNode root = new TreeNode(preorder[0]); + + int mid = 0; + int len = inorder.length; + for(int i = 0; i < len; i++) + { + if(inorder[i] == root.val) + { + mid = i; + break; + } + } + //can do copyRange in different lines + root.left = buildTreeAlter(Arrays.copyOfRange(preorder, 1, mid+1), Arrays.copyOfRange(inorder, 0, mid)); + root.right = buildTreeAlter(Arrays.copyOfRange(preorder, mid+1, len), Arrays.copyOfRange(inorder, mid+1,len)); + + return root; + } + +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/ContainerWithMostWater.java b/src/main/java/practiceproblems/ContainerWithMostWater.java new file mode 100644 index 0000000..002323c --- /dev/null +++ b/src/main/java/practiceproblems/ContainerWithMostWater.java @@ -0,0 +1,30 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/container-with-most-water/ + * tricky + */ +public class ContainerWithMostWater { + + public int maxArea(int[] height) { + if (height == null || height.length == 0) return 0; + int i = 0; + int j = height.length - 1; + int result = 0; + + while (i < j) { + + int waterVol = (j - i) * Math.min(height[i], height[j]); // width * height + result = Math.max(waterVol, result); + + if (height[i] > height[j]) { // the reason we are moving lesser side is + // j-i is going to be decreasing, so we need to + // maintain higher side to have max value + j--; + } else { + i++; + } + } + return result; + } +} diff --git a/src/practiceproblems/ConvertXToY.java b/src/main/java/practiceproblems/ConvertXToY.java similarity index 89% rename from src/practiceproblems/ConvertXToY.java rename to src/main/java/practiceproblems/ConvertXToY.java index e39b336..e9c3928 100644 --- a/src/practiceproblems/ConvertXToY.java +++ b/src/main/java/practiceproblems/ConvertXToY.java @@ -53,17 +53,18 @@ private static int minOperations(int src, int target) { public static void main(String[] args) { // int x = 2, y = 5; int x = 4, y = 7; - Steps src = new Steps(x, y); System.out.println(minOperations(x, y)); } -} -class Steps { - int val; - int steps; + static class Steps { + int val; + int steps; - public Steps(int val, int steps) { - this.val = val; - this.steps = steps; + public Steps(int val, int steps) { + this.val = val; + this.steps = steps; + } } } + + diff --git a/src/practiceproblems/CountAllPathsFrom2DMatrix.java b/src/main/java/practiceproblems/CountAllPathsFrom2DMatrix.java similarity index 95% rename from src/practiceproblems/CountAllPathsFrom2DMatrix.java rename to src/main/java/practiceproblems/CountAllPathsFrom2DMatrix.java index 1b5bc0c..fbbf937 100644 --- a/src/practiceproblems/CountAllPathsFrom2DMatrix.java +++ b/src/main/java/practiceproblems/CountAllPathsFrom2DMatrix.java @@ -29,7 +29,7 @@ static int numberOfPaths(int m, int n) { for (int j = 1; j < n; j++) // By uncommenting the last part the - // code calculatest he total possible paths + // code calculates the total possible paths // if the diagonal Movements are allowed count[i][j] = count[i - 1][j] + count[i][j - 1]; //+ count[i-1][j-1]; } diff --git a/src/practiceproblems/CountAndSay.java b/src/main/java/practiceproblems/CountAndSay.java similarity index 99% rename from src/practiceproblems/CountAndSay.java rename to src/main/java/practiceproblems/CountAndSay.java index 28ed6ff..dcf4a3a 100644 --- a/src/practiceproblems/CountAndSay.java +++ b/src/main/java/practiceproblems/CountAndSay.java @@ -3,6 +3,7 @@ /** * https://leetcode.com/problems/count-and-say/ + * tricky */ public class CountAndSay { public String countAndSay(int n) { diff --git a/src/main/java/practiceproblems/CountBinaryStrings.java b/src/main/java/practiceproblems/CountBinaryStrings.java new file mode 100644 index 0000000..5428a1f --- /dev/null +++ b/src/main/java/practiceproblems/CountBinaryStrings.java @@ -0,0 +1,56 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/count-binary-substrings + * tricky + */ +public class CountBinaryStrings { + + /** + * The problem can be solved by observing the examples carefully - + * 1. 0011 + * In this string, consecutive count of binary characters are [2, 2]. We can form a total of 2 substrings. + * 2. 00011 + * In this string, consecutive count of binary characters are [3, 2]. Still, we can only form 2 substrings. + * 3. 000111 + * Here, consecutive count of binary characters are as - [3,3]. Now, we can form 3 substrings. + * 4. 00011100 + * Consecutive count of binary characters are - [3,3,2]. We can form 3 substrings with the first 2 groups of zeros and ones. + * Then we can form 2 substrings with the latter 2 groups. So, a total of 5 substrings. + * 5. 00011100111 + * Consecutive count - [3,3,2,3]. Substrings formed - 3 + 2 + 2 = 7 + * We can observe from the above examples that our final count will only depend on the consecutive counts of binary characters. + * With each two groups of consecutive characters, the number of substrings that can be formed + * will be minimum of count among the two groups. + */ + public int countBinarySubstrings(String s) { + + int i = 1; + int prevCount = 0; + int currCount = 1; + int result = 0; + + while (i < s.length()) { + + if (s.charAt(i - 1) != s.charAt(i)) { + /** + * s[i] != s[i - 1] :Whenever current character is not equal to previous - + * We know that we atleast have group of 2 different characters having consecutiveCount >= 1. + * The number of substrings that can be formed from these would be equal to minimum of currentConsecutiveCount & prevConsecutiveCount. + * So just add that amount to ans. Now prevConsecutiveCount will become equal to + * currentConsecutiveCount and reset the currentConsecutiveCount to 1. + */ + result += Math.min(prevCount, currCount); + prevCount = currCount; + currCount = 1; + } else { + //s[i] == s[i - 1] : When current character is equal to previous - just increment the current consecutive count. + currCount++; + } + i++; + } + + result += Math.min(prevCount, currCount); + return result; + } +} diff --git a/src/main/java/practiceproblems/CountElements.java b/src/main/java/practiceproblems/CountElements.java new file mode 100644 index 0000000..9a0de2f --- /dev/null +++ b/src/main/java/practiceproblems/CountElements.java @@ -0,0 +1,25 @@ +package practiceproblems; + + +/** + * https://leetcode.com/problems/counting-elements/ + */ +public class CountElements { + + public static int countElements(int[] arr) { + int[] count = new int[1002]; + for(int num : arr) { + count[num]++; + } + + int res = 0; + for(int num : arr) { + if (count[num + 1] > 0) res++; + } + return res; + } + + public static void main(String[] args) { + System.out.println(countElements(new int[]{1, 3, 2, 3, 5, 0})); + } +} \ No newline at end of file diff --git a/src/practiceproblems/CountMinimumStepsToFormDesiredInputArray.java b/src/main/java/practiceproblems/CountMinimumStepsToFormDesiredInputArray.java similarity index 88% rename from src/practiceproblems/CountMinimumStepsToFormDesiredInputArray.java rename to src/main/java/practiceproblems/CountMinimumStepsToFormDesiredInputArray.java index 629487a..1abf2aa 100644 --- a/src/practiceproblems/CountMinimumStepsToFormDesiredInputArray.java +++ b/src/main/java/practiceproblems/CountMinimumStepsToFormDesiredInputArray.java @@ -1,10 +1,12 @@ -package practiceproblems;/* Java program to count minimum number of operations -to get the given arr array */ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/count-minimum-steps-get-given-desired-array/ + */ -/*https://www.geeksforgeeks.org/count-minimum-steps-get-given-desired-array/*/ // unsolved class CountMinimumStepsToFormDesiredInputArray { - static int arr[] = new int[] { 16, 16, 16 }; + static int arr[] = new int[]{16, 16, 16}; // Returns count of minimum operations to covert a // zero array to arr array with increment and diff --git a/src/practiceproblems/DivideSubArrayAverage.java b/src/main/java/practiceproblems/DivideSubArrayAverage.java similarity index 100% rename from src/practiceproblems/DivideSubArrayAverage.java rename to src/main/java/practiceproblems/DivideSubArrayAverage.java diff --git a/src/main/java/practiceproblems/DoubledPairArray.java b/src/main/java/practiceproblems/DoubledPairArray.java new file mode 100644 index 0000000..5059083 --- /dev/null +++ b/src/main/java/practiceproblems/DoubledPairArray.java @@ -0,0 +1,108 @@ +package practiceproblems; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * https://leetcode.com/problems/array-of-doubled-pairs + * + * tricky offset/sort + */ +public class DoubledPairArray { + /** + * Question is essentially asking to find a pair of doubles, in question they twisted it by providing a formula + * arr[2 * i + 1] = 2 * arr[2 * i]. + * What the formula essentially means is find a pair for given A[i] + * + * if 2i == j or i == 2j (reverse to accommodate negatives) then we have solution + * + * The edge case here is that the elements may be negative in the array + * + * We greedily process elements starting from the smallest value, WHY smallest value but not an arbitrary value? + * + * Because since it's the smallest values, let say x, there is only one choice to pair with x: + * If x is a positive number, then it pairs with y = x*2, for example: x = 4 pair with y = 8. + * If x is a non-positive number, then it pairs with y = x/2, for example: x = -8 pair with y = -4. + * (for arr = [-2, -1], -2 is the smallest, this need to be processed first, then it returns valid.) + * + * If there is no corresponding y then it's IMPOSSIBLE, return FALSE. + * If it's an arbitrary value, let say x, there are two choices, + * either x/2 or x*2 is also a good pairing with x (no matter if x is a possible or negative number), + * if we choose x/2 or x*2 to pair with x, it maybe WRONG, because some other elements may need it to make pair. + * + * For example: arr = [2, 4, 1, 8] + * If we process x = 2 first, then there are 2 choices, + * either 4 or 1 can be paired with 2, if we choose 4 -> we got WRONG ANSWER. + * + * Because 8 needs 4, so 2 should be paired with 1. + * So we need to sort our arr array first. + * + * When a pair of (x and y) match, we need to decrease their count. + * So we need to use a HashTable data structure to count the frequency of elements in the arr array. + * + * @param arr + * @return + */ + public static boolean canReorderDoubled(int[] arr) { + Arrays.sort(arr); + var map = new HashMap(); + + for (int x : arr) map.put(x, map.getOrDefault(x, 0) + 1); + + for (int elem : arr) { + + if (map.get(elem) == 0) continue; + + if (elem < 0 && elem % 2 != 0) return false; + + int value = elem < 0 ? elem / 2 : elem * 2; + + if (map.getOrDefault(value, 0) == 0) return false; + + map.put(elem, map.get(elem) - 1); + map.put(value, map.get(value) - 1); + + } + + return true; + } + + public static void main(String[] args) { + canReorderDoubled(new int[]{4,-2,2,-4}); + } + + /** + * The same approach as above but without sorting + */ + public static boolean canReorderDoubledWithoutSorting(int[] A) { + int offset=100000; + // Count the frequency of each number + int[] freq= new int[2*offset]; + for (int n: A) freq[n+offset]++; // n+offset is to accommodate negative values inside array + // -10 becomes 99990 + + // deal with "0", there must be even 0s in array + if (freq[0]%2==1) return false; + + // from -100000 to 100000 + for (int i=0; i<2*offset; i++){ + // if there's no current number left, skip + if (freq[i]==0) continue; + + // otherwise, calculate current number, and it's pair number, then get their frequencies + int cur= i-offset; + int next= cur<0?cur/2:cur*2; + + int curCnt= freq[i]; + int nextCnt= freq[next+offset]; + + // if not enough pair number left, return false + if (nextCnt= 0; i--) { + dp[i][n - 1] = Math.max(1, dp[i + 1][n - 1] - dungeon[i][n - 1]); + } + + // Populate the last row + for (int i = n - 2; i >= 0; i--) { + dp[m - 1][i] = Math.max(1, dp[m - 1][i + 1] - dungeon[m - 1][i]); + } + + // to achieve the answer, we need to setup the last row and last column + // we know to reach last cell we need 6 as energy, let's say that comes + // from cell above it, that cell's original val is +1, so we must have + // 5 energy when we reach there and adding it up, it became 6 + // the reason to put 1 on last row is, the value in that cell is 30 + // so to reach last cell from that cell, we need only 6 energy(min) + // to have 6 from +30, player should have health of -24 and player cannot + // have neg val, so we put 1 as filler + // |* * 2 | + // |* * 5 | + // |1 1 6 | + + // Populate the rest by taking max of bottom and right (reverse of down and left) + + for (int i = m - 2; i >= 0; i--) { + for (int j = n - 2; j >= 0; j--) { + dp[i][j] = Math.max(1, Math.min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j]); + } + } + + return dp[0][0]; + } + + /** + * tricky + */ + public int calculateMinimumHPRecursion(int[][] dungeon) { + int height = dungeon.length; + int width = dungeon[0].length; + // minimal health required to reach this point + Integer[][] minHealth = new Integer[height][width]; + + return calculateMinHealth(0, 0, dungeon, minHealth); + } + + private int calculateMinHealth(int i, int j, int[][] dungeon, Integer[][] minHealth) { + // base case + if (i == (dungeon.length - 1) && j == (dungeon[0].length - 1)) { + return dungeon[i][j] >= 0 ? 1 : (1 - dungeon[i][j]); + } + + // transition + // corner case, i or j out of bound, return very large number, that will never be used + if (i == dungeon.length || j == dungeon[0].length) { + return Integer.MAX_VALUE; + } + + // check cache + // min health requires at least 1 + if (minHealth[i][j] != null) { + return minHealth[i][j]; + } + + // real transition, from right or bottom + int rightMinHealth = calculateMinHealth(i, j + 1, dungeon, minHealth); + int bottomMinHealth = calculateMinHealth(i + 1, j, dungeon, minHealth); + int currentRequiredHealth = Math.min(rightMinHealth, bottomMinHealth) - dungeon[i][j]; + // update cache + minHealth[i][j] = currentRequiredHealth <= 0 ? 1 : currentRequiredHealth; + + return minHealth[i][j]; + } +} \ No newline at end of file diff --git a/src/practiceproblems/DutchNationalFlag.java b/src/main/java/practiceproblems/DutchNationalFlag.java similarity index 51% rename from src/practiceproblems/DutchNationalFlag.java rename to src/main/java/practiceproblems/DutchNationalFlag.java index f8a6c53..9ae16fc 100644 --- a/src/practiceproblems/DutchNationalFlag.java +++ b/src/main/java/practiceproblems/DutchNationalFlag.java @@ -1,5 +1,9 @@ package practiceproblems; +/** + * https://leetcode.com/problems/sort-colors/ + * tricky + */ class DutchNationalFlag { public void sortColors(int[] arr) { if (arr.length == 0) { @@ -9,9 +13,19 @@ public void sortColors(int[] arr) { int i = 0; int j = arr.length - 1; int zeroPos = 0; + while (i <= j) { if (arr[i] > pivot) { swap(arr, i, j); + /** + * I guess to answer why we increment i when nums[i] == 0 and not do the same when nums[i] == 2, + * the easy way for me to remember is, after we swap the 2 we still need to check the current idx + * because it maybe 1 or 0 at the current index. + * But when nums[i] == 0, we pretty sure there are no 2 to the left of current idx since we walked from the left to right and + * already swapped all the 2. + */ + // no need to increment i here + // ex case [1,2,0] j--; } else if (arr[i] == pivot) { i++; diff --git a/src/main/java/practiceproblems/EvaluateRPN.java b/src/main/java/practiceproblems/EvaluateRPN.java new file mode 100644 index 0000000..7ce3b85 --- /dev/null +++ b/src/main/java/practiceproblems/EvaluateRPN.java @@ -0,0 +1,41 @@ +package practiceproblems; + +import java.util.ArrayDeque; + +/** + * https://leetcode.com/problems/evaluate-reverse-polish-notation + */ +public class EvaluateRPN { + public int evalRPN(String[] tokens) { + ArrayDeque s = new ArrayDeque<>(); + + for (String token : tokens) { + if ("+-*/".contains(token)) { + int second = s.pop(); + int first = s.pop(); + switch (token) { + case "+": + s.push(second + first); + break; + case "-": + s.push(first - second); + break; + case "*": + s.push(first * second); + break; + default: + s.push(first / second); + break; + } + + } else { + s.push(Integer.parseInt(token)); + } + + } + + return s.pop(); + + + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/Fenwick2D.java b/src/main/java/practiceproblems/Fenwick2D.java new file mode 100644 index 0000000..f7e6be1 --- /dev/null +++ b/src/main/java/practiceproblems/Fenwick2D.java @@ -0,0 +1,74 @@ +package practiceproblems; + +public class Fenwick2D { + + // Instance variables + int[][] tree; // bit tree, sumNums(0->i) will be stored at tree(i+1), tree is reference by Length + int[][] nums; // a deep clone of the input matrix. otherwise matrix might be updated by other process + int m; // num of rows + int n; // num of cols + + // Constructor initialization + public Fenwick2D(int[][] matrix) { + // input checks + if (matrix.length == 0 || matrix[0].length == 0) { + return; + } + // initialize variables + m = matrix.length; + n = matrix[0].length; + tree = new int[m + 1][n + 1]; + // deep clone matrix for reference, to prevent other process change matrix + nums = new int[m][n]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + // Another change that happens in the case of 2D bit is, + // the partial sums that we store now are corresponding to + // partial sum of the non-overlapping sub-rectangles or sub-matrix present in the matrix. + update(i, j, matrix[i][j]); + } + } + } + + // Function similar to Map.put(Key, Val), key is (row, col), new value is (val) + public void update(int row, int col, int val) { + // input validation: empty matrix || row col not in range + if (m == 0 || n == 0 || row < 0 || row > m || col < 0 || col > n) { + return; + } + // update cloned matrix: nums + int oldVal = nums[row][col]; + nums[row][col] = val; + // update bit tree with delta + int delta = val - oldVal; + for (int i = row + 1; i <= m; i += i & (-i)) { // remember tree is indexed by rLen & cLen, off-by-one index + for (int j = col + 1; j <= n; j += j & (-j)) { + tree[i][j] += delta; + } + } + } + + // Assume row1 <= row2 and col1 <= col2. both 0-base index and all input within range + public int sumRegion(int row1, int col1, int row2, int col2) { + // input validation: empty matrix || row col not in range + if (m == 0 || n == 0 || row1 < 0 || row1 > m || col1 < 0 || col1 > n || row2 < 0 || row2 > m || col2 < 0 || col2 > n) { + return 0; + } + // used 4 rectangle areas [(0, 0), (x, y)] to compute wanted area + // think about cases where row1 || col1 might be 0 + return sum(row2, col2) + sum(row1 - 1, col1 - 1) - sum(row1 - 1, col2) - sum(row2, col1 - 1); + } + + public int sum(int row, int col) { + // remember tree is indexed by rLen & cLen, off-by-one index + int rLen = row + 1; + int cLen = col + 1; + int sum = 0; + for (int i = rLen; i > 0; i -= i & (-i)) { + for (int j = cLen; j > 0; j -= j & (-j)) { + sum += tree[i][j]; + } + } + return sum; + } +} diff --git a/src/practiceproblems/FenwickTree.java b/src/main/java/practiceproblems/FenwickTree.java similarity index 79% rename from src/practiceproblems/FenwickTree.java rename to src/main/java/practiceproblems/FenwickTree.java index aaa07e5..29df534 100644 --- a/src/practiceproblems/FenwickTree.java +++ b/src/main/java/practiceproblems/FenwickTree.java @@ -1,6 +1,8 @@ package practiceproblems; /** + * tricky + * * https://codeforces.com/blog/entry/61364 * * Fenwick trees are binary indexed trees, when asked for a range queries for an array @@ -8,24 +10,24 @@ * one way is to pre-compute the prefix sums like [1,4,8,9,11] * when asked for sum between 0 to 4 return 9 * when asked sum between 2 to 4 we can return sum of (0,1) - (0,4) - * the retrival is O(1), but if the original array is updated we need to compute + * the retrieval is O(1), but if the original array is updated we need to compute * the prefix sum which will take O(N). * Fenwick tree solves this by making both get and update as O(log n) */ public class FenwickTree{ // the array size is always incremented by 1, because the first entry is - // a dummy entry, the trees are arranges in set bits of each array's index + // a dummy entry, the trees are arranged in set bits of each array's index // we consider 4 pos of the bit representation /** * for array [1,-7,15,9,4,2,0,10] * 0=> [0/0000] (index/ bit val of index) * / | \ \ - * 1=> [1/0001] [2/0010] [4/0100] [8/1000] - * / / \ - * 2=> [3/0011] [5/0101] [6/0110] + * 1=> [1/0001] [2/0010] [4/0100] [8/1000] - level of indexes with 1 right set bit (flipping right most bit will get parent) + * / / \ + * 2=> [3/0011] [5/0101] [6/0110] - level of indexes with 2 right set bit (flipping right most bit will get parent) * / - * 3=> [7/0111] + * 3=> [7/0111] - level of indexes with 3 right set bit (flipping right most bit will get parent) * * so from the above tree we can infer that to get to a parent node, we need to * remove the right most set bit @@ -33,7 +35,7 @@ public class FenwickTree{ * and the formula for that is parent = i - (i & -i); * * before populating fenwick tree with values, calculate the prefix sum for the array - * [1,-7,15,9,4,2,0,10]=> [1,-6,9,18,22,24,24,34] and update in it's posistion in fenwick tree + * [1,-7,15,9,4,2,0,10]=> [1,-6,9,18,22,24,24,34] and update in its position in fenwick tree * * [0/0000] * / | \ \ @@ -42,7 +44,10 @@ public class FenwickTree{ * [9/0011] [22/0101] [24/0110] * / * [24/0111] - * the we need to subract each cell's value to it's immediate parent's value, then the tree would look like + * then we need to subtract each cell's value to its immediate parent's value, while traversing (through parent )we can add parent's value to + * get the correct ans. + * + * Then the tree would look like * we can use the above formula parent = i - (i & -i); * * [0/0000] @@ -76,7 +81,6 @@ public void init(){ int parent = i - (i & -i); if(parent >= 0) fen[i] -= fen[parent]; } - //System.out.println(Arrays.toString(fen)); } diff --git a/src/main/java/practiceproblems/FindAllAnagram.java b/src/main/java/practiceproblems/FindAllAnagram.java new file mode 100644 index 0000000..e645967 --- /dev/null +++ b/src/main/java/practiceproblems/FindAllAnagram.java @@ -0,0 +1,50 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * https://leetcode.com/problems/find-all-anagrams-in-a-string/ + */ +public class FindAllAnagram { + + public static List findAnagrams(String s, String p) { + Map map = new HashMap<>(); + for (char ch : p.toCharArray()) { + map.put(ch, map.getOrDefault(ch, 0) + 1); + } + int counter = map.size(); + + int start = 0; + int end = 0; + List result = new ArrayList<>(); + while (end < s.length()) { + char temp = s.charAt(end); + if (map.containsKey(temp)) { + map.put(temp, map.get(temp) - 1); + if (map.get(temp) == 0) counter--; + } + end++; + + while (counter == 0) { + char begin = s.charAt(start); + if (map.containsKey(begin)) { + map.put(begin, map.get(begin) + 1); + if (map.get(begin) > 0) counter++; + } + if (end - start == p.length()) { + result.add(start); + } + start++; + } + } + + return result; + } + + public static void main(String[] args) { + System.out.println(findAnagrams("abbabab", "ab")); + } +} diff --git a/src/main/java/practiceproblems/FindAllPossibleRecipes.java b/src/main/java/practiceproblems/FindAllPossibleRecipes.java new file mode 100644 index 0000000..c16a0da --- /dev/null +++ b/src/main/java/practiceproblems/FindAllPossibleRecipes.java @@ -0,0 +1,147 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * https://leetcode.com/problems/find-all-possible-recipes-from-given-supplies + * + */ +public class FindAllPossibleRecipes { + + + public List findAllRecipesBruteForce(String[] recipes, List> ingredients, String[] supplies) { + Set supply= new HashSet<>(List.of(supplies)); + List result= new ArrayList<>(); + + + for(int i=0;i [sandwich,burger] + * // sandwich -> [burger] ] + * + * enqueue the indegree 0 and start processing + * + * if the indegree 0's reciepe is found in the dependency list we got the missing reciepe, start processing it + */ + public List findAllRecipesTopological(String[] recipes, List> ingredients, String[] supplies) { + // Map for storing the recipes indexes + HashMap recMap = new HashMap<>(); + + // Graph for vertices as the recipes and all the dependent recipes on them + HashMap> graph = new HashMap<>(); + + // Number of recipes + int n = recipes.length; + + // Set of all the supplies we have + HashSet sup = new HashSet<>(); + + // Maintain the list of all the available supplies with us + Collections.addAll(sup, supplies); + + // Maintain the index for all the recipes + for (int i = 0; i < n; i++) { + recMap.put(recipes[i], i); + } + + // indegree for all receipes + int[] indegree = new int[n]; + + // Traverse through all the receipes and the ingredients required by them + for (int i = 0; i < n; i++) { + //[["yeast","flour"],["bread","meat"],["sandwich","meat","bread"]] + //supplies = ["yeast","flour","meat"] + for (String str : ingredients.get(i)) { + + // If one of the ingredient is not present in supply then it is dependent on a recipes + if (!sup.contains(str)) { + // Add this particular receipe as a dependent recipe + //recipes = ["bread","sandwich","burger"] + graph.computeIfAbsent(str, x->new ArrayList<>()).add(recipes[i]); + // [bread -> [sandwich,burger] + // sandwich -> [burger] ] + + // Increment the indegree of the dependent recipe + indegree[i]++; + } + } + } + + // Queue for doing Topological Sorting + Queue q = new LinkedList<>(); + + // All the recipes that have indegree as 0 + for (int i = 0; i < n; i++) { + if (indegree[i] == 0) { + q.add(recipes[i]); + } + } + + // List of all the recipes that can be created + List ans = new ArrayList<>(); + + // Until there are nodes traverse it + while (!q.isEmpty()) { + // Peek a node from the queue + String node = q.poll(); + // Add it to the list of recipes that can be created + ans.add(node); + + // Traverse through all the dependent recipes and add them to queue if indegree is 0 + if (graph.containsKey(node)) { + // [bread -> [sandwich,burger] + // sandwich -> [burger] ] + for (String str : graph.get(node)) { + + indegree[recMap.get(str)]--; + if (indegree[recMap.get(str)] == 0) + q.add(str); + } + } + } + + return ans; + + } + + public static void main(String[] args) { + System.out.println(new FindAllPossibleRecipes().findAllRecipesTopological(new String[]{"bread","sandwich","burger"}, + List.of(List.of("yeast","flour"),List.of("bread","meat"),List.of("sandwich","meat","bread")),new String[]{"yeast","flour","meat"})); + } +} diff --git a/src/main/java/practiceproblems/FindHeaters.java b/src/main/java/practiceproblems/FindHeaters.java new file mode 100644 index 0000000..f87eee0 --- /dev/null +++ b/src/main/java/practiceproblems/FindHeaters.java @@ -0,0 +1,39 @@ +package practiceproblems; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/heaters/ + * tricky + * + * The difficulty of this problem is to understand Math.abs(heaters[i] - house) >= Math.abs(heaters[i + 1] - house + * Let's us understand this with a example: + * houses: 1, 2, 3, 4 + * heaters: 1, 4 + * For house 1, heater 1 is closer to it than heater 4, so we don't move i to i + 1. + * For house 2, it is same. heater 1 is closer. + * For house 3, it is clear that heater 1 no longer closer, so we move i to i + 1. + * For house 4, continue.... + * + * The idea here is we move the heater to rightward in case it is closer to the given house. + */ +public class FindHeaters { + + public int findRadius(int[] houses, int[] heaters) { + Arrays.sort(houses); + Arrays.sort(heaters); + + int i = 0; + int result = 0; + + for (int house : houses) { + while (i + 1 < heaters.length && Math.abs(house - heaters[i]) >= Math.abs(house - heaters[i + 1])) { + i++; + } + + result = Math.max(result, Math.abs(house - heaters[i])); + } + + return result; + } +} diff --git a/src/main/java/practiceproblems/FindMissingNumbers.java b/src/main/java/practiceproblems/FindMissingNumbers.java new file mode 100644 index 0000000..0ceb9ca --- /dev/null +++ b/src/main/java/practiceproblems/FindMissingNumbers.java @@ -0,0 +1,74 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +// Input: [2, 3, 1, 8, 2, 3, 5, 1] +// Output: 4, 6, 7 +public class FindMissingNumbers { + + //Brute Force + // Set set = new HashSet<>(); + // for (int i = 0; i < nums.length; i++) set.add(i + 1); + // for (int i = 0; i < nums.length; i++) set.remove(nums[i]); + // return new ArrayList<>(set); + public List findDisappearedNumbers(int[] nums) { + if (nums.length == 0) return Collections.emptyList(); + int i = 0; + // cyclic sort begins + while (i < nums.length) { + int j = nums[i] - 1; + if (nums[i] != nums[j]) { + swap(nums, i, j); + } else { + i++; + } + } + // cyclic sort ends + // when cyclic sort ends the i+1 element will be in correct index + List result = new ArrayList<>(); + i = 0; + while (i < nums.length) { + if (i + 1 != nums[i]) result.add(i + 1); + i++; + } + return result; + } + + public void swap(int[] nums, int i, int j) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } + + public int missingNumber(int[] nums) { + //using a bit modify version of cyclic sort + int index = 0; + int n = nums.length; + while (index < n) { + int correct = nums[index]; + if (nums[index] < n && nums[index] != nums[correct]) //ignore if value is equal to n + { + int temp = nums[index]; + nums[index] = nums[correct]; + nums[correct] = temp; + + } else { + index++; + } + } + + //now search + for (int i = 0; i < n; i++) { + if (nums[i] != i)//we know every element should equal to its index + { + return i; + } + } + //case 2 , when missing number is not in array + return n; + + + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/FindPairs.java b/src/main/java/practiceproblems/FindPairs.java new file mode 100644 index 0000000..9e493d3 --- /dev/null +++ b/src/main/java/practiceproblems/FindPairs.java @@ -0,0 +1,32 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.Map; + +/** + * https://leetcode.com/problems/k-diff-pairs-in-an-array/ + */ +public class FindPairs { + + public static int findPairs(int[] nums, int k) { + if (k < 0) return 0; + Map map = new HashMap<>(); + for (int i : nums) { + map.put(i, map.getOrDefault(i, 0) + 1); + } + int count = 0; + for (int m : map.keySet()) { + if (k == 0) { + if (map.get(m) >= 2) count++; + } else { + if (map.containsKey(m + k)) + count++; + } + } + return count; + } + + public static void main(String[] args) { + System.out.println(findPairs(new int[]{3, 1, 4, 1, 5}, 0)); + } +} diff --git a/src/practiceproblems/FindSmallestInteger.java b/src/main/java/practiceproblems/FindSmallestInteger.java similarity index 65% rename from src/practiceproblems/FindSmallestInteger.java rename to src/main/java/practiceproblems/FindSmallestInteger.java index 40fa4d3..fbc7c1e 100644 --- a/src/practiceproblems/FindSmallestInteger.java +++ b/src/main/java/practiceproblems/FindSmallestInteger.java @@ -10,17 +10,30 @@ * */ class FindSmallestInteger { - int findSmallest(int arr[], int n) { - int result = 1; - - // Traverse the array and increment 'result' if arr[i] is - // smaller than or equal to 'result'. - for (int i = 0; i < n && arr[i] <= result; i++) { - System.out.println("Result :" + result + ":: arr[" + i + "] " + arr[i]); - result = result + arr[i]; + int findSmallest(int a[], int n) { + int maxPossible = 0; + + if(a.length == 0 || a[0] != 1) + { + return maxPossible + 1; + } + + // we have verified that 1 exists in the array. + maxPossible = 1; + + for(int i=1; i maxPossible + 1) + { + break; + } + + maxPossible += a[i]; } - return result; + return maxPossible + 1; } public static void main(String[] args) { diff --git a/src/practiceproblems/FirstMissingPositive.java b/src/main/java/practiceproblems/FirstMissingPositive.java similarity index 57% rename from src/practiceproblems/FirstMissingPositive.java rename to src/main/java/practiceproblems/FirstMissingPositive.java index 7a7237c..dc4ca59 100644 --- a/src/practiceproblems/FirstMissingPositive.java +++ b/src/main/java/practiceproblems/FirstMissingPositive.java @@ -8,16 +8,6 @@ /** * https://leetcode.com/problems/first-missing-positive/ - * Given an unsorted integer array nums, find the smallest missing positive integer. - * - * Follow up: Could you implement an algorithm that runs in O(n) time - * and uses constant extra space.? - * - * Input: nums = [1,2,0] - * Output: 3 - * - * Input: nums = [7,8,9,11,12] - * Output: 1 */ public class FirstMissingPositive { @@ -25,13 +15,13 @@ public int firstMissingPositive(int[] A) { int i = 0; while (i < A.length) { // same cyclic sort, as missing numbers - if (A[i] == i + 1 || A[i] <= 0 || A[i] > A.length) { - i++; - } else if (A[A[i] - 1] != A[i]) { - swap(A, i, A[i] - 1); - } else { - i++; - } + if (A[i] == i + 1 || A[i] <= 0 || A[i] > A.length) { + i++; + } else if (A[A[i] - 1] != A[i]) { + swap(A, i, A[i] - 1); + } else { + i++; + } } i = 0; while (i < A.length && A[i] == i + 1) @@ -46,9 +36,9 @@ private void swap(int[] A, int i, int j) { } public int firstMissingPositiveWithExtraSpace(int[] nums) { - if (nums == null || nums.length == 0) { - return 1; - } + if (nums == null || nums.length == 0) { + return 1; + } int length = nums.length; int[] arr = new int[length + 1]; for (int i = 0; i < length; i++) { @@ -65,40 +55,41 @@ public int firstMissingPositiveWithExtraSpace(int[] nums) { return -1; } - public List findKMissingPositiveNumberOfSizeK(int[] A, int k){ + public List findKMissingPositiveNumberOfSizeK(int[] A, int k) { int i = 0; while (i < A.length) { // same cyclic sort, as missing numbers - if (A[i] == i + 1 || A[i] <= 0 || A[i] > A.length) { - i++; - } else if (A[A[i] - 1] != A[i]) { - swap(A, i, A[i] - 1); - } else { - i++; - } + if (A[i] == i + 1 || A[i] <= 0 || A[i] > A.length) { + i++; + } else if (A[A[i] - 1] != A[i]) { + swap(A, i, A[i] - 1); + } else { + i++; + } } - List missingNumber= new ArrayList<>(); - Set additionalNumber= new HashSet<>(); + List missingNumber = new ArrayList<>(); + Set additionalNumber = new HashSet<>(); - i=0; - while(i 1) s++; + while (j < i && charCounts[charArr[j] - 'a'] > 1) j++; // If the character at start index is a non repeating character, add it the string otherwise add '#'' - if (charCounts[charArr[s] - 'a'] == 1) sb.append(charArr[s]); + if (charCounts[charArr[j] - 'a'] == 1) sb.append(charArr[j]); else sb.append('#'); } @@ -57,52 +63,48 @@ public String solveEfficient(String A) { } public static void main(String[] args) { - String[] vals= "jpxvxivxkkthvpqhhhjuzhkegnzqriokhsgea".split(""); - FirstNonRepeatingCharacterStream solution= new FirstNonRepeatingCharacterStream(); - for(String s:vals){ - System.out.println("ans:: "+solution.solve(s)); - } + String vals = "jpxvxivxkkthvpqhhhjuzhkegnzqriokhsgea"; + FirstNonRepeatingCharacterStream solution = new FirstNonRepeatingCharacterStream(); + System.out.println("ans:: " + solution.solveEfficient(vals)); } -} - - + class DLList { + Node head; + Node tail; + public DLList() { + head = new Node("#"); + tail = new Node("#"); + head.next = tail; + tail.prev = head; + } + public void add(Node node) { + Node prev = tail.prev; + prev.next = node; + node.prev = prev; -class DLList { - Node head; - Node tail; + node.next = tail; + tail.prev = node; + } - public DLList() { - head = new Node("#"); - tail = new Node("#"); - head.next = tail; - tail.prev = head; + public void remove(Node temp) { + Node next = temp.next; + temp.prev.next = next; + next.prev = temp.prev; + } } - public void add(Node node) { - Node prev = tail.prev; - prev.next = node; - node.prev = prev; + class Node { + Node prev; + Node next; + String val; - node.next = tail; - tail.prev = node; - } - - public void remove(Node temp) { - Node next = temp.next; - temp.prev.next = next; - next.prev = temp.prev; + public Node(String val) { + this.val = val; + } } } -class Node { - Node prev; - Node next; - String val; - public Node(String val) { - this.val = val; - } -} + diff --git a/src/practiceproblems/Flatten2DVector.java b/src/main/java/practiceproblems/Flatten2DVector.java similarity index 94% rename from src/practiceproblems/Flatten2DVector.java rename to src/main/java/practiceproblems/Flatten2DVector.java index 250ac0f..3ee139b 100644 --- a/src/practiceproblems/Flatten2DVector.java +++ b/src/main/java/practiceproblems/Flatten2DVector.java @@ -64,9 +64,6 @@ public boolean hasNext() { if (x >= list.size()) { return false; } - if (y >= list.get(x).size()) { - return false; - } - return true; + return y < list.get(x).size(); } } diff --git a/src/practiceproblems/FlattenLinkedList.java b/src/main/java/practiceproblems/FlattenLinkedList.java similarity index 100% rename from src/practiceproblems/FlattenLinkedList.java rename to src/main/java/practiceproblems/FlattenLinkedList.java diff --git a/src/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java b/src/main/java/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java similarity index 92% rename from src/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java rename to src/main/java/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java index beb009a..92b752f 100644 --- a/src/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java +++ b/src/main/java/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java @@ -1,8 +1,10 @@ package practiceproblems; +import javafx.util.Pair; + /** * https://www.geeksforgeeks.org/maximize-number-0s-flipping-subarray/ - * + *

* Problem : flip 1's to 0's so that total no.of 0's in array is maximized */ class FlipMaximizeZeroesSubarrayKadane { @@ -33,8 +35,9 @@ public static int findMaxZeroCount(int[] arr, int n) { } public static void main(String[] args) { - int[] arr = { 0, 1, 0, 0, 1, 1, 0 }; + int[] arr = {0, 1, 0, 0, 1, 1, 0}; System.out.println(findMaxZeroCount(arr, arr.length)); } + } \ No newline at end of file diff --git a/src/practiceproblems/FlipZeroesToFormConsecutiveMaximumOnes.java b/src/main/java/practiceproblems/FlipZeroesToFormConsecutiveMaximumOnes.java similarity index 92% rename from src/practiceproblems/FlipZeroesToFormConsecutiveMaximumOnes.java rename to src/main/java/practiceproblems/FlipZeroesToFormConsecutiveMaximumOnes.java index fe63cb4..0d7697f 100644 --- a/src/practiceproblems/FlipZeroesToFormConsecutiveMaximumOnes.java +++ b/src/main/java/practiceproblems/FlipZeroesToFormConsecutiveMaximumOnes.java @@ -2,7 +2,7 @@ /** * https://www.geeksforgeeks.org/find-zeroes-to-be-flipped-so-that-number-of-consecutive-1s-is-maximized/ - + *

* https://www.techiedelight.com/find-maximum-sequence-of-continuous-1s-can-formed-replacing-k-zeroes-ones/ */ class FlipZeroesToFormConsecutiveMaximumOnes { @@ -34,7 +34,7 @@ public static void longestSeq(int[] A, int k) { } // when we reach here, the window [left..right] contains at-most - // k zeroes and we update max window size and leftmost index + // k zeroes, and we update max window size and leftmost index // of the window if (right - left + 1 > window) { window = right - left + 1; @@ -49,7 +49,7 @@ public static void longestSeq(int[] A, int k) { // main function public static void main(String[] args) { - int[] A = { 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0 }; + int[] A = {1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0}; int k = 2; longestSeq(A, k); diff --git a/src/main/java/practiceproblems/FourSum.java b/src/main/java/practiceproblems/FourSum.java new file mode 100644 index 0000000..2bc532e --- /dev/null +++ b/src/main/java/practiceproblems/FourSum.java @@ -0,0 +1,105 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * https://leetcode.com/problems/4sum-ii/ + * Given four lists A, B, C, D of integer values, + * compute how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero. + * To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. + * All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1. + *

+ * Input: + * A = [ 1, 2] + * B = [-2,-1] + * C = [-1, 2] + * D = [ 0, 2] + *

+ * Output: + * 2 + *

+ * Explanation: + * The two tuples are: + * 1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0 + * 2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0 + */ +public class FourSum { + + public int fourSumCount(int[] A, int[] B, int[] C, int[] D) { + Map sumMap = new HashMap<>(); + + for (int value : A) { + for (int i : B) { + int sum = value + i; + sumMap.put(sum, sumMap.getOrDefault(sum, 0) + 1); + } + } + + int count = 0; + /** + * Compute all the possible sums of the arrays C and D. + * If the hash map contains the opposite value of the current sum, + * increase the count of four elements sum to 0 by the counter in the map. + */ + for (int i : C) { + for (int j : D) { + int sum = i + j; + count += sumMap.getOrDefault(-sum, 0); + } + } + + return count; + } + + public List> fourSum(int[] nums, int target) { + List> result = new ArrayList<>(); + Arrays.sort(nums); + + for (int i = 0; i < nums.length; i++) { + if (i != 0 && nums[i] == nums[i - 1]) { + continue; + } + for (int j = i + 1; j < nums.length; j++) { + if (j != i + 1 && nums[j] == nums[j - 1]) { + continue; + } + int temp = nums[i] + nums[j]; + int k = j + 1; + int l = nums.length - 1; + while (k < l) { + if (target == temp + nums[k] + nums[l]) { + result.add(Arrays.asList(nums[i], nums[j], nums[k], nums[l])); + k++; + l--; + while (k < l && nums[k] == nums[k - 1]) k++; + while (k < l && nums[l] == nums[l + 1]) l--; + + } else if (target > temp + nums[k] + nums[l]) { + k++; + while (k < l && nums[k] == nums[k - 1]) k++; + + } else { + l--; + while (k < l && nums[l] == nums[l + 1]) l--; + } + } + } + } + + return result; + } + + public static void main(String[] args) { + int[] A = {1, 2}; + int[] B = {-2, -1}; + int[] C = {-1, 2}; + int[] D = {0, 2}; + + FourSum fs = new FourSum(); + fs.fourSumCount(A, B, C, D); + } +} diff --git a/src/practiceproblems/FrequencySort.java b/src/main/java/practiceproblems/FrequencySort.java similarity index 53% rename from src/practiceproblems/FrequencySort.java rename to src/main/java/practiceproblems/FrequencySort.java index 3f38033..461214f 100644 --- a/src/practiceproblems/FrequencySort.java +++ b/src/main/java/practiceproblems/FrequencySort.java @@ -4,30 +4,49 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.PriorityQueue; // sort the string by character frequency from high to low public class FrequencySort { // this could be easily done with priority queue but this is ref for bucket sort public String frequencySort(String s) { Map map = new HashMap<>(); - for (char c : s.toCharArray()) + for (char c : s.toCharArray()) map.put(c, map.getOrDefault(c, 0) + 1); - - List[] bucket = new List[s.length() + 1]; + + List[] bucket = new ArrayList[s.length() + 1]; for (char key : map.keySet()) { int frequency = map.get(key); if (bucket[frequency] == null) bucket[frequency] = new ArrayList<>(); bucket[frequency].add(key); } - + StringBuilder sb = new StringBuilder(); // since this is max frequency we are iterating from last else we'd go from start for (int pos = bucket.length - 1; pos >= 0; pos--) if (bucket[pos] != null) for (char c : bucket[pos]) - for (int i = 0; i < map.get(c); i++) - sb.append(c); + sb.append(String.valueOf(c).repeat(Math.max(0, map.get(c)))); + + return sb.toString(); + } + + public String frequencySortEff(String s) { + + Map map = new HashMap<>(); + for (char c : s.toCharArray()) { + map.put(c, map.getOrDefault(c, 0) + 1); + } + + PriorityQueue> pq = new PriorityQueue<>((a, b) -> b.getValue() - a.getValue()); + pq.addAll(map.entrySet()); + + StringBuilder sb = new StringBuilder(); + while (!pq.isEmpty()) { + Map.Entry e = pq.poll(); + sb.append(String.valueOf(e.getKey()).repeat(Math.max(0, e.getValue()))); + } return sb.toString(); } diff --git a/src/main/java/practiceproblems/FurthestBuildingJump.java b/src/main/java/practiceproblems/FurthestBuildingJump.java new file mode 100644 index 0000000..3c0e793 --- /dev/null +++ b/src/main/java/practiceproblems/FurthestBuildingJump.java @@ -0,0 +1,46 @@ +package practiceproblems; + +import java.util.PriorityQueue; + +/** + * tricky priority queue + */ +public class FurthestBuildingJump { + + public int furthestBuilding(int[] heights, int bricks, int ladders) { + + + PriorityQueue queue = new PriorityQueue<>((a, b) -> Integer.compare(b, a)); + for (int reach = 0; reach < heights.length - 1; reach++) { + + if (heights[reach] >= heights[reach + 1]) continue; + + int diff = heights[reach + 1] - heights[reach]; + + if (diff <= bricks) { + bricks -= diff; + queue.offer(diff); + } else if (ladders > 0) { + + /** + * If, however, bricks has become negative, then we'll need to make bricks positive again by reclaiming some bricks; + * we do this by removing the largest brick allocation from the heap and subtracting 1 from ladders to cover the removed brick allocation. + * This works because one of two cases is true; either there's a previous climb with more bricks to reclaim, + * or we've just added the largest climb onto the max-heap. So when we remove the maximum from the max-heap, + * we'll definitely get at least as many bricks as we just subtracted to make bricks non-negative again. + */ + if (!queue.isEmpty()) { + bricks += queue.poll(); + if (bricks >= diff) { + bricks -= diff; + queue.offer(diff); + } + } + ladders--; + } else { + return reach; + } + } + return heights.length - 1; + } +} diff --git a/src/main/java/practiceproblems/GameOfLife.java b/src/main/java/practiceproblems/GameOfLife.java new file mode 100644 index 0000000..8cacb42 --- /dev/null +++ b/src/main/java/practiceproblems/GameOfLife.java @@ -0,0 +1,64 @@ +package practiceproblems; + +/** + * https://forum.letstalkalgorithms.com/t/game-of-life/516/2 + *

+ * https://leetcode.com/problems/game-of-life/ + */ +public class GameOfLife { + // all eight possible directions + private static final int[][] directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {-1, -1}, {-1, 1}, {1, -1}}; + private static final int ALIVE = 1; + private static final int DEAD = 0; + private static final int DEAD_TO_ALIVE = 2; + private static final int ALIVE_TO_DEAD = 3; + + public void gameOfLife(int[][] board) { + // iterate through every cell in this 2D array + for (int r = 0; r < board.length; r++) { + for (int c = 0; c < board[0].length; c++) { + // keep track of the number of alive neighbors + int alive = 0; + + // for each cell, check all possible 8 directions and count the number of alive neighbors + for (int[] direction : directions) { + alive += isAlive(board, r + direction[0], c + direction[1]) ? 1 : 0; + } + + // in case current cell is dead but has 3 live neighbors + if (board[r][c] == DEAD) { + if (alive == 3) { + + //Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction. + board[r][c] = DEAD_TO_ALIVE; + } + } + // in case current cell is alive + else { + //Any live cell with fewer than two live neighbors dies as if caused by under-population. + //Any live cell with more than three live neighbors dies, as if by over-population. + //Any live cell with two or three live neighbors lives on to the next generation. + // in case, only 2 or 3 neighbors are alive + if (alive != 2 && alive != 3) { + board[r][c] = ALIVE_TO_DEAD; + } + } + } + } + + for (int r = 0; r < board.length; r++) { + for (int c = 0; c < board[0].length; c++) { + if (board[r][c] == DEAD_TO_ALIVE) { + board[r][c] = ALIVE; + } else if (board[r][c] == ALIVE_TO_DEAD) { + board[r][c] = DEAD; + } + } + } + } + + private boolean isAlive(int[][] board, int r, int c) { + return r >= 0 && r < board.length && c >= 0 && c < board[0].length && (board[r][c] == ALIVE || board[r][c] == ALIVE_TO_DEAD); + } + +} \ No newline at end of file diff --git a/src/practiceproblems/GrammarMistake.java b/src/main/java/practiceproblems/GrammarMistake.java similarity index 83% rename from src/practiceproblems/GrammarMistake.java rename to src/main/java/practiceproblems/GrammarMistake.java index 65706d1..6a40b83 100644 --- a/src/practiceproblems/GrammarMistake.java +++ b/src/main/java/practiceproblems/GrammarMistake.java @@ -3,7 +3,6 @@ /** * https://www.geeksforgeeks.org/check-given-sentence-given-set-simple-grammer-rules/ * A simple sentence if syntactically correct if it fulfills given rules. The following are given rules. - * * 1. Sentence must start with a Uppercase character (e.g. Noun/ I/ We/ He etc.) * 2. Then lowercase character follows. * 3. There must be spaces between words. @@ -11,25 +10,20 @@ * 5. Two continuous spaces are not allowed. * 6. Two continuous upper case characters are not allowed. * 7. However, the sentence can end after an upper case character. - * - * */ + import java.util.Arrays; import java.util.List; -class Main -{ - public static boolean validateSentence(char[] chars) - { +public class GrammarMistake { + public static boolean validateSentence(char[] chars) { int index = 0; if (Character.isLowerCase(chars[index])) { // 1st condition return false; } - while (index < chars.length) - { - if (Character.isUpperCase(chars[index])) - { + while (index < chars.length) { + if (Character.isUpperCase(chars[index])) { if (Character.isUpperCase(chars[index + 1])) { // 5th condition return false; } @@ -46,15 +40,11 @@ public static boolean validateSentence(char[] chars) index++; } - if (chars[index - 2] == ' ' || chars[index - 1] != '.') { // 3th condition - return false; - } - - return true; + // 3th condition + return chars[index - 2] != ' ' && chars[index - 1] == '.'; } - public static void main(String[] args) - { + public static void main(String[] args) { List list = Arrays.asList( "This sentence is syntactically correct.", @@ -74,7 +64,7 @@ public static void main(String[] args) ); System.out.println("Valid sentences are -"); - for (String sentence: list) { + for (String sentence : list) { if (validateSentence(sentence.toCharArray())) { System.out.println(sentence); } diff --git a/src/practiceproblems/GraphSplitwiseSimplify.java b/src/main/java/practiceproblems/GraphSplitwiseSimplify.java similarity index 93% rename from src/practiceproblems/GraphSplitwiseSimplify.java rename to src/main/java/practiceproblems/GraphSplitwiseSimplify.java index 7d42d79..21f24e9 100644 --- a/src/practiceproblems/GraphSplitwiseSimplify.java +++ b/src/main/java/practiceproblems/GraphSplitwiseSimplify.java @@ -31,15 +31,6 @@ public AdjNode(int adjVertices, int debt) { this.debt = debt; } - @Override - public boolean equals(Object o) { - if (this.adjVertices == ((AdjNode) o).adjVertices) { - return true; - } else { - return false; - } - } - public String toString() { return adjVertices + "->" + debt; } @@ -49,7 +40,7 @@ public Graph(int v) { this.V = v; adjNodesList = new LinkedList[V]; for (int i = 0; i < V; i++) { - adjNodesList[i] = new LinkedList(); + adjNodesList[i] = new LinkedList<>(); } } diff --git a/src/main/java/practiceproblems/GroupAnagrams.java b/src/main/java/practiceproblems/GroupAnagrams.java new file mode 100644 index 0000000..159dd50 --- /dev/null +++ b/src/main/java/practiceproblems/GroupAnagrams.java @@ -0,0 +1,21 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class GroupAnagrams { + public List> groupAnagrams(String[] strs) { + Map> map = new HashMap<>(); + for (String s : strs) { + char[] temp = s.toCharArray(); + Arrays.sort(temp); + String s1 = new String(temp); + map.putIfAbsent(s1, new ArrayList<>()); + map.get(s1).add(s); + } + return new ArrayList<>(map.values()); + } +} \ No newline at end of file diff --git a/src/practiceproblems/GroupIsomorphicString.java b/src/main/java/practiceproblems/GroupIsomorphicString.java similarity index 77% rename from src/practiceproblems/GroupIsomorphicString.java rename to src/main/java/practiceproblems/GroupIsomorphicString.java index 234e771..a73d7a9 100644 --- a/src/practiceproblems/GroupIsomorphicString.java +++ b/src/main/java/practiceproblems/GroupIsomorphicString.java @@ -1,26 +1,32 @@ package practiceproblems; -import java.util.*; - +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * tricky- string hash + */ public class GroupIsomorphicString { public Collection> groupIsomorphicStrings(List strings) { if (strings == null || strings.isEmpty()) { - return Collections.EMPTY_LIST; + return Collections.emptyList(); } Map> hashToList = new HashMap<>(); for (String string : strings) { String hash = hash(string); - - if (!hashToList.containsKey(hash)) { - hashToList.put(hash, new ArrayList<>()); - } - + hashToList.putIfAbsent(hash, new ArrayList<>()); hashToList.get(hash).add(string); } return hashToList.values(); } + // this method returns a hash value for every string passed in // apple = 12234 // apply = 12234 @@ -31,20 +37,15 @@ private String hash(String s) { if (s.isEmpty()) { return ""; } - int count = 1; StringBuilder hash = new StringBuilder(); Map map = new HashMap<>(); for (char c : s.toCharArray()) { - - if (!map.containsKey(c)) { - map.put(c, count++); - } + map.putIfAbsent(c, count++); hash.append(map.get(c)); } - System.out.println(s +" = "+hash.toString() ); return hash.toString(); } diff --git a/src/main/java/practiceproblems/HappyNumber.java b/src/main/java/practiceproblems/HappyNumber.java new file mode 100644 index 0000000..7d0bd52 --- /dev/null +++ b/src/main/java/practiceproblems/HappyNumber.java @@ -0,0 +1,56 @@ +package practiceproblems; + +import java.util.HashSet; +import java.util.Set; + +/** + * https://leetcode.com/problems/happy-number/ + */ +class HappyNumber { + public boolean isHappy(int n) { + if (n == 1) return true; + + Set seen = new HashSet<>(); + + while (true) { + int result = 0; + while (n > 0) { + int temp = n % 10; + result += temp * temp; + n /= 10; + } + if (!seen.add(result)) return false; + if (result == 1) break; + seen.add(result); + n = result; + } + + return true; + } + + public int getNext(int n) { + int res = 0; + while (n > 0) { + int t = n % 10; + res += t * t; + n /= 10; + } + return res; + } + + public boolean isHappyOpt(int n) { + int slowRunner = n; + int fastRunner = getNext(n); + + while (fastRunner != 1 && slowRunner != fastRunner) { + slowRunner = getNext(slowRunner); + fastRunner = getNext(getNext(fastRunner)); + } + return fastRunner == 1; + } + + public static void main(String[] args) { + HappyNumber hn = new HappyNumber(); + System.out.println(hn.isHappyOpt(19)); + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/HouseRobber.java b/src/main/java/practiceproblems/HouseRobber.java new file mode 100644 index 0000000..d1e481f --- /dev/null +++ b/src/main/java/practiceproblems/HouseRobber.java @@ -0,0 +1,78 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/house-robber/ + */ +public class HouseRobber { + + public int rob(int[] nums) { + if (nums.length == 0) { + return 0; + } + int incl = nums[0]; // max money can get if rob current house + int excl = 0; // max money can get if not rob current house + for (int i = 1; i < nums.length; i++) { + int temp = incl; + incl = Math.max(incl, excl + nums[i]); + excl = temp; + } + return incl; + } + + public int robCircular(int[] nums) { + + if (nums.length == 0) return 0; + if (nums.length == 1) return nums[0]; + return Math.max(helperFn(nums, 0, nums.length - 2), helperFn(nums, 1, nums.length - 1)); + + } + + public int helperFn(int[] nums, int start, int end) { + int pre = 0; + int cur = 0; + for (int i = start; i <= end; i++) { + int temp = Math.max(pre + nums[i], cur); + pre = cur; + cur = temp; + + } + return cur; + } + + Integer[] cache; + + public int robBottomUp(int[] nums) { + cache = new Integer[nums.length]; + return recursionHelper(nums, 0); + } + + public int recursionHelper(int[] nums, int index) { + if (index >= nums.length) return 0; + if (cache[index] != null) return cache[index]; + int inclusive = recursionHelper(nums, index + 2) + nums[index]; + int exclusive = recursionHelper(nums, index + 1); + + return cache[index] = Math.max(inclusive, exclusive); + } + + public int robExtraSpace(int[] nums) { + if (nums.length == 1) return nums[0]; + if (nums.length == 2) return Math.max(nums[0], nums[1]); + + int[] dp = new int[nums.length]; + dp[0] = nums[0]; + dp[1] = Math.max(dp[0], nums[1]); + + for (int i = 2; i < nums.length; i++) { + dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]); + } + + return dp[nums.length - 1]; + } + + public static void main(String[] args) { + int[] arr = {2, 7, 9, 3, 1}; + HouseRobber houseRobber = new HouseRobber(); + System.out.println(houseRobber.rob(arr)); + } +} diff --git a/src/main/java/practiceproblems/IPOMaxProfit.java b/src/main/java/practiceproblems/IPOMaxProfit.java new file mode 100644 index 0000000..bd4c80b --- /dev/null +++ b/src/main/java/practiceproblems/IPOMaxProfit.java @@ -0,0 +1,41 @@ +package practiceproblems; + +import java.util.Comparator; +import java.util.PriorityQueue; + +/** + * https://leetcode.com/problems/ipo/ + */ + + +public class IPOMaxProfit { + + // Create (capital, profit) pairs and put them into PriorityQueue pqCap. + // This PriorityQueue sort by capital increasingly. + // Keep polling pairs from pqCap until the project out of current capital capability. Put them into + // PriorityQueue pqPro which sort by profit decreasingly. + // Poll one from pqPro, it's guaranteed to be the project with max profit and within current capital capability. + //Add the profit to capital W. + //Repeat step 2 and 3 till finish k steps or no suitable project (pqPro.isEmpty()). + public int findMaximizedCapital(int steps, int initialCapital, int[] profits, int[] capital) { + + PriorityQueue minQueue = new PriorityQueue<>(Comparator.comparingInt(a -> a[0])); + PriorityQueue maxQueue = new PriorityQueue<>((a, b) -> Integer.compare(b[1], a[1])); + + for (int i = 0; i < profits.length; i++) { + minQueue.offer(new int[]{capital[i], profits[i]}); + } + for (int i = 0; i < steps; i++) { + while (!minQueue.isEmpty() && minQueue.peek()[0] <= initialCapital) { + maxQueue.offer(minQueue.poll()); + } + + if (maxQueue.isEmpty()) break; + + initialCapital += maxQueue.poll()[1]; + + } + return initialCapital; + + } +} \ No newline at end of file diff --git a/src/practiceproblems/InOrderSuccessor.java b/src/main/java/practiceproblems/InOrderSuccessor.java similarity index 58% rename from src/practiceproblems/InOrderSuccessor.java rename to src/main/java/practiceproblems/InOrderSuccessor.java index 809ae1c..f2551b6 100644 --- a/src/practiceproblems/InOrderSuccessor.java +++ b/src/main/java/practiceproblems/InOrderSuccessor.java @@ -1,28 +1,32 @@ package practiceproblems; + +import trees.TreeNode; + public class InOrderSuccessor { /* * @param root: The root of the BST. * @param p: You need find the successor node of p. * @return: Successor of p. */ - TreeNode result=null; + TreeNode result = null; + public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { - helperFn(root,p); - return result; + helperFn(root, p); + return result; } // Inorder traversal is obtained by going right first and follow the left path till end // while traversing right we record the right before taking left turn, in case the left path is null - public void helperFn(TreeNode root, TreeNode p){ - if(root==null) return; - - if(root.val>p.val){ - - result=root; - helperFn(root.left,p); - }else{ - helperFn(root.right,p); + public void helperFn(TreeNode root, TreeNode p) { + if (root == null) return; + + if (root.val > p.val) { + + result = root; + helperFn(root.left, p); + } else { + helperFn(root.right, p); } - + } } \ No newline at end of file diff --git a/src/main/java/practiceproblems/InorderSuccessorPredecessor.java b/src/main/java/practiceproblems/InorderSuccessorPredecessor.java new file mode 100644 index 0000000..a21c87d --- /dev/null +++ b/src/main/java/practiceproblems/InorderSuccessorPredecessor.java @@ -0,0 +1,143 @@ +package practiceproblems; + +import trees.TreeNode; + +/** + * https://algorithms.tutorialhorizon.com/inorder-predecessor-and-successor-in-binary-search-tree/ + */ +public class InorderSuccessorPredecessor { + static int successor, predecessor; + + + public Node inorderSuccessorII(Node node) { + if (node == null) return null; + + if (node.right == null) { + while (node.parent != null && node.parent.val < node.val) + node = node.parent; + + return node.parent; + } + return findBelow(node.right); + } + + private Node findBelow(Node node) { + while (node != null && node.left != null) + node = node.left; + return node; + } + + public void successorPredecessor(TNode root, int val) { + if (root == null) return; + + if (root.data > val) { + // we make the root as successor because we might have a + // situation when value matches with the root, it wont have + // right subtree to find the successor, in that case we need + // parent to be the successor + successor = root.data; + successorPredecessor(root.left, val); + } else if (root.data < val) { + // we make the root as predecessor because we might have a + // situation when value matches with the root, it wont have + // left subtree to find the predecessor, in that case we need + // parent to be the predecessor. + predecessor = root.data; + successorPredecessor(root.right, val); + } + } + + public static void main(String args[]) { + TNode root = new TNode(25); + root.left = new TNode(15); + root.right = new TNode(40); + root.left.left = new TNode(10); + root.left.left.left = new TNode(5); + root.left.right = new TNode(18); + root.right.left = new TNode(35); + root.right.right = new TNode(45); + root.left.right.left = new TNode(19); + root.left.right.right = new TNode(20); + InorderSuccessorPredecessor i = new InorderSuccessorPredecessor(); + + i.successorPredecessor(root, 20); + + System.out.println("Inorder Successor of 20 is : " + successor + " and predecessor is : " + predecessor); + + } + + TreeNode result = null; + + public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { + helperFn(root, p); + return result; + } + + public void helperFn(TreeNode root, TreeNode p) { + if (root == null) return; + + if (root.val > p.val) { + result = root; + helperFn(root.left, p); + } else { + helperFn(root.right, p); + } + + } + + // tricky tree traversal + // predecessor go to left first and then go right till end + // so place the result assignment (pre = cur) in the go right block + private TreeNode findPredecessor(TreeNode root, TreeNode node) { + TreeNode pre = null; + TreeNode cur = root; + while (cur != null) { + if (cur.val < node.val) { + pre = cur; + cur = cur.right; + } else { + cur = cur.left; + } + } + return pre; + } + + // successor go to right first and then go left till end + // so place the result assignment (pre = cur) in the go left block + private TreeNode findSuccessor(TreeNode root, TreeNode node) { + TreeNode succ = null; + TreeNode cur = root; + while (cur != null) { + if (cur.val > node.val) { + succ = cur; + cur = cur.left; + } else { + cur = cur.right; + } + } + return succ; + } + + + class Node { + public int val; + public Node left; + public Node right; + public Node parent; + } + + static class TNode { + int data; + TNode left; + TNode right; + + public TNode(int data) { + this.data = data; + left = null; + right = null; + } + + + } +} + diff --git a/src/practiceproblems/IntegerToBinary.java b/src/main/java/practiceproblems/IntegerToBinary.java similarity index 100% rename from src/practiceproblems/IntegerToBinary.java rename to src/main/java/practiceproblems/IntegerToBinary.java diff --git a/src/practiceproblems/IntersectionOfArrays.java b/src/main/java/practiceproblems/IntersectionOfArrays.java similarity index 62% rename from src/practiceproblems/IntersectionOfArrays.java rename to src/main/java/practiceproblems/IntersectionOfArrays.java index c7992e1..e76b674 100644 --- a/src/practiceproblems/IntersectionOfArrays.java +++ b/src/main/java/practiceproblems/IntersectionOfArrays.java @@ -20,8 +20,8 @@ public class IntersectionOfArrays { public static void main(String[] args) { IntersectionOfArrays intersectionOfArrays = new IntersectionOfArrays(); - int[] nums1 = { 4, 4, 9, 5 }; - int[] nums2 = { 9, 4, 9, 4, 2, 3 }; + int[] nums1 = {4, 4, 9, 5}; + int[] nums2 = {9, 4, 9, 4, 2, 3}; System.out.println(Arrays.toString(intersectionOfArrays.intersect(nums1, nums2))); } @@ -31,14 +31,14 @@ public int[] intersect(int[] nums1, int[] nums2) { // Then for every element of nums2, look upon the hashmap. If we found an intersection, deduct by 1 to avoid duplicate. HashMap map = new HashMap<>(); ArrayList result = new ArrayList<>(); - for (int i = 0; i < nums1.length; i++) { - map.put(nums1[i], map.getOrDefault(nums1[i], 1)); + for (int j : nums1) { + map.put(j, 1); } - for (int i = 0; i < nums2.length; i++) { - if (map.containsKey(nums2[i]) && map.get(nums2[i]) > 0) { - result.add(nums2[i]); - map.put(nums2[i], map.get(nums2[i]) - 1); + for (int j : nums2) { + if (map.containsKey(j) && map.get(j) > 0) { + result.add(j); + map.put(j, map.get(j) - 1); } } @@ -51,7 +51,7 @@ public int[] intersect(int[] nums1, int[] nums2) { } //What if the given array is already sorted? How would you optimize your algorithm? - // Classic two pointer iteration, i points to nums1 and j points to nums2. + // Classic two pointer iteration, i points to nums1 and j points to nums2. // Because a sorted array is in ascending order, so if nums1[i] > nums[j], we need to increment j, and vice versa. // Only when nums1[i] == nums[j], we add it to the result array. Time Complexity O(max(N, M)) public int[] intersectSorted(int[] nums1, int[] nums2) { @@ -60,20 +60,47 @@ public int[] intersectSorted(int[] nums1, int[] nums2) { int n = nums1.length, m = nums2.length; int i = 0, j = 0; List list = new ArrayList<>(); - while(i < n && j < m){ - int a = nums1[i], b= nums2[j]; - if(a == b){ + while (i < n && j < m) { + int a = nums1[i], b = nums2[j]; + if (a == b) { list.add(a); i++; j++; - }else if(a < b){ + } else if (a < b) { i++; - }else{ + } else { j++; } } int[] ret = new int[list.size()]; - for(int k = 0; k < list.size();k++) ret[k] = list.get(k); + for (int k = 0; k < list.size(); k++) ret[k] = list.get(k); return ret; } + + public List arraysIntersection(int[] arr1, int[] arr2, int[] arr3) { + + List result = new ArrayList<>(); + + int i = 0; + int j = 0; + int k = 0; + + while (i < arr1.length && j < arr2.length && k < arr3.length) { + if (arr1[i] == arr2[j] && arr2[j] == arr3[k]) { + result.add(arr1[i]); + i++; + j++; + k++; + } else if (arr1[i] < arr2[j]) { + i++; + } else if (arr2[j] < arr3[k]) { + j++; + } else { + k++; + } + } + + return result; + + } } \ No newline at end of file diff --git a/src/main/java/practiceproblems/IsEditOneDistanceAway.java b/src/main/java/practiceproblems/IsEditOneDistanceAway.java new file mode 100644 index 0000000..2a376ca --- /dev/null +++ b/src/main/java/practiceproblems/IsEditOneDistanceAway.java @@ -0,0 +1,89 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/one-edit-distance/ + * + * Insert exactly one character into s to get t. + * Delete exactly one character from s to get t. + * Replace exactly one character of s with a different c + * + * Input: s = "ab", t = "acb" + * Output: true + * Explanation: We can insert 'c' into s to get t. + */ +public class IsEditOneDistanceAway { + static boolean isOneEdit(String first, String second) { + // if the input string are same + if (first.equals(second)) + return false; + + int len1 = first.length(); + int len2 = second.length(); + // If the length difference of the stings is more than 1, return false. + if ((len1 - len2) > 1 || (len2 - len1) > 1) { + return false; + } + int i = 0, j = 0; + int diff = 0; + while (i < len1 && j < len2) { + char f = first.charAt(i); + char s = second.charAt(j); + if (f != s) { + diff++; + // delete a character + if (len1 > len2) { + i++; + } + // add a character + if (len2 > len1) { + j++; + } + // replace a character + if (len1 == len2) { + i++; + j++; + } + + } else { + i++; + j++; + } + if (diff > 1) { + return false; + } + } + // If the length of the string is not same. ex. "abc" and "abde" are not one + // edit distance. + return diff != 1 || len1 == len2 || (i == len1 && j == len2); + } + + /* + * There are 3 possibilities to satisfy one edit distance apart: + * + * 1) Replace 1 char: + s: a B c + t: a D c + * 2) Delete 1 char from s: + s: a D b c + t: a b c + * 3) Delete 1 char from t + s: a b c + t: a D b c + * + * tricky substring + */ + public boolean isOneEditDistance(String s, String t) { + for (int i = 0; i < Math.min(s.length(), t.length()); i++) { + if (s.charAt(i) != t.charAt(i)) { + if (s.length() == t.length()) // s has the same length as t, so the only possibility is replacing one char in s and t + return s.substring(i + 1).equals(t.substring(i + 1)); + else if (s.length() < t.length()) // t is longer than s, so the only possibility is deleting one char from t + return s.substring(i).equals(t.substring(i + 1)); + else // s is longer than t, so the only possibility is deleting one char from s + return t.substring(i).equals(s.substring(i + 1)); + } + } + //All previous chars are the same, the only possibility is deleting the end char in the longer one of s and t + return Math.abs(s.length() - t.length()) == 1; + } +} \ No newline at end of file diff --git a/src/practiceproblems/IsSubsequence.java b/src/main/java/practiceproblems/IsSubsequence.java similarity index 51% rename from src/practiceproblems/IsSubsequence.java rename to src/main/java/practiceproblems/IsSubsequence.java index 6491928..9e1e4c3 100644 --- a/src/practiceproblems/IsSubsequence.java +++ b/src/main/java/practiceproblems/IsSubsequence.java @@ -6,17 +6,18 @@ public class IsSubsequence { // Input: s = "axc", t = "ahbgdc" // Output: false public boolean isSubsequence(String s, String t) { - if(s==null || t==null) return false; - int i=0; int j=0; - - while(i 'a' and 'g' -> 'd'. + * Instead of directly mapping 'e' to 'a', another way is to mark them with same value, + * for example, 'e' -> 1, 'a'-> 1, and 'g' -> 2, 'd' -> 2, this works same. + * So we use two arrays here m1 and m2, initialized space is 256 (Since the whole ASCII size is 256, 128 also works here). + * Traverse the character of both s and t on the same position, + * if their mapping values in m1 and m2 are different, means they are not mapping correctly, + * return false; else we construct the mapping, since m1 and m2 are both initialized as 0, + * we want to use a new value when i == 0, so i + 1 works here. + */ +class IsomorphicString { + static boolean isIsomorphic(String s, String t) { + int[] map1 = new int[256]; + int[] map2 = new int[256]; + Arrays.fill(map1, -1); + Arrays.fill(map2, -1); + + int n = s.length(); + for (int i = 0; i < n; i++) { + char c1 = s.charAt(i); + char c2 = t.charAt(i); + // first time to see the two characters + if (map1[c1] == -1 && map2[c2] == -1) { + map1[s.charAt(i)] = i; + map2[t.charAt(i)] = i; + // one of them is seen before or two are mapping to different + } else if (map1[c1] != map2[c2]) { + return false; + } + + } + return true; + } + + public static boolean isIsomorphicEff(String s, String t) { + int[] mappingDictStoT = new int[256]; + Arrays.fill(mappingDictStoT, -1); + + int[] mappingDictTtoS = new int[256]; + Arrays.fill(mappingDictTtoS, -1); + + for (int i = 0; i < s.length(); ++i) { + char c1 = s.charAt(i); + char c2 = t.charAt(i); + + // Case 1: No mapping exists in either of the dictionaries + if (mappingDictStoT[c1] == -1 && mappingDictTtoS[c2] == -1) { + mappingDictStoT[c1] = c2; + mappingDictTtoS[c2] = c1; + } + + // Case 2: Ether mapping doesn't exist in one of the dictionaries or Mapping exists and + // it doesn't match in either of the dictionaries or both + else if (!(mappingDictStoT[c1] == c2 && mappingDictTtoS[c2] == c1)) { + return false; + } + } + + return true; + } + + public static void main(String[] args) { + System.out.println(isIsomorphicEff("abacb", "xyxzy")); + System.out.println(isIsomorphicEff("paper", "title")); + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/KSmallestPairSum.java b/src/main/java/practiceproblems/KSmallestPairSum.java new file mode 100644 index 0000000..d94c227 --- /dev/null +++ b/src/main/java/practiceproblems/KSmallestPairSum.java @@ -0,0 +1,33 @@ +package practiceproblems; + +import java.util.LinkedList; +import java.util.List; +import java.util.PriorityQueue; + +/** + * tricky priority queue + * https://leetcode.com/problems/find-k-pairs-with-smallest-sums/ + * + * Basic idea: Use min_heap to keep track on next minimum pair sum, and we only need to maintain K possible candidates in the data structure. + * + * Some observations: For every numbers in nums1, its best partner(yields min sum) always strats from nums2[0] since arrays are all sorted; + * And for a specific number in nums1, its next candidate sould be [this specific number] + nums2[current_associated_index + 1], unless out of boundary;) + */ +public class KSmallestPairSum { + public List> kSmallestPairs(int[] nums1, int[] nums2, int k) { + PriorityQueue pq = new PriorityQueue<>((a, b) -> a[0] - b[0]); + for (int i = 0; i < nums1.length && i < k; i++) { + pq.add(new int[]{nums1[i] + nums2[0], i, 0}); + } + List> ans = new LinkedList<>(); + while (!pq.isEmpty() && k > 0) { + int[] peek = pq.remove(); + int i = peek[1], j = peek[2]; + ans.add(List.of(nums1[i], nums2[j])); + if (j < nums2.length - 1) + pq.add(new int[]{nums1[i] + nums2[j + 1], i, j + 1}); + k--; + } + return ans; + } +} diff --git a/src/practiceproblems/KmostFrequentLetters.java b/src/main/java/practiceproblems/KmostFrequentLetters.java similarity index 77% rename from src/practiceproblems/KmostFrequentLetters.java rename to src/main/java/practiceproblems/KmostFrequentLetters.java index 9dacc7f..9db2041 100644 --- a/src/practiceproblems/KmostFrequentLetters.java +++ b/src/main/java/practiceproblems/KmostFrequentLetters.java @@ -11,16 +11,14 @@ */ public class KmostFrequentLetters { public static void main(String[] args) { - int k1 = 2; - String[] keywords1 = {"anacell", "cetracular", "betacellular"}; - String[] reviews1 = {"Anacell provides the best services in the city", "betacellular has awesome services", - "Best services provided by anacell, everyone should use anacell",}; +// String[] keywords1 = {"anacell", "cetracular", "betacellular"}; +// String[] reviews1 = {"Anacell provides the best services in the city", "betacellular has awesome services", +// "Best services provided by anacell, everyone should use anacell",}; int k2 = 2; String[] keywords2 = {"anacell", "betacellular", "cetracular", "deltacellular", "eurocell"}; String[] reviews2 = {"I love anacell Best services; Best services provided by anacell", "betacellular has great services", "deltacellular provides much better services than betacellular", "cetracular is worse than anacell", "Betacellular is better than deltacellular.",}; - //System.out.println(solve(k1, keywords1, reviews1)); System.out.println(solve(k2, keywords2, reviews2)); } @@ -39,9 +37,9 @@ private static List solve(int k, String[] keywords, String[] reviews) { } } } - PriorityQueue> maxHeap = new PriorityQueue<>((a, b) -> a.getValue() == b.getValue() ? a.getKey().compareTo(b.getKey()) : b.getValue() - a.getValue()); + PriorityQueue> maxHeap = new PriorityQueue<>((a, b) -> Objects.equals(a.getValue(), b.getValue()) ? a.getKey().compareTo(b.getKey()) : b.getValue() - a.getValue()); maxHeap.addAll(map.entrySet()); - map.entrySet().forEach(e-> System.out.println(e.getKey() +" "+e.getValue())); + map.forEach((key, value) -> System.out.println(key + " " + value)); while (!maxHeap.isEmpty() && k-- > 0) { res.add(maxHeap.poll().getKey()); } diff --git a/src/main/java/practiceproblems/KthCharacterInString.java b/src/main/java/practiceproblems/KthCharacterInString.java new file mode 100644 index 0000000..1ef3706 --- /dev/null +++ b/src/main/java/practiceproblems/KthCharacterInString.java @@ -0,0 +1,41 @@ +package practiceproblems; + +/** + * TODO + * given 2 string s , t we have to find kth character from the string formed by following process lets say x = "" + * i = 1 append s to x 1 time + * i = 2 append t to x 2 times + * i = 3 append s to x 3 times + * i = 4 append t to x 4 times + * i = 5 append s to x 5 times + * and so on + *

+ * you are given k <= 10^16, you have to find kth character from x formed using above process. + * eg: s = "a", t = "bc", k = 4 ---> given input + * Output: b + * (since string x = "abcbcaaabcbcbcbc..... 4th char is b) + */ +public class KthCharacterInString { + + public static char kthCharacter(String s, String t, int k) { + k = k - 1; + for (int i = 1; k >= 0; i++) { + if ((i) % 2 == 1) {//odd s + int currIdxLen1 = (i) * s.length(); + if (currIdxLen1 > k) { // can't reduce k further + return s.charAt(k % s.length()); + } else { + k = k - currIdxLen1; + } + } else { + int currIdxLen = (i) * t.length(); + if (currIdxLen > k) { // can't reduce k further + return t.charAt(k % t.length()); + } else { + k = k - currIdxLen; + } + } + } + return 'x'; + } +} diff --git a/src/main/java/practiceproblems/KthClosestOrigin.java b/src/main/java/practiceproblems/KthClosestOrigin.java new file mode 100644 index 0000000..d1c6701 --- /dev/null +++ b/src/main/java/practiceproblems/KthClosestOrigin.java @@ -0,0 +1,86 @@ +package practiceproblems; + +import java.util.Arrays; +import java.util.PriorityQueue; +import java.util.Random; + +/** + * https://leetcode.com/problems/k-closest-points-to-origin/solution/ + */ +class KthClosestOrigin { + + public int[][] kClosestPQ(int[][] points, int K) { + PriorityQueue pq = new PriorityQueue<>((p1, p2) -> p2[0] * p2[0] + p2[1] * p2[1] - p1[0] * p1[0] - p1[1] * p1[1]); + for (int[] p : points) { + pq.offer(p); + if (pq.size() > K) { + pq.poll(); + } + } + int[][] res = new int[K][2]; + while (K > 0) { + res[--K] = pq.poll(); + } + return res; + } + + + public int[][] kClosest(int[][] points, int k) { + if (k == points.length) { + return points; + } + + int low = 0; + int high = points.length - 1; + int pivotIndex = partition(points, low, high); + + while (pivotIndex != k) { + if (k < pivotIndex) { + high = pivotIndex - 1; + } else { + low = pivotIndex + 1; + } + + pivotIndex = partition(points, low, high); + } + + return Arrays.copyOfRange(points, 0, k); + } + + private int partition(final int[][] points, final int low, final int high) { + if (low >= high) { + return low; + } + + swap(points, low + new Random().nextInt(high - low), high); + + int leftIndex = low; + int rightIndex = high - 1; + + double pivotDistance = distance(points[high]); + + while (leftIndex <= rightIndex) { + if (distance(points[leftIndex]) < pivotDistance) { + leftIndex += 1; + } else { + swap(points, leftIndex, rightIndex); + rightIndex -= 1; + } + } + + swap(points, leftIndex, high); + + return leftIndex; + } + + private void swap(final int[][] points, final int index1, final int index2) { + final int[] temp = points[index1]; + + points[index1] = points[index2]; + points[index2] = temp; + } + + private double distance(final int[] point) { + return Math.sqrt(point[0] * point[0] + point[1] * point[1]); + } +} diff --git a/src/practiceproblems/KthSmallestFromTwoSortedArrays.java b/src/main/java/practiceproblems/KthSmallestFromTwoSortedArrays.java similarity index 94% rename from src/practiceproblems/KthSmallestFromTwoSortedArrays.java rename to src/main/java/practiceproblems/KthSmallestFromTwoSortedArrays.java index 425377e..cbf1417 100644 --- a/src/practiceproblems/KthSmallestFromTwoSortedArrays.java +++ b/src/main/java/practiceproblems/KthSmallestFromTwoSortedArrays.java @@ -2,6 +2,10 @@ /** * https://www.geeksforgeeks.org/k-th-element-two-sorted-arrays/ + * + * https://www.youtube.com/watch?v=nv7F4PiLUzo + * + * TODO */ class KthSmallestFromTwoSortedArrays { diff --git a/src/main/java/practiceproblems/KthSmallestMatrix.java b/src/main/java/practiceproblems/KthSmallestMatrix.java new file mode 100644 index 0000000..ddca7ce --- /dev/null +++ b/src/main/java/practiceproblems/KthSmallestMatrix.java @@ -0,0 +1,48 @@ +package practiceproblems; + +import java.util.Comparator; +import java.util.PriorityQueue; + +/** + * https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/ + */ +public class KthSmallestMatrix { + public static int kthSmallest(int[][] matrix, int k) { + PriorityQueue minQueue = new PriorityQueue<>(Comparator.comparingInt(a -> a.value)); + + for (int i = 0; i < matrix[0].length; i++) { + minQueue.offer(new Pair(matrix[0][i], 0, i)); + } + k--; + while (k-- > 0 && !minQueue.isEmpty()) { + Pair temp = minQueue.poll(); + if (temp.x + 1 >= matrix.length) continue; + minQueue.offer(new Pair(matrix[temp.x + 1][temp.y], temp.x + 1, temp.y)); + } + return minQueue.isEmpty() ? -1 : minQueue.peek().value; + } + + public static void main(String[] args) { + int[][] matrix = {{1, 2, 9}, {3, 11, 13}, {4, 13, 15}}; + int k = 4; + + System.out.println(kthSmallest(matrix, k)); + } + + static class Pair { + int value; + int x; + int y; + + public Pair(int value, int x, int y) { + this.value = value; + this.x = x; + this.y = y; + } + + @Override + public String toString() { + return this.value + " "; + } + } +} \ No newline at end of file diff --git a/src/practiceproblems/LargestDivisibleSubset.java b/src/main/java/practiceproblems/LargestDivisibleSubset.java similarity index 84% rename from src/practiceproblems/LargestDivisibleSubset.java rename to src/main/java/practiceproblems/LargestDivisibleSubset.java index d38fa2a..5d68882 100644 --- a/src/practiceproblems/LargestDivisibleSubset.java +++ b/src/main/java/practiceproblems/LargestDivisibleSubset.java @@ -41,20 +41,20 @@ public List largestDivisibleSubset(int[] nums) { int maxLength=0; int resIndex=-1; - List re; + List tempList; for(int i=nums.length-1;i>=0;i--){ result[i]=new ArrayList<>(); // every element is an answer itself - re= new ArrayList<>(); + tempList= new ArrayList<>(); result[i].add(nums[i]); for(int j=i+1;j re.size()){ // this is to take even if 1 element is at j position - re=result[j]; // the reason we take list is consider 4,8,24 when i is at 4 and j is 8 mod is 0 means 4%24 is also zero + if(result[j].size() > tempList.size()){ // this is to take even if 1 element is at j position + tempList=result[j]; // the reason we take list is consider 4,8,24 when i is at 4 and j is 8 mod is 0 means 4%24 is also zero } } } - result[i].addAll(re); + result[i].addAll(tempList); if(result[i].size()>maxLength){ maxLength=result[i].size(); resIndex=i; diff --git a/src/practiceproblems/LargestPossibleNumber.java b/src/main/java/practiceproblems/LargestPossibleNumber.java similarity index 81% rename from src/practiceproblems/LargestPossibleNumber.java rename to src/main/java/practiceproblems/LargestPossibleNumber.java index 0acbc49..cb397eb 100644 --- a/src/practiceproblems/LargestPossibleNumber.java +++ b/src/main/java/practiceproblems/LargestPossibleNumber.java @@ -14,8 +14,8 @@ public static void main(String[] args) { int nums[] = { 10, 68, 97, 9, 21, 12 }; List numbers = Arrays.asList("10", "68", "97", "9", "21", "12"); - Collections.sort(numbers, (a, b) -> (b + a).compareTo(a + b)); - numbers.stream().forEach(System.out::print); + numbers.sort((a, b) -> (b + a).compareTo(a + b)); + numbers.forEach(System.out::print); System.out.println(new LargestPossibleNumber().largestNumber(nums)); } @@ -25,9 +25,7 @@ public String largestNumber(int[] nums) { arr[i] = String.valueOf(nums[i]); } - Arrays.sort(arr, (a, b) -> { - return (b + a).compareTo(a + b); - }); + Arrays.sort(arr, (a, b) -> (b + a).compareTo(a + b)); StringBuilder sb = new StringBuilder(); for (String s : arr) { @@ -47,7 +45,7 @@ public String largestNumber1(int[] nums) { list.add(String.valueOf(i)); } - Collections.sort(list, (a,b)->(int)(Long.parseLong(b+a)-Long.parseLong(a+b))); + list.sort((a, b) -> (int) (Long.parseLong(b + a) - Long.parseLong(a + b))); return String.join("",list).replaceFirst("^0+(?!$)", ""); diff --git a/src/main/java/practiceproblems/LargestSubArrayWithZeroesAndOnes.java b/src/main/java/practiceproblems/LargestSubArrayWithZeroesAndOnes.java new file mode 100644 index 0000000..94e2e70 --- /dev/null +++ b/src/main/java/practiceproblems/LargestSubArrayWithZeroesAndOnes.java @@ -0,0 +1,67 @@ +package practiceproblems; + +import java.util.HashMap; + +/** + * https://www.geeksforgeeks.org/largest-subarray-with-equal-number-of-0s-and-1s/ + * Given an array containing only 0s and 1s, find the largest subarray which contains equal no of 0s and 1s. + * Expected time complexity is O(n). + */ +class LargestSubArrayWithZeroesAndOnes { + /** + * The concept of taking cumulative sum, taking 0’s as -1 will help us in optimising the approach. + * While taking the cumulative sum, there are two cases when there can be a sub-array with equal number of 0’s and 1’s + * When cumulative sum=0, which signifies that sub-array from index (0) till present index has equal number of 0’s and 1’s. + *

+ * When we encounter a cumulative sum value which we have already encountered before, + * which means that sub-array from the previous index+1 till the present index has equal number of 0’s and 1’s as they give a cumulative sum of 0 . + * + */ + int maxLen(int[] arr, int n) { + + HashMap map = new HashMap<>(); + + int sum = 0; + int maxLength = 0; + int endingIndex = -1; + + for (int i = 0; i < n; i++) { + arr[i] = (arr[i] == 0) ? -1 : 1; + } + + for (int i = 0; i < n; i++) { + sum += arr[i]; + + if (sum == 0) { // To handle sum=0 at last index + maxLength = i + 1; + endingIndex = i; + } + // If this sum is seen before, + // then update max_len if required + if (map.containsKey(sum)) { + if (maxLength < i - map.get(sum)) { + maxLength = i - map.get(sum); + endingIndex = i; + } + } else + map.put(sum, i); + } + + for (int i = 0; i < n; i++) { + arr[i] = (arr[i] == -1) ? 0 : 1; + } + + int start = endingIndex - maxLength + 1; + System.out.println(start + " to " + endingIndex); + + return maxLength; + } + + public static void main(String[] args) { + LargestSubArrayWithZeroesAndOnes sub = new LargestSubArrayWithZeroesAndOnes(); + int arr[] = {0, 0, 0, 1, 0, 1, 1}; + int n = arr.length; + + sub.maxLen(arr, n); + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/LargestTimeFromDigits.java b/src/main/java/practiceproblems/LargestTimeFromDigits.java new file mode 100644 index 0000000..f85ae43 --- /dev/null +++ b/src/main/java/practiceproblems/LargestTimeFromDigits.java @@ -0,0 +1,40 @@ +package practiceproblems; + +/** + * TODO + * + * Given an array of 4 digits, return the largest 24 hour time that can be made. + * The smallest 24 hour time is 00:00, and the largest is 23:59. + * Starting from 00:00, a time is larger if more time has elapsed since midnight. + * Return the answer as a string of length 5. If no valid time can be made, return an empty string. + */ +public class LargestTimeFromDigits { + public String largestTimeFromDigits(int[] A) { + if (A == null || A.length == 0) return ""; + String result = ""; + // because A.length == 4 + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + for (int k = 0; k < 4; k++) { + //We cannot take a number twice. i, j, k and (6-i-j-k) denoting the indices of 4 numbers should be distinct. + if (i == j || j == k || k == i) continue; + String hrs = A[i] + "" + A[j]; + //We are trying out all possible ordering, + //indices of 4 numbers are 0, 1, 2, and 3. + //sum of indices = 0 + 1 + 2 + 3= 6 + //i, j and k denote 3 indices. + //So, if we know 3 numbers, + //the 4th number will be the remaining index, i.e., 6-i-j-k + + String mins = A[k] + "" + A[6 - i - j - k]; + + if (hrs.compareTo("24") < 0 && mins.compareTo("59") < 0 && result.compareTo(hrs + ":" + mins) < 0) { + result = hrs + ":" + mins; + } + + } + } + } + return result; + } +} \ No newline at end of file diff --git a/src/practiceproblems/LeftMostColumnWithOne.java b/src/main/java/practiceproblems/LeftMostColumnWithOne.java similarity index 69% rename from src/practiceproblems/LeftMostColumnWithOne.java rename to src/main/java/practiceproblems/LeftMostColumnWithOne.java index fbbfe27..be49d9c 100644 --- a/src/practiceproblems/LeftMostColumnWithOne.java +++ b/src/main/java/practiceproblems/LeftMostColumnWithOne.java @@ -4,36 +4,41 @@ /** * A binary matrix means that all elements are 0 or 1. For each individual row of the matrix, this row is sorted in non-decreasing order. - * + *

* Given a row-sorted binary matrix binaryMatrix, return leftmost column index(0-indexed) with at least a 1 in it. If such index doesn’t exist, return -1. - * + *

* You can’t access the Binary Matrix directly. You may only access the matrix using a BinaryMatrix interface: - * + *

* BinaryMatrix.get(row, col) returns the element of the matrix at index (row, col) (0-indexed). * BinaryMatrix.dimensions() returns a list of 2 elements [rows, cols], which means the matrix is rows * cols. * Submissions making more than 1000 calls to BinaryMatrix.get will be judged Wrong Answer. * Also, any solutions that attempt to circumvent the judge will result in disqualification */ interface BinaryMatrix { - public int get(int row, int col); + public int get(int row, int col); + public List dimensions(); - } +} + public class LeftMostColumnWithOne { + /** + * tricky binary search + * + */ public int leftMostColumnWithOne(BinaryMatrix binaryMatrix) { - List dimension=binaryMatrix.dimensions(); - int n=dimension.get(0); - int m=dimension.get(1); + List dimension = binaryMatrix.dimensions(); + int n = dimension.get(0); + int m = dimension.get(1); - int i=0,j=m-1,leftMostOne=-1; // start from 0th row and last column + int i = 0, j = m - 1, leftMostOne = -1; // start from 0th row and last column - while(i=0) - { - int result=binaryMatrix.get(i,j); - if(result==0) + while (i < n && j >= 0) { + int result = binaryMatrix.get(i, j); + if (result == 0) i++; - else{ - leftMostOne=j; + else { + leftMostOne = j; j--; } } diff --git a/src/practiceproblems/LengthOfLongestSubstringKDistinct.java b/src/main/java/practiceproblems/LengthOfLongestSubstringKDistinct.java similarity index 91% rename from src/practiceproblems/LengthOfLongestSubstringKDistinct.java rename to src/main/java/practiceproblems/LengthOfLongestSubstringKDistinct.java index ca45e65..b96dc11 100644 --- a/src/practiceproblems/LengthOfLongestSubstringKDistinct.java +++ b/src/main/java/practiceproblems/LengthOfLongestSubstringKDistinct.java @@ -5,14 +5,13 @@ import java.util.Map; import java.util.Set; +/** + * https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters + */ public class LengthOfLongestSubstringKDistinct { public static final int CHAR_RANGE = 128; - /** - * @param s: A string - * @param k: An integer - * @return: An integer - */ + public static int lengthOfLongestSubstringKDistinct(String s, int k) { if (s == null || k == 0) { return 0; @@ -45,8 +44,7 @@ public static void main(String[] args) { System.out.println(lengthOfLongestSubstringKDistinct("aaaaaa", 2)); } - public static String findLongestSubstring(String str, int k) - { + public static String findLongestSubstring(String str, int k) { // stores the longest substring boundaries int end = 0, begin = 0; @@ -58,14 +56,12 @@ public static String findLongestSubstring(String str, int k) int[] freq = new int[CHAR_RANGE]; // `[low…high]` maintains the sliding window boundaries - for (int low = 0, high = 0; high < str.length(); high++) - { + for (int low = 0, high = 0; high < str.length(); high++) { window.add(str.charAt(high)); freq[str.charAt(high)]++; // if the window size is more than `k`, remove characters from the left - while (window.size() > k) - { + while (window.size() > k) { // If the leftmost character's frequency becomes 0 after // removing it in the window, remove it from the set as well if (--freq[str.charAt(low)] == 0) { @@ -76,8 +72,7 @@ public static String findLongestSubstring(String str, int k) } // update the maximum window size if necessary - if (end - begin < high - low) - { + if (end - begin < high - low) { end = high; begin = low; } diff --git a/src/practiceproblems/LongestConsequtiveSequence.java b/src/main/java/practiceproblems/LongestConsequtiveSequence.java similarity index 88% rename from src/practiceproblems/LongestConsequtiveSequence.java rename to src/main/java/practiceproblems/LongestConsequtiveSequence.java index 5ee2e4a..aaeee12 100644 --- a/src/practiceproblems/LongestConsequtiveSequence.java +++ b/src/main/java/practiceproblems/LongestConsequtiveSequence.java @@ -7,7 +7,7 @@ /** * Given an unsorted array of integers, * find the length of the longest consecutive elements sequence. - * + *

* Your algorithm should run in O(n) complexity. * Input: [100, 4, 200, 1, 3, 2] * Output: 4 @@ -47,6 +47,9 @@ public int longestConsecutive(int[] nums) { return max; } + /** + * tricky traversal array + */ public int longestConsecutiveSorting(int[] nums) { if (nums == null || nums.length == 0) return 0; @@ -57,11 +60,10 @@ public int longestConsecutiveSorting(int[] nums) { int currentStreak = 1; for (int i = 0; i < nums.length - 1; i++) { - if (nums[i] != nums[i+1]) { // avoid duplicate - if (nums[i] + 1 == nums[i+1]) { // if increasing increase streak count else reset + if (nums[i] != nums[i + 1]) { // avoid duplicate + if (nums[i] + 1 == nums[i + 1]) { // if increasing then increase streak count else reset currentStreak += 1; - } - else { + } else { longestStreak = Math.max(longestStreak, currentStreak); currentStreak = 1; } diff --git a/src/main/java/practiceproblems/LongestDiverseString.java b/src/main/java/practiceproblems/LongestDiverseString.java new file mode 100644 index 0000000..649e339 --- /dev/null +++ b/src/main/java/practiceproblems/LongestDiverseString.java @@ -0,0 +1,72 @@ +package practiceproblems; + +import java.util.PriorityQueue; + +/** + * https://leetcode.com/problems/longest-happy-string + * + * Input: a = 1, b = 1, c = 7 + * Output: "ccaccbcc" + * Explanation: "ccbccacc" would also be a correct answer. + */ +public class LongestDiverseString { + public String longestDiverseString(int a, int b, int c) { + StringBuilder builder = new StringBuilder(); + PriorityQueue pq = new PriorityQueue( + (count1, count2) -> Integer.compare(count2.count, count1.count)); + + if (a > 0) + pq.add(new Pair('a', a)); + if (b > 0) + pq.add(new Pair('b', b)); + if (c > 0) + pq.add(new Pair('c', c)); + + while (pq.size() >= 2) { + Pair pair_one = pq.poll(); + if (pair_one.count >= 2) { + builder.append(pair_one.ch); + builder.append(pair_one.ch); + pair_one.count -= 2; + } else { + builder.append(pair_one.ch); + pair_one.count -= 1; + } + + Pair pair_two = pq.poll(); + if (pair_two.count >= 2 && pair_one.count < pair_two.count) { + builder.append(pair_two.ch); + builder.append(pair_two.ch); + pair_two.count -= 2; + } else { + builder.append(pair_two.ch); + pair_two.count -= 1; + } + + if (pair_one.count > 0) + pq.add(pair_one); + if (pair_two.count > 0) + pq.add(pair_two); + } + + if (!pq.isEmpty()) { + if (pq.peek().count >= 2) { + builder.append(pq.peek().ch); + builder.append(pq.peek().ch); + } else { + builder.append(pq.peek().ch); + } + } + return builder.toString(); + } + + static class Pair { + public Character ch; + int count; + + public Pair(Character ch, int count) { + this.ch = ch; + this.count = count; + } + } +} diff --git a/src/practiceproblems/LIS2DMatrix.java b/src/main/java/practiceproblems/LongestIncreasingPathInMatrix.java similarity index 64% rename from src/practiceproblems/LIS2DMatrix.java rename to src/main/java/practiceproblems/LongestIncreasingPathInMatrix.java index abae2bf..0768ad0 100644 --- a/src/practiceproblems/LIS2DMatrix.java +++ b/src/main/java/practiceproblems/LongestIncreasingPathInMatrix.java @@ -1,21 +1,29 @@ package practiceproblems; /** + * tricky dfs + * + * https://leetcode.com/problems/longest-increasing-path-in-a-matrix + *

+ * Do DFS from every cell + * Compare every 4 direction and skip cells that are out of boundary or smaller + * Get matrix max from every cell's max + * Use matrix[x][y] <= matrix[i][j] so we don't need a visited[m][n] array + * The key is to cache the distance because it's highly possible to revisit a cell + *

* DFS + Memoization *

* Traverse all points in matrix, use every point as starting point to do dfs traversal. DFS function returns max increasing * path after comparing four max return distance from four directions. */ +public class LongestIncreasingPathInMatrix { -class LIS2DMatrix { int[][] dirs = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; public int longestIncreasingPath(int[][] matrix) { - if (matrix.length == 0) return 0; - // i+1,j, i-1,j i,j+1 i,j-1 Integer[][] cache = new Integer[matrix.length][matrix[0].length]; - //Arrays.fill(cache,-1); + int result = 0; for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[0].length; j++) { @@ -32,21 +40,21 @@ public int dfsUtil(int[][] matrix, int i, int j, Integer[][] cache, int data) { if (cache[i][j] != null) return cache[i][j]; - int max = 1; // every element is an answer to itself + // initialize max distance as 1 since the path includes starting point itself + int max = 1; for (int[] dir : dirs) { int x = i + dir[0]; int y = j + dir[1]; - + // if next point is a valid point, add curLen by 1 and continue DFS traversal int count = 1 + dfsUtil(matrix, x, y, cache, matrix[i][j]); max = Math.max(count, max); } + // update max increasing path value starting from current point in cache cache[i][j] = max; return cache[i][j]; } - - -} \ No newline at end of file +} diff --git a/src/practiceproblems/LongestRepeatCharReplace.java b/src/main/java/practiceproblems/LongestRepeatCharReplace.java similarity index 58% rename from src/practiceproblems/LongestRepeatCharReplace.java rename to src/main/java/practiceproblems/LongestRepeatCharReplace.java index f5ab7df..55f6666 100644 --- a/src/practiceproblems/LongestRepeatCharReplace.java +++ b/src/main/java/practiceproblems/LongestRepeatCharReplace.java @@ -1,31 +1,28 @@ package practiceproblems; -// you can perform at most k operations on that string. -// In one operation, you can choose any character of the string and change it to any other uppercase English character. -// Find the length of the longest sub-string containing all repeating letters -// s = "ABAB", k = 2 -// Output: -// 4 -// Explanation: -// Replace the two 'A's with two 'B's or vice versa. +/** + * https://leetcode.com/problems/longest-repeating-character-replacement/ + * + * revise + */ public class LongestRepeatCharReplace { public int characterReplacement(String s, int k) { - if(s==null || s.length()==0) return 0; - - int[] cache= new int[26]; - int left=0; - int right=0; - int result=0; - int maxOccured=0; - while(right 0, then we have characters in the window that are NOT the character that occurs the most. // end-start+1-maxCount is equal to exactly the # of characters that are NOT the character that occurs the most in that window. //Example: For a window "xxxyz", end-start+1-maxCount would equal 2. (maxCount is 3 and there are 2 characters here, "y" and "z" that are not "x" in the window.) @@ -33,15 +30,15 @@ public int characterReplacement(String s, int k) { //then there are more characters in the window than we can replace, and we need to shrink the window. // If we have window with "xxxy" and k = 1, that's fine because end-start+1-maxCount = 1, which is not > k. maxLength gets updated to 4. // But if we then find a "z" after, like "xxxyz", then we need to shrink the window because now end-start+1-maxCount = 2, and 2 > 1. The window becomes "xxyz". - if(right-left+1-maxOccured > k){ - char leftchr= s.charAt(left); - --cache[leftchr-'A']; + while (right - left + 1 - maxOccurred > k) { + char leftChr = s.charAt(left); + --cache[leftChr - 'A']; left++; } - result=Math.max(result, right-left+1); + result = Math.max(result, right - left + 1); right++; } - + return result; } } \ No newline at end of file diff --git a/src/practiceproblems/LongestSpanWithSameSumArray.java b/src/main/java/practiceproblems/LongestSpanWithSameSumArray.java similarity index 86% rename from src/practiceproblems/LongestSpanWithSameSumArray.java rename to src/main/java/practiceproblems/LongestSpanWithSameSumArray.java index ef73db9..debe2b5 100644 --- a/src/practiceproblems/LongestSpanWithSameSumArray.java +++ b/src/main/java/practiceproblems/LongestSpanWithSameSumArray.java @@ -7,25 +7,23 @@ * Given two binary arrays arr1[] and arr2[] of same size n. * Find length of the longest common span (i, j) * where j >= i such that arr1[i] + arr1[i+1] + …. + arr1[j] = arr2[i] + arr2[i+1] + …. + arr2[j]. - * + *

* Expected time complexity is Θ(n). - * + *

* Input: arr1[] = {0, 1, 0, 0, 0, 0}; - * arr2[] = {1, 0, 1, 0, 0, 1}; + * arr2[] = {1, 0, 1, 0, 0, 1}; * Output: 4 * The longest span with same sum is from index 1 to 4. - * + *

* Input: arr1[] = {0, 1, 0, 1, 1, 1, 1}; - * arr2[] = {1, 1, 1, 1, 1, 0, 1}; + * arr2[] = {1, 1, 1, 1, 1, 0, 1}; * Output: 6 * The longest span with same sum is from index 1 to 6. - * - * */ + */ class LongestSpanWithSameSumArray { // Returns largest common subarray with equal // number of 0s and 1s - static int longestCommonSum(int[] arr1, int[] arr2, int n) - { + static int longestCommonSum(int[] arr1, int[] arr2, int n) { // Find difference between the two int[] arr = new int[n]; // the reason we take the difference is, the resultant array @@ -41,8 +39,7 @@ static int longestCommonSum(int[] arr1, int[] arr2, int n) int max_len = 0; // Initialize result // Traverse through the given array - for (int i = 0; i < n; i++) - { + for (int i = 0; i < n; i++) { // Add current element to sum sum += arr[i]; @@ -65,8 +62,8 @@ static int longestCommonSum(int[] arr1, int[] arr2, int n) public static void main(String args[]) { /* int[] arr1 = {0, 1, 0, 1, 1, 1, 1}; int[] arr2 = {1, 1, 1, 1, 1, 0, 1};*/ - int arr1[] = { 0, 1, 0, 0, 1, 1, 1, 0 }; - int arr2[] = { 1, 1, 1, 1, 1, 1, 0, 1 }; + int arr1[] = {0, 1, 0, 0, 1, 1, 1, 0}; + int arr2[] = {1, 1, 1, 1, 1, 1, 0, 1}; //{-1,0,-1,0,0,1,0} int n = arr1.length; System.out.println(longestCommonSum(arr1, arr2, n)); diff --git a/src/practiceproblems/LongestSubArraySumUtmostK.java b/src/main/java/practiceproblems/LongestSubArraySumUtmostK.java similarity index 77% rename from src/practiceproblems/LongestSubArraySumUtmostK.java rename to src/main/java/practiceproblems/LongestSubArraySumUtmostK.java index fe9f864..867d142 100644 --- a/src/practiceproblems/LongestSubArraySumUtmostK.java +++ b/src/main/java/practiceproblems/LongestSubArraySumUtmostK.java @@ -1,26 +1,28 @@ package practiceproblems; /** - * https://www.geeksforgeeks.org/longest-subarray-sum-elements-atmost-k/ + * revise * + * https://www.geeksforgeeks.org/longest-subarray-sum-elements-atmost-k/ + *

* Given an array of integers, * our goal is to find the length of largest subarray * having sum of its elements atmost ‘k’ where k>0. - * + *

* Examples: - * + *

* Input : arr[] = {1, 2, 1, 0, 1, 1, 0}, - * k = 4 + * k = 4 * Output : 5 * Explanation: - * {1, 2, 1} => sum = 4, length = 3 - * {1, 2, 1, 0}, {2, 1, 0, 1} => sum = 4, length = 4 - * {1, 0, 1, 1, 0} =>5 sum = 3, length = 5 + * {1, 2, 1} => sum = 4, length = 3 + * {1, 2, 1, 0}, {2, 1, 0, 1} => sum = 4, length = 4 + * {1, 0, 1, 1, 0} =>5 sum = 3, length = 5 */ // array is non-negative class LongestSubArraySumUtmostK { - public static int utMostSum(int arr[], int n, int target) { + public static int utMostSum(int[] arr, int n, int target) { int sum = 0; int count = 0; int maxCount = 0; @@ -38,7 +40,7 @@ public static int utMostSum(int arr[], int n, int target) { } public static void main(String[] args) { - int arr[] = { 1, 2, 1, 0, 1, 1, 0 }; + int arr[] = {1, 2, 1, 0, 1, 1, 0}; int n = arr.length; int k = 4; diff --git a/src/practiceproblems/LongestUniqueSubstring.java b/src/main/java/practiceproblems/LongestUniqueSubstring.java similarity index 80% rename from src/practiceproblems/LongestUniqueSubstring.java rename to src/main/java/practiceproblems/LongestUniqueSubstring.java index 3fc1f5f..0a617e9 100644 --- a/src/practiceproblems/LongestUniqueSubstring.java +++ b/src/main/java/practiceproblems/LongestUniqueSubstring.java @@ -3,7 +3,10 @@ import java.util.HashMap; import java.util.Map; -/*https://leetcode.com/problems/longest-substring-without-repeating-characters/*/ +/** + * https://leetcode.com/problems/longest-substring-without-repeating-characters/ + */ + public class LongestUniqueSubstring { public static int lengthOfLongestSubstring(String s) { @@ -19,7 +22,6 @@ public static int lengthOfLongestSubstring(String s) { if (map.get(c) > 1) { counter++; } - end++; while (counter > 0) { char charTemp = s.charAt(begin); @@ -29,24 +31,27 @@ public static int lengthOfLongestSubstring(String s) { map.put(charTemp, map.get(charTemp) - 1); begin++; } - result = Math.max(result, end - begin); + result = Math.max(result, end - begin + 1); + end++; } return result; } + public static int lengthOfLongestSubstringOpt(String s) { int res = 0, n = s.length(); int[] arr = new int[256]; - int startIndex=0; - for(int curr=0;curr next index, so that we can start from here - arr[s.charAt(curr)] = curr+1; + arr[s.charAt(curr)] = curr + 1; } return res; } + public static void main(String[] args) { System.out.println(lengthOfLongestSubstringOpt("pwwkew")); } diff --git a/src/practiceproblems/MajorityVoting.java b/src/main/java/practiceproblems/MajorityVoting.java similarity index 62% rename from src/practiceproblems/MajorityVoting.java rename to src/main/java/practiceproblems/MajorityVoting.java index fc5b390..21874af 100644 --- a/src/practiceproblems/MajorityVoting.java +++ b/src/main/java/practiceproblems/MajorityVoting.java @@ -16,16 +16,16 @@ public static List majorityElementII(int[] nums) { int count1 = 0; int count2 = 0; int len = nums.length; - for (int i = 0; i < len; i++) { - if (nums[i] == candidate1) { + for (int num : nums) { + if (num == candidate1) { count1++; - } else if (nums[i] == candidate2) { + } else if (num == candidate2) { count2++; } else if (count1 == 0) { - candidate1 = nums[i]; + candidate1 = num; count1 = 1; } else if (count2 == 0) { - candidate2 = nums[i]; + candidate2 = num; count2 = 1; } else { count1--; @@ -34,10 +34,10 @@ public static List majorityElementII(int[] nums) { } count1 = 0; count2 = 0; - for (int i = 0; i < len; i++) { - if (nums[i] == candidate1) { + for (int num : nums) { + if (num == candidate1) { count1++; - } else if (nums[i] == candidate2) { + } else if (num == candidate2) { count2++; } } @@ -51,33 +51,26 @@ public static List majorityElementII(int[] nums) { } public static int majorityElementI(int[] nums) { - int count = 1; - int candidate = nums[0]; - int majority = nums.length / 2; + int count = 0; + int majorElem = 0; - for (int i = 1; i < nums.length; i++) { - if (candidate == nums[i]) { - count++; - } else if (count == 0) { + for (int i : nums) { + if (count == 0) { + majorElem = i; + } + if (i == majorElem) { count++; - candidate = nums[i]; } else { count--; } - } - //what if array is even and it has many elements - count = 0; - for (int num : nums) { - if (num == candidate) { - count++; - } + } - return count > majority ? candidate : 0; + return majorElem; } public static void main(String[] args) { - int[] arr = { 1, 1, 1, 1, 1, 2, 2, 4, 4, 4, 4, 4, 2, 2 }; + int[] arr = {1, 1, 1, 1, 1, 2, 2, 4, 4, 4, 4, 4, 2, 2}; System.out.println(majorityElementI(arr)); System.out.println(majorityElementII(arr)); diff --git a/src/practiceproblems/MakeAnArrayPalindrome.java b/src/main/java/practiceproblems/MakeAnArrayPalindrome.java similarity index 88% rename from src/practiceproblems/MakeAnArrayPalindrome.java rename to src/main/java/practiceproblems/MakeAnArrayPalindrome.java index 25210c1..bf7ba7b 100644 --- a/src/practiceproblems/MakeAnArrayPalindrome.java +++ b/src/main/java/practiceproblems/MakeAnArrayPalindrome.java @@ -1,6 +1,9 @@ package practiceproblems; +import java.util.Arrays; + /** + * tricky palindrome * https://www.geeksforgeeks.org/find-minimum-number-of-merge-operations-to-make-an-array-palindrome/ */ class MakeAnArrayPalindrome { @@ -29,12 +32,12 @@ else if (arr[i] > arr[j]) { ans++; } } - + System.out.println(Arrays.toString(arr)); return ans; } public static void main(String[] args) { - int arr[] = new int[] { 1, 4, 5, 9, 1 }; + int arr[] = new int[]{1, 4, 5, 9, 1}; System.out.println("Count of minimum operations is " + findMinOps(arr, arr.length)); } diff --git a/src/practiceproblems/MatrixRowWithMax1.java b/src/main/java/practiceproblems/MatrixRowWithMax1.java similarity index 92% rename from src/practiceproblems/MatrixRowWithMax1.java rename to src/main/java/practiceproblems/MatrixRowWithMax1.java index 4f6e33c..0af8c4d 100644 --- a/src/practiceproblems/MatrixRowWithMax1.java +++ b/src/main/java/practiceproblems/MatrixRowWithMax1.java @@ -6,7 +6,7 @@ public class MatrixRowWithMax1 { public static void main(String[] args) { - int[][] mat = { { 0, 0, 0, 1 }, { 0, 1, 1, 1 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 } }; + int[][] mat = {{0, 0, 0, 1}, {0, 1, 1, 1}, {1, 1, 1, 1}, {0, 0, 0, 0}}; System.out.println(rowWithMax1s(mat)); } diff --git a/src/practiceproblems/MaxDistinctElementAfterKRemoval.java b/src/main/java/practiceproblems/MaxDistinctElementAfterKRemoval.java similarity index 97% rename from src/practiceproblems/MaxDistinctElementAfterKRemoval.java rename to src/main/java/practiceproblems/MaxDistinctElementAfterKRemoval.java index 3e2c2d2..86e29d1 100644 --- a/src/practiceproblems/MaxDistinctElementAfterKRemoval.java +++ b/src/main/java/practiceproblems/MaxDistinctElementAfterKRemoval.java @@ -25,10 +25,6 @@ public class MaxDistinctElementAfterKRemoval { * Insert frequency of each element in a max heap. * Now, perform the following operation k times. * Remove an element from the max heap. Decrement its value by 1. After this if element is not equal to 0, then again push the element in the max heap. - * @param arr - * @param n - * @param k - * @return */ static int maxDistinctNum(int[] arr, int n, int k) { @@ -67,7 +63,7 @@ static int maxDistinctNum(int[] arr, int n, int k) // Count all those elements that appear // once after above operations. int res = 0; - while (pq.size() != 0) { + while (!pq.isEmpty()) { pq.poll(); res++; } diff --git a/src/main/java/practiceproblems/MaxPointsInLine.java b/src/main/java/practiceproblems/MaxPointsInLine.java new file mode 100644 index 0000000..2500833 --- /dev/null +++ b/src/main/java/practiceproblems/MaxPointsInLine.java @@ -0,0 +1,116 @@ +package practiceproblems; + +import javafx.util.Pair; + +import java.util.HashMap; +import java.util.Map; + +/** + * https://leetcode.com/problems/max-points-on-a-line + * + * + * input: [[2,1],[3,2],[4,3],[5,4]] + * slope: ^ 1/1 1/1 1/1 Slope is dy/dx, e.g. (5-2)/(4-1)=3/3=1/1 + * | o GCD is used to map equal slopes to identical. + * | o result: number of identical slopes + starting point = 3+1=4 + * | o + * | o + * +-------------------------- + * + * input: [[2,1],[3,2],[6,3],[5,4]] + * slope: ^ 1/1 2/1 1/1 We keep track of slopes related to the + * | o current point [2,1] in map. + * | o result: number of identical slopes + starting point = 2+1=3 + * | o + * | o + * +-------------------------- + * + * input: [[2,2],[3,2],[5,2],[6,2]] + * slope: ^ 1/0 1/0 1/0 GCD returns dx for pair [dx, 0]. + * | Then dx/dx / 0/dx = 1/0 + * | result: 3 + 1 = 4 + * | o o o o + * | + * +-------------------------- + * + * input: [[3,1],[3,2],[3,3],[3,4]] + * slope: ^ 0/1 0/1 0/1 GCD retuns dy for [o,dy]. + * | o Then 0/dy / dy/dy = 0/1 + * | o result: 3 + 1 = 4 + * | o + * | o + * +-------------------------- + * + * input: [[2,1],[3,2],[2,1],[4,1],[5,4],[2,1],[2,1]] + * slope: ^ 1/1 dup 1/0 1/1 dup dup + * | o Identical points have no slope. + * | We have 2 possible lines: 2 * 1/1 and 1 * 1/0. + * | o Keep track of duplicates and add them to max line. + * | 0 o result: 3 dups + max(2,1) + 1 = 6 + * +-------------------------- + * + * input: [[1,1],[5,1],[2,2],[3,3],[4,4],[6,2],[7,3]] + * slope: ^ 1/0 1/1 1/1 1/1 5/1 3/1 Slopes: max(1,3,1,1) = 3 + * slope: ^ -3/1 1/-1 1/-3 1/1 1/1 Slopes: max(1,1,1,2) = 2 + * | o The map tracks slopes for the current point only. + * | o o So parallel lines do not sum up points. + * | o o + * | o o result: 0 dups + max(3,2) + 1 = 4 + * +-------------------------- + * + * */ +public class MaxPointsInLine { + + public int maxPoints(int[][] points) { + if (points.length == 1) return 1; + int result = 2; + Map, Integer> cache = new HashMap<>(); + + for (int i = 0; i < points.length; i++) { + int duplicate = 0; + int count = 0; + cache.clear(); + for (int j = i + 1; j < points.length; j++) { + + int dx = points[j][0] - points[i][0]; + int dy = points[j][1] - points[i][1]; + + if (dx == 0 && dy == 0) { + duplicate++; + continue; + } + /** + * we need the slope: dx/dy. normally we can check dx/dy=1 + * but float rounds up the end and produces slightly different results, + * so instead we keep both dx and dy as the key. + * to make them identical for the identical slope, use GCD: greatest common divisor + */ + + int gcd = gcd(dx, dy); + if (gcd != 0) { + dx /= gcd; + dy /= gcd; + } + + // dx and dy define the slope. + // we keep the map for the current point i, so the full key is point[i]+slope excludes parallel lines. + // vertical line: dx==0, horizontal line: dy==0. + // GCD will set vertical: dx=0, dy=1, horizontal: dx=1, dy=0 + Pair line = new Pair<>(dx, dy); + + cache.put(line, cache.getOrDefault(line, 0) + 1); + count = Math.max(count, cache.get(line)); + } + + result = Math.max(result, count + duplicate + 1); + + } + + return result; + } + + public int gcd(int a, int b) { + if (b == 0) return a; + return gcd(b, a % b); + } +} diff --git a/src/main/java/practiceproblems/MaxSumTwoNonOverlappingSubArray.java b/src/main/java/practiceproblems/MaxSumTwoNonOverlappingSubArray.java new file mode 100644 index 0000000..9f28a42 --- /dev/null +++ b/src/main/java/practiceproblems/MaxSumTwoNonOverlappingSubArray.java @@ -0,0 +1,109 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/maximum-sum-of-two-non-overlapping-subarrays + *

+ * Basically it can be broken it into 2 cases: L is always before M vs M is always before L. + * + * + * Really tricky problem but not too hard once you see the method + * here is how I see it lets say you have the following array + * [2 , 1 , 5 , 6 , 0 , 9 , 5 , 0 , 3 , 8] with L = 3, M = 2 + * now lets look for our answer when M comes before L we will need to iterate the array like this + * [2 , 1 , 5 , 6 , 0 , 9 , 5 , 0 , 3 ] + * [ M ][ L ] + * [ M ][ L ] + * [ M ][ L ] + * [ M ][ L ] + * [ M ][ L ] + * + * where we keep track of the MMax and at every iteration we sum up the mMax and the current L and keep track of the maxValue + * the reasoning behind this is that since the arrays cant intercept mMax will keep track of greatest value of M before our current L + * + * once we do it one way we now run the algorithm with M and L reversed + * + * + * i-M-L i-M i + * 1, 2, 3, 4, 5, 6, 7 + * |- - L - - -|- M- - | + * To get the lengths: + * L= (i-M)-(i-M-L): M= i-(i-M) + * + * + * */ +public class MaxSumTwoNonOverlappingSubArray { + + public static int maxSumTwoNoOverlapConcise(int[] A, int L, int M) { + int[] prefixSum = new int[A.length + 1]; + for (int i = 0; i < A.length; ++i) { + prefixSum[i + 1] = prefixSum[i] + A[i]; + } + /* + maxSum(prefixSum, L, M) ==> find maximum sum for L length before index i and add it with every M length sum right to it + maxSum(prefixSum, M, L) ==> find maximum sum for M length before index i and add it with every L length sum right to it + */ + return Math.max(maxSum(prefixSum, L, M), maxSum(prefixSum, M, L)); + } + + private static int maxSum(int[] p, int L, int M) { + int ans = 0; + for (int i = L + M, maxL = 0; i < p.length; ++i) { + maxL = Math.max(maxL, p[i - M] - p[i - M - L]); // update max of L-length sub-array. + ans = Math.max(ans, maxL + p[i] - p[i - M]); // update max of the sum of L-length & M-length sub-arrays. + } + return ans; + } + + public static int maxSumTwoNoOverlap(int[] A, int L, int M) { + // L and M could be at left or right + // so we need to calculate the both to get the max non-overlapping sum of entire array + return Math.max(calculate(A, L, M), calculate(A, M, L)); + } + + private static int calculate(int[] A, int L, int M) { + int sum = 0; + int len = A.length; + + // calculate the prefix sum from A[0] to A[i] + int[] prefixSum = new int[len]; + prefixSum[0] = A[0]; + for(int i = 1; i < len; i++) { + prefixSum[i] = prefixSum[i-1] + A[i]; + } + + // calculate the maximum sum with length L with rightmost position at A[i], A[i] doesn't have to be included + int[] leftSum = new int[len]; + leftSum[L-1] = prefixSum[L-1]; + for(int i = L; i < len; i++) { + leftSum[i] = Math.max(leftSum[i-1], prefixSum[i] - prefixSum[i-L]); + } + + // calculate the suffix sum from A[i] to A[len-1] + int[] suffixSum = new int[len]; + suffixSum[len-1] = A[len-1]; + for(int i = len-2; i >= 0; i--) { + suffixSum[i] = suffixSum[i+1] + A[i]; + } + + // calculate the maximum sum with length M with leftmost position at A[i], A[i] doesn't have to be included + int[] rightSum = new int[len]; + rightSum[len-M] = suffixSum[len-M]; + for(int i = len-M-1; i >= 0; i--) { + rightSum[i] = Math.max(rightSum[i+1], suffixSum[i] - suffixSum[i+M]); + } + + // now we have all the data for max sum with length L from the left + // and max sum with length M from the right + // just iterate and add them up to find the max non-overlapping sum + // note the i+1 index is for non-overlapping + int res = Integer.MIN_VALUE; + for(int i = L-1; i <= len-M-1; i++) { + res = Math.max(leftSum[i] + rightSum[i+1], res); + } + + return res; + } + public static void main(String[] args) { + System.out.println(maxSumTwoNoOverlap(new int[]{0, 6, 5, 2, 2, 5, 1, 9, 4}, 1, 2)); + } +} diff --git a/src/practiceproblems/MaximumDifference.java b/src/main/java/practiceproblems/MaximumDifference.java similarity index 100% rename from src/practiceproblems/MaximumDifference.java rename to src/main/java/practiceproblems/MaximumDifference.java diff --git a/src/practiceproblems/MaximumGap.java b/src/main/java/practiceproblems/MaximumGap.java similarity index 81% rename from src/practiceproblems/MaximumGap.java rename to src/main/java/practiceproblems/MaximumGap.java index dd35b24..ef75081 100644 --- a/src/practiceproblems/MaximumGap.java +++ b/src/main/java/practiceproblems/MaximumGap.java @@ -1,15 +1,16 @@ package practiceproblems; /** + * TODO * Given an unsorted array, find the maximum difference between the successive elements in its sorted form. -Return 0 if the array contains less than 2 elements. -Input: [3,6,9,1] -Output: 3 -Explanation: The sorted form of the array is [1,3,6,9], either - (3,6) or (6,9) has the maximum difference 3. - - -trick is to do in O(N)= > Radix sort + * Return 0 if the array contains less than 2 elements. + * Input: [3,6,9,1] + * Output: 3 + * Explanation: The sorted form of the array is [1,3,6,9], either + * (3,6) or (6,9) has the maximum difference 3. + *

+ *

+ * trick is to do in O(N)= > Radix sort */ public class MaximumGap { // The first step is to find the maximum value in nums array, it will @@ -42,8 +43,8 @@ public int maximumGap(int[] nums) { while (m / exp > 0) { // Go through all digits from LSB to MSB int[] count = new int[R]; - for (int i = 0; i < nums.length; i++) { - count[(nums[i] / exp) % 10]++; + for (int num : nums) { + count[(num / exp) % 10]++; } for (int i = 1; i < count.length; i++) { @@ -54,9 +55,7 @@ public int maximumGap(int[] nums) { aux[--count[(nums[i] / exp) % 10]] = nums[i]; } - for (int i = 0; i < nums.length; i++) { - nums[i] = aux[i]; - } + System.arraycopy(aux, 0, nums, 0, nums.length); exp *= 10; } diff --git a/src/main/java/practiceproblems/MaximumProductSubarray.java b/src/main/java/practiceproblems/MaximumProductSubarray.java new file mode 100644 index 0000000..65c5a6e --- /dev/null +++ b/src/main/java/practiceproblems/MaximumProductSubarray.java @@ -0,0 +1,149 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/maximum-product-subarray/ + */ +public class MaximumProductSubarray { + + // 1, -2, -3, 0, 8, 7, -2 + public static int maxProductSubArray(int[] A) { + + if (A.length == 0) { + return 0; + } + + int maxHerePre = A[0]; + int minHerePre = A[0]; + int maxsofar = A[0]; + + for (int i = 1; i < A.length; i++) { + /** + * maxHere is updated by taking the maximum value among: + * + * Current number: + * This value will be picked if the accumulated product has been awful (even compared to the current number). + * This can happen when the current number has a preceding zero (e.g. [0,4]) or is preceded by a single negative number (e.g. [-3,5]). + * + * Product of last max_so_far and current number: + * This value will be picked if the accumulated product has been steadily increasing (all positive numbers). + * + * Product of last min_so_far and current number: + * This value will be picked if the current number is a negative number + * and the combo chain has been disrupted by a single negative number before + * (In a sense, this value is like an antidote to an already poisoned combo chain). + */ + int maxHere = Math.max(Math.max(maxHerePre * A[i], minHerePre * A[i]), A[i]); + int minHere = Math.min(Math.min(maxHerePre * A[i], minHerePre * A[i]), A[i]); + maxsofar = Math.max(maxHere, maxsofar); + maxHerePre = maxHere; + minHerePre = minHere; + } + return maxsofar; + } + + /** + * Simplest case. + * Consider this array [1,2,3,-4,5,6]. + * We can think of -4 as dividing the array into 2 halves, [1,2,3] and [5,6]. + * The forward traversal yields the max as 6, while the reverse traversal yields 30. + *

+ * Say the array has even number of negative numbers eg. [1,2,-3,-4,5,6]. + * Both forward and reverse traversals yield the same result, so it doesnt matter. + *

+ * Say the array has multiple odd number of negative integers. eg. [1,2,-3,-4,-5, 6]. + * We can think of the "last" negative number in each traversal breaks the array to 2 halves. + * In this case , the max array in forward traversal is the maximum of ([1,2,-3,-4] and [6]) which is 24. + * In the reverse, the split is delimited by -3. So the max subarrray is teh maximum of ([6,-5,-4] and [2]) + *

+ * Hence, in the end, its all about the presence of odd or even number of negative integers. + * In case of even, the product is always positive. In case of odd, the max product is limited by the last negative integer in each traversal. + * + * @param nums + * @return + */ + public int maxProduct(int[] nums) { + int max = Integer.MIN_VALUE, product = 1; + int len = nums.length; + + for (int num : nums) { + product *= num; + max = Math.max(product, max); + if (num == 0) product = 1; + } + + product = 1; + for (int i = len - 1; i >= 0; i--) { + product *= nums[i]; + max = Math.max(product, max); + if (nums[i] == 0) product = 1; + } + + return max; + + } + + + public static MaxSubarray getMaxSubarray(int[] inputArr){ + MaxSubarray result ; + int start=0; + int end=0; + int maxSum=Integer.MIN_VALUE; + int currSum=0; + int actualStart=0; + for(int i=0;imaxSum){ + maxSum =currSum; + actualStart = start; + end=i; + } + + if(currSum<0){ + currSum = 0; + start =i+1; + } + } + if(start>end) { + start=end; + } + + result = new MaxSubarray(maxSum, actualStart, end); + return result; + + } + + public static int maxSubArray(int[] nums) { + if (nums == null || nums.length == 0) return 0; + + int maxHere = 0; + int max = Integer.MIN_VALUE; + for (int i : nums) { + maxHere = Math.max(i, maxHere + i); + max = Math.max(maxHere, max); + } + + return max; + } + + public static void main(String[] args) { + int arr[] = {1, -2, -3, 0, 8, 7, -2}; + System.out.println("Maximum Sub array sum is " + maxSubArray(arr)); + System.out.println("Maximum Sub array product is " + maxProductSubArray(arr)); + } + + static class MaxSubarray { + int maxSum; + int startIndex; + int endIndex; + + public MaxSubarray(int maxSum,int startIndex,int endIndex){ + this.maxSum = maxSum; + this.startIndex= startIndex; + this.endIndex =endIndex; + } + } +} + + diff --git a/src/practiceproblems/MaximumSubstringWithKDistinctChar.java b/src/main/java/practiceproblems/MaximumSubstringWithKDistinctChar.java similarity index 100% rename from src/practiceproblems/MaximumSubstringWithKDistinctChar.java rename to src/main/java/practiceproblems/MaximumSubstringWithKDistinctChar.java diff --git a/src/practiceproblems/UnSortedSubArray.java b/src/main/java/practiceproblems/MaximumUnsortedSubarray.java similarity index 55% rename from src/practiceproblems/UnSortedSubArray.java rename to src/main/java/practiceproblems/MaximumUnsortedSubarray.java index 070927b..3767d0b 100644 --- a/src/practiceproblems/UnSortedSubArray.java +++ b/src/main/java/practiceproblems/MaximumUnsortedSubarray.java @@ -1,21 +1,21 @@ package practiceproblems; +//https://leetcode.com/problems/shortest-unsorted-continuous-subarray/ + /** - * 581. Shortest Unsorted Continuous Subarray - * Given an integer array nums, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order. - * - * Return the shortest such subarray and output its length. - * - * + * tricky array traversal * + * Given an integer array, you need to find one continuous subarray that if you only sort this subarray in ascending order, + * then the whole array will be sorted in ascending order, too. + *

+ * You need to find the shortest such subarray and output its length. + *

* Example 1: - * - * Input: nums = [2,6,4,8,10,9,15] + * Input: [2, 6, 4, 8, 10, 9, 15] * Output: 5 - * Explanation: You need to sort [6, 4, 8, 10, 9] in ascending - * order to make the whole array sorted in ascending order. + * Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order. */ -public class UnSortedSubArray { +public class MaximumUnsortedSubarray { public static int findUnsortedSubarray(int[] nums) { if (nums == null) { @@ -37,7 +37,7 @@ public static int findUnsortedSubarray(int[] nums) { begin = i; } } - + if (begin == -1) return 0; int max = Integer.MIN_VALUE; int end = -2; //iterate from beginning of array @@ -51,4 +51,13 @@ public static int findUnsortedSubarray(int[] nums) { } return end - begin + 1; } + + public static void main(final String[] args) { + //1, 1, 10, 10, 15, 10, 15, 10,10, 15, 10, 15 + //1, 3, 2, 4, 5 + //4, 15, 4, 4, 15, 18, 20 + //2, 6, 1, 8, 10, 9, 15 + findUnsortedSubarray(new int[]{4, 15, 4, 4, 15, 18, 20}); + + } } diff --git a/src/main/java/practiceproblems/MedianOfKWindow.java b/src/main/java/practiceproblems/MedianOfKWindow.java new file mode 100644 index 0000000..87c2023 --- /dev/null +++ b/src/main/java/practiceproblems/MedianOfKWindow.java @@ -0,0 +1,51 @@ +package practiceproblems; + +import java.util.Collections; +import java.util.PriorityQueue; + +public class MedianOfKWindow { + public double[] medianSlidingWindow(int[] nums, int k) { + MedianQueue medianHeap = new MedianQueue(); + + double[] result = new double[nums.length - k + 1]; + + int resultIndex = 0; + + for (int i = 0; i < nums.length; i++) { + medianHeap.offer(nums[i]); + if (medianHeap.size() == k) { + result[resultIndex++] = medianHeap.median(); + medianHeap.remove(nums[i + 1 - k]); + } + + } + + return result; + } + + static class MedianQueue { + PriorityQueue minQueue = new PriorityQueue<>(); + PriorityQueue maxQueue = new PriorityQueue<>(Collections.reverseOrder()); + + public void offer(int x) { + maxQueue.offer(x); + minQueue.offer(maxQueue.poll()); + if (maxQueue.size() < minQueue.size()) { + maxQueue.offer(minQueue.poll()); + } + + } + + public double median() { + return maxQueue.size() > minQueue.size() ? maxQueue.peek() : ((long) maxQueue.peek() + minQueue.peek()) * 0.5; + } + + public int size() { + return minQueue.size() + maxQueue.size(); + } + + public boolean remove(int x) { + return minQueue.remove(x) || maxQueue.remove(x); + } + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/MedianOfRunningIntegers.java b/src/main/java/practiceproblems/MedianOfRunningIntegers.java new file mode 100644 index 0000000..a1f8b06 --- /dev/null +++ b/src/main/java/practiceproblems/MedianOfRunningIntegers.java @@ -0,0 +1,60 @@ +package practiceproblems; + +import java.util.Collections; +import java.util.PriorityQueue; + +/** + * https://leetcode.com/problems/find-median-from-data-stream/ + */ +public class MedianOfRunningIntegers { + + PriorityQueue upperHalf = new PriorityQueue<>(); + PriorityQueue lowerHalf = new PriorityQueue<>(Collections.reverseOrder()); + + // 6,8,1,4,9,2,3,5 + // median is a middle element in sorted array + // in a sorted array if we choose a point the immediate left to that point is maxLeft (max of all left) + // the immediate right to that point is minRight (min of all right) + // to mimic that here the right(max) values are stored in min heap + // the left(min) values are stored in maxheap + // maxHeap.. i.. minHeap + // if odd return from maxHeap + public void addNum(int num) { + // Insert in lowerHalf if it's empty or + // if number being inserted is less than the peek of lowerHalf otherwise insert in upperHalf + if (lowerHalf.isEmpty() || num <= lowerHalf.peek()) { + lowerHalf.add(num); + } else { + upperHalf.add(num); + } + + // We also need to ensure that the halves are balanced i.e. + // there is no more than a difference of 1 in size of both halves + // Let lowerHalf be the one to hold one extra element if the size of total + // data stream is odd otherwise be equal to upperHalf + if (upperHalf.size() > lowerHalf.size()) { // If an element added above made upperHalf have one more element than lowerHalf then we poll it and put it into lowerHalf + lowerHalf.add(upperHalf.poll()); + } else if (lowerHalf.size() > upperHalf.size() + 1) { + // If an element added above, made lowerHalf have 2 more elements then upperHalf then we put one into upperHalf from lowerHalf + upperHalf.add(lowerHalf.poll()); + } + } + + public double findMedian() { + if (lowerHalf.size() == upperHalf.size()) { + return (lowerHalf.peek() + upperHalf.peek()) / 2.0; + } else { + return lowerHalf.peek(); + } + } + + public static void main(String[] args) { + MedianOfRunningIntegers median = new MedianOfRunningIntegers(); + int A[] = {5, 15, 1, 3, 2, 8, 7, 9, 10, 6, 11, 4}; + for (int num : A) { + median.addNum(num); + System.out.println(median.findMedian()); + } + } + +} diff --git a/src/practiceproblems/MedianOfTwoSortedArrays.java b/src/main/java/practiceproblems/MedianOfTwoSortedArrays.java similarity index 73% rename from src/practiceproblems/MedianOfTwoSortedArrays.java rename to src/main/java/practiceproblems/MedianOfTwoSortedArrays.java index 250bb64..4d1bf3f 100644 --- a/src/practiceproblems/MedianOfTwoSortedArrays.java +++ b/src/main/java/practiceproblems/MedianOfTwoSortedArrays.java @@ -1,7 +1,12 @@ package practiceproblems; +import java.util.Comparator; +import java.util.PriorityQueue; + /** * https://github.com/mission-peace/interview/blob/master/src/com/interview/binarysearch/MedianOfTwoSortedArrayOfDifferentLength.java + * TODO revise + * tricky binary search */ public class MedianOfTwoSortedArrays { @@ -13,7 +18,7 @@ public double findMedianSortedArrays(int[] input1, int[] input2) { int x = input1.length; int y = input2.length; - // the whole idea is to partition the 2 arrays so that the left side and right side has same number of elements + // the whole idea is to partition the 2 arrays so that the left side and right side have same number of elements // let's take example A= 1,3,7 and B= 2,6,8,9,10 // so if we assume both are combined the median would be at 6(6+7/2= 6.5 to be exact) @@ -65,15 +70,49 @@ public double findMedianSortedArrays(int[] input1, int[] input2) { } } - //Only we we can come here is if input arrays were not sorted. Throw in that scenario. + //Only we can come here is if input arrays were not sorted. Throw in that scenario. throw new IllegalArgumentException(); } + public double findMedianSortedArraysEff(int[] nums1, int[] nums2) { + + + PriorityQueue minHeap = new PriorityQueue<>(); + PriorityQueue maxHeap = new PriorityQueue<>(Comparator.reverseOrder()); + + + for (int value : nums1) { + maxHeap.add(value); + } + + for (int i : nums2) { + maxHeap.add(i); + } + + int val = 0; + + if ((nums1.length + nums2.length) % 2 == 0) { + val = (nums1.length + nums2.length) / 2; + } else { + val = (nums1.length + nums2.length) / 2 + 1; + } + + for (int k = 0; k < val; k++) { + minHeap.add(maxHeap.poll()); + } + + if (minHeap.size() == maxHeap.size()) { + return (double) (minHeap.peek() + maxHeap.peek()) / 2; + } else { + return minHeap.peek(); + } + } + public static void main(String[] args) { - int[] x = { 1, 3, 8, 9, 15, 17 }; - int[] y = { 7, 11, 18, 19, 21, 25 }; + int[] x = {1, 3, 8, 9, 15, 17, 30}; + int[] y = {7, 11, 18, 19, 21, 25}; // 1,3,7,8,9,11,15,18,19,21,25 MedianOfTwoSortedArrays mm = new MedianOfTwoSortedArrays(); - System.out.println(mm.findMedianSortedArrays(x, y)); + System.out.println(mm.findMedianSortedArraysEff(x, y) + " - " + mm.findMedianSortedArrays(x, y)); } } diff --git a/src/practiceproblems/MinAdjSwapsToMakePalindrome.java b/src/main/java/practiceproblems/MinAdjSwapsToMakePalindrome.java similarity index 62% rename from src/practiceproblems/MinAdjSwapsToMakePalindrome.java rename to src/main/java/practiceproblems/MinAdjSwapsToMakePalindrome.java index 67f0966..a85b195 100644 --- a/src/practiceproblems/MinAdjSwapsToMakePalindrome.java +++ b/src/main/java/practiceproblems/MinAdjSwapsToMakePalindrome.java @@ -3,6 +3,8 @@ /** * https://leetcode.com/discuss/interview-question/351783/ * https://www.youtube.com/watch?v=zXpYs8j5oI8&ab_channel=Insidecode + * + * TODO */ public class MinAdjSwapsToMakePalindrome { @@ -12,29 +14,29 @@ private int getNoOfSwaps(String s) { if (isShuffledPalindrome(s)) { char[] chars = s.toCharArray(); - int p1 = 0, p2 = chars.length - 1; + int left = 0, right = chars.length - 1; - while (p2 > p1) { - if (chars[p1] != chars[p2]) { - int k = p2; - while (k > p1 && chars[k] != chars[p1]) k--; + while (right > left) { + if (chars[left] != chars[right]) { + int searcher = right; + while (searcher > left && chars[searcher] != chars[left]) searcher--; - if (k == p1) { //When no matching character found - swap(chars, p1, p1 + 1); + if (searcher == left) { //When no matching character found + swap(chars, left, left + 1); totalSwaps++; } else { //When Matching character found swap until K reaches p2 position - while (k < p2) { - swap(chars, k, k + 1); + while (searcher < right) { + swap(chars, searcher, searcher + 1); totalSwaps++; - k++; + searcher++; } - p1++; - p2--; + left++; + right--; } } else { - p1++; - p2--; //When the characters are equal move on + left++; + right--; //When the characters are equal move on } } return totalSwaps; diff --git a/src/practiceproblems/MinCostRopeConnect.java b/src/main/java/practiceproblems/MinCostRopeConnect.java similarity index 95% rename from src/practiceproblems/MinCostRopeConnect.java rename to src/main/java/practiceproblems/MinCostRopeConnect.java index f23c350..77a63c5 100644 --- a/src/practiceproblems/MinCostRopeConnect.java +++ b/src/main/java/practiceproblems/MinCostRopeConnect.java @@ -12,7 +12,7 @@ public class MinCostRopeConnect { // 2+3 = 5 .. 5 + 4 = 9 .. 9 + 6 = 15 .. public static void main(String[] args) { - int arr[] = { 4, 3, 2, 6 }; + int arr[] = {4, 3, 2, 6}; MinCostRopeConnect rope = new MinCostRopeConnect(); rope.connectRopes(arr); diff --git a/src/main/java/practiceproblems/MinIncrementToMakeArrayUnique.java b/src/main/java/practiceproblems/MinIncrementToMakeArrayUnique.java new file mode 100644 index 0000000..97761d7 --- /dev/null +++ b/src/main/java/practiceproblems/MinIncrementToMakeArrayUnique.java @@ -0,0 +1,106 @@ +package practiceproblems; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class MinIncrementToMakeArrayUnique { + + /** + * O(N^2) + * + * @param A + * @return + */ + public int minIncrementForUniqueBruteForce(int[] A) { + if (A == null || A.length == 0) return 0; + Map map = new HashMap<>(); + for (int i : A) { + map.put(i, map.getOrDefault(i, 0) + 1); + } + int result = 0; + for (int i = 0; i < A.length; i++) { + if (map.get(A[i]) > 1) { + int temp = A[i]; + while (map.containsKey(temp)) { + temp++; + result++; + } + map.put(A[i], map.get(A[i]) - 1); + map.put(temp, map.getOrDefault(i, 0) + 1); + A[i] = temp; + } + } + //System.out.println(Arrays.toString(A)); + + return result; + } + + + /** + * tricky make array unique + * @param A + * @return + */ + public int minIncrementForUniqueSort(int[] A) { + Arrays.sort(A); + int count = 0; + /** + * in the case of [1,1,2,2,3,3]: + * A[1] is incremented to 2 (+1) + * [1,2,2,2,3,3] + * A[2] is incremented to 3 (+1) + * [1,2,3,2,3,3] + * A[3] is incremented to 4 (+2) + * [1,2,3,4,3,3] + * A[4] is incremented to 5, (+2) + * [1,2,3,4,5,3] + * A[5] is incremented to 6, (+3) + * [1,2,3,4,5,6] + */ + for (int i = 1; i < A.length; i++) { + //condition '<=' is because [1,2,2,2,3,7] when optimising this array + // when i=2 completes iteration the arr becomes [1,2,3,2,3,7] + // when i=3 we need to check if nums[i]<=nums[i-1] + if (A[i] <= A[i - 1]) { + int diff = A[i - 1] - A[i] + 1; + A[i] = A[i] + diff; + count += diff; + } + } + + return count; + } + + + /** + * tricky array processing + * O(N) + * + * @param arr + * @return + */ + public int minIncrementForUnique(int[] arr) { + if (arr == null || arr.length == 0) + return 0; + + int moves = 0; + int[] freq = new int[110000]; //given the max num = 40000 and array length = 39999, the worst case will fit in 80000 + for (int num : arr) + freq[num]++; + + for (int i = 0; i < freq.length - 1; i++) { + if (freq[i] <= 1) //no need to move anything! + continue; + //consider an example like where frequency of number 3 is 4 + //remaining that needs to be "reevaluated" is 3 (since one 3 is valid in this slot) + //if we were to add 1 to value 3, it is 4 + //since we have frequency of 3, its like now 4 has 3 frequency + //we repeat this process + int remain = freq[i] - 1; + moves += remain; + freq[i + 1] += remain; + } + return moves; + } +} diff --git a/src/main/java/practiceproblems/MinOperationToMakeArrayIncreasing.java b/src/main/java/practiceproblems/MinOperationToMakeArrayIncreasing.java new file mode 100644 index 0000000..ec8cb41 --- /dev/null +++ b/src/main/java/practiceproblems/MinOperationToMakeArrayIncreasing.java @@ -0,0 +1,26 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/minimum-operations-to-make-the-array-increasing/ + */ +public class MinOperationToMakeArrayIncreasing { + + public int minOperations(int[] nums) { + if (nums.length == 0 || nums.length == 1) return 0; + int total = 0; + + /** + If at any point, nums[i] <= nums[i - 1], + then we need to increment nums[i] to make the array strictly increasing. + The number of increments needed is given by - nums[i - 1] + nums[i] + 1. + Basically, it is the number of increments needed to take nums[i] to atleast nums[i - 1] + 1. + **/ + for (int i = 1; i < nums.length; i++) { + if (nums[i] > nums[i - 1]) continue; + total += Math.abs(nums[i] - nums[i - 1]) + 1; + nums[i] += Math.abs(nums[i] - nums[i - 1]) + 1; + } + + return total; + } +} diff --git a/src/main/java/practiceproblems/MinRefuelStops.java b/src/main/java/practiceproblems/MinRefuelStops.java new file mode 100644 index 0000000..2776be4 --- /dev/null +++ b/src/main/java/practiceproblems/MinRefuelStops.java @@ -0,0 +1,35 @@ +package practiceproblems; + +import java.util.PriorityQueue; + +/** + * tricky priority queue + * revise + */ +public class MinRefuelStops { + + public int minRefuelStops(int target, int startFuel, int[][] stations) { + if (startFuel >= target) return 0; + int curFarthest = startFuel, refuel = 0; + PriorityQueue pq = new PriorityQueue<>((a, b) -> b - a); + for (int[] station : stations) { + // check if we can reach next station + // if we cannot reach this station, refuel the gas from the previous station with most gas + // redo the operation until we get enough gas to reach this station + while (curFarthest < station[0]) { + if (pq.isEmpty()) + return -1; // if we refuel in each station but still cannot reach this station, return -1 + curFarthest += pq.poll(); + refuel++; + } + pq.offer(station[1]); + } + // now we have reached the last station, check if we can reach the target + while (curFarthest < target) { + if (pq.isEmpty()) return -1; + curFarthest += pq.poll(); + refuel++; + } + return refuel; + } +} diff --git a/src/practiceproblems/MinStepsToConvertXtoY.java b/src/main/java/practiceproblems/MinStepsToConvertXtoY.java similarity index 100% rename from src/practiceproblems/MinStepsToConvertXtoY.java rename to src/main/java/practiceproblems/MinStepsToConvertXtoY.java diff --git a/src/main/java/practiceproblems/MinTimeRotOranges.java b/src/main/java/practiceproblems/MinTimeRotOranges.java new file mode 100644 index 0000000..39e22ac --- /dev/null +++ b/src/main/java/practiceproblems/MinTimeRotOranges.java @@ -0,0 +1,61 @@ +package practiceproblems; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * https://github.com/bibhas-abhishek/projects/tree/master/MinTimeRotOranges + * https://www.geeksforgeeks.org/minimum-time-required-so-that-all-oranges-become-rotten/ + */ + +public class MinTimeRotOranges { + + public int orangesRotting(int[][] grid) { + if (grid == null || grid.length == 0) return 0; + int countFresh = 0; + int[][] dirs = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; + Deque queue = new ArrayDeque<>(); + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 2) { + queue.offer(new int[]{i, j}); + } else if (grid[i][j] == 1) { + countFresh++; + } + } + } + if (countFresh == 0) return 0; + int result = -1; + while (!queue.isEmpty()) { + int size = queue.size(); + + for (int i = 0; i < size; i++) { + int[] temp = queue.poll(); + + for (int[] dir : dirs) { + int newX = temp[0] + dir[0]; + int newY = temp[1] + dir[1]; + + if (newX < 0 || newX >= grid.length || newY < 0 || newY >= grid[0].length || grid[newX][newY] == 0 || grid[newX][newY] == 2) { + continue; + } + + queue.offer(new int[]{newX, newY}); + grid[newX][newY] = 2; + countFresh--; + } + } + + result++; + } + + + return countFresh != 0 ? -1 : result; + } + + public static void main(String[] args) { + int grid[][] = {{2, 1, 0, 1, 1}, {1, 0, 2, 1, 1}, {1, 1, 1, 1, 1}}; + System.out.println(new MinTimeRotOranges().orangesRotting(grid)); + } + +} \ No newline at end of file diff --git a/src/practiceproblems/MinimumBribes.java b/src/main/java/practiceproblems/MinimumBribes.java similarity index 70% rename from src/practiceproblems/MinimumBribes.java rename to src/main/java/practiceproblems/MinimumBribes.java index 2e1c427..647cbf8 100644 --- a/src/practiceproblems/MinimumBribes.java +++ b/src/main/java/practiceproblems/MinimumBribes.java @@ -1,5 +1,8 @@ package practiceproblems; + /** + * TODO + * * https://www.hackerrank.com/challenges/new-year-chaos/problem * https://www.youtube.com/watch?v=UpmVTEvaXPE * Any person in the queue can bribe the person directly in front of them to swap positions. @@ -7,34 +10,33 @@ * One person can bribe at most two other persons. * That is to say, if n = 8, and Person 5 bribes Person 4, the queue will look like this: 1,2,3,5,4,6,7,8. * Fascinated by this chaotic queue, you decide you must know the minimum number of bribes that took place to get the queue into its current state! - * * No person can bribe more than 2 persons if yes then print chaotic * Input: 2 1 5 3 4 * Output: 3 - * + *

* Input: 2 5 1 3 4 * Output: Too chaotic */ public class MinimumBribes { - // input is 2 1 5 3 4, + // input is 2 1 5 3 4, // when index is at 2(val=>5) we see how many elements lesser than 5 is there // if the value is greater that 2 we print too chaotic // else we add it to result void minimumBribes(int[] q) { - int bribes=0; - for(int i = q.length-1; i >= 0; i--) { - - if(i-1>=0 && q[i-1]==i+1){ - q[i-1]=q[i]; - q[i]=i+1; - bribes+=1; - } else if(i-2>=0 && q[i-2]==i+2){ + int bribes = 0; + for (int i = q.length - 1; i >= 0; i--) { + if (q[i] == i + 1) continue; + if (i - 1 >= 0 && q[i - 1] == i + 1) { + q[i - 1] = q[i]; + q[i] = i + 1; + bribes += 1; + } else if (i - 2 >= 0 && q[i - 2] == i + 2) { //2,1,5,3,4 we need to swap 2 elements to restore the array - q[i-2]=q[i-1]; - q[i-1]=q[i]; - q[i]=i+1; - bribes+=2; - }else{ + q[i - 2] = q[i - 1]; + q[i - 1] = q[i]; + q[i] = i + 1; + bribes += 2; + } else { System.out.println("Too Chaotic"); return; } @@ -45,6 +47,6 @@ void minimumBribes(int[] q) { public static void main(String[] args) { // inputs 5,1,2,3,7,8,6,4 => too chaotic // 1,2,5,3,7,8,6,4 => 7 - new MinimumBribes().minimumBribes(new int[]{2,1,5,3,4}); + new MinimumBribes().minimumBribes(new int[]{2, 1, 5, 3, 4}); } } \ No newline at end of file diff --git a/src/practiceproblems/MinimumDistanceBetweenTwoNumbers.java b/src/main/java/practiceproblems/MinimumDistanceBetweenTwoNumbers.java similarity index 95% rename from src/practiceproblems/MinimumDistanceBetweenTwoNumbers.java rename to src/main/java/practiceproblems/MinimumDistanceBetweenTwoNumbers.java index d99a887..d203eb0 100644 --- a/src/practiceproblems/MinimumDistanceBetweenTwoNumbers.java +++ b/src/main/java/practiceproblems/MinimumDistanceBetweenTwoNumbers.java @@ -42,7 +42,7 @@ int minDist(int arr[], int n, int x, int y) { public static void main(String[] args) { MinimumDistanceBetweenTwoNumbers min = new MinimumDistanceBetweenTwoNumbers(); int arr[] = {3, 5, 4, 2, 6, 5, 6, 6, 5, 4, 8, 3}; - int arr1[] = { 3, 5, 4, 3, 1, 2, 4, 6, 5, 6, 6, 5, 4, 8, 3 }; + int arr1[] = {3, 5, 4, 3, 1, 2, 4, 6, 5, 6, 6, 5, 4, 8, 3}; int n = arr.length; int x = 3; int y = 6; diff --git a/src/practiceproblems/MinimumIndexDistanceOfMaximumNumbers.java b/src/main/java/practiceproblems/MinimumIndexDistanceOfMaximumNumbers.java similarity index 100% rename from src/practiceproblems/MinimumIndexDistanceOfMaximumNumbers.java rename to src/main/java/practiceproblems/MinimumIndexDistanceOfMaximumNumbers.java diff --git a/src/practiceproblems/MinimumStepsKnight.java b/src/main/java/practiceproblems/MinimumStepsKnight.java similarity index 57% rename from src/practiceproblems/MinimumStepsKnight.java rename to src/main/java/practiceproblems/MinimumStepsKnight.java index 8c9219c..f2e1505 100644 --- a/src/practiceproblems/MinimumStepsKnight.java +++ b/src/main/java/practiceproblems/MinimumStepsKnight.java @@ -1,6 +1,11 @@ package practiceproblems; -import java.util.*; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Queue; +import java.util.Set; /** * https://www.geeksforgeeks.org/minimum-steps-reach-target-knight/ @@ -35,8 +40,8 @@ static boolean isInside(int x, int y, int N) { // to reach target position static int minStepToReachTarget(int knightPos[], int targetPos[], int N) { // x and y direction, where a knight can move - int dx[] = { -2, -1, 1, 2, -2, -1, 1, 2 }; - int dy[] = { -1, -2, -2, -1, 1, 2, 2, 1 }; + int dx[] = {-2, -1, 1, 2, -2, -1, 1, 2}; + int dy[] = {-1, -2, -2, -1, 1, 2, 2, 1}; // queue for storing states of knight in board Queue q = new LinkedList<>(); @@ -82,10 +87,40 @@ static int minStepToReachTarget(int knightPos[], int targetPos[], int N) { return Integer.MAX_VALUE; } + public int minKnightMoves(int x, int y) { + x = Math.abs(x); + y = Math.abs(y); // If we can reach x,y in one quadrant then we can do it for all others in the same number of moves too. + if (x == 1 && y == 1) + return 2; // Special case for 1,1 because there is a more efficient way to reach it if we allow negative positions + int[][] dirs = new int[][]{{-2, -1}, {-2, 1}, {-1, 2}, {1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}}; + Deque queue = new ArrayDeque<>(); + Set seen = new HashSet<>(); + queue.addLast(new int[]{0, 0}); + seen.add("0,0"); + int result = 0; + while (!queue.isEmpty()) { + int size = queue.size(); // Number of unique positions reachable with exactly result moves. + for (int i = 0; i < size; ++i) { + int[] currPos = queue.removeFirst(); + if (currPos[0] == x && currPos[1] == y) return result; + for (int[] currDir : dirs) { + int newX = currPos[0] + currDir[0]; + int newY = currPos[1] + currDir[1]; + if (newX >= 0 && newY >= 0 && !seen.contains(newX + "," + newY)) { + seen.add(newX + "," + newY); + queue.addLast(new int[]{newX, newY}); + } + } + } + result++; + } + return -1; // Can't be reached on an infinite chess board. + } + public static void main(String[] args) { int N = 30; - int[] knightPos = { 1, 1 }; - int[] targetPos = { 30, 30 }; + int[] knightPos = {1, 1}; + int[] targetPos = {30, 30}; System.out.println(minStepToReachTarget(knightPos, targetPos, N)); } } \ No newline at end of file diff --git a/src/main/java/practiceproblems/MinimumSubArrayLength.java b/src/main/java/practiceproblems/MinimumSubArrayLength.java new file mode 100644 index 0000000..dac78f2 --- /dev/null +++ b/src/main/java/practiceproblems/MinimumSubArrayLength.java @@ -0,0 +1,31 @@ +package practiceproblems; + +public class MinimumSubArrayLength { + + /** + * tricky int sliding window + */ + public static int minSubArrayLen(int target, int[] nums) { + + int left = 0; + int right = 0; + int sum = 0; + int result = Integer.MAX_VALUE; + while (left < nums.length) { + sum += nums[left]; + while (sum >= target) { + result = Math.min(result, left - right + 1); + sum -= nums[right]; + right++; + } + + left++; + } + + return result == Integer.MAX_VALUE ? 0 : result; + } + + public static void main(String[] args) { + minSubArrayLen(7, new int[]{2, 3, 1, 2, 4, 3}); + } +} diff --git a/src/main/java/practiceproblems/MinimumSwapSortArray.java b/src/main/java/practiceproblems/MinimumSwapSortArray.java new file mode 100644 index 0000000..4c7ee92 --- /dev/null +++ b/src/main/java/practiceproblems/MinimumSwapSortArray.java @@ -0,0 +1,110 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; + + +/** + * https://www.geeksforgeeks.org/minimum-number-swaps-required-sort-array/ + */ +public class MinimumSwapSortArray { + // Return the minimum number + // of swaps required to sort the array + public static int minSwaps(int[] nums) { + int len = nums.length; + HashMap map = new HashMap<>(); + for (int i = 0; i < len; i++) + map.put(nums[i], i); + + Arrays.sort(nums); + + // To keep track of visited elements. Initialize + // all elements as not visited or false. + boolean[] visited = new boolean[len]; + + // Initialize result + int ans = 0; + List> results = new ArrayList<>(); + for (int i = 0; i < len; i++) { + List temp = new ArrayList<>(); + // already swapped and corrected or + // already present at correct pos + if (visited[i] || map.get(nums[i]) == i) + continue; + + int j = i, cycle_size = 0; + while (!visited[j]) { + visited[j] = true; + + // move to next node + j = map.get(nums[j]); // nums is sorted now remember + cycle_size++; + temp.add(nums[j]); + } + + // Update answer by adding current cycle. + if (cycle_size > 0) { + ans += (cycle_size - 1); + if (cycle_size > 1) { + results.add(temp); + } + } + } + for (List t : results) { + System.out.println(Arrays.toString(t.toArray())); + } + return ans; + } + + public static void swap(int[] arr, int i, int j) { + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + + public static void swap(ArrayList list, int i, int j) { + Pair temp = list.get(i); + list.set(i, list.get(j)); + list.set(j, temp); + } + + /** + * tricky sort + */ + public static int minimumSwaps(int[] nums) { + + ArrayList pairs = new ArrayList<>(); + + for (int i = 0; i < nums.length; i++) { + pairs.add(new Pair(i, nums[i])); + } + + pairs.sort(Comparator.comparingInt(a -> a.val)); + int result = 0; + for (int i = 0; i < nums.length; i++) { + if (i == pairs.get(i).idx) continue; + + result++; + swap(pairs, pairs.get(i).idx, i); + i -= 1; + } + return result; + } + + public static void main(String[] args) { + System.out.println(minSwaps(new int[]{10, 19, 6, 3, 5}) + " - " + minimumSwaps(new int[]{10, 19, 6, 3, 5})); + } + + static class Pair { + int idx; + int val; + + public Pair(int idx, int val) { + this.idx = idx; + this.val = val; + } + } +} \ No newline at end of file diff --git a/src/practiceproblems/MinimumWindowSubsequence.java b/src/main/java/practiceproblems/MinimumWindowSubsequence.java similarity index 100% rename from src/practiceproblems/MinimumWindowSubsequence.java rename to src/main/java/practiceproblems/MinimumWindowSubsequence.java diff --git a/src/practiceproblems/MinimumWindowSubstring.java b/src/main/java/practiceproblems/MinimumWindowSubstring.java similarity index 100% rename from src/practiceproblems/MinimumWindowSubstring.java rename to src/main/java/practiceproblems/MinimumWindowSubstring.java diff --git a/src/practiceproblems/MirrorBinaryTree.java b/src/main/java/practiceproblems/MirrorBinaryTree.java similarity index 98% rename from src/practiceproblems/MirrorBinaryTree.java rename to src/main/java/practiceproblems/MirrorBinaryTree.java index b4c9e68..2c3c6ae 100644 --- a/src/practiceproblems/MirrorBinaryTree.java +++ b/src/main/java/practiceproblems/MirrorBinaryTree.java @@ -30,7 +30,7 @@ static void mirror(Node root) { Queue q = new LinkedList<>(); q.add(root); - while (q.size() > 0) { + while (!q.isEmpty()) { Node curr = q.poll(); Node temp = curr.left; curr.left = curr.right; diff --git a/src/practiceproblems/MobileKeyPadCombinations.java b/src/main/java/practiceproblems/MobileKeyPadCombinations.java similarity index 98% rename from src/practiceproblems/MobileKeyPadCombinations.java rename to src/main/java/practiceproblems/MobileKeyPadCombinations.java index 91d075b..12488af 100644 --- a/src/practiceproblems/MobileKeyPadCombinations.java +++ b/src/main/java/practiceproblems/MobileKeyPadCombinations.java @@ -36,7 +36,7 @@ public void generateCombinations(String digits, String[] keypad, int len, int st } public static void main(String[] args) { - new MobileKeyPadCombinations().letterCombinations("23").stream().forEach(System.out::println); + new MobileKeyPadCombinations().letterCombinations("23").forEach(System.out::println); } public List letterCombinationsIterative(String digits) { diff --git a/src/practiceproblems/MoveZeroes.java b/src/main/java/practiceproblems/MoveZeroes.java similarity index 100% rename from src/practiceproblems/MoveZeroes.java rename to src/main/java/practiceproblems/MoveZeroes.java diff --git a/src/main/java/practiceproblems/MultiplyTwoNumbers.java b/src/main/java/practiceproblems/MultiplyTwoNumbers.java new file mode 100644 index 0000000..0cd14fc --- /dev/null +++ b/src/main/java/practiceproblems/MultiplyTwoNumbers.java @@ -0,0 +1,59 @@ +package practiceproblems; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/multiply-strings/ + * + * `num1[i] * num2[j]` will be placed at indices `[i + j`, `i + j + 1]` + */ +public class MultiplyTwoNumbers { + + public static String multiply(String num1, String num2) { + int m = num1.length(), n = num2.length(); + int[] pos = new int[m + n]; + + /** + + 121 X + 23 + ------------ + 363 + 242 + ------ + + */ + for (int i = m - 1; i >= 0; i--) { + for (int j = n - 1; j >= 0; j--) { + int a = (num1.charAt(i) - '0'); + int b = (num2.charAt(j) - '0'); + int multipliedVal = a * b; + int valuePlace = i + j; + int carryOverPlace = i + j + 1; + + // add carryover to the multiplied value + int sum = multipliedVal + pos[carryOverPlace]; // pos[carryOverPlace] will act as reminder also + + pos[valuePlace] += sum / 10; + pos[carryOverPlace] = (sum) % 10; + System.out.println("a : " + a + " b: " + b + " valuePlace :" + valuePlace + " carryOverPlace " + carryOverPlace); + System.out.println("At end of j " + j + " arr vals are " + Arrays.toString(pos)); + System.out.println(); + } + System.out.println(); + System.out.println("At end of i " + i + " arr vals are " + Arrays.toString(pos)); + System.out.println(); + } + + StringBuilder sb = new StringBuilder(); + for (int p : pos) sb.append(p); + + while (sb.length() != 0 && sb.charAt(0) == '0') sb.deleteCharAt(0); + return sb.length() == 0 ? "0" : sb.toString(); + } + + public static void main(String[] args) { + System.out.println(multiply("123", "62")); + } + +} diff --git a/src/practiceproblems/NextGreaterNumber.java b/src/main/java/practiceproblems/NextGreaterNumber.java similarity index 64% rename from src/practiceproblems/NextGreaterNumber.java rename to src/main/java/practiceproblems/NextGreaterNumber.java index b3de1d8..ed052ab 100644 --- a/src/practiceproblems/NextGreaterNumber.java +++ b/src/main/java/practiceproblems/NextGreaterNumber.java @@ -1,12 +1,14 @@ package practiceproblems; /** + * tricky + * * https://www.geeksforgeeks.org/find-next-greater-number-set-digits/ *

* https://www.ideserve.co.in/learn/next-greater-number-using-same-digits */ public class NextGreaterNumber { - + // If all digits sorted in descending order, then output is always “Not Possible”. For example, 4321. // If all digits are sorted in ascending order, then we need to swap last two digits. For example, 1234. // For other cases, we need to process the number from rightmost side @@ -24,51 +26,52 @@ public class NextGreaterNumber { //For above example, we sort digits in bold 536974. We get “536479” which is the next greater number for input 534976. public int nextGreaterElement(int n) { - char[] arr = String.valueOf(n).toCharArray(); + char[] arr = String.valueOf(n).toCharArray(); - int i = arr.length - 2; + int i = arr.length - 2; // I) Start from the right most digit and // find the first digit that is // smaller than the digit next to it. - while (i >= 0 && arr[i] >= arr[i + 1]) - i--; + while (i >= 0 && arr[i] >= arr[i + 1]) + i--; // If no such digit is found, its the edge case 1. - if (i < 0) return -1; + if (i < 0) return -1; - // II) Find the smallest digit on right side of (i)'th - // digit that is greater than number[i] - int j = arr.length - 1; - while (arr[j] <= arr[i]) - j--; + // II) Find the smallest digit on right side of (i)'th + // digit that is greater than number[i] + int j = arr.length - 1; + while (arr[j] <= arr[i]) + j--; - swap(arr, i, j); - reverse(arr, i + 1, arr.length - 1); + swap(arr, i, j); + reverse(arr, i + 1, arr.length - 1); - try { - return Integer.valueOf(String.valueOf(arr)); - } catch (NumberFormatException e) { - return -1; + try { + return Integer.parseInt(String.valueOf(arr)); + } catch (NumberFormatException e) { + return -1; + } } -} -static void swap(char[] arr, int i, int j) { - arr[i] ^= arr[j]; - arr[j] ^= arr[i]; - arr[i] ^= arr[j]; -} + public void reverse(char[] element, int i, int j) { + while (i <= j) { + swap(element, i, j); + i++; + j--; + } + } -static void reverse(char[] arr, int i, int j) { - int l = i, h = j; - while (l < h) - swap(arr, l++, h--); -} - + public void swap(char[] element, int i, int j) { + char temp = element[i]; + element[i] = element[j]; + element[j] = temp; + } public static void main(String[] args) { NextGreaterNumber solution = new NextGreaterNumber(); - System.out.println("Next greater number is: "+solution.nextGreaterElement(6938652)); - + System.out.println("Next greater number is: " + solution.nextGreaterElement(6938652)); + } } diff --git a/src/main/java/practiceproblems/NextPermutation.java b/src/main/java/practiceproblems/NextPermutation.java new file mode 100644 index 0000000..91b0969 --- /dev/null +++ b/src/main/java/practiceproblems/NextPermutation.java @@ -0,0 +1,63 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/next-permutation + * https://www.youtube.com/watch?v=LuLCLgMElus + */ +public class NextPermutation { + + public void nextPermutation(int[] nums) { + // pivot is the element just before the non-increasing (weakly decreasing) suffix + /*2*/ + int pivot = indexOfLastPeak(nums) - 1; + // paritions nums into [prefix pivot suffix] + if (pivot != -1) { + int nextPrefix = lastIndexOfGreater(nums, nums[pivot]); // in the worst case it's suffix[0] + // next prefix must exist because pivot < suffix[0], otherwise pivot would be part of suffix + /*4*/ + swap(nums, pivot, nextPrefix); // this minimizes the change in prefix + } + /*5*/ + reverseSuffix(nums, pivot + 1); // reverses the whole list if there was no pivot + /*6*/ + } + + /** + * Find the last element which is a peak. + * In case there are multiple equal peaks, return the first of those. + * + * @return first index of last peak + */ + int indexOfLastPeak(int[] nums) { + for (int i = nums.length - 1; 0 < i; --i) { + if (nums[i - 1] < nums[i]) return i; + } + return 0; + } + + /** + * @return last index where the {@code num > threshold} or -1 if not found + */ + /*3*/ int lastIndexOfGreater(int[] nums, int threshold) { + for (int i = nums.length - 1; 0 <= i; --i) { + if (threshold < nums[i]) return i; + } + return -1; + } + + /** + * Reverse numbers starting from an index till the end. + */ + void reverseSuffix(int[] nums, int start) { + int end = nums.length - 1; + while (start < end) { + swap(nums, start++, end--); + } + } + + void swap(int[] nums, int i, int j) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } +} diff --git a/src/main/java/practiceproblems/NonDecreasingArray.java b/src/main/java/practiceproblems/NonDecreasingArray.java new file mode 100644 index 0000000..cbec61d --- /dev/null +++ b/src/main/java/practiceproblems/NonDecreasingArray.java @@ -0,0 +1,47 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/non-decreasing-array/description/ + * + * tricky + */ +class NonDecreasingArray { + /** + * Whenever we encounter a violation at a particular index i, we need to check what modification we can make to make the array sorted + * [3,4,5,3,6,8] + * In the example above, we consider the numbers 4, 5, 3 for deciding on how to fix the violation or. + * In this case, the correct modification is to change the number 3 to 5. + * If we change 5 to 3, then we won't be fixing the violation because the resulting array would be 3, 4, 3, 3, 6, 8. + * The basic decision-making process for fixing a violation is listed below. + * Without considering the number at the index i - 2, we won't be able to choose between updating nums[i] or nums[i - 1] + * + * in the example above nums[i-2] <= nums[i] so there's no point in changing nums[i-1] to nums[i] (i.e 5 to 3) + * so we change the nums[i] to nums[i-1] (i.e 3 to 5) + * + * @param nums + * @return + */ + public boolean checkPossibility(int[] nums) { + + int count = 0; + for (int i = 1; i < nums.length && count <= 1; i++) { + if (nums[i - 1] > nums[i]) { + count++; + if ((i - 2 < 0) || nums[i - 2] <= nums[i]) { + nums[i - 1] = nums[i]; + } else { + nums[i] = nums[i - 1]; + } + } + } + return count <= 1; + } + + public static void main(String[] args) { + // 1,4,2,3 + // //3,4,2,3 + int[] nums = {7, 8, 2, 3}; + NonDecreasingArray nda = new NonDecreasingArray(); + System.out.println(nda.checkPossibility(nums)); + } +} diff --git a/src/main/java/practiceproblems/NumberOfBallons.java b/src/main/java/practiceproblems/NumberOfBallons.java new file mode 100644 index 0000000..1546b82 --- /dev/null +++ b/src/main/java/practiceproblems/NumberOfBallons.java @@ -0,0 +1,56 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/maximum-number-of-balloons/discuss/382401/WithComments-StraightForward-Java-Simple-count-of-chars + */ +public class NumberOfBallons { + + public static int maxNumberOfBalloons(String text) { + int[] chars = new int[26]; //count all letters + for (char c : text.toCharArray()) { + chars[c - 'a']++; + } + int min = chars[1];//for b + min = Math.min(min, chars[0]);//for a + min = Math.min(min, chars[11] / 2);// for l /2 + min = Math.min(min, chars[14] / 2);//similarly for o/2 + min = Math.min(min, chars[13]);//for n + return min; + } + + private int findMaxNumberofPattern(String text, String pattern) { + int n = text.length(), m = pattern.length(), answer = Integer.MAX_VALUE; + int freqInText[] = new int[26]; + int freqInPattern[] = new int[26]; + + // Frequency of characters in text. + for (int i = 0; i < n; i++) { + freqInText[text.charAt(i) - 'a']++; + } + // Frequency of characters in pattern. + for (int i = 0; i < m; i++) { + freqInPattern[pattern.charAt(i) - 'a']++; + } + + // Compare the maximum string that can be produced + // considering one character at a time. + for (int i = 0; i < 26; i++) { + // Do not divide by zero. + if (freqInPattern[i] > 0) { + answer = Math.min(answer, freqInText[i] / freqInPattern[i]); + } + } + + return answer; + } + + public int maxNumberOfBalloonsAnother(String text) { + // Any string made up of lowercase English letters. + String pattern = "balloon"; + return findMaxNumberofPattern(text, pattern); + } + + public static void main(String[] args) { + maxNumberOfBalloons("llonbioan"); + } +} diff --git a/src/main/java/practiceproblems/NumberOfSubMatrices.java b/src/main/java/practiceproblems/NumberOfSubMatrices.java new file mode 100644 index 0000000..6cc1129 --- /dev/null +++ b/src/main/java/practiceproblems/NumberOfSubMatrices.java @@ -0,0 +1,53 @@ +package practiceproblems; + +import java.util.Arrays; + +/** + * TODO + * https://leetcode.com/problems/count-submatrices-with-all-ones/ + */ +public class NumberOfSubMatrices { + public static int numSubmat(int[][] arr) { + int n = arr.length; + int m = arr[0].length; + int brr[][] = new int[n][m]; + + // these are the loops for making a matrix brr[][] + // where index brr[i][j] will contain continuous number of 1 + //starting from index j to n-1 + for (int i = 0; i < n; ++i) { + brr[i][0] = arr[i][0]; + for (int j = 1; j < m; ++j) { + if (arr[i][j] == 1) { + brr[i][j] = 1 + brr[i][j - 1]; + } + } + } + // these are the loops for finding number of submatrices of all 1 + // starting from a particular fixed index (i,j) and adding it to answer + // we do this step for all i,j + + for (int i = 0; i < n; ++i) { + System.out.println(Arrays.toString(brr[i])); + } + int ans = 0; + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + ans += brr[i][j]; + int min = brr[i][j]; + for (int ii = i + 1; ii < n; ++ii) { + min = Math.min(min, brr[ii][j]); + ans += min; + } + } + } + return ans; + + } + + public static void main(String[] args) { + numSubmat(new int[][]{{1, 0, 1}, + {1, 1, 0}, + {1, 1, 0}}); + } +} diff --git a/src/main/java/practiceproblems/NutsAndBoltsMatch.java b/src/main/java/practiceproblems/NutsAndBoltsMatch.java new file mode 100644 index 0000000..fb7035c --- /dev/null +++ b/src/main/java/practiceproblems/NutsAndBoltsMatch.java @@ -0,0 +1,78 @@ +package practiceproblems; + +import java.util.Arrays; + +/** + * TODO + * http://www.lintcode.com/en/problem/nuts-bolts-problem/ + */ +public class NutsAndBoltsMatch { + /** + * @param nuts: an array of integers + * @param bolts: an array of integers + * @param compare: a instance of Comparator + */ + public void sortNutsAndBolts(String[] nuts, String[] bolts, NBComparator compare) { + if (nuts == null || bolts == null) return; + if (nuts.length != bolts.length) return; + + qsort(nuts, bolts, compare, 0, nuts.length - 1); + + System.out.println(Arrays.toString(nuts)); + System.out.println(Arrays.toString(bolts)); + } + + private void qsort(String[] nuts, String[] bolts, NBComparator compare, + int l, int u) { + if (l >= u) return; + // find the partition index for nuts with bolts[l] + int partitionIndex = partition(nuts, bolts[l], compare, l, u); + // partition bolts with nuts[part_inx] + partition(bolts, nuts[partitionIndex], compare, l, u); + // qsort recursively + qsort(nuts, bolts, compare, l, partitionIndex - 1); + qsort(nuts, bolts, compare, partitionIndex + 1, u); + } + + private int partition(String[] str, String pivot, NBComparator compare, + int lowerIndex, int upperIndex) { + // + int m = lowerIndex; + for (int i = lowerIndex + 1; i <= upperIndex; i++) { + if (compare.cmp(str[i], pivot) == -1 || + compare.cmp(pivot, str[i]) == 1) { + // + m++; + swap(str, i, m); + } else if (compare.cmp(str[i], pivot) == 0 || + compare.cmp(pivot, str[i]) == 0) { + // swap nuts[l]/bolts[l] with pivot + swap(str, i, lowerIndex); + i--; + } + } + // move pivot to proper index + swap(str, m, lowerIndex); + + return m; + } + + private void swap(String[] str, int l, int r) { + String temp = str[l]; + str[l] = str[r]; + str[r] = temp; + } + + public static void main(String[] args) { + new NutsAndBoltsMatch().sortNutsAndBolts(new String[]{"ab", "bc", "dd", "gg"}, new String[]{"AB", "GG", "DD", "BC"}, new NBComparator()); + } + + static class NBComparator { + public int cmp(String a, String b) { + return a.compareTo(b); + } + } +} + + + diff --git a/src/main/java/practiceproblems/PairDivisibleBy60.java b/src/main/java/practiceproblems/PairDivisibleBy60.java new file mode 100644 index 0000000..1b2c726 --- /dev/null +++ b/src/main/java/practiceproblems/PairDivisibleBy60.java @@ -0,0 +1,33 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/pairs-of-songs-with-total-durations-divisible-by-60 + */ +public class PairDivisibleBy60 { + public int numPairsDivisibleBy60(int[] time) { + //brute force - O(n ^ 2) time - TLE + // int n = time.length; + // int result = 0; + // for(int i = 0; i < n; i++){ + // for(int j = i + 1; j < n; j++){ + // if((time[i] + time[j]) % 60 == 0) + // result++; + // } + // } + // return result; + + //2 SUM PROBLEM WITH K = 60 + //O(n) time + int c[] = new int[60]; //because we know its going upto 0 to 59 + int result = 0; + for (int t : time) { + // System.out.println(t % 60) + if (t % 60 == 0) //completely divisible on its own + result += c[0]; + else + result += c[60 - t % 60]; //to keep it in range + c[t % 60] += 1; + } + return result; + } +} diff --git a/src/main/java/practiceproblems/PalindromePartition.java b/src/main/java/practiceproblems/PalindromePartition.java new file mode 100644 index 0000000..eebe0af --- /dev/null +++ b/src/main/java/practiceproblems/PalindromePartition.java @@ -0,0 +1,58 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.List; + + +/** + * tricky permutation + * + * https://leetcode.com/problems/palindrome-partitioning/ + * Given a string s, partition s such that every substring of the partition is a palindrome. + *

+ * Return all possible palindrome partitioning of s. + *

+ * Input: "aab" + * Output: + * [ + * ["aa","b"], + * ["a","a","b"] + * ] + */ +public class PalindromePartition { + public List> partition(String s) { + List> res = new ArrayList<>(); + List list = new ArrayList<>(); + dfs(s, 0, list, res); + return res; + } + + public void dfs(String s, int pos, List list, List> res) { + if (pos == s.length()) { + res.add(new ArrayList<>(list)); + return; + } + + for (int i = pos; i < s.length(); i++) { + if (isPal(s, pos, i)) { // what we are checking over here is, + // if we partition the string from index to i Example-(0, 0) is palindrome or not + + list.add(s.substring(pos, i + 1)); // take the substring and store it in our list & call the next substring from index + 1 + dfs(s, i + 1, list, res); + list.remove(list.size() - 1); + } + } + + } + + public boolean isPal(String s, int low, int high) { + while (low < high) if (s.charAt(low++) != s.charAt(high--)) return false; + return true; + } + + public static void main(String[] args) { + new PalindromePartition().partition("aab"); + } + + +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/PartitionArrayDisjoint.java b/src/main/java/practiceproblems/PartitionArrayDisjoint.java new file mode 100644 index 0000000..1ba1cec --- /dev/null +++ b/src/main/java/practiceproblems/PartitionArrayDisjoint.java @@ -0,0 +1,63 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/partition-array-into-disjoint-intervals + */ +public class PartitionArrayDisjoint { + + /** + * We need to divide the array into 2 parts such that max element on the left side is smaller or equal to every element on the right + * We can maintain a maxLeft to keep track of this. + * Now if we come across any number num[i] which is smaller than the maxLeft, this number cannot be part of the right side. + * Thus we need to update the maxLeft and the index of our partition p + * Regarding updating our index, its straight forward to update to i since the ith element has to be part of left side. + * Now what would be the updated maxLeft. + * This has to simply be the value of the maximum element encountered so far + * since this element was present before ith index so has to be the maxLeft now. + * Thus we will keep track of a max and update maxLeft to this value whenever we encounter a smaller number than maxLeft + * + * @param nums + * @return + */ + public int partitionDisjointEff(int[] nums) { + int maxLeft = nums[0]; + int max = nums[0]; + int p = 0; + for (int i = 1; i < nums.length; i++) { + if (nums[i] < maxLeft) { + maxLeft = max; + p = i; + } else if (max < nums[i]) { + max = nums[i]; + } + } + return p + 1; + } + + public int partitionDisjoint(int[] nums) { + int[] left = new int[nums.length]; + int[] right = new int[nums.length]; + left[0] = nums[0]; + + //If the maximum from left array is less than minimum from right array then we can make a split at that idx. + for (int i = 1; i < nums.length; i++) { + left[i] = Math.max(left[i - 1], nums[i]); + } + + right[nums.length - 1] = nums[nums.length - 1]; + + for (int i = nums.length - 2; i >= 0; i--) { + right[i] = Math.min(nums[i], right[i + 1]); + } + + for (int i = 0; i < nums.length - 1; i++) { + if (left[i] <= right[i + 1]) return i + 1; + } + + return -1; + } + + public static void main(String[] args) { + System.out.println(new PartitionArrayDisjoint().partitionDisjointEff(new int[]{5, 0, 3, 8, 6, 1,9})); + } +} diff --git a/src/practiceproblems/PartitionLabel.java b/src/main/java/practiceproblems/PartitionLabel.java similarity index 100% rename from src/practiceproblems/PartitionLabel.java rename to src/main/java/practiceproblems/PartitionLabel.java diff --git a/src/main/java/practiceproblems/PascalsTriangle.java b/src/main/java/practiceproblems/PascalsTriangle.java new file mode 100644 index 0000000..36b7ef1 --- /dev/null +++ b/src/main/java/practiceproblems/PascalsTriangle.java @@ -0,0 +1,67 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.List; + +/** + * https://leetcode.com/problems/pascals-triangle/ + *

+ * Input: 5 + * Output: + * [ + * [1], + * [1,1], + * [1,2,1], + * [1,3,3,1], + * [1,4,6,4,1] + * ] + */ +public class PascalsTriangle { + + public List> generate1(int numRows) { + List> allrows = new ArrayList<>(); + ArrayList row = new ArrayList<>(); + for (int i = 0; i < numRows; i++) { + // suppose if the row is [1,3,3,1] + // add 1 at start [1,1,3,3,1] + // then add together j and j+1 elements like below + // [1,4,3,3,1] => [1,4,6,3,1]=>[1,4,6,4,1] + row.add(0, 1); + for (int j = 1; j < row.size() - 1; j++) + row.set(j, row.get(j) + row.get(j + 1)); + allrows.add(new ArrayList<>(row));// every time the copy is only appended + } + return allrows; + + } + + public List> generate(int numRows) { + List> triangle = new ArrayList<>(); + + // Base case; first row is always [1]. + triangle.add(new ArrayList<>()); + triangle.get(0).add(1); + + for (int rowNum = 1; rowNum < numRows; rowNum++) { + List row = new ArrayList<>(); + List prevRow = triangle.get(rowNum - 1); + + // The first row element is always 1. + row.add(1); + + // Each triangle element (other than the first and last of each row) + // is equal to the sum of the elements above-and-to-the-left and + // above-and-to-the-right. + for (int j = 1; j < rowNum; j++) { + row.add(prevRow.get(j - 1) + prevRow.get(j)); + } + + // The last row element is always 1. + row.add(1); + + triangle.add(row); + } + + return triangle; + } +} \ No newline at end of file diff --git a/src/practiceproblems/PermutationInString.java b/src/main/java/practiceproblems/PermutationInString.java similarity index 89% rename from src/practiceproblems/PermutationInString.java rename to src/main/java/practiceproblems/PermutationInString.java index 0054d4a..27640cd 100644 --- a/src/practiceproblems/PermutationInString.java +++ b/src/main/java/practiceproblems/PermutationInString.java @@ -1,5 +1,7 @@ package practiceproblems; +import java.util.Arrays; + /** * Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. * In other words, one of the first string's permutations is the substring of the second string. @@ -39,7 +41,7 @@ public static boolean checkInclusion(String s1, String s2) { if (right >= s1.length()) { cache[s2.charAt(right - s1.length()) - 'a']++; // sliding the window } - if (allZero(cache)) { + if (Arrays.stream(cache).sum()==0) { return true; } right++; @@ -47,15 +49,6 @@ public static boolean checkInclusion(String s1, String s2) { return false; } - public static boolean allZero(int[] cache) { - for (int i = 0; i < 26; i++) { - if (cache[i] > 0) { - return false; - } - } - return true; - } - public static void main(String[] args) { System.out.println(checkInclusion("ab", "eidbaoo")); } diff --git a/src/practiceproblems/PetrolGasStation.java b/src/main/java/practiceproblems/PetrolGasStation.java similarity index 100% rename from src/practiceproblems/PetrolGasStation.java rename to src/main/java/practiceproblems/PetrolGasStation.java diff --git a/src/practiceproblems/PlusOne.java b/src/main/java/practiceproblems/PlusOne.java similarity index 100% rename from src/practiceproblems/PlusOne.java rename to src/main/java/practiceproblems/PlusOne.java diff --git a/src/practiceproblems/Pow.java b/src/main/java/practiceproblems/Pow.java similarity index 98% rename from src/practiceproblems/Pow.java rename to src/main/java/practiceproblems/Pow.java index b4be8fc..05c174a 100644 --- a/src/practiceproblems/Pow.java +++ b/src/main/java/practiceproblems/Pow.java @@ -1,6 +1,9 @@ package practiceproblems; /** + * + * tricky + * * Implement pow(x, n), which calculates x raised to the power n (i.e. xn). * * Example 1: diff --git a/src/practiceproblems/PrisonAfterNDays.java b/src/main/java/practiceproblems/PrisonAfterNDays.java similarity index 88% rename from src/practiceproblems/PrisonAfterNDays.java rename to src/main/java/practiceproblems/PrisonAfterNDays.java index dd7dd40..0528573 100644 --- a/src/practiceproblems/PrisonAfterNDays.java +++ b/src/main/java/practiceproblems/PrisonAfterNDays.java @@ -7,7 +7,6 @@ */ class PrisonAfterNDays { - public static int[] prisonAfterNDays(int[] cells, int N) { if (cells == null || cells.length == 0 || N <= 0) { return cells; @@ -29,8 +28,8 @@ public static int[] prisonAfterNDays(int[] cells, int N) { } if (hasCycle) { N %= cycle; // calculating the reminder day after excluding the cycle - // let's say N=10 and we hit cycle at 3, we need 10%3=1 remaining calculation - // to be done + // let's say N=10 and we hit cycle at 3, we need 10%3=1 remaining calculation + // to be done for (int i = 0; i < N; i++) { cells = nextDay(cells); } @@ -47,7 +46,7 @@ private static int[] nextDay(int[] cells) { } public static void main(String[] args) { - int[] cells = { 0, 1, 0, 1, 1, 0, 0, 1 }; + int[] cells = {0, 1, 0, 1, 1, 0, 0, 1}; int N = 7; System.out.println(Arrays.toString(prisonAfterNDays(cells, N))); } diff --git a/src/practiceproblems/ProductExceptSelf.java b/src/main/java/practiceproblems/ProductExceptSelf.java similarity index 98% rename from src/practiceproblems/ProductExceptSelf.java rename to src/main/java/practiceproblems/ProductExceptSelf.java index 842dd35..43b3fee 100644 --- a/src/practiceproblems/ProductExceptSelf.java +++ b/src/main/java/practiceproblems/ProductExceptSelf.java @@ -3,6 +3,9 @@ import java.util.Arrays; /** + * + * tricky array manipulation + * * https://leetcode.com/problems/product-of-array-except-self/ *

* Given numbers [2, 3, 4, 5], regarding the third number 4, diff --git a/src/main/java/practiceproblems/QueensAttackKing.java b/src/main/java/practiceproblems/QueensAttackKing.java new file mode 100644 index 0000000..27d0a7b --- /dev/null +++ b/src/main/java/practiceproblems/QueensAttackKing.java @@ -0,0 +1,56 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +//https://leetcode.com/problems/queens-that-can-attack-the-king/ + +/** + * On an 8x8 chessboard, there can be multiple Black Queens and one White King. + *

+ * Given an array of integer coordinates queens that represents the positions of the Black Queens, + * and a pair of coordinates king that represent the position of the White King, + * return the coordinates of all the queens (in any order) that can attack the King. + */ +class QueensAttackKing { + public List> queensAttacktheKing(int[][] queens, int[] king) { + List> result = new ArrayList<>(); + boolean[][] visited = new boolean[8][8]; + int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {-1, -1}, {1, 1}, {1, -1}, {-1, 1}}; + // first marking all queen positions + for (int[] qu : queens) { + visited[qu[0]][qu[1]] = true; + } + + for (int[] dir : dirs) { + List temp = findQueensPositions(king, dir[0], dir[1], visited); + if (temp != null) result.add(temp); + } + + return result; + + } + + public List findQueensPositions(int[] king, int xDir, int yDir, boolean[][] visited) { + int newX = xDir + king[0]; + int newY = yDir + king[1]; + // going to walk along x,y only not 8 directions at same time + while (newX < 8 && newY < 8 && newX >= 0 && newY >= 0) { + if (visited[newX][newY]) { + return Arrays.asList(newX, newY); // returns when first queen is met in row or column + } + + newX += xDir; + newY += yDir; + + } + + return null; + } + + public static void main(String[] args) { + int[][] queens = {{0, 1}, {1, 0}, {4, 0}, {0, 4}, {3, 3}, {2, 4}}; + int[] king = {0, 0}; + new QueensAttackKing().queensAttacktheKing(queens, king); + } +} \ No newline at end of file diff --git a/src/practiceproblems/RaceCarMinSteps.java b/src/main/java/practiceproblems/RaceCarMinSteps.java similarity index 88% rename from src/practiceproblems/RaceCarMinSteps.java rename to src/main/java/practiceproblems/RaceCarMinSteps.java index 6794359..0f9e769 100644 --- a/src/practiceproblems/RaceCarMinSteps.java +++ b/src/main/java/practiceproblems/RaceCarMinSteps.java @@ -1,9 +1,13 @@ package practiceproblems; -import java.util.*; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Queue; +import java.util.Set; + class RaceCarMinSteps { public int racecar(int target) { - Set visited = new HashSet<>(); + Set visited = new HashSet<>(); Queue queue = new LinkedList<>(); queue.add(new StateNode(1, 0)); int distance = 0; @@ -20,7 +24,7 @@ public int racecar(int target) { if (!visited.contains(nextSpeed + "," + nextPosition) && Math.abs(target - nextPosition) < target) { visited.add(nextSpeed + "," + nextPosition); queue.offer(new StateNode(nextSpeed, nextPosition)); - } + } // if R nextPosition = cur.position; nextSpeed = cur.speed > 0 ? -1 : 1; @@ -33,8 +37,8 @@ public int racecar(int target) { } return -1; } -} - class StateNode { + + static class StateNode { int speed; int position; @@ -42,4 +46,6 @@ public StateNode(int speed, int position) { this.speed = speed; this.position = position; } - } \ No newline at end of file + } +} + diff --git a/src/main/java/practiceproblems/RandomLinkedList.java b/src/main/java/practiceproblems/RandomLinkedList.java new file mode 100644 index 0000000..d73db67 --- /dev/null +++ b/src/main/java/practiceproblems/RandomLinkedList.java @@ -0,0 +1,61 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/copy-list-with-random-pointer/ + */ +class RandomLinkedList { + + public Node copyRandomList(Node head) { + if (head == null) { + return null; + } + Node dummy = new Node(-1); + dummy.next = head; + + while (head != null) { + Node newNode = new Node(head.val); + newNode.next = head.next; + head.next = newNode; + head = newNode.next; + } + + head = dummy.next; + + while (head != null && head.next != null) { + + head.next.random = head.random != null ? head.random.next : null; + head = head.next.next; + } + + Node oldHead = dummy.next; + Node newHead = dummy.next.next; + Node newTemp = newHead; + + while (oldHead != null) { + oldHead.next = oldHead.next.next; + newHead.next = newHead.next == null ? null : newHead.next.next; + + oldHead = oldHead.next; + newHead = newHead.next; + } + + return newTemp; + } + + static class Node { + public int val; + public Node next; + public Node random; + + public Node(int _val) { + val = _val; + next = null; + random = null; + } + + public String toString() { + return "" + this.val; + } + } +} + diff --git a/src/main/java/practiceproblems/RandomPickWithWeight.java b/src/main/java/practiceproblems/RandomPickWithWeight.java new file mode 100644 index 0000000..cf66710 --- /dev/null +++ b/src/main/java/practiceproblems/RandomPickWithWeight.java @@ -0,0 +1,90 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/random-pick-with-weight/ + * + * tricky + */ +class RandomPickWithWeight { + private int sum; + private int[] sumArr; + + public RandomPickWithWeight(int[] w) { + sum = 0; + sumArr = new int[w.length]; + for (int i = 0; i < w.length; ++i) { + sum += w[i]; + sumArr[i] = sum; + } + } + + /** + * Alternate example to understand the solution: + * + * So lets relate this problem with a problem of dividing a cake at a party + * such that the person with highest weight has better chance to pick a slice.(proportional to his weight) + * + * Suppose we have people with weight 1, 3, 5, 7, 9 pounds, and they went for a party to a bakery and purchased a cake. + * + * They decided that lets add our total weight and buy a cake proportional to it. So their totalWeight came as + * 1+3+5+7+9 = 25 + * They purchased a 25 pound cake :). + * They decided that lets cut cake in 1 pound slices(25 slices total) and whoever wants to eat can take a 1 pound slice at a time. + * The person who will pick a slice will be picked randomly. + * + * To find out how to pick randomly and to figure out who will pick first, they first did a cumulative sum of their weights + * + * 1->1 + * 3-> 1 + 3 = 4 + * 5-> 4 + 5 = 9 + * 7-> 7 + 9 = 16 + * 9-> 9 + 16 = 25 + * + * =1,4,9,16,25 + * + * And then asked the server to pick a random number out of 25 for them. The random number represents a slice. + * So it can be 17 out of 25 or 6 out of 25. + * + * So the slice 1 belongs to 1 pounds person. Which is only 1 slice. + * Slice between 2-4 belong to 3 pounds person. Which are 3 slices. + * . + * . + * Slice between 17- 25 belong to the 9 pounds person. Which are 9 slices. + * + * If we pick a random slice out of 25, + * there is a higher probability that it will belong to a person with 9 slices (the person with 9 pounds) , + * the person who own 7 slices has second highest probability. + * The person whose weight is 1 pound and has only 1 slice has least probability to pick a slice. + * + * And that's what we wanted. + * We want to let the person with highest weight get a greater chance to pick a slice every time even though they are picked at random. + * + * The question can also be asked in reverse + */ + public int pickIndex() { + int idx = (int) (Math.random() * sum); + return binarySearch(idx + 1); // +1 is because the rand will lie between 0-14 + } + + public int binarySearch(int idx) { + int left = 0; + int right = sumArr.length - 1; + + while (left < right) { + int mid = ((right - left) / 2) + left; + if (sumArr[mid] < idx) { + left = mid + 1; + } else { + right = mid; + } + } + return left; + } + + public static void main(String[] args) { + RandomPickWithWeight randomPickWithWeight = new RandomPickWithWeight(new int[]{1, 3, 5, 4, 2}); + randomPickWithWeight.pickIndex(); + + } + +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/RangeSum.java b/src/main/java/practiceproblems/RangeSum.java new file mode 100644 index 0000000..872f765 --- /dev/null +++ b/src/main/java/practiceproblems/RangeSum.java @@ -0,0 +1,37 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/range-sum-query-immutable/ + * + * First calculate prefix sums array for the given array nums. + * Now, your task is to find sum of elements from left to right. + * If left == 0, means we need to directly return sum at the index pref[right]. + * Otherwise, just return the difference of sums at pref[right] - pref[left - 1]. + * + * Example: + * ar = [-2, 0, 3, -5, 2, -1] + * range = [0, 2], [2, 5] + * + * Prefix Sums Array = [-2,-2,1,-4,-2,-3] + * + * Output: + * For query 1, left == 0, return prefix sum at index right. Print pref[2] = 1 + * For query 2, left != 0, return pref[right] - pref[left - 1]. Print pref[5] - pref[1] = -1 + */ +public class RangeSum { + int[] dp; + + public void NumArray(int[] nums) { + if (nums.length == 0) return; + dp = new int[nums.length]; + dp[0] = nums[0]; + for (int i = 1; i < nums.length; i++) { + dp[i] = dp[i - 1] + nums[i]; + } + } + + public int sumRange(int i, int j) { + if (i == 0) return dp[j]; + return dp[j] - dp[i - 1]; + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/RangeSum2D.java b/src/main/java/practiceproblems/RangeSum2D.java new file mode 100644 index 0000000..8be7967 --- /dev/null +++ b/src/main/java/practiceproblems/RangeSum2D.java @@ -0,0 +1,90 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/range-sum-query-2d-immutable/ + * https://www.youtube.com/watch?v=PwDqpOMwg6U&ab_channel=TusharRoy-CodingMadeSimple + * +---------------+ +---------+----+ +---+-----------+ +---------+----+ +---+----------+ + * | | | | | | | | | | | | | | + * | (r1,c1) | | | | | | | | | | | | | + * | +------+ | | | | | | | +---------+ | +---+ | + * | | | | = | | | - | | | - | (r1-1,c2) | + | (r1-1,c1-1) | + * | | | | | | | | | | | | | | + * | +------+ | +---------+ | +---+ | | | | | + * | (r2,c2)| | (r2,c2)| | (r2,c1-1) | | | | | + * +---------------+ +--------------+ +---------------+ +--------------+ +--------------+ + */ +public class RangeSum2D { + int[][] dp; + + public RangeSum2D(int[][] matrix) { + int m = matrix.length; + int n = matrix[0].length; + dp = new int[m + 1][n + 1]; + + /** + * +-----+-+-------+ +--------+-----+ +-----+---------+ +-----+--------+ + * | | | | | | | | | | | | | + * | | | | | | | | | | | | | + * +-----+-+ | +--------+ | | | | +-----+ | + * | | | | = | | + | | | - | | + * +-----+-+ | | | +-----+ | | | + * | | | | | | | | + * | | | | | | | | + * +---------------+ +--------------+ +---------------+ +--------------+ + * + * sums[i][j] = sums[i-1][j] + sums[i][j-1] - sums[i-1][j-1] + + * + * matrix[i-1][j-1] + */ + for (int i = 1; i <= m; i++) { + for (int j = 1; j <= n; j++) { + dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + matrix[i - 1][j - 1]; + } + } + } + + public int sumRegion(int row1, int col1, int row2, int col2) { + // converting to m+1,n+1 dp[][] index + row1 += 1; + row2 += 1; + col1 += 1; + col2 += 1; + + return dp[row2][col2] - dp[row2][col1 - 1] - dp[row1 - 1][col2] + dp[row1 - 1][col1 - 1]; + } + + /** + * https://leetcode.com/problems/matrix-block-sum + * + * Given a m x n matrix mat and an integer k, return a matrix answer where each answer[i][j] is the sum of all elements mat[r][c] for: + * + * i - k <= r <= i + k, + * j - k <= c <= j + k, and + * (r, c) is a valid position in the matrix. + */ + public int[][] matrixBlockSum(int[][] mat, int K) { + int m = mat.length, n = mat[0].length; + int[][] sum = new int[m + 1][n + 1]; // sum[i][j] is sum of all elements from rectangle (0,0,i,j) as left, top, right, bottom corresponding + for (int r = 1; r <= m; r++) { + for (int c = 1; c <= n; c++) { + sum[r][c] = sum[r - 1][c] + sum[r][c - 1] - sum[r - 1][c - 1] + mat[r - 1][c - 1]; + } + } + int[][] ans = new int[m][n]; + for (int r = 0; r < m; r++) { + for (int c = 0; c < n; c++) { + int r1 = Math.max(0, r - K); + int c1 = Math.max(0, c - K); + int r2 = Math.min(m - 1, r + K); + int c2 = Math.min(n - 1, c + K); + r1++; + c1++; + r2++; + c2++; // Since `sum` start with 1 so we need to increase r1, c1, r2, c2 by 1 + ans[r][c] = sum[r2][c2] - sum[r2][c1 - 1] - sum[r1 - 1][c2] + sum[r1 - 1][c1 - 1]; + } + } + return ans; + } +} + diff --git a/src/main/java/practiceproblems/ReArrangeStringKDistanceApart.java b/src/main/java/practiceproblems/ReArrangeStringKDistanceApart.java new file mode 100644 index 0000000..3f3981f --- /dev/null +++ b/src/main/java/practiceproblems/ReArrangeStringKDistanceApart.java @@ -0,0 +1,47 @@ +package practiceproblems; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.PriorityQueue; + +/** + * https://leetcode.com/problems/rearrange-string-k-distance-apart/ + */ +public class ReArrangeStringKDistanceApart { + + /** + * The greedy algorithm is that in each step, select the char with highest remaining count if possible (if it is not in the waiting queue). + * PQ is used to achieve the greedy. A regular queue waitQueue is used to "freeze" previous appeared char in the period of k. + * + * In each iteration, we need to add current char to the waitQueue and also release the char at front of the queue, put back to maxHeap. + * The "impossible" case happens when the maxHeap is empty but there is still some char in the waitQueue. + * + * The idea of using two Queue is brilliant! By polling entries from the PriorityQueue which are used to construct our result, + * and offering to queue which served as ensuring the distance larger than K, + * we can keep recording all the entries and these entries are "transferred" between two queues. The idea is fantastic. + */ + public String rearrangeString(String s, int k) { + if (k == 0) return s; + int[] freq = new int[26]; + StringBuilder ans = new StringBuilder(); + for (char c : s.toCharArray()) freq[c - 'a']++; + PriorityQueue pq = new PriorityQueue<>((a, b) -> b[1] - a[1]); + for (int i = 0; i < 26; i++) { + if (freq[i] > 0) { + pq.add(new int[]{i, freq[i]}); + } + } + Deque q = new ArrayDeque<>(); + while (!pq.isEmpty()) { + int[] current = pq.poll(); + ans.append((char) (current[0] + 'a')); + current[1]--; + q.offer(current); + if (q.size() == k) { + int[] front = q.poll(); + if (front[1] > 0) pq.offer(front); + } + } + return ans.length() == s.length() ? ans.toString() : ""; + } +} diff --git a/src/practiceproblems/RemoveAdjacentDuplicates.java b/src/main/java/practiceproblems/RemoveAdjacentDuplicates.java similarity index 100% rename from src/practiceproblems/RemoveAdjacentDuplicates.java rename to src/main/java/practiceproblems/RemoveAdjacentDuplicates.java diff --git a/src/practiceproblems/Node.java b/src/main/java/practiceproblems/RemoveBSTGivenOutsideRange.java similarity index 86% rename from src/practiceproblems/Node.java rename to src/main/java/practiceproblems/RemoveBSTGivenOutsideRange.java index c79b622..b213c83 100644 --- a/src/practiceproblems/Node.java +++ b/src/main/java/practiceproblems/RemoveBSTGivenOutsideRange.java @@ -3,7 +3,7 @@ /** * https://www.geeksforgeeks.org/remove-bst-keys-outside-the-given-range/ */ -class RemoveBSTGivenOutsideRange { +public class RemoveBSTGivenOutsideRange { private static BSTNode removeOutsideRange(BSTNode root, int min, int max) { if (root == null) { @@ -14,15 +14,11 @@ private static BSTNode removeOutsideRange(BSTNode root, int min, int max) { root.right = removeOutsideRange(root.right, min, max); if (root.data < min) { - BSTNode rchild = root.right; - root = null; - return rchild; + return root.right; } if (root.data > max) { - BSTNode lchild = root.left; - root = null; - return lchild; + return root.left; } return root; } @@ -73,10 +69,12 @@ public static void main(String[] args) { System.out.print("\nInorder traversal of " + "the modified tree: "); inorderTraversal(root); } -} -class BSTNode { - int data; - BSTNode left; - BSTNode right; + private static class BSTNode { + int data; + BSTNode left; + BSTNode right; + } } + + diff --git a/src/practiceproblems/RemoveDuplicates.java b/src/main/java/practiceproblems/RemoveDuplicates.java similarity index 95% rename from src/practiceproblems/RemoveDuplicates.java rename to src/main/java/practiceproblems/RemoveDuplicates.java index 6292653..55bf9f5 100644 --- a/src/practiceproblems/RemoveDuplicates.java +++ b/src/main/java/practiceproblems/RemoveDuplicates.java @@ -21,7 +21,7 @@ public int removeDuplicates(int[] nums) { public static void main(String[] args) { RemoveDuplicates removeDuplicates = new RemoveDuplicates(); - int[] nums = { 1, 1, 2 }; + int[] nums = {1, 1, 2}; removeDuplicates.removeDuplicates(nums); } } \ No newline at end of file diff --git a/src/practiceproblems/ReorderLogs.java b/src/main/java/practiceproblems/ReorderLogs.java similarity index 97% rename from src/practiceproblems/ReorderLogs.java rename to src/main/java/practiceproblems/ReorderLogs.java index 9cfc64b..1772adc 100644 --- a/src/practiceproblems/ReorderLogs.java +++ b/src/main/java/practiceproblems/ReorderLogs.java @@ -35,12 +35,12 @@ public static String[] reorderLogFiles(String[] logs) { int comp = split1[1].compareTo(split2[1]); if (comp == 0) return split1[0].compareTo(split2[0]); - else + return comp; } else if (isDigit1 && isDigit2) { // both digit-logs. So keep them in original order return 0; - } else if (isDigit1 && !isDigit2) { + } else if (isDigit1) { // first is digit, second is letter. bring letter to forward. return 1; } else { diff --git a/src/practiceproblems/ReorganiseString.java b/src/main/java/practiceproblems/ReorganiseString.java similarity index 100% rename from src/practiceproblems/ReorganiseString.java rename to src/main/java/practiceproblems/ReorganiseString.java diff --git a/src/practiceproblems/RestoreIpAddresses.java b/src/main/java/practiceproblems/RestoreIpAddresses.java similarity index 66% rename from src/practiceproblems/RestoreIpAddresses.java rename to src/main/java/practiceproblems/RestoreIpAddresses.java index db628f7..bfdeb98 100644 --- a/src/practiceproblems/RestoreIpAddresses.java +++ b/src/main/java/practiceproblems/RestoreIpAddresses.java @@ -1,12 +1,16 @@ package practiceproblems; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; /** - *Given a string s containing only digits, + * tricky substring + * + * Given a string s containing only digits, * return all possible valid IP addresses that can be obtained from s. * You can return them in any order. - * + *

* A valid IP address consists of exactly four integers, * each integer is between 0 and 255, separated by single dots and cannot have leading zeros. * For example, "0.1.2.201" and "192.168.1.1" are valid IP addresses and "0.011.255.245", @@ -50,4 +54,26 @@ public boolean isValid(String part) { return address >= 0 && address <= 255; } + + public List restoreIpAddressesRecur(String s) { + List ans = new ArrayList<>(); + if (s.length() < 4 || s.length() > 12) return ans; + restore(s, ans, "", 0); + return ans; + } + + private void restore(String s, List ans, String restored, int count) { + if (count == 4) { + if (s.isEmpty()) ans.add(restored); + return; + } + + for (int i = 1; i <= Math.min(3, s.length()); i++) { + String sec = s.substring(0, i); + if ((sec.length() > 1 && sec.charAt(0) == '0') || (sec.length() == 3 && Integer.parseInt(sec) > 255)) + continue; + restore(s.substring(i), ans, restored + sec + (count < 3 ? "." : ""), count + 1); + } + + } } \ No newline at end of file diff --git a/src/main/java/practiceproblems/ReverseString.java b/src/main/java/practiceproblems/ReverseString.java new file mode 100644 index 0000000..ae1f537 --- /dev/null +++ b/src/main/java/practiceproblems/ReverseString.java @@ -0,0 +1,67 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/reverse-words-in-a-string/ + * tricky + */ +public class ReverseString { + public StringBuilder trimSpaces(String s) { + int left = 0, right = s.length() - 1; + // remove leading spaces + while (left <= right && s.charAt(left) == ' ') ++left; + + // remove trailing spaces + while (left <= right && s.charAt(right) == ' ') --right; + + // reduce multiple spaces to single one + StringBuilder sb = new StringBuilder(); + while (left <= right) { + char c = s.charAt(left); + + if (c != ' ') + sb.append(c); + else if (sb.charAt(sb.length() - 1) != ' ') + sb.append(c); + + ++left; + } + return sb; + } + + public void reverse(StringBuilder sb, int left, int right) { + while (left < right) { + char tmp = sb.charAt(left); + sb.setCharAt(left++, sb.charAt(right)); + sb.setCharAt(right--, tmp); + } + } + + public void reverseEachWord(StringBuilder sb) { + int n = sb.length(); + int start = 0, end = 0; + + while (start < n) { + // go to the end of the word + while (end < n && sb.charAt(end) != ' ') ++end; + // reverse the word + reverse(sb, start, end - 1); + // move to the next word + start = end + 1; + ++end; + } + } + + public String reverseWords(String s) { + // converst string to string builder + // and trim spaces at the same time + StringBuilder sb = trimSpaces(s); + + // reverse the whole string + reverse(sb, 0, sb.length() - 1); + + // reverse each word + reverseEachWord(sb); + + return sb.toString(); + } +} diff --git a/src/main/java/practiceproblems/RollingHashRabinKarp.java b/src/main/java/practiceproblems/RollingHashRabinKarp.java new file mode 100644 index 0000000..db20c8d --- /dev/null +++ b/src/main/java/practiceproblems/RollingHashRabinKarp.java @@ -0,0 +1,113 @@ +package practiceproblems; + +/** + * revise + */ +public class RollingHashRabinKarp{ + /** + * the normal way to calculate an hash from a string would be through the following method + * for String S="abcdef" we chose a prime number which is greater that the no.of chars(26) + * we choose P=31 + * + * total hash(abcdef)= (a*P^0+ b*P^1 + c*P^2 + d*P^3 + e*P^4 + f*P^5) % M; + * %(mod) is taken to avoid overflow of values + * hash at each point is [h0, h1, h2, h3, h4, h5] + * + * this is analogous to prefix sum, the hash at each index i is hash calculated from 0 to 'i' + * + * for h2 is hash from (a-c), in order to calculate prefix sum from index 2-4 + * + * sum(2-4)= sum(4)-sum(2) [sum 0-4 - sum 0-2], likewise we can calculate rolling hash + * + * in order to find contains subString for String size M and N, the time complexity would be O(MN) + * + * if we find the hash of String M and N separately and somehow find if substring of size N in String M + * hashes to hash(N) we will have our result in O(M) + * + * M= SDESKILLS + * N= SKILLS + * Note: p0 or p1= P^number + * + * hash of M= [(S*p0)+(D*p1)+(E*p2)+(S*p4)+(K*p5)+(I*p6)+(L*p7)+(L*p8)+(S*p9)] % M + * + * in hashing no matter how many times/ at what position a string comes, it has to hash to same value + * + * if we have a hash(abcdef)= a*p0+ b*p1+ c*p2+ d*p3+ e*p4+ f*p5 + * and we need hash(cde) we need to do prefix-sum analogy + * hash(cde)= hash(R)-hash(L-1) R= Right, L=Left + * but the above equation comes down to [c*p2 + d*p3+ e*p4] this is not going to yield correct + * result for cde every time if 'cde' occurs at different index then the eq would be [c*p8+d*p9+e*p10] + * + * so what we need is to add one more part to the eq ([c*p2 + d*p3+ e*p4]/ p2) => [c*p0 + d*p1+ e*p2] + * hash(cde)= hash(R)-hash(L-1)/P^L R= Right, L=Left + * + * Hash[3,6]= (Hash(6)- Hash(2)/ p^3)%M + * + * hash([L...R]) =(hash[R] - hash[L - 1]/PL)% M + hash(s[L...R]) =(hash[R] - hash[L - 1]) * P^-L % M + + hash(s[L...R]) =(hash[R] - hash[L - 1])*(P^-1)L % M + hash(s[L...R]) =(hash[R] - hash[L - 1])%M * (P-1)L%M + + (A * B) % M =( (A % M) * (B % M)) % M + X = P^-1= P^M-2% M + hash(s[L...R]) =(((hash[R] - hash[L - 1])% M *X^L )% M) + */ + + + private int prime = 101; + + public int patternSearch(char[] text, char[] pattern) { + int m = pattern.length; + int n = text.length; + long patternHash = createHash(pattern, m - 1); + long textHash = createHash(text, m - 1); + for (int i = 1; i <= n - m + 1; i++) { + if (patternHash == textHash && checkEqual(text, i - 1, i + m - 2, pattern, 0, m - 1)) { + return i - 1; + } + if (i < n - m + 1) { + textHash = recalculateHash(text, i - 1, i + m - 1, textHash, m); + } + } + return -1; + } + + private long recalculateHash(char[] str, int oldIndex, int newIndex, long oldHash, int patternLen) { + long newHash = oldHash - str[oldIndex]; + newHash = newHash / prime; + newHash += str[newIndex] * Math.pow(prime, patternLen - 1); + return newHash; + } + + private long createHash(char[] str, int end) { + long hash = 0; + for (int i = 0; i <= end; i++) { + hash += str[i] * Math.pow(prime, i); + } + return hash; + } + + private boolean checkEqual(char str1[], int start1, int end1, char str2[], int start2, int end2) { + if (end1 - start1 != end2 - start2) { + return false; + } + while (start1 <= end1 && start2 <= end2) { + if (str1[start1] != str2[start2]) { + return false; + } + start1++; + start2++; + } + return true; + } + + public static void main(String args[]) { + RollingHashRabinKarp rks = new RollingHashRabinKarp(); + System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "sharRoy".toCharArray())); + System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "Roy".toCharArray())); + System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "shas".toCharArray())); + System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "usha".toCharArray())); + System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "Tus".toCharArray())); + } +} \ No newline at end of file diff --git a/src/practiceproblems/RomanToInteger.java b/src/main/java/practiceproblems/RomanToInteger.java similarity index 51% rename from src/practiceproblems/RomanToInteger.java rename to src/main/java/practiceproblems/RomanToInteger.java index 8abd50c..2ae1528 100644 --- a/src/practiceproblems/RomanToInteger.java +++ b/src/main/java/practiceproblems/RomanToInteger.java @@ -1,11 +1,12 @@ package practiceproblems; -import java.util.*; +import java.util.HashMap; +import java.util.Map; public class RomanToInteger { public int romanToInteger(String s) { - Map map = new HashMap(); + Map map = new HashMap<>(); map.put('I', 1); map.put('V', 5); @@ -27,6 +28,24 @@ public int romanToInteger(String s) { } + public String intToRoman(int num) { + + String[] keys = new String[]{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}; + int[] values = new int[]{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < keys.length; i++) { + + if (num - values[i] >= 0) { + while (num - values[i] >= 0) { + sb.append(keys[i]); + num -= values[i]; + } + } + } + + return sb.toString(); + } + public static void main(String[] args) { new RomanToInteger().romanToInteger("LIX"); } diff --git a/src/practiceproblems/RotateArray.java b/src/main/java/practiceproblems/RotateArray.java similarity index 57% rename from src/practiceproblems/RotateArray.java rename to src/main/java/practiceproblems/RotateArray.java index 7eb85af..d196ac0 100644 --- a/src/practiceproblems/RotateArray.java +++ b/src/main/java/practiceproblems/RotateArray.java @@ -1,14 +1,7 @@ package practiceproblems; + /** - * Given an array, rotate the array to the right by k steps, where k is - * non-negative Could you do it in-place with O(1) extra space? - * - * - * Example 1: - * - * Input: nums = [1,2,3,4,5,6,7], k = 3 Output: [5,6,7,1,2,3,4] Explanation: - * rotate 1 steps to the right: [7,1,2,3,4,5,6] rotate 2 steps to the right: - * [6,7,1,2,3,4,5] rotate 3 steps to the right: [5,6,7,1,2,3,4] + * https://leetcode.com/problems/rotate-array/ */ public class RotateArray { public void rotate(int[] nums, int k) { diff --git a/src/main/java/practiceproblems/RotateMatrixInPlace.java b/src/main/java/practiceproblems/RotateMatrixInPlace.java new file mode 100644 index 0000000..2e1195a --- /dev/null +++ b/src/main/java/practiceproblems/RotateMatrixInPlace.java @@ -0,0 +1,91 @@ +package practiceproblems; + +/** + * https://www.geeksforgeeks.org/inplace-rotate-square-matrix-by-90-degrees/ + */ +class RotateMatrixInPlace { + + /** + * N/2 for time complexity o(n) + * get all the corners first and swap ( rotate 90 degree) + */ + + public static void rotate(int[][] matrix) { + if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return; + int n = matrix.length - 1; + + for (int i = 0; i < matrix.length / 2; i++) { + // to check number of cycles + for (int j = i; j < n - i; j++) { + // loop to find number of elements + + //x1,y1= x2,y2 + //x1=y2 + + int temp = matrix[i][j]; + + //0,0= 3,0 + matrix[i][j] = matrix[n - j][i]; + + // 3,0=3,3 + matrix[n - j][i] = matrix[n - i][n - j]; + + //3,3=0,3 + matrix[n - i][n - j] = matrix[j][n - i]; + + matrix[j][n - i] = temp; + } + } + + + } + + static void displayMatrix(int N, int mat[][]) { + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) + System.out.print(" " + mat[i][j]); + + System.out.print("\n"); + } + System.out.print("\n"); + } + + /** + * For Swapping 90 -> transpose matrix (rows to col, col to rows) -> swap cols using 2 pointers + * For Swapping 180 -> swap columns using 2 pointer -> swap rows using 2 pointers + * For Swapping 270 -> transpose matrix (rows to col, col to rows) -> swap rows using 2 pointers + */ + public static void rotateAlter(int[][] matrix) { + + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < i; j++) { + int temp = matrix[i][j]; + matrix[i][j] = matrix[j][i]; + matrix[j][i] = temp; + } + } + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix.length / 2; j++) { + int temp = 0; + temp = matrix[i][j]; + matrix[i][j] = matrix[i][matrix.length - 1 - j]; + matrix[i][matrix.length - 1 - j] = temp; + } + } + } + + + public static void main(String[] args) { + int N = 4; + + // Test Case 1 + int[][] mat = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}; + + displayMatrix(N, mat); + + rotateAlter(mat); + + // Print rotated matrix + displayMatrix(N, mat); + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/SearchAMaze.java b/src/main/java/practiceproblems/SearchAMaze.java new file mode 100644 index 0000000..3b7f806 --- /dev/null +++ b/src/main/java/practiceproblems/SearchAMaze.java @@ -0,0 +1,86 @@ +package practiceproblems; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * https://www.techiedelight.com/lee-algorithm-shortest-path-in-a-maze/ + */ +public class SearchAMaze { + + private static final int M = 10; + private static final int N = 10; + + private static final int row[] = {-1, 0, 0, 1}; + private static final int col[] = {0, -1, 1, 0}; + + private static boolean isValid(int mat[][], int row, int col) { + return (row >= 0) && (row < M) && (col >= 0) && (col < N) && mat[row][col] == 1; + } + + private static void BFS(int mat[][], int srcX, int srcY, int destX, int destY) { + + Queue q = new LinkedList<>(); + + q.add(new MazeNode(srcX, srcY, 0)); + + int result = 0; + while (!q.isEmpty()) { + + int size = q.size(); + for (int i = 0; i < size; i++) { + + MazeNode node = q.poll(); + + srcX = node.x; + srcY = node.y; + int dist = node.dist; + + if (srcX == destX && srcY == destY) { + System.out.print("The shortest path from source to destination " + "has length " + result); + return; + } + + for (int k = 0; k < 4; k++) { + if (isValid(mat, srcX + row[k], srcY + col[k])) { + mat[srcX][srcY] = 0; + MazeNode e = new MazeNode(srcX + row[k], srcY + col[k], dist + 1); + q.add(e); + System.out.println("Adding to the queue :" + e); + } + } + } + result++; + } + + if (result != Integer.MAX_VALUE) { + System.out.print("The shortest path from source to destination " + "has length " + result); + } else { + System.out.print("Destination can't be reached from source"); + } + } + + public static void main(String[] args) { + int[][] mat = {{1, 1, 1, 1, 1, 0, 0, 1, 1, 1}, {0, 1, 1, 1, 1, 1, 0, 1, 0, 1}, + {0, 0, 1, 0, 1, 1, 1, 0, 0, 1}, {1, 0, 1, 1, 1, 0, 1, 1, 0, 1}, {0, 0, 0, 1, 0, 0, 0, 1, 0, 1}, + {1, 0, 1, 1, 1, 0, 0, 1, 1, 1}, {0, 0, 0, 0, 1, 0, 0, 1, 0, 1}, {0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {1, 1, 1, 1, 1, 0, 0, 1, 1, 1}, {0, 0, 1, 0, 0, 1, 1, 0, 0, 1}}; + + BFS(mat, 8, 0, 0, 9); + } + + static class MazeNode { + int x, y, dist; + + MazeNode(int x, int y, int dist) { + this.x = x; + this.y = y; + this.dist = dist; + } + + public String toString() { + return "(" + x + "," + y + ") -> " + dist; + } + } +} + diff --git a/src/practiceproblems/SearchAnElementInMatrix.java b/src/main/java/practiceproblems/SearchAnElementInMatrix.java similarity index 100% rename from src/practiceproblems/SearchAnElementInMatrix.java rename to src/main/java/practiceproblems/SearchAnElementInMatrix.java diff --git a/src/practiceproblems/SerializeAndDeserialize.java b/src/main/java/practiceproblems/SerializeAndDeserialize.java similarity index 66% rename from src/practiceproblems/SerializeAndDeserialize.java rename to src/main/java/practiceproblems/SerializeAndDeserialize.java index 607ba6b..be89f7d 100644 --- a/src/practiceproblems/SerializeAndDeserialize.java +++ b/src/main/java/practiceproblems/SerializeAndDeserialize.java @@ -1,19 +1,16 @@ package practiceproblems; +import trees.TreeNode; + import java.util.Arrays; import java.util.LinkedList; import java.util.Queue; -/* - Serialize and Deserialize Binary Tree - LeetCode: - https://leetcode.com/problems/serialize-and-deserialize-binary-tree/ - - This code passes all Leetcode test cases as of April 26 2019 - Runtime: 12 ms, faster than 62.25% of Java online submissions for Serialize and Deserialize Binary Tree. - Memory Usage: 39.4 MB, less than 71.37% of Java online submissions for Serialize and Deserialize Binary Tree. - - The video to explain this code is here: https://www.youtube.com/watch?v=suj1ro8TIVY -*/ +/** + * Serialize and Deserialize Binary Tree - LeetCode: + * https://leetcode.com/problems/serialize-and-deserialize-binary-tree/ + * The video to explain this code is here: https://www.youtube.com/watch?v=suj1ro8TIVY + */ public class SerializeAndDeserialize { @@ -23,18 +20,17 @@ public class SerializeAndDeserialize { public String serialize(TreeNode root) { if (root == null) { - return NULL_SYMBOL + DELIMITER; + return NULL_SYMBOL; } - String leftSerialized = serialize(root.left); - String rightSerialized = serialize(root.right); + String left = serialize(root.left) + DELIMITER; + String right = serialize(root.right); - return root.val + DELIMITER + leftSerialized + rightSerialized; + return root.val + DELIMITER + left + right; } public TreeNode deserialize(String data) { - Queue nodesLeftToMaterialize = new LinkedList<>(); - nodesLeftToMaterialize.addAll(Arrays.asList(data.split(DELIMITER))); + Queue nodesLeftToMaterialize = new LinkedList<>(Arrays.asList(data.split(DELIMITER))); return deserializeHelper(nodesLeftToMaterialize); } @@ -42,7 +38,7 @@ public TreeNode deserializeHelper(Queue nodesLeftToMaterialize) { String valueForNode = nodesLeftToMaterialize.poll(); - if (valueForNode.equals(NULL_SYMBOL)) { + if (valueForNode == null || valueForNode.equals(NULL_SYMBOL) || valueForNode.trim().length() == 0) { return null; } diff --git a/src/main/java/practiceproblems/SerializeDeserializeBST.java b/src/main/java/practiceproblems/SerializeDeserializeBST.java new file mode 100644 index 0000000..b6dd21a --- /dev/null +++ b/src/main/java/practiceproblems/SerializeDeserializeBST.java @@ -0,0 +1,60 @@ +package practiceproblems; + + +import trees.TreeNode; + +import java.util.LinkedList; +import java.util.Queue; + +class SerializeDeserializeBST { + // Encodes a tree to a single string. + public String serialize(TreeNode root) { + StringBuilder sb = new StringBuilder(); + helperFn(root, sb); + return sb.toString(); + } + + public void helperFn(TreeNode root, StringBuilder sb) { + if (root == null) return; + sb.append(root.val + ","); + helperFn(root.left, sb); + helperFn(root.right, sb); + } + + // Decodes your encoded data to tree. + public TreeNode deserialize(String data) { + if (data == null || data.isEmpty()) return null; + Queue treeVal = buildIntArr(data); + + return bulidTreeFromArray(treeVal); + } + + public Queue buildIntArr(String data) { + + String[] arr = data.split(","); + Queue queue = new LinkedList<>(); + for (String se : arr) { + queue.offer(Integer.parseInt(se)); + } + return queue; + } + + public TreeNode bulidTreeFromArray(Queue treeVals) { + if (treeVals.isEmpty()) return null; + + Integer rootVal = treeVals.poll(); + TreeNode root = new TreeNode(rootVal); + + Queue smallerVals = new LinkedList<>(); + + while (!treeVals.isEmpty() && treeVals.peek() < rootVal) { + smallerVals.offer(treeVals.poll()); + } + root.left = bulidTreeFromArray(smallerVals); + root.right = bulidTreeFromArray(treeVals); + return root; + + + } + +} \ No newline at end of file diff --git a/src/practiceproblems/SetBitCount.java b/src/main/java/practiceproblems/SetBitCount.java similarity index 100% rename from src/practiceproblems/SetBitCount.java rename to src/main/java/practiceproblems/SetBitCount.java diff --git a/src/main/java/practiceproblems/SetZeroesMatrix.java b/src/main/java/practiceproblems/SetZeroesMatrix.java new file mode 100644 index 0000000..104635c --- /dev/null +++ b/src/main/java/practiceproblems/SetZeroesMatrix.java @@ -0,0 +1,52 @@ +package practiceproblems; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/set-matrix-zeroes + */ +public class SetZeroesMatrix { + + public void setZeroes(int[][] matrix) { + boolean firstRow = false; + boolean firstCol = false; + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix[0].length; j++) { + if (matrix[i][j] == 0) { + /** + * + // Use first row and first column as markers. + // if matrix[i][j] = 0, mark respected row and col marker = 0; indicating + that later this respective row and col must be marked 0; + // And because you are altering first row and collumn, + you need to have two variables to track their own status. + // So, for ex, if any one of the first row is 0, fr = 0, + and at the end set all first row to 0; + + */ + if (i == 0) firstCol = true; + if (j == 0) firstRow = true; + matrix[0][j] = 0; + matrix[i][0] = 0; + } + } + } + for (int i = 1; i < matrix.length; i++) { + for (int j = 1; j < matrix[0].length; j++) { + if (matrix[0][j] == 0 || matrix[i][0] == 0) { + matrix[i][j] = 0; + } + } + } + + if (firstRow) { + for (int i = 0; i < matrix.length; i++) { + matrix[i][0] = 0; + } + } + if (firstCol) { + Arrays.fill(matrix[0], 0); + } + } + +} diff --git a/src/main/java/practiceproblems/ShortestPathBinaryMatrix.java b/src/main/java/practiceproblems/ShortestPathBinaryMatrix.java new file mode 100644 index 0000000..3458297 --- /dev/null +++ b/src/main/java/practiceproblems/ShortestPathBinaryMatrix.java @@ -0,0 +1,51 @@ +package practiceproblems; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * https://leetcode.com/problems/shortest-path-in-binary-matrix/ + */ +public class ShortestPathBinaryMatrix { + public int shortestPathBinaryMatrix(int[][] grid) { + + int m = grid.length; + int n = grid[0].length; + + if (grid[0][0] == 1 || grid[m - 1][n - 1] == 1) { + return -1; + } + int[][] dirs = new int[][]{{0, 1}, {1, 0}, {0, -1}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}}; + Deque queue = new ArrayDeque<>(); + queue.offer(new int[]{0, 0}); + boolean[][] visited = new boolean[grid.length][grid[0].length]; + visited[0][0] = true; + int steps = 0; + while (!queue.isEmpty()) { + int size = queue.size(); + + for (int i = 0; i < size; i++) { + + int[] temp = queue.poll(); + if (temp[0] == grid.length - 1 && temp[1] == grid[0].length - 1) return steps + 1; + for (int[] dir : dirs) { + + int newX = temp[0] + dir[0]; + int newY = temp[1] + dir[1]; + + if (newX < 0 || newY < 0 || newX >= grid.length || newY >= grid[0].length || visited[newX][newY] || grid[newX][newY] == 1) { + continue; + } + + visited[newX][newY] = true; + + queue.offer(new int[]{newX, newY}); + } + } + + steps++; + } + + return -1; + } +} diff --git a/src/practiceproblems/ShuffleArray.java b/src/main/java/practiceproblems/ShuffleArray.java similarity index 92% rename from src/practiceproblems/ShuffleArray.java rename to src/main/java/practiceproblems/ShuffleArray.java index ddf9ee0..9552360 100644 --- a/src/practiceproblems/ShuffleArray.java +++ b/src/main/java/practiceproblems/ShuffleArray.java @@ -27,10 +27,8 @@ public int[] reset() { * Returns a random shuffling of the array. */ public int[] shuffle() { - if (nums == null) { - return null; - } - int[] a = nums.clone(); + + int[] a = Arrays.copyOfRange(nums, 0, nums.length); for (int j = 1; j < a.length; j++) { int i = random.nextInt(j + 1); swap(a, i, j); diff --git a/src/practiceproblems/SimilarExpressions.java b/src/main/java/practiceproblems/SimilarExpressions.java similarity index 100% rename from src/practiceproblems/SimilarExpressions.java rename to src/main/java/practiceproblems/SimilarExpressions.java diff --git a/src/main/java/practiceproblems/SlidingWindow.java b/src/main/java/practiceproblems/SlidingWindow.java new file mode 100644 index 0000000..7995bc5 --- /dev/null +++ b/src/main/java/practiceproblems/SlidingWindow.java @@ -0,0 +1,46 @@ +package practiceproblems; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.List; + +/** + * https://leetcode.com/problems/sliding-window-maximum/ + */ +public class SlidingWindow { + + public static void main(String[] args) { + int arr[] = {8, 5, 10, 7, 9, 4, 15, 12, 90, 13}; + int k = 3; + maxSlidingWindow(arr, k); + } + + public static int[] maxSlidingWindow(int[] nums, int k) { + + List result = new ArrayList<>(); + + Deque queue = new ArrayDeque<>(); + + for (int i = 0; i < nums.length; i++) { + while (!queue.isEmpty() && queue.peek() < i - k + 1) { + queue.removeFirst(); + } + while (!queue.isEmpty() && nums[queue.peekLast()] < nums[i]) { + queue.pollLast(); + } + + queue.addLast(i); + + if (i >= k - 1) { + result.add(nums[queue.peekFirst()]); + } + } + int[] res = new int[nums.length - k + 1]; + + for (int j = 0; j < result.size(); j++) { + res[j] = result.get(j); + } + return res; + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/SnakeAndLadder.java b/src/main/java/practiceproblems/SnakeAndLadder.java new file mode 100644 index 0000000..eea9c28 --- /dev/null +++ b/src/main/java/practiceproblems/SnakeAndLadder.java @@ -0,0 +1,70 @@ +package practiceproblems; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * tricky bfs, consider as 1-D plane + * https://leetcode.com/problems/snakes-and-ladders/ + */ +public class SnakeAndLadder { + + public int snakesAndLadders(int[][] board) { + int n = board.length; + Queue queue = new LinkedList<>(); + queue.offer(1); + boolean[] visited = new boolean[n * n + 1]; + for (int move = 0; !queue.isEmpty(); move++) { + + for (int size = queue.size(); size > 0; size--) { + int currPos = queue.poll(); + if (visited[currPos]) continue; + visited[currPos] = true; + if (currPos == n * n) return move; + for (int i = 1; i <= 6 && currPos + i <= n * n; i++) { + int next = currPos + i; + int value = getBoardValue(board, next); + if (value > 0) next = value; + if (!visited[next]) queue.offer(next); + } + } + } + return -1; + } + + /** + * Let nextPos=1 + * 1/6=0 + * 6-0-1=5 <-- this is the row we are at + * This will work for 1,2,3,4,5 but not for 6 + * 6/6=1 + * 6-1-1=4, but we are still at row 5 + * So the way to tackle this is by using this: + * int oldRow=(next_step-1)/n; + * row=n-1-oldRow; + * This will make 1,2,3,4,5,6 all in the same row. + * column is easy all u have to do is int oldCol=(next_step-1)%n; + * 2. For flipping direction (i.e snake goes upward in zig-zag fashion )all we are going to dow is we have found oldRow in the previous step. + * so for every odd oldRow we flip the direction and for every even oldRow we maintain our normal direction. + *

+ * if(x%2==1) col =n-1-oldCol; + */ + private int getBoardValue(int[][] board, int nextPos) { + int n = board.length; + int oldRow = (nextPos - 1) / n; + int row = n - 1 - oldRow; + int oldCol = (nextPos - 1) % n; + int col = oldRow % 2 == 0 ? oldCol : n - 1 - oldCol; + + return board[row][col]; + } + + public static void main(String[] args) { + + int[][] board = {{-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1}, + {-1, 35, -1, -1, 13, -1}, {-1, -1, -1, -1, -1, -1}, {-1, 15, -1, -1, -1, -1}}; + + System.out.println("Min Dice throws required is " + new SnakeAndLadder().snakesAndLadders(board)); + + } +} \ No newline at end of file diff --git a/src/practiceproblems/SortANearlySortedArray.java b/src/main/java/practiceproblems/SortANearlySortedArray.java similarity index 92% rename from src/practiceproblems/SortANearlySortedArray.java rename to src/main/java/practiceproblems/SortANearlySortedArray.java index 4f8c092..78b3f04 100644 --- a/src/practiceproblems/SortANearlySortedArray.java +++ b/src/main/java/practiceproblems/SortANearlySortedArray.java @@ -4,7 +4,13 @@ import java.util.List; import java.util.PriorityQueue; -/*https://www.techiedelight.com/sort-k-sorted-array/*/ +/** + * https://www.techiedelight.com/sort-k-sorted-array/ + * + * tricky priority queue + */ + + class SortANearlySortedArray { public static void sortKSortedArray(List list, int k) { diff --git a/src/main/java/practiceproblems/SortedSquares.java b/src/main/java/practiceproblems/SortedSquares.java new file mode 100644 index 0000000..f537fb9 --- /dev/null +++ b/src/main/java/practiceproblems/SortedSquares.java @@ -0,0 +1,34 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/squares-of-a-sorted-array + */ +public class SortedSquares { + // Input: [-7,-3,2,3,11] + // Output: [4,9,9,49,121] + public int[] sortedSquares(int[] nums) { + + int[] result = new int[nums.length]; + + int i = 0; + int j = nums.length - 1; + int k = nums.length - 1; + while (i <= j) { + + if (nums[i] * nums[i] < nums[j] * nums[j]) { + result[k--] = nums[j] * nums[j]; + j--; + } else if (nums[i] * nums[i] > nums[j] * nums[j]) { + result[k--] = nums[i] * nums[i]; + i++; + } else { + result[k--] = nums[i] * nums[i]; + if (k >= 0) result[k--] = nums[i] * nums[i]; + i++; + j--; + } + } + + return result; + } +} \ No newline at end of file diff --git a/src/practiceproblems/SpiralMatrix.java b/src/main/java/practiceproblems/SpiralMatrix.java similarity index 88% rename from src/practiceproblems/SpiralMatrix.java rename to src/main/java/practiceproblems/SpiralMatrix.java index 9ef65f3..c21e290 100644 --- a/src/practiceproblems/SpiralMatrix.java +++ b/src/main/java/practiceproblems/SpiralMatrix.java @@ -3,11 +3,14 @@ import java.util.ArrayList; import java.util.List; +/** + * tricky matrix + */ class SpiralMatrix { public static List spiralOrder(int[][] matrix) { - List res = new ArrayList(); + List res = new ArrayList<>(); if (matrix.length == 0) { return res; @@ -32,7 +35,8 @@ public static List spiralOrder(int[][] matrix) { res.add(matrix[j][colEnd]); } colEnd--; - + + // Make sure we are now on a different row. if (rowBegin <= rowEnd) { // without this condition, this corner test case [[2,3]] would print [2,3,2] // Traverse Left for (int j = colEnd; j >= colBegin; j --) { @@ -42,7 +46,8 @@ public static List spiralOrder(int[][] matrix) { } rowEnd--; - // this block's work is to move 1 row up from bottom + // Make sure we are now on a different column. + // this block's work is to lift 1 row up from bottom // the rest of the work will be done by first 'Right' loop again if (colBegin <= colEnd) { // Traver Up diff --git a/src/practiceproblems/SpiralMatrixII.java b/src/main/java/practiceproblems/SpiralMatrixII.java similarity index 100% rename from src/practiceproblems/SpiralMatrixII.java rename to src/main/java/practiceproblems/SpiralMatrixII.java diff --git a/src/main/java/practiceproblems/StringJustify.java b/src/main/java/practiceproblems/StringJustify.java new file mode 100644 index 0000000..acde24f --- /dev/null +++ b/src/main/java/practiceproblems/StringJustify.java @@ -0,0 +1,99 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.List; + +/** + * https://leetcode.com/problems/text-justification + */ +public class StringJustify { + public List fullJustify(String[] words, int maxWidth) { + List result = new ArrayList<>(); + + int start = 0; + int end = 0; + while (start < words.length) { + end = findLastWordIndex(words, start, maxWidth); + + String line = justify(words, start, end, maxWidth); + result.add(line); + + start = end + 1; + } + + return result; + } + + private int findLastWordIndex(String[] words, int i, int maxWidth) { + int j = i; + + int currWidth = words[j].length(); //took first word at j, notice first one doesn't need a space. + j++; + // +1 is considered as space between the words + while (j < words.length && (currWidth + 1 + words[j].length() <= maxWidth)) { + currWidth = currWidth + 1 + words[j].length(); + j++; + } + + return j - 1; //end now points at the next index so -1 + } + + private String justify(String[] words, int i, int j, int maxWidth) { + // if there is only one word possible in this window, we simply pad extra spaces. + if (j - i == 0) return padResult(words[i], maxWidth); + + // For last line, j will always point to the last element. + boolean isLastLine = j == words.length - 1; + + // find the length of words. + int l = 0; + for (int k = i; k <= j; k++) { + l += words[k].length(); + } + + int numSpaces = maxWidth - l; + int numWordsToPad = j - i; // for total of 3 words, j=2, i=0 so 2 words to pad (since we don't pad last one) + + StringBuilder sb = new StringBuilder(); + + // SpaceStr is the string with right num of spaces that should be attached to each word (numWordsToPad) + String spaceStr = isLastLine ? " " : blank(numSpaces / numWordsToPad); // simple separation in last line + // remainderSpaceCount is the number of extra space that need to be attached to first words (from left) + // if we need to add 5 space and, we have 3 words we need to add extra space in round-robin manner + int remainderSpaceCount = isLastLine ? 0 : numSpaces % numWordsToPad; + + for (int k = i; k <= j; k++) { + sb.append(words[k]).append(spaceStr); // notice we also end up attaching to the last word, we will trim it later + + // also append extra spaces + if (remainderSpaceCount > 0) { + sb.append(" "); + remainderSpaceCount--; + } + } + + String line = sb.toString().trim(); // the last word will also have spaces, so need to tirm. + + return padResult(line, maxWidth); // if the last word still needs to be padded. + } + + private String padResult(String result, int maxWidth) { + return result + blank(maxWidth - result.length()); + } + + private String blank(int count) { + StringBuilder sb = new StringBuilder(); + while (count > 0) { + sb.append(" "); + count--; + } + + return sb.toString(); + } + + public static void main(String[] args) { + // System.out.println(new StringJustify().fullJustify(new String[]{"This", "is", "an", "example", "of", "text", "justification."}, 16)); + System.out.println(new StringJustify().fullJustify(new String[]{"What","must","be","acknowledgment","shall","be"}, 16)); + System.out.println(new StringJustify().fullJustify(new String[]{"Science","is","what","we","understand","well","enough","to","explain","to","a","computer.","Art","is","everything","else","we","do"}, 20)); + } +} diff --git a/src/practiceproblems/SubstringWindowTemplate.java b/src/main/java/practiceproblems/SubstringWindowTemplate.java similarity index 100% rename from src/practiceproblems/SubstringWindowTemplate.java rename to src/main/java/practiceproblems/SubstringWindowTemplate.java diff --git a/src/main/java/practiceproblems/SumOfSquares.java b/src/main/java/practiceproblems/SumOfSquares.java new file mode 100644 index 0000000..5f0b272 --- /dev/null +++ b/src/main/java/practiceproblems/SumOfSquares.java @@ -0,0 +1,19 @@ +package practiceproblems; + +/** + * https://leetcode.com/problems/sum-of-square-numbers/ + * + * Given a non-negative integer c, decide whether there're two integers a and b such that a2 + b2 = c. + */ +public class SumOfSquares { + public boolean judgeSquareSum(int c) { + long l = 0, r = (long) Math.sqrt(c); + while (l <= r) { // this <= other than < + long sum = l * l + r * r; + if (sum == c) return true; + if (sum < c) l++; + else r--; + } + return false; + } +} diff --git a/src/practiceproblems/SumSubArrayZero.java b/src/main/java/practiceproblems/SumSubArrayZero.java similarity index 85% rename from src/practiceproblems/SumSubArrayZero.java rename to src/main/java/practiceproblems/SumSubArrayZero.java index cde354d..11fed3f 100644 --- a/src/practiceproblems/SumSubArrayZero.java +++ b/src/main/java/practiceproblems/SumSubArrayZero.java @@ -7,11 +7,14 @@ /** * https://www.geeksforgeeks.org/print-all-subarrays-with-0-sum/ + * + * tricky sub array sum */ public class SumSubArrayZero { - private static class Pair { + + private static class Pair { int first, second; Pair(int a, int b) { @@ -23,6 +26,7 @@ public String toString() { return this.first + "--" + this.second; } } + static ArrayList findSubArrays(int[] arr, int n) { Map> map = new HashMap<>(); ArrayList result = new ArrayList<>(); @@ -34,8 +38,8 @@ static ArrayList findSubArrays(int[] arr, int n) { List al = new ArrayList<>(); if (map.containsKey(sum)) { al = map.get(sum); - for (int it = 0; it < al.size(); it++) { - result.add(new Pair(al.get(it) + 1, i)); + for (Integer integer : al) { + result.add(new Pair(integer + 1, i)); } } al.add(i); @@ -50,15 +54,14 @@ public static void main(String args[]) { ArrayList out = findSubArrays(arr, n); - if (out.size() == 0) + if (out.isEmpty()) System.out.println("No subarray exists"); else print(out); } static void print(ArrayList out) { - for (int i = 0; i < out.size(); i++) { - Pair p = out.get(i); + for (Pair p : out) { System.out.println("Subarray found from Index " + p.first + " to " + p.second); } } diff --git a/src/practiceproblems/SurroundedRegions.java b/src/main/java/practiceproblems/SurroundedRegions.java similarity index 98% rename from src/practiceproblems/SurroundedRegions.java rename to src/main/java/practiceproblems/SurroundedRegions.java index 2799e9a..4528267 100644 --- a/src/practiceproblems/SurroundedRegions.java +++ b/src/main/java/practiceproblems/SurroundedRegions.java @@ -10,26 +10,22 @@ * A region is captured by flipping all 'O's into 'X's in that surrounded region. *

* Example: - *

* X X X X * X O O X * X X O X * X O X X - *

* After running your function, the board should be: - *

* X X X X * X X X X * X X X X * X O X X - *

* Surrounded regions shouldn’t be on the border, * which means that any 'O' on the border of the board are not flipped to 'X'. * Any 'O' that is not on the border and * it is not connected to an 'O' on the border will be flipped to 'X'. * Two cells are connected if they are adjacent cells connected horizontally or vertically. */ -class Solution { +public class SurroundedRegions { private static class Pair { int x; int y; diff --git a/src/main/java/practiceproblems/TaskLeastInterval.java b/src/main/java/practiceproblems/TaskLeastInterval.java new file mode 100644 index 0000000..100906a --- /dev/null +++ b/src/main/java/practiceproblems/TaskLeastInterval.java @@ -0,0 +1,77 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * https://leetcode.com/problems/task-scheduler/ + * + * tricky priority queue + */ + + +public class TaskLeastInterval { + + public static int leastInterval(char[] tasks, int n) { + Map cache = new HashMap<>(); + + for (char c : tasks) { + cache.put(c, cache.getOrDefault(c, 0) + 1); + } + + PriorityQueue queue = new PriorityQueue<>((a, b) -> Integer.compare(b.freq, a.freq)); + + for (char key : cache.keySet()) { + queue.offer(new Pair(key, cache.get(key))); + } + int result = 0; + // At each iteration, we process at most 'n' elements, + // and move forwards exactly n+1 in time (regardless of how many elements we processed: + // Read the topmost from the queue and increment the time. Add it to a temp list to be added later. + // Add the element back to the queue from the temp list if count is > 0. + // if al elements are done, we're done too. + // Move time forward by n + 1 + // Return time in the end. + while (!queue.isEmpty()) { + int k = n + 1; //n slots for the gap and 1 for the task itself, At each iteration, we process at most 'n' elements, + // and move forwards exactly n+1 in time + List tempList = new ArrayList<>(); + + while (k > 0 && !queue.isEmpty()) { + Pair temp = queue.poll(); // most frequency task + temp.freq -= 1; // decrease frequency, meaning it got executed + tempList.add(temp); // collect task to add back to queue + result++; //successfully executed task + k--; + } + + for (Pair t : tempList) { + if (t.freq > 0) queue.offer(t); // add valid tasks + } + + if (queue.isEmpty()) break; + + result += k; // if k > 0, then it means we need to be idle + + } + return result; + } + + public static void main(String[] args) { + char[] arr = "A".toCharArray(); + System.out.println(leastInterval(arr, 2)); + } + + static class Pair { + char task; + int freq; + + public Pair(char task, int freq) { + this.task = task; + this.freq = freq; + } + } +} diff --git a/src/main/java/practiceproblems/ThreeSum.java b/src/main/java/practiceproblems/ThreeSum.java new file mode 100644 index 0000000..e0fef3c --- /dev/null +++ b/src/main/java/practiceproblems/ThreeSum.java @@ -0,0 +1,68 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class ThreeSum { + public List> threeSum(int[] nums) { + if (nums == null || nums.length == 0) return Collections.emptyList(); + + Arrays.sort(nums); + List> result = new ArrayList<>(); + for (int i = 0; i < nums.length; i++) { + if (i == 0 || (nums[i] != nums[i - 1])) { + + int left = i + 1; + int right = nums.length - 1; + int sum = -nums[i]; + while (left < right) { + if (nums[left] + nums[right] == sum) { + + result.add(Arrays.asList(nums[i], nums[left], nums[right])); + left++; + right--; + while (left < right && nums[left] == nums[left - 1]) left++; + while (left < right && nums[right] == nums[right + 1]) right--; + } else if (nums[left] + nums[right] < sum) { + left++; + } else if (nums[left] + nums[right] > sum) { + right--; + } + } + } + } + + return result; + } + + public int threeSumClosest(int[] nums, int target) { + + Arrays.sort(nums); + int initialSum = nums[0] + nums[1] + nums[nums.length - 1]; + for (int i = 0; i < nums.length - 2; i++) { + + int j = i + 1; + int k = nums.length - 1; + + while (j < k) { + int sum = nums[i] + nums[j] + nums[k]; + + if (sum > target) { + k--; + while (j < k && nums[k] == nums[k + 1]) k--; + } else { + j++; + while (j < k && nums[k] == nums[j - 1]) j++; + } + + if (Math.abs(target - sum) < Math.abs(target - initialSum)) { + initialSum = sum; + } + } + } + + return initialSum; + } +} \ No newline at end of file diff --git a/src/practiceproblems/TopKFrequentElements.java b/src/main/java/practiceproblems/TopKFrequentElements.java similarity index 55% rename from src/practiceproblems/TopKFrequentElements.java rename to src/main/java/practiceproblems/TopKFrequentElements.java index 8e0c563..a595729 100644 --- a/src/practiceproblems/TopKFrequentElements.java +++ b/src/main/java/practiceproblems/TopKFrequentElements.java @@ -12,6 +12,33 @@ */ public class TopKFrequentElements { + public Integer[] topKFrequentBucket(int[] nums, int k) { + + List[] bucket = new ArrayList[nums.length + 1]; + Map frequencyMap = new HashMap<>(); + + for (int n : nums) { + frequencyMap.put(n, frequencyMap.getOrDefault(n, 0) + 1); + } + + for (int key : frequencyMap.keySet()) { + int frequency = frequencyMap.get(key); + if (bucket[frequency] == null) { + bucket[frequency] = new ArrayList<>(); + } + bucket[frequency].add(key); + } + + List res = new ArrayList<>(); + + for (int pos = bucket.length - 1; pos >= 0 && res.size() < k; pos--) { + if (bucket[pos] != null) { + res.addAll(bucket[pos]); + } + } + return res.toArray(new Integer[k]); + } + public List topKFrequent(int[] nums, int k) { if (nums.length == 0) { return Collections.emptyList(); diff --git a/src/practiceproblems/TrailingZeroes.java b/src/main/java/practiceproblems/TrailingZeroes.java similarity index 100% rename from src/practiceproblems/TrailingZeroes.java rename to src/main/java/practiceproblems/TrailingZeroes.java diff --git a/src/practiceproblems/TreasureIsland.java b/src/main/java/practiceproblems/TreasureIsland.java similarity index 100% rename from src/practiceproblems/TreasureIsland.java rename to src/main/java/practiceproblems/TreasureIsland.java diff --git a/src/practiceproblems/TreasureIslandII.java b/src/main/java/practiceproblems/TreasureIslandII.java similarity index 100% rename from src/practiceproblems/TreasureIslandII.java rename to src/main/java/practiceproblems/TreasureIslandII.java diff --git a/src/practiceproblems/Trie.java b/src/main/java/practiceproblems/Trie.java similarity index 93% rename from src/practiceproblems/Trie.java rename to src/main/java/practiceproblems/Trie.java index aed8c68..6cc36d9 100644 --- a/src/practiceproblems/Trie.java +++ b/src/main/java/practiceproblems/Trie.java @@ -2,7 +2,7 @@ class Trie { - class TrieNode{ + static class TrieNode{ char data; TrieNode[] children; boolean isWord; @@ -36,8 +36,7 @@ public void insert(String word) { public boolean search(String word) { TrieNode result= helperFn(word); - if(result!=null && result.isWord) return true; - return false; + return result != null && result.isWord; } diff --git a/src/practiceproblems/TwoCityScheduling.java b/src/main/java/practiceproblems/TwoCityScheduling.java similarity index 98% rename from src/practiceproblems/TwoCityScheduling.java rename to src/main/java/practiceproblems/TwoCityScheduling.java index 7815435..cde3f6b 100644 --- a/src/practiceproblems/TwoCityScheduling.java +++ b/src/main/java/practiceproblems/TwoCityScheduling.java @@ -3,6 +3,7 @@ import java.util.PriorityQueue; /** + * TODO * There are 2N people a company is planning to interview. * The cost of flying the i-th person to city A is costs[i][0], and the cost of flying the i-th person to city B is costs[i][1]. * Return the minimum cost to fly every person to a city such that exactly N people arrive in each city. @@ -27,7 +28,8 @@ public int twoCitySchedCost(int[][] costs) { // [-10, -170, 350, 10] // what the above array indicates is that for i'th candidate=>[10,20] we will save 10 in sending to A // when i=2 we will have to spend 350 more to bring to A city so we sort by arr[0]-arr[1] - // greedily we take negative val candidates to A and rest to B for this input + // greedily we take negative val candidates to A and rest to B for this input + PriorityQueue queue= new PriorityQueue<>((a, b)->(a[0] - a[1]) - (b[0] - b[1])); for(int[] cost: costs){ diff --git a/src/practiceproblems/TwoSumClosestToZero.java b/src/main/java/practiceproblems/TwoSumClosestToZero.java similarity index 95% rename from src/practiceproblems/TwoSumClosestToZero.java rename to src/main/java/practiceproblems/TwoSumClosestToZero.java index 9afee38..3606a30 100644 --- a/src/practiceproblems/TwoSumClosestToZero.java +++ b/src/main/java/practiceproblems/TwoSumClosestToZero.java @@ -17,7 +17,6 @@ public static void findPair(Integer[] arr) { Arrays.sort(arr); - System.out.println(Arrays.toString(arr)); int low = 0; int high = arr.length - 1; diff --git a/src/practiceproblems/UniqueElementsInArray.java b/src/main/java/practiceproblems/UniqueElementsInArray.java similarity index 100% rename from src/practiceproblems/UniqueElementsInArray.java rename to src/main/java/practiceproblems/UniqueElementsInArray.java diff --git a/src/practiceproblems/UniquePath.java b/src/main/java/practiceproblems/UniquePath.java similarity index 75% rename from src/practiceproblems/UniquePath.java rename to src/main/java/practiceproblems/UniquePath.java index 4b99c71..3179712 100644 --- a/src/practiceproblems/UniquePath.java +++ b/src/main/java/practiceproblems/UniquePath.java @@ -7,7 +7,7 @@ public class UniquePath { public static void main(String[] args) { System.out.println(uniquePathI(3, 2)); - int[][] matrix = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } }; + int[][] matrix = {{0, 0, 0}, {0, 1, 0}, {0, 0, 0}}; System.out.println(uniquePathII(matrix)); @@ -32,13 +32,13 @@ private static int uniquePathI(int row, int col) { return dp[row - 1][col - 1]; } - /** + /** * Now consider if some obstacles are added to the grids. How many unique paths would there be? * Input: * [ - * [0,0,0], - * [0,1,0], - * [0,0,0] + * [0,0,0], + * [0,1,0], + * [0,0,0] * ] * Output: 2 * Explanation: @@ -86,4 +86,22 @@ private static int uniquePathII(int[][] obstacleGrid) { return dp[m - 1][n - 1]; } + + Integer[][] cache; + + public int uniquePathsWithObstacles(int[][] obstacleGrid) { + cache = new Integer[obstacleGrid.length][obstacleGrid[0].length]; + return recursionHelper(obstacleGrid, 0, 0); + } + + public int recursionHelper(int[][] arr, int i, int j) { + if (i < 0 || j < 0 || i >= arr.length || j >= arr[0].length || arr[i][j] == 1) return 0; + + if (i == arr.length - 1 && j == arr[0].length - 1) return 1; + + if (cache[i][j] != null) return cache[i][j]; + + return cache[i][j] = recursionHelper(arr, i, j + 1) + recursionHelper(arr, i + 1, j); + + } } diff --git a/src/practiceproblems/UniquePathMaximum.java b/src/main/java/practiceproblems/UniquePathMaximum.java similarity index 90% rename from src/practiceproblems/UniquePathMaximum.java rename to src/main/java/practiceproblems/UniquePathMaximum.java index ef28cac..cdbd1c9 100644 --- a/src/practiceproblems/UniquePathMaximum.java +++ b/src/main/java/practiceproblems/UniquePathMaximum.java @@ -2,8 +2,12 @@ /* https://leetcode.com/discuss/interview-question/383669/ + +// revision */ +import java.util.Arrays; + /** * find the maximum score of a path starting at [0, 0] and ending at [r-1, c-1]. The score of a path is the minimum value in that path. *

@@ -41,6 +45,10 @@ private static int findMaximumOfUniquePath(int[][] matrix) { Math.min(matrix[i][j - 1], matrix[i][j])); } } + + for (int[] ints : matrix) { + System.out.println(Arrays.toString(ints)); + } return matrix[matrix.length - 1][matrix[0].length - 1]; } } \ No newline at end of file diff --git a/src/main/java/practiceproblems/UpdateMatrix.java b/src/main/java/practiceproblems/UpdateMatrix.java new file mode 100644 index 0000000..5172905 --- /dev/null +++ b/src/main/java/practiceproblems/UpdateMatrix.java @@ -0,0 +1,116 @@ +package practiceproblems; + +import java.util.ArrayDeque; +import java.util.Queue; + +/** + * https://leetcode.com/problems/01-matrix/ + * + * Given an m x n binary matrix mat, return the distance of the nearest 0 for each cell. + * + * The distance between two adjacent cells is 1. + */ +public class UpdateMatrix { + + /** + * Naive BFS invoked multiple times (Slow) + * i) Iterate over the matrix with a nested for-loop to find cells containing 1 + * ii) Apply BFS algo on those cells -> pass those cells to a BFS helper to find distance to closest 0 + * iii) update the matrix cell with the distance + *

+ * Optimized BFS invoked only once (Fast) + * Idea + *

+ * Instead of invoking BFS for each land cell to see how far we can get away from that source, we flip the problem. + * The flipped problem is to start from target (sea) and to figure our the closest source (land) + * This allows us to run a single BFS search that emerges from different places + * (all the targets aka all the zero cells) in the grid + *

+ * Add all the targets (all zero cells) into the queue. + * While you're at it, also mark those targets as visited (add to a visited set) + *

+ * Run a single BFS on the pre-processed queue and investigate neighbours. + *

+ * if neighbour cell has not been visited --> then it must bea land cell + * (since all the sea cells have been marked visited): + * append the neighbour cell into the queue and mutate the gird + * + * @param matrix + * @return + */ + public int[][] updateMatrix(int[][] matrix) { + Queue queue = new ArrayDeque<>(); + int m = matrix.length, n = matrix[0].length; + boolean[][] visited = new boolean[m][n]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (matrix[i][j] == 0) { + queue.offer(new int[]{i, j}); + visited[i][j] = true; + } + } + } + int[][] dir = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; + while (!queue.isEmpty()) { + int[] cur = queue.poll(); + for (int i = 0; i < 4; i++) { + int row = cur[0] + dir[i][0]; + int col = cur[1] + dir[i][1]; + if (row < 0 || row >= m || col < 0 || col >= n || visited[row][col]) { + continue; + } + visited[row][col] = true; + /** + * since, we popped out the cell (cell(0),cell(1)) and now looking at all its four adjacent cells + * and since we're sure that the cell has its minimum distance from zero , + * so, in case any of its four cells value(calling it child cell) + * (which is child's distance from zero cell except when its Max Integer value) + * has value more than the {value in cell} + 1 , + * we update the child cell to {value in cell} + 1 .. + 1 is used because + * when add +1 as going from a cell to next adjacent cell increases path by 1 + */ + matrix[row][col] = matrix[cur[0]][cur[1]] + 1; + queue.offer(new int[]{row, col}); + } + } + return matrix; + } + + /** + * In this problem, a cell has at most 4 neighbors that are left, top, right, bottom. + * If we use dynamic programming to compute the distance of the current cell based on 4 neighbors simultaneously, + * it's impossible because we are not sure if distance of neighboring cells is already computed or not + * + * For those who are asking why DP is done in two passes, in DP we can only use the values which are previously calculated. + * When we are parsing from top left and coming down to bottom right, + * we can only use the values of above and left because only those two values are precomputed, + * if we take right and down, those values are not yet computed, + * if we work with those values we will get suboptimal answer. + */ + public int[][] updateMatrixDP(int[][] matrix) { + int maxValue = matrix.length * matrix[0].length; + + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix[0].length; j++) { + if (matrix[i][j] == 0) continue; + + int top = i - 1 >= 0 ? matrix[i - 1][j] : maxValue; + int left = j - 1 >= 0 ? matrix[i][j - 1] : maxValue; + + matrix[i][j] = Math.min(top, left) + 1; + } + } + + for (int i = matrix.length - 1; i >= 0; i--) { + for (int j = matrix[0].length - 1; j >= 0; j--) { + int bottom = i + 1 < matrix.length ? matrix[i + 1][j] : maxValue; + int right = j + 1 < matrix[0].length ? matrix[i][j + 1] : maxValue; + + matrix[i][j] = Math.min(matrix[i][j], Math.min(bottom, right) + 1); + } + } + + return matrix; + + } +} diff --git a/src/practiceproblems/UrlEncode.java b/src/main/java/practiceproblems/UrlEncode.java similarity index 96% rename from src/practiceproblems/UrlEncode.java rename to src/main/java/practiceproblems/UrlEncode.java index c081ea3..b5cc11d 100644 --- a/src/practiceproblems/UrlEncode.java +++ b/src/main/java/practiceproblems/UrlEncode.java @@ -37,7 +37,7 @@ public static void main(String[] args) { private static void test(char[] str, String s) { IntStream.range(0, s.length()).forEach(i -> str[i] = s.charAt(i)); - System.out.print(new String(str) +" - "); + System.out.print(new String(str) + " - "); UrlEncode ob = new UrlEncode(); ob.replaceSpaces(str, s.length()); System.out.println(new String(str)); diff --git a/src/practiceproblems/ValidPalindromeII.java b/src/main/java/practiceproblems/ValidPalindromeII.java similarity index 85% rename from src/practiceproblems/ValidPalindromeII.java rename to src/main/java/practiceproblems/ValidPalindromeII.java index 714abb4..a8eb6aa 100644 --- a/src/practiceproblems/ValidPalindromeII.java +++ b/src/main/java/practiceproblems/ValidPalindromeII.java @@ -16,10 +16,7 @@ public static boolean validPalindrome(String s) { return true; } - if (isPalindrome(s, i + 1, j) || isPalindrome(s, i, j - 1)) { - return true; - } - return false; + return isPalindrome(s, i + 1, j) || isPalindrome(s, i, j - 1); } private static boolean isPalindrome(String s, int i, int j) { diff --git a/src/practiceproblems/ValidSudoku.java b/src/main/java/practiceproblems/ValidSudoku.java similarity index 100% rename from src/practiceproblems/ValidSudoku.java rename to src/main/java/practiceproblems/ValidSudoku.java diff --git a/src/practiceproblems/ValidateIpAddresses.java b/src/main/java/practiceproblems/ValidateIpAddresses.java similarity index 100% rename from src/practiceproblems/ValidateIpAddresses.java rename to src/main/java/practiceproblems/ValidateIpAddresses.java diff --git a/src/main/java/practiceproblems/VulgarDecimal.java b/src/main/java/practiceproblems/VulgarDecimal.java new file mode 100644 index 0000000..f7e972b --- /dev/null +++ b/src/main/java/practiceproblems/VulgarDecimal.java @@ -0,0 +1,56 @@ +package practiceproblems; + +import java.util.HashMap; +import java.util.Map; + +/** + * https://leetcode.com/problems/fraction-to-recurring-decimal + * tricky + */ +public class VulgarDecimal { + + public String fractionToDecimal(int numerator, int denominator) { + + boolean isNegative = numerator < 0 && denominator > 0 || numerator > 0 && denominator < 0; + + StringBuilder sb = new StringBuilder(); + Map map = new HashMap<>(); + long numeratorL = Math.abs(numerator); + long denominatorL = Math.abs(denominator); + + long rem = numeratorL / denominatorL; + sb.append(rem); + + if (isNegative) sb.insert(0, '-'); + + if (numeratorL % denominatorL > 0) { + sb.append("."); + } else { + return sb.toString(); + } + numeratorL %= denominatorL; + map.put(numeratorL, sb.length()); + + while (numeratorL > 0) { + numeratorL *= 10; + + rem = numeratorL / denominatorL; + sb.append(rem); + numeratorL %= denominatorL; + + if (map.containsKey(numeratorL)) { + int pos = map.get(numeratorL); + sb.insert(pos, "("); + sb.append(")"); + break; + } else { + map.put(numeratorL, sb.length()); + } + + } + + return sb.toString(); + } + + +} diff --git a/src/main/java/practiceproblems/WordBreak.java b/src/main/java/practiceproblems/WordBreak.java new file mode 100644 index 0000000..f748b45 --- /dev/null +++ b/src/main/java/practiceproblems/WordBreak.java @@ -0,0 +1,117 @@ +package practiceproblems; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +class WordBreak { + +/** + * +|T| | | | | | | | | + 0 1 2 3 4 5 6 7 8 + +i = 1 +j = 0 sub = l + +i = 2 +j = 0 sub = le +j = 1 sub = e + +i = 3 +j = 0 sub = lee +j = 1 sub = ee +j = 2 sub = e + +i = 4 +j = 0 sub = leet && T[0] and then break, no need to check for rest +|T | | | |T| | | | | +0 1 2 3 4 5 6 7 8 + +i = 5 +j = 0 sub = leetc +j = 1 sub = eetc +j = 2 sub = etc +j = 3 sub = tc +j = 4 sub = c + +i = 6 +j = 0 sub = leetco +j = 1 sub = eetco +j = 2 sub = etco +j = 3 sub = tco +j = 4 sub = co +j = 5 sub = o + +i = 7 +j = 0 sub = leetcod +j = 1 sub = eetcod +j = 2 sub = etcod +j = 3 sub = tcod +j = 4 sub = cod +j = 5 sub = od +j = 6 sub = d + +i = 8 +j = 0 sub = leetcode +j = 1 sub = eetcode +j = 2 sub = etcode +j = 3 sub = tcode +j = 4 sub = code && T[4] and then break + +|T| | | |T| | | |T| + 0 1 2 3 4 5 6 7 8 +*/ + public boolean wordBreak(String s, List wordDict) { + if (s == null) { + return false; + } + boolean[] dp = new boolean[s.length() + 1]; + dp[0] = true; + Set set = new HashSet<>(wordDict); + + for (int i = 1; i <= s.length(); i++) { + for (int j = 0; j < i; j++) { + dp[i] = dp[j] && set.contains(s.substring(j, i)); + if (dp[i]) { + break; + } + } + } + + return dp[s.length()]; + } + + public boolean wordBreakRec(String s, List wordDict) { + // create the memoization array to save results and avoid repeat computations + Boolean[] canBreak = new Boolean[s.length()]; + + // convert the list into set for faster lookup + Set wordSet = new HashSet<>(wordDict); + + // recursion with memoization + return helper(s, 0, wordSet, canBreak); + } + + private boolean helper(String s, int startIdx, Set wordSet, Boolean[] canBreak) { + // in case we've reached the end of string, return true + if (startIdx == s.length()) return true; + // else if we've already computed on current substring before + if (canBreak[startIdx] != null) return canBreak[startIdx]; // auto-unboxing + + boolean res = false; + // iterate through all indices after startIdx, explore every possible word + for (int i = startIdx + 1; i <= s.length(); i++) { + String currWord = s.substring(startIdx, i); + // skip if this is not a word in the input dictionary + // recursively call upon the rest of string + if (wordSet.contains(currWord) && helper(s, i, wordSet, canBreak)) { + res = true; + break; + } + } + // add result to memo and return the result + canBreak[startIdx] = res; + return res; + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/WordBreakII.java b/src/main/java/practiceproblems/WordBreakII.java new file mode 100644 index 0000000..a4e0132 --- /dev/null +++ b/src/main/java/practiceproblems/WordBreakII.java @@ -0,0 +1,37 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * tricky WordBreak + */ +public class WordBreakII { + public List wordBreak(String s, List wordDict) { + Map> cache = new HashMap<>(); + backtrack(s, wordDict, cache); + return cache.get(s); + } + + public List backtrack(String s, List wordDict, Map> cache) { + + if (cache.containsKey(s)) return cache.get(s); + + List result = new ArrayList<>(); + for (String word : wordDict) { + if (!s.startsWith(word)) continue; // string does not start with this word? + String next = s.substring(word.length()); + if (next.isEmpty()) { + result.add(word); + } else { + for (String sub : backtrack(next, wordDict, cache)) { + result.add(word + " " + sub); + } + } + } + cache.put(s, result); + return result; + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/WordLadder.java b/src/main/java/practiceproblems/WordLadder.java new file mode 100644 index 0000000..32dd282 --- /dev/null +++ b/src/main/java/practiceproblems/WordLadder.java @@ -0,0 +1,49 @@ +package practiceproblems; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.Set; + +public class WordLadder { + public int ladderLength(String beginWord, String endWord, List wordList) { + Set set = new HashSet<>(wordList); + if (!set.contains(endWord)) return 0; // end word itself not in set + Queue queue = new LinkedList<>(); + queue.add(beginWord); + int count = 1; + + while (!queue.isEmpty()) { + + int size = queue.size(); + for (int i = 0; i < size; i++) { // going level by level + String currentWord = queue.poll(); + char[] charArray = currentWord.toCharArray(); + + for (int j = 0; j < charArray.length; j++) { + char temp = charArray[j]; // storing the value to reset back + for (char ch = 'a'; ch <= 'z'; ch++) { // try all letters in alphabets + if (temp == ch) { + continue; + } + charArray[j] = ch; + String newWord = String.valueOf(charArray); + if (set.contains(newWord)) { + if (newWord.equals(endWord)) { // if found return count + return count + 1; + } + queue.add(newWord);// else add to queue and continue + set.remove(newWord);// because you already reached this word, no need to see again + } + } + charArray[j] = temp; + } + + } + count++; + } + + return 0; + } +} \ No newline at end of file diff --git a/src/practiceproblems/WordSearch.java b/src/main/java/practiceproblems/WordSearch.java similarity index 98% rename from src/practiceproblems/WordSearch.java rename to src/main/java/practiceproblems/WordSearch.java index 00cf7e7..d8d654e 100644 --- a/src/practiceproblems/WordSearch.java +++ b/src/main/java/practiceproblems/WordSearch.java @@ -2,6 +2,8 @@ /** * https://leetcode.com/problems/word-search/ + * + * tricky dfs */ public class WordSearch { diff --git a/src/main/java/practiceproblems/WordSearchII.java b/src/main/java/practiceproblems/WordSearchII.java new file mode 100644 index 0000000..ac3ac2d --- /dev/null +++ b/src/main/java/practiceproblems/WordSearchII.java @@ -0,0 +1,57 @@ +package practiceproblems; + +import java.util.ArrayList; +import java.util.List; + +/** + * TODO- revision + * https://leetcode.com/problems/word-search-ii/ + */ +public class WordSearchII { + public List findWords(char[][] board, String[] words) { + List res = new ArrayList<>(); + TrieNode root = buildTrie(words); + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + dfs(board, i, j, root, res); + } + } + return res; + } + + public void dfs(char[][] board, int i, int j, TrieNode p, List res) { + char c = board[i][j]; + if (c == '#' || p.children[c - 'a'] == null) return; + p = p.children[c - 'a']; + if (p.word != null) { // found one + res.add(p.word); + p.word = null; // de-duplicate + } + + board[i][j] = '#'; + if (i > 0) dfs(board, i - 1, j, p, res); + if (j > 0) dfs(board, i, j - 1, p, res); + if (i < board.length - 1) dfs(board, i + 1, j, p, res); + if (j < board[0].length - 1) dfs(board, i, j + 1, p, res); + board[i][j] = c; + } + + public TrieNode buildTrie(String[] words) { + TrieNode root = new TrieNode(); + for (String w : words) { + TrieNode p = root; + for (char c : w.toCharArray()) { + int i = c - 'a'; + if (p.children[i] == null) p.children[i] = new TrieNode(); + p = p.children[i]; + } + p.word = w; + } + return root; + } + + private static class TrieNode { + TrieNode[] children = new TrieNode[26]; + String word; + } +} diff --git a/src/main/java/practiceproblems/design/AllOneDataStructure.java b/src/main/java/practiceproblems/design/AllOneDataStructure.java new file mode 100644 index 0000000..130a20d --- /dev/null +++ b/src/main/java/practiceproblems/design/AllOneDataStructure.java @@ -0,0 +1,112 @@ +package practiceproblems.design; + +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +/** + * TODO + */ +public class AllOneDataStructure { + + class ValueNode { + ValueNode prev, next; + int val; + Set strs; + + ValueNode(int v) { + val = v; + strs = new LinkedHashSet<>(); + } + + void insertAt(ValueNode node) { + next = node; + prev = node.prev; + next.prev = this; + prev.next = this; + } + + void remove(String str) { + strs.remove(str); + if (strs.isEmpty()) { + prev.next = next; + next.prev = prev; + } + } + } + + ValueNode valueHead, valueTail; // dummy + Map keys; + + /** + * Initialize your data structure here. + */ + public AllOneDataStructure() { + valueHead = new ValueNode(0); + valueTail = new ValueNode(0); + valueHead.next = valueTail; + valueTail.prev = valueHead; + keys = new HashMap<>(); + } + + /** + * Inserts a new key with value 1. Or increments an existing key by 1. + */ + public void inc(String key) { + ValueNode node = keys.getOrDefault(key, valueHead); + ValueNode vn = node.next; + if (vn.val != node.val + 1) { + vn = new ValueNode(node.val + 1); + vn.insertAt(node.next); + } + vn.strs.add(key); + keys.put(key, vn); + if (node != valueHead) node.remove(key); + } + + /** + * Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. + */ + public void dec(String key) { + ValueNode node = keys.get(key); + if (node == null) return; + if (node.val == 1) { + keys.remove(key); + node.remove(key); + return; + } + ValueNode vn = node.prev; + if (vn.val != node.val - 1) { + vn = new ValueNode(node.val - 1); + vn.insertAt(node); + } + vn.strs.add(key); + keys.put(key, vn); + node.remove(key); + } + + /** + * Returns one of the keys with maximal value. + */ + public String getMaxKey() { + if (valueTail.prev == valueHead) return ""; + return valueTail.prev.strs.iterator().next(); + } + + /** + * Returns one of the keys with Minimal value. + */ + public String getMinKey() { + if (valueHead.next == valueTail) return ""; + return valueHead.next.strs.iterator().next(); + } + + public static void main(String[] args) { + AllOneDataStructure o = new AllOneDataStructure(); + o.inc("Hello"); + o.inc("Hello"); + o.inc("Leet"); + o.dec("Hello"); + } +} diff --git a/src/main/java/practiceproblems/design/AuthenticationManager.java b/src/main/java/practiceproblems/design/AuthenticationManager.java new file mode 100644 index 0000000..8f7472a --- /dev/null +++ b/src/main/java/practiceproblems/design/AuthenticationManager.java @@ -0,0 +1,54 @@ +package practiceproblems.design; + +import java.util.TreeMap; + +/** + * https://leetcode.com/problems/design-authentication-manager/ + */ +public class AuthenticationManager { + + int timeToLive; + TreeMap authCache; + TreeMap timeCache; + + /** + * AuthenticationManager(int timeToLive) constructs the AuthenticationManager and sets the timeToLive. + */ + public AuthenticationManager(int timeToLive) { + this.timeToLive = timeToLive; + authCache = new TreeMap<>(); + timeCache = new TreeMap<>(); + + } + + /** + * generate(string tokenId, int currentTime) generates a new token with the given tokenId at the given currentTime in seconds. + */ + public void generate(String tokenId, int currentTime) { + authCache.put(tokenId, currentTime); + timeCache.put(currentTime, tokenId); + } + + /** + * renews the unexpired token with the given tokenId at the given currentTime in seconds. + * If there are no unexpired tokens with the given tokenId, the request is ignored, and nothing happens. + */ + public void renew(String tokenId, int currentTime) { + if (!authCache.containsKey(tokenId)) return; + + int timeOfToken = authCache.get(tokenId); + + if (timeOfToken + timeToLive > currentTime) { + timeCache.remove(timeOfToken); + authCache.put(tokenId, currentTime); + timeCache.put(currentTime, tokenId); + } + } + + /** + * returns the number of unexpired tokens at the given currentTime. + */ + public int countUnexpiredTokens(int currentTime) { + return timeCache.subMap(currentTime - timeToLive + 1, currentTime).size(); + } +} diff --git a/src/practiceproblems/AutoCompleteSystem.java b/src/main/java/practiceproblems/design/AutoCompleteSystem.java similarity index 98% rename from src/practiceproblems/AutoCompleteSystem.java rename to src/main/java/practiceproblems/design/AutoCompleteSystem.java index 1a8efdb..cb09986 100644 --- a/src/practiceproblems/AutoCompleteSystem.java +++ b/src/main/java/practiceproblems/design/AutoCompleteSystem.java @@ -1,8 +1,9 @@ -package practiceproblems; +package practiceproblems.design; import java.util.*; /** + * tricky trie * https://cheonhyangzhang.gitbooks.io/leetcode-solutions/content/642-design-search-autocomplete-system.html */ class AutoCompleteSystem { diff --git a/src/main/java/practiceproblems/design/BrowserHistory.java b/src/main/java/practiceproblems/design/BrowserHistory.java new file mode 100644 index 0000000..7041c36 --- /dev/null +++ b/src/main/java/practiceproblems/design/BrowserHistory.java @@ -0,0 +1,69 @@ +package practiceproblems.design; + +/** + * https://leetcode.com/problems/design-browser-history/ + * + * tricky linkedlist + */ +public class BrowserHistory { + + Node head; + Node currentNode; + + public BrowserHistory(String homepage) { + head = new Node("dummy"); + + Node newNode = new Node(homepage); + head.next = newNode; + newNode.prev = head; + currentNode = newNode; + } + + public void visit(String url) { + Node newNode = new Node(url); + head.next = newNode; + newNode.prev = head; + + currentNode.prev = newNode; + newNode.next = currentNode; + currentNode = newNode; + } + + public String back(int steps) { + Node curr = currentNode; + + while (steps > 0 && curr.next != null) { + curr = curr.next; + steps--; + } + currentNode = curr; + return curr.url; + } + + public String forward(int steps) { + Node curr = currentNode; + while (!curr.prev.url.equals("dummy") && steps > 0) { + curr = curr.prev; + steps--; + } + currentNode = curr; + return currentNode.url; + + } + + static class Node { + String url; + Node next; + Node prev; + + public Node(String url) { + this.url = url; + } + + @Override + public String toString() { + return prev + " " + url + " " + next; + } + } +} + diff --git a/src/practiceproblems/DesignCompressedStringIterator.java b/src/main/java/practiceproblems/design/DesignCompressedStringIterator.java similarity index 69% rename from src/practiceproblems/DesignCompressedStringIterator.java rename to src/main/java/practiceproblems/design/DesignCompressedStringIterator.java index 1edc6b1..1c3a959 100644 --- a/src/practiceproblems/DesignCompressedStringIterator.java +++ b/src/main/java/practiceproblems/design/DesignCompressedStringIterator.java @@ -1,13 +1,8 @@ -package practiceproblems; +package practiceproblems.design; /** * https://leetcode.com/articles/desing-compressed-string-iterator/ - * 604. Design Compressed String Iterator - * Design and implement a data structure for a compressed string iterator. The given compressed string will be in the form of each letter followed by a positive integer representing the number of this letter existing in the original uncompressed string. - * Implement the StringIterator class: - * next() Returns the next character if the original string still has uncompressed characters, otherwise returns a white space. - * hasNext() Returns true if there is any letter needs to be uncompressed in the original string, otherwise returns false. - + * * Example 1: * Input diff --git a/src/main/java/practiceproblems/design/DesignFileSystem.java b/src/main/java/practiceproblems/design/DesignFileSystem.java new file mode 100644 index 0000000..f579c37 --- /dev/null +++ b/src/main/java/practiceproblems/design/DesignFileSystem.java @@ -0,0 +1,46 @@ +package practiceproblems.design; + +import java.util.HashMap; + +/** + * https://leetcode.com/problems/design-file-system/ + */ +public class DesignFileSystem { + + private final HashMap cache = new HashMap<>(); + + /** + * Initialization of class. + * Use a hash map to store the path and value. + */ + public DesignFileSystem() { + cache.put("", -1); // avoid initially when path is "/a" regarded as false + } + + /** + * Creates a new path and associates a value to it if possible and returns True. + * The valid path's parent is the path before the last "/". + * Hence, check parent and then put the path into map if it is valid. + * If the path has already exist, return false. + * + * @param path given path + * @param value given value + * @return true to create a new path with value, false if the path already exists or its parent path doesn't exist + */ + public boolean create(String path, int value) { + if (path.charAt(0) != '/') { + return false; + } + String parent = path.substring(0, path.lastIndexOf("/")); + if (!cache.containsKey(parent)) { + return false; + } + + return cache.putIfAbsent(path, value) == null; // if the path exist, m.putIfAbsent(path, value) will be null + } + + public int get(String path) { + return cache.getOrDefault(path, -1); + } + +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/design/DesignHashMap.java b/src/main/java/practiceproblems/design/DesignHashMap.java new file mode 100644 index 0000000..4da03c5 --- /dev/null +++ b/src/main/java/practiceproblems/design/DesignHashMap.java @@ -0,0 +1,85 @@ +package practiceproblems.design; + +public class DesignHashMap { + ListNode[] nodes; + + /** + * Initialize your data structure here. + */ + public DesignHashMap() { + nodes = new ListNode[10000]; + } + + private int idx(int key) { + return Integer.hashCode(key) % nodes.length; + } + + private ListNode find(ListNode node, int val) { + ListNode temp = node, prev = null; + while (temp != null && temp.key != val) { + prev = temp; + temp = temp.next; + } + return prev; + } + + /** + * value will always be non-negative. + */ + public void put(int key, int value) { + int i = idx(key); + if (nodes[i] == null) { + nodes[i] = new ListNode(-1, -1); + } + ListNode prev = find(nodes[i], key); + if (prev.next == null) { + prev.next = new ListNode(key, value); + } else { + prev.next.val = value; + } + } + + /** + * Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key + */ + public int get(int key) { + int i = idx(key); + if (nodes[i] == null) { + return -1; + } + ListNode prev = find(nodes[i], key); + if (prev.next == null) { + return -1; + } + return prev.next.val; + } + + /** + * Removes the mapping of the specified value key if this map contains a mapping for the key + */ + public void remove(int key) { + int i = idx(key); + if (nodes[i] == null) { + return; + } + ListNode prev = find(nodes[i], key); + if (prev.next == null) { + return; + } + prev.next = prev.next.next; + } + + class ListNode { + int key; + int val; + ListNode next; + + public ListNode(int key, int val) { + this.key = key; + this.val = val; + } + } +} + + + diff --git a/src/practiceproblems/DesignInMemoryFileSystem.java b/src/main/java/practiceproblems/design/DesignInMemoryFileSystem.java similarity index 54% rename from src/practiceproblems/DesignInMemoryFileSystem.java rename to src/main/java/practiceproblems/design/DesignInMemoryFileSystem.java index 84eb5c0..00a95e0 100644 --- a/src/practiceproblems/DesignInMemoryFileSystem.java +++ b/src/main/java/practiceproblems/design/DesignInMemoryFileSystem.java @@ -1,18 +1,6 @@ -package practiceproblems; +package practiceproblems.design; /** - * Design an in-memory file system to simulate the following functions: - *

- * ls: Given a path in string format. If it is a file path, return a list that only contains this file's name. - * If it is a directory path, return the list of file and directory names in this directory. Your output (file and directory names together) should in lexicographic order. - *

- * mkdir: Given a directory path that does not exist, you should make a new directory according to the path. - * If the middle directories in the path don't exist either, you should create them as well. This function has void return type. - *

- * addContentToFile: Given a file path and file content in string format. - * If the file doesn't exist, you need to create that file containing given content. - * If the file already exists, you need to append given content to original content. This function has void return type. - *

- * readContentFromFile: Given a file path, return its content in string format. + * tricky trie */ import java.util.ArrayList; @@ -54,10 +42,9 @@ public List ls(String path) { public void mkdir(String path) { Trie trie = root; String[] arr = path.split("/"); + // we start from 1st index because "/a/b/c".split("/") => ["", "a", "b", "c"] for (int i = 1; i < arr.length; i++) { - if (!trie.folders.containsKey(arr[i])) { - trie.folders.put(arr[i], new Trie()); - } + trie.folders.putIfAbsent(arr[i], new Trie()); trie = trie.folders.get(arr[i]); } } @@ -68,9 +55,7 @@ public void addContentToFile(String filePath, String content) { for (int i = 1; i < arr.length - 1; i++) { trie = trie.folders.get(arr[i]); } - if (!trie.folders.containsKey(arr[arr.length - 1])) { - trie.folders.put(arr[arr.length - 1], new Trie()); - } + trie.folders.putIfAbsent(arr[arr.length - 1], new Trie()); trie = trie.folders.get(arr[arr.length - 1]); trie.isFile = true; trie.content = trie.content + content; @@ -84,13 +69,4 @@ public String readContentFromFile(String filePath) { } return trie.folders.get(arr[arr.length - 1]).content; } -} - -/** - * Your FileSystem object will be instantiated and called as such: - * FileSystem obj = new FileSystem(); - * List param_1 = obj.ls(path); - * obj.mkdir(path); - * obj.addContentToFile(filePath,content); - * String param_4 = obj.readContentFromFile(filePath); - */ \ No newline at end of file +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/design/DesignStackIncrement.java b/src/main/java/practiceproblems/design/DesignStackIncrement.java new file mode 100644 index 0000000..21e75bf --- /dev/null +++ b/src/main/java/practiceproblems/design/DesignStackIncrement.java @@ -0,0 +1,35 @@ +package practiceproblems.design; + +/** + * tricky sweep line + * https://leetcode.com/problems/design-a-stack-with-increment-operation + */ +public class DesignStackIncrement { + int[] st; + int top; + int maxSize; + + public DesignStackIncrement(int maxSize) { + this.maxSize = maxSize; + st = new int[maxSize]; + top = 0; + } + + public void pushAlter(int x) { + if (top < maxSize) { + st[top++] = x; + } + } + + public int popAlter() { + if (top <= 0) + return -1; + return st[--top]; + } + + public void incrementAlter(int k, int val) { + int l = Math.min(k, top); + for (int i = 0; i < l; i++) + st[i] += val; + } +} \ No newline at end of file diff --git a/src/practiceproblems/DesignTicTacToe.java b/src/main/java/practiceproblems/design/DesignTicTacToe.java similarity index 95% rename from src/practiceproblems/DesignTicTacToe.java rename to src/main/java/practiceproblems/design/DesignTicTacToe.java index 3a4fff9..ceb2875 100644 --- a/src/practiceproblems/DesignTicTacToe.java +++ b/src/main/java/practiceproblems/design/DesignTicTacToe.java @@ -1,4 +1,4 @@ -package practiceproblems; +package practiceproblems.design; /* Design a Tic-tac-toe game that is played between two players on a n x n grid. @@ -10,7 +10,7 @@ Given n = 3, assume that player 1 is "X" and player 2 is "O" in the board. -TicTacToe toe = new TicTacToe(3); +TicTacToe toe = new TicTacToe(3) toe.move(0, 0, 1); -> Returns 0 (no one wins) |X| | | @@ -69,8 +69,8 @@ public DesignTicTacToe(int n) { 2: Player 2 wins. */ public int move(int row, int col, int player) { int toAdd = player == 1 ? 1 : -1; - // if A player makes a move on 0,0 we are going to increment index posistion of row and col at 0,0 - // if B player makes a move on 0,2 we are going to decrement index posistion at row and col at 0,2 + // if A player makes a move on 0,0 we are going to increment index position of row and col at 0,0 + // if B player makes a move on 0,2 we are going to decrement index position at row and col at 0,2 // after that the count of row at 0 will be 0(balanced moves) like wise if a row or col has value n only // a player can be adjudged a winner rows[row] += toAdd; diff --git a/src/main/java/practiceproblems/design/GetRandomWithDuplicates.java b/src/main/java/practiceproblems/design/GetRandomWithDuplicates.java new file mode 100644 index 0000000..3386abb --- /dev/null +++ b/src/main/java/practiceproblems/design/GetRandomWithDuplicates.java @@ -0,0 +1,70 @@ +package practiceproblems.design; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Set; + +/** + * https://leetcode.com/problems/insert-delete-getrandom-o1-duplicates-allowed/ + * + * tricky + */ +public class GetRandomWithDuplicates { + + ArrayList randomList; + HashMap> cache; + java.util.Random rand = new java.util.Random(); + + /** + * Initialize your data structure here. + */ + + public GetRandomWithDuplicates() { + randomList = new ArrayList<>(); + cache = new HashMap<>(); + } + + /** + * Inserts a value to the collection. Returns true if the collection did not already contain the specified element. + */ + public boolean insert(int val) { + cache.putIfAbsent(val,new LinkedHashSet<>()); + cache.get(val).add(randomList.size()); + randomList.add(val); + return cache.get(val).size() == 1; + } + + /** + *This is the tricky part. We find the index of the element using the HashMap. + * We use the trick discussed in the intuition to remove the element from the list in O(1)O(1)O(1). + * Since the last element in the list gets moved around, we have to update its value in the HashMap. + * We also have to get rid of the index of the element we removed from the HashMap. + */ + public boolean remove(int val) { + if (!cache.containsKey(val) || cache.get(val).isEmpty()) return false; + int removeIndex = cache.get(val).iterator().next(); + + // remove from linkedHashSet + cache.get(val).remove(removeIndex); + + int lastVal = randomList.get(randomList.size() - 1); + + randomList.set(removeIndex, lastVal); + + cache.get(lastVal).add(removeIndex); + + cache.get(lastVal).remove(randomList.size() - 1); + + randomList.remove(randomList.size() - 1); + + return true; + } + + /** + * Get a random element from the collection. + */ + public int getRandom() { + return randomList.get(rand.nextInt(randomList.size())); + } +} diff --git a/src/main/java/practiceproblems/design/HitCounter.java b/src/main/java/practiceproblems/design/HitCounter.java new file mode 100644 index 0000000..680691f --- /dev/null +++ b/src/main/java/practiceproblems/design/HitCounter.java @@ -0,0 +1,38 @@ +package practiceproblems.design; + +import java.util.ArrayDeque; +import java.util.Deque; + +public class HitCounter { + Deque track; + /** + * Initialize your data structure here. + */ + private final int FIVE_MINUTES = 300; + + public HitCounter() { + track = new ArrayDeque<>(); + } + + /** + * Record a hit. + * + * @param timestamp - The current timestamp (in seconds granularity). + */ + public void hit(int timestamp) { + track.addLast(timestamp); + } + + /** + * Return the number of hits in the past 5 minutes. + * + * @param timestamp - The current timestamp (in seconds granularity). + */ + public int getHits(int timestamp) { + while (!track.isEmpty() && track.peekFirst() + FIVE_MINUTES <= timestamp) { + track.removeFirst(); + } + return track.size(); + } + +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/design/LFUCache.java b/src/main/java/practiceproblems/design/LFUCache.java new file mode 100644 index 0000000..7c30cfd --- /dev/null +++ b/src/main/java/practiceproblems/design/LFUCache.java @@ -0,0 +1,181 @@ +package practiceproblems.design; + +import java.util.HashMap; +import java.util.Map; + +/** + * tricky + * revise + */ +public class LFUCache { + /* + * @param capacity: total capacity of LFU Cache + * @param curSize: current size of LFU cache + * @param minFrequency: frequency of the last linked list (the minimum frequency of entire LFU cache) + * @param cache: a hash map that has key to Node mapping, which used for storing all nodes by their keys + * @param frequencyMap: a hash map that has key to linked list mapping, which used for storing all + * double linked list by their frequencies + * */ + + + final int capacity; + int curSize; + int minFrequency; + Map cache; + Map frequencyMap; + + public LFUCache(int capacity) { + + this.capacity = capacity; + this.curSize = 0; + this.minFrequency = 0; + + this.cache = new HashMap<>(); + this.frequencyMap = new HashMap<>(); + } + + /** + * get node value by key, and then update node frequency as well as relocate that node + **/ + public int get(int key) { + DLLNode curNode = cache.get(key); + if (curNode == null) { + return -1; + } + updateNode(curNode); + return curNode.val; + } + + /** + * add new node into LFU cache, as well as double linked list + * condition 1: if LFU cache has input key, update node value and node position in list + * condition 2: if LFU cache does NOT have input key + * - sub condition 1: if LFU cache does NOT have enough space, remove the Least Recent Used node + * in minimum frequency list, then add new node + * - sub condition 2: if LFU cache has enough space, add new node directly + **/ + public void put(int key, int value) { + // corner case: check cache capacity initialization + if (capacity == 0) { + return; + } + + if (cache.containsKey(key)) { + DLLNode curNode = cache.get(key); + curNode.val = value; + updateNode(curNode); + } else { + curSize++; + if (curSize > capacity) { + // get minimum frequency list + DoubleLinkedList minFreqList = frequencyMap.get(minFrequency); + DLLNode deleteNode = minFreqList.removeTail(); + cache.remove(deleteNode.key); + curSize--; + } + // reset min frequency to 1 because of adding new node + minFrequency = 1; + DLLNode newNode = new DLLNode(key, value); + + // get the list with frequency 1, and then add new node into the list, as well as into LFU cache + frequencyMap.putIfAbsent(minFrequency, new DoubleLinkedList()); + frequencyMap.get(minFrequency).addNode(newNode); + cache.put(key, newNode); + } + } + + public void updateNode(DLLNode curNode) { + int curFreq = curNode.frequency; + DoubleLinkedList curList = frequencyMap.get(curFreq); + curList.removeNode(curNode); + + // if current list the last list which has lowest frequency and current node is the only node in that list + // we need to remove the entire list and then increase min frequency value by 1 + if (curFreq == minFrequency && curList.listSize == 0) { + minFrequency++; + } + + curNode.frequency++; + // add current node to another list has current frequency + 1, + // if we do not have the list with this frequency, initialize it + frequencyMap.putIfAbsent(curNode.frequency, new DoubleLinkedList()); + frequencyMap.get(curNode.frequency).addNode(curNode); + } + + /* + * @param key: node key + * @param val: node value + * @param frequency: frequency count of current node + * (all nodes connected in same double linked list has same frequency) + * @param prev: previous pointer of current node + * @param next: next pointer of current node + * */ + static class DLLNode { + int key; + int val; + int frequency; + DLLNode prev; + DLLNode next; + + public DLLNode(int key, int val) { + this.key = key; + this.val = val; + this.frequency = 1; + } + } + + /* + * @param listSize: current size of double linked list + * @param head: head node of double linked list + * @param tail: tail node of double linked list + * */ + static class DoubleLinkedList { + int listSize; + DLLNode head; + DLLNode tail; + + public DoubleLinkedList() { + this.listSize = 0; + this.head = new DLLNode(0, 0); + this.tail = new DLLNode(0, 0); + head.next = tail; + tail.prev = head; + } + + /** + * add new node into head of list and increase list size by 1 + **/ + public void addNode(DLLNode curNode) { + DLLNode nextNode = head.next; + curNode.next = nextNode; + curNode.prev = head; + head.next = curNode; + nextNode.prev = curNode; + listSize++; + } + + /** + * remove input node and decrease list size by 1 + **/ + public void removeNode(DLLNode curNode) { + DLLNode prevNode = curNode.prev; + DLLNode nextNode = curNode.next; + prevNode.next = nextNode; + nextNode.prev = prevNode; + listSize--; + } + + /** + * remove tail node + **/ + public DLLNode removeTail() { + // DO NOT FORGET to check list size + if (listSize > 0) { + DLLNode tailNode = tail.prev; + removeNode(tailNode); + return tailNode; + } + return null; + } + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/design/LRUCache.java b/src/main/java/practiceproblems/design/LRUCache.java new file mode 100644 index 0000000..ca3207f --- /dev/null +++ b/src/main/java/practiceproblems/design/LRUCache.java @@ -0,0 +1,112 @@ +package practiceproblems.design; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +class LRUCache { + + static class DLLNode { + DLLNode prev; + DLLNode next; + int val; + int key; + + public DLLNode(int key, int val) { + this.val = val; + this.key = key; + } + } + + Map map; + DLLNode head; + DLLNode tail; + int capacity = 0; + + public LRUCache(int capacity) { + map = new HashMap<>(); + head = new DLLNode(-1, -1); + tail = new DLLNode(-1, -1); + head.next = tail; + tail.prev = head; + this.capacity = capacity; + } + + public int get(int key) { + if (!map.containsKey(key)) return -1; + DLLNode node = map.get(key); + update(node); + return node.val; + } + + public void put(int key, int value) { + if (map.containsKey(key)) { + DLLNode node = map.get(key); + node.val = value; + update(node); + } else { + if (map.size() >= capacity) { + removeTail(); + } + DLLNode newNode = new DLLNode(key, value); + map.put(key, newNode); + + updateHead(newNode); + } + } + + public void removeTail() { + DLLNode tailNode = tail.prev; + remove(tailNode); + map.remove(tailNode.key); + } + + public void updateHead(DLLNode node) { + node.prev = head; + node.next = head.next; + head.next.prev = node; + head.next = node; + } + + public void remove(DLLNode node) { + DLLNode next = node.next; + DLLNode prev = node.prev; + prev.next = next; + next.prev = prev; + } + + public void update(DLLNode node) { + remove(node); + updateHead(node); + } +} + + +class LRUCache1 { + LinkedHashMap cache; + int capacity = 0; + + public LRUCache1(int capacity) { + cache = new LinkedHashMap<>(capacity, 0.50F, true) { + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > capacity; + } + }; + this.capacity = capacity; + } + + public int get(int key) { + return cache.getOrDefault(key, -1); + } + + public void put(int key, int value) { + cache.put(key, value); + } + +} +/** + * Your LRUCache object will be instantiated and called as such: + * LRUCache obj = new LRUCache(capacity); + * int param_1 = obj.get(key); + * obj.put(key,value); + */ \ No newline at end of file diff --git a/src/main/java/practiceproblems/design/LeaderBoard.java b/src/main/java/practiceproblems/design/LeaderBoard.java new file mode 100644 index 0000000..7794399 --- /dev/null +++ b/src/main/java/practiceproblems/design/LeaderBoard.java @@ -0,0 +1,66 @@ +package practiceproblems.design; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeSet; + +/** + * https://leetcode.com/problems/design-a-leaderboard/ + */ +public class LeaderBoard { + Map players = new HashMap<>(); + TreeSet scores = new TreeSet<>((a, b) -> b.score - a.score == 0 ? a.id - b.id : b.score - a.score); + + //Log(N) + + /** + * addScore(playerId, score): Update the leaderboard by adding score to the given player's score. + * If there is no player with such id in the leaderboard, add him to the leaderboard with the given score. + */ + public void addScore(int playerId, int score) { + Player cur; + if (players.containsKey(playerId)) { + cur = players.get(playerId); + scores.remove(cur); + cur.score += score; + scores.add(cur); + } else { + cur = new Player(playerId, score); + players.put(playerId, cur); + scores.add(cur); + } + } + + /** + * Return the score sum of the top K players. + */ + public int top(int K) { + Iterator iterator = scores.iterator(); + int res = 0; + while (K-- > 0 && iterator.hasNext()) { + res += iterator.next().score; + } + return res; + } + + /** + * Reset the score of the player with the given id to 0 (in other words erase it from the leaderboard). + * It is guaranteed that the player was added to the leaderboard before calling this function. + */ + public void reset(int playerId) { + Player cur = players.get(playerId); + scores.remove(cur); + cur.score = 0; + } + + class Player { + int id; + int score; + + public Player(int id, int score) { + this.id = id; + this.score = score; + } + } +} diff --git a/src/main/java/practiceproblems/design/LogSystem.java b/src/main/java/practiceproblems/design/LogSystem.java new file mode 100644 index 0000000..8f0919a --- /dev/null +++ b/src/main/java/practiceproblems/design/LogSystem.java @@ -0,0 +1,62 @@ +package practiceproblems.design; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * https://leetcode.com/problems/design-log-storage-system/ + * tricky + */ +public class LogSystem { + + private final String MIN_TIMESTAMP = "2000:01:01:00:00:00"; + private final String MAX_TIMESTAMP = "2017:12:31:23:59:59"; + + HashMap indices; + TreeMap> logStorage; + + public LogSystem() { + indices = new HashMap<>(); + indices.put("Year", 4); + indices.put("Month", 7); + indices.put("Day", 10); + indices.put("Hour", 13); + indices.put("Minute", 16); + indices.put("Second", 19); + + logStorage = new TreeMap<>(); + } + + /** + * Stores the given log (id, timestamp) in your storage system. + */ + public void put(int id, String timestamp) { + logStorage.putIfAbsent(timestamp, new ArrayList<>()); + logStorage.get(timestamp).add(id); + } + + /** + * Returns the IDs of the logs whose timestamps are within the range from start to end inclusive. + * start and end all have the same format as timestamp, and granularity means how precise the range should be (i.e. to the exact Day, Minute, etc.). + * For example, start = "2017:01:01:23:59:59", end = "2017:01:02:23:59:59", and granularity = "Day" + * means that we need to find the logs within the inclusive range from Jan. 1st 2017 to Jan. 2nd 2017, + * and the Hour, Minute, and Second for each log entry can be ignored. + */ + public List retrieve(String start, String end, String granularity) { + + int index = indices.get(granularity); + + String startTime = start.substring(0, index) + MIN_TIMESTAMP.substring(index); + String endTime = end.substring(0, index) + MAX_TIMESTAMP.substring(index); + + List result = new ArrayList<>(); + + for (Map.Entry> entry : logStorage.subMap(startTime, true, endTime, true).entrySet()) { + result.addAll(entry.getValue()); + } + return result; + } +} diff --git a/src/practiceproblems/MaxFreqStack.java b/src/main/java/practiceproblems/design/MaxFreqStack.java similarity index 61% rename from src/practiceproblems/MaxFreqStack.java rename to src/main/java/practiceproblems/design/MaxFreqStack.java index fe087e2..3411dbb 100644 --- a/src/practiceproblems/MaxFreqStack.java +++ b/src/main/java/practiceproblems/design/MaxFreqStack.java @@ -1,6 +1,7 @@ -package practiceproblems; +package practiceproblems.design; import java.util.HashMap; +import java.util.LinkedList; import java.util.Map; import java.util.PriorityQueue; @@ -57,6 +58,7 @@ public int pop() { return temp.val; } + } // 1. val = value of the number @@ -73,3 +75,57 @@ public EntryStack(int val, int frequency, int sequence) { this.sequence = sequence; } } + +/** + * tricky + */ +class FreqStack { + + HashMap> st ; // stores max freq as key and stack consist of all element that has freq equals to key. + + HashMap freqMap; // frequency map + int maxFreq; // will contain the max frequency of element. + + public FreqStack() { + st = new HashMap<>() ; + freqMap = new HashMap<>(); + maxFreq = 0 ; + } + + public void push(int val) { + + freqMap.put(val, freqMap.getOrDefault(val,0)+1) ; // incrementing the freq of current val + + int freq= freqMap.get(val) ; + + st.getOrDefault(freq, new LinkedList<>()).addFirst(val) ; // adding on top. + + maxFreq = Math.max(maxFreq, freqMap.get(val)) ; // updating the max frequency + } + + public int pop() { + + // getting the max freq element. + + int val = st.get(maxFreq).removeFirst() ; + + if(st.get(maxFreq).isEmpty()){ + // means stack becomes empty that means we don't have any more element of maxFreq so decrease the maxFreq. + maxFreq-- ; + } + + // also decrement the freq of val in fmap. + + int freq = freqMap.get(val) ; + + if(freq == 1){ + freqMap.remove(val) ; + } + else{ + freqMap.put(val,freq-1) ; + } + + return val ; + + } +} diff --git a/src/main/java/practiceproblems/design/MaxStack.java b/src/main/java/practiceproblems/design/MaxStack.java new file mode 100644 index 0000000..8f7dde9 --- /dev/null +++ b/src/main/java/practiceproblems/design/MaxStack.java @@ -0,0 +1,58 @@ +package practiceproblems.design; + +import java.util.ArrayDeque; +import java.util.Deque; + +public class MaxStack { + Deque stack; + Deque maxStack; + + public MaxStack() { + stack = new ArrayDeque<>(); + maxStack = new ArrayDeque<>(); + } + + public void push(int x) { + int max = maxStack.isEmpty() ? x : maxStack.peek(); + maxStack.push(Math.max(max, x)); + stack.push(x); + } + + public int pop() { + maxStack.pop(); + return stack.pop(); + } + + public int top() { + return stack.peek(); + } + + public int peekMax() { + return maxStack.peek(); + } + + public int popMax() { + int max = peekMax(); + Deque buffer = new ArrayDeque<>(); + while (top() != max) buffer.push(pop()); + pop(); + while (!buffer.isEmpty()) push(buffer.pop()); + return max; + } + + public static void main(String[] args) { + MaxStack stack = new MaxStack(); + stack.push(3); + stack.push(7); + System.out.println(stack.peekMax()); + stack.push(2); + System.out.println(stack.popMax()); + stack.push(4); + System.out.println(stack.top()); + stack.push(6); + System.out.println(stack.popMax()); + stack.push(9); + System.out.println(stack.peekMax()); + + } +} diff --git a/src/main/java/practiceproblems/design/MinimumStack.java b/src/main/java/practiceproblems/design/MinimumStack.java new file mode 100644 index 0000000..6d71616 --- /dev/null +++ b/src/main/java/practiceproblems/design/MinimumStack.java @@ -0,0 +1,43 @@ +package practiceproblems.design; + + +public class MinimumStack { + + private Node head; + + public void push(int x) { + if (head == null) { + head = new Node(x, x); + } else { + head = new Node(x, Math.min(x, head.min), head); + } + } + + public void pop() { + head = head.next; + } + + public int top() { + return head.val; + } + + public int getMin() { + return head.min; + } + + private class Node { + int val; + int min; + Node next; + + private Node(int val, int min) { + this(val, min, null); + } + + private Node(int val, int min, Node next) { + this.val = val; + this.min = min; + this.next = next; + } + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/design/MyCircularQueue.java b/src/main/java/practiceproblems/design/MyCircularQueue.java new file mode 100644 index 0000000..19a22f5 --- /dev/null +++ b/src/main/java/practiceproblems/design/MyCircularQueue.java @@ -0,0 +1,58 @@ +package practiceproblems.design; + +public class MyCircularQueue { + + int[] arr; + int headIndex = 0; + + int length; + int count; + + public MyCircularQueue(int k) { + + this.arr = new int[k]; + this.length = k; + this.count = 0; + } + + public boolean enQueue(int value) { + if (count == length) return false; + + int index = (headIndex + count) % length; + arr[index] = value; + + count++; + return true; + } + + public boolean deQueue() { + if (count == 0) return false; + + headIndex = (headIndex + 1) % length; + count -= 1; + return true; + } + + public int Front() { + if (count == 0) return -1; + return arr[headIndex]; + } + + public int Rear() { + if (count == 0) return -1; + + int tailIndex = (headIndex + count - 1) % length; + return arr[tailIndex]; + + } + + public boolean isEmpty() { + return count <= 0; + } + + public boolean isFull() { + return count == length; + } + + +} \ No newline at end of file diff --git a/src/practiceproblems/OwnDataStructureUtil.java b/src/main/java/practiceproblems/design/OwnDataStructureUtil.java similarity index 92% rename from src/practiceproblems/OwnDataStructureUtil.java rename to src/main/java/practiceproblems/design/OwnDataStructureUtil.java index e0ace52..d5efef1 100644 --- a/src/practiceproblems/OwnDataStructureUtil.java +++ b/src/main/java/practiceproblems/design/OwnDataStructureUtil.java @@ -1,6 +1,8 @@ -package practiceproblems; +package practiceproblems.design; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Random; /** * https://leetcode.com/problems/insert-delete-getrandom-o1/ diff --git a/src/main/java/practiceproblems/design/RangeModule.java b/src/main/java/practiceproblems/design/RangeModule.java new file mode 100644 index 0000000..42da0f7 --- /dev/null +++ b/src/main/java/practiceproblems/design/RangeModule.java @@ -0,0 +1,65 @@ +package practiceproblems.design; + +import java.util.Iterator; +import java.util.TreeSet; + +/** + * tricky tree set + * https://leetcode.com/problems/range-module/ + */ +public class RangeModule { + TreeSet ts; + + public RangeModule() { + this.ts = new TreeSet<>((a, b) -> a[1] - b[1]); + } + + public void addRange(int left, int right) { + Iterator iter = ts.tailSet(new int[]{0, left}, true).iterator(); + while (iter.hasNext()) { + int[] temp = iter.next(); + if (temp[0] > right) break; + + left = Math.min(left, temp[0]); + right = Math.max(right, temp[1]); + iter.remove(); + } + + ts.add(new int[]{left, right}); + } + + public boolean queryRange(int left, int right) { + int[] ceiling = ts.ceiling(new int[]{0, right}); + return ceiling != null && ceiling[0] <= left; + } + + public void removeRange(int left, int right) { + Iterator iter = ts.tailSet(new int[]{0, left}, false).iterator(); + + int[] front = null; + int[] back = null; + + while (iter.hasNext()) { + int[] temp = iter.next(); + if (temp[0] >= right) break; + + if (temp[0] < left) front = new int[]{temp[0], left}; + if (right < temp[1]) back = new int[]{right, temp[1]}; + iter.remove(); + } + + if (front != null) ts.add(front); + if (back != null) ts.add(back); + } + + public static void main(String[] args) { + RangeModule rm = new RangeModule(); + rm.addRange(10, 20); + rm.addRange(11, 25); + rm.removeRange(9, 16); + rm.queryRange(10, 14); + rm.queryRange(13, 15); + rm.queryRange(16, 17); + + } +} diff --git a/src/main/java/practiceproblems/design/ShortestWordDistance.java b/src/main/java/practiceproblems/design/ShortestWordDistance.java new file mode 100644 index 0000000..cb4c3db --- /dev/null +++ b/src/main/java/practiceproblems/design/ShortestWordDistance.java @@ -0,0 +1,83 @@ +package practiceproblems.design; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * https://leetcode.com/problems/shortest-word-distance-ii + */ +public class ShortestWordDistance { + + HashMap> locations; + + public ShortestWordDistance(String[] words) { + this.locations = new HashMap<>(); + + // Prepare a mapping from a word to all it's locations (indices). + for (int i = 0; i < words.length; i++) { + ArrayList loc = this.locations.getOrDefault(words[i], new ArrayList<>()); + loc.add(i); + this.locations.put(words[i], loc); + } + } + + public int shortest(String word1, String word2) { + ArrayList loc1, loc2; + + // Location lists for both the words + // the indices will be in SORTED order by default + loc1 = this.locations.get(word1); + loc2 = this.locations.get(word2); + + int l1 = 0, l2 = 0, minDiff = Integer.MAX_VALUE; + while (l1 < loc1.size() && l2 < loc2.size()) { + minDiff = Math.min(minDiff, Math.abs(loc1.get(l1) - loc2.get(l2))); + if (loc1.get(l1) < loc2.get(l2)) { + l1++; + } else { + l2++; + } + } + + return minDiff; + } + + /** + * https://leetcode.com/problems/shortest-word-distance-iii + */ + public int shortestWordDistance(String[] words, String word1, String word2) { + int min = Integer.MAX_VALUE; + int p1 = -1; + int p2 = -1; + boolean same = word1.equals(word2); + for (int i = 0; i < words.length; i++) { + if (words[i].equals(word1)) { + if (same) { + p2 = p1; // Deal with another pointer too + } + p1 = i; + } else if (words[i].equals(word2)) { + p2 = i; + } + + if (p1 != -1 && p2 != -1) { + min = Math.min(min, Math.abs(p1 - p2)); + } + } + return min; + } + + public int shortestDistance(String[] words, String word1, String word2) { + int ret = Integer.MAX_VALUE, index1 = -1, index2 = -1; + for (int i = 0; i < words.length; i++) { + if (words[i].equals(word1)) { + index1 = i; + if (index2 >= 0) ret = Math.min(ret, i - index2); + } else if (words[i].equals(word2)) { + index2 = i; + if (index1 >= 0) ret = Math.min(ret, i - index1); + } + } + return ret; + } +} diff --git a/src/main/java/practiceproblems/design/SnakeGame.java b/src/main/java/practiceproblems/design/SnakeGame.java new file mode 100644 index 0000000..90a1b10 --- /dev/null +++ b/src/main/java/practiceproblems/design/SnakeGame.java @@ -0,0 +1,87 @@ +package practiceproblems.design; + +import java.util.LinkedList; + +/** + * tricky Linkedlist + */ +public class SnakeGame { + + // used to verify boundary conditions + int width; + int height; + + // food position + int[][] food; + int score; + + // body of snake + LinkedList snake; + + public SnakeGame(int width, int height, int[][] food) { + this.width = width; + this.height = height; + this.food = food; + + snake = new LinkedList<>(); + snake.add(new Node(0, 0)); + } + + + public int move(String direction) { + Node head = snake.peekFirst(); + Node nxt = new Node(head.x, head.y); + + switch (direction) { + case "U": + nxt.x--; + break; + case "D": + nxt.x++; + break; + case "L": + nxt.y--; + break; + case "R": + nxt.y++; + } + + // boundary check + if (nxt.x < 0 || nxt.x >= height || nxt.y < 0 || nxt.y >= width) + return -1; + + // body check -> check size()-1 as the last node will be cleared(when snake moves) if moved to next block + for (int i = 0; i < snake.size() - 1; i++) { + if (nxt.isEqual(snake.get(i))) { + return -1; + } + } + + // is food? Eat! + if (score < food.length && nxt.x == food[score][0] && nxt.y == food[score][1]) { + score++; + snake.addFirst(nxt); + } else { + snake.addFirst(nxt); + snake.removeLast(); + } + + return score; + } + + + static class Node { + int x; + int y; + + Node(int x, int y) { + this.x = x; + this.y = y; + } + + public boolean isEqual(Node node) { + return this.x == node.x && this.y == node.y; + } + } + +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/design/SnapShotUtil.java b/src/main/java/practiceproblems/design/SnapShotUtil.java new file mode 100644 index 0000000..0b45c37 --- /dev/null +++ b/src/main/java/practiceproblems/design/SnapShotUtil.java @@ -0,0 +1,72 @@ +package practiceproblems.design; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.TreeMap; +import java.util.stream.IntStream; + +/** + * https://leetcode.com/problems/snapshot-array/ + */ +class SnapShotUtil { + + int[] arr; + List snapShot; + int maxIndex = 0; + + /** + * initializes an array-like data structure with the given length. Initially, each element equals 0. + */ + public SnapShotUtil(int length) { + arr = new int[length]; + snapShot = new ArrayList<>(); + } + + /** + * sets the element at the given index to be equal to val. + */ + public void set(int index, int val) { + arr[index] = val; + maxIndex = Math.max(index, maxIndex); + } + + /** + * takes a snapshot of the array and returns the snap_id: the total number of times we called snap() minus 1. + */ + public int snap() { + snapShot.add(Arrays.copyOfRange(arr, 0, maxIndex + 1)); + return snapShot.size() - 1; + } + + /** + * returns the value at the given index, at the time we took the snapshot with the given snap_id + */ + public int get(int index, int snap_id) { + int[] arr = snapShot.get(snap_id); + if (index >= arr.length) return 0; + return arr[index]; + } + + + private int count; + private List> shot = new ArrayList<>(); + + public SnapShotUtil(int length, int k) { + IntStream.range(0, length).forEach(i -> shot.add(new TreeMap<>())); + } + + public void setOptimised(int index, int val) { + shot.get(index).put(count, val); + } + + public int snapOptimised() { + return count++; + } + + public int getOptimised(int index, int snap_id) { + Integer key = shot.get(index).floorKey(snap_id); + return key == null ? 0 : shot.get(index).get(key); + } +} + diff --git a/src/main/java/practiceproblems/design/StockPrice.java b/src/main/java/practiceproblems/design/StockPrice.java new file mode 100644 index 0000000..71bd65d --- /dev/null +++ b/src/main/java/practiceproblems/design/StockPrice.java @@ -0,0 +1,77 @@ +package practiceproblems.design; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * https://leetcode.com/problems/stock-price-fluctuation/ + */ +public class StockPrice { + static class Node { + public int timestamp; + public int price; + + public Node(int timestamp, int price) { + this.timestamp = timestamp; + this.price = price; + } + } + + Map timeToPrice = new HashMap<>(); + + PriorityQueue maxHeap = new PriorityQueue<>((a, b) -> Integer.compare(b.price, a.price)); + + PriorityQueue minHeap = new PriorityQueue<>(Comparator.comparingInt(a -> a.price)); + + Node latest = null; + + public StockPrice() { + + } + + /** + * Updates the price of the stock at the given timestamp. + */ + public void update(int timestamp, int price) { + Node newNode = new Node(timestamp, price); + timeToPrice.put(timestamp, newNode); + maxHeap.add(newNode); + minHeap.add(newNode); + if (latest == null || timestamp >= latest.timestamp) { + latest = newNode; + } + } + + /** + * Returns the latest price of the stock. + */ + public int current() { + return latest.price; + } + + /** + * Returns the maximum price of the stock. + */ + public int maximum() { + if (maxHeap.isEmpty()) return -1; + + while (maxHeap.peek().price != timeToPrice.get(maxHeap.peek().timestamp).price) { + maxHeap.remove(); + } + return maxHeap.isEmpty() ? -1 : maxHeap.peek().price; + } + + /** + * Returns the minimum price of the stock. + */ + public int minimum() { + if (minHeap.isEmpty()) return -1; + + while (minHeap.peek().price != timeToPrice.get(minHeap.peek().timestamp).price) { + minHeap.remove(); + } + return minHeap.isEmpty() ? -1 : minHeap.peek().price; + } +} diff --git a/src/main/java/practiceproblems/design/SubRectangleQueries.java b/src/main/java/practiceproblems/design/SubRectangleQueries.java new file mode 100644 index 0000000..252f198 --- /dev/null +++ b/src/main/java/practiceproblems/design/SubRectangleQueries.java @@ -0,0 +1,37 @@ +package practiceproblems.design; + +import java.util.ArrayList; +import java.util.List; + +/** + * https://leetcode.com/problems/subrectangle-queries/ + */ +public class SubRectangleQueries { + + + private int[][] rec = null; + private List list = null; + + public SubRectangleQueries(int[][] rectangle) { + rec = rectangle; + list = new ArrayList<>(); + + } + + public void updateSubrectangle(int row1, int col1, int row2, int col2, int newValue) { + int[] arr = new int[]{row1, col1, row2, col2, newValue}; + list.add(arr); + } + + public int getValue(int row, int col) { + int result = rec[row][col]; + + for (int[] arr : list) { + if (row >= arr[0] && row <= arr[2] && col <= arr[3] && col >= arr[1]) { + result = arr[4]; + } + } + + return result; + } +} diff --git a/src/main/java/practiceproblems/design/SummaryRanges.java b/src/main/java/practiceproblems/design/SummaryRanges.java new file mode 100644 index 0000000..c642139 --- /dev/null +++ b/src/main/java/practiceproblems/design/SummaryRanges.java @@ -0,0 +1,88 @@ +package practiceproblems.design; + +import java.util.TreeMap; + +/** + * https://leetcode.com/problems/data-stream-as-disjoint-intervals + * + * // When do we merge the number to an existing interval? + * // 1. If it's within 1 interval(No merge operation needed in this case) + * // 2. If it's 1 less than left bound or 1 larger than right bound of 1 interval + */ +public class SummaryRanges { + TreeMap sortedMap; + + /** + * Initialize your data structure here. + */ + public SummaryRanges() { + sortedMap = new TreeMap<>(); + } + + public void addNum(int val) { + if (sortedMap.containsKey(val)) return; + + Integer floor = sortedMap.lowerKey(val); + Integer ceiling = sortedMap.higherKey(val); + + /* + When both ceiling and floor are there + for example 1,1 and 3,3 are there and val=2 comes + sortedMap.get(floor).end + 1 == val => 1+1 == 2 + ceiling - 1 == val => 3-1 ==2 + in this case remove 3 and update 1,1's end as 1,3 + */ + if (floor != null && ceiling != null && sortedMap.get(floor).end + 1 == val && ceiling - 1 == val) { + + sortedMap.get(floor).end = sortedMap.get(ceiling).end; + sortedMap.remove(ceiling); + + } else if (floor != null && val <= sortedMap.get(floor).end + 1) { + + /* + * When ceiling is null or ceiling - 1 != val + * for ex 1 => [1,4] and val = 5 comes + * or + * 1 => [1,6] and val = 5 comes + */ + sortedMap.get(floor).end = Math.max(sortedMap.get(floor).end, val); + + } else if (ceiling != null && ceiling - 1 == val) { + + /* + * when [7,7] is there in the map and val=6 comes + * ceiling =7 and val =6 + * update the val inside the map and remove the ceiling + */ + sortedMap.put(val, new Interval(val, sortedMap.get(ceiling).end)); + sortedMap.remove(ceiling); + + } else { + /* + When both ceiling and floor are not there + */ + sortedMap.put(val, new Interval(val, val)); + } + } + + public int[][] getIntervals() { + int[][] result = new int[sortedMap.size()][2]; + int i = 0; + for (Integer key : sortedMap.keySet()) { + result[i] = new int[]{sortedMap.get(key).start, sortedMap.get(key).end}; + i++; + } + + return result; + } + + private static class Interval { + int start; + int end; + + public Interval(int start, int end) { + this.start = start; + this.end = end; + } + } +} diff --git a/src/practiceproblems/TimeMap.java b/src/main/java/practiceproblems/design/TimeMap.java similarity index 67% rename from src/practiceproblems/TimeMap.java rename to src/main/java/practiceproblems/design/TimeMap.java index a9dc333..685ffb2 100644 --- a/src/practiceproblems/TimeMap.java +++ b/src/main/java/practiceproblems/design/TimeMap.java @@ -1,20 +1,23 @@ -package practiceproblems; +package practiceproblems.design; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * Create a time based key-value store class TimeMap, that supports two operations. - * + *

* 1. set(string key, string value, int timestamp) - * + *

* Stores the key and value, along with the given timestamp. * 2. get(string key, int timestamp) - * + *

* Returns a value such that set(key, value, timestamp_prev) was called previously, * with timestamp_prev <= timestamp. * If there are multiple such values, it returns the one with the largest timestamp_prev. * If there are no values, it returns the empty string (""). - * + *

* Input: inputs = ["TimeMap","set","get","get","set","get","get"], inputs = [[],["foo","bar",1],["foo",1],["foo",3],["foo","bar2",4],["foo",4],["foo",5]] * Output: [null,null,"bar","bar",null,"bar2","bar2"] * Explanation: @@ -29,39 +32,32 @@ class TimeMap { - class Node{ + class Value { String val; int time; - Node next; - public Node(String value, int timestamp){ - val=value; - time=timestamp; + + public Value(String val, int time) { + this.val = val; + this.time = time; } } - /** Initialize your data structure here. */ - HashMap map; - + + Map> map; + public TimeMap() { - map=new HashMap<>(); + map = new HashMap<>(); } - + public void set(String key, String value, int timestamp) { - Node node =new Node(value,timestamp); - if(map.containsKey(key)){ - node.next=map.get(key); - } - map.put(key,node); + map.computeIfAbsent(key, x->new ArrayList<>()).add(new Value(value, timestamp)); } - + public String get(String key, int timestamp) { - String vl=""; - if(map.containsKey(key)){ - Node y=map.get(key); - while(y.time>timestamp&&y.next!=null) - y=y.next; - if(y.time<=timestamp) - vl=y.val; + if (!map.containsKey(key)) return ""; + List values = map.get(key); + for (int i = values.size() - 1; i >= 0; i--) { + if (timestamp >= values.get(i).time) return values.get(i).val; } - return vl; + return ""; } } \ No newline at end of file diff --git a/src/main/java/practiceproblems/design/TweetCounts.java b/src/main/java/practiceproblems/design/TweetCounts.java new file mode 100644 index 0000000..ac10ae9 --- /dev/null +++ b/src/main/java/practiceproblems/design/TweetCounts.java @@ -0,0 +1,60 @@ +package practiceproblems.design; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * https://leetcode.com/problems/tweet-counts-per-frequency/ + * + * tricky tree map + */ +class TweetCounts { + private Map> tweetsCache; + + public TweetCounts() { + tweetsCache = new HashMap<>(); + } + + public void recordTweet(String tweetName, int time) { + + tweetsCache.putIfAbsent(tweetName, new TreeMap<>()); + + TreeMap timeToFreq = tweetsCache.get(tweetName); + timeToFreq.put(time, timeToFreq.getOrDefault(time, 0) + 1); + + } + + public List getTweetCountsPerFrequency(String freq, String tweetName, int startTime, int endTime) { + int interval = 1; + if (!tweetsCache.containsKey(tweetName)) { + return Collections.emptyList(); + } + if (freq.equals("minute")) { + interval = 60; + } + if (freq.equals("hour")) { + interval = 3600; + } + if (freq.equals("day")) { + interval = 86400; + } + + int size = ((endTime - startTime) / interval) + 1; + int[] cur = new int[size]; + TreeMap temp = tweetsCache.get(tweetName); + for (Map.Entry entry : temp.subMap(startTime, endTime + 1).entrySet()) { + int pos = (entry.getKey() - startTime) / interval; + cur[pos] += entry.getValue(); + } + List res = new ArrayList<>(); + for (int num : cur) { + res.add(num); + } + + return res; + } +} diff --git a/src/practiceproblems/Twitter.java b/src/main/java/practiceproblems/design/Twitter.java similarity index 70% rename from src/practiceproblems/Twitter.java rename to src/main/java/practiceproblems/design/Twitter.java index 3ae5180..4dcff5d 100644 --- a/src/practiceproblems/Twitter.java +++ b/src/main/java/practiceproblems/design/Twitter.java @@ -1,12 +1,14 @@ -package practiceproblems; +package practiceproblems.design; import java.util.*; -/*https://leetcode.com/problems/design-twitter/discuss/82825/Java-OO-Design-with-most-efficient-function-getNewsFeed*/ +/** + * https://leetcode.com/problems/design-twitter/discuss/82825/Java-OO-Design-with-most-efficient-function-getNewsFeed + * + **/ public class Twitter { private static int timeStamp = 0; - - private Map userMap; + private Map userMap; // Tweet link to next Tweet so that we can save a lot of time // when we execute getNewsFeed(userId) @@ -24,29 +26,29 @@ public Tweet(int id) { public class User { public int id; - public Set followed; - public Tweet tweet_head; + public Set followers; + public Tweet tweetHead; public User(int id) { this.id = id; - followed = new HashSet<>(); + followers = new HashSet<>(); follow(id); // first follow yourself - tweet_head = null; + tweetHead = null; } public void follow(int id) { - followed.add(id); + followers.add(id); } public void unfollow(int id) { - followed.remove(id); + followers.remove(id); } // everytime user post a new tweet, add it to the head of tweet list. public void post(int id) { Tweet t = new Tweet(id); - t.next = tweet_head; - tweet_head = t; + t.next = tweetHead; + tweetHead = t; } } @@ -61,18 +63,13 @@ public Twitter() { * Compose a new tweet. */ public void postTweet(int userId, int tweetId) { - if (!userMap.containsKey(userId)) { - User u = new User(userId); - userMap.put(userId, u); - } - userMap.get(userId).post(tweetId); - + userMap.computeIfAbsent(userId, x -> new User(userId)).post(tweetId); } // Best part of this. // first get all tweets lists from one user including itself and all people it followed. // Second add all heads into a max heap. Every time we poll a tweet with - // largest time stamp from the heap, then we add its next tweet into the heap. + // the largest time stamp from the heap, then we add its next tweet into the heap. // So after adding all heads we only need to add 9 tweets at most into this // heap before we get the 10 most recent tweet. public List getNewsFeed(int userId) { @@ -82,20 +79,19 @@ public List getNewsFeed(int userId) { return result; } - Set users = userMap.get(userId).followed; + Set users = userMap.get(userId).followers; PriorityQueue q = new PriorityQueue<>(users.size(), (a, b) -> (b.time - a.time)); for (int user : users) { - Tweet t = userMap.get(user).tweet_head; + Tweet t = userMap.get(user).tweetHead; // very important! If we add null to the head we are screwed. if (t != null) { q.add(t); } } - int n = 0; - while (!q.isEmpty() && n < 10) { + + while (!q.isEmpty() && result.size()<10) { Tweet t = q.poll(); result.add(t.id); - n++; if (t.next != null) { q.add(t.next); } @@ -109,14 +105,8 @@ public List getNewsFeed(int userId) { * Follower follows a followee. If the operation is invalid, it should be a no-op. */ public void follow(int followerId, int followeeId) { - if (!userMap.containsKey(followerId)) { - User u = new User(followerId); - userMap.put(followerId, u); - } - if (!userMap.containsKey(followeeId)) { - User u = new User(followeeId); - userMap.put(followeeId, u); - } + userMap.computeIfAbsent(followerId, x -> new User(followerId)); + userMap.computeIfAbsent(followeeId, x -> new User(followeeId)); userMap.get(followerId).follow(followeeId); } diff --git a/src/main/java/practiceproblems/design/TwoSum.java b/src/main/java/practiceproblems/design/TwoSum.java new file mode 100644 index 0000000..dd02370 --- /dev/null +++ b/src/main/java/practiceproblems/design/TwoSum.java @@ -0,0 +1,56 @@ +package practiceproblems.design; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class TwoSum { + + // all numbers + private List list = new ArrayList<>(); + + // every number's occurrence + private Map map = new HashMap<>(); + + // record max and minimum value + int max, min; + + /** + * Initialize your data structure here. + */ + public TwoSum() { + } + + /** + * Add the number to an internal data structure.. + */ + public void add(int number) { + list.add(number); + + min = Math.min(number, min); + max = Math.max(number, max); + + map.put(number, map.getOrDefault(number, 0) + 1); + } + + /** + * Find if there exists any pair of numbers which sum is equal to the value. + */ + public boolean find(int value) { + if (value < 2 * min || value > 2 * max) { + return false; + } + + for (int num : list) { + int num2 = value - num; + + if ((num == num2 && map.getOrDefault(num, 0) > 1) || + (num != num2 && map.containsKey(num2))) { + return true; + } + } + + return false; + } +} diff --git a/src/main/java/practiceproblems/design/UndergroundSystem.java b/src/main/java/practiceproblems/design/UndergroundSystem.java new file mode 100644 index 0000000..27586d7 --- /dev/null +++ b/src/main/java/practiceproblems/design/UndergroundSystem.java @@ -0,0 +1,91 @@ +package practiceproblems.design; + +import java.util.HashMap; +import java.util.Map; + +/** + * https://leetcode.com/problems/design-underground-system/ + * + * tricky + */ +public class UndergroundSystem { + + Map passengerDetails; + Map routeDetails; + + public UndergroundSystem() { + this.passengerDetails = new HashMap<>(); + this.routeDetails = new HashMap<>(); + } + + public void checkIn(int id, String stationName, int t) { + passengerDetails.putIfAbsent(id, new Passenger(id)); + passengerDetails.get(id).checkin(stationName, t); + } + + public void checkOut(int id, String stationName, int t) { + if (!passengerDetails.containsKey(id)) return; + + Passenger pass = passengerDetails.get(id); + pass.checkout(stationName, t); + + String routeKey = pass.startStation + " , " + pass.endStation; + routeDetails.putIfAbsent(routeKey, new Route(pass.startStation, pass.endStation)); + + routeDetails.get(routeKey).addTotalTiming(pass.startTime, pass.endTime); + passengerDetails.remove(id); + } + + public double getAverageTime(String startStation, String endStation) { + return routeDetails.get(startStation + " , " + endStation).avgTimeTaken(); + } + + + static class Passenger { + + int passengerId; + String startStation; + String endStation; + int startTime; + int endTime; + + public Passenger(int passengerId) { + this.passengerId = passengerId; + } + + public void checkin(String startStation, int startTime) { + this.startStation = startStation; + this.startTime = startTime; + } + + public void checkout(String endStation, int endTime) { + this.endStation = endStation; + this.endTime = endTime; + } + } + + static class Route { + String startStation; + String endStation; + long totalTravelTime; + int numberOfTravels; + + public Route(String startStation, String endStation) { + this.startStation = startStation; + this.endStation = endStation; + this.totalTravelTime = 0; + this.numberOfTravels = 0; + } + + public void addTotalTiming(int startTime, int endTime) { + this.totalTravelTime += (endTime - startTime); + numberOfTravels++; + } + + public double avgTimeTaken() { + return (double) totalTravelTime / numberOfTravels; + } + + } +} + diff --git a/src/main/java/practiceproblems/design/ValidTicTacToeState.java b/src/main/java/practiceproblems/design/ValidTicTacToeState.java new file mode 100644 index 0000000..fc315ae --- /dev/null +++ b/src/main/java/practiceproblems/design/ValidTicTacToeState.java @@ -0,0 +1,58 @@ +package practiceproblems.design; + +/** + * TODO- revision + * https://leetcode.com/problems/valid-tic-tac-toe-state + */ +public class ValidTicTacToeState { + public boolean validTicTacToe(String[] board) { + // turns = 0 represents 'X' will move, otherwise, 'O' will move + int turns = 0; + + // check whether 'X' wins or 'O' wins, or no players win + boolean xWin = getWinCombination(board, 'X'); + boolean yWin = getWinCombination(board, 'O'); + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + if (board[i].charAt(j) == 'X') turns++; + if (board[i].charAt(j) == 'O') turns--; + } + } + + /** + * Four conditions will be the invalid tic tac toe board: + * 1. there are more 'O' than 'X' + * 2. the board has 2 more 'X' than 'O' + * 3. number of 'X' is equal to number of 'O', but 'X' wins, it is impossible because if 'X' wins, the game is + over, 'O' cannot play again, then number of 'O' MUST less than 'X' + * 4. number of 'X' is more than number of 'O', but 'O' wins, it is impossible because if 'O' wins, the game is + over, 'X' cannot play again, then number of 'X' CANNOT greater than 'O' + * */ + return turns >= 0 && turns <= 1 && (turns != 0 || !xWin) && (turns != 1 || !yWin); + } + + public boolean getWinCombination(String[] board, char target) { + + // check horizontal + for (int i = 0; i < 3; i++) { + if (board[i].charAt(0) == target && board[i].charAt(0) == board[i].charAt(1) && board[i].charAt(1) == board[i].charAt(2)) { + return true; + } + } + // check vertical + for (int j = 0; j < 3; j++) { + if (board[0].charAt(j) == target && board[0].charAt(j) == board[1].charAt(j) && board[1].charAt(j) == board[2].charAt(j)) { + return true; + } + } + + // check diagonal + if (board[0].charAt(0) == target && board[0].charAt(0) == board[1].charAt(1) && board[1].charAt(1) == board[2].charAt(2)) { + return true; + } + // check diagonal + return board[2].charAt(0) == target && board[2].charAt(0) == board[1].charAt(1) && board[1].charAt(1) == board[0].charAt(2); + + } +} diff --git a/src/main/java/practiceproblems/intervals/BalloonBurst.java b/src/main/java/practiceproblems/intervals/BalloonBurst.java new file mode 100644 index 0000000..67a20a6 --- /dev/null +++ b/src/main/java/practiceproblems/intervals/BalloonBurst.java @@ -0,0 +1,55 @@ +package practiceproblems.intervals; + +import java.util.Arrays; +import java.util.Comparator; + +/** + * https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/ + * + * + * We know that eventually we have to shoot down every balloon, + * so for each ballon there must be an arrow whose position is between balloon[0] and balloon[1] inclusively. + * Given that, we can sort the array of balloons by their ending position. + * Then we make sure that while we take care of each balloon in order, + * we can shoot as many following balloons as possible. + * + * So what position should we pick each time? + * We should shoot as to the right as possible, because since balloons are sorted, this gives you the best chance to take down more balloons. + * Therefore the position should always be balloon[i][1] for the ith balloon. + * + * This is exactly what I do in the for loop: + * check how many balloons I can shoot down with one shot aiming at the ending position of the current balloon. + * Then I skip all these balloons and start again from the next one (or the leftmost remaining one) that needs another arrow. + * + * Example: + * balloons = [[7,10], [1,5], [3,6], [2,4], [1,4]] + * After sorting, it becomes: + * balloons = [[2,4], [1,4], [1,5], [3,6], [7,10]] + * So first of all, we shoot at position 4, + * we go through the array and see that all first 4 balloons can be taken care of by this single shot. + * Then we need another shot for one last balloon. So the result should be 2. + */ +public class BalloonBurst { + + public int findMinArrowShots(int[][] points) { + if (points.length == 0) { + return 0; + } + Arrays.sort(points, Comparator.comparingInt(a -> a[1])); + + int count=1; + + int arrowPos = points[0][1]; + + for(int i=1;i=points[i][0]) + continue; + + arrowPos = points[i][1]; + count++; + } + + return count; + } +} diff --git a/src/main/java/practiceproblems/intervals/InsertIntervals.java b/src/main/java/practiceproblems/intervals/InsertIntervals.java new file mode 100644 index 0000000..0c14ceb --- /dev/null +++ b/src/main/java/practiceproblems/intervals/InsertIntervals.java @@ -0,0 +1,80 @@ +package practiceproblems.intervals; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * https://leetcode.com/problems/insert-interval/ + * + * Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). + *

+ * You may assume that the intervals were initially sorted according to their start times. + * Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] + * Output: [[1,2],[3,10],[12,16]] + * Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10]. + */ +public class InsertIntervals { + public int[][] insert(int[][] intervals, int[] newInterval) { + List result = new ArrayList<>(); + int i = 0; + int n = intervals.length; + + //Add to the output all the intervals starting before newInterval. + while (i < n && intervals[i][1] < newInterval[0]) { + result.add(intervals[i++]); + } + + //Add to the output newInterval. + // Merge it with the last added interval if newInterval starts before the last added interval. + int[] mI = newInterval; + while (i < n && intervals[i][0] <= newInterval[1]) { + mI[0] = Math.min(intervals[i][0], mI[0]); + mI[1] = Math.max(intervals[i][1], mI[1]); + i++; + } + result.add(mI); + while (i < n) { + result.add(intervals[i++]); + } + + return result.toArray(new int[result.size() - 1][2]); + } + + public static int[][] insertEff(int[][] intervals, int[] newInterval) { + + List result = new ArrayList<>(); + + // Iterate through all slots + for (int[] interval : intervals) { + + // if newInterval before interval insert newInterval & update slot as new interval + if (newInterval[1] < interval[0]) { + result.add(newInterval); + newInterval = interval; + } + + // if interval is lesser than new Interval insert slot + else if (interval[1] < newInterval[0]) { + result.add(interval); + } + + // if above conditions fail it's an overlap since possibility of new interval existing in left & right of interval is checked + // update lowest of start & highest of end & not insert + else { + newInterval[0] = Math.min(newInterval[0], interval[0]); + newInterval[1] = Math.max(newInterval[1], interval[1]); + } + } + + // insert the last newInterval + result.add(newInterval); + + // convert to int[][] array + return result.toArray(new int[result.size()][]); + } + + public static void main(String[] args) { + System.out.println(Arrays.deepToString(insertEff(new int[][]{{1, 2}, {3, 5}, {6, 7}, {8, 10}, {12, 16}}, new int[]{4, 8}))); + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/intervals/MaxProfitJobScheduling.java b/src/main/java/practiceproblems/intervals/MaxProfitJobScheduling.java new file mode 100644 index 0000000..4a9bba6 --- /dev/null +++ b/src/main/java/practiceproblems/intervals/MaxProfitJobScheduling.java @@ -0,0 +1,112 @@ +package practiceproblems.intervals; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.TreeMap; + +/** + * tricky interval + * https://leetcode.com/problems/maximum-profit-in-job-scheduling + * + * https://www.youtube.com/watch?v=ZOP43iB_E_8&ab_channel=CodingDecoded + * + * So the goal is to find the profit up until the current start time and add the current profit to it, + * so we use the TreeMap to store the endTime and profit, if we pass the current startTime and find the floorKey + * from the map we will get the profit before the start of current startTime + */ +public class MaxProfitJobScheduling { + public int jobScheduling(int[] startTime, int[] endTime, int[] profit) { + Interval[] intervals = new Interval[profit.length]; + + for (int i = 0; i < profit.length; i++) { + intervals[i] = new Interval(startTime[i], endTime[i], profit[i]); + } + // sort by endTime greedily + Arrays.sort(intervals, Comparator.comparingInt(a -> a.endTime)); + TreeMap treeMap = new TreeMap<>(); + int result = Integer.MIN_VALUE; + + for (Interval interval : intervals) { + Integer key = treeMap.floorKey(interval.startTime); // returns endTime which is just before the curr start + result = Math.max(result, interval.profit + (key == null ? 0 : treeMap.get(key))); + treeMap.put(interval.endTime, result); + } + + return result; + } + + /** + * Thushar roy's approach + */ + public int jobSchedulingEff(int[] st, int[] et, int[] profit) { + int n = profit.length; + Interval[] jobs = new Interval[n]; + for (int i = 0; i < n; i++) + jobs[i] = new Interval(st[i], et[i], profit[i]); + Arrays.sort(jobs, Comparator.comparingInt(a -> a.endTime)); + + int[] dp = new int[n]; + dp[0] = jobs[0].profit; + for (int i = 1; i < n; i++) { + dp[i] = jobs[i].profit; + // we can further optimise the second for loop with binary search since the arr is sorted + for (int j = i - 1; j >= 0; j--) { + if (jobs[j].endTime <= jobs[i].startTime) { + dp[i] = Math.max(dp[i], jobs[i].profit + dp[j]); + break; + } + } + dp[i] = Math.max(dp[i], dp[i - 1]); + } + /** + * for (int i = 1; i < n; i++) { + * int profit = jobs[i].profit; + * int l = search(jobs, i); + * if (l != -1) + * profit += dp[l]; + * // Store maximum of including and excluding + * dp[i] = Math.max(profit, dp[i-1]); + * } + */ + return dp[n - 1]; + } + + // binary search code + private int search(Interval[] jobs, int index) { + int start = 0, end = index - 1; + while (start <= end) { + int mid = (start + end) / 2; + if (jobs[mid].endTime <= jobs[index].startTime) { + if (jobs[mid + 1].endTime <= jobs[index].startTime) + start = mid + 1; + else + return mid; + } else + end = mid - 1; + } + return -1; + } + + + private static class Interval { + int startTime; + int endTime; + int profit; + + public Interval(int startTime, int endTime, int profit) { + this.startTime = startTime; + this.endTime = endTime; + this.profit = profit; + } + + @Override + public String toString() { + return "Interval{" + + "startTime=" + startTime + + ", endTime=" + endTime + + ", profit=" + profit + + '}'; + } + + } +} diff --git a/src/main/java/practiceproblems/intervals/MeetingRoomsII.java b/src/main/java/practiceproblems/intervals/MeetingRoomsII.java new file mode 100644 index 0000000..f1c3419 --- /dev/null +++ b/src/main/java/practiceproblems/intervals/MeetingRoomsII.java @@ -0,0 +1,82 @@ +package practiceproblems.intervals; + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.PriorityQueue; + +/** + * https://www.lintcode.com/problem/meeting-rooms-ii/ + */ + +public class MeetingRoomsII { + // [(0,30),(5,10),(15,20)] + + // without using priority queue these cases will fail + // [[1,5],[8,9],[8,9]] + // [[9,10],[4,9],[4,17]] + public int minMeetingRooms(int[][] intervals) { + + Arrays.sort(intervals, Comparator.comparingInt(a -> a[0])); + + // Use a min heap to track the minimum end time of merged intervals + // this will take care of multiple same start time + PriorityQueue queue = new PriorityQueue<>(); + + int end = intervals[0][1]; + queue.offer(end); + for (int i = 1; i < intervals.length; i++) { + if (queue.peek() <= intervals[i][0]) { + queue.poll(); + } + queue.offer(intervals[i][1]); + } + + return queue.size(); + + } + + // Input: schedule = [[[1,2],[5,6]],[[1,3]],[[4,10]]] + // Output: [[3,4]] + + public List employeeFreeTime(List> schedule) { + PriorityQueue que = new PriorityQueue<>(Comparator.comparingInt(a -> a.start)); + + for (List list : schedule) { + for (Interval i : list) { + que.add(i); + } + } + + List rt = new ArrayList<>(); + int max = -1; + while (!que.isEmpty()) { + Interval top = que.poll(); + if (max != -1 && top.start > max) { + rt.add(new Interval(max, top.start)); + } + max = Math.max(max, top.end); + } + + return rt; + } + + class Interval { + + public int buy, sell; + int start; // for meeting problem + int end; + + public Interval(int buy, int sell) { + this.buy = buy; + this.sell = sell; + } + + public Interval() { + + } + } + +} diff --git a/src/main/java/practiceproblems/intervals/MergeIntervalIntersection.java b/src/main/java/practiceproblems/intervals/MergeIntervalIntersection.java new file mode 100644 index 0000000..4d9dae3 --- /dev/null +++ b/src/main/java/practiceproblems/intervals/MergeIntervalIntersection.java @@ -0,0 +1,84 @@ +package practiceproblems.intervals; + +import java.util.ArrayList; +import java.util.List; + +/** + * https://leetcode.com/problems/interval-list-intersections/ + * Return the intersection of these two interval lists. + * Input: firstList = [[0,2],[5,10],[13,23],[24,25]], secondList = [[1,5],[8,12],[15,24],[25,26]] + * + * Output: [[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]] + */ +public class MergeIntervalIntersection { + + // inorder to find a overlapping part alone between two intervals + // we take + // start = max(a.start, b.start) + // end = min(a.end, b.end) + // That is, the highest start time and the lowest end time will be the overlapping interval. + public int[][] intervalIntersection(int[][] A, int[][] B) { + int i = 0; + int j = 0; + List result = new ArrayList<>(); + while (i < A.length && j < B.length) { + + if (A[i][0] >= B[j][0] && A[i][0] <= B[j][1] || + B[j][0] >= A[i][0] && B[j][0] <= A[i][1]) { // this condition checks if there's a overlapping + //A=>[0,2], B=> [1,5] + result.add(new int[]{Math.max(A[i][0], B[j][0]), Math.min(A[i][1], B[j][1])}); + } + // once added to result move the i or j based on lesser end time + if (A[i][1] < B[j][1]) { // Exhausted this range in A + i++; // # Point to next range in A + } else { //# Exhausted this range in B + j++; //# Point to next range in B + } + } + + return result.toArray(new int[result.size()][2]); + } + + public int[][] intervalIntersectionEff(int[][] A, int[][] B) { + List ans = new ArrayList<>(); + int i = 0, j = 0; + + while (i < A.length && j < B.length) { + // Let's check if A[i] intersects B[j]. + // lo - the starting point of the intersection + // hi - the endpoint of the intersection + int lo = Math.max(A[i][0], B[j][0]); + int hi = Math.min(A[i][1], B[j][1]); + if (lo <= hi) + ans.add(new int[]{lo, hi}); + + // Remove the interval with the smallest endpoint + if (A[i][1] < B[j][1]) + i++; + else + j++; + } + + return ans.toArray(new int[ans.size()][]); + } + + public int[][] intervalIntersectionBrute(int[][] A, int[][] B) { + List list = new ArrayList<>(); + for (int[] ints : A) { + for (int[] value : B) { + int[] intersect = findIntersection(ints, value); + if (intersect.length != 0) list.add(intersect); + } + } + return list.toArray(new int[list.size()][]); + } + + /** + * 1st interval ending should be greater than 2nd 's first + * 1st interval begin should be less than 2nd's end + */ + public int[] findIntersection(int[] a, int[] b) { + if (a[1] < b[0] || b[1] < a[0]) return new int[]{}; + return new int[]{Math.max(a[0], b[0]), Math.min(a[1], b[1])}; + } +} \ No newline at end of file diff --git a/src/practiceproblems/MergeIntervals.java b/src/main/java/practiceproblems/intervals/MergeIntervals.java similarity index 89% rename from src/practiceproblems/MergeIntervals.java rename to src/main/java/practiceproblems/intervals/MergeIntervals.java index ae87748..7ff73e1 100644 --- a/src/practiceproblems/MergeIntervals.java +++ b/src/main/java/practiceproblems/intervals/MergeIntervals.java @@ -1,4 +1,4 @@ -package practiceproblems; +package practiceproblems.intervals; import java.util.ArrayList; import java.util.Arrays; @@ -14,9 +14,6 @@ public static int[][] merge(int[][] intervals) { if (intervals.length <= 1) { return intervals; } - - /* Arrays.sort(intervals, (a, b) -> a[0] - b[0]); - Arrays.sort(intervals, (i1, i2) -> Integer.compare(i1[0], i2[0]));*/ Arrays.sort(intervals, Comparator.comparingInt(i -> i[0])); List result = new ArrayList<>(); diff --git a/src/main/java/practiceproblems/intervals/OverlappingIntervals.java b/src/main/java/practiceproblems/intervals/OverlappingIntervals.java new file mode 100644 index 0000000..3c110b4 --- /dev/null +++ b/src/main/java/practiceproblems/intervals/OverlappingIntervals.java @@ -0,0 +1,49 @@ +package practiceproblems.intervals; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/non-overlapping-intervals/ + */ + +public class OverlappingIntervals { + + public int eraseOverlapIntervals(int[][] intervals) { + if (intervals.length == 0) return 0; + Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0])); + + int end = intervals[0][1]; + + int result = 0; + for (int i = 1; i < intervals.length; i++) { + + result++; + + if (intervals[i][0] < end) { + result++; + /** + * The reason we choose min of ends + * 1 -------------------- + * 2 ----- ----------------- 3 + * + * Suppose we have three intervals as above, and we sort them acc to start time. + * Then for interval 2, which overlaps with 1, we can either remove 1 or 2. + * If we removed 2, then interval 3 will overlap again with 1 and we have to remove one more interval(mostly 3). + * We are removing 2 intervals which is not the correct ans. + * We need more logic to make the code work correctly. + * + * So instead of 2 if we removed 1 then we have to update the previous end point as 1 is now gone. + * Hence the assignment of the smaller endtime (e = itv.end). + * Interval 3 doesnt overlap with last end time and so we only have to remove 1 interval, + * which is what we expected. + */ + end = Math.min(end, intervals[i][1]); + } else { + end = intervals[i][1]; + } + } + + return result; + } + +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/intervals/RectangleComputeArea.java b/src/main/java/practiceproblems/intervals/RectangleComputeArea.java new file mode 100644 index 0000000..0245fa9 --- /dev/null +++ b/src/main/java/practiceproblems/intervals/RectangleComputeArea.java @@ -0,0 +1,33 @@ +package practiceproblems.intervals; + +/** + * https://leetcode.com/problems/rectangle-area/submissions/ + * + * Calculate the area of each rectangle at first. Judge whether they have intersection. + * If not, return the sum area of them. + * Otherwise, count the intersection area and subtract it by one time of total area. + */ +public class RectangleComputeArea { + + public int computeArea(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) { + + + int rectOneArea = (ax2 - ax1) * (ay2 - ay1); + int rectTwoArea = (bx2 - bx1) * (by2 - by1); + + + int[] overlapping = new int[4]; + + overlapping[0] = Math.max(ax1, bx1); + overlapping[1] = Math.max(ay1, by1); + + overlapping[2] = Math.min(ax2, bx2); + overlapping[3] = Math.min(ay2, by2); + + int overlapLength = overlapping[2] - overlapping[0]; + int overlapWidth = overlapping[3] - overlapping[1]; + + + return rectOneArea + rectTwoArea - (overlapLength <= 0 || overlapWidth <= 0 ? 0 : overlapLength * overlapWidth); + } +} diff --git a/src/main/java/practiceproblems/intervals/RectangleOverlap.java b/src/main/java/practiceproblems/intervals/RectangleOverlap.java new file mode 100644 index 0000000..4962ba3 --- /dev/null +++ b/src/main/java/practiceproblems/intervals/RectangleOverlap.java @@ -0,0 +1,62 @@ +package practiceproblems.intervals; + +/** + * https://leetcode.com/problems/rectangle-overlap + * + * For overlapping questions: + * + * Interval A = [leftA, rightA] + * Interval B = [leftB, rightB] + * Overlapping region: [max(leftA, leftB) , min(rightA, rightB)] + * + * which means if(max(leftA, leftB) < min(rightA, rightB)), there is an overlap. + * So the code of this problem is to check whether x is overlapped && y is overlapped. + * + * + * ------------ ------------- + * 0 1 2 3 + * + * start = Math.max(start1, start2) = 2 + * end = Math.min(end1, end2) = 1 + * + * does not overlap as start > end + * + * ------------- + * 1 3 + * ------------ + * 0 2 + * + * start = Math.max(start1, start2) = 1 + * end = Math.min(end1, end2) = 2 + * + * overlap as start < end + */ +public class RectangleOverlap { + public boolean isRectangleOverlap(int[] rec1, int[] rec2) { + + int x1 = rec1[0]; + int y1 = rec1[1]; + + int x2 = rec1[2]; + int y2 = rec1[3]; + + int r2X1 = rec2[0]; + int r2Y1 = rec2[1]; + + int r2X2 = rec2[2]; + int r2Y2 = rec2[3]; + + boolean overlapX = false; + boolean overlapY = false; + + if (Math.max(x1, r2X1) < Math.min(x2, r2X2)) { + overlapX = true; + } + + if (Math.max(y1, r2Y1) < Math.min(y2, r2Y2)) { + overlapY = true; + } + + return overlapX && overlapY; + } +} diff --git a/src/main/java/practiceproblems/jumpGame/JumpGameV.java b/src/main/java/practiceproblems/jumpGame/JumpGameV.java new file mode 100644 index 0000000..0a5f070 --- /dev/null +++ b/src/main/java/practiceproblems/jumpGame/JumpGameV.java @@ -0,0 +1,68 @@ +package practiceproblems.jumpGame; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; + +/** + * https://leetcode.com/problems/jump-game-iv/ + */ +public class JumpGameV { + + public int minJumps(int[] arr) { + int n = arr.length; + + if (n == 1) return 0; + + // craeted map holding integer & list + Map> map = new HashMap<>(); + int step = 0; // intial step is 0 + + // Our 1st job is "fill the map" + for (int i = 0; i < n; i++) { + // so, using this function it will check is arr[i] is present or not, if it's not present it would create a new arraylist + // and if it's already present we will add index in it + map.computeIfAbsent(arr[i], v -> new LinkedList<>()).add(i); + } + + // next we need a queue. + Queue q = new LinkedList<>(); + q.offer(0);// in queue we will add our 1st index which is 0 + + while (!q.isEmpty()) { // looping until queue is not empty + step++; // incrementing our step + int size = q.size(); // taking queue size + for (int i = 0; i < size; i++) { // now for each element in this queue for this particulart size running a loop + // so, here we will perform 3 steps + int j = q.poll(); // getting element from queue + + // Jump to j - 1 + if (j - 1 >= 0 && map.containsKey(arr[j - 1])) { + q.offer(j - 1); + } + + // Jump to j + 1 + if (j + 1 < n && map.containsKey(arr[j + 1])) { + // there could be 2 conditions + if (j + 1 == n - 1) return step; // if j+1 is equals to last element + q.offer(j + 1); // otherwise add in queue + } + + // Jump to k --> arr[j] == arr[k] + if (map.containsKey(arr[j])) { // if this particular element hasn't processed + for (int k : map.get(arr[j])) { // so, we will iterate over each k + if (k != j) { // in this we first check if they are not equal, positions are not same + if (k == n - 1) return step; + q.offer(k); + } + } + } + map.remove(arr[j]); // removing from map + } + } + + return step; + } +} diff --git a/src/main/java/practiceproblems/jumpGame/JumpsToReachEnd.java b/src/main/java/practiceproblems/jumpGame/JumpsToReachEnd.java new file mode 100644 index 0000000..1e256d5 --- /dev/null +++ b/src/main/java/practiceproblems/jumpGame/JumpsToReachEnd.java @@ -0,0 +1,124 @@ +package practiceproblems.jumpGame; + +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.Deque; +import java.util.List; + +public class JumpsToReachEnd { + + /** + * Given an array of non-negative integers nums, + * you are initially positioned at the first index of the array. + * Each element in the array represents your maximum jump length at that position. + *

+ * Determine if you are able to reach the last index + * Input: nums = [2,3,1,1,4] + * Output: true + * Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index. + *

+ * Input: nums = [3,2,1,0,4] + * Output: false + * Explanation: You will always arrive at index 3 no matter what. + * Its maximum jump length is 0, which makes it impossible to reach the last index. + */ + public static boolean canReachEnd(Integer[] nums) { + + int curMax = nums[0]; + for (int i = 1; i < nums.length; i++) { + if (curMax < i) return false; //means we are not able to reach position i + curMax = Math.max(curMax, i + nums[i]); + } + return true; + } + + + /** + * Given an array of non-negative integers arr, + * you are initially positioned at start index of the array. + * When you are at index i, you can jump to i + arr[i] or i - arr[i], + * check if you can reach to any index with value 0. + * Notice that you can not jump outside of the array at any time. + *

+ * Input: arr = [4,2,3,0,3,1,2], start = 5 + * Output: true + * Explanation: + * All possible ways to reach at index 3 with value 0 are: + * index 5 -> index 4 -> index 1 -> index 3 + * index 5 -> index 6 -> index 4 -> index 1 -> index 3 + *

+ * Input: arr = [4,2,3,0,3,1,2], start = 0 + * Output: true + * Explanation: + * One possible way to reach at index 3 with value 0 is: + * index 0 -> index 4 -> index 1 -> index 3 + */ + public boolean canReach(int[] arr, int start) { + + if (arr[start] == 0) return true; + + Deque queue = new ArrayDeque<>(); + + queue.offer(new int[]{start, arr[start]}); + boolean[] visited = new boolean[arr.length]; + visited[start] = true; + while (!queue.isEmpty()) { + + int[] temp = queue.poll(); + + int jumpIndexFwd = temp[0] + temp[1]; + int jumpIndexBack = temp[0] - temp[1]; + + if (jumpIndexFwd >= 0 && jumpIndexFwd < arr.length && !visited[jumpIndexFwd]) { + if (arr[jumpIndexFwd] == 0) return true; + visited[jumpIndexFwd] = true; + queue.offer(new int[]{jumpIndexFwd, arr[jumpIndexFwd]}); + } + + if (jumpIndexBack >= 0 && jumpIndexBack < arr.length && !visited[jumpIndexBack]) { + if (arr[jumpIndexBack] == 0) return true; + visited[jumpIndexBack] = true; + queue.offer(new int[]{jumpIndexBack, arr[jumpIndexBack]}); + } + + } + + return false; + } + + + /** + * This is a BFS solution + * + * @param nums + * @return + */ + public int minJump(int[] nums) { + int result = 0, curEnd = 0, curFarthest = 0; + for (int i = 0; i < nums.length - 1; i++) { // loop till last jump hasn't taken us till the end + + //maxReachable is the maximum reachable index from index i. + // Consider this example 2, 3, 10, 1 in this case, maxReachable will be 12 at index 2 which says we can reach till 12th index but not the number of jumps. + // So, if you update it with number of jumps you get 12 where as answer is 2. + + curFarthest = Math.max(curFarthest, i + nums[i]); //Updating the range of next level. + // Similar to queue.push(node) step of BFS but here we are only greedily storing the max reachable index on next level. + + if (i == curEnd) { //When it becomes true, current level iteration has been completed. + result++; + curEnd = curFarthest; //Move on to the next level. + + if (curEnd >= nums.length - 1) { + break; + } + } + } + return result; + } + + public static void main(String[] args) { + + List list = Arrays.asList(3, 3, 1, 0, 2, 0, 1); + System.out.println(canReachEnd(list.toArray(new Integer[list.size()]))); + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/jumpGame/MinTapsToFillGarden.java b/src/main/java/practiceproblems/jumpGame/MinTapsToFillGarden.java new file mode 100644 index 0000000..ce911e2 --- /dev/null +++ b/src/main/java/practiceproblems/jumpGame/MinTapsToFillGarden.java @@ -0,0 +1,38 @@ +package practiceproblems.jumpGame; + +/** + * https://leetcode.com/problems/minimum-number-of-taps-to-open-to-water-a-garden/ + */ +public class MinTapsToFillGarden { + public int minTaps(int n, int[] ranges) { + /** + * i <= end. Suppose ranges = [1,2,1,0,2,1,0,1], arr becomes [3,3,6,0,6,0,8,0]. + * After the 1st step, farCanReach becomes 3, end also becomes 3. + * Now we can choose to move to index 1, index 2, or index 3. + * Since moving to index 2 will give us the largest move (6) in the next step, farCanReach is updated to 6. + * And we can move from there. + */ + for (int i=0; i= n ? steps : -1; + } +} diff --git a/src/main/java/practiceproblems/jumpGame/VideoStitching.java b/src/main/java/practiceproblems/jumpGame/VideoStitching.java new file mode 100644 index 0000000..56a79e6 --- /dev/null +++ b/src/main/java/practiceproblems/jumpGame/VideoStitching.java @@ -0,0 +1,47 @@ +package practiceproblems.jumpGame; + +/** + * https://leetcode.com/problems/video-stitching/ + * + * Observation 1: We will always pick a clip with the maximum coverage if they have same starting points. + * + * eg: [0,3],[0,7],[0,5] -> We pick [0,7] , there is no point of picking others as the problem states that we need to minimize the number of clips picked, + * and this can only be done if we maximize the gap between start and end point of each clip. + * + * Observation 2: Once we start picking the clips from the minimum starting point, + * we only increase the count if we find a starting point greater than previously selected clip's end, + * from then on we keep maximizing the reachable end without increasing count. + */ +public class VideoStitching { + public int videoStitching(int[][] clips, int time) { + + int[] clippings = new int[time + 1]; + + for (int[] clip : clips) { + if (clip[0] > time) continue; + + clippings[clip[0]] = Math.max(clippings[clip[0]], clip[1]); + } + + int currJumpIndex = 0; + int maxJumIndex = 0; + int steps = 0; + + for (int i = 0; i <= time; i++) { + + if (i > maxJumIndex) break; + + maxJumIndex = Math.max(maxJumIndex, clippings[i]); + + if (i >= currJumpIndex) { + + steps++; + + currJumpIndex = maxJumIndex; + if (maxJumIndex >= time) return steps; + } + } + + return maxJumIndex >= time ? steps : -1; + } +} diff --git a/src/practiceproblems/CountNumbersLessThanSelf.java b/src/main/java/practiceproblems/mergesort/CountNumbersLessThanSelf.java similarity index 86% rename from src/practiceproblems/CountNumbersLessThanSelf.java rename to src/main/java/practiceproblems/mergesort/CountNumbersLessThanSelf.java index 4197b67..36af8a6 100644 --- a/src/practiceproblems/CountNumbersLessThanSelf.java +++ b/src/main/java/practiceproblems/mergesort/CountNumbersLessThanSelf.java @@ -1,4 +1,4 @@ -package practiceproblems; +package practiceproblems.mergesort; import java.util.LinkedList; import java.util.List; @@ -12,22 +12,23 @@ class CountNumbersLessThanSelf { // Wrapper class for each and every value of the input array, // to store the original index position of each value, before we merge sort the array - private class ArrayValWithOrigIdx { + private static class ArrayValWithOrigIdx { int val; - int originalIdx; + int idx; - public ArrayValWithOrigIdx(int val, int originalIdx) { + public ArrayValWithOrigIdx(int val, int idx) { this.val = val; - this.originalIdx = originalIdx; + this.idx = idx; } } public List countSmaller(int[] nums) { - if (nums == null || nums.length == 0) return new LinkedList(); + if (nums == null || nums.length == 0) return new LinkedList<>(); int n = nums.length; int[] result = new int[n]; ArrayValWithOrigIdx[] newNums = new ArrayValWithOrigIdx[n]; + for (int i = 0; i < n; ++i) newNums[i] = new ArrayValWithOrigIdx(nums[i], i); mergeSortAndCount(newNums, 0, n - 1, result); @@ -50,9 +51,9 @@ private void mergeSortAndCount(ArrayValWithOrigIdx[] nums, int start, int end, i // right subarray mid+1...end int leftPos = start; int rightPos = mid + 1; - LinkedList merged = new LinkedList(); + LinkedList merged = new LinkedList<>(); int numElemsRightArrayLessThanLeftArray = 0; - while (leftPos < mid + 1 && rightPos <= end) { + while (leftPos <= mid && rightPos <= end) { if (nums[leftPos].val > nums[rightPos].val) { // this code block is exactly what the problem is asking us for: // a number from the right side of the original input array, is smaller @@ -70,7 +71,7 @@ private void mergeSortAndCount(ArrayValWithOrigIdx[] nums, int start, int end, i } else { // a number from left side of array, is smaller than a number from // right side of array - result[nums[leftPos].originalIdx] += numElemsRightArrayLessThanLeftArray; + result[nums[leftPos].idx] += numElemsRightArrayLessThanLeftArray; // Continue with normal merge sort merged.add(nums[leftPos]); @@ -80,8 +81,8 @@ private void mergeSortAndCount(ArrayValWithOrigIdx[] nums, int start, int end, i // part of normal merge sort, if either left or right sub-array is not empty, // move all remaining elements into merged result - while (leftPos < mid + 1) { - result[nums[leftPos].originalIdx] += numElemsRightArrayLessThanLeftArray; + while (leftPos <= mid) { + result[nums[leftPos].idx] += numElemsRightArrayLessThanLeftArray; merged.add(nums[leftPos]); ++leftPos; diff --git a/src/main/java/practiceproblems/mergesort/CountOfRanges.java b/src/main/java/practiceproblems/mergesort/CountOfRanges.java new file mode 100644 index 0000000..f076003 --- /dev/null +++ b/src/main/java/practiceproblems/mergesort/CountOfRanges.java @@ -0,0 +1,61 @@ +package practiceproblems.mergesort; + +/** + * https://leetcode.com/problems/count-of-range-sum/ + */ +public class CountOfRanges { + + int count = 0; + int lower; + int upper; + + public int countRangeSum(int[] nums, int lower, int upper) { + long[] sum = new long[nums.length + 1]; + long[] temp = new long[nums.length + 1]; + sum[0] = 0; + this.lower = lower; + this.upper = upper; + for (int i = 1; i <= nums.length; i++) { + sum[i] = sum[i - 1] + nums[i - 1]; + } + + mergesort(sum, 0, sum.length - 1, temp); + return count; + } + + private void mergesort(long[] sum, int start, int end, long[] temp) { + if (start >= end) { + return; + } + int mid = start + (end - start) / 2; + mergesort(sum, start, mid, temp); + mergesort(sum, mid + 1, end, temp); + merge(sum, start, mid, end, temp); + } + + private void merge(long[] sum, int start, int mid, int end, long[] temp) { + int right = mid + 1; + int index = start; + int low = mid + 1, high = mid + 1; + for (int left = start; left <= mid; left++) { + while (low <= end && sum[low] - sum[left] < lower) { + low++; + } + while (high <= end && sum[high] - sum[left] <= upper) { + high++; + } + while (right <= end && sum[right] < sum[left]) { + temp[index++] = sum[right++]; + } + temp[index++] = sum[left]; + count += high - low; + } + while (right <= end) { + temp[index++] = sum[right++]; + } + + for (int i = start; i <= end; i++) { + sum[i] = temp[i]; + } + } +} diff --git a/src/practiceproblems/CountingInversion.java b/src/main/java/practiceproblems/mergesort/CountingInversion.java similarity index 96% rename from src/practiceproblems/CountingInversion.java rename to src/main/java/practiceproblems/mergesort/CountingInversion.java index eb81ddd..0ca4129 100644 --- a/src/practiceproblems/CountingInversion.java +++ b/src/main/java/practiceproblems/mergesort/CountingInversion.java @@ -1,4 +1,4 @@ -package practiceproblems; +package practiceproblems.mergesort; /** * https://www.geeksforgeeks.org/counting-inversions/ @@ -40,7 +40,7 @@ static int merge(int[] arr, int[] temp, int left, int mid, int right) { // when i=1 and j=0 (value 3 and 2) we see an inversion, since // the first part is sorted and values after i=1(3) will be greater than j=0(2) // so we consider all elements after 3 as inversions - invCount = invCount + (mid - i); + invCount+= i - mid+1; } } diff --git a/src/main/java/practiceproblems/mergesort/ReversePairs.java b/src/main/java/practiceproblems/mergesort/ReversePairs.java new file mode 100644 index 0000000..02592ee --- /dev/null +++ b/src/main/java/practiceproblems/mergesort/ReversePairs.java @@ -0,0 +1,85 @@ +package practiceproblems.mergesort; + +public class ReversePairs { + + public int reversePairs(int[] nums) { + int[] temp = new int[nums.length]; + return mergeSort(nums, temp, 0, nums.length - 1); + + } + + int mergeSort(int[] arr, int[] temp, int left, int right) { + int mid; + int invCount = 0; + if (left < right) { + + mid = ((right + left) / 2); + + invCount = mergeSort(arr, temp, left, mid); + invCount += mergeSort(arr, temp, mid + 1, right); + + invCount += merge(arr, temp, left, mid, right); + } + return invCount; + } + + int merge(int[] arr, int[] temp, int left, int mid, int right) { + int invCount = 0; + int rightArrStart = mid + 1; + + /** + * the idea is move the rightArrStart for all the valid 2 * arr[j] + * fox ex leftArr = [12,19,28] and rightArr = [2,10,12] + * + * when leftArrPointer = 12 + * rightArrPointer = 10 + * the while loop breaks and the count is added as (rightArrPointer - mid+1) => 1 + * + * we then increment leftArrPointer + * + * when leftArrPointer = 19 + * rightArrPointer = 10 + * the while loop is skipped and the count is added as (rightArrPointer - mid+1) => 1 because the previous 2 values is + * lesser than the 19(2*2 < 19) + * + * we then increment leftArrPointer + * + * when leftArrPointer = 28 + * rightArrPointer = 10 + * + * the while loop breaks because no more value in rightArr + * and the count is added as (rightArrPointer - mid+1) => 3 + * + * + */ + for (int leftArrStart = left; leftArrStart <= mid; leftArrStart++) { + + while (rightArrStart <= right && arr[leftArrStart] > 2 * (long) arr[rightArrStart]) { + rightArrStart++; + } + invCount += (rightArrStart - (mid + 1)); // this gives the length of right array's valid window + } + + int i = left; + int j = mid + 1; + int k = left; + while ((i <= mid) && (j <= right)) { + if (arr[i] <= arr[j]) { + temp[k++] = arr[i++]; + } else { + temp[k++] = arr[j++]; + } + } + + while (i <= mid) + temp[k++] = arr[i++]; + while (j <= right) + temp[k++] = arr[j++]; + + for (i = left; i <= right; i++) + arr[i] = temp[i]; + + return invCount; + } + +} diff --git a/src/main/java/practiceproblems/parentheses/BalancedSmiley.java b/src/main/java/practiceproblems/parentheses/BalancedSmiley.java new file mode 100644 index 0000000..0aa442a --- /dev/null +++ b/src/main/java/practiceproblems/parentheses/BalancedSmiley.java @@ -0,0 +1,62 @@ +package practiceproblems.parentheses; + +/** + * Your friend John uses a lot of emoticons when you talk to him on Messenger. + * In addition to being a person who likes to express himself through emoticons, + * he hates unbalanced parenthesis so much that it makes him go :( + *

+ * Sometimes he puts emoticons within parentheses, + * and you find it hard to tell if a parenthesis really is a parenthesis or part of an emoticon. + + * A message has balanced parentheses if it consists of one of the following: + * - An empty string "" + * - One or more of the following characters: 'a' to 'z', ' ' (a space) or ':' (a colon) + * - An open parenthesis '(', followed by a message with balanced parentheses, followed by a close parenthesis ')'. + * - A message with balanced parentheses followed by another message with balanced parentheses. + * - A smiley face ":)" or a frowny face ":(" + * + * (:) : YES + * i am sick today (:() : YES + * )(: NO + * hacker cup: started :):): YES + * :((: NO + */ +public class BalancedSmiley { + + /** + * Idea : + * + * Idea is similar to other Balance Parentheses related problems. i.e we check the balance of ( and ) brackets. + * + * And whenever number of ) exceeds number of ( , we can say that it is unbalanced from start. + * + * And whenever number of ( exceeds number of ) , we can say that it is unbalanced from end ( this one is trivial). + * + * This can be done by incrementing when we see opening ( bracket and decrementing vice versa. + * + * + * if maxOpen is negative or minOpen isn't zero, it's not possible for the message to have balanced parentheses + * + * @param s + */ + public boolean isBalanced(String s) { + int minOpen = 0; + int maxOpen = 0; + + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == '(') { + maxOpen++; + if (i == 0 || s.charAt(i - 1) == ':') { + minOpen++; + } + } else if (s.charAt(i) == ')') { + minOpen = Math.max(0, minOpen - 1); + if (i == 0 || s.charAt(i - 1) == ':') { + maxOpen--; + if (maxOpen < 0) break; + } + } + } + return maxOpen >= 0 && minOpen == 0; + } +} diff --git a/src/main/java/practiceproblems/parentheses/CanBeValid.java b/src/main/java/practiceproblems/parentheses/CanBeValid.java new file mode 100644 index 0000000..00dfeeb --- /dev/null +++ b/src/main/java/practiceproblems/parentheses/CanBeValid.java @@ -0,0 +1,60 @@ +package practiceproblems.parentheses; + +/** + * https://leetcode.com/problems/check-if-a-parentheses-string-can-be-valid + * + * Idea : + * + * Idea is similar to other Balance Parentheses related problems. i.e we check the balance of ( and ) brackets. + * + * And whenever number of ) exceeds number of ( , we can say that it is unbalanced from start. + * + * And whenever number of ( exceeds number of ) , we can say that it is unbalanced from end ( this one is trivial). + * + * This can be done by incrementing when we see opening ( bracket and decrementing vice versa. + */ +public class CanBeValid { + + public boolean canBeValid(String s, String locked) { + int n = s.length(); + if (n % 2 != 0) return false; + + int open = 0; + int close = 0; + + // First check balance from left to right + // For opening '(' brackets + for (int i = 0; i < n; i++) { + + // If either char is ( or it is unlocked, + // We can increment open balance + if (locked.charAt(i) == '0' || s.charAt(i) == '(') open++; + else close++; // otherwise, decrement balance, since it is ) and also locked + + // Since balance is negative, we have more ')'. + // And there is no unlocked char available + // SO, it is invalid string for sure + if (close > open) return false; + } + + open = 0; + close = 0; + // Then also check balance from right to left + // For closing ')' brackets + for (int i = n - 1; i >= 0; i--) { + + // If either char is ) or it is unlocked, + // We can increment balance + if (locked.charAt(i) == '0' || s.charAt(i) == ')') close++; + else open++; + + // Since balance is negative, we have more '('. + // And there is no unlocked char available + // SO, it is invalid string for sure + + if (open > close) return false; + } + + return true; + } +} diff --git a/src/main/java/practiceproblems/parentheses/DifferentWaysToAddParenthesis.java b/src/main/java/practiceproblems/parentheses/DifferentWaysToAddParenthesis.java new file mode 100644 index 0000000..3f32860 --- /dev/null +++ b/src/main/java/practiceproblems/parentheses/DifferentWaysToAddParenthesis.java @@ -0,0 +1,61 @@ +package practiceproblems.parentheses; + +// Given a string of numbers and operators, +// return all possible results from computing all the different possible ways to group numbers +// and operators. The valid operators are +, - and *. + +import java.util.*; + +// Input: "2*3-4*5" +// Output: [-34, -14, -10, -10, 10] +// Explanation: +// (2*(3-(4*5))) = -34 +// ((2*3)-(4*5)) = -14 +// ((2*(3-4))*5) = -10 +// (2*((3-4)*5)) = -10 +// (((2*3)-4)*5) = 10 +public class DifferentWaysToAddParenthesis { + public List diffWaysToCompute(String input) { + if (input == null) return Collections.emptyList(); + + Map> map = new HashMap<>(); + return bfsHelper(input, map); + + } + + public List bfsHelper(String input, Map> map) { + + if (map.containsKey(input)) { + return map.get(input); + } + + List result = new ArrayList<>(); + if (!input.contains("+") && !input.contains("-") && !input.contains("*")) { + result.add(Integer.parseInt(input)); + } else { + // Split input string into two parts and solve them recursively + // for ex input = 2*3-4 output=2,-2 + // 2* | 3-4 => this right and left expression returns a list + // 2*3| -4 => this right and left expression returns another list + for (int i = 0; i < input.length(); i++) { + if (!Character.isDigit(input.charAt(i))) { + List firstList = bfsHelper(input.substring(0, i), map); + List secondList = bfsHelper(input.substring(i + 1), map); + for (int first : firstList) { + for (int second : secondList) { + if (input.charAt(i) == '+') { + result.add(first + second); + } else if (input.charAt(i) == '-') { + result.add(first - second); + } else { + result.add(first * second); + } + } + } + } + } + } + map.put(input, result); + return result; + } +} \ No newline at end of file diff --git a/src/practiceproblems/GenerateParenthesis.java b/src/main/java/practiceproblems/parentheses/GenerateParenthesis.java similarity index 97% rename from src/practiceproblems/GenerateParenthesis.java rename to src/main/java/practiceproblems/parentheses/GenerateParenthesis.java index c060cb4..68a0523 100644 --- a/src/practiceproblems/GenerateParenthesis.java +++ b/src/main/java/practiceproblems/parentheses/GenerateParenthesis.java @@ -1,4 +1,4 @@ -package practiceproblems; +package practiceproblems.parentheses; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/practiceproblems/parentheses/LongestValidParentheses.java b/src/main/java/practiceproblems/parentheses/LongestValidParentheses.java new file mode 100644 index 0000000..9681e58 --- /dev/null +++ b/src/main/java/practiceproblems/parentheses/LongestValidParentheses.java @@ -0,0 +1,51 @@ +package practiceproblems.parentheses; + +/** + * https://leetcode.com/problems/longest-valid-parentheses/submissions/ + */ +public class LongestValidParentheses { + + public int longestValidParentheses(String s) { + + int open = 0; + int close = 0; + int maxLen = 0; + + for (int i = 0; i < s.length(); i++) { + + if (s.charAt(i) == '(') { + open++; + } else { + close++; + } + + if (open == close) { + maxLen = Math.max(open + close, maxLen); + } + if (close > open) { + open = 0; + close = 0; + } + } + open = 0; + close = 0; + for (int i = s.length() - 1; i >= 0; i--) { + + if (s.charAt(i) == '(') { + open++; + } else { + close++; + } + + if (open == close) { + maxLen = Math.max(open + close, maxLen); + } + if (open > close) { + open = 0; + close = 0; + } + } + + return maxLen; + } +} diff --git a/src/main/java/practiceproblems/parentheses/MinSwapsToBalance.java b/src/main/java/practiceproblems/parentheses/MinSwapsToBalance.java new file mode 100644 index 0000000..789b648 --- /dev/null +++ b/src/main/java/practiceproblems/parentheses/MinSwapsToBalance.java @@ -0,0 +1,75 @@ +package practiceproblems.parentheses; + +import java.util.ArrayList; +import java.util.List; + +/** + * Idea : + * + * Idea is similar to other Balance Parentheses related problems. i.e we check the balance of ( and ) brackets. + * + * And whenever number of ) exceeds number of ( , we can say that it is unbalanced from start. + * + * And whenever number of ( exceeds number of ) , we can say that it is unbalanced from end ( this one is trivial). + * + * This can be done by incrementing when we see opening ( bracket and decrementing vice versa. + */ +public class MinSwapsToBalance { + public static long swapCount(String s) { + + // Keep track of '[' + List pos = new ArrayList<>(); + for (int i = 0; i < s.length(); ++i) + if (s.charAt(i) == '[') + pos.add(i); + + // To OpenBraceCount number of encountered '[' + int OpenBraceCount = 0; + + // To track position of next '[' in pos + int nextPosOfOpen = 0; + + // To store result + long sum = 0; + + char[] S = s.toCharArray(); + + for (int i = 0; i < s.length(); ++i) { + + // Increment OpenBraceCount and move nextPosOfOpen + // to next position + if (S[i] == '[') { + ++OpenBraceCount; + ++nextPosOfOpen; + } else if (S[i] == ']') + --OpenBraceCount; + + // We have encountered an + // unbalanced part of string + if (OpenBraceCount < 0) { + + // Increment sum by number of + // swaps required i.e. position + // of next '[' - current position + sum += pos.get(nextPosOfOpen) - i; + char temp = S[i]; + S[i] = S[pos.get(nextPosOfOpen)]; + S[pos.get(nextPosOfOpen)] = temp; + ++nextPosOfOpen; + + // Reset OpenBraceCount to 1 + OpenBraceCount = 1; + } + } + return sum; + } + + // Driver code + public static void main(String[] args) { + String s = "[]][]["; + System.out.println(swapCount(s)); + + s = "[[][]]"; + System.out.println(swapCount(s)); + } +} diff --git a/src/main/java/practiceproblems/parentheses/RemoveInvalidParentheses.java b/src/main/java/practiceproblems/parentheses/RemoveInvalidParentheses.java new file mode 100644 index 0000000..2fa7881 --- /dev/null +++ b/src/main/java/practiceproblems/parentheses/RemoveInvalidParentheses.java @@ -0,0 +1,100 @@ +package practiceproblems.parentheses; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class RemoveInvalidParentheses { + public List removeInvalidParentheses(String s) { + List res = new ArrayList<>(); + + // sanity check + if (s == null) return res; + + Set visited = new HashSet<>(); + Deque queue = new ArrayDeque<>(); + + // initialize + queue.add(s); + visited.add(s); + + boolean found = false; + + while (!queue.isEmpty()) { + s = queue.poll(); + + if (isValid(s)) { + // found an answer, add to the result + res.add(s); + found = true; + } + /** + * this ensures once we've found a valid parentheses pattern, + * we don't do any further bfs using items pending in the queue since any further bfs would only yield strings of smaller length. + * However the items already in queue need to be processed since there could be other solutions of the same length. + * great solution. + */ + if (found) continue; + + // generate all possible states + for (int i = 0; i < s.length(); i++) { + // we only try to remove left or right paren + if (s.charAt(i) != '(' && s.charAt(i) != ')') continue; + + String t = s.substring(0, i) + s.substring(i + 1); + + if (!visited.contains(t)) { + // for each state, if it's not visited, add it to the queue + queue.add(t); + visited.add(t); + } + } + } + + return res; + } + + // helper function checks if string s contains valid parentheses + boolean isValid(String s) { + int count = 0; + + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '(') count++; + if (c == ')' && count-- == 0) return false; + } + + return count == 0; + } + + + public List removeInvalidParenthesesDFS(String s) { + List output = new ArrayList<>(); + removeHelper(s, output, 0, 0, '(', ')'); + return output; + } + + public void removeHelper(String s, List output, int iStart, int jStart, char openParen, char closedParen) { + int numOpenParen = 0, numClosedParen = 0; + for (int i = iStart; i < s.length(); i++) { + if (s.charAt(i) == openParen) numOpenParen++; + if (s.charAt(i) == closedParen) numClosedParen++; + if (numClosedParen > numOpenParen) { // We have an extra closed paren we need to remove + for (int j = jStart; j <= i; j++) // Try removing one at each position, skipping duplicates + if (s.charAt(j) == closedParen && (j == jStart || s.charAt(j - 1) != closedParen)) + // Recursion: iStart = i since we now have valid # closed parenthesis thru i. jStart = j prevents duplicates + removeHelper(s.substring(0, j) + s.substring(j + 1, s.length()), output, i, j, openParen, closedParen); + return; // Stop here. The recursive calls handle the rest of the string. + } + } + // No invalid closed parenthesis detected. Now check opposite direction, or reverse back to original direction. + String reversed = new StringBuilder(s).reverse().toString(); + if (openParen == '(') + removeHelper(reversed, output, 0, 0, ')', '('); + else + output.add(reversed); + } +} diff --git a/src/main/java/practiceproblems/parentheses/ScoreOfParentheses.java b/src/main/java/practiceproblems/parentheses/ScoreOfParentheses.java new file mode 100644 index 0000000..30f3d58 --- /dev/null +++ b/src/main/java/practiceproblems/parentheses/ScoreOfParentheses.java @@ -0,0 +1,43 @@ +package practiceproblems.parentheses; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * Idea : + *

+ * Idea is similar to other Balance Parentheses related problems. i.e we check the balance of ( and ) brackets. + *

+ * And whenever number of ) exceeds number of ( , we can say that it is unbalanced from start. + *

+ * And whenever number of ( exceeds number of ) , we can say that it is unbalanced from end ( this one is trivial). + *

+ * This can be done by incrementing when we see opening ( bracket and decrementing vice versa. + */ +public class ScoreOfParentheses { + public int scoreOfParentheses(String s) { + int cur = 0, result = 0; + Deque stack = new ArrayDeque<>(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '(') { + //cur is local variable. This line stores cur so that it could be retrieved later + stack.push(cur); + //From here a new function call starts. So reset cur + cur = 0; + } else if (c == ')') { + //Retrieve cur + cur = stack.pop(); + //calculate result based on result + if (s.charAt(i - 1) == '(') { + cur += 1; + } else { + cur += result * 2; + } + //store intermediate result + result = cur; + } + } + return result; + } +} diff --git a/src/practiceproblems/ValidParentheses.java b/src/main/java/practiceproblems/parentheses/ValidParentheses.java similarity index 94% rename from src/practiceproblems/ValidParentheses.java rename to src/main/java/practiceproblems/parentheses/ValidParentheses.java index f44a828..07f490a 100644 --- a/src/practiceproblems/ValidParentheses.java +++ b/src/main/java/practiceproblems/parentheses/ValidParentheses.java @@ -1,4 +1,4 @@ -package practiceproblems; +package practiceproblems.parentheses; import java.util.Stack; diff --git a/src/practiceproblems/ValidParenthesesString.java b/src/main/java/practiceproblems/parentheses/ValidParenthesesString.java similarity index 73% rename from src/practiceproblems/ValidParenthesesString.java rename to src/main/java/practiceproblems/parentheses/ValidParenthesesString.java index 2a47e06..97b0959 100644 --- a/src/practiceproblems/ValidParenthesesString.java +++ b/src/main/java/practiceproblems/parentheses/ValidParenthesesString.java @@ -1,19 +1,19 @@ -package practiceproblems; +package practiceproblems.parentheses; /** * Given a string containing only three types of characters: '(', ')' and '*', * write a function to check whether this string is valid. * We define the validity of a string by these rules: - * + *

* Any left parenthesis '(' must have a corresponding right parenthesis ')'. * Any right parenthesis ')' must have a corresponding left parenthesis '('. * Left parenthesis '(' must go before the corresponding right parenthesis ')'. * '*' could be treated as a single right parenthesis ')' or a single left parenthesis '(' or an empty string. * An empty string is also valid. - * + *

* Input: "(*))" * Output: True - * + *

* Input: "(*)" * Output: True */ @@ -42,4 +42,26 @@ public boolean checkValidString(String s) { } return cmin == 0; // Return true if can found `openCount == 0` in range [cmin, cmax] } + + public boolean checkValidStringAnother(String s) { + if (s.length() < 1) return true; + + int balance = 0; + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == ')') balance--; + else balance++; + + if (balance < 0) return false; + } + + if (balance == 0) return true; + balance = 0; + for (int i = s.length() - 1; i >= 0; i--) { + if (s.charAt(i) == '(') balance--; + else balance++; + if (balance < 0) return false; + + } + return true; + } } diff --git a/src/main/java/practiceproblems/prefixsum/IntervalsBetweenIdenticalElements.java b/src/main/java/practiceproblems/prefixsum/IntervalsBetweenIdenticalElements.java new file mode 100644 index 0000000..a22b325 --- /dev/null +++ b/src/main/java/practiceproblems/prefixsum/IntervalsBetweenIdenticalElements.java @@ -0,0 +1,54 @@ +package practiceproblems.prefixsum; + +import java.util.HashMap; +import java.util.Map; + +public class IntervalsBetweenIdenticalElements { + + /** + * https://leetcode.com/problems/intervals-between-identical-elements + * + * Consider 1's at different postions of an array. + * x y z p q + * 1 1 1 1 1 + * + * consider 1 at index z: |z - x| + |z - y| + |z - p| + |z - q| + * + * when we are looping from left to right we are storing sum and count of previous indices of num in maps. + * |z - x| + |z - y| = z - x + z - y, since z is greater than x and y. + * z - x + z - y = 2z - (x + y) = (count) * (currentIndex) - (sum). + * + * Similarly, we can calculate the |z - p| + |z - q| when we loop from right to left. + * + * @param arr + * @return + */ + public long[] getDistances(int[] arr) { + long[] output = new long[arr.length]; + Map sumMap = new HashMap<>(); + Map countMap = new HashMap<>(); + for (int i = 0; i < arr.length; ++i) { + long leftsum = sumMap.getOrDefault(arr[i], 0L); + int leftcount = countMap.getOrDefault(arr[i], 0); + + output[i] += i * (long) leftcount - leftsum; + sumMap.put(arr[i], leftsum + i); + countMap.put(arr[i], leftcount + 1); + } + + sumMap = new HashMap<>(); + countMap = new HashMap<>(); + int len = arr.length; + for (int i = len - 1; i >= 0; --i) { + //since now the current index goes from right to left, all of the prev would be greater than our current idx + long rightsum = sumMap.getOrDefault(arr[i], 0L); + int rightcount = countMap.getOrDefault(arr[i], 0); + + output[i] += rightsum - i * (long) rightcount; + sumMap.put(arr[i], rightsum + i); + countMap.put(arr[i], rightcount + 1); + } + + return output; + } +} diff --git a/src/main/java/practiceproblems/prefixsum/SubArrayDivisibleByP.java b/src/main/java/practiceproblems/prefixsum/SubArrayDivisibleByP.java new file mode 100644 index 0000000..fefdc2f --- /dev/null +++ b/src/main/java/practiceproblems/prefixsum/SubArrayDivisibleByP.java @@ -0,0 +1,52 @@ +package practiceproblems.prefixsum; + +import java.util.HashMap; + +/** + * https://leetcode.com/problems/make-sum-divisible-by-p/ + *

+ * Calculate the rem = sum(nums) % p, which means we need to remove a subarray which has sum % p == rem to make the rest sum divisible by p. + * It also requires that the removed subarray should be the shortest subarray. + * Then the questions become: Find the shortest array with sum(subarray) % p == rem. + * Since we need the shortest length, last[remainder] = idx records the last index that (A[0] + A[1] + ... + A[i]) % p == remainder. + * Everytime, we find a possible sum, we need get the right-most index to make sure that the subarray removed is the shortest. + * If there is no element what we want, then i - (-N) > N. Since we cannot remove the whole array, therefore, return res when res < N. + */ +public class SubArrayDivisibleByP { + + public static int minSubarray(int[] nums, int p) { + + int remainder = 0, prefixSum = 0; + for (int num : nums) { + remainder = (remainder + num) % p; + } + + if (remainder == 0) return 0; + + + int result = nums.length; + var prefixSumToIndex = new HashMap(); + prefixSumToIndex.put(0, -1); + + for (int i = 0; i < nums.length; i++) { + prefixSum = (prefixSum + nums[i]) % p; + + prefixSumToIndex.put(prefixSum, i); + + int key = (prefixSum - remainder + p) % p; //Avoid the case where prefixSum - remainder is negative + + if (prefixSumToIndex.containsKey(key)) { + result = Math.min(result, i - prefixSumToIndex.get(key)); + } + + + } + + return result == nums.length ? -1 : result; + + } + + public static void main(String[] args) { + minSubarray(new int[]{3,1,4,2},6); + } +} diff --git a/src/practiceproblems/SubArraySumDivisibleByK.java b/src/main/java/practiceproblems/prefixsum/SubArraySumDivisibleByK.java similarity index 70% rename from src/practiceproblems/SubArraySumDivisibleByK.java rename to src/main/java/practiceproblems/prefixsum/SubArraySumDivisibleByK.java index 04057a1..f8ce79c 100644 --- a/src/practiceproblems/SubArraySumDivisibleByK.java +++ b/src/main/java/practiceproblems/prefixsum/SubArraySumDivisibleByK.java @@ -1,15 +1,19 @@ -package practiceproblems; +package practiceproblems.prefixsum; import java.util.HashMap; import java.util.Map; /** - * Given an array A of integers, return the number of (contiguous, non-empty) - * subarrays that have a sum divisible by K. - * Input: A = [4,5,0,-2,-3,1], K = 5 - * Output: 7 - * Explanation: There are 7 subarrays with a sum divisible by K = 5: - * [4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3] + * let's take an array with random values and K=5 + * Si = sum till 0,.. ith pos + * Sj = sum till 0,..jth pos + * + * [x,x,x,x,x,x,x,x,x,x,x,x,x] + * Si Sj + * 22 52 + * at Si the remainder/surplus is 2 + * at Sj the remainder/surplus is still 2 + * that means in between the subarry i...j the sum is divisible by K */ public class SubArraySumDivisibleByK { @@ -35,11 +39,14 @@ public int subarraysDivByK(int[] A, int K) { // step 6 : {0:1,4:3,2:1} a=-3 sum=4 mod=4 count = 3+3 =6 // step 7 : {0:1,4:4,2:1} a=1 sum=5 mod=0 count = 6+1 =7 public int subarraysDivByKOptimised(int[] A, int K) { - int[] map = new int[K]; + int[] map = new int[K]; // this optimisation is when we do % we can have result at most K + map[0] = 1; int prefix = 0, res = 0; for (int a : A) { prefix = (prefix + a % K + K) % K; + // trick is to add the map[prefix] to result before incrementing it + res += map[prefix]; map[prefix]++; } diff --git a/src/practiceproblems/SubArraySumEqualsK.java b/src/main/java/practiceproblems/prefixsum/SubArraySumEqualsK.java similarity index 69% rename from src/practiceproblems/SubArraySumEqualsK.java rename to src/main/java/practiceproblems/prefixsum/SubArraySumEqualsK.java index 7dafb03..481e4c5 100644 --- a/src/practiceproblems/SubArraySumEqualsK.java +++ b/src/main/java/practiceproblems/prefixsum/SubArraySumEqualsK.java @@ -1,8 +1,11 @@ -package practiceproblems; +package practiceproblems.prefixsum; import java.util.HashMap; import java.util.Map; +/** + * https://leetcode.com/problems/subarray-sum-equals-k/ + */ public class SubArraySumEqualsK { public int subarraySum(int[] nums, int k) { int left = 0; @@ -40,18 +43,4 @@ public int subarraySum(int[] nums, int k) { } - public static int subarraySumDivByK(int[] nums, int K) { - int prefix = 0; - int result = 0; - Map count = new HashMap<>(); - count.put(0, 1); - - for (int a : nums) { - //(prefix+a%K+K)%K is just a trick to make the remainder positive. - prefix = (prefix + (a % K) + K) % K; - result += count.getOrDefault(prefix, 0); - count.put(prefix, count.getOrDefault(prefix, 0) + 1); - } - return result; - } } \ No newline at end of file diff --git a/src/main/java/practiceproblems/recursion/NQueens.java b/src/main/java/practiceproblems/recursion/NQueens.java new file mode 100644 index 0000000..766debe --- /dev/null +++ b/src/main/java/practiceproblems/recursion/NQueens.java @@ -0,0 +1,86 @@ +package practiceproblems.recursion; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * https://leetcode.com/problems/n-queens/ + *

+ * This is a perfect problem for backtracking - place the queens one by one, and when all possibilities are exhausted, + * backtrack by removing a queen and placing it elsewhere. + */ +public class NQueens { + + public List> solveNQueens(int n) { + if (n == 0) return Collections.emptyList(); + + List> result = new ArrayList<>(); + char[][] board = new char[n][n]; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + board[i][j] = '.'; + } + } + + nQueensHelper(0, n, board, result); + + return result; + } + + public void nQueensHelper(int row, int n, char[][] board, List> result) { + + if (row == board.length) { + result.add(construct(board)); + return; + } + for (int i = 0; i < n; i++) { + // check if it can be placed in current i(col) of the row and explore possibilities + if (isValidPlacement(row, i, board)) { + board[row][i] = 'Q'; // if yes proceed to next row and explore all possibilities + nQueensHelper(row + 1, n, board, result); + board[row][i] = '.'; + } + + } + + } + + public boolean isValidPlacement(int row, int col, char[][] chess) { + // check all cols + for (int i = 0; i < row; i++) { + if (chess[i][col] == 'Q') { + return false; + } + } + int x = row; + int y = col; + //checking for upper left diagonal(non-main diagonal), row is decreasing and col too + while (x >= 0 && y >= 0) { + if (chess[x][y] == 'Q') { + return false; + } + --x; + --y; + } + + //checking for main diagonal(upper right), row is decreasing and col increasing + while (row >= 0 && col < chess.length) { + if (chess[row][col] == 'Q') { + return false; + } + --row; + ++col; + } + return true; + } + + private List construct(char[][] chess) { + List path = new ArrayList<>(); + for (char[] chars : chess) { + path.add(new String(chars)); + } + return path; + } + +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/recursion/SudokuSolver.java b/src/main/java/practiceproblems/recursion/SudokuSolver.java new file mode 100644 index 0000000..61f6568 --- /dev/null +++ b/src/main/java/practiceproblems/recursion/SudokuSolver.java @@ -0,0 +1,87 @@ +package practiceproblems.recursion; + +import java.util.Arrays; + +/** + * tricky recursion + */ +public class SudokuSolver { + public void solveSudoku(char[][] board) { + solveBoard(board, 0, 0); + } + + private boolean solveBoard(char[][] board, int currentRow, int currentCol) { + for (int row = currentRow; row < 9; row++, currentCol = 0) { + for (int col = currentCol; col < 9; col++) { + if (board[row][col] == '.') { + for (char num = '1'; num <= '9'; num++) { + if (isValid(board, row, col, num)) { + board[row][col] = num; + if (solveBoard(board, row, col + 1)) { + return true; + } + board[row][col] = '.'; + } + } + + return false; + } + } + } + + return true; + } + + // Make sure the digit doesn't exist in the current row, col or square. + private boolean isValid(char[][] board, int row, int col, char num) { + int regionRow = (row / 3) * 3; //region start row + int regionCol = (col / 3) * 3; //region start col + for (int i = 0; i < 9; i++) { + // [regionRow + i / 3][regionCol + i % 3] check 3*3 block + if (board[i][col] == num || board[row][i] == num || board[regionRow + i / 3][regionCol + i % 3] == num) { + return false; + } + } + + return true; + } + + + /** + * start from 0 and go till 81 (9*9), for each cell do a dfs, if not backtrack and change the value + * + * @param board + */ + public void solveSudokuDFS(char[][] board) { + dfs(board, 0); + } + + private boolean dfs(char[][] board, int d) { + if (d == 81) return true; //found solution + int i = d / 9, j = d % 9; + if (board[i][j] != '.') return dfs(board, d + 1);//prefill number skip + + boolean[] flag = new boolean[10]; + validate(board, i, j, flag); + for (int k = 1; k <= 9; k++) { + if (flag[k]) { + board[i][j] = (char) ('0' + k); + if (dfs(board, d + 1)) return true; + } + } + board[i][j] = '.'; //if you can not solve, in the wrong path, change back to '.' and out + return false; + } + + // in arr[0..9] fill the values with numbers in row and col as false + private void validate(char[][] board, int i, int j, boolean[] flag) { + Arrays.fill(flag, true); + for (int k = 0; k < 9; k++) { + if (board[i][k] != '.') flag[board[i][k] - '0'] = false; + if (board[k][j] != '.') flag[board[k][j] - '0'] = false; + int r = i / 3 * 3 + k / 3; + int c = j / 3 * 3 + k % 3; + if (board[r][c] != '.') flag[board[r][c] - '0'] = false; + } + } +} diff --git a/src/main/java/practiceproblems/stack/AsteroidCollision.java b/src/main/java/practiceproblems/stack/AsteroidCollision.java new file mode 100644 index 0000000..3e473a8 --- /dev/null +++ b/src/main/java/practiceproblems/stack/AsteroidCollision.java @@ -0,0 +1,35 @@ +package practiceproblems.stack; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * https://leetcode.com/problems/asteroid-collision + */ +public class AsteroidCollision { + + public int[] asteroidCollision(int[] asteroids) { + if (asteroids.length <= 1) return asteroids; + Deque stack = new ArrayDeque<>(); + for (int asteroid : asteroids) { + if (asteroid > 0) { // Pushing all +ve asteroid + stack.push(asteroid); + } else { + // Remove all positive asteroid before our current asteroid + while (!stack.isEmpty() && stack.peek() > 0 && Math.abs(stack.peek()) < Math.abs(asteroid)) + stack.pop(); + // Checking if the stack is empty or the recent asteroid is negative! + if (stack.isEmpty() || stack.peek() < 0) + stack.push(asteroid); + // If recent asteroid <= our asteroid, We broke our outer loop if equal we pop it. + else if (stack.peek() == Math.abs(asteroid)) + stack.pop(); + } + } + int[] output = new int[stack.size()]; + for (int i = output.length - 1; i >= 0; i--) + output[i] = stack.pop(); + + return output; + } +} diff --git a/src/main/java/practiceproblems/stack/BasicCalculatorII.java b/src/main/java/practiceproblems/stack/BasicCalculatorII.java new file mode 100644 index 0000000..df06e63 --- /dev/null +++ b/src/main/java/practiceproblems/stack/BasicCalculatorII.java @@ -0,0 +1,49 @@ +package practiceproblems.stack; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * tricky sign maintenance + */ +public class BasicCalculatorII { + public static int calculate(String s) { + if (s == null || s.length() == 0) return 0; + + Deque stack = new ArrayDeque<>(); + int num = 0; + char sign = '+'; + int len = s.length(); + for (int i = 0; i < len; i++) { + if (Character.isDigit(s.charAt(i))) { + num = num * 10 + s.charAt(i) - '0'; + } + if ((!Character.isDigit(s.charAt(i)) && ' ' != s.charAt(i)) || i == len - 1) { + if (sign == '-') { + stack.push(-num); + } + if (sign == '+') { + stack.push(num); + } + if (sign == '*') { + stack.push(stack.pop() * num); + } + if (sign == '/') { + stack.push(stack.pop() / num); + } + sign = s.charAt(i); + num = 0; + } + } + + int re = 0; + for (int i : stack) { + re += i; + } + return re; + } + + public static void main(String[] args) { + System.out.println(calculate("10-4+3*2+10/5")); + } +} diff --git a/src/main/java/practiceproblems/stack/DailyTemperature.java b/src/main/java/practiceproblems/stack/DailyTemperature.java new file mode 100644 index 0000000..973f466 --- /dev/null +++ b/src/main/java/practiceproblems/stack/DailyTemperature.java @@ -0,0 +1,62 @@ +package practiceproblems.stack; + +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.Deque; + +public class DailyTemperature { + public static int[] dailyTemperatures(int[] temperatures) { + if (temperatures.length == 1) return new int[]{0}; + Deque stack = new ArrayDeque<>(); + int[] result = new int[temperatures.length]; + stack.push(new Pair(temperatures[temperatures.length - 1], 0)); + result[temperatures.length - 1] = 0; + for (int i = temperatures.length - 2; i >= 0; i--) { + int count = 0; + while (!stack.isEmpty() && stack.peek().temp <= temperatures[i]) { + count += stack.pop().count; + } + if (!stack.isEmpty() && stack.peek().temp > temperatures[i]) count++; + + // for case [55,38,53,81,61,93,97,32,43,78] 97 comes in middle then we have to eliminate all entries + // but the count is zero + if (stack.isEmpty()) count = 0; + result[i] = count; + stack.push(new Pair(temperatures[i], count)); + } + + return result; + } + + public int[] dailyTemperaturesOptimised(int[] temperatures) { + Deque stack = new ArrayDeque<>(); + int[] ret = new int[temperatures.length]; + for (int i = 0; i < temperatures.length; i++) { + while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) { + int idx = stack.pop(); + ret[idx] = i - idx; + } + stack.push(i); + } + return ret; + } + + public static void main(String[] args) { + int[][] inputs = new int[][]{{73, 74, 75, 71, 69, 72, 76, 73, + 30, 40, 50, 60, + 30, 60, 90, + 55, 38, 53, 81, 61, 93, 97, 32, 43, 78}}; + for (int[] input : inputs) + System.out.println(Arrays.toString(dailyTemperatures(input))); + } + + private static class Pair { + int temp; + int count; + + public Pair(int temp, int count) { + this.temp = temp; + this.count = count; + } + } +} diff --git a/src/practiceproblems/DecodeString.java b/src/main/java/practiceproblems/stack/DecodeString.java similarity index 55% rename from src/practiceproblems/DecodeString.java rename to src/main/java/practiceproblems/stack/DecodeString.java index 55058a9..ef55af9 100644 --- a/src/practiceproblems/DecodeString.java +++ b/src/main/java/practiceproblems/stack/DecodeString.java @@ -1,4 +1,4 @@ -package practiceproblems; +package practiceproblems.stack; import java.util.ArrayDeque; import java.util.Deque; @@ -10,39 +10,39 @@ public static String decodeString(String s) { if (s == null) return ""; - Deque count = new ArrayDeque<>(); - Deque result = new ArrayDeque<>(); + Deque countStack = new ArrayDeque<>(); + Deque characterStack = new ArrayDeque<>(); int start = 0; - StringBuilder tempResult = new StringBuilder(); + StringBuilder result = new StringBuilder(); while (start < s.length()) { - // whenever we see number, we push to count queue + // whenever we see number, we push to countStack if (Character.isDigit(s.charAt(start))) { int num = 0; while (Character.isDigit(s.charAt(start))) { num = num * 10 + s.charAt(start) - '0'; start++; } - count.push(num); + countStack.push(num); } else if (s.charAt(start) == '[') { - // whenever we see a open brace we push the string we have to result queue - result.push(tempResult.toString()); - tempResult = new StringBuilder(); + // whenever we see a open brace we push the string we have to characterStack + characterStack.push(result.toString()); + result = new StringBuilder(); start++; } else if (s.charAt(start) == ']') { - // whenever a closing brace comes, we pop the last seen count and last seen string - // and replicate that string and stores in temp result - StringBuilder sb = new StringBuilder(result.pop()); - int tempCount = count.pop(); - sb.append(tempResult.toString().repeat(tempCount)); - tempResult = sb; + // whenever a closing brace comes, we pop the last seen countStack and last seen string + // and replicate that string and stores in temp characterStack + StringBuilder sb = new StringBuilder(characterStack.pop()); + int tempCount = countStack.pop(); + sb.append(result.toString().repeat(tempCount)); + result = sb; start++; } else { - // whenever we see a char, we push to result string - tempResult.append(s.charAt(start++)); + // whenever we see a char, we push to characterStack string + result.append(s.charAt(start++)); } } - return tempResult.toString(); + return result.toString(); } public static void main(String[] args) { diff --git a/src/main/java/practiceproblems/stack/ExclusiveTIme.java b/src/main/java/practiceproblems/stack/ExclusiveTIme.java new file mode 100644 index 0000000..e4a0e2a --- /dev/null +++ b/src/main/java/practiceproblems/stack/ExclusiveTIme.java @@ -0,0 +1,46 @@ +package practiceproblems.stack; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.List; + +/** + * tricky revise TODO + * https://leetcode.com/problems/exclusive-time-of-functions/ + */ +public class ExclusiveTIme { + + public int[] exclusiveTime(int n, List logs) { + Deque stack = new ArrayDeque<>(); + int[] result = new int[n]; + for (String content : logs) { + Log log = new Log(content); + if (log.isStart) { + stack.push(log); + } else { + Log top = stack.pop(); + result[top.id] += (log.time - top.time + 1 - top.subDuration); + if (!stack.isEmpty()) { + stack.peek().subDuration += (log.time - top.time + 1); + } + } + } + + return result; + } + + public static class Log { + public int id; + public boolean isStart; + public int time; + public int subDuration; + + public Log(String content) { + String[] strs = content.split(":"); + id = Integer.parseInt(strs[0]); + isStart = strs[1].equals("start"); + time = Integer.parseInt(strs[2]); + subDuration = 0; + } + } +} diff --git a/src/main/java/practiceproblems/stack/MaxHistogram.java b/src/main/java/practiceproblems/stack/MaxHistogram.java new file mode 100644 index 0000000..491a55a --- /dev/null +++ b/src/main/java/practiceproblems/stack/MaxHistogram.java @@ -0,0 +1,104 @@ +package practiceproblems.stack; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * https://leetcode.com/problems/largest-rectangle-in-histogram/ + */ + +public class MaxHistogram { + + /** + * Lets start by thinking of a brute force, naive solution. + * Pick two bars and find the maxArea between them and compare that to your global maxArea. + * To do that, you’ll need to find the bar that “restricts” the height of the forming rectangle to its own height - + * i.e; the bar with the minimum height between two bars. + * + * @param heights + * @return + */ + public int largestRectangleAreaBruteForce(int[] heights) { + if (heights.length == 1) return heights[0]; + int area = 0; + for (int i = 0; i < heights.length; i++) { + int min = heights[i]; + for (int j = i; j < heights.length; j++) { + min = Math.min(min, heights[j]); + area = Math.max(area, ((j - i + 1) * min)); + } + } + + return area; + } + + /** + * https://abhinandandubey.github.io/posts/2019/12/15/Largest-Rectangle-In-Histogram.html + * Because if the length of the array is n, the largest possible rectangle has to have a height one of the elements of the array, + * that is to say, there are only n possible largest rectangles. + * So we don't really need to go through every pair of bars, but should rather search by the height of the bar. + * + * Why Stack? + * At each step we need the information of previously seen "candidate" bars - bars which give us hope. + * These are the bars of increasing heights. + * And since they'll need to be put in the order of their occurrence, stack should come to your mind. + * + * Lets take the example [2, 1, 5, 6, 2, 3] + * + * The first bar we see is the bar at position 0 of height 2. + * It is definitely as "candidate bar" as it gives us hope of finding a larger rectangle, so we just add it to the stack. + * The next one we see is the bar at position 1 with height 1. + * At this point, we look at the stack and see that the "candidate bar" at the top of the stack is of height 2, + * and because of this 1, we definitely can't do a rectangle of height 2 now, + * so the only natural thing to do at this point is to pop it out of the stack, + * and see what area it could have given us. + * + * After adding 1,5,6 to the stack hoping to find bigger rectangle we hit at 2 which is smaller than 6 + * At this point it should be clear that we only pop from the stack when + * height of the current bar is lower than the height of the bar at the top of the stack. + * so lets see what it can give us and pop it out. + * The height of this rectangle is 6, and the width is i−stack[peek()]−1=> 4−2−1 => 1. + */ + public static int largestRectangleArea(int[] heights) { + if (heights.length == 1) return heights[0]; + int area = 0; + int result = 0; + Deque stack = new ArrayDeque<>(); + int i = 0; + while (i < heights.length) { + + if (stack.isEmpty() || heights[stack.peekLast()] <= heights[i]) { + stack.addLast(i++); + } else { + int top = stack.removeLast(); + if (stack.isEmpty()) { + area = heights[top] * i; + } else { + area = heights[top] * (i - stack.peekLast() - 1); + + } + + result = Math.max(result, area); + } + + } + + while (!stack.isEmpty()) { + int top = stack.removeLast(); + if (stack.isEmpty()) { + area = heights[top] * i; + } else { + area = heights[top] * (i - stack.peekLast() - 1); + } + result = Math.max(result, area); + } + + return result; + } + + + public static void main(String[] args) { + int[] arr = new int[]{2, 1, 5, 6, 2, 3}; + System.out.println(largestRectangleArea(arr)); + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/stack/MaxSubarrMinProduct.java b/src/main/java/practiceproblems/stack/MaxSubarrMinProduct.java new file mode 100644 index 0000000..58739d5 --- /dev/null +++ b/src/main/java/practiceproblems/stack/MaxSubarrMinProduct.java @@ -0,0 +1,99 @@ +package practiceproblems.stack; + +import java.util.ArrayDeque; +import java.util.Deque; + +public class MaxSubarrMinProduct { + /** + * The main idea is + * As we want to find min-product, calculating minimum number from all sub arrays gives us TLE + * So what we do is, we consider nums[i] where 0<=i< n, + * as min element and find the min-products of subarrays with minimum as nums[i]. + * + * left_max_index: index of the farthest element greater or equal to nums[i] in the left side + * right_max_index: index of the farthest element greater or equal to nums[i] in the right side + * + * Then we find the prefix sum of given input array. + * Then we find the number of largest numbers to the left in "array left" (left_max_index) + * and number of largest numbers to the right in "array right" with nums[i] as minimum. (right_max_index) + * + * After finding that, now its become simple, as we know the length of sub array with nums[i] as minimum. + * + * nums = [3,1,5,6,4,2] + *

+ * indices: [0, 1, 2, 3, 4, 5] + * input: [3, 1, 5, 6, 4, 2] + * left: [0, 0, 2, 3, 2, 2] + * right: [0, 5, 3, 3, 4, 5] + * prefixSum: [3, 4, 9, 15, 19, 21] + */ + public int maxSumMinProductEff(int[] nums) { + int n = nums.length; + long max = -1; + long[] prefix = new long[n + 1]; + for (int i = 1; i < prefix.length; i++) { + prefix[i] = prefix[i - 1] + nums[i - 1]; + } + Deque s1 = new ArrayDeque<>(); + Deque s2 = new ArrayDeque<>(); + int[] leftMaxIndex = new int[n]; + int[] rightMaxIndex = new int[n]; + for (int i = 0; i < n; i++) { + while (!s1.isEmpty() && nums[s1.peek()] >= nums[i]) { + s1.pop(); + } + if (s1.isEmpty()) { + leftMaxIndex[i] = -1; + } else { + leftMaxIndex[i] = s1.peek(); + } + s1.push(i); + } + for (int i = n - 1; i >= 0; i--) { + while (!s2.isEmpty() && nums[s2.peek()] >= nums[i]) { + s2.pop(); + } + if (s2.isEmpty()) { + rightMaxIndex[i] = n; + } else { + rightMaxIndex[i] = s2.peek(); + } + s2.push(i); + } + + for (int i = 0; i < n; i++) { + int leftIndex = leftMaxIndex[i]; + int rightIndex = rightMaxIndex[i]; + int min = nums[i]; + + // range sum technique + long subArraySum = prefix[rightIndex] - prefix[leftIndex + 1]; + long maxSubArrMinProduct = min * subArraySum; + max = Math.max(max, maxSubArrMinProduct); + } + return (int) (max % 1_000_000_007); + } + + + public static int maxSumMinProduct(int[] nums) { + int mod = (int) Math.pow(10, 9) + 7; + + int result = 0; + + for (int i = 0; i < nums.length; i++) { + int min = nums[i]; + int sum = nums[i]; + for (int j = i + 1; j < nums.length; j++) { + + min = Math.min(nums[j], min); + sum += nums[j]; + + result = Math.max(result, sum * min); + } + + System.out.println(result); + } + + return result % mod; + } +} diff --git a/src/main/java/practiceproblems/stack/NextGreaterElement.java b/src/main/java/practiceproblems/stack/NextGreaterElement.java new file mode 100644 index 0000000..b510aee --- /dev/null +++ b/src/main/java/practiceproblems/stack/NextGreaterElement.java @@ -0,0 +1,133 @@ +package practiceproblems.stack; + +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.Deque; +import java.util.HashMap; +import java.util.Stack; + +/** + * https://www.geeksforgeeks.org/next-greater-element/ + *

+ * https://www.geeksforgeeks.org/find-next-greater-number-set-digits/ + */ +class NextGreaterElement { + + static int arr[] = {1, 3, 4, 2}; + + // 9,1,2,3,4,5,6,7 + public static void printNGE() { + Stack s = new Stack<>(); + int[] nge = new int[arr.length]; + + for (int i = arr.length - 1; i >= 0; i--) { + + while (!s.empty() && s.peek() <= arr[i]) { + s.pop(); + } + nge[i] = s.empty() ? -1 : s.peek(); + s.push(arr[i]); + + } + for (int i = 0; i < arr.length; i++) + System.out.println(arr[i] + " --> " + nge[i]); + + } + + // Input: nums1 = [4,1,2], nums2 = [1,3,4,2]. + // Output: [-1,3,-1] + // Explanation: + // For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1. + // For number 1 in the first array, the next greater number for it in the second array is 3. + // For number 2 in the first array, there is no next greater number for it in the second array, so output -1. + public int[] nextGreaterElement(int[] findNums, int[] nums) { + int[] ret = new int[findNums.length]; + ArrayDeque stack = new ArrayDeque<>(); + HashMap map = new HashMap<>(); + for (int i = nums.length - 1; i >= 0; i--) { + while (!stack.isEmpty() && stack.peek() <= nums[i]) { + stack.pop(); + } + if (stack.isEmpty()) map.put(nums[i], -1); + else map.put(nums[i], stack.peek()); + stack.push(nums[i]); + } + for (int i = 0; i < findNums.length; i++) { + ret[i] = map.get(findNums[i]); + } + return ret; + } + + public int[] nextGreaterElementBruteForce(int[] nums1, int[] nums2) { + HashMap hash = new HashMap<>(); + for (int i = 0; i < nums2.length; i++) { + hash.put(nums2[i], i); + } + + int[] res = new int[nums1.length]; + int j; + + for (int i = 0; i < nums1.length; i++) { + for (j = hash.get(nums1[i]) + 1; j < nums2.length; j++) { + if (nums1[i] < nums2[j]) { + res[i] = nums2[j]; + break; + } + } + if (j == nums2.length) { + res[i] = -1; + } + } + + return res; + } + + // Input: [1,2,1] + // Output: [2,-1,2] + // Explanation: The first 1's next greater number is 2 + // The number 2 can't find next greater number; + // The second 1's next greater number needs to search circularly, which is also 2. + public static int[] nextGreaterElementCircular(int[] nums) { + if (nums == null || nums.length == 0) return new int[0]; + int[] result = new int[nums.length]; + Arrays.fill(result, -1); + Deque deque = new ArrayDeque<>(); + // to mimic the circular array we iterate for 2*n because input [1,2,1] will be like [1,2,1,1,2,1] + // and we take mod of 'n' to update the correct index + for (int i = 2 * nums.length - 1; i >= 0; --i) { + + while (!deque.isEmpty() && nums[deque.peek()] <= nums[i % nums.length]) { + deque.pop(); + } + // The stack is either empty, when no "greater element" is found to the right of nums[i], + // or contains the next greater element of nums[i] at the top. + result[i % nums.length] = deque.isEmpty() ? -1 : nums[deque.peek()]; + + // Push i into stack, so that nums[i-1] will compare with nums[i] first, before falling back to + // the next greater element of nums[i] + deque.push(i % nums.length); + } + + return result; + } + public int[] nextGreaterElementCircularBruteForce(int[] nums) { + int[] res = new int[nums.length]; + int[] doublenums = new int[nums.length * 2]; + System.arraycopy(nums, 0, doublenums, 0, nums.length); + System.arraycopy(nums, 0, doublenums, nums.length, nums.length); + for (int i = 0; i < nums.length; i++) { + res[i]=-1; + for (int j = i + 1; j < doublenums.length; j++) { + if (doublenums[j] > doublenums[i]) { + res[i] = doublenums[j]; + break; + } + } + } + return res; + } + + public static void main(String[] args) { + printNGE(); + } +} diff --git a/src/main/java/practiceproblems/stack/Pattern132.java b/src/main/java/practiceproblems/stack/Pattern132.java new file mode 100644 index 0000000..22315f5 --- /dev/null +++ b/src/main/java/practiceproblems/stack/Pattern132.java @@ -0,0 +1,74 @@ +package practiceproblems.stack; + +import java.util.ArrayDeque; +import java.util.Deque; + +public class Pattern132 { + + // record minimum till j and iterate from the end to find a max value which is + // greater the minimum(i) and smaller than j + // O(N^2) + public boolean find132pattern(int[] nums) { + int min = Integer.MAX_VALUE; // stores the min value till j + for (int j = 0; j < nums.length; j++) { + min = Math.min(nums[j], min); + if (min == nums[j]) continue; // if min and j are same move to next element + + for (int k = nums.length - 1; k > j; k--) { + if (min < nums[k] && nums[k] < nums[j]) return true; // condition to be satisfied + } + } + return false; + } + + /** + * Create a stack and initialize a variable second with INT_MIN value. + * Start traversing from the end of array. + * Check if the current number is lesser than second. If it is, then it means our 132 pattern is satisfied as the stack is taking care of the 32 pattern and the current number satisfies the entire pattern. So return true. + * If the above is not true, update the peak value in the stack. Keep popping from the stack until stack is empty OR the top value is greater than the current value. + * Push the current number into the stack. + * If the loop terminates, it means that the pattern was not found in the array. So, return false. + *

+ * Take the sample input as [3, 6, 4, 1, 2] + * Basically, the top of stack is containing the highest number so far, i.e. 3 and + * second is containing the second highest number after the highest number, i.e. 2. + * So, this satisfies the 32 pattern. Now, we will just keep updating second and stack top when we encounter a number + * which is greater than the highest number. + */ + public static boolean find132patternEffective(int[] nums) { + Deque maxStack = new ArrayDeque<>(); + int minValue = Integer.MIN_VALUE; + + for (int i = nums.length - 1; i >= 0; i--) { + if (nums[i] < minValue) return true; + while (!maxStack.isEmpty() && maxStack.peek() < nums[i]) { + minValue = maxStack.pop(); + } + maxStack.push(nums[i]); + } + + return false; + } + + public boolean find132patternMinArr(int[] nums) { + int n = nums.length; + int[] mins = new int[n]; + mins[0] = nums[0]; + for (int i = 1; i < n - 1; i++) { + mins[i] = Math.min(nums[i], mins[i - 1]); + } + Deque stk = new ArrayDeque<>(); + for (int i = n - 1; i > 0; i--) { + while (!stk.isEmpty() && nums[i] > stk.peek()) { + if (stk.peek() > mins[i - 1]) return true; + stk.pop(); + } + stk.push(nums[i]); + } + return false; + } + + public static void main(String[] args) { + System.out.println(find132patternEffective(new int[]{3, 5, 0, 3, 4})); + } +} diff --git a/src/practiceproblems/RemoveKDigits.java b/src/main/java/practiceproblems/stack/RemoveKDigits.java similarity index 98% rename from src/practiceproblems/RemoveKDigits.java rename to src/main/java/practiceproblems/stack/RemoveKDigits.java index d218206..c77381a 100644 --- a/src/practiceproblems/RemoveKDigits.java +++ b/src/main/java/practiceproblems/stack/RemoveKDigits.java @@ -1,4 +1,4 @@ -package practiceproblems; +package practiceproblems.stack; import java.util.ArrayDeque; import java.util.Deque; diff --git a/src/main/java/practiceproblems/stack/SmallestLexicoSubSeq.java b/src/main/java/practiceproblems/stack/SmallestLexicoSubSeq.java new file mode 100644 index 0000000..88062c5 --- /dev/null +++ b/src/main/java/practiceproblems/stack/SmallestLexicoSubSeq.java @@ -0,0 +1,46 @@ +package practiceproblems.stack; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/ + * https://leetcode.com/problems/remove-duplicate-letters/ + */ +public class SmallestLexicoSubSeq { + + /** + * Question is asking sequence without duplicates but in sorted order + * The Characters Which are unique will remain in the same order. + * If we have pushed a unique character then there is no benefit of changing element before unique character. + * + * So we process character by character in to a stack + * if we find a character which is smaller that stack's peek, we check if we are going to encounter it again by having lastPos array + * |--> if yes then we pop from stack and remove from used arr, so we can process the duplicate which will give smaller string + * + */ + public String smallestSubsequence(String s) { + int[] lastPos = new int[26]; + boolean[] used = new boolean[26]; + int n = s.length(); + for (int i = 0; i < n; i++) + lastPos[s.charAt(i) - 'a'] = i; + + Deque stack = new ArrayDeque<>(); + for (int i = 0; i < n; i++) { + int c = s.charAt(i) - 'a'; + if (used[c]) continue; + // if stack has larger value and lastPos of that larger value is not yet reached we pop and place smaller char + while (!stack.isEmpty() && stack.peekLast() >= c && lastPos[stack.peekLast()] > i) { + used[stack.pollLast()] = false; + } + used[c] = true; + stack.push(c); + } + + StringBuilder sb = new StringBuilder(); + while (!stack.isEmpty()) + sb.append((char) (stack.poll() + 'a')); + return sb.toString(); + } +} diff --git a/src/main/java/practiceproblems/stack/SortStack.java b/src/main/java/practiceproblems/stack/SortStack.java new file mode 100644 index 0000000..55b0085 --- /dev/null +++ b/src/main/java/practiceproblems/stack/SortStack.java @@ -0,0 +1,19 @@ +package practiceproblems.stack; + +import java.util.Stack; + +public class SortStack { + // Input : [34, 3, 31, 98, 92, 23] + // Output : [3, 23, 31, 34, 92, 98] + public static void stackSorting(Stack stack) { + Stack tempStack = new Stack<>(); + while (!stack.isEmpty()) { + int item = stack.pop(); + while (!tempStack.isEmpty() && tempStack.peek() > item) { + stack.push(tempStack.pop()); + } + tempStack.push(item); + } + while (!tempStack.isEmpty()) stack.push(tempStack.pop()); + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/stack/StockSpanner.java b/src/main/java/practiceproblems/stack/StockSpanner.java new file mode 100644 index 0000000..69e6db7 --- /dev/null +++ b/src/main/java/practiceproblems/stack/StockSpanner.java @@ -0,0 +1,27 @@ +package practiceproblems.stack; + + +import javafx.util.Pair; + +import java.util.ArrayDeque; +import java.util.Deque; + +class StockSpanner { + + Deque> stack; + + public StockSpanner() { + this.stack = new ArrayDeque<>(); + } + + public int next(int price) { + int value = 1; + while (!stack.isEmpty() && stack.peek().getKey() <= price) { + value += stack.pop().getValue(); + } + + stack.push(new Pair(price, value)); + + return stack.peek().getValue(); + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/stack/SumOfMinSubArrays.java b/src/main/java/practiceproblems/stack/SumOfMinSubArrays.java new file mode 100644 index 0000000..30c3c0a --- /dev/null +++ b/src/main/java/practiceproblems/stack/SumOfMinSubArrays.java @@ -0,0 +1,112 @@ +package practiceproblems.stack; + +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.Deque; + +/** + * https://leetcode.com/problems/sum-of-subarray-minimums/ + *

+ * https://www.youtube.com/watch?v=Ulb3ixSpE4Y&ab_channel=AnuragCodes + */ +public class SumOfMinSubArrays { + + public static void main(String[] args) { + sumSubarrayMins(new int[]{5, 3, 4, 1, 2, 7}); + } + + public static int sumSubarrayMins(int[] arr) { + int length = arr.length; + long mod = (long) 1e9 + 7; + long result = 0; + Deque previousLess = new ArrayDeque<>(); + Deque nextLess = new ArrayDeque<>(); + int[] left = new int[length]; + int[] right = new int[length]; + // previous less element - imagine 2, 5, 6, 5 you don't want to double count so you can either enforce the = on the left or right array. + for (int i = 0; i < length; i++) { + while (!previousLess.isEmpty() && previousLess.peek()[0] >= arr[i]) { + previousLess.pop(); + } + // i - previousLess.peek()[1] similar to histogram problem + //For example [7 8 4 3], there is no Prev Left Element for element 4, so left[2] = 2+1 =3. + left[i] = previousLess.isEmpty() ? i + 1 : i - previousLess.peek()[1]; + previousLess.push(new int[]{arr[i], i}); + } + // left[i] corresponds => for the subarray size left[i] the current element arr[i] is the minimum + // the arr[3]=>1 is having left[i]=4 means for the subarray length size 4 to the left, 1 is minimum; + // [5, 3, 4, 1, 2, 7] + // [1, 2, 1, 4, 1, 1] + System.out.println(Arrays.toString(left)); + // next less element. for this we do reverse traversal + for (int i = length - 1; i >= 0; i--) { + while (!nextLess.isEmpty() && nextLess.peek()[0] > arr[i]) { + nextLess.pop(); + } + right[i] = nextLess.isEmpty() ? length - i : nextLess.peek()[1] - i; + nextLess.push(new int[]{arr[i], i}); + } + System.out.println(Arrays.toString(right)); + + /** + * Generally there are (N*N+1)/2 sub arrays in a given array, + * to find out the number of sub arrays the arr[i] to be present in + * we calculate using arr[i]*leftLength*rightLength + * + * example: [5, 3, 4, 1, 2, 7] total subarrays = 6*(6+1)/2 = 21 + * excluding 1 from above we have the left part [5,3,4] => 3*4/2 = 6 + * excluding 1 from above we have the right part [2,7] => 2*3/2 = 3 + * so out of 21, the arr[3]= 1 will be part of only 21-6+3 sub arrays = 12 + * + * the reason to multiply arr[i] is to get total sum + * + * How much the element 2 contributes to the final answer? + * Since we want to add the minimum from each subarray. + * In this case in the 12 subarrays, 1 is the minimum, so it will contribute 1*12 i.e. 12. + * if the min is 2 then it will be 2*12= 24 + */ + for (int i = 0; i < length; i++) { + result = (result + (long) arr[i] * left[i] * right[i]) % mod; + } + return (int) result; + } + + public int sumSubarrayMinsTLE(int[] arr) { + if (arr.length == 1) return arr[0]; + int mod = (int) Math.pow(10, 9) + 7; + + int result = 0; + for (int i = 0; i < arr.length; i++) { + int min = arr[i]; + for (int j = i; j < arr.length; j++) { + min = Math.min(min, arr[j]); + result += min; + result %= mod; + } + } + return result; + + } + + public int sumSubarrayMinsMLE(int[] arr) { + if (arr.length == 1) return arr[0]; + int mod = (int) Math.pow(10, 9) + 7; + int[][] dp = new int[arr.length][arr.length]; + int result = 0; + for (int i = 0; i < arr.length; i++) { + dp[i][i] = arr[i]; + result += dp[i][i]; + } + + for (int l = 1; l < arr.length; l++) { + for (int i = 0; i < arr.length - l; i++) { + int j = i + l; + dp[i][j] = Math.min(dp[i + 1][j] % mod, dp[i][j - 1] % mod); + result += dp[i][j]; + result %= mod; + } + } + + return result; + } +} diff --git a/src/main/java/practiceproblems/stack/WaterTrapping.java b/src/main/java/practiceproblems/stack/WaterTrapping.java new file mode 100644 index 0000000..e45d5db --- /dev/null +++ b/src/main/java/practiceproblems/stack/WaterTrapping.java @@ -0,0 +1,91 @@ +package practiceproblems.stack; + +/** + * pseudocode : GetTotalWater(H) + * total <- 0 + * for every i in H + * leftMax <- findMax(0,i); + * rightMax <- findMax(i,n); + * permissibleWaterStored <- min(leftMax,rightMax); + * waterStored <- permissibleWaterStored-H[i]; + * total <- total+waterStored; + * return total; + */ +class WaterTrapping { + + public static int trap(int[] height) { + + int[] maxLeft = new int[height.length]; + int[] maxRight = new int[height.length]; + int maxHeight = 0; + int minHeight = 0; + + for (int i = 0; i < height.length; i++) { + maxHeight = Math.max(maxHeight, height[i]); + maxLeft[i] = maxHeight; + + } + maxHeight = 0; + for (int i = height.length - 1; i >= 0; i--) { + maxHeight = Math.max(maxHeight, height[i]); + maxRight[i] = maxHeight; + } + int result = 0; + for (int i = 0; i < height.length; i++) { + minHeight = Math.min(maxLeft[i], maxRight[i]); + height[i] = Math.max(0, minHeight - height[i]); + result += height[i]; + } + + return result; + + } + + /** + * https://www.youtube.com/watch?v=EdR3V5DBgyo + * + * @param height + * @return + */ + public int trapAnother(int[] height) { + if (height == null || height.length == 0) { + return 0; + } + int left = 0; + int right = height.length - 1; // Pointers to both ends of the array. + int maxLeft = 0; + int maxRight = 0; + + int totalWater = 0; + while (left < right) { + // Water could, potentially, fill everything from left to right, if there is nothing in between. + if (height[left] <= height[right]) { + // If the current elevation is greater than the previous maximum, water cannot occupy that point at all. + // However, we do know that everything from maxLeft to the current index, has been optimally filled, as we've + // been adding water to the brim of the last maxLeft. + maxLeft = Math.max(maxLeft, height[left]); + totalWater += maxLeft - height[left]; + + // Increment left, we'll now look at the next point. + left++; + // If the height at the left is NOT greater than height at the right, we cannot fill from left to right without over- + // flowing; however, we do know that we could potentially fill from right to left, if there is nothing in between. + } else { + // Similarly to above, we see that we've found a height greater than the max, and cannot fill it whatsoever, but + // everything before is optimally filled + maxRight = Math.max(maxRight, height[right]); + totalWater += maxRight - height[right]; + + // Decrement left, we'll look at the next point. + right--; + } + } + // Return the sum we've been adding to. + return totalWater; + } + + public static void main(String[] args) { + int[] arr = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1}; + System.out.println("Maximum water that " + "can be accumulated is " + trap(arr)); + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/sweepline/MaxSumRangeQuery.java b/src/main/java/practiceproblems/sweepline/MaxSumRangeQuery.java new file mode 100644 index 0000000..0de998d --- /dev/null +++ b/src/main/java/practiceproblems/sweepline/MaxSumRangeQuery.java @@ -0,0 +1,75 @@ +package practiceproblems.sweepline; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/maximum-sum-obtained-of-any-permutation + *

+ * Idea is to find the frequencies/(number of times an index appear + * in the requests) and then keep the maximum number from input array + * in the max frequency index and so on. + *

+ * Example: input array [1,2,3,4,5] requests [[1,3],[0,1]] + * frequencyOfRequests =[1,2,1,1,0]; + *

+ * Since we are trying to get maximum sum we have to position max number in the input array in the index such that, + * index has maximum frequency. + * Now sort the input array and frequencyOfRequests so that we will have max number and max frequency in first indexes. + * After sorting: + * input array = [5,4,3,2,1] + * frequencyOfRequests =[2,1,1,1,0]; + *

+ * for i in input array { + * sum += inputArray[i] * frequencyOfRequests[i] + * since sum can be very large and can cause overflow int; sum = sum % (10^9 + 7); + * }; + *

+ * frequencyOfRequests can be found by iterating every request from start to end and mark the inputArray[index]++; in this case Time = * O(inputArray.size) * O(request.size) but with marking start index with +1 and (end + 1) index with -1 Time = (requests.size) * (1); + *

+ * Time - r + n + nlog(n) + flog(f) + n -> O(nlog(n)) + * Space - O(n) for storing frequencies. + */ +public class MaxSumRangeQuery { + + public static int maxSumRangeQuery(int[] nums, int[][] requests) { + + int[] freq = new int[nums.length]; + long mod = (long) 1e9 + 7; + long res = 0; + int n = nums.length; + /* + Mark start and ends of requests with +1 and -1 + Imagine that you had intervals [1:3], [3:5]. + For each mark boundaries only to avoid complexity raise (TLE) on a wide interval as you do nothing with values + inside the interval and ignore it quantity. + t[start] +=1 means every index after this one will be counted 1 more time, + t[end+1] -= 1, means every index this one will be counted 1 less time + after [1:3] : [0, 1(+1), 0, 0, -1(-1), 0, 0] + after [3:5] : [0, 1, 0, 1(+1), -1, 0, -1(-1)] + Then after all intervals start|end+1 marking we can set the final frequency in one pass. + So the prefix sum of t will correspond to the number of requests for each index. + for i in range(1, n): + count[i] += count[i - 1] + It will become + [0, 1, 0, 1, -1, 0, -1] -> [0, 1, 1, 2, 1, 1, 0] + As you can see 3rd element occurred 2 times 1,2,4,5 1 time and others 0 time + */ + for (int[] r : requests) { + freq[r[0]] += 1; + if (r[1] + 1 < n) + freq[r[1] + 1] -= 1; + } + for (int i = 1; i < n; ++i) + freq[i] += freq[i - 1]; + Arrays.sort(nums); + Arrays.sort(freq); + for (int i = 0; i < n; i++) + res += (long) nums[i] * freq[i]; + return (int) (res % mod); + + } + + public static void main(String[] args) { + maxSumRangeQuery(new int[]{1, 2, 3, 4, 5}, new int[][]{{1, 3}, {0, 1}}); + } +} diff --git a/src/main/java/practiceproblems/sweepline/ModifyArray.java b/src/main/java/practiceproblems/sweepline/ModifyArray.java new file mode 100644 index 0000000..2152170 --- /dev/null +++ b/src/main/java/practiceproblems/sweepline/ModifyArray.java @@ -0,0 +1,42 @@ +package practiceproblems.sweepline; + +/** + * https://leetcode.com/problems/range-addition/ + * https://leetcode.com/problems/corporate-flight-bookings/ + * + * e.g. n =5 , [1,3,2] [2,4,3] [0,2,-2] + * + * idx: 0 1 2 3 4 + * nbr: 1 2 3 4 5 + * -------------------------------------------------------- + * [1,3,2] +2 -2 + * [2,4,3] +3 -3 + * [0,2,-2] -2 +2 + * -------------------------------------------------------- + * Sum: -2 2 3 2 -2 + * PrefixSum: -2 0 3 5 3 + */ +public class ModifyArray { + + public int[] getModifiedArray(int length, int[][] updates) { + + int[] result = new int[length]; + + for (int[] update : updates) { + int val = update[2]; + int start = update[0]; + int end = update[1]; + + result[start] += val; + if (end < length - 1) { + result[end + 1] -= val; + } + } + + + for (int i = 1; i < length; i++) { + result[i] += result[i - 1]; + } + return result; + } +} diff --git a/src/main/java/practiceproblems/tries/LongestRepeatingSubstring.java b/src/main/java/practiceproblems/tries/LongestRepeatingSubstring.java new file mode 100644 index 0000000..43d1b63 --- /dev/null +++ b/src/main/java/practiceproblems/tries/LongestRepeatingSubstring.java @@ -0,0 +1,37 @@ +package practiceproblems.tries; + +/** + * https://leetcode.com/problems/longest-repeating-substring + * // revise tricky + */ +public class LongestRepeatingSubstring { + + + public int longestRepeatingSubstring(String S) { + char[] A = S.toCharArray(); + int res = 0; + TrieNode root = new TrieNode(); + for (int i = 0; i < S.length(); i++) { + TrieNode cur = root; + for (int j = i; j < S.length(); j++) { + if (cur.next[A[j] - 'a'] == null) { + TrieNode newNode = new TrieNode(); + cur.next[A[j] - 'a'] = newNode; + cur = newNode; + } else { + res = Math.max(res, j - i + 1); + cur = cur.next[A[j] - 'a']; + } + } + } + return res; + } + + class TrieNode { + TrieNode[] next; + + public TrieNode() { + next = new TrieNode[26]; + } + } +} diff --git a/src/main/java/practiceproblems/tries/MapSum.java b/src/main/java/practiceproblems/tries/MapSum.java new file mode 100644 index 0000000..f688b27 --- /dev/null +++ b/src/main/java/practiceproblems/tries/MapSum.java @@ -0,0 +1,102 @@ +package practiceproblems.tries; + +import java.util.HashMap; +import java.util.Map; + +/** + * https://leetcode.com/problems/map-sum-pairs/ + * https://www.youtube.com/watch?v=AaMIYNdOz8w&ab_channel=NareshGupta + * + * brute force approach is add all the key value to a map + * + * for every sum(prefix) call: + * iterate -> map + * -> map.key.startsWith(prefix) add it to sum + * -> return sum + */ +public class MapSum { + + TrieNode root; + /** + * Initialize your data structure here. + */ + Map sumStorage; + + public MapSum() { + root = new TrieNode(); + sumStorage = new HashMap<>(); + } + + /** + * sumStorage is used to track the changes of the existing keys + * + * this is going to update all the chars in the path with value apple,5 + * diff is initially 5 + * apple -> 5 + * a -> 5 + * | + * ap -> 5 + * | + * app -> 5 + * | + * appl -> 5 + * | + * apple -> 5 + * + * if we get a new key app,2 + * diff will be 2 initially + * a -> 5+2 + * | + * p -> 5+2 + * | + * ap -> 5 +2 + * | + * app -> 5 + 2 + * | + * appl -> 5 + * | + * apple -> 5 + * + * after some time if we get apple , 3 + * we get difference as 3-(map.get('apple')) = 3-5 = -2 + * we add the diff to all the elements + */ + + + + public void insert(String key, int val) { + TrieNode head = root; + int diff = val - sumStorage.getOrDefault(key, 0); + sumStorage.put(key, val); + + for (char c : key.toCharArray()) { + head.children.putIfAbsent(c, new TrieNode()); + head = head.children.get(c); + head.value += diff; + } + } + + public int sum(String prefix) { + TrieNode head = root; + for (char c : prefix.toCharArray()) { + if (head.children.get(c) == null) return 0; + head = head.children.get(c); + + } + return head.value; + } + + private static class TrieNode { + Map children; + boolean isWord; + int value; + + public TrieNode() { + isWord = false; + children = new HashMap<>(); + value = 0; + } + } + +} + diff --git a/src/main/java/practiceproblems/tries/WordDictionary.java b/src/main/java/practiceproblems/tries/WordDictionary.java new file mode 100644 index 0000000..cd60efc --- /dev/null +++ b/src/main/java/practiceproblems/tries/WordDictionary.java @@ -0,0 +1,67 @@ +package practiceproblems.tries; + +/** + * Design a data structure that supports the following two operations: + * void addWord(word) + * bool search(word) + * search(word) can search a literal word or + * a regular expression string containing only letters a-z or .. A . + * means it can represent any one letter. + * addWord("bad") + * addWord("dad") + * addWord("mad") + * search("pad") -> false + * search("bad") -> true + * search(".ad") -> true + * search("b..") -> true + */ +public class WordDictionary { + TrieNode root; + + public WordDictionary() { + this.root = new TrieNode(); + } + + public void addWord(String word) { + TrieNode head = root; + for (int i = 0; i < word.length(); i++) { + if (head.children[word.charAt(i) - 'a'] == null) head.children[word.charAt(i) - 'a'] = new TrieNode(); + head = head.children[word.charAt(i) - 'a']; + } + + head.isWord = true; + + } + + public boolean search(String word) { + + return searchUtil(word.toCharArray(), 0, root); + } + + public boolean searchUtil(char[] words, int start, TrieNode root) { + if (start == words.length) return root.isWord; + + if (words[start] == '.') { + for (int i = 0; i < 26; i++) { + if (root.children[i] != null && searchUtil(words, start + 1, root.children[i])) { + return true; + } + } + } else { + return root.children[words[start] - 'a'] != null && searchUtil(words, start + 1, root.children[words[start] - 'a']); + } + + return false; + } + + static class TrieNode { + boolean isWord; + TrieNode[] children; + + public TrieNode() { + isWord = false; + children = new TrieNode[26]; + } + } +} + diff --git a/src/main/java/reflections/annotation/Main.java b/src/main/java/reflections/annotation/Main.java new file mode 100644 index 0000000..d83033b --- /dev/null +++ b/src/main/java/reflections/annotation/Main.java @@ -0,0 +1,137 @@ +package reflections.annotation; + +import reflections.annotation.annotations.Annotations; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.*; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * Repeatable Annotations + * https://www.udemy.com/course/java-reflection-master-class + */ +@Annotations.ScanPackages({"loaders"}) +public class Main { + public static void main(String[] args) throws Throwable { + schedule(); + } + + public static void schedule() throws ClassNotFoundException, IOException, URISyntaxException { + Annotations.ScanPackages scanPackages = Main.class.getAnnotation(Annotations.ScanPackages.class); + if (scanPackages == null || scanPackages.value().length == 0) { + return; + } + + List> allClasses = getAllClasses(scanPackages.value()); + List scheduledExecutorMethods = getScheduledExecutorMethods(allClasses); + + for (Method method : scheduledExecutorMethods) { + scheduleMethodExecution(method); + } + } + + private static void scheduleMethodExecution(Method method) { + Annotations.ExecuteOnSchedule[] schedules = method.getAnnotationsByType(Annotations.ExecuteOnSchedule.class); + + ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); + + for (Annotations.ExecuteOnSchedule schedule : schedules) { + scheduledExecutorService.scheduleAtFixedRate( + () -> runWhenScheduled(method), + schedule.delaySeconds(), + schedule.periodSeconds(), + TimeUnit.SECONDS); + } + } + + private static void runWhenScheduled(Method method) { + Date currentDate = new Date(); + SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); + + System.out.println(String.format("Executing at %s", dateFormat.format(currentDate))); + + try { + method.invoke(null); + } catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } + + private static List getScheduledExecutorMethods(List> allClasses) { + List scheduledMethods = new ArrayList<>(); + + for (Class clazz : allClasses) { + if (!clazz.isAnnotationPresent(Annotations.ScheduledExecutorClass.class)) { + continue; + } + for (Method method : clazz.getDeclaredMethods()) { + if (method.getAnnotationsByType(Annotations.ExecuteOnSchedule.class).length != 0) { + scheduledMethods.add(method); + } + } + } + return scheduledMethods; + } + + public static List> getAllClasses(String... packageNames) throws URISyntaxException, IOException, ClassNotFoundException { + List> allClasses = new ArrayList<>(); + + for (String packageName : packageNames) { + String packageRelativePath = packageName.replace('.', '/'); + + URI packageUri = Main.class.getResource(packageRelativePath).toURI(); + + if (packageUri.getScheme().equals("file")) { + Path packageFullPath = Paths.get(packageUri); + allClasses.addAll(getAllPackageClasses(packageFullPath, packageName)); + } else if (packageUri.getScheme().equals("jar")) { + FileSystem fileSystem = FileSystems.newFileSystem(packageUri, Collections.emptyMap()); + + Path packageFullPathInJar = fileSystem.getPath(packageRelativePath); + allClasses.addAll(getAllPackageClasses(packageFullPathInJar, packageName)); + + fileSystem.close(); + } + } + return allClasses; + } + + private static List> getAllPackageClasses(Path packagePath, String packageName) throws IOException, ClassNotFoundException { + + if (!Files.exists(packagePath)) { + return Collections.emptyList(); + } + + List files = Files.list(packagePath) + .filter(Files::isRegularFile) + .collect(Collectors.toList()); + + List> classes = new ArrayList<>(); + + for (Path filePath : files) { + String fileName = filePath.getFileName().toString(); + + if (fileName.endsWith(".class")) { + String classFullName = packageName.isBlank() + ? fileName.replaceFirst("\\.class$", "") + : packageName + "." + fileName.replaceFirst("\\.class$", ""); + + Class clazz = Class.forName(classFullName); + classes.add(clazz); + } + } + return classes; + } +} diff --git a/src/main/java/reflections/annotation/annotations/Annotations.java b/src/main/java/reflections/annotation/annotations/Annotations.java new file mode 100644 index 0000000..0258051 --- /dev/null +++ b/src/main/java/reflections/annotation/annotations/Annotations.java @@ -0,0 +1,33 @@ + + +package reflections.annotation.annotations; + +import java.lang.annotation.*; + +public class Annotations { + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE) + public @interface ScanPackages { + String[] value(); + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE) + public @interface ScheduledExecutorClass { + } + + @Repeatable(ExecutionSchedules.class) + @Target(ElementType.METHOD) + public @interface ExecuteOnSchedule { + int delaySeconds() default 0; + + int periodSeconds(); + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public @interface ExecutionSchedules { + ExecuteOnSchedule[] value(); + } +} diff --git a/src/main/java/reflections/annotation/loaders/Cache.java b/src/main/java/reflections/annotation/loaders/Cache.java new file mode 100644 index 0000000..e2669ee --- /dev/null +++ b/src/main/java/reflections/annotation/loaders/Cache.java @@ -0,0 +1,17 @@ + + +package reflections.annotation.loaders; + +import static reflections.annotation.annotations.Annotations.ExecuteOnSchedule; +import static reflections.annotation.annotations.Annotations.ScheduledExecutorClass; + + +@ScheduledExecutorClass +public class Cache { + + @ExecuteOnSchedule(periodSeconds = 5) + @ExecuteOnSchedule(delaySeconds = 10, periodSeconds = 1) + public static void reloadCache() { + System.out.println("Reloading cache"); + } +} diff --git a/src/main/java/reflections/arrays/Main.java b/src/main/java/reflections/arrays/Main.java new file mode 100644 index 0000000..06d462d --- /dev/null +++ b/src/main/java/reflections/arrays/Main.java @@ -0,0 +1,129 @@ + + +package reflections.arrays; + +import reflections.arrays.data.Actor; +import reflections.arrays.data.Movie; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; + +/** + * Json Write With Arrays + * https://www.udemy.com/course/java-reflection-master-class + */ +public class Main { + public static void main(String[] args) throws IllegalAccessException { + Actor actor1 = new Actor("Elijah Wood", new String[]{"Lord of the Rings", "The Good Son"}); + Actor actor2 = new Actor("Ian McKellen", new String[]{"X-Men", "Hobbit"}); + Actor actor3 = new Actor("Orlando Bloom", new String[]{"Pirates of the Caribbean", "Kingdom of Heaven"}); + + Movie movie = new Movie("Lord of the Rings", 8.8f, new String[]{"Action", "Adventure", "Drama"}, + new Actor[]{actor1, actor2, actor3}); + + String json = objectToJson(movie, 0); + + System.out.println(json); + } + + public static String objectToJson(Object instance, int indentSize) throws IllegalAccessException { + Field[] fields = instance.getClass().getDeclaredFields(); + StringBuilder stringBuilder = new StringBuilder(); + + stringBuilder.append(indent(indentSize)); + stringBuilder.append("{"); + stringBuilder.append("\n"); + + for (int i = 0; i < fields.length; i++) { + Field field = fields[i]; + field.setAccessible(true); + + if (field.isSynthetic()) { + continue; + } + + stringBuilder.append(indent(indentSize + 1)); + stringBuilder.append(formatStringValue(field.getName())); + + stringBuilder.append(":"); + + if (field.getType().isPrimitive()) { + stringBuilder.append(formatPrimitiveValue(field.get(instance), field.getType())); + } else if (field.getType().equals(String.class)) { + stringBuilder.append(formatStringValue(field.get(instance).toString())); + } else if (field.getType().isArray()) { + stringBuilder.append(arrayToJson(field.get(instance), indentSize + 1)); + } else { + stringBuilder.append(objectToJson(field.get(instance), indentSize + 1)); + } + + if (i != fields.length - 1) { + stringBuilder.append(","); + } + stringBuilder.append("\n"); + } + + stringBuilder.append(indent(indentSize)); + stringBuilder.append("}"); + return stringBuilder.toString(); + } + + private static String arrayToJson(Object arrayInstance, int indentSize) throws IllegalAccessException { + StringBuilder stringBuilder = new StringBuilder(); + + int arrayLength = Array.getLength(arrayInstance); + + Class componentType = arrayInstance.getClass().getComponentType(); + + stringBuilder.append("["); + stringBuilder.append("\n"); + + for (int i = 0; i < arrayLength; i++) { + Object element = Array.get(arrayInstance, i); + + if (componentType.isPrimitive()) { + stringBuilder.append(indent(indentSize + 1)); + stringBuilder.append(formatPrimitiveValue(element, componentType)); + } else if (componentType.equals(String.class)) { + stringBuilder.append(indent(indentSize + 1)); + stringBuilder.append(formatStringValue(element.toString())); + } else { + stringBuilder.append(objectToJson(element, indentSize + 1)); + } + + if (i != arrayLength - 1) { + stringBuilder.append(","); + } + stringBuilder.append("\n"); + } + + stringBuilder.append(indent(indentSize)); + stringBuilder.append("]"); + return stringBuilder.toString(); + } + + private static String indent(int indentSize) { + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < indentSize; i++) { + stringBuilder.append("\t"); + } + return stringBuilder.toString(); + } + + private static String formatPrimitiveValue(Object instance, Class type) { + if (type.equals(boolean.class) + || type.equals(int.class) + || type.equals(long.class) + || type.equals(short.class)) { + return instance.toString(); + } else if (type.equals(double.class) || type.equals(float.class)) { + return String.format("%.02f", instance); + } + + throw new RuntimeException(String.format("Type : %s is unsupported", type.getTypeName())); + } + + private static String formatStringValue(String value) { + return String.format("\"%s\"", value); + } +} diff --git a/src/main/java/reflections/arrays/data/Actor.java b/src/main/java/reflections/arrays/data/Actor.java new file mode 100644 index 0000000..83b9e94 --- /dev/null +++ b/src/main/java/reflections/arrays/data/Actor.java @@ -0,0 +1,13 @@ + + +package reflections.arrays.data; + +public class Actor { + private final String name; + private final String[] knownForMovies; + + public Actor(String name, String[] knownForMovies) { + this.name = name; + this.knownForMovies = knownForMovies; + } +} diff --git a/src/main/java/reflections/arrays/data/Movie.java b/src/main/java/reflections/arrays/data/Movie.java new file mode 100644 index 0000000..808271f --- /dev/null +++ b/src/main/java/reflections/arrays/data/Movie.java @@ -0,0 +1,17 @@ + + +package reflections.arrays.data; + +public class Movie { + private final String name; + private final float rating; + private final String[] categories; + private final Actor[] actors; + + public Movie(String name, float rating, String[] categories, Actor[] actors) { + this.name = name; + this.rating = rating; + this.categories = categories; + this.actors = actors; + } +} diff --git a/src/main/java/reflections/configparser/configloader/ConfigLoaderLibrary.java b/src/main/java/reflections/configparser/configloader/ConfigLoaderLibrary.java new file mode 100644 index 0000000..3e8d28c --- /dev/null +++ b/src/main/java/reflections/configparser/configloader/ConfigLoaderLibrary.java @@ -0,0 +1,102 @@ + + +package reflections.configparser.configloader; + +import reflections.configparser.data.GameConfig; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.nio.file.Path; +import java.util.Scanner; + +/** + * Config Parser - Part 2 + * https://www.udemy.com/course/java-reflection-master-class + */ +public class ConfigLoaderLibrary { + private static final Path GAME_CONFIG_PATH = Path.of("resources/game-properties.cfg"); + private static final Path UI_CONFIG_PATH = Path.of("resources/user-interface.cfg"); + + public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, IOException { + GameConfig config = createConfigObject(GameConfig.class, GAME_CONFIG_PATH); + //UserInterfaceConfig config = createConfigObject(UserInterfaceConfig.class, UI_CONFIG_PATH); + + System.out.println(config); + } + + public static T createConfigObject(Class clazz, Path filePath) throws IOException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { + + Scanner scanner = new Scanner(filePath); + + Constructor constructor = clazz.getDeclaredConstructor(); + constructor.setAccessible(true); + + T configInstance = (T) constructor.newInstance(); + + while (scanner.hasNextLine()) { + String configLine = scanner.nextLine(); + + String[] nameValuePair = configLine.split("="); + + if (nameValuePair.length != 2) { + continue; + } + + String propertyName = nameValuePair[0]; + String propertyValue = nameValuePair[1]; + + Field field; + try { + field = clazz.getDeclaredField(propertyName); + } catch (NoSuchFieldException e) { + System.out.println(String.format("Property name : %s is unsupported", propertyName)); + continue; + } + + field.setAccessible(true); + + Object parsedValue; + + if (field.getType().isArray()) { + parsedValue = parseArray(field.getType().getComponentType(), propertyValue); + } else { + parsedValue = parseValue(field.getType(), propertyValue); + } + + field.set(configInstance, parsedValue); + } + + return configInstance; + } + + private static Object parseArray(Class arrayElementType, String value) { + String[] elementValues = value.split(","); + + Object arrayObject = Array.newInstance(arrayElementType, elementValues.length); + + for (int i = 0; i < elementValues.length; i++) { + Array.set(arrayObject, i, parseValue(arrayElementType, elementValues[i])); + } + return arrayObject; + } + + private static Object parseValue(Class type, String value) { + if (type.equals(int.class)) { + return Integer.parseInt(value); + } else if (type.equals(short.class)) { + return Short.parseShort(value); + } else if (type.equals(long.class)) { + return Long.parseLong(value); + } else if (type.equals(double.class)) { + return Double.parseDouble(value); + } else if (type.equals(float.class)) { + return Float.parseFloat(value); + } else if (type.equals(String.class)) { + return value; + } + throw new RuntimeException(String.format("Type : %s unsupported", type.getTypeName())); + } +} diff --git a/src/main/java/reflections/configparser/data/GameConfig.java b/src/main/java/reflections/configparser/data/GameConfig.java new file mode 100644 index 0000000..706c58a --- /dev/null +++ b/src/main/java/reflections/configparser/data/GameConfig.java @@ -0,0 +1,38 @@ + + +package reflections.configparser.data; + +import java.util.Arrays; + +public class GameConfig { + private int releaseYear; + private String gameName; + private double price; + private String[] characterNames; + + public int getReleaseYear() { + return this.releaseYear; + } + + public String getGameName() { + return this.gameName; + } + + public double getPrice() { + return this.price; + } + + public String[] getCharacterNames() { + return characterNames; + } + + @Override + public String toString() { + return "GameConfig{" + + "releaseYear=" + releaseYear + + ", gameName='" + gameName + '\'' + + ", price=" + price + + ", characterName=" + Arrays.toString(characterNames) + + '}'; + } +} diff --git a/src/main/java/reflections/configparser/data/UserInterfaceConfig.java b/src/main/java/reflections/configparser/data/UserInterfaceConfig.java new file mode 100644 index 0000000..38f901f --- /dev/null +++ b/src/main/java/reflections/configparser/data/UserInterfaceConfig.java @@ -0,0 +1,32 @@ + + +package reflections.configparser.data; + +import java.util.Arrays; + +public class UserInterfaceConfig { + private String titleText; + private String[] titleFonts; + private short[] titleTextSizes; + + public String getTitleText() { + return titleText; + } + + public String[] getTitleFonts() { + return titleFonts; + } + + public short[] getTitleTextSizes() { + return titleTextSizes; + } + + @Override + public String toString() { + return "UserInterfaceConfig{" + + "titleText='" + titleText + '\'' + + ", titleFonts=" + Arrays.toString(titleFonts) + + ", titleTextSizes=" + Arrays.toString(titleTextSizes) + + '}'; + } +} diff --git a/src/main/java/reflections/configparser/resources/game-properties.cfg b/src/main/java/reflections/configparser/resources/game-properties.cfg new file mode 100644 index 0000000..d8a2b62 --- /dev/null +++ b/src/main/java/reflections/configparser/resources/game-properties.cfg @@ -0,0 +1,7 @@ +releaseYear=1993 + +gameName=The Lost Vikings + +price=10.99 + +characterNames=Erik the Swift,Baleog the Fierce,Olaf the Stout \ No newline at end of file diff --git a/src/main/java/reflections/configparser/resources/user-interface.cfg b/src/main/java/reflections/configparser/resources/user-interface.cfg new file mode 100644 index 0000000..f95256a --- /dev/null +++ b/src/main/java/reflections/configparser/resources/user-interface.cfg @@ -0,0 +1,3 @@ +titleText=Welcome to Our Store +titleFonts=Ariel,Sans-serif +titleTextSizes=10,15 \ No newline at end of file diff --git a/src/main/java/reflections/customMockito/ExternalService.java b/src/main/java/reflections/customMockito/ExternalService.java new file mode 100644 index 0000000..63381a4 --- /dev/null +++ b/src/main/java/reflections/customMockito/ExternalService.java @@ -0,0 +1,9 @@ +package reflections.customMockito; + +public interface ExternalService { + public String concat(String arg1, String arg2); + + public void someStrangeOperation(Object obj); + + public int divide(int a, int b); +} \ No newline at end of file diff --git a/src/main/java/reflections/customMockito/OurMockTest.java b/src/main/java/reflections/customMockito/OurMockTest.java new file mode 100644 index 0000000..ed35441 --- /dev/null +++ b/src/main/java/reflections/customMockito/OurMockTest.java @@ -0,0 +1,26 @@ +package reflections.customMockito; + +public class OurMockTest { + ExternalService externalService = (ExternalService) OurMockito.mock(ExternalService.class); + + //@Test + public void stubbing_method() throws Exception { + OurMockito.stub(externalService, "concat", "dummy"); + String returned = externalService.concat(null, null); + //assertEquals("dummy", returned); + } + + // @Test + public void stubbing_error_conditions() throws Exception { + OurMockito.stub(externalService, "divide", 0); + int returned = externalService.divide(0, 0); + //assertEquals(0, returned); + } + + // @Test + public void stubbing_exception() throws Exception { + OurMockito.stub(externalService, "someStrangeOperation", new + RuntimeException("Just blow this up!")); + externalService.someStrangeOperation(null); + } +} \ No newline at end of file diff --git a/src/main/java/reflections/customMockito/OurMockito.java b/src/main/java/reflections/customMockito/OurMockito.java new file mode 100644 index 0000000..bf52e9c --- /dev/null +++ b/src/main/java/reflections/customMockito/OurMockito.java @@ -0,0 +1,50 @@ +package reflections.customMockito; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Proxy; +import java.util.HashMap; +import java.util.Map; + +public class OurMockito implements InvocationHandler { + private static Map stubMap = new HashMap<>(); + private static Map excepMap = new + HashMap<>(); + + @Override + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { + String methodName = method.getName(); + if (Modifier.isFinal(method.getModifiers()) || + Modifier.isPrivate(method.getModifiers()) || + Modifier.isStatic(method.getModifiers())) { + throw new RuntimeException("You naughty developer mocking a private,static or final method " + methodName); + } + if (excepMap.containsKey(methodName)) { + Exception excep = excepMap.get(methodName); + throw excep; + } + if (stubMap.containsKey(methodName)) { + return stubMap.get(methodName); + } + return null; + } + + public static Object mock(Class aClass) { + return Proxy.newProxyInstance + (OurMockito.class.getClassLoader(), new Class[]{aClass + }, new OurMockito()); + } + + public static void stub(Object stubOn, String methodName, Object stubbedValue) { + stubMap.put(methodName, stubbedValue); + } + + public static void stub(Object stubOn, String methodName, + Exception excep) { + if (excep != null) { + excepMap.put(methodName, excep); + } + } +} \ No newline at end of file diff --git a/src/main/java/reflections/dynamicProxy/Main.java b/src/main/java/reflections/dynamicProxy/Main.java new file mode 100644 index 0000000..5ae3a0a --- /dev/null +++ b/src/main/java/reflections/dynamicProxy/Main.java @@ -0,0 +1,92 @@ +package reflections.dynamicProxy; + +import reflections.dynamicProxy.external.impl.DatabaseReader; +import reflections.dynamicProxy.external.impl.HttpClient; +import reflections.dynamicProxy.external.impl.DatabaseReaderImpl; + +import java.io.IOException; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.List; + +/** + * Dynamic Proxy + * https://www.udemy.com/course/java-reflection-master-class + */ +public class Main { + + public static void main(String[] args) throws InterruptedException { + DatabaseReader databaseReader = createProxy(new DatabaseReaderImpl()); + + useDatabaseReader(databaseReader); + + List listOfGreetings = new ArrayList<>(); + + listOfGreetings.add("hello"); + listOfGreetings.add("good morning"); + listOfGreetings.remove("hello"); + } + + public static void useHttpClient(HttpClient httpClient) { + httpClient.initialize(); + String response = httpClient.sendRequest("some request"); + + System.out.println(String.format("Http response is : %s", response)); + } + + public static void useDatabaseReader(DatabaseReader databaseReader) throws InterruptedException { + int rowsInGamesTable = 0; + try { + rowsInGamesTable = databaseReader.countRowsInTable("GamesTable"); + } catch (IOException e) { + System.out.println("Catching exception " + e); + return; + } + + System.out.println(String.format("There are %s rows in GamesTable", rowsInGamesTable)); + + String[] data = databaseReader.readRow("SELECT * from GamesTable"); + + System.out.println(String.format("Received %s", String.join(" , ", data))); + } + + @SuppressWarnings("unchecked") + public static T createProxy(Object originalObject) { + Class[] interfaces = originalObject.getClass().getInterfaces(); + + TimeMeasuringProxyHandler timeMeasuringProxyHandler = new TimeMeasuringProxyHandler(originalObject); + + return (T) Proxy.newProxyInstance(originalObject.getClass().getClassLoader(), interfaces, timeMeasuringProxyHandler); + } + + public static class TimeMeasuringProxyHandler implements InvocationHandler { + private final Object originalObject; + + public TimeMeasuringProxyHandler(Object originalObject) { + this.originalObject = originalObject; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + Object result; + + System.out.println(String.format("Measuring Proxy - Before Executing method : %s()", method.getName())); + + long startTime = System.nanoTime(); + try { + result = method.invoke(originalObject, args); + } catch (InvocationTargetException e) { + throw e.getTargetException(); + } + long endTime = System.nanoTime(); + + System.out.println(); + System.out.println(String.format("Measuring Proxy - Execution of %s() took %dns \n", method.getName(), endTime - startTime)); + + return result; + } + } +} diff --git a/src/main/java/reflections/dynamicProxy/external/impl/DatabaseReader.java b/src/main/java/reflections/dynamicProxy/external/impl/DatabaseReader.java new file mode 100644 index 0000000..b3673a5 --- /dev/null +++ b/src/main/java/reflections/dynamicProxy/external/impl/DatabaseReader.java @@ -0,0 +1,12 @@ + + +package reflections.dynamicProxy.external.impl; + +import java.io.IOException; + +public interface DatabaseReader { + + int countRowsInTable(String tableName) throws InterruptedException, IOException; + + String[] readRow(String sqlQuery) throws InterruptedException; +} diff --git a/src/main/java/reflections/dynamicProxy/external/impl/DatabaseReaderImpl.java b/src/main/java/reflections/dynamicProxy/external/impl/DatabaseReaderImpl.java new file mode 100644 index 0000000..a5c484c --- /dev/null +++ b/src/main/java/reflections/dynamicProxy/external/impl/DatabaseReaderImpl.java @@ -0,0 +1,22 @@ + + +package reflections.dynamicProxy.external.impl; + + +public final class DatabaseReaderImpl implements DatabaseReader { + @Override + public int countRowsInTable(String tableName) throws InterruptedException { + System.out.println(String.format("DatabaseReaderImpl - counting rows in table %s", tableName)); + + Thread.sleep(1000); + return 50; + } + + @Override + public String[] readRow(String sqlQuery) throws InterruptedException { + System.out.println(String.format("DatabaseReaderImpl - Executing SQL query : %s", sqlQuery)); + + Thread.sleep(1500); + return new String[]{"column1", "column2", "column3"}; + } +} diff --git a/src/main/java/reflections/dynamicProxy/external/impl/HttpClient.java b/src/main/java/reflections/dynamicProxy/external/impl/HttpClient.java new file mode 100644 index 0000000..73c005b --- /dev/null +++ b/src/main/java/reflections/dynamicProxy/external/impl/HttpClient.java @@ -0,0 +1,10 @@ + + +package reflections.dynamicProxy.external.impl; + +public interface HttpClient { + + void initialize(); + + String sendRequest(String request); +} diff --git a/src/main/java/reflections/dynamicProxy/external/impl/HttpClientImpl.java b/src/main/java/reflections/dynamicProxy/external/impl/HttpClientImpl.java new file mode 100644 index 0000000..86fb9d7 --- /dev/null +++ b/src/main/java/reflections/dynamicProxy/external/impl/HttpClientImpl.java @@ -0,0 +1,27 @@ + + +package reflections.dynamicProxy.external.impl; + +public final class HttpClientImpl implements HttpClient { + @Override + public void initialize() { + System.out.println("Initializing HTTP client"); + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + @Override + public String sendRequest(String request) { + System.out.println(String.format("Sending request %s", request)); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("Received response"); + return "someResponse data"; + } +} diff --git a/src/main/java/reflections/game/Game.java b/src/main/java/reflections/game/Game.java new file mode 100644 index 0000000..ab3ab5d --- /dev/null +++ b/src/main/java/reflections/game/Game.java @@ -0,0 +1,8 @@ + + +package reflections.game; + +public interface Game { + + void startGame(); +} diff --git a/src/main/java/reflections/game/internal/Board.java b/src/main/java/reflections/game/internal/Board.java new file mode 100644 index 0000000..37ec6ed --- /dev/null +++ b/src/main/java/reflections/game/internal/Board.java @@ -0,0 +1,123 @@ + + +package reflections.game.internal; + +class Board { + private Cell[][] cells; + private BoardDimensions dimensions; + + public Board(BoardDimensions boardDimensions) { + this.dimensions = boardDimensions; + this.cells = new Cell[boardDimensions.getNumberOfColumns()][boardDimensions.getNumberOfRows()]; + initAllCells(); + } + + private void initAllCells() { + for (int r = 0; r < dimensions.getNumberOfRows(); r++) { + for (int c = 0; c < dimensions.getNumberOfColumns(); c++) { + this.cells[c][r] = new Cell(); + } + } + } + + public void updateCell(int row, int column, Sign sign) { + this.cells[column][row].setSign(sign); + } + + public Sign checkWinner() { + // Check rows + for (int r = 0; r < dimensions.getNumberOfRows(); r++) { + Sign sign = getRowWinner(r); + if (sign != Sign.EMPTY) { + return sign; + } + } + + // Check columns + for (int c = 0; c < dimensions.getNumberOfColumns(); c++) { + Sign sign = getColumnWinner(c); + if (sign != Sign.EMPTY) { + return sign; + } + } + + // Check diagonal + Sign sign = getDiagonalWinner(0, 0, 1, 1); + if (sign != Sign.EMPTY) { + return sign; + } + + // Check diagonal + return getDiagonalWinner(0, dimensions.getNumberOfColumns() - 1, -1, 1); + } + + public boolean isCellEmpty(int row, int column) { + return this.cells[column][row].isEmpty(); + } + + public char getPrintableCellSign(int row, int column) { + return this.cells[column][row].getSign().getValue(); + } + + public boolean isBoardFull() { + for (int r = 0; r < dimensions.getNumberOfRows(); r++) { + for (int c = 0; c < dimensions.getNumberOfColumns(); c++) { + if (this.cells[c][r].isEmpty()) { + return false; + } + } + } + return true; + } + + private Sign getColumnWinner(int currentColumn) { + Sign initialSign = this.cells[currentColumn][0].getSign(); + + if (initialSign == Sign.EMPTY) { + return initialSign; + } + + for (int r = 1; r < dimensions.getNumberOfRows(); r++) { + if (this.cells[currentColumn][r].getSign() != initialSign) { + return Sign.EMPTY; + } + } + return initialSign; + } + + private Sign getRowWinner(int currentRow) { + Sign initialSign = this.cells[0][currentRow].getSign(); + + if (initialSign == Sign.EMPTY) { + return initialSign; + } + + for (int c = 1; c < dimensions.getNumberOfColumns(); c++) { + if (this.cells[c][currentRow].getSign() != initialSign) { + return Sign.EMPTY; + } + } + return initialSign; + } + + + private Sign getDiagonalWinner(int startRow, int startColumn, int horizontalStep, int verticalStep) { + Sign initialSign = this.cells[startColumn][startRow].getSign(); + if (initialSign == Sign.EMPTY) { + return Sign.EMPTY; + } + + int r = startRow + verticalStep; + int c = startColumn + horizontalStep; + + while (r < dimensions.getNumberOfRows() && c < dimensions.getNumberOfColumns()) { + if (this.cells[c][r].getSign() != initialSign) { + return Sign.EMPTY; + } + r += verticalStep; + c += horizontalStep; + } + + return initialSign; + } +} diff --git a/src/main/java/reflections/game/internal/BoardDimensions.java b/src/main/java/reflections/game/internal/BoardDimensions.java new file mode 100644 index 0000000..634ecb4 --- /dev/null +++ b/src/main/java/reflections/game/internal/BoardDimensions.java @@ -0,0 +1,17 @@ + + +package reflections.game.internal; + +class BoardDimensions { + private static final int NUM_OF_ROWS = 3; + private static final int NUM_OF_COLUMNS = 3; + + + public int getNumberOfRows() { + return NUM_OF_ROWS; + } + + public int getNumberOfColumns() { + return NUM_OF_COLUMNS; + } +} diff --git a/src/main/java/reflections/game/internal/BoardLocation.java b/src/main/java/reflections/game/internal/BoardLocation.java new file mode 100644 index 0000000..ae8d6ac --- /dev/null +++ b/src/main/java/reflections/game/internal/BoardLocation.java @@ -0,0 +1,21 @@ + + +package reflections.game.internal; + +class BoardLocation { + private int row; + private int column; + + public BoardLocation(int row, int column) { + this.row = row; + this.column = column; + } + + public int getRow() { + return row; + } + + public int getColumn() { + return column; + } +} diff --git a/src/main/java/reflections/game/internal/BoardPrinter.java b/src/main/java/reflections/game/internal/BoardPrinter.java new file mode 100644 index 0000000..863d5b6 --- /dev/null +++ b/src/main/java/reflections/game/internal/BoardPrinter.java @@ -0,0 +1,36 @@ + + +package reflections.game.internal; + +class BoardPrinter { + private final BoardDimensions dimensions; + + public BoardPrinter(BoardDimensions dimensions) { + this.dimensions = dimensions; + } + + public void print(Board board) { + printHorizontalBorder(); + + printBoard(board); + + printHorizontalBorder(); + } + + private void printBoard(Board board) { + for (int r = 0; r < dimensions.getNumberOfRows(); r++) { + System.out.print("|"); + for (int c = 0; c < dimensions.getNumberOfColumns(); c++) { + System.out.print(String.format(" %s |", board.getPrintableCellSign(r, c))); + } + System.out.println(); + } + } + + private void printHorizontalBorder() { + for (int c = 0; c < dimensions.getNumberOfColumns() * 4 + 1; c++) { + System.out.print("-"); + } + System.out.println(); + } +} diff --git a/src/main/java/reflections/game/internal/Cell.java b/src/main/java/reflections/game/internal/Cell.java new file mode 100644 index 0000000..12bae44 --- /dev/null +++ b/src/main/java/reflections/game/internal/Cell.java @@ -0,0 +1,23 @@ + + +package reflections.game.internal; + +class Cell { + private Sign sign; + + public Cell() { + sign = Sign.EMPTY; + } + + public boolean isEmpty() { + return sign == Sign.EMPTY; + } + + public Sign getSign() { + return sign; + } + + public void setSign(Sign sign) { + this.sign = sign; + } +} diff --git a/src/main/java/reflections/game/internal/ComputerInputProvider.java b/src/main/java/reflections/game/internal/ComputerInputProvider.java new file mode 100644 index 0000000..7c9baa4 --- /dev/null +++ b/src/main/java/reflections/game/internal/ComputerInputProvider.java @@ -0,0 +1,33 @@ + + +package reflections.game.internal; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +class ComputerInputProvider implements InputProvider { + public final BoardDimensions dimensions; + private final Random random = new Random(); + + public ComputerInputProvider(BoardDimensions dimensions) { + this.dimensions = dimensions; + } + + @Override + public BoardLocation provideNextMove(Board board) { + List availableCells = new ArrayList<>(); + + for (int r = 0; r < dimensions.getNumberOfRows(); r++) { + for (int c = 0; c < dimensions.getNumberOfColumns(); c++) { + if (board.isCellEmpty(r, c)) { + availableCells.add(new BoardLocation(r, c)); + } + } + } + + int chosenCell = random.nextInt(availableCells.size()); + + return availableCells.get(chosenCell); + } +} diff --git a/src/main/java/reflections/game/internal/ComputerPlayer.java b/src/main/java/reflections/game/internal/ComputerPlayer.java new file mode 100644 index 0000000..724482e --- /dev/null +++ b/src/main/java/reflections/game/internal/ComputerPlayer.java @@ -0,0 +1,23 @@ + + +package reflections.game.internal; + +class ComputerPlayer implements Player { + private static final String NAME = "Computer"; + private final ComputerInputProvider locationProvider; + + public ComputerPlayer(ComputerInputProvider locationProvider) { + this.locationProvider = locationProvider; + } + + @Override + public void play(Board board, Sign sign) { + BoardLocation location = locationProvider.provideNextMove(board); + board.updateCell(location.getRow(), location.getColumn(), sign); + } + + @Override + public String getPlayerName() { + return NAME; + } +} diff --git a/src/main/java/reflections/game/internal/HumanPlayer.java b/src/main/java/reflections/game/internal/HumanPlayer.java new file mode 100644 index 0000000..a7c7cb5 --- /dev/null +++ b/src/main/java/reflections/game/internal/HumanPlayer.java @@ -0,0 +1,23 @@ + + +package reflections.game.internal; + +class HumanPlayer implements Player { + private static final String NAME = "You"; + private final KeyboardInputProvider inputProvider; + + public HumanPlayer(KeyboardInputProvider inputProvider) { + this.inputProvider = inputProvider; + } + + @Override + public void play(Board board, Sign sign) { + BoardLocation nextMoveLocation = inputProvider.provideNextMove(board); + board.updateCell(nextMoveLocation.getRow(), nextMoveLocation.getColumn(), sign); + } + + @Override + public String getPlayerName() { + return NAME; + } +} diff --git a/src/main/java/reflections/game/internal/InputProvider.java b/src/main/java/reflections/game/internal/InputProvider.java new file mode 100644 index 0000000..7d39e3c --- /dev/null +++ b/src/main/java/reflections/game/internal/InputProvider.java @@ -0,0 +1,7 @@ + + +package reflections.game.internal; + +interface InputProvider { + BoardLocation provideNextMove(Board board); +} diff --git a/src/main/java/reflections/game/internal/KeyboardInputProvider.java b/src/main/java/reflections/game/internal/KeyboardInputProvider.java new file mode 100644 index 0000000..5cdd1d0 --- /dev/null +++ b/src/main/java/reflections/game/internal/KeyboardInputProvider.java @@ -0,0 +1,31 @@ + + +package reflections.game.internal; + +import java.util.Scanner; + +class KeyboardInputProvider implements InputProvider { + private final Scanner scanner = new Scanner(System.in); + private final BoardDimensions boardDimensions; + + public KeyboardInputProvider(BoardDimensions boardDimensions) { + this.boardDimensions = boardDimensions; + } + + @Override + public BoardLocation provideNextMove(Board board) { + int row; + int column; + do { + System.out.print("Please choose row: "); + row = scanner.nextInt(); + System.out.print("Please choose column: "); + column = scanner.nextInt(); + } while (row < 0 + || row >= boardDimensions.getNumberOfRows() + || column < 0 + || column >= boardDimensions.getNumberOfColumns() + || !board.isCellEmpty(row, column)); + return new BoardLocation(row, column); + } +} diff --git a/src/main/java/reflections/game/internal/Player.java b/src/main/java/reflections/game/internal/Player.java new file mode 100644 index 0000000..4e7ab4a --- /dev/null +++ b/src/main/java/reflections/game/internal/Player.java @@ -0,0 +1,10 @@ + + +package reflections.game.internal; + +interface Player { + + void play(Board board, Sign sign); + + String getPlayerName(); +} diff --git a/src/main/java/reflections/game/internal/Sign.java b/src/main/java/reflections/game/internal/Sign.java new file mode 100644 index 0000000..2fac9c1 --- /dev/null +++ b/src/main/java/reflections/game/internal/Sign.java @@ -0,0 +1,19 @@ + + +package reflections.game.internal; + +enum Sign { + EMPTY(' '), + X('X'), + Y('Y'); + + private char value; + + Sign(char value) { + this.value = value; + } + + public char getValue() { + return this.value; + } +} diff --git a/src/main/java/reflections/game/internal/TicTacToeGame.java b/src/main/java/reflections/game/internal/TicTacToeGame.java new file mode 100644 index 0000000..bf725e3 --- /dev/null +++ b/src/main/java/reflections/game/internal/TicTacToeGame.java @@ -0,0 +1,57 @@ + + +package reflections.game.internal; + + +import reflections.game.Game; + +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +public class TicTacToeGame implements Game { + private static final int NUMBER_OF_PLAYERS = 2; + private final Random random = new Random(); + private final List playerSigns = Arrays.asList(Sign.X, Sign.Y); + + private final Board board; + private final List players; + private final BoardPrinter printer; + + TicTacToeGame(Board board, + BoardPrinter printer, + HumanPlayer humanPlayer, + ComputerPlayer computerPlayer) { + this.board = board; + this.printer = printer; + this.players = Arrays.asList(humanPlayer, computerPlayer); + } + + public void startGame() { + Sign winner; + int nextPlayerIndex = random.nextInt(NUMBER_OF_PLAYERS); + + Player player; + printer.print(board); + do { + nextPlayerIndex = NUMBER_OF_PLAYERS - nextPlayerIndex - 1; + + player = players.get(nextPlayerIndex); + + Sign playerSign = playerSigns.get(nextPlayerIndex); + + player.play(board, playerSign); + + winner = board.checkWinner(); + + printer.print(board); + } while (!board.isBoardFull() && winner == Sign.EMPTY); + + if (winner != Sign.EMPTY) { + System.out.println(String.format("Winner is : %s", player.getPlayerName())); + } else { + System.out.println("Game over! Nobody won."); + } + + } +} diff --git a/src/main/java/reflections/init/Main.java b/src/main/java/reflections/init/Main.java new file mode 100644 index 0000000..6d1d71d --- /dev/null +++ b/src/main/java/reflections/init/Main.java @@ -0,0 +1,40 @@ + +package reflections.init; +import reflections.game.Game; +import reflections.game.internal.TicTacToeGame; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +public class Main { + + public static void main(String[] args) throws IllegalAccessException, InstantiationException, InvocationTargetException { + Game game = (Game) createObjectRecursively(TicTacToeGame.class); + game.startGame(); + } + + public static T createObjectRecursively(Class clazz) throws IllegalAccessException, InvocationTargetException, InstantiationException { + Constructor constructor = getFirstConstructor(clazz); + + List constructorArguments = new ArrayList<>(); + + for (Class argumentType : constructor.getParameterTypes()) { + Object argumentValue = createObjectRecursively(argumentType); + constructorArguments.add(argumentValue); + } + + constructor.setAccessible(true); + return (T) constructor.newInstance(constructorArguments.toArray()); + } + + private static Constructor getFirstConstructor(Class clazz) { + Constructor[] constructors = clazz.getDeclaredConstructors(); + if (constructors.length == 0) { + throw new IllegalStateException(String.format("No constructor has been found for class %s", clazz.getName())); + } + + return constructors[0]; + } +} diff --git a/src/main/java/reflections/methodDiscovery/Address.java b/src/main/java/reflections/methodDiscovery/Address.java new file mode 100644 index 0000000..d354f31 --- /dev/null +++ b/src/main/java/reflections/methodDiscovery/Address.java @@ -0,0 +1,19 @@ + +package reflections.methodDiscovery; + +public class Address { + private String city; + private String state; + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getState() { + return state; + } +} diff --git a/src/main/java/reflections/methodDiscovery/ClothingProduct.java b/src/main/java/reflections/methodDiscovery/ClothingProduct.java new file mode 100644 index 0000000..a43e4b5 --- /dev/null +++ b/src/main/java/reflections/methodDiscovery/ClothingProduct.java @@ -0,0 +1,26 @@ + +package reflections.methodDiscovery; + +public class ClothingProduct extends Product { + private Size size; + private String color; + + // Getters + public Size getSize() { + return size; + } + + public void setSize(Size size) { + this.size = size; + } + + // Setters + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } +} diff --git a/src/main/java/reflections/methodDiscovery/Product.java b/src/main/java/reflections/methodDiscovery/Product.java new file mode 100644 index 0000000..ee3aca1 --- /dev/null +++ b/src/main/java/reflections/methodDiscovery/Product.java @@ -0,0 +1,54 @@ + +package reflections.methodDiscovery; + +import java.util.Date; + +public class Product { + private double price; + private String name; + private long quantity; + private Date expirationDate; + private Address address; + + // Getters + public double getPrice() { + return price; + } + + // Setters + public void setPrice(double price) { + this.price = price; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getQuantity() { + return quantity; + } + + public void setQuantity(long quantity) { + this.quantity = quantity; + } + + public Date getExpirationDate() { + return expirationDate; + } + + public void setExpirationDate(Date expirationDate) { + this.expirationDate = expirationDate; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } +} diff --git a/src/main/java/reflections/methodDiscovery/ProductTest.java b/src/main/java/reflections/methodDiscovery/ProductTest.java new file mode 100644 index 0000000..5a4a310 --- /dev/null +++ b/src/main/java/reflections/methodDiscovery/ProductTest.java @@ -0,0 +1,94 @@ + +package reflections.methodDiscovery; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.*; + +public class ProductTest { + + public static void main(String[] args) { + testGetters(ClothingProduct.class); + testSetters(ClothingProduct.class); + } + + public static void testSetters(Class dataClass) { + List fields = getAllFields(dataClass); + + for (Field field : fields) { + String setterName = "set" + capitalizeFirstLetter(field.getName()); + + Method setterMethod = null; + try { + setterMethod = dataClass.getMethod(setterName, field.getType()); + } catch (NoSuchMethodException e) { + throw new IllegalStateException(String.format("Setter : %s not found", setterName)); + } + + if (!setterMethod.getReturnType().equals(void.class)) { + throw new IllegalStateException(String.format("Setter method : %s has to return void", setterName)); + } + } + } + + public static void testGetters(Class dataClass) { + List fields = getAllFields(dataClass); + + Map methodNameToMethod = mapMethodNameToMethod(dataClass); + + for (Field field : fields) { + String getterName = "get" + capitalizeFirstLetter(field.getName()); + + if (!methodNameToMethod.containsKey(getterName)) { + throw new IllegalStateException(String.format("Field : %s doesn't have a getter method", field.getName())); + } + + Method getter = methodNameToMethod.get(getterName); + + if (!getter.getReturnType().equals(field.getType())) { + throw new IllegalStateException( + String.format("Getter method : %s() has return type %s but expected %s", + getter.getName(), + getter.getReturnType().getTypeName(), + field.getType().getTypeName())); + } + + if (getter.getParameterCount() > 0) { + throw new IllegalStateException(String.format("Getter : %s has %d arguments", getterName)); + } + } + } + + private static List getAllFields(Class clazz) { + if (clazz == null || clazz.equals(Object.class)) { + return Collections.emptyList(); + } + + Field[] currentClassFields = clazz.getDeclaredFields(); + + List inheritedFields = getAllFields(clazz.getSuperclass()); + + List allFields = new ArrayList<>(); + + allFields.addAll(Arrays.asList(currentClassFields)); + allFields.addAll(inheritedFields); + + return allFields; + } + + private static String capitalizeFirstLetter(String fieldName) { + return fieldName.substring(0, 1).toUpperCase().concat(fieldName.substring(1)); + } + + private static Map mapMethodNameToMethod(Class dataClass) { + Method[] allMethods = dataClass.getMethods(); + + Map nameToMethod = new HashMap<>(); + + for (Method method : allMethods) { + nameToMethod.put(method.getName(), method); + } + + return nameToMethod; + } +} diff --git a/src/main/java/reflections/methodDiscovery/Size.java b/src/main/java/reflections/methodDiscovery/Size.java new file mode 100644 index 0000000..3a82752 --- /dev/null +++ b/src/main/java/reflections/methodDiscovery/Size.java @@ -0,0 +1,9 @@ + +package reflections.methodDiscovery; + +public enum Size { + SMALL, + MEDIUM, + LARGE, + XLARGE +} diff --git a/src/main/java/reflections/retries/Main.java b/src/main/java/reflections/retries/Main.java new file mode 100644 index 0000000..954b6d8 --- /dev/null +++ b/src/main/java/reflections/retries/Main.java @@ -0,0 +1,140 @@ +package reflections.retries; + +import reflections.retries.annotations.InitializerClass; +import reflections.retries.annotations.InitializerMethod; +import reflections.retries.annotations.RetryOperation; +import reflections.retries.annotations.ScanPackages; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Annotations - Retry + * https://www.udemy.com/course/java-reflection-master-class + */ + +@ScanPackages({"app", "app.configs", "app.databases", "app.http"}) +public class Main { + + public static void main(String[] args) throws Throwable { + initialize(); + } + + public static void initialize() throws Throwable { + ScanPackages scanPackages = Main.class.getAnnotation(ScanPackages.class); + + if (scanPackages == null || scanPackages.value().length == 0) { + return; + } + + List> classes = getAllClasses(scanPackages.value()); + + for (Class clazz : classes) { + if (!clazz.isAnnotationPresent(InitializerClass.class)) { + continue; + } + + List methods = getAllInitializingMethods(clazz); + + Object instance = clazz.getDeclaredConstructor().newInstance(); + + for (Method method : methods) { + callInitializingMethod(instance, method); + } + } + } + + private static void callInitializingMethod(Object instance, Method method) throws Throwable { + RetryOperation retryOperation = method.getAnnotation(RetryOperation.class); + + int numberOfRetries = retryOperation == null ? 0 : retryOperation.numberOfRetries(); + + while (true) { + try { + method.invoke(instance); + break; + } catch (InvocationTargetException e) { + Throwable targetException = e.getTargetException(); + + if (numberOfRetries > 0 && Set.of(retryOperation.retryExceptions()).contains(targetException.getClass())) { + numberOfRetries--; + + System.out.println("Retrying ..."); + Thread.sleep(retryOperation.durationBetweenRetriesMs()); + } else if (retryOperation != null) { + throw new Exception(retryOperation.failureMessage(), targetException); + } else { + throw targetException; + } + } + } + } + + private static List getAllInitializingMethods(Class clazz) { + List initializingMethods = new ArrayList<>(); + for (Method method : clazz.getDeclaredMethods()) { + if (method.isAnnotationPresent(InitializerMethod.class)) { + initializingMethods.add(method); + } + } + return initializingMethods; + } + + public static List> getAllClasses(String... packageNames) throws URISyntaxException, IOException, ClassNotFoundException { + List> allClasses = new ArrayList<>(); + + for (String packageName : packageNames) { + String packageRelativePath = packageName.replace('.', '/'); + + URI packageUri = Main.class.getResource(packageRelativePath).toURI(); + + if (packageUri.getScheme().equals("file")) { + Path packageFullPath = Paths.get(packageUri); + allClasses.addAll(getAllPackageClasses(packageFullPath, packageName)); + } else if (packageUri.getScheme().equals("jar")) { + FileSystem fileSystem = FileSystems.newFileSystem(packageUri, Collections.emptyMap()); + + Path packageFullPathInJar = fileSystem.getPath(packageRelativePath); + allClasses.addAll(getAllPackageClasses(packageFullPathInJar, packageName)); + + fileSystem.close(); + } + } + return allClasses; + } + + private static List> getAllPackageClasses(Path packagePath, String packageName) throws IOException, ClassNotFoundException { + + if (!Files.exists(packagePath)) { + return Collections.emptyList(); + } + + List files = Files.list(packagePath) + .filter(Files::isRegularFile) + .collect(Collectors.toList()); + + List> classes = new ArrayList<>(); + + for (Path filePath : files) { + String fileName = filePath.getFileName().toString(); + + if (fileName.endsWith(".class")) { + String classFullName = packageName.isBlank() ? + fileName.replaceFirst("\\.class$", "") + : packageName + "." + fileName.replaceFirst("\\.class$", ""); + Class clazz = Class.forName(classFullName); + classes.add(clazz); + } + } + return classes; + } +} diff --git a/src/main/java/reflections/retries/annotations/InitializerClass.java b/src/main/java/reflections/retries/annotations/InitializerClass.java new file mode 100644 index 0000000..4d01471 --- /dev/null +++ b/src/main/java/reflections/retries/annotations/InitializerClass.java @@ -0,0 +1,13 @@ + + +package reflections.retries.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface InitializerClass { +} diff --git a/src/main/java/reflections/retries/annotations/InitializerMethod.java b/src/main/java/reflections/retries/annotations/InitializerMethod.java new file mode 100644 index 0000000..918d98f --- /dev/null +++ b/src/main/java/reflections/retries/annotations/InitializerMethod.java @@ -0,0 +1,13 @@ + + +package reflections.retries.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface InitializerMethod { +} diff --git a/src/main/java/reflections/retries/annotations/RetryOperation.java b/src/main/java/reflections/retries/annotations/RetryOperation.java new file mode 100644 index 0000000..bc9c3f7 --- /dev/null +++ b/src/main/java/reflections/retries/annotations/RetryOperation.java @@ -0,0 +1,20 @@ + + +package reflections.retries.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface RetryOperation { + Class[] retryExceptions() default {Exception.class}; + + long durationBetweenRetriesMs() default 0; + + String failureMessage() default "Operation failed after retrying"; + + int numberOfRetries(); +} diff --git a/src/main/java/reflections/retries/annotations/ScanPackages.java b/src/main/java/reflections/retries/annotations/ScanPackages.java new file mode 100644 index 0000000..1bf32a7 --- /dev/null +++ b/src/main/java/reflections/retries/annotations/ScanPackages.java @@ -0,0 +1,14 @@ + + +package reflections.retries.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ScanPackages { + String[] value(); +} diff --git a/src/main/java/reflections/retries/app/AutoSaver.java b/src/main/java/reflections/retries/app/AutoSaver.java new file mode 100644 index 0000000..9b8b278 --- /dev/null +++ b/src/main/java/reflections/retries/app/AutoSaver.java @@ -0,0 +1,15 @@ + + +package reflections.retries.app; + +import reflections.retries.annotations.InitializerClass; +import reflections.retries.annotations.InitializerMethod; + +@InitializerClass +public class AutoSaver { + + @InitializerMethod + public void startAutoSavingThreads() { + System.out.println("Start automatic data saving to disk"); + } +} diff --git a/src/main/java/reflections/retries/app/configs/ConfigsLoader.java b/src/main/java/reflections/retries/app/configs/ConfigsLoader.java new file mode 100644 index 0000000..dfe2bba --- /dev/null +++ b/src/main/java/reflections/retries/app/configs/ConfigsLoader.java @@ -0,0 +1,15 @@ + + +package reflections.retries.app.configs; + +import reflections.retries.annotations.InitializerClass; +import reflections.retries.annotations.InitializerMethod; + +@InitializerClass +public class ConfigsLoader { + + @InitializerMethod + public void loadAllConfigs() { + System.out.println("Loading all configuration files"); + } +} diff --git a/src/main/java/reflections/retries/app/databases/CacheLoader.java b/src/main/java/reflections/retries/app/databases/CacheLoader.java new file mode 100644 index 0000000..8521e05 --- /dev/null +++ b/src/main/java/reflections/retries/app/databases/CacheLoader.java @@ -0,0 +1,19 @@ + + +package reflections.retries.app.databases; + +import reflections.retries.annotations.InitializerClass; +import reflections.retries.annotations.InitializerMethod; + +@InitializerClass +public class CacheLoader { + + @InitializerMethod + public void loadCache() { + System.out.println("Loading data from cache"); + } + + public void reloadCache() { + System.out.println("Reload cache"); + } +} diff --git a/src/main/java/reflections/retries/app/databases/DatabaseConnection.java b/src/main/java/reflections/retries/app/databases/DatabaseConnection.java new file mode 100644 index 0000000..1fb91c9 --- /dev/null +++ b/src/main/java/reflections/retries/app/databases/DatabaseConnection.java @@ -0,0 +1,36 @@ + + +package reflections.retries.app.databases; + +import reflections.retries.annotations.InitializerClass; +import reflections.retries.annotations.InitializerMethod; +import reflections.retries.annotations.RetryOperation; + +import java.io.IOException; + +@InitializerClass +public class DatabaseConnection { + private int failCounter = 5; + + @RetryOperation( + numberOfRetries = 10, + retryExceptions = IOException.class, + durationBetweenRetriesMs = 1000, + failureMessage = "Connection to database 1 failed after retries" + ) + @InitializerMethod + public void connectToDatabase1() throws IOException { + System.out.println("Connecting to database 1"); + if (failCounter > 0) { + failCounter--; + throw new IOException("Connection failed"); + } + + System.out.println("Connection to database 1 succeeded"); + } + + @InitializerMethod + public void connectToDatabase2() { + System.out.println("Connecting to database 2"); + } +} diff --git a/src/main/java/reflections/retries/app/http/ServiceRegistry.java b/src/main/java/reflections/retries/app/http/ServiceRegistry.java new file mode 100644 index 0000000..0839c9f --- /dev/null +++ b/src/main/java/reflections/retries/app/http/ServiceRegistry.java @@ -0,0 +1,15 @@ + + +package reflections.retries.app.http; + +import reflections.retries.annotations.InitializerClass; +import reflections.retries.annotations.InitializerMethod; + +@InitializerClass +public class ServiceRegistry { + + @InitializerMethod + public void registerService() { + System.out.println("Service successfully registered"); + } +} diff --git a/src/main/java/reflections/topologicalsort/BestGamesFinder.java b/src/main/java/reflections/topologicalsort/BestGamesFinder.java new file mode 100644 index 0000000..b38c84b --- /dev/null +++ b/src/main/java/reflections/topologicalsort/BestGamesFinder.java @@ -0,0 +1,44 @@ +package reflections.topologicalsort; + +import reflections.topologicalsort.databases.Database; + +import java.util.*; + +import static reflections.topologicalsort.annotations.Annotations.*; + +public class BestGamesFinder { + private Database database = new Database(); + + @Operation("All-Games") + public Set getAllGames() { + return database.readAllGames(); + } + + @Operation("Game-To-Price") + public Map getGameToPrice(@DependsOn("All-Games") Set allGames) { + return database.readGameToPrice(allGames); + } + + @Operation("Game-To-Rating") + public Map getGameToRating(@DependsOn("All-Games") Set allGames) { + return database.readGameToRatings(allGames); + } + + @Operation("Score-To-Game") + public SortedMap scoreGames(@DependsOn("Game-To-Price") Map gameToPrice, + @DependsOn("Game-To-Rating") Map gameToRating) { + SortedMap gameToScore = new TreeMap<>(Collections.reverseOrder()); + for (String gameName : gameToPrice.keySet()) { + double score = (double) gameToRating.get(gameName) / gameToPrice.get(gameName); + gameToScore.put(score, gameName); + } + + return gameToScore; + } + + @FinalResult + public List getTopGames(@DependsOn("Score-To-Game") SortedMap gameToScore) { + return new ArrayList<>(gameToScore.values()); + } +} + diff --git a/src/main/java/reflections/topologicalsort/Main.java b/src/main/java/reflections/topologicalsort/Main.java new file mode 100644 index 0000000..f4ce11e --- /dev/null +++ b/src/main/java/reflections/topologicalsort/Main.java @@ -0,0 +1,105 @@ +package reflections.topologicalsort; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.*; + +import static reflections.topologicalsort.annotations.Annotations.*; + +/** + * Graph Execution with Inputs + * https://www.udemy.com/course/java-reflection-master-class + */ +public class Main { + + public static void main(String[] args) throws InvocationTargetException, IllegalAccessException { + SqlQueryBuilder sqlQueryBuilder = new SqlQueryBuilder(Arrays.asList("1", "2", "3"), + 10, + "Movies", + Arrays.asList("Id", "Name")); + + String sqlQuery = execute(sqlQueryBuilder); + System.out.println(sqlQuery); + } + + public static T execute(Object instance) throws InvocationTargetException, IllegalAccessException { + Class clazz = instance.getClass(); + + Map operationToMethod = getOperationToMethod(clazz); + Map inputToField = getInputToField(clazz); + + Method finalResultMethod = findFinalResultMethod(clazz); + + return (T) executeWithDependencies(instance, finalResultMethod, operationToMethod, inputToField); + } + + private static Object executeWithDependencies(Object instance, + Method currentMethod, + Map operationToMethod, + Map inputToField) throws InvocationTargetException, IllegalAccessException { + List parameterValues = new ArrayList<>(currentMethod.getParameterCount()); + + for (Parameter parameter : currentMethod.getParameters()) { + Object value = null; + if (parameter.isAnnotationPresent(DependsOn.class)) { + String dependencyOperationName = parameter.getAnnotation(DependsOn.class).value(); + Method dependencyMethod = operationToMethod.get(dependencyOperationName); + + value = executeWithDependencies(instance, dependencyMethod, operationToMethod, inputToField); + } else if (parameter.isAnnotationPresent(Input.class)) { + String inputName = parameter.getAnnotation(Input.class).value(); + + Field field = inputToField.get(inputName); + field.setAccessible(true); + + value = field.get(instance); + } + + parameterValues.add(value); + } + + return currentMethod.invoke(instance, parameterValues.toArray()); + } + + private static Map getInputToField(Class clazz) { + Map inputNameToField = new HashMap<>(); + + for (Field field : clazz.getDeclaredFields()) { + if (!field.isAnnotationPresent(Input.class)) { + continue; + } + + Input input = field.getAnnotation(Input.class); + inputNameToField.put(input.value(), field); + } + + return inputNameToField; + } + + private static Map getOperationToMethod(Class clazz) { + Map operationNameToMethod = new HashMap<>(); + + for (Method method : clazz.getDeclaredMethods()) { + if (!method.isAnnotationPresent(Operation.class)) { + continue; + } + + Operation operation = method.getAnnotation(Operation.class); + + operationNameToMethod.put(operation.value(), method); + } + return operationNameToMethod; + } + + private static Method findFinalResultMethod(Class clazz) { + for (Method method : clazz.getDeclaredMethods()) { + if (method.isAnnotationPresent(FinalResult.class)) { + return method; + } + } + + throw new RuntimeException("No method found with FinalResult annotation"); + } +} diff --git a/src/main/java/reflections/topologicalsort/SqlQueryBuilder.java b/src/main/java/reflections/topologicalsort/SqlQueryBuilder.java new file mode 100644 index 0000000..c707c37 --- /dev/null +++ b/src/main/java/reflections/topologicalsort/SqlQueryBuilder.java @@ -0,0 +1,55 @@ +package reflections.topologicalsort; + +import reflections.topologicalsort.annotations.Annotations; + +import java.util.List; + +public class SqlQueryBuilder { + + @Annotations.Input("ids") + private List ids; + + @Annotations.Input("limit") + private Integer limit; + + @Annotations.Input("table") + private String tableName; + + @Annotations.Input("columns") + private List columnNames; + + public SqlQueryBuilder(List ids, Integer limit, String tableName, List columnNames) { + this.ids = ids; + this.limit = limit; + this.tableName = tableName; + this.columnNames = columnNames; + } + + @Annotations.Operation("SelectBuilder") + public String selectStatementBuilder(@Annotations.Input("table") String tableName, @Annotations.Input("columns") List columnNames) { + String columnsString = columnNames.isEmpty() ? "*" : String.join(",", columnNames); + + return String.format("SELECT %s FROM %s", columnsString, tableName); + } + + @Annotations.FinalResult + public String addWhereClause(@Annotations.DependsOn("SelectBuilder") String query, @Annotations.Input("ids") List ids) { + if (ids.isEmpty()) { + return query; + } + + return String.format("%s WHERE id IN (%s)", query, String.join(",", ids)); + } + + public String addLimit(@Annotations.DependsOn("SelectBuilder") String query, @Annotations.Input("limit") Integer limit) { + if (limit == null || limit == 0) { + return query; + } + + if (limit < 0) { + throw new RuntimeException("limit cannot be negative"); + } + + return String.format("%s LIMIT %d", query, limit.intValue()); + } +} diff --git a/src/main/java/reflections/topologicalsort/annotations/Annotations.java b/src/main/java/reflections/topologicalsort/annotations/Annotations.java new file mode 100644 index 0000000..808f76f --- /dev/null +++ b/src/main/java/reflections/topologicalsort/annotations/Annotations.java @@ -0,0 +1,34 @@ + + +package reflections.topologicalsort.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +public class Annotations { + + @Target({ElementType.FIELD, ElementType.PARAMETER}) + @Retention(RetentionPolicy.RUNTIME) + public @interface Input { + String value(); + } + + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + public @interface Operation { + String value(); + } + + @Target(ElementType.PARAMETER) + @Retention(RetentionPolicy.RUNTIME) + public @interface DependsOn { + String value(); + } + + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + public @interface FinalResult { + } +} diff --git a/src/main/java/reflections/topologicalsort/databases/Database.java b/src/main/java/reflections/topologicalsort/databases/Database.java new file mode 100644 index 0000000..e49f04f --- /dev/null +++ b/src/main/java/reflections/topologicalsort/databases/Database.java @@ -0,0 +1,38 @@ + + +package reflections.topologicalsort.databases; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * Simulates database + */ +public class Database { + /// Game Name -> (Rating, Price) + private Map> GAME_TO_PRICE = Map.of("Fortnite", Arrays.asList(5f, 10f), + "Minecraft", Arrays.asList(4.3f, 100f), + "League Of Legends", Arrays.asList(4.9f, 89f), + "Ace Combat", Arrays.asList(4.8f, 50f), + "StarCraft", Arrays.asList(4.7f, 66f), + "Burnout", Arrays.asList(4.4f, 31f)); + + + public Set readAllGames() { + return Collections.unmodifiableSet(GAME_TO_PRICE.keySet()); + } + + public Map readGameToRatings(Set games) { + return GAME_TO_PRICE.entrySet() + .stream() + .filter(entry -> games.contains(entry.getKey())) + .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, entry -> entry.getValue().get(0))); + } + + public Map readGameToPrice(Set games) { + return GAME_TO_PRICE.entrySet() + .stream() + .filter(entry -> games.contains(entry.getKey())) + .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, entry -> entry.getValue().get(1))); + } +} diff --git a/src/main/java/sorting/InsertionSort.java b/src/main/java/sorting/InsertionSort.java new file mode 100644 index 0000000..fa4572a --- /dev/null +++ b/src/main/java/sorting/InsertionSort.java @@ -0,0 +1,23 @@ +package sorting; + +public class InsertionSort { + + public static void main(String[] args) { + int[] arr = {12, 11, 13, 5, 6}; + System.out.println(System.currentTimeMillis()); + + for (int i = 1; i < arr.length; i++) { + int index = i; + for (int j = i - 1; j >= 0; j--) { + if (arr[index] < arr[j]) { + int temp = arr[j]; + arr[j] = arr[index]; + arr[index] = temp; + index--; + } + } + } + System.out.println(System.currentTimeMillis()); + } + +} diff --git a/src/sorting/KthLargestElement.java b/src/main/java/sorting/KthLargestElement.java similarity index 100% rename from src/sorting/KthLargestElement.java rename to src/main/java/sorting/KthLargestElement.java diff --git a/src/main/java/sorting/MaxHeap.java b/src/main/java/sorting/MaxHeap.java new file mode 100644 index 0000000..0a50d1e --- /dev/null +++ b/src/main/java/sorting/MaxHeap.java @@ -0,0 +1,51 @@ +package sorting; + +public class MaxHeap { + + public static void main(String[] args) { + int arr[] = {7, 4, 55, 2, 77, 54, 3, 1, 12, 16, 19, 20}; + MaxHeap heap = new MaxHeap(); + heap.sort(arr); + + } + + private void sort(int[] arr) { + int n = arr.length; + + for (int i = n / 2 - 1; i >= 0; i--) + heapify(arr, i, n); + + for (int i = 0; i < n; i++) + System.out.print(arr[i] + " "); + + System.out.println(); + for (int i = n - 1; i >= 0; i--) { + int temp = arr[0]; + arr[0] = arr[i]; + arr[i] = temp; + + heapify(arr, 0, i); + } + + for (int i = 0; i < n; i++) + System.out.print(arr[i] + " "); + } + + private void heapify(int[] arr, int i, int n) { + int largest = i; + int left = 2 * i + 1; + int right = 2 * i + 2; + + if (left < n && arr[left] > arr[largest]) + largest = left; + if (right < n && arr[right] > arr[largest]) + largest = right; + if (largest != i) { + int temp = arr[largest]; + arr[largest] = arr[i]; + arr[i] = temp; + + heapify(arr, largest, n); + } + } +} \ No newline at end of file diff --git a/src/sorting/MergeSort.java b/src/main/java/sorting/MergeSort.java similarity index 100% rename from src/sorting/MergeSort.java rename to src/main/java/sorting/MergeSort.java diff --git a/src/main/java/sorting/MinHeap.java b/src/main/java/sorting/MinHeap.java new file mode 100644 index 0000000..5abf4a3 --- /dev/null +++ b/src/main/java/sorting/MinHeap.java @@ -0,0 +1,225 @@ +package sorting; +/* + A min heap implementation + + Array Form: [ 5, 7, 6, 10, 15, 17, 12 ] + + Complete Binary Tree Form: + 5 + / \ + 7 6 + / \ / \ + 10 15 17 12 + + Mappings: + Parent -> (childIndex - 1) / 2 + Left Child -> 2 * parentIndex + 1 + Right Child -> 2 * parentIndex + 2 + + YouTube explanation: https://www.youtube.com/watch?v=g9YK6sftDi0 + Heap Sort explanation: https://www.youtube.com/watch?v=k72DtCnY4MU +*/ + +import java.util.*; + +public class MinHeap { + + public MinHeap() { + elements = new int[capacity]; + } + + private int capacity = 5; + private int[] elements; + private int size; + + public void add(int itemToAdd) { + ensureExtraCapacity(); + elements[size] = itemToAdd; + size++; + siftUp(); + } + + public boolean isEmpty() { + return size == 0; + } + + public int peek() { + if (isEmpty()) { + throw new NoSuchElementException("Heap is empty."); + } + + return elements[0]; + } + + public int remove() { + if (isEmpty()) { + throw new NoSuchElementException("Heap is empty."); + } + + int minItem = elements[0]; + elements[0] = elements[size - 1]; + size--; + + heapifyDown(); + + return minItem; + } + + + private void heapifyDown() { + + /* + We will bubble down the item just swapped to the "top" of the heap + after a removal operation to restore the heap + */ + int index = 0; + + /* + Since a binary heap is a complete binary tree, if we have no left child + then we have no right child. So we continue to bubble down as long as + there is a left child. + + A non-existent left child immediately tells us that a right child does + not exist. + */ + while (hasLeftChild(index)) { + /* + By default, assume that left child is smaller. If a right + child exists see if it can overtake the left child by + being smaller + */ + int smallerChildIndex = getLeftChildIndex(index); + + if (hasRightChild(index) && rightChild(index) < leftChild(index)) { + smallerChildIndex = getRightChildIndex(index); + } + + /* + If the item we are sitting on is < the smaller child then + nothing needs to happen & sifting down is finished. + + But if the smaller child is smaller than the node we are + holding, we should swap and continue sifting down. + */ + if (elements[index] < elements[smallerChildIndex]) { + break; + } else { + swap(index, smallerChildIndex); + } + + // Move to the node we just swapped down + index = smallerChildIndex; + } + } + + // Bubble up the item we inserted at the "end" of the heap + private void siftUp() { + /* + We will bubble up the item just inserted into to the "bottom" + of the heap after an insert operation. It will be at the last index + so index 'size' - 1 + */ + int index = size - 1; + + /* + While the item has a parent and the item beats its parent in + smallness, bubble this item up. + */ + while (hasParent(index) && elements[index] < parent(index)) { + swap(getParentIndex(index), index); + index = getParentIndex(index); + } + } + + /************************************************ + Helpers to access our array easily, perform + rudimentary operations, and manipulate capacity + ************************************************/ + + private void swap(int indexOne, int indexTwo) { + int temp = elements[indexOne]; + elements[indexOne] = elements[indexTwo]; + elements[indexTwo] = temp; + } + + // If heap is full then double capacity + private void ensureExtraCapacity() { + if (size == capacity) { + elements = Arrays.copyOf(elements, capacity * 2); + capacity *= 2; + } + } + + private int getLeftChildIndex(int parentIndex) { + return 2 * parentIndex + 1; + } + + private int getRightChildIndex(int parentIndex) { + return 2 * parentIndex + 2; + } + + private int getParentIndex(int childIndex) { + return (childIndex - 1) / 2; + } + + private boolean hasLeftChild(int index) { + return getLeftChildIndex(index) < size; + } + + private boolean hasRightChild(int index) { + return getRightChildIndex(index) < size; + } + + private boolean hasParent(int index) { + return index != 0 && getParentIndex(index) >= 0; + } + + private int leftChild(int index) { + return elements[getLeftChildIndex(index)]; + } + + private int rightChild(int index) { + return elements[getRightChildIndex(index)]; + } + + private int parent(int index) { + return elements[getParentIndex(index)]; + } + + /***********************************************/ + + private void printUnderlyingArray() { + System.out.print("[ "); + for (int item : elements) { + System.out.print(item + " "); + } + System.out.print("]"); + } + + public static void main(String args[]) { + MinHeap minHeap = new MinHeap(); + int[] insertItems = new int[]{0, 1, 3, 2, -4, 9, 1, 2}; + + for (int insertItem : insertItems) { + minHeap.add(insertItem); + System.out.println("Add " + insertItem); + System.out.println("Min is " + minHeap.peek()); + + minHeap.printUnderlyingArray(); + + System.out.println("\n"); + } + + System.out.println("\n\n"); + + for (int i = 0; i < insertItems.length; i++) { + System.out.println("Remove " + minHeap.remove()); + System.out.println("Min is " + minHeap.peek()); + + minHeap.printUnderlyingArray(); + + System.out.println("\n"); + } + } + +} \ No newline at end of file diff --git a/src/main/java/sorting/MinHeapTest.java b/src/main/java/sorting/MinHeapTest.java new file mode 100644 index 0000000..dffd2c4 --- /dev/null +++ b/src/main/java/sorting/MinHeapTest.java @@ -0,0 +1,107 @@ +package sorting; + +import java.util.NoSuchElementException; + +public class MinHeapTest { + + int[] elements; + int capacity; + int currentIndex; + + public MinHeapTest(int capacity) { + this.capacity = capacity; + this.elements = new int[capacity]; + } + + public void add(int value) { + currentIndex++; + if (currentIndex > capacity) { + currentIndex--; + return; + } + + elements[currentIndex] = value; + + verifyParent(currentIndex); + } + + public int peek() { + if (currentIndex < 0 || currentIndex > capacity) return Integer.MIN_VALUE; + return elements[0]; + } + + public int remove() { + if (isEmpty()) { + throw new NoSuchElementException("Heap is empty."); + } + int result = elements[0]; + currentIndex--; + elements[0] = elements[currentIndex]; + + verifyChild(); + return result; + } + + private boolean isEmpty() { + return currentIndex < 0; + } + + public void verifyParent(int currentIndex) { + int index = currentIndex; + + while (hasParent(index) && elements[index] < elements[getParentIndex(index)]) { + swap(index, getParentIndex(index)); + index = getParentIndex(index); + } + } + + private void swap(int index, int parentIndex) { + int temp = elements[index]; + elements[index] = elements[parentIndex]; + elements[parentIndex] = temp; + } + + private boolean hasParent(int index) { + return index != 0 || getParentIndex(index) >= 0; + } + + private int getParentIndex(int childIndex) { + return (childIndex - 1) / 2; + } + + public void verifyChild() { + int index = 0; + + while (hasLeftChildren(index)) { + + int minIndex = getLeftChildIndex(index); + if (hasRightChildren(index) && elements[getRightChildIndex(index)] < elements[minIndex]) { + minIndex = getRightChildIndex(index); + } + + if (elements[minIndex] < elements[index]) { + swap(index, minIndex); + } else { + break; + } + index = minIndex; + } + } + + private boolean hasRightChildren(int index) { + return getRightChildIndex(index) < capacity; + } + + private int getRightChildIndex(int parentIndex) { + return 2 * parentIndex + 2; + } + + private boolean hasLeftChildren(int index) { + return getLeftChildIndex(index) < capacity; + } + + private int getLeftChildIndex(int parentIndex) { + return 2 * parentIndex + 1; + } + +} diff --git a/src/sorting/PractiseMergeSort.java b/src/main/java/sorting/PractiseMergeSort.java similarity index 100% rename from src/sorting/PractiseMergeSort.java rename to src/main/java/sorting/PractiseMergeSort.java diff --git a/src/sorting/QuickSelect.java b/src/main/java/sorting/QuickSelect.java similarity index 100% rename from src/sorting/QuickSelect.java rename to src/main/java/sorting/QuickSelect.java diff --git a/src/sorting/QuickSort.java b/src/main/java/sorting/QuickSort.java similarity index 91% rename from src/sorting/QuickSort.java rename to src/main/java/sorting/QuickSort.java index d067654..5354cf3 100644 --- a/src/sorting/QuickSort.java +++ b/src/main/java/sorting/QuickSort.java @@ -33,7 +33,9 @@ public int findPivot(int[] nums, int start, int end){ end--; while(start<=end){ - if(nums[start] + Integer.compare(cache[a - 'a'], cache[b - 'a']) + ); + StringBuilder sb = new StringBuilder(); + for (Character i : tmpArr) { + sb.append(i); + } + return sb.toString(); + } + + public String customSortString(String order, String str) { + int[] cache = new int[26]; + // take target's char counts + for (char c : str.toCharArray()) { + cache[c - 'a']++; + } + StringBuilder sb = new StringBuilder(); + // greedily populate the order chars as first + for (char c : order.toCharArray()) { + if (cache[c - 'a'] == 0) continue; + int occurence = cache[c - 'a']; + while (occurence-- > 0) { + sb.append(c); + } + cache[c - 'a'] = 0; + } + // then populate the non order chars + for (int i = 0; i < 26; i++) { + int occurrence = cache[i]; + while (occurrence-- > 0) { + sb.append((char) (i + 'a')); + } + cache[i] = 0; + } + return sb.toString(); + } +} diff --git a/src/strings/stringProblems/DistinctSubstring.java b/src/main/java/strings/stringProblems/DistinctSubstring.java similarity index 100% rename from src/strings/stringProblems/DistinctSubstring.java rename to src/main/java/strings/stringProblems/DistinctSubstring.java diff --git a/src/strings/stringProblems/FindLongestStringInArray.java b/src/main/java/strings/stringProblems/FindLongestStringInArray.java similarity index 100% rename from src/strings/stringProblems/FindLongestStringInArray.java rename to src/main/java/strings/stringProblems/FindLongestStringInArray.java diff --git a/src/main/java/strings/stringProblems/LongestCommonPrefix.java b/src/main/java/strings/stringProblems/LongestCommonPrefix.java new file mode 100644 index 0000000..3683619 --- /dev/null +++ b/src/main/java/strings/stringProblems/LongestCommonPrefix.java @@ -0,0 +1,39 @@ +package strings.stringProblems; + +import java.util.Arrays; + +public class LongestCommonPrefix { + + /** + * The first thing to understand is that the longest common prefix can only be as long as the shortest string with a commo prefix in the array. + * So, when we sort, the shortest string with a common prefix will be the first string (assuming ascending order). + * + * Then, we have to understand that the longest common prefix must apply for ALL array elements, + * if there's an array element that does not have the longest common prefix you've found so far, then there is no prefix, it's empty string. + * So, for example, if the first string is "aaa" and last string comes out to be "baa", then there is no common prefix. + * + * ["HAM",.........."HAMPER"] + * So, here the first and only the last is compared because if all the middle starts with "HAM" and even the last one is "HAM ", + * that means all the middle one would have had "HAM" in them. + * + * Arrays.Sort sorts the string in a lexicographical order. Which means that the order would be following: + * AAA + * AAAA + * AAB + * BAA + */ + public String longestCommonPrefix(String[] strs) { + if (strs == null || strs.length == 0) return ""; + if (strs.length == 1) return strs[0]; + + StringBuilder sb = new StringBuilder(); + Arrays.sort(strs); + char[] first = strs[0].toCharArray(); + char[] last = strs[strs.length - 1].toCharArray(); + for (int i = 0, j = 0; i < first.length && j < last.length; i++, j++) { + if (first[i] != last[j]) break; + sb.append(first[i]); + } + return sb.toString(); + } +} diff --git a/src/strings/stringProblems/MostCommonWord.java b/src/main/java/strings/stringProblems/MostCommonWord.java similarity index 100% rename from src/strings/stringProblems/MostCommonWord.java rename to src/main/java/strings/stringProblems/MostCommonWord.java diff --git a/src/strings/stringProblems/PermutationAndCombination.java b/src/main/java/strings/stringProblems/PermutationAndCombination.java similarity index 100% rename from src/strings/stringProblems/PermutationAndCombination.java rename to src/main/java/strings/stringProblems/PermutationAndCombination.java diff --git a/src/main/java/strings/stringProblems/PushDominoes.java b/src/main/java/strings/stringProblems/PushDominoes.java new file mode 100644 index 0000000..e7582b5 --- /dev/null +++ b/src/main/java/strings/stringProblems/PushDominoes.java @@ -0,0 +1,112 @@ +package strings.stringProblems; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/push-dominoes + */ +public class PushDominoes { + + /** + * // if there is NO dot (meaning every domino is pushed), then the final state is the initial state + * // for example, all "LLL" => "LLL", all "RRR" => "RRR", + * // mixed "LLLRR" => "LLLRR" (falling domino having no effect on already-fallen domino) + * // if there is only ONE dot, we have a few possibilities: + * // "L.R" => "L.R", "R.L" => "R.L" (center-one standing), "L.L" => "LLL", "R.R" => "RRR" + * // if there are Three dots, we have the following possibilities: + * // "L..R" => "L..R", "R..L" => "RRLL" (center-one standing), "L..L" => "LLLL", "R..R" => "RRRR" + * // if there are TWO dots, we have the following possibilities: + * // "L...R" => "L...R", "R...L" => "RR.LL" (center-one standing), "L...L" => "LLLLL", "R...R" => "RRRRR" + * // Therefore the rule is: + * // for each region of dots (a substring "P....Q"), check its left and right + * // if left is "L" and right is "R", the substring remains as is; + * // if left is "R" and right is "L", the substring is converted into either "RRRLLL" or "RR.LL" + * // if left and right are the same, the substring is converted into either "RRRRR" or "LLLLL" + * + * @param dominoes + * @return + */ + public String pushDominoes(String dominoes) { + // place a sentinel "L" + dominoes + "R", as this does not impact the final outcome + dominoes = "L" + dominoes + "R"; + char[] dom = dominoes.toCharArray(); + + int i = 0; // slow pointer + int j = 0; + while (i < dominoes.length() - 1) { + j = i + 1; // fast pointer + while (j < dominoes.length() && dominoes.charAt(j) == '.') j++; + + if (dom[i] == dom[j]) Arrays.fill(dom, i, j, dom[i]); + + else if (dom[i] == 'R' && dom[j] == 'L') { + int effect = (j - i - 1) / 2; + /** + * // half R + * for (int count = 0; count < effect / 2; count++) { + * builder.append('R'); + * } + * if (1 == countDots % 2) { + * // center dot + * builder.append('.'); + * } + * // half L + * for (int count = 0; count < effect / 2; count++) { + * builder.append('L'); + * } + */ + Arrays.fill(dom, i, i + effect + 1, 'R'); + Arrays.fill(dom, j - effect, j + 1, 'L'); + } + + i = j; + } + + return new String(Arrays.copyOfRange(dom, 1, dom.length - 1)); + } + + public String pushDominoesAnother(String dominoes) { + int[] leftForce = new int[dominoes.length()]; + int[] rightForce = new int[dominoes.length()]; + int lastSeen = -1; + for (int i = dominoes.length() - 1; i >= 0; i--) { + if (dominoes.charAt(i) == 'L') lastSeen = i; + else if (dominoes.charAt(i) == 'R') lastSeen = -1; + + leftForce[i] = lastSeen; + } + lastSeen = -1; + for (int i = 0; i < dominoes.length(); i++) { + if (dominoes.charAt(i) == 'R') lastSeen = i; + else if (dominoes.charAt(i) == 'L') lastSeen = -1; + + rightForce[i] = lastSeen; + } + char[] result = new char[dominoes.length()]; + + for (int i = 0; i < dominoes.length(); i++) { + if (dominoes.charAt(i) == '.') { + + int nearestLeft = leftForce[i]; + int nearestRight = rightForce[i]; + + int leftDiff = nearestLeft == -1 ? Integer.MAX_VALUE : Math.abs(nearestLeft - i); + int rightDiff = nearestRight == -1 ? Integer.MAX_VALUE : Math.abs(nearestRight - i); + + if (leftDiff == rightDiff) { + result[i] = '.'; + } else if (leftDiff < rightDiff) { + result[i] = 'L'; + } else if (leftDiff > rightDiff) { + result[i] = 'R'; + } + + } else { + result[i] = dominoes.charAt(i); + } + + } + + return new String(result); + } +} diff --git a/src/strings/stringProblems/RearrangeCharactersInString.java b/src/main/java/strings/stringProblems/RearrangeCharactersInString.java similarity index 99% rename from src/strings/stringProblems/RearrangeCharactersInString.java rename to src/main/java/strings/stringProblems/RearrangeCharactersInString.java index 29f831a..8e88e0c 100644 --- a/src/strings/stringProblems/RearrangeCharactersInString.java +++ b/src/main/java/strings/stringProblems/RearrangeCharactersInString.java @@ -4,6 +4,9 @@ import java.util.Map; import java.util.PriorityQueue; +/** + * + */ public class RearrangeCharactersInString { public static String rearrangeString(String S) { diff --git a/src/main/java/strings/stringProblems/ShiftingLetters.java b/src/main/java/strings/stringProblems/ShiftingLetters.java new file mode 100644 index 0000000..1e7db0a --- /dev/null +++ b/src/main/java/strings/stringProblems/ShiftingLetters.java @@ -0,0 +1,36 @@ +package strings.stringProblems; + +public class ShiftingLetters { + public String shiftingLetters(String s, int[] shifts) { + int total = 0; + shifts[shifts.length - 1] %= 26; + for (int i = shifts.length - 2; i >= 0; i--) { + shifts[i] += shifts[i + 1]; + shifts[i] %= 26; + } + + //System.out.println(Arrays.toString(shifts)); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { + int temp = s.charAt(i) - 'a'; + temp = (temp + shifts[i]) % 26; + char val = (char) (temp + 'a'); + sb.append("" + val); + } + + return sb.toString(); + } + + public String shiftingLettersEffective(String S, int[] shifts) { + char[] arr = S.toCharArray(); + int sum = 0; + for (int i = shifts.length - 1; i >= 0; i--) { + int cur = arr[i] - 'a'; + sum += shifts[i] % 26; + cur += sum; + arr[i] = (char) ('a' + cur % 26); + } + + return new String(arr); + } +} diff --git a/src/main/java/strings/stringProblems/ShortDistanceBetweenChars.java b/src/main/java/strings/stringProblems/ShortDistanceBetweenChars.java new file mode 100644 index 0000000..4bf41eb --- /dev/null +++ b/src/main/java/strings/stringProblems/ShortDistanceBetweenChars.java @@ -0,0 +1,31 @@ +package strings.stringProblems; + +/** + * https://leetcode.com/problems/shortest-distance-to-a-character + */ +public class ShortDistanceBetweenChars { + + public int[] shortestToChar(String s, char c) { + + int[] result = new int[s.length()]; + //Before the first C value is reached, there is no index behind it to compute a difference. + //So letting lastSeen = Integer.MAX_VALUE assures that the computed difference on the first pass before the first C value is reached is higher than what would be computed on the way back. + int lastSeen = Integer.MAX_VALUE; + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == c) { + lastSeen = i; + } + + result[i] = Math.abs(lastSeen - i); + } + + for (int i = s.length() - 1; i >= 0; i--) { + if (s.charAt(i) == c) { + lastSeen = i; + } + result[i] = Math.min(result[i], Math.abs(lastSeen - i)); + } + + return result; + } +} diff --git a/src/main/java/strings/stringProblems/SlowestKey.java b/src/main/java/strings/stringProblems/SlowestKey.java new file mode 100644 index 0000000..4fda0a7 --- /dev/null +++ b/src/main/java/strings/stringProblems/SlowestKey.java @@ -0,0 +1,27 @@ +package strings.stringProblems; + +/** + * https://leetcode.com/problems/slowest-key/ + */ +public class SlowestKey { + public char slowestKey(int[] releaseTimes, String keysPressed) { + int index = 0; + + int duration = 0; + int maxDuration = releaseTimes[0]; + + for (int i = 1; i < releaseTimes.length; i++) { + duration = releaseTimes[i] - releaseTimes[i - 1]; + + if (duration > maxDuration || (maxDuration == duration && keysPressed.charAt(index) < keysPressed.charAt(i))) { + + maxDuration = duration; + index = i; + + } + + } + + return keysPressed.charAt(index); + } +} diff --git a/src/main/java/strings/stringmatching/KMP.java b/src/main/java/strings/stringmatching/KMP.java new file mode 100644 index 0000000..484f254 --- /dev/null +++ b/src/main/java/strings/stringmatching/KMP.java @@ -0,0 +1,60 @@ +package strings.stringmatching; + +import java.util.Arrays; + +/** + * the key to KMP algo is prefix suffix match i.e the longest prefix which is also a suffix (LPS) + * + * for example take a pattern abcdabcd + * + * the prefix = [a,ab,abc,abcd,abcda,abcdab,abcdabc,final string] + * the suffix = [d,cd,bcd,abcd,dabcd,cdabcd,bcdabcd, final string] + * we will not consider final string because that'll be used in last step for final comparison + * + * in the above example index abcd is the longest prefix which is same as suffix. + * + * This LPS tells which index should we move back to in case of pattern match failure + */ +public class KMP { + + public static void main(String[] args) { + String given = "abxabcabcabyasd"; + String pattern = "abcaby"; + System.out.println(strStr(given, pattern)); + } + + + public static int strStr( String haystack, String needle) { + if (needle.isEmpty()) return 0; + int[] lps = computeKMPTable(needle); + int i = 0, j = 0, n = haystack.length(), m = needle.length(); + while (i < n) { + if (haystack.charAt(i) == needle.charAt(j)) { + ++i; ++j; + if (j == m) return i - m; // found solution + } else { + if (j != 0) j = lps[j - 1]; // try match with longest prefix suffix + else i++; // don't match -> go to next character of `haystack` string + } + } + return -1; + } + private static int[] computeKMPTable(String pattern) { + int i = 1, j = 0, n = pattern.length(); + int[] lps = new int[n]; + while (i < n) { + if (pattern.charAt(i) == pattern.charAt(j)) { + lps[i++] = ++j; + } else { + if (j != 0) { + j = lps[j - 1]; // try match with longest prefix suffix + } + else{ + i++; // don't match -> go to next character + } + } + } + return lps; + } + +} diff --git a/src/strings/stringmatching/MaxProductString.java b/src/main/java/strings/stringmatching/MaxProductString.java similarity index 100% rename from src/strings/stringmatching/MaxProductString.java rename to src/main/java/strings/stringmatching/MaxProductString.java diff --git a/src/main/java/trees/AVLTree.java b/src/main/java/trees/AVLTree.java new file mode 100644 index 0000000..4e82d7d --- /dev/null +++ b/src/main/java/trees/AVLTree.java @@ -0,0 +1,178 @@ +package trees; + +public class AVLTree> implements Tree { + + private Node root; + + @Override + public Tree insert(T data) { + root = insert(data, root); + return this; + } + + private Node insert(T data, Node node) { + if (node == null) { + return new Node<>(data); + } + if (data.compareTo(node.getData()) < 0) { + node.setLeftChild(insert(data, node.getLeftChild())); + } else if (data.compareTo(node.getData()) > 0) { + node.setRightChild(insert(data, node.getRightChild())); + } else { + return node; + } + updateHeight(node); + return applyRotation(node); + } + + @Override + public void delete(T data) { + root = delete(data, root); + } + + private Node delete(T data, Node node) { + if (node == null) { + return null; + } + if (data.compareTo(node.getData()) < 0) { + node.setLeftChild(delete(data, node.getLeftChild())); + } else if (data.compareTo(node.getData()) > 0) { + node.setRightChild(delete(data, node.getRightChild())); + } else { + // One Child or Leaf Node (no children) + if (node.getLeftChild() == null) { + return node.getRightChild(); + } else if (node.getRightChild() == null) { + return node.getLeftChild(); + } + // Two Children + node.setData(getMax(node.getLeftChild())); + node.setLeftChild(delete(node.getData(), node.getLeftChild())); + } + updateHeight(node); + return applyRotation(node); + } + + @Override + public void traverse() { + traverseInOrder(root); + } + + private void traverseInOrder(Node node) { + if (node != null) { + traverseInOrder(node.getLeftChild()); + System.out.println(node); + traverseInOrder(node.getRightChild()); + } + } + + @Override + public T getMax() { + if (isEmpty()) { + return null; + } + return getMax(root); + } + + private T getMax(Node node) { + if (node.getRightChild() != null) { + return getMax(node.getRightChild()); + } + return node.getData(); + } + + @Override + public T getMin() { + if (isEmpty()) { + return null; + } + return getMin(root); + } + + private T getMin(Node node) { + if (node.getLeftChild() != null) { + return getMin(node.getLeftChild()); + } + return node.getData(); + } + + @Override + public boolean isEmpty() { + return root == null; + } + + private Node applyRotation(Node node) { + int balance = balance(node); + if (balance > 1) { + if (balance(node.getLeftChild()) < 0) { + node.setLeftChild(rotateLeft(node.getLeftChild())); + } + return rotateRight(node); + } + if (balance < -1) { + if (balance(node.getRightChild()) > 0) { + node.setRightChild(rotateRight(node.getRightChild())); + } + return rotateLeft(node); + } + return node; + } + + private Node rotateRight(Node node) { + Node leftNode = node.getLeftChild(); + Node centerNode = leftNode.getRightChild(); + leftNode.setRightChild(node); + node.setLeftChild(centerNode); + updateHeight(node); + updateHeight(leftNode); + return leftNode; + } + + private Node rotateLeft(Node node) { + Node rightNode = node.getRightChild(); + Node centerNode = rightNode.getLeftChild(); + rightNode.setLeftChild(node); + node.setRightChild(centerNode); + updateHeight(node); + updateHeight(rightNode); + return rightNode; + } + + private void updateHeight(Node node) { + int maxHeight = Math.max( + height(node.getLeftChild()), + height(node.getRightChild()) + ); + node.setHeight(maxHeight + 1); + } + + private int balance(Node node) { + return node != null ? height(node.getLeftChild()) - height(node.getRightChild()) : 0; + } + + private int height(Node node) { + return node != null ? node.getHeight() : 0; + } + + public static void main(String[] args) { + + Tree avlTree = new AVLTree<>(); + avlTree.insert(10).insert(2).insert(6).insert(8).insert(25).insert(18).insert(35).insert(15).insert(22).insert(42) + .insert(30).insert(40).insert(12).insert(17).insert(19).insert(24).insert(28).insert(33).insert(38); + + avlTree.traverse(); + + System.out.println("Max is: " + avlTree.getMax()); + System.out.println("Min is: " + avlTree.getMin()); + + System.out.println("Deleting 42 from Tree"); + avlTree.delete(42); + + System.out.println("New Max is: " + avlTree.getMax()); + + avlTree.traverse(); + + } + + +} \ No newline at end of file diff --git a/src/main/java/trees/BinaryTreeCamera.java b/src/main/java/trees/BinaryTreeCamera.java new file mode 100644 index 0000000..7ea1931 --- /dev/null +++ b/src/main/java/trees/BinaryTreeCamera.java @@ -0,0 +1,55 @@ +package trees; + + +/** + * https://leetcode.com/problems/binary-tree-cameras/ + */ +public class BinaryTreeCamera { + + int count = 0; + int NOT_MONITERED = 0; + int MONITERED = 1; + int CAMERA = 2; + + public int minCameraCover(TreeNode root) { + if (root == null) return 0; + if (dfs(root) == NOT_MONITERED) count++; + return count; + } + + public int dfs(TreeNode root) { + /** + So that leaf doesn't install camera on it + Note: I will never assign camera to a leaf node. + It will be better if I assign camera to that leaf's + parent node,because parent will cover both its + child as well its own parent as well. + **/ + if (root == null) return MONITERED; + + + int left = dfs(root.left); + int right = dfs(root.right); + + if (left == NOT_MONITERED || right == NOT_MONITERED) { + /** + if any of my child wants me to put a camera on me, + I will have to put a camera on my self. AND I will tell + my parent that I have a camera. Not to worry + */ + count++; + return CAMERA; + } + + if (left == CAMERA || right == CAMERA) { + /** + If any of my child has a camera, I will + be covered as well. So, I will tell my parent + that I am covered + */ + return MONITERED; + } + + return NOT_MONITERED; + } +} diff --git a/src/main/java/trees/BinaryTreesUpsideDown.java b/src/main/java/trees/BinaryTreesUpsideDown.java new file mode 100644 index 0000000..8bab007 --- /dev/null +++ b/src/main/java/trees/BinaryTreesUpsideDown.java @@ -0,0 +1,41 @@ +package trees; + +/** + * https://leetcode.com/problems/binary-tree-upside-down/ + */ +public class BinaryTreesUpsideDown { + public TreeNode upsideDownBinaryTree(TreeNode root) { + TreeNode curr = root; + TreeNode next = null; + TreeNode temp = null; + TreeNode prev = null; + + while (curr != null) { + next = curr.left; + + // swapping nodes now, need temp to keep the previous right child + curr.left = temp; + temp = curr.right; + curr.right = prev; + + prev = curr; + curr = next; + } + return prev; + } + + public TreeNode upsideDownBinaryTreeRecur(TreeNode root) { + if (root == null || root.left == null && root.right == null) + return root; + + TreeNode newRoot = upsideDownBinaryTreeRecur(root.left); + + root.left.left = root.right; + root.left.right = root; + + root.left = null; + root.right = null; + + return newRoot; + } +} diff --git a/src/main/java/trees/ClosestValue.java b/src/main/java/trees/ClosestValue.java new file mode 100644 index 0000000..1acf539 --- /dev/null +++ b/src/main/java/trees/ClosestValue.java @@ -0,0 +1,51 @@ +package trees; + +import java.util.ArrayList; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; + +/** + * https://leetcode.com/problems/closest-binary-search-tree-value + * https://leetcode.com/problems/closest-binary-search-tree-value-ii + */ +public class ClosestValue { + public int closestValue(TreeNode root, double target) { + if (root == null) return 0; + + int val = root.val; + double bestDiff = Math.abs(target - val); + TreeNode node = root; + while (node != null) { + double diff = Math.abs(target - node.val); + if (diff <= bestDiff) { + bestDiff = diff; + val = node.val; + } + node = target <= node.val ? node.left : node.right; + } + + return val; + } + + public List closestKValues(TreeNode root, double target, int k) { + Deque dq = new LinkedList<>(); + + inorder(root, dq); + while (dq.size() > k) { + if (Math.abs(dq.peekFirst() - target) > Math.abs(dq.peekLast() - target)) + dq.pollFirst(); + else + dq.pollLast(); + } + + return new ArrayList<>(dq); + } + + public void inorder(TreeNode root, Deque dq) { + if (root == null) return; + inorder(root.left, dq); + dq.add(root.val); + inorder(root.right, dq); + } +} diff --git a/src/main/java/trees/CountGoodNodes.java b/src/main/java/trees/CountGoodNodes.java new file mode 100644 index 0000000..6634570 --- /dev/null +++ b/src/main/java/trees/CountGoodNodes.java @@ -0,0 +1,108 @@ +package trees; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * https://leetcode.com/problems/count-good-nodes-in-binary-tree/ + * + * Given a binary tree root, a node X in the tree is named good if in the path from root to X there are no nodes with a value greater than X. + * + * Return the number of good nodes in the binary tree. + */ +public class CountGoodNodes { + + int result = 0; + + /** + * Thought Process: + * + * Question say that, path from root to X there are no nodes with a value greater than X + * In other words, how many elements in the path maintain ascending order ? + * What can be the best way to check if the ascending order is maintained or not ? + * While traversing from root to any node, we can keep a variable having the maximum value till now + * + * Initially let the max value be int_min + * At every node check if ( node value ) >= ( max till now from root ) + * if greater, increase the count( bcz. we got one good node ) and update the max value which we need to pass for left and right subtree + * Now get the count for left and right subtree recursively passing the updated max value as argument + * so final ans will be count( left subtree ) + count( right subtree ) + ( 1 or 0 as per step 2 ) + * + * @param root + * @return + */ + public int goodNodes(TreeNode root) { + if (root == null) return 0; + + return recursionHelper(root, Integer.MIN_VALUE); + } + + + public int recursionHelper(TreeNode root, int max) { + if (root == null) return 0; + + if (root.val >= max) { + max = root.val; + result++; + } + + recursionHelper(root.left, max); + recursionHelper(root.right, max); + return result; + } + + public int goodNodesBruteForce(TreeNode root) { + if (root == null) return 0; + + recursionHelper(root, new ArrayList<>()); + return result; + } + + + public void recursionHelper(TreeNode root, List tempList) { + if (root == null) return; + + tempList.add(root.val); + List temp = new ArrayList<>(tempList); + Collections.sort(temp); + if (root.val >= temp.get(temp.size() - 1)) { + result++; + } + + recursionHelper(root.left, tempList); + recursionHelper(root.right, tempList); + tempList.remove(tempList.size() - 1); + } + + static class Pair{ + TreeNode root; + int val; + Pair(TreeNode root, int val) { + this.root = root; + this.val = val; + } + } + public int goodNodesBFS(TreeNode root) { + if(root == null) return 0; + int count = 0 ; + Queue q = new LinkedList<>(); + q.offer(new Pair(root, root.val)); + while(!q.isEmpty()) { + Pair p = q.poll(); + TreeNode t = p.root; + if(t.val >= p.val) { + count++; + } + if(t.left != null) { + q.offer(new Pair(t.left, Math.max(t.left.val, p.val))); + } + if(t.right != null) { + q.offer(new Pair(t.right, Math.max(t.right.val, p.val))); + } + } + return count; + } +} diff --git a/src/main/java/trees/DeleteBST.java b/src/main/java/trees/DeleteBST.java new file mode 100644 index 0000000..7502408 --- /dev/null +++ b/src/main/java/trees/DeleteBST.java @@ -0,0 +1,35 @@ +package trees; + +/** + * tricky + */ +public class DeleteBST { + public TreeNode deleteNode(TreeNode root, int key) { + if (root == null) return null; + + if (key < root.val) { + root.left = deleteNode(root.left, key); + return root; + } else if (key > root.val) { + root.right = deleteNode(root.right, key); + return root; + } else { + if (root.left == null && root.right == null) return null; + + else if (root.left == null) return root.right; + else if (root.right == null) return root.left; + else { + root.val = getRightMin(root.right); + root.right = deleteNode(root.right, root.val); + return root; + } + } + } + + public int getRightMin(TreeNode root) { + while (root.left != null) { + root = root.left; + } + return root.val; + } +} diff --git a/src/main/java/trees/DepthOfTree.java b/src/main/java/trees/DepthOfTree.java new file mode 100644 index 0000000..8d4a8a5 --- /dev/null +++ b/src/main/java/trees/DepthOfTree.java @@ -0,0 +1,46 @@ +package trees; + +import java.util.ArrayDeque; +import java.util.Deque; + +public class DepthOfTree { + + public int maxDepth(TreeNode root) { + if (root == null) return 0; + + return 1 + Math.max(maxDepth(root.left), maxDepth(root.right)); + } + + public int minDepth(TreeNode root) { + + Deque deque = new ArrayDeque<>(); + int result = 0; + deque.offer(root); + + while (!deque.isEmpty()) { + int size = deque.size(); + for (int i = 0; i < size; i++) { + TreeNode temp = deque.poll(); + + if (temp.left == null && temp.right == null) + return result; + if (temp.left != null) { + deque.offer(temp.left); + } + if (temp.right != null) { + deque.offer(temp.right); + } + } + result++; + } + return result; + } + + public int minDepthDFS(TreeNode root) { + if (root == null) return 0; + int left = minDepthDFS(root.left); + int right = minDepthDFS(root.right); + return (left == 0 || right == 0) ? left + right + 1 : Math.min(left, right) + 1; + + } +} diff --git a/src/main/java/trees/DiameterTree.java b/src/main/java/trees/DiameterTree.java new file mode 100644 index 0000000..a67e187 --- /dev/null +++ b/src/main/java/trees/DiameterTree.java @@ -0,0 +1,21 @@ +package trees; + +public class DiameterTree { + + public int height(TreeNode root, int[] ans) { + if (root != null) { + int left = height(root.left, ans); + int right = height(root.right, ans); + ans[0] = Math.max(ans[0], 1 + left + right); + return 1 + Math.max(left, right); + } + return 0; + } + + int diameterOfBinaryTree(TreeNode root) { + int[] ans = new int[1]; + height(root, ans); + return ans[0] - 1; + } + +} diff --git a/src/main/java/trees/FindLeaves.java b/src/main/java/trees/FindLeaves.java new file mode 100644 index 0000000..dcb828e --- /dev/null +++ b/src/main/java/trees/FindLeaves.java @@ -0,0 +1,49 @@ +package trees; + +/** + * https://leetcode.com/problems/find-leaves-of-binary-tree/ + * Given the root of a binary tree, collect a tree's nodes as if you were doing this: + * Collect all the leaf nodes. + * Remove all the leaf nodes. + * Repeat until the tree is empty. + */ + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class FindLeaves { + + private int calculateHeight(TreeNode root, List> result) { + if (root == null) return -1; + int height = 1 + Math.max(calculateHeight(root.left, result), calculateHeight(root.right, result)); + if (result.size() <= height) result.add(new HashSet<>()); + result.get(height).add(root); + return height; + } + + + public List> fallingLeaves(TreeNode root) { + List> result = new ArrayList<>(); + calculateHeight(root, result); + return result; + } + + + public int calculateHeightNArray(TreeNode root, List> result) { + if (root == null) return -1; + int max = -1; + + for (TreeNode child : root.children) { + max = Math.max(max, calculateHeight(child, result)); + } + int height = 1 + max; + + if (result.size() <= height) result.add(new HashSet<>()); + result.get(height).add(root); + return height; + } + + +} diff --git a/src/main/java/trees/GenerateAllPossibleBST.java b/src/main/java/trees/GenerateAllPossibleBST.java new file mode 100644 index 0000000..b537c01 --- /dev/null +++ b/src/main/java/trees/GenerateAllPossibleBST.java @@ -0,0 +1,90 @@ +package trees; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * tricky + * + * https://leetcode.com/problems/unique-binary-search-trees-ii/ + * + * 1 1 2 3 3 + * \ \ / \ / / + * 2 3 1 3 2 1 + * \ / / \ + * 3 2 1 2 + * Create root nodes by cycling through [start,end] or [1,n] + * Recursively generate all possible left subtrees. By rules of a BST, all values in a left subtree are less than the root. + * Thus, use the list [start, curRootVal - 1] to create the left subtrees + * Recursively generate all possible right subtrees. By rules of a BST, + * all values in a right subtree are greater than the root. + * Thus, use the list [curRooVal + 1, end] to create the right subtrees. + * For each combination of left and right subtrees, attach them to the current root to form a unique BST (or subtree) + * + * First we want each number for 1..n to be the root, for all different combinations tree roots so we can do + * + * for i in range(1, n+1): + * curRoot = TreeNode(curRootVal) + * we can try to do the same and cycle through [1,n] for each of the children of curRoot + * But we have to obey the rules of a binary search tree which are: + * nodes in a left subtree must be less than the root + * nodes in a right subtree must be greater than the root + * + * So we make each possible left child by cycling through all values less than the current root or [1,curRootVal -1]. + * We make each possible right child by cycling through all values greater than the current root or [curRootVal + 1, n] + * + * Following above method we've created all possible roots using [1,n] in the for loop. + * We somehow made the left subtree using the list [1,curRootVal-1] (numbers less than curRootVal). + * We somehow made the right subtree using the list [curRootVal +1, n] (numbers greater than curRootVal). + * Then we make left_subtree the left child of curRoot and right_subtree the right child of curRoot. + * + * From this code, should the recursive function return a single subtree? + * Take a look at the trees for roots 1 and 3 above, + * they have multiple possible subtrees! Thus, we should return all possible left and right subtrees. + * That is, the recursive function returns a list! I'll call this list all_trees. + */ +public class GenerateAllPossibleBST { + List[][] cache; + + public List generateTrees(int n) { + if (n == 0) return Collections.emptyList(); + cache = new ArrayList[n + 1][n + 1]; + return recursiveTreeBuilder(1, n); + } + + public List recursiveTreeBuilder(int start, int end) { + + List result = new ArrayList<>(); + + // edge case , when i= start the call becomes recursiveTreeBuilder(i, i - 1) + // when i=end the call becomes recursiveTreeBuilder(i+1, i) + // both the cases produce start>end + // so we return null list, the reason is if we return simply and empty list + // for (TreeNode left : leftTree), for (TreeNode right : rightTree) + // one of the for loops for the edge case will get skipped because of empty list + // so we place null at that position + if (start > end) { + result.add(null); + return result; + } + if (cache[start][end] != null) return cache[start][end]; + + for (int i = start; i <= end; i++) { + + List leftTree = recursiveTreeBuilder(start, i - 1); + List rightTree = recursiveTreeBuilder(i + 1, end); + + // the double for loop is to generate all possible combinations of left and right + for (TreeNode left : leftTree) { + for (TreeNode right : rightTree) { + TreeNode root = new TreeNode(i); + root.left = left; + root.right = right; + result.add(root); + } + } + } + return cache[start][end] = result; + } +} diff --git a/src/main/java/trees/HouseRobberTree.java b/src/main/java/trees/HouseRobberTree.java new file mode 100644 index 0000000..f06c1e2 --- /dev/null +++ b/src/main/java/trees/HouseRobberTree.java @@ -0,0 +1,64 @@ +package trees; + +/** + * https://leetcode.com/problems/house-robber-iii/ + */ +public class HouseRobberTree { + + /** + * Approach1: Recursive (TLE) + * T.C : O(2^n) + * S.C : O(1) (ignoring stack memory used for recursion) + */ + public int robNaive(TreeNode root) { + if (root == null) return 0; + + int ans = 0; + + // max value from left grandchildren + if (root.left != null) { + ans += robNaive(root.left.left) + robNaive(root.left.right); + } + + // max value from right grandchildren + if (root.right != null) { + ans += robNaive(root.right.left) + robNaive(root.right.right); + } + + return Math.max(ans + root.val, robNaive(root.left) + robNaive(root.right)); //(Case1,Case2) + } + + public int rob(TreeNode root) { + int[] res = robSub(root); + return Math.max(res[0], res[1]); + } + + /** + * Redefine rob(root) as a new function which will return an array of two elements, + * the first element of which denotes the maximum amount of money that can be robbed if root is not robbed, + * while the second element signifies the maximum amount of money robbed if it is robbed. + */ + private int[] robSub(TreeNode root) { + if (root == null) return new int[2]; + + int[] left = robSub(root.left); + int[] right = robSub(root.right); + int[] res = new int[2]; + + /** + * Let's relate rob(root) to rob(root.left) and rob(root.right)..., etc. + * For the 1st element of rob(root), we only need to sum up the larger elements of rob(root.left) and rob(root.right), respectively, + * since root is not robbed and we are free to rob its left and right subtrees + */ + res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]); + + + /** + * For the 2nd element of rob(root), however, we only need to add up the 1st elements of rob(root.left) and rob(root.right), respectively, + * plus the value robbed from root itself, since in this case it's guaranteed that we cannot rob the nodes of root.left and root.right. + */ + res[1] = root.val + left[0] + right[0]; + + return res; + } +} diff --git a/src/main/java/trees/InsertBST.java b/src/main/java/trees/InsertBST.java new file mode 100644 index 0000000..7160a43 --- /dev/null +++ b/src/main/java/trees/InsertBST.java @@ -0,0 +1,35 @@ +package trees; + +public class InsertBST { + + public TreeNode insertIntoBST(TreeNode root, int val){ + if(root==null) return new TreeNode(val); + + if(val stack = new ArrayDeque<>(); + TreeNode pre = null; + while (root != null || !stack.isEmpty()) { + while (root != null) { + stack.push(root); + root = root.left; + } + root = stack.pop(); + if (pre != null && root.val <= pre.val) return false; + pre = root; + root = root.right; + } + return true; + } +} diff --git a/src/main/java/trees/LargestBST.java b/src/main/java/trees/LargestBST.java new file mode 100644 index 0000000..a2a7b2f --- /dev/null +++ b/src/main/java/trees/LargestBST.java @@ -0,0 +1,68 @@ +package trees; + +/** + * tricky BST + */ +public class LargestBST { + + + public int largestBSTSubtree(TreeNode root) { + if (root == null) return 0; + + NodeValue result = largestBSTSubtreeHelper(root); + + return result.maxSize; + + } + + /** + * Idea for a valid BST is if a node root has + * + * root + * / \ + * / \ + * Max left Min right + * + * if root > 'Max left' then it is greater than all the nodes in the left subtree + * if root < 'Min right' then it is smaller than the all the nodes in the right subtree + * + * in case of non bst then pass +INF as left max and -INF as right min which will break the result and then keep the size of the previous result + * + * if root == null pass leftmax as -INF and rightMin as +INF + * + * @param root + * @return + */ + public NodeValue largestBSTSubtreeHelper(TreeNode root) { + if (root == null) return new NodeValue(Integer.MAX_VALUE, Integer.MIN_VALUE, 0); + + + NodeValue left = largestBSTSubtreeHelper(root.left); + NodeValue right = largestBSTSubtreeHelper(root.right); + + int size = Math.max(left.maxSize, right.maxSize); + + if (left.maxNode < root.val && root.val < right.minNode) { + + return new NodeValue(Math.min(root.val, left.minNode), Math.max(root.val, right.maxNode), left.maxSize + right.maxSize + 1); + } + + //non bst is found, then pass +INF as left max and -INF as right min which will break the result and then keep the size of the previous result + return new NodeValue(Integer.MIN_VALUE, Integer.MAX_VALUE, size); + + + } + + + static class NodeValue { + int maxSize; + int maxNode; + int minNode; + + public NodeValue(int minNode, int maxNode, int maxSize) { + this.minNode = minNode; + this.maxNode = maxNode; + this.maxSize = maxSize; + } + } +} diff --git a/src/main/java/trees/LowestCommonAncestor.java b/src/main/java/trees/LowestCommonAncestor.java new file mode 100644 index 0000000..2923f75 --- /dev/null +++ b/src/main/java/trees/LowestCommonAncestor.java @@ -0,0 +1,153 @@ +package trees; + +import java.util.HashSet; +import java.util.Set; + +public class LowestCommonAncestor { + + /** + * It is guaranteed that both p and q are in the tree. + * A node can be a descendant of itself. + * + * @param root + * @param p + * @param q + * @return + */ + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + + if (root == null || root == p || root == q) return root; + + TreeNode left = lowestCommonAncestor(root.left, p, q); + TreeNode right = lowestCommonAncestor(root.right, p, q); + + if (left != null && right != null) return root; + + if (left == null) return right; + + return left; + } + + public TreeNode lowestCommonAncestorII(TreeNode root, TreeNode p, TreeNode q) { + + boolean[] exists = new boolean[2]; + TreeNode lca = LCAHelper(root, p, q, exists); + return (exists[0] && exists[1] ? lca : null); + } + + TreeNode LCAHelper(TreeNode root, TreeNode p, TreeNode q, boolean[] exists) { + if (root == null) + return root; + + TreeNode left = LCAHelper(root.left, p, q, exists); + TreeNode right = LCAHelper(root.right, p, q, exists); + + if (root.val == p.val) { + exists[0] = true; + return root; + } + if (root.val == q.val) { + exists[1] = true; + return root; + } + + if (left == null) + return right; + else if (right == null) + return left; + else //both are not null and hence we have found our LCA + return root; + } + + public Node lowestCommonAncestorIIIExtraSpace(Node p, Node q) { + Set seen = new HashSet<>(); + while (p != null) { + seen.add(p); + p = p.parent; + } + + while (q != null) { + if (seen.contains(q)) { + return q; + } + q = q.parent; + } + + return null; + } + + /** + * tricky LCA + */ + public Node lowestCommonAncestorIII(Node p, Node q) { + Node pRunner = p; + Node qRunner = q; + + while (pRunner != qRunner) { + // Guaranteed to complete since both nodes belong to same tree + // We are simulating a cycle when any of the conditions below is satisfied + // by pointing runner to the head of the other "list" to make sure + // intersection is found before either of the below conditions are satisfied again + pRunner = pRunner.parent == null ? q : pRunner.parent; + qRunner = qRunner.parent == null ? p : qRunner.parent; + } + + return pRunner; + } + + public Node lowestCommonAncestor(Node p, Node q) { + if (p == null || q == null) + throw new IllegalArgumentException("Invalid input as p and q are guaranteed to exist"); + + int pDepth = getDepth(p), qDepth = getDepth(q); + + while (pDepth > qDepth) { + pDepth--; + p = p.parent; + } + + while (qDepth > pDepth) { + qDepth--; + q = q.parent; + } + + while (p != q) { + p = p.parent; + q = q.parent; + } + + return p; + } + + private int getDepth(Node a) { + int depth = 0; + while (a != null) { + a = a.parent; + depth++; + } + return depth; + } + + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode[] nodes) { + Set s = new HashSet<>(); + for (TreeNode n : nodes) s.add(n.val); + return lcaHelper(root, s); + } + + private TreeNode lcaHelper(TreeNode root, Set s) { + if (root == null) return null; + if (s.contains(root.val)) return root; + TreeNode left = lcaHelper(root.left, s); + TreeNode right = lcaHelper(root.right, s); + if (left != null && right != null) return root; + else return (left != null) ? left : right; + } + + static class Node { + Node left; + Node right; + Node parent; + int data; + } + +} diff --git a/src/main/java/trees/MaxPathSum.java b/src/main/java/trees/MaxPathSum.java new file mode 100644 index 0000000..d3be61f --- /dev/null +++ b/src/main/java/trees/MaxPathSum.java @@ -0,0 +1,33 @@ +package trees; + +/** + * https://leetcode.com/problems/binary-tree-maximum-path-sum/discuss/603423/Python-Recursion-stack-thinking-process-diagram + * + * tricky Path sum + */ + +public class MaxPathSum { + + public int maxPathSum(TreeNode root) { + + if (root == null) return 0; + int[] result = new int[1]; + result[0] = Integer.MIN_VALUE; + maxPathSumUtil(root, result); + return result[0]; + } + + public int maxPathSumUtil(TreeNode root, int[] result) { + + if (root == null) return 0; + + int leftRootSum = Math.max(0, maxPathSumUtil(root.left, result)); + int rightRootSum = Math.max(0, maxPathSumUtil(root.right, result)); + + int rootPathSum = rightRootSum + leftRootSum + root.val; + + result[0] = Math.max(rootPathSum, result[0]); + + return root.val + Math.max(leftRootSum, rightRootSum); + } +} diff --git a/src/main/java/trees/MaxProductSplitBinaryTree.java b/src/main/java/trees/MaxProductSplitBinaryTree.java new file mode 100644 index 0000000..91d1286 --- /dev/null +++ b/src/main/java/trees/MaxProductSplitBinaryTree.java @@ -0,0 +1,66 @@ +package trees; + +/** + * https://leetcode.com/problems/maximum-product-of-splitted-binary-tree/submissions/ + * + * I will use an example to explain the logic behind the solution of this exercise. + * Below you see a Binary Tree. + * In red, next to each node, you see the sum of all nodes' values rooted at the subtree. + * This information can be computed by running DFS on the tree (see the code in the end). + * For example, the sum of all nodes rooted at the node with value 2 is: 11= 2 + 5+ 4. + * We can note that the sum of all nodes rooted at the root of the tree is the total sum of all nodes. + * This information is important, and we will use it later. + * 1 (21) + * / \ + * (11) 2 3 (9) + * / \ \ + * 4 5 6 + * + * Suppose we cut the edge connecting the node with value 1 and the node with value 2. + * 1 (10) 21 becomes 10 because of cut + * X \ + * (11) 2 3 (9) + * / \ \ + * 4 5 6 + * + * What is the product of the sum of the subtrees? Well, + * we have already pre-calculated the sum of all nodes in the left subtree (rooted at 2) + * and we can note that the sum of all nodes in the right subtree is the total sum minus the sum of the left subtree. + * We have pre-calculated all the information we need! + * However, we do not know which edge deletion results in the maximum product, so we need to try all the edges. + */ +public class MaxProductSplitBinaryTree { + long max = Long.MIN_VALUE; + long totalSum = 0; + + public int maxProduct(TreeNode root) { + sum(root); + max(root, totalSum); + return (int) (max % (1e9 + 7)); + } + + public void max(TreeNode node, long totalSum) { + if (node == null) return; + if (node.left != null) { + int sum1= (int) (totalSum - node.left.val); + int sum2=node.left.val; + max = Math.max(max, (long) sum1 * sum2); + } + if (node.right != null) { + int sum1= (int) (totalSum - node.right.val); + int sum2=node.right.val; + max = Math.max(max, (long) sum1 * sum2); + } + max(node.left, totalSum); + max(node.right, totalSum); + } + + // use the root value to represent the sum of its subtree + public void sum(TreeNode root) { + if (root == null) return; + totalSum += root.val; + sum(root.left); + sum(root.right); + root.val += (root.left == null ? 0 : root.left.val) + (root.right == null ? 0 : root.right.val); + } +} diff --git a/src/main/java/trees/MaxWidthOfBinaryTree.java b/src/main/java/trees/MaxWidthOfBinaryTree.java new file mode 100644 index 0000000..b55368a --- /dev/null +++ b/src/main/java/trees/MaxWidthOfBinaryTree.java @@ -0,0 +1,65 @@ +package trees; + +import trees.TreeNode; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Queue; + +/** + * tricky level order traversal + * + * Given a binary tree, write a function to get the maximum width of the given tree. + * The width of a tree is the maximum width among all levels. + * The binary tree has the same structure as a full binary tree, but some nodes are null + * + * Input: + + 1 + / \ + 3 2 + / \ + 5 9 + / \ + 6 7 +Output: 8 +The maximum width existing in the fourth level with the length 8 (6,null,null,null,null,null,null,7). + */ +public class MaxWidthOfBinaryTree { + + // Each time a node is traversed, the position of the node(as it is in a full binary tree) is stored in the HashMap. + //If the position of the parent node is 'n', then the left child is '2 * n' and the right child is '2 * n + 1'. + //The width of each level is the last node's position in this level subtracts the first node's position in this level plus 1. + public int widthOfBinaryTree(TreeNode root) { + if (root == null) return 0; + int maxWidth = 0; + + Map map = new HashMap<>(); + Queue queue = new LinkedList<>(); + queue.offer(root); + map.put(root, 1); // if we are assigning head as 0 then the formula is left=>2*n+1, right=> 2*n+2 + while (!queue.isEmpty()) { + int width = queue.size(); + int start = 0; + int end = 0; + for (int i = 0; i < width; i++) { + TreeNode temp = queue.poll(); + if (i == 0) start = map.get(temp); + if (i == width - 1) end = map.get(temp); + if (temp.left != null) { + map.put(temp.left, map.get(temp) * 2); + queue.offer(temp.left); + } + if (temp.right != null) { + map.put(temp.right, map.get(temp) * 2 + 1); + queue.offer(temp.right); + } + } + + maxWidth = Math.max(maxWidth, end - start + 1); + } + + return maxWidth; + } +} \ No newline at end of file diff --git a/src/main/java/trees/Node.java b/src/main/java/trees/Node.java new file mode 100644 index 0000000..c8d8b16 --- /dev/null +++ b/src/main/java/trees/Node.java @@ -0,0 +1,52 @@ +package trees; + +import lombok.Data; +import lombok.NonNull; + +@Data +public class Node> { + + @NonNull + private T data; + + private int height = 1; + + private Node leftChild; + private Node rightChild; + + public Node(@NonNull T data) { + this.data = data; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public Node getLeftChild() { + return leftChild; + } + + public void setLeftChild(Node leftChild) { + this.leftChild = leftChild; + } + + public Node getRightChild() { + return rightChild; + } + + public void setRightChild(Node rightChild) { + this.rightChild = rightChild; + } +} \ No newline at end of file diff --git a/src/main/java/trees/NodesAtDistanceK.java b/src/main/java/trees/NodesAtDistanceK.java new file mode 100644 index 0000000..ad8ac38 --- /dev/null +++ b/src/main/java/trees/NodesAtDistanceK.java @@ -0,0 +1,65 @@ +package trees; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.Set; + +/** + * https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/ + */ +public class NodesAtDistanceK { + + public List distanceK(TreeNode root, TreeNode target, int K) { + List res = new ArrayList<>(); + Map parentsMap = new HashMap<>(); + buildParentMap(root, root, parentsMap);//first root is node and second root is its parent considered + Set visited = new HashSet<>(); //keep track of visited nodes + Queue q = new LinkedList<>();//for BFS + q.add(target); //instead of root here we are adding target as we need to find from that node + visited.add(target); //also target node need to be visited first + int level = 0; //as we are using level order traversal k == level then we find all the nodes in queue + while (!q.isEmpty()) { + int size = q.size(); + if (level == K) return buildResult(q);//elements remaining in queue will be nodes at dist + for (int i = 0; i < size; i++) { //k from target + TreeNode t = q.remove(); + if (t.left != null && !visited.contains(t.left)) { + q.add(t.left); + visited.add(t.left); + } + if (t.right != null && !visited.contains(t.right)) { + q.add(t.right); + visited.add(t.right); + } + TreeNode parent = parentsMap.get(t); + if (!visited.contains(parent)) { //if parent is not visited + q.add(parent);//add parent to q + visited.add(parent); //mark it as visited + } + } + level++; //we check level wise and each level covers 1 unit distance + } + return res; + } + + private List buildResult(Queue q) { + List lst = new ArrayList<>(); + while (!q.isEmpty()) { + lst.add(q.remove().val); + } + return lst; + } + + private void buildParentMap(TreeNode root, TreeNode parent, Map parentsMap) { + if (root == null) + return; + parentsMap.put(root, parent); + buildParentMap(root.left, root, parentsMap); //build for left subtree root.left will be child of root + buildParentMap(root.right, root, parentsMap);//build for right subtree + } +} diff --git a/src/main/java/trees/PathSum.java b/src/main/java/trees/PathSum.java new file mode 100644 index 0000000..65f3ef7 --- /dev/null +++ b/src/main/java/trees/PathSum.java @@ -0,0 +1,55 @@ +package trees; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class PathSum { + + + /** + * Given the root of a binary tree and an integer targetSum, + * return true if the tree has a root-to-leaf + * path such that adding up all the values along the path equals targetSum. + *

+ * A leaf is a node with no children. + */ + public boolean hasPathSum(TreeNode root, int targetSum) { + if (root == null) return false; + if (root.left == null && root.right == null && targetSum - root.val == 0) return true; + boolean left = hasPathSum(root.left, targetSum - root.val); + boolean right = hasPathSum(root.right, targetSum - root.val); + + return left || right; + } + + /** + * Given the root of a binary tree and an integer targetSum, + * return all root-to-leaf paths where each path's sum equals targetSum. + *

+ * A leaf is a node with no children. + *

+ * Input: root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22 + * Output: [[5,4,11,2],[5,8,4,5]] + */ + + public List> pathSum(TreeNode root, int targetSum) { + if (root == null) return Collections.emptyList(); + List> result = new ArrayList<>(); + pathSumUtil(root, result, targetSum, new ArrayList<>()); + return result; + } + + public void pathSumUtil(TreeNode root, List> result, int targetSum, List tempList) { + if (root == null) return; + tempList.add(root.val); + if (root.left == null && root.right == null && targetSum - root.val == 0) { + result.add(new ArrayList<>(tempList)); + } + + pathSumUtil(root.left, result, targetSum - root.val, tempList); + pathSumUtil(root.right, result, targetSum - root.val, tempList); + tempList.remove(tempList.size() - 1); + } + +} diff --git a/src/main/java/trees/PathSumIII.java b/src/main/java/trees/PathSumIII.java new file mode 100644 index 0000000..3691d7a --- /dev/null +++ b/src/main/java/trees/PathSumIII.java @@ -0,0 +1,91 @@ +package trees; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * tricky + * You are given a binary tree in which each node contains an integer value. + *

+ * Find the number of paths that sum to a given value. + *

+ * The path does not need to start or end at the root or a leaf, + * but it must go downwards (traveling only from parent nodes to child nodes). + *

+ * The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000. + */ +public class PathSumIII { + Map h = new HashMap<>(); + int count = 0; + + public void preorder(TreeNode node, int currSum, int targetSum) { + if (node == null) + return; + + // current prefix sum + currSum += node.val; + + /** + * situation 1, the tree path with the target sum starts from the root. + * That means the current prefix sum is equal to the target sum curr_sum == k, + * so one should increase the counter by 1: count += 1 + */ + if (currSum == targetSum) + count++; + + /** + * In situation 2, the tree path with the target sum starts somewhere downwards. + * That means we should add to the counter the number of times we have seen the prefix sum curr_sum - target + * so far: count += h[curr_sum - target]. + * + * The logic is simple: the current prefix sum is curr_sum, and some elements before the prefix sum was curr_sum - target. + * All the elements in between sum up to curr_sum - (curr_sum - target) = target. + */ + + count += h.getOrDefault(currSum - targetSum, 0); + + // add the current sum into hashmap + // to use it during the child nodes processing + h.put(currSum, h.getOrDefault(currSum, 0) + 1); + + // process left subtree + preorder(node.left, currSum, targetSum); + // process right subtree + preorder(node.right, currSum, targetSum); + + /** + * Now the current subtree is processed. + * It's time to remove the current prefix sum from the hashmap, + * in order not to blend the parallel subtrees: h[curr_sum] -= 1. + */ + h.put(currSum, h.get(currSum) - 1); + } + + public int pathSumAlter(TreeNode root, int sum) { + preorder(root, 0, sum); + return count; + } + + List list = new ArrayList<>(); + + public int pathSumIII(TreeNode root, int sum) { + if (root == null) return 0; + list.add(root.val); + pathSumIII(root.left, sum); + pathSumIII(root.right, sum); + + int tempSum = 0; + for (int i = list.size() - 1; i >= 0; i--) { // coming in reverse order, inorder to avoid considering head node + tempSum += list.get(i); + if (sum == tempSum) { + count++; + } + } + + list.remove(list.size() - 1); + return count; + } + +} \ No newline at end of file diff --git a/src/main/java/trees/PruneBinaryTree.java b/src/main/java/trees/PruneBinaryTree.java new file mode 100644 index 0000000..78f97fc --- /dev/null +++ b/src/main/java/trees/PruneBinaryTree.java @@ -0,0 +1,28 @@ +package trees; + +/** + * https://leetcode.com/problems/binary-tree-pruning/ + *

+ * Given the root of a binary tree, return the same tree where every subtree (of the given tree) not containing a 1 has been removed. + *

+ * A subtree of a node is node plus every node that is a descendant of node. + */ +public class PruneBinaryTree { + + + public TreeNode pruneTreeEffective(TreeNode root) { + if (root == null) return null; + + root.left = pruneTreeEffective(root.left); + root.right = pruneTreeEffective(root.right); + + if (root.val == 0 && root.left == null && root.right == null) { + root = null; + } + + return root; + } +} + + + diff --git a/src/trees/RootToLeafPaths.java b/src/main/java/trees/RootToLeafPaths.java similarity index 93% rename from src/trees/RootToLeafPaths.java rename to src/main/java/trees/RootToLeafPaths.java index 4877342..98f287f 100644 --- a/src/trees/RootToLeafPaths.java +++ b/src/main/java/trees/RootToLeafPaths.java @@ -6,7 +6,7 @@ public class RootToLeafPaths { public void construct_paths(TreeNode root, String path, List paths) { if (root != null) { - path += Integer.toString(root.val); + path += "" + root.val; if ((root.left == null) && (root.right == null)) // if reach a leaf paths.add(path); // update paths else { diff --git a/src/main/java/trees/SameTree.java b/src/main/java/trees/SameTree.java new file mode 100644 index 0000000..cb4a42a --- /dev/null +++ b/src/main/java/trees/SameTree.java @@ -0,0 +1,47 @@ +package trees; + +import trees.TreeNode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Given two binary trees, write a function to check if they are the same or not. + * Two binary trees are considered the same if they are structurally identical and the nodes have the same value. + * Input: 1 1 + * / \ / \ + * 2 1 1 2 + *

+ * [1,2,1], [1,1,2] + *

+ * Output: false + */ +public class SameTree { + + public boolean isSameTree(TreeNode p, TreeNode q) { + Queue queue = new LinkedList<>(); + queue.add(p); + queue.add(q); + while (!queue.isEmpty()) { + TreeNode f = queue.poll(); + TreeNode s = queue.poll(); + if (f == null && s == null) { + continue; + } else if (f == null || s == null || f.val != s.val) { + return false; + } + queue.add(f.left); + queue.add(s.left); + queue.add(f.right); + queue.add(s.right); + } + return true; + } + + public boolean isSameTreeRecur(TreeNode p, TreeNode q) { + if (p == null || q == null) return p == q; + if (p.val == q.val) return true; + + return isSameTreeRecur(p.left, q.left) && isSameTreeRecur(p.right, q.right); + } +} \ No newline at end of file diff --git a/src/main/java/trees/SecondMinValueInSpecialTree.java b/src/main/java/trees/SecondMinValueInSpecialTree.java new file mode 100644 index 0000000..ea58f6d --- /dev/null +++ b/src/main/java/trees/SecondMinValueInSpecialTree.java @@ -0,0 +1,40 @@ +package trees; + +/** + * https://leetcode.com/problems/second-minimum-node-in-a-binary-tree + */ +public class SecondMinValueInSpecialTree { + + public int findSecondMinimumValue(TreeNode root) { + // tree is not empty + // root != null + + // each node in this tree has exactly two or zero sub-node + if (root.left == null) { + return -1; + } + + int left = -1; + if (root.val != root.left.val) { + // find a value bigger than root.val + left = root.left.val; + } else { + left = findSecondMinimumValue(root.left); + } + + int right = -1; + if (root.val != root.right.val) { + right = root.right.val; + } else { + right = findSecondMinimumValue(root.right); + } + + if (left == -1 || right == -1) { + // the bigger value is left or right, or it not exist + return Math.max(left, right); + } else { + // the min of left and right is what we want + return Math.min(left, right); + } + } +} diff --git a/src/practiceproblems/SortedArrayToBST.java b/src/main/java/trees/SortedArrayToBST.java similarity index 97% rename from src/practiceproblems/SortedArrayToBST.java rename to src/main/java/trees/SortedArrayToBST.java index 9071bcf..e22720a 100644 --- a/src/practiceproblems/SortedArrayToBST.java +++ b/src/main/java/trees/SortedArrayToBST.java @@ -1,4 +1,4 @@ -package practiceproblems; +package trees; public class SortedArrayToBST { diff --git a/src/practiceproblems/SwapRecoverBST.java b/src/main/java/trees/SwapRecoverBST.java similarity index 98% rename from src/practiceproblems/SwapRecoverBST.java rename to src/main/java/trees/SwapRecoverBST.java index 053a225..782f4c5 100644 --- a/src/practiceproblems/SwapRecoverBST.java +++ b/src/main/java/trees/SwapRecoverBST.java @@ -1,4 +1,6 @@ -package practiceproblems; +package trees; + +import trees.TreeNode; public class SwapRecoverBST { diff --git a/src/practiceproblems/SymmetricTree.java b/src/main/java/trees/SymmetricTree.java similarity index 95% rename from src/practiceproblems/SymmetricTree.java rename to src/main/java/trees/SymmetricTree.java index fc72385..bc0a0c7 100644 --- a/src/practiceproblems/SymmetricTree.java +++ b/src/main/java/trees/SymmetricTree.java @@ -1,4 +1,5 @@ -package practiceproblems; +package trees; + class SymmetricTree { public boolean isSymmetric(TreeNode root) { diff --git a/src/main/java/trees/Tree.java b/src/main/java/trees/Tree.java new file mode 100644 index 0000000..6191036 --- /dev/null +++ b/src/main/java/trees/Tree.java @@ -0,0 +1,17 @@ +package trees; + +public interface Tree> { + + Tree insert(T data); + + void delete(T data); + + void traverse(); + + T getMax(); + + T getMin(); + + boolean isEmpty(); + +} \ No newline at end of file diff --git a/src/trees/TreeNode.java b/src/main/java/trees/TreeNode.java similarity index 59% rename from src/trees/TreeNode.java rename to src/main/java/trees/TreeNode.java index 23d7fbd..b5e568f 100644 --- a/src/trees/TreeNode.java +++ b/src/main/java/trees/TreeNode.java @@ -1,9 +1,9 @@ package trees; -class TreeNode { - TreeNode left; - TreeNode right; - int val; +public class TreeNode { + public TreeNode left; + public TreeNode right; + public int val; public TreeNode(int val) { this.val = val; diff --git a/src/main/java/trees/TreeToDLL.java b/src/main/java/trees/TreeToDLL.java new file mode 100644 index 0000000..d23f22f --- /dev/null +++ b/src/main/java/trees/TreeToDLL.java @@ -0,0 +1,65 @@ +package trees; + +/** + * tricky traversal + * + */ +public class TreeToDLL { + + public void flatten(TreeNode root) { + if (root == null) + return; + flatten(root.left); + flatten(root.right); + TreeNode left = root.left; + TreeNode right = root.right; + root.left = null; + root.right = left; + while (root.right != null) + root = root.right; + root.right = right; + } + + private TreeNode prev = null; + + public void flattenOptimised(TreeNode root) { + if (root == null) + return; + flattenOptimised(root.right); + flattenOptimised(root.left); + root.right = prev; + root.left = null; + prev = root; + } + + public void flattenIterative(TreeNode root) { + + // Handle the null scenario + if (root == null) { + return; + } + + TreeNode node = root; + + while (node != null) { + + // If the node has a left child + if (node.left != null) { + + // Find the predecessor node + TreeNode rightmost = node.left; + while (rightmost.right != null) { + rightmost = rightmost.right; + } + + // rewire the connections + rightmost.right = node.right; + node.right = node.left; + node.left = null; + } + + // move on to the right side of the tree + node = node.right; + } + } +} diff --git a/src/main/java/trees/TreeTraversals.java b/src/main/java/trees/TreeTraversals.java new file mode 100644 index 0000000..2a29ed3 --- /dev/null +++ b/src/main/java/trees/TreeTraversals.java @@ -0,0 +1,155 @@ +package trees; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.TreeMap; + +public class TreeTraversals { + + public List preOrderTraversal(TreeNode root) { + if (root == null) return Collections.emptyList(); + + Deque stack = new ArrayDeque<>(); + stack.push(root); + List result = new ArrayList<>(); + while (!stack.isEmpty()) { + + TreeNode temp = stack.pop(); + result.add(temp.val); + if (temp.left != null) stack.push(temp.left); + if (temp.right != null) stack.push(temp.right); + } + + return result; + } + + public List inorderTraversal(TreeNode root) { + if (root == null) return Collections.emptyList(); + + Deque stack = new ArrayDeque<>(); + stack.push(root); + List result = new ArrayList<>(); + + while (root != null || !stack.isEmpty()) { + while (root != null) { + stack.push(root); + root = root.left; + } + root = stack.pop(); + result.add(root.val); + root = root.right; + } + + return result; + } + + /** + * Just like with in-order traversal we go to the left subtree as long as we can. At the same time we keep adding the nodes to the stack. + * If we can't (left = null) - we try to go to the right subtree. In order to do that we check the last one we added to the stack. + * If it has a right subtree and we haven't visited it yet then we go there and repeat steps 1 and 2. + * Else we visit the node (also pop out of the stack) 'cause by that time we visited left and right subtrees snd it's time to visit their parent. + * After that we continue the outer loop, peek another node from the stack and repeat 2, 3. + * + * @param root + * @return + */ + public List postorderTraversal(TreeNode root) { + List res = new ArrayList<>(); + Deque stack = new ArrayDeque<>(); + TreeNode cur = root, lastVisited = null; + + while (!stack.isEmpty() || cur != null) { + while (cur != null) { + stack.push(cur); + cur = cur.left; + } + TreeNode peek = stack.pop(); + if (peek.right != null && peek.right != lastVisited) { + cur = peek.right; + } else { + res.add(peek.val); + lastVisited = stack.pop(); + } + + } + + return res; + } + + public int index = 0; + public TreeMap> tm; + + static class Pair { + TreeNode node; + int index; + + public Pair(TreeNode n, int i) { + node = n; + index = i; + } + } + + public List> verticalOrder(TreeNode root) { + List> res = new ArrayList<>(); + tm = new TreeMap<>(); + if (root == null) return res; + + Queue q = new LinkedList<>(); + q.offer(new Pair(root, 0)); + + while (!q.isEmpty()) { + Pair cur = q.poll(); + if (!tm.containsKey(cur.index)) tm.put(cur.index, new ArrayList<>()); + tm.get(cur.index).add(cur.node.val); + + if (cur.node.left != null) q.offer(new Pair(cur.node.left, cur.index - 1)); + if (cur.node.right != null) q.offer(new Pair(cur.node.right, cur.index + 1)); + } + + for (int key : tm.keySet()) res.add(tm.get(key)); + return res; + } + + List nodes = new ArrayList<>(1000); + + public List boundaryOfBinaryTree(TreeNode root) { + + if (root == null) return nodes; + + nodes.add(root.val); + leftBoundary(root.left); + leaves(root); + rightBoundary(root.right); + + return nodes; + } + + public void leftBoundary(TreeNode root) { + if (root == null || (root.left == null && root.right == null)) return; + nodes.add(root.val); + if (root.left == null) leftBoundary(root.right); + else leftBoundary(root.left); + } + + public void rightBoundary(TreeNode root) { + if (root == null || (root.right == null && root.left == null)) return; + if (root.right == null) rightBoundary(root.left); + else rightBoundary(root.right); + nodes.add(root.val); // add after child visit(reverse) + } + + public void leaves(TreeNode root) { + if (root == null) return; + if (root.left == null && root.right == null) { + nodes.add(root.val); + return; + } + leaves(root.left); + leaves(root.right); + } +} diff --git a/src/main/java/trees/TrimBst.java b/src/main/java/trees/TrimBst.java new file mode 100644 index 0000000..18dd9df --- /dev/null +++ b/src/main/java/trees/TrimBst.java @@ -0,0 +1,37 @@ +package trees; + +public class TrimBst { + + public TreeNode trimBST(TreeNode root, int L, int R) { + if (root == null) + return null; + + // If the value of this node is less than L, then the whole left subtree will be smaller, + // so we can discard the left subtree and return the root of the trimmed right sub tree + if (root.val < L) + return trimBST(root.right, L, R); + + // If the value of this node is greater than R, then the whole right subtree will be greater + // so we can discard the right subtree and return the root of the trimmed left sub tree + if (root.val > R) + return trimBST(root.left, L, R); + + // If the value of this node does not need to be deleted, + // we need to pass this recursive call downwards to both sides + root.left = trimBST(root.left, L, R); + root.right = trimBST(root.right, L, R); + + // All the processing of the subtrees done, now return this node + return root; + } + + public TreeNode trimBSTPostOrder(TreeNode root, int L, int R) { + if (root == null) return root; + + root.left = trimBSTPostOrder(root.left, L, R); + root.right = trimBSTPostOrder(root.right, L, R); + if (root.val > R) return root.left; + if (root.val < L) return root.right; + return root; + } +} diff --git a/src/main/java/trees/TwoSumTree.java b/src/main/java/trees/TwoSumTree.java new file mode 100644 index 0000000..eed6a58 --- /dev/null +++ b/src/main/java/trees/TwoSumTree.java @@ -0,0 +1,88 @@ +package trees; + +import java.util.ArrayList; +import java.util.List; + +public class TwoSumTree { + + public boolean findTargetExtraSpace(TreeNode root, int k) { + if (root == null) return false; + List in = new ArrayList<>(); + + inorder(root, in); + + int i = 0; + int j = in.size() - 1; + + while (i < j) { + if (in.get(i) + in.get(j) == k) + return true; + if (in.get(i) + in.get(j) > k) + j--; + else i++; + } + + return false; + + } + + private void inorder(TreeNode root, List in) { + if (root == null) return; + inorder(root.left, in); + in.add(root.val); + inorder(root.right, in); + } + + public boolean findTarget(TreeNode root, int k) { + if (root == null) { + return false; + } + TreeNode start = root; + TreeNode end = root; + while (start.left != null) { + start = start.left; + } + while (end.right != null) { + end = end.right; + } + while (start != end) { + int sum = start.val + end.val; + if (sum > k) { + end = findPredecessor(root, end); + } else if (sum < k) { + start = findSuccessor(root, start); + } else { + return true; + } + } + return false; + } + + private TreeNode findPredecessor(TreeNode root, TreeNode node) { + TreeNode pre = null; + TreeNode cur = root; + while (cur != null) { + if (cur.val < node.val) { + pre = cur; + cur = cur.right; + } else { + cur = cur.left; + } + } + return pre; + } + + private TreeNode findSuccessor(TreeNode root, TreeNode node) { + TreeNode succ = null; + TreeNode cur = root; + while (cur != null) { + if (cur.val > node.val) { + succ = cur; + cur = cur.left; + } else { + cur = cur.right; + } + } + return succ; + } +} diff --git a/src/main/java/trees/UniqueTreePath.java b/src/main/java/trees/UniqueTreePath.java new file mode 100644 index 0000000..9e6b31f --- /dev/null +++ b/src/main/java/trees/UniqueTreePath.java @@ -0,0 +1,35 @@ +package trees; + +import java.util.HashSet; + +/** + * Given Binary tree, return the number of nodes on the longest distinct path that starts at the root. + * Grab Codility + * Question states that if the current node val is seen anywhere in the tree, stop proceeding further + */ +public class UniqueTreePath { + + int result = 0; + + public int solution(TreeNode T) { + // write your code in Java SE 8 + HashSet set = new HashSet<>(); + helper(T, set); + return result; + + } + + private void helper(TreeNode root, HashSet set) { + if (root == null) + return; + if (set.contains(root.val)) { + return; + } + set.add(root.val); + result = Math.max(result, set.size()); + helper(root.left, set); + helper(root.right, set); + set.remove(root.val); + + } +} diff --git a/src/main/java/trees/isValidPreOrderSerialisation.java b/src/main/java/trees/isValidPreOrderSerialisation.java new file mode 100644 index 0000000..ae5d71d --- /dev/null +++ b/src/main/java/trees/isValidPreOrderSerialisation.java @@ -0,0 +1,55 @@ +package trees; + +import java.util.Stack; + +/** + * tricky + * + * https://leetcode.com/problems/verify-preorder-serialization-of-a-binary-tree/ + * + * In a binary tree, if we consider null as leaves, then + * + * all non-null node provides 2 outdegree and 1 indegree (2 children and 1 parent), except root + * all null node provides 0 outdegree and 1 indegree (0 child and 1 parent). + * + * Suppose we try to build this tree. During building, + * we record the difference between out degree and in degree diff = outdegree - indegree. + * When the next node comes, we then decrease diff by 1, because the node provides an in degree. + * If the node is not null, we increase diff by 2, because it provides two out degrees. + * If a serialization is correct, diff should never be negative and diff will be zero when finished. + */ +public class isValidPreOrderSerialisation { + + public boolean isValidSerialization(String preorder) { + int vacancy = 1; + String[] preOrder = preorder.split(","); + + for (String s : preOrder) { + vacancy--; + if (vacancy < 0) return false; + if (!s.equals("#")) vacancy += 2; + + } + + return vacancy == 0; + } + + public boolean isValidSerializationStack(String preorder) { + if (preorder == null) return false; + + Stack st = new Stack<>(); + String[] strs = preorder.split(","); + for (String curr : strs) { + if (curr.equals("#")) { + // replace a number node and its left child "#" to a "#" node. + while (!st.isEmpty() && st.peek().equals("#")) { + st.pop(); + if (st.isEmpty()) return false; + st.pop(); + } + } + st.push(curr); + } + return st.size() == 1 && st.peek().equals("#"); + } +} diff --git a/src/microsoftassesment/DLLNode.java b/src/microsoftassesment/DLLNode.java deleted file mode 100644 index 9efbda4..0000000 --- a/src/microsoftassesment/DLLNode.java +++ /dev/null @@ -1,180 +0,0 @@ -package microsoftassesment; - -import java.util.HashMap; -import java.util.Map; - - class LFUCacahe { - /*.*/ - /* - * @param capacity: total capacity of LFU Cache - * @param curSize: current size of LFU cache - * @param minFrequency: frequency of the last linked list (the minimum frequency of entire LFU cache) - * @param cache: a hash map that has key to Node mapping, which used for storing all nodes by their keys - * @param frequencyMap: a hash map that has key to linked list mapping, which used for storing all - * double linked list by their frequencies - * */ - - - final int capacity; - int curSize; - int minFrequency; - Map cache; - Map frequencyMap; - - public LFUCacahe(int capacity) { - - this.capacity = capacity; - this.curSize = 0; - this.minFrequency = 0; - - this.cache = new HashMap<>(); - this.frequencyMap = new HashMap<>(); - } - - /** - * get node value by key, and then update node frequency as well as relocate that node - **/ - public int get(int key) { - DLLNode curNode = cache.get(key); - if (curNode == null) { - return -1; - } - updateNode(curNode); - return curNode.val; - } - - /** - * add new node into LFU cache, as well as double linked list - * condition 1: if LFU cache has input key, update node value and node position in list - * condition 2: if LFU cache does NOT have input key - * - sub condition 1: if LFU cache does NOT have enough space, remove the Least Recent Used node - * in minimum frequency list, then add new node - * - sub condition 2: if LFU cache has enough space, add new node directly - **/ - public void put(int key, int value) { - // corner case: check cache capacity initialization - if (capacity == 0) { - return; - } - - if (cache.containsKey(key)) { - DLLNode curNode = cache.get(key); - curNode.val = value; - updateNode(curNode); - } else { - curSize++; - if (curSize > capacity) { - // get minimum frequency list - DoubleLinkedList minFreqList = frequencyMap.get(minFrequency); - DLLNode deleteNode = minFreqList.removeTail(); - cache.remove(deleteNode.key); - curSize--; - } - // reset min frequency to 1 because of adding new node - minFrequency = 1; - DLLNode newNode = new DLLNode(key, value); - - // get the list with frequency 1, and then add new node into the list, as well as into LFU cache - DoubleLinkedList curList = frequencyMap.getOrDefault(1, new DoubleLinkedList()); - curList.addNode(newNode); - frequencyMap.put(1, curList); - cache.put(key, newNode); - } - } - - public void updateNode(DLLNode curNode) { - int curFreq = curNode.frequency; - DoubleLinkedList curList = frequencyMap.get(curFreq); - curList.removeNode(curNode); - - // if current list the the last list which has lowest frequency and current node is the only node in that list - // we need to remove the entire list and then increase min frequency value by 1 - if (curFreq == minFrequency && curList.listSize == 0) { - minFrequency++; - } - - curNode.frequency++; - // add current node to another list has current frequency + 1, - // if we do not have the list with this frequency, initialize it - DoubleLinkedList newList = frequencyMap.getOrDefault(curNode.frequency, new DoubleLinkedList()); - newList.addNode(curNode); - frequencyMap.put(curNode.frequency, newList); - } - - /* - * @param key: node key - * @param val: node value - * @param frequency: frequency count of current node - * (all nodes connected in same double linked list has same frequency) - * @param prev: previous pointer of current node - * @param next: next pointer of current node - * */ - public class DLLNode { - int key; - int val; - int frequency; - DLLNode prev; - DLLNode next; - - public DLLNode(int key, int val) { - this.key = key; - this.val = val; - this.frequency = 1; - } - } - - /* - * @param listSize: current size of double linked list - * @param head: head node of double linked list - * @param tail: tail node of double linked list - * */ - class DoubleLinkedList { - int listSize; - DLLNode head; - DLLNode tail; - - public DoubleLinkedList() { - this.listSize = 0; - this.head = new DLLNode(0, 0); - this.tail = new DLLNode(0, 0); - head.next = tail; - tail.prev = head; - } - - /** - * add new node into head of list and increase list size by 1 - **/ - public void addNode(DLLNode curNode) { - DLLNode nextNode = head.next; - curNode.next = nextNode; - curNode.prev = head; - head.next = curNode; - nextNode.prev = curNode; - listSize++; - } - - /** - * remove input node and decrease list size by 1 - **/ - public void removeNode(DLLNode curNode) { - DLLNode prevNode = curNode.prev; - DLLNode nextNode = curNode.next; - prevNode.next = nextNode; - nextNode.prev = prevNode; - listSize--; - } - - /** - * remove tail node - **/ - public DLLNode removeTail() { - // DO NOT FORGET to check list size - if (listSize > 0) { - DLLNode tailNode = tail.prev; - removeNode(tailNode); - return tailNode; - } - return null; - } - } - } \ No newline at end of file diff --git a/src/microsoftassesment/RemoveCharsMoreThanKOccurrence.java b/src/microsoftassesment/RemoveCharsMoreThanKOccurrence.java deleted file mode 100644 index 8bc8b25..0000000 --- a/src/microsoftassesment/RemoveCharsMoreThanKOccurrence.java +++ /dev/null @@ -1,55 +0,0 @@ -package microsoftassesment; - - -// given eedaaad and k=3 return eedaad -public class RemoveCharsMoreThanKOccurrence { - - public static String removeKConsequtiveChars(String s, int k){ - if(s==null || s.length()==0) return null; - StringBuilder sb = new StringBuilder(); - sb.append(s.charAt(0)); - int cnt = 1; - for(int r=1;r synchronousQueue; - - private volatile boolean shaved; - - public Customer(WaitingRoom waitingRoom) { - this.id = idGenerator.incrementAndGet(); - this.waitingRoom = waitingRoom; - this.synchronousQueue = new SynchronousQueue<>(); - } - - @Override - public void run() { - try { - waitingRoom.takeASeat(this); - - System.out.println("customer " + this + " wait to be called and shaved"); - waitToBeCalledAndShaved(); - - shaved = true; - - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void callAndShave() throws InterruptedException { - synchronousQueue.put(true); - } - - public void waitToBeCalledAndShaved() throws InterruptedException { - synchronousQueue.take(); - } - - public boolean isShaved() { - return shaved; - } - - @Override - public String toString() { - return Integer.toString(id); - } -} diff --git a/src/multithreading/barberProblem/Main.java b/src/multithreading/barberProblem/Main.java deleted file mode 100755 index 1f4a65a..0000000 --- a/src/multithreading/barberProblem/Main.java +++ /dev/null @@ -1,37 +0,0 @@ -package multithreading.barberProblem; - -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Stream; - -import static java.util.concurrent.TimeUnit.MINUTES; -import static java.util.stream.Collectors.toList; - -public class Main { - - public static void main(String[] args) throws InterruptedException { - WaitingRoom waitingRoom = new WaitingRoom(10); - - ExecutorService executorService = Executors.newFixedThreadPool(100); - executorService.submit(new Barber(waitingRoom, new AtomicInteger(0))); - executorService.submit(new Barber(waitingRoom, new AtomicInteger(1))); - executorService.submit(new Barber(waitingRoom, new AtomicInteger(2))); - - List customers = Stream.generate(() -> new Customer(waitingRoom)) - .limit(100) - .peek(executorService::submit) - .collect(toList()); - - while (!customers.stream().allMatch(Customer::isShaved)) { - TimeUnit.SECONDS.sleep(1); - } - - System.out.println("all customers have been shaved"); - executorService.shutdownNow(); - executorService.awaitTermination(1, MINUTES); - } - -} diff --git a/src/multithreading/barberProblem/WaitingRoom.java b/src/multithreading/barberProblem/WaitingRoom.java deleted file mode 100755 index 667fd81..0000000 --- a/src/multithreading/barberProblem/WaitingRoom.java +++ /dev/null @@ -1,21 +0,0 @@ -package multithreading.barberProblem; - -import java.util.concurrent.ArrayBlockingQueue; - -public class WaitingRoom { - - private final ArrayBlockingQueue waitingCustomers; - - public WaitingRoom(int capacity) { - waitingCustomers = new ArrayBlockingQueue<>(capacity); - } - - public void takeASeat(Customer customer) throws InterruptedException { - waitingCustomers.put(customer); - } - - public Customer nextCustomer() throws InterruptedException { - return waitingCustomers.take(); - } - -} diff --git a/src/multithreading/executor/User.java b/src/multithreading/executor/User.java deleted file mode 100644 index f5fd305..0000000 --- a/src/multithreading/executor/User.java +++ /dev/null @@ -1,32 +0,0 @@ -package multithreading.executor; - -public class User { - - String userName; - String userId; - String emailAddress; - - public String getUserName() { - return userName; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public String getUserId() { - return userId; - } - - public void setUserId(String userId) { - this.userId = userId; - } - - public String getEmailAddress() { - return emailAddress; - } - - public void setEmailAddress(String emailAddress) { - this.emailAddress = emailAddress; - } -} diff --git a/src/multithreading/practice/CountdownLatch.java b/src/multithreading/practice/CountdownLatch.java deleted file mode 100644 index 0e6dfcf..0000000 --- a/src/multithreading/practice/CountdownLatch.java +++ /dev/null @@ -1,38 +0,0 @@ -package multithreading.practice; - -import java.util.concurrent.CountDownLatch; - -public class CountdownLatch { - - public static void main(String[] args) { - final CountDownLatch countdown = new CountDownLatch(10); - for (int i = 0; i < 10; ++ i){ - Thread t= new Thread() { - public void run() { - try { - doSomething(); - countdown.countDown(); - System.out.printf("Waiting on %d other threads.",countdown.getCount()); - System.out.println(); - countdown.await(); //waits until everyone reaches this point - - } catch (InterruptedException e) { - e.printStackTrace(); - } - finish(); - } - }; - t.start(); - } - } - - public static void doSomething() throws InterruptedException { - Thread.sleep(1000); - } - - public static void finish(){ - System.out.println("Finished everything"); - } -} - - diff --git a/src/multithreading/practice/Foo.java b/src/multithreading/practice/Foo.java deleted file mode 100644 index 007f9ac..0000000 --- a/src/multithreading/practice/Foo.java +++ /dev/null @@ -1,39 +0,0 @@ -package multithreading.practice; - -import java.util.concurrent.Semaphore; - -class Foo { - Semaphore first= new Semaphore(0); - Semaphore second= new Semaphore(0); - Semaphore third= new Semaphore(0); - - public Foo() { - - } - - public void first(Runnable printFirst) throws InterruptedException { - first.acquire(); - - - printFirst.run(); - - second.release(); - } - - public void second(Runnable printSecond) throws InterruptedException { - first.release(); - second.acquire(); - - printSecond.run(); - third.release(); - } - - public void third(Runnable printThird) throws InterruptedException { - first.release(); - third.acquire(); - - printThird.run(); - - - } -} \ No newline at end of file diff --git a/src/practiceproblems/.vscode/UrlEncode.java b/src/practiceproblems/.vscode/UrlEncode.java deleted file mode 100644 index e69de29..0000000 diff --git a/src/practiceproblems/AdvantageShuffle.java b/src/practiceproblems/AdvantageShuffle.java deleted file mode 100644 index 681c060..0000000 --- a/src/practiceproblems/AdvantageShuffle.java +++ /dev/null @@ -1,40 +0,0 @@ -package practiceproblems; - -// the advantage of A with respect to B is the number of indices i for which A[i] > B[i]. - -import java.util.Arrays; -import java.util.PriorityQueue; - -// Return any permutation of A that maximizes its advantage with respect to B. -//Input: A = [12,24,8,32], B = [13,25,32,11] -//Output: [24,32,8,12] -// Input: A = [2,7,11,15], B = [1,10,4,11] -// Output: [2,11,7,15] -public class AdvantageShuffle { - public int[] advantageCount(int[] A, int[] B) { - Arrays.sort(A); - - PriorityQueue pq= new PriorityQueue<>((a, b)->Integer.compare(b[0],a[0])); - for(int i=0;ival){ // if polled element is lesser thar A[hi], put A[hi] at index of - // queued elements index, means, equal to B's current index we are putting - // a value greater that B's in result arrays - result[index]=A[hi--]; - }else{ - result[index]=A[lo++]; - } - } - return result; - } -} \ No newline at end of file diff --git a/src/practiceproblems/ArrangeInQueue.java b/src/practiceproblems/ArrangeInQueue.java deleted file mode 100644 index 2ea3c8b..0000000 --- a/src/practiceproblems/ArrangeInQueue.java +++ /dev/null @@ -1,51 +0,0 @@ -package practiceproblems; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -//You are given an array of people, people, -// which are the attributes of some people in a queue (not necessarily in order). -// Each people[i] = [hi, ki] represents the ith person of height hi with exactly ki -// other people in front who have a height greater than or equal to hi. -//Reconstruct and return the queue that is represented by the input array people. -// The returned queue should be formatted as an array queue, -// where queue[j] = [hj, kj] is the attributes of the jth person in the -// queue (queue[0] is the person at the front of the queue). - -// Input: -// [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] -// Output: -// [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]] -//Explanation: -// Person 0 has height 5 with no other people taller or the same height in front. -// Person 1 has height 7 with no other people taller or the same height in front. -// Person 2 has height 5 with two persons taller or the same height in front, which is person 0 and 1. -// Person 3 has height 6 with one person taller or the same height in front, which is person 1. -// Person 4 has height 4 with four people taller or the same height in front, which are people 0, 1, 2, and 3. -// Person 5 has height 7 with one person taller or the same height in front, which is person 1. -// Hence [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] is the reconstructed queue. -public class ArrangeInQueue { - -// 1. Sort people by their height, shortest to tallest -// 2. Iterate and put each person to the correct position -// 2.a When placing the shortest person, all person to his left will be taller or equal height, since you are iterating in height sorted array, so put it at a index equal to its k value -// 2.b When placing the next shortest person, find a position, where count of positions to the left unoccupied plus the ones where same height person is placed, is equal to its k value -// 2.c Keep repeating - public static int[][] reconstructQueue(int[][] people) { - List result= new ArrayList<>(); - Arrays.sort(people,(a, b)->{ - if(a[0]==b[0]) return a[1]-b[1]; - else return b[0]-a[0]; - }); - System.out.println("Sorted values: "+ Arrays.deepToString(people)); - for(int[] x: people){ - result.add(x[1],x); - System.out.println(Arrays.deepToString(result.toArray(new int[people.length][2]))); - } - return result.toArray(new int[people.length][2]); - } - - public static void main(String[] args) { - System.out.println(Arrays.deepToString(reconstructQueue(new int[][]{{7,0},{4,4},{7,1},{5,0},{6,1},{5,2}}))); - } -} \ No newline at end of file diff --git a/src/practiceproblems/BackspaceCompare.java b/src/practiceproblems/BackspaceCompare.java deleted file mode 100644 index 151c4c0..0000000 --- a/src/practiceproblems/BackspaceCompare.java +++ /dev/null @@ -1,63 +0,0 @@ -package practiceproblems; - -/** - * https://leetcode.com/problems/backspace-string-compare/ - * Given two strings S and T, return if they are equal when both are typed into empty text editors. # means a backspace character. - * - * Note that after backspacing an empty text, the text will continue empty. - * - * Input: S = "ab#c", T = "ad#c" - * Output: true - * Explanation: Both S and T become "ac". - * - * Input: S = "a##c", T = "#a#c" - * Output: true - * Explanation: Both S and T become "c". - */ -class BackspaceCompare { - - public static boolean backspaceCompare(String S, String T) { - - if (S == null || T == null) { - return S == T; - } - int i = S.length() - 1, j = T.length() - 1; - int cnt1 = 0, cnt2 = 0;//number of '#'; - while (i >= 0 || j >= 0) { - //this while loop is executed 2 times i) when it sees '#' it increments the count 'cnt1' - // ii) since 'cnt1'>0 - // the above logic is decrementing the 'i' i.e deleting the char before '#' - - while (i >= 0 && (S.charAt(i) == '#' || cnt1 > 0)) { - if (S.charAt(i) == '#') { - cnt1++; - } else { - cnt1--; - } - i--; - } - - // same as previous comment - while (j >= 0 && (T.charAt(j) == '#' || cnt2 > 0)) { - if (T.charAt(j) == '#') { - cnt2++; - } else { - cnt2--; - } - j--; - } - // if the non '#' char is not equal, then no need to proceed further - if (i >= 0 && j >= 0 && S.charAt(i) == T.charAt(j)) { - i--; - j--; - } else { - return i == -1 && j == -1; - } - } - return true; - } - - public static void main(String[] args) { - System.out.println(backspaceCompare("a##c", "#a#c")); - } -} \ No newline at end of file diff --git a/src/practiceproblems/BinaryTreeCousins.java b/src/practiceproblems/BinaryTreeCousins.java deleted file mode 100644 index a9859fe..0000000 --- a/src/practiceproblems/BinaryTreeCousins.java +++ /dev/null @@ -1,51 +0,0 @@ -package practiceproblems; - -import java.util.LinkedList; -import java.util.Queue; - -/** - * In a binary tree, the root node is at depth 0, - * and children of each depth k node are at depth k+1. - * Two nodes of a binary tree are cousins if they have the same depth, - * but have different parents. - * We are given the root of a binary tree with unique values, - * and the values x and y of two different nodes in the tree. - * Return true if and only if the nodes corresponding to the values x and y are cousins. - * - * Input: root = [1,2,3,null,4,null,5], x = 5, y = 4 - * Output: true - * 1 - * / \ - * 2 3 - * \ \ - * 4 5 - * - */ -public class BinaryTreeCousins { - public boolean isCousins(TreeNode root, int x, int y) { - Queue queue = new LinkedList<>(); - if(root == null) return false; - queue.add(root); - int depthY = -1; - int depthX = -2; - int level = 0; - while(!queue.isEmpty()){ - int size = queue.size(); - for(int i = 0 ; i < size ; i++){ - TreeNode node = queue.remove(); - // eagerly checking if both vales are of same parent - if(node.left != null && node.right != null){ - if(node.left.val == x && node.right.val == y) return false; - if(node.left.val == y && node.right.val == x) return false; - } - //now checking if any of x or y matches with current node and records the level - if(node.val == x) depthX = level; - if(node.val == y) depthY = level; - if(node.left != null) queue.add(node.left); - if(node.right != null) queue.add(node.right); - } - level++; - } - return depthX == depthY; - } -} \ No newline at end of file diff --git a/src/practiceproblems/BuyAndSellStockAtMostTwice.java b/src/practiceproblems/BuyAndSellStockAtMostTwice.java deleted file mode 100644 index 96153e1..0000000 --- a/src/practiceproblems/BuyAndSellStockAtMostTwice.java +++ /dev/null @@ -1,50 +0,0 @@ -package practiceproblems; - -/** - * https://www.geeksforgeeks.org/maximum-profit-by-buying-and-selling-a-share-at-most-twice/ - */ -class BuyAndSellStockAtMostTwice { - - public static void main(String args[]) { - int price[] = { 2, 30, 15, 10, 8, 25, 80 }; - int n = price.length; - System.out.println("Maximum Profit = " + maxProfit(price)); - } - - /** - * the idea is when we find a profit which is from - * i to n, we can break it in to i to k, k+1 to n - * in this manner at each point we can calculate profit from - * (left min element to current element) and (current element to right max element) - * the second part of the above eq can be achieved by coming from right to left - * for input [3,3,5,0,0,3,1,4] - * profit from l->r [0,0,2,2,2,3,3,4] - * profit from r->l [4,4,4,4,4,3,3,0] - * this simply states that at index 2 if we come from left the profit is 2 - * and we can initiate another transaction to obtain another profit - */ - public static int maxProfit(int[] prices) { - int ans = 0; - if (prices.length == 0 || prices.length == 1) - return ans; - int[] p = new int[prices.length]; - int minBuy = prices[0]; - int maxProfit = 0; - for (int i=1;i=0;i--) { - maxSell = Math.max(maxSell, prices[i]); - maxProfit = Math.max(maxProfit, maxSell - prices[i]); - p[i] += maxProfit; - ans = Math.max(p[i], ans); - } - return ans; - } - -} diff --git a/src/practiceproblems/CloneGraph.java b/src/practiceproblems/CloneGraph.java deleted file mode 100644 index ba1569b..0000000 --- a/src/practiceproblems/CloneGraph.java +++ /dev/null @@ -1,70 +0,0 @@ -package practiceproblems; - -import java.util.*; - -/** - * Given a reference of a node in a connected undirected graph. - * - * Return a deep copy (clone) of the graph. - * - * Each node in the graph contains a val (int) and a list (List[Node]) of its neighbors - * - * For simplicity sake, each node's value is the same as the node's index (1-indexed). - * For example, the first node with val = 1, the second node with val = 2, and so on. - * The graph is represented in the test case using an adjacency list. - * - * Adjacency list is a collection of unordered lists used to represent a finite graph. - * Each list describes the set of neighbors of a node in the graph. - * - * The given node will always be the first node with val = 1. - * You must return the copy of the given node as a reference to the cloned graph. - */ -public class CloneGraph { - private static class Node { - public int val; - public List neighbors; - - public Node() { - val = 0; - neighbors = new ArrayList(); - } - - public Node(int _val) { - val = _val; - neighbors = new ArrayList(); - } - - public Node(int _val, ArrayList _neighbors) { - val = _val; - neighbors = _neighbors; - } - } - public Node cloneGraph(Node node) { - if(node==null) return node; - - Map map= new HashMap<>(); - - Queue queue= new ArrayDeque<>(); - queue.offer(node); - map.put(node, new Node(node.val)); - - while(!queue.isEmpty()){ - Node current= queue.poll(); - - for(Node neighbors: current.neighbors){ - if(!map.containsKey(neighbors)){ - Node neighborClone= new Node(neighbors.val); - map.put(neighbors,neighborClone); - queue.offer(neighbors); - } - - map.get(current).neighbors.add(map.get(neighbors)); - } - } - - return map.get(node); - - } - - -} \ No newline at end of file diff --git a/src/practiceproblems/ConstructTreeFromInorderAndPostorder.java b/src/practiceproblems/ConstructTreeFromInorderAndPostorder.java deleted file mode 100644 index f0eb91a..0000000 --- a/src/practiceproblems/ConstructTreeFromInorderAndPostorder.java +++ /dev/null @@ -1,31 +0,0 @@ -package practiceproblems; - -import java.util.HashMap; -import java.util.Map; - -public class ConstructTreeFromInorderAndPostorder { - // idea is same as inorder-preorder, but we take postOrder[lastIndex] as root; - public TreeNode buildTree(int[] inorder, int[] postorder) { - if(inorder==null || postorder==null) return null; - Map map= new HashMap(); - for(int i=0;i map){ - if(iStart>iEnd || pstart>pend) return null; - - TreeNode root= new TreeNode(postorder[pend]); - int divider=map.get(root.val); - // one more change is, since we need to take last element as root - // we have to carefully pass the right index to recursive calls - // pstart, pstart+divider-iStart-1-> left subarray - //pstart+divider-iStart, pend -> right sub array - root.left= helperFn(inorder, iStart,divider-1,postorder,pstart,pstart+divider-iStart-1,map); - root.right=helperFn(inorder,divider+1,iEnd,postorder,pstart+divider-iStart,pend-1,map); - return root; - } -} \ No newline at end of file diff --git a/src/practiceproblems/ConstructTreeFromInorderAndPreorder.java b/src/practiceproblems/ConstructTreeFromInorderAndPreorder.java deleted file mode 100644 index ffbb34d..0000000 --- a/src/practiceproblems/ConstructTreeFromInorderAndPreorder.java +++ /dev/null @@ -1,49 +0,0 @@ -package practiceproblems; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ - */ -class ConstructTreeFromInorderAndPreorder { - - // The basic idea is here: - // Say we have 2 arrays, PRE and IN. - // Preorder traversing implies that PRE[0] is the root node. - // Then we can find this PRE[0] in IN, say it's IN[5]. - // Now we know that IN[5] is root, so we know that IN[0] - IN[4] is on the left - // side, IN[6] to the end is on the right side. - // Recursively doing this on sub arrays, we can build a tree out of it :) - public TreeNode buildTree(int[] preorder, int[] inorder) { - Map map = new HashMap<>(); - List set = new LinkedList<>(); - - for (int i = 0; i < inorder.length; i++) { - map.put(inorder[i], i); - } - - for (int i = 0; i < preorder.length; i++) { - set.add(preorder[i]); - } - - return buildTreeUtil(map, set, 0, inorder.length - 1); - - } - - public TreeNode buildTreeUtil(Map map, List set, int start, int end) { - if (start > end) - return null; - if (set.isEmpty()) - return null; - int rootVal = set.get(0); - set.remove(0); - TreeNode root = new TreeNode(rootVal); - int inorderIndex = map.get(rootVal); - root.left = buildTreeUtil(map, set, start, inorderIndex - 1); - root.right = buildTreeUtil(map, set, inorderIndex + 1, end); - return root; - } -} \ No newline at end of file diff --git a/src/practiceproblems/ContainerWithMostWater.java b/src/practiceproblems/ContainerWithMostWater.java deleted file mode 100644 index c2fc13f..0000000 --- a/src/practiceproblems/ContainerWithMostWater.java +++ /dev/null @@ -1,36 +0,0 @@ -package practiceproblems; - -/** - * Given n non-negative integers a1, a2, ..., an , - * where each represents a point at coordinate (i, ai). - * n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). - * Find two lines, which together with x-axis forms a container, such that the container contains the most water. - - Note: You may not slant the container and n is at least 2. - Input: [1,8,6,2,5,4,8,3,7] - Output: 49 - */ -public class ContainerWithMostWater { - - public int maxArea(int[] height) { - if(height==null || height.length==0) return 0; - int i=0; - int j= height.length-1; - int result=0; - - while(iheight[j]){ // the reason we are moving lesser side is - // j-i is going to be decreasing so we need to - // maintain higher side to have max value - j--; - }else{ - i++; - } - } - return result; - } -} diff --git a/src/practiceproblems/CountElements.java b/src/practiceproblems/CountElements.java deleted file mode 100644 index e65132b..0000000 --- a/src/practiceproblems/CountElements.java +++ /dev/null @@ -1,59 +0,0 @@ -package practiceproblems; - -import java.util.HashMap; - -/** - * Given an integer array arr, count element x such that x + 1 is also in arr. - *

- * If there're duplicates in arr, count them separetely. - *

- *

- *

- * Example 1: - *

- * Input: arr = [1,2,3] - * Output: 2 - * Explanation: 1 and 2 are counted cause 2 and 3 are in arr. - * Example 2: - *

- * Input: arr = [1,1,3,3,5,5,7,7] - * Output: 0 - * Explanation: No numbers are counted, cause there's no 2, 4, 6, or 8 in arr. - * Example 3: - *

- * Input: arr = [1,3,2,3,5,0] - * Output: 3 - * Explanation: 0, 1 and 2 are counted cause 1, 2 and 3 are in arr. - * Example 4: - *

- * Input: arr = [1,1,2,2] - * Output: 2 - * Explanation: Two 1s are counted cause 2 is in arr. - */ -public class CountElements { - - public static int countElements(int[] arr) { - if (arr == null || arr.length == 0) { - return 0; - } - - HashMap freqMap = new HashMap<>(); - - for (int in : arr) { - freqMap.put(in, freqMap.getOrDefault(in, 0) + 1); - } - - int count = 0; - for (int i = 0; i < arr.length; i++) { - if (freqMap.containsKey(arr[i] - 1)) { - count = count + freqMap.get(arr[i] - 1); - freqMap.put(arr[i] - 1, 0); - } - } - return count; - } - - public static void main(String[] args) { - System.out.println(countElements(new int[]{1, 3, 2, 3, 5, 0})); - } -} \ No newline at end of file diff --git a/src/practiceproblems/CourseSchedule.java b/src/practiceproblems/CourseSchedule.java deleted file mode 100644 index e943097..0000000 --- a/src/practiceproblems/CourseSchedule.java +++ /dev/null @@ -1,116 +0,0 @@ -package practiceproblems; - -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Queue; -/** - * Input: numCourses = 2, prerequisites = [[1,0]] -Output: true -Explanation: There are a total of 2 courses to take. -To take course 1 you should have finished course 0. So it is possible. - -Input: numCourses = 2, prerequisites = [[1,0],[0,1]] -Output: false -Explanation: There are a total of 2 courses to take. - To take course 1 you should have finished course 0, and to take course 0 you should - also have finished course 1. So it is impossible. - */ -class CourseSchedule { - public boolean canFinish(int numCourses, int[][] prerequisites) { - - Map> map = new HashMap<>(); // Courses that depend on the key - int[] degrees = new int[numCourses]; // # of prerequisites for course i - Queue queue = new ArrayDeque<>(); // Used to find dependants and decrease their outdegree - - for (int[] pre : prerequisites) { - List tempList = map.getOrDefault(pre[1], new ArrayList<>()); - tempList.add(pre[0]); - degrees[pre[0]]++; - map.put(pre[1], tempList); - } - - for (int i = 0; i < degrees.length; i++) { - if (degrees[i] == 0) { - queue.offer(i); - } - } - - int count = 0; - while (!queue.isEmpty()) { - int temp = queue.poll(); - if (degrees[temp] == 0) { - count++; // if cond for duplicates - } - if (!map.containsKey(temp)) { - continue; - } - for (int i : map.get(temp)) { - if (--degrees[i] == 0) { - queue.offer(i); - } - } - } - - return count == numCourses; - } - - public boolean canFinishDFS(int numCourses, int[][] prerequisites) { - // this method basically finds a back-edge between nodes - // backedge is when doing a node(A)'s dfs, it puts A to a temp state - // while traversing A's child, if any of child dosen't have anymore child it's marked as completed - // if there are children it put's the current child to temp state and visits it's children - // so when doing a dfs for a node if it encounters a temp state node rather than completed node - // then that means there's a cycle we cannot complete the course - // (T) A \ - // / / - // (T) B / - // / \ / - // (Co) C D (T) while doing DFS for D's components we encounter A, but A is still in temp state - // - ArrayList[] adjList= new ArrayList[numCourses]; - for(int i=0;i(); - } - for(int[] preReq:prerequisites){ - adjList[preReq[0]].add(preReq[1]); - } - // this visited array will maintain 3 values 0,1 and 2 - // 0-unvisited, 1-being visited and 2 visited - int[] visited= new int[numCourses]; - for(int i=0;i[] adjList, int[] visited, int vertex){ - if(visited[vertex]==1) return false; // when a node comes with being visited state, we fail it - visited[vertex]=1; - for(int adj: adjList[vertex]){ - if(!dfs(adjList, visited, adj)) return false; - } - visited[vertex]=2; // finally we set visited to true - return true; - } - // this is to get the order of course as output - public boolean dfs( List[] adjList, int[] visited, Listresult, int node){ - if(visited[node]==1) return false; - if(visited[node]==2) return true; - - visited[node]=1; - for(int adj: adjList[node]){ - if(!dfs(adjList, visited, result, adj)){ - return false; - } - } - visited[node]=2; - result.add(node); // this will keep track of which to fininsh first and last - return true; - } -} \ No newline at end of file diff --git a/src/practiceproblems/DesignFileSystem.java b/src/practiceproblems/DesignFileSystem.java deleted file mode 100644 index aecb906..0000000 --- a/src/practiceproblems/DesignFileSystem.java +++ /dev/null @@ -1,64 +0,0 @@ -package practiceproblems; - -import java.util.HashMap; - -/** - * You are asked to design a file system which provides two functions: - * - * createPath(path, value): Creates a new path and associates a value to it if possible and returns True. - * Returns False if the path already exists or its parent path doesn't exist. - * - * get(path): Returns the value associated with a path or returns -1 if the path doesn't exist. - * - * ["FileSystem","createPath","createPath","get","createPath","get"] - * [[],["/leet",1],["/leet/code",2],["/leet/code"],["/c/d",1],["/c"]] - * Output: - * [null,true,true,2,false,-1] - * Explanation: - * FileSystem fileSystem = new FileSystem(); - * - * fileSystem.createPath("/leet", 1); // return true - * fileSystem.createPath("/leet/code", 2); // return true - * fileSystem.get("/leet/code"); // return 2 - * fileSystem.createPath("/c/d", 1); // return false because the parent path "/c" doesn't exist. - * fileSystem.get("/c"); // return -1 because this path doesn't exist. - */ -public class DesignFileSystem { - - private HashMap m = new HashMap<>(); - - /** - * Initialization of class. - * Use a hash map to store the path and value. - */ - public DesignFileSystem() { - m.put("", -1); // avoid initially when path is "/a" regarded as false - } - - /** - * Creates a new path and associates a value to it if possible and returns True. - * The valid path's parent is the path before the last "/". - * Hence, check parent and then put the path into map if it is valid. - * If the path has already exist, return false. - * - * @param path given path - * @param value given value - * @return true to create a new path with value, false if the path already exists or its parent path doesn't exist - */ - public boolean create(String path, int value) { - if (path.charAt(0) != '/') { - return false; - } - String parent = path.substring(0, path.lastIndexOf("/")); - if (!m.containsKey(parent)) { - return false; - } - - return m.putIfAbsent(path, value) == null; // if the path exist, m.putIfAbsent(path, value) will be null - } - - public int get(String path) { - return m.getOrDefault(path, -1); - } - -} \ No newline at end of file diff --git a/src/practiceproblems/DesignStackIncrement.java b/src/practiceproblems/DesignStackIncrement.java deleted file mode 100644 index 9c0b6cf..0000000 --- a/src/practiceproblems/DesignStackIncrement.java +++ /dev/null @@ -1,101 +0,0 @@ -package practiceproblems; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Stack; - -/** - * Design a stack which supports the following operations. - * - * Implement the CustomStack class: - * - * CustomStack(int maxSize) Initializes the object with maxSize which is the maximum number of elements in the stack or do nothing if the stack reached the maxSize. - * void push(int x) Adds x to the top of the stack if the stack hasn't reached the maxSize. - * int pop() Pops and returns the top of stack or -1 if the stack is empty. - * void inc(int k, int val) Increments the bottom k elements of the stack by val. - * If there are less than k elements in the stack, just increment all the elements in the stack. - * - * ["CustomStack","push","push","pop","push","push","push","increment","increment","pop","pop","pop","pop"] - * [[3],[1],[2],[],[2],[3],[4],[5,100],[2,100],[],[],[],[]] - * Output - * [null,null,null,2,null,null,null,null,null,103,202,201,-1] - * Explanation - * CustomStack customStack = new CustomStack(3); // Stack is Empty [] - * customStack.push(1); // stack becomes [1] - * customStack.push(2); // stack becomes [1, 2] - * customStack.pop(); // return 2 --> Return top of the stack 2, stack becomes [1] - * customStack.push(2); // stack becomes [1, 2] - * customStack.push(3); // stack becomes [1, 2, 3] - * customStack.push(4); // stack still [1, 2, 3], Don't add another elements as size is 4 - * customStack.increment(5, 100); // stack becomes [101, 102, 103] - * customStack.increment(2, 100); // stack becomes [201, 202, 103] - * customStack.pop(); // return 103 --> Return top of the stack 103, stack becomes [201, 202] - * customStack.pop(); // return 202 --> Return top of the stack 102, stack becomes [201] - * customStack.pop(); // return 201 --> Return top of the stack 101, stack becomes [] - * customStack.pop(); // return -1 --> Stack is empty return -1. - */ -public class DesignStackIncrement { - - int n; - int[] inc; - Stack stack; - - public DesignStackIncrement(int maxSize) { - n = maxSize; - inc = new int[n]; - stack = new Stack<>(); - } - - public void push(int x) { - if (stack.size() < n) { - stack.push(x); - } - } - - public int pop() { - /* - since array elements go forward(left -> right) and stack goes - top to bottom which translates to array as right->left - so when the increment operation happens for let's say last 4 elements - we set the array pos 4 to 'increment' value. Finally when the pop - is happened we need to set the array's 3rd posistion to the 4th's value inc[i - 1] += inc[i]; - since 3 is yet to be pop-ed from stack - */ - - int i = stack.size() - 1; - if (i < 0) { - return -1; - } - if (i > 0) { - inc[i - 1] += inc[i]; - } - int res = stack.pop() + inc[i]; - inc[i] = 0; - return res; - } - - public void increment(int k, int val) { - int i = Math.min(k, stack.size()) - 1; - if (i >= 0) { - inc[i] += val; - } - } - - public static void main(String[] args) { - DesignStackIncrement customStack = new DesignStackIncrement(4); - customStack.push(1); - customStack.push(2); - customStack.push(3); - customStack.push(4); - customStack.increment(5, 100); - customStack.increment(2, 100); - System.out.println(customStack.pop()); - System.out.println(customStack.pop()); - System.out.println(customStack.pop()); - System.out.println(customStack.pop()); - - List list = new ArrayList<>(Arrays.asList("hello".split(""))); - list.size(); - } -} \ No newline at end of file diff --git a/src/practiceproblems/DifferentWaysToAddParenthesis.java b/src/practiceproblems/DifferentWaysToAddParenthesis.java deleted file mode 100644 index 22039f6..0000000 --- a/src/practiceproblems/DifferentWaysToAddParenthesis.java +++ /dev/null @@ -1,61 +0,0 @@ -package practiceproblems; - -// Given a string of numbers and operators, -// return all possible results from computing all the different possible ways to group numbers -// and operators. The valid operators are +, - and *. - -import java.util.*; - -// Input: "2*3-4*5" -// Output: [-34, -14, -10, -10, 10] -// Explanation: -// (2*(3-(4*5))) = -34 -// ((2*3)-(4*5)) = -14 -// ((2*(3-4))*5) = -10 -// (2*((3-4)*5)) = -10 -// (((2*3)-4)*5) = 10 -public class DifferentWaysToAddParenthesis { - public List diffWaysToCompute(String input) { - if(input==null) return Collections.emptyList(); - - Map> map= new HashMap<>(); - return bfsHelper(input, map); - - } - - public List bfsHelper(String input, Map> map){ - - if(map.containsKey(input)){ - return map.get(input); - } - - List result= new ArrayList<>(); - if(!input.contains("+") && !input.contains("-") && !input.contains("*")){ - result.add(Integer.parseInt(input)); - }else{ - // Split input string into two parts and solve them recursively - // for ex input = 2*3-4 output=2,-2 - // 2* | 3-4 => this right and left expression returns a list - // 2*3| -4 => this right and left expression returns another list - for(int i=0;i firstList= bfsHelper(input.substring(0,i),map); - List secondList= bfsHelper(input.substring(i+1),map); - for(int first: firstList){ - for(int second: secondList){ - if(input.charAt(i)=='+'){ - result.add(first+second); - }else if(input.charAt(i)=='-'){ - result.add(first-second); - }else{ - result.add(first*second); - } - } - } - } - } - } - map.put(input,result); - return result; - } -} \ No newline at end of file diff --git a/src/practiceproblems/DungeonGame.java b/src/practiceproblems/DungeonGame.java deleted file mode 100644 index 7e24344..0000000 --- a/src/practiceproblems/DungeonGame.java +++ /dev/null @@ -1,64 +0,0 @@ -package practiceproblems; - -// The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. -//The dungeon consists of M x N rooms laid out in a 2D grid. -//Our valiant knight (K) was initially positioned in the top-left room and must fight his way through the dungeon to rescue the princess. - -// The knight has an initial health point represented by a positive integer. -//If at any point his health point drops to 0 or below, he dies immediately. -//Input -// |-2 -3 3 | -// |-5 -10 1 | -// |10 30 -5 | - -//output 7 - -// the trick here is to go bottom up, start from the last cell, -// inorder to reach there he should have at-least 6 as health, so that -// when he reaches -5(energy is consumed) and he's left with +1 health -// likewise if we backtrack from end to start, we'll need +7 as min initial health to -// play the game -public class DungeonGame { - public int calculateMinimumHP(int[][] dungeon) { - - int[][] dp = new int[dungeon.length][dungeon[0].length]; - - int m = dungeon.length; - int n = dungeon[0].length; - - dp[m-1][n-1] = Math.max(1, 1-dungeon[m-1][n-1]); - - // Populate the last column - for(int i=m-2;i>=0;i--){ - dp[i][n-1] = Math.max(1, dp[i+1][n-1]-dungeon[i][n-1]); - } - - // Populate the last row - for(int i=n-2;i>=0;i--){ - dp[m-1][i] = Math.max(1, dp[m-1][i+1]-dungeon[m-1][i]); - } - - // to achieve the answer, we need to setup the last row and last column - // we know to reach last cell we need 6 as energy, let's say that comes - // from cell above it, that cell's original val is +1, so we must have - // 5 energy when we reach there and adding it up, it became 6 - // the reason to put 1 on last row is, the value in that cell is 30 - // so to reach last cell from that cell, we need only 6 energy(min) - // to have 6 from +30, player should have health of -24 and player cannot - // have neg val, so we put 1 as filler - // |* * 2 | - // |* * 5 | - // |1 1 6 | - - // Populate the rest by taking max of bottom and right (reverse of down and left) - - for(int i=m-2;i>=0;i--){ - for(int j=n-2;j>=0;j--){ - dp[i][j] = Math.max(1, Math.min(dp[i+1][j], dp[i][j+1])-dungeon[i][j]); - } - } - - - return dp[0][0]; - } -} \ No newline at end of file diff --git a/src/practiceproblems/EvaluvateRPN.java b/src/practiceproblems/EvaluvateRPN.java deleted file mode 100644 index 033e295..0000000 --- a/src/practiceproblems/EvaluvateRPN.java +++ /dev/null @@ -1,47 +0,0 @@ -package practiceproblems; - -import java.util.ArrayDeque; -import java.util.Deque; - -// Input: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"] -// Output: 22 -// Explanation: -// ((10 * (6 / ((9 + 3) * -11))) + 17) + 5 -// = ((10 * (6 / (12 * -11))) + 17) + 5 -// = ((10 * (6 / -132)) + 17) + 5 -// = ((10 * 0) + 17) + 5 -// = (0 + 17) + 5 -// = 17 + 5 -// = 22 -public class EvaluvateRPN { - public int reversePolishNotation(String[] tokens) { - if(tokens==null && tokens.length==0) return 0; - Deque deque= new ArrayDeque<>(); - for(String i: tokens){ - if(i.length()==1 && "+*-/".contains(i)){ - Integer second= deque.removeFirst(); - Integer first= deque.removeFirst(); - //System.out.println(first +" - "+ second +" "+i); - switch(i){ - case "+": - deque.addFirst(first+second); - break; - case "-": - deque.addFirst(first-second); - break; - case "*": - deque.addFirst(first*second); - break; - case "/": - deque.addFirst(first/second); - break; - - } - }else{ - deque.addFirst(Integer.parseInt(i)); - } - } - - return deque.removeFirst(); - } -} \ No newline at end of file diff --git a/src/practiceproblems/FindAllAnagram.java b/src/practiceproblems/FindAllAnagram.java deleted file mode 100644 index 0ae0fbf..0000000 --- a/src/practiceproblems/FindAllAnagram.java +++ /dev/null @@ -1,60 +0,0 @@ -package practiceproblems; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. - * - * Strings consists of lowercase English letters only and the length of - * both strings s and p will not be larger than 20,100. - * - * The order of output does not matter. - * - * Input: - * s: "cbaebabacd" p: "abc" - * - * Output: - * [0, 6] - * - * Explanation: - * The substring with start index = 0 is "cba", which is an anagram of "abc". - * The substring with start index = 6 is "bac", which is an anagram of "abc". - */ -public class FindAllAnagram { - - public List findAnagrams(String s, String p) { - Map map = new HashMap<>(); - for(char ch: p.toCharArray()){ - map.put(ch, map.getOrDefault(ch,0)+1); - } - int counter= map.size(); - - int start=0; int end=0; - List result= new ArrayList<>(); - while(end0) counter++; - } - if(end-start==p.length()) { - result.add(start); - } - start++; - } - } - - return result; - } -} diff --git a/src/practiceproblems/FindMissingNumbers.java b/src/practiceproblems/FindMissingNumbers.java deleted file mode 100644 index 50326d3..0000000 --- a/src/practiceproblems/FindMissingNumbers.java +++ /dev/null @@ -1,44 +0,0 @@ -package practiceproblems; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -// Input: [2, 3, 1, 8, 2, 3, 5, 1] -// Output: 4, 6, 7 -public class FindMissingNumbers { - - //Brute Force - // Set set = new HashSet<>(); - // for (int i = 0; i < nums.length; i++) set.add(i + 1); - // for (int i = 0; i < nums.length; i++) set.remove(nums[i]); - // return new ArrayList<>(set); - public List findDisappearedNumbers(int[] nums) { - if(nums.length==0) return Collections.emptyList(); - int i=0; - // cyclic sort begins - while(i result= new ArrayList<>(); - i=0; - while(i A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0 - * 2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0 - */ -public class FourSum { - - public int fourSumCount(int[] A, int[] B, int[] C, int[] D) { - Map sumMap = new HashMap<>(); - - for(int i=0; i - * https://leetcode.com/problems/game-of-life/ - * Given a board with m by n cells, each cell has an initial state live (1) or dead (0). - * Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules - * Any live cell with fewer than two live neighbors dies, as if caused by under-population. - * Any live cell with two or three live neighbors lives on to the next generation. - * Any live cell with more than three live neighbors dies, as if by over-population.. - * Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction. - * - * Input: - * [ - * [0,1,0], - * [0,0,1], - * [1,1,1], - * [0,0,0] - * ] - * Output: - * [ - * [0,0,0], - * [1,0,1], - * [0,1,1], - * [0,1,0] - * ] - */ -public class GameOfLife { - - public void gameOfLife(int[][] board) { - - int[][] dir ={{1,-1},{1,0},{1,1},{0,-1},{0,1},{-1,-1},{-1,0},{-1,1}}; - int row=board.length; - int col=board[0].length; - - for(int i=0; i=row || j1>=col || i1<0 || j1<0) continue; // border conditions - - if(board[i1][j1]==1 || board[i1][j1]==2) liveCells++; - } - - if(board[i][j]==0 && liveCells==3) board[i][j]=3; //Any dead cell with exactly three live neighbors becomes a live cell - - if(board[i][j]==1 && (liveCells<2 || liveCells>3)) board[i][j]=2; //live cell with fewer than two live neighbors dies || Any live cell with more than three live neighbors dies - } - } - - for(int i=0; i 0th node connects to 1,3 .. -Output: true -Explanation: -The graph looks like this: -0----1 -| | -| | -3----2 -We can divide the vertices into two groups: {0, 2} and {1, 3}. -Input: [[1,2,3], [0,2], [0,1,3], [0,2]] -Output: false -Explanation: -The graph looks like this: -0----1 -| \ | -| \ | -3----2 -We cannot find a way to divide the set of nodes into two independent subsets. - */ -public class GraphBiPartite { - public boolean isBipartite(int[][] graph) { - int[] color= new int[graph.length]; - - for(int i=0;i> groupAnagrams(String[] strs) { - List> result= new ArrayList<>(); - - if(strs==null || strs.length==0) return result; - Map> map= new HashMap<>(); - - for(String s: strs){ - // int[] cache= new int[26]; - // for(char ch: s.toCharArray()){ - // cache[ch-'a']++; - // } - // String hash=Arrays.toString(cache); - char[] te=s.toCharArray(); - Arrays.sort(te); - String hash=new String(te); - - List list= map.getOrDefault(hash, new LinkedList<>()); - list.add(s); - map.put(hash,list); - } - - return new ArrayList(map.values()); - } -} \ No newline at end of file diff --git a/src/practiceproblems/HappyNumber.java b/src/practiceproblems/HappyNumber.java deleted file mode 100644 index 8f66d07..0000000 --- a/src/practiceproblems/HappyNumber.java +++ /dev/null @@ -1,57 +0,0 @@ -package practiceproblems; - -import java.util.HashSet; -import java.util.Set; - -/** - * https://leetcode.com/problems/happy-number/ - */ -class HappyNumber { - public boolean isHappy(int n) { - - Set visited = new HashSet<>(); - int sum = String.valueOf(n).chars().map(Character::getNumericValue).map(val -> val * val).sum() == 1 ? 1 : n; - while (true) { - if (sum == 1) { - return true; - } - sum = String.valueOf(sum).chars().map(Character::getNumericValue).map(val -> val * val).sum(); - if (visited.contains(sum)) { - return false; - } - - visited.add(sum); - } - } - - public int next(int n) - { - int res=0; - while (n>0) - { - int t = n % 10; - res += t*t; - n/=10; - } - return res; - } - - public boolean isHappyOpt(int n) - { - int i1=n, i2=next(n); - - while ( i2 != i1) - { - System.out.println("i1: "+ i1+" i2: "+ i2); - i1 = next(i1); - i2 = next(next(i2)); - } - - return i1==1; - } - - public static void main(String[] args) { - HappyNumber hn = new HappyNumber(); - System.out.println(hn.isHappyOpt(19)); - } -} \ No newline at end of file diff --git a/src/practiceproblems/HitCounter.java b/src/practiceproblems/HitCounter.java deleted file mode 100644 index 81440fb..0000000 --- a/src/practiceproblems/HitCounter.java +++ /dev/null @@ -1,31 +0,0 @@ -package practiceproblems; - -import java.util.ArrayDeque; - -public class HitCounter { - ArrayDeque trac; - /** Initialize your data structure here. */ - private final int FIVE_MINUTES = 300; - public HitCounter() { - trac = new ArrayDeque(); - } - - /** - * Record a hit. - @param timestamp - The current timestamp (in seconds granularity). - */ - public void hit(int timestamp) { - trac.addLast(timestamp); - } - - /** - * Return the number of hits in the past 5 minutes. - @param timestamp - The current timestamp (in seconds granularity). - */ - public int getHits(int timestamp) { - while(trac.size() > 0 && ( int) trac.getFirst() + FIVE_MINUTES <= timestamp) { - trac.removeFirst(); - } return trac.size(); - } - -} \ No newline at end of file diff --git a/src/practiceproblems/HouseRobber.java b/src/practiceproblems/HouseRobber.java deleted file mode 100644 index eff9b8d..0000000 --- a/src/practiceproblems/HouseRobber.java +++ /dev/null @@ -1,46 +0,0 @@ -package practiceproblems; - -/** - * https://leetcode.com/problems/house-robber/ - */ -public class HouseRobber { - - public int rob(int[] nums) { - if (nums.length == 0) { - return 0; - } - int incl = nums[0]; - int excl = 0; - for (int i = 1; i < nums.length; i++) { - int temp = incl; - incl = Math.max(incl, excl + nums[i]); - excl = temp; - } - return incl; - } - - public int robCircular(int[] nums) { - - if(nums.length==0) return 0; - if(nums.length==1) return nums[0]; - return Math.max(helperFn(nums,0,nums.length-2), helperFn(nums,1,nums.length-1)); - - } - - public int helperFn(int[] nums, int start, int end){ - int pre=0; int cur=0; - for(int i=start;i<=end;i++){ - int temp=Math.max(pre+nums[i],cur); - pre=cur; - cur=temp; - - } - return cur; - } - - public static void main(String[] args) { - int[] arr = { 2, 7, 9, 3, 1 }; - HouseRobber houseRobber = new HouseRobber(); - System.out.println(houseRobber.rob(arr)); - } -} diff --git a/src/practiceproblems/IPOMaxProfit.java b/src/practiceproblems/IPOMaxProfit.java deleted file mode 100644 index 8d0b08a..0000000 --- a/src/practiceproblems/IPOMaxProfit.java +++ /dev/null @@ -1,46 +0,0 @@ -package practiceproblems; - - - -import java.util.PriorityQueue; -//https://leetcode.com/problems/ipo/ - -// Input: distinctProjToFind=2, capital=0, Profits=[1,2,3], Capital=[0,1,1]. -// Output: 4 - -// Explanation: Since your initial capital is 0, you can only start the project indexed 0. -// After finishing it you will obtain profit 1 and your capital becomes 1. -// With capital 1, you can either start the project indexed 1 or the project indexed 2. -// Since you can choose at most 2 projects, you need to finish the project indexed 2 to get the maximum capital. -// Therefore, output the final maximized capital, which is 0 + 1 + 3 = 4. -public class IPOMaxProfit { - - // Create (capital, profit) pairs and put them into PriorityQueue pqCap. - // This PriorityQueue sort by capital increasingly. - // Keep polling pairs from pqCap until the project out of current capital capability. Put them into - // PriorityQueue pqPro which sort by profit decreasingly. - // Poll one from pqPro, it's guaranteed to be the project with max profit and within current capital capability. - //Add the profit to capital W. - //Repeat step 2 and 3 till finish k steps or no suitable project (pqPro.isEmpty()). - public int findMaximizedCapital(int steps, int initialCapital, int[] Profits, int[] Capital) { - - PriorityQueue minQueue= new PriorityQueue<>((a, b)->Integer.compare(a[0],b[0])); - PriorityQueue maxQueue= new PriorityQueue<>((a,b)->Integer.compare(b[1],a[1])); - - for(int i=0;i dirs = new HashMap < > (); - HashMap < String, String > files = new HashMap < > (); - } - Dir root; - public InMemeoryFIleSystem() { - root = new Dir(); - } - public List < String > ls(String path) { - Dir t = root; - List < String > files = new ArrayList < > (); - if (!path.equals("/")) { - String[] d = path.split("/"); - for (int i = 1; i < d.length - 1; i++) { - t = t.dirs.get(d[i]); - } - if (t.files.containsKey(d[d.length - 1])) { - files.add(d[d.length - 1]); - return files; - } else { - t = t.dirs.get(d[d.length - 1]); - } - } - files.addAll(new ArrayList < > (t.dirs.keySet())); - files.addAll(new ArrayList < > (t.files.keySet())); - Collections.sort(files); - return files; - } - - public void mkdir(String path) { - Dir t = root; - String[] d = path.split("/"); - for (int i = 1; i < d.length; i++) { - if (!t.dirs.containsKey(d[i])) - t.dirs.put(d[i], new Dir()); - t = t.dirs.get(d[i]); - } - } - - public void addContentToFile(String filePath, String content) { - Dir t = root; - String[] d = filePath.split("/"); - for (int i = 1; i < d.length - 1; i++) { - t = t.dirs.get(d[i]); - } - t.files.put(d[d.length - 1], t.files.getOrDefault(d[d.length - 1], "") + content); - } - - public String readContentFromFile(String filePath) { - Dir t = root; - String[] d = filePath.split("/"); - for (int i = 1; i < d.length - 1; i++) { - t = t.dirs.get(d[i]); - } - return t.files.get(d[d.length - 1]); - } -} - -class FileSystem1 { - class File { - boolean isfile = false; - HashMap < String, File > files = new HashMap < > (); - String content = ""; - } - File root; - public void FileSystem() { - root = new File(); - } - - public List < String > ls(String path) { - File t = root; - List< String > files = new ArrayList< >(); - if (!path.equals("/")) { - String[] d = path.split("/"); - for (int i = 1; i < d.length; i++) { - t = t.files.get(d[i]); - } - if (t.isfile) { - files.add(d[d.length - 1]); - return files; - } - } - List < String > res_files = new ArrayList < > (t.files.keySet()); - Collections.sort(res_files); - return res_files; - } - - public void mkdir(String path) { - File t = root; - String[] d = path.split("/"); - for (int i = 1; i < d.length; i++) { - if (!t.files.containsKey(d[i])) - t.files.put(d[i], new File()); - t = t.files.get(d[i]); - } - } - - public void addContentToFile(String filePath, String content) { - File t = root; - String[] d = filePath.split("/"); - for (int i = 1; i < d.length - 1; i++) { - t = t.files.get(d[i]); - } - if (!t.files.containsKey(d[d.length - 1])) - t.files.put(d[d.length - 1], new File()); - t = t.files.get(d[d.length - 1]); - t.isfile = true; - t.content = t.content + content; - } - - public String readContentFromFile(String filePath) { - File t = root; - String[] d = filePath.split("/"); - for (int i = 1; i < d.length - 1; i++) { - t = t.files.get(d[i]); - } - return t.files.get(d[d.length - 1]).content; - } -} - -/** - * Your FileSystem object will be instantiated and called as such: - * FileSystem obj = new FileSystem(); - * List param_1 = obj.ls(path); - * obj.mkdir(path); - * obj.addContentToFile(filePath,content); - * String param_4 = obj.readContentFromFile(filePath); - */ \ No newline at end of file diff --git a/src/practiceproblems/InorderSuccessorPredecessor.java b/src/practiceproblems/InorderSuccessorPredecessor.java deleted file mode 100644 index 243e131..0000000 --- a/src/practiceproblems/InorderSuccessorPredecessor.java +++ /dev/null @@ -1,105 +0,0 @@ -package practiceproblems; - -/** - * https://algorithms.tutorialhorizon.com/inorder-predecessor-and-successor-in-binary-search-tree/ - */ -public class InorderSuccessorPredecessor { - static int successor, predecessor; - - public void successorPredecessor(TNode root, int val) { - if (root == null) return; - - if (root.data > val) { - // we make the root as successor because we might have a - // situation when value matches with the root, it wont have - // right subtree to find the successor, in that case we need - // parent to be the successor - successor = root.data; - successorPredecessor(root.left, val); - } else if (root.data < val) { - // we make the root as predecessor because we might have a - // situation when value matches with the root, it wont have - // left subtree to find the predecessor, in that case we need - // parent to be the predecessor. - predecessor = root.data; - successorPredecessor(root.right, val); - } - } - - public static void main(String args[]) { - TNode root = new TNode(25); - root.left = new TNode(15); - root.right = new TNode(40); - root.left.left = new TNode(10); - root.left.left.left = new TNode(5); - root.left.right = new TNode(18); - root.right.left = new TNode(35); - root.right.right = new TNode(45); - root.left.right.left = new TNode(19); - root.left.right.right = new TNode(20); - InorderSuccessorPredecessor i = new InorderSuccessorPredecessor(); - - i.successorPredecessor(root, 20); - - System.out.println("Inorder Successor of 20 is : " + successor + " and predecessor is : " + predecessor); - - } - - TreeNode result=null; - public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { - helperFn(root,p); - return result; - } - - public void helperFn(TreeNode root, TreeNode p){ - if(root==null) return; - - if(root.val>p.val){ - result=root; - helperFn(root.left,p); - }else{ - helperFn(root.right,p); - } - - } - private TreeNode findPredecessor(TreeNode root, TreeNode node) { - TreeNode pre = null; - TreeNode cur = root; - while (cur != null) { - if (cur.val < node.val) { - pre = cur; - cur = cur.right; - } else { - cur = cur.left; - } - } - return pre; - } - private TreeNode findSuccessor(TreeNode root, TreeNode node) { - TreeNode succ = null; - TreeNode cur = root; - while (cur != null) { - if (cur.val > node.val) { - succ = cur; - cur = cur.left; - } else { - cur = cur.right; - } - } - return succ; - } -} - - - - class TNode { - int data; - TNode left; - TNode right; - - public TNode(int data) { - this.data = data; - left = null; - right = null; - } -} \ No newline at end of file diff --git a/src/practiceproblems/InsertIntervals.java b/src/practiceproblems/InsertIntervals.java deleted file mode 100644 index 2f78c11..0000000 --- a/src/practiceproblems/InsertIntervals.java +++ /dev/null @@ -1,36 +0,0 @@ -package practiceproblems; - -import java.util.ArrayList; -import java.util.List; - -/** - * Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). - - You may assume that the intervals were initially sorted according to their start times. - Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] - Output: [[1,2],[3,10],[12,16]] - Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10]. - */ -public class InsertIntervals{ - public int[][] insert(int[][] intervals, int[] newInterval) { - List result= new ArrayList<>(); - int i=0; int n= intervals.length; - - while(i - * Insertion sort iterates, - * consuming one input element each repetition, and growing a sorted output list. - * At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. - * It repeats until no input elements remain. - */ -public class InsertionSortList { - public ListNode insertionSortList(ListNode head) { - if (head == null) { - return head; - } - - ListNode helper = new ListNode(0); //new starter of the sorted list - ListNode cur = head; //the node will be inserted - ListNode pre = helper; //insert node between pre and pre.next - ListNode next; //the next node will be inserted - //not the end of input list - while (cur != null) { - next = cur.next; - //find the right place to insert - while (pre.next != null && pre.next.val < cur.val) { - pre = pre.next; - } - //insert between pre and pre.next - cur.next = pre.next; - pre.next = cur; - pre = helper; - cur = next; - } - - return helper.next; - } -} \ No newline at end of file diff --git a/src/practiceproblems/IsEditOneDistanceAway.java b/src/practiceproblems/IsEditOneDistanceAway.java deleted file mode 100644 index f85ecce..0000000 --- a/src/practiceproblems/IsEditOneDistanceAway.java +++ /dev/null @@ -1,63 +0,0 @@ -package practiceproblems; - -/** - * Given two strings first and second, determine if they are both one edit distance apart. - * One edit distance means doing one of these operation: - * - * insert one character in any position of S - * delete one character in S - * change one character in S to other character - * - * Input: s = "ab", t = "ab" - * Output: false - * Explanation: - * s=t ,so they aren't one edit distance apart - * - * Input: s = "aDb", t = "adb" - * Output: true - */ -public class IsEditOneDistanceAway { - static boolean isOneEdit(String first, String second) { - // if the input string are same - if (first.equals(second)) - return false; - - int len1 = first.length(); - int len2 = second.length(); - // If the length difference of the stings is more than 1, return false. - if ((len1 - len2) > 1 || (len2 - len1) > 1) { - return false; - } - int i = 0, j = 0; - int diff = 0; - while (i < len1 && j < len2) { - char f = first.charAt(i); - char s = second.charAt(j); - if (f != s) { - diff++; - // delete a character - if (len1 > len2) - i++; - // add a character - if (len2 > len1) - j++; - // replace a character - if (len1 == len2) - i++; - j++; - } else { - i++; - j++; - } - if (diff > 1) { - return false; - } - } - // If the length of the string is not same. ex. "abc" and "abde" are not one - // edit distance. - if (diff == 1 && len1 != len2 && (i != len1 || j != len2)) { - return false; - } - return true; - } -} \ No newline at end of file diff --git a/src/practiceproblems/Islands.java b/src/practiceproblems/Islands.java deleted file mode 100644 index 05ff0f1..0000000 --- a/src/practiceproblems/Islands.java +++ /dev/null @@ -1,44 +0,0 @@ -package practiceproblems; - -/** - * https://www.geeksforgeeks.org/find-number-of-islands/ - */ -class Islands { - - private int n; - private int m; - - public int numIslands(int[][] grid) { - int count = 0; - n = grid.length; - if (n == 0) { - return 0; - } - m = grid[0].length; - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) - if (grid[i][j] == 1) { - DFSMarking(grid, i, j); - ++count; - } - } - return count; - } - - private void DFSMarking(int[][] grid, int i, int j) { - if (i < 0 || j < 0 || i >= n || j >= m || grid[i][j] != 1) { - return; - } - grid[i][j] = 0; - DFSMarking(grid, i + 1, j); - DFSMarking(grid, i - 1, j); - DFSMarking(grid, i, j + 1); - DFSMarking(grid, i, j - 1); - } - - public static void main(String[] args) { - int M[][] = new int[][] { { 1, 1, 1, 1, 0 }, { 1, 1, 0, 1, 0 }, { 1, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0 } }; - Islands I = new Islands(); - System.out.println("Number of islands is: " + I.numIslands(M)); - } -} diff --git a/src/practiceproblems/IsomorphicString.java b/src/practiceproblems/IsomorphicString.java deleted file mode 100644 index cc08bae..0000000 --- a/src/practiceproblems/IsomorphicString.java +++ /dev/null @@ -1,31 +0,0 @@ -package practiceproblems; - -import java.util.Arrays; - -/** - * https://www.geeksforgeeks.org/check-if-two-given-strings-are-isomorphic-to-each-other/ - */ -class IsomorphicString { - static boolean isIsomorphic(String s, String t) { - char[] m1 = new char[256]; - char[] m2 = new char[256]; - int n = s.length(); - for (int i = 0; i < n; ++i) { - // it checks the count of the character in the array ; - // for 'g' -> a[103] is 2 and 'd' -> a[100] is 2 - // if both are same both gets incremented together else return false - if (m1[s.charAt(i)] != m2[t.charAt(i)]) { - return false; - } - m1[s.charAt(i)] = (char) (i + 1); - m2[t.charAt(i)] = (char) (i + 1); - } - System.out.println(Arrays.toString(m1)); - System.out.println(Arrays.toString(m2)); - return true; - } - - public static void main(String[] args) { - System.out.println(isIsomorphic("egg", "add")); - } -}; \ No newline at end of file diff --git a/src/practiceproblems/JumpsToReachEnd.java b/src/practiceproblems/JumpsToReachEnd.java deleted file mode 100644 index 609b96b..0000000 --- a/src/practiceproblems/JumpsToReachEnd.java +++ /dev/null @@ -1,96 +0,0 @@ -package practiceproblems; - -import java.util.*; - -public class JumpsToReachEnd { - - /** - * Given an array of non-negative integers nums, - * you are initially positioned at the first index of the array. - * Each element in the array represents your maximum jump length at that position. - * - * Determine if you are able to reach the last index - * Input: nums = [2,3,1,1,4] - * Output: true - * Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index. - * - * Input: nums = [3,2,1,0,4] - * Output: false - * Explanation: You will always arrive at index 3 no matter what. - * Its maximum jump length is 0, which makes it impossible to reach the last index. - */ - public static boolean canReachEnd(Integer[] nums) { - - int curMax = nums[0]; - for (int i = 1; i < nums.length; i++) { - if (curMax < i) return false; //means we are not able to reach position i - curMax = Math.max(curMax, i + nums[i]); - } - return true; - } - - - /** - *Given an array of non-negative integers arr, - * you are initially positioned at start index of the array. - * When you are at index i, you can jump to i + arr[i] or i - arr[i], - * check if you can reach to any index with value 0. - * Notice that you can not jump outside of the array at any time. - * - * Input: arr = [4,2,3,0,3,1,2], start = 5 - * Output: true - * Explanation: - * All possible ways to reach at index 3 with value 0 are: - * index 5 -> index 4 -> index 1 -> index 3 - * index 5 -> index 6 -> index 4 -> index 1 -> index 3 - * - * Input: arr = [4,2,3,0,3,1,2], start = 0 - * Output: true - * Explanation: - * One possible way to reach at index 3 with value 0 is: - * index 0 -> index 4 -> index 1 -> index 3 - */ - public boolean canReach(int[] arr, int start) { - // visited check included - if(start>=arr.length || start<0 || arr[start]>arr.length || arr[start]<0) return false; - if(arr[start]==0 ) return true; - arr[start]=-arr[start]; // visited marking - return canReach(arr, start+arr[start]) || canReach(arr, start-arr[start]); - - } - - - public int minJump(int[] nums) { - if(nums==null || nums.length==0) return 0; - int currentMax=0; - int currentEnd=0; - int jumps=0; - - for(int i=0;i=nums.length-1){ // if the current pick solves the issue - jumps++; - break; - } - //Once the current point reaches curEnd, - //then trigger another jump, and set the new curEnd with curFarthest, - //then keep the above steps, as the following - - //This is an implicit bfs solution. i == curEnd means you visited all the items on the current level. - // Incrementing jumps++ is like incrementing the level you are on. - // And curEnd = curFarthest is like getting the queue size (level size) for the next level you are traversing. - if(currentEnd==i){ // when the current pick of ladder reached last step - jumps++; - currentEnd=currentMax; - } - } - return jumps; - } - - public static void main(String[] args) { - - List list= Arrays.asList(3,3,1,0, 2,0,1); - System.out.println(canReachEnd(list.toArray(new Integer[list.size()]))); - } -} \ No newline at end of file diff --git a/src/practiceproblems/KClosestElements.java b/src/practiceproblems/KClosestElements.java deleted file mode 100644 index 629be41..0000000 --- a/src/practiceproblems/KClosestElements.java +++ /dev/null @@ -1,66 +0,0 @@ -package practiceproblems; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.PriorityQueue; - -/** - * Given a sorted array arr, two integers k and x, find the k closest elements to x in the array. - * Input: arr = [1,2,3,4,5], k = 4, x = 3 -Output: [1,2,3,4] - */ -public class KClosestElements { - public List findClosestElements(int[] arr, int k, int x) { - // since this is sorted array we are making use of binary search to get index of X and - // fix the range between index-K to index+K and doing normal PQ solution - int index= binarySearch(arr,x); - //if(index==-1) return Collections.emptyList(); - - int low= Math.max(0,index-k); - int high= Math.min(index+k,arr.length-1); - - PriorityQueue queue= new PriorityQueue<>((a, b)->Integer.compare(a.key,b.key)); - - for(int i=low;i<=high;i++){ - // taking abs value because question is askin closest in both signs - queue.offer(new Entry(Math.abs(arr[i]-x),i)); - } - List result= new ArrayList<>(); - int i=0; - while(i0){ - start--; - } - return start; - } -} - -class Entry{ - int key; - int value; - public Entry(int key, int value){ - this.key=key; - this.value=value; - } -} \ No newline at end of file diff --git a/src/practiceproblems/KthClosestOrigin.java b/src/practiceproblems/KthClosestOrigin.java deleted file mode 100644 index ce4bf58..0000000 --- a/src/practiceproblems/KthClosestOrigin.java +++ /dev/null @@ -1,74 +0,0 @@ -package practiceproblems; - -import java.util.Arrays; -import java.util.Random; - -/** - * https://leetcode.com/problems/k-closest-points-to-origin/solution/ - */ -class KthClosestOrigin { - int[][] points = new int[3][2]; - - // quick select - public int[][] kClosest(int[][] points, int K) { - this.points= points; - sort(0, points.length - 1, K); - return Arrays.copyOfRange(points, 0, K); - } - - public void sort(int i, int j, int K) { - if (i >= j) { - return; - } - int k = new Random().nextInt(j - i + 1) + i; - swap(i, k); - - int mid = partition(i, j); - int leftLength = mid - i + 1; - if (K < leftLength) { - sort(i, mid - 1, K); - } else if (K > leftLength) { - sort(mid + 1, j, K - leftLength); - } - } - - public int partition(int i, int j) { - int pivot = dist(i); - swap(i, j); - int iLow = i; - for (int i1 = i; i1 < j; i1++) { - if (dist(i1) <= pivot) { - swap(i1, iLow); - iLow++; - } - } - swap(iLow, j); - return iLow; - } - - public int dist(int i) { - return points[i][0] * points[i][0] + points[i][1] * points[i][1]; - } - - public void swap(int i, int j) { - int t0 = points[i][0], t1 = points[i][1]; - points[i][0] = points[j][0]; - points[i][1] = points[j][1]; - points[j][0] = t0; - points[j][1] = t1; - } - public static void main(String[] args) { -// KthClosestOrigin kth = new KthClosestOrigin(); -// points[0][0] = 3; -// points[0][1] = 3; -// -// points[1][0] = 5; -// points[1][1] = -1; -// -// points[2][0] = 2; -// points[2][1] = 4; -// -// // System.out.println(Arrays.deepToString(kth.kClosestOLogN(points, 1))); -// System.out.println(Arrays.deepToString(kth.kClosest(points, 2))); - } -} diff --git a/src/practiceproblems/KthSmallestMatrix.java b/src/practiceproblems/KthSmallestMatrix.java deleted file mode 100644 index b0a21a6..0000000 --- a/src/practiceproblems/KthSmallestMatrix.java +++ /dev/null @@ -1,51 +0,0 @@ -package practiceproblems; - -import java.util.PriorityQueue; - -/*https://www.geeksforgeeks.org/kth-smallest-element-in-a-row-wise-and-column-wise-sorted-2d-array-set-1/*/ -public class KthSmallestMatrix { - public static int kthSmallest(int[][] matrix, int k) { - int n = matrix.length; - PriorityQueue pq = new PriorityQueue<>(); - // add first row elements - for (int j = 0; j <= n - 1; j++) - pq.offer(new Points(0, j, matrix[0][j])); - for (int i = 0; i < k - 1; i++) { - Points t = pq.poll(); - System.out.println(t.x); - if (t.x == n - 1) { - continue; - } - pq.offer(new Points(t.x + 1, t.y, matrix[t.x + 1][t.y])); - } - return pq.poll().val; - } - - public static void main(String[] args) { - int[][] matrix = { { 1, 2, 9 }, { 3, 11, 13 }, { 4, 13, 15 } }; - int k = 4; - - System.out.println(kthSmallest(matrix, k)); - } -} - -class Points implements Comparable { - int x; - int y; - int val; - - public Points(int x, int y, int val) { - this.x = x; - this.y = y; - this.val = val; - } - - @Override - public int compareTo(Points that) { - return this.val - that.val; - } - - public String toString() { - return this.val + ""; - } -} \ No newline at end of file diff --git a/src/practiceproblems/LRUCache.java b/src/practiceproblems/LRUCache.java deleted file mode 100644 index a96554b..0000000 --- a/src/practiceproblems/LRUCache.java +++ /dev/null @@ -1,123 +0,0 @@ -package practiceproblems; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; - -class LRUCache { - - class DLLNode{ - DLLNode prev; - DLLNode next; - int val; - int key; - public DLLNode(int key, int val){ - this.val=val; - this.key=key; - } - } - Map map; - DLLNode head; - DLLNode tail; - int capacity=0; - public LRUCache(int capacity) { - map= new HashMap<>(); - head= new DLLNode(-1,-1); - tail= new DLLNode(-1,-1); - head.next=tail; - tail.prev=head; - this.capacity=capacity; - } - - public int get(int key) { - if(!map.containsKey(key)) return -1; - DLLNode node= map.get(key); - update(node); - return node.val; - } - - public void put(int key, int value) { - if(map.containsKey(key)){ - DLLNode node= map.get(key); - node.val=value; - update(node); - }else{ - if(map.size()>=capacity){ - removeTail(); - } - DLLNode newNode= new DLLNode(key,value); - map.put(key, newNode); - - updateHead(newNode); - } - } - - public void removeTail(){ - DLLNode tailNode=tail.prev; - remove(tailNode); - map.remove(tailNode.key); - } - - public void updateHead(DLLNode node){ - node.prev = head; - node.next = head.next; - head.next.prev = node; - head.next = node; - } - - public void remove(DLLNode node){ - DLLNode next= node.next; - DLLNode prev= node.prev; - prev.next=next; - next.prev=prev; - } - public void update(DLLNode node){ - remove(node); - updateHead(node); - } - } - - - class LRUCache1 { - LinkedHashMap isbnToPrice; - - public LRUCache1(final int capacity) { - this.isbnToPrice - = new LinkedHashMap(capacity, 1f, true) { - @Override - protected boolean removeEldestEntry(Map.Entry e) { - return this.size() > capacity; - } - }; - } - - public Integer lookup(Integer key) { - if (!isbnToPrice.containsKey(key)) { - return null; - } - return isbnToPrice.get(key); - } - - public Integer insert(Integer key, Integer value) { - // We add the value for key only if key is not present - we don’t update - // existing values. - Integer currentValue = isbnToPrice.get(key); - if (!isbnToPrice.containsKey(key)) { - isbnToPrice.put(key, value); - return currentValue; - } else { - return null; - } - } - - public Integer erase(Object key) { - return isbnToPrice.remove(key); - } - - } - /** - * Your LRUCache object will be instantiated and called as such: - * LRUCache obj = new LRUCache(capacity); - * int param_1 = obj.get(key); - * obj.put(key,value); - */ \ No newline at end of file diff --git a/src/practiceproblems/LargestSubArrayWithZeroesAndOnes.java b/src/practiceproblems/LargestSubArrayWithZeroesAndOnes.java deleted file mode 100644 index 5ceeb3b..0000000 --- a/src/practiceproblems/LargestSubArrayWithZeroesAndOnes.java +++ /dev/null @@ -1,68 +0,0 @@ -package practiceproblems; - -import java.util.HashMap; - -/*https://www.geeksforgeeks.org/largest-subarray-with-equal-number-of-0s-and-1s/ - Given an array containing only 0s and 1s, find the largest subarray which contains equal no of 0s and 1s. - Expected time complexity is O(n). -*/ -class LargestSubArrayWithZeroesAndOnes { - /** - * The concept of taking cumulative sum, taking 0’s as -1 will help us in optimising the approach. - * While taking the cumulative sum, there are two cases when there can be a sub-array with equal number of 0’s and 1’s - * When cumulative sum=0, which signifies that sub-array from index (0) till present index has equal number of 0’s and 1’s. - * - * When we encounter a cumulative sum value which we have already encountered before, - * which means that sub-array from the previous index+1 till the present index has equal number of 0’s and 1’s as they give a cumulative sum of 0 . - * @param arr - * @param n - * @return - */ - int maxLen(int arr[], int n) { - - HashMap map = new HashMap<>(); - - int sum = 0; - int maxLength = 0; - int endingIndex = -1; - - for (int i = 0; i < n; i++) { - arr[i] = (arr[i] == 0) ? -1 : 1; - } - - for (int i = 0; i < n; i++) { - sum += arr[i]; - - if (sum == 0) { // To handle sum=0 at last index - maxLength = i + 1; - endingIndex = i; - } - // If this sum is seen before, - // then update max_len if required - if (map.containsKey(sum)) { - if (maxLength < i - map.get(sum)) { - maxLength = i - map.get(sum); - endingIndex = i; - } - } else - map.put(sum, i); - } - - for (int i = 0; i < n; i++) { - arr[i] = (arr[i] == -1) ? 0 : 1; - } - - int start = endingIndex - maxLength + 1; - System.out.println(start + " to " + endingIndex); - - return maxLength; - } - - public static void main(String[] args) { - LargestSubArrayWithZeroesAndOnes sub = new LargestSubArrayWithZeroesAndOnes(); - int arr[] = {0, 0, 0, 1, 0, 1, 1}; - int n = arr.length; - - sub.maxLen(arr, n); - } -} \ No newline at end of file diff --git a/src/practiceproblems/LargestTimeFromDigits.java b/src/practiceproblems/LargestTimeFromDigits.java deleted file mode 100644 index 9767d04..0000000 --- a/src/practiceproblems/LargestTimeFromDigits.java +++ /dev/null @@ -1,39 +0,0 @@ -package practiceproblems; - -/** - * Given an array of 4 digits, return the largest 24 hour time that can be made. - -The smallest 24 hour time is 00:00, and the largest is 23:59. Starting from 00:00, a time is larger if more time has elapsed since midnight. - -Return the answer as a string of length 5. If no valid time can be made, return an empty string. - */ -public class LargestTimeFromDigits{ - public String largestTimeFromDigits(int[] A) { - if(A==null || A.length==0) return ""; - String result=""; - // because A.length == 4 - for(int i=0;i<4;i++){ - for(int j=0;j<4;j++){ - for(int k=0;k<4;k++){ - //We cannot take a number twice. i, j, k and (6-i-j-k) denoting the indices of 4 numbers should be distinct. - if(i==j || j==k|| k==i) continue; - String hrs= A[i]+""+A[j]; - //We are trying out all possible ordering, - //indices of 4 numbers are 0, 1, 2, and 3. - //sum of indices = 0 + 1 + 2 + 3= 6 - //i, j and k denote 3 indices. - //So, if we know 3 numbers, - //the 4th number will be the remaining index, i.e., 6-i-j-k - - String mins= A[k]+""+A[6-i-j-k]; - - if(hrs.compareTo("24")<0 && mins.compareTo("59")<0 && result.compareTo(hrs+":"+mins)<0){ - result=hrs+":"+mins; - } - - } - } - } - return result; - } -} \ No newline at end of file diff --git a/src/practiceproblems/LongestIncreasingPathInMatrix.java b/src/practiceproblems/LongestIncreasingPathInMatrix.java deleted file mode 100644 index 83e49e3..0000000 --- a/src/practiceproblems/LongestIncreasingPathInMatrix.java +++ /dev/null @@ -1,64 +0,0 @@ -package practiceproblems; - -/** - * https://leetcode.com/problems/longest-increasing-path-in-a-matrix - * - * Do DFS from every cell - * Compare every 4 direction and skip cells that are out of boundary or smaller - * Get matrix max from every cell's max - * Use matrix[x][y] <= matrix[i][j] so we don't need a visited[m][n] array - * The key is to cache the distance because it's highly possible to revisit a cell - * - * DFS + Memoization - * - * Traverse all points in matrix, use every point as starting point to do dfs traversal. DFS function returns max increasing - * path after comparing four max return distance from four directions. - * - * */ -public class LongestIncreasingPathInMatrix { - - int[][] dirs= new int[][] {{1,0},{-1,0},{0,1},{0,-1}}; - public int longestIncreasingPath(int[][] matrix) { - if(matrix.length == 0) return 0; - // i+1,j, i-1,j i,j+1 i,j-1 - Integer[][] cache= new Integer[matrix.length][matrix[0].length]; - - int result=0; - for(int i=0;i=matrix.length || j<0 || j>=matrix[0].length|| data>=matrix[i][j]) return 0; - - - - if(cache[i][j]!=null) return cache[i][j]; - - // initialize max distance as 1 since the path includes starting point itself - int max=1; - - for(int[] dir: dirs){ - - int x=i+dir[0]; - int y=j+dir[1]; - // if next point is a valid point, add curLen by 1 and continue DFS traversal - int count=1+dfsUtil(matrix,x,y,cache, matrix[i][j]); - max=Math.max(count,max); - } - // update max increasing path value starting from current point in cache - cache[i][j]=max; - - return cache[i][j]; - - } - - public boolean isValid(int[][] matrix, int i, int j, int data){ - return i >= 0 && i < matrix.length && j >= 0 && j < matrix[0].length; - } -} diff --git a/src/practiceproblems/MaxHistogram.java b/src/practiceproblems/MaxHistogram.java deleted file mode 100644 index 841008b..0000000 --- a/src/practiceproblems/MaxHistogram.java +++ /dev/null @@ -1,68 +0,0 @@ -package practiceproblems; - -import java.util.Arrays; - -/** - * https://leetcode.com/problems/largest-rectangle-in-histogram/ - */ - -public class MaxHistogram { - - //For any bar i the maximum rectangle is of width r - l - 1 - // where r - is the last coordinate of the bar to the right with height h[r] >= h[i] and - // l - is the last coordinate of the bar to the left which height h[l] >= h[i] - //So if for any i coordinate we know his utmost higher (or of the same height) neighbors to the right and to the left, - // we can easily find the largest rectangle: maxArea = Math.max(maxArea, height[i] * (lessFromRight[i] - lessFromLeft[i] - 1)); - - //The main trick is how to effectively calculate lessFromRight and lessFromLeft arrays. - // The trivial solution is to use O(n^2) solution and for each i element - // first find his left/right neighbour in the second inner loop just iterating back or forward: - public static int largestRectangleArea(int[] height) { - if (height == null || height.length == 0) { - return 0; - } - int[] lessFromLeft = new int[height.length]; // idx of the first bar the left that is lower than current - int[] lessFromRight = new int[height.length]; // idx of the first bar the right that is lower than current - lessFromRight[height.length - 1] = height.length; - lessFromLeft[0] = -1; - - // for example in order to lessFromLeft[i]; if height[i - 1] < height[i] then left[i] = i - 1; - // other wise we do not need to start scan from i - 1; we can start the scan from lessFromLeft[i - 1], - // because since lessFromLeft[i - 1] is the first position to the left of i - 1 that have height less than height[i - 1], - // and we know height[i - 1] >= height[i]; so lessFromLeft[i] must be at the left or at lessFromLeft[i - 1]; similar for the right array; - for (int i = 1; i < height.length; i++) { - int p = i - 1; - - while (p >= 0 && height[p] >= height[i]) { - p = lessFromLeft[p]; - } - lessFromLeft[i] = p; - } - - for (int i = height.length - 2; i >= 0; i--) { - int p = i + 1; - - while (p < height.length && height[p] >= height[i]) { - p = lessFromRight[p]; - } - lessFromRight[i] = p; - } - // after both the loop ends, this is the output of left and right - // input [2, 1, 5, 6, 2, 3] - // 0, 1, ,2 3, 4, 5 - // left [-1, -1, 1, 2, 1, 4] => indexes of elements - // right [1, 6, 4, 4, 6, 6] - int maxArea = 0; - for (int i = 0; i < height.length; i++) { - maxArea = Math.max(maxArea, height[i] * (lessFromRight[i] - lessFromLeft[i] - 1)); - } - System.out.println(Arrays.toString(lessFromLeft)); - System.out.println(Arrays.toString(lessFromRight)); - return maxArea; - } - - public static void main(String[] args) { - int[] arr = new int[] { 2, 1, 5, 6, 2, 3 }; - System.out.println(largestRectangleArea(arr)); - } -} \ No newline at end of file diff --git a/src/practiceproblems/MaxProductString.java b/src/practiceproblems/MaxProductString.java deleted file mode 100644 index 5474c06..0000000 --- a/src/practiceproblems/MaxProductString.java +++ /dev/null @@ -1,57 +0,0 @@ -package practiceproblems; - -/** - * Given a string array words, find the maximum value of length(word[i]) * length(word[j]) - * where the two words do not share common letters. - * You may assume that each word will contain only lower case letters - * Input: ["abcw","baz","foo","bar","xtfn","abcdef"] - * Output: 16 - * Explanation: The two words can be "abcw", "xtfn". - * - * Input: ["a","aa","aaa","aaaa"] - * Output: 0 - * Explanation: No such pair of words. - */ -public class MaxProductString { - public int maxProduct(String[] words) { - int[] checker = new int[words.length]; - int max = 0; - // populating the checker array with their respective numbers - for (int i = 0; i < checker.length; i++) { - int num = 0; - for (int j = 0; j < words[i].length(); j++) { - // we are making char index in bit to be set - // a 1->1 making first bit marked - // b 2->10 - // c 4->100 - // ab 3->11 // making first and secind marked - // ac 5->101 - // abc 7->111 - // az 33554433->10000000000000000000000001 - - num |= 1 << (words[i].charAt(j) - 'a'); - System.out.println(words[i].charAt(j)+"->"+num+ "->"+Integer.toBinaryString(num) ); - } - - checker[i] = num; - } - - for (int i = 0; i < words.length; i++) { - for (int j = i + 1; j < words.length; j++) { - // abcd efgd - // 11110000 -> abcd - // 00011110 -> efgd - // and-ing these two might say if even a single char is present in other - if ((checker[i] & checker[j]) == 0) //checking if the two strings have common character - max = Math.max(max, words[i].length() * words[j].length()); - } - } - System.out.println(max); - return max; - } - - - public static void main(String[] args) { - new MaxProductString().maxProduct(new String[]{"abcw", "baz", "foo", "bar", "xtfn", "abcdef"}); - } -} \ No newline at end of file diff --git a/src/practiceproblems/MaxWidthOfBinaryTree.java b/src/practiceproblems/MaxWidthOfBinaryTree.java deleted file mode 100644 index 53699eb..0000000 --- a/src/practiceproblems/MaxWidthOfBinaryTree.java +++ /dev/null @@ -1,61 +0,0 @@ -package practiceproblems; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.Map; -import java.util.Queue; - -/** - * Given a binary tree, write a function to get the maximum width of the given tree. - * The width of a tree is the maximum width among all levels. - * The binary tree has the same structure as a full binary tree, but some nodes are null - * - * Input: - - 1 - / \ - 3 2 - / \ - 5 9 - / \ - 6 7 -Output: 8 -The maximum width existing in the fourth level with the length 8 (6,null,null,null,null,null,null,7). - */ -public class MaxWidthOfBinaryTree { - - // Each time a node is traversed, the position of the node(as it is in a full binary tree) is stored in the HashMap. - //If the position of the parent node is 'n', then the left child is '2 * n' and the right child is '2 * n + 1'. - //The width of each level is the last node's position in this level subtracts the first node's position in this level plus 1. - public int widthOfBinaryTree(TreeNode root) { - if(root==null) return 0; - int maxWidth=0; - - Map map= new HashMap<>(); - Queue stack=new LinkedList(); - stack.offer(root); - map.put(root,1); // if we are assigning head as 0 then the fourmula is left=>2*n+1, right=> 2*n+2 - while(!stack.isEmpty()){ - int width= stack.size(); - int start=0; - int end=0; - for(int i=0;i subarraySort(final ArrayList A) { - - final ArrayList list = new ArrayList<>(); - int start = -1; - int end = -1; - - // from left - for (int i = 1; i < A.size(); ++i) { - if (A.get(i) < A.get(i - 1)) { - start = i - 1; - break; - } - } - - // fully sorted - if (start == -1) { - list.add(-1); - return list; - } - - // from right - for (int i = A.size() - 2; i >= 0; --i) { - if (A.get(i) > A.get(i + 1)) { - end = i + 1; - break; - } - } - // [1, 3, 2, 0, -1, 7, 10] - // the initial finding gives you 3 and -1 however the original sort array is - // [1, -1, 0, 2, 3, 7, 10], - //The problem here is that the smallest number of our subarray is ‘-1’ - // which dictates that we need to include more numbers from the beginning of the array - // We will have a similar problem - //if the maximum of the subarray is bigger than some elements at the end of the array - // find min and max in the range [start, end] - int min = A.get(start); - int max = A.get(start); - for (int i = start; i <= end; ++i) { - min = Math.min(min, A.get(i)); - max = Math.max(max, A.get(i)); - } - - for (int i = 0; i < start; ++i) { - if (A.get(i) > min) { - start = i; - break; - } - } - - for (int i = A.size() - 1; i >= end + 1; --i) { - if (A.get(i) < max) { - end = i; - break; - } - } - - list.add(start); - list.add(end); - - return list; - } - - public static void main(final String[] args) { - //1, 1, 10, 10, 15, 10, 15, 10,10, 15, 10, 15 - //(1, 3, 2, 4, 5); - //4, 15, 4, 4, 15, 18, 20 - //2, 6, 1, 8, 10, 9, 15 - final List result = subarraySort(new ArrayList<>(Arrays.asList(4, 15, 4, 4, 15, 18, 20))); - result.stream().forEach(System.out::println); - } -} diff --git a/src/practiceproblems/MedianOfKWindow.java b/src/practiceproblems/MedianOfKWindow.java deleted file mode 100644 index aaaa66d..0000000 --- a/src/practiceproblems/MedianOfKWindow.java +++ /dev/null @@ -1,49 +0,0 @@ -package practiceproblems; - -import java.util.Collections; -import java.util.PriorityQueue; - -public class MedianOfKWindow { - public double[] medianSlidingWindow(int[] nums, int k) { - MedianQueue medianHeap= new MedianQueue(); - - double[] result= new double[nums.length-k+1]; - - int resultIndex=0; - - for( int i=0;i minQueue= new PriorityQueue<>(); - PriorityQueue maxQueue= new PriorityQueue<>(Collections.reverseOrder()); - - public void offer(int x){ - maxQueue.offer(x); - minQueue.offer(maxQueue.poll()); - if(maxQueue.size() minQueue.size() ? maxQueue.peek() : ((long)maxQueue.peek() + minQueue.peek()) * 0.5; - } - public int size(){ - return minQueue.size() + maxQueue.size(); - } - - public boolean remove(int x){ - return minQueue.remove(x) || maxQueue.remove(x); - } - } -} \ No newline at end of file diff --git a/src/practiceproblems/MedianOfRunningIntegers.java b/src/practiceproblems/MedianOfRunningIntegers.java deleted file mode 100644 index 2a961d0..0000000 --- a/src/practiceproblems/MedianOfRunningIntegers.java +++ /dev/null @@ -1,45 +0,0 @@ -package practiceproblems; - -import java.util.Collections; -import java.util.PriorityQueue; - -/** - * https://leetcode.com/problems/find-median-from-data-stream/ - */ -public class MedianOfRunningIntegers { - - PriorityQueue min = new PriorityQueue<>(); - PriorityQueue max = new PriorityQueue<>(Collections.reverseOrder()); - - // 6,8,1,4,9,2,3,5 - // median is a middle element in sorted array - // in a sorted array if we choose a point the immediate left to that point is maxLeft (max of all left) - // the immediate right to that point is minRight (min of all right) - // to mimic that here the right(max) values are stored in min heap - // the left(min) values are stored in maxheap - public void addNum(int num) { - max.offer(num); - min.offer(max.poll()); - if (max.size() < min.size()) { - max.offer(min.poll()); - } - } - - public double findMedian() { - if (max.size() == min.size()) { - return (max.peek() + min.peek()) / 2.0; - } else { - return max.peek(); - } - } - - public static void main(String[] args) { - MedianOfRunningIntegers median = new MedianOfRunningIntegers(); - int A[] = { 5, 15, 1, 3, 2, 8, 7, 9, 10, 6, 11, 4 }; - for (int num : A) { - median.addNum(num); - System.out.println(median.findMedian()); - } - } - -} diff --git a/src/practiceproblems/MeetingRoomsII.java b/src/practiceproblems/MeetingRoomsII.java deleted file mode 100644 index 3bba853..0000000 --- a/src/practiceproblems/MeetingRoomsII.java +++ /dev/null @@ -1,63 +0,0 @@ -package practiceproblems; - -import java.util.*; - -/** - * https://www.lintcode.com/problem/meeting-rooms-ii/ - */ - -public class MeetingRoomsII { - /** - * @param intervals: an array of meeting time intervals - * - * @return: the minimum number of conference rooms required - */ - // [(0,30),(5,10),(15,20)] - public int minMeetingRooms(List intervals) { - if (intervals == null || intervals.size() == 0) { - return -1; - } - - Collections.sort(intervals, Comparator.comparingInt(a -> a.start)); - - PriorityQueue queue = new PriorityQueue<>(); - queue.offer(intervals.get(0).end); - for (int i = 1; i < intervals.size(); i++) { - Interval temp = intervals.get(i); - if (queue.peek() <= temp.start) { - queue.poll(); - } - queue.offer(temp.end); - } - - return queue.size(); - - } - - // Input: schedule = [[[1,2],[5,6]],[[1,3]],[[4,10]]] - // Output: [[3,4]] - - public List employeeFreeTime(List> schedule) { - PriorityQueue que = new PriorityQueue<>((a, b) -> a.start - b.start); - - for (List list : schedule) { - for (Interval i : list) { - que.add(i); - } - } - - List rt = new ArrayList<>(); - int max = -1; - while (!que.isEmpty()) { - Interval top = que.poll(); - if (max != -1 && top.start > max) { - rt.add(new Interval(max, top.start)); - } - max = Math.max(max, top.end); - } - - return rt; - } - - -} diff --git a/src/practiceproblems/MergeIntervalIntersection.java b/src/practiceproblems/MergeIntervalIntersection.java deleted file mode 100644 index 690469a..0000000 --- a/src/practiceproblems/MergeIntervalIntersection.java +++ /dev/null @@ -1,42 +0,0 @@ -package practiceproblems; - -import java.util.ArrayList; -import java.util.List; - -/** - * -Given two lists of closed intervals, each list of intervals is pairwise disjoint and in sorted order. -Return the intersection of these two interval lists. - -Input: A = [[0,2],[5,10],[13,23],[24,25]], B = [[1,5],[8,12],[15,24],[25,26]] -Output: [[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]] - */ -public class MergeIntervalIntersection { - - // inorder to find a overlapping part alone between two intervals - // we take - // start = max(a.start, b.start) - // end = min(a.end, b.end) - // That is, the highest start time and the lowest end time will be the overlapping interval. - public int[][] intervalIntersection(int[][] A, int[][] B) { - int i=0; - int j=0; - List result= new ArrayList<>(); - while(i=B[j][0] && A[i][0]<=B[j][1] || - B[j][0]>=A[i][0] && B[j][0]<=A[i][1]){ // this condition checks if there'a ovelapping - //A=>[0,2], B=> [1,5] - result.add(new int[]{Math.max(A[i][0],B[j][0]), Math.min(A[i][1],B[j][1])}); - } - // once added to result move the i or j based on lesser end time - if(A[i][1]= 0 && row < maxRow && col >= 0 && col < maxCol && grid[row][col] == 1; - } - - private void rotOranges(Queue queue, Pair p, int[][] grid) { - int[] xMoves = { 1, -1, 0, 0 }; - int[] yMoves = { 0, 0, 1, -1 }; - for (int k = 0; k < xMoves.length; k++) { - int x = p.x + xMoves[k]; - int y = p.y + yMoves[k]; - if (isValidFresh(x, y, grid)) { - grid[x][y] = 2; - queue.add(new Pair(x, y)); - } - } - } - - public int findMinTime(int[][] grid) { - int result = 0; - Queue queue = new LinkedList<>(); - for (int i = 0; i < grid.length; i++) { - for (int j = 0; j < grid[0].length; j++) { - if (grid[i][j] == 2) { - queue.add(new Pair(i, j)); - } - } - } - - if (queue.isEmpty()) { - return -1; - } - - queue.add(new Pair(-1, -1)); - while (!queue.isEmpty()) { - Pair p = queue.poll(); - if (!isDelimiter(p)) { - rotOranges(queue, p, grid); - } else if (!queue.isEmpty()) { - queue.add(p); // add back delimiter - result += 1; - } - } - - if (hasFreshOrange(grid)) { - return -1; - } - - return result; - } - - public static void main(String[] args) { - int grid[][] = { { 2, 1, 0, 1, 1 }, { 1, 0, 2, 1, 1 }, { 1, 1, 1, 1, 1 } }; - System.out.println(new MinTimeRotOranges().findMinTime(grid)); - } - -} \ No newline at end of file diff --git a/src/practiceproblems/MinimumPathSum.java b/src/practiceproblems/MinimumPathSum.java deleted file mode 100644 index 825e208..0000000 --- a/src/practiceproblems/MinimumPathSum.java +++ /dev/null @@ -1,40 +0,0 @@ -package practiceproblems; - -class MinPathSum { - public int minPathSum(int[][] grid) { - if (grid == null || grid.length == 0) - return 0; - int dp[][] = new int[grid.length][grid[0].length]; - return getMinPathSum(0, 0, grid, dp); - } - - public int getMinPathSum(int i, int j, int[][] grid, int[][] dp) { - if (i == grid.length - 1 && j == grid[0].length - 1) - return grid[i][j]; - else if (i > grid.length - 1 || j > grid[0].length - 1) - return Integer.MAX_VALUE; - else { - if (dp[i][j] != 0) - return dp[i][j]; - dp[i][j] = grid[i][j] + Math.min(getMinPathSum(i + 1, j, grid, dp), getMinPathSum(i, j + 1, grid, dp)); - } - return dp[i][j]; - } - - public int minPathSum1(int[][] grid) { - - for(int i=1;i stack; - Integer minEle; - - MyStack() { - stack = new Stack<>(); - } - - void getMin() { - if (stack.isEmpty()) { - System.out.println("Stack is empty"); - } else { - System.out.println("Minimum Element in the " + " stack is: " + minEle); - } - } - - void peek() { - if (stack.isEmpty()) { - System.out.println("Stack is empty "); - return; - } - - Integer t = stack.peek(); - System.out.print("Top Most Element is: "); - - if (t < minEle) { - System.out.println(minEle); - } else { - System.out.println(t); - } - } - - void pop() { - if (stack.isEmpty()) { - System.out.println("Stack is empty"); - return; - } - - System.out.print("Top Most Element Removed: "); - Integer t = stack.pop(); - - if (t < minEle) { - System.out.println(minEle); - minEle = 2 * minEle - t; - } else { - System.out.println(t); - } - } - - void push(Integer x) { - if (stack.isEmpty()) { - minEle = x; - stack.push(x); - System.out.println("Number Inserted: " + x); - return; - } - - if (x < minEle) { - // x-minEle<0 - // x-minEle+x<0+x - // 2x-minEle h - = new HashMap<>(); - - Arrays.sort(temp); - for (int i = 0; i < N; i++) { - h.put(arr[i], i); - } - for (int i = 0; i < N; i++) { - - // This is checking whether - // the current element is - // at the right place or not - if (arr[i] != temp[i]) { - ans++; - int init = arr[i]; - - // If not, swap this element - // with the index of the - // element which should come here - swap(arr, i, h.get(temp[i])); - - // Update the indexes in - // the hashmap accordingly - h.put(init, h.get(temp[i])); - h.put(temp[i], i); - } - } - return ans; - } - - public void swap(int[] arr, int i, int j) { - int temp = arr[i]; - arr[i] = arr[j]; - arr[j] = temp; - } - - public static void main(String[] args) { - //nums = {10, 19, 6, 3, 5} - //nums = {2, 8, 5, 4} - } -} \ No newline at end of file diff --git a/src/practiceproblems/NQueens.java b/src/practiceproblems/NQueens.java deleted file mode 100644 index 3a192ad..0000000 --- a/src/practiceproblems/NQueens.java +++ /dev/null @@ -1,90 +0,0 @@ -package practiceproblems; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * https://leetcode.com/problems/n-queens/ - * - * Input: 4 - * Output: [ - * [".Q..", // Solution 1 - * "...Q", - * "Q...", - * "..Q."], - * - * ["..Q.", // Solution 2 - * "Q...", - * "...Q", - * ".Q.."] - * ] - * Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above. - */ -public class NQueens { - - public List> solveNQueens(int n) { - if(n==0) return Collections.emptyList(); - - List> result= new ArrayList<>(); - char[][] board= new char[n][n]; - for(int i=0;i> result) { - - if(row==board.length){ - result.add(construct(board)); - return; - } - for(int i=0;i= 0 && j < chess.length; i--, j++) { - if (chess[i][j] == 'Q') { - return false; - } - } - //check 135 - for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) { - if (chess[i][j] == 'Q') { - return false; - } - } - return true; - } - - private List construct(char[][] chess) { - List path = new ArrayList<>(); - for (int i = 0; i < chess.length; i++) { - path.add(new String(chess[i])); - } - return path; - } - -} \ No newline at end of file diff --git a/src/practiceproblems/NextGreaterElement.java b/src/practiceproblems/NextGreaterElement.java deleted file mode 100644 index 7c422bb..0000000 --- a/src/practiceproblems/NextGreaterElement.java +++ /dev/null @@ -1,90 +0,0 @@ -package practiceproblems; - -import java.util.*; - -/** - * https://www.geeksforgeeks.org/next-greater-element/ - *

- * https://www.geeksforgeeks.org/find-next-greater-number-set-digits/ - */ -class NextGreaterElement { - - static int arr[] = { 1,3,4,2 }; - - // 9,1,2,3,4,5,6,7 - public static void printNGE() { - Stack s = new Stack<>(); - int[] nge = new int[arr.length]; - - for (int i = arr.length - 1; i >= 0; i--) { - - while (!s.empty() && s.peek() <= arr[i]) { - s.pop(); - } - nge[i] = s.empty() ? -1 : s.peek(); - s.push(arr[i]); - - } - for (int i = 0; i < arr.length; i++) - System.out.println(arr[i] + " --> " + nge[i]); - - } - -// Input: nums1 = [4,1,2], nums2 = [1,3,4,2]. -// Output: [-1,3,-1] -// Explanation: -// For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1. -// For number 1 in the first array, the next greater number for it in the second array is 3. -// For number 2 in the first array, there is no next greater number for it in the second array, so output -1. - public int[] nextGreaterElement(int[] findNums, int[] nums) { - int[] ret = new int[findNums.length]; - ArrayDeque stack = new ArrayDeque<>(); - HashMap map = new HashMap<>(); - for(int i = nums.length - 1; i >= 0; i--) { - while(!stack.isEmpty() && stack.peek() <= nums[i]) { - stack.pop(); - } - if(stack.isEmpty()) map.put(nums[i], -1); - else map.put(nums[i], stack.peek()); - stack.push(nums[i]); - } - for(int i = 0; i < findNums.length; i++) { - ret[i] = map.get(findNums[i]); - } - return ret; - } - -// Input: [1,2,1] -// Output: [2,-1,2] -// Explanation: The first 1's next greater number is 2; -// The number 2 can't find next greater number; -// The second 1's next greater number needs to search circularly, which is also 2. - public static int[] nextGreaterElementCircular(int[] nums){ - if(nums==null || nums.length==0) return new int[0]; - int[] result= new int[nums.length]; - int n= nums.length; - Arrays.fill(result, -1); - Deque deque= new ArrayDeque<>(); - // to mimic the circular array we iterate for 2*n because input [1,2,1] will be like [1,2,1,1,2,1] - // and we take mod of 'n' to update the correct index - for (int i = 2 * nums.length - 1; i >= 0; --i) { - - while (!deque.isEmpty() && nums[deque.peek()] <= nums[i % nums.length]) { - deque.pop(); - } - // The stack is either empty, when no "greater element" is found to the right of nums[i], - // or contains the next greater element of nums[i] at the top. - result[i % nums.length] = deque.isEmpty() ? -1 : nums[deque.peek()]; - - // Push i into stack, so that nums[i-1] will compare with nums[i] first, before falling back to - // the next greater element of nums[i] - deque.push(i % nums.length); - } - - return result; - } - - public static void main(String[] args) { - printNGE(); - } -} diff --git a/src/practiceproblems/NonDecreasingArray.java b/src/practiceproblems/NonDecreasingArray.java deleted file mode 100644 index 24ee76c..0000000 --- a/src/practiceproblems/NonDecreasingArray.java +++ /dev/null @@ -1,31 +0,0 @@ -package practiceproblems; - -/** - * https://leetcode.com/problems/non-decreasing-array/description/ - */ -class NonDecreasingArray { - - public boolean checkPossibility(int[] nums) { - - int count = 0; - for (int i = 1; i < nums.length && count <= 1; i++) { - if (nums[i - 1] > nums[i]) { - count++; - if ((i - 2 < 0) || nums[i - 2] <= nums[i]) { - nums[i - 1] = nums[i]; - } else { - nums[i] = nums[i - 1]; - } - } - } - return count <= 1; - } - - public static void main(String[] args) { - // 1,4,2,3 - // //3,4,2,3 - int[] nums = { 7, 8, 2, 3 }; - NonDecreasingArray nda = new NonDecreasingArray(); - System.out.println(nda.checkPossibility(nums)); - } -} diff --git a/src/practiceproblems/NumberOfBallons.java b/src/practiceproblems/NumberOfBallons.java deleted file mode 100644 index 4e1be80..0000000 --- a/src/practiceproblems/NumberOfBallons.java +++ /dev/null @@ -1,24 +0,0 @@ -package practiceproblems; - -/** - * https://leetcode.com/problems/maximum-number-of-balloons/discuss/382401/WithComments-StraightForward-Java-Simple-count-of-chars - */ -public class NumberOfBallons { - - public static int maxNumberOfBalloons(String text) { - int[] chars = new int[26]; //count all letters - for (char c : text.toCharArray()) { - chars[c - 'a']++; - } - int min = chars[1];//for b - min = Math.min(min, chars[0]);//for a - min = Math.min(min, chars[11] / 2);// for l /2 - min = Math.min(min, chars[14] / 2);//similarly for o/2 - min = Math.min(min, chars[13]);//for n - return min; - } - - public static void main(String[] args) { - maxNumberOfBalloons("llonbioan"); - } -} diff --git a/src/practiceproblems/NutsAndBoltsMatch.java b/src/practiceproblems/NutsAndBoltsMatch.java deleted file mode 100644 index 85adc90..0000000 --- a/src/practiceproblems/NutsAndBoltsMatch.java +++ /dev/null @@ -1,74 +0,0 @@ -package practiceproblems; - -/** - * https://www.geeksforgeeks.org/nuts-bolts-problem-lock-key-problem/ - * Java program to solve nut and bolt problem using Quick Sort - */ -public class NutsAndBoltsMatch { - - public static void main(String[] args) { - // Nuts and bolts are represented as array of characters - char nuts[] = { '@', '#', '$', '%', '^', '&' }; - char bolts[] = { '$', '%', '&', '^', '@', '#' }; - - // Method based on quick sort which matches nuts and bolts - matchPairs(nuts, bolts, 0, 5); - - System.out.println("Matched nuts and bolts are : "); - printArray(nuts); - System.out.println(); - printArray(bolts); - } - - // Method to print the array - private static void printArray(char[] arr) { - for (char ch : arr) { - System.out.print(ch + " "); - } - System.out.print("n"); - } - - // Method which works just like quick sort - private static void matchPairs(char[] nuts, char[] bolts, int low, int high) { - if (low < high) { - - // Choose last character of bolts array for nuts partition. - int pivot = partition(nuts, low, high, bolts[high]); - - // Now using the partition of nuts choose that for bolts partition. - partition(bolts, low, high, nuts[pivot]); - - // Recur for [low...pivot-1] & [pivot+1...high] for nuts and - // bolts array. - matchPairs(nuts, bolts, low, pivot - 1); - matchPairs(nuts, bolts, pivot + 1, high); - } - } - - // Similar to standard partition method. Here we pass the pivot element - // too instead of choosing it inside the method. - private static int partition(char[] arr, int low, int high, char pivot) { - int i = low; - char temp1, temp2; - for (int j = low; j < high; j++) { - if (arr[j] < pivot) { - temp1 = arr[i]; - arr[i] = arr[j]; - arr[j] = temp1; - i++; - } else if (arr[j] == pivot) { - temp1 = arr[j]; - arr[j] = arr[high]; - arr[high] = temp1; - j--; - } - } - temp2 = arr[i]; - arr[i] = arr[high]; - arr[high] = temp2; - - // Return the partition index of an array based on the pivot - // element of other array. - return i; - } -} diff --git a/src/practiceproblems/OverlappingIntervals.java b/src/practiceproblems/OverlappingIntervals.java deleted file mode 100644 index 1efac77..0000000 --- a/src/practiceproblems/OverlappingIntervals.java +++ /dev/null @@ -1,42 +0,0 @@ -package practiceproblems; - -import java.util.PriorityQueue; - -/** - * Given a collection of intervals, find the minimum number of intervals - * you need to remove to make the rest of the intervals non-overlapping. - * Input: [[1,2],[2,3],[3,4],[1,3]] - Output: 1 - Explanation: [1,3] can be removed and the rest of intervals are non-overlapping. - Input: [[1,2],[1,2],[1,2]] - Output: 2 - Explanation: You need to remove two [1,2] to make the rest of intervals non-overlapping. - */ - -public class OverlappingIntervals{ - - public int eraseOverlapIntervals(int[][] intervals) { - if(intervals.length==0) return 0; - - PriorityQueue queue = new PriorityQueue((a, b) -> Integer.compare(a[0],b[0])); - - for(int[] interval: intervals){ - queue.offer(interval); - } - int result=0; - - int end= queue.poll()[1]; - - while(!queue.isEmpty()){ - if(end>queue.peek()[0]) { - result++; - end=Math.min(end, queue.poll()[1]); - }else{ - end=queue.poll()[1]; - } - } - - return result; - } - -} \ No newline at end of file diff --git a/src/practiceproblems/PalindromePartion.java b/src/practiceproblems/PalindromePartion.java deleted file mode 100644 index 61c34be..0000000 --- a/src/practiceproblems/PalindromePartion.java +++ /dev/null @@ -1,52 +0,0 @@ -package practiceproblems; - -import java.util.*; - -//https://leetcode.com/problems/palindrome-partitioning/ -/* -Given a string s, partition s such that every substring of the partition is a palindrome. - -Return all possible palindrome partitioning of s. - -Input: "aab" -Output: -[ - ["aa","b"], - ["a","a","b"] -] - */ -class PalindromePartion { - public List> partition(String s) { - List> res = new ArrayList>(); - List list = new ArrayList(); - dfs(s, 0, list, res); - return res; - } - - public void dfs(String s, int pos, List list, List> res) { - if (pos == s.length()) { - res.add(new ArrayList(list)); - return; - } - - for (int i = pos; i < s.length(); i++) { - if (isPal(s, pos, i)) { - list.add(s.substring(pos, i + 1)); - dfs(s, i + 1, list, res); - list.remove(list.size() - 1); - } - } - - } - - public boolean isPal(String s, int low, int high) { - while (low < high) if (s.charAt(low++) != s.charAt(high--)) return false; - return true; - } - - public static void main(String[] args) { - new PalindromePartion().partition("aab"); - } - - -} \ No newline at end of file diff --git a/src/practiceproblems/PalindromeSinglyLinkedList.java b/src/practiceproblems/PalindromeSinglyLinkedList.java deleted file mode 100644 index 770eb9f..0000000 --- a/src/practiceproblems/PalindromeSinglyLinkedList.java +++ /dev/null @@ -1,64 +0,0 @@ -package practiceproblems; - -/** - * https://leetcode.com/problems/palindrome-linked-list/ - */ -public class PalindromeSinglyLinkedList { - - class Node { - int data; - Node next; - - public Node(int data) { - this.data = data; - } - - } - - public static void main(String[] args) { - - PalindromeSinglyLinkedList palindrome = new PalindromeSinglyLinkedList(); - Node head = palindrome.new Node(1); - head.next = palindrome.new Node(2); - head.next.next = palindrome.new Node(3); - head.next.next.next = palindrome.new Node(2); - head.next.next.next.next = palindrome.new Node(1); - - System.out.println(palindrome.isPalindrome(head)); - - } - - public boolean isPalindrome(Node head) { - Node fast = head, slow = head; - while (fast != null && fast.next != null) { - fast = fast.next.next; - slow = slow.next; - } - if (fast != null) { // odd nodes: let right half smaller - slow = slow.next; - } - slow = reverse(slow); - fast = head; - - while (slow != null) { - if (fast.data != slow.data) { - return false; - } - fast = fast.next; - slow = slow.next; - } - return true; - } - - public Node reverse(Node slow) { - Node prev = null; - while (slow != null) { - Node next = slow.next; - slow.next = prev; - prev = slow; - slow = next; - } - return prev; - } - -} diff --git a/src/practiceproblems/PalindromicSubSequence.java b/src/practiceproblems/PalindromicSubSequence.java deleted file mode 100644 index df1b1f5..0000000 --- a/src/practiceproblems/PalindromicSubSequence.java +++ /dev/null @@ -1,52 +0,0 @@ -package practiceproblems; - -/** - * Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000. - * Input: "cbbd" - * Output: 2 - * - * - */ -class PalindromicSubSequence { - // genral solution if s[l]==s[r] ? 2 + longestPalindromeSubseq(l+1,r-1, s) : - // max(longestPalindromeSubseq(l+1,r, s),longestPalindromeSubseq(l,r-1, s)); - public int longestPalindromeSubseq(String s) { - if(s==null || s.length()==0) return 0; - - int[][] dp= new int[s.length()][s.length()]; - - for(int i=s.length()-1;i>=0;i--){ - for(int j=i;j= 0; i--) { - dp[i] = 1; - int pre = 0; - for (int j = i + 1; j < s.length(); j++) { - int tmp = dp[j]; - if (s.charAt(i) == s.charAt(j)) { - dp[j] = pre + 2; - } else { - dp[j] = Math.max(dp[j], dp[j - 1]); - } - pre = tmp; - } - } - return dp[s.length() - 1]; - } -} \ No newline at end of file diff --git a/src/practiceproblems/PascalsTriangle.java b/src/practiceproblems/PascalsTriangle.java deleted file mode 100644 index 532be23..0000000 --- a/src/practiceproblems/PascalsTriangle.java +++ /dev/null @@ -1,39 +0,0 @@ -package practiceproblems; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * https://leetcode.com/problems/pascals-triangle/ - *

- * Input: 5 - * Output: - * [ - * [1], - * [1,1], - * [1,2,1], - * [1,3,3,1], - * [1,4,6,4,1] - * ] - */ -public class PascalsTriangle { - - public List> generate1(int numRows) { - List> allrows = new ArrayList<>(); - ArrayList row = new ArrayList<>(); - for (int i = 0; i < numRows; i++) { - // suppose if the row is [1,3,3,1] - // add 1 at start [1,1,3,3,1] - // then add together j and j+1 elements like below - // [1,4,3,3,1] => [1,4,6,3,1]=>[1,4,6,4,1] - row.add(0, 1); - for (int j = 1; j < row.size() - 1; j++) - row.set(j, row.get(j) + row.get(j + 1)); - allrows.add(new ArrayList<>(row));// every time the copy is only appended - } - return allrows; - - } -} \ No newline at end of file diff --git a/src/practiceproblems/PathSumIII.java b/src/practiceproblems/PathSumIII.java deleted file mode 100644 index 1ee3bf9..0000000 --- a/src/practiceproblems/PathSumIII.java +++ /dev/null @@ -1,48 +0,0 @@ -package practiceproblems; - - -import java.util.HashMap; -import java.util.Map; - -public class PathSumIII { - Map h= new HashMap<>(); - int count=0; - - public void preorder(TreeNode node, int currSum, int k) { - if (node == null) - return; - - // current prefix sum - currSum += node.val; - - // here is the sum we're looking for - if (currSum == k) - count++; - - // number of times the curr_sum − k has occured already, - // determines the number of times a path with sum k - // has occurred upto the current node - count += h.getOrDefault(currSum - k, 0); - - // add the current sum into hashmap - // to use it during the child nodes processing - h.put(currSum, h.getOrDefault(currSum, 0) + 1); - - // process left subtree - preorder(node.left, currSum, k); - // process right subtree - preorder(node.right, currSum, k); - - // remove the current sum from the hashmap - // in order not to use it during - // the parallel subtree processing - h.put(currSum, h.get(currSum) - 1); - } - - public int pathSumAlter(TreeNode root, int sum) { - int k = sum; - preorder(root, 0, k); - return count; - } - -} \ No newline at end of file diff --git a/src/practiceproblems/Pattern132.java b/src/practiceproblems/Pattern132.java deleted file mode 100644 index c1bd5ca..0000000 --- a/src/practiceproblems/Pattern132.java +++ /dev/null @@ -1,33 +0,0 @@ -package practiceproblems; - -import java.util.Arrays; - -/*https://leetcode.com/problems/132-pattern/discuss/94089/Java-solutions-from-O(n3)-to-O(n)-for-%22132%22-pattern-(updated-with-one-pass-slution)*/ -public class Pattern132 { - - public static boolean find132pattern(int[] arr) { - - int[] temp = Arrays.copyOf(arr, arr.length); - - for (int i = 1; i < arr.length; i++) { - temp[i] = Math.min(arr[i - 1], temp[i - 1]); - } - // {3, 3, 3, 1, 1, 1, 1, 1} - - for (int j = arr.length - 1, top = arr.length; j >= 0; j--) { - if (arr[j] <= temp[j]) - continue; - while (top < arr.length && temp[top] <= temp[j]) - top++; - if (top < arr.length && arr[j] > temp[top]) - return true; - temp[--top] = arr[j]; - } - return false; - } - - public static void main(String[] args) { - int[] arr = { 3, 4, 1, 2, 9, 6, 7, 8 }; - find132pattern(arr); - } -} diff --git a/src/practiceproblems/QueensAttackKing.java b/src/practiceproblems/QueensAttackKing.java deleted file mode 100644 index 4ca1848..0000000 --- a/src/practiceproblems/QueensAttackKing.java +++ /dev/null @@ -1,54 +0,0 @@ -package practiceproblems; - -import java.util.*; -//https://leetcode.com/problems/queens-that-can-attack-the-king/submissions/ - -/** - * On an 8x8 chessboard, there can be multiple Black Queens and one White King. - * - * Given an array of integer coordinates queens that represents the positions of the Black Queens, - * and a pair of coordinates king that represent the position of the White King, - * return the coordinates of all the queens (in any order) that can attack the King. - */ -class QueensAttackKing { - public List> queensAttacktheKing(int[][] queens, int[] king) { - List> result= new ArrayList<>(); - boolean[][] visited= new boolean[8][8]; - int[][]dirs= {{1,0},{-1,0},{0,1},{0,-1},{-1,-1},{1,1},{1,-1},{-1,1}}; - // first marking all queen positions - for(int[] qu:queens){ - visited[qu[0]][qu[1]]=true; - } - - for(int[] dir: dirs){ - List temp= findQueensPositions(king,dir[0],dir[1],visited); - if(temp!=null) result.add(temp); - } - - return result; - - } - - public List findQueensPositions(int[] king, int xDir, int yDir, boolean[][] visited){ - int newX= xDir+king[0]; - int newY= yDir+king[1]; - // going to walk along x,y only not 8 directions at same time - while(newX<8 && newY<8 && newX>=0 && newY>=0){ - if(visited[newX][newY]){ - return Arrays.asList(newX,newY); // returns when first queen is met in row or column - } - - newX+=xDir; - newY+=yDir; - - } - - return null; - } - - public static void main(String[] args) { - int[][] queens= {{0,1},{1,0},{4,0},{0,4},{3,3},{2,4}}; - int[] king= {0,0}; - new QueensAttackKing().queensAttacktheKing(queens, king); - } -} \ No newline at end of file diff --git a/src/practiceproblems/RandomLinkedList.java b/src/practiceproblems/RandomLinkedList.java deleted file mode 100644 index 32fd33a..0000000 --- a/src/practiceproblems/RandomLinkedList.java +++ /dev/null @@ -1,62 +0,0 @@ -package practiceproblems; - -/** - * https://leetcode.com/problems/copy-list-with-random-pointer/ - */ -class RandomLinkedList { - - public LLNode copyRandomList(LLNode head) { - if (head == null) { - return null; - } - LLNode temp = head; - while (temp != null) { - LLNode LLNode = new LLNode(temp.val + 10, temp.next, null); - temp.next = LLNode; - temp = temp.next.next; - } - LLNode randomLLNode = head; - while (randomLLNode != null) { - randomLLNode.next.random = randomLLNode.random.next; - randomLLNode = randomLLNode.next.next; - } - LLNode copyHead = head.next; - LLNode tempHead = copyHead; - while (head != null && tempHead != null) { - head.next = head.next == null || head.next.next == null ? head.next : head.next.next; - tempHead.next = tempHead.next == null || tempHead.next.next == null ? tempHead.next : tempHead.next.next; - head = head.next; - tempHead = tempHead.next; - } - return copyHead; - } - - public static void main(String[] args) { - LLNode head = new LLNode(1, null, null); - head.next = new LLNode(2, null, null); - head.next.next = new LLNode(3, null, null); - head.next.next.next = new LLNode(4, null, null); - head.random = head.next.next; - head.next.random = head.next.next.next; - head.next.next.random = head.next; - head.next.next.next.random = head; - RandomLinkedList solution = new RandomLinkedList(); - solution.copyRandomList(head); - } -} - -class LLNode { - public int val; - public LLNode next; - public LLNode random; - - public LLNode(int _val, LLNode _next, LLNode _random) { - val = _val; - next = _next; - random = _random; - } - - public String toString() { - return "" + this.val; - } -} \ No newline at end of file diff --git a/src/practiceproblems/RandomPickWithWeight.java b/src/practiceproblems/RandomPickWithWeight.java deleted file mode 100644 index bf38a9c..0000000 --- a/src/practiceproblems/RandomPickWithWeight.java +++ /dev/null @@ -1,52 +0,0 @@ -package practiceproblems; - -/** - * https://leetcode.com/problems/random-pick-with-weight/ - */ -class RandomPickWithWeight { - private int sum; - private int[] sumArr; - - public RandomPickWithWeight(int[] w) { - sum = 0; - sumArr = new int[w.length]; - for (int i = 0; i < w.length; ++i) { - sum += w[i]; - sumArr[i] = sum; - } - } - - public int pickIndex() { - int idx = (int) (Math.random() * sum); - return binarySearch(idx + 1); // +1 is because the rand will lie between 0-14 - } - - public int binarySearch(int idx) { - int left = 0; - int right = sumArr.length - 1; - - while (left < right) { - int mid = ((right - left) / 2) + left; - if (sumArr[mid] < idx) { - left = mid + 1; - } else { - right = mid; - } - } - return left; - } - - public static void main(String[] args) { - RandomPickWithWeight randomPickWithWeight = new RandomPickWithWeight(new int[]{1, 3, 5, 4, 2}); - randomPickWithWeight.pickIndex(); - - //IntStream.range(0, 10).forEach(i -> System.out.println((int) (Math.random() * 3))); - } - -} - -/** - * Your Solution object will be instantiated and called as such: - * Solution obj = new Solution(w); - * int param_1 = obj.pickIndex(); - */ \ No newline at end of file diff --git a/src/practiceproblems/RangeSum.java b/src/practiceproblems/RangeSum.java deleted file mode 100644 index 75f1df5..0000000 --- a/src/practiceproblems/RangeSum.java +++ /dev/null @@ -1,41 +0,0 @@ -package practiceproblems; - -/** - * 303. Range Sum Query - Immutable - * - * Given an integer array nums, - * find the sum of the elements between indices i and j (i ≤ j), inclusive. - * - * Implement the NumArray class: - * - * NumArray(int[] nums) Initializes the object with the integer array nums. - * int sumRange(int i, int j) Return the sum of the elements of the nums array in the range [i, j] - * inclusive (i.e., sum(nums[i], nums[i + 1], ... , nums[j])) - * - * ["NumArray", "sumRange", "sumRange", "sumRange"] - * [[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]] - * Output - * [null, 1, -1, -3] - * - * Explanation - * NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]); - * numArray.sumRange(0, 2); // return 1 ((-2) + 0 + 3) - * numArray.sumRange(2, 5); // return -1 (3 + (-5) + 2 + (-1)) - * numArray.sumRange(0, 5); // return -3 ((-2) + 0 + 3 + (-5) + 2 + (-1)) - */ -public class RangeSum { - int[] dp; - public void NumArray(int[] nums) { - if(nums.length==0) return ; - dp= new int[nums.length]; - dp[0]=nums[0]; - for(int i=1;i findItinerary(List> tickets) { - if(tickets==null || tickets.size()==0) return Collections.emptyList(); - - Map> map= new HashMap<>(); - - for(List ticket: tickets){ - map.putIfAbsent(ticket.get(0), new PriorityQueue<>()); - map.get(ticket.get(0)).offer(ticket.get(1)); - } - List res = new ArrayList(); - dfs(map, res, "JFK"); - return res; - } - - public void dfs( Map> map, List res, String s){ - - PriorityQueue queue= map.get(s); - - while(queue!=null && !queue.isEmpty()){ - String temp= queue.poll(); - dfs(map, res, temp); - } - - res.add(0,s); - } - } - -} \ No newline at end of file diff --git a/src/practiceproblems/RedundantConnection.java b/src/practiceproblems/RedundantConnection.java deleted file mode 100644 index f5f2f0a..0000000 --- a/src/practiceproblems/RedundantConnection.java +++ /dev/null @@ -1,44 +0,0 @@ -package practiceproblems; - -public class RedundantConnection { - public int[] findRedundantConnection(int[][] edges) { - DisjointSet set= new DisjointSet(edges.length); - - for(int[]edge: edges){ - if(!set.union(edge[0]-1, edge[1]-1)) return edge; - } - return new int[]{-1,-1}; - } - - static class DisjointSet{ - int[] parent; - int[] rank; - - public DisjointSet(int n){ - this.parent= new int[n]; - this.rank= new int[n]; - } - - public int find(int x){ - if(parent[x]==0) return x; - return parent[x]=find(parent[x]); - } - - public boolean union(int x, int y){ - int rootX= find(x); - int rootY= find(y); - - if(rootX==rootY) return false; - - if(rank[rootX] removeInvalidParentheses(String s) { - if (isValid(s)) - return Collections.singletonList(s); - List ans = new ArrayList<>(); - //The queue only contains invalid middle steps - Queue queue = new LinkedList<>(); - //The 3-Tuple is (string, startIndex, lastRemovedChar) - queue.add(new Tuple(s, 0, ')')); - while (!queue.isEmpty()) { - Tuple x = queue.poll(); - //Observation 2, start from last removal position - for (int i = x.start; i < x.string.length(); ++i) { - char ch = x.string.charAt(i); - //Not parentheses - if (ch != '(' && ch != ')') continue; - //Observation 1, do not repeatedly remove from consecutive ones - if (i != x.start && x.string.charAt(i - 1) == ch) continue; - //Observation 3, do not remove a pair of valid parentheses - if (x.removed == '(' && ch == ')') continue; - String t = x.string.substring(0, i) + x.string.substring(i + 1); - //Check isValid before add - if (isValid(t)) - ans.add(t); - //Avoid adding leaf level strings - else if (ans.isEmpty()) - queue.add(new Tuple(t, i, ch)); - } - } - return ans; -} - -public static boolean isValid(String s) { - int count = 0; - for (int i = 0; i < s.length(); ++i) { - char c = s.charAt(i); - if (c == '(') ++count; - if (c == ')' && count-- == 0) return false; - } - return count == 0; -} - -} - - class Tuple { - public final String string; - public final int start; - public final char removed; - - public Tuple(String string, int start, char removed) { - this.string = string; - this.start = start; - this.removed = removed; - -} -} \ No newline at end of file diff --git a/src/practiceproblems/ReverseWordsInString.java b/src/practiceproblems/ReverseWordsInString.java deleted file mode 100644 index f848084..0000000 --- a/src/practiceproblems/ReverseWordsInString.java +++ /dev/null @@ -1,40 +0,0 @@ -package practiceproblems; - -import java.util.Arrays; - -public class ReverseWordsInString { - - public char[] reverse(char[] arr, int i, int j) { - while (i < j) { - char tmp = arr[i]; - arr[i++] = arr[j]; - arr[j--] = tmp; - } - return arr; - } - - public String reverseWords(String s) { - // reverse the whole string and convert to char array - char[] str = reverse(s.toCharArray(), 0, s.length()-1); - int start = 0, end = 0; // start and end positions of a current word - //for input "the sky is blue" - // the char arr contians - //[e u l b s i y k s e h t] - - System.out.println(Arrays.toString(str)); - for (int i = 0; i < str.length; i++) { - if (str[i] != ' ') { // if the current char is letter - str[end++] = str[i]; // just move this letter to the next free pos - } else if (i > 0 && str[i-1] != ' ') { // if the first space after word - reverse(str, start, end-1); // reverse the word - str[end++] = ' '; // and put the space after it - start = end; // move start position further for the next word - } - } - reverse(str, start, end-1); // reverse the tail word if it's there - // here's an ugly return just because we need to return Java's String - // also as there could be spaces at the end of original string - // we need to consider redundant space we have put there before - return new String(str, 0, end > 0 && str[end-1] == ' ' ? end-1 : end); - } -} \ No newline at end of file diff --git a/src/practiceproblems/RollingHashRabinKarp.java b/src/practiceproblems/RollingHashRabinKarp.java deleted file mode 100644 index bafdac5..0000000 --- a/src/practiceproblems/RollingHashRabinKarp.java +++ /dev/null @@ -1,134 +0,0 @@ -package practiceproblems; - -public class RollingHashRabinKarp{ - /** - * the normal way to calculate an hash from a string would be through the following method - * for String S="abcdef" we chose a prime number which is greater that the no.of chars(26) - * we choose P=31 - * - * total hash(abcdef)= (a*P^0+ b*P^1 + c*P^2 + d*P^3 + e*P^4 + f*P^5) % M; - * %(mod) is taken to avoid overflow of values - * hash at each point is [h0, h1, h2, h3, h4, h5] - * - * this is anlogus to prefix sum, the hash at each index i is hash calculated from 0 to 'i' - * - * for h2 is hash from (a-c), in order to calculate prefix sum from index 2-4 - * - * sum(2-4)= sum(4)-sum(2) [sum 0-4 - sum 0-2], likewise we can calulate rolling hash - * - * in order to find contains subString for String size M and N, the time complexity would be O(MN) - * - * if we find the hash of String M and N seperately and somehow find if substring of size N in String M - * hashes to hash(N) we will have our result in O(M) - * - * M= SDESKILLS - * N= SKILLS - * Note: p0 or p1= P^number - * - * hash of M= [(S*p0)+(D*p1)+(E*p2)+(S*p4)+(K*p5)+(I*p6)+(L*p7)+(L*p8)+(S*p9)] % M - * - * in hashing no matter how many times/ at what posistion a string comes, it has to hash to same value - * - * if we have a hash(abcdef)= a*p0+ b*p1+ c*p2+ d*p3+ e*p4+ f*p5 - * and i need hash(cde) i need to do prefix sum analogy - * hash(cde)= hash(R)-hash(L-1) R= Right, L=Left - * but the above equation comes down to [c*p2 + d*p3+ e*p4] this is not going to yeild correct - * result for cde every time if 'cde' occurs at different index then the eq would be [c*p8+d*p9+e*p10] - * - * so what we need is to add one more part to the eq ([c*p2 + d*p3+ e*p4]/ p2) => [c*p0 + d*p1+ e*p2] - * hash(cde)= hash(R)-hash(L-1)/P^L R= Right, L=Left - * - * Hash[3,6]= (Hash(6)- Hash(2)/ p^3)%M - * - * hash([L...R]) =(hash[R] - hash[L - 1]/PL)% M - hash(s[L...R]) =(hash[R] - hash[L - 1]) * P^-L % M - - hash(s[L...R]) =(hash[R] - hash[L - 1])*(P^-1)L % M - hash(s[L...R]) =(hash[R] - hash[L - 1])% M*(P-1)L %M% M - - (A * B) % M =( (A % M) * (B % M)) % M - X = P^-1= P^M-2% M - hash(s[L...R]) =(((hash[R] - hash[L - 1])% M *X^L )% M) - */ - - - public static void main(String[] args) { - String givenValue = "abaaab"; - String input = "aaa"; - -// char[] givenArr = givenValue.toCharArray(); -// char[] inputArr = input.toCharArray(); -// -// int inputHash = createHash(inputArr, inputArr.length); -// int previousValue = 0; -// for (int i = 0; i < (givenArr.length - inputArr.length + 1); i++) { -// previousValue = givenHash(givenArr, i, previousValue); -// if (inputHash == previousValue && matchString(inputArr, givenArr, i)) { -// System.out.println("It exists"); -// } -// } - - rabinKarp(givenValue, input); - } - - private static int givenHash(char[] givenArr, int i, int previousValue) { - - if (previousValue == 0) { - return createHash(givenArr, 3); - } - - int currentValue = previousValue - givenArr[i - 1]; - System.out.println(currentValue + givenArr[i + 2] * 100); - return currentValue + givenArr[i + 2] * 100; - - } - - private static int createHash(char[] inputArr, int length) { - int hash = 0; - double power = 0; - for (int i = 0; i < length; i++) { - hash = hash + (int) Math.pow(10, power++) * inputArr[i]; - } - return hash; - } - - private static boolean matchString(char[] inputArr, char[] givenArr, int i) { - int index = 0; - for (int j = i; j < inputArr.length; j++) { - if (inputArr[index++] != givenArr[j]) { - return false; - } - } - return true; - } - - //the time complexity is O(m + n) - public static int rabinKarp(String t, String s) { - if (s.length() > t.length()) { - return -1; // s is not a substring of t. - } - final int BASE = 26; - int tHash = 0, sHash = 0; // Hash codes for the substring of t and s. - int powerS = 1; // this will be used to calculate the rolling hash when current window moves out - for (int i = 0; i < s.length(); i++) { - powerS = i > 0 ? powerS * BASE : 1; - tHash = tHash * BASE + t.charAt(i); - sHash = sHash * BASE + s.charAt(i); - } - for (int i = s.length(); i < t.length(); i++) { -// Checks the two substrings are actually equal or not, to protect -// against hash collision. - if (tHash == sHash ){ //&& t.substring(i - s.length(), i).equals(s)) { - return i - s.length(); // Found a match. - } -// Uses rolling hash to compute the new hash code. - tHash -= t.charAt(i - s.length()) * powerS; - tHash = tHash * BASE + t.charAt(i); - } -// Tries to match s and t.substring(t.length() - s.lengthO). - if (tHash == sHash){ // && t .substring(t.length() - s.length()).equals(s)){ - return t.length() - s.length(); - } - return -1; - } -} \ No newline at end of file diff --git a/src/practiceproblems/RotateMatrixInPlace.java b/src/practiceproblems/RotateMatrixInPlace.java deleted file mode 100644 index e6bf289..0000000 --- a/src/practiceproblems/RotateMatrixInPlace.java +++ /dev/null @@ -1,102 +0,0 @@ -package practiceproblems; - -/** - * https://www.geeksforgeeks.org/inplace-rotate-square-matrix-by-90-degrees/ - */ -// looking for easy solution -class RotateMatrixInPlace { - - /** - * N/2 for time complexity o(n) - *

- * get all the corners first and swap ( rotate 90 degree) - * - * @param N - * @param mat - */ - static void rotateMatrix(int N, int mat[][]) { - // Consider all squares one by one - for (int x = 0; x < N / 2; x++) { - // Consider elements in group of 4 in - // current square - for (int y = x; y < N - x - 1; y++) { - // store current cell in temp variable - System.out.println("mat[" + x + "][" + y + "] = " + mat[x][y]); - int temp = mat[x][y]; - - // move values from right to top - System.out.println("mat[" + y + "][" + (N - 1 - x) + "] = " + mat[y][N - 1 - x]); - mat[x][y] = mat[y][N - 1 - x]; - - // move values from bottom to right - System.out.println("mat[" + (N - 1 - x) + "][" + (N - 1 - y) + "] = " + mat[N - 1 - x][N - 1 - y]); - mat[y][N - 1 - x] = mat[N - 1 - x][N - 1 - y]; - - // move values from left to bottom - System.out.println("mat[" + (N - 1 - y) + "][" + (x) + "] = " + mat[N - 1 - y][x]); - mat[N - 1 - x][N - 1 - y] = mat[N - 1 - y][x]; - - // assign temp to left - System.out.println("mat[" + (N - 1 - y) + "][" + (x) + "] = " + temp); - mat[N - 1 - y][x] = temp; - } - } - } - - public void rotate(int[][] matrix) { - if(matrix == null || matrix.length == 0 || matrix[0].length == 0)return; - int n= matrix.length-1; - - for(int i=0; i - * https://leetcode.com/problems/rotate-image/discuss/298719/A-Java-one-pass-solution-with-detailed-explanation - *

- * //x,y1=x2,y2 - * // x1=y2 - */ -class RotateMatrixInPlaceAntiClockwise { - - static void rotateMatrix(int N, int mat[][]) { - - for (int x = 0; x < N / 2; x++) { - - for (int y = x; y < N - x; y++) { - - // store current cell in temp variable - int temp = mat[x][y]; - - // move values from right to top - mat[x][y] = mat[y][N - x]; - - // move values from bottom to right - mat[y][N - x] = mat[N - x][N - y]; - - // move values from left to bottom - mat[N - x][N - y] = mat[N - y][x]; - - // assign temp to left - mat[N - y][x] = temp; - } - } - } - - static void displayMatrix(int N, int mat[][]) { - for (int i = 0; i < N; i++) { - for (int j = 0; j < N; j++) - System.out.print(" " + mat[i][j]); - - System.out.print("\n"); - } - System.out.print("\n"); - } - - public static void main(String[] args) { - int N = 4; - - // Test Case 1 - int mat[][] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } }; - - // int mat[][] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; - // int mat[][] = { {1, 2}, {4, 5} }; - - // displayMatrix(mat); - - rotateMatrix(N - 1, mat); - - // Print rotated matrix - displayMatrix(N, mat); - } -} \ No newline at end of file diff --git a/src/practiceproblems/SameTree.java b/src/practiceproblems/SameTree.java deleted file mode 100644 index 72b456d..0000000 --- a/src/practiceproblems/SameTree.java +++ /dev/null @@ -1,62 +0,0 @@ -package practiceproblems; - -import java.util.ArrayDeque; - -/** - * Given two binary trees, write a function to check if they are the same or not. - * Two binary trees are considered the same if they are structurally identical and the nodes have the same value. -Input: 1 1 - / \ / \ - 2 1 1 2 - - [1,2,1], [1,1,2] - -Output: false - */ -public class SameTree { - public boolean check(TreeNode p, TreeNode q) { - // p and q are null - if (p == null || q == null) return p==q; - if (p.val != q.val) return false; - return true; - } - - public boolean isSameTree(TreeNode p, TreeNode q) { - if (p == null && q == null) return true; - if (!check(p, q)) return false; - - // init deques - ArrayDeque deqP = new ArrayDeque(); - ArrayDeque deqQ = new ArrayDeque(); - deqP.addLast(p); - deqQ.addLast(q); - - while (!deqP.isEmpty()) { - p = deqP.removeFirst(); - q = deqQ.removeFirst(); - - if (!check(p, q)) return false; - if (p != null) { - // in Java nulls are not allowed in Deque - if (!check(p.left, q.left)) return false; - if (p.left != null) { - deqP.addLast(p.left); - deqQ.addLast(q.left); - } - if (!check(p.right, q.right)) return false; - if (p.right != null) { - deqP.addLast(p.right); - deqQ.addLast(q.right); - } - } - } - return true; - } - - public boolean isSameTreeRecur(TreeNode p, TreeNode q){ - if(p==null || q==null) return p==q; - if(p.val==q.val) return true; - - return isSameTreeRecur(p.left, q.left) && isSameTreeRecur(p.right, q.right); - } -} \ No newline at end of file diff --git a/src/practiceproblems/SearchAMaze.java b/src/practiceproblems/SearchAMaze.java deleted file mode 100644 index c701597..0000000 --- a/src/practiceproblems/SearchAMaze.java +++ /dev/null @@ -1,80 +0,0 @@ -package practiceproblems; - -import java.util.LinkedList; -import java.util.Queue; - -/** - * https://www.techiedelight.com/lee-algorithm-shortest-path-in-a-maze/ - */ -public class SearchAMaze { - - private static final int M = 10; - private static final int N = 10; - - private static final int row[] = { -1, 0, 0, 1 }; - private static final int col[] = { 0, -1, 1, 0 }; - - private static boolean isValid(int mat[][], int row, int col) { - return (row >= 0) && (row < M) && (col >= 0) && (col < N) && mat[row][col] == 1; - } - - private static void BFS(int mat[][], int srcX, int srcY, int destX, int destY) { - - Queue q = new LinkedList<>(); - - q.add(new MazeNode(srcX, srcY, 0)); - - int minDist = Integer.MAX_VALUE; - - while (!q.isEmpty()) { - MazeNode node = q.poll(); - - srcX = node.x; - srcY = node.y; - int dist = node.dist; - - if (srcX == destX && srcY == destY) { - minDist = dist; - break; - } - - for (int k = 0; k < 4; k++) { - if (isValid(mat, srcX + row[k], srcY + col[k])) { - mat[srcX][srcY] = 0; - MazeNode e = new MazeNode(srcX + row[k], srcY + col[k], dist + 1); - q.add(e); - System.out.println(" Adding to the queue :" + e); - } - } - } - - if (minDist != Integer.MAX_VALUE) { - System.out.print("The shortest path from source to destination " + "has length " + minDist); - } else { - System.out.print("Destination can't be reached from source"); - } - } - - public static void main(String[] args) { - int[][] mat = { { 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 }, { 0, 1, 1, 1, 1, 1, 0, 1, 0, 1 }, - { 0, 0, 1, 0, 1, 1, 1, 0, 0, 1 }, { 1, 0, 1, 1, 1, 0, 1, 1, 0, 1 }, { 0, 0, 0, 1, 0, 0, 0, 1, 0, 1 }, - { 1, 0, 1, 1, 1, 0, 0, 1, 1, 1 }, { 0, 0, 0, 0, 1, 0, 0, 1, 0, 1 }, { 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, - { 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 }, { 0, 0, 1, 0, 0, 1, 1, 0, 0, 1 } }; - - BFS(mat, 8, 0, 0, 9); - } -} - -class MazeNode { - int x, y, dist; - - MazeNode(int x, int y, int dist) { - this.x = x; - this.y = y; - this.dist = dist; - } - - public String toString() { - return "(" + x + "," + y + ") -> " + dist; - } -}; \ No newline at end of file diff --git a/src/practiceproblems/SerializeDeserializeBST.java b/src/practiceproblems/SerializeDeserializeBST.java deleted file mode 100644 index a970bb5..0000000 --- a/src/practiceproblems/SerializeDeserializeBST.java +++ /dev/null @@ -1,76 +0,0 @@ -package practiceproblems; - -// Hi all, I think my solution is pretty straightforward and easy to understand, not that efficient though. And the serialized tree is compact. -// Pre order traversal of BST will output root node first, then left children, then right. - -// root left1 left2 leftX right1 rightX -// If we look at the value of the pre-order traversal we get this: - -// rootValue (rootValue) (>rootValue) -// Because of BST's property: before the |separate line| all the node values are less than root value, all the node values after |separate line| are greater than root value. We will utilize this to build left and right tree. - -import java.util.*; - -class SerializeDeserializeBST { - private static final String SEP = ","; - private static final String NULL = "null"; - // Encodes a tree to a single string. - - public String serialize(TreeNode root) { - - if (root == null) { - return NULL + SEP; - } - - String leftSerialized = serialize(root.left); - String rightSerialized = serialize(root.right); - - return root.val + SEP + leftSerialized + rightSerialized; - } - - public String serializeIterative(TreeNode root) { - StringBuilder sb = new StringBuilder(); - if (root == null) return NULL; - //traverse it recursively if you want to, I am doing it iteratively here - Deque st = new ArrayDeque<>(); - st.push(root); - while (!st.isEmpty()) { - root = st.pop(); - sb.append(root.val).append(SEP); - if (root.right != null) st.push(root.right); - if (root.left != null) st.push(root.left); - } - return sb.toString(); - } - - // Decodes your encoded data to tree. - // pre-order traversal - public TreeNode deserialize(String data) { - if (data.equals(NULL)) return null; - String[] strs = data.split(SEP); - Queue q = new LinkedList<>(); - for (String e : strs) { - q.offer(Integer.parseInt(e)); - } - return getNode(q); - } - - // some notes: - // 5 - // 3 6 - // 2 7 - private TreeNode getNode(Queue q) { //q: 5,3,2,6,7 - if (q.isEmpty()) return null; - TreeNode root = new TreeNode(q.poll());//root (5) - Queue samllerQueue = new LinkedList<>(); - while (!q.isEmpty() && q.peek() < root.val) { - samllerQueue.offer(q.poll()); - } - //smallerQueue : 3,2 storing elements smaller than 5 (root) - root.left = getNode(samllerQueue); - //q: 6,7 storing elements bigger than 5 (root) - root.right = getNode(q); - return root; - } - -} \ No newline at end of file diff --git a/src/practiceproblems/SingleElementInSortedArray.java b/src/practiceproblems/SingleElementInSortedArray.java deleted file mode 100644 index a9ba2f3..0000000 --- a/src/practiceproblems/SingleElementInSortedArray.java +++ /dev/null @@ -1,44 +0,0 @@ -package practiceproblems; - -/** - * You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once. - * Find this single element that appears only once. - */ -public class SingleElementInSortedArray { - public int singleNonDuplicate(int[] nums) { - if (nums == null || nums.length == 0) return 0; - - int left = 0; - int right = nums.length - 1; - // for 1,1,2,3,3,4,4,8,8 - // when mid is at 4 and right-mid is even, means the rest elements are only pairs, so we check - // left side by right=mid-2 - // when mid is at 3 and right-mid is odd means the 3's duplicate is present in right and rest - //are all pairs only so we check left side by right=mid-1 - // when mid is 4 => nums[mid]==nums[mid-1] - // when mid is 3 => nums[mid]==nums[mid+1] - while (left < right) { - int mid = left + (right - left) / 2; - boolean isEven = (right - mid) % 2 == 0; - - if (nums[mid] == nums[mid - 1]) { - if (isEven) { - right = mid - 2; - } else { - left = mid + 1; - } - } else if (nums[mid] == nums[mid + 1]) { - if (isEven) { - left = mid + 2; - } else { - right = mid - 1; - } - } else { - return nums[mid]; - } - - } - - return nums[left]; - } -} \ No newline at end of file diff --git a/src/practiceproblems/SlidingWindow.java b/src/practiceproblems/SlidingWindow.java deleted file mode 100644 index 4377ea0..0000000 --- a/src/practiceproblems/SlidingWindow.java +++ /dev/null @@ -1,74 +0,0 @@ -package practiceproblems; - -import java.util.Deque; -import java.util.*; - -/** - * https://leetcode.com/problems/sliding-window-maximum/ - */ -public class SlidingWindow { - - public static void main(String[] args) { - int arr[] = { 8, 5, 10, 7, 9, 4, 15, 12, 90, 13 }; - int k = 3; - maxSlidingWindow(arr, k); - } - - public static int[] maxSlidingWindow(int[] nums, int k) { - if (nums.length == 0) { - return new int[0]; - } - if (nums.length == 1) { - return nums; - } - - List list = new ArrayList<>(); - Deque deque = new ArrayDeque<>(); - int i = 0; - - while (i < k) { - - while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) { - deque.removeLast(); - } - deque.addLast(i); - i++; - } - - for (; i < nums.length; i++) { - - list.add(nums[deque.peekFirst()]); - - if (!deque.isEmpty() && deque.peekFirst() <= i - k) { - deque.removeFirst(); - } - - while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) - deque.removeLast(); - - deque.addLast(i); - } - list.add(nums[deque.peekFirst()]); - - return list.stream().mapToInt(Integer::new).toArray(); - } - - void maxSlidingVicky(int[] nums, int k) { - List result = new ArrayList<>(); - Deque queue = new ArrayDeque<>(); - for (int i = 0; i < nums.length; i++) { - while (!queue.isEmpty() && queue.peek() < i - k + 1) { - queue.poll(); - } - while (!queue.isEmpty() && nums[queue.peekLast()] < nums[i]) { - queue.pollLast(); - } - - queue.offer(i); - - if (i >= k - 1) { - result.add(nums[queue.peekFirst()]); - } - } - } -} \ No newline at end of file diff --git a/src/practiceproblems/SnakeAndLadder.java b/src/practiceproblems/SnakeAndLadder.java deleted file mode 100644 index 2973bd6..0000000 --- a/src/practiceproblems/SnakeAndLadder.java +++ /dev/null @@ -1,70 +0,0 @@ -package practiceproblems; - -import java.util.Queue; -import java.util.*; - -/** - * https://leetcode.com/problems/snakes-and-ladders/ - */ -public class SnakeAndLadder { - class BoardCells { - int pos; - int steps; - - public BoardCells(int pos, int steps) { - this.pos = pos; - this.steps = steps; - } - } - - private int n; - - public int snakesAndLadders(int[][] board) { - n = board.length; - boolean[] visited = new boolean[n * n + 1]; - Queue queue = new LinkedList<>(); - queue.offer(new BoardCells(1, 1)); - visited[1] = true; - - while (!queue.isEmpty()) { - BoardCells cur = queue.poll(); - for (int i = 1; i <= 6; i++) { - int next = cur.pos + i; - int[] pos = numToPos(next); - if (board[pos[0]][pos[1]] > 0) { - next = board[pos[0]][pos[1]]; - } - if (next == n * n) { - return cur.steps; - } - if (!visited[next]) { - queue.offer(new BoardCells(next, cur.steps + 1)); - visited[next] = true; - } - } - - } - return queue.peek().steps; - } - - private int[] numToPos(int target) { - int row = (target - 1) / n, col = (target - 1) % n; - int x = n - 1 - row, y = row % 2 == 0 ? col : n - 1 - col; - return new int[] { x, y }; - } - - private int posToNum(int[] position) { - int row = (n - 1 - position[0]); - int y = row % 2 == 0 ? position[1] + 1 : n - position[1]; - return row * n + y; - } - - public static void main(String[] args) { - - int[][] board = { { -1, -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1, -1 }, - { -1, 35, -1, -1, 13, -1 }, { -1, -1, -1, -1, -1, -1 }, { -1, 15, -1, -1, -1, -1 } }; - - System.out.println("Min Dice throws required is " + new SnakeAndLadder().snakesAndLadders(board)); - - } -} \ No newline at end of file diff --git a/src/practiceproblems/SnakeGame.java b/src/practiceproblems/SnakeGame.java deleted file mode 100644 index bb6a32a..0000000 --- a/src/practiceproblems/SnakeGame.java +++ /dev/null @@ -1,88 +0,0 @@ -package practiceproblems; - -import java.util.HashSet; -import java.util.LinkedList; - -public class SnakeGame { - int[][] food; - int m, n; - int headX, headY; - int eaten; - private HashSet snake; - LinkedList queue; - - /** - * Initialize your data structure here. - * - * @param width - screen width - * @param height - screen height - * @param food - A list of food positions - * E.g food = [[1,1], [1,0]] means the first food is positioned at [1,1], the second is at [1,0]. - */ - public SnakeGame(int width, int height, int[][] food) { - this.food = food; - snake = new HashSet(); - eaten = 0; - headX = 0; - headY = 0; - m = height; - n = width; - queue = new LinkedList(); - queue.offer(new int[]{0, 0}); - snake.add("0,0"); - } - - /** - * Moves the snake. - * - * @param direction - 'U' = Up, 'L' = Left, 'R' = Right, 'D' = Down - * @return The game's score after the move. Return -1 if game over. - * Game over when snake crosses the screen boundary or bites its body. - */ - public int move(String direction) { - if (direction.equals("U")) { - headX--; - } else if (direction.equals("L")) { - headY--; - } else if (direction.equals("R")) { - headY++; - } else if (direction.equals("D")) { - headX++; - } else { - System.out.println("Wrong move"); - } - - if (!isValid(headX, headY)) { - return -1; - } - - return process(headX, headY); - } - - public boolean isValid(int i, int j) { - if (i < 0 || i >= m || j < 0 || j >= n) - return false; - return true; - } - - public int process(int x, int y) { - if (eaten == food.length) { - snake.remove(queue.peek()[0] + "," + queue.peek()[1]); - queue.poll(); - } else if (food[eaten][0] == x && food[eaten][1] == y) { - eaten++; - } else { - snake.remove(queue.peek()[0] + "," + queue.peek()[1]); - queue.poll(); - } - - if (snake.contains(x + "," + y)) { - return -1; - } - - snake.add(x + "," + y); - queue.offer(new int[]{x, y}); - - return eaten; - } -} \ No newline at end of file diff --git a/src/practiceproblems/SortStack.java b/src/practiceproblems/SortStack.java deleted file mode 100644 index b5146e7..0000000 --- a/src/practiceproblems/SortStack.java +++ /dev/null @@ -1,31 +0,0 @@ -package practiceproblems; - -import java.util.Stack; - -class SortStack { - // Input : [34, 3, 31, 98, 92, 23] - // Output : [3, 23, 31, 34, 92, 98] - public static Stack sortStack(Stack input) { - /* If input is null, no processing needed */ - if (input == null) { - return null; - } - /* Create a temp stack */ - Stack tempStack = new Stack<>(); - /* Keep going until input is not empty */ - while (!input.isEmpty()) { - /* Pop value from input */ - int tempValue = input.pop(); - /* - * We want smallest one at the bottom. So keep comparing and if temp stack has - * bigger item, pop it and push it to input stack - */ - while (!tempStack.isEmpty() && tempStack.peek() > tempValue) { - input.push(tempStack.pop()); - } - /* Push temp value to the temp stack */ - tempStack.push(tempValue); - } - return tempStack; - } -} \ No newline at end of file diff --git a/src/practiceproblems/SortedSquares.java b/src/practiceproblems/SortedSquares.java deleted file mode 100644 index abd3aa8..0000000 --- a/src/practiceproblems/SortedSquares.java +++ /dev/null @@ -1,28 +0,0 @@ -package practiceproblems; - -public class SortedSquares { - // Input: [-7,-3,2,3,11] - // Output: [4,9,9,49,121] - public int[] sortedSquares(int[] A) { - if(A==null || A.length==0) return new int[0]; - - int[]result= new int[A.length]; - - int index= A.length-1; - int left=0; - int right=index; - - while(left<=right){ - if(Math.abs(A[left]) result = new ArrayList<>(); - - int i = 0; - while (i < n - 1) { - // Find Local Minima. Note that the limit is (n-2) as we are - // comparing present element to the next element. - while ((i < n - 1) && (price[i + 1] <= price[i])) - i++; - - // If we reached the end, break as no further solution possible - if (i == n - 1) { - break; - } - - Interval e = new Interval(); - e.buy = i++; - // Store the index of minima - - // Find Local Maxima. Note that the limit is (n-1) as we are - // comparing to previous element - while ((i < n) && (price[i] >= price[i - 1])) - i++; - - // Store the index of maxima - e.sell = i - 1; - result.add(e); - - // Increment number of buy/sell - count++; - } - - if (count == 0) { - System.out.println("There is no day when buying the stock " + "will make profit"); - } else { - for (int j = 0; j < count; j++) - System.out.println( - "Buy on day: " + result.get(j).buy + " " + "Sell on day : " + result.get(j).sell); - } - - return; - } - - public static void main(String args[]) { - StockBuySellManyTimes stock = new StockBuySellManyTimes(); - - int price[] = { 200, 180, 260, 310, 40, 535, 695 }; - int n = price.length; - - stock.stockBuySell(price, n); - } -} diff --git a/src/practiceproblems/StockSpanner.java b/src/practiceproblems/StockSpanner.java deleted file mode 100644 index 58babe4..0000000 --- a/src/practiceproblems/StockSpanner.java +++ /dev/null @@ -1,21 +0,0 @@ -package practiceproblems; - - -class StockSpanner { -// -// Deque> stack; -// public StockSpanner() { -// this.stack= new ArrayDeque<>(); -// } -// -// public int next(int price) { -// int value=1; -// while(!stack.isEmpty() && stack.peek().fst<=price){ -// value+=stack.pop().snd; -// } -// -// stack.push(new Pair(price,value)); -// -// return stack.peek().snd; -// } -} \ No newline at end of file diff --git a/src/practiceproblems/StringIterator.java b/src/practiceproblems/StringIterator.java deleted file mode 100644 index f7ecb37..0000000 --- a/src/practiceproblems/StringIterator.java +++ /dev/null @@ -1,37 +0,0 @@ -package practiceproblems; - -//StringIterator iterator = new StringIterator("L1e2t1C1o1d1e1"); -// iterator.next(); // return 'L' -// iterator.next(); // return 'e' -// iterator.next(); // return 'e' -// iterator.next(); // return 't' -// iterator.next(); // return 'C' -// iterator.next(); // return 'o' -// iterator.next(); // return 'd' -// iterator.hasNext(); // return true -// iterator.next(); // return 'e' -// iterator.hasNext(); // return false -// iterator.next(); // return ' ' -public class StringIterator { - String res; - int ptr = 0, num = 0; - char ch = ' '; - public StringIterator(String s) { - res = s; - } - public char next() { - if (!hasNext()) - return ' '; - if (num == 0) { - ch = res.charAt(ptr++); - while (ptr < res.length() && Character.isDigit(res.charAt(ptr))) { - num = num * 10 + res.charAt(ptr++) - '0'; - } - } - num--; - return ch; - } - public boolean hasNext() { - return ptr != res.length() || num != 0; - } -} \ No newline at end of file diff --git a/src/practiceproblems/SumOfThreeElements.java b/src/practiceproblems/SumOfThreeElements.java deleted file mode 100644 index 1a604fc..0000000 --- a/src/practiceproblems/SumOfThreeElements.java +++ /dev/null @@ -1,39 +0,0 @@ -package practiceproblems; - -import java.util.Arrays; - -public class SumOfThreeElements { - - public static void main(String[] args) { - int arr[] = {1, 4, 45, 6, 10, 8}; - int sum = 22; - SumOfThreeElements ste = new SumOfThreeElements(); - ste.findTriplets(arr, sum); - } - - private boolean findTriplets(int[] arr, int sum) { - - int arrSize = arr.length; - Arrays.sort(arr); - - for (int i = 0; i < arrSize; i++) { - - int left = i + 1; - int right = arrSize - 1; - - while (left < right) { - int result = arr[i] + arr[left] + arr[right]; - if (result == sum) { - System.out.println("triplet found" + i + "+" + left + "+" + right); - break; - } else if (result < sum) { - left++; - } else { - right--; - } - } - } - - return false; - } -} diff --git a/src/practiceproblems/TaskLeastInterval.java b/src/practiceproblems/TaskLeastInterval.java deleted file mode 100644 index fa43bcb..0000000 --- a/src/practiceproblems/TaskLeastInterval.java +++ /dev/null @@ -1,55 +0,0 @@ -package practiceproblems; - -import java.util.*; - -/** - * https://leetcode.com/problems/task-scheduler/ - */ - - -public class TaskLeastInterval { - - public static int leastInterval(char[] tasks, int n) { - Map map = new HashMap<>(); - for (char task : tasks) { - map.put(task, map.getOrDefault(task, 0) + 1); - } - PriorityQueue> queue = new PriorityQueue<>( - (a, b) -> Integer.compare(b.getValue(), a.getValue())); - - queue.addAll(map.entrySet()); - - int count = 0; - // At each iteration, we process at most 'n' elements, - // and move forwards exactly n+1 in time (regardless of how many elements we processed: - // Read the topmost from the queue and increment the time. Add it to a temp list to be added later. - // Add the element back to the queue from the temp list if count is > 0. - // if al elements are done, we're done too. - // Move time forward by n + 1 - // Return time in the end. - while (!queue.isEmpty()) { - int k = n + 1; //each time fill k elements, if k is not full, that's the idle - List tempList = new ArrayList<>(); - while (k > 0 && !queue.isEmpty()) { - Map.Entry top = queue.poll(); - top.setValue(top.getValue() - 1); - tempList.add(top); - k--; - count++; - } - - for (Map.Entry e : tempList) { - if (e.getValue() > 0) queue.add(e); // add valid tasks - } - - if (queue.isEmpty()) break; - count = count + k; // if k > 0, then it means we need to be idle - } - return count; - } - - public static void main(String[] args) { - char[] arr = "A".toCharArray(); - System.out.println(leastInterval(arr, 2)); - } -} diff --git a/src/practiceproblems/ThreeSum.java b/src/practiceproblems/ThreeSum.java deleted file mode 100644 index 4932aea..0000000 --- a/src/practiceproblems/ThreeSum.java +++ /dev/null @@ -1,40 +0,0 @@ -package practiceproblems; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class ThreeSum { - public List> threeSum(int[] nums) { - if(nums==null || nums.length==0) return Collections.emptyList(); - - Arrays.sort(nums); - List> result= new ArrayList<>(); - for(int i=0;isum){ - right--; - } - } - } - } - - return result; - } -} \ No newline at end of file diff --git a/src/practiceproblems/TopKFrequentElement.java b/src/practiceproblems/TopKFrequentElement.java deleted file mode 100644 index bcda327..0000000 --- a/src/practiceproblems/TopKFrequentElement.java +++ /dev/null @@ -1,38 +0,0 @@ -package practiceproblems; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -class TopKFrequentElement{ - public List topKFrequent(int[] nums, int k) { - List result = new ArrayList<>(); - - Map map = new HashMap<>(); //Key: val, Val: #of freq - for (int num : nums) { - if (map.containsKey(num)) { - map.put(num, map.get(num)+1); - }else { - map.put(num, 1); - } - } - - List[] bucks = new List[nums.length+1]; // index : freq; val: set of key - for (int key : map.keySet()) { - int freq = map.get(key); - if (bucks[freq] == null) { - bucks[freq] = new ArrayList<>(); - } - bucks[freq].add(key); - } - - for (int freq = nums.length; freq >=0 && k > 0; freq--) { - if (bucks[freq] != null) { - k -=bucks[freq].size(); - result.addAll(bucks[freq]); - } - } - return result; - } -} \ No newline at end of file diff --git a/src/practiceproblems/VulgarDecimal.java b/src/practiceproblems/VulgarDecimal.java deleted file mode 100644 index f767a12..0000000 --- a/src/practiceproblems/VulgarDecimal.java +++ /dev/null @@ -1,115 +0,0 @@ -package practiceproblems; - -/** - * https://leetcode.com/problems/fraction-to-recurring-decimal/ - *

- * Given two integers representing the numerator and denominator of a fraction, return the fraction in string format. - *

- * If the fractional part is repeating, enclose the repeating part in parentheses. - *

- * If multiple answers are possible, return any of them. - *

- * It is guaranteed that the length of the answer string is less than 104 for all the given inputs. - *

- * Input: numerator = 1, denominator = 2 - * Output: "0.5" - *

- * Input: numerator = 2, denominator = 1 - * Output: "2" - */ - - -import java.util.*; - -public class VulgarDecimal { - - public static String fractionToDecimal(long numerator, long denominator) { - if (denominator == 0) return null; - // if both are negative then the ans would be positive - boolean isNegative = (numerator < 0 && denominator > 0) || (numerator > 0 && denominator < 0); - - long denomiL = Math.abs(denominator); - long numerL = Math.abs(numerator); - - Map map = new HashMap<>(); - - StringBuilder sb = new StringBuilder(); - - sb.append((numerL / denomiL)); - - if (numerL % denomiL != 0) { - sb.append("."); - } - if (isNegative) sb.insert(0, "-"); - - numerL %= denomiL; - - if (numerL == 0) return sb.toString(); - - map.put(numerL, sb.length()); - - while (numerL > 0) { - - numerL *= 10; - sb.append((numerL / denomiL)); - numerL = (numerL % denomiL); - - if (map.containsKey(numerL)) { - int index = map.get(numerL); - sb.insert(index, "("); - sb.append(")"); - break; - } else { - map.put(numerL, sb.length()); - } - } - - return sb.toString(); - } - - public String fractionToDecimal(int numerator, int denominator) { - - boolean isNegative= numerator<0 && denominator>0 || numerator>0 && denominator<0; - - StringBuilder sb= new StringBuilder(); - Map map= new HashMap<>(); - long numeratorL= Math.abs(Long.valueOf(numerator)); - long denominatorL= Math.abs(Long.valueOf(denominator)); - - long rem=numeratorL/denominatorL; - sb.append(rem); - - - - if(isNegative) sb.insert(0,'-'); - - if(numeratorL%denominatorL>0){ - sb.append("."); - }else{ - return sb.toString(); - } - numeratorL%=denominatorL; - map.put(numeratorL,sb.length()); - - while(numeratorL>0){ - numeratorL*=10; - - rem=numeratorL/denominatorL; - sb.append(rem); - numeratorL%=denominatorL; - if(map.containsKey(numeratorL)){ - int pos= map.get(numeratorL); - sb.insert(pos,"("); - sb.append(")"); - break; - }else{ - map.put(numeratorL,sb.length()); - } - - } - - return sb.toString(); - } - - -} diff --git a/src/practiceproblems/WaterTrapping.java b/src/practiceproblems/WaterTrapping.java deleted file mode 100644 index 1df9f1b..0000000 --- a/src/practiceproblems/WaterTrapping.java +++ /dev/null @@ -1,37 +0,0 @@ -package practiceproblems; - -class WaterTrapping { - - static int findWater(int arr[], int n) { - int result = 0; - int leftMax = 0; - int rightMax = 0; - int low = 0; - int high = n - 1; - - while (low < high) { - if (arr[low] < arr[high]) { - if (arr[low] > leftMax) { - leftMax = arr[low]; - } else { - result += leftMax - arr[low]; - } - low++; - } else { - if (arr[high] > rightMax) { - rightMax = arr[high]; - } else { - result += rightMax - arr[high]; - } - high--; - } - } - return result; - } - - public static void main(String[] args) { - int arr[] = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1}; - int n = arr.length; - System.out.println("Maximum water that " + "can be accumulated is " + findWater(arr, n)); - } -} \ No newline at end of file diff --git a/src/practiceproblems/WordBreak.java b/src/practiceproblems/WordBreak.java deleted file mode 100644 index 653dadb..0000000 --- a/src/practiceproblems/WordBreak.java +++ /dev/null @@ -1,83 +0,0 @@ -package practiceproblems; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -class WordBreak { - - /* -|T| | | | | | | | | - 0 1 2 3 4 5 6 7 8 - -i = 1 -j = o sub = l - -i = 2 -j = 0 sub = le -j = 1 sub = e - -i = 3 -j = 0 sub = lee -j = 1 sub = ee -j = 2 sub = e - -i = 4 -j = 0 sub = leet && T[0] and then break, no need to check for rest -|T | | | |T| | | | | -0 1 2 3 4 5 6 7 8 - -i = 5 -j = 0 sub = leetc -j = 1 sub = eetc -j = 2 sub = etc -j = 3 sub = tc -j = 4 sub = c - -i = 6 -j = 0 sub = leetco -j = 1 sub = eetco -j = 2 sub = etco -j = 3 sub = tco -j = 4 sub = co -j = 5 sub = o - -i = 7 -j = 0 sub = leetcod -j = 1 sub = eetcod -j = 2 sub = etcod -j = 3 sub = tcod -j = 4 sub = cod -j = 5 sub = od -j = 6 sub = d - -i = 8 -j = 0 sub = leetcode -j = 1 sub = eetcode -j = 2 sub = etcode -j = 3 sub = tcode -j = 4 sub = code && T[4] and then break - -|T| | | |T| | | |T| - 0 1 2 3 4 5 6 7 8 -*/ - public boolean wordBreak(String s, List wordDict) { - if (s == null) { - return false; - } - boolean[] dp = new boolean[s.length() + 1]; - dp[0] = true; - Set set = new HashSet<>(wordDict); - - for (int i = 1; i <= s.length(); i++) { - for (int j = 0; j < i; j++) { - dp[i] = dp[j] && set.contains(s.substring(j, i)); - if (dp[i]) { - break; - } - } - } - - return dp[s.length()]; - } -} \ No newline at end of file diff --git a/src/practiceproblems/WordBreakII.java b/src/practiceproblems/WordBreakII.java deleted file mode 100644 index 3b043e9..0000000 --- a/src/practiceproblems/WordBreakII.java +++ /dev/null @@ -1,33 +0,0 @@ -package practiceproblems; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class WordBreakII { - public List wordBreak(String s, List wordDict) { - Map> cache = new HashMap<>(); - backtrack(s,wordDict, cache); - return cache.get(s); - } - - public List backtrack(String s, List wordDict, Map> cache){ - - if(cache.containsKey(s)) return cache.get(s); - - List result = new ArrayList<>(); - for(String word: wordDict) { - if(!s.startsWith(word)) continue; // string does not start with this word? - String next = s.substring(word.length()); - if(next.isEmpty()) { // awesome! - result.add(word); - continue; - } - for(String sub: backtrack(next, wordDict, cache)) - result.add(word + " " + sub); - } - cache.put(s, result); - return result; - } -} \ No newline at end of file diff --git a/src/practiceproblems/WordDictionary.java b/src/practiceproblems/WordDictionary.java deleted file mode 100644 index ef50133..0000000 --- a/src/practiceproblems/WordDictionary.java +++ /dev/null @@ -1,69 +0,0 @@ -package practiceproblems; - -import java.util.HashMap; -import java.util.Map; - -/** - * Design a data structure that supports the following two operations: - * void addWord(word) - * bool search(word) - * search(word) can search a literal word or - * a regular expression string containing only letters a-z or .. A . - * means it can represent any one letter. - * addWord("bad") - addWord("dad") - addWord("mad") - search("pad") -> false - search("bad") -> true - search(".ad") -> true - search("b..") -> true - */ -public class WordDictionary { - private TrieNode root; - - /** Initialize your data structure here. */ - private class TrieNode { - public Map children = new HashMap<>(); - public boolean isWord; - } - - public WordDictionary() { - root = new TrieNode(); - } - - /** Adds a word into the data structure. */ - public void addWord(String word) { - - TrieNode temp = root; - - for (char c : word.toCharArray()) { - if (temp.children.get(c) == null) - temp.children.put(c, new TrieNode()); - - temp = temp.children.get(c); - } - - temp.isWord = true; - } - - /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ - public boolean search(String word) { - return match(word.toCharArray(), 0, root); - } - - private boolean match(char[] chs, int k, TrieNode node) { - - if (k == chs.length) - return node.isWord; - - if (chs[k] == '.') { - for (Character curr: node.children.keySet()) { - if (node.children.get(curr) != null && match(chs, k+1, node.children.get(curr))) - return true; - } - } else - return node.children.get(chs[k]) != null && match(chs, k + 1, node.children.get(chs[k])); - - return false; - } -} \ No newline at end of file diff --git a/src/practiceproblems/WordLadder.java b/src/practiceproblems/WordLadder.java deleted file mode 100644 index 1627fb8..0000000 --- a/src/practiceproblems/WordLadder.java +++ /dev/null @@ -1,45 +0,0 @@ -package practiceproblems; - -import java.util.*; - -public class WordLadder { - public int ladderLength(String beginWord, String endWord, List wordList) { - Set set = new HashSet(wordList); - if(!set.contains(endWord)) return 0; // end word itself not in set - Queue queue = new LinkedList(); - queue.add(beginWord); - int count = 1; - - while(!queue.isEmpty()) { - - int size = queue.size(); - for (int i =0; i (childIndex - 1) / 2 - Left Child -> 2 * parentIndex + 1 - Right Child -> 2 * parentIndex + 2 - - YouTube explanation: https://www.youtube.com/watch?v=g9YK6sftDi0 - Heap Sort explanation: https://www.youtube.com/watch?v=k72DtCnY4MU -*/ -import java.util.*; - -public class ImplementABinaryHeap { - int[] insertItems = new int[]{ 0, 1, 3, 2, -4, 9, 1, 2 }; - public static void main(String args[]) { - MinHeap minHeap = new MinHeap(); - int[] insertItems = new int[]{ 0, 1, 3, 2, -4, 9, 1, 2 }; - - for (int i = 0; i < insertItems.length; i++) { - minHeap.add(insertItems[i]); - System.out.println("Add " + insertItems[i]); - System.out.println("Min is " + minHeap.peek()); - - minHeap.printUnderlyingArray(); - - System.out.println("\n"); - } - - System.out.println("\n\n"); - - for (int i = 0; i < insertItems.length; i++) { - System.out.println("Remove " + minHeap.remove()); - System.out.println("Min is " + minHeap.peek()); - - minHeap.printUnderlyingArray(); - - System.out.println("\n"); - } - } - - private static class MinHeap { - private int capacity = 5; - private int heap[]; - private int size; - // int[] temp= new ImplementABinaryHeap().insertItems; - public MinHeap() { - heap = new int[capacity]; - } - - public boolean isEmpty() { - return size == 0; - } - - public int peek() { - if (isEmpty()) { - throw new NoSuchElementException("Heap is empty."); - } - - return heap[0]; - } - - public int remove() { - if (isEmpty()) { - throw new NoSuchElementException("Heap is empty."); - } - - /* - -> Grab the min item. It is at index 0. - -> Move the last item in the heap to the "top" of the - heap at index 0. - -> Reduce size. - */ - int minItem = heap[0]; - heap[0] = heap[size - 1]; - size--; - - /* - Restore the heap since it is very likely messed up now - by bubbling down the element we swapped up to index 0 - */ - heapifyDown(); - - return minItem; - } - - public void add(int itemToAdd) { - ensureExtraCapacity(); - - /* - -> Place the item at the bottom, far right, of the - conceptual binary heap structure - -> Increment size - */ - heap[size] = itemToAdd; - size++; - - /* - Restore the heap since it is very likely messed up now - by bubbling up the element we just put in the last empty - position of the conceptual complete binary tree - */ - siftUp(); - } - - /*********************************** - Heap restoration helpers - ***********************************/ - - private void heapifyDown() { - /* - We will bubble down the item just swapped to the "top" of the heap - after a removal operation to restore the heap - */ - int index = 0; - - /* - Since a binary heap is a complete binary tree, if we have no left child - then we have no right child. So we continue to bubble down as long as - there is a left child. - - A non-existent left child immediately tells us that a right child does - not exist. - */ - while (hasLeftChild(index)) { - /* - By default assume that left child is smaller. If a right - child exists see if it can overtake the left child by - being smaller - */ - int smallerChildIndex = getLeftChildIndex(index); - if (hasRightChild(index) && rightChild(index) < leftChild(index)) { - smallerChildIndex = getRightChildIndex(index); - } - - /* - If the item we are sitting on is < the smaller child then - nothing needs to happen & sifting down is finished. - - But if the smaller child is smaller than the node we are - holding, we should swap and continue sifting down. - */ - if (heap[index] < heap[smallerChildIndex]) { - break; - } else { - swap(index, smallerChildIndex); - } - - // Move to the node we just swapped down - index = smallerChildIndex; - } - } - - // Bubble up the item we inserted at the "end" of the heap - private void siftUp() { - /* - We will bubble up the item just inserted into to the "bottom" - of the heap after an insert operation. It will be at the last index - so index 'size' - 1 - */ - int index = size - 1; - - /* - While the item has a parent and the item beats its parent in - smallness, bubble this item up. - */ - while (hasParent(index) && heap[index] < parent(index)) { - swap(getParentIndex(index), index); - index = getParentIndex(index); - } - } - - /************************************************ - Helpers to access our array easily, perform - rudimentary operations, and manipulate capacity - ************************************************/ - - private void swap(int indexOne, int indexTwo) { - int temp = heap[indexOne]; - heap[indexOne] = heap[indexTwo]; - heap[indexTwo] = temp; - } - - // If heap is full then double capacity - private void ensureExtraCapacity() { - if (size == capacity) { - heap = Arrays.copyOf(heap, capacity * 2); - capacity *= 2; - } - } - - private int getLeftChildIndex(int parentIndex) { - return 2 * parentIndex + 1; - } - - private int getRightChildIndex(int parentIndex) { - return 2 * parentIndex + 2; - } - - private int getParentIndex(int childIndex) { - return (childIndex - 1) / 2; - } - - private boolean hasLeftChild(int index) { - return getLeftChildIndex(index) < size; - } - - private boolean hasRightChild(int index) { - return getRightChildIndex(index) < size; - } - - private boolean hasParent(int index) { - return index != 0 && getParentIndex(index) >= 0; - } - - private int leftChild(int index) { - return heap[getLeftChildIndex(index)]; - } - - private int rightChild(int index) { - return heap[getRightChildIndex(index)]; - } - - private int parent(int index) { - return heap[getParentIndex(index)]; - } - - /***********************************************/ - - private void printUnderlyingArray() { - System.out.print("[ "); - for (int item: heap) { - System.out.print(item + " "); - } - System.out.print("]"); - } - } -} \ No newline at end of file diff --git a/src/sorting/InsertionSort.java b/src/sorting/InsertionSort.java deleted file mode 100644 index 2eafe7e..0000000 --- a/src/sorting/InsertionSort.java +++ /dev/null @@ -1,30 +0,0 @@ -package sorting; - -public class InsertionSort { - - public static void main(String[] args) { - int[] arr = { 12, 11, 13, 5, 6 }; -System.out.println(System.currentTimeMillis()); - - for (int i = 1; i < arr.length; i++) { - int index =i; - for (int j = i-1; j >= 0; j--) { - int value = arr[index]; - if (arr[index] < arr[j]) { - int temp = arr[j]; - arr[j] = value; - arr[index] = temp; - index--; - }else{ - continue; - } - } - } - System.out.println(System.currentTimeMillis()); - - for (int i = 0; i < arr.length; i++) { - System.out.println(arr[i]); - } - } - -} diff --git a/src/sorting/MaxHeap.java b/src/sorting/MaxHeap.java deleted file mode 100644 index 577bcfe..0000000 --- a/src/sorting/MaxHeap.java +++ /dev/null @@ -1,51 +0,0 @@ -package sorting; - -public class MaxHeap { - - public static void main(String[] args) { - int arr[] = { 7, 4, 55, 2, 77, 54, 3, 1, 12, 16, 19, 20 }; - MaxHeap heap = new MaxHeap(); - heap.sort(arr); - - } - - private void sort(int[] arr) { - int n = arr.length; - - for (int i = n / 2 - 1; i >= 0; i--) - heapify(arr, i, n); - - for (int i = 0; i < n; i++) - System.out.print(arr[i] + " "); - - System.out.println(); - for (int i = n - 1; i >= 0; i--) { - int temp = arr[0]; - arr[0] = arr[i]; - arr[i] = temp; - - heapify(arr, 0, i); - } - - for (int i = 0; i < n; i++) - System.out.print(arr[i] + " "); - } - - private void heapify(int[] arr, int i, int n) { - int largest = i; - int left = 2 * i + 1; - int right = 2 * i + 2; - - if (left < n && arr[left] > arr[largest]) - largest = left; - if (right < n && arr[right] > arr[largest]) - largest = right; - if (largest != i) { - int temp = arr[largest]; - arr[largest] = arr[i]; - arr[i] = temp; - - heapify(arr, largest, n); - } - } -} \ No newline at end of file diff --git a/src/strings/stringmatching/KMP.java b/src/strings/stringmatching/KMP.java deleted file mode 100644 index 17a9609..0000000 --- a/src/strings/stringmatching/KMP.java +++ /dev/null @@ -1,58 +0,0 @@ -package strings.stringmatching; - -import java.util.Arrays; - -public class KMP { - - public static void main(String[] args) { - String given = "abxabcabcabyasd"; - String pattern = "abcaby"; - int[] arr = formPrefixAndSuffixArray(pattern); - System.out.println(Arrays.toString(arr)); - System.out.println(kmp(arr, given.toCharArray(), pattern.toCharArray())); - } - - - private static boolean kmp(int[] arr, char[] charArray, char[] cs) { - - int j = 0; - int i = 0; - while (j < cs.length && i < charArray.length) { - if (cs[j] == charArray[i]) { - j++; - i++; - } else { - if (j != 0) { - j = arr[j - 1]; - } else { - i++; - } - } - } - - return j == arr.length; - } - - private static int[] formPrefixAndSuffixArray(String pattern) { - - char[] arr = pattern.toCharArray(); - int value = 0; - int[] valueArr = new int[arr.length]; - valueArr[0] = 0; - for (int i = 1; i < arr.length;) { - if (arr[value] == arr[i]) { - valueArr[i] = ++value; - i++; - } else { - if (value != 0) { - value = valueArr[value - 1]; - } else { - valueArr[i] = 0; - i++; - } - } - } - return valueArr; - } - -} diff --git a/src/strings/stringmatching/RabinKarp.java b/src/strings/stringmatching/RabinKarp.java deleted file mode 100644 index e900d05..0000000 --- a/src/strings/stringmatching/RabinKarp.java +++ /dev/null @@ -1,60 +0,0 @@ -package strings.stringmatching; - -public class RabinKarp { - - private int prime = 101; - - public int patternSearch(char[] text, char[] pattern) { - int m = pattern.length; - int n = text.length; - long patternHash = createHash(pattern, m - 1); - long textHash = createHash(text, m - 1); - for (int i = 1; i <= n - m + 1; i++) { - if (patternHash == textHash && checkEqual(text, i - 1, i + m - 2, pattern, 0, m - 1)) { - return i - 1; - } - if (i < n - m + 1) { - textHash = recalculateHash(text, i - 1, i + m - 1, textHash, m); - } - } - return -1; - } - - private long recalculateHash(char[] str, int oldIndex, int newIndex, long oldHash, int patternLen) { - long newHash = oldHash - str[oldIndex]; - newHash = newHash / prime; - newHash += str[newIndex] * Math.pow(prime, patternLen - 1); - return newHash; - } - - private long createHash(char[] str, int end) { - long hash = 0; - for (int i = 0; i <= end; i++) { - hash += str[i] * Math.pow(prime, i); - } - return hash; - } - - private boolean checkEqual(char[] str1, int start1, int end1, char[] str2, int start2, int end2) { - if (end1 - start1 != end2 - start2) { - return false; - } - while (start1 <= end1 && start2 <= end2) { - if (str1[start1] != str2[start2]) { - return false; - } - start1++; - start2++; - } - return true; - } - - public static void main(String args[]) { - RabinKarp rks = new RabinKarp(); - // System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "sharRoy".toCharArray())); - System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "Roy".toCharArray())); -/* System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "shas".toCharArray())); - System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "usha".toCharArray())); - System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "Tus".toCharArray()));*/ - } -} diff --git a/src/trees/BinaryTraversalIterative.java b/src/trees/BinaryTraversalIterative.java deleted file mode 100644 index 76a3442..0000000 --- a/src/trees/BinaryTraversalIterative.java +++ /dev/null @@ -1,62 +0,0 @@ -package trees; - -import java.util.*; - -/** - * https://leetcode.com/problems/binary-tree-inorder-traversal/ - * https://leetcode.com/problems/binary-tree-preorder-traversal/ - * - */ -public class BinaryTraversalIterative { - public List inorderTraversal(TreeNode root) { - List result = new ArrayList<>(); - if (root == null) return result; - - Deque stack = new ArrayDeque<>(); - TreeNode cur = root; - - while (cur != null || !stack.isEmpty()) { - while (cur != null) { - stack.add(cur); - cur = cur.left; - } - cur = stack.pop(); - result.add(cur.val); - cur = cur.right; - } - - - return result; - } - - - public List preorderTraversal(TreeNode root) { - if (root == null) return new ArrayList<>(); - Deque stack = new ArrayDeque<>(); - stack.push(root); - List list = new LinkedList<>(); - while (!stack.isEmpty()) { - TreeNode temp = stack.pop(); - list.add(temp.val); - if (temp.right != null) stack.push(temp.right); - if (temp.left != null) stack.push(temp.left); - } - - return list; - } - - public List postorderTraversal(TreeNode root) { - if(root==null) return new ArrayList<>(); - Deque stack = new ArrayDeque<>(); - LinkedList result= new LinkedList<>(); - stack.push(root); - while(!stack.isEmpty()){ - TreeNode temp= stack.pop(); - result.addFirst(temp.val); - if(temp.left!=null) stack.push(temp.left); - if(temp.right!=null) stack.push(temp.right); - } - - return result; - } -} \ No newline at end of file diff --git a/src/trees/LCA.java b/src/trees/LCA.java deleted file mode 100644 index 41e6503..0000000 --- a/src/trees/LCA.java +++ /dev/null @@ -1,67 +0,0 @@ -package trees; - -public class LCA { - - /** - *Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. - * - * According to the definition of LCA on Wikipedia: - * “The lowest common ancestor is defined between - * two nodes p and q as the lowest node in T that has both p and q as descendants - * (where we allow a node to be a descendant of itself).” - * p and q will exist in the tree. - */ - public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { - if(root==null) return null; - if(root.val==p.val || root.val==q.val) return root; - - TreeNode left=lowestCommonAncestor( root.left, p,q); - TreeNode right= lowestCommonAncestor(root.right,p,q); - - if(left!=null && right!=null ) return root; - if(left!=null) return left; - return right; - - } - - /** - * the variation with the LCA is that - * It is guaranteed that both p and q are in the tree. - * A node can be a descendant of itself. - * In the case of p = 5 and q = 4: - * Because of the premises, we can return either p OR q as soon as we find one of them. - * But for this question, the premises are different: - * It is NOT guaranteed that both p and q are in the tree. - * A node can still be a descendant of itself. - * Hence, - * We need a way to record if we've seen both p and q - * We need to traverse the entire tree even after we've found one of them. - * Here are the differences in code. The rest is the same. - * Use either boolean or integers as flags - * Keep traversing down the entire tree. If you return early, the above example would be null, - * because the code stops when it finds 5 and does not keep searching for 4. - */ - - boolean pFound = false; - boolean qFound = false; - - public TreeNode lowestCommonAncestorII(TreeNode root, TreeNode p, TreeNode q) { - TreeNode LCA = LCA(root, p, q); - return pFound && qFound ? LCA : null; - } - - public TreeNode LCA(TreeNode root, TreeNode p, TreeNode q) { - if (root == null) return root; - TreeNode left = LCA(root.left, p, q); - TreeNode right = LCA(root.right, p, q); - if (root == p) { - pFound = true; - return root; - } - if (root == q) { - qFound = true; - return root; - } - return left == null ? right : right == null ? left : root; - } -} diff --git a/src/trees/PathSum.java b/src/trees/PathSum.java deleted file mode 100644 index ed1fa37..0000000 --- a/src/trees/PathSum.java +++ /dev/null @@ -1,85 +0,0 @@ -package trees; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class PathSum { - - List list= new ArrayList<>(); - int count=0; - - /** - * Given the root of a binary tree and an integer targetSum, - * return true if the tree has a root-to-leaf - * path such that adding up all the values along the path equals targetSum. - * - * A leaf is a node with no children. - */ - public boolean hasPathSum(TreeNode root, int targetSum) { - if(root==null) return false; - if(root.left==null && root.right==null && targetSum-root.val==0) return true; - boolean left= hasPathSum(root.left, targetSum-root.val); - boolean right= hasPathSum(root.right, targetSum-root.val); - - return left||right; - } - - /** - * Given the root of a binary tree and an integer targetSum, - * return all root-to-leaf paths where each path's sum equals targetSum. - * - * A leaf is a node with no children. - * - * Input: root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22 - * Output: [[5,4,11,2],[5,8,4,5]] - */ - - public List> pathSum(TreeNode root, int targetSum) { - if(root==null) return Collections.emptyList(); - List> result= new ArrayList<>(); - pathSumUtil(root, result, targetSum, new ArrayList<>()); - return result; - } - - public void pathSumUtil(TreeNode root,List> result,int targetSum, List tempList){ - if(root==null) return ; - tempList.add(root.val); - if(root.left==null && root.right==null && targetSum-root.val==0){ - result.add(new ArrayList<>(tempList)); - } - - pathSumUtil(root.left,result,targetSum-root.val,tempList); - pathSumUtil(root.right,result,targetSum-root.val,tempList); - tempList.remove(tempList.size()-1); - } - - /** - * You are given a binary tree in which each node contains an integer value. - * - * Find the number of paths that sum to a given value. - * - * The path does not need to start or end at the root or a leaf, - * but it must go downwards (traveling only from parent nodes to child nodes). - * - * The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000. - */ - public int pathSumIII(TreeNode root, int sum) { - if(root==null) return 0; - list.add(root.val); - pathSumIII(root.left,sum); - pathSumIII(root.right,sum); - - int k=0; - for(int i=list.size()-1;i>=0;i--){ // coming in reverse order, inorder to avoid considering - // head node - k+=list.get(i); - if(sum==k){ - count++; - } - } - - list.remove(list.size()-1); - return count; - } -} diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..7b182e0 --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,985 @@ +practiceproblems/CountMinimumStepsToFormDesiredInputArray.class +graph/leetcode/SentenceSimilarityII$UnionFind.class +practiceproblems/CheckPalindromePermutation.class +graph/cycle/Edge.class +multithreading/educative/DeferredCallbackExecutor.class +practiceproblems/jumpGame/VideoStitching.class +machinecoding/splitwise/ExpenseService$1.class +dynamicProgramming/palindrome/LongestPalindromicSubstring.class +practiceproblems/design/UndergroundSystem$Passenger.class +reflections/dynamicProxy/external/impl/HttpClient.class +graph/interview/DisjointSet$Node.class +practiceproblems/stack/AsteroidCollision.class +internals/QuadTree$Point.class +practiceproblems/MaxSumTwoNonOverlappingSubArray.class +reflections/dynamicProxy/external/impl/DatabaseReaderImpl.class +binarysearch/FirstBadVersion.class +graph/leetcode/MatrixStoneRemoval$UnionFind.class +linkedLists/Top20LinkedListQuestions.class +lld/auctionSystem/services/strategies/BuyerViewAuctionDetails.class +graph/cycle/CycleUndirectedGraph.class +graph/leetcode/EquationEquality.class +practiceproblems/tries/MapSum$TrieNode.class +practiceproblems/TrailingZeroes.class +multithreading/com/safecabs/exceptions/UnRegisteredPassengerException.class +reflections/methodDiscovery/ProductTest.class +graph/leetcode/NewRoadsMST.class +dynamicProgramming/AssemblyLineScheduling.class +practiceproblems/MinimumWindowSubstring.class +binarysearch/NumberOfDaysToMakeMBouquets.class +graph/bellmanFord/NegativeException.class +binarysearch/ShipPackageWithNDays.class +graph/shortestPath/Graph.class +practiceproblems/tries/WordDictionary.class +practiceproblems/design/TimeMap.class +lld/vendingmachine/HasMoneyState.class +practiceproblems/ConstructBSTFromPreorder.class +linkedLists/MergeTwoLinkedList.class +linkedLists/FlattenLinkedList.class +practiceproblems/ConstructTreeFromInorderAndPreorder.class +practiceproblems/recursion/SudokuSolver.class +practiceproblems/ComplexNumberMultiply.class +practiceproblems/NonDecreasingArray.class +graph/leetcode/GraphBiPartite.class +multithreading/thread/PrintOddEvenByTwoThreads$EvenThread.class +practiceproblems/design/LRUCache1$1.class +graph/primsAlgorithm/BinaryMinHeap$Node.class +lld/auctionSystem/enums/Channel.class +reflections/topologicalsort/annotations/Annotations$FinalResult.class +lld/auctionSystem/repository/SellerRepository.class +graph/leetcode/MinPathHavingMaxDifference.class +graph/bellmanFord/Vertex.class +dynamicProgramming/BoxStacking.class +practiceproblems/intervals/BalloonBurst.class +reflections/init/Main.class +practiceproblems/BackspaceCompare.class +dynamicProgramming/lcs/TwoStringInterleavingToFormThird.class +reflections/game/internal/ComputerPlayer.class +graph/kruskalAlgorithm/KruskalMST.class +strings/stringProblems/Combination.class +java8/Functional.class +machinecoding/splitwise/ExpenseService.class +practiceproblems/DungeonGame.class +dynamicProgramming/lcs/RussianDollEnvelope.class +reflections/dynamicProxy/external/impl/DatabaseReader.class +machinecoding/splitwise/ExactSplit.class +lld/auctionSystem/services/PublisherService.class +practiceproblems/KthSmallestMatrix.class +practiceproblems/LongestConsequtiveSequence.class +practiceproblems/FindPairs.class +practiceproblems/PlusOne.class +lld/auctionSystem/models/Event.class +graph/leetcode/AllPathsInGraph.class +lld/auctionSystem/models/Auction.class +internals/ThreadPool.class +multithreading/practice/OddSemaphore.class +dynamicProgramming/fibonacci/DecodeWays.class +practiceproblems/BinaryTreeCousins.class +practiceproblems/IntegerToBinary.class +dynamicProgramming/BooleanParenthesization.class +practiceproblems/RemoveBSTGivenOutsideRange$BSTNode.class +practiceproblems/LeftMostColumnWithOne.class +multithreading/educative/AsyncToSyncConverter.class +graph/leetcode/RedundantConnection$UnionFind.class +practiceproblems/design/SnakeGame.class +practiceproblems/SurroundedRegions$Pair.class +binarysearch/BoatsToSave.class +multithreading/educative/DemonstrationThreadLocal$Counter.class +practiceproblems/BuildArray.class +dynamicProgramming/lcs/LongestStringChain.class +linkedLists/RandomListNode.class +practiceproblems/mergesort/CountNumbersLessThanSelf$ArrayValWithOrigIdx.class +practiceproblems/AircraftMovieDuration.class +reflections/topologicalsort/Main.class +practiceproblems/NextGreaterNumber.class +practiceproblems/SortANearlySortedArray.class +multithreading/educative/ReadWriteLock.class +graph/leetcode/FindAllSafeStates$State.class +practiceproblems/MinimumWindowSubsequence.class +lld/auctionSystem/services/AuctionService.class +practiceproblems/stack/DecodeString.class +trees/TreeToDLL.class +multithreading/educative/superman/SupermanSlightlyBetter.class +lld/billsharing/service/NotificationServiceImpl.class +practiceproblems/ReverseString.class +practiceproblems/IsSubsequence.class +internals/HashMapJava8.class +trees/TwoSumTree.class +sorting/KthLargestElement$Solution.class +java8/IConfigurator.class +practiceproblems/RangeSum2D.class +practiceproblems/GameOfLife.class +internals/QuadTree.class +practiceproblems/stack/BasicCalculatorII.class +lld/billsharing/exceptions/InvalidExpenseState.class +graph/leetcode/ReconstructItenary.class +reflections/retries/app/configs/ConfigsLoader.class +reflections/customMockito/ExternalService.class +multithreading/thread/DeadLock.class +practiceproblems/TreasureIsland$Point.class +lld/auctionSystem/services/ObserverService.class +reflections/annotation/loaders/Cache.class +multithreading/practice/FizzBuzz.class +graph/leetcode/FindTheCity.class +practiceproblems/Trie.class +sorting/MinHeap.class +multithreading/thread/MyRunnable.class +machinecoding/splitwise/Expense.class +linkedLists/MiddleElement.class +reflections/retries/Main.class +multithreading/educative/DemonstrationThreadLocal.class +practiceproblems/stack/WaterTrapping.class +practiceproblems/prefixsum/SubArrayDivisibleByP.class +linkedLists/ListNode.class +trees/BinaryTreeCamera.class +multithreading/educative/ReadWriteLock1.class +practiceproblems/parentheses/ScoreOfParentheses.class +practiceproblems/NutsAndBoltsMatch.class +practiceproblems/AdvantageShuffle.class +practiceproblems/GraphSplitwiseSimplify$Graph.class +practiceproblems/PrisonAfterNDays.class +multithreading/practice/FooBar.class +practiceproblems/design/MinimumStack$Node.class +practiceproblems/PalindromePartition.class +linkedLists/NestedInteger.class +reflections/arrays/data/Actor.class +multithreading/educative/SynchronousExecutor.class +dynamicProgramming/lcs/BitonicSequence.class +graph/leetcode/RedundantConnection.class +graph/topologicalsort/TopologicalSortList$Graph.class +graph/leetcode/ConnectedComponentsInGraph.class +CombinationsAndPermutations/SplitUniqueSubstring.class +practiceproblems/MinimumStepsKnight$Cell.class +linkedLists/LinkedListRemoveDuplicate.class +trees/Tree.class +multithreading/educative/examples/ThreadExample$ExecuteMe.class +trees/LCA.class +multithreading/educative/examples/ThreadSpawn.class +dynamicProgramming/MonotoneIncreasingString.class +lld/auctionSystem/services/BuyerService.class +linkedLists/DetectAndRemoveLoop.class +graph/topologicalsort/Edge.class +practiceproblems/LongestSubArraySumUtmostK.class +multithreading/educative/superman/SupermanWithFlaws.class +linkedLists/MyStack.class +graph/leetcode/GraphValidTree$UnionFind.class +reflections/game/internal/BoardLocation.class +lld/elevator/TestElevator.class +linkedLists/ReversePairsNode.class +multithreading/practice/WebCrawler.class +practiceproblems/intervals/MeetingRoomsII$Interval.class +graph/leetcode/ClosedIsland.class +graph/leetcode/MakeIslandLarger.class +trees/PathSum.class +CombinationsAndPermutations/CombinationSum.class +reflections/topologicalsort/SqlQueryBuilder.class +microsoftassesment/NumsWithEqualDigitSum.class +dynamicProgramming/MaximumRectangle.class +practiceproblems/UrlEncode.class +internals/Entry.class +dynamicProgramming/NumberWithSameConsequtiveDifference.class +trees/DeleteBST.class +trees/MaxProductSplitBinaryTree.class +reflections/topologicalsort/annotations/Annotations$Operation.class +practiceproblems/PermutationInString.class +reflections/annotation/annotations/Annotations.class +binarysearch/SubArraySplitSum.class +practiceproblems/design/MaxFreqStack.class +practiceproblems/ValidSudoku.class +dynamicProgramming/LastStoneWeight.class +machinecoding/splitwise/Driver.class +practiceproblems/MaximumSubstringWithKDistinctChar.class +practiceproblems/MobileKeyPadCombinations.class +practiceproblems/design/EntryStack.class +practiceproblems/design/ShortestWordDistance.class +practiceproblems/LengthOfLongestSubstringKDistinct.class +multithreading/thread/BasicMultiThreading.class +practiceproblems/design/SubRectangleQueries.class +practiceproblems/ShortestPathBinaryMatrix.class +trees/GenerateAllPossibleBST.class +multithreading/thread/Tesst$ThreadA.class +multithreading/educative/superman/Superman.class +linkedLists/CloneRandomPointerLinkedList.class +graph/leetcode/ShortestPathToGetFood.class +multithreading/practice/H2O.class +lld/billsharing/repository/UserRepository.class +strings/stringProblems/ShortDistanceBetweenChars.class +practiceproblems/parentheses/MinSwapsToBalance.class +java8/Square.class +trees/Node.class +reflections/game/internal/Sign.class +graph/leetcode/FindJudge.class +internals/TwitterSnowflakeUUID.class +practiceproblems/HappyNumber.class +CombinationsAndPermutations/SubSets.class +graph/leetcode/CriticalConnectionInGraph.class +graph/Vertex.class +practiceproblems/stack/RemoveKDigits.class +multithreading/educative/BarberShopProblem.class +lld/billsharing/exceptions/ExpenseSettledException.class +reflections/annotation/annotations/Annotations$ExecutionSchedules.class +practiceproblems/design/AuthenticationManager.class +practiceproblems/intervals/RectangleComputeArea.class +practiceproblems/FindHeaters.class +linkedLists/StackOperationUsingLinkedList.class +practiceproblems/SumSubArrayZero$Pair.class +practiceproblems/design/DesignStackIncrement.class +lld/billsharing/model/User.class +linkedLists/SinglyLinkedListNode.class +reflections/topologicalsort/annotations/Annotations$DependsOn.class +lld/billsharing/model/Expense$ExpenseBuilder.class +multithreading/thread/Tesst$ThreadB.class +graph/disjoints/RankTransformMatrix$Position.class +practiceproblems/design/HitCounter.class +practiceproblems/intervals/MergeIntervals.class +reflections/retries/app/databases/CacheLoader.class +graph/primsAlgorithm/Graph.class +multithreading/thread/PrintOddEvenByTwoThreads.class +practiceproblems/parentheses/LongestValidParentheses.class +linkedLists/Agoda.class +graph/shortestPath/ShortestPath$Graph.class +multithreading/educative/examples/ThreadExecutorExample$MyTask.class +graph/leetcode/MinCostConnectCities$UnionFind.class +multithreading/com/safecabs/app/CabProvider.class +practiceproblems/parentheses/ValidParenthesesString.class +practiceproblems/design/SummaryRanges.class +practiceproblems/MaxDistinctElementAfterKRemoval.class +machinecoding/snakesandladder/Driver.class +practiceproblems/MinTimeRotOranges.class +practiceproblems/InOrderSuccessor.class +linkedLists/ArrayToBST.class +lld/vendingmachine/NoMoneyState.class +trees/RootToLeafPaths.class +practiceproblems/CloneGraph.class +trees/SortedArrayToBST.class +multithreading/educative/UnisexBathroom2.class +multithreading/practice/RealTimeCounter.class +internals/LinkedHashMap.class +practiceproblems/parentheses/ValidParentheses.class +reflections/game/internal/ComputerInputProvider.class +java8/Consumer.class +graph/topologicalsort/Vertex.class +practiceproblems/RangeSum.class +linkedLists/InsertionSortList.class +practiceproblems/IsomorphicString.class +trees/MaxWidthOfBinaryTree.class +lld/billsharing/model/Contribution.class +lld/auctionSystem/models/Publisher.class +java8/Employee.class +java8/DesignPatternJava8.class +practiceproblems/tries/LongestRepeatingSubstring.class +multithreading/practice/DiningPhilosophers.class +multithreading/educative/BlockingQueue.class +internals/SkipNode.class +linkedLists/DetectAndRemoveLoop$Node.class +linkedLists/StackImpl.class +lld/billsharing/BillSharingMain.class +graph/bellmanFord/BellmanFord.class +graph/disjoints/DisjointSetArrayImplementation.class +practiceproblems/design/DesignInMemoryFileSystem.class +lld/billsharing/model/Expense.class +dynamicProgramming/UniqueCoinChange.class +graph/bellmanFord/Edge.class +internals/HashMap$Entry.class +microsoftassesment/MinStepsToMakePileSameHeight.class +practiceproblems/design/MyCircularQueue.class +multithreading/educative/examples/FutureTaskExample$1.class +dynamicProgramming/EggDropping.class +lld/vendingmachine/SoldOutState.class +practiceproblems/design/MaxStack.class +graph/leetcode/NetworkConnection.class +multithreading/producerconsumer/Main$1.class +trees/DiameterTree.class +practiceproblems/PetrolGasStation.class +graph/leetcode/ArrayNesting.class +practiceproblems/design/AutoCompleteSystem.class +practiceproblems/LongestIncreasingPathInMatrix.class +binarysearch/SingleElementInSortedArray.class +microsoftassesment/LexicographicallySmallest.class +dynamicProgramming/fibonacci/DiceThrow.class +dynamicProgramming/oiknapsack/NumberOfUniqueWaysToMakeChange.class +practiceproblems/design/LeaderBoard.class +linkedLists/LinkedListToBST.class +linkedLists/Main.class +practiceproblems/LongestUniqueSubstring.class +practiceproblems/ConstructTreeFromInorderAndPostorder.class +multithreading/educative/examples/TimerVsPool$2.class +multithreading/educative/examples/ThreadSleepExample.class +trees/SortedArrayToBST$Node.class +internals/ThreadPool$PoolThreadRunnable.class +internals/ConcurrentHashMap$MyHashMap$MapEntry.class +practiceproblems/sweepline/ModifyArray.class +practiceproblems/FlipZeroesToFormConsecutiveMaximumOnes.class +linkedLists/MergeTwoLinkedLists.class +graph/cycle/Graph.class +strings/stringProblems/PermutationAndCombination.class +multithreading/com/safecabs/app/CabRequest.class +multithreading/producerconsumer/ProducerConsumer.class +lld/auctionSystem/models/Buyer.class +multithreading/educative/examples/ThreadInterruptedException$ExecuteMe.class +practiceproblems/CountBinaryStrings.class +reflections/game/internal/Cell.class +graph/leetcode/CanVisitAllRooms.class +multithreading/practice/Odd.class +practiceproblems/jumpGame/JumpGameV.class +graph/dijkstraAlgorithm/Vertex.class +practiceproblems/MedianOfRunningIntegers.class +dynamicProgramming/MaxSumForNonAdjacentElements.class +practiceproblems/SumOfSquares.class +lld/auctionSystem/repository/ProductRepository.class +strings/stringProblems/StringComparator.class +dynamicProgramming/stocks/StockBuySellKTransactions.class +graph/Edge.class +graph/depthFirstSearch/DepthFirstSearch.class +practiceproblems/SpiralMatrix.class +practiceproblems/VulgarDecimal.class +binarysearch/BinarySearchTemplate.class +multithreading/com/safecabs/client/ClientTest.class +sorting/InsertionSort.class +java8/CustomCollectors.class +practiceproblems/stack/SumOfMinSubArrays.class +multithreading/educative/Demonstration1.class +multithreading/educative/MultiThreadedMergeSort$1.class +practiceproblems/FindAllAnagram.class +practiceproblems/LargestPossibleNumber.class +multithreading/thread/RaceConditionExample.class +practiceproblems/tries/LongestRepeatingSubstring$TrieNode.class +practiceproblems/InorderSuccessorPredecessor.class +dynamicProgramming/lcs/NumberOfLIS.class +multithreading/educative/examples/CallableExample$1.class +multithreading/practice/Demonstration.class +reflections/dynamicProxy/external/impl/HttpClientImpl.class +trees/TreeTraversals$Pair.class +RandomProblemGenerator.class +lld/vendingmachine/VendingMachineState.class +practiceproblems/ConstructBSTFromPreorder$TreeNode.class +reflections/annotation/annotations/Annotations$ExecuteOnSchedule.class +multithreading/educative/examples/TimerVsPool$4.class +multithreading/practice/ZeroEvenOdd.class +dynamicProgramming/stocks/BuyAndSellWithTransactionFee.class +graph/leetcode/MaxDistanceFromWater.class +microsoftassesment/MinSwapsToGroupRedBalls.class +practiceproblems/Candy.class +practiceproblems/jumpGame/JumpsToReachEnd.class +practiceproblems/parentheses/RemoveInvalidParentheses.class +practiceproblems/InorderSuccessorPredecessor$TNode.class +practiceproblems/FirstNonRepeatedCharacter.class +practiceproblems/SumSubArrayZero.class +practiceproblems/TreasureIslandII.class +reflections/topologicalsort/databases/Database.class +strings/stringProblems/LongestCommonPrefix.class +graph/primsAlgorithm/PrimMST.class +multithreading/thread/Tesst.class +lld/auctionSystem/utils/Utils.class +microsoftassesment/Pair.class +lld/auctionSystem/enums/ObserverType.class +practiceproblems/MoveZeroes.class +lld/billsharing/repository/ExpenseRepository.class +practiceproblems/RandomLinkedList$Node.class +lld/vendingmachine/VendingMachine.class +multithreading/educative/examples/ThreadExample.class +practiceproblems/recursion/NQueens.class +practiceproblems/MinOperationToMakeArrayIncreasing.class +trees/DepthOfTree.class +binarysearch/SearchInsertPosition.class +multithreading/educative/examples/StockOrder$Order.class +multithreading/com/safecabs/Gender.class +reflections/game/internal/BoardDimensions.class +practiceproblems/InorderSuccessorPredecessor$Node.class +practiceproblems/SpiralMatrixII.class +machinecoding/snakesandladder/Snake.class +linkedLists/FlattenMultiLevelLinkedList$Node.class +internals/ConcurrentHashMap$MyHashMap.class +practiceproblems/design/LeaderBoard$Player.class +machinecoding/splitwise/User.class +lld/billsharing/model/ExpenseStatus.class +binarysearch/KthSmallestInMultiplicationTable.class +graph/leetcode/NewRoadsMST$UF.class +multithreading/educative/examples/DaemonThreadSpawn$1.class +multithreading/educative/examples/FutureTaskExample$1TrivialTask.class +lld/billsharing/service/UserService.class +machinecoding/splitwise/EqualSplit.class +trees/LowestCommonAncestor$Node.class +machinecoding/snakesandladder/DiceService.class +multithreading/thread/TaskEvenOdd.class +dynamicProgramming/OnesAndZeroes.class +graph/leetcode/SentenceSimilarityII.class +linkedLists/MergeKSortedLists.class +practiceproblems/design/Twitter$User.class +reflections/retries/app/databases/DatabaseConnection.class +practiceproblems/Flatten2DVector.class +multithreading/educative/UnisexBathroom.class +practiceproblems/RomanToInteger.class +practiceproblems/stack/Pattern132.class +binarysearch/SumMutatedArrayCloseTarget.class +practiceproblems/KthSmallestMatrix$Pair.class +multithreading/thread/TestForLocking.class +practiceproblems/RandomLinkedList.class +graph/primsAlgorithm/Vertex.class +lld/billsharing/model/UserShare.class +reflections/retries/annotations/InitializerClass.class +reflections/dynamicProxy/Main.class +multithreading/practice/PrintInOrder.class +trees/LargestBST.class +practiceproblems/CloneGraph$Node.class +sorting/QuickSort.class +practiceproblems/TwoCityScheduling.class +practiceproblems/CanPlaceFlower.class +graph/dijkstraAlgorithm/DijkstraAlgorithm.class +multithreading/practice/OddEvenSemaphore.class +practiceproblems/mergesort/ReversePairs.class +practiceproblems/UpdateMatrix.class +practiceproblems/SearchAMaze$MazeNode.class +reflections/retries/app/AutoSaver.class +practiceproblems/SetBitCount.class +practiceproblems/DoubledPairArray.class +reflections/methodDiscovery/Address.class +graph/leetcode/MinCostRepairEdges.class +dynamicProgramming/TargetSum.class +practiceproblems/SnakeAndLadder.class +binarysearch/KokoEatingBananas.class +multithreading/practice/ProducerConsumer$1Producer.class +multithreading/thread/TestForLocking$WaitTester.class +multithreading/educative/examples/CallableExample$2.class +practiceproblems/stack/DailyTemperature$Pair.class +binarysearch/FindMinimumInRotatedArray.class +practiceproblems/NumberOfBallons.class +multithreading/educative/examples/CallableExample.class +graph/leetcode/MinCostConnectAllPipes$UnionFind.class +trees/isValidPreOrderSerialisation.class +internals/MyBlockingQueue.class +graph/leetcode/FriendCircles.class +practiceproblems/ShuffleArray.class +strings/stringProblems/DistinctSubstring.class +graph/shortestPath/Graph$Vertex.class +practiceproblems/TreasureIsland.class +sorting/PractiseMergeSort.class +graph/leetcode/IslandBFS$Pair.class +multithreading/educative/examples/CallableExample$3.class +graph/disjoints/RankTransformMatrix$UnionFind.class +dynamicProgramming/lcs/WildCardMatching.class +practiceproblems/MinCostRopeConnect.class +linkedLists/Node.class +practiceproblems/UniqueElementsInArray.class +multithreading/educative/examples/ThreadExecutorExample.class +graph/leetcode/ConnectCitiesWithDiscount.class +multithreading/educative/DiningPhilosophers2.class +practiceproblems/intervals/MaxProfitJobScheduling$Interval.class +practiceproblems/WordSearch.class +multithreading/educative/examples/CallableExample$4.class +reflections/customMockito/OurMockito.class +lld/elevator/Elevator.class +practiceproblems/FirstNonRepeatingCharacterStream$Node.class +practiceproblems/MinStepsToConvertXtoY$GFG.class +multithreading/educative/examples/TimerVsPool$1.class +practiceproblems/design/DesignFileSystem.class +multithreading/com/safecabs/cab/Cab.class +lld/auctionSystem/services/strategies/SellerViewAuctionDetails.class +lld/auctionSystem/enums/AuctionState.class +practiceproblems/design/LFUCache$DoubleLinkedList.class +graph/leetcode/RedundantConnectionII$UnionFind.class +practiceproblems/MaxPointsInLine.class +practiceproblems/MatrixRowWithMax1.class +practiceproblems/UniquePathMaximum.class +practiceproblems/KthSmallestFromTwoSortedArrays.class +graph/leetcode/EmployeeImportance$Employee.class +practiceproblems/GrammarMistake.class +practiceproblems/IPOMaxProfit.class +multithreading/com/safecabs/passenger/RegisteredPassenger.class +dynamicProgramming/lcs/MaximumContiguousSubarraySum.class +lld/vendingmachine/SoldState.class +graph/shortestPath/Graph$Edge.class +practiceproblems/SlidingWindow.class +practiceproblems/design/LFUCache.class +multithreading/practice/Even.class +lld/auctionSystem/models/Product.class +practiceproblems/MaximumProductSubarray$MaxSubarray.class +graph/interview/UnionFind.class +multithreading/educative/Demonstration.class +practiceproblems/tries/WordDictionary$TrieNode.class +practiceproblems/design/StockPrice$Node.class +binarysearch/MaxSoldiers.class +practiceproblems/HouseRobber.class +dynamicProgramming/lcs/EditDistance.class +dynamicProgramming/TriangleSum.class +practiceproblems/UniquePath.class +multithreading/educative/examples/DaemonThreadSpawn.class +strings/stringProblems/PushDominoes.class +linkedLists/RemoveDuplicates.class +practiceproblems/PascalsTriangle.class +practiceproblems/mergesort/CountNumbersLessThanSelf.class +java8/FunctionalInterfaceExamples.class +strings/stringProblems/ShiftingLetters.class +graph/kruskalAlgorithm/Graph.class +lld/auctionSystem/services/AuctionService$1.class +graph/primsAlgorithm/PrimsMSTArray.class +graph/leetcode/IslandBFS.class +practiceproblems/design/DesignInMemoryFileSystem$Trie.class +reflections/retries/annotations/InitializerMethod.class +lld/billsharing/exceptions/ContributionExceededException.class +graph/leetcode/MinStepsToCutTrees$Node.class +linkedLists/PalindromeSinglyLinkedList$Node.class +practiceproblems/design/SnapShotUtil.class +multithreading/educative/examples/ThreadExample$MyTask.class +practiceproblems/parentheses/DifferentWaysToAddParenthesis.class +dynamicProgramming/palindrome/PalindromePartitioningII.class +graph/adjacencyMatrix/AdjacencyMatrix.class +graph/leetcode/EmployeeImportance.class +practiceproblems/MinimumIndexDistanceOfMaximumNumbers.class +dynamicProgramming/palindrome/PalindromePartitioning.class +multithreading/com/safecabs/passenger/Passenger.class +graph/bellmanFord/Graph.class +lld/elevator/ExternalRequest.class +practiceproblems/TopKFrequentElements.class +reflections/game/internal/BoardPrinter.class +graph/leetcode/AlienDictionary.class +reflections/game/internal/HumanPlayer.class +graph/disjoints/DisjointSetWithNode.class +internals/SJUArrayList.class +multithreading/thread/Counter.class +machinecoding/splitwise/PercentExpense.class +practiceproblems/design/TimeMap$Value.class +trees/SymmetricTree.class +multithreading/educative/TokenBucketFilter.class +linkedLists/FlattenNestedIterator.class +practiceproblems/intervals/RectangleOverlap.class +reflections/topologicalsort/annotations/Annotations$Input.class +binarysearch/Sqrt.class +practiceproblems/stack/SmallestLexicoSubSeq.class +lld/auctionSystem/enums/AuctionProductState.class +reflections/retries/annotations/RetryOperation.class +reflections/methodDiscovery/Product.class +practiceproblems/MinimumSwapSortArray$Pair.class +linkedLists/ReverseLinkedListBetweenMandN.class +graph/breadthFirstSearch/BreadthFirstSearch.class +practiceproblems/intervals/MaxProfitJobScheduling.class +graph/leetcode/CourseSchedule.class +practiceproblems/design/BrowserHistory$Node.class +trees/LargestBST$NodeValue.class +practiceproblems/EvaluateRPN.class +graph/primsAlgorithm/BinaryMinHeap.class +practiceproblems/MultiplyTwoNumbers.class +practiceproblems/design/ValidTicTacToeState.class +practiceproblems/MinIncrementToMakeArrayUnique.class +graph/topologicalsort/Graph.class +practiceproblems/ReorderLogs.class +graph/kruskalAlgorithm/Edge.class +machinecoding/snakesandladder/Player.class +multithreading/educative/examples/TimerVsPool$3.class +graph/leetcode/ShortestBridge.class +practiceproblems/NutsAndBoltsMatch$NBComparator.class +practiceproblems/MinAdjSwapsToMakePalindrome.class +graph/disjoints/DisjointSetWithNode$Node.class +dynamicProgramming/lcs/ShortestCommonSupersequence.class +reflections/game/internal/TicTacToeGame.class +multithreading/practice/OddEven.class +multithreading/producerconsumer/Main.class +microsoftassesment/AutocompleteSystem.class +practiceproblems/MedianOfKWindow$MedianQueue.class +reflections/methodDiscovery/ClothingProduct.class +practiceproblems/design/Twitter.class +practiceproblems/FirstNonRepeatingCharacterStream$DLList.class +practiceproblems/ArrangeInQueue.class +multithreading/thread/PrintOddEvenByTwoThreads$OddThread.class +graph/leetcode/FindAllSafeStates.class +practiceproblems/stack/SortStack.class +practiceproblems/RollingHashRabinKarp.class +strings/stringProblems/RearrangeCharactersInString.class +microsoftassesment/StringWithout3ConsequitiveLetter.class +java8/IProducer.class +dynamicProgramming/matrix/MinCostPath.class +trees/NodesAtDistanceK.class +practiceproblems/MajorityVoting.class +multithreading/practice/ProducerConsumer.class +practiceproblems/prefixsum/IntervalsBetweenIdenticalElements.class +lld/auctionSystem/repository/BuyerRepository.class +multithreading/practice/CountdownLatch.class +dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.class +practiceproblems/design/StockPrice.class +binarysearch/SearchElementInSortedAndRotatedArray.class +practiceproblems/design/DesignHashMap$ListNode.class +practiceproblems/ValidateIpAddresses.class +trees/TreeNode.class +practiceproblems/BasicCalculator.class +practiceproblems/GroupIsomorphicString.class +linkedLists/DLLToBBST.class +practiceproblems/FindSmallestInteger.class +practiceproblems/RaceCarMinSteps.class +java8/ArrayListIteratorPattern.class +lld/auctionSystem/services/SellerService.class +practiceproblems/design/DesignTicTacToe.class +graph/cycle/Vertex.class +trees/MaxPathSum.class +practiceproblems/BitonicSearch.class +internals/SkippableList.class +graph/dijkstraAlgorithm/BinaryHeap.class +practiceproblems/LongestSpanWithSameSumArray.class +dynamicProgramming/lcs/MinimumAsciiDelete.class +dynamicProgramming/OptimalStratergy.class +practiceproblems/KthCharacterInString.class +graph/floydwarshall/FloydWarshall.class +java8/IFactory.class +practiceproblems/design/SnakeGame$Node.class +practiceproblems/mergesort/CountOfRanges.class +dynamicProgramming/oiknapsack/EqualSubsetSumPartition.class +graph/leetcode/MinCostConnectPoints$DSU.class +multithreading/educative/examples/ThreadSleepExample$ExecuteMe.class +graph/topologicalsort/TopologicalSort.class +graph/leetcode/NetworkConnection$UnionFind.class +dynamicProgramming/oiknapsack/MinPartition.class +practiceproblems/WordBreak.class +practiceproblems/RandomPickWithWeight.class +practiceproblems/LargestSubArrayWithZeroesAndOnes.class +practiceproblems/FlattenLinkedList.class +graph/Graph.class +practiceproblems/ThreeSum.class +graph/leetcode/GraphBiPartitePossiblity.class +dynamicProgramming/stocks/BuyAndSellStockAnytime.class +practiceproblems/AircraftOptimization.class +lld/auctionSystem/models/AuctionProduct.class +lld/elevator/InternalRequest.class +multithreading/educative/examples/ThreadInterruptedException.class +practiceproblems/FirstNonRepeatingCharacterStream.class +multithreading/educative/UberSeatingProblem.class +binarysearch/FirstAndLastOccurence.class +linkedLists/LinkedListToBST$LNode.class +practiceproblems/FurthestBuildingJump.class +graph/leetcode/MinCostConnectPoints.class +graph/kruskalAlgorithm/DisjointSet.class +practiceproblems/NextPermutation.class +reflections/retries/annotations/ScanPackages.class +practiceproblems/ClosestNumbers.class +machinecoding/splitwise/ExactExpense.class +java8/BookSpliterator.class +multithreading/educative/MultiThreadedMergeSort$2.class +practiceproblems/intervals/MergeIntervalIntersection.class +practiceproblems/RestoreIpAddresses.class +strings/stringProblems/CustomSortString.class +lld/billsharing/exceptions/ExpenseDoesNotExistsException.class +sorting/MinHeapTest.class +graph/leetcode/FriendCircles$UnionFind.class +graph/leetcode/NetworkDelayTime.class +microsoftassesment/RemoveCharsMoreThanKOccurrence.class +trees/PruneBinaryTree.class +machinecoding/splitwise/ExpenseType.class +practiceproblems/SortedSquares.class +linkedLists/NextLargestList.class +microsoftassesment/LongestSubStringWithout3ContiguousLetter.class +trees/InsertBST.class +practiceproblems/FourSum.class +practiceproblems/LargestTimeFromDigits.class +practiceproblems/BinaryMatrix.class +graph/dijkstraAlgorithm/BinaryHeap$Node.class +machinecoding/snakesandladder/SnakeAndLadderBoard.class +dynamicProgramming/MinCoinChange.class +multithreading/educative/examples/StockOrder.class +practiceproblems/FrequencySort.class +practiceproblems/ReArrangeStringKDistanceApart.class +practiceproblems/DutchNationalFlag.class +reflections/configparser/configloader/ConfigLoaderLibrary.class +lld/auctionSystem/repository/AuctionRepository.class +dynamicProgramming/palindrome/LongestPalindromicSubsequence.class +practiceproblems/NumberOfSubMatrices.class +binarysearch/MagneticForceBetweenTwoBalls.class +dynamicProgramming/matrix/MaximumSquareDP.class +trees/SameTree.class +graph/dijkstraAlgorithm/Graph.class +java8/BurgerShop.class +java8/Book.class +practiceproblems/RemoveDuplicates.class +reflections/game/internal/InputProvider.class +internals/LinkedHashMap$Entry.class +trees/PathSumIII.class +multithreading/practice/Printer.class +dynamicProgramming/oiknapsack/MinimumSubsetSum.class +practiceproblems/TreasureIslandII$Point.class +practiceproblems/stack/MaxSubarrMinProduct.class +trees/TrimBst.class +lld/billsharing/service/NotificationService.class +lld/elevator/Direction.class +dynamicProgramming/matrix/MatrixMultiplicationCost.class +linkedLists/ReverseKBlockNode.class +trees/SwapRecoverBST.class +multithreading/com/safecabs/app/AssignCab.class +dynamicProgramming/lcs/LongestCommonSubsequence.class +practiceproblems/parentheses/GenerateParenthesis.class +practiceproblems/DivideSubArrayAverage.class +reflections/annotation/annotations/Annotations$ScanPackages.class +linkedLists/SplitLinkedList.class +practiceproblems/LongestRepeatCharReplace.class +lld/auctionSystem/models/Notification.class +multithreading/practice/ProducerConsumer$1Consumer.class +java8/FuncInter.class +strings/stringmatching/KMP.class +graph/cycle/CycleInDirectedGraph.class +graph/leetcode/CourseScheduleII.class +practiceproblems/MirrorBinaryTree$Node.class +practiceproblems/RotateMatrixInPlace.class +multithreading/educative/examples/ThreadSpawn$1.class +graph/leetcode/MinCostConnectCities.class +graph/disjoints/PredatorDisjointSet.class +practiceproblems/MirrorBinaryTree.class +binarysearch/MaxSoldiers$Pair.class +linkedLists/FlattenLinkedList$Node.class +graph/shortestPath/ShortestPath.class +multithreading/practice/WebCrawler$HtmlParser.class +microsoftassesment/MinDeletionToMakeUniqueCount.class +practiceproblems/GraphSplitwiseSimplify.class +practiceproblems/MinRefuelStops.class +reflections/game/Game.class +lld/elevator/ProcessJobWorker.class +machinecoding/splitwise/Split.class +practiceproblems/AlternateOddAndEvenNumbers.class +practiceproblems/CompareVersions.class +practiceproblems/WordBreakII.class +practiceproblems/design/DesignCompressedStringIterator.class +practiceproblems/KthClosestOrigin.class +lld/elevator/State.class +practiceproblems/CountAllPathsFrom2DMatrix.class +machinecoding/splitwise/ExpenseManager.class +reflections/retries/app/http/ServiceRegistry.class +practiceproblems/intervals/MeetingRoomsII.class +practiceproblems/design/AutoCompleteSystem$TrieNode.class +graph/leetcode/EquationEquality$UnionFind.class +dynamicProgramming/OutOfBounds.class +practiceproblems/MedianOfKWindow.class +reflections/arrays/data/Movie.class +practiceproblems/MakeAnArrayPalindrome.class +graph/breadthFirstSearch/Graph.class +practiceproblems/SubstringWindowTemplate.class +multithreading/com/safecabs/app/CustomCyclicBarrier.class +practiceproblems/MinimumStepsKnight.class +graph/leetcode/MatrixStoneRemoval.class +dynamicProgramming/lcs/MaximumSumIncreasingSubsequence.class +multithreading/educative/Barrier.class +internals/QuadTree$QuadNode.class +practiceproblems/FindMissingNumbers.class +practiceproblems/SerializeAndDeserialize.class +practiceproblems/MedianOfTwoSortedArrays.class +practiceproblems/stack/MaxHistogram.class +multithreading/practice/Foo.class +dynamicProgramming/lcs/LongestCommonSubstring.class +binarysearch/FindPeakElement.class +graph/leetcode/MinimumHeightTrees.class +dynamicProgramming/stocks/BuyAndSellStockAtMostTwice.class +multithreading/educative/companies/netflix/SynchronousExecutor.class +internals/SkipList.class +practiceproblems/RemoveBSTGivenOutsideRange.class +trees/IsValidBST.class +lld/vendingmachine/State.class +practiceproblems/design/LogSystem.class +practiceproblems/ProductExceptSelf.class +trees/BinaryTreesUpsideDown.class +practiceproblems/RaceCarMinSteps$StateNode.class +lld/auctionSystem/enums/PublisherEventType.class +practiceproblems/RemoveAdjacentDuplicates.class +reflections/arrays/Main.class +dynamicProgramming/palindrome/CountSubStrings.class +linkedLists/MergeSortLinkedList.class +lld/elevator/AddJobWorker.class +linkedLists/LinkedListToBST$TNode.class +dynamicProgramming/OptimalTreeSearch.class +practiceproblems/GraphSplitwiseSimplify$Graph$AdjNode.class +practiceproblems/MinimumDistanceBetweenTwoNumbers.class +practiceproblems/CompleteBinaryTreeInserter.class +trees/LowestCommonAncestor.class +binarysearch/KClosestElements.class +practiceproblems/ConvertXToY$Steps.class +practiceproblems/IsEditOneDistanceAway.class +lld/auctionSystem/models/User.class +practiceproblems/PartitionLabel.class +CombinationsAndPermutations/CombinationIterator.class +practiceproblems/design/TweetCounts.class +java8/Burger.class +lld/billsharing/service/ExpenseService.class +practiceproblems/FirstMissingPositive.class +practiceproblems/QueensAttackKing.class +practiceproblems/ContainerWithMostWater.class +sorting/KthLargestElement.class +strings/stringmatching/MaxProductString.class +dynamicProgramming/PerfectSquare.class +dynamicProgramming/unboundedknapsack/CuttingRod.class +machinecoding/snakesandladder/Ladder.class +graph/leetcode/CheapestFlightKStops.class +practiceproblems/PartitionArrayDisjoint.class +strings/stringProblems/MostCommonWord.class +multithreading/thread/ThreadRunnable.class +dynamicProgramming/matrix/MinimumFallingPathMatrix.class +sorting/QuickSelect.class +linkedLists/CloneRandomPointerLinkedList$Node.class +multithreading/educative/Demonstration1$1.class +linkedLists/PalindromeSinglyLinkedList.class +practiceproblems/SearchAnElementInMatrix.class +multithreading/com/safecabs/Constants.class +dynamicProgramming/StoneGame.class +reflections/game/internal/Board.class +multithreading/practice/EvenSemaphore.class +multithreading/practice/NonReentrantLock.class +multithreading/educative/superman/SupermanNaiveButCorrect.class +practiceproblems/MinimumBribes.class +multithreading/educative/Callback.class +reflections/topologicalsort/BestGamesFinder.class +dynamicProgramming/BoxStacking$Dimension.class +multithreading/thread/DeadLock$1.class +java8/EmployeeSpliterator.class +trees/CountGoodNodes.class +trees/AVLTree.class +multithreading/educative/companies/netflix/Executor.class +practiceproblems/RotateArray.class +multithreading/educative/DeferredCallbackExecutor$CallBack.class +practiceproblems/GroupAnagrams.class +practiceproblems/stack/StockSpanner.class +strings/stringProblems/FindLongestStringInArray.class +practiceproblems/ConvertXToY.class +practiceproblems/SimilarExpressions.class +practiceproblems/TwoSumClosestToZero.class +practiceproblems/sweepline/MaxSumRangeQuery.class +graph/leetcode/MinCostConnectAllPipes.class +graph/kruskalAlgorithm/DisjointSet$Node.class +dynamicProgramming/lcs/LongestIncreasingSubsequence.class +practiceproblems/CountAndSay.class +machinecoding/splitwise/PercentSplit.class +practiceproblems/design/OwnDataStructureUtil.class +multithreading/educative/examples/TimerVsPool.class +practiceproblems/design/LFUCache$DLLNode.class +practiceproblems/stack/DailyTemperature.class +practiceproblems/Pow.class +practiceproblems/TaskLeastInterval.class +practiceproblems/parentheses/BalancedSmiley.class +reflections/annotation/annotations/Annotations$ScheduledExecutorClass.class +practiceproblems/prefixsum/SubArraySumDivisibleByK.class +reflections/topologicalsort/annotations/Annotations.class +practiceproblems/parentheses/CanBeValid.class +practiceproblems/SurroundedRegions.class +graph/leetcode/PacificAtlantic.class +practiceproblems/FlattenLinkedList$Node.class +graph/primsAlgorithm/Edge.class +dynamicProgramming/stocks/StockBuySellWithCoolDown.class +practiceproblems/design/LRUCache1.class +linkedLists/AllProblems.class +multithreading/practice/SumUpExample.class +binarysearch/FindSmallestDivisor.class +practiceproblems/stack/NextGreaterElement.class +reflections/dynamicProxy/Main$TimeMeasuringProxyHandler.class +graph/adjacencyList/AdjacencyList.class +practiceproblems/prefixsum/SubArraySumEqualsK.class +practiceproblems/tries/MapSum.class +strings/stringProblems/SlowestKey.class +multithreading/thread/ThreadJoinExample.class +internals/HashMap.class +lld/elevator/Request.class +multithreading/thread/Printer.class +linkedLists/RotateList.class +practiceproblems/PairDivisibleBy60.class +sorting/MaxHeap.class +sorting/MergeSort.class +machinecoding/snakesandladder/SnakeAndLadderService.class +reflections/methodDiscovery/Size.class +reflections/game/internal/Player.class +practiceproblems/MaximumDifference.class +practiceproblems/SerializeDeserializeBST.class +reflections/customMockito/OurMockTest.class +practiceproblems/design/BrowserHistory.class +multithreading/thread/Bank.class +graph/leetcode/MinCostConnectPoints$Edge.class +practiceproblems/WordLadder.class +practiceproblems/MaximumProductSubarray.class +graph/leetcode/MinStepsToCutTrees.class +practiceproblems/ValidPalindromeII.class +multithreading/educative/examples/ThreadExecutorExample$DumbExecutor.class +multithreading/educative/DiningPhilosophers.class +graph/leetcode/ConnectCities.class +practiceproblems/jumpGame/MinTapsToFillGarden.class +lld/auctionSystem/models/Observer.class +linkedLists/DLLToBBSTTimeEfficiency.class +graph/leetcode/RedundantConnectionII.class +practiceproblems/MaximumGap.class +linkedLists/FlattenMultiLevelLinkedList.class +lld/auctionSystem/models/Seller.class +multithreading/practice/PositionUpdater.class +practiceproblems/ReorganiseString.class +practiceproblems/CountElements.class +practiceproblems/design/FreqStack.class +practiceproblems/intervals/InsertIntervals.class +reflections/annotation/Main.class +multithreading/thread/DeadLock$2.class +linkedLists/ReverseLinkedList.class +dynamicProgramming/lcs/DeleteAndEarn.class +trees/CountGoodNodes$Pair.class +practiceproblems/LargestDivisibleSubset.class +graph/leetcode/MaxProbabilityPath.class +multithreading/educative/CountingSemaphore.class +graph/leetcode/AccountsMerge.class +dynamicProgramming/lcs/NumberOfDistinctSubSequence.class +multithreading/educative/examples/FutureTaskExample.class +reflections/configparser/data/GameConfig.class +multithreading/educative/companies/netflix/Callback.class +multithreading/thread/PrintEvenOddTester.class +multithreading/educative/Executor.class +graph/disjoints/RankTransformMatrix.class +graph/interview/DisjointSet.class +multithreading/practice/PrinterSemaphore.class +dynamicProgramming/TwoKeysKeyBoard.class +practiceproblems/MinimumSwapSortArray.class +dynamicProgramming/oiknapsack/SubsetSumProblem.class +practiceproblems/FindAllPossibleRecipes.class +practiceproblems/StringJustify.class +reflections/game/internal/KeyboardInputProvider.class +lld/billsharing/model/ExpenseGroup.class +internals/ConcurrentHashMap.class +practiceproblems/MinimumSubArrayLength.class +practiceproblems/design/DesignHashMap.class +dynamicProgramming/MakeArrayStrictlyIncreasing.class +practiceproblems/FlipMaximizeZeroesSubarrayKadane.class +graph/kruskalAlgorithm/Vertex.class +graph/topologicalsort/TopologicalSortList.class +dynamicProgramming/MinSwapsToMakeArrayIncreasing.class +lld/auctionSystem/services/strategies/AuctionDetails.class +practiceproblems/WordSearchII$TrieNode.class +graph/dijkstraAlgorithm/Edge.class +trees/TreeTraversals.class +multithreading/educative/companies/netflix/SynchronousExecutor$1.class +practiceproblems/KmostFrequentLetters.class +practiceproblems/IntersectionOfArrays.class +practiceproblems/design/MinimumStack.class +reflections/configparser/data/UserInterfaceConfig.class +microsoftassesment/CropWords.class +practiceproblems/design/GetRandomWithDuplicates.class +practiceproblems/design/Twitter$Tweet.class +dynamicProgramming/KnightDialer.class +practiceproblems/design/LRUCache$DLLNode.class +practiceproblems/design/UndergroundSystem$Route.class +dynamicProgramming/CatalanNumberBinarySearchTree.class +practiceproblems/FenwickTree.class +practiceproblems/MinStepsToConvertXtoY.class +graph/leetcode/ConnectCities$UnionSet.class +practiceproblems/Trie$TrieNode.class +graph/interview/DisjointSetLeetcode.class +CombinationsAndPermutations/Permutations.class +practiceproblems/design/UndergroundSystem.class +dynamicProgramming/oiknapsack/O1KnapsackSpaceOptimized.class +java8/CustomSpliterator.class +practiceproblems/TaskLeastInterval$Pair.class +practiceproblems/WordSearchII.class +graph/leetcode/GraphValidTree.class +practiceproblems/intervals/OverlappingIntervals.class +practiceproblems/CelebrityProblem.class +multithreading/educative/MultiThreadedMergeSort.class +practiceproblems/mergesort/CountingInversion.class +practiceproblems/SearchAMaze.class +machinecoding/splitwise/EqualExpense.class +practiceproblems/design/SummaryRanges$Interval.class +lld/vendingmachine/Main.class +graph/depthFirstSearch/Graph.class +machinecoding/splitwise/ExpenseMetadata.class +practiceproblems/MaximumUnsortedSubarray.class +dynamicProgramming/lcs/MaximumLengthRepeatedSubarray.class +graph/leetcode/TimeToInformEmployee.class +multithreading/educative/companies/netflix/Run.class +dynamicProgramming/MinCostTickets.class +practiceproblems/design/LRUCache.class +graph/leetcode/AccountsMerge$UnionFind.class +practiceproblems/Fenwick2D.class +practiceproblems/AngleOfClock.class +practiceproblems/SetZeroesMatrix.class +graph/ArticulationPoint.class diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..3edcf50 --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,763 @@ +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/Sign.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/LinkedHashMap.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SumSubArrayZero.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MinCostConnectCities.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/MinHeapTest.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/SplitLinkedList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MaximumSubstringWithKDistinctChar.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MultiplyTwoNumbers.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CountBinaryStrings.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/services/SellerService.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/disjoints/RankTransformMatrix.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/DeleteAndEarn.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/PermutationAndCombination.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RangeSum.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/services/strategies/AuctionDetails.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/DesignHashMap.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/BalancedSmiley.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CountAndSay.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/stocks/BuyAndSellStockAnytime.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/ConnectCitiesWithDiscount.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/BillSharingMain.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/BasicCalculator.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/methodDiscovery/Product.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/DetectAndRemoveLoop.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/PrintEvenOddTester.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/PractiseMergeSort.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinimumIndexDistanceOfMaximumNumbers.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/Top20LinkedListQuestions.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MaxDistanceFromWater.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/IslandBFS.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/matrix/MinCostPath.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SurroundedRegions.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/Pattern132.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/configparser/data/UserInterfaceConfig.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/app/databases/CacheLoader.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/SmallestLexicoSubSeq.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/DeferredCallbackExecutor.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/adjacencyMatrix/AdjacencyMatrix.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/WildCardMatching.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LongestIncreasingPathInMatrix.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/TwoSumClosestToZero.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RollingHashRabinKarp.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/bellmanFord/Vertex.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ProductExceptSelf.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/customMockito/OurMockTest.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinimumBribes.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/MergeSortLinkedList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/BitonicSearch.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/PercentSplit.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/snakesandladder/SnakeAndLadderBoard.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FrequencySort.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/DivideSubArrayAverage.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/SymmetricTree.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/DiningPhilosophers2.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/primsAlgorithm/PrimMST.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/jumpGame/JumpsToReachEnd.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/enums/AuctionProductState.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/repository/UserRepository.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/RemoveDuplicates.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/NextPermutation.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/BalloonBurst.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/CriticalConnectionInGraph.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/HitCounter.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SortANearlySortedArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/Board.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/DesignTicTacToe.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/TestForLocking.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/MinimumStack.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MobileKeyPadCombinations.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinStepsToConvertXtoY.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/ThreadInterruptedException.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/StockPrice.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MaxPointsInLine.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/AircraftMovieDuration.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MinPathHavingMaxDifference.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/fibonacci/DiceThrow.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/model/UserShare.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/superman/SupermanSlightlyBetter.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/AutocompleteSystem.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/vendingmachine/State.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/CountdownLatch.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/PushDominoes.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/LinkedListToBST.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LeftMostColumnWithOne.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/GrammarMistake.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/PathSumIII.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/LargestBST.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/MaxSubarrMinProduct.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/MinCoinChange.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/SubRectangleQueries.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/java8/DesignPatternJava8.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/dijkstraAlgorithm/DijkstraAlgorithm.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/oiknapsack/MinimumSubsetSum.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/DesignCompressedStringIterator.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/RemoveCharsMoreThanKOccurrence.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ShuffleArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SimilarExpressions.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ContainerWithMostWater.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/mergesort/ReversePairs.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/topologicalsort/Main.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/BinarySearchTemplate.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/cycle/CycleUndirectedGraph.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/MaximumLengthRepeatedSubarray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MatrixRowWithMax1.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/ThreadSpawn.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/AsyncToSyncConverter.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/Driver.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringmatching/KMP.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MaximumProductSubarray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/AssemblyLineScheduling.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/palindrome/PalindromePartitioningII.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/AllPathsInGraph.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/ReconstructItenary.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/GenerateAllPossibleBST.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/KmostFrequentLetters.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/elevator/TestElevator.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/DiningPhilosophers.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/User.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/NumberWithSameConsequtiveDifference.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/WordSearchII.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/StoneGame.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PalindromePartition.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/adjacencyList/AdjacencyList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/MaxProductSplitBinaryTree.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/FlattenLinkedList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/InorderSuccessorPredecessor.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RomanToInteger.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/kruskalAlgorithm/DisjointSet.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/mergesort/CountingInversion.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/primsAlgorithm/BinaryMinHeap.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/prefixsum/SubArrayDivisibleByP.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MajorityVoting.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/InsertBST.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/topologicalsort/TopologicalSort.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/UpdateMatrix.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/prefixsum/SubArraySumEqualsK.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/ShortestWordDistance.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/topologicalsort/annotations/Annotations.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/app/CabRequest.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RemoveBSTGivenOutsideRange.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/vendingmachine/NoMoneyState.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/arrays/data/Actor.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/AlienDictionary.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/tries/LongestRepeatingSubstring.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RandomPickWithWeight.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/MaximumContiguousSubarraySum.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MedianOfKWindow.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MaxProbabilityPath.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/NetworkDelayTime.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/LastStoneWeight.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RotateArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/MergeIntervals.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinimumDistanceBetweenTwoNumbers.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CountAllPathsFrom2DMatrix.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/CustomSortString.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MinCostConnectAllPipes.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/MiddleElement.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/model/User.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/companies/netflix/Run.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/SubArraySplitSum.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/depthFirstSearch/Graph.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/model/ExpenseStatus.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/QuickSelect.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RemoveAdjacentDuplicates.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/LexicographicallySmallest.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinimumWindowSubstring.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/mergesort/CountOfRanges.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/TrailingZeroes.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/oiknapsack/NumberOfUniqueWaysToMakeChange.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/TreeTraversals.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/Observer.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/UnisexBathroom2.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SubstringWindowTemplate.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/NextGreaterNumber.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/BoatsToSave.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/java8/FunctionalInterfaceExamples.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/SlowestKey.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/BrowserHistory.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/LeaderBoard.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/TaskLeastInterval.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/TimeToInformEmployee.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/KnightDialer.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/vendingmachine/SoldState.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/client/ClientTest.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/TweetCounts.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FirstNonRepeatedCharacter.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/TimerVsPool.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/MinSwapsToGroupRedBalls.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/IsEditOneDistanceAway.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/StackImpl.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/services/ObserverService.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/superman/Superman.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/EmployeeImportance.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/ReverseKBlockNode.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/services/strategies/BuyerViewAuctionDetails.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/FizzBuzz.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/InputProvider.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/IsomorphicString.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/ThreadExample.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/QuickSort.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/DLLToBBST.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ReArrangeStringKDistanceApart.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/Seller.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PascalsTriangle.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/ShipPackageWithNDays.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ReorganiseString.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SumOfSquares.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/repository/SellerRepository.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/ExpenseService.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SlidingWindow.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/MaximumSumIncreasingSubsequence.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/ArrayNesting.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/FirstBadVersion.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/Node.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/GroupAnagrams.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinTimeRotOranges.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/disjoints/DisjointSetWithNode.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/SortedArrayToBST.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/dijkstraAlgorithm/Graph.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/ArrayToBST.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MirrorBinaryTree.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/MaxHistogram.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/methodDiscovery/Address.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinOperationToMakeArrayIncreasing.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/topologicalsort/TopologicalSortList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FenwickTree.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/java8/CustomCollectors.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/CourseScheduleII.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ShortestPathBinaryMatrix.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MakeAnArrayPalindrome.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/repository/ProductRepository.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FurthestBuildingJump.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/InsertIntervals.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/CountGoodNodes.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/TreasureIslandII.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/annotations/InitializerMethod.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/depthFirstSearch/DepthFirstSearch.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ValidPalindromeII.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MinimumHeightTrees.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/LongestCommonSubsequence.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/TwoCityScheduling.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CloneGraph.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FlipZeroesToFormConsecutiveMaximumOnes.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/AuctionProduct.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/AllProblems.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/superman/SupermanWithFlaws.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/DeleteBST.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/producerconsumer/ProducerConsumer.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/producerconsumer/Main.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/Twitter.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/Tesst.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/StackOperationUsingLinkedList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/Product.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/CombinationsAndPermutations/CombinationSum.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/Cell.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/GraphBiPartite.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/SingleElementInSortedArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/snakesandladder/Ladder.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/CanVisitAllRooms.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/EggDropping.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/Pow.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/sweepline/ModifyArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/MergeTwoLinkedList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/UberSeatingProblem.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/TreasureIsland.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/customMockito/OurMockito.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/prefixsum/IntervalsBetweenIdenticalElements.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CountElements.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/WaterTrapping.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/exceptions/InvalidExpenseState.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/IntersectionOfArrays.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/vendingmachine/SoldOutState.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FindAllAnagram.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MedianOfTwoSortedArrays.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/DeadLock.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/RearrangeCharactersInString.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/methodDiscovery/Size.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PartitionArrayDisjoint.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/Main.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/UndergroundSystem.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/NonDecreasingArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SetBitCount.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/ConnectedComponentsInGraph.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/TokenBucketFilter.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/ThreadJoinExample.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/services/strategies/SellerViewAuctionDetails.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/H2O.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/app/http/ServiceRegistry.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/topologicalsort/Graph.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/Flatten2DVector.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ValidSudoku.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinIncrementToMakeArrayUnique.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/NextGreaterElement.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/NodesAtDistanceK.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/GenerateParenthesis.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/Gender.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/NumsWithEqualDigitSum.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/MergeIntervalIntersection.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MedianOfRunningIntegers.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/DiningPhilosophers.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/stocks/StockBuySellKTransactions.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/FindSmallestDivisor.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/ShortestCommonSupersequence.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LongestUniqueSubstring.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/MaxSumForNonAdjacentElements.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/Agoda.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PlusOne.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/arrays/data/Movie.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/ExactSplit.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FindAllPossibleRecipes.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/MinSwapsToMakeArrayIncreasing.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinimumSwapSortArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/DepthOfTree.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/service/NotificationServiceImpl.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/annotation/annotations/Annotations.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/ExpenseMetadata.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ConstructBSTFromPreorder.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/prefixsum/SubArraySumDivisibleByK.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/RootToLeafPaths.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/bellmanFord/Graph.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/FriendCircles.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/ComputerPlayer.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/KthSmallestFromTwoSortedArrays.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/stocks/BuyAndSellStockAtMostTwice.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/GraphSplitwiseSimplify.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/StockOrder.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/MaxHeap.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/companies/netflix/Executor.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/app/AssignCab.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FindHeaters.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/ValidParentheses.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/init/Main.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/HashMapJava8.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/matrix/MatrixMultiplicationCost.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/RectangleComputeArea.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/recursion/SudokuSolver.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/DemonstrationThreadLocal.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/BlockingQueue.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/FlattenNestedIterator.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/PrintOddEvenByTwoThreads.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/BitonicSequence.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/TrimBst.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/LongestSubStringWithout3ContiguousLetter.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MaxDistinctElementAfterKRemoval.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/FirstAndLastOccurence.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/LongestIncreasingSubsequence.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/BasicCalculatorII.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/bellmanFord/NegativeException.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/oiknapsack/O1KnapsackSpaceOptimized.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/primsAlgorithm/Graph.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/palindrome/PalindromePartitioning.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/BinaryTreeCousins.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/TreeNode.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/ArticulationPoint.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SpiralMatrixII.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/model/ExpenseGroup.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/EqualExpense.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/Publisher.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RestoreIpAddresses.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/ShortestPathToGetFood.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/CropWords.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/MinCostTickets.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/arrays/Main.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/SameTree.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/EvaluateRPN.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/recursion/NQueens.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/enums/Channel.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/CombinationsAndPermutations/Permutations.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/Notification.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/MyCircularQueue.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/SortStack.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FindSmallestInteger.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SnakeAndLadder.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/OverlappingIntervals.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/NumberOfBallons.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/MultiThreadedMergeSort.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/repository/ExpenseRepository.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/EditDistance.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/ProducerConsumer.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ReverseString.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinCostRopeConnect.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RangeSum2D.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/enums/ObserverType.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/AuthenticationManager.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/DiameterTree.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/ExpenseType.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LargestDivisibleSubset.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/palindrome/LongestPalindromicSubsequence.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/ThreadRunnable.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/MaxStack.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/FindPeakElement.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/PathSum.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/primsAlgorithm/PrimsMSTArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/OutOfBounds.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/GetRandomWithDuplicates.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/BackspaceCompare.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FirstMissingPositive.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/KthSmallestInMultiplicationTable.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/SkipList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/DesignFileSystem.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/ValidParenthesesString.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/dynamicProxy/external/impl/DatabaseReader.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/DLLToBBSTTimeEfficiency.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/java8/CustomSpliterator.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/annotation/Main.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/BoxStacking.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/ValidTicTacToeState.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/AVLTree.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/OwnDataStructureUtil.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/app/CabProvider.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/SnapShotUtil.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/shortestPath/Graph.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/CloneRandomPointerLinkedList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/TwoKeysKeyBoard.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/NextLargestList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/ConcurrentHashMap.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/Buyer.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/CombinationsAndPermutations/SplitUniqueSubstring.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/PalindromeSinglyLinkedList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/SJUArrayList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/CheapestFlightKStops.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PermutationInString.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinimumSubArrayLength.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/IPOMaxProfit.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/Bank.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/BinaryTreeCamera.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/superman/SupermanNaiveButCorrect.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/CombinationsAndPermutations/CombinationIterator.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/StringJustify.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/annotations/RetryOperation.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/Combination.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/StockSpanner.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RandomLinkedList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/RemoveInvalidParentheses.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CanPlaceFlower.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/BuildArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/RussianDollEnvelope.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/dynamicProxy/external/impl/HttpClientImpl.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/SumOfMinSubArrays.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/MaxWidthOfBinaryTree.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/BasicMultiThreading.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinimumWindowSubsequence.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FirstNonRepeatingCharacterStream.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/FindTheCity.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SetZeroesMatrix.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/Addition.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/ComputerInputProvider.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/enums/AuctionState.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/app/CustomCyclicBarrier.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/MinStepsToMakePileSameHeight.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/WordLadder.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/TicTacToeGame.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/LogSystem.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/EqualSplit.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MaximumGap.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/IsSubsequence.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/cycle/CycleInDirectedGraph.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/Constants.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/NumberOfLIS.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RotateMatrixInPlace.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/MeetingRoomsII.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PairDivisibleBy60.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/User.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MinCostRepairEdges.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PetrolGasStation.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ComplexNumberMultiply.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LargestTimeFromDigits.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LongestSpanWithSameSumArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MinStepsToCutTrees.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/customMockito/ExternalService.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/ReverseLinkedList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/MaxFreqStack.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/breadthFirstSearch/Graph.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/PruneBinaryTree.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/ThreadExecutorExample.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/RaceConditionExample.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/TreeToDLL.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/ReversePairsNode.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/TwoStringInterleavingToFormThird.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/stocks/BuyAndSellWithTransactionFee.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SpiralMatrix.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ConstructTreeFromInorderAndPreorder.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/palindrome/LongestPalindromicSubstring.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/LongestValidParentheses.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/oiknapsack/SubsetSumProblem.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinimumStepsKnight.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CompleteBinaryTreeInserter.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/UniqueCoinChange.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/MyBlockingQueue.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/BinaryTreesUpsideDown.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/EquationEquality.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/LongestStringChain.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/snakesandladder/Driver.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/MergeTwoLinkedLists.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CountMinimumStepsToFormDesiredInputArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ValidateIpAddresses.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/bellmanFord/Edge.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/Split.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/TimeMap.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/dynamicProxy/Main.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/GraphValidTree.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/SearchInsertPosition.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/annotation/loaders/Cache.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/service/UserService.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/TriangleSum.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MoveZeroes.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/AlternateOddAndEvenNumbers.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/FutureTaskExample.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/DaemonThreadSpawn.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/Expense.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/annotations/ScanPackages.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/LCA.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/UrlEncode.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MatrixStoneRemoval.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/SentenceSimilarityII.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/VulgarDecimal.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/MaximumRectangle.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/Node.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/ExpenseManager.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/service/NotificationService.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/SnakeGame.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/UniquePathMaximum.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/NetworkConnection.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/UniquePath.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/MergeKSortedLists.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SearchAMaze.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/OptimalTreeSearch.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/KClosestElements.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/Main.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/MonotoneIncreasingString.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/sweepline/MaxSumRangeQuery.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/dynamicProxy/external/impl/DatabaseReaderImpl.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/Sqrt.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/WordBreak.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/Player.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/UnisexBathroom.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/configparser/configloader/ConfigLoaderLibrary.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/Fenwick2D.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/FindJudge.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/app/databases/DatabaseConnection.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/ReverseLinkedListBetweenMandN.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/methodDiscovery/ProductTest.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/configparser/data/GameConfig.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/breadthFirstSearch/BreadthFirstSearch.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ClosestNumbers.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/FindMinimumInRotatedArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/MinHeap.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/OptimalStratergy.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/WordBreakII.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/InOrderSuccessor.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/FlattenMultiLevelLinkedList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/DesignInMemoryFileSystem.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/RotateList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/annotations/InitializerClass.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/kruskalAlgorithm/Graph.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/RedundantConnection.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/matrix/MaximumSquareDP.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/repository/AuctionRepository.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/snakesandladder/DiceService.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FindPairs.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/DutchNationalFlag.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/MinSwapsToBalance.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/TopKFrequentElements.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/snakesandladder/SnakeAndLadderService.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/services/PublisherService.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FlattenLinkedList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/DifferentWaysToAddParenthesis.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/HouseRobber.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/QueensAttackKing.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/ShortDistanceBetweenChars.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/MaxPathSum.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/RandomProblemGenerator.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/MinimumAsciiDelete.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MaxSumTwoNonOverlappingSubArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/utils/Utils.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/topologicalsort/databases/Database.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/OddEven.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MinCostConnectPoints.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/exceptions/ExpenseSettledException.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/BarberShopProblem.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/Foo.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/exceptions/ExpenseDoesNotExistsException.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/DistinctSubstring.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/Barrier.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/QuadTree.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/FindLongestStringInArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/RandomListNode.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SerializeAndDeserialize.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/AdvantageShuffle.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/RemoveKDigits.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/BoardDimensions.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/ExactExpense.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/IntegerToBinary.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MakeIslandLarger.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/AutoCompleteSystem.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ArrangeInQueue.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/oiknapsack/EqualSubsetSumPartition.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/NumberOfDistinctSubSequence.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/NumberOfSubMatrices.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/exceptions/UnRegisteredPassengerException.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/NewRoadsMST.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/model/Contribution.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/MaxSoldiers.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/InsertionSortList.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/snakesandladder/Player.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LongestSubArraySumUtmostK.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/topologicalsort/SqlQueryBuilder.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/floydwarshall/FloydWarshall.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/companies/netflix/Callback.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ReorderLogs.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/KthSmallestMatrix.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PartitionLabel.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/services/BuyerService.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/CourseSchedule.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/DailyTemperature.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/KokoEatingBananas.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/fibonacci/DecodeWays.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/snakesandladder/Snake.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/RedundantConnectionII.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/oiknapsack/MinPartition.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/jumpGame/JumpGameV.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/Tree.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/IsValidBST.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/app/configs/ConfigsLoader.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/DecodeString.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/ThreadSleepExample.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/KthLargestElement.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/UniqueElementsInArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/MinDeletionToMakeUniqueCount.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/PerfectSquare.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/jumpGame/VideoStitching.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/MagneticForceBetweenTwoBalls.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/ThreadPool.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/DungeonGame.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/stocks/StockBuySellWithCoolDown.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MaximumDifference.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/HumanPlayer.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CheckPalindromePermutation.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/AsteroidCollision.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/ShiftingLetters.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/ZeroEvenOdd.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/kruskalAlgorithm/KruskalMST.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/NutsAndBoltsMatch.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/TwitterSnowflakeUUID.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/MostCommonWord.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/palindrome/CountSubStrings.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/LRUCache.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/BoardLocation.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/TwoSumTree.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/SinglyLinkedListNode.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/vendingmachine/VendingMachineState.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/InsertionSort.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/KthCharacterInString.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/KthClosestOrigin.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/services/AuctionService.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/methodDiscovery/ClothingProduct.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LongestRepeatCharReplace.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/isValidPreOrderSerialisation.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/Game.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/LongestCommonSubstring.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/FooBar.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinRefuelStops.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/mergesort/CountNumbersLessThanSelf.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/jumpGame/MinTapsToFillGarden.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinAdjSwapsToMakePalindrome.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/GroupIsomorphicString.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/app/AutoSaver.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/GraphBiPartitePossiblity.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/model/Expense.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/SwapRecoverBST.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/CountingSemaphore.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/BoardPrinter.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/ReadWriteLock.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/HashMap.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/PercentExpense.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/NumberOfDaysToMakeMBouquets.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LargestSubArrayWithZeroesAndOnes.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RemoveDuplicates.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/AngleOfClock.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/LongestCommonPrefix.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/SumMutatedArrayCloseTarget.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/ScoreOfParentheses.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/WordSearch.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/RealTimeCounter.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/cab/Cab.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/FindAllSafeStates.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/companies/netflix/SynchronousExecutor.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/disjoints/PredatorDisjointSet.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/bellmanFord/BellmanFord.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/matrix/MinimumFallingPathMatrix.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/NonReentrantLock.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/LFUCache.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/dynamicProxy/external/impl/HttpClient.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ThreeSum.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FourSum.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/tries/WordDictionary.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/MergeSort.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringmatching/MaxProductString.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PrisonAfterNDays.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/interview/DisjointSet.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CelebrityProblem.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/SummaryRanges.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/GameOfLife.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SearchAnElementInMatrix.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RaceCarMinSteps.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ConvertXToY.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/Auction.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/AccountsMerge.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/tries/MapSum.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/LowestCommonAncestor.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/CombinationsAndPermutations/SubSets.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/disjoints/DisjointSetArrayImplementation.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/OddEvenSemaphore.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/MakeArrayStrictlyIncreasing.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SerializeDeserializeBST.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/CallableExample.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MaximumUnsortedSubarray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/ShortestBridge.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/exceptions/ContributionExceededException.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/unboundedknapsack/CuttingRod.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/CanBeValid.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LargestPossibleNumber.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LengthOfLongestSubstringKDistinct.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/repository/BuyerRepository.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/cycle/Graph.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/Event.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/dijkstraAlgorithm/BinaryHeap.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CompareVersions.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/passenger/RegisteredPassenger.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LongestConsequtiveSequence.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/passenger/Passenger.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/ConnectCities.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/TargetSum.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/LinkedListRemoveDuplicates.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/RectangleOverlap.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ConstructTreeFromInorderAndPostorder.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/DoubledPairArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/KeyboardInputProvider.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/Trie.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/WebCrawler.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/BooleanParenthesization.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/shortestPath/ShortestPath.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/Candy.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/DesignStackIncrement.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/MaxProfitJobScheduling.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SortedSquares.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/AircraftOptimization.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/SearchElementInSortedAndRotatedArray.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/PacificAtlantic.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/ClosedIsland.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/topologicalsort/BestGamesFinder.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/service/ExpenseService.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/vendingmachine/VendingMachine.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/enums/PublisherEventType.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/OnesAndZeroes.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/vendingmachine/Main.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/StringWithout3ConsequitiveLetter.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/CatalanNumberBinarySearchTree.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FindMissingNumbers.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/vendingmachine/HasMoneyState.java +/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/HappyNumber.java From b4811de956ad0ca9a394326747d253588a14b099 Mon Sep 17 00:00:00 2001 From: vickey290 Date: Sat, 23 Jul 2022 16:12:26 +0530 Subject: [PATCH 46/51] 2022 problem set --- .idea/misc.xml | 7 ++ Problems.iml | 34 ++++++++-- .../CombinationIterator.java | 2 +- .../CombinationSum.java | 2 +- .../Permutations.java | 2 +- .../SplitUniqueSubstring.java | 2 +- .../combinationsandpermutations/SubSets.java | 2 +- .../java/graph/leetcode/AccountsMerge.java | 12 ++-- .../graph/leetcode/CheapestFlightKStops.java | 2 +- .../leetcode/ConnectCitiesWithDiscount.java | 1 + .../java/graph/leetcode/EquationEquality.java | 2 + .../java/graph/leetcode/FriendCircles.java | 54 +++++++-------- .../leetcode/MinCostConnectAllPipes.java | 68 +++++++++---------- src/main/java/graph/leetcode/NewRoadsMST.java | 13 ++-- .../java/internals/ConcurrentHashMap.java | 15 ++-- .../linkedLists/FlattenNestedIterator.java | 8 +-- src/main/java/linkedLists/Node.java | 4 +- src/main/java/linkedLists/RotateList.java | 2 +- .../educative/AsyncToSyncConverter.java | 4 +- .../java/multithreading/practice/Foo.java | 3 - .../java/practiceproblems/CloneGraph.java | 7 +- .../practiceproblems/NextPermutation.java | 4 +- .../practiceproblems/PermutationInString.java | 2 + .../SerializeDeserializeBST.java | 16 ++--- .../java/practiceproblems/WordLadder.java | 8 +-- .../java/practiceproblems/WordSearch.java | 5 ++ .../java/practiceproblems/WordSearchII.java | 2 +- .../parentheses/ValidParenthesesString.java | 45 ++++++++---- .../java/trees/BinaryTreesUpsideDown.java | 3 + src/main/java/trees/LowestCommonAncestor.java | 20 ++++-- src/main/java/trees/MaxWidthOfBinaryTree.java | 1 - src/main/java/trees/TreeNode.java | 5 +- 32 files changed, 218 insertions(+), 139 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 1763e15..d460235 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,12 @@ + + + diff --git a/Problems.iml b/Problems.iml index c90834f..77c5230 100644 --- a/Problems.iml +++ b/Problems.iml @@ -1,11 +1,37 @@ - - - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/combinationsandpermutations/CombinationIterator.java b/src/main/java/combinationsandpermutations/CombinationIterator.java index 647c22a..352b1c8 100644 --- a/src/main/java/combinationsandpermutations/CombinationIterator.java +++ b/src/main/java/combinationsandpermutations/CombinationIterator.java @@ -1,4 +1,4 @@ -package CombinationsAndPermutations; +package combinationsandpermutations; // CombinationIterator iterator = new CombinationIterator("abc", 2); // creates the iterator. diff --git a/src/main/java/combinationsandpermutations/CombinationSum.java b/src/main/java/combinationsandpermutations/CombinationSum.java index 438eb49..327eb8e 100644 --- a/src/main/java/combinationsandpermutations/CombinationSum.java +++ b/src/main/java/combinationsandpermutations/CombinationSum.java @@ -1,4 +1,4 @@ -package CombinationsAndPermutations; +package combinationsandpermutations; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/main/java/combinationsandpermutations/Permutations.java b/src/main/java/combinationsandpermutations/Permutations.java index 37bb265..ead11cd 100644 --- a/src/main/java/combinationsandpermutations/Permutations.java +++ b/src/main/java/combinationsandpermutations/Permutations.java @@ -1,4 +1,4 @@ -package CombinationsAndPermutations; +package combinationsandpermutations; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/main/java/combinationsandpermutations/SplitUniqueSubstring.java b/src/main/java/combinationsandpermutations/SplitUniqueSubstring.java index cf4306f..8a5aa75 100644 --- a/src/main/java/combinationsandpermutations/SplitUniqueSubstring.java +++ b/src/main/java/combinationsandpermutations/SplitUniqueSubstring.java @@ -1,4 +1,4 @@ -package CombinationsAndPermutations; +package combinationsandpermutations; import java.util.HashSet; import java.util.Set; diff --git a/src/main/java/combinationsandpermutations/SubSets.java b/src/main/java/combinationsandpermutations/SubSets.java index 160c74f..dabe675 100644 --- a/src/main/java/combinationsandpermutations/SubSets.java +++ b/src/main/java/combinationsandpermutations/SubSets.java @@ -1,4 +1,4 @@ -package CombinationsAndPermutations; +package combinationsandpermutations; import java.util.*; diff --git a/src/main/java/graph/leetcode/AccountsMerge.java b/src/main/java/graph/leetcode/AccountsMerge.java index b61e9fd..b76e68d 100644 --- a/src/main/java/graph/leetcode/AccountsMerge.java +++ b/src/main/java/graph/leetcode/AccountsMerge.java @@ -11,6 +11,7 @@ * * https://www.youtube.com/watch?v=QHniHFvxAl8&ab_channel=ShiranAfergan * https://leetcode.com/problems/accounts-merge/ + * * Here, we use disjoint set union data structure to keep track of same user accounts. * We use a hash map to map emails to account's indices (index of the account in accounts list). * Note that different accounts (equivalently account ids) may belong to the same user. @@ -19,24 +20,24 @@ * If we observe that an email has been observed before, we know that both email ids must belong to different accounts which belong to the same user. * Thus, we fetch the account ids corresponding to this email id, one is the current account's index, and the other is the account index from the map. * We then perform union on the account indices. - * + * * In the end, all account ids which belong to the same user get grouped together and return the same account id on calling findSet. * For each email, we check which account id it belongs to, get that account's parent's id from the union structure, and add the email to that id in a new map. - * + * * a b c // now b, c have parent a * d e f // now e, f have parent d * g a d // now abc, def all merged to group g - * + * * parents populated after parsing 1st account: a b c * a->a * b->a * c->a - * + * * parents populated after parsing 2nd account: d e f * d->d * e->d * f->d - * + * * parents populated after parsing 3rd account: g a d * g->g * a->g @@ -55,6 +56,7 @@ public List> accountsMerge(List> accounts) { List emails = accounts.get(i); // Step 1: traverse all emails except names, if we have not seen an email before, put it with its index into map. // Otherwise, union the email to its parent index. + // we are starting j=1 because j=0 will contain the name not the email for(int j=1;j * Intuition: diff --git a/src/main/java/graph/leetcode/FriendCircles.java b/src/main/java/graph/leetcode/FriendCircles.java index 1a153e2..2d6d3ed 100644 --- a/src/main/java/graph/leetcode/FriendCircles.java +++ b/src/main/java/graph/leetcode/FriendCircles.java @@ -3,55 +3,55 @@ // similar to number of Islands public class FriendCircles { public int findCircleNum(int[][] M) { - UnionFind uf= new UnionFind(M.length); - for(int i=0;irank[rootY]){ - parent[rootY]=rootX; - }else if(rank[rootY]>rank[rootX]){ - parent[rootX]=rootY; - }else{ - parent[rootY]=rootX; + if (rank[rootX] > rank[rootY]) { + parent[rootY] = rootX; + } else if (rank[rootY] > rank[rootX]) { + parent[rootX] = rootY; + } else { + parent[rootY] = rootX; rank[rootX]++; } count--; } - public int getCount(){ + public int getCount() { return count; } } diff --git a/src/main/java/graph/leetcode/MinCostConnectAllPipes.java b/src/main/java/graph/leetcode/MinCostConnectAllPipes.java index 9996569..1c3e78c 100644 --- a/src/main/java/graph/leetcode/MinCostConnectAllPipes.java +++ b/src/main/java/graph/leetcode/MinCostConnectAllPipes.java @@ -6,59 +6,57 @@ import java.util.List; public class MinCostConnectAllPipes { - List graphEdges; + /** + * I take it this way: + * We cannot build any well. + * There is one and only one hidding well in my house (house 0). + * The cost to lay pipe between house[i] and my house is wells[i]. + * In order to supply water to the whole village, + * we need to make the village a connected graph. + */ public int minCostToSupplyWater(int n, int[] wells, int[][] pipes) { - graphEdges = new ArrayList<>(); - addEdges(n, wells, pipes); - return minCostKruskals(n); - } - - /// select edges based on Kruskals - with least edge node to be added first - private int minCostKruskals(int n) { - /// Sort edges in increasing order of edge value - graphEdges.sort(Comparator.comparingInt(a -> a[2])); - int minCost = 0, processedEdges = 0; - - DSU dsu = new DSU(n + 1); - for (int[] edge : graphEdges) { - /// check if this can be merged (in this case:`union`) to the existing graph component - if (dsu.union(edge[0], edge[1])) { - processedEdges++; - minCost += edge[2]; - /// Break processing once all edges are processed - if (processedEdges == n) break; - } - } - return minCost; - } + UnionFind uf = new UnionFind(n + 1); - private void addEdges(int n, int[] wells, int[][] pipes) { + List edges = new ArrayList<>(); // build an imaginary edge between node 0 to all other houses so that // even the wells are converted into edges. Now it's a proper MST problem for (int i = 0; i < n; i++) { - graphEdges.add(new int[]{0, i + 1, wells[i]}); + edges.add(new int[]{0, i + 1, wells[i]}); } - Collections.addAll(graphEdges, pipes); + Collections.addAll(edges, pipes); + + /// Sort edges in increasing order of edge value + edges.sort(Comparator.comparingInt(a -> a[2])); + + int res = 0; + for (int[] edge : edges) { + int x = edge[0], y = edge[1]; + if (uf.find(x) == uf.find(y)) { + continue; + } + uf.union(x, y); + res += edge[2]; + } + + return res; } - /// Disjoint Set Union Implementation - static class DSU { + static class UnionFind { int[] parent; int[] rank; - DSU(int n) { + UnionFind(int n) { parent = new int[n]; rank = new int[n]; for (int i = 0; i < n; i++) parent[i] = i; } - public int find(int x) { - if (x != parent[x]) { - parent[x] = find(parent[x]); - } - return parent[x]; + public int find(int n) { + if (parent[n] == n) return n; + parent[n] = find(parent[n]); + return parent[n]; } public boolean union(int x, int y) { diff --git a/src/main/java/graph/leetcode/NewRoadsMST.java b/src/main/java/graph/leetcode/NewRoadsMST.java index 0911dce..efe8ba1 100644 --- a/src/main/java/graph/leetcode/NewRoadsMST.java +++ b/src/main/java/graph/leetcode/NewRoadsMST.java @@ -7,7 +7,8 @@ /** * Given an undirected graph with n nodes labeled 1..n. Some of the nodes are already connected. - * The i-th edge connects nodes edges[i][0] and edges[i][1] together. Your task is to augment this set of edges with additional edges to connect all the nodes. + * The i-th edge connects nodes edges[i][0] and edges[i][1] together. + * Your task is to augment this set of edges with additional edges to connect all the nodes. * Find the minimum cost to add new edges between the nodes such that all the nodes are accessible from each other. * Input: n = 6, edges = [[1, 4], [4, 5], [2, 3]], newEdges = [[1, 2, 5], [1, 3, 10], [1, 6, 2], [5, 6, 5]] * Output: 7 @@ -59,12 +60,10 @@ public UF(int n) { count = n; } - public int find(int p) { - while (p != parent[p]) { - parent[p] = parent[parent[p]]; - p = parent[p]; - } - return p; + public int find(int n) { + if (parent[n] == n) return n; + parent[n] = find(parent[n]); + return parent[n]; } public void union(int p, int q) { diff --git a/src/main/java/internals/ConcurrentHashMap.java b/src/main/java/internals/ConcurrentHashMap.java index 7eccf84..ba431c6 100644 --- a/src/main/java/internals/ConcurrentHashMap.java +++ b/src/main/java/internals/ConcurrentHashMap.java @@ -102,6 +102,12 @@ public class ConcurrentHashMap { private MyHashMap myHashMap = new MyHashMap(); + public ConcurrentHashMap(int concurrencyLevel) { + locks = new Lock[concurrencyLevel]; + for (int i = 0; i < concurrencyLevel; i++) { + locks[i] = new ReentrantLock(); + } + } private class MyHashMap { private LinkedList[] lists = new LinkedList[INITIAL_CAPACITY]; @@ -182,14 +188,11 @@ int capacity() { return capacity; } } - - public ConcurrentHashMap(int concurrencyLevel) { - locks = new Lock[concurrencyLevel]; - for (int i = 0; i < concurrencyLevel; i++) { - locks[i] = new ReentrantLock(); - } + int capacity() { + return capacity; } + public ConcurrentHashMap() { this(DEFAULT_CONCURRENCY_LEVEL); } diff --git a/src/main/java/linkedLists/FlattenNestedIterator.java b/src/main/java/linkedLists/FlattenNestedIterator.java index 15c6b25..2569013 100644 --- a/src/main/java/linkedLists/FlattenNestedIterator.java +++ b/src/main/java/linkedLists/FlattenNestedIterator.java @@ -28,10 +28,10 @@ public boolean hasNext() { } private void populateList(List nestedList) { - if (nestedList == null || nestedList.size() == 0) return; - for (int i = 0; i < nestedList.size(); i++) { - populateList(nestedList.get(i).getList()); - if (nestedList.get(i).getInteger() != null) flattenedList.add(nestedList.get(i).getInteger()); + if (nestedList == null || nestedList.isEmpty()) return; + for (NestedInteger nestedInteger : nestedList) { + populateList(nestedInteger.getList()); + if (nestedInteger.getInteger() != null) flattenedList.add(nestedInteger.getInteger()); } } } diff --git a/src/main/java/linkedLists/Node.java b/src/main/java/linkedLists/Node.java index de06ce0..31f74fe 100644 --- a/src/main/java/linkedLists/Node.java +++ b/src/main/java/linkedLists/Node.java @@ -2,8 +2,8 @@ public class Node { - Node left; - Node right; + public Node left; + public Node right; public Node next; public int data; public Node child; diff --git a/src/main/java/linkedLists/RotateList.java b/src/main/java/linkedLists/RotateList.java index c726a53..70cf43b 100644 --- a/src/main/java/linkedLists/RotateList.java +++ b/src/main/java/linkedLists/RotateList.java @@ -24,6 +24,6 @@ public ListNode rotateRight(ListNode head, int k) { class ListNode { int val; - ListNode next; + public ListNode next; ListNode(int x) { val = x; } } \ No newline at end of file diff --git a/src/main/java/multithreading/educative/AsyncToSyncConverter.java b/src/main/java/multithreading/educative/AsyncToSyncConverter.java index e221d9a..00fdafc 100644 --- a/src/main/java/multithreading/educative/AsyncToSyncConverter.java +++ b/src/main/java/multithreading/educative/AsyncToSyncConverter.java @@ -3,9 +3,7 @@ public class AsyncToSyncConverter { public static void main(String args[]) throws Exception { SynchronousExecutor executor = new SynchronousExecutor(); - executor.asynchronousExecution(() -> { - System.out.println("I am done"); - }); + executor.asynchronousExecution(() -> System.out.println("I am done")); System.out.println("main thread exiting..."); } diff --git a/src/main/java/multithreading/practice/Foo.java b/src/main/java/multithreading/practice/Foo.java index 2bc81b6..920504e 100644 --- a/src/main/java/multithreading/practice/Foo.java +++ b/src/main/java/multithreading/practice/Foo.java @@ -1,6 +1,5 @@ package multithreading.practice; -import org.junit.Test; import java.util.concurrent.Semaphore; @@ -102,7 +101,6 @@ private Thread createThread(Foo foo, int index) { }); } - @Test public void test0() throws InterruptedException { Foo foo = new Foo(); int[] input = {1, 2, 3}; @@ -112,7 +110,6 @@ public void test0() throws InterruptedException { } } - @Test public void test1() throws InterruptedException { Foo foo = new Foo(); int[] input = {1, 3, 2}; diff --git a/src/main/java/practiceproblems/CloneGraph.java b/src/main/java/practiceproblems/CloneGraph.java index d1de082..7962e97 100644 --- a/src/main/java/practiceproblems/CloneGraph.java +++ b/src/main/java/practiceproblems/CloneGraph.java @@ -1,6 +1,11 @@ package practiceproblems; -import java.util.*; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Queue; /** * https://leetcode.com/problems/clone-graph/ diff --git a/src/main/java/practiceproblems/NextPermutation.java b/src/main/java/practiceproblems/NextPermutation.java index 91b0969..5fe78b4 100644 --- a/src/main/java/practiceproblems/NextPermutation.java +++ b/src/main/java/practiceproblems/NextPermutation.java @@ -10,7 +10,7 @@ public void nextPermutation(int[] nums) { // pivot is the element just before the non-increasing (weakly decreasing) suffix /*2*/ int pivot = indexOfLastPeak(nums) - 1; - // paritions nums into [prefix pivot suffix] + // partitions nums into [prefix pivot suffix] if (pivot != -1) { int nextPrefix = lastIndexOfGreater(nums, nums[pivot]); // in the worst case it's suffix[0] // next prefix must exist because pivot < suffix[0], otherwise pivot would be part of suffix @@ -60,4 +60,6 @@ void swap(int[] nums, int i, int j) { nums[i] = nums[j]; nums[j] = temp; } + + } diff --git a/src/main/java/practiceproblems/PermutationInString.java b/src/main/java/practiceproblems/PermutationInString.java index 27640cd..e277156 100644 --- a/src/main/java/practiceproblems/PermutationInString.java +++ b/src/main/java/practiceproblems/PermutationInString.java @@ -3,6 +3,8 @@ import java.util.Arrays; /** + * tricky sliding window + * * Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. * In other words, one of the first string's permutations is the substring of the second string. * Input:s1= "ab" s2 = "eidboaoo" diff --git a/src/main/java/practiceproblems/SerializeDeserializeBST.java b/src/main/java/practiceproblems/SerializeDeserializeBST.java index b6dd21a..7b80c13 100644 --- a/src/main/java/practiceproblems/SerializeDeserializeBST.java +++ b/src/main/java/practiceproblems/SerializeDeserializeBST.java @@ -39,19 +39,19 @@ public Queue buildIntArr(String data) { return queue; } - public TreeNode bulidTreeFromArray(Queue treeVals) { - if (treeVals.isEmpty()) return null; + public TreeNode bulidTreeFromArray(Queue treeValues) { + if (treeValues.isEmpty()) return null; - Integer rootVal = treeVals.poll(); + Integer rootVal = treeValues.poll(); TreeNode root = new TreeNode(rootVal); - Queue smallerVals = new LinkedList<>(); + Queue smallerValues = new LinkedList<>(); - while (!treeVals.isEmpty() && treeVals.peek() < rootVal) { - smallerVals.offer(treeVals.poll()); + while (!treeValues.isEmpty() && treeValues.peek() < rootVal) { + smallerValues.offer(treeValues.poll()); } - root.left = bulidTreeFromArray(smallerVals); - root.right = bulidTreeFromArray(treeVals); + root.left = bulidTreeFromArray(smallerValues); + root.right = bulidTreeFromArray(treeValues); return root; diff --git a/src/main/java/practiceproblems/WordLadder.java b/src/main/java/practiceproblems/WordLadder.java index 32dd282..9506a26 100644 --- a/src/main/java/practiceproblems/WordLadder.java +++ b/src/main/java/practiceproblems/WordLadder.java @@ -12,7 +12,7 @@ public int ladderLength(String beginWord, String endWord, List wordList) if (!set.contains(endWord)) return 0; // end word itself not in set Queue queue = new LinkedList<>(); queue.add(beginWord); - int count = 1; + int level = 1; while (!queue.isEmpty()) { @@ -30,8 +30,8 @@ public int ladderLength(String beginWord, String endWord, List wordList) charArray[j] = ch; String newWord = String.valueOf(charArray); if (set.contains(newWord)) { - if (newWord.equals(endWord)) { // if found return count - return count + 1; + if (newWord.equals(endWord)) { // if found return level + return level + 1; } queue.add(newWord);// else add to queue and continue set.remove(newWord);// because you already reached this word, no need to see again @@ -41,7 +41,7 @@ public int ladderLength(String beginWord, String endWord, List wordList) } } - count++; + level++; } return 0; diff --git a/src/main/java/practiceproblems/WordSearch.java b/src/main/java/practiceproblems/WordSearch.java index d8d654e..206f480 100644 --- a/src/main/java/practiceproblems/WordSearch.java +++ b/src/main/java/practiceproblems/WordSearch.java @@ -4,6 +4,11 @@ * https://leetcode.com/problems/word-search/ * * tricky dfs + * + * I don't think BFS is feasible here. + * This is because we would need to separately track visited_elements for each entry in the queue which will increase the Space Complexity to skyrocket. + * Every time you dequeue and move in 3 other directions (worst case), you will be creating clones of the visited array for each of 3 directions. + * In case of BFS, space complexity will be O(nm3^(n^2 * m^2)) */ public class WordSearch { diff --git a/src/main/java/practiceproblems/WordSearchII.java b/src/main/java/practiceproblems/WordSearchII.java index ac3ac2d..8ec61fd 100644 --- a/src/main/java/practiceproblems/WordSearchII.java +++ b/src/main/java/practiceproblems/WordSearchII.java @@ -50,7 +50,7 @@ public TrieNode buildTrie(String[] words) { return root; } - private static class TrieNode { + static class TrieNode { TrieNode[] children = new TrieNode[26]; String word; } diff --git a/src/main/java/practiceproblems/parentheses/ValidParenthesesString.java b/src/main/java/practiceproblems/parentheses/ValidParenthesesString.java index 97b0959..51c260f 100644 --- a/src/main/java/practiceproblems/parentheses/ValidParenthesesString.java +++ b/src/main/java/practiceproblems/parentheses/ValidParenthesesString.java @@ -1,21 +1,9 @@ package practiceproblems.parentheses; /** - * Given a string containing only three types of characters: '(', ')' and '*', - * write a function to check whether this string is valid. - * We define the validity of a string by these rules: - *

- * Any left parenthesis '(' must have a corresponding right parenthesis ')'. - * Any right parenthesis ')' must have a corresponding left parenthesis '('. - * Left parenthesis '(' must go before the corresponding right parenthesis ')'. - * '*' could be treated as a single right parenthesis ')' or a single left parenthesis '(' or an empty string. - * An empty string is also valid. - *

- * Input: "(*))" - * Output: True - *

- * Input: "(*)" - * Output: True + * tricky braces + * + * https://leetcode.com/problems/valid-parenthesis-string/discuss/543521/Java-Count-Open-Parenthesis-O(n)-time-O(1)-space-Picture-Explain */ public class ValidParenthesesString { public boolean checkValidString(String s) { @@ -34,9 +22,36 @@ public boolean checkValidString(String s) { // if `*` become `` then nothing happens // So openCount will be in new range [cmin-1, cmax+1] } + + /** + * Case - 1: + * If cmax < 0, the number of ')' is lesser than 0. We immediately return false. + * Why : Let's take an example "())", in this case, cmax would be less than 0 because we have two ' )' and only one '('. + * Now irrespective of how many '*' we have, this sequence is already invalid, hence we return false. + */ if (cmax < 0) { return false; // Currently, don't have enough open parentheses to match close parentheses-> Invalid } + + /** + * Case - 2: + * cmin = Math.max(cmin, 0) + * + * The way I got to wrap my head around this was: + * Cmin and Cmax are both subtracted by 1, whenever we encounter a ")". + * Therefore, Case -1 covers the case in which we have more ")" than "(". + * Now the additional case we have to look at is, when we have extra ")", which we can account to the "*" [Since we do --cmin here]. + * + * However, we can just ignore the "*" as empty strings in this case. + * Example: "( ) * * " + * cmax = 1 0 1 2 + * cmin = 1 0 0 0 -> We don't want the last two to become 1 0 -1 -2 + * + * We can see that the cmin values would become -1 and -2 for the last two "*". + * However this would mean we would be adding additional ")", which makes the sequence "()))". + * This is not a right sequence. Therefore, we must keep them as empty strings. + * Hence we do a max with 0, which implies that if we have additional "*", we don't take them as ")", instead we treat them as empty strings. + */ // For example: ())( cmin = Math.max(cmin, 0); // It's invalid if open parentheses count < 0 that's why cmin can't be negative } diff --git a/src/main/java/trees/BinaryTreesUpsideDown.java b/src/main/java/trees/BinaryTreesUpsideDown.java index 8bab007..546eed0 100644 --- a/src/main/java/trees/BinaryTreesUpsideDown.java +++ b/src/main/java/trees/BinaryTreesUpsideDown.java @@ -4,6 +4,9 @@ * https://leetcode.com/problems/binary-tree-upside-down/ */ public class BinaryTreesUpsideDown { + /** + * tricky tree swap + */ public TreeNode upsideDownBinaryTree(TreeNode root) { TreeNode curr = root; TreeNode next = null; diff --git a/src/main/java/trees/LowestCommonAncestor.java b/src/main/java/trees/LowestCommonAncestor.java index 2923f75..f8d6fd2 100644 --- a/src/main/java/trees/LowestCommonAncestor.java +++ b/src/main/java/trees/LowestCommonAncestor.java @@ -5,6 +5,18 @@ public class LowestCommonAncestor { + public TreeNode lowestCommonAncestorBinarySearchTree(TreeNode root, TreeNode p, TreeNode q) { + while (root != null) { + if (root.val > p.val && root.val > q.val) + root = root.left; + else if (root.val < p.val && root.val < q.val) + root = root.right; + else + return root; + } + return root; + } + /** * It is guaranteed that both p and q are in the tree. * A node can be a descendant of itself. @@ -144,10 +156,10 @@ private TreeNode lcaHelper(TreeNode root, Set s) { } static class Node { - Node left; - Node right; - Node parent; - int data; + public Node left; + public Node right; + public Node parent; + public int data; } } diff --git a/src/main/java/trees/MaxWidthOfBinaryTree.java b/src/main/java/trees/MaxWidthOfBinaryTree.java index b55368a..779493c 100644 --- a/src/main/java/trees/MaxWidthOfBinaryTree.java +++ b/src/main/java/trees/MaxWidthOfBinaryTree.java @@ -1,6 +1,5 @@ package trees; -import trees.TreeNode; import java.util.HashMap; import java.util.LinkedList; diff --git a/src/main/java/trees/TreeNode.java b/src/main/java/trees/TreeNode.java index b5e568f..ccd4a89 100644 --- a/src/main/java/trees/TreeNode.java +++ b/src/main/java/trees/TreeNode.java @@ -1,9 +1,12 @@ package trees; +import java.util.Collection; + public class TreeNode { public TreeNode left; public TreeNode right; - public int val; + public int val; + Collection children; public TreeNode(int val) { this.val = val; From 6e553a8b62f318d26986e7bd43f3928bf253cded Mon Sep 17 00:00:00 2001 From: vickey290 Date: Sat, 17 Sep 2022 13:55:53 +0530 Subject: [PATCH 47/51] 2022 problem set --- src/main/java/graph/leetcode/BombEnemy.java | 42 +++++++++++++++++++ .../practiceproblems/PairDivisibleBy60.java | 11 ++++- 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 src/main/java/graph/leetcode/BombEnemy.java diff --git a/src/main/java/graph/leetcode/BombEnemy.java b/src/main/java/graph/leetcode/BombEnemy.java new file mode 100644 index 0000000..bc99863 --- /dev/null +++ b/src/main/java/graph/leetcode/BombEnemy.java @@ -0,0 +1,42 @@ +package graph.leetcode; + +/** + * https://leetcode.com/problems/bomb-enemy/ + */ +public class BombEnemy { + + private int row; + private int col; + private int max = 0; + private int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; + + + public int maxKilledEnemies(char[][] grid) { + if (grid == null || grid.length == 0) + return 0; + row = grid.length; + col = grid[0].length; + for (int i = 0; i < row; i++) + for (int j = 0; j < col; j++) + if (grid[i][j] == '0') + max = Math.max(max, bfs(grid, i, j)); + return max; + } + + private int bfs(char[][] grid, int i, int j) { + int count = 0; + for (int[] dir : dirs) { + int x = i + dir[0]; + int y = j + dir[1]; + + while (x < row && y < col && x >= 0 && y >= 0 && grid[x][y] != 'W') { + if (grid[x][y] == 'E') + count++; + x = x + dir[0]; + y = y + dir[1]; + } + } + return count; + + } +} diff --git a/src/main/java/practiceproblems/PairDivisibleBy60.java b/src/main/java/practiceproblems/PairDivisibleBy60.java index 1b2c726..4af0264 100644 --- a/src/main/java/practiceproblems/PairDivisibleBy60.java +++ b/src/main/java/practiceproblems/PairDivisibleBy60.java @@ -18,7 +18,16 @@ public int numPairsDivisibleBy60(int[] time) { //2 SUM PROBLEM WITH K = 60 //O(n) time - int c[] = new int[60]; //because we know its going upto 0 to 59 + /** + * the solution is (time[i]+time[j]%60 == 0) + * if we replace time[j] = 20 + * then we can have time[i] as either 40 , 100 or 160 + * the 40, 100 and 160 if we mod with 60 the results would be 40 + * + * let's take this arr = [60, 30, 20, 150, 120, 100, 30] + * if we mod with 60 then the arr would look like [0, 30, 20, 30, 0, 40, 30] + */ + int[] c = new int[60]; //because we know its going upto 0 to 59 int result = 0; for (int t : time) { // System.out.println(t % 60) From f6477fc112c09cdca82c9cee2fa8fc3141600e6b Mon Sep 17 00:00:00 2001 From: Vignesh Rajarajan Date: Tue, 28 Nov 2023 14:40:42 +0530 Subject: [PATCH 48/51] new problems --- .idea/misc.xml | 2 +- .idea/modules.xml | 8 - Problems.iml | 37 - src/main/java/RandomProblemGenerator.java | 2 +- src/main/java/cess/AppleDivision.java | 31 + src/main/java/cess/BinaryExponentiation.java | 20 + src/main/java/cess/GreyCode.java | 70 ++ src/main/java/cess/NumberFromSpiral.java | 39 + src/main/java/cess/PalindromeReorder.java | 49 + src/main/java/cess/TowerOfHanoi.java | 20 + src/main/java/cess/TwoKnights.java | 22 + .../graph/leetcode/MaxProbabilityPath.java | 1 - .../java/graph/leetcode/NetworkDelayTime.java | 29 +- src/main/java/graph/leetcode/Pair.java | 25 + .../FlipMaximizeZeroesSubarrayKadane.java | 1 - .../practiceproblems/MaxPointsInLine.java | 4 +- .../practiceproblems/recursion/NQueens.java | 5 +- .../practiceproblems/stack/StockSpanner.java | 2 +- src/main/java/trees/AVLTree.java | 46 +- .../compile/default-compile/createdFiles.lst | 985 ------------------ .../compile/default-compile/inputFiles.lst | 763 -------------- 21 files changed, 334 insertions(+), 1827 deletions(-) delete mode 100644 .idea/modules.xml delete mode 100644 Problems.iml create mode 100644 src/main/java/cess/AppleDivision.java create mode 100644 src/main/java/cess/BinaryExponentiation.java create mode 100644 src/main/java/cess/GreyCode.java create mode 100644 src/main/java/cess/NumberFromSpiral.java create mode 100644 src/main/java/cess/PalindromeReorder.java create mode 100644 src/main/java/cess/TowerOfHanoi.java create mode 100644 src/main/java/cess/TwoKnights.java create mode 100644 src/main/java/graph/leetcode/Pair.java delete mode 100644 target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst delete mode 100644 target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst diff --git a/.idea/misc.xml b/.idea/misc.xml index d460235..35bf185 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,5 @@ - +

+ * https://cses.fi/problemset/task/1623 + * https://www.youtube.com/watch?v=raGn3saVfa8 + */ +public class AppleDivision { + + public static long solve(int[] arr) { + long result = Long.MAX_VALUE; + int n = arr.length; + for (int mask = 0; mask < (1 << n); mask++) { + + long sumA = 0; + long sumB = 0; + + for (int pos = 0; pos < n; pos++) { + if ((mask & (1 << pos)) > 0) { + sumA += arr[pos]; + } else { + sumB += arr[pos]; + } + } + result = Math.min(result, Math.abs(sumA - sumB)); + + } + return result; + } +} diff --git a/src/main/java/cess/BinaryExponentiation.java b/src/main/java/cess/BinaryExponentiation.java new file mode 100644 index 0000000..eea8ba6 --- /dev/null +++ b/src/main/java/cess/BinaryExponentiation.java @@ -0,0 +1,20 @@ +package cess; + +public class BinaryExponentiation { + + /** + * Fast method to compute exponent values a^b + * https://www.youtube.com/watch?v=L-Wzglnm4dM + */ + public int power(int a, int b) { + + int result = 1; + + while (b > 0) { + if (b == 1) result *= a; + a *= a; + b /= 2; + } + return result; + } +} diff --git a/src/main/java/cess/GreyCode.java b/src/main/java/cess/GreyCode.java new file mode 100644 index 0000000..9e2a04b --- /dev/null +++ b/src/main/java/cess/GreyCode.java @@ -0,0 +1,70 @@ +package cess; + + +import java.util.ArrayList; +import java.util.BitSet; +import java.util.List; + +/** + * https://www.youtube.com/watch?v=KOD2BFauQbA + * A Gray code is a list of all 2n + * bit strings of length n + * , where any two successive strings differ in exactly one bit (i.e., their Hamming distance is one). + * Your task is to create a Gray code for a given length n + *

+ *

+ * Input: + * 2 + *

+ * Output: + * 00 -| + * 01 -| - difference 1 + * 11 + * 10 + */ +public class GreyCode { + + public static List greyCode(int n) { + + if (n == 0) return new ArrayList<>(); + if (n == 1) { + List baseRes = new ArrayList<>(); + baseRes.add("0"); + baseRes.add("1"); + return baseRes; + } + + List intermediateResult = greyCode(n - 1); + List finalResult = new ArrayList<>(); + for (String s : intermediateResult) { + finalResult.add("0" + s); + } + + for (int i = intermediateResult.size() - 1; i >= 0; i--) { + finalResult.add("1" + intermediateResult.get(i)); + } + return finalResult; + + } + + public static List greyCode1(int n) { + List finalResult = new ArrayList<>(); + for (int i = 0; i < 1 << n; i++) { + int val = i ^ (i >> 1); + + // If len = 4 and val = 1, + // Integer.toBinaryString( (1 << len) | val ) => returns the string "10001", then + // "10001".substring( 1 ) discards the very first character. So we obtain what we want: + // "0001" + finalResult.add(Integer.toBinaryString((1 << n) | val).substring(1)); + } + return finalResult; + } + + public static void main(String[] args) { + BitSet b = new BitSet(); + greyCode(3).forEach(System.out::println); + System.out.println(); + greyCode1(3).forEach(System.out::println); + } +} diff --git a/src/main/java/cess/NumberFromSpiral.java b/src/main/java/cess/NumberFromSpiral.java new file mode 100644 index 0000000..6829749 --- /dev/null +++ b/src/main/java/cess/NumberFromSpiral.java @@ -0,0 +1,39 @@ +package cess; + +/** + * https://cses.fi/problemset/task/1071 + * https://www.youtube.com/watch?v=pNN35ZdX77Y + *

+ * tricky complex + */ +public class NumberFromSpiral { + + public int getValueAtIndex(int i, int j) { + + int max = Math.max(i, j); + + if ((max & 1) == 0) { + if (j == 1) { + return max * max; + } + + if (i < max) { + return getValueAtIndex(max, max) - (max - i); + } else if (i == max) { + return max * max - (j - 1); + } + } else { + if (i == 1) { + return max * max; + } + + if (j < max) { + return getValueAtIndex(max, max) - (max - j); + } else { + return max * max - (i - 1); + } + } + return -1; + } + +} diff --git a/src/main/java/cess/PalindromeReorder.java b/src/main/java/cess/PalindromeReorder.java new file mode 100644 index 0000000..ab3b984 --- /dev/null +++ b/src/main/java/cess/PalindromeReorder.java @@ -0,0 +1,49 @@ +package cess; + +/** + * https://cses.fi/problemset/task/1755 + * https://www.youtube.com/watch?v=ou8Xhp_YO8E&t=767s + */ +public class PalindromeReorder { + + public static String reorderToPalindrome(String s) { + + int[] arr = new int[26]; + + for (char c : s.toCharArray()) { + arr[c - 'A']++; + } + + int oddCharPos = -1; + + for (int i = 0; i < 26; i++) { + if (arr[i] == 1 && oddCharPos != -1) { + return ""; + } else if (arr[i] == 1 && oddCharPos == -1) { + oddCharPos = i; + } + } + + if (oddCharPos == -1 && s.length() % 2 == 1) return ""; + if (oddCharPos != -1 && s.length() % 2 == 0) return ""; + + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < 26; i++) { + for (int j = 0; j < arr[i] / 2; j++) { + sb.append(Character.toString(i + 'A')); + } + } + + String s1 = sb.reverse().toString(); + sb.reverse(); + if (oddCharPos != -1) { + sb.append(Character.toString(oddCharPos + 'A')); + } + return sb.append(s1).toString(); + } + + public static void main(String[] args) { + System.out.println(reorderToPalindrome("AAAACACBA")); + } +} diff --git a/src/main/java/cess/TowerOfHanoi.java b/src/main/java/cess/TowerOfHanoi.java new file mode 100644 index 0000000..5bbf0fa --- /dev/null +++ b/src/main/java/cess/TowerOfHanoi.java @@ -0,0 +1,20 @@ +package cess; + +public class TowerOfHanoi { + + public static void solve(String from, String to, String aux, int n) { + if (n == 1) { + System.out.println("Take disk 1 from rod " + from + " to rod " + to); + return; + } + solve(from, aux, to, n - 1); + System.out.println("Take disk " + n + " from rod " + from + " to rod " + to); + + System.out.println(); + solve(aux, to, from, n - 1); + } + + public static void main(String[] args) { + solve("A", "C", "B", 3); + } +} diff --git a/src/main/java/cess/TwoKnights.java b/src/main/java/cess/TwoKnights.java new file mode 100644 index 0000000..1eba0b7 --- /dev/null +++ b/src/main/java/cess/TwoKnights.java @@ -0,0 +1,22 @@ +package cess; + +/** + * https://cses.fi/problemset/task/1072 + *

+ * https://www.youtube.com/watch?v=nKVubpav6Uk + */ +public class TwoKnights { + + public int getNumberOfWays(int n) { + + // number af all possibilities to place 2 knights on n*n board + // binomial formula + int numberOfAllPossibilities = (((n * n) * (n * n) - 1) / 2); + + //number Of rectangles Where two knights can attack each other + int noOfRect = 4 * (n - 1) * (n - 2); + + // this return no of ways the two knights cannot attack each other + return numberOfAllPossibilities - noOfRect; + } +} diff --git a/src/main/java/graph/leetcode/MaxProbabilityPath.java b/src/main/java/graph/leetcode/MaxProbabilityPath.java index 89644b7..10976b8 100644 --- a/src/main/java/graph/leetcode/MaxProbabilityPath.java +++ b/src/main/java/graph/leetcode/MaxProbabilityPath.java @@ -1,6 +1,5 @@ package graph.leetcode; -import javafx.util.Pair; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/main/java/graph/leetcode/NetworkDelayTime.java b/src/main/java/graph/leetcode/NetworkDelayTime.java index a582e5d..79f5e2e 100644 --- a/src/main/java/graph/leetcode/NetworkDelayTime.java +++ b/src/main/java/graph/leetcode/NetworkDelayTime.java @@ -1,16 +1,11 @@ package graph.leetcode; -import javafx.util.Pair; + +import lombok.Getter; +import lombok.Setter; import java.util.*; -/** - * There are N network nodes, labelled 1 to N. - * - * Given times, a list of travel times as directed edges times[i] = (u, v, w), where u is the source node, v is the target node, - * and w is the time it takes for a signal to travel from source to target. - * - * Now, we send a signal from a certain node K. How long will it take for all nodes to receive the signal? If it is impossible, return -1. - */ + public class NetworkDelayTime { public int networkDelayTime(int[][] times, int N, int K) { @@ -28,7 +23,7 @@ public int networkDelayTime(int[][] times, int N, int K) { int[] signalReceivedAt = new int[N + 1]; Arrays.fill(signalReceivedAt, Integer.MAX_VALUE); //distance, node into pq - Queue pq = new PriorityQueue<>((a,b) -> (a[0] - b[0])); + Queue pq = new PriorityQueue<>((a, b) -> (a[0] - b[0])); pq.add(new int[]{0, K}); @@ -42,19 +37,21 @@ public int networkDelayTime(int[][] times, int N, int K) { only if the current path takes less time than the value at signalReceivedAt[neighborNode]. Update the time at signalReceivedAt[neighborNode] to current path time. */ - while(!pq.isEmpty()){ + while (!pq.isEmpty()) { int[] cur = pq.remove(); int currNode = cur[1]; int currNodeTime = cur[0]; - if (visited.contains(currNode)) { continue; } + if (visited.contains(currNode)) { + continue; + } if (currNodeTime > signalReceivedAt[currNode]) { continue; } visited.add(currNode); - if(adj.containsKey(currNode)){ - for(Pair next : adj.get(currNode)){ + if (adj.containsKey(currNode)) { + for (Pair next : adj.get(currNode)) { int time = next.getKey(); int neighborNode = next.getValue(); if (signalReceivedAt[neighborNode] > currNodeTime + time) { @@ -74,7 +71,7 @@ public int networkDelayTime(int[][] times, int N, int K) { } public int networkDelayTime_BF(int[][] times, int N, int K) { - double[] disTo = new double[N+1]; + double[] disTo = new double[N + 1]; Arrays.fill(disTo, Double.POSITIVE_INFINITY); disTo[K - 1] = 0; for (int i = 1; i < N; i++) { @@ -84,7 +81,7 @@ public int networkDelayTime_BF(int[][] times, int N, int K) { } } double res = Double.MIN_VALUE; - for (double i: disTo) { + for (double i : disTo) { res = Math.max(i, res); } return res == Double.POSITIVE_INFINITY ? -1 : (int) res; diff --git a/src/main/java/graph/leetcode/Pair.java b/src/main/java/graph/leetcode/Pair.java new file mode 100644 index 0000000..a85ae15 --- /dev/null +++ b/src/main/java/graph/leetcode/Pair.java @@ -0,0 +1,25 @@ +package graph.leetcode; + +import lombok.Getter; +import lombok.Setter; + +/** + * There are N network nodes, labelled 1 to N. + *

+ * Given times, a list of travel times as directed edges times[i] = (u, v, w), where u is the source node, v is the target node, + * and w is the time it takes for a signal to travel from source to target. + *

+ * Now, we send a signal from a certain node K. How long will it take for all nodes to receive the signal? If it is impossible, return -1. + */ + +@Getter +@Setter +public class Pair { + public T key; + public U value; + + public Pair(T key, U value) { + this.key = key; + this.value = value; + } +} diff --git a/src/main/java/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java b/src/main/java/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java index 92b752f..da38c9b 100644 --- a/src/main/java/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java +++ b/src/main/java/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java @@ -1,6 +1,5 @@ package practiceproblems; -import javafx.util.Pair; /** * https://www.geeksforgeeks.org/maximize-number-0s-flipping-subarray/ diff --git a/src/main/java/practiceproblems/MaxPointsInLine.java b/src/main/java/practiceproblems/MaxPointsInLine.java index 2500833..18c7cf7 100644 --- a/src/main/java/practiceproblems/MaxPointsInLine.java +++ b/src/main/java/practiceproblems/MaxPointsInLine.java @@ -1,6 +1,8 @@ package practiceproblems; -import javafx.util.Pair; + + +import graph.leetcode.Pair; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/practiceproblems/recursion/NQueens.java b/src/main/java/practiceproblems/recursion/NQueens.java index 766debe..0a2bb95 100644 --- a/src/main/java/practiceproblems/recursion/NQueens.java +++ b/src/main/java/practiceproblems/recursion/NQueens.java @@ -1,6 +1,7 @@ package practiceproblems.recursion; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -18,9 +19,7 @@ public List> solveNQueens(int n) { List> result = new ArrayList<>(); char[][] board = new char[n][n]; for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - board[i][j] = '.'; - } + Arrays.fill(board[i], '.'); } nQueensHelper(0, n, board, result); diff --git a/src/main/java/practiceproblems/stack/StockSpanner.java b/src/main/java/practiceproblems/stack/StockSpanner.java index 69e6db7..f191b0e 100644 --- a/src/main/java/practiceproblems/stack/StockSpanner.java +++ b/src/main/java/practiceproblems/stack/StockSpanner.java @@ -1,7 +1,7 @@ package practiceproblems.stack; -import javafx.util.Pair; +import graph.leetcode.Pair; import java.util.ArrayDeque; import java.util.Deque; diff --git a/src/main/java/trees/AVLTree.java b/src/main/java/trees/AVLTree.java index 4e82d7d..09e9059 100644 --- a/src/main/java/trees/AVLTree.java +++ b/src/main/java/trees/AVLTree.java @@ -101,18 +101,50 @@ public boolean isEmpty() { return root == null; } + /** + * LL Rotation + * It is a type of single rotation that is performed when the tree gets unbalanced, + * upon insertion of a node into the left subtree of the left child of the imbalance node i.e., upon Left-Left (LL) insertion. + * This imbalance indicates that the tree is heavy on the left side. + * Hence, a right rotation is applied, left heaviness imbalance is countered and the tree becomes a balanced tree + * RR Rotation + * It is a type of single rotation that is performed when the tree gets unbalanced, + * upon insertion of a node into the right subtree of the right child of the imbalance node i.e., upon Right-Right (RR) insertion. + * This imbalance indicates that the tree is heavy on the right side. + * Hence, a left rotation is applied, right heaviness imbalance is countered and the tree becomes a balanced tree + * LR Rotation + * It is a type of double rotation that is performed when the tree gets unbalanced, + * upon insertion of a node into the right subtree of the left child of the imbalance node i.e., upon Left-Right (LR) insertion. + * Apply RR Rotation on the left subtree of the imbalanced node as the left child of the imbalanced node is right-heavy. + * This process flips the tree and converts it into a left-skewed tree + * This is now the case of LL rotation and by rotating the tree along the edge of the imbalanced node. + * RL Rotation + * It is similar to LR rotation but it is performed when the tree gets unbalanced, + * upon insertion of a node into the left subtree of the right child of the imbalance node + * Apply LL Rotation on the right subtree of the imbalanced node as the right child of the imbalanced node is left-heavy. + * This process flips the tree and converts it into a right-skewed tree. + * Perform RR Rotation on the imbalanced node to balance the right-skewed tree. + * + * + * @param node + * @return + */ private Node applyRotation(Node node) { - int balance = balance(node); - if (balance > 1) { - if (balance(node.getLeftChild()) < 0) { + // left heavy situation + if (height(node.getLeftChild()) - height(node.getRightChild()) > 1) { + if (height(node.getLeftChild().getLeftChild()) - height(node.getLeftChild().getRightChild()) < 0) { + // LR situation node.setLeftChild(rotateLeft(node.getLeftChild())); } + // LL situation return rotateRight(node); } - if (balance < -1) { - if (balance(node.getRightChild()) > 0) { + if (height(node.getLeftChild()) - height(node.getRightChild()) < -1) { // right heavy situation + if (height(node.getRightChild()) > 0) { + // RL situation node.setRightChild(rotateRight(node.getRightChild())); } + // RR situation return rotateLeft(node); } return node; @@ -146,10 +178,6 @@ private void updateHeight(Node node) { node.setHeight(maxHeight + 1); } - private int balance(Node node) { - return node != null ? height(node.getLeftChild()) - height(node.getRightChild()) : 0; - } - private int height(Node node) { return node != null ? node.getHeight() : 0; } diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst deleted file mode 100644 index 7b182e0..0000000 --- a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +++ /dev/null @@ -1,985 +0,0 @@ -practiceproblems/CountMinimumStepsToFormDesiredInputArray.class -graph/leetcode/SentenceSimilarityII$UnionFind.class -practiceproblems/CheckPalindromePermutation.class -graph/cycle/Edge.class -multithreading/educative/DeferredCallbackExecutor.class -practiceproblems/jumpGame/VideoStitching.class -machinecoding/splitwise/ExpenseService$1.class -dynamicProgramming/palindrome/LongestPalindromicSubstring.class -practiceproblems/design/UndergroundSystem$Passenger.class -reflections/dynamicProxy/external/impl/HttpClient.class -graph/interview/DisjointSet$Node.class -practiceproblems/stack/AsteroidCollision.class -internals/QuadTree$Point.class -practiceproblems/MaxSumTwoNonOverlappingSubArray.class -reflections/dynamicProxy/external/impl/DatabaseReaderImpl.class -binarysearch/FirstBadVersion.class -graph/leetcode/MatrixStoneRemoval$UnionFind.class -linkedLists/Top20LinkedListQuestions.class -lld/auctionSystem/services/strategies/BuyerViewAuctionDetails.class -graph/cycle/CycleUndirectedGraph.class -graph/leetcode/EquationEquality.class -practiceproblems/tries/MapSum$TrieNode.class -practiceproblems/TrailingZeroes.class -multithreading/com/safecabs/exceptions/UnRegisteredPassengerException.class -reflections/methodDiscovery/ProductTest.class -graph/leetcode/NewRoadsMST.class -dynamicProgramming/AssemblyLineScheduling.class -practiceproblems/MinimumWindowSubstring.class -binarysearch/NumberOfDaysToMakeMBouquets.class -graph/bellmanFord/NegativeException.class -binarysearch/ShipPackageWithNDays.class -graph/shortestPath/Graph.class -practiceproblems/tries/WordDictionary.class -practiceproblems/design/TimeMap.class -lld/vendingmachine/HasMoneyState.class -practiceproblems/ConstructBSTFromPreorder.class -linkedLists/MergeTwoLinkedList.class -linkedLists/FlattenLinkedList.class -practiceproblems/ConstructTreeFromInorderAndPreorder.class -practiceproblems/recursion/SudokuSolver.class -practiceproblems/ComplexNumberMultiply.class -practiceproblems/NonDecreasingArray.class -graph/leetcode/GraphBiPartite.class -multithreading/thread/PrintOddEvenByTwoThreads$EvenThread.class -practiceproblems/design/LRUCache1$1.class -graph/primsAlgorithm/BinaryMinHeap$Node.class -lld/auctionSystem/enums/Channel.class -reflections/topologicalsort/annotations/Annotations$FinalResult.class -lld/auctionSystem/repository/SellerRepository.class -graph/leetcode/MinPathHavingMaxDifference.class -graph/bellmanFord/Vertex.class -dynamicProgramming/BoxStacking.class -practiceproblems/intervals/BalloonBurst.class -reflections/init/Main.class -practiceproblems/BackspaceCompare.class -dynamicProgramming/lcs/TwoStringInterleavingToFormThird.class -reflections/game/internal/ComputerPlayer.class -graph/kruskalAlgorithm/KruskalMST.class -strings/stringProblems/Combination.class -java8/Functional.class -machinecoding/splitwise/ExpenseService.class -practiceproblems/DungeonGame.class -dynamicProgramming/lcs/RussianDollEnvelope.class -reflections/dynamicProxy/external/impl/DatabaseReader.class -machinecoding/splitwise/ExactSplit.class -lld/auctionSystem/services/PublisherService.class -practiceproblems/KthSmallestMatrix.class -practiceproblems/LongestConsequtiveSequence.class -practiceproblems/FindPairs.class -practiceproblems/PlusOne.class -lld/auctionSystem/models/Event.class -graph/leetcode/AllPathsInGraph.class -lld/auctionSystem/models/Auction.class -internals/ThreadPool.class -multithreading/practice/OddSemaphore.class -dynamicProgramming/fibonacci/DecodeWays.class -practiceproblems/BinaryTreeCousins.class -practiceproblems/IntegerToBinary.class -dynamicProgramming/BooleanParenthesization.class -practiceproblems/RemoveBSTGivenOutsideRange$BSTNode.class -practiceproblems/LeftMostColumnWithOne.class -multithreading/educative/AsyncToSyncConverter.class -graph/leetcode/RedundantConnection$UnionFind.class -practiceproblems/design/SnakeGame.class -practiceproblems/SurroundedRegions$Pair.class -binarysearch/BoatsToSave.class -multithreading/educative/DemonstrationThreadLocal$Counter.class -practiceproblems/BuildArray.class -dynamicProgramming/lcs/LongestStringChain.class -linkedLists/RandomListNode.class -practiceproblems/mergesort/CountNumbersLessThanSelf$ArrayValWithOrigIdx.class -practiceproblems/AircraftMovieDuration.class -reflections/topologicalsort/Main.class -practiceproblems/NextGreaterNumber.class -practiceproblems/SortANearlySortedArray.class -multithreading/educative/ReadWriteLock.class -graph/leetcode/FindAllSafeStates$State.class -practiceproblems/MinimumWindowSubsequence.class -lld/auctionSystem/services/AuctionService.class -practiceproblems/stack/DecodeString.class -trees/TreeToDLL.class -multithreading/educative/superman/SupermanSlightlyBetter.class -lld/billsharing/service/NotificationServiceImpl.class -practiceproblems/ReverseString.class -practiceproblems/IsSubsequence.class -internals/HashMapJava8.class -trees/TwoSumTree.class -sorting/KthLargestElement$Solution.class -java8/IConfigurator.class -practiceproblems/RangeSum2D.class -practiceproblems/GameOfLife.class -internals/QuadTree.class -practiceproblems/stack/BasicCalculatorII.class -lld/billsharing/exceptions/InvalidExpenseState.class -graph/leetcode/ReconstructItenary.class -reflections/retries/app/configs/ConfigsLoader.class -reflections/customMockito/ExternalService.class -multithreading/thread/DeadLock.class -practiceproblems/TreasureIsland$Point.class -lld/auctionSystem/services/ObserverService.class -reflections/annotation/loaders/Cache.class -multithreading/practice/FizzBuzz.class -graph/leetcode/FindTheCity.class -practiceproblems/Trie.class -sorting/MinHeap.class -multithreading/thread/MyRunnable.class -machinecoding/splitwise/Expense.class -linkedLists/MiddleElement.class -reflections/retries/Main.class -multithreading/educative/DemonstrationThreadLocal.class -practiceproblems/stack/WaterTrapping.class -practiceproblems/prefixsum/SubArrayDivisibleByP.class -linkedLists/ListNode.class -trees/BinaryTreeCamera.class -multithreading/educative/ReadWriteLock1.class -practiceproblems/parentheses/ScoreOfParentheses.class -practiceproblems/NutsAndBoltsMatch.class -practiceproblems/AdvantageShuffle.class -practiceproblems/GraphSplitwiseSimplify$Graph.class -practiceproblems/PrisonAfterNDays.class -multithreading/practice/FooBar.class -practiceproblems/design/MinimumStack$Node.class -practiceproblems/PalindromePartition.class -linkedLists/NestedInteger.class -reflections/arrays/data/Actor.class -multithreading/educative/SynchronousExecutor.class -dynamicProgramming/lcs/BitonicSequence.class -graph/leetcode/RedundantConnection.class -graph/topologicalsort/TopologicalSortList$Graph.class -graph/leetcode/ConnectedComponentsInGraph.class -CombinationsAndPermutations/SplitUniqueSubstring.class -practiceproblems/MinimumStepsKnight$Cell.class -linkedLists/LinkedListRemoveDuplicate.class -trees/Tree.class -multithreading/educative/examples/ThreadExample$ExecuteMe.class -trees/LCA.class -multithreading/educative/examples/ThreadSpawn.class -dynamicProgramming/MonotoneIncreasingString.class -lld/auctionSystem/services/BuyerService.class -linkedLists/DetectAndRemoveLoop.class -graph/topologicalsort/Edge.class -practiceproblems/LongestSubArraySumUtmostK.class -multithreading/educative/superman/SupermanWithFlaws.class -linkedLists/MyStack.class -graph/leetcode/GraphValidTree$UnionFind.class -reflections/game/internal/BoardLocation.class -lld/elevator/TestElevator.class -linkedLists/ReversePairsNode.class -multithreading/practice/WebCrawler.class -practiceproblems/intervals/MeetingRoomsII$Interval.class -graph/leetcode/ClosedIsland.class -graph/leetcode/MakeIslandLarger.class -trees/PathSum.class -CombinationsAndPermutations/CombinationSum.class -reflections/topologicalsort/SqlQueryBuilder.class -microsoftassesment/NumsWithEqualDigitSum.class -dynamicProgramming/MaximumRectangle.class -practiceproblems/UrlEncode.class -internals/Entry.class -dynamicProgramming/NumberWithSameConsequtiveDifference.class -trees/DeleteBST.class -trees/MaxProductSplitBinaryTree.class -reflections/topologicalsort/annotations/Annotations$Operation.class -practiceproblems/PermutationInString.class -reflections/annotation/annotations/Annotations.class -binarysearch/SubArraySplitSum.class -practiceproblems/design/MaxFreqStack.class -practiceproblems/ValidSudoku.class -dynamicProgramming/LastStoneWeight.class -machinecoding/splitwise/Driver.class -practiceproblems/MaximumSubstringWithKDistinctChar.class -practiceproblems/MobileKeyPadCombinations.class -practiceproblems/design/EntryStack.class -practiceproblems/design/ShortestWordDistance.class -practiceproblems/LengthOfLongestSubstringKDistinct.class -multithreading/thread/BasicMultiThreading.class -practiceproblems/design/SubRectangleQueries.class -practiceproblems/ShortestPathBinaryMatrix.class -trees/GenerateAllPossibleBST.class -multithreading/thread/Tesst$ThreadA.class -multithreading/educative/superman/Superman.class -linkedLists/CloneRandomPointerLinkedList.class -graph/leetcode/ShortestPathToGetFood.class -multithreading/practice/H2O.class -lld/billsharing/repository/UserRepository.class -strings/stringProblems/ShortDistanceBetweenChars.class -practiceproblems/parentheses/MinSwapsToBalance.class -java8/Square.class -trees/Node.class -reflections/game/internal/Sign.class -graph/leetcode/FindJudge.class -internals/TwitterSnowflakeUUID.class -practiceproblems/HappyNumber.class -CombinationsAndPermutations/SubSets.class -graph/leetcode/CriticalConnectionInGraph.class -graph/Vertex.class -practiceproblems/stack/RemoveKDigits.class -multithreading/educative/BarberShopProblem.class -lld/billsharing/exceptions/ExpenseSettledException.class -reflections/annotation/annotations/Annotations$ExecutionSchedules.class -practiceproblems/design/AuthenticationManager.class -practiceproblems/intervals/RectangleComputeArea.class -practiceproblems/FindHeaters.class -linkedLists/StackOperationUsingLinkedList.class -practiceproblems/SumSubArrayZero$Pair.class -practiceproblems/design/DesignStackIncrement.class -lld/billsharing/model/User.class -linkedLists/SinglyLinkedListNode.class -reflections/topologicalsort/annotations/Annotations$DependsOn.class -lld/billsharing/model/Expense$ExpenseBuilder.class -multithreading/thread/Tesst$ThreadB.class -graph/disjoints/RankTransformMatrix$Position.class -practiceproblems/design/HitCounter.class -practiceproblems/intervals/MergeIntervals.class -reflections/retries/app/databases/CacheLoader.class -graph/primsAlgorithm/Graph.class -multithreading/thread/PrintOddEvenByTwoThreads.class -practiceproblems/parentheses/LongestValidParentheses.class -linkedLists/Agoda.class -graph/shortestPath/ShortestPath$Graph.class -multithreading/educative/examples/ThreadExecutorExample$MyTask.class -graph/leetcode/MinCostConnectCities$UnionFind.class -multithreading/com/safecabs/app/CabProvider.class -practiceproblems/parentheses/ValidParenthesesString.class -practiceproblems/design/SummaryRanges.class -practiceproblems/MaxDistinctElementAfterKRemoval.class -machinecoding/snakesandladder/Driver.class -practiceproblems/MinTimeRotOranges.class -practiceproblems/InOrderSuccessor.class -linkedLists/ArrayToBST.class -lld/vendingmachine/NoMoneyState.class -trees/RootToLeafPaths.class -practiceproblems/CloneGraph.class -trees/SortedArrayToBST.class -multithreading/educative/UnisexBathroom2.class -multithreading/practice/RealTimeCounter.class -internals/LinkedHashMap.class -practiceproblems/parentheses/ValidParentheses.class -reflections/game/internal/ComputerInputProvider.class -java8/Consumer.class -graph/topologicalsort/Vertex.class -practiceproblems/RangeSum.class -linkedLists/InsertionSortList.class -practiceproblems/IsomorphicString.class -trees/MaxWidthOfBinaryTree.class -lld/billsharing/model/Contribution.class -lld/auctionSystem/models/Publisher.class -java8/Employee.class -java8/DesignPatternJava8.class -practiceproblems/tries/LongestRepeatingSubstring.class -multithreading/practice/DiningPhilosophers.class -multithreading/educative/BlockingQueue.class -internals/SkipNode.class -linkedLists/DetectAndRemoveLoop$Node.class -linkedLists/StackImpl.class -lld/billsharing/BillSharingMain.class -graph/bellmanFord/BellmanFord.class -graph/disjoints/DisjointSetArrayImplementation.class -practiceproblems/design/DesignInMemoryFileSystem.class -lld/billsharing/model/Expense.class -dynamicProgramming/UniqueCoinChange.class -graph/bellmanFord/Edge.class -internals/HashMap$Entry.class -microsoftassesment/MinStepsToMakePileSameHeight.class -practiceproblems/design/MyCircularQueue.class -multithreading/educative/examples/FutureTaskExample$1.class -dynamicProgramming/EggDropping.class -lld/vendingmachine/SoldOutState.class -practiceproblems/design/MaxStack.class -graph/leetcode/NetworkConnection.class -multithreading/producerconsumer/Main$1.class -trees/DiameterTree.class -practiceproblems/PetrolGasStation.class -graph/leetcode/ArrayNesting.class -practiceproblems/design/AutoCompleteSystem.class -practiceproblems/LongestIncreasingPathInMatrix.class -binarysearch/SingleElementInSortedArray.class -microsoftassesment/LexicographicallySmallest.class -dynamicProgramming/fibonacci/DiceThrow.class -dynamicProgramming/oiknapsack/NumberOfUniqueWaysToMakeChange.class -practiceproblems/design/LeaderBoard.class -linkedLists/LinkedListToBST.class -linkedLists/Main.class -practiceproblems/LongestUniqueSubstring.class -practiceproblems/ConstructTreeFromInorderAndPostorder.class -multithreading/educative/examples/TimerVsPool$2.class -multithreading/educative/examples/ThreadSleepExample.class -trees/SortedArrayToBST$Node.class -internals/ThreadPool$PoolThreadRunnable.class -internals/ConcurrentHashMap$MyHashMap$MapEntry.class -practiceproblems/sweepline/ModifyArray.class -practiceproblems/FlipZeroesToFormConsecutiveMaximumOnes.class -linkedLists/MergeTwoLinkedLists.class -graph/cycle/Graph.class -strings/stringProblems/PermutationAndCombination.class -multithreading/com/safecabs/app/CabRequest.class -multithreading/producerconsumer/ProducerConsumer.class -lld/auctionSystem/models/Buyer.class -multithreading/educative/examples/ThreadInterruptedException$ExecuteMe.class -practiceproblems/CountBinaryStrings.class -reflections/game/internal/Cell.class -graph/leetcode/CanVisitAllRooms.class -multithreading/practice/Odd.class -practiceproblems/jumpGame/JumpGameV.class -graph/dijkstraAlgorithm/Vertex.class -practiceproblems/MedianOfRunningIntegers.class -dynamicProgramming/MaxSumForNonAdjacentElements.class -practiceproblems/SumOfSquares.class -lld/auctionSystem/repository/ProductRepository.class -strings/stringProblems/StringComparator.class -dynamicProgramming/stocks/StockBuySellKTransactions.class -graph/Edge.class -graph/depthFirstSearch/DepthFirstSearch.class -practiceproblems/SpiralMatrix.class -practiceproblems/VulgarDecimal.class -binarysearch/BinarySearchTemplate.class -multithreading/com/safecabs/client/ClientTest.class -sorting/InsertionSort.class -java8/CustomCollectors.class -practiceproblems/stack/SumOfMinSubArrays.class -multithreading/educative/Demonstration1.class -multithreading/educative/MultiThreadedMergeSort$1.class -practiceproblems/FindAllAnagram.class -practiceproblems/LargestPossibleNumber.class -multithreading/thread/RaceConditionExample.class -practiceproblems/tries/LongestRepeatingSubstring$TrieNode.class -practiceproblems/InorderSuccessorPredecessor.class -dynamicProgramming/lcs/NumberOfLIS.class -multithreading/educative/examples/CallableExample$1.class -multithreading/practice/Demonstration.class -reflections/dynamicProxy/external/impl/HttpClientImpl.class -trees/TreeTraversals$Pair.class -RandomProblemGenerator.class -lld/vendingmachine/VendingMachineState.class -practiceproblems/ConstructBSTFromPreorder$TreeNode.class -reflections/annotation/annotations/Annotations$ExecuteOnSchedule.class -multithreading/educative/examples/TimerVsPool$4.class -multithreading/practice/ZeroEvenOdd.class -dynamicProgramming/stocks/BuyAndSellWithTransactionFee.class -graph/leetcode/MaxDistanceFromWater.class -microsoftassesment/MinSwapsToGroupRedBalls.class -practiceproblems/Candy.class -practiceproblems/jumpGame/JumpsToReachEnd.class -practiceproblems/parentheses/RemoveInvalidParentheses.class -practiceproblems/InorderSuccessorPredecessor$TNode.class -practiceproblems/FirstNonRepeatedCharacter.class -practiceproblems/SumSubArrayZero.class -practiceproblems/TreasureIslandII.class -reflections/topologicalsort/databases/Database.class -strings/stringProblems/LongestCommonPrefix.class -graph/primsAlgorithm/PrimMST.class -multithreading/thread/Tesst.class -lld/auctionSystem/utils/Utils.class -microsoftassesment/Pair.class -lld/auctionSystem/enums/ObserverType.class -practiceproblems/MoveZeroes.class -lld/billsharing/repository/ExpenseRepository.class -practiceproblems/RandomLinkedList$Node.class -lld/vendingmachine/VendingMachine.class -multithreading/educative/examples/ThreadExample.class -practiceproblems/recursion/NQueens.class -practiceproblems/MinOperationToMakeArrayIncreasing.class -trees/DepthOfTree.class -binarysearch/SearchInsertPosition.class -multithreading/educative/examples/StockOrder$Order.class -multithreading/com/safecabs/Gender.class -reflections/game/internal/BoardDimensions.class -practiceproblems/InorderSuccessorPredecessor$Node.class -practiceproblems/SpiralMatrixII.class -machinecoding/snakesandladder/Snake.class -linkedLists/FlattenMultiLevelLinkedList$Node.class -internals/ConcurrentHashMap$MyHashMap.class -practiceproblems/design/LeaderBoard$Player.class -machinecoding/splitwise/User.class -lld/billsharing/model/ExpenseStatus.class -binarysearch/KthSmallestInMultiplicationTable.class -graph/leetcode/NewRoadsMST$UF.class -multithreading/educative/examples/DaemonThreadSpawn$1.class -multithreading/educative/examples/FutureTaskExample$1TrivialTask.class -lld/billsharing/service/UserService.class -machinecoding/splitwise/EqualSplit.class -trees/LowestCommonAncestor$Node.class -machinecoding/snakesandladder/DiceService.class -multithreading/thread/TaskEvenOdd.class -dynamicProgramming/OnesAndZeroes.class -graph/leetcode/SentenceSimilarityII.class -linkedLists/MergeKSortedLists.class -practiceproblems/design/Twitter$User.class -reflections/retries/app/databases/DatabaseConnection.class -practiceproblems/Flatten2DVector.class -multithreading/educative/UnisexBathroom.class -practiceproblems/RomanToInteger.class -practiceproblems/stack/Pattern132.class -binarysearch/SumMutatedArrayCloseTarget.class -practiceproblems/KthSmallestMatrix$Pair.class -multithreading/thread/TestForLocking.class -practiceproblems/RandomLinkedList.class -graph/primsAlgorithm/Vertex.class -lld/billsharing/model/UserShare.class -reflections/retries/annotations/InitializerClass.class -reflections/dynamicProxy/Main.class -multithreading/practice/PrintInOrder.class -trees/LargestBST.class -practiceproblems/CloneGraph$Node.class -sorting/QuickSort.class -practiceproblems/TwoCityScheduling.class -practiceproblems/CanPlaceFlower.class -graph/dijkstraAlgorithm/DijkstraAlgorithm.class -multithreading/practice/OddEvenSemaphore.class -practiceproblems/mergesort/ReversePairs.class -practiceproblems/UpdateMatrix.class -practiceproblems/SearchAMaze$MazeNode.class -reflections/retries/app/AutoSaver.class -practiceproblems/SetBitCount.class -practiceproblems/DoubledPairArray.class -reflections/methodDiscovery/Address.class -graph/leetcode/MinCostRepairEdges.class -dynamicProgramming/TargetSum.class -practiceproblems/SnakeAndLadder.class -binarysearch/KokoEatingBananas.class -multithreading/practice/ProducerConsumer$1Producer.class -multithreading/thread/TestForLocking$WaitTester.class -multithreading/educative/examples/CallableExample$2.class -practiceproblems/stack/DailyTemperature$Pair.class -binarysearch/FindMinimumInRotatedArray.class -practiceproblems/NumberOfBallons.class -multithreading/educative/examples/CallableExample.class -graph/leetcode/MinCostConnectAllPipes$UnionFind.class -trees/isValidPreOrderSerialisation.class -internals/MyBlockingQueue.class -graph/leetcode/FriendCircles.class -practiceproblems/ShuffleArray.class -strings/stringProblems/DistinctSubstring.class -graph/shortestPath/Graph$Vertex.class -practiceproblems/TreasureIsland.class -sorting/PractiseMergeSort.class -graph/leetcode/IslandBFS$Pair.class -multithreading/educative/examples/CallableExample$3.class -graph/disjoints/RankTransformMatrix$UnionFind.class -dynamicProgramming/lcs/WildCardMatching.class -practiceproblems/MinCostRopeConnect.class -linkedLists/Node.class -practiceproblems/UniqueElementsInArray.class -multithreading/educative/examples/ThreadExecutorExample.class -graph/leetcode/ConnectCitiesWithDiscount.class -multithreading/educative/DiningPhilosophers2.class -practiceproblems/intervals/MaxProfitJobScheduling$Interval.class -practiceproblems/WordSearch.class -multithreading/educative/examples/CallableExample$4.class -reflections/customMockito/OurMockito.class -lld/elevator/Elevator.class -practiceproblems/FirstNonRepeatingCharacterStream$Node.class -practiceproblems/MinStepsToConvertXtoY$GFG.class -multithreading/educative/examples/TimerVsPool$1.class -practiceproblems/design/DesignFileSystem.class -multithreading/com/safecabs/cab/Cab.class -lld/auctionSystem/services/strategies/SellerViewAuctionDetails.class -lld/auctionSystem/enums/AuctionState.class -practiceproblems/design/LFUCache$DoubleLinkedList.class -graph/leetcode/RedundantConnectionII$UnionFind.class -practiceproblems/MaxPointsInLine.class -practiceproblems/MatrixRowWithMax1.class -practiceproblems/UniquePathMaximum.class -practiceproblems/KthSmallestFromTwoSortedArrays.class -graph/leetcode/EmployeeImportance$Employee.class -practiceproblems/GrammarMistake.class -practiceproblems/IPOMaxProfit.class -multithreading/com/safecabs/passenger/RegisteredPassenger.class -dynamicProgramming/lcs/MaximumContiguousSubarraySum.class -lld/vendingmachine/SoldState.class -graph/shortestPath/Graph$Edge.class -practiceproblems/SlidingWindow.class -practiceproblems/design/LFUCache.class -multithreading/practice/Even.class -lld/auctionSystem/models/Product.class -practiceproblems/MaximumProductSubarray$MaxSubarray.class -graph/interview/UnionFind.class -multithreading/educative/Demonstration.class -practiceproblems/tries/WordDictionary$TrieNode.class -practiceproblems/design/StockPrice$Node.class -binarysearch/MaxSoldiers.class -practiceproblems/HouseRobber.class -dynamicProgramming/lcs/EditDistance.class -dynamicProgramming/TriangleSum.class -practiceproblems/UniquePath.class -multithreading/educative/examples/DaemonThreadSpawn.class -strings/stringProblems/PushDominoes.class -linkedLists/RemoveDuplicates.class -practiceproblems/PascalsTriangle.class -practiceproblems/mergesort/CountNumbersLessThanSelf.class -java8/FunctionalInterfaceExamples.class -strings/stringProblems/ShiftingLetters.class -graph/kruskalAlgorithm/Graph.class -lld/auctionSystem/services/AuctionService$1.class -graph/primsAlgorithm/PrimsMSTArray.class -graph/leetcode/IslandBFS.class -practiceproblems/design/DesignInMemoryFileSystem$Trie.class -reflections/retries/annotations/InitializerMethod.class -lld/billsharing/exceptions/ContributionExceededException.class -graph/leetcode/MinStepsToCutTrees$Node.class -linkedLists/PalindromeSinglyLinkedList$Node.class -practiceproblems/design/SnapShotUtil.class -multithreading/educative/examples/ThreadExample$MyTask.class -practiceproblems/parentheses/DifferentWaysToAddParenthesis.class -dynamicProgramming/palindrome/PalindromePartitioningII.class -graph/adjacencyMatrix/AdjacencyMatrix.class -graph/leetcode/EmployeeImportance.class -practiceproblems/MinimumIndexDistanceOfMaximumNumbers.class -dynamicProgramming/palindrome/PalindromePartitioning.class -multithreading/com/safecabs/passenger/Passenger.class -graph/bellmanFord/Graph.class -lld/elevator/ExternalRequest.class -practiceproblems/TopKFrequentElements.class -reflections/game/internal/BoardPrinter.class -graph/leetcode/AlienDictionary.class -reflections/game/internal/HumanPlayer.class -graph/disjoints/DisjointSetWithNode.class -internals/SJUArrayList.class -multithreading/thread/Counter.class -machinecoding/splitwise/PercentExpense.class -practiceproblems/design/TimeMap$Value.class -trees/SymmetricTree.class -multithreading/educative/TokenBucketFilter.class -linkedLists/FlattenNestedIterator.class -practiceproblems/intervals/RectangleOverlap.class -reflections/topologicalsort/annotations/Annotations$Input.class -binarysearch/Sqrt.class -practiceproblems/stack/SmallestLexicoSubSeq.class -lld/auctionSystem/enums/AuctionProductState.class -reflections/retries/annotations/RetryOperation.class -reflections/methodDiscovery/Product.class -practiceproblems/MinimumSwapSortArray$Pair.class -linkedLists/ReverseLinkedListBetweenMandN.class -graph/breadthFirstSearch/BreadthFirstSearch.class -practiceproblems/intervals/MaxProfitJobScheduling.class -graph/leetcode/CourseSchedule.class -practiceproblems/design/BrowserHistory$Node.class -trees/LargestBST$NodeValue.class -practiceproblems/EvaluateRPN.class -graph/primsAlgorithm/BinaryMinHeap.class -practiceproblems/MultiplyTwoNumbers.class -practiceproblems/design/ValidTicTacToeState.class -practiceproblems/MinIncrementToMakeArrayUnique.class -graph/topologicalsort/Graph.class -practiceproblems/ReorderLogs.class -graph/kruskalAlgorithm/Edge.class -machinecoding/snakesandladder/Player.class -multithreading/educative/examples/TimerVsPool$3.class -graph/leetcode/ShortestBridge.class -practiceproblems/NutsAndBoltsMatch$NBComparator.class -practiceproblems/MinAdjSwapsToMakePalindrome.class -graph/disjoints/DisjointSetWithNode$Node.class -dynamicProgramming/lcs/ShortestCommonSupersequence.class -reflections/game/internal/TicTacToeGame.class -multithreading/practice/OddEven.class -multithreading/producerconsumer/Main.class -microsoftassesment/AutocompleteSystem.class -practiceproblems/MedianOfKWindow$MedianQueue.class -reflections/methodDiscovery/ClothingProduct.class -practiceproblems/design/Twitter.class -practiceproblems/FirstNonRepeatingCharacterStream$DLList.class -practiceproblems/ArrangeInQueue.class -multithreading/thread/PrintOddEvenByTwoThreads$OddThread.class -graph/leetcode/FindAllSafeStates.class -practiceproblems/stack/SortStack.class -practiceproblems/RollingHashRabinKarp.class -strings/stringProblems/RearrangeCharactersInString.class -microsoftassesment/StringWithout3ConsequitiveLetter.class -java8/IProducer.class -dynamicProgramming/matrix/MinCostPath.class -trees/NodesAtDistanceK.class -practiceproblems/MajorityVoting.class -multithreading/practice/ProducerConsumer.class -practiceproblems/prefixsum/IntervalsBetweenIdenticalElements.class -lld/auctionSystem/repository/BuyerRepository.class -multithreading/practice/CountdownLatch.class -dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.class -practiceproblems/design/StockPrice.class -binarysearch/SearchElementInSortedAndRotatedArray.class -practiceproblems/design/DesignHashMap$ListNode.class -practiceproblems/ValidateIpAddresses.class -trees/TreeNode.class -practiceproblems/BasicCalculator.class -practiceproblems/GroupIsomorphicString.class -linkedLists/DLLToBBST.class -practiceproblems/FindSmallestInteger.class -practiceproblems/RaceCarMinSteps.class -java8/ArrayListIteratorPattern.class -lld/auctionSystem/services/SellerService.class -practiceproblems/design/DesignTicTacToe.class -graph/cycle/Vertex.class -trees/MaxPathSum.class -practiceproblems/BitonicSearch.class -internals/SkippableList.class -graph/dijkstraAlgorithm/BinaryHeap.class -practiceproblems/LongestSpanWithSameSumArray.class -dynamicProgramming/lcs/MinimumAsciiDelete.class -dynamicProgramming/OptimalStratergy.class -practiceproblems/KthCharacterInString.class -graph/floydwarshall/FloydWarshall.class -java8/IFactory.class -practiceproblems/design/SnakeGame$Node.class -practiceproblems/mergesort/CountOfRanges.class -dynamicProgramming/oiknapsack/EqualSubsetSumPartition.class -graph/leetcode/MinCostConnectPoints$DSU.class -multithreading/educative/examples/ThreadSleepExample$ExecuteMe.class -graph/topologicalsort/TopologicalSort.class -graph/leetcode/NetworkConnection$UnionFind.class -dynamicProgramming/oiknapsack/MinPartition.class -practiceproblems/WordBreak.class -practiceproblems/RandomPickWithWeight.class -practiceproblems/LargestSubArrayWithZeroesAndOnes.class -practiceproblems/FlattenLinkedList.class -graph/Graph.class -practiceproblems/ThreeSum.class -graph/leetcode/GraphBiPartitePossiblity.class -dynamicProgramming/stocks/BuyAndSellStockAnytime.class -practiceproblems/AircraftOptimization.class -lld/auctionSystem/models/AuctionProduct.class -lld/elevator/InternalRequest.class -multithreading/educative/examples/ThreadInterruptedException.class -practiceproblems/FirstNonRepeatingCharacterStream.class -multithreading/educative/UberSeatingProblem.class -binarysearch/FirstAndLastOccurence.class -linkedLists/LinkedListToBST$LNode.class -practiceproblems/FurthestBuildingJump.class -graph/leetcode/MinCostConnectPoints.class -graph/kruskalAlgorithm/DisjointSet.class -practiceproblems/NextPermutation.class -reflections/retries/annotations/ScanPackages.class -practiceproblems/ClosestNumbers.class -machinecoding/splitwise/ExactExpense.class -java8/BookSpliterator.class -multithreading/educative/MultiThreadedMergeSort$2.class -practiceproblems/intervals/MergeIntervalIntersection.class -practiceproblems/RestoreIpAddresses.class -strings/stringProblems/CustomSortString.class -lld/billsharing/exceptions/ExpenseDoesNotExistsException.class -sorting/MinHeapTest.class -graph/leetcode/FriendCircles$UnionFind.class -graph/leetcode/NetworkDelayTime.class -microsoftassesment/RemoveCharsMoreThanKOccurrence.class -trees/PruneBinaryTree.class -machinecoding/splitwise/ExpenseType.class -practiceproblems/SortedSquares.class -linkedLists/NextLargestList.class -microsoftassesment/LongestSubStringWithout3ContiguousLetter.class -trees/InsertBST.class -practiceproblems/FourSum.class -practiceproblems/LargestTimeFromDigits.class -practiceproblems/BinaryMatrix.class -graph/dijkstraAlgorithm/BinaryHeap$Node.class -machinecoding/snakesandladder/SnakeAndLadderBoard.class -dynamicProgramming/MinCoinChange.class -multithreading/educative/examples/StockOrder.class -practiceproblems/FrequencySort.class -practiceproblems/ReArrangeStringKDistanceApart.class -practiceproblems/DutchNationalFlag.class -reflections/configparser/configloader/ConfigLoaderLibrary.class -lld/auctionSystem/repository/AuctionRepository.class -dynamicProgramming/palindrome/LongestPalindromicSubsequence.class -practiceproblems/NumberOfSubMatrices.class -binarysearch/MagneticForceBetweenTwoBalls.class -dynamicProgramming/matrix/MaximumSquareDP.class -trees/SameTree.class -graph/dijkstraAlgorithm/Graph.class -java8/BurgerShop.class -java8/Book.class -practiceproblems/RemoveDuplicates.class -reflections/game/internal/InputProvider.class -internals/LinkedHashMap$Entry.class -trees/PathSumIII.class -multithreading/practice/Printer.class -dynamicProgramming/oiknapsack/MinimumSubsetSum.class -practiceproblems/TreasureIslandII$Point.class -practiceproblems/stack/MaxSubarrMinProduct.class -trees/TrimBst.class -lld/billsharing/service/NotificationService.class -lld/elevator/Direction.class -dynamicProgramming/matrix/MatrixMultiplicationCost.class -linkedLists/ReverseKBlockNode.class -trees/SwapRecoverBST.class -multithreading/com/safecabs/app/AssignCab.class -dynamicProgramming/lcs/LongestCommonSubsequence.class -practiceproblems/parentheses/GenerateParenthesis.class -practiceproblems/DivideSubArrayAverage.class -reflections/annotation/annotations/Annotations$ScanPackages.class -linkedLists/SplitLinkedList.class -practiceproblems/LongestRepeatCharReplace.class -lld/auctionSystem/models/Notification.class -multithreading/practice/ProducerConsumer$1Consumer.class -java8/FuncInter.class -strings/stringmatching/KMP.class -graph/cycle/CycleInDirectedGraph.class -graph/leetcode/CourseScheduleII.class -practiceproblems/MirrorBinaryTree$Node.class -practiceproblems/RotateMatrixInPlace.class -multithreading/educative/examples/ThreadSpawn$1.class -graph/leetcode/MinCostConnectCities.class -graph/disjoints/PredatorDisjointSet.class -practiceproblems/MirrorBinaryTree.class -binarysearch/MaxSoldiers$Pair.class -linkedLists/FlattenLinkedList$Node.class -graph/shortestPath/ShortestPath.class -multithreading/practice/WebCrawler$HtmlParser.class -microsoftassesment/MinDeletionToMakeUniqueCount.class -practiceproblems/GraphSplitwiseSimplify.class -practiceproblems/MinRefuelStops.class -reflections/game/Game.class -lld/elevator/ProcessJobWorker.class -machinecoding/splitwise/Split.class -practiceproblems/AlternateOddAndEvenNumbers.class -practiceproblems/CompareVersions.class -practiceproblems/WordBreakII.class -practiceproblems/design/DesignCompressedStringIterator.class -practiceproblems/KthClosestOrigin.class -lld/elevator/State.class -practiceproblems/CountAllPathsFrom2DMatrix.class -machinecoding/splitwise/ExpenseManager.class -reflections/retries/app/http/ServiceRegistry.class -practiceproblems/intervals/MeetingRoomsII.class -practiceproblems/design/AutoCompleteSystem$TrieNode.class -graph/leetcode/EquationEquality$UnionFind.class -dynamicProgramming/OutOfBounds.class -practiceproblems/MedianOfKWindow.class -reflections/arrays/data/Movie.class -practiceproblems/MakeAnArrayPalindrome.class -graph/breadthFirstSearch/Graph.class -practiceproblems/SubstringWindowTemplate.class -multithreading/com/safecabs/app/CustomCyclicBarrier.class -practiceproblems/MinimumStepsKnight.class -graph/leetcode/MatrixStoneRemoval.class -dynamicProgramming/lcs/MaximumSumIncreasingSubsequence.class -multithreading/educative/Barrier.class -internals/QuadTree$QuadNode.class -practiceproblems/FindMissingNumbers.class -practiceproblems/SerializeAndDeserialize.class -practiceproblems/MedianOfTwoSortedArrays.class -practiceproblems/stack/MaxHistogram.class -multithreading/practice/Foo.class -dynamicProgramming/lcs/LongestCommonSubstring.class -binarysearch/FindPeakElement.class -graph/leetcode/MinimumHeightTrees.class -dynamicProgramming/stocks/BuyAndSellStockAtMostTwice.class -multithreading/educative/companies/netflix/SynchronousExecutor.class -internals/SkipList.class -practiceproblems/RemoveBSTGivenOutsideRange.class -trees/IsValidBST.class -lld/vendingmachine/State.class -practiceproblems/design/LogSystem.class -practiceproblems/ProductExceptSelf.class -trees/BinaryTreesUpsideDown.class -practiceproblems/RaceCarMinSteps$StateNode.class -lld/auctionSystem/enums/PublisherEventType.class -practiceproblems/RemoveAdjacentDuplicates.class -reflections/arrays/Main.class -dynamicProgramming/palindrome/CountSubStrings.class -linkedLists/MergeSortLinkedList.class -lld/elevator/AddJobWorker.class -linkedLists/LinkedListToBST$TNode.class -dynamicProgramming/OptimalTreeSearch.class -practiceproblems/GraphSplitwiseSimplify$Graph$AdjNode.class -practiceproblems/MinimumDistanceBetweenTwoNumbers.class -practiceproblems/CompleteBinaryTreeInserter.class -trees/LowestCommonAncestor.class -binarysearch/KClosestElements.class -practiceproblems/ConvertXToY$Steps.class -practiceproblems/IsEditOneDistanceAway.class -lld/auctionSystem/models/User.class -practiceproblems/PartitionLabel.class -CombinationsAndPermutations/CombinationIterator.class -practiceproblems/design/TweetCounts.class -java8/Burger.class -lld/billsharing/service/ExpenseService.class -practiceproblems/FirstMissingPositive.class -practiceproblems/QueensAttackKing.class -practiceproblems/ContainerWithMostWater.class -sorting/KthLargestElement.class -strings/stringmatching/MaxProductString.class -dynamicProgramming/PerfectSquare.class -dynamicProgramming/unboundedknapsack/CuttingRod.class -machinecoding/snakesandladder/Ladder.class -graph/leetcode/CheapestFlightKStops.class -practiceproblems/PartitionArrayDisjoint.class -strings/stringProblems/MostCommonWord.class -multithreading/thread/ThreadRunnable.class -dynamicProgramming/matrix/MinimumFallingPathMatrix.class -sorting/QuickSelect.class -linkedLists/CloneRandomPointerLinkedList$Node.class -multithreading/educative/Demonstration1$1.class -linkedLists/PalindromeSinglyLinkedList.class -practiceproblems/SearchAnElementInMatrix.class -multithreading/com/safecabs/Constants.class -dynamicProgramming/StoneGame.class -reflections/game/internal/Board.class -multithreading/practice/EvenSemaphore.class -multithreading/practice/NonReentrantLock.class -multithreading/educative/superman/SupermanNaiveButCorrect.class -practiceproblems/MinimumBribes.class -multithreading/educative/Callback.class -reflections/topologicalsort/BestGamesFinder.class -dynamicProgramming/BoxStacking$Dimension.class -multithreading/thread/DeadLock$1.class -java8/EmployeeSpliterator.class -trees/CountGoodNodes.class -trees/AVLTree.class -multithreading/educative/companies/netflix/Executor.class -practiceproblems/RotateArray.class -multithreading/educative/DeferredCallbackExecutor$CallBack.class -practiceproblems/GroupAnagrams.class -practiceproblems/stack/StockSpanner.class -strings/stringProblems/FindLongestStringInArray.class -practiceproblems/ConvertXToY.class -practiceproblems/SimilarExpressions.class -practiceproblems/TwoSumClosestToZero.class -practiceproblems/sweepline/MaxSumRangeQuery.class -graph/leetcode/MinCostConnectAllPipes.class -graph/kruskalAlgorithm/DisjointSet$Node.class -dynamicProgramming/lcs/LongestIncreasingSubsequence.class -practiceproblems/CountAndSay.class -machinecoding/splitwise/PercentSplit.class -practiceproblems/design/OwnDataStructureUtil.class -multithreading/educative/examples/TimerVsPool.class -practiceproblems/design/LFUCache$DLLNode.class -practiceproblems/stack/DailyTemperature.class -practiceproblems/Pow.class -practiceproblems/TaskLeastInterval.class -practiceproblems/parentheses/BalancedSmiley.class -reflections/annotation/annotations/Annotations$ScheduledExecutorClass.class -practiceproblems/prefixsum/SubArraySumDivisibleByK.class -reflections/topologicalsort/annotations/Annotations.class -practiceproblems/parentheses/CanBeValid.class -practiceproblems/SurroundedRegions.class -graph/leetcode/PacificAtlantic.class -practiceproblems/FlattenLinkedList$Node.class -graph/primsAlgorithm/Edge.class -dynamicProgramming/stocks/StockBuySellWithCoolDown.class -practiceproblems/design/LRUCache1.class -linkedLists/AllProblems.class -multithreading/practice/SumUpExample.class -binarysearch/FindSmallestDivisor.class -practiceproblems/stack/NextGreaterElement.class -reflections/dynamicProxy/Main$TimeMeasuringProxyHandler.class -graph/adjacencyList/AdjacencyList.class -practiceproblems/prefixsum/SubArraySumEqualsK.class -practiceproblems/tries/MapSum.class -strings/stringProblems/SlowestKey.class -multithreading/thread/ThreadJoinExample.class -internals/HashMap.class -lld/elevator/Request.class -multithreading/thread/Printer.class -linkedLists/RotateList.class -practiceproblems/PairDivisibleBy60.class -sorting/MaxHeap.class -sorting/MergeSort.class -machinecoding/snakesandladder/SnakeAndLadderService.class -reflections/methodDiscovery/Size.class -reflections/game/internal/Player.class -practiceproblems/MaximumDifference.class -practiceproblems/SerializeDeserializeBST.class -reflections/customMockito/OurMockTest.class -practiceproblems/design/BrowserHistory.class -multithreading/thread/Bank.class -graph/leetcode/MinCostConnectPoints$Edge.class -practiceproblems/WordLadder.class -practiceproblems/MaximumProductSubarray.class -graph/leetcode/MinStepsToCutTrees.class -practiceproblems/ValidPalindromeII.class -multithreading/educative/examples/ThreadExecutorExample$DumbExecutor.class -multithreading/educative/DiningPhilosophers.class -graph/leetcode/ConnectCities.class -practiceproblems/jumpGame/MinTapsToFillGarden.class -lld/auctionSystem/models/Observer.class -linkedLists/DLLToBBSTTimeEfficiency.class -graph/leetcode/RedundantConnectionII.class -practiceproblems/MaximumGap.class -linkedLists/FlattenMultiLevelLinkedList.class -lld/auctionSystem/models/Seller.class -multithreading/practice/PositionUpdater.class -practiceproblems/ReorganiseString.class -practiceproblems/CountElements.class -practiceproblems/design/FreqStack.class -practiceproblems/intervals/InsertIntervals.class -reflections/annotation/Main.class -multithreading/thread/DeadLock$2.class -linkedLists/ReverseLinkedList.class -dynamicProgramming/lcs/DeleteAndEarn.class -trees/CountGoodNodes$Pair.class -practiceproblems/LargestDivisibleSubset.class -graph/leetcode/MaxProbabilityPath.class -multithreading/educative/CountingSemaphore.class -graph/leetcode/AccountsMerge.class -dynamicProgramming/lcs/NumberOfDistinctSubSequence.class -multithreading/educative/examples/FutureTaskExample.class -reflections/configparser/data/GameConfig.class -multithreading/educative/companies/netflix/Callback.class -multithreading/thread/PrintEvenOddTester.class -multithreading/educative/Executor.class -graph/disjoints/RankTransformMatrix.class -graph/interview/DisjointSet.class -multithreading/practice/PrinterSemaphore.class -dynamicProgramming/TwoKeysKeyBoard.class -practiceproblems/MinimumSwapSortArray.class -dynamicProgramming/oiknapsack/SubsetSumProblem.class -practiceproblems/FindAllPossibleRecipes.class -practiceproblems/StringJustify.class -reflections/game/internal/KeyboardInputProvider.class -lld/billsharing/model/ExpenseGroup.class -internals/ConcurrentHashMap.class -practiceproblems/MinimumSubArrayLength.class -practiceproblems/design/DesignHashMap.class -dynamicProgramming/MakeArrayStrictlyIncreasing.class -practiceproblems/FlipMaximizeZeroesSubarrayKadane.class -graph/kruskalAlgorithm/Vertex.class -graph/topologicalsort/TopologicalSortList.class -dynamicProgramming/MinSwapsToMakeArrayIncreasing.class -lld/auctionSystem/services/strategies/AuctionDetails.class -practiceproblems/WordSearchII$TrieNode.class -graph/dijkstraAlgorithm/Edge.class -trees/TreeTraversals.class -multithreading/educative/companies/netflix/SynchronousExecutor$1.class -practiceproblems/KmostFrequentLetters.class -practiceproblems/IntersectionOfArrays.class -practiceproblems/design/MinimumStack.class -reflections/configparser/data/UserInterfaceConfig.class -microsoftassesment/CropWords.class -practiceproblems/design/GetRandomWithDuplicates.class -practiceproblems/design/Twitter$Tweet.class -dynamicProgramming/KnightDialer.class -practiceproblems/design/LRUCache$DLLNode.class -practiceproblems/design/UndergroundSystem$Route.class -dynamicProgramming/CatalanNumberBinarySearchTree.class -practiceproblems/FenwickTree.class -practiceproblems/MinStepsToConvertXtoY.class -graph/leetcode/ConnectCities$UnionSet.class -practiceproblems/Trie$TrieNode.class -graph/interview/DisjointSetLeetcode.class -CombinationsAndPermutations/Permutations.class -practiceproblems/design/UndergroundSystem.class -dynamicProgramming/oiknapsack/O1KnapsackSpaceOptimized.class -java8/CustomSpliterator.class -practiceproblems/TaskLeastInterval$Pair.class -practiceproblems/WordSearchII.class -graph/leetcode/GraphValidTree.class -practiceproblems/intervals/OverlappingIntervals.class -practiceproblems/CelebrityProblem.class -multithreading/educative/MultiThreadedMergeSort.class -practiceproblems/mergesort/CountingInversion.class -practiceproblems/SearchAMaze.class -machinecoding/splitwise/EqualExpense.class -practiceproblems/design/SummaryRanges$Interval.class -lld/vendingmachine/Main.class -graph/depthFirstSearch/Graph.class -machinecoding/splitwise/ExpenseMetadata.class -practiceproblems/MaximumUnsortedSubarray.class -dynamicProgramming/lcs/MaximumLengthRepeatedSubarray.class -graph/leetcode/TimeToInformEmployee.class -multithreading/educative/companies/netflix/Run.class -dynamicProgramming/MinCostTickets.class -practiceproblems/design/LRUCache.class -graph/leetcode/AccountsMerge$UnionFind.class -practiceproblems/Fenwick2D.class -practiceproblems/AngleOfClock.class -practiceproblems/SetZeroesMatrix.class -graph/ArticulationPoint.class diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst deleted file mode 100644 index 3edcf50..0000000 --- a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +++ /dev/null @@ -1,763 +0,0 @@ -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/Sign.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/LinkedHashMap.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SumSubArrayZero.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MinCostConnectCities.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/MinHeapTest.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/SplitLinkedList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MaximumSubstringWithKDistinctChar.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MultiplyTwoNumbers.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CountBinaryStrings.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/services/SellerService.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/disjoints/RankTransformMatrix.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/DeleteAndEarn.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/PermutationAndCombination.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RangeSum.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/services/strategies/AuctionDetails.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/DesignHashMap.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/BalancedSmiley.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CountAndSay.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/stocks/BuyAndSellStockAnytime.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/ConnectCitiesWithDiscount.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/BillSharingMain.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/BasicCalculator.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/methodDiscovery/Product.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/DetectAndRemoveLoop.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/PrintEvenOddTester.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/PractiseMergeSort.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinimumIndexDistanceOfMaximumNumbers.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/Top20LinkedListQuestions.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MaxDistanceFromWater.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/IslandBFS.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/matrix/MinCostPath.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SurroundedRegions.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/Pattern132.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/configparser/data/UserInterfaceConfig.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/app/databases/CacheLoader.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/SmallestLexicoSubSeq.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/DeferredCallbackExecutor.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/adjacencyMatrix/AdjacencyMatrix.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/WildCardMatching.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LongestIncreasingPathInMatrix.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/TwoSumClosestToZero.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RollingHashRabinKarp.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/bellmanFord/Vertex.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ProductExceptSelf.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/customMockito/OurMockTest.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinimumBribes.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/MergeSortLinkedList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/BitonicSearch.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/PercentSplit.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/snakesandladder/SnakeAndLadderBoard.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FrequencySort.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/DivideSubArrayAverage.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/SymmetricTree.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/DiningPhilosophers2.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/primsAlgorithm/PrimMST.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/jumpGame/JumpsToReachEnd.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/enums/AuctionProductState.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/repository/UserRepository.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/RemoveDuplicates.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/NextPermutation.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/BalloonBurst.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/CriticalConnectionInGraph.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/HitCounter.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SortANearlySortedArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/Board.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/DesignTicTacToe.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/TestForLocking.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/MinimumStack.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MobileKeyPadCombinations.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinStepsToConvertXtoY.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/ThreadInterruptedException.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/StockPrice.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MaxPointsInLine.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/AircraftMovieDuration.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MinPathHavingMaxDifference.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/fibonacci/DiceThrow.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/model/UserShare.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/superman/SupermanSlightlyBetter.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/AutocompleteSystem.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/vendingmachine/State.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/CountdownLatch.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/PushDominoes.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/LinkedListToBST.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LeftMostColumnWithOne.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/GrammarMistake.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/PathSumIII.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/LargestBST.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/MaxSubarrMinProduct.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/MinCoinChange.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/SubRectangleQueries.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/java8/DesignPatternJava8.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/dijkstraAlgorithm/DijkstraAlgorithm.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/oiknapsack/MinimumSubsetSum.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/DesignCompressedStringIterator.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/RemoveCharsMoreThanKOccurrence.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ShuffleArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SimilarExpressions.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ContainerWithMostWater.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/mergesort/ReversePairs.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/topologicalsort/Main.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/BinarySearchTemplate.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/cycle/CycleUndirectedGraph.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/MaximumLengthRepeatedSubarray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MatrixRowWithMax1.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/ThreadSpawn.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/AsyncToSyncConverter.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/Driver.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringmatching/KMP.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MaximumProductSubarray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/AssemblyLineScheduling.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/palindrome/PalindromePartitioningII.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/AllPathsInGraph.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/ReconstructItenary.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/GenerateAllPossibleBST.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/KmostFrequentLetters.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/elevator/TestElevator.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/DiningPhilosophers.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/User.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/NumberWithSameConsequtiveDifference.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/WordSearchII.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/StoneGame.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PalindromePartition.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/adjacencyList/AdjacencyList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/MaxProductSplitBinaryTree.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/FlattenLinkedList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/InorderSuccessorPredecessor.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RomanToInteger.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/kruskalAlgorithm/DisjointSet.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/mergesort/CountingInversion.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/primsAlgorithm/BinaryMinHeap.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/prefixsum/SubArrayDivisibleByP.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MajorityVoting.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/InsertBST.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/topologicalsort/TopologicalSort.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/UpdateMatrix.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/prefixsum/SubArraySumEqualsK.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/ShortestWordDistance.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/topologicalsort/annotations/Annotations.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/app/CabRequest.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RemoveBSTGivenOutsideRange.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/vendingmachine/NoMoneyState.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/arrays/data/Actor.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/AlienDictionary.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/tries/LongestRepeatingSubstring.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RandomPickWithWeight.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/MaximumContiguousSubarraySum.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MedianOfKWindow.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MaxProbabilityPath.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/NetworkDelayTime.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/LastStoneWeight.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RotateArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/MergeIntervals.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinimumDistanceBetweenTwoNumbers.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CountAllPathsFrom2DMatrix.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/CustomSortString.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MinCostConnectAllPipes.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/MiddleElement.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/model/User.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/companies/netflix/Run.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/SubArraySplitSum.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/depthFirstSearch/Graph.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/model/ExpenseStatus.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/QuickSelect.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RemoveAdjacentDuplicates.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/LexicographicallySmallest.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinimumWindowSubstring.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/mergesort/CountOfRanges.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/TrailingZeroes.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/oiknapsack/NumberOfUniqueWaysToMakeChange.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/TreeTraversals.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/Observer.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/UnisexBathroom2.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SubstringWindowTemplate.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/NextGreaterNumber.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/BoatsToSave.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/java8/FunctionalInterfaceExamples.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/SlowestKey.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/BrowserHistory.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/LeaderBoard.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/TaskLeastInterval.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/TimeToInformEmployee.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/KnightDialer.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/vendingmachine/SoldState.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/client/ClientTest.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/TweetCounts.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FirstNonRepeatedCharacter.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/TimerVsPool.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/MinSwapsToGroupRedBalls.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/IsEditOneDistanceAway.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/StackImpl.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/services/ObserverService.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/superman/Superman.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/EmployeeImportance.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/ReverseKBlockNode.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/services/strategies/BuyerViewAuctionDetails.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/FizzBuzz.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/InputProvider.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/IsomorphicString.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/ThreadExample.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/QuickSort.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/DLLToBBST.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ReArrangeStringKDistanceApart.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/Seller.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PascalsTriangle.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/ShipPackageWithNDays.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ReorganiseString.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SumOfSquares.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/repository/SellerRepository.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/ExpenseService.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SlidingWindow.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/MaximumSumIncreasingSubsequence.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/ArrayNesting.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/FirstBadVersion.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/Node.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/GroupAnagrams.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinTimeRotOranges.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/disjoints/DisjointSetWithNode.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/SortedArrayToBST.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/dijkstraAlgorithm/Graph.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/ArrayToBST.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MirrorBinaryTree.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/MaxHistogram.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/methodDiscovery/Address.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinOperationToMakeArrayIncreasing.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/topologicalsort/TopologicalSortList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FenwickTree.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/java8/CustomCollectors.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/CourseScheduleII.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ShortestPathBinaryMatrix.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MakeAnArrayPalindrome.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/repository/ProductRepository.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FurthestBuildingJump.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/InsertIntervals.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/CountGoodNodes.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/TreasureIslandII.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/annotations/InitializerMethod.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/depthFirstSearch/DepthFirstSearch.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ValidPalindromeII.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MinimumHeightTrees.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/LongestCommonSubsequence.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/TwoCityScheduling.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CloneGraph.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FlipZeroesToFormConsecutiveMaximumOnes.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/AuctionProduct.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/AllProblems.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/superman/SupermanWithFlaws.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/DeleteBST.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/producerconsumer/ProducerConsumer.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/producerconsumer/Main.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/Twitter.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/Tesst.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/StackOperationUsingLinkedList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/Product.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/CombinationsAndPermutations/CombinationSum.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/Cell.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/GraphBiPartite.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/SingleElementInSortedArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/snakesandladder/Ladder.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/CanVisitAllRooms.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/EggDropping.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/Pow.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/sweepline/ModifyArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/MergeTwoLinkedList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/UberSeatingProblem.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/TreasureIsland.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/customMockito/OurMockito.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/prefixsum/IntervalsBetweenIdenticalElements.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CountElements.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/WaterTrapping.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/exceptions/InvalidExpenseState.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/IntersectionOfArrays.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/vendingmachine/SoldOutState.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FindAllAnagram.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MedianOfTwoSortedArrays.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/DeadLock.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/RearrangeCharactersInString.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/methodDiscovery/Size.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PartitionArrayDisjoint.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/Main.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/UndergroundSystem.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/NonDecreasingArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SetBitCount.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/ConnectedComponentsInGraph.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/TokenBucketFilter.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/ThreadJoinExample.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/services/strategies/SellerViewAuctionDetails.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/H2O.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/app/http/ServiceRegistry.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/topologicalsort/Graph.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/Flatten2DVector.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ValidSudoku.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinIncrementToMakeArrayUnique.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/NextGreaterElement.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/NodesAtDistanceK.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/GenerateParenthesis.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/Gender.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/NumsWithEqualDigitSum.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/MergeIntervalIntersection.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MedianOfRunningIntegers.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/DiningPhilosophers.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/stocks/StockBuySellKTransactions.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/FindSmallestDivisor.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/ShortestCommonSupersequence.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LongestUniqueSubstring.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/MaxSumForNonAdjacentElements.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/Agoda.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PlusOne.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/arrays/data/Movie.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/ExactSplit.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FindAllPossibleRecipes.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/MinSwapsToMakeArrayIncreasing.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinimumSwapSortArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/DepthOfTree.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/service/NotificationServiceImpl.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/annotation/annotations/Annotations.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/ExpenseMetadata.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ConstructBSTFromPreorder.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/prefixsum/SubArraySumDivisibleByK.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/RootToLeafPaths.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/bellmanFord/Graph.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/FriendCircles.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/ComputerPlayer.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/KthSmallestFromTwoSortedArrays.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/stocks/BuyAndSellStockAtMostTwice.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/GraphSplitwiseSimplify.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/StockOrder.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/MaxHeap.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/companies/netflix/Executor.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/app/AssignCab.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FindHeaters.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/ValidParentheses.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/init/Main.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/HashMapJava8.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/matrix/MatrixMultiplicationCost.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/RectangleComputeArea.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/recursion/SudokuSolver.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/DemonstrationThreadLocal.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/BlockingQueue.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/FlattenNestedIterator.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/PrintOddEvenByTwoThreads.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/BitonicSequence.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/TrimBst.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/LongestSubStringWithout3ContiguousLetter.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MaxDistinctElementAfterKRemoval.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/FirstAndLastOccurence.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/LongestIncreasingSubsequence.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/BasicCalculatorII.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/bellmanFord/NegativeException.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/oiknapsack/O1KnapsackSpaceOptimized.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/primsAlgorithm/Graph.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/palindrome/PalindromePartitioning.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/BinaryTreeCousins.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/TreeNode.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/ArticulationPoint.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SpiralMatrixII.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/model/ExpenseGroup.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/EqualExpense.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/Publisher.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RestoreIpAddresses.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/ShortestPathToGetFood.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/CropWords.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/MinCostTickets.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/arrays/Main.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/SameTree.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/EvaluateRPN.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/recursion/NQueens.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/enums/Channel.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/CombinationsAndPermutations/Permutations.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/Notification.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/MyCircularQueue.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/SortStack.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FindSmallestInteger.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SnakeAndLadder.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/OverlappingIntervals.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/NumberOfBallons.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/MultiThreadedMergeSort.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/repository/ExpenseRepository.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/EditDistance.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/ProducerConsumer.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ReverseString.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinCostRopeConnect.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RangeSum2D.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/enums/ObserverType.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/AuthenticationManager.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/DiameterTree.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/ExpenseType.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LargestDivisibleSubset.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/palindrome/LongestPalindromicSubsequence.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/ThreadRunnable.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/MaxStack.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/FindPeakElement.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/PathSum.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/primsAlgorithm/PrimsMSTArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/OutOfBounds.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/GetRandomWithDuplicates.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/BackspaceCompare.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FirstMissingPositive.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/KthSmallestInMultiplicationTable.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/SkipList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/DesignFileSystem.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/ValidParenthesesString.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/dynamicProxy/external/impl/DatabaseReader.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/DLLToBBSTTimeEfficiency.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/java8/CustomSpliterator.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/annotation/Main.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/BoxStacking.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/ValidTicTacToeState.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/AVLTree.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/OwnDataStructureUtil.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/app/CabProvider.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/SnapShotUtil.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/shortestPath/Graph.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/CloneRandomPointerLinkedList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/TwoKeysKeyBoard.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/NextLargestList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FlipMaximizeZeroesSubarrayKadane.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/ConcurrentHashMap.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/Buyer.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/CombinationsAndPermutations/SplitUniqueSubstring.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/PalindromeSinglyLinkedList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/SJUArrayList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/CheapestFlightKStops.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PermutationInString.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinimumSubArrayLength.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/IPOMaxProfit.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/Bank.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/BinaryTreeCamera.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/superman/SupermanNaiveButCorrect.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/CombinationsAndPermutations/CombinationIterator.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/StringJustify.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/annotations/RetryOperation.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/Combination.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/StockSpanner.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RandomLinkedList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/RemoveInvalidParentheses.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CanPlaceFlower.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/BuildArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/RussianDollEnvelope.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/dynamicProxy/external/impl/HttpClientImpl.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/SumOfMinSubArrays.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/MaxWidthOfBinaryTree.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/BasicMultiThreading.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinimumWindowSubsequence.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FirstNonRepeatingCharacterStream.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/FindTheCity.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SetZeroesMatrix.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/Addition.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/ComputerInputProvider.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/enums/AuctionState.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/app/CustomCyclicBarrier.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/MinStepsToMakePileSameHeight.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/WordLadder.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/TicTacToeGame.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/LogSystem.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/EqualSplit.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MaximumGap.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/IsSubsequence.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/cycle/CycleInDirectedGraph.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/Constants.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/NumberOfLIS.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RotateMatrixInPlace.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/MeetingRoomsII.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PairDivisibleBy60.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/User.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MinCostRepairEdges.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PetrolGasStation.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ComplexNumberMultiply.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LargestTimeFromDigits.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LongestSpanWithSameSumArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MinStepsToCutTrees.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/customMockito/ExternalService.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/ReverseLinkedList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/MaxFreqStack.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/breadthFirstSearch/Graph.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/PruneBinaryTree.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/ThreadExecutorExample.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/thread/RaceConditionExample.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/TreeToDLL.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/ReversePairsNode.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/TwoStringInterleavingToFormThird.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/stocks/BuyAndSellWithTransactionFee.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SpiralMatrix.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ConstructTreeFromInorderAndPreorder.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/palindrome/LongestPalindromicSubstring.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/LongestValidParentheses.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/fibonacci/FibonacciStaircaseWaysToCoverDist.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/oiknapsack/SubsetSumProblem.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinimumStepsKnight.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CompleteBinaryTreeInserter.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/UniqueCoinChange.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/MyBlockingQueue.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/BinaryTreesUpsideDown.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/EquationEquality.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/LongestStringChain.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/snakesandladder/Driver.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/MergeTwoLinkedLists.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CountMinimumStepsToFormDesiredInputArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ValidateIpAddresses.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/bellmanFord/Edge.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/Split.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/TimeMap.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/dynamicProxy/Main.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/GraphValidTree.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/SearchInsertPosition.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/annotation/loaders/Cache.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/service/UserService.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/TriangleSum.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MoveZeroes.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/AlternateOddAndEvenNumbers.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/FutureTaskExample.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/DaemonThreadSpawn.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/Expense.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/annotations/ScanPackages.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/LCA.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/UrlEncode.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MatrixStoneRemoval.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/SentenceSimilarityII.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/VulgarDecimal.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/MaximumRectangle.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/Node.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/ExpenseManager.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/service/NotificationService.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/SnakeGame.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/UniquePathMaximum.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/NetworkConnection.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/UniquePath.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/MergeKSortedLists.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SearchAMaze.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/OptimalTreeSearch.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/KClosestElements.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/Main.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/MonotoneIncreasingString.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/sweepline/MaxSumRangeQuery.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/dynamicProxy/external/impl/DatabaseReaderImpl.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/Sqrt.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/WordBreak.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/Player.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/UnisexBathroom.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/configparser/configloader/ConfigLoaderLibrary.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/Fenwick2D.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/FindJudge.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/app/databases/DatabaseConnection.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/ReverseLinkedListBetweenMandN.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/methodDiscovery/ProductTest.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/configparser/data/GameConfig.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/breadthFirstSearch/BreadthFirstSearch.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ClosestNumbers.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/FindMinimumInRotatedArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/MinHeap.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/OptimalStratergy.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/WordBreakII.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/InOrderSuccessor.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/FlattenMultiLevelLinkedList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/DesignInMemoryFileSystem.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/RotateList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/annotations/InitializerClass.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/kruskalAlgorithm/Graph.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/RedundantConnection.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/matrix/MaximumSquareDP.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/repository/AuctionRepository.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/snakesandladder/DiceService.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FindPairs.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/DutchNationalFlag.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/MinSwapsToBalance.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/TopKFrequentElements.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/snakesandladder/SnakeAndLadderService.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/services/PublisherService.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FlattenLinkedList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/DifferentWaysToAddParenthesis.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/HouseRobber.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/QueensAttackKing.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/ShortDistanceBetweenChars.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/MaxPathSum.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/RandomProblemGenerator.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/MinimumAsciiDelete.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MaxSumTwoNonOverlappingSubArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/utils/Utils.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/topologicalsort/databases/Database.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/OddEven.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MinCostConnectPoints.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/exceptions/ExpenseSettledException.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/BarberShopProblem.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/Foo.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/exceptions/ExpenseDoesNotExistsException.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/DistinctSubstring.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/Barrier.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/QuadTree.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/FindLongestStringInArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/RandomListNode.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SerializeAndDeserialize.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/AdvantageShuffle.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/RemoveKDigits.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/BoardDimensions.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/ExactExpense.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/IntegerToBinary.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/MakeIslandLarger.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/AutoCompleteSystem.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ArrangeInQueue.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/oiknapsack/EqualSubsetSumPartition.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/NumberOfDistinctSubSequence.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/NumberOfSubMatrices.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/exceptions/UnRegisteredPassengerException.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/NewRoadsMST.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/model/Contribution.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/MaxSoldiers.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/InsertionSortList.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/snakesandladder/Player.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LongestSubArraySumUtmostK.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/topologicalsort/SqlQueryBuilder.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/floydwarshall/FloydWarshall.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/companies/netflix/Callback.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ReorderLogs.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/KthSmallestMatrix.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PartitionLabel.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/services/BuyerService.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/CourseSchedule.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/DailyTemperature.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/KokoEatingBananas.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/fibonacci/DecodeWays.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/snakesandladder/Snake.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/RedundantConnectionII.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/oiknapsack/MinPartition.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/jumpGame/JumpGameV.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/Tree.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/IsValidBST.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/app/configs/ConfigsLoader.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/DecodeString.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/ThreadSleepExample.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/KthLargestElement.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/UniqueElementsInArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/MinDeletionToMakeUniqueCount.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/PerfectSquare.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/jumpGame/VideoStitching.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/MagneticForceBetweenTwoBalls.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/ThreadPool.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/DungeonGame.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/stocks/StockBuySellWithCoolDown.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MaximumDifference.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/HumanPlayer.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CheckPalindromePermutation.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/stack/AsteroidCollision.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/ShiftingLetters.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/ZeroEvenOdd.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/kruskalAlgorithm/KruskalMST.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/NutsAndBoltsMatch.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/TwitterSnowflakeUUID.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/MostCommonWord.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/palindrome/CountSubStrings.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/LRUCache.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/BoardLocation.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/TwoSumTree.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/SinglyLinkedListNode.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/vendingmachine/VendingMachineState.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/InsertionSort.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/KthCharacterInString.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/KthClosestOrigin.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/services/AuctionService.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/methodDiscovery/ClothingProduct.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LongestRepeatCharReplace.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/isValidPreOrderSerialisation.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/Game.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/lcs/LongestCommonSubstring.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/FooBar.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinRefuelStops.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/mergesort/CountNumbersLessThanSelf.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/jumpGame/MinTapsToFillGarden.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MinAdjSwapsToMakePalindrome.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/GroupIsomorphicString.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/retries/app/AutoSaver.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/GraphBiPartitePossiblity.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/model/Expense.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/SwapRecoverBST.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/CountingSemaphore.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/BoardPrinter.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/ReadWriteLock.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/internals/HashMap.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/machinecoding/splitwise/PercentExpense.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/NumberOfDaysToMakeMBouquets.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LargestSubArrayWithZeroesAndOnes.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RemoveDuplicates.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/AngleOfClock.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringProblems/LongestCommonPrefix.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/SumMutatedArrayCloseTarget.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/ScoreOfParentheses.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/WordSearch.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/RealTimeCounter.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/cab/Cab.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/FindAllSafeStates.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/companies/netflix/SynchronousExecutor.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/disjoints/PredatorDisjointSet.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/bellmanFord/BellmanFord.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/matrix/MinimumFallingPathMatrix.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/NonReentrantLock.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/LFUCache.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/dynamicProxy/external/impl/HttpClient.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ThreeSum.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FourSum.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/tries/WordDictionary.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/sorting/MergeSort.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/strings/stringmatching/MaxProductString.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/PrisonAfterNDays.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/interview/DisjointSet.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CelebrityProblem.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/SummaryRanges.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/GameOfLife.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SearchAnElementInMatrix.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/RaceCarMinSteps.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ConvertXToY.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/Auction.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/AccountsMerge.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/tries/MapSum.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/trees/LowestCommonAncestor.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/CombinationsAndPermutations/SubSets.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/disjoints/DisjointSetArrayImplementation.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/OddEvenSemaphore.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/MakeArrayStrictlyIncreasing.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SerializeDeserializeBST.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/educative/examples/CallableExample.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/MaximumUnsortedSubarray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/ShortestBridge.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/exceptions/ContributionExceededException.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/unboundedknapsack/CuttingRod.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/parentheses/CanBeValid.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LargestPossibleNumber.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LengthOfLongestSubstringKDistinct.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/repository/BuyerRepository.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/cycle/Graph.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/models/Event.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/dijkstraAlgorithm/BinaryHeap.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/CompareVersions.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/passenger/RegisteredPassenger.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/LongestConsequtiveSequence.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/com/safecabs/passenger/Passenger.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/ConnectCities.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/TargetSum.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/linkedLists/LinkedListRemoveDuplicates.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/RectangleOverlap.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/ConstructTreeFromInorderAndPostorder.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/DoubledPairArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/game/internal/KeyboardInputProvider.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/Trie.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/multithreading/practice/WebCrawler.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/BooleanParenthesization.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/shortestPath/ShortestPath.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/Candy.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/design/DesignStackIncrement.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/intervals/MaxProfitJobScheduling.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/SortedSquares.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/AircraftOptimization.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/binarysearch/SearchElementInSortedAndRotatedArray.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/PacificAtlantic.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/graph/leetcode/ClosedIsland.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/reflections/topologicalsort/BestGamesFinder.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/billsharing/service/ExpenseService.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/vendingmachine/VendingMachine.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/auctionSystem/enums/PublisherEventType.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/OnesAndZeroes.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/vendingmachine/Main.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/microsoftassesment/StringWithout3ConsequitiveLetter.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/dynamicProgramming/CatalanNumberBinarySearchTree.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/FindMissingNumbers.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/lld/vendingmachine/HasMoneyState.java -/Users/vignesh_rajarajan/Documents/learning/Problems/src/main/java/practiceproblems/HappyNumber.java From a4d8157872e52bf5cbc9c4f67b4b615e4f818522 Mon Sep 17 00:00:00 2001 From: Vignesh Rajarajan Date: Tue, 28 Nov 2023 14:45:25 +0530 Subject: [PATCH 49/51] new problems --- .gitignore | 5 ++++- .idea/.gitignore | 3 --- .idea/aws.xml | 17 ----------------- .idea/misc.xml | 13 ------------- .idea/vcs.xml | 6 ------ 5 files changed, 4 insertions(+), 40 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/aws.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/vcs.xml diff --git a/.gitignore b/.gitignore index de410e2..84238f2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,12 @@ .DS_Store .classpath .project -AmazonProblems.iml +*.iml out/ *.json /.idea/* /.idea/ /out/*.class + +target/ +.idea/ \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/aws.xml b/.idea/aws.xml deleted file mode 100644 index 03f1bb6..0000000 --- a/.idea/aws.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 35bf185..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 61efa87a529edb7b287b8d62fbb822175e5a8ffc Mon Sep 17 00:00:00 2001 From: Vignesh Rajarajan Date: Tue, 9 Jul 2024 12:46:36 +0530 Subject: [PATCH 50/51] adding newer problems --- Readme.md | 0 .../backtracking/DistributeStonesInGrid.java | 70 ++++++++ .../binarysearch/FlowerBloomSparseArray.java | 92 +++++++++++ .../java/binarysearch/NumberOfRectangles.java | 65 ++++++++ src/main/java/binarysearch/PivotInteger.java | 26 +++ src/main/java/bitwise/AddNumbers.java | 24 +++ src/main/java/bitwise/BitwiseRange.java | 31 ++++ src/main/java/bitwise/ExcellentList.java | 51 ++++++ .../MaxProductString.java | 17 +- src/main/java/bitwise/Reverse.java | 14 ++ src/main/java/bitwise/SingleNumberII.java | 70 ++++++++ src/main/java/bitwise/Subset.java | 34 ++++ src/main/java/cess/DigitQueries.java | 67 ++++++++ src/main/java/cess/GridPath.java | 153 ++++++++++++++++++ .../java/cess/sort_search/Apartments.java | 33 ++++ .../java/cess/sort_search/MovieFestival.java | 41 +++++ .../cess/sort_search/RestaurantCustomers.java | 29 ++++ .../java/cess/sort_search/SubsetSumCoin.java | 31 ++++ .../fibonacci/DecodeWays.java | 16 +- .../java/graph/MinimumJumpsToReachHome.java | 57 +++++++ .../practiceproblems/AdvantageShuffle.java | 4 +- .../AircraftMovieDuration.java | 37 ++--- .../AircraftOptimization.java | 4 +- .../AlternateOddAndEvenNumbers.java | 18 +-- .../java/practiceproblems/AngleOfClock.java | 1 - .../java/practiceproblems/ArrangeInQueue.java | 10 +- .../PlatesBetweenCandles.java | 82 ++++++++++ .../UniqueCharactersInSubStringII.java | 55 +++++++ .../practiceproblems/design/MyCalendar.java | 47 ++++++ .../design/UniqueCharactersInSubString.java | 78 +++++++++ .../prefixsum/MaxNegativeNumbers.java | 42 +++++ .../prefixsum/SubstringEqualFragments.java | 118 ++++++++++++++ .../prefixsum/UniqueSubArrayDivisibleByK.java | 43 +++++ src/main/java/segmentTree/SegmentTree.java | 141 ++++++++++++++++ .../java/strings/stringProblems/ZigZag.java | 35 ++++ 35 files changed, 1587 insertions(+), 49 deletions(-) create mode 100644 Readme.md create mode 100644 src/main/java/backtracking/DistributeStonesInGrid.java create mode 100644 src/main/java/binarysearch/FlowerBloomSparseArray.java create mode 100644 src/main/java/binarysearch/NumberOfRectangles.java create mode 100644 src/main/java/binarysearch/PivotInteger.java create mode 100644 src/main/java/bitwise/AddNumbers.java create mode 100644 src/main/java/bitwise/BitwiseRange.java create mode 100644 src/main/java/bitwise/ExcellentList.java rename src/main/java/{strings/stringmatching => bitwise}/MaxProductString.java (66%) create mode 100644 src/main/java/bitwise/Reverse.java create mode 100644 src/main/java/bitwise/SingleNumberII.java create mode 100644 src/main/java/bitwise/Subset.java create mode 100644 src/main/java/cess/DigitQueries.java create mode 100644 src/main/java/cess/GridPath.java create mode 100644 src/main/java/cess/sort_search/Apartments.java create mode 100644 src/main/java/cess/sort_search/MovieFestival.java create mode 100644 src/main/java/cess/sort_search/RestaurantCustomers.java create mode 100644 src/main/java/cess/sort_search/SubsetSumCoin.java create mode 100644 src/main/java/graph/MinimumJumpsToReachHome.java create mode 100644 src/main/java/practiceproblems/PlatesBetweenCandles.java create mode 100644 src/main/java/practiceproblems/UniqueCharactersInSubStringII.java create mode 100644 src/main/java/practiceproblems/design/MyCalendar.java create mode 100644 src/main/java/practiceproblems/design/UniqueCharactersInSubString.java create mode 100644 src/main/java/practiceproblems/prefixsum/MaxNegativeNumbers.java create mode 100644 src/main/java/practiceproblems/prefixsum/SubstringEqualFragments.java create mode 100644 src/main/java/practiceproblems/prefixsum/UniqueSubArrayDivisibleByK.java create mode 100644 src/main/java/segmentTree/SegmentTree.java create mode 100644 src/main/java/strings/stringProblems/ZigZag.java diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/backtracking/DistributeStonesInGrid.java b/src/main/java/backtracking/DistributeStonesInGrid.java new file mode 100644 index 0000000..05c4516 --- /dev/null +++ b/src/main/java/backtracking/DistributeStonesInGrid.java @@ -0,0 +1,70 @@ +package backtracking; + +/** + * https://leetcode.com/problems/minimum-moves-to-spread-stones-over-grid/ + * + * Brute force solution + * DFS + */ +public class DistributeStonesInGrid { + int ret = Integer.MAX_VALUE; + public int minimumMoves(int[][] grid) { + dfs(grid, 0); + return ret; + } + + /** + * Iterate through all possible pairs of source (cell value > 1) and destination cells (cell value == 0) + * in the grid to check if it's possible to move a stone from the source cell to the destination cell. + * + * Check if the Destination cell is empty (contains 0 stones) and if the Source cell contains more than 1 stone. + * Decrease the number of stones in the Source by 1 and increase stones in the Destination cell by 1. + * Calculate the Manhattan distance between the Source and the Destination. + * Backtracking step: After exploration, restore the original grid configuration, i.e, reverse of step 2. + * The count variable keeps track of the minimum number of moves needed to achieve the desired configuration. + */ + private void dfs(int[][] grid, int move) { + int zx = -1; + int zy = -1; + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + if (grid[i][j] == 0) { + zx = i; + zy = j; + break; + + } + } + } + + // this is the base case, because of the constraint + if (zx == -1 && zy == -1) { + ret = Math.min(ret, move); + return; + } + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + if (grid[i][j] > 1) { + + grid[i][j] -= 1; + grid[zx][zy] += 1; + + int dx = Math.abs(i - zx); + int dy = Math.abs(j - zy); + + dfs(grid, move + dx + dy); + + // the reason we reset is to try all combinations + // if the result changes, it means we have found a better solution + // line 28 will take care of updating the result + grid[i][j] += 1; + grid[zx][zy] -= 1; + + } + } + } + + } +} diff --git a/src/main/java/binarysearch/FlowerBloomSparseArray.java b/src/main/java/binarysearch/FlowerBloomSparseArray.java new file mode 100644 index 0000000..36f5351 --- /dev/null +++ b/src/main/java/binarysearch/FlowerBloomSparseArray.java @@ -0,0 +1,92 @@ +package binarysearch; + +import java.util.*; + +/** + * ... + *

+ * one of the trick involved in computing rage queries over prefix sum is use the given query index to calculate the prefix-sum for ex + *

+ * if queries are from index (1 , 5) value is 4 and from index (3,7) value is 6, then the prefix array would look like + * [0,5,0,6,0,0,-5,0,0,-6,0,0] => when prefix sum is calculated then the array would get transformed to [0,5,5,11,11,11,6,6,6,0,0,0] + * the advantage is update query run time is O(1) as we are touching the specific index at that point, when get query comes we have to traverse the array and it's complexity is O(N) + *

+ * we can improve the above array storage space by removing 0 entries with the help of sparse array(a simple hashmap to store index and value at that place) + */ +public class FlowerBloomSparseArray { + // Blooming flowers = started flowers - ended flowers + // Collect start bloom time point array, then sort it. + //Collect end bloom time point array, then sort it. + // For each time point t in persons: + // + //Binary search the upper bound of t in start, then we find the started flowers. + //Binary search the lower bound of t in end, then we find the started flowers. + //Blooming flowers = started flowers - ended flowers + public static int[] fullBloomFlowersBinarySearch(int[][] flowers, int[] people) { + List starts = new ArrayList<>(); + List ends = new ArrayList<>(); + + + for (int[] flower: flowers) { + starts.add(flower[0]); + ends.add(flower[1] + 1); // Note that a flower = [start, end] stops blooming at end + 1, not end. + } + + Collections.sort(starts); + Collections.sort(ends); + int[] ans = new int[people.length]; + + for (int index = 0; index < people.length; index++) { + int person = people[index]; + int i = binarySearch(starts, person); + int j = binarySearch(ends, person); + ans[index] = i - j; + } + + return ans; + } + + public static int binarySearch(List arr, int target) { + int left = 0; + int right = arr.size(); + while (left < right) { + int mid = (left + right) / 2; + if (target < arr.get(mid)) { + right = mid; + } else { + left = mid + 1; + } + } + + return left; + } + + + public static void main(String[] args) { + fullBloomFlowersBinarySearch(new int[][]{{1, 6}, {3, 7}, {9, 12}, {4, 13}}, new int[]{2, 3, 7, 11}); + } + + public int[] fullBloomFlowers(int[][] flowers, int[] persons) { + int BLOOM = 0, WILT = 1, PERSON = 2; + int[] arr = new int[persons.length]; + PriorityQueue pq = new PriorityQueue<>((a,b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]); + for (int[] flower : flowers) { + pq.offer(new int[]{flower[0], BLOOM}); + pq.offer(new int[]{flower[1], WILT}); + } + for(int i = 0; i < persons.length; i++){ + pq.offer(new int[]{persons[i],PERSON,i}); + } + int count = 0; + while(!pq.isEmpty()){ + int[] temp = pq.poll(); + + if(temp[1] == BLOOM) count++; + else if(temp[1] == WILT) count--; + else{ + arr[temp[2]] = count; + } + } + return arr; + } +} diff --git a/src/main/java/binarysearch/NumberOfRectangles.java b/src/main/java/binarysearch/NumberOfRectangles.java new file mode 100644 index 0000000..f8be65b --- /dev/null +++ b/src/main/java/binarysearch/NumberOfRectangles.java @@ -0,0 +1,65 @@ +package binarysearch; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + + +/** + * https://leetcode.com/problems/count-number-of-rectangles-containing-each-point + * the constraints are + * 1 <= rectangles.length, points.length <= 5 * 10^4 + * 1 <= li, xj <= 10^9 + * 1 <= hi, yj <= 100 + * This tells us that we cannot go through all the rectangles for all the points, + * coz that will be 5 * 10^4 * 5* 10^4 which would be > 10^8 operations, so would give TLE. + */ +public class NumberOfRectangles { + //We see that heights are only from 0 to 100. + // So can traverse in them. But lengths can be till 10^9 so have to do binary search in that. + public int[] countRectangles(int[][] rectangles, int[][] points) { + int[] res = new int[points.length]; + List> group = new ArrayList<>(101); + for(int i = 0; i < 101; i++){ + group.add(new ArrayList<>()); + } + + for(int[] rec : rectangles){ + int l = rec[0]; + int h = rec[1]; + group.get(h).add(l); + } + + for(int i = 0; i < 101; i++){ + Collections.sort(group.get(i)); + } + + for(int i = 0; i < points.length; i++){ + int count = 0; + int x = points[i][0]; + int y = points[i][1]; + for(int j = y; j < 101; j++){ + List cur = group.get(j); + int index = binarySearch(cur, x); + count += cur.size() - index; + } + res[i] = count; + } + + return res; + } + + private int binarySearch(List list, int x){ + int left = 0; + int right = list.size(); + while(left < right){ + int mid = left + (right - left) / 2; + if(list.get(mid) >= x){ + right = mid; + } else{ + left = mid + 1; + } + } + return left; + } +} diff --git a/src/main/java/binarysearch/PivotInteger.java b/src/main/java/binarysearch/PivotInteger.java new file mode 100644 index 0000000..aec4bf0 --- /dev/null +++ b/src/main/java/binarysearch/PivotInteger.java @@ -0,0 +1,26 @@ +package binarysearch; + +public class PivotInteger { + + public int pivotInteger(int n) { + + int total = (n * (n + 1)) / 2; + + int left = 0; + int right = n; + + while (left < right) { + int mid = (left + right) / 2; + + if ((mid * mid - total) < 0) { + left = mid + 1; + } else { + right = mid; + } + + } + + return left * left - total == 0 ? left : -1; + + } +} diff --git a/src/main/java/bitwise/AddNumbers.java b/src/main/java/bitwise/AddNumbers.java new file mode 100644 index 0000000..302057b --- /dev/null +++ b/src/main/java/bitwise/AddNumbers.java @@ -0,0 +1,24 @@ +package bitwise; + +// https://leetcode.com/problems/add-binary/ +public class AddNumbers { + public String addBinary(String a, String b) { + StringBuilder sb = new StringBuilder(); + int i = a.length()-1; + int j = b.length()-1; + int carry = 0; + while (i >= 0 || j >= 0 || carry == 1) { + if (i >= 0) { + carry += a.charAt(i--) - '0'; + } + if (j >= 0) { + carry += b.charAt(j--) - '0'; + } + sb.append(carry % 2); + carry /= 2; + } + + return sb.reverse().toString(); + } + +} diff --git a/src/main/java/bitwise/BitwiseRange.java b/src/main/java/bitwise/BitwiseRange.java new file mode 100644 index 0000000..e7aaef3 --- /dev/null +++ b/src/main/java/bitwise/BitwiseRange.java @@ -0,0 +1,31 @@ +package bitwise; + +// https://leetcode.com/problems/bitwise-and-of-numbers-range/ +public class BitwiseRange { + + + // https://www.youtube.com/watch?v=j3XRFREnPWI + // the reason here is there is a common prefix between the two numbers + // we find the common prefix and then shift it to the left + // this is a property of bitwise and + + public static int rangeBitwiseAnd(int left, int right) { + int shift = 0; + System.out.println("le: " + Integer.toBinaryString(left)); + System.out.println("ri: " + Integer.toBinaryString(right)); + System.out.println("#########"); + while (left < right) { + left >>= 1; + right >>= 1; + System.out.println("le : " + Integer.toBinaryString(left)); + System.out.println("ri : " + Integer.toBinaryString(right)); + shift++; + } + + return left << shift; + } + + public static void main(String[] args) { + System.out.println(rangeBitwiseAnd(1024, 512)); + } +} diff --git a/src/main/java/bitwise/ExcellentList.java b/src/main/java/bitwise/ExcellentList.java new file mode 100644 index 0000000..b6d6308 --- /dev/null +++ b/src/main/java/bitwise/ExcellentList.java @@ -0,0 +1,51 @@ +package bitwise; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +// https://leetcode.com/problems/number-of-excellent-pairs/ +public class ExcellentList { + /** + https://leetcode.com/problems/number-of-excellent-pairs/solutions/2370663/c-logic-explained-with-pictures/ + * If there are x set bits in a number and y set bits in b number + * then the OR component is x+y-k where k is the number of set bits common in a&b + * the AND component is k + * so the final answer (AND+OR) is x+y-k+k = x+y + * @param nums + * @param k + * @return + */ + public long countExcellentPairs(int[] nums, int k) { + long[] count = new long[30]; // 30 instead of 32 because the constraint of the problem is + // 1E9 which can be considered as 2^30 + Set set = Arrays.stream(nums).collect(HashSet::new, Set::add, Set::addAll); + for (int a: set){ + count[Integer.bitCount(a)]++; + } + long result = 0L; + for (int i=1;i<30;++i){ + for (int j=1;j<30;++j){ + if (i+j >= k){ + // the reason we are multiplying the count[i] and count[j] is because + // if we have 2 elements with i bits and 3 elements with j bits, then + // we can have 2*3 = 6 excellent pairs + /** + * Array: nums = [4, 6, 7, 10] + * k = 5 + * Count Array: + * count[2] = 2 (two numbers with 2 1s: 4 and 6) + * count[3] = 1 (one number with 3 1s: 7) + * count[4] = 1 (one number with 4 1s: 10) + * Multiplication: + * count[2] * count[3] = 2 * 1 = 2 (pairs: (4, 7), (6, 7)) + * count[2] * count[4] = 2 * 1 = 2 (pairs: (4, 10), (6, 10)) + * Total potential excellent pairs: 4 + */ + result+=count[i]*count[j]; + } + } + } + return result; + } +} diff --git a/src/main/java/strings/stringmatching/MaxProductString.java b/src/main/java/bitwise/MaxProductString.java similarity index 66% rename from src/main/java/strings/stringmatching/MaxProductString.java rename to src/main/java/bitwise/MaxProductString.java index d734ac9..fe0b165 100644 --- a/src/main/java/strings/stringmatching/MaxProductString.java +++ b/src/main/java/bitwise/MaxProductString.java @@ -1,4 +1,4 @@ -package strings.stringmatching; +package bitwise; public class MaxProductString { @@ -27,10 +27,10 @@ public int maxProduct(String[] words) { for (int i = 0; i < words.length; i++) { for (int j = i + 1; j < words.length; j++) { - // abcd efgd - // 11110000 -> abcd - // and-ing these two might say if even a single char is present in other - if ((checker[i] & checker[j]) == 0) //checking if the two strings have common character + // bitwise and operation between two numbers + // if the result is 0, then there is no common character + // if the result is not 0, then there is a common character + if ((checker[i] & checker[j]) == 0) max = Math.max(max, words[i].length() * words[j].length()); } } @@ -40,8 +40,9 @@ public int maxProduct(String[] words) { public static void main(String[] args) { - // new MaxProductString().maxProduct(new String[]{"abcw", "baz", "foo", "bar", "xtfn", "abcdef"}); - - //new MaxProductString().backspaceCompare("isfcow#", "isfco#w#"); + MaxProductString m = new MaxProductString(); + m.maxProduct(new String[]{"abcw", "baz", "foo", "bar", "xtfn", "abcdef"}); + m.maxProduct(new String[]{"a", "ab", "abc", "d", "cd", "bcd", "abcd"}); + m.maxProduct(new String[]{"a", "aa", "aaa", "aaaa"}); } } \ No newline at end of file diff --git a/src/main/java/bitwise/Reverse.java b/src/main/java/bitwise/Reverse.java new file mode 100644 index 0000000..6097f1f --- /dev/null +++ b/src/main/java/bitwise/Reverse.java @@ -0,0 +1,14 @@ +package bitwise; + +// https://leetcode.com/problems/reverse-bits/ +public class Reverse { + + public int reverseBits(int n) { + int ans =0; + for(int i=0;i<=31;i++){ + int bit = n>>i & 1; + ans|=(bit<<31-i); + } + return ans; + } +} diff --git a/src/main/java/bitwise/SingleNumberII.java b/src/main/java/bitwise/SingleNumberII.java new file mode 100644 index 0000000..b2da3d4 --- /dev/null +++ b/src/main/java/bitwise/SingleNumberII.java @@ -0,0 +1,70 @@ +package bitwise; +// https://leetcode.com/problems/single-number-ii/ +// https://leetcode.com/problems/single-number-iii/ +public class SingleNumberII { + public int singleNumber(int[] nums) { + int ans = 0; + + for (int i = 0; i < 32; ++i) { + int sum = 0; + for (final int num : nums) { + // This step creates a bitmask pos where only the bit at + // position i is set to the value of sum + sum += num >> i & 1; + } + //Take the modulo of sum by 3: sum %= 3 + // This will clear the ith bit of ans if the corresponding bit of sum is 3. + // It will leave it as 1 if the corresponding bit of sum is 1. + sum %= 3; + + //Use the bitwise OR operation with ans and pos: ans |= pos. + // This sets the corresponding bit in ans to 1 + // if the bit at position i is part of an unbalanced line. + ans |= sum << i; + } + + return ans; + } + + /** + * High level: find XOR combo of two result. Then find one of them + * Step 1: XOR all numbers, the result will be res1 ^ res2 + * Step 2: traverse all 32 bit indexes of previous XOR result, once we find there exist 1 on a bit index, break + * the loop. Because one of the result at least have bit 1 on current bit index + * Step 3: traverse all numbers in the input array, if we find a number & the bit index we found at step 2 is not 0, + * then we can use res1 XOR current num to iteratively fill out effective bit in res1 + * (i.e. res1 ^ n1 ^ n1 ^ n2 ^ n2 = res1, if res1, n1 and n2 have bit 1 on the bitIndex + * Step 4: find another result number by using res1 ^ allNumberXOR (i.e. res1 ^ (res1 ^ res2 ^ ...)) = res2) + * */ + + public int[] singleNumberIII(int[] nums) { + int res1 = 0; + int res2 = 0; + + // step 1: find XOR combo of two numbers + int allNumXOR = 0; + for (int num : nums) { + allNumXOR ^= num; + } + + // step 2: find effective bit index of a number in one of two result numbers + int bitIndex; + for (bitIndex = 0; bitIndex < 32; bitIndex++) { + if ((allNumXOR & (1 << bitIndex)) != 0) { + break; + } + } + + // step 3: find first result + for (int num : nums) { + if ((num & (1 << bitIndex)) != 0) { + // current bitIndex, we only want that single one, + // and cancel all the rest of numbers by using XOR + res1 ^= num; + }else{ + res2 ^= num; + } + } + return new int[]{res1, res2}; + } +} diff --git a/src/main/java/bitwise/Subset.java b/src/main/java/bitwise/Subset.java new file mode 100644 index 0000000..aa2519c --- /dev/null +++ b/src/main/java/bitwise/Subset.java @@ -0,0 +1,34 @@ +package bitwise; + +import java.util.ArrayList; +import java.util.List; + +public class Subset { + + public List> subsets(int[] nums) { + List> result = new ArrayList<>(); + int n=nums.length; + /* + + Iteration 1: num = 0 (000 in binary), loop skips. + Iteration 2: num = 1 (001), subset = [1]. + Iteration 3: num = 2 (010), subset = [2]. + Iteration 4: num = 3 (011), subset = [1, 3]. + Iteration 5: num = 4 (100), subset = [3]. + Iteration 6: num = 5 (101), subset = [2, 3]. + Iteration 7: num = 6 (110), subset = [1, 2]. + Iteration 8: num = 7 (111), subset = [1, 2, 3]. + */ + for (int i = 0; i < (1 << n); i++) { + ArrayList in = new ArrayList<>(); + for (int j = 0; j < n; j++) { + if ((i & (1 << j)) != 0) { + in.add(nums[j]); + } + } + result.add(in); + } + + return result; // total complexity: n.2^n + } +} diff --git a/src/main/java/cess/DigitQueries.java b/src/main/java/cess/DigitQueries.java new file mode 100644 index 0000000..afe8745 --- /dev/null +++ b/src/main/java/cess/DigitQueries.java @@ -0,0 +1,67 @@ +package cess; + +import java.util.Arrays; + +/** + * https://www.youtube.com/watch?v=QAcH8qD9Pe0 + * https://cses.fi/problemset/task/2431 + * + * too complex, debug to understand + */ +public class DigitQueries { + + public static String solve(long[] arr) { + long[] powerOfTen = new long[19]; + Arrays.fill(powerOfTen, 1); + + for (int i = 1; i < powerOfTen.length; i++) { + powerOfTen[i] = powerOfTen[i - 1] * 10; + + } + + for (long index : arr) { + + long digitsSoFar = 0; + long digitsBeforeActualBlock = 0; + int numberOfDigits = 0; + + for (int j = 1; j <= 18; j++) { + long distance = (powerOfTen[j] * powerOfTen[j - 1]) * j; + + digitsSoFar += distance; + + if (digitsSoFar >= index) { + numberOfDigits = j; + break; + } + digitsBeforeActualBlock += distance; + } + + long smallestValue = powerOfTen[numberOfDigits - 1]; + long largestValue = powerOfTen[numberOfDigits] - 1; + long bestValue = 0; + long bestValueStartPos = 0; + + while (smallestValue <= largestValue) { + long mid = (smallestValue + largestValue) / 2; + long startPostOfActual = digitsBeforeActualBlock + 1 + (mid - powerOfTen[numberOfDigits - 1]) * numberOfDigits; + if (startPostOfActual <= index) { + if (mid > bestValue) { + bestValue = mid; + bestValueStartPos = startPostOfActual; + } + smallestValue = mid + 1; + } else { + largestValue = mid - 1; + } + } + int res = (int) ((int) index - bestValueStartPos); + return String.valueOf(String.valueOf(bestValue).charAt(res)); + } + return ""; + } + + public static void main(String[] args) { + solve(new long[]{107}); + } +} diff --git a/src/main/java/cess/GridPath.java b/src/main/java/cess/GridPath.java new file mode 100644 index 0000000..dab0fb4 --- /dev/null +++ b/src/main/java/cess/GridPath.java @@ -0,0 +1,153 @@ +package cess; + +public class GridPath { + + public static boolean[][] onPath = new boolean[9][9]; + public static int[][] dirs = new int[][]{{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; + static int[] p = new int[48]; + + /** + * Basic Algorithm + + * The first version of the algorithm does not contain any optimizations. We simply + * use backtracking to generate all possible paths from the upper-left corner to + * the lower-right corner and count the number of such paths. + + * Running time: 483 seconds + * Number of recursive calls: 76 billion + * + * + * Optimization 1 + * + * If the path reaches the lower-right square before it has visited all other + * squares of the grid, it is clear that it will not be possible to complete the + * solution. Using this observation, we can terminate the search immediately if we + * reach the lower-right square too early. + * + * Running time: 119 seconds + * Number of recursive calls: 20 billion + * + * + * If the path touches a wall and can turn either left or right, the grid splits + * into two parts that contain unvisited squares. In this case, we cannot visit all + * squares anymore, so we can terminate the search. + * + * Running time: 1.8 seconds + * Number of recursive calls: 221 million + * + * + * The idea of Optimization 2 can be generalized: if the path cannot continue + * forward but can turn either left or right, the grid splits into two parts that + * both contain unvisited squares. It is clear that we cannot visit all squares + * anymore, so we can terminate the search. + * + * Running time: 0.6 seconds + * Number of recursive calls: 69 million + * + * + * Now is a good moment to stop optimizing the algorithm and see what we have + * achieved. The running time of the original algorithm was $483$ seconds, and now + * after the optimizations, the running time is only $0.6$ seconds. Thus, the + * algorithm became nearly $1000$ times faster after the optimizations. + * + * Optimization 4 + * + * If the path creates a dead end that is not the bottom left corner, either the + * path will fail to visit all squares (the path may stop at the dead end or pass + * over it, sealing a square off) or the path will end in the wrong location. Thus, + * we want to avoid creating dead ends. For example, if the square to the left of + * our current location is blocked on three sides (including our current location), + * then the next step must be to the left in order to avoid creating a dead end. + * After this optimization, the program runs in under $1$ second. + */ + public int calculateGridPaths(String line) { + if (line.length() != 48) return -1; + + for (int i = 0; i < p.length; i++) { + char cur = line.charAt(i); + + if (cur == 'U') p[i] = 0; + else if (cur == 'R') p[i] = 1; + else if (cur == 'D') p[i] = 2; + else if (cur == 'L') p[i] = 3; + else p[i] = 4; // cur == '?' + } + + // set borders of grid + for (int i = 0; i < 9; i++) { + onPath[0][i] = true; + onPath[8][i] = true; + onPath[i][0] = true; + onPath[i][8] = true; + } + + return tryPath(0, 1, 1); + } + + public static int tryPath(int pathIdx, int curR, int curC) { + // Optimization 3 + if ((onPath[curR][curC - 1] && onPath[curR][curC + 1]) && + (!onPath[curR - 1][curC] && !onPath[curR + 1][curC])) + return 0; + if ((onPath[curR - 1][curC] && onPath[curR + 1][curC]) && + (!onPath[curR][curC - 1] && !onPath[curR][curC + 1])) + return 0; + + // Optimization 1 + if (curR == 7 && curC == 1) { // reached endpoint + if (pathIdx == p.length) return 1; // visited every cell -> valid! + return 0; // didn't visit every cell (path length is too short) + } + // visited all cells, but didn't end up in the correct location + if (pathIdx == p.length) return 0; + + int ret = 0; // cumulative count for this "starting position" + onPath[curR][curC] = true; + + // turn already determined, try going in that direction + if (p[pathIdx] < 4) { + int nxtR = curR + dirs[p[pathIdx]][0]; + int nxtC = curC + dirs[p[pathIdx]][1]; + if (!onPath[nxtR][nxtC]) { + ret += tryPath(pathIdx + 1, nxtR, nxtC); + } + } +// // now search for dead ends (Optimization 4) +// else if ((curC > 2) && onPath[curR][curC - 2] && +// (onPath[curR - 1][curC - 1] || onPath[curR + 1][curC - 1]) && +// (!onPath[curR][curC - 1])) { +// // potential dead end on the left: +// int nxtR = curR; +// int nxtC = curC - 1; +// ret += tryPath(pathIdx + 1, nxtR, nxtC); +// } else if ((curC < 6) && onPath[curR][curC + 2] && +// (onPath[curR - 1][curC + 1] || onPath[curR + 1][curC + 1]) && +// (!onPath[curR][curC + 1])) { +// // potential dead end on the right: +// int nxtR = curR; +// int nxtC = curC + 1; +// ret += tryPath(pathIdx + 1, nxtR, nxtC); +// } else if ((curR > 2) && onPath[curR - 2][curC] && +// onPath[curR - 1][curC - 1] && (!onPath[curR - 1][curC])) { +// // potential dead end upwards +// // note: I didn't include all possible scenarios because +// // it wasn't necessary in order for the program to run in time +// int nxtR = curR - 1; +// int nxtC = curC; +// ret += tryPath(pathIdx + 1, nxtR, nxtC); +// } + // iterate through all four possible turns + else { + for (int i = 0; i < 4; i++) { + int nxtR = curR + dirs[i][0]; + int nxtC = curC + dirs[i][1]; + if (onPath[nxtR][nxtC]) continue; + ret += tryPath(pathIdx + 1, nxtR, nxtC); + } + } + + // reset and return + onPath[curR][curC] = false; + return ret; + } +} diff --git a/src/main/java/cess/sort_search/Apartments.java b/src/main/java/cess/sort_search/Apartments.java new file mode 100644 index 0000000..ffae1ec --- /dev/null +++ b/src/main/java/cess/sort_search/Apartments.java @@ -0,0 +1,33 @@ +package cess.sort_search; + +import java.util.Arrays; + +public class Apartments { + + public static int search(int[] memberReq, int[] apartments, int diff) { + Arrays.sort(apartments); + Arrays.sort(memberReq); + int i = 0; + int j = 0; + int ans = 0; + for (; i < memberReq.length; i++) { + // if the curr space is less, then try finding a suitable apartment for applicant i + while (j < apartments.length && apartments[j] < memberReq[i] - diff) { + j++; + } + if (Math.abs(apartments[j] - memberReq[i]) <= diff) { + ans++; + i++; + j++; + } else { + // if it's large then move to next applicant + i++; + } + } + return ans; + } + + public static void main(String[] args) { + search(new int[]{60,45,80,60},new int[]{30,60,75}, 5); + } +} diff --git a/src/main/java/cess/sort_search/MovieFestival.java b/src/main/java/cess/sort_search/MovieFestival.java new file mode 100644 index 0000000..e3d4cfc --- /dev/null +++ b/src/main/java/cess/sort_search/MovieFestival.java @@ -0,0 +1,41 @@ +package cess.sort_search; + +import graph.leetcode.Pair; + +import java.util.*; + +// similar to intervals problem but with a twist +public class MovieFestival { + + public static int moviesWatchedCount(int[][] movieTimings, int persons){ + int unWatchableCount = 0; + Arrays.sort(movieTimings, Comparator.comparingInt(a -> a[1])); + TreeSet> set = new TreeSet<>(Comparator.comparingInt(a -> a.key)); + + for(int i=0;i(movieTimings[i][1]*-1,i)); + continue; + } + Pair p = set.lower(new Pair<>(movieTimings[i][0]*-1,-1)); + if (p!=null && !Objects.equals(p.value, set.last().value)){ + set.remove(p); + set.add(new Pair<>(movieTimings[i][1]*-1,i)); + continue; + } + if (set.size() < persons){ + set.add(new Pair<>(movieTimings[i][1]*-1,i)); + }else { + unWatchableCount++; + } + + } + + return movieTimings.length - unWatchableCount; + } + + public static void main(String[] args) { + System.out.println(moviesWatchedCount(new int[][]{{1,5},{8,10},{3,6},{2,5},{6,9}},2)); + } + +} diff --git a/src/main/java/cess/sort_search/RestaurantCustomers.java b/src/main/java/cess/sort_search/RestaurantCustomers.java new file mode 100644 index 0000000..bb8e8d3 --- /dev/null +++ b/src/main/java/cess/sort_search/RestaurantCustomers.java @@ -0,0 +1,29 @@ +package cess.sort_search; + +import java.util.Map; +import java.util.TreeMap; + +/** + * https://cses.fi/problemset/task/1619 + * https://www.youtube.com/watch?v=O9Sptr-RdRo + */ +public class RestaurantCustomers { + + public int maxCustomersAtGivenTime(int[][] arrivalTimes){ + Map cache = new TreeMap<>(); + + for (int[] arr:arrivalTimes) { + cache.put(arr[0],1); + cache.put(arr[1],-1); + } + int ans =0; + int count =0; + for (Map.Entry entry : cache.entrySet()){ + + ans = Math.max(ans,count+entry.getValue()); + } + + return ans; + + } +} diff --git a/src/main/java/cess/sort_search/SubsetSumCoin.java b/src/main/java/cess/sort_search/SubsetSumCoin.java new file mode 100644 index 0000000..1578ec5 --- /dev/null +++ b/src/main/java/cess/sort_search/SubsetSumCoin.java @@ -0,0 +1,31 @@ +package cess.sort_search; + +import java.util.Arrays; + +public class SubsetSumCoin { + + public static int sumCannotFormedBySubset(int[] arr) { + int res = 1; // Initialize result + + // sort the input array + Arrays.sort(arr); + + // Traverse the array and increment 'res' if arr[i] is + // smaller than or equal to 'res'. + for (int i = 0; i < arr.length; i++) + { + if(arr[i] > res){ + return res; + } + else{ + res+=arr[i]; + } + } + + return res; + } + + public static void main(String[] args) { + System.out.println(sumCannotFormedBySubset(new int[]{2,9,1,2,7})); + } +} diff --git a/src/main/java/dynamicProgramming/fibonacci/DecodeWays.java b/src/main/java/dynamicProgramming/fibonacci/DecodeWays.java index c6d1fdc..7aa87b1 100644 --- a/src/main/java/dynamicProgramming/fibonacci/DecodeWays.java +++ b/src/main/java/dynamicProgramming/fibonacci/DecodeWays.java @@ -15,7 +15,7 @@ public class DecodeWays { public int numDecodings(String s) { - if (s == null || s.length() == 0) { + if (s == null || s.isEmpty()) { return 0; } int n = s.length(); @@ -36,29 +36,29 @@ public int numDecodings(String s) { } public int numDecodings1(String s) { - if (s == null || s.length() == 0) return 0; + if (s == null || s.isEmpty()) return 0; Integer[] cache = new Integer[s.length() + 1]; return helperFn(s, 0, cache); } public int helperFn(String s, int index, Integer[] cache) { -// When we reach the end of the string this means that we have found a possible way to decode. -// Thus, this will contribute to answer and return 1. - if (index >= s.length()) return 0; + //When we reach the end of the string this means that we have found a possible way to decode. + //Thus, this will contribute to answer and return 1. + if (index >= s.length()) return 1; if (cache[index] != null) return cache[index]; int total = 0; if (index + 1 <= s.length()) { String temp1 = s.substring(index, index + 1); if (valid(temp1)) { - total += 1+helperFn(s, index + 1, cache); + total += helperFn(s, index + 1, cache); } } if (index + 2 <= s.length()) { String temp2 = s.substring(index, index + 2); if (valid(temp2)) { - total += 1+helperFn(s, index + 2, cache); + total += helperFn(s, index + 2, cache); } } @@ -68,7 +68,7 @@ public int helperFn(String s, int index, Integer[] cache) { } public boolean valid(String s1) { - if (s1.length() == 0) return false; + if (s1.isEmpty()) return false; if (s1.charAt(0) == '0') return false; //If current element is 0, we simply return 0 as it is not possible to get a character using 0. int val = Integer.parseInt(s1); diff --git a/src/main/java/graph/MinimumJumpsToReachHome.java b/src/main/java/graph/MinimumJumpsToReachHome.java new file mode 100644 index 0000000..f204168 --- /dev/null +++ b/src/main/java/graph/MinimumJumpsToReachHome.java @@ -0,0 +1,57 @@ +package graph; + +import java.util.LinkedList; +import java.util.Queue; + +//https://leetcode.com/problems/minimum-jumps-to-reach-home/description/ +public class MinimumJumpsToReachHome { + static class Pair { + int pos; + boolean dir; + public Pair(int pos, boolean dir) { + this.pos = pos; + this.dir = dir; + } + } + public int minimumJumps(int[] forbidden, int a, int b, int x) { + int limit = 2000 + 2 * b + 1; // could hardcode a value grater than given in the limit of the problem + boolean[] visited = new boolean[limit]; + for (int num: forbidden) { + visited[num] = true; + } + int step = 0; + Queue q = new LinkedList<>(); + q.add(new Pair(0, false)); + visited[0] = true; + while (!q.isEmpty()) { + int size = q.size(); + for (int i = 0; i < size; i++) { + Pair p = q.poll(); + int pos = p.pos; + boolean dir = p.dir; + + if (pos == x) return step; + + if (!dir) { + int backward = pos - b; + + if (backward > 0 && !visited[backward]) { + q.offer(new Pair(backward, true)); + visited[backward] = true; + } + } + + int forward = pos + a; + + if (forward < limit && !visited[forward]) { + q.offer(new Pair(forward, false)); + visited[forward] = true; + } + + + } + step++; + } + return -1; + } +} diff --git a/src/main/java/practiceproblems/AdvantageShuffle.java b/src/main/java/practiceproblems/AdvantageShuffle.java index b05aff7..40ca136 100644 --- a/src/main/java/practiceproblems/AdvantageShuffle.java +++ b/src/main/java/practiceproblems/AdvantageShuffle.java @@ -22,7 +22,7 @@ public class AdvantageShuffle { public static int[] advantageCount(int[] A, int[] B) { Arrays.sort(A); - PriorityQueue pq = new PriorityQueue<>((a, b) -> Integer.compare(b[0], a[0])); + var pq = new PriorityQueue((a, b) -> Integer.compare(b[0], a[0])); for (int i = 0; i < B.length; i++) { pq.offer(new Integer[]{B[i], i}); // add elements of B along with its index to max queue } @@ -32,7 +32,7 @@ public static int[] advantageCount(int[] A, int[] B) { //B is transformed to [32,25,13,11] //A is transformed to [8,12,24,32] while (!pq.isEmpty()) { - Integer[] temp = pq.poll(); + var temp = pq.poll(); int index = temp[1]; int val = temp[0]; /** diff --git a/src/main/java/practiceproblems/AircraftMovieDuration.java b/src/main/java/practiceproblems/AircraftMovieDuration.java index 517b470..bdf7ce8 100644 --- a/src/main/java/practiceproblems/AircraftMovieDuration.java +++ b/src/main/java/practiceproblems/AircraftMovieDuration.java @@ -38,24 +38,25 @@ private static int[] get2SumClosest(int[] movie_duration, int d) { int max = 0; int[] res = new int[]{-1, -1}; while (l < r) { - int sum = movie_duration[l] + movie_duration[r]; - if ((sum > max || (sum == max && movie_duration[r] > res[1])) && sum <= d) { - max = sum; - res[0] = movie_duration[l]; - res[1] = movie_duration[r]; - } - if (sum > d) - r--; - else - l++; - } - if (map.get(res[0]) == map.get(res[1])) { // checking if both values contains same list, could improve a bit - res[0] = map.get(res[0]).get(0); - res[1] = map.get(res[1]).get(1); - } else { - res[0] = map.get(res[0]).get(0); - res[1] = map.get(res[1]).get(0); - } + int sum = movie_duration[l] + movie_duration[r]; + boolean isSumGreater = sum > max; + boolean isSumEqualAndDurationGreater = sum == max && movie_duration[r] > res[1]; + boolean isSumWithinDuration = sum <= d; + + if ((isSumGreater || isSumEqualAndDurationGreater) && isSumWithinDuration) { + max = sum; + res[0] = movie_duration[l]; + res[1] = movie_duration[r]; + } + + int direction = sum > d ? -1 : 1; + if (direction == -1) r += direction; + else l += direction; +} + +boolean isSameList = map.get(res[0]) == map.get(res[1]); +res[0] = map.get(res[0]).get(0); +res[1] = map.get(res[1]).get(isSameList ? 1 : 0); return res; } } diff --git a/src/main/java/practiceproblems/AircraftOptimization.java b/src/main/java/practiceproblems/AircraftOptimization.java index f9d859a..03e6987 100644 --- a/src/main/java/practiceproblems/AircraftOptimization.java +++ b/src/main/java/practiceproblems/AircraftOptimization.java @@ -7,7 +7,7 @@ * Given 2 lists a and b. Each element is a pair of integers where the first integer represents the unique id and the second integer represents a value. * Your task is to find an element from a and an element form b such that the sum of their values is less or equal to target and as close to target as possible. * Return a list of ids of selected elements. If no pair is possible, return an empty list. - * + * * a = [[1, 2], [2, 4], [3, 6]] b = [[1, 2]] target = 7 @@ -36,7 +36,7 @@ public List> calculateOptimalRoute(final List> forwa if (currentSum > max && currentSum <= capacity) { max = currentSum; - // Initializing new list + // got a new max so Initializing new list result = new LinkedList<>(); result.add(new ArrayList<>(Arrays.asList(forwardList.get(i).get(0), returnList.get(j).get(0)))); i++; diff --git a/src/main/java/practiceproblems/AlternateOddAndEvenNumbers.java b/src/main/java/practiceproblems/AlternateOddAndEvenNumbers.java index 6361814..13ab9bc 100644 --- a/src/main/java/practiceproblems/AlternateOddAndEvenNumbers.java +++ b/src/main/java/practiceproblems/AlternateOddAndEvenNumbers.java @@ -4,6 +4,7 @@ /** * https://www.geeksforgeeks.org/rearrange-positive-and-negative-numbers-publish/ + * * An array contains both positive and negative numbers in random order. * Rearrange the array elements so that positive and negative numbers are placed alternatively. * If there are more positive numbers they appear at the end of the array. @@ -13,9 +14,9 @@ */ class AlternateOddAndEvenNumbers { - static void rearrange(int arr[], int n) { + static void rearrange(int[] arr, int n) { //-1, 2, -3, 4, 5, 6, -7, 8, 9 - int i = 0, temp = 0; + int i = 0, temp; for (int j = 0; j < n; j++) { if (arr[j] < 0) { temp = arr[i]; @@ -26,17 +27,16 @@ static void rearrange(int arr[], int n) { } // we have segregated positive and negative elements System.out.println(Arrays.toString(arr) + " :i - " + i); - // now the 'pos' indicates start of positive integer, 'neg' starts from 0 - int pos = i, neg = 0; + // now the 'pos' indicates start of positive integer, 'negPos' starts from 0 + int pos = i, negPos = 0; - while (pos < n && neg < pos && arr[neg] < 0) { - temp = arr[neg]; - arr[neg] = arr[pos]; + while (pos < n && negPos < pos && arr[negPos] < 0) { + temp = arr[negPos]; + arr[negPos] = arr[pos]; arr[pos] = temp; pos++; - neg += 2; // need to skip next element as output should be alternative - System.out.println(Arrays.toString(arr)); + negPos += 2; // need to skip next element as output should be alternative } } diff --git a/src/main/java/practiceproblems/AngleOfClock.java b/src/main/java/practiceproblems/AngleOfClock.java index a162592..d0dc121 100644 --- a/src/main/java/practiceproblems/AngleOfClock.java +++ b/src/main/java/practiceproblems/AngleOfClock.java @@ -1,7 +1,6 @@ package practiceproblems; public class AngleOfClock { - public double angleClock(int hours, int minutes) { // every hour is 30(deg) (360 (deg)/12) because 12 hrs in clock // every min is 6(deg) (360(deg)/60) because 60 mins per hr diff --git a/src/main/java/practiceproblems/ArrangeInQueue.java b/src/main/java/practiceproblems/ArrangeInQueue.java index 3ee25ac..1257d09 100644 --- a/src/main/java/practiceproblems/ArrangeInQueue.java +++ b/src/main/java/practiceproblems/ArrangeInQueue.java @@ -4,6 +4,8 @@ import java.util.Arrays; import java.util.List; + +//https://leetcode.com/problems/queue-reconstruction-by-height/description/ public class ArrangeInQueue { // 1. Sort people by their height, shortest to tallest @@ -17,7 +19,13 @@ public static int[][] reconstructQueue(int[][] people) { if (a[0] == b[0]) return a[1] - b[1]; else return b[0] - a[0]; }); - System.out.println("Sorted values: " + Arrays.deepToString(people)); + //Here's a potential algorithm: + //a. Sort the people array in descending order of height. If heights are equal, sort by ascending order of 'k'. + //b. Create an empty result array to represent the queue. + //c. Iterate through the sorted people array: + // + //For each person, insert them into the result array at index 'k'. + //This works because we're inserting taller people first, so the 'k' value directly corresponds to their position. for (int[] x : people) { result.add(x[1], x); System.out.println(Arrays.deepToString(result.toArray(new int[people.length][2]))); diff --git a/src/main/java/practiceproblems/PlatesBetweenCandles.java b/src/main/java/practiceproblems/PlatesBetweenCandles.java new file mode 100644 index 0000000..971a7ec --- /dev/null +++ b/src/main/java/practiceproblems/PlatesBetweenCandles.java @@ -0,0 +1,82 @@ +package practiceproblems; + +import java.util.TreeSet; + +//https://leetcode.com/problems/plates-between-candles/ +public class PlatesBetweenCandles { + public int[] platesBetweenCandles(String s, int[][] queries) { + int n = s.length(); + int[] nearestRightCandle = new int[n], nearestLeftCandle = new int[n] , starCount = new int[n]; + int candles = -1, stars = 0; + char[] ch = s.toCharArray(); + + for(int i = 0; i< n; i++){ + if(ch[i] == '*'){ + stars++; + } else{ + candles = i; + } + nearestLeftCandle[i] = candles; + starCount[i] = stars; + } + + candles = -1; + for(int i = n-1; i>= 0; i--){ + if(ch[i] == '|'){ + candles = i; + } + nearestRightCandle[i] = candles; + } + int m = queries.length; + int[] res = new int[m]; + + for(int i = 0; i< m; i++){ + int lw = nearestRightCandle[queries[i][0]]; + int rw = nearestLeftCandle[queries[i][1]]; + + if(lw == -1 || rw == -1 || lw >= rw){ + res[i] = 0; + continue; + } + + res[i] = starCount[rw] - starCount[lw]; + } + + return res; + } + public int[] platesBetweenCandlesWithTreeSet(String s, int[][] queries) { + int len = s.length(); + int[] plates = new int[len]; + + TreeSet candles = new TreeSet<>(); + + int plateCount = 0; + + //get the platecount and the indices of the candles + for (int i = 0; i < len; i++) { + if (s.charAt(i) == '|') { + candles.add(i); + plates[i] = plateCount; + } else { + plateCount++; + } + } + + //iterating through the queries + int[] result = new int[queries.length]; + int i = 0; + + for (int[] query : queries) { + Integer leftCandle = candles.ceiling(query[0]); + Integer rightCandle = candles.floor(query[1]); + + if (leftCandle != null && rightCandle != null && leftCandle < rightCandle) { + result[i] = plates[rightCandle] - plates[leftCandle]; + } + i++; + + } + + return result; + } +} diff --git a/src/main/java/practiceproblems/UniqueCharactersInSubStringII.java b/src/main/java/practiceproblems/UniqueCharactersInSubStringII.java new file mode 100644 index 0000000..77ae2cd --- /dev/null +++ b/src/main/java/practiceproblems/UniqueCharactersInSubStringII.java @@ -0,0 +1,55 @@ +package practiceproblems; + + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/total-appeal-of-a-string + */ +public class UniqueCharactersInSubStringII { + + + /** + * Consider string "bcde" + *

+ * 🎯 lets talk about character 'c' that in how many substrings this 'c' will be counted as unique string + * ::: left no of characters on L.H.S of 'c' = left + * ::: left no of characters on R.H.S of 'c' = right + * Then total possible substrings containing this 'c' = (left+1) x (right+1) + *

+ * Thus contributions for c = 2 * 3 = 6 + * and those 6 substrings are ( bc, bcd, bcde, c, cd, cde ) + *

+ * So we can say that every character will have contribution of (left+1)x(right+1) to the ans. + *

+ * 🎯 But there is one small catch here ! + * What if characters are same ?? then only one of those characters will have contribution in any substring containing them. + * "acca" + * Here first 'c' will for sure have a contribution = (left+1)x(right+1) = 2 x 3 = 6 + * but for second 'c' Left region will be reduced till the rightmost 'c' on leftside. So the value of left for second 'c' will be = 0 !! + * Right will have no change. + * So contribution for second 'c' = 1 x 2 = 2; + *

+ * This way we can calculate the contribution for each and every character in just one for loop. + */ + public long appealSum(String s) { + int l = s.length(); + int[] lo = new int[26]; //store the last occurrence index of every character + Arrays.fill(lo, -1); + long ans = 0; + for (int i = 0; i < l; i++) { + int cc = s.charAt(i) - 'a'; + int right = l - i - 1; + int left; + + int last = lo[cc]; + if (last == -1) left = i; + else + left = (i - last) - 1; // this is to ensure that contribution for duplicate char will skip from the prev last seen position + ans += (left + 1) * (right + 1); + lo[cc] = i; + } + return ans; + + } +} diff --git a/src/main/java/practiceproblems/design/MyCalendar.java b/src/main/java/practiceproblems/design/MyCalendar.java new file mode 100644 index 0000000..e818dc3 --- /dev/null +++ b/src/main/java/practiceproblems/design/MyCalendar.java @@ -0,0 +1,47 @@ +package practiceproblems.design; + +import java.util.TreeMap; + +public class MyCalendar { + TreeMap calendar; + + MyCalendar() { + calendar = new TreeMap(); + } + + /** + * floor ceiling + * ... |----| ... |----| ... + * |---------| + * s e + * if s < floor.end or e > ceiling.start, there is an overlap. + * + * Another way to think of it: + * If there is an interval start within the new book (must be the ceilingEntry) at all, or + * books: |----| |--| + * s |------| e + * + * books: |----| |----| + * s |----| e + * If the new book start within an interval (must be the floorEntry) at all + * books: |-------| |--| + * s |---| e + * + * books: |----| |----| + * s |----| e + * There is a overlap + * @param start + * @param end + * @return + */ + public boolean book(int start, int end) { + Integer prev = calendar.floorKey(start), + next = calendar.ceilingKey(start); + if ((prev == null || calendar.get(prev) <= start) && + (next == null || end <= next)) { + calendar.put(start, end); + return true; + } + return false; + } +} diff --git a/src/main/java/practiceproblems/design/UniqueCharactersInSubString.java b/src/main/java/practiceproblems/design/UniqueCharactersInSubString.java new file mode 100644 index 0000000..ef896a1 --- /dev/null +++ b/src/main/java/practiceproblems/design/UniqueCharactersInSubString.java @@ -0,0 +1,78 @@ +package practiceproblems.design; + +import java.util.*; + + +/** + * https://leetcode.com/problems/count-unique-characters-of-all-substrings-of-a-given-string/ + *

+ * https://www.youtube.com/watch?v=JT1NDR-M_8A&t=1212s + */ +public class UniqueCharactersInSubString { + + public int uniqueLetterString(String s) { + + Map> cache = new HashMap<>(); + + for (int i = 0; i < 26; i++) { + cache.putIfAbsent(i, new ArrayList<>()); + cache.get(i).add(-1); + } + + for (int i = 0; i < s.length(); i++) { + cache.get(s.charAt(i) - 'A').add(i); + } + + for (int i = 0; i < 26; i++) { + cache.get(i).add(s.length()); + } + + int result = 0; + for (int i = 0; i < 26; i++) { + for (int j = 1; j < cache.get(i).size() - 1; j++) { + result += (cache.get(i).get(j) - cache.get(i).get(j - 1)) * (cache.get(i).get(j + 1) - cache.get(i).get(j)); + } + } + + return result; + + } + + /** + * In the first for loop, we initialize the index array to -1 to indicate that none of the characters have occurred yet. + + * In the second for loop, we iterate over the input string "ABC". For each character, + * we calculate the contribution of all substrings that end with that character by using the last two occurrences of that character in the index array. + * For example, when we process "A" (at index 0), the last two occurrences of "A" are both -1, + * so the contribution of all substrings that end with "A" is (0 - (-1)) * ((-1) - (-1)) = 1. When we process "B" (at index 1), + * the last two occurrences of "B" are -1 and -1, so the contribution of all substrings that end with "B" is (1 - (-1)) * ((-1) - (-1)) = 0. + * When we process "C" (at index 2), the last two occurrences of "C" are both -1, so the contribution of all substrings that end with "C" is (2 - (-1)) * ((-1) - (-1)) = 0. + * The total contribution of all substrings is 1 + 0 + 0 = 1, so res is updated to 1. + + * In the third for loop, we calculate the contribution of all substrings that end with a character that has not occurred twice yet (i.e., all remaining characters in the index array). + * For example, for the character "D" (with index 3), the last two occurrences of "D" are both -1, so the contribution of all substrings that end with "D" is (3 - (-1)) * ((-1) - (-1)) = 0. + * We do this for all characters that have not occurred twice yet. + + * Finally, we return the result res, which is the sum of the contributions of all substrings that end with each character in the input string. For the input string "ABC", the result should be 10. + */ + public int uniqueLetterStringOptimised(String s) { + int n = s.length(); // Get the length of the input string, n = 3 for "ABC" + int res = 0; // Initialize the result variable, res = 0 + int[][] index = new int[26][2]; // Create a 2D array of size 26x2 to store the last two occurrences of each character + for (int i = 0; i < 26; i++) { + Arrays.fill(index[i], -1); // Initialize the array to -1 to indicate that the character has not occurred yet + } + for (int i = 0; i < n; i++) { + int c = s.charAt(i) - 'A'; // Get the index of the current character in the index array, c = 0 for "A", c = 1 for "B", c = 2 for "C" + res = (res + (i - index[c][1]) * (index[c][1] - index[c][0]) % 1000000007) % 1000000007; // Calculate the contribution of all substrings that end with the current character + index[c][0] = index[c][1]; // Update the last occurrence of the current character to be the second last occurrence + index[c][1] = i; // Update the last occurrence of the current character to be the current index + } + for (int i = 0; i < 26; i++) { + res = (res + (n - index[i][1]) * (index[i][1] - index[i][0]) % 1000000007) % 1000000007; // Calculate the contribution of all substrings that end with the current character + } + return res; // Return the result + } + + +} diff --git a/src/main/java/practiceproblems/prefixsum/MaxNegativeNumbers.java b/src/main/java/practiceproblems/prefixsum/MaxNegativeNumbers.java new file mode 100644 index 0000000..f83bf29 --- /dev/null +++ b/src/main/java/practiceproblems/prefixsum/MaxNegativeNumbers.java @@ -0,0 +1,42 @@ +package practiceproblems.prefixsum; + +import java.util.Collections; +import java.util.PriorityQueue; + +public class MaxNegativeNumbers { + + + /** + * We add each number to the priority queue and increment ans, assuming we can keep it negative. + * If the sum becomes non-positive, we need to make some numbers positive to keep the overall sum positive. + * We choose the largest available number (top of the priority queue) to make positive, as this allows us to keep more numbers negative overall. + * When we make a number positive, we add twice its value to the sum (reversing the initial subtraction and then adding it). + * We decrease ans each time we make a number positive. + * @param numbers + * @return + */ + public static int maxNegativeSigns(int[] numbers) { + int sum = 0; + PriorityQueue pq = new PriorityQueue<>(Collections.reverseOrder()); + int ans = 0; + + for (int val : numbers) { + sum -= val; + pq.offer(val); + ans++; + while (!pq.isEmpty() && sum <= 0) { + int top = pq.peek(); + sum += 2 * top; // make it positive by adding twice its value + pq.poll(); + ans--; + } + } + return ans; + + } + + public static void main(String[] args) { + System.out.println(maxNegativeSigns(new int[]{3, 2, 1, 1, 1,1})); + System.out.println(maxNegativeSigns(new int[]{1, 2, 3, 4, 5})); + } +} diff --git a/src/main/java/practiceproblems/prefixsum/SubstringEqualFragments.java b/src/main/java/practiceproblems/prefixsum/SubstringEqualFragments.java new file mode 100644 index 0000000..9ca9398 --- /dev/null +++ b/src/main/java/practiceproblems/prefixsum/SubstringEqualFragments.java @@ -0,0 +1,118 @@ +package practiceproblems.prefixsum; + + +import java.util.HashMap; +import java.util.Map; + +/** + * https://www.youtube.com/watch?v=9SS83X6Na6k + *

+ * Microsoft interview + *

+ * There are two strings, A and B, each of length N. + * A fragment of string A Corresponds with a fragment of string B if: both fragments start at the same position; + * letters from one fragment can be rearranged into the order of letters in the other fragment + * (note that the case and number of occurrences of the letter matters). + *

+ * Given A "dBacaAA" and B = "caBdaaA", the function should return 5. The corresponding fragments are: + * "dBaca" and "caBda" (starting at position 0) + * "dBac" and "caBd"(starting at position 0) + * ."Ba" and "aB" (starting at position 1) + * ."a" and "a" (starting at position 4) + * . "A" and "A" (at position 6). + *

+ * Given A = "zzzX" and B "zzzX",the function should return 10. total substrings = (n*(n+1))/2 + * All fragments starting at the same positions in both strings correspond. + */ +public class SubstringEqualFragments { + + public static int countFragmentsOptimised(String A, String B) { + int count = 0; + int strLength = A.length(); + Map letters = new HashMap<>(); + + + int noOfCharacterToBeChecked = 1; + int startIndex = 0; + while (noOfCharacterToBeChecked <= strLength) { + + int lastIndex = startIndex + noOfCharacterToBeChecked; + //First get the characters in HashMap for the noOfLtters to be checked + for (int i = startIndex; i < lastIndex; i++) { + letters.put(A.charAt(i), letters.getOrDefault(A.charAt(i), 0) + 1); + } + //compare the second string and increase count if matched + for (int i = startIndex; i < lastIndex; i++) { + if (letters.containsKey(B.charAt(i))) { + int letterCount = letters.getOrDefault(B.charAt(i), 0); + if (letterCount > 1) { + letters.put(B.charAt(i), letters.getOrDefault(B.charAt(i), 0) - 1); + } else { + letters.remove(B.charAt(i)); + } + } else { + break; + } + } + + if (letters.isEmpty()) { + count++; + } + letters.clear(); + //Check till last index + if (lastIndex < strLength) { + startIndex++; + } else { + //Once last index is reached increase noOfLetter to be checked and reset startIndex + noOfCharacterToBeChecked++; + startIndex = 0; + } + + } + return count; + } + + + public static int countFragmentsBruteForce(String a, String b) { + int[] cache1; + int[] cache2; + int ans = 0; + for (int i = 0; i < a.length(); i++) { + cache1 = new int[52]; + cache2 = new int[52]; + int totalCountOfParity = 52; // at first all the values in cache has same value i.e 0 + for (int j = i; j < a.length(); j++) { + int c1 = mapToInt(a.charAt(j)); + int c2 = mapToInt(b.charAt(j)); + + if (cache1[c1] == cache2[c1]) totalCountOfParity--; + + cache1[c1]++; + + if (cache1[c1] == cache2[c1]) totalCountOfParity++; + + if (cache1[c2] == cache2[c2]) totalCountOfParity--; + + cache2[c2]++; + + if (cache1[c2] == cache2[c2]) totalCountOfParity++; + + if (totalCountOfParity == 52) ans++; + } + } + return ans; + } + + public static int mapToInt(char ch) { + if (ch >= 'a' && ch <= 'z') return (ch - 'a'); + if (ch >= 'A' && ch <= 'Z') return (ch - 'A' + 26); + return -1; + } + + public static void main(String[] args) { + String s1 = "dBacaAA"; + String s2 = "caBdaaA"; + System.out.println(countFragmentsOptimised(s1, s2)); + } + +} diff --git a/src/main/java/practiceproblems/prefixsum/UniqueSubArrayDivisibleByK.java b/src/main/java/practiceproblems/prefixsum/UniqueSubArrayDivisibleByK.java new file mode 100644 index 0000000..fa845b5 --- /dev/null +++ b/src/main/java/practiceproblems/prefixsum/UniqueSubArrayDivisibleByK.java @@ -0,0 +1,43 @@ +package practiceproblems.prefixsum; + +import java.util.HashSet; +import java.util.Set; + +/** + * https://leetcode.com/problems/k-divisible-elements-subarrays/ + * + * It's tempting to apply a sliding window technique here, however, it won't help us identify distinct subarrays. + * + * Because constraints are low (n <= 200), we can just identify all valid subarrays O(n ^ 2), + * and use a set to dedup them O(n). So, the overall complexity would be O(n ^ 3). + * + * For O(n ^ 2) solution, we can use a rolling hash (Rabin-Karp). + * Note that we only need to check hashes for arrays of the same size, which reduces the collision probability. + * + * We can also use a Trie to achieve a quadratic complexity - check the second solution below. + * + * Rolling Hash (Simple) + * We need to do the collision check, but here I omitted it for simplicity (see third solution below if you want to handle collisions). + */ +public class UniqueSubArrayDivisibleByK { + + public int countDistinct(int[] nums, int k, int p) { + int n = nums.length; + // we are storing hashcode for all the substrings so that we can compare them faster. + // main goal is to avoid entire sub array comparision using hashcode. + Set ways = new HashSet<>(); + for(int i = 0; i < n; i++) { + int cnt = 0; + long hc = 1; // this is the running hashcode for sub array [i...j] + for(int j = i; j < n; j++) { + hc = 199L * hc + nums[j]; // updating running hashcode, since we nums are <=200, we shall consider a prime near 200 to avoid collision + if(nums[j] % p == 0) + cnt++; + if(cnt <= k) { // if current subarray [i...j] is valid, add its hashcode in our storage. + ways.add(hc); + } + } + } + return ways.size(); + } +} diff --git a/src/main/java/segmentTree/SegmentTree.java b/src/main/java/segmentTree/SegmentTree.java new file mode 100644 index 0000000..176e9e8 --- /dev/null +++ b/src/main/java/segmentTree/SegmentTree.java @@ -0,0 +1,141 @@ +package segmentTree; + +// https://leetcode.com/problems/range-sum-query-mutable/ +public class SegmentTree { + private int[] tree; + private int n; + + public SegmentTree(int[] nums) { + n = nums.length; + tree = new int[n * 2]; + buildTree(nums); + } + + /** + * Suppose we have the array nums = [1, 3, 5, 7, 9, 11]. + * + * First, we determine n = 6 (the length of nums). + * We create tree with size 2 * n = 12. + * + * After the first loop: + * Copytree = [0, 0, 0, 0, 0, 0, 1, 3, 5, 7, 9, 11] + * 0 1 2 3 4 5 6 7 8 9 10 11 (indices) + * + * Now, the second loop builds the rest of the tree: + * + * tree[5] = tree[10] + tree[11] = 9 + 11 = 20 + * tree[4] = tree[8] + tree[9] = 5 + 7 = 12 + * tree[3] = tree[6] + tree[7] = 1 + 3 = 4 + * tree[2] = tree[4] + tree[5] = 12 + 20 = 32 + * tree[1] = tree[2] + tree[3] = 32 + 4 = 36 + * + * After the second loop: + * Copytree = [0, 36, 32, 4, 12, 20, 1, 3, 5, 7, 9, 11] + * 0 1 2 3 4 5 6 7 8 9 10 11 (indices) + * + * since we are leaving zeroth index empty, + * the left and right nodes are calculated as 2*i and 2*i+1 else it would be 2*i+1 and 2*i+2 + * @param nums + */ + private void buildTree(int[] nums) { + //This copies the elements from nums into the second half of tree. Here, n is the size of the original array. + for (int i = n, j = 0; i < 2 * n; i++, j++) { + tree[i] = nums[j]; + } + //This builds the rest of the tree from the bottom up. Each non-leaf node is the sum of its two children. + for (int i = n - 1; i > 0; --i) { + tree[i] = tree[i * 2] + tree[i * 2 + 1]; + } + } + + /** + * array nums = [1, 3, 5, 7, 9, 11]. + * Initial tree: + * [0, 36, 32, 4, 12, 20, 1, 3, 5, 7, 9, 11] + * 0 1 2 3 4 5 6 7 8 9 10 11 (indices) + * + * Suppose we want to update index 2 (third element in the original array) to value 8. + * + * treeIndex = 2 + 6 = 8 (as n = 6) + * Update leaf: tree[8] = 8 + * Move up: + * treeIndex = 8 / 2 = 4 + * tree[4] = tree[8] + tree[9] = 8 + 7 = 15 + * + * Move up again: + * treeIndex = 4 / 2 = 2 + * tree[2] = tree[4] + tree[5] = 15 + 20 = 35 + * + * Final move: + * treeIndex = 2 / 2 = 1 + * tree[1] = tree[2] + tree[3] = 35 + 4 = 39 + * + * @param index + * @param newValue + */ + public void update(int index, int newValue) { + // Convert to tree index + int treeIndex = index + n; //We add n to the input index to convert it to the corresponding index in the tree array. + + // Update the leaf node + tree[treeIndex] = newValue; + + // Update parent nodes + while (treeIndex > 1) { + treeIndex = treeIndex / 2; // Move to parent + int leftChild = 2 * treeIndex; + int rightChild = 2 * treeIndex + 1; + tree[treeIndex] = tree[leftChild] + tree[rightChild]; + } + } + + /** + * array nums = [1, 3, 5, 7, 9, 11]. + * Initial tree: + * [0, 36, 32, 4, 12, 20, 1, 3, 5, 7, 9, 11] + * 0 1 2 3 4 5 6 7 8 9 10 11 (indices) + * + * Suppose we want to query the sum of the range [1, 4] (2nd to 5th elements in the original array). + * Initialize: i = 1 + 6 = 7, j = 4 + 6 = 10, sum = 0 + * + * First iteration: + * i (7) is odd: sum += tree[7] = 3, i = 8 + * j (10) is even: sum += tree[10] = 9, j = 9 + * i = 8 / 2 = 4, j = 9 / 2 = 4 + * + * Second iteration: + * i == j == 4, so we add tree[4] = 15 to sum + * i = 4 / 2 = 2, j = 4 / 2 = 2 + * Loop ends as i == j == 2 + * The final sum is 3 + 9 + 15 = 27, which is indeed the sum of [3, 5, 8, 7] in the original array. + * + * @param i + * @param j + * @return + */ + public int sumRange(int i, int j) { + // We add n to both i and j to convert them to tree indices. + i += n; + j += n; + + int sum = 0; + + while (i <= j) { + if (i % 2 == 1) { //If i is odd, it's a right child. We include it in the sum and move to its right sibling. + sum += tree[i]; + i++; // Move to the j sibling + } + if (j % 2 == 0) { //If j is even, it's a left child. We include it in the sum and move to its left sibling. + sum += tree[j]; + j--; // Move to the i sibling + } + // Move up to the parent level + i /= 2; + j /= 2; + } + + return sum; + } + + +} diff --git a/src/main/java/strings/stringProblems/ZigZag.java b/src/main/java/strings/stringProblems/ZigZag.java new file mode 100644 index 0000000..4ccea44 --- /dev/null +++ b/src/main/java/strings/stringProblems/ZigZag.java @@ -0,0 +1,35 @@ +package strings.stringProblems; + +import java.util.ArrayList; +import java.util.List; + +public class ZigZag { + + public String convert(String s, int numRows) { + if (numRows == 1 || s.length() <= numRows) { + return s; + } + + List grid = new ArrayList<>(numRows); + for (int i = 0; i < numRows; i++) { + grid.add(new StringBuilder()); + } + + int row = 0; + boolean goingDown = false; + + for (char c : s.toCharArray()) { + grid.get(row).append(c); + if (row == 0 || row == numRows - 1) { + goingDown = !goingDown; + } + row += goingDown ? 1 : -1; + } + + StringBuilder result = new StringBuilder(); + for (StringBuilder sb : grid) { + result.append(sb); + } + return result.toString(); + } +} From f10ee2eaf09480d9d6cbf3e5991620bf80b329f1 Mon Sep 17 00:00:00 2001 From: Vignesh Rajarajan Date: Mon, 26 Aug 2024 18:43:57 +0530 Subject: [PATCH 51/51] updating existing and adding new --- src/main/java/RandomProblemGenerator.java | 3 +- .../java/binarysearch/AggressiveCows.java | 67 ++++++ src/main/java/binarysearch/AssignBooks.java | 45 ++++ .../binarysearch/BinarySearchTemplate.java | 51 +++- src/main/java/binarysearch/BitonicSearch.java | 224 ++++++++++++++++++ .../FindMinimumInRotatedArray.java | 2 +- .../java/binarysearch/FindPeakElement.java | 27 --- .../binarysearch/FirstAndLastOccurence.java | 39 +++ .../java/binarysearch/KokoEatingBananas.java | 11 +- .../java/binarysearch/KthMissingPositive.java | 24 ++ .../KthSmallestFromTwoSortedArrays.java | 49 ++++ .../MagneticForceBetweenTwoBalls.java | 77 +++--- .../MaximumDistanceBetweenGasStation.java | 128 ++++++++++ .../binarysearch/MedianOfTwoSortedArrays.java | 137 +++++++++++ .../NumberOfDaysToMakeMBouquets.java | 4 +- .../SearchAnElementInMatrix.java | 25 +- .../binarysearch/ShipPackageWithNDays.java | 2 + .../SingleElementInSortedArray.java | 124 ++-------- .../java/binarysearch/SmallestDivisor.java | 33 +++ src/main/java/binarysearch/Sqrt.java | 20 +- .../leetcode}/CloneGraph.java | 4 +- .../java/practiceproblems/BitonicSearch.java | 103 -------- .../java/practiceproblems/BuildArray.java | 52 ++-- .../java/practiceproblems/CanPlaceFlower.java | 3 +- .../java/practiceproblems/ClosestNumbers.java | 45 ---- .../CompleteBinaryTreeInserter.java | 59 ----- .../ComplexNumberMultiply.java | 6 + .../ConstructTreeFromInorderAndPostorder.java | 70 ------ .../CountAllPathsFrom2DMatrix.java | 2 +- .../practiceproblems/CountBinaryStrings.java | 21 ++ .../java/practiceproblems/CountElements.java | 11 +- .../practiceproblems/DutchNationalFlag.java | 40 ++-- .../InorderSuccessorPredecessor.java | 143 ----------- .../KthSmallestFromTwoSortedArrays.java | 47 ---- .../practiceproblems/MatrixRowWithMax1.java | 61 ++--- .../MaximumProductSubarray.java | 124 +++++----- .../MedianOfTwoSortedArrays.java | 118 --------- .../practiceproblems/NextGreaterNumber.java | 77 ------ .../practiceproblems/NextPermutation.java | 77 +++--- .../practiceproblems/RotateMatrixInPlace.java | 62 +---- .../SerializeDeserializeBST.java | 60 ----- .../practiceproblems/SetZeroesMatrix.java | 24 +- .../java/practiceproblems/SpiralMatrix.java | 215 ++++++++++++++--- .../java/practiceproblems/SpiralMatrixII.java | 56 ----- .../intervals/MergeIntervals.java | 22 +- .../intervals/OverlappingIntervals.java | 30 ++- .../mergesort/CountingInversion.java | 29 ++- .../mergesort}/MergeSort.java | 20 +- .../mergesort/ReversePairs.java | 69 ++---- .../prefixsum/UniqueSubArrayDivisibleByK.java | 24 +- .../practiceproblems/stack/AtomCounts.java | 59 +++++ .../{ => stack}/BasicCalculator.java | 38 ++- src/main/java/sorting/QuickSort.java | 3 +- .../parentheses/BalancedSmiley.java | 2 +- .../parentheses/CanBeValid.java | 7 +- .../DifferentWaysToAddParenthesis.java | 2 +- .../parentheses/GenerateParenthesis.java | 2 +- .../parentheses/LongestValidParentheses.java | 2 +- .../parentheses/MinSwapsToBalance.java | 2 +- .../parentheses/RemoveInvalidParentheses.java | 2 +- .../parentheses/RemoveOuterParentheses.java | 31 +++ .../parentheses/ScoreOfParentheses.java | 2 +- .../parentheses/ValidParentheses.java | 2 +- .../parentheses/ValidParenthesesString.java | 2 +- src/main/java/trees/BST/BSTIterator.java | 33 +++ src/main/java/trees/BST/CeilAndFloor.java | 110 +++++++++ .../BST}/ConstructBSTFromPreorder.java | 11 +- src/main/java/trees/{ => BST}/DeleteBST.java | 14 +- .../{ => BST}/GenerateAllPossibleBST.java | 4 +- .../BST/InorderSuccessorPredecessor.java | 59 +++++ src/main/java/trees/BST/InsertBST.java | 57 +++++ src/main/java/trees/{ => BST}/IsValidBST.java | 16 +- .../java/trees/BST/KthSmallestOrLargest.java | 46 ++++ src/main/java/trees/BST/LargestBST.java | 105 ++++++++ src/main/java/trees/BST/Search.java | 23 ++ .../trees/BST/SerializeDeserializeBST.java | 60 +++++ .../trees/{ => BST}/SortedArrayToBST.java | 2 +- src/main/java/trees/BST/SwapRecoverBST.java | 56 +++++ src/main/java/trees/{ => BST}/TwoSumTree.java | 6 +- src/main/java/trees/BoundaryTraversal.java | 66 ++++++ .../trees/CompleteBinaryTreeInserter.java | 47 ++++ .../ConstructTreeFromInorderAndPostorder.java | 111 +++++++++ .../ConstructTreeFromInorderAndPreorder.java | 28 ++- .../java/trees/CountCompleteTreeNodes.java | 43 ++++ src/main/java/trees/DepthOfTree.java | 5 +- src/main/java/trees/DiameterTree.java | 27 ++- src/main/java/trees/InsertBST.java | 35 --- src/main/java/trees/IsHeightBalanced.java | 26 ++ src/main/java/trees/LargestBST.java | 68 ------ src/main/java/trees/LongestUniValuePath.java | 27 +++ src/main/java/trees/LowestCommonAncestor.java | 28 ++- src/main/java/trees/MaxPathSum.java | 49 +++- src/main/java/trees/MaxWidthOfBinaryTree.java | 72 ++++-- src/main/java/trees/MorrisTraversal.java | 104 ++++++++ .../java/trees/MorrisTraversalTreeToDLL.java | 62 +++++ src/main/java/trees/NodesAtDistanceK.java | 3 + src/main/java/trees/RootToLeafPaths.java | 44 ++-- .../SerializeAndDeserialize.java | 14 +- src/main/java/trees/SwapRecoverBST.java | 56 ----- src/main/java/trees/TreeToDLL.java | 65 ----- src/main/java/trees/TreeTraversals.java | 160 ++++++++----- src/main/java/trees/Zigzag.java | 36 +++ 102 files changed, 2955 insertions(+), 1745 deletions(-) create mode 100644 src/main/java/binarysearch/AggressiveCows.java create mode 100644 src/main/java/binarysearch/AssignBooks.java create mode 100644 src/main/java/binarysearch/BitonicSearch.java delete mode 100644 src/main/java/binarysearch/FindPeakElement.java create mode 100644 src/main/java/binarysearch/KthMissingPositive.java create mode 100644 src/main/java/binarysearch/KthSmallestFromTwoSortedArrays.java create mode 100644 src/main/java/binarysearch/MaximumDistanceBetweenGasStation.java create mode 100644 src/main/java/binarysearch/MedianOfTwoSortedArrays.java rename src/main/java/{practiceproblems => binarysearch}/SearchAnElementInMatrix.java (65%) create mode 100644 src/main/java/binarysearch/SmallestDivisor.java rename src/main/java/{practiceproblems => graph/leetcode}/CloneGraph.java (95%) delete mode 100644 src/main/java/practiceproblems/BitonicSearch.java delete mode 100644 src/main/java/practiceproblems/ClosestNumbers.java delete mode 100644 src/main/java/practiceproblems/CompleteBinaryTreeInserter.java delete mode 100644 src/main/java/practiceproblems/ConstructTreeFromInorderAndPostorder.java delete mode 100644 src/main/java/practiceproblems/InorderSuccessorPredecessor.java delete mode 100644 src/main/java/practiceproblems/KthSmallestFromTwoSortedArrays.java delete mode 100644 src/main/java/practiceproblems/MedianOfTwoSortedArrays.java delete mode 100644 src/main/java/practiceproblems/NextGreaterNumber.java delete mode 100644 src/main/java/practiceproblems/SerializeDeserializeBST.java delete mode 100644 src/main/java/practiceproblems/SpiralMatrixII.java rename src/main/java/{sorting => practiceproblems/mergesort}/MergeSort.java (58%) create mode 100644 src/main/java/practiceproblems/stack/AtomCounts.java rename src/main/java/practiceproblems/{ => stack}/BasicCalculator.java (66%) rename src/main/java/{practiceproblems => strings}/parentheses/BalancedSmiley.java (98%) rename src/main/java/{practiceproblems => strings}/parentheses/CanBeValid.java (97%) rename src/main/java/{practiceproblems => strings}/parentheses/DifferentWaysToAddParenthesis.java (98%) rename src/main/java/{practiceproblems => strings}/parentheses/GenerateParenthesis.java (97%) rename src/main/java/{practiceproblems => strings}/parentheses/LongestValidParentheses.java (96%) rename src/main/java/{practiceproblems => strings}/parentheses/MinSwapsToBalance.java (98%) rename src/main/java/{practiceproblems => strings}/parentheses/RemoveInvalidParentheses.java (98%) create mode 100644 src/main/java/strings/parentheses/RemoveOuterParentheses.java rename src/main/java/{practiceproblems => strings}/parentheses/ScoreOfParentheses.java (97%) rename src/main/java/{practiceproblems => strings}/parentheses/ValidParentheses.java (94%) rename src/main/java/{practiceproblems => strings}/parentheses/ValidParenthesesString.java (98%) create mode 100644 src/main/java/trees/BST/BSTIterator.java create mode 100644 src/main/java/trees/BST/CeilAndFloor.java rename src/main/java/{practiceproblems => trees/BST}/ConstructBSTFromPreorder.java (82%) rename src/main/java/trees/{ => BST}/DeleteBST.java (66%) rename src/main/java/trees/{ => BST}/GenerateAllPossibleBST.java (98%) create mode 100644 src/main/java/trees/BST/InorderSuccessorPredecessor.java create mode 100644 src/main/java/trees/BST/InsertBST.java rename src/main/java/trees/{ => BST}/IsValidBST.java (52%) create mode 100644 src/main/java/trees/BST/KthSmallestOrLargest.java create mode 100644 src/main/java/trees/BST/LargestBST.java create mode 100644 src/main/java/trees/BST/Search.java create mode 100644 src/main/java/trees/BST/SerializeDeserializeBST.java rename src/main/java/trees/{ => BST}/SortedArrayToBST.java (97%) create mode 100644 src/main/java/trees/BST/SwapRecoverBST.java rename src/main/java/trees/{ => BST}/TwoSumTree.java (95%) create mode 100644 src/main/java/trees/BoundaryTraversal.java create mode 100644 src/main/java/trees/CompleteBinaryTreeInserter.java create mode 100644 src/main/java/trees/ConstructTreeFromInorderAndPostorder.java rename src/main/java/{practiceproblems => trees}/ConstructTreeFromInorderAndPreorder.java (67%) create mode 100644 src/main/java/trees/CountCompleteTreeNodes.java delete mode 100644 src/main/java/trees/InsertBST.java create mode 100644 src/main/java/trees/IsHeightBalanced.java delete mode 100644 src/main/java/trees/LargestBST.java create mode 100644 src/main/java/trees/LongestUniValuePath.java create mode 100644 src/main/java/trees/MorrisTraversal.java create mode 100644 src/main/java/trees/MorrisTraversalTreeToDLL.java rename src/main/java/{practiceproblems => trees}/SerializeAndDeserialize.java (86%) delete mode 100644 src/main/java/trees/SwapRecoverBST.java delete mode 100644 src/main/java/trees/TreeToDLL.java create mode 100644 src/main/java/trees/Zigzag.java diff --git a/src/main/java/RandomProblemGenerator.java b/src/main/java/RandomProblemGenerator.java index 86d9279..69074d5 100644 --- a/src/main/java/RandomProblemGenerator.java +++ b/src/main/java/RandomProblemGenerator.java @@ -21,6 +21,7 @@ public static void main(String[] args) throws IOException { file.getPath().contains("internals"))) .filter(file -> file.getName().contains(".java")) .collect(Collectors.toList()); + int rand= (new Random().nextInt(filesInFolder.size())); System.out.println(rand+" "+filesInFolder.get(rand).getName()); try (BufferedReader reader = @@ -28,7 +29,7 @@ public static void main(String[] args) throws IOException { reader.lines().filter(e->e.contains("http") || e.contains("https")).forEach(System.out::println); } - System.out.println(filesInFolder.size()); + System.out.println("Total files: "+filesInFolder.size()); } } diff --git a/src/main/java/binarysearch/AggressiveCows.java b/src/main/java/binarysearch/AggressiveCows.java new file mode 100644 index 0000000..f3ed02f --- /dev/null +++ b/src/main/java/binarysearch/AggressiveCows.java @@ -0,0 +1,67 @@ +package binarysearch; + +// https://takeuforward.org/data-structure/aggressive-cows-detailed-solution/ + +import java.util.Arrays; + +/** + * Example 1: + * Input Format: + * N = 6, k = 4, arr[] = {0,3,4,7,10,9} + * Result: + * 3 + * Explanation: + * The maximum possible minimum distance between any two cows will be 3 when 4 cows are placed at positions {0, 3, 7, 10}. + * Here the distances between cows are 3, 4, and 3 respectively. + * We cannot make the minimum distance greater than 3 in any ways. + */ +public class AggressiveCows { + + public int aggressiveCows(int[] stalls, int cows){ + //To arrange the cows in a consecutive manner while ensuring a certain distance between them, + // the initial step is to sort the stalls based on their positions. + // In a sorted array, the minimum distance will always be obtained from any two consecutive cows + Arrays.sort(stalls); + //The minimum possible distance between two cows is 1 as the minimum distance between 2 consecutive stalls is 1. + //The maximum possible distance between two cows is = max(stalls[])-min(stalls[]). This case occurs when we place 2 cows at two ends of the sorted stalls array. + int right = stalls[stalls.length-1] - stalls[0]; + int left=1; + + while(left= distance){ + count++; + lastPosition = stalls[j]; + } + } + + return count >= cows; + } +} diff --git a/src/main/java/binarysearch/AssignBooks.java b/src/main/java/binarysearch/AssignBooks.java new file mode 100644 index 0000000..643b4d4 --- /dev/null +++ b/src/main/java/binarysearch/AssignBooks.java @@ -0,0 +1,45 @@ +package binarysearch; + +import java.util.Arrays; + +// https://leetcode.com/problems/split-array-largest-sum/ +//https://takeuforward.org/data-structure/allocate-minimum-number-of-pages/ +public class AssignBooks { + + private static int getPieces(int[] nums, int mid) { + int sum = 0; // Current sum of the subarray + int pieces = 1; // At least one subarray is needed + + for (int num : nums) { + if (sum + num > mid) { // If adding num to current sum exceeds mid + sum = num; // Start a new subarray + pieces++; // Increase the count of subarrays + } else { + sum += num; // Continue adding to the current subarray + } + } + return pieces; + } + + public int splitArray(int[] nums, int k) { + // Initial boundary values for binary search + int start = Arrays.stream(nums).max().orElse(0); // The minimum possible largest sum is the max element in the array + int end = Arrays.stream(nums).sum(); // The maximum possible largest sum is the sum of all elements in the array + + // Binary search for the minimum possible largest sum + while (start < end) { + int mid = start + (end - start) / 2; // Middle value between start and end + int pieces = getPieces(nums, mid); + + // If more subarrays are needed than allowed, increase the lower bound + if (pieces > k) { + start = mid + 1; // Increase the lower bound since mid is too small + } else { + end = mid; // Decrease the upper bound since mid could be the answer + } + } + + // When start == end, we've found the minimum possible largest sum + return start; // or return end; since start == end + } +} diff --git a/src/main/java/binarysearch/BinarySearchTemplate.java b/src/main/java/binarysearch/BinarySearchTemplate.java index 72400e7..98f37bd 100644 --- a/src/main/java/binarysearch/BinarySearchTemplate.java +++ b/src/main/java/binarysearch/BinarySearchTemplate.java @@ -1,19 +1,48 @@ package binarysearch; public class BinarySearchTemplate { + /** - public T template(int n) { + * while (left < right): + * This condition is typically used when you want to find the insertion point or a specific boundary in a sorted array. + * It's often used when you're not necessarily looking for an exact match, + * but rather a position where an element should be inserted to maintain the sorted order. + * while (left <= right): + * This condition is used when you're searching for a specific element in the array + * and want to return its index if found. + * It allows the search to continue until the pointers cross each other, ensuring that every element is checked. - int left= min_val; - int right= max_val; + * The key differences are: + * + * Termination condition: + * + * left < right will terminate when left == right + * left <= right will terminate when left > right + * + * Final state: + * + * With left < right, left will be the insertion point or boundary you're looking for + * With left <= right, you need to check if the element was found after the loop ends + * + * Use case: + * + * left < right is often used for problems like finding the first/last occurrence of an element, or finding an insertion point + * left <= right is typically used when you're searching for a specific element and want to return its index + * + */ - while(left T template(int n) { +// +// int left= min_val; +// int right= max_val; +// +// while(left... + * + * @param arr + * @return + */ + public boolean validMountainArray(int[] arr) { + int left = 0; + int right = arr.length; + int peak = -1; + while (left <= right) { + int mid = left + (right - left) / 2; + System.out.println("mid: " + mid); + if (mid > 0 && arr[mid] > arr[mid - 1] && mid < arr.length - 1 && arr[mid + 1] < arr[mid]) { + peak = mid; + break; + } + + if (mid < arr.length - 1 && arr[mid] < arr[mid + 1]) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + if (peak == -1) + return false; + for (int i = 0; i < peak; i++) { + if (arr[i] >= arr[i + 1]) + return false; + } + // peak to n - 1 + for (int i = peak; i < arr.length - 1; i++) { + if (arr[i] <= arr[i + 1]) + return false; + } + return true; + } + + //https://leetcode.com/problems/find-peak-element + public int findPeakElement(int[] nums) { + //if(nums.length) + int left = 0; + int right = nums.length - 1; + + while (left <= right) { + int mid = (left + right) / 2; + if ((mid == 0 || nums[mid - 1] < nums[mid]) && (mid == nums.length - 1 || nums[mid + 1] < nums[mid])) { + return mid; + } else if (mid == 0 || nums[mid - 1] < nums[mid] && nums[mid + 1] > nums[mid]) { + left = mid + 1; + } else { + right = mid - 1; + } + } + return -1; + } + + //https://leetcode.com/problems/peak-index-in-a-mountain-array/description/ + public int peakIndexInMountainArray(int[] arr) { + + int left = 0; + int right = arr.length - 1; + + while (left <= right) { + int mid = left + (right - left) / 2; + if (arr[mid] > arr[mid - 1] && (arr[mid] > arr[mid + 1] || mid == arr.length - 1)) { + return mid; + } + if (arr[mid] > arr[mid - 1]) { + left = mid + 1; + } else { + right = mid; + } + } + + return -1; + } + + //https://leetcode.com/problems/find-in-mountain-array/ + public int findInMountainArray(int target, MountainArray mountainArr) { + int left = 0; + int n = mountainArr.length(); + int right = n - 1; + int peak = 0; + int mid = 0; + while (left < right) { + mid = (left + right) / 2; + if (mountainArr.get(mid) < mountainArr.get(mid + 1)) { + left = mid + 1; + + } else { + right = mid; + } + } + peak = left; + left = 0; + right = peak; + + while (left <= right) { + mid = (left + right) / 2; + if (mountainArr.get(mid) < target) { + left = mid + 1; + } else if (mountainArr.get(mid) > target) { + right = mid - 1; + } else { + return mid; + } + } + + left = peak; + right = n - 1; + + while (left <= right) { + mid = (left + right) / 2; + if (mountainArr.get(mid) > target) { + left = mid + 1; + } else if (mountainArr.get(mid) < target) { + right = mid - 1; + } else { + return mid; + } + } + + return -1; + + } + + //https://leetcode.com/problems/longest-mountain-in-array + // O(N) solution is fine for this constraint + public int longestMountain(int[] A) { + if (A == null || A.length < 3) + return 0; + int ans = 0; + for (int i = 1; i < A.length - 1; i++) { + if (A[i] > A[i - 1] && A[i] > A[i + 1]) { // i is a peak + int left = i - 1; // find leftmost of the peak + while (left > 0 && A[left - 1] < A[left]) + left--; + + int right = i + 1; // find rightmost of the peak + while (right < A.length - 1 && A[right + 1] < A[right]) + right++; + + ans = Math.max(ans, right - left + 1); // get the width using left and rightmost + + } + } + return ans; + } + + //https://leetcode.com/problems/find-peak-element-ii/ + // https://youtu.be/nGGp5XBzC4g + public int[] findPeakGrid(int[][] mat) { + + int left = 0; + int right = mat[0].length; + int m = mat.length; + //In this scenario, we'll employ binary search within the columns of the matrix. + // Since the peak element is guaranteed to exist in one of the columns, + // our search range will span from 0 to M, where M represents the total number of columns. + int n = mat[0].length; + while (left <= right) { + int mid = (left + right) / 2; + //Find the largest element in the ‘mid’ column: We will use the function findMaxIndex() + // to find the largest element of the mid-th column and the function will return the row number + int maxRow = getMaxElementRow(mat, mid); + + int prev = mid - 1 >= 0 ? mat[maxRow][mid - 1] : -1; + int next = mid + 1 < n ? mat[maxRow][mid + 1] : -1; + + //If matrix[maxRowIndex][mid] > matrix[maxRowIndex][mid-1] && matrix[maxRowIndex][mid] > matrix[maxRowIndex][mid+1]: + // This means matrix[maxRowIndex][mid] is the peak element. So, we will return its location + if (mat[maxRow][mid] > prev && mat[maxRow][mid] > next) { + return new int[]{maxRow, mid}; + } + //For example, if matrix[i][j-1] is greater than the chosen largest element matrix[i][j], + // we can conclude that matrix[i][j-1] is also greater than all the elements of the j-th column. + // This is because matrix[i][j] is the largest element of j-th column. + // Thus matrix[i][j-1] is now more likely to be the peak element. + // The logic is also applied to matrix[i][j+1]. This is how the elimination is working. + if (mat[maxRow][mid] < next) { + + left = mid + 1; + } else { + //If matrix[maxRowIndex][mid] < matrix[maxRowIndex][mid-1]: As we are in the right half of the peak element, + // we have to eliminate this right half (i.e. high = mid-1). Because our peak element appears somewhere on the left side. + right = mid - 1; + } + } + + return new int[]{-1, -1}; + + } + + public int getMaxElementRow(int[][] mat, int col) { + + int rowNum = -1; + int maxElem = Integer.MIN_VALUE; + for (int i = 0; i < mat.length; i++) { + //Although every element of the selected column might be a peak element, + // the largest number has always the highest possibility of being one. + // That is why, to reduce the checking operation, we are selecting the largest number. + if (mat[i][col] > maxElem) { + maxElem = mat[i][col]; + rowNum = i; + } + } + + return rowNum; + } +} \ No newline at end of file diff --git a/src/main/java/binarysearch/FindMinimumInRotatedArray.java b/src/main/java/binarysearch/FindMinimumInRotatedArray.java index 481f74a..eb8f598 100644 --- a/src/main/java/binarysearch/FindMinimumInRotatedArray.java +++ b/src/main/java/binarysearch/FindMinimumInRotatedArray.java @@ -37,7 +37,7 @@ public int findMinWithDuplicate(int[] nums) { while (start < end) { if (nums[start] == nums[end]) { - start++; // we need to find the imbalance in the array to start the alg. + start++; // conservative approach that ensures we don't accidentally skip over the minimum element. } else { int mid = start + (end - start) / 2; if (nums[mid] > nums[end]) { diff --git a/src/main/java/binarysearch/FindPeakElement.java b/src/main/java/binarysearch/FindPeakElement.java deleted file mode 100644 index 0ef027d..0000000 --- a/src/main/java/binarysearch/FindPeakElement.java +++ /dev/null @@ -1,27 +0,0 @@ -package binarysearch; - -/** - * https://leetcode.com/problems/find-peak-element/ - */ -public class FindPeakElement { - public int findPeakElement(int[] nums) { - int left = 0; - int right = nums.length - 1; - - while (left <= right) { - int mid = (left + right) / 2; - // if the mid element is the peak - if ((mid == 0 || nums[mid - 1] < nums[mid]) && (mid == nums.length - 1 || nums[mid + 1] < nums[mid])) { - return mid; - } - // if the mid element is in middle of increasing sub-arr we move towards the peak of increasing sub-arr - // mid==0 is for edge case [1,2] - else if (mid == 0 || nums[mid - 1] < nums[mid] && nums[mid + 1] > nums[mid]) { - left = mid + 1; - } else { // else we move back - right = mid - 1; - } - } - return -1; - } -} diff --git a/src/main/java/binarysearch/FirstAndLastOccurence.java b/src/main/java/binarysearch/FirstAndLastOccurence.java index 3a04a56..1529edf 100644 --- a/src/main/java/binarysearch/FirstAndLastOccurence.java +++ b/src/main/java/binarysearch/FirstAndLastOccurence.java @@ -39,4 +39,43 @@ public int binarySearch(int[] nums, int target) { return left; } + public int[] searchRangeII(int[] nums, int target) { + int low = 0; + int high = nums.length - 1; + int[] ans = {-1 , -1}; + + if(nums.length < 1){ + return ans; + } + while(low <= high){ //Binary search for 1st occurrence + int mid = (low + high)/2; + if(target == nums[mid]){ + ans[0] = mid; + high = mid -1; //searching on the left half + } + else if(target > nums[mid]){ + low = mid + 1; + } + else{ + high = mid - 1; + } + } + + low = 0; //Binary search for 2nd occurrence + high = nums.length - 1; + while(low <= high){ + int mid = (low + high)/2; + if(target == nums[mid]){ + ans[1] = mid; + low = mid + 1; //searching on the right half + } + else if(target > nums[mid]){ + low = mid + 1; + } + else{ + high = mid - 1; + } + } + return ans; + } } \ No newline at end of file diff --git a/src/main/java/binarysearch/KokoEatingBananas.java b/src/main/java/binarysearch/KokoEatingBananas.java index 6b121af..9066645 100644 --- a/src/main/java/binarysearch/KokoEatingBananas.java +++ b/src/main/java/binarysearch/KokoEatingBananas.java @@ -30,15 +30,12 @@ public int minEatingSpeed(int[] piles, int h) { } public boolean isFeasible(int[] piles, int mid, int h) { - int hour = 0; + int time = 0; - for (int pile : piles) { - hour += pile / mid; - if (pile % mid != 0) { - hour++; - } + for (int p : piles) { + time += (int) Math.ceil((double) (p) / (double) (mid)); } - return hour <= h; + return time <= h; } } diff --git a/src/main/java/binarysearch/KthMissingPositive.java b/src/main/java/binarysearch/KthMissingPositive.java new file mode 100644 index 0000000..5359c0c --- /dev/null +++ b/src/main/java/binarysearch/KthMissingPositive.java @@ -0,0 +1,24 @@ +package binarysearch; + +public class KthMissingPositive { + + public int findKthPositive(int[] arr, int k) { + int left = 0; + int right = arr.length; //Initialize right to arr.length instead of arr.length - 1. + // This allows the search to consider the position just after the array's end. + //[1,2,3,4], k = 2, the answer is 6, not 5. + + while (left < right) { + int mid = left + (right - left) / 2; + + int diff = arr[mid] - (mid + 1); + if (diff < k) { + left = mid + 1; + } else { + right = mid; + } + } + + return left + k; + } +} diff --git a/src/main/java/binarysearch/KthSmallestFromTwoSortedArrays.java b/src/main/java/binarysearch/KthSmallestFromTwoSortedArrays.java new file mode 100644 index 0000000..0d76e4c --- /dev/null +++ b/src/main/java/binarysearch/KthSmallestFromTwoSortedArrays.java @@ -0,0 +1,49 @@ +package binarysearch; + +/** + * this is same as median for 2 sorted arrays, with little bit modification + * + */ +class KthSmallestFromTwoSortedArrays { + + + public double findKthSmallestFromSortedArrays(int[] input1, int[] input2, int k) { + //if input1 length is greater than switch them so that input1 is smaller than input2. + // the reason is to do binary search on smaller array to reduce time complexity + if (input1.length > input2.length) { + return findKthSmallestFromSortedArrays(input2, input1,k); + } + int x = input1.length; + int y = input2.length; + int n = x + y; + + int low = 0; + int high = x; + while (low <= high) { + int mid1 = (low + high) / 2; + int mid2 = k - mid1; + + int left1 = (mid1 == 0) ? Integer.MIN_VALUE : input1[mid1 - 1]; + int right1 = (mid1 == x) ? Integer.MAX_VALUE : input1[mid1]; + int left2 = (mid2 == 0) ? Integer.MIN_VALUE : input2[mid2 - 1]; + int right2 = (mid2 == y) ? Integer.MAX_VALUE : input2[mid2]; + + if (left1 <= right2 && left2 <= right1) { + return Math.max(left1, left2); + } else if (left1 > right2) { + //If l1 > r2: This implies that we have considered more elements from arr1[] than necessary. + // So, we have to take less elements from arr1[] and more from arr2[]. + // In such a scenario, we should try smaller values of x. + // To achieve this, we will eliminate the right half (high = mid-1). + high = mid1 - 1; + } + //This implies that we have considered more elements from arr2[] than necessary. + // So, we have to take less elements from arr2[] and more from arr1[]. + // In such a scenario, we should try bigger values of x. + // To achieve this, we will eliminate the left half (low = mid+1). + else low = mid1 + 1; + + } + return -1.0; + } +} diff --git a/src/main/java/binarysearch/MagneticForceBetweenTwoBalls.java b/src/main/java/binarysearch/MagneticForceBetweenTwoBalls.java index 6d0f993..c31d1c3 100644 --- a/src/main/java/binarysearch/MagneticForceBetweenTwoBalls.java +++ b/src/main/java/binarysearch/MagneticForceBetweenTwoBalls.java @@ -4,62 +4,49 @@ /** * https://leetcode.com/problems/magnetic-force-between-two-balls/ - * - * Revise + *

+ * same as aggressive cows */ public class MagneticForceBetweenTwoBalls { - /** - * - First, might as well consider the placements in sorted order. - * - We only really need to check the forces of balls immediately to their left and right. - * - Say our target is D. We want all balls to be at least D units apart. - * - We can check if D is doable, by trying a greedy approach. Put the very - * first ball at the first available position, place the next ball at the - * first position rightwards that is sufficiently distant, etc. - *

- * - We can do a binary search for what minimum distance is achievable. - * - With this we have an O(n*log(L/m)) solution. Where L is the largest distance between - * baskets, and m is the number of balls we're trying to place, n is number of possible positions. - */ + + public static void main(String[] args) { + new MagneticForceBetweenTwoBalls().maxDistance(new int[]{1, 2, 3, 4, 7}, 3); + } + + /*minimum magnetic force between any two balls is maximum means + ex: 1 2 3 4 7 + . . . min magnetic force is 1 min is 1 + . . . min magnetic force is 2 min is 1 + . . . min magnetic force is 3 * + we should maximise the minimum magnetic force + minimum magnetic must come 1 from all cases and if we have maximise it then it will come as 3 3 6 + */ public int maxDistance(int[] position, int m) { int n = position.length; Arrays.sort(position); - int left = 0, right = position[n - 1] - position[0]; - while (left < right) { - int mid = right - (right - left) / 2; - if (check( position,mid, m)) - left = mid+1; + int left = 1, right = position[n - 1] - position[0]; + while (left <= right) { + int mid = left + (right - left) / 2; + if (check(position, mid, m)) + left = mid + 1; else - right = mid; + right = mid - 1; } - return left; + //When the binary search ends, right will be the largest distance that satisfies the condition, + // and left will be one more than this value. + return right; } - /** - * Define function count(d) that counts the number of balls can be placed in to baskets, - * under the condition that the minimum distance between any two balls is d. - */ - private boolean check(int[] position, int minimumDistance, int m) { - // Always place first object at position[0] - int lastBallPosition = position[0]; - int ballsLeftToBePlaced = m - 1; // we have placed first ball at 0 position - for (int i = 1; i < position.length && ballsLeftToBePlaced != 0; ) { - /** if minDistance between last position and position at idx is greater than or equal to minDistance - * then place the ball else skip - * */ - if (position[i] - lastBallPosition < minimumDistance) { - // Try to place the next ball, since this ball isn't minimumDistance away from lastBall - i++; - } else { - // Place the ball only if this ball is farther than the previous ball by minimumDistance - lastBallPosition = position[i]; - ballsLeftToBePlaced--; + private boolean check(int[] arr, int mid, int m) { + int count = 1, last = arr[0]; + for (int i = 1; i < arr.length; i++) { + if (arr[i] - last >= mid) { + count++; + last = arr[i]; + if (count >= m) return true; } } - return ballsLeftToBePlaced == 0; /*if all balls have been placed then return true else false*/ - } - - public static void main(String[] args) { - new MagneticForceBetweenTwoBalls().maxDistance(new int[]{1, 2, 3, 4, 7}, 3); + return false; } } diff --git a/src/main/java/binarysearch/MaximumDistanceBetweenGasStation.java b/src/main/java/binarysearch/MaximumDistanceBetweenGasStation.java new file mode 100644 index 0000000..8ae0098 --- /dev/null +++ b/src/main/java/binarysearch/MaximumDistanceBetweenGasStation.java @@ -0,0 +1,128 @@ +package binarysearch; + +// https://leetcode.com/problems/minimize-max-distance-to-gas-station +// https://takeuforward.org/arrays/minimise-maximum-distance-between-gas-stations/ +// extreme tricky hard problem + +/** + * You are given a sorted array ‘arr’ of length ‘n’, which contains positive integer positions of ‘n’ gas stations on the X-axis. + * You are also given an integer ‘k’. You have to place 'k' new gas stations on the X-axis. + * You can place them anywhere on the non-negative side of the X-axis, even on non-integer positions. + * Let 'dist' be the maximum value of the distance between adjacent gas stations after adding k new gas stations. + * Find the minimum value of ‘dist’. + *

+ * Input Format: + * N = 5, arr[] = {1,2,3,4,5}, k = 4 + * Result: + * 0.5 + * Explanation: + * One of the possible ways to place 4 gas stations is {1,1.5,2,2.5,3,3.5,4,4.5,5}. + * Thus the maximum difference between adjacent gas stations is 0.5. + * Hence, the value of ‘dist’ is 0.5. It can be shown that there is no possible way to add 4 gas stations in such a way that the value of ‘dist’ is lower than this. + */ +public class MaximumDistanceBetweenGasStation { + + public double minimiseMaxDistanceBruteForce(int[] stations, int k) { + int n = stations.length; + int[] howManyLeft = new int[n - 1]; + + for (int gasStations = 1; gasStations <= k; gasStations++) { + double maxSelection = -1; + int maxIndex = -1; + + for (int i = 0; i < n - 1; i++) { + double diff = (stations[i + 1] - stations[i]); + double selectionLength = diff / (howManyLeft[i] + 1); + if (selectionLength > maxSelection) { + maxSelection = selectionLength; + maxIndex = i; + } + } + howManyLeft[maxIndex]++; + } + + double maxDistance = -1; + for (int i = 0; i < n - 1; i++) { + double diff = (stations[i + 1] - stations[i]); + double selectionLength = diff / (howManyLeft[i] + 1); + maxDistance = Math.max(maxDistance, selectionLength); + } + + return maxDistance; + } + + public double minimiseMaxDistanceHeap(int[] stations, int k) { + int n = stations.length; + int[] howManyLeft = new int[n - 1]; + + var priorityQueue = new java.util.PriorityQueue((a, b) -> Double.compare(b[0], a[0])); + + for (int i = 0; i < n - 1; i++) { + double diff = (stations[i + 1] - stations[i]); + priorityQueue.add(new double[]{diff, i}); + } + + for (int gasStations = 1; gasStations <= k && !priorityQueue.isEmpty(); gasStations++) { + double[] curr = priorityQueue.poll(); + int index = (int) curr[1]; + howManyLeft[index]++; + double diff = stations[index + 1] - stations[index]; + double selectionLength = diff / (howManyLeft[index] + 1); + priorityQueue.add(new double[]{selectionLength, index}); + } + return priorityQueue.peek()[0]; + } + + //Minimum possible answer: We will get the minimum answer when we place all the gas stations in a single location. + // Now, in this case, the maximum distance will be 0. + //Maximum possible answer: We will not place stations before the first or after the last station rather we will place stations in between the existing stations. + // So, the maximum possible answer is the maximum distance between two consecutive existing stations. + public double minimiseMaxDistance(int[] stations, int k) { + int n = stations.length; // size of the array + double left = 0; + double right = 0; + + for (int i = 0; i < n - 1; i++) { + right = Math.max(right, stations[i + 1] - stations[i]); + } + + double diff = 1e-6; + + //The condition 'while(low <= high)' inside the 'while' loop won't work for decimal answers, and using it might lead to a TLE error. + // To avoid this, we can modify the condition to 'while(high - low > 10^(-6))'. + // This means we will only check numbers up to the 6th decimal place. + while (right - left < diff) { + double mid = (left + right) / (2.0); + int count = numberOfGasStationsRequired(stations, mid); + //low = mid+1: We have used this operation to eliminate the left half. + // But if we apply the same here, we might ignore several decimal numbers and possibly our actual answer. + // So, we will use this: low = mid. + if (count > k) { + //If result > k: On satisfying this condition, we can conclude that the number ‘mid’ is smaller than our answer. + // So, we will eliminate the left half and consider the right half + left = mid; + } else { + right = mid; + } + } + return right; + } + + private int numberOfGasStationsRequired(int[] arr, double mid) { + int n = arr.length; + int cnt = 0; + for (int i = 1; i < n; i++) { + //For each section between i and i-1, we will do the following: + //No. of stations = (arr[i]-arr[i-1]) / dist + int numberInBetween = (int) ((arr[i] - arr[i - 1]) / mid); + //Let's keep in mind a crucial edge case: if the section_length (arr[i] - arr[i-1]) is completely divisible by 'dist', + // the actual number of stations required will be one less than what we calculate. + //if (arr[i]-arr[i-1] == (No. of stations*dist): No. of stations -= 1. + if ((arr[i] - arr[i - 1]) == (mid * numberInBetween)) { + numberInBetween--; + } + cnt += numberInBetween; + } + return cnt; + } +} diff --git a/src/main/java/binarysearch/MedianOfTwoSortedArrays.java b/src/main/java/binarysearch/MedianOfTwoSortedArrays.java new file mode 100644 index 0000000..04b59d5 --- /dev/null +++ b/src/main/java/binarysearch/MedianOfTwoSortedArrays.java @@ -0,0 +1,137 @@ +package binarysearch; + +import java.util.Comparator; +import java.util.PriorityQueue; + +/** + * https://www.youtube.com/watch?v=F9c7LpRZWVQ + * TODO revise + * tricky binary search + */ +public class MedianOfTwoSortedArrays { + + public static void main(String[] args) { + int[] x = {1, 3, 8, 9, 15, 17, 30}; + int[] y = {7, 11, 18, 19, 21, 25}; + // 1,3,7,8,9,11,15,18,19,21,25 + MedianOfTwoSortedArrays mm = new MedianOfTwoSortedArrays(); + System.out.println(mm.findMedianSortedArraysEff(x, y) + " - " + mm.findMedianSortedArrays(x, y)); + } + + /** + * Each half contains (n/2) elements. + * Each half also contains x elements from the first array i.e. arr1[] and (n/2)-x elements from the second array i.e. arr2[]. + * The value of x might be different for the two halves. + * For example, in the above array, the left half contains 3 elements from arr1[] and 2 elements from arr2[]. + * + * @param input1 + * @param input2 + * @return + */ + public double findMedianSortedArraysBruteForce(int[] input1, int[] input2) { + int[] merged = new int[input1.length + input2.length]; + int i = 0; + int j = 0; + int k = 0; + while (i < input1.length && j < input2.length) { + if (input1[i] < input2[j]) { + merged[k++] = input1[i++]; + } else { + merged[k++] = input2[j++]; + } + } + while (i < input1.length) { + merged[k++] = input1[i++]; + } + while (j < input2.length) { + merged[k++] = input2[j++]; + } + + if (merged.length % 2 == 0) { + return (merged[merged.length / 2] + merged[merged.length / 2 - 1]) / 2.0; + } else { + return merged[merged.length / 2]; + } + } + + public double findMedianSortedArrays(int[] input1, int[] input2) { + //if input1 length is greater than switch them so that input1 is smaller than input2. + // the reason is to do binary search on smaller array to reduce time complexity + if (input1.length > input2.length) { + return findMedianSortedArrays(input2, input1); + } + int x = input1.length; + int y = input2.length; + int n = x + y; + int leftHalf = (n + 1) / 2; // the reason is this works for both odd and even + // if the n is 10, 10+1/2 = median is 5, if n is 9, 9+1/2 = median 5 + + // the whole idea is to partition the 2 arrays so that the left side and right side have same number of elements + // let's take example A= 1,3,7 and B= 2,6,8,9,10 + + // first take (low + high) / 2 for A it'd be 1 in this example. we partition at 1, [1 ||, 3,7] (1 element on left and 2 on right) + // for B we need to do this, {(x + y + 1) / 2 - partitionX} = (3+5+1/2)-1=3 [2,6,8||,9,10] (3 elements on left and 2 on right) + // add the total left and right elements for both arrays would come to be equal 3+1(left partition) and 2+2(right partition) + + int low = 0; + int high = x; + while (low <= high) { + int mid1 = (low + high) / 2; + int mid2 = leftHalf - mid1; + + int left1 = (mid1 == 0) ? Integer.MIN_VALUE : input1[mid1 - 1]; + int right1 = (mid1 == x) ? Integer.MAX_VALUE : input1[mid1]; + int left2 = (mid2 == 0) ? Integer.MIN_VALUE : input2[mid2 - 1]; + int right2 = (mid2 == y) ? Integer.MAX_VALUE : input2[mid2]; + + if (left1 <= right2 && left2 <= right1) { + if (n % 2 == 0) { + return (Math.max(left1, left2) + Math.min(right1, right2)) / 2.0; + } else { + return Math.max(left1, left2); + } + } else if (left1 > right2) { + //If l1 > r2: This implies that we have considered more elements from arr1[] than necessary. + // So, we have to take less elements from arr1[] and more from arr2[]. + // In such a scenario, we should try smaller values of x. + // To achieve this, we will eliminate the right half (high = mid-1). + high = mid1 - 1; + } + //This implies that we have considered more elements from arr2[] than necessary. + // So, we have to take less elements from arr2[] and more from arr1[]. + // In such a scenario, we should try bigger values of x. + // To achieve this, we will eliminate the left half (low = mid+1). + else low = mid1 + 1; + + } + return -1.0; + } + + public double findMedianSortedArraysEff(int[] nums1, int[] nums2) { + + PriorityQueue minHeap = new PriorityQueue<>(); + PriorityQueue maxHeap = new PriorityQueue<>(Comparator.reverseOrder()); + + + for (int value : nums1) { + maxHeap.add(value); + } + + for (int i : nums2) { + maxHeap.add(i); + } + + int val = 0; + //division refers to integer division, this modified formula (n1+n2+1) / 2 will be valid for both cases of odd and even. + val = (nums1.length + nums2.length + 1) / 2; + for (int k = 0; k < val; k++) { + minHeap.add(maxHeap.poll()); + } + + if (minHeap.size() == maxHeap.size()) { + return (double) (minHeap.peek() + maxHeap.peek()) / 2; + } else { + return minHeap.peek(); + } + } +} diff --git a/src/main/java/binarysearch/NumberOfDaysToMakeMBouquets.java b/src/main/java/binarysearch/NumberOfDaysToMakeMBouquets.java index 4d52ae0..6e4c4b0 100644 --- a/src/main/java/binarysearch/NumberOfDaysToMakeMBouquets.java +++ b/src/main/java/binarysearch/NumberOfDaysToMakeMBouquets.java @@ -8,7 +8,9 @@ public class NumberOfDaysToMakeMBouquets { public int minDays(int[] bloomDay, int m, int k) { - if(bloomDay.length< m*k) return -1; + if ((long) m * k > bloomDay.length) { + return -1; + } int left=1; int right= Arrays.stream(bloomDay).max().orElse(0); diff --git a/src/main/java/practiceproblems/SearchAnElementInMatrix.java b/src/main/java/binarysearch/SearchAnElementInMatrix.java similarity index 65% rename from src/main/java/practiceproblems/SearchAnElementInMatrix.java rename to src/main/java/binarysearch/SearchAnElementInMatrix.java index cd6fc4a..7c2f7e1 100644 --- a/src/main/java/practiceproblems/SearchAnElementInMatrix.java +++ b/src/main/java/binarysearch/SearchAnElementInMatrix.java @@ -1,4 +1,4 @@ -package practiceproblems; +package binarysearch; /** * https://www.youtube.com/watch?v=FOa55B9Ikfg @@ -14,6 +14,8 @@ private static boolean searchII(int[][] mat, int n, int x) { int j = n - 1; // set indexes for top right element // we can start from top right corner or bottom left corner, because from // these points only we have 2 paths one increasing one decreasing + // if we start at 0,0 both ways are increasing order, so we cannot decide + // same with n,n both ways are decreasing order. while (i < n && j >= 0) { if (mat[i][j] == x) { System.out.print("n Found at " + i + " " + j); @@ -43,11 +45,22 @@ public static boolean searchI(int[][] matrix, int target) { while (start <= end) { int mid = (start + end) / 2; /** - * Another way to took at it is: lets say you have a matrix M with 4 rows and 3 columns. - * When we want to access M[2][1], the way the memory address is calculated is 2*3+1 = 7. - * so you are just reversing the calculation , row number is given by 7/3 = 2, - * and column is the offset in that row so for 7th element it is 7%3 = 1. - * This link helped me understand it. https://www.youtube.com/watch?v=n5KNdUAftC4 + * Row calculation (mid / col): + * + * Think of it as "how many complete rows do we need to move down?" + * Each row contains col number of elements + * Integer division gives us the number of complete rows + * + * + * Column calculation (mid % col): + * + * Think of it as "after moving down the rows, how many steps do we need to move right in the current row?" + * The modulus operation gives us the remainder, which is the offset within the current row + * + * Imagine a bookshelf with 5 shelves (rows), each holding 10 books (columns). If you're told to get the 37th book: + * + * You'd move down 3 full shelves (37 / 10 = 3) + * Then move 7 books to the right on the 4th shelf (37 % 10 = 7) */ if (matrix[mid / cols][mid % cols] == target) { return true; diff --git a/src/main/java/binarysearch/ShipPackageWithNDays.java b/src/main/java/binarysearch/ShipPackageWithNDays.java index 27887ef..c905235 100644 --- a/src/main/java/binarysearch/ShipPackageWithNDays.java +++ b/src/main/java/binarysearch/ShipPackageWithNDays.java @@ -9,6 +9,8 @@ public class ShipPackageWithNDays { public static int shipWithinDays(int[] weights, int D) { if (weights.length == 0 || D == 0) return 0; + // this is because the ship should carry atleast the max weight + // else the max would be rejected int lowerBound = Arrays.stream(weights).max().orElse(0); int upperBound = Arrays.stream(weights).sum(); int mid = 0; diff --git a/src/main/java/binarysearch/SingleElementInSortedArray.java b/src/main/java/binarysearch/SingleElementInSortedArray.java index dc2b404..26f5f00 100644 --- a/src/main/java/binarysearch/SingleElementInSortedArray.java +++ b/src/main/java/binarysearch/SingleElementInSortedArray.java @@ -2,117 +2,37 @@ /** * https://leetcode.com/problems/single-element-in-a-sorted-array - * - * You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once. - * Find this single element that appears only once. */ public class SingleElementInSortedArray { - /** - * The single element is at the first even index not followed by its pair. We used this property in the linear search algorithm, - * where we iterated over all the even indexes until we encountered the first one not followed by its pair. - * - * for (int i = 0; i < nums.length - 1; i+=2) { - * if (nums[i] != nums[i + 1]) { - * return nums[i]; - * } - * } - * - * After the single element, the pattern changes to being odd indexes followed by their pair. - * This means that the single element (an even index) and all elements after it are even indexes not followed by their pair. - * Therefore, given any even index in the array, we can easily determine whether the single element is to the left or to the right. - * - * - * @param nums - * @return - */ - public int singleNonDuplicateElegant(int[] nums) { - int lo = 0; - int hi = nums.length - 1; - while (lo < hi) { - int mid = lo + (hi - lo) / 2; - - //We need to make sure our mid index is even. - // We can do this by dividing lo and hi in the usual way, but then decrementing it by 1 if it is odd. - // This also ensures that if we have an even number of even indexes to search, - // that we are getting the lower middle (incrementing by 1 here would not work, - // it'd lead to an infinite loop as the search space would not be reduced in some cases). - if (mid % 2 == 1) mid--; - - //Then we check whether the mid-index is the same as the one after it. - //If it is, then we know that mid is not the single element, and that the single element must be at an even index after mid. - //Therefore, we set lo to be mid + 2. It is +2 rather than the usual +1 because we want it to point at an even index. - if (nums[mid] == nums[mid + 1]) { - lo = mid + 2; - } else { - //If it is not, then we know that the single element is either at mid, or at some index before mid. - // Therefore, we set hi to be mid. - hi = mid; - } - } - return nums[lo]; - } - - - - /** - * The key observation to make is that the starting array must always have an odd number of elements (be odd-lengthed), - * because it has one element appearing once, and all the other elements appearing twice. - * [1,1,4,4,5,5,6,6,8,9,9] - * Here is what happens when we remove a pair(5,5) from the center. We are left with a left subarray and a right subarray. - * [1,1,4,4]**[6,6,8,9,9] - *

- * Like the original array, the subarray containing the single element must be odd-length-ed. - * The subarray not containing it must be even-length-ed. - * So by taking a pair out of the middle and then calculating which side is now odd-length-ed, - * we have the information needed for binary search. - * - * @param nums - * @return - */ + // the main idea here is the single element flips the order of the duplicates + // for example in [1,1,2,2,3,4,4,8,8] before 3 the order is (even,odd) after 3 the order is (odd,even) public int singleNonDuplicate(int[] nums) { - if (nums == null || nums.length == 0) return 0; + if (nums.length == 1) + return nums[0]; - int left = 0; + int left = 1; int right = nums.length - 1; - - while (left < right) { + if(nums[0]!=nums[1]) return nums[0]; + if(nums[nums.length-1]!=nums[nums.length-2]) return nums[nums.length-1]; + while (left <= right) { int mid = left + (right - left) / 2; - - boolean halvesAreEven = (right - mid) % 2 == 0; - - - if (nums[mid] == nums[mid + 1]) { - //Case 1: Mid’s partner is to the right, and the halves were originally even. - //The right side becomes odd-lengthed because we removed mid's partner from it. - // We need to set left to mid + 2 so that the remaining array is the part above mid's partner. - //[1,1,4,4,$5,$5,6,8,8] $=removed item - if (halvesAreEven) { - left = mid + 2; - } else { - //Case 2: Mid’s partner is to the right, and the halves were originally odd. - //The left side remains odd-lengthed. We need to set hi to mid - 1 so that the remaining array is the part below mid. - //[1,1,4,5,5,$6,$6,8,8,9,9] $=removed item - right = mid - 1; - } - } else if (nums[mid] == nums[mid - 1]) { - //Case 3: Mid’s partner is to the left, and the halves were originally even. - //The left side becomes odd-lengthed because we removed mid's partner from it. - // We need to set hi to mid - 2 so that the remaining array is the part below mid's partner. - //[1,1,4,$5,$5,6,6,8,8] $=removed item - if (halvesAreEven) { - right = mid - 2; - } else { - //Case 4: Mid’s partner is to the left, and the halves were originally odd. - //The right side remains odd-lengthed. We need to set lo to mid + 1 so that the remaining array is the part above mid. - //[1,1,4,4,$5,$5,6,6,8,9,9] - left = mid + 1; - } - } else { + //base case + if (nums[mid - 1] != nums[mid] && nums[mid + 1] != nums[mid]) { return nums[mid]; } - + // if mid is odd and mid-1 is equal to mid then the single element is on the left + // if mid is even and mid+1 is equal to mid then the single element is on the left + //[1,1,2,2,3,4,4,8,8] here if the mid is odd say 3 we check the mid-1 + // if the mid is even we check the mid+1 if the condition meets then we haven't + // seen the single element which flips the order of the duplicates + if((mid%2==1 && nums[mid] == nums[mid-1]) || (mid%2==0 && nums[mid]==nums[mid+1])){ + left=mid+1; + }else{ + right=mid-1; + } } - return nums[left]; + + return -1; } } \ No newline at end of file diff --git a/src/main/java/binarysearch/SmallestDivisor.java b/src/main/java/binarysearch/SmallestDivisor.java new file mode 100644 index 0000000..2b4e8b9 --- /dev/null +++ b/src/main/java/binarysearch/SmallestDivisor.java @@ -0,0 +1,33 @@ +package binarysearch; + +import java.util.Arrays; + +// https://leetcode.com/problems/find-the-smallest-divisor-given-a-threshold/ +public class SmallestDivisor { + + public int smallestDivisor(int[] nums, int threshold) { + int left=1; + int right= Arrays.stream(nums).max().orElse(0); + + while(left x / mid) { - right = mid; - } else { - res = mid; - left = mid + 1; + if(x <= 1)return x; + long min = 1, max = x / 2, ans = -1, mid; + while(min <= max){ + mid = (max + min) / 2; + if (mid*mid == x)return (int)mid; + if (mid*mid <= x){ + ans = mid; + min = mid + 1; } + else max = mid - 1; } - return res; + return (int)ans; } } diff --git a/src/main/java/practiceproblems/CloneGraph.java b/src/main/java/graph/leetcode/CloneGraph.java similarity index 95% rename from src/main/java/practiceproblems/CloneGraph.java rename to src/main/java/graph/leetcode/CloneGraph.java index 7962e97..ed9123b 100644 --- a/src/main/java/practiceproblems/CloneGraph.java +++ b/src/main/java/graph/leetcode/CloneGraph.java @@ -1,4 +1,4 @@ -package practiceproblems; +package graph.leetcode; import java.util.ArrayDeque; import java.util.ArrayList; @@ -50,7 +50,7 @@ public Node cloneGraph(Node node) { cloned.get(curr).neighbors.add(cloned.get(nb)); } } - return cloned.get(node); + return clonedNode; } diff --git a/src/main/java/practiceproblems/BitonicSearch.java b/src/main/java/practiceproblems/BitonicSearch.java deleted file mode 100644 index 91a6ac8..0000000 --- a/src/main/java/practiceproblems/BitonicSearch.java +++ /dev/null @@ -1,103 +0,0 @@ -package practiceproblems; - -/* A Bitonic Sequence is a sequence of numbers which is first strictly increasing then after a point strictly decreasing.*/ - -public class BitonicSearch { - - static int ascendingBinarySearch(int[] arr, int low, int high, int key) { - while (low <= high) { - int mid = low + (high - low) / 2; - if (arr[mid] == key) { - return mid; - } - if (arr[mid] > key) { - high = mid - 1; - } else { - low = mid + 1; - } - } - return -1; - } - - static int descendingBinarySearch(int[] arr, int low, int high, int key) { - while (low <= high) { - int mid = low + (high - low) / 2; - if (arr[mid] == key) { - return mid; - } - if (arr[mid] < key) { - high = mid - 1; - } else { - low = mid + 1; - } - } - return -1; - } - - // instead of writing two methods, we can write a method which contains order agnostic - // binary search, which compares the first and last element at first and inside while - // if ascending add below - // if (arr[mid] > key) { - // high = mid - 1; - // } else { - // low = mid + 1; - // } - //else if descending - // if (arr[mid] < key) { - // high = mid - 1; - // } else { - // low = mid + 1; - // } - - - // -3,1,-2,-3,-4,-5,-6 - static int findBitonicPoint(int arr[], int n, int l, int r) { - int mid = ((r + l) / 2) + l; - if (arr[mid] > arr[mid - 1] && arr[mid] > arr[mid + 1]) { - return mid; - } else { - // towards right if next number is greater - if (arr[mid] > arr[mid - 1] && arr[mid] < arr[mid + 1]) { - mid = findBitonicPoint(arr, n, mid, r); - } else { - // towards left if next number is smaller - if (arr[mid] < arr[mid - 1] && arr[mid] > arr[mid + 1]) { - mid = findBitonicPoint(arr, n, l, mid); - } - } - } - return mid; - } - - static int searchBitonic(int arr[], int n, int key, int index) { - if (key > arr[index]) { - return -1; - } else if (key == arr[index]) { - return index; - } else { - int temp = ascendingBinarySearch(arr, 0, index - 1, key); - if (temp != -1) { - return temp; - } - return descendingBinarySearch(arr, index + 1, n - 1, key); - } - } - - public static void main(String args[]) { - int[] arr = {-3, 3, 9, 8, 20, 17, 5, 3, 1}; - int key = 3; - int n = arr.length; - int l = 0; - int r = n - 1; - int index = findBitonicPoint(arr, n, l, r); - - int x = searchBitonic(arr, n, key, index); - - if (x == -1) { - System.out.println("Element Not Found"); - } else { - System.out.println("Element Found at index " + x); - } - - } -} \ No newline at end of file diff --git a/src/main/java/practiceproblems/BuildArray.java b/src/main/java/practiceproblems/BuildArray.java index 5bd3ba1..766b062 100644 --- a/src/main/java/practiceproblems/BuildArray.java +++ b/src/main/java/practiceproblems/BuildArray.java @@ -13,31 +13,33 @@ public static int[] buildArray(int[] nums) { int n = nums.length; int i = 0; /** - * To achieve O(1) space complexicity ,we need to store two values i.e. nums[i] and nums[nums[i]] in the same spot . - * we can do this by - * nums[i] = nums[i] + n *(nums[nums[i]] % n); - * - * In this both values i.e. nums[i] and nums[nums[i]] are being stored - * For eg. - * - * input = [0,2,1,5,3,4] - * Output: [0,1,2,4,5,3] - * - * here, let i=3, - * then nums[3] = 5; - * and nums[nums[3]] = 4; - * - * Now we store both of them in nums[i] itself by - * nums[i] = nums[i] + n *(nums[nums[i]] % n); //Equation 1 - * - * nums[3] = 5 + 6 *(4 %6); - * nums[3] = 29 - * Now in Second loop we Can retrieve nums[nums[i]] by dividing by n, - * nums[i] = nums[i] + n *(nums[nums[i]] % n) / n; - * nums[i] = 0 + nums[nums[i]]; - * nums[i]= nums[nums[i]; - * - * nums[3]/n = 29/6 =4; + a = r +bq Euclid's Division algorithm + let r = nums[i] + replace nums[i] with a number that: + + when you mod by q you get nums[i] + when you divide by q you get nums[nums[i]] + From a = r + bq + + we can observe that + + a % q = r + a / q = b + a % q = r + + Since a = r + bq, we can write: + (r + bq) % q = r % q + (bq % q) = r % q + 0 = r + This is because any multiple of q will give a remainder of 0 when divided by q. + + a / q = b + Again, using a = r + bq: + (r + bq) / q = r/q + b + Since r < q (as r is a remainder), r/q will be 0 in integer division. + So, (r + bq) / q = 0 + b = b + + nums[i] is stored as r (the remainder) + nums[nums[i]] is stored as b (the quotient) + n is stored as q */ while (i < nums.length) { diff --git a/src/main/java/practiceproblems/CanPlaceFlower.java b/src/main/java/practiceproblems/CanPlaceFlower.java index 2c7afc5..16ec9f7 100644 --- a/src/main/java/practiceproblems/CanPlaceFlower.java +++ b/src/main/java/practiceproblems/CanPlaceFlower.java @@ -1,14 +1,13 @@ package practiceproblems; /** - * https://leetcode.com/problems/can-place-flowers/submissions/ + * https://leetcode.com/problems/can-place-flowers/ */ public class CanPlaceFlower { public boolean canPlaceFlowers(int[] flowerbed, int n) { int flowerCounts = 0; - for (int i = 0; i < flowerbed.length && flowerCounts < n; i++) { if (flowerbed[i] == 0) { int prev = i > 0 ? flowerbed[i - 1] : 0; diff --git a/src/main/java/practiceproblems/ClosestNumbers.java b/src/main/java/practiceproblems/ClosestNumbers.java deleted file mode 100644 index fffed1e..0000000 --- a/src/main/java/practiceproblems/ClosestNumbers.java +++ /dev/null @@ -1,45 +0,0 @@ -package practiceproblems; - -import java.util.Arrays; - -/** - * https://www.geeksforgeeks.org/closest-numbers-list-unsorted-integers/ - * Given a list of distinct unsorted integers, - * find the pair of elements that have the smallest absolute difference between them? - * If there are multiple pairs, find them all. - * Input : arr[] = {10, 50, 12, 100} -Output : (10, 12) -The closest elements are 10 and 12 - -Input : arr[] = {5, 4, 3, 2} -Output : (2, 3), (3, 4), (4, 5) - */ -public class ClosestNumbers { - - public static void main(String[] args) { - //10, 50, 12, 100 - int[] arr = new int[] { 10, 50, 12, 100 }; - int n = arr.length; - if (n <= 1) { - return; - } - - // Sort array elements - Arrays.sort(arr); - - // Compare differences of adjacent - // pairs to find the minimum difference. - int minDiff = arr[1] - arr[0]; - for (int i = 2; i < n; i++) - minDiff = Math.min(minDiff, arr[i] - arr[i - 1]); - - // Traverse array again and print all pairs - // with difference as minDiff. - for (int i = 1; i < n; i++) { - if ((arr[i] - arr[i - 1]) == minDiff) { - System.out.print("(" + arr[i - 1] + ", " + arr[i] + "),"); - } - } - } - -} diff --git a/src/main/java/practiceproblems/CompleteBinaryTreeInserter.java b/src/main/java/practiceproblems/CompleteBinaryTreeInserter.java deleted file mode 100644 index 4ff17e1..0000000 --- a/src/main/java/practiceproblems/CompleteBinaryTreeInserter.java +++ /dev/null @@ -1,59 +0,0 @@ -package practiceproblems; - -import trees.TreeNode; - -import java.util.Deque; -import java.util.LinkedList; -import java.util.Queue; - -/** - * https://leetcode.com/problems/complete-binary-tree-inserter/ - * - * tricky - */ -public class CompleteBinaryTreeInserter { - - TreeNode root; - Deque queue; - - public CompleteBinaryTreeInserter(TreeNode root) { - this.root = root; - this.queue = new LinkedList<>(); - Queue tempQueue = new LinkedList<>(); - tempQueue.offer(root); - while (!tempQueue.isEmpty()) { - TreeNode temp = tempQueue.poll(); - - /** - * store only the nodes with incomplete children - */ - if (temp.right == null || temp.left == null) { - queue.offerLast(temp); - } - - - if (temp.left != null) tempQueue.offer(temp.left); - if (temp.right != null) tempQueue.offer(temp.right); - } - } - - public int insert(int v) { - - TreeNode deepNode = queue.peekFirst(); - queue.offerLast(new TreeNode(v)); - if (deepNode.left == null) { - deepNode.left = queue.peekLast(); - } else { - deepNode.right = queue.peekLast(); - queue.pollFirst(); - } - - return deepNode.val; - - } - - public TreeNode get_root() { - return root; - - } -} diff --git a/src/main/java/practiceproblems/ComplexNumberMultiply.java b/src/main/java/practiceproblems/ComplexNumberMultiply.java index 335645b..e98142c 100644 --- a/src/main/java/practiceproblems/ComplexNumberMultiply.java +++ b/src/main/java/practiceproblems/ComplexNumberMultiply.java @@ -13,10 +13,16 @@ public String complexNumberMultiply(String num1, String num2) { int ab = 0; aSq += Integer.parseInt(first[0]) * Integer.parseInt(second[0]); + // remove i from the string and multiply so substring(0, length - 1) bSq *= Integer.parseInt(first[1].substring(0, first[1].length() - 1)) * Integer.parseInt(second[1].substring(0, second[1].length() - 1)); ab += (Integer.parseInt(first[0]) * Integer.parseInt(second[1].substring(0, second[1].length() - 1))) + (Integer.parseInt(second[0]) * Integer.parseInt(first[1].substring(0, first[1].length() - 1))); return (aSq + bSq) + "+" + ab + "i"; } + + public static void main(String[] args) { + ComplexNumberMultiply complexNumberMultiply = new ComplexNumberMultiply(); + System.out.println(complexNumberMultiply.complexNumberMultiply("1+1i", "1+1i")); + } } diff --git a/src/main/java/practiceproblems/ConstructTreeFromInorderAndPostorder.java b/src/main/java/practiceproblems/ConstructTreeFromInorderAndPostorder.java deleted file mode 100644 index 1180448..0000000 --- a/src/main/java/practiceproblems/ConstructTreeFromInorderAndPostorder.java +++ /dev/null @@ -1,70 +0,0 @@ -package practiceproblems; - -import trees.TreeNode; - -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.HashMap; -import java.util.Map; -import java.util.Stack; - -public class ConstructTreeFromInorderAndPostorder { - int postorderIndex; - - public TreeNode buildTree(int[] inorder, int[] postorder) { - - postorderIndex = postorder.length - 1; - // build a hashmap to store value -> its index relations - Map inorderIndexMap = new HashMap<>(); - for (int i = 0; i < inorder.length; i++) { - inorderIndexMap.put(inorder[i], i); - } - - return arrayToTree(postorder, 0, postorder.length - 1, inorderIndexMap); - } - - private TreeNode arrayToTree(int[] postorder, int left, int right, Map inorderIndexMap) { - // if there are no elements to construct the tree - if (left > right) return null; - - // select the preorder_index element as the root and increment it - int rootValue = postorder[postorderIndex]; - postorderIndex--; - TreeNode root = new TreeNode(rootValue); - - // build left and right subtree - // excluding inorderIndexMap[rootValue] element because it's the root - // right has to be built first - /** - * The intuition behind it is that since postorder: LEFT → RIGHT → ROOT, - * so when we go in reverse order, we must construct the tree in the order of: ROOT → RIGHT → LEFT - */ - root.right = arrayToTree(postorder, inorderIndexMap.get(rootValue) + 1, right, inorderIndexMap); - root.left = arrayToTree(postorder, left, inorderIndexMap.get(rootValue) - 1, inorderIndexMap); - return root; - } - - public TreeNode buildTreeIterative(int[] inorder, int[] postorder) { - if (inorder.length == 0) return null; - int j = postorder.length - 1; - Deque stack = new ArrayDeque<>(); - TreeNode root = new TreeNode(postorder[j--]); - stack.push(root); - TreeNode node = null; - for (int i = inorder.length - 1; j >= 0; j--) { - TreeNode cur = new TreeNode(postorder[j]); - while (!stack.isEmpty() && stack.peek().val == inorder[i]) { - node = stack.pop(); - i--; - } - if (node != null) { - node.left = cur; - node = null; - } else { - stack.peek().right = cur; - } - stack.push(cur); - } - return root; - } -} \ No newline at end of file diff --git a/src/main/java/practiceproblems/CountAllPathsFrom2DMatrix.java b/src/main/java/practiceproblems/CountAllPathsFrom2DMatrix.java index fbbf937..334adb5 100644 --- a/src/main/java/practiceproblems/CountAllPathsFrom2DMatrix.java +++ b/src/main/java/practiceproblems/CountAllPathsFrom2DMatrix.java @@ -10,7 +10,7 @@ class CountAllPathsFrom2DMatrix { static int numberOfPaths(int m, int n) { // Create a 2D table to store results // of subproblems - int count[][] = new int[m][n]; + int[][] count = new int[m][n]; // Count of paths to reach any cell in // first row is 1 diff --git a/src/main/java/practiceproblems/CountBinaryStrings.java b/src/main/java/practiceproblems/CountBinaryStrings.java index 5428a1f..285a0e1 100644 --- a/src/main/java/practiceproblems/CountBinaryStrings.java +++ b/src/main/java/practiceproblems/CountBinaryStrings.java @@ -53,4 +53,25 @@ public int countBinarySubstrings(String s) { result += Math.min(prevCount, currCount); return result; } + + public int countBinarySubstringsExtraSpace(String s) { + //We can convert the string s into an array groups that represents the length of same-character contiguous blocks + // within the string. For example, if s = "110001111000000", then groups = [2, 3, 4, 6]. + int[] groups = new int[s.length()]; + int t = 0; + groups[0] = 1; + for (int i = 1; i < s.length(); i++) { + if (s.charAt(i-1) != s.charAt(i)) { + groups[++t] = 1; + } else { + groups[t]++; + } + } + + int ans = 0; + for (int i = 1; i <= t; i++) { + ans += Math.min(groups[i-1], groups[i]); + } + return ans; + } } diff --git a/src/main/java/practiceproblems/CountElements.java b/src/main/java/practiceproblems/CountElements.java index 9a0de2f..1fafaf8 100644 --- a/src/main/java/practiceproblems/CountElements.java +++ b/src/main/java/practiceproblems/CountElements.java @@ -3,18 +3,23 @@ /** * https://leetcode.com/problems/counting-elements/ + * Given an integer array arr, count how many elements x there are, such that x + 1 is also in arr. + * If there are duplicates in arr, count them separately. + * Input: arr = [1,3,2,3,5,0] + * Output: 3 + * Explanation: 0, 1 and 2 are counted cause 1, 2 and 3 are in arr. */ public class CountElements { public static int countElements(int[] arr) { - int[] count = new int[1002]; + int[] freq = new int[1002]; for(int num : arr) { - count[num]++; + freq[num]++; } int res = 0; for(int num : arr) { - if (count[num + 1] > 0) res++; + if (freq[num + 1] > 0) res++; } return res; } diff --git a/src/main/java/practiceproblems/DutchNationalFlag.java b/src/main/java/practiceproblems/DutchNationalFlag.java index 9ae16fc..4255483 100644 --- a/src/main/java/practiceproblems/DutchNationalFlag.java +++ b/src/main/java/practiceproblems/DutchNationalFlag.java @@ -2,37 +2,31 @@ /** * https://leetcode.com/problems/sort-colors/ - * tricky */ class DutchNationalFlag { public void sortColors(int[] arr) { if (arr.length == 0) { return; } - int pivot = 1; - int i = 0; - int j = arr.length - 1; - int zeroPos = 0; + int low = 0; + int mid = 0; + int high = arr.length - 1; - while (i <= j) { - if (arr[i] > pivot) { - swap(arr, i, j); - /** - * I guess to answer why we increment i when nums[i] == 0 and not do the same when nums[i] == 2, - * the easy way for me to remember is, after we swap the 2 we still need to check the current idx - * because it maybe 1 or 0 at the current index. - * But when nums[i] == 0, we pretty sure there are no 2 to the left of current idx since we walked from the left to right and - * already swapped all the 2. - */ - // no need to increment i here - // ex case [1,2,0] - j--; - } else if (arr[i] == pivot) { - i++; + while (mid <= high) { + if (arr[mid] == 0) { + //whatever comes from the low index has already been processed, + // so it's safe to increment both low and mid + swap(arr, low, mid); + low++; + mid++; + } else if (arr[mid] == 1) { + mid++; } else { - swap(arr, zeroPos, i); - zeroPos++; - i++; + swap(arr, mid, high); + //The reason we don't increment mid in this case is that after the swap, + // we're not sure what value is now at arr[mid]. + // It could be 0, 1, or 2. We need to examine this new value in the next iteration. + high--; } } } diff --git a/src/main/java/practiceproblems/InorderSuccessorPredecessor.java b/src/main/java/practiceproblems/InorderSuccessorPredecessor.java deleted file mode 100644 index a21c87d..0000000 --- a/src/main/java/practiceproblems/InorderSuccessorPredecessor.java +++ /dev/null @@ -1,143 +0,0 @@ -package practiceproblems; - -import trees.TreeNode; - -/** - * https://algorithms.tutorialhorizon.com/inorder-predecessor-and-successor-in-binary-search-tree/ - */ -public class InorderSuccessorPredecessor { - static int successor, predecessor; - - - public Node inorderSuccessorII(Node node) { - if (node == null) return null; - - if (node.right == null) { - while (node.parent != null && node.parent.val < node.val) - node = node.parent; - - return node.parent; - } - return findBelow(node.right); - } - - private Node findBelow(Node node) { - while (node != null && node.left != null) - node = node.left; - return node; - } - - public void successorPredecessor(TNode root, int val) { - if (root == null) return; - - if (root.data > val) { - // we make the root as successor because we might have a - // situation when value matches with the root, it wont have - // right subtree to find the successor, in that case we need - // parent to be the successor - successor = root.data; - successorPredecessor(root.left, val); - } else if (root.data < val) { - // we make the root as predecessor because we might have a - // situation when value matches with the root, it wont have - // left subtree to find the predecessor, in that case we need - // parent to be the predecessor. - predecessor = root.data; - successorPredecessor(root.right, val); - } - } - - public static void main(String args[]) { - TNode root = new TNode(25); - root.left = new TNode(15); - root.right = new TNode(40); - root.left.left = new TNode(10); - root.left.left.left = new TNode(5); - root.left.right = new TNode(18); - root.right.left = new TNode(35); - root.right.right = new TNode(45); - root.left.right.left = new TNode(19); - root.left.right.right = new TNode(20); - InorderSuccessorPredecessor i = new InorderSuccessorPredecessor(); - - i.successorPredecessor(root, 20); - - System.out.println("Inorder Successor of 20 is : " + successor + " and predecessor is : " + predecessor); - - } - - TreeNode result = null; - - public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { - helperFn(root, p); - return result; - } - - public void helperFn(TreeNode root, TreeNode p) { - if (root == null) return; - - if (root.val > p.val) { - result = root; - helperFn(root.left, p); - } else { - helperFn(root.right, p); - } - - } - - // tricky tree traversal - // predecessor go to left first and then go right till end - // so place the result assignment (pre = cur) in the go right block - private TreeNode findPredecessor(TreeNode root, TreeNode node) { - TreeNode pre = null; - TreeNode cur = root; - while (cur != null) { - if (cur.val < node.val) { - pre = cur; - cur = cur.right; - } else { - cur = cur.left; - } - } - return pre; - } - - // successor go to right first and then go left till end - // so place the result assignment (pre = cur) in the go left block - private TreeNode findSuccessor(TreeNode root, TreeNode node) { - TreeNode succ = null; - TreeNode cur = root; - while (cur != null) { - if (cur.val > node.val) { - succ = cur; - cur = cur.left; - } else { - cur = cur.right; - } - } - return succ; - } - - - class Node { - public int val; - public Node left; - public Node right; - public Node parent; - } - - static class TNode { - int data; - TNode left; - TNode right; - - public TNode(int data) { - this.data = data; - left = null; - right = null; - } - - - } -} - diff --git a/src/main/java/practiceproblems/KthSmallestFromTwoSortedArrays.java b/src/main/java/practiceproblems/KthSmallestFromTwoSortedArrays.java deleted file mode 100644 index cbf1417..0000000 --- a/src/main/java/practiceproblems/KthSmallestFromTwoSortedArrays.java +++ /dev/null @@ -1,47 +0,0 @@ -package practiceproblems; - -/** - * https://www.geeksforgeeks.org/k-th-element-two-sorted-arrays/ - * - * https://www.youtube.com/watch?v=nv7F4PiLUzo - * - * TODO - */ -class KthSmallestFromTwoSortedArrays { - - public static int findKth(int[] A, int i, int[] B, int j, int k) { - - if ((A.length - i) > (B.length - j)) { - return findKth(B, j, A, i, k); - } - - if (i >= A.length) { - return B[j + k - 1]; - } - if (k == 1) { - return Math.min(A[i], B[j]); - } - - int aMid = Math.min(k / 2, A.length - i); - int bMid = k - aMid; - - if (A[i + aMid - 1] <= B[j + bMid - 1]) { - return findKth(A, i + aMid, B, j, k - aMid); - } - - return findKth(A, i, B, j + bMid, k - bMid); - } - - public static void main(String[] args) { - int arr1[] = { 1, 6, 8, 9, 15 }; - int arr2[] = { 3, 5, 10, 14, 20 }; - - int k = 6; - int ans = findKth(arr1, 0, arr2, 0, k); - if (ans == -1) { - System.out.println("Invalid query"); - } else { - System.out.println(ans); - } - } -} diff --git a/src/main/java/practiceproblems/MatrixRowWithMax1.java b/src/main/java/practiceproblems/MatrixRowWithMax1.java index 0af8c4d..910d394 100644 --- a/src/main/java/practiceproblems/MatrixRowWithMax1.java +++ b/src/main/java/practiceproblems/MatrixRowWithMax1.java @@ -1,48 +1,49 @@ package practiceproblems; +import java.util.ArrayList; + /** * https://www.geeksforgeeks.org/find-the-row-with-maximum-number-1s/ */ public class MatrixRowWithMax1 { - public static void main(String[] args) { - int[][] mat = {{0, 0, 0, 1}, {0, 1, 1, 1}, {1, 1, 1, 1}, {0, 0, 0, 0}}; - System.out.println(rowWithMax1s(mat)); - } - - static int rowWithMax1s(int mat[][]) { - - int R = mat.length; - int C = mat[0].length; - int max_row_index = 0; + public int[] rowAndMaximumOnes(int[][] mat) { + + var result = new ArrayList(); + int maxSoFar=-1; + int m = mat.length; + int n = mat[0].length; + + for(int i=0;imaxSoFar){ + maxSoFar = onesCount; + result = new ArrayList(); + result.add(i); + }else if(onesCount==maxSoFar){ + result.add(i); + } - int j = findFirstIndex(mat[0], 0, C - 1); - if (j == -1) { - j = C - 1; } - for (int i = 1; i < R; i++) { - while (j >= 0 && mat[i][j] == 1) { - j = j - 1; - max_row_index = i; - } - } - return max_row_index; + return result.stream().mapToInt(i->i).toArray(); + } - static int findFirstIndex(int arr[], int low, int high) { - if (high >= low) { - int mid = low + (high - low) / 2; + public int lowerBound(int[] arr, int x){ + int left=0; + int right=arr.length-1; + + while(left - * Say the array has even number of negative numbers eg. [1,2,-3,-4,5,6]. - * Both forward and reverse traversals yield the same result, so it doesnt matter. - *

- * Say the array has multiple odd number of negative integers. eg. [1,2,-3,-4,-5, 6]. - * We can think of the "last" negative number in each traversal breaks the array to 2 halves. - * In this case , the max array in forward traversal is the maximum of ([1,2,-3,-4] and [6]) which is 24. - * In the reverse, the split is delimited by -3. So the max subarrray is teh maximum of ([6,-5,-4] and [2]) - *

- * Hence, in the end, its all about the presence of odd or even number of negative integers. - * In case of even, the product is always positive. In case of odd, the max product is limited by the last negative integer in each traversal. - * - * @param nums - * @return - */ - public int maxProduct(int[] nums) { - int max = Integer.MIN_VALUE, product = 1; - int len = nums.length; - - for (int num : nums) { - product *= num; - max = Math.max(product, max); - if (num == 0) product = 1; - } - - product = 1; - for (int i = len - 1; i >= 0; i--) { - product *= nums[i]; - max = Math.max(product, max); - if (nums[i] == 0) product = 1; - } - - return max; - - } - - - public static MaxSubarray getMaxSubarray(int[] inputArr){ - MaxSubarray result ; - int start=0; - int end=0; - int maxSum=Integer.MIN_VALUE; - int currSum=0; - int actualStart=0; - for(int i=0;imaxSum){ - maxSum =currSum; + public static MaxSubarray getMaxSubarray(int[] inputArr) { + MaxSubarray result; + int start = 0; + int end = 0; + int maxSum = Integer.MIN_VALUE; + int currSum = 0; + int actualStart = 0; + for (int i = 0; i < inputArr.length; i++) { + + currSum += inputArr[i]; + + if (currSum > maxSum) { + maxSum = currSum; actualStart = start; - end=i; + end = i; } - if(currSum<0){ + if (currSum < 0) { currSum = 0; - start =i+1; + start = i + 1; } } - if(start>end) { - start=end; + if (start > end) { + start = end; } result = new MaxSubarray(maxSum, actualStart, end); @@ -133,15 +91,53 @@ public static void main(String[] args) { System.out.println("Maximum Sub array product is " + maxProductSubArray(arr)); } - static class MaxSubarray { + /** + * Simplest case. + * Consider this array [1,2,3,-4,5,6]. + * We can think of -4 as dividing the array into 2 halves, [1,2,3] and [5,6]. + * The forward traversal yields the max as 6, while the reverse traversal yields 30. + *

+ * Say the array has even number of negative numbers eg. [1,2,-3,-4,5,6]. + * Both forward and reverse traversals yield the same result, so it doesnt matter. + *

+ * Say the array has multiple odd number of negative integers. eg. [1,2,-3,-4,-5, 6]. + * We can think of the "last" negative number in each traversal breaks the array to 2 halves. + * In this case , the max array in forward traversal is the maximum of ([1,2,-3,-4] and [6]) which is 24. + * In the reverse, the split is delimited by -3. So the max subarrray is teh maximum of ([6,-5,-4] and [2]) + *

+ * Hence, in the end, its all about the presence of odd or even number of negative integers. + * In case of even, the product is always positive. In case of odd, the max product is limited by the last negative integer in each traversal. + * + * @param nums + * @return + */ + public int maxProduct(int[] nums) { + + int n = nums.length; + double left = 1; + double right = 1; + double ans = nums[0]; + for (int i = 0; i < n; i++) { + left = left == 0 ? 1 : left; + right = right == 0 ? 1 : right; + + left *= nums[i]; + right *= nums[n - i - 1]; + ans = Math.max(ans, Math.max(left, right)); + } + return (int) ans; + + } + + static class MaxSubarray { int maxSum; int startIndex; int endIndex; - public MaxSubarray(int maxSum,int startIndex,int endIndex){ + public MaxSubarray(int maxSum, int startIndex, int endIndex) { this.maxSum = maxSum; - this.startIndex= startIndex; - this.endIndex =endIndex; + this.startIndex = startIndex; + this.endIndex = endIndex; } } } diff --git a/src/main/java/practiceproblems/MedianOfTwoSortedArrays.java b/src/main/java/practiceproblems/MedianOfTwoSortedArrays.java deleted file mode 100644 index 4d1bf3f..0000000 --- a/src/main/java/practiceproblems/MedianOfTwoSortedArrays.java +++ /dev/null @@ -1,118 +0,0 @@ -package practiceproblems; - -import java.util.Comparator; -import java.util.PriorityQueue; - -/** - * https://github.com/mission-peace/interview/blob/master/src/com/interview/binarysearch/MedianOfTwoSortedArrayOfDifferentLength.java - * TODO revise - * tricky binary search - */ -public class MedianOfTwoSortedArrays { - - public double findMedianSortedArrays(int[] input1, int[] input2) { - //if input1 length is greater than switch them so that input1 is smaller than input2. - if (input1.length > input2.length) { - return findMedianSortedArrays(input2, input1); - } - int x = input1.length; - int y = input2.length; - - // the whole idea is to partition the 2 arrays so that the left side and right side have same number of elements - // let's take example A= 1,3,7 and B= 2,6,8,9,10 - // so if we assume both are combined the median would be at 6(6+7/2= 6.5 to be exact) - - // first take (low + high) / 2 for A it'd be 1 in this example. we partition at 1, [1 ||, 3,7] (1 element on left and 2 on right) - // for B we need to do this, {(x + y + 1) / 2 - partitionX} = (3+5+1/2)-1=3 [2,6,8||,9,10] (3 elements on left and 2 on right) - // add the total left and right elements for both arrays would come to be equal 3+1(left partition) and 2+2(right partition) - - // the reason to add 1 ((x + y + 1) / 2 ) is to account for both odd and even lengths - // for odd length the left half should be greater, the +1 is to adjust for that - - int low = 0; - int high = x; - while (low <= high) { - int partitionX = (low + high) / 2; - int partitionY = (x + y + 1) / 2 - partitionX; - - //if partitionX is 0 it means nothing is there on left side to partition. [|| 1] Use -INF for maxLeftX - //if partitionX is length of input then there is nothing on right side. Use +INF for minRightX - - // to understand it further let's take an edge case A=[2] B=[1,3] - // partitionX=0+1/2 => 0 - // partitionY= 1+2+1/2 - 0 => 2 , the partition would look like this - // A= [-inf || 2] - // B= [2,3 || +inf] - int maxLeftX = (partitionX == 0) ? Integer.MIN_VALUE : input1[partitionX - 1]; - int minRightX = (partitionX == x) ? Integer.MAX_VALUE : input1[partitionX]; - - int maxLeftY = (partitionY == 0) ? Integer.MIN_VALUE : input2[partitionY - 1]; - int minRightY = (partitionY == y) ? Integer.MAX_VALUE : input2[partitionY]; - - // for the example given above, at right partition the elements would be grouped like below - // A=> 1,3 || 7 - // B=> 2,6 || 8,9,10 - // 3<8 and 6<7 so we take max of left and min of right - - if (maxLeftX <= minRightY && maxLeftY <= minRightX) { - //We have partitioned array at correct place - // Now get max of left elements and min of right elements to get the median in case of even length combined array size - // or get max of left for odd length combined array size. - if ((x + y) % 2 == 0) { - return ((double) Math.max(maxLeftX, maxLeftY) + Math.min(minRightX, minRightY)) / 2; - } else { - return Math.max(maxLeftX, maxLeftY); - } - } else if (maxLeftX > minRightY) { //we are too far on right side for partitionX. Go on left side. - high = partitionX - 1; - } else { //we are too far on left side for partitionX. Go on right side. - low = partitionX + 1; - } - } - - //Only we can come here is if input arrays were not sorted. Throw in that scenario. - throw new IllegalArgumentException(); - } - - public double findMedianSortedArraysEff(int[] nums1, int[] nums2) { - - - PriorityQueue minHeap = new PriorityQueue<>(); - PriorityQueue maxHeap = new PriorityQueue<>(Comparator.reverseOrder()); - - - for (int value : nums1) { - maxHeap.add(value); - } - - for (int i : nums2) { - maxHeap.add(i); - } - - int val = 0; - - if ((nums1.length + nums2.length) % 2 == 0) { - val = (nums1.length + nums2.length) / 2; - } else { - val = (nums1.length + nums2.length) / 2 + 1; - } - - for (int k = 0; k < val; k++) { - minHeap.add(maxHeap.poll()); - } - - if (minHeap.size() == maxHeap.size()) { - return (double) (minHeap.peek() + maxHeap.peek()) / 2; - } else { - return minHeap.peek(); - } - } - - public static void main(String[] args) { - int[] x = {1, 3, 8, 9, 15, 17, 30}; - int[] y = {7, 11, 18, 19, 21, 25}; - // 1,3,7,8,9,11,15,18,19,21,25 - MedianOfTwoSortedArrays mm = new MedianOfTwoSortedArrays(); - System.out.println(mm.findMedianSortedArraysEff(x, y) + " - " + mm.findMedianSortedArrays(x, y)); - } -} diff --git a/src/main/java/practiceproblems/NextGreaterNumber.java b/src/main/java/practiceproblems/NextGreaterNumber.java deleted file mode 100644 index ed052ab..0000000 --- a/src/main/java/practiceproblems/NextGreaterNumber.java +++ /dev/null @@ -1,77 +0,0 @@ -package practiceproblems; - -/** - * tricky - * - * https://www.geeksforgeeks.org/find-next-greater-number-set-digits/ - *

- * https://www.ideserve.co.in/learn/next-greater-number-using-same-digits - */ -public class NextGreaterNumber { - - // If all digits sorted in descending order, then output is always “Not Possible”. For example, 4321. - // If all digits are sorted in ascending order, then we need to swap last two digits. For example, 1234. - // For other cases, we need to process the number from rightmost side - //(why? because we need to find the smallest of all greater numbers) - - // Traverse the given number from rightmost digit, - //keep traversing till you find a digit which is smaller than the previously traversed digit. - //For example, if the input number is “534976”, we stop at 4 because 4 is smaller than next digit 9. - // If we do not find such a digit, then output is “Not Possible”. - // II) Now search the right side of above found digit ‘d’ for the smallest digit greater than ‘d’. - // For “534976″, the right side of 4 contains “976”. The smallest digit greater than 4 is 6. - // III) Swap the above found two digits, we get 536974 in above example. - // IV) Now sort all digits from position next to ‘d’ to the end of number. - //The number that we get after sorting is the output. - //For above example, we sort digits in bold 536974. We get “536479” which is the next greater number for input 534976. - public int nextGreaterElement(int n) { - - char[] arr = String.valueOf(n).toCharArray(); - - int i = arr.length - 2; - // I) Start from the right most digit and - // find the first digit that is - // smaller than the digit next to it. - while (i >= 0 && arr[i] >= arr[i + 1]) - i--; - - // If no such digit is found, its the edge case 1. - if (i < 0) return -1; - - // II) Find the smallest digit on right side of (i)'th - // digit that is greater than number[i] - int j = arr.length - 1; - while (arr[j] <= arr[i]) - j--; - - swap(arr, i, j); - reverse(arr, i + 1, arr.length - 1); - - try { - return Integer.parseInt(String.valueOf(arr)); - } catch (NumberFormatException e) { - return -1; - } - } - - public void reverse(char[] element, int i, int j) { - while (i <= j) { - swap(element, i, j); - i++; - j--; - } - } - - public void swap(char[] element, int i, int j) { - char temp = element[i]; - element[i] = element[j]; - element[j] = temp; - } - - public static void main(String[] args) { - NextGreaterNumber solution = new NextGreaterNumber(); - - System.out.println("Next greater number is: " + solution.nextGreaterElement(6938652)); - - } -} diff --git a/src/main/java/practiceproblems/NextPermutation.java b/src/main/java/practiceproblems/NextPermutation.java index 5fe78b4..7349376 100644 --- a/src/main/java/practiceproblems/NextPermutation.java +++ b/src/main/java/practiceproblems/NextPermutation.java @@ -5,54 +5,53 @@ * https://www.youtube.com/watch?v=LuLCLgMElus */ public class NextPermutation { - public void nextPermutation(int[] nums) { - // pivot is the element just before the non-increasing (weakly decreasing) suffix - /*2*/ - int pivot = indexOfLastPeak(nums) - 1; - // partitions nums into [prefix pivot suffix] - if (pivot != -1) { - int nextPrefix = lastIndexOfGreater(nums, nums[pivot]); // in the worst case it's suffix[0] - // next prefix must exist because pivot < suffix[0], otherwise pivot would be part of suffix - /*4*/ - swap(nums, pivot, nextPrefix); // this minimizes the change in prefix + if (nums.length == 0) + return; + + //Find the break-point, i:first index i from the back of the given array arr[i] becomes smaller than arr[i+1]. + //For example, if the given array is {2,1,5,4,3,0,0}, the break-point will be index 1(0-based indexing). + // Here from the back of the array, index 1 is the first index where arr[1] i.e. 1 is smaller than arr[i+1] i.e. 5. + int idx = -1; + int n = nums.length; + // the reason for starting backwards is we need to find a sub-array in descending order + for (int i = n - 2; i >= 0; i--) { + if (nums[i] < nums[i + 1]) { + idx = i; + break; + } } - /*5*/ - reverseSuffix(nums, pivot + 1); // reverses the whole list if there was no pivot - /*6*/ - } - /** - * Find the last element which is a peak. - * In case there are multiple equal peaks, return the first of those. - * - * @return first index of last peak - */ - int indexOfLastPeak(int[] nums) { - for (int i = nums.length - 1; 0 < i; --i) { - if (nums[i - 1] < nums[i]) return i; + if (idx == -1) { + //If such a break-point does not exist i.e. if the array is sorted in decreasing order, + // the given permutation is the last one in the sorted order of all possible permutations. + // So, the next permutation must be the first i.e. the permutation in increasing order. + //So, in this case, we will reverse the whole array and will return it as our answer. + for (int i = 0; i < n / 2; i++) { + swap(nums, i, n - i - 1); + } + return; } - return 0; - } - /** - * @return last index where the {@code num > threshold} or -1 if not found - */ - /*3*/ int lastIndexOfGreater(int[] nums, int threshold) { - for (int i = nums.length - 1; 0 <= i; --i) { - if (threshold < nums[i]) return i; + //Find the smallest number i.e. > arr[i] and in the right half of index i + // (i.e. from index i+1 to n-1) and swap it with arr[i]. + for (int i = n - 1; i >= idx; i--) { + if (nums[i] > nums[idx]) { + swap(nums, i, idx); + break; + } } - return -1; - } - /** - * Reverse numbers starting from an index till the end. - */ - void reverseSuffix(int[] nums, int start) { - int end = nums.length - 1; + //Reverse the entire right half(i.e. from index i+1 to n-1) of index i. And finally, return the array. + int start = idx + 1; + int end = n - 1; while (start < end) { - swap(nums, start++, end--); + swap(nums, start, end); + start++; + end--; } + return; + } void swap(int[] nums, int i, int j) { diff --git a/src/main/java/practiceproblems/RotateMatrixInPlace.java b/src/main/java/practiceproblems/RotateMatrixInPlace.java index 2e1195a..e274210 100644 --- a/src/main/java/practiceproblems/RotateMatrixInPlace.java +++ b/src/main/java/practiceproblems/RotateMatrixInPlace.java @@ -1,55 +1,9 @@ package practiceproblems; /** - * https://www.geeksforgeeks.org/inplace-rotate-square-matrix-by-90-degrees/ + * https://leetcode.com/problems/rotate-image/description/ */ class RotateMatrixInPlace { - - /** - * N/2 for time complexity o(n) - * get all the corners first and swap ( rotate 90 degree) - */ - - public static void rotate(int[][] matrix) { - if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return; - int n = matrix.length - 1; - - for (int i = 0; i < matrix.length / 2; i++) { - // to check number of cycles - for (int j = i; j < n - i; j++) { - // loop to find number of elements - - //x1,y1= x2,y2 - //x1=y2 - - int temp = matrix[i][j]; - - //0,0= 3,0 - matrix[i][j] = matrix[n - j][i]; - - // 3,0=3,3 - matrix[n - j][i] = matrix[n - i][n - j]; - - //3,3=0,3 - matrix[n - i][n - j] = matrix[j][n - i]; - - matrix[j][n - i] = temp; - } - } - - - } - - static void displayMatrix(int N, int mat[][]) { - for (int i = 0; i < N; i++) { - for (int j = 0; j < N; j++) - System.out.print(" " + mat[i][j]); - - System.out.print("\n"); - } - System.out.print("\n"); - } - /** * For Swapping 90 -> transpose matrix (rows to col, col to rows) -> swap cols using 2 pointers * For Swapping 180 -> swap columns using 2 pointer -> swap rows using 2 pointers @@ -58,7 +12,10 @@ static void displayMatrix(int N, int mat[][]) { public static void rotateAlter(int[][] matrix) { for (int i = 0; i < matrix.length; i++) { - for (int j = 0; j < i; j++) { + //If we start j from 0, we would end up swapping each element twice. + // For example, we'd swap matrix[1][2] with matrix[2][1], + // and then later swap matrix[2][1] with matrix[1][2] + for (int j = i; j < matrix[0].length; j++) { int temp = matrix[i][j]; matrix[i][j] = matrix[j][i]; matrix[j][i] = temp; @@ -66,8 +23,7 @@ public static void rotateAlter(int[][] matrix) { } for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix.length / 2; j++) { - int temp = 0; - temp = matrix[i][j]; + int temp = matrix[i][j]; matrix[i][j] = matrix[i][matrix.length - 1 - j]; matrix[i][matrix.length - 1 - j] = temp; } @@ -80,12 +36,6 @@ public static void main(String[] args) { // Test Case 1 int[][] mat = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}; - - displayMatrix(N, mat); - rotateAlter(mat); - - // Print rotated matrix - displayMatrix(N, mat); } } \ No newline at end of file diff --git a/src/main/java/practiceproblems/SerializeDeserializeBST.java b/src/main/java/practiceproblems/SerializeDeserializeBST.java deleted file mode 100644 index 7b80c13..0000000 --- a/src/main/java/practiceproblems/SerializeDeserializeBST.java +++ /dev/null @@ -1,60 +0,0 @@ -package practiceproblems; - - -import trees.TreeNode; - -import java.util.LinkedList; -import java.util.Queue; - -class SerializeDeserializeBST { - // Encodes a tree to a single string. - public String serialize(TreeNode root) { - StringBuilder sb = new StringBuilder(); - helperFn(root, sb); - return sb.toString(); - } - - public void helperFn(TreeNode root, StringBuilder sb) { - if (root == null) return; - sb.append(root.val + ","); - helperFn(root.left, sb); - helperFn(root.right, sb); - } - - // Decodes your encoded data to tree. - public TreeNode deserialize(String data) { - if (data == null || data.isEmpty()) return null; - Queue treeVal = buildIntArr(data); - - return bulidTreeFromArray(treeVal); - } - - public Queue buildIntArr(String data) { - - String[] arr = data.split(","); - Queue queue = new LinkedList<>(); - for (String se : arr) { - queue.offer(Integer.parseInt(se)); - } - return queue; - } - - public TreeNode bulidTreeFromArray(Queue treeValues) { - if (treeValues.isEmpty()) return null; - - Integer rootVal = treeValues.poll(); - TreeNode root = new TreeNode(rootVal); - - Queue smallerValues = new LinkedList<>(); - - while (!treeValues.isEmpty() && treeValues.peek() < rootVal) { - smallerValues.offer(treeValues.poll()); - } - root.left = bulidTreeFromArray(smallerValues); - root.right = bulidTreeFromArray(treeValues); - return root; - - - } - -} \ No newline at end of file diff --git a/src/main/java/practiceproblems/SetZeroesMatrix.java b/src/main/java/practiceproblems/SetZeroesMatrix.java index 104635c..12f8a1f 100644 --- a/src/main/java/practiceproblems/SetZeroesMatrix.java +++ b/src/main/java/practiceproblems/SetZeroesMatrix.java @@ -18,7 +18,7 @@ public void setZeroes(int[][] matrix) { // Use first row and first column as markers. // if matrix[i][j] = 0, mark respected row and col marker = 0; indicating that later this respective row and col must be marked 0; - // And because you are altering first row and collumn, + // And because you are altering first row and column, you need to have two variables to track their own status. // So, for ex, if any one of the first row is 0, fr = 0, and at the end set all first row to 0; @@ -49,4 +49,26 @@ public void setZeroes(int[][] matrix) { } } + public void setZeroesExtraSpace(int[][] matrix){ + int[] row = new int[matrix.length]; + int[] col = new int[matrix[0].length]; + + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix[0].length; j++) { + if (matrix[i][j] == 0){ + row[i] = 1; + col[j] = 1; + } + } + } + + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix[0].length; j++) { + if (row[i] == 1 || col[j] == 1) { + matrix[i][j] = 0; + } + } + } + + } } diff --git a/src/main/java/practiceproblems/SpiralMatrix.java b/src/main/java/practiceproblems/SpiralMatrix.java index c21e290..43f0fd4 100644 --- a/src/main/java/practiceproblems/SpiralMatrix.java +++ b/src/main/java/practiceproblems/SpiralMatrix.java @@ -1,6 +1,7 @@ package practiceproblems; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -9,29 +10,29 @@ class SpiralMatrix { public static List spiralOrder(int[][] matrix) { - + List res = new ArrayList<>(); - + if (matrix.length == 0) { return res; } - + int rowBegin = 0; - int rowEnd = matrix.length-1; + int rowEnd = matrix.length - 1; int colBegin = 0; int colEnd = matrix[0].length - 1; - + while (rowBegin <= rowEnd && colBegin <= colEnd) { // Traverse Right - for (int j = colBegin; j <= colEnd; j ++) { - System.out.println(" Right "+matrix[rowBegin][j]); + for (int j = colBegin; j <= colEnd; j++) { + System.out.println(" Right " + matrix[rowBegin][j]); res.add(matrix[rowBegin][j]); } rowBegin++; - + // Traverse Down - for (int j = rowBegin; j <= rowEnd; j ++) { - System.out.println(" Down "+matrix[j][colEnd]); + for (int j = rowBegin; j <= rowEnd; j++) { + System.out.println(" Down " + matrix[j][colEnd]); res.add(matrix[j][colEnd]); } colEnd--; @@ -39,35 +40,195 @@ public static List spiralOrder(int[][] matrix) { // Make sure we are now on a different row. if (rowBegin <= rowEnd) { // without this condition, this corner test case [[2,3]] would print [2,3,2] // Traverse Left - for (int j = colEnd; j >= colBegin; j --) { - System.out.println(" Left "+matrix[rowEnd][j]); + for (int j = colEnd; j >= colBegin; j--) { + System.out.println(" Left " + matrix[rowEnd][j]); res.add(matrix[rowEnd][j]); } } rowEnd--; - // Make sure we are now on a different column. - // this block's work is to lift 1 row up from bottom - // the rest of the work will be done by first 'Right' loop again + // It's necessary because after we've traversed right, down, and left, + // we might have exhausted all columns. + if (colBegin <= colEnd) { - // Traver Up - for (int j = rowEnd; j >= rowBegin; j --) { - System.out.println(" uppp "+matrix[j][colBegin]); + // Travel Up + // this block's work is to lift 1 row up from bottom + // the rest of the work will be done by first 'Right' loop again + for (int j = rowEnd; j >= rowBegin; j--) { + System.out.println(" uppp " + matrix[j][colBegin]); res.add(matrix[j][colBegin]); } } - colBegin ++; + colBegin++; } - + return res; } public static void main(String[] args) { - - int a[][] = {{1, 2, 3, 4}, - {5, 6, 7, 8}, - {9, 10, 11, 12}, - {13, 14, 15, 16}}; - spiralOrder(a); + +// int a[][] = {{1, 2, 3, 4}, +// {5, 6, 7, 8}, +// {9, 10, 11, 12}, +// {13, 14, 15, 16}}; +// spiralOrder(a); + + SpiralMatrix sm = new SpiralMatrix(); + sm.spiralMatrixIII(5, 6, 1, 4); + } + + public int[][] generateMatrix(int n) { + + int[][] matrix = new int[n][n]; + + int rowBegin = 0; + int rowEnd = n - 1; + int colBegin = 0; + int colEnd = n - 1; + int num = 1; + while (rowBegin <= rowEnd && colBegin <= colEnd) { + // Traverse Right + for (int j = colBegin; j <= colEnd; j++) { + matrix[rowBegin][j] = num++; + } + rowBegin++; + + // Traverse Down + for (int j = rowBegin; j <= rowEnd; j++) { + matrix[j][colEnd] = num++; + } + colEnd--; + + // Make sure we are now on a different row. + if (rowBegin <= rowEnd) { // without this condition, this corner test case [[2,3]] would print [2,3,2] + // Traverse Left + for (int j = colEnd; j >= colBegin; j--) { + matrix[rowEnd][j] = num++; + } + } + rowEnd--; + + // It's necessary because after we've traversed right, down, and left, + // we might have exhausted all columns. + + if (colBegin <= colEnd) { + // Travel Up + // this block's work is to lift 1 row up from bottom + // the rest of the work will be done by first 'Right' loop again + for (int j = rowEnd; j >= rowBegin; j--) { + matrix[j][colBegin] = num++; + } + } + colBegin++; + } + + return matrix; + } + + //The idea here is that once we start at (r=r0, c=c0), + // we walk along the east, then south, then west, and then north. + public int[][] spiralMatrixIII(int R, int C, int r0, int c0) { + int[][] dirt = new int[][]{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // east, south, west, north is 0, 1, 2, + // 3 + int[][] res = new int[R * C][2]; + int len = 0, d = 0, j = 0; // move steps in the direction + res[j++] = new int[]{r0, c0}; + //After starting at (r0,c0), we need to walk in spirals, + // where the length of the spiral increases after every two directions. + // For example 2, we start at (r0=1, c0=4), then we go east by one length, we go south by one length. + // Following that, we go west by 2 length and then, go north by 2 length. + // After that, we go in next directions by 3 lengths, and so on. + while (j < R * C) { // fill all the blanks + if (d == 0 || d == 2) { + len++; // when move east or west, the length of path need plus 1 + } + for (int i = 0; i < len; i++) { + r0 += dirt[d][0]; + c0 += dirt[d][1]; + if (r0 >= 0 && r0 < R && c0 >= 0 && c0 < C) // check valid + res[j++] = new int[]{r0, c0}; + } + d = (d + 1) % 4; // turn to next direction + } + return res; } -} \ No newline at end of file + + public int[][] spiralMatrixWithLinkedList(int m, int n, ListNode head) { + int[][] matrix = new int[m][n]; + + for (int i = 0; i < m; i++) { + Arrays.fill(matrix[i], -1); + } + int rowBegin = 0; + int rowEnd = m - 1; + int colBegin = 0; + int colEnd = n - 1; + + while (rowBegin <= rowEnd && colBegin <= colEnd) { + + for (int j = colBegin; j <= colEnd; j++) { + if (head != null) { + matrix[rowBegin][j] = head.val; + head = head.next; + } + } + rowBegin++; + + for (int j = rowBegin; j <= rowEnd; j++) { + if (head != null) { + matrix[j][colEnd] = head.val; + head = head.next; + } + } + colEnd--; + + // Make sure we are now on a different row. + if (rowBegin <= rowEnd) { // without this condition, this corner test case [[2,3]] would print [2,3,2] + for (int j = colEnd; j >= colBegin; j--) { + if (head != null) { + matrix[rowEnd][j] = head.val; + head = head.next; + } + } + } + rowEnd--; + + // It's necessary because after we've traversed right, down, and left, + // we might have exhausted all columns. + + if (colBegin <= colEnd) { + // Travel Up + // this block's work is to lift 1 row up from bottom + // the rest of the work will be done by first 'Right' loop again + for (int j = rowEnd; j >= rowBegin; j--) { + if (head != null) { + matrix[j][colBegin] = head.val; + head = head.next; + } + } + } + colBegin++; + } + + return matrix; + } + + class ListNode { + int val; + ListNode next; + + ListNode() { + } + + ListNode(int val) { + this.val = val; + } + + ListNode(int val, ListNode next) { + this.val = val; + this.next = next; + } + } + +} + diff --git a/src/main/java/practiceproblems/SpiralMatrixII.java b/src/main/java/practiceproblems/SpiralMatrixII.java deleted file mode 100644 index 8b37806..0000000 --- a/src/main/java/practiceproblems/SpiralMatrixII.java +++ /dev/null @@ -1,56 +0,0 @@ -package practiceproblems; - -import java.util.Arrays; - -public class SpiralMatrixII { - - public static int[][] generateMatrix(int n) { - // Declaration - int[][] matrix = new int[n][n]; - - // Edge Case - if (n == 0) { - return matrix; - } - - - // Normal Case - int rowStart = 0; - int rowEnd = n - 1; - int colStart = 0; - int colEnd = n - 1; - int num = 1; // change - - while (rowStart <= rowEnd && colStart <= colEnd) { - for (int i = colStart; i <= colEnd; i++) { - matrix[rowStart][i] = num++; // change - } - rowStart++; - - for (int i = rowStart; i <= rowEnd; i++) { - matrix[i][colEnd] = num++; // change - } - colEnd--; - - for (int i = colEnd; i >= colStart; i--) { - if (rowStart <= rowEnd) - matrix[rowEnd][i] = num++; // change - } - rowEnd--; - - for (int i = rowEnd; i >= rowStart; i--) { - if (colStart <= colEnd) - matrix[i][colStart] = num++; // change - } - colStart++; - - System.out.println(Arrays.deepToString(matrix)); - } - - return matrix; - } - - public static void main(String[] args) { - generateMatrix(4); - } -} diff --git a/src/main/java/practiceproblems/intervals/MergeIntervals.java b/src/main/java/practiceproblems/intervals/MergeIntervals.java index 7ff73e1..feaf47f 100644 --- a/src/main/java/practiceproblems/intervals/MergeIntervals.java +++ b/src/main/java/practiceproblems/intervals/MergeIntervals.java @@ -14,20 +14,20 @@ public static int[][] merge(int[][] intervals) { if (intervals.length <= 1) { return intervals; } - Arrays.sort(intervals, Comparator.comparingInt(i -> i[0])); - List result = new ArrayList<>(); - int[] prevInterval = intervals[0]; - result.add(prevInterval); - for (int[] currInterval : intervals) { - if (currInterval[0] <= prevInterval[1]) // Overlapping intervals, move the end if needed - { - prevInterval[1] = Math.max(prevInterval[1], currInterval[1]); - } else { // Disjoint intervals, add the new interval to the list - prevInterval = currInterval; - result.add(prevInterval); + Arrays.sort(intervals, Comparator.comparingInt(a -> a[0])); + + for (int[] interval : intervals) { + int start = interval[0]; + int end = interval[1]; + + if (result.isEmpty() || start > result.get(result.size() - 1)[1]) { + result.add(new int[]{start, end}); + } else { + result.get(result.size() - 1)[1] = Math.max(end, result.get(result.size() - 1)[1]); } } + return result.toArray(new int[result.size()][]); } diff --git a/src/main/java/practiceproblems/intervals/OverlappingIntervals.java b/src/main/java/practiceproblems/intervals/OverlappingIntervals.java index 3c110b4..f8384e9 100644 --- a/src/main/java/practiceproblems/intervals/OverlappingIntervals.java +++ b/src/main/java/practiceproblems/intervals/OverlappingIntervals.java @@ -9,17 +9,15 @@ public class OverlappingIntervals { public int eraseOverlapIntervals(int[][] intervals) { - if (intervals.length == 0) return 0; Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0])); - int end = intervals[0][1]; - + int maxObservedEnd = intervals[0][1]; int result = 0; for (int i = 1; i < intervals.length; i++) { + int start = intervals[i][0]; + int end = intervals[i][1]; - result++; - - if (intervals[i][0] < end) { + if (start < maxObservedEnd) { result++; /** * The reason we choose min of ends @@ -33,17 +31,31 @@ public int eraseOverlapIntervals(int[][] intervals) { * We need more logic to make the code work correctly. * * So instead of 2 if we removed 1 then we have to update the previous end point as 1 is now gone. - * Hence the assignment of the smaller endtime (e = itv.end). + * Hence, the assignment of the smaller endtime (e = itv.end). * Interval 3 doesnt overlap with last end time and so we only have to remove 1 interval, * which is what we expected. */ - end = Math.min(end, intervals[i][1]); + maxObservedEnd = Math.min(maxObservedEnd, end); } else { - end = intervals[i][1]; + maxObservedEnd = end; } } return result; } + public int eraseOverlappingIntervalsAlter(int[][] intervals) { + Arrays.sort(intervals, (a, b) -> (a[1] - b[1])); + + int ct = 1; + int prev = intervals[0][1]; + for (int i = 1; i < intervals.length; i++) { + if (intervals[i][0] >= prev) { + ct++; + prev = intervals[i][1]; + } + } + return intervals.length - ct; + } + } \ No newline at end of file diff --git a/src/main/java/practiceproblems/mergesort/CountingInversion.java b/src/main/java/practiceproblems/mergesort/CountingInversion.java index 0ca4129..bc9b075 100644 --- a/src/main/java/practiceproblems/mergesort/CountingInversion.java +++ b/src/main/java/practiceproblems/mergesort/CountingInversion.java @@ -6,31 +6,30 @@ class CountingInversion { static int mergeSort(int[] arr, int arrSize) { - int[] temp = new int[arrSize]; - return mergeSort(arr, temp, 0, arrSize - 1); + return mergeSort(arr, 0, arrSize - 1); } - static int mergeSort(int[] arr, int[] temp, int left, int right) { - int mid; + static int mergeSort(int[] arr, int left, int right) { + if (left >= right) + return 0; int invCount = 0; - if (left < right) { - mid = ((right - left) / 2) + left; + int mid = ((right - left) / 2) + left; - invCount = mergeSort(arr, temp, left, mid); - invCount += mergeSort(arr, temp, mid + 1, right); + invCount += mergeSort(arr, left, mid); + invCount += mergeSort(arr, mid + 1, right); + + invCount += merge(arr, left, mid + 1, right); - invCount += merge(arr, temp, left, mid + 1, right); - } return invCount; } - static int merge(int[] arr, int[] temp, int left, int mid, int right) { + static int merge(int[] arr, int left, int mid, int right) { int invCount = 0; - + int[] temp = new int[arr.length]; int i = left; - int j = mid; + int j = mid+1; int k = left; - while ((i <= mid - 1) && (j <= right)) { + while ((i <= mid) && (j <= right)) { if (arr[i] <= arr[j]) { temp[k++] = arr[i++]; } else { @@ -40,7 +39,7 @@ static int merge(int[] arr, int[] temp, int left, int mid, int right) { // when i=1 and j=0 (value 3 and 2) we see an inversion, since // the first part is sorted and values after i=1(3) will be greater than j=0(2) // so we consider all elements after 3 as inversions - invCount+= i - mid+1; + invCount += mid - i + 1; } } diff --git a/src/main/java/sorting/MergeSort.java b/src/main/java/practiceproblems/mergesort/MergeSort.java similarity index 58% rename from src/main/java/sorting/MergeSort.java rename to src/main/java/practiceproblems/mergesort/MergeSort.java index b2d046d..570bed4 100644 --- a/src/main/java/sorting/MergeSort.java +++ b/src/main/java/practiceproblems/mergesort/MergeSort.java @@ -1,22 +1,22 @@ -package sorting; +package practiceproblems.mergesort; import java.util.Arrays; class MergeSort { - static void mergeSort(int arr[], int temp[], int left, int right) { + static void mergeSort(int[] arr, int left, int right) { if (left < right) { int mid = ((right - left) / 2) + left; - mergeSort(arr, temp, left, mid); - mergeSort(arr, temp, mid + 1, right); + mergeSort(arr, left, mid); + mergeSort(arr, mid + 1, right); - merge(arr, temp, left, mid, right); + merge(arr, left, mid, right); } } - static void merge(int arr[], int temp[], int left, int mid, int right) { - + static void merge(int[] arr, int left, int mid, int right) { + int[] temp = new int[arr.length]; int i = left; int j = mid + 1; int k = left; @@ -39,9 +39,9 @@ static void merge(int arr[], int temp[], int left, int mid, int right) { } public static void main(String[] args) { - int arr[] = new int[] { 8, 4, 1, 2 }; - int temp[] = new int[arr.length]; - mergeSort(arr, temp, 0, arr.length - 1); + int []arr = new int[] { 8, 4, 1,6,6,9,2, 2 }; + + mergeSort(arr, 0,arr.length - 1); System.out.println(Arrays.toString(arr)); } } diff --git a/src/main/java/practiceproblems/mergesort/ReversePairs.java b/src/main/java/practiceproblems/mergesort/ReversePairs.java index 02592ee..33f7798 100644 --- a/src/main/java/practiceproblems/mergesort/ReversePairs.java +++ b/src/main/java/practiceproblems/mergesort/ReversePairs.java @@ -3,62 +3,37 @@ public class ReversePairs { public int reversePairs(int[] nums) { - int[] temp = new int[nums.length]; - return mergeSort(nums, temp, 0, nums.length - 1); + return mergeSort(nums, 0, nums.length - 1); } - int mergeSort(int[] arr, int[] temp, int left, int right) { - int mid; + int mergeSort(int[] arr, int left, int right) { + if (left >= right) { + return 0; + } int invCount = 0; - if (left < right) { - - mid = ((right + left) / 2); - - invCount = mergeSort(arr, temp, left, mid); - invCount += mergeSort(arr, temp, mid + 1, right); - - invCount += merge(arr, temp, left, mid, right); + int mid = ((right + left) / 2); + + invCount += mergeSort(arr, left, mid); + invCount += mergeSort(arr, mid + 1, right); + // Count reverse pairs across the two sorted halves + int i = left, j = mid + 1; + while (i <= mid && j <= right) { + if ((long) arr[i] > 2 * (long) arr[j]) { + invCount += (mid - i + 1); // All elements from i to mid are greater than 2*nums[j] + j++; + } else { + i++; + } } + merge(arr, left, mid, right); return invCount; } - int merge(int[] arr, int[] temp, int left, int mid, int right) { + void merge(int[] arr, int left, int mid, int right) { int invCount = 0; int rightArrStart = mid + 1; - - /** - * the idea is move the rightArrStart for all the valid 2 * arr[j] - * fox ex leftArr = [12,19,28] and rightArr = [2,10,12] - * - * when leftArrPointer = 12 - * rightArrPointer = 10 - * the while loop breaks and the count is added as (rightArrPointer - mid+1) => 1 - * - * we then increment leftArrPointer - * - * when leftArrPointer = 19 - * rightArrPointer = 10 - * the while loop is skipped and the count is added as (rightArrPointer - mid+1) => 1 because the previous 2 values is - * lesser than the 19(2*2 < 19) - * - * we then increment leftArrPointer - * - * when leftArrPointer = 28 - * rightArrPointer = 10 - * - * the while loop breaks because no more value in rightArr - * and the count is added as (rightArrPointer - mid+1) => 3 - * - * - */ - for (int leftArrStart = left; leftArrStart <= mid; leftArrStart++) { - - while (rightArrStart <= right && arr[leftArrStart] > 2 * (long) arr[rightArrStart]) { - rightArrStart++; - } - invCount += (rightArrStart - (mid + 1)); // this gives the length of right array's valid window - } + int[] temp = new int[arr.length]; int i = left; int j = mid + 1; @@ -78,8 +53,6 @@ int merge(int[] arr, int[] temp, int left, int mid, int right) { for (i = left; i <= right; i++) arr[i] = temp[i]; - - return invCount; } } diff --git a/src/main/java/practiceproblems/prefixsum/UniqueSubArrayDivisibleByK.java b/src/main/java/practiceproblems/prefixsum/UniqueSubArrayDivisibleByK.java index fa845b5..6f1a93a 100644 --- a/src/main/java/practiceproblems/prefixsum/UniqueSubArrayDivisibleByK.java +++ b/src/main/java/practiceproblems/prefixsum/UniqueSubArrayDivisibleByK.java @@ -7,15 +7,12 @@ * https://leetcode.com/problems/k-divisible-elements-subarrays/ * * It's tempting to apply a sliding window technique here, however, it won't help us identify distinct subarrays. - * * Because constraints are low (n <= 200), we can just identify all valid subarrays O(n ^ 2), * and use a set to dedup them O(n). So, the overall complexity would be O(n ^ 3). * * For O(n ^ 2) solution, we can use a rolling hash (Rabin-Karp). * Note that we only need to check hashes for arrays of the same size, which reduces the collision probability. * - * We can also use a Trie to achieve a quadratic complexity - check the second solution below. - * * Rolling Hash (Simple) * We need to do the collision check, but here I omitted it for simplicity (see third solution below if you want to handle collisions). */ @@ -40,4 +37,25 @@ public int countDistinct(int[] nums, int k, int p) { } return ways.size(); } + // for (int i = 0; i < n; i++) { + // StringBuilder sb = new StringBuilder(); + // int t = 0; + // for (int j = i; j < n ; j++) { + // sb.append(nums[j] + ","); + // if(nums[j] % p == 0){ + // t++; + // } + // if(t > k){ + // break; + // } + // + // set.add(sb.toString()); + // } + // } + + public static void main(String[] args) { + UniqueSubArrayDivisibleByK uniqueSubArrayDivisibleByK = new UniqueSubArrayDivisibleByK(); + System.out.println(uniqueSubArrayDivisibleByK.countDistinct(new int[]{2,3,3,2,2}, 2, 2)); + System.out.println(uniqueSubArrayDivisibleByK.countDistinct(new int[]{1, 2, 3, 4}, 4, 1)); + } } diff --git a/src/main/java/practiceproblems/stack/AtomCounts.java b/src/main/java/practiceproblems/stack/AtomCounts.java new file mode 100644 index 0000000..284cf2c --- /dev/null +++ b/src/main/java/practiceproblems/stack/AtomCounts.java @@ -0,0 +1,59 @@ +package practiceproblems.stack; + +import java.util.*; + +// https://leetcode.com/problems/number-of-atoms/ +public class AtomCounts { + public String countOfAtoms(String formula) { + + var stack = new Stack>(); + stack.push(new HashMap<>()); + int len = formula.length(); + for (int i = 0; i < formula.length();) { + + if (formula.charAt(i) == '(') { + stack.push(new HashMap<>()); + i++; + continue; + } + if (formula.charAt(i) == ')') { + Map top = stack.pop(); + i++; + int number = 0; + int start = i; + while (i < len && Character.isDigit(formula.charAt(i))){ + i++; + } + int multiplier = start < i ? Integer.parseInt(formula.substring(start, i)) : 1; + for (String key : top.keySet()) { + stack.peek().put(key, stack.peek().getOrDefault(key, 0) + top.get(key) * multiplier); + } + continue; + } + int start = i; + i++; + while (i < len && Character.isLowerCase(formula.charAt(i))) + i++; + String element = formula.substring(start, i); + start = i; + while (i < len && Character.isDigit(formula.charAt(i))) { + i++; + } + int count = start < i ? Integer.parseInt(formula.substring(start, i)) : 1; + stack.peek().put(element, stack.peek().getOrDefault(element, 0) + count); + } + + Map result = stack.pop(); + List elements = new ArrayList<>(result.keySet()); + Collections.sort(elements); + StringBuilder sb = new StringBuilder(); + for (String element : elements) { + sb.append(element); + int count = result.get(element); + if (count > 1) + sb.append(count); + } + return sb.toString(); + } + +} diff --git a/src/main/java/practiceproblems/BasicCalculator.java b/src/main/java/practiceproblems/stack/BasicCalculator.java similarity index 66% rename from src/main/java/practiceproblems/BasicCalculator.java rename to src/main/java/practiceproblems/stack/BasicCalculator.java index d7acc24..346cef3 100644 --- a/src/main/java/practiceproblems/BasicCalculator.java +++ b/src/main/java/practiceproblems/stack/BasicCalculator.java @@ -1,4 +1,4 @@ -package practiceproblems; +package practiceproblems.stack; import java.util.ArrayDeque; import java.util.Deque; @@ -13,7 +13,7 @@ public static void main(String[] args) { } public static int calculate(String s) { - if (s == null || s.length() == 0) return -1; + if (s == null || s.isEmpty()) return -1; Deque deque = new ArrayDeque<>(); int sign = 1; int number = 0; @@ -21,7 +21,7 @@ public static int calculate(String s) { // let's take an edge case 2-(5-6)=3 // at i=0 number=2 // i=1 char ='-' update with prev seen sign res=sign*number reset number we are looking for next operand - //i=2 char='(' and sign is '-', push prev result and sign and reset result for calclating + //i=2 char='(' and sign is '-', push prev result and sign and reset result for calculating // sub problem inside braces // i=3 update number to 5 // i=4 char ='-' update result as sign*number = 5 reset number and sign =-1 @@ -60,5 +60,37 @@ public static int calculate(String s) { return result; } + /** + * Example 1: + * Input: s = "(abcd)" + * Output: "dcba" + * Example 2: + * Input: s = "(u(love)i)" + * Output: "iloveu" + * Explanation: The substring "love" is reversed first, then the whole string is reversed. + */ + public String reverseParentheses(String s) { + + StringBuilder sb = new StringBuilder(); + Deque queue = new ArrayDeque<>(); + + for(char ch:s.toCharArray()){ + + if (ch=='('){ + queue.push(sb.length()); + }else if (ch==')'){ + var reversed = new StringBuilder(); + for(int j= sb.length()-queue.pop();j>0;--j){ + reversed.append(sb.charAt(sb.length()-1)); + sb.deleteCharAt(sb.length()-1); + } + sb.append(reversed); + }else{ + sb.append(ch); + } + } + + return sb.toString(); + } } \ No newline at end of file diff --git a/src/main/java/sorting/QuickSort.java b/src/main/java/sorting/QuickSort.java index 5354cf3..b439760 100644 --- a/src/main/java/sorting/QuickSort.java +++ b/src/main/java/sorting/QuickSort.java @@ -35,8 +35,7 @@ public int findPivot(int[] nums, int start, int end){ while(start<=end){ if(nums[start] 0) sb.append(ch); + opened++; + + } else { + if (opened > 1) sb.append(ch); + opened--; + } + } + return sb.toString(); + } +} diff --git a/src/main/java/practiceproblems/parentheses/ScoreOfParentheses.java b/src/main/java/strings/parentheses/ScoreOfParentheses.java similarity index 97% rename from src/main/java/practiceproblems/parentheses/ScoreOfParentheses.java rename to src/main/java/strings/parentheses/ScoreOfParentheses.java index 30f3d58..f514af4 100644 --- a/src/main/java/practiceproblems/parentheses/ScoreOfParentheses.java +++ b/src/main/java/strings/parentheses/ScoreOfParentheses.java @@ -1,4 +1,4 @@ -package practiceproblems.parentheses; +package strings.parentheses; import java.util.ArrayDeque; import java.util.Deque; diff --git a/src/main/java/practiceproblems/parentheses/ValidParentheses.java b/src/main/java/strings/parentheses/ValidParentheses.java similarity index 94% rename from src/main/java/practiceproblems/parentheses/ValidParentheses.java rename to src/main/java/strings/parentheses/ValidParentheses.java index 07f490a..4067a1b 100644 --- a/src/main/java/practiceproblems/parentheses/ValidParentheses.java +++ b/src/main/java/strings/parentheses/ValidParentheses.java @@ -1,4 +1,4 @@ -package practiceproblems.parentheses; +package strings.parentheses; import java.util.Stack; diff --git a/src/main/java/practiceproblems/parentheses/ValidParenthesesString.java b/src/main/java/strings/parentheses/ValidParenthesesString.java similarity index 98% rename from src/main/java/practiceproblems/parentheses/ValidParenthesesString.java rename to src/main/java/strings/parentheses/ValidParenthesesString.java index 51c260f..38a9f27 100644 --- a/src/main/java/practiceproblems/parentheses/ValidParenthesesString.java +++ b/src/main/java/strings/parentheses/ValidParenthesesString.java @@ -1,4 +1,4 @@ -package practiceproblems.parentheses; +package strings.parentheses; /** * tricky braces diff --git a/src/main/java/trees/BST/BSTIterator.java b/src/main/java/trees/BST/BSTIterator.java new file mode 100644 index 0000000..cd57c3f --- /dev/null +++ b/src/main/java/trees/BST/BSTIterator.java @@ -0,0 +1,33 @@ +package trees.BST; + +import trees.TreeNode; + +import java.util.ArrayDeque; +import java.util.Deque; + +// https://leetcode.com/problems/binary-search-tree-iterator/ +public class BSTIterator { + Deque stack; + + public BSTIterator(TreeNode root) { + stack = new ArrayDeque<>(); + for (TreeNode node = root; node != null; node = node.left) { + stack.push(node); + } + } + + public int next() { + if (!hasNext()) return -1; + TreeNode curr = stack.pop(); + TreeNode right = curr.right; + while (right != null) { + stack.push(right); + right = right.left; + } + return curr.val; + } + + public boolean hasNext() { + return !stack.isEmpty(); + } +} diff --git a/src/main/java/trees/BST/CeilAndFloor.java b/src/main/java/trees/BST/CeilAndFloor.java new file mode 100644 index 0000000..2af4544 --- /dev/null +++ b/src/main/java/trees/BST/CeilAndFloor.java @@ -0,0 +1,110 @@ +package trees.BST; + +import trees.TreeNode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class CeilAndFloor { + + public int[] ceilAndFloor(TreeNode root, int key) { + int[] result = new int[2]; + ceilAndFloorHelper(root, key, result); + return result; + } + + public void ceilAndFloorHelper(TreeNode root, int key, int[] result) { + if (root == null) return; + + if (root.val == key) { + result[0] = root.val; + result[1] = root.val; + return; + } + + if (root.val > key) { + result[0] = root.val; + ceilAndFloorHelper(root.left, key, result); + } else { + result[1] = root.val; + ceilAndFloorHelper(root.right, key, result); + } + } + + public List> closestNodes(TreeNode root, List queries) { + List> result = new ArrayList<>(); + if (root == null) + return result; + + for (int q : queries) { + int[] ceilAndFloor = new int[2]; + Arrays.fill(ceilAndFloor, -1); + closestNodesHelper(root, q, ceilAndFloor); + result.add(Arrays.asList(ceilAndFloor[0], ceilAndFloor[1])); + } + + return result; + } + + //In the worst case (skewed tree), this can become O(n), where n is the number of nodes. + // or we can use inorder traversal to get the sorted list of nodes and then find the closest nodes + //using binary search + public void closestNodesHelper(TreeNode root, int target, int[] ceilAndFloor) { + if (root == null) + return; + + if (root.val == target) { + ceilAndFloor[0] = root.val; + ceilAndFloor[1] = root.val; + return; + } + + if (root.val > target) { + ceilAndFloor[1] = root.val; + closestNodesHelper(root.left, target, ceilAndFloor); + } else { + ceilAndFloor[0] = root.val;// ceil + + closestNodesHelper(root.right, target, ceilAndFloor); + } + } + + //private List closestBinarySearch(List sortedTree, int target){ + // int min = Integer.MIN_VALUE, max = Integer.MAX_VALUE; + // int left = 0, right = sortedTree.size() - 1; + // + // + // // TreeNode curr = root; + // + // while(left <= right){ + // int mid = left + (right - left) / 2; + // int midVal = sortedTree.get(mid); + // + // if(midVal == target){ + // min = midVal; + // max = midVal; + // break; + // } + // + // // min_t is the largest value in the tree that is smaller than or equal to + // // min_t= Max(Set of values < target) + // // Set of values < target are + // // max_t= Min(Set of values > target) + // + // if(midVal < target){ + // min = Math.max(min, midVal); + // left = mid + 1; + // }else { + // max = Math.min(max, midVal); + // right = mid - 1; + // } + // } + // + // min = (min == Integer.MIN_VALUE) ? -1 : min; + // max = (max == Integer.MAX_VALUE) ? -1 : max; + // + // return List.of(min, max); + // } + +} diff --git a/src/main/java/practiceproblems/ConstructBSTFromPreorder.java b/src/main/java/trees/BST/ConstructBSTFromPreorder.java similarity index 82% rename from src/main/java/practiceproblems/ConstructBSTFromPreorder.java rename to src/main/java/trees/BST/ConstructBSTFromPreorder.java index 8dfe00d..bb1acef 100644 --- a/src/main/java/practiceproblems/ConstructBSTFromPreorder.java +++ b/src/main/java/trees/BST/ConstructBSTFromPreorder.java @@ -1,4 +1,4 @@ -package practiceproblems; +package trees.BST; import java.util.ArrayDeque; import java.util.Deque; @@ -29,6 +29,15 @@ private TreeNode helper(int[] preorder, int start, int end) { TreeNode node = new TreeNode(preorder[start]); int i; + // 8, 3, 1, 6, 4, 7, 10, 14, 13 + // Root is 8 (index 0) + //The loop finds that 10 (index 6) is the first element greater than 8 + //So, elements from index 1 to 5 form the left subtree, and 6 to 8 form the right subtree + // + //For the left subtree {3, 1, 6, 4, 7}: + //Root is 3 (index 1) + //The loop finds that 6 (index 3) is the first element greater than 3 + //So, {1} forms the left subtree of 3, and {6, 4, 7} forms the right subtree for (i = start; i <= end; i++) { if (preorder[i] > node.val) break; diff --git a/src/main/java/trees/DeleteBST.java b/src/main/java/trees/BST/DeleteBST.java similarity index 66% rename from src/main/java/trees/DeleteBST.java rename to src/main/java/trees/BST/DeleteBST.java index 7502408..75346ec 100644 --- a/src/main/java/trees/DeleteBST.java +++ b/src/main/java/trees/BST/DeleteBST.java @@ -1,7 +1,15 @@ -package trees; +package trees.BST; + +import trees.TreeNode; /** * tricky + * https://leetcode.com/problems/delete-node-in-a-bst/ + * + * if the node has no children, simply remove it by returning null + * if the node has one child, return the child + * if the node has two children, find the inorder successor of the node. + * Copy the value of the inorder successor to the node and then delete the inorder successor by calling step 1. */ public class DeleteBST { public TreeNode deleteNode(TreeNode root, int key) { @@ -9,10 +17,8 @@ public TreeNode deleteNode(TreeNode root, int key) { if (key < root.val) { root.left = deleteNode(root.left, key); - return root; } else if (key > root.val) { root.right = deleteNode(root.right, key); - return root; } else { if (root.left == null && root.right == null) return null; @@ -21,9 +27,9 @@ public TreeNode deleteNode(TreeNode root, int key) { else { root.val = getRightMin(root.right); root.right = deleteNode(root.right, root.val); - return root; } } + return root; } public int getRightMin(TreeNode root) { diff --git a/src/main/java/trees/GenerateAllPossibleBST.java b/src/main/java/trees/BST/GenerateAllPossibleBST.java similarity index 98% rename from src/main/java/trees/GenerateAllPossibleBST.java rename to src/main/java/trees/BST/GenerateAllPossibleBST.java index b537c01..77e63da 100644 --- a/src/main/java/trees/GenerateAllPossibleBST.java +++ b/src/main/java/trees/BST/GenerateAllPossibleBST.java @@ -1,4 +1,6 @@ -package trees; +package trees.BST; + +import trees.TreeNode; import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/java/trees/BST/InorderSuccessorPredecessor.java b/src/main/java/trees/BST/InorderSuccessorPredecessor.java new file mode 100644 index 0000000..cc03086 --- /dev/null +++ b/src/main/java/trees/BST/InorderSuccessorPredecessor.java @@ -0,0 +1,59 @@ +package trees.BST; + +import trees.TreeNode; + +/** + * https://leetcode.com/problems/inorder-successor-in-bst/ + */ +public class InorderSuccessorPredecessor { + TreeNode result = null; + + public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { + helperFn(root, p); + return result; + } + + public void helperFn(TreeNode root, TreeNode p) { + if (root == null) return; + + if (root.val > p.val) { + result = root; + helperFn(root.left, p); + } else { + helperFn(root.right, p); + } + + } + + // tricky tree traversal + // predecessor go to left first and then go right till end + // so place the result assignment (pre = cur) in the go right block + private TreeNode findPredecessor(TreeNode root, TreeNode p) { + TreeNode predecessor = null; + while (root != null) { + if (root.val >= p.val) { + root = root.left; + } else { + predecessor = root; + root = root.right; + } + } + return predecessor; + } + + // successor go to right first and then go left till end + // so place the result assignment (pre = cur) in the go left block + private TreeNode findSuccessor(TreeNode root, TreeNode p) { + TreeNode successor = null; + while (root != null) { + if (p.val >= root.val) { + root = root.right; + } else { + successor = root; + root = root.left; + } + } + return successor; + } +} + diff --git a/src/main/java/trees/BST/InsertBST.java b/src/main/java/trees/BST/InsertBST.java new file mode 100644 index 0000000..a103d3b --- /dev/null +++ b/src/main/java/trees/BST/InsertBST.java @@ -0,0 +1,57 @@ +package trees.BST; + +import trees.TreeNode; + +// tricky +public class InsertBST { + + public TreeNode insertIntoBST(TreeNode root, int val) { + if (root == null) { + return new TreeNode(val); + } + + if (val < root.val) { + root.left = insertIntoBST(root.left, val); + } else if (val > root.val) { + root.right = insertIntoBST(root.right, val); + } + + return root; + } + + // the solution is simple, just traverse the tree and find the correct place to insert the node + // for example + // 4 + // / \ + // 2 6 + // / \ + // 1 3 + // Inserting 5: + // + //Start at root (4) + //5 > 4, go right to 6 + //5 < 6, try to go left but left is null + //Insert 5 as left child of 6 + public TreeNode insertIntoBSTIterative(TreeNode curr, int val) { + if (curr == null) return new TreeNode(val); + TreeNode root = curr; + while (true) { + // this is a lazy update, the target node is found in one iteration + // and the new node is inserted in the next iteration + if (val < root.val) { + if (root.left == null) { + root.left = new TreeNode(val); + break; + } + root = root.left; + } else { + if (root.right == null) { + root.right = new TreeNode(val); + break; + } + root = root.right; + } + } + return curr; + } +} diff --git a/src/main/java/trees/IsValidBST.java b/src/main/java/trees/BST/IsValidBST.java similarity index 52% rename from src/main/java/trees/IsValidBST.java rename to src/main/java/trees/BST/IsValidBST.java index eaf507f..671063f 100644 --- a/src/main/java/trees/IsValidBST.java +++ b/src/main/java/trees/BST/IsValidBST.java @@ -1,4 +1,6 @@ -package trees; +package trees.BST; + +import trees.TreeNode; import java.util.ArrayDeque; import java.util.Deque; @@ -24,4 +26,16 @@ public boolean isValidBST(TreeNode root) { } return true; } + + public boolean isValidBSTRecursive(TreeNode root) { + if (root == null) return true; + if (root.right == null && root.left == null) return true; + return isValidBSTHelper(root, Long.MIN_VALUE, Long.MAX_VALUE); + } + + public boolean isValidBSTHelper(TreeNode root, long lowerBound, long upperBound) { + if (root == null) return true; + if (root.val <= lowerBound || root.val >= upperBound) return false; + return isValidBSTHelper(root.left, lowerBound, root.val) && isValidBSTHelper(root.right, root.val, upperBound); + } } diff --git a/src/main/java/trees/BST/KthSmallestOrLargest.java b/src/main/java/trees/BST/KthSmallestOrLargest.java new file mode 100644 index 0000000..c4e494a --- /dev/null +++ b/src/main/java/trees/BST/KthSmallestOrLargest.java @@ -0,0 +1,46 @@ +package trees.BST; + +import trees.TreeNode; +// https://leetcode.com/problems/kth-smallest-element-in-a-bst/ +public class KthSmallestOrLargest { + + // doing inorder traversal and keeping track of the kth element + public int kthSmallest(TreeNode root, int k) { + int[] result = new int[]{0,0}; + kthSmallestHelper(root,k, result); + return result[1]; + } + + public void kthSmallestHelper(TreeNode root, int k, int[] result){ + if(root==null || result[0]>k) return ; + + kthSmallestHelper(root.left,k,result); + result[0]++; + if (result[0]==k){ + result[1]=root.val; + return; + } + kthSmallestHelper(root.right,k,result); + + } + + // doing reverse inorder traversal and keeping track of the kth element + public int kthLargest(TreeNode root, int k) { + int[] result = new int[]{0,0}; + kthSmallestHelper(root,k, result); + return result[1]; + } + + public void kthLargestHelper(TreeNode root, int k, int[] result){ + if(root==null || result[0]>k) return ; + + kthSmallestHelper(root.right,k,result); + result[0]++; + if (result[0]==k){ + result[1]=root.val; + return; + } + kthSmallestHelper(root.left,k,result); + + } +} diff --git a/src/main/java/trees/BST/LargestBST.java b/src/main/java/trees/BST/LargestBST.java new file mode 100644 index 0000000..5baa329 --- /dev/null +++ b/src/main/java/trees/BST/LargestBST.java @@ -0,0 +1,105 @@ +package trees.BST; + +import trees.TreeNode; + +/** + * tricky BST + */ +public class LargestBST { + public int largestBSTSubtree(TreeNode root) { + if (root == null) return 0; + NodeValue result = largestBSTSubtreeHelper(root); + return result.maxSize; + + } + + + // Idea for a valid BST is if a node root has +// +// root +// / \ +// / \ +// largest in left smallest in right +// +// if root > 'Max left' then it is greater than all the nodes in the left subtree +// if root < 'Min right' then it is smaller than the all the nodes in the right subtree +// +// in case of non bst then pass +INF as left max and -INF as right min which will break the result and then keep the size of the previous result +// +// if root == null pass leftmax as -INF and rightMin as +INF*/ + + // 10 + // / \ + // 5 15 + // / \ / \ + // 1 8 12 20 + // / + // 7 + //We start at the root (10). We recursively call the function on the left and right subtrees. + //Let's follow the left subtree (5) first: + // + //For node 1: It's a leaf, so we return (1, 1, 1) (minNode, maxNode, size) + //For node 7: It's a leaf, so we return (7, 7, 1) + //For node 8: + //Left child (7) < 8 < Right child (null), so it's a BST + //We return (7, 8, 2) + //For node 5: + //1 < 5 < 8, so this subtree is a BST + //We return (1, 8, 4) + // + // + //Now the right subtree (15): + // + //For nodes 12 and 20: They're leaves, so we return (12, 12, 1) and (20, 20, 1) + //For node 15: + //12 < 15 < 20, so this subtree is a BST + //We return (12, 20, 3) + // + // + //Back to the root (10): + // + //Left subtree: (1, 8, 4) + //Right subtree: (12, 20, 3) + //8 < 10 < 12, so the entire tree is a BST + //We return (1, 20, 8) - This is the final result + public NodeValue largestBSTSubtreeHelper(TreeNode root) { + // The reason for this seemingly counterintuitive choice is to ensure + // that these null node values don't interfere with the BST property checks in the parent nodes + //For a null left child, left.maxNode is MIN_VALUE, so root.val is always greater. + //For a null right child, right.minNode is MAX_VALUE, so root.val is always less. + if (root == null) { + return new NodeValue(Integer.MAX_VALUE, Integer.MIN_VALUE, 0); + } + + + //The `NodeValue` information fo the current node is updated + //based on the information from the left and right subtree properties + //ie. the left subtree’s maximum node is less than the current node + //and the right subtree’s minimum node is greater than the current node. + NodeValue left = largestBSTSubtreeHelper(root.left); + NodeValue right = largestBSTSubtreeHelper(root.right); + + int size = Math.max(left.maxSize, right.maxSize); + + if (left.maxNode < root.val && root.val < right.minNode) { + return new NodeValue(Math.min(root.val, left.minNode), Math.max(root.val, right.maxNode), left.maxSize + right.maxSize + 1); + } + //non bst is found, then pass +INF as left max and -INF as right min which will break the result and then keep the size of the previous result + return new NodeValue(Integer.MIN_VALUE, Integer.MAX_VALUE, size); + + + } + + + static class NodeValue { + int maxSize; + int maxNode; + int minNode; + + public NodeValue(int minNode, int maxNode, int maxSize) { + this.minNode = minNode; + this.maxNode = maxNode; + this.maxSize = maxSize; + } + } +} diff --git a/src/main/java/trees/BST/Search.java b/src/main/java/trees/BST/Search.java new file mode 100644 index 0000000..0e81944 --- /dev/null +++ b/src/main/java/trees/BST/Search.java @@ -0,0 +1,23 @@ +package trees.BST; + +import trees.TreeNode; + +// https://leetcode.com/problems/search-in-a-binary-search-tree/ +public class Search { + public TreeNode searchBST(TreeNode root, int val) { + if (root == null) return null; + + if (root.val == val) return root; + + TreeNode result = null; + if (root.val > val) { + result = searchBST(root.left, val); + } + + if (root.val < val) { + result = searchBST(root.right, val); + } + + return result; + } +} diff --git a/src/main/java/trees/BST/SerializeDeserializeBST.java b/src/main/java/trees/BST/SerializeDeserializeBST.java new file mode 100644 index 0000000..2c5e69c --- /dev/null +++ b/src/main/java/trees/BST/SerializeDeserializeBST.java @@ -0,0 +1,60 @@ +package trees.BST; + + +import trees.TreeNode; + +import java.util.LinkedList; +import java.util.Queue; + +class SerializeDeserializeBST { + private static final String NULL_SYMBOL = "X"; + private static final String DELIMITER = ","; + + // Encodes a tree to a single string. + public String serialize(TreeNode root) { + if (root == null) { + return NULL_SYMBOL; + } + + StringBuilder sb = new StringBuilder(); + String left = serialize(root.left); + String right = serialize(root.right); + // root, left, right pre-order traversal + sb.append(root.val).append(DELIMITER).append(left).append(DELIMITER).append(right); + + return sb.toString(); + } + + // Decodes your encoded data to tree. + public TreeNode deserialize(String data) { + if (data.isEmpty()) { + return null; + } + Queue nodes = new LinkedList<>(); + for (String s : data.split(DELIMITER)) { + if (s.equals(NULL_SYMBOL)) + continue; + nodes.offer(Integer.parseInt(s)); + } + return deserializeHelper(nodes); + } + + public TreeNode deserializeHelper(Queue treeValues) { + if (treeValues.isEmpty()) return null; + + Integer rootVal = treeValues.poll(); + TreeNode root = new TreeNode(rootVal); + + Queue smallerValues = new LinkedList<>(); + + while (!treeValues.isEmpty() && treeValues.peek() < rootVal) { + smallerValues.offer(treeValues.poll()); + } + root.left = deserializeHelper(smallerValues); + root.right = deserializeHelper(treeValues); + return root; + + + } + +} \ No newline at end of file diff --git a/src/main/java/trees/SortedArrayToBST.java b/src/main/java/trees/BST/SortedArrayToBST.java similarity index 97% rename from src/main/java/trees/SortedArrayToBST.java rename to src/main/java/trees/BST/SortedArrayToBST.java index e22720a..178a094 100644 --- a/src/main/java/trees/SortedArrayToBST.java +++ b/src/main/java/trees/BST/SortedArrayToBST.java @@ -1,4 +1,4 @@ -package trees; +package trees.BST; public class SortedArrayToBST { diff --git a/src/main/java/trees/BST/SwapRecoverBST.java b/src/main/java/trees/BST/SwapRecoverBST.java new file mode 100644 index 0000000..8049526 --- /dev/null +++ b/src/main/java/trees/BST/SwapRecoverBST.java @@ -0,0 +1,56 @@ +package trees.BST; + +import trees.TreeNode; + +// https://leetcode.com/problems/recover-binary-search-tree/ +public class SwapRecoverBST { + + TreeNode firstElement = null; + TreeNode secondElement = null; + TreeNode prevElement = null; + + public void recoverTree(TreeNode root) { + + // In order traversal to find the two elements + traverse(root); + // Swap the values of the two nodes + int temp = firstElement.val; + firstElement.val = secondElement.val; + secondElement.val = temp; + } + + private void traverse(TreeNode root) { + + if (root == null) + return; + + traverse(root.left); + // Let's assume this is the original in-order traversal sequence of BST: 1 2 3 4 5 + // If 2 and 3 get swapped, it becomes 1 3 2 4 5 and + //there is only one time that you will have prev.val >= root.val + // If 2 and 4 get swapped, it becomes 1 4 3 2 5 and + //there are two times that you will have prev.val >= root.val + + //When we find the first violation of the BST property (where a node's value is less than or equal to its predecessor), + // we set firstElement to prev. + // This is because in an inorder traversal of a BST, each node should be greater than the previous node + // [1, 6, 3, 4, 5, 2, 7]. + //During inorder traversal: + //When we reach 3, we find that 3 <= 6 is true. This is our first violation. We set firstElement = prev (which is 6). + //We continue until we reach 2. We find that 2 <= 5 is true. + // This is our second violation. We set secondElement = root (which is 2). + if (prevElement != null) { + if (firstElement == null && prevElement.val >= root.val) { + firstElement = prevElement; + } + + //When we find a second violation (or the continuation of the first violation), we set secondElement to the current root. + // This is because this node is smaller than it should be in the BST order. + if (firstElement != null && prevElement.val >= root.val) { + secondElement = root; + } + } + prevElement = root; + traverse(root.right); + } +} \ No newline at end of file diff --git a/src/main/java/trees/TwoSumTree.java b/src/main/java/trees/BST/TwoSumTree.java similarity index 95% rename from src/main/java/trees/TwoSumTree.java rename to src/main/java/trees/BST/TwoSumTree.java index eed6a58..9f4978d 100644 --- a/src/main/java/trees/TwoSumTree.java +++ b/src/main/java/trees/BST/TwoSumTree.java @@ -1,8 +1,10 @@ -package trees; +package trees.BST; + +import trees.TreeNode; import java.util.ArrayList; import java.util.List; - +// https://leetcode.com/problems/two-sum-iv-input-is-a-bst/ public class TwoSumTree { public boolean findTargetExtraSpace(TreeNode root, int k) { diff --git a/src/main/java/trees/BoundaryTraversal.java b/src/main/java/trees/BoundaryTraversal.java new file mode 100644 index 0000000..104714c --- /dev/null +++ b/src/main/java/trees/BoundaryTraversal.java @@ -0,0 +1,66 @@ +package trees; + +import java.util.*; + +public class BoundaryTraversal { + + // the level order traversal is not needed here + // this requires dfs approach + // left side, right side view is totally different from boundary traversal + public List boundaryOfBinaryTree(TreeNode root) { + if (root == null) { + return Collections.emptyList(); + } + List res = new ArrayList<>(); + + // root + if (!isLeaf(root)) { + res.add(root.val); + } + + // left boundary + TreeNode t = root.left; + while (t != null) { + if (!isLeaf(t)) { + res.add(t.val); + } + t = t.left == null ? t.right : t.left; + } + + // leaves + addLeaves(root, res); + + // right boundary(reverse order) + Deque s = new ArrayDeque<>(); + t = root.right; + while (t != null) { + if (!isLeaf(t)) { + s.offer(t.val); + } + t = t.right == null ? t.left : t.right; + } + while (!s.isEmpty()) { + res.add(s.pollLast()); + } + + // output + return res; + } + + private void addLeaves(TreeNode root, List res) { + if (isLeaf(root)) { + res.add(root.val); + return; + } + if (root.left != null) { + addLeaves(root.left, res); + } + if (root.right != null) { + addLeaves(root.right,res); + } + } + + private boolean isLeaf(TreeNode node) { + return node != null && node.left == null && node.right == null; + } +} diff --git a/src/main/java/trees/CompleteBinaryTreeInserter.java b/src/main/java/trees/CompleteBinaryTreeInserter.java new file mode 100644 index 0000000..5e93be6 --- /dev/null +++ b/src/main/java/trees/CompleteBinaryTreeInserter.java @@ -0,0 +1,47 @@ +package trees; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * https://leetcode.com/problems/complete-binary-tree-inserter/ + * + * tricky + */ +public class CompleteBinaryTreeInserter { + private final TreeNode root; + + private final Queue queue; + + public CompleteBinaryTreeInserter(TreeNode root) { + this.root = root; + this.queue = new LinkedList<>(); + queue.add(root); + // iterate till we encounter first non-full node + while (queue.peek()!=null && queue.peek().left != null && queue.peek().right != null) { + TreeNode node = queue.poll(); + queue.offer(node.left); + queue.offer(node.right); + } + if (queue.peek()!=null && queue.peek().left != null) { + queue.offer(queue.peek().left); + } + } + + public int insert(int val) { + TreeNode node = new TreeNode(val); + TreeNode parent = queue.peek(); + if (parent.left == null) { + parent.left = node; + } else if (parent.right == null) { + parent.right = node; + queue.poll(); // remove parent from queue as it is full + } + queue.add(node); + return parent.val; + } + + public TreeNode get_root() { + return root; + } +} diff --git a/src/main/java/trees/ConstructTreeFromInorderAndPostorder.java b/src/main/java/trees/ConstructTreeFromInorderAndPostorder.java new file mode 100644 index 0000000..6f64199 --- /dev/null +++ b/src/main/java/trees/ConstructTreeFromInorderAndPostorder.java @@ -0,0 +1,111 @@ +package trees; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.HashMap; +import java.util.Map; + +//https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal + +public class ConstructTreeFromInorderAndPostorder { + int postorderIndex; + public TreeNode buildTree(int[] inorder, int[] postorder) { + + postorderIndex = postorder.length - 1; + // build a hashmap to store value -> its index relations + Map inorderIndexMap = new HashMap<>(); + for (int i = 0; i < inorder.length; i++) { + inorderIndexMap.put(inorder[i], i); + } + + return arrayToTree(postorder, 0, postorder.length - 1, inorderIndexMap); + } + + private TreeNode arrayToTree(int[] postorder, int left, int right, Map inorderIndexMap) { + // if there are no elements to construct the tree + if (left > right) return null; + + // select the preorder_index element as the root and increment it + int rootValue = postorder[postorderIndex]; + postorderIndex--; + TreeNode root = new TreeNode(rootValue); + + // build left and right subtree + // excluding inorderIndexMap[rootValue] element because it's the root + /* + * The intuition behind it is that since postorder: LEFT → RIGHT → ROOT, + * so when we go in reverse order, we must construct the tree in the order of: ROOT → RIGHT → LEFT + */ + root.right = arrayToTree(postorder, inorderIndexMap.get(rootValue) + 1, right, inorderIndexMap); + root.left = arrayToTree(postorder, left, inorderIndexMap.get(rootValue) - 1, inorderIndexMap); + return root; + } + + public TreeNode buildTreeAlternative(int[] inorder, int[] postorder) { + // build a hashmap to store value -> its index relations + Map inorderIndexMap = new HashMap<>(); + for (int i = 0; i < inorder.length; i++) { + inorderIndexMap.put(inorder[i], i); + } + return helperFn(inorder, 0, inorder.length-1, postorder, 0, postorder.length-1, inorderIndexMap); + } + + public TreeNode helperFn(int[] inorder, int iStart, int iEnd, int[] postorder, int ps, int pe, Map map){ + if(iStart>iEnd || ps>pe) return null; + + TreeNode root= new TreeNode(postorder[pe]); + pe--; + int divider=map.get(root.val); + int leftWindow = divider-iStart; + root.left= helperFn(inorder, iStart,divider-1,postorder,ps,ps+leftWindow-1,map); + root.right=helperFn(inorder,divider+1,iEnd,postorder,ps+leftWindow,pe,map); + return root; + } + + + /** + * The core idea is: Starting from the last element of the postorder and inorder array, + * we put elements from postorder array to a stack and each one is the right child of the last one + * until an element in postorder array is equal to the element on the inorder array. + * Then, we pop as many as elements we can from the stack and decrease the mark in inorder array + * until the peek() element is not equal to the mark value or the stack is empty. + * Then, the new element that we are gonna scan from postorder array is the left child of the last element + * we have popped out from the stack. + * @param inorder + * @param postorder + * @return + */ + public TreeNode buildTreeIterative(int[] inorder, int[] postorder) { + if (inorder.length == 0) return null; + int postOrderPos = postorder.length - 1; + Deque stack = new ArrayDeque<>(); + // last element in the postorder is the root of the tree + TreeNode root = new TreeNode(postorder[postOrderPos--]); + stack.push(root); + TreeNode node = null; + int inorderPos = inorder.length - 1; + + for (; postOrderPos >= 0; postOrderPos--) { + TreeNode cur = new TreeNode(postorder[postOrderPos]); + //pop till all the elements matching inorder elements are removed from stack + while (!stack.isEmpty() && stack.peek().val == inorder[inorderPos]) { + node = stack.pop(); + inorderPos--; + } + if (node != null) { + node.left = cur; + node = null; + } else { + stack.peek().right = cur; + } + stack.push(cur); + } + return root; + } + + public static void main(String[] args) { + ConstructTreeFromInorderAndPostorder tree = new ConstructTreeFromInorderAndPostorder(); + TreeNode root = tree.buildTreeIterative(new int[]{4, 2, 5, 1, 6, 3, 7}, new int[]{4, 5, 2, 6, 7, 3, 1}); + System.out.println(root); + } +} \ No newline at end of file diff --git a/src/main/java/practiceproblems/ConstructTreeFromInorderAndPreorder.java b/src/main/java/trees/ConstructTreeFromInorderAndPreorder.java similarity index 67% rename from src/main/java/practiceproblems/ConstructTreeFromInorderAndPreorder.java rename to src/main/java/trees/ConstructTreeFromInorderAndPreorder.java index 7d8976b..4d92986 100644 --- a/src/main/java/practiceproblems/ConstructTreeFromInorderAndPreorder.java +++ b/src/main/java/trees/ConstructTreeFromInorderAndPreorder.java @@ -1,11 +1,7 @@ -package practiceproblems; - -import trees.TreeNode; +package trees; import java.util.Arrays; import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; import java.util.Map; /** @@ -46,6 +42,28 @@ public TreeNode buildTreeHelper(int[] preorder, int left, int right, Map1){ + return -1; + } + return 1+Math.max(left,right); + } +} diff --git a/src/main/java/trees/LargestBST.java b/src/main/java/trees/LargestBST.java deleted file mode 100644 index a2a7b2f..0000000 --- a/src/main/java/trees/LargestBST.java +++ /dev/null @@ -1,68 +0,0 @@ -package trees; - -/** - * tricky BST - */ -public class LargestBST { - - - public int largestBSTSubtree(TreeNode root) { - if (root == null) return 0; - - NodeValue result = largestBSTSubtreeHelper(root); - - return result.maxSize; - - } - - /** - * Idea for a valid BST is if a node root has - * - * root - * / \ - * / \ - * Max left Min right - * - * if root > 'Max left' then it is greater than all the nodes in the left subtree - * if root < 'Min right' then it is smaller than the all the nodes in the right subtree - * - * in case of non bst then pass +INF as left max and -INF as right min which will break the result and then keep the size of the previous result - * - * if root == null pass leftmax as -INF and rightMin as +INF - * - * @param root - * @return - */ - public NodeValue largestBSTSubtreeHelper(TreeNode root) { - if (root == null) return new NodeValue(Integer.MAX_VALUE, Integer.MIN_VALUE, 0); - - - NodeValue left = largestBSTSubtreeHelper(root.left); - NodeValue right = largestBSTSubtreeHelper(root.right); - - int size = Math.max(left.maxSize, right.maxSize); - - if (left.maxNode < root.val && root.val < right.minNode) { - - return new NodeValue(Math.min(root.val, left.minNode), Math.max(root.val, right.maxNode), left.maxSize + right.maxSize + 1); - } - - //non bst is found, then pass +INF as left max and -INF as right min which will break the result and then keep the size of the previous result - return new NodeValue(Integer.MIN_VALUE, Integer.MAX_VALUE, size); - - - } - - - static class NodeValue { - int maxSize; - int maxNode; - int minNode; - - public NodeValue(int minNode, int maxNode, int maxSize) { - this.minNode = minNode; - this.maxNode = maxNode; - this.maxSize = maxSize; - } - } -} diff --git a/src/main/java/trees/LongestUniValuePath.java b/src/main/java/trees/LongestUniValuePath.java new file mode 100644 index 0000000..893181c --- /dev/null +++ b/src/main/java/trees/LongestUniValuePath.java @@ -0,0 +1,27 @@ +package trees; + +// https://leetcode.com/problems/longest-univalue-path/ +public class LongestUniValuePath { + + Integer result=0; + public int longestUnivaluePath(TreeNode root) { + + if(root==null) return 0; + + helperFn(root,root.val); + + return result; + + } + + private int helperFn(TreeNode root, int prevVal){ + if(root==null) return 0; + + int left=helperFn(root.left, root.val); + int right=helperFn(root.right,root.val); + result= Math.max(result,left+right); + if(root.val==prevVal) return 1+Math.max(left,right); + return 0; + } + +} diff --git a/src/main/java/trees/LowestCommonAncestor.java b/src/main/java/trees/LowestCommonAncestor.java index f8d6fd2..e8769da 100644 --- a/src/main/java/trees/LowestCommonAncestor.java +++ b/src/main/java/trees/LowestCommonAncestor.java @@ -3,45 +3,51 @@ import java.util.HashSet; import java.util.Set; +//https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/ +//https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/ public class LowestCommonAncestor { public TreeNode lowestCommonAncestorBinarySearchTree(TreeNode root, TreeNode p, TreeNode q) { while (root != null) { + // 1st one is that if both p & q are smaller than the root then call the left subtree if (root.val > p.val && root.val > q.val) root = root.left; + // 2nd if both p & q are greater than the root then call the right subtree else if (root.val < p.val && root.val < q.val) root = root.right; else return root; } + // if(root==null) return null; + // + // if(root.val>p.val && root.val>q.val){ + // return lowestCommonAncestor(root.left,p,q); + // }else if(root.val -2 -> 5 in the left subtree) */ public class MaxPathSum { @@ -17,17 +25,52 @@ public int maxPathSum(TreeNode root) { return result[0]; } + /** + * -10 + * / \ + * 9 20 + * / \ / \ + * -4 3 15 7 + + * For node 9: + * leftRootSum = max(0, -4) = 0 // We use max(0, value) to ignore negative paths + * rightRootSum = max(0, 3) = 3 + * rootPathSum = 0 + 3 + 9 = 12 + * Update result[0] to 12 + * Return 9 + max(0, 3) = 12 to parent + + * For node 20: + + * leftRootSum = max(0, 15) = 15 + * rightRootSum = max(0, 7) = 7 + * rootPathSum = 15 + 7 + 20 = 42 + * Update result[0] to 42 + * Return 20 + max(15, 7) = 35 to parent + + * For the root (-10): + * leftRootSum = max(0, 12) = 12 + * rightRootSum = max(0, 35) = 35 + * rootPathSum = 12 + 35 + (-10) = 37 + * result[0] remains 42 (from step 3) + * Return -10 + max(12, 35) = 25 to parent (which doesn't exist) + */ + public int maxPathSumUtil(TreeNode root, int[] result) { if (root == null) return 0; - + //We use max(0, value) when calculating leftRootSum and rightRootSum. + // This ensures we don't include negative paths that would decrease our sum. int leftRootSum = Math.max(0, maxPathSumUtil(root.left, result)); int rightRootSum = Math.max(0, maxPathSumUtil(root.right, result)); - + //By adding these three components, we get the sum of the path that starts from the left subtree, + // goes through the root, and ends in the right subtree (or vice versa). + //Negative values can be part of the maximum path if they're outweighed by positive values. + // In our example, the -10 at the root is part of the path 9 -> -10 -> 20 -> 15, which sums to 34. int rootPathSum = rightRootSum + leftRootSum + root.val; result[0] = Math.max(rootPathSum, result[0]); + //This represents the maximum sum of a path from the current node to one of its subtrees. return root.val + Math.max(leftRootSum, rightRootSum); } } diff --git a/src/main/java/trees/MaxWidthOfBinaryTree.java b/src/main/java/trees/MaxWidthOfBinaryTree.java index 779493c..1a2bba0 100644 --- a/src/main/java/trees/MaxWidthOfBinaryTree.java +++ b/src/main/java/trees/MaxWidthOfBinaryTree.java @@ -1,32 +1,17 @@ package trees; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.Map; -import java.util.Queue; +import java.util.*; /** - * tricky level order traversal - * - * Given a binary tree, write a function to get the maximum width of the given tree. - * The width of a tree is the maximum width among all levels. - * The binary tree has the same structure as a full binary tree, but some nodes are null - * - * Input: - - 1 - / \ - 3 2 - / \ - 5 9 - / \ - 6 7 -Output: 8 -The maximum width existing in the fourth level with the length 8 (6,null,null,null,null,null,null,7). + * tricky level order and dfs traversal */ +//https://leetcode.com/problems/maximum-width-of-binary-tree/ public class MaxWidthOfBinaryTree { + //Considering nodes are in an array, + //left child of any node at index i should be at index 2i. + //right child of any node at index i should be ar index 2i+1. // Each time a node is traversed, the position of the node(as it is in a full binary tree) is stored in the HashMap. //If the position of the parent node is 'n', then the left child is '2 * n' and the right child is '2 * n + 1'. //The width of each level is the last node's position in this level subtracts the first node's position in this level plus 1. @@ -61,4 +46,49 @@ public int widthOfBinaryTree(TreeNode root) { return maxWidth; } + + public int widthOfBinaryTreeDFS(TreeNode root) { + if (root == null) { + return 0; + } + return helper(root, 0, 1, new ArrayList()); + + } + + private int helper(TreeNode root, int depth, int index, List list) { + if (root == null) { + return 0; + } + //add index of leftmost node to list, at depth position in list + //The condition depth == list.size() checks if we're seeing a new depth for the first time. + //We only add to the list when we encounter a new depth, ensuring we always store the leftmost node at each level. + //Depth Tree List + // 0 1 [1] + // / \ + // 1 2 3 [1,2] + // / \ \ + // 2 4 5 6 [1,2,4] + // / + // 3 7 [1,2,4,7] + //When we first reach depth 2 at node 4: + // + //depth = 2 + //list.size() = 2 (contains [1, 2] from previous depths) + //Since depth == list.size(), we add 4's index to the list + //Now list becomes [1, 2, 4] + // + // + //When we reach node 5, also at depth 2: + // + //depth = 2 + //list.size() = 3 (contains [1, 2, 4]) + //Since depth != list.size(), we don't add 5's index + if (depth == list.size()) { + list.add(index); + } + int currWidth = index - list.get(depth) + 1; + int leftWidth = helper(root.left, depth + 1, index * 2, list); + int rightWidth = helper(root.right, depth + 1, index * 2 + 1, list); + return Math.max(currWidth, Math.max(leftWidth, rightWidth)); + } } \ No newline at end of file diff --git a/src/main/java/trees/MorrisTraversal.java b/src/main/java/trees/MorrisTraversal.java new file mode 100644 index 0000000..0fcc0ee --- /dev/null +++ b/src/main/java/trees/MorrisTraversal.java @@ -0,0 +1,104 @@ +package trees; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +// https://youtu.be/80Zug6D1_r4 +// https://takeuforward.org/data-structure/morris-inorder-traversal-of-a-binary-tree/ +public class MorrisTraversal { + + // Morris Traversal is a way to traverse the tree without using any extra space. + public List inorderTraversal(TreeNode root) { + if (root == null) return Collections.emptyList(); + List result = new ArrayList<>(); + + TreeNode current = root; + while (current != null) { + // Case 1: No Left Child + if (current.left == null) { + result.add(current.val); + current = current.right; + continue; + } + // Case 2: Left Child Exists (Find Predecessor) + TreeNode prev = current.left; + while (prev.right != null && prev.right != current) { + prev = prev.right; + } + // If a left child exists, find the predecessor and decide whether to create or remove a thread. + if (prev.right == null) { + prev.right = current; + current = current.left; + } else { + prev.right = null; + result.add(current.val); + current = current.right; + } + + } + + return result; + } + + public List preOrderTraversal(TreeNode root) { + if (root == null) return Collections.emptyList(); + List result = new ArrayList<>(); + + TreeNode current = root; + while (current != null) { + // Case 1: No Left Child + if (current.left == null) { + result.add(current.val); + current = current.right; + continue; + } + // Case 2: Left Child Exists (Find Predecessor) + TreeNode prev = current.left; + while (prev.right != null && prev.right != current) { + prev = prev.right; + } + // If a left child exists, find the predecessor and decide whether to create or remove a thread. + if (prev.right == null) { + prev.right = current; + result.add(current.val); + current = current.left; + } else { + prev.right = null; + + current = current.right; + } + + } + return result; + } + + + public List postOrderTraversal(TreeNode root) { + if (root == null) return Collections.emptyList(); + List result = new ArrayList<>(); + + TreeNode current = root; + while (current != null) { + if (current.right == null) { + result.add(0, current.val); // Add the current node's value to the beginning of the result list + current = current.left; + continue; + } + TreeNode prev = current.right; + while (prev.left != null && prev.left != current) { + prev = prev.left; + } + if (prev.left == null) { + prev.left = current; + result.add(0, current.val); // Add the current node's value to the beginning of the result list + current = current.right; + } else { + prev.left = null; + current = current.left; + } + + } + return result; + } +} diff --git a/src/main/java/trees/MorrisTraversalTreeToDLL.java b/src/main/java/trees/MorrisTraversalTreeToDLL.java new file mode 100644 index 0000000..902bc4d --- /dev/null +++ b/src/main/java/trees/MorrisTraversalTreeToDLL.java @@ -0,0 +1,62 @@ +package trees; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * tricky morris traversal + * https://leetcode.com/problems/flatten-binary-tree-to-linked-list/ + * https://youtu.be/sWf7k1x9XR4 + * https://takeuforward.org/data-structure/flatten-binary-tree-to-linked-list/ + */ +public class MorrisTraversalTreeToDLL { + + public void flattenIterativeExtraSpace(TreeNode root) { + Deque stack = new ArrayDeque<>(); + stack.push(root); + while (!stack.isEmpty()) { + TreeNode curr = stack.pop(); + // remember to push right first + //the goal is to convert the given binary tree into a singly-linked list, + // where the left pointer of each node is set to null, and the right pointer is set to the next node in the list. + if (curr.right != null) { + stack.push(curr.right); + } + if (curr.left != null) { + stack.push(curr.left); + } + + if (!stack.isEmpty()) { + curr.right = stack.peek(); + } + curr.left = null; + } + } + + public void flattenMorris(TreeNode root) { + // Handle the null scenario + if (root == null) { + return; + } + TreeNode node = root; + while (node != null) { + // If the node has a left child + if (node.left != null) { + // Find the predecessor node + TreeNode rightmost = node.left; + while (rightmost.right != null) { + rightmost = rightmost.right; + } + // this is the only change from typical morris traversal + // there we assign rightmost.right = node and proceed to node.left + // here we assign rightmost.right = node.right and proceed to node.right + rightmost.right = node.right; + node.right = node.left; + node.left = null; + } + + // move on to the right side of the tree + node = node.right; + } + } +} diff --git a/src/main/java/trees/NodesAtDistanceK.java b/src/main/java/trees/NodesAtDistanceK.java index ad8ac38..60fe4f2 100644 --- a/src/main/java/trees/NodesAtDistanceK.java +++ b/src/main/java/trees/NodesAtDistanceK.java @@ -11,6 +11,9 @@ /** * https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/ + * + * this problem can be asked as Min time taken to burn a binary tree starting from target node + * https://www.geeksforgeeks.org/minimum-time-to-burn-a-tree-starting-from-a-leaf-node/ */ public class NodesAtDistanceK { diff --git a/src/main/java/trees/RootToLeafPaths.java b/src/main/java/trees/RootToLeafPaths.java index 98f287f..65ce013 100644 --- a/src/main/java/trees/RootToLeafPaths.java +++ b/src/main/java/trees/RootToLeafPaths.java @@ -3,24 +3,40 @@ import java.util.LinkedList; import java.util.List; +//https://leetcode.com/problems/binary-tree-paths/ public class RootToLeafPaths { - public void construct_paths(TreeNode root, String path, List paths) { - if (root != null) { - path += "" + root.val; - if ((root.left == null) && (root.right == null)) // if reach a leaf - paths.add(path); // update paths - else { - path += "->"; // extend the current path - construct_paths(root.left, path, paths); - construct_paths(root.right, path, paths); - } + public List binaryTreePaths(TreeNode root) { + var result= new LinkedList(); + binaryTreePathsUtil(root, result, ""); + return result; + } + + public void binaryTreePathsUtil(TreeNode root, List result , String temp ){ + if(root==null) return; + if ( root.left==null && root.right==null){ + result.add(temp+root.val); + return; } + + temp+=(root.val+"->"); + binaryTreePathsUtil(root.left,result,temp); + binaryTreePathsUtil(root.right,result,temp); + } - public List binaryTreePaths(TreeNode root) { - LinkedList paths = new LinkedList<>(); - construct_paths(root, "", paths); - return paths; + public List returnRootToLeafPaths(TreeNode root, int targetVal){ + List result = new LinkedList<>(); + returnRootToLeafPathsUtil(root,result,targetVal); + return result; + } + + public void returnRootToLeafPathsUtil(TreeNode root, List result, int targetVal){ + if(root==null) return; + result.add(root.val); + if(root.val == targetVal) return; + returnRootToLeafPathsUtil(root.left,result,targetVal); + returnRootToLeafPathsUtil(root.right,result,targetVal); + result.remove(result.size()-1); } } diff --git a/src/main/java/practiceproblems/SerializeAndDeserialize.java b/src/main/java/trees/SerializeAndDeserialize.java similarity index 86% rename from src/main/java/practiceproblems/SerializeAndDeserialize.java rename to src/main/java/trees/SerializeAndDeserialize.java index be89f7d..1c6945e 100644 --- a/src/main/java/practiceproblems/SerializeAndDeserialize.java +++ b/src/main/java/trees/SerializeAndDeserialize.java @@ -1,13 +1,10 @@ -package practiceproblems; - -import trees.TreeNode; +package trees; import java.util.Arrays; import java.util.LinkedList; import java.util.Queue; /** - * Serialize and Deserialize Binary Tree - LeetCode: * https://leetcode.com/problems/serialize-and-deserialize-binary-tree/ * The video to explain this code is here: https://www.youtube.com/watch?v=suj1ro8TIVY */ @@ -23,10 +20,13 @@ public String serialize(TreeNode root) { return NULL_SYMBOL; } - String left = serialize(root.left) + DELIMITER; + StringBuilder sb = new StringBuilder(); + String left = serialize(root.left); String right = serialize(root.right); + // root, left, right pre-order traversal + sb.append(root.val).append(DELIMITER).append(left).append(DELIMITER).append(right); - return root.val + DELIMITER + left + right; + return sb.toString(); } public TreeNode deserialize(String data) { @@ -38,7 +38,7 @@ public TreeNode deserializeHelper(Queue nodesLeftToMaterialize) { String valueForNode = nodesLeftToMaterialize.poll(); - if (valueForNode == null || valueForNode.equals(NULL_SYMBOL) || valueForNode.trim().length() == 0) { + if (valueForNode == null || valueForNode.equals(NULL_SYMBOL) || valueForNode.trim().isEmpty()) { return null; } diff --git a/src/main/java/trees/SwapRecoverBST.java b/src/main/java/trees/SwapRecoverBST.java deleted file mode 100644 index 782f4c5..0000000 --- a/src/main/java/trees/SwapRecoverBST.java +++ /dev/null @@ -1,56 +0,0 @@ -package trees; - -import trees.TreeNode; - -public class SwapRecoverBST { - - TreeNode firstElement = null; - TreeNode secondElement = null; - // The reason for this initialization is to avoid null pointer exception in the first comparison when prevElement has not been initialized - TreeNode prevElement = new TreeNode(Integer.MIN_VALUE); - - public void recoverTree(TreeNode root) { - - // In order traversal to find the two elements - traverse(root); - - // Swap the values of the two nodes - int temp = firstElement.val; - firstElement.val = secondElement.val; - secondElement.val = temp; - } - - private void traverse(TreeNode root) { - - if (root == null) - return; - - traverse(root.left); - // Let's assume this is the original in-order traversal sequence of BST: 1 2 3 4 5 - // If 2 and 3 get swapped, it becomes 1 3 2 4 5 and - //there is only one time that you will have prev.val >= root.val - // If 2 and 4 get swapped, it becomes 1 4 3 2 5 and - //there are two times that you will have prev.val >= root.val - - // If during the first time when you find prev.val >= root.val, - //the previous node "prev" MUST be one of two nodes that get swapped. - //However, the current node MAY OR MAY NOT be another node that gets swapped, - //which will depend on whether later during in-order traversal, there is another prev.val >= root.val or not. - // If there is, then the current node "root" during the 2nd time of prev.val >= root.val will be the other node that gets swapped - // Start of "do some business", - // If first element has not been found, assign it to prevElement (refer to 6 in the example above) - if (firstElement == null && prevElement.val >= root.val) { - firstElement = prevElement; - } - - // If first element is found, assign the second element to the root (refer to 2 in the example above) - if (firstElement != null && prevElement.val >= root.val) { - secondElement = root; - } - prevElement = root; - - // End of "do some business" - - traverse(root.right); - } -} \ No newline at end of file diff --git a/src/main/java/trees/TreeToDLL.java b/src/main/java/trees/TreeToDLL.java deleted file mode 100644 index d23f22f..0000000 --- a/src/main/java/trees/TreeToDLL.java +++ /dev/null @@ -1,65 +0,0 @@ -package trees; - -/** - * tricky traversal - * - */ -public class TreeToDLL { - - public void flatten(TreeNode root) { - if (root == null) - return; - flatten(root.left); - flatten(root.right); - TreeNode left = root.left; - TreeNode right = root.right; - root.left = null; - root.right = left; - while (root.right != null) - root = root.right; - root.right = right; - } - - private TreeNode prev = null; - - public void flattenOptimised(TreeNode root) { - if (root == null) - return; - flattenOptimised(root.right); - flattenOptimised(root.left); - root.right = prev; - root.left = null; - prev = root; - } - - public void flattenIterative(TreeNode root) { - - // Handle the null scenario - if (root == null) { - return; - } - - TreeNode node = root; - - while (node != null) { - - // If the node has a left child - if (node.left != null) { - - // Find the predecessor node - TreeNode rightmost = node.left; - while (rightmost.right != null) { - rightmost = rightmost.right; - } - - // rewire the connections - rightmost.right = node.right; - node.right = node.left; - node.left = null; - } - - // move on to the right side of the tree - node = node.right; - } - } -} diff --git a/src/main/java/trees/TreeTraversals.java b/src/main/java/trees/TreeTraversals.java index 2a29ed3..00672d6 100644 --- a/src/main/java/trees/TreeTraversals.java +++ b/src/main/java/trees/TreeTraversals.java @@ -1,24 +1,26 @@ package trees; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Deque; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; -import java.util.TreeMap; +import java.util.*; public class TreeTraversals { + public int index = 0; + public TreeMap> tm; + List nodes = new ArrayList<>(1000); + public List preOrderTraversal(TreeNode root) { if (root == null) return Collections.emptyList(); - + // add root to the stack + // while stack is not empty + // pop the element from the stack + // add it to the result + // if right is not null add it to the stack + // if left is not null add it to the stack + // reason to add right first is because stack is LIFO Deque stack = new ArrayDeque<>(); stack.push(root); List result = new ArrayList<>(); while (!stack.isEmpty()) { - TreeNode temp = stack.pop(); result.add(temp.val); if (temp.left != null) stack.push(temp.left); @@ -49,7 +51,8 @@ public List inorderTraversal(TreeNode root) { } /** - * Just like with in-order traversal we go to the left subtree as long as we can. At the same time we keep adding the nodes to the stack. + * Just like with in-order traversal we go to the left subtree as long as we can. + * At the same time we keep adding the nodes to the stack. * If we can't (left = null) - we try to go to the right subtree. In order to do that we check the last one we added to the stack. * If it has a right subtree and we haven't visited it yet then we go there and repeat steps 1 and 2. * Else we visit the node (also pop out of the stack) 'cause by that time we visited left and right subtrees snd it's time to visit their parent. @@ -62,17 +65,36 @@ public List postorderTraversal(TreeNode root) { List res = new ArrayList<>(); Deque stack = new ArrayDeque<>(); TreeNode cur = root, lastVisited = null; + // 1 + // / \ + // 2 3 + // / \ + // 4 5 + //Initialize: cur = 1, stack = [], res = [] + //Push 1, 2, 4 onto stack. cur = null, stack = [1, 2, 4], res = [] + //Process 4: res = [4], lastVisited = 4, stack = [1, 2] + //Peek at 2, it has right child 5. cur = 5 + //Push 5 onto stack. stack = [1, 2, 5] + //Process 5: res = [4, 5], lastVisited = 5, stack = [1, 2] + //Process 2: res = [4, 5, 2], lastVisited = 2, stack = [1] + //Peek at 1, it has unvisited right child 3. cur = 3 + //Push 3 onto stack. stack = [1, 3] + //Process 3: res = [4, 5, 2, 3], lastVisited = 3, stack = [1] + //Finally, process 1: res = [4, 5, 2, 3, 1], stack = [] while (!stack.isEmpty() || cur != null) { while (cur != null) { stack.push(cur); cur = cur.left; } - TreeNode peek = stack.pop(); + TreeNode peek = stack.peek(); if (peek.right != null && peek.right != lastVisited) { cur = peek.right; } else { res.add(peek.val); + //The lastVisited variable is crucial here. + // It helps us determine whether we've already processed the right child of a node. + // Without it, we might end up in an infinite loop when backtracking from a right child to its parent. lastVisited = stack.pop(); } @@ -81,19 +103,8 @@ public List postorderTraversal(TreeNode root) { return res; } - public int index = 0; - public TreeMap> tm; - - static class Pair { - TreeNode node; - int index; - - public Pair(TreeNode n, int i) { - node = n; - index = i; - } - } - + //https://leetcode.com/problems/vertical-order-traversal-of-a-binary-tree + // question asks for result in vertical order with some order preservation, can be ignored public List> verticalOrder(TreeNode root) { List> res = new ArrayList<>(); tm = new TreeMap<>(); @@ -104,52 +115,85 @@ public List> verticalOrder(TreeNode root) { while (!q.isEmpty()) { Pair cur = q.poll(); - if (!tm.containsKey(cur.index)) tm.put(cur.index, new ArrayList<>()); - tm.get(cur.index).add(cur.node.val); - - if (cur.node.left != null) q.offer(new Pair(cur.node.left, cur.index - 1)); - if (cur.node.right != null) q.offer(new Pair(cur.node.right, cur.index + 1)); + tm.computeIfAbsent(cur.index, k -> new ArrayList<>()).add(cur.node.val); + if (cur.node.left != null) { + q.offer(new Pair(cur.node.left, cur.index - 1)); + } + if (cur.node.right != null) { + q.offer(new Pair(cur.node.right, cur.index + 1)); + } } - for (int key : tm.keySet()) res.add(tm.get(key)); + for (int key : tm.keySet()) { + res.add(tm.get(key)); + } return res; } - List nodes = new ArrayList<>(1000); - - public List boundaryOfBinaryTree(TreeNode root) { + public List> AllIterativeTraversalInOneGo(TreeNode root) { + List preOrder = new ArrayList<>(); + List inOrder = new ArrayList<>(); + List postOrder = new ArrayList<>(); + int PREORDER = 0; + int INORDER = 1; + int POSTORDER = 2; + Deque stack = new ArrayDeque<>(); + stack.push(new Pair(root, PREORDER)); - if (root == null) return nodes; + while (!stack.isEmpty()) { + Pair curr = stack.pop(); + + if (curr.index == PREORDER) { + preOrder.add(curr.node.val); + stack.push(new Pair(curr.node, INORDER)); + if (curr.node.left != null) stack.push(new Pair(curr.node.left, PREORDER)); + } else if (curr.index == INORDER) { + inOrder.add(curr.node.val); + stack.push(new Pair(curr.node, POSTORDER)); + if (curr.node.right != null) stack.push(new Pair(curr.node.right, PREORDER)); + } else { + postOrder.add(curr.node.val); + } + } - nodes.add(root.val); - leftBoundary(root.left); - leaves(root); - rightBoundary(root.right); + return List.of(preOrder, inOrder, postOrder); - return nodes; } - public void leftBoundary(TreeNode root) { - if (root == null || (root.left == null && root.right == null)) return; - nodes.add(root.val); - if (root.left == null) leftBoundary(root.right); - else leftBoundary(root.left); - } + public List rightSideView(TreeNode root) { + List res = new ArrayList<>(); + if (root == null) { + return res; + } + + Queue q = new LinkedList<>(); + q.offer(root); - public void rightBoundary(TreeNode root) { - if (root == null || (root.right == null && root.left == null)) return; - if (root.right == null) rightBoundary(root.left); - else rightBoundary(root.right); - nodes.add(root.val); // add after child visit(reverse) + while (!q.isEmpty()) { + int n = q.size(); + for (int i = 0; i < n; i++) { + TreeNode curNode = q.poll(); // for left assign if curNode != null + if (i == n - 1) { + res.add(curNode.val); + } + if (curNode.left != null) { + q.offer(curNode.left); + } + if (curNode.right != null) { + q.offer(curNode.right); + } + } + } + return res; } - public void leaves(TreeNode root) { - if (root == null) return; - if (root.left == null && root.right == null) { - nodes.add(root.val); - return; + static class Pair { + TreeNode node; + int index; + + public Pair(TreeNode n, int i) { + node = n; + index = i; } - leaves(root.left); - leaves(root.right); } } diff --git a/src/main/java/trees/Zigzag.java b/src/main/java/trees/Zigzag.java new file mode 100644 index 0000000..c8be3fc --- /dev/null +++ b/src/main/java/trees/Zigzag.java @@ -0,0 +1,36 @@ +package trees; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; + +//https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/ +public class Zigzag { + + public List> zigzagTraversal(TreeNode root) { + List> result= new ArrayList<>(); + if(root==null) return result; + + Queue queue= new ArrayDeque<>(); + int level=1; + queue.offer(root); + while(!queue.isEmpty()){ + int n= queue.size(); + List tempList= new ArrayList<>(); + for(int i=0;i