From a59a941945848a686a45c44960871aa2e1452ced Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 10 May 2017 00:01:45 +0200 Subject: [PATCH 001/235] Largest BST Subtree : Accepted solution --- problems/src/tree/LargestBSTSubtree.java | 124 +++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 problems/src/tree/LargestBSTSubtree.java diff --git a/problems/src/tree/LargestBSTSubtree.java b/problems/src/tree/LargestBSTSubtree.java new file mode 100644 index 00000000..69b18bfe --- /dev/null +++ b/problems/src/tree/LargestBSTSubtree.java @@ -0,0 +1,124 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 08/05/2017. + * + * Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest means subtree with largest number of nodes in it. + + Note: + A subtree must include all of its descendants. + Here's an example: + 10 + / \ + 5 15 + / \ \ + 1 8 7 + The Largest BST Subtree in this case is the highlighted one (5-1-8). + The return value is the subtree's size, which is 3. + + Follow up: + Can you figure out ways to solve it with O(n) time complexity? + + Solution: The below solution works with O(n). Validate the BST property from the leaf node and increment the count, as soon as a violation + of BST property is found terminate the count. + * + */ +public class LargestBSTSubtree +{ + /** + * Range class + */ + private class Range + { + int min, max, count; + Range(int min, int max, int count) + { + this.min = min; + this.max = max; + this.count = count; + } + } + + /** + * TreeNode + */ + public static class TreeNode + { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + /** + * Count + */ + private static int count = 0; + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception + { + TreeNode root = new TreeNode(10); + root.left = new TreeNode(9); + root.left.left = new TreeNode(8); + System.out.println(new LargestBSTSubtree().largestBSTSubtree(root)); + } + + /** + * Largest subtree count + * @param root root node + * @return count + */ + public int largestBSTSubtree(TreeNode root) + { + getCount(root); + return count; + } + + /** + * Get count + * @param node root node + * @return Range + */ + private Range getCount(TreeNode node) + { + if(node == null) return null; + Range left = getCount(node.left); + Range right = getCount(node.right); + if(left == null && right == null) + { + count = Math.max(count, 1); + return new Range(node.val, node.val, 1); + } + else if(left == null) + { + if(node.val < right.min && right.count != -1) //check for -1 ensures that there is no violation of BST property + return countMaxAndBuildNewRange(right.count + 1, node.val, right.max); + } + else if(right == null) + { + if(node.val > left.max && left.count != -1) + return countMaxAndBuildNewRange(left.count + 1, left.min, node.val); + } + else if(node.val > left.max && node.val < right.min && right.count != -1 && left.count != -1) + return countMaxAndBuildNewRange(left.count + right.count + 1, left.min, right.max); + return new Range(0, 0, -1); //violation of BST property + } + + /** + * Record max and build new range + * @param sum total sum + * @param min min + * @param max max + * @return new Range + */ + private Range countMaxAndBuildNewRange(int sum, int min, int max) + { + count = Math.max(count, sum); + return new Range(min, max, sum); + } +} From b989a7cb1f87c453e87fe18c0802e4b208fea62c Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 10 May 2017 00:04:02 +0200 Subject: [PATCH 002/235] Readme update and some fixes --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 72f59c18..2b18a016 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Serialize Deserialize Binary Tree](problems/src/design/SerializeDeserializeBinaryTree.java) (Hard) - [Design Twitter](problems/src/design/Twitter.java) (Medium) -#### [Devide and Conquer](problems/src/divide_and_conquer) +#### [Divide and Conquer](problems/src/divide_and_conquer) - [Kth Largest Element In a Array](problems/src/divide_and_conquer/KthLargestElementInAnArray.java) (Medium) - [Search in a 2D Matrix](problems/src/divide_and_conquer/SearchA2DMatrix.java) (Medium) @@ -113,7 +113,7 @@ My accepted leetcode solutions to some of the common interview problems. #### [Stack](problems/src/stack) - [Min Stack](problems/src/stack/MinStack.java) (Easy) -- [Valid Parentheses](problems/src/stack/ValidParentheses.java) (Easy)) +- [Valid Parentheses](problems/src/stack/ValidParentheses.java) (Easy) #### [String](problems/src/string) @@ -137,6 +137,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Convert Preorder and Inorder traversal to Binary Tree](problems/src/tree/PreorderToBT.java) (Medium) - [Sorted Array to BST](problems/src/tree/SortedArrayToBST.java) (Medium) - [Valid Binary Search Tree](problems/src/tree/ValidBinarySearchTree.java) (Medium) +- [Largest BST Subtree](problems/src/tree/LargestBSTSubtree.java) (Medium) #### [Two Pointers](problems/src/two_pointers) From 4515c2a9ae89aeda8ca277033aa41c11fceed183 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 10 May 2017 00:50:34 +0200 Subject: [PATCH 003/235] Closest Binary Search Tree Value : Accepted solution --- .../tree/ClosestBinarySearchTreeValue.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 problems/src/tree/ClosestBinarySearchTreeValue.java diff --git a/problems/src/tree/ClosestBinarySearchTreeValue.java b/problems/src/tree/ClosestBinarySearchTreeValue.java new file mode 100644 index 00000000..3576b231 --- /dev/null +++ b/problems/src/tree/ClosestBinarySearchTreeValue.java @@ -0,0 +1,62 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 10/05/2017. + * Given a non-empty binary search tree and a target value, find the value in the BST that is closest to the target. + + Note: + Given target value is a floating point. + You are guaranteed to have only one unique value in the BST that is closest to the target. + + Solution: Simple dfs recursive algorithm to find the closest match. + Worst case time complexity is O(h) where h is height of the tree + */ +public class ClosestBinarySearchTreeValue +{ + /** + * TreeNode + */ + public static class TreeNode + { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + private double absDiff = Double.MAX_VALUE; + private int closest; + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception + { + TreeNode root = new TreeNode(10); + root.left = new TreeNode(9); + root.left.left = new TreeNode(8); + System.out.println(new ClosestBinarySearchTreeValue().closestValue(root, 7.63354D)); + } + + /** + * Find closest + * @param root Root node + * @param target double target + * @return closest value + */ + public int closestValue(TreeNode root, double target) + { + if(root == null) return closest; + if(Math.abs(target - root.val) < absDiff) + { + absDiff = Math.abs(target - root.val); + closest = root.val; + } + if(root.val > target) + return closestValue(root.left, target); + else return closestValue(root.right, target); + } + +} From a011602e9dc8bb0643887c28a5be9108c190270f Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 10 May 2017 00:51:49 +0200 Subject: [PATCH 004/235] Readme update --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2b18a016..b7d2251a 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Sorted Array to BST](problems/src/tree/SortedArrayToBST.java) (Medium) - [Valid Binary Search Tree](problems/src/tree/ValidBinarySearchTree.java) (Medium) - [Largest BST Subtree](problems/src/tree/LargestBSTSubtree.java) (Medium) +- [Closest Binary Search Tree Value](problems/src/tree/ClosestBinarySearchTreeValue.java) (Easy) #### [Two Pointers](problems/src/two_pointers) From 3b069b8d9e7f2d2a6b35d27a860abaf24e1f07ed Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 13 May 2017 16:57:33 +0200 Subject: [PATCH 005/235] TicTacToe : Accepted --- README.md | 1 + problems/src/design/TicTacToe.java | 152 +++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 problems/src/design/TicTacToe.java diff --git a/README.md b/README.md index b7d2251a..d19b96e6 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Insert Delete Get Random](problems/src/design/RandomizedSet.java) (Medium) - [Serialize Deserialize Binary Tree](problems/src/design/SerializeDeserializeBinaryTree.java) (Hard) - [Design Twitter](problems/src/design/Twitter.java) (Medium) +- [Tic-Tac-Toe](problems/src/design/TicTacToe.java) (Medium) #### [Divide and Conquer](problems/src/divide_and_conquer) diff --git a/problems/src/design/TicTacToe.java b/problems/src/design/TicTacToe.java new file mode 100644 index 00000000..0eb7c2f8 --- /dev/null +++ b/problems/src/design/TicTacToe.java @@ -0,0 +1,152 @@ +package design; + +/** + * Created by gouthamvidyapradhan on 13/05/2017. + + 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. + Example: + 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| + + Follow up: + Could you do better than O(n2) per move() operation? + + Solution: The below solution works in O(1) time complexity. + 1. For each player move, keep track of count of selection for each row and each column. + 2. To keep track of counts in each diagonals we need to first know if the move is made on either one of the diagonals. + The move is made in either of the diagonals if and only if (row = col) AND/OR (col + row = N - 1) + 3. As soon as the count in any of column, row or diagonal reach N then return the current player as the winner, else return 0. + */ +public class TicTacToe +{ + /** + * Cell class to keep track of first player and second player row/column count + */ + private class Cell + { + int player1 = 0, player2 = 0; + } + + Cell[] rows, columns; //Array of row and column cells + private int N, fPD1 = 0, fPD2 = 0, sPD1 = 0, sPD2 = 0; //fPD1 -> first_player_diagonal1 + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception + { + TicTacToe toe = new TicTacToe(3); + System.out.println(toe.move(0, 0, 1)); + System.out.println(toe.move(0, 2, 2)); + System.out.println(toe.move(1, 0, 1)); + System.out.println(toe.move(1, 1, 2)); + System.out.println(toe.move(2, 0, 1)); + } + + /** Initialize your data structure here. */ + public TicTacToe(int n) + { + N = n; + rows = new Cell[N]; + columns = new Cell[N]; + } + + /** + * Move and check who wins. + * @param row row + * @param col col + * @param player player + * @return integer indicating the winner + */ + public int move(int row, int col, int player) + { + switch (player) + { + case 1: + increment(rows, row, 1); + increment(columns, col, 1); + if((col + row) == (N - 1)) + fPD2 ++; + if(row == col) + fPD1 ++; + if(rows[row].player1 == N + || columns[col].player1 == N || fPD1 == N || fPD2 == N) + return 1; + break; + + case 2: + increment(rows, row, 2); + increment(columns, col, 2); + if((col + row) == (N - 1)) + sPD2 ++; + if(row == col) + sPD1 ++; + if(rows[row].player2 == N + || columns[col].player2 == N || sPD1 == N || sPD2 == N) + return 2; + break; + } + return 0; + } + + /** + * Increment row / col count + * @param cells array of cells + * @param key row / col key + * @param player Player object + */ + private void increment(Cell[] cells, int key, int player) { + Cell p = cells[key]; + if(p == null) { + p = new Cell(); + cells[key] = p; + } + if(player == 1) + p.player1++; + else p.player2++; + } +} From 95b269219e92ce92b891fdb085239784032a5041 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 14 May 2017 13:15:06 +0200 Subject: [PATCH 006/235] Inorder Successor in BST : Accepted --- README.md | 1 + problems/src/tree/InorderSuccessorInBST.java | 70 ++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 problems/src/tree/InorderSuccessorInBST.java diff --git a/README.md b/README.md index d19b96e6..181c34f9 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Valid Binary Search Tree](problems/src/tree/ValidBinarySearchTree.java) (Medium) - [Largest BST Subtree](problems/src/tree/LargestBSTSubtree.java) (Medium) - [Closest Binary Search Tree Value](problems/src/tree/ClosestBinarySearchTreeValue.java) (Easy) +- [Inorder Successor in BST](problems/src/tree/InorderSuccessorInBST.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/InorderSuccessorInBST.java b/problems/src/tree/InorderSuccessorInBST.java new file mode 100644 index 00000000..6f214dc8 --- /dev/null +++ b/problems/src/tree/InorderSuccessorInBST.java @@ -0,0 +1,70 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 14/05/2017. + Given a binary search tree and a node in it, find the in-order successor of that node in the BST. + + Note: If the given node has no in-order successor in the tree, return null. + + Solution: The below solution works with worst case time complexity of O(h) where h is the height of the tree. + If the current node is <= target_node, recursively iterate the right of the current node. + else if the current node is > target_node then mark the current node as the successor and recursively iterate the left of the current node. + */ +public class InorderSuccessorInBST +{ + public static class TreeNode + { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception + { + TreeNode root = new TreeNode(10); + root.left = new TreeNode(5); + root.left.left = new TreeNode(3); + root.left.right = new TreeNode(6); + root.right = new TreeNode(15); + root.right.left = new TreeNode(13); + root.right.left.left = new TreeNode(12); + root.right.left.right = new TreeNode(14); + root.right.right = new TreeNode(17); + TreeNode ans = new InorderSuccessorInBST().inorderSuccessor(root, root.right.left.right); + if(ans != null) + System.out.println(ans.val); + else System.out.println(ans); + } + + /** + * Find successor + * @param root root node + * @param p target + * @return successor + */ + public TreeNode inorderSuccessor(TreeNode root, TreeNode p) + { + return inOrder(root, p, null); + } + + /** + * Inorder traversal + * @param curr current node + * @param target target node + * @param successor successor + * @return successor node + */ + private TreeNode inOrder(TreeNode curr, TreeNode target, TreeNode successor) + { + if(curr == null) return successor; + if(curr.val <= target.val) + return inOrder(curr.right, target, successor); + return inOrder(curr.left, target, curr); //make the current node as successor + } +} From 009e527c5b6ea725ef1b8ebf9fa5a58ea827b094 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 19 May 2017 02:15:04 +0200 Subject: [PATCH 007/235] ZigZag Conversion : Accepted --- README.md | 2 + problems/src/string/ZigZagConversion.java | 73 +++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 problems/src/string/ZigZagConversion.java diff --git a/README.md b/README.md index 181c34f9..892ca764 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,8 @@ My accepted leetcode solutions to some of the common interview problems. - [ReverseWords II](problems/src/string/ReverseWordsII.java) (Medium) - [String to Integer](problems/src/string/StringToInteger.java) (Medium) - [Text Justification](problems/src/string/TextJustification.java) (Hard) +- [ZigZag Conversion](problems/src/string/ZigZagConversion.java) (Medium) + #### [Tree](problems/src/tree) diff --git a/problems/src/string/ZigZagConversion.java b/problems/src/string/ZigZagConversion.java new file mode 100644 index 00000000..b017431e --- /dev/null +++ b/problems/src/string/ZigZagConversion.java @@ -0,0 +1,73 @@ +package string; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by gouthamvidyapradhan on 19/05/2017. + The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) + + P A H N + A P L S I I G + Y I R + And then read line by line: "PAHNAPLSIIGYIR" + Write the code that will take a string and make this conversion given a number of rows: + + string convert(string text, int nRows); + convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR". + */ +public class ZigZagConversion +{ + /** + * Main method + * @param args + */ + public static void main(String[] args) + { + System.out.println(new ZigZagConversion().convert("PAYPALISHIRING", 5)); + } + + /** + * Convert and return the result + * @param s input string + * @param numRows max rows + * @return Result string + */ + public String convert(String s, int numRows) { + if(s == null || s.length() <= numRows || numRows == 1) return s; + List list = new ArrayList<>(); + char[] A = new char[numRows]; + int direction = 1; // 1 indicates forward, 0 indicates backwards + int n = 1; + A[0] = s.charAt(0); + for(int j = 1; j < numRows;) { + if(n >= s.length()) break; + A[j] = s.charAt(n++); + if(j == numRows - 1) { + list.add(String.valueOf(A)); + A = new char[numRows]; + Arrays.fill(A, ' '); + direction = 0; + } + else if(j == 0) { + list.add(String.valueOf(A)); + A = new char[numRows]; + Arrays.fill(A, ' '); + direction = 1; + } + j = direction == 1 ? j + 1 : j - 1; + } + if(!String.valueOf(A).trim().isEmpty()) + list.add(String.valueOf(A)); + char[] arr = new char[s.length()]; + int k = 0; + for(int j = 0; j < numRows; j ++) { + for (String aList : list) { + if (aList.charAt(j) != ' ') + arr[k++] = aList.charAt(j); + } + } + return new String(arr).trim(); + } +} From 45fbafa9ea4c0a0c9b0247cf1cd8fff02372ba2c Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 20 May 2017 13:31:45 +0200 Subject: [PATCH 008/235] Search for a Range : Accepted --- README.md | 1 + .../src/binary_search/SearchForARange.java | 62 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 problems/src/binary_search/SearchForARange.java diff --git a/README.md b/README.md index 892ca764..eed2aacb 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Minimum Sorted Rotated Array](problems/src/binary_search/MinSortedRotatedArray.java) (Medium) - [Search in a Rotated Sorted Array](problems/src/binary_search/SearchRotatedSortedArray.java) (Medium) +- [Search for a Range](problems/src/binary_search/SearchForARange.java) (Medium) #### [Bit Manipulation](problems/src/bit_manipulation) diff --git a/problems/src/binary_search/SearchForARange.java b/problems/src/binary_search/SearchForARange.java new file mode 100644 index 00000000..2d806a7a --- /dev/null +++ b/problems/src/binary_search/SearchForARange.java @@ -0,0 +1,62 @@ +package binary_search; + +/** + * Created by gouthamvidyapradhan on 20/05/2017. + Given an array of integers sorted in ascending order, find the starting and ending position of a given target value. + + Your algorithm's runtime complexity must be in the order of O(log n). + + If the target is not found in the array, return [-1, -1]. + + For example, + Given [5, 7, 7, 8, 8, 10] and target value 8, + return [3, 4]. + + Solution: Works with worst case time complexity of O(log n). Recursively binary search to find the target index. + */ +public class SearchForARange +{ + public static void main(String[] args) throws Exception + { + int[] test = {5, 7, 7, 8, 8, 10, 10, 10, 10, 18, 19, 20, 21, 21, 21, 21, 22, 23, 28, 28, 90, 101, 101, + 101, 200, 200, 200, 200, 200, 200}; + int[] result = new SearchForARange().searchRange(test, 200); + for (int i : result) + System.out.print(i + " "); + } + + public int[] searchRange(int[] nums, int target) { + int low = findIndex(nums, target, true); + int high = findIndex(nums, target, false); + int[] result = new int[2]; + result[0] = low; + result[1] = high; + return result; + } + + /** + * Find index + * @param nums nums array + * @param target target + * @param isLowerIndex true if target is to find lower index, false otherwise + * @return index + */ + private int findIndex(int[] nums, int target, boolean isLowerIndex){ + int result = -1; + int s = 0, e = nums.length - 1; + while(s <= e) { + int m = s + (e - s) / 2; + if(nums[m] == target) { + result = m; + if(isLowerIndex) e = m - 1; //if searching for the lower index then search the lower bound, + // else search the upper bound + else s = m + 1; + } + else if(nums[m] < target){ + s = m + 1; + } + else e = m - 1; + } + return result; + } +} From 35af97541e6c67567e61ea05037ddcdbb4a779c4 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Mon, 22 May 2017 19:53:46 +0200 Subject: [PATCH 009/235] Sqrt(x) : Accepted --- README.md | 1 + problems/src/binary_search/SqrtX.java | 35 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 problems/src/binary_search/SqrtX.java diff --git a/README.md b/README.md index eed2aacb..8fef2f2b 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Minimum Sorted Rotated Array](problems/src/binary_search/MinSortedRotatedArray.java) (Medium) - [Search in a Rotated Sorted Array](problems/src/binary_search/SearchRotatedSortedArray.java) (Medium) - [Search for a Range](problems/src/binary_search/SearchForARange.java) (Medium) +- [Sqrt(x)](problems/src/binary_search/SqrtX.java) (Easy) #### [Bit Manipulation](problems/src/bit_manipulation) diff --git a/problems/src/binary_search/SqrtX.java b/problems/src/binary_search/SqrtX.java new file mode 100644 index 00000000..4f008ff6 --- /dev/null +++ b/problems/src/binary_search/SqrtX.java @@ -0,0 +1,35 @@ +package binary_search; + +/** + * Created by gouthamvidyapradhan on 22/05/2017. + Implement int sqrt(int x). + + Compute and return the square root of x. + */ +public class SqrtX +{ + public static void main(String[] args) throws Exception + { + System.out.println(new SqrtX().mySqrt(Integer.MAX_VALUE)); + } + + public int mySqrt(int x) + { + int s = 0, e = x; + long ans = 0L; + while(s <= e) + { + long m = s + (e - s) / 2; + long prod = m * m; + if(prod <= x) + { + s = (int)(m + 1); + ans = m; + } + else e = (int)m - 1; + } + return (int)ans; + } + + +} From b947124d5db2cba0a102552620d55ccb4ec4de6e Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Mon, 22 May 2017 23:31:19 +0200 Subject: [PATCH 010/235] Search Insert Position : Accepted --- README.md | 1 + .../binary_search/SearchInsertPosition.java | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 problems/src/binary_search/SearchInsertPosition.java diff --git a/README.md b/README.md index 8fef2f2b..d3d5990f 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Search in a Rotated Sorted Array](problems/src/binary_search/SearchRotatedSortedArray.java) (Medium) - [Search for a Range](problems/src/binary_search/SearchForARange.java) (Medium) - [Sqrt(x)](problems/src/binary_search/SqrtX.java) (Easy) +- [Search Insert Position](problems/src/binary_search/SearchInsertPosition.java) (Easy) #### [Bit Manipulation](problems/src/bit_manipulation) diff --git a/problems/src/binary_search/SearchInsertPosition.java b/problems/src/binary_search/SearchInsertPosition.java new file mode 100644 index 00000000..31a28d49 --- /dev/null +++ b/problems/src/binary_search/SearchInsertPosition.java @@ -0,0 +1,40 @@ +package binary_search; + +/** + * Created by gouthamvidyapradhan on 22/05/2017. + Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. + + You may assume no duplicates in the array. + + Here are few examples. + [1,3,5,6], 5 → 2 + [1,3,5,6], 2 → 1 + [1,3,5,6], 7 → 4 + [1,3,5,6], 0 → 0 + */ +public class SearchInsertPosition +{ + public static void main(String[] args) throws Exception + { + int[] A = {1, 3, 5, 6}; + new SearchInsertPosition().searchInsert(A, 5); + } + + public int searchInsert(int[] nums, int target) + { + int pos = nums.length; + int s = 0, e = nums.length - 1; + while(s <= e) + { + int m = s + (e - s) / 2; + if(nums[m] >= target) + { + pos = m; + e = m - 1; + } + else s = m + 1; + } + return pos; + } + +} From a5724dd0546cee4d10836c6a66860e51ac9d8d2c Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 23 May 2017 02:26:06 +0200 Subject: [PATCH 011/235] Median of Two Sorted Arrays : Accepted --- README.md | 1 + .../MedianOfTwoSortedArrays.java | 97 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 problems/src/binary_search/MedianOfTwoSortedArrays.java diff --git a/README.md b/README.md index d3d5990f..482eef44 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Search for a Range](problems/src/binary_search/SearchForARange.java) (Medium) - [Sqrt(x)](problems/src/binary_search/SqrtX.java) (Easy) - [Search Insert Position](problems/src/binary_search/SearchInsertPosition.java) (Easy) +- [Median of Two Sorted Arrays](problems/src/binary_search/MedianOfTwoSortedArrays.java) (Hard) #### [Bit Manipulation](problems/src/bit_manipulation) diff --git a/problems/src/binary_search/MedianOfTwoSortedArrays.java b/problems/src/binary_search/MedianOfTwoSortedArrays.java new file mode 100644 index 00000000..fcc60c86 --- /dev/null +++ b/problems/src/binary_search/MedianOfTwoSortedArrays.java @@ -0,0 +1,97 @@ +package binary_search; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Created by gouthamvidyapradhan on 23/05/2017. + There are two sorted arrays nums1 and nums2 of size m and n respectively. + + Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). + + Example 1: + nums1 = [1, 3] + nums2 = [2] + + The median is 2.0 + Example 2: + nums1 = [1, 2] + nums2 = [3, 4] + + The median is (2 + 3)/2 = 2.5 + + Solution: Works in worst case time complexity of O(log min(m, n)) + + The basic idea is that if you are given two arrays A and B and know + the length of each, you can check whether an element A[i] is the median in constant + time. Suppose that the median is A[i]. Since the array is sorted, it is greater than + exactly i − 1 values in array A. Then if it is the median, it is also greater than exactly + j = [n / 2] − (i − 1) elements in B. It requires constant time to check if B[j] + A[i] <= B[j + 1]. If A[i] is not the median, then depending on whether A[i] is greater + or less than B[j] and B[j + 1], you know that A[i] is either greater than or less than + the median. Thus you can binary search for A[i] in O(log N) worst-case time + + */ +public class MedianOfTwoSortedArrays +{ + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception + { + int[] A = {1,2,5,8,44,45,45}; + int[] B = {1, 2, 3,4,5,6,7,23,23,23,33,44,45,45,56,77,5555}; + System.out.println(new MedianOfTwoSortedArrays().findMedianSortedArrays(A, B)); + } + + /** + * Find median + * @param nums1 array one + * @param nums2 array two + * @return + */ + public double findMedianSortedArrays(int[] nums1, int[] nums2) + { + if(nums1.length > nums2.length) + return findMedianSortedArrays(nums2, nums1); //ensure always nums1 is the shortest array + int T = nums1.length + nums2.length, low = -1, high = -1; + int median = (T - 1) / 2; + boolean isOdd = false; + if((T % 2) != 0) + isOdd = true; + + int s = 0, e = nums1.length - 1; + while(s <= e) { + int m = s + (e - s) / 2; + if((median - m - 1) < 0 || nums1[m] >= nums2[median - m - 1]) { + e = m - 1; + low = m; + high = median - m; + } + else s = m + 1; + } + + if(low == -1) { + if(isOdd) return nums2[median - nums1.length]; + else return (double)(nums2[median - nums1.length] + nums2[median - nums1.length + 1]) / 2.0D; + } + else { + if(isOdd) return nums1[low] < nums2[high] ? nums1[low] : nums2[high]; + else { + //Always sorts maximum of 4 elements hence works in O(1) + List list = new ArrayList<>(); + list.add(nums1[low]); + if(low + 1 < nums1.length) + list.add(nums1[low + 1]); + list.add(nums2[high]); + if(high + 1 < nums2.length) + list.add(nums2[high + 1]); + Collections.sort(list); + return (double)(list.get(0) + list.get(1)) / 2.0; + } + } + } +} From 0732ead2cd3d2788cd81f609f91148e02a4ca30b Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 24 May 2017 00:38:22 +0200 Subject: [PATCH 012/235] Pow(x, n) : Accepted --- README.md | 1 + problems/src/binary_search/PowXN.java | 36 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 problems/src/binary_search/PowXN.java diff --git a/README.md b/README.md index 482eef44..663e722c 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Sqrt(x)](problems/src/binary_search/SqrtX.java) (Easy) - [Search Insert Position](problems/src/binary_search/SearchInsertPosition.java) (Easy) - [Median of Two Sorted Arrays](problems/src/binary_search/MedianOfTwoSortedArrays.java) (Hard) +- [Pow(x, n)](problems/src/binary_search/PowXN.java) (Medium) #### [Bit Manipulation](problems/src/bit_manipulation) diff --git a/problems/src/binary_search/PowXN.java b/problems/src/binary_search/PowXN.java new file mode 100644 index 00000000..eeb5457c --- /dev/null +++ b/problems/src/binary_search/PowXN.java @@ -0,0 +1,36 @@ +package binary_search; + +/** + * Created by gouthamvidyapradhan on 23/05/2017. + + Implement pow(x, n). + + Solution: Works with O(log n) + */ +public class PowXN +{ + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception + { + System.out.println(1 / new PowXN().myPow(2.00000, -2147483648)); + } + + public double myPow(double x, int n) + { + if(n == 0) return 1D; + long N = n; //use long to avoid overflow. + return solve(n < 0 ? (1 / x) : x, N < 0 ? (N * -1) : N); + } + + public double solve(double x, long n) + { + if(n == 1) return x; + double val = solve(x, n / 2); + return val * val * ((n % 2) == 0 ? 1 : x); + } + +} From 24dc32a7e909aac103fba06b48bedf56d40ab901 Mon Sep 17 00:00:00 2001 From: Voicu Pop Date: Fri, 2 Jun 2017 14:33:00 -0700 Subject: [PATCH 013/235] Avoid boxing and unboxing by doing a cast to int --- problems/src/math/CountPrimes.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/src/math/CountPrimes.java b/problems/src/math/CountPrimes.java index 645eb5fe..3b1c4c0a 100644 --- a/problems/src/math/CountPrimes.java +++ b/problems/src/math/CountPrimes.java @@ -26,7 +26,7 @@ public int countPrimes(int n) else if(n == 3) return 1; BitSet set = new BitSet(); n = n - 1; - int sqRt = new Double(Math.sqrt(n)).intValue(); + int sqRt = (int)Math.sqrt(n); int count = n; for(int i = 2; i <= sqRt; i ++) { From e28c81a1fe25c397f6596aa67a808d835a3b61d8 Mon Sep 17 00:00:00 2001 From: Voicu Pop Date: Wed, 7 Jun 2017 17:51:48 -0700 Subject: [PATCH 014/235] Prevent overflow for large integer numbers --- problems/src/binary_search/SearchRotatedSortedArray.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/src/binary_search/SearchRotatedSortedArray.java b/problems/src/binary_search/SearchRotatedSortedArray.java index e6b17e21..28e27423 100644 --- a/problems/src/binary_search/SearchRotatedSortedArray.java +++ b/problems/src/binary_search/SearchRotatedSortedArray.java @@ -34,7 +34,7 @@ public int search(int[] nums, int target) int low = 0, high = nums.length - 1; while(low < high) { - int mid = (low + high) / 2; + int mid = (low + high) >>> 1; if(nums[mid] == target) return mid; if((nums[mid] <= nums[low]) && (target > nums[mid] && target <= nums[high]) || From 3e507cea31b357b73e9d237866955cef064f8e10 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 10 Jun 2017 12:57:24 +0200 Subject: [PATCH 015/235] CanPlaceFlowers : Accepted ConstructStringFromBinaryTree : Accepted --- README.md | 2 + problems/src/array/CanPlaceFlowers.java | 56 ++++++++++++++ .../tree/ConstructStringFromBinaryTree.java | 73 +++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 problems/src/array/CanPlaceFlowers.java create mode 100644 problems/src/tree/ConstructStringFromBinaryTree.java diff --git a/README.md b/README.md index 663e722c..379e0e96 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Set Matrix Zeroes](problems/src/array/SetMatrixZeroes.java) (Medium) - [Third Maximum Number](problems/src/array/ThirdMaximumNumber.java) (Easy) - [TwoSum II](problems/src/array/TwoSumII.java) (Easy) +- [Can Place Flowers](problems/src/array/CanPlaceFlowers.java) (Easy) #### [Backtracking](problems/src/backtracking) @@ -148,6 +149,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Largest BST Subtree](problems/src/tree/LargestBSTSubtree.java) (Medium) - [Closest Binary Search Tree Value](problems/src/tree/ClosestBinarySearchTreeValue.java) (Easy) - [Inorder Successor in BST](problems/src/tree/InorderSuccessorInBST.java) (Medium) +- [Construct String From Binary Tree](problems/src/tree/ConstructStringFromBinaryTree.java) (Easy) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/array/CanPlaceFlowers.java b/problems/src/array/CanPlaceFlowers.java new file mode 100644 index 00000000..f8442336 --- /dev/null +++ b/problems/src/array/CanPlaceFlowers.java @@ -0,0 +1,56 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 10/06/2017. + * Accepted + * + Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, flowers cannot be planted in adjacent plots - they would compete for water and both would die. + + Given a flowerbed (represented as an array containing 0 and 1, where 0 means empty and 1 means not empty), and a number n, return if n new flowers can be planted in it without violating the no-adjacent-flowers rule. + + Example 1: + Input: flowerbed = [1,0,0,0,1], n = 1 + Output: True + Example 2: + Input: flowerbed = [1,0,0,0,1], n = 2 + Output: False + Note: + The input array won't violate no-adjacent-flowers rule. + The input array size is in the range of [1, 20000]. + n is a non-negative integer which won't exceed the input array size. + */ +public class CanPlaceFlowers +{ + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception + { + int[] n = {1,0,0,0,1}; + System.out.println(new CanPlaceFlowers().canPlaceFlowers(n, 1)); + } + + public boolean canPlaceFlowers(int[] flowerbed, int n) { + + int[] T = new int[flowerbed.length + 4]; + for(int i = 0, j = 2; i < flowerbed.length; i ++) + T[j++] = flowerbed[i]; + T[0] = 1; + T[T.length - 1] = 1; + int total = 0, count = 0; + for(int i = 1; i < T.length; i ++) { + if(T[i] == 0) + count++; + else { + if((count % 2) == 0) + total += ((count / 2) - 1); + else + total += (count / 2); + count = 0; //reset + } + } + return (total >= n); + } +} diff --git a/problems/src/tree/ConstructStringFromBinaryTree.java b/problems/src/tree/ConstructStringFromBinaryTree.java new file mode 100644 index 00000000..c83708f3 --- /dev/null +++ b/problems/src/tree/ConstructStringFromBinaryTree.java @@ -0,0 +1,73 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 10/06/2017. + * Accepted + You need to construct a string consists of parenthesis and integers from a binary tree with the preorder traversing way. + + The null node needs to be represented by empty parenthesis pair "()". And you need to omit all the empty parenthesis pairs that don't affect the one-to-one mapping relationship between the string and the original binary tree. + + Example 1: + Input: Binary tree: [1,2,3,4] + 1 + / \ + 2 3 + / + 4 + + Output: "1(2(4))(3)" + + Explanation: Originallay it needs to be "1(2(4)())(3()())", + but you need to omit all the unnecessary empty parenthesis pairs. + And it will be "1(2(4))(3)". + Example 2: + Input: Binary tree: [1,2,3,null,4] + 1 + / \ + 2 3 + \ + 4 + + Output: "1(2()(4))(3)" + + Explanation: Almost the same as the first example, + except we can't omit the first parenthesis pair to break the one-to-one mapping relationship between the input and the output. + */ +public class ConstructStringFromBinaryTree +{ + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception + { + TreeNode t = new TreeNode(1); + t.left = new TreeNode(2); + t.left.left = new TreeNode(4); + t.right = new TreeNode(3); + System.out.println(new ConstructStringFromBinaryTree().tree2str(t)); + } + + public String tree2str(TreeNode t) + { + if(t == null) return ""; + String left = tree2str(t.left); + String right = tree2str(t.right); + if(left.equals("") && right.equals("")) + return String.valueOf(t.val); + if(left.equals("")) + left = "()"; + else left = "(" + left + ")"; + if(!right.equals("")) + right = "(" + right + ")"; + return t.val + left + right; + } +} From bc5d8443c0a80645b406a35f0b5425e2e16555ee Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 13 Jun 2017 00:00:18 +0200 Subject: [PATCH 016/235] Concatenated Words : Accepted --- README.md | 1 + .../ConcatenatedWords.java | 69 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 problems/src/dynamic_programming/ConcatenatedWords.java diff --git a/README.md b/README.md index 379e0e96..64b8e15f 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Unique Binary Search Trees II](problems/src/dynamic_programming/UniqueBinarySearchTreesII.java) (Medium) - [WordBreak](problems/src/dynamic_programming/WordBreak.java) (Medium) - [WordBreak II](problems/src/dynamic_programming/WordBreakII.java) (Hard) +- [Concatenated Words](problems/src/dynamic_programming/ConcatenatedWords.java) (Hard) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/ConcatenatedWords.java b/problems/src/dynamic_programming/ConcatenatedWords.java new file mode 100644 index 00000000..12a25a8a --- /dev/null +++ b/problems/src/dynamic_programming/ConcatenatedWords.java @@ -0,0 +1,69 @@ +package dynamic_programming; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Created by gouthamvidyapradhan on 12/06/2017. + * Accepted + Given a list of words (without duplicates), please write a program that returns all concatenated words in the given list of words. + + A concatenated word is defined as a string that is comprised entirely of at least two shorter words in the given array. + + Example: + Input: ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"] + + Output: ["catsdogcats","dogcatsdog","ratcatdogcat"] + + Explanation: "catsdogcats" can be concatenated by "cats", "dog" and "cats"; + "dogcatsdog" can be concatenated by "dog", "cats" and "dog"; + "ratcatdogcat" can be concatenated by "rat", "cat", "dog" and "cat". + + Note: + The number of elements of the given array will not exceed 10,000 + The length sum of elements in the given array will not exceed 600,000. + All the input string will only include lower case letters. + The returned elements order does not matter. + + + */ +public class ConcatenatedWords +{ + public static void main(String[] args) throws Exception + { + String[] words = {""}; + System.out.println(new ConcatenatedWords().findAllConcatenatedWordsInADict(words)); + } + + public List findAllConcatenatedWordsInADict(String[] words) { + Set dictionary = new HashSet<>(); + for(String w : words) + dictionary.add(w); + List result = new ArrayList<>(); + for(String w : words) { + if(!w.isEmpty() && concatenatedWordsPossible(w, dictionary)) + result.add(w); + } + return result; + } + + private boolean concatenatedWordsPossible(String word, Set dictionary) + { + boolean[] D = new boolean[word.length() + 1]; + D[word.length()] = true; + dictionary.remove(word); //remove current word from dictionary temporarily + for(int i = word.length() - 1; i >= 0; i --) { + for(int j = i, l = word.length(); j < l; j ++) { + String subStr = word.substring(i, j + 1); + if(dictionary.contains(subStr) && D[j + 1]) { + D[i] = true; + break; + } + } + } + dictionary.add(word); //restore deleted word + return D[0]; + } +} From 138a1ce7b58e98862ba67f911a132e3fd83be7b3 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 13 Jun 2017 00:13:01 +0200 Subject: [PATCH 017/235] Three Sum Closest: Accepted --- README.md | 1 + .../src/two_pointers/ThreeSumClosest.java | 57 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 problems/src/two_pointers/ThreeSumClosest.java diff --git a/README.md b/README.md index 64b8e15f..1eee7bfe 100644 --- a/README.md +++ b/README.md @@ -158,3 +158,4 @@ My accepted leetcode solutions to some of the common interview problems. - [Longest Substring Witout Repeats](problems/src/two_pointers/LongestSubstringWitoutRepeats.java) (Medium) - [Three Sum](problems/src/two_pointers/ThreeSum.java) (Medium) - [Trapping Rain Water](problems/src/two_pointers/TrappingRainWater.java) (Hard) +- [3Sum Closest](problems/src/two_pointers/ThreeSumClosest.java) (Hard) diff --git a/problems/src/two_pointers/ThreeSumClosest.java b/problems/src/two_pointers/ThreeSumClosest.java new file mode 100644 index 00000000..df8cfce9 --- /dev/null +++ b/problems/src/two_pointers/ThreeSumClosest.java @@ -0,0 +1,57 @@ +package two_pointers; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 13/06/2017. + * Accepted + Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. + + For example, given array S = {-1 2 1 -4}, and target = 1. + + The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). + */ +public class ThreeSumClosest { + + public static void main(String[] args) { + int[] a = {-1, 2, 1, -4}; + System.out.println(new ThreeSumClosest().threeSumClosest(a, 1)); + } + + public int threeSumClosest(int[] a, int target) { + Arrays.sort(a); + int min = Integer.MAX_VALUE, ans = -1; + for(int i = 0, l = a.length; i < l - 2; i ++) { + if(i == 0 || ! (a[i] == a[i - 1])) { + int j = i + 1, k = l - 1; + while(k > j) { + if(j != i + 1 && (a[j] == a[j - 1])) { + j ++; + continue; + } + int sum = a[i] + a[j] + a[k]; + if(sum < target) { + int diff = Math.abs(sum - target); + if(diff < min) { + min = diff; + ans = sum; + } + j++; + } + else if(sum > target) { + int diff = Math.abs(sum - target); + if(diff < min) { + min = diff; + ans = sum; + } + k--; + } + else{ + return sum; + } + } + } + } + return ans; + } +} From 8adf98ff8130cd6b258419d62814a11c68690944 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 13 Jun 2017 00:13:46 +0200 Subject: [PATCH 018/235] Update to readme file --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1eee7bfe..a9c0135d 100644 --- a/README.md +++ b/README.md @@ -158,4 +158,4 @@ My accepted leetcode solutions to some of the common interview problems. - [Longest Substring Witout Repeats](problems/src/two_pointers/LongestSubstringWitoutRepeats.java) (Medium) - [Three Sum](problems/src/two_pointers/ThreeSum.java) (Medium) - [Trapping Rain Water](problems/src/two_pointers/TrappingRainWater.java) (Hard) -- [3Sum Closest](problems/src/two_pointers/ThreeSumClosest.java) (Hard) +- [3Sum Closest](problems/src/two_pointers/ThreeSumClosest.java) (Medium) From a882a90a1aebefa91cf2cebb7e0d020c3af4cef1 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 13 Jun 2017 00:42:44 +0200 Subject: [PATCH 019/235] MoveZeroes : Accepted --- README.md | 1 + problems/src/two_pointers/MoveZeroes.java | 40 +++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 problems/src/two_pointers/MoveZeroes.java diff --git a/README.md b/README.md index a9c0135d..d10f52f1 100644 --- a/README.md +++ b/README.md @@ -159,3 +159,4 @@ My accepted leetcode solutions to some of the common interview problems. - [Three Sum](problems/src/two_pointers/ThreeSum.java) (Medium) - [Trapping Rain Water](problems/src/two_pointers/TrappingRainWater.java) (Hard) - [3Sum Closest](problems/src/two_pointers/ThreeSumClosest.java) (Medium) +- [Move Zeroes](problems/src/two_pointers/MoveZeroes.java) (Medium) diff --git a/problems/src/two_pointers/MoveZeroes.java b/problems/src/two_pointers/MoveZeroes.java new file mode 100644 index 00000000..309bbb1d --- /dev/null +++ b/problems/src/two_pointers/MoveZeroes.java @@ -0,0 +1,40 @@ +package two_pointers; + +/** + * Created by gouthamvidyapradhan on 13/06/2017. + * Accepted + * Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements. + + For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0]. + + Note: + You must do this in-place without making a copy of the array. + Minimize the total number of operations. + */ +public class MoveZeroes +{ + public static void main(String[] args) throws Exception { + int[] nums = {0,0,0,0,1,0,1,0,2}; + new MoveZeroes().moveZeroes(nums); + for (int n : nums) + System.out.print(n); + } + + public void moveZeroes(int[] nums) { + int i = 0; + for(int j = 0, l = nums.length; j < l;) { + if(nums[j] == 0) + j++; + else { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + i ++; + j ++; + } + } + while (i < nums.length) + nums[i++] = 0; + } + +} From 3e4baa361e8d5aa003eba79b1341b5027a41bcb0 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 13 Jun 2017 00:43:06 +0200 Subject: [PATCH 020/235] Updated to readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d10f52f1..81106aa0 100644 --- a/README.md +++ b/README.md @@ -159,4 +159,4 @@ My accepted leetcode solutions to some of the common interview problems. - [Three Sum](problems/src/two_pointers/ThreeSum.java) (Medium) - [Trapping Rain Water](problems/src/two_pointers/TrappingRainWater.java) (Hard) - [3Sum Closest](problems/src/two_pointers/ThreeSumClosest.java) (Medium) -- [Move Zeroes](problems/src/two_pointers/MoveZeroes.java) (Medium) +- [Move Zeroes](problems/src/two_pointers/MoveZeroes.java) (Easy) From 260fb545959f199928f67340c5b88657f76e510f Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 13 Jun 2017 23:54:12 +0200 Subject: [PATCH 021/235] Merge Interval : Accepted --- README.md | 1 + problems/src/array/MergeIntervals.java | 58 ++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 problems/src/array/MergeIntervals.java diff --git a/README.md b/README.md index 81106aa0..283736cc 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Third Maximum Number](problems/src/array/ThirdMaximumNumber.java) (Easy) - [TwoSum II](problems/src/array/TwoSumII.java) (Easy) - [Can Place Flowers](problems/src/array/CanPlaceFlowers.java) (Easy) +- [Merge Intervals](problems/src/array/MergeIntervals.java) (Medium) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/MergeIntervals.java b/problems/src/array/MergeIntervals.java new file mode 100644 index 00000000..25e5c653 --- /dev/null +++ b/problems/src/array/MergeIntervals.java @@ -0,0 +1,58 @@ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 13/06/2017. + * Given a collection of intervals, merge all overlapping intervals. + + For example, + Given [1,3],[2,6],[8,10],[15,18], + return [1,6],[8,10],[15,18]. + + Solution: O(N log N) where N is the number of intervals + 1. Sort the intervals based on start index + 2. Mark the first interval as the current interval + 3. For every ith interval starting 1 -> N, if the ith interval overlaps with the current interval then create a new + current interval. Else, add the current interval to result set and begin a new current interval. + + */ +public class MergeIntervals +{ + public static class Interval { + int start; + int end; + Interval() { start = 0; end = 0; } + Interval(int s, int e) { start = s; end = e; } + } + + public static void main(String[] args) throws Exception + { + Interval i1 = new Interval(1, 2); + Interval i2 = new Interval(3, 4); + Interval i3 = new Interval(5, 6); + Interval i4 = new Interval(1, 10); + List result = new MergeIntervals().merge(Arrays.asList(i1, i2, i3, i4)); + result.forEach((I) -> System.out.println(I.start + " " + I.end)); + } + + public List merge(List intervals) { + if(intervals.isEmpty()) return new ArrayList<>(); + Collections.sort(intervals, (o1, o2) -> Integer.compare(o1.start, o2.start)); + List result = new ArrayList<>(); + Interval curr = intervals.get(0); + for(int i = 1, l = intervals.size(); i < l; i ++) { + Interval I = intervals.get(i); + if(I.start >= curr.start && I.start <= curr.end) { //check if the new interval overlaps with the current + curr.end = curr.end > I.end ? curr.end : I.end; + } + else { + result.add(curr); + curr = I; + } + } + result.add(curr); + return result; + } + +} From fe49c6119309fa076e4a4c33329273595b175c7b Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 21 Jun 2017 02:23:15 +0200 Subject: [PATCH 022/235] LargestRectangleInHistogram : Accepted --- README.md | 1 + .../stack/LargestRectangleInHistogram.java | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 problems/src/stack/LargestRectangleInHistogram.java diff --git a/README.md b/README.md index 283736cc..023482a6 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Min Stack](problems/src/stack/MinStack.java) (Easy) - [Valid Parentheses](problems/src/stack/ValidParentheses.java) (Easy) +- [Largest Rectangle In Histogram](problems/src/stack/LargestRectangleInHistogram.java) (Hard) #### [String](problems/src/string) diff --git a/problems/src/stack/LargestRectangleInHistogram.java b/problems/src/stack/LargestRectangleInHistogram.java new file mode 100644 index 00000000..cbe14b4a --- /dev/null +++ b/problems/src/stack/LargestRectangleInHistogram.java @@ -0,0 +1,52 @@ +package stack; + +import java.util.Stack; + +/** + * Created by gouthamvidyapradhan on 20/06/2017. + * Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram. + + For example, + Given heights = [2,1,5,6,2,3], + return 10. (min of index 2 and 3 multiplied by two) + + Solution O(N): + + 1) Create an empty stack. + + 2) Start from first bar, and do following for every bar ‘hist[i]’ where ‘i’ varies from 0 to n-1. + a) If stack is empty or hist[i] is higher than the bar at top of stack, then push ‘i’ to stack. + b) If this bar is smaller than the top of stack, then keep removing the top of stack while top of the stack is greater. Let the removed bar be hist[tp]. + Calculate area of rectangle with hist[tp] as smallest bar. For hist[tp], the ‘left index’ is previous (previous to tp) item in stack and ‘right index’ is ‘i’ (current index). + + 3) If the stack is not empty, then one by one remove all bars from stack and do step 2.b for every removed bar. + + */ +public class LargestRectangleInHistogram { + public static void main(String[] args) throws Exception{ + int[] A = {2, 3}; + System.out.println(new LargestRectangleInHistogram().largestRectangleArea(A)); + } + + public int largestRectangleArea(int[] heights) { + if(heights.length == 0) return 0; + int maxArea = Integer.MIN_VALUE; + Stack stack = new Stack<>(); + int i = 0; + for(; i < heights.length; i ++) { + while(!stack.isEmpty() && heights[stack.peek()] >= heights[i]) { + int top = stack.pop(); + int base = stack.isEmpty() ? i : i - stack.peek() - 1; + maxArea = Math.max(maxArea, base * heights[top]); + } + stack.push(i); + } + while(!stack.isEmpty()) { + int top = stack.pop(); + int base = stack.isEmpty() ? i : i - stack.peek() - 1; + maxArea = Math.max(maxArea, base * heights[top]); + } + return maxArea; + } + +} From 630251d8c13969c72d6f18594bd81f59406d587a Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 23 Jun 2017 01:48:31 +0200 Subject: [PATCH 023/235] CourseSchedule : Accepted --- README.md | 1 + .../depth_first_search/CourseSchedule.java | 89 +++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 problems/src/depth_first_search/CourseSchedule.java diff --git a/README.md b/README.md index 023482a6..3bef33fc 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Minesweeper](problems/src/depth_first_search/Minesweeper.java) (Medium) - [Movie Recommend](problems/src/depth_first_search/MovieRecommend.java) (Medium) - [Number Of Islands](problems/src/depth_first_search/NumberOfIslands.java) (Medium) +- [Course Schedule](problems/src/depth_first_search/CourseSchedule.java) (Medium) #### [Design](problems/src/design) diff --git a/problems/src/depth_first_search/CourseSchedule.java b/problems/src/depth_first_search/CourseSchedule.java new file mode 100644 index 00000000..131b4f25 --- /dev/null +++ b/problems/src/depth_first_search/CourseSchedule.java @@ -0,0 +1,89 @@ +package depth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 22/06/2017. + * There are a total of n courses you have to take, labeled from 0 to n - 1. + + Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] + + Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses? + + For example: + + 2, [[1,0]] + There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible. + + 2, [[1,0],[0,1]] + 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. + + Note: + The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented. + You may assume that there are no duplicate edges in the input prerequisites. + + Solution: + 1. Topologically sort the vertices. + 2. Pick each sorted vertex and mark each of its neighbours as visited, + if you encounter a vertex which is already visited then return false otherwise return true + */ +public class CourseSchedule { + private Map> graph; + private BitSet visited; + private Queue toposorted; + public static void main(String[] args) throws Exception{ + int[][] pre = {{1,0}}; + System.out.println(new CourseSchedule().canFinish(2, pre)); + } + + public boolean canFinish(int numCourses, int[][] prerequisites) { + graph = new HashMap<>(); + visited = new BitSet(); + toposorted = new ArrayDeque<>(); + //build graph + for (int[] children : prerequisites) { + graph.putIfAbsent(children[0], new ArrayList<>()); + graph.get(children[0]).add(children[1]); + } + graph.keySet().stream().filter(v -> !visited.get(v)).forEach(this::dfs); + + visited.clear(); + + while(!toposorted.isEmpty()){ + int v = toposorted.poll(); + if(visited.get(v)) + return false; + relax(v); + } + return true; + } + + /** + * Mark a vetex and its connected vertices as visited. + * @param v vertex + */ + private void relax(int v) { + visited.set(v); + List children = graph.get(v); + if(children != null){ + for (int c : children) + visited.set(c); + } + } + + /** + * Toposort + * @param v vertex + */ + private void dfs(int v) { + visited.set(v); + List children = graph.get(v); + if(children != null) { + for(int c : children) + if(!visited.get(c)) + dfs(c); + } + toposorted.offer(v); + } + +} From dc1edee120ce02a492c1b97b7d2b90693caa87f2 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 23 Jun 2017 02:18:53 +0200 Subject: [PATCH 024/235] CourseScheduleII : Accepted --- README.md | 1 + .../depth_first_search/CourseScheduleII.java | 100 ++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 problems/src/depth_first_search/CourseScheduleII.java diff --git a/README.md b/README.md index 3bef33fc..f4e07547 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Movie Recommend](problems/src/depth_first_search/MovieRecommend.java) (Medium) - [Number Of Islands](problems/src/depth_first_search/NumberOfIslands.java) (Medium) - [Course Schedule](problems/src/depth_first_search/CourseSchedule.java) (Medium) +- [Course Schedule II](problems/src/depth_first_search/CourseScheduleII.java) (Medium) #### [Design](problems/src/design) diff --git a/problems/src/depth_first_search/CourseScheduleII.java b/problems/src/depth_first_search/CourseScheduleII.java new file mode 100644 index 00000000..cb8967b4 --- /dev/null +++ b/problems/src/depth_first_search/CourseScheduleII.java @@ -0,0 +1,100 @@ +package depth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 23/06/2017. + * There are a total of n courses you have to take, labeled from 0 to n - 1. + + Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] + + Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses. + + There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array. + + For example: + + 2, [[1,0]] + There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is [0,1] + + 4, [[1,0],[2,0],[3,1],[3,2]] + There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. Another correct ordering is[0,2,1,3]. + + Note: + The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented. + You may assume that there are no duplicate edges in the input prerequisites. + */ +public class CourseScheduleII { + private Map> graph; + private BitSet visited; + private Queue toposorted; + + public static void main(String[] args) throws Exception{ + int[][] pre = {{1, 0}}; + int[] result = new CourseScheduleII().findOrder(2, pre); + for (int i : result) + System.out.print(i + " "); + System.out.println(); + } + + public int[] findOrder(int numCourses, int[][] prerequisites) { + int j = 0; + int[] courses = new int[numCourses]; + int[] result = new int[numCourses]; + for(int i = 0; i < numCourses; i ++) + courses[i] = j++; + graph = new HashMap<>(); + visited = new BitSet(); + toposorted = new ArrayDeque<>(); + //build graph + for (int[] children : prerequisites) { + graph.putIfAbsent(children[0], new ArrayList<>()); + graph.get(children[0]).add(children[1]); + } + graph.keySet().stream().filter(v -> !visited.get(v)).forEach(this::dfs); + + visited.clear(); + int i = 0; + while(!toposorted.isEmpty()){ + int v = toposorted.poll(); + if(visited.get(v)) + return new int[0]; + relax(v); + result[i++] = v; + courses[v] = -1; + } + //add the remaining courses + for(int c : courses) + if(c != -1) + result[i++] = c; + return result; + } + + /** + * Mark a vetex and its connected vertices as visited. + * @param v vertex + */ + private void relax(int v) { + visited.set(v); + List children = graph.get(v); + if(children != null){ + for (int c : children) + visited.set(c); + } + } + + /** + * Toposort + * @param v vertex + */ + private void dfs(int v) { + visited.set(v); + List children = graph.get(v); + if(children != null) { + for(int c : children) + if(!visited.get(c)) + dfs(c); + } + toposorted.offer(v); + } +} From 02af7539998c8cfe7f215d1526abb50c3b2d3f16 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 23 Jun 2017 21:33:56 +0200 Subject: [PATCH 025/235] CoinChange : Accepted --- README.md | 1 + .../src/dynamic_programming/CoinChange.java | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 problems/src/dynamic_programming/CoinChange.java diff --git a/README.md b/README.md index f4e07547..9e4e4a32 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Best Time To Buy and Sell Stocks](problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java) (Easy) - [Climbing Stairs](problems/src/dynamic_programming/ClimbingStairs.java) (Easy) +- [Coin Change](problems/src/dynamic_programming/CoinChange.java) (Medium) - [Coin Change 2](problems/src/dynamic_programming/CoinChange2.java) (Medium) - [Decode Ways](problems/src/dynamic_programming/DecodeWays.java) (Medium) - [House Robber](problems/src/dynamic_programming/HouseRobber.java) (Easy) diff --git a/problems/src/dynamic_programming/CoinChange.java b/problems/src/dynamic_programming/CoinChange.java new file mode 100644 index 00000000..b9a1bf3f --- /dev/null +++ b/problems/src/dynamic_programming/CoinChange.java @@ -0,0 +1,63 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 23/06/2017. + * You are given coins of different denominations and a total amount of money amount. + * Write a function to compute the fewest number of coins that you need to make up that amount. + * If that amount of money cannot be made up by any combination of the coins, return -1. + + Example 1: + coins = [1, 2, 5], amount = 11 + return 3 (11 = 5 + 5 + 1) + + Example 2: + coins = [2], amount = 3 + return -1. + + Note: + You may assume that you have an infinite number of each kind of coin. + + Solution: + For example if you have N coins and amount equal to Q + For every coin you have two options + i) If you chose to include this coin then, total amount reduces by the sum equivalent to the value of this coin and you are + left with N coins and Q = (Q - value of this coin) + ii) If you chose not to include this coin then, you are left with N - 1 coins (since you chose to not to include this coin) + and total amount is still equal to Q + + Calculate recursively for each coin and possible amount + Since there can be overlapping sub-problems you can save the state in a 2D matrix - a typical DP approach. + + For each state minimum is calculated using -> Min(1 + fn(i, amount - v[i]), fn(i + 1, amount)) + + Worst-case time complexity is O(N x Q) where N is the total number of coins and Q is the total amount + + */ +public class CoinChange +{ + private int[][] DP; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] coins = {1, 2, 5}; + System.out.println(new CoinChange().coinChange(coins, 11)); + } + + public int coinChange(int[] coins, int amount) { + DP = new int[coins.length][amount + 1]; + int result = dp(amount, 0, coins); + if(result == Integer.MAX_VALUE - 1) return -1; + return result; + } + + private int dp(int amount, int i, int[] coins){ + if(amount == 0) return 0; + else if(i >= coins.length || amount < 0) return Integer.MAX_VALUE - 1; + if(DP[i][amount] != 0) return DP[i][amount]; + DP[i][amount] = Math.min(1 + dp(amount - coins[i], i, coins), dp(amount, i + 1, coins)); + return DP[i][amount]; + } +} From 58af5d3555d81e46cd90d63096ed9e526585befe Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 24 Jun 2017 19:46:47 +0200 Subject: [PATCH 026/235] FirstMissingPositive : Accepted --- README.md | 1 + problems/src/array/FirstMissingPositive.java | 46 ++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 problems/src/array/FirstMissingPositive.java diff --git a/README.md b/README.md index 9e4e4a32..91a0d42e 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ My accepted leetcode solutions to some of the common interview problems. - [TwoSum II](problems/src/array/TwoSumII.java) (Easy) - [Can Place Flowers](problems/src/array/CanPlaceFlowers.java) (Easy) - [Merge Intervals](problems/src/array/MergeIntervals.java) (Medium) +- [First Missing Positive](problems/src/array/FirstMissingPositive.java) (Hard) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/FirstMissingPositive.java b/problems/src/array/FirstMissingPositive.java new file mode 100644 index 00000000..57d2c9c8 --- /dev/null +++ b/problems/src/array/FirstMissingPositive.java @@ -0,0 +1,46 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 24/06/2017. + * Given an unsorted integer array, find the first missing positive integer. + + For example, + Given [1,2,0] return 3, + and [3,4,-1,1] return 2. + + Your algorithm should run in O(n) time and uses constant space. + */ +public class FirstMissingPositive { + private int L; + public static void main(String[] args) throws Exception{ + int[] nums = {1, 3, 5, 9}; + System.out.println(new FirstMissingPositive().firstMissingPositive(nums)); + } + + public int firstMissingPositive(int[] nums) { + L = nums.length; + for(int i = 0; i < L; i ++){ + if(nums[i] > 0 && nums[i] <= L && nums[i] != i + 1){ + int v = nums[i]; + nums[i] = -1; + replace(v, nums); + } + } + + for(int i = 0; i < L; i ++){ + if(nums[i] != i + 1) + return i + 1; + } + + return L + 1; + } + + private void replace(int i, int[] nums){ + if(i > 0 && i <= L && i != nums[i - 1]){ + int v = nums[i - 1]; + nums[i - 1] = i; + replace(v, nums); + } + } + +} From f6b125ba9769c9d206ad9b4d7e013cc170a8a2d1 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 24 Jun 2017 20:20:26 +0200 Subject: [PATCH 027/235] ImplementStrStr : Accepted --- README.md | 1 + problems/src/string/ImplementStrStr.java | 42 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 problems/src/string/ImplementStrStr.java diff --git a/README.md b/README.md index 91a0d42e..b5199d01 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,7 @@ My accepted leetcode solutions to some of the common interview problems. - [String to Integer](problems/src/string/StringToInteger.java) (Medium) - [Text Justification](problems/src/string/TextJustification.java) (Hard) - [ZigZag Conversion](problems/src/string/ZigZagConversion.java) (Medium) +- [Implement StrStr](problems/src/string/ImplementStrStr.java) (Easy) #### [Tree](problems/src/tree) diff --git a/problems/src/string/ImplementStrStr.java b/problems/src/string/ImplementStrStr.java new file mode 100644 index 00000000..b273a814 --- /dev/null +++ b/problems/src/string/ImplementStrStr.java @@ -0,0 +1,42 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 24/06/2017. + * Implement strStr(). + + Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. + + Solution O(N ^ 2) + */ +public class ImplementStrStr { + public static void main(String[] args) throws Exception{ + System.out.println(new ImplementStrStr().strStr("AABB", "")); + } + + public int strStr(String haystack, String needle) { + if(haystack.isEmpty() && needle.isEmpty()) return 0; + if(needle.isEmpty()) return 0; + for(int i = 0, l = haystack.length(); i < l; i ++){ + if(haystack.charAt(i) == needle.charAt(0)){ + if(isEqual(haystack, needle, i)) + return i; + } + } + return -1; + } + + private boolean isEqual(String haystack, String needle, int i){ + int hL = haystack.length(); + int nL = needle.length(); + int j = 0; + while(i < hL && j < nL){ + if(haystack.charAt(i) != needle.charAt(j)) + return false; + i++; + j++; + } + return j >= nL; + } + + +} From fdde1bc91b5d43fd1ef60dd05da56b1b50bf1f30 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 25 Jun 2017 01:38:33 +0200 Subject: [PATCH 028/235] GenerateParentheses : Accepted --- README.md | 1 + .../src/backtracking/GenerateParentheses.java | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 problems/src/backtracking/GenerateParentheses.java diff --git a/README.md b/README.md index b5199d01..28cea521 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ My accepted leetcode solutions to some of the common interview problems. - [SubSets](problems/src/backtracking/Subsets.java) (Medium) - [SubSet II](problems/src/backtracking/SubsetsII.java) (Medium) - [WordSearch](problems/src/backtracking/WordSearch.java) (Medium) +- [Generate Parentheses](problems/src/backtracking/GenerateParentheses.java) (Medium) #### [Binary Search](problems/src/binary_search) diff --git a/problems/src/backtracking/GenerateParentheses.java b/problems/src/backtracking/GenerateParentheses.java new file mode 100644 index 00000000..54dfa9bf --- /dev/null +++ b/problems/src/backtracking/GenerateParentheses.java @@ -0,0 +1,42 @@ +package backtracking; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 24/06/2017. + * Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. + + For example, given n = 3, a solution set is: + + [ + "((()))", + "(()())", + "(())()", + "()(())", + "()()()" + ] + + */ +public class GenerateParentheses { + public static void main(String[] args) throws Exception{ + System.out.println(new GenerateParentheses().generateParenthesis(4)); + } + + public List generateParenthesis(int n) { + List list = new ArrayList<>(); + backTrack(list, "", 0, 0, n); + return list; + } + + private void backTrack(List list, String str, int open, int close, int n){ + if(str.length() == n * 2){ + list.add(str); + } + else { + if(open < n) + backTrack(list, str.concat("("), open + 1, close, n); + if(close < open) //number of open should be less than close or else it can result in unbalanced parentheses + backTrack(list, str.concat(")"), open, close + 1, n); + } + } +} From b9ff17e5810b90f4631c0e3b89ffb9101d9965c4 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 25 Jun 2017 01:41:44 +0200 Subject: [PATCH 029/235] GenerateParentheses : Accepted --- problems/src/backtracking/GenerateParentheses.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/src/backtracking/GenerateParentheses.java b/problems/src/backtracking/GenerateParentheses.java index 54dfa9bf..e4c779ca 100644 --- a/problems/src/backtracking/GenerateParentheses.java +++ b/problems/src/backtracking/GenerateParentheses.java @@ -35,7 +35,7 @@ private void backTrack(List list, String str, int open, int close, int n else { if(open < n) backTrack(list, str.concat("("), open + 1, close, n); - if(close < open) //number of open should be less than close or else it can result in unbalanced parentheses + if(close < open) //number of close should be less than close or else it can result in unbalanced parentheses backTrack(list, str.concat(")"), open, close + 1, n); } } From 3617e887ce3e4bf66e3ccaf02692a8061daa2c34 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 25 Jun 2017 01:42:16 +0200 Subject: [PATCH 030/235] GenerateParentheses : Accepted --- problems/src/backtracking/GenerateParentheses.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/src/backtracking/GenerateParentheses.java b/problems/src/backtracking/GenerateParentheses.java index e4c779ca..764945ec 100644 --- a/problems/src/backtracking/GenerateParentheses.java +++ b/problems/src/backtracking/GenerateParentheses.java @@ -35,7 +35,7 @@ private void backTrack(List list, String str, int open, int close, int n else { if(open < n) backTrack(list, str.concat("("), open + 1, close, n); - if(close < open) //number of close should be less than close or else it can result in unbalanced parentheses + if(close < open) //number of close should be less than open or else it can result in unbalanced parentheses backTrack(list, str.concat(")"), open, close + 1, n); } } From f0aff8c0a79ad205fc734db2e404ad014fed6e19 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 27 Jun 2017 16:24:10 +0200 Subject: [PATCH 031/235] MaxProductOfThreeNumbers : Accepted --- README.md | 1 + .../src/array/MaxProductOfThreeNumbers.java | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 problems/src/array/MaxProductOfThreeNumbers.java diff --git a/README.md b/README.md index 28cea521..d6e4e1a3 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Can Place Flowers](problems/src/array/CanPlaceFlowers.java) (Easy) - [Merge Intervals](problems/src/array/MergeIntervals.java) (Medium) - [First Missing Positive](problems/src/array/FirstMissingPositive.java) (Hard) +- [MaxProduct Of Three Numbers](problems/src/array/MaxProductOfThreeNumbers.java) (Easy) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/MaxProductOfThreeNumbers.java b/problems/src/array/MaxProductOfThreeNumbers.java new file mode 100644 index 00000000..8428e3dd --- /dev/null +++ b/problems/src/array/MaxProductOfThreeNumbers.java @@ -0,0 +1,32 @@ +package array; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 27/06/2017. + * Given an integer array, find three numbers whose product is maximum and output the maximum product. + + Example 1: + Input: [1,2,3] + Output: 6 + Example 2: + Input: [1,2,3,4] + Output: 24 + Note: + The length of the given array will be in range [3,104] and all elements are in the range [-1000, 1000]. + Multiplication of any three numbers in the input won't exceed the range of 32-bit signed integer. + */ +public class MaxProductOfThreeNumbers { + public static void main(String[] args) { + int[] A = {1,2,3}; + System.out.println(new MaxProductOfThreeNumbers().maximumProduct(A)); + } + + public int maximumProduct(int[] nums) { + Arrays.sort(nums); + int prod1 = nums[nums.length - 1] * nums[nums.length - 2] * nums[nums.length - 3]; + int prod2 = nums[nums.length - 1] * nums[0] * nums[1]; + return prod1 > prod2 ? prod1 : prod2; + } + +} From 3542cfedcea921c5bf5e07158014f4ed134f0566 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 27 Jun 2017 20:07:42 +0200 Subject: [PATCH 032/235] CourseScheduleIII : Accepted --- README.md | 1 + problems/src/greedy/CourseScheduleIII.java | 54 ++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 problems/src/greedy/CourseScheduleIII.java diff --git a/README.md b/README.md index d6e4e1a3..5496e1b7 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Jump Game](problems/src/greedy/JumpGame.java) (Medium) - [Jump Game II](problems/src/greedy/JumpGameII.java) (Medium) +- [Course Schedule III](problems/src/greedy/CourseScheduleIII.java) (Medium) #### [Hashing](problems/src/hashing) diff --git a/problems/src/greedy/CourseScheduleIII.java b/problems/src/greedy/CourseScheduleIII.java new file mode 100644 index 00000000..16469658 --- /dev/null +++ b/problems/src/greedy/CourseScheduleIII.java @@ -0,0 +1,54 @@ +package greedy; + +import java.util.Arrays; +import java.util.PriorityQueue; +import java.util.Queue; + +/** + * Created by gouthamvidyapradhan on 27/06/2017. + * + * There are n different online courses numbered from 1 to n. Each course has some duration(course length) t and closed on dth day. A course should be taken continuously for t days and must be finished before or on the dth day. You will start at the 1st day. + + Given n online courses represented by pairs (t,d), your task is to find the maximal number of courses that can be taken. + + Example: + Input: [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]] + Output: 3 + Explanation: + There're totally 4 courses, but you can take 3 courses at most: + First, take the 1st course, it costs 100 days so you will finish it on the 100th day, and ready to take the next course on the 101st day. + Second, take the 3rd course, it costs 1000 days so you will finish it on the 1100th day, and ready to take the next course on the 1101st day. + Third, take the 2nd course, it costs 200 days so you will finish it on the 1300th day. + The 4th course cannot be taken now, since you will finish it on the 3300th day, which exceeds the closed date. + + Note: + The integer 1 <= d, t, n <= 10,000. + You can't take two courses simultaneously. + + * Solution: O(N log N) + * 1. Sort the courses with earliest deadline time (Greedy sort) + * 2. Maintain a max-heap of course duration. + * 3. Iterate through each course and increment the total time by current course time and include this in the + * max-heap created in step 2. + * 4. If the total time exceeds the current course deadline then, remove the course with max duration from max-heap + * inorder to accommodate the new course. + */ +public class CourseScheduleIII { + public static void main(String[] args) throws Exception{ + int[][] course = {{5, 5}, {2, 6}, {4, 6}}; + System.out.println(new CourseScheduleIII().scheduleCourse(course)); + } + + public int scheduleCourse(int[][] courses) { + Arrays.sort(courses, (a, b) -> a[1] - b[1]); + Queue pq = new PriorityQueue<>((a, b) -> b - a); + int time = 0; + for(int[] course : courses){ + time += course[0]; + pq.add(course[0]); + if(time > course[1]) + time -= pq.poll(); + } + return pq.size(); + } +} From e60f252d77e1d4079a47459eb64c1ce6b8986525 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 28 Jun 2017 02:31:47 +0200 Subject: [PATCH 033/235] GasStation : Accepted --- README.md | 3 +- problems/src/greedy/GasStation.java | 45 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 problems/src/greedy/GasStation.java diff --git a/README.md b/README.md index 5496e1b7..f8b6b2eb 100644 --- a/README.md +++ b/README.md @@ -95,8 +95,9 @@ My accepted leetcode solutions to some of the common interview problems. #### [Greedy](problems/src/greedy) - [Jump Game](problems/src/greedy/JumpGame.java) (Medium) -- [Jump Game II](problems/src/greedy/JumpGameII.java) (Medium) +- [Jump Game II](problems/src/greedy/JumpGameII.java) (Hard) - [Course Schedule III](problems/src/greedy/CourseScheduleIII.java) (Medium) +- [GasStation](problems/src/greedy/GasStation.java) (Medium) #### [Hashing](problems/src/hashing) diff --git a/problems/src/greedy/GasStation.java b/problems/src/greedy/GasStation.java new file mode 100644 index 00000000..b6f38879 --- /dev/null +++ b/problems/src/greedy/GasStation.java @@ -0,0 +1,45 @@ +package greedy; + +/** + * Created by gouthamvidyapradhan on 28/06/2017. + * There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. + + You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations. + + Return the starting gas station's index if you can travel around the circuit once, otherwise return -1. + + Note: + The solution is guaranteed to be unique. + + Solution: O(N) + If point B cant be reached from point A then all the intermediate points between A and B cant be the starting + point. Therefore reset the starting point to the new starting point. + + */ +public class GasStation { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] gas = {10, 20, 30, 10}; + int[] cost = {5, 30, 10, 10}; + System.out.println(new GasStation().canCompleteCircuit(gas, cost)); + } + + public int canCompleteCircuit(int[] gas, int[] cost) { + int debt = 0, sum = 0, start = 0; + for(int i = 0; i < gas.length; i ++){ + sum += gas[i] - cost[i]; + if(sum < 0){ + debt += sum; + sum = 0; + start = i + 1; + } + } + debt += sum; + return debt >= 0 ? start : -1; + } + +} From e485fdad270b0ef6d20d5c21bd62af286e009677 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 28 Jun 2017 23:19:06 +0200 Subject: [PATCH 034/235] NonOverlappingIntervals : Accepted --- README.md | 1 + .../src/greedy/NonOverlappingIntervals.java | 72 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 problems/src/greedy/NonOverlappingIntervals.java diff --git a/README.md b/README.md index f8b6b2eb..58b69efd 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Jump Game II](problems/src/greedy/JumpGameII.java) (Hard) - [Course Schedule III](problems/src/greedy/CourseScheduleIII.java) (Medium) - [GasStation](problems/src/greedy/GasStation.java) (Medium) +- [Non-Overlapping Intervals](problems/src/greedy/NonOverlappingIntervals.java) (Medium) #### [Hashing](problems/src/hashing) diff --git a/problems/src/greedy/NonOverlappingIntervals.java b/problems/src/greedy/NonOverlappingIntervals.java new file mode 100644 index 00000000..0f0bbaf4 --- /dev/null +++ b/problems/src/greedy/NonOverlappingIntervals.java @@ -0,0 +1,72 @@ +package greedy; + +import array.MergeIntervals; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 28/06/2017. + * Given a collection of intervals, find the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping. + + Note: + You may assume the interval's end point is always bigger than its start point. + Intervals like [1,2] and [2,3] have borders "touching" but they don't overlap each other. + Example 1: + 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. + Example 2: + 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. + Example 3: + Input: [ [1,2], [2,3] ] + + Output: 0 + + Explanation: You don't need to remove any of the intervals since they're already non-overlapping. + */ +public class NonOverlappingIntervals { + + public static class Interval { + int start; + int end; + Interval() { start = 0; end = 0; } + Interval(int s, int e) { start = s; end = e; } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + Interval i1 = new Interval(1, 4); + Interval i2 = new Interval(5, 9); + Interval i3 = new Interval(3, 12); + //Interval i4 = new Interval(1, 3); + Interval[] intervals = {i1, i2, i3}; + System.out.println(new NonOverlappingIntervals().eraseOverlapIntervals(intervals)); + } + + public int eraseOverlapIntervals(Interval[] intervals) { + if(intervals.length == 0) return 0; + Arrays.sort(intervals, ((o1, o2) -> o1.end - o2.end)); + int count = 0; + Interval prev = intervals[0]; + for(int i = 1; i < intervals.length; i ++){ + if(intervals[i].start < prev.end){ + count++; + } + else{ + prev = intervals[i]; + } + } + return count; + } + +} From 184d52bb79c332aa3da75692c039819cd2339d6f Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 28 Jun 2017 23:56:31 +0200 Subject: [PATCH 035/235] Minimum Number of Arrows to Burst Balloons : Accepted --- README.md | 1 + problems/src/greedy/BurstBalloons.java | 49 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 problems/src/greedy/BurstBalloons.java diff --git a/README.md b/README.md index 58b69efd..8baabde7 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Course Schedule III](problems/src/greedy/CourseScheduleIII.java) (Medium) - [GasStation](problems/src/greedy/GasStation.java) (Medium) - [Non-Overlapping Intervals](problems/src/greedy/NonOverlappingIntervals.java) (Medium) +- [Minimum Number of Arrows to Burst Balloons](problems/src/greedy/BurstBalloons.java) (Medium) #### [Hashing](problems/src/hashing) diff --git a/problems/src/greedy/BurstBalloons.java b/problems/src/greedy/BurstBalloons.java new file mode 100644 index 00000000..1fe8e8ea --- /dev/null +++ b/problems/src/greedy/BurstBalloons.java @@ -0,0 +1,49 @@ +package greedy; + +import java.util.ArrayDeque; +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 28/06/2017. + * + * There are a number of spherical balloons spread in two-dimensional space. For each balloon, provided input is the start and end coordinates of the horizontal diameter. Since it's horizontal, y-coordinates don't matter and hence the x-coordinates of start and end of the diameter suffice. Start is always smaller than end. There will be at most 104 balloons. + + An arrow can be shot up exactly vertically from different points along the x-axis. A balloon with xstart and xend bursts by an arrow shot at x if xstart ≤ x ≤ xend. There is no limit to the number of arrows that can be shot. An arrow once shot keeps travelling up infinitely. The problem is to find the minimum number of arrows that must be shot to burst all balloons. + + Example: + + Input: + [[10,16], [2,8], [1,6], [7,12]] + + Output: + 2 + + Explanation: + One way is to shoot one arrow for example at x = 6 (bursting the balloons [2,8] and [1,6]) and another arrow at x + */ +public class BurstBalloons { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[][] baloons = {{10,16}, {2,8}, {1,6}, {7,12}}; + System.out.println(new BurstBalloons().findMinArrowShots(baloons)); + } + + public int findMinArrowShots(int[][] points) { + if(points.length == 0) return 0; + Arrays.sort(points, ((o1, o2) -> o1[1] - o2[1])); + int count = 0; + int leftMost = points[0][1]; + for(int i = 1; i < points.length; i ++){ + if(leftMost < points[i][0]){ + count ++; + leftMost = points[i][1]; + } + } + return count + 1; + } + +} From faf4b7fb6f55681617eb5bb7ebe25932d360d9a0 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 29 Jun 2017 13:27:05 +0200 Subject: [PATCH 036/235] QueueReconstructionByHeight : Accepted --- README.md | 1 + .../greedy/QueueReconstructionByHeight.java | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 problems/src/greedy/QueueReconstructionByHeight.java diff --git a/README.md b/README.md index 8baabde7..868971fe 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,7 @@ My accepted leetcode solutions to some of the common interview problems. - [GasStation](problems/src/greedy/GasStation.java) (Medium) - [Non-Overlapping Intervals](problems/src/greedy/NonOverlappingIntervals.java) (Medium) - [Minimum Number of Arrows to Burst Balloons](problems/src/greedy/BurstBalloons.java) (Medium) +- [Queue Reconstruction By Height](problems/src/greedy/QueueReconstructionByHeight.java) (Medium) #### [Hashing](problems/src/hashing) diff --git a/problems/src/greedy/QueueReconstructionByHeight.java b/problems/src/greedy/QueueReconstructionByHeight.java new file mode 100644 index 00000000..4de71294 --- /dev/null +++ b/problems/src/greedy/QueueReconstructionByHeight.java @@ -0,0 +1,40 @@ +package greedy; + +import java.util.Arrays; +import java.util.LinkedList; + +/** + * Created by gouthamvidyapradhan on 29/06/2017. + * Suppose you have a random list of people standing in a queue. Each person is described by a pair of integers (h, k), where h is the height of the person and k is the number of people in front of this person who have a height greater than or equal to h. Write an algorithm to reconstruct the queue. + + Note: + The number of people is less than 1,100. + + Example + + 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 QueueReconstructionByHeight { + public static void main(String[] args) throws Exception{ + int[][] A = {{7,0}, {4,4}, {7,1}, {5,0}, {6,1}, {5,2}}; + int[][] r = new QueueReconstructionByHeight().reconstructQueue(A); + for(int[] i : r){ + System.out.println(i[0] + " " + i[1]); + } + } + + public int[][] reconstructQueue(int[][] people) { + Arrays.sort(people, ((o1, o2) -> (o2[0] - o1[0] == 0) ? o1[1] - o2[1] : o2[0] - o1[0])); + LinkedList list = new LinkedList<>(); + for(int[] p : people) + list.add(p[1], p); + int[][] result = new int[people.length][2]; + for(int i = 0, l = list.size(); i < l; i ++) + result[i] = list.get(i); + return result; + } +} From 0a0bae34a8d78a8f7c25fd4218478ce706de0096 Mon Sep 17 00:00:00 2001 From: Goutham Pradhan Date: Mon, 3 Jul 2017 17:42:51 +0200 Subject: [PATCH 037/235] Implement Trie (Prefix Tree) : Accepted --- README.md | 1 + problems/src/design/Trie.java | 93 +++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 problems/src/design/Trie.java diff --git a/README.md b/README.md index 868971fe..22225bf9 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Serialize Deserialize Binary Tree](problems/src/design/SerializeDeserializeBinaryTree.java) (Hard) - [Design Twitter](problems/src/design/Twitter.java) (Medium) - [Tic-Tac-Toe](problems/src/design/TicTacToe.java) (Medium) +- [Implement Trie (Prefix Tree)](problems/src/design/Trie.java) (Medium) #### [Divide and Conquer](problems/src/divide_and_conquer) diff --git a/problems/src/design/Trie.java b/problems/src/design/Trie.java new file mode 100644 index 00000000..3b6f8711 --- /dev/null +++ b/problems/src/design/Trie.java @@ -0,0 +1,93 @@ +package design; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by Goutham Vidya Pradhan on 7/3/2017. + * Implement a trie with insert, search, and startsWith methods. + + Note: + You may assume that all inputs are consist of lowercase letters a-z. + */ +public class Trie { + + private Map map; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + Trie trie = new Trie(); + trie.insert("boxing"); + trie.insert("box"); + System.out.println(trie.search("boxing")); + System.out.println(trie.startsWith("box")); + System.out.println(trie.search("box")); + } + + /** Initialize your data structure here. */ + public Trie() { + map = new HashMap<>(); + } + + /** Inserts a word into the trie. */ + public void insert(String word) { + if(word != null){ + add(0, word, word.length()); + } + } + + private void add(int i, String word, int length){ + if(i < length){ + char c = word.charAt(i); + Trie subTrie = map.get(c); + if(subTrie == null){ + subTrie = new Trie(); + map.put(c, subTrie); + } + subTrie.add(i + 1, word, length); + } + else map.put(null, new Trie()); //use null to indicate end of string + } + + /** Returns if the word is in the trie. */ + public boolean search(String word) { + if(word != null){ + return search(0, word, word.length()); + } + return false; + } + + private boolean search(int i, String word, int length){ + if(i < length){ + char c = word.charAt(i); + Trie subTrie = map.get(c); + if(subTrie == null) + return false; + return subTrie.search(i + 1, word, length); + } + return map.containsKey(null); + } + + /** Returns if there is any word in the trie that starts with the given prefix. */ + public boolean startsWith(String prefix) { + if(prefix != null){ + return startsWith(0, prefix, prefix.length()); + } + return false; + } + + private boolean startsWith(int i, String prefix, int length){ + if(i < length){ + char c = prefix.charAt(i); + Trie subTrie = map.get(c); + if(subTrie == null) + return false; + return subTrie.startsWith(i + 1, prefix, length); + } + else return true; + } + +} From bb79f5e246708640b068e29bade1a3c854d27e50 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 4 Jul 2017 01:08:59 +0200 Subject: [PATCH 038/235] CanIWin : Accepted --- README.md | 1 + problems/src/dynamic_programming/CanIWin.java | 76 +++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 problems/src/dynamic_programming/CanIWin.java diff --git a/README.md b/README.md index 22225bf9..59a6a8eb 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,7 @@ My accepted leetcode solutions to some of the common interview problems. - [WordBreak](problems/src/dynamic_programming/WordBreak.java) (Medium) - [WordBreak II](problems/src/dynamic_programming/WordBreakII.java) (Hard) - [Concatenated Words](problems/src/dynamic_programming/ConcatenatedWords.java) (Hard) +- [Can I Win](problems/src/dynamic_programming/CanIWin.java) (Medium) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/CanIWin.java b/problems/src/dynamic_programming/CanIWin.java new file mode 100644 index 00000000..3042da02 --- /dev/null +++ b/problems/src/dynamic_programming/CanIWin.java @@ -0,0 +1,76 @@ +package dynamic_programming; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by gouthamvidyapradhan on 04/07/2017. + * In the "100 game," two players take turns adding, to a running total, any integer from 1..10. The player who first causes the running total to reach or exceed 100 wins. + + What if we change the game so that players cannot re-use integers? + + For example, two players might take turns drawing from a common pool of numbers of 1..15 without replacement until they reach a total >= 100. + + Given an integer maxChoosableInteger and another integer desiredTotal, determine if the first player to move can force a win, assuming both players play optimally. + + You can always assume that maxChoosableInteger will not be larger than 20 and desiredTotal will not be larger than 300. + + Example + + Input: + maxChoosableInteger = 10 + desiredTotal = 11 + + Output: + false + + Explanation: + No matter which integer the first player choose, the first player will lose. + The first player can choose an integer from 1 up to 10. + If the first player choose 1, the second player can only choose integers from 2 up to 10. + The second player will win by choosing 10 and get a total = 11, which is >= desiredTotal. + Same with other integers chosen by the first player, the second player will always win. + */ +public class CanIWin { + + private Map> DP; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new CanIWin().canIWin(5, 15)); + } + + public boolean canIWin(int maxChoosableInteger, int desiredTotal) { + int sum = 0; + for(int i = 1; i <= maxChoosableInteger; i ++) + sum += i; + if(desiredTotal == 0) return true; + else if(desiredTotal > sum) return false; //if the desiredTotal exceeds the max possible sum return false; + DP = new HashMap<>(); + DP.put(true, new HashMap<>()); + DP.put(false, new HashMap<>()); + return dp(0, maxChoosableInteger, desiredTotal, true, 0); + } + + private boolean dp(int state, int M, int D, boolean P, int sum){ + if(sum >= D) return false; + Map map = DP.get(P); + if(map.containsKey(state)) + return map.get(state); + else { + map.put(state, false); + for(int i = 0; i < M; i ++){ + if((state & (1 << i)) == 0){ + if(!dp(state | (1 << i), M, D, !P, sum + i + 1)){ + map.put(state, true); + break; + } + } + } + } + return map.get(state); + } +} From e424652287294d9d7535c4a3acadea6096732495 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 4 Jul 2017 01:40:13 +0200 Subject: [PATCH 039/235] Delete Node in a Linked List : Accepted --- README.md | 1 + problems/src/linked_list/DeleteNode.java | 43 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 problems/src/linked_list/DeleteNode.java diff --git a/README.md b/README.md index 59a6a8eb..b93dfce1 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Merge Two Sorted List](problems/src/linked_list/MergeTwoSortedList.java) (Easy) - [Paliandrome List](problems/src/linked_list/PaliandromeList.java) (Easy) - [Reverse Linked List](problems/src/linked_list/ReverseLinkedList.java) (Easy) +- [Delete Node in a Linked List](problems/src/linked_list/DeleteNode.java) (Easy) #### [Math](problems/src/math) diff --git a/problems/src/linked_list/DeleteNode.java b/problems/src/linked_list/DeleteNode.java new file mode 100644 index 00000000..50a5172a --- /dev/null +++ b/problems/src/linked_list/DeleteNode.java @@ -0,0 +1,43 @@ +package linked_list; + +/** + * Created by gouthamvidyapradhan on 04/07/2017. + * Write a function to delete a node (except the tail) in a singly linked list, given only access to that node. + + Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function. + + */ +public class DeleteNode { + public static class ListNode { + int val; + ListNode next; + ListNode(int x) { val = x; } + } + + 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); + new DeleteNode().deleteNode(node.next.next); + while (node != null){ + System.out.println(node.val); + node = node.next; + } + } + + public void deleteNode(ListNode node) { + ListNode prev = node; + ListNode last = node; + ListNode next = node.next; + while(next != null){ + last = prev; + int temp = prev.val; + prev.val = next.val; + next.val = temp; + prev = prev.next; + next = next.next; + } + last.next = null; + } +} From 29a49cb02cbd116c015fd1660e626da90a8f6d57 Mon Sep 17 00:00:00 2001 From: Goutham Pradhan Date: Tue, 4 Jul 2017 14:11:43 +0200 Subject: [PATCH 040/235] WordSearchII : Accepted --- README.md | 3 +- problems/src/backtracking/WordSearchII.java | 110 ++++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 problems/src/backtracking/WordSearchII.java diff --git a/README.md b/README.md index b93dfce1..6fa2d7a5 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,8 @@ My accepted leetcode solutions to some of the common interview problems. - [Permutations II](problems/src/backtracking/PermutationsII.java) (Medium) - [SubSets](problems/src/backtracking/Subsets.java) (Medium) - [SubSet II](problems/src/backtracking/SubsetsII.java) (Medium) -- [WordSearch](problems/src/backtracking/WordSearch.java) (Medium) +- [Word Search](problems/src/backtracking/WordSearch.java) (Medium) +- [Word Search II](problems/src/backtracking/WordSearchII.java) (Hard) - [Generate Parentheses](problems/src/backtracking/GenerateParentheses.java) (Medium) #### [Binary Search](problems/src/binary_search) diff --git a/problems/src/backtracking/WordSearchII.java b/problems/src/backtracking/WordSearchII.java new file mode 100644 index 00000000..bf4333e2 --- /dev/null +++ b/problems/src/backtracking/WordSearchII.java @@ -0,0 +1,110 @@ +package backtracking; + +import java.util.*; + +/** + * Created by pradhang on 7/4/2017. + * Given a 2D board and a list of words from the dictionary, find all words in the board. + + Each word must be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word. + + For example, + Given words = ["oath","pea","eat","rain"] and board = + + [ + ['o','a','a','n'], + ['e','t','a','e'], + ['i','h','k','r'], + ['i','f','l','v'] + ] + Return ["eat","oath"]. + Note: + You may assume that all inputs are consist of lowercase letters a-z. + */ +public class WordSearchII { + private final int[] R = {0, 0, -1, 1}; + private final int[] C = {-1, 1, 0, 0}; + boolean[][] visited; + private Set dictionary; + + public static void main(String[] args) throws Exception{ + char[][] board = {{'o','a','a','n'},{'e','t','a','e'},{'i','h','k','r'},{'i','f','l','v'}}; + String[] words = {"oath","pea","eat","rain"}; + System.out.println(new WordSearchII().findWords(board, words)); + } + + public List findWords(char[][] board, String[] words) { + dictionary = new HashSet<>(); + Trie trie = new Trie(); + for(String w : words){ + trie.insert(w); + dictionary.add(w); + } + visited = new boolean[board.length][board[0].length]; + Set resultSet = new HashSet<>(); + for(int i = 0; i < board.length; i ++){ + for(int j = 0; j < board[0].length; j++){ + dfs(i, j, board, resultSet, trie, String.valueOf(board[i][j])); + } + } + return new ArrayList<>(resultSet); + } + + private void dfs(int r, int c, char[][] board, Set result, Trie trie, String s){ + char newChar = board[r][c]; + Trie subTrie = trie.next(newChar); + if(subTrie == null) return; + visited[r][c] = true; + if(dictionary.contains(s)) + result.add(s); + for(int i = 0; i < 4; i ++){ + int newR = r + R[i]; + int newC = c + C[i]; + if(newR >= 0 && newC >= 0 && newR < board.length && newC < board[0].length){ + if(!visited[newR][newC]){ + dfs(newR, newC, board, result, subTrie, s + board[newR][newC]); + } + } + } + visited[r][c] = false; + } + + private class Trie { + + private Map map; + + /** Initialize your data structure here. */ + public Trie() { + map = new HashMap<>(); + } + + /** Inserts a word into the trie. */ + public void insert(String word) { + if(word != null){ + add(0, word, word.length()); + } + } + + private void add(int i, String word, int length){ + if(i < length){ + char c = word.charAt(i); + Trie subTrie = map.get(c); + if(subTrie == null){ + subTrie = new Trie(); + map.put(c, subTrie); + } + subTrie.add(i + 1, word, length); + } + else map.put(null, new Trie()); //use null to indicate end of string + } + + /** + * Get next Trie node + * @param c char c + * @return return Trie + */ + public Trie next(char c){ + return this.map.get(c); + } + } +} From 00263391ace8dd9973095aa98019e1e945c852e6 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 4 Jul 2017 23:38:12 +0200 Subject: [PATCH 041/235] MissingNumber and RemoveDuplicates : Accepted --- README.md | 2 ++ problems/src/array/MissingNumber.java | 29 ++++++++++++++++ .../src/two_pointers/RemoveDuplicates.java | 33 +++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 problems/src/array/MissingNumber.java create mode 100644 problems/src/two_pointers/RemoveDuplicates.java diff --git a/README.md b/README.md index b93dfce1..77610ed8 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Merge Intervals](problems/src/array/MergeIntervals.java) (Medium) - [First Missing Positive](problems/src/array/FirstMissingPositive.java) (Hard) - [MaxProduct Of Three Numbers](problems/src/array/MaxProductOfThreeNumbers.java) (Easy) +- [Missing Number](problems/src/array/MissingNumber.java) (Easy) #### [Backtracking](problems/src/backtracking) @@ -177,3 +178,4 @@ My accepted leetcode solutions to some of the common interview problems. - [Trapping Rain Water](problems/src/two_pointers/TrappingRainWater.java) (Hard) - [3Sum Closest](problems/src/two_pointers/ThreeSumClosest.java) (Medium) - [Move Zeroes](problems/src/two_pointers/MoveZeroes.java) (Easy) +- [Remove Duplicates](problems/src/two_pointers/RemoveDuplicates.java) (Easy) diff --git a/problems/src/array/MissingNumber.java b/problems/src/array/MissingNumber.java new file mode 100644 index 00000000..512bc9fc --- /dev/null +++ b/problems/src/array/MissingNumber.java @@ -0,0 +1,29 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 04/07/2017. + * Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array. + + For example, + Given nums = [0, 1, 3] return 2. + + Note: + Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity? + */ +public class MissingNumber { + + public static void main(String[] args) throws Exception{ + int[] nums = {0}; + System.out.println(new MissingNumber().missingNumber(nums)); + } + public int missingNumber(int[] nums){ + int sum = 0; + int n = nums.length; + for (int num : nums) { + sum += num; + } + int arrSum = (((n + 1)) * n) / 2; + if(arrSum == sum) return 0; + else return arrSum - sum; + } +} diff --git a/problems/src/two_pointers/RemoveDuplicates.java b/problems/src/two_pointers/RemoveDuplicates.java new file mode 100644 index 00000000..96eb7131 --- /dev/null +++ b/problems/src/two_pointers/RemoveDuplicates.java @@ -0,0 +1,33 @@ +package two_pointers; + +/** + * Created by gouthamvidyapradhan on 04/07/2017. + * Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. + + Do not allocate extra space for another array, you must do this in place with constant memory. + + For example, + Given input array nums = [1,1,2], + + Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length. + */ +public class RemoveDuplicates { + public static void main(String[] args) throws Exception{ + int[] nums = {1, 1, 2}; + int N = new RemoveDuplicates().removeDuplicates(nums); + for(int i = 0; i < N; i ++) + System.out.print(nums[i] + " "); + } + public int removeDuplicates(int[] nums) { + if(nums.length == 1) return 1; + int size = 1; + for(int j = 0, i = 1; i < nums.length; i ++){ + if(nums[i] != nums[i - 1]){ + size++; + j++; + nums[j] = nums[i]; + } + } + return size; + } +} From 8ecc71848319db07eb7feecb892dda03cc6726c7 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 4 Jul 2017 23:56:30 +0200 Subject: [PATCH 042/235] ReverseWordsInAString : Accepted --- README.md | 1 + .../src/string/ReverseWordsInAString.java | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 problems/src/string/ReverseWordsInAString.java diff --git a/README.md b/README.md index 385cea8d..7fe46761 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,7 @@ My accepted leetcode solutions to some of the common interview problems. - [First Unique Character In a String](problems/src/string/FirstUniqueCharacterInAString.java) (Easy) - [Repeated Substring Pattern](problems/src/string/RepeatedSubstringPattern.java) (Easy) +- [Reverse Words In a String](problems/src/string/ReverseWordsInAString.java) (Medium) - [ReverseWords II](problems/src/string/ReverseWordsII.java) (Medium) - [String to Integer](problems/src/string/StringToInteger.java) (Medium) - [Text Justification](problems/src/string/TextJustification.java) (Hard) diff --git a/problems/src/string/ReverseWordsInAString.java b/problems/src/string/ReverseWordsInAString.java new file mode 100644 index 00000000..9d4822bb --- /dev/null +++ b/problems/src/string/ReverseWordsInAString.java @@ -0,0 +1,49 @@ +package string; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +/** + * Created by gouthamvidyapradhan on 04/07/2017. + * Given an input string, reverse the string word by word. + + For example, + Given s = "the sky is blue", + return "blue is sky the". + + Clarification: + What constitutes a word? + A sequence of non-space characters constitutes a word. + Could the input string contain leading or trailing spaces? + Yes. However, your reversed string should not contain leading or trailing spaces. + How about multiple spaces between two words? + Reduce them to a single space in the reversed string. + */ +public class ReverseWordsInAString { + public static void main(String[] args) throws Exception{ + System.out.println(new ReverseWordsInAString().reverseWords(" the sky is blue")); + } + + public String reverseWords(String s) { + if(s == null || s.isEmpty()) return ""; + StringBuilder sb = new StringBuilder(s.trim()); + String reverse = sb.reverse().toString(); + StringTokenizer st = new StringTokenizer(reverse, " "); + List list = new ArrayList<>(); + while(st.hasMoreTokens()){ + list.add(st.nextToken()); + } + for(int i = 0, l = list.size(); i < l; i ++){ + String str = list.get(i); + String newStr = new StringBuilder(str).reverse().toString(); + list.set(i, newStr); + } + StringBuilder result = new StringBuilder(); + for(String str : list){ + result.append(str).append(" "); + } + return result.toString().trim(); + } + +} From 6689aa749bc93f4b5d61fd6a06e489559cdaab11 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 5 Jul 2017 01:28:41 +0200 Subject: [PATCH 043/235] Flatten Binary Tree to Linked List : Accepted --- README.md | 1 + problems/src/tree/FlattenBinaryTree.java | 94 ++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 problems/src/tree/FlattenBinaryTree.java diff --git a/README.md b/README.md index 7fe46761..882c7288 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Closest Binary Search Tree Value](problems/src/tree/ClosestBinarySearchTreeValue.java) (Easy) - [Inorder Successor in BST](problems/src/tree/InorderSuccessorInBST.java) (Medium) - [Construct String From Binary Tree](problems/src/tree/ConstructStringFromBinaryTree.java) (Easy) +- [Flatten Binary Tree to Linked List](problems/src/tree/FlattenBinaryTree.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/FlattenBinaryTree.java b/problems/src/tree/FlattenBinaryTree.java new file mode 100644 index 00000000..b4b06ffb --- /dev/null +++ b/problems/src/tree/FlattenBinaryTree.java @@ -0,0 +1,94 @@ +package tree; +/** + * Created by gouthamvidyapradhan on 04/07/2017. + * Given a binary tree, flatten it to a linked list in-place. + + For example, + Given + + 1 + / \ + 2 5 + / \ \ + 3 4 6 + + The flattened tree should look like: + 1 + \ + 2 + \ + 3 + \ + 4 + \ + 5 + \ + 6 + + Solution: Do a pre-order traversal and maintain head and tail of a linked list at each recursive step. + i. Join the current node to the head of the left sub-list to form the current node as the new head. + ii. Join the tail of the left sub-list to the head of the right sub-list. + iii. Mark the left of the current node as null + */ +public class FlattenBinaryTree { + + /** + * Class to keep track of head and tail + */ + private class LinkNode{ + TreeNode head; + TreeNode tail; + LinkNode(TreeNode head, TreeNode tail){ + this.head = head; + this.tail = tail; + } + } + + public static class TreeNode + { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + public static void main(String[] args) throws Exception{ + TreeNode root = new TreeNode(3); + root.left = new TreeNode(2); + root.right = new TreeNode(1); + new FlattenBinaryTree().flatten(root); + System.out.print(root.val+ " "); + System.out.print(root.right.val + " "); + System.out.print(root.right.right.val); + } + + public void flatten(TreeNode root) { + preOrder(root); + } + + private LinkNode preOrder(TreeNode node){ + if(node == null) return null; + LinkNode left = preOrder(node.left); + LinkNode right = preOrder(node.right); + LinkNode lNode; + if(left == null && right == null){ + lNode = new LinkNode(node, node); + } + else if(left == null){ + node.right = right.head; + lNode = new LinkNode(node, right.tail); + } + else if(right == null){ + node.right = left.head; + lNode = new LinkNode(node, left.tail); + } + else { + node.right = left.head; + left.tail.right = right.head; + lNode = new LinkNode(node, right.tail); + } + node.left = null; + return lNode; + } + +} From b3dbe3d6fc4c6ec0deb3b7ed8271ea30a7ec3e49 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 7 Jul 2017 01:09:31 +0200 Subject: [PATCH 044/235] Reverse Nodes in k-Group : Accepted --- README.md | 1 + .../src/linked_list/ReverseNodesKGroup.java | 94 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 problems/src/linked_list/ReverseNodesKGroup.java diff --git a/README.md b/README.md index 882c7288..8a3bcedc 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Paliandrome List](problems/src/linked_list/PaliandromeList.java) (Easy) - [Reverse Linked List](problems/src/linked_list/ReverseLinkedList.java) (Easy) - [Delete Node in a Linked List](problems/src/linked_list/DeleteNode.java) (Easy) +- [Reverse Nodes in k-Group](problems/src/linked_list/ReverseNodesKGroup.java) (Hard) #### [Math](problems/src/math) diff --git a/problems/src/linked_list/ReverseNodesKGroup.java b/problems/src/linked_list/ReverseNodesKGroup.java new file mode 100644 index 00000000..fb058595 --- /dev/null +++ b/problems/src/linked_list/ReverseNodesKGroup.java @@ -0,0 +1,94 @@ +package linked_list; + +/** + * Created by gouthamvidyapradhan on 06/07/2017. + * Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. + + k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. + + You may not alter the values in the nodes, only nodes itself may be changed. + + Only constant memory is allowed. + + For example, + Given this linked list: 1->2->3->4->5 + + For k = 2, you should return: 2->1->4->3->5 + + For k = 3, you should return: 3->2->1->4->5 + + + Solution: O(N) solution with constant space. + Recursively reverse a group of K nodes and for each group join the tail of the prev group to the head + of the next group. + */ +public class ReverseNodesKGroup { + public static class ListNode { + int val; + ListNode next; + ListNode(int x) { val = x; } + } + + private ListNode newHead, newStart, prev; + + public static void main(String[] args) throws Exception{ + 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); + ListNode result = new ReverseNodesKGroup().reverseKGroup(node, 2); + while(result != null){ + System.out.println(result.val + " "); + result = result.next; + } + } + + public ListNode reverseKGroup(ListNode head, int k) { + if(head == null) return null; + ListNode node = head; + int count = 0; + while(node != null){ + node = node.next; + count++; + } + if(k > count) return head; + int N = count / k; + newStart = head; + ListNode tail = null; + ListNode result = null; + while(N -- > 0){ + tail = reverse(newStart, 1, k); + tail.next = null; + if(result == null) + result = newHead; //save the head only once + if(prev != null){ + prev.next = newHead; + } + prev = tail; + } + if(tail != null) + tail.next = newStart; + return result; + } + + /** + * Reverse k nodes + * @param node head node + * @param count count + * @param k K + * @return + */ + private ListNode reverse(ListNode node, int count, int k){ + if(count == k){ + newStart = node.next; //new start node + newHead = node; //mark this as the new head + } + else{ + ListNode nNode = reverse(node.next, count + 1, k); + nNode.next = node; + } + return node; + } + +} From 6a1edd9884c2c67b956f0912eaa4fdb5775ca818 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 7 Jul 2017 01:17:48 +0200 Subject: [PATCH 045/235] Populating Next Right Pointers in Each Node : Accepted --- README.md | 1 + problems/src/tree/NextRightPointer.java | 85 +++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 problems/src/tree/NextRightPointer.java diff --git a/README.md b/README.md index 8a3bcedc..b62acb26 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Inorder Successor in BST](problems/src/tree/InorderSuccessorInBST.java) (Medium) - [Construct String From Binary Tree](problems/src/tree/ConstructStringFromBinaryTree.java) (Easy) - [Flatten Binary Tree to Linked List](problems/src/tree/FlattenBinaryTree.java) (Medium) +- [Populating Next Right Pointers in Each Node](problems/src/tree/NextRightPointer.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/NextRightPointer.java b/problems/src/tree/NextRightPointer.java new file mode 100644 index 00000000..2c73016d --- /dev/null +++ b/problems/src/tree/NextRightPointer.java @@ -0,0 +1,85 @@ +package tree; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 07/07/2017. + * + Given a binary tree + + struct TreeLinkNode { + TreeLinkNode *left; + TreeLinkNode *right; + TreeLinkNode *next; + } + Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. + + Initially, all next pointers are set to NULL. + + Note: + + You may only use constant extra space. + You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children). + For example, + Given the following perfect binary tree, + 1 + / \ + 2 3 + / \ / \ + 4 5 6 7 + After calling your function, the tree should look like: + 1 -> NULL + / \ + 2 -> 3 -> NULL + / \ / \ + 4->5->6->7 -> NULL + +Solution: Perform a level order traversal using BFS, keep track of prev node at each level. Link the prev node to + current node if both the nodes are in the same level. + */ +public class NextRightPointer { + private class LevelNode{ + int level; + TreeLinkNode node; + LevelNode(TreeLinkNode node, int level){ + this.node = node; + this.level = level; + } + } + + public static class TreeLinkNode { + int val; + TreeLinkNode left, right, next; + TreeLinkNode(int x) { val = x; } + } + + public static void main(String[] args) throws Exception{ + TreeLinkNode node = new TreeLinkNode(2); + node.left = new TreeLinkNode(1); + node.right = new TreeLinkNode(3); + new NextRightPointer().connect(node); + System.out.println(node.next); + System.out.println(node.left.next.val); + System.out.println(node.right.next); + } + + public void connect(TreeLinkNode root) { + Queue queue = new ArrayDeque<>(); + LevelNode zero = new LevelNode(root, 0); + queue.offer(zero); + LevelNode prev = null; + while(!queue.isEmpty()){ + LevelNode levelNode = queue.poll(); + if(levelNode.node == null) break; + TreeLinkNode curr = levelNode.node; + if(prev != null){ + if(prev.level == levelNode.level){ + prev.node.next = levelNode.node; + } + } + prev = levelNode; + queue.offer(new LevelNode(curr.left, levelNode.level + 1)); + queue.offer(new LevelNode(curr.right, levelNode.level + 1)); + } + } + +} From 51f264d8db8e4e446b94631ce38114adb8e70fdb Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 7 Jul 2017 01:39:16 +0200 Subject: [PATCH 046/235] Maximum Subarray: Accepted --- README.md | 1 + .../dynamic_programming/MaximumSubarray.java | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 problems/src/dynamic_programming/MaximumSubarray.java diff --git a/README.md b/README.md index b62acb26..f9c161b4 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ My accepted leetcode solutions to some of the common interview problems. - [WordBreak II](problems/src/dynamic_programming/WordBreakII.java) (Hard) - [Concatenated Words](problems/src/dynamic_programming/ConcatenatedWords.java) (Hard) - [Can I Win](problems/src/dynamic_programming/CanIWin.java) (Medium) +- [Maximum Subarray](problems/src/dynamic_programming/MaximumSubarray.java) (Easy) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/MaximumSubarray.java b/problems/src/dynamic_programming/MaximumSubarray.java new file mode 100644 index 00000000..ec3fdc97 --- /dev/null +++ b/problems/src/dynamic_programming/MaximumSubarray.java @@ -0,0 +1,26 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 07/07/2017. + * Find the contiguous subarray within an array (containing at least one number) which has the largest sum. + + For example, given the array [-2,1,-3,4,-1,2,1,-5,4], + the contiguous subarray [4,-1,2,1] has the largest sum = 6. + */ +public class MaximumSubarray { + public static void main(String[] args) throws Exception{ + int[] nums = {-2,1,-3,4,-1,2,1,-5,4}; + System.out.println(new MaximumSubarray().maxSubArray(nums)); + } + + public int maxSubArray(int[] nums) { + if(nums.length == 1) return nums[0]; + int max = nums[nums.length - 1]; + for(int i = nums.length - 2; i >= 0; i --){ + nums[i] = Math.max(nums[i], nums[i] + nums[i + 1]); + max = Math.max(max, nums[i]); + } + return max; + } + +} From f498cfed72b9008af6867275717ed45397a90553 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 7 Jul 2017 02:04:59 +0200 Subject: [PATCH 047/235] ExcelSheetColumnNumber : Accepted --- README.md | 1 + .../src/string/ExcelSheetColumnNumber.java | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 problems/src/string/ExcelSheetColumnNumber.java diff --git a/README.md b/README.md index f9c161b4..f179d6e5 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Text Justification](problems/src/string/TextJustification.java) (Hard) - [ZigZag Conversion](problems/src/string/ZigZagConversion.java) (Medium) - [Implement StrStr](problems/src/string/ImplementStrStr.java) (Easy) +- [Excel Sheet Column Number](problems/src/string/ExcelSheetColumnNumber.java) (Easy) #### [Tree](problems/src/tree) diff --git a/problems/src/string/ExcelSheetColumnNumber.java b/problems/src/string/ExcelSheetColumnNumber.java new file mode 100644 index 00000000..db08bab8 --- /dev/null +++ b/problems/src/string/ExcelSheetColumnNumber.java @@ -0,0 +1,35 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 07/07/2017. + * Given a column title as appear in an Excel sheet, return its corresponding column number. + + For example: + + A -> 1 + B -> 2 + C -> 3 + ... + Z -> 26 + AA -> 27 + AB -> 28 + */ +public class ExcelSheetColumnNumber { + String CONST = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + public static void main(String[] args) throws Exception{ + System.out.println(new ExcelSheetColumnNumber().titleToNumber("AAB")); + } + + public int titleToNumber(String s) { + int total = 0; + int j = 0; + for(int i = s.length() - 1; i >= 0; i --){ + char c = s.charAt(i); + int pos = CONST.indexOf(c) + 1; + int pow = (int)Math.pow(26, j++); + total += (pow * pos); + } + return total; + } + +} From 43514bdf45f3b8a995684a5d2a5cc855b1fe6cfe Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 7 Jul 2017 15:04:24 +0200 Subject: [PATCH 048/235] SubtreeOfAnotherTree : Accepted --- README.md | 1 + problems/src/tree/SubtreeOfAnotherTree.java | 68 +++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 problems/src/tree/SubtreeOfAnotherTree.java diff --git a/README.md b/README.md index f179d6e5..5e819c11 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Construct String From Binary Tree](problems/src/tree/ConstructStringFromBinaryTree.java) (Easy) - [Flatten Binary Tree to Linked List](problems/src/tree/FlattenBinaryTree.java) (Medium) - [Populating Next Right Pointers in Each Node](problems/src/tree/NextRightPointer.java) (Medium) +- [Subtree of Another Tree](problems/src/tree/SubtreeOfAnotherTree.java) (Easy) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/SubtreeOfAnotherTree.java b/problems/src/tree/SubtreeOfAnotherTree.java new file mode 100644 index 00000000..9c27a515 --- /dev/null +++ b/problems/src/tree/SubtreeOfAnotherTree.java @@ -0,0 +1,68 @@ +package tree; +/** + * Created by gouthamvidyapradhan on 07/07/2017. + Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node's descendants. The tree s could also be considered as a subtree of itself. + + Example 1: + Given tree s: + + 3 + / \ + 4 5 + / \ + 1 2 + Given tree t: + 4 + / \ + 1 2 + Return true, because t has the same structure and node values with a subtree of s. + Example 2: + Given tree s: + + 3 + / \ + 4 5 + / \ + 1 2 + / + 0 + Given tree t: + 4 + / \ + 1 2 + Return false. + + */ +public class SubtreeOfAnotherTree { + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + public static void main(String[] args) throws Exception{ + } + + public boolean isSubtree(TreeNode s, TreeNode t) { + if(s != null){ + if(s.val == t.val) { + if(equal(s, t)) + return true; + else return (isSubtree(s.left, t) || isSubtree(s.right, t)); + } + else return (isSubtree(s.left, t) || isSubtree(s.right, t)); + } + return false; + } + + private boolean equal(TreeNode s, TreeNode t){ + if (s == null && t == null) + return true; + else if(s == null || t == null) + return false; + else if(s.val != t.val) return false; + else return equal(s.left, t.left) && equal(s.right, t.right); + } + +} From 3270c8b41e02f212b7cd49aabbcaca6cbc79b5d0 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 11 Jul 2017 00:00:34 +0200 Subject: [PATCH 049/235] Find Peak Element : Accepted --- README.md | 1 + .../src/binary_search/FindPeakElement.java | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 problems/src/binary_search/FindPeakElement.java diff --git a/README.md b/README.md index 5e819c11..1a89e9ed 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Search Insert Position](problems/src/binary_search/SearchInsertPosition.java) (Easy) - [Median of Two Sorted Arrays](problems/src/binary_search/MedianOfTwoSortedArrays.java) (Hard) - [Pow(x, n)](problems/src/binary_search/PowXN.java) (Medium) +- [Find Peak Element](problems/src/binary_search/FindPeakElement.java) (Medium) #### [Bit Manipulation](problems/src/bit_manipulation) diff --git a/problems/src/binary_search/FindPeakElement.java b/problems/src/binary_search/FindPeakElement.java new file mode 100644 index 00000000..ae6e8ba2 --- /dev/null +++ b/problems/src/binary_search/FindPeakElement.java @@ -0,0 +1,55 @@ +package binary_search; + +/** + * Created by gouthamvidyapradhan on 10/07/2017. + * A peak element is an element that is greater than its neighbors. + + Given an input array where num[i] ≠ num[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 num[-1] = num[n] = -∞. + + For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2. + + Note: + Your solution should be in logarithmic complexity. + + Solution: O(log N) check if the first or the last element is the peak element, if yes then return this index. + Else binary search for the answer - check mid element if this is a peak element return this index, else if the + left element is greater than current element search left else search right. + */ +public class FindPeakElement { + public static void main(String[] args) throws Exception{ + int[] nums = {3, 4, 3, 2, 1}; + System.out.println(new FindPeakElement().findPeakElement(nums)); + } + + public int findPeakElement(int[] nums) { + if(nums.length == 1)return 0; + if(nums[0] > nums[1]) + return 0; + else if(nums[nums.length - 1] > nums[nums.length - 2]) + return nums.length - 1; + + int l = 0, h = nums.length - 1; + int ans = 0; + while(l <= h){ + int m = l + (h - l) / 2; + if(m - 1 >= 0 && m + 1 < nums.length){ + if(nums[m] > nums[m - 1] && nums[m] > nums[m + 1]){ + return m; + } + } + if(m - 1 >= 0 && nums[m - 1] > nums[m]){ //search left + h = m - 1; + } + else { + ans = l; //mark this as the answer and search right + l = m + 1; + } + } + return ans; + } + +} From 247de1a097fd1af86193b7d42f6df0e814da5a64 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 11 Jul 2017 00:34:33 +0200 Subject: [PATCH 050/235] TwoSum : Accepted --- README.md | 1 + problems/src/array/TwoSum.java | 66 ++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 problems/src/array/TwoSum.java diff --git a/README.md b/README.md index 1a89e9ed..456fb200 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Rotate Matrix](problems/src/array/RotateMatrix.java) (Medium) - [Set Matrix Zeroes](problems/src/array/SetMatrixZeroes.java) (Medium) - [Third Maximum Number](problems/src/array/ThirdMaximumNumber.java) (Easy) +- [Two Sum](problems/src/array/TwoSum.java) (Easy) - [TwoSum II](problems/src/array/TwoSumII.java) (Easy) - [Can Place Flowers](problems/src/array/CanPlaceFlowers.java) (Easy) - [Merge Intervals](problems/src/array/MergeIntervals.java) (Medium) diff --git a/problems/src/array/TwoSum.java b/problems/src/array/TwoSum.java new file mode 100644 index 00000000..6fd0cc2f --- /dev/null +++ b/problems/src/array/TwoSum.java @@ -0,0 +1,66 @@ +package array; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by gouthamvidyapradhan on 11/07/2017. + * Given an array of integers, return indices of the two numbers such that they add up to a specific target. + + You may assume that each input would have exactly one solution, and you may not use the same element twice. + + Example: + Given nums = [2, 7, 11, 15], target = 9, + + Because nums[0] + nums[1] = 2 + 7 = 9, + return [0, 1]. + + Solution: O(n log n). Wrap index and element in a class and sort in increasing order. Do a two pointer sum and compare. + An alternative solution is to use hashing which is a O(n) solution - For each element e check if element (target - e) + is already found in hashset, if yes return their index, else add this to hash-set and continue. + */ +public class TwoSum { + + class NumIndex + { + int i, e; + NumIndex(int i, int e){ + this.i = i; + this.e = e; + } + } + + public static void main(String[] args) { + int[] nums = {3, 2, 4}; + int[] ans = new TwoSum().twoSum(nums, 6); + for (int i : ans) + System.out.println(i); + } + + public int[] twoSum(int[] nums, int target) { + List list = new ArrayList<>(); + for(int i = 0; i < nums.length; i ++){ + NumIndex n = new NumIndex(i, nums[i]); + list.add(n); + } + list.sort((o1, o2) -> Integer.compare(o1.e, o2.e)); + + int[] ans = new int[2]; + for(int i = 0, j = nums.length - 1; i < j; ){ + NumIndex numi = list.get(i); + NumIndex numj = list.get(j); + int sum = numi.e + numj.e; + if(sum == target){ + ans[0] = numi.i; + ans[1] = numj.i; + return ans; + } + else if(sum > target){ + j --; + } + else i++; + } + return ans; + } + +} From f8fc631f8058ecb7de0ebc30ade2ea89f1127933 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 12 Jul 2017 00:09:29 +0200 Subject: [PATCH 051/235] HouseRobberII, CompareVersionNumbers and ZigZagTraversal : Accepted --- README.md | 3 + .../dynamic_programming/HouseRobberII.java | 48 +++++++++++++++ .../src/string/CompareVersionNumbers.java | 54 +++++++++++++++++ problems/src/tree/ZigZagTraversal.java | 59 +++++++++++++++++++ 4 files changed, 164 insertions(+) create mode 100644 problems/src/dynamic_programming/HouseRobberII.java create mode 100644 problems/src/string/CompareVersionNumbers.java create mode 100644 problems/src/tree/ZigZagTraversal.java diff --git a/README.md b/README.md index 456fb200..cb1436a1 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Coin Change 2](problems/src/dynamic_programming/CoinChange2.java) (Medium) - [Decode Ways](problems/src/dynamic_programming/DecodeWays.java) (Medium) - [House Robber](problems/src/dynamic_programming/HouseRobber.java) (Easy) +- [House Robber II](problems/src/dynamic_programming/HouseRobberII.java) (Medium) - [Longest Increasing Subsequence](problems/src/dynamic_programming/LongestIncreasingSubsequence.java) (Medium) - [Longest Paliandromic Substring](problems/src/dynamic_programming/LongestPaliandromicSubstring.java) (Medium) - [Longest Palindromic Subsequence](problems/src/dynamic_programming/LongestPalindromicSubsequence.java) (Medium) @@ -156,6 +157,7 @@ My accepted leetcode solutions to some of the common interview problems. - [ZigZag Conversion](problems/src/string/ZigZagConversion.java) (Medium) - [Implement StrStr](problems/src/string/ImplementStrStr.java) (Easy) - [Excel Sheet Column Number](problems/src/string/ExcelSheetColumnNumber.java) (Easy) +- [Compare Version Numbers](problems/src/string/CompareVersionNumbers.java) (Easy) #### [Tree](problems/src/tree) @@ -179,6 +181,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Flatten Binary Tree to Linked List](problems/src/tree/FlattenBinaryTree.java) (Medium) - [Populating Next Right Pointers in Each Node](problems/src/tree/NextRightPointer.java) (Medium) - [Subtree of Another Tree](problems/src/tree/SubtreeOfAnotherTree.java) (Easy) +- [Binary Tree Zigzag Level Order Traversal](problems/src/tree/ZigZagTraversal.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/dynamic_programming/HouseRobberII.java b/problems/src/dynamic_programming/HouseRobberII.java new file mode 100644 index 00000000..f3554c76 --- /dev/null +++ b/problems/src/dynamic_programming/HouseRobberII.java @@ -0,0 +1,48 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by pradhang on 7/11/2017. + * After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. + * This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street. + + Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. + */ +public class HouseRobberII { + public static void main(String[] args) throws Exception{ + int[] nums = {6,3,10,8,2,10,3,5,10,5,3}; + System.out.println(new HouseRobberII().rob(nums)); + } + + public int rob(int[] nums) { + if(nums.length == 0) return 0; + if(nums.length == 1) + return nums[0]; + else if(nums.length == 2){ + if(nums[0] > nums[1]) + return nums[0]; + return nums[1]; + } + else if(nums.length == 3) return Math.max(Math.max(nums[0], nums[1]), nums[2]); + int[] DP = new int[nums.length]; + for(int i = nums.length - 1; i > 0; i --){ + if(i + 3 < nums.length) + DP[i] = Math.max(nums[i] + DP[i + 2], nums[i] + DP[i + 3]); + else if(i + 2 < nums.length) + DP[i] = nums[i] + DP[i + 2]; + else DP[i] = nums[i]; + } + int max = Math.max(DP[1], DP[2]); + Arrays.fill(DP, 0); //reset + for(int i = nums.length - 2; i >= 0; i --){ + if(i + 3 < nums.length) + DP[i] = Math.max(nums[i] + DP[i + 2], nums[i] + DP[i + 3]); + else if(i + 2 < nums.length) + DP[i] = nums[i] + DP[i + 2]; + else DP[i] = nums[i]; + } + max = Math.max(max, Math.max(DP[0], DP[1])); + return max; + } +} diff --git a/problems/src/string/CompareVersionNumbers.java b/problems/src/string/CompareVersionNumbers.java new file mode 100644 index 00000000..8d7a814a --- /dev/null +++ b/problems/src/string/CompareVersionNumbers.java @@ -0,0 +1,54 @@ +package string; + +import java.util.StringTokenizer; + +/** + * Created by pradhang on 7/11/2017. + * Compare two version numbers version1 and version2. + If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0. + + You may assume that the version strings are non-empty and contain only digits and the . character. + The . character does not represent a decimal point and is used to separate number sequences. + For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision. + + Here is an example of version numbers ordering: + + 0.1 < 1.1 < 1.2 < 13.37 + */ +public class CompareVersionNumbers { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new CompareVersionNumbers().compareVersion("1.11.1", "1.11")); + } + + public int compareVersion(String version1, String version2) { + StringTokenizer st1 = new StringTokenizer(version1, "."); + StringTokenizer st2 = new StringTokenizer(version2, "."); + while(st1.hasMoreTokens() & st2.hasMoreTokens()){ + int token1 = Integer.parseInt(st1.nextToken()); + int token2 = Integer.parseInt(st2.nextToken()); + if(token1 > token2) + return 1; + else if(token2 > token1) + return -1; + } + if(st1.countTokens() > st2.countTokens()){ + while(st1.hasMoreTokens()){ + if(Integer.parseInt(st1.nextToken()) > 0) + return 1; + } + } + else if(st2.countTokens() > st1.countTokens()){ + while(st2.hasMoreTokens()){ + if(Integer.parseInt(st2.nextToken()) > 0) + return -1; + } + } + return 0; + } + +} diff --git a/problems/src/tree/ZigZagTraversal.java b/problems/src/tree/ZigZagTraversal.java new file mode 100644 index 00000000..216acdd4 --- /dev/null +++ b/problems/src/tree/ZigZagTraversal.java @@ -0,0 +1,59 @@ +package tree; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * Created by pradhang on 7/11/2017. + * Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). + + For example: + Given binary tree [3,9,20,null,null,15,7], + 3 + / \ + 9 20 + / \ + 15 7 + return its zigzag level order traversal as: + [ + [3], + [20,9], + [15,7] + ] + */ +public class ZigZagTraversal { + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + public static void main(String[] args) throws Exception{ + + } + public List> zigzagLevelOrder(TreeNode root) { + List> result = new ArrayList<>(); + if(root == null) return result; + dfs(root, 0, result); + return result; + } + + @SuppressWarnings("unchecked") + private void dfs(TreeNode root, int level, List> result){ + if(root != null){ + LinkedList subList; + if(level >= result.size()){ + subList = new LinkedList<>(); + result.add(subList); + }else subList = (LinkedList)result.get(level); + if(level % 2 == 0) + subList.addFirst(root.val); //add to right + else subList.add(root.val); //add to left + dfs(root.right, level + 1, result); + dfs(root.left, level + 1, result); + } + } +} From 8e491f19c0971977a4d1dccf88e353af41f648ff Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 12 Jul 2017 01:54:55 +0200 Subject: [PATCH 052/235] DungeonGame : Accepted --- README.md | 1 + .../src/dynamic_programming/DungeonGame.java | 77 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 problems/src/dynamic_programming/DungeonGame.java diff --git a/README.md b/README.md index cb1436a1..075c6ce3 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Concatenated Words](problems/src/dynamic_programming/ConcatenatedWords.java) (Hard) - [Can I Win](problems/src/dynamic_programming/CanIWin.java) (Medium) - [Maximum Subarray](problems/src/dynamic_programming/MaximumSubarray.java) (Easy) +- [Dungeon Game](problems/src/dynamic_programming/DungeonGame.java) (Hard) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/DungeonGame.java b/problems/src/dynamic_programming/DungeonGame.java new file mode 100644 index 00000000..f58ba285 --- /dev/null +++ b/problems/src/dynamic_programming/DungeonGame.java @@ -0,0 +1,77 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 12/07/2017. + * 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. + + Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon entering these rooms; other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers). + + In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step. + + + Write a function to determine the knight's minimum initial health so that he is able to rescue the princess. + + For example, given the dungeon below, the initial health of the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN. + + -2 (K) -3 3 + -5 -10 1 + 10 30 -5 (P) + + Notes: + + The knight's health has no upper bound. + Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned. + + Solution: O(MxN log Integer.MAX_VALUE) + Binary search the suitable initial health value in the range (1, Integer.MAX_VALUE) and do a top down DP to check the + balance health when he reaches princess. + */ +public class DungeonGame { + private final int[] R = {0, -1}; + private final int[] C = {-1, 0}; + private int DP[][]; + public static void main(String[] args) throws Exception{ + int[][] dungeon = {{200}}; + System.out.println(new DungeonGame().calculateMinimumHP(dungeon)); + } + + public int calculateMinimumHP(int[][] dungeon) { + DP = new int[dungeon.length][dungeon[0].length]; + int l = 0, h = Integer.MAX_VALUE, ans = 0; + while(l <= h){ + int m = l + (h - l) / 2; + for(int i = 0; i < dungeon.length; i ++) + Arrays.fill(DP[i], Integer.MIN_VALUE); + DP[0][0] = m + dungeon[0][0]; + if(dp(dungeon, dungeon.length - 1, dungeon[0].length - 1) > 0){ + ans = m; + h = m - 1; + }else{ + l = m + 1; + } + } + return ans == 0 ? 1 : ans; + } + + private int dp(int[][] dungeon, int r, int c){ + if(DP[r][c] != Integer.MIN_VALUE) + return DP[r][c]; + for(int i = 0; i < 2; i ++){ + int newR = r + R[i]; + int newC = c + C[i]; + if(newR >= 0 && newR < dungeon.length && newC >=0 && newC < dungeon[0].length){ + int life = dp(dungeon, newR, newC); + if(life <= 0) + DP[r][c] = Math.max(DP[r][c], 0); + else DP[r][c] = Math.max(DP[r][c], dungeon[r][c] + life); + } + + } + return DP[r][c]; + } +} From 05c2076caf546aa709c26ac091d84584c2f8dca4 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 26 Jul 2017 00:19:45 +0200 Subject: [PATCH 053/235] ValidPalindrome : Accepted --- README.md | 1 + problems/src/string/ValidPalindrome.java | 44 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 problems/src/string/ValidPalindrome.java diff --git a/README.md b/README.md index 075c6ce3..5271a136 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Implement StrStr](problems/src/string/ImplementStrStr.java) (Easy) - [Excel Sheet Column Number](problems/src/string/ExcelSheetColumnNumber.java) (Easy) - [Compare Version Numbers](problems/src/string/CompareVersionNumbers.java) (Easy) +- [Valid Palindrome](problems/src/string/ValidPalindrome.java) (Easy) #### [Tree](problems/src/tree) diff --git a/problems/src/string/ValidPalindrome.java b/problems/src/string/ValidPalindrome.java new file mode 100644 index 00000000..1a565826 --- /dev/null +++ b/problems/src/string/ValidPalindrome.java @@ -0,0 +1,44 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 13/07/2017. + * Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. + + For example, + "A man, a plan, a canal: Panama" is a palindrome. + "race a car" is not a palindrome. + + Note: + Have you consider that the string might be empty? This is a good question to ask during an interview. + + For the purpose of this problem, we define empty string as valid palindrome. + + + */ +public class ValidPalindrome { + public static void main(String[] args) throws Exception{ + System.out.println(new ValidPalindrome().isPalindrome("989 ")); + } + + public boolean isPalindrome(String s) { + if(s == null || s.isEmpty()) return true; + s = s.toLowerCase(); + for(int i = 0,j = s.length() - 1; i < j; ){ + char f = s.charAt(i); + char l = s.charAt(j); + if(!(f >= 'a' && f <= 'z') && !(f >= '0' && f <= '9')){ + i++; + continue; + } + if(!(l >= 'a' && l <= 'z') && !(l >= '0' && l <= '9')){ + j--; + continue; + } + if(f != l) + return false; + i++; j --; + } + return true; + } + +} From 9e646ac4f92319f5b7d3c2f32cfbdaf2129b7168 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 28 Jul 2017 19:44:06 +0200 Subject: [PATCH 054/235] SimplifyPath : Accepted --- README.md | 1 + problems/src/string/SimplifyPath.java | 55 +++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 problems/src/string/SimplifyPath.java diff --git a/README.md b/README.md index 5271a136..9954dd7e 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Excel Sheet Column Number](problems/src/string/ExcelSheetColumnNumber.java) (Easy) - [Compare Version Numbers](problems/src/string/CompareVersionNumbers.java) (Easy) - [Valid Palindrome](problems/src/string/ValidPalindrome.java) (Easy) +- [Simplify Path](problems/src/string/SimplifyPath.java) (Medium) #### [Tree](problems/src/tree) diff --git a/problems/src/string/SimplifyPath.java b/problems/src/string/SimplifyPath.java new file mode 100644 index 00000000..ebd3be19 --- /dev/null +++ b/problems/src/string/SimplifyPath.java @@ -0,0 +1,55 @@ +package string; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.StringTokenizer; + +/** + * Created by gouthamvidyapradhan on 28/07/2017. + * + * Given an absolute path for a file (Unix-style), simplify it. + + For example, + path = "/home/", => "/home" + path = "/a/./b/../../c/", => "/c" + + Corner Cases: + Did you consider the case where path = "/../"? + In this case, you should return "/". + Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/". + In this case, you should ignore redundant slashes and return "/home/foo". + */ +public class SimplifyPath { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new SimplifyPath().simplifyPath("/home/")); + } + + public String simplifyPath(String path) { + if(path == null || path.isEmpty()) return "/"; + StringTokenizer st = new StringTokenizer(path, "/"); + Deque dQueue = new ArrayDeque<>(); + while(st.hasMoreTokens()){ + String token = st.nextToken(); + if(token.trim().equals("..")){ + if(!dQueue.isEmpty()) + dQueue.pop(); + } else if(token.trim().equals(".")){ + //ignore + } + else dQueue.push(token); + } + if(dQueue.isEmpty()) return "/"; + StringBuilder finalStr = new StringBuilder(); + while(!dQueue.isEmpty()){ + finalStr.append("/").append(dQueue.removeLast()); + } + return finalStr.toString(); + } + + +} From 5ca1a20495698c6aa1e78c75bd84724c34e98833 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 29 Jul 2017 13:48:35 +0200 Subject: [PATCH 055/235] WaterAndJugProblem : Accepted --- README.md | 1 + problems/src/math/WaterAndJugProblem.java | 44 +++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 problems/src/math/WaterAndJugProblem.java diff --git a/README.md b/README.md index 9954dd7e..3fc362fc 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Add Two Numbers](problems/src/math/AddTwoNumbers.java) (Medium) - [Count Primes](problems/src/math/CountPrimes.java) (Easy) - [Rotate Function](problems/src/math/RotateFunction.java) (Medium) +- [Water and Jug Problem](problems/src/math/WaterAndJugProblem.java) (Medium) #### [Stack](problems/src/stack) diff --git a/problems/src/math/WaterAndJugProblem.java b/problems/src/math/WaterAndJugProblem.java new file mode 100644 index 00000000..c53af0ca --- /dev/null +++ b/problems/src/math/WaterAndJugProblem.java @@ -0,0 +1,44 @@ +package math; + +import java.math.BigInteger; + +/** + * Created by gouthamvidyapradhan on 29/07/2017. + * You are given two jugs with capacities x and y litres. There is an infinite amount of water supply available. You need to determine whether it is possible to measure exactly z litres using these two jugs. + + If z liters of water is measurable, you must have z liters of water contained within one or both buckets by the end. + + Operations allowed: + + Fill any of the jugs completely with water. + Empty any of the jugs. + Pour water from one jug into another till the other jug is completely full or the first jug itself is empty. + Example 1: (From the famous "Die Hard" example) + + Input: x = 3, y = 5, z = 4 + Output: True + Example 2: + + Input: x = 2, y = 6, z = 5 + Output: False + + */ +public class WaterAndJugProblem { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new WaterAndJugProblem().canMeasureWater(0, 0, 1)); + } + + public boolean canMeasureWater(int x, int y, int z) { + if (x == y && y == z) return true; + if (z > (x + y)) return false; + BigInteger b1 = new BigInteger(String.valueOf(x)); + BigInteger b2 = new BigInteger(String.valueOf(y)); + BigInteger b3 = b1.gcd(b2); + return b3.intValue() != 0 && (z % b3.intValue()) == 0; + } +} From 95b6a74c96b342ab524630996ceeca0b98c8dae1 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 29 Jul 2017 14:45:53 +0200 Subject: [PATCH 056/235] MergeSortedArray : Accepted --- README.md | 1 + problems/src/array/MergeSortedArray.java | 45 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 problems/src/array/MergeSortedArray.java diff --git a/README.md b/README.md index 3fc362fc..ef2e3c10 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ My accepted leetcode solutions to some of the common interview problems. - [First Missing Positive](problems/src/array/FirstMissingPositive.java) (Hard) - [MaxProduct Of Three Numbers](problems/src/array/MaxProductOfThreeNumbers.java) (Easy) - [Missing Number](problems/src/array/MissingNumber.java) (Easy) +- [Merge Sorted Array](problems/src/array/MergeSortedArray.java) (Easy) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/MergeSortedArray.java b/problems/src/array/MergeSortedArray.java new file mode 100644 index 00000000..58dcbc2a --- /dev/null +++ b/problems/src/array/MergeSortedArray.java @@ -0,0 +1,45 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 29/07/2017. + * Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. + + Note: + You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively. + */ +public class MergeSortedArray { + public static void main(String[] args) throws Exception{ + int[] A = {0}; + int[] B = {1}; + new MergeSortedArray().merge(A, 0, B, 1); + for(int i : A) + System.out.println(i); + } + + public void merge(int[] nums1, int m, int[] nums2, int n) { + int s = m + n; + int l = s - 1; + for(int i = m - 1; i >= 0; i --, l --){ + nums1[l] = nums1[i]; + } + l++; //last index of nums1 + int i = 0, j = 0; + for(; i < s && l < s && j < n; i ++){ + if(nums1[l] <= nums2[j]){ + nums1[i] = nums1[l]; + l++; + } + else{ + nums1[i] = nums2[j]; + j++; + } + } + while(l < s){ + nums1[i++] = nums1[l++]; + } + while(j < n){ + nums1[i++] = nums2[j++]; + } + } + +} From 4aefb3decbc5004c021303c1f3e7dcea23385e06 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 29 Jul 2017 15:00:16 +0200 Subject: [PATCH 057/235] MergeSortedArray : Accepted --- problems/src/array/MergeSortedArray.java | 28 +++++------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/problems/src/array/MergeSortedArray.java b/problems/src/array/MergeSortedArray.java index 58dcbc2a..75e088c2 100644 --- a/problems/src/array/MergeSortedArray.java +++ b/problems/src/array/MergeSortedArray.java @@ -17,29 +17,11 @@ public static void main(String[] args) throws Exception{ } public void merge(int[] nums1, int m, int[] nums2, int n) { - int s = m + n; - int l = s - 1; - for(int i = m - 1; i >= 0; i --, l --){ - nums1[l] = nums1[i]; - } - l++; //last index of nums1 - int i = 0, j = 0; - for(; i < s && l < s && j < n; i ++){ - if(nums1[l] <= nums2[j]){ - nums1[i] = nums1[l]; - l++; - } - else{ - nums1[i] = nums2[j]; - j++; - } - } - while(l < s){ - nums1[i++] = nums1[l++]; - } - while(j < n){ - nums1[i++] = nums2[j++]; - } + int i = m + n - 1, j = m - 1, k = n - 1; + while(j >= 0 && k >= 0) + nums1[i--] = (nums1[j] > nums2[k]) ? nums1[j--] : nums2[k--]; + while(k >= 0) + nums1[i--] = nums2[k--]; } } From 39cdd6d0d5eb51e3cd11da9b76dc24945fc390c4 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 29 Jul 2017 15:17:27 +0200 Subject: [PATCH 058/235] Implement Queue using Stacks : Accepted --- README.md | 1 + problems/src/stack/MyQueue.java | 76 +++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 problems/src/stack/MyQueue.java diff --git a/README.md b/README.md index ef2e3c10..37805e4f 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Min Stack](problems/src/stack/MinStack.java) (Easy) - [Valid Parentheses](problems/src/stack/ValidParentheses.java) (Easy) - [Largest Rectangle In Histogram](problems/src/stack/LargestRectangleInHistogram.java) (Hard) +- [Implement Queue using Stacks](problems/src/stack/MyQueue.java) (Easy) #### [String](problems/src/string) diff --git a/problems/src/stack/MyQueue.java b/problems/src/stack/MyQueue.java new file mode 100644 index 00000000..911a9bca --- /dev/null +++ b/problems/src/stack/MyQueue.java @@ -0,0 +1,76 @@ +package stack; + +import java.util.Stack; + +/** + * Created by gouthamvidyapradhan on 29/07/2017. + * Implement the following operations of a queue using stacks. + + push(x) -- Push element x to the back of queue. + pop() -- Removes the element from in front of queue. + peek() -- Get the front element. + empty() -- Return whether the queue is empty. + + Notes: + You must use only standard operations of a stack -- which means only push to top, peek/pop from top, size, and is empty operations are valid. + Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack. + You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue). + */ +public class MyQueue { + + private Stack stack; + public static void main(String[] args) throws Exception{ + MyQueue myQueue = new MyQueue(); + myQueue.push(5); + myQueue.push(12); + myQueue.push(7); + myQueue.push(9); + System.out.println(myQueue.peek()); + System.out.println(myQueue.pop()); + myQueue.push(56); + myQueue.push(53); + System.out.println(myQueue.pop()); + } + + /** Initialize your data structure here. */ + public MyQueue() { + stack = new Stack<>(); + } + + /** Push element x to the back of queue. */ + public void push(int x) { + stack.push(x); + } + + /** Removes the element from in front of queue and returns that element. */ + public int pop() { + Stack auxStack = new Stack<>(); + while(!stack.isEmpty()){ + auxStack.push(stack.pop()); + } + int result = auxStack.pop(); + while(!auxStack.isEmpty()){ + stack.push(auxStack.pop()); + } + return result; + } + + /** Get the front element. */ + public int peek() { + Stack auxStack = new Stack<>(); + while(!stack.isEmpty()){ + auxStack.push(stack.pop()); + } + int result = auxStack.peek(); + while(!auxStack.isEmpty()){ + stack.push(auxStack.pop()); + } + return result; + } + + /** Returns whether the queue is empty. */ + public boolean empty() { + return stack.isEmpty(); + } + +} From 6b7fc0b40aa3112d896f7a3ff642502f17177f40 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 2 Aug 2017 01:23:45 +0200 Subject: [PATCH 059/235] RotateArray : Accepted --- README.md | 1 + problems/src/array/RotateArray.java | 44 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 problems/src/array/RotateArray.java diff --git a/README.md b/README.md index 37805e4f..bc1c8886 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ My accepted leetcode solutions to some of the common interview problems. - [MaxProduct Of Three Numbers](problems/src/array/MaxProductOfThreeNumbers.java) (Easy) - [Missing Number](problems/src/array/MissingNumber.java) (Easy) - [Merge Sorted Array](problems/src/array/MergeSortedArray.java) (Easy) +- [Rotate Array](problems/src/array/RotateArray.java) (Easy) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/RotateArray.java b/problems/src/array/RotateArray.java new file mode 100644 index 00000000..a1c04df0 --- /dev/null +++ b/problems/src/array/RotateArray.java @@ -0,0 +1,44 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 01/08/2017. + * Rotate an array of n elements to the right by k steps. + + For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4]. + + Note: + Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. + + Hint: + Could you do it in-place with O(1) extra space? + Related problem: Reverse Words in a String II + */ +public class RotateArray { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1, 2, 3, 4, 5, 6}; + new RotateArray().rotate(A, 2); + for (int i : A) + System.out.print(i + " "); + } + + public void rotate(int[] nums, int k) { + k = k % nums.length; + reverse(nums, 0, nums.length - 1); + reverse(nums, 0, k - 1); + reverse(nums, k, nums.length - 1); + } + + private void reverse(int[] nums, int s, int e){ + for(int i = s, j = e; i < j; i ++, j --){ + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } + } + +} From 21024b3ecc890d887db19ab75c85b00c0c6bbce6 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 2 Aug 2017 01:53:39 +0200 Subject: [PATCH 060/235] AddDigits : Accepted --- README.md | 1 + problems/src/math/AddDigits.java | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 problems/src/math/AddDigits.java diff --git a/README.md b/README.md index bc1c8886..d5e90ac5 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Count Primes](problems/src/math/CountPrimes.java) (Easy) - [Rotate Function](problems/src/math/RotateFunction.java) (Medium) - [Water and Jug Problem](problems/src/math/WaterAndJugProblem.java) (Medium) +- [Add Digits](problems/src/math/AddDigits.java) (Easy) #### [Stack](problems/src/stack) diff --git a/problems/src/math/AddDigits.java b/problems/src/math/AddDigits.java new file mode 100644 index 00000000..c7fb605e --- /dev/null +++ b/problems/src/math/AddDigits.java @@ -0,0 +1,26 @@ +package math; + +/** + * Created by gouthamvidyapradhan on 02/08/2017. + * Given a non-negative integer num, repeatedly add all its digits until the result has only one digit. + + For example: + + Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it. + + Follow up: + Could you do it without any loop/recursion in O(1) runtime? + + */ +public class AddDigits { + + public static void main(String[] args) throws Exception{ + System.out.println(new AddDigits().addDigits(38)); + } + + public int addDigits(int num) { + if(num == 0) return 0; + return num % 9 == 0 ? 9 : num % 9; + } + +} From 91260573bc7cb3a1a3ec790428b795030393e095 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 6 Aug 2017 11:39:53 +0200 Subject: [PATCH 061/235] SortColors : Accepted --- README.md | 1 + problems/src/array/SortColors.java | 62 ++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 problems/src/array/SortColors.java diff --git a/README.md b/README.md index d5e90ac5..2cdf416b 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Missing Number](problems/src/array/MissingNumber.java) (Easy) - [Merge Sorted Array](problems/src/array/MergeSortedArray.java) (Easy) - [Rotate Array](problems/src/array/RotateArray.java) (Easy) +- [Sort Colors](problems/src/array/SortColors.java) (Medium) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/SortColors.java b/problems/src/array/SortColors.java new file mode 100644 index 00000000..5cc208da --- /dev/null +++ b/problems/src/array/SortColors.java @@ -0,0 +1,62 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 06/08/2017. + * Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue. + + Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively. + + Note: + You are not suppose to use the library's sort function for this problem. + + Follow up: + A rather straight forward solution is a two-pass algorithm using counting sort. + First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's. + + Could you come up with an one-pass algorithm using only constant space? + + */ +public class SortColors { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] nums = {2, 1, 0, 0, 1}; + new SortColors().sortColors(nums); + for(int i : nums) + System.out.println(i); + } + + public void sortColors(int[] nums) { + int s = nums[0]; //save the first index value + nums[0] = 1; //overwrite with 1 + int l = 0, r = 0; //left and right index indicating the start and end index of 1s + for(int i = 1; i < nums.length; i ++){ + switch (nums[i]){ + case 0: + nums[l] = 0; + nums[r + 1] = 1; + if(r + 1 != i){ + nums[i] = 2; + } + l ++; r ++; + break; + + case 1: + nums[r + 1] = 1; + if(r + 1 != i){ + nums[i] = 2; + } + r++; + break; + } + } + //replace the initial overwritten value with the original value + if(s == 0) + nums[l] = 0; + else if(s == 2) + nums[r] = 2; + } +} From 55efe493d41a367d86c8fc10e11c979be867e282 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 6 Aug 2017 11:44:04 +0200 Subject: [PATCH 062/235] SortColors : Updated javadoc --- problems/src/array/SortColors.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/src/array/SortColors.java b/problems/src/array/SortColors.java index 5cc208da..d049bdf0 100644 --- a/problems/src/array/SortColors.java +++ b/problems/src/array/SortColors.java @@ -15,6 +15,10 @@ Could you come up with an one-pass algorithm using only constant space? + Solution: + The below solution works with one pass. The basic idea is to keep track of start and end index of + contiguous 1s and push the 0s to left of 1s and 2 to right of 1s. + */ public class SortColors { /** From bea89e569230cc46a48be6517e7f2eb0aa873588 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 6 Aug 2017 13:08:22 +0200 Subject: [PATCH 063/235] Binary Tree Inorder Traversal : Accepted --- README.md | 1 + .../src/tree/BinaryTreeInorderTraversal.java | 60 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 problems/src/tree/BinaryTreeInorderTraversal.java diff --git a/README.md b/README.md index 2cdf416b..5003be51 100644 --- a/README.md +++ b/README.md @@ -191,6 +191,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Populating Next Right Pointers in Each Node](problems/src/tree/NextRightPointer.java) (Medium) - [Subtree of Another Tree](problems/src/tree/SubtreeOfAnotherTree.java) (Easy) - [Binary Tree Zigzag Level Order Traversal](problems/src/tree/ZigZagTraversal.java) (Medium) +- [Binary Tree Inorder Traversal](problems/src/tree/BinaryTreeInorderTraversal.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/BinaryTreeInorderTraversal.java b/problems/src/tree/BinaryTreeInorderTraversal.java new file mode 100644 index 00000000..f2314336 --- /dev/null +++ b/problems/src/tree/BinaryTreeInorderTraversal.java @@ -0,0 +1,60 @@ +package tree; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 06/08/2017. + * Given a binary tree, return the inorder traversal of its nodes' values. + + For example: + Given binary tree [1,null,2,3], + 1 + \ + 2 + / + 3 + return [1,3,2]. + + Note: Recursive solution is trivial, could you do it iteratively? + + + */ +public class BinaryTreeInorderTraversal { + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + public static void main(String[] args) throws Exception{ + TreeNode root = new TreeNode(3); + root.left = new TreeNode(4); + root.left.left = new TreeNode(5); + root.left.right = new TreeNode(6); + root.left.left.left = new TreeNode(9); + root.left.left.right = new TreeNode(10); + root.right = new TreeNode(2); + root.right.left = new TreeNode(7); + root.right.right = new TreeNode(8); + List result = new BinaryTreeInorderTraversal().inorderTraversal(root); + System.out.println(result); + } + + public List inorderTraversal(TreeNode root) { + Stack stack = new Stack<>(); + TreeNode curr = root; + List result = new ArrayList<>(); + while(curr != null || !stack.isEmpty()){ + while(curr != null){ + stack.push(curr); + curr = curr.left; + } + curr = stack.pop(); + result.add(curr.val); + curr = curr.right; + } + return result; + } + +} From c2f13c8c0bae2db26e8553b12d427bc2cb99cd0b Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 12 Aug 2017 13:15:45 +0200 Subject: [PATCH 064/235] Excel Sheet Column Title : Accepted --- README.md | 1 + problems/src/math/ExcelSheetColumnTitle.java | 45 ++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 problems/src/math/ExcelSheetColumnTitle.java diff --git a/README.md b/README.md index 5003be51..68ff3073 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Rotate Function](problems/src/math/RotateFunction.java) (Medium) - [Water and Jug Problem](problems/src/math/WaterAndJugProblem.java) (Medium) - [Add Digits](problems/src/math/AddDigits.java) (Easy) +- [Excel Sheet Column Title](problems/src/math/ExcelSheetColumnTitle.java) (Easy) #### [Stack](problems/src/stack) diff --git a/problems/src/math/ExcelSheetColumnTitle.java b/problems/src/math/ExcelSheetColumnTitle.java new file mode 100644 index 00000000..8c1c4175 --- /dev/null +++ b/problems/src/math/ExcelSheetColumnTitle.java @@ -0,0 +1,45 @@ +package math; + +/** + * Created by gouthamvidyapradhan on 12/08/2017. + * Given a positive integer, return its corresponding column title as appear in an Excel sheet. + + For example: + + 1 -> A + 2 -> B + 3 -> C + ... + 26 -> Z + 27 -> AA + 28 -> AB + */ +public class ExcelSheetColumnTitle { + + private static final String CONST = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new ExcelSheetColumnTitle().convertToTitle(52)); + } + + + public String convertToTitle(int n) { + StringBuilder ans = new StringBuilder(); + while(n > 0){ + int mod = n % 26; + n /= 26; + if(mod == 0){ + ans.append('Z'); + n -= 1; + }else{ + ans.append(CONST.charAt(mod - 1)); + } + } + return ans.reverse().toString(); + } + +} From a50e37781e7f7c9106c79b98f9ce88beae274c81 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 12 Aug 2017 13:34:38 +0200 Subject: [PATCH 065/235] Roman to Integer: Accepted --- README.md | 1 + problems/src/math/RomanToInteger.java | 48 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 problems/src/math/RomanToInteger.java diff --git a/README.md b/README.md index 68ff3073..067454ce 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Water and Jug Problem](problems/src/math/WaterAndJugProblem.java) (Medium) - [Add Digits](problems/src/math/AddDigits.java) (Easy) - [Excel Sheet Column Title](problems/src/math/ExcelSheetColumnTitle.java) (Easy) +- [Roman to Integer](problems/src/math/RomanToInteger.java) (Easy) #### [Stack](problems/src/stack) diff --git a/problems/src/math/RomanToInteger.java b/problems/src/math/RomanToInteger.java new file mode 100644 index 00000000..46067513 --- /dev/null +++ b/problems/src/math/RomanToInteger.java @@ -0,0 +1,48 @@ +package math; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by gouthamvidyapradhan on 12/08/2017. + * + * Given a roman numeral, convert it to an integer. + + Input is guaranteed to be within the range from 1 to 3999. + */ +public class RomanToInteger { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new RomanToInteger().romanToInt("DXCIX")); + } + + public int romanToInt(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); + + String str = new StringBuilder(s).reverse().toString(); + int sum = 0, prev = -1; + for(int i = 0, l = str.length(); i < l; i++){ + int curr = map.get(str.charAt(i)); + if(curr < prev){ + sum -= curr; + } else{ + sum += curr; + } + prev = curr; + } + + return sum; + } + +} From 7ae7065c724eae8d1af4fcfd536c9fff3321be83 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 12 Aug 2017 14:09:09 +0200 Subject: [PATCH 066/235] Battleships in a Board: Accepted --- README.md | 1 + problems/src/array/BattleshipsInABoard.java | 61 +++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 problems/src/array/BattleshipsInABoard.java diff --git a/README.md b/README.md index 067454ce..8bbc90f3 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Merge Sorted Array](problems/src/array/MergeSortedArray.java) (Easy) - [Rotate Array](problems/src/array/RotateArray.java) (Easy) - [Sort Colors](problems/src/array/SortColors.java) (Medium) +- [Battleships in a Board](problems/src/array/BattleshipsInABoard.java) (Medium) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/BattleshipsInABoard.java b/problems/src/array/BattleshipsInABoard.java new file mode 100644 index 00000000..9da1e41d --- /dev/null +++ b/problems/src/array/BattleshipsInABoard.java @@ -0,0 +1,61 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 12/08/2017. + * Given an 2D board, count how many battleships are in it. The battleships are represented with 'X's, empty slots are represented with '.'s. You may assume the following rules: + + You receive a valid board, made of only battleships or empty slots. + Battleships can only be placed horizontally or vertically. In other words, they can only be made of the shape 1xN (1 row, N columns) or Nx1 (N rows, 1 column), where N can be of any size. + At least one horizontal or vertical cell separates between two battleships - there are no adjacent battleships. + Example: + X..X + ...X + ...X + In the above board there are 2 battleships. + Invalid Example: + ...X + XXXX + ...X + This is an invalid board that you will not receive - as battleships will always have a cell separating between them. + + Follow up: + Could you do it in one-pass, using only O(1) extra memory and without modifying the value of the board? + + Solution: + The below solution works in one pass using only O(1) memory. + Iterate through each cell and add one to count if and only if the current cell equals 'X' and its adjacent upper and + left cell does not contain 'X' + */ +public class BattleshipsInABoard { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + char[][] board = {{'X', '.', '.', 'X'}, {'.', '.', '.', 'X'}, {'.', '.', '.', 'X'}}; + System.out.println(new BattleshipsInABoard().countBattleships(board)); + } + + public int countBattleships(char[][] board) { + int count = 0; + for(int i = 0; i < board.length; i ++){ + for(int j = 0; j < board[0].length; j ++){ + if(board[i][j] == 'X'){ + if(i - 1 >= 0){ //check for the boundary condition + if(board[i - 1][j] == 'X') + continue; + } + if(j - 1 >= 0){ + if(board[i][j - 1] == 'X'){ + continue; + } + } + count++; + } + } + } + return count; + } + +} From 51b4970144024d24d2ed065c397c1ee1b25adc5e Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 13 Aug 2017 13:12:25 +0200 Subject: [PATCH 067/235] BSTIterator: Accepted --- README.md | 1 + problems/src/tree/BSTIterator.java | 83 ++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 problems/src/tree/BSTIterator.java diff --git a/README.md b/README.md index 8bbc90f3..0ad17153 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Subtree of Another Tree](problems/src/tree/SubtreeOfAnotherTree.java) (Easy) - [Binary Tree Zigzag Level Order Traversal](problems/src/tree/ZigZagTraversal.java) (Medium) - [Binary Tree Inorder Traversal](problems/src/tree/BinaryTreeInorderTraversal.java) (Medium) +- [Binary Search Tree Iterator](problems/src/tree/BSTIterator.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/BSTIterator.java b/problems/src/tree/BSTIterator.java new file mode 100644 index 00000000..5a1734c6 --- /dev/null +++ b/problems/src/tree/BSTIterator.java @@ -0,0 +1,83 @@ +package tree; + +import java.util.Stack; + +/** + * Created by gouthamvidyapradhan on 13/08/2017. + * Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST. + + Calling next() will return the next smallest number in the BST. + + Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree. + + Solution: The below solution works in average O(1) time and worst case O(h) time using O(h) memory. + Use a stack to keep track of min value node. + */ +public class BSTIterator { + + private Stack stack; + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + public static void main(String[] args) throws Exception{ + TreeNode root = new TreeNode(10); + root.left = new TreeNode(5); + root.left.left = new TreeNode(4); + root.left.right = new TreeNode(8); + root.left.left.left = new TreeNode(1); + root.left.right.left = new TreeNode(7); + root.right = new TreeNode(12); + root.right.left = new TreeNode(11); + root.right.right = new TreeNode(15); + BSTIterator ite = new BSTIterator(root); + System.out.println("Hasnext: " + ite.hasNext()); + System.out.println("next: " + ite.next()); + System.out.println("next: " + ite.next()); + System.out.println("next: " + ite.next()); + System.out.println("next: " + ite.next()); + System.out.println("next: " + ite.next()); + System.out.println("next: " + ite.next()); + System.out.println("next: " + ite.next()); + System.out.println("next: " + ite.next()); + System.out.println("next: " + ite.next()); + System.out.println("Hasnext: " + ite.hasNext()); + } + + public BSTIterator(TreeNode root) { + stack = new Stack<>(); + fillStack(root); + } + + /** @return whether we have a next smallest number */ + public boolean hasNext() { + return !stack.isEmpty(); + } + + /** @return the next smallest number */ + public int next() { + if(!stack.isEmpty()) { + TreeNode top = stack.pop(); + fillStack(top.right); + return top.val; + } + return -1; + } + + /** + * Fill stack with min values + * @param node curr node to begin with + */ + private void fillStack(TreeNode node){ + TreeNode ite = node; + while(ite != null){ + stack.push(ite); + ite = ite.left; + } + } + +} From fa90d78a4cfbad83d869122d8d8f3b4760e481b9 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 13 Aug 2017 13:38:54 +0200 Subject: [PATCH 068/235] Swap Nodes in Pairs: Accepted --- README.md | 1 + .../src/linked_list/SwapNodesInPairs.java | 58 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 problems/src/linked_list/SwapNodesInPairs.java diff --git a/README.md b/README.md index 0ad17153..7a88c01f 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Reverse Linked List](problems/src/linked_list/ReverseLinkedList.java) (Easy) - [Delete Node in a Linked List](problems/src/linked_list/DeleteNode.java) (Easy) - [Reverse Nodes in k-Group](problems/src/linked_list/ReverseNodesKGroup.java) (Hard) +- [Swap Nodes in Pairs](problems/src/linked_list/SwapNodesInPairs.java) (Medium) #### [Math](problems/src/math) diff --git a/problems/src/linked_list/SwapNodesInPairs.java b/problems/src/linked_list/SwapNodesInPairs.java new file mode 100644 index 00000000..fa65c7b3 --- /dev/null +++ b/problems/src/linked_list/SwapNodesInPairs.java @@ -0,0 +1,58 @@ +package linked_list; + +/** + * Created by gouthamvidyapradhan on 13/08/2017. + * Given a linked list, swap every two adjacent nodes and return its head. + + For example, + Given 1->2->3->4, you should return the list as 2->1->4->3. + + Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed. + */ +public class SwapNodesInPairs { + + public static class ListNode{ + int val; + ListNode next; + ListNode(int x){ + val = x; + } + } + + public static void main(String[] args) throws Exception{ + 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); + node.next.next.next.next.next = new ListNode(6); + ListNode head = new SwapNodesInPairs().swapPairs(node); + while(head != null){ + System.out.println(head.val); + head = head.next; + } + } + + public ListNode swapPairs(ListNode head) { + if(head == null || head.next == null) + return head; + ListNode newHead = head.next; + ListNode curr = head.next; + ListNode prev = head; + ListNode prevPrev = new ListNode(-1); //dummy node + while(curr != null){ + prev.next = curr.next; + curr.next = prev; + prevPrev.next = curr; + if(prev.next != null){ + curr = prev.next.next; + prev = prev.next; + prevPrev = prevPrev.next.next; + } else { + curr = null; + } + } + return newHead; + } + +} From 9b9387378c18ba58ec06b51256b52d2c5b17e9ab Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 13 Aug 2017 13:43:13 +0200 Subject: [PATCH 069/235] Update to readme --- README.md | 4 ++-- problems/src/{tree => design}/BSTIterator.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename problems/src/{tree => design}/BSTIterator.java (99%) diff --git a/README.md b/README.md index 7a88c01f..8d2eba13 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Design Twitter](problems/src/design/Twitter.java) (Medium) - [Tic-Tac-Toe](problems/src/design/TicTacToe.java) (Medium) - [Implement Trie (Prefix Tree)](problems/src/design/Trie.java) (Medium) +- [Binary Search Tree Iterator](problems/src/design/BSTIterator.java) (Medium) #### [Divide and Conquer](problems/src/divide_and_conquer) @@ -157,6 +158,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Largest Rectangle In Histogram](problems/src/stack/LargestRectangleInHistogram.java) (Hard) - [Implement Queue using Stacks](problems/src/stack/MyQueue.java) (Easy) + #### [String](problems/src/string) - [First Unique Character In a String](problems/src/string/FirstUniqueCharacterInAString.java) (Easy) @@ -172,7 +174,6 @@ My accepted leetcode solutions to some of the common interview problems. - [Valid Palindrome](problems/src/string/ValidPalindrome.java) (Easy) - [Simplify Path](problems/src/string/SimplifyPath.java) (Medium) - #### [Tree](problems/src/tree) - [Binaray Tree Right Side View](problems/src/tree/BinarayTreeRightSideView.java) (Medium) @@ -196,7 +197,6 @@ My accepted leetcode solutions to some of the common interview problems. - [Subtree of Another Tree](problems/src/tree/SubtreeOfAnotherTree.java) (Easy) - [Binary Tree Zigzag Level Order Traversal](problems/src/tree/ZigZagTraversal.java) (Medium) - [Binary Tree Inorder Traversal](problems/src/tree/BinaryTreeInorderTraversal.java) (Medium) -- [Binary Search Tree Iterator](problems/src/tree/BSTIterator.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/BSTIterator.java b/problems/src/design/BSTIterator.java similarity index 99% rename from problems/src/tree/BSTIterator.java rename to problems/src/design/BSTIterator.java index 5a1734c6..801781af 100644 --- a/problems/src/tree/BSTIterator.java +++ b/problems/src/design/BSTIterator.java @@ -1,4 +1,4 @@ -package tree; +package design; import java.util.Stack; From fc4b00cffec970bd60b9094669edb91329c4590b Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Mon, 14 Aug 2017 23:09:54 +0200 Subject: [PATCH 070/235] SymmetricTree: Accepted --- README.md | 1 + problems/src/tree/SymmetricTree.java | 54 ++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 problems/src/tree/SymmetricTree.java diff --git a/README.md b/README.md index 8d2eba13..a1839710 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Subtree of Another Tree](problems/src/tree/SubtreeOfAnotherTree.java) (Easy) - [Binary Tree Zigzag Level Order Traversal](problems/src/tree/ZigZagTraversal.java) (Medium) - [Binary Tree Inorder Traversal](problems/src/tree/BinaryTreeInorderTraversal.java) (Medium) +- [Symmetric Tree](problems/src/tree/SymmetricTree.java) (Easy) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/SymmetricTree.java b/problems/src/tree/SymmetricTree.java new file mode 100644 index 00000000..7e1c7265 --- /dev/null +++ b/problems/src/tree/SymmetricTree.java @@ -0,0 +1,54 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 14/08/2017. + * Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). + + For example, this binary tree [1,2,2,3,4,4,3] is symmetric: + + 1 + / \ + 2 2 + / \ / \ + 3 4 4 3 + + But the following [1,2,2,null,3,null,3] is not: + 1 + / \ + 2 2 + \ \ + 3 3 + + */ +public class SymmetricTree { + + static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + TreeNode node = new TreeNode(3); + node.left = new TreeNode(4); + node.right = new TreeNode(5); + System.out.println(new SymmetricTree().isSymmetric(node)); + } + + public boolean isSymmetric(TreeNode root) { + if(root == null) return true; + return dfs(root.left, root.right); + } + + private boolean dfs(TreeNode left, TreeNode right) { + if (left == null && right == null) return true; + else if (left == null || right == null) return false; + return dfs(left.left, right.right) && left.val == right.val && dfs(left.right, right.left); + } +} From 21f0542a30b5e8d6ca75abd2f32cd4a2445dc1ec Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 19 Aug 2017 14:38:53 +0200 Subject: [PATCH 071/235] MaximumBinaryTree: Accepted --- README.md | 1 + problems/src/tree/MaximumBinaryTree.java | 79 ++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 problems/src/tree/MaximumBinaryTree.java diff --git a/README.md b/README.md index a1839710..8ddf059d 100644 --- a/README.md +++ b/README.md @@ -198,6 +198,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Binary Tree Zigzag Level Order Traversal](problems/src/tree/ZigZagTraversal.java) (Medium) - [Binary Tree Inorder Traversal](problems/src/tree/BinaryTreeInorderTraversal.java) (Medium) - [Symmetric Tree](problems/src/tree/SymmetricTree.java) (Easy) +- [Maximum Binary Tree](problems/src/tree/MaximumBinaryTree.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/MaximumBinaryTree.java b/problems/src/tree/MaximumBinaryTree.java new file mode 100644 index 00000000..8af8cc6f --- /dev/null +++ b/problems/src/tree/MaximumBinaryTree.java @@ -0,0 +1,79 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 19/08/2017. + * Given an integer array with no duplicates. A maximum tree building on this array is defined as follow: + + The root is the maximum number in the array. + The left subtree is the maximum tree constructed from left part subarray divided by the maximum number. + The right subtree is the maximum tree constructed from right part subarray divided by the maximum number. + Construct the maximum tree by the given array and output the root node of this tree. + + Example 1: + Input: [3,2,1,6,0,5] + Output: return the tree root node representing the following tree: + + 6 + / \ + 3 5 + \ / + 2 0 + \ + 1 + + Note: + The size of the given array will be in the range [1,1000]. + + */ +public class MaximumBinaryTree { + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + private int[][] max; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] nums = {3,2,1,6,0,5}; + TreeNode root = new MaximumBinaryTree().constructMaximumBinaryTree(nums); + System.out.println(root.val); //print root + } + + public TreeNode constructMaximumBinaryTree(int[] nums) { + + max = new int[nums.length][nums.length]; + + //pre-fill with initial values + for(int i = 0; i < nums.length; i ++){ + max[i][i] = i; + } + + //pre-calculate max for range index + for(int i = 0; i < nums.length; i ++){ + for(int j = i + 1; j < nums.length; j++){ + max[i][j] = nums[max[i][j - 1]] > nums[j] ? max[i][j - 1] : j; + } + } + + return build(0, nums.length - 1, nums); + } + + private TreeNode build(int s, int e, int[] nums){ + if(s <= e){ + int val = nums[max[s][e]]; + TreeNode n = new TreeNode(val); + n.left = build(s, max[s][e] - 1, nums); + n.right = build(max[s][e] + 1, e, nums); + return n; + } + return null; + } + +} From 073f215ab4639d52194ae3f1c153871315483824 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 19 Aug 2017 15:29:16 +0200 Subject: [PATCH 072/235] TwoKeysKeyboard: Accepted --- README.md | 1 + .../dynamic_programming/TwoKeysKeyboard.java | 46 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 problems/src/dynamic_programming/TwoKeysKeyboard.java diff --git a/README.md b/README.md index 8ddf059d..3d2b4c82 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Can I Win](problems/src/dynamic_programming/CanIWin.java) (Medium) - [Maximum Subarray](problems/src/dynamic_programming/MaximumSubarray.java) (Easy) - [Dungeon Game](problems/src/dynamic_programming/DungeonGame.java) (Hard) +- [2 Keys Keyboard](problems/src/dynamic_programming/TwoKeysKeyboard.java) (Medium) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/TwoKeysKeyboard.java b/problems/src/dynamic_programming/TwoKeysKeyboard.java new file mode 100644 index 00000000..8c1f1b25 --- /dev/null +++ b/problems/src/dynamic_programming/TwoKeysKeyboard.java @@ -0,0 +1,46 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 19/08/2017. + * Initially on a notepad only one character 'A' is present. You can perform two operations on this notepad for each step: + + Copy All: You can copy all the characters present on the notepad (partial copy is not allowed). + Paste: You can paste the characters which are copied last time. + Given a number n. You have to get exactly n 'A' on the notepad by performing the minimum number of steps permitted. Output the minimum number of steps to get n 'A'. + + Example 1: + Input: 3 + Output: 3 + Explanation: + Intitally, we have one character 'A'. + In step 1, we use Copy All operation. + In step 2, we use Paste operation to get 'AA'. + In step 3, we use Paste operation to get 'AAA'. + + Note: + The n will be in the range [1, 1000]. + */ +public class TwoKeysKeyboard { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new TwoKeysKeyboard().minSteps(8)); + } + + public int minSteps(int n) { + int[] DP = new int[n + 1]; + for(int i = 2; i <= n; i++){ + DP[i] = i; + for(int j = 2; j < i; j++){ + if((i % j) == 0){ + DP[i] = Math.min(DP[i], DP[j] + (i / j)); + } + } + } + return DP[n]; + } + +} From 59dd54a2c90aec42d1300ebd9240841ffcc36e59 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 22 Aug 2017 00:31:39 +0200 Subject: [PATCH 073/235] Design Search Autocomplete System: Accepted --- README.md | 1 + problems/src/design/AutocompleteSystem.java | 291 ++++++++++++++++++++ 2 files changed, 292 insertions(+) create mode 100644 problems/src/design/AutocompleteSystem.java diff --git a/README.md b/README.md index 3d2b4c82..0d36db68 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Tic-Tac-Toe](problems/src/design/TicTacToe.java) (Medium) - [Implement Trie (Prefix Tree)](problems/src/design/Trie.java) (Medium) - [Binary Search Tree Iterator](problems/src/design/BSTIterator.java) (Medium) +- [Design Search Autocomplete System](problems/src/design/AutocompleteSystem.java) (Hard) #### [Divide and Conquer](problems/src/divide_and_conquer) diff --git a/problems/src/design/AutocompleteSystem.java b/problems/src/design/AutocompleteSystem.java new file mode 100644 index 00000000..dec4eea1 --- /dev/null +++ b/problems/src/design/AutocompleteSystem.java @@ -0,0 +1,291 @@ +package design; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 20/08/2017. + * + * Design a search autocomplete system for a search engine. Users may input a sentence (at least one word and end with a special character '#'). + * For each character they type except '#', you need to return the top 3 historical hot sentences that have prefix the same as the part of sentence already typed. + * Here are the specific rules: + + The hot degree for a sentence is defined as the number of times a user typed the exactly same sentence before. + The returned top 3 hot sentences should be sorted by hot degree (The first is the hottest one). + If several sentences have the same degree of hot, you need to use ASCII-code order (smaller one appears first). + If less than 3 hot sentences exist, then just return as many as you can. + When the input is a special character, it means the sentence ends, and in this case, you need to return an empty list. + Your job is to implement the following functions: + + The constructor function: + + AutocompleteSystem(String[] sentences, int[] times): This is the constructor. + The input is historical data. Sentences is a string array consists of previously typed sentences. + Times is the corresponding times a sentence has been typed. Your system should record these historical data. + + Now, the user wants to input a new sentence. The following function will provide the next character the user types: + + List input(char c): The input c is the next character typed by the user. + The character will only be lower-case letters ('a' to 'z'), blank space (' ') or a special character ('#'). + Also, the previously typed sentence should be recorded in your system. + The output will be the top 3 historical hot sentences that have prefix the same as the part of sentence already typed. + + + Example: + Operation: AutocompleteSystem(["i love you", "island","ironman", "i love leetcode"], [5,3,2,2]) + The system have already tracked down the following sentences and their corresponding times: + "i love you" : 5 times + "island" : 3 times + "ironman" : 2 times + "i love leetcode" : 2 times + Now, the user begins another search: + + Operation: input('i') + Output: ["i love you", "island","i love leetcode"] + Explanation: + There are four sentences that have prefix "i". Among them, "ironman" and "i love leetcode" have same hot degree. + Since ' ' has ASCII code 32 and 'r' has ASCII code 114, "i love leetcode" should be in front of "ironman". + Also we only need to output top 3 hot sentences, so "ironman" will be ignored. + + Operation: input(' ') + Output: ["i love you","i love leetcode"] + Explanation: + There are only two sentences that have prefix "i ". + + Operation: input('a') + Output: [] + Explanation: + There are no sentences that have prefix "i a". + + Operation: input('#') + Output: [] + Explanation: + The user finished the input, the sentence "i a" should be saved as a historical sentence in system. + And the following input will be counted as a new search. + + Note: + The input sentence will always start with a letter and end with '#', and only one blank space will exist between two words. + The number of complete sentences that to be searched won't exceed 100. + The length of each sentence including those in the historical data won't exceed 100. + Please use double-quote instead of single-quote when you write test cases even for a character input. + Please remember to RESET your class variables declared in class AutocompleteSystem, as static/class variables are persisted across multiple test cases. + + Solution: Maintain a Trie (slightly modified) data-structure to all the input sentences where each node of the Trie + is a node containing a hash-map of child character and node and a TreeSet containing the sorted order of all the + possible child sentences starting from the current node. Maintain a cursor node 'curr' to indicate the current node + of input, if the input character is absent then simply mark curr as null indicating no further auto-complete terms possible. + On the other hand if the input character is present then simply pick the top 3 elements from the TreeSet object of curr + node. + Finally, use a StringBuilder to accumulate all the input characters and when a end of sentence is '#' is encountered + simply update the trie with new sentence and degree. + */ +public class AutocompleteSystem { + + private Map hotTextMap; //Maintain a hash-map of sentences and degree + private Trie curr, trie, root; + private StringBuilder currSentence; //StringBuilder class to maintain current input sentence (until '#') + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + String[] sentences = {"i love you", "island","ironman", "i love leetcode"}; + int[] degree = {5,3,2,2}; + AutocompleteSystem autocomplete = new AutocompleteSystem(sentences, degree); + List result = autocomplete.input('i'); + result.forEach(System.out::println); + result = autocomplete.input(' '); + result.forEach(System.out::println); + result = autocomplete.input('a'); + result.forEach(System.out::println); + result = autocomplete.input('#'); + result.forEach(System.out::println); + } + + /** + * Initialize the trie data-structure + * @param sentences array of sentences + * @param times degree + */ + public AutocompleteSystem(String[] sentences, int[] times) { + hotTextMap = new HashMap<>(); + trie = new Trie(); + for(int i = 0; i < sentences.length; i ++){ + hotTextMap.put(sentences[i], times[i]); + trie.insert(sentences[i]); + trie.update(sentences[i]); + } + curr = trie; root = trie; + currSentence = new StringBuilder(); + } + + /** + * Accept input and return hot-text for the current char + * @param c char + * @return List of top 3 hot-text + */ + public List input(char c) { + List result = new ArrayList<>(); + if(c == '#'){ + String sentence = currSentence.toString(); + if(hotTextMap.containsKey(sentence)){ + //already a known sentence hence only update in necessary + hotTextMap.put(sentence, hotTextMap.get(sentence) + 1); + trie.update(sentence); + } else{ + //insert a new sentence and update the degree + hotTextMap.put(sentence, 1); + trie.insert(sentence); + trie.update(sentence); + } + currSentence = new StringBuilder(); //reset StringBuilder + curr = root; //point to root of the trie + } + else { + if(curr != null) { + if(curr.containsChild(c)) { + List hotText = curr.getSubtrie(c).getTop3HotText(); + hotText.stream().forEach((x) -> result.add(currSentence.toString() + x)); //each node only returns + //the hot-text for the current and child nodes hence we have to attach the prefix string + curr = curr.getSubtrie(c); + } else { + curr = null; //as soon as we encounter a empty node then set current to null indicating no further + //auto-complete terms are available + } + } + currSentence.append(c); + } + return result; + } + + /** + * Class HotText to store the text and degree + */ + private class HotText{ + private String text; + private int degree; + HotText(String text, int degree){ + this.text = text; + this.degree = degree; + } + + private String getText() { + return text; + } + + private int getDegree() { + return degree; + } + } + + /** + * Class Trie + */ + private class Trie { + private Map map = new HashMap<>(); + private TreeSet hotText = + new TreeSet<>((HotText o1, HotText o2) -> { + int cmp = Integer.compare(o2.getDegree(), o1.getDegree()); + return cmp == 0 ? o1.getText().compareTo(o2.getText()) : cmp; + }); + + /** + * Get hot-text + * @return HotText + */ + public TreeSet getHotText() { + return hotText; + } + + /** + * Return top 3 hottext + * @return hot text + */ + private List getTop3HotText(){ + List hotText = new ArrayList<>(); + if(this.getHotText() != null){ + this.getHotText().stream().limit(3).forEach((x) -> hotText.add(x.getText())); + } + return hotText; + } + + /** Inserts a word into the trie. */ + private void insert(String word) { + if(word != null){ + add(0, word, word.length()); + } + } + + private void add(int i, String word, int length){ + if(i < length){ + char c = word.charAt(i); + Trie subTrie = map.get(c); + if(subTrie == null){ + subTrie = new Trie(); + map.put(c, subTrie); + } + subTrie.add(i + 1, word, length); + } + else map.put(null, new Trie()); //use null to indicate end of string + } + + /** + * Update hottex and degree + * @param word word or sentence + */ + private void update(String word) { + if(word != null){ + update(0, word, word.length()); + } + } + + /** + * Update trie + * @param i curr position + * @param word sentence + * @param length length + * @return HotText + */ + private HotText update(int i, String word, int length){ + if(i < length){ + char c = word.charAt(i); + Trie subTrie = map.get(c); + HotText subTrieHotText = subTrie.update(i + 1, word, length); + HotText currHotText = new HotText(c + (subTrieHotText == null ? "" : + subTrieHotText.getText()), hotTextMap.get(word)); + updateHotText(subTrie, currHotText); + return currHotText; + } + return null; + } + + /** + * Hot text update + * @param hotText hotText object + */ + private void updateHotText(Trie trie, HotText hotText){ + trie.getHotText().remove(new HotText(hotText.getText(), hotText.getDegree() - 1)); //remove already + // contained hot-text and add new + trie.getHotText().add(hotText); + } + + /** + * Contains child + * @param c char + * @return true if it contains child, false otherwise + */ + private boolean containsChild(char c){ + return this.map.containsKey(c); + } + + /** + * Return child tree + * @param c char + * @return child subTrie + */ + private Trie getSubtrie(char c){ + return this.map.get(c); + } + } +} From 566f32efcc013a2d67455c7c174d2a1a0c219c25 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 30 Aug 2017 01:51:58 +0200 Subject: [PATCH 074/235] Find Bottom Left Tree Value: Accepted --- README.md | 1 + .../src/tree/FindBottomLeftTreeValue.java | 68 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 problems/src/tree/FindBottomLeftTreeValue.java diff --git a/README.md b/README.md index 0d36db68..7d6e16df 100644 --- a/README.md +++ b/README.md @@ -201,6 +201,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Binary Tree Inorder Traversal](problems/src/tree/BinaryTreeInorderTraversal.java) (Medium) - [Symmetric Tree](problems/src/tree/SymmetricTree.java) (Easy) - [Maximum Binary Tree](problems/src/tree/MaximumBinaryTree.java) (Medium) +- [Find Bottom Left Tree Value](problems/src/tree/FindBottomLeftTreeValue.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/FindBottomLeftTreeValue.java b/problems/src/tree/FindBottomLeftTreeValue.java new file mode 100644 index 00000000..83509ee5 --- /dev/null +++ b/problems/src/tree/FindBottomLeftTreeValue.java @@ -0,0 +1,68 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 30/08/2017. + * Given a binary tree, find the leftmost value in the last row of the tree. + + Example 1: + Input: + + 2 + / \ + 1 3 + + Output: + 1 + Example 2: + Input: + + 1 + / \ + 2 3 + / / \ + 4 5 6 + / + 7 + + Output: + 7 + Note: You may assume the tree (i.e., the given root node) is not NULL. + + + */ +public class FindBottomLeftTreeValue { + private int max = 0, result; + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + public static void main(String[] args) throws Exception{ + TreeNode root = new TreeNode(1); + root.left = new TreeNode(2); + root.left.left = new TreeNode(4); + root.right = new TreeNode(3); + root.right.left = new TreeNode(5); + root.right.left.left = new TreeNode(7); + root.right.right = new TreeNode(6); + System.out.println(new FindBottomLeftTreeValue().findBottomLeftValue(root)); + } + + public int findBottomLeftValue(TreeNode root) { + preorder(root, 1); + return result; + } + + private void preorder(TreeNode node, int level){ + if(node != null){ + if(level > max){ + result = node.val; + max = level; + } + preorder(node.left, level + 1); + preorder(node.right, level + 1); + } + } +} From feeb3136d8d9339909492ca5f928b16dc0d8fbcd Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 8 Sep 2017 03:08:58 +0200 Subject: [PATCH 075/235] Bulb Switcher II : Accepted --- README.md | 1 + problems/src/math/BulbSwitcherII.java | 52 +++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 problems/src/math/BulbSwitcherII.java diff --git a/README.md b/README.md index 7d6e16df..e40bcc5e 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Add Digits](problems/src/math/AddDigits.java) (Easy) - [Excel Sheet Column Title](problems/src/math/ExcelSheetColumnTitle.java) (Easy) - [Roman to Integer](problems/src/math/RomanToInteger.java) (Easy) +- [Bulb Switcher II](problems/src/math/BulbSwitcherII.java) (Medium) #### [Stack](problems/src/stack) diff --git a/problems/src/math/BulbSwitcherII.java b/problems/src/math/BulbSwitcherII.java new file mode 100644 index 00000000..8bbeeb3d --- /dev/null +++ b/problems/src/math/BulbSwitcherII.java @@ -0,0 +1,52 @@ +package math; + + +/** + * Created by gouthamvidyapradhan on 08/09/2017. + * There is a room with n lights which are turned on initially and 4 buttons on the wall. + * After performing exactly m unknown operations towards buttons, you need to return how many different kinds of status of the n lights could be. + *

+ * Suppose n lights are labeled as number [1, 2, 3 ..., n], function of these 4 buttons are given below: + *

+ * Flip all the lights. + * Flip lights with even numbers. + * Flip lights with odd numbers. + * Flip lights with (3k + 1) numbers, k = 0, 1, 2, ... + *

+ * Example 1: + * Input: n = 1, m = 1. + * Output: 2 + * Explanation: Status can be: [on], [off] + *

+ * Example 2: + * Input: n = 2, m = 1. + * Output: 3 + * Explanation: Status can be: [on, off], [off, on], [off, off] + *

+ * Example 3: + * Input: n = 3, m = 1. + * Output: 4 + * Explanation: Status can be: [off, on, off], [on, off, on], [off, off, off], [off, on, on]. + *

+ * Note: n and m both fit in range [0, 1000]. + */ +public class BulbSwitcherII { + + public static void main(String[] args) throws Exception { + System.out.println(new BulbSwitcherII().flipLights(1, 1000)); + } + + public int flipLights(int n, int m) { + if (n == 0 || m == 0) return 1; + if (n == 1 && m >= 1) return 2; + if (n == 2) { + if (m == 1) return 3; + if (m >= 2) return 4; + } else if (n >= 3) { + if (m == 1) return 4; + if (m == 2) return 7; + } + return 8; + } + +} From a273cc99fa7d2c1d3f41264637cf85083f909efd Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 14 Sep 2017 23:44:32 +0200 Subject: [PATCH 076/235] The Skyline Problem: Accepted --- README.md | 1 + problems/src/heap/TheSkylineProblem.java | 120 +++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 problems/src/heap/TheSkylineProblem.java diff --git a/README.md b/README.md index e40bcc5e..9abff8b1 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,7 @@ My accepted leetcode solutions to some of the common interview problems. #### [Heap](problems/src/heap) - [Sliding Window Maximum](problems/src/heap/SlidingWindowMaximum.java) (Hard) +- [The Skyline Problem](problems/src/heap/TheSkylineProblem.java) (Hard) #### [Linked List](problems/src/linked_list) diff --git a/problems/src/heap/TheSkylineProblem.java b/problems/src/heap/TheSkylineProblem.java new file mode 100644 index 00000000..2b323ced --- /dev/null +++ b/problems/src/heap/TheSkylineProblem.java @@ -0,0 +1,120 @@ +package heap; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 13/09/2017. + *

+ * A city's skyline is the outer contour of the silhouette formed by all the buildings in that city when viewed from a distance. + * Now suppose you are given the locations and height of all the buildings as shown on a cityscape photo (Figure A), + * write a program to output the skyline formed by these buildings collectively (Figure B). + * + *

+ * See below link for image. + * https://leetcode.com/problems/the-skyline-problem/description/ + *

+ * + * Buildings Skyline Contour + * The geometric information of each building is represented by a triplet of integers [Li, Ri, Hi], where Li and Ri are the x coordinates of the left and right edge of the ith building, respectively, and Hi is its height. It is guaranteed that 0 ≤ Li, Ri ≤ INT_MAX, 0 < Hi ≤ INT_MAX, and Ri - Li > 0. You may assume all buildings are perfect rectangles grounded on an absolutely flat surface at height 0. + *

+ * For instance, the dimensions of all buildings in Figure A are recorded as: [ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ] . + *

+ * The output is a list of "key points" (red dots in Figure B) in the format of [ [x1,y1], [x2, y2], [x3, y3], ... ] that uniquely defines a skyline. A key point is the left endpoint of a horizontal line segment. Note that the last key point, where the rightmost building ends, is merely used to mark the termination of the skyline, and always has zero height. Also, the ground in between any two adjacent buildings should be considered part of the skyline contour. + *

+ * For instance, the skyline in Figure B should be represented as:[ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ]. + *

+ * Notes: + *

+ * The number of buildings in any input list is guaranteed to be in the range [0, 10000]. + * The input list is already sorted in ascending order by the left x position Li. + * The output list must be sorted by the x position. + * There must be no consecutive horizontal lines of equal height in the output skyline. For instance, [...[2 3], [4 5], [7 5], [11 5], [12 7]...] is not acceptable; the three lines of height 5 should be merged into one in the final output as such: [...[2 3], [4 5], [12 7], ...] + * + */ +public class TheSkylineProblem { + + public static void main(String[] args) throws Exception { + int[][] A = {{0, 30, 30}, {2, 9, 10}, {3, 7, 15}, {4, 8, 10}, {5, 12, 12}, {15, 20, 10}, {19, 24, 8}}; + //int[][] A = {{2,9,10}, {3,9,11}, {4,9,12}, {5,9,13}}; + List result = new TheSkylineProblem().getSkyline(A); + result.forEach(System.out::println); + } + + public List getSkyline(int[][] buildings) { + PriorityQueue pq = new PriorityQueue<>(Comparator.comparing(Rectangle::getH).reversed().thenComparing(Rectangle::getX1)); + List result = new ArrayList<>(); + Set set = new HashSet<>(); + for (int[] p : buildings) { + set.add(p[0]); + set.add(p[1]); + } + List points = new ArrayList<>(); + points.addAll(set); + points.sort(Integer::compare); + + for (int i = 0, j = 0, l = points.size(); i < l; i++) { + int curr = points.get(i); + for (int k = j; k < buildings.length; k++) { + int[] rectangle = buildings[k]; + if (rectangle[0] == curr) { + pq.offer(new Rectangle(rectangle[0], rectangle[1], rectangle[2])); + } else if (rectangle[0] > curr) { + j = k; + break; + } + } + int max = Integer.MIN_VALUE; + while (!pq.isEmpty()) { + if (pq.peek().getX2() == curr) { + Rectangle top = pq.poll(); + max = Math.max(max, top.getH()); + } else if (pq.peek().getX2() < curr) { + pq.poll(); + } else { + break; + } + } + if (pq.isEmpty()) { + result.add(makeNewPoint(curr, 0)); + } else { + if (max > pq.peek().getH()) { + result.add(makeNewPoint(curr, pq.peek().getH())); + } else if (max < pq.peek().getH()) { + if (pq.peek().getX1() == curr) { + result.add(makeNewPoint(curr, pq.peek().getH())); + } + } + } + } + return result; + } + + private int[] makeNewPoint(int x, int y) { + int[] point = new int[2]; + point[0] = x; + point[1] = y; + return point; + } + + class Rectangle { + private int x1, x2, h; + + Rectangle(int x1, int x2, int h) { + this.x1 = x1; + this.x2 = x2; + this.h = h; + } + + public int getH() { + return h; + } + + public int getX2() { + return x2; + } + + public int getX1() { + return x1; + } + } +} From 47e3fee32d6207982b0646a9c1297c2d6a973297 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 15 Sep 2017 00:19:11 +0200 Subject: [PATCH 077/235] Code reformat --- problems/src/array/BattleshipsInABoard.java | 61 ++--- problems/src/array/CanPlaceFlowers.java | 47 ++-- problems/src/array/FirstMissingPositive.java | 27 +-- .../src/array/MaxProductOfThreeNumbers.java | 22 +- problems/src/array/MergeIntervals.java | 53 +++-- problems/src/array/MergeSortedArray.java | 14 +- problems/src/array/MissingNumber.java | 19 +- problems/src/array/PascalsTriangle.java | 35 ++- .../src/array/ProductOfArrayExceptSelf.java | 37 ++- problems/src/array/RotateArray.java | 27 +-- problems/src/array/RotateMatrix.java | 39 ++-- problems/src/array/SetMatrixZeroes.java | 47 ++-- problems/src/array/SortColors.java | 51 ++-- problems/src/array/ThirdMaximumNumber.java | 56 +++-- problems/src/array/TwoSum.java | 48 ++-- problems/src/array/TwoSumII.java | 35 ++- problems/src/backtracking/CombinationSum.java | 53 ++--- .../src/backtracking/CombinationSumII.java | 55 ++--- problems/src/backtracking/Combinations.java | 50 ++-- .../src/backtracking/GenerateParentheses.java | 37 ++- .../src/backtracking/LetterPhoneNumber.java | 46 ++-- .../backtracking/PalindromePartitioning.java | 59 ++--- problems/src/backtracking/Permutations.java | 49 ++-- problems/src/backtracking/PermutationsII.java | 47 ++-- problems/src/backtracking/Subsets.java | 51 ++-- problems/src/backtracking/SubsetsII.java | 49 ++-- problems/src/backtracking/WordSearch.java | 81 +++---- problems/src/backtracking/WordSearchII.java | 76 +++--- .../src/binary_search/FindPeakElement.java | 49 ++-- .../MedianOfTwoSortedArrays.java | 94 ++++---- .../binary_search/MinSortedRotatedArray.java | 37 ++- problems/src/binary_search/PowXN.java | 25 +- .../src/binary_search/SearchForARange.java | 47 ++-- .../binary_search/SearchInsertPosition.java | 36 ++- .../SearchRotatedSortedArray.java | 37 ++- problems/src/binary_search/SqrtX.java | 28 +-- problems/src/bit_manipulation/GrayCode.java | 47 ++-- .../BinarayTreeLevelOrderTraversal.java | 68 +++--- .../src/breadth_first_search/WordLadder.java | 73 +++--- .../breadth_first_search/WordLadderII.java | 116 ++++------ .../depth_first_search/CourseSchedule.java | 61 ++--- .../depth_first_search/CourseScheduleII.java | 58 ++--- .../src/depth_first_search/Minesweeper.java | 137 +++++------ .../depth_first_search/MovieRecommend.java | 40 ++-- .../depth_first_search/NumberOfIslands.java | 65 +++--- problems/src/design/AutocompleteSystem.java | 218 +++++++++--------- problems/src/design/BSTIterator.java | 36 +-- .../src/design/CopyListWithRandomPointer.java | 41 ++-- .../src/design/EncodeAndDecodeTinyURL.java | 21 +- problems/src/design/LFUCache.java | 142 +++++------- problems/src/design/LRUCache.java | 86 +++---- problems/src/design/RandomizedSet.java | 105 ++++----- .../SerializeDeserializeBinaryTree.java | 71 +++--- problems/src/design/TicTacToe.java | 169 +++++++------- problems/src/design/Trie.java | 56 +++-- problems/src/design/Twitter.java | 169 +++++++------- .../KthLargestElementInAnArray.java | 44 ++-- .../divide_and_conquer/SearchA2DMatrix.java | 67 +++--- .../BestTimeToBuyAndSellStocks.java | 46 ++-- problems/src/dynamic_programming/CanIWin.java | 70 +++--- .../dynamic_programming/ClimbingStairs.java | 26 +-- .../src/dynamic_programming/CoinChange.java | 70 +++--- .../src/dynamic_programming/CoinChange2.java | 77 +++---- .../ConcatenatedWords.java | 61 +++-- .../src/dynamic_programming/DecodeWays.java | 51 ++-- .../src/dynamic_programming/DungeonGame.java | 69 +++--- .../src/dynamic_programming/HouseRobber.java | 24 +- .../dynamic_programming/HouseRobberII.java | 31 ++- .../LongestIncreasingSubsequence.java | 38 ++- .../LongestPaliandromicSubstring.java | 64 +++-- .../LongestPalindromicSubsequence.java | 33 ++- .../MaximumProductSubarray.java | 25 +- .../dynamic_programming/MaximumSubarray.java | 16 +- .../PalindromePartitioningII.java | 47 ++-- .../dynamic_programming/TwoKeysKeyboard.java | 41 ++-- .../UniqueBinarySearchTrees.java | 40 ++-- .../UniqueBinarySearchTreesII.java | 89 +++---- .../src/dynamic_programming/WordBreak.java | 49 ++-- .../src/dynamic_programming/WordBreakII.java | 49 ++-- problems/src/greedy/BurstBalloons.java | 42 ++-- problems/src/greedy/CourseScheduleIII.java | 42 ++-- problems/src/greedy/GasStation.java | 32 +-- problems/src/greedy/JumpGame.java | 39 ++-- problems/src/greedy/JumpGameII.java | 42 ++-- .../src/greedy/NonOverlappingIntervals.java | 70 +++--- .../greedy/QueueReconstructionByHeight.java | 32 +-- problems/src/hashing/Anagrams.java | 89 ++++--- problems/src/hashing/GroupAnagrams.java | 52 ++--- problems/src/hashing/KdiffPairsInanArray.java | 77 +++---- problems/src/hashing/SortCharByFrequency.java | 109 +++++---- problems/src/hashing/TwoSum.java | 62 ++--- problems/src/hashing/ValidAnagram.java | 46 ++-- problems/src/heap/SlidingWindowMaximum.java | 62 +++-- problems/src/heap/TheSkylineProblem.java | 47 +++- problems/src/linked_list/DeleteNode.java | 14 +- .../linked_list/IntersectionOfTwoLists.java | 85 +++---- problems/src/linked_list/LinkedListCycle.java | 35 ++- .../src/linked_list/MergeKSortedLists.java | 46 ++-- .../src/linked_list/MergeTwoSortedList.java | 33 ++- problems/src/linked_list/PaliandromeList.java | 47 ++-- .../src/linked_list/ReverseLinkedList.java | 29 +-- .../src/linked_list/ReverseNodesKGroup.java | 71 +++--- .../src/linked_list/SwapNodesInPairs.java | 25 +- problems/src/math/AddDigits.java | 19 +- problems/src/math/AddTwoNumbers.java | 41 ++-- problems/src/math/CountPrimes.java | 36 ++- problems/src/math/ExcelSheetColumnTitle.java | 30 +-- problems/src/math/RomanToInteger.java | 15 +- problems/src/math/RotateFunction.java | 60 +++-- problems/src/math/WaterAndJugProblem.java | 36 +-- .../stack/LargestRectangleInHistogram.java | 41 ++-- problems/src/stack/MinStack.java | 67 +++--- problems/src/stack/MyQueue.java | 51 ++-- problems/src/stack/ValidParentheses.java | 28 +-- .../src/string/CompareVersionNumbers.java | 40 ++-- .../src/string/ExcelSheetColumnNumber.java | 27 +-- .../string/FirstUniqueCharacterInAString.java | 40 ++-- problems/src/string/ImplementStrStr.java | 26 +-- .../src/string/RepeatedSubstringPattern.java | 63 +++-- problems/src/string/ReverseWordsII.java | 71 +++--- .../src/string/ReverseWordsInAString.java | 34 +-- problems/src/string/SimplifyPath.java | 42 ++-- problems/src/string/StringToInteger.java | 58 ++--- problems/src/string/TextJustification.java | 79 +++---- problems/src/string/ValidPalindrome.java | 35 ++- problems/src/string/ZigZagConversion.java | 45 ++-- .../src/tree/BinarayTreeRightSideView.java | 50 ++-- .../src/tree/BinaryTreeInorderTraversal.java | 39 ++-- .../src/tree/BinaryTreeMaximumPathSum.java | 46 ++-- problems/src/tree/BoundaryOfBinaryTree.java | 154 ++++++------- .../tree/ClosestBinarySearchTreeValue.java | 42 ++-- .../tree/ConstructStringFromBinaryTree.java | 89 +++---- .../src/tree/ConvertSortedArrayToBST.java | 25 +- .../src/tree/FindBottomLeftTreeValue.java | 64 ++--- problems/src/tree/FlattenBinaryTree.java | 87 +++---- problems/src/tree/InorderSuccessorInBST.java | 49 ++-- problems/src/tree/LCA.java | 50 ++-- problems/src/tree/LargestBSTSubtree.java | 91 ++++---- .../src/tree/LowestCommonAncestorBST.java | 49 ++-- problems/src/tree/MaximumBinaryTree.java | 64 ++--- problems/src/tree/MostFrequentSubtreeSum.java | 71 +++--- problems/src/tree/NextRightPointer.java | 88 +++---- problems/src/tree/PathSumIII.java | 77 +++---- problems/src/tree/PostorderToBT.java | 39 ++-- problems/src/tree/PreorderToBT.java | 35 +-- problems/src/tree/SortedArrayToBST.java | 32 ++- problems/src/tree/SubtreeOfAnotherTree.java | 84 +++---- problems/src/tree/SymmetricTree.java | 41 ++-- problems/src/tree/ValidBinarySearchTree.java | 76 +++--- problems/src/tree/ZigZagTraversal.java | 48 ++-- problems/src/two_pointers/FourSum.java | 75 +++--- .../LongestSubstringWitoutRepeats.java | 37 ++- problems/src/two_pointers/MoveZeroes.java | 25 +- .../src/two_pointers/RemoveDuplicates.java | 25 +- problems/src/two_pointers/ThreeSum.java | 59 +++-- .../src/two_pointers/ThreeSumClosest.java | 32 ++- .../src/two_pointers/TrappingRainWater.java | 34 ++- 157 files changed, 4046 insertions(+), 4473 deletions(-) diff --git a/problems/src/array/BattleshipsInABoard.java b/problems/src/array/BattleshipsInABoard.java index 9da1e41d..c42fbbde 100644 --- a/problems/src/array/BattleshipsInABoard.java +++ b/problems/src/array/BattleshipsInABoard.java @@ -3,51 +3,52 @@ /** * Created by gouthamvidyapradhan on 12/08/2017. * Given an 2D board, count how many battleships are in it. The battleships are represented with 'X's, empty slots are represented with '.'s. You may assume the following rules: - - You receive a valid board, made of only battleships or empty slots. - Battleships can only be placed horizontally or vertically. In other words, they can only be made of the shape 1xN (1 row, N columns) or Nx1 (N rows, 1 column), where N can be of any size. - At least one horizontal or vertical cell separates between two battleships - there are no adjacent battleships. - Example: - X..X - ...X - ...X - In the above board there are 2 battleships. - Invalid Example: - ...X - XXXX - ...X - This is an invalid board that you will not receive - as battleships will always have a cell separating between them. - - Follow up: - Could you do it in one-pass, using only O(1) extra memory and without modifying the value of the board? - - Solution: - The below solution works in one pass using only O(1) memory. - Iterate through each cell and add one to count if and only if the current cell equals 'X' and its adjacent upper and - left cell does not contain 'X' + *

+ * You receive a valid board, made of only battleships or empty slots. + * Battleships can only be placed horizontally or vertically. In other words, they can only be made of the shape 1xN (1 row, N columns) or Nx1 (N rows, 1 column), where N can be of any size. + * At least one horizontal or vertical cell separates between two battleships - there are no adjacent battleships. + * Example: + * X..X + * ...X + * ...X + * In the above board there are 2 battleships. + * Invalid Example: + * ...X + * XXXX + * ...X + * This is an invalid board that you will not receive - as battleships will always have a cell separating between them. + *

+ * Follow up: + * Could you do it in one-pass, using only O(1) extra memory and without modifying the value of the board? + *

+ * Solution: + * The below solution works in one pass using only O(1) memory. + * Iterate through each cell and add one to count if and only if the current cell equals 'X' and its adjacent upper and + * left cell does not contain 'X' */ public class BattleshipsInABoard { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { char[][] board = {{'X', '.', '.', 'X'}, {'.', '.', '.', 'X'}, {'.', '.', '.', 'X'}}; System.out.println(new BattleshipsInABoard().countBattleships(board)); } public int countBattleships(char[][] board) { int count = 0; - for(int i = 0; i < board.length; i ++){ - for(int j = 0; j < board[0].length; j ++){ - if(board[i][j] == 'X'){ - if(i - 1 >= 0){ //check for the boundary condition - if(board[i - 1][j] == 'X') + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (board[i][j] == 'X') { + if (i - 1 >= 0) { //check for the boundary condition + if (board[i - 1][j] == 'X') continue; } - if(j - 1 >= 0){ - if(board[i][j - 1] == 'X'){ + if (j - 1 >= 0) { + if (board[i][j - 1] == 'X') { continue; } } diff --git a/problems/src/array/CanPlaceFlowers.java b/problems/src/array/CanPlaceFlowers.java index f8442336..8b7e732e 100644 --- a/problems/src/array/CanPlaceFlowers.java +++ b/problems/src/array/CanPlaceFlowers.java @@ -3,48 +3,47 @@ /** * Created by gouthamvidyapradhan on 10/06/2017. * Accepted - * - Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, flowers cannot be planted in adjacent plots - they would compete for water and both would die. - - Given a flowerbed (represented as an array containing 0 and 1, where 0 means empty and 1 means not empty), and a number n, return if n new flowers can be planted in it without violating the no-adjacent-flowers rule. - - Example 1: - Input: flowerbed = [1,0,0,0,1], n = 1 - Output: True - Example 2: - Input: flowerbed = [1,0,0,0,1], n = 2 - Output: False - Note: - The input array won't violate no-adjacent-flowers rule. - The input array size is in the range of [1, 20000]. - n is a non-negative integer which won't exceed the input array size. + *

+ * Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, flowers cannot be planted in adjacent plots - they would compete for water and both would die. + *

+ * Given a flowerbed (represented as an array containing 0 and 1, where 0 means empty and 1 means not empty), and a number n, return if n new flowers can be planted in it without violating the no-adjacent-flowers rule. + *

+ * Example 1: + * Input: flowerbed = [1,0,0,0,1], n = 1 + * Output: True + * Example 2: + * Input: flowerbed = [1,0,0,0,1], n = 2 + * Output: False + * Note: + * The input array won't violate no-adjacent-flowers rule. + * The input array size is in the range of [1, 20000]. + * n is a non-negative integer which won't exceed the input array size. */ -public class CanPlaceFlowers -{ +public class CanPlaceFlowers { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] n = {1,0,0,0,1}; + public static void main(String[] args) throws Exception { + int[] n = {1, 0, 0, 0, 1}; System.out.println(new CanPlaceFlowers().canPlaceFlowers(n, 1)); } public boolean canPlaceFlowers(int[] flowerbed, int n) { int[] T = new int[flowerbed.length + 4]; - for(int i = 0, j = 2; i < flowerbed.length; i ++) + for (int i = 0, j = 2; i < flowerbed.length; i++) T[j++] = flowerbed[i]; T[0] = 1; T[T.length - 1] = 1; int total = 0, count = 0; - for(int i = 1; i < T.length; i ++) { - if(T[i] == 0) + for (int i = 1; i < T.length; i++) { + if (T[i] == 0) count++; else { - if((count % 2) == 0) + if ((count % 2) == 0) total += ((count / 2) - 1); else total += (count / 2); diff --git a/problems/src/array/FirstMissingPositive.java b/problems/src/array/FirstMissingPositive.java index 57d2c9c8..034a9bc1 100644 --- a/problems/src/array/FirstMissingPositive.java +++ b/problems/src/array/FirstMissingPositive.java @@ -3,40 +3,41 @@ /** * Created by gouthamvidyapradhan on 24/06/2017. * Given an unsorted integer array, find the first missing positive integer. - - For example, - Given [1,2,0] return 3, - and [3,4,-1,1] return 2. - - Your algorithm should run in O(n) time and uses constant space. + *

+ * For example, + * Given [1,2,0] return 3, + * and [3,4,-1,1] return 2. + *

+ * Your algorithm should run in O(n) time and uses constant space. */ public class FirstMissingPositive { private int L; - public static void main(String[] args) throws Exception{ + + public static void main(String[] args) throws Exception { int[] nums = {1, 3, 5, 9}; System.out.println(new FirstMissingPositive().firstMissingPositive(nums)); } public int firstMissingPositive(int[] nums) { L = nums.length; - for(int i = 0; i < L; i ++){ - if(nums[i] > 0 && nums[i] <= L && nums[i] != i + 1){ + for (int i = 0; i < L; i++) { + if (nums[i] > 0 && nums[i] <= L && nums[i] != i + 1) { int v = nums[i]; nums[i] = -1; replace(v, nums); } } - for(int i = 0; i < L; i ++){ - if(nums[i] != i + 1) + for (int i = 0; i < L; i++) { + if (nums[i] != i + 1) return i + 1; } return L + 1; } - private void replace(int i, int[] nums){ - if(i > 0 && i <= L && i != nums[i - 1]){ + private void replace(int i, int[] nums) { + if (i > 0 && i <= L && i != nums[i - 1]) { int v = nums[i - 1]; nums[i - 1] = i; replace(v, nums); diff --git a/problems/src/array/MaxProductOfThreeNumbers.java b/problems/src/array/MaxProductOfThreeNumbers.java index 8428e3dd..a61b5abe 100644 --- a/problems/src/array/MaxProductOfThreeNumbers.java +++ b/problems/src/array/MaxProductOfThreeNumbers.java @@ -5,20 +5,20 @@ /** * Created by gouthamvidyapradhan on 27/06/2017. * Given an integer array, find three numbers whose product is maximum and output the maximum product. - - Example 1: - Input: [1,2,3] - Output: 6 - Example 2: - Input: [1,2,3,4] - Output: 24 - Note: - The length of the given array will be in range [3,104] and all elements are in the range [-1000, 1000]. - Multiplication of any three numbers in the input won't exceed the range of 32-bit signed integer. + *

+ * Example 1: + * Input: [1,2,3] + * Output: 6 + * Example 2: + * Input: [1,2,3,4] + * Output: 24 + * Note: + * The length of the given array will be in range [3,104] and all elements are in the range [-1000, 1000]. + * Multiplication of any three numbers in the input won't exceed the range of 32-bit signed integer. */ public class MaxProductOfThreeNumbers { public static void main(String[] args) { - int[] A = {1,2,3}; + int[] A = {1, 2, 3}; System.out.println(new MaxProductOfThreeNumbers().maximumProduct(A)); } diff --git a/problems/src/array/MergeIntervals.java b/problems/src/array/MergeIntervals.java index 25e5c653..e16e1c56 100644 --- a/problems/src/array/MergeIntervals.java +++ b/problems/src/array/MergeIntervals.java @@ -1,33 +1,41 @@ package array; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * Created by gouthamvidyapradhan on 13/06/2017. * Given a collection of intervals, merge all overlapping intervals. - - For example, - Given [1,3],[2,6],[8,10],[15,18], - return [1,6],[8,10],[15,18]. - - Solution: O(N log N) where N is the number of intervals - 1. Sort the intervals based on start index - 2. Mark the first interval as the current interval - 3. For every ith interval starting 1 -> N, if the ith interval overlaps with the current interval then create a new - current interval. Else, add the current interval to result set and begin a new current interval. - + *

+ * For example, + * Given [1,3],[2,6],[8,10],[15,18], + * return [1,6],[8,10],[15,18]. + *

+ * Solution: O(N log N) where N is the number of intervals + * 1. Sort the intervals based on start index + * 2. Mark the first interval as the current interval + * 3. For every ith interval starting 1 -> N, if the ith interval overlaps with the current interval then create a new + * current interval. Else, add the current interval to result set and begin a new current interval. */ -public class MergeIntervals -{ +public class MergeIntervals { public static class Interval { int start; int end; - Interval() { start = 0; end = 0; } - Interval(int s, int e) { start = s; end = e; } + + Interval() { + start = 0; + end = 0; + } + + Interval(int s, int e) { + start = s; + end = e; + } } - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { Interval i1 = new Interval(1, 2); Interval i2 = new Interval(3, 4); Interval i3 = new Interval(5, 6); @@ -37,16 +45,15 @@ public static void main(String[] args) throws Exception } public List merge(List intervals) { - if(intervals.isEmpty()) return new ArrayList<>(); + if (intervals.isEmpty()) return new ArrayList<>(); Collections.sort(intervals, (o1, o2) -> Integer.compare(o1.start, o2.start)); List result = new ArrayList<>(); Interval curr = intervals.get(0); - for(int i = 1, l = intervals.size(); i < l; i ++) { + for (int i = 1, l = intervals.size(); i < l; i++) { Interval I = intervals.get(i); - if(I.start >= curr.start && I.start <= curr.end) { //check if the new interval overlaps with the current + if (I.start >= curr.start && I.start <= curr.end) { //check if the new interval overlaps with the current curr.end = curr.end > I.end ? curr.end : I.end; - } - else { + } else { result.add(curr); curr = I; } diff --git a/problems/src/array/MergeSortedArray.java b/problems/src/array/MergeSortedArray.java index 75e088c2..82530e63 100644 --- a/problems/src/array/MergeSortedArray.java +++ b/problems/src/array/MergeSortedArray.java @@ -3,24 +3,24 @@ /** * Created by gouthamvidyapradhan on 29/07/2017. * Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. - - Note: - You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively. + *

+ * Note: + * You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively. */ public class MergeSortedArray { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[] A = {0}; int[] B = {1}; new MergeSortedArray().merge(A, 0, B, 1); - for(int i : A) + for (int i : A) System.out.println(i); } public void merge(int[] nums1, int m, int[] nums2, int n) { int i = m + n - 1, j = m - 1, k = n - 1; - while(j >= 0 && k >= 0) + while (j >= 0 && k >= 0) nums1[i--] = (nums1[j] > nums2[k]) ? nums1[j--] : nums2[k--]; - while(k >= 0) + while (k >= 0) nums1[i--] = nums2[k--]; } diff --git a/problems/src/array/MissingNumber.java b/problems/src/array/MissingNumber.java index 512bc9fc..b874c83a 100644 --- a/problems/src/array/MissingNumber.java +++ b/problems/src/array/MissingNumber.java @@ -3,27 +3,28 @@ /** * Created by gouthamvidyapradhan on 04/07/2017. * Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array. - - For example, - Given nums = [0, 1, 3] return 2. - - Note: - Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity? + *

+ * For example, + * Given nums = [0, 1, 3] return 2. + *

+ * Note: + * Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity? */ public class MissingNumber { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[] nums = {0}; System.out.println(new MissingNumber().missingNumber(nums)); } - public int missingNumber(int[] nums){ + + public int missingNumber(int[] nums) { int sum = 0; int n = nums.length; for (int num : nums) { sum += num; } int arrSum = (((n + 1)) * n) / 2; - if(arrSum == sum) return 0; + if (arrSum == sum) return 0; else return arrSum - sum; } } diff --git a/problems/src/array/PascalsTriangle.java b/problems/src/array/PascalsTriangle.java index c1b00861..d12a2384 100644 --- a/problems/src/array/PascalsTriangle.java +++ b/problems/src/array/PascalsTriangle.java @@ -6,28 +6,25 @@ /** * Created by gouthamvidyapradhan on 25/03/2017. - * + *

* Given an index k, return the kth row of the Pascal's triangle. - - For example, given k = 3, - Return [1,3,3,1]. - - Note: - Could you optimize your algorithm to use only O(k) extra space? + *

+ * For example, given k = 3, + * Return [1,3,3,1]. + *

+ * Note: + * Could you optimize your algorithm to use only O(k) extra space? */ -public class PascalsTriangle -{ - public static void main(String[] args) throws Exception - { +public class PascalsTriangle { + public static void main(String[] args) throws Exception { System.out.println(new PascalsTriangle().getRow(3)); } - public List getRow(int rowIndex) - { - int k = rowIndex; - if(k == 0) + public List getRow(int rowIndex) { + int k = rowIndex; + if (k == 0) return Arrays.asList(1); - else if(k == 1) + else if (k == 1) return Arrays.asList(1, 1); else if (k == 2) return Arrays.asList(1, 2, 1); @@ -35,12 +32,10 @@ else if (k == 2) result.add(2); k = k - 2; int p, c; - while(k-- > 0) - { + while (k-- > 0) { p = 1; int i = 0; - for(int l = result.size(); i < l; i ++) - { + for (int l = result.size(); i < l; i++) { c = result.get(i); result.set(i, p + c); p = c; diff --git a/problems/src/array/ProductOfArrayExceptSelf.java b/problems/src/array/ProductOfArrayExceptSelf.java index fc380515..4ed21a77 100644 --- a/problems/src/array/ProductOfArrayExceptSelf.java +++ b/problems/src/array/ProductOfArrayExceptSelf.java @@ -1,38 +1,33 @@ package array; /** - Created by gouthamvidyapradhan on 04/05/2017. - - Given an array of n integers where n > 1, nums, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i]. - - Solve it without division and in O(n). - - For example, given [1,2,3,4], return [24,12,8,6]. - - Follow up: - Could you solve it with constant space complexity? (Note: The output array does not count as extra space for the purpose of space complexity analysis.) + * Created by gouthamvidyapradhan on 04/05/2017. + *

+ * Given an array of n integers where n > 1, nums, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i]. + *

+ * Solve it without division and in O(n). + *

+ * For example, given [1,2,3,4], return [24,12,8,6]. + *

+ * Follow up: + * Could you solve it with constant space complexity? (Note: The output array does not count as extra space for the purpose of space complexity analysis.) */ -public class ProductOfArrayExceptSelf -{ - public static void main(String[] args) - { - int[] nums = {1,2,3,4}; +public class ProductOfArrayExceptSelf { + public static void main(String[] args) { + int[] nums = {1, 2, 3, 4}; int[] result = new ProductOfArrayExceptSelf().productExceptSelf(nums); for (int r : result) System.out.print(r + " "); } - public int[] productExceptSelf(int[] nums) - { + public int[] productExceptSelf(int[] nums) { int[] result = new int[nums.length]; - for(int i = 0, temp = 1, l = nums.length; i < l; i++) - { + for (int i = 0, temp = 1, l = nums.length; i < l; i++) { result[i] = temp; temp *= nums[i]; } - for(int i = nums.length - 1, temp = 1; i >= 0; i--) - { + for (int i = nums.length - 1, temp = 1; i >= 0; i--) { result[i] = result[i] * temp; temp *= nums[i]; } diff --git a/problems/src/array/RotateArray.java b/problems/src/array/RotateArray.java index a1c04df0..f418a52b 100644 --- a/problems/src/array/RotateArray.java +++ b/problems/src/array/RotateArray.java @@ -3,27 +3,28 @@ /** * Created by gouthamvidyapradhan on 01/08/2017. * Rotate an array of n elements to the right by k steps. - - For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4]. - - Note: - Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. - - Hint: - Could you do it in-place with O(1) extra space? - Related problem: Reverse Words in a String II + *

+ * For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4]. + *

+ * Note: + * Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. + *

+ * Hint: + * Could you do it in-place with O(1) extra space? + * Related problem: Reverse Words in a String II */ public class RotateArray { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[] A = {1, 2, 3, 4, 5, 6}; new RotateArray().rotate(A, 2); for (int i : A) - System.out.print(i + " "); + System.out.print(i + " "); } public void rotate(int[] nums, int k) { @@ -33,8 +34,8 @@ public void rotate(int[] nums, int k) { reverse(nums, k, nums.length - 1); } - private void reverse(int[] nums, int s, int e){ - for(int i = s, j = e; i < j; i ++, j --){ + private void reverse(int[] nums, int s, int e) { + for (int i = s, j = e; i < j; i++, j--) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; diff --git a/problems/src/array/RotateMatrix.java b/problems/src/array/RotateMatrix.java index aff6e5c8..6df275cf 100644 --- a/problems/src/array/RotateMatrix.java +++ b/problems/src/array/RotateMatrix.java @@ -3,39 +3,33 @@ /** * Created by gouthamvidyapradhan on 21/03/2017. * You are given an n x n 2D matrix representing an image. - - Rotate the image by 90 degrees (clockwise). - - Follow up: - Could you do this in-place? + *

+ * Rotate the image by 90 degrees (clockwise). + *

+ * Follow up: + * Could you do this in-place? */ -public class RotateMatrix -{ +public class RotateMatrix { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[][] A = {{1,2,3}, {4,5,6}, {7,8,9}}; + public static void main(String[] args) throws Exception { + int[][] A = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; new RotateMatrix().rotate(A); - for (int i = 0; i < A.length; i ++) - { - for(int j = 0; j < A[0].length; j ++) - { + for (int i = 0; i < A.length; i++) { + for (int j = 0; j < A[0].length; j++) { System.out.println(A[i][j]); } } } - public void rotate(int[][] matrix) - { + public void rotate(int[][] matrix) { int lc = 0, tr = 0, rc = matrix[0].length - 1, br = matrix.length - 1; - while(tr < br) - { - for(int i = lc, j = tr, k = rc, l = br; i < rc && j < br && k > lc && l > tr; i ++, j ++, k--, l--) - { + while (tr < br) { + for (int i = lc, j = tr, k = rc, l = br; i < rc && j < br && k > lc && l > tr; i++, j++, k--, l--) { int temp1 = matrix[j][rc]; matrix[j][rc] = matrix[tr][i]; int temp2 = matrix[br][k]; @@ -44,7 +38,10 @@ public void rotate(int[][] matrix) matrix[l][lc] = temp2; matrix[tr][i] = temp1; } - lc ++; tr ++; rc --; br --; + lc++; + tr++; + rc--; + br--; } } } diff --git a/problems/src/array/SetMatrixZeroes.java b/problems/src/array/SetMatrixZeroes.java index c520bd69..43e8223e 100644 --- a/problems/src/array/SetMatrixZeroes.java +++ b/problems/src/array/SetMatrixZeroes.java @@ -6,59 +6,50 @@ /** * Created by pradhang on 3/28/2017. * Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. - - click to show follow up. - - Follow up: - Did you use extra space? - A straight forward solution using O(mn) space is probably a bad idea. - A simple improvement uses O(m + n) space, but still not the best solution. - Could you devise a constant space solution? + *

+ * click to show follow up. + *

+ * Follow up: + * Did you use extra space? + * A straight forward solution using O(mn) space is probably a bad idea. + * A simple improvement uses O(m + n) space, but still not the best solution. + * Could you devise a constant space solution? */ -public class SetMatrixZeroes -{ +public class SetMatrixZeroes { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[][] matrix = {{0, 8, 7}, {9, 0, 8}, {9, 9, 0}}; new SetMatrixZeroes().setZeroes(matrix); } - public void setZeroes(int[][] matrix) - { + public void setZeroes(int[][] matrix) { Set row = new HashSet<>(); Set col = new HashSet<>(); int m = matrix.length; int n = matrix[0].length; - for(int i = 0; i < m; i ++) - { - for(int j = 0; j < n; j ++) - { - if(matrix[i][j] == 0) - { + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (matrix[i][j] == 0) { row.add(i); col.add(j); } } } - for(int r : row) - { - for(int j = 0; j < n; j++) - { + for (int r : row) { + for (int j = 0; j < n; j++) { matrix[r][j] = 0; } } - for(int c : col) - { - for(int i = 0; i < m; i++) - { + for (int c : col) { + for (int i = 0; i < m; i++) { matrix[i][c] = 0; } } diff --git a/problems/src/array/SortColors.java b/problems/src/array/SortColors.java index d049bdf0..cd9486e4 100644 --- a/problems/src/array/SortColors.java +++ b/problems/src/array/SortColors.java @@ -3,33 +3,33 @@ /** * Created by gouthamvidyapradhan on 06/08/2017. * Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue. - - Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively. - - Note: - You are not suppose to use the library's sort function for this problem. - - Follow up: - A rather straight forward solution is a two-pass algorithm using counting sort. - First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's. - - Could you come up with an one-pass algorithm using only constant space? - - Solution: - The below solution works with one pass. The basic idea is to keep track of start and end index of - contiguous 1s and push the 0s to left of 1s and 2 to right of 1s. - + *

+ * Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively. + *

+ * Note: + * You are not suppose to use the library's sort function for this problem. + *

+ * Follow up: + * A rather straight forward solution is a two-pass algorithm using counting sort. + * First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's. + *

+ * Could you come up with an one-pass algorithm using only constant space? + *

+ * Solution: + * The below solution works with one pass. The basic idea is to keep track of start and end index of + * contiguous 1s and push the 0s to left of 1s and 2 to right of 1s. */ public class SortColors { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[] nums = {2, 1, 0, 0, 1}; new SortColors().sortColors(nums); - for(int i : nums) + for (int i : nums) System.out.println(i); } @@ -37,20 +37,21 @@ public void sortColors(int[] nums) { int s = nums[0]; //save the first index value nums[0] = 1; //overwrite with 1 int l = 0, r = 0; //left and right index indicating the start and end index of 1s - for(int i = 1; i < nums.length; i ++){ - switch (nums[i]){ + for (int i = 1; i < nums.length; i++) { + switch (nums[i]) { case 0: nums[l] = 0; nums[r + 1] = 1; - if(r + 1 != i){ + if (r + 1 != i) { nums[i] = 2; } - l ++; r ++; + l++; + r++; break; case 1: nums[r + 1] = 1; - if(r + 1 != i){ + if (r + 1 != i) { nums[i] = 2; } r++; @@ -58,9 +59,9 @@ public void sortColors(int[] nums) { } } //replace the initial overwritten value with the original value - if(s == 0) + if (s == 0) nums[l] = 0; - else if(s == 2) + else if (s == 2) nums[r] = 2; } } diff --git a/problems/src/array/ThirdMaximumNumber.java b/problems/src/array/ThirdMaximumNumber.java index 6438ad20..3de8137b 100644 --- a/problems/src/array/ThirdMaximumNumber.java +++ b/problems/src/array/ThirdMaximumNumber.java @@ -2,44 +2,42 @@ /** * Created by gouthamvidyapradhan on 25/03/2017. - Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n). - - Example 1: - Input: [3, 2, 1] - - Output: 1 - - Explanation: The third maximum is 1. - Example 2: - Input: [1, 2] - - Output: 2 - - Explanation: The third maximum does not exist, so the maximum (2) is returned instead. - Example 3: - Input: [2, 2, 3, 1] - - Output: 1 - - Explanation: Note that the third maximum here means the third maximum distinct number. - Both numbers with value 2 are both considered as second maximum. + * Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n). + *

+ * Example 1: + * Input: [3, 2, 1] + *

+ * Output: 1 + *

+ * Explanation: The third maximum is 1. + * Example 2: + * Input: [1, 2] + *

+ * Output: 2 + *

+ * Explanation: The third maximum does not exist, so the maximum (2) is returned instead. + * Example 3: + * Input: [2, 2, 3, 1] + *

+ * Output: 1 + *

+ * Explanation: Note that the third maximum here means the third maximum distinct number. + * Both numbers with value 2 are both considered as second maximum. */ -public class ThirdMaximumNumber -{ +public class ThirdMaximumNumber { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] a = {1, 2}; System.out.println(new ThirdMaximumNumber().thirdMax(a)); } - public int thirdMax(int[] nums) - { - long[] max = {Long.MIN_VALUE, Long.MIN_VALUE, Long.MIN_VALUE}; + public int thirdMax(int[] nums) { + long[] max = {Long.MIN_VALUE, Long.MIN_VALUE, Long.MIN_VALUE}; int count = 0; for (int num : nums) { for (int j = 0; j < 3; j++) { @@ -59,6 +57,6 @@ public int thirdMax(int[] nums) } } System.out.println(Integer.MIN_VALUE); - return (count >= 3)? (int)max[2] : (int)max[0]; + return (count >= 3) ? (int) max[2] : (int) max[0]; } } diff --git a/problems/src/array/TwoSum.java b/problems/src/array/TwoSum.java index 6fd0cc2f..1333f950 100644 --- a/problems/src/array/TwoSum.java +++ b/problems/src/array/TwoSum.java @@ -6,25 +6,25 @@ /** * Created by gouthamvidyapradhan on 11/07/2017. * Given an array of integers, return indices of the two numbers such that they add up to a specific target. - - You may assume that each input would have exactly one solution, and you may not use the same element twice. - - Example: - Given nums = [2, 7, 11, 15], target = 9, - - Because nums[0] + nums[1] = 2 + 7 = 9, - return [0, 1]. - - Solution: O(n log n). Wrap index and element in a class and sort in increasing order. Do a two pointer sum and compare. - An alternative solution is to use hashing which is a O(n) solution - For each element e check if element (target - e) - is already found in hashset, if yes return their index, else add this to hash-set and continue. + *

+ * You may assume that each input would have exactly one solution, and you may not use the same element twice. + *

+ * Example: + * Given nums = [2, 7, 11, 15], target = 9, + *

+ * Because nums[0] + nums[1] = 2 + 7 = 9, + * return [0, 1]. + *

+ * Solution: O(n log n). Wrap index and element in a class and sort in increasing order. Do a two pointer sum and compare. + * An alternative solution is to use hashing which is a O(n) solution - For each element e check if element (target - e) + * is already found in hashset, if yes return their index, else add this to hash-set and continue. */ public class TwoSum { - class NumIndex - { + class NumIndex { int i, e; - NumIndex(int i, int e){ + + NumIndex(int i, int e) { this.i = i; this.e = e; } @@ -39,26 +39,24 @@ public static void main(String[] args) { public int[] twoSum(int[] nums, int target) { List list = new ArrayList<>(); - for(int i = 0; i < nums.length; i ++){ + for (int i = 0; i < nums.length; i++) { NumIndex n = new NumIndex(i, nums[i]); list.add(n); } list.sort((o1, o2) -> Integer.compare(o1.e, o2.e)); int[] ans = new int[2]; - for(int i = 0, j = nums.length - 1; i < j; ){ - NumIndex numi = list.get(i); - NumIndex numj = list.get(j); + for (int i = 0, j = nums.length - 1; i < j; ) { + NumIndex numi = list.get(i); + NumIndex numj = list.get(j); int sum = numi.e + numj.e; - if(sum == target){ + if (sum == target) { ans[0] = numi.i; ans[1] = numj.i; return ans; - } - else if(sum > target){ - j --; - } - else i++; + } else if (sum > target) { + j--; + } else i++; } return ans; } diff --git a/problems/src/array/TwoSumII.java b/problems/src/array/TwoSumII.java index c69928b9..d8a338d7 100644 --- a/problems/src/array/TwoSumII.java +++ b/problems/src/array/TwoSumII.java @@ -2,44 +2,39 @@ /** * Created by gouthamvidyapradhan on 18/03/2017. - Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. - - The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based. - - You may assume that each input would have exactly one solution and you may not use the same element twice. - - Input: numbers={2, 7, 11, 15}, target=9 - Output: index1=1, index2=2 + * Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. + *

+ * The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based. + *

+ * You may assume that each input would have exactly one solution and you may not use the same element twice. + *

+ * Input: numbers={2, 7, 11, 15}, target=9 + * Output: index1=1, index2=2 */ -public class TwoSumII -{ +public class TwoSumII { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] nums = {2, 7, 11, 15}; int[] result = new TwoSumII().twoSum(nums, 23); for (int i : result) System.out.println(i); } - public int[] twoSum(int[] numbers, int target) - { + public int[] twoSum(int[] numbers, int target) { int i = 0, j = numbers.length - 1; - while(i < j) - { + while (i < j) { int x = (numbers[i] + numbers[j]); - if(x == target) - { + if (x == target) { int[] result = new int[2]; result[0] = i + 1; result[1] = j + 1; return result; - } - else if(x < target) + } else if (x < target) i++; else j--; } diff --git a/problems/src/backtracking/CombinationSum.java b/problems/src/backtracking/CombinationSum.java index f426adec..b9c87cbe 100644 --- a/problems/src/backtracking/CombinationSum.java +++ b/problems/src/backtracking/CombinationSum.java @@ -5,55 +5,48 @@ /** * Created by pradhang on 3/14/2017. - Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. - - The same repeated number may be chosen from C unlimited number of times. - - Note: - All numbers (including target) will be positive integers. - The solution set must not contain duplicate combinations. - For example, given candidate set [2, 3, 6, 7] and target 7, - A solution set is: - [ - [7], - [2, 2, 3] - ] + * Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. + *

+ * The same repeated number may be chosen from C unlimited number of times. + *

+ * Note: + * All numbers (including target) will be positive integers. + * The solution set must not contain duplicate combinations. + * For example, given candidate set [2, 3, 6, 7] and target 7, + * A solution set is: + * [ + * [7], + * [2, 2, 3] + * ] */ -public class CombinationSum -{ +public class CombinationSum { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] candidates = {2,3,6,7}; + public static void main(String[] args) throws Exception { + int[] candidates = {2, 3, 6, 7}; List> result = new CombinationSum().combinationSum(candidates, 7); } - public List> combinationSum(int[] candidates, int target) - { + public List> combinationSum(int[] candidates, int target) { List> result = new ArrayList<>(); List subList = new ArrayList<>(); doNext(0, result, 0, candidates, target, subList); return result; } - private void doNext(int i, List> result, int count, int[] candidates, int target, List subArr) - { - if(target == 0) - { + private void doNext(int i, List> result, int count, int[] candidates, int target, List subArr) { + if (target == 0) { List subList = new ArrayList<>(); - for(int k = 0; k < count; k ++) + for (int k = 0; k < count; k++) subList.add(subArr.get(k)); result.add(subList); - } - else if(target > 0) - { - for(int j = i, l = candidates.length; j < l; j ++) - { + } else if (target > 0) { + for (int j = i, l = candidates.length; j < l; j++) { subArr.add(candidates[j]); doNext(j, result, count + 1, candidates, target - candidates[j], subArr); subArr.remove(subArr.size() - 1); diff --git a/problems/src/backtracking/CombinationSumII.java b/problems/src/backtracking/CombinationSumII.java index 091c2d45..857137ce 100644 --- a/problems/src/backtracking/CombinationSumII.java +++ b/problems/src/backtracking/CombinationSumII.java @@ -6,55 +6,48 @@ /** * Created by gouthamvidyapradhan on 14/03/2017. - Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. - - Each number in C may only be used once in the combination. - - Note: - All numbers (including target) will be positive integers. - The solution set must not contain duplicate combinations. - For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8, - A solution set is: - [ - [1, 7], - [1, 2, 5], - [2, 6], - [1, 1, 6] - ] + * Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. + *

+ * Each number in C may only be used once in the combination. + *

+ * Note: + * All numbers (including target) will be positive integers. + * The solution set must not contain duplicate combinations. + * For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8, + * A solution set is: + * [ + * [1, 7], + * [1, 2, 5], + * [2, 6], + * [1, 1, 6] + * ] */ -public class CombinationSumII -{ +public class CombinationSumII { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] candidates = {1, 1, 2, 2}; List> result = new CombinationSumII().combinationSum2(candidates, 4); } - public List> combinationSum2(int[] candidates, int target) - { + public List> combinationSum2(int[] candidates, int target) { Arrays.sort(candidates); List> result = new ArrayList<>(); combination(0, target, candidates, new ArrayList<>(), result); return result; } - private void combination(int i, int target, int[] candidates, List row, List> result) - { - if(target == 0) - { + private void combination(int i, int target, int[] candidates, List row, List> result) { + if (target == 0) { result.add(new ArrayList<>(row)); - } - else if(target > 0) - { - for(int j = i, l = candidates.length; j < l; j ++) - { - if(j > i && candidates[j] == candidates[j - 1]) continue; + } else if (target > 0) { + for (int j = i, l = candidates.length; j < l; j++) { + if (j > i && candidates[j] == candidates[j - 1]) continue; row.add(candidates[j]); combination(j + 1, target - candidates[j], candidates, row, result); row.remove(row.size() - 1); diff --git a/problems/src/backtracking/Combinations.java b/problems/src/backtracking/Combinations.java index 5d11932d..1d1c2ded 100644 --- a/problems/src/backtracking/Combinations.java +++ b/problems/src/backtracking/Combinations.java @@ -5,30 +5,27 @@ /** * Created by pradhang on 3/8/2017. - Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. - - For example, - If n = 4 and k = 2, a solution is: - - [ - [2,4], - [3,4], - [2,3], - [1,2], - [1,3], - [1,4], - ] + * Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. + *

+ * For example, + * If n = 4 and k = 2, a solution is: + *

+ * [ + * [2,4], + * [3,4], + * [2,3], + * [1,2], + * [1,3], + * [1,4], + * ] */ -public class Combinations -{ +public class Combinations { - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List> result = new Combinations().combine(3, 3); } - public List> combine(int n, int k) - { + public List> combine(int n, int k) { int[] subArr = new int[k]; List> result = new ArrayList<>(); getNext(0, 0, n, k, subArr, result); @@ -36,19 +33,14 @@ public List> combine(int n, int k) } private void getNext(int i, int count, - int n, int k, int[] subArr, List> result) - { - if(k == 0) - { + int n, int k, int[] subArr, List> result) { + if (k == 0) { List subList = new ArrayList<>(); - for(int a : subArr) + for (int a : subArr) subList.add(a); result.add(subList); - } - else - { - for(int j = i + 1; j <= n; j++) - { + } else { + for (int j = i + 1; j <= n; j++) { subArr[count] = j; getNext(j, count + 1, n, k - 1, subArr, result); } diff --git a/problems/src/backtracking/GenerateParentheses.java b/problems/src/backtracking/GenerateParentheses.java index 764945ec..5c20329c 100644 --- a/problems/src/backtracking/GenerateParentheses.java +++ b/problems/src/backtracking/GenerateParentheses.java @@ -1,24 +1,24 @@ package backtracking; -import java.util.*; +import java.util.ArrayList; +import java.util.List; /** * Created by gouthamvidyapradhan on 24/06/2017. * Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. - - For example, given n = 3, a solution set is: - - [ - "((()))", - "(()())", - "(())()", - "()(())", - "()()()" - ] - + *

+ * For example, given n = 3, a solution set is: + *

+ * [ + * "((()))", + * "(()())", + * "(())()", + * "()(())", + * "()()()" + * ] */ public class GenerateParentheses { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new GenerateParentheses().generateParenthesis(4)); } @@ -28,14 +28,13 @@ public List generateParenthesis(int n) { return list; } - private void backTrack(List list, String str, int open, int close, int n){ - if(str.length() == n * 2){ + private void backTrack(List list, String str, int open, int close, int n) { + if (str.length() == n * 2) { list.add(str); - } - else { - if(open < n) + } else { + if (open < n) backTrack(list, str.concat("("), open + 1, close, n); - if(close < open) //number of close should be less than open or else it can result in unbalanced parentheses + if (close < open) //number of close should be less than open or else it can result in unbalanced parentheses backTrack(list, str.concat(")"), open, close + 1, n); } } diff --git a/problems/src/backtracking/LetterPhoneNumber.java b/problems/src/backtracking/LetterPhoneNumber.java index 1712396c..dda5d638 100644 --- a/problems/src/backtracking/LetterPhoneNumber.java +++ b/problems/src/backtracking/LetterPhoneNumber.java @@ -5,47 +5,43 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given a digit string, return all possible letter combinations that the number could represent. - - A mapping of digit to letters (just like on the telephone buttons) is given below. - 1 2(abc) 3(def) - 4(ghi) 5(jkl) 6(mno) - 7(pqrs) 8(tuv) 9(wxyz) - - - Input:Digit string "23" - Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. - Note: - Although the above answer is in lexicographical order, your answer could be in any order you want. + * Given a digit string, return all possible letter combinations that the number could represent. + *

+ * A mapping of digit to letters (just like on the telephone buttons) is given below. + * 1 2(abc) 3(def) + * 4(ghi) 5(jkl) 6(mno) + * 7(pqrs) 8(tuv) 9(wxyz) + *

+ *

+ * Input:Digit string "23" + * Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. + * Note: + * Although the above answer is in lexicographical order, your answer could be in any order you want. */ -public class LetterPhoneNumber -{ +public class LetterPhoneNumber { private String[] NUMBER_ALPHA = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List result = new LetterPhoneNumber().letterCombinations("23"); result.forEach(System.out::println); } - private List letterCombinations(String digits) - { - if(digits == null || digits.isEmpty() || digits.contains("1") || digits.contains("0")) return new ArrayList<>(); + private List letterCombinations(String digits) { + if (digits == null || digits.isEmpty() || digits.contains("1") || digits.contains("0")) + return new ArrayList<>(); List prev = new ArrayList<>(); prev.add(""); - for(int i = digits.length() - 1; i >= 0; i --) - { + for (int i = digits.length() - 1; i >= 0; i--) { String str = NUMBER_ALPHA[Integer.parseInt(String.valueOf(digits.charAt(i)))]; List newList = new ArrayList<>(); - for(int j = 0, l = str.length(); j < l; j ++) - { - for(String s : prev) - { + for (int j = 0, l = str.length(); j < l; j++) { + for (String s : prev) { s = str.charAt(j) + s; newList.add(s); } diff --git a/problems/src/backtracking/PalindromePartitioning.java b/problems/src/backtracking/PalindromePartitioning.java index 008aa5c7..822d1fd8 100644 --- a/problems/src/backtracking/PalindromePartitioning.java +++ b/problems/src/backtracking/PalindromePartitioning.java @@ -5,51 +5,43 @@ /** * Created by pradhang on 3/15/2017. - Given a string s, partition s such that every substring of the partition is a palindrome. - - Return all possible palindrome partitioning of s. - - For example, given s = "aab", - Return - - [ - ["aa","b"], - ["a","a","b"] - ] + * Given a string s, partition s such that every substring of the partition is a palindrome. + *

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

+ * For example, given s = "aab", + * Return + *

+ * [ + * ["aa","b"], + * ["a","a","b"] + * ] */ -public class PalindromePartitioning -{ +public class PalindromePartitioning { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List> result = new PalindromePartitioning().partition("aaaaaaaaaaaaaaaaaa"); } - public List> partition(String s) - { + public List> partition(String s) { List> result = new ArrayList<>(); doNext(0, new ArrayList<>(), s, result); return result; } - private void doNext(int i, List row, String s, List> result) - { - if(i == s.length()) - { + private void doNext(int i, List row, String s, List> result) { + if (i == s.length()) { List list = new ArrayList<>(row); result.add(list); - } - else - { - for(int j = i, l = s.length(); j < l; j++) - { + } else { + for (int j = i, l = s.length(); j < l; j++) { String sbStr = s.substring(i, j + 1); - if(isPalindrome(sbStr)) - { + if (isPalindrome(sbStr)) { row.add(sbStr); doNext(j + 1, row, s, result); row.remove(row.size() - 1); @@ -58,14 +50,13 @@ private void doNext(int i, List row, String s, List> result } } - private boolean isPalindrome(String s) - { + private boolean isPalindrome(String s) { int i = 0, j = s.length() - 1; - while(i <= j) - { - if(s.charAt(i) != s.charAt(j)) + while (i <= j) { + if (s.charAt(i) != s.charAt(j)) return false; - i++; j--; + i++; + j--; } return true; } diff --git a/problems/src/backtracking/Permutations.java b/problems/src/backtracking/Permutations.java index c74674d2..5f5ebc32 100644 --- a/problems/src/backtracking/Permutations.java +++ b/problems/src/backtracking/Permutations.java @@ -5,52 +5,45 @@ /** * Created by gouthamvidyapradhan on 15/03/2017. - Given a collection of distinct numbers, return all possible permutations. - - For example, - [1,2,3] have the following permutations: - [ - [1,2,3], - [1,3,2], - [2,1,3], - [2,3,1], - [3,1,2], - [3,2,1] - ] + * Given a collection of distinct numbers, return all possible permutations. + *

+ * For example, + * [1,2,3] have the following permutations: + * [ + * [1,2,3], + * [1,3,2], + * [2,1,3], + * [2,3,1], + * [3,1,2], + * [3,2,1] + * ] */ -public class Permutations -{ +public class Permutations { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] nums = {1, 2, 3}; List> result = new Permutations().permute(nums); } - public List> permute(int[] nums) - { + public List> permute(int[] nums) { List> result = new ArrayList<>(); nextPermutation(0, nums, result); return result; } - private void nextPermutation(int i, int[] nums, List> result) - { - if(i == nums.length - 1) - { + private void nextPermutation(int i, int[] nums, List> result) { + if (i == nums.length - 1) { List list = new ArrayList<>(); - for(int n : nums) + for (int n : nums) list.add(n); result.add(list); - } - else - { - for(int j = i, l = nums.length; j < l; j++) - { + } else { + for (int j = i, l = nums.length; j < l; j++) { int temp = nums[j]; nums[j] = nums[i]; nums[i] = temp; diff --git a/problems/src/backtracking/PermutationsII.java b/problems/src/backtracking/PermutationsII.java index 80829241..a2656886 100644 --- a/problems/src/backtracking/PermutationsII.java +++ b/problems/src/backtracking/PermutationsII.java @@ -6,54 +6,45 @@ /** * Created by gouthamvidyapradhan on 12/04/2017. - Given a collection of numbers that might contain duplicates, return all possible unique permutations. - - For example, - [1,1,2] have the following unique permutations: - [ - [1,1,2], - [1,2,1], - [2,1,1] - ] - + * Given a collection of numbers that might contain duplicates, return all possible unique permutations. + *

+ * For example, + * [1,1,2] have the following unique permutations: + * [ + * [1,1,2], + * [1,2,1], + * [2,1,1] + * ] */ -public class PermutationsII -{ - public static void main(String[] args) - { +public class PermutationsII { + public static void main(String[] args) { int[] A = {1, 2, 2}; System.out.println(new PermutationsII().permuteUnique(A)); } - public List> permuteUnique(int[] nums) - { + public List> permuteUnique(int[] nums) { List> result = new ArrayList<>(); Arrays.sort(nums); nextPermutation(0, nums, result); return result; } - private void nextPermutation(int i, int[] nums, List> result) - { - if(i == nums.length - 1) - { + private void nextPermutation(int i, int[] nums, List> result) { + if (i == nums.length - 1) { List list = new ArrayList<>(); - for(int n : nums) + for (int n : nums) list.add(n); result.add(list); - } - else - { - for(int j = i, l = nums.length; j < l; j++) - { - if(j > i && nums[j] == nums[i]) continue; + } else { + for (int j = i, l = nums.length; j < l; j++) { + if (j > i && nums[j] == nums[i]) continue; swap(nums, i, j); nextPermutation(i + 1, Arrays.copyOf(nums, nums.length), result); } } } - private void swap(int[] a, int i , int j){ + private void swap(int[] a, int i, int j) { int tmp = a[i]; a[i] = a[j]; a[j] = tmp; diff --git a/problems/src/backtracking/Subsets.java b/problems/src/backtracking/Subsets.java index bbfef2a4..de74ac7a 100644 --- a/problems/src/backtracking/Subsets.java +++ b/problems/src/backtracking/Subsets.java @@ -5,46 +5,41 @@ /** * Created by gouthamvidyapradhan on 14/03/2017. - Given a set of distinct integers, nums, return all possible subsets. - - Note: The solution set must not contain duplicate subsets. - - For example, - If nums = [1,2,3], a solution is: - - [ - [3], - [1], - [2], - [1,2,3], - [1,3], - [2,3], - [1,2], - [] - ] - + * Given a set of distinct integers, nums, return all possible subsets. + *

+ * Note: The solution set must not contain duplicate subsets. + *

+ * For example, + * If nums = [1,2,3], a solution is: + *

+ * [ + * [3], + * [1], + * [2], + * [1,2,3], + * [1,3], + * [2,3], + * [1,2], + * [] + * ] */ -public class Subsets -{ +public class Subsets { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] n = {1, 2, 3}; List> result = new Subsets().subsets(n); } - public List> subsets(int[] nums) - { + public List> subsets(int[] nums) { List> result = new ArrayList<>(); result.add(new ArrayList<>()); //empty subset - for(int i = 0, l = nums.length; i < l; i ++) - { - for(int j = 0, resLen = result.size(); j < resLen; j++) - { + for (int i = 0, l = nums.length; i < l; i++) { + for (int j = 0, resLen = result.size(); j < resLen; j++) { List newList = new ArrayList<>(result.get(j)); newList.add(nums[i]); result.add(newList); diff --git a/problems/src/backtracking/SubsetsII.java b/problems/src/backtracking/SubsetsII.java index bfd93ecd..65a90795 100644 --- a/problems/src/backtracking/SubsetsII.java +++ b/problems/src/backtracking/SubsetsII.java @@ -6,50 +6,45 @@ /** * Created by gouthamvidyapradhan on 14/03/2017. - Given a collection of integers that might contain duplicates, nums, return all possible subsets. - - Note: The solution set must not contain duplicate subsets. - - For example, - If nums = [1,2,2], a solution is: - - [ - [2], - [1], - [1,2,2], - [2,2], - [1,2], - [] - ] + * Given a collection of integers that might contain duplicates, nums, return all possible subsets. + *

+ * Note: The solution set must not contain duplicate subsets. + *

+ * For example, + * If nums = [1,2,2], a solution is: + *

+ * [ + * [2], + * [1], + * [1,2,2], + * [2,2], + * [1,2], + * [] + * ] */ -public class SubsetsII -{ +public class SubsetsII { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] n = {1, 2, 3}; List> result = new SubsetsII().subsetsWithDup(n); } - public List> subsetsWithDup(int[] nums) - { + public List> subsetsWithDup(int[] nums) { List> result = new ArrayList<>(); result.add(new ArrayList<>()); //empty subset int start = 0, newStart = 0; Arrays.sort(nums); - for(int i = 0, l = nums.length; i < l; i ++) - { + for (int i = 0, l = nums.length; i < l; i++) { newStart = result.size(); - if(i == 0 || nums[i] != nums[i - 1]) - { + if (i == 0 || nums[i] != nums[i - 1]) { start = 0; } - for(int j = start, resLen = result.size(); j < resLen; j++) - { + for (int j = start, resLen = result.size(); j < resLen; j++) { List newList = new ArrayList<>(result.get(j)); newList.add(nums[i]); result.add(newList); diff --git a/problems/src/backtracking/WordSearch.java b/problems/src/backtracking/WordSearch.java index 3e4b409a..7032b201 100644 --- a/problems/src/backtracking/WordSearch.java +++ b/problems/src/backtracking/WordSearch.java @@ -2,55 +2,51 @@ /** * Created by PRADHANG on 4/13/2017. - Given a 2D board and a word, find if the word exists in the grid. - - The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once. - - For example, - Given board = - - [ - ['A','B','C','E'], - ['S','F','C','S'], - ['A','D','E','E'] - ] - word = "ABCCED", -> returns true, - word = "SEE", -> returns true, - word = "ABCB", -> returns false. + * Given a 2D board and a word, find if the word exists in the grid. + *

+ * The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once. + *

+ * For example, + * Given board = + *

+ * [ + * ['A','B','C','E'], + * ['S','F','C','S'], + * ['A','D','E','E'] + * ] + * word = "ABCCED", -> returns true, + * word = "SEE", -> returns true, + * word = "ABCB", -> returns false. */ -public class WordSearch -{ - private static final int[] R = {0,0,1,-1}; - private static final int[] C = {1,-1,0,0}; +public class WordSearch { + private static final int[] R = {0, 0, 1, -1}; + private static final int[] C = {1, -1, 0, 0}; private static boolean[][] visited; private static int length = 0, N, M; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { char[][] board = { {'A'} }; System.out.println(new WordSearch().exist(board, "A")); } - public boolean exist(char[][] board, String word) - { + public boolean exist(char[][] board, String word) { N = board.length; M = board[0].length; - if(N * M < word.length()) return false; + if (N * M < word.length()) return false; visited = new boolean[N][M]; length = word.length(); - for (int i = 0 ; i < N; i ++) - { - for (int j = 0 ; j < M; j ++) - { - if(board[i][j] == word.charAt(0)) - { - if(dfs(i, j, board, word, 1)) return true; + for (int i = 0; i < N; i++) { + for (int j = 0; j < M; j++) { + if (board[i][j] == word.charAt(0)) { + if (dfs(i, j, board, word, 1)) return true; visited[i][j] = false; } } @@ -58,29 +54,22 @@ public boolean exist(char[][] board, String word) return false; } - private boolean dfs(int r, int c, char[][] board, String word, int pos) - { - if(pos < length) - { + private boolean dfs(int r, int c, char[][] board, String word, int pos) { + if (pos < length) { visited[r][c] = true; - for(int i = 0; i < 4; i ++) - { + for (int i = 0; i < 4; i++) { int newR = r + R[i]; int newC = c + C[i]; - if(newR >= 0 && newR < N && newC >= 0 && newC < M) - { - if(!visited[newR][newC]) - { - if(board[newR][newC] == word.charAt(pos)) - { - if(dfs(newR, newC, board, word, pos + 1)) return true; + if (newR >= 0 && newR < N && newC >= 0 && newC < M) { + if (!visited[newR][newC]) { + if (board[newR][newC] == word.charAt(pos)) { + if (dfs(newR, newC, board, word, pos + 1)) return true; visited[newR][newC] = false; } } } } - } - else return true; + } else return true; return false; } } diff --git a/problems/src/backtracking/WordSearchII.java b/problems/src/backtracking/WordSearchII.java index bf4333e2..bbd2b453 100644 --- a/problems/src/backtracking/WordSearchII.java +++ b/problems/src/backtracking/WordSearchII.java @@ -5,21 +5,21 @@ /** * Created by pradhang on 7/4/2017. * Given a 2D board and a list of words from the dictionary, find all words in the board. - - Each word must be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word. - - For example, - Given words = ["oath","pea","eat","rain"] and board = - - [ - ['o','a','a','n'], - ['e','t','a','e'], - ['i','h','k','r'], - ['i','f','l','v'] - ] - Return ["eat","oath"]. - Note: - You may assume that all inputs are consist of lowercase letters a-z. + *

+ * Each word must be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word. + *

+ * For example, + * Given words = ["oath","pea","eat","rain"] and board = + *

+ * [ + * ['o','a','a','n'], + * ['e','t','a','e'], + * ['i','h','k','r'], + * ['i','f','l','v'] + * ] + * Return ["eat","oath"]. + * Note: + * You may assume that all inputs are consist of lowercase letters a-z. */ public class WordSearchII { private final int[] R = {0, 0, -1, 1}; @@ -27,41 +27,41 @@ public class WordSearchII { boolean[][] visited; private Set dictionary; - public static void main(String[] args) throws Exception{ - char[][] board = {{'o','a','a','n'},{'e','t','a','e'},{'i','h','k','r'},{'i','f','l','v'}}; - String[] words = {"oath","pea","eat","rain"}; + public static void main(String[] args) throws Exception { + char[][] board = {{'o', 'a', 'a', 'n'}, {'e', 't', 'a', 'e'}, {'i', 'h', 'k', 'r'}, {'i', 'f', 'l', 'v'}}; + String[] words = {"oath", "pea", "eat", "rain"}; System.out.println(new WordSearchII().findWords(board, words)); } public List findWords(char[][] board, String[] words) { dictionary = new HashSet<>(); Trie trie = new Trie(); - for(String w : words){ + for (String w : words) { trie.insert(w); dictionary.add(w); } visited = new boolean[board.length][board[0].length]; Set resultSet = new HashSet<>(); - for(int i = 0; i < board.length; i ++){ - for(int j = 0; j < board[0].length; j++){ + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { dfs(i, j, board, resultSet, trie, String.valueOf(board[i][j])); } } return new ArrayList<>(resultSet); } - private void dfs(int r, int c, char[][] board, Set result, Trie trie, String s){ + private void dfs(int r, int c, char[][] board, Set result, Trie trie, String s) { char newChar = board[r][c]; Trie subTrie = trie.next(newChar); - if(subTrie == null) return; + if (subTrie == null) return; visited[r][c] = true; - if(dictionary.contains(s)) + if (dictionary.contains(s)) result.add(s); - for(int i = 0; i < 4; i ++){ + for (int i = 0; i < 4; i++) { int newR = r + R[i]; int newC = c + C[i]; - if(newR >= 0 && newC >= 0 && newR < board.length && newC < board[0].length){ - if(!visited[newR][newC]){ + if (newR >= 0 && newC >= 0 && newR < board.length && newC < board[0].length) { + if (!visited[newR][newC]) { dfs(newR, newC, board, result, subTrie, s + board[newR][newC]); } } @@ -73,37 +73,41 @@ private class Trie { private Map map; - /** Initialize your data structure here. */ + /** + * Initialize your data structure here. + */ public Trie() { map = new HashMap<>(); } - /** Inserts a word into the trie. */ + /** + * Inserts a word into the trie. + */ public void insert(String word) { - if(word != null){ + if (word != null) { add(0, word, word.length()); } } - private void add(int i, String word, int length){ - if(i < length){ + private void add(int i, String word, int length) { + if (i < length) { char c = word.charAt(i); Trie subTrie = map.get(c); - if(subTrie == null){ + if (subTrie == null) { subTrie = new Trie(); map.put(c, subTrie); } subTrie.add(i + 1, word, length); - } - else map.put(null, new Trie()); //use null to indicate end of string + } else map.put(null, new Trie()); //use null to indicate end of string } /** * Get next Trie node + * * @param c char c * @return return Trie */ - public Trie next(char c){ + public Trie next(char c) { return this.map.get(c); } } diff --git a/problems/src/binary_search/FindPeakElement.java b/problems/src/binary_search/FindPeakElement.java index ae6e8ba2..6421f86b 100644 --- a/problems/src/binary_search/FindPeakElement.java +++ b/problems/src/binary_search/FindPeakElement.java @@ -3,48 +3,47 @@ /** * Created by gouthamvidyapradhan on 10/07/2017. * A peak element is an element that is greater than its neighbors. - - Given an input array where num[i] ≠ num[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 num[-1] = num[n] = -∞. - - For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2. - - Note: - Your solution should be in logarithmic complexity. - - Solution: O(log N) check if the first or the last element is the peak element, if yes then return this index. - Else binary search for the answer - check mid element if this is a peak element return this index, else if the - left element is greater than current element search left else search right. + *

+ * Given an input array where num[i] ≠ num[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 num[-1] = num[n] = -∞. + *

+ * For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2. + *

+ * Note: + * Your solution should be in logarithmic complexity. + *

+ * Solution: O(log N) check if the first or the last element is the peak element, if yes then return this index. + * Else binary search for the answer - check mid element if this is a peak element return this index, else if the + * left element is greater than current element search left else search right. */ public class FindPeakElement { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[] nums = {3, 4, 3, 2, 1}; System.out.println(new FindPeakElement().findPeakElement(nums)); } public int findPeakElement(int[] nums) { - if(nums.length == 1)return 0; - if(nums[0] > nums[1]) + if (nums.length == 1) return 0; + if (nums[0] > nums[1]) return 0; - else if(nums[nums.length - 1] > nums[nums.length - 2]) + else if (nums[nums.length - 1] > nums[nums.length - 2]) return nums.length - 1; int l = 0, h = nums.length - 1; int ans = 0; - while(l <= h){ + while (l <= h) { int m = l + (h - l) / 2; - if(m - 1 >= 0 && m + 1 < nums.length){ - if(nums[m] > nums[m - 1] && nums[m] > nums[m + 1]){ + if (m - 1 >= 0 && m + 1 < nums.length) { + if (nums[m] > nums[m - 1] && nums[m] > nums[m + 1]) { return m; } } - if(m - 1 >= 0 && nums[m - 1] > nums[m]){ //search left + if (m - 1 >= 0 && nums[m - 1] > nums[m]) { //search left h = m - 1; - } - else { + } else { ans = l; //mark this as the answer and search right l = m + 1; } diff --git a/problems/src/binary_search/MedianOfTwoSortedArrays.java b/problems/src/binary_search/MedianOfTwoSortedArrays.java index fcc60c86..e6bdc86c 100644 --- a/problems/src/binary_search/MedianOfTwoSortedArrays.java +++ b/problems/src/binary_search/MedianOfTwoSortedArrays.java @@ -6,91 +6,87 @@ /** * Created by gouthamvidyapradhan on 23/05/2017. - There are two sorted arrays nums1 and nums2 of size m and n respectively. - - Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). - - Example 1: - nums1 = [1, 3] - nums2 = [2] - - The median is 2.0 - Example 2: - nums1 = [1, 2] - nums2 = [3, 4] - - The median is (2 + 3)/2 = 2.5 - - Solution: Works in worst case time complexity of O(log min(m, n)) - - The basic idea is that if you are given two arrays A and B and know - the length of each, you can check whether an element A[i] is the median in constant - time. Suppose that the median is A[i]. Since the array is sorted, it is greater than - exactly i − 1 values in array A. Then if it is the median, it is also greater than exactly - j = [n / 2] − (i − 1) elements in B. It requires constant time to check if B[j] - A[i] <= B[j + 1]. If A[i] is not the median, then depending on whether A[i] is greater - or less than B[j] and B[j + 1], you know that A[i] is either greater than or less than - the median. Thus you can binary search for A[i] in O(log N) worst-case time - + * There are two sorted arrays nums1 and nums2 of size m and n respectively. + *

+ * Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). + *

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

+ * The median is 2.0 + * Example 2: + * nums1 = [1, 2] + * nums2 = [3, 4] + *

+ * The median is (2 + 3)/2 = 2.5 + *

+ * Solution: Works in worst case time complexity of O(log min(m, n)) + *

+ * The basic idea is that if you are given two arrays A and B and know + * the length of each, you can check whether an element A[i] is the median in constant + * time. Suppose that the median is A[i]. Since the array is sorted, it is greater than + * exactly i − 1 values in array A. Then if it is the median, it is also greater than exactly + * j = [n / 2] − (i − 1) elements in B. It requires constant time to check if B[j] + * A[i] <= B[j + 1]. If A[i] is not the median, then depending on whether A[i] is greater + * or less than B[j] and B[j + 1], you know that A[i] is either greater than or less than + * the median. Thus you can binary search for A[i] in O(log N) worst-case time */ -public class MedianOfTwoSortedArrays -{ +public class MedianOfTwoSortedArrays { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] A = {1,2,5,8,44,45,45}; - int[] B = {1, 2, 3,4,5,6,7,23,23,23,33,44,45,45,56,77,5555}; + public static void main(String[] args) throws Exception { + int[] A = {1, 2, 5, 8, 44, 45, 45}; + int[] B = {1, 2, 3, 4, 5, 6, 7, 23, 23, 23, 33, 44, 45, 45, 56, 77, 5555}; System.out.println(new MedianOfTwoSortedArrays().findMedianSortedArrays(A, B)); } /** * Find median + * * @param nums1 array one * @param nums2 array two * @return */ - public double findMedianSortedArrays(int[] nums1, int[] nums2) - { - if(nums1.length > nums2.length) + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + if (nums1.length > nums2.length) return findMedianSortedArrays(nums2, nums1); //ensure always nums1 is the shortest array int T = nums1.length + nums2.length, low = -1, high = -1; int median = (T - 1) / 2; boolean isOdd = false; - if((T % 2) != 0) + if ((T % 2) != 0) isOdd = true; int s = 0, e = nums1.length - 1; - while(s <= e) { + while (s <= e) { int m = s + (e - s) / 2; - if((median - m - 1) < 0 || nums1[m] >= nums2[median - m - 1]) { + if ((median - m - 1) < 0 || nums1[m] >= nums2[median - m - 1]) { e = m - 1; low = m; high = median - m; - } - else s = m + 1; + } else s = m + 1; } - if(low == -1) { - if(isOdd) return nums2[median - nums1.length]; - else return (double)(nums2[median - nums1.length] + nums2[median - nums1.length + 1]) / 2.0D; - } - else { - if(isOdd) return nums1[low] < nums2[high] ? nums1[low] : nums2[high]; + if (low == -1) { + if (isOdd) return nums2[median - nums1.length]; + else return (double) (nums2[median - nums1.length] + nums2[median - nums1.length + 1]) / 2.0D; + } else { + if (isOdd) return nums1[low] < nums2[high] ? nums1[low] : nums2[high]; else { //Always sorts maximum of 4 elements hence works in O(1) List list = new ArrayList<>(); list.add(nums1[low]); - if(low + 1 < nums1.length) + if (low + 1 < nums1.length) list.add(nums1[low + 1]); list.add(nums2[high]); - if(high + 1 < nums2.length) + if (high + 1 < nums2.length) list.add(nums2[high + 1]); Collections.sort(list); - return (double)(list.get(0) + list.get(1)) / 2.0; + return (double) (list.get(0) + list.get(1)) / 2.0; } } } diff --git a/problems/src/binary_search/MinSortedRotatedArray.java b/problems/src/binary_search/MinSortedRotatedArray.java index 9ae7e843..7c107bc3 100644 --- a/problems/src/binary_search/MinSortedRotatedArray.java +++ b/problems/src/binary_search/MinSortedRotatedArray.java @@ -2,40 +2,37 @@ /** * Created by gouthamvidyapradhan on 10/04/2017. - Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. - - (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). - - Find the minimum element. - - You may assume no duplicate exists in the array. + * Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. + *

+ * (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). + *

+ * Find the minimum element. + *

+ * You may assume no duplicate exists in the array. */ -public class MinSortedRotatedArray -{ +public class MinSortedRotatedArray { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] A = {5, 1, 2, 3, 4}; System.out.println(new MinSortedRotatedArray().findMin(A)); } - public int findMin(int[] nums) - { - if(nums.length == 0) return 0; - else if(nums.length == 1) return nums[0]; + public int findMin(int[] nums) { + if (nums.length == 0) return 0; + else if (nums.length == 1) return nums[0]; int low = 0, high = nums.length - 1; - while(low < high) - { + while (low < high) { int mid = (low + high) / 2; - if(mid > 0 && nums[mid] < nums[mid - 1]) + if (mid > 0 && nums[mid] < nums[mid - 1]) return nums[mid]; - if(nums[low] > nums[mid]) + if (nums[low] > nums[mid]) high = mid - 1; - else if(nums[high] < nums[mid]) + else if (nums[high] < nums[mid]) low = mid + 1; else high = mid - 1; } diff --git a/problems/src/binary_search/PowXN.java b/problems/src/binary_search/PowXN.java index eeb5457c..da3e1a78 100644 --- a/problems/src/binary_search/PowXN.java +++ b/problems/src/binary_search/PowXN.java @@ -2,33 +2,30 @@ /** * Created by gouthamvidyapradhan on 23/05/2017. - - Implement pow(x, n). - - Solution: Works with O(log n) + *

+ * Implement pow(x, n). + *

+ * Solution: Works with O(log n) */ -public class PowXN -{ +public class PowXN { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(1 / new PowXN().myPow(2.00000, -2147483648)); } - public double myPow(double x, int n) - { - if(n == 0) return 1D; + public double myPow(double x, int n) { + if (n == 0) return 1D; long N = n; //use long to avoid overflow. return solve(n < 0 ? (1 / x) : x, N < 0 ? (N * -1) : N); } - public double solve(double x, long n) - { - if(n == 1) return x; + public double solve(double x, long n) { + if (n == 1) return x; double val = solve(x, n / 2); return val * val * ((n % 2) == 0 ? 1 : x); } diff --git a/problems/src/binary_search/SearchForARange.java b/problems/src/binary_search/SearchForARange.java index 2d806a7a..b75192c8 100644 --- a/problems/src/binary_search/SearchForARange.java +++ b/problems/src/binary_search/SearchForARange.java @@ -2,22 +2,20 @@ /** * Created by gouthamvidyapradhan on 20/05/2017. - Given an array of integers sorted in ascending order, find the starting and ending position of a given target value. - - Your algorithm's runtime complexity must be in the order of O(log n). - - If the target is not found in the array, return [-1, -1]. - - For example, - Given [5, 7, 7, 8, 8, 10] and target value 8, - return [3, 4]. - - Solution: Works with worst case time complexity of O(log n). Recursively binary search to find the target index. + * Given an array of integers sorted in ascending order, find the starting and ending position of a given target value. + *

+ * Your algorithm's runtime complexity must be in the order of O(log n). + *

+ * If the target is not found in the array, return [-1, -1]. + *

+ * For example, + * Given [5, 7, 7, 8, 8, 10] and target value 8, + * return [3, 4]. + *

+ * Solution: Works with worst case time complexity of O(log n). Recursively binary search to find the target index. */ -public class SearchForARange -{ - public static void main(String[] args) throws Exception - { +public class SearchForARange { + public static void main(String[] args) throws Exception { int[] test = {5, 7, 7, 8, 8, 10, 10, 10, 10, 18, 19, 20, 21, 21, 21, 21, 22, 23, 28, 28, 90, 101, 101, 101, 200, 200, 200, 200, 200, 200}; int[] result = new SearchForARange().searchRange(test, 200); @@ -36,26 +34,25 @@ public int[] searchRange(int[] nums, int target) { /** * Find index - * @param nums nums array - * @param target target + * + * @param nums nums array + * @param target target * @param isLowerIndex true if target is to find lower index, false otherwise * @return index */ - private int findIndex(int[] nums, int target, boolean isLowerIndex){ + private int findIndex(int[] nums, int target, boolean isLowerIndex) { int result = -1; int s = 0, e = nums.length - 1; - while(s <= e) { + while (s <= e) { int m = s + (e - s) / 2; - if(nums[m] == target) { + if (nums[m] == target) { result = m; - if(isLowerIndex) e = m - 1; //if searching for the lower index then search the lower bound, + if (isLowerIndex) e = m - 1; //if searching for the lower index then search the lower bound, // else search the upper bound else s = m + 1; - } - else if(nums[m] < target){ + } else if (nums[m] < target) { s = m + 1; - } - else e = m - 1; + } else e = m - 1; } return result; } diff --git a/problems/src/binary_search/SearchInsertPosition.java b/problems/src/binary_search/SearchInsertPosition.java index 31a28d49..d054cb24 100644 --- a/problems/src/binary_search/SearchInsertPosition.java +++ b/problems/src/binary_search/SearchInsertPosition.java @@ -2,37 +2,31 @@ /** * Created by gouthamvidyapradhan on 22/05/2017. - Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. - - You may assume no duplicates in the array. - - Here are few examples. - [1,3,5,6], 5 → 2 - [1,3,5,6], 2 → 1 - [1,3,5,6], 7 → 4 - [1,3,5,6], 0 → 0 + * Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. + *

+ * You may assume no duplicates in the array. + *

+ * Here are few examples. + * [1,3,5,6], 5 → 2 + * [1,3,5,6], 2 → 1 + * [1,3,5,6], 7 → 4 + * [1,3,5,6], 0 → 0 */ -public class SearchInsertPosition -{ - public static void main(String[] args) throws Exception - { +public class SearchInsertPosition { + public static void main(String[] args) throws Exception { int[] A = {1, 3, 5, 6}; new SearchInsertPosition().searchInsert(A, 5); } - public int searchInsert(int[] nums, int target) - { + public int searchInsert(int[] nums, int target) { int pos = nums.length; int s = 0, e = nums.length - 1; - while(s <= e) - { + while (s <= e) { int m = s + (e - s) / 2; - if(nums[m] >= target) - { + if (nums[m] >= target) { pos = m; e = m - 1; - } - else s = m + 1; + } else s = m + 1; } return pos; } diff --git a/problems/src/binary_search/SearchRotatedSortedArray.java b/problems/src/binary_search/SearchRotatedSortedArray.java index 28e27423..755a608b 100644 --- a/problems/src/binary_search/SearchRotatedSortedArray.java +++ b/problems/src/binary_search/SearchRotatedSortedArray.java @@ -2,42 +2,37 @@ /** * Created by gouthamvidyapradhan on 10/04/2017. - Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. - - (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). - - You are given a target value to search. If found in the array return its index, otherwise return -1. - - You may assume no duplicate exists in the array. - + * Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. + *

+ * (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). + *

+ * You are given a target value to search. If found in the array return its index, otherwise return -1. + *

+ * You may assume no duplicate exists in the array. */ -public class SearchRotatedSortedArray -{ +public class SearchRotatedSortedArray { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] A = {5, 4, 3, 2, 1}; System.out.println(new SearchRotatedSortedArray().search(A, 4)); } - public int search(int[] nums, int target) - { - if(nums.length == 0) return -1; - if(nums.length == 1) - { + public int search(int[] nums, int target) { + if (nums.length == 0) return -1; + if (nums.length == 1) { return (nums[0] == target) ? 0 : -1; } int low = 0, high = nums.length - 1; - while(low < high) - { + while (low < high) { int mid = (low + high) >>> 1; - if(nums[mid] == target) + if (nums[mid] == target) return mid; - if((nums[mid] <= nums[low]) && (target > nums[mid] && target <= nums[high]) || + if ((nums[mid] <= nums[low]) && (target > nums[mid] && target <= nums[high]) || (nums[low] <= nums[mid] && (target < nums[low] || target > nums[mid]))) low = mid + 1; else high = mid - 1; diff --git a/problems/src/binary_search/SqrtX.java b/problems/src/binary_search/SqrtX.java index 4f008ff6..ef9e191b 100644 --- a/problems/src/binary_search/SqrtX.java +++ b/problems/src/binary_search/SqrtX.java @@ -2,33 +2,27 @@ /** * Created by gouthamvidyapradhan on 22/05/2017. - Implement int sqrt(int x). - - Compute and return the square root of x. + * Implement int sqrt(int x). + *

+ * Compute and return the square root of x. */ -public class SqrtX -{ - public static void main(String[] args) throws Exception - { +public class SqrtX { + public static void main(String[] args) throws Exception { System.out.println(new SqrtX().mySqrt(Integer.MAX_VALUE)); } - public int mySqrt(int x) - { + public int mySqrt(int x) { int s = 0, e = x; long ans = 0L; - while(s <= e) - { + while (s <= e) { long m = s + (e - s) / 2; long prod = m * m; - if(prod <= x) - { - s = (int)(m + 1); + if (prod <= x) { + s = (int) (m + 1); ans = m; - } - else e = (int)m - 1; + } else e = (int) m - 1; } - return (int)ans; + return (int) ans; } diff --git a/problems/src/bit_manipulation/GrayCode.java b/problems/src/bit_manipulation/GrayCode.java index 6c50336a..9db5ce92 100644 --- a/problems/src/bit_manipulation/GrayCode.java +++ b/problems/src/bit_manipulation/GrayCode.java @@ -1,43 +1,42 @@ package bit_manipulation; -import java.util.*; +import java.util.ArrayList; +import java.util.List; /** * Created by gouthamvidyapradhan on 16/03/2017. - The gray code is a binary numeral system where two successive values differ in only one bit. - - Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0. - - For example, given n = 2, return [0,1,3,2]. Its gray code sequence is: - - 00 - 0 - 01 - 1 - 11 - 3 - 10 - 2 - Note: - For a given n, a gray code sequence is not uniquely defined. - - For example, [0,2,3,1] is also a valid gray code sequence according to the above definition. - - For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that. + * The gray code is a binary numeral system where two successive values differ in only one bit. + *

+ * Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0. + *

+ * For example, given n = 2, return [0,1,3,2]. Its gray code sequence is: + *

+ * 00 - 0 + * 01 - 1 + * 11 - 3 + * 10 - 2 + * Note: + * For a given n, a gray code sequence is not uniquely defined. + *

+ * For example, [0,2,3,1] is also a valid gray code sequence according to the above definition. + *

+ * For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that. */ -public class GrayCode -{ +public class GrayCode { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List result = new GrayCode().grayCode(3); } - public List grayCode(int n) - { + public List grayCode(int n) { List result = new ArrayList<>(); - for(int i = 0; i <= ((1 << n) - 1); i ++) + for (int i = 0; i <= ((1 << n) - 1); i++) result.add(i ^ (i >> 1)); return result; } diff --git a/problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java b/problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java index 5df4b49d..a266ddc0 100644 --- a/problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java +++ b/problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java @@ -7,50 +7,50 @@ /** * Created by gouthamvidyapradhan on 13/03/2017. - Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). - - For example: - Given binary tree [3,9,20,null,null,15,7], - 3 - / \ - 9 20 - / \ - 15 7 - return its level order traversal as: - [ - [3], - [9,20], - [15,7] - ] - + * Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). + *

+ * For example: + * Given binary tree [3,9,20,null,null,15,7], + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * return its level order traversal as: + * [ + * [3], + * [9,20], + * [15,7] + * ] */ -public class BinarayTreeLevelOrderTraversal -{ - public static class TreeNode - { +public class BinarayTreeLevelOrderTraversal { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - private class LevelNode - { + private class LevelNode { TreeNode node; int level; - LevelNode(TreeNode node, int level) - { + + LevelNode(TreeNode node, int level) { this.node = node; this.level = level; } } + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(2); root.left = new TreeNode(3); root.right = new TreeNode(4); @@ -64,21 +64,17 @@ public static void main(String[] args) throws Exception List> result = new BinarayTreeLevelOrderTraversal().levelOrder(root); } - public List> levelOrder(TreeNode root) - { + public List> levelOrder(TreeNode root) { List> result = new ArrayList<>(); - if(root == null) return result; + if (root == null) return result; Queue queue = new ArrayDeque<>(); queue.offer(new LevelNode(root, 0)); int currentLevel = 0; List row = new ArrayList<>(); - while(!queue.isEmpty()) - { + while (!queue.isEmpty()) { LevelNode levelNode = queue.poll(); - if(levelNode.node != null) - { - if(levelNode.level != currentLevel) - { + if (levelNode.node != null) { + if (levelNode.level != currentLevel) { result.add(row); row = new ArrayList<>(); currentLevel++; diff --git a/problems/src/breadth_first_search/WordLadder.java b/problems/src/breadth_first_search/WordLadder.java index af7cefa1..c7a4444d 100644 --- a/problems/src/breadth_first_search/WordLadder.java +++ b/problems/src/breadth_first_search/WordLadder.java @@ -4,35 +4,33 @@ /** * Created by gouthamvidyapradhan on 21/03/2017. - Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that: - - Only one letter can be changed at a time. - Each transformed word must exist in the word list. Note that beginWord is not a transformed word. - For example, - - Given: - beginWord = "hit" - endWord = "cog" - wordList = ["hot","dot","dog","lot","log","cog"] - As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", - return its length 5. - - Note: - Return 0 if there is no such transformation sequence. - All words have the same length. - All words contain only lowercase alphabetic characters. - You may assume no duplicates in the word list. - You may assume beginWord and endWord are non-empty and are not the same. + * Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that: + *

+ * Only one letter can be changed at a time. + * Each transformed word must exist in the word list. Note that beginWord is not a transformed word. + * For example, + *

+ * Given: + * beginWord = "hit" + * endWord = "cog" + * wordList = ["hot","dot","dog","lot","log","cog"] + * As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", + * return its length 5. + *

+ * Note: + * Return 0 if there is no such transformation sequence. + * All words have the same length. + * All words contain only lowercase alphabetic characters. + * You may assume no duplicates in the word list. + * You may assume beginWord and endWord are non-empty and are not the same. */ -public class WordLadder -{ +public class WordLadder { - class State - { + class State { String word; int len; - State(String word, int len) - { + + State(String word, int len) { this.word = word; this.len = len; } @@ -42,13 +40,14 @@ class State private static Set dictionary = new HashSet<>(); private static final String CONST = "abcdefghijklmnopqrstuvwxyz"; private static Set done = new HashSet<>(); + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List list = new ArrayList<>(); list.add("hot"); list.add("dot"); @@ -60,27 +59,21 @@ public static void main(String[] args) throws Exception } - public int ladderLength(String beginWord, String endWord, List wordList) - { + public int ladderLength(String beginWord, String endWord, List wordList) { dictionary.addAll(wordList); queue.offer(new State(beginWord, 0)); done.add(beginWord); - while(!queue.isEmpty()) - { + while (!queue.isEmpty()) { State head = queue.poll(); - if(head.word.equals(endWord)) + if (head.word.equals(endWord)) return head.len + 1; - for(int i = 0, l = CONST.length(); i < l; i ++ ) - { + for (int i = 0, l = CONST.length(); i < l; i++) { StringBuilder word = new StringBuilder(head.word); - for(int j = 0, ln = word.length(); j < ln; j ++ ) - { + for (int j = 0, ln = word.length(); j < ln; j++) { char old = word.charAt(j); word.replace(j, j + 1, String.valueOf(CONST.charAt(i))); - if(!done.contains(word.toString())) - { - if(dictionary.contains(word.toString())) - { + if (!done.contains(word.toString())) { + if (dictionary.contains(word.toString())) { done.add(word.toString()); queue.offer(new State(word.toString(), head.len + 1)); } diff --git a/problems/src/breadth_first_search/WordLadderII.java b/problems/src/breadth_first_search/WordLadderII.java index 8df6bb21..f25325d4 100644 --- a/problems/src/breadth_first_search/WordLadderII.java +++ b/problems/src/breadth_first_search/WordLadderII.java @@ -4,30 +4,29 @@ /** * Created by gouthamvidyapradhan on 24/03/2017. - Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that: - - Only one letter can be changed at a time - Each transformed word must exist in the word list. Note that beginWord is not a transformed word. - For example, - - Given: - beginWord = "hit" - endWord = "cog" - wordList = ["hot","dot","dog","lot","log","cog"] - Return - [ - ["hit","hot","dot","dog","cog"], - ["hit","hot","lot","log","cog"] - ] - Note: - Return an empty list if there is no such transformation sequence. - All words have the same length. - All words contain only lowercase alphabetic characters. - You may assume no duplicates in the word list. - You may assume beginWord and endWord are non-empty and are not the same. + * Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that: + *

+ * Only one letter can be changed at a time + * Each transformed word must exist in the word list. Note that beginWord is not a transformed word. + * For example, + *

+ * Given: + * beginWord = "hit" + * endWord = "cog" + * wordList = ["hot","dot","dog","lot","log","cog"] + * Return + * [ + * ["hit","hot","dot","dog","cog"], + * ["hit","hot","lot","log","cog"] + * ] + * Note: + * Return an empty list if there is no such transformation sequence. + * All words have the same length. + * All words contain only lowercase alphabetic characters. + * You may assume no duplicates in the word list. + * You may assume beginWord and endWord are non-empty and are not the same. */ -public class WordLadderII -{ +public class WordLadderII { private static Queue queue = new ArrayDeque<>(); private static Set dictionary = new HashSet<>(); @@ -37,20 +36,18 @@ public class WordLadderII private static List> result = new ArrayList<>(); - /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - List dic = Arrays.asList("kid","tag","pup","ail","tun","woo","erg","luz","brr","gay","sip","kay","per","val","mes","ohs","now","boa","cet","pal","bar","die","war","hay","eco","pub","lob","rue","fry","lit","rex","jan","cot","bid","ali","pay","col","gum","ger","row","won","dan","rum","fad","tut","sag","yip","sui","ark","has","zip","fez","own","ump","dis","ads","max","jaw","out","btu","ana","gap","cry","led","abe","box","ore","pig","fie","toy","fat","cal","lie","noh","sew","ono","tam","flu","mgm","ply","awe","pry","tit","tie","yet","too","tax","jim","san","pan","map","ski","ova","wed","non","wac","nut","why","bye","lye","oct","old","fin","feb","chi","sap","owl","log","tod","dot","bow","fob","for","joe","ivy","fan","age","fax","hip","jib","mel","hus","sob","ifs","tab","ara","dab","jag","jar","arm","lot","tom","sax","tex","yum","pei","wen","wry","ire","irk","far","mew","wit","doe","gas","rte","ian","pot","ask","wag","hag","amy","nag","ron","soy","gin","don","tug","fay","vic","boo","nam","ave","buy","sop","but","orb","fen","paw","his","sub","bob","yea","oft","inn","rod","yam","pew","web","hod","hun","gyp","wei","wis","rob","gad","pie","mon","dog","bib","rub","ere","dig","era","cat","fox","bee","mod","day","apr","vie","nev","jam","pam","new","aye","ani","and","ibm","yap","can","pyx","tar","kin","fog","hum","pip","cup","dye","lyx","jog","nun","par","wan","fey","bus","oak","bad","ats","set","qom","vat","eat","pus","rev","axe","ion","six","ila","lao","mom","mas","pro","few","opt","poe","art","ash","oar","cap","lop","may","shy","rid","bat","sum","rim","fee","bmw","sky","maj","hue","thy","ava","rap","den","fla","auk","cox","ibo","hey","saw","vim","sec","ltd","you","its","tat","dew","eva","tog","ram","let","see","zit","maw","nix","ate","gig","rep","owe","ind","hog","eve","sam","zoo","any","dow","cod","bed","vet","ham","sis","hex","via","fir","nod","mao","aug","mum","hoe","bah","hal","keg","hew","zed","tow","gog","ass","dem","who","bet","gos","son","ear","spy","kit","boy","due","sen","oaf","mix","hep","fur","ada","bin","nil","mia","ewe","hit","fix","sad","rib","eye","hop","haw","wax","mid","tad","ken","wad","rye","pap","bog","gut","ito","woe","our","ado","sin","mad","ray","hon","roy","dip","hen","iva","lug","asp","hui","yak","bay","poi","yep","bun","try","lad","elm","nat","wyo","gym","dug","toe","dee","wig","sly","rip","geo","cog","pas","zen","odd","nan","lay","pod","fit","hem","joy","bum","rio","yon","dec","leg","put","sue","dim","pet","yaw","nub","bit","bur","sid","sun","oil","red","doc","moe","caw","eel","dix","cub","end","gem","off","yew","hug","pop","tub","sgt","lid","pun","ton","sol","din","yup","jab","pea","bug","gag","mil","jig","hub","low","did","tin","get","gte","sox","lei","mig","fig","lon","use","ban","flo","nov","jut","bag","mir","sty","lap","two","ins","con","ant","net","tux","ode","stu","mug","cad","nap","gun","fop","tot","sow","sal","sic","ted","wot","del","imp","cob","way","ann","tan","mci","job","wet","ism","err","him","all","pad","hah","hie","aim","ike","jed","ego","mac","baa","min","com","ill","was","cab","ago","ina","big","ilk","gal","tap","duh","ola","ran","lab","top","gob","hot","ora","tia","kip","han","met","hut","she","sac","fed","goo","tee","ell","not","act","gil","rut","ala","ape","rig","cid","god","duo","lin","aid","gel","awl","lag","elf","liz","ref","aha","fib","oho","tho","her","nor","ace","adz","fun","ned","coo","win","tao","coy","van","man","pit","guy","foe","hid","mai","sup","jay","hob","mow","jot","are","pol","arc","lax","aft","alb","len","air","pug","pox","vow","got","meg","zoe","amp","ale","bud","gee","pin","dun","pat","ten","mob"); + public static void main(String[] args) throws Exception { + List dic = Arrays.asList("kid", "tag", "pup", "ail", "tun", "woo", "erg", "luz", "brr", "gay", "sip", "kay", "per", "val", "mes", "ohs", "now", "boa", "cet", "pal", "bar", "die", "war", "hay", "eco", "pub", "lob", "rue", "fry", "lit", "rex", "jan", "cot", "bid", "ali", "pay", "col", "gum", "ger", "row", "won", "dan", "rum", "fad", "tut", "sag", "yip", "sui", "ark", "has", "zip", "fez", "own", "ump", "dis", "ads", "max", "jaw", "out", "btu", "ana", "gap", "cry", "led", "abe", "box", "ore", "pig", "fie", "toy", "fat", "cal", "lie", "noh", "sew", "ono", "tam", "flu", "mgm", "ply", "awe", "pry", "tit", "tie", "yet", "too", "tax", "jim", "san", "pan", "map", "ski", "ova", "wed", "non", "wac", "nut", "why", "bye", "lye", "oct", "old", "fin", "feb", "chi", "sap", "owl", "log", "tod", "dot", "bow", "fob", "for", "joe", "ivy", "fan", "age", "fax", "hip", "jib", "mel", "hus", "sob", "ifs", "tab", "ara", "dab", "jag", "jar", "arm", "lot", "tom", "sax", "tex", "yum", "pei", "wen", "wry", "ire", "irk", "far", "mew", "wit", "doe", "gas", "rte", "ian", "pot", "ask", "wag", "hag", "amy", "nag", "ron", "soy", "gin", "don", "tug", "fay", "vic", "boo", "nam", "ave", "buy", "sop", "but", "orb", "fen", "paw", "his", "sub", "bob", "yea", "oft", "inn", "rod", "yam", "pew", "web", "hod", "hun", "gyp", "wei", "wis", "rob", "gad", "pie", "mon", "dog", "bib", "rub", "ere", "dig", "era", "cat", "fox", "bee", "mod", "day", "apr", "vie", "nev", "jam", "pam", "new", "aye", "ani", "and", "ibm", "yap", "can", "pyx", "tar", "kin", "fog", "hum", "pip", "cup", "dye", "lyx", "jog", "nun", "par", "wan", "fey", "bus", "oak", "bad", "ats", "set", "qom", "vat", "eat", "pus", "rev", "axe", "ion", "six", "ila", "lao", "mom", "mas", "pro", "few", "opt", "poe", "art", "ash", "oar", "cap", "lop", "may", "shy", "rid", "bat", "sum", "rim", "fee", "bmw", "sky", "maj", "hue", "thy", "ava", "rap", "den", "fla", "auk", "cox", "ibo", "hey", "saw", "vim", "sec", "ltd", "you", "its", "tat", "dew", "eva", "tog", "ram", "let", "see", "zit", "maw", "nix", "ate", "gig", "rep", "owe", "ind", "hog", "eve", "sam", "zoo", "any", "dow", "cod", "bed", "vet", "ham", "sis", "hex", "via", "fir", "nod", "mao", "aug", "mum", "hoe", "bah", "hal", "keg", "hew", "zed", "tow", "gog", "ass", "dem", "who", "bet", "gos", "son", "ear", "spy", "kit", "boy", "due", "sen", "oaf", "mix", "hep", "fur", "ada", "bin", "nil", "mia", "ewe", "hit", "fix", "sad", "rib", "eye", "hop", "haw", "wax", "mid", "tad", "ken", "wad", "rye", "pap", "bog", "gut", "ito", "woe", "our", "ado", "sin", "mad", "ray", "hon", "roy", "dip", "hen", "iva", "lug", "asp", "hui", "yak", "bay", "poi", "yep", "bun", "try", "lad", "elm", "nat", "wyo", "gym", "dug", "toe", "dee", "wig", "sly", "rip", "geo", "cog", "pas", "zen", "odd", "nan", "lay", "pod", "fit", "hem", "joy", "bum", "rio", "yon", "dec", "leg", "put", "sue", "dim", "pet", "yaw", "nub", "bit", "bur", "sid", "sun", "oil", "red", "doc", "moe", "caw", "eel", "dix", "cub", "end", "gem", "off", "yew", "hug", "pop", "tub", "sgt", "lid", "pun", "ton", "sol", "din", "yup", "jab", "pea", "bug", "gag", "mil", "jig", "hub", "low", "did", "tin", "get", "gte", "sox", "lei", "mig", "fig", "lon", "use", "ban", "flo", "nov", "jut", "bag", "mir", "sty", "lap", "two", "ins", "con", "ant", "net", "tux", "ode", "stu", "mug", "cad", "nap", "gun", "fop", "tot", "sow", "sal", "sic", "ted", "wot", "del", "imp", "cob", "way", "ann", "tan", "mci", "job", "wet", "ism", "err", "him", "all", "pad", "hah", "hie", "aim", "ike", "jed", "ego", "mac", "baa", "min", "com", "ill", "was", "cab", "ago", "ina", "big", "ilk", "gal", "tap", "duh", "ola", "ran", "lab", "top", "gob", "hot", "ora", "tia", "kip", "han", "met", "hut", "she", "sac", "fed", "goo", "tee", "ell", "not", "act", "gil", "rut", "ala", "ape", "rig", "cid", "god", "duo", "lin", "aid", "gel", "awl", "lag", "elf", "liz", "ref", "aha", "fib", "oho", "tho", "her", "nor", "ace", "adz", "fun", "ned", "coo", "win", "tao", "coy", "van", "man", "pit", "guy", "foe", "hid", "mai", "sup", "jay", "hob", "mow", "jot", "are", "pol", "arc", "lax", "aft", "alb", "len", "air", "pug", "pox", "vow", "got", "meg", "zoe", "amp", "ale", "bud", "gee", "pin", "dun", "pat", "ten", "mob"); new WordLadderII().findLadders("cet", "ism", dic); } - public List> findLadders(String beginWord, String endWord, List wordList) - { + public List> findLadders(String beginWord, String endWord, List wordList) { dictionary.addAll(wordList); bfs(beginWord, endWord, wordList); List path = new ArrayList<>(); @@ -62,37 +59,30 @@ public List> findLadders(String beginWord, String endWord, List wordList) - { + private void bfs(String beginWord, String endWord, List wordList) { queue.offer(beginWord); minDistance.put(beginWord, 0); - while(!queue.isEmpty()) - { + while (!queue.isEmpty()) { String currWord = queue.poll(); StringBuilder childSb = new StringBuilder(currWord); - for(int j = 0, ln = childSb.length(); j < ln; j ++ ) - { - for(int i = 0, l = CONST.length(); i < l; i ++ ) - { + for (int j = 0, ln = childSb.length(); j < ln; j++) { + for (int i = 0, l = CONST.length(); i < l; i++) { char old = childSb.charAt(j); childSb.replace(j, j + 1, String.valueOf(CONST.charAt(i))); String child = childSb.toString(); - if(dictionary.contains(child)) - { - if(minDistance.get(child) == null) - { + if (dictionary.contains(child)) { + if (minDistance.get(child) == null) { minDistance.put(child, minDistance.get(currWord) + 1); addChild(currWord, child); - if(!child.equals(endWord)) + if (!child.equals(endWord)) queue.offer(child); - } - else - { - if(minDistance.get(child) == (minDistance.get(currWord) + 1)) + } else { + if (minDistance.get(child) == (minDistance.get(currWord) + 1)) addChild(currWord, child); } } @@ -101,15 +91,16 @@ private void bfs(String beginWord, String endWord, List wordList) } } } + /** * Add child + * * @param parent parent - * @param child child + * @param child child */ - private void addChild(String parent, String child) - { + private void addChild(String parent, String child) { Set children = graph.get(parent); - if(children == null) + if (children == null) children = new HashSet<>(); children.add(child); graph.put(parent, children); @@ -117,23 +108,18 @@ private void addChild(String parent, String child) /** * Dfs to build path + * * @param currWord node - * @param endWord endword - * @param path path + * @param endWord endword + * @param path path */ - private void dfs(String currWord, String endWord, List path) - { - if(currWord.equals(endWord)) - { + private void dfs(String currWord, String endWord, List path) { + if (currWord.equals(endWord)) { result.add(new ArrayList<>(path)); - } - else - { + } else { Set children = graph.get(currWord); - if(children != null) - { - for(String c : children) - { + if (children != null) { + for (String c : children) { path.add(c); dfs(c, endWord, path); path.remove(path.size() - 1); diff --git a/problems/src/depth_first_search/CourseSchedule.java b/problems/src/depth_first_search/CourseSchedule.java index 131b4f25..b7465228 100644 --- a/problems/src/depth_first_search/CourseSchedule.java +++ b/problems/src/depth_first_search/CourseSchedule.java @@ -5,34 +5,35 @@ /** * Created by gouthamvidyapradhan on 22/06/2017. * There are a total of n courses you have to take, labeled from 0 to n - 1. - - Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] - - Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses? - - For example: - - 2, [[1,0]] - There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible. - - 2, [[1,0],[0,1]] - 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. - - Note: - The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented. - You may assume that there are no duplicate edges in the input prerequisites. - - Solution: - 1. Topologically sort the vertices. - 2. Pick each sorted vertex and mark each of its neighbours as visited, - if you encounter a vertex which is already visited then return false otherwise return true + *

+ * Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] + *

+ * Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses? + *

+ * For example: + *

+ * 2, [[1,0]] + * There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible. + *

+ * 2, [[1,0],[0,1]] + * 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. + *

+ * Note: + * The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented. + * You may assume that there are no duplicate edges in the input prerequisites. + *

+ * Solution: + * 1. Topologically sort the vertices. + * 2. Pick each sorted vertex and mark each of its neighbours as visited, + * if you encounter a vertex which is already visited then return false otherwise return true */ public class CourseSchedule { private Map> graph; private BitSet visited; private Queue toposorted; - public static void main(String[] args) throws Exception{ - int[][] pre = {{1,0}}; + + public static void main(String[] args) throws Exception { + int[][] pre = {{1, 0}}; System.out.println(new CourseSchedule().canFinish(2, pre)); } @@ -49,9 +50,9 @@ public boolean canFinish(int numCourses, int[][] prerequisites) { visited.clear(); - while(!toposorted.isEmpty()){ + while (!toposorted.isEmpty()) { int v = toposorted.poll(); - if(visited.get(v)) + if (visited.get(v)) return false; relax(v); } @@ -60,12 +61,13 @@ public boolean canFinish(int numCourses, int[][] prerequisites) { /** * Mark a vetex and its connected vertices as visited. + * * @param v vertex */ private void relax(int v) { visited.set(v); List children = graph.get(v); - if(children != null){ + if (children != null) { for (int c : children) visited.set(c); } @@ -73,14 +75,15 @@ private void relax(int v) { /** * Toposort + * * @param v vertex */ private void dfs(int v) { visited.set(v); List children = graph.get(v); - if(children != null) { - for(int c : children) - if(!visited.get(c)) + if (children != null) { + for (int c : children) + if (!visited.get(c)) dfs(c); } toposorted.offer(v); diff --git a/problems/src/depth_first_search/CourseScheduleII.java b/problems/src/depth_first_search/CourseScheduleII.java index cb8967b4..987e4f36 100644 --- a/problems/src/depth_first_search/CourseScheduleII.java +++ b/problems/src/depth_first_search/CourseScheduleII.java @@ -5,31 +5,31 @@ /** * Created by gouthamvidyapradhan on 23/06/2017. * There are a total of n courses you have to take, labeled from 0 to n - 1. - - Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] - - Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses. - - There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array. - - For example: - - 2, [[1,0]] - There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is [0,1] - - 4, [[1,0],[2,0],[3,1],[3,2]] - There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. Another correct ordering is[0,2,1,3]. - - Note: - The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented. - You may assume that there are no duplicate edges in the input prerequisites. + *

+ * Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] + *

+ * Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses. + *

+ * There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array. + *

+ * For example: + *

+ * 2, [[1,0]] + * There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is [0,1] + *

+ * 4, [[1,0],[2,0],[3,1],[3,2]] + * There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. Another correct ordering is[0,2,1,3]. + *

+ * Note: + * The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented. + * You may assume that there are no duplicate edges in the input prerequisites. */ public class CourseScheduleII { private Map> graph; private BitSet visited; private Queue toposorted; - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[][] pre = {{1, 0}}; int[] result = new CourseScheduleII().findOrder(2, pre); for (int i : result) @@ -41,7 +41,7 @@ public int[] findOrder(int numCourses, int[][] prerequisites) { int j = 0; int[] courses = new int[numCourses]; int[] result = new int[numCourses]; - for(int i = 0; i < numCourses; i ++) + for (int i = 0; i < numCourses; i++) courses[i] = j++; graph = new HashMap<>(); visited = new BitSet(); @@ -55,29 +55,30 @@ public int[] findOrder(int numCourses, int[][] prerequisites) { visited.clear(); int i = 0; - while(!toposorted.isEmpty()){ + while (!toposorted.isEmpty()) { int v = toposorted.poll(); - if(visited.get(v)) + if (visited.get(v)) return new int[0]; relax(v); result[i++] = v; courses[v] = -1; } //add the remaining courses - for(int c : courses) - if(c != -1) + for (int c : courses) + if (c != -1) result[i++] = c; return result; } /** * Mark a vetex and its connected vertices as visited. + * * @param v vertex */ private void relax(int v) { visited.set(v); List children = graph.get(v); - if(children != null){ + if (children != null) { for (int c : children) visited.set(c); } @@ -85,14 +86,15 @@ private void relax(int v) { /** * Toposort + * * @param v vertex */ private void dfs(int v) { visited.set(v); List children = graph.get(v); - if(children != null) { - for(int c : children) - if(!visited.get(c)) + if (children != null) { + for (int c : children) + if (!visited.get(c)) dfs(c); } toposorted.offer(v); diff --git a/problems/src/depth_first_search/Minesweeper.java b/problems/src/depth_first_search/Minesweeper.java index 1008ed08..fbf41584 100644 --- a/problems/src/depth_first_search/Minesweeper.java +++ b/problems/src/depth_first_search/Minesweeper.java @@ -2,108 +2,99 @@ /** * Created by pradhang on 3/28/2017. - You are given a 2D char matrix representing the game board. 'M' represents an unrevealed mine, 'E' represents an unrevealed empty square, 'B' represents a revealed blank square that has no adjacent (above, below, left, right, and all 4 diagonals) mines, digit ('1' to '8') represents how many mines are adjacent to this revealed square, and finally 'X' represents a revealed mine. - - Now given the next click position (row and column indices) among all the unrevealed squares ('M' or 'E'), return the board after revealing this position according to the following rules: - - If a mine ('M') is revealed, then the game is over - change it to 'X'. - If an empty square ('E') with no adjacent mines is revealed, then change it to revealed blank ('B') and all of its adjacent unrevealed squares should be revealed recursively. - If an empty square ('E') with at least one adjacent mine is revealed, then change it to a digit ('1' to '8') representing the number of adjacent mines. - Return the board when no more squares will be revealed. - Example 1: - Input: - - [['E', 'E', 'E', 'E', 'E'], - ['E', 'E', 'M', 'E', 'E'], - ['E', 'E', 'E', 'E', 'E'], - ['E', 'E', 'E', 'E', 'E']] - - Click : [3,0] - - Output: - - [['B', '1', 'E', '1', 'B'], - ['B', '1', 'M', '1', 'B'], - ['B', '1', '1', '1', 'B'], - ['B', 'B', 'B', 'B', 'B']] - - Example 2: - Input: - - [['B', '1', 'E', '1', 'B'], - ['B', '1', 'M', '1', 'B'], - ['B', '1', '1', '1', 'B'], - ['B', 'B', 'B', 'B', 'B']] - - Click : [1,2] - - Output: - - [['B', '1', 'E', '1', 'B'], - ['B', '1', 'X', '1', 'B'], - ['B', '1', '1', '1', 'B'], - ['B', 'B', 'B', 'B', 'B']] - - Note: - The range of the input matrix's height and width is [1,50]. - The click position will only be an unrevealed square ('M' or 'E'), which also means the input board contains at least one clickable square. - The input board won't be a stage when game is over (some mines have been revealed). - For simplicity, not mentioned rules should be ignored in this problem. For example, you don't need to reveal all the unrevealed mines when the game is over, consider any cases that you will win the game or flag any squares. - + * You are given a 2D char matrix representing the game board. 'M' represents an unrevealed mine, 'E' represents an unrevealed empty square, 'B' represents a revealed blank square that has no adjacent (above, below, left, right, and all 4 diagonals) mines, digit ('1' to '8') represents how many mines are adjacent to this revealed square, and finally 'X' represents a revealed mine. + *

+ * Now given the next click position (row and column indices) among all the unrevealed squares ('M' or 'E'), return the board after revealing this position according to the following rules: + *

+ * If a mine ('M') is revealed, then the game is over - change it to 'X'. + * If an empty square ('E') with no adjacent mines is revealed, then change it to revealed blank ('B') and all of its adjacent unrevealed squares should be revealed recursively. + * If an empty square ('E') with at least one adjacent mine is revealed, then change it to a digit ('1' to '8') representing the number of adjacent mines. + * Return the board when no more squares will be revealed. + * Example 1: + * Input: + *

+ * [['E', 'E', 'E', 'E', 'E'], + * ['E', 'E', 'M', 'E', 'E'], + * ['E', 'E', 'E', 'E', 'E'], + * ['E', 'E', 'E', 'E', 'E']] + *

+ * Click : [3,0] + *

+ * Output: + *

+ * [['B', '1', 'E', '1', 'B'], + * ['B', '1', 'M', '1', 'B'], + * ['B', '1', '1', '1', 'B'], + * ['B', 'B', 'B', 'B', 'B']] + *

+ * Example 2: + * Input: + *

+ * [['B', '1', 'E', '1', 'B'], + * ['B', '1', 'M', '1', 'B'], + * ['B', '1', '1', '1', 'B'], + * ['B', 'B', 'B', 'B', 'B']] + *

+ * Click : [1,2] + *

+ * Output: + *

+ * [['B', '1', 'E', '1', 'B'], + * ['B', '1', 'X', '1', 'B'], + * ['B', '1', '1', '1', 'B'], + * ['B', 'B', 'B', 'B', 'B']] + *

+ * Note: + * The range of the input matrix's height and width is [1,50]. + * The click position will only be an unrevealed square ('M' or 'E'), which also means the input board contains at least one clickable square. + * The input board won't be a stage when game is over (some mines have been revealed). + * For simplicity, not mentioned rules should be ignored in this problem. For example, you don't need to reveal all the unrevealed mines when the game is over, consider any cases that you will win the game or flag any squares. */ -public class Minesweeper -{ +public class Minesweeper { private static final int[] R = {1, 1, 1, 0, 0, -1, -1, -1}; private static final int[] C = {-1, 0, 1, -1, 1, -1, 0, 1}; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - char[][] board = {{'E','E','E','E','E'},{'E','E','M','E','E'},{'E','E','E','E','E'},{'E','E','E','E','E'}}; + public static void main(String[] args) throws Exception { + char[][] board = {{'E', 'E', 'E', 'E', 'E'}, {'E', 'E', 'M', 'E', 'E'}, {'E', 'E', 'E', 'E', 'E'}, {'E', 'E', 'E', 'E', 'E'}}; int[] click = {3, 0}; new Minesweeper().updateBoard(board, click); - for (int i = 0; i < board.length; i ++) + for (int i = 0; i < board.length; i++) System.out.println(board[i]); } - public char[][] updateBoard(char[][] board, int[] click) - { + public char[][] updateBoard(char[][] board, int[] click) { int r = click[0]; int c = click[1]; dfs(board, r, c); return board; } - private void dfs(char[][] board, int r, int c) - { - if(board[r][c] == 'M') - { + private void dfs(char[][] board, int r, int c) { + if (board[r][c] == 'M') { board[r][c] = 'X'; - } - else - { + } else { int mineCount = 0; - for(int i = 0; i < 8; i ++) - { + for (int i = 0; i < 8; i++) { int newR = r + R[i]; int newC = c + C[i]; - if(newR >=0 && newC >= 0 && newR < board.length && newC < board[0].length && + if (newR >= 0 && newC >= 0 && newR < board.length && newC < board[0].length && board[newR][newC] == 'M') //boundary check mineCount++; } - if(mineCount > 0) - board[r][c] = (char)(mineCount + '0'); - else - { + if (mineCount > 0) + board[r][c] = (char) (mineCount + '0'); + else { board[r][c] = 'B'; - for(int i = 0; i < 8; i ++) - { + for (int i = 0; i < 8; i++) { int newR = r + R[i]; int newC = c + C[i]; - if(newR >=0 && newC >= 0 && newR < board.length && newC < board[0].length && + if (newR >= 0 && newC >= 0 && newR < board.length && newC < board[0].length && board[newR][newC] == 'E') //boundary check { dfs(board, newR, newC); diff --git a/problems/src/depth_first_search/MovieRecommend.java b/problems/src/depth_first_search/MovieRecommend.java index dff0c202..a4e061d7 100644 --- a/problems/src/depth_first_search/MovieRecommend.java +++ b/problems/src/depth_first_search/MovieRecommend.java @@ -6,66 +6,58 @@ * Created by gouthamvidyapradhan on 25/02/2017. * Accepted */ -public class MovieRecommend -{ +public class MovieRecommend { Set visited = new HashSet<>(); List list = new ArrayList<>(); - class Movie - { + + class Movie { private int movieId; private float rating; private ArrayList similarMovies; - public List getSimilarMovies() - { + + public List getSimilarMovies() { return similarMovies; } } + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { } - public Set getMovieRecommendations (Movie movie, int N) - { + public Set getMovieRecommendations(Movie movie, int N) { dfs(movie); Set result = new HashSet<>(); - Comparator cmp = new Comparator() - { + Comparator cmp = new Comparator() { @Override - public int compare(Movie o1, Movie o2) - { + public int compare(Movie o1, Movie o2) { return Float.compare(o2.rating, o1.rating); } }; Collections.sort(list, cmp); - if(list.size() < N) - { + if (list.size() < N) { result.addAll(list); return result; } - for(int i = 0; i < N; i ++) - { + for (int i = 0; i < N; i++) { result.add(list.get(i)); } return result; } - private void dfs(Movie m) - { + private void dfs(Movie m) { visited.add(m.movieId); // mark this visited List movies = m.getSimilarMovies(); - for(Movie mo : movies) - { - if(!visited.contains(mo.movieId)) - { + for (Movie mo : movies) { + if (!visited.contains(mo.movieId)) { list.add(mo); dfs(mo); } diff --git a/problems/src/depth_first_search/NumberOfIslands.java b/problems/src/depth_first_search/NumberOfIslands.java index a5ff9468..e624f42f 100644 --- a/problems/src/depth_first_search/NumberOfIslands.java +++ b/problems/src/depth_first_search/NumberOfIslands.java @@ -2,50 +2,44 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water. - - Example 1: - - 11110 - 11010 - 11000 - 00000 - Answer: 1 - - Example 2: - - 11000 - 11000 - 00100 - 00011 - Answer: 3 + * Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water. + *

+ * Example 1: + *

+ * 11110 + * 11010 + * 11000 + * 00000 + * Answer: 1 + *

+ * Example 2: + *

+ * 11000 + * 11000 + * 00100 + * 00011 + * Answer: 3 */ -public class NumberOfIslands -{ +public class NumberOfIslands { int[] R = {0, 0, 1, -1}; int[] C = {1, -1, 0, 0}; private static int M, N; private static char temp[][]; - public int numIslands(char[][] grid) - { + public int numIslands(char[][] grid) { M = grid.length; - if(M == 0) return 0; + if (M == 0) return 0; N = grid[0].length; temp = new char[M][N]; int count = 0; - for(int i = 0; i < M; i ++) - { + for (int i = 0; i < M; i++) { System.arraycopy(grid[i], 0, temp[i], 0, N); } - for(int i = 0; i < M; i ++) - { - for(int j = 0; j < N; j++) - { - if(temp[i][j] == '1') - { + for (int i = 0; i < M; i++) { + for (int j = 0; j < N; j++) { + if (temp[i][j] == '1') { ++count; dfs(i, j); } @@ -55,16 +49,13 @@ public int numIslands(char[][] grid) return count; } - private void dfs(int r, int c) - { + private void dfs(int r, int c) { temp[r][c] = '0'; - for(int i = 0; i < 4; i++) - { + for (int i = 0; i < 4; i++) { int newR = r + R[i]; int newC = c + C[i]; - if(newR >=0 && newC >= 0 && newR < M && newC < N) - { - if(temp[newR][newC] != '0') //not visited + if (newR >= 0 && newC >= 0 && newR < M && newC < N) { + if (temp[newR][newC] != '0') //not visited { dfs(newR, newC); } diff --git a/problems/src/design/AutocompleteSystem.java b/problems/src/design/AutocompleteSystem.java index dec4eea1..89b426fe 100644 --- a/problems/src/design/AutocompleteSystem.java +++ b/problems/src/design/AutocompleteSystem.java @@ -4,79 +4,79 @@ /** * Created by gouthamvidyapradhan on 20/08/2017. - * + *

* Design a search autocomplete system for a search engine. Users may input a sentence (at least one word and end with a special character '#'). * For each character they type except '#', you need to return the top 3 historical hot sentences that have prefix the same as the part of sentence already typed. * Here are the specific rules: - - The hot degree for a sentence is defined as the number of times a user typed the exactly same sentence before. - The returned top 3 hot sentences should be sorted by hot degree (The first is the hottest one). - If several sentences have the same degree of hot, you need to use ASCII-code order (smaller one appears first). - If less than 3 hot sentences exist, then just return as many as you can. - When the input is a special character, it means the sentence ends, and in this case, you need to return an empty list. - Your job is to implement the following functions: - - The constructor function: - - AutocompleteSystem(String[] sentences, int[] times): This is the constructor. - The input is historical data. Sentences is a string array consists of previously typed sentences. - Times is the corresponding times a sentence has been typed. Your system should record these historical data. - - Now, the user wants to input a new sentence. The following function will provide the next character the user types: - - List input(char c): The input c is the next character typed by the user. - The character will only be lower-case letters ('a' to 'z'), blank space (' ') or a special character ('#'). - Also, the previously typed sentence should be recorded in your system. - The output will be the top 3 historical hot sentences that have prefix the same as the part of sentence already typed. - - - Example: - Operation: AutocompleteSystem(["i love you", "island","ironman", "i love leetcode"], [5,3,2,2]) - The system have already tracked down the following sentences and their corresponding times: - "i love you" : 5 times - "island" : 3 times - "ironman" : 2 times - "i love leetcode" : 2 times - Now, the user begins another search: - - Operation: input('i') - Output: ["i love you", "island","i love leetcode"] - Explanation: - There are four sentences that have prefix "i". Among them, "ironman" and "i love leetcode" have same hot degree. - Since ' ' has ASCII code 32 and 'r' has ASCII code 114, "i love leetcode" should be in front of "ironman". - Also we only need to output top 3 hot sentences, so "ironman" will be ignored. - - Operation: input(' ') - Output: ["i love you","i love leetcode"] - Explanation: - There are only two sentences that have prefix "i ". - - Operation: input('a') - Output: [] - Explanation: - There are no sentences that have prefix "i a". - - Operation: input('#') - Output: [] - Explanation: - The user finished the input, the sentence "i a" should be saved as a historical sentence in system. - And the following input will be counted as a new search. - - Note: - The input sentence will always start with a letter and end with '#', and only one blank space will exist between two words. - The number of complete sentences that to be searched won't exceed 100. - The length of each sentence including those in the historical data won't exceed 100. - Please use double-quote instead of single-quote when you write test cases even for a character input. - Please remember to RESET your class variables declared in class AutocompleteSystem, as static/class variables are persisted across multiple test cases. - - Solution: Maintain a Trie (slightly modified) data-structure to all the input sentences where each node of the Trie - is a node containing a hash-map of child character and node and a TreeSet containing the sorted order of all the - possible child sentences starting from the current node. Maintain a cursor node 'curr' to indicate the current node - of input, if the input character is absent then simply mark curr as null indicating no further auto-complete terms possible. - On the other hand if the input character is present then simply pick the top 3 elements from the TreeSet object of curr - node. - Finally, use a StringBuilder to accumulate all the input characters and when a end of sentence is '#' is encountered - simply update the trie with new sentence and degree. + *

+ * The hot degree for a sentence is defined as the number of times a user typed the exactly same sentence before. + * The returned top 3 hot sentences should be sorted by hot degree (The first is the hottest one). + * If several sentences have the same degree of hot, you need to use ASCII-code order (smaller one appears first). + * If less than 3 hot sentences exist, then just return as many as you can. + * When the input is a special character, it means the sentence ends, and in this case, you need to return an empty list. + * Your job is to implement the following functions: + *

+ * The constructor function: + *

+ * AutocompleteSystem(String[] sentences, int[] times): This is the constructor. + * The input is historical data. Sentences is a string array consists of previously typed sentences. + * Times is the corresponding times a sentence has been typed. Your system should record these historical data. + *

+ * Now, the user wants to input a new sentence. The following function will provide the next character the user types: + *

+ * List input(char c): The input c is the next character typed by the user. + * The character will only be lower-case letters ('a' to 'z'), blank space (' ') or a special character ('#'). + * Also, the previously typed sentence should be recorded in your system. + * The output will be the top 3 historical hot sentences that have prefix the same as the part of sentence already typed. + *

+ *

+ * Example: + * Operation: AutocompleteSystem(["i love you", "island","ironman", "i love leetcode"], [5,3,2,2]) + * The system have already tracked down the following sentences and their corresponding times: + * "i love you" : 5 times + * "island" : 3 times + * "ironman" : 2 times + * "i love leetcode" : 2 times + * Now, the user begins another search: + *

+ * Operation: input('i') + * Output: ["i love you", "island","i love leetcode"] + * Explanation: + * There are four sentences that have prefix "i". Among them, "ironman" and "i love leetcode" have same hot degree. + * Since ' ' has ASCII code 32 and 'r' has ASCII code 114, "i love leetcode" should be in front of "ironman". + * Also we only need to output top 3 hot sentences, so "ironman" will be ignored. + *

+ * Operation: input(' ') + * Output: ["i love you","i love leetcode"] + * Explanation: + * There are only two sentences that have prefix "i ". + *

+ * Operation: input('a') + * Output: [] + * Explanation: + * There are no sentences that have prefix "i a". + *

+ * Operation: input('#') + * Output: [] + * Explanation: + * The user finished the input, the sentence "i a" should be saved as a historical sentence in system. + * And the following input will be counted as a new search. + *

+ * Note: + * The input sentence will always start with a letter and end with '#', and only one blank space will exist between two words. + * The number of complete sentences that to be searched won't exceed 100. + * The length of each sentence including those in the historical data won't exceed 100. + * Please use double-quote instead of single-quote when you write test cases even for a character input. + * Please remember to RESET your class variables declared in class AutocompleteSystem, as static/class variables are persisted across multiple test cases. + *

+ * Solution: Maintain a Trie (slightly modified) data-structure to all the input sentences where each node of the Trie + * is a node containing a hash-map of child character and node and a TreeSet containing the sorted order of all the + * possible child sentences starting from the current node. Maintain a cursor node 'curr' to indicate the current node + * of input, if the input character is absent then simply mark curr as null indicating no further auto-complete terms possible. + * On the other hand if the input character is present then simply pick the top 3 elements from the TreeSet object of curr + * node. + * Finally, use a StringBuilder to accumulate all the input characters and when a end of sentence is '#' is encountered + * simply update the trie with new sentence and degree. */ public class AutocompleteSystem { @@ -86,12 +86,13 @@ public class AutocompleteSystem { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ - String[] sentences = {"i love you", "island","ironman", "i love leetcode"}; - int[] degree = {5,3,2,2}; + public static void main(String[] args) throws Exception { + String[] sentences = {"i love you", "island", "ironman", "i love leetcode"}; + int[] degree = {5, 3, 2, 2}; AutocompleteSystem autocomplete = new AutocompleteSystem(sentences, degree); List result = autocomplete.input('i'); result.forEach(System.out::println); @@ -105,35 +106,38 @@ public static void main(String[] args) throws Exception{ /** * Initialize the trie data-structure + * * @param sentences array of sentences - * @param times degree + * @param times degree */ public AutocompleteSystem(String[] sentences, int[] times) { hotTextMap = new HashMap<>(); trie = new Trie(); - for(int i = 0; i < sentences.length; i ++){ + for (int i = 0; i < sentences.length; i++) { hotTextMap.put(sentences[i], times[i]); trie.insert(sentences[i]); trie.update(sentences[i]); } - curr = trie; root = trie; + curr = trie; + root = trie; currSentence = new StringBuilder(); } /** * Accept input and return hot-text for the current char + * * @param c char * @return List of top 3 hot-text */ public List input(char c) { List result = new ArrayList<>(); - if(c == '#'){ + if (c == '#') { String sentence = currSentence.toString(); - if(hotTextMap.containsKey(sentence)){ + if (hotTextMap.containsKey(sentence)) { //already a known sentence hence only update in necessary hotTextMap.put(sentence, hotTextMap.get(sentence) + 1); trie.update(sentence); - } else{ + } else { //insert a new sentence and update the degree hotTextMap.put(sentence, 1); trie.insert(sentence); @@ -141,10 +145,9 @@ public List input(char c) { } currSentence = new StringBuilder(); //reset StringBuilder curr = root; //point to root of the trie - } - else { - if(curr != null) { - if(curr.containsChild(c)) { + } else { + if (curr != null) { + if (curr.containsChild(c)) { List hotText = curr.getSubtrie(c).getTop3HotText(); hotText.stream().forEach((x) -> result.add(currSentence.toString() + x)); //each node only returns //the hot-text for the current and child nodes hence we have to attach the prefix string @@ -162,10 +165,11 @@ public List input(char c) { /** * Class HotText to store the text and degree */ - private class HotText{ + private class HotText { private String text; private int degree; - HotText(String text, int degree){ + + HotText(String text, int degree) { this.text = text; this.degree = degree; } @@ -187,11 +191,12 @@ private class Trie { private TreeSet hotText = new TreeSet<>((HotText o1, HotText o2) -> { int cmp = Integer.compare(o2.getDegree(), o1.getDegree()); - return cmp == 0 ? o1.getText().compareTo(o2.getText()) : cmp; + return cmp == 0 ? o1.getText().compareTo(o2.getText()) : cmp; }); /** * Get hot-text + * * @return HotText */ public TreeSet getHotText() { @@ -200,55 +205,59 @@ public TreeSet getHotText() { /** * Return top 3 hottext + * * @return hot text */ - private List getTop3HotText(){ + private List getTop3HotText() { List hotText = new ArrayList<>(); - if(this.getHotText() != null){ + if (this.getHotText() != null) { this.getHotText().stream().limit(3).forEach((x) -> hotText.add(x.getText())); } return hotText; } - /** Inserts a word into the trie. */ + /** + * Inserts a word into the trie. + */ private void insert(String word) { - if(word != null){ + if (word != null) { add(0, word, word.length()); } } - private void add(int i, String word, int length){ - if(i < length){ + private void add(int i, String word, int length) { + if (i < length) { char c = word.charAt(i); Trie subTrie = map.get(c); - if(subTrie == null){ + if (subTrie == null) { subTrie = new Trie(); map.put(c, subTrie); } subTrie.add(i + 1, word, length); - } - else map.put(null, new Trie()); //use null to indicate end of string + } else map.put(null, new Trie()); //use null to indicate end of string } /** * Update hottex and degree + * * @param word word or sentence */ private void update(String word) { - if(word != null){ + if (word != null) { update(0, word, word.length()); } } /** * Update trie - * @param i curr position - * @param word sentence + * + * @param i curr position + * @param word sentence * @param length length * @return HotText */ - private HotText update(int i, String word, int length){ - if(i < length){ + private HotText update(int i, String word, int length) { + if (i < length) { char c = word.charAt(i); Trie subTrie = map.get(c); HotText subTrieHotText = subTrie.update(i + 1, word, length); @@ -262,9 +271,10 @@ private HotText update(int i, String word, int length){ /** * Hot text update + * * @param hotText hotText object */ - private void updateHotText(Trie trie, HotText hotText){ + private void updateHotText(Trie trie, HotText hotText) { trie.getHotText().remove(new HotText(hotText.getText(), hotText.getDegree() - 1)); //remove already // contained hot-text and add new trie.getHotText().add(hotText); @@ -272,19 +282,21 @@ private void updateHotText(Trie trie, HotText hotText){ /** * Contains child + * * @param c char * @return true if it contains child, false otherwise */ - private boolean containsChild(char c){ + private boolean containsChild(char c) { return this.map.containsKey(c); } /** * Return child tree + * * @param c char * @return child subTrie */ - private Trie getSubtrie(char c){ + private Trie getSubtrie(char c) { return this.map.get(c); } } diff --git a/problems/src/design/BSTIterator.java b/problems/src/design/BSTIterator.java index 801781af..0955e621 100644 --- a/problems/src/design/BSTIterator.java +++ b/problems/src/design/BSTIterator.java @@ -5,13 +5,13 @@ /** * Created by gouthamvidyapradhan on 13/08/2017. * Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST. - - Calling next() will return the next smallest number in the BST. - - Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree. - - Solution: The below solution works in average O(1) time and worst case O(h) time using O(h) memory. - Use a stack to keep track of min value node. + *

+ * Calling next() will return the next smallest number in the BST. + *

+ * Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree. + *

+ * Solution: The below solution works in average O(1) time and worst case O(h) time using O(h) memory. + * Use a stack to keep track of min value node. */ public class BSTIterator { @@ -21,10 +21,13 @@ public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(10); root.left = new TreeNode(5); root.left.left = new TreeNode(4); @@ -53,14 +56,18 @@ public BSTIterator(TreeNode root) { fillStack(root); } - /** @return whether we have a next smallest number */ + /** + * @return whether we have a next smallest number + */ public boolean hasNext() { return !stack.isEmpty(); } - /** @return the next smallest number */ + /** + * @return the next smallest number + */ public int next() { - if(!stack.isEmpty()) { + if (!stack.isEmpty()) { TreeNode top = stack.pop(); fillStack(top.right); return top.val; @@ -70,11 +77,12 @@ public int next() { /** * Fill stack with min values + * * @param node curr node to begin with */ - private void fillStack(TreeNode node){ + private void fillStack(TreeNode node) { TreeNode ite = node; - while(ite != null){ + while (ite != null) { stack.push(ite); ite = ite.left; } diff --git a/problems/src/design/CopyListWithRandomPointer.java b/problems/src/design/CopyListWithRandomPointer.java index 90157e19..ec83f894 100644 --- a/problems/src/design/CopyListWithRandomPointer.java +++ b/problems/src/design/CopyListWithRandomPointer.java @@ -2,28 +2,28 @@ /** * Created by gouthamvidyapradhan on 11/03/2017. - A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. - - Return a deep copy of the list. + * A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. + *

+ * Return a deep copy of the list. */ -public class CopyListWithRandomPointer -{ +public class CopyListWithRandomPointer { - static class RandomListNode - { + static class RandomListNode { int label; RandomListNode next, random; - RandomListNode(int x) - { this.label = x; } + + RandomListNode(int x) { + this.label = x; + } } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { RandomListNode one = new RandomListNode(1); one.next = null; one.random = one; @@ -44,12 +44,10 @@ public static void main(String[] args) throws Exception System.out.println(); } - private RandomListNode copyRandomList(RandomListNode head) - { - if(head == null) return null; + private RandomListNode copyRandomList(RandomListNode head) { + if (head == null) return null; RandomListNode ite = head, next; - while(ite != null) - { + while (ite != null) { next = ite.next; RandomListNode node = new RandomListNode(ite.label); ite.next = node; @@ -58,16 +56,15 @@ private RandomListNode copyRandomList(RandomListNode head) } ite = head; - while(ite != null) - { - if(ite.random != null) + while (ite != null) { + if (ite.random != null) ite.next.random = ite.random.next; ite = ite.next.next; } - ite = head; RandomListNode copyIte = ite.next, copyHead = ite.next; - while(copyIte.next != null) - { + ite = head; + RandomListNode copyIte = ite.next, copyHead = ite.next; + while (copyIte.next != null) { ite.next = copyIte.next; copyIte.next = ite.next.next; copyIte = copyIte.next; diff --git a/problems/src/design/EncodeAndDecodeTinyURL.java b/problems/src/design/EncodeAndDecodeTinyURL.java index fb9b8001..09eae92a 100644 --- a/problems/src/design/EncodeAndDecodeTinyURL.java +++ b/problems/src/design/EncodeAndDecodeTinyURL.java @@ -5,37 +5,34 @@ /** * Created by gouthamvidyapradhan on 11/04/2017. - TinyURL is a URL shortening service where you enter a URL such as https://leetcode.com/problems/design-tinyurl and it returns a short URL such as http://tinyurl.com/4e9iAk. - - Design the encode and decode methods for the TinyURL service. There is no restriction on how your encode/decode algorithm should work. You just need to ensure that a URL can be encoded to a tiny URL and the tiny URL can be decoded to the original URL. - + * TinyURL is a URL shortening service where you enter a URL such as https://leetcode.com/problems/design-tinyurl and it returns a short URL such as http://tinyurl.com/4e9iAk. + *

+ * Design the encode and decode methods for the TinyURL service. There is no restriction on how your encode/decode algorithm should work. You just need to ensure that a URL can be encoded to a tiny URL and the tiny URL can be decoded to the original URL. */ -public class EncodeAndDecodeTinyURL -{ +public class EncodeAndDecodeTinyURL { private List list = new ArrayList<>(); private static final String URL = "http://tinyurl.com/"; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { EncodeAndDecodeTinyURL encoder = new EncodeAndDecodeTinyURL(); String shorterUrl = encoder.encode("https://leetcode.com/problems/design-tinyurl"); System.out.println(encoder.decode(shorterUrl)); } // Encodes a URL to a shortened URL. - public String encode(String longUrl) - { + public String encode(String longUrl) { list.add(longUrl); return URL.concat(String.valueOf(list.size())); } // Decodes a shortened URL to its original URL. - public String decode(String shortUrl) - { + public String decode(String shortUrl) { String[] parts = shortUrl.split("http://tinyurl.com/"); String code = parts[1]; return list.get(Integer.parseInt(code) - 1); diff --git a/problems/src/design/LFUCache.java b/problems/src/design/LFUCache.java index d8e6b0f6..7a9fd05b 100644 --- a/problems/src/design/LFUCache.java +++ b/problems/src/design/LFUCache.java @@ -1,20 +1,23 @@ package design; -import java.util.*; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; /** * Created by gouthamvidyapradhan on 20/03/2017. - Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the following operations: get and put. - - get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. - put(key, value) - Set or insert the value if the key is not already present. When the cache reaches its capacity, it should invalidate the least frequently used item before inserting a new item. For the purpose of this problem, when there is a tie (i.e., two or more keys that have the same frequency), the least recently used key would be evicted. - - Follow up: - Could you do both operations in O(1) time complexity? - - Example: - - LFUCache cache = new LFUCache( 2 /* capacity */ /*) + * Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the following operations: get and put. + *

+ * get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. + * put(key, value) - Set or insert the value if the key is not already present. When the cache reaches its capacity, it should invalidate the least frequently used item before inserting a new item. For the purpose of this problem, when there is a tie (i.e., two or more keys that have the same frequency), the least recently used key would be evicted. + *

+ * Follow up: + * Could you do both operations in O(1) time complexity? + *

+ * Example: + *

+ * LFUCache cache = new LFUCache( 2 /* capacity + */ /*) cache.put(1, 1); cache.put(2, 2); @@ -27,17 +30,15 @@ Could you do both operations in O(1) time complexity? cache.get(3); // returns 3 cache.get(4); // returns 4 */ -public class LFUCache -{ - private class Node - { +public class LFUCache { + private class Node { int frequency; Node prev; Node next; LinkedHashSet hashSet; + Node(int frequency, - LinkedHashSet hashSet) - { + LinkedHashSet hashSet) { this.frequency = frequency; this.hashSet = hashSet; prev = null; @@ -51,12 +52,13 @@ private class Node private Map cache; private Map fMap; //frequency private Node head; + /** * Main method + * * @param args */ - public static void main(String[] args) - { + public static void main(String[] args) { LFUCache cache1 = new LFUCache(2); cache1.put(1, 1); cache1.put(2, 2); @@ -83,8 +85,7 @@ public static void main(String[] args) //System.out.println(cache1.get(4)); } - public LFUCache(int capacity) - { + public LFUCache(int capacity) { currentSize = 0; this.capacity = capacity; cache = new HashMap<>(); @@ -93,22 +94,17 @@ public LFUCache(int capacity) /** * Remove node and delink + * * @param node Node */ - private void popNode(Node node) - { - if(node.prev != null && node.next != null) - { + private void popNode(Node node) { + if (node.prev != null && node.next != null) { node.prev.next = node.next; node.next.prev = node.prev; - } - else if(node.prev == null) - { + } else if (node.prev == null) { node.next.prev = null; node.next = null; - } - else - { + } else { node.prev.next = null; node.prev = null; } @@ -116,58 +112,54 @@ else if(node.prev == null) /** * Get value + * * @param key key * @return value */ - public int get(int key) - { - if(!cache.containsKey(key)) return -1; + public int get(int key) { + if (!cache.containsKey(key)) return -1; fMap.put(key, update(key)); return cache.get(key); } /** * Update fMap + * * @param key key */ - private Node update(int key) - { + private Node update(int key) { Node node = fMap.get(key); node.hashSet.remove(key); Node newNode; - if(node.next == null) - { + if (node.next == null) { newNode = makeNewNode(key, node.frequency + 1); node.next = newNode; newNode.prev = node; - } - else if(node.next.frequency == node.frequency + 1) - { + } else if (node.next.frequency == node.frequency + 1) { node.next.hashSet.add(key); newNode = node.next; - } - else - { + } else { newNode = makeNewNode(key, node.frequency + 1); node.next.prev = newNode; newNode.next = node.next; newNode.prev = node; node.next = newNode; } - if(node.equals(head)) + if (node.equals(head)) incrementHead(); - else if(node.hashSet.isEmpty()) + else if (node.hashSet.isEmpty()) popNode(node); return newNode; } + /** * Make new node - * @param key key + * + * @param key key * @param frequency frequency * @return Node */ - private Node makeNewNode(int key, int frequency) - { + private Node makeNewNode(int key, int frequency) { LinkedHashSet linkedHashSet = new LinkedHashSet<>(); linkedHashSet.add(key); return new Node(frequency, linkedHashSet); @@ -175,33 +167,29 @@ private Node makeNewNode(int key, int frequency) /** * Add new head - * @param key key + * + * @param key key * @param frequency frequency */ - private Node addHead(int key, int frequency) - { - if(head == null) + private Node addHead(int key, int frequency) { + if (head == null) head = makeNewNode(key, frequency); - else if(head.frequency > frequency) - { + else if (head.frequency > frequency) { Node node = makeNewNode(key, frequency); node.next = head; head.prev = node; head = node; - } - else head.hashSet.add(key); + } else head.hashSet.add(key); return head; } + /** * Increment head */ - private void incrementHead() - { - if(head.hashSet.isEmpty()) - { + private void incrementHead() { + if (head.hashSet.isEmpty()) { head = head.next; - if(head != null) - { + if (head != null) { head.prev.next = null; head.prev = null; } @@ -210,28 +198,21 @@ private void incrementHead() /** * Put key value pair - * @param key key + * + * @param key key * @param value value */ - public void put(int key, int value) - { - if(capacity != 0) - { - if(cache.containsKey(key)) - { + public void put(int key, int value) { + if (capacity != 0) { + if (cache.containsKey(key)) { fMap.put(key, update(key)); //update existing cache.put(key, value); - } - else - { - if(currentSize == capacity) - { + } else { + if (currentSize == capacity) { evict(); cache.put(key, value); fMap.put(key, addHead(key, 1)); - } - else - { + } else { fMap.put(key, addHead(key, 1)); //add new head cache.put(key, value); currentSize++; @@ -243,8 +224,7 @@ public void put(int key, int value) /** * Evict the node with least frequency */ - private void evict() - { + private void evict() { int key = head.hashSet.iterator().next(); head.hashSet.remove(key); cache.remove(key); diff --git a/problems/src/design/LRUCache.java b/problems/src/design/LRUCache.java index 7838106a..2608859f 100644 --- a/problems/src/design/LRUCache.java +++ b/problems/src/design/LRUCache.java @@ -1,20 +1,22 @@ package design; -import java.util.*; +import java.util.HashMap; +import java.util.Map; /** * Created by gouthamvidyapradhan on 18/03/2017. - Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put. - - get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. - put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item. - - Follow up: - Could you do both operations in O(1) time complexity? - - Example: - - LRUCache cache = new LRUCache( 2 /* capacity */ /*); + * Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put. + *

+ * get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. + * put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item. + *

+ * Follow up: + * Could you do both operations in O(1) time complexity? + *

+ * Example: + *

+ * LRUCache cache = new LRUCache( 2 /* capacity + */ /*); cache.put(1, 1); cache.put(2, 2); @@ -30,15 +32,13 @@ Could you do both operations in O(1) time complexity? Show Similar Problems */ -public class LRUCache -{ - public static class DLinkList - { +public class LRUCache { + public static class DLinkList { int key, value; DLinkList left; DLinkList right; - DLinkList(int key, int value) - { + + DLinkList(int key, int value) { this.key = key; this.value = value; left = null; @@ -52,12 +52,11 @@ public static class DLinkList /** * Pop head node + * * @return */ - private DLinkList popHead() - { - if(!head.right.equals(tail)) - { + private DLinkList popHead() { + if (!head.right.equals(tail)) { DLinkList node = head.right; head.right = node.right; node.right.left = head; @@ -70,10 +69,10 @@ private DLinkList popHead() /** * Push to tail + * * @param node */ - private void offer(DLinkList node) - { + private void offer(DLinkList node) { tail.left.right = node; node.left = tail.left; node.right = tail; @@ -82,26 +81,27 @@ private void offer(DLinkList node) /** * Move node to tail + * * @param node */ - private void moveToTail(DLinkList node) - { + private void moveToTail(DLinkList node) { node.left.right = node.right; node.right.left = node.left; offer(node); } + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { LRUCache cache = new LRUCache(2); cache.put(1, 1); cache.put(2, 2); System.out.println(cache.get(1)); - cache.put(3,3); + cache.put(3, 3); System.out.println(cache.get(2)); cache.put(4, 4); System.out.println(cache.get(1)); @@ -109,8 +109,7 @@ public static void main(String[] args) throws Exception System.out.println(cache.get(4)); } - public LRUCache(int capacity) - { + public LRUCache(int capacity) { this.capacity = capacity; this.currentSize = 0; cache = new HashMap<>(); @@ -120,37 +119,28 @@ public LRUCache(int capacity) tail.left = head; } - public int get(int key) - { - if(cache.get(key) == null) return -1; + public int get(int key) { + if (cache.get(key) == null) return -1; DLinkList node = cache.get(key); moveToTail(node); return node.value; } - public void put(int key, int value) - { - if(cache.containsKey(key)) - { + public void put(int key, int value) { + if (cache.containsKey(key)) { DLinkList node = cache.get(key); node.value = value; moveToTail(node); - } - else - { - if(capacity == currentSize) - { + } else { + if (capacity == currentSize) { DLinkList head = popHead(); - if(head != null) - { + if (head != null) { cache.remove(head.key); DLinkList node = new DLinkList(key, value); offer(node); cache.put(key, node); } - } - else - { + } else { DLinkList node = new DLinkList(key, value); offer(node); cache.put(key, node); diff --git a/problems/src/design/RandomizedSet.java b/problems/src/design/RandomizedSet.java index f675c9b9..5e21d892 100644 --- a/problems/src/design/RandomizedSet.java +++ b/problems/src/design/RandomizedSet.java @@ -4,45 +4,46 @@ /** * Created by gouthamvidyapradhan on 23/03/2017. - Design a data structure that supports all following operations in average O(1) time. - - insert(val): Inserts an item val to the set if not already present. - remove(val): Removes an item val from the set if present. - getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned. - Example: - - // Init an empty set. - RandomizedSet randomSet = new RandomizedSet(); - - // Inserts 1 to the set. Returns true as 1 was inserted successfully. - randomSet.insert(1); - - // Returns false as 2 does not exist in the set. - randomSet.remove(2); - - // Inserts 2 to the set, returns true. Set now contains [1,2]. - randomSet.insert(2); - - // getRandom should return either 1 or 2 randomly. - randomSet.getRandom(); - - // Removes 1 from the set, returns true. Set now contains [2]. - randomSet.remove(1); - - // 2 was already in the set, so return false. - randomSet.insert(2); - - // Since 2 is the only number in the set, getRandom always return 2. - randomSet.getRandom(); + * Design a data structure that supports all following operations in average O(1) time. + *

+ * insert(val): Inserts an item val to the set if not already present. + * remove(val): Removes an item val from the set if present. + * getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned. + * Example: + *

+ * // Init an empty set. + * RandomizedSet randomSet = new RandomizedSet(); + *

+ * // Inserts 1 to the set. Returns true as 1 was inserted successfully. + * randomSet.insert(1); + *

+ * // Returns false as 2 does not exist in the set. + * randomSet.remove(2); + *

+ * // Inserts 2 to the set, returns true. Set now contains [1,2]. + * randomSet.insert(2); + *

+ * // getRandom should return either 1 or 2 randomly. + * randomSet.getRandom(); + *

+ * // Removes 1 from the set, returns true. Set now contains [2]. + * randomSet.remove(1); + *

+ * // 2 was already in the set, so return false. + * randomSet.insert(2); + *

+ * // Since 2 is the only number in the set, getRandom always return 2. + * randomSet.getRandom(); */ -public class RandomizedSet -{ +public class RandomizedSet { private Map map; private List list; private Random random; - /** Initialize your data structure here. */ - public RandomizedSet() - { + + /** + * Initialize your data structure here. + */ + public RandomizedSet() { map = new HashMap<>(); list = new ArrayList<>(); random = new Random(); @@ -50,11 +51,11 @@ public RandomizedSet() /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { RandomizedSet rSet = new RandomizedSet(); System.out.println(rSet.getRandom()); System.out.println(rSet.insert(1)); @@ -73,11 +74,11 @@ public static void main(String[] args) throws Exception System.out.println(rSet.getRandom()); } - /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ - public boolean insert(int val) - { - if(!map.keySet().contains(val)) - { + /** + * Inserts a value to the set. Returns true if the set did not already contain the specified element. + */ + public boolean insert(int val) { + if (!map.keySet().contains(val)) { int pos = list.size(); map.put(val, pos); list.add(val); @@ -86,15 +87,14 @@ public boolean insert(int val) return false; } - /** Removes a value from the set. Returns true if the set contained the specified element. */ - public boolean remove(int val) - { - if(map.containsKey(val)) - { + /** + * Removes a value from the set. Returns true if the set contained the specified element. + */ + public boolean remove(int val) { + if (map.containsKey(val)) { int size = list.size(); int posVal = map.get(val); - if(posVal < (size - 1)) - { + if (posVal < (size - 1)) { int last = list.get(size - 1); map.put(last, posVal); list.set(posVal, last); @@ -106,9 +106,10 @@ public boolean remove(int val) return false; } - /** Get a random element from the set. */ - public int getRandom() - { + /** + * Get a random element from the set. + */ + public int getRandom() { /*if(list.size() == 0) return 0; else if (list.size() == 1) return list.get(0);*/ return list.get(random.nextInt(list.size() - 1)); diff --git a/problems/src/design/SerializeDeserializeBinaryTree.java b/problems/src/design/SerializeDeserializeBinaryTree.java index c3251026..1517e6b0 100644 --- a/problems/src/design/SerializeDeserializeBinaryTree.java +++ b/problems/src/design/SerializeDeserializeBinaryTree.java @@ -4,39 +4,40 @@ /** * Created by gouthamvidyapradhan on 11/03/2017. - Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment. - - Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure. - - For example, you may serialize the following tree - - 1 - / \ - 2 3 - / \ - 4 5 - as "[1,2,3,null,null,4,5]", just the same as how LeetCode OJ serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself. - Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless. - + * Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment. + *

+ * Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure. + *

+ * For example, you may serialize the following tree + *

+ * 1 + * / \ + * 2 3 + * / \ + * 4 5 + * as "[1,2,3,null,null,4,5]", just the same as how LeetCode OJ serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself. + * Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless. */ -public class SerializeDeserializeBinaryTree -{ - public static class TreeNode - { +public class SerializeDeserializeBinaryTree { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private static final String NULL = "X"; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(1); TreeNode two = new TreeNode(2); TreeNode three = new TreeNode(3); @@ -63,25 +64,21 @@ public static void main(String[] args) throws Exception } // Encodes a tree to a single string. - public String serialize(TreeNode root) - { - if(root == null) return null; + public String serialize(TreeNode root) { + if (root == null) return null; List list = new ArrayList<>(); encode(root, list); StringBuilder sb = new StringBuilder(); sb.append(list.get(0)); - for(int i = 1, l = list.size(); i < l; i++) - { + for (int i = 1, l = list.size(); i < l; i++) { sb.append(",").append(list.get(i)); } return sb.toString(); } - private void encode(TreeNode root, List list) - { - if(root == null) list.add(NULL); - else - { + private void encode(TreeNode root, List list) { + if (root == null) list.add(NULL); + else { list.add(String.valueOf(root.val)); encode(root.left, list); encode(root.right, list); @@ -89,20 +86,18 @@ private void encode(TreeNode root, List list) } // Decodes your encoded data to tree. - public TreeNode deserialize(String data) - { - if(data == null || data.isEmpty()) return null; + public TreeNode deserialize(String data) { + if (data == null || data.isEmpty()) return null; StringTokenizer st = new StringTokenizer(data, ","); Queue queue = new ArrayDeque<>(); - while(st.hasMoreTokens()) + while (st.hasMoreTokens()) queue.offer(st.nextToken()); return decode(queue); } - private TreeNode decode(Queue queue) - { + private TreeNode decode(Queue queue) { String node = queue.poll(); - if(node.equals(NULL)) + if (node.equals(NULL)) return null; TreeNode root = new TreeNode(Integer.parseInt(node)); root.left = decode(queue); diff --git a/problems/src/design/TicTacToe.java b/problems/src/design/TicTacToe.java index 0eb7c2f8..aef7b8fe 100644 --- a/problems/src/design/TicTacToe.java +++ b/problems/src/design/TicTacToe.java @@ -2,70 +2,68 @@ /** * Created by gouthamvidyapradhan on 13/05/2017. - - 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. - Example: - 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| - - Follow up: - Could you do better than O(n2) per move() operation? - - Solution: The below solution works in O(1) time complexity. - 1. For each player move, keep track of count of selection for each row and each column. - 2. To keep track of counts in each diagonals we need to first know if the move is made on either one of the diagonals. - The move is made in either of the diagonals if and only if (row = col) AND/OR (col + row = N - 1) - 3. As soon as the count in any of column, row or diagonal reach N then return the current player as the winner, else return 0. + *

+ * 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. + * Example: + * 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| + *

+ * Follow up: + * Could you do better than O(n2) per move() operation? + *

+ * Solution: The below solution works in O(1) time complexity. + * 1. For each player move, keep track of count of selection for each row and each column. + * 2. To keep track of counts in each diagonals we need to first know if the move is made on either one of the diagonals. + * The move is made in either of the diagonals if and only if (row = col) AND/OR (col + row = N - 1) + * 3. As soon as the count in any of column, row or diagonal reach N then return the current player as the winner, else return 0. */ -public class TicTacToe -{ +public class TicTacToe { /** * Cell class to keep track of first player and second player row/column count */ - private class Cell - { + private class Cell { int player1 = 0, player2 = 0; } @@ -74,11 +72,11 @@ private class Cell /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TicTacToe toe = new TicTacToe(3); System.out.println(toe.move(0, 0, 1)); System.out.println(toe.move(0, 2, 2)); @@ -87,9 +85,10 @@ public static void main(String[] args) throws Exception System.out.println(toe.move(2, 0, 1)); } - /** Initialize your data structure here. */ - public TicTacToe(int n) - { + /** + * Initialize your data structure here. + */ + public TicTacToe(int n) { N = n; rows = new Cell[N]; columns = new Cell[N]; @@ -97,23 +96,22 @@ public TicTacToe(int n) /** * Move and check who wins. - * @param row row - * @param col col + * + * @param row row + * @param col col * @param player player * @return integer indicating the winner */ - public int move(int row, int col, int player) - { - switch (player) - { + public int move(int row, int col, int player) { + switch (player) { case 1: increment(rows, row, 1); increment(columns, col, 1); - if((col + row) == (N - 1)) - fPD2 ++; - if(row == col) - fPD1 ++; - if(rows[row].player1 == N + if ((col + row) == (N - 1)) + fPD2++; + if (row == col) + fPD1++; + if (rows[row].player1 == N || columns[col].player1 == N || fPD1 == N || fPD2 == N) return 1; break; @@ -121,11 +119,11 @@ public int move(int row, int col, int player) case 2: increment(rows, row, 2); increment(columns, col, 2); - if((col + row) == (N - 1)) - sPD2 ++; - if(row == col) - sPD1 ++; - if(rows[row].player2 == N + if ((col + row) == (N - 1)) + sPD2++; + if (row == col) + sPD1++; + if (rows[row].player2 == N || columns[col].player2 == N || sPD1 == N || sPD2 == N) return 2; break; @@ -135,17 +133,18 @@ public int move(int row, int col, int player) /** * Increment row / col count - * @param cells array of cells - * @param key row / col key + * + * @param cells array of cells + * @param key row / col key * @param player Player object */ private void increment(Cell[] cells, int key, int player) { Cell p = cells[key]; - if(p == null) { + if (p == null) { p = new Cell(); cells[key] = p; } - if(player == 1) + if (player == 1) p.player1++; else p.player2++; } diff --git a/problems/src/design/Trie.java b/problems/src/design/Trie.java index 3b6f8711..ff77639c 100644 --- a/problems/src/design/Trie.java +++ b/problems/src/design/Trie.java @@ -6,19 +6,21 @@ /** * Created by Goutham Vidya Pradhan on 7/3/2017. * Implement a trie with insert, search, and startsWith methods. - - Note: - You may assume that all inputs are consist of lowercase letters a-z. + *

+ * Note: + * You may assume that all inputs are consist of lowercase letters a-z. */ public class Trie { private Map map; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { Trie trie = new Trie(); trie.insert("boxing"); trie.insert("box"); @@ -27,67 +29,73 @@ public static void main(String[] args) throws Exception{ System.out.println(trie.search("box")); } - /** Initialize your data structure here. */ + /** + * Initialize your data structure here. + */ public Trie() { map = new HashMap<>(); } - /** Inserts a word into the trie. */ + /** + * Inserts a word into the trie. + */ public void insert(String word) { - if(word != null){ + if (word != null) { add(0, word, word.length()); } } - private void add(int i, String word, int length){ - if(i < length){ + private void add(int i, String word, int length) { + if (i < length) { char c = word.charAt(i); Trie subTrie = map.get(c); - if(subTrie == null){ + if (subTrie == null) { subTrie = new Trie(); map.put(c, subTrie); } subTrie.add(i + 1, word, length); - } - else map.put(null, new Trie()); //use null to indicate end of string + } else map.put(null, new Trie()); //use null to indicate end of string } - /** Returns if the word is in the trie. */ + /** + * Returns if the word is in the trie. + */ public boolean search(String word) { - if(word != null){ + if (word != null) { return search(0, word, word.length()); } return false; } - private boolean search(int i, String word, int length){ - if(i < length){ + private boolean search(int i, String word, int length) { + if (i < length) { char c = word.charAt(i); Trie subTrie = map.get(c); - if(subTrie == null) + if (subTrie == null) return false; return subTrie.search(i + 1, word, length); } return map.containsKey(null); } - /** Returns if there is any word in the trie that starts with the given prefix. */ + /** + * Returns if there is any word in the trie that starts with the given prefix. + */ public boolean startsWith(String prefix) { - if(prefix != null){ + if (prefix != null) { return startsWith(0, prefix, prefix.length()); } return false; } - private boolean startsWith(int i, String prefix, int length){ - if(i < length){ + private boolean startsWith(int i, String prefix, int length) { + if (i < length) { char c = prefix.charAt(i); Trie subTrie = map.get(c); - if(subTrie == null) + if (subTrie == null) return false; return subTrie.startsWith(i + 1, prefix, length); - } - else return true; + } else return true; } } diff --git a/problems/src/design/Twitter.java b/problems/src/design/Twitter.java index d56c3bc2..88095f88 100644 --- a/problems/src/design/Twitter.java +++ b/problems/src/design/Twitter.java @@ -4,64 +4,61 @@ /** * Created by gouthamvidyapradhan on 18/03/2017. - Design a simplified version of Twitter where users can post tweets, follow/unfollow another user and is able to see the 10 most recent tweets in the user's news feed. Your design should support the following methods: - - postTweet(userId, tweetId): Compose a new tweet. - getNewsFeed(userId): Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. - follow(followerId, followeeId): Follower follows a followee. - unfollow(followerId, followeeId): Follower unfollows a followee. - Example: - - Twitter twitter = new Twitter(); - - // User 1 posts a new tweet (id = 5). - twitter.postTweet(1, 5); - - // User 1's news feed should return a list with 1 tweet id -> [5]. - twitter.getNewsFeed(1); - - // User 1 follows user 2. - twitter.follow(1, 2); - - // User 2 posts a new tweet (id = 6). - twitter.postTweet(2, 6); - - // User 1's news feed should return a list with 2 tweet ids -> [6, 5]. - // Tweet id 6 should precede tweet id 5 because it is posted after tweet id 5. - twitter.getNewsFeed(1); - - // User 1 unfollows user 2. - twitter.unfollow(1, 2); - - // User 1's news feed should return a list with 1 tweet id -> [5], - // since user 1 is no longer following user 2. - twitter.getNewsFeed(1); + * Design a simplified version of Twitter where users can post tweets, follow/unfollow another user and is able to see the 10 most recent tweets in the user's news feed. Your design should support the following methods: + *

+ * postTweet(userId, tweetId): Compose a new tweet. + * getNewsFeed(userId): Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. + * follow(followerId, followeeId): Follower follows a followee. + * unfollow(followerId, followeeId): Follower unfollows a followee. + * Example: + *

+ * Twitter twitter = new Twitter(); + *

+ * // User 1 posts a new tweet (id = 5). + * twitter.postTweet(1, 5); + *

+ * // User 1's news feed should return a list with 1 tweet id -> [5]. + * twitter.getNewsFeed(1); + *

+ * // User 1 follows user 2. + * twitter.follow(1, 2); + *

+ * // User 2 posts a new tweet (id = 6). + * twitter.postTweet(2, 6); + *

+ * // User 1's news feed should return a list with 2 tweet ids -> [6, 5]. + * // Tweet id 6 should precede tweet id 5 because it is posted after tweet id 5. + * twitter.getNewsFeed(1); + *

+ * // User 1 unfollows user 2. + * twitter.unfollow(1, 2); + *

+ * // User 1's news feed should return a list with 1 tweet id -> [5], + * // since user 1 is no longer following user 2. + * twitter.getNewsFeed(1); */ -public class Twitter -{ - class User - { +public class Twitter { + class User { int id; Set follow = new HashSet<>(); Queue tweets = new ArrayDeque<>(); - User(int id) - { + + User(int id) { this.id = id; } - public void follow(int id) - { + + public void follow(int id) { follow.add(id); } - public void addTweet(Tweet t) - { - if(tweets.size() == 10) - { + + public void addTweet(Tweet t) { + if (tweets.size() == 10) { tweets.poll(); } tweets.offer(t); } - public void unFollow(int id) - { + + public void unFollow(int id) { follow.remove(id); } @@ -74,12 +71,11 @@ public Queue getTweets() { } } - class Tweet - { + class Tweet { int id; long time; - Tweet(int id, long time) - { + + Tweet(int id, long time) { this.id = id; this.time = time; } @@ -88,13 +84,14 @@ class Tweet private Map userMap; private Map tweetMap; private static long tweetCount = 0L; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { Twitter twitter = new Twitter(); twitter.postTweet(1, 5); twitter.follow(1, 1); @@ -114,41 +111,40 @@ public static void main(String[] args) throws Exception */ } - /** Initialize your data structure here. */ - public Twitter() - { + /** + * Initialize your data structure here. + */ + public Twitter() { userMap = new HashMap<>(); tweetMap = new HashMap<>(); } - /** Compose a new tweet. */ - public void postTweet(int userId, int tweetId) - { + /** + * Compose a new tweet. + */ + public void postTweet(int userId, int tweetId) { User user = userMap.get(userId); - if(user == null) - { + if (user == null) { user = new User(userId); userMap.put(userId, user); } user.addTweet(new Tweet(tweetId, tweetCount++)); } - /** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */ - public List getNewsFeed(int userId) - { + /** + * Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. + */ + public List getNewsFeed(int userId) { User user = userMap.get(userId); List result = new ArrayList<>(); - if(user == null) return result; + if (user == null) return result; Set follwers = user.getFollow(); - if(follwers != null) - { + if (follwers != null) { List tweets = new ArrayList<>(); tweets.addAll(user.getTweets()); - for(Integer i : follwers) - { + for (Integer i : follwers) { User f = userMap.get(i); - if(f != null) - { + if (f != null) { tweets.addAll(f.getTweets()); } } @@ -161,9 +157,8 @@ public int compare(Tweet o1, Tweet o2) { Collections.sort(tweets, comparator); - for(int i = 0; i < 10; i ++) - { - if(i >= tweets.size()) + for (int i = 0; i < 10; i++) { + if (i >= tweets.size()) break; result.add(tweets.get(i).id); } @@ -171,32 +166,30 @@ public int compare(Tweet o1, Tweet o2) { 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(followerId == followeeId) return; + /** + * Follower follows a followee. If the operation is invalid, it should be a no-op. + */ + public void follow(int followerId, int followeeId) { + if (followerId == followeeId) return; User user = userMap.get(followerId); - if(user == null) + if (user == null) user = new User(followerId); userMap.put(followerId, user); - if(userMap.get(followeeId) != null) - { + if (userMap.get(followeeId) != null) { user.follow(userMap.get(followeeId).id); - } - else - { + } else { User newUser = new User(followeeId); userMap.put(followeeId, newUser); user.follow(userMap.get(followeeId).id); } } - /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ - public void unfollow(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) { User user = userMap.get(followerId); - if(user != null) - { + if (user != null) { user.unFollow(followeeId); } } diff --git a/problems/src/divide_and_conquer/KthLargestElementInAnArray.java b/problems/src/divide_and_conquer/KthLargestElementInAnArray.java index 7d2b44db..4d4d4249 100644 --- a/problems/src/divide_and_conquer/KthLargestElementInAnArray.java +++ b/problems/src/divide_and_conquer/KthLargestElementInAnArray.java @@ -2,42 +2,37 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element. - - For example, - Given [3,2,1,5,6,4] and k = 2, return 5. - - Note: - You may assume k is always valid, 1 ≤ k ≤ array's length. + * Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element. + *

+ * For example, + * Given [3,2,1,5,6,4] and k = 2, return 5. + *

+ * Note: + * You may assume k is always valid, 1 ≤ k ≤ array's length. */ -public class KthLargestElementInAnArray -{ +public class KthLargestElementInAnArray { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] nums = {3,2,1,5,6,4}; + public static void main(String[] args) throws Exception { + int[] nums = {3, 2, 1, 5, 6, 4}; System.out.println(new KthLargestElementInAnArray().findKthLargest(nums, 6)); } - private int findKthLargest(int[] nums, int k) - { + private int findKthLargest(int[] nums, int k) { return solve(nums, 0, nums.length - 1, k); } - private int solve(int[] nums, int pIndex, int end, int k) - { + private int solve(int[] nums, int pIndex, int end, int k) { int pivot = nums[end]; int temp; int start = pIndex; - for(int i = pIndex; i < end; i ++) - { - if(nums[i] <= pivot) - { + for (int i = pIndex; i < end; i++) { + if (nums[i] <= pivot) { temp = nums[i]; nums[i] = nums[pIndex]; nums[pIndex] = temp; @@ -49,13 +44,10 @@ private int solve(int[] nums, int pIndex, int end, int k) nums[end] = temp; int pos = (end - pIndex) + 1; - if(pos == k) return nums[pIndex]; - else if(pos > k) - { + if (pos == k) return nums[pIndex]; + else if (pos > k) { return solve(nums, pIndex + 1, end, k); - } - else - { + } else { return solve(nums, start, pIndex - 1, k - pos); } } diff --git a/problems/src/divide_and_conquer/SearchA2DMatrix.java b/problems/src/divide_and_conquer/SearchA2DMatrix.java index fb533803..c876b612 100644 --- a/problems/src/divide_and_conquer/SearchA2DMatrix.java +++ b/problems/src/divide_and_conquer/SearchA2DMatrix.java @@ -2,57 +2,54 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: - - Integers in each row are sorted in ascending from left to right. - Integers in each column are sorted in ascending from top to bottom. - For example, - - Consider the following matrix: - - [ - [1, 4, 7, 11, 15], - [2, 5, 8, 12, 19], - [3, 6, 9, 16, 22], - [10, 13, 14, 17, 24], - [18, 21, 23, 26, 30] - ] - Given target = 5, return true. - - Given target = 20, return false. + * Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: + *

+ * Integers in each row are sorted in ascending from left to right. + * Integers in each column are sorted in ascending from top to bottom. + * For example, + *

+ * Consider the following matrix: + *

+ * [ + * [1, 4, 7, 11, 15], + * [2, 5, 8, 12, 19], + * [3, 6, 9, 16, 22], + * [10, 13, 14, 17, 24], + * [18, 21, 23, 26, 30] + * ] + * Given target = 5, return true. + *

+ * Given target = 20, return false. */ -public class SearchA2DMatrix -{ +public class SearchA2DMatrix { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[][] matrix = { - {1,3,5,7,9} , //1, 3, 5, 7, 9 - {2,4,6,8,10}, //2, 4, 6, 8, 10 - {11,13,15,17,19}, //11, 15, 17, 18, 19 - {12,14,16,18,20}, //13, 20, 21, 22, 23 - {21,22,23,24,25} //14, 25, 26, 27, 28 + {1, 3, 5, 7, 9}, //1, 3, 5, 7, 9 + {2, 4, 6, 8, 10}, //2, 4, 6, 8, 10 + {11, 13, 15, 17, 19}, //11, 15, 17, 18, 19 + {12, 14, 16, 18, 20}, //13, 20, 21, 22, 23 + {21, 22, 23, 24, 25} //14, 25, 26, 27, 28 }; System.out.println(new SearchA2DMatrix().searchMatrix(matrix, 11)); } - private boolean searchMatrix(int[][] matrix, int target) - { - if(matrix.length == 0) return false; + private boolean searchMatrix(int[][] matrix, int target) { + if (matrix.length == 0) return false; int M = matrix.length; int N = matrix[0].length; int r = 0, c = N - 1; - while(r < M && c >= 0) - { - if(matrix[r][c] == target) return true; - else if(target < matrix[r][c]) --c; - else if(target > matrix[r][c]) r++; + while (r < M && c >= 0) { + if (matrix[r][c] == target) return true; + else if (target < matrix[r][c]) --c; + else if (target > matrix[r][c]) r++; } return false; } diff --git a/problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java b/problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java index 1d312863..54417f9f 100644 --- a/problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java +++ b/problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java @@ -2,46 +2,42 @@ /** * Created by gouthamvidyapradhan on 17/03/2017. - Say you have an array for which the ith element is the price of a given stock on day i. - - If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit. - - Example 1: - Input: [7, 1, 5, 3, 6, 4] - Output: 5 - - max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price) - Example 2: - Input: [7, 6, 4, 3, 1] - Output: 0 - - In this case, no transaction is done, i.e. max profit = 0. + * Say you have an array for which the ith element is the price of a given stock on day i. + *

+ * If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit. + *

+ * Example 1: + * Input: [7, 1, 5, 3, 6, 4] + * Output: 5 + *

+ * max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price) + * Example 2: + * Input: [7, 6, 4, 3, 1] + * Output: 0 + *

+ * In this case, no transaction is done, i.e. max profit = 0. */ -public class BestTimeToBuyAndSellStocks -{ +public class BestTimeToBuyAndSellStocks { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] prices = {1, 1, 1, 1, 1}; System.out.println(new BestTimeToBuyAndSellStocks().maxProfit(prices)); } - public int maxProfit(int[] prices) - { - if(prices.length == 0) return 0; + public int maxProfit(int[] prices) { + if (prices.length == 0) return 0; int[] max = new int[prices.length]; max[prices.length - 1] = prices[prices.length - 1]; - for(int i = prices.length - 2; i >= 0; i --) - { + for (int i = prices.length - 2; i >= 0; i--) { max[i] = Math.max(prices[i], max[i + 1]); } int result = Integer.MIN_VALUE; - for(int i = 0, l = max.length; i < l; i ++) - { + for (int i = 0, l = max.length; i < l; i++) { result = Math.max(result, max[i] - prices[i]); } return result; diff --git a/problems/src/dynamic_programming/CanIWin.java b/problems/src/dynamic_programming/CanIWin.java index 3042da02..acd26de4 100644 --- a/problems/src/dynamic_programming/CanIWin.java +++ b/problems/src/dynamic_programming/CanIWin.java @@ -6,65 +6,67 @@ /** * Created by gouthamvidyapradhan on 04/07/2017. * In the "100 game," two players take turns adding, to a running total, any integer from 1..10. The player who first causes the running total to reach or exceed 100 wins. - - What if we change the game so that players cannot re-use integers? - - For example, two players might take turns drawing from a common pool of numbers of 1..15 without replacement until they reach a total >= 100. - - Given an integer maxChoosableInteger and another integer desiredTotal, determine if the first player to move can force a win, assuming both players play optimally. - - You can always assume that maxChoosableInteger will not be larger than 20 and desiredTotal will not be larger than 300. - - Example - - Input: - maxChoosableInteger = 10 - desiredTotal = 11 - - Output: - false - - Explanation: - No matter which integer the first player choose, the first player will lose. - The first player can choose an integer from 1 up to 10. - If the first player choose 1, the second player can only choose integers from 2 up to 10. - The second player will win by choosing 10 and get a total = 11, which is >= desiredTotal. - Same with other integers chosen by the first player, the second player will always win. + *

+ * What if we change the game so that players cannot re-use integers? + *

+ * For example, two players might take turns drawing from a common pool of numbers of 1..15 without replacement until they reach a total >= 100. + *

+ * Given an integer maxChoosableInteger and another integer desiredTotal, determine if the first player to move can force a win, assuming both players play optimally. + *

+ * You can always assume that maxChoosableInteger will not be larger than 20 and desiredTotal will not be larger than 300. + *

+ * Example + *

+ * Input: + * maxChoosableInteger = 10 + * desiredTotal = 11 + *

+ * Output: + * false + *

+ * Explanation: + * No matter which integer the first player choose, the first player will lose. + * The first player can choose an integer from 1 up to 10. + * If the first player choose 1, the second player can only choose integers from 2 up to 10. + * The second player will win by choosing 10 and get a total = 11, which is >= desiredTotal. + * Same with other integers chosen by the first player, the second player will always win. */ public class CanIWin { private Map> DP; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new CanIWin().canIWin(5, 15)); } public boolean canIWin(int maxChoosableInteger, int desiredTotal) { int sum = 0; - for(int i = 1; i <= maxChoosableInteger; i ++) + for (int i = 1; i <= maxChoosableInteger; i++) sum += i; - if(desiredTotal == 0) return true; - else if(desiredTotal > sum) return false; //if the desiredTotal exceeds the max possible sum return false; + if (desiredTotal == 0) return true; + else if (desiredTotal > sum) return false; //if the desiredTotal exceeds the max possible sum return false; DP = new HashMap<>(); DP.put(true, new HashMap<>()); DP.put(false, new HashMap<>()); return dp(0, maxChoosableInteger, desiredTotal, true, 0); } - private boolean dp(int state, int M, int D, boolean P, int sum){ - if(sum >= D) return false; + private boolean dp(int state, int M, int D, boolean P, int sum) { + if (sum >= D) return false; Map map = DP.get(P); - if(map.containsKey(state)) + if (map.containsKey(state)) return map.get(state); else { map.put(state, false); - for(int i = 0; i < M; i ++){ - if((state & (1 << i)) == 0){ - if(!dp(state | (1 << i), M, D, !P, sum + i + 1)){ + for (int i = 0; i < M; i++) { + if ((state & (1 << i)) == 0) { + if (!dp(state | (1 << i), M, D, !P, sum + i + 1)) { map.put(state, true); break; } diff --git a/problems/src/dynamic_programming/ClimbingStairs.java b/problems/src/dynamic_programming/ClimbingStairs.java index d886fd3c..a5f1cd34 100644 --- a/problems/src/dynamic_programming/ClimbingStairs.java +++ b/problems/src/dynamic_programming/ClimbingStairs.java @@ -2,32 +2,30 @@ /** * Created by gouthamvidyapradhan on 01/04/2017. - You are climbing a stair case. It takes n steps to reach to the top. - - Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? - - Note: Given n will be a positive integer. + * You are climbing a stair case. It takes n steps to reach to the top. + *

+ * Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? + *

+ * Note: Given n will be a positive integer. */ -public class ClimbingStairs -{ +public class ClimbingStairs { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { } - public int climbStairs(int n) - { - if(n == 0 || n == 1) return 1; + public int climbStairs(int n) { + if (n == 0 || n == 1) return 1; int[] A = new int[n + 1]; A[n] = 1; A[n - 1] = 1; - for(int i = n - 2; i >= 0; i --) - A[i] = A[i + 1] + A[i + 2]; + for (int i = n - 2; i >= 0; i--) + A[i] = A[i + 1] + A[i + 2]; return A[0]; } diff --git a/problems/src/dynamic_programming/CoinChange.java b/problems/src/dynamic_programming/CoinChange.java index b9a1bf3f..b6e1445b 100644 --- a/problems/src/dynamic_programming/CoinChange.java +++ b/problems/src/dynamic_programming/CoinChange.java @@ -5,43 +5,43 @@ * You are given coins of different denominations and a total amount of money amount. * Write a function to compute the fewest number of coins that you need to make up that amount. * If that amount of money cannot be made up by any combination of the coins, return -1. - - Example 1: - coins = [1, 2, 5], amount = 11 - return 3 (11 = 5 + 5 + 1) - - Example 2: - coins = [2], amount = 3 - return -1. - - Note: - You may assume that you have an infinite number of each kind of coin. - - Solution: - For example if you have N coins and amount equal to Q - For every coin you have two options - i) If you chose to include this coin then, total amount reduces by the sum equivalent to the value of this coin and you are - left with N coins and Q = (Q - value of this coin) - ii) If you chose not to include this coin then, you are left with N - 1 coins (since you chose to not to include this coin) - and total amount is still equal to Q - - Calculate recursively for each coin and possible amount - Since there can be overlapping sub-problems you can save the state in a 2D matrix - a typical DP approach. - - For each state minimum is calculated using -> Min(1 + fn(i, amount - v[i]), fn(i + 1, amount)) - - Worst-case time complexity is O(N x Q) where N is the total number of coins and Q is the total amount - + *

+ * Example 1: + * coins = [1, 2, 5], amount = 11 + * return 3 (11 = 5 + 5 + 1) + *

+ * Example 2: + * coins = [2], amount = 3 + * return -1. + *

+ * Note: + * You may assume that you have an infinite number of each kind of coin. + *

+ * Solution: + * For example if you have N coins and amount equal to Q + * For every coin you have two options + * i) If you chose to include this coin then, total amount reduces by the sum equivalent to the value of this coin and you are + * left with N coins and Q = (Q - value of this coin) + * ii) If you chose not to include this coin then, you are left with N - 1 coins (since you chose to not to include this coin) + * and total amount is still equal to Q + *

+ * Calculate recursively for each coin and possible amount + * Since there can be overlapping sub-problems you can save the state in a 2D matrix - a typical DP approach. + *

+ * For each state minimum is calculated using -> Min(1 + fn(i, amount - v[i]), fn(i + 1, amount)) + *

+ * Worst-case time complexity is O(N x Q) where N is the total number of coins and Q is the total amount */ -public class CoinChange -{ +public class CoinChange { private int[][] DP; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[] coins = {1, 2, 5}; System.out.println(new CoinChange().coinChange(coins, 11)); } @@ -49,14 +49,14 @@ public static void main(String[] args) throws Exception{ public int coinChange(int[] coins, int amount) { DP = new int[coins.length][amount + 1]; int result = dp(amount, 0, coins); - if(result == Integer.MAX_VALUE - 1) return -1; + if (result == Integer.MAX_VALUE - 1) return -1; return result; } - private int dp(int amount, int i, int[] coins){ - if(amount == 0) return 0; - else if(i >= coins.length || amount < 0) return Integer.MAX_VALUE - 1; - if(DP[i][amount] != 0) return DP[i][amount]; + private int dp(int amount, int i, int[] coins) { + if (amount == 0) return 0; + else if (i >= coins.length || amount < 0) return Integer.MAX_VALUE - 1; + if (DP[i][amount] != 0) return DP[i][amount]; DP[i][amount] = Math.min(1 + dp(amount - coins[i], i, coins), dp(amount, i + 1, coins)); return DP[i][amount]; } diff --git a/problems/src/dynamic_programming/CoinChange2.java b/problems/src/dynamic_programming/CoinChange2.java index 275e02a5..2f072002 100644 --- a/problems/src/dynamic_programming/CoinChange2.java +++ b/problems/src/dynamic_programming/CoinChange2.java @@ -4,60 +4,57 @@ /** * Created by gouthamvidyapradhan on 22/03/2017. - You are given coins of different denominations and a total amount of money. Write a function to compute the number of combinations that make up that amount. You may assume that you have infinite number of each kind of coin. - - Note: You can assume that - - 0 <= amount <= 5000 - 1 <= coin <= 5000 - the number of coins is less than 500 - the answer is guaranteed to fit into signed 32-bit integer - Example 1: - - Input: amount = 5, coins = [1, 2, 5] - Output: 4 - Explanation: there are four ways to make up the amount: - 5=5 - 5=2+2+1 - 5=2+1+1+1 - 5=1+1+1+1+1 - Example 2: - - Input: amount = 3, coins = [2] - Output: 0 - Explanation: the amount of 3 cannot be made up just with coins of 2. - Example 3: - - Input: amount = 10, coins = [10] - Output: 1 + * You are given coins of different denominations and a total amount of money. Write a function to compute the number of combinations that make up that amount. You may assume that you have infinite number of each kind of coin. + *

+ * Note: You can assume that + *

+ * 0 <= amount <= 5000 + * 1 <= coin <= 5000 + * the number of coins is less than 500 + * the answer is guaranteed to fit into signed 32-bit integer + * Example 1: + *

+ * Input: amount = 5, coins = [1, 2, 5] + * Output: 4 + * Explanation: there are four ways to make up the amount: + * 5=5 + * 5=2+2+1 + * 5=2+1+1+1 + * 5=1+1+1+1+1 + * Example 2: + *

+ * Input: amount = 3, coins = [2] + * Output: 0 + * Explanation: the amount of 3 cannot be made up just with coins of 2. + * Example 3: + *

+ * Input: amount = 10, coins = [10] + * Output: 1 */ -public class CoinChange2 -{ +public class CoinChange2 { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] coins = {1,2,5}; + public static void main(String[] args) throws Exception { + int[] coins = {1, 2, 5}; System.out.println(new CoinChange2().change(5, coins)); } - public int change(int amount, int[] coins) - { + public int change(int amount, int[] coins) { int[][] dp = new int[coins.length][amount + 1]; - for(int i = 0, l = coins.length; i < l; i ++) + for (int i = 0, l = coins.length; i < l; i++) Arrays.fill(dp[i], -1); return dp(dp, 0, coins, coins.length, amount); } - private int dp(int[][] dp, int i, int[] coins, int l, int n) - { - if(n == 0) return 1; - else if(i >= l) return 0; - if(n < 0) return 0; - if(dp[i][n] != -1) return dp[i][n]; + private int dp(int[][] dp, int i, int[] coins, int l, int n) { + if (n == 0) return 1; + else if (i >= l) return 0; + if (n < 0) return 0; + if (dp[i][n] != -1) return dp[i][n]; dp[i][n] = dp(dp, i + 1, coins, l, n) + dp(dp, i, coins, l, n - coins[i]); return dp[i][n]; } diff --git a/problems/src/dynamic_programming/ConcatenatedWords.java b/problems/src/dynamic_programming/ConcatenatedWords.java index 12a25a8a..dc4254ac 100644 --- a/problems/src/dynamic_programming/ConcatenatedWords.java +++ b/problems/src/dynamic_programming/ConcatenatedWords.java @@ -8,56 +8,51 @@ /** * Created by gouthamvidyapradhan on 12/06/2017. * Accepted - Given a list of words (without duplicates), please write a program that returns all concatenated words in the given list of words. - - A concatenated word is defined as a string that is comprised entirely of at least two shorter words in the given array. - - Example: - Input: ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"] - - Output: ["catsdogcats","dogcatsdog","ratcatdogcat"] - - Explanation: "catsdogcats" can be concatenated by "cats", "dog" and "cats"; - "dogcatsdog" can be concatenated by "dog", "cats" and "dog"; - "ratcatdogcat" can be concatenated by "rat", "cat", "dog" and "cat". - - Note: - The number of elements of the given array will not exceed 10,000 - The length sum of elements in the given array will not exceed 600,000. - All the input string will only include lower case letters. - The returned elements order does not matter. - - + * Given a list of words (without duplicates), please write a program that returns all concatenated words in the given list of words. + *

+ * A concatenated word is defined as a string that is comprised entirely of at least two shorter words in the given array. + *

+ * Example: + * Input: ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"] + *

+ * Output: ["catsdogcats","dogcatsdog","ratcatdogcat"] + *

+ * Explanation: "catsdogcats" can be concatenated by "cats", "dog" and "cats"; + * "dogcatsdog" can be concatenated by "dog", "cats" and "dog"; + * "ratcatdogcat" can be concatenated by "rat", "cat", "dog" and "cat". + *

+ * Note: + * The number of elements of the given array will not exceed 10,000 + * The length sum of elements in the given array will not exceed 600,000. + * All the input string will only include lower case letters. + * The returned elements order does not matter. */ -public class ConcatenatedWords -{ - public static void main(String[] args) throws Exception - { +public class ConcatenatedWords { + public static void main(String[] args) throws Exception { String[] words = {""}; System.out.println(new ConcatenatedWords().findAllConcatenatedWordsInADict(words)); } public List findAllConcatenatedWordsInADict(String[] words) { Set dictionary = new HashSet<>(); - for(String w : words) - dictionary.add(w); + for (String w : words) + dictionary.add(w); List result = new ArrayList<>(); - for(String w : words) { - if(!w.isEmpty() && concatenatedWordsPossible(w, dictionary)) + for (String w : words) { + if (!w.isEmpty() && concatenatedWordsPossible(w, dictionary)) result.add(w); } return result; } - private boolean concatenatedWordsPossible(String word, Set dictionary) - { + private boolean concatenatedWordsPossible(String word, Set dictionary) { boolean[] D = new boolean[word.length() + 1]; D[word.length()] = true; dictionary.remove(word); //remove current word from dictionary temporarily - for(int i = word.length() - 1; i >= 0; i --) { - for(int j = i, l = word.length(); j < l; j ++) { + for (int i = word.length() - 1; i >= 0; i--) { + for (int j = i, l = word.length(); j < l; j++) { String subStr = word.substring(i, j + 1); - if(dictionary.contains(subStr) && D[j + 1]) { + if (dictionary.contains(subStr) && D[j + 1]) { D[i] = true; break; } diff --git a/problems/src/dynamic_programming/DecodeWays.java b/problems/src/dynamic_programming/DecodeWays.java index 95dffb39..f554179f 100644 --- a/problems/src/dynamic_programming/DecodeWays.java +++ b/problems/src/dynamic_programming/DecodeWays.java @@ -2,49 +2,42 @@ /** * Created by gouthamvidyapradhan on 01/04/2017. - A message containing letters from A-Z is being encoded to numbers using the following mapping: - - 'A' -> 1 - 'B' -> 2 - ... - 'Z' -> 26 - Given an encoded message containing digits, determine the total number of ways to decode it. - - For example, - Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12). - - The number of ways decoding "12" is 2. + * A message containing letters from A-Z is being encoded to numbers using the following mapping: + *

+ * 'A' -> 1 + * 'B' -> 2 + * ... + * 'Z' -> 26 + * Given an encoded message containing digits, determine the total number of ways to decode it. + *

+ * For example, + * Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12). + *

+ * The number of ways decoding "12" is 2. */ -public class DecodeWays -{ +public class DecodeWays { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new DecodeWays().numDecodings("3120")); } - public int numDecodings(String s) - { - if(s == null || s.isEmpty()) return 0; + public int numDecodings(String s) { + if (s == null || s.isEmpty()) return 0; int[] dp = new int[s.length() + 2]; dp[s.length()] = 1; dp[s.length() + 1] = 1; - for(int i = s.length() - 1; i >= 0; i --) - { - for(int j = i + 1; j < i + 3; j ++) - { - if(j <= s.length()) - { + for (int i = s.length() - 1; i >= 0; i--) { + for (int j = i + 1; j < i + 3; j++) { + if (j <= s.length()) { String subStr = s.substring(i, j); - if(!subStr.startsWith("0")) - { + if (!subStr.startsWith("0")) { int intVal = Integer.parseInt(subStr); - if(intVal <= 26) - { + if (intVal <= 26) { dp[i] += dp[j]; } } diff --git a/problems/src/dynamic_programming/DungeonGame.java b/problems/src/dynamic_programming/DungeonGame.java index f58ba285..03111f51 100644 --- a/problems/src/dynamic_programming/DungeonGame.java +++ b/problems/src/dynamic_programming/DungeonGame.java @@ -6,36 +6,37 @@ * Created by gouthamvidyapradhan on 12/07/2017. * 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. - - Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon entering these rooms; other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers). - - In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step. - - - Write a function to determine the knight's minimum initial health so that he is able to rescue the princess. - - For example, given the dungeon below, the initial health of the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN. - - -2 (K) -3 3 - -5 -10 1 - 10 30 -5 (P) - - Notes: - - The knight's health has no upper bound. - Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned. - - Solution: O(MxN log Integer.MAX_VALUE) - Binary search the suitable initial health value in the range (1, Integer.MAX_VALUE) and do a top down DP to check the - balance health when he reaches 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. + *

+ * Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon entering these rooms; other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers). + *

+ * In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step. + *

+ *

+ * Write a function to determine the knight's minimum initial health so that he is able to rescue the princess. + *

+ * For example, given the dungeon below, the initial health of the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN. + *

+ * -2 (K) -3 3 + * -5 -10 1 + * 10 30 -5 (P) + *

+ * Notes: + *

+ * The knight's health has no upper bound. + * Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned. + *

+ * Solution: O(MxN log Integer.MAX_VALUE) + * Binary search the suitable initial health value in the range (1, Integer.MAX_VALUE) and do a top down DP to check the + * balance health when he reaches princess. */ public class DungeonGame { private final int[] R = {0, -1}; private final int[] C = {-1, 0}; private int DP[][]; - public static void main(String[] args) throws Exception{ + + public static void main(String[] args) throws Exception { int[][] dungeon = {{200}}; System.out.println(new DungeonGame().calculateMinimumHP(dungeon)); } @@ -43,30 +44,30 @@ public static void main(String[] args) throws Exception{ public int calculateMinimumHP(int[][] dungeon) { DP = new int[dungeon.length][dungeon[0].length]; int l = 0, h = Integer.MAX_VALUE, ans = 0; - while(l <= h){ + while (l <= h) { int m = l + (h - l) / 2; - for(int i = 0; i < dungeon.length; i ++) + for (int i = 0; i < dungeon.length; i++) Arrays.fill(DP[i], Integer.MIN_VALUE); DP[0][0] = m + dungeon[0][0]; - if(dp(dungeon, dungeon.length - 1, dungeon[0].length - 1) > 0){ + if (dp(dungeon, dungeon.length - 1, dungeon[0].length - 1) > 0) { ans = m; h = m - 1; - }else{ + } else { l = m + 1; } } return ans == 0 ? 1 : ans; } - private int dp(int[][] dungeon, int r, int c){ - if(DP[r][c] != Integer.MIN_VALUE) + private int dp(int[][] dungeon, int r, int c) { + if (DP[r][c] != Integer.MIN_VALUE) return DP[r][c]; - for(int i = 0; i < 2; i ++){ + for (int i = 0; i < 2; i++) { int newR = r + R[i]; int newC = c + C[i]; - if(newR >= 0 && newR < dungeon.length && newC >=0 && newC < dungeon[0].length){ + if (newR >= 0 && newR < dungeon.length && newC >= 0 && newC < dungeon[0].length) { int life = dp(dungeon, newR, newC); - if(life <= 0) + if (life <= 0) DP[r][c] = Math.max(DP[r][c], 0); else DP[r][c] = Math.max(DP[r][c], dungeon[r][c] + life); } diff --git a/problems/src/dynamic_programming/HouseRobber.java b/problems/src/dynamic_programming/HouseRobber.java index aa4ccfdd..14678335 100644 --- a/problems/src/dynamic_programming/HouseRobber.java +++ b/problems/src/dynamic_programming/HouseRobber.java @@ -2,32 +2,30 @@ /** * Created by pradhang on 4/3/2017. - You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night. - - Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. + * You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night. + *

+ * Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. */ -public class HouseRobber -{ +public class HouseRobber { private int[] max; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { } - public int rob(int[] nums) - { - if(nums.length == 0) return 0; + public int rob(int[] nums) { + if (nums.length == 0) return 0; max = new int[nums.length]; - if(nums.length == 1) return nums[0]; + if (nums.length == 1) return nums[0]; max[nums.length - 1] = nums[nums.length - 1]; max[nums.length - 2] = Math.max(nums[nums.length - 1], nums[nums.length - 2]); - for(int i = nums.length - 3; i >= 0; i --) - { + for (int i = nums.length - 3; i >= 0; i--) { max[i] = Math.max(max[i + 1], nums[i] + max[i + 2]); } return max[0]; diff --git a/problems/src/dynamic_programming/HouseRobberII.java b/problems/src/dynamic_programming/HouseRobberII.java index f3554c76..ed118091 100644 --- a/problems/src/dynamic_programming/HouseRobberII.java +++ b/problems/src/dynamic_programming/HouseRobberII.java @@ -6,39 +6,38 @@ * Created by pradhang on 7/11/2017. * After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. * This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street. - - Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. + *

+ * Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. */ public class HouseRobberII { - public static void main(String[] args) throws Exception{ - int[] nums = {6,3,10,8,2,10,3,5,10,5,3}; + public static void main(String[] args) throws Exception { + int[] nums = {6, 3, 10, 8, 2, 10, 3, 5, 10, 5, 3}; System.out.println(new HouseRobberII().rob(nums)); } public int rob(int[] nums) { - if(nums.length == 0) return 0; - if(nums.length == 1) + if (nums.length == 0) return 0; + if (nums.length == 1) return nums[0]; - else if(nums.length == 2){ - if(nums[0] > nums[1]) + else if (nums.length == 2) { + if (nums[0] > nums[1]) return nums[0]; return nums[1]; - } - else if(nums.length == 3) return Math.max(Math.max(nums[0], nums[1]), nums[2]); + } else if (nums.length == 3) return Math.max(Math.max(nums[0], nums[1]), nums[2]); int[] DP = new int[nums.length]; - for(int i = nums.length - 1; i > 0; i --){ - if(i + 3 < nums.length) + for (int i = nums.length - 1; i > 0; i--) { + if (i + 3 < nums.length) DP[i] = Math.max(nums[i] + DP[i + 2], nums[i] + DP[i + 3]); - else if(i + 2 < nums.length) + else if (i + 2 < nums.length) DP[i] = nums[i] + DP[i + 2]; else DP[i] = nums[i]; } int max = Math.max(DP[1], DP[2]); Arrays.fill(DP, 0); //reset - for(int i = nums.length - 2; i >= 0; i --){ - if(i + 3 < nums.length) + for (int i = nums.length - 2; i >= 0; i--) { + if (i + 3 < nums.length) DP[i] = Math.max(nums[i] + DP[i + 2], nums[i] + DP[i + 3]); - else if(i + 2 < nums.length) + else if (i + 2 < nums.length) DP[i] = nums[i] + DP[i + 2]; else DP[i] = nums[i]; } diff --git a/problems/src/dynamic_programming/LongestIncreasingSubsequence.java b/problems/src/dynamic_programming/LongestIncreasingSubsequence.java index 4a1bf4aa..db119e0d 100644 --- a/problems/src/dynamic_programming/LongestIncreasingSubsequence.java +++ b/problems/src/dynamic_programming/LongestIncreasingSubsequence.java @@ -2,40 +2,36 @@ /** * Created by gouthamvidyapradhan on 02/04/2017. - Given an unsorted array of integers, find the length of longest increasing subsequence. - - For example, - Given [10, 9, 2, 5, 3, 7, 101, 18], - The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length. - - Your algorithm should run in O(n2) complexity. - - Follow up: Could you improve it to O(n log n) time complexity? + * Given an unsorted array of integers, find the length of longest increasing subsequence. + *

+ * For example, + * Given [10, 9, 2, 5, 3, 7, 101, 18], + * The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length. + *

+ * Your algorithm should run in O(n2) complexity. + *

+ * Follow up: Could you improve it to O(n log n) time complexity? */ -public class LongestIncreasingSubsequence -{ +public class LongestIncreasingSubsequence { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] nums = {9, 8, 7, 6}; System.out.println(new LongestIncreasingSubsequence().lengthOfLIS(nums)); } - public int lengthOfLIS(int[] nums) - { - if(nums.length == 0) return 0; + public int lengthOfLIS(int[] nums) { + if (nums.length == 0) return 0; int[] A = new int[nums.length]; int max = Integer.MIN_VALUE; - for(int i = 0, l = nums.length; i < l; i ++) - { + for (int i = 0, l = nums.length; i < l; i++) { int lis = 1; - for(int j = 0; j < i; j ++) - { - if(nums[i] > nums[j]) + for (int j = 0; j < i; j++) { + if (nums[i] > nums[j]) lis = Math.max(lis, A[j] + 1); } A[i] = lis; diff --git a/problems/src/dynamic_programming/LongestPaliandromicSubstring.java b/problems/src/dynamic_programming/LongestPaliandromicSubstring.java index 33b92216..5587dea1 100644 --- a/problems/src/dynamic_programming/LongestPaliandromicSubstring.java +++ b/problems/src/dynamic_programming/LongestPaliandromicSubstring.java @@ -2,62 +2,54 @@ /** * Created by gouthamvidyapradhan on 24/02/2017. - Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. - - Example: - - Input: "babad" - - Output: "bab" - - Note: "aba" is also a valid answer. - Example: - - Input: "cbbd" - - Output: "bb" + * Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. + *

+ * Example: + *

+ * Input: "babad" + *

+ * Output: "bab" + *

+ * Note: "aba" is also a valid answer. + * Example: + *

+ * Input: "cbbd" + *

+ * Output: "bb" */ -public class LongestPaliandromicSubstring -{ +public class LongestPaliandromicSubstring { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new LongestPaliandromicSubstring().longestPalindrome("forgeeksskeegfor")); } - public String longestPalindrome(String s) - { + public String longestPalindrome(String s) { int l = s.length(); - int startIndex = 0; int maxLen = 1; + int startIndex = 0; + int maxLen = 1; boolean[][] A = new boolean[l][l]; - for(int i = 0, j = 0; i < l; i++, j++) + for (int i = 0, j = 0; i < l; i++, j++) A[i][j] = true; - for(int i = 0, j = i + 1; j < l; i++, j++) - { - if(s.charAt(i) == s.charAt(j)) - { + for (int i = 0, j = i + 1; j < l; i++, j++) { + if (s.charAt(i) == s.charAt(j)) { A[i][j] = true; startIndex = i; maxLen = 2; } } - for(int k = 3; k <= l; k++) - { - for(int i = 0, j = k - 1; j < l; i++, j++) - { - if(s.charAt(i) == s.charAt(j)) - { + for (int k = 3; k <= l; k++) { + for (int i = 0, j = k - 1; j < l; i++, j++) { + if (s.charAt(i) == s.charAt(j)) { A[i][j] = A[i + 1][j - 1]; - if(A[i][j]) - { - if(k > maxLen) - { + if (A[i][j]) { + if (k > maxLen) { startIndex = i; maxLen = k; } diff --git a/problems/src/dynamic_programming/LongestPalindromicSubsequence.java b/problems/src/dynamic_programming/LongestPalindromicSubsequence.java index d00f7890..b450687a 100644 --- a/problems/src/dynamic_programming/LongestPalindromicSubsequence.java +++ b/problems/src/dynamic_programming/LongestPalindromicSubsequence.java @@ -2,35 +2,32 @@ /** * Created by gouthamvidyapradhan on 27/03/2017. - Given an unsorted array of integers, find the length of longest increasing subsequence. - - For example, - Given [10, 9, 2, 5, 3, 7, 101, 18], - The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length. - - Your algorithm should run in O(n2) complexity. - - Follow up: Could you improve it to O(n log n) time complexity? + * Given an unsorted array of integers, find the length of longest increasing subsequence. + *

+ * For example, + * Given [10, 9, 2, 5, 3, 7, 101, 18], + * The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length. + *

+ * Your algorithm should run in O(n2) complexity. + *

+ * Follow up: Could you improve it to O(n log n) time complexity? */ -public class LongestPalindromicSubsequence -{ +public class LongestPalindromicSubsequence { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new LongestPalindromicSubsequence().longestPalindromeSubseq("bbbab")); } - public int longestPalindromeSubseq(String s) - { + public int longestPalindromeSubseq(String s) { int[][] dp = new int[s.length() + 1][s.length() + 1]; String sI = new StringBuilder(s).reverse().toString(); - for(int i = 1, l = s.length(); i <= l; i++) - for(int j = 1; j <= l; j++) - { + for (int i = 1, l = s.length(); i <= l; i++) + for (int j = 1; j <= l; j++) { dp[i][j] = (s.charAt(i - 1) == sI.charAt(j - 1)) ? dp[i - 1][j - 1] + 1 : Math.max(dp[i - 1][j], dp[i][j - 1]); } diff --git a/problems/src/dynamic_programming/MaximumProductSubarray.java b/problems/src/dynamic_programming/MaximumProductSubarray.java index 0ed05cdc..ee14e793 100644 --- a/problems/src/dynamic_programming/MaximumProductSubarray.java +++ b/problems/src/dynamic_programming/MaximumProductSubarray.java @@ -2,32 +2,29 @@ /** * Created by gouthamvidyapradhan on 02/04/2017. - Find the contiguous subarray within an array (containing at least one number) which has the largest product. - - For example, given the array [2,3,-2,4], - the contiguous subarray [2,3] has the largest product = 6. + * Find the contiguous subarray within an array (containing at least one number) which has the largest product. + *

+ * For example, given the array [2,3,-2,4], + * the contiguous subarray [2,3] has the largest product = 6. */ -public class MaximumProductSubarray -{ +public class MaximumProductSubarray { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] A = {2,3,-2,4}; + public static void main(String[] args) throws Exception { + int[] A = {2, 3, -2, 4}; System.out.println(new MaximumProductSubarray().maxProduct(A)); } - public int maxProduct(int[] nums) - { - if(nums.length == 1) return nums[0]; + public int maxProduct(int[] nums) { + if (nums.length == 1) return nums[0]; int min = nums[0]; int max = nums[0]; int result = max; - for(int i = 1; i < nums.length; i ++) - { + for (int i = 1; i < nums.length; i++) { int prevMin = min, prevMax = max; min = Math.min(nums[i], Math.min(nums[i] * prevMin, nums[i] * prevMax)); max = Math.max(nums[i], Math.max(nums[i] * prevMin, nums[i] * prevMax)); diff --git a/problems/src/dynamic_programming/MaximumSubarray.java b/problems/src/dynamic_programming/MaximumSubarray.java index ec3fdc97..2a122c31 100644 --- a/problems/src/dynamic_programming/MaximumSubarray.java +++ b/problems/src/dynamic_programming/MaximumSubarray.java @@ -3,21 +3,21 @@ /** * Created by gouthamvidyapradhan on 07/07/2017. * Find the contiguous subarray within an array (containing at least one number) which has the largest sum. - - For example, given the array [-2,1,-3,4,-1,2,1,-5,4], - the contiguous subarray [4,-1,2,1] has the largest sum = 6. + *

+ * For example, given the array [-2,1,-3,4,-1,2,1,-5,4], + * the contiguous subarray [4,-1,2,1] has the largest sum = 6. */ public class MaximumSubarray { - public static void main(String[] args) throws Exception{ - int[] nums = {-2,1,-3,4,-1,2,1,-5,4}; + public static void main(String[] args) throws Exception { + int[] nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; System.out.println(new MaximumSubarray().maxSubArray(nums)); } public int maxSubArray(int[] nums) { - if(nums.length == 1) return nums[0]; + if (nums.length == 1) return nums[0]; int max = nums[nums.length - 1]; - for(int i = nums.length - 2; i >= 0; i --){ - nums[i] = Math.max(nums[i], nums[i] + nums[i + 1]); + for (int i = nums.length - 2; i >= 0; i--) { + nums[i] = Math.max(nums[i], nums[i] + nums[i + 1]); max = Math.max(max, nums[i]); } return max; diff --git a/problems/src/dynamic_programming/PalindromePartitioningII.java b/problems/src/dynamic_programming/PalindromePartitioningII.java index 83705149..a72f8e26 100644 --- a/problems/src/dynamic_programming/PalindromePartitioningII.java +++ b/problems/src/dynamic_programming/PalindromePartitioningII.java @@ -4,29 +4,28 @@ /** * Created by pradhang on 4/3/2017. - Given a string s, partition s such that every substring of the partition is a palindrome. - - Return the minimum cuts needed for a palindrome partitioning of s. - - For example, given s = "aab", - Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut. + * Given a string s, partition s such that every substring of the partition is a palindrome. + *

+ * Return the minimum cuts needed for a palindrome partitioning of s. + *

+ * For example, given s = "aab", + * Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut. */ -public class PalindromePartitioningII -{ +public class PalindromePartitioningII { private int A[]; private boolean[][] paliandrome; + /** * Main method + * * @param args */ - public static void main(String[] args) - { + public static void main(String[] args) { System.out.println(new PalindromePartitioningII().minCut("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); } - public int minCut(String s) - { - if(s == null || s.isEmpty()) return 0; + public int minCut(String s) { + if (s == null || s.isEmpty()) return 0; A = new int[s.length()]; Arrays.fill(A, Integer.MAX_VALUE); char[] charArr = s.toCharArray(); @@ -34,22 +33,16 @@ public int minCut(String s) return doNext(charArr, 0) - 1; } - private int doNext(char[] s, int p) - { - if(p >= s.length) return 0; - if(A[p] < Integer.MAX_VALUE) return A[p]; - for(int i = p, l = s.length; i < l; i ++ ) - { - if(p + 1 <= i - 1) - { - paliandrome[p][i] = (paliandrome[p+1][i-1] && (s[p] == s[i])); - } - else - { + private int doNext(char[] s, int p) { + if (p >= s.length) return 0; + if (A[p] < Integer.MAX_VALUE) return A[p]; + for (int i = p, l = s.length; i < l; i++) { + if (p + 1 <= i - 1) { + paliandrome[p][i] = (paliandrome[p + 1][i - 1] && (s[p] == s[i])); + } else { paliandrome[p][i] = (i == p) || (s[i] == s[p]); } - if(paliandrome[p][i]) - { + if (paliandrome[p][i]) { A[p] = Math.min(doNext(s, i + 1) + 1, A[p]); } } diff --git a/problems/src/dynamic_programming/TwoKeysKeyboard.java b/problems/src/dynamic_programming/TwoKeysKeyboard.java index 8c1f1b25..0bd11db5 100644 --- a/problems/src/dynamic_programming/TwoKeysKeyboard.java +++ b/problems/src/dynamic_programming/TwoKeysKeyboard.java @@ -3,39 +3,40 @@ /** * Created by gouthamvidyapradhan on 19/08/2017. * Initially on a notepad only one character 'A' is present. You can perform two operations on this notepad for each step: - - Copy All: You can copy all the characters present on the notepad (partial copy is not allowed). - Paste: You can paste the characters which are copied last time. - Given a number n. You have to get exactly n 'A' on the notepad by performing the minimum number of steps permitted. Output the minimum number of steps to get n 'A'. - - Example 1: - Input: 3 - Output: 3 - Explanation: - Intitally, we have one character 'A'. - In step 1, we use Copy All operation. - In step 2, we use Paste operation to get 'AA'. - In step 3, we use Paste operation to get 'AAA'. - - Note: - The n will be in the range [1, 1000]. + *

+ * Copy All: You can copy all the characters present on the notepad (partial copy is not allowed). + * Paste: You can paste the characters which are copied last time. + * Given a number n. You have to get exactly n 'A' on the notepad by performing the minimum number of steps permitted. Output the minimum number of steps to get n 'A'. + *

+ * Example 1: + * Input: 3 + * Output: 3 + * Explanation: + * Intitally, we have one character 'A'. + * In step 1, we use Copy All operation. + * In step 2, we use Paste operation to get 'AA'. + * In step 3, we use Paste operation to get 'AAA'. + *

+ * Note: + * The n will be in the range [1, 1000]. */ public class TwoKeysKeyboard { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new TwoKeysKeyboard().minSteps(8)); } public int minSteps(int n) { int[] DP = new int[n + 1]; - for(int i = 2; i <= n; i++){ + for (int i = 2; i <= n; i++) { DP[i] = i; - for(int j = 2; j < i; j++){ - if((i % j) == 0){ + for (int j = 2; j < i; j++) { + if ((i % j) == 0) { DP[i] = Math.min(DP[i], DP[j] + (i / j)); } } diff --git a/problems/src/dynamic_programming/UniqueBinarySearchTrees.java b/problems/src/dynamic_programming/UniqueBinarySearchTrees.java index 922e7296..708c9a1f 100644 --- a/problems/src/dynamic_programming/UniqueBinarySearchTrees.java +++ b/problems/src/dynamic_programming/UniqueBinarySearchTrees.java @@ -2,42 +2,38 @@ /** * Created by gouthamvidyapradhan on 31/03/2017. - Given n, how many structurally unique BST's (binary search trees) that store values 1...n? - - For example, - Given n = 3, there are a total of 5 unique BST's. - - 1 3 3 2 1 - \ / / / \ \ - 3 2 1 1 3 2 - / / \ \ - 2 1 2 3 - + * Given n, how many structurally unique BST's (binary search trees) that store values 1...n? + *

+ * For example, + * Given n = 3, there are a total of 5 unique BST's. + *

+ * 1 3 3 2 1 + * \ / / / \ \ + * 3 2 1 1 3 2 + * / / \ \ + * 2 1 2 3 */ -public class UniqueBinarySearchTrees -{ +public class UniqueBinarySearchTrees { int[] dp; + /** * Main method + * * @param args */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new UniqueBinarySearchTrees().numTrees(5)); } - public int numTrees(int n) - { + public int numTrees(int n) { dp = new int[n + 1]; dp[0] = 1; return dp(n); } - private int dp(int n) - { - if(dp[n] != 0) return dp[n]; - for(int i = 1; i <= n; i ++) - { + private int dp(int n) { + if (dp[n] != 0) return dp[n]; + for (int i = 1; i <= n; i++) { dp[n] += dp(n - i) * dp(n - (n - i) - 1); } return dp[n]; diff --git a/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java b/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java index e55c19fa..5fd0bc56 100644 --- a/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java +++ b/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java @@ -5,98 +5,83 @@ /** * Created by gouthamvidyapradhan on 31/03/2017. - Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1...n. - - For example, - Given n = 3, your program should return all 5 unique BST's shown below. - - 1 3 3 2 1 - \ / / / \ \ - 3 2 1 1 3 2 - / / \ \ - 2 1 2 3 - + * Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1...n. + *

+ * For example, + * Given n = 3, your program should return all 5 unique BST's shown below. + *

+ * 1 3 3 2 1 + * \ / / / \ \ + * 3 2 1 1 3 2 + * / / \ \ + * 2 1 2 3 */ -public class UniqueBinarySearchTreesII -{ - public static class TreeNode - { +public class UniqueBinarySearchTreesII { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private List[][] dp; /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List list = new UniqueBinarySearchTreesII().generateTrees(3); } - public List generateTrees(int n) - { - if(n == 0) return new ArrayList<>(); + public List generateTrees(int n) { + if (n == 0) return new ArrayList<>(); dp = new List[n + 1][n + 1]; dp[0][0] = new ArrayList<>(); - for(int i = 1, j = 1; i <= n; i ++, j ++) - { + for (int i = 1, j = 1; i <= n; i++, j++) { dp[i][j] = new ArrayList<>(); dp[i][j].add(new TreeNode(i)); } return dp(1, n, n); } - private List dp(int s, int e, int n) - { - if(e < s) return null; - if(dp[s][e] != null) return dp[s][e]; + private List dp(int s, int e, int n) { + if (e < s) return null; + if (dp[s][e] != null) return dp[s][e]; List result = new ArrayList<>(); - for(int i = s; i <= e; i ++) - { + for (int i = s; i <= e; i++) { List left = dp(s, i - 1, n); List right = dp(i + 1, e, n); List temp = new ArrayList<>(); - if(left != null) - { - for(TreeNode node : left) - { + if (left != null) { + for (TreeNode node : left) { TreeNode root = new TreeNode(i); root.left = node; temp.add(root); } } - if(right != null) - { - if(!temp.isEmpty()) - { - for(TreeNode root : temp) - { - for(TreeNode node : right) - { + if (right != null) { + if (!temp.isEmpty()) { + for (TreeNode root : temp) { + for (TreeNode node : right) { TreeNode newRoot = clone(root); newRoot.right = node; result.add(newRoot); } } - } - else - { - for(TreeNode node : right) - { + } else { + for (TreeNode node : right) { TreeNode root = new TreeNode(i); root.right = node; result.add(root); } } - } - else if(!temp.isEmpty()) - { + } else if (!temp.isEmpty()) { result.addAll(temp); } } @@ -106,12 +91,12 @@ else if(!temp.isEmpty()) /** * Clone treeNode + * * @param root rootnode * @return cloned root */ - private TreeNode clone(TreeNode root) - { - if(root == null) return null; + private TreeNode clone(TreeNode root) { + if (root == null) return null; TreeNode newNode = new TreeNode(root.val); newNode.left = clone(root.left); newNode.right = clone(root.right); diff --git a/problems/src/dynamic_programming/WordBreak.java b/problems/src/dynamic_programming/WordBreak.java index 70968715..bc7ca55b 100644 --- a/problems/src/dynamic_programming/WordBreak.java +++ b/problems/src/dynamic_programming/WordBreak.java @@ -4,60 +4,53 @@ /** * Created by gouthamvidyapradhan on 16/03/2017. - Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words. You may assume the dictionary does not contain duplicate words. - - For example, given - s = "leetcode", - dict = ["leet", "code"]. - - Return true because "leetcode" can be segmented as "leet code". + * Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words. You may assume the dictionary does not contain duplicate words. + *

+ * For example, given + * s = "leetcode", + * dict = ["leet", "code"]. + *

+ * Return true because "leetcode" can be segmented as "leet code". */ -public class WordBreak -{ +public class WordBreak { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List dic = new ArrayList<>(); - String[] arr = {"a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"}; + String[] arr = {"a", "aa", "aaa", "aaaa", "aaaaa", "aaaaaa", "aaaaaaa", "aaaaaaaa", "aaaaaaaaa", "aaaaaaaaaa"}; for (String s : arr) dic.add(s); System.out.println(new WordBreak().wordBreak("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", dic)); } - public boolean wordBreak(String s, List wordDict) - { + public boolean wordBreak(String s, List wordDict) { Set dictionary = new HashSet<>(); dictionary.addAll(wordDict); Map dic = new HashMap<>(); - for(int i = s.length() - 1; i >= 0; i --) + for (int i = s.length() - 1; i >= 0; i--) dp(i, s, dic, dictionary); return dic.get(0); } - private boolean dp(int i, String s, Map dic, Set dictionary) - { - if(i == s.length()) return true; - else if(dic.containsKey(i)) return dic.get(i); - else - { - for(int j = i, l = s.length(); j < l; j++) - { + private boolean dp(int i, String s, Map dic, Set dictionary) { + if (i == s.length()) return true; + else if (dic.containsKey(i)) return dic.get(i); + else { + for (int j = i, l = s.length(); j < l; j++) { String subStr = s.substring(i, j + 1); - if(dictionary.contains(subStr)) - { - if(dp(j + 1, s, dic, dictionary)) - { + if (dictionary.contains(subStr)) { + if (dp(j + 1, s, dic, dictionary)) { dic.put(i, true); break; } } } } - if(!dic.containsKey(i)) + if (!dic.containsKey(i)) dic.put(i, false); return dic.get(i); } diff --git a/problems/src/dynamic_programming/WordBreakII.java b/problems/src/dynamic_programming/WordBreakII.java index 6c99493d..7265dcb1 100644 --- a/problems/src/dynamic_programming/WordBreakII.java +++ b/problems/src/dynamic_programming/WordBreakII.java @@ -4,26 +4,26 @@ /** * Created by gouthamvidyapradhan on 07/04/2017. - Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. You may assume the dictionary does not contain duplicate words. - - Return all such possible sentences. - - For example, given - s = "catsanddog", - dict = ["cat", "cats", "and", "sand", "dog"]. - - A solution is ["cats and dog", "cat sand dog"]. + * Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. You may assume the dictionary does not contain duplicate words. + *

+ * Return all such possible sentences. + *

+ * For example, given + * s = "catsanddog", + * dict = ["cat", "cats", "and", "sand", "dog"]. + *

+ * A solution is ["cats and dog", "cat sand dog"]. */ -public class WordBreakII -{ +public class WordBreakII { private Map> map; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List wordList = new ArrayList<>(); wordList.add("cat"); wordList.add("cats"); @@ -33,34 +33,27 @@ public static void main(String[] args) throws Exception System.out.println(new WordBreakII().wordBreak("catsanddog", wordList)); } - public List wordBreak(String s, List wordDict) - { - if(s == null) return new ArrayList<>(); + public List wordBreak(String s, List wordDict) { + if (s == null) return new ArrayList<>(); map = new HashMap<>(); Set dictionary = new HashSet<>(); dictionary.addAll(wordDict); return dp(0, s, s.length(), dictionary); } - private List dp(int p, String s, int l, Set dictionary) - { + private List dp(int p, String s, int l, Set dictionary) { List result = new ArrayList<>(); - if(p >= s.length()) - { + if (p >= s.length()) { result.add(""); return result; - } - else if(map.containsKey(p)) - { + } else if (map.containsKey(p)) { return map.get(p); } - for(int i = p; i < l; i ++) - { + for (int i = p; i < l; i++) { String subStr = s.substring(p, i + 1); - if(dictionary.contains(subStr)) - { + if (dictionary.contains(subStr)) { List subList = dp(i + 1, s, l, dictionary); - for(String se : subList) + for (String se : subList) result.add((subStr + " " + se).trim()); } } diff --git a/problems/src/greedy/BurstBalloons.java b/problems/src/greedy/BurstBalloons.java index 1fe8e8ea..c9501aab 100644 --- a/problems/src/greedy/BurstBalloons.java +++ b/problems/src/greedy/BurstBalloons.java @@ -1,45 +1,45 @@ package greedy; -import java.util.ArrayDeque; import java.util.Arrays; /** * Created by gouthamvidyapradhan on 28/06/2017. - * + *

* There are a number of spherical balloons spread in two-dimensional space. For each balloon, provided input is the start and end coordinates of the horizontal diameter. Since it's horizontal, y-coordinates don't matter and hence the x-coordinates of start and end of the diameter suffice. Start is always smaller than end. There will be at most 104 balloons. - - An arrow can be shot up exactly vertically from different points along the x-axis. A balloon with xstart and xend bursts by an arrow shot at x if xstart ≤ x ≤ xend. There is no limit to the number of arrows that can be shot. An arrow once shot keeps travelling up infinitely. The problem is to find the minimum number of arrows that must be shot to burst all balloons. - - Example: - - Input: - [[10,16], [2,8], [1,6], [7,12]] - - Output: - 2 - - Explanation: - One way is to shoot one arrow for example at x = 6 (bursting the balloons [2,8] and [1,6]) and another arrow at x + *

+ * An arrow can be shot up exactly vertically from different points along the x-axis. A balloon with xstart and xend bursts by an arrow shot at x if xstart ≤ x ≤ xend. There is no limit to the number of arrows that can be shot. An arrow once shot keeps travelling up infinitely. The problem is to find the minimum number of arrows that must be shot to burst all balloons. + *

+ * Example: + *

+ * Input: + * [[10,16], [2,8], [1,6], [7,12]] + *

+ * Output: + * 2 + *

+ * Explanation: + * One way is to shoot one arrow for example at x = 6 (bursting the balloons [2,8] and [1,6]) and another arrow at x */ public class BurstBalloons { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ - int[][] baloons = {{10,16}, {2,8}, {1,6}, {7,12}}; + public static void main(String[] args) throws Exception { + int[][] baloons = {{10, 16}, {2, 8}, {1, 6}, {7, 12}}; System.out.println(new BurstBalloons().findMinArrowShots(baloons)); } public int findMinArrowShots(int[][] points) { - if(points.length == 0) return 0; + if (points.length == 0) return 0; Arrays.sort(points, ((o1, o2) -> o1[1] - o2[1])); int count = 0; int leftMost = points[0][1]; - for(int i = 1; i < points.length; i ++){ - if(leftMost < points[i][0]){ - count ++; + for (int i = 1; i < points.length; i++) { + if (leftMost < points[i][0]) { + count++; leftMost = points[i][1]; } } diff --git a/problems/src/greedy/CourseScheduleIII.java b/problems/src/greedy/CourseScheduleIII.java index 16469658..b370de3f 100644 --- a/problems/src/greedy/CourseScheduleIII.java +++ b/problems/src/greedy/CourseScheduleIII.java @@ -6,25 +6,25 @@ /** * Created by gouthamvidyapradhan on 27/06/2017. - * + *

* There are n different online courses numbered from 1 to n. Each course has some duration(course length) t and closed on dth day. A course should be taken continuously for t days and must be finished before or on the dth day. You will start at the 1st day. - - Given n online courses represented by pairs (t,d), your task is to find the maximal number of courses that can be taken. - - Example: - Input: [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]] - Output: 3 - Explanation: - There're totally 4 courses, but you can take 3 courses at most: - First, take the 1st course, it costs 100 days so you will finish it on the 100th day, and ready to take the next course on the 101st day. - Second, take the 3rd course, it costs 1000 days so you will finish it on the 1100th day, and ready to take the next course on the 1101st day. - Third, take the 2nd course, it costs 200 days so you will finish it on the 1300th day. - The 4th course cannot be taken now, since you will finish it on the 3300th day, which exceeds the closed date. - - Note: - The integer 1 <= d, t, n <= 10,000. - You can't take two courses simultaneously. - + *

+ * Given n online courses represented by pairs (t,d), your task is to find the maximal number of courses that can be taken. + *

+ * Example: + * Input: [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]] + * Output: 3 + * Explanation: + * There're totally 4 courses, but you can take 3 courses at most: + * First, take the 1st course, it costs 100 days so you will finish it on the 100th day, and ready to take the next course on the 101st day. + * Second, take the 3rd course, it costs 1000 days so you will finish it on the 1100th day, and ready to take the next course on the 1101st day. + * Third, take the 2nd course, it costs 200 days so you will finish it on the 1300th day. + * The 4th course cannot be taken now, since you will finish it on the 3300th day, which exceeds the closed date. + *

+ * Note: + * The integer 1 <= d, t, n <= 10,000. + * You can't take two courses simultaneously. + *

* Solution: O(N log N) * 1. Sort the courses with earliest deadline time (Greedy sort) * 2. Maintain a max-heap of course duration. @@ -34,7 +34,7 @@ Given n online courses represented by pairs (t,d), your task is to find the maxi * inorder to accommodate the new course. */ public class CourseScheduleIII { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[][] course = {{5, 5}, {2, 6}, {4, 6}}; System.out.println(new CourseScheduleIII().scheduleCourse(course)); } @@ -43,10 +43,10 @@ public int scheduleCourse(int[][] courses) { Arrays.sort(courses, (a, b) -> a[1] - b[1]); Queue pq = new PriorityQueue<>((a, b) -> b - a); int time = 0; - for(int[] course : courses){ + for (int[] course : courses) { time += course[0]; pq.add(course[0]); - if(time > course[1]) + if (time > course[1]) time -= pq.poll(); } return pq.size(); diff --git a/problems/src/greedy/GasStation.java b/problems/src/greedy/GasStation.java index b6f38879..7afa0f51 100644 --- a/problems/src/greedy/GasStation.java +++ b/problems/src/greedy/GasStation.java @@ -3,36 +3,36 @@ /** * Created by gouthamvidyapradhan on 28/06/2017. * There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. - - You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations. - - Return the starting gas station's index if you can travel around the circuit once, otherwise return -1. - - Note: - The solution is guaranteed to be unique. - - Solution: O(N) - If point B cant be reached from point A then all the intermediate points between A and B cant be the starting - point. Therefore reset the starting point to the new starting point. - + *

+ * You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations. + *

+ * Return the starting gas station's index if you can travel around the circuit once, otherwise return -1. + *

+ * Note: + * The solution is guaranteed to be unique. + *

+ * Solution: O(N) + * If point B cant be reached from point A then all the intermediate points between A and B cant be the starting + * point. Therefore reset the starting point to the new starting point. */ public class GasStation { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ - int[] gas = {10, 20, 30, 10}; + public static void main(String[] args) throws Exception { + int[] gas = {10, 20, 30, 10}; int[] cost = {5, 30, 10, 10}; System.out.println(new GasStation().canCompleteCircuit(gas, cost)); } public int canCompleteCircuit(int[] gas, int[] cost) { int debt = 0, sum = 0, start = 0; - for(int i = 0; i < gas.length; i ++){ + for (int i = 0; i < gas.length; i++) { sum += gas[i] - cost[i]; - if(sum < 0){ + if (sum < 0) { debt += sum; sum = 0; start = i + 1; diff --git a/problems/src/greedy/JumpGame.java b/problems/src/greedy/JumpGame.java index 91b43b0f..3c7ea2fa 100644 --- a/problems/src/greedy/JumpGame.java +++ b/problems/src/greedy/JumpGame.java @@ -2,37 +2,34 @@ /** * Created by gouthamvidyapradhan on 17/03/2017. - Given an array of non-negative integers, 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. - - For example: - A = [2,3,1,1,4], return true. - - A = [3,2,1,0,4], return false. + * Given an array of non-negative integers, 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. + *

+ * For example: + * A = [2,3,1,1,4], return true. + *

+ * A = [3,2,1,0,4], return false. */ -public class JumpGame -{ +public class JumpGame { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] nums = {1,2,1,0,4}; + public static void main(String[] args) throws Exception { + int[] nums = {1, 2, 1, 0, 4}; System.out.println(new JumpGame().canJump(nums)); } - public boolean canJump(int[] nums) - { - if(nums.length == 0) return false; + public boolean canJump(int[] nums) { + if (nums.length == 0) return false; int min = nums.length - 1, max = nums.length - 1; - for(int i = nums.length - 2; i >= 0; i --) - { - if((nums[i] + i) >= min) + for (int i = nums.length - 2; i >= 0; i--) { + if ((nums[i] + i) >= min) min = i; } return (min == 0); diff --git a/problems/src/greedy/JumpGameII.java b/problems/src/greedy/JumpGameII.java index 7e45e13d..051ab50e 100644 --- a/problems/src/greedy/JumpGameII.java +++ b/problems/src/greedy/JumpGameII.java @@ -2,41 +2,37 @@ /** * Created by gouthamvidyapradhan on 02/04/2017. - Given an array of non-negative integers, you are initially positioned at the first index of the array. - - Each element in the array represents your maximum jump length at that position. - - Your goal is to reach the last index in the minimum number of jumps. - - For example: - Given array A = [2,3,1,1,4] - - The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.) - - Note: - You can assume that you can always reach the last index. + * Given an array of non-negative integers, you are initially positioned at the first index of the array. + *

+ * Each element in the array represents your maximum jump length at that position. + *

+ * Your goal is to reach the last index in the minimum number of jumps. + *

+ * For example: + * Given array A = [2,3,1,1,4] + *

+ * The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.) + *

+ * Note: + * You can assume that you can always reach the last index. */ -public class JumpGameII -{ +public class JumpGameII { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { } - public int jump(int[] nums) - { + public int jump(int[] nums) { int step = 0; int e = 0, max = 0; - for(int i = 0; i < nums.length - 1; i++) - { + for (int i = 0; i < nums.length - 1; i++) { max = Math.max(max, i + nums[i]); - if(i == e) - { + if (i == e) { step++; e = max; } diff --git a/problems/src/greedy/NonOverlappingIntervals.java b/problems/src/greedy/NonOverlappingIntervals.java index 0f0bbaf4..2ec7bcce 100644 --- a/problems/src/greedy/NonOverlappingIntervals.java +++ b/problems/src/greedy/NonOverlappingIntervals.java @@ -1,50 +1,57 @@ package greedy; -import array.MergeIntervals; - import java.util.Arrays; /** * Created by gouthamvidyapradhan on 28/06/2017. * Given a collection of intervals, find the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping. - - Note: - You may assume the interval's end point is always bigger than its start point. - Intervals like [1,2] and [2,3] have borders "touching" but they don't overlap each other. - Example 1: - 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. - Example 2: - 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. - Example 3: - Input: [ [1,2], [2,3] ] - - Output: 0 - - Explanation: You don't need to remove any of the intervals since they're already non-overlapping. + *

+ * Note: + * You may assume the interval's end point is always bigger than its start point. + * Intervals like [1,2] and [2,3] have borders "touching" but they don't overlap each other. + * Example 1: + * 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. + * Example 2: + * 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. + * Example 3: + * Input: [ [1,2], [2,3] ] + *

+ * Output: 0 + *

+ * Explanation: You don't need to remove any of the intervals since they're already non-overlapping. */ public class NonOverlappingIntervals { public static class Interval { int start; int end; - Interval() { start = 0; end = 0; } - Interval(int s, int e) { start = s; end = e; } + + Interval() { + start = 0; + end = 0; + } + + Interval(int s, int e) { + start = s; + end = e; + } } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { Interval i1 = new Interval(1, 4); Interval i2 = new Interval(5, 9); Interval i3 = new Interval(3, 12); @@ -54,15 +61,14 @@ public static void main(String[] args) throws Exception{ } public int eraseOverlapIntervals(Interval[] intervals) { - if(intervals.length == 0) return 0; + if (intervals.length == 0) return 0; Arrays.sort(intervals, ((o1, o2) -> o1.end - o2.end)); int count = 0; Interval prev = intervals[0]; - for(int i = 1; i < intervals.length; i ++){ - if(intervals[i].start < prev.end){ + for (int i = 1; i < intervals.length; i++) { + if (intervals[i].start < prev.end) { count++; - } - else{ + } else { prev = intervals[i]; } } diff --git a/problems/src/greedy/QueueReconstructionByHeight.java b/problems/src/greedy/QueueReconstructionByHeight.java index 4de71294..96269910 100644 --- a/problems/src/greedy/QueueReconstructionByHeight.java +++ b/problems/src/greedy/QueueReconstructionByHeight.java @@ -6,23 +6,23 @@ /** * Created by gouthamvidyapradhan on 29/06/2017. * Suppose you have a random list of people standing in a queue. Each person is described by a pair of integers (h, k), where h is the height of the person and k is the number of people in front of this person who have a height greater than or equal to h. Write an algorithm to reconstruct the queue. - - Note: - The number of people is less than 1,100. - - Example - - 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]] + *

+ * Note: + * The number of people is less than 1,100. + *

+ * Example + *

+ * 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 QueueReconstructionByHeight { - public static void main(String[] args) throws Exception{ - int[][] A = {{7,0}, {4,4}, {7,1}, {5,0}, {6,1}, {5,2}}; + public static void main(String[] args) throws Exception { + int[][] A = {{7, 0}, {4, 4}, {7, 1}, {5, 0}, {6, 1}, {5, 2}}; int[][] r = new QueueReconstructionByHeight().reconstructQueue(A); - for(int[] i : r){ + for (int[] i : r) { System.out.println(i[0] + " " + i[1]); } } @@ -30,10 +30,10 @@ public static void main(String[] args) throws Exception{ public int[][] reconstructQueue(int[][] people) { Arrays.sort(people, ((o1, o2) -> (o2[0] - o1[0] == 0) ? o1[1] - o2[1] : o2[0] - o1[0])); LinkedList list = new LinkedList<>(); - for(int[] p : people) + for (int[] p : people) list.add(p[1], p); int[][] result = new int[people.length][2]; - for(int i = 0, l = list.size(); i < l; i ++) + for (int i = 0, l = list.size(); i < l; i++) result[i] = list.get(i); return result; } diff --git a/problems/src/hashing/Anagrams.java b/problems/src/hashing/Anagrams.java index 10fc0bf1..a9a91aa1 100644 --- a/problems/src/hashing/Anagrams.java +++ b/problems/src/hashing/Anagrams.java @@ -6,84 +6,79 @@ /** * Created by gouthamvidyapradhan on 25/02/2017. - 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. - - Example 1: - - 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". - Example 2: - - Input: - s: "abab" p: "ab" - - Output: - [0, 1, 2] - - Explanation: - The substring with start index = 0 is "ab", which is an anagram of "ab". - The substring with start index = 1 is "ba", which is an anagram of "ab". - The substring with start index = 2 is "ab", which is an anagram of "ab". + * 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. + *

+ * Example 1: + *

+ * 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". + * Example 2: + *

+ * Input: + * s: "abab" p: "ab" + *

+ * Output: + * [0, 1, 2] + *

+ * Explanation: + * The substring with start index = 0 is "ab", which is an anagram of "ab". + * The substring with start index = 1 is "ba", which is an anagram of "ab". + * The substring with start index = 2 is "ab", which is an anagram of "ab". */ -public class Anagrams -{ +public class Anagrams { int[] TC = new int[256]; int[] PC = new int[256]; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List result = new Anagrams().findAnagrams("abab", "ab"); result.forEach(System.out::print); } - public List findAnagrams(String s, String p) - { + public List findAnagrams(String s, String p) { List result = new ArrayList<>(); int pLen = p.length(); - if(pLen > s.length()) return result; + if (pLen > s.length()) return result; Arrays.fill(TC, 0); Arrays.fill(PC, 0); - for(int i = 0; i < pLen; i ++) - { + for (int i = 0; i < pLen; i++) { TC[s.charAt(i)]++; PC[p.charAt(i)]++; } int i = pLen; - for(int l = s.length(); i < l; i ++) - { - if(compare()) + for (int l = s.length(); i < l; i++) { + if (compare()) result.add(i - pLen); TC[s.charAt(i)]++; TC[s.charAt(i - pLen)]--; } - if(compare()) + if (compare()) result.add(i - pLen); return result; } - private boolean compare() - { - for(int i = 0; i < 256; i ++) - { - if(TC[i] != PC[i]) + private boolean compare() { + for (int i = 0; i < 256; i++) { + if (TC[i] != PC[i]) return false; } return true; diff --git a/problems/src/hashing/GroupAnagrams.java b/problems/src/hashing/GroupAnagrams.java index 4b62b9c3..06ba7b78 100644 --- a/problems/src/hashing/GroupAnagrams.java +++ b/problems/src/hashing/GroupAnagrams.java @@ -7,64 +7,60 @@ /** * Created by gouthamvidyapradhan on 10/03/2017. - Given an array of strings, group anagrams together. - - For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"], - Return: - - [ - ["ate", "eat","tea"], - ["nat","tan"], - ["bat"] - ] - Note: All inputs will be in lower-case. + * Given an array of strings, group anagrams together. + *

+ * For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"], + * Return: + *

+ * [ + * ["ate", "eat","tea"], + * ["nat","tan"], + * ["bat"] + * ] + * Note: All inputs will be in lower-case. */ -public class GroupAnagrams -{ +public class GroupAnagrams { private int[] A = new int[256]; private HashMap> hashMap = new HashMap<>(); private List> result = new ArrayList<>(); + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { String[] strs = {"huh", "tit"}; List> result = new GroupAnagrams().groupAnagrams(strs); - for (List l : result) - { - for(String s : l) + for (List l : result) { + for (String s : l) System.out.println(s); System.out.println("-----"); } } - public List> groupAnagrams(String[] strs) - { - for(int i = 0, l = strs.length; i < l; i ++) - { + public List> groupAnagrams(String[] strs) { + for (int i = 0, l = strs.length; i < l; i++) { Arrays.fill(A, 0); String s = strs[i]; - for(int j = 0, sl = s.length(); j < sl; j ++) + for (int j = 0, sl = s.length(); j < sl; j++) A[s.charAt(j)]++; StringBuilder sb = new StringBuilder(); - for(int k = 0; k < 256; k ++) - { - if(A[k] != 0) + for (int k = 0; k < 256; k++) { + if (A[k] != 0) sb.append(k).append("").append(A[k]); } List value = hashMap.get(sb.toString()); - if(value == null) + if (value == null) value = new ArrayList<>(); value.add(s); hashMap.put(sb.toString(), value); } - for(String s : hashMap.keySet()) + for (String s : hashMap.keySet()) result.add(hashMap.get(s)); return result; diff --git a/problems/src/hashing/KdiffPairsInanArray.java b/problems/src/hashing/KdiffPairsInanArray.java index 5d1b330d..4f9b2ca2 100644 --- a/problems/src/hashing/KdiffPairsInanArray.java +++ b/problems/src/hashing/KdiffPairsInanArray.java @@ -1,62 +1,57 @@ package hashing; -import java.util.*; +import java.util.HashMap; +import java.util.Map; /** * Created by gouthamvidyapradhan on 28/03/2017. - Given an array of integers and an integer k, you need to find the number of unique k-diff pairs in the array. Here a k-diff pair is defined as an integer pair (i, j), where i and j are both numbers in the array and their absolute difference is k. - - Example 1: - Input: [3, 1, 4, 1, 5], k = 2 - Output: 2 - Explanation: There are two 2-diff pairs in the array, (1, 3) and (3, 5). - Although we have two 1s in the input, we should only return the number of unique pairs. - Example 2: - Input:[1, 2, 3, 4, 5], k = 1 - Output: 4 - Explanation: There are four 1-diff pairs in the array, (1, 2), (2, 3), (3, 4) and (4, 5). - Example 3: - Input: [1, 3, 1, 5, 4], k = 0 - Output: 1 - Explanation: There is one 0-diff pair in the array, (1, 1). - Note: - The pairs (i, j) and (j, i) count as the same pair. - The length of the array won't exceed 10,000. - All the integers in the given input belong to the range: [-1e7, 1e7]. + * Given an array of integers and an integer k, you need to find the number of unique k-diff pairs in the array. Here a k-diff pair is defined as an integer pair (i, j), where i and j are both numbers in the array and their absolute difference is k. + *

+ * Example 1: + * Input: [3, 1, 4, 1, 5], k = 2 + * Output: 2 + * Explanation: There are two 2-diff pairs in the array, (1, 3) and (3, 5). + * Although we have two 1s in the input, we should only return the number of unique pairs. + * Example 2: + * Input:[1, 2, 3, 4, 5], k = 1 + * Output: 4 + * Explanation: There are four 1-diff pairs in the array, (1, 2), (2, 3), (3, 4) and (4, 5). + * Example 3: + * Input: [1, 3, 1, 5, 4], k = 0 + * Output: 1 + * Explanation: There is one 0-diff pair in the array, (1, 1). + * Note: + * The pairs (i, j) and (j, i) count as the same pair. + * The length of the array won't exceed 10,000. + * All the integers in the given input belong to the range: [-1e7, 1e7]. */ -public class KdiffPairsInanArray -{ +public class KdiffPairsInanArray { private Map map = new HashMap<>(); private int count = 0; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] nums = {1,2,3,4,5}; + public static void main(String[] args) throws Exception { + int[] nums = {1, 2, 3, 4, 5}; System.out.println(new KdiffPairsInanArray().findPairs(nums, -1)); } - public int findPairs(int[] nums, int k) - { - if(nums.length == 0 || k < 0) return 0; - for(int i : nums) - { + public int findPairs(int[] nums, int k) { + if (nums.length == 0 || k < 0) return 0; + for (int i : nums) { map.put(i, map.getOrDefault(i, 0) + 1); } - for(Map.Entry entry : map.entrySet()) - { - if(k == 0) - { - if(entry.getValue() > 1) - count ++; - } - else - { - if(map.containsKey(entry.getKey() + k)) - count ++; + for (Map.Entry entry : map.entrySet()) { + if (k == 0) { + if (entry.getValue() > 1) + count++; + } else { + if (map.containsKey(entry.getKey() + k)) + count++; } } return count; diff --git a/problems/src/hashing/SortCharByFrequency.java b/problems/src/hashing/SortCharByFrequency.java index cf4da160..eb9ce36a 100644 --- a/problems/src/hashing/SortCharByFrequency.java +++ b/problems/src/hashing/SortCharByFrequency.java @@ -1,79 +1,77 @@ package hashing; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * Created by gouthamvidyapradhan on 25/03/2017. - Given a string, sort it in decreasing order based on the frequency of characters. - - Example 1: - - Input: - "tree" - - Output: - "eert" - - Explanation: - 'e' appears twice while 'r' and 't' both appear once. - So 'e' must appear before both 'r' and 't'. Therefore "eetr" is also a valid answer. - Example 2: - - Input: - "cccaaa" - - Output: - "cccaaa" - - Explanation: - Both 'c' and 'a' appear three times, so "aaaccc" is also a valid answer. - Note that "cacaca" is incorrect, as the same characters must be together. - - Example 3: - - Input: - "Aabb" - - Output: - "bbAa" - - Explanation: - "bbaA" is also a valid answer, but "Aabb" is incorrect. - Note that 'A' and 'a' are treated as two different characters. - + * Given a string, sort it in decreasing order based on the frequency of characters. + *

+ * Example 1: + *

+ * Input: + * "tree" + *

+ * Output: + * "eert" + *

+ * Explanation: + * 'e' appears twice while 'r' and 't' both appear once. + * So 'e' must appear before both 'r' and 't'. Therefore "eetr" is also a valid answer. + * Example 2: + *

+ * Input: + * "cccaaa" + *

+ * Output: + * "cccaaa" + *

+ * Explanation: + * Both 'c' and 'a' appear three times, so "aaaccc" is also a valid answer. + * Note that "cacaca" is incorrect, as the same characters must be together. + *

+ * Example 3: + *

+ * Input: + * "Aabb" + *

+ * Output: + * "bbAa" + *

+ * Explanation: + * "bbaA" is also a valid answer, but "Aabb" is incorrect. + * Note that 'A' and 'a' are treated as two different characters. */ -public class SortCharByFrequency -{ - class Freq - { +public class SortCharByFrequency { + class Freq { int i; int c; } private int[] buff = new int[256]; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new SortCharByFrequency().frequencySort("askdfkasdkfasdkljfklasdjfkl")); } - public String frequencySort(String s) - { - if(s == null || s.isEmpty()) return s; + public String frequencySort(String s) { + if (s == null || s.isEmpty()) return s; Arrays.fill(buff, 0); StringBuilder sb = new StringBuilder(); - for(int i = 0, l = s.length(); i < l; i ++) + for (int i = 0, l = s.length(); i < l; i++) buff[s.charAt(i)]++; List fList = new ArrayList<>(); - for(int i = 0; i < 256; i ++) - { - if(buff[i] > 0) - { + for (int i = 0; i < 256; i++) { + if (buff[i] > 0) { Freq f = new Freq(); f.i = i; f.c = buff[i]; @@ -83,11 +81,10 @@ public String frequencySort(String s) Collections.sort(fList, (o1, o2) -> Integer.compare(o2.c, o1.c)); - for(Freq f : fList) - { - char c = (char)f.i; + for (Freq f : fList) { + char c = (char) f.i; int freq = f.c; - while(freq-- > 0) + while (freq-- > 0) sb.append(c); } return sb.toString(); diff --git a/problems/src/hashing/TwoSum.java b/problems/src/hashing/TwoSum.java index 84ee1f30..9ddd8909 100644 --- a/problems/src/hashing/TwoSum.java +++ b/problems/src/hashing/TwoSum.java @@ -4,65 +4,49 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given an array of integers, return indices of the two numbers such that they add up to a specific target. - - You may assume that each input would have exactly one solution, and you may not use the same element twice. - - Example: - Given nums = [2, 7, 11, 15], target = 9, - - Because nums[0] + nums[1] = 2 + 7 = 9, - return [0, 1]. + * Given an array of integers, return indices of the two numbers such that they add up to a specific target. + *

+ * You may assume that each input would have exactly one solution, and you may not use the same element twice. + *

+ * Example: + * Given nums = [2, 7, 11, 15], target = 9, + *

+ * Because nums[0] + nums[1] = 2 + 7 = 9, + * return [0, 1]. */ -public class TwoSum -{ +public class TwoSum { HashMap map = new HashMap<>(); - public int[] twoSum(int[] nums, int target) - { + public int[] twoSum(int[] nums, int target) { int[] result = new int[2]; - for(int i : nums) - { - if(map.keySet().contains(i)) - { + for (int i : nums) { + if (map.keySet().contains(i)) { int count = map.get(i); map.put(i, ++count); - } - else - { + } else { map.put(i, 1); } } - for(int i = 0, l = nums.length; i < l; i ++) - { + for (int i = 0, l = nums.length; i < l; i++) { int ele = nums[i]; int req = target - ele; - if(map.keySet().contains(req)) - { + if (map.keySet().contains(req)) { result[0] = i; - if(ele == req) - { + if (ele == req) { int count = map.get(req); - if(count > 1) - { - for(int j = i + 1; j < l; j++) - { - if(nums[j] == req) - { + if (count > 1) { + for (int j = i + 1; j < l; j++) { + if (nums[j] == req) { result[1] = j; return result; } } } - } - else - { - for(int j = i + 1; j < l; j++) - { - if(nums[j] == req) - { + } else { + for (int j = i + 1; j < l; j++) { + if (nums[j] == req) { result[1] = j; return result; } diff --git a/problems/src/hashing/ValidAnagram.java b/problems/src/hashing/ValidAnagram.java index 3b01751f..da98099d 100644 --- a/problems/src/hashing/ValidAnagram.java +++ b/problems/src/hashing/ValidAnagram.java @@ -2,49 +2,45 @@ /** * Created by gouthamvidyapradhan on 10/03/2017. - Given two strings s and t, write a function to determine if t is an anagram of s. - - For example, - s = "anagram", t = "nagaram", return true. - s = "rat", t = "car", return false. - - Note: - You may assume the string contains only lowercase alphabets. - - Follow up: - What if the inputs contain unicode characters? How would you adapt your solution to such case? + * Given two strings s and t, write a function to determine if t is an anagram of s. + *

+ * For example, + * s = "anagram", t = "nagaram", return true. + * s = "rat", t = "car", return false. + *

+ * Note: + * You may assume the string contains only lowercase alphabets. + *

+ * Follow up: + * What if the inputs contain unicode characters? How would you adapt your solution to such case? */ -public class ValidAnagram -{ +public class ValidAnagram { private int[] S = new int[256]; private int[] T = new int[256]; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new ValidAnagram().isAnagram("anagram", "nagaram")); } - public boolean isAnagram(String s, String t) - { - if(s.length() != t.length()) return false; + public boolean isAnagram(String s, String t) { + if (s.length() != t.length()) return false; - for(int i = 0, l = s.length(); i < l; i ++) - { + for (int i = 0, l = s.length(); i < l; i++) { S[s.charAt(i)]++; } - for(int i = 0, l = t.length(); i < l; i ++) - { + for (int i = 0, l = t.length(); i < l; i++) { T[t.charAt(i)]++; } - for(int i = 0; i < 256; i ++) - { - if(S[i] != T[i]) return false; + for (int i = 0; i < 256; i++) { + if (S[i] != T[i]) return false; } return true; diff --git a/problems/src/heap/SlidingWindowMaximum.java b/problems/src/heap/SlidingWindowMaximum.java index f457524e..76682aa3 100644 --- a/problems/src/heap/SlidingWindowMaximum.java +++ b/problems/src/heap/SlidingWindowMaximum.java @@ -5,67 +5,61 @@ /** * Created by gouthamvidyapradhan on 10/03/2017. - Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. - - For example, - Given nums = [1,3,-1,-3,5,3,6,7], and k = 3. - - Window position Max - --------------- ----- - [1 3 -1] -3 5 3 6 7 3 - 1 [3 -1 -3] 5 3 6 7 3 - 1 3 [-1 -3 5] 3 6 7 5 - 1 3 -1 [-3 5 3] 6 7 5 - 1 3 -1 -3 [5 3 6] 7 6 - 1 3 -1 -3 5 [3 6 7] 7 - Therefore, return the max sliding window as [3,3,5,5,6,7]. - - Note: - You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array. + * Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. + *

+ * For example, + * Given nums = [1,3,-1,-3,5,3,6,7], and k = 3. + *

+ * Window position Max + * --------------- ----- + * [1 3 -1] -3 5 3 6 7 3 + * 1 [3 -1 -3] 5 3 6 7 3 + * 1 3 [-1 -3 5] 3 6 7 5 + * 1 3 -1 [-3 5 3] 6 7 5 + * 1 3 -1 -3 [5 3 6] 7 6 + * 1 3 -1 -3 5 [3 6 7] 7 + * Therefore, return the max sliding window as [3,3,5,5,6,7]. + *

+ * Note: + * You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array. */ -public class SlidingWindowMaximum -{ +public class SlidingWindowMaximum { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] a = {1, 3, 1, 2, 0, 5}; int[] result = new SlidingWindowMaximum().maxSlidingWindow(a, 3); - for(int i : result) + for (int i : result) System.out.print(i + " "); } /** - * * @param nums * @param k * @return */ - public int[] maxSlidingWindow(int[] nums, int k) - { + public int[] maxSlidingWindow(int[] nums, int k) { int[] result = new int[nums.length - (k - 1)]; - if(nums.length == 0) return new int[0]; + if (nums.length == 0) return new int[0]; Deque queue = new ArrayDeque<>(); - for(int i = 0, j = 0, l = nums.length; i < l; i ++) - { + for (int i = 0, j = 0, l = nums.length; i < l; i++) { int head = i - (k - 1); - if(head >= 0) - { + if (head >= 0) { //remove out of range - if(queue.peek() != null && queue.peek() < head) + if (queue.peek() != null && queue.peek() < head) queue.poll(); } - while(queue.peekLast() != null && nums[queue.peekLast()] <= nums[i]) - { + while (queue.peekLast() != null && nums[queue.peekLast()] <= nums[i]) { queue.pollLast(); } queue.offer(i); - if(i >= k - 1) + if (i >= k - 1) result[j++] = nums[queue.peek()]; } diff --git a/problems/src/heap/TheSkylineProblem.java b/problems/src/heap/TheSkylineProblem.java index 2b323ced..90bc186b 100644 --- a/problems/src/heap/TheSkylineProblem.java +++ b/problems/src/heap/TheSkylineProblem.java @@ -8,12 +8,12 @@ * A city's skyline is the outer contour of the silhouette formed by all the buildings in that city when viewed from a distance. * Now suppose you are given the locations and height of all the buildings as shown on a cityscape photo (Figure A), * write a program to output the skyline formed by these buildings collectively (Figure B). - * + *

*

* See below link for image. * https://leetcode.com/problems/the-skyline-problem/description/ *

- * + *

* Buildings Skyline Contour * The geometric information of each building is represented by a triplet of integers [Li, Ri, Hi], where Li and Ri are the x coordinates of the left and right edge of the ith building, respectively, and Hi is its height. It is guaranteed that 0 ≤ Li, Ri ≤ INT_MAX, 0 < Hi ≤ INT_MAX, and Ri - Li > 0. You may assume all buildings are perfect rectangles grounded on an absolutely flat surface at height 0. *

@@ -29,10 +29,32 @@ * The input list is already sorted in ascending order by the left x position Li. * The output list must be sorted by the x position. * There must be no consecutive horizontal lines of equal height in the output skyline. For instance, [...[2 3], [4 5], [7 5], [11 5], [12 7]...] is not acceptable; the three lines of height 5 should be merged into one in the final output as such: [...[2 3], [4 5], [12 7], ...] - * + *

+ * Solution: + * 1. Sort array of points. Each point here is either a start of a rectangle or end of a rectangle. + * 2. Maintain a priority queue of rectangles ordered by increasing order of height, if height of two rectangle is same then, + * order by left most start index. + * 3. For each point starting from left-most point: + * 3.a. Add all the rectangles which starts at this point. + * 3.b. Remove all the rectangles which ends at this point. Keep a max of height for each rectangle removed. + * 3.c. If the current priority queue is empty then, include current point (x, 0) to the result set. This indicates this was the last rectangle and after this + * there is a gap of at least 1 unit. + *

+ * If the max calculated in step b is greater than current max then, include current x and max height from priority queue to the result set. + * This indicates one of the larger rectangle's right edge intersects with a smaller one. + *

+ * If the max calculated in stop b is smaller then check if the peek element in priority queue has the left edge value equal to current point. If so, + * then this indicates that a new larger rectangle starts from this point therefore add this point to the result set. + * 4. Return the result set */ public class TheSkylineProblem { + /** + * Main method + * + * @param args + * @throws Exception + */ public static void main(String[] args) throws Exception { int[][] A = {{0, 30, 30}, {2, 9, 10}, {3, 7, 15}, {4, 8, 10}, {5, 12, 12}, {15, 20, 10}, {19, 24, 8}}; //int[][] A = {{2,9,10}, {3,9,11}, {4,9,12}, {5,9,13}}; @@ -41,7 +63,9 @@ public static void main(String[] args) throws Exception { } public List getSkyline(int[][] buildings) { - PriorityQueue pq = new PriorityQueue<>(Comparator.comparing(Rectangle::getH).reversed().thenComparing(Rectangle::getX1)); + PriorityQueue pq = new PriorityQueue<>(Comparator.comparing(Rectangle::getH) + .reversed() + .thenComparing(Rectangle::getX1)); //order by height, if height is same then, order by left most starting edge. List result = new ArrayList<>(); Set set = new HashSet<>(); for (int[] p : buildings) { @@ -54,7 +78,8 @@ public List getSkyline(int[][] buildings) { for (int i = 0, j = 0, l = points.size(); i < l; i++) { int curr = points.get(i); - for (int k = j; k < buildings.length; k++) { + + for (int k = j; k < buildings.length; k++) { //add all the rectangles that begin at this point int[] rectangle = buildings[k]; if (rectangle[0] == curr) { pq.offer(new Rectangle(rectangle[0], rectangle[1], rectangle[2])); @@ -64,7 +89,7 @@ public List getSkyline(int[][] buildings) { } } int max = Integer.MIN_VALUE; - while (!pq.isEmpty()) { + while (!pq.isEmpty()) { // remove all the rectangles that end at this point if (pq.peek().getX2() == curr) { Rectangle top = pq.poll(); max = Math.max(max, top.getH()); @@ -75,14 +100,12 @@ public List getSkyline(int[][] buildings) { } } if (pq.isEmpty()) { - result.add(makeNewPoint(curr, 0)); + result.add(makeNewPoint(curr, 0)); //This is the last rectangle after this there is a gap of at least one unit } else { if (max > pq.peek().getH()) { - result.add(makeNewPoint(curr, pq.peek().getH())); - } else if (max < pq.peek().getH()) { - if (pq.peek().getX1() == curr) { - result.add(makeNewPoint(curr, pq.peek().getH())); - } + result.add(makeNewPoint(curr, pq.peek().getH())); //one of the larger rectangle's right edge intersects with a smaller one + } else if (max < pq.peek().getH() && pq.peek().getX1() == curr) { + result.add(makeNewPoint(curr, pq.peek().getH())); //new larger rectangle begins at this point } } } diff --git a/problems/src/linked_list/DeleteNode.java b/problems/src/linked_list/DeleteNode.java index 50a5172a..b22be8cc 100644 --- a/problems/src/linked_list/DeleteNode.java +++ b/problems/src/linked_list/DeleteNode.java @@ -3,15 +3,17 @@ /** * Created by gouthamvidyapradhan on 04/07/2017. * Write a function to delete a node (except the tail) in a singly linked list, given only access to that node. - - Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function. - + *

+ * Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function. */ public class DeleteNode { public static class ListNode { int val; ListNode next; - ListNode(int x) { val = x; } + + ListNode(int x) { + val = x; + } } public static void main(String[] args) { @@ -20,7 +22,7 @@ public static void main(String[] args) { node.next.next = new ListNode(3); node.next.next.next = new ListNode(4); new DeleteNode().deleteNode(node.next.next); - while (node != null){ + while (node != null) { System.out.println(node.val); node = node.next; } @@ -30,7 +32,7 @@ public void deleteNode(ListNode node) { ListNode prev = node; ListNode last = node; ListNode next = node.next; - while(next != null){ + while (next != null) { last = prev; int temp = prev.val; prev.val = next.val; diff --git a/problems/src/linked_list/IntersectionOfTwoLists.java b/problems/src/linked_list/IntersectionOfTwoLists.java index 19cfbab6..5e9ae0c2 100644 --- a/problems/src/linked_list/IntersectionOfTwoLists.java +++ b/problems/src/linked_list/IntersectionOfTwoLists.java @@ -2,36 +2,33 @@ /** * Created by gouthamvidyapradhan on 24/02/2017. - Write a program to find the node at which the intersection of two singly linked lists begins. - - - For example, the following two linked lists: - - A: a1 → a2 - ↘ - c1 → c2 → c3 - ↗ - B: b1 → b2 → b3 - begin to intersect at node c1. - - - Notes: - - If the two linked lists have no intersection at all, return null. - The linked lists must retain their original structure after the function returns. - You may assume there are no cycles anywhere in the entire linked structure. - Your code should preferably run in O(n) time and use only O(1) memory. - + * Write a program to find the node at which the intersection of two singly linked lists begins. + *

+ *

+ * For example, the following two linked lists: + *

+ * A: a1 → a2 + * ↘ + * c1 → c2 → c3 + * ↗ + * B: b1 → b2 → b3 + * begin to intersect at node c1. + *

+ *

+ * Notes: + *

+ * If the two linked lists have no intersection at all, return null. + * The linked lists must retain their original structure after the function returns. + * You may assume there are no cycles anywhere in the entire linked structure. + * Your code should preferably run in O(n) time and use only O(1) memory. */ -public class IntersectionOfTwoLists -{ +public class IntersectionOfTwoLists { - public static class ListNode - { + public static class ListNode { int val; ListNode next; - ListNode(int x) - { + + ListNode(int x) { val = x; next = null; } @@ -39,35 +36,32 @@ public static class ListNode /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { ListNode node1 = new ListNode(2); ListNode node2 = new ListNode(3); node1.next = node2; System.out.println(new IntersectionOfTwoLists().getIntersectionNode(node1, node2)); } - public ListNode getIntersectionNode(ListNode headA, ListNode headB) - { - if(headA == null || headB == null) + public ListNode getIntersectionNode(ListNode headA, ListNode headB) { + if (headA == null || headB == null) return null; int l1len = 0, l2len = 0; ListNode temp1 = headA; - while(temp1 != null) - { + while (temp1 != null) { temp1 = temp1.next; - l1len ++; + l1len++; } temp1 = headB; - while(temp1 != null) - { + while (temp1 != null) { temp1 = temp1.next; - l2len ++; + l2len++; } @@ -75,30 +69,25 @@ public ListNode getIntersectionNode(ListNode headA, ListNode headB) ListNode temp2; - if(l1len > l2len) - { + if (l1len > l2len) { temp1 = headA; temp2 = headB; - } - else - { + } else { temp1 = headB; temp2 = headA; } - while(diff != 0) - { + while (diff != 0) { temp1 = temp1.next; diff--; } - while(!temp1.equals(temp2) ) - { + while (!temp1.equals(temp2)) { temp1 = temp1.next; temp2 = temp2.next; - if(temp1 == null || temp2 == null) return null; + if (temp1 == null || temp2 == null) return null; } - if(temp1.equals(temp2)) + if (temp1.equals(temp2)) return temp1; return null; } diff --git a/problems/src/linked_list/LinkedListCycle.java b/problems/src/linked_list/LinkedListCycle.java index ec218f89..72f5fa07 100644 --- a/problems/src/linked_list/LinkedListCycle.java +++ b/problems/src/linked_list/LinkedListCycle.java @@ -5,20 +5,19 @@ /** * Created by gouthamvidyapradhan on 23/02/2017. - Given a linked list, determine if it has a cycle in it. - - Follow up: - Can you solve it without using extra space? + * Given a linked list, determine if it has a cycle in it. + *

+ * Follow up: + * Can you solve it without using extra space? */ -public class LinkedListCycle -{ +public class LinkedListCycle { private static Set hashCode = new HashSet<>(); - static class ListNode - { + + static class ListNode { int val; ListNode next; - ListNode(int x) - { + + ListNode(int x) { val = x; next = null; } @@ -26,10 +25,10 @@ static class ListNode /** * Main method + * * @param args */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { ListNode node1 = new ListNode(1); ListNode node2 = new ListNode(2); ListNode node3 = new ListNode(3); @@ -39,19 +38,17 @@ public static void main(String[] args) throws Exception System.out.println(new LinkedListCycle().hasCycle(node1)); } - public boolean hasCycle(ListNode head) - { + public boolean hasCycle(ListNode head) { ListNode slow = head; ListNode fast = head; - while(slow != null && fast != null) - { + while (slow != null && fast != null) { slow = slow.next; fast = fast.next; - if(fast != null) + if (fast != null) fast = fast.next; else break; - if(fast != null && slow != null) - if(fast.equals(slow)) return true; + if (fast != null && slow != null) + if (fast.equals(slow)) return true; } return false; } diff --git a/problems/src/linked_list/MergeKSortedLists.java b/problems/src/linked_list/MergeKSortedLists.java index c15b5a80..8e3cd62f 100644 --- a/problems/src/linked_list/MergeKSortedLists.java +++ b/problems/src/linked_list/MergeKSortedLists.java @@ -2,16 +2,14 @@ /** * Created by gouthamvidyapradhan on 11/03/2017. - Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. + * Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. */ -public class MergeKSortedLists -{ - public static class ListNode - { +public class MergeKSortedLists { + public static class ListNode { int val; ListNode next; - ListNode(int x) - { + + ListNode(int x) { val = x; next = null; } @@ -19,11 +17,11 @@ public static class ListNode /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { ListNode node2 = new ListNode(-1); ListNode node3 = new ListNode(5); ListNode node4 = new ListNode(11); @@ -68,16 +66,14 @@ public static void main(String[] args) throws Exception ListNode result = new MergeKSortedLists().mergeKLists(list); } - public ListNode mergeKLists(ListNode[] lists) - { - if(lists.length == 0) return null; - if(lists.length == 1) return lists[0]; + public ListNode mergeKLists(ListNode[] lists) { + if (lists.length == 0) return null; + if (lists.length == 1) return lists[0]; return merge(lists, 0, lists.length - 1); } - private ListNode merge(ListNode[] lists, int s, int e) - { - if(s == e) return lists[s]; + private ListNode merge(ListNode[] lists, int s, int e) { + if (s == e) return lists[s]; int m = s + (e - s) / 2; ListNode left = merge(lists, s, m); ListNode right = merge(lists, m + 1, e); @@ -85,26 +81,22 @@ private ListNode merge(ListNode[] lists, int s, int e) ListNode headNode = new ListNode(0); headNode.next = left; prev = headNode; - if(left == null && right == null) return null; - else if(left == null) return right; - else if(right == null) return left; - while(left != null && right != null) - { - if(left.val > right.val) - { + if (left == null && right == null) return null; + else if (left == null) return right; + else if (right == null) return left; + while (left != null && right != null) { + if (left.val > right.val) { temp = right; right = right.next; prev.next = temp; temp.next = left; prev = prev.next; - } - else - { + } else { left = left.next; prev = prev.next; } } - if(left == null && right != null) + if (left == null && right != null) prev.next = right; return headNode.next; } diff --git a/problems/src/linked_list/MergeTwoSortedList.java b/problems/src/linked_list/MergeTwoSortedList.java index c0eba315..377ebf10 100644 --- a/problems/src/linked_list/MergeTwoSortedList.java +++ b/problems/src/linked_list/MergeTwoSortedList.java @@ -2,23 +2,20 @@ /** * Created by gouthamvidyapradhan on 18/03/2017. - Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. + * Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. */ -public class MergeTwoSortedList -{ - public static class ListNode - { +public class MergeTwoSortedList { + public static class ListNode { int val; ListNode next; - ListNode(int x) - { + + ListNode(int x) { val = x; next = null; } } - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { ListNode head = new ListNode(0); ListNode head1 = new ListNode(3); ListNode head2 = new ListNode(8); @@ -37,23 +34,19 @@ public static void main(String[] args) throws Exception ListNode newHead = new MergeTwoSortedList().mergeTwoLists(head, head3); ListNode link = newHead; - while(link != null) - { + while (link != null) { System.out.println(link.val); link = link.next; } } - public ListNode mergeTwoLists(ListNode l1, ListNode l2) - { - if(l1 == null) return l2; - else if(l2 == null) return l1; - if(l1.val <= l2.val) - { + + public ListNode mergeTwoLists(ListNode l1, ListNode l2) { + if (l1 == null) return l2; + else if (l2 == null) return l1; + if (l1.val <= l2.val) { l1.next = mergeTwoLists(l1.next, l2); return l1; - } - else - { + } else { l2.next = mergeTwoLists(l1, l2.next); return l2; } diff --git a/problems/src/linked_list/PaliandromeList.java b/problems/src/linked_list/PaliandromeList.java index 63c90e67..c1c930fe 100644 --- a/problems/src/linked_list/PaliandromeList.java +++ b/problems/src/linked_list/PaliandromeList.java @@ -2,32 +2,31 @@ /** * Created by gouthamvidyapradhan on 25/02/2017. - Given a singly linked list, determine if it is a palindrome. - - Follow up: - Could you do it in O(n) time and O(1) space? + * Given a singly linked list, determine if it is a palindrome. + *

+ * Follow up: + * Could you do it in O(n) time and O(1) space? */ -public class PaliandromeList -{ - public static class ListNode - { +public class PaliandromeList { + public static class ListNode { int val; ListNode next; - ListNode(int x) - { + + ListNode(int x) { val = x; next = null; } } ListNode headNode; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { ListNode node1 = new ListNode(1); //ListNode node2 = new ListNode(2); //ListNode node3 = new ListNode(3); @@ -42,23 +41,20 @@ public static void main(String[] args) throws Exception System.out.println(new PaliandromeList().isPalindrome(node1)); } - public boolean isPalindrome(ListNode head) - { + public boolean isPalindrome(ListNode head) { int length = 0, count = 0; - if(head == null) return true; + if (head == null) return true; ListNode temp = head; - while(temp != null) - { + while (temp != null) { temp = temp.next; length++; } - if(length == 1) return true; + if (length == 1) return true; int halfLen = length / 2; temp = head; - while(count < halfLen - 1) - { + while (count < halfLen - 1) { temp = temp.next; count++; } @@ -67,9 +63,8 @@ public boolean isPalindrome(ListNode head) temp.next = null; reverse(newHead); ListNode first = head, second = headNode; - for(int i = 0; i < halfLen; i ++) - { - if(first.val != second.val) + for (int i = 0; i < halfLen; i++) { + if (first.val != second.val) return false; first = first.next; second = second.next; @@ -77,10 +72,8 @@ public boolean isPalindrome(ListNode head) return true; } - private ListNode reverse(ListNode node) - { - if(node.next == null) - { + private ListNode reverse(ListNode node) { + if (node.next == null) { headNode = node; return node; } diff --git a/problems/src/linked_list/ReverseLinkedList.java b/problems/src/linked_list/ReverseLinkedList.java index 451b219b..36df8437 100644 --- a/problems/src/linked_list/ReverseLinkedList.java +++ b/problems/src/linked_list/ReverseLinkedList.java @@ -2,18 +2,16 @@ /** * Created by gouthamvidyapradhan on 24/02/2017. - Reverse a singly linked list. + * Reverse a singly linked list. */ -public class ReverseLinkedList -{ +public class ReverseLinkedList { private ListNode newHead; - public static class ListNode - { + public static class ListNode { int val; ListNode next; - ListNode(int x) - { + + ListNode(int x) { val = x; next = null; } @@ -21,11 +19,11 @@ public static class ListNode /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { ListNode node1 = new ListNode(1); ListNode node2 = new ListNode(2); ListNode node3 = new ListNode(3); @@ -41,18 +39,15 @@ public static void main(String[] args) throws Exception System.out.println(newNode.val); } - public ListNode reverseList(ListNode head) - { - if(head == null) return null; - else if(head.next == null) return head; + public ListNode reverseList(ListNode head) { + if (head == null) return null; + else if (head.next == null) return head; reverse(head).next = null; return newHead; } - private ListNode reverse(ListNode head) - { - if(head.next == null) - { + private ListNode reverse(ListNode head) { + if (head.next == null) { newHead = head; return head; } diff --git a/problems/src/linked_list/ReverseNodesKGroup.java b/problems/src/linked_list/ReverseNodesKGroup.java index fb058595..11dc19ca 100644 --- a/problems/src/linked_list/ReverseNodesKGroup.java +++ b/problems/src/linked_list/ReverseNodesKGroup.java @@ -3,88 +3,91 @@ /** * Created by gouthamvidyapradhan on 06/07/2017. * Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. - - k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. - - You may not alter the values in the nodes, only nodes itself may be changed. - - Only constant memory is allowed. - - For example, - Given this linked list: 1->2->3->4->5 - - For k = 2, you should return: 2->1->4->3->5 - - For k = 3, you should return: 3->2->1->4->5 - - - Solution: O(N) solution with constant space. - Recursively reverse a group of K nodes and for each group join the tail of the prev group to the head - of the next group. + *

+ * k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. + *

+ * You may not alter the values in the nodes, only nodes itself may be changed. + *

+ * Only constant memory is allowed. + *

+ * For example, + * Given this linked list: 1->2->3->4->5 + *

+ * For k = 2, you should return: 2->1->4->3->5 + *

+ * For k = 3, you should return: 3->2->1->4->5 + *

+ *

+ * Solution: O(N) solution with constant space. + * Recursively reverse a group of K nodes and for each group join the tail of the prev group to the head + * of the next group. */ public class ReverseNodesKGroup { public static class ListNode { int val; ListNode next; - ListNode(int x) { val = x; } + + ListNode(int x) { + val = x; + } } private ListNode newHead, newStart, prev; - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { 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); ListNode result = new ReverseNodesKGroup().reverseKGroup(node, 2); - while(result != null){ + while (result != null) { System.out.println(result.val + " "); result = result.next; } } public ListNode reverseKGroup(ListNode head, int k) { - if(head == null) return null; + if (head == null) return null; ListNode node = head; int count = 0; - while(node != null){ + while (node != null) { node = node.next; count++; } - if(k > count) return head; + if (k > count) return head; int N = count / k; newStart = head; ListNode tail = null; ListNode result = null; - while(N -- > 0){ + while (N-- > 0) { tail = reverse(newStart, 1, k); tail.next = null; - if(result == null) + if (result == null) result = newHead; //save the head only once - if(prev != null){ + if (prev != null) { prev.next = newHead; } prev = tail; } - if(tail != null) + if (tail != null) tail.next = newStart; return result; } /** * Reverse k nodes - * @param node head node + * + * @param node head node * @param count count - * @param k K + * @param k K * @return */ - private ListNode reverse(ListNode node, int count, int k){ - if(count == k){ + private ListNode reverse(ListNode node, int count, int k) { + if (count == k) { newStart = node.next; //new start node newHead = node; //mark this as the new head - } - else{ + } else { ListNode nNode = reverse(node.next, count + 1, k); nNode.next = node; } diff --git a/problems/src/linked_list/SwapNodesInPairs.java b/problems/src/linked_list/SwapNodesInPairs.java index fa65c7b3..4a9bba13 100644 --- a/problems/src/linked_list/SwapNodesInPairs.java +++ b/problems/src/linked_list/SwapNodesInPairs.java @@ -3,23 +3,24 @@ /** * Created by gouthamvidyapradhan on 13/08/2017. * Given a linked list, swap every two adjacent nodes and return its head. - - For example, - Given 1->2->3->4, you should return the list as 2->1->4->3. - - Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed. + *

+ * For example, + * Given 1->2->3->4, you should return the list as 2->1->4->3. + *

+ * Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed. */ public class SwapNodesInPairs { - public static class ListNode{ + public static class ListNode { int val; ListNode next; - ListNode(int x){ + + ListNode(int x) { val = x; } } - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { ListNode node = new ListNode(1); node.next = new ListNode(2); node.next.next = new ListNode(3); @@ -27,24 +28,24 @@ public static void main(String[] args) throws Exception{ node.next.next.next.next = new ListNode(5); node.next.next.next.next.next = new ListNode(6); ListNode head = new SwapNodesInPairs().swapPairs(node); - while(head != null){ + while (head != null) { System.out.println(head.val); head = head.next; } } public ListNode swapPairs(ListNode head) { - if(head == null || head.next == null) + if (head == null || head.next == null) return head; ListNode newHead = head.next; ListNode curr = head.next; ListNode prev = head; ListNode prevPrev = new ListNode(-1); //dummy node - while(curr != null){ + while (curr != null) { prev.next = curr.next; curr.next = prev; prevPrev.next = curr; - if(prev.next != null){ + if (prev.next != null) { curr = prev.next.next; prev = prev.next; prevPrev = prevPrev.next.next; diff --git a/problems/src/math/AddDigits.java b/problems/src/math/AddDigits.java index c7fb605e..596714e0 100644 --- a/problems/src/math/AddDigits.java +++ b/problems/src/math/AddDigits.java @@ -3,23 +3,22 @@ /** * Created by gouthamvidyapradhan on 02/08/2017. * Given a non-negative integer num, repeatedly add all its digits until the result has only one digit. - - For example: - - Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it. - - Follow up: - Could you do it without any loop/recursion in O(1) runtime? - + *

+ * For example: + *

+ * Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it. + *

+ * Follow up: + * Could you do it without any loop/recursion in O(1) runtime? */ public class AddDigits { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new AddDigits().addDigits(38)); } public int addDigits(int num) { - if(num == 0) return 0; + if (num == 0) return 0; return num % 9 == 0 ? 9 : num % 9; } diff --git a/problems/src/math/AddTwoNumbers.java b/problems/src/math/AddTwoNumbers.java index 1d30a8fa..a2387ab4 100644 --- a/problems/src/math/AddTwoNumbers.java +++ b/problems/src/math/AddTwoNumbers.java @@ -2,28 +2,25 @@ /** * Created by gouthamvidyapradhan on 13/03/2017. - You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. - - You may assume the two numbers do not contain any leading zero, except the number 0 itself. - - Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) - Output: 7 -> 0 -> 8 + * You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. + *

+ * You may assume the two numbers do not contain any leading zero, except the number 0 itself. + *

+ * Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) + * Output: 7 -> 0 -> 8 */ -public class AddTwoNumbers -{ - public static class ListNode - { +public class AddTwoNumbers { + public static class ListNode { int val; ListNode next; - ListNode(int x) - { + + ListNode(int x) { val = x; next = null; } } - public static void main(String[] args) - { + public static void main(String[] args) { ListNode node = new ListNode(2); node.next = new ListNode(4); node.next.next = new ListNode(4); @@ -35,16 +32,14 @@ public static void main(String[] args) ListNode result = new AddTwoNumbers().addTwoNumbers(node, node1); } - private ListNode addTwoNumbers(ListNode l1, ListNode l2) - { - if(l1 == null && l2 == null) return null; + private ListNode addTwoNumbers(ListNode l1, ListNode l2) { + if (l1 == null && l2 == null) return null; ListNode first = l1; ListNode second = l2; int carry = 0; ListNode head = new ListNode(0); ListNode prev = head; - while(first != null && second != null) - { + while (first != null && second != null) { int q = (first.val + second.val + carry) / 10; int r = (first.val + second.val + carry) % 10; carry = q; @@ -55,8 +50,7 @@ private ListNode addTwoNumbers(ListNode l1, ListNode l2) second = second.next; } - while(first != null) - { + while (first != null) { int q = (first.val + carry) / 10; int r = (first.val + carry) % 10; carry = q; @@ -66,8 +60,7 @@ private ListNode addTwoNumbers(ListNode l1, ListNode l2) first = first.next; } - while(second != null) - { + while (second != null) { int q = (second.val + carry) / 10; int r = (second.val + carry) % 10; carry = q; @@ -77,7 +70,7 @@ private ListNode addTwoNumbers(ListNode l1, ListNode l2) second = second.next; } - if(carry != 0) + if (carry != 0) prev.next = new ListNode(carry); return head.next; diff --git a/problems/src/math/CountPrimes.java b/problems/src/math/CountPrimes.java index 3b1c4c0a..a72140d1 100644 --- a/problems/src/math/CountPrimes.java +++ b/problems/src/math/CountPrimes.java @@ -4,39 +4,33 @@ /** * Created by gouthamvidyapradhan on 21/03/2017. - Description: - - Count the number of prime numbers less than a non-negative number, n. + * Description: + *

+ * Count the number of prime numbers less than a non-negative number, n. */ -public class CountPrimes -{ +public class CountPrimes { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new CountPrimes().countPrimes(999187)); } - public int countPrimes(int n) - { - if(n == 0 || n == 1 || n == 2) return 0; - else if(n == 3) return 1; + public int countPrimes(int n) { + if (n == 0 || n == 1 || n == 2) return 0; + else if (n == 3) return 1; BitSet set = new BitSet(); n = n - 1; - int sqRt = (int)Math.sqrt(n); + int sqRt = (int) Math.sqrt(n); int count = n; - for(int i = 2; i <= sqRt; i ++) - { - if(!set.get(i)) - { - for(int j = 2; (i * j) <= n; j ++) - { - if(!set.get(i * j)) - { - count --; + for (int i = 2; i <= sqRt; i++) { + if (!set.get(i)) { + for (int j = 2; (i * j) <= n; j++) { + if (!set.get(i * j)) { + count--; set.set(i * j); } } diff --git a/problems/src/math/ExcelSheetColumnTitle.java b/problems/src/math/ExcelSheetColumnTitle.java index 8c1c4175..21c43c4c 100644 --- a/problems/src/math/ExcelSheetColumnTitle.java +++ b/problems/src/math/ExcelSheetColumnTitle.java @@ -3,39 +3,41 @@ /** * Created by gouthamvidyapradhan on 12/08/2017. * Given a positive integer, return its corresponding column title as appear in an Excel sheet. - - For example: - - 1 -> A - 2 -> B - 3 -> C - ... - 26 -> Z - 27 -> AA - 28 -> AB + *

+ * For example: + *

+ * 1 -> A + * 2 -> B + * 3 -> C + * ... + * 26 -> Z + * 27 -> AA + * 28 -> AB */ public class ExcelSheetColumnTitle { private static final String CONST = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new ExcelSheetColumnTitle().convertToTitle(52)); } public String convertToTitle(int n) { StringBuilder ans = new StringBuilder(); - while(n > 0){ + while (n > 0) { int mod = n % 26; n /= 26; - if(mod == 0){ + if (mod == 0) { ans.append('Z'); n -= 1; - }else{ + } else { ans.append(CONST.charAt(mod - 1)); } } diff --git a/problems/src/math/RomanToInteger.java b/problems/src/math/RomanToInteger.java index 46067513..9b3a87d8 100644 --- a/problems/src/math/RomanToInteger.java +++ b/problems/src/math/RomanToInteger.java @@ -5,18 +5,19 @@ /** * Created by gouthamvidyapradhan on 12/08/2017. - * + *

* Given a roman numeral, convert it to an integer. - - Input is guaranteed to be within the range from 1 to 3999. + *

+ * Input is guaranteed to be within the range from 1 to 3999. */ public class RomanToInteger { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new RomanToInteger().romanToInt("DXCIX")); } @@ -32,11 +33,11 @@ public int romanToInt(String s) { String str = new StringBuilder(s).reverse().toString(); int sum = 0, prev = -1; - for(int i = 0, l = str.length(); i < l; i++){ + for (int i = 0, l = str.length(); i < l; i++) { int curr = map.get(str.charAt(i)); - if(curr < prev){ + if (curr < prev) { sum -= curr; - } else{ + } else { sum += curr; } prev = curr; diff --git a/problems/src/math/RotateFunction.java b/problems/src/math/RotateFunction.java index 775b5dc3..e0789341 100644 --- a/problems/src/math/RotateFunction.java +++ b/problems/src/math/RotateFunction.java @@ -2,55 +2,51 @@ /** * Created by gouthamvidyapradhan on 18/03/2017. - Given an array of integers A and let n to be its length. - - Assume Bk to be an array obtained by rotating the array A k positions clock-wise, we define a "rotation function" F on A as follow: - - F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1]. - - Calculate the maximum value of F(0), F(1), ..., F(n-1). - - Note: - n is guaranteed to be less than 105. - - Example: - - A = [4, 3, 2, 6] - - F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25 - F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16 - F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23 - F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26 - - So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26. + * Given an array of integers A and let n to be its length. + *

+ * Assume Bk to be an array obtained by rotating the array A k positions clock-wise, we define a "rotation function" F on A as follow: + *

+ * F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1]. + *

+ * Calculate the maximum value of F(0), F(1), ..., F(n-1). + *

+ * Note: + * n is guaranteed to be less than 105. + *

+ * Example: + *

+ * A = [4, 3, 2, 6] + *

+ * F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25 + * F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16 + * F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23 + * F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26 + *

+ * So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26. */ -public class RotateFunction -{ +public class RotateFunction { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] a = {4, 3, 2, 6}; System.out.println(new RotateFunction().maxRotateFunction(a)); } - public int maxRotateFunction(int[] A) - { - if(A.length == 0 || A.length == 1) return 0; + public int maxRotateFunction(int[] A) { + if (A.length == 0 || A.length == 1) return 0; int max = Integer.MIN_VALUE; int l = A.length; int sum = 0, prodSum = 0; - for(int i = 0; i < l; i ++) - { + for (int i = 0; i < l; i++) { prodSum += (A[i] * i); sum += A[i]; } max = Math.max(max, prodSum); - for(int i = 0; i < l - 1; i ++) - { + for (int i = 0; i < l - 1; i++) { prodSum = (prodSum - sum + A[i] + ((l - 1) * A[i])); max = Math.max(max, prodSum); } diff --git a/problems/src/math/WaterAndJugProblem.java b/problems/src/math/WaterAndJugProblem.java index c53af0ca..37572a85 100644 --- a/problems/src/math/WaterAndJugProblem.java +++ b/problems/src/math/WaterAndJugProblem.java @@ -5,31 +5,31 @@ /** * Created by gouthamvidyapradhan on 29/07/2017. * You are given two jugs with capacities x and y litres. There is an infinite amount of water supply available. You need to determine whether it is possible to measure exactly z litres using these two jugs. - - If z liters of water is measurable, you must have z liters of water contained within one or both buckets by the end. - - Operations allowed: - - Fill any of the jugs completely with water. - Empty any of the jugs. - Pour water from one jug into another till the other jug is completely full or the first jug itself is empty. - Example 1: (From the famous "Die Hard" example) - - Input: x = 3, y = 5, z = 4 - Output: True - Example 2: - - Input: x = 2, y = 6, z = 5 - Output: False - + *

+ * If z liters of water is measurable, you must have z liters of water contained within one or both buckets by the end. + *

+ * Operations allowed: + *

+ * Fill any of the jugs completely with water. + * Empty any of the jugs. + * Pour water from one jug into another till the other jug is completely full or the first jug itself is empty. + * Example 1: (From the famous "Die Hard" example) + *

+ * Input: x = 3, y = 5, z = 4 + * Output: True + * Example 2: + *

+ * Input: x = 2, y = 6, z = 5 + * Output: False */ public class WaterAndJugProblem { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new WaterAndJugProblem().canMeasureWater(0, 0, 1)); } diff --git a/problems/src/stack/LargestRectangleInHistogram.java b/problems/src/stack/LargestRectangleInHistogram.java index cbe14b4a..985b2e6e 100644 --- a/problems/src/stack/LargestRectangleInHistogram.java +++ b/problems/src/stack/LargestRectangleInHistogram.java @@ -5,43 +5,42 @@ /** * Created by gouthamvidyapradhan on 20/06/2017. * Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram. - - For example, - Given heights = [2,1,5,6,2,3], - return 10. (min of index 2 and 3 multiplied by two) - - Solution O(N): - - 1) Create an empty stack. - - 2) Start from first bar, and do following for every bar ‘hist[i]’ where ‘i’ varies from 0 to n-1. - a) If stack is empty or hist[i] is higher than the bar at top of stack, then push ‘i’ to stack. - b) If this bar is smaller than the top of stack, then keep removing the top of stack while top of the stack is greater. Let the removed bar be hist[tp]. - Calculate area of rectangle with hist[tp] as smallest bar. For hist[tp], the ‘left index’ is previous (previous to tp) item in stack and ‘right index’ is ‘i’ (current index). - - 3) If the stack is not empty, then one by one remove all bars from stack and do step 2.b for every removed bar. - + *

+ * For example, + * Given heights = [2,1,5,6,2,3], + * return 10. (min of index 2 and 3 multiplied by two) + *

+ * Solution O(N): + *

+ * 1) Create an empty stack. + *

+ * 2) Start from first bar, and do following for every bar ‘hist[i]’ where ‘i’ varies from 0 to n-1. + * a) If stack is empty or hist[i] is higher than the bar at top of stack, then push ‘i’ to stack. + * b) If this bar is smaller than the top of stack, then keep removing the top of stack while top of the stack is greater. Let the removed bar be hist[tp]. + * Calculate area of rectangle with hist[tp] as smallest bar. For hist[tp], the ‘left index’ is previous (previous to tp) item in stack and ‘right index’ is ‘i’ (current index). + *

+ * 3) If the stack is not empty, then one by one remove all bars from stack and do step 2.b for every removed bar. */ public class LargestRectangleInHistogram { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[] A = {2, 3}; System.out.println(new LargestRectangleInHistogram().largestRectangleArea(A)); } public int largestRectangleArea(int[] heights) { - if(heights.length == 0) return 0; + if (heights.length == 0) return 0; int maxArea = Integer.MIN_VALUE; Stack stack = new Stack<>(); int i = 0; - for(; i < heights.length; i ++) { - while(!stack.isEmpty() && heights[stack.peek()] >= heights[i]) { + for (; i < heights.length; i++) { + while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) { int top = stack.pop(); int base = stack.isEmpty() ? i : i - stack.peek() - 1; maxArea = Math.max(maxArea, base * heights[top]); } stack.push(i); } - while(!stack.isEmpty()) { + while (!stack.isEmpty()) { int top = stack.pop(); int base = stack.isEmpty() ? i : i - stack.peek() - 1; maxArea = Math.max(maxArea, base * heights[top]); diff --git a/problems/src/stack/MinStack.java b/problems/src/stack/MinStack.java index a5ea3f25..5cd66d68 100644 --- a/problems/src/stack/MinStack.java +++ b/problems/src/stack/MinStack.java @@ -4,42 +4,41 @@ /** * Created by gouthamvidyapradhan on 08/03/2017. - Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. - - push(x) -- Push element x onto stack. - pop() -- Removes the element on top of the stack. - top() -- Get the top element. - getMin() -- Retrieve the minimum element in the stack. - Example: - MinStack minStack = new MinStack(); - minStack.push(-2); - minStack.push(0); - minStack.push(-3); - minStack.getMin(); --> Returns -3. - minStack.pop(); - minStack.top(); --> Returns 0. - minStack.getMin(); --> Returns -2. + * Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. + *

+ * push(x) -- Push element x onto stack. + * pop() -- Removes the element on top of the stack. + * top() -- Get the top element. + * getMin() -- Retrieve the minimum element in the stack. + * Example: + * MinStack minStack = new MinStack(); + * minStack.push(-2); + * minStack.push(0); + * minStack.push(-3); + * minStack.getMin(); --> Returns -3. + * minStack.pop(); + * minStack.top(); --> Returns 0. + * minStack.getMin(); --> Returns -2. */ -public class MinStack -{ - class Node - { +public class MinStack { + class Node { int value, min; - Node(int value, int min) - { + + Node(int value, int min) { this.value = value; this.min = min; } } private Stack stack = new Stack<>(); + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { MinStack minStack = new MinStack(); minStack.push(-2); minStack.push(0); @@ -50,38 +49,30 @@ public static void main(String[] args) throws Exception System.out.println(minStack.getMin()); } - public MinStack() - { + public MinStack() { } - public void push(int x) - { + public void push(int x) { Node node; - if(!stack.isEmpty()) - { + if (!stack.isEmpty()) { Node top = stack.peek(); node = new Node(x, Math.min(top.min, x)); - } - else - { + } else { node = new Node(x, x); } stack.push(node); } - public void pop() - { + public void pop() { stack.pop(); } - public int top() - { + public int top() { return stack.peek().value; } - public int getMin() - { + public int getMin() { return stack.peek().min; } diff --git a/problems/src/stack/MyQueue.java b/problems/src/stack/MyQueue.java index 911a9bca..0b29d36e 100644 --- a/problems/src/stack/MyQueue.java +++ b/problems/src/stack/MyQueue.java @@ -5,21 +5,22 @@ /** * Created by gouthamvidyapradhan on 29/07/2017. * Implement the following operations of a queue using stacks. - - push(x) -- Push element x to the back of queue. - pop() -- Removes the element from in front of queue. - peek() -- Get the front element. - empty() -- Return whether the queue is empty. - - Notes: - You must use only standard operations of a stack -- which means only push to top, peek/pop from top, size, and is empty operations are valid. - Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack. - You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue). + *

+ * push(x) -- Push element x to the back of queue. + * pop() -- Removes the element from in front of queue. + * peek() -- Get the front element. + * empty() -- Return whether the queue is empty. + *

+ * Notes: + * You must use only standard operations of a stack -- which means only push to top, peek/pop from top, size, and is empty operations are valid. + * Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack. + * You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue). */ public class MyQueue { private Stack stack; - public static void main(String[] args) throws Exception{ + + public static void main(String[] args) throws Exception { MyQueue myQueue = new MyQueue(); myQueue.push(5); myQueue.push(12); @@ -32,43 +33,53 @@ public static void main(String[] args) throws Exception{ System.out.println(myQueue.pop()); } - /** Initialize your data structure here. */ + /** + * Initialize your data structure here. + */ public MyQueue() { stack = new Stack<>(); } - /** Push element x to the back of queue. */ + /** + * Push element x to the back of queue. + */ public void push(int x) { stack.push(x); } - /** Removes the element from in front of queue and returns that element. */ + /** + * Removes the element from in front of queue and returns that element. + */ public int pop() { Stack auxStack = new Stack<>(); - while(!stack.isEmpty()){ + while (!stack.isEmpty()) { auxStack.push(stack.pop()); } int result = auxStack.pop(); - while(!auxStack.isEmpty()){ + while (!auxStack.isEmpty()) { stack.push(auxStack.pop()); } return result; } - /** Get the front element. */ + /** + * Get the front element. + */ public int peek() { Stack auxStack = new Stack<>(); - while(!stack.isEmpty()){ + while (!stack.isEmpty()) { auxStack.push(stack.pop()); } int result = auxStack.peek(); - while(!auxStack.isEmpty()){ + while (!auxStack.isEmpty()) { stack.push(auxStack.pop()); } return result; } - /** Returns whether the queue is empty. */ + /** + * Returns whether the queue is empty. + */ public boolean empty() { return stack.isEmpty(); } diff --git a/problems/src/stack/ValidParentheses.java b/problems/src/stack/ValidParentheses.java index fdabe184..d3a6213a 100644 --- a/problems/src/stack/ValidParentheses.java +++ b/problems/src/stack/ValidParentheses.java @@ -6,22 +6,20 @@ /** * Created by gouthamvidyapradhan on 25/02/2017. - Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. - - The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not. + * Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. + *

+ * The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not. */ -public class ValidParentheses -{ - public static void main(String[] args) - { +public class ValidParentheses { + public static void main(String[] args) { System.out.println(hasBalancedBrackets("(h[e")); } + private static Map MAP = new HashMap<>(); // METHOD SIGNATURE BEGINS, THIS METHOD IS REQUIRED - public static int hasBalancedBrackets(String str) - { - if(str == null) return 1; + public static int hasBalancedBrackets(String str) { + if (str == null) return 1; MAP.put(')', '('); MAP.put('}', '{'); @@ -29,10 +27,8 @@ public static int hasBalancedBrackets(String str) MAP.put(']', '['); Stack stack = new Stack<>(); - for(int i = 0, l = str.length(); i < l; i ++) - { - switch (str.charAt(i)) - { + for (int i = 0, l = str.length(); i < l; i++) { + switch (str.charAt(i)) { case '(': case '{': case '[': @@ -44,9 +40,9 @@ public static int hasBalancedBrackets(String str) case '}': case ']': case '>': - if(stack.isEmpty()) return 0; + if (stack.isEmpty()) return 0; char top = stack.pop(); - if(top != MAP.get(str.charAt(i))) return 0; + if (top != MAP.get(str.charAt(i))) return 0; break; default: //ignore diff --git a/problems/src/string/CompareVersionNumbers.java b/problems/src/string/CompareVersionNumbers.java index 8d7a814a..82419240 100644 --- a/problems/src/string/CompareVersionNumbers.java +++ b/problems/src/string/CompareVersionNumbers.java @@ -5,46 +5,46 @@ /** * Created by pradhang on 7/11/2017. * Compare two version numbers version1 and version2. - If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0. - - You may assume that the version strings are non-empty and contain only digits and the . character. - The . character does not represent a decimal point and is used to separate number sequences. - For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision. - - Here is an example of version numbers ordering: - - 0.1 < 1.1 < 1.2 < 13.37 + * If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0. + *

+ * You may assume that the version strings are non-empty and contain only digits and the . character. + * The . character does not represent a decimal point and is used to separate number sequences. + * For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision. + *

+ * Here is an example of version numbers ordering: + *

+ * 0.1 < 1.1 < 1.2 < 13.37 */ public class CompareVersionNumbers { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new CompareVersionNumbers().compareVersion("1.11.1", "1.11")); } public int compareVersion(String version1, String version2) { StringTokenizer st1 = new StringTokenizer(version1, "."); StringTokenizer st2 = new StringTokenizer(version2, "."); - while(st1.hasMoreTokens() & st2.hasMoreTokens()){ + while (st1.hasMoreTokens() & st2.hasMoreTokens()) { int token1 = Integer.parseInt(st1.nextToken()); int token2 = Integer.parseInt(st2.nextToken()); - if(token1 > token2) + if (token1 > token2) return 1; - else if(token2 > token1) + else if (token2 > token1) return -1; } - if(st1.countTokens() > st2.countTokens()){ - while(st1.hasMoreTokens()){ - if(Integer.parseInt(st1.nextToken()) > 0) + if (st1.countTokens() > st2.countTokens()) { + while (st1.hasMoreTokens()) { + if (Integer.parseInt(st1.nextToken()) > 0) return 1; } - } - else if(st2.countTokens() > st1.countTokens()){ - while(st2.hasMoreTokens()){ - if(Integer.parseInt(st2.nextToken()) > 0) + } else if (st2.countTokens() > st1.countTokens()) { + while (st2.hasMoreTokens()) { + if (Integer.parseInt(st2.nextToken()) > 0) return -1; } } diff --git a/problems/src/string/ExcelSheetColumnNumber.java b/problems/src/string/ExcelSheetColumnNumber.java index db08bab8..9431f510 100644 --- a/problems/src/string/ExcelSheetColumnNumber.java +++ b/problems/src/string/ExcelSheetColumnNumber.java @@ -3,30 +3,31 @@ /** * Created by gouthamvidyapradhan on 07/07/2017. * Given a column title as appear in an Excel sheet, return its corresponding column number. - - For example: - - A -> 1 - B -> 2 - C -> 3 - ... - Z -> 26 - AA -> 27 - AB -> 28 + *

+ * For example: + *

+ * A -> 1 + * B -> 2 + * C -> 3 + * ... + * Z -> 26 + * AA -> 27 + * AB -> 28 */ public class ExcelSheetColumnNumber { String CONST = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - public static void main(String[] args) throws Exception{ + + public static void main(String[] args) throws Exception { System.out.println(new ExcelSheetColumnNumber().titleToNumber("AAB")); } public int titleToNumber(String s) { int total = 0; int j = 0; - for(int i = s.length() - 1; i >= 0; i --){ + for (int i = s.length() - 1; i >= 0; i--) { char c = s.charAt(i); int pos = CONST.indexOf(c) + 1; - int pow = (int)Math.pow(26, j++); + int pow = (int) Math.pow(26, j++); total += (pow * pos); } return total; diff --git a/problems/src/string/FirstUniqueCharacterInAString.java b/problems/src/string/FirstUniqueCharacterInAString.java index fc04dc06..08aa90ad 100644 --- a/problems/src/string/FirstUniqueCharacterInAString.java +++ b/problems/src/string/FirstUniqueCharacterInAString.java @@ -2,40 +2,38 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1. - - Examples: - - s = "leetcode" - return 0. - - s = "loveleetcode", - return 2. - Note: You may assume the string contain only lowercase letters. + * Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1. + *

+ * Examples: + *

+ * s = "leetcode" + * return 0. + *

+ * s = "loveleetcode", + * return 2. + * Note: You may assume the string contain only lowercase letters. */ -public class FirstUniqueCharacterInAString -{ +public class FirstUniqueCharacterInAString { int[] CHAR = new int[256]; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new FirstUniqueCharacterInAString().firstUniqChar("loveleetcode")); } - public int firstUniqChar(String s) - { - if(s == null || s.isEmpty()) return -1; + public int firstUniqChar(String s) { + if (s == null || s.isEmpty()) return -1; - for(int i = 0, l = s.length(); i < l; i ++) + for (int i = 0, l = s.length(); i < l; i++) CHAR[s.charAt(i)]++; - for(int i = 0, l = s.length(); i < l; i ++) - { - if(CHAR[s.charAt(i)] == 1) + for (int i = 0, l = s.length(); i < l; i++) { + if (CHAR[s.charAt(i)] == 1) return i; } diff --git a/problems/src/string/ImplementStrStr.java b/problems/src/string/ImplementStrStr.java index b273a814..374908d8 100644 --- a/problems/src/string/ImplementStrStr.java +++ b/problems/src/string/ImplementStrStr.java @@ -3,34 +3,34 @@ /** * Created by gouthamvidyapradhan on 24/06/2017. * Implement strStr(). - - Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. - - Solution O(N ^ 2) + *

+ * Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. + *

+ * Solution O(N ^ 2) */ public class ImplementStrStr { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new ImplementStrStr().strStr("AABB", "")); } public int strStr(String haystack, String needle) { - if(haystack.isEmpty() && needle.isEmpty()) return 0; - if(needle.isEmpty()) return 0; - for(int i = 0, l = haystack.length(); i < l; i ++){ - if(haystack.charAt(i) == needle.charAt(0)){ - if(isEqual(haystack, needle, i)) + if (haystack.isEmpty() && needle.isEmpty()) return 0; + if (needle.isEmpty()) return 0; + for (int i = 0, l = haystack.length(); i < l; i++) { + if (haystack.charAt(i) == needle.charAt(0)) { + if (isEqual(haystack, needle, i)) return i; } } return -1; } - private boolean isEqual(String haystack, String needle, int i){ + private boolean isEqual(String haystack, String needle, int i) { int hL = haystack.length(); int nL = needle.length(); int j = 0; - while(i < hL && j < nL){ - if(haystack.charAt(i) != needle.charAt(j)) + while (i < hL && j < nL) { + if (haystack.charAt(i) != needle.charAt(j)) return false; i++; j++; diff --git a/problems/src/string/RepeatedSubstringPattern.java b/problems/src/string/RepeatedSubstringPattern.java index 0245e4a6..9acc361a 100644 --- a/problems/src/string/RepeatedSubstringPattern.java +++ b/problems/src/string/RepeatedSubstringPattern.java @@ -2,59 +2,54 @@ /** * Created by gouthamvidyapradhan on 25/03/2017. - Given a non-empty string check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. You may assume the given string consists of lowercase English letters only and its length will not exceed 10000. - - Example 1: - Input: "abab" - - Output: True - - Explanation: It's the substring "ab" twice. - Example 2: - Input: "aba" - - Output: False - Example 3: - Input: "abcabcabcabc" - - Output: True - - Explanation: It's the substring "abc" four times. (And the substring "abcabc" twice.) + * Given a non-empty string check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. You may assume the given string consists of lowercase English letters only and its length will not exceed 10000. + *

+ * Example 1: + * Input: "abab" + *

+ * Output: True + *

+ * Explanation: It's the substring "ab" twice. + * Example 2: + * Input: "aba" + *

+ * Output: False + * Example 3: + * Input: "abcabcabcabc" + *

+ * Output: True + *

+ * Explanation: It's the substring "abc" four times. (And the substring "abcabc" twice.) */ -public class RepeatedSubstringPattern -{ +public class RepeatedSubstringPattern { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new RepeatedSubstringPattern().repeatedSubstringPattern("a")); } - public boolean repeatedSubstringPattern(String s) - { + public boolean repeatedSubstringPattern(String s) { boolean found; - for(int i = 1, l = s.length(); i < l; i ++) - { + for (int i = 1, l = s.length(); i < l; i++) { found = true; String subI = s.substring(0, i); int j = i; - if(j >= l) return false; - while(j < l) - { - if((j + i) >= l + 1) + if (j >= l) return false; + while (j < l) { + if ((j + i) >= l + 1) return false; - String subJ = s.substring(j , j + i); - if(!subI.equals(subJ)) - { + String subJ = s.substring(j, j + i); + if (!subI.equals(subJ)) { found = false; break; } j += i; } - if(found) return true; + if (found) return true; } return false; } diff --git a/problems/src/string/ReverseWordsII.java b/problems/src/string/ReverseWordsII.java index 0f6de4de..a948fa7b 100644 --- a/problems/src/string/ReverseWordsII.java +++ b/problems/src/string/ReverseWordsII.java @@ -2,76 +2,65 @@ /** * Created by gouthamvidyapradhan on 21/03/2017. - Given an input string, reverse the string word by word. A word is defined as a sequence of non-space characters. - - The input string does not contain leading or trailing spaces and the words are always separated by a single space. - - For example, - Given s = "the sky is blue", - return "blue is sky the". - - Could you do it in-place without allocating extra space? + * Given an input string, reverse the string word by word. A word is defined as a sequence of non-space characters. + *

+ * The input string does not contain leading or trailing spaces and the words are always separated by a single space. + *

+ * For example, + * Given s = "the sky is blue", + * return "blue is sky the". + *

+ * Could you do it in-place without allocating extra space? */ -public class ReverseWordsII -{ +public class ReverseWordsII { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - char[] c = {'t','h','e', ' ', 's', 'k', 'y', ' ', 'i', 's', ' ', 'b', 'l', 'u', 'e'}; + public static void main(String[] args) throws Exception { + char[] c = {'t', 'h', 'e', ' ', 's', 'k', 'y', ' ', 'i', 's', ' ', 'b', 'l', 'u', 'e'}; new ReverseWordsII().reverseWords(c); for (char i : c) System.out.print(i); } - public void reverseWords(char[] s) - { - for(int i = 0, j = s.length - 1; i < j; i ++, j --) - { + public void reverseWords(char[] s) { + for (int i = 0, j = s.length - 1; i < j; i++, j--) { char temp = s[i]; s[i] = s[j]; s[j] = temp; } - for(int i = 0, j = 0, l = s.length; i < l;) - { - if(s[i] == ' ') - { - if(s[i - 1] == ' ') - { + for (int i = 0, j = 0, l = s.length; i < l; ) { + if (s[i] == ' ') { + if (s[i - 1] == ' ') { j = i; - i ++; j ++; - } - else - { + i++; + j++; + } else { i = i - 1; - for(int p = j, q = i; p < q; p ++, q--) - { + for (int p = j, q = i; p < q; p++, q--) { char temp = s[p]; s[p] = s[q]; s[q] = temp; } i = i + 1; j = i; - i ++; j ++; + i++; + j++; } - } - else if(i == l - 1) - { - for(int p = j, q = i; p < q; p ++, q--) - { + } else if (i == l - 1) { + for (int p = j, q = i; p < q; p++, q--) { char temp = s[p]; s[p] = s[q]; s[q] = temp; } j = i; - i ++; j ++; - } - else - { - i ++; + i++; + j++; + } else { + i++; } } } diff --git a/problems/src/string/ReverseWordsInAString.java b/problems/src/string/ReverseWordsInAString.java index 9d4822bb..a29b6850 100644 --- a/problems/src/string/ReverseWordsInAString.java +++ b/problems/src/string/ReverseWordsInAString.java @@ -7,40 +7,40 @@ /** * Created by gouthamvidyapradhan on 04/07/2017. * Given an input string, reverse the string word by word. - - For example, - Given s = "the sky is blue", - return "blue is sky the". - - Clarification: - What constitutes a word? - A sequence of non-space characters constitutes a word. - Could the input string contain leading or trailing spaces? - Yes. However, your reversed string should not contain leading or trailing spaces. - How about multiple spaces between two words? - Reduce them to a single space in the reversed string. + *

+ * For example, + * Given s = "the sky is blue", + * return "blue is sky the". + *

+ * Clarification: + * What constitutes a word? + * A sequence of non-space characters constitutes a word. + * Could the input string contain leading or trailing spaces? + * Yes. However, your reversed string should not contain leading or trailing spaces. + * How about multiple spaces between two words? + * Reduce them to a single space in the reversed string. */ public class ReverseWordsInAString { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new ReverseWordsInAString().reverseWords(" the sky is blue")); } public String reverseWords(String s) { - if(s == null || s.isEmpty()) return ""; + if (s == null || s.isEmpty()) return ""; StringBuilder sb = new StringBuilder(s.trim()); String reverse = sb.reverse().toString(); StringTokenizer st = new StringTokenizer(reverse, " "); List list = new ArrayList<>(); - while(st.hasMoreTokens()){ + while (st.hasMoreTokens()) { list.add(st.nextToken()); } - for(int i = 0, l = list.size(); i < l; i ++){ + for (int i = 0, l = list.size(); i < l; i++) { String str = list.get(i); String newStr = new StringBuilder(str).reverse().toString(); list.set(i, newStr); } StringBuilder result = new StringBuilder(); - for(String str : list){ + for (String str : list) { result.append(str).append(" "); } return result.toString().trim(); diff --git a/problems/src/string/SimplifyPath.java b/problems/src/string/SimplifyPath.java index ebd3be19..7905249d 100644 --- a/problems/src/string/SimplifyPath.java +++ b/problems/src/string/SimplifyPath.java @@ -6,46 +6,46 @@ /** * Created by gouthamvidyapradhan on 28/07/2017. - * + *

* Given an absolute path for a file (Unix-style), simplify it. - - For example, - path = "/home/", => "/home" - path = "/a/./b/../../c/", => "/c" - - Corner Cases: - Did you consider the case where path = "/../"? - In this case, you should return "/". - Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/". - In this case, you should ignore redundant slashes and return "/home/foo". + *

+ * For example, + * path = "/home/", => "/home" + * path = "/a/./b/../../c/", => "/c" + *

+ * Corner Cases: + * Did you consider the case where path = "/../"? + * In this case, you should return "/". + * Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/". + * In this case, you should ignore redundant slashes and return "/home/foo". */ public class SimplifyPath { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new SimplifyPath().simplifyPath("/home/")); } public String simplifyPath(String path) { - if(path == null || path.isEmpty()) return "/"; + if (path == null || path.isEmpty()) return "/"; StringTokenizer st = new StringTokenizer(path, "/"); Deque dQueue = new ArrayDeque<>(); - while(st.hasMoreTokens()){ + while (st.hasMoreTokens()) { String token = st.nextToken(); - if(token.trim().equals("..")){ - if(!dQueue.isEmpty()) + if (token.trim().equals("..")) { + if (!dQueue.isEmpty()) dQueue.pop(); - } else if(token.trim().equals(".")){ + } else if (token.trim().equals(".")) { //ignore - } - else dQueue.push(token); + } else dQueue.push(token); } - if(dQueue.isEmpty()) return "/"; + if (dQueue.isEmpty()) return "/"; StringBuilder finalStr = new StringBuilder(); - while(!dQueue.isEmpty()){ + while (!dQueue.isEmpty()) { finalStr.append("/").append(dQueue.removeLast()); } return finalStr.toString(); diff --git a/problems/src/string/StringToInteger.java b/problems/src/string/StringToInteger.java index e172f121..f9d790b0 100644 --- a/problems/src/string/StringToInteger.java +++ b/problems/src/string/StringToInteger.java @@ -2,67 +2,55 @@ /** * Created by gouthamvidyapradhan on 21/03/2017. - Implement atoi to convert a string to an integer. - - Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases. - - Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front. + * Implement atoi to convert a string to an integer. + *

+ * Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases. + *

+ * Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front. */ -public class StringToInteger -{ +public class StringToInteger { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new StringToInteger().myAtoi(" 2147483649a sdfasdf")); } - public int myAtoi(String str) - { + public int myAtoi(String str) { boolean isPositive = true; - if(str == null || str.trim().isEmpty()) return 0; + if (str == null || str.trim().isEmpty()) return 0; str = str.trim(); - if(str.charAt(0) == '+') - { + if (str.charAt(0) == '+') { isPositive = true; str = str.substring(1, str.length()); - } - else if(str.charAt(0) == '-') - { + } else if (str.charAt(0) == '-') { isPositive = false; str = str.substring(1, str.length()); - } - - else if(str.charAt(0) > '9' || str.charAt(0) < '0') + } else if (str.charAt(0) > '9' || str.charAt(0) < '0') return 0; int i = 0; - for(int l = str.length(); i < l; i ++) - { - if(str.charAt(i) > '9' || str.charAt(i) < '0') + for (int l = str.length(); i < l; i++) { + if (str.charAt(i) > '9' || str.charAt(i) < '0') break; } str = str.substring(0, i); long num = 0; - for(int j = 0, l = str.length(); j < l; j++) - { + for (int j = 0, l = str.length(); j < l; j++) { int n = (str.charAt(j) - '0'); num *= 10; num += n; - if(isPositive) - { - if(num > Integer.MAX_VALUE) return Integer.MAX_VALUE; - } - else - { - if((num * -1) < Integer.MIN_VALUE) return Integer.MIN_VALUE; + if (isPositive) { + if (num > Integer.MAX_VALUE) return Integer.MAX_VALUE; + } else { + if ((num * -1) < Integer.MIN_VALUE) return Integer.MIN_VALUE; } } - if(isPositive) - return (int)num; - else return (int)(num * -1); + if (isPositive) + return (int) num; + else return (int) (num * -1); } diff --git a/problems/src/string/TextJustification.java b/problems/src/string/TextJustification.java index 420bd24c..74c35307 100644 --- a/problems/src/string/TextJustification.java +++ b/problems/src/string/TextJustification.java @@ -5,72 +5,61 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified. - - You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly L characters. - - Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right. - - For the last line of text, it should be left justified and no extra space is inserted between words. - - For example, - words: ["This", "is", "an", "example", "of", "text", "justification."] - L: 16. - - Return the formatted lines as: - [ - "This is an", - "example of text", - "justification. " - ] - Note: Each word is guaranteed not to exceed L in length. + * Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified. + *

+ * You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly L characters. + *

+ * Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right. + *

+ * For the last line of text, it should be left justified and no extra space is inserted between words. + *

+ * For example, + * words: ["This", "is", "an", "example", "of", "text", "justification."] + * L: 16. + *

+ * Return the formatted lines as: + * [ + * "This is an", + * "example of text", + * "justification. " + * ] + * Note: Each word is guaranteed not to exceed L in length. */ -public class TextJustification -{ - public List fullJustify(String[] words, int L) - { +public class TextJustification { + public List fullJustify(String[] words, int L) { int wCount = 0, charCount = 0; List line = new ArrayList<>(); List result = new ArrayList<>(); StringBuilder sb = new StringBuilder(); - for(int i = 0, l = words.length; i < l; i++) - { + for (int i = 0, l = words.length; i < l; i++) { String next = words[i]; - if( (L - (charCount + wCount)) >= next.length()) - { + if ((L - (charCount + wCount)) >= next.length()) { line.add(next); charCount += next.length(); wCount++; - } - else - { + } else { //justify and add to list sb.append(line.get(0)); StringBuilder space = new StringBuilder(); - if(line.size() > 1) - { + if (line.size() > 1) { int spaceCount = (L - charCount) / (wCount - 1); int remaining = (L - charCount) % (wCount - 1); - for(int j = 0; j < spaceCount; j++) + for (int j = 0; j < spaceCount; j++) space.append(' '); - for(int k = 1, kl = line.size(); k < kl; k++) - { + for (int k = 1, kl = line.size(); k < kl; k++) { sb.append(space); - if(remaining > 0) - { + if (remaining > 0) { sb.append(' '); --remaining; } sb.append(line.get(k)); } - } - else - { + } else { int balance = L - (charCount + (wCount - 1)); - for(int j = 0; j < balance; j ++) + for (int j = 0; j < balance; j++) sb.append(' '); } result.add(sb.toString()); @@ -81,17 +70,15 @@ public List fullJustify(String[] words, int L) wCount = 1; } } - if(!line.isEmpty()) - { + if (!line.isEmpty()) { sb.append(line.get(0)); - for(int i = 1, l = line.size(); i < l; i++) - { + for (int i = 1, l = line.size(); i < l; i++) { sb.append(' '); sb.append(line.get(i)); } } int balance = L - (charCount + (wCount - 1)); - for(int i = 0; i < balance; i ++) + for (int i = 0; i < balance; i++) sb.append(' '); result.add(sb.toString()); return result; diff --git a/problems/src/string/ValidPalindrome.java b/problems/src/string/ValidPalindrome.java index 1a565826..3144d001 100644 --- a/problems/src/string/ValidPalindrome.java +++ b/problems/src/string/ValidPalindrome.java @@ -3,40 +3,39 @@ /** * Created by gouthamvidyapradhan on 13/07/2017. * Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. - - For example, - "A man, a plan, a canal: Panama" is a palindrome. - "race a car" is not a palindrome. - - Note: - Have you consider that the string might be empty? This is a good question to ask during an interview. - - For the purpose of this problem, we define empty string as valid palindrome. - - + *

+ * For example, + * "A man, a plan, a canal: Panama" is a palindrome. + * "race a car" is not a palindrome. + *

+ * Note: + * Have you consider that the string might be empty? This is a good question to ask during an interview. + *

+ * For the purpose of this problem, we define empty string as valid palindrome. */ public class ValidPalindrome { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new ValidPalindrome().isPalindrome("989 ")); } public boolean isPalindrome(String s) { - if(s == null || s.isEmpty()) return true; + if (s == null || s.isEmpty()) return true; s = s.toLowerCase(); - for(int i = 0,j = s.length() - 1; i < j; ){ + for (int i = 0, j = s.length() - 1; i < j; ) { char f = s.charAt(i); char l = s.charAt(j); - if(!(f >= 'a' && f <= 'z') && !(f >= '0' && f <= '9')){ + if (!(f >= 'a' && f <= 'z') && !(f >= '0' && f <= '9')) { i++; continue; } - if(!(l >= 'a' && l <= 'z') && !(l >= '0' && l <= '9')){ + if (!(l >= 'a' && l <= 'z') && !(l >= '0' && l <= '9')) { j--; continue; } - if(f != l) + if (f != l) return false; - i++; j --; + i++; + j--; } return true; } diff --git a/problems/src/string/ZigZagConversion.java b/problems/src/string/ZigZagConversion.java index b017431e..f88c9aff 100644 --- a/problems/src/string/ZigZagConversion.java +++ b/problems/src/string/ZigZagConversion.java @@ -6,51 +6,50 @@ /** * Created by gouthamvidyapradhan on 19/05/2017. - The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) - - P A H N - A P L S I I G - Y I R - And then read line by line: "PAHNAPLSIIGYIR" - Write the code that will take a string and make this conversion given a number of rows: - - string convert(string text, int nRows); - convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR". + * The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) + *

+ * P A H N + * A P L S I I G + * Y I R + * And then read line by line: "PAHNAPLSIIGYIR" + * Write the code that will take a string and make this conversion given a number of rows: + *

+ * string convert(string text, int nRows); + * convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR". */ -public class ZigZagConversion -{ +public class ZigZagConversion { /** * Main method + * * @param args */ - public static void main(String[] args) - { + public static void main(String[] args) { System.out.println(new ZigZagConversion().convert("PAYPALISHIRING", 5)); } /** * Convert and return the result - * @param s input string + * + * @param s input string * @param numRows max rows * @return Result string */ public String convert(String s, int numRows) { - if(s == null || s.length() <= numRows || numRows == 1) return s; + if (s == null || s.length() <= numRows || numRows == 1) return s; List list = new ArrayList<>(); char[] A = new char[numRows]; int direction = 1; // 1 indicates forward, 0 indicates backwards int n = 1; A[0] = s.charAt(0); - for(int j = 1; j < numRows;) { - if(n >= s.length()) break; + for (int j = 1; j < numRows; ) { + if (n >= s.length()) break; A[j] = s.charAt(n++); - if(j == numRows - 1) { + if (j == numRows - 1) { list.add(String.valueOf(A)); A = new char[numRows]; Arrays.fill(A, ' '); direction = 0; - } - else if(j == 0) { + } else if (j == 0) { list.add(String.valueOf(A)); A = new char[numRows]; Arrays.fill(A, ' '); @@ -58,11 +57,11 @@ else if(j == 0) { } j = direction == 1 ? j + 1 : j - 1; } - if(!String.valueOf(A).trim().isEmpty()) + if (!String.valueOf(A).trim().isEmpty()) list.add(String.valueOf(A)); char[] arr = new char[s.length()]; int k = 0; - for(int j = 0; j < numRows; j ++) { + for (int j = 0; j < numRows; j++) { for (String aList : list) { if (aList.charAt(j) != ' ') arr[k++] = aList.charAt(j); diff --git a/problems/src/tree/BinarayTreeRightSideView.java b/problems/src/tree/BinarayTreeRightSideView.java index d4aa5ad9..821cd279 100644 --- a/problems/src/tree/BinarayTreeRightSideView.java +++ b/problems/src/tree/BinarayTreeRightSideView.java @@ -5,37 +5,39 @@ /** * Created by gouthamvidyapradhan on 12/03/2017. - Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom. - - For example: - Given the following binary tree, - 1 <--- - / \ - 2 3 <--- - \ \ - 5 4 <--- - You should return [1, 3, 4]. + * Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom. + *

+ * For example: + * Given the following binary tree, + * 1 <--- + * / \ + * 2 3 <--- + * \ \ + * 5 4 <--- + * You should return [1, 3, 4]. */ -public class BinarayTreeRightSideView -{ - public static class TreeNode - { +public class BinarayTreeRightSideView { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private int maxHeigh = Integer.MIN_VALUE; List list = new ArrayList<>(); + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(2); root.left = new TreeNode(3); root.right = new TreeNode(4); @@ -49,19 +51,15 @@ public static void main(String[] args) throws Exception List list = new BinarayTreeRightSideView().rightSideView(root); } - public List rightSideView(TreeNode root) - { - if(root == null) return list; + public List rightSideView(TreeNode root) { + if (root == null) return list; dfs(root, 0); return list; } - private void dfs(TreeNode node, int height) - { - if(node != null) - { - if(height > maxHeigh) - { + private void dfs(TreeNode node, int height) { + if (node != null) { + if (height > maxHeigh) { list.add(node.val); maxHeigh = height; } diff --git a/problems/src/tree/BinaryTreeInorderTraversal.java b/problems/src/tree/BinaryTreeInorderTraversal.java index f2314336..42aedb08 100644 --- a/problems/src/tree/BinaryTreeInorderTraversal.java +++ b/problems/src/tree/BinaryTreeInorderTraversal.java @@ -1,33 +1,36 @@ package tree; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; /** * Created by gouthamvidyapradhan on 06/08/2017. * Given a binary tree, return the inorder traversal of its nodes' values. - - For example: - Given binary tree [1,null,2,3], - 1 - \ - 2 - / - 3 - return [1,3,2]. - - Note: Recursive solution is trivial, could you do it iteratively? - - + *

+ * For example: + * Given binary tree [1,null,2,3], + * 1 + * \ + * 2 + * / + * 3 + * return [1,3,2]. + *

+ * Note: Recursive solution is trivial, could you do it iteratively? */ public class BinaryTreeInorderTraversal { public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(3); root.left = new TreeNode(4); root.left.left = new TreeNode(5); @@ -45,8 +48,8 @@ public List inorderTraversal(TreeNode root) { Stack stack = new Stack<>(); TreeNode curr = root; List result = new ArrayList<>(); - while(curr != null || !stack.isEmpty()){ - while(curr != null){ + while (curr != null || !stack.isEmpty()) { + while (curr != null) { stack.push(curr); curr = curr.left; } diff --git a/problems/src/tree/BinaryTreeMaximumPathSum.java b/problems/src/tree/BinaryTreeMaximumPathSum.java index 2180737a..c2d5ce30 100644 --- a/problems/src/tree/BinaryTreeMaximumPathSum.java +++ b/problems/src/tree/BinaryTreeMaximumPathSum.java @@ -2,35 +2,38 @@ /** * Created by gouthamvidyapradhan on 03/04/2017. - Given a binary tree, find the maximum path sum. - - For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root. - - For example: - Given the below binary tree, - - 1 - / \ - 2 3 - Return 6. + * Given a binary tree, find the maximum path sum. + *

+ * For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root. + *

+ * For example: + * Given the below binary tree, + *

+ * 1 + * / \ + * 2 3 + * Return 6. */ -public class BinaryTreeMaximumPathSum -{ +public class BinaryTreeMaximumPathSum { public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private int max = Integer.MIN_VALUE; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(5); root.left = new TreeNode(4); root.left.left = new TreeNode(3); @@ -40,16 +43,15 @@ public static void main(String[] args) throws Exception root.right.left.left = new TreeNode(9); System.out.println(new BinaryTreeMaximumPathSum().maxPathSum(root)); } - public int maxPathSum(TreeNode root) - { - if(root == null) return 0; + + public int maxPathSum(TreeNode root) { + if (root == null) return 0; dfs(root); return max; } - private int dfs(TreeNode root) - { - if(root == null) return 0; + private int dfs(TreeNode root) { + if (root == null) return 0; int left = dfs(root.left); int right = dfs(root.right); max = Math.max(max, root.val); diff --git a/problems/src/tree/BoundaryOfBinaryTree.java b/problems/src/tree/BoundaryOfBinaryTree.java index b219798b..a4a96f34 100644 --- a/problems/src/tree/BoundaryOfBinaryTree.java +++ b/problems/src/tree/BoundaryOfBinaryTree.java @@ -4,66 +4,69 @@ /** * Created by gouthamvidyapradhan on 27/03/2017. - Given a binary tree, return the values of its boundary in anti-clockwise direction starting from root. Boundary includes left boundary, leaves, and right boundary in order without duplicate nodes. - - Left boundary is defined as the path from root to the left-most node. Right boundary is defined as the path from root to the right-most node. If the root doesn't have left subtree or right subtree, then the root itself is left boundary or right boundary. Note this definition only applies to the input binary tree, and not applies to any subtrees. - - The left-most node is defined as a leaf node you could reach when you always firstly travel to the left subtree if exists. If not, travel to the right subtree. Repeat until you reach a leaf node. - - The right-most node is also defined by the same way with left and right exchanged. - - Example 1 - Input: - 1 - \ - 2 - / \ - 3 4 - - Ouput: - [1, 3, 4, 2] - - Explanation: - The root doesn't have left subtree, so the root itself is left boundary. - The leaves are node 3 and 4. - The right boundary are node 1,2,4. Note the anti-clockwise direction means you should output reversed right boundary. - So order them in anti-clockwise without duplicates and we have [1,3,4,2]. - Example 2 - Input: - ____1_____ - / \ - 2 3 - / \ / - 4 5 6 - / \ / \ - 7 8 9 10 - - Ouput: - [1,2,4,7,8,9,10,6,3] - - Explanation: - The left boundary are node 1,2,4. (4 is the left-most node according to definition) - The leaves are node 4,7,8,9,10. - The right boundary are node 1,3,6,10. (10 is the right-most node). - So order them in anti-clockwise without duplicate nodes we have [1,2,4,7,8,9,10,6,3]. + * Given a binary tree, return the values of its boundary in anti-clockwise direction starting from root. Boundary includes left boundary, leaves, and right boundary in order without duplicate nodes. + *

+ * Left boundary is defined as the path from root to the left-most node. Right boundary is defined as the path from root to the right-most node. If the root doesn't have left subtree or right subtree, then the root itself is left boundary or right boundary. Note this definition only applies to the input binary tree, and not applies to any subtrees. + *

+ * The left-most node is defined as a leaf node you could reach when you always firstly travel to the left subtree if exists. If not, travel to the right subtree. Repeat until you reach a leaf node. + *

+ * The right-most node is also defined by the same way with left and right exchanged. + *

+ * Example 1 + * Input: + * 1 + * \ + * 2 + * / \ + * 3 4 + *

+ * Ouput: + * [1, 3, 4, 2] + *

+ * Explanation: + * The root doesn't have left subtree, so the root itself is left boundary. + * The leaves are node 3 and 4. + * The right boundary are node 1,2,4. Note the anti-clockwise direction means you should output reversed right boundary. + * So order them in anti-clockwise without duplicates and we have [1,3,4,2]. + * Example 2 + * Input: + * ____1_____ + * / \ + * 2 3 + * / \ / + * 4 5 6 + * / \ / \ + * 7 8 9 10 + *

+ * Ouput: + * [1,2,4,7,8,9,10,6,3] + *

+ * Explanation: + * The left boundary are node 1,2,4. (4 is the left-most node according to definition) + * The leaves are node 4,7,8,9,10. + * The right boundary are node 1,3,6,10. (10 is the right-most node). + * So order them in anti-clockwise without duplicate nodes we have [1,2,4,7,8,9,10,6,3]. */ -public class BoundaryOfBinaryTree -{ +public class BoundaryOfBinaryTree { public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private Set done = new HashSet<>(); + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(1); /*root.right = new TreeNode(2); root.right.right = new TreeNode(3); @@ -82,18 +85,15 @@ public static void main(String[] args) throws Exception System.out.println(new BoundaryOfBinaryTree().boundaryOfBinaryTree(root)); } - public List boundaryOfBinaryTree(TreeNode root) - { - if(root == null) return new ArrayList<>(); + public List boundaryOfBinaryTree(TreeNode root) { + if (root == null) return new ArrayList<>(); List antiClockwiseCollection = new ArrayList<>(); List collection = new ArrayList<>(); - if(root.left != null) + if (root.left != null) leftShoulder(root, collection); - else - { - if(!done.contains(root)) - { + else { + if (!done.contains(root)) { done.add(root); collection.add(root.val); } @@ -105,12 +105,10 @@ public List boundaryOfBinaryTree(TreeNode root) antiClockwiseCollection.addAll(collection); collection.clear(); - if(root.right != null) + if (root.right != null) rightShoulder(root, collection); - else - { - if(!done.contains(root)) - { + else { + if (!done.contains(root)) { done.add(root); collection.add(root.val); } @@ -118,42 +116,36 @@ public List boundaryOfBinaryTree(TreeNode root) Stack stack = new Stack<>(); stack.addAll(collection); - while(!stack.isEmpty()) + while (!stack.isEmpty()) antiClockwiseCollection.add(stack.pop()); return new ArrayList<>(antiClockwiseCollection); } - private void leftShoulder(TreeNode node, List list) - { - if(node == null) return; - if(!done.contains(node)) - { + private void leftShoulder(TreeNode node, List list) { + if (node == null) return; + if (!done.contains(node)) { list.add(node.val); done.add(node); } - if(node.left != null) leftShoulder(node.left, list); - else if(node.right != null) leftShoulder(node.right, list); + if (node.left != null) leftShoulder(node.left, list); + else if (node.right != null) leftShoulder(node.right, list); } - private void rightShoulder(TreeNode node, List list) - { - if(node == null) return; - if(!done.contains(node)) - { + private void rightShoulder(TreeNode node, List list) { + if (node == null) return; + if (!done.contains(node)) { list.add(node.val); done.add(node); } - if(node.right != null) rightShoulder(node.right, list); - else if(node.left != null) rightShoulder(node.left, list); + if (node.right != null) rightShoulder(node.right, list); + else if (node.left != null) rightShoulder(node.left, list); } - private void leafNode(TreeNode node, List list) - { - if(node == null) return; - if(node.left == null && node.right == null) - if(!done.contains(node)) - { + private void leafNode(TreeNode node, List list) { + if (node == null) return; + if (node.left == null && node.right == null) + if (!done.contains(node)) { list.add(node.val); done.add(node); } diff --git a/problems/src/tree/ClosestBinarySearchTreeValue.java b/problems/src/tree/ClosestBinarySearchTreeValue.java index 3576b231..b64113fa 100644 --- a/problems/src/tree/ClosestBinarySearchTreeValue.java +++ b/problems/src/tree/ClosestBinarySearchTreeValue.java @@ -3,25 +3,26 @@ /** * Created by gouthamvidyapradhan on 10/05/2017. * Given a non-empty binary search tree and a target value, find the value in the BST that is closest to the target. - - Note: - Given target value is a floating point. - You are guaranteed to have only one unique value in the BST that is closest to the target. - - Solution: Simple dfs recursive algorithm to find the closest match. - Worst case time complexity is O(h) where h is height of the tree + *

+ * Note: + * Given target value is a floating point. + * You are guaranteed to have only one unique value in the BST that is closest to the target. + *

+ * Solution: Simple dfs recursive algorithm to find the closest match. + * Worst case time complexity is O(h) where h is height of the tree */ -public class ClosestBinarySearchTreeValue -{ +public class ClosestBinarySearchTreeValue { /** * TreeNode */ - public static class TreeNode - { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private double absDiff = Double.MAX_VALUE; @@ -29,11 +30,11 @@ public static class TreeNode /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(10); root.left = new TreeNode(9); root.left.left = new TreeNode(8); @@ -42,19 +43,18 @@ public static void main(String[] args) throws Exception /** * Find closest - * @param root Root node + * + * @param root Root node * @param target double target * @return closest value */ - public int closestValue(TreeNode root, double target) - { - if(root == null) return closest; - if(Math.abs(target - root.val) < absDiff) - { + public int closestValue(TreeNode root, double target) { + if (root == null) return closest; + if (Math.abs(target - root.val) < absDiff) { absDiff = Math.abs(target - root.val); closest = root.val; } - if(root.val > target) + if (root.val > target) return closestValue(root.left, target); else return closestValue(root.right, target); } diff --git a/problems/src/tree/ConstructStringFromBinaryTree.java b/problems/src/tree/ConstructStringFromBinaryTree.java index c83708f3..d390eb03 100644 --- a/problems/src/tree/ConstructStringFromBinaryTree.java +++ b/problems/src/tree/ConstructStringFromBinaryTree.java @@ -3,52 +3,54 @@ /** * Created by gouthamvidyapradhan on 10/06/2017. * Accepted - You need to construct a string consists of parenthesis and integers from a binary tree with the preorder traversing way. - - The null node needs to be represented by empty parenthesis pair "()". And you need to omit all the empty parenthesis pairs that don't affect the one-to-one mapping relationship between the string and the original binary tree. - - Example 1: - Input: Binary tree: [1,2,3,4] - 1 - / \ - 2 3 - / - 4 - - Output: "1(2(4))(3)" - - Explanation: Originallay it needs to be "1(2(4)())(3()())", - but you need to omit all the unnecessary empty parenthesis pairs. - And it will be "1(2(4))(3)". - Example 2: - Input: Binary tree: [1,2,3,null,4] - 1 - / \ - 2 3 - \ - 4 - - Output: "1(2()(4))(3)" - - Explanation: Almost the same as the first example, - except we can't omit the first parenthesis pair to break the one-to-one mapping relationship between the input and the output. + * You need to construct a string consists of parenthesis and integers from a binary tree with the preorder traversing way. + *

+ * The null node needs to be represented by empty parenthesis pair "()". And you need to omit all the empty parenthesis pairs that don't affect the one-to-one mapping relationship between the string and the original binary tree. + *

+ * Example 1: + * Input: Binary tree: [1,2,3,4] + * 1 + * / \ + * 2 3 + * / + * 4 + *

+ * Output: "1(2(4))(3)" + *

+ * Explanation: Originallay it needs to be "1(2(4)())(3()())", + * but you need to omit all the unnecessary empty parenthesis pairs. + * And it will be "1(2(4))(3)". + * Example 2: + * Input: Binary tree: [1,2,3,null,4] + * 1 + * / \ + * 2 3 + * \ + * 4 + *

+ * Output: "1(2()(4))(3)" + *

+ * Explanation: Almost the same as the first example, + * except we can't omit the first parenthesis pair to break the one-to-one mapping relationship between the input and the output. */ -public class ConstructStringFromBinaryTree -{ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } +public class ConstructStringFromBinaryTree { + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode t = new TreeNode(1); t.left = new TreeNode(2); t.left.left = new TreeNode(4); @@ -56,17 +58,16 @@ public static void main(String[] args) throws Exception System.out.println(new ConstructStringFromBinaryTree().tree2str(t)); } - public String tree2str(TreeNode t) - { - if(t == null) return ""; + public String tree2str(TreeNode t) { + if (t == null) return ""; String left = tree2str(t.left); String right = tree2str(t.right); - if(left.equals("") && right.equals("")) + if (left.equals("") && right.equals("")) return String.valueOf(t.val); - if(left.equals("")) + if (left.equals("")) left = "()"; else left = "(" + left + ")"; - if(!right.equals("")) + if (!right.equals("")) right = "(" + right + ")"; return t.val + left + right; } diff --git a/problems/src/tree/ConvertSortedArrayToBST.java b/problems/src/tree/ConvertSortedArrayToBST.java index 4690acec..5c9f7bbe 100644 --- a/problems/src/tree/ConvertSortedArrayToBST.java +++ b/problems/src/tree/ConvertSortedArrayToBST.java @@ -2,32 +2,31 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given an array where elements are sorted in ascending order, convert it to a height balanced BST. + * Given an array where elements are sorted in ascending order, convert it to a height balanced BST. */ -public class ConvertSortedArrayToBST -{ - public class TreeNode - { +public class ConvertSortedArrayToBST { + public class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - public TreeNode sortedArrayToBST(int[] nums) - { - if(nums.length == 0) return null; + public TreeNode sortedArrayToBST(int[] nums) { + if (nums.length == 0) return null; return build(0, nums.length - 1, nums); } - private TreeNode build(int s, int e, int[] nums) - { - if(s > e) return null; + private TreeNode build(int s, int e, int[] nums) { + if (s > e) return null; int m = (e - s) / 2; int node = nums[s + m]; TreeNode root = new TreeNode(node); - if(s == e) + if (s == e) return root; root.left = build(s, s + m - 1, nums); diff --git a/problems/src/tree/FindBottomLeftTreeValue.java b/problems/src/tree/FindBottomLeftTreeValue.java index 83509ee5..0624e351 100644 --- a/problems/src/tree/FindBottomLeftTreeValue.java +++ b/problems/src/tree/FindBottomLeftTreeValue.java @@ -3,43 +3,45 @@ /** * Created by gouthamvidyapradhan on 30/08/2017. * Given a binary tree, find the leftmost value in the last row of the tree. - - Example 1: - Input: - - 2 - / \ - 1 3 - - Output: - 1 - Example 2: - Input: - - 1 - / \ - 2 3 - / / \ - 4 5 6 - / - 7 - - Output: - 7 - Note: You may assume the tree (i.e., the given root node) is not NULL. - - + *

+ * Example 1: + * Input: + *

+ * 2 + * / \ + * 1 3 + *

+ * Output: + * 1 + * Example 2: + * Input: + *

+ * 1 + * / \ + * 2 3 + * / / \ + * 4 5 6 + * / + * 7 + *

+ * Output: + * 7 + * Note: You may assume the tree (i.e., the given root node) is not NULL. */ public class FindBottomLeftTreeValue { private int max = 0, result; + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(1); root.left = new TreeNode(2); root.left.left = new TreeNode(4); @@ -55,9 +57,9 @@ public int findBottomLeftValue(TreeNode root) { return result; } - private void preorder(TreeNode node, int level){ - if(node != null){ - if(level > max){ + private void preorder(TreeNode node, int level) { + if (node != null) { + if (level > max) { result = node.val; max = level; } diff --git a/problems/src/tree/FlattenBinaryTree.java b/problems/src/tree/FlattenBinaryTree.java index b4b06ffb..65024e51 100644 --- a/problems/src/tree/FlattenBinaryTree.java +++ b/problems/src/tree/FlattenBinaryTree.java @@ -1,63 +1,67 @@ package tree; + /** * Created by gouthamvidyapradhan on 04/07/2017. * Given a binary tree, flatten it to a linked list in-place. - - For example, - Given - - 1 - / \ - 2 5 - / \ \ - 3 4 6 - - The flattened tree should look like: - 1 - \ - 2 - \ - 3 - \ - 4 - \ - 5 - \ - 6 - - Solution: Do a pre-order traversal and maintain head and tail of a linked list at each recursive step. - i. Join the current node to the head of the left sub-list to form the current node as the new head. - ii. Join the tail of the left sub-list to the head of the right sub-list. - iii. Mark the left of the current node as null + *

+ * For example, + * Given + *

+ * 1 + * / \ + * 2 5 + * / \ \ + * 3 4 6 + *

+ * The flattened tree should look like: + * 1 + * \ + * 2 + * \ + * 3 + * \ + * 4 + * \ + * 5 + * \ + * 6 + *

+ * Solution: Do a pre-order traversal and maintain head and tail of a linked list at each recursive step. + * i. Join the current node to the head of the left sub-list to form the current node as the new head. + * ii. Join the tail of the left sub-list to the head of the right sub-list. + * iii. Mark the left of the current node as null */ public class FlattenBinaryTree { /** * Class to keep track of head and tail */ - private class LinkNode{ + private class LinkNode { TreeNode head; TreeNode tail; - LinkNode(TreeNode head, TreeNode tail){ + + LinkNode(TreeNode head, TreeNode tail) { this.head = head; this.tail = tail; } } - public static class TreeNode - { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(3); root.left = new TreeNode(2); root.right = new TreeNode(1); new FlattenBinaryTree().flatten(root); - System.out.print(root.val+ " "); + System.out.print(root.val + " "); System.out.print(root.right.val + " "); System.out.print(root.right.right.val); } @@ -66,23 +70,20 @@ public void flatten(TreeNode root) { preOrder(root); } - private LinkNode preOrder(TreeNode node){ - if(node == null) return null; + private LinkNode preOrder(TreeNode node) { + if (node == null) return null; LinkNode left = preOrder(node.left); LinkNode right = preOrder(node.right); LinkNode lNode; - if(left == null && right == null){ + if (left == null && right == null) { lNode = new LinkNode(node, node); - } - else if(left == null){ + } else if (left == null) { node.right = right.head; lNode = new LinkNode(node, right.tail); - } - else if(right == null){ + } else if (right == null) { node.right = left.head; lNode = new LinkNode(node, left.tail); - } - else { + } else { node.right = left.head; left.tail.right = right.head; lNode = new LinkNode(node, right.tail); diff --git a/problems/src/tree/InorderSuccessorInBST.java b/problems/src/tree/InorderSuccessorInBST.java index 6f214dc8..79399792 100644 --- a/problems/src/tree/InorderSuccessorInBST.java +++ b/problems/src/tree/InorderSuccessorInBST.java @@ -2,31 +2,32 @@ /** * Created by gouthamvidyapradhan on 14/05/2017. - Given a binary search tree and a node in it, find the in-order successor of that node in the BST. - - Note: If the given node has no in-order successor in the tree, return null. - - Solution: The below solution works with worst case time complexity of O(h) where h is the height of the tree. - If the current node is <= target_node, recursively iterate the right of the current node. - else if the current node is > target_node then mark the current node as the successor and recursively iterate the left of the current node. + * Given a binary search tree and a node in it, find the in-order successor of that node in the BST. + *

+ * Note: If the given node has no in-order successor in the tree, return null. + *

+ * Solution: The below solution works with worst case time complexity of O(h) where h is the height of the tree. + * If the current node is <= target_node, recursively iterate the right of the current node. + * else if the current node is > target_node then mark the current node as the successor and recursively iterate the left of the current node. */ -public class InorderSuccessorInBST -{ - public static class TreeNode - { +public class InorderSuccessorInBST { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(10); root.left = new TreeNode(5); root.left.left = new TreeNode(3); @@ -37,33 +38,33 @@ public static void main(String[] args) throws Exception root.right.left.right = new TreeNode(14); root.right.right = new TreeNode(17); TreeNode ans = new InorderSuccessorInBST().inorderSuccessor(root, root.right.left.right); - if(ans != null) + if (ans != null) System.out.println(ans.val); else System.out.println(ans); } /** * Find successor + * * @param root root node - * @param p target + * @param p target * @return successor */ - public TreeNode inorderSuccessor(TreeNode root, TreeNode p) - { + public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { return inOrder(root, p, null); } /** * Inorder traversal - * @param curr current node - * @param target target node + * + * @param curr current node + * @param target target node * @param successor successor * @return successor node */ - private TreeNode inOrder(TreeNode curr, TreeNode target, TreeNode successor) - { - if(curr == null) return successor; - if(curr.val <= target.val) + private TreeNode inOrder(TreeNode curr, TreeNode target, TreeNode successor) { + if (curr == null) return successor; + if (curr.val <= target.val) return inOrder(curr.right, target, successor); return inOrder(curr.left, target, curr); //make the current node as successor } diff --git a/problems/src/tree/LCA.java b/problems/src/tree/LCA.java index 9cfd76b5..c34799f9 100644 --- a/problems/src/tree/LCA.java +++ b/problems/src/tree/LCA.java @@ -2,47 +2,47 @@ /** * Created by gouthamvidyapradhan on 21/03/2017. - 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 v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” - - _______3______ - / \ - ___5__ ___1__ - / \ / \ - 6 _2 0 8 - / \ - 7 4 - For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition. + * 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 v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” + *

+ * _______3______ + * / \ + * ___5__ ___1__ + * / \ / \ + * 6 _2 0 8 + * / \ + * 7 4 + * For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition. */ -public class LCA -{ +public class LCA { public class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } - } + + TreeNode(int x) { + val = x; + } + } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { } - public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) - { - if(root != null) - { - if(root.equals(p) || root.equals(q)) return root; + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root != null) { + if (root.equals(p) || root.equals(q)) return root; TreeNode left = lowestCommonAncestor(root.left, p, q); TreeNode right = lowestCommonAncestor(root.right, p, q); - if(left != null && right != null) return root; - else if(left != null) return left; + if (left != null && right != null) return root; + else if (left != null) return left; else return right; } return null; diff --git a/problems/src/tree/LargestBSTSubtree.java b/problems/src/tree/LargestBSTSubtree.java index 69b18bfe..43c6dfe8 100644 --- a/problems/src/tree/LargestBSTSubtree.java +++ b/problems/src/tree/LargestBSTSubtree.java @@ -2,37 +2,34 @@ /** * Created by gouthamvidyapradhan on 08/05/2017. - * + *

* Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest means subtree with largest number of nodes in it. - - Note: - A subtree must include all of its descendants. - Here's an example: - 10 - / \ - 5 15 - / \ \ - 1 8 7 - The Largest BST Subtree in this case is the highlighted one (5-1-8). - The return value is the subtree's size, which is 3. - - Follow up: - Can you figure out ways to solve it with O(n) time complexity? - - Solution: The below solution works with O(n). Validate the BST property from the leaf node and increment the count, as soon as a violation - of BST property is found terminate the count. - * + *

+ * Note: + * A subtree must include all of its descendants. + * Here's an example: + * 10 + * / \ + * 5 15 + * / \ \ + * 1 8 7 + * The Largest BST Subtree in this case is the highlighted one (5-1-8). + * The return value is the subtree's size, which is 3. + *

+ * Follow up: + * Can you figure out ways to solve it with O(n) time complexity? + *

+ * Solution: The below solution works with O(n). Validate the BST property from the leaf node and increment the count, as soon as a violation + * of BST property is found terminate the count. */ -public class LargestBSTSubtree -{ +public class LargestBSTSubtree { /** * Range class */ - private class Range - { + private class Range { int min, max, count; - Range(int min, int max, int count) - { + + Range(int min, int max, int count) { this.min = min; this.max = max; this.count = count; @@ -42,12 +39,14 @@ private class Range /** * TreeNode */ - public static class TreeNode - { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } /** @@ -57,11 +56,11 @@ public static class TreeNode /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(10); root.left = new TreeNode(9); root.left.left = new TreeNode(8); @@ -70,54 +69,48 @@ public static void main(String[] args) throws Exception /** * Largest subtree count + * * @param root root node * @return count */ - public int largestBSTSubtree(TreeNode root) - { + public int largestBSTSubtree(TreeNode root) { getCount(root); return count; } /** * Get count + * * @param node root node * @return Range */ - private Range getCount(TreeNode node) - { - if(node == null) return null; + private Range getCount(TreeNode node) { + if (node == null) return null; Range left = getCount(node.left); Range right = getCount(node.right); - if(left == null && right == null) - { + if (left == null && right == null) { count = Math.max(count, 1); return new Range(node.val, node.val, 1); - } - else if(left == null) - { - if(node.val < right.min && right.count != -1) //check for -1 ensures that there is no violation of BST property + } else if (left == null) { + if (node.val < right.min && right.count != -1) //check for -1 ensures that there is no violation of BST property return countMaxAndBuildNewRange(right.count + 1, node.val, right.max); - } - else if(right == null) - { - if(node.val > left.max && left.count != -1) + } else if (right == null) { + if (node.val > left.max && left.count != -1) return countMaxAndBuildNewRange(left.count + 1, left.min, node.val); - } - else if(node.val > left.max && node.val < right.min && right.count != -1 && left.count != -1) + } else if (node.val > left.max && node.val < right.min && right.count != -1 && left.count != -1) return countMaxAndBuildNewRange(left.count + right.count + 1, left.min, right.max); return new Range(0, 0, -1); //violation of BST property } /** * Record max and build new range + * * @param sum total sum * @param min min * @param max max * @return new Range */ - private Range countMaxAndBuildNewRange(int sum, int min, int max) - { + private Range countMaxAndBuildNewRange(int sum, int min, int max) { count = Math.max(count, sum); return new Range(min, max, sum); } diff --git a/problems/src/tree/LowestCommonAncestorBST.java b/problems/src/tree/LowestCommonAncestorBST.java index 3ba76954..d8e9091c 100644 --- a/problems/src/tree/LowestCommonAncestorBST.java +++ b/problems/src/tree/LowestCommonAncestorBST.java @@ -2,45 +2,44 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. - - According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” - - _______6______ - / \ - ___2__ ___8__ - / \ / \ - 0 _4 7 9 - / \ - 3 5 - For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition. + * Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. + *

+ * According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” + *

+ * _______6______ + * / \ + * ___2__ ___8__ + * / \ / \ + * 0 _4 7 9 + * / \ + * 3 5 + * For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition. */ -public class LowestCommonAncestorBST -{ - class TreeNode - { +public class LowestCommonAncestorBST { + class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { } - private TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) - { - if(root == null) return null; + private TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == null) return null; - if(p.val == root.val || q.val == root.val) return root; + if (p.val == root.val || q.val == root.val) return root; - else if((p.val < root.val && q.val > root.val) || (q.val < root.val && p.val > root.val)) + else if ((p.val < root.val && q.val > root.val) || (q.val < root.val && p.val > root.val)) return root; - else if(p.val < root.val && q.val < root.val) + else if (p.val < root.val && q.val < root.val) return lowestCommonAncestor(root.left, p, q); else diff --git a/problems/src/tree/MaximumBinaryTree.java b/problems/src/tree/MaximumBinaryTree.java index 8af8cc6f..4af5a666 100644 --- a/problems/src/tree/MaximumBinaryTree.java +++ b/problems/src/tree/MaximumBinaryTree.java @@ -3,27 +3,26 @@ /** * Created by gouthamvidyapradhan on 19/08/2017. * Given an integer array with no duplicates. A maximum tree building on this array is defined as follow: - - The root is the maximum number in the array. - The left subtree is the maximum tree constructed from left part subarray divided by the maximum number. - The right subtree is the maximum tree constructed from right part subarray divided by the maximum number. - Construct the maximum tree by the given array and output the root node of this tree. - - Example 1: - Input: [3,2,1,6,0,5] - Output: return the tree root node representing the following tree: - - 6 - / \ - 3 5 - \ / - 2 0 - \ - 1 - - Note: - The size of the given array will be in the range [1,1000]. - + *

+ * The root is the maximum number in the array. + * The left subtree is the maximum tree constructed from left part subarray divided by the maximum number. + * The right subtree is the maximum tree constructed from right part subarray divided by the maximum number. + * Construct the maximum tree by the given array and output the root node of this tree. + *

+ * Example 1: + * Input: [3,2,1,6,0,5] + * Output: return the tree root node representing the following tree: + *

+ * 6 + * / \ + * 3 5 + * \ / + * 2 0 + * \ + * 1 + *

+ * Note: + * The size of the given array will be in the range [1,1000]. */ public class MaximumBinaryTree { @@ -31,17 +30,22 @@ public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private int[][] max; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ - int[] nums = {3,2,1,6,0,5}; + public static void main(String[] args) throws Exception { + int[] nums = {3, 2, 1, 6, 0, 5}; TreeNode root = new MaximumBinaryTree().constructMaximumBinaryTree(nums); System.out.println(root.val); //print root } @@ -51,22 +55,22 @@ public TreeNode constructMaximumBinaryTree(int[] nums) { max = new int[nums.length][nums.length]; //pre-fill with initial values - for(int i = 0; i < nums.length; i ++){ + for (int i = 0; i < nums.length; i++) { max[i][i] = i; } //pre-calculate max for range index - for(int i = 0; i < nums.length; i ++){ - for(int j = i + 1; j < nums.length; j++){ - max[i][j] = nums[max[i][j - 1]] > nums[j] ? max[i][j - 1] : j; + for (int i = 0; i < nums.length; i++) { + for (int j = i + 1; j < nums.length; j++) { + max[i][j] = nums[max[i][j - 1]] > nums[j] ? max[i][j - 1] : j; } } return build(0, nums.length - 1, nums); } - private TreeNode build(int s, int e, int[] nums){ - if(s <= e){ + private TreeNode build(int s, int e, int[] nums) { + if (s <= e) { int val = nums[max[s][e]]; TreeNode n = new TreeNode(val); n.left = build(s, max[s][e] - 1, nums); diff --git a/problems/src/tree/MostFrequentSubtreeSum.java b/problems/src/tree/MostFrequentSubtreeSum.java index b68f3a0f..aa8a2250 100644 --- a/problems/src/tree/MostFrequentSubtreeSum.java +++ b/problems/src/tree/MostFrequentSubtreeSum.java @@ -7,43 +7,45 @@ /** * Created by gouthamvidyapradhan on 27/03/2017. - Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). So what is the most frequent subtree sum value? If there is a tie, return all the values with the highest frequency in any order. - - Examples 1 - Input: - - 5 - / \ - 2 -3 - return [2, -3, 4], since all the values happen only once, return all of them in any order. - Examples 2 - Input: - - 5 - / \ - 2 -5 - return [2], since 2 happens twice, however -5 only occur once. - Note: You may assume the sum of values in any subtree is in the range of 32-bit signed integer. + * Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). So what is the most frequent subtree sum value? If there is a tie, return all the values with the highest frequency in any order. + *

+ * Examples 1 + * Input: + *

+ * 5 + * / \ + * 2 -3 + * return [2, -3, 4], since all the values happen only once, return all of them in any order. + * Examples 2 + * Input: + *

+ * 5 + * / \ + * 2 -5 + * return [2], since 2 happens twice, however -5 only occur once. + * Note: You may assume the sum of values in any subtree is in the range of 32-bit signed integer. */ -public class MostFrequentSubtreeSum -{ - static class TreeNode - { +public class MostFrequentSubtreeSum { + static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private Map> fList = new HashMap<>(); private Map fCount = new HashMap<>(); + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { MostFrequentSubtreeSum mfs = new MostFrequentSubtreeSum(); TreeNode node = new TreeNode(5); //node.left = new TreeNode(2); @@ -51,37 +53,34 @@ public static void main(String[] args) throws Exception int[] result = mfs.findFrequentTreeSum(node); } - public int[] findFrequentTreeSum(TreeNode root) - { + public int[] findFrequentTreeSum(TreeNode root) { int[] resArr = new int[0]; - if(root == null) return resArr; + if (root == null) return resArr; postOrder(root); - for (Map.Entry entry : fCount.entrySet()) - { + for (Map.Entry entry : fCount.entrySet()) { int frequency = entry.getValue(); List list = fList.get(frequency); - if(list == null) + if (list == null) list = new ArrayList<>(); list.add(entry.getKey()); fList.put(frequency, list); } int max = Integer.MIN_VALUE; List result; - for(int key : fList.keySet()) + for (int key : fList.keySet()) max = Math.max(max, key); result = fList.get(max); resArr = new int[result.size()]; - for(int i = 0, l = resArr.length; i < l; i ++) + for (int i = 0, l = resArr.length; i < l; i++) resArr[i] = result.get(i); return resArr; } - private int postOrder(TreeNode root) - { - if(root == null) return 0; + private int postOrder(TreeNode root) { + if (root == null) return 0; int sum = postOrder(root.left) + postOrder(root.right) + root.val; Integer fSum = fCount.get(sum); - if(fSum == null) + if (fSum == null) fCount.put(sum, 1); else fCount.put(sum, fSum + 1); return sum; diff --git a/problems/src/tree/NextRightPointer.java b/problems/src/tree/NextRightPointer.java index 2c73016d..5f12415f 100644 --- a/problems/src/tree/NextRightPointer.java +++ b/problems/src/tree/NextRightPointer.java @@ -1,46 +1,49 @@ package tree; -import java.util.*; + +import java.util.ArrayDeque; +import java.util.Queue; /** * Created by gouthamvidyapradhan on 07/07/2017. - * - Given a binary tree - - struct TreeLinkNode { - TreeLinkNode *left; - TreeLinkNode *right; - TreeLinkNode *next; - } - Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. - - Initially, all next pointers are set to NULL. - - Note: - - You may only use constant extra space. - You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children). - For example, - Given the following perfect binary tree, - 1 - / \ - 2 3 - / \ / \ - 4 5 6 7 - After calling your function, the tree should look like: - 1 -> NULL - / \ - 2 -> 3 -> NULL - / \ / \ - 4->5->6->7 -> NULL - -Solution: Perform a level order traversal using BFS, keep track of prev node at each level. Link the prev node to - current node if both the nodes are in the same level. + *

+ * Given a binary tree + *

+ * struct TreeLinkNode { + * TreeLinkNode *left; + * TreeLinkNode *right; + * TreeLinkNode *next; + * } + * Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. + *

+ * Initially, all next pointers are set to NULL. + *

+ * Note: + *

+ * You may only use constant extra space. + * You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children). + * For example, + * Given the following perfect binary tree, + * 1 + * / \ + * 2 3 + * / \ / \ + * 4 5 6 7 + * After calling your function, the tree should look like: + * 1 -> NULL + * / \ + * 2 -> 3 -> NULL + * / \ / \ + * 4->5->6->7 -> NULL + *

+ * Solution: Perform a level order traversal using BFS, keep track of prev node at each level. Link the prev node to + * current node if both the nodes are in the same level. */ public class NextRightPointer { - private class LevelNode{ + private class LevelNode { int level; TreeLinkNode node; - LevelNode(TreeLinkNode node, int level){ + + LevelNode(TreeLinkNode node, int level) { this.node = node; this.level = level; } @@ -49,10 +52,13 @@ private class LevelNode{ public static class TreeLinkNode { int val; TreeLinkNode left, right, next; - TreeLinkNode(int x) { val = x; } + + TreeLinkNode(int x) { + val = x; + } } - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { TreeLinkNode node = new TreeLinkNode(2); node.left = new TreeLinkNode(1); node.right = new TreeLinkNode(3); @@ -67,12 +73,12 @@ public void connect(TreeLinkNode root) { LevelNode zero = new LevelNode(root, 0); queue.offer(zero); LevelNode prev = null; - while(!queue.isEmpty()){ + while (!queue.isEmpty()) { LevelNode levelNode = queue.poll(); - if(levelNode.node == null) break; + if (levelNode.node == null) break; TreeLinkNode curr = levelNode.node; - if(prev != null){ - if(prev.level == levelNode.level){ + if (prev != null) { + if (prev.level == levelNode.level) { prev.node.next = levelNode.node; } } diff --git a/problems/src/tree/PathSumIII.java b/problems/src/tree/PathSumIII.java index 455579bb..c1c7c870 100644 --- a/problems/src/tree/PathSumIII.java +++ b/problems/src/tree/PathSumIII.java @@ -5,68 +5,65 @@ /** * Created by gouthamvidyapradhan on 08/04/2017. - 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. - - Example: - - root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8 - - 10 - / \ - 5 -3 - / \ \ - 3 2 11 - / \ \ - 3 -2 1 - - Return 3. The paths that sum to 8 are: - - 1. 5 -> 3 - 2. 5 -> 2 -> 1 - 3. -3 -> 11 + * 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. + *

+ * Example: + *

+ * root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8 + *

+ * 10 + * / \ + * 5 -3 + * / \ \ + * 3 2 11 + * / \ \ + * 3 -2 1 + *

+ * Return 3. The paths that sum to 8 are: + *

+ * 1. 5 -> 3 + * 2. 5 -> 2 -> 1 + * 3. -3 -> 11 */ -public class PathSumIII -{ +public class PathSumIII { /** * */ - public static class TreeNode - { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private Map pathCount = new HashMap<>(); private int totalCount; - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode node = new TreeNode(1); System.out.println(new PathSumIII().pathSum(node, 0)); } - public int pathSum(TreeNode root, int sum) - { - if(root == null) return 0; + public int pathSum(TreeNode root, int sum) { + if (root == null) return 0; dfs(root, sum, 0); return totalCount; } - private void dfs(TreeNode root, int target, int pSum) - { - if(root != null) - { + private void dfs(TreeNode root, int target, int pSum) { + if (root != null) { pSum += root.val; - if(pSum == target) totalCount++; + if (pSum == target) totalCount++; totalCount += pathCount.getOrDefault(pSum - target, 0); pathCount.put(pSum, pathCount.getOrDefault(pSum, 0) + 1); dfs(root.left, target, pSum); diff --git a/problems/src/tree/PostorderToBT.java b/problems/src/tree/PostorderToBT.java index 8a36f0df..bb724d88 100644 --- a/problems/src/tree/PostorderToBT.java +++ b/problems/src/tree/PostorderToBT.java @@ -5,13 +5,12 @@ /** * Created by gouthamvidyapradhan on 23/02/2017. - Given inorder and postorder traversal of a tree, construct the binary tree. - - Note: - You may assume that duplicates do not exist in the tree. + * Given inorder and postorder traversal of a tree, construct the binary tree. + *

+ * Note: + * You may assume that duplicates do not exist in the tree. */ -public class PostorderToBT -{ +public class PostorderToBT { private Map INDEX = new HashMap<>(); private static int postIndex; @@ -20,45 +19,43 @@ public class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int in[] = new int[]{1, 2}; int post[] = new int[]{1, 2}; TreeNode root = new PostorderToBT().buildTree(in, post); new PostorderToBT().preorderPrint(root); } - public TreeNode buildTree(int[] inorder, int[] postorder) - { + public TreeNode buildTree(int[] inorder, int[] postorder) { int count = 0; - for(int i : inorder) + for (int i : inorder) INDEX.put(i, count++); postIndex = postorder.length - 1; return build(0, inorder.length - 1, postorder); } - private void preorderPrint(TreeNode root) - { - if(root != null) - { + private void preorderPrint(TreeNode root) { + if (root != null) { System.out.print(root.val + " "); preorderPrint(root.left); preorderPrint(root.right); } } - private TreeNode build(int s, int e, int[] postorder) - { - if(postIndex >= 0 && s <= e) - { + private TreeNode build(int s, int e, int[] postorder) { + if (postIndex >= 0 && s <= e) { int poi = postorder[postIndex]; int ini = INDEX.get(poi); @@ -66,7 +63,7 @@ private TreeNode build(int s, int e, int[] postorder) TreeNode node = new TreeNode(poi); postIndex--; - if(s == e) + if (s == e) return node; //leaf node node.right = build(ini + 1, e, postorder); diff --git a/problems/src/tree/PreorderToBT.java b/problems/src/tree/PreorderToBT.java index fd2992ca..5982da4e 100644 --- a/problems/src/tree/PreorderToBT.java +++ b/problems/src/tree/PreorderToBT.java @@ -5,51 +5,52 @@ /** * Created by gouthamvidyapradhan on 25/02/2017. - Given preorder and inorder traversal of a tree, construct the binary tree. - - Note: - You may assume that duplicates do not exist in the tree. + * Given preorder and inorder traversal of a tree, construct the binary tree. + *

+ * Note: + * You may assume that duplicates do not exist in the tree. */ -public class PreorderToBT -{ +public class PreorderToBT { public class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } Map MAP = new HashMap<>(); private int index = 0, totalLen = 0; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] perorder = {7,-10,-4,3,-1,2,-8,11}; - int[] inorder = {-4,-10,3,-1,7,11,-8,2}; + public static void main(String[] args) throws Exception { + int[] perorder = {7, -10, -4, 3, -1, 2, -8, 11}; + int[] inorder = {-4, -10, 3, -1, 7, 11, -8, 2}; new PreorderToBT().buildTree(perorder, inorder); } - public TreeNode buildTree(int[] preorder, int[] inorder) - { - for(int i = 0, l = inorder.length; i < l; i ++) + public TreeNode buildTree(int[] preorder, int[] inorder) { + for (int i = 0, l = inorder.length; i < l; i++) MAP.put(inorder[i], i); totalLen = preorder.length; return build(preorder, 0, inorder.length - 1); } - private TreeNode build(int[] preorder, int s, int e) - { + private TreeNode build(int[] preorder, int s, int e) { if (s > e || index >= totalLen) return null; int n = preorder[index++]; int pos = MAP.get(n); TreeNode node = new TreeNode(n); - if(s == e) return node; + if (s == e) return node; node.left = build(preorder, s, pos - 1); node.right = build(preorder, pos + 1, e); diff --git a/problems/src/tree/SortedArrayToBST.java b/problems/src/tree/SortedArrayToBST.java index c89d6ef1..18eb0b6f 100644 --- a/problems/src/tree/SortedArrayToBST.java +++ b/problems/src/tree/SortedArrayToBST.java @@ -2,56 +2,54 @@ /** * Created by gouthamvidyapradhan on 25/02/2017. - Given an array where elements are sorted in ascending order, convert it to a height balanced BST. + * Given an array where elements are sorted in ascending order, convert it to a height balanced BST. */ -public class SortedArrayToBST -{ +public class SortedArrayToBST { public class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] A = {1, 2, 3, 4, 5, 6}; new SortedArrayToBST().sortedArrayToBST(A); } - public TreeNode sortedArrayToBST(int[] nums) - { - if(nums.length == 0) return null; + public TreeNode sortedArrayToBST(int[] nums) { + if (nums.length == 0) return null; TreeNode root = new SortedArrayToBST().build(0, nums.length - 1, nums); preorder(root); return root; } - private void preorder(TreeNode node) - { - if(node != null) - { + private void preorder(TreeNode node) { + if (node != null) { preorder(node.left); System.out.println(node.val); preorder(node.right); } } - private TreeNode build(int s, int e, int[] nums) - { - if(s > e) return null; + private TreeNode build(int s, int e, int[] nums) { + if (s > e) return null; int m = (e - s) / 2; int node = nums[s + m]; TreeNode root = new TreeNode(node); - if(s == e) + if (s == e) return root; root.left = build(s, s + m - 1, nums); diff --git a/problems/src/tree/SubtreeOfAnotherTree.java b/problems/src/tree/SubtreeOfAnotherTree.java index 9c27a515..0d94d926 100644 --- a/problems/src/tree/SubtreeOfAnotherTree.java +++ b/problems/src/tree/SubtreeOfAnotherTree.java @@ -1,67 +1,69 @@ package tree; + /** * Created by gouthamvidyapradhan on 07/07/2017. - Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node's descendants. The tree s could also be considered as a subtree of itself. - - Example 1: - Given tree s: - - 3 - / \ - 4 5 - / \ - 1 2 - Given tree t: - 4 - / \ - 1 2 - Return true, because t has the same structure and node values with a subtree of s. - Example 2: - Given tree s: - - 3 - / \ - 4 5 - / \ - 1 2 - / - 0 - Given tree t: - 4 - / \ - 1 2 - Return false. - + * Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node's descendants. The tree s could also be considered as a subtree of itself. + *

+ * Example 1: + * Given tree s: + *

+ * 3 + * / \ + * 4 5 + * / \ + * 1 2 + * Given tree t: + * 4 + * / \ + * 1 2 + * Return true, because t has the same structure and node values with a subtree of s. + * Example 2: + * Given tree s: + *

+ * 3 + * / \ + * 4 5 + * / \ + * 1 2 + * / + * 0 + * Given tree t: + * 4 + * / \ + * 1 2 + * Return false. */ public class SubtreeOfAnotherTree { public class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { } public boolean isSubtree(TreeNode s, TreeNode t) { - if(s != null){ - if(s.val == t.val) { - if(equal(s, t)) + if (s != null) { + if (s.val == t.val) { + if (equal(s, t)) return true; else return (isSubtree(s.left, t) || isSubtree(s.right, t)); - } - else return (isSubtree(s.left, t) || isSubtree(s.right, t)); + } else return (isSubtree(s.left, t) || isSubtree(s.right, t)); } return false; } - private boolean equal(TreeNode s, TreeNode t){ + private boolean equal(TreeNode s, TreeNode t) { if (s == null && t == null) return true; - else if(s == null || t == null) + else if (s == null || t == null) return false; - else if(s.val != t.val) return false; + else if (s.val != t.val) return false; else return equal(s.left, t.left) && equal(s.right, t.right); } diff --git a/problems/src/tree/SymmetricTree.java b/problems/src/tree/SymmetricTree.java index 7e1c7265..287db22a 100644 --- a/problems/src/tree/SymmetricTree.java +++ b/problems/src/tree/SymmetricTree.java @@ -3,22 +3,21 @@ /** * Created by gouthamvidyapradhan on 14/08/2017. * Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). - - For example, this binary tree [1,2,2,3,4,4,3] is symmetric: - - 1 - / \ - 2 2 - / \ / \ - 3 4 4 3 - - But the following [1,2,2,null,3,null,3] is not: - 1 - / \ - 2 2 - \ \ - 3 3 - + *

+ * For example, this binary tree [1,2,2,3,4,4,3] is symmetric: + *

+ * 1 + * / \ + * 2 2 + * / \ / \ + * 3 4 4 3 + *

+ * But the following [1,2,2,null,3,null,3] is not: + * 1 + * / \ + * 2 2 + * \ \ + * 3 3 */ public class SymmetricTree { @@ -26,15 +25,19 @@ static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { TreeNode node = new TreeNode(3); node.left = new TreeNode(4); node.right = new TreeNode(5); @@ -42,7 +45,7 @@ public static void main(String[] args) throws Exception{ } public boolean isSymmetric(TreeNode root) { - if(root == null) return true; + if (root == null) return true; return dfs(root.left, root.right); } diff --git a/problems/src/tree/ValidBinarySearchTree.java b/problems/src/tree/ValidBinarySearchTree.java index b355bf0b..4ab6893a 100644 --- a/problems/src/tree/ValidBinarySearchTree.java +++ b/problems/src/tree/ValidBinarySearchTree.java @@ -2,54 +2,53 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given a binary tree, determine if it is a valid binary search tree (BST). - - Assume a BST is defined as follows: - - The left subtree of a node contains only nodes with keys less than the node's key. - The right subtree of a node contains only nodes with keys greater than the node's key. - Both the left and right subtrees must also be binary search trees. - Example 1: - 2 - / \ - 1 3 - Binary tree [2,1,3], return true. - Example 2: - 1 - / \ - 2 3 - Binary tree [1,2,3], return false. + * Given a binary tree, determine if it is a valid binary search tree (BST). + *

+ * Assume a BST is defined as follows: + *

+ * The left subtree of a node contains only nodes with keys less than the node's key. + * The right subtree of a node contains only nodes with keys greater than the node's key. + * Both the left and right subtrees must also be binary search trees. + * Example 1: + * 2 + * / \ + * 1 3 + * Binary tree [2,1,3], return true. + * Example 2: + * 1 + * / \ + * 2 3 + * Binary tree [1,2,3], return false. */ -public class ValidBinarySearchTree -{ - class Range - { +public class ValidBinarySearchTree { + class Range { long low, high; } - static class TreeNode - { + static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(Integer.MIN_VALUE); root.right = new TreeNode(Integer.MAX_VALUE); System.out.println(new ValidBinarySearchTree().isValidBST(root)); } - private boolean isValidBST(TreeNode root) - { - if(root == null || + private boolean isValidBST(TreeNode root) { + if (root == null || (root.right == null && root.left == null)) return true; Range range = new Range(); range.high = Long.MAX_VALUE; @@ -57,25 +56,20 @@ private boolean isValidBST(TreeNode root) return validate(root, range); } - private boolean validate(TreeNode root, Range range) - { - if((root.val > range.low) && (root.val < range.high)) - { + private boolean validate(TreeNode root, Range range) { + if ((root.val > range.low) && (root.val < range.high)) { long temp = range.high; - if(root.left != null) - { + if (root.left != null) { range.high = root.val; - if(!validate(root.left, range)) return false; + if (!validate(root.left, range)) return false; } - if(root.right != null) - { + if (root.right != null) { range.high = temp; range.low = root.val; - if(!validate(root.right, range)) return false; + if (!validate(root.right, range)) return false; } return true; - } - else return false; + } else return false; } } diff --git a/problems/src/tree/ZigZagTraversal.java b/problems/src/tree/ZigZagTraversal.java index 216acdd4..60100c2f 100644 --- a/problems/src/tree/ZigZagTraversal.java +++ b/problems/src/tree/ZigZagTraversal.java @@ -7,20 +7,20 @@ /** * Created by pradhang on 7/11/2017. * Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). - - For example: - Given binary tree [3,9,20,null,null,15,7], - 3 - / \ - 9 20 - / \ - 15 7 - return its zigzag level order traversal as: - [ - [3], - [20,9], - [15,7] - ] + *

+ * For example: + * Given binary tree [3,9,20,null,null,15,7], + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * return its zigzag level order traversal as: + * [ + * [3], + * [20,9], + * [15,7] + * ] */ public class ZigZagTraversal { @@ -28,28 +28,32 @@ public class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { } + public List> zigzagLevelOrder(TreeNode root) { List> result = new ArrayList<>(); - if(root == null) return result; + if (root == null) return result; dfs(root, 0, result); return result; } @SuppressWarnings("unchecked") - private void dfs(TreeNode root, int level, List> result){ - if(root != null){ + private void dfs(TreeNode root, int level, List> result) { + if (root != null) { LinkedList subList; - if(level >= result.size()){ + if (level >= result.size()) { subList = new LinkedList<>(); result.add(subList); - }else subList = (LinkedList)result.get(level); - if(level % 2 == 0) + } else subList = (LinkedList) result.get(level); + if (level % 2 == 0) subList.addFirst(root.val); //add to right else subList.add(root.val); //add to left dfs(root.right, level + 1, result); diff --git a/problems/src/two_pointers/FourSum.java b/problems/src/two_pointers/FourSum.java index 639da11b..3df8ee11 100644 --- a/problems/src/two_pointers/FourSum.java +++ b/problems/src/two_pointers/FourSum.java @@ -6,66 +6,55 @@ /** * Created by gouthamvidyapradhan on 29/03/2017. - Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target. - - Note: The solution set must not contain duplicate quadruplets. - - For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0. - - A solution set is: - [ - [-1, 0, 0, 1], - [-2, -1, 1, 2], - [-2, 0, 0, 2] - ] + * Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target. + *

+ * Note: The solution set must not contain duplicate quadruplets. + *

+ * For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0. + *

+ * A solution set is: + * [ + * [-1, 0, 0, 1], + * [-2, -1, 1, 2], + * [-2, 0, 0, 2] + * ] */ -public class FourSum -{ +public class FourSum { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] nums = {1, 0, -1, 0, -2, 2}; System.out.println(new FourSum().fourSum(nums, 0)); } - public List> fourSum(int[] nums, int target) - { + public List> fourSum(int[] nums, int target) { List> result = new ArrayList<>(); - if(nums.length < 4) return result; + if (nums.length < 4) return result; Arrays.sort(nums); - for(int i = 0; i < nums.length - 3; i++) - { - if(i == 0 || nums[i] != nums[i - 1]) - { - for(int j = i + 1; j < nums.length - 2; j ++) - { - if(j == i + 1 || nums[j] != nums[j - 1]) - { + for (int i = 0; i < nums.length - 3; i++) { + if (i == 0 || nums[i] != nums[i - 1]) { + for (int j = i + 1; j < nums.length - 2; j++) { + if (j == i + 1 || nums[j] != nums[j - 1]) { int k = j + 1, l = nums.length - 1; - while(k < l) - { - if(k != j + 1 && nums[k] == nums[k + 1]) - { - k++; continue; + while (k < l) { + if (k != j + 1 && nums[k] == nums[k + 1]) { + k++; + continue; } int sum = nums[i] + nums[j] + nums[k] + nums[l]; - if(sum == target) - { + if (sum == target) { result.add(Arrays.asList(nums[i], nums[j], nums[k], nums[l])); - k++; l --; - } - else if(sum < target) - { - k ++; - } - else - { - l --; + k++; + l--; + } else if (sum < target) { + k++; + } else { + l--; } } } diff --git a/problems/src/two_pointers/LongestSubstringWitoutRepeats.java b/problems/src/two_pointers/LongestSubstringWitoutRepeats.java index 67b389bb..fb20367b 100644 --- a/problems/src/two_pointers/LongestSubstringWitoutRepeats.java +++ b/problems/src/two_pointers/LongestSubstringWitoutRepeats.java @@ -7,38 +7,35 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given a string, find the length of the longest substring without repeating characters. - - Examples: - - Given "abcabcbb", the answer is "abc", which the length is 3. - - Given "bbbbb", the answer is "b", with the length of 1. - - Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring. + * Given a string, find the length of the longest substring without repeating characters. + *

+ * Examples: + *

+ * Given "abcabcbb", the answer is "abc", which the length is 3. + *

+ * Given "bbbbb", the answer is "b", with the length of 1. + *

+ * Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring. */ -public class LongestSubstringWitoutRepeats -{ +public class LongestSubstringWitoutRepeats { Set set = new HashSet<>(); + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new LongestSubstringWitoutRepeats().lengthOfLongestSubstring("asdfsdfsdfsdfasdfdjdjjdjjdjjjjjajsdjjdjdjjd")); } - private int lengthOfLongestSubstring(String s) - { - if(s == null || s.isEmpty()) return 0; + private int lengthOfLongestSubstring(String s) { + if (s == null || s.isEmpty()) return 0; Map map = new HashMap<>(); int i = 0, max = Integer.MIN_VALUE; - for(int j = 0, l = s.length(); j < l; j ++) - { - if(map.keySet().contains(s.charAt(j))) - { + for (int j = 0, l = s.length(); j < l; j++) { + if (map.keySet().contains(s.charAt(j))) { i = Math.max(map.get(s.charAt(j)) + 1, i); } map.put(s.charAt(j), j); diff --git a/problems/src/two_pointers/MoveZeroes.java b/problems/src/two_pointers/MoveZeroes.java index 309bbb1d..9805b6df 100644 --- a/problems/src/two_pointers/MoveZeroes.java +++ b/problems/src/two_pointers/MoveZeroes.java @@ -4,17 +4,16 @@ * Created by gouthamvidyapradhan on 13/06/2017. * Accepted * Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements. - - For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0]. - - Note: - You must do this in-place without making a copy of the array. - Minimize the total number of operations. + *

+ * For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0]. + *

+ * Note: + * You must do this in-place without making a copy of the array. + * Minimize the total number of operations. */ -public class MoveZeroes -{ +public class MoveZeroes { public static void main(String[] args) throws Exception { - int[] nums = {0,0,0,0,1,0,1,0,2}; + int[] nums = {0, 0, 0, 0, 1, 0, 1, 0, 2}; new MoveZeroes().moveZeroes(nums); for (int n : nums) System.out.print(n); @@ -22,15 +21,15 @@ public static void main(String[] args) throws Exception { public void moveZeroes(int[] nums) { int i = 0; - for(int j = 0, l = nums.length; j < l;) { - if(nums[j] == 0) + for (int j = 0, l = nums.length; j < l; ) { + if (nums[j] == 0) j++; else { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; - i ++; - j ++; + i++; + j++; } } while (i < nums.length) diff --git a/problems/src/two_pointers/RemoveDuplicates.java b/problems/src/two_pointers/RemoveDuplicates.java index 96eb7131..9d1e9741 100644 --- a/problems/src/two_pointers/RemoveDuplicates.java +++ b/problems/src/two_pointers/RemoveDuplicates.java @@ -3,26 +3,27 @@ /** * Created by gouthamvidyapradhan on 04/07/2017. * Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. - - Do not allocate extra space for another array, you must do this in place with constant memory. - - For example, - Given input array nums = [1,1,2], - - Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length. + *

+ * Do not allocate extra space for another array, you must do this in place with constant memory. + *

+ * For example, + * Given input array nums = [1,1,2], + *

+ * Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length. */ public class RemoveDuplicates { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[] nums = {1, 1, 2}; int N = new RemoveDuplicates().removeDuplicates(nums); - for(int i = 0; i < N; i ++) + for (int i = 0; i < N; i++) System.out.print(nums[i] + " "); } + public int removeDuplicates(int[] nums) { - if(nums.length == 1) return 1; + if (nums.length == 1) return 1; int size = 1; - for(int j = 0, i = 1; i < nums.length; i ++){ - if(nums[i] != nums[i - 1]){ + for (int j = 0, i = 1; i < nums.length; i++) { + if (nums[i] != nums[i - 1]) { size++; j++; nums[j] = nums[i]; diff --git a/problems/src/two_pointers/ThreeSum.java b/problems/src/two_pointers/ThreeSum.java index 9e105ae7..22d91ad9 100644 --- a/problems/src/two_pointers/ThreeSum.java +++ b/problems/src/two_pointers/ThreeSum.java @@ -6,55 +6,48 @@ /** * Created by gouthamvidyapradhan on 29/03/2017. - Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. - - Note: The solution set must not contain duplicate triplets. - - For example, given array S = [-1, 0, 1, 2, -1, -4], - - A solution set is: - [ - [-1, 0, 1], - [-1, -1, 2] - ] + * Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. + *

+ * Note: The solution set must not contain duplicate triplets. + *

+ * For example, given array S = [-1, 0, 1, 2, -1, -4], + *

+ * A solution set is: + * [ + * [-1, 0, 1], + * [-1, -1, 2] + * ] */ -public class ThreeSum -{ +public class ThreeSum { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] nums = {-1,0,1,2,-1,-4,-1,0,1,2,-1,-4,-1,0,1,2,-1,-4,-1,0,1,2,-1,-4,-1,0,1,2,-1,-4,-1,0,1,2,-1,-4,-1,0,1,2,-1,-4,-1,0,1,2,-1,-4}; + public static void main(String[] args) throws Exception { + int[] nums = {-1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4}; System.out.println(new ThreeSum().threeSum(nums)); } - public List> threeSum(int[] nums) - { + public List> threeSum(int[] nums) { List> result = new ArrayList<>(); - if(nums.length < 3) return result; + if (nums.length < 3) return result; Arrays.sort(nums); - for(int i = 0, l = nums.length; i < l - 2; i ++) - { - if(i == 0 || nums[i] != nums[i - 1]) - { + for (int i = 0, l = nums.length; i < l - 2; i++) { + if (i == 0 || nums[i] != nums[i - 1]) { int j = i + 1, k = l - 1; - while(k > j) - { - if(j != i + 1 && nums[j] == nums[j - 1]) - { - j ++; + while (k > j) { + if (j != i + 1 && nums[j] == nums[j - 1]) { + j++; continue; } int sum = nums[i] + nums[j] + nums[k]; - if(sum == 0) - { + if (sum == 0) { result.add(Arrays.asList(nums[i], nums[j], nums[k])); - k--; j++; - } - else if(sum > 0) k--; + k--; + j++; + } else if (sum > 0) k--; else j++; } } diff --git a/problems/src/two_pointers/ThreeSumClosest.java b/problems/src/two_pointers/ThreeSumClosest.java index df8cfce9..769db5c8 100644 --- a/problems/src/two_pointers/ThreeSumClosest.java +++ b/problems/src/two_pointers/ThreeSumClosest.java @@ -5,11 +5,11 @@ /** * Created by gouthamvidyapradhan on 13/06/2017. * Accepted - Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. - - For example, given array S = {-1 2 1 -4}, and target = 1. - - The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). + * Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. + *

+ * For example, given array S = {-1 2 1 -4}, and target = 1. + *

+ * The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). */ public class ThreeSumClosest { @@ -21,32 +21,30 @@ public static void main(String[] args) { public int threeSumClosest(int[] a, int target) { Arrays.sort(a); int min = Integer.MAX_VALUE, ans = -1; - for(int i = 0, l = a.length; i < l - 2; i ++) { - if(i == 0 || ! (a[i] == a[i - 1])) { + for (int i = 0, l = a.length; i < l - 2; i++) { + if (i == 0 || !(a[i] == a[i - 1])) { int j = i + 1, k = l - 1; - while(k > j) { - if(j != i + 1 && (a[j] == a[j - 1])) { - j ++; + while (k > j) { + if (j != i + 1 && (a[j] == a[j - 1])) { + j++; continue; } int sum = a[i] + a[j] + a[k]; - if(sum < target) { + if (sum < target) { int diff = Math.abs(sum - target); - if(diff < min) { + if (diff < min) { min = diff; ans = sum; } j++; - } - else if(sum > target) { + } else if (sum > target) { int diff = Math.abs(sum - target); - if(diff < min) { + if (diff < min) { min = diff; ans = sum; } k--; - } - else{ + } else { return sum; } } diff --git a/problems/src/two_pointers/TrappingRainWater.java b/problems/src/two_pointers/TrappingRainWater.java index d45cb2ad..3fda5a3c 100644 --- a/problems/src/two_pointers/TrappingRainWater.java +++ b/problems/src/two_pointers/TrappingRainWater.java @@ -2,27 +2,25 @@ /** * Created by gouthamvidyapradhan on 08/03/2017. - Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. - - For example, - Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6. + * Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. + *

+ * For example, + * Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6. */ -public class TrappingRainWater -{ +public class TrappingRainWater { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] height = {0,1,0,2,1,0,1,3,2,1,2,1}; + public static void main(String[] args) throws Exception { + int[] height = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1}; System.out.println(new TrappingRainWater().trap(height)); } - private int trap(int[] height) - { - if(height.length == 0) return 0; + private int trap(int[] height) { + if (height.length == 0) return 0; int[] left = new int[height.length]; int[] right = new int[height.length]; @@ -32,22 +30,18 @@ private int trap(int[] height) int total = 0; - for(int i = 1, l = height.length; i < l; i ++) - { + for (int i = 1, l = height.length; i < l; i++) { left[i] = Math.max(max, height[i - 1]); max = left[i]; } max = 0; - for(int i = height.length - 2; i >= 0; i --) - { + for (int i = height.length - 2; i >= 0; i--) { right[i] = Math.max(max, height[i + 1]); max = right[i]; } - for(int i = 0, l = height.length; i < l; i++) - { + for (int i = 0, l = height.length; i < l; i++) { int min = Math.min(left[i], right[i]); - if(min > height[i]) - { + if (min > height[i]) { total += (min - height[i]); } } From e294f2f9fc2003c1449fec7e5d9b103d4770a316 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 15 Sep 2017 00:27:32 +0200 Subject: [PATCH 078/235] Fixed print output --- problems/src/heap/TheSkylineProblem.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/problems/src/heap/TheSkylineProblem.java b/problems/src/heap/TheSkylineProblem.java index 90bc186b..fd5fcce9 100644 --- a/problems/src/heap/TheSkylineProblem.java +++ b/problems/src/heap/TheSkylineProblem.java @@ -59,7 +59,9 @@ public static void main(String[] args) throws Exception { int[][] A = {{0, 30, 30}, {2, 9, 10}, {3, 7, 15}, {4, 8, 10}, {5, 12, 12}, {15, 20, 10}, {19, 24, 8}}; //int[][] A = {{2,9,10}, {3,9,11}, {4,9,12}, {5,9,13}}; List result = new TheSkylineProblem().getSkyline(A); - result.forEach(System.out::println); + result.forEach(x -> { + System.out.println(x[0] + " " + x[1]); + }); } public List getSkyline(int[][] buildings) { From 0214329a6b948d415444b170129edbcbe7606b57 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 16 Sep 2017 18:48:14 +0200 Subject: [PATCH 079/235] Design Excel Sum Formula : Accepted --- README.md | 1 + problems/src/design/Excel.java | 228 +++++++++++++++++++++++++++++++++ 2 files changed, 229 insertions(+) create mode 100644 problems/src/design/Excel.java diff --git a/README.md b/README.md index 9abff8b1..58bc9ed0 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Implement Trie (Prefix Tree)](problems/src/design/Trie.java) (Medium) - [Binary Search Tree Iterator](problems/src/design/BSTIterator.java) (Medium) - [Design Search Autocomplete System](problems/src/design/AutocompleteSystem.java) (Hard) +- [Design Excel Sum Formula](problems/src/design/Excel.java) (Hard) #### [Divide and Conquer](problems/src/divide_and_conquer) diff --git a/problems/src/design/Excel.java b/problems/src/design/Excel.java new file mode 100644 index 00000000..30d6fc3c --- /dev/null +++ b/problems/src/design/Excel.java @@ -0,0 +1,228 @@ +package design; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 16/09/2017. + *

+ * Your task is to design the basic function of Excel and implement the function of sum formula. + * Specifically, you need to implement the following functions: + *

+ * Excel(int H, char W): This is the constructor. + * The inputs represents the height and width of the Excel form. H is a positive integer, range from 1 to 26. + * It represents the height. W is a character range from 'A' to 'Z'. It represents that the width is the number of + * characters from 'A' to W. The Excel form content is represented by a height * width 2D integer array C, it should be + * initialized to zero. You should assume that the first row of C starts from 1, and the first column of C starts from + * 'A'. + *

+ *

+ * void Set(int row, char column, int val): Change the value at C(row, column) to be val. + *

+ *

+ * int Get(int row, char column): Return the value at C(row, column). + *

+ *

+ * int Sum(int row, char column, List of Strings : numbers): This function calculate and set the value at C(row, + * column), where the value should be the sum of cells represented by numbers. This function return the sum result at + * C(row, column). This sum formula should exist until this cell is overlapped by another value or another sum formula. + *

+ * numbers is a list of strings that each string represent a cell or a range of cells. If the string represent a + * single cell, then it has the following format : ColRow. For example, "F7" represents the cell at (7, F). + *

+ * If the string represent a range of cells, then it has the following format : ColRow1:ColRow2. The range will always + * be a rectangle, and ColRow1 represent the position of the top-left cell, and ColRow2 represents the position of the + * bottom-right cell. + *

+ *

+ * Example 1: + * Excel(3,"C"); + * // construct a 3*3 2D array with all zero. + * // A B C + * // 1 0 0 0 + * // 2 0 0 0 + * // 3 0 0 0 + *

+ * Set(1, "A", 2); + * // set C(1,"A") to be 2. + * // A B C + * // 1 2 0 0 + * // 2 0 0 0 + * // 3 0 0 0 + *

+ * Sum(3, "C", ["A1", "A1:B2"]); + * // set C(3,"C") to be the sum of value at C(1,"A") and the values sum of the rectangle range whose top-left cell is + * C (1,"A") and bottom-right cell is C(2,"B"). Return 4. + * // A B C + * // 1 2 0 0 + * // 2 0 0 0 + * // 3 0 0 4 + *

+ * Set(2, "B", 2); + * // set C(2,"B") to be 2. Note C(3, "C") should also be changed. + * // A B C + * // 1 2 0 0 + * // 2 0 2 0 + * // 3 0 0 6 + * Note: + * You could assume that there won't be any circular sum reference. For example, A1 = sum(B1) and B1 = sum(A1). + * The test cases are using double-quotes to represent a character. + * Please remember to RESET your class variables declared in class Excel, as static/class variables are persisted + * across multiple test cases. + *

+ * Solution: Build a graph and for each cell keep track of forward and backward links. When a cell is updated with a + * new value broadcast the new value to all the forward links and remove all the forward links pointing to this + * particular cell. + */ +public class Excel { + + private Map> fwdEdges; //Forward links from cell + private Map> backEdge; //All backward links from cell + private Map count; //Keep track of number of times the cell is linked + private int[][] grid; //excel grid + + /** + * Initialize datastructure + * + * @param H row + * @param W column + */ + public Excel(int H, char W) { + grid = new int[H][(Character.toUpperCase(W) - 'A') + 1]; + fwdEdges = new HashMap<>(); + backEdge = new HashMap<>(); + count = new HashMap<>(); + } + + public static void main(String[] args) throws Exception { + Excel excel = new Excel(26, 'Z'); + excel.set(1, 'A', 1); + excel.set(1, 'I', 1); + String[] arr = {"A1:D6", "A1:G3", "A1:C12"}; + String[] arr1 = {"A1:D7", "D1:F10", "D3:I8", "I1:I9"}; + System.out.println(excel.get(1, 'A')); + System.out.println(excel.sum(7, 'D', arr)); + System.out.println(excel.get(1, 'A')); + System.out.println(excel.sum(10, 'G', arr1)); + System.out.println(excel.get(1, 'A')); + } + + /** + * Set value to the grid + * + * @param r row + * @param c column + * @param v value + */ + public void set(int r, char c, int v) { + setValue(r, c, v); + removeForwardEdges(String.valueOf(c) + r); + } + + private void setValue(int r, char c, int v) { + int curr = grid[r - 1][Character.toUpperCase(c) - 'A']; + grid[r - 1][Character.toUpperCase(c) - 'A'] = v; + broadcast(v - curr, String.valueOf(c) + r); + } + + /** + * Remove all the links + * + * @param node node + */ + private void removeForwardEdges(String node) { + List parents = backEdge.get(node); + if (parents != null) { + for (String p : parents) { + Set children = fwdEdges.get(p); + if (children != null) { + count.remove(p + ":" + node); + children.remove(node); + } + } + } + } + + /** + * Broadcast to all the links + * + * @param v current node + * @param node node + */ + private void broadcast(int v, String node) { + Set children = fwdEdges.get(node); + if (children != null) { + for (String c : children) { + int order = count.get(node + ":" + c); + grid[Integer.parseInt(c.substring(1)) - 1][c.charAt(0) - 'A'] += (v * order); + broadcast(v, c); + } + } + } + + public int get(int r, char c) { + return grid[r - 1][c - 'A']; + } + + /** + * Sum range of cells + * + * @param r row + * @param c column + * @param strs Strings + * @return integer sum + */ + public int sum(int r, char c, String[] strs) { + int sum = 0; + //Remove all the forward and backward edges or links + removeForwardEdges(c + String.valueOf(r)); + backEdge.remove(c + String.valueOf(r)); + Set nodes = new HashSet<>(); + for (String s : strs) { + String[] range = s.split(":"); + if (range.length > 1) { + int startRow = Integer.parseInt(range[0].substring(1)) - 1; + int startColumn = range[0].charAt(0) - 'A'; + + int endRow = Integer.parseInt(range[1].substring(1)) - 1; + int endColumn = range[1].charAt(0) - 'A'; + + for (int i = startRow; i <= endRow; i++) { + for (int j = startColumn; j <= endColumn; j++) { + char newC = (char) ('A' + j); + nodes.add(newC + String.valueOf(i + 1)); + sum += grid[i][j]; + String key = newC + String.valueOf(i + 1) + ":" + (c + String.valueOf(r)); + if (count.putIfAbsent(key, 1) != null) { + count.put(key, (count.get(key) + 1)); + } + } + } + } else { + sum += grid[Integer.parseInt(range[0].substring(1)) - 1][range[0].charAt(0) - 'A']; + nodes.add(range[0]); + String key = range[0] + ":" + (c + String.valueOf(r)); + if (count.putIfAbsent(key, 1) != null) { + count.put(key, count.get(key) + 1); + } + } + } + //set value + setValue(r, c, sum); + + //make new forward-edges + for (String n : nodes) { + Set children = fwdEdges.get(n); + if (children == null) { + children = new HashSet<>(); + fwdEdges.put(n, children); + } + children.add(c + String.valueOf(r)); + } + + //make new back-edges + List backEdges = new ArrayList<>(); + backEdges.addAll(nodes); + backEdge.put(c + String.valueOf(r), backEdges); + return sum; + } +} From dcfd69cc83a3a74249681edd603157f01d126785 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 19 Sep 2017 00:21:28 +0200 Subject: [PATCH 080/235] Permutation in String : Accepted --- README.md | 1 + problems/src/string/PermutationInString.java | 60 ++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 problems/src/string/PermutationInString.java diff --git a/README.md b/README.md index 58bc9ed0..33154224 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Compare Version Numbers](problems/src/string/CompareVersionNumbers.java) (Easy) - [Valid Palindrome](problems/src/string/ValidPalindrome.java) (Easy) - [Simplify Path](problems/src/string/SimplifyPath.java) (Medium) +- [Permutation in String](problems/src/string/PermutationInString.java) (Medium) #### [Tree](problems/src/tree) diff --git a/problems/src/string/PermutationInString.java b/problems/src/string/PermutationInString.java new file mode 100644 index 00000000..86cccc94 --- /dev/null +++ b/problems/src/string/PermutationInString.java @@ -0,0 +1,60 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 18/09/2017. + * 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. + + Example 1: + Input:s1 = "ab" s2 = "eidbaooo" + Output:True + Explanation: s2 contains one permutation of s1 ("ba"). + + Example 2: + Input:s1= "ab" s2 = "eidboaoo" + Output: False + Note: + The input strings only contain lower case letters. + The length of both given strings is in range [1, 10,000]. + + */ +public class PermutationInString { + private int[] S1 = new int[256]; + private int[] S2 = new int[256]; + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new PermutationInString().checkInclusion("ab", "eidboaoo")); + } + + public boolean checkInclusion(String s1, String s2) { + if(s2.length() < s1.length()) return false; + for(int i = 0, l = s1.length(); i < l; i ++){ + S1[s1.charAt(i)] ++; + S2[s2.charAt(i)] ++; + } + if(isEqual()) return true; + for(int i = 1, j = s1.length(), l = s2.length(); j < l; i++, j++){ + S2[s2.charAt(i - 1)] --; + S2[s2.charAt(j)] ++; + if(isEqual()) return true; + } + return false; + } + + private boolean isEqual(){ + boolean equal = true; + for(int i = 0; i < 256; i ++){ + if(S1[i] != S2[i]){ + equal = false; + break; + } + } + return equal; + } + +} From cdf6b19a0796ff9b2bcb1a75bdd617ceba22b497 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 3 Oct 2017 20:01:35 +0200 Subject: [PATCH 081/235] Populating Next Right Pointers in Each Node II : Accepted --- README.md | 1 + problems/src/tree/NextRightPointerII.java | 74 +++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 problems/src/tree/NextRightPointerII.java diff --git a/README.md b/README.md index 33154224..516156f0 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Construct String From Binary Tree](problems/src/tree/ConstructStringFromBinaryTree.java) (Easy) - [Flatten Binary Tree to Linked List](problems/src/tree/FlattenBinaryTree.java) (Medium) - [Populating Next Right Pointers in Each Node](problems/src/tree/NextRightPointer.java) (Medium) +- [Populating Next Right Pointers in Each Node II](problems/src/tree/NextRightPointerII.java) (Medium) - [Subtree of Another Tree](problems/src/tree/SubtreeOfAnotherTree.java) (Easy) - [Binary Tree Zigzag Level Order Traversal](problems/src/tree/ZigZagTraversal.java) (Medium) - [Binary Tree Inorder Traversal](problems/src/tree/BinaryTreeInorderTraversal.java) (Medium) diff --git a/problems/src/tree/NextRightPointerII.java b/problems/src/tree/NextRightPointerII.java new file mode 100644 index 00000000..777213f0 --- /dev/null +++ b/problems/src/tree/NextRightPointerII.java @@ -0,0 +1,74 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 03/10/2017. + *

+ * Follow up for problem "Populating Next Right Pointers in Each Node". + *

+ * What if the given tree could be any binary tree? Would your previous solution still work? + *

+ * Note: + *

+ * You may only use constant extra space. + * For example, + * Given the following binary tree, + * 1 + * / \ + * 2 3 + * / \ \ + * 4 5 7 + * After calling your function, the tree should look like: + * 1 -> NULL + * / \ + * 2 -> 3 -> NULL + * / \ \ + * 4-> 5 -> 7 -> NULL + */ +public class NextRightPointerII { + + public static void main(String[] args) throws Exception { + TreeLinkNode root = new TreeLinkNode(1); + root.left = new TreeLinkNode(2); + root.right = new TreeLinkNode(3); + root.right.right = new TreeLinkNode(4); + root.right.right.left = new TreeLinkNode(5); + root.right.right.right = new TreeLinkNode(6); + new NextRightPointerII().connect(root); + } + + public void connect(TreeLinkNode root) { + TreeLinkNode prev = new TreeLinkNode(0); + TreeLinkNode first = null; + while (root != null) { + if (root.left != null) { + prev.next = root.left; + prev = root.left; + if (first == null) { + first = root.left; + } + } + if (root.right != null) { + prev.next = root.right; + prev = root.right; + if (first == null) { + first = root.right; + } + } + root = root.next; + if (root == null) { + root = first; + first = null; + prev = new TreeLinkNode(0); + } + } + } + + public static class TreeLinkNode { + int val; + TreeLinkNode left, right, next; + + TreeLinkNode(int x) { + val = x; + } + } +} From ecdad4a7f36998a15838863f058d6c98a16c857c Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 18 Oct 2017 01:13:28 +0200 Subject: [PATCH 082/235] Remove Invalid Parentheses : Accepted --- README.md | 1 + .../RemoveInvalidParentheses.java | 84 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 problems/src/backtracking/RemoveInvalidParentheses.java diff --git a/README.md b/README.md index 516156f0..3db77175 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Word Search](problems/src/backtracking/WordSearch.java) (Medium) - [Word Search II](problems/src/backtracking/WordSearchII.java) (Hard) - [Generate Parentheses](problems/src/backtracking/GenerateParentheses.java) (Medium) +- [Remove Invalid Parentheses](problems/src/backtracking/RemoveInvalidParentheses.java) (Medium) #### [Binary Search](problems/src/binary_search) diff --git a/problems/src/backtracking/RemoveInvalidParentheses.java b/problems/src/backtracking/RemoveInvalidParentheses.java new file mode 100644 index 00000000..b71df8ab --- /dev/null +++ b/problems/src/backtracking/RemoveInvalidParentheses.java @@ -0,0 +1,84 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Created by gouthamvidyapradhan on 17/10/2017. + * Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results. + + Note: The input string may contain letters other than the parentheses ( and ). + + Examples: + "()())()" -> ["()()()", "(())()"] + "(a)())()" -> ["(a)()()", "(a())()"] + ")(" -> [""] + + Solution: O(N x 2 ^ N) generate all combination of unique parentheses and return a list of valid parentheses which + has the string length maximum + + */ +public class RemoveInvalidParentheses { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + List result = new RemoveInvalidParentheses().removeInvalidParentheses("()())()"); + result.forEach(System.out::println); + } + + public List removeInvalidParentheses(String s) { + Set set = new HashSet<>(); + List result = new ArrayList<>(); + result.add(""); + //generate all combinations of unique parentheses + for(int i = s.length() - 1; i >= 0; i --){ + for(int j = 0, l = result.size(); j < l; j++){ + String curr = s.charAt(i) + result.get(j); + if(!set.contains(curr)){ + result.add(curr); + set.add(curr); + } + } + } + //check for max length + int maxLen = 0; + for(String r : result){ + if(isValid(r)){ + maxLen = Math.max(maxLen, r.length()); + } + } + //prepare the final list + List finalR = new ArrayList<>(); + for(String r : result){ + if(isValid(r)) { + if(r.length() == maxLen){ + finalR.add(r); + } + } + } + return finalR; + } + + /** + * Check if the given string of parentheses is valid or not + * @param s String of parentheses + * @return true if valid + */ + private boolean isValid(String s){ + int count = 0; + for(int i = 0, l = s.length(); i < l; i ++){ + if(s.charAt(i) == '('){ + count ++; + } else if(s.charAt(i) == ')'){ + count --; + if(count < 0) return false; + } + } + return count == 0; + } +} From 68653da1cf39931d6115ee7b01314c1c5f2a0fc1 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 18 Oct 2017 02:13:49 +0200 Subject: [PATCH 083/235] DiameterOfBinaryTree : Accepted --- README.md | 1 + problems/src/tree/DiameterOfBinaryTree.java | 55 +++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 problems/src/tree/DiameterOfBinaryTree.java diff --git a/README.md b/README.md index 3db77175..411ad557 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Symmetric Tree](problems/src/tree/SymmetricTree.java) (Easy) - [Maximum Binary Tree](problems/src/tree/MaximumBinaryTree.java) (Medium) - [Find Bottom Left Tree Value](problems/src/tree/FindBottomLeftTreeValue.java) (Medium) +- [Diameter of Binary Tree](problems/src/tree/DiameterOfBinaryTree.java) (Easy) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/DiameterOfBinaryTree.java b/problems/src/tree/DiameterOfBinaryTree.java new file mode 100644 index 00000000..fee3d54e --- /dev/null +++ b/problems/src/tree/DiameterOfBinaryTree.java @@ -0,0 +1,55 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 18/10/2017. + * + * Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is + * the length of the longest path between any two nodes in a tree. This path may or may not pass through the root. + + Example: + Given a binary tree + 1 + / \ + 2 3 + / \ + 4 5 + Return 3, which is the length of the path [4,2,1,3] or [5,2,1,3]. + + Note: The length of path between two nodes is represented by the number of edges between them. + */ +public class DiameterOfBinaryTree { + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + private int max = 0; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + TreeNode root = new TreeNode(5); + root.left = new TreeNode(4); + System.out.println(new DiameterOfBinaryTree().diameterOfBinaryTree(root)); + } + + public int diameterOfBinaryTree(TreeNode root) { + dfs(root); + return max; + } + + private int dfs(TreeNode node){ + if(node != null){ + int left = dfs(node.left); + int right = dfs(node.right); + max = Math.max(max, left + right); + return left > right ? left + 1 : right + 1; + } + return 0; + } +} From d7a1e90d776ee9f828b32cfcd8a516fef279e240 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 18 Oct 2017 21:30:00 +0200 Subject: [PATCH 084/235] Maximum Size Subarray Sum Equals k : Accepted --- README.md | 1 + .../MaximumSizeSubarraySumEqualsk.java | 64 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 problems/src/hashing/MaximumSizeSubarraySumEqualsk.java diff --git a/README.md b/README.md index 411ad557..ce4e0e26 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Sort Character by Frequency](problems/src/hashing/SortCharByFrequency.java) (Medium) - [Two Sum](problems/src/hashing/TwoSum.java) (Easy) - [Valid Anagram](problems/src/hashing/ValidAnagram.java) (Easy) +- [Maximum Size Subarray Sum Equals k](problems/src/hashing/MaximumSizeSubarraySumEqualsk.java) (Medium) #### [Heap](problems/src/heap) diff --git a/problems/src/hashing/MaximumSizeSubarraySumEqualsk.java b/problems/src/hashing/MaximumSizeSubarraySumEqualsk.java new file mode 100644 index 00000000..348d426a --- /dev/null +++ b/problems/src/hashing/MaximumSizeSubarraySumEqualsk.java @@ -0,0 +1,64 @@ +package hashing; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by gouthamvidyapradhan on 18/10/2017. + * Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If there isn't + * one, return 0 instead. + + Note: + The sum of the entire nums array is guaranteed to fit within the 32-bit signed integer range. + + Example 1: + Given nums = [1, -1, 5, -2, 3], k = 3, + return 4. (because the subarray [1, -1, 5, -2] sums to 3 and is the longest) + + Example 2: + Given nums = [-2, -1, 2, 1], k = 1, + return 2. (because the subarray [-1, 2] sums to 1 and is the longest) + + Follow Up: + Can you do it in O(n) time? + */ +public class MaximumSizeSubarraySumEqualsk { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1,-1,5,-2,3}; + System.out.println(new MaximumSizeSubarraySumEqualsk().maxSubArrayLen(A, 10)); + } + + public int maxSubArrayLen(int[] nums, int k) { + Map index = new HashMap<>(); + long sum = 0L; + for(int i = 0; i < nums.length; i ++){ + sum += nums[i]; + index.putIfAbsent(sum, i); + } + sum = 0; + int ans = 0; + for(int i = 0; i < nums.length; i ++){ + sum += nums[i]; + if(sum == k){ + ans = Math.max(ans, i + 1); + } else{ + long exp = sum - k; + if(index.containsKey(exp)){ + int farLeft = index.get(exp); + if(farLeft < i){ + ans = Math.max(ans, i - index.get(exp)); + } + } + } + } + + return ans; + } + +} From 1269b679d88ced036903ded7710449d161c76ec0 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 18 Oct 2017 21:31:44 +0200 Subject: [PATCH 085/235] Maximum Size Subarray Sum Equals k : Accepted --- problems/src/hashing/MaximumSizeSubarraySumEqualsk.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/problems/src/hashing/MaximumSizeSubarraySumEqualsk.java b/problems/src/hashing/MaximumSizeSubarraySumEqualsk.java index 348d426a..ac97da99 100644 --- a/problems/src/hashing/MaximumSizeSubarraySumEqualsk.java +++ b/problems/src/hashing/MaximumSizeSubarraySumEqualsk.java @@ -35,8 +35,8 @@ public static void main(String[] args) throws Exception{ } public int maxSubArrayLen(int[] nums, int k) { - Map index = new HashMap<>(); - long sum = 0L; + Map index = new HashMap<>(); + int sum = 0; for(int i = 0; i < nums.length; i ++){ sum += nums[i]; index.putIfAbsent(sum, i); @@ -48,7 +48,7 @@ public int maxSubArrayLen(int[] nums, int k) { if(sum == k){ ans = Math.max(ans, i + 1); } else{ - long exp = sum - k; + int exp = sum - k; if(index.containsKey(exp)){ int farLeft = index.get(exp); if(farLeft < i){ @@ -57,7 +57,6 @@ public int maxSubArrayLen(int[] nums, int k) { } } } - return ans; } From dbfbb452fde06221ff6221f57ee76d8ed0754d54 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 23 Nov 2017 01:54:52 +0100 Subject: [PATCH 086/235] Maximum Sum of 3 Non-Overlapping Subarrays : Accepted --- README.md | 1 + .../dynamic_programming/MaxSum3SubArray.java | 124 ++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 problems/src/dynamic_programming/MaxSum3SubArray.java diff --git a/README.md b/README.md index ce4e0e26..a0c0c050 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Maximum Subarray](problems/src/dynamic_programming/MaximumSubarray.java) (Easy) - [Dungeon Game](problems/src/dynamic_programming/DungeonGame.java) (Hard) - [2 Keys Keyboard](problems/src/dynamic_programming/TwoKeysKeyboard.java) (Medium) +- [Maximum Sum of 3 Non-Overlapping Subarrays](problems/src/dynamic_programming/MaxSum3SubArray.java) (Hard) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/MaxSum3SubArray.java b/problems/src/dynamic_programming/MaxSum3SubArray.java new file mode 100644 index 00000000..71152d16 --- /dev/null +++ b/problems/src/dynamic_programming/MaxSum3SubArray.java @@ -0,0 +1,124 @@ +package dynamic_programming; +/** + * Created by gouthamvidyapradhan on 22/11/2017. + + In a given array nums of positive integers, find three non-overlapping subarrays with maximum sum. + + Each subarray will be of size k, and we want to maximize the sum of all 3*k entries. + + Return the result as a list of indices representing the starting position of each interval (0-indexed). If there are multiple answers, return the lexicographically smallest one. + + Example: + Input: [1,2,1,2,6,7,5,1], 2 + Output: [0, 3, 5] + Explanation: Subarrays [1, 2], [2, 6], [7, 5] correspond to the starting indices [0, 3, 5]. + We could have also taken [2, 1], but an answer of [1, 3, 5] would be lexicographically larger. + Note: + nums.length will be between 1 and 20000. + nums[i] will be between 1 and 65535. + k will be between 1 and floor(nums.length / 3). + + Solution: + O(N) solution by prefix and reverse-prefix sum + First calculate max index for array index k, then use this to calculate max index for two array indices j and k and + again use this result to calculate the final max index for i, j and k for the 3 arrays. + + */ +public class MaxSum3SubArray { + + class Max{ + int i, j, k, max; + Max(int i, int max){ + this.i = i; + this.max = max; + } + Max(int i, int j, int max){ + this.i = i; + this.j = j; + this.max = max; + } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1,2,1,2,6}; + int[] result = new MaxSum3SubArray().maxSumOfThreeSubarrays(A, 1); + for (int i = 0; i < result.length; i ++) + System.out.print(result[i] + " "); + } + + public int[] maxSumOfThreeSubarrays(int[] nums, int k) { + int[] fPrefix = new int[nums.length]; //forward prefix sum + int[] rPrefix = new int[nums.length]; //reverse prefix sum + + //calculate forward prefix sum + for(int i = 0; i < k; i ++){ + fPrefix[0] += nums[i]; + } + for(int i = 1; i < nums.length; i ++){ + if(i + k - 1 < nums.length){ + fPrefix[i] = fPrefix[i - 1] - nums[i - 1] + nums[i + k - 1]; + } + } + int sum = 0; + for(int i = nums.length - 1; i >= nums.length - k; i --){ + sum += nums[i]; + } + Max[] max1 = new Max[nums.length]; + max1[nums.length - k] = new Max(nums.length - k, sum); + + //calculate reverse prefix sum + rPrefix[nums.length - k] = sum; + for(int i = nums.length - 1; i >= 0; i --){ + if(i + k >= nums.length) continue; + rPrefix[i] = rPrefix[i + 1] - nums[i + k] + nums[i]; + } + + //calculate max for k index + for(int i = nums.length - 1; i >= 0; i --){ + if(i + k >= nums.length) continue; + max1[i] = new Max(i, rPrefix[i]); + if(max1[i + 1] != null){ + if(max1[i].max < max1[i + 1].max){ + max1[i] = new Max(max1[i + 1].i, max1[i + 1].max); + } + } + } + + //calculate max for j and k index + Max[] max2 = new Max[nums.length]; + for(int i = nums.length - 1; i >= 0; i --){ + if(i + k < nums.length && max1[i + k] != null){ + max2[i] = new Max(i, max1[i + k].i, fPrefix[i] + max1[i + k].max); + } + } + for(int i = nums.length - 1; i >= 0; i --){ + if(i + 1 > nums.length - 1 || max2[i + 1] == null) continue; + if(max2[i].max < max2[i + 1].max){ + max2[i].max = max2[i + 1].max; + max2[i].i = max2[i + 1].i; + max2[i].j = max2[i + 1].j; + } + } + + //calculate max for i, j and k index + int[] result = new int[3]; + int max = 0; + for(int i = 0; i < nums.length; i ++){ + if((i + k) < nums.length - 1 && max2[i + k] != null){ + int temp = fPrefix[i] + max2[i + k].max; + if(temp > max){ + max = temp; + result[0] = i; + result[1] = max2[i + k].i; + result[2] = max2[i + k].j; + } + } + } + return result; + } +} \ No newline at end of file From 08ee2403f8a1e73113c9f3ea30980edb33c13dfe Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 25 Nov 2017 14:25:11 +0100 Subject: [PATCH 087/235] Find the Celebrity : Accepted --- README.md | 1 + problems/src/array/FindTheCelebrity.java | 105 +++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 problems/src/array/FindTheCelebrity.java diff --git a/README.md b/README.md index a0c0c050..9c18a0d8 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Rotate Array](problems/src/array/RotateArray.java) (Easy) - [Sort Colors](problems/src/array/SortColors.java) (Medium) - [Battleships in a Board](problems/src/array/BattleshipsInABoard.java) (Medium) +- [Find the Celebrity](problems/src/array/FindTheCelebrity.java) (Medium) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/FindTheCelebrity.java b/problems/src/array/FindTheCelebrity.java new file mode 100644 index 00000000..b86db317 --- /dev/null +++ b/problems/src/array/FindTheCelebrity.java @@ -0,0 +1,105 @@ +package array; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * Created by gouthamvidyapradhan on 25/11/2017. + * + * Suppose you are at a party with n people (labeled from 0 to n - 1) and among them, there may exist one celebrity. + * The definition of a celebrity is that all the other n - 1 people know him/her but he/she does not know any of them. + + Now you want to find out who the celebrity is or verify that there is not one. The only thing you are allowed to do + is to ask questions like: "Hi, A. Do you know B?" to get information of whether A knows B. You need to find out the + celebrity (or verify there is not one) by asking as few questions as possible (in the asymptotic sense). + + You are given a helper function bool knows(a, b) which tells you whether A knows B. Implement a function int + findCelebrity(n), your function should minimize the number of calls to knows. + + Note: There will be exactly one celebrity if he/she is in the party. Return the celebrity's label if there is a + celebrity in the party. If there is no celebrity, return -1. + */ +public class FindTheCelebrity { + + private static Map> map = new HashMap<>(); + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + //initialize relationship + map.put(0, new HashSet<>()); + map.put(1, new HashSet<>()); + map.put(2, new HashSet<>()); + map.put(3, new HashSet<>()); + map.put(4, new HashSet<>()); + map.put(5, new HashSet<>()); + map.put(6, new HashSet<>()); + map.get(0).add(3); + map.get(0).add(1); + map.get(0).add(2); + map.get(0).add(4); + map.get(0).add(5); + map.get(0).add(6); + + map.get(1).add(0); + map.get(1).add(3); + map.get(1).add(2); + + map.get(2).add(1); + map.get(2).add(3); + map.get(2).add(4); + + map.get(4).add(2); + map.get(4).add(3); + map.get(4).add(5); + + map.get(5).add(4); + map.get(5).add(3); + map.get(5).add(6); + + map.get(6).add(5); + map.get(6).add(3); + map.get(6).add(0); + + System.out.println(new FindTheCelebrity().findCelebrity(0)); + } + + /** + * Find celebrity + * @param n + * @return + */ + public int findCelebrity(int n) { + int candidate = -1, i = 0, next = 1; + while(i < n){ + if(next >= n) break; + if(knows(i, next) && !knows(next, i)){ + i = next; + next = i + 1; + } else if((!knows(i, next) && !knows(next, i)) || (knows(i, next) && knows(next, i))){ + i = next + 1; + next = i + 1; + } else { + next++; + } + candidate = i; + } + if(candidate == -1 || candidate >= n) + return -1; + for(int j = 0; j < candidate; j ++){ + if(!knows(j, candidate) || knows(candidate, j)){ + candidate = -1; + break; + } + } + return candidate; + } + + private boolean knows(int a, int b){ + return map.get(a).contains(b); + } +} From a2f799378c4a79c4364e0ab0eec164bfc85f8392 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 25 Nov 2017 15:27:05 +0100 Subject: [PATCH 088/235] Add Binary : Accepted --- README.md | 1 + problems/src/string/AddBinary.java | 50 ++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 problems/src/string/AddBinary.java diff --git a/README.md b/README.md index 9c18a0d8..d2d2dd18 100644 --- a/README.md +++ b/README.md @@ -183,6 +183,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Valid Palindrome](problems/src/string/ValidPalindrome.java) (Easy) - [Simplify Path](problems/src/string/SimplifyPath.java) (Medium) - [Permutation in String](problems/src/string/PermutationInString.java) (Medium) +- [Add Binary](problems/src/string/AddBinary.java) (Easy) #### [Tree](problems/src/tree) diff --git a/problems/src/string/AddBinary.java b/problems/src/string/AddBinary.java new file mode 100644 index 00000000..04f823e1 --- /dev/null +++ b/problems/src/string/AddBinary.java @@ -0,0 +1,50 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 25/11/2017. + * + * Given two binary strings, return their sum (also a binary string). + + For example, + a = "11" + b = "1" + Return "100". + */ +public class AddBinary { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + System.out.println(new AddBinary().addBinary("000001010000101001", "0")); + } + + public String addBinary(String a, String b) { + if(a.length() > b.length()){ + return calculate(a, b); + } else return calculate(b, a); + } + + /** + * Calculate sum + * @param a length of a should always be greater or equal to b + * @param b length of b should always be smaller of equal to a + * @return + */ + private String calculate(String a, String b){ + int carry = 0; + int d = a.length() - b.length(); + StringBuilder sb = new StringBuilder(); + for(int i = a.length() - 1; i >= 0; i --){ + int first = Integer.parseInt(String.valueOf(a.charAt(i))); + int second = i - d >= 0 ? Integer.parseInt(String.valueOf(b.charAt(i - d))) : 0; + int sum = (first + second + carry); + carry = sum / 2; + sb.append(sum % 2); + } + if(carry != 0) + sb.append(carry); + return sb.reverse().toString(); + } +} From 97e0fdfdb2d7e84929338b269f1deb03c74ad3c9 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Mon, 27 Nov 2017 00:50:32 +0100 Subject: [PATCH 089/235] TaskScheduler and Meeting Rooms II : Accepted --- README.md | 2 + problems/src/greedy/TaskScheduler.java | 93 ++++++++++++++++++++++++++ problems/src/heap/MeetingRoomsII.java | 57 ++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 problems/src/greedy/TaskScheduler.java create mode 100644 problems/src/heap/MeetingRoomsII.java diff --git a/README.md b/README.md index d2d2dd18..3d782d4a 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Non-Overlapping Intervals](problems/src/greedy/NonOverlappingIntervals.java) (Medium) - [Minimum Number of Arrows to Burst Balloons](problems/src/greedy/BurstBalloons.java) (Medium) - [Queue Reconstruction By Height](problems/src/greedy/QueueReconstructionByHeight.java) (Medium) +- [Task Scheduler](problems/src/greedy/TaskScheduler.java) (Medium) #### [Hashing](problems/src/hashing) @@ -136,6 +137,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Sliding Window Maximum](problems/src/heap/SlidingWindowMaximum.java) (Hard) - [The Skyline Problem](problems/src/heap/TheSkylineProblem.java) (Hard) +- [Meeting Rooms II](problems/src/heap/MeetingRoomsII.java) (Medium) #### [Linked List](problems/src/linked_list) diff --git a/problems/src/greedy/TaskScheduler.java b/problems/src/greedy/TaskScheduler.java new file mode 100644 index 00000000..96475a6a --- /dev/null +++ b/problems/src/greedy/TaskScheduler.java @@ -0,0 +1,93 @@ +package greedy; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 26/11/2017. + * + * Given a char array representing tasks CPU need to do. It contains capital letters A to Z where different letters represent different tasks.Tasks could be done without original order. Each task could be done in one interval. For each interval, CPU could finish one task or just be idle. + + However, there is a non-negative cooling interval n that means between two same tasks, there must be at least n intervals that CPU are doing different tasks or just be idle. + + You need to return the least number of intervals the CPU will take to finish all the given tasks. + + Example 1: + Input: tasks = ["A","A","A","B","B","B"], n = 2 + Output: 8 + Explanation: A -> B -> idle -> A -> B -> idle -> A -> B. + Note: + The number of tasks is in the range [1, 10000]. + The integer n is in the range [0, 100]. + + */ +public class TaskScheduler { + + class Task { + char t; + int count; + Task(char t, int count){ + this.t = t; + this.count = count; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + } + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + char[] tasks = {'A','A','A','B','B','B'}; + System.out.println(new TaskScheduler().leastInterval(tasks, 2)); + } + + /** + * + * @param tasks + * @param n + * @return + */ + public int leastInterval(char[] tasks, int n) { + PriorityQueue queue = new PriorityQueue<>(Comparator.comparing(Task::getCount).reversed()); + List waiting = new ArrayList<>(); + Map map = new HashMap<>(); + for(char c : tasks){ + if(map.get(c) == null){ + map.put(c, 1); + } else{ + int v = map.get(c) + 1; + map.put(c, v); + } + } + for(char c : map.keySet()){ + Task task = new Task(c, map.get(c)); + queue.offer(task); + } + int count = 0; + while(!queue.isEmpty()){ + int i = 0; + while(i <= n){ + if(!queue.isEmpty()){ + Task task = queue.poll(); + task.count--; + if(task.count > 0){ + waiting.add(task); + } + } + count++; + if(queue.isEmpty() && waiting.isEmpty()) break; + i++; + } + queue.addAll(waiting); + waiting.clear(); + } + return count; + } +} diff --git a/problems/src/heap/MeetingRoomsII.java b/problems/src/heap/MeetingRoomsII.java new file mode 100644 index 00000000..d152686b --- /dev/null +++ b/problems/src/heap/MeetingRoomsII.java @@ -0,0 +1,57 @@ +package heap; + +import java.util.Arrays; +import java.util.PriorityQueue; + +/** + * Created by gouthamvidyapradhan on 27/11/2017. + * Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), find the minimum number of conference rooms required. + + For example, + Given [[0, 30],[5, 10],[15, 20]], + return 2. + + Solution: Sort the array based on start-time of the interval. Then, use the min-heap based on min end time. For + every interval remove the top element of the priority queue if the end time of the top <= start time of the new + interval. Add the new interval to the queue. The max size of the priority queue attained during this process + will be the answer. + */ +public class MeetingRoomsII { + + public static class Interval { + int start; + int end; + Interval() { start = 0; end = 0; } + Interval(int s, int e) { start = s; end = e; } + } + /** + * Main method + * @param args + */ + public static void main(String[] args) { + Interval i1 = new Interval(0, 40); + Interval i2 = new Interval(2, 10); + Interval i3 = new Interval(10, 40); + Interval i4 = new Interval(15, 20); + Interval i5 = new Interval(20, 30); + Interval i6 = new Interval(20, 40); + Interval i7 = new Interval(1, 5); + Interval[] intervals = {i1, i2, i3, i4, i5, i6, i7}; + System.out.println(minMeetingRooms(intervals)); + } + + public static int minMeetingRooms(Interval[] intervals) { + Arrays.sort(intervals, (a, b) -> Integer.compare(a.start, b.start)); + PriorityQueue queue = new PriorityQueue<>((a, b) -> Integer.compare(a.end, b.end)); + int max = 0; + for(Interval i : intervals){ + while(!queue.isEmpty() && queue.peek().end <= i.start){ + queue.poll(); + } + queue.offer(i); + max = Math.max(max, queue.size()); + } + return max; + } + +} From 491cf15b1f4eb465599212872c2a7938483f8315 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Mon, 27 Nov 2017 01:09:15 +0100 Subject: [PATCH 090/235] MeetingRooms : Accepted --- README.md | 1 + problems/src/array/MeetingRooms.java | 43 ++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 problems/src/array/MeetingRooms.java diff --git a/README.md b/README.md index 3d782d4a..06b48c0f 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Sort Colors](problems/src/array/SortColors.java) (Medium) - [Battleships in a Board](problems/src/array/BattleshipsInABoard.java) (Medium) - [Find the Celebrity](problems/src/array/FindTheCelebrity.java) (Medium) +- [Meeting Rooms](problems/src/array/MeetingRooms.java) (Easy) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/MeetingRooms.java b/problems/src/array/MeetingRooms.java new file mode 100644 index 00000000..e9a48074 --- /dev/null +++ b/problems/src/array/MeetingRooms.java @@ -0,0 +1,43 @@ +package array; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 27/11/2017. + * Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), determine if a person could attend all meetings. + + For example, + Given [[0, 30],[5, 10],[15, 20]], + return false. + + Solution: Sort the interval based on the start interval. Then, for every interval check if the previous interval + ends before the start of the current interval. + */ +public class MeetingRooms { + + public static class Interval { + int start; + int end; + Interval() { start = 0; end = 0; } + Interval(int s, int e) { start = s; end = e; } + } + + public static void main(String[] args) throws Exception{ + Interval i1 = new Interval(0, 30); + Interval i2 = new Interval(5, 10); + Interval i3 = new Interval(15, 20); + Interval[] intervals = {i1, i2, i3}; + + System.out.println(new MeetingRooms().canAttendMeetings(intervals)); + } + + public boolean canAttendMeetings(Interval[] intervals) { + Arrays.sort(intervals, (a, b) -> Integer.compare(a.start, b.start)); + for(int i = 1; i < intervals.length; i ++){ + if(intervals[i].start < intervals[i - 1].end) + return false; + } + return true; + } + +} From 715da202ed7eebf35468754ffe6582771db4be73 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 28 Nov 2017 02:12:35 +0100 Subject: [PATCH 091/235] Maximal Square : Accepted --- README.md | 1 + .../dynamic_programming/MaximalSquare.java | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 problems/src/dynamic_programming/MaximalSquare.java diff --git a/README.md b/README.md index 06b48c0f..7a64f2d9 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Dungeon Game](problems/src/dynamic_programming/DungeonGame.java) (Hard) - [2 Keys Keyboard](problems/src/dynamic_programming/TwoKeysKeyboard.java) (Medium) - [Maximum Sum of 3 Non-Overlapping Subarrays](problems/src/dynamic_programming/MaxSum3SubArray.java) (Hard) +- [Maximal Square](problems/src/dynamic_programming/MaximalSquare.java) (Medium) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/MaximalSquare.java b/problems/src/dynamic_programming/MaximalSquare.java new file mode 100644 index 00000000..c8b367ec --- /dev/null +++ b/problems/src/dynamic_programming/MaximalSquare.java @@ -0,0 +1,52 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 28/11/2017. + * Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area. + + For example, given the following matrix: + + 1 0 1 0 0 + 1 0 1 1 1 + 1 1 1 1 1 + 1 0 0 1 0 + Return 4. + + Solution: O(n * m) time and space complexity. + Calculate the max length of a square using DP(i, j) = min(DP[i - 1][j], DP[i][j - 1], DP[i - 1][j - 1]) + 1 + Return the square of the answer. + */ +public class MaximalSquare { + /** + * Main method + * @param args + */ + public static void main(String[] args) { + char[][] A = {{'1','0','1','0','0'}, {'1','0','1','1','1'}, {'1','1','1','1','1'}, {'1','0','0','1','0'}}; + System.out.println(new MaximalSquare().maximalSquare(A)); + } + + public int maximalSquare(char[][] matrix) { + if(matrix.length == 0) return 0; + int[][] dp = new int[matrix.length][matrix[0].length]; + for(int i = 0; i < matrix.length; i ++){ + for(int j = 0; j < matrix[0].length; j++){ + if(j - 1 >= 0 && i - 1 >= 0){ + if(matrix[i][j] == '1'){ + dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]); + dp[i][j] = Math.min(dp[i][j], dp[i - 1][j - 1]) + 1; + } + } else { + dp[i][j] = matrix[i][j] == '1' ? 1 : 0; + } + } + } + int max = 0; + for(int i = 0; i < dp.length; i++){ + for(int j = 0; j < dp[0].length; j++){ + max = Math.max(max, dp[i][j]); + } + } + return max * max; + } +} From 62c54cecaabb2745f0300e73a4f5e1269bdc776e Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 29 Nov 2017 01:51:35 +0100 Subject: [PATCH 092/235] Maximal Rectangle : Accepted --- README.md | 1 + problems/src/stack/MaximalRectangle.java | 80 ++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 problems/src/stack/MaximalRectangle.java diff --git a/README.md b/README.md index 7a64f2d9..374dafab 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Valid Parentheses](problems/src/stack/ValidParentheses.java) (Easy) - [Largest Rectangle In Histogram](problems/src/stack/LargestRectangleInHistogram.java) (Hard) - [Implement Queue using Stacks](problems/src/stack/MyQueue.java) (Easy) +- [Maximal Rectangle](problems/src/stack/MaximalRectangle.java) (Hard) #### [String](problems/src/string) diff --git a/problems/src/stack/MaximalRectangle.java b/problems/src/stack/MaximalRectangle.java new file mode 100644 index 00000000..7840e5ae --- /dev/null +++ b/problems/src/stack/MaximalRectangle.java @@ -0,0 +1,80 @@ +package stack; + +import java.util.Stack; + +/** + * Created by gouthamvidyapradhan on 29/11/2017. + * + * Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area. + + For example, given the following matrix: + + 1 0 1 0 0 + 1 0 1 1 1 + 1 1 1 1 1 + 1 0 0 1 0 + Return 6. + + Solution O(n * m): This problem is similar to LargestRectangleInHistogram. + Run the largest rectangle in histogram algorithm for each row. + */ +public class MaximalRectangle { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + char[][] matrix = {{'1','0','1','0','0'}, {'1', '0', '1', '1', '1'}, {'1', '1', '1', '1', '1'}, + {'1', '0', '0', '1', '0'}}; + System.out.println(new MaximalRectangle().maximalRectangle(matrix)); + } + + public int maximalRectangle(char[][] matrix) { + if(matrix.length == 0 || matrix[0].length == 0) return 0; + int[] A = new int[matrix[0].length]; + int max = Integer.MIN_VALUE; + for(int i = 0; i < matrix.length; i ++){ + for(int j = 0; j < matrix[0].length; j++){ + if(matrix[i][j] == '1'){ + if(i > 0 && matrix[i - 1][j] == '1'){ + A[j] = A[j] + 1; + } else{ + A[j] = 1; + } + } else { + A[j] = 0; + } + } + //calculate max rectangle for this row + max = Math.max(max, getMaxRectangle(A)); + } + return max; + } + + /** + * Get max rectangle algorithm similar to max rectangle in histogram + * @param heights + * @return + */ + private int getMaxRectangle(int[] heights){ + int maxArea = Integer.MIN_VALUE; + Stack stack = new Stack<>(); + int i = 0; + for (; i < heights.length; i++) { + while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) { + int top = stack.pop(); + int base = stack.isEmpty() ? i : i - stack.peek() - 1; + maxArea = Math.max(maxArea, base * heights[top]); + } + stack.push(i); + } + while (!stack.isEmpty()) { + int top = stack.pop(); + int base = stack.isEmpty() ? i : i - stack.peek() - 1; + maxArea = Math.max(maxArea, base * heights[top]); + } + return maxArea; + } +} From 33fa48fde40b820261c7b3dffd989883bb9c2f4f Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 29 Nov 2017 02:32:57 +0100 Subject: [PATCH 093/235] First Bad Version : Accepted --- README.md | 1 + .../src/binary_search/FirstBadVersion.java | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 problems/src/binary_search/FirstBadVersion.java diff --git a/README.md b/README.md index 374dafab..e2d40a44 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Median of Two Sorted Arrays](problems/src/binary_search/MedianOfTwoSortedArrays.java) (Hard) - [Pow(x, n)](problems/src/binary_search/PowXN.java) (Medium) - [Find Peak Element](problems/src/binary_search/FindPeakElement.java) (Medium) +- [First Bad Version](problems/src/binary_search/FirstBadVersion.java) (Easy) #### [Bit Manipulation](problems/src/bit_manipulation) diff --git a/problems/src/binary_search/FirstBadVersion.java b/problems/src/binary_search/FirstBadVersion.java new file mode 100644 index 00000000..51f68fe9 --- /dev/null +++ b/problems/src/binary_search/FirstBadVersion.java @@ -0,0 +1,37 @@ +package binary_search; + +/** + * Created by gouthamvidyapradhan on 29/11/2017. + * + * You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version + * of your product fails the quality check. Since each version is developed based on the previous version, + * all the versions after a bad version are also bad. + + Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, which causes all the + following ones to be bad. + + You are given an API bool isBadVersion(version) which will return whether version is bad. Implement a function to + find the first bad version. You should minimize the number of calls to the API. + */ +public class FirstBadVersion { + public static void main(String[] args) throws Exception{ + System.out.println(new FirstBadVersion().firstBadVersion(2126753390)); + } + + public int firstBadVersion(int n) { + int low = 0, high = n; + while(low < high){ + int mid = (low + high) >>> 1; + if(isBadVersion(mid)){ + high = mid; + } else low = mid + 1; + } + return high; + } + + private boolean isBadVersion(int n){ + if(n >= 1702766719) + return true; + return false; + } +} From a4ba73bdfcf833326bc247f7c09750784d91e21d Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 30 Nov 2017 23:45:00 +0100 Subject: [PATCH 094/235] Flatten Nested List Iterator : Accepted --- README.md | 1 + problems/src/design/NestedIterator.java | 78 +++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 problems/src/design/NestedIterator.java diff --git a/README.md b/README.md index e2d40a44..c25ffd1a 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Binary Search Tree Iterator](problems/src/design/BSTIterator.java) (Medium) - [Design Search Autocomplete System](problems/src/design/AutocompleteSystem.java) (Hard) - [Design Excel Sum Formula](problems/src/design/Excel.java) (Hard) +- [Flatten Nested List Iterator](problems/src/design/NestedIterator.java) (Medium) #### [Divide and Conquer](problems/src/divide_and_conquer) diff --git a/problems/src/design/NestedIterator.java b/problems/src/design/NestedIterator.java new file mode 100644 index 00000000..9ce14219 --- /dev/null +++ b/problems/src/design/NestedIterator.java @@ -0,0 +1,78 @@ +package design; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Created by gouthamvidyapradhan on 30/11/2017. + * + * Given a nested list of integers, implement an iterator to flatten it. + + Each element is either an integer, or a list -- whose elements may also be integers or other lists. + + Example 1: + Given the list [[1,1],2,[1,1]], + + By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,1,2,1,1]. + + Example 2: + Given the list [1,[4,[6]]], + + By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,4,6]. + */ +public class NestedIterator implements Iterator{ + + private List result; + private int curr, size; + + // This is the interface that allows for creating nested lists. + // You should not implement it, or speculate about its implementation + public interface NestedInteger{ + //@return true if this NestedInteger holds a single integer, rather than a nested list. + 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 nested list that this NestedInteger holds, if it holds a nested list + // Return null if this NestedInteger holds a single integer + public List getList(); + } + + public NestedIterator(List nestedList) { + this.result = new ArrayList<>(); + curr = 0; + flatten(result, nestedList); + size = result.size(); + } + + @Override + public Integer next() { + if(curr < size){ + return result.get(curr++); + } + return -1; + } + + @Override + public boolean hasNext() { + return curr < size; + } + + public static void main(String[] args) { + + } + + private void flatten(List flatList, List nestedList){ + for(NestedInteger n : nestedList){ + if(n.isInteger()){ + flatList.add(n.getInteger()); + } else{ + flatten(flatList, n.getList()); + } + } + } + +} From 76824bd23b075a60896c459b16c9419031f957d4 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 1 Dec 2017 00:52:28 +0100 Subject: [PATCH 095/235] Total Hamming Distance : Accepted --- README.md | 1 + .../TotalHammingDistance.java | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 problems/src/bit_manipulation/TotalHammingDistance.java diff --git a/README.md b/README.md index c25ffd1a..9f118c23 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ My accepted leetcode solutions to some of the common interview problems. #### [Bit Manipulation](problems/src/bit_manipulation) - [Gray Code](problems/src/bit_manipulation/GrayCode.java) (Medium) +- [Total Hamming Distance](problems/src/bit_manipulation/TotalHammingDistance.java) (Medium) #### [Breadth First Search](problems/src/breadth_first_search) diff --git a/problems/src/bit_manipulation/TotalHammingDistance.java b/problems/src/bit_manipulation/TotalHammingDistance.java new file mode 100644 index 00000000..411f2672 --- /dev/null +++ b/problems/src/bit_manipulation/TotalHammingDistance.java @@ -0,0 +1,49 @@ +package bit_manipulation; + +/** + * Created by gouthamvidyapradhan on 01/12/2017. + * The Hamming distance between two integers is the number of positions at which the corresponding bits are different. + + Now your job is to find the total Hamming distance between all pairs of the given numbers. + + Example: + Input: 4, 14, 2 + + Output: 6 + + Explanation: In binary representation, the 4 is 0100, 14 is 1110, and 2 is 0010 (just + showing the four bits relevant in this case). So the answer will be: + HammingDistance(4, 14) + HammingDistance(4, 2) + HammingDistance(14, 2) = 2 + 2 + 2 = 6. + Note: + Elements of the given array are in the range of 0 to 10^9 + Length of the array will not exceed 10^4. + + Solution: O(N * 32): Count the number of set bits in each of 32 bit positions and then take the sum of + product of number of set bits x number of un-set bits + */ +public class TotalHammingDistance { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1000000000, 4, 14, 2}; + System.out.println(new TotalHammingDistance().totalHammingDistance(A)); + } + + public int totalHammingDistance(int[] nums) { + int sum = 0; + for(int i = 0; i < 32; i ++){ + int numOfOnes = 0; + int p = (1 << i); + for (int num : nums) { + if ((num & p) > 0) { + numOfOnes++; + } + } + sum += ((nums.length - numOfOnes) * numOfOnes); + } + return sum; + } +} From 455fa5568219d32bee998ba51a9d4f463dfcbdfe Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 2 Dec 2017 23:56:40 +0100 Subject: [PATCH 096/235] Alien Dictionary : Accepted --- README.md | 1 + .../depth_first_search/AlienDictionary.java | 145 ++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 problems/src/depth_first_search/AlienDictionary.java diff --git a/README.md b/README.md index 9f118c23..fc267b7f 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Number Of Islands](problems/src/depth_first_search/NumberOfIslands.java) (Medium) - [Course Schedule](problems/src/depth_first_search/CourseSchedule.java) (Medium) - [Course Schedule II](problems/src/depth_first_search/CourseScheduleII.java) (Medium) +- [Alien Dictionary](problems/src/depth_first_search/AlienDictionary.java) (Hard) #### [Design](problems/src/design) diff --git a/problems/src/depth_first_search/AlienDictionary.java b/problems/src/depth_first_search/AlienDictionary.java new file mode 100644 index 00000000..7e0cc387 --- /dev/null +++ b/problems/src/depth_first_search/AlienDictionary.java @@ -0,0 +1,145 @@ +package depth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 02/12/2017. + * There is a new alien language which uses the latin alphabet. However, the order among letters are unknown + * to you. You receive a list of non-empty words from the dictionary, where words are sorted lexicographically by the + * rules of this new language. Derive the order of letters in this language. + + Example 1: + Given the following words in dictionary, + + [ + "wrt", + "wrf", + "er", + "ett", + "rftt" + ] + The correct order is: "wertf". + + Example 2: + Given the following words in dictionary, + + [ + "z", + "x" + ] + The correct order is: "zx". + + Example 3: + Given the following words in dictionary, + + [ + "z", + "x", + "z" + ] + The order is invalid, so return "". + + Note: + You may assume all letters are in lowercase. + You may assume that if a is a prefix of b, then a must appear before b in the given dictionary. + If the order is invalid, return an empty string. + There may be multiple valid order of letters, return any one of them is fine. + + Solution: Build a graph with with character links and perform a topological sort. Topological sort can be + performed only on a DAG hence if there is a cycle immediately return empty string + + */ +public class AlienDictionary { + + private Map> graph; + private Set done; + private Set visited; + private Stack toposort; + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + String[] words = {"z", "x", "z"}; + System.out.println(new AlienDictionary().alienOrder(words)); + } + + public String alienOrder(String[] words) { + graph = new HashMap<>(); + done = new HashSet<>(); + visited = new HashSet<>(); + toposort = new Stack<>(); + boolean[] A = new boolean[26]; + for(int i = 0; i < words.length - 1; i ++){ + for(int j = 0, l = Math.min(words[i].length(), words[i + 1].length()); j < l; j++){ + if(words[i].charAt(j) != words[i + 1].charAt(j)){ + graph.putIfAbsent(words[i].charAt(j), new ArrayList<>()); + graph.get(words[i].charAt(j)).add(words[i + 1].charAt(j)); + break; + } + } + } + + for(String w : words){ + for(int i = 0, l = w.length(); i < l; i++){ + A[w.charAt(i) - 'a'] = true; + } + } + + for(char c : graph.keySet()){ + if(!done.contains(c)){ + if(!dfs(c)) return ""; + } + } + + StringBuilder sb = new StringBuilder(); + while(!toposort.isEmpty()){ + sb.append(toposort.pop()); + } + + //Add remaining elements. This can come in any order. + String result = sb.toString(); + StringBuilder remaining = new StringBuilder(); + for(int i = 0; i < 26; i ++){ + if(A[i]){ + char c = (char)(i + 'a'); + boolean found = false; + for(char r : result.toCharArray()){ + if(r == c){ + found = true; + break; + } + } + if(!found){ + remaining.append(c); + } + } + } + return result.concat(remaining.toString().trim()); + } + + /** + * Dfs to toposort + * @param u + * @return + */ + private boolean dfs(char u){ + done.add(u); + visited.add(u); + List children = graph.get(u); + if(children != null){ + for(char c : children){ + if(visited.contains(c)) return false; //check cycle + if(!done.contains(c)){ + boolean status = dfs(c); + if(!status) return false; + } + } + } + toposort.push(u); + visited.remove(u); + return true; + } +} From c40cf32cc0637f0ca3b58ba108665b99d2bd7f2b Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 3 Dec 2017 00:10:13 +0100 Subject: [PATCH 097/235] Longest Continuous Increasing Subsequence: Accepted --- README.md | 1 + .../array/LongestIncreasingSubsequence.java | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 problems/src/array/LongestIncreasingSubsequence.java diff --git a/README.md b/README.md index fc267b7f..b5ebc804 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Battleships in a Board](problems/src/array/BattleshipsInABoard.java) (Medium) - [Find the Celebrity](problems/src/array/FindTheCelebrity.java) (Medium) - [Meeting Rooms](problems/src/array/MeetingRooms.java) (Easy) +- [Longest Continuous Increasing Subsequence](problems/src/array/LongestIncreasingSubsequence.java) (Easy) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/LongestIncreasingSubsequence.java b/problems/src/array/LongestIncreasingSubsequence.java new file mode 100644 index 00000000..39e5e2f0 --- /dev/null +++ b/problems/src/array/LongestIncreasingSubsequence.java @@ -0,0 +1,48 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 03/12/2017. + * + * Given an unsorted array of integers, find the length of longest continuous increasing subsequence (subarray). + + Example 1: + Input: [1,3,5,4,7] + Output: 3 + Explanation: The longest continuous increasing subsequence is [1,3,5], its length is 3. + Even though [1,3,5,7] is also an increasing subsequence, it's not a continuous one where 5 and 7 are separated by 4. + Example 2: + Input: [2,2,2,2,2] + Output: 1 + Explanation: The longest continuous increasing subsequence is [2], its length is 1. + Note: Length of the array will not exceed 10,000. + */ +public class LongestIncreasingSubsequence { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1,3,5,4,7}; + System.out.println(new LongestIncreasingSubsequence().findLengthOfLCIS(A)); + } + + public int findLengthOfLCIS(int[] nums) { + int max = 1, count = 1; + if(nums.length == 1) return max; + if(nums.length == 0) return 0; + for(int i = 0, j = i + 1; j < nums.length;){ + if(nums[j] > nums[i]){ + count++; + i++; j++; + } else { + max = Math.max(max, count); + count = 0; + i = j; + j = i + 1; + } + } + return max; + } +} From fbfffdf1e9ef3066d1b3f63ddaf3c556d46be107 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 3 Dec 2017 00:59:04 +0100 Subject: [PATCH 098/235] Minimum Size Subarray Sum: Accepted --- README.md | 1 + .../two_pointers/MinimumSizeSubarraySum.java | 56 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 problems/src/two_pointers/MinimumSizeSubarraySum.java diff --git a/README.md b/README.md index b5ebc804..036ba261 100644 --- a/README.md +++ b/README.md @@ -233,3 +233,4 @@ My accepted leetcode solutions to some of the common interview problems. - [3Sum Closest](problems/src/two_pointers/ThreeSumClosest.java) (Medium) - [Move Zeroes](problems/src/two_pointers/MoveZeroes.java) (Easy) - [Remove Duplicates](problems/src/two_pointers/RemoveDuplicates.java) (Easy) +- [Minimum Size Subarray Sum](problems/src/two_pointers/MinimumSizeSubarraySum.java) (Medium) diff --git a/problems/src/two_pointers/MinimumSizeSubarraySum.java b/problems/src/two_pointers/MinimumSizeSubarraySum.java new file mode 100644 index 00000000..de30cb1e --- /dev/null +++ b/problems/src/two_pointers/MinimumSizeSubarraySum.java @@ -0,0 +1,56 @@ +package two_pointers; + +/** + * Created by gouthamvidyapradhan on 03/12/2017. + * + * Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous + * subarray of which the sum ≥ s. If there isn't one, return 0 instead. + + For example, given the array [2,3,1,2,4,3] and s = 7, + the subarray [4,3] has the minimal length under the problem constraint. + + click to show more practice. + + Credits: + Special thanks to @Freezen for adding this problem and creating all test cases. + + Solution: O(n) solution. Solve using sliding window sub-array sum using two pointers. + */ +public class MinimumSizeSubarraySum { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] nums = {2,3,1,2,4,3}; + System.out.println(new MinimumSizeSubarraySum().minSubArrayLen(7, nums)); + } + + public int minSubArrayLen(int s, int[] nums) { + int sum = 0, count = 0, min = Integer.MAX_VALUE; + for(int i = 0, j = 0; j < nums.length;){ + if(nums[j] >= s){ + return 1; + } else{ + sum += nums[j]; + count ++; + if(sum >= s){ + min = Math.min(min, count); + while(j > i){ + sum -= nums[i]; + count --; + i ++; + if(sum < s) break; + min = Math.min(min, count); + } + } + } + j ++; + } + if(min == Integer.MAX_VALUE){ + return 0; + } + return min; + } +} From e736b60f2de5111e6b33ab781bdf6efa6ee9e56a Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 3 Dec 2017 01:58:48 +0100 Subject: [PATCH 099/235] Minimum Window Substring: Accepted --- README.md | 1 + .../two_pointers/MinimumWindowSubstring.java | 84 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 problems/src/two_pointers/MinimumWindowSubstring.java diff --git a/README.md b/README.md index 036ba261..e47e2efe 100644 --- a/README.md +++ b/README.md @@ -234,3 +234,4 @@ My accepted leetcode solutions to some of the common interview problems. - [Move Zeroes](problems/src/two_pointers/MoveZeroes.java) (Easy) - [Remove Duplicates](problems/src/two_pointers/RemoveDuplicates.java) (Easy) - [Minimum Size Subarray Sum](problems/src/two_pointers/MinimumSizeSubarraySum.java) (Medium) +- [Minimum Window Substring](problems/src/two_pointers/MinimumWindowSubstring.java) (Hard) diff --git a/problems/src/two_pointers/MinimumWindowSubstring.java b/problems/src/two_pointers/MinimumWindowSubstring.java new file mode 100644 index 00000000..39089823 --- /dev/null +++ b/problems/src/two_pointers/MinimumWindowSubstring.java @@ -0,0 +1,84 @@ +package two_pointers; + +/** + * Created by gouthamvidyapradhan on 03/12/2017. + * + * Given a string S and a string T, find the minimum window in S which will contain all the characters in + * T in complexity O(n). + + For example, + S = "ADOBECODEBANC" + T = "ABC" + Minimum window is "BANC". + + Note: + If there is no such window in S that covers all characters in T, return the empty string "". + + If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S. + + Solution O(n). Sliding window sub-sting using two pointers. + + */ +public class MinimumWindowSubstring { + private int[] hash = new int[256]; + private int[] curr = new int[256]; + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new MinimumWindowSubstring().minWindow("ADOBECODEBANC", "ABC")); + } + + public String minWindow(String s, String t) { + if(s.isEmpty() && t.isEmpty()) return ""; + if(t.length() > s.length()) return ""; + int start = -1, end = -1, min = Integer.MAX_VALUE; + for(int i = 0, l = t.length(); i < l; i ++){ + hash[t.charAt(i)]++; + } + + for(int i = 0, l = t.length() - 1; i < l; i ++){ + curr[s.charAt(i)]++; + } + + for(int i = 0, j = t.length() - 1, l = s.length(); j < l;){ + curr[s.charAt(j)]++; + if(isMatch()){ + if(j - i < min){ + min = j - i; + start = i; + end = j; + } + while(j > i){ + curr[s.charAt(i)]--; + i ++; + if(isMatch()){ + if(j - i < min){ + min = j - i; + start = i; + end = j; + } + } else break; + } + } + j ++; + } + if(min == Integer.MAX_VALUE){ + return ""; + } + return s.substring(start, end + 1); + } + + + private boolean isMatch(){ + for(int i = 0; i < 256; i ++){ + if(curr[i] < hash[i]){ + return false; + } + } + return true; + } +} From 2928b8204958de5625934af35907f5b799d5bfd3 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 3 Dec 2017 03:14:47 +0100 Subject: [PATCH 100/235] Sparse Matrix Multiplication: Accepted --- README.md | 1 + .../src/array/SparseMatrixMultiplication.java | 80 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 problems/src/array/SparseMatrixMultiplication.java diff --git a/README.md b/README.md index e47e2efe..f7726318 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Find the Celebrity](problems/src/array/FindTheCelebrity.java) (Medium) - [Meeting Rooms](problems/src/array/MeetingRooms.java) (Easy) - [Longest Continuous Increasing Subsequence](problems/src/array/LongestIncreasingSubsequence.java) (Easy) +- [Sparse Matrix Multiplication](problems/src/array/SparseMatrixMultiplication.java) (Medium) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/SparseMatrixMultiplication.java b/problems/src/array/SparseMatrixMultiplication.java new file mode 100644 index 00000000..1a9d0cfe --- /dev/null +++ b/problems/src/array/SparseMatrixMultiplication.java @@ -0,0 +1,80 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 03/12/2017. + * + * Given two sparse matrices A and B, return the result of AB. + + You may assume that A's column number is equal to B's row number. + + Example: + + A = [ + [ 1, 0, 0], + [-1, 0, 3] + ] + + B = [ + [ 7, 0, 0 ], + [ 0, 0, 0 ], + [ 0, 0, 1 ] + ] + + + | 1 0 0 | | 7 0 0 | | 7 0 0 | + AB = | -1 0 3 | x | 0 0 0 | = | -7 0 3 | + | 0 0 1 | + + Solution: Skip the rows and columns which you already know would result in zero after multiplication. + */ +public class SparseMatrixMultiplication { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[][] A = {{1,0,0,1}}; + int[][] B = {{7,0,0}, {0,0,0}, {0,0,1}, {0,0,1}}; + int[][] C = new SparseMatrixMultiplication().multiply(A, B); + } + + public int[][] multiply(int[][] A, int[][] B) { + boolean[] AH = new boolean[A.length]; // Metadata for matrix A + boolean[] BH = new boolean[B[0].length]; // Metadata for matrix A + for(int i = 0; i < A.length; i ++){ + for(int j = 0; j < A[0].length; j ++){ + if(A[i][j] != 0){ + AH[i] = true; + break; + } + } + } + + for(int i = 0; i < B[0].length; i ++){ + for(int j = 0; j < B.length; j ++){ + if(B[j][i] != 0){ + BH[i] = true; + break; + } + } + } + + int[][] C = new int[A.length][B[0].length]; + for(int i = 0; i < C.length; i ++){ + if(AH[i]){ + for(int j = 0; j < C[0].length; j++){ + if(BH[j]){ + int sum = 0; + for(int k = 0; k < A[0].length; k++){ + sum += A[i][k] * B[k][j]; + } + C[i][j] = sum; + } + } + } + } + return C; + } +} From f867737beeebbc1b8fc66c429341c771e436fe4c Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 5 Dec 2017 02:55:58 +0100 Subject: [PATCH 101/235] Regular Expression Matching: Accepted --- README.md | 1 + .../RegularExpressionMatching.java | 76 +++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 problems/src/backtracking/RegularExpressionMatching.java diff --git a/README.md b/README.md index f7726318..d6abdd4c 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Word Search II](problems/src/backtracking/WordSearchII.java) (Hard) - [Generate Parentheses](problems/src/backtracking/GenerateParentheses.java) (Medium) - [Remove Invalid Parentheses](problems/src/backtracking/RemoveInvalidParentheses.java) (Medium) +- [Regular Expression Matching](problems/src/backtracking/RegularExpressionMatching.java) (Hard) #### [Binary Search](problems/src/binary_search) diff --git a/problems/src/backtracking/RegularExpressionMatching.java b/problems/src/backtracking/RegularExpressionMatching.java new file mode 100644 index 00000000..aa98e3ea --- /dev/null +++ b/problems/src/backtracking/RegularExpressionMatching.java @@ -0,0 +1,76 @@ +package backtracking; + +/** + * Created by gouthamvidyapradhan on 05/12/2017. + * + * Implement regular expression matching with support for '.' and '*'. + + '.' Matches any single character. + '*' Matches zero or more of the preceding element. + + The matching should cover the entire input string (not partial). + + The function prototype should be: + bool isMatch(const char *s, const char *p) + + Some examples: + isMatch("aa","a") → false + isMatch("aa","aa") → true + isMatch("aaa","aa") → false + isMatch("aa", "a*") → true + isMatch("aa", ".*") → true + isMatch("ab", ".*") → true + isMatch("aab", "c*a*b") → true + + Solution: When a wildcard is encountered try to match all the possible prefixes including none, otherwise + do a simple one to one match. If the end of string is reached simultaneously in both string and pattern + then return true + */ +public class RegularExpressionMatching { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new RegularExpressionMatching().isMatch("aa", "a*a*a")); + } + + public boolean isMatch(String s, String p) { + return backTrack(0, 0, s, p); + } + + private boolean backTrack(int si, int pi, String s, String p){ + if(si >= s.length() && pi >= p.length()) return true; //end of the string has been reached hence return true + else { + if(pi >= p.length()) return false; //pattern has exhausted hence return false + else if(si >= s.length()){ + if(pi + 1 < p.length() && p.charAt(pi + 1) == '*'){ + return backTrack(si, pi + 2, s, p); + } else return false; //string has exhausted and pattern does not contain wildcard hence return false + } + else if(s.charAt(si) == p.charAt(pi) || p.charAt(pi) == '.'){ + if(pi + 1 < p.length() && p.charAt(pi + 1) == '*'){ + //match 0 or more repeated preceding element + if(backTrack(si, pi + 2, s, p)) return true; + for(int i = si, l = s.length(); i < l; i ++){ + if(s.charAt(i) == p.charAt(pi) || p.charAt(pi) == '.'){ + if(backTrack(i + 1, pi + 2, s, p)) return true; + } else { + return false; + } + } + return backTrack(s.length(), pi, s, p); + } else{ + return backTrack(si + 1, pi + 1, s, p); //not wildcard match immediate chars + } + } else{ + if(pi + 1 < p.length() && p.charAt(pi + 1) == '*'){ + return backTrack(si, pi + 2, s, p); + } else return false; + } + } + } + +} From 9a130676c3e88ff8e7abc5eb084dc75fb9fa0109 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 9 Dec 2017 12:37:20 +0100 Subject: [PATCH 102/235] Expression Add Operators: Accepted --- README.md | 1 + .../backtracking/ExpressionAddOperators.java | 70 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 problems/src/backtracking/ExpressionAddOperators.java diff --git a/README.md b/README.md index d6abdd4c..28bd7eeb 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Generate Parentheses](problems/src/backtracking/GenerateParentheses.java) (Medium) - [Remove Invalid Parentheses](problems/src/backtracking/RemoveInvalidParentheses.java) (Medium) - [Regular Expression Matching](problems/src/backtracking/RegularExpressionMatching.java) (Hard) +- [Expression Add Operators](problems/src/backtracking/ExpressionAddOperators.java) (Hard) #### [Binary Search](problems/src/binary_search) diff --git a/problems/src/backtracking/ExpressionAddOperators.java b/problems/src/backtracking/ExpressionAddOperators.java new file mode 100644 index 00000000..e057400e --- /dev/null +++ b/problems/src/backtracking/ExpressionAddOperators.java @@ -0,0 +1,70 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by gouthamvidyapradhan on 05/12/2017. + * Given a string that contains only digits 0-9 and a target value, return all possibilities to add binary operators + * (not unary) +, -, or * between the digits so they evaluate to the target value. + + Examples: + "123", 6 -> ["1+2+3", "1*2*3"] + "232", 8 -> ["2*3+2", "2+3*2"] + "105", 5 -> ["1*0+5","10-5"] + "00", 0 -> ["0+0", "0-0", "0*0"] + "3456237490", 9191 -> [] + + Solution: Backtrack and keep track of the total and product value. + In case of + or - add/sub curr to total and curr becomes the new product + In case of * take difference of total and prod and add (product of curr value with previous product and make this a + new product for the next iteration) + + Worst-case time complexity can be O(n * (2^n-1)) + */ +public class ExpressionAddOperators { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + List result = new ExpressionAddOperators().addOperators("202010201", 201); + result.stream().forEach(System.out::println); + } + + public List addOperators(String num, int target) { + List result = new ArrayList<>(); + backTrack("", result, 0, num, target, 0L, 0L); + return result; + } + + private void backTrack(String exp, List list, int curr, String num, int target, long total, + long prod){ + if(curr == num.length()){ + if(total == target){ + list.add(exp); + } + } + else { + for(int i = curr, l = num.length(); i < l; i ++){ + String newNum = num.substring(curr, i + 1); + if(newNum.length() > 1 && newNum.startsWith("0")) { + break; + } + long newNumL = Long.parseLong(newNum); + if(curr == 0){ + backTrack(newNum, list, i + 1, num, target, newNumL, newNumL); + } else { + backTrack(exp + "+" + newNum, list, i + 1, num, target, total + newNumL, newNumL); + + backTrack(exp + "-" + newNum, list, i + 1, num, target, total - newNumL, newNumL * -1L); + + backTrack(exp + "*" + newNum, list, i + 1, num, target, (total - prod + (prod * newNumL)), prod + * newNumL); + } + } + } + } + +} From b393590684234efd38a1eb69c2160b3e535be21d Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 9 Dec 2017 12:53:44 +0100 Subject: [PATCH 103/235] Valid Palindrome II: Accepted --- README.md | 1 + problems/src/string/ValidPalindromeII.java | 47 ++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 problems/src/string/ValidPalindromeII.java diff --git a/README.md b/README.md index 28bd7eeb..5915c9ec 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Simplify Path](problems/src/string/SimplifyPath.java) (Medium) - [Permutation in String](problems/src/string/PermutationInString.java) (Medium) - [Add Binary](problems/src/string/AddBinary.java) (Easy) +- [Valid Palindrome II](problems/src/string/ValidPalindromeII.java) (Easy) #### [Tree](problems/src/tree) diff --git a/problems/src/string/ValidPalindromeII.java b/problems/src/string/ValidPalindromeII.java new file mode 100644 index 00000000..b652e70f --- /dev/null +++ b/problems/src/string/ValidPalindromeII.java @@ -0,0 +1,47 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 09/12/2017. + * Given a non-empty string s, you may delete at most one character. Judge whether you can make it a palindrome. + + Example 1: + Input: "aba" + Output: True + Example 2: + Input: "abca" + Output: True + Explanation: You could delete the character 'c'. + Note: + The string will only contain lowercase characters a-z. The maximum length of the string is 50000. + */ +public class ValidPalindromeII { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new ValidPalindromeII().validPalindrome("aaaaaab")); + } + + public boolean validPalindrome(String s) { + for(int i = 0, j = s.length() - 1; i < j;){ + if(s.charAt(i) == s.charAt(j)){ + i++; j--; + } else { + return isPaliandrome(s.substring(i, j)) || isPaliandrome(s.substring(i + 1, j + 1)); + } + } + return true; + } + + private boolean isPaliandrome(String s){ + for(int i = 0, j = s.length() - 1; i < j;){ + if(s.charAt(i) == s.charAt(j)){ + i++; j--; + } else return false; + } + return true; + } +} From 7fa33426d026527a5ccf44239eb27f65de6eed65 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 9 Dec 2017 13:17:10 +0100 Subject: [PATCH 104/235] Binary Tree Paths: Accepted --- README.md | 1 + problems/src/tree/BinaryTreePaths.java | 47 ++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 problems/src/tree/BinaryTreePaths.java diff --git a/README.md b/README.md index 5915c9ec..ee4ef638 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Maximum Binary Tree](problems/src/tree/MaximumBinaryTree.java) (Medium) - [Find Bottom Left Tree Value](problems/src/tree/FindBottomLeftTreeValue.java) (Medium) - [Diameter of Binary Tree](problems/src/tree/DiameterOfBinaryTree.java) (Easy) +- [Binary Tree Paths](problems/src/tree/BinaryTreePaths.java) (Easy) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/BinaryTreePaths.java b/problems/src/tree/BinaryTreePaths.java new file mode 100644 index 00000000..13e49644 --- /dev/null +++ b/problems/src/tree/BinaryTreePaths.java @@ -0,0 +1,47 @@ +package tree; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by gouthamvidyapradhan on 09/12/2017. + * Given a binary tree, return all root-to-leaf paths. + + For example, given the following binary tree: + + 1 + / \ + 2 3 + \ + 5 + All root-to-leaf paths are: + + ["1->2->5", "1->3"] + */ +public class BinaryTreePaths { + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + public List binaryTreePaths(TreeNode root) { + List result = new ArrayList<>(); + new BinaryTreePaths().inorder(root, result, ""); + return result; + } + + private void inorder(TreeNode node, List list, String path){ + if(node != null){ + if(node.left == null && node.right == null){ + list.add(path + node.val); + } else { + inorder(node.left, list, path + node.val + "->"); + inorder(node.right, list, path + node.val + "->"); + } + } + } + +} From 1f31562213695bf86ccd78202165d2398d3d9b06 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 9 Dec 2017 17:06:28 +0100 Subject: [PATCH 105/235] Read N Characters Given Read4: Accepted --- README.md | 1 + problems/src/array/ReadNCharacters.java | 53 +++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 problems/src/array/ReadNCharacters.java diff --git a/README.md b/README.md index ee4ef638..f98cc1c3 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Meeting Rooms](problems/src/array/MeetingRooms.java) (Easy) - [Longest Continuous Increasing Subsequence](problems/src/array/LongestIncreasingSubsequence.java) (Easy) - [Sparse Matrix Multiplication](problems/src/array/SparseMatrixMultiplication.java) (Medium) +- [Read N Characters Given Read4](problems/src/array/ReadNCharacters.java) (Easy) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/ReadNCharacters.java b/problems/src/array/ReadNCharacters.java new file mode 100644 index 00000000..0dae036c --- /dev/null +++ b/problems/src/array/ReadNCharacters.java @@ -0,0 +1,53 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 09/12/2017. + * The API: int read4(char *buf) reads 4 characters at a time from a file. + + The return value is the actual number of characters read. For example, it returns 3 if there is only 3 characters + left in the file. + + By using the read4 API, implement the function int read(char *buf, int n) that reads n characters from the file. + + Note: + The read function will only be called once for each test case. + + + */ +public class ReadNCharacters { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + + } + + /** + * + * @param buf + * @param n + * @return + */ + public int read(char[] buf, int n) { + int i = 0; + int toRead = Math.min(n, buf.length); + while(i < toRead){ + char[] temp = new char[4]; + int r = read4(temp); + for(int j = 0; j < r && i < toRead; j ++){ + buf[i] = temp[j]; + i++; + } + if(r < 4) break; + } + return Math.min(i, toRead); + } + + + private int read4(char[] buf){ + return 1;//return fake value just to resolve compilation error + } + +} From 62e873afc06c8d84b87f7ef7786598ce3fb7cc97 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 9 Dec 2017 18:08:31 +0100 Subject: [PATCH 106/235] Add and Search Word - Data structure design: Accepted --- README.md | 1 + problems/src/design/WordDictionary.java | 128 ++++++++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 problems/src/design/WordDictionary.java diff --git a/README.md b/README.md index f98cc1c3..b81985b6 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Design Search Autocomplete System](problems/src/design/AutocompleteSystem.java) (Hard) - [Design Excel Sum Formula](problems/src/design/Excel.java) (Hard) - [Flatten Nested List Iterator](problems/src/design/NestedIterator.java) (Medium) +- [Add and Search Word - Data structure design](problems/src/design/WordDictionary.java) (Medium) #### [Divide and Conquer](problems/src/divide_and_conquer) diff --git a/problems/src/design/WordDictionary.java b/problems/src/design/WordDictionary.java new file mode 100644 index 00000000..6bae0965 --- /dev/null +++ b/problems/src/design/WordDictionary.java @@ -0,0 +1,128 @@ +package design; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by gouthamvidyapradhan on 09/12/2017. + * + * 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. + + For example: + + addWord("bad") + addWord("dad") + addWord("mad") + search("pad") -> false + search("bad") -> true + search(".ad") -> true + search("b..") -> true + Note: + You may assume that all words are consist of lowercase letters a-z. + + Solution: Implement a simple Trie and perform a search. + */ +public class WordDictionary { + + private Trie trie; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + WordDictionary wd = new WordDictionary(); + wd.addWord("bad"); + wd.addWord("dad"); + wd.addWord("mad"); + System.out.println(wd.search("pad")); + System.out.println(wd.search("bad")); + System.out.println(wd.search(".ad")); + System.out.println(wd.search("...")); + } + + /** Initialize your data structure here. */ + public WordDictionary() { + this.trie = new Trie(); + } + + /** Adds a word into the data structure. */ + public void addWord(String word) { + this.trie.insert(word); + } + + /** 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 this.trie.search(word); + } + + private class Trie { + + private Map map; + + /** + * Initialize your data structure here. + */ + private Trie() { + map = new HashMap<>(); + } + + /** + * Inserts a word into the trie. + */ + private void insert(String word) { + if (word != null) { + add(0, word, word.length()); + } + } + + private void add(int i, String word, int length) { + if (i < length) { + char c = word.charAt(i); + Trie subTrie = map.get(c); + if (subTrie == null) { + subTrie = new Trie(); + map.put(c, subTrie); + } + subTrie.add(i + 1, word, length); + } else map.put(null, new Trie()); //use null to indicate end of string + } + + /** + * Returns if the word is in the trie. + */ + private boolean search(String word) { + if (word != null) { + return search(0, word, word.length()); + } + return false; + } + + private boolean search(int i, String word, int length) { + if (i < length) { + char c = word.charAt(i); + if(c == '.'){ + for(Character child : map.keySet()){ + if(child != null){ + Trie subTrie = map.get(child); + if(subTrie.search(i + 1, word, length)) return true; + } + } + return false; + } else{ + Trie subTrie = map.get(c); + if (subTrie == null) + return false; + return subTrie.search(i + 1, word, length); + } + } + return map.containsKey(null); + } + } +} From 04a858729690b504d768372790866941f9d478f3 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 9 Dec 2017 20:32:11 +0100 Subject: [PATCH 107/235] Target Sum: Accepted --- README.md | 3 +- problems/src/backtracking/TargetSum.java | 60 ++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 problems/src/backtracking/TargetSum.java diff --git a/README.md b/README.md index b81985b6..385086c9 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Remove Invalid Parentheses](problems/src/backtracking/RemoveInvalidParentheses.java) (Medium) - [Regular Expression Matching](problems/src/backtracking/RegularExpressionMatching.java) (Hard) - [Expression Add Operators](problems/src/backtracking/ExpressionAddOperators.java) (Hard) +- [Expression Add Operators](problems/src/backtracking/ExpressionAddOperators.java) (Hard) #### [Binary Search](problems/src/binary_search) @@ -54,7 +55,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Median of Two Sorted Arrays](problems/src/binary_search/MedianOfTwoSortedArrays.java) (Hard) - [Pow(x, n)](problems/src/binary_search/PowXN.java) (Medium) - [Find Peak Element](problems/src/binary_search/FindPeakElement.java) (Medium) -- [First Bad Version](problems/src/binary_search/FirstBadVersion.java) (Easy) +- [Target Sum](problems/src/binary_search/TargetSum.java) (Medium) #### [Bit Manipulation](problems/src/bit_manipulation) diff --git a/problems/src/backtracking/TargetSum.java b/problems/src/backtracking/TargetSum.java new file mode 100644 index 00000000..3480a25f --- /dev/null +++ b/problems/src/backtracking/TargetSum.java @@ -0,0 +1,60 @@ +package backtracking; + +/** + * Created by gouthamvidyapradhan on 09/12/2017. + * You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symbols + and -. + * For each integer, you should choose one from + and - as its new symbol. + + Find out how many ways to assign symbols to make sum of integers equal to target S. + + Example 1: + Input: nums is [1, 1, 1, 1, 1], S is 3. + Output: 5 + Explanation: + + -1+1+1+1+1 = 3 + +1-1+1+1+1 = 3 + +1+1-1+1+1 = 3 + +1+1+1-1+1 = 3 + +1+1+1+1-1 = 3 + + There are 5 ways to assign symbols to make the sum of nums be target 3. + Note: + The length of the given array is positive and will not exceed 20. + The sum of elements in the given array will not exceed 1000. + Your output answer is guaranteed to be fitted in a 32-bit integer. + * + */ +public class TargetSum { + + private static int n; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1, 1, 1, 1, 1}; + n = 0; + new TargetSum().findTargetSumWays(A, 3); + System.out.println(n); + } + + public int findTargetSumWays(int[] nums, int S) { + backtrack(nums, S, 0, 0); + return n; + } + + private void backtrack(int[] nums, int target, int sum, int i){ + if(i == nums.length){ + if(sum == target){ + n++; + } + } else{ + backtrack(nums, target, sum + nums[i], i + 1); + backtrack(nums, target, sum - nums[i], i + 1); + } + } + +} + From e3b976b929c5a71fd2e2123b21d6cd978c185c30 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 9 Dec 2017 21:03:42 +0100 Subject: [PATCH 108/235] One Edit Distance: Accepted --- README.md | 1 + problems/src/string/OneEditDistance.java | 51 ++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 problems/src/string/OneEditDistance.java diff --git a/README.md b/README.md index 385086c9..a8c33db9 100644 --- a/README.md +++ b/README.md @@ -201,6 +201,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Permutation in String](problems/src/string/PermutationInString.java) (Medium) - [Add Binary](problems/src/string/AddBinary.java) (Easy) - [Valid Palindrome II](problems/src/string/ValidPalindromeII.java) (Easy) +- [One Edit Distance](problems/src/string/OneEditDistance.java) (Medium) #### [Tree](problems/src/tree) diff --git a/problems/src/string/OneEditDistance.java b/problems/src/string/OneEditDistance.java new file mode 100644 index 00000000..fc65eb7e --- /dev/null +++ b/problems/src/string/OneEditDistance.java @@ -0,0 +1,51 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 09/12/2017. + * + * Given two strings S and T, determine if they are both one edit distance apart. + */ +public class OneEditDistance { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new OneEditDistance().isOneEditDistance("abxd", "adxb")); + } + + public boolean isOneEditDistance(String s, String t) { + if(Math.abs(s.length() - t.length()) > 1 || s.equals(t)) return false; + if(s.length() > t.length()){ + return hasDiffOne(s, t, false); + } else if(t.length() > s.length()){ + return hasDiffOne(t, s, false); + } else{ + return hasDiffOne(s, t, true); + } + } + + private boolean hasDiffOne(String s, String t, boolean sameLength){ + int count = 0, i = 0, j = 0; + for(int l1 = s.length(), l2 = t.length(); i < l1 && j < l2;){ + if(s.charAt(i) == t.charAt(j)){ + i++; j++; + } else{ + if(count > 0) return false; + count++; + if(sameLength){ + i++; j++; + } else{ + i++; + } + } + } + if(i == j){ + return true; + } else{ + return (s.charAt(s.length() - 1) == t.charAt(t.length() - 1)); + } + } +} From 7b67a01753a61c5a3e67fddfccaa9cbe33a3218b Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 10 Dec 2017 02:14:08 +0100 Subject: [PATCH 109/235] Continuous Subarray Sum: Accepted --- README.md | 1 + .../ContinuousSubarraySum.java | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 problems/src/dynamic_programming/ContinuousSubarraySum.java diff --git a/README.md b/README.md index a8c33db9..535f6873 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,7 @@ My accepted leetcode solutions to some of the common interview problems. - [2 Keys Keyboard](problems/src/dynamic_programming/TwoKeysKeyboard.java) (Medium) - [Maximum Sum of 3 Non-Overlapping Subarrays](problems/src/dynamic_programming/MaxSum3SubArray.java) (Hard) - [Maximal Square](problems/src/dynamic_programming/MaximalSquare.java) (Medium) +- [Continuous Subarray Sum](problems/src/dynamic_programming/ContinuousSubarraySum.java) (Medium) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/ContinuousSubarraySum.java b/problems/src/dynamic_programming/ContinuousSubarraySum.java new file mode 100644 index 00000000..47d6250a --- /dev/null +++ b/problems/src/dynamic_programming/ContinuousSubarraySum.java @@ -0,0 +1,55 @@ +package dynamic_programming; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by gouthamvidyapradhan on 10/12/2017. + * Given a list of non-negative numbers and a target integer k, write a function to check if the array has a + * continuous subarray of size at least 2 that sums up to the multiple of k, that is, sums up to n*k where n is also + * an integer. + + Example 1: + Input: [23, 2, 4, 6, 7], k=6 + Output: True + Explanation: Because [2, 4] is a continuous subarray of size 2 and sums up to 6. + Example 2: + Input: [23, 2, 6, 4, 7], k=6 + Output: True + Explanation: Because [23, 2, 6, 4, 7] is an continuous subarray of size 5 and sums up to 42. + Note: + The length of the array won't exceed 10,000. + You may assume the sum of all the numbers is in the range of a signed 32-bit integer. + + Solution: O(n) sum the elements and maintain a hashmap of key value pair of (sum % k) -> index. If the key is + already found in the hashmap and the difference in the current_index and hashmap index is > 1 then return true. + */ +public class ContinuousSubarraySum { + + /** + * Main method + * @param args + */ + public static void main(String[] args) throws Exception{ + int[] A = {1, 3, 6, 12, 7}; + System.out.println(new ContinuousSubarraySum().checkSubarraySum(A, 6)); + } + + public boolean checkSubarraySum(int[] nums, int k) { + Map map = new HashMap<>(); + int sum = 0; + map.put(0, -1); + for(int i = 0; i < nums.length; i ++){ + sum += nums[i]; + int mod = (k == 0) ? sum : sum % k; //this is to handle case where k is 0 + if(map.containsKey(mod)){ + if(i - map.get(mod) > 1){ + return true; + } + } else{ + map.put(mod, i); + } + } + return false; + } +} From 2dfc70be2a2b2db05f8c9ae76e853a36beb941ca Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 10 Dec 2017 02:58:25 +0100 Subject: [PATCH 110/235] Random Pick Index: Accepted --- README.md | 3 + .../reservoir_sampling/RandomPickIndex.java | 62 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 problems/src/reservoir_sampling/RandomPickIndex.java diff --git a/README.md b/README.md index 535f6873..21ac93d8 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,9 @@ My accepted leetcode solutions to some of the common interview problems. - [Roman to Integer](problems/src/math/RomanToInteger.java) (Easy) - [Bulb Switcher II](problems/src/math/BulbSwitcherII.java) (Medium) +#### [Reservoir Sampling](problems/src/reservoir_sampling) +- [Random Pick Index](problems/src/reservoir_sampling/RandomPickIndex.java) (Medium) + #### [Stack](problems/src/stack) - [Min Stack](problems/src/stack/MinStack.java) (Easy) diff --git a/problems/src/reservoir_sampling/RandomPickIndex.java b/problems/src/reservoir_sampling/RandomPickIndex.java new file mode 100644 index 00000000..8671f82e --- /dev/null +++ b/problems/src/reservoir_sampling/RandomPickIndex.java @@ -0,0 +1,62 @@ +package reservoir_sampling; + +import java.util.Random; + +/** + * Created by gouthamvidyapradhan on 10/12/2017. + * Given an array of integers with possible duplicates, randomly output the index of a given target number. You can + * assume that the given target number must exist in the array. + + Note: + The array size can be very large. Solution that uses too much extra space will not pass the judge. + + Example: + + int[] nums = new int[] {1,2,3,3,3}; + Solution solution = new Solution(nums); + + // pick(3) should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning. + solution.pick(3); + + // pick(1) should return 0. Since in the array only nums[0] is equal to 1. + solution.pick(1); + + */ +public class RandomPickIndex { + + private int[] nums; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1,2,3,3,3}; + System.out.println(new RandomPickIndex(A).pick(1)); + } + + public RandomPickIndex(int[] nums) { + this.nums = nums; + } + + public int pick(int target) { + int count = 0; + for (int num : nums) { + if (num == target) { + count++; + } + } + Random random = new Random(); + int nPick = 1 + random.nextInt(count); + count = 0; + for(int i = 0; i < nums.length; i ++){ + if(nums[i] == target){ + if(++count == nPick){ + return i; + } + } + } + return 0; //this is impossible + } + +} From 704b7b11798ff62d1fc4caf7c9ff5f09f8ff9cc9 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 10 Dec 2017 04:00:44 +0100 Subject: [PATCH 111/235] Maximum Swap: Accepted --- README.md | 1 + problems/src/array/MaximumSwap.java | 55 +++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 problems/src/array/MaximumSwap.java diff --git a/README.md b/README.md index 21ac93d8..27ac8732 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Longest Continuous Increasing Subsequence](problems/src/array/LongestIncreasingSubsequence.java) (Easy) - [Sparse Matrix Multiplication](problems/src/array/SparseMatrixMultiplication.java) (Medium) - [Read N Characters Given Read4](problems/src/array/ReadNCharacters.java) (Easy) +- [Maximum Swap](problems/src/array/MaximumSwap.java) (Medium) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/MaximumSwap.java b/problems/src/array/MaximumSwap.java new file mode 100644 index 00000000..3351fd08 --- /dev/null +++ b/problems/src/array/MaximumSwap.java @@ -0,0 +1,55 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 10/12/2017. + * Given a non-negative integer, you could swap two digits at most once to get the maximum valued number. Return the + * maximum valued number you could get. + + Example 1: + Input: 2736 + Output: 7236 + Explanation: Swap the number 2 and the number 7. + Example 2: + Input: 9973 + Output: 9973 + Explanation: No swap. + Note: + The given number is in the range [0, 108] + + Solution O(n): Create a array of digit index. Iterate through the digits starting from left and in each iteration + check if there is any digit which is greater than the current digit and appearing after the current index, if found + then swap and return the new integer. + */ +public class MaximumSwap { + + public static void main(String[] args) throws Exception{ + System.out.println(new MaximumSwap().maximumSwap(2736)); + } + + public int maximumSwap(int num) { + int[] D = new int[10]; + char[] A = String.valueOf(num).toCharArray(); + for(int i = 0; i < A.length; i ++){ + D[A[i] - '0'] = i; + } + + boolean found = false; + + for(int i = 0; i < A.length; i ++){ + int digit = A[i] - '0'; + for(int j = 9; j > digit; j--){ + if(D[j] > i){ + char temp = A[i]; + A[i] = (char)(j + '0'); + A[D[j]] = temp; + found = true; + break; + } + } + if(found) break; + } + + return Integer.parseInt(String.valueOf(A)); + } + +} From 286a32920034cc134aba614902dd572203b77799 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 10 Dec 2017 04:04:16 +0100 Subject: [PATCH 112/235] Update to readme file --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 27ac8732..2b8c449c 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,6 @@ My accepted leetcode solutions to some of the common interview problems. - [Remove Invalid Parentheses](problems/src/backtracking/RemoveInvalidParentheses.java) (Medium) - [Regular Expression Matching](problems/src/backtracking/RegularExpressionMatching.java) (Hard) - [Expression Add Operators](problems/src/backtracking/ExpressionAddOperators.java) (Hard) -- [Expression Add Operators](problems/src/backtracking/ExpressionAddOperators.java) (Hard) #### [Binary Search](problems/src/binary_search) @@ -178,6 +177,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Bulb Switcher II](problems/src/math/BulbSwitcherII.java) (Medium) #### [Reservoir Sampling](problems/src/reservoir_sampling) + - [Random Pick Index](problems/src/reservoir_sampling/RandomPickIndex.java) (Medium) #### [Stack](problems/src/stack) From b8c54e5eb9744bbb277c46a4f3dd782039955f71 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Mon, 11 Dec 2017 01:40:32 +0100 Subject: [PATCH 113/235] Decode Ways II : Accepted --- README.md | 1 + .../src/dynamic_programming/DecodeWaysII.java | 109 ++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 problems/src/dynamic_programming/DecodeWaysII.java diff --git a/README.md b/README.md index 2b8c449c..fa4424a2 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Maximum Sum of 3 Non-Overlapping Subarrays](problems/src/dynamic_programming/MaxSum3SubArray.java) (Hard) - [Maximal Square](problems/src/dynamic_programming/MaximalSquare.java) (Medium) - [Continuous Subarray Sum](problems/src/dynamic_programming/ContinuousSubarraySum.java) (Medium) +- [Decode Ways II](problems/src/dynamic_programming/DecodeWaysII.java) (Medium) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/DecodeWaysII.java b/problems/src/dynamic_programming/DecodeWaysII.java new file mode 100644 index 00000000..5ae0cff2 --- /dev/null +++ b/problems/src/dynamic_programming/DecodeWaysII.java @@ -0,0 +1,109 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 11/12/2017. + * A message containing letters from A-Z is being encoded to numbers using the following mapping way: + + 'A' -> 1 + 'B' -> 2 + ... + 'Z' -> 26 + Beyond that, now the encoded string can also contain the character '*', which can be treated as one of the numbers + from 1 to 9. + + Given the encoded message containing digits and the character '*', return the total number of ways to decode it. + + Also, since the answer may be very large, you should return the output mod 109 + 7. + + Example 1: + Input: "*" + Output: 9 + Explanation: The encoded message can be decoded to the string: "A", "B", "C", "D", "E", "F", "G", "H", "I". + Example 2: + Input: "1*" + Output: 9 + 9 = 18 + Note: + The length of the input string will fit in range [1, 105]. + The input string will only contain the character '*' and digits '0' - '9'. + + Solution: O(n) consider each digit and a pair of digits and perform a cartesian product to calculate the total + number of ways. A pair of digits are to be considered only if their combined value does not exceed 26. + Corner cases with combination of * and 0s can be tricky + */ +public class DecodeWaysII { + + private final int CONST = 1000000007; + private int[] dp; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new DecodeWaysII().numDecodings("10")); + } + + public int numDecodings(String s) { + dp = new int[s.length() + 1]; + if(s.charAt(s.length() - 1) == '*'){ + dp[s.length() - 1] = 9; + } else if(s.charAt(s.length() - 1) == '0') { + dp[s.length() - 1] = 0; + } else dp[s.length() - 1] = 1; + dp[s.length()] = 1; + + for(int i = s.length() - 2; i >= 0; i --){ + char curr = s.charAt(i); + char next = s.charAt(i + 1); + switch (curr){ + case '0': + dp[i] = 0; + break; + //number begins with a '*' + case '*': + dp[i] = (int)((9 * (long)dp[i + 1]) % CONST); + switch (next){ + //The next char is a '*' + case '*': + dp[i] = (int)((dp[i] + ((15 * (long)dp[i + 2]) % CONST)) % CONST); //multiplication can be + //very large hence type casting to long is necessary + break; + + case '0': + dp[i] = (int)((dp[i] + ((2 * (long)dp[i + 2]) % CONST)) % CONST); + break; + + default: + if((next - '0') > 6){ + dp[i] = ((dp[i] + (dp[i + 2])) % CONST); + } else { + dp[i] = (int)((dp[i] + ((2 * (long)dp[i + 2]) % CONST)) % CONST); + } + break; + } + break; + + default: + dp[i] = dp[i + 1]; + switch (next){ + case '*': + if((curr - '0') == 1){ + dp[i] = (int)((dp[i] + ((9 * (long)dp[i + 2]) % CONST)) % CONST); + } else if((curr - '0') == 2){ + dp[i] = (int)((dp[i] + ((6 * (long)dp[i + 2]) % CONST)) % CONST); + } + break; + + default: + if((curr - '0') == 1){ + dp[i] = ((dp[i] + dp[i + 2]) % CONST); + } else if((curr - '0') == 2 && (next - '0' <= 6)){ + dp[i] = ((dp[i] + dp[i + 2]) % CONST); + } + break; + } + } + } + return dp[0]; + } +} From 6c1b48576121608c3b3b0e411faad6d3c1c23c6b Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Mon, 11 Dec 2017 02:01:08 +0100 Subject: [PATCH 114/235] Updated to readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fa4424a2..5d3de4d6 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Maximum Sum of 3 Non-Overlapping Subarrays](problems/src/dynamic_programming/MaxSum3SubArray.java) (Hard) - [Maximal Square](problems/src/dynamic_programming/MaximalSquare.java) (Medium) - [Continuous Subarray Sum](problems/src/dynamic_programming/ContinuousSubarraySum.java) (Medium) -- [Decode Ways II](problems/src/dynamic_programming/DecodeWaysII.java) (Medium) +- [Decode Ways II](problems/src/dynamic_programming/DecodeWaysII.java) (Hard) #### [Greedy](problems/src/greedy) From 5771e937e98187630e67b4e1ca388246a6fc5f87 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Mon, 11 Dec 2017 23:18:12 +0100 Subject: [PATCH 115/235] Graph Valid Tree : Accepted --- README.md | 1 + .../depth_first_search/GraphValidTree.java | 83 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 problems/src/depth_first_search/GraphValidTree.java diff --git a/README.md b/README.md index 5d3de4d6..9a4c5da3 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Course Schedule](problems/src/depth_first_search/CourseSchedule.java) (Medium) - [Course Schedule II](problems/src/depth_first_search/CourseScheduleII.java) (Medium) - [Alien Dictionary](problems/src/depth_first_search/AlienDictionary.java) (Hard) +- [Graph Valid Tree](problems/src/depth_first_search/GraphValidTree.java) (Medium) #### [Design](problems/src/design) diff --git a/problems/src/depth_first_search/GraphValidTree.java b/problems/src/depth_first_search/GraphValidTree.java new file mode 100644 index 00000000..2562319b --- /dev/null +++ b/problems/src/depth_first_search/GraphValidTree.java @@ -0,0 +1,83 @@ +package depth_first_search; + +import java.util.ArrayList; +import java.util.BitSet; +import java.util.List; + +/** + * Created by gouthamvidyapradhan on 11/12/2017. + * Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a + * function to check whether these edges make up a valid tree. + + For example: + + Given n = 5 and edges = [[0, 1], [0, 2], [0, 3], [1, 4]], return true. + + Given n = 5 and edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]], return false. + + Note: you can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the + same as [1, 0] and thus will not appear together in edges. + + Solution O(E + V). A graph is a tree if there are no cycles and number of connected components is 1. + */ +public class GraphValidTree { + + private List[] graph; + private BitSet done; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[][] graph = {{1, 0}}; + System.out.println(new GraphValidTree().validTree(2, graph)); + } + + + public boolean validTree(int n, int[][] edges) { + graph = new List[n]; + done = new BitSet(); + for(int i = 0; i < n; i ++){ + graph[i] = new ArrayList<>(); + } + for(int i = 0; i < edges.length; i ++){ + int u = edges[i][0]; + int v = edges[i][1]; + graph[u].add(v); + graph[v].add(u); + } + + int count = 0; + for(int i = 0; i < n; i++){ + if(!done.get(i)){ + if(!dfs(graph, 0, -1)){ + return false; + } + count ++; //count number of connected components + } + } + return count <= 1; + } + + private boolean dfs(List[] graph, int u, int p){ + done.set(u); + List children = graph[u]; + if(children != null){ + for(int c : children){ + if(p != c){ //should not be equal to parent + if(!done.get(c)){ + if(!dfs(graph, c, u)){ + return false; + } + } else{ + return false; + } + } + } + } + return true; + } + + +} From 7a6c087195a65b4c23448db082f90563697f74dc Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 12 Dec 2017 01:56:53 +0100 Subject: [PATCH 116/235] H-Index II : Accepted --- README.md | 2 + problems/src/array/HIndex.java | 56 ++++++++++++++++++++++++ problems/src/binary_search/HIndexII.java | 42 ++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 problems/src/array/HIndex.java create mode 100644 problems/src/binary_search/HIndexII.java diff --git a/README.md b/README.md index 9a4c5da3..ead4d52e 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Sparse Matrix Multiplication](problems/src/array/SparseMatrixMultiplication.java) (Medium) - [Read N Characters Given Read4](problems/src/array/ReadNCharacters.java) (Easy) - [Maximum Swap](problems/src/array/MaximumSwap.java) (Medium) +- [H-Index](problems/src/array/HIndex.java) (Medium) #### [Backtracking](problems/src/backtracking) @@ -56,6 +57,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Pow(x, n)](problems/src/binary_search/PowXN.java) (Medium) - [Find Peak Element](problems/src/binary_search/FindPeakElement.java) (Medium) - [Target Sum](problems/src/binary_search/TargetSum.java) (Medium) +- [H-Index II](problems/src/binary_search/HIndexII.java) (Medium) #### [Bit Manipulation](problems/src/bit_manipulation) diff --git a/problems/src/array/HIndex.java b/problems/src/array/HIndex.java new file mode 100644 index 00000000..a3577600 --- /dev/null +++ b/problems/src/array/HIndex.java @@ -0,0 +1,56 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 12/12/2017. + * Given an array of citations (each citation is a non-negative integer) of a researcher, write a function to + * compute the researcher's h-index. + + According to the definition of h-index on Wikipedia: "A scientist has index h if h of his/her N papers have at + least h citations each, and the other N − h papers have no more than h citations each." + + For example, given citations = [3, 0, 6, 1, 5], which means the researcher has 5 papers in total and each of them + had received 3, 0, 6, 1, 5 citations respectively. Since the researcher has 3 papers with at least 3 citations each + and the remaining two with no more than 3 citations each, his h-index is 3. + + Note: If there are several possible values for h, the maximum one is taken as the h-index. + + Solution O(n) Replace all the citations which are greater than n with n, the result will not change with this + operation. + Maintain a count array with count of each citations. Sum up all the counts from n -> 0 and store this in a array S. + Value in array index Si is number of papers having citations at least i. + + The first value at index i, from right to left in array S which has i <= Si is the answer. + + + */ +public class HIndex { + + public static void main(String[] args) throws Exception{ + int[] A = {3, 0, 6, 1, 5}; + System.out.println(new HIndex().hIndex(A)); + } + + public int hIndex(int[] citations) { + int n = citations.length; + int[] count = new int[n + 1]; + int[] S = new int[n + 1]; + for(int i = 0; i < citations.length; i ++){ + if(citations[i] > n){ + citations[i] = n; + } + } + for (int citation : citations) { + count[citation]++; + } + S[n] = count[n]; + for(int i = n - 1; i >= 0; i --){ + S[i] = count[i] + S[i + 1]; + } + for(int i = n; i >= 0; i--){ + if(i <= S[i]){ + return i; + } + } + return 0; + } +} diff --git a/problems/src/binary_search/HIndexII.java b/problems/src/binary_search/HIndexII.java new file mode 100644 index 00000000..f07928d1 --- /dev/null +++ b/problems/src/binary_search/HIndexII.java @@ -0,0 +1,42 @@ +package binary_search; + +/** + * Created by gouthamvidyapradhan on 11/12/2017. + * + * Follow up for H-Index: What if the citations array is sorted in ascending order? Could you optimize your algorithm? + * @see array.HIndex + */ +public class HIndexII { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1, 1, 1, 1, 1, 15, 20}; + System.out.println(new HIndexII().hIndex(A)); + } + + public int hIndex(int[] citations) { + if(citations.length == 0) return 0; + int s = 0, e = citations.length; + int ans = -1; + while(s < e){ + int m = (s + e) >>> 1; + int cit = citations.length - m; + if(citations[m] > cit){ + if(ans < cit){ + ans = cit; + } + e = m; + } else{ + if(ans < citations[m]){ + ans = citations[m]; + } + s = m + 1; + } + } + return ans; + } + +} From 7383892737267995f417fce54283ae36ccfb8eff Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 13 Dec 2017 01:30:16 +0100 Subject: [PATCH 117/235] Palindromic Substrings : Accepted --- README.md | 1 + .../PalindromicSubstrings.java | 60 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 problems/src/dynamic_programming/PalindromicSubstrings.java diff --git a/README.md b/README.md index ead4d52e..cf96cafe 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Maximal Square](problems/src/dynamic_programming/MaximalSquare.java) (Medium) - [Continuous Subarray Sum](problems/src/dynamic_programming/ContinuousSubarraySum.java) (Medium) - [Decode Ways II](problems/src/dynamic_programming/DecodeWaysII.java) (Hard) +- [Palindromic Substrings](problems/src/dynamic_programming/PalindromicSubstrings.java) (Medium) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/PalindromicSubstrings.java b/problems/src/dynamic_programming/PalindromicSubstrings.java new file mode 100644 index 00000000..9379de52 --- /dev/null +++ b/problems/src/dynamic_programming/PalindromicSubstrings.java @@ -0,0 +1,60 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 13/12/2017. + * + * Given a string, your task is to count how many palindromic substrings in this string. + + The substrings with different start indexes or end indexes are counted as different substrings even they consist of + same characters. + + Example 1: + Input: "abc" + Output: 3 + Explanation: Three palindromic strings: "a", "b", "c". + Example 2: + Input: "aaa" + Output: 6 + Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa". + Note: + The input string length won't exceed 1000. + + Solution O(n ^ 2): Example abcba: Compare char at two indices each time for example if char at + index 0 and index 4 are equal and if substring 1 and 3 is a palindrome then, sub-string 0 and 4 is also a palindrome + + */ +public class PalindromicSubstrings { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + System.out.println(new PalindromicSubstrings().countSubstrings("aaa")); + } + + public int countSubstrings(String s) { + boolean[][] T = new boolean[s.length()][s.length()]; + int count = s.length(); + for(int i = 0, j = 0; i < T.length; i ++, j ++){ + T[i][j] = true; + } + + for(int k = 1, col = s.length(); k < col; k++){ + for(int i = 0, j = k; i < col && j < col; i++, j++){ + if(k == 1){ + if(s.charAt(i) == s.charAt(j)){ + T[i][j] = true; + count++; + } + } else{ + if(s.charAt(i) == s.charAt(j) && T[i + 1][j - 1]){ + T[i][j] = true; + count++; + } + } + } + } + return count; + } +} From 3d152ccf26256bf85faa62b2b04410e05813f184 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 13 Dec 2017 01:46:13 +0100 Subject: [PATCH 118/235] Sum of Left Leaves : Accepted --- README.md | 1 + problems/src/tree/SumofLeftLeaves.java | 51 ++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 problems/src/tree/SumofLeftLeaves.java diff --git a/README.md b/README.md index cf96cafe..4e7ffd09 100644 --- a/README.md +++ b/README.md @@ -242,6 +242,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Find Bottom Left Tree Value](problems/src/tree/FindBottomLeftTreeValue.java) (Medium) - [Diameter of Binary Tree](problems/src/tree/DiameterOfBinaryTree.java) (Easy) - [Binary Tree Paths](problems/src/tree/BinaryTreePaths.java) (Easy) +- [Sum of Left Leaves](problems/src/tree/SumofLeftLeaves.java) (Easy) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/SumofLeftLeaves.java b/problems/src/tree/SumofLeftLeaves.java new file mode 100644 index 00000000..a5814f1e --- /dev/null +++ b/problems/src/tree/SumofLeftLeaves.java @@ -0,0 +1,51 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 13/12/2017. + * Find the sum of all left leaves in a given binary tree. + + Example: + + 3 + / \ + 9 20 + / \ + 15 7 + + There are two left leaves in the binary tree, with values 9 and 15 respectively. Return 24. + + */ +public class SumofLeftLeaves { + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + + } + + public int sumOfLeftLeaves(TreeNode root) { + return inorder(root, false); + } + + private int inorder(TreeNode node, boolean isLeft){ + if(node != null){ + if(node.left == null && node.right == null){ + if(isLeft){ + return node.val; + } else return 0; + } + return inorder(node.left, true) + inorder(node.right, false); + } return 0; + } + +} From 57f64e92792f90b24cfd711bd0bd4275b6f0308c Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 14 Dec 2017 21:48:18 +0100 Subject: [PATCH 119/235] Number of Longest Increasing Subsequence : Accepted --- README.md | 1 + .../src/dynamic_programming/NumberOfLIS.java | 73 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 problems/src/dynamic_programming/NumberOfLIS.java diff --git a/README.md b/README.md index 4e7ffd09..2e0a7fe1 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Continuous Subarray Sum](problems/src/dynamic_programming/ContinuousSubarraySum.java) (Medium) - [Decode Ways II](problems/src/dynamic_programming/DecodeWaysII.java) (Hard) - [Palindromic Substrings](problems/src/dynamic_programming/PalindromicSubstrings.java) (Medium) +- [Number of Longest Increasing Subsequence](problems/src/dynamic_programming/NumberOfLIS.java) (Medium) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/NumberOfLIS.java b/problems/src/dynamic_programming/NumberOfLIS.java new file mode 100644 index 00000000..3738f63a --- /dev/null +++ b/problems/src/dynamic_programming/NumberOfLIS.java @@ -0,0 +1,73 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 13/12/2017. + * Given an unsorted array of integers, find the number of longest increasing subsequence. + + Example 1: + Input: [1,3,5,4,7] + Output: 2 + Explanation: The two longest increasing subsequence are [1, 3, 4, 7] and [1, 3, 5, 7]. + Example 2: + Input: [2,2,2,2,2] + Output: 5 + Explanation: The length of longest continuous increasing subsequence is 1, and there are 5 subsequences' length is + 1, so output 5. + Note: Length of the given array will be not exceed 2000 and the answer is guaranteed to be fit in 32-bit signed int. + + Solution O(n ^ 2) compute the LIS and save the results in length also save the max length of LIS in maxVal. Calculate + the count as below + + For every pair of (i, j) + count[i] = count[i] + count[j] where length[i] == length[j] + 1 and nums[j] < nums[i] + + sum-up the count for every length where length[i] == maxVal + */ +public class NumberOfLIS { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1, 12, 11, 1, 1, 1, 12}; + System.out.println(new NumberOfLIS().findNumberOfLIS(A)); + } + + public int findNumberOfLIS(int[] nums) { + if(nums.length == 0) return 0; + int[] length = new int[nums.length]; + length[0] = 1; + int maxVal = 1; + for(int i = 1; i < nums.length; i ++){ + int max = 1; + for(int j = 0; j < i; j++){ + if(nums[i] > nums[j]){ + max = Math.max(max, length[j] + 1); + maxVal = Math.max(maxVal, max); + } + } + length[i] = max; + } + int[] count = new int[nums.length]; + count[0] = 1; + for(int i = 1; i < length.length; i ++){ + for(int j = 0; j < i; j++){ + if((length[j] + 1 == length[i]) && (nums[j] < nums[i])){ + count[i] += count[j]; + } + } + if(count[i] == 0){ + count[i] = 1; //default is just 1 + } + } + int ans = 0; + for(int i = 0; i < length.length; i ++){ + if(length[i] == maxVal){ + ans += count[i]; + } + } + return ans; + } +} From f90d4891e413cd60ec2108f831824c551d07b748 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 14 Dec 2017 22:23:51 +0100 Subject: [PATCH 120/235] Best Time to Buy and Sell Stock with Transaction Fee : Accepted --- README.md | 1 + .../BestTimeToBuyAndSellStocksWithFee.java | 53 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java diff --git a/README.md b/README.md index 2e0a7fe1..9d912908 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Decode Ways II](problems/src/dynamic_programming/DecodeWaysII.java) (Hard) - [Palindromic Substrings](problems/src/dynamic_programming/PalindromicSubstrings.java) (Medium) - [Number of Longest Increasing Subsequence](problems/src/dynamic_programming/NumberOfLIS.java) (Medium) +- [Best Time to Buy and Sell Stock with Transaction Fee](problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java) (Medium) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java b/problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java new file mode 100644 index 00000000..b9ad0e70 --- /dev/null +++ b/problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java @@ -0,0 +1,53 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 14/12/2017. + * Your are given an array of integers prices, for which the i-th element is the price of a given stock on day i; + * and a non-negative integer fee representing a transaction fee. + + You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction. + You may not buy more than 1 share of a stock at a time (ie. you must sell the stock share before you buy again.) + + Return the maximum profit you can make. + + Example 1: + Input: prices = [1, 3, 2, 8, 4, 9], fee = 2 + Output: 8 + Explanation: The maximum profit can be achieved by: + Buying at prices[0] = 1 + Selling at prices[3] = 8 + Buying at prices[4] = 4 + Selling at prices[5] = 9 + The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8. + Note: + + 0 < prices.length <= 50000. + 0 < prices[i] < 50000. + 0 <= fee < 50000. + + Solution: O(n) for every step either you can buy stock or sell. Maintain two variables 'cash' to save max value if + you had sold the stock at current price and 'stock' to save max value if you had purchased the stock at current + price. Return max cash + + */ +public class BestTimeToBuyAndSellStocksWithFee { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1, 3, 2, 8, 4, 9}; + System.out.println(new BestTimeToBuyAndSellStocksWithFee().maxProfit(A, 2)); + } + + public int maxProfit(int[] prices, int fee) { + int cash = 0, stock = -prices[0]; + for(int i = 1; i < prices.length; i ++){ + cash = Math.max(cash, prices[i] + stock - fee); + stock = Math.max(stock, cash - prices[i]); + } + return cash; + } +} From 11f6c5b92f0061c3d092d0a696d8c262cf9cef56 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 15 Dec 2017 01:32:06 +0100 Subject: [PATCH 121/235] Insert Interval: Accepted --- README.md | 1 + problems/src/array/InsertInterval.java | 87 ++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 problems/src/array/InsertInterval.java diff --git a/README.md b/README.md index 9d912908..694b31dc 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Read N Characters Given Read4](problems/src/array/ReadNCharacters.java) (Easy) - [Maximum Swap](problems/src/array/MaximumSwap.java) (Medium) - [H-Index](problems/src/array/HIndex.java) (Medium) +- [Insert Interval](problems/src/array/InsertInterval.java) (Hard) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/InsertInterval.java b/problems/src/array/InsertInterval.java new file mode 100644 index 00000000..cd37f6f8 --- /dev/null +++ b/problems/src/array/InsertInterval.java @@ -0,0 +1,87 @@ +package array; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by gouthamvidyapradhan on 15/12/2017. + * 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. + + Example 1: + Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9]. + + Example 2: + Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16]. + + This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10]. + + Solution: O(n): Iterate through each interval and check for each overlapping case + */ +public class InsertInterval { + + public static class Interval { + int start; + int end; + Interval() { start = 0; end = 0; } + Interval(int s, int e) { start = s; end = e; } + } + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + Interval i1 = new Interval(1, 2); + Interval i2 = new Interval(3, 5); + Interval i3 = new Interval(6, 7); + Interval i4 = new Interval(8, 10); + Interval i5 = new Interval(12, 16); + List list = Arrays.asList(i1, i2, i3, i4, i5); + List result = new InsertInterval().insert(list, new Interval(2, 5)); + result.stream().map(x -> x.start + " " + x.end).forEach(System.out::println); + } + + public List insert(List intervals, Interval newInterval) { + List result = new ArrayList<>(); + for(int i = 0, l = intervals.size(); i < l; i ++){ + Interval curr = intervals.get(i); + if(newInterval.start >= curr.start && newInterval.end <= curr.end){ + insertRest(intervals, result, i); + return result; //easy case + } else if(newInterval.start < curr.start && newInterval.end > curr.end){ + newInterval = new Interval(newInterval.start, newInterval.end); + //merge and continue + } else if(newInterval.start >= curr.start && newInterval.start <= curr.end + && newInterval.end > curr.end){ + newInterval = new Interval(curr.start, newInterval.end); + //merge and continue + } else if(newInterval.start < curr.start && newInterval.end >= curr.start + && newInterval.end <= curr.end){ + Interval newI = new Interval(newInterval.start, curr.end); + result.add(newI); + insertRest(intervals, result, i + 1); + return result; + } else if(newInterval.start > curr.end){ + result.add(curr); + } else { + result.add(newInterval); + insertRest(intervals, result, i); + return result; + } + } + result.add(newInterval); + return result; + } + + private void insertRest(List intervals, List result, int i){ + int l = intervals.size(); + while(i < l){ + result.add(intervals.get(i)); + i++; + } + } + +} From 67d8929a2f1e4182d3dce6ac24ca653bc263ded8 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 15 Dec 2017 03:27:06 +0100 Subject: [PATCH 122/235] Longest Consecutive Sequence: Accepted --- README.md | 1 + .../LongestConsecutiveSequence.java | 74 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 problems/src/depth_first_search/LongestConsecutiveSequence.java diff --git a/README.md b/README.md index 694b31dc..940e2f8b 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Course Schedule II](problems/src/depth_first_search/CourseScheduleII.java) (Medium) - [Alien Dictionary](problems/src/depth_first_search/AlienDictionary.java) (Hard) - [Graph Valid Tree](problems/src/depth_first_search/GraphValidTree.java) (Medium) +- [Longest Consecutive Sequence](problems/src/depth_first_search/LongestConsecutiveSequence.java) (Medium) #### [Design](problems/src/design) diff --git a/problems/src/depth_first_search/LongestConsecutiveSequence.java b/problems/src/depth_first_search/LongestConsecutiveSequence.java new file mode 100644 index 00000000..af0665b8 --- /dev/null +++ b/problems/src/depth_first_search/LongestConsecutiveSequence.java @@ -0,0 +1,74 @@ +package depth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 15/12/2017. + * Given an unsorted array of integers, find the length of the longest consecutive elements sequence. + + For example, + Given [100, 4, 200, 1, 3, 2], + The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4. + + Your algorithm should run in O(n) complexity. + + Solution: O(n) time and space complexity - Build a graph linking each number which is greater or lesser by one. + Perform a dfs to count the depth of a graph. + + Dfs using recursion fails due to StackOverFlowError(due to deep recursion) hence used a iterative approach with a + stack + */ +public class LongestConsecutiveSequence { + + private Map> graph; + private Set done; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] nums = {-1, 0, -3, -2, 1, 2, 3, 4, 5, 4}; + System.out.println(new LongestConsecutiveSequence().longestConsecutive(nums)); + } + + public int longestConsecutive(int[] nums) { + done = new HashSet<>(); + graph = new HashMap<>(); + for (int u : nums) { + graph.putIfAbsent(u, new HashSet<>()); + if (graph.keySet().contains(u - 1)) { + graph.get(u - 1).add(u); + graph.get(u).add(u - 1); + } + if (graph.keySet().contains(u + 1)) { + graph.get(u + 1).add(u); + graph.get(u).add(u + 1); + } + } + int max = 0; + for(int i : graph.keySet()){ + if(!done.contains(i)){ + Stack stack = new Stack<>(); + stack.add(i); + max = Math.max(max, dfs(0, stack)); + } + } + return max; + } + + + private int dfs(int count, Stack stack){ + while(!stack.isEmpty()){ + int top = stack.pop(); + count++; + done.add(top); + + Set children = graph.get(top); + if(children != null){ + children.stream().filter(c -> !done.contains(c)).forEach(stack::push); + } + } + return count; + } +} From 9e6ab3b34a160f2f8e3f365c9f9fb5b699952094 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 15 Dec 2017 03:29:08 +0100 Subject: [PATCH 123/235] Update to readme file --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 940e2f8b..1cef2adc 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Course Schedule II](problems/src/depth_first_search/CourseScheduleII.java) (Medium) - [Alien Dictionary](problems/src/depth_first_search/AlienDictionary.java) (Hard) - [Graph Valid Tree](problems/src/depth_first_search/GraphValidTree.java) (Medium) -- [Longest Consecutive Sequence](problems/src/depth_first_search/LongestConsecutiveSequence.java) (Medium) +- [Longest Consecutive Sequence](problems/src/depth_first_search/LongestConsecutiveSequence.java) (Hard) #### [Design](problems/src/design) From 0de7489daffeec0dae0a28bb2d4f546cf361e8ac Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 16 Dec 2017 11:35:57 +0100 Subject: [PATCH 124/235] Two Sum IV - Input is a BST : Accepted --- README.md | 1 + problems/src/tree/TwoSumIV.java | 70 +++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 problems/src/tree/TwoSumIV.java diff --git a/README.md b/README.md index 1cef2adc..1f0aadfb 100644 --- a/README.md +++ b/README.md @@ -247,6 +247,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Diameter of Binary Tree](problems/src/tree/DiameterOfBinaryTree.java) (Easy) - [Binary Tree Paths](problems/src/tree/BinaryTreePaths.java) (Easy) - [Sum of Left Leaves](problems/src/tree/SumofLeftLeaves.java) (Easy) +- [Two Sum IV - Input is a BST](problems/src/tree/TwoSumIV.java) (Easy) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/TwoSumIV.java b/problems/src/tree/TwoSumIV.java new file mode 100644 index 00000000..2c32b15f --- /dev/null +++ b/problems/src/tree/TwoSumIV.java @@ -0,0 +1,70 @@ +package tree; + +import java.util.HashSet; + +/** + * Created by gouthamvidyapradhan on 16/12/2017. + * Given a Binary Search Tree and a target number, return true if there exist two elements in the BST such that + * their sum is equal to the given target. + + Example 1: + Input: + 5 + / \ + 3 6 + / \ \ + 2 4 7 + + Target = 9 + + Output: True + Example 2: + Input: + 5 + / \ + 3 6 + / \ \ + 2 4 7 + + Target = 28 + + Output: False + */ +public class TwoSumIV { + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + } + + public boolean findTarget(TreeNode root, int k) { + return inorder(root, new HashSet<>(), k); + } + + private boolean inorder(TreeNode node, HashSet set, int k){ + if(node != null){ + int req = k - (node.val); + if(set.contains(req)){ + return true; + } + set.add(node.val); + if(inorder(node.left, set, k)){ + return true; + } else{ + if(inorder(node.right, set, k)){ + return true; + } + } + } return false; + } +} From 29bea8375e2aaa33aa4d65f7905fce3377030710 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 16 Dec 2017 12:11:46 +0100 Subject: [PATCH 125/235] Average of Levels in Binary Tree : Accepted --- README.md | 1 + .../src/tree/AverageOfLevelsInBinaryTree.java | 82 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 problems/src/tree/AverageOfLevelsInBinaryTree.java diff --git a/README.md b/README.md index 1f0aadfb..e85a7fd5 100644 --- a/README.md +++ b/README.md @@ -248,6 +248,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Binary Tree Paths](problems/src/tree/BinaryTreePaths.java) (Easy) - [Sum of Left Leaves](problems/src/tree/SumofLeftLeaves.java) (Easy) - [Two Sum IV - Input is a BST](problems/src/tree/TwoSumIV.java) (Easy) +- [Average of Levels in Binary Tree](problems/src/tree/AverageOfLevelsInBinaryTree.java) (Easy) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/AverageOfLevelsInBinaryTree.java b/problems/src/tree/AverageOfLevelsInBinaryTree.java new file mode 100644 index 00000000..74c917b4 --- /dev/null +++ b/problems/src/tree/AverageOfLevelsInBinaryTree.java @@ -0,0 +1,82 @@ +package tree; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; + +/** + * Created by gouthamvidyapradhan on 16/12/2017. + * Given a non-empty binary tree, return the average value of the nodes on each level in the form of an array. + Example 1: + Input: + 3 + / \ + 9 20 + / \ + 15 7 + Output: [3, 14.5, 11] + Explanation: + The average value of nodes on level 0 is 3, on level 1 is 14.5, and on level 2 is 11. Hence return [3, 14.5, 11]. + Note: + The range of node's value is in the range of 32-bit signed integer. + + Solution O(n) : Perform a BFS and calculate average for each level. + */ +public class AverageOfLevelsInBinaryTree { + + class LevelNode { + int level; + TreeNode node; + LevelNode(int level, TreeNode node){ + this.level = level; + this.node = node; + } + } + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + + } + + public List averageOfLevels(TreeNode root) { + Queue queue = new ArrayDeque<>(); + LevelNode node = new LevelNode(0, root); + queue.offer(node); + int curLevel = 0, count = 0; + long sum = 0L; + List result = new ArrayList<>(); + while(!queue.isEmpty()){ + LevelNode first = queue.poll(); + if(first.level == curLevel){ + sum += first.node.val; + count++; + } else{ + result.add((double)sum/count); + sum = first.node.val; + count = 1; + curLevel++; + } + if(first.node.left != null){ + queue.offer(new LevelNode(curLevel + 1, first.node.left)); + } if(first.node.right != null){ + queue.offer(new LevelNode(curLevel + 1, first.node.right)); + } + } + result.add((double)sum/count); + return result; + } + + +} From 77156c4ae7332c7056509da9667ef73e9f5ae323 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 16 Dec 2017 14:32:34 +0100 Subject: [PATCH 126/235] Contiguous Array : Accepted --- README.md | 1 + problems/src/hashing/ContiguousArray.java | 56 +++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 problems/src/hashing/ContiguousArray.java diff --git a/README.md b/README.md index e85a7fd5..2bea31db 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Two Sum](problems/src/hashing/TwoSum.java) (Easy) - [Valid Anagram](problems/src/hashing/ValidAnagram.java) (Easy) - [Maximum Size Subarray Sum Equals k](problems/src/hashing/MaximumSizeSubarraySumEqualsk.java) (Medium) +- [Contiguous Array](problems/src/hashing/ContiguousArray.java) (Medium) #### [Heap](problems/src/heap) diff --git a/problems/src/hashing/ContiguousArray.java b/problems/src/hashing/ContiguousArray.java new file mode 100644 index 00000000..a46776af --- /dev/null +++ b/problems/src/hashing/ContiguousArray.java @@ -0,0 +1,56 @@ +package hashing; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by gouthamvidyapradhan on 16/12/2017. + * Given a binary array, find the maximum length of a contiguous subarray with equal number of 0 and 1. + + Example 1: + Input: [0,1] + Output: 2 + Explanation: [0, 1] is the longest contiguous subarray with equal number of 0 and 1. + Example 2: + Input: [0,1,0] + Output: 2 + Explanation: [0, 1] (or [1, 0]) is a longest contiguous subarray with equal number of 0 and 1. + Note: The length of the given binary array will not exceed 50,000. + + Solution: O(n) keep a count variable and increment count when a 1 is found and decrement count when a 0 is found. + Maintain a map of count and its corresponding index. if the count repeats itself then take the difference of the + current index and the index saved in the map. Max of the difference is the answer. + */ +public class ContiguousArray { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1, 1}; + System.out.println(new ContiguousArray().findMaxLength(A)); + } + + public int findMaxLength(int[] nums) { + Map map = new HashMap<>(); + int count = 0; + int max = 0; + for(int i = 0; i < nums.length; i ++){ + if(nums[i] == 0){ + count--; + } else count++; + if(count == 0){ + max = Math.max(max, i + 1); + } else { + if(map.containsKey(count)){ + int index = map.get(count); + max = Math.max(max, i - index); + } else{ + map.put(count, i); + } + } + } + return max; + } +} From 993ac52ecd82655e697da228a94045115c2f81a1 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 16 Dec 2017 14:40:43 +0100 Subject: [PATCH 127/235] Hamming Distance : Accepted --- README.md | 1 + .../src/bit_manipulation/HammingDistance.java | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 problems/src/bit_manipulation/HammingDistance.java diff --git a/README.md b/README.md index 2bea31db..9826ec4a 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ My accepted leetcode solutions to some of the common interview problems. #### [Bit Manipulation](problems/src/bit_manipulation) - [Gray Code](problems/src/bit_manipulation/GrayCode.java) (Medium) +- [Hamming Distance](problems/src/bit_manipulation/HammingDistance.java) (Easy) - [Total Hamming Distance](problems/src/bit_manipulation/TotalHammingDistance.java) (Medium) #### [Breadth First Search](problems/src/breadth_first_search) diff --git a/problems/src/bit_manipulation/HammingDistance.java b/problems/src/bit_manipulation/HammingDistance.java new file mode 100644 index 00000000..4f1a6dbf --- /dev/null +++ b/problems/src/bit_manipulation/HammingDistance.java @@ -0,0 +1,49 @@ +package bit_manipulation; + +/** + * Created by gouthamvidyapradhan on 16/12/2017. + * The Hamming distance between two integers is the number of positions at which the corresponding bits are different. + + Given two integers x and y, calculate the Hamming distance. + + Note: + 0 ≤ x, y < 231. + + Example: + + Input: x = 1, y = 4 + + Output: 2 + + Explanation: + 1 (0 0 0 1) + 4 (0 1 0 0) + ↑ ↑ + + The above arrows point to positions where the corresponding bits are different. + + Solution O(1): XOR (x, y) and count the number of bits set + + */ +public class HammingDistance { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + + } + + public int hammingDistance(int x, int y) { + int z = (x ^ y); + int count = 0; + for(int i = 0; i < 31; i++){ + if((z & (1 << i)) > 0){ + count++; + } + } + return count; + } +} From 3de29fb53a37122772d131e15ad245ce5b02b70b Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 17 Dec 2017 01:28:35 +0100 Subject: [PATCH 128/235] Increasing Triplet Subsequence : Accepted --- README.md | 1 + .../array/IncreasingTripletSubsequence.java | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 problems/src/array/IncreasingTripletSubsequence.java diff --git a/README.md b/README.md index 9826ec4a..dc66ed92 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Maximum Swap](problems/src/array/MaximumSwap.java) (Medium) - [H-Index](problems/src/array/HIndex.java) (Medium) - [Insert Interval](problems/src/array/InsertInterval.java) (Hard) +- [Increasing Triplet Subsequence](problems/src/array/IncreasingTripletSubsequence.java) (Medium) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/IncreasingTripletSubsequence.java b/problems/src/array/IncreasingTripletSubsequence.java new file mode 100644 index 00000000..27970ca2 --- /dev/null +++ b/problems/src/array/IncreasingTripletSubsequence.java @@ -0,0 +1,48 @@ +package array; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 17/12/2017. + * Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the array. + + Formally the function should: + Return true if there exists i, j, k + such that arr[i] < arr[j] < arr[k] given 0 ≤ i < j < k ≤ n-1 else return false. + Your algorithm should run in O(n) time complexity and O(1) space complexity. + + Examples: + Given [1, 2, 3, 4, 5], + return true. + + Given [5, 4, 3, 2, 1], + return false. + */ +public class IncreasingTripletSubsequence { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1, 2, 3, 4, 5}; + System.out.println(new IncreasingTripletSubsequence().increasingTriplet(A)); + } + + public boolean increasingTriplet(int[] nums) { + int[] A = new int[3]; + Arrays.fill(A, Integer.MAX_VALUE); + for (int num : nums) { + if (num < A[0]) { + A[0] = num; + } else if (num < A[1] && num > A[0]) { + A[1] = num; + } else if (num < A[2] && num > A[1]) { + return true; + } + } + return false; + } +} + From 778a0f656bc4fa6770c3ff55e7596a39ab282d1d Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 17 Dec 2017 20:47:07 +0100 Subject: [PATCH 129/235] Combination Sum IV : Accepted --- README.md | 1 + .../dynamic_programming/CombinationSumIV.java | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 problems/src/dynamic_programming/CombinationSumIV.java diff --git a/README.md b/README.md index dc66ed92..69f55872 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Palindromic Substrings](problems/src/dynamic_programming/PalindromicSubstrings.java) (Medium) - [Number of Longest Increasing Subsequence](problems/src/dynamic_programming/NumberOfLIS.java) (Medium) - [Best Time to Buy and Sell Stock with Transaction Fee](problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java) (Medium) +- [Combination Sum IV](problems/src/dynamic_programming/CombinationSumIV.java) (Medium) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/CombinationSumIV.java b/problems/src/dynamic_programming/CombinationSumIV.java new file mode 100644 index 00000000..e9ecab7d --- /dev/null +++ b/problems/src/dynamic_programming/CombinationSumIV.java @@ -0,0 +1,66 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 17/12/2017. + * Given an integer array with all positive numbers and no duplicates, find the number of possible combinations that + * add up to a positive integer target. + + Example: + + nums = [1, 2, 3] + target = 4 + + The possible combination ways are: + (1, 1, 1, 1) + (1, 1, 2) + (1, 2, 1) + (1, 3) + (2, 1, 1) + (2, 2) + (3, 1) + + Note that different sequences are counted as different combinations. + + Therefore the output is 7. + Follow up: + What if negative numbers are allowed in the given array? + How does it change the problem? + What limitation we need to add to the question to allow negative numbers? + + Solution: Backtrack and dp + */ +public class CombinationSumIV { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1, 2, 3}; + System.out.println(new CombinationSumIV().combinationSum4(A, 4)); + } + + public int combinationSum4(int[] nums, int target) { + int[] dp = new int[target + 1]; + Arrays.fill(dp, -1); + dp[0] = 1; + return backtrack(nums, dp, target); + } + + private int backtrack(int[] nums, int[] dp, int sum){ + int total = 0; + if(sum < 0) return 0; + if(dp[sum] != -1) return dp[sum]; + else{ + for (int num : nums) { + total += backtrack(nums, dp, sum - num); + } + } + dp[sum] = total; + return dp[sum]; + } + +} From e256d05c7b5dc08993936a84a0f27790923bace7 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 24 Dec 2017 02:32:55 +0530 Subject: [PATCH 130/235] Paint House II: Accepted --- README.md | 1 + .../src/dynamic_programming/PaintHouseII.java | 69 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 problems/src/dynamic_programming/PaintHouseII.java diff --git a/README.md b/README.md index 69f55872..d63c36eb 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Number of Longest Increasing Subsequence](problems/src/dynamic_programming/NumberOfLIS.java) (Medium) - [Best Time to Buy and Sell Stock with Transaction Fee](problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java) (Medium) - [Combination Sum IV](problems/src/dynamic_programming/CombinationSumIV.java) (Medium) +- [Paint House II](problems/src/dynamic_programming/PaintHouseII.java) (Hard) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/PaintHouseII.java b/problems/src/dynamic_programming/PaintHouseII.java new file mode 100644 index 00000000..8330300a --- /dev/null +++ b/problems/src/dynamic_programming/PaintHouseII.java @@ -0,0 +1,69 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 23/12/2017. + * There are a row of n houses, each house can be painted with one of the k colors. The cost of painting each house + * with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same + * color. + + The cost of painting each house with a certain color is represented by a n x k cost matrix. For example, costs[0][0] + is the cost of painting house 0 with color 0; costs[1][2] is the cost of painting house 1 with color 2, and so on... + Find the minimum cost to paint all houses. + + Note: + All costs are positive integers. + + Follow up: + Could you solve it in O(nk) runtime? + + Solution: + Worst case run-time complexity of O(n x k) : Perform a prefix and postfix sum and maintain a auxiliary array to keep + track of prefix and post-fix sum. + Perform a bottom-up dp to calculate the final result. + DP[i][j] = DP[i][j] + Min(LeftPrefixSum[i + 1][j], RightPrefixSum[i + 1][j]) + */ +public class PaintHouseII { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[][] A = {{1, 2, 3}, {1, 2, 3}, {1, 2, 3}}; + System.out.println(new PaintHouseII().minCostII(A)); + } + + public int minCostII(int[][] costs) { + if(costs.length == 0) return 0; + int[][] lMin = new int[costs.length][costs[0].length]; + int[][] rMin = new int[costs.length][costs[0].length]; + for(int i = costs.length - 2; i >= 0; i--){ + int min = Integer.MAX_VALUE; + for(int j = 0; j < costs[0].length; j++){ + lMin[i + 1][j] = min; + min = Math.min(min, costs[i + 1][j]); + } + min = Integer.MAX_VALUE; + for(int j = costs[0].length - 1; j >= 0; j--){ + rMin[i + 1][j] = min; + min = Math.min(min, costs[i + 1][j]); + } + + for(int j = 0; j < costs[0].length; j++){ + if(j == 0){ + costs[i][j] = costs[i][j] + rMin[i + 1][j]; + } else if(j == costs[0].length - 1){ + costs[i][j] = costs[i][j] + lMin[i + 1][j]; + } else { + costs[i][j] = costs[i][j] + Math.min(lMin[i + 1][j], rMin[i + 1][j]); + } + } + } + int min = Integer.MAX_VALUE; + for(int i = 0; i < costs[0].length; i ++){ + min = Math.min(min, costs[0][i]); + } + return min; + } +} From 7ef1e62b0793270e448950f73e2b43baa9fa4e28 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Mon, 25 Dec 2017 02:15:31 +0530 Subject: [PATCH 131/235] Split Array Largest Sum: Accepted --- README.md | 1 + .../SplitArrayLargestSum.java | 59 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 problems/src/dynamic_programming/SplitArrayLargestSum.java diff --git a/README.md b/README.md index d63c36eb..7ad5a19e 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Best Time to Buy and Sell Stock with Transaction Fee](problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java) (Medium) - [Combination Sum IV](problems/src/dynamic_programming/CombinationSumIV.java) (Medium) - [Paint House II](problems/src/dynamic_programming/PaintHouseII.java) (Hard) +- [Split Array Largest Sum](problems/src/dynamic_programming/SplitArrayLargestSum.java) (Hard) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/SplitArrayLargestSum.java b/problems/src/dynamic_programming/SplitArrayLargestSum.java new file mode 100644 index 00000000..5bfc86ea --- /dev/null +++ b/problems/src/dynamic_programming/SplitArrayLargestSum.java @@ -0,0 +1,59 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 24/12/2017. + * Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty + * continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays. + + Note: + If n is the length of array, assume the following constraints are satisfied: + + 1 ≤ n ≤ 1000 + 1 ≤ m ≤ min(50, n) + Examples: + + Input: + nums = [7,2,5,10,8] + m = 2 + + Output: + 18 + + Explanation: + There are four ways to split nums into two subarrays. + The best way is to split it into [7,2,5] and [10,8], + where the largest sum among the two subarrays is only 18. + + Solution O(n ^ 2 * k) + Build a bottom up min-max dp table for each sub-array ranging from n -> 0 + */ +public class SplitArrayLargestSum { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {7,2,5,10,8}; + System.out.println(new SplitArrayLargestSum().splitArray(A, 2)); + } + + public int splitArray(int[] nums, int m) { + int[][] dp = new int[m][nums.length]; + for(int i = nums.length - 1; i >= 0; i --){ + int sum = 0; + for(int j = i; j < nums.length; j ++){ + sum += nums[j]; + if(j + 1 >= nums.length) break; + for(int k = 0; k < m - 1; k++){ + dp[k + 1][i] = (dp[k + 1][i] == 0) ? Integer.MAX_VALUE : dp[k + 1][i]; + int temp = Math.max(sum, dp[k][j + 1]); + dp[k + 1][i] = Math.min(dp[k + 1][i], temp); + } + } + dp[0][i] = sum; + } + return dp[m - 1][0]; + } +} From 76d0ee345974084c85e397daa19feaa5fee13191 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 26 Dec 2017 03:19:18 +0530 Subject: [PATCH 132/235] Prefix and Suffix Search: Accepted --- README.md | 1 + problems/src/design/WordFilter.java | 124 ++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 problems/src/design/WordFilter.java diff --git a/README.md b/README.md index 7ad5a19e..172717a9 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Design Excel Sum Formula](problems/src/design/Excel.java) (Hard) - [Flatten Nested List Iterator](problems/src/design/NestedIterator.java) (Medium) - [Add and Search Word - Data structure design](problems/src/design/WordDictionary.java) (Medium) +- [Prefix and Suffix Search](problems/src/design/WordFilter.java) (Hard) #### [Divide and Conquer](problems/src/divide_and_conquer) diff --git a/problems/src/design/WordFilter.java b/problems/src/design/WordFilter.java new file mode 100644 index 00000000..8503edb3 --- /dev/null +++ b/problems/src/design/WordFilter.java @@ -0,0 +1,124 @@ +package design; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by gouthamvidyapradhan on 25/12/2017. + * Given many words, words[i] has weight i. + + Design a class WordFilter that supports one function, WordFilter.f(String prefix, String suffix). It will return the + word with given prefix and suffix with maximum weight. If no word exists, return -1. + + Examples: + Input: + WordFilter(["apple"]) + WordFilter.f("a", "e") // returns 0 + WordFilter.f("b", "") // returns -1 + Note: + words has length in range [1, 15000]. + For each test case, up to words.length queries WordFilter.f may be made. + words[i] has length in range [1, 10]. + prefix, suffix have lengths in range [0, 10]. + words[i] and prefix, suffix queries consist of lowercase letters only. + + Solution: Implement a trie to store the dictionary of words. For every word insert all the possible suffixes into + the trie. Additionally overwrite weight each time a word is inserted. + Example for a word 'cat' all the possible trie insertions are -> #cat, t#cat, at#cat, cat#cat + Search for 'suffix#prefix' in the trie and return its weight + */ +public class WordFilter { + + private Trie trie; + private int maxWeight; //max weight possible + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + String[] words = {"apple", "cat", "mat", "mars", "abxcd", "abycd", "apple"}; + WordFilter wf = new WordFilter(words); + System.out.println(wf.f("abx", "")); + } + + public WordFilter(String[] words) { + trie = new Trie(); + trie.weight = -1; + maxWeight = words.length - 1; + for(int i = 0; i < words.length; i ++){ + String word = words[i]; + trie.insert("#" + word, i); + for(int j = 0, l = word.length(); j < l; j++){ + trie.insert(word.substring(j, l) + "#" + word, i); + } + } + } + + public int f(String prefix, String suffix) { + if((suffix == null || suffix.isEmpty()) && (prefix == null || prefix.isEmpty())){ + return maxWeight; + } else if(prefix == null || prefix.isEmpty()){ + return trie.search(suffix + "#"); + } else if(suffix == null || suffix.isEmpty()){ + return trie.search("#" + prefix); + } else{ + return trie.search(suffix + "#" + prefix); + } + } + + public static class Trie { + + private Map map; + int weight; + + + /** + * Initialize your data structure here. + */ + public Trie() { + map = new HashMap<>(); + } + + /** + * Inserts a word into the trie. + */ + public void insert(String word, int weight) { + if (word != null) { + add(0, word, word.length(), weight); + } + } + + private void add(int i, String word, int length, int weight) { + if (i < length) { + char c = word.charAt(i); + map.putIfAbsent(c, new Trie()); + Trie subTrie = map.get(c); + subTrie.weight = weight; + subTrie.add(i + 1, word, length, weight); + } + } + + /** + * Returns if the word is in the trie. + */ + public int search(String word) { + if (word != null) { + return search(0, word, word.length()); + } + return -1; + } + + private int search(int i, String word, int length) { + if (i < length) { + char c = word.charAt(i); + Trie subTrie = map.get(c); + if (subTrie == null) + return -1; + return subTrie.search(i + 1, word, length); + } + return this.weight; + } + } +} From ecd4d652988b54c00d68a5a7ddc1f91bea15d88c Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 26 Dec 2017 21:42:27 +0530 Subject: [PATCH 133/235] Number Of Corner Rectangles: Accepted --- README.md | 1 + .../dynamic_programming/CornerRectangles.java | 71 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 problems/src/dynamic_programming/CornerRectangles.java diff --git a/README.md b/README.md index 172717a9..72cfdd90 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Combination Sum IV](problems/src/dynamic_programming/CombinationSumIV.java) (Medium) - [Paint House II](problems/src/dynamic_programming/PaintHouseII.java) (Hard) - [Split Array Largest Sum](problems/src/dynamic_programming/SplitArrayLargestSum.java) (Hard) +- [Number Of Corner Rectangles](problems/src/dynamic_programming/CornerRectangles.java) (Medium) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/CornerRectangles.java b/problems/src/dynamic_programming/CornerRectangles.java new file mode 100644 index 00000000..183396dd --- /dev/null +++ b/problems/src/dynamic_programming/CornerRectangles.java @@ -0,0 +1,71 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 26/12/2017. + * Given a grid where each entry is only 0 or 1, find the number of corner rectangles. + + A corner rectangle is 4 distinct 1s on the grid that form an axis-aligned rectangle. Note that only the corners need + to have the value 1. Also, all four 1s used must be distinct. + + Example 1: + Input: grid = + [[1, 0, 0, 1, 0], + [0, 0, 1, 0, 1], + [0, 0, 0, 1, 0], + [1, 0, 1, 0, 1]] + Output: 1 + Explanation: There is only one corner rectangle, with corners grid[1][2], grid[1][4], grid[3][2], grid[3][4]. + Example 2: + Input: grid = + [[1, 1, 1], + [1, 1, 1], + [1, 1, 1]] + Output: 9 + Explanation: There are four 2x2 rectangles, four 2x3 and 3x2 rectangles, and one 3x3 rectangle. + Example 3: + Input: grid = + [[1, 1, 1, 1]] + Output: 0 + Explanation: Rectangles must have four distinct corners. + Note: + The number of rows and columns of grid will each be in the range [1, 200]. + Each grid[i][j] will be either 0 or 1. + The number of 1s in the grid will be at most 6000. + + Solution O(n + m ^ 2): For every row, consider each pair of 1s (every column pairs) and sum up the previous + occurrence of 1s for the same column. + + */ +public class CornerRectangles { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[][] A = {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}; + System.out.println(new CornerRectangles().countCornerRectangles(A)); + } + + public int countCornerRectangles(int[][] grid) { + int[][] count = new int[grid[0].length][grid[0].length]; + int result = 0; + for(int[] row : grid){ + for(int i = 0; i < row.length; i ++){ + if(row[i] == 1){ + for(int j = i + 1; j < row.length; j++){ + if(row[j] == 1){ + if(count[i][j] > 0){ + result += count[i][j]; + } + count[i][j] ++; + } + } + } + } + } + return result; + } + +} From cbd97add9a0646db8c9195ed5e09a613376bf894 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 27 Dec 2017 00:47:06 +0530 Subject: [PATCH 134/235] Walls and Gates: Accepted --- README.md | 1 + .../breadth_first_search/WallsAndGates.java | 81 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 problems/src/breadth_first_search/WallsAndGates.java diff --git a/README.md b/README.md index 72cfdd90..24f45680 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Binaray Tree Level Order Traversal](problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java) (Medium) - [Word Ladder](problems/src/breadth_first_search/WordLadder.java) (Medium) - [Word Ladder II](problems/src/breadth_first_search/WordLadderII.java) (Hard) +- [Walls and Gates](problems/src/breadth_first_search/WallsAndGates.java) (Medium) #### [Depth First Search](problems/src/depth_first_search) diff --git a/problems/src/breadth_first_search/WallsAndGates.java b/problems/src/breadth_first_search/WallsAndGates.java new file mode 100644 index 00000000..08bc6e59 --- /dev/null +++ b/problems/src/breadth_first_search/WallsAndGates.java @@ -0,0 +1,81 @@ +package breadth_first_search; + +import java.util.ArrayDeque; +import java.util.Queue; + +/** + * Created by gouthamvidyapradhan on 26/12/2017. + * You are given a m x n 2D grid initialized with these three possible values. + + -1 - A wall or an obstacle. + 0 - A gate. + INF - Infinity means an empty room. We use the value 231 - 1 = 2147483647 to represent INF as you may assume that + the distance to a gate is less than 2147483647. + Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, it should be filled + with INF. + + For example, given the 2D grid: + INF -1 0 INF + INF INF INF -1 + INF -1 INF -1 + 0 -1 INF INF + After running your function, the 2D grid should be: + 3 -1 0 1 + 2 2 1 -1 + 1 -1 2 -1 + 0 -1 3 4 + + Solution: O(n x m): Treat each coordinate of grid with 0 as a source and destination as the coordinate of 2147483647 + and perform a multi-sources BFS from each source. + */ +public class WallsAndGates { + + private static final int[] R = {0, 0, 1, -1}; + private static final int[] C = {1, -1, 0, 0}; + + private class Cell{ + int r, c; + Cell(int r, int c){ + this.r = r; + this.c = c; + } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[][] A = {{Integer.MAX_VALUE, -1, 0, Integer.MAX_VALUE}, + {Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, -1}, + {Integer.MAX_VALUE, -1, Integer.MAX_VALUE, -1}, + {0, -1, Integer.MAX_VALUE, Integer.MAX_VALUE}}; + new WallsAndGates().wallsAndGates(A); + } + + public void wallsAndGates(int[][] rooms) { + Queue queue = new ArrayDeque<>(); + for(int i = 0; i < rooms.length; i ++){ + for(int j = 0; j < rooms[0].length; j ++){ + if(rooms[i][j] == 0){ //treat each co-ordinates of gate as a source + Cell cell = new Cell(i, j); + queue.offer(cell); + } + } + } + while(!queue.isEmpty()){ + Cell top = queue.poll(); + for(int i = 0; i < 4; i++){ + int newR = top.r + R[i]; + int newC = top.c + C[i]; + if(newR >= 0 && newC >= 0 && newR < rooms.length && newC < rooms[0].length){ + if(rooms[newR][newC] == Integer.MAX_VALUE){ + rooms[newR][newC] = rooms[top.r][top.c] + 1; + queue.offer(new Cell(newR, newC)); + } + } + } + } + } +} From 065c80074636299dab354708f3bf0efd4b36b09e Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 27 Dec 2017 19:48:59 +0530 Subject: [PATCH 135/235] Accounts Merge: Accepted --- README.md | 1 + .../src/depth_first_search/AccountsMerge.java | 145 ++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 problems/src/depth_first_search/AccountsMerge.java diff --git a/README.md b/README.md index 24f45680..e6dac153 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Alien Dictionary](problems/src/depth_first_search/AlienDictionary.java) (Hard) - [Graph Valid Tree](problems/src/depth_first_search/GraphValidTree.java) (Medium) - [Longest Consecutive Sequence](problems/src/depth_first_search/LongestConsecutiveSequence.java) (Hard) +- [Accounts Merge](problems/src/depth_first_search/AccountsMerge.java) (Medium) #### [Design](problems/src/design) diff --git a/problems/src/depth_first_search/AccountsMerge.java b/problems/src/depth_first_search/AccountsMerge.java new file mode 100644 index 00000000..07bd27df --- /dev/null +++ b/problems/src/depth_first_search/AccountsMerge.java @@ -0,0 +1,145 @@ +package depth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 27/12/2017. + * Given a list accounts, each element accounts[i] is a list of strings, where the first element accounts[i][0] is a + * name, and the rest of the elements are emails representing emails of the account. + + Now, we would like to merge these accounts. Two accounts definitely belong to the same person if there is some email + that is common to both accounts. Note that even if two accounts have the same name, they may belong to different + people as people could have the same name. A person can have any number of accounts initially, but all of their + accounts definitely have the same name. + + After merging the accounts, return the accounts in the following format: the first element of each account is the + name, and the rest of the elements are emails in sorted order. The accounts themselves can be returned in any order. + + Example 1: + Input: + accounts = [["John", "johnsmith@mail.com", "john00@mail.com"], ["John", "johnnybravo@mail.com"], ["John", + "johnsmith@mail.com", "john_newyork@mail.com"], ["Mary", "mary@mail.com"]] + Output: [["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'], ["John", "johnnybravo@mail + .com"], ["Mary", "mary@mail.com"]] + Explanation: + The first and third John's are the same person as they have the common email "johnsmith@mail.com". + The second John and Mary are different people as none of their email addresses are used by other accounts. + We could return these lists in any order, for example the answer [['Mary', 'mary@mail.com'], ['John', + 'johnnybravo@mail.com'], + ['John', 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com']] would still be accepted. + Note: + + The length of accounts will be in the range [1, 1000]. + The length of accounts[i] will be in the range [1, 10]. + The length of accounts[i][j] will be in the range [1, 30]. + + Solution: Consider each email_address as a vertex and link the emails of each account as bidirectional edges and + perform a dfs on connected components and return the email addresses of connected components. + */ +public class AccountsMerge { + + private class Account{ + String email, name; + Account(String email, String name){ + this.email = email; + this.name = name; + } + } + + private Map numMap; //for simplicity mapping each email to a unique integer + private Map emailMap; + private Map> graph; + private BitSet done; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + List account1 = new ArrayList<>(); + List> accounts = new ArrayList<>(); + account1.add("John"); + account1.add("johnsmith@mail.com"); + account1.add("john00@mail.com"); + accounts.add(account1); + + List account2 = new ArrayList<>(); + account2.add("John"); + account2.add("johnnybravo@mail.com"); + accounts.add(account2); + + List account3 = new ArrayList<>(); + account3.add("John"); + account3.add("johnsmith@mail.com"); + account3.add("john_newyork@mail.com"); + accounts.add(account3); + + List account4 = new ArrayList<>(); + account4.add("Mary"); + account4.add("mary@mail.com"); + accounts.add(account4); + + List> result = new AccountsMerge().accountsMerge(accounts); + System.out.println(result); + } + + public List> accountsMerge(List> accounts) { + done = new BitSet(); + numMap = new HashMap<>(); + emailMap = new HashMap<>(); + graph = new HashMap<>(); + int index = -1; + for(List account : accounts){ + String name = account.get(0); + int prev = -1; + for(int i = 1, l = account.size(); i < l; i ++){ + String email = account.get(i); + int vertex; + if(!emailMap.containsKey(email)){ + vertex = ++index; + emailMap.put(email, vertex); + numMap.put(vertex, new Account(email, name)); + } else { + vertex = emailMap.get(email); + } + graph.putIfAbsent(vertex, new ArrayList<>()); + if(i != 1){ + //make bi-directional link + graph.get(prev).add(vertex); + graph.get(vertex).add(prev); + } + prev = vertex; + } + } + List> result = new ArrayList<>(); + for(int i : graph.keySet()){ + if(!done.get(i)){ + List list = new ArrayList<>(); + List account = new ArrayList<>(); + dfs(i, list); + list.stream().forEach(x -> account.add(numMap.get(x).email)); + account.sort(String::compareTo); + + //Add account user name + Account acc = numMap.get(list.get(0)); + account.add(0, acc.name); + result.add(account); + } + } + return result; + } + + private void dfs(int i, List list){ + done.set(i); + list.add(i); + List children = graph.get(i); + if(children != null){ + for(int c : children){ + if(!done.get(c)){ + dfs(c, list); + } + } + } + } + +} From a81fc07079ab94ad1d46b20000ccb9152dbbaf10 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 2 Jan 2018 01:03:11 +0530 Subject: [PATCH 136/235] K Empty Slots: Accepted --- README.md | 1 + problems/src/array/KEmptySlots.java | 70 +++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 problems/src/array/KEmptySlots.java diff --git a/README.md b/README.md index e6dac153..7ce489c8 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ My accepted leetcode solutions to some of the common interview problems. - [H-Index](problems/src/array/HIndex.java) (Medium) - [Insert Interval](problems/src/array/InsertInterval.java) (Hard) - [Increasing Triplet Subsequence](problems/src/array/IncreasingTripletSubsequence.java) (Medium) +- [K Empty Slots](problems/src/array/KEmptySlots.java) (Hard) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/KEmptySlots.java b/problems/src/array/KEmptySlots.java new file mode 100644 index 00000000..24f3bf0d --- /dev/null +++ b/problems/src/array/KEmptySlots.java @@ -0,0 +1,70 @@ +package array; + +import java.util.TreeSet; + +/** + * Created by gouthamvidyapradhan on 01/01/2018. + * There is a garden with N slots. In each slot, there is a flower. The N flowers will bloom one by one in N days. + * In each day, there will be exactly one flower blooming and it will be in the status of blooming since then. + + Given an array flowers consists of number from 1 to N. Each number in the array represents the place where the + flower will open in that day. + + For example, flowers[i] = x means that the unique flower that blooms at day i will be at position x, where i and x + will be in the range from 1 to N. + + Also given an integer k, you need to output in which day there exists two flowers in the status of blooming, and + also the number of flowers between them is k and these flowers are not blooming. + + If there isn't such day, output -1. + + Example 1: + Input: + flowers: [1,3,2] + k: 1 + Output: 2 + Explanation: In the second day, the first and the third flower have become blooming. + Example 2: + Input: + flowers: [1,2,3] + k: 1 + Output: -1 + Note: + The given array will be in the range [1, 20000]. + + Solution: O(n log n). Maintain a tree-set of bloomed flowers and for every element in the array + find the upper and lower bound bloomed flowers and calculate their difference with the current. If + the difference is k return the current day, if none found then return -1 + + */ +public class KEmptySlots { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1, 3, 2}; + System.out.println(new KEmptySlots().kEmptySlots(A, 2)); + } + + public int kEmptySlots(int[] flowers, int k) { + TreeSet set = new TreeSet<>(); + for(int i = 0; i < flowers.length; i ++){ + Integer lowerBound = set.floor(flowers[i]); + Integer upperBound = set.ceiling(flowers[i]); + if(lowerBound != null){ + if((Math.abs(flowers[i] - lowerBound) + 1) == k){ + return i + 1; + } + } if(upperBound != null){ + if((Math.abs(flowers[i] - upperBound) + 1) == k){ + return i + 1; + } + } + set.add(flowers[i]); + } + return -1; + } + +} From 1e286770eacadf802ab8a6b7ea11deb22864e085 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 3 Jan 2018 00:35:31 +0530 Subject: [PATCH 137/235] Burst Balloons: Accepted --- README.md | 1 + .../dynamic_programming/BurstBalloons.java | 77 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 problems/src/dynamic_programming/BurstBalloons.java diff --git a/README.md b/README.md index 7ce489c8..06b7d434 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Paint House II](problems/src/dynamic_programming/PaintHouseII.java) (Hard) - [Split Array Largest Sum](problems/src/dynamic_programming/SplitArrayLargestSum.java) (Hard) - [Number Of Corner Rectangles](problems/src/dynamic_programming/CornerRectangles.java) (Medium) +- [Burst Balloons](problems/src/dynamic_programming/BurstBalloons.java) (Hard) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/BurstBalloons.java b/problems/src/dynamic_programming/BurstBalloons.java new file mode 100644 index 00000000..bed05c8e --- /dev/null +++ b/problems/src/dynamic_programming/BurstBalloons.java @@ -0,0 +1,77 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 02/01/2018. + * Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by array nums. + * You are asked to burst all the balloons. If the you burst balloon i you will get nums[left] * nums[i] * + * nums[right] coins. Here left and right are adjacent indices of i. After the burst, the left and right then + * becomes adjacent. + + Find the maximum coins you can collect by bursting the balloons wisely. + + Note: + (1) You may imagine nums[-1] = nums[n] = 1. They are not real therefore you can not burst them. + (2) 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100 + + Example: + + Given [3, 1, 5, 8] + + Return 167 + + nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> [] + coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167 + + Solution: O(N ^ 3) + The recursive top-down dp memorization solution is based on the idea where each balloon is considered as the last + balloon to be burst. + For the above example 1,3,1,5,8,1 (1 included at either end to indicate boundary) + each balloon starting from 3 until 8 is chosen each time as a the last balloon to be burst using the boundary 1 on + either side. + So, for the first iteration the result is calculated as + 3*1(left boundary)*1(right boundary) + dp(1, 3) (left-sub-problem having 1 and 3 as the boundary) + dp(3, 1) + (right-sub-problem having 3 and 1 as the boundary) + + */ +public class BurstBalloons { + private int[][] dp; + private int[] N; + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {3, 1, 5, 8}; + System.out.println(new BurstBalloons().maxCoins(A)); + } + + public int maxCoins(int[] nums) { + N = new int[nums.length + 2]; + N[0] = N[N.length - 1] = 1; //boundary + for(int i = 0; i < nums.length; i ++){ + N[i + 1] = nums[i]; + } + dp = new int[N.length][N.length]; + for (int[] aDp : dp) { + Arrays.fill(aDp, -1); + } + return dp(0, N.length - 1); + } + + private int dp(int l, int r){ + if(l + 1 == r) return 0; + if(dp[l][r] != -1) return dp[l][r]; + int result = 0; + for(int i = l + 1; i < r; i ++){ + result = Math.max(result, N[i] * N[l] * N[r] + dp(l, i) + dp(i, r)); + } + dp[l][r] = result; + return dp[l][r]; + } + + +} From 55f397eff19e9f3221d5342c6033af124aab1bb5 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 3 Jan 2018 20:42:02 +0530 Subject: [PATCH 138/235] Subarray Sum Equals K: Accepted --- README.md | 1 + problems/src/array/SubarraySumEqualsK.java | 64 ++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 problems/src/array/SubarraySumEqualsK.java diff --git a/README.md b/README.md index 06b7d434..b1c1d6f5 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Insert Interval](problems/src/array/InsertInterval.java) (Hard) - [Increasing Triplet Subsequence](problems/src/array/IncreasingTripletSubsequence.java) (Medium) - [K Empty Slots](problems/src/array/KEmptySlots.java) (Hard) +- [Subarray Sum Equals K](problems/src/array/SubarraySumEqualsK.java) (Medium) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/SubarraySumEqualsK.java b/problems/src/array/SubarraySumEqualsK.java new file mode 100644 index 00000000..e3ffc753 --- /dev/null +++ b/problems/src/array/SubarraySumEqualsK.java @@ -0,0 +1,64 @@ +package array; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by gouthamvidyapradhan on 03/01/2018. + * Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum + * equals to k. + + Example 1: + Input:nums = [1,1,1], k = 2 + Output: 2 + Note: + The length of the array is in range [1, 20,000]. + The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7]. + + Solution: O(n) Maintain a hash-map of prefix sum and its count and check for range sum for each element. + */ +public class SubarraySumEqualsK { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1, 2, 1, -2, 3, -1, -1}; + System.out.println(new SubarraySumEqualsK().subarraySum(A, 2)); + } + + public int subarraySum(int[] nums, int k) { + Map map = new HashMap<>(); + int sum = 0; + for(int i : nums){ + sum += i; + Integer count = map.get(sum); + if(count == null){ + map.put(sum, 1); + } else{ + map.put(sum, count + 1); + } + } + sum = 0; + int result = 0; + for(int i : nums){ + int key = sum + k; + if(map.containsKey(key)){ + int count = map.get(key); + result += count; + } + sum += i; + if(map.containsKey(sum)){ + int count = map.get(sum); + if(count - 1 > 0){ + map.put(sum, count - 1); + } else{ + map.remove(sum); + } + } + } + return result; + } +} From bff0843ca420236b710aff124622bf809507a8d2 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 19 Jan 2018 00:06:15 +0100 Subject: [PATCH 139/235] Clone Graph : Accepted --- README.md | 1 + .../src/depth_first_search/CloneGraph.java | 90 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 problems/src/depth_first_search/CloneGraph.java diff --git a/README.md b/README.md index b1c1d6f5..bdef474f 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Graph Valid Tree](problems/src/depth_first_search/GraphValidTree.java) (Medium) - [Longest Consecutive Sequence](problems/src/depth_first_search/LongestConsecutiveSequence.java) (Hard) - [Accounts Merge](problems/src/depth_first_search/AccountsMerge.java) (Medium) +- [CloneGraph](problems/src/depth_first_search/CloneGraph.java) (Medium) #### [Design](problems/src/design) diff --git a/problems/src/depth_first_search/CloneGraph.java b/problems/src/depth_first_search/CloneGraph.java new file mode 100644 index 00000000..9cdec1ab --- /dev/null +++ b/problems/src/depth_first_search/CloneGraph.java @@ -0,0 +1,90 @@ +package depth_first_search; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by gouthamvidyapradhan on 18/01/2018. + * Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. + + + OJ's undirected graph serialization: + Nodes are labeled uniquely. + + We use # as a separator for each node, and , as a separator for node label and each neighbor of the node. + As an example, consider the serialized graph {0,1,2#1,2#2,2}. + + The graph has a total of three nodes, and therefore contains three parts as separated by #. + + First node is labeled as 0. Connect node 0 to both nodes 1 and 2. + Second node is labeled as 1. Connect node 1 to node 2. + Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle. + Visually, the graph looks like the following: + + 1 + / \ + / \ + 0 --- 2 + / \ + \_/ + + Solution: O(V + E) maintain a hashmap of reference nodes and build the graph by dfs + */ +public class CloneGraph { + + static class UndirectedGraphNode { + int label; + List neighbors; + UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<>(); } + } + + private Map map; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + UndirectedGraphNode node = new UndirectedGraphNode(0); + UndirectedGraphNode node1 = new UndirectedGraphNode(1); + UndirectedGraphNode node2 = new UndirectedGraphNode(2); + node.neighbors.add(node1); + node.neighbors.add(node2); + + node1.neighbors.add(node); + node1.neighbors.add(node2); + + node2.neighbors.add(node); + node2.neighbors.add(node1); + node2.neighbors.add(node2); + UndirectedGraphNode result = new CloneGraph().cloneGraph(node); + //print result + } + + public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { + if(node == null) return null; + map = new HashMap<>(); + UndirectedGraphNode clone = new UndirectedGraphNode(node.label); + dfs(node, clone); + return clone; + } + + private void dfs(UndirectedGraphNode original, UndirectedGraphNode clone){ + map.put(clone.label, clone); + List oChildren = original.neighbors; //original child nodes + List cChildren = clone.neighbors; //clone child nodes + for(UndirectedGraphNode oChild : oChildren){ + if(map.containsKey(oChild.label)){ + //already visited node + cChildren.add(map.get(oChild.label)); + } else{ + //a new node + UndirectedGraphNode newChildClone = new UndirectedGraphNode(oChild.label); + cChildren.add(newChildClone); + dfs(oChild, newChildClone); + } + } + } +} From 769b29fe89ecf71f61647c80ebcb29dff28b19f3 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 19 Jan 2018 01:54:41 +0100 Subject: [PATCH 140/235] Brick Wall : Accepted --- README.md | 1 + problems/src/hashing/BrickWall.java | 95 +++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 problems/src/hashing/BrickWall.java diff --git a/README.md b/README.md index bdef474f..2a25f9fd 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Valid Anagram](problems/src/hashing/ValidAnagram.java) (Easy) - [Maximum Size Subarray Sum Equals k](problems/src/hashing/MaximumSizeSubarraySumEqualsk.java) (Medium) - [Contiguous Array](problems/src/hashing/ContiguousArray.java) (Medium) +- [Brick Wall](problems/src/hashing/BrickWall.java) (Medium) #### [Heap](problems/src/heap) diff --git a/problems/src/hashing/BrickWall.java b/problems/src/hashing/BrickWall.java new file mode 100644 index 00000000..b3e824f1 --- /dev/null +++ b/problems/src/hashing/BrickWall.java @@ -0,0 +1,95 @@ +package hashing; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by gouthamvidyapradhan on 19/01/2018. + * There is a brick wall in front of you. The wall is rectangular and has several rows of bricks. The bricks have + * the same height but different width. You want to draw a vertical line from the top to the bottom and cross the least bricks. + + The brick wall is represented by a list of rows. Each row is a list of integers representing the width of each + brick in this row from left to right. + + If your line go through the edge of a brick, then the brick is not considered as crossed. You need to find out how + to draw the line to cross the least bricks and return the number of crossed bricks. + + You cannot draw a line just along one of the two vertical edges of the wall, in which case the line will obviously + cross no bricks. + + Example: + Input: + [[1,2,2,1], + [3,1,2], + [1,3,2], + [2,4], + [3,1,2], + [1,3,1,1]] + Output: 2 + Explanation: + + Note: + The width sum of bricks in different rows are the same and won't exceed INT_MAX. + The number of bricks in each row is in range [1,10,000]. The height of wall is in range [1,10,000]. Total number of + bricks of the wall won't exceed 20,000. + + Solution: O(N) where N is the total number of bricks. Calculate the prefix sum for each row of bricks and + keep a max_count of each occurrence of prefix. The answer is total number of rows of bricks - max_count + */ +public class BrickWall { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + List> wall = new ArrayList<>(); + List row1 = new ArrayList<>(); + List row2 = new ArrayList<>(); + List row3 = new ArrayList<>(); + List row4 = new ArrayList<>(); + List row5 = new ArrayList<>(); + List row6 = new ArrayList<>(); + row1.add(1); row1.add(2); row1.add(2); row1.add(1); + row2.add(3); row2.add(1); row2.add(2); + row3.add(1); row3.add(3); row3.add(2); + row4.add(2); row4.add(4); + row5.add(3); row5.add(1); row5.add(2); + row6.add(1); row6.add(3); row6.add(1); row6.add(1); + wall.add(row1); + wall.add(row2); + wall.add(row3); + wall.add(row4); + wall.add(row5); + wall.add(row6); + System.out.println(new BrickWall().leastBricks(wall)); + } + + public int leastBricks(List> wall) { + for(List row : wall){ + int prefix = 0; + for(int i = 0, l = row.size(); i < l; i ++){ + prefix += row.get(i); + row.set(i, prefix); + } + } + int result = Integer.MIN_VALUE; + Map map = new HashMap<>(); + for(List row : wall){ + for(int i = 0, l = row.size(); i < l - 1; i ++){ + int prefix = row.get(i); + if(map.containsKey(prefix)){ + int plusOne = map.get(prefix) + 1; + map.put(prefix, plusOne); + result = Math.max(result, plusOne); + } else{ + map.put(prefix, 1); + result = Math.max(result, 1); + } + } + } + return (result == Integer.MIN_VALUE) ? wall.size() : wall.size() - result; + } +} From e35529c4f9fbc01fddf9270226bca4c692a20d43 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 20 Jan 2018 12:09:10 +0100 Subject: [PATCH 141/235] Count and Say : Accepted --- README.md | 1 + problems/src/string/CountAndSay.java | 60 ++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 problems/src/string/CountAndSay.java diff --git a/README.md b/README.md index 2a25f9fd..6d40e603 100644 --- a/README.md +++ b/README.md @@ -231,6 +231,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Add Binary](problems/src/string/AddBinary.java) (Easy) - [Valid Palindrome II](problems/src/string/ValidPalindromeII.java) (Easy) - [One Edit Distance](problems/src/string/OneEditDistance.java) (Medium) +- [Count and Say](problems/src/string/CountAndSay.java) (Easy) #### [Tree](problems/src/tree) diff --git a/problems/src/string/CountAndSay.java b/problems/src/string/CountAndSay.java new file mode 100644 index 00000000..1ed7e39a --- /dev/null +++ b/problems/src/string/CountAndSay.java @@ -0,0 +1,60 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 20/01/2018. + * + * The count-and-say sequence is the sequence of integers with the first five terms as following: + + 1. 1 + 2. 11 + 3. 21 + 4. 1211 + 5. 111221 + 1 is read off as "one 1" or 11. + 11 is read off as "two 1s" or 21. + 21 is read off as "one 2, then one 1" or 1211. + Given an integer n, generate the nth term of the count-and-say sequence. + + Note: Each term of the sequence of integers will be represented as a string. + + Example 1: + + Input: 1 + Output: "1" + Example 2: + + Input: 4 + Output: "1211" + + */ +public class CountAndSay { + + /** + * Main method + * @param args + */ + public static void main(String[] args) throws Exception { + System.out.println(new CountAndSay().countAndSay(4)); + } + + public String countAndSay(int n) { + String result = "1"; + for(int i = 1; i < n; i ++){ + int count = 1; + char num = result.charAt(0); + StringBuilder temp = new StringBuilder(); + for(int j = 1, l = result.length(); j < l; j++){ + if(result.charAt(j) == num){ + count++; + } else{ + temp = temp.append(String.valueOf(count)).append(String.valueOf(num)); + num = result.charAt(j); + count = 1; + } + } + temp = temp.append(String.valueOf(count)).append(String.valueOf(num)); + result = temp.toString(); + } + return result; + } +} From b26a605dc6271e0532d82aebb66ebadbcd03e551 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 20 Jan 2018 13:36:59 +0100 Subject: [PATCH 142/235] Exclusive Time of Functions : Accepted --- README.md | 1 + .../src/stack/ExclusiveTimeOfFunctions.java | 101 ++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 problems/src/stack/ExclusiveTimeOfFunctions.java diff --git a/README.md b/README.md index 6d40e603..59e49dec 100644 --- a/README.md +++ b/README.md @@ -211,6 +211,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Largest Rectangle In Histogram](problems/src/stack/LargestRectangleInHistogram.java) (Hard) - [Implement Queue using Stacks](problems/src/stack/MyQueue.java) (Easy) - [Maximal Rectangle](problems/src/stack/MaximalRectangle.java) (Hard) +- [Exclusive Time of Functions](problems/src/stack/ExclusiveTimeOfFunctions.java) (Medium) #### [String](problems/src/string) diff --git a/problems/src/stack/ExclusiveTimeOfFunctions.java b/problems/src/stack/ExclusiveTimeOfFunctions.java new file mode 100644 index 00000000..23b27d24 --- /dev/null +++ b/problems/src/stack/ExclusiveTimeOfFunctions.java @@ -0,0 +1,101 @@ +package stack; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Stack; + +/** + * Created by gouthamvidyapradhan on 20/01/2018. + * Given the running logs of n functions that are executed in a nonpreemptive single threaded CPU, find the exclusive + * time of these functions. + + Each function has a unique id, start from 0 to n-1. A function may be called recursively or by another function. + + A log is a string has this format : function_id:start_or_end:timestamp. For example, "0:start:0" means function 0 + starts from the very beginning of time 0. "0:end:0" means function 0 ends to the very end of time 0. + + Exclusive time of a function is defined as the time spent within this function, the time spent by calling other + functions should not be considered as this function's exclusive time. You should return the exclusive time of each + function sorted by their function id. + + Example 1: + Input: + n = 2 + logs = + ["0:start:0", + "1:start:2", + "1:end:5", + "0:end:6"] + Output:[3, 4] + Explanation: + Function 0 starts at time 0, then it executes 2 units of time and reaches the end of time 1. + Now function 0 calls function 1, function 1 starts at time 2, executes 4 units of time and end at time 5. + Function 0 is running again at time 6, and also end at the time 6, thus executes 1 unit of time. + So function 0 totally execute 2 + 1 = 3 units of time, and function 1 totally execute 4 units of time. + Note: + Input logs will be sorted by timestamp, NOT log id. + Your output should be sorted by function id, which means the 0th element of your output corresponds to the + exclusive time of function 0. + Two functions won't start or end at the same time. + Functions could be called recursively, and will always end. + 1 <= n <= 100 + + Solution: Use a stack to store the logs and update time. + + */ +public class ExclusiveTimeOfFunctions { + + class Log{ + int funId, time; + String fun; + Log(int funId, String fun, int time){ + this.funId = funId; + this.fun = fun; + this.time = time; + } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] N = new ExclusiveTimeOfFunctions().exclusiveTime(2, Arrays.asList("0:start:0", "1:start:2", "1:end:5", + "0:end:6")); + Arrays.stream(N).forEach(System.out::println); + } + + public int[] exclusiveTime(int n, List logs) { + int[] N = new int[n]; + List functions = new ArrayList<>(); + for(String s : logs){ + String[] parts = s.split(":"); + functions.add(new Log(Integer.parseInt(parts[0]), parts[1], Integer.parseInt(parts[2]))); + } + Stack stack = new Stack<>(); + stack.push(functions.get(0)); + for(int i = 1, l = functions.size(); i < l; i ++){ + Log next = functions.get(i); + if(stack.isEmpty()){ + stack.push(next); + continue; + } + Log curr = stack.peek(); + if(next.fun.equals("end")){ + N[curr.funId] += (next.time - curr.time + 1); + stack.pop(); //since the end has reached, remove from stack + if(!stack.isEmpty()){ + stack.peek().time = next.time + 1; //IMPORTANT: update the time of the old function to a new start + // time + } + } else { + stack.push(next); + N[curr.funId] += (next.time - curr.time); + } + } + return N; + } + +} From a6f69066158b199e67e9f1153f67eca67b996aa4 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 20 Jan 2018 21:42:24 +0100 Subject: [PATCH 143/235] Largest Plus Sign : Accepted --- README.md | 1 + .../dynamic_programming/LargestPlusSign.java | 158 ++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 problems/src/dynamic_programming/LargestPlusSign.java diff --git a/README.md b/README.md index 59e49dec..e712649f 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Split Array Largest Sum](problems/src/dynamic_programming/SplitArrayLargestSum.java) (Hard) - [Number Of Corner Rectangles](problems/src/dynamic_programming/CornerRectangles.java) (Medium) - [Burst Balloons](problems/src/dynamic_programming/BurstBalloons.java) (Hard) +- [Largest Plus Sign](problems/src/dynamic_programming/LargestPlusSign.java) (Medium) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/LargestPlusSign.java b/problems/src/dynamic_programming/LargestPlusSign.java new file mode 100644 index 00000000..0a85f70d --- /dev/null +++ b/problems/src/dynamic_programming/LargestPlusSign.java @@ -0,0 +1,158 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 20/01/2018. + * In a 2D grid from (0, 0) to (N-1, N-1), every cell contains a 1, except those cells in the given list mines which + * are 0. What is the largest axis-aligned plus sign of 1s contained in the grid? Return the order of the plus sign. + * If there is none, return 0. + + An "axis-aligned plus sign of 1s of order k" has some center grid[x][y] = 1 along with 4 arms of length k-1 going + up, down, left, and right, and made of 1s. This is demonstrated in the diagrams below. Note that there could be 0s + or 1s beyond the arms of the plus sign, only the relevant area of the plus sign is checked for 1s. + + Examples of Axis-Aligned Plus Signs of Order k: + + Order 1: + 000 + 010 + 000 + + Order 2: + 00000 + 00100 + 01110 + 00100 + 00000 + + Order 3: + 0000000 + 0001000 + 0001000 + 0111110 + 0001000 + 0001000 + 0000000 + Example 1: + + Input: N = 5, mines = [[4, 2]] + Output: 2 + Explanation: + 11111 + 11111 + 11111 + 11111 + 11011 + In the above grid, the largest plus sign can only be order 2. One of them is marked in bold. + Example 2: + + Input: N = 2, mines = [] + Output: 1 + Explanation: + There is no plus sign of order 2, but there is of order 1. + Example 3: + + Input: N = 1, mines = [[0, 0]] + Output: 0 + Explanation: + There is no plus sign, so return 0. + Note: + + N will be an integer in the range [1, 500]. + mines will have length at most 5000. + mines[i] will be length 2 and consist of integers in the range [0, N-1]. + (Additionally, programs submitted in C, C++, or C# will be judged with a slightly smaller time limit.) + + Solution O(N x N) for each cell containing 1 find the nearest cell containing 0 in both vertical and horizontal + direction - save this value in a 2d array for each cell. The answer is max value saved in 2d array. + */ +public class LargestPlusSign { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[][] M = {{4, 2}}; + System.out.println(new LargestPlusSign().orderOfLargestPlusSign(5, M)); + } + + public int orderOfLargestPlusSign(int N, int[][] mines) { + int[][] A = new int[N][N]; //array to save the mines information. + int[][] B = new int[N][N]; //array to save the minimum distance to the cell containing 0 + for(int[] row : mines){ + int r = row[0]; + int c = row[1]; + A[r][c] = 1; + } + for(int i = 0; i < A.length; i ++){ + for(int j = 0; j < A[0].length; j++){ + if(A[i][j] == 0){ + A[i][j] = 1; + } else{ + A[i][j] = 0; + } + B[i][j] = Integer.MAX_VALUE; + } + } + //For each rwo + for(int i = 0; i < A.length; i ++){ + int prev = 0; + //forward direction + for(int j = 0; j < A[0].length; j ++){ + if(A[i][j] == 0){ + prev = 0; + B[i][j] = 0; + } else{ + prev++; + B[i][j] = Math.min(B[i][j], prev); + } + } + prev = 0; + //backward direction + for(int j = N - 1; j >= 0; j --){ + if(A[i][j] == 0){ + prev = 0; + B[i][j] = 0; + } else{ + prev++; + B[i][j] = Math.min(B[i][j], prev); + } + } + } + + //for each column + for(int j = 0; j < B[0].length; j ++){ + int prev = 0; + //downward direction + for(int i = 0; i < B.length; i ++){ + if(A[i][j] == 0){ + prev = 0; + B[i][j] = 0; + } else{ + prev++; + B[i][j] = Math.min(B[i][j], prev); + } + } + prev = 0; + //upward direction + for(int i = N - 1; i >= 0; i --){ + if(A[i][j] == 0){ + prev = 0; + B[i][j] = 0; + } else{ + prev++; + B[i][j] = Math.min(B[i][j], prev); + } + } + } + + int result = 0; + for(int i = 0; i < B.length; i++){ + for(int j = 0; j < B[0].length; j++){ + result = Math.max(result, B[i][j]); + } + } + return result; + } +} From d3f502b5d9d78a31dd6d1374268c6fb68e2ea6ef Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 20 Jan 2018 22:05:41 +0100 Subject: [PATCH 144/235] Remove Duplicates from Sorted Array II : Accepted --- README.md | 2 + .../src/two_pointers/RemoveDuplicatesII.java | 44 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 problems/src/two_pointers/RemoveDuplicatesII.java diff --git a/README.md b/README.md index e712649f..c0c5bfb5 100644 --- a/README.md +++ b/README.md @@ -277,5 +277,7 @@ My accepted leetcode solutions to some of the common interview problems. - [3Sum Closest](problems/src/two_pointers/ThreeSumClosest.java) (Medium) - [Move Zeroes](problems/src/two_pointers/MoveZeroes.java) (Easy) - [Remove Duplicates](problems/src/two_pointers/RemoveDuplicates.java) (Easy) +- [Remove Duplicates II](problems/src/two_pointers/RemoveDuplicatesII.java) (Medium) - [Minimum Size Subarray Sum](problems/src/two_pointers/MinimumSizeSubarraySum.java) (Medium) - [Minimum Window Substring](problems/src/two_pointers/MinimumWindowSubstring.java) (Hard) + diff --git a/problems/src/two_pointers/RemoveDuplicatesII.java b/problems/src/two_pointers/RemoveDuplicatesII.java new file mode 100644 index 00000000..10c59f98 --- /dev/null +++ b/problems/src/two_pointers/RemoveDuplicatesII.java @@ -0,0 +1,44 @@ +package two_pointers; + +/** + * Created by gouthamvidyapradhan on 20/01/2018. + * Follow up for "Remove Duplicates": + What if duplicates are allowed at most twice? + + For example, + Given sorted array nums = [1,1,1,2,2,3], + + Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 and 3. It doesn't + matter what you leave beyond the new length. + */ +public class RemoveDuplicatesII { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1, 1, 1, 2, 2, 2, 3, 4, 4}; + System.out.println(new RemoveDuplicatesII().removeDuplicates(A)); + } + + public int removeDuplicates(int[] nums) { + if(nums.length == 0) return 0; + int j = 0; + int count = 1; + for(int i = 1; i < nums.length; i++){ + if(nums[i - 1] == nums[i]){ + count ++; + } else{ + count = 1; + } + if(count == 1 || count == 2){ + j++; + nums[j] = nums[i]; + } + } + return j + 1; + } + +} From 55de61a626d0808a8176421a843bfc193e7a2489 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 21 Jan 2018 22:04:17 +0100 Subject: [PATCH 145/235] Wildcard Matching : Accepted --- README.md | 1 + .../src/backtracking/WildcardMatching.java | 71 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 problems/src/backtracking/WildcardMatching.java diff --git a/README.md b/README.md index c0c5bfb5..27f9d38f 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Remove Invalid Parentheses](problems/src/backtracking/RemoveInvalidParentheses.java) (Medium) - [Regular Expression Matching](problems/src/backtracking/RegularExpressionMatching.java) (Hard) - [Expression Add Operators](problems/src/backtracking/ExpressionAddOperators.java) (Hard) +- [Wildcard Matching](problems/src/backtracking/WildcardMatching.java) (Hard) #### [Binary Search](problems/src/binary_search) diff --git a/problems/src/backtracking/WildcardMatching.java b/problems/src/backtracking/WildcardMatching.java new file mode 100644 index 00000000..939d7bf8 --- /dev/null +++ b/problems/src/backtracking/WildcardMatching.java @@ -0,0 +1,71 @@ +package backtracking; + +/** + * Created by gouthamvidyapradhan on 21/01/2018. + * Implement wildcard pattern matching with support for '?' and '*'. + + '?' Matches any single character. + '*' Matches any sequence of characters (including the empty sequence). + + The matching should cover the entire input string (not partial). + + The function prototype should be: + bool isMatch(const char *s, const char *p) + + Some examples: + isMatch("aa","a") → false + isMatch("aa","aa") → true + isMatch("aaa","aa") → false + isMatch("aa", "*") → true + isMatch("aa", "a*") → true + isMatch("ab", "?*") → true + isMatch("aab", "c*a*b") → false + + Solution: Maintain two indexes one for string and other one for the pattern. + 1. If the characters match in both the indexes or if the char at pattern is '?' then increment both the indexes. + 2. If a star(*) is encountered save the position of star in the given string as 'startPosAtStr' and position of star in + the pattern as 'starIdx' and this time increment only index for pattern. + 3. If the characters do not match and if the start is not encountered previously return false else increment + 'startPosAtStr' and assign this as the new index for string and start the new pattern index from starIdx + 1 + */ +public class WildcardMatching { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new WildcardMatching().isMatch("abebd", "?be******e")); + } + + public boolean isMatch(String s, String p) { + int starIdx = -1; + int starPosAtStr = -1; + int j = 0; + for(int i = 0, l = s.length(); i < l;){ + if(j < p.length()){ + if(s.charAt(i) == p.charAt(j) || p.charAt(j) == '?'){ + i++; j++; + } else if(p.charAt(j) == '*'){ + starIdx = j; + starPosAtStr = i; + j++; //increment only pattern index. This is because '*' can match also empty string. + } else if(starIdx != -1){ + i = ++starPosAtStr; + j = starIdx + 1; + } else return false; + } else if(starIdx != -1){ + i = ++starPosAtStr; + j = starIdx + 1; + } else return false; + } + //check if the remaining characters in pattern contains only '*' + while(j < p.length()){ + if(p.charAt(j) == '*'){ + j++; + } else break; + } + return j == p.length(); + } +} From cc925811d986e97a5e442e1374046aedfdb54f70 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 23 Jan 2018 01:53:35 +0100 Subject: [PATCH 146/235] Smallest Range : Accepted --- README.md | 1 + problems/src/two_pointers/SmallestRange.java | 86 ++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 problems/src/two_pointers/SmallestRange.java diff --git a/README.md b/README.md index 27f9d38f..c73242de 100644 --- a/README.md +++ b/README.md @@ -281,4 +281,5 @@ My accepted leetcode solutions to some of the common interview problems. - [Remove Duplicates II](problems/src/two_pointers/RemoveDuplicatesII.java) (Medium) - [Minimum Size Subarray Sum](problems/src/two_pointers/MinimumSizeSubarraySum.java) (Medium) - [Minimum Window Substring](problems/src/two_pointers/MinimumWindowSubstring.java) (Hard) +- [Smallest Range](problems/src/two_pointers/SmallestRange.java) (Hard) diff --git a/problems/src/two_pointers/SmallestRange.java b/problems/src/two_pointers/SmallestRange.java new file mode 100644 index 00000000..f0d66392 --- /dev/null +++ b/problems/src/two_pointers/SmallestRange.java @@ -0,0 +1,86 @@ +package two_pointers; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.PriorityQueue; + +/** + * Created by gouthamvidyapradhan on 23/01/2018. + * You have k lists of sorted integers in ascending order. Find the smallest range that includes at least one number + * from each of the k lists. + + We define the range [a,b] is smaller than range [c,d] if b-a < d-c or a < c if b-a == d-c. + + Example 1: + Input:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]] + Output: [20,24] + Explanation: + List 1: [4, 10, 15, 24,26], 24 is in range [20,24]. + List 2: [0, 9, 12, 20], 20 is in range [20,24]. + List 3: [5, 18, 22, 30], 22 is in range [20,24]. + Note: + The given list may contain duplicates, so ascending order means >= here. + 1 <= k <= 3500 + -105 <= value of elements <= 105. + For Java users, please note that the input type has been changed to List>. And after you reset the + code template, you'll see this point. + + Solution O(n log m) where m is the total number of lists and n in the total elements in all the list combined. + + */ +public class SmallestRange { + + class MinIndex{ + int i, j; + MinIndex(int i, int j){ + this.i = i; + this.j = j; + } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + List> list = new ArrayList<>(); + List row1 = Arrays.asList(4,10,15,24,26); + List row2 = Arrays.asList(0,9,12,20); + List row3 = Arrays.asList(5,18,22,30); + list.add(row1); + list.add(row2); + list.add(row3); + int[] R = new SmallestRange().smallestRange(list); + System.out.println(R[0] + " " + R[1]); + } + + public int[] smallestRange(List> nums) { + PriorityQueue pq = new PriorityQueue<>((o1, o2) -> + Integer.compare(nums.get(o1.i).get(o1.j), nums.get(o2.i).get(o2.j))); + int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE; + for(int i = 0, l = nums.size(); i < l; i ++){ + min = Math.min(min, nums.get(i).get(0)); + max = Math.max(max, nums.get(i).get(0)); + pq.offer(new MinIndex(i, 0)); + } + if(min == max) return new int[]{min, max}; + int ansMin = min, ansMax = max; + while(true){ + MinIndex minIndex = pq.poll(); + if(minIndex.j + 1 >= nums.get(minIndex.i).size()){ + return new int[]{ansMin, ansMax}; + } + int next = nums.get(minIndex.i).get(minIndex.j + 1); + max = Math.max(max, next); //update max if any + pq.offer(new MinIndex(minIndex.i, minIndex.j + 1)); + min = nums.get(pq.peek().i).get(pq.peek().j); //new minimum + if((max - min) < (ansMax - ansMin)){ + ansMax = max; + ansMin = min; + } + } + } + +} From 23c5486a98ff820f6a6dcc7456756f646764d92f Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 23 Jan 2018 23:39:14 +0100 Subject: [PATCH 147/235] Convert Binary Search Tree to Sorted Doubly Linked List : Accepted --- README.md | 1 + problems/src/tree/BSTtoDoublyLinkedList.java | 57 ++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 problems/src/tree/BSTtoDoublyLinkedList.java diff --git a/README.md b/README.md index c73242de..09c5870b 100644 --- a/README.md +++ b/README.md @@ -268,6 +268,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Sum of Left Leaves](problems/src/tree/SumofLeftLeaves.java) (Easy) - [Two Sum IV - Input is a BST](problems/src/tree/TwoSumIV.java) (Easy) - [Average of Levels in Binary Tree](problems/src/tree/AverageOfLevelsInBinaryTree.java) (Easy) +- [Convert Binary Search Tree to Sorted Doubly Linked List](problems/src/tree/BSTtoDoublyLinkedList.java) (Easy) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/BSTtoDoublyLinkedList.java b/problems/src/tree/BSTtoDoublyLinkedList.java new file mode 100644 index 00000000..9cfbe71e --- /dev/null +++ b/problems/src/tree/BSTtoDoublyLinkedList.java @@ -0,0 +1,57 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 23/01/2018. + * Convert a BST to a sorted circular doubly-linked list in-place. Think of the left and right pointers as synonymous + * to the previous and next pointers in a doubly-linked list. + * + * Solution: Do a preorder traversal, keep track of previous node at every step and construct the dd-linked list + * in-place. + */ +public class BSTtoDoublyLinkedList { + + static class Node { + public int val; + public Node left; + public Node right; + + public Node() {} + + public Node(int _val,Node _left,Node _right) { + val = _val; + left = _left; + right = _right; + } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + Node root = new Node(4, new Node(2, null, null), new Node(5, null, null)); + Node result = new BSTtoDoublyLinkedList().treeToDoublyList(root); + //print result + } + + public Node treeToDoublyList(Node root) { + if(root == null) return null; + Node head = new Node(); + Node last = preorder(root, head); + last.right = head.right; + head.right.left = last; + return head.right; + } + + Node preorder(Node node, Node prev){ + if(node == null) return prev; + else{ + Node left = preorder(node.left, prev); + left.right = node; + node.left = left; + return preorder(node.right, node); + } + } + +} From 1227586184039d9a0419b44268e4ca01ed37e710 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 24 Jan 2018 00:03:54 +0100 Subject: [PATCH 148/235] Same Tree : Accepted --- README.md | 1 + problems/src/tree/SameTree.java | 69 +++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 problems/src/tree/SameTree.java diff --git a/README.md b/README.md index 09c5870b..333c245e 100644 --- a/README.md +++ b/README.md @@ -269,6 +269,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Two Sum IV - Input is a BST](problems/src/tree/TwoSumIV.java) (Easy) - [Average of Levels in Binary Tree](problems/src/tree/AverageOfLevelsInBinaryTree.java) (Easy) - [Convert Binary Search Tree to Sorted Doubly Linked List](problems/src/tree/BSTtoDoublyLinkedList.java) (Easy) +- [Same Tree](problems/src/tree/SameTree.java) (Easy) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/SameTree.java b/problems/src/tree/SameTree.java new file mode 100644 index 00000000..9d1dfa98 --- /dev/null +++ b/problems/src/tree/SameTree.java @@ -0,0 +1,69 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 23/01/2018. + * 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. + + + Example 1: + + Input: 1 1 + / \ / \ + 2 3 2 3 + + [1,2,3], [1,2,3] + + Output: true + Example 2: + + Input: 1 1 + / \ + 2 2 + + [1,2], [1,null,2] + + Output: false + Example 3: + + Input: 1 1 + / \ / \ + 2 1 1 2 + + [1,2,1], [1,1,2] + + Output: false + + Solution: Do a pre-order traversal of both the trees in parallel and compare each node + */ +public class SameTree { + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + + } + + public boolean isSameTree(TreeNode p, TreeNode q) { + if((p == null && q != null) || (p != null && q == null)) return false; + if(p == null && q == null) return true; + else{ + boolean status = isSameTree(p.left, q.left); + if(!status || p.val != q.val){ + return false; + } + return isSameTree(p.right, q.right); + } + } +} From d1ceab124ff45fa21af5ddfe0efa1d7df6cc72e9 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 25 Jan 2018 22:53:50 +0100 Subject: [PATCH 149/235] Palindrome Pairs : Accepted --- README.md | 1 + .../dynamic_programming/PalindromePairs.java | 163 ++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 problems/src/dynamic_programming/PalindromePairs.java diff --git a/README.md b/README.md index 333c245e..978874b5 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Number Of Corner Rectangles](problems/src/dynamic_programming/CornerRectangles.java) (Medium) - [Burst Balloons](problems/src/dynamic_programming/BurstBalloons.java) (Hard) - [Largest Plus Sign](problems/src/dynamic_programming/LargestPlusSign.java) (Medium) +- [Palindrome Pairs](problems/src/dynamic_programming/PalindromePairs.java) (Hard) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/PalindromePairs.java b/problems/src/dynamic_programming/PalindromePairs.java new file mode 100644 index 00000000..8c5a04d7 --- /dev/null +++ b/problems/src/dynamic_programming/PalindromePairs.java @@ -0,0 +1,163 @@ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 25/01/2018. + * Given a list of unique words, find all pairs of distinct indices (i, j) in the given list, so that the + * concatenation of the two words, i.e. words[i] + words[j] is a palindrome. + + Example 1: + Given words = ["bat", "tab", "cat"] + Return [[0, 1], [1, 0]] + The palindromes are ["battab", "tabbat"] + Example 2: + Given words = ["abcd", "dcba", "lls", "s", "sssll"] + Return [[0, 1], [1, 0], [3, 2], [2, 4]] + The palindromes are ["dcbaabcd", "abcddcba", "slls", "llssssll"] + + Solution O(n x m ^ 2) where m is the average length of each string and n is the number of strings. + + */ +public class PalindromePairs { + + public class Trie { + + private Map map; + private int index; + + /** + * Initialize your data structure here. + */ + public Trie() { + map = new HashMap<>(); + } + + /** + * Inserts a word into the trie. + */ + public void insert(String word, int pos) { + if (word != null) { + add(0, word, word.length(), pos); + } + } + + private void add(int i, String word, int length, int pos) { + if (i < length) { + char c = word.charAt(i); + Trie subTrie = map.get(c); + if (subTrie == null) { + subTrie = new Trie(); + map.put(c, subTrie); + } + subTrie.add(i + 1, word, length, pos); + } else { + Trie t = new Trie(); + t.index = pos; + map.put(null, t); //use null to indicate end of string + } + } + + public Trie getSubTrie(Character c){ + return this.map.get(c); + } + + public int getIndex() { + return index; + } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + String[] words = {"", "aa"}; + List> result = new PalindromePairs().palindromePairs(words); + result.stream().map(x -> (x.get(0) + " " + x.get(1))).forEach(System.out::println); + } + + public List> palindromePairs(String[] words) { + Trie forwardTrie = new Trie(); //maintain a forward and backward trie + Trie backwardTrie = new Trie(); + Map> links = new HashMap<>(); //maintain links to avoid duplicates + for(int i = 0; i < words.length; i ++){ + forwardTrie.insert(words[i], i); + backwardTrie.insert(new StringBuilder(words[i]).reverse().toString(), i); + } + List> result = new ArrayList<>(); + for(int i = 0; i < words.length; i ++){ + String word = words[i]; + boolean[][] T = new boolean[word.length()][word.length()]; + for(int j = 0, l = word.length(); j < l; j++){ + T[j][j] = true; + int k = j + 1; + if(k < l){ + if(word.charAt(j) == word.charAt(k)){ + T[j][k] = true; + } + } + } + for(int m = 2, l = word.length(); m < l; m++){ + for(int j = 0, k = m; j < l && k < l; j++, k++){ + if(word.charAt(j) == word.charAt(k) && T[j + 1][k - 1]){ + T[j][k] = true; + } + } + } + Trie subTrie = backwardTrie; + if(subTrie.getSubTrie(null) != null && !word.isEmpty() && T[0][word.length() - 1]){ + Trie emptySubTrie = subTrie.getSubTrie(null); + result.add(Arrays.asList(i, emptySubTrie.getIndex())); + result.add(Arrays.asList(emptySubTrie.getIndex(), i)); + } + for(int j = 0, l = word.length(); j < l; j++){ + char c = word.charAt(j); + subTrie = subTrie.getSubTrie(c); + if(subTrie == null) break; + Trie indexNode = subTrie.getSubTrie(null); + if(indexNode != null){ + if((j == l - 1) || (T[j + 1][l - 1])){ + if(indexNode.getIndex() != i){ //ignore same index + Set linkedTo = links.get(i); + if(linkedTo == null) { + linkedTo = new HashSet<>(); + links.put(i, linkedTo); + } + if(!linkedTo.contains(indexNode.getIndex())){ + linkedTo.add(indexNode.getIndex()); + result.add(Arrays.asList(i, indexNode.getIndex())); + } + } + } + } + } + subTrie = forwardTrie; + for(int j = word.length() - 1; j >= 0; j--){ + char c = word.charAt(j); + subTrie = subTrie.getSubTrie(c); + if(subTrie == null) break; + Trie indexNode = subTrie.getSubTrie(null); + if(indexNode != null){ + if((j == 0) || (T[0][j - 1])){ + if(indexNode.getIndex() != i){ //ignore same index + Set linkedTo = links.get(indexNode.getIndex()); + if(linkedTo == null) { + linkedTo = new HashSet<>(); + links.put(indexNode.getIndex(), linkedTo); + } + if(!linkedTo.contains(i)){ + linkedTo.add(i); + result.add(Arrays.asList(indexNode.getIndex(), i)); + } + } + } + } + } + + } + return result; + } + +} From 9d7fbf72c8cffb76216cca38a18393fdbdbb06bf Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 27 Jan 2018 14:29:56 +0100 Subject: [PATCH 150/235] Remove Invalid Parentheses: Accepted --- .../RemoveInvalidParentheses.java | 92 ++++++++++--------- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/problems/src/backtracking/RemoveInvalidParentheses.java b/problems/src/backtracking/RemoveInvalidParentheses.java index b71df8ab..0feac7ed 100644 --- a/problems/src/backtracking/RemoveInvalidParentheses.java +++ b/problems/src/backtracking/RemoveInvalidParentheses.java @@ -16,69 +16,71 @@ "(a)())()" -> ["(a)()()", "(a())()"] ")(" -> [""] - Solution: O(N x 2 ^ N) generate all combination of unique parentheses and return a list of valid parentheses which - has the string length maximum + Solution: O(N x 2 ^ N) backtrack and generate all combination of unique parentheses. Keep track of a counter which + keeps track of validity of parentheses. Prune the search space by checking for validity of parenthesis on the fly + by checking if the counter goes below 0 in which case a valid combination is impossible and also keep track + of selected count and total count of characters in each state to check if the difference between them is above the min + threshold. */ public class RemoveInvalidParentheses { + + private Set done; + private int maxLen = Integer.MIN_VALUE; + private int minDiff = Integer.MAX_VALUE; /** * Main method * @param args * @throws Exception */ public static void main(String[] args) throws Exception{ - List result = new RemoveInvalidParentheses().removeInvalidParentheses("()())()"); + List result = new RemoveInvalidParentheses().removeInvalidParentheses("())())"); result.forEach(System.out::println); } + public List removeInvalidParentheses(String s) { - Set set = new HashSet<>(); + done = new HashSet<>(); List result = new ArrayList<>(); - result.add(""); - //generate all combinations of unique parentheses - for(int i = s.length() - 1; i >= 0; i --){ - for(int j = 0, l = result.size(); j < l; j++){ - String curr = s.charAt(i) + result.get(j); - if(!set.contains(curr)){ - result.add(curr); - set.add(curr); + backTrack(s, 0, 0, result, "", 0, 0); + return result; + } + + private void backTrack(String s, int i, int count, List result, String state, int selected, int total){ + if(i >= s.length()){ + if(count == 0){ + if(selected >= maxLen){ + result.add(state); + maxLen = selected; + minDiff = total - selected; } } - } - //check for max length - int maxLen = 0; - for(String r : result){ - if(isValid(r)){ - maxLen = Math.max(maxLen, r.length()); - } - } - //prepare the final list - List finalR = new ArrayList<>(); - for(String r : result){ - if(isValid(r)) { - if(r.length() == maxLen){ - finalR.add(r); + } else{ + done.add(state); + char c = s.charAt(i); + if(c == '('){ + if(!done.contains(state + "(")){ + backTrack(s, i + 1, count + 1, result, state + "(", selected + 1, total + 1); } + if((total - selected + 1) <= minDiff){ + backTrack(s, i + 1, count, result, state, selected, total + 1); + } + } else if(c == ')'){ + if(count - 1 < 0){ + if((total - selected + 1) <= minDiff){ + backTrack(s, i + 1, count, result, state, selected, total + 1); + } + } else{ + if(!done.contains(state + ")")) { + backTrack(s, i + 1, count - 1, result, state + ")", selected + 1, total + 1); + } + if((total - selected + 1) <= minDiff){ + backTrack(s, i + 1, count, result, state, selected, total + 1); + } + } + } else { + backTrack(s, i + 1, count, result, state + c, selected + 1, total + 1); } } - return finalR; - } - - /** - * Check if the given string of parentheses is valid or not - * @param s String of parentheses - * @return true if valid - */ - private boolean isValid(String s){ - int count = 0; - for(int i = 0, l = s.length(); i < l; i ++){ - if(s.charAt(i) == '('){ - count ++; - } else if(s.charAt(i) == ')'){ - count --; - if(count < 0) return false; - } - } - return count == 0; } } From 0757fce83d1870e2da3caaa9fd1860c465939f95 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 28 Jan 2018 03:16:20 +0100 Subject: [PATCH 151/235] Cherry Pickup: Accepted --- README.md | 1 + .../src/dynamic_programming/CherryPickup.java | 82 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 problems/src/dynamic_programming/CherryPickup.java diff --git a/README.md b/README.md index 978874b5..8c423789 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Burst Balloons](problems/src/dynamic_programming/BurstBalloons.java) (Hard) - [Largest Plus Sign](problems/src/dynamic_programming/LargestPlusSign.java) (Medium) - [Palindrome Pairs](problems/src/dynamic_programming/PalindromePairs.java) (Hard) +- [Cherry Pickup](problems/src/dynamic_programming/CherryPickup.java) (Hard) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/CherryPickup.java b/problems/src/dynamic_programming/CherryPickup.java new file mode 100644 index 00000000..15a65b70 --- /dev/null +++ b/problems/src/dynamic_programming/CherryPickup.java @@ -0,0 +1,82 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 27/01/2018. + * In a N x N grid representing a field of cherries, each cell is one of three possible integers. + + 0 means the cell is empty, so you can pass through; + 1 means the cell contains a cherry, that you can pick up and pass through; + -1 means the cell contains a thorn that blocks your way. + Your task is to collect maximum number of cherries possible by following the rules below: + + Starting at the position (0, 0) and reaching (N-1, N-1) by moving right or down through valid path cells (cells + with value 0 or 1); + After reaching (N-1, N-1), returning to (0, 0) by moving left or up through valid path cells; + When passing through a path cell containing a cherry, you pick it up and the cell becomes an empty cell (0); + If there is no valid path between (0, 0) and (N-1, N-1), then no cherries can be collected. + Example 1: + Input: grid = + [[0, 1, -1], + [1, 0, -1], + [1, 1, 1]] + Output: 5 + Explanation: + The player started at (0, 0) and went down, down, right right to reach (2, 2). + 4 cherries were picked up during this single trip, and the matrix becomes [[0,1,-1],[0,0,-1],[0,0,0]]. + Then, the player went left, up, up, left to return home, picking up one more cherry. + The total number of cherries picked up is 5, and this is the maximum possible. + Note: + + grid is an N by N 2D array, with 1 <= N <= 50. + Each grid[i][j] is an integer in the set {-1, 0, 1}. + It is guaranteed that grid[0][0] and grid[N-1][N-1] are not -1. + + Solution O(N ^ 3) time-complexity. Traversing from (0, 0) -> (n - 1, n - 1) or the other way around both are the same. + The key point to note here is the traversal should be done by two person simultaneously starting from (0, 0). + Notice after t steps, each position (r, c) we could be, is on the line r + c = t (along the diagonal). So if we have + two people at positions (r1, c1) and (r2, c2), then r2 = r1 + c1 - c2. + + */ +public class CherryPickup { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[][] A = {{0 ,1,-1},{1, 0,-1},{1,1,1}}; + System.out.println(new CherryPickup().cherryPickup(A)); + } + + public int cherryPickup(int[][] grid) { + int[][][] DP = new int[grid.length][grid.length][grid.length]; + for(int i = 0; i < grid.length; i ++){ + for(int j = 0; j < grid.length; j ++){ + Arrays.fill(DP[i][j], -1); + } + } + int result = dp(grid.length, 0, 0, 0, DP, grid); + if(result < 0) return 0; + else return result; + } + + private int dp(int N, int r1, int c1, int c2, int[][][] DP, int[][] grid){ + int r2 = r1 + (c1 - c2); + if(r1 >= N || c1 >= N || c2 >= N || r2 >= N || grid[r1][c1] == -1 || grid[r2][c2] == -1) return Integer.MIN_VALUE; + else if(DP[r1][c1][c2] != -1) return DP[r1][c1][c2]; + else if(r1 == N - 1 && c1 == N - 1) return grid[N - 1][N - 1]; + else{ + int max = (c1 == c2) ? grid[r1][c1] : (grid[r1][c1] + grid[r2][c2]); + //verify all the 4 possibilities. (P1 down + P2 right), (P1 right, P2 right), (P1 right + P2 down), + // (P1 down, P2 down) + max += Math.max(Math.max(Math.max(dp(N, r1 + 1, c1, c2, DP, grid), dp(N, r1 + 1, c1, c2 + 1, DP, grid)), dp(N, + r1, c1 + 1, c2, DP, grid)), dp(N, r1, c1 + 1, c2 + 1, DP, grid)); + DP[r1][c1][c2] = max; + return max; + } + } + +} From 2391e9fc49c2fc7377cf1510a905fd8f08c2a6b2 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 1 Feb 2018 00:21:17 +0100 Subject: [PATCH 152/235] Global and Local Inversions : Accepted --- README.md | 1 + .../src/math/GlobalAndLocalInversions.java | 54 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 problems/src/math/GlobalAndLocalInversions.java diff --git a/README.md b/README.md index 8c423789..0edfcc83 100644 --- a/README.md +++ b/README.md @@ -203,6 +203,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Excel Sheet Column Title](problems/src/math/ExcelSheetColumnTitle.java) (Easy) - [Roman to Integer](problems/src/math/RomanToInteger.java) (Easy) - [Bulb Switcher II](problems/src/math/BulbSwitcherII.java) (Medium) +- [Global and Local Inversions](problems/src/math/GlobalAndLocalInversions.java) (Medium) #### [Reservoir Sampling](problems/src/reservoir_sampling) diff --git a/problems/src/math/GlobalAndLocalInversions.java b/problems/src/math/GlobalAndLocalInversions.java new file mode 100644 index 00000000..4da900af --- /dev/null +++ b/problems/src/math/GlobalAndLocalInversions.java @@ -0,0 +1,54 @@ +package math; + +/** + * Created by gouthamvidyapradhan on 01/02/2018. + * + * We have some permutation A of [0, 1, ..., N - 1], where N is the length of A. + + The number of (global) inversions is the number of i < j with 0 <= i < j < N and A[i] > A[j]. + + The number of local inversions is the number of i with 0 <= i < N and A[i] > A[i+1]. + + Return true if and only if the number of global inversions is equal to the number of local inversions. + + Example 1: + + Input: A = [1,0,2] + Output: true + Explanation: There is 1 global inversion, and 1 local inversion. + Example 2: + + Input: A = [1,2,0] + Output: false + Explanation: There are 2 global inversions, and 1 local inversion. + Note: + + A will be a permutation of [0, 1, ..., A.length - 1]. + A will have length in range [1, 5000]. + The time limit for this problem has been reduced. + + Solution: O(N) For every i, Maintain a max value up until (i - 1). If the current element at i < max value return false + */ +public class GlobalAndLocalInversions { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + + } + + public boolean isIdealPermutation(int[] A) { + if(A.length == 0 || A.length == 1) return true; + int max = Integer.MIN_VALUE; + for(int i = 1; i < A.length; i ++) { + if(A[i] < max){ + return false; + } else{ + max = Math.max(max, A[i - 1]); + } + } + return true; + } +} From 99bdeedca86a72fadf97502a5562e7433428f044 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 1 Feb 2018 01:17:41 +0100 Subject: [PATCH 153/235] Update to readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0edfcc83..f6614c4f 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Word Search](problems/src/backtracking/WordSearch.java) (Medium) - [Word Search II](problems/src/backtracking/WordSearchII.java) (Hard) - [Generate Parentheses](problems/src/backtracking/GenerateParentheses.java) (Medium) -- [Remove Invalid Parentheses](problems/src/backtracking/RemoveInvalidParentheses.java) (Medium) +- [Remove Invalid Parentheses](problems/src/backtracking/RemoveInvalidParentheses.java) (Hard) - [Regular Expression Matching](problems/src/backtracking/RegularExpressionMatching.java) (Hard) - [Expression Add Operators](problems/src/backtracking/ExpressionAddOperators.java) (Hard) - [Wildcard Matching](problems/src/backtracking/WildcardMatching.java) (Hard) From be81d55ed8f92eb805c3a3209eae90756f9cbd43 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 1 Feb 2018 22:28:27 +0100 Subject: [PATCH 154/235] Multiply Strings : Accepted --- README.md | 1 + problems/src/string/MultiplyStrings.java | 72 ++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 problems/src/string/MultiplyStrings.java diff --git a/README.md b/README.md index f6614c4f..208f2b19 100644 --- a/README.md +++ b/README.md @@ -238,6 +238,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Valid Palindrome II](problems/src/string/ValidPalindromeII.java) (Easy) - [One Edit Distance](problems/src/string/OneEditDistance.java) (Medium) - [Count and Say](problems/src/string/CountAndSay.java) (Easy) +- [Multiply Strings](problems/src/string/MultiplyStrings.java) (Medium) #### [Tree](problems/src/tree) diff --git a/problems/src/string/MultiplyStrings.java b/problems/src/string/MultiplyStrings.java new file mode 100644 index 00000000..ac9b98f2 --- /dev/null +++ b/problems/src/string/MultiplyStrings.java @@ -0,0 +1,72 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 01/02/2018. + * Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2. + + Note: + + The length of both num1 and num2 is < 110. + Both num1 and num2 contains only digits 0-9. + Both num1 and num2 does not contain any leading zero. + You must not use any built-in BigInteger library or convert the inputs to integer directly. + + Solution: O(N x M) where N and M are length of strings + */ +public class MultiplyStrings { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new MultiplyStrings().multiply("00", "0000")); + } + + public String multiply(String num1, String num2) { + if((num1.length() == 1 && num1.equals("0")) || (num2.length() == 1 && num2.equals("0"))) return "0"; + if(num1.length() < num2.length()) return multiply(num2, num1); + String temp2 = "", trail = ""; + int carry = 0; + for(int i = 0; i < num1.length(); i ++){ + temp2 += "0"; + } + for(int i = num1.length() - 1; i >= 0; i --){ + String temp1 = ""; + for(int j = num2.length() - 1; j >= 0; j --){ + int prod = Integer.parseInt(String.valueOf(num2.charAt(j))) * + Integer.parseInt(String.valueOf(num1.charAt(i))); + prod += carry; + temp1 = (prod % 10) + temp1; + carry = (prod / 10); + } + if(carry > 0){ + temp1 = String.valueOf(carry) + temp1; + carry = 0; + } + String temp3 = add(temp1, temp2); + temp2 = temp3.substring(0, temp3.length() - 1); + trail = temp3.substring(temp3.length() - 1, temp3.length()) + trail; + } + return temp2 + trail; + } + + private String add(String s1, String s2){ + String result = ""; + int carry = 0; + int i = s1.length() - 1, j = s2.length() - 1; + for(; i >= 0 || j >= 0; i --, j--){ + int l = (i >= 0) ? Integer.parseInt(String.valueOf(s1.charAt(i))) : 0; + int r = (j >= 0) ? Integer.parseInt(String.valueOf(s2.charAt(j))) : 0; + int sum = l + r + carry; + carry = sum / 10; + result = sum % 10 + result; + } + if(carry > 0){ + result = carry + result; + } + return result; + } + +} From d03f20fec3c8596d0e2df2153effec43752aedd4 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 7 Feb 2018 02:51:22 +0100 Subject: [PATCH 155/235] BasicCalculator and PourWater: Accepted --- README.md | 2 + problems/src/array/PourWater.java | 169 ++++++++++++++++++++++++ problems/src/stack/BasicCalculator.java | 85 ++++++++++++ 3 files changed, 256 insertions(+) create mode 100644 problems/src/array/PourWater.java create mode 100644 problems/src/stack/BasicCalculator.java diff --git a/README.md b/README.md index 208f2b19..a8df2a80 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Increasing Triplet Subsequence](problems/src/array/IncreasingTripletSubsequence.java) (Medium) - [K Empty Slots](problems/src/array/KEmptySlots.java) (Hard) - [Subarray Sum Equals K](problems/src/array/SubarraySumEqualsK.java) (Medium) +- [Pour Water](problems/src/array/PourWater.java) (Medium) #### [Backtracking](problems/src/backtracking) @@ -217,6 +218,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Implement Queue using Stacks](problems/src/stack/MyQueue.java) (Easy) - [Maximal Rectangle](problems/src/stack/MaximalRectangle.java) (Hard) - [Exclusive Time of Functions](problems/src/stack/ExclusiveTimeOfFunctions.java) (Medium) +- [Basic Calculator](problems/src/stack/BasicCalculator.java) (Hard) #### [String](problems/src/string) diff --git a/problems/src/array/PourWater.java b/problems/src/array/PourWater.java new file mode 100644 index 00000000..e9e53488 --- /dev/null +++ b/problems/src/array/PourWater.java @@ -0,0 +1,169 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 03/02/2018. + * We are given an elevation map, heights[i] representing the height of the terrain at that index. The width at each + * index is 1. After V units of water fall at index K, how much water is at each index? + + Water first drops at index K and rests on top of the highest terrain or water at that index. Then, it flows + according to the following rules: + + If the droplet would eventually fall by moving left, then move left. + Otherwise, if the droplet would eventually fall by moving right, then move right. + Otherwise, rise at it's current position. + Here, "eventually fall" means that the droplet will eventually be at a lower level if it moves in that direction. + Also, "level" means the height of the terrain plus any water in that column. + We can assume there's infinitely high terrain on the two sides out of bounds of the array. Also, there could not be + partial water being spread out evenly on more than 1 grid block - each unit of water has to be in exactly one block. + + Example 1: + Input: heights = [2,1,1,2,1,2,2], V = 4, K = 3 + Output: [2,2,2,3,2,2,2] + Explanation: + # # + # # + ## # ### + ######### + 0123456 <- index + + The first drop of water lands at index K = 3: + + # # + # w # + ## # ### + ######### + 0123456 + + When moving left or right, the water can only move to the same level or a lower level. + (By level, we mean the total height of the terrain plus any water in that column.) + Since moving left will eventually make it fall, it moves left. + (A droplet "made to fall" means go to a lower height than it was at previously.) + + # # + # # + ## w# ### + ######### + 0123456 + + Since moving left will not make it fall, it stays in place. The next droplet falls: + + # # + # w # + ## w# ### + ######### + 0123456 + + Since the new droplet moving left will eventually make it fall, it moves left. + Notice that the droplet still preferred to move left, + even though it could move right (and moving right makes it fall quicker.) + + # # + # w # + ## w# ### + ######### + 0123456 + + # # + # # + ##ww# ### + ######### + 0123456 + + After those steps, the third droplet falls. + Since moving left would not eventually make it fall, it tries to move right. + Since moving right would eventually make it fall, it moves right. + + # # + # w # + ##ww# ### + ######### + 0123456 + + # # + # # + ##ww#w### + ######### + 0123456 + + Finally, the fourth droplet falls. + Since moving left would not eventually make it fall, it tries to move right. + Since moving right would not eventually make it fall, it stays in place: + + # # + # w # + ##ww#w### + ######### + 0123456 + + The final answer is [2,2,2,3,2,2,2]: + + # + ####### + ####### + 0123456 + Example 2: + Input: heights = [1,2,3,4], V = 2, K = 2 + Output: [2,3,3,4] + Explanation: + The last droplet settles at index 1, since moving further left would not cause it to eventually fall to a lower + height. + Example 3: + Input: heights = [3,1,3], V = 5, K = 1 + Output: [4,4,4] + Note: + + heights will have length in [1, 100] and contain integers in [0, 99]. + V will be in range [0, 2000]. + K will be in range [0, heights.length - 1]. + + Solution: + Check first left and then right to see if there are any lower levels, if yes then drop the water at this point. Else + maintain the drop at the start position + */ +public class PourWater { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {2, 1, 1, 2, 1, 2, 2}; + int[] result = new PourWater().pourWater(A, 4, 3); + for(int i : result){ + System.out.print(i + " "); + } + } + + public int[] pourWater(int[] heights, int V, int K) { + while(V-- > 0){ + heights[K] += 1; + int index = K; + int min = heights[K]; + for(int i = K - 1; i >= 0; i--){ + if(heights[i] + 1 > min){ + break; + } else if(heights[i] + 1 < min){ + min = heights[i] + 1; + index = i; + } + } + if(index == K){ + for(int i = K + 1; i < heights.length; i++){ + if(heights[i] + 1 > min){ + break; + } else if(heights[i] + 1 < min){ + min = heights[i] + 1; + index = i; + } + } + } + if(index != K){ + heights[K]--; + heights[index]++; + } + } + return heights; + } + +} diff --git a/problems/src/stack/BasicCalculator.java b/problems/src/stack/BasicCalculator.java new file mode 100644 index 00000000..d5992129 --- /dev/null +++ b/problems/src/stack/BasicCalculator.java @@ -0,0 +1,85 @@ +package stack; + +import java.util.Stack; + +/** + * Created by gouthamvidyapradhan on 06/02/2018. + * Implement a basic calculator to evaluate a simple expression string. + + The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative + integers and empty spaces . + + You may assume that the given expression is always valid. + + Some examples: + "1 + 1" = 2 + " 2-1 + 2 " = 3 + "(1+(4+5+2)-3)+(6+8)" = 23 + Note: Do not use the eval built-in library function. + + Solution: O(n) where n is the length of the string. + Maintain a stack and push each character from the string (ignore space). As soon as a close parentheses ')' + is encountered, start to pop values and sum-up the total until '(' is poped. Push the total back to stack + and continue to iterate. The final result will be in the top of the stack which is the last + and only element in stack. + */ +public class BasicCalculator { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new BasicCalculator().calculate("2-1 + (2 - 3) - ((2 - (2 - (3 - (4 - 5)))))")); + } + + public int calculate(String s) { + Stack stack = new Stack<>(); + String num = ""; + s = "(" + s + ")"; + for(char c : s.toCharArray()){ + switch (c){ + case ' ': + case '(': + case '+': + case '-': + if(!num.equals("")){ + stack.push(String.valueOf(num)); + num = ""; + } + if(c != ' '){ //ignore blank + stack.push(String.valueOf(c)); + } + break; + case ')': + if(!num.equals("")){ + stack.push(String.valueOf(num)); + num = ""; + } + int sum = 0; + int prev = 0; //maintain a prev value inorder to handle minus '-' + while(!stack.isEmpty()){ + String top = stack.pop(); + if(top.equals("-")){ + sum -= (prev * 2); + prev = 0; + } else if(top.equals("+")){ + //ignore + } else if(top.equals("(")){ + stack.push(String.valueOf(sum)); + break; + } else{ + sum += Integer.parseInt(top); + prev = Integer.parseInt(top); + } + } + break; + default: + num += String.valueOf(c); + break; + } + } + return Integer.parseInt(stack.peek()); + } +} From c8822336a7bd1b78fbebb24ee210fca664489f27 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 10 Feb 2018 00:30:39 +0100 Subject: [PATCH 156/235] Accepted solutions --- README.md | 4 + .../src/array/LargestNumberAtLeastTwice.java | 59 +++++++++++ problems/src/array/NextGreaterElementI.java | 67 +++++++++++++ problems/src/array/RelativeRanks.java | 66 +++++++++++++ .../src/breadth_first_search/OpenTheLock.java | 99 +++++++++++++++++++ 5 files changed, 295 insertions(+) create mode 100644 problems/src/array/LargestNumberAtLeastTwice.java create mode 100644 problems/src/array/NextGreaterElementI.java create mode 100644 problems/src/array/RelativeRanks.java create mode 100644 problems/src/breadth_first_search/OpenTheLock.java diff --git a/README.md b/README.md index a8df2a80..c70a5183 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,9 @@ My accepted leetcode solutions to some of the common interview problems. - [K Empty Slots](problems/src/array/KEmptySlots.java) (Hard) - [Subarray Sum Equals K](problems/src/array/SubarraySumEqualsK.java) (Medium) - [Pour Water](problems/src/array/PourWater.java) (Medium) +- [Relative Ranks](problems/src/array/RelativeRanks.java) (Easy) +- [Next Greater Element I](problems/src/array/NextGreaterElementI.java) (Easy) +- [Largest Number At Least Twice of Others](problems/src/array/LargestNumberAtLeastTwice.java) (Easy) #### [Backtracking](problems/src/backtracking) @@ -77,6 +80,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Word Ladder](problems/src/breadth_first_search/WordLadder.java) (Medium) - [Word Ladder II](problems/src/breadth_first_search/WordLadderII.java) (Hard) - [Walls and Gates](problems/src/breadth_first_search/WallsAndGates.java) (Medium) +- [Open the lock](problems/src/breadth_first_search/OpenTheLock.java) (Medium) #### [Depth First Search](problems/src/depth_first_search) diff --git a/problems/src/array/LargestNumberAtLeastTwice.java b/problems/src/array/LargestNumberAtLeastTwice.java new file mode 100644 index 00000000..fdb7395d --- /dev/null +++ b/problems/src/array/LargestNumberAtLeastTwice.java @@ -0,0 +1,59 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 09/02/2018. + * In a given integer array nums, there is always exactly one largest element. + + Find whether the largest element in the array is at least twice as much as every other number in the array. + + If it is, return the index of the largest element, otherwise return -1. + + Example 1: + + Input: nums = [3, 6, 1, 0] + Output: 1 + Explanation: 6 is the largest integer, and for every other number in the array x, + 6 is more than twice as big as x. The index of value 6 is 1, so we return 1. + + + Example 2: + + Input: nums = [1, 2, 3, 4] + Output: -1 + Explanation: 4 isn't at least as big as twice the value of 3, so we return -1. + + + Note: + + nums will have a length in the range [1, 50]. + Every nums[i] will be an integer in the range [0, 99]. + */ +public class LargestNumberAtLeastTwice { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + + } + + public int dominantIndex(int[] nums) { + int index = 0, max = Integer.MIN_VALUE; + for(int i = 0; i < nums.length; i ++){ + if(nums[i] > max){ + max = nums[i]; + index = i; + } + } + for(int i = 0; i < nums.length; i ++){ + if(i == index) continue; + if(((long)nums[i] * 2) > max){ + return -1; + } + } + return index; + } + +} diff --git a/problems/src/array/NextGreaterElementI.java b/problems/src/array/NextGreaterElementI.java new file mode 100644 index 00000000..7c053d8b --- /dev/null +++ b/problems/src/array/NextGreaterElementI.java @@ -0,0 +1,67 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 09/02/2018. + * You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of nums2. + * Find all the next greater numbers for nums1's elements in the corresponding places of nums2. + + The Next Greater Number of a number x in nums1 is the first greater number to its right in nums2. + If it does not exist, output -1 for this number. + + Example 1: + 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. + Example 2: + Input: nums1 = [2,4], nums2 = [1,2,3,4]. + Output: [3,-1] + Explanation: + For number 2 in the first array, the next greater number for it in the second array is 3. + For number 4 in the first array, there is no next greater number for it in the second array, so output -1. + Note: + All elements in nums1 and nums2 are unique. + The length of both nums1 and nums2 would not exceed 1000. + */ +public class NextGreaterElementI { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {4,1,2}; + int[] B = {1,3,4,2}; + int[] result = new NextGreaterElementI().nextGreaterElement(A, B); + System.out.println(result); + } + + public int[] nextGreaterElement(int[] nums1, int[] nums2) { + int[] result = new int[nums1.length]; + for(int i = 0; i < nums1.length; i ++){ + int n = nums1[i]; + boolean found = false; + int nF = 0; + for(int j = 0; j < nums2.length; j ++){ + if(nums2[j] == n){ + found = true; + } if(found){ + if(nums2[j] > n){ + nF = nums2[j]; + break; + } + } + } + if(found){ + result[i] = nF; + } else{ + result[i] = -1; + } + } + return result; + } + +} diff --git a/problems/src/array/RelativeRanks.java b/problems/src/array/RelativeRanks.java new file mode 100644 index 00000000..43f41b59 --- /dev/null +++ b/problems/src/array/RelativeRanks.java @@ -0,0 +1,66 @@ +package array; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by gouthamvidyapradhan on 09/02/2018. + * Given scores of N athletes, find their relative ranks and the people with the top three highest scores, + * who will be awarded medals: "Gold Medal", "Silver Medal" and "Bronze Medal". + + Example 1: + Input: [5, 4, 3, 2, 1] + Output: ["Gold Medal", "Silver Medal", "Bronze Medal", "4", "5"] + Explanation: The first three athletes got the top three highest scores, so they got "Gold Medal", "Silver Medal" + and "Bronze Medal". + For the left two athletes, you just need to output their relative ranks according to their scores. + Note: + N is a positive integer and won't exceed 10,000. + All the scores of athletes are guaranteed to be unique. + */ +public class RelativeRanks { + + class Position{ + int score, poisition; + Position(int score, int position){ + this.score = score; + this.poisition = position; + } + } + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {5, 4, 3, 2, 1}; + String[] S = new RelativeRanks().findRelativeRanks(A); + for(String i : S){ + System.out.println(i); + } + } + + public String[] findRelativeRanks(int[] nums) { + String[] S = new String[nums.length]; + List list = new ArrayList<>(); + for(int i = 0; i < nums.length; i ++){ + list.add(new Position(nums[i], i)); + } + list.sort((o1, o2) -> Integer.compare(o2.score, o1.score)); + //Collections.reverse(list); + for(int i = 0; i < list.size(); i ++){ + if(i == 0){ + S[list.get(i).poisition] = "Gold Medal"; + } else if(i == 1){ + S[list.get(i).poisition] = "Silver Medal"; + } else if(i == 2){ + S[list.get(i).poisition] = "Bronze Medal"; + } + else { + S[list.get(i).poisition] = String.valueOf(i + 1); + } + } + return S; + } + +} diff --git a/problems/src/breadth_first_search/OpenTheLock.java b/problems/src/breadth_first_search/OpenTheLock.java new file mode 100644 index 00000000..a9f0c8e0 --- /dev/null +++ b/problems/src/breadth_first_search/OpenTheLock.java @@ -0,0 +1,99 @@ +package breadth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 09/02/2018. + * You have a lock in front of you with 4 circular wheels. Each wheel has 10 slots: '0', '1', '2', '3', '4', '5', + * '6', '7', '8', '9'. The wheels can rotate freely and wrap around: for example we can turn '9' to be '0', or '0' + * to be '9'. Each move consists of turning one wheel one slot. + + The lock initially starts at '0000', a string representing the state of the 4 wheels. + + You are given a list of deadends dead ends, meaning if the lock displays any of these codes, the wheels of the lock + will stop turning and you will be unable to open it. + + Given a target representing the value of the wheels that will unlock the lock, return the minimum total number of + turns required to open the lock, or -1 if it is impossible. + + Example 1: + Input: deadends = ["0201","0101","0102","1212","2002"], target = "0202" + Output: 6 + Explanation: + A sequence of valid moves would be "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "0202". + Note that a sequence like "0000" -> "0001" -> "0002" -> "0102" -> "0202" would be invalid, + because the wheels of the lock become stuck after the display becomes the dead end "0102". + Example 2: + Input: deadends = ["8888"], target = "0009" + Output: 1 + Explanation: + We can turn the last wheel in reverse to move from "0000" -> "0009". + Example 3: + Input: deadends = ["8887","8889","8878","8898","8788","8988","7888","9888"], target = "8888" + Output: -1 + Explanation: + We can't reach the target without getting stuck. + Example 4: + Input: deadends = ["0000"], target = "8888" + Output: -1 + Note: + The length of deadends will be in the range [1, 500]. + target will not be in the list deadends. + Every string in deadends and the string target will be a string of4 digits from the 10,000 possibilities '0000' to '9999'. + + Solution: Perform a bfs of each state starting from 0000 and return the minimum distance. + */ +public class OpenTheLock { + + class State{ + String state; + int dist; + State(String state, int dist){ + this.state = state; + this.dist = dist; + } + } + private Set done; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + String[] A = {"0201","0101","0102","1212","2002"}; + System.out.println(new OpenTheLock().openLock(A, "0202")); + } + + public int openLock(String[] deadends, String target) { + done = new HashSet<>(); + Arrays.stream(deadends).forEach(e -> done.add(e)); + if(done.contains("0000")) return -1; + if(target.equals("0000")) return 0; + Queue queue = new ArrayDeque<>(); + queue.offer(new State("0000", 0)); + done.add("0000"); + while(!queue.isEmpty()){ + State state = queue.poll(); + if(state.state.equals(target)) return state.dist; + String currState = state.state; + for(int i = 0; i < 4; i ++){ + char c = currState.charAt(i); + int cV = Integer.parseInt(String.valueOf(c)); + String prefix = currState.substring(0, i); + String postFix = currState.substring(i + 1, 4); + String newChild1 = prefix + (((cV + 1) > 9) ? 0 : (cV + 1)) + postFix; + if(!done.contains(newChild1)){ + queue.offer(new State(newChild1, state.dist + 1)); + done.add(newChild1); + } + String newChild2 = prefix + (((cV - 1) < 0) ? 9 : (cV - 1)) + postFix; + if(!done.contains(newChild2)){ + queue.offer(new State(newChild2, state.dist + 1)); + done.add(newChild2); + } + } + } + return -1; + } + +} From b6a84d9daf3255a00c924abac9cc6f1976a55d6d Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 13 Feb 2018 01:51:12 +0100 Subject: [PATCH 157/235] Accepted solutions --- README.md | 2 + .../KnightProbabilityInChessboard.java | 77 +++++++++++++ ...inaryTreeLongestConsecutiveSequenceII.java | 104 ++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 problems/src/dynamic_programming/KnightProbabilityInChessboard.java create mode 100644 problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java diff --git a/README.md b/README.md index c70a5183..0f28c1fe 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Largest Plus Sign](problems/src/dynamic_programming/LargestPlusSign.java) (Medium) - [Palindrome Pairs](problems/src/dynamic_programming/PalindromePairs.java) (Hard) - [Cherry Pickup](problems/src/dynamic_programming/CherryPickup.java) (Hard) +- [Knight Probability in Chessboard](problems/src/dynamic_programming/KnightProbabilityInChessboard.java) (Medium) #### [Greedy](problems/src/greedy) @@ -280,6 +281,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Average of Levels in Binary Tree](problems/src/tree/AverageOfLevelsInBinaryTree.java) (Easy) - [Convert Binary Search Tree to Sorted Doubly Linked List](problems/src/tree/BSTtoDoublyLinkedList.java) (Easy) - [Same Tree](problems/src/tree/SameTree.java) (Easy) +- [Binary Tree Longest Consecutive Sequence II](problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/dynamic_programming/KnightProbabilityInChessboard.java b/problems/src/dynamic_programming/KnightProbabilityInChessboard.java new file mode 100644 index 00000000..02b9319a --- /dev/null +++ b/problems/src/dynamic_programming/KnightProbabilityInChessboard.java @@ -0,0 +1,77 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 13/02/2018. + * On an NxN chessboard, a knight starts at the r-th row and c-th column and attempts to make exactly K moves. + * The rows and columns are 0 indexed, so the top-left square is (0, 0), and the bottom-right square is (N-1, N-1). + + A chess knight has 8 possible moves it can make, as illustrated below. Each move is two squares in a cardinal + direction, then one square in an orthogonal direction. + + + Each time the knight is to move, it chooses one of eight possible moves uniformly at random + (even if the piece would go off the chessboard) and moves there. + + The knight continues moving until it has made exactly K moves or has moved off the chessboard. + Return the probability that the knight remains on the board after it has stopped moving. + + Example: + Input: 3, 2, 0, 0 + Output: 0.0625 + Explanation: There are two moves (to (1,2), (2,1)) that will keep the knight on the board. + From each of those positions, there are also two moves that will keep the knight on the board. + The total probability the knight stays on the board is 0.0625. + Note: + N will be between 1 and 25. + K will be between 0 and 100. + The knight always initially starts on the board. + + Solution: Solution O(N ^ 2 x K) DP top down memoization for each different states. + */ +public class KnightProbabilityInChessboard { + + int[] R = {1, -1, 2, -2, -1, -2, 2, 1}; + int[] C = {2, 2, 1, 1, -2, -1, -1, -2}; + + double[][][] dp; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new KnightProbabilityInChessboard().knightProbability(3, 2, 0, 0)); + } + + public double knightProbability(int N, int K, int r, int c) { + dp = new double[N][N][K + 1]; + for(int i = 0; i < N; i ++){ + for(int j = 0; j < N; j ++){ + Arrays.fill(dp[i][j], -1.0D); + } + } + for(int i = 0; i < N; i ++){ + for(int j = 0; j < N; j ++){ + dp[i][j][0] = 1.0D; + } + } + return dp(dp, r, c, K, N); + } + + private double dp(double[][][] dp, int r, int c, int K, int N){ + if(r < 0 || r >= N || c < 0 || c >= N) return 0.0D; + if(dp[r][c][K] != -1.0D) return dp[r][c][K]; + double sum = 0.0D; + for(int i = 0; i < 8; i ++){ + int newR = r + R[i]; + int newC = c + C[i]; + if(newR >= 0 && newR < N && newC >= 0 && newC < N){ + sum += dp(dp, newR, newC, K - 1, N); + } + } + dp[r][c][K] = (sum / 8.0); + return dp[r][c][K]; + } +} diff --git a/problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java b/problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java new file mode 100644 index 00000000..3a50fad7 --- /dev/null +++ b/problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java @@ -0,0 +1,104 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 11/02/2018. + * Given a binary tree, you need to find the length of Longest Consecutive Path in Binary Tree. + + Especially, this path can be either increasing or decreasing. For example, [1,2,3,4] and [4,3,2,1] are both + considered valid, but the path [1,2,4,3] is not valid. On the other hand, the path can be in the child-Parent-child + order, where not necessarily be parent-child order. + + Example 1: + Input: + 1 + / \ + 2 3 + Output: 2 + Explanation: The longest consecutive path is [1, 2] or [2, 1]. + Example 2: + Input: + 2 + / \ + 1 3 + Output: 3 + Explanation: The longest consecutive path is [1, 2, 3] or [3, 2, 1]. + Note: All the values of tree nodes are in the range of [-1e7, 1e7]. + */ +public class BinaryTreeLongestConsecutiveSequenceII { + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + private class Node{ + int i, d; + int val; + Node(int i, int d, int val){ + this.i = i; + this.d = d; + this.val = val; + } + } + private int max = Integer.MIN_VALUE; + public static void main(String[] args) throws Exception{ + TreeNode root = new TreeNode(2); + root.left = new TreeNode(1); + //root.left.left = new TreeNode(4); + root.right = new TreeNode(3); + System.out.println(new BinaryTreeLongestConsecutiveSequenceII().longestConsecutive(root)); + } + + + public int longestConsecutive(TreeNode root) { + Node n = preorder(root); + if(n != null){ + max = Math.max(max, n.d); + max = Math.max(max, n.i); + if(n.i > 1 && n.d > 1){ + max = Math.max(max, n.d + n.i - 1); + } + } + if(max == Integer.MIN_VALUE) return 0; + return max; + } + + + private Node preorder(TreeNode node){ + if(node == null) return null; + Node left = preorder(node.left); + Node curr = new Node(1, 1, node.val); + if(left != null){ + max = Math.max(max, left.d); + max = Math.max(max, left.i); + if(left.val == node.val + 1){ + curr.d = left.d + 1; + curr.i = 1; + } else if(left.val == node.val - 1){ + curr.i = left.i + 1; + curr.d = 1; + } + } + Node right = preorder(node.right); + if(right != null){ + max = Math.max(max, right.d); + max = Math.max(max, right.i); + if(right.val == node.val + 1){ + if(right.d + 1 > curr.d){ + curr.d = right.d + 1; + } + } else if(right.val == node.val - 1){ + if(right.i + 1 > curr.i){ + curr.i = right.i + 1; + } + } + } + if(curr.i > 1 && curr.d > 1){ + max = Math.max(max, curr.d + curr.i - 1); + } + return curr; + } + +} From 7d36ff2a091fa66e5aabf03f53a79ecab6e3e2eb Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 14 Feb 2018 00:04:19 +0100 Subject: [PATCH 158/235] Accepted solutions --- README.md | 1 + .../bit_manipulation/DivideTwoIntegers.java | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 problems/src/bit_manipulation/DivideTwoIntegers.java diff --git a/README.md b/README.md index 0f28c1fe..33140741 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Gray Code](problems/src/bit_manipulation/GrayCode.java) (Medium) - [Hamming Distance](problems/src/bit_manipulation/HammingDistance.java) (Easy) - [Total Hamming Distance](problems/src/bit_manipulation/TotalHammingDistance.java) (Medium) +- [Divide Two Integers](problems/src/bit_manipulation/DivideTwoIntegers.java) (Medium) #### [Breadth First Search](problems/src/breadth_first_search) diff --git a/problems/src/bit_manipulation/DivideTwoIntegers.java b/problems/src/bit_manipulation/DivideTwoIntegers.java new file mode 100644 index 00000000..9e370897 --- /dev/null +++ b/problems/src/bit_manipulation/DivideTwoIntegers.java @@ -0,0 +1,43 @@ +package bit_manipulation; + +/** + * Created by gouthamvidyapradhan on 13/02/2018. + * Divide two integers without using multiplication, division and mod operator. + + If it is overflow, return MAX_INT. + */ +public class DivideTwoIntegers { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new DivideTwoIntegers().divide(0, 775)); + } + + public int divide(int dividend, int divisor) { + if(divisor == 0) return Integer.MAX_VALUE; + else if(dividend == Integer.MIN_VALUE && divisor == -1) return Integer.MAX_VALUE; + else if(divisor == 1) return dividend; + boolean isNegative = ((dividend < 0 && divisor > 0) || (dividend > 0 && divisor < 0)); + dividend = (dividend < 0)? -dividend : dividend; + divisor = (divisor < 0) ? -divisor : divisor; + int sum, result = 0; + while(true){ + int d1 = divisor; + sum = 0; + if(dividend - d1 == 0) {sum += 1; result += sum; break;} + if(dividend - d1 < 0) break; + while(dividend - (d1 << 1) > 0){ + d1 <<= 1; + sum += 1; + } + result += (1 << sum); + dividend = dividend - d1; + } + return isNegative ? -result : result; + } + +} From 3030ca135bb70743f4c64893ba2a79b2d43bc950 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 15 Feb 2018 00:29:15 +0100 Subject: [PATCH 159/235] Best Time to Buy and Sell Stock III: Accepted --- README.md | 4 +- .../BestTimeToBuyAndSellStockIII.java | 45 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java diff --git a/README.md b/README.md index 33140741..626ac432 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,8 @@ My accepted leetcode solutions to some of the common interview problems. #### [Dynamic Programming](problems/src/dynamic_programming) - [Best Time To Buy and Sell Stocks](problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java) (Easy) +- [Best Time to Buy and Sell Stock III](problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java) (Hard) +- [Best Time to Buy and Sell Stock with Transaction Fee](problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java) (Medium) - [Climbing Stairs](problems/src/dynamic_programming/ClimbingStairs.java) (Easy) - [Coin Change](problems/src/dynamic_programming/CoinChange.java) (Medium) - [Coin Change 2](problems/src/dynamic_programming/CoinChange2.java) (Medium) @@ -148,7 +150,6 @@ My accepted leetcode solutions to some of the common interview problems. - [Decode Ways II](problems/src/dynamic_programming/DecodeWaysII.java) (Hard) - [Palindromic Substrings](problems/src/dynamic_programming/PalindromicSubstrings.java) (Medium) - [Number of Longest Increasing Subsequence](problems/src/dynamic_programming/NumberOfLIS.java) (Medium) -- [Best Time to Buy and Sell Stock with Transaction Fee](problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java) (Medium) - [Combination Sum IV](problems/src/dynamic_programming/CombinationSumIV.java) (Medium) - [Paint House II](problems/src/dynamic_programming/PaintHouseII.java) (Hard) - [Split Array Largest Sum](problems/src/dynamic_programming/SplitArrayLargestSum.java) (Hard) @@ -159,6 +160,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Cherry Pickup](problems/src/dynamic_programming/CherryPickup.java) (Hard) - [Knight Probability in Chessboard](problems/src/dynamic_programming/KnightProbabilityInChessboard.java) (Medium) + #### [Greedy](problems/src/greedy) - [Jump Game](problems/src/greedy/JumpGame.java) (Medium) diff --git a/problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java b/problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java new file mode 100644 index 00000000..9b9c463f --- /dev/null +++ b/problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java @@ -0,0 +1,45 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 15/02/2018. + * Say you have an array for which the ith element is the price of a given stock on day i. + + Design an algorithm to find the maximum profit. You may complete at most two transactions. + + Note: + You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again). + +Solution: O(n): In the first iteration calculate the max profit that can be made by one buy and sell by iterating from + right to left and saving this in a dp array and maintaining a max value. + In the second iteration starting from left to right maintain a min value and calculate the max profit that can be + made by one buy and sell by taking the difference of current with min and calculate the total profit of two + transactions by summing up the current profit made with the profit in dp array. + */ +public class BestTimeToBuyAndSellStockIII { + + /** + * Main method + * @param args + */ + public static void main(String[] args) throws Exception{ + int[] A = {10, 9, 8, 7}; + System.out.println(new BestTimeToBuyAndSellStockIII().maxProfit(A)); + } + + public int maxProfit(int[] prices) { + if(prices.length == 0 || prices.length == 1) return 0; + int[] dp = new int[prices.length]; + int min = prices[0]; + int max = prices[prices.length - 1]; + for(int i = prices.length - 2; i >= 0; i--){ + dp[i] = Math.max(max - prices[i], dp[i + 1]); + max = Math.max(max, prices[i]); + } + max = Integer.MIN_VALUE; + for(int i = 0; i < prices.length; i ++){ + max = Math.max(max, prices[i] - min + dp[i]); + min = Math.min(min, prices[i]); + } + return max; + } +} From c941169bc3924993e33f2b4a9c67408c1cdc57b1 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 16 Feb 2018 01:09:42 +0100 Subject: [PATCH 160/235] Accepted Solutions --- README.md | 2 + .../src/string/LongestWordInDictonary.java | 60 +++++++++++++++++++ .../tree/MinimumAbsoluteDifferenceInBST.java | 57 ++++++++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 problems/src/string/LongestWordInDictonary.java create mode 100644 problems/src/tree/MinimumAbsoluteDifferenceInBST.java diff --git a/README.md b/README.md index 626ac432..6f32e72b 100644 --- a/README.md +++ b/README.md @@ -249,6 +249,7 @@ My accepted leetcode solutions to some of the common interview problems. - [One Edit Distance](problems/src/string/OneEditDistance.java) (Medium) - [Count and Say](problems/src/string/CountAndSay.java) (Easy) - [Multiply Strings](problems/src/string/MultiplyStrings.java) (Medium) +- [Longest Word in Dictionary through Deleting](problems/src/string/LongestWordInDictonary.java) (Medium) #### [Tree](problems/src/tree) @@ -285,6 +286,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Convert Binary Search Tree to Sorted Doubly Linked List](problems/src/tree/BSTtoDoublyLinkedList.java) (Easy) - [Same Tree](problems/src/tree/SameTree.java) (Easy) - [Binary Tree Longest Consecutive Sequence II](problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java) (Medium) +- [Minimum Absolute Difference in BST](problems/src/tree/MinimumAbsoluteDifferenceInBST.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/string/LongestWordInDictonary.java b/problems/src/string/LongestWordInDictonary.java new file mode 100644 index 00000000..910c2946 --- /dev/null +++ b/problems/src/string/LongestWordInDictonary.java @@ -0,0 +1,60 @@ +package string; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 15/02/2018. + * Given a string and a string dictionary, find the longest string in the dictionary that can be formed by deleting + * some characters of the given string. If there are more than one possible results, return the longest word with the + * smallest lexicographical order. If there is no possible result, return the empty string. + + Example 1: + Input: + s = "abpcplea", d = ["ale","apple","monkey","plea"] + + Output: + "apple" + Example 2: + Input: + s = "abpcplea", d = ["a","b","c"] + + Output: + "a" + Note: + All the strings in the input will only contain lower-case letters. + The size of the dictionary won't exceed 1,000. + The length of all the strings in the input won't exceed 1,000. + + Solution: O((n x m x log n) + (m ^ 2 + m x n))) sort the dictionary based on the longest first and then + lexicographically and compare each sorted word with given word and do a two pointer comparison to check for + sub-sequence. + */ +public class LongestWordInDictonary { + + /** + * Main method + * @param args + */ + public static void main(String[] args) throws Exception{ + List dict = Arrays.asList("ale","apple","monkey","plea"); + System.out.println(new LongestWordInDictonary().findLongestWord("abpcplea", dict)); + } + + public String findLongestWord(String s, List d) { + Collections.sort(d, Comparator.comparing(String::length).reversed().thenComparing(String::compareTo)); + for(String str : d){ + if(str.length() <= s.length()){ + int i = 0, j = 0; + for(int l1 = s.length(), l2 = str.length(); i < l1 && j < l2; ){ + if(s.charAt(i) == str.charAt(j)){ + i++; j++; + } else{ + i++; + } + } + if(j >= str.length()) return str; + } + } + return ""; + } +} diff --git a/problems/src/tree/MinimumAbsoluteDifferenceInBST.java b/problems/src/tree/MinimumAbsoluteDifferenceInBST.java new file mode 100644 index 00000000..7714bc88 --- /dev/null +++ b/problems/src/tree/MinimumAbsoluteDifferenceInBST.java @@ -0,0 +1,57 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 15/02/2018. + * Given a binary search tree with non-negative values, find the minimum absolute difference between values of any + * two nodes. + + Example: + + Input: + + 1 + \ + 3 + / + 2 + + Output: + 1 + + Explanation: + The minimum absolute difference is 1, which is the difference between 2 and 1 (or between 2 and 3). + Note: There are at least two nodes in this BST. + */ +public class MinimumAbsoluteDifferenceInBST { + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + int min = Integer.MAX_VALUE; + + public static void main(String[] args) throws Exception{ + TreeNode root = new TreeNode(1); + root.right = new TreeNode(2); + root.right.right = new TreeNode(3); + new MinimumAbsoluteDifferenceInBST().getMinimumDifference(root); + } + + public int getMinimumDifference(TreeNode root) { + getMin(root, null); + return min; + } + + private Integer getMin(TreeNode node, Integer prev){ + if(node == null) return prev; + Integer left = getMin(node.left, prev); + if(left != null){ + min = Math.min(min, Math.abs(node.val - left)); + } + return getMin(node.right, node.val); + } + +} From 34d28d7c70a84ad206a25573a082c507a117cc7f Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 16 Feb 2018 03:25:35 +0100 Subject: [PATCH 161/235] Solve the Equation: Accepted --- README.md | 1 + problems/src/math/SolveTheEquation.java | 115 ++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 problems/src/math/SolveTheEquation.java diff --git a/README.md b/README.md index 6f32e72b..4019913b 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Roman to Integer](problems/src/math/RomanToInteger.java) (Easy) - [Bulb Switcher II](problems/src/math/BulbSwitcherII.java) (Medium) - [Global and Local Inversions](problems/src/math/GlobalAndLocalInversions.java) (Medium) +- [Solve the Equation](problems/src/math/SolveTheEquation.java) (Medium) #### [Reservoir Sampling](problems/src/reservoir_sampling) diff --git a/problems/src/math/SolveTheEquation.java b/problems/src/math/SolveTheEquation.java new file mode 100644 index 00000000..a995b3fb --- /dev/null +++ b/problems/src/math/SolveTheEquation.java @@ -0,0 +1,115 @@ +package math; + +/** + * Created by gouthamvidyapradhan on 16/02/2018. + * Solve a given equation and return the value of x in the form of string "x=#value". The equation contains only + * '+', '-' operation, the variable x and its coefficient. + + If there is no solution for the equation, return "No solution". + + If there are infinite solutions for the equation, return "Infinite solutions". + + If there is exactly one solution for the equation, we ensure that the value of x is an integer. + + Example 1: + Input: "x+5-3+x=6+x-2" + Output: "x=2" + Example 2: + Input: "x=x" + Output: "Infinite solutions" + Example 3: + Input: "2x=x" + Output: "x=0" + Example 4: + Input: "2x+3x-6x=x+2" + Output: "x=-1" + Example 5: + Input: "x=x+2" + Output: "No solution" + + Solution: Solve the left and right part separately and then sum up the results. + */ + +public class SolveTheEquation { + + int xL = 0, xR = 0, tL = 0, tR = 0; + public static void main(String[] args) throws Exception{ + System.out.println(new SolveTheEquation().solveEquation("x=x+2")); + } + + public String solveEquation(String equation) { + String[] parts = equation.split("="); + solve(parts[0], true); + solve(parts[1], false); + long right = (long)tR - tL; + long left = (long)xL - xR; + if(left == 0 && right == 0){ + return "Infinite solutions"; + } else if(left == 0){ + return "No solution"; + } else if(right == 0){ + return "x=0"; + } else{ + return "x=" + (right / left); + } + } + + private void solve(String s, boolean isLeft){ + String num = ""; + int xSum = 0; + int rest = 0; + boolean isNeg = false; + for(int i = 0; i < s.length(); i ++){ + char c = s.charAt(i); + if(c == '-'){ + if(!num.isEmpty()){ + xSum = calculate(num, isNeg)[0]; + rest = calculate(num, isNeg)[1]; + } + isNeg = true; + num = ""; + }else if(c == '+'){ + if(!num.isEmpty()){ + xSum = calculate(num, isNeg)[0]; + rest = calculate(num, isNeg)[1]; + } + isNeg = false; + num = ""; + } else{ + num += c; + } + } + if(!num.isEmpty()){ + xSum = calculate(num, isNeg)[0]; + rest = calculate(num, isNeg)[1]; + } + if(isLeft){ + xL = xSum; + tL = rest; + } else{ + xR = xSum; + tR = rest; + } + } + + private int[] calculate(String num, boolean isNeg){ + int[] A = new int[2]; + if(num.contains("x")){ + num = num.substring(0, num.length() - 1); + if(isNeg){ + A[0] -= num.isEmpty() ? 1 : Integer.parseInt(num); + } else{ + A[0] += num.isEmpty() ? 1 : Integer.parseInt(num); + } + + } else{ + if(isNeg){ + A[1] -= Integer.parseInt(num); + } else{ + A[1] += Integer.parseInt(num); + } + } + return A; + } + +} From 416d5851c923aff0ad3e08007b0ace60542abbb2 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 16 Feb 2018 03:33:58 +0100 Subject: [PATCH 162/235] Solve the Equation: Accepted --- problems/src/math/SolveTheEquation.java | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/problems/src/math/SolveTheEquation.java b/problems/src/math/SolveTheEquation.java index a995b3fb..23b230f1 100644 --- a/problems/src/math/SolveTheEquation.java +++ b/problems/src/math/SolveTheEquation.java @@ -63,15 +63,15 @@ private void solve(String s, boolean isLeft){ char c = s.charAt(i); if(c == '-'){ if(!num.isEmpty()){ - xSum = calculate(num, isNeg)[0]; - rest = calculate(num, isNeg)[1]; + xSum = calculate(num, isNeg, xSum, rest)[0]; + rest = calculate(num, isNeg, xSum, rest)[1]; } isNeg = true; num = ""; }else if(c == '+'){ if(!num.isEmpty()){ - xSum = calculate(num, isNeg)[0]; - rest = calculate(num, isNeg)[1]; + xSum = calculate(num, isNeg, xSum, rest)[0]; + rest = calculate(num, isNeg, xSum, rest)[1]; } isNeg = false; num = ""; @@ -80,8 +80,8 @@ private void solve(String s, boolean isLeft){ } } if(!num.isEmpty()){ - xSum = calculate(num, isNeg)[0]; - rest = calculate(num, isNeg)[1]; + xSum = calculate(num, isNeg, xSum, rest)[0]; + rest = calculate(num, isNeg, xSum, rest)[1]; } if(isLeft){ xL = xSum; @@ -92,23 +92,25 @@ private void solve(String s, boolean isLeft){ } } - private int[] calculate(String num, boolean isNeg){ + private int[] calculate(String num, boolean isNeg, int xSum, int rest){ int[] A = new int[2]; if(num.contains("x")){ num = num.substring(0, num.length() - 1); if(isNeg){ - A[0] -= num.isEmpty() ? 1 : Integer.parseInt(num); + xSum -= num.isEmpty() ? 1 : Integer.parseInt(num); } else{ - A[0] += num.isEmpty() ? 1 : Integer.parseInt(num); + xSum += num.isEmpty() ? 1 : Integer.parseInt(num); } } else{ if(isNeg){ - A[1] -= Integer.parseInt(num); + rest -= Integer.parseInt(num); } else{ - A[1] += Integer.parseInt(num); + rest += Integer.parseInt(num); } } + A[0] = xSum; + A[1] = rest; return A; } From 4ab690a0a7a12cb3581a6997281c35c523d017b2 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 17 Feb 2018 00:52:32 +0100 Subject: [PATCH 163/235] Accepted solutions --- README.md | 2 + .../src/array/MinimumMovesToEqualArray.java | 68 +++++++++++++++++ .../depth_first_search/IslandPerimeter.java | 73 +++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 problems/src/array/MinimumMovesToEqualArray.java create mode 100644 problems/src/depth_first_search/IslandPerimeter.java diff --git a/README.md b/README.md index 4019913b..02b0610d 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Relative Ranks](problems/src/array/RelativeRanks.java) (Easy) - [Next Greater Element I](problems/src/array/NextGreaterElementI.java) (Easy) - [Largest Number At Least Twice of Others](problems/src/array/LargestNumberAtLeastTwice.java) (Easy) +- [Minimum Moves to Equal Array Elements II](problems/src/array/MinimumMovesToEqualArray.java) (Median) #### [Backtracking](problems/src/backtracking) @@ -95,6 +96,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Longest Consecutive Sequence](problems/src/depth_first_search/LongestConsecutiveSequence.java) (Hard) - [Accounts Merge](problems/src/depth_first_search/AccountsMerge.java) (Medium) - [CloneGraph](problems/src/depth_first_search/CloneGraph.java) (Medium) +- [Island Perimeter](problems/src/depth_first_search/IslandPerimeter.java) (Easy) #### [Design](problems/src/design) diff --git a/problems/src/array/MinimumMovesToEqualArray.java b/problems/src/array/MinimumMovesToEqualArray.java new file mode 100644 index 00000000..9c421ba6 --- /dev/null +++ b/problems/src/array/MinimumMovesToEqualArray.java @@ -0,0 +1,68 @@ +package array; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 17/02/2018. + * Given a non-empty integer array, find the minimum number of moves required to make all array elements equal, + * where a move is incrementing a selected element by 1 or decrementing a selected element by 1. + + You may assume the array's length is at most 10,000. + + Example: + + Input: + [1,2,3] + + Output: + 2 + + Explanation: + Only two moves are needed (remember each move increments or decrements one element): + + [1,2,3] => [2,2,3] => [2,2,2] + + Solution: O(n log n): Sort the array and find the median of the array. + Use the median of array to increment/decrement other value of array. Sum up the difference and return the answer. + */ +public class MinimumMovesToEqualArray { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1, 2, 3}; + System.out.println(new MinimumMovesToEqualArray().minMoves2(A)); + } + + public int minMoves2(int[] nums) { + if(nums.length == 1) return 0; + else if(nums.length == 2) return Math.abs(nums[0] - nums[1]); + Arrays.sort(nums); + int median; + if((nums.length % 2) == 1){ + median = (nums.length / 2); + int sum = 0; + for(int i = 0; i < nums.length; i++){ + sum += Math.abs(nums[i] - nums[median]); + } + return sum; + } else{ + median = (nums.length / 2) - 1; + int sum = 0; + int min; + for(int i = 0; i < nums.length; i++){ + sum += Math.abs(nums[i] - nums[median]); + } + min = sum; + sum = 0; + median = (nums.length / 2); + for(int i = 0; i < nums.length; i++){ + sum += Math.abs(nums[i] - nums[median]); + } + min = Math.min(min, sum); + return min; + } + } +} diff --git a/problems/src/depth_first_search/IslandPerimeter.java b/problems/src/depth_first_search/IslandPerimeter.java new file mode 100644 index 00000000..82fd5723 --- /dev/null +++ b/problems/src/depth_first_search/IslandPerimeter.java @@ -0,0 +1,73 @@ +package depth_first_search; + +/** + * Created by gouthamvidyapradhan on 16/02/2018. + * You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. + * Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, + * and there is exactly one island (i.e., one or more connected land cells). The island doesn't have "lakes" (water + * inside that isn't connected to the water around the island). One cell is a square with side length 1. The grid is + * rectangular, width and height don't exceed 100. Determine the perimeter of the island. + + Example: + + [[0,1,0,0], + [1,1,1,0], + [0,1,0,0], + [1,1,0,0]] + + Answer: 16 + Explanation: The perimeter is the 16 yellow stripes in the image below: + + Solution: Perform a dfs and count + 1 if any adjacent cell is a 0 or border + */ + +public class IslandPerimeter { + + int[] R = {1, -1, 0, 0}; + int[] C = {0, 0, 1, -1}; + boolean[][] done; + int perimeter; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[][] grid = {{0,1,0,0}, {1,1,1,0}, {0,1,0,0}, {1,1,0,0}}; + System.out.println(new IslandPerimeter().islandPerimeter(grid)); + } + + public int islandPerimeter(int[][] grid) { + done = new boolean[grid.length][grid[0].length]; + perimeter = 0; + for(int i = 0; i < grid.length; i ++){ + for(int j = 0; j < grid[0].length; j ++){ + if(grid[i][j] == 1 && !done[i][j]){ + dfs(i, j, grid); + break; + } + } + } + + return perimeter; + } + + private void dfs(int r, int c, int[][] grid){ + done[r][c] = true; + for(int i = 0; i < 4; i ++){ + int newR = r + R[i]; + int newC = c + C[i]; + if(newR < 0 || newC < 0 || newR >= grid.length || newC >= grid[0].length){ + perimeter++; + } + else if(grid[newR][newC] == 0) { + perimeter++; + } else{ + if(!done[newR][newC]){ + dfs(newR, newC, grid); + } + } + } + } + +} From ea5e5391a8e62afb4d1556a89831dcd06e7f4836 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 17 Feb 2018 15:23:56 +0100 Subject: [PATCH 164/235] Accepted solutions --- README.md | 2 + problems/src/array/ImageSmoother.java | 57 ++++++++++++++ problems/src/tree/EqualTreePartition.java | 95 +++++++++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 problems/src/array/ImageSmoother.java create mode 100644 problems/src/tree/EqualTreePartition.java diff --git a/README.md b/README.md index 02b0610d..1ccc96b8 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Next Greater Element I](problems/src/array/NextGreaterElementI.java) (Easy) - [Largest Number At Least Twice of Others](problems/src/array/LargestNumberAtLeastTwice.java) (Easy) - [Minimum Moves to Equal Array Elements II](problems/src/array/MinimumMovesToEqualArray.java) (Median) +- [Image Smoother](problems/src/array/ImageSmoother.java) (Easy) #### [Backtracking](problems/src/backtracking) @@ -290,6 +291,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Same Tree](problems/src/tree/SameTree.java) (Easy) - [Binary Tree Longest Consecutive Sequence II](problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java) (Medium) - [Minimum Absolute Difference in BST](problems/src/tree/MinimumAbsoluteDifferenceInBST.java) (Medium) +- [Equal Tree Partition](problems/src/tree/EqualTreePartition.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/array/ImageSmoother.java b/problems/src/array/ImageSmoother.java new file mode 100644 index 00000000..d37f0aa9 --- /dev/null +++ b/problems/src/array/ImageSmoother.java @@ -0,0 +1,57 @@ +package array; +/** + * Created by gouthamvidyapradhan on 17/02/2018. + * * Given a 2D integer matrix M representing the gray scale of an image, you need to design a smoother to make the + * gray scale of each cell becomes the average gray scale (rounding down) of all the 8 surrounding cells and itself. + * If a cell has less than 8 surrounding cells, then use as many as you can. + + Example 1: + Input: + [[1,1,1], + [1,0,1], + [1,1,1]] + Output: + [[0, 0, 0], + [0, 0, 0], + [0, 0, 0]] + Explanation: + For the point (0,0), (0,2), (2,0), (2,2): floor(3/4) = floor(0.75) = 0 + For the point (0,1), (1,0), (1,2), (2,1): floor(5/6) = floor(0.83333333) = 0 + For the point (1,1): floor(8/9) = floor(0.88888889) = 0 + Note: + The value in the given matrix is in the range of [0, 255]. + The length and width of the given matrix are in the range of [1, 150]. + */ + +public class ImageSmoother { + + int[] R = {1, -1, 0, 0, 1, -1, 1, -1}; + int[] C = {0, 0, -1, 1, 1, 1, -1, -1}; + public static void main(String[] args) throws Exception{ + + } + + public int[][] imageSmoother(int[][] M) { + int[][] result = new int[M.length][M[0].length]; + for(int i = 0; i < M.length; i ++){ + for(int j = 0; j < M[0].length; j ++){ + int numCount = 0; + int totalCount = 1; + for(int k = 0; k < 8; k++){ + int newR = i + R[k]; + int newC = j + C[k]; + if(newR >= 0 && newC >= 0 && newR < M.length && newC < M[0].length){ + if(M[newR][newC] > 0){ + numCount += M[newR][newC]; + } + totalCount++; + } + } + if(M[i][j] == 1) numCount++; + result[i][j] = numCount / totalCount; + } + } + return result; + } + +} diff --git a/problems/src/tree/EqualTreePartition.java b/problems/src/tree/EqualTreePartition.java new file mode 100644 index 00000000..b8590c7a --- /dev/null +++ b/problems/src/tree/EqualTreePartition.java @@ -0,0 +1,95 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 17/02/2018. + * Given a binary tree with n nodes, your task is to check if it's possible to partition the tree to two trees which + * have the equal sum of values after removing exactly one edge on the original tree. + + Example 1: + Input: + 5 + / \ + 10 10 + / \ + 2 3 + + Output: True + Explanation: + 5 + / + 10 + + Sum: 15 + + 10 + / \ + 2 3 + + Sum: 15 + Example 2: + Input: + 1 + / \ + 2 10 + / \ + 2 20 + + Output: False + Explanation: You can't split the tree into two trees with equal sum after removing exactly one edge on the tree. + Note: + The range of tree node value is in the range of [-100000, 100000]. + 1 <= n <= 10000 + */ + +public class EqualTreePartition { + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + private long sum; + private boolean possible = false; + + public static void main(String[] args) throws Exception{ + + } + + public boolean checkEqualTree(TreeNode root) { + sum = 0L; + getSum(root); + getDiff(root); + return possible; + } + + private void getSum(TreeNode node){ + if(node != null){ + sum += node.val; + getSum(node.left); + getSum(node.right); + } + } + + private Long getDiff(TreeNode node){ + if(node == null) return null; + Long left = getDiff(node.left); + Long right = getDiff(node.right); + if(left != null){ + if((sum - left) == left){ + possible = true; + } + }if(right != null){ + if((sum - right) == right){ + possible = true; + } + } + Long curr = (long)node.val; + if(left != null){ + curr += left; + } if(right != null){ + curr += right; + } + return curr; + } + +} From 9f8be545a36a1ee2c35511271f4873bc19821dab Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 7 Apr 2018 12:23:01 +0200 Subject: [PATCH 165/235] Subarray Product Less Than K: Accepted --- README.md | 1 + .../SubarrayProductLessThanK.java | 68 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 problems/src/two_pointers/SubarrayProductLessThanK.java diff --git a/README.md b/README.md index 1ccc96b8..c0a865de 100644 --- a/README.md +++ b/README.md @@ -306,4 +306,5 @@ My accepted leetcode solutions to some of the common interview problems. - [Minimum Size Subarray Sum](problems/src/two_pointers/MinimumSizeSubarraySum.java) (Medium) - [Minimum Window Substring](problems/src/two_pointers/MinimumWindowSubstring.java) (Hard) - [Smallest Range](problems/src/two_pointers/SmallestRange.java) (Hard) +- [Subarray Product Less Than K](problems/src/two_pointers/SubarrayProductLessThanK.java) (Medium) diff --git a/problems/src/two_pointers/SubarrayProductLessThanK.java b/problems/src/two_pointers/SubarrayProductLessThanK.java new file mode 100644 index 00000000..553ce797 --- /dev/null +++ b/problems/src/two_pointers/SubarrayProductLessThanK.java @@ -0,0 +1,68 @@ +package two_pointers; /** + * Created by gouthamvidyapradhan on 17/02/2018. + * Your are given an array of positive integers nums. + + Count and print the number of (contiguous) subarrays where the product of all the elements in the subarray is less + than k. + + Example 1: + Input: nums = [10, 5, 2, 6], k = 100 + Output: 8 + Explanation: The 8 subarrays that have product less than 100 are: [10], [5], [2], [6], [10, 5], [5, 2], [2, 6], + [5, 2, 6]. + Note that [10, 5, 2] is not included as the product of 100 is not strictly less than k. + Note: + + 0 < nums.length <= 50000. + 0 < nums[i] < 1000. + 0 <= k < 10^6. + */ + +import java.util.ArrayDeque; +import java.util.Queue; + +public class SubarrayProductLessThanK { + + public static void main(String[] args) throws Exception{ + int[] A = {10,2,2,5,4,4,4,3,7,7}; + System.out.println(new SubarrayProductLessThanK().numSubarrayProductLessThanK(A, 289)); + } + + + public int numSubarrayProductLessThanK(int[] nums, int k) { + long prod = 1; + int count = 0; + Queue queue = new ArrayDeque<>(); + for(int i = 0; i < nums.length; i++){ + if(nums[i] < k){ + count++; + if((prod * nums[i]) < k){ + prod *= nums[i]; + if(!queue.isEmpty()){ + count += (i - queue.peek()); + } + }else{ + while(!queue.isEmpty()){ + int last = queue.poll(); + prod /= nums[last]; + if((prod * nums[i]) < k){ + prod = prod * nums[i]; + if(!queue.isEmpty()){ + count += (i - queue.peek()); + } + break; + } + } + } + if(queue.isEmpty()){ + prod = nums[i]; + } + queue.offer(i); + } else{ + queue.clear(); + } + } + return count; + } + +} From 5ff13902a6fd2689a8856225dc9c30e0956376a0 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 7 Apr 2018 13:15:46 +0200 Subject: [PATCH 166/235] Top K Frequent Words: Accepted --- README.md | 1 + problems/src/heap/TopKFrequentWords.java | 77 ++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 problems/src/heap/TopKFrequentWords.java diff --git a/README.md b/README.md index c0a865de..0073f257 100644 --- a/README.md +++ b/README.md @@ -192,6 +192,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Sliding Window Maximum](problems/src/heap/SlidingWindowMaximum.java) (Hard) - [The Skyline Problem](problems/src/heap/TheSkylineProblem.java) (Hard) - [Meeting Rooms II](problems/src/heap/MeetingRoomsII.java) (Medium) +- [Top K Frequent Words](problems/src/heap/TopKFrequentWords.java) (Medium) #### [Linked List](problems/src/linked_list) diff --git a/problems/src/heap/TopKFrequentWords.java b/problems/src/heap/TopKFrequentWords.java new file mode 100644 index 00000000..f47cf236 --- /dev/null +++ b/problems/src/heap/TopKFrequentWords.java @@ -0,0 +1,77 @@ +package heap; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 07/04/2018. + * Given a non-empty list of words, return the k most frequent elements. + + Your answer should be sorted by frequency from highest to lowest. If two words have the same frequency, then the + word with the lower alphabetical order comes first. + + Example 1: + Input: ["i", "love", "leetcode", "i", "love", "coding"], k = 2 + Output: ["i", "love"] + Explanation: "i" and "love" are the two most frequent words. + Note that "i" comes before "love" due to a lower alphabetical order. + Example 2: + Input: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4 + Output: ["the", "is", "sunny", "day"] + Explanation: "the", "is", "sunny" and "day" are the four most frequent words, + with the number of occurrence being 4, 3, 2 and 1 respectively. + Note: + You may assume k is always valid, 1 ≤ k ≤ number of unique elements. + Input words contain only lowercase letters. + Follow up: + Try to solve it in O(n log k) time and O(n) extra space. + + Solution: O(n log k). Calculate frequency and maintain a inverse priority queue of size k and add elements. Return + result by reversing the priority queue elements. + */ +public class TopKFrequentWords { + + class Pair{ + String word; + int freq; + Pair(String word, int freq){ + this.word = word; + this.freq = freq; + } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + String[] words = {"i", "love", "leetcode", "i", "love", "coding"}; + List sorted = new TopKFrequentWords().topKFrequent(words, 2); + sorted.stream().forEach(System.out::println); + } + + public List topKFrequent(String[] words, int k) { + Map map = new HashMap<>(); + for(String w : words){ + map.putIfAbsent(w, 0); + int freq = map.get(w); + map.put(w, freq + 1); + } + Queue pq = new PriorityQueue<>((o1, o2) -> (o1.freq == o2.freq) ? o2.word.compareTo(o1.word) : + Integer.compare(o1.freq, o2.freq)); + for(String w : map.keySet()){ + int f = map.get(w); + pq.offer(new Pair(w, f)); + if(pq.size() > k){ + pq.poll(); + } + } + List result = new ArrayList<>(); + while(!pq.isEmpty()){ + result.add(pq.poll().word); + } + Collections.reverse(result); + return result; + } + +} From 6e645533021d17bc2b45ef844509d200552eea45 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 10 Apr 2018 01:38:48 +0200 Subject: [PATCH 167/235] Partition Labels: Accepted --- README.md | 1 + problems/src/hashing/PartitionLabels.java | 63 +++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 problems/src/hashing/PartitionLabels.java diff --git a/README.md b/README.md index 0073f257..897c9411 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Maximum Size Subarray Sum Equals k](problems/src/hashing/MaximumSizeSubarraySumEqualsk.java) (Medium) - [Contiguous Array](problems/src/hashing/ContiguousArray.java) (Medium) - [Brick Wall](problems/src/hashing/BrickWall.java) (Medium) +- [Partition Labels](problems/src/hashing/PartitionLabels.java) (Medium) #### [Heap](problems/src/heap) diff --git a/problems/src/hashing/PartitionLabels.java b/problems/src/hashing/PartitionLabels.java new file mode 100644 index 00000000..498d04f5 --- /dev/null +++ b/problems/src/hashing/PartitionLabels.java @@ -0,0 +1,63 @@ +package hashing; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by gouthamvidyapradhan on 10/04/2018. + * A string S of lowercase 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. + + Example 1: + 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. + Note: + + S will have length in range [1, 500]. + S will consist of lowercase letters ('a' to 'z') only. + + Solution O(n): Maintain a hashmap index of last occurrence of a character and do a linear check for max index, get + the length and add it to the result set. + */ +public class PartitionLabels{ + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new PartitionLabels().partitionLabels("abc")); + } + + public List partitionLabels(String S) { + if(S == null || S.trim().isEmpty()) return new ArrayList<>(); + Map map = new HashMap<>(); + for(int i = S.length() - 1; i >= 0; i --){ + char c = S.charAt(i); + map.putIfAbsent(c, i); + } + List result = new ArrayList<>(); + int start = 0; + int max = map.get(S.charAt(0)); + for(int i = 0; i < S.length(); i ++){ + char c = S.charAt(i); + if(map.get(c) > max){ + max = map.get(c); + } else if(i == max){ + result.add(max - start + 1); + if(i < S.length() - 1){ + start = i + 1; + max = map.get(S.charAt(i + 1)); + } + } + } + return result; + } +} From 1d00fe23a78abd461172f47031e5bcb2d443e866 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 11 Apr 2018 01:00:05 +0200 Subject: [PATCH 168/235] Minimum Index Sum of Two Lists: Accepted --- README.md | 1 + .../src/array/MinimumIndexSumOfTwoLists.java | 81 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 problems/src/array/MinimumIndexSumOfTwoLists.java diff --git a/README.md b/README.md index 897c9411..8ccbaaa7 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Largest Number At Least Twice of Others](problems/src/array/LargestNumberAtLeastTwice.java) (Easy) - [Minimum Moves to Equal Array Elements II](problems/src/array/MinimumMovesToEqualArray.java) (Median) - [Image Smoother](problems/src/array/ImageSmoother.java) (Easy) +- [Minimum Index Sum of Two Lists](problems/src/array/MinimumIndexSumOfTwoLists.java) (Easy) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/MinimumIndexSumOfTwoLists.java b/problems/src/array/MinimumIndexSumOfTwoLists.java new file mode 100644 index 00000000..1751d75b --- /dev/null +++ b/problems/src/array/MinimumIndexSumOfTwoLists.java @@ -0,0 +1,81 @@ +package array; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by gouthamvidyapradhan on 11/04/2018. + * Suppose Andy and Doris want to choose a restaurant for dinner, and they both have a list of favorite restaurants + * represented by strings. + + You need to help them find out their common interest with the least list index sum. If there is a choice tie between + answers, output all of them with no order requirement. You could assume there always exists an answer. + + Example 1: + Input: + ["Shogun", "Tapioca Express", "Burger King", "KFC"] + ["Piatti", "The Grill at Torrey Pines", "Hungry Hunter Steakhouse", "Shogun"] + Output: ["Shogun"] + Explanation: The only restaurant they both like is "Shogun". + Example 2: + Input: + ["Shogun", "Tapioca Express", "Burger King", "KFC"] + ["KFC", "Shogun", "Burger King"] + Output: ["Shogun"] + Explanation: The restaurant they both like and have the least index sum is "Shogun" with index sum 1 (0+1). + Note: + The length of both lists will be in the range of [1, 1000]. + The length of strings in both lists will be in the range of [1, 30]. + The index is starting from 0 to the list length minus 1. + No duplicates in both lists. + + Solution:O(N) maintain index of each restaurant in a list using a HashMap, find the min sum of indices and list + all the restaurants which match the min sum of indices + + */ +public class MinimumIndexSumOfTwoLists { + /** + * Main method + * @param args + */ + public static void main(String[] args) throws Exception{ + String[] A1 = {"Shogun", "Tapioca Express", "Burger King", "KFC"}; + String[] A2 = {"Tapioca Express", "Shogun", "Burger King"}; + String[] ans = new MinimumIndexSumOfTwoLists().findRestaurant(A1, A2); + for(String s : ans){ + System.out.println(s); + } + } + + public String[] findRestaurant(String[] list1, String[] list2) { + int min = Integer.MAX_VALUE; + List result = new ArrayList<>(); + if(list2.length == 0) return new String[0]; + Map index = new HashMap<>(); + for(int i = 0; i < list2.length; i ++){ + index.put(list2[i], i); + } + for(int i = 0; i < list1.length; i ++){ + String s = list1[i]; + if(index.containsKey(s)){ + int sum = i + index.get(s); + min = Math.min(min, sum); + } + } + + for(int i = 0; i < list1.length; i ++){ + String s = list1[i]; + if(index.containsKey(s)){ + int sum = i + index.get(s); + if(sum == min){ + result.add(s); + } + } + } + String[] resArr = new String[result.size()]; + result.toArray(resArr); + return resArr; + } +} From 2b187efda395deae0168983f160824d9daeb2b8d Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 12 Apr 2018 00:00:40 +0200 Subject: [PATCH 169/235] Isomorphic Strings: Accepted --- README.md | 1 + problems/src/string/IsomorphicStrings.java | 54 ++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 problems/src/string/IsomorphicStrings.java diff --git a/README.md b/README.md index 8ccbaaa7..e0b763f4 100644 --- a/README.md +++ b/README.md @@ -257,6 +257,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Count and Say](problems/src/string/CountAndSay.java) (Easy) - [Multiply Strings](problems/src/string/MultiplyStrings.java) (Medium) - [Longest Word in Dictionary through Deleting](problems/src/string/LongestWordInDictonary.java) (Medium) +- [Isomorphic Strings](problems/src/string/IsomorphicStrings.java) (Easy) #### [Tree](problems/src/tree) diff --git a/problems/src/string/IsomorphicStrings.java b/problems/src/string/IsomorphicStrings.java new file mode 100644 index 00000000..73d2d512 --- /dev/null +++ b/problems/src/string/IsomorphicStrings.java @@ -0,0 +1,54 @@ +package string; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by gouthamvidyapradhan on 11/04/2018. + * Given two strings s and t, determine if they are isomorphic. + + Two strings are isomorphic if the characters in s can be replaced to get t. + + All occurrences of a character must be replaced with another character while preserving the order of characters. No + two characters may map to the same character but a character may map to itself. + + For example, + Given "egg", "add", return true. + + Given "foo", "bar", return false. + + Given "paper", "title", return true. + + Note: + You may assume both s and t have the same length. + Solution O(N): Maintain two hashmaps and compare character by character. + */ +public class IsomorphicStrings { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new IsomorphicStrings().isIsomorphic("abc", "dea")); + } + + public boolean isIsomorphic(String s, String t) { + if(s.length() != t.length()) return false; + Map first = new HashMap<>(); + Map second = new HashMap<>(); + for(int i = 0; i < s.length(); i ++){ + char c = s.charAt(i); + if(first.containsKey(c)){ + char secondC = first.get(c); + if(t.charAt(i) != secondC) return false; + } else{ + first.put(c, t.charAt(i)); + if(second.containsKey(t.charAt(i))) return false; + second.put(t.charAt(i), c); + } + } + return true; + } + +} From 251e1ff7215b89e746d52272297eaa7cc648b412 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 12 Apr 2018 00:57:37 +0200 Subject: [PATCH 170/235] String Compression: Accepted --- README.md | 1 + problems/src/string/StringCompression.java | 95 ++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 problems/src/string/StringCompression.java diff --git a/README.md b/README.md index e0b763f4..8c2b80c3 100644 --- a/README.md +++ b/README.md @@ -258,6 +258,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Multiply Strings](problems/src/string/MultiplyStrings.java) (Medium) - [Longest Word in Dictionary through Deleting](problems/src/string/LongestWordInDictonary.java) (Medium) - [Isomorphic Strings](problems/src/string/IsomorphicStrings.java) (Easy) +- [String Compression](problems/src/string/StringCompression.java) (Easy) #### [Tree](problems/src/tree) diff --git a/problems/src/string/StringCompression.java b/problems/src/string/StringCompression.java new file mode 100644 index 00000000..8c88c805 --- /dev/null +++ b/problems/src/string/StringCompression.java @@ -0,0 +1,95 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 12/04/2018. + * Given an array of characters, compress it in-place. + + The length after compression must always be smaller than or equal to the original array. + + Every element of the array should be a character (not int) of length 1. + + After you are done modifying the input array in-place, return the new length of the array. + + + Follow up: + Could you solve it using only O(1) extra space? + + + Example 1: + Input: + ["a","a","b","b","c","c","c"] + + Output: + Return 6, and the first 6 characters of the input array should be: ["a","2","b","2","c","3"] + + Explanation: + "aa" is replaced by "a2". "bb" is replaced by "b2". "ccc" is replaced by "c3". + Example 2: + Input: + ["a"] + + Output: + Return 1, and the first 1 characters of the input array should be: ["a"] + + Explanation: + Nothing is replaced. + Example 3: + Input: + ["a","b","b","b","b","b","b","b","b","b","b","b","b"] + + Output: + Return 4, and the first 4 characters of the input array should be: ["a","b","1","2"]. + + Explanation: + Since the character "a" does not repeat, it is not compressed. "bbbbbbbbbbbb" is replaced by "b12". + Notice each digit has it's own entry in the array. + Note: + All characters have an ASCII value in [35, 126]. + 1 <= len(chars) <= 1000. + + Solution O(N) time complexity and O(1) space complexity. Maintain read and write pointers. Read from read pointer and + increment count when a repetition is found, when there is no repetition write the count value using write pointer. + */ +public class StringCompression { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + char[] A = {'a','a','b','b','c','c','c'}; + System.out.println(new StringCompression().compress(A)); + } + + public int compress(char[] chars) { + int count = 0; + int i = 0; + int p = 0; + for(int j = 0; j < chars.length; j ++){ + if(chars[i] == chars[j]){ + count ++; + } else{ + chars[p] = chars[i]; + p++; + if(count > 1){ + String countStr = String.valueOf(count); + for (int l = 0; l < countStr.length(); l++){ + chars[p++] = countStr.charAt(l); + } + } + i = j; + count = 1; + } + } + chars[p] = chars[i]; + p++; + if(count > 1){ + String countStr = String.valueOf(count); + for (int l = 0; l < countStr.length(); l++){ + chars[p++] = countStr.charAt(l); + } + } + return p; + } +} From 4ebd2850012863ab607dffa209e512d51184f4c7 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 12 Apr 2018 01:14:53 +0200 Subject: [PATCH 171/235] Letter Case Permutation: Accepted --- README.md | 1 + .../backtracking/LetterCasePermutation.java | 61 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 problems/src/backtracking/LetterCasePermutation.java diff --git a/README.md b/README.md index 8c2b80c3..c76c8519 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Regular Expression Matching](problems/src/backtracking/RegularExpressionMatching.java) (Hard) - [Expression Add Operators](problems/src/backtracking/ExpressionAddOperators.java) (Hard) - [Wildcard Matching](problems/src/backtracking/WildcardMatching.java) (Hard) +- [Letter Case Permutation](problems/src/backtracking/LetterCasePermutation.java) (Easy) #### [Binary Search](problems/src/binary_search) diff --git a/problems/src/backtracking/LetterCasePermutation.java b/problems/src/backtracking/LetterCasePermutation.java new file mode 100644 index 00000000..9ec9bf06 --- /dev/null +++ b/problems/src/backtracking/LetterCasePermutation.java @@ -0,0 +1,61 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by gouthamvidyapradhan on 12/04/2018. + * Given a string S, we can transform every letter individually to be lowercase or uppercase to create another string. + * Return a list of all possible strings we could create. + *

+ * Examples: + * Input: S = "a1b2" + * Output: ["a1b2", "a1B2", "A1b2", "A1B2"] + *

+ * Input: S = "3z4" + * Output: ["3z4", "3Z4"] + *

+ * Input: S = "12345" + * Output: ["12345"] + * Note: + *

+ * S will be a string with length at most 12. + * S will consist only of letters or digits. + * + * Solution: O(N x 2 ^ N) Backtrack and generate all possible combinations. + */ +public class LetterCasePermutation { + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new LetterCasePermutation().letterCasePermutation("a1b2")); + } + + public List letterCasePermutation(String S) { + List result = new ArrayList<>(); + backtrack(S, result, 0, ""); + return result; + } + + private void backtrack(String s, List result, int i, String r) { + if (i == s.length()) { + result.add(r); + } else { + if (Character.isAlphabetic(s.charAt(i))) { + backtrack(s, result, i + 1, r + s.charAt(i)); + if (Character.isLowerCase(s.charAt(i))) { + backtrack(s, result, i + 1, r + Character.toUpperCase(s.charAt(i))); + } else { + backtrack(s, result, i + 1, r + Character.toLowerCase(s.charAt(i))); + } + } else { + backtrack(s, result, i + 1, r + s.charAt(i)); + } + } + } +} From 451bdffcda78550a7a272957097ad80db73525c1 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 12 Apr 2018 02:20:01 +0200 Subject: [PATCH 172/235] Decode String: Accepted --- README.md | 1 + problems/src/stack/DecodeString.java | 68 ++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 problems/src/stack/DecodeString.java diff --git a/README.md b/README.md index c76c8519..13643147 100644 --- a/README.md +++ b/README.md @@ -235,6 +235,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Maximal Rectangle](problems/src/stack/MaximalRectangle.java) (Hard) - [Exclusive Time of Functions](problems/src/stack/ExclusiveTimeOfFunctions.java) (Medium) - [Basic Calculator](problems/src/stack/BasicCalculator.java) (Hard) +- [Decode String](problems/src/stack/DecodeString.java) (Medium) #### [String](problems/src/string) diff --git a/problems/src/stack/DecodeString.java b/problems/src/stack/DecodeString.java new file mode 100644 index 00000000..e87eccb7 --- /dev/null +++ b/problems/src/stack/DecodeString.java @@ -0,0 +1,68 @@ +package stack; + +import java.util.Stack; +/** + * Created by gouthamvidyapradhan on 12/04/2018. + * Given an encoded string, return it's decoded string. + *

+ * The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated + * exactly k times. Note that k is guaranteed to be a positive integer. + *

+ * You may assume that the input string is always valid; No extra white spaces, square brackets are well-formed, etc. + *

+ * Furthermore, you may assume that the original data does not contain any digits and that digits are only for those + * repeat numbers, k. For example, there won't be input like 3a or 2[4]. + *

+ * Examples: + *

+ * s = "3[a]2[bc]", return "aaabcbc". + * s = "3[a2[c]]", return "accaccacc". + * s = "2[abc]3[cd]ef", return "abcabccdcdcdef". + * + * Solution: Maintain a stack and push items when a character other than ] is encountered. When a character ] is + * encountered pop elements, build string and duplicate it. + */ +public class DecodeString { + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new DecodeString().decodeString("100[leetcode]")); + } + + public String decodeString(String s) { + Stack stack = new Stack<>(); + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == ']') { + StringBuilder stackBuff = new StringBuilder(); + while (stack.peek() != '[') { + stackBuff.append(stack.pop()); + } + stack.pop(); //pop '[' + String num = ""; + while (!stack.isEmpty() && !Character.isAlphabetic(stack.peek()) && stack.peek() != '[') { + num = stack.pop() + num; + } + String str = stackBuff.reverse().toString(); + StringBuilder stringMultiple = new StringBuilder(); + int N = Integer.parseInt(num); + while (N-- > 0) { + stringMultiple.append(str); + } + for (int j = 0; j < stringMultiple.length(); j++) { + stack.push(stringMultiple.charAt(j)); + } + } else stack.push(s.charAt(i)); + } + StringBuilder result = new StringBuilder(); + while (!stack.isEmpty()) { + result.append(stack.pop()); + } + return result.reverse().toString(); + } + +} From 25dfc531def2d9692276582d48ebf42967a03fc5 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 12 Apr 2018 02:38:36 +0200 Subject: [PATCH 173/235] Longest Common Prefix: Accepted --- README.md | 1 + problems/src/string/LongestCommonPrefix.java | 34 ++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 problems/src/string/LongestCommonPrefix.java diff --git a/README.md b/README.md index 13643147..8778b3dd 100644 --- a/README.md +++ b/README.md @@ -261,6 +261,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Longest Word in Dictionary through Deleting](problems/src/string/LongestWordInDictonary.java) (Medium) - [Isomorphic Strings](problems/src/string/IsomorphicStrings.java) (Easy) - [String Compression](problems/src/string/StringCompression.java) (Easy) +- [Longest Common Prefix](problems/src/string/LongestCommonPrefix.java) (Easy) #### [Tree](problems/src/tree) diff --git a/problems/src/string/LongestCommonPrefix.java b/problems/src/string/LongestCommonPrefix.java new file mode 100644 index 00000000..716c459c --- /dev/null +++ b/problems/src/string/LongestCommonPrefix.java @@ -0,0 +1,34 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 12/04/2018. + * Write a function to find the longest common prefix string amongst an array of strings. + * + * Solution: O(N x M) where N is the length of the given array and M is the max_length of a string. + */ +public class LongestCommonPrefix { + /** + * Main method + * @param args + */ + public static void main(String[] args) throws Exception{ + String[] A = {"abc", "a", "adkd"}; + System.out.println(new LongestCommonPrefix().longestCommonPrefix(A)); + } + + public String longestCommonPrefix(String[] strs) { + if(strs.length == 0) return ""; + String result = strs[0]; + for(int i = 1; i < strs.length; i ++){ + String s = strs[i]; + for(int j = 0; j < result.length(); j++){ + if(j >= s.length() || result.charAt(j) != s.charAt(j)) { + result = result.substring(0, j); + break; + } + } + } + return result; + } + +} From ec7294974a596929fe1d7274bdf23a2a36505047 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 14 Apr 2018 13:06:50 +0200 Subject: [PATCH 174/235] Insert Delete GetRandom O(1) - Duplicates allowed: Accepted --- README.md | 1 + problems/src/design/RandomizedCollection.java | 115 ++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 problems/src/design/RandomizedCollection.java diff --git a/README.md b/README.md index 8778b3dd..932787bc 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Flatten Nested List Iterator](problems/src/design/NestedIterator.java) (Medium) - [Add and Search Word - Data structure design](problems/src/design/WordDictionary.java) (Medium) - [Prefix and Suffix Search](problems/src/design/WordFilter.java) (Hard) +- [Insert Delete GetRandom O(1) - Duplicates allowed](problems/src/design/RandomizedCollection.java) (Hard) #### [Divide and Conquer](problems/src/divide_and_conquer) diff --git a/problems/src/design/RandomizedCollection.java b/problems/src/design/RandomizedCollection.java new file mode 100644 index 00000000..ac47d90b --- /dev/null +++ b/problems/src/design/RandomizedCollection.java @@ -0,0 +1,115 @@ +package design; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 14/04/2018. + * Design a data structure that supports all following operations in average O(1) time. + + Note: Duplicate elements are allowed. + insert(val): Inserts an item val to the collection. + remove(val): Removes an item val from the collection if present. + getRandom: Returns a random element from current collection of elements. The probability of each element being + returned is linearly related to the number of same value the collection contains. + Example: + + // Init an empty collection. + RandomizedCollection collection = new RandomizedCollection(); + + // Inserts 1 to the collection. Returns true as the collection did not contain 1. + collection.insert(1); + + // Inserts another 1 to the collection. Returns false as the collection contained 1. Collection now contains [1,1]. + collection.insert(1); + + // Inserts 2 to the collection, returns true. Collection now contains [1,1,2]. + collection.insert(2); + + // getRandom should return 1 with the probability 2/3, and returns 2 with the probability 1/3. + collection.getRandom(); + + // Removes 1 from the collection, returns true. Collection now contains [1,2]. + collection.remove(1); + + // getRandom should return 1 and 2 both equally likely. + collection.getRandom(); + + Solution O(1) for each operation. Maintain a hashmap of value -> {set of indices}; Set of indices are indices of array + containing the value. + Insert: Insert a element in end of array and add the index of array as the set of values in hashmap. + Remove: If the hashmap contains value remove a random element from the set and replace the element at that index + with the last element from array and remove the last element from the array. Since we are removing the last + element from array this operation requires only O(1) time + getRandom(): Generate a random number between 0 and size of array and return the element at that position. + */ +public class RandomizedCollection { + + private Map> map; + private List list; + + /** Initialize your data structure here. */ + public RandomizedCollection() { + map = new HashMap<>(); + list = new ArrayList<>(); + } + + /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ + public boolean insert(int val) { + boolean status = map.containsKey(val); + Set set = map.get(val); + if(set == null){ + set = new HashSet<>(); + map.put(val, set); + } + list.add(val); + set.add(list.size() - 1); + return !status; + } + + /** Removes a value from the collection. Returns true if the collection contained the specified element. */ + public boolean remove(int val) { + if(map.containsKey(val)){ + Set set = map.get(val); + int valIndex = set.iterator().next(); + set.remove(valIndex); + if(set.isEmpty()){ + map.remove(val); + } + if(valIndex == list.size() - 1){ //if this is the last index then simply remove it + list.remove(list.size() - 1); + } else{ + int lastEle = list.get(list.size() - 1); + map.get(lastEle).remove(list.size() - 1); + map.get(lastEle).add(valIndex); + list.set(valIndex, lastEle); + list.remove(list.size() - 1); + } + return true; + } else return false; + } + + /** Get a random element from the collection. */ + public int getRandom() { + Random random = new Random(); + return list.get(random.nextInt(list.size())); + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + RandomizedCollection collection = new RandomizedCollection(); + System.out.println(collection.insert(1)); + System.out.println(collection.insert(1)); + System.out.println(collection.insert(2)); + System.out.println(collection.getRandom()); + System.out.println(collection.remove(2)); + System.out.println(collection.getRandom()); + System.out.println(collection.remove(1)); + System.out.println(collection.getRandom()); + System.out.println(collection.remove(1)); + } + + +} From e2f6a20246b28d71b2f6bfd1ca7c25101b708ba7 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 21 Apr 2018 15:36:44 +0200 Subject: [PATCH 175/235] Find the Closest Palindrome - Accepted --- README.md | 1 + .../src/string/FindTheClosestPalindrome.java | 121 ++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 problems/src/string/FindTheClosestPalindrome.java diff --git a/README.md b/README.md index 932787bc..ab30a585 100644 --- a/README.md +++ b/README.md @@ -263,6 +263,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Isomorphic Strings](problems/src/string/IsomorphicStrings.java) (Easy) - [String Compression](problems/src/string/StringCompression.java) (Easy) - [Longest Common Prefix](problems/src/string/LongestCommonPrefix.java) (Easy) +- [Find the Closest Palindrome](problems/src/string/FindTheClosestPalindrome.java) (Hard) #### [Tree](problems/src/tree) diff --git a/problems/src/string/FindTheClosestPalindrome.java b/problems/src/string/FindTheClosestPalindrome.java new file mode 100644 index 00000000..1667d708 --- /dev/null +++ b/problems/src/string/FindTheClosestPalindrome.java @@ -0,0 +1,121 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 21/04/2018. + * Given an integer n, find the closest integer (not including itself), which is a palindrome. + + The 'closest' is defined as absolute difference minimized between two integers. + + Example 1: + Input: "123" + Output: "121" + Note: + The input n is a positive integer represented by string, whose length will not exceed 18. + If there is a tie, return the smaller one as answer. + + Solution O(N): General idea is to consider the first half of the string and make a new string by reversing the first + half of string. Concatenate the first_half and the new_string and return this as an answer. There are also + a lot of edge cases to be considered using this approach. +*/ +public class FindTheClosestPalindrome { + public static void main(String[] args) throws Exception { + System.out.println(new FindTheClosestPalindrome().nearestPalindromic("1837722381")); + } + + public String nearestPalindromic(String n) { + if(n.length() == 1) return String.valueOf(Integer.parseInt(n) - 1); + String p1, p2; + String palindrome; + if(isPaliandrome(n)){ + String newFirstHalf; + if(n.length() % 2 == 0){ + String firstHalf = n.substring(0, n.length() / 2); + newFirstHalf = String.valueOf(Long.parseLong(firstHalf) - 1); + p1 = newFirstHalf + new StringBuilder(newFirstHalf).reverse(); + newFirstHalf = String.valueOf(Long.parseLong(firstHalf) + 1); + p2 = newFirstHalf + new StringBuilder(newFirstHalf).reverse(); + } else{ + String firstHalf = n.substring(0, n.length() / 2); + char middle = n.charAt(n.length() / 2); + if(middle == '0'){ + p1 = firstHalf + "1" + new StringBuilder(firstHalf).reverse(); + } else{ + p1 = firstHalf + (Integer.parseInt(String.valueOf(middle)) - 1) + new StringBuilder + (firstHalf).reverse(); + } + newFirstHalf = String.valueOf(Long.parseLong(firstHalf) + 1); + p2 = newFirstHalf + "0" + new StringBuilder(newFirstHalf).reverse(); + } + }else{ + String firstHalf = n.substring(0, n.length() / 2); + if(n.length() % 2 == 0){ + p1 = firstHalf + new StringBuilder(firstHalf).reverse(); + String temp = String.valueOf(Long.parseLong(firstHalf) + 1); + p2 = temp + new StringBuilder(temp).reverse(); + temp = String.valueOf(Long.parseLong(firstHalf) - 1); + String p3 = temp + new StringBuilder(temp).reverse(); + p1 = Math.abs(Long.parseLong(p3) - Long.parseLong(n)) <= Math.abs(Long.parseLong(p1) - Long.parseLong + (n)) ? p3 : p1; + } else { + char middle = n.charAt(n.length() / 2); + p1 = firstHalf + middle + new StringBuilder(firstHalf).reverse(); + String temp = String.valueOf(Long.parseLong(firstHalf) + 1); + p2 = temp + "0" + new StringBuilder(temp).reverse(); + String p3 = firstHalf + (Integer.parseInt(String.valueOf(middle)) + 1) + new StringBuilder(firstHalf) + .reverse(); + String p4 = null; + if(middle != '0'){ + p4 = firstHalf + (Integer.parseInt(String.valueOf(middle)) - 1) + new StringBuilder + (firstHalf).reverse(); + } + p1 = Math.abs(Long.parseLong(p1) - Long.parseLong(n)) <= Math.abs(Long.parseLong(p3) - Long.parseLong + (n)) ? p1 : p3; + if(p4 != null){ + p1 = Math.abs(Long.parseLong(p4) - Long.parseLong(n)) <= Math.abs(Long.parseLong(p1) - Long + .parseLong(n)) ? p4 : p1; + } + } + } + long l1 = Math.abs(Long.parseLong(n) - Long.parseLong(p1)); + long l2 = Math.abs(Long.parseLong(n) - Long.parseLong(p2)); + if(l1 <= l2){ + palindrome = p1; + } else palindrome = p2; + long m1 = Math.abs(Long.parseLong(getLow(n)) - Long.parseLong(n)); + long m2 = Math.abs(Long.parseLong(palindrome) - Long.parseLong(n)); + long m3 = Math.abs(Long.parseLong(getHigh(n)) - Long.parseLong(n)); + long min = Math.min(Math.min(m1, m2), m3); + if(min == m1) return getLow(n); + else if(min == m2) return palindrome; + else return getHigh(n); + } + + private String getLow(String s){ + int n = s.length() - 1; + StringBuilder sb = new StringBuilder(); + for(int i = 0; i < n; i ++){ + sb.append("9"); + } + return sb.toString(); + } + + private String getHigh(String s){ + int n = s.length() - 1; + StringBuilder sb = new StringBuilder(); + sb.append("1"); + for(int i = 0; i < n; i ++){ + sb.append("0"); + } + sb.append("1"); + return sb.toString(); + } + + private boolean isPaliandrome(String s){ + for(int i = 0, j = s.length() - 1; i < j; i++, j--){ + if(s.charAt(i) != s.charAt(j)){ + return false; + } + } + return true; + } +} From 61853693d3eb5ddb12e4822f3aa4d4e2447a592a Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 24 Apr 2018 01:44:27 +0200 Subject: [PATCH 176/235] Number of Distinct Islands - Accepted --- README.md | 1 + .../NumberOfDistinctIslands.java | 91 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 problems/src/depth_first_search/NumberOfDistinctIslands.java diff --git a/README.md b/README.md index ab30a585..f12e0dcb 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Accounts Merge](problems/src/depth_first_search/AccountsMerge.java) (Medium) - [CloneGraph](problems/src/depth_first_search/CloneGraph.java) (Medium) - [Island Perimeter](problems/src/depth_first_search/IslandPerimeter.java) (Easy) +- [Number of Distinct Islands](problems/src/depth_first_search/NumberOfDistinctIslands.java) (Medium) #### [Design](problems/src/design) diff --git a/problems/src/depth_first_search/NumberOfDistinctIslands.java b/problems/src/depth_first_search/NumberOfDistinctIslands.java new file mode 100644 index 00000000..18a79a2f --- /dev/null +++ b/problems/src/depth_first_search/NumberOfDistinctIslands.java @@ -0,0 +1,91 @@ +package depth_first_search; + +import java.util.HashSet; +import java.util.Set; + +/** + * Created by gouthamvidyapradhan on 23/04/2018. + * Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) connected + * 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water. + + Count the number of distinct islands. An island is considered to be the same as another if and only if one island + can be translated (and not rotated or reflected) to equal the other. + + Example 1: + 11000 + 11000 + 00011 + 00011 + Given the above grid map, return 1. + Example 2: + 11011 + 10000 + 00001 + 11011 + Given the above grid map, return 3. + + Notice that: + 11 + 1 + and + 1 + 11 + are considered different island islands, because we do not consider reflection / rotation. + Note: The length of each dimension in the given grid does not exceed 50. + + Solution: O(N x M) create a signature of each island based on the direction and then use a hashset to count the + islands. + */ +public class NumberOfDistinctIslands { + private int[] R = {0, 1, 0, -1}; + private int[] C = {1, 0, -1, 0}; + private boolean[][] done; + private Set islands; + /** + * Main method + * @param args + */ + public static void main(String[] args) throws Exception{ + int[][] N = {{1, 1, 1, 1}, {1, 0, 1, 0}, {0, 0, 0, 0}, {0, 1, 1, 1}, {1,1,0,1}}; + System.out.println(new NumberOfDistinctIslands().numDistinctIslands(N)); + } + + public int numDistinctIslands(int[][] grid) { + done = new boolean[grid.length][grid[0].length]; + islands = new HashSet<>(); + for(int i = 0; i < grid.length; i ++){ + for(int j = 0; j < grid[0].length; j ++){ + if(!done[i][j] && grid[i][j] == 1){ + StringBuilder sb = new StringBuilder(); + dfs(i, j, grid, sb); + islands.add(sb.toString()); + } + } + } + return islands.size(); + } + + private void dfs(int r, int c, int[][] grid, StringBuilder sb){ + done[r][c] = true; + for(int i = 0; i < 4; i ++){ + int newR = r + R[i]; + int newC = c + C[i]; + if(newR >= 0 && newC >= 0 && newR < grid.length && newC < grid[0].length){ + if(!done[newR][newC] && grid[newR][newC] == 1){ + if(R[i] == 0 && C[i] == 1){ + sb.append("R"); + } else if(R[i] == 1 && C[i] == 0){ + sb.append("D"); + } else if(R[i] == 0 && C[i] == -1){ + sb.append("L"); + } else{ + sb.append("U"); + } + dfs(newR, newC, grid, sb); + } + } + } + sb.append("B"); + } + +} From f3f8826409be419763fb861d4dbfe355d42761d6 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 24 Apr 2018 02:29:29 +0200 Subject: [PATCH 177/235] Number of Distinct Islands - Accepted --- .../src/depth_first_search/NumberOfDistinctIslands.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/problems/src/depth_first_search/NumberOfDistinctIslands.java b/problems/src/depth_first_search/NumberOfDistinctIslands.java index 18a79a2f..803a1342 100644 --- a/problems/src/depth_first_search/NumberOfDistinctIslands.java +++ b/problems/src/depth_first_search/NumberOfDistinctIslands.java @@ -72,11 +72,11 @@ private void dfs(int r, int c, int[][] grid, StringBuilder sb){ int newC = c + C[i]; if(newR >= 0 && newC >= 0 && newR < grid.length && newC < grid[0].length){ if(!done[newR][newC] && grid[newR][newC] == 1){ - if(R[i] == 0 && C[i] == 1){ + if(i == 0){ sb.append("R"); - } else if(R[i] == 1 && C[i] == 0){ + } else if(i == 1){ sb.append("D"); - } else if(R[i] == 0 && C[i] == -1){ + } else if(i == 2){ sb.append("L"); } else{ sb.append("U"); From ef2aefd03dcdc4436215a3f2653144832cdf1c93 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 28 Apr 2018 16:20:35 +0200 Subject: [PATCH 178/235] Number of Distinct Islands II- Accepted --- README.md | 1 + .../NumberOfDistinctIslandsII.java | 171 ++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 problems/src/depth_first_search/NumberOfDistinctIslandsII.java diff --git a/README.md b/README.md index f12e0dcb..b9559155 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,7 @@ My accepted leetcode solutions to some of the common interview problems. - [CloneGraph](problems/src/depth_first_search/CloneGraph.java) (Medium) - [Island Perimeter](problems/src/depth_first_search/IslandPerimeter.java) (Easy) - [Number of Distinct Islands](problems/src/depth_first_search/NumberOfDistinctIslands.java) (Medium) +- [Number of Distinct Islands II](problems/src/depth_first_search/NumberOfDistinctIslandsII.java) (Hard) #### [Design](problems/src/design) diff --git a/problems/src/depth_first_search/NumberOfDistinctIslandsII.java b/problems/src/depth_first_search/NumberOfDistinctIslandsII.java new file mode 100644 index 00000000..a71aab50 --- /dev/null +++ b/problems/src/depth_first_search/NumberOfDistinctIslandsII.java @@ -0,0 +1,171 @@ +package depth_first_search; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * Created by gouthamvidyapradhan on 27/04/2018. + * Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) connected + * 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water. + + Count the number of distinct islands. An island is considered to be the same as another if they have the same + shape, or have the same shape after rotation (90, 180, or 270 degrees only) or reflection (left/right direction or + up/down direction). + + Example 1: + 11000 + 10000 + 00001 + 00011 + Given the above grid map, return 1. + + Notice that: + 11 + 1 + and + 1 + 11 + are considered same island shapes. Because if we make a 180 degrees clockwise rotation on the first island, then + two islands will have the same shapes. + Example 2: + 11100 + 10001 + 01001 + 01110 + Given the above grid map, return 2. + + Here are the two distinct islands: + 111 + 1 + and + 1 + 1 + + Notice that: + 111 + 1 + and + 1 + 111 + are considered same island shapes. Because if we flip the first array in the up/down direction, then they have the + same shapes. + Note: The length of each dimension in the given grid does not exceed 50. + + Solution: General idea is to get the co-ordinates of each shape using dfs and rotate/reflect each point in a shape + to transform each shape to a new possible shape (there are 8 possible shapes after rotation and reflection). Sort the + new coordinates of each transformed shape and reduce each shape to a canonical key. Use a hash-set to count total + number of such keys. + + Some background on rotation and reflection: + ------------------------------------------- + Rotate co-ordinates using formula [x′y′]=[[cosθ -sinθ], [sinθ cosθ]] [x y] where θ = {0, 90, 180, 270} + There are 4 possible rotation points and for each rotation point obtain the reflection on each x and y axis. + Rotation and reflection results in total of 8 points such as (x, y), (-x, y), (x, -y), (-x, -y), + (y, x), (-y, x), (y, -x) and (-y, -x). + + + + */ +public class NumberOfDistinctIslandsII { + private final int[] R = {0, 1, 0, -1}; + private final int[] C = {1, 0, -1, 0}; + private boolean[][] done; + + class Point implements Comparable{ + int x; int y; + Point(int x, int y){ + this.x = x; + this.y = y; + } + + @Override + public int compareTo(Point o) { + if(this.x == o.x){ + return Integer.compare(this.y, o.y); + } return Integer.compare(this.x, o.x); + } + } + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[][] grid = {{1,1,0,0,0}, {1,0,0,0,0}, {0,0,0,0,1}, {0,0,0,1,1}}; + System.out.println(new NumberOfDistinctIslandsII().numDistinctIslands2(grid)); + } + + public int numDistinctIslands2(int[][] grid) { + List> shapes = new ArrayList<>(); + done = new boolean[grid.length][grid[0].length]; + Set islands = new HashSet<>(); + for(int i = 0; i < grid.length; i++){ + for(int j = 0; j < grid[0].length; j++){ + if(!done[i][j] && grid[i][j] == 1){ + List points = new ArrayList<>(); + dfs(i, j, grid, points); + shapes.add(points); + } + } + } + for(List shape : shapes){ + List> eightShapes = rotateAndReflect(shape); + islands.add(genKey(eightShapes)); + } + return islands.size(); + } + + /** + * Generate a canonical key + * @param eighShapes + * @return + */ + private String genKey(List> eighShapes){ + List keys = new ArrayList<>(); + for(List shape : eighShapes){ + Collections.sort(shape); + Point first = shape.get(0); + keys.add(shape.stream().map(s -> new Point(s.x - first.x, s.y - first.y)) + .map(p -> p.x + ":" + p.y).collect(Collectors.joining( "," ))); + } + Collections.sort(keys); + return keys.get(0); + } + + /** + * Rotate and reflect a given shape to 8 possible shapes + * @param shape + * @return + */ + private List> rotateAndReflect(List shape){ + Map> map = new HashMap<>(); + for(int i = 0; i < 8; i ++){ + map.put(i, new ArrayList<>()); + } + for(Point point : shape){ + map.get(0).add(new Point(point.x, point.y)); + map.get(1).add(new Point(-point.x, point.y)); + map.get(2).add(new Point(point.x, -point.y)); + map.get(3).add(new Point(-point.x, -point.y)); + map.get(4).add(new Point(point.y, point.x)); + map.get(5).add(new Point(-point.y, point.x)); + map.get(6).add(new Point(point.y, -point.x)); + map.get(7).add(new Point(-point.y, -point.x)); + } + return new ArrayList<>(map.values()); + } + + + private void dfs(int r, int c, int[][] grid, List points){ + done[r][c] = true; + points.add(new Point(c, r)); + for(int i = 0; i < 4; i ++){ + int newR = r + R[i]; + int newC = c + C[i]; + if(newR >= 0 && newC >= 0 && newR < grid.length && newC < grid[0].length && grid[newR][newC] == 1 && + !done[newR][newC]){ + dfs(newR, newC, grid, points); + } + } + } +} From 5411b8b521f34bcc74812f0b9356ade4e9692971 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Mon, 30 Apr 2018 23:50:48 +0200 Subject: [PATCH 179/235] Min Cost Climbing Stairs - Accepted --- README.md | 1 + .../MinCostClimbingStairs.java | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 problems/src/dynamic_programming/MinCostClimbingStairs.java diff --git a/README.md b/README.md index b9559155..44224b85 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Longest Paliandromic Substring](problems/src/dynamic_programming/LongestPaliandromicSubstring.java) (Medium) - [Longest Palindromic Subsequence](problems/src/dynamic_programming/LongestPalindromicSubsequence.java) (Medium) - [Maximum Product Subarray](problems/src/dynamic_programming/MaximumProductSubarray.java) (Medium) +- [Min Cost Climbing Stairs](problems/src/dynamic_programming/MinCostClimbingStairs.java) (Medium) - [Palindrome Partitioning II](problems/src/dynamic_programming/PalindromePartitioningII.java) (Hard) - [UniqueBinary Search Trees](problems/src/dynamic_programming/UniqueBinarySearchTrees.java) (Medium) - [Unique Binary Search Trees II](problems/src/dynamic_programming/UniqueBinarySearchTreesII.java) (Medium) diff --git a/problems/src/dynamic_programming/MinCostClimbingStairs.java b/problems/src/dynamic_programming/MinCostClimbingStairs.java new file mode 100644 index 00000000..4a98498b --- /dev/null +++ b/problems/src/dynamic_programming/MinCostClimbingStairs.java @@ -0,0 +1,37 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 30/04/2018. + * On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). + + Once you pay the cost, you can either climb one or two steps. You need to find minimum cost to reach the top of the + floor, and you can either start from the step with index 0, or the step with index 1. + + Example 1: + Input: cost = [10, 15, 20] + Output: 15 + Explanation: Cheapest is start on cost[1], pay that cost and go to the top. + Example 2: + Input: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] + Output: 6 + Explanation: Cheapest is start on cost[0], and only step on 1s, skipping cost[3]. + Note: + cost will have a length in the range [2, 1000]. + Every cost[i] will be an integer in the range [0, 999]. + + Solution: O(N) At every step there are two options, either cost[i] + cost[i + 1] or cost[i] + cost[i + 2] + */ +public class MinCostClimbingStairs { + public static void main(String[] args) throws Exception{ + + } + + public int minCostClimbingStairs(int[] cost) { + for(int i = cost.length - 1; i >= 0; i --){ + if(i + 1 < cost.length && i + 2 < cost.length){ + cost[i] = Math.min(cost[i] + cost[i + 1], cost[i] + cost[i + 2]); + } + } + return Math.min(cost[0], cost[1]); + } +} From 4ca1595a77b9b0fbaca3663a7ab779c6925bf5bb Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 1 May 2018 00:28:50 +0200 Subject: [PATCH 180/235] Maximum Length of Pair Chain - Accepted --- README.md | 3 +- .../src/greedy/MaximumLengthOfPairChain.java | 50 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 problems/src/greedy/MaximumLengthOfPairChain.java diff --git a/README.md b/README.md index 44224b85..4b2a9f44 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Longest Paliandromic Substring](problems/src/dynamic_programming/LongestPaliandromicSubstring.java) (Medium) - [Longest Palindromic Subsequence](problems/src/dynamic_programming/LongestPalindromicSubsequence.java) (Medium) - [Maximum Product Subarray](problems/src/dynamic_programming/MaximumProductSubarray.java) (Medium) -- [Min Cost Climbing Stairs](problems/src/dynamic_programming/MinCostClimbingStairs.java) (Medium) +- [Min Cost Climbing Stairs](problems/src/dynamic_programming/MinCostClimbingStairs.java) (Easy) - [Palindrome Partitioning II](problems/src/dynamic_programming/PalindromePartitioningII.java) (Hard) - [UniqueBinary Search Trees](problems/src/dynamic_programming/UniqueBinarySearchTrees.java) (Medium) - [Unique Binary Search Trees II](problems/src/dynamic_programming/UniqueBinarySearchTreesII.java) (Medium) @@ -180,6 +180,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Minimum Number of Arrows to Burst Balloons](problems/src/greedy/BurstBalloons.java) (Medium) - [Queue Reconstruction By Height](problems/src/greedy/QueueReconstructionByHeight.java) (Medium) - [Task Scheduler](problems/src/greedy/TaskScheduler.java) (Medium) +- [Maximum Length of Pair Chain](problems/src/greedy/MaximumLengthOfPairChain.java) (Medium) #### [Hashing](problems/src/hashing) diff --git a/problems/src/greedy/MaximumLengthOfPairChain.java b/problems/src/greedy/MaximumLengthOfPairChain.java new file mode 100644 index 00000000..41b0574f --- /dev/null +++ b/problems/src/greedy/MaximumLengthOfPairChain.java @@ -0,0 +1,50 @@ +package greedy; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 01/05/2018. + * You are given n pairs of numbers. In every pair, the first number is always smaller than the second number. + + Now, we define a pair (c, d) can follow another pair (a, b) if and only if b < c. + Chain of pairs can be formed in this fashion. + + Given a set of pairs, find the length longest chain which can be formed. You needn't use up all the given pairs. + You can select pairs in any order. + + Example 1: + Input: [[1,2], [2,3], [3,4]] + Output: 2 + Explanation: The longest chain is [1,2] -> [3,4] + Note: + The number of given pairs will be in the range [1, 1000]. + + Solution: O(N log N) sort the pairs with ending interval (greedy sort) and try to accommodate as many pairs + as possible. If any current pair violates the chaining condition (b < c) then, ignore that particular pair. + */ +public class MaximumLengthOfPairChain { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[][] A = {{1,2}, {2,3}, {3,4}}; + System.out.println(new MaximumLengthOfPairChain().findLongestChain(A)); + } + + public int findLongestChain(int[][] pairs) { + Arrays.sort(pairs, (o1, o2) -> o1[1] == o2[1] ? Integer.compare(o1[0], o2[0]) : Integer.compare(o1[1], o2[1])); + int count = 1; + int[] curr = pairs[0]; + for(int i = 1; i < pairs.length; i ++){ + if(pairs[i][0] > curr[1]){ + count++; + curr = pairs[i]; + } + } + return count; + } + +} From 48d99a25f3b08a3b3e73965e0b4c34accb68c99b Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 1 May 2018 01:11:33 +0200 Subject: [PATCH 181/235] Monotone Increasing Digits - Accepted --- README.md | 1 + .../src/string/MonotoneIncreasingDigits.java | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 problems/src/string/MonotoneIncreasingDigits.java diff --git a/README.md b/README.md index 4b2a9f44..646a7cb2 100644 --- a/README.md +++ b/README.md @@ -268,6 +268,7 @@ My accepted leetcode solutions to some of the common interview problems. - [String Compression](problems/src/string/StringCompression.java) (Easy) - [Longest Common Prefix](problems/src/string/LongestCommonPrefix.java) (Easy) - [Find the Closest Palindrome](problems/src/string/FindTheClosestPalindrome.java) (Hard) +- [Monotone Increasing Digits](problems/src/string/MonotoneIncreasingDigits.java) (Medium) #### [Tree](problems/src/tree) diff --git a/problems/src/string/MonotoneIncreasingDigits.java b/problems/src/string/MonotoneIncreasingDigits.java new file mode 100644 index 00000000..b8dd0784 --- /dev/null +++ b/problems/src/string/MonotoneIncreasingDigits.java @@ -0,0 +1,66 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 01/05/2018. + * Given a non-negative integer N, find the largest number that is less than or equal to N with monotone + * increasing digits. + + (Recall that an integer has monotone increasing digits if and only if each pair of + adjacent digits x and y satisfy x <= y.) + + Example 1: + Input: N = 10 + Output: 9 + Example 2: + Input: N = 1234 + Output: 1234 + Example 3: + Input: N = 332 + Output: 299 + Note: N is an integer in the range [0, 10^9]. + + Solution O(N): Convert to string for easier manipulation. + Start from N.length - 1 and iterate through until index 0.Mark the index where the violation occurs. + Decrement the value of the latest index where the violation occurs and append '9' to + rest of the trailing digits. Convert the string to integer before returning. + */ +public class MonotoneIncreasingDigits { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new MonotoneIncreasingDigits().monotoneIncreasingDigits(100001)); + } + + public int monotoneIncreasingDigits(int N) { + String s = String.valueOf(N); + if(s.length() == 1) return N; + int p = -1; + int prev = N % 10; + for(int i = s.length() - 2; i >= 0; i--){ + int curr = Integer.parseInt(String.valueOf(s.charAt(i))); + if(curr > prev){ + p = i; + prev = curr - 1; + } else { + prev = curr; + } + } + if(p == -1) return N; + StringBuilder result = new StringBuilder(); + for(int i = 0; i < s.length(); i ++){ + if(i == p){ + int pV = Integer.parseInt(String.valueOf(s.charAt(i))); + result.append(pV - 1); + break; + } result.append(String.valueOf(s.charAt(i))); + } + for(int i = p + 1; i < s.length(); i ++){ + result.append("9"); + } + return Integer.parseInt(result.toString()); + } + +} From 82d43adfe995925572ca4827e4a977aba44a1734 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 1 May 2018 14:26:29 +0200 Subject: [PATCH 182/235] Custom Sort String - Accepted --- README.md | 1 + problems/src/hashing/CustomSortString.java | 69 ++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 problems/src/hashing/CustomSortString.java diff --git a/README.md b/README.md index 646a7cb2..7c332367 100644 --- a/README.md +++ b/README.md @@ -194,6 +194,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Contiguous Array](problems/src/hashing/ContiguousArray.java) (Medium) - [Brick Wall](problems/src/hashing/BrickWall.java) (Medium) - [Partition Labels](problems/src/hashing/PartitionLabels.java) (Medium) +- [Custom Sort String](problems/src/hashing/CustomSortString.java) (Medium) #### [Heap](problems/src/heap) diff --git a/problems/src/hashing/CustomSortString.java b/problems/src/hashing/CustomSortString.java new file mode 100644 index 00000000..f9efef15 --- /dev/null +++ b/problems/src/hashing/CustomSortString.java @@ -0,0 +1,69 @@ +package hashing; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 01/05/2018. + * S and T are strings composed of lowercase letters. In S, no letter occurs more than once. + + S was sorted in some custom order previously. We want to permute the characters of T so that they match the order + that S was sorted. More specifically, if x occurs before y in S, then x should occur before y in the returned string. + + Return any permutation of T (as a string) that satisfies this property. + + Example : + Input: + S = "cba" + T = "abcd" + Output: "cbad" + Explanation: + "a", "b", "c" appear in S, so the order of "a", "b", "c" should be "c", "b", and "a". + Since "d" does not appear in S, it can be at any position in T. "dcba", "cdba", "cbda" are also valid outputs. + + + Note: + + S has length at most 26, and no character is repeated in S. + T has length at most 200. + S and T consist of lowercase letters only. + + Solution: O(N) count occurrence of each character and write to the output string + */ +public class CustomSortString { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new CustomSortString().customSortString("cba", "abcd")); + } + + public String customSortString(String S, String T) { + Map map = new HashMap<>(); + for(int i = 0; i < T.length(); i ++){ + if(!map.containsKey(T.charAt(i))){ + map.put(T.charAt(i), 1); + } else{ + map.put(T.charAt(i), map.get(T.charAt(i)) + 1); + } + } + StringBuilder result = new StringBuilder(); + for(char c : S.toCharArray()){ + if(map.containsKey(c)){ + int count = map.remove(c); + for(int i = 0; i < count; i ++){ + result.append(c); + } + } + } + for(char c : map.keySet()){ + int count = map.get(c); + for(int i = 0; i < count; i ++){ + result.append(c); + } + } + return result.toString(); + } +} From 449ff7468d1ad1adec6d1f872067c3a7fcbda1d0 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 2 May 2018 01:24:18 +0200 Subject: [PATCH 183/235] Split BST - Accepted --- README.md | 1 + problems/src/tree/SplitBST.java | 92 +++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 problems/src/tree/SplitBST.java diff --git a/README.md b/README.md index 7c332367..e4f03561 100644 --- a/README.md +++ b/README.md @@ -308,6 +308,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Binary Tree Longest Consecutive Sequence II](problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java) (Medium) - [Minimum Absolute Difference in BST](problems/src/tree/MinimumAbsoluteDifferenceInBST.java) (Medium) - [Equal Tree Partition](problems/src/tree/EqualTreePartition.java) (Medium) +- [Split BST](problems/src/tree/SplitBST.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/SplitBST.java b/problems/src/tree/SplitBST.java new file mode 100644 index 00000000..bd1284d8 --- /dev/null +++ b/problems/src/tree/SplitBST.java @@ -0,0 +1,92 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 01/05/2018. + * Given a Binary Search Tree (BST) with root node root, and a target value V, split the tree into two subtrees + * where one subtree has nodes that are all smaller or equal to the target value, while the other subtree has all + * nodes that are greater than the target value. It's not necessarily the case that the tree contains a node with + * value V. + + Additionally, most of the structure of the original tree should remain. Formally, for any child C with parent P in + the original tree, if they are both in the same subtree after the split, then node C should still have the parent P. + + You should output the root TreeNode of both subtrees after splitting, in any order. + + Example 1: + + Input: root = [4,2,6,1,3,5,7], V = 2 + Output: [[2,1],[4,3,6,null,null,5,7]] + Explanation: + Note that root, output[0], and output[1] are TreeNode objects, not arrays. + + The given tree [4,2,6,1,3,5,7] is represented by the following diagram: + + 4 + / \ + 2 6 + / \ / \ + 1 3 5 7 + + while the diagrams for the outputs are: + + 4 + / \ + 3 6 and 2 + / \ / + 5 7 1 + Note: + + The size of the BST will not exceed 50. + The BST is always valid and each node's value is different. + + Solution: O(N) if a current node is <= to key then the current node and its child nodes form the left sub-tree. Split + the right node further recursively + */ +public class SplitBST { + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + TreeNode root = new TreeNode(4); + root.left = new TreeNode(2); + root.left.left = new TreeNode(1); + root.left.right = new TreeNode(3); + root.right = new TreeNode(6); + root.right.left = new TreeNode(5); + root.right.right = new TreeNode(7); + root.right.right.right = new TreeNode(9); + TreeNode[] result = new SplitBST().splitBST(root, 3); + } + + public TreeNode[] splitBST(TreeNode root, int V) { + if(root == null){ + return new TreeNode[] {null, null}; + } else{ + TreeNode[] result = new TreeNode[2]; + if(root.val <= V){ + result[0] = root; + TreeNode[] right = splitBST(root.right, V); + root.right = right[0]; + result[1] = right[1]; + return result; + } else{ + TreeNode[] left = splitBST(root.left, V); + root.left = left[1]; + result[0] = left[0]; + result[1] = root; + return result; + } + } + } + +} From 1b4142bd2ed9c4931a7bfac722ab7b819bed55b2 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 3 May 2018 19:27:53 +0200 Subject: [PATCH 184/235] Closest Leaf in a Binary Tree - Accepted --- README.md | 1 + .../src/tree/ClosestLeafInABinaryTree.java | 145 ++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 problems/src/tree/ClosestLeafInABinaryTree.java diff --git a/README.md b/README.md index e4f03561..5689ae3a 100644 --- a/README.md +++ b/README.md @@ -309,6 +309,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Minimum Absolute Difference in BST](problems/src/tree/MinimumAbsoluteDifferenceInBST.java) (Medium) - [Equal Tree Partition](problems/src/tree/EqualTreePartition.java) (Medium) - [Split BST](problems/src/tree/SplitBST.java) (Medium) +- [Closest Leaf in a Binary Tree](problems/src/tree/ClosestLeafInABinaryTree.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/ClosestLeafInABinaryTree.java b/problems/src/tree/ClosestLeafInABinaryTree.java new file mode 100644 index 00000000..8a33ac7a --- /dev/null +++ b/problems/src/tree/ClosestLeafInABinaryTree.java @@ -0,0 +1,145 @@ +package tree; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 02/05/2018. + * Given a binary tree where every node has a unique value, and a target key k, find the value of the nearest leaf node to target k in the tree. + + Here, nearest to a leaf means the least number of edges travelled on the binary tree to reach any leaf of the tree. Also, a node is called a leaf if it has no children. + + In the following examples, the input tree is represented in flattened form row by row. The actual root tree given will be a TreeNode object. + + Example 1: + + Input: + root = [1, 3, 2], k = 1 + Diagram of binary tree: + 1 + / \ + 3 2 + + Output: 2 (or 3) + + Explanation: Either 2 or 3 is the nearest leaf node to the target of 1. + Example 2: + + Input: + root = [1], k = 1 + Output: 1 + + Explanation: The nearest leaf node is the root node itself. + Example 3: + + Input: + root = [1,2,3,4,null,null,null,5,null,6], k = 2 + Diagram of binary tree: + 1 + / \ + 2 3 + / + 4 + / + 5 + / + 6 + + Output: 3 + Explanation: The leaf node with value 3 (and not the leaf node with value 6) is nearest to the node with value 2. + Note: + root represents a binary tree with at least 1 node and at most 1000 nodes. + Every node has a unique node.val in range [1, 1000]. + There exists some node in the given binary tree for which node.val == k. + + Solution: O(N): Maintain a hashmap of distances from each node in the first iteration. In the second iteration, + find the key value node and then calculate distance from each node during backtrack. + */ +public class ClosestLeafInABinaryTree { + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + private static class Pair{ + int n, d; + Pair(int n, int d){ + this.n = n; + this.d = d; + } + } + + private Map map; + private Pair minNode; + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + TreeNode root = new TreeNode(1); + root.left = new TreeNode(2); + root.right = new TreeNode(3); + root.left.left = new TreeNode(4); + root.left.left.left = new TreeNode(5); + root.left.left.left.left = new TreeNode(6); + //root.right = new TreeNode(3); + System.out.println(new ClosestLeafInABinaryTree().findClosestLeaf(root, 2)); + } + + public int findClosestLeaf(TreeNode root, int k) { + map = new HashMap<>(); + minNode = new Pair(-1, Integer.MAX_VALUE); + findDistanceToLeaf(root); + findMin(root, k); + return minNode.n; + } + + private Pair findDistanceToLeaf(TreeNode node){ + if(node != null){ + if(node.left == null && node.right == null){ + map.put(node.val, new Pair(node.val, 0)); + return new Pair(node.val, 1); + } else { + Pair left = findDistanceToLeaf(node.left); + Pair right = findDistanceToLeaf(node.right); + if(left.d < right.d){ + map.put(node.val, left); + return new Pair(left.n, left.d + 1); + } else{ + map.put(node.val, right); + return new Pair(right.n, right.d + 1); + } + } + } return new Pair(-1, Integer.MAX_VALUE); + } + + private int findMin(TreeNode node, int k){ + if(node != null){ + if(node.val == k){ + if(map.get(node.val).d < minNode.d){ + minNode = map.get(node.val); + } + return 1; + } else{ + int left = findMin(node.left, k); + int right = findMin(node.right, k); + if(left != -1){ + if((left + map.get(node.val).d) < minNode.d){ + minNode = new Pair(map.get(node.val).n, (left + map.get(node.val).d)); + } + return left + 1; + } + else if(right != -1){ + if((right + map.get(node.val).d) < minNode.d){ + minNode = new Pair(map.get(node.val).n, (right + map.get(node.val).d)); + } + return right + 1; + } + } + } + return -1; + } +} From 365b47a369425690e291503d35d4a85df260f356 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 3 May 2018 23:49:04 +0200 Subject: [PATCH 185/235] Maximum Width of Binary Tree - Accepted --- README.md | 1 + .../src/tree/MaximumWidthOfBinaryTree.java | 102 ++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 problems/src/tree/MaximumWidthOfBinaryTree.java diff --git a/README.md b/README.md index 5689ae3a..ff46d023 100644 --- a/README.md +++ b/README.md @@ -310,6 +310,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Equal Tree Partition](problems/src/tree/EqualTreePartition.java) (Medium) - [Split BST](problems/src/tree/SplitBST.java) (Medium) - [Closest Leaf in a Binary Tree](problems/src/tree/ClosestLeafInABinaryTree.java) (Medium) +- [Maximum Width of Binary Tree](problems/src/tree/MaximumWidthOfBinaryTree.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/MaximumWidthOfBinaryTree.java b/problems/src/tree/MaximumWidthOfBinaryTree.java new file mode 100644 index 00000000..4ca38690 --- /dev/null +++ b/problems/src/tree/MaximumWidthOfBinaryTree.java @@ -0,0 +1,102 @@ +package tree; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by gouthamvidyapradhan on 03/05/2018. + * 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. + + The width of one level is defined as the length between the end-nodes (the leftmost and right most non-null nodes in the level, where the null nodes between the end-nodes are also counted into the length calculation. + + Example 1: + Input: + + 1 + / \ + 3 2 + / \ \ + 5 3 9 + + Output: 4 + Explanation: The maximum width existing in the third level with the length 4 (5,3,null,9). + Example 2: + Input: + + 1 + / + 3 + / \ + 5 3 + + Output: 2 + Explanation: The maximum width existing in the third level with the length 2 (5,3). + Example 3: + Input: + + 1 + / \ + 3 2 + / + 5 + + Output: 2 + Explanation: The maximum width existing in the second level with the length 2 (3,2). + Example 4: + Input: + + 1 + / \ + 3 2 + / \ + 5 9 + / \ + 6 7 + Output: 8 + Explanation:The maximum width existing in the fourth level with the length 8 (6,null,null,null,null,null,null,7). + + + Solution: O(N): General idea is to give a position value to each node. + On every left traversal give the value curr_pos * 2 and on every right traversal give the value curr_pos * 2 + 1 + Calculate maximum width for each level using right - left + 1 + */ +public class MaximumWidthOfBinaryTree { + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + private Map> map; + public static void main(String[] args) { + + } + + public int widthOfBinaryTree(TreeNode root) { + map = new HashMap<>(); + preorder(root, 1, 1); + int max = 0; + for(int k : map.keySet()){ + List list = map.get(k); + if(list.size() == 1){ + max = Math.max(max, 1); + } else { + max = Math.max(max, list.get(list.size() - 1) - list.get(0) + 1); + } + } + return max; + } + + private void preorder(TreeNode node, int level, int pos){ + if(node != null){ + preorder(node.left, level + 1, pos * 2); + map.putIfAbsent(level, new ArrayList<>()); + map.get(level).add(pos); + preorder(node.right, level + 1, pos * 2 + 1); + } + } + +} From d3d503a0eda9ed006b6944ca866239dc17a40343 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 4 May 2018 17:45:01 +0200 Subject: [PATCH 186/235] Accepted problems --- README.md | 3 + problems/src/array/CardFilipGame.java | 65 +++++++++++++++++++ .../LargestSumOfAverages.java | 65 +++++++++++++++++++ .../src/hashing/ShortEncodingOfWords.java | 64 ++++++++++++++++++ 4 files changed, 197 insertions(+) create mode 100644 problems/src/array/CardFilipGame.java create mode 100644 problems/src/dynamic_programming/LargestSumOfAverages.java create mode 100644 problems/src/hashing/ShortEncodingOfWords.java diff --git a/README.md b/README.md index ff46d023..2af10a50 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Minimum Moves to Equal Array Elements II](problems/src/array/MinimumMovesToEqualArray.java) (Median) - [Image Smoother](problems/src/array/ImageSmoother.java) (Easy) - [Minimum Index Sum of Two Lists](problems/src/array/MinimumIndexSumOfTwoLists.java) (Easy) +- [Card Flipping Game](problems/src/array/CardFilipGame.java) (Medium) #### [Backtracking](problems/src/backtracking) @@ -168,6 +169,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Palindrome Pairs](problems/src/dynamic_programming/PalindromePairs.java) (Hard) - [Cherry Pickup](problems/src/dynamic_programming/CherryPickup.java) (Hard) - [Knight Probability in Chessboard](problems/src/dynamic_programming/KnightProbabilityInChessboard.java) (Medium) +- [Largest Sum of Averages](problems/src/dynamic_programming/LargestSumOfAverages.java) (Medium) #### [Greedy](problems/src/greedy) @@ -195,6 +197,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Brick Wall](problems/src/hashing/BrickWall.java) (Medium) - [Partition Labels](problems/src/hashing/PartitionLabels.java) (Medium) - [Custom Sort String](problems/src/hashing/CustomSortString.java) (Medium) +- [Short Encoding of Words](problems/src/hashing/ShortEncodingOfWords.java) (Medium) #### [Heap](problems/src/heap) diff --git a/problems/src/array/CardFilipGame.java b/problems/src/array/CardFilipGame.java new file mode 100644 index 00000000..ede311ad --- /dev/null +++ b/problems/src/array/CardFilipGame.java @@ -0,0 +1,65 @@ +package array; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Created by gouthamvidyapradhan on 04/05/2018. + * + * On a table are N cards, with a positive integer printed on the front and back of each card (possibly different). + + We flip any number of cards, and after we choose one card. + + If the number X on the back of the chosen card is not on the front of any card, then this number X is good. + + What is the smallest number that is good? If no number is good, output 0. + + Here, fronts[i] and backs[i] represent the number on the front and back of card i. + + A flip swaps the front and back numbers, so the value on the front is now on the back and vice versa. + + Example: + + Input: fronts = [1,2,4,4,7], backs = [1,3,4,1,3] + Output: 2 + Explanation: If we flip the second card, the fronts are [1,3,4,4,7] and the backs are [1,2,4,1,3]. + We choose the second card, which has number 2 on the back, and it isn't on the front of any card, so 2 is good. + + + Note: + + 1 <= fronts.length == backs.length <= 1000. + 1 <= fronts[i] <= 2000. + 1 <= backs[i] <= 2000. + + */ +public class CardFilipGame { + + public static void main(String[] args) { + + } + + public int flipgame(int[] fronts, int[] backs) { + List numbers = new ArrayList<>(); + for(int i = 0; i < fronts.length; i ++){ + numbers.add(fronts[i]); + numbers.add(backs[i]); + } + Collections.sort(numbers); + for(int n : numbers){ + boolean success = true; + for(int i = 0; i < fronts.length; i ++){ + if(n == fronts[i] && n == backs[i]){ + success = false; + break; + } + } + if(success){ + return n; + } + } + return 0; + } + +} diff --git a/problems/src/dynamic_programming/LargestSumOfAverages.java b/problems/src/dynamic_programming/LargestSumOfAverages.java new file mode 100644 index 00000000..11f149c7 --- /dev/null +++ b/problems/src/dynamic_programming/LargestSumOfAverages.java @@ -0,0 +1,65 @@ +package dynamic_programming; +/** + * Created by gouthamvidyapradhan on 04/05/2018. + * We partition a row of numbers A into at most K adjacent (non-empty) groups, then our score is the sum of the average of each group. What is the largest score we can achieve? + + Note that our partition must use every number in A, and that scores are not necessarily integers. + + Example: + Input: + A = [9,1,2,3,9] + K = 3 + Output: 20 + Explanation: + The best choice is to partition A into [9], [1, 2, 3], [9]. The answer is 9 + (1 + 2 + 3) / 3 + 9 = 20. + We could have also partitioned A into [9, 1], [2], [3, 9], for example. + That partition would lead to a score of 5 + 2 + 6 = 13, which is worse. + + + Note: + + 1 <= A.length <= 100. + 1 <= A[i] <= 10000. + 1 <= K <= A.length. + Answers within 10^-6 of the correct answer will be accepted as correct. + + Solution: O(N x N x K): Calculate average for each sub-array starting from the right. + */ + +public class LargestSumOfAverages { + + public static void main(String[] args) { + int[] A = {9,1,2,3,9}; + System.out.println(new LargestSumOfAverages().largestSumOfAverages(A, 3)); + } + + public double largestSumOfAverages(int[] A, int K) { + double[][] dp = new double[K][A.length]; + for(int i = dp[0].length - 1; i >= 0; i --){ + dp[0][i] = A[i]; + if(i + 1 < dp[0].length){ + dp[0][i] += dp[0][i + 1]; + } + } + + for(int i = dp[0].length - 1, j = 1; i >= 0; i --, j++){ + dp[0][i] = dp[0][i] / j; + } + + for(int i = dp[0].length - 1; i >= 0; i --){ + for(int j = 1; j < dp.length; j ++){ + double sum = 0.0D; + for(int k = i, c = 1; k < dp[0].length; k ++, c++){ + sum += A[k]; + if(k + 1 < dp[0].length){ + double avg = sum / c; + avg += dp[j - 1][k + 1]; + dp[j][i] = Math.max(dp[j][i], avg); + } + } + } + } + return dp[K-1][0]; + } + +} diff --git a/problems/src/hashing/ShortEncodingOfWords.java b/problems/src/hashing/ShortEncodingOfWords.java new file mode 100644 index 00000000..c9d2a556 --- /dev/null +++ b/problems/src/hashing/ShortEncodingOfWords.java @@ -0,0 +1,64 @@ +package hashing; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 04/05/2018. + * Given a list of words, we may encode it by writing a reference string S and a list of indexes A. + + For example, if the list of words is ["time", "me", "bell"], we can write it as S = "time#bell#" and indexes = [0, + 2, 5]. + + Then for each index, we will recover the word by reading from the reference string from that index until we reach a + "#" character. + + What is the length of the shortest reference string S possible that encodes the given words? + + Example: + + Input: words = ["time", "me", "bell"] + Output: 10 + Explanation: S = "time#bell#" and indexes = [0, 2, 5]. + Note: + + 1 <= words.length <= 2000. + 1 <= words[i].length <= 7. + Each word has only lowercase letters. + + Solution: Sort the words by length and then use a hashmap to map each substring of a string with its position. + */ +public class ShortEncodingOfWords { + class Node { + String s; + int l; + Node(String s, int l){ + this.s = s; + this.l = l; + } + } + + public static void main(String[] args) { + String[] A = {"memo", "me", "mo"}; + System.out.println(new ShortEncodingOfWords().minimumLengthEncoding(A)); + } + + public int minimumLengthEncoding(String[] words) { + List list = new ArrayList<>(); + for(String w : words){ + list.add(new Node(w, w.length())); + } + Collections.sort(list, (o1, o2) -> Integer.compare(o2.l, o1.l)); + Map map = new HashMap<>(); + int count = 0; + for(Node node : list){ + String str = node.s; + if(!map.containsKey(str)){ + for(int i = 0, l = str.length(); i < l; i++){ + map.put(str.substring(i, l), count + i); + } + count += (str.length() + 1); + } + } + return count; + } +} From 1789610e4ea469c7e9e403d0ae512883df22310a Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 23 Jun 2018 13:19:33 +0200 Subject: [PATCH 187/235] Couples Holding Hands --- README.md | 1 + problems/src/math/CouplesHoldingHands.java | 81 ++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 problems/src/math/CouplesHoldingHands.java diff --git a/README.md b/README.md index 2af10a50..d745d735 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Bulb Switcher II](problems/src/math/BulbSwitcherII.java) (Medium) - [Global and Local Inversions](problems/src/math/GlobalAndLocalInversions.java) (Medium) - [Solve the Equation](problems/src/math/SolveTheEquation.java) (Medium) +- [Couples Holding Hands](problems/src/math/CouplesHoldingHands.java) (Hard) #### [Reservoir Sampling](problems/src/reservoir_sampling) diff --git a/problems/src/math/CouplesHoldingHands.java b/problems/src/math/CouplesHoldingHands.java new file mode 100644 index 00000000..7a1a8906 --- /dev/null +++ b/problems/src/math/CouplesHoldingHands.java @@ -0,0 +1,81 @@ +package math; + +/** + * Created by gouthamvidyapradhan on 23/06/2018. + * N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum number of swaps so + * that every couple is sitting side by side. A swap consists of choosing any two people, then they stand up and + * switch seats. + + The people and seats are represented by an integer from 0 to 2N-1, the couples are numbered in order, the first + couple being (0, 1), the second couple being (2, 3), and so on with the last couple being (2N-2, 2N-1). + + The couples' initial seating is given by row[i] being the value of the person who is initially sitting in the i-th + seat. + + Example 1: + + Input: row = [0, 2, 1, 3] + Output: 1 + Explanation: We only need to swap the second (row[1]) and third (row[2]) person. + Example 2: + + Input: row = [3, 2, 0, 1] + Output: 0 + Explanation: All couples are already seated side by side. + Note: + + len(row) is even and in the range of [4, 60]. + row is guaranteed to be a permutation of 0...len(row)-1. + + Solution: O(N ^ 2). Find the index i of every even-number n and (n + 1)th number. If the index i of number n is even + then swap the number (n + 1) with index i + 1, else swap the number (n + 1) with index i - 1. Count the total swaps + and return the answer. + */ +public class CouplesHoldingHands { + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {1, 3, 4, 0, 2, 5}; + System.out.println(new CouplesHoldingHands().minSwapsCouples(A)); + } + + public int minSwapsCouples(int[] row) { + int N = row.length; + int count = 0; + for(int i = 0; i < N; i +=2){ + int pos = find(row, i); + if((pos % 2) == 0){ + if(row[pos + 1] != i + 1){ + int nexNumPos = find(row, i + 1); + swap(row, pos + 1, nexNumPos); + count ++; + } + } else{ + if(row[pos - 1] != i + 1){ + int nexNumPos = find(row, i + 1); + swap(row, pos - 1, nexNumPos); + count ++; + } + } + } + return count; + } + + private int find(int[] A, int n){ + for(int i = 0; i < A.length; i ++){ + if(A[i] == n){ + return i; + } + } + return -1; + } + + private void swap(int[] A, int i, int j){ + int temp = A[i]; + A[i] = A[j]; + A[j] = temp; + } +} From a91dda6711777d8830477d5a385a03d82e7142f4 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 23 Jun 2018 13:36:10 +0200 Subject: [PATCH 188/235] Cut Off Trees for Golf Event --- README.md | 1 + .../CutOffTreesForGolfEvent.java | 129 ++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 problems/src/breadth_first_search/CutOffTreesForGolfEvent.java diff --git a/README.md b/README.md index d745d735..225008b9 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Word Ladder II](problems/src/breadth_first_search/WordLadderII.java) (Hard) - [Walls and Gates](problems/src/breadth_first_search/WallsAndGates.java) (Medium) - [Open the lock](problems/src/breadth_first_search/OpenTheLock.java) (Medium) +- [Cut Off Trees for Golf Event](problems/src/breadth_first_search/CutOffTreesForGolfEvent.java) (Hard) #### [Depth First Search](problems/src/depth_first_search) diff --git a/problems/src/breadth_first_search/CutOffTreesForGolfEvent.java b/problems/src/breadth_first_search/CutOffTreesForGolfEvent.java new file mode 100644 index 00000000..388550ff --- /dev/null +++ b/problems/src/breadth_first_search/CutOffTreesForGolfEvent.java @@ -0,0 +1,129 @@ +package breadth_first_search; +import java.util.*; +/** + * Created by gouthamvidyapradhan on 23/06/2018. + * + * You are asked to cut off trees in a forest for a golf event. The forest is represented as a non-negative 2D map, + * in this map: + + 0 represents the obstacle can't be reached. + 1 represents the ground can be walked through. + The place with number bigger than 1 represents a tree can be walked through, and this positive number represents the + tree's height. + You are asked to cut off all the trees in this forest in the order of tree's height - always cut off the tree with + lowest height first. And after cutting, the original place has the tree will become a grass (value 1). + + You will start from the point (0, 0) and you should output the minimum steps you need to walk to cut off all the + trees. If you can't cut off all the trees, output -1 in that situation. + + You are guaranteed that no two trees have the same height and there is at least one tree needs to be cut off. + + Example 1: + Input: + [ + [1,2,3], + [0,0,4], + [7,6,5] + ] + Output: 6 + Example 2: + Input: + [ + [1,2,3], + [0,0,0], + [7,6,5] + ] + Output: -1 + Example 3: + Input: + [ + [2,3,4], + [0,0,5], + [8,7,6] + ] + Output: 6 + Explanation: You started from the point (0,0) and you can cut off the tree in (0,0) directly without walking. + Hint: size of the given matrix will not exceed 50x50. + + + Solution: O(N x M) ^ 2: Bfs to each height starting from 1 and calculate the total sum of distance. + */ +public class CutOffTreesForGolfEvent { + + public static void main(String[] args) throws Exception{ + + } + + private static final int[] R = {0, 0, 1, -1}; + private static final int[] C = {1, -1, 0, 0}; + + static class Cell implements Comparable{ + int r, c; + int distance; + int height; + Cell(int r, int c){ + this.r = r; + this.c = c; + } + @Override + public int compareTo(Cell o) { + return Integer.compare(this.height, o.height); + } + } + + public int cutOffTree(List> forest) { + int distance = 0; + List trees = new ArrayList<>(); + for(int i = 0; i < forest.size(); i ++){ + for(int j = 0; j < forest.get(0).size(); j ++) { + if(forest.get(i).get(j) > 1){ + Cell cell = new Cell(i, j); + cell.height = forest.get(i).get(j); + trees.add(cell); + } + } + } + Collections.sort(trees); + int sR = 0, sC = 0; + for(Cell t : trees){ + int dist = bfs(forest, t.height, sR, sC); + if(dist == -1) return -1; + else distance += dist; + sR = t.r; + sC = t.c; + } + return distance; + } + + private int bfs(List> forest, int target, int sR, int sC){ + if(forest.get(sR).get(sC) == target) { + forest.get(sR).set(sC, 1); + return 0; + } + Cell start = new Cell(sR, sC); + start.distance = 0; + Queue queue = new ArrayDeque<>(); + queue.add(start); + boolean[][] done = new boolean[forest.size()][forest.get(0).size()]; + done[sR][sC] = true; + while(!queue.isEmpty()){ + Cell cell = queue.poll(); + for(int i = 0; i < 4; i ++){ + int newR = cell.r + R[i]; + int newC = cell.c + C[i]; + Cell newCell = new Cell(newR, newC); + if(newR >= 0 && newR < forest.size() && newC >= 0 && newC < forest.get(0).size() && + forest.get(newR).get(newC) != 0 && !done[newCell.r][newCell.c]) { + newCell.distance = cell.distance + 1; + if(forest.get(newR).get(newC) == target){ + forest.get(newR).set(newC, 1); + return newCell.distance; + } + done[newCell.r][newCell.c] = true; + queue.offer(newCell); + } + } + } + return -1; + } +} From 9d8ce18cc1e382b91dcaede7805801919d2fa586 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 24 Jun 2018 13:34:59 +0200 Subject: [PATCH 189/235] Smallest Rectangle Enclosing Black Pixels --- README.md | 1 + ...SmallestRectangleEnclosingBlackPixels.java | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java diff --git a/README.md b/README.md index 225008b9..038aa930 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Island Perimeter](problems/src/depth_first_search/IslandPerimeter.java) (Easy) - [Number of Distinct Islands](problems/src/depth_first_search/NumberOfDistinctIslands.java) (Medium) - [Number of Distinct Islands II](problems/src/depth_first_search/NumberOfDistinctIslandsII.java) (Hard) +- [Smallest Rectangle Enclosing Black Pixels](problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java) (Hard) #### [Design](problems/src/design) diff --git a/problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java b/problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java new file mode 100644 index 00000000..a1b012d0 --- /dev/null +++ b/problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java @@ -0,0 +1,63 @@ +package depth_first_search; + +/** + * Created by gouthamvidyapradhan on 24/06/2018. + * An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. The black pixels are + * connected, i.e., there is only one black region. Pixels are connected horizontally and vertically. Given the + * location (x, y) of one of the black pixels, return the area of the smallest (axis-aligned) rectangle that + * encloses all black pixels. + + Example: + + Input: + [ + "0010", + "0110", + "0100" + ] + and x = 0, y = 2 + + Output: 6 + + Solution: O(n x m) do a dfs and keep track of min and max length-breadth. Return the product of l x b + */ +public class SmallestRectangleEnclosingBlackPixels { + private final int[] R = {1, -1, 0, 0}; + private final int[] C = {0, 0, -1, 1}; + private boolean[][] done; + private int maxR, minR, minC, maxC; + public static void main(String[] args) { + char[][] A = {{'0', '0', '1', '1'}, {'0', '1', '1', '0'}, {'0', '1', '0', '0'}}; + System.out.println(new SmallestRectangleEnclosingBlackPixels().minArea(A, 0, 2)); + } + + public int minArea(char[][] image, int x, int y) { + done = new boolean[image.length][image[0].length]; + maxR = 0; maxC = 0; minR = Integer.MAX_VALUE; minC = Integer.MAX_VALUE; + maxR = Math.max(maxR, x); + minR = Math.min(minR, x); + + maxC = Math.max(maxC, y); + minC = Math.min(minC, y); + dfs(image, x, y); + return ((maxR - minR) + 1) * ((maxC - minC) + 1); + } + + private void dfs(char[][] image, int r, int c){ + done[r][c] = true; + for(int i = 0; i < 4; i ++){ + int newR = r + R[i]; + int newC = c + C[i]; + if(newR >=0 && newR < image.length && newC >= 0 && newC < image[0].length && !done[newR][newC]){ + if(image[newR][newC] == '1'){ + maxR = Math.max(maxR, newR); + minR = Math.min(minR, newR); + + maxC = Math.max(maxC, newC); + minC = Math.min(minC, newC); + dfs(image, newR, newC); + } + } + } + } +} From 23395a1da9f15570350bda29704c08ca02810084 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 30 Jun 2018 14:22:18 +0200 Subject: [PATCH 190/235] Reverse Pairs --- README.md | 1 + .../src/divide_and_conquer/ReversePairs.java | 121 ++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 problems/src/divide_and_conquer/ReversePairs.java diff --git a/README.md b/README.md index 038aa930..bfd9825e 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ My accepted leetcode solutions to some of the common interview problems. #### [Divide and Conquer](problems/src/divide_and_conquer) - [Kth Largest Element In a Array](problems/src/divide_and_conquer/KthLargestElementInAnArray.java) (Medium) +- [Reverse Pairs](problems/src/divide_and_conquer/ReversePairs.java) (Hard) - [Search in a 2D Matrix](problems/src/divide_and_conquer/SearchA2DMatrix.java) (Medium) #### [Dynamic Programming](problems/src/dynamic_programming) diff --git a/problems/src/divide_and_conquer/ReversePairs.java b/problems/src/divide_and_conquer/ReversePairs.java new file mode 100644 index 00000000..8168e92c --- /dev/null +++ b/problems/src/divide_and_conquer/ReversePairs.java @@ -0,0 +1,121 @@ +package divide_and_conquer; +import java.util.*; +/** + * Created by gouthamvidyapradhan on 30/06/2018. + * Given an array nums, we call (i, j) an important reverse pair if i < j and nums[i] > 2*nums[j]. + + You need to return the number of important reverse pairs in the given array. + + Example1: + + Input: [1,3,2,3,1] + Output: 2 + Example2: + + Input: [2,4,3,5,1] + Output: 3 + Note: + The length of the given array will not exceed 50,000. + All the numbers in the input array are in the range of 32-bit integer. + + Solution: O(n log n): + Example: 1,3,2,3,1 + 1. Sort the array in non-increasing order (if there is a collision, sort by lower index). + So the sorted array will be (3, 3, 2, 1, 1) having indexes (1, 3, 2, 0, 4) + 2. Maintain a prefix sum of index (starting from 1) for the sorted array. So, prefix sum for the above sorted array is + (1, 2, 3, 4, 5) + Now, the basic idea is to iterate from index n - 1 to 0 in the original array and for each element calculate the + element p (num[i] x 2) and find the upper bound of the element p in sorted array which is 3 at index 1 in this case + and add prefix sum of the index 1 to the result. So the result now becomes 2. + + To maintain a prefix sum and update it efficiently we have to use a BIT or Fenwick tree. + + + */ +public class ReversePairs { + + class Pair{ + int i, n; + Pair(int i, int n){ + this.i = i; + this.n = n; + } + int getN(){ + return n; + } + int getI(){ + return i; + } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] A = {2,4,3,5,1}; + System.out.println(new ReversePairs().reversePairs(A)); + } + + public int reversePairs(int[] nums) { + List list = new ArrayList<>(); + Ftree ft = new Ftree(nums.length); + for(int i = 0; i < nums.length; i ++){ + list.add(new Pair(i, nums[i])); + ft.update(i, 1); + } + Collections.sort(list, (Comparator.comparing(Pair::getN).reversed().thenComparing(Pair::getI))); + int[] indexMap = new int[nums.length]; + for(int i = 0, l = list.size(); i < l; i ++){ + indexMap[list.get(i).getI()] = i; + } + int ans = 0; + for(int i = nums.length - 1; i >= 0; i --){ + ft.update(indexMap[i], -1); + int index = binarySearch(list, (long)nums[i] * 2); + if(index > -1){ + ans += ft.getRangeSum(index); + } + } + return ans; + } + + private int binarySearch(List list, long n){ + int l = 0, h = list.size() - 1; + int ans = -1; + while(l <= h){ + int m = l + (h - l) / 2; + if(list.get(m).n > n){ + ans = m; + l = m + 1; + } else{ + h = m - 1; + } + } + return ans; + } + + private class Ftree { + private int[] a; + + Ftree(int n) { + a = new int[n + 1]; + } + + void update(int p, int v) { + for (int i = p + 1; i < a.length; i += (i & (-i))) { + a[i] += v; + } + } + + int getRangeSum(int p) { + int sum = 0; + for (int i = p + 1; i > 0; i -= (i & (-i))) { + sum += a[i]; + } + return sum; + } + + } +} From d6f9d93af30239efeb5e6cbc612245f186c93e43 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 7 Jul 2018 18:18:00 +0200 Subject: [PATCH 191/235] Bricks Falling When Hit --- README.md | 1 + .../BricksFallingWhenHit.java | 239 ++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 problems/src/depth_first_search/BricksFallingWhenHit.java diff --git a/README.md b/README.md index bfd9825e..60b24223 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Number of Distinct Islands](problems/src/depth_first_search/NumberOfDistinctIslands.java) (Medium) - [Number of Distinct Islands II](problems/src/depth_first_search/NumberOfDistinctIslandsII.java) (Hard) - [Smallest Rectangle Enclosing Black Pixels](problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java) (Hard) +- [Bricks Falling When Hit](problems/src/depth_first_search/BricksFallingWhenHit.java) (Hard) #### [Design](problems/src/design) diff --git a/problems/src/depth_first_search/BricksFallingWhenHit.java b/problems/src/depth_first_search/BricksFallingWhenHit.java new file mode 100644 index 00000000..e9e6c6f2 --- /dev/null +++ b/problems/src/depth_first_search/BricksFallingWhenHit.java @@ -0,0 +1,239 @@ +package depth_first_search; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by gouthamvidyapradhan on 01/07/2018. + * We have a grid of 1s and 0s; the 1s in a cell represent bricks. A brick will not drop if and only if it is + * directly connected to the top of the grid, or at least one of its (4-way) adjacent bricks will not drop. + + We will do some erasures sequentially. Each time we want to do the erasure at the location (i, j), the brick (if it + exists) on that location will disappear, and then some other bricks may drop because of that erasure. + + Return an array representing the number of bricks that will drop after each erasure in sequence. + + Example 1: + Input: + grid = [[1,0,0,0],[1,1,1,0]] + hits = [[1,0]] + Output: [2] + Explanation: + If we erase the brick at (1, 0), the brick at (1, 1) and (1, 2) will drop. So we should return 2. + Example 2: + Input: + grid = [[1,0,0,0],[1,1,0,0]] + hits = [[1,1],[1,0]] + Output: [0,0] + Explanation: + When we erase the brick at (1, 0), the brick at (1, 1) has already disappeared due to the last move. So each + erasure will cause no bricks dropping. Note that the erased brick (1, 0) will not be counted as a dropped brick. + + + Note: + + The number of rows and columns in the grid will be in the range [1, 200]. + The number of erasures will not exceed the area of the grid. + It is guaranteed that each erasure will be different from any other erasure, and located inside the grid. + An erasure may refer to a location with no brick - if it does, no bricks drop. + + Solution: O(R x C): Erase all the bricks in the grid and do a union of all the bricks using a union-find disjoint set. + (A modified union-find disjoint set is necessary to keep track of size of the connected component and to check + if its connected to roof or not) + Once you have the different connected components of the grid, solve the problem in the reverse order by + iterating the hits in the reverse order. First set 1 in the grid for each hits and count the connected bricks + in all four directions which are not linked to roof of the grid. + + */ +public class BricksFallingWhenHit { + + private static final int[] R = {0, 0, 1, -1}; + private static final int[] C = {1, -1, 0, 0}; + + /** + * + * @author gouthamvidyapradhan + * Class to represent UnionFind Disjoint Set + * + */ + private static class UnionFind { + private int[] p; + private int[] rank; + private boolean[] roof; + private int[] size; + + UnionFind(int s){ + this.p = new int[s]; + this.rank = new int[s]; + this.size = new int[s]; + this.roof = new boolean[s]; + init(); + } + /** + * Initialize with its same index as its parent + */ + private void init() { + for(int i=0; i rank[y]){ + p[y] = p[x]; + roof[x] = (roof[x] || roof[y]); + size[x] = size[x] + size[y]; + } + else { + p[x] = p[y]; + roof[y] = (roof[x] || roof[y]); + size[y] = size[x] + size[y]; + if(rank[x] == rank[y]){ + rank[y]++; //increment the rank + } + } + return true; + } + return false; + } + + /** + * is attached to roof + * @param i + * @return + */ + public boolean isRoof(int i){ + return roof[findSet(i)]; + } + + /** + * is attached to roof + * @param i + * @return + */ + public int size(int i){ + return size[findSet(i)]; + } + } + + /** + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[][] grid = {{1,1,1,1,1}, {0, 0, 1, 0, 1}, {1, 0, 1, 0, 1}, {1, 1, 1, 0, 1}}; + int[][] hits = {{1,2}, {2,2}, {2, 4}, {0, 4}, {0, 0}}; + int[] r = new BricksFallingWhenHit().hitBricks(grid, hits); + for(int i = 0; i < r.length; i ++){ + System.out.print(r[i] + " "); + } + } + + public int[] hitBricks(int[][] grid, int[][] hits) { + int nR = grid.length; + int nC = grid[0].length; + UnionFind unionFind = new UnionFind((nR * nC) + 1); + for(int i = 0; i < nC; i ++){ + if(grid[0][i] == 1){ + unionFind.setAsRoof(i + 1); + } + } + for(int k = 0; k < hits.length; k++){ + int[] h = hits[k]; + if(grid[h[0]][h[1]] == 0){ + h[0] = -1; + h[1] = -1; + }else{ + grid[h[0]][h[1]] = 0; + } + } + boolean[][] done = new boolean[grid.length][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 && !done[i][j]){ + dfs(i, j, grid, done, unionFind); + } + } + } + int[] result = new int[hits.length]; + for(int i = hits.length - 1; i >= 0; i --){ + int[] h = hits[i]; + int r = h[0]; + int c = h[1]; + if(r == -1) continue; + grid[r][c] = 1; + int cell = (r * nC) + c + 1; + int sum = 0; + List notLinkedToRoof = new ArrayList<>(); + List linkedToRoof = new ArrayList<>(); + for(int k = 0; k < 4; k ++){ + int newR = r + R[k]; + int newC = c + C[k]; + if(newR >=0 && newR < nR && newC >= 0 && newC < nC && grid[newR][newC] == 1){ + int newCell = (newR * nC) + newC + 1; + if(unionFind.isRoof(newCell)){ + linkedToRoof.add(newCell); + } else{ + notLinkedToRoof.add(newCell); + } + } + } + for(int nr : notLinkedToRoof){ + unionFind.union(cell, nr); + } + if(!linkedToRoof.isEmpty() || unionFind.isRoof(cell)){ + sum += (unionFind.size(cell) - 1); + } + for(int rr : linkedToRoof){ + unionFind.union(cell, rr); + } + result[i] = sum; + } + return result; + } + + private void dfs(int r, int c, int[][] grid, boolean[][] done, UnionFind unionFind){ + done[r][c] = true; + int cell = (r * grid[0].length) + c + 1; + for(int i = 0; i < 4; i ++){ + int newR = r + R[i]; + int newC = c + C[i]; + if(newR >= 0 && newR < grid.length && newC >= 0 && newC < grid[0].length){ + if(grid[newR][newC] == 1 && !done[newR][newC]){ + int newCell = (newR * grid[0].length) + newC + 1; + unionFind.union(cell, newCell); + dfs(newR, newC,grid, done, unionFind); + } + } + } + } +} From c71f3bbc2e034a1663e7a41b693aadf0d485b010 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 8 Jul 2018 13:50:02 +0200 Subject: [PATCH 192/235] Longest Valid Parentheses --- README.md | 1 + .../src/stack/LongestValidParentheses.java | 75 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 problems/src/stack/LongestValidParentheses.java diff --git a/README.md b/README.md index 60b24223..440f4ccd 100644 --- a/README.md +++ b/README.md @@ -250,6 +250,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Exclusive Time of Functions](problems/src/stack/ExclusiveTimeOfFunctions.java) (Medium) - [Basic Calculator](problems/src/stack/BasicCalculator.java) (Hard) - [Decode String](problems/src/stack/DecodeString.java) (Medium) +- [Longest Valid Parentheses](problems/src/stack/LongestValidParentheses.java) (Hard) #### [String](problems/src/string) diff --git a/problems/src/stack/LongestValidParentheses.java b/problems/src/stack/LongestValidParentheses.java new file mode 100644 index 00000000..d4d3ae0a --- /dev/null +++ b/problems/src/stack/LongestValidParentheses.java @@ -0,0 +1,75 @@ +package stack; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 08/07/2018. + * Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) + * parentheses substring. + + Example 1: + + Input: "(()" + Output: 2 + Explanation: The longest valid parentheses substring is "()" + Example 2: + + Input: ")()())" + Output: 4 + Explanation: The longest valid parentheses substring is "()()" + + Solution: O(N) Iterate through each of the parentheses and if '(' is encountered push it to stack else check the top + of the stack to see if there is a matching parentheses, if yes pop it and then take the length (currIndex - index at + top of the stack). Maintain a max length and return this as the answer. + */ +public class LongestValidParentheses { + + private class Node{ + char c; + int i; + Node(char c, int i){ + this.c = c; + this.i = i; + } + } + + /** + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new LongestValidParentheses().longestValidParentheses("((()()(((())))))")); + } + + public int longestValidParentheses(String s) { + Stack stack = new Stack<>(); + int max = 0; + for(int i = 0, l = s.length(); i < l; i ++){ + char c = s.charAt(i); + switch (c){ + case '(': + stack.push(new Node(c, i)); + break; + + case ')': + if(!stack.isEmpty()){ + if(stack.peek().c == '('){ + stack.pop(); + if(stack.isEmpty()){ + max = Math.max(max, i + 1); + } else { + max = Math.max(max, i - stack.peek().i); + } + } else{ + stack.push(new Node(c, i)); + } + } else{ + stack.push(new Node(c, i)); + } + } + } + return max; + } + +} From 4035cda4ee2feb74d4f985b690de2e3e3cebb8a3 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 14 Jul 2018 13:49:31 +0200 Subject: [PATCH 193/235] Reaching Points --- README.md | 1 + problems/src/math/ReachingPoints.java | 88 +++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 problems/src/math/ReachingPoints.java diff --git a/README.md b/README.md index 440f4ccd..3f1f3e1b 100644 --- a/README.md +++ b/README.md @@ -235,6 +235,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Global and Local Inversions](problems/src/math/GlobalAndLocalInversions.java) (Medium) - [Solve the Equation](problems/src/math/SolveTheEquation.java) (Medium) - [Couples Holding Hands](problems/src/math/CouplesHoldingHands.java) (Hard) +- [Reaching Points](problems/src/math/ReachingPoints.java) (Hard) #### [Reservoir Sampling](problems/src/reservoir_sampling) diff --git a/problems/src/math/ReachingPoints.java b/problems/src/math/ReachingPoints.java new file mode 100644 index 00000000..40b47bf8 --- /dev/null +++ b/problems/src/math/ReachingPoints.java @@ -0,0 +1,88 @@ +package math; + +/** + * Created by gouthamvidyapradhan on 14/07/2018. + * A move consists of taking a point (x, y) and transforming it to either (x, x+y) or (x+y, y). + + Given a starting point (sx, sy) and a target point (tx, ty), return True if and only if a sequence of moves exists + to transform the point (sx, sy) to (tx, ty). Otherwise, return False. + + Examples: + Input: sx = 1, sy = 1, tx = 3, ty = 5 + Output: True + Explanation: + One series of moves that transforms the starting point to the target is: + (1, 1) -> (1, 2) + (1, 2) -> (3, 2) + (3, 2) -> (3, 5) + + Input: sx = 1, sy = 1, tx = 2, ty = 2 + Output: False + + Input: sx = 1, sy = 1, tx = 1, ty = 1 + Output: True + + Note: + + sx, sy, tx, ty will all be integers in the range [1, 10^9]. + + Solution: Start from the target, reduce the target value to start value. + If at any stage the target value goes below start value then there exist no solution hence return false. + */ +public class ReachingPoints { + + class Pair{ + int x, y; + Pair(int x, int y){ + this.x = x; + this.y = y; + } + } + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new ReachingPoints().reachingPoints(1, 1, 153, 10)); + } + + public boolean reachingPoints(int sx, int sy, int tx, int ty) { + Pair target = new Pair(tx, ty); + Pair start = new Pair(sx, sy); + while(true){ + if(start.x == target.x && start.y == target.y){ + return true; + } else if(start.x > target.x || start.y > target.y || target.x == target.y){ + return false; + } else if(start.x == target.x){ + int t = target.y - start.y; + return (t % target.x) == 0; + } else if(start.y == target.y){ + int t = target.x - start.x; + return (t % target.y) == 0; + } else{ + if(target.x > target.y){ + int[] R = reduce(target.x, target.y); + target.x = R[0]; + target.y = R[1]; + } else { + int[] R = reduce(target.y, target.x); + target.x = R[1]; + target.y = R[0]; + } + } + } + } + + private int[] reduce(int x, int y){ + int t = x - y; + int q = t / y; + x -= (y * q); + if((t % y) != 0){ + x -= y; + } + return new int[]{x, y}; + } +} From 243f142579e42c811ea004a905025dd00a34c4f2 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 21 Jul 2018 22:17:11 +0200 Subject: [PATCH 194/235] Shortest Palindrome --- README.md | 1 + problems/src/string/ShortestPalindrome.java | 61 +++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 problems/src/string/ShortestPalindrome.java diff --git a/README.md b/README.md index 3f1f3e1b..29a070b2 100644 --- a/README.md +++ b/README.md @@ -280,6 +280,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Longest Common Prefix](problems/src/string/LongestCommonPrefix.java) (Easy) - [Find the Closest Palindrome](problems/src/string/FindTheClosestPalindrome.java) (Hard) - [Monotone Increasing Digits](problems/src/string/MonotoneIncreasingDigits.java) (Medium) +- [Shortest Palindrome](problems/src/string/ShortestPalindrome.java) (Hard) #### [Tree](problems/src/tree) diff --git a/problems/src/string/ShortestPalindrome.java b/problems/src/string/ShortestPalindrome.java new file mode 100644 index 00000000..6b07e66b --- /dev/null +++ b/problems/src/string/ShortestPalindrome.java @@ -0,0 +1,61 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 21/07/2018. + * + * Given a string s, you are allowed to convert it to a palindrome by adding characters in front of it. Find and + * return the shortest palindrome you can find by performing this transformation. + + Example 1: + + Input: "aacecaaa" + Output: "aaacecaaa" + Example 2: + + Input: "abcd" + Output: "dcbabcd" + + Solution: O(N ^ 2): for i : (s.length() - 1 -> 0) check if (0, i) is a paliandrome, if not append char at i to + result string else return string (result + (0, i)) + */ +public class ShortestPalindrome { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + System.out.println(new ShortestPalindrome().shortestPalindrome("aaaaaaaaaa")); + } + + public String shortestPalindrome(String s) { + if(s.length() == 0 || s.length() == 1){ + return s; + } else if(s.length() == 2){ + if(s.charAt(0) == s.charAt(1)){ + return s; + } else{ + return (s.charAt(1) + s); + } + } + if(isPaliandrome(s, 0, s.length() - 1)) return s; + StringBuilder sb = new StringBuilder(""); + for(int i = 0, j = s.length() - 1; j >= i; j--){ + if(!isPaliandrome(s, i, j)){ + sb.append(s.charAt(j)); + } else{ + sb.append(s.substring(0, s.length())); + break; + } + } + return sb.toString(); + } + + boolean isPaliandrome(String s, int x, int y){ + for(int i = x, j = y; i < j; i++, j--){ + if(s.charAt(i) != s.charAt(j)) return false; + } + return true; + } +} From 36a9dbfde98bf72dbd944462d69fb2ecc8f1061e Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 24 Jul 2018 02:18:29 +0200 Subject: [PATCH 195/235] Minimum Number of Refueling Stops --- README.md | 1 + .../MinimumNumberOfRefuelingStops.java | 87 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java diff --git a/README.md b/README.md index 29a070b2..aa324322 100644 --- a/README.md +++ b/README.md @@ -174,6 +174,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Cherry Pickup](problems/src/dynamic_programming/CherryPickup.java) (Hard) - [Knight Probability in Chessboard](problems/src/dynamic_programming/KnightProbabilityInChessboard.java) (Medium) - [Largest Sum of Averages](problems/src/dynamic_programming/LargestSumOfAverages.java) (Medium) +- [Minimum Number of Refueling Stops](problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java) (Hard) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java b/problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java new file mode 100644 index 00000000..4c28dd8b --- /dev/null +++ b/problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java @@ -0,0 +1,87 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 24/07/2018. + * A car travels from a starting position to a destination which is target miles east of the starting position. + + Along the way, there are gas stations. Each station[i] represents a gas station that is station[i][0] miles east + of the starting position, and has station[i][1] liters of gas. + + The car starts with an infinite tank of gas, which initially has startFuel liters of fuel in it. It uses 1 liter of + gas per 1 mile that it drives. + + When the car reaches a gas station, it may stop and refuel, transferring all the gas from the station into the car. + + What is the least number of refueling stops the car must make in order to reach its destination? If it cannot reach + the destination, return -1. + + Note that if the car reaches a gas station with 0 fuel left, the car can still refuel there. If the car reaches the + destination with 0 fuel left, it is still considered to have arrived. + + + + Example 1: + + Input: target = 1, startFuel = 1, stations = [] + Output: 0 + Explanation: We can reach the target without refueling. + Example 2: + + Input: target = 100, startFuel = 1, stations = [[10,100]] + Output: -1 + Explanation: We can't reach the target (or even the first gas station). + Example 3: + + Input: target = 100, startFuel = 10, stations = [[10,60],[20,30],[30,30],[60,40]] + Output: 2 + Explanation: + We start with 10 liters of fuel. + We drive to position 10, expending 10 liters of fuel. We refuel from 0 liters to 60 liters of gas. + Then, we drive from position 10 to position 60 (expending 50 liters of fuel), + and refuel from 10 liters to 50 liters of gas. We then drive to and reach the target. + We made 2 refueling stops along the way, so we return 2. + + + Note: + + 1 <= target, startFuel, stations[i][1] <= 10^9 + 0 <= stations.length <= 500 + 0 < stations[0][0] < stations[1][0] < ... < stations[stations.length-1][0] < target + + Solution O(N ^ 2): Maintain a DP array with maximum distance that can be travelled with i stops. + DP[i] is the max distance that can be travelled with exactly i stops. + The minimum i where the target can be achieved (dp[i] >= target) will be the answer. + */ +public class MinimumNumberOfRefuelingStops { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int target = 100, startFuel = 10; + int[][] stations = {{10,60},{20,30},{30,30},{60,40}}; + System.out.println(new MinimumNumberOfRefuelingStops().minRefuelStops(target, startFuel, stations)); + } + + public int minRefuelStops(int target, int startFuel, int[][] stations) { + long[] dp = new long[stations.length + 1]; + dp[0] = startFuel; + for(int i = 0; i < stations.length; i ++){ + int d = stations[i][0]; + int f = stations[i][1]; + for(int j = i; j >= 0; j --){ + if(dp[j] >= d){ + dp[j + 1] = Math.max(dp[j + 1], dp[j] + f); + } + } + } + for(int i = 0; i < dp.length; i ++){ + if(dp[i] >= target){ + return i; + } + } + return -1; + } + +} From 45229bd6e12971ad31db77a7ec8a5c371f7bc536 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 27 Jul 2018 01:06:33 +0200 Subject: [PATCH 196/235] Candy --- README.md | 1 + problems/src/heap/Candy.java | 92 ++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 problems/src/heap/Candy.java diff --git a/README.md b/README.md index aa324322..d27cce48 100644 --- a/README.md +++ b/README.md @@ -210,6 +210,7 @@ My accepted leetcode solutions to some of the common interview problems. - [The Skyline Problem](problems/src/heap/TheSkylineProblem.java) (Hard) - [Meeting Rooms II](problems/src/heap/MeetingRoomsII.java) (Medium) - [Top K Frequent Words](problems/src/heap/TopKFrequentWords.java) (Medium) +- [Candy](problems/src/heap/Candy.java) (Hard) #### [Linked List](problems/src/linked_list) diff --git a/problems/src/heap/Candy.java b/problems/src/heap/Candy.java new file mode 100644 index 00000000..26a52fae --- /dev/null +++ b/problems/src/heap/Candy.java @@ -0,0 +1,92 @@ +package heap; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 26/07/2018. + * There are N children standing in a line. Each child is assigned a rating value. + + You are giving candies to these children subjected to the following requirements: + + Each child must have at least one candy. + Children with a higher rating get more candies than their neighbors. + What is the minimum candies you must give? + + Example 1: + + Input: [1,0,2] + Output: 5 + Explanation: You can allocate to the first, second and third child with 2, 1, 2 candies respectively. + Example 2: + + Input: [1,2,2] + Output: 4 + Explanation: You can allocate to the first, second and third child with 1, 2, 1 candies respectively. + The third child gets 1 candy because it satisfies the above two conditions. + + Solution: O(N log N): Store the indexes in a heap, iterate through the heap one by one and assign candies one + greater than its neighbours. Take care of edge cases. + + */ +public class Candy { + + /** + * Main method + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception{ + int[] ratings = {29,51,87,87,72,12}; + System.out.println(new Candy().candy(ratings)); + } + + public int candy(int[] ratings) { + if(ratings.length == 1) return 1; + PriorityQueue pq = new PriorityQueue<>((o1, o2) -> Integer.compare(ratings[o1], ratings[o2])); + for(int i = 0; i < ratings.length; i ++){ + pq.offer(i); + } + int[] count = new int[ratings.length]; + while (!pq.isEmpty()){ + int index = pq.poll(); + if(index - 1 < 0){ + if(ratings[index + 1] == ratings[index]){ + count[index] = 1; + } else{ + count[index] = count[index + 1] + 1; + } + } else if(index + 1 >= ratings.length) { + if(ratings[index - 1] == ratings[index]){ + count[index] = 1; + } else{ + count[index] = count[index - 1] + 1; + } + } else{ + if((ratings[index - 1] == ratings[index]) && (ratings[index + 1] == ratings[index])){ + count[index] = 1; + } else{ + if(((ratings[index - 1] == ratings[index]) && (ratings[index + 1] > ratings[index])) + || ((ratings[index + 1] == ratings[index]) && (ratings[index - 1] > ratings[index]))){ + count[index] = 1; + } else if(((ratings[index - 1] == ratings[index]) && (ratings[index + 1] < ratings[index]))){ + count[index] = count[index + 1] + 1; + } else if(((ratings[index + 1] == ratings[index]) && (ratings[index - 1] < ratings[index]))){ + count[index] = count[index - 1] + 1; + } + else { + if(count[index - 1] > count[index + 1]){ + count[index] = count[index - 1] + 1; + } else { + count[index] = count[index + 1] + 1; + } + } + } + } + } + int result = 0; + for(int c : count){ + result += c; + } + return result; + } +} From 81887f5827976f99f2a32c9ed85cc0130952e9c6 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 28 Jul 2018 12:34:38 +0200 Subject: [PATCH 197/235] Recover Binary Search Tree --- README.md | 1 + .../src/tree/RecoverBinarySearchTree.java | 107 ++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 problems/src/tree/RecoverBinarySearchTree.java diff --git a/README.md b/README.md index d27cce48..9b4f17d9 100644 --- a/README.md +++ b/README.md @@ -324,6 +324,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Split BST](problems/src/tree/SplitBST.java) (Medium) - [Closest Leaf in a Binary Tree](problems/src/tree/ClosestLeafInABinaryTree.java) (Medium) - [Maximum Width of Binary Tree](problems/src/tree/MaximumWidthOfBinaryTree.java) (Medium) +- [Recover Binary Search Tree](problems/src/tree/RecoverBinarySearchTree.java) (Hard) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/RecoverBinarySearchTree.java b/problems/src/tree/RecoverBinarySearchTree.java new file mode 100644 index 00000000..1ae01804 --- /dev/null +++ b/problems/src/tree/RecoverBinarySearchTree.java @@ -0,0 +1,107 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 28/07/2018. + * Two elements of a binary search tree (BST) are swapped by mistake. + + Recover the tree without changing its structure. + + Example 1: + + Input: [1,3,null,null,2] + + 1 + / + 3 + \ + 2 + + Output: [3,1,null,null,2] + + 3 + / + 1 + \ + 2 + Example 2: + + Input: [3,1,4,null,null,2] + + 3 + / \ + 1 4 + / + 2 + + Output: [2,1,4,null,null,3] + + 2 + / \ + 1 4 + / + 3 + Follow up: + + A solution using O(n) space is pretty straight forward. + Could you devise a constant space solution? + + Solution: O(N) time and O(1) space. Step 1, perform a inorder traversal and mark left and right pointer at the node + where violation of BST occurs. Step2, find the next node which is smaller or equal to right pointer node. + Finally swap left and right node values. + */ +public class RecoverBinarySearchTree { + private boolean violation; + private TreeNode left, right, prev; + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public static void main(String[] args) throws Exception{ + TreeNode root = new TreeNode(10); + root.left = new TreeNode(1); + root.left.left = new TreeNode(3); + root.left.left.left = new TreeNode(5); + new RecoverBinarySearchTree().recoverTree(root); + } + + public void recoverTree(TreeNode root) { + inorder(root); + if(left != null && right != null){ + int temp = left.val; + left.val = right.val; + right.val = temp; + } + } + + private void inorder(TreeNode root){ + if(root != null){ + inorder(root.left); + if(prev != null){ + if(!violation){ + if(prev.val > root.val){ + violation = true; + left = prev; + right = root; + } else{ + prev = root; + } + } else{ + if(root.val <= right.val){ + right = root; + } + } + } else { + prev = root; + } + inorder(root.right); + } + } + +} From d0d5eb6832cacc4d01130d3691ec9a7f3b4e63e3 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 28 Jul 2018 13:26:02 +0200 Subject: [PATCH 198/235] Binary Tree Postorder Traversal --- README.md | 1 + .../tree/BinaryTreePostorderTraversal.java | 62 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 problems/src/tree/BinaryTreePostorderTraversal.java diff --git a/README.md b/README.md index 9b4f17d9..93f23058 100644 --- a/README.md +++ b/README.md @@ -325,6 +325,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Closest Leaf in a Binary Tree](problems/src/tree/ClosestLeafInABinaryTree.java) (Medium) - [Maximum Width of Binary Tree](problems/src/tree/MaximumWidthOfBinaryTree.java) (Medium) - [Recover Binary Search Tree](problems/src/tree/RecoverBinarySearchTree.java) (Hard) +- [Binary Tree Postorder Traversal](problems/src/tree/BinaryTreePostorderTraversal.java) (Hard) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/tree/BinaryTreePostorderTraversal.java b/problems/src/tree/BinaryTreePostorderTraversal.java new file mode 100644 index 00000000..c7533312 --- /dev/null +++ b/problems/src/tree/BinaryTreePostorderTraversal.java @@ -0,0 +1,62 @@ +package tree; +import java.util.*; +/** + * Created by gouthamvidyapradhan on 28/07/2018. + * Given a binary tree, return the postorder traversal of its nodes' values. + + Example: + + Input: [1,null,2,3] + 1 + \ + 2 + / + 3 + + Output: [3,2,1] + Follow up: Recursive solution is trivial, could you do it iteratively? + +Solution: O(N). Maintain a stack, for every node which you pop from stack add it to result list, push left + and right node to stack. Reverse the result list and return this as the answer. + */ +public class BinaryTreePostorderTraversal { + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public static void main(String[] args) throws Exception{ + TreeNode root = new TreeNode(1); + root.right = new TreeNode(2); + root.right.left = new TreeNode(3); + List result = new BinaryTreePostorderTraversal().postorderTraversal(root); + result.forEach(System.out::println); + } + + public List postorderTraversal(TreeNode root) { + Stack stack = new Stack<>(); + List result = new ArrayList<>(); + if(root != null){ + stack.push(root); + } + while(!stack.isEmpty()){ + TreeNode node = stack.pop(); + result.add(node.val); + if(node.left != null){ + stack.push(node.left); + } if(node.right != null){ + stack.push(node.right); + } + } + Collections.reverse(result); + return result; + } + + + +} From 45a96c74d1031bce4686efd5cba8c6c9d8c3514f Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Mon, 20 Aug 2018 00:37:30 +0200 Subject: [PATCH 199/235] Race Car --- README.md | 1 + .../src/breadth_first_search/RaceCar.java | 107 ++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 problems/src/breadth_first_search/RaceCar.java diff --git a/README.md b/README.md index 93f23058..8e638bae 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Walls and Gates](problems/src/breadth_first_search/WallsAndGates.java) (Medium) - [Open the lock](problems/src/breadth_first_search/OpenTheLock.java) (Medium) - [Cut Off Trees for Golf Event](problems/src/breadth_first_search/CutOffTreesForGolfEvent.java) (Hard) +- [Race Car](problems/src/breadth_first_search/RaceCar.java) (Hard) #### [Depth First Search](problems/src/depth_first_search) diff --git a/problems/src/breadth_first_search/RaceCar.java b/problems/src/breadth_first_search/RaceCar.java new file mode 100644 index 00000000..3db18984 --- /dev/null +++ b/problems/src/breadth_first_search/RaceCar.java @@ -0,0 +1,107 @@ +package breadth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 19/08/2018 + * Your car starts at position 0 and speed +1 on an infinite number line. (Your car can go into negative positions.) + * + * Your car drives automatically according to a sequence of instructions A (accelerate) and R (reverse). + * + * When you get an instruction "A", your car does the following: position += speed, speed *= 2. + * + * When you get an instruction "R", your car does the following: if your speed is positive then speed = -1 , + * otherwise speed = 1. (Your position stays the same.) + * + * For example, after commands "AAR", your car goes to positions 0->1->3->3, and your speed goes to 1->2->4->-1. + * + * Now for some target position, say the length of the shortest sequence of instructions to get there. + * + * Example 1: + * Input: + * target = 3 + * Output: 2 + * Explanation: + * The shortest instruction sequence is "AA". + * Your position goes from 0->1->3. + * Example 2: + * Input: + * target = 6 + * Output: 5 + * Explanation: + * The shortest instruction sequence is "AAARA". + * Your position goes from 0->1->3->7->7->6. + * + * + * Note: + * + * 1 <= target <= 10000. + * + * Solution: O(n log n) Do a BFS and visit every possible state. Prune the search space by avoiding negative vertices + * and keep a boundary target of approximately (target * 2) - beyond this boundary target the race car should not + * progress in the forward direction. + */ +public class RaceCar { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + System.out.println(new RaceCar().racecar(1000)); + } + + private class Node{ + int v, s, d; + Node(int v, int s, int d){ + this.v = v; + this.s = s; + this.d = d; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Node)) return false; + Node node = (Node) o; + return v == node.v && + s == node.s; + } + + @Override + public int hashCode() { + return Objects.hash(v, s); + } + } + + public int racecar(int target) { + if(target == 0) return 0; + Queue queue = new ArrayDeque<>(); + Set done = new HashSet<>(); + Node start = new Node(0, 1, 0); + done.add(start); + queue.offer(start); + while(!queue.isEmpty()){ + Node curr = queue.poll(); + if(curr.v < (target * 2)){ + Node c1 = new Node(curr.v + curr.s, curr.s * 2, curr.d + 1); + if(c1.v >= 0){ + if(!done.contains(c1)){ + queue.offer(c1); + done.add(c1); + if(target == c1.v){ + return c1.d; + } + } + } + } + Node c2 = new Node(curr.v, curr.s < 0 ? 1 : -1, curr.d + 1); + if(!done.contains(c2)){ + done.add(c2); + queue.offer(c2); + } + } + return -1; + } + +} From ce7b810654d621fa3254f0e936b8061345c9bdf3 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 29 Aug 2018 00:58:28 +0200 Subject: [PATCH 200/235] Bus Routes --- README.md | 1 + .../src/breadth_first_search/BusRoutes.java | 114 ++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 problems/src/breadth_first_search/BusRoutes.java diff --git a/README.md b/README.md index 8e638bae..27077edd 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Open the lock](problems/src/breadth_first_search/OpenTheLock.java) (Medium) - [Cut Off Trees for Golf Event](problems/src/breadth_first_search/CutOffTreesForGolfEvent.java) (Hard) - [Race Car](problems/src/breadth_first_search/RaceCar.java) (Hard) +- [Bus Routes](problems/src/breadth_first_search/BusRoutes.java) (Hard) #### [Depth First Search](problems/src/depth_first_search) diff --git a/problems/src/breadth_first_search/BusRoutes.java b/problems/src/breadth_first_search/BusRoutes.java new file mode 100644 index 00000000..f90e832f --- /dev/null +++ b/problems/src/breadth_first_search/BusRoutes.java @@ -0,0 +1,114 @@ +package breadth_first_search; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 25/08/2018 + * We have a list of bus routes. Each routes[i] is a bus route that the i-th bus repeats forever. For example if + * routes[0] = [1, 5, 7], this means that the first bus (0-th indexed) travels in the sequence 1->5->7->1->5->7->1->. + * .. forever. + * + * We start at bus stop S (initially not on a bus), and we want to go to bus stop T. Travelling by buses only, what + * is the least number of buses we must take to reach our destination? Return -1 if it is not possible. + * + * Example: + * Input: + * routes = [[1, 2, 7], [3, 6, 7]] + * S = 1 + * T = 6 + * Output: 2 + * Explanation: + * The best strategy is take the first bus to the bus stop 7, then take the second bus to the bus stop 6. + * Note: + * + * 1 <= routes.length <= 500. + * 1 <= routes[i].length <= 500. + * 0 <= routes[i][j] < 10 ^ 6. + * + * Solution: Model a graph based on interconnection of routes and then run a BFS to find the shortest distance. + */ +public class BusRoutes { + + private class Node{ + int v, dist; + Node(int v, int dist){ + this.v = v; + this.dist = dist; + } + } + + private Map> routeGraph = new HashMap<>(); + private Map> stationRouteMap = new HashMap<>(); + private BitSet done = new BitSet(); + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[][] R = {{1, 2, 3, 9}, {9, 3, 4, 5, 8}, {5, 6, 7, 8}, {9, 8, 10, 11}, {12, 13, 14, 6, 1, 2, 3, 5, 7}}; + System.out.println(new BusRoutes().numBusesToDestination(R, 1, 14)); + } + + + public int numBusesToDestination(int[][] routes, int S, int T) { + if(S == T) return 0; + for(int i = 0; i < routes.length; i ++){ + Arrays.sort(routes[i]); + int[] n = routes[i]; + for(int j : n){ + if(j == S || j == T){ + stationRouteMap.putIfAbsent(j, new ArrayList<>()); + stationRouteMap.get(j).add(i); + } + } + } + for(int i = 0; i < routes.length; i ++){ + int[] A = routes[i]; + for(int j = i + 1; j < routes.length; j ++){ + int[] B = routes[j]; + if(intersect(A, B)){ + routeGraph.putIfAbsent(i, new HashSet<>()); + routeGraph.putIfAbsent(j, new HashSet<>()); + routeGraph.get(i).add(j); + routeGraph.get(j).add(i); + } + } + } + List start = stationRouteMap.get(S); + if(!stationRouteMap.containsKey(T)) return -1; + Set destination = new HashSet<>(stationRouteMap.get(T)); + Queue queue = new ArrayDeque<>(); + for(int r : start){ + if(destination.contains(r)) return 1; + done.set(r); + queue.offer(new Node(r, 0)); + } + while(!queue.isEmpty()){ + Node curr = queue.poll(); + Set children = routeGraph.get(curr.v); + if(children != null){ + for(int c : children){ + if(!done.get(c)){ + done.set(c); + Node child = new Node(c, curr.dist + 1); + if(destination.contains(child.v)){ + return child.dist + 1; + } else{ + queue.offer(child); + } + } + } + } + } + return -1; + } + + private boolean intersect(int[] A, int[] B){ + for(int i = 0, j = 0; i < A.length && j < B.length; ){ + if(A[i] == B[j]) return true; + else if(A[i] < B[j]) i ++; + else j ++; + } + return false; + } +} From 2098195013b807bf572fa96be07a64574f028368 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 2 Mar 2019 12:07:24 +0100 Subject: [PATCH 201/235] Fruit Into Baskets --- README.md | 1 + problems/src/array/FruitIntoBaskets.java | 100 +++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 problems/src/array/FruitIntoBaskets.java diff --git a/README.md b/README.md index 27077edd..ca64b0ed 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Can Place Flowers](problems/src/array/CanPlaceFlowers.java) (Easy) - [Merge Intervals](problems/src/array/MergeIntervals.java) (Medium) - [First Missing Positive](problems/src/array/FirstMissingPositive.java) (Hard) +- [Fruit Into Baskets](problems/src/array/FruitIntoBaskets.java) (Medium) - [MaxProduct Of Three Numbers](problems/src/array/MaxProductOfThreeNumbers.java) (Easy) - [Missing Number](problems/src/array/MissingNumber.java) (Easy) - [Merge Sorted Array](problems/src/array/MergeSortedArray.java) (Easy) diff --git a/problems/src/array/FruitIntoBaskets.java b/problems/src/array/FruitIntoBaskets.java new file mode 100644 index 00000000..7765f735 --- /dev/null +++ b/problems/src/array/FruitIntoBaskets.java @@ -0,0 +1,100 @@ +package array; + +import java.util.Stack; + +/** + * Created by gouthamvidyapradhan on 02/03/2019 + * In a row of trees, the i-th tree produces fruit with type tree[i]. + * + * You start at any tree of your choice, then repeatedly perform the following steps: + * + * Add one piece of fruit from this tree to your baskets. If you cannot, stop. + * Move to the next tree to the right of the current tree. If there is no tree to the right, stop. + * Note that you do not have any choice after the initial choice of starting tree: you must perform step 1, then step 2, then back to step 1, then step 2, and so on until you stop. + * + * You have two baskets, and each basket can carry any quantity of fruit, but you want each basket to only carry one type of fruit each. + * + * What is the total amount of fruit you can collect with this procedure? + * + * + * + * Example 1: + * + * Input: [1,2,1] + * Output: 3 + * Explanation: We can collect [1,2,1]. + * Example 2: + * + * Input: [0,1,2,2] + * Output: 3 + * Explanation: We can collect [1,2,2]. + * If we started at the first tree, we would only collect [0, 1]. + * Example 3: + * + * Input: [1,2,3,2,2] + * Output: 4 + * Explanation: We can collect [2,3,2,2]. + * If we started at the first tree, we would only collect [1, 2]. + * Example 4: + * + * Input: [3,3,3,1,2,1,1,2,3,3,4] + * Output: 5 + * Explanation: We can collect [1,2,1,1,2]. + * If we started at the first tree or the eighth tree, we would only collect 4 fruits. + * + * + * Note: + * + * 1 <= tree.length <= 40000 + * 0 <= tree[i] < tree.length + * + */ +public class FruitIntoBaskets { + + private int count = 0; + private int max = 0; + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[] trees = {1, 0, 3, 4, 3}; + System.out.println(new FruitIntoBaskets().totalFruit(trees)); + } + + public int totalFruit(int[] tree) { + int t1 = -1, t2 = -1; + Stack stack = new Stack<>(); + for(int i : tree){ + if(i == t1 || i == t2){ + countAndMax(stack, i); + } else { + if(t1 == -1){ + t1 = i; + countAndMax(stack, i); + } else if(t2 == -1){ + t2 = i; + countAndMax(stack, i); + } else{ + Stack temp = new Stack<>(); + count = 0; + t1 = stack.pop(); + countAndMax(temp, t1); + while(!stack.isEmpty() && stack.peek() == t1){ + countAndMax(temp, stack.pop()); + } + t2 = i; + stack = temp; + countAndMax(stack, i); + } + } + } + return max; + } + + private void countAndMax(Stack stack, int i){ + count++; + stack.push(i); + max = Math.max(max, count); + } +} From c3992f30769e05c043933f82d3b61648442f78eb Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 2 Mar 2019 13:23:00 +0100 Subject: [PATCH 202/235] Substring with Concatenation of All Words --- README.md | 1 + .../SubstringConcatenationOfWords.java | 79 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 problems/src/hashing/SubstringConcatenationOfWords.java diff --git a/README.md b/README.md index ca64b0ed..56edf729 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Partition Labels](problems/src/hashing/PartitionLabels.java) (Medium) - [Custom Sort String](problems/src/hashing/CustomSortString.java) (Medium) - [Short Encoding of Words](problems/src/hashing/ShortEncodingOfWords.java) (Medium) +- [Substring with Concatenation of All Words](problems/src/hashing/SubstringConcatenationOfWords.java) (Hard) #### [Heap](problems/src/heap) diff --git a/problems/src/hashing/SubstringConcatenationOfWords.java b/problems/src/hashing/SubstringConcatenationOfWords.java new file mode 100644 index 00000000..f6968673 --- /dev/null +++ b/problems/src/hashing/SubstringConcatenationOfWords.java @@ -0,0 +1,79 @@ +package hashing; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by gouthamvidyapradhan on 02/03/2019 + * You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices + * of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters. + * + * Example 1: + * + * Input: + * s = "barfoothefoobarman", + * words = ["foo","bar"] + * Output: [0,9] + * Explanation: Substrings starting at index 0 and 9 are "barfoor" and "foobar" respectively. + * The output order does not matter, returning [9,0] is fine too. + * Example 2: + * + * Input: + * s = "wordgoodgoodgoodbestword", + * words = ["word","good","best","word"] + * Output: [] + * + * Solution: + * General idea is to do the following + * 1. Calculate the word count for the given array of words and store this in a HashMap. + * 2. For every substring (substring of s) of length (words[0].length() * words.length) split this into words of + * length words[0].length and calculate the word frequency for the split words. If the word frequency matches + * the word frequency of the given original word list then add the starting index of this substring into the result + * array. + * + * A small optimization is to break the substring match as soon as you find out that the word formed from the substring + * is not part of the original given word list or if the frequency of the word exceeds the frequency of the original + * word count. + */ +public class SubstringConcatenationOfWords { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + String[] words = {"word","good","best","word"}; + System.out.println(new SubstringConcatenationOfWords().findSubstring("wordgoodgoodgoodbestword", words)); + } + + public List findSubstring(String s, String[] words) { + if(words.length == 0) return new ArrayList<>(); + int wLen = words[0].length(); + int sLen = wLen * words.length; + List result = new ArrayList<>(); + if(sLen > s.length()) return result; + Map countMap = new HashMap<>(); + for(String w : words){ + countMap.putIfAbsent(w, 0); + countMap.put(w, countMap.get(w) + 1); + } + for(int k = 0; (s.length() - k) >= sLen; k++) { + Map subSMap = new HashMap<>(); + int i = k; + for(int j = i + wLen; (i - k) < sLen; i = j, j += wLen){ + String subS = s.substring(i, j); + subSMap.putIfAbsent(subS, 0); + subSMap.put(subS, subSMap.get(subS) + 1); + if(!countMap.containsKey(subS) || subSMap.get(subS) > countMap.get(subS)){ + break; + } + } + if((i - k) >= sLen){ + result.add(k); + } + } + return result; + } +} From f791664562074f6c5b47125ce450805167162809 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 9 Mar 2019 00:43:08 +0100 Subject: [PATCH 203/235] EmployeeFreeTime, RobotRoomCleaner, CatAndMouse --- README.md | 3 + problems/src/array/EmployeeFreeTime.java | 112 +++++++++++++ .../depth_first_search/RobotRoomCleaner.java | 145 +++++++++++++++++ .../src/dynamic_programming/CatAndMouse.java | 150 ++++++++++++++++++ 4 files changed, 410 insertions(+) create mode 100644 problems/src/array/EmployeeFreeTime.java create mode 100644 problems/src/depth_first_search/RobotRoomCleaner.java create mode 100644 problems/src/dynamic_programming/CatAndMouse.java diff --git a/README.md b/README.md index 56edf729..7c47adbb 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Image Smoother](problems/src/array/ImageSmoother.java) (Easy) - [Minimum Index Sum of Two Lists](problems/src/array/MinimumIndexSumOfTwoLists.java) (Easy) - [Card Flipping Game](problems/src/array/CardFilipGame.java) (Medium) +- [Card Flipping Game](problems/src/array/EmployeeFreeTime.java) (Hard) #### [Backtracking](problems/src/backtracking) @@ -109,6 +110,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Number of Distinct Islands II](problems/src/depth_first_search/NumberOfDistinctIslandsII.java) (Hard) - [Smallest Rectangle Enclosing Black Pixels](problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java) (Hard) - [Bricks Falling When Hit](problems/src/depth_first_search/BricksFallingWhenHit.java) (Hard) +- [Bricks Falling When Hit](problems/src/depth_first_search/RobotRoomCleaner.java) (Hard) #### [Design](problems/src/design) @@ -178,6 +180,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Knight Probability in Chessboard](problems/src/dynamic_programming/KnightProbabilityInChessboard.java) (Medium) - [Largest Sum of Averages](problems/src/dynamic_programming/LargestSumOfAverages.java) (Medium) - [Minimum Number of Refueling Stops](problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java) (Hard) +- [Minimum Number of Refueling Stops](problems/src/dynamic_programming/CatAndMouse.java) (Hard) #### [Greedy](problems/src/greedy) diff --git a/problems/src/array/EmployeeFreeTime.java b/problems/src/array/EmployeeFreeTime.java new file mode 100644 index 00000000..d365f958 --- /dev/null +++ b/problems/src/array/EmployeeFreeTime.java @@ -0,0 +1,112 @@ +package array; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by gouthamvidyapradhan on 08/03/2019 + * We are given a list schedule of employees, which represents the working time for each employee. + * + * Each employee has a list of non-overlapping Intervals, and these intervals are in sorted order. + * + * Return the list of finite intervals representing common, positive-length free time for all employees, also in sorted order. + * + * Example 1: + * Input: schedule = [[[1,2],[5,6]],[[1,3]],[[4,10]]] + * Output: [[3,4]] + * Explanation: + * There are a total of three employees, and all common + * free time intervals would be [-inf, 1], [3, 4], [10, inf]. + * We discard any intervals that contain inf as they aren't finite. + * Example 2: + * Input: schedule = [[[1,3],[6,7]],[[2,4]],[[2,5],[9,12]]] + * Output: [[5,6],[7,9]] + * (Even though we are representing Intervals in the form [x, y], the objects inside are Intervals, not lists or arrays. For example, schedule[0][0].start = 1, schedule[0][0].end = 2, and schedule[0][0][0] is not defined.) + * + * Also, we wouldn't include intervals like [5, 5] in our answer, as they have zero length. + * + * Note: + * + * schedule and schedule[i] are lists with lengths in range [1, 50]. + * 0 <= schedule[i].start < schedule[i].end <= 10^8. + * + * Solution: O(L X N x N) Where L is the number of schedules, N is the length of schedules for each employee. + * Merge all the intervals to form a single merged array, now by using this array form a result array with the intervals + * which form the free time. + * + */ +public class EmployeeFreeTime { + + public static class Interval { + int start; + int end; + Interval() { start = 0; end = 0; } + Interval(int s, int e) { start = s; end = e; } + } + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + List> schedule = new ArrayList<>(); + List ints1 = new ArrayList<>(); + ints1.add(new Interval(45, 56)); + ints1.add(new Interval(89, 96)); + + + List ints3 = new ArrayList<>(); + ints3.add(new Interval(5, 21)); + ints3.add(new Interval(57, 74)); + + schedule.add(ints1); + schedule.add(ints3); + + List result = new EmployeeFreeTime().employeeFreeTime(schedule); + for(Interval i : result){ + System.out.println(i.start + " " + i.end); + } + } + + public List employeeFreeTime(List> schedule) { + if(schedule.isEmpty()) return new ArrayList<>(); + List merged = schedule.get(0); + for(int i = 1, l = schedule.size(); i < l; i++){ + List employeeInt = schedule.get(i); + for(Interval in : employeeInt){ + merged = merge(merged, in); + } + } + List result = new ArrayList<>(); + for(int i = 0, l = merged.size(); i + 1 < l; i ++){ + if(merged.get(i).end != merged.get(i + 1).start){ + result.add(new Interval(merged.get(i).end, merged.get(i + 1).start)); + } + } + return result; + } + + private List merge(List list, Interval interval){ + List result = new ArrayList<>(); + for(int i = 0, l = list.size(); i < l; i ++){ + Interval curr = list.get(i); + if(interval.start >= curr.start && interval.end <= curr.end){ + return list; + } else if(interval.start >= curr.start && interval.start <= curr.end){ + interval = new Interval(curr.start, interval.end); + } else if(interval.end >= curr.start && interval.end <= curr.end){ + interval = new Interval(interval.start, curr.end); + } else if(interval.end < curr.start){ + result.add(interval); + for(int j = i; j < l; j++){ + result.add(list.get(j)); + } + return result; + } else if(interval.start > curr.end){ + result.add(curr); + } + } + result.add(interval); + return result; + } +} diff --git a/problems/src/depth_first_search/RobotRoomCleaner.java b/problems/src/depth_first_search/RobotRoomCleaner.java new file mode 100644 index 00000000..2189f431 --- /dev/null +++ b/problems/src/depth_first_search/RobotRoomCleaner.java @@ -0,0 +1,145 @@ +package depth_first_search; + +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +/** + * Created by gouthamvidyapradhan on 08/03/2019 + Given a robot cleaner in a room modeled as a grid. + + Each cell in the grid can be empty or blocked. + + The robot cleaner with 4 given APIs can move forward, turn left or turn right. Each turn it made is 90 degrees. + + When it tries to move into a blocked cell, its bumper sensor detects the obstacle and it stays on the current cell. + + Design an algorithm to clean the entire room using only the 4 given APIs shown below. + + interface Robot { + // returns true if next cell is open and robot moves into the cell. + // returns false if next cell is obstacle and robot stays on the current cell. + boolean move(); + + // Robot will stay on the same cell after calling turnLeft/turnRight. + // Each turn will be 90 degrees. + void turnLeft(); + void turnRight(); + + // Clean the current cell. + void clean(); + } + Example: + + Input: + room = [ + [1,1,1,1,1,0,1,1], + [1,1,1,1,1,0,1,1], + [1,0,1,1,1,1,1,1], + [0,0,0,1,0,0,0,0], + [1,1,1,1,1,1,1,1] + ], + row = 1, + col = 3 + + Explanation: + All grids in the room are marked by either 0 or 1. + 0 means the cell is blocked, while 1 means the cell is accessible. + The robot initially starts at the position of row=1, col=3. + From the top left corner, its position is one row below and three columns right. + Notes: + + The input is only given to initialize the room and the robot's position internally. You must solve this problem + "blindfolded". In other words, you must control the robot using only the mentioned 4 APIs, without knowing the room + layout and the initial robot's position. + The robot's initial position will always be in an accessible cell. + The initial direction of the robot will be facing up. + All accessible cells are connected, which means the all cells marked as 1 will be accessible by the robot. + Assume all four edges of the grid are all surrounded by wall. + * + * + * Solution: O(N x M) + * Maintain a direction and position of robot in each cell and perform a dfs to clean all rooms. + * Important to note here is that during call back in the dfs recursion the robot has to return back to its original + * cell and orientation + */ +public class RobotRoomCleaner { + + //direction + //UP 0, LEFT = 1, DOWN = 2, RIGHT = 3 + + private final int[] R = {-1, 0, 1, 0}; + private final int[] C = {0, -1, 0, 1}; + + + interface Robot { + // Returns true if the cell in front is open and robot moves into the cell. + // Returns false if the cell in front is blocked and robot stays in the current cell. + public boolean move(); + + // Robot will stay in the same cell after calling turnLeft/turnRight. + // Each turn will be 90 degrees. + public void turnLeft(); + public void turnRight(); + + // Clean the current cell. + public void clean(); + } + + static class Position{ + int r, c; + Position(int r, int c){ + this.r = r; + this.c = c; + } + + @Override + public boolean equals(Object obj) { + int r = ((Position)obj).r; + int c = ((Position)obj).c; + return (this.r == r && this.c == c); + } + + @Override + public int hashCode() { + return Objects.hash(r, c); + } + } + + private static Set done; + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + + } + + public void cleanRoom(Robot robot) { + done = new HashSet<>(); + dfs(1, 3, done, robot, 0); + } + + private void dfs(int r, int c, Set done, Robot robot, int direction){ + done.add(new Position(r, c)); + robot.clean(); + for(int i = 0; i < 4; i ++){ + int newR = r + R[direction]; + int newC = c + C[direction]; + if(!done.contains(new Position(newR, newC))){ + boolean possible = robot.move(); + if(possible){ + dfs(newR, newC, done, robot, direction); + } + } + robot.turnLeft(); + direction = (direction + 1) % 4; + } + robot.turnLeft(); + robot.turnLeft(); + robot.move(); + robot.turnLeft(); + robot.turnLeft(); + } +} diff --git a/problems/src/dynamic_programming/CatAndMouse.java b/problems/src/dynamic_programming/CatAndMouse.java new file mode 100644 index 00000000..7168ddad --- /dev/null +++ b/problems/src/dynamic_programming/CatAndMouse.java @@ -0,0 +1,150 @@ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 03/03/2019 + * + * A game on an undirected graph is played by two players, Mouse and Cat, who alternate turns. + * + * The graph is given as follows: graph[a] is a list of all nodes b such that ab is an edge of the graph. + * + * Mouse starts at node 1 and goes first, Cat starts at node 2 and goes second, and there is a Hole at node 0. + * + * During each player's turn, they must travel along one edge of the graph that meets where they are. For example, if the Mouse is at node 1, it must travel to any node in graph[1]. + * + * Additionally, it is not allowed for the Cat to travel to the Hole (node 0.) + * + * Then, the game can end in 3 ways: + * + * If ever the Cat occupies the same node as the Mouse, the Cat wins. + * If ever the Mouse reaches the Hole, the Mouse wins. + * If ever a position is repeated (ie. the players are in the same position as a previous turn, and it is the same player's turn to move), the game is a draw. + * Given a graph, and assuming both players play optimally, return 1 if the game is won by Mouse, 2 if the game is won by Cat, and 0 if the game is a draw. + * + * + * + * Example 1: + * + * Input: [[2,5],[3],[0,4,5],[1,4,5],[2,3],[0,2,3]] + * Output: 0 + * Explanation: + * 4---3---1 + * | | + * 2---5 + * \ / + * 0 + * + * + * Note: + * + * 3 <= graph.length <= 50 + * It is guaranteed that graph[1] is non-empty. + * It is guaranteed that graph[2] contains a non-zero element. + * + * Solution: Each combination of mouse, cat and turn for a state (m, c, p). Transition between different states form + * a state graph - start to color each state with either MOUSE, CAT or a DRAW based on who wins this state. Perform a + * bottom up dp inorder to arrive at the answer. + */ +public class CatAndMouse { + + private final int CAT = 2, MOUSE = 1, DRAW = 0, PLAYER_CAT = 1, PLAYER_MOUSE = 0; + private Queue queue = new ArrayDeque<>(); + class State{ + int catPos, mPos, player, color; + State(int mPos, int catPos, int player, int color){ + this.catPos = catPos; + this.mPos = mPos; + this.player = player; + this.color = color; + } + } + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[][] graph = {{2,5},{3},{0,4,5},{1,4,5},{2,3},{0,2,3}}; + System.out.println(new CatAndMouse().catMouseGame(graph)); + } + + public int catMouseGame(int[][] graph) { + int[][][] color = new int[graph.length][graph.length][2]; + int[][][] degree = new int[graph.length][graph.length][2]; + + for(int i = 1; i < graph.length; i ++){ + for(int p = 0; p < 2; p ++){ + color[0][i][p] = MOUSE; + queue.offer(new State(0, i, p, MOUSE)); + color[i][i][p] = CAT; + queue.offer(new State(i, i, p, CAT)); + } + } + + for(int m = 0; m < graph.length; m ++){ + for(int c = 1; c < graph.length; c ++){ + degree[m][c][0] = graph[m].length; + degree[m][c][1] = graph[c].length; + for(int v : graph[c]){ + if(v == 0){ + degree[m][c][1]--; + break; + } + } + } + } + + while(!queue.isEmpty()){ + State current = queue.poll(); + List parents = getParents(graph, current, color); + if(color[current.mPos][current.catPos][current.player] == CAT){ + enqueue(queue, parents, PLAYER_CAT, CAT, color, degree); + } else{ + enqueue(queue, parents, PLAYER_MOUSE, MOUSE, color, degree); + } + } + return color[1][2][0]; + } + + private void enqueue(Queue queue, List parents, int player, int col, int[][][] color, + int[][][] degree){ + for(State parent : parents){ + if(color[parent.mPos][parent.catPos][parent.player] == DRAW){ + if(parent.player == player){ + color[parent.mPos][parent.catPos][parent.player] = col; + queue.offer(new State(parent.mPos, parent.catPos, parent.player, col)); + } else{ + int currDegree = --degree[parent.mPos][parent.catPos][parent.player]; + if(currDegree == 0){ + color[parent.mPos][parent.catPos][parent.player] = col; + queue.offer(new State(parent.mPos, parent.catPos, parent.player, col)); + } + } + } + } + } + + private List getParents(int[][] graph, State current, int[][][] color){ + int player = current.player; + int[] positions; + List list = new ArrayList<>(); + if(player == PLAYER_MOUSE){ + positions = graph[current.catPos]; + for(int pos: positions){ + if(pos == 0) continue; + if(color[current.mPos][pos][PLAYER_CAT] == DRAW){ + list.add(new State(current.mPos, pos, PLAYER_CAT, DRAW)); + } + } + } else{ + positions = graph[current.mPos]; + for(int pos: positions){ + if(color[pos][current.catPos][PLAYER_MOUSE] == DRAW) { + list.add(new State(pos, current.catPos, PLAYER_MOUSE, DRAW)); + } + } + } + return list; + } +} From 3a33f230940e27d64822ac972c1cdcf3db629216 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 9 Mar 2019 16:07:54 +0100 Subject: [PATCH 204/235] Cracking The Safe --- README.md | 3 +- .../depth_first_search/CrackingTheSafe.java | 99 +++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 problems/src/depth_first_search/CrackingTheSafe.java diff --git a/README.md b/README.md index 7c47adbb..ba844a6a 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,8 @@ My accepted leetcode solutions to some of the common interview problems. - [Number of Distinct Islands II](problems/src/depth_first_search/NumberOfDistinctIslandsII.java) (Hard) - [Smallest Rectangle Enclosing Black Pixels](problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java) (Hard) - [Bricks Falling When Hit](problems/src/depth_first_search/BricksFallingWhenHit.java) (Hard) -- [Bricks Falling When Hit](problems/src/depth_first_search/RobotRoomCleaner.java) (Hard) +- [Robot Room Cleaner](problems/src/depth_first_search/RobotRoomCleaner.java) (Hard) +- [Cracking the Safe](problems/src/depth_first_search/CrackingTheSafe.java) (Hard) #### [Design](problems/src/design) diff --git a/problems/src/depth_first_search/CrackingTheSafe.java b/problems/src/depth_first_search/CrackingTheSafe.java new file mode 100644 index 00000000..b8361738 --- /dev/null +++ b/problems/src/depth_first_search/CrackingTheSafe.java @@ -0,0 +1,99 @@ +package depth_first_search; + +import java.util.HashSet; +import java.util.Set; + +/** + * Created by gouthamvidyapradhan on 09/03/2019 + * There is a box protected by a password. The password is n digits, where each letter can be one of the first k + * digits 0, 1, ..., k-1. + * + * You can keep inputting the password, the password will automatically be matched against the last n digits entered. + * + * For example, assuming the password is "345", I can open it when I type "012345", but I enter a total of 6 digits. + * + * Please return any string of minimum length that is guaranteed to open the box after the entire string is inputted. + * + * Example 1: + * Input: n = 1, k = 2 + * Output: "01" + * Note: "10" will be accepted too. + * Example 2: + * Input: n = 2, k = 2 + * Output: "00110" + * Note: "01100", "10011", "11001" will be accepted too. + * Note: + * n will be in the range [1, 4]. + * k will be in the range [1, 10]. + * k^n will be at most 4096. + * + * Solution O(n x k ^ n) Do a dfs and explore every possible states which form a n digit number with-in the given + * range k. Maintain a 'result' string and keep appending the new digit in every state, if the total number of states + * visited reaches k ^ n then, the result string will be the answer. + */ +public class CrackingTheSafe { + + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + System.out.println(new CrackingTheSafe().crackSafe(4, 5)); + } + + public String crackSafe(int n, int k) { + int states = getStates(n, k); + int[] N = new int[k]; + for (int i = 0; i < k; i++) { + N[i] = i; + } + return generate(N, n, 0, 0, "", k, states); + } + + private int getStates(int n, int k) { + if (n == 0) return 1; + if (n == 1) return k; + int result = 1; + for (int i = 0; i < n; i++) { + result *= k; + } + return result; + } + + private String generate(int[] N, int n, int i, int count, String num, int k, int states) { + if (count == n) { + return dfs(num, new StringBuilder(num), new HashSet<>(), k, states, 1); + } else { + for (int j = i; j < N.length; j++) { + String result = generate(N, n, j, count + 1, num + String.valueOf(N[j]), k, states); + if (!result.isEmpty()) { + return result; + } + } + } + return ""; + } + + private String dfs(String num, StringBuilder result, Set done, int k, int states, int count) { + done.add(num); + if (states == count) { + return result.toString(); + } else { + for (int i = 0; i < k; i++) { + String newNum = (num + String.valueOf(i)); + String newState = newNum.substring(1); + if (!done.contains(newState)) { + String retValue = dfs(newState, result.append(String.valueOf(i)), done, k, states, count + 1); + if (!retValue.isEmpty()) { + return retValue; + } else { + result.deleteCharAt(result.length() - 1); + } + } + } + } + done.remove(num); + return ""; + } +} From ebe07446b3fec8aab2987ecfe46de1e1bb12a28a Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 10 Mar 2019 12:51:52 +0100 Subject: [PATCH 205/235] Best Meeting Point --- README.md | 5 +- problems/src/array/BestMeetingPoint.java | 81 ++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 problems/src/array/BestMeetingPoint.java diff --git a/README.md b/README.md index ba844a6a..c16cf9b1 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,8 @@ My accepted leetcode solutions to some of the common interview problems. - [Image Smoother](problems/src/array/ImageSmoother.java) (Easy) - [Minimum Index Sum of Two Lists](problems/src/array/MinimumIndexSumOfTwoLists.java) (Easy) - [Card Flipping Game](problems/src/array/CardFilipGame.java) (Medium) -- [Card Flipping Game](problems/src/array/EmployeeFreeTime.java) (Hard) +- [Employee Free Time](problems/src/array/EmployeeFreeTime.java) (Hard) +- [Best Meeting Point](problems/src/array/BestMeetingPoint.java) (Hard) #### [Backtracking](problems/src/backtracking) @@ -181,7 +182,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Knight Probability in Chessboard](problems/src/dynamic_programming/KnightProbabilityInChessboard.java) (Medium) - [Largest Sum of Averages](problems/src/dynamic_programming/LargestSumOfAverages.java) (Medium) - [Minimum Number of Refueling Stops](problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java) (Hard) -- [Minimum Number of Refueling Stops](problems/src/dynamic_programming/CatAndMouse.java) (Hard) +- [Cat and Mouse](problems/src/dynamic_programming/CatAndMouse.java) (Hard) #### [Greedy](problems/src/greedy) diff --git a/problems/src/array/BestMeetingPoint.java b/problems/src/array/BestMeetingPoint.java new file mode 100644 index 00000000..c2d9e8c1 --- /dev/null +++ b/problems/src/array/BestMeetingPoint.java @@ -0,0 +1,81 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 10/03/2019 + * A group of two or more people wants to meet and minimize the total travel distance. You are given a 2D grid of + * values 0 or 1, where each 1 marks the home of someone in the group. The distance is calculated using Manhattan + * Distance, where distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|. + *

+ * Example: + *

+ * Input: + *

+ * 1 - 0 - 0 - 0 - 1 + * | | | | | + * 0 - 0 - 0 - 0 - 0 + * | | | | | + * 0 - 0 - 1 - 0 - 0 + *

+ * Output: 6 + *

+ * Explanation: Given three people living at (0,0), (0,4), and (2,2): + * The point (0,2) is an ideal meeting point, as the total travel distance + * of 2+2+2=6 is minimal. So return 6. + *

+ * Solution: O(N ^ 2 + M ^ 2) + O(N x M): Calculate the total number of persons in each row and each column and then + * take a minimum of cartesian product of each row and each column. + */ +public class BestMeetingPoint { + + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[][] grid = {{1, 0, 0, 0, 1}, {0, 0, 0, 0, 0}, {0, 0, 1, 0, 0}}; + System.out.println(new BestMeetingPoint().minTotalDistance(grid)); + } + + public int minTotalDistance(int[][] grid) { + int[] countR = new int[grid.length]; + int[] countC = new int[grid[0].length]; + + int[] distR = new int[grid.length]; + int[] distC = new int[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) { + countR[i]++; + countC[j]++; + } + } + } + + for (int i = 0; i < distR.length; i++) { + for (int j = 0; j < distR.length; j++) { + if (countR[j] != 0) { + distR[i] += Math.abs(j - i) * countR[j]; + } + } + } + + for (int i = 0; i < distC.length; i++) { + for (int j = 0; j < distC.length; j++) { + if (countC[j] != 0) { + distC[i] += Math.abs(j - i) * countC[j]; + } + } + } + + int min = Integer.MAX_VALUE; + for (int i = 0; i < distR.length; i++) { + for (int j = 0; j < distC.length; j++) { + min = Math.min(min, distR[i] + distC[j]); + } + } + + return min; + } +} From 964f49ee3e849e3168bca4c5a4c336715df564e4 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 23 Mar 2019 14:40:21 +0100 Subject: [PATCH 206/235] Some solved problems --- README.md | 11 ++ problems/src/array/MyCalendarThree.java | 92 +++++++++++ problems/src/breadth_first_search/Matrix.java | 104 ++++++++++++ .../breadth_first_search/SlidingPuzzle.java | 146 +++++++++++++++++ .../src/dynamic_programming/OddEvenJump.java | 148 ++++++++++++++++++ .../src/dynamic_programming/StoneGame.java | 101 ++++++++++++ .../src/linked_list/MiddleOfLinkedList.java | 57 +++++++ problems/src/math/NthMagicalNumber.java | 94 +++++++++++ problems/src/string/LongestPalindrome.java | 57 +++++++ .../src/string/ValidWordAbbreviation.java | 73 +++++++++ .../src/tree/ConvertBSTToGreaterTree.java | 54 +++++++ .../tree/SerializeAndDeserializeNAryTree.java | 121 ++++++++++++++ 12 files changed, 1058 insertions(+) create mode 100644 problems/src/array/MyCalendarThree.java create mode 100644 problems/src/breadth_first_search/Matrix.java create mode 100644 problems/src/breadth_first_search/SlidingPuzzle.java create mode 100644 problems/src/dynamic_programming/OddEvenJump.java create mode 100644 problems/src/dynamic_programming/StoneGame.java create mode 100644 problems/src/linked_list/MiddleOfLinkedList.java create mode 100644 problems/src/math/NthMagicalNumber.java create mode 100644 problems/src/string/LongestPalindrome.java create mode 100644 problems/src/string/ValidWordAbbreviation.java create mode 100644 problems/src/tree/ConvertBSTToGreaterTree.java create mode 100644 problems/src/tree/SerializeAndDeserializeNAryTree.java diff --git a/README.md b/README.md index c16cf9b1..6d959925 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Card Flipping Game](problems/src/array/CardFilipGame.java) (Medium) - [Employee Free Time](problems/src/array/EmployeeFreeTime.java) (Hard) - [Best Meeting Point](problems/src/array/BestMeetingPoint.java) (Hard) +- [My Calendar III](problems/src/array/MyCalendarThree.java) (Hard) #### [Backtracking](problems/src/backtracking) @@ -93,6 +94,8 @@ My accepted leetcode solutions to some of the common interview problems. - [Cut Off Trees for Golf Event](problems/src/breadth_first_search/CutOffTreesForGolfEvent.java) (Hard) - [Race Car](problems/src/breadth_first_search/RaceCar.java) (Hard) - [Bus Routes](problems/src/breadth_first_search/BusRoutes.java) (Hard) +- [Sliding Puzzle](problems/src/breadth_first_search/SlidingPuzzle.java) (Hard) +- [Matrix](problems/src/breadth_first_search/Matrix.java) (Medium) #### [Depth First Search](problems/src/depth_first_search) @@ -183,6 +186,8 @@ My accepted leetcode solutions to some of the common interview problems. - [Largest Sum of Averages](problems/src/dynamic_programming/LargestSumOfAverages.java) (Medium) - [Minimum Number of Refueling Stops](problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java) (Hard) - [Cat and Mouse](problems/src/dynamic_programming/CatAndMouse.java) (Hard) +- [Stone Game](problems/src/dynamic_programming/StoneGame.java) (Medium) +- [Odd Even Jump](problems/src/dynamic_programming/OddEvenJump.java) (Hard) #### [Greedy](problems/src/greedy) @@ -232,6 +237,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Delete Node in a Linked List](problems/src/linked_list/DeleteNode.java) (Easy) - [Reverse Nodes in k-Group](problems/src/linked_list/ReverseNodesKGroup.java) (Hard) - [Swap Nodes in Pairs](problems/src/linked_list/SwapNodesInPairs.java) (Medium) +- [Middle of Linked List](problems/src/linked_list/MiddleOfLinkedList.java) (Easy) #### [Math](problems/src/math) @@ -247,6 +253,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Solve the Equation](problems/src/math/SolveTheEquation.java) (Medium) - [Couples Holding Hands](problems/src/math/CouplesHoldingHands.java) (Hard) - [Reaching Points](problems/src/math/ReachingPoints.java) (Hard) +- [Nth Magical Number](problems/src/math/NthMagicalNumber.java) (Hard) #### [Reservoir Sampling](problems/src/reservoir_sampling) @@ -292,6 +299,8 @@ My accepted leetcode solutions to some of the common interview problems. - [Find the Closest Palindrome](problems/src/string/FindTheClosestPalindrome.java) (Hard) - [Monotone Increasing Digits](problems/src/string/MonotoneIncreasingDigits.java) (Medium) - [Shortest Palindrome](problems/src/string/ShortestPalindrome.java) (Hard) +- [Valid Word Abbreviation](problems/src/string/ValidWordAbbreviation.java) (Easy) +- [Longest Palindrome](problems/src/string/LongestPalindrome.java) (Easy) #### [Tree](problems/src/tree) @@ -335,6 +344,8 @@ My accepted leetcode solutions to some of the common interview problems. - [Maximum Width of Binary Tree](problems/src/tree/MaximumWidthOfBinaryTree.java) (Medium) - [Recover Binary Search Tree](problems/src/tree/RecoverBinarySearchTree.java) (Hard) - [Binary Tree Postorder Traversal](problems/src/tree/BinaryTreePostorderTraversal.java) (Hard) +- [Serialize and Deserialize N-ary Tree](problems/src/tree/SerializeAndDeserializeNAryTree.java) (Hard) +- [Convert BST to Greater Tree](problems/src/tree/ConvertBSTToGreaterTree.java) (Easy) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/array/MyCalendarThree.java b/problems/src/array/MyCalendarThree.java new file mode 100644 index 00000000..991a071b --- /dev/null +++ b/problems/src/array/MyCalendarThree.java @@ -0,0 +1,92 @@ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 12/03/2019 + * Implement a MyCalendarThree class to store your events. A new event can always be added. + * + * Your class will have one method, book(int start, int end). Formally, this represents a booking on the half open + * interval [start, end), the range of real numbers x such that start <= x < end. + * + * A K-booking happens when K events have some non-empty intersection (ie., there is some time that is common to all + * K events.) + * + * For each call to the method MyCalendar.book, return an integer K representing the largest integer such that there + * exists a K-booking in the calendar. + * + * Your class will be called like this: MyCalendarThree cal = new MyCalendarThree(); MyCalendarThree.book(start, end) + * Example 1: + * + * MyCalendarThree(); + * MyCalendarThree.book(10, 20); // returns 1 + * MyCalendarThree.book(50, 60); // returns 1 + * MyCalendarThree.book(10, 40); // returns 2 + * MyCalendarThree.book(5, 15); // returns 3 + * MyCalendarThree.book(5, 10); // returns 3 + * MyCalendarThree.book(25, 55); // returns 3 + * Explanation: + * The first two events can be booked and are disjoint, so the maximum K-booking is a 1-booking. + * The third event [10, 40) intersects the first event, and the maximum K-booking is a 2-booking. + * The remaining events cause the maximum K-booking to be only a 3-booking. + * Note that the last event locally causes a 2-booking, but the answer is still 3 because + * eg. [10, 20), [10, 40), and [5, 15) are still triple booked. + */ +public class MyCalendarThree{ + + private List events; + private int max; + + private class Node{ + int n, index; + Node(int n, int index){ + this.n = n; + this.index = index; + } + + public int getN() { + return n; + } + + public int getIndex() { + return index; + } + } + + public MyCalendarThree() { + events = new ArrayList<>(); + max = 0; + } + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + MyCalendarThree calendar = new MyCalendarThree(); + System.out.println(calendar.book(10, 20)); + System.out.println(calendar.book(50, 60)); + System.out.println(calendar.book(10, 40)); + System.out.println(calendar.book(5, 15)); + System.out.println(calendar.book(5, 10)); + System.out.println(calendar.book(25, 55)); + } + + + public int book(int start, int end) { + events.add(new Node(start, 1)); + events.add(new Node(end, 0)); + events.sort((Comparator.comparing(Node::getN).thenComparing(Node::getIndex))); + int count = 0; + for(Node node : events){ + if(node.index == 1 && node.n >= end){ + break; + } + count += node.index == 1 ? 1 : -1; + if(node.getN() >= start){ + max = Math.max(max, count); + } + } + return max; + } +} diff --git a/problems/src/breadth_first_search/Matrix.java b/problems/src/breadth_first_search/Matrix.java new file mode 100644 index 00000000..76f28186 --- /dev/null +++ b/problems/src/breadth_first_search/Matrix.java @@ -0,0 +1,104 @@ +package breadth_first_search; + +import java.util.*; +/** + * Created by gouthamvidyapradhan on 14/03/2019 + * Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell. + * + * The distance between two adjacent cells is 1. + * Example 1: + * Input: + * + * 0 0 0 + * 0 1 0 + * 0 0 0 + * Output: + * 0 0 0 + * 0 1 0 + * 0 0 0 + * Example 2: + * Input: + * + * 0 0 0 + * 0 1 0 + * 1 1 1 + * Output: + * 0 0 0 + * 0 1 0 + * 1 2 1 + * Note: + * The number of elements of the given matrix will not exceed 10,000. + * There are at least one 0 in the given matrix. + * The cells are adjacent in only four directions: up, down, left and right. + * + * Solution: Add all the 0th cell to the queue and do a multi-source bfs to count the minimum distance + */ +public class Matrix { + private static class Node{ + int r, c; + int d; + Node(int r, int c){ + this.r = r; + this.c = c; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Node)) return false; + Node node = (Node) o; + return r == node.r && + c == node.c; + } + + @Override + public int hashCode() { + return Objects.hash(r, c); + } + } + private final int[] R = {0, 0, 1, -1}; + private final int[] C = {1, -1, 0, 0}; + private Set done; + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[][] temp = {{0, 0, 0}, {0, 1, 0}, {1, 1, 1}}; + int[][] result = new Matrix().updateMatrix(temp); + System.out.println(); + } + + public int[][] updateMatrix(int[][] matrix) { + int[][] temp = new int[matrix.length][matrix[0].length]; + done = new HashSet<>(); + Queue queue = new ArrayDeque<>(); + for(int i = 0; i < matrix.length; i ++){ + for(int j = 0; j < matrix[0].length; j ++){ + temp[i][j] = matrix[i][j]; + if(matrix[i][j] == 0){ + Node node = new Node(i, j); + queue.offer(node); + done.add(node); + } + } + } + while(!queue.isEmpty()){ + Node curr = queue.poll(); + for(int i = 0; i < 4; i ++){ + int newR = curr.r + R[i]; + int newC = curr.c + C[i]; + if(newR >= 0 && newR < matrix.length && newC >= 0 && newC < matrix[0].length){ + Node child = new Node(newR, newC); + if(!done.contains(child)){ + done.add(child); + child.d = curr.d + 1; + temp[newR][newC] = child.d; + queue.offer(child); + } + } + } + } + return temp; + } +} diff --git a/problems/src/breadth_first_search/SlidingPuzzle.java b/problems/src/breadth_first_search/SlidingPuzzle.java new file mode 100644 index 00000000..5fb39cc1 --- /dev/null +++ b/problems/src/breadth_first_search/SlidingPuzzle.java @@ -0,0 +1,146 @@ +package breadth_first_search; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 17/03/2019 + * On a 2x3 board, there are 5 tiles represented by the integers 1 through 5, and an empty square represented by 0. + * + * A move consists of choosing 0 and a 4-directionally adjacent number and swapping it. + * + * The state of the board is solved if and only if the board is [[1,2,3],[4,5,0]]. + * + * Given a puzzle board, return the least number of moves required so that the state of the board is solved. If it + * is impossible for the state of the board to be solved, return -1. + * + * Examples: + * + * Input: board = [[1,2,3],[4,0,5]] + * Output: 1 + * Explanation: Swap the 0 and the 5 in one move. + * Input: board = [[1,2,3],[5,4,0]] + * Output: -1 + * Explanation: No number of moves will make the board solved. + * Input: board = [[4,1,2],[5,0,3]] + * Output: 5 + * Explanation: 5 is the smallest number of moves that solves the board. + * An example path: + * After move 0: [[4,1,2],[5,0,3]] + * After move 1: [[4,1,2],[0,5,3]] + * After move 2: [[0,1,2],[4,5,3]] + * After move 3: [[1,0,2],[4,5,3]] + * After move 4: [[1,2,0],[4,5,3]] + * After move 5: [[1,2,3],[4,5,0]] + * Input: board = [[3,2,4],[1,5,0]] + * Output: 14 + * Note: + * + * board will be a 2 x 3 array as described above. + * board[i][j] will be a permutation of [0, 1, 2, 3, 4, 5]. + * + * Solution: Do a bfs of each state of the board to find the least possible moves. + */ +public class SlidingPuzzle { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[][] board = {{1, 2, 3}, {4, 0, 5}}; + System.out.println(new SlidingPuzzle().slidingPuzzle(board)); + } + + class Node{ + Node(Board b){ + this.b = b; + } + Board b; + int dist; + } + + private static final int[] R = {-1, 0, 0, 1}; + private static final int[] C = {0, 1, -1, 0}; + private static final String result = "123450"; + class Board{ + int[][] board; + int r, c; + final String state; + Board(int[][] board){ + this.board = board; + StringBuilder sb = new StringBuilder(); + for(int i = 0; i < 2; i ++){ + for(int j = 0; j < 3; j++){ + sb.append(board[i][j]); + } + } + state = sb.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Board)) return false; + Board board = (Board) o; + return Objects.equals(state, board.state); + } + + @Override + public int hashCode() { + return Objects.hash(state); + } + } + private Set done; + + public int slidingPuzzle(int[][] board) { + done = new HashSet<>(); + Board b = new Board(board); + for(int i = 0; i < board.length; i ++){ + for(int j = 0; j < board[0].length; j ++){ + if(board[i][j] == 0){ + b.r = i; + b.c = j; + break; + } + } + } + if(b.state.equals(result)) return 0; + Queue queue = new ArrayDeque<>(); + queue.offer(new Node(b)); + while(!queue.isEmpty()){ + Node child = queue.poll(); + Board br = child.b; + done.add(br); + for(int i = 0; i < 4; i++){ + int newR = br.r + R[i]; + int newC = br.c + C[i]; + if(newR < 0 || newR >= 2 || newC < 0 || newC >= 3)continue; + int num = br.board[newR][newC]; + int[][] tempB = clone(br.board); + tempB[newR][newC] = 0; + tempB[br.r][br.c] = num; + Board tempBoard = new Board(tempB); + tempBoard.r = newR; + tempBoard.c = newC; + if(!done.contains(tempBoard)){ + if(tempBoard.state.equals(result)){ + return child.dist + 1; + } + Node newChild = new Node(tempBoard); + newChild.dist = child.dist + 1; + queue.offer(newChild); + } + } + } + return -1; + } + + private int[][] clone(int[][] original){ + int[][] cloned = new int[2][3]; + for(int i = 0; i < 2; i ++){ + for(int j = 0; j < 3; j++){ + cloned[i][j] = original[i][j]; + } + } + return cloned; + } +} diff --git a/problems/src/dynamic_programming/OddEvenJump.java b/problems/src/dynamic_programming/OddEvenJump.java new file mode 100644 index 00000000..5cd33f48 --- /dev/null +++ b/problems/src/dynamic_programming/OddEvenJump.java @@ -0,0 +1,148 @@ +package dynamic_programming; +import java.util.*; +/** + * Created by gouthamvidyapradhan on 17/03/2019 + * You are given an integer array A. From some starting index, you can make a series of jumps. The (1st, 3rd, 5th, + * ...) jumps in the series are called odd numbered jumps, and the (2nd, 4th, 6th, ...) jumps in the series are + * called even numbered jumps. + * + * You may from index i jump forward to index j (with i < j) in the following way: + * + * During odd numbered jumps (ie. jumps 1, 3, 5, ...), you jump to the index j such that A[i] <= A[j] and A[j] is + * the smallest possible value. If there are multiple such indexes j, you can only jump to the smallest such index j. + * During even numbered jumps (ie. jumps 2, 4, 6, ...), you jump to the index j such that A[i] >= A[j] and A[j] is + * the largest possible value. If there are multiple such indexes j, you can only jump to the smallest such index j. + * (It may be the case that for some index i, there are no legal jumps.) + * A starting index is good if, starting from that index, you can reach the end of the array (index A.length - 1) by + * jumping some number of times (possibly 0 or more than once.) + * + * Return the number of good starting indexes. + * + * + * + * Example 1: + * + * Input: [10,13,12,14,15] + * Output: 2 + * Explanation: + * From starting index i = 0, we can jump to i = 2 (since A[2] is the smallest among A[1], A[2], A[3], A[4] that is + * greater or equal to A[0]), then we can't jump any more. + * From starting index i = 1 and i = 2, we can jump to i = 3, then we can't jump any more. + * From starting index i = 3, we can jump to i = 4, so we've reached the end. + * From starting index i = 4, we've reached the end already. + * In total, there are 2 different starting indexes (i = 3, i = 4) where we can reach the end with some number of jumps. + * Example 2: + * + * Input: [2,3,1,1,4] + * Output: 3 + * Explanation: + * From starting index i = 0, we make jumps to i = 1, i = 2, i = 3: + * + * During our 1st jump (odd numbered), we first jump to i = 1 because A[1] is the smallest value in (A[1], A[2], + * A[3], A[4]) that is greater than or equal to A[0]. + * + * During our 2nd jump (even numbered), we jump from i = 1 to i = 2 because A[2] is the largest value in (A[2], A[3], + * A[4]) that is less than or equal to A[1]. A[3] is also the largest value, but 2 is a smaller index, so we can + * only jump to i = 2 and not i = 3. + * + * During our 3rd jump (odd numbered), we jump from i = 2 to i = 3 because A[3] is the smallest value in (A[3], A[4]) + * that is greater than or equal to A[2]. + * + * We can't jump from i = 3 to i = 4, so the starting index i = 0 is not good. + * + * In a similar manner, we can deduce that: + * From starting index i = 1, we jump to i = 4, so we reach the end. + * From starting index i = 2, we jump to i = 3, and then we can't jump anymore. + * From starting index i = 3, we jump to i = 4, so we reach the end. + * From starting index i = 4, we are already at the end. + * In total, there are 3 different starting indexes (i = 1, i = 3, i = 4) where we can reach the end with some number + * of jumps. + * Example 3: + * + * Input: [5,1,3,4,2] + * Output: 3 + * Explanation: + * We can reach the end from starting indexes 1, 2, and 4. + * + * + * Note: + * + * 1 <= A.length <= 20000 + * 0 <= A[i] < 100000 + * + * Solution: O(N log N) + * For each array index and for each odd/even turn pre-calculate the next jump index - this can be achieved in O(n + * log n) by using a balanced tree. + * Check for each array index if we can reach end of the array by using the pre-calculated values for next jump - + * cache the values to avoid recalculating. Sum up total number of such start indices and that will be the answer. + */ +public class OddEvenJump { + + private class Node { + int num, pos; + Node(int num, int pos){ + this.num = num; + this.pos = pos; + } + } + + TreeSet treeSet; + int[][] next; + int[][] possible; + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[] A = {10,13,12,14,15}; + System.out.println(new OddEvenJump().oddEvenJumps(A)); + } + + public int oddEvenJumps(int[] A) { + treeSet = new TreeSet<>(Comparator.comparingInt(o -> o.num)); + next = new int[2][A.length]; + possible = new int[2][A.length]; + Arrays.fill(next[0], -1); + Arrays.fill(next[1], -1); + Arrays.fill(possible[0], -1); + Arrays.fill(possible[1], -1); + for(int i = A.length - 1; i >= 0; i --) { + int num = A[i]; + // odd case + Node curr = new Node(num, i); + Node ceil = treeSet.ceiling(new Node(num, i)); + if (ceil != null) { + next[0][i] = ceil.pos; + } + // even case + Node floor = treeSet.floor(new Node(num, i)); + if (floor != null) { + next[1][i] = floor.pos; + } + treeSet.remove(curr); + treeSet.add(curr); + } + int count = 0; + for(int i = 0; i < A.length; i ++){ + count += dp(A, i, next, possible, 0) == 1 ? 1 : 0; + } + return count; + } + + + private int dp(int[] A, int i, int[][] next, int[][] possible, int oddOrEven){ + if(i == A.length - 1) return 1; + else if(possible[oddOrEven][i] == 1 || possible[oddOrEven][i] == 0){ + return possible[oddOrEven][i]; + }else{ + int nextPos = oddOrEven == 0 ? next[0][i] : next[1][i]; + if(nextPos == -1){ + possible[oddOrEven][i] = 0; + return possible[oddOrEven][i]; + } else { + possible[oddOrEven][i] = dp(A, nextPos, next, possible, ((oddOrEven + 1) % 2)); + return possible[oddOrEven][i]; + } + } + } +} diff --git a/problems/src/dynamic_programming/StoneGame.java b/problems/src/dynamic_programming/StoneGame.java new file mode 100644 index 00000000..e7aa6e18 --- /dev/null +++ b/problems/src/dynamic_programming/StoneGame.java @@ -0,0 +1,101 @@ +package dynamic_programming; + +import java.util.*; +/** + * Created by gouthamvidyapradhan on 22/03/2019 + * Alex and Lee play a game with piles of stones. There are an even number of piles arranged in a row, and each + * pile has a positive integer number of stones piles[i]. + * + * The objective of the game is to end with the most stones. The total number of stones is odd, so there are no ties. + * + * Alex and Lee take turns, with Alex starting first. Each turn, a player takes the entire pile of stones from + * either the beginning or the end of the row. This continues until there are no more piles left, at which point + * the person with the most stones wins. + * + * Assuming Alex and Lee play optimally, return True if and only if Alex wins the game. + * + * + * + * Example 1: + * + * Input: [5,3,4,5] + * Output: true + * Explanation: + * Alex starts first, and can only take the first 5 or the last 5. + * Say he takes the first 5, so that the row becomes [3, 4, 5]. + * If Lee takes 3, then the board is [4, 5], and Alex takes 5 to win with 10 points. + * If Lee takes the last 5, then the board is [3, 4], and Alex takes 4 to win with 9 points. + * This demonstrated that taking the first 5 was a winning move for Alex, so we return true. + * + * + * Note: + * + * 2 <= piles.length <= 500 + * piles.length is even. + * 1 <= piles[i] <= 500 + * sum(piles) is odd. + * + * Solution: + * O(N ^ 2) + * Each state can be considered as State = (total stones left, player's turn). Do a dfs on each state and memoize + * the result in order not to recalculate. When all the stones are exhausted - Alex wins if the total collected stones + * by her is greater than total collected by Lee + */ +public class StoneGame { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[] A = {5,3,4,5}; + System.out.println(new StoneGame().stoneGame(A)); + } + + public boolean stoneGame(int[] piles) { + int sum = 0; + for(int i = 0; i < piles.length; i ++){ + sum += piles[i]; + } + int[][] A = new int[2][sum + 1]; + Arrays.fill(A[0], -1); + Arrays.fill(A[1], -1); + int result = dp(A, piles, 0, piles.length - 1, sum, 0, 0, 0); + return result == 1; + } + + private int dp(int[][] A, int[] piles, int i, int j, int sum, int p, int sumA, int sumB){ + if(A[p][sum] != -1) return A[p][sum]; + else { + if(p == 0){ + if(i <= j){ + int result = dp(A, piles, i + 1, j, sum - piles[i], (p + 1) % 2, sumA + piles[i], sumB); + if(result == 0){ + A[p][sum] = 1; + return 1; + } else { + result = dp(A, piles, i, j - 1, sum - piles[j], (p + 1) % 2, sumA + piles[j], sumB); + A[p][sum] = result; + return result; + } + } else{ + if(sumA > sumB) return 1; else return 0; + } + } else { + if(i <= j){ + int result = dp(A, piles, i + 1, j, sum - piles[i], (p + 1) % 2, sumA, sumB + piles[i]); + if(result == 0){ + A[p][sum] = 1; + return 1; + } else { + result = dp(A, piles, i, j - 1, sum - piles[j], (p + 1) % 2, sumA, sumB + piles[j]); + A[p][sum] = result; + return result; + } + } else{ + if(sumB > sumA) return 1; else return 0; + } + } + } + } +} diff --git a/problems/src/linked_list/MiddleOfLinkedList.java b/problems/src/linked_list/MiddleOfLinkedList.java new file mode 100644 index 00000000..33425f14 --- /dev/null +++ b/problems/src/linked_list/MiddleOfLinkedList.java @@ -0,0 +1,57 @@ +package linked_list; + +/** + * Created by gouthamvidyapradhan on 22/03/2019 + * Given a non-empty, singly linked list with head node head, return a middle node of linked list. + * + * If there are two middle nodes, return the second middle node. + * + * + * + * Example 1: + * + * Input: [1,2,3,4,5] + * Output: Node 3 from this list (Serialization: [3,4,5]) + * The returned node has value 3. (The judge's serialization of this node is [3,4,5]). + * Note that we returned a ListNode object ans, such that: + * ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, and ans.next.next.next = NULL. + * Example 2: + * + * Input: [1,2,3,4,5,6] + * Output: Node 4 from this list (Serialization: [4,5,6]) + * Since the list has two middle nodes with values 3 and 4, we return the second one. + * + * Solution: O(N) + * Return the middle node. middle = count / 2 + */ +public class MiddleOfLinkedList { + + public class ListNode { + int val; + ListNode next; + ListNode(int x) { val = x; } + } + /** + * Main method + * @param args + */ + public static void main(String[] args) { + } + + public ListNode middleNode(ListNode head) { + int count = 0; + ListNode temp = head; + while(temp != null){ + temp = temp.next; + count++; + } + int mid = count / 2; + int c = 0; + while(head != null && c < mid){ + head = head.next; + c++; + } + return head; + } + +} diff --git a/problems/src/math/NthMagicalNumber.java b/problems/src/math/NthMagicalNumber.java new file mode 100644 index 00000000..38ac55e1 --- /dev/null +++ b/problems/src/math/NthMagicalNumber.java @@ -0,0 +1,94 @@ +package math; + +import java.math.BigInteger; + +/** + * Created by gouthamvidyapradhan on 23/03/2019 + * A positive integer is magical if it is divisible by either A or B. + * + * Return the N-th magical number. Since the answer may be very large, return it modulo 10^9 + 7. + * + * + * + * Example 1: + * + * Input: N = 1, A = 2, B = 3 + * Output: 2 + * Example 2: + * + * Input: N = 4, A = 2, B = 3 + * Output: 6 + * Example 3: + * + * Input: N = 5, A = 2, B = 4 + * Output: 10 + * Example 4: + * + * Input: N = 3, A = 6, B = 4 + * Output: 8 + * + * + * Note: + * + * 1 <= N <= 10^9 + * 2 <= A <= 40000 + * 2 <= B <= 40000 + * + * Solution: O(log((2 ^ 64) - 1)) + * Lets take example of N = 5, A = 4 and B = 6 + * The multiple of A are 4, 8, 12, 16, 20, 24 . . . + * The multiple of B are 6, 12, 18, 24 . . . + * + * Lets take a arbitrary number E = 21 and see if this fits the correct answer + * E / A = 5 + * E / B = 3 + * This means there are 5 + 3 = 8 numbers which are divisible by either A or B such as + * 4, 6, 8, 12, 12, 16, 18, 20 but we have double counted number 12 so we have to reduce 8 by 1 therefore there are + * 7 numbers. But, 7 is greater than required number N = 5 that means we have to search between 0 and E - 1. + * Thus we can binary search to arrive at the answer. + * + * The number of common multiples such as 12 in the above example can be found by E / LCM(4, 6) + */ +public class NthMagicalNumber { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + System.out.println(new NthMagicalNumber().nthMagicalNumber(3, 2, 4)); + } + + public int nthMagicalNumber(int N, int A, int B) { + final int CONST = 1000000007; + BigInteger bigInteger = new BigInteger(String.valueOf(A)); + long aL = (long)A * B; + long lcm = aL / bigInteger.gcd(new BigInteger(String.valueOf(B))).longValue(); + long l = 0, h = Long.MAX_VALUE; + while(l <= h){ + long m = l + (h - l) / 2; + int status = check(N, m, A, B, lcm); + if(status == 0){ + long modA = m % A; + long modB = m % B; + if(modA == 0 || modB == 0) return (int)(m % CONST); + else if(modA < modB) return (int)((m - modA) % CONST); + else return (int)((m - modB) % CONST); + } else if(status == -1){ + l = m + 1; + } else { + h = m - 1; + } + } + return 0; + } + + private int check(int N, long num, int A, int B, long lcm){ + long sum = (num / A) + (num / B); + long common = num / lcm; + sum -= common; + if(sum == N) return 0; + else if(sum > N) return 1; + else return -1; + } +} diff --git a/problems/src/string/LongestPalindrome.java b/problems/src/string/LongestPalindrome.java new file mode 100644 index 00000000..a5bc9792 --- /dev/null +++ b/problems/src/string/LongestPalindrome.java @@ -0,0 +1,57 @@ +package string; +/** + * Created by gouthamvidyapradhan on 20/03/2019 + * Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that + * can be built with those letters. + * + * This is case sensitive, for example "Aa" is not considered a palindrome here. + * + * Note: + * Assume the length of given string will not exceed 1,010. + * + * Example: + * + * Input: + * "abccccdd" + * + * Output: + * 7 + * + * Explanation: + * One longest palindrome that can be built is "dccaccd", whose length is 7. + */ +import java.util.*; + +public class LongestPalindrome { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int result = new LongestPalindrome().longestPalindrome( + "asdfasdf"); + System.out.println(result); + } + + public int longestPalindrome(String s) { + Map map = new HashMap<>(); + for(char c : s.toCharArray()){ + map.putIfAbsent(c, 0); + int count = map.get(c); + map.put(c, count + 1); + } + int max = 0; + boolean odd = false; + for(char c : map.keySet()){ + int count = map.get(c); + max += count; + if((count % 2) != 0){ + max --; + odd = true; + } + } + if(odd) max ++; + return max; + } +} diff --git a/problems/src/string/ValidWordAbbreviation.java b/problems/src/string/ValidWordAbbreviation.java new file mode 100644 index 00000000..e3653943 --- /dev/null +++ b/problems/src/string/ValidWordAbbreviation.java @@ -0,0 +1,73 @@ +package string; +/** + * Created by gouthamvidyapradhan on 20/03/2019 + * Given a non-empty string s and an abbreviation abbr, return whether the string matches with the given abbreviation. + * + * A string such as "word" contains only the following valid abbreviations: + * + * ["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"] + * Notice that only the above abbreviations are valid abbreviations of the string "word". Any other string is not a + * valid abbreviation of "word". + * + * Note: + * Assume s contains only lowercase letters and abbr contains only lowercase letters and digits. + * + * Example 1: + * Given s = "internationalization", abbr = "i12iz4n": + * + * Return true. + * Example 2: + * Given s = "apple", abbr = "a2e": + * + * Return false. + */ + +public class ValidWordAbbreviation { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + System.out.println(new ValidWordAbbreviation().validWordAbbreviation("abbreviation", "a10n")); + } + + public boolean validWordAbbreviation(String word, String abbr) { + if(abbr.length() > word.length()) return false; + StringBuilder num = new StringBuilder(); + int j = 0; + for(int i = 0; i < abbr.length() && j < word.length(); i ++){ + char curr = abbr.charAt(i); + if(curr == '0' && num.toString().isEmpty()) return false; + if(curr >= '0' && curr <= '9'){ + num.append(curr); + } else{ + if(num.toString().isEmpty()){ + if(word.charAt(j) != abbr.charAt(i)){ + return false; + } + j++; + } else{ + int next = Integer.parseInt(num.toString()); + j += next; + if(word.length() <= j){ + return false; + } + if(word.charAt(j) != abbr.charAt(i)){ + return false; + } + num = new StringBuilder(); + j++; + } + } + } + if(!num.toString().isEmpty()){ + int next = Integer.parseInt(num.toString()); + j += next; + if(j > word.length() || j < word.length()){ + return false; + } + } + return true; + } +} diff --git a/problems/src/tree/ConvertBSTToGreaterTree.java b/problems/src/tree/ConvertBSTToGreaterTree.java new file mode 100644 index 00000000..74064013 --- /dev/null +++ b/problems/src/tree/ConvertBSTToGreaterTree.java @@ -0,0 +1,54 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 14/03/2019 + * Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed + * to the original key plus sum of all keys greater than the original key in BST. + * + * Example: + * + * Input: The root of a Binary Search Tree like this: + * 5 + * / \ + * 2 13 + * + * Output: The root of a Greater Tree like this: + * 18 + * / \ + * 20 13 + */ +public class ConvertBSTToGreaterTree { + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + TreeNode node = new TreeNode(5); + node.right = new TreeNode(13); + node.left = new TreeNode(2); + node.left.left = new TreeNode(1); + node.left.right = new TreeNode(3); + TreeNode result = new ConvertBSTToGreaterTree().convertBST(node); + System.out.println(result); + } + + public TreeNode convertBST(TreeNode root) { + postOrder(root, 0); + return root; + } + + private int postOrder(TreeNode node, int value){ + if(node == null) return value; + int right = postOrder(node.right, value); + node.val = node.val + right; + return postOrder(node.left, node.val); + } +} diff --git a/problems/src/tree/SerializeAndDeserializeNAryTree.java b/problems/src/tree/SerializeAndDeserializeNAryTree.java new file mode 100644 index 00000000..03f67496 --- /dev/null +++ b/problems/src/tree/SerializeAndDeserializeNAryTree.java @@ -0,0 +1,121 @@ +package tree; +import java.util.*; +import java.util.stream.Collectors; + +/** + * Created by gouthamvidyapradhan on 16/03/2019 + * Serialization is the process of converting a data structure or object into a sequence of bits so that it can be + * stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in + * the same or another computer environment. + * + * Design an algorithm to serialize and deserialize an N-ary tree. An N-ary tree is a rooted tree in which each node + * has no more than N children. There is no restriction on how your serialization/deserialization algorithm should + * work. You just need to ensure that an N-ary tree can be serialized to a string and this string can be + * deserialized to the original tree structure. + * + * For example, you may serialize the following 3-ary tree + * + * 1 + * /|\ + * 3 2 4 + * /\ + * 5 6 + * + * as [1 [3[5 6] 2 4]]. You do not necessarily need to follow this format, so please be creative and come up with + * different approaches yourself. + * + * + * + * Note: + * + * N is in the range of [1, 1000] + * Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should + * be stateless. + * + * Solution: To encode recursively iterate through each node and build a root and its children as 3[5,6] where 3 is the + * root and 5, 6 are its children. + * To decode, build the root node first and then recursively build its children. + */ +public class SerializeAndDeserializeNAryTree { + + static class Node { + public int val; + public List children; + + public Node() {} + + public Node(int _val,List _children) { + val = _val; + children = _children; + } + } + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + Node n1 = new Node(5, new ArrayList<>()); + Node n2 = new Node(6, Arrays.asList(n1)); + Node n3 = new Node(2, Arrays.asList(n2)); + Node n4 = new Node(4, Arrays.asList(n3)); + Node n5 = new Node(3, Arrays.asList(n4)); + Node root = new Node(1, Arrays.asList(n5)); + SerializeAndDeserializeNAryTree serializer = new SerializeAndDeserializeNAryTree(); + String result = serializer.serialize(root); + Node rootNode = serializer.deserialize(result); + System.out.println(result); + System.out.println(rootNode); + } + + // Encodes a tree to a single string. + public String serialize(Node root) { + if(root != null){ + String curr = String.valueOf(root.val); + List children = root.children; + return children != null ? + curr + "[" + children.stream().map(this::serialize).collect(Collectors.joining(",")) + "]" : + curr + "[]"; + } else { + return ""; + } + } + + // Decodes your encoded data to tree. + public Node deserialize(String data) { + char[] arr = data.toCharArray(); + StringBuilder num = new StringBuilder(); + Queue queue = new ArrayDeque<>(); + for(char c : arr){ + if(c >= '0' && c <= '9'){ + num.append(c); + } else if(c == '['){ + if(num.length() != 0){ + queue.offer(num.toString()); + num = new StringBuilder(); + } + queue.offer("["); + } else { + queue.offer(String.valueOf(c)); + } + } + if(queue.isEmpty()) return null; + return decode(queue).get(0); + } + + private List decode(Queue elements){ + List children = new ArrayList<>(); + while(!elements.isEmpty()){ + String curr = elements.poll(); + if(curr.equals("[") || curr.equals(",")){ + } else if(curr.equals("]")){ + return children; + } else{ + int num = Integer.parseInt(curr); + Node currNode = new Node(num, decode(elements)); + children.add(currNode); + } + } + return children; + } +} From 9c883b73741650e9eea801acd41ec7d980e6a7aa Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 6 Apr 2019 13:43:43 +0200 Subject: [PATCH 207/235] Solved problems --- README.md | 9 ++ problems/src/array/ChampagneTower.java | 74 ++++++++++++ .../array/SubArraysWithBoundedMaximum.java | 63 ++++++++++ problems/src/array/ValidTicTacToeState.java | 88 ++++++++++++++ .../AllPathsFromSourceToTarget.java | 63 ++++++++++ .../ProfitableSchemes.java | 79 +++++++++++++ .../SmallestRotationWithHighestScore.java | 104 +++++++++++++++++ .../string/NumberOfMatchingSubsequences.java | 59 ++++++++++ problems/src/string/ReplaceWords.java | 109 ++++++++++++++++++ problems/src/string/RotateString.java | 45 ++++++++ .../NumberOfMatchingSubsequences.java | 63 ++++++++++ 11 files changed, 756 insertions(+) create mode 100644 problems/src/array/ChampagneTower.java create mode 100644 problems/src/array/SubArraysWithBoundedMaximum.java create mode 100644 problems/src/array/ValidTicTacToeState.java create mode 100644 problems/src/depth_first_search/AllPathsFromSourceToTarget.java create mode 100644 problems/src/dynamic_programming/ProfitableSchemes.java create mode 100644 problems/src/heap/SmallestRotationWithHighestScore.java create mode 100644 problems/src/string/NumberOfMatchingSubsequences.java create mode 100644 problems/src/string/ReplaceWords.java create mode 100644 problems/src/string/RotateString.java create mode 100644 problems/src/two_pointers/NumberOfMatchingSubsequences.java diff --git a/README.md b/README.md index 6d959925..1d1dc859 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,9 @@ My accepted leetcode solutions to some of the common interview problems. - [Employee Free Time](problems/src/array/EmployeeFreeTime.java) (Hard) - [Best Meeting Point](problems/src/array/BestMeetingPoint.java) (Hard) - [My Calendar III](problems/src/array/MyCalendarThree.java) (Hard) +- [Champagne Tower](problems/src/array/ChampagneTower.java) (Medium) +- [Valid Tic-Tac-Toe State](problems/src/array/ValidTicTacToeState.java) (Medium) +- [Number of Subarrays with Bounded Maximum](problems/src/array/SubArraysWithBoundedMaximum.java) (Medium) #### [Backtracking](problems/src/backtracking) @@ -116,6 +119,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Bricks Falling When Hit](problems/src/depth_first_search/BricksFallingWhenHit.java) (Hard) - [Robot Room Cleaner](problems/src/depth_first_search/RobotRoomCleaner.java) (Hard) - [Cracking the Safe](problems/src/depth_first_search/CrackingTheSafe.java) (Hard) +- [All Paths From Source to Target](problems/src/depth_first_search/AllPathsFromSourceToTarget.java) (Medium) #### [Design](problems/src/design) @@ -188,6 +192,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Cat and Mouse](problems/src/dynamic_programming/CatAndMouse.java) (Hard) - [Stone Game](problems/src/dynamic_programming/StoneGame.java) (Medium) - [Odd Even Jump](problems/src/dynamic_programming/OddEvenJump.java) (Hard) +- [Profitable Schemes](problems/src/dynamic_programming/ProfitableSchemes.java) (Hard) #### [Greedy](problems/src/greedy) @@ -225,6 +230,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Meeting Rooms II](problems/src/heap/MeetingRoomsII.java) (Medium) - [Top K Frequent Words](problems/src/heap/TopKFrequentWords.java) (Medium) - [Candy](problems/src/heap/Candy.java) (Hard) +- [Smallest Rotation with Highest Score](problems/src/heap/SmallestRotationWithHighestScore.java) (Hard) #### [Linked List](problems/src/linked_list) @@ -301,6 +307,8 @@ My accepted leetcode solutions to some of the common interview problems. - [Shortest Palindrome](problems/src/string/ShortestPalindrome.java) (Hard) - [Valid Word Abbreviation](problems/src/string/ValidWordAbbreviation.java) (Easy) - [Longest Palindrome](problems/src/string/LongestPalindrome.java) (Easy) +- [Replace Words](problems/src/string/ReplaceWords.java) (Medium) +- [Rotate String](problems/src/string/RotateString.java) (Easy) #### [Tree](problems/src/tree) @@ -361,4 +369,5 @@ My accepted leetcode solutions to some of the common interview problems. - [Minimum Window Substring](problems/src/two_pointers/MinimumWindowSubstring.java) (Hard) - [Smallest Range](problems/src/two_pointers/SmallestRange.java) (Hard) - [Subarray Product Less Than K](problems/src/two_pointers/SubarrayProductLessThanK.java) (Medium) +- [Number of Matching Subsequences](problems/src/two_pointers/NumberOfMatchingSubsequences.java) (Medium) diff --git a/problems/src/array/ChampagneTower.java b/problems/src/array/ChampagneTower.java new file mode 100644 index 00000000..cedcb529 --- /dev/null +++ b/problems/src/array/ChampagneTower.java @@ -0,0 +1,74 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 28/03/2019 + * We stack glasses in a pyramid, where the first row has 1 glass, the second row has 2 glasses, and so on until the + * 100th row. Each glass holds one cup (250ml) of champagne. + * + * Then, some champagne is poured in the first glass at the top. When the top most glass is full, any excess liquid + * poured will fall equally to the glass immediately to the left and right of it. When those glasses become full, + * any excess champagne will fall equally to the left and right of those glasses, and so on. (A glass at the bottom + * row has it's excess champagne fall on the floor.) + * + * For example, after one cup of champagne is poured, the top most glass is full. After two cups of champagne are + * poured, the two glasses on the second row are half full. After three cups of champagne are poured, those two + * cups become full - there are 3 full glasses total now. After four cups of champagne are poured, the third row + * has the middle glass half full, and the two outside glasses are a quarter full, as pictured below. + * + * + * + * Now after pouring some non-negative integer cups of champagne, return how full the j-th glass in the i-th row is + * (both i and j are 0 indexed.) + * + * + * + * Example 1: + * Input: poured = 1, query_glass = 1, query_row = 1 + * Output: 0.0 + * Explanation: We poured 1 cup of champange to the top glass of the tower (which is indexed as (0, 0)). There will + * be no excess liquid so all the glasses under the top glass will remain empty. + * + * Example 2: + * Input: poured = 2, query_glass = 1, query_row = 1 + * Output: 0.5 + * Explanation: We poured 2 cups of champange to the top glass of the tower (which is indexed as (0, 0)). There is + * one cup of excess liquid. The glass indexed as (1, 0) and the glass indexed as (1, 1) will share the excess liquid + * equally, and each will get half cup of champange. + * + * + * Note: + * + * poured will be in the range of [0, 10 ^ 9]. + * query_glass and query_row will be in the range of [0, 99]. + * + * Solution: Calculate for every glass and for each row at a time. Use the value from the previous row to calculate the + * current value. + * @see PascalsTriangle + */ +public class ChampagneTower { + /** + * Main method + * @param args + */ + public static void main(String[] args) { + System.out.println(new ChampagneTower().champagneTower(4, 2, 1)); + } + + public double champagneTower(int poured, int query_row, int query_glass) { + double[][] A = new double[query_row + 1][query_row + 1]; + A[0][0] = poured; + for(int i = 1; i <= query_row; i ++){ + for(int j = 0; j <= query_row; j ++){ + if(A[i - 1][j] > 1.0){ + A[i][j] += (A[i - 1][j] - 1.0) / 2; + } + if(j == 0) continue; + if(A[i - 1][j - 1] > 1.0){ + A[i][j] += (A[i - 1][j - 1] - 1.0) / 2; + } + } + } + if(A[query_row][query_glass] > 1.0) return 1; + else return A[query_row][query_glass]; + } +} diff --git a/problems/src/array/SubArraysWithBoundedMaximum.java b/problems/src/array/SubArraysWithBoundedMaximum.java new file mode 100644 index 00000000..dab0cc04 --- /dev/null +++ b/problems/src/array/SubArraysWithBoundedMaximum.java @@ -0,0 +1,63 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 29/03/2019 + * We are given an array A of positive integers, and two positive integers L and R (L <= R). + * + * Return the number of (contiguous, non-empty) subarrays such that the value of the maximum array element in that + * subarray is at least L and at most R. + * + * Example : + * Input: + * A = [2, 1, 4, 3] + * L = 2 + * R = 3 + * Output: 3 + * Explanation: There are three subarrays that meet the requirements: [2], [2, 1], [3]. + * Note: + * + * L, R and A[i] will be an integer in the range [0, 10^9]. + * The length of A will be in the range of [1, 50000]. + */ +public class SubArraysWithBoundedMaximum { + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[] A = {2, 1, 4, 3}; + System.out.println(new SubArraysWithBoundedMaximum().numSubarrayBoundedMax(A, 2, 3)); + } + + public int numSubarrayBoundedMax(int[] A, int L, int R) { + int[] DP = new int[A.length]; + int v = -1; + for(int i = A.length - 1; i >= 0; i --){ + if(A[i] >= L && A[i] <= R){ + if(v != -1){ + DP[i] = v - i + 1; + } else { + DP[i] = 1; + v = i; + } + } else if(A[i] < L){ + if(v == -1){ + v = i; + } if(i + 1 < A.length){ + if(A[i + 1] < L || (A[i + 1] >= L && A[i + 1] <= R)){ + DP[i] = DP[i + 1]; + } else { + DP[i] = 0; + } + } + } else { + v = -1; + } + } + int sum = 0; + for(int i = 0; i < DP.length; i ++){ + sum += DP[i]; + } + return sum; + } +} diff --git a/problems/src/array/ValidTicTacToeState.java b/problems/src/array/ValidTicTacToeState.java new file mode 100644 index 00000000..d2c20820 --- /dev/null +++ b/problems/src/array/ValidTicTacToeState.java @@ -0,0 +1,88 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 29/03/2019 + * A Tic-Tac-Toe board is given as a string array board. Return True if and only if it is possible to reach this + * board position during the course of a valid tic-tac-toe game. + * + * The board is a 3 x 3 array, and consists of characters " ", "X", and "O". The " " character represents an empty + * square. + * + * Here are the rules of Tic-Tac-Toe: + * + * Players take turns placing characters into empty squares (" "). + * The first player always places "X" characters, while the second player always places "O" characters. + * "X" and "O" characters are always placed into empty squares, never filled ones. + * The game ends when there are 3 of the same (non-empty) character filling any row, column, or diagonal. + * The game also ends if all squares are non-empty. + * No more moves can be played if the game is over. + * Example 1: + * Input: board = ["O ", " ", " "] + * Output: false + * Explanation: The first player always plays "X". + * + * Example 2: + * Input: board = ["XOX", " X ", " "] + * Output: false + * Explanation: Players take turns making moves. + * + * Example 3: + * Input: board = ["XXX", " ", "OOO"] + * Output: false + * + * Example 4: + * Input: board = ["XOX", "O O", "XOX"] + * Output: true + * Note: + * + * board is a length-3 array of strings, where each string board[i] has length 3. + * Each board[i][j] is a character in the set {" ", "X", "O"}. + * + * Solution: Do a brute-force check for each row, column and diagonals and keep track of count of 'X' and 'O' + */ +public class ValidTicTacToeState { + /** + * Main method + * @param args + */ + public static void main(String[] args) { + String[] board = {"XXX", "XOO", "OO "}; + System.out.println(new ValidTicTacToeState().validTicTacToe(board)); + } + + public boolean validTicTacToe(String[] board) { + boolean xWon = hasWon(board, 'X'); + boolean oWon = hasWon(board, 'O'); + int xcount = 0, ocount = 0; + for(int i = 0; i < 3; i ++){ + for(int j = 0; j < 3; j ++){ + if(board[i].charAt(j) == 'X'){ + xcount++; + }else if(board[i].charAt(j) == 'O'){ + ocount++; + } + } + } + if(xWon && oWon) return false; + if(xWon){ + return ((xcount - 1 == ocount)); + } else if(oWon){ + return ((xcount == ocount)); + } else { + return (xcount == ocount || xcount - 1 == ocount); + } + } + + private boolean hasWon(String[] board, char c){ + boolean diagnol = ((board[0].charAt(0) == c && board[1].charAt(1) == c && board[2].charAt(2) == c) || + (board[0].charAt(2) == c && board[1].charAt(1) == c && board[2].charAt(0) == c)); + if(diagnol) return true; + for(int i = 0; i < 3; i ++){ + if(board[i].charAt(0) == c && board[i].charAt(1) == c && board[i].charAt(2) == c) return true; + } + for(int i = 0; i < 3; i ++){ + if(board[0].charAt(i) == c && board[1].charAt(i) == c && board[2].charAt(i) == c) return true; + } + return false; + } +} diff --git a/problems/src/depth_first_search/AllPathsFromSourceToTarget.java b/problems/src/depth_first_search/AllPathsFromSourceToTarget.java new file mode 100644 index 00000000..da0b0f46 --- /dev/null +++ b/problems/src/depth_first_search/AllPathsFromSourceToTarget.java @@ -0,0 +1,63 @@ +package depth_first_search; + +import java.util.*; +/** + * Created by gouthamvidyapradhan on 28/03/2019 + * 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. + * Note: + * + * The number of nodes in the graph will be in the range [2, 15]. + * You can print different paths in any order, but you should keep the order of nodes inside one path. + * + * Solution: Do a dfs to reach every path. Since its a DAG there can be no cycles and safe to proceed without + * checking if the node has already been visited. Maintain a stack to keep track of the path and when a leaf node + * has been reached add the elements in the stack to the result array + */ +public class AllPathsFromSourceToTarget { + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[][] graph = {{1, 2}, {3}, {3}, {}}; + System.out.println(new AllPathsFromSourceToTarget().allPathsSourceTarget(graph)); + } + + public List> allPathsSourceTarget(int[][] graph) { + Set done = new HashSet<>(); + Stack stack = new Stack<>(); + List> result = new ArrayList<>(); + dfs(result, done, 0, stack, graph); + return result; + } + + private void dfs(List> result, Set done, int i, Stack stack, int[][] graph){ + done.add(i); + stack.push(i); + int[] children = graph[i]; + if(children.length == 0){ + List childList = new ArrayList<>(stack); + result.add(childList); + } else{ + for(int c : children){ + dfs(result, done, c, stack, graph); + } + } + stack.pop(); + done.remove(i); + } +} diff --git a/problems/src/dynamic_programming/ProfitableSchemes.java b/problems/src/dynamic_programming/ProfitableSchemes.java new file mode 100644 index 00000000..2b06488c --- /dev/null +++ b/problems/src/dynamic_programming/ProfitableSchemes.java @@ -0,0 +1,79 @@ +package dynamic_programming; +/** + * Created by gouthamvidyapradhan on 26/03/2019 + * There are G people in a gang, and a list of various crimes they could commit. + * + * The i-th crime generates a profit[i] and requires group[i] gang members to participate. + * + * If a gang member participates in one crime, that member can't participate in another crime. + * + * Let's call a profitable scheme any subset of these crimes that generates at least P profit, and the total number + * of gang members participating in that subset of crimes is at most G. + * + * How many schemes can be chosen? Since the answer may be very large, return it modulo 10^9 + 7. + * + * + * + * Example 1: + * + * Input: G = 5, P = 3, group = [2,2], profit = [2,3] + * Output: 2 + * Explanation: + * To make a profit of at least 3, the gang could either commit crimes 0 and 1, or just crime 1. + * In total, there are 2 schemes. + * Example 2: + * + * Input: G = 10, P = 5, group = [2,3,5], profit = [6,7,8] + * Output: 7 + * Explanation: + * To make a profit of at least 5, the gang could commit any crimes, as long as they commit one. + * There are 7 possible schemes: (0), (1), (2), (0,1), (0,2), (1,2), and (0,1,2). + * + * + * Note: + * + * 1 <= G <= 100 + * 0 <= P <= 100 + * 1 <= group[i] <= 100 + * 0 <= profit[i] <= 100 + * 1 <= group.length = profit.length <= 100 + * + * Solution: O(G x P) Time and Space complexity. The problem is similar to the standard Knapsack DP problem. For every + * group value (ranging from 0 - 100) if a minimum of profit can be achieved then add this to the total count. + * Sum up the count (profitable schemes) for every group value ranging from 0 - G and return this as your answer. + */ +public class ProfitableSchemes { + + private final int MOD = 1000000007; + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[] group = {2, 3}; + int[] profit = {2, 5}; + System.out.println(new ProfitableSchemes().profitableSchemes(5, 2, group, profit)); + } + + public int profitableSchemes(int G, int P, int[] group, int[] profit) { + int[][] DP = new int[G + 1][P + 1]; + int ans = 0; + DP[0][0] = 1; + for(int k = group.length - 1; k >= 0; k --){ + int g = group[k]; + int p = profit[k]; + for(int i = DP.length - 1; i >= 0; i --) { + for(int j = DP[0].length - 1; j >= 0; j --) { + int r1 = (i - g < 0) ? 0 : DP[i - g][Math.max(0, j - p)]; + int r2 = DP[i][j]; + DP[i][j] = ((r1 % MOD) + (r2 % MOD)) % MOD; + } + } + } + for(int i = 0; i < DP.length; i ++){ + ans = (ans + DP[i][P]) % MOD; + } + return ans; + } + +} diff --git a/problems/src/heap/SmallestRotationWithHighestScore.java b/problems/src/heap/SmallestRotationWithHighestScore.java new file mode 100644 index 00000000..5d3d0bb4 --- /dev/null +++ b/problems/src/heap/SmallestRotationWithHighestScore.java @@ -0,0 +1,104 @@ +package heap; + +import java.util.Comparator; +import java.util.PriorityQueue; + +/** + * Created by gouthamvidyapradhan on 06/04/2019 + * Given an array A, we may rotate it by a non-negative integer K so that the array becomes A[K], A[K+1], A{K+2], ... + * A[A.length - 1], A[0], A[1], ..., A[K-1]. Afterward, any entries that are less than or equal to their index are + * worth 1 point. + * + * For example, if we have [2, 4, 1, 3, 0], and we rotate by K = 2, it becomes [1, 3, 0, 2, 4]. This is worth 3 + * points because 1 > 0 [no points], 3 > 1 [no points], 0 <= 2 [one point], 2 <= 3 [one point], 4 <= 4 [one point]. + * + * Over all possible rotations, return the rotation index K that corresponds to the highest score we could receive. + * If there are multiple answers, return the smallest such index K. + * + * Example 1: + * Input: [2, 3, 1, 4, 0] + * Output: 3 + * Explanation: + * Scores for each K are listed below: + * K = 0, A = [2,3,1,4,0], score 2 + * K = 1, A = [3,1,4,0,2], score 3 + * K = 2, A = [1,4,0,2,3], score 3 + * K = 3, A = [4,0,2,3,1], score 4 + * K = 4, A = [0,2,3,1,4], score 3 + * So we should choose K = 3, which has the highest score. + * + * + * + * Example 2: + * Input: [1, 3, 0, 2, 4] + * Output: 0 + * Explanation: A will always have 3 points no matter how it shifts. + * So we will choose the smallest K, which is 0. + * Note: + * + * A will have length at most 20000. + * A[i] will be in the range [0, A.length]. + * + * Solution O(NLogN). The key insight to this problem is to notice that the point of a number + * changes to 1 from 0 if the position changes to A.length - 1 and similarly the point changes to 1 from 0 if the + * position changes to a index = NUM - 1. + * Maintain a priority queue with rotation_count (the number of rotation required to change its points from either + * 0 to 1 or from 1 to 0), pop all the indices from priority queue which has rotation_count equal to current rotation + * count and update the rotation_count to its next value. + * Maintain a max count and the rotation index pair and return rotation index as the answer. + */ +public class SmallestRotationWithHighestScore { + + private class Node{ + int i, n, r, v; + Node(int i, int n, int r, int v){ + this.i = i; + this.n = n; + this.r = r; + this.v = v; + } + } + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[] A = {2, 3, 1, 4, 0}; + System.out.println(new SmallestRotationWithHighestScore().bestRotation(A)); + } + + public int bestRotation(int[] A) { + PriorityQueue pq = new PriorityQueue<>(Comparator.comparingInt(o -> o.r)); + int curr = 0; + for(int i = 0; i < A.length; i ++){ + int num = A[i]; + int v = 0, r = Integer.MAX_VALUE; + if(num <= i){ + v = 1; + curr++; + } + if(num != 0){ + r = v == 0 ? i + 1 : (i - num + 1); + } + pq.offer(new Node(i, num, r , v)); + } + int R = 0, max = curr, ans = 0; + while(R < A.length){ + while(pq.peek().r - R == 0){ + Node top = pq.poll(); + top.v = (top.v + 1) % 2; + top.i = (top.i - R < 0) ? (A.length + (top.i - R)) : (top.i - R); + top.r = top.v == 0 ? top.i + 1 : (top.i - top.n + 1); + top.r += R; + curr = (top.v == 0) ? curr - 1 : curr + 1; + pq.offer(top); + } + if(curr > max){ + ans = R; + max = curr; + } + R++; + } + return ans; + } +} diff --git a/problems/src/string/NumberOfMatchingSubsequences.java b/problems/src/string/NumberOfMatchingSubsequences.java new file mode 100644 index 00000000..02f63b8c --- /dev/null +++ b/problems/src/string/NumberOfMatchingSubsequences.java @@ -0,0 +1,59 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 04/04/2019 + * Given string S and a dictionary of words words, find the number of words[i] that is a subsequence of S. + * + * Example : + * Input: + * S = "abcde" + * words = ["a", "bb", "acd", "ace"] + * Output: 3 + * Explanation: There are three words in words that are a subsequence of S: "a", "acd", "ace". + * Note: + * + * All words in words and S will only consists of lowercase letters. + * The length of S will be in the range of [1, 50000]. + * The length of words will be in the range of [1, 5000]. + * The length of words[i] will be in the range of [1, 50]. + */ +public class NumberOfMatchingSubsequences { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + String[] A = {"a", "bb", "acd", "ace"}; + System.out.println(new NumberOfMatchingSubsequences().numMatchingSubseq("abcde", A)); + } + + public int numMatchingSubseq(String S, String[] words) { + int count = 0; + for(int i = 0; i < words.length; i ++){ + String w = words[i]; + if(isSubsequence(S, w)){ + count ++; + } + } + return count; + } + + private boolean isSubsequence(String S, String P){ + int i = 0, j = 0; + if(P.length() > S.length()) return false; + for(;;){ + if(j >= P.length()) return true; + else if(i >= S.length()) return false; + else { + if(S.charAt(i) == P.charAt(j)){ + i ++; + j ++; + } else { + i ++; + } + } + } + } + +} diff --git a/problems/src/string/ReplaceWords.java b/problems/src/string/ReplaceWords.java new file mode 100644 index 00000000..d5f99f6d --- /dev/null +++ b/problems/src/string/ReplaceWords.java @@ -0,0 +1,109 @@ +package string; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +/** + * Created by gouthamvidyapradhan on 04/04/2019 + * In English, we have a concept called root, which can be followed by some other words to form another longer word + * - let's call this word successor. For example, the root an, followed by other, which can form another word another. + * + * Now, given a dictionary consisting of many roots and a sentence. You need to replace all the successor in the + * sentence with the root forming it. If a successor has many roots can form it, replace it with the root with the + * shortest length. + * + * You need to output the sentence after the replacement. + * + * Example 1: + * + * Input: dict = ["cat", "bat", "rat"] + * sentence = "the cattle was rattled by the battery" + * Output: "the cat was rat by the bat" + * + * + * Note: + * + * The input will only have lower-case letters. + * 1 <= dict words number <= 1000 + * 1 <= sentence words number <= 1000 + * 1 <= root length <= 100 + * 1 <= sentence words length <= 1000 + * + * Solution: O(w + S) where w is the max length of each word in the dictionary and S is the length of the string. + * Add all the words in the dictionary to a trie and evaluate each word in the string to check if it matches any path + * in the trie. Terminate the search as soon as a leaf node in the trie has been reached. + */ +public class ReplaceWords { + class Trie { + private Map map; + + /** + * Initialize your data structure here. + */ + public Trie() { + map = new HashMap<>(); + } + + /** + * Inserts a word into the trie. + */ + public void insert(String word) { + if (word != null) { + add(0, word, word.length()); + } + } + + public String find(String s){ + return search(this, s, 0, new StringBuilder()); + } + + private void add(int i, String word, int length) { + if (i < length) { + char c = word.charAt(i); + Trie subTrie = map.get(c); + if (subTrie == null) { + subTrie = new Trie(); + map.put(c, subTrie); + } + subTrie.add(i + 1, word, length); + } else map.put(null, new Trie()); //use null to indicate end of string + } + + private String search(Trie curr, String s, int i, StringBuilder sb){ + if(s.length() == i) return sb.toString(); + else { + Trie subTrie = curr.map.get(s.charAt(i)); + if(subTrie == null){ + return curr.map.containsKey(null) ? sb.toString() : ""; + } else { + sb.append(s.charAt(i)); + if(subTrie.map.containsKey(null)) return sb.toString(); + return search(subTrie, s, i + 1, sb); + } + } + } + } + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + List words = Arrays.asList("a", "aa", "aaa"); + String sentence = "aa aa"; + System.out.println(new ReplaceWords().replaceWords(words, sentence)); + } + + public String replaceWords(List dict, String sentence) { + Trie root = new Trie(); + dict.forEach(root::insert); + String[] words = sentence.split(" "); + StringBuilder result = new StringBuilder(); + Stream.of(words).map(w -> {String s = root.find(w); return s.isEmpty() ? w.concat(" ") : + s.concat(" ");}).forEach(result::append); + return result.toString().trim(); + } +} diff --git a/problems/src/string/RotateString.java b/problems/src/string/RotateString.java new file mode 100644 index 00000000..2811d539 --- /dev/null +++ b/problems/src/string/RotateString.java @@ -0,0 +1,45 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 28/03/2019 + * We are given two strings, A and B. + * + * A shift on A consists of taking string A and moving the leftmost character to the rightmost position. For + * example, if A = 'abcde', then it will be 'bcdea' after one shift on A. Return True if and only if A can become B + * after some number of shifts on A. + * + * Example 1: + * Input: A = 'abcde', B = 'cdeab' + * Output: true + * + * Example 2: + * Input: A = 'abcde', B = 'abced' + * Output: false + * Note: + * + * A and B will have length at most 100. + */ +public class RotateString { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + System.out.println(new RotateString().rotateString("abcde", "cdeab")); + } + + public boolean rotateString(String A, String B) { + if(A.length() == 1 || A.isEmpty() || B.length() == 1 || B.isEmpty()) { + return A.equals(B); + } else if(A.length() != B.length()){ + return false; + } + for(int i = 0, l = A.length(); i < l; i ++){ + char s = A.charAt(0); + A = A.substring(1) + s; + if(A.equals(B)) return true; + } + return false; + } +} diff --git a/problems/src/two_pointers/NumberOfMatchingSubsequences.java b/problems/src/two_pointers/NumberOfMatchingSubsequences.java new file mode 100644 index 00000000..51dd3dc4 --- /dev/null +++ b/problems/src/two_pointers/NumberOfMatchingSubsequences.java @@ -0,0 +1,63 @@ +package two_pointers; + +/** + * Created by gouthamvidyapradhan on 04/04/2019 + * Given string S and a dictionary of words words, find the number of words[i] that is a subsequence of S. + * + * Example : + * Input: + * S = "abcde" + * words = ["a", "bb", "acd", "ace"] + * Output: 3 + * Explanation: There are three words in words that are a subsequence of S: "a", "acd", "ace". + * Note: + * + * All words in words and S will only consists of lowercase letters. + * The length of S will be in the range of [1, 50000]. + * The length of words will be in the range of [1, 5000]. + * The length of words[i] will be in the range of [1, 50]. + * + * Solution: O((w + S) x N (no of words)) + * Using two pointers technique check if each of the given string is a sub-sequence of the main string. + * + */ +public class NumberOfMatchingSubsequences { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + String[] A = {"a", "bb", "acd", "ace"}; + System.out.println(new NumberOfMatchingSubsequences().numMatchingSubseq("abcde", A)); + } + + public int numMatchingSubseq(String S, String[] words) { + int count = 0; + for(int i = 0; i < words.length; i ++){ + String w = words[i]; + if(isSubsequence(S, w)){ + count ++; + } + } + return count; + } + + private boolean isSubsequence(String S, String P){ + int i = 0, j = 0; + if(P.length() > S.length()) return false; + for(;;){ + if(j >= P.length()) return true; + else if(i >= S.length()) return false; + else { + if(S.charAt(i) == P.charAt(j)){ + i ++; + j ++; + } else { + i ++; + } + } + } + } + +} From d6e745afde4f3a5efb21e93905b6c76c94e21c23 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 7 Apr 2019 12:42:20 +0200 Subject: [PATCH 208/235] Solved problems --- README.md | 1 + .../src/binary_search/SwimInRisingWater.java | 120 ++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 problems/src/binary_search/SwimInRisingWater.java diff --git a/README.md b/README.md index 1d1dc859..668dc256 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Find Peak Element](problems/src/binary_search/FindPeakElement.java) (Medium) - [Target Sum](problems/src/binary_search/TargetSum.java) (Medium) - [H-Index II](problems/src/binary_search/HIndexII.java) (Medium) +- [Swim in Rising Water](problems/src/binary_search/SwimInRisingWater.java) (Hard) #### [Bit Manipulation](problems/src/bit_manipulation) diff --git a/problems/src/binary_search/SwimInRisingWater.java b/problems/src/binary_search/SwimInRisingWater.java new file mode 100644 index 00000000..adf717a0 --- /dev/null +++ b/problems/src/binary_search/SwimInRisingWater.java @@ -0,0 +1,120 @@ +package binary_search; + +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +/** + * Created by gouthamvidyapradhan on 07/04/2019 + * On an N x N grid, each square grid[i][j] represents the elevation at that point (i,j). + * + * Now rain starts to fall. At time t, the depth of the water everywhere is t. You can swim from a square to another + * 4-directionally adjacent square if and only if the elevation of both squares individually are at most t. You can + * swim infinite distance in zero time. Of course, you must stay within the boundaries of the grid during your swim. + * + * You start at the top left square (0, 0). What is the least time until you can reach the bottom right square (N-1, + * N-1)? + * + * Example 1: + * + * Input: [[0,2],[1,3]] + * Output: 3 + * Explanation: + * At time 0, you are in grid location (0, 0). + * You cannot go anywhere else because 4-directionally adjacent neighbors have a higher elevation than t = 0. + * + * You cannot reach point (1, 1) until time 3. + * When the depth of water is 3, we can swim anywhere inside the grid. + * Example 2: + * + * Input: [[0,1,2,3,4],[24,23,22,21,5],[12,13,14,15,16],[11,17,18,19,20],[10,9,8,7,6]] + * Output: 16 + * Explanation: + * 0 1 2 3 4 + * 24 23 22 21 5 + * 12 13 14 15 16 + * 11 17 18 19 20 + * 10 9 8 7 6 + * + * The final route is marked in bold. + * We need to wait until time 16 so that (0, 0) and (4, 4) are connected. + * Note: + * + * 2 <= N <= 50. + * grid[i][j] is a permutation of [0, ..., N*N - 1]. + * + * Solution: O(N ^ 2 x log N ^ 2) + * Binary search for the possible answers in the range [0 to N * N-1] and dfs through the grid to check if the + * destination is reachable + */ +public class SwimInRisingWater { + + private final int[] R = {0, 0, 1, -1}; + private final int[] C = {1, -1, 0, 0}; + + class Pair{ + int r, c; + Pair(int r, int c){ + this.r = r; + this.c = c; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Pair)) return false; + Pair pair = (Pair) o; + return r == pair.r && + c == pair.c; + } + + @Override + public int hashCode() { + return Objects.hash(r, c); + } + } + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[][] grid = {{0,1,2,3,4},{24,23,22,21,5},{12,13,14,15,16},{11,17,18,19,20},{10,9,8,7,6}}; + System.out.println(new SwimInRisingWater().swimInWater(grid)); + } + + public int swimInWater(int[][] grid) { + int l = 0, h = (grid.length * grid.length); + int ans = 0; + while(l <= h){ + int m = l + (h - l) / 2; + Set done = new HashSet<>(); + if(dfs(grid, 0, 0, done, m)){ + ans = m; + h = m - 1; + } else{ + l = m + 1; + } + } + return ans; + } + + private boolean dfs(int[][] grid, int r, int c, Set done, int V){ + if(r == grid.length - 1 && c == grid[0].length - 1) return true; + done.add(new Pair(r, c)); + for(int i = 0; i < 4; i ++){ + int newR = r + R[i]; + int newC = c + C[i]; + if(newR >= 0 && newR < grid.length && newC >= 0 && newC < grid[0].length){ + int childH = Math.max(V, grid[newR][newC]); + int curH = Math.max(V, grid[r][c]); + if(curH == childH){ + Pair child = new Pair(newR, newC); + if(!done.contains(child)){ + if(dfs(grid, newR, newC, done, V)) return true; + } + } + } + } + return false; + } +} From 78147c91940fd9932f572e18b6c22aa928804924 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Thu, 2 May 2019 00:30:09 +0200 Subject: [PATCH 209/235] Solved problems --- README.md | 13 ++ .../src/array/SurfaceAreaOfThreeDShapes.java | 82 +++++++++ .../MaximumVacationDays.java | 110 +++++++++++ .../UniqueBinarySearchTreesII.java | 106 +++++------ problems/src/greedy/IPO.java | 102 +++++++++++ problems/src/greedy/LemonadeChange.java | 90 +++++++++ .../src/greedy/ScoreAfterFlippingMatrix.java | 102 +++++++++++ problems/src/hashing/DistributeCandies.java | 42 +++++ .../GroupsOfSpecialEquivalentStrings.java | 85 +++++++++ problems/src/heap/FreqStack.java | 171 ++++++++++++++++++ problems/src/math/SquirrelSimulation.java | 57 ++++++ problems/src/string/KeyboardRow.java | 63 +++++++ .../tree/AllNodesDistanceKInBinaryTree.java | 126 +++++++++++++ .../src/tree/AllPossibleFullBinaryTrees.java | 80 ++++++++ 14 files changed, 1170 insertions(+), 59 deletions(-) create mode 100644 problems/src/array/SurfaceAreaOfThreeDShapes.java create mode 100644 problems/src/dynamic_programming/MaximumVacationDays.java create mode 100644 problems/src/greedy/IPO.java create mode 100644 problems/src/greedy/LemonadeChange.java create mode 100644 problems/src/greedy/ScoreAfterFlippingMatrix.java create mode 100644 problems/src/hashing/DistributeCandies.java create mode 100644 problems/src/hashing/GroupsOfSpecialEquivalentStrings.java create mode 100644 problems/src/heap/FreqStack.java create mode 100644 problems/src/math/SquirrelSimulation.java create mode 100644 problems/src/string/KeyboardRow.java create mode 100644 problems/src/tree/AllNodesDistanceKInBinaryTree.java create mode 100644 problems/src/tree/AllPossibleFullBinaryTrees.java diff --git a/README.md b/README.md index 668dc256..686a9637 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Champagne Tower](problems/src/array/ChampagneTower.java) (Medium) - [Valid Tic-Tac-Toe State](problems/src/array/ValidTicTacToeState.java) (Medium) - [Number of Subarrays with Bounded Maximum](problems/src/array/SubArraysWithBoundedMaximum.java) (Medium) +- [Surface Area of 3D Shapes](problems/src/array/SurfaceAreaOfThreeDShapes.java) (Easy) #### [Backtracking](problems/src/backtracking) @@ -67,6 +68,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Wildcard Matching](problems/src/backtracking/WildcardMatching.java) (Hard) - [Letter Case Permutation](problems/src/backtracking/LetterCasePermutation.java) (Easy) + #### [Binary Search](problems/src/binary_search) - [Minimum Sorted Rotated Array](problems/src/binary_search/MinSortedRotatedArray.java) (Medium) @@ -194,6 +196,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Stone Game](problems/src/dynamic_programming/StoneGame.java) (Medium) - [Odd Even Jump](problems/src/dynamic_programming/OddEvenJump.java) (Hard) - [Profitable Schemes](problems/src/dynamic_programming/ProfitableSchemes.java) (Hard) +- [Maximum Vacation Days](problems/src/dynamic_programming/MaximumVacationDays.java) (Hard) #### [Greedy](problems/src/greedy) @@ -207,6 +210,9 @@ My accepted leetcode solutions to some of the common interview problems. - [Queue Reconstruction By Height](problems/src/greedy/QueueReconstructionByHeight.java) (Medium) - [Task Scheduler](problems/src/greedy/TaskScheduler.java) (Medium) - [Maximum Length of Pair Chain](problems/src/greedy/MaximumLengthOfPairChain.java) (Medium) +- [Lemonade Change](problems/src/greedy/LemonadeChange.java) (Easy) +- [Score After Flipping Matrix](problems/src/greedy/ScoreAfterFlippingMatrix.java) (Medium) +- [IPO](problems/src/greedy/IPO.java) (Hard) #### [Hashing](problems/src/hashing) @@ -223,6 +229,8 @@ My accepted leetcode solutions to some of the common interview problems. - [Custom Sort String](problems/src/hashing/CustomSortString.java) (Medium) - [Short Encoding of Words](problems/src/hashing/ShortEncodingOfWords.java) (Medium) - [Substring with Concatenation of All Words](problems/src/hashing/SubstringConcatenationOfWords.java) (Hard) +- [Distribute Candies](problems/src/hashing/DistributeCandies.java) (Easy) +- [Groups of Special-Equivalent Strings](problems/src/hashing/GroupsOfSpecialEquivalentStrings.java) (Easy) #### [Heap](problems/src/heap) @@ -232,6 +240,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Top K Frequent Words](problems/src/heap/TopKFrequentWords.java) (Medium) - [Candy](problems/src/heap/Candy.java) (Hard) - [Smallest Rotation with Highest Score](problems/src/heap/SmallestRotationWithHighestScore.java) (Hard) +- [Maximum Frequency Stack](problems/src/heap/FreqStack.java) (Hard) #### [Linked List](problems/src/linked_list) @@ -261,6 +270,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Couples Holding Hands](problems/src/math/CouplesHoldingHands.java) (Hard) - [Reaching Points](problems/src/math/ReachingPoints.java) (Hard) - [Nth Magical Number](problems/src/math/NthMagicalNumber.java) (Hard) +- [Squirrel Simulation](problems/src/math/SquirrelSimulation.java) (Medium) #### [Reservoir Sampling](problems/src/reservoir_sampling) @@ -310,6 +320,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Longest Palindrome](problems/src/string/LongestPalindrome.java) (Easy) - [Replace Words](problems/src/string/ReplaceWords.java) (Medium) - [Rotate String](problems/src/string/RotateString.java) (Easy) +- [Keyboard Row](problems/src/string/KeyboardRow.java) (Easy) #### [Tree](problems/src/tree) @@ -355,6 +366,8 @@ My accepted leetcode solutions to some of the common interview problems. - [Binary Tree Postorder Traversal](problems/src/tree/BinaryTreePostorderTraversal.java) (Hard) - [Serialize and Deserialize N-ary Tree](problems/src/tree/SerializeAndDeserializeNAryTree.java) (Hard) - [Convert BST to Greater Tree](problems/src/tree/ConvertBSTToGreaterTree.java) (Easy) +- [All Nodes Distance K in Binary Tree](problems/src/tree/AllNodesDistanceKInBinaryTree.java) (Medium) +- [All Possible Full Binary Trees](problems/src/tree/AllPossibleFullBinaryTrees.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/array/SurfaceAreaOfThreeDShapes.java b/problems/src/array/SurfaceAreaOfThreeDShapes.java new file mode 100644 index 00000000..44a661d6 --- /dev/null +++ b/problems/src/array/SurfaceAreaOfThreeDShapes.java @@ -0,0 +1,82 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 30/04/2019 + * On a N * N grid, we place some 1 * 1 * 1 cubes. + * + * Each value v = grid[i][j] represents a tower of v cubes placed on top of grid cell (i, j). + * + * Return the total surface area of the resulting shapes. + * + * + * + * Example 1: + * + * Input: [[2]] + * Output: 10 + * Example 2: + * + * Input: [[1,2],[3,4]] + * Output: 34 + * Example 3: + * + * Input: [[1,0],[0,2]] + * Output: 16 + * Example 4: + * + * Input: [[1,1,1],[1,0,1],[1,1,1]] + * Output: 32 + * Example 5: + * + * Input: [[2,2,2],[2,1,2],[2,2,2]] + * Output: 46 + * + * + * Note: + * + * 1 <= N <= 50 + * 0 <= grid[i][j] <= 50 + * + * Solution: O(N x M) For each cell, check each adjacent cell and sum the value of (current cell - adjacent cell) + * if the current cell value is greater than adjacent cell. + * For every cell which has value grater then 0, the top surface area is by default 1 therefore add one to + * the sum of each cell. + */ +public class SurfaceAreaOfThreeDShapes { + + private final int[] R = {0, 0, -1, 1}; + private final int[] C = {1, -1, 0, 0}; + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[][] A = {{2}}; + System.out.println(new SurfaceAreaOfThreeDShapes().surfaceArea(A)); + } + + public int surfaceArea(int[][] grid) { + int sum = 0; + for(int i = 0; i < grid.length; i ++){ + for(int j = 0; j < grid[i].length; j ++){ + int cell = grid[i][j]; + for(int k = 0; k < 4; k ++){ + int newR = i + R[k]; + int newC = j + C[k]; + if(newR >= 0 && newC >= 0 && newR < grid.length && newC < grid[0].length){ + int adjacent = grid[newR][newC]; + if(cell > adjacent){ + sum += (cell - adjacent); + } + } else if(newR < 0 || newR >= grid.length || newC < 0 || newC >= grid[0].length){ + sum += cell; + } + } + if(cell > 0){ + sum += 2; + } + } + } + return sum; + } +} diff --git a/problems/src/dynamic_programming/MaximumVacationDays.java b/problems/src/dynamic_programming/MaximumVacationDays.java new file mode 100644 index 00000000..f5868c3a --- /dev/null +++ b/problems/src/dynamic_programming/MaximumVacationDays.java @@ -0,0 +1,110 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 13/04/2019 + * + * LeetCode wants to give one of its best employees the option to travel among N cities to collect algorithm + * problems. But all work and no play makes Jack a dull boy, you could take vacations in some particular cities and + * weeks. Your job is to schedule the traveling to maximize the number of vacation days you could take, but there are + * certain rules and restrictions you need to follow. + * + * Rules and restrictions: + * You can only travel among N cities, represented by indexes from 0 to N-1. Initially, you are in the city indexed 0 + * on Monday. + * The cities are connected by flights. The flights are represented as a N*N matrix (not necessary symmetrical), + * called flights representing the airline status from the city i to the city j. If there is no flight from the city + * i to the city j, flights[i][j] = 0; Otherwise, flights[i][j] = 1. Also, flights[i][i] = 0 for all i. + * You totally have K weeks (each week has 7 days) to travel. You can only take flights at most once per day and can + * only take flights on each week's Monday morning. Since flight time is so short, we don't consider the impact of + * flight time. + * For each city, you can only have restricted vacation days in different weeks, given an N*K matrix called days + * representing this relationship. For the value of days[i][j], it represents the maximum days you could take + * vacation in the city i in the week j. + * You're given the flights matrix and days matrix, and you need to output the maximum vacation days you could take + * during K weeks. + * + * Example 1: + * Input:flights = [[0,1,1],[1,0,1],[1,1,0]], days = [[1,3,1],[6,0,3],[3,3,3]] + * Output: 12 + * Explanation: + * Ans = 6 + 3 + 3 = 12. + * + * One of the best strategies is: + * 1st week : fly from city 0 to city 1 on Monday, and play 6 days and work 1 day. + * (Although you start at city 0, we could also fly to and start at other cities since it is Monday.) + * 2nd week : fly from city 1 to city 2 on Monday, and play 3 days and work 4 days. + * 3rd week : stay at city 2, and play 3 days and work 4 days. + * Example 2: + * Input:flights = [[0,0,0],[0,0,0],[0,0,0]], days = [[1,1,1],[7,7,7],[7,7,7]] + * Output: 3 + * Explanation: + * Ans = 1 + 1 + 1 = 3. + * + * Since there is no flights enable you to move to another city, you have to stay at city 0 for the whole 3 weeks. + * For each week, you only have one day to play and six days to work. + * So the maximum number of vacation days is 3. + * Example 3: + * Input:flights = [[0,1,1],[1,0,1],[1,1,0]], days = [[7,0,0],[0,7,0],[0,0,7]] + * Output: 21 + * Explanation: + * Ans = 7 + 7 + 7 = 21 + * + * One of the best strategies is: + * 1st week : stay at city 0, and play 7 days. + * 2nd week : fly from city 0 to city 1 on Monday, and play 7 days. + * 3rd week : fly from city 1 to city 2 on Monday, and play 7 days. + * Note: + * N and K are positive integers, which are in the range of [1, 100]. + * In the matrix flights, all the values are integers in the range of [0, 1]. + * In the matrix days, all the values are integers in the range [0, 7]. + * You could stay at a city beyond the number of vacation days, but you should work on the extra days, which won't be + * counted as vacation days. + * If you fly from the city A to the city B and take the vacation on that day, the deduction towards vacation days + * will count towards the vacation days of city B in that week. + * We don't consider the impact of flight hours towards the calculation of vacation days. + * + * Solution: + * O(N x N x K) + * Start from the last week K; Calculate for the last week maximum vacation days for all possible cities. + * Now, iteratively calculate backwards + * for each week K - 1 + * and for each city + * and for each available connection from the city + * memoize the maximum vacation days possible for this city + * Return the answer for city 0 and week 0 + */ +public class MaximumVacationDays { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[][] flights = {{0,1,0,1,1},{1,0,0,1,1},{1,0,0,1,0},{0,1,0,0,0},{0,0,0,1,0}}; + int[][] days = {{0,4,1,6,6},{4,3,3,0,1},{3,6,6,5,0},{1,3,1,1,4},{5,3,3,3,4}}; + System.out.println(new MaximumVacationDays().maxVacationDays(flights, days)); + } + + public int maxVacationDays(int[][] flights, int[][] days) { + int N = days.length; + int W = days[0].length; + int[][] DP = new int[N][W + 1]; + for(int w = W - 1; w >= 0; w --){ + for(int n = 0; n < N; n ++){ + DP[n][w] = days[n][w] + DP[n][w + 1]; + } + + for(int n = 0; n < N; n ++){ + int max = Integer.MIN_VALUE; + int[] F = flights[n]; + for(int i = 0; i < F.length; i ++){ + if(F[i] == 1){ + max = Math.max(max, days[i][w] + DP[i][w + 1]); + } + } + DP[n][w] = Math.max(DP[n][w], max); + } + } + return DP[0][0]; + } +} diff --git a/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java b/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java index 5fd0bc56..c8299675 100644 --- a/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java +++ b/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java @@ -1,7 +1,6 @@ package dynamic_programming; -import java.util.ArrayList; -import java.util.List; +import java.util.*; /** * Created by gouthamvidyapradhan on 31/03/2017. @@ -27,8 +26,6 @@ public static class TreeNode { } } - private List[][] dp; - /** * Main method * @@ -39,67 +36,58 @@ public static void main(String[] args) throws Exception { List list = new UniqueBinarySearchTreesII().generateTrees(3); } - public List generateTrees(int n) { - if (n == 0) return new ArrayList<>(); - dp = new List[n + 1][n + 1]; - dp[0][0] = new ArrayList<>(); - for (int i = 1, j = 1; i <= n; i++, j++) { - dp[i][j] = new ArrayList<>(); - dp[i][j].add(new TreeNode(i)); + class Pair{ + int l, r; + Pair(int l, int r){ + this.l = l; + this.r = r; } - return dp(1, n, n); + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Pair)) return false; + Pair pair = (Pair) o; + return l == pair.l && + r == pair.r; + } + + @Override + public int hashCode() { + return Objects.hash(l, r); + } + } + + Map> dp; + + public List generateTrees(int n) { + dp = new HashMap<>(); + if(n == 0) return new ArrayList<>(); + return generate(new Pair(1, n)); } - private List dp(int s, int e, int n) { - if (e < s) return null; - if (dp[s][e] != null) return dp[s][e]; - List result = new ArrayList<>(); - for (int i = s; i <= e; i++) { - List left = dp(s, i - 1, n); - List right = dp(i + 1, e, n); - List temp = new ArrayList<>(); - if (left != null) { - for (TreeNode node : left) { + private List generate(Pair p){ + if(dp.containsKey(p)){ + return dp.get(p); + } + else if(p.l > p.r) return Arrays.asList(new TreeNode(-1)); + else if(p.l == p.r) return Arrays.asList(new TreeNode(p.l)); + List list = new ArrayList<>(); + for(int i = p.l; i <= p.r; i ++){ + Pair left = new Pair(p.l, i - 1); + Pair right = new Pair(i + 1, p.r); + List leftList = generate(left); + List rightList = generate(right); + for(TreeNode lNode : leftList){ + for(TreeNode rNode : rightList){ TreeNode root = new TreeNode(i); - root.left = node; - temp.add(root); + root.left = lNode.val == -1 ? null : lNode; + root.right = rNode.val == -1 ? null : rNode; + list.add(root); } } - if (right != null) { - if (!temp.isEmpty()) { - for (TreeNode root : temp) { - for (TreeNode node : right) { - TreeNode newRoot = clone(root); - newRoot.right = node; - result.add(newRoot); - } - } - } else { - for (TreeNode node : right) { - TreeNode root = new TreeNode(i); - root.right = node; - result.add(root); - } - } - } else if (!temp.isEmpty()) { - result.addAll(temp); - } } - dp[s][e] = result; - return result; - } - - /** - * Clone treeNode - * - * @param root rootnode - * @return cloned root - */ - private TreeNode clone(TreeNode root) { - if (root == null) return null; - TreeNode newNode = new TreeNode(root.val); - newNode.left = clone(root.left); - newNode.right = clone(root.right); - return newNode; + dp.put(p, list); + return list; } } diff --git a/problems/src/greedy/IPO.java b/problems/src/greedy/IPO.java new file mode 100644 index 00000000..7e42b170 --- /dev/null +++ b/problems/src/greedy/IPO.java @@ -0,0 +1,102 @@ +package greedy; /** + * Created by gouthamvidyapradhan on 09/04/2019 + * Suppose LeetCode will start its IPO soon. In order to sell a good price of its shares to Venture Capital, + * LeetCode would like to work on some projects to increase its capital before the IPO. Since it has limited + * resources, it can only finish at most k distinct projects before the IPO. Help LeetCode design the best way to + * maximize its total capital after finishing at most k distinct projects. + * + * You are given several projects. For each project i, it has a pure profit Pi and a minimum capital of Ci is needed + * to start the corresponding project. Initially, you have W capital. When you finish a project, you will obtain its + * pure profit and the profit will be added to your total capital. + * + * To sum up, pick a list of at most k distinct projects from given projects to maximize your final capital, and + * output your final maximized capital. + * + * Example 1: + * Input: k=2, W=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. + * Note: + * You may assume all numbers in the input are non-negative integers. + * The length of Profits array and Capital array will not exceed 50,000. + * The answer is guaranteed to fit in a 32-bit signed integer. + * + * Solution: + * O(N log N) where N is the size of Capital/Profit array. + * General intuition is to pick a project which gives maximum profit for the available capital. Sum the + * profit with the original capital and this becomes the new available capital now, again pick the + * project which gives maximum profit. Continue this until K projects are picked. Maintain a priority queue + * to pick the project which gives maximum profit. + */ +import java.util.*; +public class IPO { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[] P = {1, 2, 3}; + int[] C = {1, 1, 2}; + System.out.println(new IPO().findMaximizedCapital(1, 0, P, C)); + } + class Pair { + int p, c; + Pair(int p, int c){ + this.p = p; + this.c = c; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Pair)) return false; + Pair pair = (Pair) o; + return p == pair.p && + c == pair.c; + } + + public int getP() { + return p; + } + + public int getC() { + return c; + } + + @Override + public int hashCode() { + return Objects.hash(p, c); + } + } + public int findMaximizedCapital(int k, int W, int[] Profits, int[] Capital) { + PriorityQueue profits = + new PriorityQueue<>(Comparator.comparing(Pair::getP).reversed().thenComparing(Pair::getC)); + PriorityQueue capitals = new PriorityQueue<>(Comparator.comparing(Pair::getC)); + for(int i = 0; i < Profits.length; i ++){ + capitals.offer(new Pair(Profits[i], Capital[i])); + } + while(true){ + while(!capitals.isEmpty() && capitals.peek().getC() <= W){ + profits.offer(capitals.poll()); + } + if(!profits.isEmpty() && profits.peek().getC() <= W && k > 0){ + W += profits.poll().getP(); + k --; + } + if(capitals.isEmpty() || capitals.peek().getC() > W || k == 0) break; + } + while(k > 0 && !profits.isEmpty()){ + W += profits.poll().getP(); + k--; + } + return W; + } +} diff --git a/problems/src/greedy/LemonadeChange.java b/problems/src/greedy/LemonadeChange.java new file mode 100644 index 00000000..3798c8f3 --- /dev/null +++ b/problems/src/greedy/LemonadeChange.java @@ -0,0 +1,90 @@ +package greedy; + +/** + * Created by gouthamvidyapradhan on 26/04/2019 + * + * At a lemonade stand, each lemonade costs $5. + * + * Customers are standing in a queue to buy from you, and order one at a time (in the order specified by bills). + * + * Each customer will only buy one lemonade and pay with either a $5, $10, or $20 bill. You must provide the correct change to each customer, so that the net transaction is that the customer pays $5. + * + * Note that you don't have any change in hand at first. + * + * Return true if and only if you can provide every customer with correct change. + * + * + * + * Example 1: + * + * Input: [5,5,5,10,20] + * Output: true + * Explanation: + * From the first 3 customers, we collect three $5 bills in order. + * From the fourth customer, we collect a $10 bill and give back a $5. + * From the fifth customer, we give a $10 bill and a $5 bill. + * Since all customers got correct change, we output true. + * Example 2: + * + * Input: [5,5,10] + * Output: true + * Example 3: + * + * Input: [10,10] + * Output: false + * Example 4: + * + * Input: [5,5,10,10,20] + * Output: false + * Explanation: + * From the first two customers in order, we collect two $5 bills. + * For the next two customers in order, we collect a $10 bill and give back a $5 bill. + * For the last customer, we can't give change of $15 back because we only have two $10 bills. + * Since not every customer received correct change, the answer is false. + * + * + * Note: + * + * 0 <= bills.length <= 10000 + * bills[i] will be either 5, 10, or 20. + * + * Solution: Store the count of number of five's and tens's. In case of change 15 return a 10 + 5 (if + * 10 is not available then, return 5 + 5 + 5 if three fives are available) + * Since we are choosing a 10 + 5 instead of 5 + 5 + 5, this problem holds a greedy property + */ +public class LemonadeChange { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + + } + + public boolean lemonadeChange(int[] bills) { + int five = 0, ten = 0; + for(int b : bills){ + if(b == 5){ + five++; + } else if(b == 10){ + ten++; + if(five > 0){ + five--; + }else{ + return false; + } + } else{ + if(ten > 0 && five > 0){ + ten --; + five--; + } else if(five > 2){ + five -= 3; + } else { + return false; + } + } + } + return true; + } +} diff --git a/problems/src/greedy/ScoreAfterFlippingMatrix.java b/problems/src/greedy/ScoreAfterFlippingMatrix.java new file mode 100644 index 00000000..e9cc20ff --- /dev/null +++ b/problems/src/greedy/ScoreAfterFlippingMatrix.java @@ -0,0 +1,102 @@ +package greedy; + +/** + * Created by gouthamvidyapradhan on 26/04/2019 + * We have a two dimensional matrix A where each value is 0 or 1. + * + * A move consists of choosing any row or column, and toggling each value in that row or column: changing all 0s to + * 1s, and all 1s to 0s. + * + * After making any number of moves, every row of this matrix is interpreted as a binary number, and the score of + * the matrix is the sum of these numbers. + * + * Return the highest possible score. + * + * + * + * Example 1: + * + * Input: [[0,0,1,1],[1,0,1,0],[1,1,0,0]] + * Output: 39 + * Explanation: + * Toggled to [[1,1,1,1],[1,0,0,1],[1,1,1,1]]. + * 0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39 + * + * + * Note: + * + * 1 <= A.length <= 20 + * 1 <= A[0].length <= 20 + * A[i][j] is 0 or 1. + * + * Solution: O(N x N) + * Select each row and greedily flip the row if it maximizes the value. + * Select each column and flip the column if the count of 1's in the column is smaller than count + * of 0's + * Sum up the final value from each column return the answer. + */ +public class ScoreAfterFlippingMatrix { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[][] A = {{1, 0}, {1, 0}, {1, 0}, {1, 1}}; + System.out.println(new ScoreAfterFlippingMatrix().matrixScore(A)); + } + + public int matrixScore(int[][] A) { + for(int[] a : A){ + int temp1 = makeNum(a); + flip(a); + int temp2 = makeNum(a); + if(temp1 > temp2){ + //revert + flip(a); + } + } + for(int i = 0; i < A[0].length; i ++){ + int count = 0; + for(int j = 0; j < A.length; j ++){ + if(A[j][i] == 1){ + count++; + } + } + if(count < (A.length - count)){ + for(int j = 0; j < A.length; j ++){ + if(A[j][i] == 0){ + A[j][i] = 1; + } else{ + A[j][i] = 0; + } + } + } + } + int sum = 0; + for(int[] a : A){ + sum += makeNum(a); + } + return sum; + } + + private int makeNum(int[] a){ + int n = 0; + for(int i = 0; i < a.length; i ++){ + if(a[i] == 1){ + n |= (1 << (a.length - i - 1)); + } + } + return n; + } + + private void flip(int[] A){ + for(int i = 0; i < A.length; i ++){ + if(A[i] == 1){ + A[i] = 0; + } else{ + A[i] = 1; + } + } + } +} diff --git a/problems/src/hashing/DistributeCandies.java b/problems/src/hashing/DistributeCandies.java new file mode 100644 index 00000000..a3a8038a --- /dev/null +++ b/problems/src/hashing/DistributeCandies.java @@ -0,0 +1,42 @@ +package hashing; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 25/04/2019 + * Given an integer array with even length, where different numbers in this array represent different kinds of + * candies. Each number means one candy of the corresponding kind. You need to distribute these candies equally in number to brother and sister. Return the maximum number of kinds of candies the sister could gain. + * Example 1: + * Input: candies = [1,1,2,2,3,3] + * Output: 3 + * Explanation: + * There are three different kinds of candies (1, 2 and 3), and two candies for each kind. + * Optimal distribution: The sister has candies [1,2,3] and the brother has candies [1,2,3], too. + * The sister has three different kinds of candies. + * Example 2: + * Input: candies = [1,1,2,3] + * Output: 2 + * Explanation: For example, the sister has candies [2,3] and the brother has candies [1,1]. + * The sister has two different kinds of candies, the brother has only one kind of candies. + * Note: + * + * The length of the given array is in range [2, 10,000], and will be even. + * The number in given array is in range [-100,000, 100,000]. + * + * Solution: O(N) Use a HashSet to identify all the different possible candies. The maximum types of + * candies sister can get is always Min(N/2, Number Of Unique Type of Candies) + */ +public class DistributeCandies { + public static void main(String[] args) { + + } + + public int distributeCandies(int[] candies) { + int N = candies.length; + Set set = new HashSet<>(); + for(int c : candies){ + set.add(c); + } + int n = set.size(); + return Math.min(N / 2, set.size()); + } +} diff --git a/problems/src/hashing/GroupsOfSpecialEquivalentStrings.java b/problems/src/hashing/GroupsOfSpecialEquivalentStrings.java new file mode 100644 index 00000000..2d80b1a9 --- /dev/null +++ b/problems/src/hashing/GroupsOfSpecialEquivalentStrings.java @@ -0,0 +1,85 @@ +package hashing; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 30/04/2019 + * You are given an array A of strings. + * + * Two strings S and T are special-equivalent if after any number of moves, S == T. + * + * A move consists of choosing two indices i and j with i % 2 == j % 2, and swapping S[i] with S[j]. + * + * Now, a group of special-equivalent strings from A is a non-empty subset S of A such that any string not in S is + * not special-equivalent with any string in S. + * + * Return the number of groups of special-equivalent strings from A. + * + * + * + * Example 1: + * + * Input: ["a","b","c","a","c","c"] + * Output: 3 + * Explanation: 3 groups ["a","a"], ["b"], ["c","c","c"] + * Example 2: + * + * Input: ["aa","bb","ab","ba"] + * Output: 4 + * Explanation: 4 groups ["aa"], ["bb"], ["ab"], ["ba"] + * Example 3: + * + * Input: ["abc","acb","bac","bca","cab","cba"] + * Output: 3 + * Explanation: 3 groups ["abc","cba"], ["acb","bca"], ["bac","cab"] + * Example 4: + * + * Input: ["abcd","cdab","adcb","cbad"] + * Output: 1 + * Explanation: 1 group ["abcd","cdab","adcb","cbad"] + * + * + * Note: + * + * 1 <= A.length <= 1000 + * 1 <= A[i].length <= 20 + * All A[i] have the same length. + * All A[i] consist of only lowercase letters. + * + * Solution: + * The character array of odd positions and even positions of two special-equivalent strings + * should be exactly equal after sorting. Use a hashset to count number of such groups. + */ +public class GroupsOfSpecialEquivalentStrings { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + + } + + public int numSpecialEquivGroups(String[] A) { + Set set = new HashSet<>(); + for(String s : A){ + StringBuilder temp1 = new StringBuilder(); + for(int i = 0, l = s.length(); i < l; i += 2){ + char c = s.charAt(i); + temp1.append(c); + } + StringBuilder temp2 = new StringBuilder(); + if(s.length() > 1){ + for(int i = 1, l = s.length(); i < l; i += 2){ + char c = s.charAt(i); + temp2.append(c); + } + } + char[] temp1Chars = temp1.toString().toCharArray(); + char[] temp2Chars = temp2.toString().toCharArray(); + Arrays.sort(temp1Chars); + Arrays.sort(temp2Chars); + set.add(String.valueOf(temp1Chars) + "+" + String.valueOf(temp2Chars)); + } + return set.size(); + } +} diff --git a/problems/src/heap/FreqStack.java b/problems/src/heap/FreqStack.java new file mode 100644 index 00000000..39e7e76e --- /dev/null +++ b/problems/src/heap/FreqStack.java @@ -0,0 +1,171 @@ +package heap; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 30/04/2019 + * Implement FreqStack, a class which simulates the operation of a stack-like data structure. + * + * 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. + * + * + * Example 1: + * + * Input: + * ["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]. + * + * + * Note: + * + * Calls to FreqStack.push(int x) will be such that 0 <= x <= 10^9. + * It is guaranteed that FreqStack.pop() won't be called if the stack has zero elements. + * The total number of FreqStack.push calls will not exceed 10000 in a single test case. + * The total number of FreqStack.pop calls will not exceed 10000 in a single test case. + * The total number of FreqStack.push and FreqStack.pop calls will not exceed 150000 across all test cases. + * + * Solution: + * push O(log N) + * pop O(log N) + * Maintain a priority queue with a FreqNode where each FreqNode contains a frequency and a stack + * with (value and pushCount). Each stack in a priority queue contains same set of values. Every time when a value + * is to be added to the stack a new Node is created and pushed to stack which contains the push value and pushCount. + * + * Example: For the below push operation + * push 5, push 5, push 5, push 6, push 6, push 7 + * the state of priority stack will be + * 3 : 5(0) -> 5(1) -> 5(2) + * 2 : 6(3) -> 6(4) + * 1 : 7(5) + * + * When a push operation is invoked we have to identify in which stack the value has to go in + * therefore maintain a hashmap with push-value as key and value contains the reference to FreqNode + * in priority queue. Remove this FreqNode from priority queue and update the stack. + * + * When a pop operation is invoked remove the FreqNode from the top of the priority queue and pop the + * value from top of its stack. + */ +public class FreqStack { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + FreqStack freqStack = new FreqStack(); + freqStack.push(5); + freqStack.push(5); + freqStack.push(5); + freqStack.push(5); + freqStack.push(6); + System.out.println(freqStack.pop()); + freqStack.push(7); + System.out.println(freqStack.pop()); + System.out.println(freqStack.pop()); + freqStack.push(1); + freqStack.push(2); + System.out.println(freqStack.pop()); + System.out.println(freqStack.pop()); + System.out.println(freqStack.pop()); + System.out.println(freqStack.pop()); + System.out.println(freqStack.pop()); + } + + class Node{ + int val, pos; + Node(int val, int pushCount){ + this.val = val; + this.pos = pushCount; + } + } + + class FreqNode{ + int freq; + Stack stack; + FreqNode(int freq, Stack stack){ + this.freq = freq; + this.stack = stack; + } + + public int getFreq() { + return freq; + } + + public int getTop() { + return !stack.isEmpty() ? stack.peek().pos : -1; + } + + public void push(Node e){ + freq++; + stack.push(e); + } + + public Node pop(){ + freq--; + return stack.pop(); + } + } + + private PriorityQueue priorityQueue; + private Map map; + private int pushCount; + + public FreqStack() { + priorityQueue = + new PriorityQueue<>((o1, o2) -> { + if(o1.freq == o2.freq){ + return Integer.compare(o2.getTop(), o1.getTop()); + } else{ + return Integer.compare(o2.freq, o1.freq); + } + }); + map = new HashMap<>(); + pushCount = 0; + } + + public void push(int x) { + pushCount++; + Node node = new Node(x, pushCount); + FreqNode freqNode; + if(map.containsKey(x)){ + freqNode = map.get(x); + priorityQueue.remove(freqNode); + freqNode.push(node); + } else{ + Stack stack = new Stack<>(); + stack.push(node); + freqNode = new FreqNode(1, stack); + map.put(x, freqNode); + } + priorityQueue.offer(freqNode); + } + + public int pop() { + FreqNode freqNode = priorityQueue.poll(); + Node topNode = freqNode.pop(); + if(freqNode.freq == 0){ + map.remove(topNode.val); + } else{ + priorityQueue.offer(freqNode); + } + return topNode.val; + } +} diff --git a/problems/src/math/SquirrelSimulation.java b/problems/src/math/SquirrelSimulation.java new file mode 100644 index 00000000..54e77abf --- /dev/null +++ b/problems/src/math/SquirrelSimulation.java @@ -0,0 +1,57 @@ +package math; + +/** + * Created by gouthamvidyapradhan on 25/04/2019 + * There's a tree, a squirrel, and several nuts. Positions are represented by the cells in a 2D grid. Your goal is + * to find the minimal distance for the squirrel to collect all the nuts and put them under the tree one by one. The + * squirrel can only take at most one nut at one time and can move in four directions - up, down, left and right, to + * the adjacent cell. The distance is represented by the number of moves. + * Example 1: + * + * Input: + * Height : 5 + * Width : 7 + * Tree position : [2,2] + * Squirrel : [4,4] + * Nuts : [[3,0], [2,5]] + * Output: 12 + * Explanation: + * ​​​​​ + * Note: + * + * All given positions won't overlap. + * The squirrel can take at most one nut at one time. + * The given positions of nuts have no order. + * Height and width are positive integers. 3 <= height * width <= 10,000. + * The given positions contain at least one nut, only one tree and one squirrel. + * + * Solution O(N) + * Calculate the Manhattan Distance from each of the nut to the tree and double this value - Let this + * value be D. We are doubling here to simulate going from tree to a nut and back. + * Now, to get the minimum distance - for each distance d from squirrel position to nut position do, + * Min(D + d - (distance from this nut to tree)) + */ +public class SquirrelSimulation { + public static void main(String[] args) { + int height = 5; + int width = 7; + int[] tree = {2, 2}; + int[] squirrel = {4, 4}; + int[][] nuts = {{3, 0}, {2, 5}}; + System.out.println(new SquirrelSimulation().minDistance(height, width, tree, squirrel, nuts)); + } + + public int minDistance(int height, int width, int[] tree, int[] squirrel, int[][] nuts) { + int dist = 0; + for(int[] n : nuts){ + dist += Math.abs(n[0] - tree[0]) + Math.abs(n[1] - tree[1]); + } + dist *= 2; + int ans = Integer.MAX_VALUE; + for(int[] n : nuts){ + int nutDist = Math.abs(n[0] - squirrel[0]) + Math.abs(n[1] - squirrel[1]); + ans = Math.min(ans, dist - (Math.abs(n[0] - tree[0]) + Math.abs(n[1] - tree[1])) + nutDist); + } + return ans; + } +} diff --git a/problems/src/string/KeyboardRow.java b/problems/src/string/KeyboardRow.java new file mode 100644 index 00000000..9fd5729e --- /dev/null +++ b/problems/src/string/KeyboardRow.java @@ -0,0 +1,63 @@ +package string; /** + * Created by gouthamvidyapradhan on 09/04/2019 + * + * Given a List of words, return the words that can be typed using letters of alphabet on only one row's of American + * keyboard like the image below. + * + * + * + * + * + * + * Example: + * + * Input: ["Hello", "Alaska", "Dad", "Peace"] + * Output: ["Alaska", "Dad"] + * + * Note: + * + * You may use one character in the keyboard more than once. + * You may assume the input string will only contain letters of alphabet. + */ +import java.util.*; +public class KeyboardRow { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + + } + + public String[] findWords(String[] words) { + String R1 = "qwertyuiop"; + String R2 = "asdfghjkl"; + String R3 = "zxcvbnm"; + List answer = new ArrayList<>(); + for(String s : words){ + Set set = new HashSet<>(); + for(char c : s.toCharArray()){ + if(R1.indexOf(c) != -1){ + set.add('1'); + } + else if(R2.indexOf(c) != -1){ + set.add('2'); + } + else if(R3.indexOf(c) != -1){ + set.add('3'); + } + } + if(set.size() == 1){ + answer.add(s); + } + } + String[] ans = new String[answer.size()]; + int i = 0; + for(String s : answer){ + ans[i++] = s; + } + return ans; + } + +} diff --git a/problems/src/tree/AllNodesDistanceKInBinaryTree.java b/problems/src/tree/AllNodesDistanceKInBinaryTree.java new file mode 100644 index 00000000..f74e40ba --- /dev/null +++ b/problems/src/tree/AllNodesDistanceKInBinaryTree.java @@ -0,0 +1,126 @@ +package tree; +import java.util.*; +/** + * Created by gouthamvidyapradhan on 26/04/2019 + * We are given a binary tree (with root node root), a target node, and an integer value K. + * + * Return a list of the values of all nodes that have a distance K from the target node. The answer can be returned + * in any order. + * + * + * + * Example 1: + * + * Input: root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, K = 2 + * + * Output: [7,4,1] + * + * 3 + * / \ + * 5 1 + * / \ / \ + * 6 2 0 8 + * / \ + * 7 4 + * Explanation: + * The nodes that are a distance 2 from the target node (with value 5) + * have values 7, 4, and 1. + * + * + * + * Note that the inputs "root" and "target" are actually TreeNodes. + * The descriptions of the inputs above are just serializations of these objects. + * + * + * Note: + * + * The given tree is non-empty. + * Each node in the tree has unique values 0 <= node.val <= 500. + * The target node is a node in the tree. + * 0 <= K <= 1000. + * + * Solution: O(N) + * The general intuition is as below. + * All the nodes from which a target nodes can be reached (including the target node) can have child nodes at a + * distance of K from target node. All the nodes from which a target node cannot be reached definitely cannot have a + * child node at a distance of K from target node. + * Do a dfs from root to find the target node. As soon as a target node is found, all the nodes in the + * recursion stack are the ancestors of target node i.e the target node can be reached from each of these + * nodes. Now do another dfs from each of the nodes starting from target node and all its ancestors up to + * the root to find nodes at a distance of (K - dk) where dk is the distance to the target node. + * Keep track of visited nodes in order not to revisit the same node once again. + */ +public class AllNodesDistanceKInBinaryTree { + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + + } + + class Node{ + int v, d; + Node(int v, int d){ + this.d = d; + this.v = v; + } + } + + private Set done; + + public List distanceK(TreeNode root, TreeNode target, int K) { + done = new HashSet<>(); + List result = new ArrayList<>(); + findAndProcess(root, result, K, target); + return result; + } + + private int findAndProcess(TreeNode node, List result, int K, TreeNode target){ + if(node != null){ + if(target == node){ + fillResult(node, result, 0, K); + return 1; + } else{ + int status = findAndProcess(node.left, result, K, target); + if(status > 0){ + if(K - status >= 0){ + fillResult(node, result, 0, K - status); + } + return status + 1; + } else { + status = findAndProcess(node.right, result, K, target); + if(status > 0){ + if(K - status >= 0){ + fillResult(node, result, 0, K - status); + } + return status + 1; + } + } + return -1; + } + } else return -1; + } + + private void fillResult(TreeNode node, List result, int d, int K){ + done.add(node.val); + if(d == K){ + result.add(node.val); + return; + } + if(node.left != null && !done.contains(node.left.val)){ + fillResult(node.left, result, d + 1, K); + } + if(node.right != null && !done.contains(node.right.val)){ + fillResult(node.right, result, d + 1, K); + } + } +} diff --git a/problems/src/tree/AllPossibleFullBinaryTrees.java b/problems/src/tree/AllPossibleFullBinaryTrees.java new file mode 100644 index 00000000..c9ab3816 --- /dev/null +++ b/problems/src/tree/AllPossibleFullBinaryTrees.java @@ -0,0 +1,80 @@ +package tree; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 30/04/2019 + * A full binary tree is a binary tree where each node has exactly 0 or 2 children. + * + * Return a list of all possible full binary trees with N nodes. Each element of the answer is the root node of one + * possible tree. + * + * Each node of each tree in the answer must have node.val = 0. + * + * You may return the final list of trees in any order. + * + * + * + * Example 1: + * + * Input: 7 + * Output: [[0,0,0,null,null,0,0,null,null,0,0],[0,0,0,null,null,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,null,null,null, + * null,0,0],[0,0,0,0,0,null,null,0,0]] + * + * Note: + * + * 1 <= N <= 20 + * + * Solution: + * O(2 ^ N) + * A full binary tree can only be generated for a case with odd number of nodes. + * Start with a base case - when only one node is given a full binary tree can be formed with only one + * node. Cache this value in a hashmap. + * + * Now, iteratively generate a list of possible trees for 3, 5, 7 . . . N - ((N + 1) % 2) and cache + * this in a hashmap. + */ +public class AllPossibleFullBinaryTrees { + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + List result = new AllPossibleFullBinaryTrees().allPossibleFBT(7); + System.out.println(result.size()); + } + + public List allPossibleFBT(int N) { + if(N % 2 == 0) return new ArrayList<>(); + Map> map = new HashMap<>(); + map.put(1, Arrays.asList(new TreeNode(0))); + for(int i = 3; i <= N; i += 2){ + List list = new ArrayList<>(); + for(int j = 1; j < i - 1; j += 2){ + int l = j, r = i - 1 - j; + List leftList = map.get(l); + List rightList = map.get(r); + for(TreeNode leftNode : leftList){ + for(TreeNode rightNode : rightList){ + TreeNode root = new TreeNode(0); + root.left = leftNode; + root.right = rightNode; + list.add(root); + } + } + } + map.put(i, list); + } + return map.get(N); + } +} From 06ce9fb060cb9f920603271be156c32525b4f654 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 3 May 2019 12:31:13 +0200 Subject: [PATCH 210/235] Adding gradle support --- .gitignore | 0 .idea/google-java-format.xml | 6 ++++++ .idea/gradle.xml | 12 +++++++++++ ..._com_google_code_findbugs_jsr305_3_0_2.xml | 11 ++++++++++ ...rorprone_error_prone_annotations_2_2_0.xml | 11 ++++++++++ ..._errorprone_javac_shaded_9_181_r4173_1.xml | 11 ++++++++++ ...ooglejavaformat_google_java_format_1_7.xml | 9 +++++++++ ...__com_google_guava_failureaccess_1_0_1.xml | 11 ++++++++++ ...dle__com_google_guava_guava_27_0_1_jre.xml | 11 ++++++++++ ...9_0_empty_to_avoid_conflict_with_guava.xml | 9 +++++++++ ...m_google_j2objc_j2objc_annotations_1_1.xml | 11 ++++++++++ ...rg_checkerframework_checker_qual_2_5_2.xml | 11 ++++++++++ ...s_mojo_animal_sniffer_annotations_1_17.xml | 11 ++++++++++ .idea/modules/leetcode_main.iml | 11 ++++++++++ .idea/modules/leetcode_test.iml | 12 +++++++++++ build.gradle | 0 problems/src/Test1.java | 5 +++++ problems/src/Test2.java | 5 +++++ problems/src/Test3.java | 5 +++++ .../src/string/IntegerToEnglishWords.java | 10 ++++++++++ problems/src/test/MyList.java | 20 +++++++++++++++++++ problems/src/tomtom/Solution1.java | 11 ++++++++++ problems/src/zalando/TaskA.java | 7 +++++++ problems/src/zalando/TaskB.java | 7 +++++++ 24 files changed, 217 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/google-java-format.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/libraries/Gradle__com_google_code_findbugs_jsr305_3_0_2.xml create mode 100644 .idea/libraries/Gradle__com_google_errorprone_error_prone_annotations_2_2_0.xml create mode 100644 .idea/libraries/Gradle__com_google_errorprone_javac_shaded_9_181_r4173_1.xml create mode 100644 .idea/libraries/Gradle__com_google_googlejavaformat_google_java_format_1_7.xml create mode 100644 .idea/libraries/Gradle__com_google_guava_failureaccess_1_0_1.xml create mode 100644 .idea/libraries/Gradle__com_google_guava_guava_27_0_1_jre.xml create mode 100644 .idea/libraries/Gradle__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml create mode 100644 .idea/libraries/Gradle__com_google_j2objc_j2objc_annotations_1_1.xml create mode 100644 .idea/libraries/Gradle__org_checkerframework_checker_qual_2_5_2.xml create mode 100644 .idea/libraries/Gradle__org_codehaus_mojo_animal_sniffer_annotations_1_17.xml create mode 100644 .idea/modules/leetcode_main.iml create mode 100644 .idea/modules/leetcode_test.iml create mode 100644 build.gradle create mode 100644 problems/src/Test1.java create mode 100644 problems/src/Test2.java create mode 100644 problems/src/Test3.java create mode 100644 problems/src/string/IntegerToEnglishWords.java create mode 100644 problems/src/test/MyList.java create mode 100644 problems/src/tomtom/Solution1.java create mode 100644 problems/src/zalando/TaskA.java create mode 100644 problems/src/zalando/TaskB.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/.idea/google-java-format.xml b/.idea/google-java-format.xml new file mode 100644 index 00000000..2aa056da --- /dev/null +++ b/.idea/google-java-format.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 00000000..ff858f93 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_3_0_2.xml b/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_3_0_2.xml new file mode 100644 index 00000000..122552e3 --- /dev/null +++ b/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_3_0_2.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_errorprone_error_prone_annotations_2_2_0.xml b/.idea/libraries/Gradle__com_google_errorprone_error_prone_annotations_2_2_0.xml new file mode 100644 index 00000000..9b2f9076 --- /dev/null +++ b/.idea/libraries/Gradle__com_google_errorprone_error_prone_annotations_2_2_0.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_errorprone_javac_shaded_9_181_r4173_1.xml b/.idea/libraries/Gradle__com_google_errorprone_javac_shaded_9_181_r4173_1.xml new file mode 100644 index 00000000..52ed4de9 --- /dev/null +++ b/.idea/libraries/Gradle__com_google_errorprone_javac_shaded_9_181_r4173_1.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_googlejavaformat_google_java_format_1_7.xml b/.idea/libraries/Gradle__com_google_googlejavaformat_google_java_format_1_7.xml new file mode 100644 index 00000000..93c825ed --- /dev/null +++ b/.idea/libraries/Gradle__com_google_googlejavaformat_google_java_format_1_7.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_guava_failureaccess_1_0_1.xml b/.idea/libraries/Gradle__com_google_guava_failureaccess_1_0_1.xml new file mode 100644 index 00000000..8ba66b57 --- /dev/null +++ b/.idea/libraries/Gradle__com_google_guava_failureaccess_1_0_1.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_guava_guava_27_0_1_jre.xml b/.idea/libraries/Gradle__com_google_guava_guava_27_0_1_jre.xml new file mode 100644 index 00000000..d2f31086 --- /dev/null +++ b/.idea/libraries/Gradle__com_google_guava_guava_27_0_1_jre.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml b/.idea/libraries/Gradle__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml new file mode 100644 index 00000000..11f8cce0 --- /dev/null +++ b/.idea/libraries/Gradle__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_j2objc_j2objc_annotations_1_1.xml b/.idea/libraries/Gradle__com_google_j2objc_j2objc_annotations_1_1.xml new file mode 100644 index 00000000..ab45264c --- /dev/null +++ b/.idea/libraries/Gradle__com_google_j2objc_j2objc_annotations_1_1.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_checkerframework_checker_qual_2_5_2.xml b/.idea/libraries/Gradle__org_checkerframework_checker_qual_2_5_2.xml new file mode 100644 index 00000000..e629e112 --- /dev/null +++ b/.idea/libraries/Gradle__org_checkerframework_checker_qual_2_5_2.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_codehaus_mojo_animal_sniffer_annotations_1_17.xml b/.idea/libraries/Gradle__org_codehaus_mojo_animal_sniffer_annotations_1_17.xml new file mode 100644 index 00000000..cbfbdf1d --- /dev/null +++ b/.idea/libraries/Gradle__org_codehaus_mojo_animal_sniffer_annotations_1_17.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/leetcode_main.iml b/.idea/modules/leetcode_main.iml new file mode 100644 index 00000000..dcb84d6f --- /dev/null +++ b/.idea/modules/leetcode_main.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/leetcode_test.iml b/.idea/modules/leetcode_test.iml new file mode 100644 index 00000000..001e400c --- /dev/null +++ b/.idea/modules/leetcode_test.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..e69de29b diff --git a/problems/src/Test1.java b/problems/src/Test1.java new file mode 100644 index 00000000..37427e5b --- /dev/null +++ b/problems/src/Test1.java @@ -0,0 +1,5 @@ +/** + * Created by gouthamvidyapradhan on 14/08/2017. + */ +public class Test1 { +} diff --git a/problems/src/Test2.java b/problems/src/Test2.java new file mode 100644 index 00000000..0fe995cf --- /dev/null +++ b/problems/src/Test2.java @@ -0,0 +1,5 @@ +/** + * Created by gouthamvidyapradhan on 14/08/2017. + */ +public class Test2 { +} diff --git a/problems/src/Test3.java b/problems/src/Test3.java new file mode 100644 index 00000000..cd946537 --- /dev/null +++ b/problems/src/Test3.java @@ -0,0 +1,5 @@ +/** + * Created by gouthamvidyapradhan on 14/08/2017. + */ +public class Test3 { +} diff --git a/problems/src/string/IntegerToEnglishWords.java b/problems/src/string/IntegerToEnglishWords.java new file mode 100644 index 00000000..ae7e296a --- /dev/null +++ b/problems/src/string/IntegerToEnglishWords.java @@ -0,0 +1,10 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 12/08/2017. + */ +public class IntegerToEnglishWords { + public static void main(String[] args) { + System.out.println(Integer.MAX_VALUE); + } +} diff --git a/problems/src/test/MyList.java b/problems/src/test/MyList.java new file mode 100644 index 00000000..2a442251 --- /dev/null +++ b/problems/src/test/MyList.java @@ -0,0 +1,20 @@ +package test; + +/** + * Created by gouthamvidyapradhan on 05/05/2018. + */ +import java.util.*; +public class MyList { + + private static final int[] R = {0, 0, 1, -1}; + private static final int[] C = {1, -1, 0, 0}; + private boolean[][] done; + //private Set done; + + public static void main(String[] args) { + + } + + + +} diff --git a/problems/src/tomtom/Solution1.java b/problems/src/tomtom/Solution1.java new file mode 100644 index 00000000..2c0730f5 --- /dev/null +++ b/problems/src/tomtom/Solution1.java @@ -0,0 +1,11 @@ +package tomtom; + +import java.util.Stack; + +/** + * Created by gouthamvidyapradhan on 03/10/2017. + */ +public class Solution1 { + public static void main(String[] args) throws Exception{ + } +} diff --git a/problems/src/zalando/TaskA.java b/problems/src/zalando/TaskA.java new file mode 100644 index 00000000..52a848ae --- /dev/null +++ b/problems/src/zalando/TaskA.java @@ -0,0 +1,7 @@ +package zalando; + +/** + * Created by gouthamvidyapradhan on 05/07/2018. + */ +public class TaskA { +} diff --git a/problems/src/zalando/TaskB.java b/problems/src/zalando/TaskB.java new file mode 100644 index 00000000..ec33b9d5 --- /dev/null +++ b/problems/src/zalando/TaskB.java @@ -0,0 +1,7 @@ +package zalando; + +/** + * Created by gouthamvidyapradhan on 05/07/2018. + */ +public class TaskB { +} From 69d787c2edded6e107181b536e21e4c3d9cfdb2a Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 3 May 2019 12:38:10 +0200 Subject: [PATCH 211/235] Adding gradle support and google java code formatter --- .gitignore | 18 + .idea/google-java-format.xml | 2 +- .idea/gradle.xml | 5 + ...ooglejavaformat_google_java_format_1_7.xml | 5 +- .idea/modules/leetcode_main.iml | 9 + .idea/modules/leetcode_test.iml | 10 + README.md | 1 - build.gradle | 12 + problems/src/Test1.java | 5 - problems/src/Test2.java | 5 - problems/src/Test3.java | 5 - problems/src/array/BattleshipsInABoard.java | 94 ++-- problems/src/array/BestMeetingPoint.java | 123 ++-- problems/src/array/CanPlaceFlowers.java | 85 ++- problems/src/array/CardFilipGame.java | 91 ++- problems/src/array/ChampagneTower.java | 103 ++-- problems/src/array/EmployeeFreeTime.java | 169 +++--- problems/src/array/FindTheCelebrity.java | 165 +++--- problems/src/array/FirstMissingPositive.java | 66 ++- problems/src/array/FruitIntoBaskets.java | 139 +++-- problems/src/array/HIndex.java | 93 ++-- problems/src/array/ImageSmoother.java | 78 ++- .../array/IncreasingTripletSubsequence.java | 72 ++- problems/src/array/InsertInterval.java | 145 ++--- problems/src/array/KEmptySlots.java | 111 ++-- .../src/array/LargestNumberAtLeastTwice.java | 95 ++-- .../array/LongestIncreasingSubsequence.java | 72 ++- .../src/array/MaxProductOfThreeNumbers.java | 37 +- problems/src/array/MaximumSwap.java | 77 ++- problems/src/array/MeetingRooms.java | 63 ++- problems/src/array/MergeIntervals.java | 91 ++- problems/src/array/MergeSortedArray.java | 37 +- .../src/array/MinimumIndexSumOfTwoLists.java | 121 ++-- .../src/array/MinimumMovesToEqualArray.java | 115 ++-- problems/src/array/MissingNumber.java | 41 +- problems/src/array/MyCalendarThree.java | 134 +++-- problems/src/array/NextGreaterElementI.java | 108 ++-- problems/src/array/PascalsTriangle.java | 67 ++- problems/src/array/PourWater.java | 265 ++++----- .../src/array/ProductOfArrayExceptSelf.java | 54 +- problems/src/array/ReadNCharacters.java | 82 ++- problems/src/array/RelativeRanks.java | 100 ++-- problems/src/array/RotateArray.java | 69 ++- problems/src/array/RotateMatrix.java | 77 +-- problems/src/array/SetMatrixZeroes.java | 82 ++- problems/src/array/SortColors.java | 113 ++-- .../src/array/SparseMatrixMultiplication.java | 118 ++-- .../array/SubArraysWithBoundedMaximum.java | 96 ++-- problems/src/array/SubarraySumEqualsK.java | 100 ++-- .../src/array/SurfaceAreaOfThreeDShapes.java | 107 ++-- problems/src/array/ThirdMaximumNumber.java | 103 ++-- problems/src/array/TwoSum.java | 96 ++-- problems/src/array/TwoSumII.java | 72 ++- problems/src/array/ValidTicTacToeState.java | 132 +++-- problems/src/backtracking/CombinationSum.java | 85 ++- .../src/backtracking/CombinationSumII.java | 80 ++- problems/src/backtracking/Combinations.java | 62 +-- .../backtracking/ExpressionAddOperators.java | 109 ++-- .../src/backtracking/GenerateParentheses.java | 53 +- .../backtracking/LetterCasePermutation.java | 84 ++- .../src/backtracking/LetterPhoneNumber.java | 80 ++- .../backtracking/PalindromePartitioning.java | 91 ++- problems/src/backtracking/Permutations.java | 81 ++- problems/src/backtracking/PermutationsII.java | 69 ++- .../RegularExpressionMatching.java | 119 ++-- .../RemoveInvalidParentheses.java | 137 +++-- problems/src/backtracking/Subsets.java | 69 +-- problems/src/backtracking/SubsetsII.java | 81 ++- problems/src/backtracking/TargetSum.java | 91 ++- .../src/backtracking/WildcardMatching.java | 121 ++-- problems/src/backtracking/WordSearch.java | 119 ++-- problems/src/backtracking/WordSearchII.java | 175 +++--- .../src/binary_search/FindPeakElement.java | 87 ++- .../src/binary_search/FirstBadVersion.java | 52 +- problems/src/binary_search/HIndexII.java | 62 ++- .../MedianOfTwoSortedArrays.java | 150 +++-- .../binary_search/MinSortedRotatedArray.java | 63 +-- problems/src/binary_search/PowXN.java | 47 +- .../src/binary_search/SearchForARange.java | 101 ++-- .../binary_search/SearchInsertPosition.java | 48 +- .../SearchRotatedSortedArray.java | 68 ++- problems/src/binary_search/SqrtX.java | 39 +- .../src/binary_search/SwimInRisingWater.java | 176 +++--- .../bit_manipulation/DivideTwoIntegers.java | 72 +-- problems/src/bit_manipulation/GrayCode.java | 60 +- .../src/bit_manipulation/HammingDistance.java | 76 ++- .../TotalHammingDistance.java | 78 ++- .../BinarayTreeLevelOrderTraversal.java | 135 +++-- .../src/breadth_first_search/BusRoutes.java | 176 +++--- .../CutOffTreesForGolfEvent.java | 204 ++++--- problems/src/breadth_first_search/Matrix.java | 156 +++--- .../src/breadth_first_search/OpenTheLock.java | 161 +++--- .../src/breadth_first_search/RaceCar.java | 153 +++-- .../breadth_first_search/SlidingPuzzle.java | 228 ++++---- .../breadth_first_search/WallsAndGates.java | 122 ++-- .../src/breadth_first_search/WordLadder.java | 132 ++--- .../breadth_first_search/WordLadderII.java | 260 +++++---- .../src/depth_first_search/AccountsMerge.java | 256 +++++---- .../depth_first_search/AlienDictionary.java | 232 ++++---- .../AllPathsFromSourceToTarget.java | 92 ++- .../BricksFallingWhenHit.java | 409 +++++++------- .../src/depth_first_search/CloneGraph.java | 139 +++-- .../depth_first_search/CourseSchedule.java | 147 +++-- .../depth_first_search/CourseScheduleII.java | 169 +++--- .../depth_first_search/CrackingTheSafe.java | 144 +++-- .../depth_first_search/GraphValidTree.java | 127 +++-- .../depth_first_search/IslandPerimeter.java | 115 ++-- .../LongestConsecutiveSequence.java | 119 ++-- .../src/depth_first_search/Minesweeper.java | 194 +++---- .../depth_first_search/MovieRecommend.java | 98 ++-- .../NumberOfDistinctIslands.java | 136 ++--- .../NumberOfDistinctIslandsII.java | 288 +++++----- .../depth_first_search/NumberOfIslands.java | 96 ++-- .../depth_first_search/RobotRoomCleaner.java | 218 ++++---- ...SmallestRectangleEnclosingBlackPixels.java | 105 ++-- problems/src/design/AutocompleteSystem.java | 523 +++++++++--------- problems/src/design/BSTIterator.java | 140 +++-- .../src/design/CopyListWithRandomPointer.java | 125 +++-- .../src/design/EncodeAndDecodeTinyURL.java | 60 +- problems/src/design/Excel.java | 384 +++++++------ problems/src/design/LFUCache.java | 428 +++++++------- problems/src/design/LRUCache.java | 258 ++++----- problems/src/design/NestedIterator.java | 128 +++-- problems/src/design/RandomizedCollection.java | 214 +++---- problems/src/design/RandomizedSet.java | 191 +++---- .../SerializeDeserializeBinaryTree.java | 176 +++--- problems/src/design/TicTacToe.java | 244 ++++---- problems/src/design/Trie.java | 146 +++-- problems/src/design/Twitter.java | 330 ++++++----- problems/src/design/WordDictionary.java | 196 +++---- problems/src/design/WordFilter.java | 194 +++---- .../KthLargestElementInAnArray.java | 85 ++- .../src/divide_and_conquer/ReversePairs.java | 202 ++++--- .../divide_and_conquer/SearchA2DMatrix.java | 86 ++- .../BestTimeToBuyAndSellStockIII.java | 74 +-- .../BestTimeToBuyAndSellStocks.java | 71 ++- .../BestTimeToBuyAndSellStocksWithFee.java | 82 ++- .../dynamic_programming/BurstBalloons.java | 123 ++-- problems/src/dynamic_programming/CanIWin.java | 125 +++-- .../src/dynamic_programming/CatAndMouse.java | 230 ++++---- .../src/dynamic_programming/CherryPickup.java | 135 +++-- .../dynamic_programming/ClimbingStairs.java | 47 +- .../src/dynamic_programming/CoinChange.java | 102 ++-- .../src/dynamic_programming/CoinChange2.java | 91 ++- .../dynamic_programming/CombinationSumIV.java | 103 ++-- .../ConcatenatedWords.java | 93 ++-- .../ContinuousSubarraySum.java | 79 ++- .../dynamic_programming/CornerRectangles.java | 104 ++-- .../src/dynamic_programming/DecodeWays.java | 74 ++- .../src/dynamic_programming/DecodeWaysII.java | 185 +++---- .../src/dynamic_programming/DungeonGame.java | 130 ++--- .../src/dynamic_programming/HouseRobber.java | 49 +- .../dynamic_programming/HouseRobberII.java | 71 ++- .../KnightProbabilityInChessboard.java | 121 ++-- .../dynamic_programming/LargestPlusSign.java | 258 ++++----- .../LargestSumOfAverages.java | 100 ++-- .../LongestIncreasingSubsequence.java | 67 ++- .../LongestPaliandromicSubstring.java | 100 ++-- .../LongestPalindromicSubsequence.java | 60 +- .../dynamic_programming/MaxSum3SubArray.java | 209 ++++--- .../dynamic_programming/MaximalSquare.java | 87 +-- .../MaximumProductSubarray.java | 54 +- .../dynamic_programming/MaximumSubarray.java | 35 +- .../MaximumVacationDays.java | 166 +++--- .../MinCostClimbingStairs.java | 52 +- .../MinimumNumberOfRefuelingStops.java | 147 +++-- .../src/dynamic_programming/NumberOfLIS.java | 120 ++-- .../src/dynamic_programming/OddEvenJump.java | 229 ++++---- .../src/dynamic_programming/PaintHouseII.java | 113 ++-- .../dynamic_programming/PalindromePairs.java | 270 +++++---- .../PalindromePartitioningII.java | 81 +-- .../PalindromicSubstrings.java | 86 ++- .../ProfitableSchemes.java | 110 ++-- .../SplitArrayLargestSum.java | 93 ++-- .../src/dynamic_programming/StoneGame.java | 155 +++--- .../dynamic_programming/TwoKeysKeyboard.java | 70 ++- .../UniqueBinarySearchTrees.java | 57 +- .../UniqueBinarySearchTreesII.java | 140 +++-- .../src/dynamic_programming/WordBreak.java | 93 ++-- .../src/dynamic_programming/WordBreakII.java | 100 ++-- problems/src/greedy/BurstBalloons.java | 79 +-- problems/src/greedy/CourseScheduleIII.java | 76 ++- problems/src/greedy/GasStation.java | 72 +-- problems/src/greedy/IPO.java | 169 +++--- problems/src/greedy/JumpGame.java | 56 +- problems/src/greedy/JumpGameII.java | 65 ++- problems/src/greedy/LemonadeChange.java | 119 ++-- .../src/greedy/MaximumLengthOfPairChain.java | 79 ++- .../src/greedy/NonOverlappingIntervals.java | 120 ++-- .../greedy/QueueReconstructionByHeight.java | 55 +- .../src/greedy/ScoreAfterFlippingMatrix.java | 147 +++-- problems/src/greedy/TaskScheduler.java | 149 ++--- problems/src/hashing/Anagrams.java | 130 ++--- problems/src/hashing/BrickWall.java | 167 +++--- problems/src/hashing/ContiguousArray.java | 85 ++- problems/src/hashing/CustomSortString.java | 109 ++-- problems/src/hashing/DistributeCandies.java | 55 +- problems/src/hashing/GroupAnagrams.java | 96 ++-- .../GroupsOfSpecialEquivalentStrings.java | 109 ++-- problems/src/hashing/KdiffPairsInanArray.java | 85 ++- .../MaximumSizeSubarraySumEqualsk.java | 96 ++-- problems/src/hashing/PartitionLabels.java | 94 ++-- .../src/hashing/ShortEncodingOfWords.java | 100 ++-- problems/src/hashing/SortCharByFrequency.java | 136 +++-- .../SubstringConcatenationOfWords.java | 111 ++-- problems/src/hashing/TwoSum.java | 89 ++- problems/src/hashing/ValidAnagram.java | 69 ++- problems/src/heap/Candy.java | 155 +++--- problems/src/heap/FreqStack.java | 258 +++++---- problems/src/heap/MeetingRoomsII.java | 93 ++-- problems/src/heap/SlidingWindowMaximum.java | 100 ++-- .../SmallestRotationWithHighestScore.java | 158 +++--- problems/src/heap/TheSkylineProblem.java | 270 +++++---- problems/src/heap/TopKFrequentWords.java | 126 +++-- problems/src/linked_list/DeleteNode.java | 67 +-- .../linked_list/IntersectionOfTwoLists.java | 142 +++-- problems/src/linked_list/LinkedListCycle.java | 78 ++- .../src/linked_list/MergeKSortedLists.java | 164 +++--- .../src/linked_list/MergeTwoSortedList.java | 90 +-- .../src/linked_list/MiddleOfLinkedList.java | 80 ++- problems/src/linked_list/PaliandromeList.java | 135 +++-- .../src/linked_list/ReverseLinkedList.java | 91 ++- .../src/linked_list/ReverseNodesKGroup.java | 159 +++--- .../src/linked_list/SwapNodesInPairs.java | 90 ++- problems/src/math/AddDigits.java | 33 +- problems/src/math/AddTwoNumbers.java | 123 ++-- problems/src/math/BulbSwitcherII.java | 76 ++- problems/src/math/CountPrimes.java | 60 +- problems/src/math/CouplesHoldingHands.java | 135 +++-- problems/src/math/ExcelSheetColumnTitle.java | 66 +-- .../src/math/GlobalAndLocalInversions.java | 86 ++- problems/src/math/NthMagicalNumber.java | 127 ++--- problems/src/math/ReachingPoints.java | 143 +++-- problems/src/math/RomanToInteger.java | 69 ++- problems/src/math/RotateFunction.java | 93 ++-- problems/src/math/SolveTheEquation.java | 190 +++---- problems/src/math/SquirrelSimulation.java | 80 ++- problems/src/math/WaterAndJugProblem.java | 68 ++- .../reservoir_sampling/RandomPickIndex.java | 97 ++-- problems/src/stack/BasicCalculator.java | 145 +++-- problems/src/stack/DecodeString.java | 110 ++-- .../src/stack/ExclusiveTimeOfFunctions.java | 159 +++--- .../stack/LargestRectangleInHistogram.java | 84 +-- .../src/stack/LongestValidParentheses.java | 114 ++-- problems/src/stack/MaximalRectangle.java | 131 ++--- problems/src/stack/MinStack.java | 111 ++-- problems/src/stack/MyQueue.java | 126 ++--- problems/src/stack/ValidParentheses.java | 85 +-- problems/src/string/AddBinary.java | 74 ++- .../src/string/CompareVersionNumbers.java | 83 ++- problems/src/string/CountAndSay.java | 89 ++- .../src/string/ExcelSheetColumnNumber.java | 47 +- .../src/string/FindTheClosestPalindrome.java | 225 ++++---- .../string/FirstUniqueCharacterInAString.java | 57 +- problems/src/string/ImplementStrStr.java | 60 +- .../src/string/IntegerToEnglishWords.java | 10 - problems/src/string/IsomorphicStrings.java | 87 ++- problems/src/string/KeyboardRow.java | 90 ++- problems/src/string/LongestCommonPrefix.java | 49 +- problems/src/string/LongestPalindrome.java | 78 ++- .../src/string/LongestWordInDictonary.java | 92 ++- .../src/string/MonotoneIncreasingDigits.java | 108 ++-- problems/src/string/MultiplyStrings.java | 123 ++-- .../string/NumberOfMatchingSubsequences.java | 84 ++- problems/src/string/OneEditDistance.java | 77 +-- problems/src/string/PermutationInString.java | 95 ++-- .../src/string/RepeatedSubstringPattern.java | 90 ++- problems/src/string/ReplaceWords.java | 158 +++--- problems/src/string/ReverseWordsII.java | 112 ++-- .../src/string/ReverseWordsInAString.java | 66 +-- problems/src/string/RotateString.java | 59 +- problems/src/string/ShortestPalindrome.java | 94 ++-- problems/src/string/SimplifyPath.java | 77 ++- problems/src/string/StringCompression.java | 153 +++-- problems/src/string/StringToInteger.java | 94 ++-- problems/src/string/TextJustification.java | 134 +++-- problems/src/string/ValidPalindrome.java | 67 ++- problems/src/string/ValidPalindromeII.java | 69 ++- .../src/string/ValidWordAbbreviation.java | 113 ++-- problems/src/string/ZigZagConversion.java | 116 ++-- problems/src/test/MyList.java | 20 - problems/src/tomtom/Solution1.java | 11 - .../tree/AllNodesDistanceKInBinaryTree.java | 187 +++---- .../src/tree/AllPossibleFullBinaryTrees.java | 112 ++-- .../src/tree/AverageOfLevelsInBinaryTree.java | 119 ++-- problems/src/tree/BSTtoDoublyLinkedList.java | 90 +-- .../src/tree/BinarayTreeRightSideView.java | 109 ++-- .../src/tree/BinaryTreeInorderTraversal.java | 88 ++- ...inaryTreeLongestConsecutiveSequenceII.java | 165 +++--- .../src/tree/BinaryTreeMaximumPathSum.java | 103 ++-- problems/src/tree/BinaryTreePaths.java | 64 +-- .../tree/BinaryTreePostorderTraversal.java | 98 ++-- problems/src/tree/BoundaryOfBinaryTree.java | 249 ++++----- .../tree/ClosestBinarySearchTreeValue.java | 95 ++-- .../src/tree/ClosestLeafInABinaryTree.java | 243 ++++---- .../tree/ConstructStringFromBinaryTree.java | 113 ++-- .../src/tree/ConvertBSTToGreaterTree.java | 78 ++- .../src/tree/ConvertSortedArrayToBST.java | 47 +- problems/src/tree/DiameterOfBinaryTree.java | 81 ++- problems/src/tree/EqualTreePartition.java | 141 ++--- .../src/tree/FindBottomLeftTreeValue.java | 100 ++-- problems/src/tree/FlattenBinaryTree.java | 137 ++--- problems/src/tree/InorderSuccessorInBST.java | 119 ++-- problems/src/tree/LCA.java | 75 ++- problems/src/tree/LargestBSTSubtree.java | 188 +++---- .../src/tree/LowestCommonAncestorBST.java | 63 +-- problems/src/tree/MaximumBinaryTree.java | 121 ++-- .../src/tree/MaximumWidthOfBinaryTree.java | 151 +++-- .../tree/MinimumAbsoluteDifferenceInBST.java | 89 ++- problems/src/tree/MostFrequentSubtreeSum.java | 132 ++--- problems/src/tree/NextRightPointer.java | 129 ++--- problems/src/tree/NextRightPointerII.java | 109 ++-- problems/src/tree/PathSumIII.java | 106 ++-- problems/src/tree/PostorderToBT.java | 102 ++-- problems/src/tree/PreorderToBT.java | 94 ++-- .../src/tree/RecoverBinarySearchTree.java | 171 +++--- problems/src/tree/SameTree.java | 112 ++-- .../tree/SerializeAndDeserializeNAryTree.java | 184 +++--- problems/src/tree/SortedArrayToBST.java | 93 ++-- problems/src/tree/SplitBST.java | 154 +++--- problems/src/tree/SubtreeOfAnotherTree.java | 91 ++- problems/src/tree/SumofLeftLeaves.java | 79 ++- problems/src/tree/SymmetricTree.java | 81 ++- problems/src/tree/TwoSumIV.java | 107 ++-- problems/src/tree/ValidBinarySearchTree.java | 115 ++-- problems/src/tree/ZigZagTraversal.java | 85 ++- problems/src/two_pointers/FourSum.java | 99 ++-- .../LongestSubstringWitoutRepeats.java | 67 +-- .../two_pointers/MinimumSizeSubarraySum.java | 90 +-- .../two_pointers/MinimumWindowSubstring.java | 129 +++-- problems/src/two_pointers/MoveZeroes.java | 57 +- .../NumberOfMatchingSubsequences.java | 89 ++- .../src/two_pointers/RemoveDuplicates.java | 51 +- .../src/two_pointers/RemoveDuplicatesII.java | 68 ++- problems/src/two_pointers/SmallestRange.java | 134 +++-- .../SubarrayProductLessThanK.java | 107 ++-- problems/src/two_pointers/ThreeSum.java | 88 +-- .../src/two_pointers/ThreeSumClosest.java | 84 +-- .../src/two_pointers/TrappingRainWater.java | 78 +-- problems/src/zalando/TaskA.java | 7 - problems/src/zalando/TaskB.java | 7 - 341 files changed, 18172 insertions(+), 19879 deletions(-) delete mode 100644 problems/src/Test1.java delete mode 100644 problems/src/Test2.java delete mode 100644 problems/src/Test3.java delete mode 100644 problems/src/string/IntegerToEnglishWords.java delete mode 100644 problems/src/test/MyList.java delete mode 100644 problems/src/tomtom/Solution1.java delete mode 100644 problems/src/zalando/TaskA.java delete mode 100644 problems/src/zalando/TaskB.java diff --git a/.gitignore b/.gitignore index e69de29b..4042776d 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,18 @@ +CheckerClass.template +TaskClass.template +TestCaseClass.template +TopCoderTaskClass.template +TopCoderTestCaseClass.template +build/ +chelper.properties +gradle/ +gradlew +gradlew.bat +leetcode.iml +leetcode.ipr +leetcode.iws +out/ +problems/src.iml +.idea/codeStyles/ +.idea/copyright/ +.idea/markdown-navigator/ diff --git a/.idea/google-java-format.xml b/.idea/google-java-format.xml index 2aa056da..8b57f452 100644 --- a/.idea/google-java-format.xml +++ b/.idea/google-java-format.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index ff858f93..0ca37c94 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -6,6 +6,11 @@ diff --git a/.idea/libraries/Gradle__com_google_googlejavaformat_google_java_format_1_7.xml b/.idea/libraries/Gradle__com_google_googlejavaformat_google_java_format_1_7.xml index 93c825ed..374a1a85 100644 --- a/.idea/libraries/Gradle__com_google_googlejavaformat_google_java_format_1_7.xml +++ b/.idea/libraries/Gradle__com_google_googlejavaformat_google_java_format_1_7.xml @@ -2,8 +2,11 @@ + - + + + \ No newline at end of file diff --git a/.idea/modules/leetcode_main.iml b/.idea/modules/leetcode_main.iml index dcb84d6f..784fcd71 100644 --- a/.idea/modules/leetcode_main.iml +++ b/.idea/modules/leetcode_main.iml @@ -7,5 +7,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/leetcode_test.iml b/.idea/modules/leetcode_test.iml index 001e400c..7ac9b410 100644 --- a/.idea/modules/leetcode_test.iml +++ b/.idea/modules/leetcode_test.iml @@ -6,7 +6,17 @@ + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 686a9637..6070d906 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,6 @@ My accepted leetcode solutions to some of the common interview problems. - [Profitable Schemes](problems/src/dynamic_programming/ProfitableSchemes.java) (Hard) - [Maximum Vacation Days](problems/src/dynamic_programming/MaximumVacationDays.java) (Hard) - #### [Greedy](problems/src/greedy) - [Jump Game](problems/src/greedy/JumpGame.java) (Medium) diff --git a/build.gradle b/build.gradle index e69de29b..2a27034e 100644 --- a/build.gradle +++ b/build.gradle @@ -0,0 +1,12 @@ +plugins { + id 'java' + id 'com.github.sherter.google-java-format' version '0.8' +} + +dependencies { + compile 'com.google.googlejavaformat:google-java-format:1.7' +} + +repositories { + jcenter() // or mavenCentral() +} \ No newline at end of file diff --git a/problems/src/Test1.java b/problems/src/Test1.java deleted file mode 100644 index 37427e5b..00000000 --- a/problems/src/Test1.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Created by gouthamvidyapradhan on 14/08/2017. - */ -public class Test1 { -} diff --git a/problems/src/Test2.java b/problems/src/Test2.java deleted file mode 100644 index 0fe995cf..00000000 --- a/problems/src/Test2.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Created by gouthamvidyapradhan on 14/08/2017. - */ -public class Test2 { -} diff --git a/problems/src/Test3.java b/problems/src/Test3.java deleted file mode 100644 index cd946537..00000000 --- a/problems/src/Test3.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Created by gouthamvidyapradhan on 14/08/2017. - */ -public class Test3 { -} diff --git a/problems/src/array/BattleshipsInABoard.java b/problems/src/array/BattleshipsInABoard.java index c42fbbde..566221fe 100644 --- a/problems/src/array/BattleshipsInABoard.java +++ b/problems/src/array/BattleshipsInABoard.java @@ -1,62 +1,54 @@ package array; /** - * Created by gouthamvidyapradhan on 12/08/2017. - * Given an 2D board, count how many battleships are in it. The battleships are represented with 'X's, empty slots are represented with '.'s. You may assume the following rules: - *

- * You receive a valid board, made of only battleships or empty slots. - * Battleships can only be placed horizontally or vertically. In other words, they can only be made of the shape 1xN (1 row, N columns) or Nx1 (N rows, 1 column), where N can be of any size. - * At least one horizontal or vertical cell separates between two battleships - there are no adjacent battleships. - * Example: - * X..X - * ...X - * ...X - * In the above board there are 2 battleships. - * Invalid Example: - * ...X - * XXXX - * ...X - * This is an invalid board that you will not receive - as battleships will always have a cell separating between them. - *

- * Follow up: - * Could you do it in one-pass, using only O(1) extra memory and without modifying the value of the board? - *

- * Solution: - * The below solution works in one pass using only O(1) memory. - * Iterate through each cell and add one to count if and only if the current cell equals 'X' and its adjacent upper and + * Created by gouthamvidyapradhan on 12/08/2017. Given an 2D board, count how many battleships are + * in it. The battleships are represented with 'X's, empty slots are represented with '.'s. You may + * assume the following rules: + * + *

You receive a valid board, made of only battleships or empty slots. Battleships can only be + * placed horizontally or vertically. In other words, they can only be made of the shape 1xN (1 row, + * N columns) or Nx1 (N rows, 1 column), where N can be of any size. At least one horizontal or + * vertical cell separates between two battleships - there are no adjacent battleships. Example: + * X..X ...X ...X In the above board there are 2 battleships. Invalid Example: ...X XXXX ...X This + * is an invalid board that you will not receive - as battleships will always have a cell separating + * between them. + * + *

Follow up: Could you do it in one-pass, using only O(1) extra memory and without modifying the + * value of the board? + * + *

Solution: The below solution works in one pass using only O(1) memory. Iterate through each + * cell and add one to count if and only if the current cell equals 'X' and its adjacent upper and * left cell does not contain 'X' */ public class BattleshipsInABoard { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - char[][] board = {{'X', '.', '.', 'X'}, {'.', '.', '.', 'X'}, {'.', '.', '.', 'X'}}; - System.out.println(new BattleshipsInABoard().countBattleships(board)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + char[][] board = {{'X', '.', '.', 'X'}, {'.', '.', '.', 'X'}, {'.', '.', '.', 'X'}}; + System.out.println(new BattleshipsInABoard().countBattleships(board)); + } - public int countBattleships(char[][] board) { - int count = 0; - for (int i = 0; i < board.length; i++) { - for (int j = 0; j < board[0].length; j++) { - if (board[i][j] == 'X') { - if (i - 1 >= 0) { //check for the boundary condition - if (board[i - 1][j] == 'X') - continue; - } - if (j - 1 >= 0) { - if (board[i][j - 1] == 'X') { - continue; - } - } - count++; - } + public int countBattleships(char[][] board) { + int count = 0; + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (board[i][j] == 'X') { + if (i - 1 >= 0) { // check for the boundary condition + if (board[i - 1][j] == 'X') continue; + } + if (j - 1 >= 0) { + if (board[i][j - 1] == 'X') { + continue; } + } + count++; } - return count; + } } - + return count; + } } diff --git a/problems/src/array/BestMeetingPoint.java b/problems/src/array/BestMeetingPoint.java index c2d9e8c1..46c04225 100644 --- a/problems/src/array/BestMeetingPoint.java +++ b/problems/src/array/BestMeetingPoint.java @@ -1,81 +1,76 @@ package array; /** - * Created by gouthamvidyapradhan on 10/03/2019 - * A group of two or more people wants to meet and minimize the total travel distance. You are given a 2D grid of - * values 0 or 1, where each 1 marks the home of someone in the group. The distance is calculated using Manhattan - * Distance, where distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|. - *

- * Example: - *

- * Input: - *

- * 1 - 0 - 0 - 0 - 1 - * | | | | | - * 0 - 0 - 0 - 0 - 0 - * | | | | | - * 0 - 0 - 1 - 0 - 0 - *

- * Output: 6 - *

- * Explanation: Given three people living at (0,0), (0,4), and (2,2): - * The point (0,2) is an ideal meeting point, as the total travel distance - * of 2+2+2=6 is minimal. So return 6. - *

- * Solution: O(N ^ 2 + M ^ 2) + O(N x M): Calculate the total number of persons in each row and each column and then - * take a minimum of cartesian product of each row and each column. + * Created by gouthamvidyapradhan on 10/03/2019 A group of two or more people wants to meet and + * minimize the total travel distance. You are given a 2D grid of values 0 or 1, where each 1 marks + * the home of someone in the group. The distance is calculated using Manhattan Distance, where + * distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|. + * + *

Example: + * + *

Input: + * + *

1 - 0 - 0 - 0 - 1 | | | | | 0 - 0 - 0 - 0 - 0 | | | | | 0 - 0 - 1 - 0 - 0 + * + *

Output: 6 + * + *

Explanation: Given three people living at (0,0), (0,4), and (2,2): The point (0,2) is an ideal + * meeting point, as the total travel distance of 2+2+2=6 is minimal. So return 6. + * + *

Solution: O(N ^ 2 + M ^ 2) + O(N x M): Calculate the total number of persons in each row and + * each column and then take a minimum of cartesian product of each row and each column. */ public class BestMeetingPoint { - /** - * Main method - * - * @param args - */ - public static void main(String[] args) { - int[][] grid = {{1, 0, 0, 0, 1}, {0, 0, 0, 0, 0}, {0, 0, 1, 0, 0}}; - System.out.println(new BestMeetingPoint().minTotalDistance(grid)); - } - - public int minTotalDistance(int[][] grid) { - int[] countR = new int[grid.length]; - int[] countC = new int[grid[0].length]; + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[][] grid = {{1, 0, 0, 0, 1}, {0, 0, 0, 0, 0}, {0, 0, 1, 0, 0}}; + System.out.println(new BestMeetingPoint().minTotalDistance(grid)); + } - int[] distR = new int[grid.length]; - int[] distC = new int[grid[0].length]; + public int minTotalDistance(int[][] grid) { + int[] countR = new int[grid.length]; + int[] countC = new int[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) { - countR[i]++; - countC[j]++; - } - } - } + int[] distR = new int[grid.length]; + int[] distC = new int[grid[0].length]; - for (int i = 0; i < distR.length; i++) { - for (int j = 0; j < distR.length; j++) { - if (countR[j] != 0) { - distR[i] += Math.abs(j - i) * countR[j]; - } - } + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 1) { + countR[i]++; + countC[j]++; } + } + } - for (int i = 0; i < distC.length; i++) { - for (int j = 0; j < distC.length; j++) { - if (countC[j] != 0) { - distC[i] += Math.abs(j - i) * countC[j]; - } - } + for (int i = 0; i < distR.length; i++) { + for (int j = 0; j < distR.length; j++) { + if (countR[j] != 0) { + distR[i] += Math.abs(j - i) * countR[j]; } + } + } - int min = Integer.MAX_VALUE; - for (int i = 0; i < distR.length; i++) { - for (int j = 0; j < distC.length; j++) { - min = Math.min(min, distR[i] + distC[j]); - } + for (int i = 0; i < distC.length; i++) { + for (int j = 0; j < distC.length; j++) { + if (countC[j] != 0) { + distC[i] += Math.abs(j - i) * countC[j]; } + } + } - return min; + int min = Integer.MAX_VALUE; + for (int i = 0; i < distR.length; i++) { + for (int j = 0; j < distC.length; j++) { + min = Math.min(min, distR[i] + distC[j]); + } } + + return min; + } } diff --git a/problems/src/array/CanPlaceFlowers.java b/problems/src/array/CanPlaceFlowers.java index 8b7e732e..d811e108 100644 --- a/problems/src/array/CanPlaceFlowers.java +++ b/problems/src/array/CanPlaceFlowers.java @@ -1,55 +1,48 @@ package array; /** - * Created by gouthamvidyapradhan on 10/06/2017. - * Accepted - *

- * Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, flowers cannot be planted in adjacent plots - they would compete for water and both would die. - *

- * Given a flowerbed (represented as an array containing 0 and 1, where 0 means empty and 1 means not empty), and a number n, return if n new flowers can be planted in it without violating the no-adjacent-flowers rule. - *

- * Example 1: - * Input: flowerbed = [1,0,0,0,1], n = 1 - * Output: True - * Example 2: - * Input: flowerbed = [1,0,0,0,1], n = 2 - * Output: False - * Note: - * The input array won't violate no-adjacent-flowers rule. - * The input array size is in the range of [1, 20000]. - * n is a non-negative integer which won't exceed the input array size. + * Created by gouthamvidyapradhan on 10/06/2017. Accepted + * + *

Suppose you have a long flowerbed in which some of the plots are planted and some are not. + * However, flowers cannot be planted in adjacent plots - they would compete for water and both + * would die. + * + *

Given a flowerbed (represented as an array containing 0 and 1, where 0 means empty and 1 means + * not empty), and a number n, return if n new flowers can be planted in it without violating the + * no-adjacent-flowers rule. + * + *

Example 1: Input: flowerbed = [1,0,0,0,1], n = 1 Output: True Example 2: Input: flowerbed = + * [1,0,0,0,1], n = 2 Output: False Note: The input array won't violate no-adjacent-flowers rule. + * The input array size is in the range of [1, 20000]. n is a non-negative integer which won't + * exceed the input array size. */ public class CanPlaceFlowers { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] n = {1, 0, 0, 0, 1}; - System.out.println(new CanPlaceFlowers().canPlaceFlowers(n, 1)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] n = {1, 0, 0, 0, 1}; + System.out.println(new CanPlaceFlowers().canPlaceFlowers(n, 1)); + } - public boolean canPlaceFlowers(int[] flowerbed, int n) { + public boolean canPlaceFlowers(int[] flowerbed, int n) { - int[] T = new int[flowerbed.length + 4]; - for (int i = 0, j = 2; i < flowerbed.length; i++) - T[j++] = flowerbed[i]; - T[0] = 1; - T[T.length - 1] = 1; - int total = 0, count = 0; - for (int i = 1; i < T.length; i++) { - if (T[i] == 0) - count++; - else { - if ((count % 2) == 0) - total += ((count / 2) - 1); - else - total += (count / 2); - count = 0; //reset - } - } - return (total >= n); + int[] T = new int[flowerbed.length + 4]; + for (int i = 0, j = 2; i < flowerbed.length; i++) T[j++] = flowerbed[i]; + T[0] = 1; + T[T.length - 1] = 1; + int total = 0, count = 0; + for (int i = 1; i < T.length; i++) { + if (T[i] == 0) count++; + else { + if ((count % 2) == 0) total += ((count / 2) - 1); + else total += (count / 2); + count = 0; // reset + } } + return (total >= n); + } } diff --git a/problems/src/array/CardFilipGame.java b/problems/src/array/CardFilipGame.java index ede311ad..5a8e1e90 100644 --- a/problems/src/array/CardFilipGame.java +++ b/problems/src/array/CardFilipGame.java @@ -7,59 +7,54 @@ /** * Created by gouthamvidyapradhan on 04/05/2018. * - * On a table are N cards, with a positive integer printed on the front and back of each card (possibly different). - - We flip any number of cards, and after we choose one card. - - If the number X on the back of the chosen card is not on the front of any card, then this number X is good. - - What is the smallest number that is good? If no number is good, output 0. - - Here, fronts[i] and backs[i] represent the number on the front and back of card i. - - A flip swaps the front and back numbers, so the value on the front is now on the back and vice versa. - - Example: - - Input: fronts = [1,2,4,4,7], backs = [1,3,4,1,3] - Output: 2 - Explanation: If we flip the second card, the fronts are [1,3,4,4,7] and the backs are [1,2,4,1,3]. - We choose the second card, which has number 2 on the back, and it isn't on the front of any card, so 2 is good. - - - Note: - - 1 <= fronts.length == backs.length <= 1000. - 1 <= fronts[i] <= 2000. - 1 <= backs[i] <= 2000. - + *

On a table are N cards, with a positive integer printed on the front and back of each card + * (possibly different). + * + *

We flip any number of cards, and after we choose one card. + * + *

If the number X on the back of the chosen card is not on the front of any card, then this + * number X is good. + * + *

What is the smallest number that is good? If no number is good, output 0. + * + *

Here, fronts[i] and backs[i] represent the number on the front and back of card i. + * + *

A flip swaps the front and back numbers, so the value on the front is now on the back and vice + * versa. + * + *

Example: + * + *

Input: fronts = [1,2,4,4,7], backs = [1,3,4,1,3] Output: 2 Explanation: If we flip the second + * card, the fronts are [1,3,4,4,7] and the backs are [1,2,4,1,3]. We choose the second card, which + * has number 2 on the back, and it isn't on the front of any card, so 2 is good. + * + *

Note: + * + *

1 <= fronts.length == backs.length <= 1000. 1 <= fronts[i] <= 2000. 1 <= backs[i] <= 2000. */ public class CardFilipGame { - public static void main(String[] args) { + public static void main(String[] args) {} + public int flipgame(int[] fronts, int[] backs) { + List numbers = new ArrayList<>(); + for (int i = 0; i < fronts.length; i++) { + numbers.add(fronts[i]); + numbers.add(backs[i]); } - - public int flipgame(int[] fronts, int[] backs) { - List numbers = new ArrayList<>(); - for(int i = 0; i < fronts.length; i ++){ - numbers.add(fronts[i]); - numbers.add(backs[i]); + Collections.sort(numbers); + for (int n : numbers) { + boolean success = true; + for (int i = 0; i < fronts.length; i++) { + if (n == fronts[i] && n == backs[i]) { + success = false; + break; } - Collections.sort(numbers); - for(int n : numbers){ - boolean success = true; - for(int i = 0; i < fronts.length; i ++){ - if(n == fronts[i] && n == backs[i]){ - success = false; - break; - } - } - if(success){ - return n; - } - } - return 0; + } + if (success) { + return n; + } } - + return 0; + } } diff --git a/problems/src/array/ChampagneTower.java b/problems/src/array/ChampagneTower.java index cedcb529..6296214d 100644 --- a/problems/src/array/ChampagneTower.java +++ b/problems/src/array/ChampagneTower.java @@ -1,74 +1,69 @@ package array; /** - * Created by gouthamvidyapradhan on 28/03/2019 - * We stack glasses in a pyramid, where the first row has 1 glass, the second row has 2 glasses, and so on until the - * 100th row. Each glass holds one cup (250ml) of champagne. + * Created by gouthamvidyapradhan on 28/03/2019 We stack glasses in a pyramid, where the first row + * has 1 glass, the second row has 2 glasses, and so on until the 100th row. Each glass holds one + * cup (250ml) of champagne. * - * Then, some champagne is poured in the first glass at the top. When the top most glass is full, any excess liquid - * poured will fall equally to the glass immediately to the left and right of it. When those glasses become full, - * any excess champagne will fall equally to the left and right of those glasses, and so on. (A glass at the bottom - * row has it's excess champagne fall on the floor.) + *

Then, some champagne is poured in the first glass at the top. When the top most glass is full, + * any excess liquid poured will fall equally to the glass immediately to the left and right of it. + * When those glasses become full, any excess champagne will fall equally to the left and right of + * those glasses, and so on. (A glass at the bottom row has it's excess champagne fall on the + * floor.) * - * For example, after one cup of champagne is poured, the top most glass is full. After two cups of champagne are - * poured, the two glasses on the second row are half full. After three cups of champagne are poured, those two - * cups become full - there are 3 full glasses total now. After four cups of champagne are poured, the third row - * has the middle glass half full, and the two outside glasses are a quarter full, as pictured below. + *

For example, after one cup of champagne is poured, the top most glass is full. After two cups + * of champagne are poured, the two glasses on the second row are half full. After three cups of + * champagne are poured, those two cups become full - there are 3 full glasses total now. After four + * cups of champagne are poured, the third row has the middle glass half full, and the two outside + * glasses are a quarter full, as pictured below. * + *

Now after pouring some non-negative integer cups of champagne, return how full the j-th glass + * in the i-th row is (both i and j are 0 indexed.) * - * - * Now after pouring some non-negative integer cups of champagne, return how full the j-th glass in the i-th row is - * (both i and j are 0 indexed.) - * - * - * - * Example 1: - * Input: poured = 1, query_glass = 1, query_row = 1 - * Output: 0.0 - * Explanation: We poured 1 cup of champange to the top glass of the tower (which is indexed as (0, 0)). There will + *

Example 1: Input: poured = 1, query_glass = 1, query_row = 1 Output: 0.0 Explanation: We + * poured 1 cup of champange to the top glass of the tower (which is indexed as (0, 0)). There will * be no excess liquid so all the glasses under the top glass will remain empty. * - * Example 2: - * Input: poured = 2, query_glass = 1, query_row = 1 - * Output: 0.5 - * Explanation: We poured 2 cups of champange to the top glass of the tower (which is indexed as (0, 0)). There is - * one cup of excess liquid. The glass indexed as (1, 0) and the glass indexed as (1, 1) will share the excess liquid - * equally, and each will get half cup of champange. + *

Example 2: Input: poured = 2, query_glass = 1, query_row = 1 Output: 0.5 Explanation: We + * poured 2 cups of champange to the top glass of the tower (which is indexed as (0, 0)). There is + * one cup of excess liquid. The glass indexed as (1, 0) and the glass indexed as (1, 1) will share + * the excess liquid equally, and each will get half cup of champange. * + *

Note: * - * Note: + *

poured will be in the range of [0, 10 ^ 9]. query_glass and query_row will be in the range of + * [0, 99]. * - * poured will be in the range of [0, 10 ^ 9]. - * query_glass and query_row will be in the range of [0, 99]. + *

Solution: Calculate for every glass and for each row at a time. Use the value from the + * previous row to calculate the current value. * - * Solution: Calculate for every glass and for each row at a time. Use the value from the previous row to calculate the - * current value. * @see PascalsTriangle */ public class ChampagneTower { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - System.out.println(new ChampagneTower().champagneTower(4, 2, 1)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + System.out.println(new ChampagneTower().champagneTower(4, 2, 1)); + } - public double champagneTower(int poured, int query_row, int query_glass) { - double[][] A = new double[query_row + 1][query_row + 1]; - A[0][0] = poured; - for(int i = 1; i <= query_row; i ++){ - for(int j = 0; j <= query_row; j ++){ - if(A[i - 1][j] > 1.0){ - A[i][j] += (A[i - 1][j] - 1.0) / 2; - } - if(j == 0) continue; - if(A[i - 1][j - 1] > 1.0){ - A[i][j] += (A[i - 1][j - 1] - 1.0) / 2; - } - } + public double champagneTower(int poured, int query_row, int query_glass) { + double[][] A = new double[query_row + 1][query_row + 1]; + A[0][0] = poured; + for (int i = 1; i <= query_row; i++) { + for (int j = 0; j <= query_row; j++) { + if (A[i - 1][j] > 1.0) { + A[i][j] += (A[i - 1][j] - 1.0) / 2; + } + if (j == 0) continue; + if (A[i - 1][j - 1] > 1.0) { + A[i][j] += (A[i - 1][j - 1] - 1.0) / 2; } - if(A[query_row][query_glass] > 1.0) return 1; - else return A[query_row][query_glass]; + } } + if (A[query_row][query_glass] > 1.0) return 1; + else return A[query_row][query_glass]; + } } diff --git a/problems/src/array/EmployeeFreeTime.java b/problems/src/array/EmployeeFreeTime.java index d365f958..f6aff8dc 100644 --- a/problems/src/array/EmployeeFreeTime.java +++ b/problems/src/array/EmployeeFreeTime.java @@ -4,109 +4,114 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 08/03/2019 - * We are given a list schedule of employees, which represents the working time for each employee. + * Created by gouthamvidyapradhan on 08/03/2019 We are given a list schedule of employees, which + * represents the working time for each employee. * - * Each employee has a list of non-overlapping Intervals, and these intervals are in sorted order. + *

Each employee has a list of non-overlapping Intervals, and these intervals are in sorted + * order. * - * Return the list of finite intervals representing common, positive-length free time for all employees, also in sorted order. + *

Return the list of finite intervals representing common, positive-length free time for all + * employees, also in sorted order. * - * Example 1: - * Input: schedule = [[[1,2],[5,6]],[[1,3]],[[4,10]]] - * Output: [[3,4]] - * Explanation: - * There are a total of three employees, and all common - * free time intervals would be [-inf, 1], [3, 4], [10, inf]. - * We discard any intervals that contain inf as they aren't finite. - * Example 2: - * Input: schedule = [[[1,3],[6,7]],[[2,4]],[[2,5],[9,12]]] - * Output: [[5,6],[7,9]] - * (Even though we are representing Intervals in the form [x, y], the objects inside are Intervals, not lists or arrays. For example, schedule[0][0].start = 1, schedule[0][0].end = 2, and schedule[0][0][0] is not defined.) + *

Example 1: Input: schedule = [[[1,2],[5,6]],[[1,3]],[[4,10]]] Output: [[3,4]] Explanation: + * There are a total of three employees, and all common free time intervals would be [-inf, 1], [3, + * 4], [10, inf]. We discard any intervals that contain inf as they aren't finite. Example 2: Input: + * schedule = [[[1,3],[6,7]],[[2,4]],[[2,5],[9,12]]] Output: [[5,6],[7,9]] (Even though we are + * representing Intervals in the form [x, y], the objects inside are Intervals, not lists or arrays. + * For example, schedule[0][0].start = 1, schedule[0][0].end = 2, and schedule[0][0][0] is not + * defined.) * - * Also, we wouldn't include intervals like [5, 5] in our answer, as they have zero length. + *

Also, we wouldn't include intervals like [5, 5] in our answer, as they have zero length. * - * Note: + *

Note: * - * schedule and schedule[i] are lists with lengths in range [1, 50]. - * 0 <= schedule[i].start < schedule[i].end <= 10^8. - * - * Solution: O(L X N x N) Where L is the number of schedules, N is the length of schedules for each employee. - * Merge all the intervals to form a single merged array, now by using this array form a result array with the intervals - * which form the free time. + *

schedule and schedule[i] are lists with lengths in range [1, 50]. 0 <= schedule[i].start < + * schedule[i].end <= 10^8. * + *

Solution: O(L X N x N) Where L is the number of schedules, N is the length of schedules for + * each employee. Merge all the intervals to form a single merged array, now by using this array + * form a result array with the intervals which form the free time. */ public class EmployeeFreeTime { - public static class Interval { - int start; - int end; - Interval() { start = 0; end = 0; } - Interval(int s, int e) { start = s; end = e; } + public static class Interval { + int start; + int end; + + Interval() { + start = 0; + end = 0; } - /** - * Main method - * @param args - */ - public static void main(String[] args) { - List> schedule = new ArrayList<>(); - List ints1 = new ArrayList<>(); - ints1.add(new Interval(45, 56)); - ints1.add(new Interval(89, 96)); + Interval(int s, int e) { + start = s; + end = e; + } + } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + List> schedule = new ArrayList<>(); + List ints1 = new ArrayList<>(); + ints1.add(new Interval(45, 56)); + ints1.add(new Interval(89, 96)); - List ints3 = new ArrayList<>(); - ints3.add(new Interval(5, 21)); - ints3.add(new Interval(57, 74)); + List ints3 = new ArrayList<>(); + ints3.add(new Interval(5, 21)); + ints3.add(new Interval(57, 74)); - schedule.add(ints1); - schedule.add(ints3); + schedule.add(ints1); + schedule.add(ints3); - List result = new EmployeeFreeTime().employeeFreeTime(schedule); - for(Interval i : result){ - System.out.println(i.start + " " + i.end); - } + List result = new EmployeeFreeTime().employeeFreeTime(schedule); + for (Interval i : result) { + System.out.println(i.start + " " + i.end); } + } - public List employeeFreeTime(List> schedule) { - if(schedule.isEmpty()) return new ArrayList<>(); - List merged = schedule.get(0); - for(int i = 1, l = schedule.size(); i < l; i++){ - List employeeInt = schedule.get(i); - for(Interval in : employeeInt){ - merged = merge(merged, in); - } - } - List result = new ArrayList<>(); - for(int i = 0, l = merged.size(); i + 1 < l; i ++){ - if(merged.get(i).end != merged.get(i + 1).start){ - result.add(new Interval(merged.get(i).end, merged.get(i + 1).start)); - } - } - return result; + public List employeeFreeTime(List> schedule) { + if (schedule.isEmpty()) return new ArrayList<>(); + List merged = schedule.get(0); + for (int i = 1, l = schedule.size(); i < l; i++) { + List employeeInt = schedule.get(i); + for (Interval in : employeeInt) { + merged = merge(merged, in); + } + } + List result = new ArrayList<>(); + for (int i = 0, l = merged.size(); i + 1 < l; i++) { + if (merged.get(i).end != merged.get(i + 1).start) { + result.add(new Interval(merged.get(i).end, merged.get(i + 1).start)); + } } + return result; + } - private List merge(List list, Interval interval){ - List result = new ArrayList<>(); - for(int i = 0, l = list.size(); i < l; i ++){ - Interval curr = list.get(i); - if(interval.start >= curr.start && interval.end <= curr.end){ - return list; - } else if(interval.start >= curr.start && interval.start <= curr.end){ - interval = new Interval(curr.start, interval.end); - } else if(interval.end >= curr.start && interval.end <= curr.end){ - interval = new Interval(interval.start, curr.end); - } else if(interval.end < curr.start){ - result.add(interval); - for(int j = i; j < l; j++){ - result.add(list.get(j)); - } - return result; - } else if(interval.start > curr.end){ - result.add(curr); - } - } + private List merge(List list, Interval interval) { + List result = new ArrayList<>(); + for (int i = 0, l = list.size(); i < l; i++) { + Interval curr = list.get(i); + if (interval.start >= curr.start && interval.end <= curr.end) { + return list; + } else if (interval.start >= curr.start && interval.start <= curr.end) { + interval = new Interval(curr.start, interval.end); + } else if (interval.end >= curr.start && interval.end <= curr.end) { + interval = new Interval(interval.start, curr.end); + } else if (interval.end < curr.start) { result.add(interval); + for (int j = i; j < l; j++) { + result.add(list.get(j)); + } return result; + } else if (interval.start > curr.end) { + result.add(curr); + } } + result.add(interval); + return result; + } } diff --git a/problems/src/array/FindTheCelebrity.java b/problems/src/array/FindTheCelebrity.java index b86db317..c18bf6c1 100644 --- a/problems/src/array/FindTheCelebrity.java +++ b/problems/src/array/FindTheCelebrity.java @@ -8,98 +8,101 @@ /** * Created by gouthamvidyapradhan on 25/11/2017. * - * Suppose you are at a party with n people (labeled from 0 to n - 1) and among them, there may exist one celebrity. - * The definition of a celebrity is that all the other n - 1 people know him/her but he/she does not know any of them. - - Now you want to find out who the celebrity is or verify that there is not one. The only thing you are allowed to do - is to ask questions like: "Hi, A. Do you know B?" to get information of whether A knows B. You need to find out the - celebrity (or verify there is not one) by asking as few questions as possible (in the asymptotic sense). - - You are given a helper function bool knows(a, b) which tells you whether A knows B. Implement a function int - findCelebrity(n), your function should minimize the number of calls to knows. - - Note: There will be exactly one celebrity if he/she is in the party. Return the celebrity's label if there is a - celebrity in the party. If there is no celebrity, return -1. + *

Suppose you are at a party with n people (labeled from 0 to n - 1) and among them, there may + * exist one celebrity. The definition of a celebrity is that all the other n - 1 people know + * him/her but he/she does not know any of them. + * + *

Now you want to find out who the celebrity is or verify that there is not one. The only thing + * you are allowed to do is to ask questions like: "Hi, A. Do you know B?" to get information of + * whether A knows B. You need to find out the celebrity (or verify there is not one) by asking as + * few questions as possible (in the asymptotic sense). + * + *

You are given a helper function bool knows(a, b) which tells you whether A knows B. Implement + * a function int findCelebrity(n), your function should minimize the number of calls to knows. + * + *

Note: There will be exactly one celebrity if he/she is in the party. Return the celebrity's + * label if there is a celebrity in the party. If there is no celebrity, return -1. */ public class FindTheCelebrity { - private static Map> map = new HashMap<>(); + private static Map> map = new HashMap<>(); - /** - * Main method - * @param args - */ - public static void main(String[] args) { - //initialize relationship - map.put(0, new HashSet<>()); - map.put(1, new HashSet<>()); - map.put(2, new HashSet<>()); - map.put(3, new HashSet<>()); - map.put(4, new HashSet<>()); - map.put(5, new HashSet<>()); - map.put(6, new HashSet<>()); - map.get(0).add(3); - map.get(0).add(1); - map.get(0).add(2); - map.get(0).add(4); - map.get(0).add(5); - map.get(0).add(6); + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + // initialize relationship + map.put(0, new HashSet<>()); + map.put(1, new HashSet<>()); + map.put(2, new HashSet<>()); + map.put(3, new HashSet<>()); + map.put(4, new HashSet<>()); + map.put(5, new HashSet<>()); + map.put(6, new HashSet<>()); + map.get(0).add(3); + map.get(0).add(1); + map.get(0).add(2); + map.get(0).add(4); + map.get(0).add(5); + map.get(0).add(6); - map.get(1).add(0); - map.get(1).add(3); - map.get(1).add(2); + map.get(1).add(0); + map.get(1).add(3); + map.get(1).add(2); - map.get(2).add(1); - map.get(2).add(3); - map.get(2).add(4); + map.get(2).add(1); + map.get(2).add(3); + map.get(2).add(4); - map.get(4).add(2); - map.get(4).add(3); - map.get(4).add(5); + map.get(4).add(2); + map.get(4).add(3); + map.get(4).add(5); - map.get(5).add(4); - map.get(5).add(3); - map.get(5).add(6); + map.get(5).add(4); + map.get(5).add(3); + map.get(5).add(6); - map.get(6).add(5); - map.get(6).add(3); - map.get(6).add(0); + map.get(6).add(5); + map.get(6).add(3); + map.get(6).add(0); - System.out.println(new FindTheCelebrity().findCelebrity(0)); - } + System.out.println(new FindTheCelebrity().findCelebrity(0)); + } - /** - * Find celebrity - * @param n - * @return - */ - public int findCelebrity(int n) { - int candidate = -1, i = 0, next = 1; - while(i < n){ - if(next >= n) break; - if(knows(i, next) && !knows(next, i)){ - i = next; - next = i + 1; - } else if((!knows(i, next) && !knows(next, i)) || (knows(i, next) && knows(next, i))){ - i = next + 1; - next = i + 1; - } else { - next++; - } - candidate = i; - } - if(candidate == -1 || candidate >= n) - return -1; - for(int j = 0; j < candidate; j ++){ - if(!knows(j, candidate) || knows(candidate, j)){ - candidate = -1; - break; - } - } - return candidate; + /** + * Find celebrity + * + * @param n + * @return + */ + public int findCelebrity(int n) { + int candidate = -1, i = 0, next = 1; + while (i < n) { + if (next >= n) break; + if (knows(i, next) && !knows(next, i)) { + i = next; + next = i + 1; + } else if ((!knows(i, next) && !knows(next, i)) || (knows(i, next) && knows(next, i))) { + i = next + 1; + next = i + 1; + } else { + next++; + } + candidate = i; } - - private boolean knows(int a, int b){ - return map.get(a).contains(b); + if (candidate == -1 || candidate >= n) return -1; + for (int j = 0; j < candidate; j++) { + if (!knows(j, candidate) || knows(candidate, j)) { + candidate = -1; + break; + } } + return candidate; + } + + private boolean knows(int a, int b) { + return map.get(a).contains(b); + } } diff --git a/problems/src/array/FirstMissingPositive.java b/problems/src/array/FirstMissingPositive.java index 034a9bc1..1e704581 100644 --- a/problems/src/array/FirstMissingPositive.java +++ b/problems/src/array/FirstMissingPositive.java @@ -1,47 +1,43 @@ package array; /** - * Created by gouthamvidyapradhan on 24/06/2017. - * Given an unsorted integer array, find the first missing positive integer. - *

- * For example, - * Given [1,2,0] return 3, - * and [3,4,-1,1] return 2. - *

- * Your algorithm should run in O(n) time and uses constant space. + * Created by gouthamvidyapradhan on 24/06/2017. Given an unsorted integer array, find the first + * missing positive integer. + * + *

For example, Given [1,2,0] return 3, and [3,4,-1,1] return 2. + * + *

Your algorithm should run in O(n) time and uses constant space. */ public class FirstMissingPositive { - private int L; + private int L; - public static void main(String[] args) throws Exception { - int[] nums = {1, 3, 5, 9}; - System.out.println(new FirstMissingPositive().firstMissingPositive(nums)); - } - - public int firstMissingPositive(int[] nums) { - L = nums.length; - for (int i = 0; i < L; i++) { - if (nums[i] > 0 && nums[i] <= L && nums[i] != i + 1) { - int v = nums[i]; - nums[i] = -1; - replace(v, nums); - } - } - - for (int i = 0; i < L; i++) { - if (nums[i] != i + 1) - return i + 1; - } + public static void main(String[] args) throws Exception { + int[] nums = {1, 3, 5, 9}; + System.out.println(new FirstMissingPositive().firstMissingPositive(nums)); + } - return L + 1; + public int firstMissingPositive(int[] nums) { + L = nums.length; + for (int i = 0; i < L; i++) { + if (nums[i] > 0 && nums[i] <= L && nums[i] != i + 1) { + int v = nums[i]; + nums[i] = -1; + replace(v, nums); + } } - private void replace(int i, int[] nums) { - if (i > 0 && i <= L && i != nums[i - 1]) { - int v = nums[i - 1]; - nums[i - 1] = i; - replace(v, nums); - } + for (int i = 0; i < L; i++) { + if (nums[i] != i + 1) return i + 1; } + return L + 1; + } + + private void replace(int i, int[] nums) { + if (i > 0 && i <= L && i != nums[i - 1]) { + int v = nums[i - 1]; + nums[i - 1] = i; + replace(v, nums); + } + } } diff --git a/problems/src/array/FruitIntoBaskets.java b/problems/src/array/FruitIntoBaskets.java index 7765f735..5a6404e8 100644 --- a/problems/src/array/FruitIntoBaskets.java +++ b/problems/src/array/FruitIntoBaskets.java @@ -3,98 +3,85 @@ import java.util.Stack; /** - * Created by gouthamvidyapradhan on 02/03/2019 - * In a row of trees, the i-th tree produces fruit with type tree[i]. + * Created by gouthamvidyapradhan on 02/03/2019 In a row of trees, the i-th tree produces fruit with + * type tree[i]. * - * You start at any tree of your choice, then repeatedly perform the following steps: + *

You start at any tree of your choice, then repeatedly perform the following steps: * - * Add one piece of fruit from this tree to your baskets. If you cannot, stop. - * Move to the next tree to the right of the current tree. If there is no tree to the right, stop. - * Note that you do not have any choice after the initial choice of starting tree: you must perform step 1, then step 2, then back to step 1, then step 2, and so on until you stop. + *

Add one piece of fruit from this tree to your baskets. If you cannot, stop. Move to the next + * tree to the right of the current tree. If there is no tree to the right, stop. Note that you do + * not have any choice after the initial choice of starting tree: you must perform step 1, then step + * 2, then back to step 1, then step 2, and so on until you stop. * - * You have two baskets, and each basket can carry any quantity of fruit, but you want each basket to only carry one type of fruit each. + *

You have two baskets, and each basket can carry any quantity of fruit, but you want each + * basket to only carry one type of fruit each. * - * What is the total amount of fruit you can collect with this procedure? + *

What is the total amount of fruit you can collect with this procedure? * + *

Example 1: * + *

Input: [1,2,1] Output: 3 Explanation: We can collect [1,2,1]. Example 2: * - * Example 1: + *

Input: [0,1,2,2] Output: 3 Explanation: We can collect [1,2,2]. If we started at the first + * tree, we would only collect [0, 1]. Example 3: * - * Input: [1,2,1] - * Output: 3 - * Explanation: We can collect [1,2,1]. - * Example 2: + *

Input: [1,2,3,2,2] Output: 4 Explanation: We can collect [2,3,2,2]. If we started at the first + * tree, we would only collect [1, 2]. Example 4: * - * Input: [0,1,2,2] - * Output: 3 - * Explanation: We can collect [1,2,2]. - * If we started at the first tree, we would only collect [0, 1]. - * Example 3: + *

Input: [3,3,3,1,2,1,1,2,3,3,4] Output: 5 Explanation: We can collect [1,2,1,1,2]. If we + * started at the first tree or the eighth tree, we would only collect 4 fruits. * - * Input: [1,2,3,2,2] - * Output: 4 - * Explanation: We can collect [2,3,2,2]. - * If we started at the first tree, we would only collect [1, 2]. - * Example 4: - * - * Input: [3,3,3,1,2,1,1,2,3,3,4] - * Output: 5 - * Explanation: We can collect [1,2,1,1,2]. - * If we started at the first tree or the eighth tree, we would only collect 4 fruits. - * - * - * Note: - * - * 1 <= tree.length <= 40000 - * 0 <= tree[i] < tree.length + *

Note: * + *

1 <= tree.length <= 40000 0 <= tree[i] < tree.length */ public class FruitIntoBaskets { - private int count = 0; - private int max = 0; - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int[] trees = {1, 0, 3, 4, 3}; - System.out.println(new FruitIntoBaskets().totalFruit(trees)); - } + private int count = 0; + private int max = 0; + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[] trees = {1, 0, 3, 4, 3}; + System.out.println(new FruitIntoBaskets().totalFruit(trees)); + } - public int totalFruit(int[] tree) { - int t1 = -1, t2 = -1; - Stack stack = new Stack<>(); - for(int i : tree){ - if(i == t1 || i == t2){ - countAndMax(stack, i); - } else { - if(t1 == -1){ - t1 = i; - countAndMax(stack, i); - } else if(t2 == -1){ - t2 = i; - countAndMax(stack, i); - } else{ - Stack temp = new Stack<>(); - count = 0; - t1 = stack.pop(); - countAndMax(temp, t1); - while(!stack.isEmpty() && stack.peek() == t1){ - countAndMax(temp, stack.pop()); - } - t2 = i; - stack = temp; - countAndMax(stack, i); - } - } + public int totalFruit(int[] tree) { + int t1 = -1, t2 = -1; + Stack stack = new Stack<>(); + for (int i : tree) { + if (i == t1 || i == t2) { + countAndMax(stack, i); + } else { + if (t1 == -1) { + t1 = i; + countAndMax(stack, i); + } else if (t2 == -1) { + t2 = i; + countAndMax(stack, i); + } else { + Stack temp = new Stack<>(); + count = 0; + t1 = stack.pop(); + countAndMax(temp, t1); + while (!stack.isEmpty() && stack.peek() == t1) { + countAndMax(temp, stack.pop()); + } + t2 = i; + stack = temp; + countAndMax(stack, i); } - return max; + } } + return max; + } - private void countAndMax(Stack stack, int i){ - count++; - stack.push(i); - max = Math.max(max, count); - } + private void countAndMax(Stack stack, int i) { + count++; + stack.push(i); + max = Math.max(max, count); + } } diff --git a/problems/src/array/HIndex.java b/problems/src/array/HIndex.java index a3577600..2cc1dad3 100644 --- a/problems/src/array/HIndex.java +++ b/problems/src/array/HIndex.java @@ -1,56 +1,55 @@ package array; /** - * Created by gouthamvidyapradhan on 12/12/2017. - * Given an array of citations (each citation is a non-negative integer) of a researcher, write a function to - * compute the researcher's h-index. - - According to the definition of h-index on Wikipedia: "A scientist has index h if h of his/her N papers have at - least h citations each, and the other N − h papers have no more than h citations each." - - For example, given citations = [3, 0, 6, 1, 5], which means the researcher has 5 papers in total and each of them - had received 3, 0, 6, 1, 5 citations respectively. Since the researcher has 3 papers with at least 3 citations each - and the remaining two with no more than 3 citations each, his h-index is 3. - - Note: If there are several possible values for h, the maximum one is taken as the h-index. - - Solution O(n) Replace all the citations which are greater than n with n, the result will not change with this - operation. - Maintain a count array with count of each citations. Sum up all the counts from n -> 0 and store this in a array S. - Value in array index Si is number of papers having citations at least i. - - The first value at index i, from right to left in array S which has i <= Si is the answer. - - + * Created by gouthamvidyapradhan on 12/12/2017. Given an array of citations (each citation is a + * non-negative integer) of a researcher, write a function to compute the researcher's h-index. + * + *

According to the definition of h-index on Wikipedia: "A scientist has index h if h of his/her + * N papers have at least h citations each, and the other N − h papers have no more than h citations + * each." + * + *

For example, given citations = [3, 0, 6, 1, 5], which means the researcher has 5 papers in + * total and each of them had received 3, 0, 6, 1, 5 citations respectively. Since the researcher + * has 3 papers with at least 3 citations each and the remaining two with no more than 3 citations + * each, his h-index is 3. + * + *

Note: If there are several possible values for h, the maximum one is taken as the h-index. + * + *

Solution O(n) Replace all the citations which are greater than n with n, the result will not + * change with this operation. Maintain a count array with count of each citations. Sum up all the + * counts from n -> 0 and store this in a array S. Value in array index Si is number of papers + * having citations at least i. + * + *

The first value at index i, from right to left in array S which has i <= Si is the answer. */ public class HIndex { - public static void main(String[] args) throws Exception{ - int[] A = {3, 0, 6, 1, 5}; - System.out.println(new HIndex().hIndex(A)); + public static void main(String[] args) throws Exception { + int[] A = {3, 0, 6, 1, 5}; + System.out.println(new HIndex().hIndex(A)); + } + + public int hIndex(int[] citations) { + int n = citations.length; + int[] count = new int[n + 1]; + int[] S = new int[n + 1]; + for (int i = 0; i < citations.length; i++) { + if (citations[i] > n) { + citations[i] = n; + } } - - public int hIndex(int[] citations) { - int n = citations.length; - int[] count = new int[n + 1]; - int[] S = new int[n + 1]; - for(int i = 0; i < citations.length; i ++){ - if(citations[i] > n){ - citations[i] = n; - } - } - for (int citation : citations) { - count[citation]++; - } - S[n] = count[n]; - for(int i = n - 1; i >= 0; i --){ - S[i] = count[i] + S[i + 1]; - } - for(int i = n; i >= 0; i--){ - if(i <= S[i]){ - return i; - } - } - return 0; + for (int citation : citations) { + count[citation]++; + } + S[n] = count[n]; + for (int i = n - 1; i >= 0; i--) { + S[i] = count[i] + S[i + 1]; + } + for (int i = n; i >= 0; i--) { + if (i <= S[i]) { + return i; + } } + return 0; + } } diff --git a/problems/src/array/ImageSmoother.java b/problems/src/array/ImageSmoother.java index d37f0aa9..5c8894f1 100644 --- a/problems/src/array/ImageSmoother.java +++ b/problems/src/array/ImageSmoother.java @@ -1,57 +1,43 @@ package array; /** - * Created by gouthamvidyapradhan on 17/02/2018. - * * Given a 2D integer matrix M representing the gray scale of an image, you need to design a smoother to make the - * gray scale of each cell becomes the average gray scale (rounding down) of all the 8 surrounding cells and itself. - * If a cell has less than 8 surrounding cells, then use as many as you can. - - Example 1: - Input: - [[1,1,1], - [1,0,1], - [1,1,1]] - Output: - [[0, 0, 0], - [0, 0, 0], - [0, 0, 0]] - Explanation: - For the point (0,0), (0,2), (2,0), (2,2): floor(3/4) = floor(0.75) = 0 - For the point (0,1), (1,0), (1,2), (2,1): floor(5/6) = floor(0.83333333) = 0 - For the point (1,1): floor(8/9) = floor(0.88888889) = 0 - Note: - The value in the given matrix is in the range of [0, 255]. - The length and width of the given matrix are in the range of [1, 150]. + * Created by gouthamvidyapradhan on 17/02/2018. * Given a 2D integer matrix M representing the gray + * scale of an image, you need to design a smoother to make the gray scale of each cell becomes the + * average gray scale (rounding down) of all the 8 surrounding cells and itself. If a cell has less + * than 8 surrounding cells, then use as many as you can. + * + *

Example 1: Input: [[1,1,1], [1,0,1], [1,1,1]] Output: [[0, 0, 0], [0, 0, 0], [0, 0, 0]] + * Explanation: For the point (0,0), (0,2), (2,0), (2,2): floor(3/4) = floor(0.75) = 0 For the point + * (0,1), (1,0), (1,2), (2,1): floor(5/6) = floor(0.83333333) = 0 For the point (1,1): floor(8/9) = + * floor(0.88888889) = 0 Note: The value in the given matrix is in the range of [0, 255]. The length + * and width of the given matrix are in the range of [1, 150]. */ - public class ImageSmoother { - int[] R = {1, -1, 0, 0, 1, -1, 1, -1}; - int[] C = {0, 0, -1, 1, 1, 1, -1, -1}; - public static void main(String[] args) throws Exception{ + int[] R = {1, -1, 0, 0, 1, -1, 1, -1}; + int[] C = {0, 0, -1, 1, 1, 1, -1, -1}; - } + public static void main(String[] args) throws Exception {} - public int[][] imageSmoother(int[][] M) { - int[][] result = new int[M.length][M[0].length]; - for(int i = 0; i < M.length; i ++){ - for(int j = 0; j < M[0].length; j ++){ - int numCount = 0; - int totalCount = 1; - for(int k = 0; k < 8; k++){ - int newR = i + R[k]; - int newC = j + C[k]; - if(newR >= 0 && newC >= 0 && newR < M.length && newC < M[0].length){ - if(M[newR][newC] > 0){ - numCount += M[newR][newC]; - } - totalCount++; - } - } - if(M[i][j] == 1) numCount++; - result[i][j] = numCount / totalCount; + public int[][] imageSmoother(int[][] M) { + int[][] result = new int[M.length][M[0].length]; + for (int i = 0; i < M.length; i++) { + for (int j = 0; j < M[0].length; j++) { + int numCount = 0; + int totalCount = 1; + for (int k = 0; k < 8; k++) { + int newR = i + R[k]; + int newC = j + C[k]; + if (newR >= 0 && newC >= 0 && newR < M.length && newC < M[0].length) { + if (M[newR][newC] > 0) { + numCount += M[newR][newC]; } + totalCount++; + } } - return result; + if (M[i][j] == 1) numCount++; + result[i][j] = numCount / totalCount; + } } - + return result; + } } diff --git a/problems/src/array/IncreasingTripletSubsequence.java b/problems/src/array/IncreasingTripletSubsequence.java index 27970ca2..23f258c1 100644 --- a/problems/src/array/IncreasingTripletSubsequence.java +++ b/problems/src/array/IncreasingTripletSubsequence.java @@ -3,46 +3,42 @@ import java.util.Arrays; /** - * Created by gouthamvidyapradhan on 17/12/2017. - * Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the array. - - Formally the function should: - Return true if there exists i, j, k - such that arr[i] < arr[j] < arr[k] given 0 ≤ i < j < k ≤ n-1 else return false. - Your algorithm should run in O(n) time complexity and O(1) space complexity. - - Examples: - Given [1, 2, 3, 4, 5], - return true. - - Given [5, 4, 3, 2, 1], - return false. + * Created by gouthamvidyapradhan on 17/12/2017. Given an unsorted array return whether an + * increasing subsequence of length 3 exists or not in the array. + * + *

Formally the function should: Return true if there exists i, j, k such that arr[i] < arr[j] < + * arr[k] given 0 ≤ i < j < k ≤ n-1 else return false. Your algorithm should run in O(n) time + * complexity and O(1) space complexity. + * + *

Examples: Given [1, 2, 3, 4, 5], return true. + * + *

Given [5, 4, 3, 2, 1], return false. */ public class IncreasingTripletSubsequence { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1, 2, 3, 4, 5}; - System.out.println(new IncreasingTripletSubsequence().increasingTriplet(A)); - } - - public boolean increasingTriplet(int[] nums) { - int[] A = new int[3]; - Arrays.fill(A, Integer.MAX_VALUE); - for (int num : nums) { - if (num < A[0]) { - A[0] = num; - } else if (num < A[1] && num > A[0]) { - A[1] = num; - } else if (num < A[2] && num > A[1]) { - return true; - } - } - return false; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 2, 3, 4, 5}; + System.out.println(new IncreasingTripletSubsequence().increasingTriplet(A)); + } + + public boolean increasingTriplet(int[] nums) { + int[] A = new int[3]; + Arrays.fill(A, Integer.MAX_VALUE); + for (int num : nums) { + if (num < A[0]) { + A[0] = num; + } else if (num < A[1] && num > A[0]) { + A[1] = num; + } else if (num < A[2] && num > A[1]) { + return true; + } } + return false; + } } - diff --git a/problems/src/array/InsertInterval.java b/problems/src/array/InsertInterval.java index cd37f6f8..5202ade0 100644 --- a/problems/src/array/InsertInterval.java +++ b/problems/src/array/InsertInterval.java @@ -5,83 +5,92 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 15/12/2017. - * 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. - - Example 1: - Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9]. - - Example 2: - Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16]. - - This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10]. - - Solution: O(n): Iterate through each interval and check for each overlapping case + * Created by gouthamvidyapradhan on 15/12/2017. 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. + * + *

Example 1: Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9]. + * + *

Example 2: Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as + * [1,2],[3,10],[12,16]. + * + *

This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10]. + * + *

Solution: O(n): Iterate through each interval and check for each overlapping case */ public class InsertInterval { - public static class Interval { - int start; - int end; - Interval() { start = 0; end = 0; } - Interval(int s, int e) { start = s; end = e; } + public static class Interval { + int start; + int end; + + Interval() { + start = 0; + end = 0; } - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - Interval i1 = new Interval(1, 2); - Interval i2 = new Interval(3, 5); - Interval i3 = new Interval(6, 7); - Interval i4 = new Interval(8, 10); - Interval i5 = new Interval(12, 16); - List list = Arrays.asList(i1, i2, i3, i4, i5); - List result = new InsertInterval().insert(list, new Interval(2, 5)); - result.stream().map(x -> x.start + " " + x.end).forEach(System.out::println); + + Interval(int s, int e) { + start = s; + end = e; } + } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + Interval i1 = new Interval(1, 2); + Interval i2 = new Interval(3, 5); + Interval i3 = new Interval(6, 7); + Interval i4 = new Interval(8, 10); + Interval i5 = new Interval(12, 16); + List list = Arrays.asList(i1, i2, i3, i4, i5); + List result = new InsertInterval().insert(list, new Interval(2, 5)); + result.stream().map(x -> x.start + " " + x.end).forEach(System.out::println); + } - public List insert(List intervals, Interval newInterval) { - List result = new ArrayList<>(); - for(int i = 0, l = intervals.size(); i < l; i ++){ - Interval curr = intervals.get(i); - if(newInterval.start >= curr.start && newInterval.end <= curr.end){ - insertRest(intervals, result, i); - return result; //easy case - } else if(newInterval.start < curr.start && newInterval.end > curr.end){ - newInterval = new Interval(newInterval.start, newInterval.end); - //merge and continue - } else if(newInterval.start >= curr.start && newInterval.start <= curr.end - && newInterval.end > curr.end){ - newInterval = new Interval(curr.start, newInterval.end); - //merge and continue - } else if(newInterval.start < curr.start && newInterval.end >= curr.start - && newInterval.end <= curr.end){ - Interval newI = new Interval(newInterval.start, curr.end); - result.add(newI); - insertRest(intervals, result, i + 1); - return result; - } else if(newInterval.start > curr.end){ - result.add(curr); - } else { - result.add(newInterval); - insertRest(intervals, result, i); - return result; - } - } + public List insert(List intervals, Interval newInterval) { + List result = new ArrayList<>(); + for (int i = 0, l = intervals.size(); i < l; i++) { + Interval curr = intervals.get(i); + if (newInterval.start >= curr.start && newInterval.end <= curr.end) { + insertRest(intervals, result, i); + return result; // easy case + } else if (newInterval.start < curr.start && newInterval.end > curr.end) { + newInterval = new Interval(newInterval.start, newInterval.end); + // merge and continue + } else if (newInterval.start >= curr.start + && newInterval.start <= curr.end + && newInterval.end > curr.end) { + newInterval = new Interval(curr.start, newInterval.end); + // merge and continue + } else if (newInterval.start < curr.start + && newInterval.end >= curr.start + && newInterval.end <= curr.end) { + Interval newI = new Interval(newInterval.start, curr.end); + result.add(newI); + insertRest(intervals, result, i + 1); + return result; + } else if (newInterval.start > curr.end) { + result.add(curr); + } else { result.add(newInterval); + insertRest(intervals, result, i); return result; + } } + result.add(newInterval); + return result; + } - private void insertRest(List intervals, List result, int i){ - int l = intervals.size(); - while(i < l){ - result.add(intervals.get(i)); - i++; - } + private void insertRest(List intervals, List result, int i) { + int l = intervals.size(); + while (i < l) { + result.add(intervals.get(i)); + i++; } - + } } diff --git a/problems/src/array/KEmptySlots.java b/problems/src/array/KEmptySlots.java index 24f3bf0d..2055612f 100644 --- a/problems/src/array/KEmptySlots.java +++ b/problems/src/array/KEmptySlots.java @@ -3,68 +3,59 @@ import java.util.TreeSet; /** - * Created by gouthamvidyapradhan on 01/01/2018. - * There is a garden with N slots. In each slot, there is a flower. The N flowers will bloom one by one in N days. - * In each day, there will be exactly one flower blooming and it will be in the status of blooming since then. - - Given an array flowers consists of number from 1 to N. Each number in the array represents the place where the - flower will open in that day. - - For example, flowers[i] = x means that the unique flower that blooms at day i will be at position x, where i and x - will be in the range from 1 to N. - - Also given an integer k, you need to output in which day there exists two flowers in the status of blooming, and - also the number of flowers between them is k and these flowers are not blooming. - - If there isn't such day, output -1. - - Example 1: - Input: - flowers: [1,3,2] - k: 1 - Output: 2 - Explanation: In the second day, the first and the third flower have become blooming. - Example 2: - Input: - flowers: [1,2,3] - k: 1 - Output: -1 - Note: - The given array will be in the range [1, 20000]. - - Solution: O(n log n). Maintain a tree-set of bloomed flowers and for every element in the array - find the upper and lower bound bloomed flowers and calculate their difference with the current. If - the difference is k return the current day, if none found then return -1 - + * Created by gouthamvidyapradhan on 01/01/2018. There is a garden with N slots. In each slot, there + * is a flower. The N flowers will bloom one by one in N days. In each day, there will be exactly + * one flower blooming and it will be in the status of blooming since then. + * + *

Given an array flowers consists of number from 1 to N. Each number in the array represents the + * place where the flower will open in that day. + * + *

For example, flowers[i] = x means that the unique flower that blooms at day i will be at + * position x, where i and x will be in the range from 1 to N. + * + *

Also given an integer k, you need to output in which day there exists two flowers in the + * status of blooming, and also the number of flowers between them is k and these flowers are not + * blooming. + * + *

If there isn't such day, output -1. + * + *

Example 1: Input: flowers: [1,3,2] k: 1 Output: 2 Explanation: In the second day, the first + * and the third flower have become blooming. Example 2: Input: flowers: [1,2,3] k: 1 Output: -1 + * Note: The given array will be in the range [1, 20000]. + * + *

Solution: O(n log n). Maintain a tree-set of bloomed flowers and for every element in the + * array find the upper and lower bound bloomed flowers and calculate their difference with the + * current. If the difference is k return the current day, if none found then return -1 */ public class KEmptySlots { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1, 3, 2}; - System.out.println(new KEmptySlots().kEmptySlots(A, 2)); - } - - public int kEmptySlots(int[] flowers, int k) { - TreeSet set = new TreeSet<>(); - for(int i = 0; i < flowers.length; i ++){ - Integer lowerBound = set.floor(flowers[i]); - Integer upperBound = set.ceiling(flowers[i]); - if(lowerBound != null){ - if((Math.abs(flowers[i] - lowerBound) + 1) == k){ - return i + 1; - } - } if(upperBound != null){ - if((Math.abs(flowers[i] - upperBound) + 1) == k){ - return i + 1; - } - } - set.add(flowers[i]); + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 3, 2}; + System.out.println(new KEmptySlots().kEmptySlots(A, 2)); + } + + public int kEmptySlots(int[] flowers, int k) { + TreeSet set = new TreeSet<>(); + for (int i = 0; i < flowers.length; i++) { + Integer lowerBound = set.floor(flowers[i]); + Integer upperBound = set.ceiling(flowers[i]); + if (lowerBound != null) { + if ((Math.abs(flowers[i] - lowerBound) + 1) == k) { + return i + 1; } - return -1; + } + if (upperBound != null) { + if ((Math.abs(flowers[i] - upperBound) + 1) == k) { + return i + 1; + } + } + set.add(flowers[i]); } - + return -1; + } } diff --git a/problems/src/array/LargestNumberAtLeastTwice.java b/problems/src/array/LargestNumberAtLeastTwice.java index fdb7395d..664ace41 100644 --- a/problems/src/array/LargestNumberAtLeastTwice.java +++ b/problems/src/array/LargestNumberAtLeastTwice.java @@ -1,59 +1,54 @@ package array; /** - * Created by gouthamvidyapradhan on 09/02/2018. - * In a given integer array nums, there is always exactly one largest element. - - Find whether the largest element in the array is at least twice as much as every other number in the array. - - If it is, return the index of the largest element, otherwise return -1. - - Example 1: - - Input: nums = [3, 6, 1, 0] - Output: 1 - Explanation: 6 is the largest integer, and for every other number in the array x, - 6 is more than twice as big as x. The index of value 6 is 1, so we return 1. - - - Example 2: - - Input: nums = [1, 2, 3, 4] - Output: -1 - Explanation: 4 isn't at least as big as twice the value of 3, so we return -1. - - - Note: - - nums will have a length in the range [1, 50]. - Every nums[i] will be an integer in the range [0, 99]. + * Created by gouthamvidyapradhan on 09/02/2018. In a given integer array nums, there is always + * exactly one largest element. + * + *

Find whether the largest element in the array is at least twice as much as every other number + * in the array. + * + *

If it is, return the index of the largest element, otherwise return -1. + * + *

Example 1: + * + *

Input: nums = [3, 6, 1, 0] Output: 1 Explanation: 6 is the largest integer, and for every + * other number in the array x, 6 is more than twice as big as x. The index of value 6 is 1, so we + * return 1. + * + *

Example 2: + * + *

Input: nums = [1, 2, 3, 4] Output: -1 Explanation: 4 isn't at least as big as twice the value + * of 3, so we return -1. + * + *

Note: + * + *

nums will have a length in the range [1, 50]. Every nums[i] will be an integer in the range + * [0, 99]. */ public class LargestNumberAtLeastTwice { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception {} + + public int dominantIndex(int[] nums) { + int index = 0, max = Integer.MIN_VALUE; + for (int i = 0; i < nums.length; i++) { + if (nums[i] > max) { + max = nums[i]; + index = i; + } } - - public int dominantIndex(int[] nums) { - int index = 0, max = Integer.MIN_VALUE; - for(int i = 0; i < nums.length; i ++){ - if(nums[i] > max){ - max = nums[i]; - index = i; - } - } - for(int i = 0; i < nums.length; i ++){ - if(i == index) continue; - if(((long)nums[i] * 2) > max){ - return -1; - } - } - return index; + for (int i = 0; i < nums.length; i++) { + if (i == index) continue; + if (((long) nums[i] * 2) > max) { + return -1; + } } - + return index; + } } diff --git a/problems/src/array/LongestIncreasingSubsequence.java b/problems/src/array/LongestIncreasingSubsequence.java index 39e5e2f0..9f7a7e2f 100644 --- a/problems/src/array/LongestIncreasingSubsequence.java +++ b/problems/src/array/LongestIncreasingSubsequence.java @@ -3,46 +3,44 @@ /** * Created by gouthamvidyapradhan on 03/12/2017. * - * Given an unsorted array of integers, find the length of longest continuous increasing subsequence (subarray). - - Example 1: - Input: [1,3,5,4,7] - Output: 3 - Explanation: The longest continuous increasing subsequence is [1,3,5], its length is 3. - Even though [1,3,5,7] is also an increasing subsequence, it's not a continuous one where 5 and 7 are separated by 4. - Example 2: - Input: [2,2,2,2,2] - Output: 1 - Explanation: The longest continuous increasing subsequence is [2], its length is 1. - Note: Length of the array will not exceed 10,000. + *

Given an unsorted array of integers, find the length of longest continuous increasing + * subsequence (subarray). + * + *

Example 1: Input: [1,3,5,4,7] Output: 3 Explanation: The longest continuous increasing + * subsequence is [1,3,5], its length is 3. Even though [1,3,5,7] is also an increasing subsequence, + * it's not a continuous one where 5 and 7 are separated by 4. Example 2: Input: [2,2,2,2,2] Output: + * 1 Explanation: The longest continuous increasing subsequence is [2], its length is 1. Note: + * Length of the array will not exceed 10,000. */ public class LongestIncreasingSubsequence { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1,3,5,4,7}; - System.out.println(new LongestIncreasingSubsequence().findLengthOfLCIS(A)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 3, 5, 4, 7}; + System.out.println(new LongestIncreasingSubsequence().findLengthOfLCIS(A)); + } - public int findLengthOfLCIS(int[] nums) { - int max = 1, count = 1; - if(nums.length == 1) return max; - if(nums.length == 0) return 0; - for(int i = 0, j = i + 1; j < nums.length;){ - if(nums[j] > nums[i]){ - count++; - i++; j++; - } else { - max = Math.max(max, count); - count = 0; - i = j; - j = i + 1; - } - } - return max; + public int findLengthOfLCIS(int[] nums) { + int max = 1, count = 1; + if (nums.length == 1) return max; + if (nums.length == 0) return 0; + for (int i = 0, j = i + 1; j < nums.length; ) { + if (nums[j] > nums[i]) { + count++; + i++; + j++; + } else { + max = Math.max(max, count); + count = 0; + i = j; + j = i + 1; + } } + return max; + } } diff --git a/problems/src/array/MaxProductOfThreeNumbers.java b/problems/src/array/MaxProductOfThreeNumbers.java index a61b5abe..0658073c 100644 --- a/problems/src/array/MaxProductOfThreeNumbers.java +++ b/problems/src/array/MaxProductOfThreeNumbers.java @@ -3,30 +3,23 @@ import java.util.Arrays; /** - * Created by gouthamvidyapradhan on 27/06/2017. - * Given an integer array, find three numbers whose product is maximum and output the maximum product. - *

- * Example 1: - * Input: [1,2,3] - * Output: 6 - * Example 2: - * Input: [1,2,3,4] - * Output: 24 - * Note: - * The length of the given array will be in range [3,104] and all elements are in the range [-1000, 1000]. + * Created by gouthamvidyapradhan on 27/06/2017. Given an integer array, find three numbers whose + * product is maximum and output the maximum product. + * + *

Example 1: Input: [1,2,3] Output: 6 Example 2: Input: [1,2,3,4] Output: 24 Note: The length of + * the given array will be in range [3,104] and all elements are in the range [-1000, 1000]. * Multiplication of any three numbers in the input won't exceed the range of 32-bit signed integer. */ public class MaxProductOfThreeNumbers { - public static void main(String[] args) { - int[] A = {1, 2, 3}; - System.out.println(new MaxProductOfThreeNumbers().maximumProduct(A)); - } - - public int maximumProduct(int[] nums) { - Arrays.sort(nums); - int prod1 = nums[nums.length - 1] * nums[nums.length - 2] * nums[nums.length - 3]; - int prod2 = nums[nums.length - 1] * nums[0] * nums[1]; - return prod1 > prod2 ? prod1 : prod2; - } + public static void main(String[] args) { + int[] A = {1, 2, 3}; + System.out.println(new MaxProductOfThreeNumbers().maximumProduct(A)); + } + public int maximumProduct(int[] nums) { + Arrays.sort(nums); + int prod1 = nums[nums.length - 1] * nums[nums.length - 2] * nums[nums.length - 3]; + int prod2 = nums[nums.length - 1] * nums[0] * nums[1]; + return prod1 > prod2 ? prod1 : prod2; + } } diff --git a/problems/src/array/MaximumSwap.java b/problems/src/array/MaximumSwap.java index 3351fd08..df8df20e 100644 --- a/problems/src/array/MaximumSwap.java +++ b/problems/src/array/MaximumSwap.java @@ -1,55 +1,46 @@ package array; /** - * Created by gouthamvidyapradhan on 10/12/2017. - * Given a non-negative integer, you could swap two digits at most once to get the maximum valued number. Return the - * maximum valued number you could get. - - Example 1: - Input: 2736 - Output: 7236 - Explanation: Swap the number 2 and the number 7. - Example 2: - Input: 9973 - Output: 9973 - Explanation: No swap. - Note: - The given number is in the range [0, 108] - - Solution O(n): Create a array of digit index. Iterate through the digits starting from left and in each iteration - check if there is any digit which is greater than the current digit and appearing after the current index, if found - then swap and return the new integer. + * Created by gouthamvidyapradhan on 10/12/2017. Given a non-negative integer, you could swap two + * digits at most once to get the maximum valued number. Return the maximum valued number you could + * get. + * + *

Example 1: Input: 2736 Output: 7236 Explanation: Swap the number 2 and the number 7. Example + * 2: Input: 9973 Output: 9973 Explanation: No swap. Note: The given number is in the range [0, 108] + * + *

Solution O(n): Create a array of digit index. Iterate through the digits starting from left + * and in each iteration check if there is any digit which is greater than the current digit and + * appearing after the current index, if found then swap and return the new integer. */ public class MaximumSwap { - public static void main(String[] args) throws Exception{ - System.out.println(new MaximumSwap().maximumSwap(2736)); - } + public static void main(String[] args) throws Exception { + System.out.println(new MaximumSwap().maximumSwap(2736)); + } - public int maximumSwap(int num) { - int[] D = new int[10]; - char[] A = String.valueOf(num).toCharArray(); - for(int i = 0; i < A.length; i ++){ - D[A[i] - '0'] = i; - } - - boolean found = false; + public int maximumSwap(int num) { + int[] D = new int[10]; + char[] A = String.valueOf(num).toCharArray(); + for (int i = 0; i < A.length; i++) { + D[A[i] - '0'] = i; + } - for(int i = 0; i < A.length; i ++){ - int digit = A[i] - '0'; - for(int j = 9; j > digit; j--){ - if(D[j] > i){ - char temp = A[i]; - A[i] = (char)(j + '0'); - A[D[j]] = temp; - found = true; - break; - } - } - if(found) break; + boolean found = false; + + for (int i = 0; i < A.length; i++) { + int digit = A[i] - '0'; + for (int j = 9; j > digit; j--) { + if (D[j] > i) { + char temp = A[i]; + A[i] = (char) (j + '0'); + A[D[j]] = temp; + found = true; + break; } - - return Integer.parseInt(String.valueOf(A)); + } + if (found) break; } + return Integer.parseInt(String.valueOf(A)); + } } diff --git a/problems/src/array/MeetingRooms.java b/problems/src/array/MeetingRooms.java index e9a48074..ee7d2dd8 100644 --- a/problems/src/array/MeetingRooms.java +++ b/problems/src/array/MeetingRooms.java @@ -3,41 +3,46 @@ import java.util.Arrays; /** - * Created by gouthamvidyapradhan on 27/11/2017. - * Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), determine if a person could attend all meetings. - - For example, - Given [[0, 30],[5, 10],[15, 20]], - return false. - - Solution: Sort the interval based on the start interval. Then, for every interval check if the previous interval - ends before the start of the current interval. + * Created by gouthamvidyapradhan on 27/11/2017. Given an array of meeting time intervals consisting + * of start and end times [[s1,e1],[s2,e2],...] (si < ei), determine if a person could attend all + * meetings. + * + *

For example, Given [[0, 30],[5, 10],[15, 20]], return false. + * + *

Solution: Sort the interval based on the start interval. Then, for every interval check if the + * previous interval ends before the start of the current interval. */ public class MeetingRooms { - public static class Interval { - int start; - int end; - Interval() { start = 0; end = 0; } - Interval(int s, int e) { start = s; end = e; } - } - - public static void main(String[] args) throws Exception{ - Interval i1 = new Interval(0, 30); - Interval i2 = new Interval(5, 10); - Interval i3 = new Interval(15, 20); - Interval[] intervals = {i1, i2, i3}; + public static class Interval { + int start; + int end; - System.out.println(new MeetingRooms().canAttendMeetings(intervals)); + Interval() { + start = 0; + end = 0; } - public boolean canAttendMeetings(Interval[] intervals) { - Arrays.sort(intervals, (a, b) -> Integer.compare(a.start, b.start)); - for(int i = 1; i < intervals.length; i ++){ - if(intervals[i].start < intervals[i - 1].end) - return false; - } - return true; + Interval(int s, int e) { + start = s; + end = e; } + } + public static void main(String[] args) throws Exception { + Interval i1 = new Interval(0, 30); + Interval i2 = new Interval(5, 10); + Interval i3 = new Interval(15, 20); + Interval[] intervals = {i1, i2, i3}; + + System.out.println(new MeetingRooms().canAttendMeetings(intervals)); + } + + public boolean canAttendMeetings(Interval[] intervals) { + Arrays.sort(intervals, (a, b) -> Integer.compare(a.start, b.start)); + for (int i = 1; i < intervals.length; i++) { + if (intervals[i].start < intervals[i - 1].end) return false; + } + return true; + } } diff --git a/problems/src/array/MergeIntervals.java b/problems/src/array/MergeIntervals.java index e16e1c56..c8638b32 100644 --- a/problems/src/array/MergeIntervals.java +++ b/problems/src/array/MergeIntervals.java @@ -6,60 +6,57 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 13/06/2017. - * Given a collection of intervals, merge all overlapping intervals. - *

- * For example, - * Given [1,3],[2,6],[8,10],[15,18], - * return [1,6],[8,10],[15,18]. - *

- * Solution: O(N log N) where N is the number of intervals - * 1. Sort the intervals based on start index - * 2. Mark the first interval as the current interval - * 3. For every ith interval starting 1 -> N, if the ith interval overlaps with the current interval then create a new - * current interval. Else, add the current interval to result set and begin a new current interval. + * Created by gouthamvidyapradhan on 13/06/2017. Given a collection of intervals, merge all + * overlapping intervals. + * + *

For example, Given [1,3],[2,6],[8,10],[15,18], return [1,6],[8,10],[15,18]. + * + *

Solution: O(N log N) where N is the number of intervals 1. Sort the intervals based on start + * index 2. Mark the first interval as the current interval 3. For every ith interval starting 1 -> + * N, if the ith interval overlaps with the current interval then create a new current interval. + * Else, add the current interval to result set and begin a new current interval. */ public class MergeIntervals { - public static class Interval { - int start; - int end; + public static class Interval { + int start; + int end; - Interval() { - start = 0; - end = 0; - } - - Interval(int s, int e) { - start = s; - end = e; - } + Interval() { + start = 0; + end = 0; } - public static void main(String[] args) throws Exception { - Interval i1 = new Interval(1, 2); - Interval i2 = new Interval(3, 4); - Interval i3 = new Interval(5, 6); - Interval i4 = new Interval(1, 10); - List result = new MergeIntervals().merge(Arrays.asList(i1, i2, i3, i4)); - result.forEach((I) -> System.out.println(I.start + " " + I.end)); + Interval(int s, int e) { + start = s; + end = e; } + } + + public static void main(String[] args) throws Exception { + Interval i1 = new Interval(1, 2); + Interval i2 = new Interval(3, 4); + Interval i3 = new Interval(5, 6); + Interval i4 = new Interval(1, 10); + List result = new MergeIntervals().merge(Arrays.asList(i1, i2, i3, i4)); + result.forEach((I) -> System.out.println(I.start + " " + I.end)); + } - public List merge(List intervals) { - if (intervals.isEmpty()) return new ArrayList<>(); - Collections.sort(intervals, (o1, o2) -> Integer.compare(o1.start, o2.start)); - List result = new ArrayList<>(); - Interval curr = intervals.get(0); - for (int i = 1, l = intervals.size(); i < l; i++) { - Interval I = intervals.get(i); - if (I.start >= curr.start && I.start <= curr.end) { //check if the new interval overlaps with the current - curr.end = curr.end > I.end ? curr.end : I.end; - } else { - result.add(curr); - curr = I; - } - } + public List merge(List intervals) { + if (intervals.isEmpty()) return new ArrayList<>(); + Collections.sort(intervals, (o1, o2) -> Integer.compare(o1.start, o2.start)); + List result = new ArrayList<>(); + Interval curr = intervals.get(0); + for (int i = 1, l = intervals.size(); i < l; i++) { + Interval I = intervals.get(i); + if (I.start >= curr.start + && I.start <= curr.end) { // check if the new interval overlaps with the current + curr.end = curr.end > I.end ? curr.end : I.end; + } else { result.add(curr); - return result; + curr = I; + } } - + result.add(curr); + return result; + } } diff --git a/problems/src/array/MergeSortedArray.java b/problems/src/array/MergeSortedArray.java index 82530e63..6121ed33 100644 --- a/problems/src/array/MergeSortedArray.java +++ b/problems/src/array/MergeSortedArray.java @@ -1,27 +1,24 @@ package array; /** - * Created by gouthamvidyapradhan on 29/07/2017. - * Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. - *

- * Note: - * You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively. + * Created by gouthamvidyapradhan on 29/07/2017. Given two sorted integer arrays nums1 and nums2, + * merge nums2 into nums1 as one sorted array. + * + *

Note: You may assume that nums1 has enough space (size that is greater or equal to m + n) to + * hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m + * and n respectively. */ public class MergeSortedArray { - public static void main(String[] args) throws Exception { - int[] A = {0}; - int[] B = {1}; - new MergeSortedArray().merge(A, 0, B, 1); - for (int i : A) - System.out.println(i); - } - - public void merge(int[] nums1, int m, int[] nums2, int n) { - int i = m + n - 1, j = m - 1, k = n - 1; - while (j >= 0 && k >= 0) - nums1[i--] = (nums1[j] > nums2[k]) ? nums1[j--] : nums2[k--]; - while (k >= 0) - nums1[i--] = nums2[k--]; - } + public static void main(String[] args) throws Exception { + int[] A = {0}; + int[] B = {1}; + new MergeSortedArray().merge(A, 0, B, 1); + for (int i : A) System.out.println(i); + } + public void merge(int[] nums1, int m, int[] nums2, int n) { + int i = m + n - 1, j = m - 1, k = n - 1; + while (j >= 0 && k >= 0) nums1[i--] = (nums1[j] > nums2[k]) ? nums1[j--] : nums2[k--]; + while (k >= 0) nums1[i--] = nums2[k--]; + } } diff --git a/problems/src/array/MinimumIndexSumOfTwoLists.java b/problems/src/array/MinimumIndexSumOfTwoLists.java index 1751d75b..771a1db3 100644 --- a/problems/src/array/MinimumIndexSumOfTwoLists.java +++ b/problems/src/array/MinimumIndexSumOfTwoLists.java @@ -6,76 +6,67 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 11/04/2018. - * Suppose Andy and Doris want to choose a restaurant for dinner, and they both have a list of favorite restaurants - * represented by strings. - - You need to help them find out their common interest with the least list index sum. If there is a choice tie between - answers, output all of them with no order requirement. You could assume there always exists an answer. - - Example 1: - Input: - ["Shogun", "Tapioca Express", "Burger King", "KFC"] - ["Piatti", "The Grill at Torrey Pines", "Hungry Hunter Steakhouse", "Shogun"] - Output: ["Shogun"] - Explanation: The only restaurant they both like is "Shogun". - Example 2: - Input: - ["Shogun", "Tapioca Express", "Burger King", "KFC"] - ["KFC", "Shogun", "Burger King"] - Output: ["Shogun"] - Explanation: The restaurant they both like and have the least index sum is "Shogun" with index sum 1 (0+1). - Note: - The length of both lists will be in the range of [1, 1000]. - The length of strings in both lists will be in the range of [1, 30]. - The index is starting from 0 to the list length minus 1. - No duplicates in both lists. - - Solution:O(N) maintain index of each restaurant in a list using a HashMap, find the min sum of indices and list - all the restaurants which match the min sum of indices - + * Created by gouthamvidyapradhan on 11/04/2018. Suppose Andy and Doris want to choose a restaurant + * for dinner, and they both have a list of favorite restaurants represented by strings. + * + *

You need to help them find out their common interest with the least list index sum. If there + * is a choice tie between answers, output all of them with no order requirement. You could assume + * there always exists an answer. + * + *

Example 1: Input: ["Shogun", "Tapioca Express", "Burger King", "KFC"] ["Piatti", "The Grill at + * Torrey Pines", "Hungry Hunter Steakhouse", "Shogun"] Output: ["Shogun"] Explanation: The only + * restaurant they both like is "Shogun". Example 2: Input: ["Shogun", "Tapioca Express", "Burger + * King", "KFC"] ["KFC", "Shogun", "Burger King"] Output: ["Shogun"] Explanation: The restaurant + * they both like and have the least index sum is "Shogun" with index sum 1 (0+1). Note: The length + * of both lists will be in the range of [1, 1000]. The length of strings in both lists will be in + * the range of [1, 30]. The index is starting from 0 to the list length minus 1. No duplicates in + * both lists. + * + *

Solution:O(N) maintain index of each restaurant in a list using a HashMap, find the min sum of + * indices and list all the restaurants which match the min sum of indices */ public class MinimumIndexSumOfTwoLists { - /** - * Main method - * @param args - */ - public static void main(String[] args) throws Exception{ - String[] A1 = {"Shogun", "Tapioca Express", "Burger King", "KFC"}; - String[] A2 = {"Tapioca Express", "Shogun", "Burger King"}; - String[] ans = new MinimumIndexSumOfTwoLists().findRestaurant(A1, A2); - for(String s : ans){ - System.out.println(s); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) throws Exception { + String[] A1 = {"Shogun", "Tapioca Express", "Burger King", "KFC"}; + String[] A2 = {"Tapioca Express", "Shogun", "Burger King"}; + String[] ans = new MinimumIndexSumOfTwoLists().findRestaurant(A1, A2); + for (String s : ans) { + System.out.println(s); } + } - public String[] findRestaurant(String[] list1, String[] list2) { - int min = Integer.MAX_VALUE; - List result = new ArrayList<>(); - if(list2.length == 0) return new String[0]; - Map index = new HashMap<>(); - for(int i = 0; i < list2.length; i ++){ - index.put(list2[i], i); - } - for(int i = 0; i < list1.length; i ++){ - String s = list1[i]; - if(index.containsKey(s)){ - int sum = i + index.get(s); - min = Math.min(min, sum); - } - } + public String[] findRestaurant(String[] list1, String[] list2) { + int min = Integer.MAX_VALUE; + List result = new ArrayList<>(); + if (list2.length == 0) return new String[0]; + Map index = new HashMap<>(); + for (int i = 0; i < list2.length; i++) { + index.put(list2[i], i); + } + for (int i = 0; i < list1.length; i++) { + String s = list1[i]; + if (index.containsKey(s)) { + int sum = i + index.get(s); + min = Math.min(min, sum); + } + } - for(int i = 0; i < list1.length; i ++){ - String s = list1[i]; - if(index.containsKey(s)){ - int sum = i + index.get(s); - if(sum == min){ - result.add(s); - } - } + for (int i = 0; i < list1.length; i++) { + String s = list1[i]; + if (index.containsKey(s)) { + int sum = i + index.get(s); + if (sum == min) { + result.add(s); } - String[] resArr = new String[result.size()]; - result.toArray(resArr); - return resArr; + } } + String[] resArr = new String[result.size()]; + result.toArray(resArr); + return resArr; + } } diff --git a/problems/src/array/MinimumMovesToEqualArray.java b/problems/src/array/MinimumMovesToEqualArray.java index 9c421ba6..a431b840 100644 --- a/problems/src/array/MinimumMovesToEqualArray.java +++ b/problems/src/array/MinimumMovesToEqualArray.java @@ -3,66 +3,65 @@ import java.util.Arrays; /** - * Created by gouthamvidyapradhan on 17/02/2018. - * Given a non-empty integer array, find the minimum number of moves required to make all array elements equal, - * where a move is incrementing a selected element by 1 or decrementing a selected element by 1. - - You may assume the array's length is at most 10,000. - - Example: - - Input: - [1,2,3] - - Output: - 2 - - Explanation: - Only two moves are needed (remember each move increments or decrements one element): - - [1,2,3] => [2,2,3] => [2,2,2] - - Solution: O(n log n): Sort the array and find the median of the array. - Use the median of array to increment/decrement other value of array. Sum up the difference and return the answer. + * Created by gouthamvidyapradhan on 17/02/2018. Given a non-empty integer array, find the minimum + * number of moves required to make all array elements equal, where a move is incrementing a + * selected element by 1 or decrementing a selected element by 1. + * + *

You may assume the array's length is at most 10,000. + * + *

Example: + * + *

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

Output: 2 + * + *

Explanation: Only two moves are needed (remember each move increments or decrements one + * element): + * + *

[1,2,3] => [2,2,3] => [2,2,2] + * + *

Solution: O(n log n): Sort the array and find the median of the array. Use the median of array + * to increment/decrement other value of array. Sum up the difference and return the answer. */ public class MinimumMovesToEqualArray { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1, 2, 3}; - System.out.println(new MinimumMovesToEqualArray().minMoves2(A)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 2, 3}; + System.out.println(new MinimumMovesToEqualArray().minMoves2(A)); + } - public int minMoves2(int[] nums) { - if(nums.length == 1) return 0; - else if(nums.length == 2) return Math.abs(nums[0] - nums[1]); - Arrays.sort(nums); - int median; - if((nums.length % 2) == 1){ - median = (nums.length / 2); - int sum = 0; - for(int i = 0; i < nums.length; i++){ - sum += Math.abs(nums[i] - nums[median]); - } - return sum; - } else{ - median = (nums.length / 2) - 1; - int sum = 0; - int min; - for(int i = 0; i < nums.length; i++){ - sum += Math.abs(nums[i] - nums[median]); - } - min = sum; - sum = 0; - median = (nums.length / 2); - for(int i = 0; i < nums.length; i++){ - sum += Math.abs(nums[i] - nums[median]); - } - min = Math.min(min, sum); - return min; - } + public int minMoves2(int[] nums) { + if (nums.length == 1) return 0; + else if (nums.length == 2) return Math.abs(nums[0] - nums[1]); + Arrays.sort(nums); + int median; + if ((nums.length % 2) == 1) { + median = (nums.length / 2); + int sum = 0; + for (int i = 0; i < nums.length; i++) { + sum += Math.abs(nums[i] - nums[median]); + } + return sum; + } else { + median = (nums.length / 2) - 1; + int sum = 0; + int min; + for (int i = 0; i < nums.length; i++) { + sum += Math.abs(nums[i] - nums[median]); + } + min = sum; + sum = 0; + median = (nums.length / 2); + for (int i = 0; i < nums.length; i++) { + sum += Math.abs(nums[i] - nums[median]); + } + min = Math.min(min, sum); + return min; } + } } diff --git a/problems/src/array/MissingNumber.java b/problems/src/array/MissingNumber.java index b874c83a..3be7a426 100644 --- a/problems/src/array/MissingNumber.java +++ b/problems/src/array/MissingNumber.java @@ -1,30 +1,29 @@ package array; /** - * Created by gouthamvidyapradhan on 04/07/2017. - * Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array. - *

- * For example, - * Given nums = [0, 1, 3] return 2. - *

- * Note: - * Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity? + * Created by gouthamvidyapradhan on 04/07/2017. Given an array containing n distinct numbers taken + * from 0, 1, 2, ..., n, find the one that is missing from the array. + * + *

For example, Given nums = [0, 1, 3] return 2. + * + *

Note: Your algorithm should run in linear runtime complexity. Could you implement it using + * only constant extra space complexity? */ public class MissingNumber { - public static void main(String[] args) throws Exception { - int[] nums = {0}; - System.out.println(new MissingNumber().missingNumber(nums)); - } + public static void main(String[] args) throws Exception { + int[] nums = {0}; + System.out.println(new MissingNumber().missingNumber(nums)); + } - public int missingNumber(int[] nums) { - int sum = 0; - int n = nums.length; - for (int num : nums) { - sum += num; - } - int arrSum = (((n + 1)) * n) / 2; - if (arrSum == sum) return 0; - else return arrSum - sum; + public int missingNumber(int[] nums) { + int sum = 0; + int n = nums.length; + for (int num : nums) { + sum += num; } + int arrSum = (((n + 1)) * n) / 2; + if (arrSum == sum) return 0; + else return arrSum - sum; + } } diff --git a/problems/src/array/MyCalendarThree.java b/problems/src/array/MyCalendarThree.java index 991a071b..335341c3 100644 --- a/problems/src/array/MyCalendarThree.java +++ b/problems/src/array/MyCalendarThree.java @@ -3,90 +3,86 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 12/03/2019 - * Implement a MyCalendarThree class to store your events. A new event can always be added. + * Created by gouthamvidyapradhan on 12/03/2019 Implement a MyCalendarThree class to store your + * events. A new event can always be added. * - * Your class will have one method, book(int start, int end). Formally, this represents a booking on the half open - * interval [start, end), the range of real numbers x such that start <= x < end. + *

Your class will have one method, book(int start, int end). Formally, this represents a booking + * on the half open interval [start, end), the range of real numbers x such that start <= x < end. * - * A K-booking happens when K events have some non-empty intersection (ie., there is some time that is common to all - * K events.) + *

A K-booking happens when K events have some non-empty intersection (ie., there is some time + * that is common to all K events.) * - * For each call to the method MyCalendar.book, return an integer K representing the largest integer such that there - * exists a K-booking in the calendar. + *

For each call to the method MyCalendar.book, return an integer K representing the largest + * integer such that there exists a K-booking in the calendar. * - * Your class will be called like this: MyCalendarThree cal = new MyCalendarThree(); MyCalendarThree.book(start, end) - * Example 1: + *

Your class will be called like this: MyCalendarThree cal = new MyCalendarThree(); + * MyCalendarThree.book(start, end) Example 1: * - * MyCalendarThree(); - * MyCalendarThree.book(10, 20); // returns 1 - * MyCalendarThree.book(50, 60); // returns 1 - * MyCalendarThree.book(10, 40); // returns 2 - * MyCalendarThree.book(5, 15); // returns 3 - * MyCalendarThree.book(5, 10); // returns 3 - * MyCalendarThree.book(25, 55); // returns 3 - * Explanation: - * The first two events can be booked and are disjoint, so the maximum K-booking is a 1-booking. - * The third event [10, 40) intersects the first event, and the maximum K-booking is a 2-booking. - * The remaining events cause the maximum K-booking to be only a 3-booking. - * Note that the last event locally causes a 2-booking, but the answer is still 3 because - * eg. [10, 20), [10, 40), and [5, 15) are still triple booked. + *

MyCalendarThree(); MyCalendarThree.book(10, 20); // returns 1 MyCalendarThree.book(50, 60); // + * returns 1 MyCalendarThree.book(10, 40); // returns 2 MyCalendarThree.book(5, 15); // returns 3 + * MyCalendarThree.book(5, 10); // returns 3 MyCalendarThree.book(25, 55); // returns 3 Explanation: + * The first two events can be booked and are disjoint, so the maximum K-booking is a 1-booking. The + * third event [10, 40) intersects the first event, and the maximum K-booking is a 2-booking. The + * remaining events cause the maximum K-booking to be only a 3-booking. Note that the last event + * locally causes a 2-booking, but the answer is still 3 because eg. [10, 20), [10, 40), and [5, 15) + * are still triple booked. */ -public class MyCalendarThree{ +public class MyCalendarThree { - private List events; - private int max; + private List events; + private int max; - private class Node{ - int n, index; - Node(int n, int index){ - this.n = n; - this.index = index; - } + private class Node { + int n, index; - public int getN() { - return n; - } - - public int getIndex() { - return index; - } + Node(int n, int index) { + this.n = n; + this.index = index; } - public MyCalendarThree() { - events = new ArrayList<>(); - max = 0; + public int getN() { + return n; } - /** - * Main method - * @param args - */ - public static void main(String[] args) { - MyCalendarThree calendar = new MyCalendarThree(); - System.out.println(calendar.book(10, 20)); - System.out.println(calendar.book(50, 60)); - System.out.println(calendar.book(10, 40)); - System.out.println(calendar.book(5, 15)); - System.out.println(calendar.book(5, 10)); - System.out.println(calendar.book(25, 55)); + public int getIndex() { + return index; } + } + + public MyCalendarThree() { + events = new ArrayList<>(); + max = 0; + } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + MyCalendarThree calendar = new MyCalendarThree(); + System.out.println(calendar.book(10, 20)); + System.out.println(calendar.book(50, 60)); + System.out.println(calendar.book(10, 40)); + System.out.println(calendar.book(5, 15)); + System.out.println(calendar.book(5, 10)); + System.out.println(calendar.book(25, 55)); + } - public int book(int start, int end) { - events.add(new Node(start, 1)); - events.add(new Node(end, 0)); - events.sort((Comparator.comparing(Node::getN).thenComparing(Node::getIndex))); - int count = 0; - for(Node node : events){ - if(node.index == 1 && node.n >= end){ - break; - } - count += node.index == 1 ? 1 : -1; - if(node.getN() >= start){ - max = Math.max(max, count); - } - } - return max; + public int book(int start, int end) { + events.add(new Node(start, 1)); + events.add(new Node(end, 0)); + events.sort((Comparator.comparing(Node::getN).thenComparing(Node::getIndex))); + int count = 0; + for (Node node : events) { + if (node.index == 1 && node.n >= end) { + break; + } + count += node.index == 1 ? 1 : -1; + if (node.getN() >= start) { + max = Math.max(max, count); + } } + return max; + } } diff --git a/problems/src/array/NextGreaterElementI.java b/problems/src/array/NextGreaterElementI.java index 7c053d8b..9021407c 100644 --- a/problems/src/array/NextGreaterElementI.java +++ b/problems/src/array/NextGreaterElementI.java @@ -1,67 +1,61 @@ package array; /** - * Created by gouthamvidyapradhan on 09/02/2018. - * You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of nums2. - * Find all the next greater numbers for nums1's elements in the corresponding places of nums2. - - The Next Greater Number of a number x in nums1 is the first greater number to its right in nums2. - If it does not exist, output -1 for this number. - - Example 1: - 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. - Example 2: - Input: nums1 = [2,4], nums2 = [1,2,3,4]. - Output: [3,-1] - Explanation: - For number 2 in the first array, the next greater number for it in the second array is 3. - For number 4 in the first array, there is no next greater number for it in the second array, so output -1. - Note: - All elements in nums1 and nums2 are unique. - The length of both nums1 and nums2 would not exceed 1000. + * Created by gouthamvidyapradhan on 09/02/2018. You are given two arrays (without duplicates) nums1 + * and nums2 where nums1’s elements are subset of nums2. Find all the next greater numbers for + * nums1's elements in the corresponding places of nums2. + * + *

The Next Greater Number of a number x in nums1 is the first greater number to its right in + * nums2. If it does not exist, output -1 for this number. + * + *

Example 1: 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. Example 2: Input: nums1 = [2,4], nums2 = [1,2,3,4]. Output: [3,-1] + * Explanation: For number 2 in the first array, the next greater number for it in the second array + * is 3. For number 4 in the first array, there is no next greater number for it in the second + * array, so output -1. Note: All elements in nums1 and nums2 are unique. The length of both nums1 + * and nums2 would not exceed 1000. */ public class NextGreaterElementI { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {4,1,2}; - int[] B = {1,3,4,2}; - int[] result = new NextGreaterElementI().nextGreaterElement(A, B); - System.out.println(result); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {4, 1, 2}; + int[] B = {1, 3, 4, 2}; + int[] result = new NextGreaterElementI().nextGreaterElement(A, B); + System.out.println(result); + } - public int[] nextGreaterElement(int[] nums1, int[] nums2) { - int[] result = new int[nums1.length]; - for(int i = 0; i < nums1.length; i ++){ - int n = nums1[i]; - boolean found = false; - int nF = 0; - for(int j = 0; j < nums2.length; j ++){ - if(nums2[j] == n){ - found = true; - } if(found){ - if(nums2[j] > n){ - nF = nums2[j]; - break; - } - } - } - if(found){ - result[i] = nF; - } else{ - result[i] = -1; - } + public int[] nextGreaterElement(int[] nums1, int[] nums2) { + int[] result = new int[nums1.length]; + for (int i = 0; i < nums1.length; i++) { + int n = nums1[i]; + boolean found = false; + int nF = 0; + for (int j = 0; j < nums2.length; j++) { + if (nums2[j] == n) { + found = true; } - return result; + if (found) { + if (nums2[j] > n) { + nF = nums2[j]; + break; + } + } + } + if (found) { + result[i] = nF; + } else { + result[i] = -1; + } } - + return result; + } } diff --git a/problems/src/array/PascalsTriangle.java b/problems/src/array/PascalsTriangle.java index d12a2384..be60ed1d 100644 --- a/problems/src/array/PascalsTriangle.java +++ b/problems/src/array/PascalsTriangle.java @@ -6,44 +6,39 @@ /** * Created by gouthamvidyapradhan on 25/03/2017. - *

- * Given an index k, return the kth row of the Pascal's triangle. - *

- * For example, given k = 3, - * Return [1,3,3,1]. - *

- * Note: - * Could you optimize your algorithm to use only O(k) extra space? + * + *

Given an index k, return the kth row of the Pascal's triangle. + * + *

For example, given k = 3, Return [1,3,3,1]. + * + *

Note: Could you optimize your algorithm to use only O(k) extra space? */ public class PascalsTriangle { - public static void main(String[] args) throws Exception { - System.out.println(new PascalsTriangle().getRow(3)); - } + public static void main(String[] args) throws Exception { + System.out.println(new PascalsTriangle().getRow(3)); + } - public List getRow(int rowIndex) { - int k = rowIndex; - if (k == 0) - return Arrays.asList(1); - else if (k == 1) - return Arrays.asList(1, 1); - else if (k == 2) - return Arrays.asList(1, 2, 1); - List result = new ArrayList<>(); - result.add(2); - k = k - 2; - int p, c; - while (k-- > 0) { - p = 1; - int i = 0; - for (int l = result.size(); i < l; i++) { - c = result.get(i); - result.set(i, p + c); - p = c; - } - result.add(p + 1); - } - result.add(0, 1); - result.add(1); - return result; + public List getRow(int rowIndex) { + int k = rowIndex; + if (k == 0) return Arrays.asList(1); + else if (k == 1) return Arrays.asList(1, 1); + else if (k == 2) return Arrays.asList(1, 2, 1); + List result = new ArrayList<>(); + result.add(2); + k = k - 2; + int p, c; + while (k-- > 0) { + p = 1; + int i = 0; + for (int l = result.size(); i < l; i++) { + c = result.get(i); + result.set(i, p + c); + p = c; + } + result.add(p + 1); } + result.add(0, 1); + result.add(1); + return result; + } } diff --git a/problems/src/array/PourWater.java b/problems/src/array/PourWater.java index e9e53488..aa377d8b 100644 --- a/problems/src/array/PourWater.java +++ b/problems/src/array/PourWater.java @@ -1,169 +1,116 @@ package array; /** - * Created by gouthamvidyapradhan on 03/02/2018. - * We are given an elevation map, heights[i] representing the height of the terrain at that index. The width at each - * index is 1. After V units of water fall at index K, how much water is at each index? - - Water first drops at index K and rests on top of the highest terrain or water at that index. Then, it flows - according to the following rules: - - If the droplet would eventually fall by moving left, then move left. - Otherwise, if the droplet would eventually fall by moving right, then move right. - Otherwise, rise at it's current position. - Here, "eventually fall" means that the droplet will eventually be at a lower level if it moves in that direction. - Also, "level" means the height of the terrain plus any water in that column. - We can assume there's infinitely high terrain on the two sides out of bounds of the array. Also, there could not be - partial water being spread out evenly on more than 1 grid block - each unit of water has to be in exactly one block. - - Example 1: - Input: heights = [2,1,1,2,1,2,2], V = 4, K = 3 - Output: [2,2,2,3,2,2,2] - Explanation: - # # - # # - ## # ### - ######### - 0123456 <- index - - The first drop of water lands at index K = 3: - - # # - # w # - ## # ### - ######### - 0123456 - - When moving left or right, the water can only move to the same level or a lower level. - (By level, we mean the total height of the terrain plus any water in that column.) - Since moving left will eventually make it fall, it moves left. - (A droplet "made to fall" means go to a lower height than it was at previously.) - - # # - # # - ## w# ### - ######### - 0123456 - - Since moving left will not make it fall, it stays in place. The next droplet falls: - - # # - # w # - ## w# ### - ######### - 0123456 - - Since the new droplet moving left will eventually make it fall, it moves left. - Notice that the droplet still preferred to move left, - even though it could move right (and moving right makes it fall quicker.) - - # # - # w # - ## w# ### - ######### - 0123456 - - # # - # # - ##ww# ### - ######### - 0123456 - - After those steps, the third droplet falls. - Since moving left would not eventually make it fall, it tries to move right. - Since moving right would eventually make it fall, it moves right. - - # # - # w # - ##ww# ### - ######### - 0123456 - - # # - # # - ##ww#w### - ######### - 0123456 - - Finally, the fourth droplet falls. - Since moving left would not eventually make it fall, it tries to move right. - Since moving right would not eventually make it fall, it stays in place: - - # # - # w # - ##ww#w### - ######### - 0123456 - - The final answer is [2,2,2,3,2,2,2]: - - # - ####### - ####### - 0123456 - Example 2: - Input: heights = [1,2,3,4], V = 2, K = 2 - Output: [2,3,3,4] - Explanation: - The last droplet settles at index 1, since moving further left would not cause it to eventually fall to a lower - height. - Example 3: - Input: heights = [3,1,3], V = 5, K = 1 - Output: [4,4,4] - Note: - - heights will have length in [1, 100] and contain integers in [0, 99]. - V will be in range [0, 2000]. - K will be in range [0, heights.length - 1]. - - Solution: - Check first left and then right to see if there are any lower levels, if yes then drop the water at this point. Else - maintain the drop at the start position + * Created by gouthamvidyapradhan on 03/02/2018. We are given an elevation map, heights[i] + * representing the height of the terrain at that index. The width at each index is 1. After V units + * of water fall at index K, how much water is at each index? + * + *

Water first drops at index K and rests on top of the highest terrain or water at that index. + * Then, it flows according to the following rules: + * + *

If the droplet would eventually fall by moving left, then move left. Otherwise, if the droplet + * would eventually fall by moving right, then move right. Otherwise, rise at it's current position. + * Here, "eventually fall" means that the droplet will eventually be at a lower level if it moves in + * that direction. Also, "level" means the height of the terrain plus any water in that column. We + * can assume there's infinitely high terrain on the two sides out of bounds of the array. Also, + * there could not be partial water being spread out evenly on more than 1 grid block - each unit of + * water has to be in exactly one block. + * + *

Example 1: Input: heights = [2,1,1,2,1,2,2], V = 4, K = 3 Output: [2,2,2,3,2,2,2] Explanation: + * # # # # ## # ### ######### 0123456 <- index + * + *

The first drop of water lands at index K = 3: + * + *

# # # w # ## # ### ######### 0123456 + * + *

When moving left or right, the water can only move to the same level or a lower level. (By + * level, we mean the total height of the terrain plus any water in that column.) Since moving left + * will eventually make it fall, it moves left. (A droplet "made to fall" means go to a lower height + * than it was at previously.) + * + *

# # # # ## w# ### ######### 0123456 + * + *

Since moving left will not make it fall, it stays in place. The next droplet falls: + * + *

# # # w # ## w# ### ######### 0123456 + * + *

Since the new droplet moving left will eventually make it fall, it moves left. Notice that the + * droplet still preferred to move left, even though it could move right (and moving right makes it + * fall quicker.) + * + *

# # # w # ## w# ### ######### 0123456 + * + *

# # # # ##ww# ### ######### 0123456 + * + *

After those steps, the third droplet falls. Since moving left would not eventually make it + * fall, it tries to move right. Since moving right would eventually make it fall, it moves right. + * + *

# # # w # ##ww# ### ######### 0123456 + * + *

# # # # ##ww#w### ######### 0123456 + * + *

Finally, the fourth droplet falls. Since moving left would not eventually make it fall, it + * tries to move right. Since moving right would not eventually make it fall, it stays in place: + * + *

# # # w # ##ww#w### ######### 0123456 + * + *

The final answer is [2,2,2,3,2,2,2]: + * + *

# ####### ####### 0123456 Example 2: Input: heights = [1,2,3,4], V = 2, K = 2 Output: + * [2,3,3,4] Explanation: The last droplet settles at index 1, since moving further left would not + * cause it to eventually fall to a lower height. Example 3: Input: heights = [3,1,3], V = 5, K = 1 + * Output: [4,4,4] Note: + * + *

heights will have length in [1, 100] and contain integers in [0, 99]. V will be in range [0, + * 2000]. K will be in range [0, heights.length - 1]. + * + *

Solution: Check first left and then right to see if there are any lower levels, if yes then + * drop the water at this point. Else maintain the drop at the start position */ public class PourWater { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {2, 1, 1, 2, 1, 2, 2}; - int[] result = new PourWater().pourWater(A, 4, 3); - for(int i : result){ - System.out.print(i + " "); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {2, 1, 1, 2, 1, 2, 2}; + int[] result = new PourWater().pourWater(A, 4, 3); + for (int i : result) { + System.out.print(i + " "); } - - public int[] pourWater(int[] heights, int V, int K) { - while(V-- > 0){ - heights[K] += 1; - int index = K; - int min = heights[K]; - for(int i = K - 1; i >= 0; i--){ - if(heights[i] + 1 > min){ - break; - } else if(heights[i] + 1 < min){ - min = heights[i] + 1; - index = i; - } - } - if(index == K){ - for(int i = K + 1; i < heights.length; i++){ - if(heights[i] + 1 > min){ - break; - } else if(heights[i] + 1 < min){ - min = heights[i] + 1; - index = i; - } - } - } - if(index != K){ - heights[K]--; - heights[index]++; - } + } + + public int[] pourWater(int[] heights, int V, int K) { + while (V-- > 0) { + heights[K] += 1; + int index = K; + int min = heights[K]; + for (int i = K - 1; i >= 0; i--) { + if (heights[i] + 1 > min) { + break; + } else if (heights[i] + 1 < min) { + min = heights[i] + 1; + index = i; + } + } + if (index == K) { + for (int i = K + 1; i < heights.length; i++) { + if (heights[i] + 1 > min) { + break; + } else if (heights[i] + 1 < min) { + min = heights[i] + 1; + index = i; + } } - return heights; + } + if (index != K) { + heights[K]--; + heights[index]++; + } } - + return heights; + } } diff --git a/problems/src/array/ProductOfArrayExceptSelf.java b/problems/src/array/ProductOfArrayExceptSelf.java index 4ed21a77..d9ebac09 100644 --- a/problems/src/array/ProductOfArrayExceptSelf.java +++ b/problems/src/array/ProductOfArrayExceptSelf.java @@ -2,36 +2,34 @@ /** * Created by gouthamvidyapradhan on 04/05/2017. - *

- * Given an array of n integers where n > 1, nums, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i]. - *

- * Solve it without division and in O(n). - *

- * For example, given [1,2,3,4], return [24,12,8,6]. - *

- * Follow up: - * Could you solve it with constant space complexity? (Note: The output array does not count as extra space for the purpose of space complexity analysis.) + * + *

Given an array of n integers where n > 1, nums, return an array output such that output[i] is + * equal to the product of all the elements of nums except nums[i]. + * + *

Solve it without division and in O(n). + * + *

For example, given [1,2,3,4], return [24,12,8,6]. + * + *

Follow up: Could you solve it with constant space complexity? (Note: The output array does not + * count as extra space for the purpose of space complexity analysis.) */ - public class ProductOfArrayExceptSelf { - public static void main(String[] args) { - int[] nums = {1, 2, 3, 4}; - int[] result = new ProductOfArrayExceptSelf().productExceptSelf(nums); - for (int r : result) - System.out.print(r + " "); - } + public static void main(String[] args) { + int[] nums = {1, 2, 3, 4}; + int[] result = new ProductOfArrayExceptSelf().productExceptSelf(nums); + for (int r : result) System.out.print(r + " "); + } - public int[] productExceptSelf(int[] nums) { - int[] result = new int[nums.length]; - for (int i = 0, temp = 1, l = nums.length; i < l; i++) { - result[i] = temp; - temp *= nums[i]; - } - for (int i = nums.length - 1, temp = 1; i >= 0; i--) { - result[i] = result[i] * temp; - temp *= nums[i]; - } - return result; + public int[] productExceptSelf(int[] nums) { + int[] result = new int[nums.length]; + for (int i = 0, temp = 1, l = nums.length; i < l; i++) { + result[i] = temp; + temp *= nums[i]; } - + for (int i = nums.length - 1, temp = 1; i >= 0; i--) { + result[i] = result[i] * temp; + temp *= nums[i]; + } + return result; + } } diff --git a/problems/src/array/ReadNCharacters.java b/problems/src/array/ReadNCharacters.java index 0dae036c..fc58afae 100644 --- a/problems/src/array/ReadNCharacters.java +++ b/problems/src/array/ReadNCharacters.java @@ -1,53 +1,47 @@ package array; /** - * Created by gouthamvidyapradhan on 09/12/2017. - * The API: int read4(char *buf) reads 4 characters at a time from a file. - - The return value is the actual number of characters read. For example, it returns 3 if there is only 3 characters - left in the file. - - By using the read4 API, implement the function int read(char *buf, int n) that reads n characters from the file. - - Note: - The read function will only be called once for each test case. - - + * Created by gouthamvidyapradhan on 09/12/2017. The API: int read4(char *buf) reads 4 characters at + * a time from a file. + * + *

The return value is the actual number of characters read. For example, it returns 3 if there + * is only 3 characters left in the file. + * + *

By using the read4 API, implement the function int read(char *buf, int n) that reads n + * characters from the file. + * + *

Note: The read function will only be called once for each test case. */ public class ReadNCharacters { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - - } - - /** - * - * @param buf - * @param n - * @return - */ - public int read(char[] buf, int n) { - int i = 0; - int toRead = Math.min(n, buf.length); - while(i < toRead){ - char[] temp = new char[4]; - int r = read4(temp); - for(int j = 0; j < r && i < toRead; j ++){ - buf[i] = temp[j]; - i++; - } - if(r < 4) break; - } - return Math.min(i, toRead); - } - - - private int read4(char[] buf){ - return 1;//return fake value just to resolve compilation error + /** + * Main method + * + * @param args + */ + public static void main(String[] args) {} + + /** + * @param buf + * @param n + * @return + */ + public int read(char[] buf, int n) { + int i = 0; + int toRead = Math.min(n, buf.length); + while (i < toRead) { + char[] temp = new char[4]; + int r = read4(temp); + for (int j = 0; j < r && i < toRead; j++) { + buf[i] = temp[j]; + i++; + } + if (r < 4) break; } + return Math.min(i, toRead); + } + private int read4(char[] buf) { + return 1; // return fake value just to resolve compilation error + } } diff --git a/problems/src/array/RelativeRanks.java b/problems/src/array/RelativeRanks.java index 43f41b59..9423baa7 100644 --- a/problems/src/array/RelativeRanks.java +++ b/problems/src/array/RelativeRanks.java @@ -4,63 +4,59 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 09/02/2018. - * Given scores of N athletes, find their relative ranks and the people with the top three highest scores, - * who will be awarded medals: "Gold Medal", "Silver Medal" and "Bronze Medal". - - Example 1: - Input: [5, 4, 3, 2, 1] - Output: ["Gold Medal", "Silver Medal", "Bronze Medal", "4", "5"] - Explanation: The first three athletes got the top three highest scores, so they got "Gold Medal", "Silver Medal" - and "Bronze Medal". - For the left two athletes, you just need to output their relative ranks according to their scores. - Note: - N is a positive integer and won't exceed 10,000. - All the scores of athletes are guaranteed to be unique. + * Created by gouthamvidyapradhan on 09/02/2018. Given scores of N athletes, find their relative + * ranks and the people with the top three highest scores, who will be awarded medals: "Gold Medal", + * "Silver Medal" and "Bronze Medal". + * + *

Example 1: Input: [5, 4, 3, 2, 1] Output: ["Gold Medal", "Silver Medal", "Bronze Medal", "4", + * "5"] Explanation: The first three athletes got the top three highest scores, so they got "Gold + * Medal", "Silver Medal" and "Bronze Medal". For the left two athletes, you just need to output + * their relative ranks according to their scores. Note: N is a positive integer and won't exceed + * 10,000. All the scores of athletes are guaranteed to be unique. */ public class RelativeRanks { - class Position{ - int score, poisition; - Position(int score, int position){ - this.score = score; - this.poisition = position; - } + class Position { + int score, poisition; + + Position(int score, int position) { + this.score = score; + this.poisition = position; } - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {5, 4, 3, 2, 1}; - String[] S = new RelativeRanks().findRelativeRanks(A); - for(String i : S){ - System.out.println(i); - } + } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {5, 4, 3, 2, 1}; + String[] S = new RelativeRanks().findRelativeRanks(A); + for (String i : S) { + System.out.println(i); } + } - public String[] findRelativeRanks(int[] nums) { - String[] S = new String[nums.length]; - List list = new ArrayList<>(); - for(int i = 0; i < nums.length; i ++){ - list.add(new Position(nums[i], i)); - } - list.sort((o1, o2) -> Integer.compare(o2.score, o1.score)); - //Collections.reverse(list); - for(int i = 0; i < list.size(); i ++){ - if(i == 0){ - S[list.get(i).poisition] = "Gold Medal"; - } else if(i == 1){ - S[list.get(i).poisition] = "Silver Medal"; - } else if(i == 2){ - S[list.get(i).poisition] = "Bronze Medal"; - } - else { - S[list.get(i).poisition] = String.valueOf(i + 1); - } - } - return S; + public String[] findRelativeRanks(int[] nums) { + String[] S = new String[nums.length]; + List list = new ArrayList<>(); + for (int i = 0; i < nums.length; i++) { + list.add(new Position(nums[i], i)); } - + list.sort((o1, o2) -> Integer.compare(o2.score, o1.score)); + // Collections.reverse(list); + for (int i = 0; i < list.size(); i++) { + if (i == 0) { + S[list.get(i).poisition] = "Gold Medal"; + } else if (i == 1) { + S[list.get(i).poisition] = "Silver Medal"; + } else if (i == 2) { + S[list.get(i).poisition] = "Bronze Medal"; + } else { + S[list.get(i).poisition] = String.valueOf(i + 1); + } + } + return S; + } } diff --git a/problems/src/array/RotateArray.java b/problems/src/array/RotateArray.java index f418a52b..4b809291 100644 --- a/problems/src/array/RotateArray.java +++ b/problems/src/array/RotateArray.java @@ -1,45 +1,42 @@ package array; /** - * Created by gouthamvidyapradhan on 01/08/2017. - * Rotate an array of n elements to the right by k steps. - *

- * For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4]. - *

- * Note: - * Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. - *

- * Hint: - * Could you do it in-place with O(1) extra space? - * Related problem: Reverse Words in a String II + * Created by gouthamvidyapradhan on 01/08/2017. Rotate an array of n elements to the right by k + * steps. + * + *

For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4]. + * + *

Note: Try to come up as many solutions as you can, there are at least 3 different ways to + * solve this problem. + * + *

Hint: Could you do it in-place with O(1) extra space? Related problem: Reverse Words in a + * String II */ public class RotateArray { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] A = {1, 2, 3, 4, 5, 6}; - new RotateArray().rotate(A, 2); - for (int i : A) - System.out.print(i + " "); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 2, 3, 4, 5, 6}; + new RotateArray().rotate(A, 2); + for (int i : A) System.out.print(i + " "); + } - public void rotate(int[] nums, int k) { - k = k % nums.length; - reverse(nums, 0, nums.length - 1); - reverse(nums, 0, k - 1); - reverse(nums, k, nums.length - 1); - } + public void rotate(int[] nums, int k) { + k = k % nums.length; + reverse(nums, 0, nums.length - 1); + reverse(nums, 0, k - 1); + reverse(nums, k, nums.length - 1); + } - private void reverse(int[] nums, int s, int e) { - for (int i = s, j = e; i < j; i++, j--) { - int temp = nums[i]; - nums[i] = nums[j]; - nums[j] = temp; - } + private void reverse(int[] nums, int s, int e) { + for (int i = s, j = e; i < j; i++, j--) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; } - + } } diff --git a/problems/src/array/RotateMatrix.java b/problems/src/array/RotateMatrix.java index 6df275cf..367e9c1c 100644 --- a/problems/src/array/RotateMatrix.java +++ b/problems/src/array/RotateMatrix.java @@ -1,47 +1,48 @@ package array; /** - * Created by gouthamvidyapradhan on 21/03/2017. - * You are given an n x n 2D matrix representing an image. - *

- * Rotate the image by 90 degrees (clockwise). - *

- * Follow up: - * Could you do this in-place? + * Created by gouthamvidyapradhan on 21/03/2017. You are given an n x n 2D matrix representing an + * image. + * + *

Rotate the image by 90 degrees (clockwise). + * + *

Follow up: Could you do this in-place? */ public class RotateMatrix { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[][] A = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; - new RotateMatrix().rotate(A); - for (int i = 0; i < A.length; i++) { - for (int j = 0; j < A[0].length; j++) { - System.out.println(A[i][j]); - } - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[][] A = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; + new RotateMatrix().rotate(A); + for (int i = 0; i < A.length; i++) { + for (int j = 0; j < A[0].length; j++) { + System.out.println(A[i][j]); + } } + } - public void rotate(int[][] matrix) { - int lc = 0, tr = 0, rc = matrix[0].length - 1, br = matrix.length - 1; - while (tr < br) { - for (int i = lc, j = tr, k = rc, l = br; i < rc && j < br && k > lc && l > tr; i++, j++, k--, l--) { - int temp1 = matrix[j][rc]; - matrix[j][rc] = matrix[tr][i]; - int temp2 = matrix[br][k]; - matrix[br][k] = temp1; - temp1 = matrix[l][lc]; - matrix[l][lc] = temp2; - matrix[tr][i] = temp1; - } - lc++; - tr++; - rc--; - br--; - } + public void rotate(int[][] matrix) { + int lc = 0, tr = 0, rc = matrix[0].length - 1, br = matrix.length - 1; + while (tr < br) { + for (int i = lc, j = tr, k = rc, l = br; + i < rc && j < br && k > lc && l > tr; + i++, j++, k--, l--) { + int temp1 = matrix[j][rc]; + matrix[j][rc] = matrix[tr][i]; + int temp2 = matrix[br][k]; + matrix[br][k] = temp1; + temp1 = matrix[l][lc]; + matrix[l][lc] = temp2; + matrix[tr][i] = temp1; + } + lc++; + tr++; + rc--; + br--; } + } } diff --git a/problems/src/array/SetMatrixZeroes.java b/problems/src/array/SetMatrixZeroes.java index 43e8223e..4a80b448 100644 --- a/problems/src/array/SetMatrixZeroes.java +++ b/problems/src/array/SetMatrixZeroes.java @@ -4,54 +4,52 @@ import java.util.Set; /** - * Created by pradhang on 3/28/2017. - * Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. - *

- * click to show follow up. - *

- * Follow up: - * Did you use extra space? - * A straight forward solution using O(mn) space is probably a bad idea. - * A simple improvement uses O(m + n) space, but still not the best solution. - * Could you devise a constant space solution? + * Created by pradhang on 3/28/2017. Given a m x n matrix, if an element is 0, set its entire row + * and column to 0. Do it in place. + * + *

click to show follow up. + * + *

Follow up: Did you use extra space? A straight forward solution using O(mn) space is probably + * a bad idea. A simple improvement uses O(m + n) space, but still not the best solution. Could you + * devise a constant space solution? */ public class SetMatrixZeroes { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[][] matrix = {{0, 8, 7}, {9, 0, 8}, {9, 9, 0}}; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[][] matrix = {{0, 8, 7}, {9, 0, 8}, {9, 9, 0}}; - new SetMatrixZeroes().setZeroes(matrix); - } + new SetMatrixZeroes().setZeroes(matrix); + } - public void setZeroes(int[][] matrix) { - Set row = new HashSet<>(); - Set col = new HashSet<>(); - int m = matrix.length; - int n = matrix[0].length; - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - if (matrix[i][j] == 0) { - row.add(i); - col.add(j); - } - } + public void setZeroes(int[][] matrix) { + Set row = new HashSet<>(); + Set col = new HashSet<>(); + int m = matrix.length; + int n = matrix[0].length; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (matrix[i][j] == 0) { + row.add(i); + col.add(j); } + } + } - for (int r : row) { - for (int j = 0; j < n; j++) { - matrix[r][j] = 0; - } - } + for (int r : row) { + for (int j = 0; j < n; j++) { + matrix[r][j] = 0; + } + } - for (int c : col) { - for (int i = 0; i < m; i++) { - matrix[i][c] = 0; - } - } + for (int c : col) { + for (int i = 0; i < m; i++) { + matrix[i][c] = 0; + } } + } } diff --git a/problems/src/array/SortColors.java b/problems/src/array/SortColors.java index cd9486e4..dc9c7e39 100644 --- a/problems/src/array/SortColors.java +++ b/problems/src/array/SortColors.java @@ -1,67 +1,64 @@ package array; /** - * Created by gouthamvidyapradhan on 06/08/2017. - * Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue. - *

- * Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively. - *

- * Note: - * You are not suppose to use the library's sort function for this problem. - *

- * Follow up: - * A rather straight forward solution is a two-pass algorithm using counting sort. - * First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's. - *

- * Could you come up with an one-pass algorithm using only constant space? - *

- * Solution: - * The below solution works with one pass. The basic idea is to keep track of start and end index of - * contiguous 1s and push the 0s to left of 1s and 2 to right of 1s. + * Created by gouthamvidyapradhan on 06/08/2017. Given an array with n objects colored red, white or + * blue, sort them so that objects of the same color are adjacent, with the colors in the order red, + * white and blue. + * + *

Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue + * respectively. + * + *

Note: You are not suppose to use the library's sort function for this problem. + * + *

Follow up: A rather straight forward solution is a two-pass algorithm using counting sort. + * First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total + * number of 0's, then 1's and followed by 2's. + * + *

Could you come up with an one-pass algorithm using only constant space? + * + *

Solution: The below solution works with one pass. The basic idea is to keep track of start and + * end index of contiguous 1s and push the 0s to left of 1s and 2 to right of 1s. */ public class SortColors { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] nums = {2, 1, 0, 0, 1}; - new SortColors().sortColors(nums); - for (int i : nums) - System.out.println(i); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] nums = {2, 1, 0, 0, 1}; + new SortColors().sortColors(nums); + for (int i : nums) System.out.println(i); + } - public void sortColors(int[] nums) { - int s = nums[0]; //save the first index value - nums[0] = 1; //overwrite with 1 - int l = 0, r = 0; //left and right index indicating the start and end index of 1s - for (int i = 1; i < nums.length; i++) { - switch (nums[i]) { - case 0: - nums[l] = 0; - nums[r + 1] = 1; - if (r + 1 != i) { - nums[i] = 2; - } - l++; - r++; - break; + public void sortColors(int[] nums) { + int s = nums[0]; // save the first index value + nums[0] = 1; // overwrite with 1 + int l = 0, r = 0; // left and right index indicating the start and end index of 1s + for (int i = 1; i < nums.length; i++) { + switch (nums[i]) { + case 0: + nums[l] = 0; + nums[r + 1] = 1; + if (r + 1 != i) { + nums[i] = 2; + } + l++; + r++; + break; - case 1: - nums[r + 1] = 1; - if (r + 1 != i) { - nums[i] = 2; - } - r++; - break; - } - } - //replace the initial overwritten value with the original value - if (s == 0) - nums[l] = 0; - else if (s == 2) - nums[r] = 2; + case 1: + nums[r + 1] = 1; + if (r + 1 != i) { + nums[i] = 2; + } + r++; + break; + } } + // replace the initial overwritten value with the original value + if (s == 0) nums[l] = 0; + else if (s == 2) nums[r] = 2; + } } diff --git a/problems/src/array/SparseMatrixMultiplication.java b/problems/src/array/SparseMatrixMultiplication.java index 1a9d0cfe..04f6c8ed 100644 --- a/problems/src/array/SparseMatrixMultiplication.java +++ b/problems/src/array/SparseMatrixMultiplication.java @@ -3,78 +3,70 @@ /** * Created by gouthamvidyapradhan on 03/12/2017. * - * Given two sparse matrices A and B, return the result of AB. - - You may assume that A's column number is equal to B's row number. - - Example: - - A = [ - [ 1, 0, 0], - [-1, 0, 3] - ] - - B = [ - [ 7, 0, 0 ], - [ 0, 0, 0 ], - [ 0, 0, 1 ] - ] - - - | 1 0 0 | | 7 0 0 | | 7 0 0 | - AB = | -1 0 3 | x | 0 0 0 | = | -7 0 3 | - | 0 0 1 | - - Solution: Skip the rows and columns which you already know would result in zero after multiplication. + *

Given two sparse matrices A and B, return the result of AB. + * + *

You may assume that A's column number is equal to B's row number. + * + *

Example: + * + *

A = [ [ 1, 0, 0], [-1, 0, 3] ] + * + *

B = [ [ 7, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 1 ] ] + * + *

| 1 0 0 | | 7 0 0 | | 7 0 0 | AB = | -1 0 3 | x | 0 0 0 | = | -7 0 3 | | 0 0 1 | + * + *

Solution: Skip the rows and columns which you already know would result in zero after + * multiplication. */ public class SparseMatrixMultiplication { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[][] A = {{1,0,0,1}}; - int[][] B = {{7,0,0}, {0,0,0}, {0,0,1}, {0,0,1}}; - int[][] C = new SparseMatrixMultiplication().multiply(A, B); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[][] A = {{1, 0, 0, 1}}; + int[][] B = {{7, 0, 0}, {0, 0, 0}, {0, 0, 1}, {0, 0, 1}}; + int[][] C = new SparseMatrixMultiplication().multiply(A, B); + } - public int[][] multiply(int[][] A, int[][] B) { - boolean[] AH = new boolean[A.length]; // Metadata for matrix A - boolean[] BH = new boolean[B[0].length]; // Metadata for matrix A - for(int i = 0; i < A.length; i ++){ - for(int j = 0; j < A[0].length; j ++){ - if(A[i][j] != 0){ - AH[i] = true; - break; - } - } + public int[][] multiply(int[][] A, int[][] B) { + boolean[] AH = new boolean[A.length]; // Metadata for matrix A + boolean[] BH = new boolean[B[0].length]; // Metadata for matrix A + for (int i = 0; i < A.length; i++) { + for (int j = 0; j < A[0].length; j++) { + if (A[i][j] != 0) { + AH[i] = true; + break; } + } + } - for(int i = 0; i < B[0].length; i ++){ - for(int j = 0; j < B.length; j ++){ - if(B[j][i] != 0){ - BH[i] = true; - break; - } - } + for (int i = 0; i < B[0].length; i++) { + for (int j = 0; j < B.length; j++) { + if (B[j][i] != 0) { + BH[i] = true; + break; } + } + } - int[][] C = new int[A.length][B[0].length]; - for(int i = 0; i < C.length; i ++){ - if(AH[i]){ - for(int j = 0; j < C[0].length; j++){ - if(BH[j]){ - int sum = 0; - for(int k = 0; k < A[0].length; k++){ - sum += A[i][k] * B[k][j]; - } - C[i][j] = sum; - } - } + int[][] C = new int[A.length][B[0].length]; + for (int i = 0; i < C.length; i++) { + if (AH[i]) { + for (int j = 0; j < C[0].length; j++) { + if (BH[j]) { + int sum = 0; + for (int k = 0; k < A[0].length; k++) { + sum += A[i][k] * B[k][j]; } + C[i][j] = sum; + } } - return C; + } } + return C; + } } diff --git a/problems/src/array/SubArraysWithBoundedMaximum.java b/problems/src/array/SubArraysWithBoundedMaximum.java index dab0cc04..5ed30588 100644 --- a/problems/src/array/SubArraysWithBoundedMaximum.java +++ b/problems/src/array/SubArraysWithBoundedMaximum.java @@ -1,63 +1,59 @@ package array; /** - * Created by gouthamvidyapradhan on 29/03/2019 - * We are given an array A of positive integers, and two positive integers L and R (L <= R). + * Created by gouthamvidyapradhan on 29/03/2019 We are given an array A of positive integers, and + * two positive integers L and R (L <= R). * - * Return the number of (contiguous, non-empty) subarrays such that the value of the maximum array element in that - * subarray is at least L and at most R. + *

Return the number of (contiguous, non-empty) subarrays such that the value of the maximum + * array element in that subarray is at least L and at most R. * - * Example : - * Input: - * A = [2, 1, 4, 3] - * L = 2 - * R = 3 - * Output: 3 - * Explanation: There are three subarrays that meet the requirements: [2], [2, 1], [3]. - * Note: + *

Example : Input: A = [2, 1, 4, 3] L = 2 R = 3 Output: 3 Explanation: There are three subarrays + * that meet the requirements: [2], [2, 1], [3]. Note: * - * L, R and A[i] will be an integer in the range [0, 10^9]. - * The length of A will be in the range of [1, 50000]. + *

L, R and A[i] will be an integer in the range [0, 10^9]. The length of A will be in the range + * of [1, 50000]. */ public class SubArraysWithBoundedMaximum { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int[] A = {2, 1, 4, 3}; - System.out.println(new SubArraysWithBoundedMaximum().numSubarrayBoundedMax(A, 2, 3)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[] A = {2, 1, 4, 3}; + System.out.println(new SubArraysWithBoundedMaximum().numSubarrayBoundedMax(A, 2, 3)); + } - public int numSubarrayBoundedMax(int[] A, int L, int R) { - int[] DP = new int[A.length]; - int v = -1; - for(int i = A.length - 1; i >= 0; i --){ - if(A[i] >= L && A[i] <= R){ - if(v != -1){ - DP[i] = v - i + 1; - } else { - DP[i] = 1; - v = i; - } - } else if(A[i] < L){ - if(v == -1){ - v = i; - } if(i + 1 < A.length){ - if(A[i + 1] < L || (A[i + 1] >= L && A[i + 1] <= R)){ - DP[i] = DP[i + 1]; - } else { - DP[i] = 0; - } - } - } else { - v = -1; - } + public int numSubarrayBoundedMax(int[] A, int L, int R) { + int[] DP = new int[A.length]; + int v = -1; + for (int i = A.length - 1; i >= 0; i--) { + if (A[i] >= L && A[i] <= R) { + if (v != -1) { + DP[i] = v - i + 1; + } else { + DP[i] = 1; + v = i; + } + } else if (A[i] < L) { + if (v == -1) { + v = i; } - int sum = 0; - for(int i = 0; i < DP.length; i ++){ - sum += DP[i]; + if (i + 1 < A.length) { + if (A[i + 1] < L || (A[i + 1] >= L && A[i + 1] <= R)) { + DP[i] = DP[i + 1]; + } else { + DP[i] = 0; + } } - return sum; + } else { + v = -1; + } + } + int sum = 0; + for (int i = 0; i < DP.length; i++) { + sum += DP[i]; } + return sum; + } } diff --git a/problems/src/array/SubarraySumEqualsK.java b/problems/src/array/SubarraySumEqualsK.java index e3ffc753..282c1f80 100644 --- a/problems/src/array/SubarraySumEqualsK.java +++ b/problems/src/array/SubarraySumEqualsK.java @@ -4,61 +4,59 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 03/01/2018. - * Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum - * equals to k. - - Example 1: - Input:nums = [1,1,1], k = 2 - Output: 2 - Note: - The length of the array is in range [1, 20,000]. - The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7]. - - Solution: O(n) Maintain a hash-map of prefix sum and its count and check for range sum for each element. + * Created by gouthamvidyapradhan on 03/01/2018. Given an array of integers and an integer k, you + * need to find the total number of continuous subarrays whose sum equals to k. + * + *

Example 1: Input:nums = [1,1,1], k = 2 Output: 2 Note: The length of the array is in range [1, + * 20,000]. The range of numbers in the array is [-1000, 1000] and the range of the integer k is + * [-1e7, 1e7]. + * + *

Solution: O(n) Maintain a hash-map of prefix sum and its count and check for range sum for + * each element. */ public class SubarraySumEqualsK { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1, 2, 1, -2, 3, -1, -1}; - System.out.println(new SubarraySumEqualsK().subarraySum(A, 2)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 2, 1, -2, 3, -1, -1}; + System.out.println(new SubarraySumEqualsK().subarraySum(A, 2)); + } - public int subarraySum(int[] nums, int k) { - Map map = new HashMap<>(); - int sum = 0; - for(int i : nums){ - sum += i; - Integer count = map.get(sum); - if(count == null){ - map.put(sum, 1); - } else{ - map.put(sum, count + 1); - } - } - sum = 0; - int result = 0; - for(int i : nums){ - int key = sum + k; - if(map.containsKey(key)){ - int count = map.get(key); - result += count; - } - sum += i; - if(map.containsKey(sum)){ - int count = map.get(sum); - if(count - 1 > 0){ - map.put(sum, count - 1); - } else{ - map.remove(sum); - } - } + public int subarraySum(int[] nums, int k) { + Map map = new HashMap<>(); + int sum = 0; + for (int i : nums) { + sum += i; + Integer count = map.get(sum); + if (count == null) { + map.put(sum, 1); + } else { + map.put(sum, count + 1); + } + } + sum = 0; + int result = 0; + for (int i : nums) { + int key = sum + k; + if (map.containsKey(key)) { + int count = map.get(key); + result += count; + } + sum += i; + if (map.containsKey(sum)) { + int count = map.get(sum); + if (count - 1 > 0) { + map.put(sum, count - 1); + } else { + map.remove(sum); } - return result; + } } + return result; + } } diff --git a/problems/src/array/SurfaceAreaOfThreeDShapes.java b/problems/src/array/SurfaceAreaOfThreeDShapes.java index 44a661d6..2f35ef3d 100644 --- a/problems/src/array/SurfaceAreaOfThreeDShapes.java +++ b/problems/src/array/SurfaceAreaOfThreeDShapes.java @@ -1,82 +1,69 @@ package array; /** - * Created by gouthamvidyapradhan on 30/04/2019 - * On a N * N grid, we place some 1 * 1 * 1 cubes. + * Created by gouthamvidyapradhan on 30/04/2019 On a N * N grid, we place some 1 * 1 * 1 cubes. * - * Each value v = grid[i][j] represents a tower of v cubes placed on top of grid cell (i, j). + *

Each value v = grid[i][j] represents a tower of v cubes placed on top of grid cell (i, j). * - * Return the total surface area of the resulting shapes. + *

Return the total surface area of the resulting shapes. * + *

Example 1: * + *

Input: [[2]] Output: 10 Example 2: * - * Example 1: + *

Input: [[1,2],[3,4]] Output: 34 Example 3: * - * Input: [[2]] - * Output: 10 - * Example 2: + *

Input: [[1,0],[0,2]] Output: 16 Example 4: * - * Input: [[1,2],[3,4]] - * Output: 34 - * Example 3: + *

Input: [[1,1,1],[1,0,1],[1,1,1]] Output: 32 Example 5: * - * Input: [[1,0],[0,2]] - * Output: 16 - * Example 4: + *

Input: [[2,2,2],[2,1,2],[2,2,2]] Output: 46 * - * Input: [[1,1,1],[1,0,1],[1,1,1]] - * Output: 32 - * Example 5: + *

Note: * - * Input: [[2,2,2],[2,1,2],[2,2,2]] - * Output: 46 + *

1 <= N <= 50 0 <= grid[i][j] <= 50 * - * - * Note: - * - * 1 <= N <= 50 - * 0 <= grid[i][j] <= 50 - * - * Solution: O(N x M) For each cell, check each adjacent cell and sum the value of (current cell - adjacent cell) - * if the current cell value is greater than adjacent cell. - * For every cell which has value grater then 0, the top surface area is by default 1 therefore add one to - * the sum of each cell. + *

Solution: O(N x M) For each cell, check each adjacent cell and sum the value of (current cell + * - adjacent cell) if the current cell value is greater than adjacent cell. For every cell which + * has value grater then 0, the top surface area is by default 1 therefore add one to the sum of + * each cell. */ public class SurfaceAreaOfThreeDShapes { - private final int[] R = {0, 0, -1, 1}; - private final int[] C = {1, -1, 0, 0}; - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int[][] A = {{2}}; - System.out.println(new SurfaceAreaOfThreeDShapes().surfaceArea(A)); - } + private final int[] R = {0, 0, -1, 1}; + private final int[] C = {1, -1, 0, 0}; + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[][] A = {{2}}; + System.out.println(new SurfaceAreaOfThreeDShapes().surfaceArea(A)); + } - public int surfaceArea(int[][] grid) { - int sum = 0; - for(int i = 0; i < grid.length; i ++){ - for(int j = 0; j < grid[i].length; j ++){ - int cell = grid[i][j]; - for(int k = 0; k < 4; k ++){ - int newR = i + R[k]; - int newC = j + C[k]; - if(newR >= 0 && newC >= 0 && newR < grid.length && newC < grid[0].length){ - int adjacent = grid[newR][newC]; - if(cell > adjacent){ - sum += (cell - adjacent); - } - } else if(newR < 0 || newR >= grid.length || newC < 0 || newC >= grid[0].length){ - sum += cell; - } - } - if(cell > 0){ - sum += 2; - } + public int surfaceArea(int[][] grid) { + int sum = 0; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[i].length; j++) { + int cell = grid[i][j]; + for (int k = 0; k < 4; k++) { + int newR = i + R[k]; + int newC = j + C[k]; + if (newR >= 0 && newC >= 0 && newR < grid.length && newC < grid[0].length) { + int adjacent = grid[newR][newC]; + if (cell > adjacent) { + sum += (cell - adjacent); } + } else if (newR < 0 || newR >= grid.length || newC < 0 || newC >= grid[0].length) { + sum += cell; + } + } + if (cell > 0) { + sum += 2; } - return sum; + } } + return sum; + } } diff --git a/problems/src/array/ThirdMaximumNumber.java b/problems/src/array/ThirdMaximumNumber.java index 3de8137b..59259b33 100644 --- a/problems/src/array/ThirdMaximumNumber.java +++ b/problems/src/array/ThirdMaximumNumber.java @@ -1,62 +1,59 @@ package array; /** - * Created by gouthamvidyapradhan on 25/03/2017. - * Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n). - *

- * Example 1: - * Input: [3, 2, 1] - *

- * Output: 1 - *

- * Explanation: The third maximum is 1. - * Example 2: - * Input: [1, 2] - *

- * Output: 2 - *

- * Explanation: The third maximum does not exist, so the maximum (2) is returned instead. - * Example 3: - * Input: [2, 2, 3, 1] - *

- * Output: 1 - *

- * Explanation: Note that the third maximum here means the third maximum distinct number. - * Both numbers with value 2 are both considered as second maximum. + * Created by gouthamvidyapradhan on 25/03/2017. Given a non-empty array of integers, return the + * third maximum number in this array. If it does not exist, return the maximum number. The time + * complexity must be in O(n). + * + *

Example 1: Input: [3, 2, 1] + * + *

Output: 1 + * + *

Explanation: The third maximum is 1. Example 2: Input: [1, 2] + * + *

Output: 2 + * + *

Explanation: The third maximum does not exist, so the maximum (2) is returned instead. Example + * 3: Input: [2, 2, 3, 1] + * + *

Output: 1 + * + *

Explanation: Note that the third maximum here means the third maximum distinct number. Both + * numbers with value 2 are both considered as second maximum. */ public class ThirdMaximumNumber { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] a = {1, 2}; - System.out.println(new ThirdMaximumNumber().thirdMax(a)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] a = {1, 2}; + System.out.println(new ThirdMaximumNumber().thirdMax(a)); + } - public int thirdMax(int[] nums) { - long[] max = {Long.MIN_VALUE, Long.MIN_VALUE, Long.MIN_VALUE}; - int count = 0; - for (int num : nums) { - for (int j = 0; j < 3; j++) { - if (max[j] > num) continue; - else if (max[j] == num) break; - int k = j; - long temp1, temp2; - temp1 = num; - count++; - while (k < 3) { - temp2 = max[k]; - max[k] = temp1; - temp1 = temp2; - k++; - } - break; - } + public int thirdMax(int[] nums) { + long[] max = {Long.MIN_VALUE, Long.MIN_VALUE, Long.MIN_VALUE}; + int count = 0; + for (int num : nums) { + for (int j = 0; j < 3; j++) { + if (max[j] > num) continue; + else if (max[j] == num) break; + int k = j; + long temp1, temp2; + temp1 = num; + count++; + while (k < 3) { + temp2 = max[k]; + max[k] = temp1; + temp1 = temp2; + k++; } - System.out.println(Integer.MIN_VALUE); - return (count >= 3) ? (int) max[2] : (int) max[0]; + break; + } } + System.out.println(Integer.MIN_VALUE); + return (count >= 3) ? (int) max[2] : (int) max[0]; + } } diff --git a/problems/src/array/TwoSum.java b/problems/src/array/TwoSum.java index 1333f950..546b04ff 100644 --- a/problems/src/array/TwoSum.java +++ b/problems/src/array/TwoSum.java @@ -4,61 +4,59 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 11/07/2017. - * Given an array of integers, return indices of the two numbers such that they add up to a specific target. - *

- * You may assume that each input would have exactly one solution, and you may not use the same element twice. - *

- * Example: - * Given nums = [2, 7, 11, 15], target = 9, - *

- * Because nums[0] + nums[1] = 2 + 7 = 9, - * return [0, 1]. - *

- * Solution: O(n log n). Wrap index and element in a class and sort in increasing order. Do a two pointer sum and compare. - * An alternative solution is to use hashing which is a O(n) solution - For each element e check if element (target - e) - * is already found in hashset, if yes return their index, else add this to hash-set and continue. + * Created by gouthamvidyapradhan on 11/07/2017. Given an array of integers, return indices of the + * two numbers such that they add up to a specific target. + * + *

You may assume that each input would have exactly one solution, and you may not use the same + * element twice. + * + *

Example: Given nums = [2, 7, 11, 15], target = 9, + * + *

Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1]. + * + *

Solution: O(n log n). Wrap index and element in a class and sort in increasing order. Do a two + * pointer sum and compare. An alternative solution is to use hashing which is a O(n) solution - For + * each element e check if element (target - e) is already found in hashset, if yes return their + * index, else add this to hash-set and continue. */ public class TwoSum { - class NumIndex { - int i, e; + class NumIndex { + int i, e; - NumIndex(int i, int e) { - this.i = i; - this.e = e; - } + NumIndex(int i, int e) { + this.i = i; + this.e = e; } - - public static void main(String[] args) { - int[] nums = {3, 2, 4}; - int[] ans = new TwoSum().twoSum(nums, 6); - for (int i : ans) - System.out.println(i); + } + + public static void main(String[] args) { + int[] nums = {3, 2, 4}; + int[] ans = new TwoSum().twoSum(nums, 6); + for (int i : ans) System.out.println(i); + } + + public int[] twoSum(int[] nums, int target) { + List list = new ArrayList<>(); + for (int i = 0; i < nums.length; i++) { + NumIndex n = new NumIndex(i, nums[i]); + list.add(n); } - - public int[] twoSum(int[] nums, int target) { - List list = new ArrayList<>(); - for (int i = 0; i < nums.length; i++) { - NumIndex n = new NumIndex(i, nums[i]); - list.add(n); - } - list.sort((o1, o2) -> Integer.compare(o1.e, o2.e)); - - int[] ans = new int[2]; - for (int i = 0, j = nums.length - 1; i < j; ) { - NumIndex numi = list.get(i); - NumIndex numj = list.get(j); - int sum = numi.e + numj.e; - if (sum == target) { - ans[0] = numi.i; - ans[1] = numj.i; - return ans; - } else if (sum > target) { - j--; - } else i++; - } + list.sort((o1, o2) -> Integer.compare(o1.e, o2.e)); + + int[] ans = new int[2]; + for (int i = 0, j = nums.length - 1; i < j; ) { + NumIndex numi = list.get(i); + NumIndex numj = list.get(j); + int sum = numi.e + numj.e; + if (sum == target) { + ans[0] = numi.i; + ans[1] = numj.i; return ans; + } else if (sum > target) { + j--; + } else i++; } - + return ans; + } } diff --git a/problems/src/array/TwoSumII.java b/problems/src/array/TwoSumII.java index d8a338d7..b7a3fe3c 100644 --- a/problems/src/array/TwoSumII.java +++ b/problems/src/array/TwoSumII.java @@ -1,45 +1,43 @@ package array; /** - * Created by gouthamvidyapradhan on 18/03/2017. - * Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. - *

- * The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based. - *

- * You may assume that each input would have exactly one solution and you may not use the same element twice. - *

- * Input: numbers={2, 7, 11, 15}, target=9 - * Output: index1=1, index2=2 + * Created by gouthamvidyapradhan on 18/03/2017. Given an array of integers that is already sorted + * in ascending order, find two numbers such that they add up to a specific target number. + * + *

The function twoSum should return indices of the two numbers such that they add up to the + * target, where index1 must be less than index2. Please note that your returned answers (both + * index1 and index2) are not zero-based. + * + *

You may assume that each input would have exactly one solution and you may not use the same + * element twice. + * + *

Input: numbers={2, 7, 11, 15}, target=9 Output: index1=1, index2=2 */ public class TwoSumII { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] nums = {2, 7, 11, 15}; - int[] result = new TwoSumII().twoSum(nums, 23); - for (int i : result) - System.out.println(i); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] nums = {2, 7, 11, 15}; + int[] result = new TwoSumII().twoSum(nums, 23); + for (int i : result) System.out.println(i); + } - public int[] twoSum(int[] numbers, int target) { - int i = 0, j = numbers.length - 1; - while (i < j) { - int x = (numbers[i] + numbers[j]); - if (x == target) { - int[] result = new int[2]; - result[0] = i + 1; - result[1] = j + 1; - return result; - } else if (x < target) - i++; - else j--; - } - return new int[2]; + public int[] twoSum(int[] numbers, int target) { + int i = 0, j = numbers.length - 1; + while (i < j) { + int x = (numbers[i] + numbers[j]); + if (x == target) { + int[] result = new int[2]; + result[0] = i + 1; + result[1] = j + 1; + return result; + } else if (x < target) i++; + else j--; } - - + return new int[2]; + } } diff --git a/problems/src/array/ValidTicTacToeState.java b/problems/src/array/ValidTicTacToeState.java index d2c20820..6d2fa83c 100644 --- a/problems/src/array/ValidTicTacToeState.java +++ b/problems/src/array/ValidTicTacToeState.java @@ -1,88 +1,82 @@ package array; /** - * Created by gouthamvidyapradhan on 29/03/2019 - * A Tic-Tac-Toe board is given as a string array board. Return True if and only if it is possible to reach this - * board position during the course of a valid tic-tac-toe game. + * Created by gouthamvidyapradhan on 29/03/2019 A Tic-Tac-Toe board is given as a string array + * board. Return True if and only if it is possible to reach this board position during the course + * of a valid tic-tac-toe game. * - * The board is a 3 x 3 array, and consists of characters " ", "X", and "O". The " " character represents an empty - * square. + *

The board is a 3 x 3 array, and consists of characters " ", "X", and "O". The " " character + * represents an empty square. * - * Here are the rules of Tic-Tac-Toe: + *

Here are the rules of Tic-Tac-Toe: * - * Players take turns placing characters into empty squares (" "). - * The first player always places "X" characters, while the second player always places "O" characters. - * "X" and "O" characters are always placed into empty squares, never filled ones. - * The game ends when there are 3 of the same (non-empty) character filling any row, column, or diagonal. - * The game also ends if all squares are non-empty. - * No more moves can be played if the game is over. - * Example 1: - * Input: board = ["O ", " ", " "] - * Output: false - * Explanation: The first player always plays "X". + *

Players take turns placing characters into empty squares (" "). The first player always places + * "X" characters, while the second player always places "O" characters. "X" and "O" characters are + * always placed into empty squares, never filled ones. The game ends when there are 3 of the same + * (non-empty) character filling any row, column, or diagonal. The game also ends if all squares are + * non-empty. No more moves can be played if the game is over. Example 1: Input: board = ["O ", " ", + * " "] Output: false Explanation: The first player always plays "X". * - * Example 2: - * Input: board = ["XOX", " X ", " "] - * Output: false - * Explanation: Players take turns making moves. + *

Example 2: Input: board = ["XOX", " X ", " "] Output: false Explanation: Players take turns + * making moves. * - * Example 3: - * Input: board = ["XXX", " ", "OOO"] - * Output: false + *

Example 3: Input: board = ["XXX", " ", "OOO"] Output: false * - * Example 4: - * Input: board = ["XOX", "O O", "XOX"] - * Output: true - * Note: + *

Example 4: Input: board = ["XOX", "O O", "XOX"] Output: true Note: * - * board is a length-3 array of strings, where each string board[i] has length 3. - * Each board[i][j] is a character in the set {" ", "X", "O"}. + *

board is a length-3 array of strings, where each string board[i] has length 3. Each + * board[i][j] is a character in the set {" ", "X", "O"}. * - * Solution: Do a brute-force check for each row, column and diagonals and keep track of count of 'X' and 'O' + *

Solution: Do a brute-force check for each row, column and diagonals and keep track of count of + * 'X' and 'O' */ public class ValidTicTacToeState { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - String[] board = {"XXX", "XOO", "OO "}; - System.out.println(new ValidTicTacToeState().validTicTacToe(board)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + String[] board = {"XXX", "XOO", "OO "}; + System.out.println(new ValidTicTacToeState().validTicTacToe(board)); + } - public boolean validTicTacToe(String[] board) { - boolean xWon = hasWon(board, 'X'); - boolean oWon = hasWon(board, 'O'); - int xcount = 0, ocount = 0; - for(int i = 0; i < 3; i ++){ - for(int j = 0; j < 3; j ++){ - if(board[i].charAt(j) == 'X'){ - xcount++; - }else if(board[i].charAt(j) == 'O'){ - ocount++; - } - } - } - if(xWon && oWon) return false; - if(xWon){ - return ((xcount - 1 == ocount)); - } else if(oWon){ - return ((xcount == ocount)); - } else { - return (xcount == ocount || xcount - 1 == ocount); + public boolean validTicTacToe(String[] board) { + boolean xWon = hasWon(board, 'X'); + boolean oWon = hasWon(board, 'O'); + int xcount = 0, ocount = 0; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + if (board[i].charAt(j) == 'X') { + xcount++; + } else if (board[i].charAt(j) == 'O') { + ocount++; } + } + } + if (xWon && oWon) return false; + if (xWon) { + return ((xcount - 1 == ocount)); + } else if (oWon) { + return ((xcount == ocount)); + } else { + return (xcount == ocount || xcount - 1 == ocount); } + } - private boolean hasWon(String[] board, char c){ - boolean diagnol = ((board[0].charAt(0) == c && board[1].charAt(1) == c && board[2].charAt(2) == c) || - (board[0].charAt(2) == c && board[1].charAt(1) == c && board[2].charAt(0) == c)); - if(diagnol) return true; - for(int i = 0; i < 3; i ++){ - if(board[i].charAt(0) == c && board[i].charAt(1) == c && board[i].charAt(2) == c) return true; - } - for(int i = 0; i < 3; i ++){ - if(board[0].charAt(i) == c && board[1].charAt(i) == c && board[2].charAt(i) == c) return true; - } - return false; + private boolean hasWon(String[] board, char c) { + boolean diagnol = + ((board[0].charAt(0) == c && board[1].charAt(1) == c && board[2].charAt(2) == c) + || (board[0].charAt(2) == c && board[1].charAt(1) == c && board[2].charAt(0) == c)); + if (diagnol) return true; + for (int i = 0; i < 3; i++) { + if (board[i].charAt(0) == c && board[i].charAt(1) == c && board[i].charAt(2) == c) + return true; + } + for (int i = 0; i < 3; i++) { + if (board[0].charAt(i) == c && board[1].charAt(i) == c && board[2].charAt(i) == c) + return true; } + return false; + } } diff --git a/problems/src/backtracking/CombinationSum.java b/problems/src/backtracking/CombinationSum.java index b9c87cbe..0ec28dc3 100644 --- a/problems/src/backtracking/CombinationSum.java +++ b/problems/src/backtracking/CombinationSum.java @@ -4,53 +4,52 @@ import java.util.List; /** - * Created by pradhang on 3/14/2017. - * Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. - *

- * The same repeated number may be chosen from C unlimited number of times. - *

- * Note: - * All numbers (including target) will be positive integers. - * The solution set must not contain duplicate combinations. - * For example, given candidate set [2, 3, 6, 7] and target 7, - * A solution set is: - * [ - * [7], - * [2, 2, 3] - * ] + * Created by pradhang on 3/14/2017. Given a set of candidate numbers (C) (without duplicates) and a + * target number (T), find all unique combinations in C where the candidate numbers sums to T. + * + *

The same repeated number may be chosen from C unlimited number of times. + * + *

Note: All numbers (including target) will be positive integers. The solution set must not + * contain duplicate combinations. For example, given candidate set [2, 3, 6, 7] and target 7, A + * solution set is: [ [7], [2, 2, 3] ] */ public class CombinationSum { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] candidates = {2, 3, 6, 7}; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] candidates = {2, 3, 6, 7}; - List> result = new CombinationSum().combinationSum(candidates, 7); - } + List> result = new CombinationSum().combinationSum(candidates, 7); + } - public List> combinationSum(int[] candidates, int target) { - List> result = new ArrayList<>(); - List subList = new ArrayList<>(); - doNext(0, result, 0, candidates, target, subList); - return result; - } + public List> combinationSum(int[] candidates, int target) { + List> result = new ArrayList<>(); + List subList = new ArrayList<>(); + doNext(0, result, 0, candidates, target, subList); + return result; + } - private void doNext(int i, List> result, int count, int[] candidates, int target, List subArr) { - if (target == 0) { - List subList = new ArrayList<>(); - for (int k = 0; k < count; k++) - subList.add(subArr.get(k)); - result.add(subList); - } else if (target > 0) { - for (int j = i, l = candidates.length; j < l; j++) { - subArr.add(candidates[j]); - doNext(j, result, count + 1, candidates, target - candidates[j], subArr); - subArr.remove(subArr.size() - 1); - } - } + private void doNext( + int i, + List> result, + int count, + int[] candidates, + int target, + List subArr) { + if (target == 0) { + List subList = new ArrayList<>(); + for (int k = 0; k < count; k++) subList.add(subArr.get(k)); + result.add(subList); + } else if (target > 0) { + for (int j = i, l = candidates.length; j < l; j++) { + subArr.add(candidates[j]); + doNext(j, result, count + 1, candidates, target - candidates[j], subArr); + subArr.remove(subArr.size() - 1); + } } + } } diff --git a/problems/src/backtracking/CombinationSumII.java b/problems/src/backtracking/CombinationSumII.java index 857137ce..30fd2d20 100644 --- a/problems/src/backtracking/CombinationSumII.java +++ b/problems/src/backtracking/CombinationSumII.java @@ -5,53 +5,45 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 14/03/2017. - * Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. - *

- * Each number in C may only be used once in the combination. - *

- * Note: - * All numbers (including target) will be positive integers. - * The solution set must not contain duplicate combinations. - * For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8, - * A solution set is: - * [ - * [1, 7], - * [1, 2, 5], - * [2, 6], - * [1, 1, 6] - * ] + * Created by gouthamvidyapradhan on 14/03/2017. Given a collection of candidate numbers (C) and a + * target number (T), find all unique combinations in C where the candidate numbers sums to T. + * + *

Each number in C may only be used once in the combination. + * + *

Note: All numbers (including target) will be positive integers. The solution set must not + * contain duplicate combinations. For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and + * target 8, A solution set is: [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ] */ - public class CombinationSumII { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] candidates = {1, 1, 2, 2}; - List> result = new CombinationSumII().combinationSum2(candidates, 4); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] candidates = {1, 1, 2, 2}; + List> result = new CombinationSumII().combinationSum2(candidates, 4); + } - public List> combinationSum2(int[] candidates, int target) { - Arrays.sort(candidates); - List> result = new ArrayList<>(); - combination(0, target, candidates, new ArrayList<>(), result); - return result; - } + public List> combinationSum2(int[] candidates, int target) { + Arrays.sort(candidates); + List> result = new ArrayList<>(); + combination(0, target, candidates, new ArrayList<>(), result); + return result; + } - private void combination(int i, int target, int[] candidates, List row, List> result) { - if (target == 0) { - result.add(new ArrayList<>(row)); - } else if (target > 0) { - for (int j = i, l = candidates.length; j < l; j++) { - if (j > i && candidates[j] == candidates[j - 1]) continue; - row.add(candidates[j]); - combination(j + 1, target - candidates[j], candidates, row, result); - row.remove(row.size() - 1); - } - } + private void combination( + int i, int target, int[] candidates, List row, List> result) { + if (target == 0) { + result.add(new ArrayList<>(row)); + } else if (target > 0) { + for (int j = i, l = candidates.length; j < l; j++) { + if (j > i && candidates[j] == candidates[j - 1]) continue; + row.add(candidates[j]); + combination(j + 1, target - candidates[j], candidates, row, result); + row.remove(row.size() - 1); + } } + } } diff --git a/problems/src/backtracking/Combinations.java b/problems/src/backtracking/Combinations.java index 1d1c2ded..625ed94e 100644 --- a/problems/src/backtracking/Combinations.java +++ b/problems/src/backtracking/Combinations.java @@ -4,46 +4,36 @@ import java.util.List; /** - * Created by pradhang on 3/8/2017. - * Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. - *

- * For example, - * If n = 4 and k = 2, a solution is: - *

- * [ - * [2,4], - * [3,4], - * [2,3], - * [1,2], - * [1,3], - * [1,4], - * ] + * Created by pradhang on 3/8/2017. Given two integers n and k, return all possible combinations of + * k numbers out of 1 ... n. + * + *

For example, If n = 4 and k = 2, a solution is: + * + *

[ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ] */ public class Combinations { - public static void main(String[] args) throws Exception { - List> result = new Combinations().combine(3, 3); - } + public static void main(String[] args) throws Exception { + List> result = new Combinations().combine(3, 3); + } - public List> combine(int n, int k) { - int[] subArr = new int[k]; - List> result = new ArrayList<>(); - getNext(0, 0, n, k, subArr, result); - return result; - } + public List> combine(int n, int k) { + int[] subArr = new int[k]; + List> result = new ArrayList<>(); + getNext(0, 0, n, k, subArr, result); + return result; + } - private void getNext(int i, int count, - int n, int k, int[] subArr, List> result) { - if (k == 0) { - List subList = new ArrayList<>(); - for (int a : subArr) - subList.add(a); - result.add(subList); - } else { - for (int j = i + 1; j <= n; j++) { - subArr[count] = j; - getNext(j, count + 1, n, k - 1, subArr, result); - } - } + private void getNext(int i, int count, int n, int k, int[] subArr, List> result) { + if (k == 0) { + List subList = new ArrayList<>(); + for (int a : subArr) subList.add(a); + result.add(subList); + } else { + for (int j = i + 1; j <= n; j++) { + subArr[count] = j; + getNext(j, count + 1, n, k - 1, subArr, result); + } } + } } diff --git a/problems/src/backtracking/ExpressionAddOperators.java b/problems/src/backtracking/ExpressionAddOperators.java index e057400e..1a61b49e 100644 --- a/problems/src/backtracking/ExpressionAddOperators.java +++ b/problems/src/backtracking/ExpressionAddOperators.java @@ -4,67 +4,68 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 05/12/2017. - * Given a string that contains only digits 0-9 and a target value, return all possibilities to add binary operators - * (not unary) +, -, or * between the digits so they evaluate to the target value. - - Examples: - "123", 6 -> ["1+2+3", "1*2*3"] - "232", 8 -> ["2*3+2", "2+3*2"] - "105", 5 -> ["1*0+5","10-5"] - "00", 0 -> ["0+0", "0-0", "0*0"] - "3456237490", 9191 -> [] - - Solution: Backtrack and keep track of the total and product value. - In case of + or - add/sub curr to total and curr becomes the new product - In case of * take difference of total and prod and add (product of curr value with previous product and make this a - new product for the next iteration) - - Worst-case time complexity can be O(n * (2^n-1)) + * Created by gouthamvidyapradhan on 05/12/2017. Given a string that contains only digits 0-9 and a + * target value, return all possibilities to add binary operators (not unary) +, -, or * between the + * digits so they evaluate to the target value. + * + *

Examples: "123", 6 -> ["1+2+3", "1*2*3"] "232", 8 -> ["2*3+2", "2+3*2"] "105", 5 -> + * ["1*0+5","10-5"] "00", 0 -> ["0+0", "0-0", "0*0"] "3456237490", 9191 -> [] + * + *

Solution: Backtrack and keep track of the total and product value. In case of + or - add/sub + * curr to total and curr becomes the new product In case of * take difference of total and prod and + * add (product of curr value with previous product and make this a new product for the next + * iteration) + * + *

Worst-case time complexity can be O(n * (2^n-1)) */ public class ExpressionAddOperators { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - List result = new ExpressionAddOperators().addOperators("202010201", 201); - result.stream().forEach(System.out::println); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + List result = new ExpressionAddOperators().addOperators("202010201", 201); + result.stream().forEach(System.out::println); + } - public List addOperators(String num, int target) { - List result = new ArrayList<>(); - backTrack("", result, 0, num, target, 0L, 0L); - return result; - } + public List addOperators(String num, int target) { + List result = new ArrayList<>(); + backTrack("", result, 0, num, target, 0L, 0L); + return result; + } - private void backTrack(String exp, List list, int curr, String num, int target, long total, - long prod){ - if(curr == num.length()){ - if(total == target){ - list.add(exp); - } + private void backTrack( + String exp, List list, int curr, String num, int target, long total, long prod) { + if (curr == num.length()) { + if (total == target) { + list.add(exp); + } + } else { + for (int i = curr, l = num.length(); i < l; i++) { + String newNum = num.substring(curr, i + 1); + if (newNum.length() > 1 && newNum.startsWith("0")) { + break; } - else { - for(int i = curr, l = num.length(); i < l; i ++){ - String newNum = num.substring(curr, i + 1); - if(newNum.length() > 1 && newNum.startsWith("0")) { - break; - } - long newNumL = Long.parseLong(newNum); - if(curr == 0){ - backTrack(newNum, list, i + 1, num, target, newNumL, newNumL); - } else { - backTrack(exp + "+" + newNum, list, i + 1, num, target, total + newNumL, newNumL); + long newNumL = Long.parseLong(newNum); + if (curr == 0) { + backTrack(newNum, list, i + 1, num, target, newNumL, newNumL); + } else { + backTrack(exp + "+" + newNum, list, i + 1, num, target, total + newNumL, newNumL); - backTrack(exp + "-" + newNum, list, i + 1, num, target, total - newNumL, newNumL * -1L); + backTrack(exp + "-" + newNum, list, i + 1, num, target, total - newNumL, newNumL * -1L); - backTrack(exp + "*" + newNum, list, i + 1, num, target, (total - prod + (prod * newNumL)), prod - * newNumL); - } - } + backTrack( + exp + "*" + newNum, + list, + i + 1, + num, + target, + (total - prod + (prod * newNumL)), + prod * newNumL); } + } } - + } } diff --git a/problems/src/backtracking/GenerateParentheses.java b/problems/src/backtracking/GenerateParentheses.java index 5c20329c..9d61c2a3 100644 --- a/problems/src/backtracking/GenerateParentheses.java +++ b/problems/src/backtracking/GenerateParentheses.java @@ -4,38 +4,33 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 24/06/2017. - * Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. - *

- * For example, given n = 3, a solution set is: - *

- * [ - * "((()))", - * "(()())", - * "(())()", - * "()(())", - * "()()()" - * ] + * Created by gouthamvidyapradhan on 24/06/2017. Given n pairs of parentheses, write a function to + * generate all combinations of well-formed parentheses. + * + *

For example, given n = 3, a solution set is: + * + *

[ "((()))", "(()())", "(())()", "()(())", "()()()" ] */ public class GenerateParentheses { - public static void main(String[] args) throws Exception { - System.out.println(new GenerateParentheses().generateParenthesis(4)); - } + public static void main(String[] args) throws Exception { + System.out.println(new GenerateParentheses().generateParenthesis(4)); + } - public List generateParenthesis(int n) { - List list = new ArrayList<>(); - backTrack(list, "", 0, 0, n); - return list; - } + public List generateParenthesis(int n) { + List list = new ArrayList<>(); + backTrack(list, "", 0, 0, n); + return list; + } - private void backTrack(List list, String str, int open, int close, int n) { - if (str.length() == n * 2) { - list.add(str); - } else { - if (open < n) - backTrack(list, str.concat("("), open + 1, close, n); - if (close < open) //number of close should be less than open or else it can result in unbalanced parentheses - backTrack(list, str.concat(")"), open, close + 1, n); - } + private void backTrack(List list, String str, int open, int close, int n) { + if (str.length() == n * 2) { + list.add(str); + } else { + if (open < n) backTrack(list, str.concat("("), open + 1, close, n); + if (close + < open) // number of close should be less than open or else it can result in unbalanced + // parentheses + backTrack(list, str.concat(")"), open, close + 1, n); } + } } diff --git a/problems/src/backtracking/LetterCasePermutation.java b/problems/src/backtracking/LetterCasePermutation.java index 9ec9bf06..b5b09c56 100644 --- a/problems/src/backtracking/LetterCasePermutation.java +++ b/problems/src/backtracking/LetterCasePermutation.java @@ -4,58 +4,52 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 12/04/2018. - * Given a string S, we can transform every letter individually to be lowercase or uppercase to create another string. - * Return a list of all possible strings we could create. - *

- * Examples: - * Input: S = "a1b2" - * Output: ["a1b2", "a1B2", "A1b2", "A1B2"] - *

- * Input: S = "3z4" - * Output: ["3z4", "3Z4"] - *

- * Input: S = "12345" - * Output: ["12345"] - * Note: - *

- * S will be a string with length at most 12. - * S will consist only of letters or digits. + * Created by gouthamvidyapradhan on 12/04/2018. Given a string S, we can transform every letter + * individually to be lowercase or uppercase to create another string. Return a list of all possible + * strings we could create. * - * Solution: O(N x 2 ^ N) Backtrack and generate all possible combinations. + *

Examples: Input: S = "a1b2" Output: ["a1b2", "a1B2", "A1b2", "A1B2"] + * + *

Input: S = "3z4" Output: ["3z4", "3Z4"] + * + *

Input: S = "12345" Output: ["12345"] Note: + * + *

S will be a string with length at most 12. S will consist only of letters or digits. + * + *

Solution: O(N x 2 ^ N) Backtrack and generate all possible combinations. */ public class LetterCasePermutation { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new LetterCasePermutation().letterCasePermutation("a1b2")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new LetterCasePermutation().letterCasePermutation("a1b2")); + } - public List letterCasePermutation(String S) { - List result = new ArrayList<>(); - backtrack(S, result, 0, ""); - return result; - } + public List letterCasePermutation(String S) { + List result = new ArrayList<>(); + backtrack(S, result, 0, ""); + return result; + } - private void backtrack(String s, List result, int i, String r) { - if (i == s.length()) { - result.add(r); + private void backtrack(String s, List result, int i, String r) { + if (i == s.length()) { + result.add(r); + } else { + if (Character.isAlphabetic(s.charAt(i))) { + backtrack(s, result, i + 1, r + s.charAt(i)); + if (Character.isLowerCase(s.charAt(i))) { + backtrack(s, result, i + 1, r + Character.toUpperCase(s.charAt(i))); } else { - if (Character.isAlphabetic(s.charAt(i))) { - backtrack(s, result, i + 1, r + s.charAt(i)); - if (Character.isLowerCase(s.charAt(i))) { - backtrack(s, result, i + 1, r + Character.toUpperCase(s.charAt(i))); - } else { - backtrack(s, result, i + 1, r + Character.toLowerCase(s.charAt(i))); - } - } else { - backtrack(s, result, i + 1, r + s.charAt(i)); - } + backtrack(s, result, i + 1, r + Character.toLowerCase(s.charAt(i))); } + } else { + backtrack(s, result, i + 1, r + s.charAt(i)); + } } + } } diff --git a/problems/src/backtracking/LetterPhoneNumber.java b/problems/src/backtracking/LetterPhoneNumber.java index dda5d638..b32a09eb 100644 --- a/problems/src/backtracking/LetterPhoneNumber.java +++ b/problems/src/backtracking/LetterPhoneNumber.java @@ -4,52 +4,50 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 09/03/2017. - * Given a digit string, return all possible letter combinations that the number could represent. + * Created by gouthamvidyapradhan on 09/03/2017. Given a digit string, return all possible letter + * combinations that the number could represent. + * + *

A mapping of digit to letters (just like on the telephone buttons) is given below. 1 2(abc) + * 3(def) 4(ghi) 5(jkl) 6(mno) 7(pqrs) 8(tuv) 9(wxyz) + * *

- * A mapping of digit to letters (just like on the telephone buttons) is given below. - * 1 2(abc) 3(def) - * 4(ghi) 5(jkl) 6(mno) - * 7(pqrs) 8(tuv) 9(wxyz) - *

- *

- * Input:Digit string "23" - * Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. - * Note: - * Although the above answer is in lexicographical order, your answer could be in any order you want. + * + *

Input:Digit string "23" Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. Note: + * Although the above answer is in lexicographical order, your answer could be in any order you + * want. */ public class LetterPhoneNumber { - private String[] NUMBER_ALPHA = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; + private String[] NUMBER_ALPHA = { + "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" + }; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - List result = new LetterPhoneNumber().letterCombinations("23"); - result.forEach(System.out::println); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + List result = new LetterPhoneNumber().letterCombinations("23"); + result.forEach(System.out::println); + } - private List letterCombinations(String digits) { - if (digits == null || digits.isEmpty() || digits.contains("1") || digits.contains("0")) - return new ArrayList<>(); - List prev = new ArrayList<>(); - prev.add(""); - for (int i = digits.length() - 1; i >= 0; i--) { - String str = NUMBER_ALPHA[Integer.parseInt(String.valueOf(digits.charAt(i)))]; - List newList = new ArrayList<>(); - for (int j = 0, l = str.length(); j < l; j++) { - for (String s : prev) { - s = str.charAt(j) + s; - newList.add(s); - } - } - prev = newList; + private List letterCombinations(String digits) { + if (digits == null || digits.isEmpty() || digits.contains("1") || digits.contains("0")) + return new ArrayList<>(); + List prev = new ArrayList<>(); + prev.add(""); + for (int i = digits.length() - 1; i >= 0; i--) { + String str = NUMBER_ALPHA[Integer.parseInt(String.valueOf(digits.charAt(i)))]; + List newList = new ArrayList<>(); + for (int j = 0, l = str.length(); j < l; j++) { + for (String s : prev) { + s = str.charAt(j) + s; + newList.add(s); } - return prev; + } + prev = newList; } - - + return prev; + } } diff --git a/problems/src/backtracking/PalindromePartitioning.java b/problems/src/backtracking/PalindromePartitioning.java index 822d1fd8..b3718570 100644 --- a/problems/src/backtracking/PalindromePartitioning.java +++ b/problems/src/backtracking/PalindromePartitioning.java @@ -4,60 +4,55 @@ import java.util.List; /** - * Created by pradhang on 3/15/2017. - * Given a string s, partition s such that every substring of the partition is a palindrome. - *

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

- * For example, given s = "aab", - * Return - *

- * [ - * ["aa","b"], - * ["a","a","b"] - * ] + * Created by pradhang on 3/15/2017. Given a string s, partition s such that every substring of the + * partition is a palindrome. + * + *

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

For example, given s = "aab", Return + * + *

[ ["aa","b"], ["a","a","b"] ] */ public class PalindromePartitioning { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - List> result = new PalindromePartitioning().partition("aaaaaaaaaaaaaaaaaa"); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + List> result = new PalindromePartitioning().partition("aaaaaaaaaaaaaaaaaa"); + } - public List> partition(String s) { - List> result = new ArrayList<>(); - doNext(0, new ArrayList<>(), s, result); - return result; - } + public List> partition(String s) { + List> result = new ArrayList<>(); + doNext(0, new ArrayList<>(), s, result); + return result; + } - private void doNext(int i, List row, String s, List> result) { - if (i == s.length()) { - List list = new ArrayList<>(row); - result.add(list); - } else { - for (int j = i, l = s.length(); j < l; j++) { - String sbStr = s.substring(i, j + 1); - if (isPalindrome(sbStr)) { - row.add(sbStr); - doNext(j + 1, row, s, result); - row.remove(row.size() - 1); - } - } + private void doNext(int i, List row, String s, List> result) { + if (i == s.length()) { + List list = new ArrayList<>(row); + result.add(list); + } else { + for (int j = i, l = s.length(); j < l; j++) { + String sbStr = s.substring(i, j + 1); + if (isPalindrome(sbStr)) { + row.add(sbStr); + doNext(j + 1, row, s, result); + row.remove(row.size() - 1); } + } } + } - private boolean isPalindrome(String s) { - int i = 0, j = s.length() - 1; - while (i <= j) { - if (s.charAt(i) != s.charAt(j)) - return false; - i++; - j--; - } - return true; + private boolean isPalindrome(String s) { + int i = 0, j = s.length() - 1; + while (i <= j) { + if (s.charAt(i) != s.charAt(j)) return false; + i++; + j--; } + return true; + } } diff --git a/problems/src/backtracking/Permutations.java b/problems/src/backtracking/Permutations.java index 5f5ebc32..5509d3d1 100644 --- a/problems/src/backtracking/Permutations.java +++ b/problems/src/backtracking/Permutations.java @@ -4,54 +4,45 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 15/03/2017. - * Given a collection of distinct numbers, return all possible permutations. - *

- * For example, - * [1,2,3] have the following permutations: - * [ - * [1,2,3], - * [1,3,2], - * [2,1,3], - * [2,3,1], - * [3,1,2], - * [3,2,1] - * ] + * Created by gouthamvidyapradhan on 15/03/2017. Given a collection of distinct numbers, return all + * possible permutations. + * + *

For example, [1,2,3] have the following permutations: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], + * [3,1,2], [3,2,1] ] */ public class Permutations { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] nums = {1, 2, 3}; - List> result = new Permutations().permute(nums); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] nums = {1, 2, 3}; + List> result = new Permutations().permute(nums); + } - public List> permute(int[] nums) { - List> result = new ArrayList<>(); - nextPermutation(0, nums, result); - return result; - } + public List> permute(int[] nums) { + List> result = new ArrayList<>(); + nextPermutation(0, nums, result); + return result; + } - private void nextPermutation(int i, int[] nums, List> result) { - if (i == nums.length - 1) { - List list = new ArrayList<>(); - for (int n : nums) - list.add(n); - result.add(list); - } else { - for (int j = i, l = nums.length; j < l; j++) { - int temp = nums[j]; - nums[j] = nums[i]; - nums[i] = temp; - nextPermutation(i + 1, nums, result); - temp = nums[j]; - nums[j] = nums[i]; - nums[i] = temp; - } - } + private void nextPermutation(int i, int[] nums, List> result) { + if (i == nums.length - 1) { + List list = new ArrayList<>(); + for (int n : nums) list.add(n); + result.add(list); + } else { + for (int j = i, l = nums.length; j < l; j++) { + int temp = nums[j]; + nums[j] = nums[i]; + nums[i] = temp; + nextPermutation(i + 1, nums, result); + temp = nums[j]; + nums[j] = nums[i]; + nums[i] = temp; + } } + } } diff --git a/problems/src/backtracking/PermutationsII.java b/problems/src/backtracking/PermutationsII.java index a2656886..27f55f8e 100644 --- a/problems/src/backtracking/PermutationsII.java +++ b/problems/src/backtracking/PermutationsII.java @@ -5,48 +5,41 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 12/04/2017. - * Given a collection of numbers that might contain duplicates, return all possible unique permutations. - *

- * For example, - * [1,1,2] have the following unique permutations: - * [ - * [1,1,2], - * [1,2,1], - * [2,1,1] - * ] + * Created by gouthamvidyapradhan on 12/04/2017. Given a collection of numbers that might contain + * duplicates, return all possible unique permutations. + * + *

For example, [1,1,2] have the following unique permutations: [ [1,1,2], [1,2,1], [2,1,1] ] */ public class PermutationsII { - public static void main(String[] args) { - int[] A = {1, 2, 2}; - System.out.println(new PermutationsII().permuteUnique(A)); - } + public static void main(String[] args) { + int[] A = {1, 2, 2}; + System.out.println(new PermutationsII().permuteUnique(A)); + } - public List> permuteUnique(int[] nums) { - List> result = new ArrayList<>(); - Arrays.sort(nums); - nextPermutation(0, nums, result); - return result; - } + public List> permuteUnique(int[] nums) { + List> result = new ArrayList<>(); + Arrays.sort(nums); + nextPermutation(0, nums, result); + return result; + } - private void nextPermutation(int i, int[] nums, List> result) { - if (i == nums.length - 1) { - List list = new ArrayList<>(); - for (int n : nums) - list.add(n); - result.add(list); - } else { - for (int j = i, l = nums.length; j < l; j++) { - if (j > i && nums[j] == nums[i]) continue; - swap(nums, i, j); - nextPermutation(i + 1, Arrays.copyOf(nums, nums.length), result); - } - } + private void nextPermutation(int i, int[] nums, List> result) { + if (i == nums.length - 1) { + List list = new ArrayList<>(); + for (int n : nums) list.add(n); + result.add(list); + } else { + for (int j = i, l = nums.length; j < l; j++) { + if (j > i && nums[j] == nums[i]) continue; + swap(nums, i, j); + nextPermutation(i + 1, Arrays.copyOf(nums, nums.length), result); + } } + } - private void swap(int[] a, int i, int j) { - int tmp = a[i]; - a[i] = a[j]; - a[j] = tmp; - } + private void swap(int[] a, int i, int j) { + int tmp = a[i]; + a[i] = a[j]; + a[j] = tmp; + } } diff --git a/problems/src/backtracking/RegularExpressionMatching.java b/problems/src/backtracking/RegularExpressionMatching.java index aa98e3ea..0db4538b 100644 --- a/problems/src/backtracking/RegularExpressionMatching.java +++ b/problems/src/backtracking/RegularExpressionMatching.java @@ -3,74 +3,69 @@ /** * Created by gouthamvidyapradhan on 05/12/2017. * - * Implement regular expression matching with support for '.' and '*'. - - '.' Matches any single character. - '*' Matches zero or more of the preceding element. - - The matching should cover the entire input string (not partial). - - The function prototype should be: - bool isMatch(const char *s, const char *p) - - Some examples: - isMatch("aa","a") → false - isMatch("aa","aa") → true - isMatch("aaa","aa") → false - isMatch("aa", "a*") → true - isMatch("aa", ".*") → true - isMatch("ab", ".*") → true - isMatch("aab", "c*a*b") → true - - Solution: When a wildcard is encountered try to match all the possible prefixes including none, otherwise - do a simple one to one match. If the end of string is reached simultaneously in both string and pattern - then return true + *

Implement regular expression matching with support for '.' and '*'. + * + *

'.' Matches any single character. '*' Matches zero or more of the preceding element. + * + *

The matching should cover the entire input string (not partial). + * + *

The function prototype should be: bool isMatch(const char *s, const char *p) + * + *

Some examples: isMatch("aa","a") → false isMatch("aa","aa") → true isMatch("aaa","aa") → false + * isMatch("aa", "a*") → true isMatch("aa", ".*") → true isMatch("ab", ".*") → true isMatch("aab", + * "c*a*b") → true + * + *

Solution: When a wildcard is encountered try to match all the possible prefixes including + * none, otherwise do a simple one to one match. If the end of string is reached simultaneously in + * both string and pattern then return true */ public class RegularExpressionMatching { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new RegularExpressionMatching().isMatch("aa", "a*a*a")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new RegularExpressionMatching().isMatch("aa", "a*a*a")); + } - public boolean isMatch(String s, String p) { - return backTrack(0, 0, s, p); - } + public boolean isMatch(String s, String p) { + return backTrack(0, 0, s, p); + } - private boolean backTrack(int si, int pi, String s, String p){ - if(si >= s.length() && pi >= p.length()) return true; //end of the string has been reached hence return true - else { - if(pi >= p.length()) return false; //pattern has exhausted hence return false - else if(si >= s.length()){ - if(pi + 1 < p.length() && p.charAt(pi + 1) == '*'){ - return backTrack(si, pi + 2, s, p); - } else return false; //string has exhausted and pattern does not contain wildcard hence return false - } - else if(s.charAt(si) == p.charAt(pi) || p.charAt(pi) == '.'){ - if(pi + 1 < p.length() && p.charAt(pi + 1) == '*'){ - //match 0 or more repeated preceding element - if(backTrack(si, pi + 2, s, p)) return true; - for(int i = si, l = s.length(); i < l; i ++){ - if(s.charAt(i) == p.charAt(pi) || p.charAt(pi) == '.'){ - if(backTrack(i + 1, pi + 2, s, p)) return true; - } else { - return false; - } - } - return backTrack(s.length(), pi, s, p); - } else{ - return backTrack(si + 1, pi + 1, s, p); //not wildcard match immediate chars - } - } else{ - if(pi + 1 < p.length() && p.charAt(pi + 1) == '*'){ - return backTrack(si, pi + 2, s, p); - } else return false; + private boolean backTrack(int si, int pi, String s, String p) { + if (si >= s.length() && pi >= p.length()) + return true; // end of the string has been reached hence return true + else { + if (pi >= p.length()) return false; // pattern has exhausted hence return false + else if (si >= s.length()) { + if (pi + 1 < p.length() && p.charAt(pi + 1) == '*') { + return backTrack(si, pi + 2, s, p); + } else + return false; // string has exhausted and pattern does not contain wildcard hence return + // false + } else if (s.charAt(si) == p.charAt(pi) || p.charAt(pi) == '.') { + if (pi + 1 < p.length() && p.charAt(pi + 1) == '*') { + // match 0 or more repeated preceding element + if (backTrack(si, pi + 2, s, p)) return true; + for (int i = si, l = s.length(); i < l; i++) { + if (s.charAt(i) == p.charAt(pi) || p.charAt(pi) == '.') { + if (backTrack(i + 1, pi + 2, s, p)) return true; + } else { + return false; } + } + return backTrack(s.length(), pi, s, p); + } else { + return backTrack(si + 1, pi + 1, s, p); // not wildcard match immediate chars } + } else { + if (pi + 1 < p.length() && p.charAt(pi + 1) == '*') { + return backTrack(si, pi + 2, s, p); + } else return false; + } } - + } } diff --git a/problems/src/backtracking/RemoveInvalidParentheses.java b/problems/src/backtracking/RemoveInvalidParentheses.java index 0feac7ed..2ab68beb 100644 --- a/problems/src/backtracking/RemoveInvalidParentheses.java +++ b/problems/src/backtracking/RemoveInvalidParentheses.java @@ -6,81 +6,78 @@ import java.util.Set; /** - * Created by gouthamvidyapradhan on 17/10/2017. - * Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results. - - Note: The input string may contain letters other than the parentheses ( and ). - - Examples: - "()())()" -> ["()()()", "(())()"] - "(a)())()" -> ["(a)()()", "(a())()"] - ")(" -> [""] - - Solution: O(N x 2 ^ N) backtrack and generate all combination of unique parentheses. Keep track of a counter which - keeps track of validity of parentheses. Prune the search space by checking for validity of parenthesis on the fly - by checking if the counter goes below 0 in which case a valid combination is impossible and also keep track - of selected count and total count of characters in each state to check if the difference between them is above the min - threshold. - + * Created by gouthamvidyapradhan on 17/10/2017. Remove the minimum number of invalid parentheses in + * order to make the input string valid. Return all possible results. + * + *

Note: The input string may contain letters other than the parentheses ( and ). + * + *

Examples: "()())()" -> ["()()()", "(())()"] "(a)())()" -> ["(a)()()", "(a())()"] ")(" -> [""] + * + *

Solution: O(N x 2 ^ N) backtrack and generate all combination of unique parentheses. Keep + * track of a counter which keeps track of validity of parentheses. Prune the search space by + * checking for validity of parenthesis on the fly by checking if the counter goes below 0 in which + * case a valid combination is impossible and also keep track of selected count and total count of + * characters in each state to check if the difference between them is above the min threshold. */ public class RemoveInvalidParentheses { - private Set done; - private int maxLen = Integer.MIN_VALUE; - private int minDiff = Integer.MAX_VALUE; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - List result = new RemoveInvalidParentheses().removeInvalidParentheses("())())"); - result.forEach(System.out::println); - } - + private Set done; + private int maxLen = Integer.MIN_VALUE; + private int minDiff = Integer.MAX_VALUE; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + List result = new RemoveInvalidParentheses().removeInvalidParentheses("())())"); + result.forEach(System.out::println); + } - public List removeInvalidParentheses(String s) { - done = new HashSet<>(); - List result = new ArrayList<>(); - backTrack(s, 0, 0, result, "", 0, 0); - return result; - } + public List removeInvalidParentheses(String s) { + done = new HashSet<>(); + List result = new ArrayList<>(); + backTrack(s, 0, 0, result, "", 0, 0); + return result; + } - private void backTrack(String s, int i, int count, List result, String state, int selected, int total){ - if(i >= s.length()){ - if(count == 0){ - if(selected >= maxLen){ - result.add(state); - maxLen = selected; - minDiff = total - selected; - } - } - } else{ - done.add(state); - char c = s.charAt(i); - if(c == '('){ - if(!done.contains(state + "(")){ - backTrack(s, i + 1, count + 1, result, state + "(", selected + 1, total + 1); - } - if((total - selected + 1) <= minDiff){ - backTrack(s, i + 1, count, result, state, selected, total + 1); - } - } else if(c == ')'){ - if(count - 1 < 0){ - if((total - selected + 1) <= minDiff){ - backTrack(s, i + 1, count, result, state, selected, total + 1); - } - } else{ - if(!done.contains(state + ")")) { - backTrack(s, i + 1, count - 1, result, state + ")", selected + 1, total + 1); - } - if((total - selected + 1) <= minDiff){ - backTrack(s, i + 1, count, result, state, selected, total + 1); - } - } - } else { - backTrack(s, i + 1, count, result, state + c, selected + 1, total + 1); - } + private void backTrack( + String s, int i, int count, List result, String state, int selected, int total) { + if (i >= s.length()) { + if (count == 0) { + if (selected >= maxLen) { + result.add(state); + maxLen = selected; + minDiff = total - selected; + } + } + } else { + done.add(state); + char c = s.charAt(i); + if (c == '(') { + if (!done.contains(state + "(")) { + backTrack(s, i + 1, count + 1, result, state + "(", selected + 1, total + 1); + } + if ((total - selected + 1) <= minDiff) { + backTrack(s, i + 1, count, result, state, selected, total + 1); + } + } else if (c == ')') { + if (count - 1 < 0) { + if ((total - selected + 1) <= minDiff) { + backTrack(s, i + 1, count, result, state, selected, total + 1); + } + } else { + if (!done.contains(state + ")")) { + backTrack(s, i + 1, count - 1, result, state + ")", selected + 1, total + 1); + } + if ((total - selected + 1) <= minDiff) { + backTrack(s, i + 1, count, result, state, selected, total + 1); + } } + } else { + backTrack(s, i + 1, count, result, state + c, selected + 1, total + 1); + } } + } } diff --git a/problems/src/backtracking/Subsets.java b/problems/src/backtracking/Subsets.java index de74ac7a..03956e3e 100644 --- a/problems/src/backtracking/Subsets.java +++ b/problems/src/backtracking/Subsets.java @@ -4,48 +4,37 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 14/03/2017. - * Given a set of distinct integers, nums, return all possible subsets. - *

- * Note: The solution set must not contain duplicate subsets. - *

- * For example, - * If nums = [1,2,3], a solution is: - *

- * [ - * [3], - * [1], - * [2], - * [1,2,3], - * [1,3], - * [2,3], - * [1,2], - * [] - * ] + * Created by gouthamvidyapradhan on 14/03/2017. Given a set of distinct integers, nums, return all + * possible subsets. + * + *

Note: The solution set must not contain duplicate subsets. + * + *

For example, If nums = [1,2,3], a solution is: + * + *

[ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ] */ public class Subsets { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] n = {1, 2, 3}; - List> result = new Subsets().subsets(n); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] n = {1, 2, 3}; + List> result = new Subsets().subsets(n); + } - public List> subsets(int[] nums) { - List> result = new ArrayList<>(); - result.add(new ArrayList<>()); //empty subset - for (int i = 0, l = nums.length; i < l; i++) { - for (int j = 0, resLen = result.size(); j < resLen; j++) { - List newList = new ArrayList<>(result.get(j)); - newList.add(nums[i]); - result.add(newList); - } - } - return result; + public List> subsets(int[] nums) { + List> result = new ArrayList<>(); + result.add(new ArrayList<>()); // empty subset + for (int i = 0, l = nums.length; i < l; i++) { + for (int j = 0, resLen = result.size(); j < resLen; j++) { + List newList = new ArrayList<>(result.get(j)); + newList.add(nums[i]); + result.add(newList); + } } - + return result; + } } diff --git a/problems/src/backtracking/SubsetsII.java b/problems/src/backtracking/SubsetsII.java index 65a90795..daa83bf9 100644 --- a/problems/src/backtracking/SubsetsII.java +++ b/problems/src/backtracking/SubsetsII.java @@ -5,53 +5,44 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 14/03/2017. - * Given a collection of integers that might contain duplicates, nums, return all possible subsets. - *

- * Note: The solution set must not contain duplicate subsets. - *

- * For example, - * If nums = [1,2,2], a solution is: - *

- * [ - * [2], - * [1], - * [1,2,2], - * [2,2], - * [1,2], - * [] - * ] + * Created by gouthamvidyapradhan on 14/03/2017. Given a collection of integers that might contain + * duplicates, nums, return all possible subsets. + * + *

Note: The solution set must not contain duplicate subsets. + * + *

For example, If nums = [1,2,2], a solution is: + * + *

[ [2], [1], [1,2,2], [2,2], [1,2], [] ] */ public class SubsetsII { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] n = {1, 2, 3}; - List> result = new SubsetsII().subsetsWithDup(n); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] n = {1, 2, 3}; + List> result = new SubsetsII().subsetsWithDup(n); + } - public List> subsetsWithDup(int[] nums) { - List> result = new ArrayList<>(); - result.add(new ArrayList<>()); //empty subset - int start = 0, newStart = 0; - Arrays.sort(nums); - for (int i = 0, l = nums.length; i < l; i++) { - newStart = result.size(); - if (i == 0 || nums[i] != nums[i - 1]) { - start = 0; - } - for (int j = start, resLen = result.size(); j < resLen; j++) { - List newList = new ArrayList<>(result.get(j)); - newList.add(nums[i]); - result.add(newList); - } - start = newStart; - } - return result; + public List> subsetsWithDup(int[] nums) { + List> result = new ArrayList<>(); + result.add(new ArrayList<>()); // empty subset + int start = 0, newStart = 0; + Arrays.sort(nums); + for (int i = 0, l = nums.length; i < l; i++) { + newStart = result.size(); + if (i == 0 || nums[i] != nums[i - 1]) { + start = 0; + } + for (int j = start, resLen = result.size(); j < resLen; j++) { + List newList = new ArrayList<>(result.get(j)); + newList.add(nums[i]); + result.add(newList); + } + start = newStart; } - + return result; + } } diff --git a/problems/src/backtracking/TargetSum.java b/problems/src/backtracking/TargetSum.java index 3480a25f..dce00652 100644 --- a/problems/src/backtracking/TargetSum.java +++ b/problems/src/backtracking/TargetSum.java @@ -1,60 +1,49 @@ package backtracking; /** - * Created by gouthamvidyapradhan on 09/12/2017. - * You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symbols + and -. - * For each integer, you should choose one from + and - as its new symbol. - - Find out how many ways to assign symbols to make sum of integers equal to target S. - - Example 1: - Input: nums is [1, 1, 1, 1, 1], S is 3. - Output: 5 - Explanation: - - -1+1+1+1+1 = 3 - +1-1+1+1+1 = 3 - +1+1-1+1+1 = 3 - +1+1+1-1+1 = 3 - +1+1+1+1-1 = 3 - - There are 5 ways to assign symbols to make the sum of nums be target 3. - Note: - The length of the given array is positive and will not exceed 20. - The sum of elements in the given array will not exceed 1000. - Your output answer is guaranteed to be fitted in a 32-bit integer. + * Created by gouthamvidyapradhan on 09/12/2017. You are given a list of non-negative integers, a1, + * a2, ..., an, and a target, S. Now you have 2 symbols + and -. For each integer, you should choose + * one from + and - as its new symbol. + * + *

Find out how many ways to assign symbols to make sum of integers equal to target S. + * + *

Example 1: Input: nums is [1, 1, 1, 1, 1], S is 3. Output: 5 Explanation: + * + *

-1+1+1+1+1 = 3 +1-1+1+1+1 = 3 +1+1-1+1+1 = 3 +1+1+1-1+1 = 3 +1+1+1+1-1 = 3 * + *

There are 5 ways to assign symbols to make the sum of nums be target 3. Note: The length of + * the given array is positive and will not exceed 20. The sum of elements in the given array will + * not exceed 1000. Your output answer is guaranteed to be fitted in a 32-bit integer. */ public class TargetSum { - private static int n; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1, 1, 1, 1, 1}; - n = 0; - new TargetSum().findTargetSumWays(A, 3); - System.out.println(n); + private static int n; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 1, 1, 1, 1}; + n = 0; + new TargetSum().findTargetSumWays(A, 3); + System.out.println(n); + } + + public int findTargetSumWays(int[] nums, int S) { + backtrack(nums, S, 0, 0); + return n; + } + + private void backtrack(int[] nums, int target, int sum, int i) { + if (i == nums.length) { + if (sum == target) { + n++; + } + } else { + backtrack(nums, target, sum + nums[i], i + 1); + backtrack(nums, target, sum - nums[i], i + 1); } - - public int findTargetSumWays(int[] nums, int S) { - backtrack(nums, S, 0, 0); - return n; - } - - private void backtrack(int[] nums, int target, int sum, int i){ - if(i == nums.length){ - if(sum == target){ - n++; - } - } else{ - backtrack(nums, target, sum + nums[i], i + 1); - backtrack(nums, target, sum - nums[i], i + 1); - } - } - + } } - diff --git a/problems/src/backtracking/WildcardMatching.java b/problems/src/backtracking/WildcardMatching.java index 939d7bf8..90b383bd 100644 --- a/problems/src/backtracking/WildcardMatching.java +++ b/problems/src/backtracking/WildcardMatching.java @@ -1,71 +1,68 @@ package backtracking; /** - * Created by gouthamvidyapradhan on 21/01/2018. - * Implement wildcard pattern matching with support for '?' and '*'. - - '?' Matches any single character. - '*' Matches any sequence of characters (including the empty sequence). - - The matching should cover the entire input string (not partial). - - The function prototype should be: - bool isMatch(const char *s, const char *p) - - Some examples: - isMatch("aa","a") → false - isMatch("aa","aa") → true - isMatch("aaa","aa") → false - isMatch("aa", "*") → true - isMatch("aa", "a*") → true - isMatch("ab", "?*") → true - isMatch("aab", "c*a*b") → false - - Solution: Maintain two indexes one for string and other one for the pattern. - 1. If the characters match in both the indexes or if the char at pattern is '?' then increment both the indexes. - 2. If a star(*) is encountered save the position of star in the given string as 'startPosAtStr' and position of star in - the pattern as 'starIdx' and this time increment only index for pattern. - 3. If the characters do not match and if the start is not encountered previously return false else increment - 'startPosAtStr' and assign this as the new index for string and start the new pattern index from starIdx + 1 + * Created by gouthamvidyapradhan on 21/01/2018. Implement wildcard pattern matching with support + * for '?' and '*'. + * + *

'?' Matches any single character. '*' Matches any sequence of characters (including the empty + * sequence). + * + *

The matching should cover the entire input string (not partial). + * + *

The function prototype should be: bool isMatch(const char *s, const char *p) + * + *

Some examples: isMatch("aa","a") → false isMatch("aa","aa") → true isMatch("aaa","aa") → false + * isMatch("aa", "*") → true isMatch("aa", "a*") → true isMatch("ab", "?*") → true isMatch("aab", + * "c*a*b") → false + * + *

Solution: Maintain two indexes one for string and other one for the pattern. 1. If the + * characters match in both the indexes or if the char at pattern is '?' then increment both the + * indexes. 2. If a star(*) is encountered save the position of star in the given string as + * 'startPosAtStr' and position of star in the pattern as 'starIdx' and this time increment only + * index for pattern. 3. If the characters do not match and if the start is not encountered + * previously return false else increment 'startPosAtStr' and assign this as the new index for + * string and start the new pattern index from starIdx + 1 */ public class WildcardMatching { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new WildcardMatching().isMatch("abebd", "?be******e")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new WildcardMatching().isMatch("abebd", "?be******e")); + } - public boolean isMatch(String s, String p) { - int starIdx = -1; - int starPosAtStr = -1; - int j = 0; - for(int i = 0, l = s.length(); i < l;){ - if(j < p.length()){ - if(s.charAt(i) == p.charAt(j) || p.charAt(j) == '?'){ - i++; j++; - } else if(p.charAt(j) == '*'){ - starIdx = j; - starPosAtStr = i; - j++; //increment only pattern index. This is because '*' can match also empty string. - } else if(starIdx != -1){ - i = ++starPosAtStr; - j = starIdx + 1; - } else return false; - } else if(starIdx != -1){ - i = ++starPosAtStr; - j = starIdx + 1; - } else return false; - } - //check if the remaining characters in pattern contains only '*' - while(j < p.length()){ - if(p.charAt(j) == '*'){ - j++; - } else break; - } - return j == p.length(); + public boolean isMatch(String s, String p) { + int starIdx = -1; + int starPosAtStr = -1; + int j = 0; + for (int i = 0, l = s.length(); i < l; ) { + if (j < p.length()) { + if (s.charAt(i) == p.charAt(j) || p.charAt(j) == '?') { + i++; + j++; + } else if (p.charAt(j) == '*') { + starIdx = j; + starPosAtStr = i; + j++; // increment only pattern index. This is because '*' can match also empty string. + } else if (starIdx != -1) { + i = ++starPosAtStr; + j = starIdx + 1; + } else return false; + } else if (starIdx != -1) { + i = ++starPosAtStr; + j = starIdx + 1; + } else return false; + } + // check if the remaining characters in pattern contains only '*' + while (j < p.length()) { + if (p.charAt(j) == '*') { + j++; + } else break; } + return j == p.length(); + } } diff --git a/problems/src/backtracking/WordSearch.java b/problems/src/backtracking/WordSearch.java index 7032b201..5fa5df91 100644 --- a/problems/src/backtracking/WordSearch.java +++ b/problems/src/backtracking/WordSearch.java @@ -1,75 +1,68 @@ package backtracking; /** - * Created by PRADHANG on 4/13/2017. - * Given a 2D board and a word, find if the word exists in the grid. - *

- * The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once. - *

- * For example, - * Given board = - *

- * [ - * ['A','B','C','E'], - * ['S','F','C','S'], - * ['A','D','E','E'] - * ] - * word = "ABCCED", -> returns true, - * word = "SEE", -> returns true, - * word = "ABCB", -> returns false. + * Created by PRADHANG on 4/13/2017. Given a 2D board and a word, find if the word exists in the + * grid. + * + *

The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells + * are those horizontally or vertically neighboring. The same letter cell may not be used more than + * once. + * + *

For example, Given board = + * + *

[ ['A','B','C','E'], ['S','F','C','S'], ['A','D','E','E'] ] word = "ABCCED", -> returns true, + * word = "SEE", -> returns true, word = "ABCB", -> returns false. */ public class WordSearch { - private static final int[] R = {0, 0, 1, -1}; - private static final int[] C = {1, -1, 0, 0}; - private static boolean[][] visited; - private static int length = 0, N, M; + private static final int[] R = {0, 0, 1, -1}; + private static final int[] C = {1, -1, 0, 0}; + private static boolean[][] visited; + private static int length = 0, N, M; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - char[][] board = { - {'A'} - }; - System.out.println(new WordSearch().exist(board, "A")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + char[][] board = {{'A'}}; + System.out.println(new WordSearch().exist(board, "A")); + } - public boolean exist(char[][] board, String word) { - N = board.length; - M = board[0].length; - if (N * M < word.length()) return false; - visited = new boolean[N][M]; - length = word.length(); - for (int i = 0; i < N; i++) { - for (int j = 0; j < M; j++) { - if (board[i][j] == word.charAt(0)) { - if (dfs(i, j, board, word, 1)) return true; - visited[i][j] = false; - } - } + public boolean exist(char[][] board, String word) { + N = board.length; + M = board[0].length; + if (N * M < word.length()) return false; + visited = new boolean[N][M]; + length = word.length(); + for (int i = 0; i < N; i++) { + for (int j = 0; j < M; j++) { + if (board[i][j] == word.charAt(0)) { + if (dfs(i, j, board, word, 1)) return true; + visited[i][j] = false; } - return false; + } } + return false; + } - private boolean dfs(int r, int c, char[][] board, String word, int pos) { - if (pos < length) { - visited[r][c] = true; - for (int i = 0; i < 4; i++) { - int newR = r + R[i]; - int newC = c + C[i]; - if (newR >= 0 && newR < N && newC >= 0 && newC < M) { - if (!visited[newR][newC]) { - if (board[newR][newC] == word.charAt(pos)) { - if (dfs(newR, newC, board, word, pos + 1)) return true; - visited[newR][newC] = false; - } - } - } + private boolean dfs(int r, int c, char[][] board, String word, int pos) { + if (pos < length) { + visited[r][c] = true; + for (int i = 0; i < 4; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 && newR < N && newC >= 0 && newC < M) { + if (!visited[newR][newC]) { + if (board[newR][newC] == word.charAt(pos)) { + if (dfs(newR, newC, board, word, pos + 1)) return true; + visited[newR][newC] = false; } - } else return true; - return false; - } + } + } + } + } else return true; + return false; + } } diff --git a/problems/src/backtracking/WordSearchII.java b/problems/src/backtracking/WordSearchII.java index bbd2b453..07377143 100644 --- a/problems/src/backtracking/WordSearchII.java +++ b/problems/src/backtracking/WordSearchII.java @@ -3,112 +3,103 @@ import java.util.*; /** - * Created by pradhang on 7/4/2017. - * Given a 2D board and a list of words from the dictionary, find all words in the board. - *

- * Each word must be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word. - *

- * For example, - * Given words = ["oath","pea","eat","rain"] and board = - *

- * [ - * ['o','a','a','n'], - * ['e','t','a','e'], - * ['i','h','k','r'], - * ['i','f','l','v'] - * ] - * Return ["eat","oath"]. - * Note: - * You may assume that all inputs are consist of lowercase letters a-z. + * Created by pradhang on 7/4/2017. Given a 2D board and a list of words from the dictionary, find + * all words in the board. + * + *

Each word must be constructed from letters of sequentially adjacent cell, where "adjacent" + * cells are those horizontally or vertically neighboring. The same letter cell may not be used more + * than once in a word. + * + *

For example, Given words = ["oath","pea","eat","rain"] and board = + * + *

[ ['o','a','a','n'], ['e','t','a','e'], ['i','h','k','r'], ['i','f','l','v'] ] Return + * ["eat","oath"]. Note: You may assume that all inputs are consist of lowercase letters a-z. */ public class WordSearchII { - private final int[] R = {0, 0, -1, 1}; - private final int[] C = {-1, 1, 0, 0}; - boolean[][] visited; - private Set dictionary; + private final int[] R = {0, 0, -1, 1}; + private final int[] C = {-1, 1, 0, 0}; + boolean[][] visited; + private Set dictionary; - public static void main(String[] args) throws Exception { - char[][] board = {{'o', 'a', 'a', 'n'}, {'e', 't', 'a', 'e'}, {'i', 'h', 'k', 'r'}, {'i', 'f', 'l', 'v'}}; - String[] words = {"oath", "pea", "eat", "rain"}; - System.out.println(new WordSearchII().findWords(board, words)); - } + public static void main(String[] args) throws Exception { + char[][] board = { + {'o', 'a', 'a', 'n'}, {'e', 't', 'a', 'e'}, {'i', 'h', 'k', 'r'}, {'i', 'f', 'l', 'v'} + }; + String[] words = {"oath", "pea", "eat", "rain"}; + System.out.println(new WordSearchII().findWords(board, words)); + } - public List findWords(char[][] board, String[] words) { - dictionary = new HashSet<>(); - Trie trie = new Trie(); - for (String w : words) { - trie.insert(w); - dictionary.add(w); - } - visited = new boolean[board.length][board[0].length]; - Set resultSet = new HashSet<>(); - for (int i = 0; i < board.length; i++) { - for (int j = 0; j < board[0].length; j++) { - dfs(i, j, board, resultSet, trie, String.valueOf(board[i][j])); - } - } - return new ArrayList<>(resultSet); + public List findWords(char[][] board, String[] words) { + dictionary = new HashSet<>(); + Trie trie = new Trie(); + for (String w : words) { + trie.insert(w); + dictionary.add(w); } + visited = new boolean[board.length][board[0].length]; + Set resultSet = new HashSet<>(); + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + dfs(i, j, board, resultSet, trie, String.valueOf(board[i][j])); + } + } + return new ArrayList<>(resultSet); + } - private void dfs(int r, int c, char[][] board, Set result, Trie trie, String s) { - char newChar = board[r][c]; - Trie subTrie = trie.next(newChar); - if (subTrie == null) return; - visited[r][c] = true; - if (dictionary.contains(s)) - result.add(s); - for (int i = 0; i < 4; i++) { - int newR = r + R[i]; - int newC = c + C[i]; - if (newR >= 0 && newC >= 0 && newR < board.length && newC < board[0].length) { - if (!visited[newR][newC]) { - dfs(newR, newC, board, result, subTrie, s + board[newR][newC]); - } - } + private void dfs(int r, int c, char[][] board, Set result, Trie trie, String s) { + char newChar = board[r][c]; + Trie subTrie = trie.next(newChar); + if (subTrie == null) return; + visited[r][c] = true; + if (dictionary.contains(s)) result.add(s); + for (int i = 0; i < 4; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 && newC >= 0 && newR < board.length && newC < board[0].length) { + if (!visited[newR][newC]) { + dfs(newR, newC, board, result, subTrie, s + board[newR][newC]); } - visited[r][c] = false; + } } + visited[r][c] = false; + } - private class Trie { + private class Trie { - private Map map; + private Map map; - /** - * Initialize your data structure here. - */ - public Trie() { - map = new HashMap<>(); - } + /** Initialize your data structure here. */ + public Trie() { + map = new HashMap<>(); + } - /** - * Inserts a word into the trie. - */ - public void insert(String word) { - if (word != null) { - add(0, word, word.length()); - } - } + /** Inserts a word into the trie. */ + public void insert(String word) { + if (word != null) { + add(0, word, word.length()); + } + } - private void add(int i, String word, int length) { - if (i < length) { - char c = word.charAt(i); - Trie subTrie = map.get(c); - if (subTrie == null) { - subTrie = new Trie(); - map.put(c, subTrie); - } - subTrie.add(i + 1, word, length); - } else map.put(null, new Trie()); //use null to indicate end of string + private void add(int i, String word, int length) { + if (i < length) { + char c = word.charAt(i); + Trie subTrie = map.get(c); + if (subTrie == null) { + subTrie = new Trie(); + map.put(c, subTrie); } + subTrie.add(i + 1, word, length); + } else map.put(null, new Trie()); // use null to indicate end of string + } - /** - * Get next Trie node - * - * @param c char c - * @return return Trie - */ - public Trie next(char c) { - return this.map.get(c); - } + /** + * Get next Trie node + * + * @param c char c + * @return return Trie + */ + public Trie next(char c) { + return this.map.get(c); } + } } diff --git a/problems/src/binary_search/FindPeakElement.java b/problems/src/binary_search/FindPeakElement.java index 6421f86b..8904353f 100644 --- a/problems/src/binary_search/FindPeakElement.java +++ b/problems/src/binary_search/FindPeakElement.java @@ -1,54 +1,53 @@ package binary_search; /** - * Created by gouthamvidyapradhan on 10/07/2017. - * A peak element is an element that is greater than its neighbors. - *

- * Given an input array where num[i] ≠ num[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 num[-1] = num[n] = -∞. - *

- * For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2. - *

- * Note: - * Your solution should be in logarithmic complexity. - *

- * Solution: O(log N) check if the first or the last element is the peak element, if yes then return this index. - * Else binary search for the answer - check mid element if this is a peak element return this index, else if the - * left element is greater than current element search left else search right. + * Created by gouthamvidyapradhan on 10/07/2017. A peak element is an element that is greater than + * its neighbors. + * + *

Given an input array where num[i] ≠ num[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 num[-1] = num[n] = -∞. + * + *

For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the + * index number 2. + * + *

Note: Your solution should be in logarithmic complexity. + * + *

Solution: O(log N) check if the first or the last element is the peak element, if yes then + * return this index. Else binary search for the answer - check mid element if this is a peak + * element return this index, else if the left element is greater than current element search left + * else search right. */ public class FindPeakElement { - public static void main(String[] args) throws Exception { - int[] nums = {3, 4, 3, 2, 1}; - System.out.println(new FindPeakElement().findPeakElement(nums)); - } + public static void main(String[] args) throws Exception { + int[] nums = {3, 4, 3, 2, 1}; + System.out.println(new FindPeakElement().findPeakElement(nums)); + } - public int findPeakElement(int[] nums) { - if (nums.length == 1) return 0; - if (nums[0] > nums[1]) - return 0; - else if (nums[nums.length - 1] > nums[nums.length - 2]) - return nums.length - 1; + public int findPeakElement(int[] nums) { + if (nums.length == 1) return 0; + if (nums[0] > nums[1]) return 0; + else if (nums[nums.length - 1] > nums[nums.length - 2]) return nums.length - 1; - int l = 0, h = nums.length - 1; - int ans = 0; - while (l <= h) { - int m = l + (h - l) / 2; - if (m - 1 >= 0 && m + 1 < nums.length) { - if (nums[m] > nums[m - 1] && nums[m] > nums[m + 1]) { - return m; - } - } - if (m - 1 >= 0 && nums[m - 1] > nums[m]) { //search left - h = m - 1; - } else { - ans = l; //mark this as the answer and search right - l = m + 1; - } + int l = 0, h = nums.length - 1; + int ans = 0; + while (l <= h) { + int m = l + (h - l) / 2; + if (m - 1 >= 0 && m + 1 < nums.length) { + if (nums[m] > nums[m - 1] && nums[m] > nums[m + 1]) { + return m; } - return ans; + } + if (m - 1 >= 0 && nums[m - 1] > nums[m]) { // search left + h = m - 1; + } else { + ans = l; // mark this as the answer and search right + l = m + 1; + } } - + return ans; + } } diff --git a/problems/src/binary_search/FirstBadVersion.java b/problems/src/binary_search/FirstBadVersion.java index 51f68fe9..b4dbb393 100644 --- a/problems/src/binary_search/FirstBadVersion.java +++ b/problems/src/binary_search/FirstBadVersion.java @@ -3,35 +3,35 @@ /** * Created by gouthamvidyapradhan on 29/11/2017. * - * You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version - * of your product fails the quality check. Since each version is developed based on the previous version, - * all the versions after a bad version are also bad. - - Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, which causes all the - following ones to be bad. - - You are given an API bool isBadVersion(version) which will return whether version is bad. Implement a function to - find the first bad version. You should minimize the number of calls to the API. + *

You are a product manager and currently leading a team to develop a new product. + * Unfortunately, the latest version of your product fails the quality check. Since each version is + * developed based on the previous version, all the versions after a bad version are also bad. + * + *

Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, which + * causes all the following ones to be bad. + * + *

You are given an API bool isBadVersion(version) which will return whether version is bad. + * Implement a function to find the first bad version. You should minimize the number of calls to + * the API. */ public class FirstBadVersion { - public static void main(String[] args) throws Exception{ - System.out.println(new FirstBadVersion().firstBadVersion(2126753390)); - } + public static void main(String[] args) throws Exception { + System.out.println(new FirstBadVersion().firstBadVersion(2126753390)); + } - public int firstBadVersion(int n) { - int low = 0, high = n; - while(low < high){ - int mid = (low + high) >>> 1; - if(isBadVersion(mid)){ - high = mid; - } else low = mid + 1; - } - return high; + public int firstBadVersion(int n) { + int low = 0, high = n; + while (low < high) { + int mid = (low + high) >>> 1; + if (isBadVersion(mid)) { + high = mid; + } else low = mid + 1; } + return high; + } - private boolean isBadVersion(int n){ - if(n >= 1702766719) - return true; - return false; - } + private boolean isBadVersion(int n) { + if (n >= 1702766719) return true; + return false; + } } diff --git a/problems/src/binary_search/HIndexII.java b/problems/src/binary_search/HIndexII.java index f07928d1..9a9733ee 100644 --- a/problems/src/binary_search/HIndexII.java +++ b/problems/src/binary_search/HIndexII.java @@ -3,40 +3,42 @@ /** * Created by gouthamvidyapradhan on 11/12/2017. * - * Follow up for H-Index: What if the citations array is sorted in ascending order? Could you optimize your algorithm? + *

Follow up for H-Index: What if the citations array is sorted in ascending order? Could you + * optimize your algorithm? + * * @see array.HIndex */ public class HIndexII { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1, 1, 1, 1, 1, 15, 20}; - System.out.println(new HIndexII().hIndex(A)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 1, 1, 1, 1, 15, 20}; + System.out.println(new HIndexII().hIndex(A)); + } - public int hIndex(int[] citations) { - if(citations.length == 0) return 0; - int s = 0, e = citations.length; - int ans = -1; - while(s < e){ - int m = (s + e) >>> 1; - int cit = citations.length - m; - if(citations[m] > cit){ - if(ans < cit){ - ans = cit; - } - e = m; - } else{ - if(ans < citations[m]){ - ans = citations[m]; - } - s = m + 1; - } + public int hIndex(int[] citations) { + if (citations.length == 0) return 0; + int s = 0, e = citations.length; + int ans = -1; + while (s < e) { + int m = (s + e) >>> 1; + int cit = citations.length - m; + if (citations[m] > cit) { + if (ans < cit) { + ans = cit; } - return ans; + e = m; + } else { + if (ans < citations[m]) { + ans = citations[m]; + } + s = m + 1; + } } - + return ans; + } } diff --git a/problems/src/binary_search/MedianOfTwoSortedArrays.java b/problems/src/binary_search/MedianOfTwoSortedArrays.java index e6bdc86c..d908e664 100644 --- a/problems/src/binary_search/MedianOfTwoSortedArrays.java +++ b/problems/src/binary_search/MedianOfTwoSortedArrays.java @@ -5,89 +5,81 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 23/05/2017. - * There are two sorted arrays nums1 and nums2 of size m and n respectively. - *

- * Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). - *

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

- * The median is 2.0 - * Example 2: - * nums1 = [1, 2] - * nums2 = [3, 4] - *

- * The median is (2 + 3)/2 = 2.5 - *

- * Solution: Works in worst case time complexity of O(log min(m, n)) - *

- * The basic idea is that if you are given two arrays A and B and know - * the length of each, you can check whether an element A[i] is the median in constant - * time. Suppose that the median is A[i]. Since the array is sorted, it is greater than - * exactly i − 1 values in array A. Then if it is the median, it is also greater than exactly - * j = [n / 2] − (i − 1) elements in B. It requires constant time to check if B[j] - * A[i] <= B[j + 1]. If A[i] is not the median, then depending on whether A[i] is greater - * or less than B[j] and B[j + 1], you know that A[i] is either greater than or less than - * the median. Thus you can binary search for A[i] in O(log N) worst-case time + * Created by gouthamvidyapradhan on 23/05/2017. There are two sorted arrays nums1 and nums2 of size + * m and n respectively. + * + *

Find the median of the two sorted arrays. The overall run time complexity should be O(log + * (m+n)). + * + *

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

The median is 2.0 Example 2: nums1 = [1, 2] nums2 = [3, 4] + * + *

The median is (2 + 3)/2 = 2.5 + * + *

Solution: Works in worst case time complexity of O(log min(m, n)) + * + *

The basic idea is that if you are given two arrays A and B and know the length of each, you + * can check whether an element A[i] is the median in constant time. Suppose that the median is + * A[i]. Since the array is sorted, it is greater than exactly i − 1 values in array A. Then if it + * is the median, it is also greater than exactly j = [n / 2] − (i − 1) elements in B. It requires + * constant time to check if B[j] A[i] <= B[j + 1]. If A[i] is not the median, then depending on + * whether A[i] is greater or less than B[j] and B[j + 1], you know that A[i] is either greater than + * or less than the median. Thus you can binary search for A[i] in O(log N) worst-case time */ public class MedianOfTwoSortedArrays { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] A = {1, 2, 5, 8, 44, 45, 45}; - int[] B = {1, 2, 3, 4, 5, 6, 7, 23, 23, 23, 33, 44, 45, 45, 56, 77, 5555}; - System.out.println(new MedianOfTwoSortedArrays().findMedianSortedArrays(A, B)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 2, 5, 8, 44, 45, 45}; + int[] B = {1, 2, 3, 4, 5, 6, 7, 23, 23, 23, 33, 44, 45, 45, 56, 77, 5555}; + System.out.println(new MedianOfTwoSortedArrays().findMedianSortedArrays(A, B)); + } - /** - * Find median - * - * @param nums1 array one - * @param nums2 array two - * @return - */ - public double findMedianSortedArrays(int[] nums1, int[] nums2) { - if (nums1.length > nums2.length) - return findMedianSortedArrays(nums2, nums1); //ensure always nums1 is the shortest array - int T = nums1.length + nums2.length, low = -1, high = -1; - int median = (T - 1) / 2; - boolean isOdd = false; - if ((T % 2) != 0) - isOdd = true; + /** + * Find median + * + * @param nums1 array one + * @param nums2 array two + * @return + */ + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + if (nums1.length > nums2.length) + return findMedianSortedArrays(nums2, nums1); // ensure always nums1 is the shortest array + int T = nums1.length + nums2.length, low = -1, high = -1; + int median = (T - 1) / 2; + boolean isOdd = false; + if ((T % 2) != 0) isOdd = true; - int s = 0, e = nums1.length - 1; - while (s <= e) { - int m = s + (e - s) / 2; - if ((median - m - 1) < 0 || nums1[m] >= nums2[median - m - 1]) { - e = m - 1; - low = m; - high = median - m; - } else s = m + 1; - } + int s = 0, e = nums1.length - 1; + while (s <= e) { + int m = s + (e - s) / 2; + if ((median - m - 1) < 0 || nums1[m] >= nums2[median - m - 1]) { + e = m - 1; + low = m; + high = median - m; + } else s = m + 1; + } - if (low == -1) { - if (isOdd) return nums2[median - nums1.length]; - else return (double) (nums2[median - nums1.length] + nums2[median - nums1.length + 1]) / 2.0D; - } else { - if (isOdd) return nums1[low] < nums2[high] ? nums1[low] : nums2[high]; - else { - //Always sorts maximum of 4 elements hence works in O(1) - List list = new ArrayList<>(); - list.add(nums1[low]); - if (low + 1 < nums1.length) - list.add(nums1[low + 1]); - list.add(nums2[high]); - if (high + 1 < nums2.length) - list.add(nums2[high + 1]); - Collections.sort(list); - return (double) (list.get(0) + list.get(1)) / 2.0; - } - } + if (low == -1) { + if (isOdd) return nums2[median - nums1.length]; + else return (double) (nums2[median - nums1.length] + nums2[median - nums1.length + 1]) / 2.0D; + } else { + if (isOdd) return nums1[low] < nums2[high] ? nums1[low] : nums2[high]; + else { + // Always sorts maximum of 4 elements hence works in O(1) + List list = new ArrayList<>(); + list.add(nums1[low]); + if (low + 1 < nums1.length) list.add(nums1[low + 1]); + list.add(nums2[high]); + if (high + 1 < nums2.length) list.add(nums2[high + 1]); + Collections.sort(list); + return (double) (list.get(0) + list.get(1)) / 2.0; + } } + } } diff --git a/problems/src/binary_search/MinSortedRotatedArray.java b/problems/src/binary_search/MinSortedRotatedArray.java index 7c107bc3..ee5e151f 100644 --- a/problems/src/binary_search/MinSortedRotatedArray.java +++ b/problems/src/binary_search/MinSortedRotatedArray.java @@ -1,41 +1,38 @@ package binary_search; /** - * Created by gouthamvidyapradhan on 10/04/2017. - * Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. - *

- * (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). - *

- * Find the minimum element. - *

- * You may assume no duplicate exists in the array. + * Created by gouthamvidyapradhan on 10/04/2017. Suppose an array sorted in ascending order is + * rotated at some pivot unknown to you beforehand. + * + *

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). + * + *

Find the minimum element. + * + *

You may assume no duplicate exists in the array. */ public class MinSortedRotatedArray { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] A = {5, 1, 2, 3, 4}; - System.out.println(new MinSortedRotatedArray().findMin(A)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {5, 1, 2, 3, 4}; + System.out.println(new MinSortedRotatedArray().findMin(A)); + } - public int findMin(int[] nums) { - if (nums.length == 0) return 0; - else if (nums.length == 1) return nums[0]; - int low = 0, high = nums.length - 1; - while (low < high) { - int mid = (low + high) / 2; - if (mid > 0 && nums[mid] < nums[mid - 1]) - return nums[mid]; - if (nums[low] > nums[mid]) - high = mid - 1; - else if (nums[high] < nums[mid]) - low = mid + 1; - else high = mid - 1; - } - return nums[low]; + public int findMin(int[] nums) { + if (nums.length == 0) return 0; + else if (nums.length == 1) return nums[0]; + int low = 0, high = nums.length - 1; + while (low < high) { + int mid = (low + high) / 2; + if (mid > 0 && nums[mid] < nums[mid - 1]) return nums[mid]; + if (nums[low] > nums[mid]) high = mid - 1; + else if (nums[high] < nums[mid]) low = mid + 1; + else high = mid - 1; } + return nums[low]; + } } diff --git a/problems/src/binary_search/PowXN.java b/problems/src/binary_search/PowXN.java index da3e1a78..05c3eef4 100644 --- a/problems/src/binary_search/PowXN.java +++ b/problems/src/binary_search/PowXN.java @@ -2,32 +2,31 @@ /** * Created by gouthamvidyapradhan on 23/05/2017. - *

- * Implement pow(x, n). - *

- * Solution: Works with O(log n) + * + *

Implement pow(x, n). + * + *

Solution: Works with O(log n) */ public class PowXN { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(1 / new PowXN().myPow(2.00000, -2147483648)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(1 / new PowXN().myPow(2.00000, -2147483648)); + } - public double myPow(double x, int n) { - if (n == 0) return 1D; - long N = n; //use long to avoid overflow. - return solve(n < 0 ? (1 / x) : x, N < 0 ? (N * -1) : N); - } - - public double solve(double x, long n) { - if (n == 1) return x; - double val = solve(x, n / 2); - return val * val * ((n % 2) == 0 ? 1 : x); - } + public double myPow(double x, int n) { + if (n == 0) return 1D; + long N = n; // use long to avoid overflow. + return solve(n < 0 ? (1 / x) : x, N < 0 ? (N * -1) : N); + } + public double solve(double x, long n) { + if (n == 1) return x; + double val = solve(x, n / 2); + return val * val * ((n % 2) == 0 ? 1 : x); + } } diff --git a/problems/src/binary_search/SearchForARange.java b/problems/src/binary_search/SearchForARange.java index b75192c8..8da19dfe 100644 --- a/problems/src/binary_search/SearchForARange.java +++ b/problems/src/binary_search/SearchForARange.java @@ -1,59 +1,60 @@ package binary_search; /** - * Created by gouthamvidyapradhan on 20/05/2017. - * Given an array of integers sorted in ascending order, find the starting and ending position of a given target value. - *

- * Your algorithm's runtime complexity must be in the order of O(log n). - *

- * If the target is not found in the array, return [-1, -1]. - *

- * For example, - * Given [5, 7, 7, 8, 8, 10] and target value 8, - * return [3, 4]. - *

- * Solution: Works with worst case time complexity of O(log n). Recursively binary search to find the target index. + * Created by gouthamvidyapradhan on 20/05/2017. Given an array of integers sorted in ascending + * order, find the starting and ending position of a given target value. + * + *

Your algorithm's runtime complexity must be in the order of O(log n). + * + *

If the target is not found in the array, return [-1, -1]. + * + *

For example, Given [5, 7, 7, 8, 8, 10] and target value 8, return [3, 4]. + * + *

Solution: Works with worst case time complexity of O(log n). Recursively binary search to find + * the target index. */ public class SearchForARange { - public static void main(String[] args) throws Exception { - int[] test = {5, 7, 7, 8, 8, 10, 10, 10, 10, 18, 19, 20, 21, 21, 21, 21, 22, 23, 28, 28, 90, 101, 101, - 101, 200, 200, 200, 200, 200, 200}; - int[] result = new SearchForARange().searchRange(test, 200); - for (int i : result) - System.out.print(i + " "); - } + public static void main(String[] args) throws Exception { + int[] test = { + 5, 7, 7, 8, 8, 10, 10, 10, 10, 18, 19, 20, 21, 21, 21, 21, 22, 23, 28, 28, 90, 101, 101, 101, + 200, 200, 200, 200, 200, 200 + }; + int[] result = new SearchForARange().searchRange(test, 200); + for (int i : result) System.out.print(i + " "); + } - public int[] searchRange(int[] nums, int target) { - int low = findIndex(nums, target, true); - int high = findIndex(nums, target, false); - int[] result = new int[2]; - result[0] = low; - result[1] = high; - return result; - } + public int[] searchRange(int[] nums, int target) { + int low = findIndex(nums, target, true); + int high = findIndex(nums, target, false); + int[] result = new int[2]; + result[0] = low; + result[1] = high; + return result; + } - /** - * Find index - * - * @param nums nums array - * @param target target - * @param isLowerIndex true if target is to find lower index, false otherwise - * @return index - */ - private int findIndex(int[] nums, int target, boolean isLowerIndex) { - int result = -1; - int s = 0, e = nums.length - 1; - while (s <= e) { - int m = s + (e - s) / 2; - if (nums[m] == target) { - result = m; - if (isLowerIndex) e = m - 1; //if searching for the lower index then search the lower bound, - // else search the upper bound - else s = m + 1; - } else if (nums[m] < target) { - s = m + 1; - } else e = m - 1; - } - return result; + /** + * Find index + * + * @param nums nums array + * @param target target + * @param isLowerIndex true if target is to find lower index, false otherwise + * @return index + */ + private int findIndex(int[] nums, int target, boolean isLowerIndex) { + int result = -1; + int s = 0, e = nums.length - 1; + while (s <= e) { + int m = s + (e - s) / 2; + if (nums[m] == target) { + result = m; + if (isLowerIndex) + e = m - 1; // if searching for the lower index then search the lower bound, + // else search the upper bound + else s = m + 1; + } else if (nums[m] < target) { + s = m + 1; + } else e = m - 1; } + return result; + } } diff --git a/problems/src/binary_search/SearchInsertPosition.java b/problems/src/binary_search/SearchInsertPosition.java index d054cb24..4b9e9fac 100644 --- a/problems/src/binary_search/SearchInsertPosition.java +++ b/problems/src/binary_search/SearchInsertPosition.java @@ -1,34 +1,30 @@ package binary_search; /** - * Created by gouthamvidyapradhan on 22/05/2017. - * Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. - *

- * You may assume no duplicates in the array. - *

- * Here are few examples. - * [1,3,5,6], 5 → 2 - * [1,3,5,6], 2 → 1 - * [1,3,5,6], 7 → 4 - * [1,3,5,6], 0 → 0 + * Created by gouthamvidyapradhan on 22/05/2017. Given a sorted array and a target value, return the + * index if the target is found. If not, return the index where it would be if it were inserted in + * order. + * + *

You may assume no duplicates in the array. + * + *

Here are few examples. [1,3,5,6], 5 → 2 [1,3,5,6], 2 → 1 [1,3,5,6], 7 → 4 [1,3,5,6], 0 → 0 */ public class SearchInsertPosition { - public static void main(String[] args) throws Exception { - int[] A = {1, 3, 5, 6}; - new SearchInsertPosition().searchInsert(A, 5); - } + public static void main(String[] args) throws Exception { + int[] A = {1, 3, 5, 6}; + new SearchInsertPosition().searchInsert(A, 5); + } - public int searchInsert(int[] nums, int target) { - int pos = nums.length; - int s = 0, e = nums.length - 1; - while (s <= e) { - int m = s + (e - s) / 2; - if (nums[m] >= target) { - pos = m; - e = m - 1; - } else s = m + 1; - } - return pos; + public int searchInsert(int[] nums, int target) { + int pos = nums.length; + int s = 0, e = nums.length - 1; + while (s <= e) { + int m = s + (e - s) / 2; + if (nums[m] >= target) { + pos = m; + e = m - 1; + } else s = m + 1; } - + return pos; + } } diff --git a/problems/src/binary_search/SearchRotatedSortedArray.java b/problems/src/binary_search/SearchRotatedSortedArray.java index 755a608b..a4380b01 100644 --- a/problems/src/binary_search/SearchRotatedSortedArray.java +++ b/problems/src/binary_search/SearchRotatedSortedArray.java @@ -1,43 +1,41 @@ package binary_search; /** - * Created by gouthamvidyapradhan on 10/04/2017. - * Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. - *

- * (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). - *

- * You are given a target value to search. If found in the array return its index, otherwise return -1. - *

- * You may assume no duplicate exists in the array. + * Created by gouthamvidyapradhan on 10/04/2017. Suppose an array sorted in ascending order is + * rotated at some pivot unknown to you beforehand. + * + *

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). + * + *

You are given a target value to search. If found in the array return its index, otherwise + * return -1. + * + *

You may assume no duplicate exists in the array. */ public class SearchRotatedSortedArray { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] A = {5, 4, 3, 2, 1}; - System.out.println(new SearchRotatedSortedArray().search(A, 4)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {5, 4, 3, 2, 1}; + System.out.println(new SearchRotatedSortedArray().search(A, 4)); + } - public int search(int[] nums, int target) { - if (nums.length == 0) return -1; - if (nums.length == 1) { - return (nums[0] == target) ? 0 : -1; - } - int low = 0, high = nums.length - 1; - while (low < high) { - int mid = (low + high) >>> 1; - if (nums[mid] == target) - return mid; - if ((nums[mid] <= nums[low]) && (target > nums[mid] && target <= nums[high]) || - (nums[low] <= nums[mid] && (target < nums[low] || target > nums[mid]))) - low = mid + 1; - else high = mid - 1; - } - return (nums[low] == target) ? low : -1; + public int search(int[] nums, int target) { + if (nums.length == 0) return -1; + if (nums.length == 1) { + return (nums[0] == target) ? 0 : -1; } - + int low = 0, high = nums.length - 1; + while (low < high) { + int mid = (low + high) >>> 1; + if (nums[mid] == target) return mid; + if ((nums[mid] <= nums[low]) && (target > nums[mid] && target <= nums[high]) + || (nums[low] <= nums[mid] && (target < nums[low] || target > nums[mid]))) low = mid + 1; + else high = mid - 1; + } + return (nums[low] == target) ? low : -1; + } } diff --git a/problems/src/binary_search/SqrtX.java b/problems/src/binary_search/SqrtX.java index ef9e191b..1cb3462e 100644 --- a/problems/src/binary_search/SqrtX.java +++ b/problems/src/binary_search/SqrtX.java @@ -1,29 +1,26 @@ package binary_search; /** - * Created by gouthamvidyapradhan on 22/05/2017. - * Implement int sqrt(int x). - *

- * Compute and return the square root of x. + * Created by gouthamvidyapradhan on 22/05/2017. Implement int sqrt(int x). + * + *

Compute and return the square root of x. */ public class SqrtX { - public static void main(String[] args) throws Exception { - System.out.println(new SqrtX().mySqrt(Integer.MAX_VALUE)); - } + public static void main(String[] args) throws Exception { + System.out.println(new SqrtX().mySqrt(Integer.MAX_VALUE)); + } - public int mySqrt(int x) { - int s = 0, e = x; - long ans = 0L; - while (s <= e) { - long m = s + (e - s) / 2; - long prod = m * m; - if (prod <= x) { - s = (int) (m + 1); - ans = m; - } else e = (int) m - 1; - } - return (int) ans; + public int mySqrt(int x) { + int s = 0, e = x; + long ans = 0L; + while (s <= e) { + long m = s + (e - s) / 2; + long prod = m * m; + if (prod <= x) { + s = (int) (m + 1); + ans = m; + } else e = (int) m - 1; } - - + return (int) ans; + } } diff --git a/problems/src/binary_search/SwimInRisingWater.java b/problems/src/binary_search/SwimInRisingWater.java index adf717a0..3d8febc8 100644 --- a/problems/src/binary_search/SwimInRisingWater.java +++ b/problems/src/binary_search/SwimInRisingWater.java @@ -5,116 +5,112 @@ import java.util.Set; /** - * Created by gouthamvidyapradhan on 07/04/2019 - * On an N x N grid, each square grid[i][j] represents the elevation at that point (i,j). + * Created by gouthamvidyapradhan on 07/04/2019 On an N x N grid, each square grid[i][j] represents + * the elevation at that point (i,j). * - * Now rain starts to fall. At time t, the depth of the water everywhere is t. You can swim from a square to another - * 4-directionally adjacent square if and only if the elevation of both squares individually are at most t. You can - * swim infinite distance in zero time. Of course, you must stay within the boundaries of the grid during your swim. + *

Now rain starts to fall. At time t, the depth of the water everywhere is t. You can swim from + * a square to another 4-directionally adjacent square if and only if the elevation of both squares + * individually are at most t. You can swim infinite distance in zero time. Of course, you must stay + * within the boundaries of the grid during your swim. * - * You start at the top left square (0, 0). What is the least time until you can reach the bottom right square (N-1, - * N-1)? + *

You start at the top left square (0, 0). What is the least time until you can reach the bottom + * right square (N-1, N-1)? * - * Example 1: + *

Example 1: * - * Input: [[0,2],[1,3]] - * Output: 3 - * Explanation: - * At time 0, you are in grid location (0, 0). - * You cannot go anywhere else because 4-directionally adjacent neighbors have a higher elevation than t = 0. + *

Input: [[0,2],[1,3]] Output: 3 Explanation: At time 0, you are in grid location (0, 0). You + * cannot go anywhere else because 4-directionally adjacent neighbors have a higher elevation than t + * = 0. * - * You cannot reach point (1, 1) until time 3. - * When the depth of water is 3, we can swim anywhere inside the grid. - * Example 2: + *

You cannot reach point (1, 1) until time 3. When the depth of water is 3, we can swim anywhere + * inside the grid. Example 2: * - * Input: [[0,1,2,3,4],[24,23,22,21,5],[12,13,14,15,16],[11,17,18,19,20],[10,9,8,7,6]] - * Output: 16 - * Explanation: - * 0 1 2 3 4 - * 24 23 22 21 5 - * 12 13 14 15 16 - * 11 17 18 19 20 - * 10 9 8 7 6 + *

Input: [[0,1,2,3,4],[24,23,22,21,5],[12,13,14,15,16],[11,17,18,19,20],[10,9,8,7,6]] Output: 16 + * Explanation: 0 1 2 3 4 24 23 22 21 5 12 13 14 15 16 11 17 18 19 20 10 9 8 7 6 * - * The final route is marked in bold. - * We need to wait until time 16 so that (0, 0) and (4, 4) are connected. - * Note: + *

The final route is marked in bold. We need to wait until time 16 so that (0, 0) and (4, 4) are + * connected. Note: * - * 2 <= N <= 50. - * grid[i][j] is a permutation of [0, ..., N*N - 1]. + *

2 <= N <= 50. grid[i][j] is a permutation of [0, ..., N*N - 1]. * - * Solution: O(N ^ 2 x log N ^ 2) - * Binary search for the possible answers in the range [0 to N * N-1] and dfs through the grid to check if the - * destination is reachable + *

Solution: O(N ^ 2 x log N ^ 2) Binary search for the possible answers in the range [0 to N * + * N-1] and dfs through the grid to check if the destination is reachable */ public class SwimInRisingWater { - private final int[] R = {0, 0, 1, -1}; - private final int[] C = {1, -1, 0, 0}; + private final int[] R = {0, 0, 1, -1}; + private final int[] C = {1, -1, 0, 0}; - class Pair{ - int r, c; - Pair(int r, int c){ - this.r = r; - this.c = c; - } + class Pair { + int r, c; - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Pair)) return false; - Pair pair = (Pair) o; - return r == pair.r && - c == pair.c; - } + Pair(int r, int c) { + this.r = r; + this.c = c; + } - @Override - public int hashCode() { - return Objects.hash(r, c); - } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Pair)) return false; + Pair pair = (Pair) o; + return r == pair.r && c == pair.c; } - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int[][] grid = {{0,1,2,3,4},{24,23,22,21,5},{12,13,14,15,16},{11,17,18,19,20},{10,9,8,7,6}}; - System.out.println(new SwimInRisingWater().swimInWater(grid)); + + @Override + public int hashCode() { + return Objects.hash(r, c); } + } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[][] grid = { + {0, 1, 2, 3, 4}, + {24, 23, 22, 21, 5}, + {12, 13, 14, 15, 16}, + {11, 17, 18, 19, 20}, + {10, 9, 8, 7, 6} + }; + System.out.println(new SwimInRisingWater().swimInWater(grid)); + } - public int swimInWater(int[][] grid) { - int l = 0, h = (grid.length * grid.length); - int ans = 0; - while(l <= h){ - int m = l + (h - l) / 2; - Set done = new HashSet<>(); - if(dfs(grid, 0, 0, done, m)){ - ans = m; - h = m - 1; - } else{ - l = m + 1; - } - } - return ans; + public int swimInWater(int[][] grid) { + int l = 0, h = (grid.length * grid.length); + int ans = 0; + while (l <= h) { + int m = l + (h - l) / 2; + Set done = new HashSet<>(); + if (dfs(grid, 0, 0, done, m)) { + ans = m; + h = m - 1; + } else { + l = m + 1; + } } + return ans; + } - private boolean dfs(int[][] grid, int r, int c, Set done, int V){ - if(r == grid.length - 1 && c == grid[0].length - 1) return true; - done.add(new Pair(r, c)); - for(int i = 0; i < 4; i ++){ - int newR = r + R[i]; - int newC = c + C[i]; - if(newR >= 0 && newR < grid.length && newC >= 0 && newC < grid[0].length){ - int childH = Math.max(V, grid[newR][newC]); - int curH = Math.max(V, grid[r][c]); - if(curH == childH){ - Pair child = new Pair(newR, newC); - if(!done.contains(child)){ - if(dfs(grid, newR, newC, done, V)) return true; - } - } - } + private boolean dfs(int[][] grid, int r, int c, Set done, int V) { + if (r == grid.length - 1 && c == grid[0].length - 1) return true; + done.add(new Pair(r, c)); + for (int i = 0; i < 4; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 && newR < grid.length && newC >= 0 && newC < grid[0].length) { + int childH = Math.max(V, grid[newR][newC]); + int curH = Math.max(V, grid[r][c]); + if (curH == childH) { + Pair child = new Pair(newR, newC); + if (!done.contains(child)) { + if (dfs(grid, newR, newC, done, V)) return true; + } } - return false; + } } + return false; + } } diff --git a/problems/src/bit_manipulation/DivideTwoIntegers.java b/problems/src/bit_manipulation/DivideTwoIntegers.java index 9e370897..7bdeab67 100644 --- a/problems/src/bit_manipulation/DivideTwoIntegers.java +++ b/problems/src/bit_manipulation/DivideTwoIntegers.java @@ -1,43 +1,47 @@ package bit_manipulation; /** - * Created by gouthamvidyapradhan on 13/02/2018. - * Divide two integers without using multiplication, division and mod operator. - - If it is overflow, return MAX_INT. + * Created by gouthamvidyapradhan on 13/02/2018. Divide two integers without using multiplication, + * division and mod operator. + * + *

If it is overflow, return MAX_INT. */ public class DivideTwoIntegers { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new DivideTwoIntegers().divide(0, 775)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new DivideTwoIntegers().divide(0, 775)); + } - public int divide(int dividend, int divisor) { - if(divisor == 0) return Integer.MAX_VALUE; - else if(dividend == Integer.MIN_VALUE && divisor == -1) return Integer.MAX_VALUE; - else if(divisor == 1) return dividend; - boolean isNegative = ((dividend < 0 && divisor > 0) || (dividend > 0 && divisor < 0)); - dividend = (dividend < 0)? -dividend : dividend; - divisor = (divisor < 0) ? -divisor : divisor; - int sum, result = 0; - while(true){ - int d1 = divisor; - sum = 0; - if(dividend - d1 == 0) {sum += 1; result += sum; break;} - if(dividend - d1 < 0) break; - while(dividend - (d1 << 1) > 0){ - d1 <<= 1; - sum += 1; - } - result += (1 << sum); - dividend = dividend - d1; - } - return isNegative ? -result : result; + public int divide(int dividend, int divisor) { + if (divisor == 0) return Integer.MAX_VALUE; + else if (dividend == Integer.MIN_VALUE && divisor == -1) return Integer.MAX_VALUE; + else if (divisor == 1) return dividend; + boolean isNegative = ((dividend < 0 && divisor > 0) || (dividend > 0 && divisor < 0)); + dividend = (dividend < 0) ? -dividend : dividend; + divisor = (divisor < 0) ? -divisor : divisor; + int sum, result = 0; + while (true) { + int d1 = divisor; + sum = 0; + if (dividend - d1 == 0) { + sum += 1; + result += sum; + break; + } + if (dividend - d1 < 0) break; + while (dividend - (d1 << 1) > 0) { + d1 <<= 1; + sum += 1; + } + result += (1 << sum); + dividend = dividend - d1; } - + return isNegative ? -result : result; + } } diff --git a/problems/src/bit_manipulation/GrayCode.java b/problems/src/bit_manipulation/GrayCode.java index 9db5ce92..9c74430d 100644 --- a/problems/src/bit_manipulation/GrayCode.java +++ b/problems/src/bit_manipulation/GrayCode.java @@ -4,40 +4,36 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 16/03/2017. - * The gray code is a binary numeral system where two successive values differ in only one bit. - *

- * Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0. - *

- * For example, given n = 2, return [0,1,3,2]. Its gray code sequence is: - *

- * 00 - 0 - * 01 - 1 - * 11 - 3 - * 10 - 2 - * Note: - * For a given n, a gray code sequence is not uniquely defined. - *

- * For example, [0,2,3,1] is also a valid gray code sequence according to the above definition. - *

- * For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that. + * Created by gouthamvidyapradhan on 16/03/2017. The gray code is a binary numeral system where two + * successive values differ in only one bit. + * + *

Given a non-negative integer n representing the total number of bits in the code, print the + * sequence of gray code. A gray code sequence must begin with 0. + * + *

For example, given n = 2, return [0,1,3,2]. Its gray code sequence is: + * + *

00 - 0 01 - 1 11 - 3 10 - 2 Note: For a given n, a gray code sequence is not uniquely defined. + * + *

For example, [0,2,3,1] is also a valid gray code sequence according to the above definition. + * + *

For now, the judge is able to judge based on one instance of gray code sequence. Sorry about + * that. */ public class GrayCode { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - List result = new GrayCode().grayCode(3); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + List result = new GrayCode().grayCode(3); + } - public List grayCode(int n) { - List result = new ArrayList<>(); - for (int i = 0; i <= ((1 << n) - 1); i++) - result.add(i ^ (i >> 1)); - return result; - } + public List grayCode(int n) { + List result = new ArrayList<>(); + for (int i = 0; i <= ((1 << n) - 1); i++) result.add(i ^ (i >> 1)); + return result; + } } diff --git a/problems/src/bit_manipulation/HammingDistance.java b/problems/src/bit_manipulation/HammingDistance.java index 4f1a6dbf..63fb1fd5 100644 --- a/problems/src/bit_manipulation/HammingDistance.java +++ b/problems/src/bit_manipulation/HammingDistance.java @@ -1,49 +1,43 @@ package bit_manipulation; /** - * Created by gouthamvidyapradhan on 16/12/2017. - * The Hamming distance between two integers is the number of positions at which the corresponding bits are different. - - Given two integers x and y, calculate the Hamming distance. - - Note: - 0 ≤ x, y < 231. - - Example: - - Input: x = 1, y = 4 - - Output: 2 - - Explanation: - 1 (0 0 0 1) - 4 (0 1 0 0) - ↑ ↑ - - The above arrows point to positions where the corresponding bits are different. - - Solution O(1): XOR (x, y) and count the number of bits set - + * Created by gouthamvidyapradhan on 16/12/2017. The Hamming distance between two integers is the + * number of positions at which the corresponding bits are different. + * + *

Given two integers x and y, calculate the Hamming distance. + * + *

Note: 0 ≤ x, y < 231. + * + *

Example: + * + *

Input: x = 1, y = 4 + * + *

Output: 2 + * + *

Explanation: 1 (0 0 0 1) 4 (0 1 0 0) ↑ ↑ + * + *

The above arrows point to positions where the corresponding bits are different. + * + *

Solution O(1): XOR (x, y) and count the number of bits set */ public class HammingDistance { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - - } - - public int hammingDistance(int x, int y) { - int z = (x ^ y); - int count = 0; - for(int i = 0; i < 31; i++){ - if((z & (1 << i)) > 0){ - count++; - } - } - return count; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception {} + + public int hammingDistance(int x, int y) { + int z = (x ^ y); + int count = 0; + for (int i = 0; i < 31; i++) { + if ((z & (1 << i)) > 0) { + count++; + } } + return count; + } } diff --git a/problems/src/bit_manipulation/TotalHammingDistance.java b/problems/src/bit_manipulation/TotalHammingDistance.java index 411f2672..e0e89307 100644 --- a/problems/src/bit_manipulation/TotalHammingDistance.java +++ b/problems/src/bit_manipulation/TotalHammingDistance.java @@ -1,49 +1,47 @@ package bit_manipulation; /** - * Created by gouthamvidyapradhan on 01/12/2017. - * The Hamming distance between two integers is the number of positions at which the corresponding bits are different. - - Now your job is to find the total Hamming distance between all pairs of the given numbers. - - Example: - Input: 4, 14, 2 - - Output: 6 - - Explanation: In binary representation, the 4 is 0100, 14 is 1110, and 2 is 0010 (just - showing the four bits relevant in this case). So the answer will be: - HammingDistance(4, 14) + HammingDistance(4, 2) + HammingDistance(14, 2) = 2 + 2 + 2 = 6. - Note: - Elements of the given array are in the range of 0 to 10^9 - Length of the array will not exceed 10^4. - - Solution: O(N * 32): Count the number of set bits in each of 32 bit positions and then take the sum of - product of number of set bits x number of un-set bits + * Created by gouthamvidyapradhan on 01/12/2017. The Hamming distance between two integers is the + * number of positions at which the corresponding bits are different. + * + *

Now your job is to find the total Hamming distance between all pairs of the given numbers. + * + *

Example: Input: 4, 14, 2 + * + *

Output: 6 + * + *

Explanation: In binary representation, the 4 is 0100, 14 is 1110, and 2 is 0010 (just showing + * the four bits relevant in this case). So the answer will be: HammingDistance(4, 14) + + * HammingDistance(4, 2) + HammingDistance(14, 2) = 2 + 2 + 2 = 6. Note: Elements of the given array + * are in the range of 0 to 10^9 Length of the array will not exceed 10^4. + * + *

Solution: O(N * 32): Count the number of set bits in each of 32 bit positions and then take + * the sum of product of number of set bits x number of un-set bits */ public class TotalHammingDistance { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1000000000, 4, 14, 2}; - System.out.println(new TotalHammingDistance().totalHammingDistance(A)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1000000000, 4, 14, 2}; + System.out.println(new TotalHammingDistance().totalHammingDistance(A)); + } - public int totalHammingDistance(int[] nums) { - int sum = 0; - for(int i = 0; i < 32; i ++){ - int numOfOnes = 0; - int p = (1 << i); - for (int num : nums) { - if ((num & p) > 0) { - numOfOnes++; - } - } - sum += ((nums.length - numOfOnes) * numOfOnes); + public int totalHammingDistance(int[] nums) { + int sum = 0; + for (int i = 0; i < 32; i++) { + int numOfOnes = 0; + int p = (1 << i); + for (int num : nums) { + if ((num & p) > 0) { + numOfOnes++; } - return sum; + } + sum += ((nums.length - numOfOnes) * numOfOnes); } + return sum; + } } diff --git a/problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java b/problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java index a266ddc0..92462939 100644 --- a/problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java +++ b/problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java @@ -6,89 +6,78 @@ import java.util.Queue; /** - * Created by gouthamvidyapradhan on 13/03/2017. - * Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). - *

- * For example: - * Given binary tree [3,9,20,null,null,15,7], - * 3 - * / \ - * 9 20 - * / \ - * 15 7 - * return its level order traversal as: - * [ - * [3], - * [9,20], - * [15,7] - * ] + * Created by gouthamvidyapradhan on 13/03/2017. Given a binary tree, return the level order + * traversal of its nodes' values. (ie, from left to right, level by level). + * + *

For example: Given binary tree [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 return its level + * order traversal as: [ [3], [9,20], [15,7] ] */ public class BinarayTreeLevelOrderTraversal { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - private class LevelNode { - TreeNode node; - int level; + private class LevelNode { + TreeNode node; + int level; - LevelNode(TreeNode node, int level) { - this.node = node; - this.level = level; - } + LevelNode(TreeNode node, int level) { + this.node = node; + this.level = level; } + } - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - TreeNode root = new TreeNode(2); - root.left = new TreeNode(3); - root.right = new TreeNode(4); - root.right.right = new TreeNode(5); - root.right.left = new TreeNode(4); - root.right.left.right = new TreeNode(8); - root.right.left.left = new TreeNode(7); - root.right.left.left.right = new TreeNode(10); - root.right.left.left.left = new TreeNode(9); + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(2); + root.left = new TreeNode(3); + root.right = new TreeNode(4); + root.right.right = new TreeNode(5); + root.right.left = new TreeNode(4); + root.right.left.right = new TreeNode(8); + root.right.left.left = new TreeNode(7); + root.right.left.left.right = new TreeNode(10); + root.right.left.left.left = new TreeNode(9); - List> result = new BinarayTreeLevelOrderTraversal().levelOrder(root); - } + List> result = new BinarayTreeLevelOrderTraversal().levelOrder(root); + } - public List> levelOrder(TreeNode root) { - List> result = new ArrayList<>(); - if (root == null) return result; - Queue queue = new ArrayDeque<>(); - queue.offer(new LevelNode(root, 0)); - int currentLevel = 0; - List row = new ArrayList<>(); - while (!queue.isEmpty()) { - LevelNode levelNode = queue.poll(); - if (levelNode.node != null) { - if (levelNode.level != currentLevel) { - result.add(row); - row = new ArrayList<>(); - currentLevel++; - } - row.add(levelNode.node.val); - TreeNode left = levelNode.node.left; - TreeNode right = levelNode.node.right; - LevelNode lNodeL = new LevelNode(left, levelNode.level + 1); - LevelNode lNodeR = new LevelNode(right, levelNode.level + 1); - queue.offer(lNodeL); - queue.offer(lNodeR); - } + public List> levelOrder(TreeNode root) { + List> result = new ArrayList<>(); + if (root == null) return result; + Queue queue = new ArrayDeque<>(); + queue.offer(new LevelNode(root, 0)); + int currentLevel = 0; + List row = new ArrayList<>(); + while (!queue.isEmpty()) { + LevelNode levelNode = queue.poll(); + if (levelNode.node != null) { + if (levelNode.level != currentLevel) { + result.add(row); + row = new ArrayList<>(); + currentLevel++; } - result.add(row); - return result; + row.add(levelNode.node.val); + TreeNode left = levelNode.node.left; + TreeNode right = levelNode.node.right; + LevelNode lNodeL = new LevelNode(left, levelNode.level + 1); + LevelNode lNodeR = new LevelNode(right, levelNode.level + 1); + queue.offer(lNodeL); + queue.offer(lNodeR); + } } + result.add(row); + return result; + } } diff --git a/problems/src/breadth_first_search/BusRoutes.java b/problems/src/breadth_first_search/BusRoutes.java index f90e832f..4b975dc2 100644 --- a/problems/src/breadth_first_search/BusRoutes.java +++ b/problems/src/breadth_first_search/BusRoutes.java @@ -1,114 +1,110 @@ package breadth_first_search; + import java.util.*; /** - * Created by gouthamvidyapradhan on 25/08/2018 - * We have a list of bus routes. Each routes[i] is a bus route that the i-th bus repeats forever. For example if - * routes[0] = [1, 5, 7], this means that the first bus (0-th indexed) travels in the sequence 1->5->7->1->5->7->1->. - * .. forever. + * Created by gouthamvidyapradhan on 25/08/2018 We have a list of bus routes. Each routes[i] is a + * bus route that the i-th bus repeats forever. For example if routes[0] = [1, 5, 7], this means + * that the first bus (0-th indexed) travels in the sequence 1->5->7->1->5->7->1->. .. forever. * - * We start at bus stop S (initially not on a bus), and we want to go to bus stop T. Travelling by buses only, what - * is the least number of buses we must take to reach our destination? Return -1 if it is not possible. + *

We start at bus stop S (initially not on a bus), and we want to go to bus stop T. Travelling + * by buses only, what is the least number of buses we must take to reach our destination? Return -1 + * if it is not possible. * - * Example: - * Input: - * routes = [[1, 2, 7], [3, 6, 7]] - * S = 1 - * T = 6 - * Output: 2 - * Explanation: - * The best strategy is take the first bus to the bus stop 7, then take the second bus to the bus stop 6. + *

Example: Input: routes = [[1, 2, 7], [3, 6, 7]] S = 1 T = 6 Output: 2 Explanation: The best + * strategy is take the first bus to the bus stop 7, then take the second bus to the bus stop 6. * Note: * - * 1 <= routes.length <= 500. - * 1 <= routes[i].length <= 500. - * 0 <= routes[i][j] < 10 ^ 6. + *

1 <= routes.length <= 500. 1 <= routes[i].length <= 500. 0 <= routes[i][j] < 10 ^ 6. * - * Solution: Model a graph based on interconnection of routes and then run a BFS to find the shortest distance. + *

Solution: Model a graph based on interconnection of routes and then run a BFS to find the + * shortest distance. */ public class BusRoutes { - private class Node{ - int v, dist; - Node(int v, int dist){ - this.v = v; - this.dist = dist; - } - } + private class Node { + int v, dist; - private Map> routeGraph = new HashMap<>(); - private Map> stationRouteMap = new HashMap<>(); - private BitSet done = new BitSet(); - /** - * Main method - * - * @param args - */ - public static void main(String[] args) { - int[][] R = {{1, 2, 3, 9}, {9, 3, 4, 5, 8}, {5, 6, 7, 8}, {9, 8, 10, 11}, {12, 13, 14, 6, 1, 2, 3, 5, 7}}; - System.out.println(new BusRoutes().numBusesToDestination(R, 1, 14)); + Node(int v, int dist) { + this.v = v; + this.dist = dist; } + } + private Map> routeGraph = new HashMap<>(); + private Map> stationRouteMap = new HashMap<>(); + private BitSet done = new BitSet(); + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[][] R = { + {1, 2, 3, 9}, {9, 3, 4, 5, 8}, {5, 6, 7, 8}, {9, 8, 10, 11}, {12, 13, 14, 6, 1, 2, 3, 5, 7} + }; + System.out.println(new BusRoutes().numBusesToDestination(R, 1, 14)); + } - public int numBusesToDestination(int[][] routes, int S, int T) { - if(S == T) return 0; - for(int i = 0; i < routes.length; i ++){ - Arrays.sort(routes[i]); - int[] n = routes[i]; - for(int j : n){ - if(j == S || j == T){ - stationRouteMap.putIfAbsent(j, new ArrayList<>()); - stationRouteMap.get(j).add(i); - } - } - } - for(int i = 0; i < routes.length; i ++){ - int[] A = routes[i]; - for(int j = i + 1; j < routes.length; j ++){ - int[] B = routes[j]; - if(intersect(A, B)){ - routeGraph.putIfAbsent(i, new HashSet<>()); - routeGraph.putIfAbsent(j, new HashSet<>()); - routeGraph.get(i).add(j); - routeGraph.get(j).add(i); - } - } + public int numBusesToDestination(int[][] routes, int S, int T) { + if (S == T) return 0; + for (int i = 0; i < routes.length; i++) { + Arrays.sort(routes[i]); + int[] n = routes[i]; + for (int j : n) { + if (j == S || j == T) { + stationRouteMap.putIfAbsent(j, new ArrayList<>()); + stationRouteMap.get(j).add(i); } - List start = stationRouteMap.get(S); - if(!stationRouteMap.containsKey(T)) return -1; - Set destination = new HashSet<>(stationRouteMap.get(T)); - Queue queue = new ArrayDeque<>(); - for(int r : start){ - if(destination.contains(r)) return 1; - done.set(r); - queue.offer(new Node(r, 0)); + } + } + for (int i = 0; i < routes.length; i++) { + int[] A = routes[i]; + for (int j = i + 1; j < routes.length; j++) { + int[] B = routes[j]; + if (intersect(A, B)) { + routeGraph.putIfAbsent(i, new HashSet<>()); + routeGraph.putIfAbsent(j, new HashSet<>()); + routeGraph.get(i).add(j); + routeGraph.get(j).add(i); } - while(!queue.isEmpty()){ - Node curr = queue.poll(); - Set children = routeGraph.get(curr.v); - if(children != null){ - for(int c : children){ - if(!done.get(c)){ - done.set(c); - Node child = new Node(c, curr.dist + 1); - if(destination.contains(child.v)){ - return child.dist + 1; - } else{ - queue.offer(child); - } - } - } + } + } + List start = stationRouteMap.get(S); + if (!stationRouteMap.containsKey(T)) return -1; + Set destination = new HashSet<>(stationRouteMap.get(T)); + Queue queue = new ArrayDeque<>(); + for (int r : start) { + if (destination.contains(r)) return 1; + done.set(r); + queue.offer(new Node(r, 0)); + } + while (!queue.isEmpty()) { + Node curr = queue.poll(); + Set children = routeGraph.get(curr.v); + if (children != null) { + for (int c : children) { + if (!done.get(c)) { + done.set(c); + Node child = new Node(c, curr.dist + 1); + if (destination.contains(child.v)) { + return child.dist + 1; + } else { + queue.offer(child); } + } } - return -1; + } } + return -1; + } - private boolean intersect(int[] A, int[] B){ - for(int i = 0, j = 0; i < A.length && j < B.length; ){ - if(A[i] == B[j]) return true; - else if(A[i] < B[j]) i ++; - else j ++; - } - return false; + private boolean intersect(int[] A, int[] B) { + for (int i = 0, j = 0; i < A.length && j < B.length; ) { + if (A[i] == B[j]) return true; + else if (A[i] < B[j]) i++; + else j++; } + return false; + } } diff --git a/problems/src/breadth_first_search/CutOffTreesForGolfEvent.java b/problems/src/breadth_first_search/CutOffTreesForGolfEvent.java index 388550ff..72e2057b 100644 --- a/problems/src/breadth_first_search/CutOffTreesForGolfEvent.java +++ b/problems/src/breadth_first_search/CutOffTreesForGolfEvent.java @@ -1,129 +1,113 @@ package breadth_first_search; + import java.util.*; + /** * Created by gouthamvidyapradhan on 23/06/2018. * - * You are asked to cut off trees in a forest for a golf event. The forest is represented as a non-negative 2D map, - * in this map: - - 0 represents the obstacle can't be reached. - 1 represents the ground can be walked through. - The place with number bigger than 1 represents a tree can be walked through, and this positive number represents the - tree's height. - You are asked to cut off all the trees in this forest in the order of tree's height - always cut off the tree with - lowest height first. And after cutting, the original place has the tree will become a grass (value 1). - - You will start from the point (0, 0) and you should output the minimum steps you need to walk to cut off all the - trees. If you can't cut off all the trees, output -1 in that situation. - - You are guaranteed that no two trees have the same height and there is at least one tree needs to be cut off. - - Example 1: - Input: - [ - [1,2,3], - [0,0,4], - [7,6,5] - ] - Output: 6 - Example 2: - Input: - [ - [1,2,3], - [0,0,0], - [7,6,5] - ] - Output: -1 - Example 3: - Input: - [ - [2,3,4], - [0,0,5], - [8,7,6] - ] - Output: 6 - Explanation: You started from the point (0,0) and you can cut off the tree in (0,0) directly without walking. - Hint: size of the given matrix will not exceed 50x50. - - - Solution: O(N x M) ^ 2: Bfs to each height starting from 1 and calculate the total sum of distance. + *

You are asked to cut off trees in a forest for a golf event. The forest is represented as a + * non-negative 2D map, in this map: + * + *

0 represents the obstacle can't be reached. 1 represents the ground can be walked through. The + * place with number bigger than 1 represents a tree can be walked through, and this positive number + * represents the tree's height. You are asked to cut off all the trees in this forest in the order + * of tree's height - always cut off the tree with lowest height first. And after cutting, the + * original place has the tree will become a grass (value 1). + * + *

You will start from the point (0, 0) and you should output the minimum steps you need to walk + * to cut off all the trees. If you can't cut off all the trees, output -1 in that situation. + * + *

You are guaranteed that no two trees have the same height and there is at least one tree needs + * to be cut off. + * + *

Example 1: Input: [ [1,2,3], [0,0,4], [7,6,5] ] Output: 6 Example 2: Input: [ [1,2,3], + * [0,0,0], [7,6,5] ] Output: -1 Example 3: Input: [ [2,3,4], [0,0,5], [8,7,6] ] Output: 6 + * Explanation: You started from the point (0,0) and you can cut off the tree in (0,0) directly + * without walking. Hint: size of the given matrix will not exceed 50x50. + * + *

Solution: O(N x M) ^ 2: Bfs to each height starting from 1 and calculate the total sum of + * distance. */ public class CutOffTreesForGolfEvent { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception {} - } + private static final int[] R = {0, 0, 1, -1}; + private static final int[] C = {1, -1, 0, 0}; - private static final int[] R = {0, 0, 1, -1}; - private static final int[] C = {1, -1, 0, 0}; + static class Cell implements Comparable { + int r, c; + int distance; + int height; - static class Cell implements Comparable{ - int r, c; - int distance; - int height; - Cell(int r, int c){ - this.r = r; - this.c = c; - } - @Override - public int compareTo(Cell o) { - return Integer.compare(this.height, o.height); - } + Cell(int r, int c) { + this.r = r; + this.c = c; } - public int cutOffTree(List> forest) { - int distance = 0; - List trees = new ArrayList<>(); - for(int i = 0; i < forest.size(); i ++){ - for(int j = 0; j < forest.get(0).size(); j ++) { - if(forest.get(i).get(j) > 1){ - Cell cell = new Cell(i, j); - cell.height = forest.get(i).get(j); - trees.add(cell); - } - } - } - Collections.sort(trees); - int sR = 0, sC = 0; - for(Cell t : trees){ - int dist = bfs(forest, t.height, sR, sC); - if(dist == -1) return -1; - else distance += dist; - sR = t.r; - sC = t.c; - } - return distance; + @Override + public int compareTo(Cell o) { + return Integer.compare(this.height, o.height); } + } - private int bfs(List> forest, int target, int sR, int sC){ - if(forest.get(sR).get(sC) == target) { - forest.get(sR).set(sC, 1); - return 0; + public int cutOffTree(List> forest) { + int distance = 0; + List trees = new ArrayList<>(); + for (int i = 0; i < forest.size(); i++) { + for (int j = 0; j < forest.get(0).size(); j++) { + if (forest.get(i).get(j) > 1) { + Cell cell = new Cell(i, j); + cell.height = forest.get(i).get(j); + trees.add(cell); } - Cell start = new Cell(sR, sC); - start.distance = 0; - Queue queue = new ArrayDeque<>(); - queue.add(start); - boolean[][] done = new boolean[forest.size()][forest.get(0).size()]; - done[sR][sC] = true; - while(!queue.isEmpty()){ - Cell cell = queue.poll(); - for(int i = 0; i < 4; i ++){ - int newR = cell.r + R[i]; - int newC = cell.c + C[i]; - Cell newCell = new Cell(newR, newC); - if(newR >= 0 && newR < forest.size() && newC >= 0 && newC < forest.get(0).size() && - forest.get(newR).get(newC) != 0 && !done[newCell.r][newCell.c]) { - newCell.distance = cell.distance + 1; - if(forest.get(newR).get(newC) == target){ - forest.get(newR).set(newC, 1); - return newCell.distance; - } - done[newCell.r][newCell.c] = true; - queue.offer(newCell); - } - } + } + } + Collections.sort(trees); + int sR = 0, sC = 0; + for (Cell t : trees) { + int dist = bfs(forest, t.height, sR, sC); + if (dist == -1) return -1; + else distance += dist; + sR = t.r; + sC = t.c; + } + return distance; + } + + private int bfs(List> forest, int target, int sR, int sC) { + if (forest.get(sR).get(sC) == target) { + forest.get(sR).set(sC, 1); + return 0; + } + Cell start = new Cell(sR, sC); + start.distance = 0; + Queue queue = new ArrayDeque<>(); + queue.add(start); + boolean[][] done = new boolean[forest.size()][forest.get(0).size()]; + done[sR][sC] = true; + while (!queue.isEmpty()) { + Cell cell = queue.poll(); + for (int i = 0; i < 4; i++) { + int newR = cell.r + R[i]; + int newC = cell.c + C[i]; + Cell newCell = new Cell(newR, newC); + if (newR >= 0 + && newR < forest.size() + && newC >= 0 + && newC < forest.get(0).size() + && forest.get(newR).get(newC) != 0 + && !done[newCell.r][newCell.c]) { + newCell.distance = cell.distance + 1; + if (forest.get(newR).get(newC) == target) { + forest.get(newR).set(newC, 1); + return newCell.distance; + } + done[newCell.r][newCell.c] = true; + queue.offer(newCell); } - return -1; + } } + return -1; + } } diff --git a/problems/src/breadth_first_search/Matrix.java b/problems/src/breadth_first_search/Matrix.java index 76f28186..1c6eb9da 100644 --- a/problems/src/breadth_first_search/Matrix.java +++ b/problems/src/breadth_first_search/Matrix.java @@ -1,104 +1,90 @@ package breadth_first_search; import java.util.*; + /** - * Created by gouthamvidyapradhan on 14/03/2019 - * Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell. + * Created by gouthamvidyapradhan on 14/03/2019 Given a matrix consists of 0 and 1, find the + * distance of the nearest 0 for each cell. * - * The distance between two adjacent cells is 1. - * Example 1: - * Input: + *

The distance between two adjacent cells is 1. Example 1: Input: * - * 0 0 0 - * 0 1 0 - * 0 0 0 - * Output: - * 0 0 0 - * 0 1 0 - * 0 0 0 - * Example 2: - * Input: + *

0 0 0 0 1 0 0 0 0 Output: 0 0 0 0 1 0 0 0 0 Example 2: Input: * - * 0 0 0 - * 0 1 0 - * 1 1 1 - * Output: - * 0 0 0 - * 0 1 0 - * 1 2 1 - * Note: - * The number of elements of the given matrix will not exceed 10,000. - * There are at least one 0 in the given matrix. - * The cells are adjacent in only four directions: up, down, left and right. + *

0 0 0 0 1 0 1 1 1 Output: 0 0 0 0 1 0 1 2 1 Note: The number of elements of the given matrix + * will not exceed 10,000. There are at least one 0 in the given matrix. The cells are adjacent in + * only four directions: up, down, left and right. * - * Solution: Add all the 0th cell to the queue and do a multi-source bfs to count the minimum distance + *

Solution: Add all the 0th cell to the queue and do a multi-source bfs to count the minimum + * distance */ public class Matrix { - private static class Node{ - int r, c; - int d; - Node(int r, int c){ - this.r = r; - this.c = c; - } + private static class Node { + int r, c; + int d; - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Node)) return false; - Node node = (Node) o; - return r == node.r && - c == node.c; - } + Node(int r, int c) { + this.r = r; + this.c = c; + } - @Override - public int hashCode() { - return Objects.hash(r, c); - } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Node)) return false; + Node node = (Node) o; + return r == node.r && c == node.c; } - private final int[] R = {0, 0, 1, -1}; - private final int[] C = {1, -1, 0, 0}; - private Set done; - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int[][] temp = {{0, 0, 0}, {0, 1, 0}, {1, 1, 1}}; - int[][] result = new Matrix().updateMatrix(temp); - System.out.println(); + + @Override + public int hashCode() { + return Objects.hash(r, c); } + } - public int[][] updateMatrix(int[][] matrix) { - int[][] temp = new int[matrix.length][matrix[0].length]; - done = new HashSet<>(); - Queue queue = new ArrayDeque<>(); - for(int i = 0; i < matrix.length; i ++){ - for(int j = 0; j < matrix[0].length; j ++){ - temp[i][j] = matrix[i][j]; - if(matrix[i][j] == 0){ - Node node = new Node(i, j); - queue.offer(node); - done.add(node); - } - } + private final int[] R = {0, 0, 1, -1}; + private final int[] C = {1, -1, 0, 0}; + private Set done; + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[][] temp = {{0, 0, 0}, {0, 1, 0}, {1, 1, 1}}; + int[][] result = new Matrix().updateMatrix(temp); + System.out.println(); + } + + public int[][] updateMatrix(int[][] matrix) { + int[][] temp = new int[matrix.length][matrix[0].length]; + done = new HashSet<>(); + Queue queue = new ArrayDeque<>(); + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix[0].length; j++) { + temp[i][j] = matrix[i][j]; + if (matrix[i][j] == 0) { + Node node = new Node(i, j); + queue.offer(node); + done.add(node); } - while(!queue.isEmpty()){ - Node curr = queue.poll(); - for(int i = 0; i < 4; i ++){ - int newR = curr.r + R[i]; - int newC = curr.c + C[i]; - if(newR >= 0 && newR < matrix.length && newC >= 0 && newC < matrix[0].length){ - Node child = new Node(newR, newC); - if(!done.contains(child)){ - done.add(child); - child.d = curr.d + 1; - temp[newR][newC] = child.d; - queue.offer(child); - } - } - } + } + } + while (!queue.isEmpty()) { + Node curr = queue.poll(); + for (int i = 0; i < 4; i++) { + int newR = curr.r + R[i]; + int newC = curr.c + C[i]; + if (newR >= 0 && newR < matrix.length && newC >= 0 && newC < matrix[0].length) { + Node child = new Node(newR, newC); + if (!done.contains(child)) { + done.add(child); + child.d = curr.d + 1; + temp[newR][newC] = child.d; + queue.offer(child); + } } - return temp; + } } + return temp; + } } diff --git a/problems/src/breadth_first_search/OpenTheLock.java b/problems/src/breadth_first_search/OpenTheLock.java index a9f0c8e0..49bcde56 100644 --- a/problems/src/breadth_first_search/OpenTheLock.java +++ b/problems/src/breadth_first_search/OpenTheLock.java @@ -3,97 +3,86 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 09/02/2018. - * You have a lock in front of you with 4 circular wheels. Each wheel has 10 slots: '0', '1', '2', '3', '4', '5', - * '6', '7', '8', '9'. The wheels can rotate freely and wrap around: for example we can turn '9' to be '0', or '0' - * to be '9'. Each move consists of turning one wheel one slot. - - The lock initially starts at '0000', a string representing the state of the 4 wheels. - - You are given a list of deadends dead ends, meaning if the lock displays any of these codes, the wheels of the lock - will stop turning and you will be unable to open it. - - Given a target representing the value of the wheels that will unlock the lock, return the minimum total number of - turns required to open the lock, or -1 if it is impossible. - - Example 1: - Input: deadends = ["0201","0101","0102","1212","2002"], target = "0202" - Output: 6 - Explanation: - A sequence of valid moves would be "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "0202". - Note that a sequence like "0000" -> "0001" -> "0002" -> "0102" -> "0202" would be invalid, - because the wheels of the lock become stuck after the display becomes the dead end "0102". - Example 2: - Input: deadends = ["8888"], target = "0009" - Output: 1 - Explanation: - We can turn the last wheel in reverse to move from "0000" -> "0009". - Example 3: - Input: deadends = ["8887","8889","8878","8898","8788","8988","7888","9888"], target = "8888" - Output: -1 - Explanation: - We can't reach the target without getting stuck. - Example 4: - Input: deadends = ["0000"], target = "8888" - Output: -1 - Note: - The length of deadends will be in the range [1, 500]. - target will not be in the list deadends. - Every string in deadends and the string target will be a string of4 digits from the 10,000 possibilities '0000' to '9999'. - - Solution: Perform a bfs of each state starting from 0000 and return the minimum distance. + * Created by gouthamvidyapradhan on 09/02/2018. You have a lock in front of you with 4 circular + * wheels. Each wheel has 10 slots: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'. The wheels can + * rotate freely and wrap around: for example we can turn '9' to be '0', or '0' to be '9'. Each move + * consists of turning one wheel one slot. + * + *

The lock initially starts at '0000', a string representing the state of the 4 wheels. + * + *

You are given a list of deadends dead ends, meaning if the lock displays any of these codes, + * the wheels of the lock will stop turning and you will be unable to open it. + * + *

Given a target representing the value of the wheels that will unlock the lock, return the + * minimum total number of turns required to open the lock, or -1 if it is impossible. + * + *

Example 1: Input: deadends = ["0201","0101","0102","1212","2002"], target = "0202" Output: 6 + * Explanation: A sequence of valid moves would be "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> + * "1202" -> "0202". Note that a sequence like "0000" -> "0001" -> "0002" -> "0102" -> "0202" would + * be invalid, because the wheels of the lock become stuck after the display becomes the dead end + * "0102". Example 2: Input: deadends = ["8888"], target = "0009" Output: 1 Explanation: We can turn + * the last wheel in reverse to move from "0000" -> "0009". Example 3: Input: deadends = + * ["8887","8889","8878","8898","8788","8988","7888","9888"], target = "8888" Output: -1 + * Explanation: We can't reach the target without getting stuck. Example 4: Input: deadends = + * ["0000"], target = "8888" Output: -1 Note: The length of deadends will be in the range [1, 500]. + * target will not be in the list deadends. Every string in deadends and the string target will be a + * string of4 digits from the 10,000 possibilities '0000' to '9999'. + * + *

Solution: Perform a bfs of each state starting from 0000 and return the minimum distance. */ public class OpenTheLock { - class State{ - String state; - int dist; - State(String state, int dist){ - this.state = state; - this.dist = dist; - } - } - private Set done; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - String[] A = {"0201","0101","0102","1212","2002"}; - System.out.println(new OpenTheLock().openLock(A, "0202")); + class State { + String state; + int dist; + + State(String state, int dist) { + this.state = state; + this.dist = dist; } + } + + private Set done; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + String[] A = {"0201", "0101", "0102", "1212", "2002"}; + System.out.println(new OpenTheLock().openLock(A, "0202")); + } - public int openLock(String[] deadends, String target) { - done = new HashSet<>(); - Arrays.stream(deadends).forEach(e -> done.add(e)); - if(done.contains("0000")) return -1; - if(target.equals("0000")) return 0; - Queue queue = new ArrayDeque<>(); - queue.offer(new State("0000", 0)); - done.add("0000"); - while(!queue.isEmpty()){ - State state = queue.poll(); - if(state.state.equals(target)) return state.dist; - String currState = state.state; - for(int i = 0; i < 4; i ++){ - char c = currState.charAt(i); - int cV = Integer.parseInt(String.valueOf(c)); - String prefix = currState.substring(0, i); - String postFix = currState.substring(i + 1, 4); - String newChild1 = prefix + (((cV + 1) > 9) ? 0 : (cV + 1)) + postFix; - if(!done.contains(newChild1)){ - queue.offer(new State(newChild1, state.dist + 1)); - done.add(newChild1); - } - String newChild2 = prefix + (((cV - 1) < 0) ? 9 : (cV - 1)) + postFix; - if(!done.contains(newChild2)){ - queue.offer(new State(newChild2, state.dist + 1)); - done.add(newChild2); - } - } + public int openLock(String[] deadends, String target) { + done = new HashSet<>(); + Arrays.stream(deadends).forEach(e -> done.add(e)); + if (done.contains("0000")) return -1; + if (target.equals("0000")) return 0; + Queue queue = new ArrayDeque<>(); + queue.offer(new State("0000", 0)); + done.add("0000"); + while (!queue.isEmpty()) { + State state = queue.poll(); + if (state.state.equals(target)) return state.dist; + String currState = state.state; + for (int i = 0; i < 4; i++) { + char c = currState.charAt(i); + int cV = Integer.parseInt(String.valueOf(c)); + String prefix = currState.substring(0, i); + String postFix = currState.substring(i + 1, 4); + String newChild1 = prefix + (((cV + 1) > 9) ? 0 : (cV + 1)) + postFix; + if (!done.contains(newChild1)) { + queue.offer(new State(newChild1, state.dist + 1)); + done.add(newChild1); } - return -1; + String newChild2 = prefix + (((cV - 1) < 0) ? 9 : (cV - 1)) + postFix; + if (!done.contains(newChild2)) { + queue.offer(new State(newChild2, state.dist + 1)); + done.add(newChild2); + } + } } - + return -1; + } } diff --git a/problems/src/breadth_first_search/RaceCar.java b/problems/src/breadth_first_search/RaceCar.java index 3db18984..21c8705a 100644 --- a/problems/src/breadth_first_search/RaceCar.java +++ b/problems/src/breadth_first_search/RaceCar.java @@ -3,105 +3,96 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 19/08/2018 - * Your car starts at position 0 and speed +1 on an infinite number line. (Your car can go into negative positions.) + * Created by gouthamvidyapradhan on 19/08/2018 Your car starts at position 0 and speed +1 on an + * infinite number line. (Your car can go into negative positions.) * - * Your car drives automatically according to a sequence of instructions A (accelerate) and R (reverse). + *

Your car drives automatically according to a sequence of instructions A (accelerate) and R + * (reverse). * - * When you get an instruction "A", your car does the following: position += speed, speed *= 2. + *

When you get an instruction "A", your car does the following: position += speed, speed *= 2. * - * When you get an instruction "R", your car does the following: if your speed is positive then speed = -1 , - * otherwise speed = 1. (Your position stays the same.) + *

When you get an instruction "R", your car does the following: if your speed is positive then + * speed = -1 , otherwise speed = 1. (Your position stays the same.) * - * For example, after commands "AAR", your car goes to positions 0->1->3->3, and your speed goes to 1->2->4->-1. + *

For example, after commands "AAR", your car goes to positions 0->1->3->3, and your speed goes + * to 1->2->4->-1. * - * Now for some target position, say the length of the shortest sequence of instructions to get there. + *

Now for some target position, say the length of the shortest sequence of instructions to get + * there. * - * Example 1: - * Input: - * target = 3 - * Output: 2 - * Explanation: - * The shortest instruction sequence is "AA". - * Your position goes from 0->1->3. - * Example 2: - * Input: - * target = 6 - * Output: 5 - * Explanation: - * The shortest instruction sequence is "AAARA". - * Your position goes from 0->1->3->7->7->6. + *

Example 1: Input: target = 3 Output: 2 Explanation: The shortest instruction sequence is "AA". + * Your position goes from 0->1->3. Example 2: Input: target = 6 Output: 5 Explanation: The shortest + * instruction sequence is "AAARA". Your position goes from 0->1->3->7->7->6. * + *

Note: * - * Note: + *

1 <= target <= 10000. * - * 1 <= target <= 10000. - * - * Solution: O(n log n) Do a BFS and visit every possible state. Prune the search space by avoiding negative vertices - * and keep a boundary target of approximately (target * 2) - beyond this boundary target the race car should not - * progress in the forward direction. + *

Solution: O(n log n) Do a BFS and visit every possible state. Prune the search space by + * avoiding negative vertices and keep a boundary target of approximately (target * 2) - beyond this + * boundary target the race car should not progress in the forward direction. */ public class RaceCar { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - System.out.println(new RaceCar().racecar(1000)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + System.out.println(new RaceCar().racecar(1000)); + } - private class Node{ - int v, s, d; - Node(int v, int s, int d){ - this.v = v; - this.s = s; - this.d = d; - } + private class Node { + int v, s, d; - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Node)) return false; - Node node = (Node) o; - return v == node.v && - s == node.s; - } + Node(int v, int s, int d) { + this.v = v; + this.s = s; + this.d = d; + } - @Override - public int hashCode() { - return Objects.hash(v, s); - } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Node)) return false; + Node node = (Node) o; + return v == node.v && s == node.s; } - public int racecar(int target) { - if(target == 0) return 0; - Queue queue = new ArrayDeque<>(); - Set done = new HashSet<>(); - Node start = new Node(0, 1, 0); - done.add(start); - queue.offer(start); - while(!queue.isEmpty()){ - Node curr = queue.poll(); - if(curr.v < (target * 2)){ - Node c1 = new Node(curr.v + curr.s, curr.s * 2, curr.d + 1); - if(c1.v >= 0){ - if(!done.contains(c1)){ - queue.offer(c1); - done.add(c1); - if(target == c1.v){ - return c1.d; - } - } - } - } - Node c2 = new Node(curr.v, curr.s < 0 ? 1 : -1, curr.d + 1); - if(!done.contains(c2)){ - done.add(c2); - queue.offer(c2); + @Override + public int hashCode() { + return Objects.hash(v, s); + } + } + + public int racecar(int target) { + if (target == 0) return 0; + Queue queue = new ArrayDeque<>(); + Set done = new HashSet<>(); + Node start = new Node(0, 1, 0); + done.add(start); + queue.offer(start); + while (!queue.isEmpty()) { + Node curr = queue.poll(); + if (curr.v < (target * 2)) { + Node c1 = new Node(curr.v + curr.s, curr.s * 2, curr.d + 1); + if (c1.v >= 0) { + if (!done.contains(c1)) { + queue.offer(c1); + done.add(c1); + if (target == c1.v) { + return c1.d; } + } } - return -1; + } + Node c2 = new Node(curr.v, curr.s < 0 ? 1 : -1, curr.d + 1); + if (!done.contains(c2)) { + done.add(c2); + queue.offer(c2); + } } - + return -1; + } } diff --git a/problems/src/breadth_first_search/SlidingPuzzle.java b/problems/src/breadth_first_search/SlidingPuzzle.java index 5fb39cc1..4fa7723a 100644 --- a/problems/src/breadth_first_search/SlidingPuzzle.java +++ b/problems/src/breadth_first_search/SlidingPuzzle.java @@ -1,146 +1,140 @@ package breadth_first_search; + import java.util.*; /** - * Created by gouthamvidyapradhan on 17/03/2019 - * On a 2x3 board, there are 5 tiles represented by the integers 1 through 5, and an empty square represented by 0. + * Created by gouthamvidyapradhan on 17/03/2019 On a 2x3 board, there are 5 tiles represented by the + * integers 1 through 5, and an empty square represented by 0. * - * A move consists of choosing 0 and a 4-directionally adjacent number and swapping it. + *

A move consists of choosing 0 and a 4-directionally adjacent number and swapping it. * - * The state of the board is solved if and only if the board is [[1,2,3],[4,5,0]]. + *

The state of the board is solved if and only if the board is [[1,2,3],[4,5,0]]. * - * Given a puzzle board, return the least number of moves required so that the state of the board is solved. If it - * is impossible for the state of the board to be solved, return -1. + *

Given a puzzle board, return the least number of moves required so that the state of the board + * is solved. If it is impossible for the state of the board to be solved, return -1. * - * Examples: + *

Examples: * - * Input: board = [[1,2,3],[4,0,5]] - * Output: 1 - * Explanation: Swap the 0 and the 5 in one move. - * Input: board = [[1,2,3],[5,4,0]] - * Output: -1 - * Explanation: No number of moves will make the board solved. - * Input: board = [[4,1,2],[5,0,3]] - * Output: 5 - * Explanation: 5 is the smallest number of moves that solves the board. - * An example path: - * After move 0: [[4,1,2],[5,0,3]] - * After move 1: [[4,1,2],[0,5,3]] - * After move 2: [[0,1,2],[4,5,3]] - * After move 3: [[1,0,2],[4,5,3]] - * After move 4: [[1,2,0],[4,5,3]] - * After move 5: [[1,2,3],[4,5,0]] - * Input: board = [[3,2,4],[1,5,0]] - * Output: 14 + *

Input: board = [[1,2,3],[4,0,5]] Output: 1 Explanation: Swap the 0 and the 5 in one move. + * Input: board = [[1,2,3],[5,4,0]] Output: -1 Explanation: No number of moves will make the board + * solved. Input: board = [[4,1,2],[5,0,3]] Output: 5 Explanation: 5 is the smallest number of moves + * that solves the board. An example path: After move 0: [[4,1,2],[5,0,3]] After move 1: + * [[4,1,2],[0,5,3]] After move 2: [[0,1,2],[4,5,3]] After move 3: [[1,0,2],[4,5,3]] After move 4: + * [[1,2,0],[4,5,3]] After move 5: [[1,2,3],[4,5,0]] Input: board = [[3,2,4],[1,5,0]] Output: 14 * Note: * - * board will be a 2 x 3 array as described above. - * board[i][j] will be a permutation of [0, 1, 2, 3, 4, 5]. + *

board will be a 2 x 3 array as described above. board[i][j] will be a permutation of [0, 1, 2, + * 3, 4, 5]. * - * Solution: Do a bfs of each state of the board to find the least possible moves. + *

Solution: Do a bfs of each state of the board to find the least possible moves. */ public class SlidingPuzzle { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int[][] board = {{1, 2, 3}, {4, 0, 5}}; - System.out.println(new SlidingPuzzle().slidingPuzzle(board)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[][] board = {{1, 2, 3}, {4, 0, 5}}; + System.out.println(new SlidingPuzzle().slidingPuzzle(board)); + } - class Node{ - Node(Board b){ - this.b = b; - } - Board b; - int dist; + class Node { + Node(Board b) { + this.b = b; } - private static final int[] R = {-1, 0, 0, 1}; - private static final int[] C = {0, 1, -1, 0}; - private static final String result = "123450"; - class Board{ - int[][] board; - int r, c; - final String state; - Board(int[][] board){ - this.board = board; - StringBuilder sb = new StringBuilder(); - for(int i = 0; i < 2; i ++){ - for(int j = 0; j < 3; j++){ - sb.append(board[i][j]); - } - } - state = sb.toString(); - } + Board b; + int dist; + } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Board)) return false; - Board board = (Board) o; - return Objects.equals(state, board.state); - } + private static final int[] R = {-1, 0, 0, 1}; + private static final int[] C = {0, 1, -1, 0}; + private static final String result = "123450"; + + class Board { + int[][] board; + int r, c; + final String state; - @Override - public int hashCode() { - return Objects.hash(state); + Board(int[][] board) { + this.board = board; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 3; j++) { + sb.append(board[i][j]); } + } + state = sb.toString(); } - private Set done; - public int slidingPuzzle(int[][] board) { - done = new HashSet<>(); - Board b = new Board(board); - for(int i = 0; i < board.length; i ++){ - for(int j = 0; j < board[0].length; j ++){ - if(board[i][j] == 0){ - b.r = i; - b.c = j; - break; - } - } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Board)) return false; + Board board = (Board) o; + return Objects.equals(state, board.state); + } + + @Override + public int hashCode() { + return Objects.hash(state); + } + } + + private Set done; + + public int slidingPuzzle(int[][] board) { + done = new HashSet<>(); + Board b = new Board(board); + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (board[i][j] == 0) { + b.r = i; + b.c = j; + break; } - if(b.state.equals(result)) return 0; - Queue queue = new ArrayDeque<>(); - queue.offer(new Node(b)); - while(!queue.isEmpty()){ - Node child = queue.poll(); - Board br = child.b; - done.add(br); - for(int i = 0; i < 4; i++){ - int newR = br.r + R[i]; - int newC = br.c + C[i]; - if(newR < 0 || newR >= 2 || newC < 0 || newC >= 3)continue; - int num = br.board[newR][newC]; - int[][] tempB = clone(br.board); - tempB[newR][newC] = 0; - tempB[br.r][br.c] = num; - Board tempBoard = new Board(tempB); - tempBoard.r = newR; - tempBoard.c = newC; - if(!done.contains(tempBoard)){ - if(tempBoard.state.equals(result)){ - return child.dist + 1; - } - Node newChild = new Node(tempBoard); - newChild.dist = child.dist + 1; - queue.offer(newChild); - } - } + } + } + if (b.state.equals(result)) return 0; + Queue queue = new ArrayDeque<>(); + queue.offer(new Node(b)); + while (!queue.isEmpty()) { + Node child = queue.poll(); + Board br = child.b; + done.add(br); + for (int i = 0; i < 4; i++) { + int newR = br.r + R[i]; + int newC = br.c + C[i]; + if (newR < 0 || newR >= 2 || newC < 0 || newC >= 3) continue; + int num = br.board[newR][newC]; + int[][] tempB = clone(br.board); + tempB[newR][newC] = 0; + tempB[br.r][br.c] = num; + Board tempBoard = new Board(tempB); + tempBoard.r = newR; + tempBoard.c = newC; + if (!done.contains(tempBoard)) { + if (tempBoard.state.equals(result)) { + return child.dist + 1; + } + Node newChild = new Node(tempBoard); + newChild.dist = child.dist + 1; + queue.offer(newChild); } - return -1; + } } + return -1; + } - private int[][] clone(int[][] original){ - int[][] cloned = new int[2][3]; - for(int i = 0; i < 2; i ++){ - for(int j = 0; j < 3; j++){ - cloned[i][j] = original[i][j]; - } - } - return cloned; + private int[][] clone(int[][] original) { + int[][] cloned = new int[2][3]; + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 3; j++) { + cloned[i][j] = original[i][j]; + } } + return cloned; + } } diff --git a/problems/src/breadth_first_search/WallsAndGates.java b/problems/src/breadth_first_search/WallsAndGates.java index 08bc6e59..29c027ec 100644 --- a/problems/src/breadth_first_search/WallsAndGates.java +++ b/problems/src/breadth_first_search/WallsAndGates.java @@ -4,78 +4,72 @@ import java.util.Queue; /** - * Created by gouthamvidyapradhan on 26/12/2017. - * You are given a m x n 2D grid initialized with these three possible values. - - -1 - A wall or an obstacle. - 0 - A gate. - INF - Infinity means an empty room. We use the value 231 - 1 = 2147483647 to represent INF as you may assume that - the distance to a gate is less than 2147483647. - Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, it should be filled - with INF. - - For example, given the 2D grid: - INF -1 0 INF - INF INF INF -1 - INF -1 INF -1 - 0 -1 INF INF - After running your function, the 2D grid should be: - 3 -1 0 1 - 2 2 1 -1 - 1 -1 2 -1 - 0 -1 3 4 - - Solution: O(n x m): Treat each coordinate of grid with 0 as a source and destination as the coordinate of 2147483647 - and perform a multi-sources BFS from each source. + * Created by gouthamvidyapradhan on 26/12/2017. You are given a m x n 2D grid initialized with + * these three possible values. + * + *

-1 - A wall or an obstacle. 0 - A gate. INF - Infinity means an empty room. We use the value + * 231 - 1 = 2147483647 to represent INF as you may assume that the distance to a gate is less than + * 2147483647. Fill each empty room with the distance to its nearest gate. If it is impossible to + * reach a gate, it should be filled with INF. + * + *

For example, given the 2D grid: INF -1 0 INF INF INF INF -1 INF -1 INF -1 0 -1 INF INF After + * running your function, the 2D grid should be: 3 -1 0 1 2 2 1 -1 1 -1 2 -1 0 -1 3 4 + * + *

Solution: O(n x m): Treat each coordinate of grid with 0 as a source and destination as the + * coordinate of 2147483647 and perform a multi-sources BFS from each source. */ public class WallsAndGates { - private static final int[] R = {0, 0, 1, -1}; - private static final int[] C = {1, -1, 0, 0}; + private static final int[] R = {0, 0, 1, -1}; + private static final int[] C = {1, -1, 0, 0}; - private class Cell{ - int r, c; - Cell(int r, int c){ - this.r = r; - this.c = c; - } - } + private class Cell { + int r, c; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[][] A = {{Integer.MAX_VALUE, -1, 0, Integer.MAX_VALUE}, - {Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, -1}, - {Integer.MAX_VALUE, -1, Integer.MAX_VALUE, -1}, - {0, -1, Integer.MAX_VALUE, Integer.MAX_VALUE}}; - new WallsAndGates().wallsAndGates(A); + Cell(int r, int c) { + this.r = r; + this.c = c; } + } + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[][] A = { + {Integer.MAX_VALUE, -1, 0, Integer.MAX_VALUE}, + {Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, -1}, + {Integer.MAX_VALUE, -1, Integer.MAX_VALUE, -1}, + {0, -1, Integer.MAX_VALUE, Integer.MAX_VALUE} + }; + new WallsAndGates().wallsAndGates(A); + } - public void wallsAndGates(int[][] rooms) { - Queue queue = new ArrayDeque<>(); - for(int i = 0; i < rooms.length; i ++){ - for(int j = 0; j < rooms[0].length; j ++){ - if(rooms[i][j] == 0){ //treat each co-ordinates of gate as a source - Cell cell = new Cell(i, j); - queue.offer(cell); - } - } + public void wallsAndGates(int[][] rooms) { + Queue queue = new ArrayDeque<>(); + for (int i = 0; i < rooms.length; i++) { + for (int j = 0; j < rooms[0].length; j++) { + if (rooms[i][j] == 0) { // treat each co-ordinates of gate as a source + Cell cell = new Cell(i, j); + queue.offer(cell); } - while(!queue.isEmpty()){ - Cell top = queue.poll(); - for(int i = 0; i < 4; i++){ - int newR = top.r + R[i]; - int newC = top.c + C[i]; - if(newR >= 0 && newC >= 0 && newR < rooms.length && newC < rooms[0].length){ - if(rooms[newR][newC] == Integer.MAX_VALUE){ - rooms[newR][newC] = rooms[top.r][top.c] + 1; - queue.offer(new Cell(newR, newC)); - } - } - } + } + } + while (!queue.isEmpty()) { + Cell top = queue.poll(); + for (int i = 0; i < 4; i++) { + int newR = top.r + R[i]; + int newC = top.c + C[i]; + if (newR >= 0 && newC >= 0 && newR < rooms.length && newC < rooms[0].length) { + if (rooms[newR][newC] == Integer.MAX_VALUE) { + rooms[newR][newC] = rooms[top.r][top.c] + 1; + queue.offer(new Cell(newR, newC)); + } } + } } + } } diff --git a/problems/src/breadth_first_search/WordLadder.java b/problems/src/breadth_first_search/WordLadder.java index c7a4444d..6a71f9d1 100644 --- a/problems/src/breadth_first_search/WordLadder.java +++ b/problems/src/breadth_first_search/WordLadder.java @@ -3,86 +3,76 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 21/03/2017. - * Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that: - *

- * Only one letter can be changed at a time. - * Each transformed word must exist in the word list. Note that beginWord is not a transformed word. - * For example, - *

- * Given: - * beginWord = "hit" - * endWord = "cog" - * wordList = ["hot","dot","dog","lot","log","cog"] - * As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", - * return its length 5. - *

- * Note: - * Return 0 if there is no such transformation sequence. - * All words have the same length. - * All words contain only lowercase alphabetic characters. - * You may assume no duplicates in the word list. - * You may assume beginWord and endWord are non-empty and are not the same. + * Created by gouthamvidyapradhan on 21/03/2017. Given two words (beginWord and endWord), and a + * dictionary's word list, find the length of shortest transformation sequence from beginWord to + * endWord, such that: + * + *

Only one letter can be changed at a time. Each transformed word must exist in the word list. + * Note that beginWord is not a transformed word. For example, + * + *

Given: beginWord = "hit" endWord = "cog" wordList = ["hot","dot","dog","lot","log","cog"] As + * one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", return its length 5. + * + *

Note: Return 0 if there is no such transformation sequence. All words have the same length. + * All words contain only lowercase alphabetic characters. You may assume no duplicates in the word + * list. You may assume beginWord and endWord are non-empty and are not the same. */ public class WordLadder { - class State { - String word; - int len; + class State { + String word; + int len; - State(String word, int len) { - this.word = word; - this.len = len; - } + State(String word, int len) { + this.word = word; + this.len = len; } + } - private static Queue queue = new ArrayDeque<>(); - private static Set dictionary = new HashSet<>(); - private static final String CONST = "abcdefghijklmnopqrstuvwxyz"; - private static Set done = new HashSet<>(); - - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - List list = new ArrayList<>(); - list.add("hot"); - list.add("dot"); - list.add("dog"); - list.add("lot"); - list.add("log"); - list.add("cog"); - System.out.println(new WordLadder().ladderLength("hit", "cog", list)); - } + private static Queue queue = new ArrayDeque<>(); + private static Set dictionary = new HashSet<>(); + private static final String CONST = "abcdefghijklmnopqrstuvwxyz"; + private static Set done = new HashSet<>(); + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + List list = new ArrayList<>(); + list.add("hot"); + list.add("dot"); + list.add("dog"); + list.add("lot"); + list.add("log"); + list.add("cog"); + System.out.println(new WordLadder().ladderLength("hit", "cog", list)); + } - public int ladderLength(String beginWord, String endWord, List wordList) { - dictionary.addAll(wordList); - queue.offer(new State(beginWord, 0)); - done.add(beginWord); - while (!queue.isEmpty()) { - State head = queue.poll(); - if (head.word.equals(endWord)) - return head.len + 1; - for (int i = 0, l = CONST.length(); i < l; i++) { - StringBuilder word = new StringBuilder(head.word); - for (int j = 0, ln = word.length(); j < ln; j++) { - char old = word.charAt(j); - word.replace(j, j + 1, String.valueOf(CONST.charAt(i))); - if (!done.contains(word.toString())) { - if (dictionary.contains(word.toString())) { - done.add(word.toString()); - queue.offer(new State(word.toString(), head.len + 1)); - } - } - word.replace(j, j + 1, String.valueOf(old)); - } + public int ladderLength(String beginWord, String endWord, List wordList) { + dictionary.addAll(wordList); + queue.offer(new State(beginWord, 0)); + done.add(beginWord); + while (!queue.isEmpty()) { + State head = queue.poll(); + if (head.word.equals(endWord)) return head.len + 1; + for (int i = 0, l = CONST.length(); i < l; i++) { + StringBuilder word = new StringBuilder(head.word); + for (int j = 0, ln = word.length(); j < ln; j++) { + char old = word.charAt(j); + word.replace(j, j + 1, String.valueOf(CONST.charAt(i))); + if (!done.contains(word.toString())) { + if (dictionary.contains(word.toString())) { + done.add(word.toString()); + queue.offer(new State(word.toString(), head.len + 1)); } + } + word.replace(j, j + 1, String.valueOf(old)); } - return 0; + } } - + return 0; + } } diff --git a/problems/src/breadth_first_search/WordLadderII.java b/problems/src/breadth_first_search/WordLadderII.java index f25325d4..686dd9cf 100644 --- a/problems/src/breadth_first_search/WordLadderII.java +++ b/problems/src/breadth_first_search/WordLadderII.java @@ -3,128 +3,166 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 24/03/2017. - * Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that: - *

- * Only one letter can be changed at a time - * Each transformed word must exist in the word list. Note that beginWord is not a transformed word. - * For example, - *

- * Given: - * beginWord = "hit" - * endWord = "cog" - * wordList = ["hot","dot","dog","lot","log","cog"] - * Return - * [ - * ["hit","hot","dot","dog","cog"], - * ["hit","hot","lot","log","cog"] - * ] - * Note: - * Return an empty list if there is no such transformation sequence. - * All words have the same length. - * All words contain only lowercase alphabetic characters. - * You may assume no duplicates in the word list. - * You may assume beginWord and endWord are non-empty and are not the same. + * Created by gouthamvidyapradhan on 24/03/2017. Given two words (beginWord and endWord), and a + * dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, + * such that: + * + *

Only one letter can be changed at a time Each transformed word must exist in the word list. + * Note that beginWord is not a transformed word. For example, + * + *

Given: beginWord = "hit" endWord = "cog" wordList = ["hot","dot","dog","lot","log","cog"] + * Return [ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ] Note: Return an empty + * list if there is no such transformation sequence. All words have the same length. All words + * contain only lowercase alphabetic characters. You may assume no duplicates in the word list. You + * may assume beginWord and endWord are non-empty and are not the same. */ public class WordLadderII { - private static Queue queue = new ArrayDeque<>(); - private static Set dictionary = new HashSet<>(); - private static final String CONST = "abcdefghijklmnopqrstuvwxyz"; - private static Map> graph = new HashMap<>(); - private static Map minDistance = new HashMap<>(); - private static List> result = new ArrayList<>(); + private static Queue queue = new ArrayDeque<>(); + private static Set dictionary = new HashSet<>(); + private static final String CONST = "abcdefghijklmnopqrstuvwxyz"; + private static Map> graph = new HashMap<>(); + private static Map minDistance = new HashMap<>(); + private static List> result = new ArrayList<>(); + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + List dic = + Arrays.asList( + "kid", "tag", "pup", "ail", "tun", "woo", "erg", "luz", "brr", "gay", "sip", "kay", + "per", "val", "mes", "ohs", "now", "boa", "cet", "pal", "bar", "die", "war", "hay", + "eco", "pub", "lob", "rue", "fry", "lit", "rex", "jan", "cot", "bid", "ali", "pay", + "col", "gum", "ger", "row", "won", "dan", "rum", "fad", "tut", "sag", "yip", "sui", + "ark", "has", "zip", "fez", "own", "ump", "dis", "ads", "max", "jaw", "out", "btu", + "ana", "gap", "cry", "led", "abe", "box", "ore", "pig", "fie", "toy", "fat", "cal", + "lie", "noh", "sew", "ono", "tam", "flu", "mgm", "ply", "awe", "pry", "tit", "tie", + "yet", "too", "tax", "jim", "san", "pan", "map", "ski", "ova", "wed", "non", "wac", + "nut", "why", "bye", "lye", "oct", "old", "fin", "feb", "chi", "sap", "owl", "log", + "tod", "dot", "bow", "fob", "for", "joe", "ivy", "fan", "age", "fax", "hip", "jib", + "mel", "hus", "sob", "ifs", "tab", "ara", "dab", "jag", "jar", "arm", "lot", "tom", + "sax", "tex", "yum", "pei", "wen", "wry", "ire", "irk", "far", "mew", "wit", "doe", + "gas", "rte", "ian", "pot", "ask", "wag", "hag", "amy", "nag", "ron", "soy", "gin", + "don", "tug", "fay", "vic", "boo", "nam", "ave", "buy", "sop", "but", "orb", "fen", + "paw", "his", "sub", "bob", "yea", "oft", "inn", "rod", "yam", "pew", "web", "hod", + "hun", "gyp", "wei", "wis", "rob", "gad", "pie", "mon", "dog", "bib", "rub", "ere", + "dig", "era", "cat", "fox", "bee", "mod", "day", "apr", "vie", "nev", "jam", "pam", + "new", "aye", "ani", "and", "ibm", "yap", "can", "pyx", "tar", "kin", "fog", "hum", + "pip", "cup", "dye", "lyx", "jog", "nun", "par", "wan", "fey", "bus", "oak", "bad", + "ats", "set", "qom", "vat", "eat", "pus", "rev", "axe", "ion", "six", "ila", "lao", + "mom", "mas", "pro", "few", "opt", "poe", "art", "ash", "oar", "cap", "lop", "may", + "shy", "rid", "bat", "sum", "rim", "fee", "bmw", "sky", "maj", "hue", "thy", "ava", + "rap", "den", "fla", "auk", "cox", "ibo", "hey", "saw", "vim", "sec", "ltd", "you", + "its", "tat", "dew", "eva", "tog", "ram", "let", "see", "zit", "maw", "nix", "ate", + "gig", "rep", "owe", "ind", "hog", "eve", "sam", "zoo", "any", "dow", "cod", "bed", + "vet", "ham", "sis", "hex", "via", "fir", "nod", "mao", "aug", "mum", "hoe", "bah", + "hal", "keg", "hew", "zed", "tow", "gog", "ass", "dem", "who", "bet", "gos", "son", + "ear", "spy", "kit", "boy", "due", "sen", "oaf", "mix", "hep", "fur", "ada", "bin", + "nil", "mia", "ewe", "hit", "fix", "sad", "rib", "eye", "hop", "haw", "wax", "mid", + "tad", "ken", "wad", "rye", "pap", "bog", "gut", "ito", "woe", "our", "ado", "sin", + "mad", "ray", "hon", "roy", "dip", "hen", "iva", "lug", "asp", "hui", "yak", "bay", + "poi", "yep", "bun", "try", "lad", "elm", "nat", "wyo", "gym", "dug", "toe", "dee", + "wig", "sly", "rip", "geo", "cog", "pas", "zen", "odd", "nan", "lay", "pod", "fit", + "hem", "joy", "bum", "rio", "yon", "dec", "leg", "put", "sue", "dim", "pet", "yaw", + "nub", "bit", "bur", "sid", "sun", "oil", "red", "doc", "moe", "caw", "eel", "dix", + "cub", "end", "gem", "off", "yew", "hug", "pop", "tub", "sgt", "lid", "pun", "ton", + "sol", "din", "yup", "jab", "pea", "bug", "gag", "mil", "jig", "hub", "low", "did", + "tin", "get", "gte", "sox", "lei", "mig", "fig", "lon", "use", "ban", "flo", "nov", + "jut", "bag", "mir", "sty", "lap", "two", "ins", "con", "ant", "net", "tux", "ode", + "stu", "mug", "cad", "nap", "gun", "fop", "tot", "sow", "sal", "sic", "ted", "wot", + "del", "imp", "cob", "way", "ann", "tan", "mci", "job", "wet", "ism", "err", "him", + "all", "pad", "hah", "hie", "aim", "ike", "jed", "ego", "mac", "baa", "min", "com", + "ill", "was", "cab", "ago", "ina", "big", "ilk", "gal", "tap", "duh", "ola", "ran", + "lab", "top", "gob", "hot", "ora", "tia", "kip", "han", "met", "hut", "she", "sac", + "fed", "goo", "tee", "ell", "not", "act", "gil", "rut", "ala", "ape", "rig", "cid", + "god", "duo", "lin", "aid", "gel", "awl", "lag", "elf", "liz", "ref", "aha", "fib", + "oho", "tho", "her", "nor", "ace", "adz", "fun", "ned", "coo", "win", "tao", "coy", + "van", "man", "pit", "guy", "foe", "hid", "mai", "sup", "jay", "hob", "mow", "jot", + "are", "pol", "arc", "lax", "aft", "alb", "len", "air", "pug", "pox", "vow", "got", + "meg", "zoe", "amp", "ale", "bud", "gee", "pin", "dun", "pat", "ten", "mob"); + new WordLadderII().findLadders("cet", "ism", dic); + } - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - List dic = Arrays.asList("kid", "tag", "pup", "ail", "tun", "woo", "erg", "luz", "brr", "gay", "sip", "kay", "per", "val", "mes", "ohs", "now", "boa", "cet", "pal", "bar", "die", "war", "hay", "eco", "pub", "lob", "rue", "fry", "lit", "rex", "jan", "cot", "bid", "ali", "pay", "col", "gum", "ger", "row", "won", "dan", "rum", "fad", "tut", "sag", "yip", "sui", "ark", "has", "zip", "fez", "own", "ump", "dis", "ads", "max", "jaw", "out", "btu", "ana", "gap", "cry", "led", "abe", "box", "ore", "pig", "fie", "toy", "fat", "cal", "lie", "noh", "sew", "ono", "tam", "flu", "mgm", "ply", "awe", "pry", "tit", "tie", "yet", "too", "tax", "jim", "san", "pan", "map", "ski", "ova", "wed", "non", "wac", "nut", "why", "bye", "lye", "oct", "old", "fin", "feb", "chi", "sap", "owl", "log", "tod", "dot", "bow", "fob", "for", "joe", "ivy", "fan", "age", "fax", "hip", "jib", "mel", "hus", "sob", "ifs", "tab", "ara", "dab", "jag", "jar", "arm", "lot", "tom", "sax", "tex", "yum", "pei", "wen", "wry", "ire", "irk", "far", "mew", "wit", "doe", "gas", "rte", "ian", "pot", "ask", "wag", "hag", "amy", "nag", "ron", "soy", "gin", "don", "tug", "fay", "vic", "boo", "nam", "ave", "buy", "sop", "but", "orb", "fen", "paw", "his", "sub", "bob", "yea", "oft", "inn", "rod", "yam", "pew", "web", "hod", "hun", "gyp", "wei", "wis", "rob", "gad", "pie", "mon", "dog", "bib", "rub", "ere", "dig", "era", "cat", "fox", "bee", "mod", "day", "apr", "vie", "nev", "jam", "pam", "new", "aye", "ani", "and", "ibm", "yap", "can", "pyx", "tar", "kin", "fog", "hum", "pip", "cup", "dye", "lyx", "jog", "nun", "par", "wan", "fey", "bus", "oak", "bad", "ats", "set", "qom", "vat", "eat", "pus", "rev", "axe", "ion", "six", "ila", "lao", "mom", "mas", "pro", "few", "opt", "poe", "art", "ash", "oar", "cap", "lop", "may", "shy", "rid", "bat", "sum", "rim", "fee", "bmw", "sky", "maj", "hue", "thy", "ava", "rap", "den", "fla", "auk", "cox", "ibo", "hey", "saw", "vim", "sec", "ltd", "you", "its", "tat", "dew", "eva", "tog", "ram", "let", "see", "zit", "maw", "nix", "ate", "gig", "rep", "owe", "ind", "hog", "eve", "sam", "zoo", "any", "dow", "cod", "bed", "vet", "ham", "sis", "hex", "via", "fir", "nod", "mao", "aug", "mum", "hoe", "bah", "hal", "keg", "hew", "zed", "tow", "gog", "ass", "dem", "who", "bet", "gos", "son", "ear", "spy", "kit", "boy", "due", "sen", "oaf", "mix", "hep", "fur", "ada", "bin", "nil", "mia", "ewe", "hit", "fix", "sad", "rib", "eye", "hop", "haw", "wax", "mid", "tad", "ken", "wad", "rye", "pap", "bog", "gut", "ito", "woe", "our", "ado", "sin", "mad", "ray", "hon", "roy", "dip", "hen", "iva", "lug", "asp", "hui", "yak", "bay", "poi", "yep", "bun", "try", "lad", "elm", "nat", "wyo", "gym", "dug", "toe", "dee", "wig", "sly", "rip", "geo", "cog", "pas", "zen", "odd", "nan", "lay", "pod", "fit", "hem", "joy", "bum", "rio", "yon", "dec", "leg", "put", "sue", "dim", "pet", "yaw", "nub", "bit", "bur", "sid", "sun", "oil", "red", "doc", "moe", "caw", "eel", "dix", "cub", "end", "gem", "off", "yew", "hug", "pop", "tub", "sgt", "lid", "pun", "ton", "sol", "din", "yup", "jab", "pea", "bug", "gag", "mil", "jig", "hub", "low", "did", "tin", "get", "gte", "sox", "lei", "mig", "fig", "lon", "use", "ban", "flo", "nov", "jut", "bag", "mir", "sty", "lap", "two", "ins", "con", "ant", "net", "tux", "ode", "stu", "mug", "cad", "nap", "gun", "fop", "tot", "sow", "sal", "sic", "ted", "wot", "del", "imp", "cob", "way", "ann", "tan", "mci", "job", "wet", "ism", "err", "him", "all", "pad", "hah", "hie", "aim", "ike", "jed", "ego", "mac", "baa", "min", "com", "ill", "was", "cab", "ago", "ina", "big", "ilk", "gal", "tap", "duh", "ola", "ran", "lab", "top", "gob", "hot", "ora", "tia", "kip", "han", "met", "hut", "she", "sac", "fed", "goo", "tee", "ell", "not", "act", "gil", "rut", "ala", "ape", "rig", "cid", "god", "duo", "lin", "aid", "gel", "awl", "lag", "elf", "liz", "ref", "aha", "fib", "oho", "tho", "her", "nor", "ace", "adz", "fun", "ned", "coo", "win", "tao", "coy", "van", "man", "pit", "guy", "foe", "hid", "mai", "sup", "jay", "hob", "mow", "jot", "are", "pol", "arc", "lax", "aft", "alb", "len", "air", "pug", "pox", "vow", "got", "meg", "zoe", "amp", "ale", "bud", "gee", "pin", "dun", "pat", "ten", "mob"); - new WordLadderII().findLadders("cet", "ism", dic); - } - - public List> findLadders(String beginWord, String endWord, List wordList) { - dictionary.addAll(wordList); - bfs(beginWord, endWord, wordList); - List path = new ArrayList<>(); - path.add(beginWord); - dfs(beginWord, endWord, path); - System.out.println(result); - return result; - } + public List> findLadders(String beginWord, String endWord, List wordList) { + dictionary.addAll(wordList); + bfs(beginWord, endWord, wordList); + List path = new ArrayList<>(); + path.add(beginWord); + dfs(beginWord, endWord, path); + System.out.println(result); + return result; + } - /** - * Bfs - * - * @param beginWord begin word - * @param endWord end word - * @param wordList wordlist - */ - private void bfs(String beginWord, String endWord, List wordList) { - queue.offer(beginWord); - minDistance.put(beginWord, 0); - while (!queue.isEmpty()) { - String currWord = queue.poll(); - StringBuilder childSb = new StringBuilder(currWord); - for (int j = 0, ln = childSb.length(); j < ln; j++) { - for (int i = 0, l = CONST.length(); i < l; i++) { - char old = childSb.charAt(j); - childSb.replace(j, j + 1, String.valueOf(CONST.charAt(i))); - String child = childSb.toString(); - if (dictionary.contains(child)) { - if (minDistance.get(child) == null) { - minDistance.put(child, minDistance.get(currWord) + 1); - addChild(currWord, child); - if (!child.equals(endWord)) - queue.offer(child); - } else { - if (minDistance.get(child) == (minDistance.get(currWord) + 1)) - addChild(currWord, child); - } - } - childSb.replace(j, j + 1, String.valueOf(old)); - } + /** + * Bfs + * + * @param beginWord begin word + * @param endWord end word + * @param wordList wordlist + */ + private void bfs(String beginWord, String endWord, List wordList) { + queue.offer(beginWord); + minDistance.put(beginWord, 0); + while (!queue.isEmpty()) { + String currWord = queue.poll(); + StringBuilder childSb = new StringBuilder(currWord); + for (int j = 0, ln = childSb.length(); j < ln; j++) { + for (int i = 0, l = CONST.length(); i < l; i++) { + char old = childSb.charAt(j); + childSb.replace(j, j + 1, String.valueOf(CONST.charAt(i))); + String child = childSb.toString(); + if (dictionary.contains(child)) { + if (minDistance.get(child) == null) { + minDistance.put(child, minDistance.get(currWord) + 1); + addChild(currWord, child); + if (!child.equals(endWord)) queue.offer(child); + } else { + if (minDistance.get(child) == (minDistance.get(currWord) + 1)) + addChild(currWord, child); } + } + childSb.replace(j, j + 1, String.valueOf(old)); } + } } + } - /** - * Add child - * - * @param parent parent - * @param child child - */ - private void addChild(String parent, String child) { - Set children = graph.get(parent); - if (children == null) - children = new HashSet<>(); - children.add(child); - graph.put(parent, children); - } + /** + * Add child + * + * @param parent parent + * @param child child + */ + private void addChild(String parent, String child) { + Set children = graph.get(parent); + if (children == null) children = new HashSet<>(); + children.add(child); + graph.put(parent, children); + } - /** - * Dfs to build path - * - * @param currWord node - * @param endWord endword - * @param path path - */ - private void dfs(String currWord, String endWord, List path) { - if (currWord.equals(endWord)) { - result.add(new ArrayList<>(path)); - } else { - Set children = graph.get(currWord); - if (children != null) { - for (String c : children) { - path.add(c); - dfs(c, endWord, path); - path.remove(path.size() - 1); - } - } + /** + * Dfs to build path + * + * @param currWord node + * @param endWord endword + * @param path path + */ + private void dfs(String currWord, String endWord, List path) { + if (currWord.equals(endWord)) { + result.add(new ArrayList<>(path)); + } else { + Set children = graph.get(currWord); + if (children != null) { + for (String c : children) { + path.add(c); + dfs(c, endWord, path); + path.remove(path.size() - 1); } + } } + } } diff --git a/problems/src/depth_first_search/AccountsMerge.java b/problems/src/depth_first_search/AccountsMerge.java index 07bd27df..de15f02a 100644 --- a/problems/src/depth_first_search/AccountsMerge.java +++ b/problems/src/depth_first_search/AccountsMerge.java @@ -3,143 +3,141 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 27/12/2017. - * Given a list accounts, each element accounts[i] is a list of strings, where the first element accounts[i][0] is a - * name, and the rest of the elements are emails representing emails of the account. - - Now, we would like to merge these accounts. Two accounts definitely belong to the same person if there is some email - that is common to both accounts. Note that even if two accounts have the same name, they may belong to different - people as people could have the same name. A person can have any number of accounts initially, but all of their - accounts definitely have the same name. - - After merging the accounts, return the accounts in the following format: the first element of each account is the - name, and the rest of the elements are emails in sorted order. The accounts themselves can be returned in any order. - - Example 1: - Input: - accounts = [["John", "johnsmith@mail.com", "john00@mail.com"], ["John", "johnnybravo@mail.com"], ["John", - "johnsmith@mail.com", "john_newyork@mail.com"], ["Mary", "mary@mail.com"]] - Output: [["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'], ["John", "johnnybravo@mail - .com"], ["Mary", "mary@mail.com"]] - Explanation: - The first and third John's are the same person as they have the common email "johnsmith@mail.com". - The second John and Mary are different people as none of their email addresses are used by other accounts. - We could return these lists in any order, for example the answer [['Mary', 'mary@mail.com'], ['John', - 'johnnybravo@mail.com'], - ['John', 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com']] would still be accepted. - Note: - - The length of accounts will be in the range [1, 1000]. - The length of accounts[i] will be in the range [1, 10]. - The length of accounts[i][j] will be in the range [1, 30]. - - Solution: Consider each email_address as a vertex and link the emails of each account as bidirectional edges and - perform a dfs on connected components and return the email addresses of connected components. + * Created by gouthamvidyapradhan on 27/12/2017. Given a list accounts, each element accounts[i] is + * a list of strings, where the first element accounts[i][0] is a name, and the rest of the elements + * are emails representing emails of the account. + * + *

Now, we would like to merge these accounts. Two accounts definitely belong to the same person + * if there is some email that is common to both accounts. Note that even if two accounts have the + * same name, they may belong to different people as people could have the same name. A person can + * have any number of accounts initially, but all of their accounts definitely have the same name. + * + *

After merging the accounts, return the accounts in the following format: the first element of + * each account is the name, and the rest of the elements are emails in sorted order. The accounts + * themselves can be returned in any order. + * + *

Example 1: Input: accounts = [["John", "johnsmith@mail.com", "john00@mail.com"], ["John", + * "johnnybravo@mail.com"], ["John", "johnsmith@mail.com", "john_newyork@mail.com"], ["Mary", + * "mary@mail.com"]] Output: [["John", 'john00@mail.com', 'john_newyork@mail.com', + * 'johnsmith@mail.com'], ["John", "johnnybravo@mail .com"], ["Mary", "mary@mail.com"]] Explanation: + * The first and third John's are the same person as they have the common email + * "johnsmith@mail.com". The second John and Mary are different people as none of their email + * addresses are used by other accounts. We could return these lists in any order, for example the + * answer [['Mary', 'mary@mail.com'], ['John', 'johnnybravo@mail.com'], ['John', 'john00@mail.com', + * 'john_newyork@mail.com', 'johnsmith@mail.com']] would still be accepted. Note: + * + *

The length of accounts will be in the range [1, 1000]. The length of accounts[i] will be in + * the range [1, 10]. The length of accounts[i][j] will be in the range [1, 30]. + * + *

Solution: Consider each email_address as a vertex and link the emails of each account as + * bidirectional edges and perform a dfs on connected components and return the email addresses of + * connected components. */ public class AccountsMerge { - private class Account{ - String email, name; - Account(String email, String name){ - this.email = email; - this.name = name; - } - } - - private Map numMap; //for simplicity mapping each email to a unique integer - private Map emailMap; - private Map> graph; - private BitSet done; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - List account1 = new ArrayList<>(); - List> accounts = new ArrayList<>(); - account1.add("John"); - account1.add("johnsmith@mail.com"); - account1.add("john00@mail.com"); - accounts.add(account1); + private class Account { + String email, name; - List account2 = new ArrayList<>(); - account2.add("John"); - account2.add("johnnybravo@mail.com"); - accounts.add(account2); - - List account3 = new ArrayList<>(); - account3.add("John"); - account3.add("johnsmith@mail.com"); - account3.add("john_newyork@mail.com"); - accounts.add(account3); - - List account4 = new ArrayList<>(); - account4.add("Mary"); - account4.add("mary@mail.com"); - accounts.add(account4); - - List> result = new AccountsMerge().accountsMerge(accounts); - System.out.println(result); + Account(String email, String name) { + this.email = email; + this.name = name; } - - public List> accountsMerge(List> accounts) { - done = new BitSet(); - numMap = new HashMap<>(); - emailMap = new HashMap<>(); - graph = new HashMap<>(); - int index = -1; - for(List account : accounts){ - String name = account.get(0); - int prev = -1; - for(int i = 1, l = account.size(); i < l; i ++){ - String email = account.get(i); - int vertex; - if(!emailMap.containsKey(email)){ - vertex = ++index; - emailMap.put(email, vertex); - numMap.put(vertex, new Account(email, name)); - } else { - vertex = emailMap.get(email); - } - graph.putIfAbsent(vertex, new ArrayList<>()); - if(i != 1){ - //make bi-directional link - graph.get(prev).add(vertex); - graph.get(vertex).add(prev); - } - prev = vertex; - } + } + + private Map numMap; // for simplicity mapping each email to a unique integer + private Map emailMap; + private Map> graph; + private BitSet done; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + List account1 = new ArrayList<>(); + List> accounts = new ArrayList<>(); + account1.add("John"); + account1.add("johnsmith@mail.com"); + account1.add("john00@mail.com"); + accounts.add(account1); + + List account2 = new ArrayList<>(); + account2.add("John"); + account2.add("johnnybravo@mail.com"); + accounts.add(account2); + + List account3 = new ArrayList<>(); + account3.add("John"); + account3.add("johnsmith@mail.com"); + account3.add("john_newyork@mail.com"); + accounts.add(account3); + + List account4 = new ArrayList<>(); + account4.add("Mary"); + account4.add("mary@mail.com"); + accounts.add(account4); + + List> result = new AccountsMerge().accountsMerge(accounts); + System.out.println(result); + } + + public List> accountsMerge(List> accounts) { + done = new BitSet(); + numMap = new HashMap<>(); + emailMap = new HashMap<>(); + graph = new HashMap<>(); + int index = -1; + for (List account : accounts) { + String name = account.get(0); + int prev = -1; + for (int i = 1, l = account.size(); i < l; i++) { + String email = account.get(i); + int vertex; + if (!emailMap.containsKey(email)) { + vertex = ++index; + emailMap.put(email, vertex); + numMap.put(vertex, new Account(email, name)); + } else { + vertex = emailMap.get(email); } - List> result = new ArrayList<>(); - for(int i : graph.keySet()){ - if(!done.get(i)){ - List list = new ArrayList<>(); - List account = new ArrayList<>(); - dfs(i, list); - list.stream().forEach(x -> account.add(numMap.get(x).email)); - account.sort(String::compareTo); - - //Add account user name - Account acc = numMap.get(list.get(0)); - account.add(0, acc.name); - result.add(account); - } + graph.putIfAbsent(vertex, new ArrayList<>()); + if (i != 1) { + // make bi-directional link + graph.get(prev).add(vertex); + graph.get(vertex).add(prev); } - return result; + prev = vertex; + } } - - private void dfs(int i, List list){ - done.set(i); - list.add(i); - List children = graph.get(i); - if(children != null){ - for(int c : children){ - if(!done.get(c)){ - dfs(c, list); - } - } + List> result = new ArrayList<>(); + for (int i : graph.keySet()) { + if (!done.get(i)) { + List list = new ArrayList<>(); + List account = new ArrayList<>(); + dfs(i, list); + list.stream().forEach(x -> account.add(numMap.get(x).email)); + account.sort(String::compareTo); + + // Add account user name + Account acc = numMap.get(list.get(0)); + account.add(0, acc.name); + result.add(account); + } + } + return result; + } + + private void dfs(int i, List list) { + done.set(i); + list.add(i); + List children = graph.get(i); + if (children != null) { + for (int c : children) { + if (!done.get(c)) { + dfs(c, list); } + } } - + } } diff --git a/problems/src/depth_first_search/AlienDictionary.java b/problems/src/depth_first_search/AlienDictionary.java index 7e0cc387..f5dae3b9 100644 --- a/problems/src/depth_first_search/AlienDictionary.java +++ b/problems/src/depth_first_search/AlienDictionary.java @@ -3,143 +3,123 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 02/12/2017. - * There is a new alien language which uses the latin alphabet. However, the order among letters are unknown - * to you. You receive a list of non-empty words from the dictionary, where words are sorted lexicographically by the - * rules of this new language. Derive the order of letters in this language. - - Example 1: - Given the following words in dictionary, - - [ - "wrt", - "wrf", - "er", - "ett", - "rftt" - ] - The correct order is: "wertf". - - Example 2: - Given the following words in dictionary, - - [ - "z", - "x" - ] - The correct order is: "zx". - - Example 3: - Given the following words in dictionary, - - [ - "z", - "x", - "z" - ] - The order is invalid, so return "". - - Note: - You may assume all letters are in lowercase. - You may assume that if a is a prefix of b, then a must appear before b in the given dictionary. - If the order is invalid, return an empty string. - There may be multiple valid order of letters, return any one of them is fine. - - Solution: Build a graph with with character links and perform a topological sort. Topological sort can be - performed only on a DAG hence if there is a cycle immediately return empty string - + * Created by gouthamvidyapradhan on 02/12/2017. There is a new alien language which uses the latin + * alphabet. However, the order among letters are unknown to you. You receive a list of non-empty + * words from the dictionary, where words are sorted lexicographically by the rules of this new + * language. Derive the order of letters in this language. + * + *

Example 1: Given the following words in dictionary, + * + *

[ "wrt", "wrf", "er", "ett", "rftt" ] The correct order is: "wertf". + * + *

Example 2: Given the following words in dictionary, + * + *

[ "z", "x" ] The correct order is: "zx". + * + *

Example 3: Given the following words in dictionary, + * + *

[ "z", "x", "z" ] The order is invalid, so return "". + * + *

Note: You may assume all letters are in lowercase. You may assume that if a is a prefix of b, + * then a must appear before b in the given dictionary. If the order is invalid, return an empty + * string. There may be multiple valid order of letters, return any one of them is fine. + * + *

Solution: Build a graph with with character links and perform a topological sort. Topological + * sort can be performed only on a DAG hence if there is a cycle immediately return empty string */ public class AlienDictionary { - private Map> graph; - private Set done; - private Set visited; - private Stack toposort; - - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - String[] words = {"z", "x", "z"}; - System.out.println(new AlienDictionary().alienOrder(words)); + private Map> graph; + private Set done; + private Set visited; + private Stack toposort; + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + String[] words = {"z", "x", "z"}; + System.out.println(new AlienDictionary().alienOrder(words)); + } + + public String alienOrder(String[] words) { + graph = new HashMap<>(); + done = new HashSet<>(); + visited = new HashSet<>(); + toposort = new Stack<>(); + boolean[] A = new boolean[26]; + for (int i = 0; i < words.length - 1; i++) { + for (int j = 0, l = Math.min(words[i].length(), words[i + 1].length()); j < l; j++) { + if (words[i].charAt(j) != words[i + 1].charAt(j)) { + graph.putIfAbsent(words[i].charAt(j), new ArrayList<>()); + graph.get(words[i].charAt(j)).add(words[i + 1].charAt(j)); + break; + } + } } - public String alienOrder(String[] words) { - graph = new HashMap<>(); - done = new HashSet<>(); - visited = new HashSet<>(); - toposort = new Stack<>(); - boolean[] A = new boolean[26]; - for(int i = 0; i < words.length - 1; i ++){ - for(int j = 0, l = Math.min(words[i].length(), words[i + 1].length()); j < l; j++){ - if(words[i].charAt(j) != words[i + 1].charAt(j)){ - graph.putIfAbsent(words[i].charAt(j), new ArrayList<>()); - graph.get(words[i].charAt(j)).add(words[i + 1].charAt(j)); - break; - } - } - } + for (String w : words) { + for (int i = 0, l = w.length(); i < l; i++) { + A[w.charAt(i) - 'a'] = true; + } + } - for(String w : words){ - for(int i = 0, l = w.length(); i < l; i++){ - A[w.charAt(i) - 'a'] = true; - } - } + for (char c : graph.keySet()) { + if (!done.contains(c)) { + if (!dfs(c)) return ""; + } + } - for(char c : graph.keySet()){ - if(!done.contains(c)){ - if(!dfs(c)) return ""; - } - } + StringBuilder sb = new StringBuilder(); + while (!toposort.isEmpty()) { + sb.append(toposort.pop()); + } - StringBuilder sb = new StringBuilder(); - while(!toposort.isEmpty()){ - sb.append(toposort.pop()); + // Add remaining elements. This can come in any order. + String result = sb.toString(); + StringBuilder remaining = new StringBuilder(); + for (int i = 0; i < 26; i++) { + if (A[i]) { + char c = (char) (i + 'a'); + boolean found = false; + for (char r : result.toCharArray()) { + if (r == c) { + found = true; + break; + } } - - //Add remaining elements. This can come in any order. - String result = sb.toString(); - StringBuilder remaining = new StringBuilder(); - for(int i = 0; i < 26; i ++){ - if(A[i]){ - char c = (char)(i + 'a'); - boolean found = false; - for(char r : result.toCharArray()){ - if(r == c){ - found = true; - break; - } - } - if(!found){ - remaining.append(c); - } - } + if (!found) { + remaining.append(c); } - return result.concat(remaining.toString().trim()); + } } - - /** - * Dfs to toposort - * @param u - * @return - */ - private boolean dfs(char u){ - done.add(u); - visited.add(u); - List children = graph.get(u); - if(children != null){ - for(char c : children){ - if(visited.contains(c)) return false; //check cycle - if(!done.contains(c)){ - boolean status = dfs(c); - if(!status) return false; - } - } + return result.concat(remaining.toString().trim()); + } + + /** + * Dfs to toposort + * + * @param u + * @return + */ + private boolean dfs(char u) { + done.add(u); + visited.add(u); + List children = graph.get(u); + if (children != null) { + for (char c : children) { + if (visited.contains(c)) return false; // check cycle + if (!done.contains(c)) { + boolean status = dfs(c); + if (!status) return false; } - toposort.push(u); - visited.remove(u); - return true; + } } + toposort.push(u); + visited.remove(u); + return true; + } } diff --git a/problems/src/depth_first_search/AllPathsFromSourceToTarget.java b/problems/src/depth_first_search/AllPathsFromSourceToTarget.java index da0b0f46..fa03bba1 100644 --- a/problems/src/depth_first_search/AllPathsFromSourceToTarget.java +++ b/problems/src/depth_first_search/AllPathsFromSourceToTarget.java @@ -1,63 +1,57 @@ package depth_first_search; import java.util.*; + /** - * Created by gouthamvidyapradhan on 28/03/2019 - * 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. + * Created by gouthamvidyapradhan on 28/03/2019 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. + *

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. - * Note: + *

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. Note: * - * The number of nodes in the graph will be in the range [2, 15]. - * You can print different paths in any order, but you should keep the order of nodes inside one path. + *

The number of nodes in the graph will be in the range [2, 15]. You can print different paths + * in any order, but you should keep the order of nodes inside one path. * - * Solution: Do a dfs to reach every path. Since its a DAG there can be no cycles and safe to proceed without - * checking if the node has already been visited. Maintain a stack to keep track of the path and when a leaf node - * has been reached add the elements in the stack to the result array + *

Solution: Do a dfs to reach every path. Since its a DAG there can be no cycles and safe to + * proceed without checking if the node has already been visited. Maintain a stack to keep track of + * the path and when a leaf node has been reached add the elements in the stack to the result array */ public class AllPathsFromSourceToTarget { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int[][] graph = {{1, 2}, {3}, {3}, {}}; - System.out.println(new AllPathsFromSourceToTarget().allPathsSourceTarget(graph)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[][] graph = {{1, 2}, {3}, {3}, {}}; + System.out.println(new AllPathsFromSourceToTarget().allPathsSourceTarget(graph)); + } - public List> allPathsSourceTarget(int[][] graph) { - Set done = new HashSet<>(); - Stack stack = new Stack<>(); - List> result = new ArrayList<>(); - dfs(result, done, 0, stack, graph); - return result; - } + public List> allPathsSourceTarget(int[][] graph) { + Set done = new HashSet<>(); + Stack stack = new Stack<>(); + List> result = new ArrayList<>(); + dfs(result, done, 0, stack, graph); + return result; + } - private void dfs(List> result, Set done, int i, Stack stack, int[][] graph){ - done.add(i); - stack.push(i); - int[] children = graph[i]; - if(children.length == 0){ - List childList = new ArrayList<>(stack); - result.add(childList); - } else{ - for(int c : children){ - dfs(result, done, c, stack, graph); - } - } - stack.pop(); - done.remove(i); + private void dfs( + List> result, Set done, int i, Stack stack, int[][] graph) { + done.add(i); + stack.push(i); + int[] children = graph[i]; + if (children.length == 0) { + List childList = new ArrayList<>(stack); + result.add(childList); + } else { + for (int c : children) { + dfs(result, done, c, stack, graph); + } } + stack.pop(); + done.remove(i); + } } diff --git a/problems/src/depth_first_search/BricksFallingWhenHit.java b/problems/src/depth_first_search/BricksFallingWhenHit.java index e9e6c6f2..466bcc36 100644 --- a/problems/src/depth_first_search/BricksFallingWhenHit.java +++ b/problems/src/depth_first_search/BricksFallingWhenHit.java @@ -4,236 +4,223 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 01/07/2018. - * We have a grid of 1s and 0s; the 1s in a cell represent bricks. A brick will not drop if and only if it is - * directly connected to the top of the grid, or at least one of its (4-way) adjacent bricks will not drop. - - We will do some erasures sequentially. Each time we want to do the erasure at the location (i, j), the brick (if it - exists) on that location will disappear, and then some other bricks may drop because of that erasure. - - Return an array representing the number of bricks that will drop after each erasure in sequence. - - Example 1: - Input: - grid = [[1,0,0,0],[1,1,1,0]] - hits = [[1,0]] - Output: [2] - Explanation: - If we erase the brick at (1, 0), the brick at (1, 1) and (1, 2) will drop. So we should return 2. - Example 2: - Input: - grid = [[1,0,0,0],[1,1,0,0]] - hits = [[1,1],[1,0]] - Output: [0,0] - Explanation: - When we erase the brick at (1, 0), the brick at (1, 1) has already disappeared due to the last move. So each - erasure will cause no bricks dropping. Note that the erased brick (1, 0) will not be counted as a dropped brick. - - - Note: - - The number of rows and columns in the grid will be in the range [1, 200]. - The number of erasures will not exceed the area of the grid. - It is guaranteed that each erasure will be different from any other erasure, and located inside the grid. - An erasure may refer to a location with no brick - if it does, no bricks drop. - - Solution: O(R x C): Erase all the bricks in the grid and do a union of all the bricks using a union-find disjoint set. - (A modified union-find disjoint set is necessary to keep track of size of the connected component and to check - if its connected to roof or not) - Once you have the different connected components of the grid, solve the problem in the reverse order by - iterating the hits in the reverse order. First set 1 in the grid for each hits and count the connected bricks - in all four directions which are not linked to roof of the grid. - + * Created by gouthamvidyapradhan on 01/07/2018. We have a grid of 1s and 0s; the 1s in a cell + * represent bricks. A brick will not drop if and only if it is directly connected to the top of the + * grid, or at least one of its (4-way) adjacent bricks will not drop. + * + *

We will do some erasures sequentially. Each time we want to do the erasure at the location (i, + * j), the brick (if it exists) on that location will disappear, and then some other bricks may drop + * because of that erasure. + * + *

Return an array representing the number of bricks that will drop after each erasure in + * sequence. + * + *

Example 1: Input: grid = [[1,0,0,0],[1,1,1,0]] hits = [[1,0]] Output: [2] Explanation: If we + * erase the brick at (1, 0), the brick at (1, 1) and (1, 2) will drop. So we should return 2. + * Example 2: Input: grid = [[1,0,0,0],[1,1,0,0]] hits = [[1,1],[1,0]] Output: [0,0] Explanation: + * When we erase the brick at (1, 0), the brick at (1, 1) has already disappeared due to the last + * move. So each erasure will cause no bricks dropping. Note that the erased brick (1, 0) will not + * be counted as a dropped brick. + * + *

Note: + * + *

The number of rows and columns in the grid will be in the range [1, 200]. The number of + * erasures will not exceed the area of the grid. It is guaranteed that each erasure will be + * different from any other erasure, and located inside the grid. An erasure may refer to a location + * with no brick - if it does, no bricks drop. + * + *

Solution: O(R x C): Erase all the bricks in the grid and do a union of all the bricks using a + * union-find disjoint set. (A modified union-find disjoint set is necessary to keep track of size + * of the connected component and to check if its connected to roof or not) Once you have the + * different connected components of the grid, solve the problem in the reverse order by iterating + * the hits in the reverse order. First set 1 in the grid for each hits and count the connected + * bricks in all four directions which are not linked to roof of the grid. */ public class BricksFallingWhenHit { - private static final int[] R = {0, 0, 1, -1}; - private static final int[] C = {1, -1, 0, 0}; + private static final int[] R = {0, 0, 1, -1}; + private static final int[] C = {1, -1, 0, 0}; + + /** @author gouthamvidyapradhan Class to represent UnionFind Disjoint Set */ + private static class UnionFind { + private int[] p; + private int[] rank; + private boolean[] roof; + private int[] size; + + UnionFind(int s) { + this.p = new int[s]; + this.rank = new int[s]; + this.size = new int[s]; + this.roof = new boolean[s]; + init(); + } + /** Initialize with its same index as its parent */ + private void init() { + for (int i = 0; i < p.length; i++) { + p[i] = i; + size[i] = 1; + } + } + /** + * Find the representative vertex + * + * @param i + * @return + */ + private int findSet(int i) { + if (p[i] != i) { + p[i] = findSet(p[i]); + } + return p[i]; + } /** + * Set as roof * - * @author gouthamvidyapradhan - * Class to represent UnionFind Disjoint Set + * @param i + */ + public void setAsRoof(int i) { + roof[i] = true; + } + /** + * Perform union of two vertex * + * @param i + * @param j + * @return true if union is performed successfully, false otherwise */ - private static class UnionFind { - private int[] p; - private int[] rank; - private boolean[] roof; - private int[] size; - - UnionFind(int s){ - this.p = new int[s]; - this.rank = new int[s]; - this.size = new int[s]; - this.roof = new boolean[s]; - init(); - } - /** - * Initialize with its same index as its parent - */ - private void init() { - for(int i=0; i rank[y]){ - p[y] = p[x]; - roof[x] = (roof[x] || roof[y]); - size[x] = size[x] + size[y]; - } - else { - p[x] = p[y]; - roof[y] = (roof[x] || roof[y]); - size[y] = size[x] + size[y]; - if(rank[x] == rank[y]){ - rank[y]++; //increment the rank - } - } - return true; - } - return false; - } - - /** - * is attached to roof - * @param i - * @return - */ - public boolean isRoof(int i){ - return roof[findSet(i)]; - } - - /** - * is attached to roof - * @param i - * @return - */ - public int size(int i){ - return size[findSet(i)]; + public boolean union(int i, int j) { + int x = findSet(i); + int y = findSet(j); + if (x != y) { + if (rank[x] > rank[y]) { + p[y] = p[x]; + roof[x] = (roof[x] || roof[y]); + size[x] = size[x] + size[y]; + } else { + p[x] = p[y]; + roof[y] = (roof[x] || roof[y]); + size[y] = size[x] + size[y]; + if (rank[x] == rank[y]) { + rank[y]++; // increment the rank + } } + return true; + } + return false; } /** + * is attached to roof * - * @param args - * @throws Exception + * @param i + * @return */ - public static void main(String[] args) throws Exception{ - int[][] grid = {{1,1,1,1,1}, {0, 0, 1, 0, 1}, {1, 0, 1, 0, 1}, {1, 1, 1, 0, 1}}; - int[][] hits = {{1,2}, {2,2}, {2, 4}, {0, 4}, {0, 0}}; - int[] r = new BricksFallingWhenHit().hitBricks(grid, hits); - for(int i = 0; i < r.length; i ++){ - System.out.print(r[i] + " "); - } + public boolean isRoof(int i) { + return roof[findSet(i)]; } - public int[] hitBricks(int[][] grid, int[][] hits) { - int nR = grid.length; - int nC = grid[0].length; - UnionFind unionFind = new UnionFind((nR * nC) + 1); - for(int i = 0; i < nC; i ++){ - if(grid[0][i] == 1){ - unionFind.setAsRoof(i + 1); - } - } - for(int k = 0; k < hits.length; k++){ - int[] h = hits[k]; - if(grid[h[0]][h[1]] == 0){ - h[0] = -1; - h[1] = -1; - }else{ - grid[h[0]][h[1]] = 0; - } - } - boolean[][] done = new boolean[grid.length][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 && !done[i][j]){ - dfs(i, j, grid, done, unionFind); - } - } + /** + * is attached to roof + * + * @param i + * @return + */ + public int size(int i) { + return size[findSet(i)]; + } + } + + /** + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[][] grid = {{1, 1, 1, 1, 1}, {0, 0, 1, 0, 1}, {1, 0, 1, 0, 1}, {1, 1, 1, 0, 1}}; + int[][] hits = {{1, 2}, {2, 2}, {2, 4}, {0, 4}, {0, 0}}; + int[] r = new BricksFallingWhenHit().hitBricks(grid, hits); + for (int i = 0; i < r.length; i++) { + System.out.print(r[i] + " "); + } + } + + public int[] hitBricks(int[][] grid, int[][] hits) { + int nR = grid.length; + int nC = grid[0].length; + UnionFind unionFind = new UnionFind((nR * nC) + 1); + for (int i = 0; i < nC; i++) { + if (grid[0][i] == 1) { + unionFind.setAsRoof(i + 1); + } + } + for (int k = 0; k < hits.length; k++) { + int[] h = hits[k]; + if (grid[h[0]][h[1]] == 0) { + h[0] = -1; + h[1] = -1; + } else { + grid[h[0]][h[1]] = 0; + } + } + boolean[][] done = new boolean[grid.length][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 && !done[i][j]) { + dfs(i, j, grid, done, unionFind); } - int[] result = new int[hits.length]; - for(int i = hits.length - 1; i >= 0; i --){ - int[] h = hits[i]; - int r = h[0]; - int c = h[1]; - if(r == -1) continue; - grid[r][c] = 1; - int cell = (r * nC) + c + 1; - int sum = 0; - List notLinkedToRoof = new ArrayList<>(); - List linkedToRoof = new ArrayList<>(); - for(int k = 0; k < 4; k ++){ - int newR = r + R[k]; - int newC = c + C[k]; - if(newR >=0 && newR < nR && newC >= 0 && newC < nC && grid[newR][newC] == 1){ - int newCell = (newR * nC) + newC + 1; - if(unionFind.isRoof(newCell)){ - linkedToRoof.add(newCell); - } else{ - notLinkedToRoof.add(newCell); - } - } - } - for(int nr : notLinkedToRoof){ - unionFind.union(cell, nr); - } - if(!linkedToRoof.isEmpty() || unionFind.isRoof(cell)){ - sum += (unionFind.size(cell) - 1); - } - for(int rr : linkedToRoof){ - unionFind.union(cell, rr); - } - result[i] = sum; + } + } + int[] result = new int[hits.length]; + for (int i = hits.length - 1; i >= 0; i--) { + int[] h = hits[i]; + int r = h[0]; + int c = h[1]; + if (r == -1) continue; + grid[r][c] = 1; + int cell = (r * nC) + c + 1; + int sum = 0; + List notLinkedToRoof = new ArrayList<>(); + List linkedToRoof = new ArrayList<>(); + for (int k = 0; k < 4; k++) { + int newR = r + R[k]; + int newC = c + C[k]; + if (newR >= 0 && newR < nR && newC >= 0 && newC < nC && grid[newR][newC] == 1) { + int newCell = (newR * nC) + newC + 1; + if (unionFind.isRoof(newCell)) { + linkedToRoof.add(newCell); + } else { + notLinkedToRoof.add(newCell); + } } - return result; + } + for (int nr : notLinkedToRoof) { + unionFind.union(cell, nr); + } + if (!linkedToRoof.isEmpty() || unionFind.isRoof(cell)) { + sum += (unionFind.size(cell) - 1); + } + for (int rr : linkedToRoof) { + unionFind.union(cell, rr); + } + result[i] = sum; } - - private void dfs(int r, int c, int[][] grid, boolean[][] done, UnionFind unionFind){ - done[r][c] = true; - int cell = (r * grid[0].length) + c + 1; - for(int i = 0; i < 4; i ++){ - int newR = r + R[i]; - int newC = c + C[i]; - if(newR >= 0 && newR < grid.length && newC >= 0 && newC < grid[0].length){ - if(grid[newR][newC] == 1 && !done[newR][newC]){ - int newCell = (newR * grid[0].length) + newC + 1; - unionFind.union(cell, newCell); - dfs(newR, newC,grid, done, unionFind); - } - } + return result; + } + + private void dfs(int r, int c, int[][] grid, boolean[][] done, UnionFind unionFind) { + done[r][c] = true; + int cell = (r * grid[0].length) + c + 1; + for (int i = 0; i < 4; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 && newR < grid.length && newC >= 0 && newC < grid[0].length) { + if (grid[newR][newC] == 1 && !done[newR][newC]) { + int newCell = (newR * grid[0].length) + newC + 1; + unionFind.union(cell, newCell); + dfs(newR, newC, grid, done, unionFind); } + } } + } } diff --git a/problems/src/depth_first_search/CloneGraph.java b/problems/src/depth_first_search/CloneGraph.java index 9cdec1ab..42232959 100644 --- a/problems/src/depth_first_search/CloneGraph.java +++ b/problems/src/depth_first_search/CloneGraph.java @@ -6,85 +6,82 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 18/01/2018. - * Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. - - - OJ's undirected graph serialization: - Nodes are labeled uniquely. - - We use # as a separator for each node, and , as a separator for node label and each neighbor of the node. - As an example, consider the serialized graph {0,1,2#1,2#2,2}. - - The graph has a total of three nodes, and therefore contains three parts as separated by #. - - First node is labeled as 0. Connect node 0 to both nodes 1 and 2. - Second node is labeled as 1. Connect node 1 to node 2. - Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle. - Visually, the graph looks like the following: - - 1 - / \ - / \ - 0 --- 2 - / \ - \_/ - - Solution: O(V + E) maintain a hashmap of reference nodes and build the graph by dfs + * Created by gouthamvidyapradhan on 18/01/2018. Clone an undirected graph. Each node in the graph + * contains a label and a list of its neighbors. + * + *

OJ's undirected graph serialization: Nodes are labeled uniquely. + * + *

We use # as a separator for each node, and , as a separator for node label and each neighbor + * of the node. As an example, consider the serialized graph {0,1,2#1,2#2,2}. + * + *

The graph has a total of three nodes, and therefore contains three parts as separated by #. + * + *

First node is labeled as 0. Connect node 0 to both nodes 1 and 2. Second node is labeled as 1. + * Connect node 1 to node 2. Third node is labeled as 2. Connect node 2 to node 2 (itself), thus + * forming a self-cycle. Visually, the graph looks like the following: + * + *

1 / \ / \ 0 --- 2 / \ \_/ + * + *

Solution: O(V + E) maintain a hashmap of reference nodes and build the graph by dfs */ public class CloneGraph { - static class UndirectedGraphNode { - int label; - List neighbors; - UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<>(); } + static class UndirectedGraphNode { + int label; + List neighbors; + + UndirectedGraphNode(int x) { + label = x; + neighbors = new ArrayList<>(); } + } - private Map map; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - UndirectedGraphNode node = new UndirectedGraphNode(0); - UndirectedGraphNode node1 = new UndirectedGraphNode(1); - UndirectedGraphNode node2 = new UndirectedGraphNode(2); - node.neighbors.add(node1); - node.neighbors.add(node2); + private Map map; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + UndirectedGraphNode node = new UndirectedGraphNode(0); + UndirectedGraphNode node1 = new UndirectedGraphNode(1); + UndirectedGraphNode node2 = new UndirectedGraphNode(2); + node.neighbors.add(node1); + node.neighbors.add(node2); - node1.neighbors.add(node); - node1.neighbors.add(node2); + node1.neighbors.add(node); + node1.neighbors.add(node2); - node2.neighbors.add(node); - node2.neighbors.add(node1); - node2.neighbors.add(node2); - UndirectedGraphNode result = new CloneGraph().cloneGraph(node); - //print result - } + node2.neighbors.add(node); + node2.neighbors.add(node1); + node2.neighbors.add(node2); + UndirectedGraphNode result = new CloneGraph().cloneGraph(node); + // print result + } - public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { - if(node == null) return null; - map = new HashMap<>(); - UndirectedGraphNode clone = new UndirectedGraphNode(node.label); - dfs(node, clone); - return clone; - } + public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { + if (node == null) return null; + map = new HashMap<>(); + UndirectedGraphNode clone = new UndirectedGraphNode(node.label); + dfs(node, clone); + return clone; + } - private void dfs(UndirectedGraphNode original, UndirectedGraphNode clone){ - map.put(clone.label, clone); - List oChildren = original.neighbors; //original child nodes - List cChildren = clone.neighbors; //clone child nodes - for(UndirectedGraphNode oChild : oChildren){ - if(map.containsKey(oChild.label)){ - //already visited node - cChildren.add(map.get(oChild.label)); - } else{ - //a new node - UndirectedGraphNode newChildClone = new UndirectedGraphNode(oChild.label); - cChildren.add(newChildClone); - dfs(oChild, newChildClone); - } - } + private void dfs(UndirectedGraphNode original, UndirectedGraphNode clone) { + map.put(clone.label, clone); + List oChildren = original.neighbors; // original child nodes + List cChildren = clone.neighbors; // clone child nodes + for (UndirectedGraphNode oChild : oChildren) { + if (map.containsKey(oChild.label)) { + // already visited node + cChildren.add(map.get(oChild.label)); + } else { + // a new node + UndirectedGraphNode newChildClone = new UndirectedGraphNode(oChild.label); + cChildren.add(newChildClone); + dfs(oChild, newChildClone); + } } + } } diff --git a/problems/src/depth_first_search/CourseSchedule.java b/problems/src/depth_first_search/CourseSchedule.java index b7465228..1e96e567 100644 --- a/problems/src/depth_first_search/CourseSchedule.java +++ b/problems/src/depth_first_search/CourseSchedule.java @@ -3,90 +3,87 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 22/06/2017. - * There are a total of n courses you have to take, labeled from 0 to n - 1. - *

- * Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] - *

- * Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses? - *

- * For example: - *

- * 2, [[1,0]] - * There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible. - *

- * 2, [[1,0],[0,1]] - * 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. - *

- * Note: - * The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented. - * You may assume that there are no duplicate edges in the input prerequisites. - *

- * Solution: - * 1. Topologically sort the vertices. - * 2. Pick each sorted vertex and mark each of its neighbours as visited, - * if you encounter a vertex which is already visited then return false otherwise return true + * Created by gouthamvidyapradhan on 22/06/2017. There are a total of n courses you have to take, + * labeled from 0 to n - 1. + * + *

Some courses may have prerequisites, for example to take course 0 you have to first take + * course 1, which is expressed as a pair: [0,1] + * + *

Given the total number of courses and a list of prerequisite pairs, is it possible for you to + * finish all courses? + * + *

For example: + * + *

2, [[1,0]] There are a total of 2 courses to take. To take course 1 you should have finished + * course 0. So it is possible. + * + *

2, [[1,0],[0,1]] 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. + * + *

Note: The input prerequisites is a graph represented by a list of edges, not adjacency + * matrices. Read more about how a graph is represented. You may assume that there are no duplicate + * edges in the input prerequisites. + * + *

Solution: 1. Topologically sort the vertices. 2. Pick each sorted vertex and mark each of its + * neighbours as visited, if you encounter a vertex which is already visited then return false + * otherwise return true */ public class CourseSchedule { - private Map> graph; - private BitSet visited; - private Queue toposorted; + private Map> graph; + private BitSet visited; + private Queue toposorted; - public static void main(String[] args) throws Exception { - int[][] pre = {{1, 0}}; - System.out.println(new CourseSchedule().canFinish(2, pre)); - } + public static void main(String[] args) throws Exception { + int[][] pre = {{1, 0}}; + System.out.println(new CourseSchedule().canFinish(2, pre)); + } - public boolean canFinish(int numCourses, int[][] prerequisites) { - graph = new HashMap<>(); - visited = new BitSet(); - toposorted = new ArrayDeque<>(); - //build graph - for (int[] children : prerequisites) { - graph.putIfAbsent(children[0], new ArrayList<>()); - graph.get(children[0]).add(children[1]); - } - graph.keySet().stream().filter(v -> !visited.get(v)).forEach(this::dfs); + public boolean canFinish(int numCourses, int[][] prerequisites) { + graph = new HashMap<>(); + visited = new BitSet(); + toposorted = new ArrayDeque<>(); + // build graph + for (int[] children : prerequisites) { + graph.putIfAbsent(children[0], new ArrayList<>()); + graph.get(children[0]).add(children[1]); + } + graph.keySet().stream().filter(v -> !visited.get(v)).forEach(this::dfs); - visited.clear(); + visited.clear(); - while (!toposorted.isEmpty()) { - int v = toposorted.poll(); - if (visited.get(v)) - return false; - relax(v); - } - return true; + while (!toposorted.isEmpty()) { + int v = toposorted.poll(); + if (visited.get(v)) return false; + relax(v); } + return true; + } - /** - * Mark a vetex and its connected vertices as visited. - * - * @param v vertex - */ - private void relax(int v) { - visited.set(v); - List children = graph.get(v); - if (children != null) { - for (int c : children) - visited.set(c); - } + /** + * Mark a vetex and its connected vertices as visited. + * + * @param v vertex + */ + private void relax(int v) { + visited.set(v); + List children = graph.get(v); + if (children != null) { + for (int c : children) visited.set(c); } + } - /** - * Toposort - * - * @param v vertex - */ - private void dfs(int v) { - visited.set(v); - List children = graph.get(v); - if (children != null) { - for (int c : children) - if (!visited.get(c)) - dfs(c); - } - toposorted.offer(v); + /** + * Toposort + * + * @param v vertex + */ + private void dfs(int v) { + visited.set(v); + List children = graph.get(v); + if (children != null) { + for (int c : children) if (!visited.get(c)) dfs(c); } - + toposorted.offer(v); + } } diff --git a/problems/src/depth_first_search/CourseScheduleII.java b/problems/src/depth_first_search/CourseScheduleII.java index 987e4f36..77b12023 100644 --- a/problems/src/depth_first_search/CourseScheduleII.java +++ b/problems/src/depth_first_search/CourseScheduleII.java @@ -3,100 +3,97 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 23/06/2017. - * There are a total of n courses you have to take, labeled from 0 to n - 1. - *

- * Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] - *

- * Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses. - *

- * There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array. - *

- * For example: - *

- * 2, [[1,0]] - * There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is [0,1] - *

- * 4, [[1,0],[2,0],[3,1],[3,2]] - * There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. Another correct ordering is[0,2,1,3]. - *

- * Note: - * The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented. - * You may assume that there are no duplicate edges in the input prerequisites. + * Created by gouthamvidyapradhan on 23/06/2017. There are a total of n courses you have to take, + * labeled from 0 to n - 1. + * + *

Some courses may have prerequisites, for example to take course 0 you have to first take + * course 1, which is expressed as a pair: [0,1] + * + *

Given the total number of courses and a list of prerequisite pairs, return the ordering of + * courses you should take to finish all courses. + * + *

There may be multiple correct orders, you just need to return one of them. If it is impossible + * to finish all courses, return an empty array. + * + *

For example: + * + *

2, [[1,0]] There are a total of 2 courses to take. To take course 1 you should have finished + * course 0. So the correct course order is [0,1] + * + *

4, [[1,0],[2,0],[3,1],[3,2]] There are a total of 4 courses to take. To take course 3 you + * should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you + * finished course 0. So one correct course order is [0,1,2,3]. Another correct ordering + * is[0,2,1,3]. + * + *

Note: The input prerequisites is a graph represented by a list of edges, not adjacency + * matrices. Read more about how a graph is represented. You may assume that there are no duplicate + * edges in the input prerequisites. */ public class CourseScheduleII { - private Map> graph; - private BitSet visited; - private Queue toposorted; + private Map> graph; + private BitSet visited; + private Queue toposorted; - public static void main(String[] args) throws Exception { - int[][] pre = {{1, 0}}; - int[] result = new CourseScheduleII().findOrder(2, pre); - for (int i : result) - System.out.print(i + " "); - System.out.println(); - } + public static void main(String[] args) throws Exception { + int[][] pre = {{1, 0}}; + int[] result = new CourseScheduleII().findOrder(2, pre); + for (int i : result) System.out.print(i + " "); + System.out.println(); + } - public int[] findOrder(int numCourses, int[][] prerequisites) { - int j = 0; - int[] courses = new int[numCourses]; - int[] result = new int[numCourses]; - for (int i = 0; i < numCourses; i++) - courses[i] = j++; - graph = new HashMap<>(); - visited = new BitSet(); - toposorted = new ArrayDeque<>(); - //build graph - for (int[] children : prerequisites) { - graph.putIfAbsent(children[0], new ArrayList<>()); - graph.get(children[0]).add(children[1]); - } - graph.keySet().stream().filter(v -> !visited.get(v)).forEach(this::dfs); + public int[] findOrder(int numCourses, int[][] prerequisites) { + int j = 0; + int[] courses = new int[numCourses]; + int[] result = new int[numCourses]; + for (int i = 0; i < numCourses; i++) courses[i] = j++; + graph = new HashMap<>(); + visited = new BitSet(); + toposorted = new ArrayDeque<>(); + // build graph + for (int[] children : prerequisites) { + graph.putIfAbsent(children[0], new ArrayList<>()); + graph.get(children[0]).add(children[1]); + } + graph.keySet().stream().filter(v -> !visited.get(v)).forEach(this::dfs); - visited.clear(); - int i = 0; - while (!toposorted.isEmpty()) { - int v = toposorted.poll(); - if (visited.get(v)) - return new int[0]; - relax(v); - result[i++] = v; - courses[v] = -1; - } - //add the remaining courses - for (int c : courses) - if (c != -1) - result[i++] = c; - return result; + visited.clear(); + int i = 0; + while (!toposorted.isEmpty()) { + int v = toposorted.poll(); + if (visited.get(v)) return new int[0]; + relax(v); + result[i++] = v; + courses[v] = -1; } + // add the remaining courses + for (int c : courses) if (c != -1) result[i++] = c; + return result; + } - /** - * Mark a vetex and its connected vertices as visited. - * - * @param v vertex - */ - private void relax(int v) { - visited.set(v); - List children = graph.get(v); - if (children != null) { - for (int c : children) - visited.set(c); - } + /** + * Mark a vetex and its connected vertices as visited. + * + * @param v vertex + */ + private void relax(int v) { + visited.set(v); + List children = graph.get(v); + if (children != null) { + for (int c : children) visited.set(c); } + } - /** - * Toposort - * - * @param v vertex - */ - private void dfs(int v) { - visited.set(v); - List children = graph.get(v); - if (children != null) { - for (int c : children) - if (!visited.get(c)) - dfs(c); - } - toposorted.offer(v); + /** + * Toposort + * + * @param v vertex + */ + private void dfs(int v) { + visited.set(v); + List children = graph.get(v); + if (children != null) { + for (int c : children) if (!visited.get(c)) dfs(c); } + toposorted.offer(v); + } } diff --git a/problems/src/depth_first_search/CrackingTheSafe.java b/problems/src/depth_first_search/CrackingTheSafe.java index b8361738..ffa5f443 100644 --- a/problems/src/depth_first_search/CrackingTheSafe.java +++ b/problems/src/depth_first_search/CrackingTheSafe.java @@ -4,96 +4,92 @@ import java.util.Set; /** - * Created by gouthamvidyapradhan on 09/03/2019 - * There is a box protected by a password. The password is n digits, where each letter can be one of the first k - * digits 0, 1, ..., k-1. + * Created by gouthamvidyapradhan on 09/03/2019 There is a box protected by a password. The password + * is n digits, where each letter can be one of the first k digits 0, 1, ..., k-1. * - * You can keep inputting the password, the password will automatically be matched against the last n digits entered. + *

You can keep inputting the password, the password will automatically be matched against the + * last n digits entered. * - * For example, assuming the password is "345", I can open it when I type "012345", but I enter a total of 6 digits. + *

For example, assuming the password is "345", I can open it when I type "012345", but I enter a + * total of 6 digits. * - * Please return any string of minimum length that is guaranteed to open the box after the entire string is inputted. + *

Please return any string of minimum length that is guaranteed to open the box after the entire + * string is inputted. * - * Example 1: - * Input: n = 1, k = 2 - * Output: "01" - * Note: "10" will be accepted too. - * Example 2: - * Input: n = 2, k = 2 - * Output: "00110" - * Note: "01100", "10011", "11001" will be accepted too. - * Note: - * n will be in the range [1, 4]. - * k will be in the range [1, 10]. - * k^n will be at most 4096. + *

Example 1: Input: n = 1, k = 2 Output: "01" Note: "10" will be accepted too. Example 2: Input: + * n = 2, k = 2 Output: "00110" Note: "01100", "10011", "11001" will be accepted too. Note: n will + * be in the range [1, 4]. k will be in the range [1, 10]. k^n will be at most 4096. * - * Solution O(n x k ^ n) Do a dfs and explore every possible states which form a n digit number with-in the given - * range k. Maintain a 'result' string and keep appending the new digit in every state, if the total number of states - * visited reaches k ^ n then, the result string will be the answer. + *

Solution O(n x k ^ n) Do a dfs and explore every possible states which form a n digit number + * with-in the given range k. Maintain a 'result' string and keep appending the new digit in every + * state, if the total number of states visited reaches k ^ n then, the result string will be the + * answer. */ public class CrackingTheSafe { - /** - * Main method - * - * @param args - */ - public static void main(String[] args) { - System.out.println(new CrackingTheSafe().crackSafe(4, 5)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + System.out.println(new CrackingTheSafe().crackSafe(4, 5)); + } - public String crackSafe(int n, int k) { - int states = getStates(n, k); - int[] N = new int[k]; - for (int i = 0; i < k; i++) { - N[i] = i; - } - return generate(N, n, 0, 0, "", k, states); + public String crackSafe(int n, int k) { + int states = getStates(n, k); + int[] N = new int[k]; + for (int i = 0; i < k; i++) { + N[i] = i; } + return generate(N, n, 0, 0, "", k, states); + } - private int getStates(int n, int k) { - if (n == 0) return 1; - if (n == 1) return k; - int result = 1; - for (int i = 0; i < n; i++) { - result *= k; - } - return result; + private int getStates(int n, int k) { + if (n == 0) return 1; + if (n == 1) return k; + int result = 1; + for (int i = 0; i < n; i++) { + result *= k; } + return result; + } - private String generate(int[] N, int n, int i, int count, String num, int k, int states) { - if (count == n) { - return dfs(num, new StringBuilder(num), new HashSet<>(), k, states, 1); - } else { - for (int j = i; j < N.length; j++) { - String result = generate(N, n, j, count + 1, num + String.valueOf(N[j]), k, states); - if (!result.isEmpty()) { - return result; - } - } + private String generate(int[] N, int n, int i, int count, String num, int k, int states) { + if (count == n) { + return dfs(num, new StringBuilder(num), new HashSet<>(), k, states, 1); + } else { + for (int j = i; j < N.length; j++) { + String result = generate(N, n, j, count + 1, num + String.valueOf(N[j]), k, states); + if (!result.isEmpty()) { + return result; } - return ""; + } } + return ""; + } - private String dfs(String num, StringBuilder result, Set done, int k, int states, int count) { - done.add(num); - if (states == count) { - return result.toString(); - } else { - for (int i = 0; i < k; i++) { - String newNum = (num + String.valueOf(i)); - String newState = newNum.substring(1); - if (!done.contains(newState)) { - String retValue = dfs(newState, result.append(String.valueOf(i)), done, k, states, count + 1); - if (!retValue.isEmpty()) { - return retValue; - } else { - result.deleteCharAt(result.length() - 1); - } - } - } + private String dfs( + String num, StringBuilder result, Set done, int k, int states, int count) { + done.add(num); + if (states == count) { + return result.toString(); + } else { + for (int i = 0; i < k; i++) { + String newNum = (num + String.valueOf(i)); + String newState = newNum.substring(1); + if (!done.contains(newState)) { + String retValue = + dfs(newState, result.append(String.valueOf(i)), done, k, states, count + 1); + if (!retValue.isEmpty()) { + return retValue; + } else { + result.deleteCharAt(result.length() - 1); + } } - done.remove(num); - return ""; + } } + done.remove(num); + return ""; + } } diff --git a/problems/src/depth_first_search/GraphValidTree.java b/problems/src/depth_first_search/GraphValidTree.java index 2562319b..43543bc3 100644 --- a/problems/src/depth_first_search/GraphValidTree.java +++ b/problems/src/depth_first_search/GraphValidTree.java @@ -5,79 +5,78 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 11/12/2017. - * Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a - * function to check whether these edges make up a valid tree. - - For example: - - Given n = 5 and edges = [[0, 1], [0, 2], [0, 3], [1, 4]], return true. - - Given n = 5 and edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]], return false. - - Note: you can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the - same as [1, 0] and thus will not appear together in edges. - - Solution O(E + V). A graph is a tree if there are no cycles and number of connected components is 1. + * Created by gouthamvidyapradhan on 11/12/2017. Given n nodes labeled from 0 to n - 1 and a list of + * undirected edges (each edge is a pair of nodes), write a function to check whether these edges + * make up a valid tree. + * + *

For example: + * + *

Given n = 5 and edges = [[0, 1], [0, 2], [0, 3], [1, 4]], return true. + * + *

Given n = 5 and edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]], return false. + * + *

Note: you can assume that no duplicate edges will appear in edges. Since all edges are + * undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges. + * + *

Solution O(E + V). A graph is a tree if there are no cycles and number of connected components + * is 1. */ public class GraphValidTree { - private List[] graph; - private BitSet done; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[][] graph = {{1, 0}}; - System.out.println(new GraphValidTree().validTree(2, graph)); - } - + private List[] graph; + private BitSet done; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[][] graph = {{1, 0}}; + System.out.println(new GraphValidTree().validTree(2, graph)); + } - public boolean validTree(int n, int[][] edges) { - graph = new List[n]; - done = new BitSet(); - for(int i = 0; i < n; i ++){ - graph[i] = new ArrayList<>(); - } - for(int i = 0; i < edges.length; i ++){ - int u = edges[i][0]; - int v = edges[i][1]; - graph[u].add(v); - graph[v].add(u); - } + public boolean validTree(int n, int[][] edges) { + graph = new List[n]; + done = new BitSet(); + for (int i = 0; i < n; i++) { + graph[i] = new ArrayList<>(); + } + for (int i = 0; i < edges.length; i++) { + int u = edges[i][0]; + int v = edges[i][1]; + graph[u].add(v); + graph[v].add(u); + } - int count = 0; - for(int i = 0; i < n; i++){ - if(!done.get(i)){ - if(!dfs(graph, 0, -1)){ - return false; - } - count ++; //count number of connected components - } + int count = 0; + for (int i = 0; i < n; i++) { + if (!done.get(i)) { + if (!dfs(graph, 0, -1)) { + return false; } - return count <= 1; + count++; // count number of connected components + } } + return count <= 1; + } - private boolean dfs(List[] graph, int u, int p){ - done.set(u); - List children = graph[u]; - if(children != null){ - for(int c : children){ - if(p != c){ //should not be equal to parent - if(!done.get(c)){ - if(!dfs(graph, c, u)){ - return false; - } - } else{ - return false; - } - } + private boolean dfs(List[] graph, int u, int p) { + done.set(u); + List children = graph[u]; + if (children != null) { + for (int c : children) { + if (p != c) { // should not be equal to parent + if (!done.get(c)) { + if (!dfs(graph, c, u)) { + return false; } + } else { + return false; + } } - return true; + } } - - + return true; + } } diff --git a/problems/src/depth_first_search/IslandPerimeter.java b/problems/src/depth_first_search/IslandPerimeter.java index 82fd5723..0cc67fa1 100644 --- a/problems/src/depth_first_search/IslandPerimeter.java +++ b/problems/src/depth_first_search/IslandPerimeter.java @@ -1,73 +1,68 @@ package depth_first_search; /** - * Created by gouthamvidyapradhan on 16/02/2018. - * You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. - * Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, - * and there is exactly one island (i.e., one or more connected land cells). The island doesn't have "lakes" (water - * inside that isn't connected to the water around the island). One cell is a square with side length 1. The grid is - * rectangular, width and height don't exceed 100. Determine the perimeter of the island. - - Example: - - [[0,1,0,0], - [1,1,1,0], - [0,1,0,0], - [1,1,0,0]] - - Answer: 16 - Explanation: The perimeter is the 16 yellow stripes in the image below: - - Solution: Perform a dfs and count + 1 if any adjacent cell is a 0 or border + * Created by gouthamvidyapradhan on 16/02/2018. You are given a map in form of a two-dimensional + * integer grid where 1 represents land and 0 represents water. Grid cells are connected + * horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there + * is exactly one island (i.e., one or more connected land cells). The island doesn't have "lakes" + * (water inside that isn't connected to the water around the island). One cell is a square with + * side length 1. The grid is rectangular, width and height don't exceed 100. Determine the + * perimeter of the island. + * + *

Example: + * + *

[[0,1,0,0], [1,1,1,0], [0,1,0,0], [1,1,0,0]] + * + *

Answer: 16 Explanation: The perimeter is the 16 yellow stripes in the image below: + * + *

Solution: Perform a dfs and count + 1 if any adjacent cell is a 0 or border */ - public class IslandPerimeter { - int[] R = {1, -1, 0, 0}; - int[] C = {0, 0, 1, -1}; - boolean[][] done; - int perimeter; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[][] grid = {{0,1,0,0}, {1,1,1,0}, {0,1,0,0}, {1,1,0,0}}; - System.out.println(new IslandPerimeter().islandPerimeter(grid)); - } + int[] R = {1, -1, 0, 0}; + int[] C = {0, 0, 1, -1}; + boolean[][] done; + int perimeter; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[][] grid = {{0, 1, 0, 0}, {1, 1, 1, 0}, {0, 1, 0, 0}, {1, 1, 0, 0}}; + System.out.println(new IslandPerimeter().islandPerimeter(grid)); + } - public int islandPerimeter(int[][] grid) { - done = new boolean[grid.length][grid[0].length]; - perimeter = 0; - for(int i = 0; i < grid.length; i ++){ - for(int j = 0; j < grid[0].length; j ++){ - if(grid[i][j] == 1 && !done[i][j]){ - dfs(i, j, grid); - break; - } - } + public int islandPerimeter(int[][] grid) { + done = new boolean[grid.length][grid[0].length]; + perimeter = 0; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 1 && !done[i][j]) { + dfs(i, j, grid); + break; } - - return perimeter; + } } - private void dfs(int r, int c, int[][] grid){ - done[r][c] = true; - for(int i = 0; i < 4; i ++){ - int newR = r + R[i]; - int newC = c + C[i]; - if(newR < 0 || newC < 0 || newR >= grid.length || newC >= grid[0].length){ - perimeter++; - } - else if(grid[newR][newC] == 0) { - perimeter++; - } else{ - if(!done[newR][newC]){ - dfs(newR, newC, grid); - } - } + return perimeter; + } + + private void dfs(int r, int c, int[][] grid) { + done[r][c] = true; + for (int i = 0; i < 4; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR < 0 || newC < 0 || newR >= grid.length || newC >= grid[0].length) { + perimeter++; + } else if (grid[newR][newC] == 0) { + perimeter++; + } else { + if (!done[newR][newC]) { + dfs(newR, newC, grid); } + } } - + } } diff --git a/problems/src/depth_first_search/LongestConsecutiveSequence.java b/problems/src/depth_first_search/LongestConsecutiveSequence.java index af0665b8..1d4cd980 100644 --- a/problems/src/depth_first_search/LongestConsecutiveSequence.java +++ b/problems/src/depth_first_search/LongestConsecutiveSequence.java @@ -3,72 +3,71 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 15/12/2017. - * Given an unsorted array of integers, find the length of the longest consecutive elements sequence. - - For example, - Given [100, 4, 200, 1, 3, 2], - The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4. - - Your algorithm should run in O(n) complexity. - - Solution: O(n) time and space complexity - Build a graph linking each number which is greater or lesser by one. - Perform a dfs to count the depth of a graph. - - Dfs using recursion fails due to StackOverFlowError(due to deep recursion) hence used a iterative approach with a - stack + * Created by gouthamvidyapradhan on 15/12/2017. Given an unsorted array of integers, find the + * length of the longest consecutive elements sequence. + * + *

For example, Given [100, 4, 200, 1, 3, 2], The longest consecutive elements sequence is [1, 2, + * 3, 4]. Return its length: 4. + * + *

Your algorithm should run in O(n) complexity. + * + *

Solution: O(n) time and space complexity - Build a graph linking each number which is greater + * or lesser by one. Perform a dfs to count the depth of a graph. + * + *

Dfs using recursion fails due to StackOverFlowError(due to deep recursion) hence used a + * iterative approach with a stack */ public class LongestConsecutiveSequence { - private Map> graph; - private Set done; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] nums = {-1, 0, -3, -2, 1, 2, 3, 4, 5, 4}; - System.out.println(new LongestConsecutiveSequence().longestConsecutive(nums)); - } + private Map> graph; + private Set done; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] nums = {-1, 0, -3, -2, 1, 2, 3, 4, 5, 4}; + System.out.println(new LongestConsecutiveSequence().longestConsecutive(nums)); + } - public int longestConsecutive(int[] nums) { - done = new HashSet<>(); - graph = new HashMap<>(); - for (int u : nums) { - graph.putIfAbsent(u, new HashSet<>()); - if (graph.keySet().contains(u - 1)) { - graph.get(u - 1).add(u); - graph.get(u).add(u - 1); - } - if (graph.keySet().contains(u + 1)) { - graph.get(u + 1).add(u); - graph.get(u).add(u + 1); - } - } - int max = 0; - for(int i : graph.keySet()){ - if(!done.contains(i)){ - Stack stack = new Stack<>(); - stack.add(i); - max = Math.max(max, dfs(0, stack)); - } - } - return max; + public int longestConsecutive(int[] nums) { + done = new HashSet<>(); + graph = new HashMap<>(); + for (int u : nums) { + graph.putIfAbsent(u, new HashSet<>()); + if (graph.keySet().contains(u - 1)) { + graph.get(u - 1).add(u); + graph.get(u).add(u - 1); + } + if (graph.keySet().contains(u + 1)) { + graph.get(u + 1).add(u); + graph.get(u).add(u + 1); + } } + int max = 0; + for (int i : graph.keySet()) { + if (!done.contains(i)) { + Stack stack = new Stack<>(); + stack.add(i); + max = Math.max(max, dfs(0, stack)); + } + } + return max; + } + private int dfs(int count, Stack stack) { + while (!stack.isEmpty()) { + int top = stack.pop(); + count++; + done.add(top); - private int dfs(int count, Stack stack){ - while(!stack.isEmpty()){ - int top = stack.pop(); - count++; - done.add(top); - - Set children = graph.get(top); - if(children != null){ - children.stream().filter(c -> !done.contains(c)).forEach(stack::push); - } - } - return count; + Set children = graph.get(top); + if (children != null) { + children.stream().filter(c -> !done.contains(c)).forEach(stack::push); + } } + return count; + } } diff --git a/problems/src/depth_first_search/Minesweeper.java b/problems/src/depth_first_search/Minesweeper.java index fbf41584..eb71da36 100644 --- a/problems/src/depth_first_search/Minesweeper.java +++ b/problems/src/depth_first_search/Minesweeper.java @@ -1,107 +1,111 @@ package depth_first_search; /** - * Created by pradhang on 3/28/2017. - * You are given a 2D char matrix representing the game board. 'M' represents an unrevealed mine, 'E' represents an unrevealed empty square, 'B' represents a revealed blank square that has no adjacent (above, below, left, right, and all 4 diagonals) mines, digit ('1' to '8') represents how many mines are adjacent to this revealed square, and finally 'X' represents a revealed mine. - *

- * Now given the next click position (row and column indices) among all the unrevealed squares ('M' or 'E'), return the board after revealing this position according to the following rules: - *

- * If a mine ('M') is revealed, then the game is over - change it to 'X'. - * If an empty square ('E') with no adjacent mines is revealed, then change it to revealed blank ('B') and all of its adjacent unrevealed squares should be revealed recursively. - * If an empty square ('E') with at least one adjacent mine is revealed, then change it to a digit ('1' to '8') representing the number of adjacent mines. - * Return the board when no more squares will be revealed. - * Example 1: + * Created by pradhang on 3/28/2017. You are given a 2D char matrix representing the game board. 'M' + * represents an unrevealed mine, 'E' represents an unrevealed empty square, 'B' represents a + * revealed blank square that has no adjacent (above, below, left, right, and all 4 diagonals) + * mines, digit ('1' to '8') represents how many mines are adjacent to this revealed square, and + * finally 'X' represents a revealed mine. + * + *

Now given the next click position (row and column indices) among all the unrevealed squares + * ('M' or 'E'), return the board after revealing this position according to the following rules: + * + *

If a mine ('M') is revealed, then the game is over - change it to 'X'. If an empty square + * ('E') with no adjacent mines is revealed, then change it to revealed blank ('B') and all of its + * adjacent unrevealed squares should be revealed recursively. If an empty square ('E') with at + * least one adjacent mine is revealed, then change it to a digit ('1' to '8') representing the + * number of adjacent mines. Return the board when no more squares will be revealed. Example 1: * Input: - *

- * [['E', 'E', 'E', 'E', 'E'], - * ['E', 'E', 'M', 'E', 'E'], - * ['E', 'E', 'E', 'E', 'E'], - * ['E', 'E', 'E', 'E', 'E']] - *

- * Click : [3,0] - *

- * Output: - *

- * [['B', '1', 'E', '1', 'B'], - * ['B', '1', 'M', '1', 'B'], - * ['B', '1', '1', '1', 'B'], - * ['B', 'B', 'B', 'B', 'B']] - *

- * Example 2: - * Input: - *

- * [['B', '1', 'E', '1', 'B'], - * ['B', '1', 'M', '1', 'B'], - * ['B', '1', '1', '1', 'B'], - * ['B', 'B', 'B', 'B', 'B']] - *

- * Click : [1,2] - *

- * Output: - *

- * [['B', '1', 'E', '1', 'B'], - * ['B', '1', 'X', '1', 'B'], - * ['B', '1', '1', '1', 'B'], - * ['B', 'B', 'B', 'B', 'B']] - *

- * Note: - * The range of the input matrix's height and width is [1,50]. - * The click position will only be an unrevealed square ('M' or 'E'), which also means the input board contains at least one clickable square. - * The input board won't be a stage when game is over (some mines have been revealed). - * For simplicity, not mentioned rules should be ignored in this problem. For example, you don't need to reveal all the unrevealed mines when the game is over, consider any cases that you will win the game or flag any squares. + * + *

[['E', 'E', 'E', 'E', 'E'], ['E', 'E', 'M', 'E', 'E'], ['E', 'E', 'E', 'E', 'E'], ['E', 'E', + * 'E', 'E', 'E']] + * + *

Click : [3,0] + * + *

Output: + * + *

[['B', '1', 'E', '1', 'B'], ['B', '1', 'M', '1', 'B'], ['B', '1', '1', '1', 'B'], ['B', 'B', + * 'B', 'B', 'B']] + * + *

Example 2: Input: + * + *

[['B', '1', 'E', '1', 'B'], ['B', '1', 'M', '1', 'B'], ['B', '1', '1', '1', 'B'], ['B', 'B', + * 'B', 'B', 'B']] + * + *

Click : [1,2] + * + *

Output: + * + *

[['B', '1', 'E', '1', 'B'], ['B', '1', 'X', '1', 'B'], ['B', '1', '1', '1', 'B'], ['B', 'B', + * 'B', 'B', 'B']] + * + *

Note: The range of the input matrix's height and width is [1,50]. The click position will only + * be an unrevealed square ('M' or 'E'), which also means the input board contains at least one + * clickable square. The input board won't be a stage when game is over (some mines have been + * revealed). For simplicity, not mentioned rules should be ignored in this problem. For example, + * you don't need to reveal all the unrevealed mines when the game is over, consider any cases that + * you will win the game or flag any squares. */ public class Minesweeper { - private static final int[] R = {1, 1, 1, 0, 0, -1, -1, -1}; - private static final int[] C = {-1, 0, 1, -1, 1, -1, 0, 1}; + private static final int[] R = {1, 1, 1, 0, 0, -1, -1, -1}; + private static final int[] C = {-1, 0, 1, -1, 1, -1, 0, 1}; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - char[][] board = {{'E', 'E', 'E', 'E', 'E'}, {'E', 'E', 'M', 'E', 'E'}, {'E', 'E', 'E', 'E', 'E'}, {'E', 'E', 'E', 'E', 'E'}}; - int[] click = {3, 0}; - new Minesweeper().updateBoard(board, click); - for (int i = 0; i < board.length; i++) - System.out.println(board[i]); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + char[][] board = { + {'E', 'E', 'E', 'E', 'E'}, + {'E', 'E', 'M', 'E', 'E'}, + {'E', 'E', 'E', 'E', 'E'}, + {'E', 'E', 'E', 'E', 'E'} + }; + int[] click = {3, 0}; + new Minesweeper().updateBoard(board, click); + for (int i = 0; i < board.length; i++) System.out.println(board[i]); + } - public char[][] updateBoard(char[][] board, int[] click) { - int r = click[0]; - int c = click[1]; - dfs(board, r, c); - return board; - } + public char[][] updateBoard(char[][] board, int[] click) { + int r = click[0]; + int c = click[1]; + dfs(board, r, c); + return board; + } - private void dfs(char[][] board, int r, int c) { - if (board[r][c] == 'M') { - board[r][c] = 'X'; - } else { - int mineCount = 0; - for (int i = 0; i < 8; i++) { - int newR = r + R[i]; - int newC = c + C[i]; - if (newR >= 0 && newC >= 0 && newR < board.length && newC < board[0].length && - board[newR][newC] == 'M') //boundary check - mineCount++; - } - if (mineCount > 0) - board[r][c] = (char) (mineCount + '0'); - else { - board[r][c] = 'B'; - for (int i = 0; i < 8; i++) { - int newR = r + R[i]; - int newC = c + C[i]; - if (newR >= 0 && newC >= 0 && newR < board.length && newC < board[0].length && - board[newR][newC] == 'E') //boundary check - { - dfs(board, newR, newC); - } - } - } + private void dfs(char[][] board, int r, int c) { + if (board[r][c] == 'M') { + board[r][c] = 'X'; + } else { + int mineCount = 0; + for (int i = 0; i < 8; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 + && newC >= 0 + && newR < board.length + && newC < board[0].length + && board[newR][newC] == 'M') // boundary check + mineCount++; + } + if (mineCount > 0) board[r][c] = (char) (mineCount + '0'); + else { + board[r][c] = 'B'; + for (int i = 0; i < 8; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 + && newC >= 0 + && newR < board.length + && newC < board[0].length + && board[newR][newC] == 'E') // boundary check + { + dfs(board, newR, newC); + } } + } } + } } - diff --git a/problems/src/depth_first_search/MovieRecommend.java b/problems/src/depth_first_search/MovieRecommend.java index a4e061d7..1acb16b2 100644 --- a/problems/src/depth_first_search/MovieRecommend.java +++ b/problems/src/depth_first_search/MovieRecommend.java @@ -2,65 +2,61 @@ import java.util.*; -/** - * Created by gouthamvidyapradhan on 25/02/2017. - * Accepted - */ +/** Created by gouthamvidyapradhan on 25/02/2017. Accepted */ public class MovieRecommend { - Set visited = new HashSet<>(); - List list = new ArrayList<>(); + Set visited = new HashSet<>(); + List list = new ArrayList<>(); - class Movie { - private int movieId; - private float rating; - private ArrayList similarMovies; + class Movie { + private int movieId; + private float rating; + private ArrayList similarMovies; - public List getSimilarMovies() { - return similarMovies; - } + public List getSimilarMovies() { + return similarMovies; } - - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - - } - - public Set getMovieRecommendations(Movie movie, int N) { - dfs(movie); - Set result = new HashSet<>(); - Comparator cmp = new Comparator() { - @Override - public int compare(Movie o1, Movie o2) { - return Float.compare(o2.rating, o1.rating); - } + } + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception {} + + public Set getMovieRecommendations(Movie movie, int N) { + dfs(movie); + Set result = new HashSet<>(); + Comparator cmp = + new Comparator() { + @Override + public int compare(Movie o1, Movie o2) { + return Float.compare(o2.rating, o1.rating); + } }; - Collections.sort(list, cmp); - - if (list.size() < N) { - result.addAll(list); - return result; - } + Collections.sort(list, cmp); - for (int i = 0; i < N; i++) { - result.add(list.get(i)); - } + if (list.size() < N) { + result.addAll(list); + return result; + } - return result; + for (int i = 0; i < N; i++) { + result.add(list.get(i)); } - private void dfs(Movie m) { - visited.add(m.movieId); // mark this visited - List movies = m.getSimilarMovies(); - for (Movie mo : movies) { - if (!visited.contains(mo.movieId)) { - list.add(mo); - dfs(mo); - } - } + return result; + } + + private void dfs(Movie m) { + visited.add(m.movieId); // mark this visited + List movies = m.getSimilarMovies(); + for (Movie mo : movies) { + if (!visited.contains(mo.movieId)) { + list.add(mo); + dfs(mo); + } } + } } diff --git a/problems/src/depth_first_search/NumberOfDistinctIslands.java b/problems/src/depth_first_search/NumberOfDistinctIslands.java index 803a1342..e20e8960 100644 --- a/problems/src/depth_first_search/NumberOfDistinctIslands.java +++ b/problems/src/depth_first_search/NumberOfDistinctIslands.java @@ -4,88 +4,72 @@ import java.util.Set; /** - * Created by gouthamvidyapradhan on 23/04/2018. - * Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) connected - * 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water. - - Count the number of distinct islands. An island is considered to be the same as another if and only if one island - can be translated (and not rotated or reflected) to equal the other. - - Example 1: - 11000 - 11000 - 00011 - 00011 - Given the above grid map, return 1. - Example 2: - 11011 - 10000 - 00001 - 11011 - Given the above grid map, return 3. - - Notice that: - 11 - 1 - and - 1 - 11 - are considered different island islands, because we do not consider reflection / rotation. - Note: The length of each dimension in the given grid does not exceed 50. - - Solution: O(N x M) create a signature of each island based on the direction and then use a hashset to count the - islands. + * Created by gouthamvidyapradhan on 23/04/2018. Given a non-empty 2D array grid of 0's and 1's, an + * island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) + * You may assume all four edges of the grid are surrounded by water. + * + *

Count the number of distinct islands. An island is considered to be the same as another if and + * only if one island can be translated (and not rotated or reflected) to equal the other. + * + *

Example 1: 11000 11000 00011 00011 Given the above grid map, return 1. Example 2: 11011 10000 + * 00001 11011 Given the above grid map, return 3. + * + *

Notice that: 11 1 and 1 11 are considered different island islands, because we do not consider + * reflection / rotation. Note: The length of each dimension in the given grid does not exceed 50. + * + *

Solution: O(N x M) create a signature of each island based on the direction and then use a + * hashset to count the islands. */ public class NumberOfDistinctIslands { - private int[] R = {0, 1, 0, -1}; - private int[] C = {1, 0, -1, 0}; - private boolean[][] done; - private Set islands; - /** - * Main method - * @param args - */ - public static void main(String[] args) throws Exception{ - int[][] N = {{1, 1, 1, 1}, {1, 0, 1, 0}, {0, 0, 0, 0}, {0, 1, 1, 1}, {1,1,0,1}}; - System.out.println(new NumberOfDistinctIslands().numDistinctIslands(N)); - } + private int[] R = {0, 1, 0, -1}; + private int[] C = {1, 0, -1, 0}; + private boolean[][] done; + private Set islands; + /** + * Main method + * + * @param args + */ + public static void main(String[] args) throws Exception { + int[][] N = {{1, 1, 1, 1}, {1, 0, 1, 0}, {0, 0, 0, 0}, {0, 1, 1, 1}, {1, 1, 0, 1}}; + System.out.println(new NumberOfDistinctIslands().numDistinctIslands(N)); + } - public int numDistinctIslands(int[][] grid) { - done = new boolean[grid.length][grid[0].length]; - islands = new HashSet<>(); - for(int i = 0; i < grid.length; i ++){ - for(int j = 0; j < grid[0].length; j ++){ - if(!done[i][j] && grid[i][j] == 1){ - StringBuilder sb = new StringBuilder(); - dfs(i, j, grid, sb); - islands.add(sb.toString()); - } - } + public int numDistinctIslands(int[][] grid) { + done = new boolean[grid.length][grid[0].length]; + islands = new HashSet<>(); + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (!done[i][j] && grid[i][j] == 1) { + StringBuilder sb = new StringBuilder(); + dfs(i, j, grid, sb); + islands.add(sb.toString()); } - return islands.size(); + } } + return islands.size(); + } - private void dfs(int r, int c, int[][] grid, StringBuilder sb){ - done[r][c] = true; - for(int i = 0; i < 4; i ++){ - int newR = r + R[i]; - int newC = c + C[i]; - if(newR >= 0 && newC >= 0 && newR < grid.length && newC < grid[0].length){ - if(!done[newR][newC] && grid[newR][newC] == 1){ - if(i == 0){ - sb.append("R"); - } else if(i == 1){ - sb.append("D"); - } else if(i == 2){ - sb.append("L"); - } else{ - sb.append("U"); - } - dfs(newR, newC, grid, sb); - } - } + private void dfs(int r, int c, int[][] grid, StringBuilder sb) { + done[r][c] = true; + for (int i = 0; i < 4; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 && newC >= 0 && newR < grid.length && newC < grid[0].length) { + if (!done[newR][newC] && grid[newR][newC] == 1) { + if (i == 0) { + sb.append("R"); + } else if (i == 1) { + sb.append("D"); + } else if (i == 2) { + sb.append("L"); + } else { + sb.append("U"); + } + dfs(newR, newC, grid, sb); } - sb.append("B"); + } } - + sb.append("B"); + } } diff --git a/problems/src/depth_first_search/NumberOfDistinctIslandsII.java b/problems/src/depth_first_search/NumberOfDistinctIslandsII.java index a71aab50..ae4af067 100644 --- a/problems/src/depth_first_search/NumberOfDistinctIslandsII.java +++ b/problems/src/depth_first_search/NumberOfDistinctIslandsII.java @@ -4,168 +4,150 @@ import java.util.stream.Collectors; /** - * Created by gouthamvidyapradhan on 27/04/2018. - * Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) connected - * 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water. - - Count the number of distinct islands. An island is considered to be the same as another if they have the same - shape, or have the same shape after rotation (90, 180, or 270 degrees only) or reflection (left/right direction or - up/down direction). - - Example 1: - 11000 - 10000 - 00001 - 00011 - Given the above grid map, return 1. - - Notice that: - 11 - 1 - and - 1 - 11 - are considered same island shapes. Because if we make a 180 degrees clockwise rotation on the first island, then - two islands will have the same shapes. - Example 2: - 11100 - 10001 - 01001 - 01110 - Given the above grid map, return 2. - - Here are the two distinct islands: - 111 - 1 - and - 1 - 1 - - Notice that: - 111 - 1 - and - 1 - 111 - are considered same island shapes. Because if we flip the first array in the up/down direction, then they have the - same shapes. - Note: The length of each dimension in the given grid does not exceed 50. - - Solution: General idea is to get the co-ordinates of each shape using dfs and rotate/reflect each point in a shape - to transform each shape to a new possible shape (there are 8 possible shapes after rotation and reflection). Sort the - new coordinates of each transformed shape and reduce each shape to a canonical key. Use a hash-set to count total - number of such keys. - - Some background on rotation and reflection: - ------------------------------------------- - Rotate co-ordinates using formula [x′y′]=[[cosθ -sinθ], [sinθ cosθ]] [x y] where θ = {0, 90, 180, 270} - There are 4 possible rotation points and for each rotation point obtain the reflection on each x and y axis. - Rotation and reflection results in total of 8 points such as (x, y), (-x, y), (x, -y), (-x, -y), - (y, x), (-y, x), (y, -x) and (-y, -x). - - - + * Created by gouthamvidyapradhan on 27/04/2018. Given a non-empty 2D array grid of 0's and 1's, an + * island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) + * You may assume all four edges of the grid are surrounded by water. + * + *

Count the number of distinct islands. An island is considered to be the same as another if + * they have the same shape, or have the same shape after rotation (90, 180, or 270 degrees only) or + * reflection (left/right direction or up/down direction). + * + *

Example 1: 11000 10000 00001 00011 Given the above grid map, return 1. + * + *

Notice that: 11 1 and 1 11 are considered same island shapes. Because if we make a 180 degrees + * clockwise rotation on the first island, then two islands will have the same shapes. Example 2: + * 11100 10001 01001 01110 Given the above grid map, return 2. + * + *

Here are the two distinct islands: 111 1 and 1 1 + * + *

Notice that: 111 1 and 1 111 are considered same island shapes. Because if we flip the first + * array in the up/down direction, then they have the same shapes. Note: The length of each + * dimension in the given grid does not exceed 50. + * + *

Solution: General idea is to get the co-ordinates of each shape using dfs and rotate/reflect + * each point in a shape to transform each shape to a new possible shape (there are 8 possible + * shapes after rotation and reflection). Sort the new coordinates of each transformed shape and + * reduce each shape to a canonical key. Use a hash-set to count total number of such keys. + * + *

Some background on rotation and reflection: ------------------------------------------- Rotate + * co-ordinates using formula [x′y′]=[[cosθ -sinθ], [sinθ cosθ]] [x y] where θ = {0, 90, 180, 270} + * There are 4 possible rotation points and for each rotation point obtain the reflection on each x + * and y axis. Rotation and reflection results in total of 8 points such as (x, y), (-x, y), (x, + * -y), (-x, -y), (y, x), (-y, x), (y, -x) and (-y, -x). */ public class NumberOfDistinctIslandsII { - private final int[] R = {0, 1, 0, -1}; - private final int[] C = {1, 0, -1, 0}; - private boolean[][] done; + private final int[] R = {0, 1, 0, -1}; + private final int[] C = {1, 0, -1, 0}; + private boolean[][] done; - class Point implements Comparable{ - int x; int y; - Point(int x, int y){ - this.x = x; - this.y = y; - } + class Point implements Comparable { + int x; + int y; - @Override - public int compareTo(Point o) { - if(this.x == o.x){ - return Integer.compare(this.y, o.y); - } return Integer.compare(this.x, o.x); - } - } - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[][] grid = {{1,1,0,0,0}, {1,0,0,0,0}, {0,0,0,0,1}, {0,0,0,1,1}}; - System.out.println(new NumberOfDistinctIslandsII().numDistinctIslands2(grid)); + Point(int x, int y) { + this.x = x; + this.y = y; } - public int numDistinctIslands2(int[][] grid) { - List> shapes = new ArrayList<>(); - done = new boolean[grid.length][grid[0].length]; - Set islands = new HashSet<>(); - for(int i = 0; i < grid.length; i++){ - for(int j = 0; j < grid[0].length; j++){ - if(!done[i][j] && grid[i][j] == 1){ - List points = new ArrayList<>(); - dfs(i, j, grid, points); - shapes.add(points); - } - } - } - for(List shape : shapes){ - List> eightShapes = rotateAndReflect(shape); - islands.add(genKey(eightShapes)); - } - return islands.size(); + @Override + public int compareTo(Point o) { + if (this.x == o.x) { + return Integer.compare(this.y, o.y); + } + return Integer.compare(this.x, o.x); } - - /** - * Generate a canonical key - * @param eighShapes - * @return - */ - private String genKey(List> eighShapes){ - List keys = new ArrayList<>(); - for(List shape : eighShapes){ - Collections.sort(shape); - Point first = shape.get(0); - keys.add(shape.stream().map(s -> new Point(s.x - first.x, s.y - first.y)) - .map(p -> p.x + ":" + p.y).collect(Collectors.joining( "," ))); + } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[][] grid = {{1, 1, 0, 0, 0}, {1, 0, 0, 0, 0}, {0, 0, 0, 0, 1}, {0, 0, 0, 1, 1}}; + System.out.println(new NumberOfDistinctIslandsII().numDistinctIslands2(grid)); + } + + public int numDistinctIslands2(int[][] grid) { + List> shapes = new ArrayList<>(); + done = new boolean[grid.length][grid[0].length]; + Set islands = new HashSet<>(); + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (!done[i][j] && grid[i][j] == 1) { + List points = new ArrayList<>(); + dfs(i, j, grid, points); + shapes.add(points); } - Collections.sort(keys); - return keys.get(0); + } } - - /** - * Rotate and reflect a given shape to 8 possible shapes - * @param shape - * @return - */ - private List> rotateAndReflect(List shape){ - Map> map = new HashMap<>(); - for(int i = 0; i < 8; i ++){ - map.put(i, new ArrayList<>()); - } - for(Point point : shape){ - map.get(0).add(new Point(point.x, point.y)); - map.get(1).add(new Point(-point.x, point.y)); - map.get(2).add(new Point(point.x, -point.y)); - map.get(3).add(new Point(-point.x, -point.y)); - map.get(4).add(new Point(point.y, point.x)); - map.get(5).add(new Point(-point.y, point.x)); - map.get(6).add(new Point(point.y, -point.x)); - map.get(7).add(new Point(-point.y, -point.x)); - } - return new ArrayList<>(map.values()); + for (List shape : shapes) { + List> eightShapes = rotateAndReflect(shape); + islands.add(genKey(eightShapes)); } - - - private void dfs(int r, int c, int[][] grid, List points){ - done[r][c] = true; - points.add(new Point(c, r)); - for(int i = 0; i < 4; i ++){ - int newR = r + R[i]; - int newC = c + C[i]; - if(newR >= 0 && newC >= 0 && newR < grid.length && newC < grid[0].length && grid[newR][newC] == 1 && - !done[newR][newC]){ - dfs(newR, newC, grid, points); - } - } + return islands.size(); + } + + /** + * Generate a canonical key + * + * @param eighShapes + * @return + */ + private String genKey(List> eighShapes) { + List keys = new ArrayList<>(); + for (List shape : eighShapes) { + Collections.sort(shape); + Point first = shape.get(0); + keys.add( + shape + .stream() + .map(s -> new Point(s.x - first.x, s.y - first.y)) + .map(p -> p.x + ":" + p.y) + .collect(Collectors.joining(","))); + } + Collections.sort(keys); + return keys.get(0); + } + + /** + * Rotate and reflect a given shape to 8 possible shapes + * + * @param shape + * @return + */ + private List> rotateAndReflect(List shape) { + Map> map = new HashMap<>(); + for (int i = 0; i < 8; i++) { + map.put(i, new ArrayList<>()); + } + for (Point point : shape) { + map.get(0).add(new Point(point.x, point.y)); + map.get(1).add(new Point(-point.x, point.y)); + map.get(2).add(new Point(point.x, -point.y)); + map.get(3).add(new Point(-point.x, -point.y)); + map.get(4).add(new Point(point.y, point.x)); + map.get(5).add(new Point(-point.y, point.x)); + map.get(6).add(new Point(point.y, -point.x)); + map.get(7).add(new Point(-point.y, -point.x)); + } + return new ArrayList<>(map.values()); + } + + private void dfs(int r, int c, int[][] grid, List points) { + done[r][c] = true; + points.add(new Point(c, r)); + for (int i = 0; i < 4; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 + && newC >= 0 + && newR < grid.length + && newC < grid[0].length + && grid[newR][newC] == 1 + && !done[newR][newC]) { + dfs(newR, newC, grid, points); + } } + } } diff --git a/problems/src/depth_first_search/NumberOfIslands.java b/problems/src/depth_first_search/NumberOfIslands.java index e624f42f..a4745b05 100644 --- a/problems/src/depth_first_search/NumberOfIslands.java +++ b/problems/src/depth_first_search/NumberOfIslands.java @@ -1,65 +1,59 @@ package depth_first_search; /** - * Created by gouthamvidyapradhan on 09/03/2017. - * Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water. - *

- * Example 1: - *

- * 11110 - * 11010 - * 11000 - * 00000 - * Answer: 1 - *

- * Example 2: - *

- * 11000 - * 11000 - * 00100 - * 00011 - * Answer: 3 + * Created by gouthamvidyapradhan on 09/03/2017. Given a 2d grid map of '1's (land) and '0's + * (water), count the number of islands. An island is surrounded by water and is formed by + * connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid + * are all surrounded by water. + * + *

Example 1: + * + *

11110 11010 11000 00000 Answer: 1 + * + *

Example 2: + * + *

11000 11000 00100 00011 Answer: 3 */ public class NumberOfIslands { - int[] R = {0, 0, 1, -1}; - int[] C = {1, -1, 0, 0}; - private static int M, N; - private static char temp[][]; + int[] R = {0, 0, 1, -1}; + int[] C = {1, -1, 0, 0}; + private static int M, N; + private static char temp[][]; - public int numIslands(char[][] grid) { - M = grid.length; - if (M == 0) return 0; - N = grid[0].length; - temp = new char[M][N]; - int count = 0; + public int numIslands(char[][] grid) { + M = grid.length; + if (M == 0) return 0; + N = grid[0].length; + temp = new char[M][N]; + int count = 0; - for (int i = 0; i < M; i++) { - System.arraycopy(grid[i], 0, temp[i], 0, N); - } + for (int i = 0; i < M; i++) { + System.arraycopy(grid[i], 0, temp[i], 0, N); + } - for (int i = 0; i < M; i++) { - for (int j = 0; j < N; j++) { - if (temp[i][j] == '1') { - ++count; - dfs(i, j); - } - } + for (int i = 0; i < M; i++) { + for (int j = 0; j < N; j++) { + if (temp[i][j] == '1') { + ++count; + dfs(i, j); } - - return count; + } } - private void dfs(int r, int c) { - temp[r][c] = '0'; - for (int i = 0; i < 4; i++) { - int newR = r + R[i]; - int newC = c + C[i]; - if (newR >= 0 && newC >= 0 && newR < M && newC < N) { - if (temp[newR][newC] != '0') //not visited - { - dfs(newR, newC); - } - } + return count; + } + + private void dfs(int r, int c) { + temp[r][c] = '0'; + for (int i = 0; i < 4; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 && newC >= 0 && newR < M && newC < N) { + if (temp[newR][newC] != '0') // not visited + { + dfs(newR, newC); } + } } + } } diff --git a/problems/src/depth_first_search/RobotRoomCleaner.java b/problems/src/depth_first_search/RobotRoomCleaner.java index 2189f431..189a6478 100644 --- a/problems/src/depth_first_search/RobotRoomCleaner.java +++ b/problems/src/depth_first_search/RobotRoomCleaner.java @@ -5,141 +5,121 @@ import java.util.Set; /** - * Created by gouthamvidyapradhan on 08/03/2019 - Given a robot cleaner in a room modeled as a grid. - - Each cell in the grid can be empty or blocked. - - The robot cleaner with 4 given APIs can move forward, turn left or turn right. Each turn it made is 90 degrees. - - When it tries to move into a blocked cell, its bumper sensor detects the obstacle and it stays on the current cell. - - Design an algorithm to clean the entire room using only the 4 given APIs shown below. - - interface Robot { - // returns true if next cell is open and robot moves into the cell. - // returns false if next cell is obstacle and robot stays on the current cell. - boolean move(); - - // Robot will stay on the same cell after calling turnLeft/turnRight. - // Each turn will be 90 degrees. - void turnLeft(); - void turnRight(); - - // Clean the current cell. - void clean(); - } - Example: - - Input: - room = [ - [1,1,1,1,1,0,1,1], - [1,1,1,1,1,0,1,1], - [1,0,1,1,1,1,1,1], - [0,0,0,1,0,0,0,0], - [1,1,1,1,1,1,1,1] - ], - row = 1, - col = 3 - - Explanation: - All grids in the room are marked by either 0 or 1. - 0 means the cell is blocked, while 1 means the cell is accessible. - The robot initially starts at the position of row=1, col=3. - From the top left corner, its position is one row below and three columns right. - Notes: - - The input is only given to initialize the room and the robot's position internally. You must solve this problem - "blindfolded". In other words, you must control the robot using only the mentioned 4 APIs, without knowing the room - layout and the initial robot's position. - The robot's initial position will always be in an accessible cell. - The initial direction of the robot will be facing up. - All accessible cells are connected, which means the all cells marked as 1 will be accessible by the robot. - Assume all four edges of the grid are all surrounded by wall. + * Created by gouthamvidyapradhan on 08/03/2019 Given a robot cleaner in a room modeled as a grid. * + *

Each cell in the grid can be empty or blocked. * - * Solution: O(N x M) - * Maintain a direction and position of robot in each cell and perform a dfs to clean all rooms. - * Important to note here is that during call back in the dfs recursion the robot has to return back to its original - * cell and orientation + *

The robot cleaner with 4 given APIs can move forward, turn left or turn right. Each turn it + * made is 90 degrees. + * + *

When it tries to move into a blocked cell, its bumper sensor detects the obstacle and it stays + * on the current cell. + * + *

Design an algorithm to clean the entire room using only the 4 given APIs shown below. + * + *

interface Robot { // returns true if next cell is open and robot moves into the cell. // + * returns false if next cell is obstacle and robot stays on the current cell. boolean move(); + * + *

// Robot will stay on the same cell after calling turnLeft/turnRight. // Each turn will be 90 + * degrees. void turnLeft(); void turnRight(); + * + *

// Clean the current cell. void clean(); } Example: + * + *

Input: room = [ [1,1,1,1,1,0,1,1], [1,1,1,1,1,0,1,1], [1,0,1,1,1,1,1,1], [0,0,0,1,0,0,0,0], + * [1,1,1,1,1,1,1,1] ], row = 1, col = 3 + * + *

Explanation: All grids in the room are marked by either 0 or 1. 0 means the cell is blocked, + * while 1 means the cell is accessible. The robot initially starts at the position of row=1, col=3. + * From the top left corner, its position is one row below and three columns right. Notes: + * + *

The input is only given to initialize the room and the robot's position internally. You must + * solve this problem "blindfolded". In other words, you must control the robot using only the + * mentioned 4 APIs, without knowing the room layout and the initial robot's position. The robot's + * initial position will always be in an accessible cell. The initial direction of the robot will be + * facing up. All accessible cells are connected, which means the all cells marked as 1 will be + * accessible by the robot. Assume all four edges of the grid are all surrounded by wall. + * + *

Solution: O(N x M) Maintain a direction and position of robot in each cell and perform a dfs + * to clean all rooms. Important to note here is that during call back in the dfs recursion the + * robot has to return back to its original cell and orientation */ public class RobotRoomCleaner { - //direction - //UP 0, LEFT = 1, DOWN = 2, RIGHT = 3 + // direction + // UP 0, LEFT = 1, DOWN = 2, RIGHT = 3 - private final int[] R = {-1, 0, 1, 0}; - private final int[] C = {0, -1, 0, 1}; + private final int[] R = {-1, 0, 1, 0}; + private final int[] C = {0, -1, 0, 1}; + interface Robot { + // Returns true if the cell in front is open and robot moves into the cell. + // Returns false if the cell in front is blocked and robot stays in the current cell. + public boolean move(); - interface Robot { - // Returns true if the cell in front is open and robot moves into the cell. - // Returns false if the cell in front is blocked and robot stays in the current cell. - public boolean move(); + // Robot will stay in the same cell after calling turnLeft/turnRight. + // Each turn will be 90 degrees. + public void turnLeft(); - // Robot will stay in the same cell after calling turnLeft/turnRight. - // Each turn will be 90 degrees. - public void turnLeft(); - public void turnRight(); + public void turnRight(); - // Clean the current cell. - public void clean(); - } + // Clean the current cell. + public void clean(); + } - static class Position{ - int r, c; - Position(int r, int c){ - this.r = r; - this.c = c; - } - - @Override - public boolean equals(Object obj) { - int r = ((Position)obj).r; - int c = ((Position)obj).c; - return (this.r == r && this.c == c); - } + static class Position { + int r, c; - @Override - public int hashCode() { - return Objects.hash(r, c); - } + Position(int r, int c) { + this.r = r; + this.c = c; } - private static Set done; - - /** - * Main method - * @param args - */ - public static void main(String[] args) { - + @Override + public boolean equals(Object obj) { + int r = ((Position) obj).r; + int c = ((Position) obj).c; + return (this.r == r && this.c == c); } - public void cleanRoom(Robot robot) { - done = new HashSet<>(); - dfs(1, 3, done, robot, 0); + @Override + public int hashCode() { + return Objects.hash(r, c); } - - private void dfs(int r, int c, Set done, Robot robot, int direction){ - done.add(new Position(r, c)); - robot.clean(); - for(int i = 0; i < 4; i ++){ - int newR = r + R[direction]; - int newC = c + C[direction]; - if(!done.contains(new Position(newR, newC))){ - boolean possible = robot.move(); - if(possible){ - dfs(newR, newC, done, robot, direction); - } - } - robot.turnLeft(); - direction = (direction + 1) % 4; - } - robot.turnLeft(); - robot.turnLeft(); - robot.move(); - robot.turnLeft(); - robot.turnLeft(); + } + + private static Set done; + + /** + * Main method + * + * @param args + */ + public static void main(String[] args) {} + + public void cleanRoom(Robot robot) { + done = new HashSet<>(); + dfs(1, 3, done, robot, 0); + } + + private void dfs(int r, int c, Set done, Robot robot, int direction) { + done.add(new Position(r, c)); + robot.clean(); + for (int i = 0; i < 4; i++) { + int newR = r + R[direction]; + int newC = c + C[direction]; + if (!done.contains(new Position(newR, newC))) { + boolean possible = robot.move(); + if (possible) { + dfs(newR, newC, done, robot, direction); + } + } + robot.turnLeft(); + direction = (direction + 1) % 4; } + robot.turnLeft(); + robot.turnLeft(); + robot.move(); + robot.turnLeft(); + robot.turnLeft(); + } } diff --git a/problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java b/problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java index a1b012d0..b82ed190 100644 --- a/problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java +++ b/problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java @@ -1,63 +1,66 @@ package depth_first_search; /** - * Created by gouthamvidyapradhan on 24/06/2018. - * An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. The black pixels are - * connected, i.e., there is only one black region. Pixels are connected horizontally and vertically. Given the - * location (x, y) of one of the black pixels, return the area of the smallest (axis-aligned) rectangle that - * encloses all black pixels. - - Example: - - Input: - [ - "0010", - "0110", - "0100" - ] - and x = 0, y = 2 - - Output: 6 - - Solution: O(n x m) do a dfs and keep track of min and max length-breadth. Return the product of l x b + * Created by gouthamvidyapradhan on 24/06/2018. An image is represented by a binary matrix with 0 + * as a white pixel and 1 as a black pixel. The black pixels are connected, i.e., there is only one + * black region. Pixels are connected horizontally and vertically. Given the location (x, y) of one + * of the black pixels, return the area of the smallest (axis-aligned) rectangle that encloses all + * black pixels. + * + *

Example: + * + *

Input: [ "0010", "0110", "0100" ] and x = 0, y = 2 + * + *

Output: 6 + * + *

Solution: O(n x m) do a dfs and keep track of min and max length-breadth. Return the product + * of l x b */ public class SmallestRectangleEnclosingBlackPixels { - private final int[] R = {1, -1, 0, 0}; - private final int[] C = {0, 0, -1, 1}; - private boolean[][] done; - private int maxR, minR, minC, maxC; - public static void main(String[] args) { - char[][] A = {{'0', '0', '1', '1'}, {'0', '1', '1', '0'}, {'0', '1', '0', '0'}}; - System.out.println(new SmallestRectangleEnclosingBlackPixels().minArea(A, 0, 2)); - } + private final int[] R = {1, -1, 0, 0}; + private final int[] C = {0, 0, -1, 1}; + private boolean[][] done; + private int maxR, minR, minC, maxC; - public int minArea(char[][] image, int x, int y) { - done = new boolean[image.length][image[0].length]; - maxR = 0; maxC = 0; minR = Integer.MAX_VALUE; minC = Integer.MAX_VALUE; - maxR = Math.max(maxR, x); - minR = Math.min(minR, x); + public static void main(String[] args) { + char[][] A = {{'0', '0', '1', '1'}, {'0', '1', '1', '0'}, {'0', '1', '0', '0'}}; + System.out.println(new SmallestRectangleEnclosingBlackPixels().minArea(A, 0, 2)); + } - maxC = Math.max(maxC, y); - minC = Math.min(minC, y); - dfs(image, x, y); - return ((maxR - minR) + 1) * ((maxC - minC) + 1); - } + public int minArea(char[][] image, int x, int y) { + done = new boolean[image.length][image[0].length]; + maxR = 0; + maxC = 0; + minR = Integer.MAX_VALUE; + minC = Integer.MAX_VALUE; + maxR = Math.max(maxR, x); + minR = Math.min(minR, x); + + maxC = Math.max(maxC, y); + minC = Math.min(minC, y); + dfs(image, x, y); + return ((maxR - minR) + 1) * ((maxC - minC) + 1); + } - private void dfs(char[][] image, int r, int c){ - done[r][c] = true; - for(int i = 0; i < 4; i ++){ - int newR = r + R[i]; - int newC = c + C[i]; - if(newR >=0 && newR < image.length && newC >= 0 && newC < image[0].length && !done[newR][newC]){ - if(image[newR][newC] == '1'){ - maxR = Math.max(maxR, newR); - minR = Math.min(minR, newR); + private void dfs(char[][] image, int r, int c) { + done[r][c] = true; + for (int i = 0; i < 4; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 + && newR < image.length + && newC >= 0 + && newC < image[0].length + && !done[newR][newC]) { + if (image[newR][newC] == '1') { + maxR = Math.max(maxR, newR); + minR = Math.min(minR, newR); - maxC = Math.max(maxC, newC); - minC = Math.min(minC, newC); - dfs(image, newR, newC); - } - } + maxC = Math.max(maxC, newC); + minC = Math.min(minC, newC); + dfs(image, newR, newC); } + } } + } } diff --git a/problems/src/design/AutocompleteSystem.java b/problems/src/design/AutocompleteSystem.java index 89b426fe..ebe9deb2 100644 --- a/problems/src/design/AutocompleteSystem.java +++ b/problems/src/design/AutocompleteSystem.java @@ -4,300 +4,293 @@ /** * Created by gouthamvidyapradhan on 20/08/2017. + * + *

Design a search autocomplete system for a search engine. Users may input a sentence (at least + * one word and end with a special character '#'). For each character they type except '#', you need + * to return the top 3 historical hot sentences that have prefix the same as the part of sentence + * already typed. Here are the specific rules: + * + *

The hot degree for a sentence is defined as the number of times a user typed the exactly same + * sentence before. The returned top 3 hot sentences should be sorted by hot degree (The first is + * the hottest one). If several sentences have the same degree of hot, you need to use ASCII-code + * order (smaller one appears first). If less than 3 hot sentences exist, then just return as many + * as you can. When the input is a special character, it means the sentence ends, and in this case, + * you need to return an empty list. Your job is to implement the following functions: + * + *

The constructor function: + * + *

AutocompleteSystem(String[] sentences, int[] times): This is the constructor. The input is + * historical data. Sentences is a string array consists of previously typed sentences. Times is the + * corresponding times a sentence has been typed. Your system should record these historical data. + * + *

Now, the user wants to input a new sentence. The following function will provide the next + * character the user types: + * + *

List input(char c): The input c is the next character typed by the user. The character + * will only be lower-case letters ('a' to 'z'), blank space (' ') or a special character ('#'). + * Also, the previously typed sentence should be recorded in your system. The output will be the top + * 3 historical hot sentences that have prefix the same as the part of sentence already typed. + * *

- * Design a search autocomplete system for a search engine. Users may input a sentence (at least one word and end with a special character '#'). - * For each character they type except '#', you need to return the top 3 historical hot sentences that have prefix the same as the part of sentence already typed. - * Here are the specific rules: - *

- * The hot degree for a sentence is defined as the number of times a user typed the exactly same sentence before. - * The returned top 3 hot sentences should be sorted by hot degree (The first is the hottest one). - * If several sentences have the same degree of hot, you need to use ASCII-code order (smaller one appears first). - * If less than 3 hot sentences exist, then just return as many as you can. - * When the input is a special character, it means the sentence ends, and in this case, you need to return an empty list. - * Your job is to implement the following functions: - *

- * The constructor function: - *

- * AutocompleteSystem(String[] sentences, int[] times): This is the constructor. - * The input is historical data. Sentences is a string array consists of previously typed sentences. - * Times is the corresponding times a sentence has been typed. Your system should record these historical data. - *

- * Now, the user wants to input a new sentence. The following function will provide the next character the user types: - *

- * List input(char c): The input c is the next character typed by the user. - * The character will only be lower-case letters ('a' to 'z'), blank space (' ') or a special character ('#'). - * Also, the previously typed sentence should be recorded in your system. - * The output will be the top 3 historical hot sentences that have prefix the same as the part of sentence already typed. - *

- *

- * Example: - * Operation: AutocompleteSystem(["i love you", "island","ironman", "i love leetcode"], [5,3,2,2]) - * The system have already tracked down the following sentences and their corresponding times: - * "i love you" : 5 times - * "island" : 3 times - * "ironman" : 2 times - * "i love leetcode" : 2 times + * + *

Example: Operation: AutocompleteSystem(["i love you", "island","ironman", "i love leetcode"], + * [5,3,2,2]) The system have already tracked down the following sentences and their corresponding + * times: "i love you" : 5 times "island" : 3 times "ironman" : 2 times "i love leetcode" : 2 times * Now, the user begins another search: - *

- * Operation: input('i') - * Output: ["i love you", "island","i love leetcode"] - * Explanation: - * There are four sentences that have prefix "i". Among them, "ironman" and "i love leetcode" have same hot degree. - * Since ' ' has ASCII code 32 and 'r' has ASCII code 114, "i love leetcode" should be in front of "ironman". - * Also we only need to output top 3 hot sentences, so "ironman" will be ignored. - *

- * Operation: input(' ') - * Output: ["i love you","i love leetcode"] - * Explanation: - * There are only two sentences that have prefix "i ". - *

- * Operation: input('a') - * Output: [] - * Explanation: - * There are no sentences that have prefix "i a". - *

- * Operation: input('#') - * Output: [] - * Explanation: - * The user finished the input, the sentence "i a" should be saved as a historical sentence in system. - * And the following input will be counted as a new search. - *

- * Note: - * The input sentence will always start with a letter and end with '#', and only one blank space will exist between two words. - * The number of complete sentences that to be searched won't exceed 100. - * The length of each sentence including those in the historical data won't exceed 100. - * Please use double-quote instead of single-quote when you write test cases even for a character input. - * Please remember to RESET your class variables declared in class AutocompleteSystem, as static/class variables are persisted across multiple test cases. - *

- * Solution: Maintain a Trie (slightly modified) data-structure to all the input sentences where each node of the Trie - * is a node containing a hash-map of child character and node and a TreeSet containing the sorted order of all the - * possible child sentences starting from the current node. Maintain a cursor node 'curr' to indicate the current node - * of input, if the input character is absent then simply mark curr as null indicating no further auto-complete terms possible. - * On the other hand if the input character is present then simply pick the top 3 elements from the TreeSet object of curr - * node. - * Finally, use a StringBuilder to accumulate all the input characters and when a end of sentence is '#' is encountered - * simply update the trie with new sentence and degree. + * + *

Operation: input('i') Output: ["i love you", "island","i love leetcode"] Explanation: There + * are four sentences that have prefix "i". Among them, "ironman" and "i love leetcode" have same + * hot degree. Since ' ' has ASCII code 32 and 'r' has ASCII code 114, "i love leetcode" should be + * in front of "ironman". Also we only need to output top 3 hot sentences, so "ironman" will be + * ignored. + * + *

Operation: input(' ') Output: ["i love you","i love leetcode"] Explanation: There are only two + * sentences that have prefix "i ". + * + *

Operation: input('a') Output: [] Explanation: There are no sentences that have prefix "i a". + * + *

Operation: input('#') Output: [] Explanation: The user finished the input, the sentence "i a" + * should be saved as a historical sentence in system. And the following input will be counted as a + * new search. + * + *

Note: The input sentence will always start with a letter and end with '#', and only one blank + * space will exist between two words. The number of complete sentences that to be searched won't + * exceed 100. The length of each sentence including those in the historical data won't exceed 100. + * Please use double-quote instead of single-quote when you write test cases even for a character + * input. Please remember to RESET your class variables declared in class AutocompleteSystem, as + * static/class variables are persisted across multiple test cases. + * + *

Solution: Maintain a Trie (slightly modified) data-structure to all the input sentences where + * each node of the Trie is a node containing a hash-map of child character and node and a TreeSet + * containing the sorted order of all the possible child sentences starting from the current node. + * Maintain a cursor node 'curr' to indicate the current node of input, if the input character is + * absent then simply mark curr as null indicating no further auto-complete terms possible. On the + * other hand if the input character is present then simply pick the top 3 elements from the TreeSet + * object of curr node. Finally, use a StringBuilder to accumulate all the input characters and when + * a end of sentence is '#' is encountered simply update the trie with new sentence and degree. */ public class AutocompleteSystem { - private Map hotTextMap; //Maintain a hash-map of sentences and degree - private Trie curr, trie, root; - private StringBuilder currSentence; //StringBuilder class to maintain current input sentence (until '#') + private Map hotTextMap; // Maintain a hash-map of sentences and degree + private Trie curr, trie, root; + private StringBuilder + currSentence; // StringBuilder class to maintain current input sentence (until '#') + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + String[] sentences = {"i love you", "island", "ironman", "i love leetcode"}; + int[] degree = {5, 3, 2, 2}; + AutocompleteSystem autocomplete = new AutocompleteSystem(sentences, degree); + List result = autocomplete.input('i'); + result.forEach(System.out::println); + result = autocomplete.input(' '); + result.forEach(System.out::println); + result = autocomplete.input('a'); + result.forEach(System.out::println); + result = autocomplete.input('#'); + result.forEach(System.out::println); + } + + /** + * Initialize the trie data-structure + * + * @param sentences array of sentences + * @param times degree + */ + public AutocompleteSystem(String[] sentences, int[] times) { + hotTextMap = new HashMap<>(); + trie = new Trie(); + for (int i = 0; i < sentences.length; i++) { + hotTextMap.put(sentences[i], times[i]); + trie.insert(sentences[i]); + trie.update(sentences[i]); + } + curr = trie; + root = trie; + currSentence = new StringBuilder(); + } + + /** + * Accept input and return hot-text for the current char + * + * @param c char + * @return List of top 3 hot-text + */ + public List input(char c) { + List result = new ArrayList<>(); + if (c == '#') { + String sentence = currSentence.toString(); + if (hotTextMap.containsKey(sentence)) { + // already a known sentence hence only update in necessary + hotTextMap.put(sentence, hotTextMap.get(sentence) + 1); + trie.update(sentence); + } else { + // insert a new sentence and update the degree + hotTextMap.put(sentence, 1); + trie.insert(sentence); + trie.update(sentence); + } + currSentence = new StringBuilder(); // reset StringBuilder + curr = root; // point to root of the trie + } else { + if (curr != null) { + if (curr.containsChild(c)) { + List hotText = curr.getSubtrie(c).getTop3HotText(); + hotText + .stream() + .forEach((x) -> result.add(currSentence.toString() + x)); // each node only returns + // the hot-text for the current and child nodes hence we have to attach the prefix string + curr = curr.getSubtrie(c); + } else { + curr = + null; // as soon as we encounter a empty node then set current to null indicating no + // further + // auto-complete terms are available + } + } + currSentence.append(c); + } + return result; + } + + /** Class HotText to store the text and degree */ + private class HotText { + private String text; + private int degree; + + HotText(String text, int degree) { + this.text = text; + this.degree = degree; + } + + private String getText() { + return text; + } + + private int getDegree() { + return degree; + } + } + + /** Class Trie */ + private class Trie { + private Map map = new HashMap<>(); + private TreeSet hotText = + new TreeSet<>( + (HotText o1, HotText o2) -> { + int cmp = Integer.compare(o2.getDegree(), o1.getDegree()); + return cmp == 0 ? o1.getText().compareTo(o2.getText()) : cmp; + }); /** - * Main method + * Get hot-text * - * @param args - * @throws Exception + * @return HotText */ - public static void main(String[] args) throws Exception { - String[] sentences = {"i love you", "island", "ironman", "i love leetcode"}; - int[] degree = {5, 3, 2, 2}; - AutocompleteSystem autocomplete = new AutocompleteSystem(sentences, degree); - List result = autocomplete.input('i'); - result.forEach(System.out::println); - result = autocomplete.input(' '); - result.forEach(System.out::println); - result = autocomplete.input('a'); - result.forEach(System.out::println); - result = autocomplete.input('#'); - result.forEach(System.out::println); + public TreeSet getHotText() { + return hotText; } /** - * Initialize the trie data-structure + * Return top 3 hottext * - * @param sentences array of sentences - * @param times degree + * @return hot text */ - public AutocompleteSystem(String[] sentences, int[] times) { - hotTextMap = new HashMap<>(); - trie = new Trie(); - for (int i = 0; i < sentences.length; i++) { - hotTextMap.put(sentences[i], times[i]); - trie.insert(sentences[i]); - trie.update(sentences[i]); + private List getTop3HotText() { + List hotText = new ArrayList<>(); + if (this.getHotText() != null) { + this.getHotText().stream().limit(3).forEach((x) -> hotText.add(x.getText())); + } + return hotText; + } + + /** Inserts a word into the trie. */ + private void insert(String word) { + if (word != null) { + add(0, word, word.length()); + } + } + + private void add(int i, String word, int length) { + if (i < length) { + char c = word.charAt(i); + Trie subTrie = map.get(c); + if (subTrie == null) { + subTrie = new Trie(); + map.put(c, subTrie); } - curr = trie; - root = trie; - currSentence = new StringBuilder(); + subTrie.add(i + 1, word, length); + } else map.put(null, new Trie()); // use null to indicate end of string } /** - * Accept input and return hot-text for the current char + * Update hottex and degree * - * @param c char - * @return List of top 3 hot-text + * @param word word or sentence */ - public List input(char c) { - List result = new ArrayList<>(); - if (c == '#') { - String sentence = currSentence.toString(); - if (hotTextMap.containsKey(sentence)) { - //already a known sentence hence only update in necessary - hotTextMap.put(sentence, hotTextMap.get(sentence) + 1); - trie.update(sentence); - } else { - //insert a new sentence and update the degree - hotTextMap.put(sentence, 1); - trie.insert(sentence); - trie.update(sentence); - } - currSentence = new StringBuilder(); //reset StringBuilder - curr = root; //point to root of the trie - } else { - if (curr != null) { - if (curr.containsChild(c)) { - List hotText = curr.getSubtrie(c).getTop3HotText(); - hotText.stream().forEach((x) -> result.add(currSentence.toString() + x)); //each node only returns - //the hot-text for the current and child nodes hence we have to attach the prefix string - curr = curr.getSubtrie(c); - } else { - curr = null; //as soon as we encounter a empty node then set current to null indicating no further - //auto-complete terms are available - } - } - currSentence.append(c); - } - return result; + private void update(String word) { + if (word != null) { + update(0, word, word.length()); + } } /** - * Class HotText to store the text and degree + * Update trie + * + * @param i curr position + * @param word sentence + * @param length length + * @return HotText */ - private class HotText { - private String text; - private int degree; - - HotText(String text, int degree) { - this.text = text; - this.degree = degree; - } - - private String getText() { - return text; - } - - private int getDegree() { - return degree; - } + private HotText update(int i, String word, int length) { + if (i < length) { + char c = word.charAt(i); + Trie subTrie = map.get(c); + HotText subTrieHotText = subTrie.update(i + 1, word, length); + HotText currHotText = + new HotText( + c + (subTrieHotText == null ? "" : subTrieHotText.getText()), hotTextMap.get(word)); + updateHotText(subTrie, currHotText); + return currHotText; + } + return null; } /** - * Class Trie + * Hot text update + * + * @param hotText hotText object */ - private class Trie { - private Map map = new HashMap<>(); - private TreeSet hotText = - new TreeSet<>((HotText o1, HotText o2) -> { - int cmp = Integer.compare(o2.getDegree(), o1.getDegree()); - return cmp == 0 ? o1.getText().compareTo(o2.getText()) : cmp; - }); - - /** - * Get hot-text - * - * @return HotText - */ - public TreeSet getHotText() { - return hotText; - } - - /** - * Return top 3 hottext - * - * @return hot text - */ - private List getTop3HotText() { - List hotText = new ArrayList<>(); - if (this.getHotText() != null) { - this.getHotText().stream().limit(3).forEach((x) -> hotText.add(x.getText())); - } - return hotText; - } - - /** - * Inserts a word into the trie. - */ - private void insert(String word) { - if (word != null) { - add(0, word, word.length()); - } - } - - private void add(int i, String word, int length) { - if (i < length) { - char c = word.charAt(i); - Trie subTrie = map.get(c); - if (subTrie == null) { - subTrie = new Trie(); - map.put(c, subTrie); - } - subTrie.add(i + 1, word, length); - } else map.put(null, new Trie()); //use null to indicate end of string - } - - /** - * Update hottex and degree - * - * @param word word or sentence - */ - private void update(String word) { - if (word != null) { - update(0, word, word.length()); - } - } - - /** - * Update trie - * - * @param i curr position - * @param word sentence - * @param length length - * @return HotText - */ - private HotText update(int i, String word, int length) { - if (i < length) { - char c = word.charAt(i); - Trie subTrie = map.get(c); - HotText subTrieHotText = subTrie.update(i + 1, word, length); - HotText currHotText = new HotText(c + (subTrieHotText == null ? "" : - subTrieHotText.getText()), hotTextMap.get(word)); - updateHotText(subTrie, currHotText); - return currHotText; - } - return null; - } - - /** - * Hot text update - * - * @param hotText hotText object - */ - private void updateHotText(Trie trie, HotText hotText) { - trie.getHotText().remove(new HotText(hotText.getText(), hotText.getDegree() - 1)); //remove already - // contained hot-text and add new - trie.getHotText().add(hotText); - } + private void updateHotText(Trie trie, HotText hotText) { + trie.getHotText() + .remove(new HotText(hotText.getText(), hotText.getDegree() - 1)); // remove already + // contained hot-text and add new + trie.getHotText().add(hotText); + } - /** - * Contains child - * - * @param c char - * @return true if it contains child, false otherwise - */ - private boolean containsChild(char c) { - return this.map.containsKey(c); - } + /** + * Contains child + * + * @param c char + * @return true if it contains child, false otherwise + */ + private boolean containsChild(char c) { + return this.map.containsKey(c); + } - /** - * Return child tree - * - * @param c char - * @return child subTrie - */ - private Trie getSubtrie(char c) { - return this.map.get(c); - } + /** + * Return child tree + * + * @param c char + * @return child subTrie + */ + private Trie getSubtrie(char c) { + return this.map.get(c); } + } } diff --git a/problems/src/design/BSTIterator.java b/problems/src/design/BSTIterator.java index 0955e621..743eae61 100644 --- a/problems/src/design/BSTIterator.java +++ b/problems/src/design/BSTIterator.java @@ -3,89 +3,85 @@ import java.util.Stack; /** - * Created by gouthamvidyapradhan on 13/08/2017. - * Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST. - *

- * Calling next() will return the next smallest number in the BST. - *

- * Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree. - *

- * Solution: The below solution works in average O(1) time and worst case O(h) time using O(h) memory. - * Use a stack to keep track of min value node. + * Created by gouthamvidyapradhan on 13/08/2017. Implement an iterator over a binary search tree + * (BST). Your iterator will be initialized with the root node of a BST. + * + *

Calling next() will return the next smallest number in the BST. + * + *

Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is + * the height of the tree. + * + *

Solution: The below solution works in average O(1) time and worst case O(h) time using O(h) + * memory. Use a stack to keep track of min value node. */ public class BSTIterator { - private Stack stack; + private Stack stack; - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - public static void main(String[] args) throws Exception { - TreeNode root = new TreeNode(10); - root.left = new TreeNode(5); - root.left.left = new TreeNode(4); - root.left.right = new TreeNode(8); - root.left.left.left = new TreeNode(1); - root.left.right.left = new TreeNode(7); - root.right = new TreeNode(12); - root.right.left = new TreeNode(11); - root.right.right = new TreeNode(15); - BSTIterator ite = new BSTIterator(root); - System.out.println("Hasnext: " + ite.hasNext()); - System.out.println("next: " + ite.next()); - System.out.println("next: " + ite.next()); - System.out.println("next: " + ite.next()); - System.out.println("next: " + ite.next()); - System.out.println("next: " + ite.next()); - System.out.println("next: " + ite.next()); - System.out.println("next: " + ite.next()); - System.out.println("next: " + ite.next()); - System.out.println("next: " + ite.next()); - System.out.println("Hasnext: " + ite.hasNext()); - } + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(10); + root.left = new TreeNode(5); + root.left.left = new TreeNode(4); + root.left.right = new TreeNode(8); + root.left.left.left = new TreeNode(1); + root.left.right.left = new TreeNode(7); + root.right = new TreeNode(12); + root.right.left = new TreeNode(11); + root.right.right = new TreeNode(15); + BSTIterator ite = new BSTIterator(root); + System.out.println("Hasnext: " + ite.hasNext()); + System.out.println("next: " + ite.next()); + System.out.println("next: " + ite.next()); + System.out.println("next: " + ite.next()); + System.out.println("next: " + ite.next()); + System.out.println("next: " + ite.next()); + System.out.println("next: " + ite.next()); + System.out.println("next: " + ite.next()); + System.out.println("next: " + ite.next()); + System.out.println("next: " + ite.next()); + System.out.println("Hasnext: " + ite.hasNext()); + } - public BSTIterator(TreeNode root) { - stack = new Stack<>(); - fillStack(root); - } + public BSTIterator(TreeNode root) { + stack = new Stack<>(); + fillStack(root); + } - /** - * @return whether we have a next smallest number - */ - public boolean hasNext() { - return !stack.isEmpty(); - } + /** @return whether we have a next smallest number */ + public boolean hasNext() { + return !stack.isEmpty(); + } - /** - * @return the next smallest number - */ - public int next() { - if (!stack.isEmpty()) { - TreeNode top = stack.pop(); - fillStack(top.right); - return top.val; - } - return -1; + /** @return the next smallest number */ + public int next() { + if (!stack.isEmpty()) { + TreeNode top = stack.pop(); + fillStack(top.right); + return top.val; } + return -1; + } - /** - * Fill stack with min values - * - * @param node curr node to begin with - */ - private void fillStack(TreeNode node) { - TreeNode ite = node; - while (ite != null) { - stack.push(ite); - ite = ite.left; - } + /** + * Fill stack with min values + * + * @param node curr node to begin with + */ + private void fillStack(TreeNode node) { + TreeNode ite = node; + while (ite != null) { + stack.push(ite); + ite = ite.left; } - + } } diff --git a/problems/src/design/CopyListWithRandomPointer.java b/problems/src/design/CopyListWithRandomPointer.java index ec83f894..dbcb225c 100644 --- a/problems/src/design/CopyListWithRandomPointer.java +++ b/problems/src/design/CopyListWithRandomPointer.java @@ -1,77 +1,76 @@ package design; /** - * Created by gouthamvidyapradhan on 11/03/2017. - * A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. - *

- * Return a deep copy of the list. + * Created by gouthamvidyapradhan on 11/03/2017. A linked list is given such that each node contains + * an additional random pointer which could point to any node in the list or null. + * + *

Return a deep copy of the list. */ public class CopyListWithRandomPointer { - static class RandomListNode { - int label; - RandomListNode next, random; + static class RandomListNode { + int label; + RandomListNode next, random; - RandomListNode(int x) { - this.label = x; - } + RandomListNode(int x) { + this.label = x; } + } - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - RandomListNode one = new RandomListNode(1); - one.next = null; - one.random = one; - /*RandomListNode two = new RandomListNode(2); - RandomListNode three = new RandomListNode(3); - RandomListNode four = new RandomListNode(4); - RandomListNode five = new RandomListNode(5); - one.next = two; - two.next = three; - three.next = four; - four.next = five; - one.random = three; - two.random = five; - three.random = null; - four.random = two; - five.random = four;*/ - RandomListNode result = new CopyListWithRandomPointer().copyRandomList(one); - System.out.println(); - } - - private RandomListNode copyRandomList(RandomListNode head) { - if (head == null) return null; - RandomListNode ite = head, next; - while (ite != null) { - next = ite.next; - RandomListNode node = new RandomListNode(ite.label); - ite.next = node; - node.next = next; - ite = next; - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + RandomListNode one = new RandomListNode(1); + one.next = null; + one.random = one; + /*RandomListNode two = new RandomListNode(2); + RandomListNode three = new RandomListNode(3); + RandomListNode four = new RandomListNode(4); + RandomListNode five = new RandomListNode(5); + one.next = two; + two.next = three; + three.next = four; + four.next = five; + one.random = three; + two.random = five; + three.random = null; + four.random = two; + five.random = four;*/ + RandomListNode result = new CopyListWithRandomPointer().copyRandomList(one); + System.out.println(); + } - ite = head; - while (ite != null) { - if (ite.random != null) - ite.next.random = ite.random.next; - ite = ite.next.next; - } + private RandomListNode copyRandomList(RandomListNode head) { + if (head == null) return null; + RandomListNode ite = head, next; + while (ite != null) { + next = ite.next; + RandomListNode node = new RandomListNode(ite.label); + ite.next = node; + node.next = next; + ite = next; + } - ite = head; - RandomListNode copyIte = ite.next, copyHead = ite.next; - while (copyIte.next != null) { - ite.next = copyIte.next; - copyIte.next = ite.next.next; - copyIte = copyIte.next; - ite = ite.next; - } - ite.next = null; + ite = head; + while (ite != null) { + if (ite.random != null) ite.next.random = ite.random.next; + ite = ite.next.next; + } - return copyHead; + ite = head; + RandomListNode copyIte = ite.next, copyHead = ite.next; + while (copyIte.next != null) { + ite.next = copyIte.next; + copyIte.next = ite.next.next; + copyIte = copyIte.next; + ite = ite.next; } + ite.next = null; + + return copyHead; + } } diff --git a/problems/src/design/EncodeAndDecodeTinyURL.java b/problems/src/design/EncodeAndDecodeTinyURL.java index 09eae92a..94ca34f8 100644 --- a/problems/src/design/EncodeAndDecodeTinyURL.java +++ b/problems/src/design/EncodeAndDecodeTinyURL.java @@ -4,38 +4,40 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 11/04/2017. - * TinyURL is a URL shortening service where you enter a URL such as https://leetcode.com/problems/design-tinyurl and it returns a short URL such as http://tinyurl.com/4e9iAk. - *

- * Design the encode and decode methods for the TinyURL service. There is no restriction on how your encode/decode algorithm should work. You just need to ensure that a URL can be encoded to a tiny URL and the tiny URL can be decoded to the original URL. + * Created by gouthamvidyapradhan on 11/04/2017. TinyURL is a URL shortening service where you enter + * a URL such as https://leetcode.com/problems/design-tinyurl and it returns a short URL such as + * http://tinyurl.com/4e9iAk. + * + *

Design the encode and decode methods for the TinyURL service. There is no restriction on how + * your encode/decode algorithm should work. You just need to ensure that a URL can be encoded to a + * tiny URL and the tiny URL can be decoded to the original URL. */ public class EncodeAndDecodeTinyURL { - private List list = new ArrayList<>(); - private static final String URL = "http://tinyurl.com/"; + private List list = new ArrayList<>(); + private static final String URL = "http://tinyurl.com/"; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - EncodeAndDecodeTinyURL encoder = new EncodeAndDecodeTinyURL(); - String shorterUrl = encoder.encode("https://leetcode.com/problems/design-tinyurl"); - System.out.println(encoder.decode(shorterUrl)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + EncodeAndDecodeTinyURL encoder = new EncodeAndDecodeTinyURL(); + String shorterUrl = encoder.encode("https://leetcode.com/problems/design-tinyurl"); + System.out.println(encoder.decode(shorterUrl)); + } - // Encodes a URL to a shortened URL. - public String encode(String longUrl) { - list.add(longUrl); - return URL.concat(String.valueOf(list.size())); - } - - // Decodes a shortened URL to its original URL. - public String decode(String shortUrl) { - String[] parts = shortUrl.split("http://tinyurl.com/"); - String code = parts[1]; - return list.get(Integer.parseInt(code) - 1); - } + // Encodes a URL to a shortened URL. + public String encode(String longUrl) { + list.add(longUrl); + return URL.concat(String.valueOf(list.size())); + } + // Decodes a shortened URL to its original URL. + public String decode(String shortUrl) { + String[] parts = shortUrl.split("http://tinyurl.com/"); + String code = parts[1]; + return list.get(Integer.parseInt(code) - 1); + } } diff --git a/problems/src/design/Excel.java b/problems/src/design/Excel.java index 30d6fc3c..c00bd33a 100644 --- a/problems/src/design/Excel.java +++ b/problems/src/design/Excel.java @@ -4,225 +4,211 @@ /** * Created by gouthamvidyapradhan on 16/09/2017. - *

- * Your task is to design the basic function of Excel and implement the function of sum formula. + * + *

Your task is to design the basic function of Excel and implement the function of sum formula. * Specifically, you need to implement the following functions: - *

- * Excel(int H, char W): This is the constructor. - * The inputs represents the height and width of the Excel form. H is a positive integer, range from 1 to 26. - * It represents the height. W is a character range from 'A' to 'Z'. It represents that the width is the number of - * characters from 'A' to W. The Excel form content is represented by a height * width 2D integer array C, it should be - * initialized to zero. You should assume that the first row of C starts from 1, and the first column of C starts from - * 'A'. - *

- *

- * void Set(int row, char column, int val): Change the value at C(row, column) to be val. - *

- *

- * int Get(int row, char column): Return the value at C(row, column). - *

- *

- * int Sum(int row, char column, List of Strings : numbers): This function calculate and set the value at C(row, - * column), where the value should be the sum of cells represented by numbers. This function return the sum result at - * C(row, column). This sum formula should exist until this cell is overlapped by another value or another sum formula. - *

- * numbers is a list of strings that each string represent a cell or a range of cells. If the string represent a - * single cell, then it has the following format : ColRow. For example, "F7" represents the cell at (7, F). - *

- * If the string represent a range of cells, then it has the following format : ColRow1:ColRow2. The range will always - * be a rectangle, and ColRow1 represent the position of the top-left cell, and ColRow2 represents the position of the - * bottom-right cell. - *

- *

- * Example 1: - * Excel(3,"C"); - * // construct a 3*3 2D array with all zero. - * // A B C - * // 1 0 0 0 - * // 2 0 0 0 - * // 3 0 0 0 - *

- * Set(1, "A", 2); - * // set C(1,"A") to be 2. - * // A B C - * // 1 2 0 0 - * // 2 0 0 0 - * // 3 0 0 0 - *

- * Sum(3, "C", ["A1", "A1:B2"]); - * // set C(3,"C") to be the sum of value at C(1,"A") and the values sum of the rectangle range whose top-left cell is - * C (1,"A") and bottom-right cell is C(2,"B"). Return 4. - * // A B C - * // 1 2 0 0 - * // 2 0 0 0 - * // 3 0 0 4 - *

- * Set(2, "B", 2); - * // set C(2,"B") to be 2. Note C(3, "C") should also be changed. - * // A B C - * // 1 2 0 0 - * // 2 0 2 0 - * // 3 0 0 6 - * Note: - * You could assume that there won't be any circular sum reference. For example, A1 = sum(B1) and B1 = sum(A1). - * The test cases are using double-quotes to represent a character. - * Please remember to RESET your class variables declared in class Excel, as static/class variables are persisted - * across multiple test cases. - *

- * Solution: Build a graph and for each cell keep track of forward and backward links. When a cell is updated with a - * new value broadcast the new value to all the forward links and remove all the forward links pointing to this - * particular cell. + * + *

Excel(int H, char W): This is the constructor. The inputs represents the height and width of + * the Excel form. H is a positive integer, range from 1 to 26. It represents the height. W is a + * character range from 'A' to 'Z'. It represents that the width is the number of characters from + * 'A' to W. The Excel form content is represented by a height * width 2D integer array C, it should + * be initialized to zero. You should assume that the first row of C starts from 1, and the first + * column of C starts from 'A'. + * + *

+ * + *

void Set(int row, char column, int val): Change the value at C(row, column) to be val. + * + *

+ * + *

int Get(int row, char column): Return the value at C(row, column). + * + *

+ * + *

int Sum(int row, char column, List of Strings : numbers): This function calculate and set the + * value at C(row, column), where the value should be the sum of cells represented by numbers. This + * function return the sum result at C(row, column). This sum formula should exist until this cell + * is overlapped by another value or another sum formula. + * + *

numbers is a list of strings that each string represent a cell or a range of cells. If the + * string represent a single cell, then it has the following format : ColRow. For example, "F7" + * represents the cell at (7, F). + * + *

If the string represent a range of cells, then it has the following format : ColRow1:ColRow2. + * The range will always be a rectangle, and ColRow1 represent the position of the top-left cell, + * and ColRow2 represents the position of the bottom-right cell. + * + *

+ * + *

Example 1: Excel(3,"C"); // construct a 3*3 2D array with all zero. // A B C // 1 0 0 0 // 2 0 + * 0 0 // 3 0 0 0 + * + *

Set(1, "A", 2); // set C(1,"A") to be 2. // A B C // 1 2 0 0 // 2 0 0 0 // 3 0 0 0 + * + *

Sum(3, "C", ["A1", "A1:B2"]); // set C(3,"C") to be the sum of value at C(1,"A") and the + * values sum of the rectangle range whose top-left cell is C (1,"A") and bottom-right cell is + * C(2,"B"). Return 4. // A B C // 1 2 0 0 // 2 0 0 0 // 3 0 0 4 + * + *

Set(2, "B", 2); // set C(2,"B") to be 2. Note C(3, "C") should also be changed. // A B C // 1 + * 2 0 0 // 2 0 2 0 // 3 0 0 6 Note: You could assume that there won't be any circular sum + * reference. For example, A1 = sum(B1) and B1 = sum(A1). The test cases are using double-quotes to + * represent a character. Please remember to RESET your class variables declared in class Excel, as + * static/class variables are persisted across multiple test cases. + * + *

Solution: Build a graph and for each cell keep track of forward and backward links. When a + * cell is updated with a new value broadcast the new value to all the forward links and remove all + * the forward links pointing to this particular cell. */ public class Excel { - private Map> fwdEdges; //Forward links from cell - private Map> backEdge; //All backward links from cell - private Map count; //Keep track of number of times the cell is linked - private int[][] grid; //excel grid + private Map> fwdEdges; // Forward links from cell + private Map> backEdge; // All backward links from cell + private Map count; // Keep track of number of times the cell is linked + private int[][] grid; // excel grid - /** - * Initialize datastructure - * - * @param H row - * @param W column - */ - public Excel(int H, char W) { - grid = new int[H][(Character.toUpperCase(W) - 'A') + 1]; - fwdEdges = new HashMap<>(); - backEdge = new HashMap<>(); - count = new HashMap<>(); - } + /** + * Initialize datastructure + * + * @param H row + * @param W column + */ + public Excel(int H, char W) { + grid = new int[H][(Character.toUpperCase(W) - 'A') + 1]; + fwdEdges = new HashMap<>(); + backEdge = new HashMap<>(); + count = new HashMap<>(); + } - public static void main(String[] args) throws Exception { - Excel excel = new Excel(26, 'Z'); - excel.set(1, 'A', 1); - excel.set(1, 'I', 1); - String[] arr = {"A1:D6", "A1:G3", "A1:C12"}; - String[] arr1 = {"A1:D7", "D1:F10", "D3:I8", "I1:I9"}; - System.out.println(excel.get(1, 'A')); - System.out.println(excel.sum(7, 'D', arr)); - System.out.println(excel.get(1, 'A')); - System.out.println(excel.sum(10, 'G', arr1)); - System.out.println(excel.get(1, 'A')); - } + public static void main(String[] args) throws Exception { + Excel excel = new Excel(26, 'Z'); + excel.set(1, 'A', 1); + excel.set(1, 'I', 1); + String[] arr = {"A1:D6", "A1:G3", "A1:C12"}; + String[] arr1 = {"A1:D7", "D1:F10", "D3:I8", "I1:I9"}; + System.out.println(excel.get(1, 'A')); + System.out.println(excel.sum(7, 'D', arr)); + System.out.println(excel.get(1, 'A')); + System.out.println(excel.sum(10, 'G', arr1)); + System.out.println(excel.get(1, 'A')); + } - /** - * Set value to the grid - * - * @param r row - * @param c column - * @param v value - */ - public void set(int r, char c, int v) { - setValue(r, c, v); - removeForwardEdges(String.valueOf(c) + r); - } + /** + * Set value to the grid + * + * @param r row + * @param c column + * @param v value + */ + public void set(int r, char c, int v) { + setValue(r, c, v); + removeForwardEdges(String.valueOf(c) + r); + } - private void setValue(int r, char c, int v) { - int curr = grid[r - 1][Character.toUpperCase(c) - 'A']; - grid[r - 1][Character.toUpperCase(c) - 'A'] = v; - broadcast(v - curr, String.valueOf(c) + r); - } + private void setValue(int r, char c, int v) { + int curr = grid[r - 1][Character.toUpperCase(c) - 'A']; + grid[r - 1][Character.toUpperCase(c) - 'A'] = v; + broadcast(v - curr, String.valueOf(c) + r); + } - /** - * Remove all the links - * - * @param node node - */ - private void removeForwardEdges(String node) { - List parents = backEdge.get(node); - if (parents != null) { - for (String p : parents) { - Set children = fwdEdges.get(p); - if (children != null) { - count.remove(p + ":" + node); - children.remove(node); - } - } - } - } - - /** - * Broadcast to all the links - * - * @param v current node - * @param node node - */ - private void broadcast(int v, String node) { - Set children = fwdEdges.get(node); + /** + * Remove all the links + * + * @param node node + */ + private void removeForwardEdges(String node) { + List parents = backEdge.get(node); + if (parents != null) { + for (String p : parents) { + Set children = fwdEdges.get(p); if (children != null) { - for (String c : children) { - int order = count.get(node + ":" + c); - grid[Integer.parseInt(c.substring(1)) - 1][c.charAt(0) - 'A'] += (v * order); - broadcast(v, c); - } + count.remove(p + ":" + node); + children.remove(node); } + } } + } - public int get(int r, char c) { - return grid[r - 1][c - 'A']; + /** + * Broadcast to all the links + * + * @param v current node + * @param node node + */ + private void broadcast(int v, String node) { + Set children = fwdEdges.get(node); + if (children != null) { + for (String c : children) { + int order = count.get(node + ":" + c); + grid[Integer.parseInt(c.substring(1)) - 1][c.charAt(0) - 'A'] += (v * order); + broadcast(v, c); + } } + } - /** - * Sum range of cells - * - * @param r row - * @param c column - * @param strs Strings - * @return integer sum - */ - public int sum(int r, char c, String[] strs) { - int sum = 0; - //Remove all the forward and backward edges or links - removeForwardEdges(c + String.valueOf(r)); - backEdge.remove(c + String.valueOf(r)); - Set nodes = new HashSet<>(); - for (String s : strs) { - String[] range = s.split(":"); - if (range.length > 1) { - int startRow = Integer.parseInt(range[0].substring(1)) - 1; - int startColumn = range[0].charAt(0) - 'A'; + public int get(int r, char c) { + return grid[r - 1][c - 'A']; + } - int endRow = Integer.parseInt(range[1].substring(1)) - 1; - int endColumn = range[1].charAt(0) - 'A'; + /** + * Sum range of cells + * + * @param r row + * @param c column + * @param strs Strings + * @return integer sum + */ + public int sum(int r, char c, String[] strs) { + int sum = 0; + // Remove all the forward and backward edges or links + removeForwardEdges(c + String.valueOf(r)); + backEdge.remove(c + String.valueOf(r)); + Set nodes = new HashSet<>(); + for (String s : strs) { + String[] range = s.split(":"); + if (range.length > 1) { + int startRow = Integer.parseInt(range[0].substring(1)) - 1; + int startColumn = range[0].charAt(0) - 'A'; - for (int i = startRow; i <= endRow; i++) { - for (int j = startColumn; j <= endColumn; j++) { - char newC = (char) ('A' + j); - nodes.add(newC + String.valueOf(i + 1)); - sum += grid[i][j]; - String key = newC + String.valueOf(i + 1) + ":" + (c + String.valueOf(r)); - if (count.putIfAbsent(key, 1) != null) { - count.put(key, (count.get(key) + 1)); - } - } - } - } else { - sum += grid[Integer.parseInt(range[0].substring(1)) - 1][range[0].charAt(0) - 'A']; - nodes.add(range[0]); - String key = range[0] + ":" + (c + String.valueOf(r)); - if (count.putIfAbsent(key, 1) != null) { - count.put(key, count.get(key) + 1); - } - } - } - //set value - setValue(r, c, sum); + int endRow = Integer.parseInt(range[1].substring(1)) - 1; + int endColumn = range[1].charAt(0) - 'A'; - //make new forward-edges - for (String n : nodes) { - Set children = fwdEdges.get(n); - if (children == null) { - children = new HashSet<>(); - fwdEdges.put(n, children); + for (int i = startRow; i <= endRow; i++) { + for (int j = startColumn; j <= endColumn; j++) { + char newC = (char) ('A' + j); + nodes.add(newC + String.valueOf(i + 1)); + sum += grid[i][j]; + String key = newC + String.valueOf(i + 1) + ":" + (c + String.valueOf(r)); + if (count.putIfAbsent(key, 1) != null) { + count.put(key, (count.get(key) + 1)); } - children.add(c + String.valueOf(r)); + } } + } else { + sum += grid[Integer.parseInt(range[0].substring(1)) - 1][range[0].charAt(0) - 'A']; + nodes.add(range[0]); + String key = range[0] + ":" + (c + String.valueOf(r)); + if (count.putIfAbsent(key, 1) != null) { + count.put(key, count.get(key) + 1); + } + } + } + // set value + setValue(r, c, sum); - //make new back-edges - List backEdges = new ArrayList<>(); - backEdges.addAll(nodes); - backEdge.put(c + String.valueOf(r), backEdges); - return sum; + // make new forward-edges + for (String n : nodes) { + Set children = fwdEdges.get(n); + if (children == null) { + children = new HashSet<>(); + fwdEdges.put(n, children); + } + children.add(c + String.valueOf(r)); } + + // make new back-edges + List backEdges = new ArrayList<>(); + backEdges.addAll(nodes); + backEdge.put(c + String.valueOf(r), backEdges); + return sum; + } } diff --git a/problems/src/design/LFUCache.java b/problems/src/design/LFUCache.java index 7a9fd05b..371054bf 100644 --- a/problems/src/design/LFUCache.java +++ b/problems/src/design/LFUCache.java @@ -5,230 +5,224 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 20/03/2017. - * Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the following operations: get and put. - *

- * get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. - * put(key, value) - Set or insert the value if the key is not already present. When the cache reaches its capacity, it should invalidate the least frequently used item before inserting a new item. For the purpose of this problem, when there is a tie (i.e., two or more keys that have the same frequency), the least recently used key would be evicted. - *

- * Follow up: - * Could you do both operations in O(1) time complexity? - *

- * Example: - *

- * LFUCache cache = new LFUCache( 2 /* capacity - */ /*) - - cache.put(1, 1); - cache.put(2, 2); - cache.get(1); // returns 1 - cache.put(3, 3); // evicts key 2 - cache.get(2); // returns -1 (not found) - cache.get(3); // returns 3. - cache.put(4, 4); // evicts key 1. - cache.get(1); // returns -1 (not found) - cache.get(3); // returns 3 - cache.get(4); // returns 4 + * Created by gouthamvidyapradhan on 20/03/2017. Design and implement a data structure for Least + * Frequently Used (LFU) cache. It should support the following operations: get and put. + * + *

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, + * otherwise return -1. put(key, value) - Set or insert the value if the key is not already present. + * When the cache reaches its capacity, it should invalidate the least frequently used item before + * inserting a new item. For the purpose of this problem, when there is a tie (i.e., two or more + * keys that have the same frequency), the least recently used key would be evicted. + * + *

Follow up: Could you do both operations in O(1) time complexity? + * + *

Example: + * + *

LFUCache cache = new LFUCache( 2 /* capacity */ +/*) + + cache.put(1, 1); + cache.put(2, 2); + cache.get(1); // returns 1 + cache.put(3, 3); // evicts key 2 + cache.get(2); // returns -1 (not found) + cache.get(3); // returns 3. + cache.put(4, 4); // evicts key 1. + cache.get(1); // returns -1 (not found) + cache.get(3); // returns 3 + cache.get(4); // returns 4 +*/ public class LFUCache { - private class Node { - int frequency; - Node prev; - Node next; - LinkedHashSet hashSet; - - Node(int frequency, - LinkedHashSet hashSet) { - this.frequency = frequency; - this.hashSet = hashSet; - prev = null; - next = null; - } + private class Node { + int frequency; + Node prev; + Node next; + LinkedHashSet hashSet; + + Node(int frequency, LinkedHashSet hashSet) { + this.frequency = frequency; + this.hashSet = hashSet; + prev = null; + next = null; } - - - private int capacity; - private int currentSize; - private Map cache; - private Map fMap; //frequency - private Node head; - - /** - * Main method - * - * @param args - */ - public static void main(String[] args) { - LFUCache cache1 = new LFUCache(2); - cache1.put(1, 1); - cache1.put(2, 2); - System.out.println(cache1.get(1)); - cache1.put(3, 3); - System.out.println(cache1.get(2)); - //System.out.println(cache1.get(3)); - cache1.put(4, 4); - System.out.println(cache1.get(1)); - System.out.println(cache1.get(3)); - System.out.println(cache1.get(4)); - System.out.println(cache1.get(1)); - System.out.println(cache1.get(4)); - System.out.println(cache1.get(2)); - cache1.put(4, 4); - cache1.put(5, 4); - cache1.put(1, 9); - cache1.put(7, 1); - cache1.put(4, 2); - System.out.println(cache1.get(1)); - System.out.println(cache1.get(4)); - System.out.println(cache1.get(7)); - //System.out.println(cache1.get(3)); - //System.out.println(cache1.get(4)); + } + + private int capacity; + private int currentSize; + private Map cache; + private Map fMap; // frequency + private Node head; + + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + LFUCache cache1 = new LFUCache(2); + cache1.put(1, 1); + cache1.put(2, 2); + System.out.println(cache1.get(1)); + cache1.put(3, 3); + System.out.println(cache1.get(2)); + // System.out.println(cache1.get(3)); + cache1.put(4, 4); + System.out.println(cache1.get(1)); + System.out.println(cache1.get(3)); + System.out.println(cache1.get(4)); + System.out.println(cache1.get(1)); + System.out.println(cache1.get(4)); + System.out.println(cache1.get(2)); + cache1.put(4, 4); + cache1.put(5, 4); + cache1.put(1, 9); + cache1.put(7, 1); + cache1.put(4, 2); + System.out.println(cache1.get(1)); + System.out.println(cache1.get(4)); + System.out.println(cache1.get(7)); + // System.out.println(cache1.get(3)); + // System.out.println(cache1.get(4)); + } + + public LFUCache(int capacity) { + currentSize = 0; + this.capacity = capacity; + cache = new HashMap<>(); + fMap = new HashMap<>(); + } + + /** + * Remove node and delink + * + * @param node Node + */ + private void popNode(Node node) { + if (node.prev != null && node.next != null) { + node.prev.next = node.next; + node.next.prev = node.prev; + } else if (node.prev == null) { + node.next.prev = null; + node.next = null; + } else { + node.prev.next = null; + node.prev = null; } - - public LFUCache(int capacity) { - currentSize = 0; - this.capacity = capacity; - cache = new HashMap<>(); - fMap = new HashMap<>(); + } + + /** + * Get value + * + * @param key key + * @return value + */ + public int get(int key) { + if (!cache.containsKey(key)) return -1; + fMap.put(key, update(key)); + return cache.get(key); + } + + /** + * Update fMap + * + * @param key key + */ + private Node update(int key) { + Node node = fMap.get(key); + node.hashSet.remove(key); + Node newNode; + if (node.next == null) { + newNode = makeNewNode(key, node.frequency + 1); + node.next = newNode; + newNode.prev = node; + } else if (node.next.frequency == node.frequency + 1) { + node.next.hashSet.add(key); + newNode = node.next; + } else { + newNode = makeNewNode(key, node.frequency + 1); + node.next.prev = newNode; + newNode.next = node.next; + newNode.prev = node; + node.next = newNode; } - - /** - * Remove node and delink - * - * @param node Node - */ - private void popNode(Node node) { - if (node.prev != null && node.next != null) { - node.prev.next = node.next; - node.next.prev = node.prev; - } else if (node.prev == null) { - node.next.prev = null; - node.next = null; - } else { - node.prev.next = null; - node.prev = null; - } + if (node.equals(head)) incrementHead(); + else if (node.hashSet.isEmpty()) popNode(node); + return newNode; + } + + /** + * Make new node + * + * @param key key + * @param frequency frequency + * @return Node + */ + private Node makeNewNode(int key, int frequency) { + LinkedHashSet linkedHashSet = new LinkedHashSet<>(); + linkedHashSet.add(key); + return new Node(frequency, linkedHashSet); + } + + /** + * Add new head + * + * @param key key + * @param frequency frequency + */ + private Node addHead(int key, int frequency) { + if (head == null) head = makeNewNode(key, frequency); + else if (head.frequency > frequency) { + Node node = makeNewNode(key, frequency); + node.next = head; + head.prev = node; + head = node; + } else head.hashSet.add(key); + return head; + } + + /** Increment head */ + private void incrementHead() { + if (head.hashSet.isEmpty()) { + head = head.next; + if (head != null) { + head.prev.next = null; + head.prev = null; + } } - - /** - * Get value - * - * @param key key - * @return value - */ - public int get(int key) { - if (!cache.containsKey(key)) return -1; - fMap.put(key, update(key)); - return cache.get(key); - } - - /** - * Update fMap - * - * @param key key - */ - private Node update(int key) { - Node node = fMap.get(key); - node.hashSet.remove(key); - Node newNode; - if (node.next == null) { - newNode = makeNewNode(key, node.frequency + 1); - node.next = newNode; - newNode.prev = node; - } else if (node.next.frequency == node.frequency + 1) { - node.next.hashSet.add(key); - newNode = node.next; + } + + /** + * Put key value pair + * + * @param key key + * @param value value + */ + public void put(int key, int value) { + if (capacity != 0) { + if (cache.containsKey(key)) { + fMap.put(key, update(key)); // update existing + cache.put(key, value); + } else { + if (currentSize == capacity) { + evict(); + cache.put(key, value); + fMap.put(key, addHead(key, 1)); } else { - newNode = makeNewNode(key, node.frequency + 1); - node.next.prev = newNode; - newNode.next = node.next; - newNode.prev = node; - node.next = newNode; + fMap.put(key, addHead(key, 1)); // add new head + cache.put(key, value); + currentSize++; } - if (node.equals(head)) - incrementHead(); - else if (node.hashSet.isEmpty()) - popNode(node); - return newNode; - } - - /** - * Make new node - * - * @param key key - * @param frequency frequency - * @return Node - */ - private Node makeNewNode(int key, int frequency) { - LinkedHashSet linkedHashSet = new LinkedHashSet<>(); - linkedHashSet.add(key); - return new Node(frequency, linkedHashSet); - } - - /** - * Add new head - * - * @param key key - * @param frequency frequency - */ - private Node addHead(int key, int frequency) { - if (head == null) - head = makeNewNode(key, frequency); - else if (head.frequency > frequency) { - Node node = makeNewNode(key, frequency); - node.next = head; - head.prev = node; - head = node; - } else head.hashSet.add(key); - return head; - } - - /** - * Increment head - */ - private void incrementHead() { - if (head.hashSet.isEmpty()) { - head = head.next; - if (head != null) { - head.prev.next = null; - head.prev = null; - } - } - } - - /** - * Put key value pair - * - * @param key key - * @param value value - */ - public void put(int key, int value) { - if (capacity != 0) { - if (cache.containsKey(key)) { - fMap.put(key, update(key)); //update existing - cache.put(key, value); - } else { - if (currentSize == capacity) { - evict(); - cache.put(key, value); - fMap.put(key, addHead(key, 1)); - } else { - fMap.put(key, addHead(key, 1)); //add new head - cache.put(key, value); - currentSize++; - } - } - } - } - - /** - * Evict the node with least frequency - */ - private void evict() { - int key = head.hashSet.iterator().next(); - head.hashSet.remove(key); - cache.remove(key); - fMap.remove(key); - incrementHead(); + } } + } + + /** Evict the node with least frequency */ + private void evict() { + int key = head.hashSet.iterator().next(); + head.hashSet.remove(key); + cache.remove(key); + fMap.remove(key); + incrementHead(); + } } diff --git a/problems/src/design/LRUCache.java b/problems/src/design/LRUCache.java index 2608859f..2d12a86e 100644 --- a/problems/src/design/LRUCache.java +++ b/problems/src/design/LRUCache.java @@ -4,148 +4,150 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 18/03/2017. - * Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put. - *

- * get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. - * put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item. - *

- * Follow up: - * Could you do both operations in O(1) time complexity? - *

- * Example: - *

- * LRUCache cache = new LRUCache( 2 /* capacity - */ /*); + * Created by gouthamvidyapradhan on 18/03/2017. Design and implement a data structure for Least + * Recently Used (LRU) cache. It should support the following operations: get and put. + * + *

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, + * otherwise return -1. put(key, value) - Set or insert the value if the key is not already present. + * When the cache reached its capacity, it should invalidate the least recently used item before + * inserting a new item. + * + *

Follow up: Could you do both operations in O(1) time complexity? + * + *

Example: + * + *

LRUCache cache = new LRUCache( 2 /* capacity + */ +/*); - cache.put(1, 1); - cache.put(2, 2); - cache.get(1); // returns 1 - cache.put(3, 3); // evicts key 2 - cache.get(2); // returns -1 (not found) - cache.put(4, 4); // evicts key 1 - cache.get(1); // returns -1 (not found) - cache.get(3); // returns 3 - cache.get(4); // returns 4 - Show Company Tags - Show Tags - Show Similar Problems +cache.put(1, 1); +cache.put(2, 2); +cache.get(1); // returns 1 +cache.put(3, 3); // evicts key 2 +cache.get(2); // returns -1 (not found) +cache.put(4, 4); // evicts key 1 +cache.get(1); // returns -1 (not found) +cache.get(3); // returns 3 +cache.get(4); // returns 4 +Show Company Tags +Show Tags +Show Similar Problems - */ +*/ public class LRUCache { - public static class DLinkList { - int key, value; - DLinkList left; - DLinkList right; + public static class DLinkList { + int key, value; + DLinkList left; + DLinkList right; - DLinkList(int key, int value) { - this.key = key; - this.value = value; - left = null; - right = null; - } + DLinkList(int key, int value) { + this.key = key; + this.value = value; + left = null; + right = null; } + } - private Map cache; - private DLinkList head, tail; - private int capacity, currentSize; + private Map cache; + private DLinkList head, tail; + private int capacity, currentSize; - /** - * Pop head node - * - * @return - */ - private DLinkList popHead() { - if (!head.right.equals(tail)) { - DLinkList node = head.right; - head.right = node.right; - node.right.left = head; - node.right = null; - node.left = null; - return node; - } - return null; + /** + * Pop head node + * + * @return + */ + private DLinkList popHead() { + if (!head.right.equals(tail)) { + DLinkList node = head.right; + head.right = node.right; + node.right.left = head; + node.right = null; + node.left = null; + return node; } + return null; + } - /** - * Push to tail - * - * @param node - */ - private void offer(DLinkList node) { - tail.left.right = node; - node.left = tail.left; - node.right = tail; - tail.left = node; - } + /** + * Push to tail + * + * @param node + */ + private void offer(DLinkList node) { + tail.left.right = node; + node.left = tail.left; + node.right = tail; + tail.left = node; + } - /** - * Move node to tail - * - * @param node - */ - private void moveToTail(DLinkList node) { - node.left.right = node.right; - node.right.left = node.left; - offer(node); - } + /** + * Move node to tail + * + * @param node + */ + private void moveToTail(DLinkList node) { + node.left.right = node.right; + node.right.left = node.left; + offer(node); + } - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - LRUCache cache = new LRUCache(2); - cache.put(1, 1); - cache.put(2, 2); - System.out.println(cache.get(1)); - cache.put(3, 3); - System.out.println(cache.get(2)); - cache.put(4, 4); - System.out.println(cache.get(1)); - System.out.println(cache.get(3)); - System.out.println(cache.get(4)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + LRUCache cache = new LRUCache(2); + cache.put(1, 1); + cache.put(2, 2); + System.out.println(cache.get(1)); + cache.put(3, 3); + System.out.println(cache.get(2)); + cache.put(4, 4); + System.out.println(cache.get(1)); + System.out.println(cache.get(3)); + System.out.println(cache.get(4)); + } - public LRUCache(int capacity) { - this.capacity = capacity; - this.currentSize = 0; - cache = new HashMap<>(); - head = new DLinkList(-1, -1); - tail = new DLinkList(-1, -1); - head.right = tail; - tail.left = head; - } + public LRUCache(int capacity) { + this.capacity = capacity; + this.currentSize = 0; + cache = new HashMap<>(); + head = new DLinkList(-1, -1); + tail = new DLinkList(-1, -1); + head.right = tail; + tail.left = head; + } - public int get(int key) { - if (cache.get(key) == null) return -1; - DLinkList node = cache.get(key); - moveToTail(node); - return node.value; - } + public int get(int key) { + if (cache.get(key) == null) return -1; + DLinkList node = cache.get(key); + moveToTail(node); + return node.value; + } - public void put(int key, int value) { - if (cache.containsKey(key)) { - DLinkList node = cache.get(key); - node.value = value; - moveToTail(node); - } else { - if (capacity == currentSize) { - DLinkList head = popHead(); - if (head != null) { - cache.remove(head.key); - DLinkList node = new DLinkList(key, value); - offer(node); - cache.put(key, node); - } - } else { - DLinkList node = new DLinkList(key, value); - offer(node); - cache.put(key, node); - ++currentSize; - } + public void put(int key, int value) { + if (cache.containsKey(key)) { + DLinkList node = cache.get(key); + node.value = value; + moveToTail(node); + } else { + if (capacity == currentSize) { + DLinkList head = popHead(); + if (head != null) { + cache.remove(head.key); + DLinkList node = new DLinkList(key, value); + offer(node); + cache.put(key, node); } + } else { + DLinkList node = new DLinkList(key, value); + offer(node); + cache.put(key, node); + ++currentSize; + } } + } } diff --git a/problems/src/design/NestedIterator.java b/problems/src/design/NestedIterator.java index 9ce14219..b7d1fc09 100644 --- a/problems/src/design/NestedIterator.java +++ b/problems/src/design/NestedIterator.java @@ -7,72 +7,70 @@ /** * Created by gouthamvidyapradhan on 30/11/2017. * - * Given a nested list of integers, implement an iterator to flatten it. - - Each element is either an integer, or a list -- whose elements may also be integers or other lists. - - Example 1: - Given the list [[1,1],2,[1,1]], - - By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,1,2,1,1]. - - Example 2: - Given the list [1,[4,[6]]], - - By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,4,6]. + *

Given a nested list of integers, implement an iterator to flatten it. + * + *

Each element is either an integer, or a list -- whose elements may also be integers or other + * lists. + * + *

Example 1: Given the list [[1,1],2,[1,1]], + * + *

By calling next repeatedly until hasNext returns false, the order of elements returned by next + * should be: [1,1,2,1,1]. + * + *

Example 2: Given the list [1,[4,[6]]], + * + *

By calling next repeatedly until hasNext returns false, the order of elements returned by next + * should be: [1,4,6]. */ -public class NestedIterator implements Iterator{ - - private List result; - private int curr, size; - - // This is the interface that allows for creating nested lists. - // You should not implement it, or speculate about its implementation - public interface NestedInteger{ - //@return true if this NestedInteger holds a single integer, rather than a nested list. - 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 nested list that this NestedInteger holds, if it holds a nested list - // Return null if this NestedInteger holds a single integer - public List getList(); - } - - public NestedIterator(List nestedList) { - this.result = new ArrayList<>(); - curr = 0; - flatten(result, nestedList); - size = result.size(); - } - - @Override - public Integer next() { - if(curr < size){ - return result.get(curr++); - } - return -1; - } - - @Override - public boolean hasNext() { - return curr < size; - } - - public static void main(String[] args) { - +public class NestedIterator implements Iterator { + + private List result; + private int curr, size; + + // This is the interface that allows for creating nested lists. + // You should not implement it, or speculate about its implementation + public interface NestedInteger { + // @return true if this NestedInteger holds a single integer, rather than a nested list. + 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 nested list that this NestedInteger holds, if it holds a nested list + // Return null if this NestedInteger holds a single integer + public List getList(); + } + + public NestedIterator(List nestedList) { + this.result = new ArrayList<>(); + curr = 0; + flatten(result, nestedList); + size = result.size(); + } + + @Override + public Integer next() { + if (curr < size) { + return result.get(curr++); } - - private void flatten(List flatList, List nestedList){ - for(NestedInteger n : nestedList){ - if(n.isInteger()){ - flatList.add(n.getInteger()); - } else{ - flatten(flatList, n.getList()); - } - } + return -1; + } + + @Override + public boolean hasNext() { + return curr < size; + } + + public static void main(String[] args) {} + + private void flatten(List flatList, List nestedList) { + for (NestedInteger n : nestedList) { + if (n.isInteger()) { + flatList.add(n.getInteger()); + } else { + flatten(flatList, n.getList()); + } } - + } } diff --git a/problems/src/design/RandomizedCollection.java b/problems/src/design/RandomizedCollection.java index ac47d90b..466178c4 100644 --- a/problems/src/design/RandomizedCollection.java +++ b/problems/src/design/RandomizedCollection.java @@ -1,115 +1,117 @@ package design; + import java.util.*; /** - * Created by gouthamvidyapradhan on 14/04/2018. - * Design a data structure that supports all following operations in average O(1) time. - - Note: Duplicate elements are allowed. - insert(val): Inserts an item val to the collection. - remove(val): Removes an item val from the collection if present. - getRandom: Returns a random element from current collection of elements. The probability of each element being - returned is linearly related to the number of same value the collection contains. - Example: - - // Init an empty collection. - RandomizedCollection collection = new RandomizedCollection(); - - // Inserts 1 to the collection. Returns true as the collection did not contain 1. - collection.insert(1); - - // Inserts another 1 to the collection. Returns false as the collection contained 1. Collection now contains [1,1]. - collection.insert(1); - - // Inserts 2 to the collection, returns true. Collection now contains [1,1,2]. - collection.insert(2); - - // getRandom should return 1 with the probability 2/3, and returns 2 with the probability 1/3. - collection.getRandom(); - - // Removes 1 from the collection, returns true. Collection now contains [1,2]. - collection.remove(1); - - // getRandom should return 1 and 2 both equally likely. - collection.getRandom(); - - Solution O(1) for each operation. Maintain a hashmap of value -> {set of indices}; Set of indices are indices of array - containing the value. - Insert: Insert a element in end of array and add the index of array as the set of values in hashmap. - Remove: If the hashmap contains value remove a random element from the set and replace the element at that index - with the last element from array and remove the last element from the array. Since we are removing the last - element from array this operation requires only O(1) time - getRandom(): Generate a random number between 0 and size of array and return the element at that position. + * Created by gouthamvidyapradhan on 14/04/2018. Design a data structure that supports all following + * operations in average O(1) time. + * + *

Note: Duplicate elements are allowed. insert(val): Inserts an item val to the collection. + * remove(val): Removes an item val from the collection if present. getRandom: Returns a random + * element from current collection of elements. The probability of each element being returned is + * linearly related to the number of same value the collection contains. Example: + * + *

// Init an empty collection. RandomizedCollection collection = new RandomizedCollection(); + * + *

// Inserts 1 to the collection. Returns true as the collection did not contain 1. + * collection.insert(1); + * + *

// Inserts another 1 to the collection. Returns false as the collection contained 1. + * Collection now contains [1,1]. collection.insert(1); + * + *

// Inserts 2 to the collection, returns true. Collection now contains [1,1,2]. + * collection.insert(2); + * + *

// getRandom should return 1 with the probability 2/3, and returns 2 with the probability 1/3. + * collection.getRandom(); + * + *

// Removes 1 from the collection, returns true. Collection now contains [1,2]. + * collection.remove(1); + * + *

// getRandom should return 1 and 2 both equally likely. collection.getRandom(); + * + *

Solution O(1) for each operation. Maintain a hashmap of value -> {set of indices}; Set of + * indices are indices of array containing the value. Insert: Insert a element in end of array and + * add the index of array as the set of values in hashmap. Remove: If the hashmap contains value + * remove a random element from the set and replace the element at that index with the last element + * from array and remove the last element from the array. Since we are removing the last element + * from array this operation requires only O(1) time getRandom(): Generate a random number between 0 + * and size of array and return the element at that position. */ public class RandomizedCollection { - private Map> map; - private List list; - - /** Initialize your data structure here. */ - public RandomizedCollection() { - map = new HashMap<>(); - list = new ArrayList<>(); + private Map> map; + private List list; + + /** Initialize your data structure here. */ + public RandomizedCollection() { + map = new HashMap<>(); + list = new ArrayList<>(); + } + + /** + * Inserts a value to the collection. Returns true if the collection did not already contain the + * specified element. + */ + public boolean insert(int val) { + boolean status = map.containsKey(val); + Set set = map.get(val); + if (set == null) { + set = new HashSet<>(); + map.put(val, set); } - - /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ - public boolean insert(int val) { - boolean status = map.containsKey(val); - Set set = map.get(val); - if(set == null){ - set = new HashSet<>(); - map.put(val, set); - } - list.add(val); - set.add(list.size() - 1); - return !status; - } - - /** Removes a value from the collection. Returns true if the collection contained the specified element. */ - public boolean remove(int val) { - if(map.containsKey(val)){ - Set set = map.get(val); - int valIndex = set.iterator().next(); - set.remove(valIndex); - if(set.isEmpty()){ - map.remove(val); - } - if(valIndex == list.size() - 1){ //if this is the last index then simply remove it - list.remove(list.size() - 1); - } else{ - int lastEle = list.get(list.size() - 1); - map.get(lastEle).remove(list.size() - 1); - map.get(lastEle).add(valIndex); - list.set(valIndex, lastEle); - list.remove(list.size() - 1); - } - return true; - } else return false; - } - - /** Get a random element from the collection. */ - public int getRandom() { - Random random = new Random(); - return list.get(random.nextInt(list.size())); - } - - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - RandomizedCollection collection = new RandomizedCollection(); - System.out.println(collection.insert(1)); - System.out.println(collection.insert(1)); - System.out.println(collection.insert(2)); - System.out.println(collection.getRandom()); - System.out.println(collection.remove(2)); - System.out.println(collection.getRandom()); - System.out.println(collection.remove(1)); - System.out.println(collection.getRandom()); - System.out.println(collection.remove(1)); - } - - + list.add(val); + set.add(list.size() - 1); + return !status; + } + + /** + * Removes a value from the collection. Returns true if the collection contained the specified + * element. + */ + public boolean remove(int val) { + if (map.containsKey(val)) { + Set set = map.get(val); + int valIndex = set.iterator().next(); + set.remove(valIndex); + if (set.isEmpty()) { + map.remove(val); + } + if (valIndex == list.size() - 1) { // if this is the last index then simply remove it + list.remove(list.size() - 1); + } else { + int lastEle = list.get(list.size() - 1); + map.get(lastEle).remove(list.size() - 1); + map.get(lastEle).add(valIndex); + list.set(valIndex, lastEle); + list.remove(list.size() - 1); + } + return true; + } else return false; + } + + /** Get a random element from the collection. */ + public int getRandom() { + Random random = new Random(); + return list.get(random.nextInt(list.size())); + } + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + RandomizedCollection collection = new RandomizedCollection(); + System.out.println(collection.insert(1)); + System.out.println(collection.insert(1)); + System.out.println(collection.insert(2)); + System.out.println(collection.getRandom()); + System.out.println(collection.remove(2)); + System.out.println(collection.getRandom()); + System.out.println(collection.remove(1)); + System.out.println(collection.getRandom()); + System.out.println(collection.remove(1)); + } } diff --git a/problems/src/design/RandomizedSet.java b/problems/src/design/RandomizedSet.java index 5e21d892..42babec3 100644 --- a/problems/src/design/RandomizedSet.java +++ b/problems/src/design/RandomizedSet.java @@ -3,116 +3,101 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 23/03/2017. - * Design a data structure that supports all following operations in average O(1) time. - *

- * insert(val): Inserts an item val to the set if not already present. - * remove(val): Removes an item val from the set if present. - * getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned. - * Example: - *

- * // Init an empty set. - * RandomizedSet randomSet = new RandomizedSet(); - *

- * // Inserts 1 to the set. Returns true as 1 was inserted successfully. - * randomSet.insert(1); - *

- * // Returns false as 2 does not exist in the set. - * randomSet.remove(2); - *

- * // Inserts 2 to the set, returns true. Set now contains [1,2]. - * randomSet.insert(2); - *

- * // getRandom should return either 1 or 2 randomly. - * randomSet.getRandom(); - *

- * // Removes 1 from the set, returns true. Set now contains [2]. - * randomSet.remove(1); - *

- * // 2 was already in the set, so return false. - * randomSet.insert(2); - *

- * // Since 2 is the only number in the set, getRandom always return 2. - * randomSet.getRandom(); + * Created by gouthamvidyapradhan on 23/03/2017. Design a data structure that supports all following + * operations in average O(1) time. + * + *

insert(val): Inserts an item val to the set if not already present. remove(val): Removes an + * item val from the set if present. getRandom: Returns a random element from current set of + * elements. Each element must have the same probability of being returned. Example: + * + *

// Init an empty set. RandomizedSet randomSet = new RandomizedSet(); + * + *

// Inserts 1 to the set. Returns true as 1 was inserted successfully. randomSet.insert(1); + * + *

// Returns false as 2 does not exist in the set. randomSet.remove(2); + * + *

// Inserts 2 to the set, returns true. Set now contains [1,2]. randomSet.insert(2); + * + *

// getRandom should return either 1 or 2 randomly. randomSet.getRandom(); + * + *

// Removes 1 from the set, returns true. Set now contains [2]. randomSet.remove(1); + * + *

// 2 was already in the set, so return false. randomSet.insert(2); + * + *

// Since 2 is the only number in the set, getRandom always return 2. randomSet.getRandom(); */ public class RandomizedSet { - private Map map; - private List list; - private Random random; + private Map map; + private List list; + private Random random; - /** - * Initialize your data structure here. - */ - public RandomizedSet() { - map = new HashMap<>(); - list = new ArrayList<>(); - random = new Random(); - } - - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - RandomizedSet rSet = new RandomizedSet(); - System.out.println(rSet.getRandom()); - System.out.println(rSet.insert(1)); - System.out.println(rSet.insert(2)); - System.out.println(rSet.insert(2)); - System.out.println(rSet.insert(3)); - System.out.println(rSet.remove(2)); - System.out.println(rSet.insert(2)); - System.out.println(rSet.getRandom()); - System.out.println(rSet.insert(234)); - System.out.println(rSet.insert(23)); - System.out.println(rSet.insert(22)); - System.out.println(rSet.getRandom()); - System.out.println(rSet.remove(245)); - System.out.println(rSet.remove(234)); - System.out.println(rSet.getRandom()); - } + /** Initialize your data structure here. */ + public RandomizedSet() { + map = new HashMap<>(); + list = new ArrayList<>(); + random = new Random(); + } - /** - * Inserts a value to the set. Returns true if the set did not already contain the specified element. - */ - public boolean insert(int val) { - if (!map.keySet().contains(val)) { - int pos = list.size(); - map.put(val, pos); - list.add(val); - return true; - } - return false; - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + RandomizedSet rSet = new RandomizedSet(); + System.out.println(rSet.getRandom()); + System.out.println(rSet.insert(1)); + System.out.println(rSet.insert(2)); + System.out.println(rSet.insert(2)); + System.out.println(rSet.insert(3)); + System.out.println(rSet.remove(2)); + System.out.println(rSet.insert(2)); + System.out.println(rSet.getRandom()); + System.out.println(rSet.insert(234)); + System.out.println(rSet.insert(23)); + System.out.println(rSet.insert(22)); + System.out.println(rSet.getRandom()); + System.out.println(rSet.remove(245)); + System.out.println(rSet.remove(234)); + System.out.println(rSet.getRandom()); + } - /** - * Removes a value from the set. Returns true if the set contained the specified element. - */ - public boolean remove(int val) { - if (map.containsKey(val)) { - int size = list.size(); - int posVal = map.get(val); - if (posVal < (size - 1)) { - int last = list.get(size - 1); - map.put(last, posVal); - list.set(posVal, last); - } - map.remove(val); - list.remove(size - 1); - return true; - } - return false; + /** + * Inserts a value to the set. Returns true if the set did not already contain the specified + * element. + */ + public boolean insert(int val) { + if (!map.keySet().contains(val)) { + int pos = list.size(); + map.put(val, pos); + list.add(val); + return true; } + return false; + } - /** - * Get a random element from the set. - */ - public int getRandom() { - /*if(list.size() == 0) return 0; - else if (list.size() == 1) return list.get(0);*/ - return list.get(random.nextInt(list.size() - 1)); + /** Removes a value from the set. Returns true if the set contained the specified element. */ + public boolean remove(int val) { + if (map.containsKey(val)) { + int size = list.size(); + int posVal = map.get(val); + if (posVal < (size - 1)) { + int last = list.get(size - 1); + map.put(last, posVal); + list.set(posVal, last); + } + map.remove(val); + list.remove(size - 1); + return true; } + return false; + } + /** Get a random element from the set. */ + public int getRandom() { + /*if(list.size() == 0) return 0; + else if (list.size() == 1) return list.get(0);*/ + return list.get(random.nextInt(list.size() - 1)); + } } diff --git a/problems/src/design/SerializeDeserializeBinaryTree.java b/problems/src/design/SerializeDeserializeBinaryTree.java index 1517e6b0..2313ad53 100644 --- a/problems/src/design/SerializeDeserializeBinaryTree.java +++ b/problems/src/design/SerializeDeserializeBinaryTree.java @@ -3,105 +3,105 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 11/03/2017. - * Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment. - *

- * Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure. - *

- * For example, you may serialize the following tree - *

- * 1 - * / \ - * 2 3 - * / \ - * 4 5 - * as "[1,2,3,null,null,4,5]", just the same as how LeetCode OJ serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself. - * Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless. + * Created by gouthamvidyapradhan on 11/03/2017. Serialization is the process of converting a data + * structure or object into a sequence of bits so that it can be stored in a file or memory buffer, + * or transmitted across a network connection link to be reconstructed later in the same or another + * computer environment. + * + *

Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how + * your serialization/deserialization algorithm should work. You just need to ensure that a binary + * tree can be serialized to a string and this string can be deserialized to the original tree + * structure. + * + *

For example, you may serialize the following tree + * + *

1 / \ 2 3 / \ 4 5 as "[1,2,3,null,null,4,5]", just the same as how LeetCode OJ serializes a + * binary tree. You do not necessarily need to follow this format, so please be creative and come up + * with different approaches yourself. Note: Do not use class member/global/static variables to + * store states. Your serialize and deserialize algorithms should be stateless. */ public class SerializeDeserializeBinaryTree { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - private static final String NULL = "X"; + private static final String NULL = "X"; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - TreeNode root = new TreeNode(1); - TreeNode two = new TreeNode(2); - TreeNode three = new TreeNode(3); - TreeNode four = new TreeNode(4); - TreeNode five = new TreeNode(5); - TreeNode six = new TreeNode(6); - TreeNode seven = new TreeNode(7); - TreeNode eight = new TreeNode(8); - TreeNode nine = new TreeNode(9); - TreeNode ten = new TreeNode(10); - root.left = null; - root.right = two; - two.left = three; - three.left = four; - four.right = five; - five.right = six; - six.left = seven; - seven.left = eight; - eight.right = nine; - nine.right = ten; - String serializedStr = new SerializeDeserializeBinaryTree().serialize(root); + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(1); + TreeNode two = new TreeNode(2); + TreeNode three = new TreeNode(3); + TreeNode four = new TreeNode(4); + TreeNode five = new TreeNode(5); + TreeNode six = new TreeNode(6); + TreeNode seven = new TreeNode(7); + TreeNode eight = new TreeNode(8); + TreeNode nine = new TreeNode(9); + TreeNode ten = new TreeNode(10); + root.left = null; + root.right = two; + two.left = three; + three.left = four; + four.right = five; + five.right = six; + six.left = seven; + seven.left = eight; + eight.right = nine; + nine.right = ten; + String serializedStr = new SerializeDeserializeBinaryTree().serialize(root); - TreeNode result = new SerializeDeserializeBinaryTree().deserialize(serializedStr); - } + TreeNode result = new SerializeDeserializeBinaryTree().deserialize(serializedStr); + } - // Encodes a tree to a single string. - public String serialize(TreeNode root) { - if (root == null) return null; - List list = new ArrayList<>(); - encode(root, list); - StringBuilder sb = new StringBuilder(); - sb.append(list.get(0)); - for (int i = 1, l = list.size(); i < l; i++) { - sb.append(",").append(list.get(i)); - } - return sb.toString(); + // Encodes a tree to a single string. + public String serialize(TreeNode root) { + if (root == null) return null; + List list = new ArrayList<>(); + encode(root, list); + StringBuilder sb = new StringBuilder(); + sb.append(list.get(0)); + for (int i = 1, l = list.size(); i < l; i++) { + sb.append(",").append(list.get(i)); } + return sb.toString(); + } - private void encode(TreeNode root, List list) { - if (root == null) list.add(NULL); - else { - list.add(String.valueOf(root.val)); - encode(root.left, list); - encode(root.right, list); - } + private void encode(TreeNode root, List list) { + if (root == null) list.add(NULL); + else { + list.add(String.valueOf(root.val)); + encode(root.left, list); + encode(root.right, list); } + } - // Decodes your encoded data to tree. - public TreeNode deserialize(String data) { - if (data == null || data.isEmpty()) return null; - StringTokenizer st = new StringTokenizer(data, ","); - Queue queue = new ArrayDeque<>(); - while (st.hasMoreTokens()) - queue.offer(st.nextToken()); - return decode(queue); - } + // Decodes your encoded data to tree. + public TreeNode deserialize(String data) { + if (data == null || data.isEmpty()) return null; + StringTokenizer st = new StringTokenizer(data, ","); + Queue queue = new ArrayDeque<>(); + while (st.hasMoreTokens()) queue.offer(st.nextToken()); + return decode(queue); + } - private TreeNode decode(Queue queue) { - String node = queue.poll(); - if (node.equals(NULL)) - return null; - TreeNode root = new TreeNode(Integer.parseInt(node)); - root.left = decode(queue); - root.right = decode(queue); - return root; - } + private TreeNode decode(Queue queue) { + String node = queue.poll(); + if (node.equals(NULL)) return null; + TreeNode root = new TreeNode(Integer.parseInt(node)); + root.left = decode(queue); + root.right = decode(queue); + return root; + } } diff --git a/problems/src/design/TicTacToe.java b/problems/src/design/TicTacToe.java index aef7b8fe..1e0728b8 100644 --- a/problems/src/design/TicTacToe.java +++ b/problems/src/design/TicTacToe.java @@ -2,150 +2,122 @@ /** * Created by gouthamvidyapradhan on 13/05/2017. - *

- * 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. - * Example: - * 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| - *

- * Follow up: - * Could you do better than O(n2) per move() operation? - *

- * Solution: The below solution works in O(1) time complexity. - * 1. For each player move, keep track of count of selection for each row and each column. - * 2. To keep track of counts in each diagonals we need to first know if the move is made on either one of the diagonals. - * The move is made in either of the diagonals if and only if (row = col) AND/OR (col + row = N - 1) - * 3. As soon as the count in any of column, row or diagonal reach N then return the current player as the winner, else return 0. + * + *

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. Example: 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| + * + *

Follow up: Could you do better than O(n2) per move() operation? + * + *

Solution: The below solution works in O(1) time complexity. 1. For each player move, keep + * track of count of selection for each row and each column. 2. To keep track of counts in each + * diagonals we need to first know if the move is made on either one of the diagonals. The move is + * made in either of the diagonals if and only if (row = col) AND/OR (col + row = N - 1) 3. As soon + * as the count in any of column, row or diagonal reach N then return the current player as the + * winner, else return 0. */ public class TicTacToe { - /** - * Cell class to keep track of first player and second player row/column count - */ - private class Cell { - int player1 = 0, player2 = 0; - } + /** Cell class to keep track of first player and second player row/column count */ + private class Cell { + int player1 = 0, player2 = 0; + } - Cell[] rows, columns; //Array of row and column cells - private int N, fPD1 = 0, fPD2 = 0, sPD1 = 0, sPD2 = 0; //fPD1 -> first_player_diagonal1 + Cell[] rows, columns; // Array of row and column cells + private int N, fPD1 = 0, fPD2 = 0, sPD1 = 0, sPD2 = 0; // fPD1 -> first_player_diagonal1 - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - TicTacToe toe = new TicTacToe(3); - System.out.println(toe.move(0, 0, 1)); - System.out.println(toe.move(0, 2, 2)); - System.out.println(toe.move(1, 0, 1)); - System.out.println(toe.move(1, 1, 2)); - System.out.println(toe.move(2, 0, 1)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + TicTacToe toe = new TicTacToe(3); + System.out.println(toe.move(0, 0, 1)); + System.out.println(toe.move(0, 2, 2)); + System.out.println(toe.move(1, 0, 1)); + System.out.println(toe.move(1, 1, 2)); + System.out.println(toe.move(2, 0, 1)); + } - /** - * Initialize your data structure here. - */ - public TicTacToe(int n) { - N = n; - rows = new Cell[N]; - columns = new Cell[N]; - } + /** Initialize your data structure here. */ + public TicTacToe(int n) { + N = n; + rows = new Cell[N]; + columns = new Cell[N]; + } - /** - * Move and check who wins. - * - * @param row row - * @param col col - * @param player player - * @return integer indicating the winner - */ - public int move(int row, int col, int player) { - switch (player) { - case 1: - increment(rows, row, 1); - increment(columns, col, 1); - if ((col + row) == (N - 1)) - fPD2++; - if (row == col) - fPD1++; - if (rows[row].player1 == N - || columns[col].player1 == N || fPD1 == N || fPD2 == N) - return 1; - break; + /** + * Move and check who wins. + * + * @param row row + * @param col col + * @param player player + * @return integer indicating the winner + */ + public int move(int row, int col, int player) { + switch (player) { + case 1: + increment(rows, row, 1); + increment(columns, col, 1); + if ((col + row) == (N - 1)) fPD2++; + if (row == col) fPD1++; + if (rows[row].player1 == N || columns[col].player1 == N || fPD1 == N || fPD2 == N) return 1; + break; - case 2: - increment(rows, row, 2); - increment(columns, col, 2); - if ((col + row) == (N - 1)) - sPD2++; - if (row == col) - sPD1++; - if (rows[row].player2 == N - || columns[col].player2 == N || sPD1 == N || sPD2 == N) - return 2; - break; - } - return 0; + case 2: + increment(rows, row, 2); + increment(columns, col, 2); + if ((col + row) == (N - 1)) sPD2++; + if (row == col) sPD1++; + if (rows[row].player2 == N || columns[col].player2 == N || sPD1 == N || sPD2 == N) return 2; + break; } + return 0; + } - /** - * Increment row / col count - * - * @param cells array of cells - * @param key row / col key - * @param player Player object - */ - private void increment(Cell[] cells, int key, int player) { - Cell p = cells[key]; - if (p == null) { - p = new Cell(); - cells[key] = p; - } - if (player == 1) - p.player1++; - else p.player2++; + /** + * Increment row / col count + * + * @param cells array of cells + * @param key row / col key + * @param player Player object + */ + private void increment(Cell[] cells, int key, int player) { + Cell p = cells[key]; + if (p == null) { + p = new Cell(); + cells[key] = p; } + if (player == 1) p.player1++; + else p.player2++; + } } diff --git a/problems/src/design/Trie.java b/problems/src/design/Trie.java index ff77639c..f49eeccf 100644 --- a/problems/src/design/Trie.java +++ b/problems/src/design/Trie.java @@ -4,98 +4,86 @@ import java.util.Map; /** - * Created by Goutham Vidya Pradhan on 7/3/2017. - * Implement a trie with insert, search, and startsWith methods. - *

- * Note: - * You may assume that all inputs are consist of lowercase letters a-z. + * Created by Goutham Vidya Pradhan on 7/3/2017. Implement a trie with insert, search, and + * startsWith methods. + * + *

Note: You may assume that all inputs are consist of lowercase letters a-z. */ public class Trie { - private Map map; + private Map map; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - Trie trie = new Trie(); - trie.insert("boxing"); - trie.insert("box"); - System.out.println(trie.search("boxing")); - System.out.println(trie.startsWith("box")); - System.out.println(trie.search("box")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + Trie trie = new Trie(); + trie.insert("boxing"); + trie.insert("box"); + System.out.println(trie.search("boxing")); + System.out.println(trie.startsWith("box")); + System.out.println(trie.search("box")); + } - /** - * Initialize your data structure here. - */ - public Trie() { - map = new HashMap<>(); - } + /** Initialize your data structure here. */ + public Trie() { + map = new HashMap<>(); + } - /** - * Inserts a word into the trie. - */ - public void insert(String word) { - if (word != null) { - add(0, word, word.length()); - } + /** Inserts a word into the trie. */ + public void insert(String word) { + if (word != null) { + add(0, word, word.length()); } + } - private void add(int i, String word, int length) { - if (i < length) { - char c = word.charAt(i); - Trie subTrie = map.get(c); - if (subTrie == null) { - subTrie = new Trie(); - map.put(c, subTrie); - } - subTrie.add(i + 1, word, length); - } else map.put(null, new Trie()); //use null to indicate end of string - } - - /** - * Returns if the word is in the trie. - */ - public boolean search(String word) { - if (word != null) { - return search(0, word, word.length()); - } - return false; - } + private void add(int i, String word, int length) { + if (i < length) { + char c = word.charAt(i); + Trie subTrie = map.get(c); + if (subTrie == null) { + subTrie = new Trie(); + map.put(c, subTrie); + } + subTrie.add(i + 1, word, length); + } else map.put(null, new Trie()); // use null to indicate end of string + } - private boolean search(int i, String word, int length) { - if (i < length) { - char c = word.charAt(i); - Trie subTrie = map.get(c); - if (subTrie == null) - return false; - return subTrie.search(i + 1, word, length); - } - return map.containsKey(null); + /** Returns if the word is in the trie. */ + public boolean search(String word) { + if (word != null) { + return search(0, word, word.length()); } + return false; + } - /** - * Returns if there is any word in the trie that starts with the given prefix. - */ - public boolean startsWith(String prefix) { - if (prefix != null) { - return startsWith(0, prefix, prefix.length()); - } - return false; + private boolean search(int i, String word, int length) { + if (i < length) { + char c = word.charAt(i); + Trie subTrie = map.get(c); + if (subTrie == null) return false; + return subTrie.search(i + 1, word, length); } + return map.containsKey(null); + } - private boolean startsWith(int i, String prefix, int length) { - if (i < length) { - char c = prefix.charAt(i); - Trie subTrie = map.get(c); - if (subTrie == null) - return false; - return subTrie.startsWith(i + 1, prefix, length); - } else return true; + /** Returns if there is any word in the trie that starts with the given prefix. */ + public boolean startsWith(String prefix) { + if (prefix != null) { + return startsWith(0, prefix, prefix.length()); } + return false; + } + private boolean startsWith(int i, String prefix, int length) { + if (i < length) { + char c = prefix.charAt(i); + Trie subTrie = map.get(c); + if (subTrie == null) return false; + return subTrie.startsWith(i + 1, prefix, length); + } else return true; + } } diff --git a/problems/src/design/Twitter.java b/problems/src/design/Twitter.java index 88095f88..8c58506a 100644 --- a/problems/src/design/Twitter.java +++ b/problems/src/design/Twitter.java @@ -3,195 +3,181 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 18/03/2017. - * Design a simplified version of Twitter where users can post tweets, follow/unfollow another user and is able to see the 10 most recent tweets in the user's news feed. Your design should support the following methods: - *

- * postTweet(userId, tweetId): Compose a new tweet. - * getNewsFeed(userId): Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. - * follow(followerId, followeeId): Follower follows a followee. - * unfollow(followerId, followeeId): Follower unfollows a followee. - * Example: - *

- * Twitter twitter = new Twitter(); - *

- * // User 1 posts a new tweet (id = 5). - * twitter.postTweet(1, 5); - *

- * // User 1's news feed should return a list with 1 tweet id -> [5]. - * twitter.getNewsFeed(1); - *

- * // User 1 follows user 2. - * twitter.follow(1, 2); - *

- * // User 2 posts a new tweet (id = 6). - * twitter.postTweet(2, 6); - *

- * // User 1's news feed should return a list with 2 tweet ids -> [6, 5]. - * // Tweet id 6 should precede tweet id 5 because it is posted after tweet id 5. - * twitter.getNewsFeed(1); - *

- * // User 1 unfollows user 2. - * twitter.unfollow(1, 2); - *

- * // User 1's news feed should return a list with 1 tweet id -> [5], - * // since user 1 is no longer following user 2. - * twitter.getNewsFeed(1); + * Created by gouthamvidyapradhan on 18/03/2017. Design a simplified version of Twitter where users + * can post tweets, follow/unfollow another user and is able to see the 10 most recent tweets in the + * user's news feed. Your design should support the following methods: + * + *

postTweet(userId, tweetId): Compose a new tweet. getNewsFeed(userId): Retrieve the 10 most + * recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who + * the user followed or by the user herself. Tweets must be ordered from most recent to least + * recent. follow(followerId, followeeId): Follower follows a followee. unfollow(followerId, + * followeeId): Follower unfollows a followee. Example: + * + *

Twitter twitter = new Twitter(); + * + *

// User 1 posts a new tweet (id = 5). twitter.postTweet(1, 5); + * + *

// User 1's news feed should return a list with 1 tweet id -> [5]. twitter.getNewsFeed(1); + * + *

// User 1 follows user 2. twitter.follow(1, 2); + * + *

// User 2 posts a new tweet (id = 6). twitter.postTweet(2, 6); + * + *

// User 1's news feed should return a list with 2 tweet ids -> [6, 5]. // Tweet id 6 should + * precede tweet id 5 because it is posted after tweet id 5. twitter.getNewsFeed(1); + * + *

// User 1 unfollows user 2. twitter.unfollow(1, 2); + * + *

// User 1's news feed should return a list with 1 tweet id -> [5], // since user 1 is no + * longer following user 2. twitter.getNewsFeed(1); */ public class Twitter { - class User { - int id; - Set follow = new HashSet<>(); - Queue tweets = new ArrayDeque<>(); + class User { + int id; + Set follow = new HashSet<>(); + Queue tweets = new ArrayDeque<>(); - User(int id) { - this.id = id; - } - - public void follow(int id) { - follow.add(id); - } - - public void addTweet(Tweet t) { - if (tweets.size() == 10) { - tweets.poll(); - } - tweets.offer(t); - } - - public void unFollow(int id) { - follow.remove(id); - } - - public Set getFollow() { - return follow; - } - - public Queue getTweets() { - return tweets; - } + User(int id) { + this.id = id; } - class Tweet { - int id; - long time; - - Tweet(int id, long time) { - this.id = id; - this.time = time; - } + public void follow(int id) { + follow.add(id); } - private Map userMap; - private Map tweetMap; - private static long tweetCount = 0L; - - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - Twitter twitter = new Twitter(); - twitter.postTweet(1, 5); - twitter.follow(1, 1); - System.out.println(twitter.getNewsFeed(1)); - /*twitter.follow(2, 1); - System.out.println(twitter.getNewsFeed(2)); - //twitter.unfollow(2, 1); - twitter.postTweet(2, 3); - System.out.println(twitter.getNewsFeed(1)); - System.out.println(twitter.getNewsFeed(2)); - twitter.follow(1, 2); - System.out.println(twitter.getNewsFeed(1)); - twitter.unfollow(2, 1); - System.out.println(twitter.getNewsFeed(2)); - System.out.println(twitter.getNewsFeed(1)); - //twitter.getNewsFeed(2); - */ + public void addTweet(Tweet t) { + if (tweets.size() == 10) { + tweets.poll(); + } + tweets.offer(t); } - /** - * Initialize your data structure here. - */ - public Twitter() { - userMap = new HashMap<>(); - tweetMap = new HashMap<>(); + public void unFollow(int id) { + follow.remove(id); } - /** - * Compose a new tweet. - */ - public void postTweet(int userId, int tweetId) { - User user = userMap.get(userId); - if (user == null) { - user = new User(userId); - userMap.put(userId, user); - } - user.addTweet(new Tweet(tweetId, tweetCount++)); + public Set getFollow() { + return follow; } - /** - * Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. - */ - public List getNewsFeed(int userId) { - User user = userMap.get(userId); - List result = new ArrayList<>(); - if (user == null) return result; - Set follwers = user.getFollow(); - if (follwers != null) { - List tweets = new ArrayList<>(); - tweets.addAll(user.getTweets()); - for (Integer i : follwers) { - User f = userMap.get(i); - if (f != null) { - tweets.addAll(f.getTweets()); - } - } - Comparator comparator = new Comparator() { - @Override - public int compare(Tweet o1, Tweet o2) { - return Long.compare(o2.time, o1.time); - } - }; - - Collections.sort(tweets, comparator); - - for (int i = 0; i < 10; i++) { - if (i >= tweets.size()) - break; - result.add(tweets.get(i).id); - } - } - return result; + public Queue getTweets() { + return tweets; } + } - /** - * Follower follows a followee. If the operation is invalid, it should be a no-op. - */ - public void follow(int followerId, int followeeId) { - if (followerId == followeeId) return; - User user = userMap.get(followerId); - if (user == null) - user = new User(followerId); - userMap.put(followerId, user); - if (userMap.get(followeeId) != null) { - user.follow(userMap.get(followeeId).id); - } else { - User newUser = new User(followeeId); - userMap.put(followeeId, newUser); - user.follow(userMap.get(followeeId).id); - } - } + class Tweet { + int id; + long time; - /** - * Follower unfollows a followee. If the operation is invalid, it should be a no-op. - */ - public void unfollow(int followerId, int followeeId) { - User user = userMap.get(followerId); - if (user != null) { - user.unFollow(followeeId); + Tweet(int id, long time) { + this.id = id; + this.time = time; + } + } + + private Map userMap; + private Map tweetMap; + private static long tweetCount = 0L; + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + Twitter twitter = new Twitter(); + twitter.postTweet(1, 5); + twitter.follow(1, 1); + System.out.println(twitter.getNewsFeed(1)); + /*twitter.follow(2, 1); + System.out.println(twitter.getNewsFeed(2)); + //twitter.unfollow(2, 1); + twitter.postTweet(2, 3); + System.out.println(twitter.getNewsFeed(1)); + System.out.println(twitter.getNewsFeed(2)); + twitter.follow(1, 2); + System.out.println(twitter.getNewsFeed(1)); + twitter.unfollow(2, 1); + System.out.println(twitter.getNewsFeed(2)); + System.out.println(twitter.getNewsFeed(1)); + //twitter.getNewsFeed(2); + */ + } + + /** Initialize your data structure here. */ + public Twitter() { + userMap = new HashMap<>(); + tweetMap = new HashMap<>(); + } + + /** Compose a new tweet. */ + public void postTweet(int userId, int tweetId) { + User user = userMap.get(userId); + if (user == null) { + user = new User(userId); + userMap.put(userId, user); + } + user.addTweet(new Tweet(tweetId, tweetCount++)); + } + + /** + * Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must + * be posted by users who the user followed or by the user herself. Tweets must be ordered from + * most recent to least recent. + */ + public List getNewsFeed(int userId) { + User user = userMap.get(userId); + List result = new ArrayList<>(); + if (user == null) return result; + Set follwers = user.getFollow(); + if (follwers != null) { + List tweets = new ArrayList<>(); + tweets.addAll(user.getTweets()); + for (Integer i : follwers) { + User f = userMap.get(i); + if (f != null) { + tweets.addAll(f.getTweets()); } + } + Comparator comparator = + new Comparator() { + @Override + public int compare(Tweet o1, Tweet o2) { + return Long.compare(o2.time, o1.time); + } + }; + + Collections.sort(tweets, comparator); + + for (int i = 0; i < 10; i++) { + if (i >= tweets.size()) break; + result.add(tweets.get(i).id); + } + } + 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 (followerId == followeeId) return; + User user = userMap.get(followerId); + if (user == null) user = new User(followerId); + userMap.put(followerId, user); + if (userMap.get(followeeId) != null) { + user.follow(userMap.get(followeeId).id); + } else { + User newUser = new User(followeeId); + userMap.put(followeeId, newUser); + user.follow(userMap.get(followeeId).id); } + } + /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ + public void unfollow(int followerId, int followeeId) { + User user = userMap.get(followerId); + if (user != null) { + user.unFollow(followeeId); + } + } } diff --git a/problems/src/design/WordDictionary.java b/problems/src/design/WordDictionary.java index 6bae0965..af1c8e58 100644 --- a/problems/src/design/WordDictionary.java +++ b/problems/src/design/WordDictionary.java @@ -6,123 +6,111 @@ /** * Created by gouthamvidyapradhan on 09/12/2017. * - * 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. - - For example: - - addWord("bad") - addWord("dad") - addWord("mad") - search("pad") -> false - search("bad") -> true - search(".ad") -> true - search("b..") -> true - Note: - You may assume that all words are consist of lowercase letters a-z. - - Solution: Implement a simple Trie and perform a search. + *

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. + * + *

For example: + * + *

addWord("bad") addWord("dad") addWord("mad") search("pad") -> false search("bad") -> true + * search(".ad") -> true search("b..") -> true Note: You may assume that all words are consist of + * lowercase letters a-z. + * + *

Solution: Implement a simple Trie and perform a search. */ public class WordDictionary { - private Trie trie; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - WordDictionary wd = new WordDictionary(); - wd.addWord("bad"); - wd.addWord("dad"); - wd.addWord("mad"); - System.out.println(wd.search("pad")); - System.out.println(wd.search("bad")); - System.out.println(wd.search(".ad")); - System.out.println(wd.search("...")); - } + private Trie trie; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + WordDictionary wd = new WordDictionary(); + wd.addWord("bad"); + wd.addWord("dad"); + wd.addWord("mad"); + System.out.println(wd.search("pad")); + System.out.println(wd.search("bad")); + System.out.println(wd.search(".ad")); + System.out.println(wd.search("...")); + } + + /** Initialize your data structure here. */ + public WordDictionary() { + this.trie = new Trie(); + } + + /** Adds a word into the data structure. */ + public void addWord(String word) { + this.trie.insert(word); + } + + /** + * 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 this.trie.search(word); + } + + private class Trie { + + private Map map; /** Initialize your data structure here. */ - public WordDictionary() { - this.trie = new Trie(); - } - - /** Adds a word into the data structure. */ - public void addWord(String word) { - this.trie.insert(word); + private Trie() { + map = new HashMap<>(); } - /** 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 this.trie.search(word); + /** Inserts a word into the trie. */ + private void insert(String word) { + if (word != null) { + add(0, word, word.length()); + } } - private class Trie { - - private Map map; - - /** - * Initialize your data structure here. - */ - private Trie() { - map = new HashMap<>(); - } - - /** - * Inserts a word into the trie. - */ - private void insert(String word) { - if (word != null) { - add(0, word, word.length()); - } - } - - private void add(int i, String word, int length) { - if (i < length) { - char c = word.charAt(i); - Trie subTrie = map.get(c); - if (subTrie == null) { - subTrie = new Trie(); - map.put(c, subTrie); - } - subTrie.add(i + 1, word, length); - } else map.put(null, new Trie()); //use null to indicate end of string + private void add(int i, String word, int length) { + if (i < length) { + char c = word.charAt(i); + Trie subTrie = map.get(c); + if (subTrie == null) { + subTrie = new Trie(); + map.put(c, subTrie); } + subTrie.add(i + 1, word, length); + } else map.put(null, new Trie()); // use null to indicate end of string + } - /** - * Returns if the word is in the trie. - */ - private boolean search(String word) { - if (word != null) { - return search(0, word, word.length()); - } - return false; - } + /** Returns if the word is in the trie. */ + private boolean search(String word) { + if (word != null) { + return search(0, word, word.length()); + } + return false; + } - private boolean search(int i, String word, int length) { - if (i < length) { - char c = word.charAt(i); - if(c == '.'){ - for(Character child : map.keySet()){ - if(child != null){ - Trie subTrie = map.get(child); - if(subTrie.search(i + 1, word, length)) return true; - } - } - return false; - } else{ - Trie subTrie = map.get(c); - if (subTrie == null) - return false; - return subTrie.search(i + 1, word, length); - } + private boolean search(int i, String word, int length) { + if (i < length) { + char c = word.charAt(i); + if (c == '.') { + for (Character child : map.keySet()) { + if (child != null) { + Trie subTrie = map.get(child); + if (subTrie.search(i + 1, word, length)) return true; } - return map.containsKey(null); + } + return false; + } else { + Trie subTrie = map.get(c); + if (subTrie == null) return false; + return subTrie.search(i + 1, word, length); } + } + return map.containsKey(null); } + } } diff --git a/problems/src/design/WordFilter.java b/problems/src/design/WordFilter.java index 8503edb3..566f5999 100644 --- a/problems/src/design/WordFilter.java +++ b/problems/src/design/WordFilter.java @@ -4,121 +4,107 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 25/12/2017. - * Given many words, words[i] has weight i. - - Design a class WordFilter that supports one function, WordFilter.f(String prefix, String suffix). It will return the - word with given prefix and suffix with maximum weight. If no word exists, return -1. - - Examples: - Input: - WordFilter(["apple"]) - WordFilter.f("a", "e") // returns 0 - WordFilter.f("b", "") // returns -1 - Note: - words has length in range [1, 15000]. - For each test case, up to words.length queries WordFilter.f may be made. - words[i] has length in range [1, 10]. - prefix, suffix have lengths in range [0, 10]. - words[i] and prefix, suffix queries consist of lowercase letters only. - - Solution: Implement a trie to store the dictionary of words. For every word insert all the possible suffixes into - the trie. Additionally overwrite weight each time a word is inserted. - Example for a word 'cat' all the possible trie insertions are -> #cat, t#cat, at#cat, cat#cat - Search for 'suffix#prefix' in the trie and return its weight + * Created by gouthamvidyapradhan on 25/12/2017. Given many words, words[i] has weight i. + * + *

Design a class WordFilter that supports one function, WordFilter.f(String prefix, String + * suffix). It will return the word with given prefix and suffix with maximum weight. If no word + * exists, return -1. + * + *

Examples: Input: WordFilter(["apple"]) WordFilter.f("a", "e") // returns 0 WordFilter.f("b", + * "") // returns -1 Note: words has length in range [1, 15000]. For each test case, up to + * words.length queries WordFilter.f may be made. words[i] has length in range [1, 10]. prefix, + * suffix have lengths in range [0, 10]. words[i] and prefix, suffix queries consist of lowercase + * letters only. + * + *

Solution: Implement a trie to store the dictionary of words. For every word insert all the + * possible suffixes into the trie. Additionally overwrite weight each time a word is inserted. + * Example for a word 'cat' all the possible trie insertions are -> #cat, t#cat, at#cat, cat#cat + * Search for 'suffix#prefix' in the trie and return its weight */ public class WordFilter { - private Trie trie; - private int maxWeight; //max weight possible - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - String[] words = {"apple", "cat", "mat", "mars", "abxcd", "abycd", "apple"}; - WordFilter wf = new WordFilter(words); - System.out.println(wf.f("abx", "")); + private Trie trie; + private int maxWeight; // max weight possible + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + String[] words = {"apple", "cat", "mat", "mars", "abxcd", "abycd", "apple"}; + WordFilter wf = new WordFilter(words); + System.out.println(wf.f("abx", "")); + } + + public WordFilter(String[] words) { + trie = new Trie(); + trie.weight = -1; + maxWeight = words.length - 1; + for (int i = 0; i < words.length; i++) { + String word = words[i]; + trie.insert("#" + word, i); + for (int j = 0, l = word.length(); j < l; j++) { + trie.insert(word.substring(j, l) + "#" + word, i); + } } - - public WordFilter(String[] words) { - trie = new Trie(); - trie.weight = -1; - maxWeight = words.length - 1; - for(int i = 0; i < words.length; i ++){ - String word = words[i]; - trie.insert("#" + word, i); - for(int j = 0, l = word.length(); j < l; j++){ - trie.insert(word.substring(j, l) + "#" + word, i); - } - } - } - - public int f(String prefix, String suffix) { - if((suffix == null || suffix.isEmpty()) && (prefix == null || prefix.isEmpty())){ - return maxWeight; - } else if(prefix == null || prefix.isEmpty()){ - return trie.search(suffix + "#"); - } else if(suffix == null || suffix.isEmpty()){ - return trie.search("#" + prefix); - } else{ - return trie.search(suffix + "#" + prefix); - } + } + + public int f(String prefix, String suffix) { + if ((suffix == null || suffix.isEmpty()) && (prefix == null || prefix.isEmpty())) { + return maxWeight; + } else if (prefix == null || prefix.isEmpty()) { + return trie.search(suffix + "#"); + } else if (suffix == null || suffix.isEmpty()) { + return trie.search("#" + prefix); + } else { + return trie.search(suffix + "#" + prefix); } + } - public static class Trie { + public static class Trie { - private Map map; - int weight; + private Map map; + int weight; + /** Initialize your data structure here. */ + public Trie() { + map = new HashMap<>(); + } - /** - * Initialize your data structure here. - */ - public Trie() { - map = new HashMap<>(); - } - - /** - * Inserts a word into the trie. - */ - public void insert(String word, int weight) { - if (word != null) { - add(0, word, word.length(), weight); - } - } + /** Inserts a word into the trie. */ + public void insert(String word, int weight) { + if (word != null) { + add(0, word, word.length(), weight); + } + } - private void add(int i, String word, int length, int weight) { - if (i < length) { - char c = word.charAt(i); - map.putIfAbsent(c, new Trie()); - Trie subTrie = map.get(c); - subTrie.weight = weight; - subTrie.add(i + 1, word, length, weight); - } - } + private void add(int i, String word, int length, int weight) { + if (i < length) { + char c = word.charAt(i); + map.putIfAbsent(c, new Trie()); + Trie subTrie = map.get(c); + subTrie.weight = weight; + subTrie.add(i + 1, word, length, weight); + } + } - /** - * Returns if the word is in the trie. - */ - public int search(String word) { - if (word != null) { - return search(0, word, word.length()); - } - return -1; - } + /** Returns if the word is in the trie. */ + public int search(String word) { + if (word != null) { + return search(0, word, word.length()); + } + return -1; + } - private int search(int i, String word, int length) { - if (i < length) { - char c = word.charAt(i); - Trie subTrie = map.get(c); - if (subTrie == null) - return -1; - return subTrie.search(i + 1, word, length); - } - return this.weight; - } + private int search(int i, String word, int length) { + if (i < length) { + char c = word.charAt(i); + Trie subTrie = map.get(c); + if (subTrie == null) return -1; + return subTrie.search(i + 1, word, length); + } + return this.weight; } + } } diff --git a/problems/src/divide_and_conquer/KthLargestElementInAnArray.java b/problems/src/divide_and_conquer/KthLargestElementInAnArray.java index 4d4d4249..d1666fb3 100644 --- a/problems/src/divide_and_conquer/KthLargestElementInAnArray.java +++ b/problems/src/divide_and_conquer/KthLargestElementInAnArray.java @@ -1,55 +1,52 @@ package divide_and_conquer; /** - * Created by gouthamvidyapradhan on 09/03/2017. - * Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element. - *

- * For example, - * Given [3,2,1,5,6,4] and k = 2, return 5. - *

- * Note: - * You may assume k is always valid, 1 ≤ k ≤ array's length. + * Created by gouthamvidyapradhan on 09/03/2017. Find the kth largest element in an unsorted array. + * Note that it is the kth largest element in the sorted order, not the kth distinct element. + * + *

For example, Given [3,2,1,5,6,4] and k = 2, return 5. + * + *

Note: You may assume k is always valid, 1 ≤ k ≤ array's length. */ public class KthLargestElementInAnArray { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] nums = {3, 2, 1, 5, 6, 4}; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] nums = {3, 2, 1, 5, 6, 4}; - System.out.println(new KthLargestElementInAnArray().findKthLargest(nums, 6)); - } - - private int findKthLargest(int[] nums, int k) { - return solve(nums, 0, nums.length - 1, k); - } + System.out.println(new KthLargestElementInAnArray().findKthLargest(nums, 6)); + } - private int solve(int[] nums, int pIndex, int end, int k) { - int pivot = nums[end]; - int temp; - int start = pIndex; - for (int i = pIndex; i < end; i++) { - if (nums[i] <= pivot) { - temp = nums[i]; - nums[i] = nums[pIndex]; - nums[pIndex] = temp; - pIndex += 1; - } - } - temp = nums[pIndex]; - nums[pIndex] = nums[end]; - nums[end] = temp; + private int findKthLargest(int[] nums, int k) { + return solve(nums, 0, nums.length - 1, k); + } - int pos = (end - pIndex) + 1; - if (pos == k) return nums[pIndex]; - else if (pos > k) { - return solve(nums, pIndex + 1, end, k); - } else { - return solve(nums, start, pIndex - 1, k - pos); - } + private int solve(int[] nums, int pIndex, int end, int k) { + int pivot = nums[end]; + int temp; + int start = pIndex; + for (int i = pIndex; i < end; i++) { + if (nums[i] <= pivot) { + temp = nums[i]; + nums[i] = nums[pIndex]; + nums[pIndex] = temp; + pIndex += 1; + } } + temp = nums[pIndex]; + nums[pIndex] = nums[end]; + nums[end] = temp; + int pos = (end - pIndex) + 1; + if (pos == k) return nums[pIndex]; + else if (pos > k) { + return solve(nums, pIndex + 1, end, k); + } else { + return solve(nums, start, pIndex - 1, k - pos); + } + } } diff --git a/problems/src/divide_and_conquer/ReversePairs.java b/problems/src/divide_and_conquer/ReversePairs.java index 8168e92c..a919a4ef 100644 --- a/problems/src/divide_and_conquer/ReversePairs.java +++ b/problems/src/divide_and_conquer/ReversePairs.java @@ -1,121 +1,117 @@ package divide_and_conquer; -import java.util.*; -/** - * Created by gouthamvidyapradhan on 30/06/2018. - * Given an array nums, we call (i, j) an important reverse pair if i < j and nums[i] > 2*nums[j]. - - You need to return the number of important reverse pairs in the given array. - - Example1: - - Input: [1,3,2,3,1] - Output: 2 - Example2: - - Input: [2,4,3,5,1] - Output: 3 - Note: - The length of the given array will not exceed 50,000. - All the numbers in the input array are in the range of 32-bit integer. - - Solution: O(n log n): - Example: 1,3,2,3,1 - 1. Sort the array in non-increasing order (if there is a collision, sort by lower index). - So the sorted array will be (3, 3, 2, 1, 1) having indexes (1, 3, 2, 0, 4) - 2. Maintain a prefix sum of index (starting from 1) for the sorted array. So, prefix sum for the above sorted array is - (1, 2, 3, 4, 5) - Now, the basic idea is to iterate from index n - 1 to 0 in the original array and for each element calculate the - element p (num[i] x 2) and find the upper bound of the element p in sorted array which is 3 at index 1 in this case - and add prefix sum of the index 1 to the result. So the result now becomes 2. - - To maintain a prefix sum and update it efficiently we have to use a BIT or Fenwick tree. +import java.util.*; +/** + * Created by gouthamvidyapradhan on 30/06/2018. Given an array nums, we call (i, j) an important + * reverse pair if i < j and nums[i] > 2*nums[j]. + * + *

You need to return the number of important reverse pairs in the given array. + * + *

Example1: + * + *

Input: [1,3,2,3,1] Output: 2 Example2: + * + *

Input: [2,4,3,5,1] Output: 3 Note: The length of the given array will not exceed 50,000. All + * the numbers in the input array are in the range of 32-bit integer. + * + *

Solution: O(n log n): Example: 1,3,2,3,1 1. Sort the array in non-increasing order (if there + * is a collision, sort by lower index). So the sorted array will be (3, 3, 2, 1, 1) having indexes + * (1, 3, 2, 0, 4) 2. Maintain a prefix sum of index (starting from 1) for the sorted array. So, + * prefix sum for the above sorted array is (1, 2, 3, 4, 5) Now, the basic idea is to iterate from + * index n - 1 to 0 in the original array and for each element calculate the element p (num[i] x 2) + * and find the upper bound of the element p in sorted array which is 3 at index 1 in this case and + * add prefix sum of the index 1 to the result. So the result now becomes 2. + * + *

To maintain a prefix sum and update it efficiently we have to use a BIT or Fenwick tree. */ public class ReversePairs { - class Pair{ - int i, n; - Pair(int i, int n){ - this.i = i; - this.n = n; - } - int getN(){ - return n; - } - int getI(){ - return i; - } - } + class Pair { + int i, n; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {2,4,3,5,1}; - System.out.println(new ReversePairs().reversePairs(A)); + Pair(int i, int n) { + this.i = i; + this.n = n; } - public int reversePairs(int[] nums) { - List list = new ArrayList<>(); - Ftree ft = new Ftree(nums.length); - for(int i = 0; i < nums.length; i ++){ - list.add(new Pair(i, nums[i])); - ft.update(i, 1); - } - Collections.sort(list, (Comparator.comparing(Pair::getN).reversed().thenComparing(Pair::getI))); - int[] indexMap = new int[nums.length]; - for(int i = 0, l = list.size(); i < l; i ++){ - indexMap[list.get(i).getI()] = i; - } - int ans = 0; - for(int i = nums.length - 1; i >= 0; i --){ - ft.update(indexMap[i], -1); - int index = binarySearch(list, (long)nums[i] * 2); - if(index > -1){ - ans += ft.getRangeSum(index); - } - } - return ans; + int getN() { + return n; } - private int binarySearch(List list, long n){ - int l = 0, h = list.size() - 1; - int ans = -1; - while(l <= h){ - int m = l + (h - l) / 2; - if(list.get(m).n > n){ - ans = m; - l = m + 1; - } else{ - h = m - 1; - } - } - return ans; + int getI() { + return i; } + } + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {2, 4, 3, 5, 1}; + System.out.println(new ReversePairs().reversePairs(A)); + } + + public int reversePairs(int[] nums) { + List list = new ArrayList<>(); + Ftree ft = new Ftree(nums.length); + for (int i = 0; i < nums.length; i++) { + list.add(new Pair(i, nums[i])); + ft.update(i, 1); + } + Collections.sort(list, (Comparator.comparing(Pair::getN).reversed().thenComparing(Pair::getI))); + int[] indexMap = new int[nums.length]; + for (int i = 0, l = list.size(); i < l; i++) { + indexMap[list.get(i).getI()] = i; + } + int ans = 0; + for (int i = nums.length - 1; i >= 0; i--) { + ft.update(indexMap[i], -1); + int index = binarySearch(list, (long) nums[i] * 2); + if (index > -1) { + ans += ft.getRangeSum(index); + } + } + return ans; + } + + private int binarySearch(List list, long n) { + int l = 0, h = list.size() - 1; + int ans = -1; + while (l <= h) { + int m = l + (h - l) / 2; + if (list.get(m).n > n) { + ans = m; + l = m + 1; + } else { + h = m - 1; + } + } + return ans; + } - private class Ftree { - private int[] a; - - Ftree(int n) { - a = new int[n + 1]; - } + private class Ftree { + private int[] a; - void update(int p, int v) { - for (int i = p + 1; i < a.length; i += (i & (-i))) { - a[i] += v; - } - } + Ftree(int n) { + a = new int[n + 1]; + } - int getRangeSum(int p) { - int sum = 0; - for (int i = p + 1; i > 0; i -= (i & (-i))) { - sum += a[i]; - } - return sum; - } + void update(int p, int v) { + for (int i = p + 1; i < a.length; i += (i & (-i))) { + a[i] += v; + } + } + int getRangeSum(int p) { + int sum = 0; + for (int i = p + 1; i > 0; i -= (i & (-i))) { + sum += a[i]; + } + return sum; } + } } diff --git a/problems/src/divide_and_conquer/SearchA2DMatrix.java b/problems/src/divide_and_conquer/SearchA2DMatrix.java index c876b612..e6941fb0 100644 --- a/problems/src/divide_and_conquer/SearchA2DMatrix.java +++ b/problems/src/divide_and_conquer/SearchA2DMatrix.java @@ -1,56 +1,48 @@ package divide_and_conquer; /** - * Created by gouthamvidyapradhan on 09/03/2017. - * Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: - *

- * Integers in each row are sorted in ascending from left to right. - * Integers in each column are sorted in ascending from top to bottom. - * For example, - *

- * Consider the following matrix: - *

- * [ - * [1, 4, 7, 11, 15], - * [2, 5, 8, 12, 19], - * [3, 6, 9, 16, 22], - * [10, 13, 14, 17, 24], - * [18, 21, 23, 26, 30] - * ] - * Given target = 5, return true. - *

- * Given target = 20, return false. + * Created by gouthamvidyapradhan on 09/03/2017. Write an efficient algorithm that searches for a + * value in an m x n matrix. This matrix has the following properties: + * + *

Integers in each row are sorted in ascending from left to right. Integers in each column are + * sorted in ascending from top to bottom. For example, + * + *

Consider the following matrix: + * + *

[ [1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18, 21, 23, + * 26, 30] ] Given target = 5, return true. + * + *

Given target = 20, return false. */ public class SearchA2DMatrix { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[][] matrix = - { - {1, 3, 5, 7, 9}, //1, 3, 5, 7, 9 - {2, 4, 6, 8, 10}, //2, 4, 6, 8, 10 - {11, 13, 15, 17, 19}, //11, 15, 17, 18, 19 - {12, 14, 16, 18, 20}, //13, 20, 21, 22, 23 - {21, 22, 23, 24, 25} //14, 25, 26, 27, 28 - }; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[][] matrix = { + {1, 3, 5, 7, 9}, // 1, 3, 5, 7, 9 + {2, 4, 6, 8, 10}, // 2, 4, 6, 8, 10 + {11, 13, 15, 17, 19}, // 11, 15, 17, 18, 19 + {12, 14, 16, 18, 20}, // 13, 20, 21, 22, 23 + {21, 22, 23, 24, 25} // 14, 25, 26, 27, 28 + }; - System.out.println(new SearchA2DMatrix().searchMatrix(matrix, 11)); - } + System.out.println(new SearchA2DMatrix().searchMatrix(matrix, 11)); + } - private boolean searchMatrix(int[][] matrix, int target) { - if (matrix.length == 0) return false; - int M = matrix.length; - int N = matrix[0].length; - int r = 0, c = N - 1; - while (r < M && c >= 0) { - if (matrix[r][c] == target) return true; - else if (target < matrix[r][c]) --c; - else if (target > matrix[r][c]) r++; - } - return false; + private boolean searchMatrix(int[][] matrix, int target) { + if (matrix.length == 0) return false; + int M = matrix.length; + int N = matrix[0].length; + int r = 0, c = N - 1; + while (r < M && c >= 0) { + if (matrix[r][c] == target) return true; + else if (target < matrix[r][c]) --c; + else if (target > matrix[r][c]) r++; } + return false; + } } diff --git a/problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java b/problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java index 9b9c463f..01bffcb1 100644 --- a/problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java +++ b/problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java @@ -1,45 +1,47 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 15/02/2018. - * Say you have an array for which the ith element is the price of a given stock on day i. - - Design an algorithm to find the maximum profit. You may complete at most two transactions. - - Note: - You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again). - -Solution: O(n): In the first iteration calculate the max profit that can be made by one buy and sell by iterating from - right to left and saving this in a dp array and maintaining a max value. - In the second iteration starting from left to right maintain a min value and calculate the max profit that can be - made by one buy and sell by taking the difference of current with min and calculate the total profit of two - transactions by summing up the current profit made with the profit in dp array. + * Created by gouthamvidyapradhan on 15/02/2018. Say you have an array for which the ith element is + * the price of a given stock on day i. + * + *

Design an algorithm to find the maximum profit. You may complete at most two transactions. + * + *

Note: You may not engage in multiple transactions at the same time (ie, you must sell the + * stock before you buy again). + * + *

Solution: O(n): In the first iteration calculate the max profit that can be made by one buy + * and sell by iterating from right to left and saving this in a dp array and maintaining a max + * value. In the second iteration starting from left to right maintain a min value and calculate the + * max profit that can be made by one buy and sell by taking the difference of current with min and + * calculate the total profit of two transactions by summing up the current profit made with the + * profit in dp array. */ public class BestTimeToBuyAndSellStockIII { - /** - * Main method - * @param args - */ - public static void main(String[] args) throws Exception{ - int[] A = {10, 9, 8, 7}; - System.out.println(new BestTimeToBuyAndSellStockIII().maxProfit(A)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) throws Exception { + int[] A = {10, 9, 8, 7}; + System.out.println(new BestTimeToBuyAndSellStockIII().maxProfit(A)); + } - public int maxProfit(int[] prices) { - if(prices.length == 0 || prices.length == 1) return 0; - int[] dp = new int[prices.length]; - int min = prices[0]; - int max = prices[prices.length - 1]; - for(int i = prices.length - 2; i >= 0; i--){ - dp[i] = Math.max(max - prices[i], dp[i + 1]); - max = Math.max(max, prices[i]); - } - max = Integer.MIN_VALUE; - for(int i = 0; i < prices.length; i ++){ - max = Math.max(max, prices[i] - min + dp[i]); - min = Math.min(min, prices[i]); - } - return max; + public int maxProfit(int[] prices) { + if (prices.length == 0 || prices.length == 1) return 0; + int[] dp = new int[prices.length]; + int min = prices[0]; + int max = prices[prices.length - 1]; + for (int i = prices.length - 2; i >= 0; i--) { + dp[i] = Math.max(max - prices[i], dp[i + 1]); + max = Math.max(max, prices[i]); + } + max = Integer.MIN_VALUE; + for (int i = 0; i < prices.length; i++) { + max = Math.max(max, prices[i] - min + dp[i]); + min = Math.min(min, prices[i]); } + return max; + } } diff --git a/problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java b/problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java index 54417f9f..acb6eb14 100644 --- a/problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java +++ b/problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java @@ -1,45 +1,42 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 17/03/2017. - * Say you have an array for which the ith element is the price of a given stock on day i. - *

- * If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit. - *

- * Example 1: - * Input: [7, 1, 5, 3, 6, 4] - * Output: 5 - *

- * max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price) - * Example 2: - * Input: [7, 6, 4, 3, 1] - * Output: 0 - *

- * In this case, no transaction is done, i.e. max profit = 0. + * Created by gouthamvidyapradhan on 17/03/2017. Say you have an array for which the ith element is + * the price of a given stock on day i. + * + *

If you were only permitted to complete at most one transaction (ie, buy one and sell one share + * of the stock), design an algorithm to find the maximum profit. + * + *

Example 1: Input: [7, 1, 5, 3, 6, 4] Output: 5 + * + *

max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price) + * Example 2: Input: [7, 6, 4, 3, 1] Output: 0 + * + *

In this case, no transaction is done, i.e. max profit = 0. */ public class BestTimeToBuyAndSellStocks { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] prices = {1, 1, 1, 1, 1}; - System.out.println(new BestTimeToBuyAndSellStocks().maxProfit(prices)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] prices = {1, 1, 1, 1, 1}; + System.out.println(new BestTimeToBuyAndSellStocks().maxProfit(prices)); + } - public int maxProfit(int[] prices) { - if (prices.length == 0) return 0; - int[] max = new int[prices.length]; - max[prices.length - 1] = prices[prices.length - 1]; - for (int i = prices.length - 2; i >= 0; i--) { - max[i] = Math.max(prices[i], max[i + 1]); - } - int result = Integer.MIN_VALUE; - for (int i = 0, l = max.length; i < l; i++) { - result = Math.max(result, max[i] - prices[i]); - } - return result; + public int maxProfit(int[] prices) { + if (prices.length == 0) return 0; + int[] max = new int[prices.length]; + max[prices.length - 1] = prices[prices.length - 1]; + for (int i = prices.length - 2; i >= 0; i--) { + max[i] = Math.max(prices[i], max[i + 1]); + } + int result = Integer.MIN_VALUE; + for (int i = 0, l = max.length; i < l; i++) { + result = Math.max(result, max[i] - prices[i]); } + return result; + } } diff --git a/problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java b/problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java index b9ad0e70..7154a204 100644 --- a/problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java +++ b/problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java @@ -1,53 +1,45 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 14/12/2017. - * Your are given an array of integers prices, for which the i-th element is the price of a given stock on day i; - * and a non-negative integer fee representing a transaction fee. - - You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction. - You may not buy more than 1 share of a stock at a time (ie. you must sell the stock share before you buy again.) - - Return the maximum profit you can make. - - Example 1: - Input: prices = [1, 3, 2, 8, 4, 9], fee = 2 - Output: 8 - Explanation: The maximum profit can be achieved by: - Buying at prices[0] = 1 - Selling at prices[3] = 8 - Buying at prices[4] = 4 - Selling at prices[5] = 9 - The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8. - Note: - - 0 < prices.length <= 50000. - 0 < prices[i] < 50000. - 0 <= fee < 50000. - - Solution: O(n) for every step either you can buy stock or sell. Maintain two variables 'cash' to save max value if - you had sold the stock at current price and 'stock' to save max value if you had purchased the stock at current - price. Return max cash - + * Created by gouthamvidyapradhan on 14/12/2017. Your are given an array of integers prices, for + * which the i-th element is the price of a given stock on day i; and a non-negative integer fee + * representing a transaction fee. + * + *

You may complete as many transactions as you like, but you need to pay the transaction fee for + * each transaction. You may not buy more than 1 share of a stock at a time (ie. you must sell the + * stock share before you buy again.) + * + *

Return the maximum profit you can make. + * + *

Example 1: Input: prices = [1, 3, 2, 8, 4, 9], fee = 2 Output: 8 Explanation: The maximum + * profit can be achieved by: Buying at prices[0] = 1 Selling at prices[3] = 8 Buying at prices[4] = + * 4 Selling at prices[5] = 9 The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8. Note: + * + *

0 < prices.length <= 50000. 0 < prices[i] < 50000. 0 <= fee < 50000. + * + *

Solution: O(n) for every step either you can buy stock or sell. Maintain two variables 'cash' + * to save max value if you had sold the stock at current price and 'stock' to save max value if you + * had purchased the stock at current price. Return max cash */ public class BestTimeToBuyAndSellStocksWithFee { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1, 3, 2, 8, 4, 9}; - System.out.println(new BestTimeToBuyAndSellStocksWithFee().maxProfit(A, 2)); - } - - public int maxProfit(int[] prices, int fee) { - int cash = 0, stock = -prices[0]; - for(int i = 1; i < prices.length; i ++){ - cash = Math.max(cash, prices[i] + stock - fee); - stock = Math.max(stock, cash - prices[i]); - } - return cash; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 3, 2, 8, 4, 9}; + System.out.println(new BestTimeToBuyAndSellStocksWithFee().maxProfit(A, 2)); + } + + public int maxProfit(int[] prices, int fee) { + int cash = 0, stock = -prices[0]; + for (int i = 1; i < prices.length; i++) { + cash = Math.max(cash, prices[i] + stock - fee); + stock = Math.max(stock, cash - prices[i]); } + return cash; + } } diff --git a/problems/src/dynamic_programming/BurstBalloons.java b/problems/src/dynamic_programming/BurstBalloons.java index bed05c8e..0379ebad 100644 --- a/problems/src/dynamic_programming/BurstBalloons.java +++ b/problems/src/dynamic_programming/BurstBalloons.java @@ -3,75 +3,70 @@ import java.util.Arrays; /** - * Created by gouthamvidyapradhan on 02/01/2018. - * Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by array nums. - * You are asked to burst all the balloons. If the you burst balloon i you will get nums[left] * nums[i] * - * nums[right] coins. Here left and right are adjacent indices of i. After the burst, the left and right then - * becomes adjacent. - - Find the maximum coins you can collect by bursting the balloons wisely. - - Note: - (1) You may imagine nums[-1] = nums[n] = 1. They are not real therefore you can not burst them. - (2) 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100 - - Example: - - Given [3, 1, 5, 8] - - Return 167 - - nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> [] - coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167 - - Solution: O(N ^ 3) - The recursive top-down dp memorization solution is based on the idea where each balloon is considered as the last - balloon to be burst. - For the above example 1,3,1,5,8,1 (1 included at either end to indicate boundary) - each balloon starting from 3 until 8 is chosen each time as a the last balloon to be burst using the boundary 1 on - either side. - So, for the first iteration the result is calculated as - 3*1(left boundary)*1(right boundary) + dp(1, 3) (left-sub-problem having 1 and 3 as the boundary) + dp(3, 1) - (right-sub-problem having 3 and 1 as the boundary) - + * Created by gouthamvidyapradhan on 02/01/2018. Given n balloons, indexed from 0 to n-1. Each + * balloon is painted with a number on it represented by array nums. You are asked to burst all the + * balloons. If the you burst balloon i you will get nums[left] * nums[i] * nums[right] coins. Here + * left and right are adjacent indices of i. After the burst, the left and right then becomes + * adjacent. + * + *

Find the maximum coins you can collect by bursting the balloons wisely. + * + *

Note: (1) You may imagine nums[-1] = nums[n] = 1. They are not real therefore you can not + * burst them. (2) 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100 + * + *

Example: + * + *

Given [3, 1, 5, 8] + * + *

Return 167 + * + *

nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> [] coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = + * 167 + * + *

Solution: O(N ^ 3) The recursive top-down dp memorization solution is based on the idea where + * each balloon is considered as the last balloon to be burst. For the above example 1,3,1,5,8,1 (1 + * included at either end to indicate boundary) each balloon starting from 3 until 8 is chosen each + * time as a the last balloon to be burst using the boundary 1 on either side. So, for the first + * iteration the result is calculated as 3*1(left boundary)*1(right boundary) + dp(1, 3) + * (left-sub-problem having 1 and 3 as the boundary) + dp(3, 1) (right-sub-problem having 3 and 1 as + * the boundary) */ public class BurstBalloons { - private int[][] dp; - private int[] N; + private int[][] dp; + private int[] N; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {3, 1, 5, 8}; - System.out.println(new BurstBalloons().maxCoins(A)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {3, 1, 5, 8}; + System.out.println(new BurstBalloons().maxCoins(A)); + } - public int maxCoins(int[] nums) { - N = new int[nums.length + 2]; - N[0] = N[N.length - 1] = 1; //boundary - for(int i = 0; i < nums.length; i ++){ - N[i + 1] = nums[i]; - } - dp = new int[N.length][N.length]; - for (int[] aDp : dp) { - Arrays.fill(aDp, -1); - } - return dp(0, N.length - 1); + public int maxCoins(int[] nums) { + N = new int[nums.length + 2]; + N[0] = N[N.length - 1] = 1; // boundary + for (int i = 0; i < nums.length; i++) { + N[i + 1] = nums[i]; } - - private int dp(int l, int r){ - if(l + 1 == r) return 0; - if(dp[l][r] != -1) return dp[l][r]; - int result = 0; - for(int i = l + 1; i < r; i ++){ - result = Math.max(result, N[i] * N[l] * N[r] + dp(l, i) + dp(i, r)); - } - dp[l][r] = result; - return dp[l][r]; + dp = new int[N.length][N.length]; + for (int[] aDp : dp) { + Arrays.fill(aDp, -1); } + return dp(0, N.length - 1); + } - + private int dp(int l, int r) { + if (l + 1 == r) return 0; + if (dp[l][r] != -1) return dp[l][r]; + int result = 0; + for (int i = l + 1; i < r; i++) { + result = Math.max(result, N[i] * N[l] * N[r] + dp(l, i) + dp(i, r)); + } + dp[l][r] = result; + return dp[l][r]; + } } diff --git a/problems/src/dynamic_programming/CanIWin.java b/problems/src/dynamic_programming/CanIWin.java index acd26de4..f68e925d 100644 --- a/problems/src/dynamic_programming/CanIWin.java +++ b/problems/src/dynamic_programming/CanIWin.java @@ -4,75 +4,74 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 04/07/2017. - * In the "100 game," two players take turns adding, to a running total, any integer from 1..10. The player who first causes the running total to reach or exceed 100 wins. - *

- * What if we change the game so that players cannot re-use integers? - *

- * For example, two players might take turns drawing from a common pool of numbers of 1..15 without replacement until they reach a total >= 100. - *

- * Given an integer maxChoosableInteger and another integer desiredTotal, determine if the first player to move can force a win, assuming both players play optimally. - *

- * You can always assume that maxChoosableInteger will not be larger than 20 and desiredTotal will not be larger than 300. - *

- * Example - *

- * Input: - * maxChoosableInteger = 10 - * desiredTotal = 11 - *

- * Output: - * false - *

- * Explanation: - * No matter which integer the first player choose, the first player will lose. - * The first player can choose an integer from 1 up to 10. - * If the first player choose 1, the second player can only choose integers from 2 up to 10. - * The second player will win by choosing 10 and get a total = 11, which is >= desiredTotal. - * Same with other integers chosen by the first player, the second player will always win. + * Created by gouthamvidyapradhan on 04/07/2017. In the "100 game," two players take turns adding, + * to a running total, any integer from 1..10. The player who first causes the running total to + * reach or exceed 100 wins. + * + *

What if we change the game so that players cannot re-use integers? + * + *

For example, two players might take turns drawing from a common pool of numbers of 1..15 + * without replacement until they reach a total >= 100. + * + *

Given an integer maxChoosableInteger and another integer desiredTotal, determine if the first + * player to move can force a win, assuming both players play optimally. + * + *

You can always assume that maxChoosableInteger will not be larger than 20 and desiredTotal + * will not be larger than 300. + * + *

Example + * + *

Input: maxChoosableInteger = 10 desiredTotal = 11 + * + *

Output: false + * + *

Explanation: No matter which integer the first player choose, the first player will lose. The + * first player can choose an integer from 1 up to 10. If the first player choose 1, the second + * player can only choose integers from 2 up to 10. The second player will win by choosing 10 and + * get a total = 11, which is >= desiredTotal. Same with other integers chosen by the first player, + * the second player will always win. */ public class CanIWin { - private Map> DP; + private Map> DP; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new CanIWin().canIWin(5, 15)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new CanIWin().canIWin(5, 15)); + } - public boolean canIWin(int maxChoosableInteger, int desiredTotal) { - int sum = 0; - for (int i = 1; i <= maxChoosableInteger; i++) - sum += i; - if (desiredTotal == 0) return true; - else if (desiredTotal > sum) return false; //if the desiredTotal exceeds the max possible sum return false; - DP = new HashMap<>(); - DP.put(true, new HashMap<>()); - DP.put(false, new HashMap<>()); - return dp(0, maxChoosableInteger, desiredTotal, true, 0); - } + public boolean canIWin(int maxChoosableInteger, int desiredTotal) { + int sum = 0; + for (int i = 1; i <= maxChoosableInteger; i++) sum += i; + if (desiredTotal == 0) return true; + else if (desiredTotal > sum) + return false; // if the desiredTotal exceeds the max possible sum return false; + DP = new HashMap<>(); + DP.put(true, new HashMap<>()); + DP.put(false, new HashMap<>()); + return dp(0, maxChoosableInteger, desiredTotal, true, 0); + } - private boolean dp(int state, int M, int D, boolean P, int sum) { - if (sum >= D) return false; - Map map = DP.get(P); - if (map.containsKey(state)) - return map.get(state); - else { - map.put(state, false); - for (int i = 0; i < M; i++) { - if ((state & (1 << i)) == 0) { - if (!dp(state | (1 << i), M, D, !P, sum + i + 1)) { - map.put(state, true); - break; - } - } - } + private boolean dp(int state, int M, int D, boolean P, int sum) { + if (sum >= D) return false; + Map map = DP.get(P); + if (map.containsKey(state)) return map.get(state); + else { + map.put(state, false); + for (int i = 0; i < M; i++) { + if ((state & (1 << i)) == 0) { + if (!dp(state | (1 << i), M, D, !P, sum + i + 1)) { + map.put(state, true); + break; + } } - return map.get(state); + } } + return map.get(state); + } } diff --git a/problems/src/dynamic_programming/CatAndMouse.java b/problems/src/dynamic_programming/CatAndMouse.java index 7168ddad..b0dbbdb0 100644 --- a/problems/src/dynamic_programming/CatAndMouse.java +++ b/problems/src/dynamic_programming/CatAndMouse.java @@ -5,146 +5,148 @@ /** * Created by gouthamvidyapradhan on 03/03/2019 * - * A game on an undirected graph is played by two players, Mouse and Cat, who alternate turns. + *

A game on an undirected graph is played by two players, Mouse and Cat, who alternate turns. * - * The graph is given as follows: graph[a] is a list of all nodes b such that ab is an edge of the graph. + *

The graph is given as follows: graph[a] is a list of all nodes b such that ab is an edge of + * the graph. * - * Mouse starts at node 1 and goes first, Cat starts at node 2 and goes second, and there is a Hole at node 0. + *

Mouse starts at node 1 and goes first, Cat starts at node 2 and goes second, and there is a + * Hole at node 0. * - * During each player's turn, they must travel along one edge of the graph that meets where they are. For example, if the Mouse is at node 1, it must travel to any node in graph[1]. + *

During each player's turn, they must travel along one edge of the graph that meets where they + * are. For example, if the Mouse is at node 1, it must travel to any node in graph[1]. * - * Additionally, it is not allowed for the Cat to travel to the Hole (node 0.) + *

Additionally, it is not allowed for the Cat to travel to the Hole (node 0.) * - * Then, the game can end in 3 ways: + *

Then, the game can end in 3 ways: * - * If ever the Cat occupies the same node as the Mouse, the Cat wins. - * If ever the Mouse reaches the Hole, the Mouse wins. - * If ever a position is repeated (ie. the players are in the same position as a previous turn, and it is the same player's turn to move), the game is a draw. - * Given a graph, and assuming both players play optimally, return 1 if the game is won by Mouse, 2 if the game is won by Cat, and 0 if the game is a draw. + *

If ever the Cat occupies the same node as the Mouse, the Cat wins. If ever the Mouse reaches + * the Hole, the Mouse wins. If ever a position is repeated (ie. the players are in the same + * position as a previous turn, and it is the same player's turn to move), the game is a draw. Given + * a graph, and assuming both players play optimally, return 1 if the game is won by Mouse, 2 if the + * game is won by Cat, and 0 if the game is a draw. * + *

Example 1: * + *

Input: [[2,5],[3],[0,4,5],[1,4,5],[2,3],[0,2,3]] Output: 0 Explanation: 4---3---1 | | 2---5 \ + * / 0 * - * Example 1: + *

Note: * - * Input: [[2,5],[3],[0,4,5],[1,4,5],[2,3],[0,2,3]] - * Output: 0 - * Explanation: - * 4---3---1 - * | | - * 2---5 - * \ / - * 0 + *

3 <= graph.length <= 50 It is guaranteed that graph[1] is non-empty. It is guaranteed that + * graph[2] contains a non-zero element. * - * - * Note: - * - * 3 <= graph.length <= 50 - * It is guaranteed that graph[1] is non-empty. - * It is guaranteed that graph[2] contains a non-zero element. - * - * Solution: Each combination of mouse, cat and turn for a state (m, c, p). Transition between different states form - * a state graph - start to color each state with either MOUSE, CAT or a DRAW based on who wins this state. Perform a - * bottom up dp inorder to arrive at the answer. + *

Solution: Each combination of mouse, cat and turn for a state (m, c, p). Transition between + * different states form a state graph - start to color each state with either MOUSE, CAT or a DRAW + * based on who wins this state. Perform a bottom up dp inorder to arrive at the answer. */ public class CatAndMouse { - private final int CAT = 2, MOUSE = 1, DRAW = 0, PLAYER_CAT = 1, PLAYER_MOUSE = 0; - private Queue queue = new ArrayDeque<>(); - class State{ - int catPos, mPos, player, color; - State(int mPos, int catPos, int player, int color){ - this.catPos = catPos; - this.mPos = mPos; - this.player = player; - this.color = color; - } - } + private final int CAT = 2, MOUSE = 1, DRAW = 0, PLAYER_CAT = 1, PLAYER_MOUSE = 0; + private Queue queue = new ArrayDeque<>(); + + class State { + int catPos, mPos, player, color; - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int[][] graph = {{2,5},{3},{0,4,5},{1,4,5},{2,3},{0,2,3}}; - System.out.println(new CatAndMouse().catMouseGame(graph)); + State(int mPos, int catPos, int player, int color) { + this.catPos = catPos; + this.mPos = mPos; + this.player = player; + this.color = color; } + } - public int catMouseGame(int[][] graph) { - int[][][] color = new int[graph.length][graph.length][2]; - int[][][] degree = new int[graph.length][graph.length][2]; + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[][] graph = {{2, 5}, {3}, {0, 4, 5}, {1, 4, 5}, {2, 3}, {0, 2, 3}}; + System.out.println(new CatAndMouse().catMouseGame(graph)); + } - for(int i = 1; i < graph.length; i ++){ - for(int p = 0; p < 2; p ++){ - color[0][i][p] = MOUSE; - queue.offer(new State(0, i, p, MOUSE)); - color[i][i][p] = CAT; - queue.offer(new State(i, i, p, CAT)); - } - } + public int catMouseGame(int[][] graph) { + int[][][] color = new int[graph.length][graph.length][2]; + int[][][] degree = new int[graph.length][graph.length][2]; - for(int m = 0; m < graph.length; m ++){ - for(int c = 1; c < graph.length; c ++){ - degree[m][c][0] = graph[m].length; - degree[m][c][1] = graph[c].length; - for(int v : graph[c]){ - if(v == 0){ - degree[m][c][1]--; - break; - } - } - } - } + for (int i = 1; i < graph.length; i++) { + for (int p = 0; p < 2; p++) { + color[0][i][p] = MOUSE; + queue.offer(new State(0, i, p, MOUSE)); + color[i][i][p] = CAT; + queue.offer(new State(i, i, p, CAT)); + } + } - while(!queue.isEmpty()){ - State current = queue.poll(); - List parents = getParents(graph, current, color); - if(color[current.mPos][current.catPos][current.player] == CAT){ - enqueue(queue, parents, PLAYER_CAT, CAT, color, degree); - } else{ - enqueue(queue, parents, PLAYER_MOUSE, MOUSE, color, degree); - } + for (int m = 0; m < graph.length; m++) { + for (int c = 1; c < graph.length; c++) { + degree[m][c][0] = graph[m].length; + degree[m][c][1] = graph[c].length; + for (int v : graph[c]) { + if (v == 0) { + degree[m][c][1]--; + break; + } } - return color[1][2][0]; + } } - private void enqueue(Queue queue, List parents, int player, int col, int[][][] color, - int[][][] degree){ - for(State parent : parents){ - if(color[parent.mPos][parent.catPos][parent.player] == DRAW){ - if(parent.player == player){ - color[parent.mPos][parent.catPos][parent.player] = col; - queue.offer(new State(parent.mPos, parent.catPos, parent.player, col)); - } else{ - int currDegree = --degree[parent.mPos][parent.catPos][parent.player]; - if(currDegree == 0){ - color[parent.mPos][parent.catPos][parent.player] = col; - queue.offer(new State(parent.mPos, parent.catPos, parent.player, col)); - } - } - } + while (!queue.isEmpty()) { + State current = queue.poll(); + List parents = getParents(graph, current, color); + if (color[current.mPos][current.catPos][current.player] == CAT) { + enqueue(queue, parents, PLAYER_CAT, CAT, color, degree); + } else { + enqueue(queue, parents, PLAYER_MOUSE, MOUSE, color, degree); + } + } + return color[1][2][0]; + } + + private void enqueue( + Queue queue, + List parents, + int player, + int col, + int[][][] color, + int[][][] degree) { + for (State parent : parents) { + if (color[parent.mPos][parent.catPos][parent.player] == DRAW) { + if (parent.player == player) { + color[parent.mPos][parent.catPos][parent.player] = col; + queue.offer(new State(parent.mPos, parent.catPos, parent.player, col)); + } else { + int currDegree = --degree[parent.mPos][parent.catPos][parent.player]; + if (currDegree == 0) { + color[parent.mPos][parent.catPos][parent.player] = col; + queue.offer(new State(parent.mPos, parent.catPos, parent.player, col)); + } } + } } + } - private List getParents(int[][] graph, State current, int[][][] color){ - int player = current.player; - int[] positions; - List list = new ArrayList<>(); - if(player == PLAYER_MOUSE){ - positions = graph[current.catPos]; - for(int pos: positions){ - if(pos == 0) continue; - if(color[current.mPos][pos][PLAYER_CAT] == DRAW){ - list.add(new State(current.mPos, pos, PLAYER_CAT, DRAW)); - } - } - } else{ - positions = graph[current.mPos]; - for(int pos: positions){ - if(color[pos][current.catPos][PLAYER_MOUSE] == DRAW) { - list.add(new State(pos, current.catPos, PLAYER_MOUSE, DRAW)); - } - } + private List getParents(int[][] graph, State current, int[][][] color) { + int player = current.player; + int[] positions; + List list = new ArrayList<>(); + if (player == PLAYER_MOUSE) { + positions = graph[current.catPos]; + for (int pos : positions) { + if (pos == 0) continue; + if (color[current.mPos][pos][PLAYER_CAT] == DRAW) { + list.add(new State(current.mPos, pos, PLAYER_CAT, DRAW)); + } + } + } else { + positions = graph[current.mPos]; + for (int pos : positions) { + if (color[pos][current.catPos][PLAYER_MOUSE] == DRAW) { + list.add(new State(pos, current.catPos, PLAYER_MOUSE, DRAW)); } - return list; + } } + return list; + } } diff --git a/problems/src/dynamic_programming/CherryPickup.java b/problems/src/dynamic_programming/CherryPickup.java index 15a65b70..348c11d0 100644 --- a/problems/src/dynamic_programming/CherryPickup.java +++ b/problems/src/dynamic_programming/CherryPickup.java @@ -3,80 +3,77 @@ import java.util.Arrays; /** - * Created by gouthamvidyapradhan on 27/01/2018. - * In a N x N grid representing a field of cherries, each cell is one of three possible integers. - - 0 means the cell is empty, so you can pass through; - 1 means the cell contains a cherry, that you can pick up and pass through; - -1 means the cell contains a thorn that blocks your way. - Your task is to collect maximum number of cherries possible by following the rules below: - - Starting at the position (0, 0) and reaching (N-1, N-1) by moving right or down through valid path cells (cells - with value 0 or 1); - After reaching (N-1, N-1), returning to (0, 0) by moving left or up through valid path cells; - When passing through a path cell containing a cherry, you pick it up and the cell becomes an empty cell (0); - If there is no valid path between (0, 0) and (N-1, N-1), then no cherries can be collected. - Example 1: - Input: grid = - [[0, 1, -1], - [1, 0, -1], - [1, 1, 1]] - Output: 5 - Explanation: - The player started at (0, 0) and went down, down, right right to reach (2, 2). - 4 cherries were picked up during this single trip, and the matrix becomes [[0,1,-1],[0,0,-1],[0,0,0]]. - Then, the player went left, up, up, left to return home, picking up one more cherry. - The total number of cherries picked up is 5, and this is the maximum possible. - Note: - - grid is an N by N 2D array, with 1 <= N <= 50. - Each grid[i][j] is an integer in the set {-1, 0, 1}. - It is guaranteed that grid[0][0] and grid[N-1][N-1] are not -1. - - Solution O(N ^ 3) time-complexity. Traversing from (0, 0) -> (n - 1, n - 1) or the other way around both are the same. - The key point to note here is the traversal should be done by two person simultaneously starting from (0, 0). - Notice after t steps, each position (r, c) we could be, is on the line r + c = t (along the diagonal). So if we have - two people at positions (r1, c1) and (r2, c2), then r2 = r1 + c1 - c2. - + * Created by gouthamvidyapradhan on 27/01/2018. In a N x N grid representing a field of cherries, + * each cell is one of three possible integers. + * + *

0 means the cell is empty, so you can pass through; 1 means the cell contains a cherry, that + * you can pick up and pass through; -1 means the cell contains a thorn that blocks your way. Your + * task is to collect maximum number of cherries possible by following the rules below: + * + *

Starting at the position (0, 0) and reaching (N-1, N-1) by moving right or down through valid + * path cells (cells with value 0 or 1); After reaching (N-1, N-1), returning to (0, 0) by moving + * left or up through valid path cells; When passing through a path cell containing a cherry, you + * pick it up and the cell becomes an empty cell (0); If there is no valid path between (0, 0) and + * (N-1, N-1), then no cherries can be collected. Example 1: Input: grid = [[0, 1, -1], [1, 0, -1], + * [1, 1, 1]] Output: 5 Explanation: The player started at (0, 0) and went down, down, right right + * to reach (2, 2). 4 cherries were picked up during this single trip, and the matrix becomes + * [[0,1,-1],[0,0,-1],[0,0,0]]. Then, the player went left, up, up, left to return home, picking up + * one more cherry. The total number of cherries picked up is 5, and this is the maximum possible. + * Note: + * + *

grid is an N by N 2D array, with 1 <= N <= 50. Each grid[i][j] is an integer in the set {-1, + * 0, 1}. It is guaranteed that grid[0][0] and grid[N-1][N-1] are not -1. + * + *

Solution O(N ^ 3) time-complexity. Traversing from (0, 0) -> (n - 1, n - 1) or the other way + * around both are the same. The key point to note here is the traversal should be done by two + * person simultaneously starting from (0, 0). Notice after t steps, each position (r, c) we could + * be, is on the line r + c = t (along the diagonal). So if we have two people at positions (r1, c1) + * and (r2, c2), then r2 = r1 + c1 - c2. */ public class CherryPickup { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[][] A = {{0 ,1,-1},{1, 0,-1},{1,1,1}}; - System.out.println(new CherryPickup().cherryPickup(A)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[][] A = {{0, 1, -1}, {1, 0, -1}, {1, 1, 1}}; + System.out.println(new CherryPickup().cherryPickup(A)); + } - public int cherryPickup(int[][] grid) { - int[][][] DP = new int[grid.length][grid.length][grid.length]; - for(int i = 0; i < grid.length; i ++){ - for(int j = 0; j < grid.length; j ++){ - Arrays.fill(DP[i][j], -1); - } - } - int result = dp(grid.length, 0, 0, 0, DP, grid); - if(result < 0) return 0; - else return result; + public int cherryPickup(int[][] grid) { + int[][][] DP = new int[grid.length][grid.length][grid.length]; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid.length; j++) { + Arrays.fill(DP[i][j], -1); + } } + int result = dp(grid.length, 0, 0, 0, DP, grid); + if (result < 0) return 0; + else return result; + } - private int dp(int N, int r1, int c1, int c2, int[][][] DP, int[][] grid){ - int r2 = r1 + (c1 - c2); - if(r1 >= N || c1 >= N || c2 >= N || r2 >= N || grid[r1][c1] == -1 || grid[r2][c2] == -1) return Integer.MIN_VALUE; - else if(DP[r1][c1][c2] != -1) return DP[r1][c1][c2]; - else if(r1 == N - 1 && c1 == N - 1) return grid[N - 1][N - 1]; - else{ - int max = (c1 == c2) ? grid[r1][c1] : (grid[r1][c1] + grid[r2][c2]); - //verify all the 4 possibilities. (P1 down + P2 right), (P1 right, P2 right), (P1 right + P2 down), - // (P1 down, P2 down) - max += Math.max(Math.max(Math.max(dp(N, r1 + 1, c1, c2, DP, grid), dp(N, r1 + 1, c1, c2 + 1, DP, grid)), dp(N, - r1, c1 + 1, c2, DP, grid)), dp(N, r1, c1 + 1, c2 + 1, DP, grid)); - DP[r1][c1][c2] = max; - return max; - } + private int dp(int N, int r1, int c1, int c2, int[][][] DP, int[][] grid) { + int r2 = r1 + (c1 - c2); + if (r1 >= N || c1 >= N || c2 >= N || r2 >= N || grid[r1][c1] == -1 || grid[r2][c2] == -1) + return Integer.MIN_VALUE; + else if (DP[r1][c1][c2] != -1) return DP[r1][c1][c2]; + else if (r1 == N - 1 && c1 == N - 1) return grid[N - 1][N - 1]; + else { + int max = (c1 == c2) ? grid[r1][c1] : (grid[r1][c1] + grid[r2][c2]); + // verify all the 4 possibilities. (P1 down + P2 right), (P1 right, P2 right), (P1 right + P2 + // down), + // (P1 down, P2 down) + max += + Math.max( + Math.max( + Math.max(dp(N, r1 + 1, c1, c2, DP, grid), dp(N, r1 + 1, c1, c2 + 1, DP, grid)), + dp(N, r1, c1 + 1, c2, DP, grid)), + dp(N, r1, c1 + 1, c2 + 1, DP, grid)); + DP[r1][c1][c2] = max; + return max; } - + } } diff --git a/problems/src/dynamic_programming/ClimbingStairs.java b/problems/src/dynamic_programming/ClimbingStairs.java index a5f1cd34..531687ac 100644 --- a/problems/src/dynamic_programming/ClimbingStairs.java +++ b/problems/src/dynamic_programming/ClimbingStairs.java @@ -1,32 +1,29 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 01/04/2017. - * You are climbing a stair case. It takes n steps to reach to the top. - *

- * Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? - *

- * Note: Given n will be a positive integer. + * Created by gouthamvidyapradhan on 01/04/2017. You are climbing a stair case. It takes n steps to + * reach to the top. + * + *

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the + * top? + * + *

Note: Given n will be a positive integer. */ public class ClimbingStairs { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - - } - - public int climbStairs(int n) { - if (n == 0 || n == 1) return 1; - int[] A = new int[n + 1]; - A[n] = 1; - A[n - 1] = 1; - for (int i = n - 2; i >= 0; i--) - A[i] = A[i + 1] + A[i + 2]; - return A[0]; - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception {} + public int climbStairs(int n) { + if (n == 0 || n == 1) return 1; + int[] A = new int[n + 1]; + A[n] = 1; + A[n - 1] = 1; + for (int i = n - 2; i >= 0; i--) A[i] = A[i + 1] + A[i + 2]; + return A[0]; + } } diff --git a/problems/src/dynamic_programming/CoinChange.java b/problems/src/dynamic_programming/CoinChange.java index b6e1445b..fedb648c 100644 --- a/problems/src/dynamic_programming/CoinChange.java +++ b/problems/src/dynamic_programming/CoinChange.java @@ -1,63 +1,57 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 23/06/2017. - * You are given coins of different denominations and a total amount of money amount. - * Write a function to compute the fewest number of coins that you need to make up that amount. - * If that amount of money cannot be made up by any combination of the coins, return -1. - *

- * Example 1: - * coins = [1, 2, 5], amount = 11 - * return 3 (11 = 5 + 5 + 1) - *

- * Example 2: - * coins = [2], amount = 3 - * return -1. - *

- * Note: - * You may assume that you have an infinite number of each kind of coin. - *

- * Solution: - * For example if you have N coins and amount equal to Q - * For every coin you have two options - * i) If you chose to include this coin then, total amount reduces by the sum equivalent to the value of this coin and you are - * left with N coins and Q = (Q - value of this coin) - * ii) If you chose not to include this coin then, you are left with N - 1 coins (since you chose to not to include this coin) - * and total amount is still equal to Q - *

- * Calculate recursively for each coin and possible amount - * Since there can be overlapping sub-problems you can save the state in a 2D matrix - a typical DP approach. - *

- * For each state minimum is calculated using -> Min(1 + fn(i, amount - v[i]), fn(i + 1, amount)) - *

- * Worst-case time complexity is O(N x Q) where N is the total number of coins and Q is the total amount + * Created by gouthamvidyapradhan on 23/06/2017. You are given coins of different denominations and + * a total amount of money amount. Write a function to compute the fewest number of coins that you + * need to make up that amount. If that amount of money cannot be made up by any combination of the + * coins, return -1. + * + *

Example 1: coins = [1, 2, 5], amount = 11 return 3 (11 = 5 + 5 + 1) + * + *

Example 2: coins = [2], amount = 3 return -1. + * + *

Note: You may assume that you have an infinite number of each kind of coin. + * + *

Solution: For example if you have N coins and amount equal to Q For every coin you have two + * options i) If you chose to include this coin then, total amount reduces by the sum equivalent to + * the value of this coin and you are left with N coins and Q = (Q - value of this coin) ii) If you + * chose not to include this coin then, you are left with N - 1 coins (since you chose to not to + * include this coin) and total amount is still equal to Q + * + *

Calculate recursively for each coin and possible amount Since there can be overlapping + * sub-problems you can save the state in a 2D matrix - a typical DP approach. + * + *

For each state minimum is calculated using -> Min(1 + fn(i, amount - v[i]), fn(i + 1, amount)) + * + *

Worst-case time complexity is O(N x Q) where N is the total number of coins and Q is the total + * amount */ public class CoinChange { - private int[][] DP; + private int[][] DP; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] coins = {1, 2, 5}; - System.out.println(new CoinChange().coinChange(coins, 11)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] coins = {1, 2, 5}; + System.out.println(new CoinChange().coinChange(coins, 11)); + } - public int coinChange(int[] coins, int amount) { - DP = new int[coins.length][amount + 1]; - int result = dp(amount, 0, coins); - if (result == Integer.MAX_VALUE - 1) return -1; - return result; - } + public int coinChange(int[] coins, int amount) { + DP = new int[coins.length][amount + 1]; + int result = dp(amount, 0, coins); + if (result == Integer.MAX_VALUE - 1) return -1; + return result; + } - private int dp(int amount, int i, int[] coins) { - if (amount == 0) return 0; - else if (i >= coins.length || amount < 0) return Integer.MAX_VALUE - 1; - if (DP[i][amount] != 0) return DP[i][amount]; - DP[i][amount] = Math.min(1 + dp(amount - coins[i], i, coins), dp(amount, i + 1, coins)); - return DP[i][amount]; - } + private int dp(int amount, int i, int[] coins) { + if (amount == 0) return 0; + else if (i >= coins.length || amount < 0) return Integer.MAX_VALUE - 1; + if (DP[i][amount] != 0) return DP[i][amount]; + DP[i][amount] = Math.min(1 + dp(amount - coins[i], i, coins), dp(amount, i + 1, coins)); + return DP[i][amount]; + } } diff --git a/problems/src/dynamic_programming/CoinChange2.java b/problems/src/dynamic_programming/CoinChange2.java index 2f072002..fe5e84e6 100644 --- a/problems/src/dynamic_programming/CoinChange2.java +++ b/problems/src/dynamic_programming/CoinChange2.java @@ -3,60 +3,47 @@ import java.util.Arrays; /** - * Created by gouthamvidyapradhan on 22/03/2017. - * You are given coins of different denominations and a total amount of money. Write a function to compute the number of combinations that make up that amount. You may assume that you have infinite number of each kind of coin. - *

- * Note: You can assume that - *

- * 0 <= amount <= 5000 - * 1 <= coin <= 5000 - * the number of coins is less than 500 - * the answer is guaranteed to fit into signed 32-bit integer - * Example 1: - *

- * Input: amount = 5, coins = [1, 2, 5] - * Output: 4 - * Explanation: there are four ways to make up the amount: - * 5=5 - * 5=2+2+1 - * 5=2+1+1+1 - * 5=1+1+1+1+1 - * Example 2: - *

- * Input: amount = 3, coins = [2] - * Output: 0 - * Explanation: the amount of 3 cannot be made up just with coins of 2. - * Example 3: - *

- * Input: amount = 10, coins = [10] - * Output: 1 + * Created by gouthamvidyapradhan on 22/03/2017. You are given coins of different denominations and + * a total amount of money. Write a function to compute the number of combinations that make up that + * amount. You may assume that you have infinite number of each kind of coin. + * + *

Note: You can assume that + * + *

0 <= amount <= 5000 1 <= coin <= 5000 the number of coins is less than 500 the answer is + * guaranteed to fit into signed 32-bit integer Example 1: + * + *

Input: amount = 5, coins = [1, 2, 5] Output: 4 Explanation: there are four ways to make up the + * amount: 5=5 5=2+2+1 5=2+1+1+1 5=1+1+1+1+1 Example 2: + * + *

Input: amount = 3, coins = [2] Output: 0 Explanation: the amount of 3 cannot be made up just + * with coins of 2. Example 3: + * + *

Input: amount = 10, coins = [10] Output: 1 */ public class CoinChange2 { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] coins = {1, 2, 5}; - System.out.println(new CoinChange2().change(5, coins)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] coins = {1, 2, 5}; + System.out.println(new CoinChange2().change(5, coins)); + } - public int change(int amount, int[] coins) { - int[][] dp = new int[coins.length][amount + 1]; - for (int i = 0, l = coins.length; i < l; i++) - Arrays.fill(dp[i], -1); - return dp(dp, 0, coins, coins.length, amount); - } - - private int dp(int[][] dp, int i, int[] coins, int l, int n) { - if (n == 0) return 1; - else if (i >= l) return 0; - if (n < 0) return 0; - if (dp[i][n] != -1) return dp[i][n]; - dp[i][n] = dp(dp, i + 1, coins, l, n) + dp(dp, i, coins, l, n - coins[i]); - return dp[i][n]; - } + public int change(int amount, int[] coins) { + int[][] dp = new int[coins.length][amount + 1]; + for (int i = 0, l = coins.length; i < l; i++) Arrays.fill(dp[i], -1); + return dp(dp, 0, coins, coins.length, amount); + } + private int dp(int[][] dp, int i, int[] coins, int l, int n) { + if (n == 0) return 1; + else if (i >= l) return 0; + if (n < 0) return 0; + if (dp[i][n] != -1) return dp[i][n]; + dp[i][n] = dp(dp, i + 1, coins, l, n) + dp(dp, i, coins, l, n - coins[i]); + return dp[i][n]; + } } diff --git a/problems/src/dynamic_programming/CombinationSumIV.java b/problems/src/dynamic_programming/CombinationSumIV.java index e9ecab7d..33a6634a 100644 --- a/problems/src/dynamic_programming/CombinationSumIV.java +++ b/problems/src/dynamic_programming/CombinationSumIV.java @@ -3,64 +3,55 @@ import java.util.Arrays; /** - * Created by gouthamvidyapradhan on 17/12/2017. - * Given an integer array with all positive numbers and no duplicates, find the number of possible combinations that - * add up to a positive integer target. - - Example: - - nums = [1, 2, 3] - target = 4 - - The possible combination ways are: - (1, 1, 1, 1) - (1, 1, 2) - (1, 2, 1) - (1, 3) - (2, 1, 1) - (2, 2) - (3, 1) - - Note that different sequences are counted as different combinations. - - Therefore the output is 7. - Follow up: - What if negative numbers are allowed in the given array? - How does it change the problem? - What limitation we need to add to the question to allow negative numbers? - - Solution: Backtrack and dp + * Created by gouthamvidyapradhan on 17/12/2017. Given an integer array with all positive numbers + * and no duplicates, find the number of possible combinations that add up to a positive integer + * target. + * + *

Example: + * + *

nums = [1, 2, 3] target = 4 + * + *

The possible combination ways are: (1, 1, 1, 1) (1, 1, 2) (1, 2, 1) (1, 3) (2, 1, 1) (2, 2) + * (3, 1) + * + *

Note that different sequences are counted as different combinations. + * + *

Therefore the output is 7. Follow up: What if negative numbers are allowed in the given array? + * How does it change the problem? What limitation we need to add to the question to allow negative + * numbers? + * + *

Solution: Backtrack and dp */ public class CombinationSumIV { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1, 2, 3}; - System.out.println(new CombinationSumIV().combinationSum4(A, 4)); + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 2, 3}; + System.out.println(new CombinationSumIV().combinationSum4(A, 4)); + } + + public int combinationSum4(int[] nums, int target) { + int[] dp = new int[target + 1]; + Arrays.fill(dp, -1); + dp[0] = 1; + return backtrack(nums, dp, target); + } + + private int backtrack(int[] nums, int[] dp, int sum) { + int total = 0; + if (sum < 0) return 0; + if (dp[sum] != -1) return dp[sum]; + else { + for (int num : nums) { + total += backtrack(nums, dp, sum - num); + } } - - public int combinationSum4(int[] nums, int target) { - int[] dp = new int[target + 1]; - Arrays.fill(dp, -1); - dp[0] = 1; - return backtrack(nums, dp, target); - } - - private int backtrack(int[] nums, int[] dp, int sum){ - int total = 0; - if(sum < 0) return 0; - if(dp[sum] != -1) return dp[sum]; - else{ - for (int num : nums) { - total += backtrack(nums, dp, sum - num); - } - } - dp[sum] = total; - return dp[sum]; - } - + dp[sum] = total; + return dp[sum]; + } } diff --git a/problems/src/dynamic_programming/ConcatenatedWords.java b/problems/src/dynamic_programming/ConcatenatedWords.java index dc4254ac..eae5112d 100644 --- a/problems/src/dynamic_programming/ConcatenatedWords.java +++ b/problems/src/dynamic_programming/ConcatenatedWords.java @@ -6,59 +6,56 @@ import java.util.Set; /** - * Created by gouthamvidyapradhan on 12/06/2017. - * Accepted - * Given a list of words (without duplicates), please write a program that returns all concatenated words in the given list of words. - *

- * A concatenated word is defined as a string that is comprised entirely of at least two shorter words in the given array. - *

- * Example: - * Input: ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"] - *

- * Output: ["catsdogcats","dogcatsdog","ratcatdogcat"] - *

- * Explanation: "catsdogcats" can be concatenated by "cats", "dog" and "cats"; - * "dogcatsdog" can be concatenated by "dog", "cats" and "dog"; - * "ratcatdogcat" can be concatenated by "rat", "cat", "dog" and "cat". - *

- * Note: - * The number of elements of the given array will not exceed 10,000 - * The length sum of elements in the given array will not exceed 600,000. - * All the input string will only include lower case letters. - * The returned elements order does not matter. + * Created by gouthamvidyapradhan on 12/06/2017. Accepted Given a list of words (without + * duplicates), please write a program that returns all concatenated words in the given list of + * words. + * + *

A concatenated word is defined as a string that is comprised entirely of at least two shorter + * words in the given array. + * + *

Example: Input: + * ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"] + * + *

Output: ["catsdogcats","dogcatsdog","ratcatdogcat"] + * + *

Explanation: "catsdogcats" can be concatenated by "cats", "dog" and "cats"; "dogcatsdog" can + * be concatenated by "dog", "cats" and "dog"; "ratcatdogcat" can be concatenated by "rat", "cat", + * "dog" and "cat". + * + *

Note: The number of elements of the given array will not exceed 10,000 The length sum of + * elements in the given array will not exceed 600,000. All the input string will only include lower + * case letters. The returned elements order does not matter. */ public class ConcatenatedWords { - public static void main(String[] args) throws Exception { - String[] words = {""}; - System.out.println(new ConcatenatedWords().findAllConcatenatedWordsInADict(words)); - } + public static void main(String[] args) throws Exception { + String[] words = {""}; + System.out.println(new ConcatenatedWords().findAllConcatenatedWordsInADict(words)); + } - public List findAllConcatenatedWordsInADict(String[] words) { - Set dictionary = new HashSet<>(); - for (String w : words) - dictionary.add(w); - List result = new ArrayList<>(); - for (String w : words) { - if (!w.isEmpty() && concatenatedWordsPossible(w, dictionary)) - result.add(w); - } - return result; + public List findAllConcatenatedWordsInADict(String[] words) { + Set dictionary = new HashSet<>(); + for (String w : words) dictionary.add(w); + List result = new ArrayList<>(); + for (String w : words) { + if (!w.isEmpty() && concatenatedWordsPossible(w, dictionary)) result.add(w); } + return result; + } - private boolean concatenatedWordsPossible(String word, Set dictionary) { - boolean[] D = new boolean[word.length() + 1]; - D[word.length()] = true; - dictionary.remove(word); //remove current word from dictionary temporarily - for (int i = word.length() - 1; i >= 0; i--) { - for (int j = i, l = word.length(); j < l; j++) { - String subStr = word.substring(i, j + 1); - if (dictionary.contains(subStr) && D[j + 1]) { - D[i] = true; - break; - } - } + private boolean concatenatedWordsPossible(String word, Set dictionary) { + boolean[] D = new boolean[word.length() + 1]; + D[word.length()] = true; + dictionary.remove(word); // remove current word from dictionary temporarily + for (int i = word.length() - 1; i >= 0; i--) { + for (int j = i, l = word.length(); j < l; j++) { + String subStr = word.substring(i, j + 1); + if (dictionary.contains(subStr) && D[j + 1]) { + D[i] = true; + break; } - dictionary.add(word); //restore deleted word - return D[0]; + } } + dictionary.add(word); // restore deleted word + return D[0]; + } } diff --git a/problems/src/dynamic_programming/ContinuousSubarraySum.java b/problems/src/dynamic_programming/ContinuousSubarraySum.java index 47d6250a..53c17413 100644 --- a/problems/src/dynamic_programming/ContinuousSubarraySum.java +++ b/problems/src/dynamic_programming/ContinuousSubarraySum.java @@ -4,52 +4,47 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 10/12/2017. - * Given a list of non-negative numbers and a target integer k, write a function to check if the array has a - * continuous subarray of size at least 2 that sums up to the multiple of k, that is, sums up to n*k where n is also - * an integer. - - Example 1: - Input: [23, 2, 4, 6, 7], k=6 - Output: True - Explanation: Because [2, 4] is a continuous subarray of size 2 and sums up to 6. - Example 2: - Input: [23, 2, 6, 4, 7], k=6 - Output: True - Explanation: Because [23, 2, 6, 4, 7] is an continuous subarray of size 5 and sums up to 42. - Note: - The length of the array won't exceed 10,000. - You may assume the sum of all the numbers is in the range of a signed 32-bit integer. - - Solution: O(n) sum the elements and maintain a hashmap of key value pair of (sum % k) -> index. If the key is - already found in the hashmap and the difference in the current_index and hashmap index is > 1 then return true. + * Created by gouthamvidyapradhan on 10/12/2017. Given a list of non-negative numbers and a target + * integer k, write a function to check if the array has a continuous subarray of size at least 2 + * that sums up to the multiple of k, that is, sums up to n*k where n is also an integer. + * + *

Example 1: Input: [23, 2, 4, 6, 7], k=6 Output: True Explanation: Because [2, 4] is a + * continuous subarray of size 2 and sums up to 6. Example 2: Input: [23, 2, 6, 4, 7], k=6 Output: + * True Explanation: Because [23, 2, 6, 4, 7] is an continuous subarray of size 5 and sums up to 42. + * Note: The length of the array won't exceed 10,000. You may assume the sum of all the numbers is + * in the range of a signed 32-bit integer. + * + *

Solution: O(n) sum the elements and maintain a hashmap of key value pair of (sum % k) -> + * index. If the key is already found in the hashmap and the difference in the current_index and + * hashmap index is > 1 then return true. */ public class ContinuousSubarraySum { - /** - * Main method - * @param args - */ - public static void main(String[] args) throws Exception{ - int[] A = {1, 3, 6, 12, 7}; - System.out.println(new ContinuousSubarraySum().checkSubarraySum(A, 6)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 3, 6, 12, 7}; + System.out.println(new ContinuousSubarraySum().checkSubarraySum(A, 6)); + } - public boolean checkSubarraySum(int[] nums, int k) { - Map map = new HashMap<>(); - int sum = 0; - map.put(0, -1); - for(int i = 0; i < nums.length; i ++){ - sum += nums[i]; - int mod = (k == 0) ? sum : sum % k; //this is to handle case where k is 0 - if(map.containsKey(mod)){ - if(i - map.get(mod) > 1){ - return true; - } - } else{ - map.put(mod, i); - } + public boolean checkSubarraySum(int[] nums, int k) { + Map map = new HashMap<>(); + int sum = 0; + map.put(0, -1); + for (int i = 0; i < nums.length; i++) { + sum += nums[i]; + int mod = (k == 0) ? sum : sum % k; // this is to handle case where k is 0 + if (map.containsKey(mod)) { + if (i - map.get(mod) > 1) { + return true; } - return false; + } else { + map.put(mod, i); + } } + return false; + } } diff --git a/problems/src/dynamic_programming/CornerRectangles.java b/problems/src/dynamic_programming/CornerRectangles.java index 183396dd..2ee8ec0f 100644 --- a/problems/src/dynamic_programming/CornerRectangles.java +++ b/problems/src/dynamic_programming/CornerRectangles.java @@ -1,71 +1,53 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 26/12/2017. - * Given a grid where each entry is only 0 or 1, find the number of corner rectangles. - - A corner rectangle is 4 distinct 1s on the grid that form an axis-aligned rectangle. Note that only the corners need - to have the value 1. Also, all four 1s used must be distinct. - - Example 1: - Input: grid = - [[1, 0, 0, 1, 0], - [0, 0, 1, 0, 1], - [0, 0, 0, 1, 0], - [1, 0, 1, 0, 1]] - Output: 1 - Explanation: There is only one corner rectangle, with corners grid[1][2], grid[1][4], grid[3][2], grid[3][4]. - Example 2: - Input: grid = - [[1, 1, 1], - [1, 1, 1], - [1, 1, 1]] - Output: 9 - Explanation: There are four 2x2 rectangles, four 2x3 and 3x2 rectangles, and one 3x3 rectangle. - Example 3: - Input: grid = - [[1, 1, 1, 1]] - Output: 0 - Explanation: Rectangles must have four distinct corners. - Note: - The number of rows and columns of grid will each be in the range [1, 200]. - Each grid[i][j] will be either 0 or 1. - The number of 1s in the grid will be at most 6000. - - Solution O(n + m ^ 2): For every row, consider each pair of 1s (every column pairs) and sum up the previous - occurrence of 1s for the same column. - + * Created by gouthamvidyapradhan on 26/12/2017. Given a grid where each entry is only 0 or 1, find + * the number of corner rectangles. + * + *

A corner rectangle is 4 distinct 1s on the grid that form an axis-aligned rectangle. Note that + * only the corners need to have the value 1. Also, all four 1s used must be distinct. + * + *

Example 1: Input: grid = [[1, 0, 0, 1, 0], [0, 0, 1, 0, 1], [0, 0, 0, 1, 0], [1, 0, 1, 0, 1]] + * Output: 1 Explanation: There is only one corner rectangle, with corners grid[1][2], grid[1][4], + * grid[3][2], grid[3][4]. Example 2: Input: grid = [[1, 1, 1], [1, 1, 1], [1, 1, 1]] Output: 9 + * Explanation: There are four 2x2 rectangles, four 2x3 and 3x2 rectangles, and one 3x3 rectangle. + * Example 3: Input: grid = [[1, 1, 1, 1]] Output: 0 Explanation: Rectangles must have four distinct + * corners. Note: The number of rows and columns of grid will each be in the range [1, 200]. Each + * grid[i][j] will be either 0 or 1. The number of 1s in the grid will be at most 6000. + * + *

Solution O(n + m ^ 2): For every row, consider each pair of 1s (every column pairs) and sum up + * the previous occurrence of 1s for the same column. */ public class CornerRectangles { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[][] A = {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}; - System.out.println(new CornerRectangles().countCornerRectangles(A)); - } - - public int countCornerRectangles(int[][] grid) { - int[][] count = new int[grid[0].length][grid[0].length]; - int result = 0; - for(int[] row : grid){ - for(int i = 0; i < row.length; i ++){ - if(row[i] == 1){ - for(int j = i + 1; j < row.length; j++){ - if(row[j] == 1){ - if(count[i][j] > 0){ - result += count[i][j]; - } - count[i][j] ++; - } - } - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[][] A = {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}; + System.out.println(new CornerRectangles().countCornerRectangles(A)); + } + + public int countCornerRectangles(int[][] grid) { + int[][] count = new int[grid[0].length][grid[0].length]; + int result = 0; + for (int[] row : grid) { + for (int i = 0; i < row.length; i++) { + if (row[i] == 1) { + for (int j = i + 1; j < row.length; j++) { + if (row[j] == 1) { + if (count[i][j] > 0) { + result += count[i][j]; + } + count[i][j]++; } + } } - return result; + } } - + return result; + } } diff --git a/problems/src/dynamic_programming/DecodeWays.java b/problems/src/dynamic_programming/DecodeWays.java index f554179f..bfd708f5 100644 --- a/problems/src/dynamic_programming/DecodeWays.java +++ b/problems/src/dynamic_programming/DecodeWays.java @@ -1,49 +1,45 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 01/04/2017. - * A message containing letters from A-Z is being encoded to numbers using the following mapping: - *

- * 'A' -> 1 - * 'B' -> 2 - * ... - * 'Z' -> 26 - * Given an encoded message containing digits, determine the total number of ways to decode it. - *

- * For example, - * Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12). - *

- * The number of ways decoding "12" is 2. + * Created by gouthamvidyapradhan on 01/04/2017. A message containing letters from A-Z is being + * encoded to numbers using the following mapping: + * + *

'A' -> 1 'B' -> 2 ... 'Z' -> 26 Given an encoded message containing digits, determine the + * total number of ways to decode it. + * + *

For example, Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12). + * + *

The number of ways decoding "12" is 2. */ public class DecodeWays { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new DecodeWays().numDecodings("3120")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new DecodeWays().numDecodings("3120")); + } - public int numDecodings(String s) { - if (s == null || s.isEmpty()) return 0; - int[] dp = new int[s.length() + 2]; - dp[s.length()] = 1; - dp[s.length() + 1] = 1; - for (int i = s.length() - 1; i >= 0; i--) { - for (int j = i + 1; j < i + 3; j++) { - if (j <= s.length()) { - String subStr = s.substring(i, j); - if (!subStr.startsWith("0")) { - int intVal = Integer.parseInt(subStr); - if (intVal <= 26) { - dp[i] += dp[j]; - } - } - } + public int numDecodings(String s) { + if (s == null || s.isEmpty()) return 0; + int[] dp = new int[s.length() + 2]; + dp[s.length()] = 1; + dp[s.length() + 1] = 1; + for (int i = s.length() - 1; i >= 0; i--) { + for (int j = i + 1; j < i + 3; j++) { + if (j <= s.length()) { + String subStr = s.substring(i, j); + if (!subStr.startsWith("0")) { + int intVal = Integer.parseInt(subStr); + if (intVal <= 26) { + dp[i] += dp[j]; } + } } - return dp[0]; + } } + return dp[0]; + } } diff --git a/problems/src/dynamic_programming/DecodeWaysII.java b/problems/src/dynamic_programming/DecodeWaysII.java index 5ae0cff2..e17c441e 100644 --- a/problems/src/dynamic_programming/DecodeWaysII.java +++ b/problems/src/dynamic_programming/DecodeWaysII.java @@ -1,109 +1,104 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 11/12/2017. - * A message containing letters from A-Z is being encoded to numbers using the following mapping way: - - 'A' -> 1 - 'B' -> 2 - ... - 'Z' -> 26 - Beyond that, now the encoded string can also contain the character '*', which can be treated as one of the numbers - from 1 to 9. - - Given the encoded message containing digits and the character '*', return the total number of ways to decode it. - - Also, since the answer may be very large, you should return the output mod 109 + 7. - - Example 1: - Input: "*" - Output: 9 - Explanation: The encoded message can be decoded to the string: "A", "B", "C", "D", "E", "F", "G", "H", "I". - Example 2: - Input: "1*" - Output: 9 + 9 = 18 - Note: - The length of the input string will fit in range [1, 105]. - The input string will only contain the character '*' and digits '0' - '9'. - - Solution: O(n) consider each digit and a pair of digits and perform a cartesian product to calculate the total - number of ways. A pair of digits are to be considered only if their combined value does not exceed 26. - Corner cases with combination of * and 0s can be tricky + * Created by gouthamvidyapradhan on 11/12/2017. A message containing letters from A-Z is being + * encoded to numbers using the following mapping way: + * + *

'A' -> 1 'B' -> 2 ... 'Z' -> 26 Beyond that, now the encoded string can also contain the + * character '*', which can be treated as one of the numbers from 1 to 9. + * + *

Given the encoded message containing digits and the character '*', return the total number of + * ways to decode it. + * + *

Also, since the answer may be very large, you should return the output mod 109 + 7. + * + *

Example 1: Input: "*" Output: 9 Explanation: The encoded message can be decoded to the string: + * "A", "B", "C", "D", "E", "F", "G", "H", "I". Example 2: Input: "1*" Output: 9 + 9 = 18 Note: The + * length of the input string will fit in range [1, 105]. The input string will only contain the + * character '*' and digits '0' - '9'. + * + *

Solution: O(n) consider each digit and a pair of digits and perform a cartesian product to + * calculate the total number of ways. A pair of digits are to be considered only if their combined + * value does not exceed 26. Corner cases with combination of * and 0s can be tricky */ public class DecodeWaysII { - private final int CONST = 1000000007; - private int[] dp; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new DecodeWaysII().numDecodings("10")); - } + private final int CONST = 1000000007; + private int[] dp; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new DecodeWaysII().numDecodings("10")); + } - public int numDecodings(String s) { - dp = new int[s.length() + 1]; - if(s.charAt(s.length() - 1) == '*'){ - dp[s.length() - 1] = 9; - } else if(s.charAt(s.length() - 1) == '0') { - dp[s.length() - 1] = 0; - } else dp[s.length() - 1] = 1; - dp[s.length()] = 1; + public int numDecodings(String s) { + dp = new int[s.length() + 1]; + if (s.charAt(s.length() - 1) == '*') { + dp[s.length() - 1] = 9; + } else if (s.charAt(s.length() - 1) == '0') { + dp[s.length() - 1] = 0; + } else dp[s.length() - 1] = 1; + dp[s.length()] = 1; - for(int i = s.length() - 2; i >= 0; i --){ - char curr = s.charAt(i); - char next = s.charAt(i + 1); - switch (curr){ - case '0': - dp[i] = 0; - break; - //number begins with a '*' - case '*': - dp[i] = (int)((9 * (long)dp[i + 1]) % CONST); - switch (next){ - //The next char is a '*' - case '*': - dp[i] = (int)((dp[i] + ((15 * (long)dp[i + 2]) % CONST)) % CONST); //multiplication can be - //very large hence type casting to long is necessary - break; + for (int i = s.length() - 2; i >= 0; i--) { + char curr = s.charAt(i); + char next = s.charAt(i + 1); + switch (curr) { + case '0': + dp[i] = 0; + break; + // number begins with a '*' + case '*': + dp[i] = (int) ((9 * (long) dp[i + 1]) % CONST); + switch (next) { + // The next char is a '*' + case '*': + dp[i] = + (int) + ((dp[i] + ((15 * (long) dp[i + 2]) % CONST)) + % CONST); // multiplication can be + // very large hence type casting to long is necessary + break; - case '0': - dp[i] = (int)((dp[i] + ((2 * (long)dp[i + 2]) % CONST)) % CONST); - break; + case '0': + dp[i] = (int) ((dp[i] + ((2 * (long) dp[i + 2]) % CONST)) % CONST); + break; - default: - if((next - '0') > 6){ - dp[i] = ((dp[i] + (dp[i + 2])) % CONST); - } else { - dp[i] = (int)((dp[i] + ((2 * (long)dp[i + 2]) % CONST)) % CONST); - } - break; - } - break; + default: + if ((next - '0') > 6) { + dp[i] = ((dp[i] + (dp[i + 2])) % CONST); + } else { + dp[i] = (int) ((dp[i] + ((2 * (long) dp[i + 2]) % CONST)) % CONST); + } + break; + } + break; - default: - dp[i] = dp[i + 1]; - switch (next){ - case '*': - if((curr - '0') == 1){ - dp[i] = (int)((dp[i] + ((9 * (long)dp[i + 2]) % CONST)) % CONST); - } else if((curr - '0') == 2){ - dp[i] = (int)((dp[i] + ((6 * (long)dp[i + 2]) % CONST)) % CONST); - } - break; + default: + dp[i] = dp[i + 1]; + switch (next) { + case '*': + if ((curr - '0') == 1) { + dp[i] = (int) ((dp[i] + ((9 * (long) dp[i + 2]) % CONST)) % CONST); + } else if ((curr - '0') == 2) { + dp[i] = (int) ((dp[i] + ((6 * (long) dp[i + 2]) % CONST)) % CONST); + } + break; - default: - if((curr - '0') == 1){ - dp[i] = ((dp[i] + dp[i + 2]) % CONST); - } else if((curr - '0') == 2 && (next - '0' <= 6)){ - dp[i] = ((dp[i] + dp[i + 2]) % CONST); - } - break; - } - } - } - return dp[0]; + default: + if ((curr - '0') == 1) { + dp[i] = ((dp[i] + dp[i + 2]) % CONST); + } else if ((curr - '0') == 2 && (next - '0' <= 6)) { + dp[i] = ((dp[i] + dp[i + 2]) % CONST); + } + break; + } + } } + return dp[0]; + } } diff --git a/problems/src/dynamic_programming/DungeonGame.java b/problems/src/dynamic_programming/DungeonGame.java index 03111f51..e275dca5 100644 --- a/problems/src/dynamic_programming/DungeonGame.java +++ b/problems/src/dynamic_programming/DungeonGame.java @@ -3,76 +3,78 @@ import java.util.Arrays; /** - * Created by gouthamvidyapradhan on 12/07/2017. - * 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. + * Created by gouthamvidyapradhan on 12/07/2017. 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. + * + *

Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon + * entering these rooms; other rooms are either empty (0's) or contain magic orbs that increase the + * knight's health (positive integers). + * + *

In order to reach the princess as quickly as possible, the knight decides to move only + * rightward or downward in each step. + * *

- * 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. - *

- * Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon entering these rooms; other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers). - *

- * In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step. - *

- *

- * Write a function to determine the knight's minimum initial health so that he is able to rescue the princess. - *

- * For example, given the dungeon below, the initial health of the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN. - *

- * -2 (K) -3 3 - * -5 -10 1 - * 10 30 -5 (P) - *

- * Notes: - *

- * The knight's health has no upper bound. - * Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned. - *

- * Solution: O(MxN log Integer.MAX_VALUE) - * Binary search the suitable initial health value in the range (1, Integer.MAX_VALUE) and do a top down DP to check the - * balance health when he reaches princess. + * + *

Write a function to determine the knight's minimum initial health so that he is able to rescue + * the princess. + * + *

For example, given the dungeon below, the initial health of the knight must be at least 7 if + * he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN. + * + *

-2 (K) -3 3 -5 -10 1 10 30 -5 (P) + * + *

Notes: + * + *

The knight's health has no upper bound. Any room can contain threats or power-ups, even the + * first room the knight enters and the bottom-right room where the princess is imprisoned. + * + *

Solution: O(MxN log Integer.MAX_VALUE) Binary search the suitable initial health value in the + * range (1, Integer.MAX_VALUE) and do a top down DP to check the balance health when he reaches + * princess. */ public class DungeonGame { - private final int[] R = {0, -1}; - private final int[] C = {-1, 0}; - private int DP[][]; + private final int[] R = {0, -1}; + private final int[] C = {-1, 0}; + private int DP[][]; - public static void main(String[] args) throws Exception { - int[][] dungeon = {{200}}; - System.out.println(new DungeonGame().calculateMinimumHP(dungeon)); - } + public static void main(String[] args) throws Exception { + int[][] dungeon = {{200}}; + System.out.println(new DungeonGame().calculateMinimumHP(dungeon)); + } - public int calculateMinimumHP(int[][] dungeon) { - DP = new int[dungeon.length][dungeon[0].length]; - int l = 0, h = Integer.MAX_VALUE, ans = 0; - while (l <= h) { - int m = l + (h - l) / 2; - for (int i = 0; i < dungeon.length; i++) - Arrays.fill(DP[i], Integer.MIN_VALUE); - DP[0][0] = m + dungeon[0][0]; - if (dp(dungeon, dungeon.length - 1, dungeon[0].length - 1) > 0) { - ans = m; - h = m - 1; - } else { - l = m + 1; - } - } - return ans == 0 ? 1 : ans; + public int calculateMinimumHP(int[][] dungeon) { + DP = new int[dungeon.length][dungeon[0].length]; + int l = 0, h = Integer.MAX_VALUE, ans = 0; + while (l <= h) { + int m = l + (h - l) / 2; + for (int i = 0; i < dungeon.length; i++) Arrays.fill(DP[i], Integer.MIN_VALUE); + DP[0][0] = m + dungeon[0][0]; + if (dp(dungeon, dungeon.length - 1, dungeon[0].length - 1) > 0) { + ans = m; + h = m - 1; + } else { + l = m + 1; + } } + return ans == 0 ? 1 : ans; + } - private int dp(int[][] dungeon, int r, int c) { - if (DP[r][c] != Integer.MIN_VALUE) - return DP[r][c]; - for (int i = 0; i < 2; i++) { - int newR = r + R[i]; - int newC = c + C[i]; - if (newR >= 0 && newR < dungeon.length && newC >= 0 && newC < dungeon[0].length) { - int life = dp(dungeon, newR, newC); - if (life <= 0) - DP[r][c] = Math.max(DP[r][c], 0); - else DP[r][c] = Math.max(DP[r][c], dungeon[r][c] + life); - } - - } - return DP[r][c]; + private int dp(int[][] dungeon, int r, int c) { + if (DP[r][c] != Integer.MIN_VALUE) return DP[r][c]; + for (int i = 0; i < 2; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 && newR < dungeon.length && newC >= 0 && newC < dungeon[0].length) { + int life = dp(dungeon, newR, newC); + if (life <= 0) DP[r][c] = Math.max(DP[r][c], 0); + else DP[r][c] = Math.max(DP[r][c], dungeon[r][c] + life); + } } + return DP[r][c]; + } } diff --git a/problems/src/dynamic_programming/HouseRobber.java b/problems/src/dynamic_programming/HouseRobber.java index 14678335..3f363840 100644 --- a/problems/src/dynamic_programming/HouseRobber.java +++ b/problems/src/dynamic_programming/HouseRobber.java @@ -1,33 +1,34 @@ package dynamic_programming; /** - * Created by pradhang on 4/3/2017. - * You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night. - *

- * Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. + * Created by pradhang on 4/3/2017. You are a professional robber planning to rob houses along a + * street. Each house has a certain amount of money stashed, the only constraint stopping you from + * robbing each of them is that adjacent houses have security system connected and it will + * automatically contact the police if two adjacent houses were broken into on the same night. + * + *

Given a list of non-negative integers representing the amount of money of each house, + * determine the maximum amount of money you can rob tonight without alerting the police. */ public class HouseRobber { - private int[] max; + private int[] max; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception {} + public int rob(int[] nums) { + if (nums.length == 0) return 0; + max = new int[nums.length]; + if (nums.length == 1) return nums[0]; + max[nums.length - 1] = nums[nums.length - 1]; + max[nums.length - 2] = Math.max(nums[nums.length - 1], nums[nums.length - 2]); + for (int i = nums.length - 3; i >= 0; i--) { + max[i] = Math.max(max[i + 1], nums[i] + max[i + 2]); } - - public int rob(int[] nums) { - if (nums.length == 0) return 0; - max = new int[nums.length]; - if (nums.length == 1) return nums[0]; - max[nums.length - 1] = nums[nums.length - 1]; - max[nums.length - 2] = Math.max(nums[nums.length - 1], nums[nums.length - 2]); - for (int i = nums.length - 3; i >= 0; i--) { - max[i] = Math.max(max[i + 1], nums[i] + max[i + 2]); - } - return max[0]; - } + return max[0]; + } } diff --git a/problems/src/dynamic_programming/HouseRobberII.java b/problems/src/dynamic_programming/HouseRobberII.java index ed118091..bc469bea 100644 --- a/problems/src/dynamic_programming/HouseRobberII.java +++ b/problems/src/dynamic_programming/HouseRobberII.java @@ -3,45 +3,42 @@ import java.util.Arrays; /** - * Created by pradhang on 7/11/2017. - * After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. - * This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street. - *

- * Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. + * Created by pradhang on 7/11/2017. After robbing those houses on that street, the thief has found + * himself a new place for his thievery so that he will not get too much attention. This time, all + * houses at this place are arranged in a circle. That means the first house is the neighbor of the + * last one. Meanwhile, the security system for these houses remain the same as for those in the + * previous street. + * + *

Given a list of non-negative integers representing the amount of money of each house, + * determine the maximum amount of money you can rob tonight without alerting the police. */ public class HouseRobberII { - public static void main(String[] args) throws Exception { - int[] nums = {6, 3, 10, 8, 2, 10, 3, 5, 10, 5, 3}; - System.out.println(new HouseRobberII().rob(nums)); - } + public static void main(String[] args) throws Exception { + int[] nums = {6, 3, 10, 8, 2, 10, 3, 5, 10, 5, 3}; + System.out.println(new HouseRobberII().rob(nums)); + } - public int rob(int[] nums) { - if (nums.length == 0) return 0; - if (nums.length == 1) - return nums[0]; - else if (nums.length == 2) { - if (nums[0] > nums[1]) - return nums[0]; - return nums[1]; - } else if (nums.length == 3) return Math.max(Math.max(nums[0], nums[1]), nums[2]); - int[] DP = new int[nums.length]; - for (int i = nums.length - 1; i > 0; i--) { - if (i + 3 < nums.length) - DP[i] = Math.max(nums[i] + DP[i + 2], nums[i] + DP[i + 3]); - else if (i + 2 < nums.length) - DP[i] = nums[i] + DP[i + 2]; - else DP[i] = nums[i]; - } - int max = Math.max(DP[1], DP[2]); - Arrays.fill(DP, 0); //reset - for (int i = nums.length - 2; i >= 0; i--) { - if (i + 3 < nums.length) - DP[i] = Math.max(nums[i] + DP[i + 2], nums[i] + DP[i + 3]); - else if (i + 2 < nums.length) - DP[i] = nums[i] + DP[i + 2]; - else DP[i] = nums[i]; - } - max = Math.max(max, Math.max(DP[0], DP[1])); - return max; + public int rob(int[] nums) { + if (nums.length == 0) return 0; + if (nums.length == 1) return nums[0]; + else if (nums.length == 2) { + if (nums[0] > nums[1]) return nums[0]; + return nums[1]; + } else if (nums.length == 3) return Math.max(Math.max(nums[0], nums[1]), nums[2]); + int[] DP = new int[nums.length]; + for (int i = nums.length - 1; i > 0; i--) { + if (i + 3 < nums.length) DP[i] = Math.max(nums[i] + DP[i + 2], nums[i] + DP[i + 3]); + else if (i + 2 < nums.length) DP[i] = nums[i] + DP[i + 2]; + else DP[i] = nums[i]; + } + int max = Math.max(DP[1], DP[2]); + Arrays.fill(DP, 0); // reset + for (int i = nums.length - 2; i >= 0; i--) { + if (i + 3 < nums.length) DP[i] = Math.max(nums[i] + DP[i + 2], nums[i] + DP[i + 3]); + else if (i + 2 < nums.length) DP[i] = nums[i] + DP[i + 2]; + else DP[i] = nums[i]; } + max = Math.max(max, Math.max(DP[0], DP[1])); + return max; + } } diff --git a/problems/src/dynamic_programming/KnightProbabilityInChessboard.java b/problems/src/dynamic_programming/KnightProbabilityInChessboard.java index 02b9319a..34afbea9 100644 --- a/problems/src/dynamic_programming/KnightProbabilityInChessboard.java +++ b/problems/src/dynamic_programming/KnightProbabilityInChessboard.java @@ -3,75 +3,70 @@ import java.util.Arrays; /** - * Created by gouthamvidyapradhan on 13/02/2018. - * On an NxN chessboard, a knight starts at the r-th row and c-th column and attempts to make exactly K moves. - * The rows and columns are 0 indexed, so the top-left square is (0, 0), and the bottom-right square is (N-1, N-1). - - A chess knight has 8 possible moves it can make, as illustrated below. Each move is two squares in a cardinal - direction, then one square in an orthogonal direction. - - - Each time the knight is to move, it chooses one of eight possible moves uniformly at random - (even if the piece would go off the chessboard) and moves there. - - The knight continues moving until it has made exactly K moves or has moved off the chessboard. - Return the probability that the knight remains on the board after it has stopped moving. - - Example: - Input: 3, 2, 0, 0 - Output: 0.0625 - Explanation: There are two moves (to (1,2), (2,1)) that will keep the knight on the board. - From each of those positions, there are also two moves that will keep the knight on the board. - The total probability the knight stays on the board is 0.0625. - Note: - N will be between 1 and 25. - K will be between 0 and 100. - The knight always initially starts on the board. - - Solution: Solution O(N ^ 2 x K) DP top down memoization for each different states. + * Created by gouthamvidyapradhan on 13/02/2018. On an NxN chessboard, a knight starts at the r-th + * row and c-th column and attempts to make exactly K moves. The rows and columns are 0 indexed, so + * the top-left square is (0, 0), and the bottom-right square is (N-1, N-1). + * + *

A chess knight has 8 possible moves it can make, as illustrated below. Each move is two + * squares in a cardinal direction, then one square in an orthogonal direction. + * + *

Each time the knight is to move, it chooses one of eight possible moves uniformly at random + * (even if the piece would go off the chessboard) and moves there. + * + *

The knight continues moving until it has made exactly K moves or has moved off the chessboard. + * Return the probability that the knight remains on the board after it has stopped moving. + * + *

Example: Input: 3, 2, 0, 0 Output: 0.0625 Explanation: There are two moves (to (1,2), (2,1)) + * that will keep the knight on the board. From each of those positions, there are also two moves + * that will keep the knight on the board. The total probability the knight stays on the board is + * 0.0625. Note: N will be between 1 and 25. K will be between 0 and 100. The knight always + * initially starts on the board. + * + *

Solution: Solution O(N ^ 2 x K) DP top down memoization for each different states. */ public class KnightProbabilityInChessboard { - int[] R = {1, -1, 2, -2, -1, -2, 2, 1}; - int[] C = {2, 2, 1, 1, -2, -1, -1, -2}; + int[] R = {1, -1, 2, -2, -1, -2, 2, 1}; + int[] C = {2, 2, 1, 1, -2, -1, -1, -2}; - double[][][] dp; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new KnightProbabilityInChessboard().knightProbability(3, 2, 0, 0)); - } + double[][][] dp; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new KnightProbabilityInChessboard().knightProbability(3, 2, 0, 0)); + } - public double knightProbability(int N, int K, int r, int c) { - dp = new double[N][N][K + 1]; - for(int i = 0; i < N; i ++){ - for(int j = 0; j < N; j ++){ - Arrays.fill(dp[i][j], -1.0D); - } - } - for(int i = 0; i < N; i ++){ - for(int j = 0; j < N; j ++){ - dp[i][j][0] = 1.0D; - } - } - return dp(dp, r, c, K, N); + public double knightProbability(int N, int K, int r, int c) { + dp = new double[N][N][K + 1]; + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + Arrays.fill(dp[i][j], -1.0D); + } + } + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + dp[i][j][0] = 1.0D; + } } + return dp(dp, r, c, K, N); + } - private double dp(double[][][] dp, int r, int c, int K, int N){ - if(r < 0 || r >= N || c < 0 || c >= N) return 0.0D; - if(dp[r][c][K] != -1.0D) return dp[r][c][K]; - double sum = 0.0D; - for(int i = 0; i < 8; i ++){ - int newR = r + R[i]; - int newC = c + C[i]; - if(newR >= 0 && newR < N && newC >= 0 && newC < N){ - sum += dp(dp, newR, newC, K - 1, N); - } - } - dp[r][c][K] = (sum / 8.0); - return dp[r][c][K]; + private double dp(double[][][] dp, int r, int c, int K, int N) { + if (r < 0 || r >= N || c < 0 || c >= N) return 0.0D; + if (dp[r][c][K] != -1.0D) return dp[r][c][K]; + double sum = 0.0D; + for (int i = 0; i < 8; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 && newR < N && newC >= 0 && newC < N) { + sum += dp(dp, newR, newC, K - 1, N); + } } + dp[r][c][K] = (sum / 8.0); + return dp[r][c][K]; + } } diff --git a/problems/src/dynamic_programming/LargestPlusSign.java b/problems/src/dynamic_programming/LargestPlusSign.java index 0a85f70d..11206209 100644 --- a/problems/src/dynamic_programming/LargestPlusSign.java +++ b/problems/src/dynamic_programming/LargestPlusSign.java @@ -1,158 +1,130 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 20/01/2018. - * In a 2D grid from (0, 0) to (N-1, N-1), every cell contains a 1, except those cells in the given list mines which - * are 0. What is the largest axis-aligned plus sign of 1s contained in the grid? Return the order of the plus sign. - * If there is none, return 0. - - An "axis-aligned plus sign of 1s of order k" has some center grid[x][y] = 1 along with 4 arms of length k-1 going - up, down, left, and right, and made of 1s. This is demonstrated in the diagrams below. Note that there could be 0s - or 1s beyond the arms of the plus sign, only the relevant area of the plus sign is checked for 1s. - - Examples of Axis-Aligned Plus Signs of Order k: - - Order 1: - 000 - 010 - 000 - - Order 2: - 00000 - 00100 - 01110 - 00100 - 00000 - - Order 3: - 0000000 - 0001000 - 0001000 - 0111110 - 0001000 - 0001000 - 0000000 - Example 1: - - Input: N = 5, mines = [[4, 2]] - Output: 2 - Explanation: - 11111 - 11111 - 11111 - 11111 - 11011 - In the above grid, the largest plus sign can only be order 2. One of them is marked in bold. - Example 2: - - Input: N = 2, mines = [] - Output: 1 - Explanation: - There is no plus sign of order 2, but there is of order 1. - Example 3: - - Input: N = 1, mines = [[0, 0]] - Output: 0 - Explanation: - There is no plus sign, so return 0. - Note: - - N will be an integer in the range [1, 500]. - mines will have length at most 5000. - mines[i] will be length 2 and consist of integers in the range [0, N-1]. - (Additionally, programs submitted in C, C++, or C# will be judged with a slightly smaller time limit.) - - Solution O(N x N) for each cell containing 1 find the nearest cell containing 0 in both vertical and horizontal - direction - save this value in a 2d array for each cell. The answer is max value saved in 2d array. + * Created by gouthamvidyapradhan on 20/01/2018. In a 2D grid from (0, 0) to (N-1, N-1), every cell + * contains a 1, except those cells in the given list mines which are 0. What is the largest + * axis-aligned plus sign of 1s contained in the grid? Return the order of the plus sign. If there + * is none, return 0. + * + *

An "axis-aligned plus sign of 1s of order k" has some center grid[x][y] = 1 along with 4 arms + * of length k-1 going up, down, left, and right, and made of 1s. This is demonstrated in the + * diagrams below. Note that there could be 0s or 1s beyond the arms of the plus sign, only the + * relevant area of the plus sign is checked for 1s. + * + *

Examples of Axis-Aligned Plus Signs of Order k: + * + *

Order 1: 000 010 000 + * + *

Order 2: 00000 00100 01110 00100 00000 + * + *

Order 3: 0000000 0001000 0001000 0111110 0001000 0001000 0000000 Example 1: + * + *

Input: N = 5, mines = [[4, 2]] Output: 2 Explanation: 11111 11111 11111 11111 11011 In the + * above grid, the largest plus sign can only be order 2. One of them is marked in bold. Example 2: + * + *

Input: N = 2, mines = [] Output: 1 Explanation: There is no plus sign of order 2, but there is + * of order 1. Example 3: + * + *

Input: N = 1, mines = [[0, 0]] Output: 0 Explanation: There is no plus sign, so return 0. + * Note: + * + *

N will be an integer in the range [1, 500]. mines will have length at most 5000. mines[i] will + * be length 2 and consist of integers in the range [0, N-1]. (Additionally, programs submitted in + * C, C++, or C# will be judged with a slightly smaller time limit.) + * + *

Solution O(N x N) for each cell containing 1 find the nearest cell containing 0 in both + * vertical and horizontal direction - save this value in a 2d array for each cell. The answer is + * max value saved in 2d array. */ public class LargestPlusSign { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[][] M = {{4, 2}}; - System.out.println(new LargestPlusSign().orderOfLargestPlusSign(5, M)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[][] M = {{4, 2}}; + System.out.println(new LargestPlusSign().orderOfLargestPlusSign(5, M)); + } - public int orderOfLargestPlusSign(int N, int[][] mines) { - int[][] A = new int[N][N]; //array to save the mines information. - int[][] B = new int[N][N]; //array to save the minimum distance to the cell containing 0 - for(int[] row : mines){ - int r = row[0]; - int c = row[1]; - A[r][c] = 1; + public int orderOfLargestPlusSign(int N, int[][] mines) { + int[][] A = new int[N][N]; // array to save the mines information. + int[][] B = new int[N][N]; // array to save the minimum distance to the cell containing 0 + for (int[] row : mines) { + int r = row[0]; + int c = row[1]; + A[r][c] = 1; + } + for (int i = 0; i < A.length; i++) { + for (int j = 0; j < A[0].length; j++) { + if (A[i][j] == 0) { + A[i][j] = 1; + } else { + A[i][j] = 0; } - for(int i = 0; i < A.length; i ++){ - for(int j = 0; j < A[0].length; j++){ - if(A[i][j] == 0){ - A[i][j] = 1; - } else{ - A[i][j] = 0; - } - B[i][j] = Integer.MAX_VALUE; - } + B[i][j] = Integer.MAX_VALUE; + } + } + // For each rwo + for (int i = 0; i < A.length; i++) { + int prev = 0; + // forward direction + for (int j = 0; j < A[0].length; j++) { + if (A[i][j] == 0) { + prev = 0; + B[i][j] = 0; + } else { + prev++; + B[i][j] = Math.min(B[i][j], prev); } - //For each rwo - for(int i = 0; i < A.length; i ++){ - int prev = 0; - //forward direction - for(int j = 0; j < A[0].length; j ++){ - if(A[i][j] == 0){ - prev = 0; - B[i][j] = 0; - } else{ - prev++; - B[i][j] = Math.min(B[i][j], prev); - } - } - prev = 0; - //backward direction - for(int j = N - 1; j >= 0; j --){ - if(A[i][j] == 0){ - prev = 0; - B[i][j] = 0; - } else{ - prev++; - B[i][j] = Math.min(B[i][j], prev); - } - } + } + prev = 0; + // backward direction + for (int j = N - 1; j >= 0; j--) { + if (A[i][j] == 0) { + prev = 0; + B[i][j] = 0; + } else { + prev++; + B[i][j] = Math.min(B[i][j], prev); } + } + } - //for each column - for(int j = 0; j < B[0].length; j ++){ - int prev = 0; - //downward direction - for(int i = 0; i < B.length; i ++){ - if(A[i][j] == 0){ - prev = 0; - B[i][j] = 0; - } else{ - prev++; - B[i][j] = Math.min(B[i][j], prev); - } - } - prev = 0; - //upward direction - for(int i = N - 1; i >= 0; i --){ - if(A[i][j] == 0){ - prev = 0; - B[i][j] = 0; - } else{ - prev++; - B[i][j] = Math.min(B[i][j], prev); - } - } + // for each column + for (int j = 0; j < B[0].length; j++) { + int prev = 0; + // downward direction + for (int i = 0; i < B.length; i++) { + if (A[i][j] == 0) { + prev = 0; + B[i][j] = 0; + } else { + prev++; + B[i][j] = Math.min(B[i][j], prev); } - - int result = 0; - for(int i = 0; i < B.length; i++){ - for(int j = 0; j < B[0].length; j++){ - result = Math.max(result, B[i][j]); - } + } + prev = 0; + // upward direction + for (int i = N - 1; i >= 0; i--) { + if (A[i][j] == 0) { + prev = 0; + B[i][j] = 0; + } else { + prev++; + B[i][j] = Math.min(B[i][j], prev); } - return result; + } + } + + int result = 0; + for (int i = 0; i < B.length; i++) { + for (int j = 0; j < B[0].length; j++) { + result = Math.max(result, B[i][j]); + } } + return result; + } } diff --git a/problems/src/dynamic_programming/LargestSumOfAverages.java b/problems/src/dynamic_programming/LargestSumOfAverages.java index 11f149c7..2b63ef84 100644 --- a/problems/src/dynamic_programming/LargestSumOfAverages.java +++ b/problems/src/dynamic_programming/LargestSumOfAverages.java @@ -1,65 +1,57 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 04/05/2018. - * We partition a row of numbers A into at most K adjacent (non-empty) groups, then our score is the sum of the average of each group. What is the largest score we can achieve? - - Note that our partition must use every number in A, and that scores are not necessarily integers. - - Example: - Input: - A = [9,1,2,3,9] - K = 3 - Output: 20 - Explanation: - The best choice is to partition A into [9], [1, 2, 3], [9]. The answer is 9 + (1 + 2 + 3) / 3 + 9 = 20. - We could have also partitioned A into [9, 1], [2], [3, 9], for example. - That partition would lead to a score of 5 + 2 + 6 = 13, which is worse. - - - Note: - - 1 <= A.length <= 100. - 1 <= A[i] <= 10000. - 1 <= K <= A.length. - Answers within 10^-6 of the correct answer will be accepted as correct. - - Solution: O(N x N x K): Calculate average for each sub-array starting from the right. + * Created by gouthamvidyapradhan on 04/05/2018. We partition a row of numbers A into at most K + * adjacent (non-empty) groups, then our score is the sum of the average of each group. What is the + * largest score we can achieve? + * + *

Note that our partition must use every number in A, and that scores are not necessarily + * integers. + * + *

Example: Input: A = [9,1,2,3,9] K = 3 Output: 20 Explanation: The best choice is to partition + * A into [9], [1, 2, 3], [9]. The answer is 9 + (1 + 2 + 3) / 3 + 9 = 20. We could have also + * partitioned A into [9, 1], [2], [3, 9], for example. That partition would lead to a score of 5 + + * 2 + 6 = 13, which is worse. + * + *

Note: + * + *

1 <= A.length <= 100. 1 <= A[i] <= 10000. 1 <= K <= A.length. Answers within 10^-6 of the + * correct answer will be accepted as correct. + * + *

Solution: O(N x N x K): Calculate average for each sub-array starting from the right. */ - public class LargestSumOfAverages { - public static void main(String[] args) { - int[] A = {9,1,2,3,9}; - System.out.println(new LargestSumOfAverages().largestSumOfAverages(A, 3)); + public static void main(String[] args) { + int[] A = {9, 1, 2, 3, 9}; + System.out.println(new LargestSumOfAverages().largestSumOfAverages(A, 3)); + } + + public double largestSumOfAverages(int[] A, int K) { + double[][] dp = new double[K][A.length]; + for (int i = dp[0].length - 1; i >= 0; i--) { + dp[0][i] = A[i]; + if (i + 1 < dp[0].length) { + dp[0][i] += dp[0][i + 1]; + } } - public double largestSumOfAverages(int[] A, int K) { - double[][] dp = new double[K][A.length]; - for(int i = dp[0].length - 1; i >= 0; i --){ - dp[0][i] = A[i]; - if(i + 1 < dp[0].length){ - dp[0][i] += dp[0][i + 1]; - } - } - - for(int i = dp[0].length - 1, j = 1; i >= 0; i --, j++){ - dp[0][i] = dp[0][i] / j; - } + for (int i = dp[0].length - 1, j = 1; i >= 0; i--, j++) { + dp[0][i] = dp[0][i] / j; + } - for(int i = dp[0].length - 1; i >= 0; i --){ - for(int j = 1; j < dp.length; j ++){ - double sum = 0.0D; - for(int k = i, c = 1; k < dp[0].length; k ++, c++){ - sum += A[k]; - if(k + 1 < dp[0].length){ - double avg = sum / c; - avg += dp[j - 1][k + 1]; - dp[j][i] = Math.max(dp[j][i], avg); - } - } - } + for (int i = dp[0].length - 1; i >= 0; i--) { + for (int j = 1; j < dp.length; j++) { + double sum = 0.0D; + for (int k = i, c = 1; k < dp[0].length; k++, c++) { + sum += A[k]; + if (k + 1 < dp[0].length) { + double avg = sum / c; + avg += dp[j - 1][k + 1]; + dp[j][i] = Math.max(dp[j][i], avg); + } } - return dp[K-1][0]; + } } - + return dp[K - 1][0]; + } } diff --git a/problems/src/dynamic_programming/LongestIncreasingSubsequence.java b/problems/src/dynamic_programming/LongestIncreasingSubsequence.java index db119e0d..e594a47e 100644 --- a/problems/src/dynamic_programming/LongestIncreasingSubsequence.java +++ b/problems/src/dynamic_programming/LongestIncreasingSubsequence.java @@ -1,42 +1,41 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 02/04/2017. - * Given an unsorted array of integers, find the length of longest increasing subsequence. - *

- * For example, - * Given [10, 9, 2, 5, 3, 7, 101, 18], - * The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length. - *

- * Your algorithm should run in O(n2) complexity. - *

- * Follow up: Could you improve it to O(n log n) time complexity? + * Created by gouthamvidyapradhan on 02/04/2017. Given an unsorted array of integers, find the + * length of longest increasing subsequence. + * + *

For example, Given [10, 9, 2, 5, 3, 7, 101, 18], The longest increasing subsequence is [2, 3, + * 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is + * only necessary for you to return the length. + * + *

Your algorithm should run in O(n2) complexity. + * + *

Follow up: Could you improve it to O(n log n) time complexity? */ public class LongestIncreasingSubsequence { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] nums = {9, 8, 7, 6}; - System.out.println(new LongestIncreasingSubsequence().lengthOfLIS(nums)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] nums = {9, 8, 7, 6}; + System.out.println(new LongestIncreasingSubsequence().lengthOfLIS(nums)); + } - public int lengthOfLIS(int[] nums) { - if (nums.length == 0) return 0; - int[] A = new int[nums.length]; - int max = Integer.MIN_VALUE; - for (int i = 0, l = nums.length; i < l; i++) { - int lis = 1; - for (int j = 0; j < i; j++) { - if (nums[i] > nums[j]) - lis = Math.max(lis, A[j] + 1); - } - A[i] = lis; - max = Math.max(max, A[i]); - } - return max; + public int lengthOfLIS(int[] nums) { + if (nums.length == 0) return 0; + int[] A = new int[nums.length]; + int max = Integer.MIN_VALUE; + for (int i = 0, l = nums.length; i < l; i++) { + int lis = 1; + for (int j = 0; j < i; j++) { + if (nums[i] > nums[j]) lis = Math.max(lis, A[j] + 1); + } + A[i] = lis; + max = Math.max(max, A[i]); } + return max; + } } diff --git a/problems/src/dynamic_programming/LongestPaliandromicSubstring.java b/problems/src/dynamic_programming/LongestPaliandromicSubstring.java index 5587dea1..da69442f 100644 --- a/problems/src/dynamic_programming/LongestPaliandromicSubstring.java +++ b/problems/src/dynamic_programming/LongestPaliandromicSubstring.java @@ -1,63 +1,61 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 24/02/2017. - * Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. - *

- * Example: - *

- * Input: "babad" - *

- * Output: "bab" - *

- * Note: "aba" is also a valid answer. - * Example: - *

- * Input: "cbbd" - *

- * Output: "bb" + * Created by gouthamvidyapradhan on 24/02/2017. Given a string s, find the longest palindromic + * substring in s. You may assume that the maximum length of s is 1000. + * + *

Example: + * + *

Input: "babad" + * + *

Output: "bab" + * + *

Note: "aba" is also a valid answer. Example: + * + *

Input: "cbbd" + * + *

Output: "bb" */ public class LongestPaliandromicSubstring { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new LongestPaliandromicSubstring().longestPalindrome("forgeeksskeegfor")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new LongestPaliandromicSubstring().longestPalindrome("forgeeksskeegfor")); + } - public String longestPalindrome(String s) { - int l = s.length(); - int startIndex = 0; - int maxLen = 1; - boolean[][] A = new boolean[l][l]; - for (int i = 0, j = 0; i < l; i++, j++) - A[i][j] = true; + public String longestPalindrome(String s) { + int l = s.length(); + int startIndex = 0; + int maxLen = 1; + boolean[][] A = new boolean[l][l]; + for (int i = 0, j = 0; i < l; i++, j++) A[i][j] = true; - for (int i = 0, j = i + 1; j < l; i++, j++) { - if (s.charAt(i) == s.charAt(j)) { - A[i][j] = true; - startIndex = i; - maxLen = 2; - } - } + for (int i = 0, j = i + 1; j < l; i++, j++) { + if (s.charAt(i) == s.charAt(j)) { + A[i][j] = true; + startIndex = i; + maxLen = 2; + } + } - for (int k = 3; k <= l; k++) { - for (int i = 0, j = k - 1; j < l; i++, j++) { - if (s.charAt(i) == s.charAt(j)) { - A[i][j] = A[i + 1][j - 1]; - if (A[i][j]) { - if (k > maxLen) { - startIndex = i; - maxLen = k; - } - } - } + for (int k = 3; k <= l; k++) { + for (int i = 0, j = k - 1; j < l; i++, j++) { + if (s.charAt(i) == s.charAt(j)) { + A[i][j] = A[i + 1][j - 1]; + if (A[i][j]) { + if (k > maxLen) { + startIndex = i; + maxLen = k; } + } } - - return s.substring(startIndex, startIndex + maxLen); + } } + + return s.substring(startIndex, startIndex + maxLen); + } } diff --git a/problems/src/dynamic_programming/LongestPalindromicSubsequence.java b/problems/src/dynamic_programming/LongestPalindromicSubsequence.java index b450687a..d49d6a1b 100644 --- a/problems/src/dynamic_programming/LongestPalindromicSubsequence.java +++ b/problems/src/dynamic_programming/LongestPalindromicSubsequence.java @@ -1,37 +1,39 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 27/03/2017. - * Given an unsorted array of integers, find the length of longest increasing subsequence. - *

- * For example, - * Given [10, 9, 2, 5, 3, 7, 101, 18], - * The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length. - *

- * Your algorithm should run in O(n2) complexity. - *

- * Follow up: Could you improve it to O(n log n) time complexity? + * Created by gouthamvidyapradhan on 27/03/2017. Given an unsorted array of integers, find the + * length of longest increasing subsequence. + * + *

For example, Given [10, 9, 2, 5, 3, 7, 101, 18], The longest increasing subsequence is [2, 3, + * 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is + * only necessary for you to return the length. + * + *

Your algorithm should run in O(n2) complexity. + * + *

Follow up: Could you improve it to O(n log n) time complexity? */ public class LongestPalindromicSubsequence { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new LongestPalindromicSubsequence().longestPalindromeSubseq("bbbab")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new LongestPalindromicSubsequence().longestPalindromeSubseq("bbbab")); + } - public int longestPalindromeSubseq(String s) { - int[][] dp = new int[s.length() + 1][s.length() + 1]; - String sI = new StringBuilder(s).reverse().toString(); - for (int i = 1, l = s.length(); i <= l; i++) - for (int j = 1; j <= l; j++) { - dp[i][j] = (s.charAt(i - 1) == sI.charAt(j - 1)) ? dp[i - 1][j - 1] + 1 : Math.max(dp[i - 1][j], dp[i][j - 1]); - } - - return dp[s.length()][s.length()]; - } + public int longestPalindromeSubseq(String s) { + int[][] dp = new int[s.length() + 1][s.length() + 1]; + String sI = new StringBuilder(s).reverse().toString(); + for (int i = 1, l = s.length(); i <= l; i++) + for (int j = 1; j <= l; j++) { + dp[i][j] = + (s.charAt(i - 1) == sI.charAt(j - 1)) + ? dp[i - 1][j - 1] + 1 + : Math.max(dp[i - 1][j], dp[i][j - 1]); + } + return dp[s.length()][s.length()]; + } } diff --git a/problems/src/dynamic_programming/MaxSum3SubArray.java b/problems/src/dynamic_programming/MaxSum3SubArray.java index 71152d16..b57f4ec1 100644 --- a/problems/src/dynamic_programming/MaxSum3SubArray.java +++ b/problems/src/dynamic_programming/MaxSum3SubArray.java @@ -1,124 +1,121 @@ package dynamic_programming; /** * Created by gouthamvidyapradhan on 22/11/2017. - - In a given array nums of positive integers, find three non-overlapping subarrays with maximum sum. - - Each subarray will be of size k, and we want to maximize the sum of all 3*k entries. - - Return the result as a list of indices representing the starting position of each interval (0-indexed). If there are multiple answers, return the lexicographically smallest one. - - Example: - Input: [1,2,1,2,6,7,5,1], 2 - Output: [0, 3, 5] - Explanation: Subarrays [1, 2], [2, 6], [7, 5] correspond to the starting indices [0, 3, 5]. - We could have also taken [2, 1], but an answer of [1, 3, 5] would be lexicographically larger. - Note: - nums.length will be between 1 and 20000. - nums[i] will be between 1 and 65535. - k will be between 1 and floor(nums.length / 3). - - Solution: - O(N) solution by prefix and reverse-prefix sum - First calculate max index for array index k, then use this to calculate max index for two array indices j and k and - again use this result to calculate the final max index for i, j and k for the 3 arrays. - + * + *

In a given array nums of positive integers, find three non-overlapping subarrays with maximum + * sum. + * + *

Each subarray will be of size k, and we want to maximize the sum of all 3*k entries. + * + *

Return the result as a list of indices representing the starting position of each interval + * (0-indexed). If there are multiple answers, return the lexicographically smallest one. + * + *

Example: Input: [1,2,1,2,6,7,5,1], 2 Output: [0, 3, 5] Explanation: Subarrays [1, 2], [2, 6], + * [7, 5] correspond to the starting indices [0, 3, 5]. We could have also taken [2, 1], but an + * answer of [1, 3, 5] would be lexicographically larger. Note: nums.length will be between 1 and + * 20000. nums[i] will be between 1 and 65535. k will be between 1 and floor(nums.length / 3). + * + *

Solution: O(N) solution by prefix and reverse-prefix sum First calculate max index for array + * index k, then use this to calculate max index for two array indices j and k and again use this + * result to calculate the final max index for i, j and k for the 3 arrays. */ public class MaxSum3SubArray { - class Max{ - int i, j, k, max; - Max(int i, int max){ - this.i = i; - this.max = max; - } - Max(int i, int j, int max){ - this.i = i; - this.j = j; - this.max = max; - } + class Max { + int i, j, k, max; + + Max(int i, int max) { + this.i = i; + this.max = max; } - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1,2,1,2,6}; - int[] result = new MaxSum3SubArray().maxSumOfThreeSubarrays(A, 1); - for (int i = 0; i < result.length; i ++) - System.out.print(result[i] + " "); + Max(int i, int j, int max) { + this.i = i; + this.j = j; + this.max = max; } + } - public int[] maxSumOfThreeSubarrays(int[] nums, int k) { - int[] fPrefix = new int[nums.length]; //forward prefix sum - int[] rPrefix = new int[nums.length]; //reverse prefix sum + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 2, 1, 2, 6}; + int[] result = new MaxSum3SubArray().maxSumOfThreeSubarrays(A, 1); + for (int i = 0; i < result.length; i++) System.out.print(result[i] + " "); + } - //calculate forward prefix sum - for(int i = 0; i < k; i ++){ - fPrefix[0] += nums[i]; - } - for(int i = 1; i < nums.length; i ++){ - if(i + k - 1 < nums.length){ - fPrefix[i] = fPrefix[i - 1] - nums[i - 1] + nums[i + k - 1]; - } - } - int sum = 0; - for(int i = nums.length - 1; i >= nums.length - k; i --){ - sum += nums[i]; - } - Max[] max1 = new Max[nums.length]; - max1[nums.length - k] = new Max(nums.length - k, sum); + public int[] maxSumOfThreeSubarrays(int[] nums, int k) { + int[] fPrefix = new int[nums.length]; // forward prefix sum + int[] rPrefix = new int[nums.length]; // reverse prefix sum - //calculate reverse prefix sum - rPrefix[nums.length - k] = sum; - for(int i = nums.length - 1; i >= 0; i --){ - if(i + k >= nums.length) continue; - rPrefix[i] = rPrefix[i + 1] - nums[i + k] + nums[i]; - } + // calculate forward prefix sum + for (int i = 0; i < k; i++) { + fPrefix[0] += nums[i]; + } + for (int i = 1; i < nums.length; i++) { + if (i + k - 1 < nums.length) { + fPrefix[i] = fPrefix[i - 1] - nums[i - 1] + nums[i + k - 1]; + } + } + int sum = 0; + for (int i = nums.length - 1; i >= nums.length - k; i--) { + sum += nums[i]; + } + Max[] max1 = new Max[nums.length]; + max1[nums.length - k] = new Max(nums.length - k, sum); - //calculate max for k index - for(int i = nums.length - 1; i >= 0; i --){ - if(i + k >= nums.length) continue; - max1[i] = new Max(i, rPrefix[i]); - if(max1[i + 1] != null){ - if(max1[i].max < max1[i + 1].max){ - max1[i] = new Max(max1[i + 1].i, max1[i + 1].max); - } - } - } + // calculate reverse prefix sum + rPrefix[nums.length - k] = sum; + for (int i = nums.length - 1; i >= 0; i--) { + if (i + k >= nums.length) continue; + rPrefix[i] = rPrefix[i + 1] - nums[i + k] + nums[i]; + } - //calculate max for j and k index - Max[] max2 = new Max[nums.length]; - for(int i = nums.length - 1; i >= 0; i --){ - if(i + k < nums.length && max1[i + k] != null){ - max2[i] = new Max(i, max1[i + k].i, fPrefix[i] + max1[i + k].max); - } - } - for(int i = nums.length - 1; i >= 0; i --){ - if(i + 1 > nums.length - 1 || max2[i + 1] == null) continue; - if(max2[i].max < max2[i + 1].max){ - max2[i].max = max2[i + 1].max; - max2[i].i = max2[i + 1].i; - max2[i].j = max2[i + 1].j; - } + // calculate max for k index + for (int i = nums.length - 1; i >= 0; i--) { + if (i + k >= nums.length) continue; + max1[i] = new Max(i, rPrefix[i]); + if (max1[i + 1] != null) { + if (max1[i].max < max1[i + 1].max) { + max1[i] = new Max(max1[i + 1].i, max1[i + 1].max); } + } + } + + // calculate max for j and k index + Max[] max2 = new Max[nums.length]; + for (int i = nums.length - 1; i >= 0; i--) { + if (i + k < nums.length && max1[i + k] != null) { + max2[i] = new Max(i, max1[i + k].i, fPrefix[i] + max1[i + k].max); + } + } + for (int i = nums.length - 1; i >= 0; i--) { + if (i + 1 > nums.length - 1 || max2[i + 1] == null) continue; + if (max2[i].max < max2[i + 1].max) { + max2[i].max = max2[i + 1].max; + max2[i].i = max2[i + 1].i; + max2[i].j = max2[i + 1].j; + } + } - //calculate max for i, j and k index - int[] result = new int[3]; - int max = 0; - for(int i = 0; i < nums.length; i ++){ - if((i + k) < nums.length - 1 && max2[i + k] != null){ - int temp = fPrefix[i] + max2[i + k].max; - if(temp > max){ - max = temp; - result[0] = i; - result[1] = max2[i + k].i; - result[2] = max2[i + k].j; - } - } + // calculate max for i, j and k index + int[] result = new int[3]; + int max = 0; + for (int i = 0; i < nums.length; i++) { + if ((i + k) < nums.length - 1 && max2[i + k] != null) { + int temp = fPrefix[i] + max2[i + k].max; + if (temp > max) { + max = temp; + result[0] = i; + result[1] = max2[i + k].i; + result[2] = max2[i + k].j; } - return result; + } } -} \ No newline at end of file + return result; + } +} diff --git a/problems/src/dynamic_programming/MaximalSquare.java b/problems/src/dynamic_programming/MaximalSquare.java index c8b367ec..c87eb9da 100644 --- a/problems/src/dynamic_programming/MaximalSquare.java +++ b/problems/src/dynamic_programming/MaximalSquare.java @@ -1,52 +1,53 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 28/11/2017. - * Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area. - - For example, given the following matrix: - - 1 0 1 0 0 - 1 0 1 1 1 - 1 1 1 1 1 - 1 0 0 1 0 - Return 4. - - Solution: O(n * m) time and space complexity. - Calculate the max length of a square using DP(i, j) = min(DP[i - 1][j], DP[i][j - 1], DP[i - 1][j - 1]) + 1 - Return the square of the answer. + * Created by gouthamvidyapradhan on 28/11/2017. Given a 2D binary matrix filled with 0's and 1's, + * find the largest square containing only 1's and return its area. + * + *

For example, given the following matrix: + * + *

1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 Return 4. + * + *

Solution: O(n * m) time and space complexity. Calculate the max length of a square using DP(i, + * j) = min(DP[i - 1][j], DP[i][j - 1], DP[i - 1][j - 1]) + 1 Return the square of the answer. */ public class MaximalSquare { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - char[][] A = {{'1','0','1','0','0'}, {'1','0','1','1','1'}, {'1','1','1','1','1'}, {'1','0','0','1','0'}}; - System.out.println(new MaximalSquare().maximalSquare(A)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + char[][] A = { + {'1', '0', '1', '0', '0'}, + {'1', '0', '1', '1', '1'}, + {'1', '1', '1', '1', '1'}, + {'1', '0', '0', '1', '0'} + }; + System.out.println(new MaximalSquare().maximalSquare(A)); + } - public int maximalSquare(char[][] matrix) { - if(matrix.length == 0) return 0; - int[][] dp = new int[matrix.length][matrix[0].length]; - for(int i = 0; i < matrix.length; i ++){ - for(int j = 0; j < matrix[0].length; j++){ - if(j - 1 >= 0 && i - 1 >= 0){ - if(matrix[i][j] == '1'){ - dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]); - dp[i][j] = Math.min(dp[i][j], dp[i - 1][j - 1]) + 1; - } - } else { - dp[i][j] = matrix[i][j] == '1' ? 1 : 0; - } - } - } - int max = 0; - for(int i = 0; i < dp.length; i++){ - for(int j = 0; j < dp[0].length; j++){ - max = Math.max(max, dp[i][j]); - } + public int maximalSquare(char[][] matrix) { + if (matrix.length == 0) return 0; + int[][] dp = new int[matrix.length][matrix[0].length]; + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix[0].length; j++) { + if (j - 1 >= 0 && i - 1 >= 0) { + if (matrix[i][j] == '1') { + dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]); + dp[i][j] = Math.min(dp[i][j], dp[i - 1][j - 1]) + 1; + } + } else { + dp[i][j] = matrix[i][j] == '1' ? 1 : 0; } - return max * max; + } + } + int max = 0; + for (int i = 0; i < dp.length; i++) { + for (int j = 0; j < dp[0].length; j++) { + max = Math.max(max, dp[i][j]); + } } + return max * max; + } } diff --git a/problems/src/dynamic_programming/MaximumProductSubarray.java b/problems/src/dynamic_programming/MaximumProductSubarray.java index ee14e793..ae67a77c 100644 --- a/problems/src/dynamic_programming/MaximumProductSubarray.java +++ b/problems/src/dynamic_programming/MaximumProductSubarray.java @@ -1,35 +1,35 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 02/04/2017. - * Find the contiguous subarray within an array (containing at least one number) which has the largest product. - *

- * For example, given the array [2,3,-2,4], - * the contiguous subarray [2,3] has the largest product = 6. + * Created by gouthamvidyapradhan on 02/04/2017. Find the contiguous subarray within an array + * (containing at least one number) which has the largest product. + * + *

For example, given the array [2,3,-2,4], the contiguous subarray [2,3] has the largest product + * = 6. */ public class MaximumProductSubarray { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] A = {2, 3, -2, 4}; - System.out.println(new MaximumProductSubarray().maxProduct(A)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {2, 3, -2, 4}; + System.out.println(new MaximumProductSubarray().maxProduct(A)); + } - public int maxProduct(int[] nums) { - if (nums.length == 1) return nums[0]; - int min = nums[0]; - int max = nums[0]; - int result = max; - for (int i = 1; i < nums.length; i++) { - int prevMin = min, prevMax = max; - min = Math.min(nums[i], Math.min(nums[i] * prevMin, nums[i] * prevMax)); - max = Math.max(nums[i], Math.max(nums[i] * prevMin, nums[i] * prevMax)); - result = Math.max(result, max); - } - return result; + public int maxProduct(int[] nums) { + if (nums.length == 1) return nums[0]; + int min = nums[0]; + int max = nums[0]; + int result = max; + for (int i = 1; i < nums.length; i++) { + int prevMin = min, prevMax = max; + min = Math.min(nums[i], Math.min(nums[i] * prevMin, nums[i] * prevMax)); + max = Math.max(nums[i], Math.max(nums[i] * prevMin, nums[i] * prevMax)); + result = Math.max(result, max); } + return result; + } } diff --git a/problems/src/dynamic_programming/MaximumSubarray.java b/problems/src/dynamic_programming/MaximumSubarray.java index 2a122c31..c51abb4b 100644 --- a/problems/src/dynamic_programming/MaximumSubarray.java +++ b/problems/src/dynamic_programming/MaximumSubarray.java @@ -1,26 +1,25 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 07/07/2017. - * Find the contiguous subarray within an array (containing at least one number) which has the largest sum. - *

- * For example, given the array [-2,1,-3,4,-1,2,1,-5,4], - * the contiguous subarray [4,-1,2,1] has the largest sum = 6. + * Created by gouthamvidyapradhan on 07/07/2017. Find the contiguous subarray within an array + * (containing at least one number) which has the largest sum. + * + *

For example, given the array [-2,1,-3,4,-1,2,1,-5,4], the contiguous subarray [4,-1,2,1] has + * the largest sum = 6. */ public class MaximumSubarray { - public static void main(String[] args) throws Exception { - int[] nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; - System.out.println(new MaximumSubarray().maxSubArray(nums)); - } + public static void main(String[] args) throws Exception { + int[] nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; + System.out.println(new MaximumSubarray().maxSubArray(nums)); + } - public int maxSubArray(int[] nums) { - if (nums.length == 1) return nums[0]; - int max = nums[nums.length - 1]; - for (int i = nums.length - 2; i >= 0; i--) { - nums[i] = Math.max(nums[i], nums[i] + nums[i + 1]); - max = Math.max(max, nums[i]); - } - return max; + public int maxSubArray(int[] nums) { + if (nums.length == 1) return nums[0]; + int max = nums[nums.length - 1]; + for (int i = nums.length - 2; i >= 0; i--) { + nums[i] = Math.max(nums[i], nums[i] + nums[i + 1]); + max = Math.max(max, nums[i]); } - + return max; + } } diff --git a/problems/src/dynamic_programming/MaximumVacationDays.java b/problems/src/dynamic_programming/MaximumVacationDays.java index f5868c3a..5f57de6a 100644 --- a/problems/src/dynamic_programming/MaximumVacationDays.java +++ b/problems/src/dynamic_programming/MaximumVacationDays.java @@ -3,108 +3,92 @@ /** * Created by gouthamvidyapradhan on 13/04/2019 * - * LeetCode wants to give one of its best employees the option to travel among N cities to collect algorithm - * problems. But all work and no play makes Jack a dull boy, you could take vacations in some particular cities and - * weeks. Your job is to schedule the traveling to maximize the number of vacation days you could take, but there are - * certain rules and restrictions you need to follow. + *

LeetCode wants to give one of its best employees the option to travel among N cities to + * collect algorithm problems. But all work and no play makes Jack a dull boy, you could take + * vacations in some particular cities and weeks. Your job is to schedule the traveling to maximize + * the number of vacation days you could take, but there are certain rules and restrictions you need + * to follow. * - * Rules and restrictions: - * You can only travel among N cities, represented by indexes from 0 to N-1. Initially, you are in the city indexed 0 - * on Monday. - * The cities are connected by flights. The flights are represented as a N*N matrix (not necessary symmetrical), - * called flights representing the airline status from the city i to the city j. If there is no flight from the city - * i to the city j, flights[i][j] = 0; Otherwise, flights[i][j] = 1. Also, flights[i][i] = 0 for all i. - * You totally have K weeks (each week has 7 days) to travel. You can only take flights at most once per day and can - * only take flights on each week's Monday morning. Since flight time is so short, we don't consider the impact of - * flight time. - * For each city, you can only have restricted vacation days in different weeks, given an N*K matrix called days - * representing this relationship. For the value of days[i][j], it represents the maximum days you could take - * vacation in the city i in the week j. - * You're given the flights matrix and days matrix, and you need to output the maximum vacation days you could take - * during K weeks. + *

Rules and restrictions: You can only travel among N cities, represented by indexes from 0 to + * N-1. Initially, you are in the city indexed 0 on Monday. The cities are connected by flights. The + * flights are represented as a N*N matrix (not necessary symmetrical), called flights representing + * the airline status from the city i to the city j. If there is no flight from the city i to the + * city j, flights[i][j] = 0; Otherwise, flights[i][j] = 1. Also, flights[i][i] = 0 for all i. You + * totally have K weeks (each week has 7 days) to travel. You can only take flights at most once per + * day and can only take flights on each week's Monday morning. Since flight time is so short, we + * don't consider the impact of flight time. For each city, you can only have restricted vacation + * days in different weeks, given an N*K matrix called days representing this relationship. For the + * value of days[i][j], it represents the maximum days you could take vacation in the city i in the + * week j. You're given the flights matrix and days matrix, and you need to output the maximum + * vacation days you could take during K weeks. * - * Example 1: - * Input:flights = [[0,1,1],[1,0,1],[1,1,0]], days = [[1,3,1],[6,0,3],[3,3,3]] - * Output: 12 - * Explanation: - * Ans = 6 + 3 + 3 = 12. + *

Example 1: Input:flights = [[0,1,1],[1,0,1],[1,1,0]], days = [[1,3,1],[6,0,3],[3,3,3]] Output: + * 12 Explanation: Ans = 6 + 3 + 3 = 12. * - * One of the best strategies is: - * 1st week : fly from city 0 to city 1 on Monday, and play 6 days and work 1 day. - * (Although you start at city 0, we could also fly to and start at other cities since it is Monday.) - * 2nd week : fly from city 1 to city 2 on Monday, and play 3 days and work 4 days. - * 3rd week : stay at city 2, and play 3 days and work 4 days. - * Example 2: - * Input:flights = [[0,0,0],[0,0,0],[0,0,0]], days = [[1,1,1],[7,7,7],[7,7,7]] - * Output: 3 - * Explanation: - * Ans = 1 + 1 + 1 = 3. + *

One of the best strategies is: 1st week : fly from city 0 to city 1 on Monday, and play 6 days + * and work 1 day. (Although you start at city 0, we could also fly to and start at other cities + * since it is Monday.) 2nd week : fly from city 1 to city 2 on Monday, and play 3 days and work 4 + * days. 3rd week : stay at city 2, and play 3 days and work 4 days. Example 2: Input:flights = + * [[0,0,0],[0,0,0],[0,0,0]], days = [[1,1,1],[7,7,7],[7,7,7]] Output: 3 Explanation: Ans = 1 + 1 + + * 1 = 3. * - * Since there is no flights enable you to move to another city, you have to stay at city 0 for the whole 3 weeks. - * For each week, you only have one day to play and six days to work. - * So the maximum number of vacation days is 3. - * Example 3: - * Input:flights = [[0,1,1],[1,0,1],[1,1,0]], days = [[7,0,0],[0,7,0],[0,0,7]] - * Output: 21 - * Explanation: - * Ans = 7 + 7 + 7 = 21 + *

Since there is no flights enable you to move to another city, you have to stay at city 0 for + * the whole 3 weeks. For each week, you only have one day to play and six days to work. So the + * maximum number of vacation days is 3. Example 3: Input:flights = [[0,1,1],[1,0,1],[1,1,0]], days + * = [[7,0,0],[0,7,0],[0,0,7]] Output: 21 Explanation: Ans = 7 + 7 + 7 = 21 * - * One of the best strategies is: - * 1st week : stay at city 0, and play 7 days. - * 2nd week : fly from city 0 to city 1 on Monday, and play 7 days. - * 3rd week : fly from city 1 to city 2 on Monday, and play 7 days. - * Note: - * N and K are positive integers, which are in the range of [1, 100]. - * In the matrix flights, all the values are integers in the range of [0, 1]. - * In the matrix days, all the values are integers in the range [0, 7]. - * You could stay at a city beyond the number of vacation days, but you should work on the extra days, which won't be - * counted as vacation days. - * If you fly from the city A to the city B and take the vacation on that day, the deduction towards vacation days - * will count towards the vacation days of city B in that week. - * We don't consider the impact of flight hours towards the calculation of vacation days. + *

One of the best strategies is: 1st week : stay at city 0, and play 7 days. 2nd week : fly from + * city 0 to city 1 on Monday, and play 7 days. 3rd week : fly from city 1 to city 2 on Monday, and + * play 7 days. Note: N and K are positive integers, which are in the range of [1, 100]. In the + * matrix flights, all the values are integers in the range of [0, 1]. In the matrix days, all the + * values are integers in the range [0, 7]. You could stay at a city beyond the number of vacation + * days, but you should work on the extra days, which won't be counted as vacation days. If you fly + * from the city A to the city B and take the vacation on that day, the deduction towards vacation + * days will count towards the vacation days of city B in that week. We don't consider the impact of + * flight hours towards the calculation of vacation days. * - * Solution: - * O(N x N x K) - * Start from the last week K; Calculate for the last week maximum vacation days for all possible cities. - * Now, iteratively calculate backwards - * for each week K - 1 - * and for each city - * and for each available connection from the city - * memoize the maximum vacation days possible for this city - * Return the answer for city 0 and week 0 + *

Solution: O(N x N x K) Start from the last week K; Calculate for the last week maximum + * vacation days for all possible cities. Now, iteratively calculate backwards for each week K - 1 + * and for each city and for each available connection from the city memoize the maximum vacation + * days possible for this city Return the answer for city 0 and week 0 */ public class MaximumVacationDays { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int[][] flights = {{0,1,0,1,1},{1,0,0,1,1},{1,0,0,1,0},{0,1,0,0,0},{0,0,0,1,0}}; - int[][] days = {{0,4,1,6,6},{4,3,3,0,1},{3,6,6,5,0},{1,3,1,1,4},{5,3,3,3,4}}; - System.out.println(new MaximumVacationDays().maxVacationDays(flights, days)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[][] flights = { + {0, 1, 0, 1, 1}, {1, 0, 0, 1, 1}, {1, 0, 0, 1, 0}, {0, 1, 0, 0, 0}, {0, 0, 0, 1, 0} + }; + int[][] days = { + {0, 4, 1, 6, 6}, {4, 3, 3, 0, 1}, {3, 6, 6, 5, 0}, {1, 3, 1, 1, 4}, {5, 3, 3, 3, 4} + }; + System.out.println(new MaximumVacationDays().maxVacationDays(flights, days)); + } - public int maxVacationDays(int[][] flights, int[][] days) { - int N = days.length; - int W = days[0].length; - int[][] DP = new int[N][W + 1]; - for(int w = W - 1; w >= 0; w --){ - for(int n = 0; n < N; n ++){ - DP[n][w] = days[n][w] + DP[n][w + 1]; - } + public int maxVacationDays(int[][] flights, int[][] days) { + int N = days.length; + int W = days[0].length; + int[][] DP = new int[N][W + 1]; + for (int w = W - 1; w >= 0; w--) { + for (int n = 0; n < N; n++) { + DP[n][w] = days[n][w] + DP[n][w + 1]; + } - for(int n = 0; n < N; n ++){ - int max = Integer.MIN_VALUE; - int[] F = flights[n]; - for(int i = 0; i < F.length; i ++){ - if(F[i] == 1){ - max = Math.max(max, days[i][w] + DP[i][w + 1]); - } - } - DP[n][w] = Math.max(DP[n][w], max); - } + for (int n = 0; n < N; n++) { + int max = Integer.MIN_VALUE; + int[] F = flights[n]; + for (int i = 0; i < F.length; i++) { + if (F[i] == 1) { + max = Math.max(max, days[i][w] + DP[i][w + 1]); + } } - return DP[0][0]; + DP[n][w] = Math.max(DP[n][w], max); + } } + return DP[0][0]; + } } diff --git a/problems/src/dynamic_programming/MinCostClimbingStairs.java b/problems/src/dynamic_programming/MinCostClimbingStairs.java index 4a98498b..decdae74 100644 --- a/problems/src/dynamic_programming/MinCostClimbingStairs.java +++ b/problems/src/dynamic_programming/MinCostClimbingStairs.java @@ -1,37 +1,31 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 30/04/2018. - * On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). - - Once you pay the cost, you can either climb one or two steps. You need to find minimum cost to reach the top of the - floor, and you can either start from the step with index 0, or the step with index 1. - - Example 1: - Input: cost = [10, 15, 20] - Output: 15 - Explanation: Cheapest is start on cost[1], pay that cost and go to the top. - Example 2: - Input: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] - Output: 6 - Explanation: Cheapest is start on cost[0], and only step on 1s, skipping cost[3]. - Note: - cost will have a length in the range [2, 1000]. - Every cost[i] will be an integer in the range [0, 999]. - - Solution: O(N) At every step there are two options, either cost[i] + cost[i + 1] or cost[i] + cost[i + 2] + * Created by gouthamvidyapradhan on 30/04/2018. On a staircase, the i-th step has some non-negative + * cost cost[i] assigned (0 indexed). + * + *

Once you pay the cost, you can either climb one or two steps. You need to find minimum cost to + * reach the top of the floor, and you can either start from the step with index 0, or the step with + * index 1. + * + *

Example 1: Input: cost = [10, 15, 20] Output: 15 Explanation: Cheapest is start on cost[1], + * pay that cost and go to the top. Example 2: Input: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] + * Output: 6 Explanation: Cheapest is start on cost[0], and only step on 1s, skipping cost[3]. Note: + * cost will have a length in the range [2, 1000]. Every cost[i] will be an integer in the range [0, + * 999]. + * + *

Solution: O(N) At every step there are two options, either cost[i] + cost[i + 1] or cost[i] + + * cost[i + 2] */ public class MinCostClimbingStairs { - public static void main(String[] args) throws Exception{ - - } + public static void main(String[] args) throws Exception {} - public int minCostClimbingStairs(int[] cost) { - for(int i = cost.length - 1; i >= 0; i --){ - if(i + 1 < cost.length && i + 2 < cost.length){ - cost[i] = Math.min(cost[i] + cost[i + 1], cost[i] + cost[i + 2]); - } - } - return Math.min(cost[0], cost[1]); + public int minCostClimbingStairs(int[] cost) { + for (int i = cost.length - 1; i >= 0; i--) { + if (i + 1 < cost.length && i + 2 < cost.length) { + cost[i] = Math.min(cost[i] + cost[i + 1], cost[i] + cost[i + 2]); + } } + return Math.min(cost[0], cost[1]); + } } diff --git a/problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java b/problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java index 4c28dd8b..2c1026be 100644 --- a/problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java +++ b/problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java @@ -1,87 +1,78 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 24/07/2018. - * A car travels from a starting position to a destination which is target miles east of the starting position. - - Along the way, there are gas stations. Each station[i] represents a gas station that is station[i][0] miles east - of the starting position, and has station[i][1] liters of gas. - - The car starts with an infinite tank of gas, which initially has startFuel liters of fuel in it. It uses 1 liter of - gas per 1 mile that it drives. - - When the car reaches a gas station, it may stop and refuel, transferring all the gas from the station into the car. - - What is the least number of refueling stops the car must make in order to reach its destination? If it cannot reach - the destination, return -1. - - Note that if the car reaches a gas station with 0 fuel left, the car can still refuel there. If the car reaches the - destination with 0 fuel left, it is still considered to have arrived. - - - - Example 1: - - Input: target = 1, startFuel = 1, stations = [] - Output: 0 - Explanation: We can reach the target without refueling. - Example 2: - - Input: target = 100, startFuel = 1, stations = [[10,100]] - Output: -1 - Explanation: We can't reach the target (or even the first gas station). - Example 3: - - Input: target = 100, startFuel = 10, stations = [[10,60],[20,30],[30,30],[60,40]] - Output: 2 - Explanation: - We start with 10 liters of fuel. - We drive to position 10, expending 10 liters of fuel. We refuel from 0 liters to 60 liters of gas. - Then, we drive from position 10 to position 60 (expending 50 liters of fuel), - and refuel from 10 liters to 50 liters of gas. We then drive to and reach the target. - We made 2 refueling stops along the way, so we return 2. - - - Note: - - 1 <= target, startFuel, stations[i][1] <= 10^9 - 0 <= stations.length <= 500 - 0 < stations[0][0] < stations[1][0] < ... < stations[stations.length-1][0] < target - - Solution O(N ^ 2): Maintain a DP array with maximum distance that can be travelled with i stops. - DP[i] is the max distance that can be travelled with exactly i stops. - The minimum i where the target can be achieved (dp[i] >= target) will be the answer. + * Created by gouthamvidyapradhan on 24/07/2018. A car travels from a starting position to a + * destination which is target miles east of the starting position. + * + *

Along the way, there are gas stations. Each station[i] represents a gas station that is + * station[i][0] miles east of the starting position, and has station[i][1] liters of gas. + * + *

The car starts with an infinite tank of gas, which initially has startFuel liters of fuel in + * it. It uses 1 liter of gas per 1 mile that it drives. + * + *

When the car reaches a gas station, it may stop and refuel, transferring all the gas from the + * station into the car. + * + *

What is the least number of refueling stops the car must make in order to reach its + * destination? If it cannot reach the destination, return -1. + * + *

Note that if the car reaches a gas station with 0 fuel left, the car can still refuel there. + * If the car reaches the destination with 0 fuel left, it is still considered to have arrived. + * + *

Example 1: + * + *

Input: target = 1, startFuel = 1, stations = [] Output: 0 Explanation: We can reach the target + * without refueling. Example 2: + * + *

Input: target = 100, startFuel = 1, stations = [[10,100]] Output: -1 Explanation: We can't + * reach the target (or even the first gas station). Example 3: + * + *

Input: target = 100, startFuel = 10, stations = [[10,60],[20,30],[30,30],[60,40]] Output: 2 + * Explanation: We start with 10 liters of fuel. We drive to position 10, expending 10 liters of + * fuel. We refuel from 0 liters to 60 liters of gas. Then, we drive from position 10 to position 60 + * (expending 50 liters of fuel), and refuel from 10 liters to 50 liters of gas. We then drive to + * and reach the target. We made 2 refueling stops along the way, so we return 2. + * + *

Note: + * + *

1 <= target, startFuel, stations[i][1] <= 10^9 0 <= stations.length <= 500 0 < stations[0][0] + * < stations[1][0] < ... < stations[stations.length-1][0] < target + * + *

Solution O(N ^ 2): Maintain a DP array with maximum distance that can be travelled with i + * stops. DP[i] is the max distance that can be travelled with exactly i stops. The minimum i where + * the target can be achieved (dp[i] >= target) will be the answer. */ public class MinimumNumberOfRefuelingStops { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int target = 100, startFuel = 10; - int[][] stations = {{10,60},{20,30},{30,30},{60,40}}; - System.out.println(new MinimumNumberOfRefuelingStops().minRefuelStops(target, startFuel, stations)); - } - - public int minRefuelStops(int target, int startFuel, int[][] stations) { - long[] dp = new long[stations.length + 1]; - dp[0] = startFuel; - for(int i = 0; i < stations.length; i ++){ - int d = stations[i][0]; - int f = stations[i][1]; - for(int j = i; j >= 0; j --){ - if(dp[j] >= d){ - dp[j + 1] = Math.max(dp[j + 1], dp[j] + f); - } - } - } - for(int i = 0; i < dp.length; i ++){ - if(dp[i] >= target){ - return i; - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int target = 100, startFuel = 10; + int[][] stations = {{10, 60}, {20, 30}, {30, 30}, {60, 40}}; + System.out.println( + new MinimumNumberOfRefuelingStops().minRefuelStops(target, startFuel, stations)); + } + + public int minRefuelStops(int target, int startFuel, int[][] stations) { + long[] dp = new long[stations.length + 1]; + dp[0] = startFuel; + for (int i = 0; i < stations.length; i++) { + int d = stations[i][0]; + int f = stations[i][1]; + for (int j = i; j >= 0; j--) { + if (dp[j] >= d) { + dp[j + 1] = Math.max(dp[j + 1], dp[j] + f); } - return -1; + } } - + for (int i = 0; i < dp.length; i++) { + if (dp[i] >= target) { + return i; + } + } + return -1; + } } diff --git a/problems/src/dynamic_programming/NumberOfLIS.java b/problems/src/dynamic_programming/NumberOfLIS.java index 3738f63a..a678340a 100644 --- a/problems/src/dynamic_programming/NumberOfLIS.java +++ b/problems/src/dynamic_programming/NumberOfLIS.java @@ -1,73 +1,69 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 13/12/2017. - * Given an unsorted array of integers, find the number of longest increasing subsequence. - - Example 1: - Input: [1,3,5,4,7] - Output: 2 - Explanation: The two longest increasing subsequence are [1, 3, 4, 7] and [1, 3, 5, 7]. - Example 2: - Input: [2,2,2,2,2] - Output: 5 - Explanation: The length of longest continuous increasing subsequence is 1, and there are 5 subsequences' length is - 1, so output 5. - Note: Length of the given array will be not exceed 2000 and the answer is guaranteed to be fit in 32-bit signed int. - - Solution O(n ^ 2) compute the LIS and save the results in length also save the max length of LIS in maxVal. Calculate - the count as below - - For every pair of (i, j) - count[i] = count[i] + count[j] where length[i] == length[j] + 1 and nums[j] < nums[i] - - sum-up the count for every length where length[i] == maxVal + * Created by gouthamvidyapradhan on 13/12/2017. Given an unsorted array of integers, find the + * number of longest increasing subsequence. + * + *

Example 1: Input: [1,3,5,4,7] Output: 2 Explanation: The two longest increasing subsequence + * are [1, 3, 4, 7] and [1, 3, 5, 7]. Example 2: Input: [2,2,2,2,2] Output: 5 Explanation: The + * length of longest continuous increasing subsequence is 1, and there are 5 subsequences' length is + * 1, so output 5. Note: Length of the given array will be not exceed 2000 and the answer is + * guaranteed to be fit in 32-bit signed int. + * + *

Solution O(n ^ 2) compute the LIS and save the results in length also save the max length of + * LIS in maxVal. Calculate the count as below + * + *

For every pair of (i, j) count[i] = count[i] + count[j] where length[i] == length[j] + 1 and + * nums[j] < nums[i] + * + *

sum-up the count for every length where length[i] == maxVal */ public class NumberOfLIS { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1, 12, 11, 1, 1, 1, 12}; - System.out.println(new NumberOfLIS().findNumberOfLIS(A)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 12, 11, 1, 1, 1, 12}; + System.out.println(new NumberOfLIS().findNumberOfLIS(A)); + } - public int findNumberOfLIS(int[] nums) { - if(nums.length == 0) return 0; - int[] length = new int[nums.length]; - length[0] = 1; - int maxVal = 1; - for(int i = 1; i < nums.length; i ++){ - int max = 1; - for(int j = 0; j < i; j++){ - if(nums[i] > nums[j]){ - max = Math.max(max, length[j] + 1); - maxVal = Math.max(maxVal, max); - } - } - length[i] = max; - } - int[] count = new int[nums.length]; - count[0] = 1; - for(int i = 1; i < length.length; i ++){ - for(int j = 0; j < i; j++){ - if((length[j] + 1 == length[i]) && (nums[j] < nums[i])){ - count[i] += count[j]; - } - } - if(count[i] == 0){ - count[i] = 1; //default is just 1 - } + public int findNumberOfLIS(int[] nums) { + if (nums.length == 0) return 0; + int[] length = new int[nums.length]; + length[0] = 1; + int maxVal = 1; + for (int i = 1; i < nums.length; i++) { + int max = 1; + for (int j = 0; j < i; j++) { + if (nums[i] > nums[j]) { + max = Math.max(max, length[j] + 1); + maxVal = Math.max(maxVal, max); } - int ans = 0; - for(int i = 0; i < length.length; i ++){ - if(length[i] == maxVal){ - ans += count[i]; - } + } + length[i] = max; + } + int[] count = new int[nums.length]; + count[0] = 1; + for (int i = 1; i < length.length; i++) { + for (int j = 0; j < i; j++) { + if ((length[j] + 1 == length[i]) && (nums[j] < nums[i])) { + count[i] += count[j]; } - return ans; + } + if (count[i] == 0) { + count[i] = 1; // default is just 1 + } + } + int ans = 0; + for (int i = 0; i < length.length; i++) { + if (length[i] == maxVal) { + ans += count[i]; + } } + return ans; + } } diff --git a/problems/src/dynamic_programming/OddEvenJump.java b/problems/src/dynamic_programming/OddEvenJump.java index 5cd33f48..177b2d48 100644 --- a/problems/src/dynamic_programming/OddEvenJump.java +++ b/problems/src/dynamic_programming/OddEvenJump.java @@ -1,148 +1,137 @@ package dynamic_programming; + import java.util.*; + /** - * Created by gouthamvidyapradhan on 17/03/2019 - * You are given an integer array A. From some starting index, you can make a series of jumps. The (1st, 3rd, 5th, - * ...) jumps in the series are called odd numbered jumps, and the (2nd, 4th, 6th, ...) jumps in the series are - * called even numbered jumps. - * - * You may from index i jump forward to index j (with i < j) in the following way: - * - * During odd numbered jumps (ie. jumps 1, 3, 5, ...), you jump to the index j such that A[i] <= A[j] and A[j] is - * the smallest possible value. If there are multiple such indexes j, you can only jump to the smallest such index j. - * During even numbered jumps (ie. jumps 2, 4, 6, ...), you jump to the index j such that A[i] >= A[j] and A[j] is - * the largest possible value. If there are multiple such indexes j, you can only jump to the smallest such index j. - * (It may be the case that for some index i, there are no legal jumps.) - * A starting index is good if, starting from that index, you can reach the end of the array (index A.length - 1) by - * jumping some number of times (possibly 0 or more than once.) - * - * Return the number of good starting indexes. + * Created by gouthamvidyapradhan on 17/03/2019 You are given an integer array A. From some starting + * index, you can make a series of jumps. The (1st, 3rd, 5th, ...) jumps in the series are called + * odd numbered jumps, and the (2nd, 4th, 6th, ...) jumps in the series are called even numbered + * jumps. * + *

You may from index i jump forward to index j (with i < j) in the following way: * + *

During odd numbered jumps (ie. jumps 1, 3, 5, ...), you jump to the index j such that A[i] <= + * A[j] and A[j] is the smallest possible value. If there are multiple such indexes j, you can only + * jump to the smallest such index j. During even numbered jumps (ie. jumps 2, 4, 6, ...), you jump + * to the index j such that A[i] >= A[j] and A[j] is the largest possible value. If there are + * multiple such indexes j, you can only jump to the smallest such index j. (It may be the case that + * for some index i, there are no legal jumps.) A starting index is good if, starting from that + * index, you can reach the end of the array (index A.length - 1) by jumping some number of times + * (possibly 0 or more than once.) * - * Example 1: + *

Return the number of good starting indexes. * - * Input: [10,13,12,14,15] - * Output: 2 - * Explanation: - * From starting index i = 0, we can jump to i = 2 (since A[2] is the smallest among A[1], A[2], A[3], A[4] that is - * greater or equal to A[0]), then we can't jump any more. - * From starting index i = 1 and i = 2, we can jump to i = 3, then we can't jump any more. - * From starting index i = 3, we can jump to i = 4, so we've reached the end. - * From starting index i = 4, we've reached the end already. - * In total, there are 2 different starting indexes (i = 3, i = 4) where we can reach the end with some number of jumps. - * Example 2: + *

Example 1: * - * Input: [2,3,1,1,4] - * Output: 3 - * Explanation: - * From starting index i = 0, we make jumps to i = 1, i = 2, i = 3: + *

Input: [10,13,12,14,15] Output: 2 Explanation: From starting index i = 0, we can jump to i = 2 + * (since A[2] is the smallest among A[1], A[2], A[3], A[4] that is greater or equal to A[0]), then + * we can't jump any more. From starting index i = 1 and i = 2, we can jump to i = 3, then we can't + * jump any more. From starting index i = 3, we can jump to i = 4, so we've reached the end. From + * starting index i = 4, we've reached the end already. In total, there are 2 different starting + * indexes (i = 3, i = 4) where we can reach the end with some number of jumps. Example 2: * - * During our 1st jump (odd numbered), we first jump to i = 1 because A[1] is the smallest value in (A[1], A[2], - * A[3], A[4]) that is greater than or equal to A[0]. + *

Input: [2,3,1,1,4] Output: 3 Explanation: From starting index i = 0, we make jumps to i = 1, i + * = 2, i = 3: * - * During our 2nd jump (even numbered), we jump from i = 1 to i = 2 because A[2] is the largest value in (A[2], A[3], - * A[4]) that is less than or equal to A[1]. A[3] is also the largest value, but 2 is a smaller index, so we can - * only jump to i = 2 and not i = 3. + *

During our 1st jump (odd numbered), we first jump to i = 1 because A[1] is the smallest value + * in (A[1], A[2], A[3], A[4]) that is greater than or equal to A[0]. * - * During our 3rd jump (odd numbered), we jump from i = 2 to i = 3 because A[3] is the smallest value in (A[3], A[4]) - * that is greater than or equal to A[2]. + *

During our 2nd jump (even numbered), we jump from i = 1 to i = 2 because A[2] is the largest + * value in (A[2], A[3], A[4]) that is less than or equal to A[1]. A[3] is also the largest value, + * but 2 is a smaller index, so we can only jump to i = 2 and not i = 3. * - * We can't jump from i = 3 to i = 4, so the starting index i = 0 is not good. + *

During our 3rd jump (odd numbered), we jump from i = 2 to i = 3 because A[3] is the smallest + * value in (A[3], A[4]) that is greater than or equal to A[2]. * - * In a similar manner, we can deduce that: - * From starting index i = 1, we jump to i = 4, so we reach the end. - * From starting index i = 2, we jump to i = 3, and then we can't jump anymore. - * From starting index i = 3, we jump to i = 4, so we reach the end. - * From starting index i = 4, we are already at the end. - * In total, there are 3 different starting indexes (i = 1, i = 3, i = 4) where we can reach the end with some number - * of jumps. - * Example 3: + *

We can't jump from i = 3 to i = 4, so the starting index i = 0 is not good. * - * Input: [5,1,3,4,2] - * Output: 3 - * Explanation: - * We can reach the end from starting indexes 1, 2, and 4. + *

In a similar manner, we can deduce that: From starting index i = 1, we jump to i = 4, so we + * reach the end. From starting index i = 2, we jump to i = 3, and then we can't jump anymore. From + * starting index i = 3, we jump to i = 4, so we reach the end. From starting index i = 4, we are + * already at the end. In total, there are 3 different starting indexes (i = 1, i = 3, i = 4) where + * we can reach the end with some number of jumps. Example 3: * + *

Input: [5,1,3,4,2] Output: 3 Explanation: We can reach the end from starting indexes 1, 2, and + * 4. * - * Note: + *

Note: * - * 1 <= A.length <= 20000 - * 0 <= A[i] < 100000 + *

1 <= A.length <= 20000 0 <= A[i] < 100000 * - * Solution: O(N log N) - * For each array index and for each odd/even turn pre-calculate the next jump index - this can be achieved in O(n - * log n) by using a balanced tree. - * Check for each array index if we can reach end of the array by using the pre-calculated values for next jump - - * cache the values to avoid recalculating. Sum up total number of such start indices and that will be the answer. + *

Solution: O(N log N) For each array index and for each odd/even turn pre-calculate the next + * jump index - this can be achieved in O(n log n) by using a balanced tree. Check for each array + * index if we can reach end of the array by using the pre-calculated values for next jump - cache + * the values to avoid recalculating. Sum up total number of such start indices and that will be the + * answer. */ public class OddEvenJump { - private class Node { - int num, pos; - Node(int num, int pos){ - this.num = num; - this.pos = pos; - } - } + private class Node { + int num, pos; - TreeSet treeSet; - int[][] next; - int[][] possible; - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int[] A = {10,13,12,14,15}; - System.out.println(new OddEvenJump().oddEvenJumps(A)); + Node(int num, int pos) { + this.num = num; + this.pos = pos; } + } - public int oddEvenJumps(int[] A) { - treeSet = new TreeSet<>(Comparator.comparingInt(o -> o.num)); - next = new int[2][A.length]; - possible = new int[2][A.length]; - Arrays.fill(next[0], -1); - Arrays.fill(next[1], -1); - Arrays.fill(possible[0], -1); - Arrays.fill(possible[1], -1); - for(int i = A.length - 1; i >= 0; i --) { - int num = A[i]; - // odd case - Node curr = new Node(num, i); - Node ceil = treeSet.ceiling(new Node(num, i)); - if (ceil != null) { - next[0][i] = ceil.pos; - } - // even case - Node floor = treeSet.floor(new Node(num, i)); - if (floor != null) { - next[1][i] = floor.pos; - } - treeSet.remove(curr); - treeSet.add(curr); - } - int count = 0; - for(int i = 0; i < A.length; i ++){ - count += dp(A, i, next, possible, 0) == 1 ? 1 : 0; - } - return count; - } + TreeSet treeSet; + int[][] next; + int[][] possible; + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[] A = {10, 13, 12, 14, 15}; + System.out.println(new OddEvenJump().oddEvenJumps(A)); + } + public int oddEvenJumps(int[] A) { + treeSet = new TreeSet<>(Comparator.comparingInt(o -> o.num)); + next = new int[2][A.length]; + possible = new int[2][A.length]; + Arrays.fill(next[0], -1); + Arrays.fill(next[1], -1); + Arrays.fill(possible[0], -1); + Arrays.fill(possible[1], -1); + for (int i = A.length - 1; i >= 0; i--) { + int num = A[i]; + // odd case + Node curr = new Node(num, i); + Node ceil = treeSet.ceiling(new Node(num, i)); + if (ceil != null) { + next[0][i] = ceil.pos; + } + // even case + Node floor = treeSet.floor(new Node(num, i)); + if (floor != null) { + next[1][i] = floor.pos; + } + treeSet.remove(curr); + treeSet.add(curr); + } + int count = 0; + for (int i = 0; i < A.length; i++) { + count += dp(A, i, next, possible, 0) == 1 ? 1 : 0; + } + return count; + } - private int dp(int[] A, int i, int[][] next, int[][] possible, int oddOrEven){ - if(i == A.length - 1) return 1; - else if(possible[oddOrEven][i] == 1 || possible[oddOrEven][i] == 0){ - return possible[oddOrEven][i]; - }else{ - int nextPos = oddOrEven == 0 ? next[0][i] : next[1][i]; - if(nextPos == -1){ - possible[oddOrEven][i] = 0; - return possible[oddOrEven][i]; - } else { - possible[oddOrEven][i] = dp(A, nextPos, next, possible, ((oddOrEven + 1) % 2)); - return possible[oddOrEven][i]; - } - } + private int dp(int[] A, int i, int[][] next, int[][] possible, int oddOrEven) { + if (i == A.length - 1) return 1; + else if (possible[oddOrEven][i] == 1 || possible[oddOrEven][i] == 0) { + return possible[oddOrEven][i]; + } else { + int nextPos = oddOrEven == 0 ? next[0][i] : next[1][i]; + if (nextPos == -1) { + possible[oddOrEven][i] = 0; + return possible[oddOrEven][i]; + } else { + possible[oddOrEven][i] = dp(A, nextPos, next, possible, ((oddOrEven + 1) % 2)); + return possible[oddOrEven][i]; + } } + } } diff --git a/problems/src/dynamic_programming/PaintHouseII.java b/problems/src/dynamic_programming/PaintHouseII.java index 8330300a..68c9d8a6 100644 --- a/problems/src/dynamic_programming/PaintHouseII.java +++ b/problems/src/dynamic_programming/PaintHouseII.java @@ -1,69 +1,66 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 23/12/2017. - * There are a row of n houses, each house can be painted with one of the k colors. The cost of painting each house - * with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same - * color. - - The cost of painting each house with a certain color is represented by a n x k cost matrix. For example, costs[0][0] - is the cost of painting house 0 with color 0; costs[1][2] is the cost of painting house 1 with color 2, and so on... - Find the minimum cost to paint all houses. - - Note: - All costs are positive integers. - - Follow up: - Could you solve it in O(nk) runtime? - - Solution: - Worst case run-time complexity of O(n x k) : Perform a prefix and postfix sum and maintain a auxiliary array to keep - track of prefix and post-fix sum. - Perform a bottom-up dp to calculate the final result. - DP[i][j] = DP[i][j] + Min(LeftPrefixSum[i + 1][j], RightPrefixSum[i + 1][j]) + * Created by gouthamvidyapradhan on 23/12/2017. There are a row of n houses, each house can be + * painted with one of the k colors. The cost of painting each house with a certain color is + * different. You have to paint all the houses such that no two adjacent houses have the same color. + * + *

The cost of painting each house with a certain color is represented by a n x k cost matrix. + * For example, costs[0][0] is the cost of painting house 0 with color 0; costs[1][2] is the cost of + * painting house 1 with color 2, and so on... Find the minimum cost to paint all houses. + * + *

Note: All costs are positive integers. + * + *

Follow up: Could you solve it in O(nk) runtime? + * + *

Solution: Worst case run-time complexity of O(n x k) : Perform a prefix and postfix sum and + * maintain a auxiliary array to keep track of prefix and post-fix sum. Perform a bottom-up dp to + * calculate the final result. DP[i][j] = DP[i][j] + Min(LeftPrefixSum[i + 1][j], RightPrefixSum[i + + * 1][j]) */ public class PaintHouseII { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[][] A = {{1, 2, 3}, {1, 2, 3}, {1, 2, 3}}; - System.out.println(new PaintHouseII().minCostII(A)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[][] A = {{1, 2, 3}, {1, 2, 3}, {1, 2, 3}}; + System.out.println(new PaintHouseII().minCostII(A)); + } - public int minCostII(int[][] costs) { - if(costs.length == 0) return 0; - int[][] lMin = new int[costs.length][costs[0].length]; - int[][] rMin = new int[costs.length][costs[0].length]; - for(int i = costs.length - 2; i >= 0; i--){ - int min = Integer.MAX_VALUE; - for(int j = 0; j < costs[0].length; j++){ - lMin[i + 1][j] = min; - min = Math.min(min, costs[i + 1][j]); - } - min = Integer.MAX_VALUE; - for(int j = costs[0].length - 1; j >= 0; j--){ - rMin[i + 1][j] = min; - min = Math.min(min, costs[i + 1][j]); - } + public int minCostII(int[][] costs) { + if (costs.length == 0) return 0; + int[][] lMin = new int[costs.length][costs[0].length]; + int[][] rMin = new int[costs.length][costs[0].length]; + for (int i = costs.length - 2; i >= 0; i--) { + int min = Integer.MAX_VALUE; + for (int j = 0; j < costs[0].length; j++) { + lMin[i + 1][j] = min; + min = Math.min(min, costs[i + 1][j]); + } + min = Integer.MAX_VALUE; + for (int j = costs[0].length - 1; j >= 0; j--) { + rMin[i + 1][j] = min; + min = Math.min(min, costs[i + 1][j]); + } - for(int j = 0; j < costs[0].length; j++){ - if(j == 0){ - costs[i][j] = costs[i][j] + rMin[i + 1][j]; - } else if(j == costs[0].length - 1){ - costs[i][j] = costs[i][j] + lMin[i + 1][j]; - } else { - costs[i][j] = costs[i][j] + Math.min(lMin[i + 1][j], rMin[i + 1][j]); - } - } - } - int min = Integer.MAX_VALUE; - for(int i = 0; i < costs[0].length; i ++){ - min = Math.min(min, costs[0][i]); + for (int j = 0; j < costs[0].length; j++) { + if (j == 0) { + costs[i][j] = costs[i][j] + rMin[i + 1][j]; + } else if (j == costs[0].length - 1) { + costs[i][j] = costs[i][j] + lMin[i + 1][j]; + } else { + costs[i][j] = costs[i][j] + Math.min(lMin[i + 1][j], rMin[i + 1][j]); } - return min; + } + } + int min = Integer.MAX_VALUE; + for (int i = 0; i < costs[0].length; i++) { + min = Math.min(min, costs[0][i]); } + return min; + } } diff --git a/problems/src/dynamic_programming/PalindromePairs.java b/problems/src/dynamic_programming/PalindromePairs.java index 8c5a04d7..ebcab5c3 100644 --- a/problems/src/dynamic_programming/PalindromePairs.java +++ b/problems/src/dynamic_programming/PalindromePairs.java @@ -3,161 +3,151 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 25/01/2018. - * Given a list of unique words, find all pairs of distinct indices (i, j) in the given list, so that the - * concatenation of the two words, i.e. words[i] + words[j] is a palindrome. - - Example 1: - Given words = ["bat", "tab", "cat"] - Return [[0, 1], [1, 0]] - The palindromes are ["battab", "tabbat"] - Example 2: - Given words = ["abcd", "dcba", "lls", "s", "sssll"] - Return [[0, 1], [1, 0], [3, 2], [2, 4]] - The palindromes are ["dcbaabcd", "abcddcba", "slls", "llssssll"] - - Solution O(n x m ^ 2) where m is the average length of each string and n is the number of strings. - + * Created by gouthamvidyapradhan on 25/01/2018. Given a list of unique words, find all pairs of + * distinct indices (i, j) in the given list, so that the concatenation of the two words, i.e. + * words[i] + words[j] is a palindrome. + * + *

Example 1: Given words = ["bat", "tab", "cat"] Return [[0, 1], [1, 0]] The palindromes are + * ["battab", "tabbat"] Example 2: Given words = ["abcd", "dcba", "lls", "s", "sssll"] Return [[0, + * 1], [1, 0], [3, 2], [2, 4]] The palindromes are ["dcbaabcd", "abcddcba", "slls", "llssssll"] + * + *

Solution O(n x m ^ 2) where m is the average length of each string and n is the number of + * strings. */ public class PalindromePairs { - public class Trie { + public class Trie { - private Map map; - private int index; + private Map map; + private int index; - /** - * Initialize your data structure here. - */ - public Trie() { - map = new HashMap<>(); - } - - /** - * Inserts a word into the trie. - */ - public void insert(String word, int pos) { - if (word != null) { - add(0, word, word.length(), pos); - } - } - - private void add(int i, String word, int length, int pos) { - if (i < length) { - char c = word.charAt(i); - Trie subTrie = map.get(c); - if (subTrie == null) { - subTrie = new Trie(); - map.put(c, subTrie); - } - subTrie.add(i + 1, word, length, pos); - } else { - Trie t = new Trie(); - t.index = pos; - map.put(null, t); //use null to indicate end of string - } - } + /** Initialize your data structure here. */ + public Trie() { + map = new HashMap<>(); + } - public Trie getSubTrie(Character c){ - return this.map.get(c); - } + /** Inserts a word into the trie. */ + public void insert(String word, int pos) { + if (word != null) { + add(0, word, word.length(), pos); + } + } - public int getIndex() { - return index; + private void add(int i, String word, int length, int pos) { + if (i < length) { + char c = word.charAt(i); + Trie subTrie = map.get(c); + if (subTrie == null) { + subTrie = new Trie(); + map.put(c, subTrie); } + subTrie.add(i + 1, word, length, pos); + } else { + Trie t = new Trie(); + t.index = pos; + map.put(null, t); // use null to indicate end of string + } } - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - String[] words = {"", "aa"}; - List> result = new PalindromePairs().palindromePairs(words); - result.stream().map(x -> (x.get(0) + " " + x.get(1))).forEach(System.out::println); + public Trie getSubTrie(Character c) { + return this.map.get(c); } - public List> palindromePairs(String[] words) { - Trie forwardTrie = new Trie(); //maintain a forward and backward trie - Trie backwardTrie = new Trie(); - Map> links = new HashMap<>(); //maintain links to avoid duplicates - for(int i = 0; i < words.length; i ++){ - forwardTrie.insert(words[i], i); - backwardTrie.insert(new StringBuilder(words[i]).reverse().toString(), i); + public int getIndex() { + return index; + } + } + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + String[] words = {"", "aa"}; + List> result = new PalindromePairs().palindromePairs(words); + result.stream().map(x -> (x.get(0) + " " + x.get(1))).forEach(System.out::println); + } + + public List> palindromePairs(String[] words) { + Trie forwardTrie = new Trie(); // maintain a forward and backward trie + Trie backwardTrie = new Trie(); + Map> links = new HashMap<>(); // maintain links to avoid duplicates + for (int i = 0; i < words.length; i++) { + forwardTrie.insert(words[i], i); + backwardTrie.insert(new StringBuilder(words[i]).reverse().toString(), i); + } + List> result = new ArrayList<>(); + for (int i = 0; i < words.length; i++) { + String word = words[i]; + boolean[][] T = new boolean[word.length()][word.length()]; + for (int j = 0, l = word.length(); j < l; j++) { + T[j][j] = true; + int k = j + 1; + if (k < l) { + if (word.charAt(j) == word.charAt(k)) { + T[j][k] = true; + } } - List> result = new ArrayList<>(); - for(int i = 0; i < words.length; i ++){ - String word = words[i]; - boolean[][] T = new boolean[word.length()][word.length()]; - for(int j = 0, l = word.length(); j < l; j++){ - T[j][j] = true; - int k = j + 1; - if(k < l){ - if(word.charAt(j) == word.charAt(k)){ - T[j][k] = true; - } - } - } - for(int m = 2, l = word.length(); m < l; m++){ - for(int j = 0, k = m; j < l && k < l; j++, k++){ - if(word.charAt(j) == word.charAt(k) && T[j + 1][k - 1]){ - T[j][k] = true; - } - } - } - Trie subTrie = backwardTrie; - if(subTrie.getSubTrie(null) != null && !word.isEmpty() && T[0][word.length() - 1]){ - Trie emptySubTrie = subTrie.getSubTrie(null); - result.add(Arrays.asList(i, emptySubTrie.getIndex())); - result.add(Arrays.asList(emptySubTrie.getIndex(), i)); - } - for(int j = 0, l = word.length(); j < l; j++){ - char c = word.charAt(j); - subTrie = subTrie.getSubTrie(c); - if(subTrie == null) break; - Trie indexNode = subTrie.getSubTrie(null); - if(indexNode != null){ - if((j == l - 1) || (T[j + 1][l - 1])){ - if(indexNode.getIndex() != i){ //ignore same index - Set linkedTo = links.get(i); - if(linkedTo == null) { - linkedTo = new HashSet<>(); - links.put(i, linkedTo); - } - if(!linkedTo.contains(indexNode.getIndex())){ - linkedTo.add(indexNode.getIndex()); - result.add(Arrays.asList(i, indexNode.getIndex())); - } - } - } - } + } + for (int m = 2, l = word.length(); m < l; m++) { + for (int j = 0, k = m; j < l && k < l; j++, k++) { + if (word.charAt(j) == word.charAt(k) && T[j + 1][k - 1]) { + T[j][k] = true; + } + } + } + Trie subTrie = backwardTrie; + if (subTrie.getSubTrie(null) != null && !word.isEmpty() && T[0][word.length() - 1]) { + Trie emptySubTrie = subTrie.getSubTrie(null); + result.add(Arrays.asList(i, emptySubTrie.getIndex())); + result.add(Arrays.asList(emptySubTrie.getIndex(), i)); + } + for (int j = 0, l = word.length(); j < l; j++) { + char c = word.charAt(j); + subTrie = subTrie.getSubTrie(c); + if (subTrie == null) break; + Trie indexNode = subTrie.getSubTrie(null); + if (indexNode != null) { + if ((j == l - 1) || (T[j + 1][l - 1])) { + if (indexNode.getIndex() != i) { // ignore same index + Set linkedTo = links.get(i); + if (linkedTo == null) { + linkedTo = new HashSet<>(); + links.put(i, linkedTo); + } + if (!linkedTo.contains(indexNode.getIndex())) { + linkedTo.add(indexNode.getIndex()); + result.add(Arrays.asList(i, indexNode.getIndex())); + } } - subTrie = forwardTrie; - for(int j = word.length() - 1; j >= 0; j--){ - char c = word.charAt(j); - subTrie = subTrie.getSubTrie(c); - if(subTrie == null) break; - Trie indexNode = subTrie.getSubTrie(null); - if(indexNode != null){ - if((j == 0) || (T[0][j - 1])){ - if(indexNode.getIndex() != i){ //ignore same index - Set linkedTo = links.get(indexNode.getIndex()); - if(linkedTo == null) { - linkedTo = new HashSet<>(); - links.put(indexNode.getIndex(), linkedTo); - } - if(!linkedTo.contains(i)){ - linkedTo.add(i); - result.add(Arrays.asList(indexNode.getIndex(), i)); - } - } - } - } + } + } + } + subTrie = forwardTrie; + for (int j = word.length() - 1; j >= 0; j--) { + char c = word.charAt(j); + subTrie = subTrie.getSubTrie(c); + if (subTrie == null) break; + Trie indexNode = subTrie.getSubTrie(null); + if (indexNode != null) { + if ((j == 0) || (T[0][j - 1])) { + if (indexNode.getIndex() != i) { // ignore same index + Set linkedTo = links.get(indexNode.getIndex()); + if (linkedTo == null) { + linkedTo = new HashSet<>(); + links.put(indexNode.getIndex(), linkedTo); + } + if (!linkedTo.contains(i)) { + linkedTo.add(i); + result.add(Arrays.asList(indexNode.getIndex(), i)); + } } - + } } - return result; + } } - + return result; + } } diff --git a/problems/src/dynamic_programming/PalindromePartitioningII.java b/problems/src/dynamic_programming/PalindromePartitioningII.java index a72f8e26..a04e7747 100644 --- a/problems/src/dynamic_programming/PalindromePartitioningII.java +++ b/problems/src/dynamic_programming/PalindromePartitioningII.java @@ -3,49 +3,52 @@ import java.util.Arrays; /** - * Created by pradhang on 4/3/2017. - * Given a string s, partition s such that every substring of the partition is a palindrome. - *

- * Return the minimum cuts needed for a palindrome partitioning of s. - *

- * For example, given s = "aab", - * Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut. + * Created by pradhang on 4/3/2017. Given a string s, partition s such that every substring of the + * partition is a palindrome. + * + *

Return the minimum cuts needed for a palindrome partitioning of s. + * + *

For example, given s = "aab", Return 1 since the palindrome partitioning ["aa","b"] could be + * produced using 1 cut. */ public class PalindromePartitioningII { - private int A[]; - private boolean[][] paliandrome; + private int A[]; + private boolean[][] paliandrome; - /** - * Main method - * - * @param args - */ - public static void main(String[] args) { - System.out.println(new PalindromePartitioningII().minCut("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + System.out.println( + new PalindromePartitioningII() + .minCut( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); + } - public int minCut(String s) { - if (s == null || s.isEmpty()) return 0; - A = new int[s.length()]; - Arrays.fill(A, Integer.MAX_VALUE); - char[] charArr = s.toCharArray(); - paliandrome = new boolean[charArr.length][charArr.length]; - return doNext(charArr, 0) - 1; - } + public int minCut(String s) { + if (s == null || s.isEmpty()) return 0; + A = new int[s.length()]; + Arrays.fill(A, Integer.MAX_VALUE); + char[] charArr = s.toCharArray(); + paliandrome = new boolean[charArr.length][charArr.length]; + return doNext(charArr, 0) - 1; + } - private int doNext(char[] s, int p) { - if (p >= s.length) return 0; - if (A[p] < Integer.MAX_VALUE) return A[p]; - for (int i = p, l = s.length; i < l; i++) { - if (p + 1 <= i - 1) { - paliandrome[p][i] = (paliandrome[p + 1][i - 1] && (s[p] == s[i])); - } else { - paliandrome[p][i] = (i == p) || (s[i] == s[p]); - } - if (paliandrome[p][i]) { - A[p] = Math.min(doNext(s, i + 1) + 1, A[p]); - } - } - return A[p]; + private int doNext(char[] s, int p) { + if (p >= s.length) return 0; + if (A[p] < Integer.MAX_VALUE) return A[p]; + for (int i = p, l = s.length; i < l; i++) { + if (p + 1 <= i - 1) { + paliandrome[p][i] = (paliandrome[p + 1][i - 1] && (s[p] == s[i])); + } else { + paliandrome[p][i] = (i == p) || (s[i] == s[p]); + } + if (paliandrome[p][i]) { + A[p] = Math.min(doNext(s, i + 1) + 1, A[p]); + } } + return A[p]; + } } diff --git a/problems/src/dynamic_programming/PalindromicSubstrings.java b/problems/src/dynamic_programming/PalindromicSubstrings.java index 9379de52..cc461c24 100644 --- a/problems/src/dynamic_programming/PalindromicSubstrings.java +++ b/problems/src/dynamic_programming/PalindromicSubstrings.java @@ -3,58 +3,52 @@ /** * Created by gouthamvidyapradhan on 13/12/2017. * - * Given a string, your task is to count how many palindromic substrings in this string. - - The substrings with different start indexes or end indexes are counted as different substrings even they consist of - same characters. - - Example 1: - Input: "abc" - Output: 3 - Explanation: Three palindromic strings: "a", "b", "c". - Example 2: - Input: "aaa" - Output: 6 - Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa". - Note: - The input string length won't exceed 1000. - - Solution O(n ^ 2): Example abcba: Compare char at two indices each time for example if char at - index 0 and index 4 are equal and if substring 1 and 3 is a palindrome then, sub-string 0 and 4 is also a palindrome - + *

Given a string, your task is to count how many palindromic substrings in this string. + * + *

The substrings with different start indexes or end indexes are counted as different substrings + * even they consist of same characters. + * + *

Example 1: Input: "abc" Output: 3 Explanation: Three palindromic strings: "a", "b", "c". + * Example 2: Input: "aaa" Output: 6 Explanation: Six palindromic strings: "a", "a", "a", "aa", + * "aa", "aaa". Note: The input string length won't exceed 1000. + * + *

Solution O(n ^ 2): Example abcba: Compare char at two indices each time for example if char at + * index 0 and index 4 are equal and if substring 1 and 3 is a palindrome then, sub-string 0 and 4 + * is also a palindrome */ public class PalindromicSubstrings { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - System.out.println(new PalindromicSubstrings().countSubstrings("aaa")); + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + System.out.println(new PalindromicSubstrings().countSubstrings("aaa")); + } + + public int countSubstrings(String s) { + boolean[][] T = new boolean[s.length()][s.length()]; + int count = s.length(); + for (int i = 0, j = 0; i < T.length; i++, j++) { + T[i][j] = true; } - public int countSubstrings(String s) { - boolean[][] T = new boolean[s.length()][s.length()]; - int count = s.length(); - for(int i = 0, j = 0; i < T.length; i ++, j ++){ + for (int k = 1, col = s.length(); k < col; k++) { + for (int i = 0, j = k; i < col && j < col; i++, j++) { + if (k == 1) { + if (s.charAt(i) == s.charAt(j)) { T[i][j] = true; + count++; + } + } else { + if (s.charAt(i) == s.charAt(j) && T[i + 1][j - 1]) { + T[i][j] = true; + count++; + } } - - for(int k = 1, col = s.length(); k < col; k++){ - for(int i = 0, j = k; i < col && j < col; i++, j++){ - if(k == 1){ - if(s.charAt(i) == s.charAt(j)){ - T[i][j] = true; - count++; - } - } else{ - if(s.charAt(i) == s.charAt(j) && T[i + 1][j - 1]){ - T[i][j] = true; - count++; - } - } - } - } - return count; + } } + return count; + } } diff --git a/problems/src/dynamic_programming/ProfitableSchemes.java b/problems/src/dynamic_programming/ProfitableSchemes.java index 2b06488c..0f483933 100644 --- a/problems/src/dynamic_programming/ProfitableSchemes.java +++ b/problems/src/dynamic_programming/ProfitableSchemes.java @@ -1,79 +1,69 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 26/03/2019 - * There are G people in a gang, and a list of various crimes they could commit. + * Created by gouthamvidyapradhan on 26/03/2019 There are G people in a gang, and a list of various + * crimes they could commit. * - * The i-th crime generates a profit[i] and requires group[i] gang members to participate. + *

The i-th crime generates a profit[i] and requires group[i] gang members to participate. * - * If a gang member participates in one crime, that member can't participate in another crime. + *

If a gang member participates in one crime, that member can't participate in another crime. * - * Let's call a profitable scheme any subset of these crimes that generates at least P profit, and the total number - * of gang members participating in that subset of crimes is at most G. + *

Let's call a profitable scheme any subset of these crimes that generates at least P profit, + * and the total number of gang members participating in that subset of crimes is at most G. * - * How many schemes can be chosen? Since the answer may be very large, return it modulo 10^9 + 7. + *

How many schemes can be chosen? Since the answer may be very large, return it modulo 10^9 + 7. * + *

Example 1: * + *

Input: G = 5, P = 3, group = [2,2], profit = [2,3] Output: 2 Explanation: To make a profit of + * at least 3, the gang could either commit crimes 0 and 1, or just crime 1. In total, there are 2 + * schemes. Example 2: * - * Example 1: + *

Input: G = 10, P = 5, group = [2,3,5], profit = [6,7,8] Output: 7 Explanation: To make a + * profit of at least 5, the gang could commit any crimes, as long as they commit one. There are 7 + * possible schemes: (0), (1), (2), (0,1), (0,2), (1,2), and (0,1,2). * - * Input: G = 5, P = 3, group = [2,2], profit = [2,3] - * Output: 2 - * Explanation: - * To make a profit of at least 3, the gang could either commit crimes 0 and 1, or just crime 1. - * In total, there are 2 schemes. - * Example 2: + *

Note: * - * Input: G = 10, P = 5, group = [2,3,5], profit = [6,7,8] - * Output: 7 - * Explanation: - * To make a profit of at least 5, the gang could commit any crimes, as long as they commit one. - * There are 7 possible schemes: (0), (1), (2), (0,1), (0,2), (1,2), and (0,1,2). + *

1 <= G <= 100 0 <= P <= 100 1 <= group[i] <= 100 0 <= profit[i] <= 100 1 <= group.length = + * profit.length <= 100 * - * - * Note: - * - * 1 <= G <= 100 - * 0 <= P <= 100 - * 1 <= group[i] <= 100 - * 0 <= profit[i] <= 100 - * 1 <= group.length = profit.length <= 100 - * - * Solution: O(G x P) Time and Space complexity. The problem is similar to the standard Knapsack DP problem. For every - * group value (ranging from 0 - 100) if a minimum of profit can be achieved then add this to the total count. - * Sum up the count (profitable schemes) for every group value ranging from 0 - G and return this as your answer. + *

Solution: O(G x P) Time and Space complexity. The problem is similar to the standard Knapsack + * DP problem. For every group value (ranging from 0 - 100) if a minimum of profit can be achieved + * then add this to the total count. Sum up the count (profitable schemes) for every group value + * ranging from 0 - G and return this as your answer. */ public class ProfitableSchemes { - private final int MOD = 1000000007; - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int[] group = {2, 3}; - int[] profit = {2, 5}; - System.out.println(new ProfitableSchemes().profitableSchemes(5, 2, group, profit)); - } + private final int MOD = 1000000007; + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[] group = {2, 3}; + int[] profit = {2, 5}; + System.out.println(new ProfitableSchemes().profitableSchemes(5, 2, group, profit)); + } - public int profitableSchemes(int G, int P, int[] group, int[] profit) { - int[][] DP = new int[G + 1][P + 1]; - int ans = 0; - DP[0][0] = 1; - for(int k = group.length - 1; k >= 0; k --){ - int g = group[k]; - int p = profit[k]; - for(int i = DP.length - 1; i >= 0; i --) { - for(int j = DP[0].length - 1; j >= 0; j --) { - int r1 = (i - g < 0) ? 0 : DP[i - g][Math.max(0, j - p)]; - int r2 = DP[i][j]; - DP[i][j] = ((r1 % MOD) + (r2 % MOD)) % MOD; - } - } + public int profitableSchemes(int G, int P, int[] group, int[] profit) { + int[][] DP = new int[G + 1][P + 1]; + int ans = 0; + DP[0][0] = 1; + for (int k = group.length - 1; k >= 0; k--) { + int g = group[k]; + int p = profit[k]; + for (int i = DP.length - 1; i >= 0; i--) { + for (int j = DP[0].length - 1; j >= 0; j--) { + int r1 = (i - g < 0) ? 0 : DP[i - g][Math.max(0, j - p)]; + int r2 = DP[i][j]; + DP[i][j] = ((r1 % MOD) + (r2 % MOD)) % MOD; } - for(int i = 0; i < DP.length; i ++){ - ans = (ans + DP[i][P]) % MOD; - } - return ans; + } } - + for (int i = 0; i < DP.length; i++) { + ans = (ans + DP[i][P]) % MOD; + } + return ans; + } } diff --git a/problems/src/dynamic_programming/SplitArrayLargestSum.java b/problems/src/dynamic_programming/SplitArrayLargestSum.java index 5bfc86ea..7112af7e 100644 --- a/problems/src/dynamic_programming/SplitArrayLargestSum.java +++ b/problems/src/dynamic_programming/SplitArrayLargestSum.java @@ -1,59 +1,52 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 24/12/2017. - * Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty - * continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays. - - Note: - If n is the length of array, assume the following constraints are satisfied: - - 1 ≤ n ≤ 1000 - 1 ≤ m ≤ min(50, n) - Examples: - - Input: - nums = [7,2,5,10,8] - m = 2 - - Output: - 18 - - Explanation: - There are four ways to split nums into two subarrays. - The best way is to split it into [7,2,5] and [10,8], - where the largest sum among the two subarrays is only 18. - - Solution O(n ^ 2 * k) - Build a bottom up min-max dp table for each sub-array ranging from n -> 0 + * Created by gouthamvidyapradhan on 24/12/2017. Given an array which consists of non-negative + * integers and an integer m, you can split the array into m non-empty continuous subarrays. Write + * an algorithm to minimize the largest sum among these m subarrays. + * + *

Note: If n is the length of array, assume the following constraints are satisfied: + * + *

1 ≤ n ≤ 1000 1 ≤ m ≤ min(50, n) Examples: + * + *

Input: nums = [7,2,5,10,8] m = 2 + * + *

Output: 18 + * + *

Explanation: There are four ways to split nums into two subarrays. The best way is to split it + * into [7,2,5] and [10,8], where the largest sum among the two subarrays is only 18. + * + *

Solution O(n ^ 2 * k) Build a bottom up min-max dp table for each sub-array ranging from n -> + * 0 */ public class SplitArrayLargestSum { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {7,2,5,10,8}; - System.out.println(new SplitArrayLargestSum().splitArray(A, 2)); - } - - public int splitArray(int[] nums, int m) { - int[][] dp = new int[m][nums.length]; - for(int i = nums.length - 1; i >= 0; i --){ - int sum = 0; - for(int j = i; j < nums.length; j ++){ - sum += nums[j]; - if(j + 1 >= nums.length) break; - for(int k = 0; k < m - 1; k++){ - dp[k + 1][i] = (dp[k + 1][i] == 0) ? Integer.MAX_VALUE : dp[k + 1][i]; - int temp = Math.max(sum, dp[k][j + 1]); - dp[k + 1][i] = Math.min(dp[k + 1][i], temp); - } - } - dp[0][i] = sum; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {7, 2, 5, 10, 8}; + System.out.println(new SplitArrayLargestSum().splitArray(A, 2)); + } + + public int splitArray(int[] nums, int m) { + int[][] dp = new int[m][nums.length]; + for (int i = nums.length - 1; i >= 0; i--) { + int sum = 0; + for (int j = i; j < nums.length; j++) { + sum += nums[j]; + if (j + 1 >= nums.length) break; + for (int k = 0; k < m - 1; k++) { + dp[k + 1][i] = (dp[k + 1][i] == 0) ? Integer.MAX_VALUE : dp[k + 1][i]; + int temp = Math.max(sum, dp[k][j + 1]); + dp[k + 1][i] = Math.min(dp[k + 1][i], temp); } - return dp[m - 1][0]; + } + dp[0][i] = sum; } + return dp[m - 1][0]; + } } diff --git a/problems/src/dynamic_programming/StoneGame.java b/problems/src/dynamic_programming/StoneGame.java index e7aa6e18..514165ed 100644 --- a/problems/src/dynamic_programming/StoneGame.java +++ b/problems/src/dynamic_programming/StoneGame.java @@ -1,101 +1,96 @@ package dynamic_programming; import java.util.*; + /** - * Created by gouthamvidyapradhan on 22/03/2019 - * Alex and Lee play a game with piles of stones. There are an even number of piles arranged in a row, and each - * pile has a positive integer number of stones piles[i]. - * - * The objective of the game is to end with the most stones. The total number of stones is odd, so there are no ties. - * - * Alex and Lee take turns, with Alex starting first. Each turn, a player takes the entire pile of stones from - * either the beginning or the end of the row. This continues until there are no more piles left, at which point - * the person with the most stones wins. - * - * Assuming Alex and Lee play optimally, return True if and only if Alex wins the game. + * Created by gouthamvidyapradhan on 22/03/2019 Alex and Lee play a game with piles of stones. There + * are an even number of piles arranged in a row, and each pile has a positive integer number of + * stones piles[i]. * + *

The objective of the game is to end with the most stones. The total number of stones is odd, + * so there are no ties. * + *

Alex and Lee take turns, with Alex starting first. Each turn, a player takes the entire pile + * of stones from either the beginning or the end of the row. This continues until there are no more + * piles left, at which point the person with the most stones wins. * - * Example 1: + *

Assuming Alex and Lee play optimally, return True if and only if Alex wins the game. * - * Input: [5,3,4,5] - * Output: true - * Explanation: - * Alex starts first, and can only take the first 5 or the last 5. - * Say he takes the first 5, so that the row becomes [3, 4, 5]. - * If Lee takes 3, then the board is [4, 5], and Alex takes 5 to win with 10 points. - * If Lee takes the last 5, then the board is [3, 4], and Alex takes 4 to win with 9 points. - * This demonstrated that taking the first 5 was a winning move for Alex, so we return true. + *

Example 1: * + *

Input: [5,3,4,5] Output: true Explanation: Alex starts first, and can only take the first 5 or + * the last 5. Say he takes the first 5, so that the row becomes [3, 4, 5]. If Lee takes 3, then the + * board is [4, 5], and Alex takes 5 to win with 10 points. If Lee takes the last 5, then the board + * is [3, 4], and Alex takes 4 to win with 9 points. This demonstrated that taking the first 5 was a + * winning move for Alex, so we return true. * - * Note: + *

Note: * - * 2 <= piles.length <= 500 - * piles.length is even. - * 1 <= piles[i] <= 500 - * sum(piles) is odd. + *

2 <= piles.length <= 500 piles.length is even. 1 <= piles[i] <= 500 sum(piles) is odd. * - * Solution: - * O(N ^ 2) - * Each state can be considered as State = (total stones left, player's turn). Do a dfs on each state and memoize - * the result in order not to recalculate. When all the stones are exhausted - Alex wins if the total collected stones - * by her is greater than total collected by Lee + *

Solution: O(N ^ 2) Each state can be considered as State = (total stones left, player's turn). + * Do a dfs on each state and memoize the result in order not to recalculate. When all the stones + * are exhausted - Alex wins if the total collected stones by her is greater than total collected by + * Lee */ public class StoneGame { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int[] A = {5,3,4,5}; - System.out.println(new StoneGame().stoneGame(A)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[] A = {5, 3, 4, 5}; + System.out.println(new StoneGame().stoneGame(A)); + } - public boolean stoneGame(int[] piles) { - int sum = 0; - for(int i = 0; i < piles.length; i ++){ - sum += piles[i]; - } - int[][] A = new int[2][sum + 1]; - Arrays.fill(A[0], -1); - Arrays.fill(A[1], -1); - int result = dp(A, piles, 0, piles.length - 1, sum, 0, 0, 0); - return result == 1; + public boolean stoneGame(int[] piles) { + int sum = 0; + for (int i = 0; i < piles.length; i++) { + sum += piles[i]; } + int[][] A = new int[2][sum + 1]; + Arrays.fill(A[0], -1); + Arrays.fill(A[1], -1); + int result = dp(A, piles, 0, piles.length - 1, sum, 0, 0, 0); + return result == 1; + } - private int dp(int[][] A, int[] piles, int i, int j, int sum, int p, int sumA, int sumB){ - if(A[p][sum] != -1) return A[p][sum]; - else { - if(p == 0){ - if(i <= j){ - int result = dp(A, piles, i + 1, j, sum - piles[i], (p + 1) % 2, sumA + piles[i], sumB); - if(result == 0){ - A[p][sum] = 1; - return 1; - } else { - result = dp(A, piles, i, j - 1, sum - piles[j], (p + 1) % 2, sumA + piles[j], sumB); - A[p][sum] = result; - return result; - } - } else{ - if(sumA > sumB) return 1; else return 0; - } - } else { - if(i <= j){ - int result = dp(A, piles, i + 1, j, sum - piles[i], (p + 1) % 2, sumA, sumB + piles[i]); - if(result == 0){ - A[p][sum] = 1; - return 1; - } else { - result = dp(A, piles, i, j - 1, sum - piles[j], (p + 1) % 2, sumA, sumB + piles[j]); - A[p][sum] = result; - return result; - } - } else{ - if(sumB > sumA) return 1; else return 0; - } - } + private int dp(int[][] A, int[] piles, int i, int j, int sum, int p, int sumA, int sumB) { + if (A[p][sum] != -1) return A[p][sum]; + else { + if (p == 0) { + if (i <= j) { + int result = dp(A, piles, i + 1, j, sum - piles[i], (p + 1) % 2, sumA + piles[i], sumB); + if (result == 0) { + A[p][sum] = 1; + return 1; + } else { + result = dp(A, piles, i, j - 1, sum - piles[j], (p + 1) % 2, sumA + piles[j], sumB); + A[p][sum] = result; + return result; + } + } else { + if (sumA > sumB) return 1; + else return 0; + } + } else { + if (i <= j) { + int result = dp(A, piles, i + 1, j, sum - piles[i], (p + 1) % 2, sumA, sumB + piles[i]); + if (result == 0) { + A[p][sum] = 1; + return 1; + } else { + result = dp(A, piles, i, j - 1, sum - piles[j], (p + 1) % 2, sumA, sumB + piles[j]); + A[p][sum] = result; + return result; + } + } else { + if (sumB > sumA) return 1; + else return 0; } + } } + } } diff --git a/problems/src/dynamic_programming/TwoKeysKeyboard.java b/problems/src/dynamic_programming/TwoKeysKeyboard.java index 0bd11db5..f51a223e 100644 --- a/problems/src/dynamic_programming/TwoKeysKeyboard.java +++ b/problems/src/dynamic_programming/TwoKeysKeyboard.java @@ -1,47 +1,41 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 19/08/2017. - * Initially on a notepad only one character 'A' is present. You can perform two operations on this notepad for each step: - *

- * Copy All: You can copy all the characters present on the notepad (partial copy is not allowed). - * Paste: You can paste the characters which are copied last time. - * Given a number n. You have to get exactly n 'A' on the notepad by performing the minimum number of steps permitted. Output the minimum number of steps to get n 'A'. - *

- * Example 1: - * Input: 3 - * Output: 3 - * Explanation: - * Intitally, we have one character 'A'. - * In step 1, we use Copy All operation. - * In step 2, we use Paste operation to get 'AA'. - * In step 3, we use Paste operation to get 'AAA'. - *

- * Note: - * The n will be in the range [1, 1000]. + * Created by gouthamvidyapradhan on 19/08/2017. Initially on a notepad only one character 'A' is + * present. You can perform two operations on this notepad for each step: + * + *

Copy All: You can copy all the characters present on the notepad (partial copy is not + * allowed). Paste: You can paste the characters which are copied last time. Given a number n. You + * have to get exactly n 'A' on the notepad by performing the minimum number of steps permitted. + * Output the minimum number of steps to get n 'A'. + * + *

Example 1: Input: 3 Output: 3 Explanation: Intitally, we have one character 'A'. In step 1, we + * use Copy All operation. In step 2, we use Paste operation to get 'AA'. In step 3, we use Paste + * operation to get 'AAA'. + * + *

Note: The n will be in the range [1, 1000]. */ public class TwoKeysKeyboard { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new TwoKeysKeyboard().minSteps(8)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new TwoKeysKeyboard().minSteps(8)); + } - public int minSteps(int n) { - int[] DP = new int[n + 1]; - for (int i = 2; i <= n; i++) { - DP[i] = i; - for (int j = 2; j < i; j++) { - if ((i % j) == 0) { - DP[i] = Math.min(DP[i], DP[j] + (i / j)); - } - } + public int minSteps(int n) { + int[] DP = new int[n + 1]; + for (int i = 2; i <= n; i++) { + DP[i] = i; + for (int j = 2; j < i; j++) { + if ((i % j) == 0) { + DP[i] = Math.min(DP[i], DP[j] + (i / j)); } - return DP[n]; + } } - + return DP[n]; + } } diff --git a/problems/src/dynamic_programming/UniqueBinarySearchTrees.java b/problems/src/dynamic_programming/UniqueBinarySearchTrees.java index 708c9a1f..1297b3f8 100644 --- a/problems/src/dynamic_programming/UniqueBinarySearchTrees.java +++ b/problems/src/dynamic_programming/UniqueBinarySearchTrees.java @@ -1,41 +1,36 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 31/03/2017. - * Given n, how many structurally unique BST's (binary search trees) that store values 1...n? - *

- * For example, - * Given n = 3, there are a total of 5 unique BST's. - *

- * 1 3 3 2 1 - * \ / / / \ \ - * 3 2 1 1 3 2 - * / / \ \ - * 2 1 2 3 + * Created by gouthamvidyapradhan on 31/03/2017. Given n, how many structurally unique BST's (binary + * search trees) that store values 1...n? + * + *

For example, Given n = 3, there are a total of 5 unique BST's. + * + *

1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3 */ public class UniqueBinarySearchTrees { - int[] dp; + int[] dp; - /** - * Main method - * - * @param args - */ - public static void main(String[] args) throws Exception { - System.out.println(new UniqueBinarySearchTrees().numTrees(5)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) throws Exception { + System.out.println(new UniqueBinarySearchTrees().numTrees(5)); + } - public int numTrees(int n) { - dp = new int[n + 1]; - dp[0] = 1; - return dp(n); - } + public int numTrees(int n) { + dp = new int[n + 1]; + dp[0] = 1; + return dp(n); + } - private int dp(int n) { - if (dp[n] != 0) return dp[n]; - for (int i = 1; i <= n; i++) { - dp[n] += dp(n - i) * dp(n - (n - i) - 1); - } - return dp[n]; + private int dp(int n) { + if (dp[n] != 0) return dp[n]; + for (int i = 1; i <= n; i++) { + dp[n] += dp(n - i) * dp(n - (n - i) - 1); } + return dp[n]; + } } diff --git a/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java b/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java index c8299675..ec3e00b9 100644 --- a/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java +++ b/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java @@ -3,91 +3,85 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 31/03/2017. - * Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1...n. - *

- * For example, - * Given n = 3, your program should return all 5 unique BST's shown below. - *

- * 1 3 3 2 1 - * \ / / / \ \ - * 3 2 1 1 3 2 - * / / \ \ - * 2 1 2 3 + * Created by gouthamvidyapradhan on 31/03/2017. Given an integer n, generate all structurally + * unique BST's (binary search trees) that store values 1...n. + * + *

For example, Given n = 3, your program should return all 5 unique BST's shown below. + * + *

1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3 */ public class UniqueBinarySearchTreesII { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - List list = new UniqueBinarySearchTreesII().generateTrees(3); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + List list = new UniqueBinarySearchTreesII().generateTrees(3); + } - class Pair{ - int l, r; - Pair(int l, int r){ - this.l = l; - this.r = r; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Pair)) return false; - Pair pair = (Pair) o; - return l == pair.l && - r == pair.r; - } + class Pair { + int l, r; - @Override - public int hashCode() { - return Objects.hash(l, r); - } + Pair(int l, int r) { + this.l = l; + this.r = r; } - Map> dp; + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Pair)) return false; + Pair pair = (Pair) o; + return l == pair.l && r == pair.r; + } - public List generateTrees(int n) { - dp = new HashMap<>(); - if(n == 0) return new ArrayList<>(); - return generate(new Pair(1, n)); + @Override + public int hashCode() { + return Objects.hash(l, r); } + } - private List generate(Pair p){ - if(dp.containsKey(p)){ - return dp.get(p); - } - else if(p.l > p.r) return Arrays.asList(new TreeNode(-1)); - else if(p.l == p.r) return Arrays.asList(new TreeNode(p.l)); - List list = new ArrayList<>(); - for(int i = p.l; i <= p.r; i ++){ - Pair left = new Pair(p.l, i - 1); - Pair right = new Pair(i + 1, p.r); - List leftList = generate(left); - List rightList = generate(right); - for(TreeNode lNode : leftList){ - for(TreeNode rNode : rightList){ - TreeNode root = new TreeNode(i); - root.left = lNode.val == -1 ? null : lNode; - root.right = rNode.val == -1 ? null : rNode; - list.add(root); - } - } + Map> dp; + + public List generateTrees(int n) { + dp = new HashMap<>(); + if (n == 0) return new ArrayList<>(); + return generate(new Pair(1, n)); + } + + private List generate(Pair p) { + if (dp.containsKey(p)) { + return dp.get(p); + } else if (p.l > p.r) return Arrays.asList(new TreeNode(-1)); + else if (p.l == p.r) return Arrays.asList(new TreeNode(p.l)); + List list = new ArrayList<>(); + for (int i = p.l; i <= p.r; i++) { + Pair left = new Pair(p.l, i - 1); + Pair right = new Pair(i + 1, p.r); + List leftList = generate(left); + List rightList = generate(right); + for (TreeNode lNode : leftList) { + for (TreeNode rNode : rightList) { + TreeNode root = new TreeNode(i); + root.left = lNode.val == -1 ? null : lNode; + root.right = rNode.val == -1 ? null : rNode; + list.add(root); } - dp.put(p, list); - return list; + } } + dp.put(p, list); + return list; + } } diff --git a/problems/src/dynamic_programming/WordBreak.java b/problems/src/dynamic_programming/WordBreak.java index bc7ca55b..6a4ed7a4 100644 --- a/problems/src/dynamic_programming/WordBreak.java +++ b/problems/src/dynamic_programming/WordBreak.java @@ -3,55 +3,58 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 16/03/2017. - * Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words. You may assume the dictionary does not contain duplicate words. - *

- * For example, given - * s = "leetcode", - * dict = ["leet", "code"]. - *

- * Return true because "leetcode" can be segmented as "leet code". + * Created by gouthamvidyapradhan on 16/03/2017. Given a non-empty string s and a dictionary + * wordDict containing a list of non-empty words, determine if s can be segmented into a + * space-separated sequence of one or more dictionary words. You may assume the dictionary does not + * contain duplicate words. + * + *

For example, given s = "leetcode", dict = ["leet", "code"]. + * + *

Return true because "leetcode" can be segmented as "leet code". */ public class WordBreak { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - List dic = new ArrayList<>(); - String[] arr = {"a", "aa", "aaa", "aaaa", "aaaaa", "aaaaaa", "aaaaaaa", "aaaaaaaa", "aaaaaaaaa", "aaaaaaaaaa"}; - for (String s : arr) - dic.add(s); - System.out.println(new WordBreak().wordBreak("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", dic)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + List dic = new ArrayList<>(); + String[] arr = { + "a", "aa", "aaa", "aaaa", "aaaaa", "aaaaaa", "aaaaaaa", "aaaaaaaa", "aaaaaaaaa", "aaaaaaaaaa" + }; + for (String s : arr) dic.add(s); + System.out.println( + new WordBreak() + .wordBreak( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + dic)); + } - public boolean wordBreak(String s, List wordDict) { - Set dictionary = new HashSet<>(); - dictionary.addAll(wordDict); - Map dic = new HashMap<>(); - for (int i = s.length() - 1; i >= 0; i--) - dp(i, s, dic, dictionary); - return dic.get(0); - } + public boolean wordBreak(String s, List wordDict) { + Set dictionary = new HashSet<>(); + dictionary.addAll(wordDict); + Map dic = new HashMap<>(); + for (int i = s.length() - 1; i >= 0; i--) dp(i, s, dic, dictionary); + return dic.get(0); + } - private boolean dp(int i, String s, Map dic, Set dictionary) { - if (i == s.length()) return true; - else if (dic.containsKey(i)) return dic.get(i); - else { - for (int j = i, l = s.length(); j < l; j++) { - String subStr = s.substring(i, j + 1); - if (dictionary.contains(subStr)) { - if (dp(j + 1, s, dic, dictionary)) { - dic.put(i, true); - break; - } - } - } + private boolean dp(int i, String s, Map dic, Set dictionary) { + if (i == s.length()) return true; + else if (dic.containsKey(i)) return dic.get(i); + else { + for (int j = i, l = s.length(); j < l; j++) { + String subStr = s.substring(i, j + 1); + if (dictionary.contains(subStr)) { + if (dp(j + 1, s, dic, dictionary)) { + dic.put(i, true); + break; + } } - if (!dic.containsKey(i)) - dic.put(i, false); - return dic.get(i); + } } + if (!dic.containsKey(i)) dic.put(i, false); + return dic.get(i); + } } diff --git a/problems/src/dynamic_programming/WordBreakII.java b/problems/src/dynamic_programming/WordBreakII.java index 7265dcb1..9739e6be 100644 --- a/problems/src/dynamic_programming/WordBreakII.java +++ b/problems/src/dynamic_programming/WordBreakII.java @@ -3,61 +3,59 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 07/04/2017. - * Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. You may assume the dictionary does not contain duplicate words. - *

- * Return all such possible sentences. - *

- * For example, given - * s = "catsanddog", - * dict = ["cat", "cats", "and", "sand", "dog"]. - *

- * A solution is ["cats and dog", "cat sand dog"]. + * Created by gouthamvidyapradhan on 07/04/2017. Given a non-empty string s and a dictionary + * wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each + * word is a valid dictionary word. You may assume the dictionary does not contain duplicate words. + * + *

Return all such possible sentences. + * + *

For example, given s = "catsanddog", dict = ["cat", "cats", "and", "sand", "dog"]. + * + *

A solution is ["cats and dog", "cat sand dog"]. */ public class WordBreakII { - private Map> map; + private Map> map; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - List wordList = new ArrayList<>(); - wordList.add("cat"); - wordList.add("cats"); - wordList.add("and"); - wordList.add("sand"); - wordList.add("dog"); - System.out.println(new WordBreakII().wordBreak("catsanddog", wordList)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + List wordList = new ArrayList<>(); + wordList.add("cat"); + wordList.add("cats"); + wordList.add("and"); + wordList.add("sand"); + wordList.add("dog"); + System.out.println(new WordBreakII().wordBreak("catsanddog", wordList)); + } - public List wordBreak(String s, List wordDict) { - if (s == null) return new ArrayList<>(); - map = new HashMap<>(); - Set dictionary = new HashSet<>(); - dictionary.addAll(wordDict); - return dp(0, s, s.length(), dictionary); - } + public List wordBreak(String s, List wordDict) { + if (s == null) return new ArrayList<>(); + map = new HashMap<>(); + Set dictionary = new HashSet<>(); + dictionary.addAll(wordDict); + return dp(0, s, s.length(), dictionary); + } - private List dp(int p, String s, int l, Set dictionary) { - List result = new ArrayList<>(); - if (p >= s.length()) { - result.add(""); - return result; - } else if (map.containsKey(p)) { - return map.get(p); - } - for (int i = p; i < l; i++) { - String subStr = s.substring(p, i + 1); - if (dictionary.contains(subStr)) { - List subList = dp(i + 1, s, l, dictionary); - for (String se : subList) - result.add((subStr + " " + se).trim()); - } - } - map.put(p, result); - return result; + private List dp(int p, String s, int l, Set dictionary) { + List result = new ArrayList<>(); + if (p >= s.length()) { + result.add(""); + return result; + } else if (map.containsKey(p)) { + return map.get(p); + } + for (int i = p; i < l; i++) { + String subStr = s.substring(p, i + 1); + if (dictionary.contains(subStr)) { + List subList = dp(i + 1, s, l, dictionary); + for (String se : subList) result.add((subStr + " " + se).trim()); + } } + map.put(p, result); + return result; + } } diff --git a/problems/src/greedy/BurstBalloons.java b/problems/src/greedy/BurstBalloons.java index c9501aab..0ebca988 100644 --- a/problems/src/greedy/BurstBalloons.java +++ b/problems/src/greedy/BurstBalloons.java @@ -4,46 +4,49 @@ /** * Created by gouthamvidyapradhan on 28/06/2017. - *

- * There are a number of spherical balloons spread in two-dimensional space. For each balloon, provided input is the start and end coordinates of the horizontal diameter. Since it's horizontal, y-coordinates don't matter and hence the x-coordinates of start and end of the diameter suffice. Start is always smaller than end. There will be at most 104 balloons. - *

- * An arrow can be shot up exactly vertically from different points along the x-axis. A balloon with xstart and xend bursts by an arrow shot at x if xstart ≤ x ≤ xend. There is no limit to the number of arrows that can be shot. An arrow once shot keeps travelling up infinitely. The problem is to find the minimum number of arrows that must be shot to burst all balloons. - *

- * Example: - *

- * Input: - * [[10,16], [2,8], [1,6], [7,12]] - *

- * Output: - * 2 - *

- * Explanation: - * One way is to shoot one arrow for example at x = 6 (bursting the balloons [2,8] and [1,6]) and another arrow at x + * + *

There are a number of spherical balloons spread in two-dimensional space. For each balloon, + * provided input is the start and end coordinates of the horizontal diameter. Since it's + * horizontal, y-coordinates don't matter and hence the x-coordinates of start and end of the + * diameter suffice. Start is always smaller than end. There will be at most 104 balloons. + * + *

An arrow can be shot up exactly vertically from different points along the x-axis. A balloon + * with xstart and xend bursts by an arrow shot at x if xstart ≤ x ≤ xend. There is no limit to the + * number of arrows that can be shot. An arrow once shot keeps travelling up infinitely. The problem + * is to find the minimum number of arrows that must be shot to burst all balloons. + * + *

Example: + * + *

Input: [[10,16], [2,8], [1,6], [7,12]] + * + *

Output: 2 + * + *

Explanation: One way is to shoot one arrow for example at x = 6 (bursting the balloons [2,8] + * and [1,6]) and another arrow at x */ public class BurstBalloons { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[][] baloons = {{10, 16}, {2, 8}, {1, 6}, {7, 12}}; - System.out.println(new BurstBalloons().findMinArrowShots(baloons)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[][] baloons = {{10, 16}, {2, 8}, {1, 6}, {7, 12}}; + System.out.println(new BurstBalloons().findMinArrowShots(baloons)); + } - public int findMinArrowShots(int[][] points) { - if (points.length == 0) return 0; - Arrays.sort(points, ((o1, o2) -> o1[1] - o2[1])); - int count = 0; - int leftMost = points[0][1]; - for (int i = 1; i < points.length; i++) { - if (leftMost < points[i][0]) { - count++; - leftMost = points[i][1]; - } - } - return count + 1; + public int findMinArrowShots(int[][] points) { + if (points.length == 0) return 0; + Arrays.sort(points, ((o1, o2) -> o1[1] - o2[1])); + int count = 0; + int leftMost = points[0][1]; + for (int i = 1; i < points.length; i++) { + if (leftMost < points[i][0]) { + count++; + leftMost = points[i][1]; + } } - + return count + 1; + } } diff --git a/problems/src/greedy/CourseScheduleIII.java b/problems/src/greedy/CourseScheduleIII.java index b370de3f..e7afb7e8 100644 --- a/problems/src/greedy/CourseScheduleIII.java +++ b/problems/src/greedy/CourseScheduleIII.java @@ -6,49 +6,45 @@ /** * Created by gouthamvidyapradhan on 27/06/2017. - *

- * There are n different online courses numbered from 1 to n. Each course has some duration(course length) t and closed on dth day. A course should be taken continuously for t days and must be finished before or on the dth day. You will start at the 1st day. - *

- * Given n online courses represented by pairs (t,d), your task is to find the maximal number of courses that can be taken. - *

- * Example: - * Input: [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]] - * Output: 3 - * Explanation: - * There're totally 4 courses, but you can take 3 courses at most: - * First, take the 1st course, it costs 100 days so you will finish it on the 100th day, and ready to take the next course on the 101st day. - * Second, take the 3rd course, it costs 1000 days so you will finish it on the 1100th day, and ready to take the next course on the 1101st day. - * Third, take the 2nd course, it costs 200 days so you will finish it on the 1300th day. - * The 4th course cannot be taken now, since you will finish it on the 3300th day, which exceeds the closed date. - *

- * Note: - * The integer 1 <= d, t, n <= 10,000. - * You can't take two courses simultaneously. - *

- * Solution: O(N log N) - * 1. Sort the courses with earliest deadline time (Greedy sort) - * 2. Maintain a max-heap of course duration. - * 3. Iterate through each course and increment the total time by current course time and include this in the - * max-heap created in step 2. - * 4. If the total time exceeds the current course deadline then, remove the course with max duration from max-heap + * + *

There are n different online courses numbered from 1 to n. Each course has some + * duration(course length) t and closed on dth day. A course should be taken continuously for t days + * and must be finished before or on the dth day. You will start at the 1st day. + * + *

Given n online courses represented by pairs (t,d), your task is to find the maximal number of + * courses that can be taken. + * + *

Example: Input: [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]] Output: 3 Explanation: + * There're totally 4 courses, but you can take 3 courses at most: First, take the 1st course, it + * costs 100 days so you will finish it on the 100th day, and ready to take the next course on the + * 101st day. Second, take the 3rd course, it costs 1000 days so you will finish it on the 1100th + * day, and ready to take the next course on the 1101st day. Third, take the 2nd course, it costs + * 200 days so you will finish it on the 1300th day. The 4th course cannot be taken now, since you + * will finish it on the 3300th day, which exceeds the closed date. + * + *

Note: The integer 1 <= d, t, n <= 10,000. You can't take two courses simultaneously. + * + *

Solution: O(N log N) 1. Sort the courses with earliest deadline time (Greedy sort) 2. Maintain + * a max-heap of course duration. 3. Iterate through each course and increment the total time by + * current course time and include this in the max-heap created in step 2. 4. If the total time + * exceeds the current course deadline then, remove the course with max duration from max-heap * inorder to accommodate the new course. */ public class CourseScheduleIII { - public static void main(String[] args) throws Exception { - int[][] course = {{5, 5}, {2, 6}, {4, 6}}; - System.out.println(new CourseScheduleIII().scheduleCourse(course)); - } + public static void main(String[] args) throws Exception { + int[][] course = {{5, 5}, {2, 6}, {4, 6}}; + System.out.println(new CourseScheduleIII().scheduleCourse(course)); + } - public int scheduleCourse(int[][] courses) { - Arrays.sort(courses, (a, b) -> a[1] - b[1]); - Queue pq = new PriorityQueue<>((a, b) -> b - a); - int time = 0; - for (int[] course : courses) { - time += course[0]; - pq.add(course[0]); - if (time > course[1]) - time -= pq.poll(); - } - return pq.size(); + public int scheduleCourse(int[][] courses) { + Arrays.sort(courses, (a, b) -> a[1] - b[1]); + Queue pq = new PriorityQueue<>((a, b) -> b - a); + int time = 0; + for (int[] course : courses) { + time += course[0]; + pq.add(course[0]); + if (time > course[1]) time -= pq.poll(); } + return pq.size(); + } } diff --git a/problems/src/greedy/GasStation.java b/problems/src/greedy/GasStation.java index 7afa0f51..7b0da2c2 100644 --- a/problems/src/greedy/GasStation.java +++ b/problems/src/greedy/GasStation.java @@ -1,45 +1,45 @@ package greedy; /** - * Created by gouthamvidyapradhan on 28/06/2017. - * There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. - *

- * You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations. - *

- * Return the starting gas station's index if you can travel around the circuit once, otherwise return -1. - *

- * Note: - * The solution is guaranteed to be unique. - *

- * Solution: O(N) - * If point B cant be reached from point A then all the intermediate points between A and B cant be the starting - * point. Therefore reset the starting point to the new starting point. + * Created by gouthamvidyapradhan on 28/06/2017. There are N gas stations along a circular route, + * where the amount of gas at station i is gas[i]. + * + *

You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i + * to its next station (i+1). You begin the journey with an empty tank at one of the gas stations. + * + *

Return the starting gas station's index if you can travel around the circuit once, otherwise + * return -1. + * + *

Note: The solution is guaranteed to be unique. + * + *

Solution: O(N) If point B cant be reached from point A then all the intermediate points + * between A and B cant be the starting point. Therefore reset the starting point to the new + * starting point. */ public class GasStation { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] gas = {10, 20, 30, 10}; - int[] cost = {5, 30, 10, 10}; - System.out.println(new GasStation().canCompleteCircuit(gas, cost)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] gas = {10, 20, 30, 10}; + int[] cost = {5, 30, 10, 10}; + System.out.println(new GasStation().canCompleteCircuit(gas, cost)); + } - public int canCompleteCircuit(int[] gas, int[] cost) { - int debt = 0, sum = 0, start = 0; - for (int i = 0; i < gas.length; i++) { - sum += gas[i] - cost[i]; - if (sum < 0) { - debt += sum; - sum = 0; - start = i + 1; - } - } + public int canCompleteCircuit(int[] gas, int[] cost) { + int debt = 0, sum = 0, start = 0; + for (int i = 0; i < gas.length; i++) { + sum += gas[i] - cost[i]; + if (sum < 0) { debt += sum; - return debt >= 0 ? start : -1; + sum = 0; + start = i + 1; + } } - + debt += sum; + return debt >= 0 ? start : -1; + } } diff --git a/problems/src/greedy/IPO.java b/problems/src/greedy/IPO.java index 7e42b170..6b5dd2cf 100644 --- a/problems/src/greedy/IPO.java +++ b/problems/src/greedy/IPO.java @@ -1,102 +1,103 @@ -package greedy; /** - * Created by gouthamvidyapradhan on 09/04/2019 - * Suppose LeetCode will start its IPO soon. In order to sell a good price of its shares to Venture Capital, - * LeetCode would like to work on some projects to increase its capital before the IPO. Since it has limited - * resources, it can only finish at most k distinct projects before the IPO. Help LeetCode design the best way to - * maximize its total capital after finishing at most k distinct projects. +package greedy; +/** + * Created by gouthamvidyapradhan on 09/04/2019 Suppose LeetCode will start its IPO soon. In order + * to sell a good price of its shares to Venture Capital, LeetCode would like to work on some + * projects to increase its capital before the IPO. Since it has limited resources, it can only + * finish at most k distinct projects before the IPO. Help LeetCode design the best way to maximize + * its total capital after finishing at most k distinct projects. * - * You are given several projects. For each project i, it has a pure profit Pi and a minimum capital of Ci is needed - * to start the corresponding project. Initially, you have W capital. When you finish a project, you will obtain its - * pure profit and the profit will be added to your total capital. + *

You are given several projects. For each project i, it has a pure profit Pi and a minimum + * capital of Ci is needed to start the corresponding project. Initially, you have W capital. When + * you finish a project, you will obtain its pure profit and the profit will be added to your total + * capital. * - * To sum up, pick a list of at most k distinct projects from given projects to maximize your final capital, and - * output your final maximized capital. + *

To sum up, pick a list of at most k distinct projects from given projects to maximize your + * final capital, and output your final maximized capital. * - * Example 1: - * Input: k=2, W=0, Profits=[1,2,3], Capital=[0,1,1]. + *

Example 1: Input: k=2, W=0, Profits=[1,2,3], Capital=[0,1,1]. * - * Output: 4 + *

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. - * Note: - * You may assume all numbers in the input are non-negative integers. - * The length of Profits array and Capital array will not exceed 50,000. - * The answer is guaranteed to fit in a 32-bit signed integer. + *

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. Note: You may assume all numbers in the input are + * non-negative integers. The length of Profits array and Capital array will not exceed 50,000. The + * answer is guaranteed to fit in a 32-bit signed integer. * - * Solution: - * O(N log N) where N is the size of Capital/Profit array. - * General intuition is to pick a project which gives maximum profit for the available capital. Sum the - * profit with the original capital and this becomes the new available capital now, again pick the - * project which gives maximum profit. Continue this until K projects are picked. Maintain a priority queue - * to pick the project which gives maximum profit. + *

Solution: O(N log N) where N is the size of Capital/Profit array. General intuition is to pick + * a project which gives maximum profit for the available capital. Sum the profit with the original + * capital and this becomes the new available capital now, again pick the project which gives + * maximum profit. Continue this until K projects are picked. Maintain a priority queue to pick the + * project which gives maximum profit. */ import java.util.*; + public class IPO { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int[] P = {1, 2, 3}; - int[] C = {1, 1, 2}; - System.out.println(new IPO().findMaximizedCapital(1, 0, P, C)); + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[] P = {1, 2, 3}; + int[] C = {1, 1, 2}; + System.out.println(new IPO().findMaximizedCapital(1, 0, P, C)); + } + + class Pair { + int p, c; + + Pair(int p, int c) { + this.p = p; + this.c = c; } - class Pair { - int p, c; - Pair(int p, int c){ - this.p = p; - this.c = c; - } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Pair)) return false; - Pair pair = (Pair) o; - return p == pair.p && - c == pair.c; - } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Pair)) return false; + Pair pair = (Pair) o; + return p == pair.p && c == pair.c; + } - public int getP() { - return p; - } + public int getP() { + return p; + } - public int getC() { - return c; - } + public int getC() { + return c; + } + + @Override + public int hashCode() { + return Objects.hash(p, c); + } + } - @Override - public int hashCode() { - return Objects.hash(p, c); - } + public int findMaximizedCapital(int k, int W, int[] Profits, int[] Capital) { + PriorityQueue profits = + new PriorityQueue<>(Comparator.comparing(Pair::getP).reversed().thenComparing(Pair::getC)); + PriorityQueue capitals = new PriorityQueue<>(Comparator.comparing(Pair::getC)); + for (int i = 0; i < Profits.length; i++) { + capitals.offer(new Pair(Profits[i], Capital[i])); + } + while (true) { + while (!capitals.isEmpty() && capitals.peek().getC() <= W) { + profits.offer(capitals.poll()); + } + if (!profits.isEmpty() && profits.peek().getC() <= W && k > 0) { + W += profits.poll().getP(); + k--; + } + if (capitals.isEmpty() || capitals.peek().getC() > W || k == 0) break; } - public int findMaximizedCapital(int k, int W, int[] Profits, int[] Capital) { - PriorityQueue profits = - new PriorityQueue<>(Comparator.comparing(Pair::getP).reversed().thenComparing(Pair::getC)); - PriorityQueue capitals = new PriorityQueue<>(Comparator.comparing(Pair::getC)); - for(int i = 0; i < Profits.length; i ++){ - capitals.offer(new Pair(Profits[i], Capital[i])); - } - while(true){ - while(!capitals.isEmpty() && capitals.peek().getC() <= W){ - profits.offer(capitals.poll()); - } - if(!profits.isEmpty() && profits.peek().getC() <= W && k > 0){ - W += profits.poll().getP(); - k --; - } - if(capitals.isEmpty() || capitals.peek().getC() > W || k == 0) break; - } - while(k > 0 && !profits.isEmpty()){ - W += profits.poll().getP(); - k--; - } - return W; + while (k > 0 && !profits.isEmpty()) { + W += profits.poll().getP(); + k--; } + return W; + } } diff --git a/problems/src/greedy/JumpGame.java b/problems/src/greedy/JumpGame.java index 3c7ea2fa..8ad08d96 100644 --- a/problems/src/greedy/JumpGame.java +++ b/problems/src/greedy/JumpGame.java @@ -1,37 +1,35 @@ package greedy; /** - * Created by gouthamvidyapradhan on 17/03/2017. - * Given an array of non-negative integers, 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. - *

- * For example: - * A = [2,3,1,1,4], return true. - *

- * A = [3,2,1,0,4], return false. + * Created by gouthamvidyapradhan on 17/03/2017. Given an array of non-negative integers, 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. + * + *

For example: A = [2,3,1,1,4], return true. + * + *

A = [3,2,1,0,4], return false. */ public class JumpGame { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] nums = {1, 2, 1, 0, 4}; - System.out.println(new JumpGame().canJump(nums)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] nums = {1, 2, 1, 0, 4}; + System.out.println(new JumpGame().canJump(nums)); + } - public boolean canJump(int[] nums) { - if (nums.length == 0) return false; - int min = nums.length - 1, max = nums.length - 1; - for (int i = nums.length - 2; i >= 0; i--) { - if ((nums[i] + i) >= min) - min = i; - } - return (min == 0); + public boolean canJump(int[] nums) { + if (nums.length == 0) return false; + int min = nums.length - 1, max = nums.length - 1; + for (int i = nums.length - 2; i >= 0; i--) { + if ((nums[i] + i) >= min) min = i; } + return (min == 0); + } } diff --git a/problems/src/greedy/JumpGameII.java b/problems/src/greedy/JumpGameII.java index 051ab50e..9969fc40 100644 --- a/problems/src/greedy/JumpGameII.java +++ b/problems/src/greedy/JumpGameII.java @@ -1,42 +1,39 @@ package greedy; /** - * Created by gouthamvidyapradhan on 02/04/2017. - * Given an array of non-negative integers, you are initially positioned at the first index of the array. - *

- * Each element in the array represents your maximum jump length at that position. - *

- * Your goal is to reach the last index in the minimum number of jumps. - *

- * For example: - * Given array A = [2,3,1,1,4] - *

- * The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.) - *

- * Note: - * You can assume that you can always reach the last index. + * Created by gouthamvidyapradhan on 02/04/2017. Given an array of non-negative integers, you are + * initially positioned at the first index of the array. + * + *

Each element in the array represents your maximum jump length at that position. + * + *

Your goal is to reach the last index in the minimum number of jumps. + * + *

For example: Given array A = [2,3,1,1,4] + * + *

The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then + * 3 steps to the last index.) + * + *

Note: You can assume that you can always reach the last index. */ public class JumpGameII { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception {} + public int jump(int[] nums) { + int step = 0; + int e = 0, max = 0; + for (int i = 0; i < nums.length - 1; i++) { + max = Math.max(max, i + nums[i]); + if (i == e) { + step++; + e = max; + } } - - public int jump(int[] nums) { - int step = 0; - int e = 0, max = 0; - for (int i = 0; i < nums.length - 1; i++) { - max = Math.max(max, i + nums[i]); - if (i == e) { - step++; - e = max; - } - } - return step; - } + return step; + } } diff --git a/problems/src/greedy/LemonadeChange.java b/problems/src/greedy/LemonadeChange.java index 3798c8f3..f0aaf52d 100644 --- a/problems/src/greedy/LemonadeChange.java +++ b/problems/src/greedy/LemonadeChange.java @@ -3,88 +3,75 @@ /** * Created by gouthamvidyapradhan on 26/04/2019 * - * At a lemonade stand, each lemonade costs $5. + *

At a lemonade stand, each lemonade costs $5. * - * Customers are standing in a queue to buy from you, and order one at a time (in the order specified by bills). + *

Customers are standing in a queue to buy from you, and order one at a time (in the order + * specified by bills). * - * Each customer will only buy one lemonade and pay with either a $5, $10, or $20 bill. You must provide the correct change to each customer, so that the net transaction is that the customer pays $5. + *

Each customer will only buy one lemonade and pay with either a $5, $10, or $20 bill. You must + * provide the correct change to each customer, so that the net transaction is that the customer + * pays $5. * - * Note that you don't have any change in hand at first. + *

Note that you don't have any change in hand at first. * - * Return true if and only if you can provide every customer with correct change. + *

Return true if and only if you can provide every customer with correct change. * + *

Example 1: * + *

Input: [5,5,5,10,20] Output: true Explanation: From the first 3 customers, we collect three $5 + * bills in order. From the fourth customer, we collect a $10 bill and give back a $5. From the + * fifth customer, we give a $10 bill and a $5 bill. Since all customers got correct change, we + * output true. Example 2: * - * Example 1: + *

Input: [5,5,10] Output: true Example 3: * - * Input: [5,5,5,10,20] - * Output: true - * Explanation: - * From the first 3 customers, we collect three $5 bills in order. - * From the fourth customer, we collect a $10 bill and give back a $5. - * From the fifth customer, we give a $10 bill and a $5 bill. - * Since all customers got correct change, we output true. - * Example 2: + *

Input: [10,10] Output: false Example 4: * - * Input: [5,5,10] - * Output: true - * Example 3: + *

Input: [5,5,10,10,20] Output: false Explanation: From the first two customers in order, we + * collect two $5 bills. For the next two customers in order, we collect a $10 bill and give back a + * $5 bill. For the last customer, we can't give change of $15 back because we only have two $10 + * bills. Since not every customer received correct change, the answer is false. * - * Input: [10,10] - * Output: false - * Example 4: + *

Note: * - * Input: [5,5,10,10,20] - * Output: false - * Explanation: - * From the first two customers in order, we collect two $5 bills. - * For the next two customers in order, we collect a $10 bill and give back a $5 bill. - * For the last customer, we can't give change of $15 back because we only have two $10 bills. - * Since not every customer received correct change, the answer is false. + *

0 <= bills.length <= 10000 bills[i] will be either 5, 10, or 20. * - * - * Note: - * - * 0 <= bills.length <= 10000 - * bills[i] will be either 5, 10, or 20. - * - * Solution: Store the count of number of five's and tens's. In case of change 15 return a 10 + 5 (if - * 10 is not available then, return 5 + 5 + 5 if three fives are available) - * Since we are choosing a 10 + 5 instead of 5 + 5 + 5, this problem holds a greedy property + *

Solution: Store the count of number of five's and tens's. In case of change 15 return a 10 + 5 + * (if 10 is not available then, return 5 + 5 + 5 if three fives are available) Since we are + * choosing a 10 + 5 instead of 5 + 5 + 5, this problem holds a greedy property */ public class LemonadeChange { - /** - * Main method - * @param args - */ - public static void main(String[] args) { + /** + * Main method + * + * @param args + */ + public static void main(String[] args) {} - } - - public boolean lemonadeChange(int[] bills) { - int five = 0, ten = 0; - for(int b : bills){ - if(b == 5){ - five++; - } else if(b == 10){ - ten++; - if(five > 0){ - five--; - }else{ - return false; - } - } else{ - if(ten > 0 && five > 0){ - ten --; - five--; - } else if(five > 2){ - five -= 3; - } else { - return false; - } - } + public boolean lemonadeChange(int[] bills) { + int five = 0, ten = 0; + for (int b : bills) { + if (b == 5) { + five++; + } else if (b == 10) { + ten++; + if (five > 0) { + five--; + } else { + return false; + } + } else { + if (ten > 0 && five > 0) { + ten--; + five--; + } else if (five > 2) { + five -= 3; + } else { + return false; } - return true; + } } + return true; + } } diff --git a/problems/src/greedy/MaximumLengthOfPairChain.java b/problems/src/greedy/MaximumLengthOfPairChain.java index 41b0574f..ee8eb86c 100644 --- a/problems/src/greedy/MaximumLengthOfPairChain.java +++ b/problems/src/greedy/MaximumLengthOfPairChain.java @@ -3,48 +3,47 @@ import java.util.Arrays; /** - * Created by gouthamvidyapradhan on 01/05/2018. - * You are given n pairs of numbers. In every pair, the first number is always smaller than the second number. - - Now, we define a pair (c, d) can follow another pair (a, b) if and only if b < c. - Chain of pairs can be formed in this fashion. - - Given a set of pairs, find the length longest chain which can be formed. You needn't use up all the given pairs. - You can select pairs in any order. - - Example 1: - Input: [[1,2], [2,3], [3,4]] - Output: 2 - Explanation: The longest chain is [1,2] -> [3,4] - Note: - The number of given pairs will be in the range [1, 1000]. - - Solution: O(N log N) sort the pairs with ending interval (greedy sort) and try to accommodate as many pairs - as possible. If any current pair violates the chaining condition (b < c) then, ignore that particular pair. + * Created by gouthamvidyapradhan on 01/05/2018. You are given n pairs of numbers. In every pair, + * the first number is always smaller than the second number. + * + *

Now, we define a pair (c, d) can follow another pair (a, b) if and only if b < c. Chain of + * pairs can be formed in this fashion. + * + *

Given a set of pairs, find the length longest chain which can be formed. You needn't use up + * all the given pairs. You can select pairs in any order. + * + *

Example 1: Input: [[1,2], [2,3], [3,4]] Output: 2 Explanation: The longest chain is [1,2] -> + * [3,4] Note: The number of given pairs will be in the range [1, 1000]. + * + *

Solution: O(N log N) sort the pairs with ending interval (greedy sort) and try to accommodate + * as many pairs as possible. If any current pair violates the chaining condition (b < c) then, + * ignore that particular pair. */ public class MaximumLengthOfPairChain { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[][] A = {{1,2}, {2,3}, {3,4}}; - System.out.println(new MaximumLengthOfPairChain().findLongestChain(A)); + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[][] A = {{1, 2}, {2, 3}, {3, 4}}; + System.out.println(new MaximumLengthOfPairChain().findLongestChain(A)); + } + + public int findLongestChain(int[][] pairs) { + Arrays.sort( + pairs, + (o1, o2) -> o1[1] == o2[1] ? Integer.compare(o1[0], o2[0]) : Integer.compare(o1[1], o2[1])); + int count = 1; + int[] curr = pairs[0]; + for (int i = 1; i < pairs.length; i++) { + if (pairs[i][0] > curr[1]) { + count++; + curr = pairs[i]; + } } - - public int findLongestChain(int[][] pairs) { - Arrays.sort(pairs, (o1, o2) -> o1[1] == o2[1] ? Integer.compare(o1[0], o2[0]) : Integer.compare(o1[1], o2[1])); - int count = 1; - int[] curr = pairs[0]; - for(int i = 1; i < pairs.length; i ++){ - if(pairs[i][0] > curr[1]){ - count++; - curr = pairs[i]; - } - } - return count; - } - + return count; + } } diff --git a/problems/src/greedy/NonOverlappingIntervals.java b/problems/src/greedy/NonOverlappingIntervals.java index 2ec7bcce..c9d9cffc 100644 --- a/problems/src/greedy/NonOverlappingIntervals.java +++ b/problems/src/greedy/NonOverlappingIntervals.java @@ -3,76 +3,72 @@ import java.util.Arrays; /** - * Created by gouthamvidyapradhan on 28/06/2017. - * Given a collection of intervals, find the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping. - *

- * Note: - * You may assume the interval's end point is always bigger than its start point. - * Intervals like [1,2] and [2,3] have borders "touching" but they don't overlap each other. - * Example 1: - * 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. - * Example 2: + * Created by gouthamvidyapradhan on 28/06/2017. Given a collection of intervals, find the minimum + * number of intervals you need to remove to make the rest of the intervals non-overlapping. + * + *

Note: You may assume the interval's end point is always bigger than its start point. Intervals + * like [1,2] and [2,3] have borders "touching" but they don't overlap each other. Example 1: 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. Example 2: * 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. - * Example 3: - * Input: [ [1,2], [2,3] ] - *

- * Output: 0 - *

- * Explanation: You don't need to remove any of the intervals since they're already non-overlapping. + * + *

Output: 2 + * + *

Explanation: You need to remove two [1,2] to make the rest of intervals non-overlapping. + * Example 3: Input: [ [1,2], [2,3] ] + * + *

Output: 0 + * + *

Explanation: You don't need to remove any of the intervals since they're already + * non-overlapping. */ public class NonOverlappingIntervals { - public static class Interval { - int start; - int end; + public static class Interval { + int start; + int end; - Interval() { - start = 0; - end = 0; - } - - Interval(int s, int e) { - start = s; - end = e; - } + Interval() { + start = 0; + end = 0; } - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - Interval i1 = new Interval(1, 4); - Interval i2 = new Interval(5, 9); - Interval i3 = new Interval(3, 12); - //Interval i4 = new Interval(1, 3); - Interval[] intervals = {i1, i2, i3}; - System.out.println(new NonOverlappingIntervals().eraseOverlapIntervals(intervals)); + Interval(int s, int e) { + start = s; + end = e; } + } - public int eraseOverlapIntervals(Interval[] intervals) { - if (intervals.length == 0) return 0; - Arrays.sort(intervals, ((o1, o2) -> o1.end - o2.end)); - int count = 0; - Interval prev = intervals[0]; - for (int i = 1; i < intervals.length; i++) { - if (intervals[i].start < prev.end) { - count++; - } else { - prev = intervals[i]; - } - } - return count; - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + Interval i1 = new Interval(1, 4); + Interval i2 = new Interval(5, 9); + Interval i3 = new Interval(3, 12); + // Interval i4 = new Interval(1, 3); + Interval[] intervals = {i1, i2, i3}; + System.out.println(new NonOverlappingIntervals().eraseOverlapIntervals(intervals)); + } + public int eraseOverlapIntervals(Interval[] intervals) { + if (intervals.length == 0) return 0; + Arrays.sort(intervals, ((o1, o2) -> o1.end - o2.end)); + int count = 0; + Interval prev = intervals[0]; + for (int i = 1; i < intervals.length; i++) { + if (intervals[i].start < prev.end) { + count++; + } else { + prev = intervals[i]; + } + } + return count; + } } diff --git a/problems/src/greedy/QueueReconstructionByHeight.java b/problems/src/greedy/QueueReconstructionByHeight.java index 96269910..2ae1f5a7 100644 --- a/problems/src/greedy/QueueReconstructionByHeight.java +++ b/problems/src/greedy/QueueReconstructionByHeight.java @@ -4,37 +4,34 @@ import java.util.LinkedList; /** - * Created by gouthamvidyapradhan on 29/06/2017. - * Suppose you have a random list of people standing in a queue. Each person is described by a pair of integers (h, k), where h is the height of the person and k is the number of people in front of this person who have a height greater than or equal to h. Write an algorithm to reconstruct the queue. - *

- * Note: - * The number of people is less than 1,100. - *

- * Example - *

- * 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]] + * Created by gouthamvidyapradhan on 29/06/2017. Suppose you have a random list of people standing + * in a queue. Each person is described by a pair of integers (h, k), where h is the height of the + * person and k is the number of people in front of this person who have a height greater than or + * equal to h. Write an algorithm to reconstruct the queue. + * + *

Note: The number of people is less than 1,100. + * + *

Example + * + *

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 QueueReconstructionByHeight { - public static void main(String[] args) throws Exception { - int[][] A = {{7, 0}, {4, 4}, {7, 1}, {5, 0}, {6, 1}, {5, 2}}; - int[][] r = new QueueReconstructionByHeight().reconstructQueue(A); - for (int[] i : r) { - System.out.println(i[0] + " " + i[1]); - } + public static void main(String[] args) throws Exception { + int[][] A = {{7, 0}, {4, 4}, {7, 1}, {5, 0}, {6, 1}, {5, 2}}; + int[][] r = new QueueReconstructionByHeight().reconstructQueue(A); + for (int[] i : r) { + System.out.println(i[0] + " " + i[1]); } + } - public int[][] reconstructQueue(int[][] people) { - Arrays.sort(people, ((o1, o2) -> (o2[0] - o1[0] == 0) ? o1[1] - o2[1] : o2[0] - o1[0])); - LinkedList list = new LinkedList<>(); - for (int[] p : people) - list.add(p[1], p); - int[][] result = new int[people.length][2]; - for (int i = 0, l = list.size(); i < l; i++) - result[i] = list.get(i); - return result; - } + public int[][] reconstructQueue(int[][] people) { + Arrays.sort(people, ((o1, o2) -> (o2[0] - o1[0] == 0) ? o1[1] - o2[1] : o2[0] - o1[0])); + LinkedList list = new LinkedList<>(); + for (int[] p : people) list.add(p[1], p); + int[][] result = new int[people.length][2]; + for (int i = 0, l = list.size(); i < l; i++) result[i] = list.get(i); + return result; + } } diff --git a/problems/src/greedy/ScoreAfterFlippingMatrix.java b/problems/src/greedy/ScoreAfterFlippingMatrix.java index e9cc20ff..3fc6b6f1 100644 --- a/problems/src/greedy/ScoreAfterFlippingMatrix.java +++ b/problems/src/greedy/ScoreAfterFlippingMatrix.java @@ -1,102 +1,93 @@ package greedy; /** - * Created by gouthamvidyapradhan on 26/04/2019 - * We have a two dimensional matrix A where each value is 0 or 1. + * Created by gouthamvidyapradhan on 26/04/2019 We have a two dimensional matrix A where each value + * is 0 or 1. * - * A move consists of choosing any row or column, and toggling each value in that row or column: changing all 0s to - * 1s, and all 1s to 0s. + *

A move consists of choosing any row or column, and toggling each value in that row or column: + * changing all 0s to 1s, and all 1s to 0s. * - * After making any number of moves, every row of this matrix is interpreted as a binary number, and the score of - * the matrix is the sum of these numbers. + *

After making any number of moves, every row of this matrix is interpreted as a binary number, + * and the score of the matrix is the sum of these numbers. * - * Return the highest possible score. + *

Return the highest possible score. * + *

Example 1: * + *

Input: [[0,0,1,1],[1,0,1,0],[1,1,0,0]] Output: 39 Explanation: Toggled to + * [[1,1,1,1],[1,0,0,1],[1,1,1,1]]. 0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39 * - * Example 1: + *

Note: * - * Input: [[0,0,1,1],[1,0,1,0],[1,1,0,0]] - * Output: 39 - * Explanation: - * Toggled to [[1,1,1,1],[1,0,0,1],[1,1,1,1]]. - * 0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39 + *

1 <= A.length <= 20 1 <= A[0].length <= 20 A[i][j] is 0 or 1. * - * - * Note: - * - * 1 <= A.length <= 20 - * 1 <= A[0].length <= 20 - * A[i][j] is 0 or 1. - * - * Solution: O(N x N) - * Select each row and greedily flip the row if it maximizes the value. - * Select each column and flip the column if the count of 1's in the column is smaller than count - * of 0's + *

Solution: O(N x N) Select each row and greedily flip the row if it maximizes the value. Select + * each column and flip the column if the count of 1's in the column is smaller than count of 0's * Sum up the final value from each column return the answer. */ public class ScoreAfterFlippingMatrix { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int[][] A = {{1, 0}, {1, 0}, {1, 0}, {1, 1}}; - System.out.println(new ScoreAfterFlippingMatrix().matrixScore(A)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[][] A = {{1, 0}, {1, 0}, {1, 0}, {1, 1}}; + System.out.println(new ScoreAfterFlippingMatrix().matrixScore(A)); + } - public int matrixScore(int[][] A) { - for(int[] a : A){ - int temp1 = makeNum(a); - flip(a); - int temp2 = makeNum(a); - if(temp1 > temp2){ - //revert - flip(a); - } - } - for(int i = 0; i < A[0].length; i ++){ - int count = 0; - for(int j = 0; j < A.length; j ++){ - if(A[j][i] == 1){ - count++; - } - } - if(count < (A.length - count)){ - for(int j = 0; j < A.length; j ++){ - if(A[j][i] == 0){ - A[j][i] = 1; - } else{ - A[j][i] = 0; - } - } - } + public int matrixScore(int[][] A) { + for (int[] a : A) { + int temp1 = makeNum(a); + flip(a); + int temp2 = makeNum(a); + if (temp1 > temp2) { + // revert + flip(a); + } + } + for (int i = 0; i < A[0].length; i++) { + int count = 0; + for (int j = 0; j < A.length; j++) { + if (A[j][i] == 1) { + count++; } - int sum = 0; - for(int[] a : A){ - sum += makeNum(a); + } + if (count < (A.length - count)) { + for (int j = 0; j < A.length; j++) { + if (A[j][i] == 0) { + A[j][i] = 1; + } else { + A[j][i] = 0; + } } - return sum; + } + } + int sum = 0; + for (int[] a : A) { + sum += makeNum(a); } + return sum; + } - private int makeNum(int[] a){ - int n = 0; - for(int i = 0; i < a.length; i ++){ - if(a[i] == 1){ - n |= (1 << (a.length - i - 1)); - } - } - return n; + private int makeNum(int[] a) { + int n = 0; + for (int i = 0; i < a.length; i++) { + if (a[i] == 1) { + n |= (1 << (a.length - i - 1)); + } } + return n; + } - private void flip(int[] A){ - for(int i = 0; i < A.length; i ++){ - if(A[i] == 1){ - A[i] = 0; - } else{ - A[i] = 1; - } - } + private void flip(int[] A) { + for (int i = 0; i < A.length; i++) { + if (A[i] == 1) { + A[i] = 0; + } else { + A[i] = 1; + } } + } } diff --git a/problems/src/greedy/TaskScheduler.java b/problems/src/greedy/TaskScheduler.java index 96475a6a..d084359c 100644 --- a/problems/src/greedy/TaskScheduler.java +++ b/problems/src/greedy/TaskScheduler.java @@ -5,89 +5,90 @@ /** * Created by gouthamvidyapradhan on 26/11/2017. * - * Given a char array representing tasks CPU need to do. It contains capital letters A to Z where different letters represent different tasks.Tasks could be done without original order. Each task could be done in one interval. For each interval, CPU could finish one task or just be idle. - - However, there is a non-negative cooling interval n that means between two same tasks, there must be at least n intervals that CPU are doing different tasks or just be idle. - - You need to return the least number of intervals the CPU will take to finish all the given tasks. - - Example 1: - Input: tasks = ["A","A","A","B","B","B"], n = 2 - Output: 8 - Explanation: A -> B -> idle -> A -> B -> idle -> A -> B. - Note: - The number of tasks is in the range [1, 10000]. - The integer n is in the range [0, 100]. - + *

Given a char array representing tasks CPU need to do. It contains capital letters A to Z where + * different letters represent different tasks.Tasks could be done without original order. Each task + * could be done in one interval. For each interval, CPU could finish one task or just be idle. + * + *

However, there is a non-negative cooling interval n that means between two same tasks, there + * must be at least n intervals that CPU are doing different tasks or just be idle. + * + *

You need to return the least number of intervals the CPU will take to finish all the given + * tasks. + * + *

Example 1: Input: tasks = ["A","A","A","B","B","B"], n = 2 Output: 8 Explanation: A -> B -> + * idle -> A -> B -> idle -> A -> B. Note: The number of tasks is in the range [1, 10000]. The + * integer n is in the range [0, 100]. */ public class TaskScheduler { - class Task { - char t; - int count; - Task(char t, int count){ - this.t = t; - this.count = count; - } + class Task { + char t; + int count; - public int getCount() { - return count; - } + Task(char t, int count) { + this.t = t; + this.count = count; + } - public void setCount(int count) { - this.count = count; - } + public int getCount() { + return count; } - /** - * Main method - * @param args - */ - public static void main(String[] args) { - char[] tasks = {'A','A','A','B','B','B'}; - System.out.println(new TaskScheduler().leastInterval(tasks, 2)); + public void setCount(int count) { + this.count = count; } + } - /** - * - * @param tasks - * @param n - * @return - */ - public int leastInterval(char[] tasks, int n) { - PriorityQueue queue = new PriorityQueue<>(Comparator.comparing(Task::getCount).reversed()); - List waiting = new ArrayList<>(); - Map map = new HashMap<>(); - for(char c : tasks){ - if(map.get(c) == null){ - map.put(c, 1); - } else{ - int v = map.get(c) + 1; - map.put(c, v); - } - } - for(char c : map.keySet()){ - Task task = new Task(c, map.get(c)); - queue.offer(task); - } - int count = 0; - while(!queue.isEmpty()){ - int i = 0; - while(i <= n){ - if(!queue.isEmpty()){ - Task task = queue.poll(); - task.count--; - if(task.count > 0){ - waiting.add(task); - } - } - count++; - if(queue.isEmpty() && waiting.isEmpty()) break; - i++; - } - queue.addAll(waiting); - waiting.clear(); + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + char[] tasks = {'A', 'A', 'A', 'B', 'B', 'B'}; + System.out.println(new TaskScheduler().leastInterval(tasks, 2)); + } + + /** + * @param tasks + * @param n + * @return + */ + public int leastInterval(char[] tasks, int n) { + PriorityQueue queue = + new PriorityQueue<>(Comparator.comparing(Task::getCount).reversed()); + List waiting = new ArrayList<>(); + Map map = new HashMap<>(); + for (char c : tasks) { + if (map.get(c) == null) { + map.put(c, 1); + } else { + int v = map.get(c) + 1; + map.put(c, v); + } + } + for (char c : map.keySet()) { + Task task = new Task(c, map.get(c)); + queue.offer(task); + } + int count = 0; + while (!queue.isEmpty()) { + int i = 0; + while (i <= n) { + if (!queue.isEmpty()) { + Task task = queue.poll(); + task.count--; + if (task.count > 0) { + waiting.add(task); + } } - return count; + count++; + if (queue.isEmpty() && waiting.isEmpty()) break; + i++; + } + queue.addAll(waiting); + waiting.clear(); } + return count; + } } diff --git a/problems/src/hashing/Anagrams.java b/problems/src/hashing/Anagrams.java index a9a91aa1..6bcbba8c 100644 --- a/problems/src/hashing/Anagrams.java +++ b/problems/src/hashing/Anagrams.java @@ -5,83 +5,73 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 25/02/2017. - * 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. - *

- * Example 1: - *

- * 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". - * Example 2: - *

- * Input: - * s: "abab" p: "ab" - *

- * Output: - * [0, 1, 2] - *

- * Explanation: - * The substring with start index = 0 is "ab", which is an anagram of "ab". - * The substring with start index = 1 is "ba", which is an anagram of "ab". - * The substring with start index = 2 is "ab", which is an anagram of "ab". + * Created by gouthamvidyapradhan on 25/02/2017. 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. + * + *

Example 1: + * + *

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". Example 2: + * + *

Input: s: "abab" p: "ab" + * + *

Output: [0, 1, 2] + * + *

Explanation: The substring with start index = 0 is "ab", which is an anagram of "ab". The + * substring with start index = 1 is "ba", which is an anagram of "ab". The substring with start + * index = 2 is "ab", which is an anagram of "ab". */ public class Anagrams { - int[] TC = new int[256]; - int[] PC = new int[256]; + int[] TC = new int[256]; + int[] PC = new int[256]; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - List result = new Anagrams().findAnagrams("abab", "ab"); - result.forEach(System.out::print); - } - - public List findAnagrams(String s, String p) { - List result = new ArrayList<>(); - int pLen = p.length(); - if (pLen > s.length()) return result; - Arrays.fill(TC, 0); - Arrays.fill(PC, 0); - for (int i = 0; i < pLen; i++) { - TC[s.charAt(i)]++; - PC[p.charAt(i)]++; - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + List result = new Anagrams().findAnagrams("abab", "ab"); + result.forEach(System.out::print); + } - int i = pLen; - for (int l = s.length(); i < l; i++) { - if (compare()) - result.add(i - pLen); + public List findAnagrams(String s, String p) { + List result = new ArrayList<>(); + int pLen = p.length(); + if (pLen > s.length()) return result; + Arrays.fill(TC, 0); + Arrays.fill(PC, 0); + for (int i = 0; i < pLen; i++) { + TC[s.charAt(i)]++; + PC[p.charAt(i)]++; + } - TC[s.charAt(i)]++; - TC[s.charAt(i - pLen)]--; - } - if (compare()) - result.add(i - pLen); + int i = pLen; + for (int l = s.length(); i < l; i++) { + if (compare()) result.add(i - pLen); - return result; + TC[s.charAt(i)]++; + TC[s.charAt(i - pLen)]--; } + if (compare()) result.add(i - pLen); - private boolean compare() { - for (int i = 0; i < 256; i++) { - if (TC[i] != PC[i]) - return false; - } - return true; - } + return result; + } + private boolean compare() { + for (int i = 0; i < 256; i++) { + if (TC[i] != PC[i]) return false; + } + return true; + } } diff --git a/problems/src/hashing/BrickWall.java b/problems/src/hashing/BrickWall.java index b3e824f1..3376c5b3 100644 --- a/problems/src/hashing/BrickWall.java +++ b/problems/src/hashing/BrickWall.java @@ -6,90 +6,97 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 19/01/2018. - * There is a brick wall in front of you. The wall is rectangular and has several rows of bricks. The bricks have - * the same height but different width. You want to draw a vertical line from the top to the bottom and cross the least bricks. - - The brick wall is represented by a list of rows. Each row is a list of integers representing the width of each - brick in this row from left to right. - - If your line go through the edge of a brick, then the brick is not considered as crossed. You need to find out how - to draw the line to cross the least bricks and return the number of crossed bricks. - - You cannot draw a line just along one of the two vertical edges of the wall, in which case the line will obviously - cross no bricks. - - Example: - Input: - [[1,2,2,1], - [3,1,2], - [1,3,2], - [2,4], - [3,1,2], - [1,3,1,1]] - Output: 2 - Explanation: - - Note: - The width sum of bricks in different rows are the same and won't exceed INT_MAX. - The number of bricks in each row is in range [1,10,000]. The height of wall is in range [1,10,000]. Total number of - bricks of the wall won't exceed 20,000. - - Solution: O(N) where N is the total number of bricks. Calculate the prefix sum for each row of bricks and - keep a max_count of each occurrence of prefix. The answer is total number of rows of bricks - max_count + * Created by gouthamvidyapradhan on 19/01/2018. There is a brick wall in front of you. The wall is + * rectangular and has several rows of bricks. The bricks have the same height but different width. + * You want to draw a vertical line from the top to the bottom and cross the least bricks. + * + *

The brick wall is represented by a list of rows. Each row is a list of integers representing + * the width of each brick in this row from left to right. + * + *

If your line go through the edge of a brick, then the brick is not considered as crossed. You + * need to find out how to draw the line to cross the least bricks and return the number of crossed + * bricks. + * + *

You cannot draw a line just along one of the two vertical edges of the wall, in which case the + * line will obviously cross no bricks. + * + *

Example: Input: [[1,2,2,1], [3,1,2], [1,3,2], [2,4], [3,1,2], [1,3,1,1]] Output: 2 + * Explanation: + * + *

Note: The width sum of bricks in different rows are the same and won't exceed INT_MAX. The + * number of bricks in each row is in range [1,10,000]. The height of wall is in range [1,10,000]. + * Total number of bricks of the wall won't exceed 20,000. + * + *

Solution: O(N) where N is the total number of bricks. Calculate the prefix sum for each row of + * bricks and keep a max_count of each occurrence of prefix. The answer is total number of rows of + * bricks - max_count */ public class BrickWall { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - List> wall = new ArrayList<>(); - List row1 = new ArrayList<>(); - List row2 = new ArrayList<>(); - List row3 = new ArrayList<>(); - List row4 = new ArrayList<>(); - List row5 = new ArrayList<>(); - List row6 = new ArrayList<>(); - row1.add(1); row1.add(2); row1.add(2); row1.add(1); - row2.add(3); row2.add(1); row2.add(2); - row3.add(1); row3.add(3); row3.add(2); - row4.add(2); row4.add(4); - row5.add(3); row5.add(1); row5.add(2); - row6.add(1); row6.add(3); row6.add(1); row6.add(1); - wall.add(row1); - wall.add(row2); - wall.add(row3); - wall.add(row4); - wall.add(row5); - wall.add(row6); - System.out.println(new BrickWall().leastBricks(wall)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + List> wall = new ArrayList<>(); + List row1 = new ArrayList<>(); + List row2 = new ArrayList<>(); + List row3 = new ArrayList<>(); + List row4 = new ArrayList<>(); + List row5 = new ArrayList<>(); + List row6 = new ArrayList<>(); + row1.add(1); + row1.add(2); + row1.add(2); + row1.add(1); + row2.add(3); + row2.add(1); + row2.add(2); + row3.add(1); + row3.add(3); + row3.add(2); + row4.add(2); + row4.add(4); + row5.add(3); + row5.add(1); + row5.add(2); + row6.add(1); + row6.add(3); + row6.add(1); + row6.add(1); + wall.add(row1); + wall.add(row2); + wall.add(row3); + wall.add(row4); + wall.add(row5); + wall.add(row6); + System.out.println(new BrickWall().leastBricks(wall)); + } - public int leastBricks(List> wall) { - for(List row : wall){ - int prefix = 0; - for(int i = 0, l = row.size(); i < l; i ++){ - prefix += row.get(i); - row.set(i, prefix); - } - } - int result = Integer.MIN_VALUE; - Map map = new HashMap<>(); - for(List row : wall){ - for(int i = 0, l = row.size(); i < l - 1; i ++){ - int prefix = row.get(i); - if(map.containsKey(prefix)){ - int plusOne = map.get(prefix) + 1; - map.put(prefix, plusOne); - result = Math.max(result, plusOne); - } else{ - map.put(prefix, 1); - result = Math.max(result, 1); - } - } + public int leastBricks(List> wall) { + for (List row : wall) { + int prefix = 0; + for (int i = 0, l = row.size(); i < l; i++) { + prefix += row.get(i); + row.set(i, prefix); + } + } + int result = Integer.MIN_VALUE; + Map map = new HashMap<>(); + for (List row : wall) { + for (int i = 0, l = row.size(); i < l - 1; i++) { + int prefix = row.get(i); + if (map.containsKey(prefix)) { + int plusOne = map.get(prefix) + 1; + map.put(prefix, plusOne); + result = Math.max(result, plusOne); + } else { + map.put(prefix, 1); + result = Math.max(result, 1); } - return (result == Integer.MIN_VALUE) ? wall.size() : wall.size() - result; + } } + return (result == Integer.MIN_VALUE) ? wall.size() : wall.size() - result; + } } diff --git a/problems/src/hashing/ContiguousArray.java b/problems/src/hashing/ContiguousArray.java index a46776af..2702df6f 100644 --- a/problems/src/hashing/ContiguousArray.java +++ b/problems/src/hashing/ContiguousArray.java @@ -4,53 +4,50 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 16/12/2017. - * Given a binary array, find the maximum length of a contiguous subarray with equal number of 0 and 1. - - Example 1: - Input: [0,1] - Output: 2 - Explanation: [0, 1] is the longest contiguous subarray with equal number of 0 and 1. - Example 2: - Input: [0,1,0] - Output: 2 - Explanation: [0, 1] (or [1, 0]) is a longest contiguous subarray with equal number of 0 and 1. - Note: The length of the given binary array will not exceed 50,000. - - Solution: O(n) keep a count variable and increment count when a 1 is found and decrement count when a 0 is found. - Maintain a map of count and its corresponding index. if the count repeats itself then take the difference of the - current index and the index saved in the map. Max of the difference is the answer. + * Created by gouthamvidyapradhan on 16/12/2017. Given a binary array, find the maximum length of a + * contiguous subarray with equal number of 0 and 1. + * + *

Example 1: Input: [0,1] Output: 2 Explanation: [0, 1] is the longest contiguous subarray with + * equal number of 0 and 1. Example 2: Input: [0,1,0] Output: 2 Explanation: [0, 1] (or [1, 0]) is a + * longest contiguous subarray with equal number of 0 and 1. Note: The length of the given binary + * array will not exceed 50,000. + * + *

Solution: O(n) keep a count variable and increment count when a 1 is found and decrement count + * when a 0 is found. Maintain a map of count and its corresponding index. if the count repeats + * itself then take the difference of the current index and the index saved in the map. Max of the + * difference is the answer. */ public class ContiguousArray { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1, 1}; - System.out.println(new ContiguousArray().findMaxLength(A)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 1}; + System.out.println(new ContiguousArray().findMaxLength(A)); + } - public int findMaxLength(int[] nums) { - Map map = new HashMap<>(); - int count = 0; - int max = 0; - for(int i = 0; i < nums.length; i ++){ - if(nums[i] == 0){ - count--; - } else count++; - if(count == 0){ - max = Math.max(max, i + 1); - } else { - if(map.containsKey(count)){ - int index = map.get(count); - max = Math.max(max, i - index); - } else{ - map.put(count, i); - } - } + public int findMaxLength(int[] nums) { + Map map = new HashMap<>(); + int count = 0; + int max = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] == 0) { + count--; + } else count++; + if (count == 0) { + max = Math.max(max, i + 1); + } else { + if (map.containsKey(count)) { + int index = map.get(count); + max = Math.max(max, i - index); + } else { + map.put(count, i); } - return max; + } } + return max; + } } diff --git a/problems/src/hashing/CustomSortString.java b/problems/src/hashing/CustomSortString.java index f9efef15..de7e44bb 100644 --- a/problems/src/hashing/CustomSortString.java +++ b/problems/src/hashing/CustomSortString.java @@ -3,67 +3,62 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 01/05/2018. - * S and T are strings composed of lowercase letters. In S, no letter occurs more than once. - - S was sorted in some custom order previously. We want to permute the characters of T so that they match the order - that S was sorted. More specifically, if x occurs before y in S, then x should occur before y in the returned string. - - Return any permutation of T (as a string) that satisfies this property. - - Example : - Input: - S = "cba" - T = "abcd" - Output: "cbad" - Explanation: - "a", "b", "c" appear in S, so the order of "a", "b", "c" should be "c", "b", and "a". - Since "d" does not appear in S, it can be at any position in T. "dcba", "cdba", "cbda" are also valid outputs. - - - Note: - - S has length at most 26, and no character is repeated in S. - T has length at most 200. - S and T consist of lowercase letters only. - - Solution: O(N) count occurrence of each character and write to the output string + * Created by gouthamvidyapradhan on 01/05/2018. S and T are strings composed of lowercase letters. + * In S, no letter occurs more than once. + * + *

S was sorted in some custom order previously. We want to permute the characters of T so that + * they match the order that S was sorted. More specifically, if x occurs before y in S, then x + * should occur before y in the returned string. + * + *

Return any permutation of T (as a string) that satisfies this property. + * + *

Example : Input: S = "cba" T = "abcd" Output: "cbad" Explanation: "a", "b", "c" appear in S, + * so the order of "a", "b", "c" should be "c", "b", and "a". Since "d" does not appear in S, it can + * be at any position in T. "dcba", "cdba", "cbda" are also valid outputs. + * + *

Note: + * + *

S has length at most 26, and no character is repeated in S. T has length at most 200. S and T + * consist of lowercase letters only. + * + *

Solution: O(N) count occurrence of each character and write to the output string */ public class CustomSortString { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new CustomSortString().customSortString("cba", "abcd")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new CustomSortString().customSortString("cba", "abcd")); + } - public String customSortString(String S, String T) { - Map map = new HashMap<>(); - for(int i = 0; i < T.length(); i ++){ - if(!map.containsKey(T.charAt(i))){ - map.put(T.charAt(i), 1); - } else{ - map.put(T.charAt(i), map.get(T.charAt(i)) + 1); - } - } - StringBuilder result = new StringBuilder(); - for(char c : S.toCharArray()){ - if(map.containsKey(c)){ - int count = map.remove(c); - for(int i = 0; i < count; i ++){ - result.append(c); - } - } - } - for(char c : map.keySet()){ - int count = map.get(c); - for(int i = 0; i < count; i ++){ - result.append(c); - } + public String customSortString(String S, String T) { + Map map = new HashMap<>(); + for (int i = 0; i < T.length(); i++) { + if (!map.containsKey(T.charAt(i))) { + map.put(T.charAt(i), 1); + } else { + map.put(T.charAt(i), map.get(T.charAt(i)) + 1); + } + } + StringBuilder result = new StringBuilder(); + for (char c : S.toCharArray()) { + if (map.containsKey(c)) { + int count = map.remove(c); + for (int i = 0; i < count; i++) { + result.append(c); } - return result.toString(); + } + } + for (char c : map.keySet()) { + int count = map.get(c); + for (int i = 0; i < count; i++) { + result.append(c); + } } + return result.toString(); + } } diff --git a/problems/src/hashing/DistributeCandies.java b/problems/src/hashing/DistributeCandies.java index a3a8038a..9b8d18f5 100644 --- a/problems/src/hashing/DistributeCandies.java +++ b/problems/src/hashing/DistributeCandies.java @@ -1,42 +1,35 @@ package hashing; + import java.util.*; /** - * Created by gouthamvidyapradhan on 25/04/2019 - * Given an integer array with even length, where different numbers in this array represent different kinds of - * candies. Each number means one candy of the corresponding kind. You need to distribute these candies equally in number to brother and sister. Return the maximum number of kinds of candies the sister could gain. - * Example 1: - * Input: candies = [1,1,2,2,3,3] - * Output: 3 - * Explanation: - * There are three different kinds of candies (1, 2 and 3), and two candies for each kind. - * Optimal distribution: The sister has candies [1,2,3] and the brother has candies [1,2,3], too. - * The sister has three different kinds of candies. - * Example 2: - * Input: candies = [1,1,2,3] - * Output: 2 - * Explanation: For example, the sister has candies [2,3] and the brother has candies [1,1]. - * The sister has two different kinds of candies, the brother has only one kind of candies. - * Note: + * Created by gouthamvidyapradhan on 25/04/2019 Given an integer array with even length, where + * different numbers in this array represent different kinds of candies. Each number means one candy + * of the corresponding kind. You need to distribute these candies equally in number to brother and + * sister. Return the maximum number of kinds of candies the sister could gain. Example 1: Input: + * candies = [1,1,2,2,3,3] Output: 3 Explanation: There are three different kinds of candies (1, 2 + * and 3), and two candies for each kind. Optimal distribution: The sister has candies [1,2,3] and + * the brother has candies [1,2,3], too. The sister has three different kinds of candies. Example 2: + * Input: candies = [1,1,2,3] Output: 2 Explanation: For example, the sister has candies [2,3] and + * the brother has candies [1,1]. The sister has two different kinds of candies, the brother has + * only one kind of candies. Note: * - * The length of the given array is in range [2, 10,000], and will be even. - * The number in given array is in range [-100,000, 100,000]. + *

The length of the given array is in range [2, 10,000], and will be even. The number in given + * array is in range [-100,000, 100,000]. * - * Solution: O(N) Use a HashSet to identify all the different possible candies. The maximum types of - * candies sister can get is always Min(N/2, Number Of Unique Type of Candies) + *

Solution: O(N) Use a HashSet to identify all the different possible candies. The maximum types + * of candies sister can get is always Min(N/2, Number Of Unique Type of Candies) */ public class DistributeCandies { - public static void main(String[] args) { - - } + public static void main(String[] args) {} - public int distributeCandies(int[] candies) { - int N = candies.length; - Set set = new HashSet<>(); - for(int c : candies){ - set.add(c); - } - int n = set.size(); - return Math.min(N / 2, set.size()); + public int distributeCandies(int[] candies) { + int N = candies.length; + Set set = new HashSet<>(); + for (int c : candies) { + set.add(c); } + int n = set.size(); + return Math.min(N / 2, set.size()); + } } diff --git a/problems/src/hashing/GroupAnagrams.java b/problems/src/hashing/GroupAnagrams.java index 06ba7b78..69251926 100644 --- a/problems/src/hashing/GroupAnagrams.java +++ b/problems/src/hashing/GroupAnagrams.java @@ -6,63 +6,51 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 10/03/2017. - * Given an array of strings, group anagrams together. - *

- * For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"], - * Return: - *

- * [ - * ["ate", "eat","tea"], - * ["nat","tan"], - * ["bat"] - * ] - * Note: All inputs will be in lower-case. + * Created by gouthamvidyapradhan on 10/03/2017. Given an array of strings, group anagrams together. + * + *

For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"], Return: + * + *

[ ["ate", "eat","tea"], ["nat","tan"], ["bat"] ] Note: All inputs will be in lower-case. */ public class GroupAnagrams { - private int[] A = new int[256]; - private HashMap> hashMap = new HashMap<>(); - private List> result = new ArrayList<>(); - - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - String[] strs = {"huh", "tit"}; - - List> result = new GroupAnagrams().groupAnagrams(strs); - for (List l : result) { - for (String s : l) - System.out.println(s); - System.out.println("-----"); - } + private int[] A = new int[256]; + private HashMap> hashMap = new HashMap<>(); + private List> result = new ArrayList<>(); + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + String[] strs = {"huh", "tit"}; + + List> result = new GroupAnagrams().groupAnagrams(strs); + for (List l : result) { + for (String s : l) System.out.println(s); + System.out.println("-----"); + } + } + + public List> groupAnagrams(String[] strs) { + for (int i = 0, l = strs.length; i < l; i++) { + Arrays.fill(A, 0); + String s = strs[i]; + for (int j = 0, sl = s.length(); j < sl; j++) A[s.charAt(j)]++; + + StringBuilder sb = new StringBuilder(); + for (int k = 0; k < 256; k++) { + if (A[k] != 0) sb.append(k).append("").append(A[k]); + } + List value = hashMap.get(sb.toString()); + if (value == null) value = new ArrayList<>(); + value.add(s); + hashMap.put(sb.toString(), value); } - public List> groupAnagrams(String[] strs) { - for (int i = 0, l = strs.length; i < l; i++) { - Arrays.fill(A, 0); - String s = strs[i]; - for (int j = 0, sl = s.length(); j < sl; j++) - A[s.charAt(j)]++; - - StringBuilder sb = new StringBuilder(); - for (int k = 0; k < 256; k++) { - if (A[k] != 0) - sb.append(k).append("").append(A[k]); - } - List value = hashMap.get(sb.toString()); - if (value == null) - value = new ArrayList<>(); - value.add(s); - hashMap.put(sb.toString(), value); - } - - for (String s : hashMap.keySet()) - result.add(hashMap.get(s)); + for (String s : hashMap.keySet()) result.add(hashMap.get(s)); - return result; - } + return result; + } } diff --git a/problems/src/hashing/GroupsOfSpecialEquivalentStrings.java b/problems/src/hashing/GroupsOfSpecialEquivalentStrings.java index 2d80b1a9..fd37ad63 100644 --- a/problems/src/hashing/GroupsOfSpecialEquivalentStrings.java +++ b/problems/src/hashing/GroupsOfSpecialEquivalentStrings.java @@ -1,85 +1,72 @@ package hashing; + import java.util.*; /** - * Created by gouthamvidyapradhan on 30/04/2019 - * You are given an array A of strings. - * - * Two strings S and T are special-equivalent if after any number of moves, S == T. - * - * A move consists of choosing two indices i and j with i % 2 == j % 2, and swapping S[i] with S[j]. + * Created by gouthamvidyapradhan on 30/04/2019 You are given an array A of strings. * - * Now, a group of special-equivalent strings from A is a non-empty subset S of A such that any string not in S is - * not special-equivalent with any string in S. + *

Two strings S and T are special-equivalent if after any number of moves, S == T. * - * Return the number of groups of special-equivalent strings from A. + *

A move consists of choosing two indices i and j with i % 2 == j % 2, and swapping S[i] with + * S[j]. * + *

Now, a group of special-equivalent strings from A is a non-empty subset S of A such that any + * string not in S is not special-equivalent with any string in S. * + *

Return the number of groups of special-equivalent strings from A. * - * Example 1: + *

Example 1: * - * Input: ["a","b","c","a","c","c"] - * Output: 3 - * Explanation: 3 groups ["a","a"], ["b"], ["c","c","c"] - * Example 2: + *

Input: ["a","b","c","a","c","c"] Output: 3 Explanation: 3 groups ["a","a"], ["b"], + * ["c","c","c"] Example 2: * - * Input: ["aa","bb","ab","ba"] - * Output: 4 - * Explanation: 4 groups ["aa"], ["bb"], ["ab"], ["ba"] + *

Input: ["aa","bb","ab","ba"] Output: 4 Explanation: 4 groups ["aa"], ["bb"], ["ab"], ["ba"] * Example 3: * - * Input: ["abc","acb","bac","bca","cab","cba"] - * Output: 3 - * Explanation: 3 groups ["abc","cba"], ["acb","bca"], ["bac","cab"] - * Example 4: + *

Input: ["abc","acb","bac","bca","cab","cba"] Output: 3 Explanation: 3 groups ["abc","cba"], + * ["acb","bca"], ["bac","cab"] Example 4: * - * Input: ["abcd","cdab","adcb","cbad"] - * Output: 1 - * Explanation: 1 group ["abcd","cdab","adcb","cbad"] + *

Input: ["abcd","cdab","adcb","cbad"] Output: 1 Explanation: 1 group + * ["abcd","cdab","adcb","cbad"] * + *

Note: * - * Note: + *

1 <= A.length <= 1000 1 <= A[i].length <= 20 All A[i] have the same length. All A[i] consist + * of only lowercase letters. * - * 1 <= A.length <= 1000 - * 1 <= A[i].length <= 20 - * All A[i] have the same length. - * All A[i] consist of only lowercase letters. - * - * Solution: - * The character array of odd positions and even positions of two special-equivalent strings - * should be exactly equal after sorting. Use a hashset to count number of such groups. + *

Solution: The character array of odd positions and even positions of two special-equivalent + * strings should be exactly equal after sorting. Use a hashset to count number of such groups. */ public class GroupsOfSpecialEquivalentStrings { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) {} - public int numSpecialEquivGroups(String[] A) { - Set set = new HashSet<>(); - for(String s : A){ - StringBuilder temp1 = new StringBuilder(); - for(int i = 0, l = s.length(); i < l; i += 2){ - char c = s.charAt(i); - temp1.append(c); - } - StringBuilder temp2 = new StringBuilder(); - if(s.length() > 1){ - for(int i = 1, l = s.length(); i < l; i += 2){ - char c = s.charAt(i); - temp2.append(c); - } - } - char[] temp1Chars = temp1.toString().toCharArray(); - char[] temp2Chars = temp2.toString().toCharArray(); - Arrays.sort(temp1Chars); - Arrays.sort(temp2Chars); - set.add(String.valueOf(temp1Chars) + "+" + String.valueOf(temp2Chars)); + public int numSpecialEquivGroups(String[] A) { + Set set = new HashSet<>(); + for (String s : A) { + StringBuilder temp1 = new StringBuilder(); + for (int i = 0, l = s.length(); i < l; i += 2) { + char c = s.charAt(i); + temp1.append(c); + } + StringBuilder temp2 = new StringBuilder(); + if (s.length() > 1) { + for (int i = 1, l = s.length(); i < l; i += 2) { + char c = s.charAt(i); + temp2.append(c); } - return set.size(); + } + char[] temp1Chars = temp1.toString().toCharArray(); + char[] temp2Chars = temp2.toString().toCharArray(); + Arrays.sort(temp1Chars); + Arrays.sort(temp2Chars); + set.add(String.valueOf(temp1Chars) + "+" + String.valueOf(temp2Chars)); } + return set.size(); + } } diff --git a/problems/src/hashing/KdiffPairsInanArray.java b/problems/src/hashing/KdiffPairsInanArray.java index 4f9b2ca2..ab5ef28a 100644 --- a/problems/src/hashing/KdiffPairsInanArray.java +++ b/problems/src/hashing/KdiffPairsInanArray.java @@ -4,57 +4,46 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 28/03/2017. - * Given an array of integers and an integer k, you need to find the number of unique k-diff pairs in the array. Here a k-diff pair is defined as an integer pair (i, j), where i and j are both numbers in the array and their absolute difference is k. - *

- * Example 1: - * Input: [3, 1, 4, 1, 5], k = 2 - * Output: 2 - * Explanation: There are two 2-diff pairs in the array, (1, 3) and (3, 5). - * Although we have two 1s in the input, we should only return the number of unique pairs. - * Example 2: - * Input:[1, 2, 3, 4, 5], k = 1 - * Output: 4 - * Explanation: There are four 1-diff pairs in the array, (1, 2), (2, 3), (3, 4) and (4, 5). - * Example 3: - * Input: [1, 3, 1, 5, 4], k = 0 - * Output: 1 - * Explanation: There is one 0-diff pair in the array, (1, 1). - * Note: - * The pairs (i, j) and (j, i) count as the same pair. - * The length of the array won't exceed 10,000. - * All the integers in the given input belong to the range: [-1e7, 1e7]. + * Created by gouthamvidyapradhan on 28/03/2017. Given an array of integers and an integer k, you + * need to find the number of unique k-diff pairs in the array. Here a k-diff pair is defined as an + * integer pair (i, j), where i and j are both numbers in the array and their absolute difference is + * k. + * + *

Example 1: Input: [3, 1, 4, 1, 5], k = 2 Output: 2 Explanation: There are two 2-diff pairs in + * the array, (1, 3) and (3, 5). Although we have two 1s in the input, we should only return the + * number of unique pairs. Example 2: Input:[1, 2, 3, 4, 5], k = 1 Output: 4 Explanation: There are + * four 1-diff pairs in the array, (1, 2), (2, 3), (3, 4) and (4, 5). Example 3: Input: [1, 3, 1, 5, + * 4], k = 0 Output: 1 Explanation: There is one 0-diff pair in the array, (1, 1). Note: The pairs + * (i, j) and (j, i) count as the same pair. The length of the array won't exceed 10,000. All the + * integers in the given input belong to the range: [-1e7, 1e7]. */ public class KdiffPairsInanArray { - private Map map = new HashMap<>(); - private int count = 0; + private Map map = new HashMap<>(); + private int count = 0; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] nums = {1, 2, 3, 4, 5}; - System.out.println(new KdiffPairsInanArray().findPairs(nums, -1)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] nums = {1, 2, 3, 4, 5}; + System.out.println(new KdiffPairsInanArray().findPairs(nums, -1)); + } - public int findPairs(int[] nums, int k) { - if (nums.length == 0 || k < 0) return 0; - for (int i : nums) { - map.put(i, map.getOrDefault(i, 0) + 1); - } - for (Map.Entry entry : map.entrySet()) { - if (k == 0) { - if (entry.getValue() > 1) - count++; - } else { - if (map.containsKey(entry.getKey() + k)) - count++; - } - } - return count; + public int findPairs(int[] nums, int k) { + if (nums.length == 0 || k < 0) return 0; + for (int i : nums) { + map.put(i, map.getOrDefault(i, 0) + 1); } - + for (Map.Entry entry : map.entrySet()) { + if (k == 0) { + if (entry.getValue() > 1) count++; + } else { + if (map.containsKey(entry.getKey() + k)) count++; + } + } + return count; + } } diff --git a/problems/src/hashing/MaximumSizeSubarraySumEqualsk.java b/problems/src/hashing/MaximumSizeSubarraySumEqualsk.java index ac97da99..9616f9a4 100644 --- a/problems/src/hashing/MaximumSizeSubarraySumEqualsk.java +++ b/problems/src/hashing/MaximumSizeSubarraySumEqualsk.java @@ -4,60 +4,56 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 18/10/2017. - * Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If there isn't - * one, return 0 instead. - - Note: - The sum of the entire nums array is guaranteed to fit within the 32-bit signed integer range. - - Example 1: - Given nums = [1, -1, 5, -2, 3], k = 3, - return 4. (because the subarray [1, -1, 5, -2] sums to 3 and is the longest) - - Example 2: - Given nums = [-2, -1, 2, 1], k = 1, - return 2. (because the subarray [-1, 2] sums to 1 and is the longest) - - Follow Up: - Can you do it in O(n) time? + * Created by gouthamvidyapradhan on 18/10/2017. Given an array nums and a target value k, find the + * maximum length of a subarray that sums to k. If there isn't one, return 0 instead. + * + *

Note: The sum of the entire nums array is guaranteed to fit within the 32-bit signed integer + * range. + * + *

Example 1: Given nums = [1, -1, 5, -2, 3], k = 3, return 4. (because the subarray [1, -1, 5, + * -2] sums to 3 and is the longest) + * + *

Example 2: Given nums = [-2, -1, 2, 1], k = 1, return 2. (because the subarray [-1, 2] sums to + * 1 and is the longest) + * + *

Follow Up: Can you do it in O(n) time? */ public class MaximumSizeSubarraySumEqualsk { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1,-1,5,-2,3}; - System.out.println(new MaximumSizeSubarraySumEqualsk().maxSubArrayLen(A, 10)); + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, -1, 5, -2, 3}; + System.out.println(new MaximumSizeSubarraySumEqualsk().maxSubArrayLen(A, 10)); + } + + public int maxSubArrayLen(int[] nums, int k) { + Map index = new HashMap<>(); + int sum = 0; + for (int i = 0; i < nums.length; i++) { + sum += nums[i]; + index.putIfAbsent(sum, i); } - - public int maxSubArrayLen(int[] nums, int k) { - Map index = new HashMap<>(); - int sum = 0; - for(int i = 0; i < nums.length; i ++){ - sum += nums[i]; - index.putIfAbsent(sum, i); - } - sum = 0; - int ans = 0; - for(int i = 0; i < nums.length; i ++){ - sum += nums[i]; - if(sum == k){ - ans = Math.max(ans, i + 1); - } else{ - int exp = sum - k; - if(index.containsKey(exp)){ - int farLeft = index.get(exp); - if(farLeft < i){ - ans = Math.max(ans, i - index.get(exp)); - } - } - } + sum = 0; + int ans = 0; + for (int i = 0; i < nums.length; i++) { + sum += nums[i]; + if (sum == k) { + ans = Math.max(ans, i + 1); + } else { + int exp = sum - k; + if (index.containsKey(exp)) { + int farLeft = index.get(exp); + if (farLeft < i) { + ans = Math.max(ans, i - index.get(exp)); + } } - return ans; + } } - + return ans; + } } diff --git a/problems/src/hashing/PartitionLabels.java b/problems/src/hashing/PartitionLabels.java index 498d04f5..0b00ccdd 100644 --- a/problems/src/hashing/PartitionLabels.java +++ b/problems/src/hashing/PartitionLabels.java @@ -6,58 +6,54 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 10/04/2018. - * A string S of lowercase 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. - - Example 1: - 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. - Note: - - S will have length in range [1, 500]. - S will consist of lowercase letters ('a' to 'z') only. - - Solution O(n): Maintain a hashmap index of last occurrence of a character and do a linear check for max index, get - the length and add it to the result set. + * Created by gouthamvidyapradhan on 10/04/2018. A string S of lowercase 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. + * + *

Example 1: 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. Note: + * + *

S will have length in range [1, 500]. S will consist of lowercase letters ('a' to 'z') only. + * + *

Solution O(n): Maintain a hashmap index of last occurrence of a character and do a linear + * check for max index, get the length and add it to the result set. */ -public class PartitionLabels{ +public class PartitionLabels { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new PartitionLabels().partitionLabels("abc")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new PartitionLabels().partitionLabels("abc")); + } - public List partitionLabels(String S) { - if(S == null || S.trim().isEmpty()) return new ArrayList<>(); - Map map = new HashMap<>(); - for(int i = S.length() - 1; i >= 0; i --){ - char c = S.charAt(i); - map.putIfAbsent(c, i); - } - List result = new ArrayList<>(); - int start = 0; - int max = map.get(S.charAt(0)); - for(int i = 0; i < S.length(); i ++){ - char c = S.charAt(i); - if(map.get(c) > max){ - max = map.get(c); - } else if(i == max){ - result.add(max - start + 1); - if(i < S.length() - 1){ - start = i + 1; - max = map.get(S.charAt(i + 1)); - } - } + public List partitionLabels(String S) { + if (S == null || S.trim().isEmpty()) return new ArrayList<>(); + Map map = new HashMap<>(); + for (int i = S.length() - 1; i >= 0; i--) { + char c = S.charAt(i); + map.putIfAbsent(c, i); + } + List result = new ArrayList<>(); + int start = 0; + int max = map.get(S.charAt(0)); + for (int i = 0; i < S.length(); i++) { + char c = S.charAt(i); + if (map.get(c) > max) { + max = map.get(c); + } else if (i == max) { + result.add(max - start + 1); + if (i < S.length() - 1) { + start = i + 1; + max = map.get(S.charAt(i + 1)); } - return result; + } } + return result; + } } diff --git a/problems/src/hashing/ShortEncodingOfWords.java b/problems/src/hashing/ShortEncodingOfWords.java index c9d2a556..56b80a15 100644 --- a/problems/src/hashing/ShortEncodingOfWords.java +++ b/problems/src/hashing/ShortEncodingOfWords.java @@ -3,62 +3,60 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 04/05/2018. - * Given a list of words, we may encode it by writing a reference string S and a list of indexes A. - - For example, if the list of words is ["time", "me", "bell"], we can write it as S = "time#bell#" and indexes = [0, - 2, 5]. - - Then for each index, we will recover the word by reading from the reference string from that index until we reach a - "#" character. - - What is the length of the shortest reference string S possible that encodes the given words? - - Example: - - Input: words = ["time", "me", "bell"] - Output: 10 - Explanation: S = "time#bell#" and indexes = [0, 2, 5]. - Note: - - 1 <= words.length <= 2000. - 1 <= words[i].length <= 7. - Each word has only lowercase letters. - - Solution: Sort the words by length and then use a hashmap to map each substring of a string with its position. + * Created by gouthamvidyapradhan on 04/05/2018. Given a list of words, we may encode it by writing + * a reference string S and a list of indexes A. + * + *

For example, if the list of words is ["time", "me", "bell"], we can write it as S = + * "time#bell#" and indexes = [0, 2, 5]. + * + *

Then for each index, we will recover the word by reading from the reference string from that + * index until we reach a "#" character. + * + *

What is the length of the shortest reference string S possible that encodes the given words? + * + *

Example: + * + *

Input: words = ["time", "me", "bell"] Output: 10 Explanation: S = "time#bell#" and indexes = + * [0, 2, 5]. Note: + * + *

1 <= words.length <= 2000. 1 <= words[i].length <= 7. Each word has only lowercase letters. + * + *

Solution: Sort the words by length and then use a hashmap to map each substring of a string + * with its position. */ public class ShortEncodingOfWords { - class Node { - String s; - int l; - Node(String s, int l){ - this.s = s; - this.l = l; - } - } + class Node { + String s; + int l; - public static void main(String[] args) { - String[] A = {"memo", "me", "mo"}; - System.out.println(new ShortEncodingOfWords().minimumLengthEncoding(A)); + Node(String s, int l) { + this.s = s; + this.l = l; } + } - public int minimumLengthEncoding(String[] words) { - List list = new ArrayList<>(); - for(String w : words){ - list.add(new Node(w, w.length())); - } - Collections.sort(list, (o1, o2) -> Integer.compare(o2.l, o1.l)); - Map map = new HashMap<>(); - int count = 0; - for(Node node : list){ - String str = node.s; - if(!map.containsKey(str)){ - for(int i = 0, l = str.length(); i < l; i++){ - map.put(str.substring(i, l), count + i); - } - count += (str.length() + 1); - } + public static void main(String[] args) { + String[] A = {"memo", "me", "mo"}; + System.out.println(new ShortEncodingOfWords().minimumLengthEncoding(A)); + } + + public int minimumLengthEncoding(String[] words) { + List list = new ArrayList<>(); + for (String w : words) { + list.add(new Node(w, w.length())); + } + Collections.sort(list, (o1, o2) -> Integer.compare(o2.l, o1.l)); + Map map = new HashMap<>(); + int count = 0; + for (Node node : list) { + String str = node.s; + if (!map.containsKey(str)) { + for (int i = 0, l = str.length(); i < l; i++) { + map.put(str.substring(i, l), count + i); } - return count; + count += (str.length() + 1); + } } + return count; + } } diff --git a/problems/src/hashing/SortCharByFrequency.java b/problems/src/hashing/SortCharByFrequency.java index eb9ce36a..29e40bc7 100644 --- a/problems/src/hashing/SortCharByFrequency.java +++ b/problems/src/hashing/SortCharByFrequency.java @@ -6,87 +6,75 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 25/03/2017. - * Given a string, sort it in decreasing order based on the frequency of characters. - *

- * Example 1: - *

- * Input: - * "tree" - *

- * Output: - * "eert" - *

- * Explanation: - * 'e' appears twice while 'r' and 't' both appear once. - * So 'e' must appear before both 'r' and 't'. Therefore "eetr" is also a valid answer. - * Example 2: - *

- * Input: - * "cccaaa" - *

- * Output: - * "cccaaa" - *

- * Explanation: - * Both 'c' and 'a' appear three times, so "aaaccc" is also a valid answer. - * Note that "cacaca" is incorrect, as the same characters must be together. - *

- * Example 3: - *

- * Input: - * "Aabb" - *

- * Output: - * "bbAa" - *

- * Explanation: - * "bbaA" is also a valid answer, but "Aabb" is incorrect. - * Note that 'A' and 'a' are treated as two different characters. + * Created by gouthamvidyapradhan on 25/03/2017. Given a string, sort it in decreasing order based + * on the frequency of characters. + * + *

Example 1: + * + *

Input: "tree" + * + *

Output: "eert" + * + *

Explanation: 'e' appears twice while 'r' and 't' both appear once. So 'e' must appear before + * both 'r' and 't'. Therefore "eetr" is also a valid answer. Example 2: + * + *

Input: "cccaaa" + * + *

Output: "cccaaa" + * + *

Explanation: Both 'c' and 'a' appear three times, so "aaaccc" is also a valid answer. Note + * that "cacaca" is incorrect, as the same characters must be together. + * + *

Example 3: + * + *

Input: "Aabb" + * + *

Output: "bbAa" + * + *

Explanation: "bbaA" is also a valid answer, but "Aabb" is incorrect. Note that 'A' and 'a' are + * treated as two different characters. */ public class SortCharByFrequency { - class Freq { - int i; - int c; - } + class Freq { + int i; + int c; + } - private int[] buff = new int[256]; + private int[] buff = new int[256]; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new SortCharByFrequency().frequencySort("askdfkasdkfasdkljfklasdjfkl")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new SortCharByFrequency().frequencySort("askdfkasdkfasdkljfklasdjfkl")); + } - public String frequencySort(String s) { - if (s == null || s.isEmpty()) return s; - Arrays.fill(buff, 0); - StringBuilder sb = new StringBuilder(); - for (int i = 0, l = s.length(); i < l; i++) - buff[s.charAt(i)]++; + public String frequencySort(String s) { + if (s == null || s.isEmpty()) return s; + Arrays.fill(buff, 0); + StringBuilder sb = new StringBuilder(); + for (int i = 0, l = s.length(); i < l; i++) buff[s.charAt(i)]++; - List fList = new ArrayList<>(); - for (int i = 0; i < 256; i++) { - if (buff[i] > 0) { - Freq f = new Freq(); - f.i = i; - f.c = buff[i]; - fList.add(f); - } - } + List fList = new ArrayList<>(); + for (int i = 0; i < 256; i++) { + if (buff[i] > 0) { + Freq f = new Freq(); + f.i = i; + f.c = buff[i]; + fList.add(f); + } + } - Collections.sort(fList, (o1, o2) -> Integer.compare(o2.c, o1.c)); + Collections.sort(fList, (o1, o2) -> Integer.compare(o2.c, o1.c)); - for (Freq f : fList) { - char c = (char) f.i; - int freq = f.c; - while (freq-- > 0) - sb.append(c); - } - return sb.toString(); + for (Freq f : fList) { + char c = (char) f.i; + int freq = f.c; + while (freq-- > 0) sb.append(c); } + return sb.toString(); + } } diff --git a/problems/src/hashing/SubstringConcatenationOfWords.java b/problems/src/hashing/SubstringConcatenationOfWords.java index f6968673..1c23716e 100644 --- a/problems/src/hashing/SubstringConcatenationOfWords.java +++ b/problems/src/hashing/SubstringConcatenationOfWords.java @@ -6,74 +6,67 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 02/03/2019 - * You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices - * of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters. + * Created by gouthamvidyapradhan on 02/03/2019 You are given a string, s, and a list of words, + * words, that are all of the same length. Find all starting indices of substring(s) in s that is a + * concatenation of each word in words exactly once and without any intervening characters. * - * Example 1: + *

Example 1: * - * Input: - * s = "barfoothefoobarman", - * words = ["foo","bar"] - * Output: [0,9] - * Explanation: Substrings starting at index 0 and 9 are "barfoor" and "foobar" respectively. - * The output order does not matter, returning [9,0] is fine too. - * Example 2: + *

Input: s = "barfoothefoobarman", words = ["foo","bar"] Output: [0,9] Explanation: Substrings + * starting at index 0 and 9 are "barfoor" and "foobar" respectively. The output order does not + * matter, returning [9,0] is fine too. Example 2: * - * Input: - * s = "wordgoodgoodgoodbestword", - * words = ["word","good","best","word"] - * Output: [] + *

Input: s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"] Output: [] * - * Solution: - * General idea is to do the following - * 1. Calculate the word count for the given array of words and store this in a HashMap. - * 2. For every substring (substring of s) of length (words[0].length() * words.length) split this into words of - * length words[0].length and calculate the word frequency for the split words. If the word frequency matches - * the word frequency of the given original word list then add the starting index of this substring into the result - * array. + *

Solution: General idea is to do the following 1. Calculate the word count for the given array + * of words and store this in a HashMap. 2. For every substring (substring of s) of length + * (words[0].length() * words.length) split this into words of length words[0].length and calculate + * the word frequency for the split words. If the word frequency matches the word frequency of the + * given original word list then add the starting index of this substring into the result array. * - * A small optimization is to break the substring match as soon as you find out that the word formed from the substring - * is not part of the original given word list or if the frequency of the word exceeds the frequency of the original - * word count. + *

A small optimization is to break the substring match as soon as you find out that the word + * formed from the substring is not part of the original given word list or if the frequency of the + * word exceeds the frequency of the original word count. */ public class SubstringConcatenationOfWords { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - String[] words = {"word","good","best","word"}; - System.out.println(new SubstringConcatenationOfWords().findSubstring("wordgoodgoodgoodbestword", words)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + String[] words = {"word", "good", "best", "word"}; + System.out.println( + new SubstringConcatenationOfWords().findSubstring("wordgoodgoodgoodbestword", words)); + } - public List findSubstring(String s, String[] words) { - if(words.length == 0) return new ArrayList<>(); - int wLen = words[0].length(); - int sLen = wLen * words.length; - List result = new ArrayList<>(); - if(sLen > s.length()) return result; - Map countMap = new HashMap<>(); - for(String w : words){ - countMap.putIfAbsent(w, 0); - countMap.put(w, countMap.get(w) + 1); - } - for(int k = 0; (s.length() - k) >= sLen; k++) { - Map subSMap = new HashMap<>(); - int i = k; - for(int j = i + wLen; (i - k) < sLen; i = j, j += wLen){ - String subS = s.substring(i, j); - subSMap.putIfAbsent(subS, 0); - subSMap.put(subS, subSMap.get(subS) + 1); - if(!countMap.containsKey(subS) || subSMap.get(subS) > countMap.get(subS)){ - break; - } - } - if((i - k) >= sLen){ - result.add(k); - } + public List findSubstring(String s, String[] words) { + if (words.length == 0) return new ArrayList<>(); + int wLen = words[0].length(); + int sLen = wLen * words.length; + List result = new ArrayList<>(); + if (sLen > s.length()) return result; + Map countMap = new HashMap<>(); + for (String w : words) { + countMap.putIfAbsent(w, 0); + countMap.put(w, countMap.get(w) + 1); + } + for (int k = 0; (s.length() - k) >= sLen; k++) { + Map subSMap = new HashMap<>(); + int i = k; + for (int j = i + wLen; (i - k) < sLen; i = j, j += wLen) { + String subS = s.substring(i, j); + subSMap.putIfAbsent(subS, 0); + subSMap.put(subS, subSMap.get(subS) + 1); + if (!countMap.containsKey(subS) || subSMap.get(subS) > countMap.get(subS)) { + break; } - return result; + } + if ((i - k) >= sLen) { + result.add(k); + } } + return result; + } } diff --git a/problems/src/hashing/TwoSum.java b/problems/src/hashing/TwoSum.java index 9ddd8909..5e1bba45 100644 --- a/problems/src/hashing/TwoSum.java +++ b/problems/src/hashing/TwoSum.java @@ -3,57 +3,56 @@ import java.util.HashMap; /** - * Created by gouthamvidyapradhan on 09/03/2017. - * Given an array of integers, return indices of the two numbers such that they add up to a specific target. - *

- * You may assume that each input would have exactly one solution, and you may not use the same element twice. - *

- * Example: - * Given nums = [2, 7, 11, 15], target = 9, - *

- * Because nums[0] + nums[1] = 2 + 7 = 9, - * return [0, 1]. + * Created by gouthamvidyapradhan on 09/03/2017. Given an array of integers, return indices of the + * two numbers such that they add up to a specific target. + * + *

You may assume that each input would have exactly one solution, and you may not use the same + * element twice. + * + *

Example: Given nums = [2, 7, 11, 15], target = 9, + * + *

Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1]. */ public class TwoSum { - HashMap map = new HashMap<>(); + HashMap map = new HashMap<>(); - public int[] twoSum(int[] nums, int target) { - int[] result = new int[2]; + public int[] twoSum(int[] nums, int target) { + int[] result = new int[2]; - for (int i : nums) { - if (map.keySet().contains(i)) { - int count = map.get(i); - map.put(i, ++count); - } else { - map.put(i, 1); - } - } + for (int i : nums) { + if (map.keySet().contains(i)) { + int count = map.get(i); + map.put(i, ++count); + } else { + map.put(i, 1); + } + } - for (int i = 0, l = nums.length; i < l; i++) { - int ele = nums[i]; - int req = target - ele; - if (map.keySet().contains(req)) { - result[0] = i; - if (ele == req) { - int count = map.get(req); - if (count > 1) { - for (int j = i + 1; j < l; j++) { - if (nums[j] == req) { - result[1] = j; - return result; - } - } - } - } else { - for (int j = i + 1; j < l; j++) { - if (nums[j] == req) { - result[1] = j; - return result; - } - } - } + for (int i = 0, l = nums.length; i < l; i++) { + int ele = nums[i]; + int req = target - ele; + if (map.keySet().contains(req)) { + result[0] = i; + if (ele == req) { + int count = map.get(req); + if (count > 1) { + for (int j = i + 1; j < l; j++) { + if (nums[j] == req) { + result[1] = j; + return result; + } + } + } + } else { + for (int j = i + 1; j < l; j++) { + if (nums[j] == req) { + result[1] = j; + return result; } + } } - return result; + } } + return result; + } } diff --git a/problems/src/hashing/ValidAnagram.java b/problems/src/hashing/ValidAnagram.java index da98099d..0fb2a6c9 100644 --- a/problems/src/hashing/ValidAnagram.java +++ b/problems/src/hashing/ValidAnagram.java @@ -1,48 +1,45 @@ package hashing; /** - * Created by gouthamvidyapradhan on 10/03/2017. - * Given two strings s and t, write a function to determine if t is an anagram of s. - *

- * For example, - * s = "anagram", t = "nagaram", return true. - * s = "rat", t = "car", return false. - *

- * Note: - * You may assume the string contains only lowercase alphabets. - *

- * Follow up: - * What if the inputs contain unicode characters? How would you adapt your solution to such case? + * Created by gouthamvidyapradhan on 10/03/2017. Given two strings s and t, write a function to + * determine if t is an anagram of s. + * + *

For example, s = "anagram", t = "nagaram", return true. s = "rat", t = "car", return false. + * + *

Note: You may assume the string contains only lowercase alphabets. + * + *

Follow up: What if the inputs contain unicode characters? How would you adapt your solution to + * such case? */ public class ValidAnagram { - private int[] S = new int[256]; - private int[] T = new int[256]; + private int[] S = new int[256]; + private int[] T = new int[256]; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new ValidAnagram().isAnagram("anagram", "nagaram")); - } - - public boolean isAnagram(String s, String t) { - if (s.length() != t.length()) return false; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new ValidAnagram().isAnagram("anagram", "nagaram")); + } - for (int i = 0, l = s.length(); i < l; i++) { - S[s.charAt(i)]++; - } + public boolean isAnagram(String s, String t) { + if (s.length() != t.length()) return false; - for (int i = 0, l = t.length(); i < l; i++) { - T[t.charAt(i)]++; - } + for (int i = 0, l = s.length(); i < l; i++) { + S[s.charAt(i)]++; + } - for (int i = 0; i < 256; i++) { - if (S[i] != T[i]) return false; - } + for (int i = 0, l = t.length(); i < l; i++) { + T[t.charAt(i)]++; + } - return true; + for (int i = 0; i < 256; i++) { + if (S[i] != T[i]) return false; } + + return true; + } } diff --git a/problems/src/heap/Candy.java b/problems/src/heap/Candy.java index 26a52fae..387389a2 100644 --- a/problems/src/heap/Candy.java +++ b/problems/src/heap/Candy.java @@ -3,90 +3,89 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 26/07/2018. - * There are N children standing in a line. Each child is assigned a rating value. - - You are giving candies to these children subjected to the following requirements: - - Each child must have at least one candy. - Children with a higher rating get more candies than their neighbors. - What is the minimum candies you must give? - - Example 1: - - Input: [1,0,2] - Output: 5 - Explanation: You can allocate to the first, second and third child with 2, 1, 2 candies respectively. - Example 2: - - Input: [1,2,2] - Output: 4 - Explanation: You can allocate to the first, second and third child with 1, 2, 1 candies respectively. - The third child gets 1 candy because it satisfies the above two conditions. - - Solution: O(N log N): Store the indexes in a heap, iterate through the heap one by one and assign candies one - greater than its neighbours. Take care of edge cases. - + * Created by gouthamvidyapradhan on 26/07/2018. There are N children standing in a line. Each child + * is assigned a rating value. + * + *

You are giving candies to these children subjected to the following requirements: + * + *

Each child must have at least one candy. Children with a higher rating get more candies than + * their neighbors. What is the minimum candies you must give? + * + *

Example 1: + * + *

Input: [1,0,2] Output: 5 Explanation: You can allocate to the first, second and third child + * with 2, 1, 2 candies respectively. Example 2: + * + *

Input: [1,2,2] Output: 4 Explanation: You can allocate to the first, second and third child + * with 1, 2, 1 candies respectively. The third child gets 1 candy because it satisfies the above + * two conditions. + * + *

Solution: O(N log N): Store the indexes in a heap, iterate through the heap one by one and + * assign candies one greater than its neighbours. Take care of edge cases. */ public class Candy { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] ratings = {29,51,87,87,72,12}; - System.out.println(new Candy().candy(ratings)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] ratings = {29, 51, 87, 87, 72, 12}; + System.out.println(new Candy().candy(ratings)); + } - public int candy(int[] ratings) { - if(ratings.length == 1) return 1; - PriorityQueue pq = new PriorityQueue<>((o1, o2) -> Integer.compare(ratings[o1], ratings[o2])); - for(int i = 0; i < ratings.length; i ++){ - pq.offer(i); + public int candy(int[] ratings) { + if (ratings.length == 1) return 1; + PriorityQueue pq = + new PriorityQueue<>((o1, o2) -> Integer.compare(ratings[o1], ratings[o2])); + for (int i = 0; i < ratings.length; i++) { + pq.offer(i); + } + int[] count = new int[ratings.length]; + while (!pq.isEmpty()) { + int index = pq.poll(); + if (index - 1 < 0) { + if (ratings[index + 1] == ratings[index]) { + count[index] = 1; + } else { + count[index] = count[index + 1] + 1; } - int[] count = new int[ratings.length]; - while (!pq.isEmpty()){ - int index = pq.poll(); - if(index - 1 < 0){ - if(ratings[index + 1] == ratings[index]){ - count[index] = 1; - } else{ - count[index] = count[index + 1] + 1; - } - } else if(index + 1 >= ratings.length) { - if(ratings[index - 1] == ratings[index]){ - count[index] = 1; - } else{ - count[index] = count[index - 1] + 1; - } - } else{ - if((ratings[index - 1] == ratings[index]) && (ratings[index + 1] == ratings[index])){ - count[index] = 1; - } else{ - if(((ratings[index - 1] == ratings[index]) && (ratings[index + 1] > ratings[index])) - || ((ratings[index + 1] == ratings[index]) && (ratings[index - 1] > ratings[index]))){ - count[index] = 1; - } else if(((ratings[index - 1] == ratings[index]) && (ratings[index + 1] < ratings[index]))){ - count[index] = count[index + 1] + 1; - } else if(((ratings[index + 1] == ratings[index]) && (ratings[index - 1] < ratings[index]))){ - count[index] = count[index - 1] + 1; - } - else { - if(count[index - 1] > count[index + 1]){ - count[index] = count[index - 1] + 1; - } else { - count[index] = count[index + 1] + 1; - } - } - } - } + } else if (index + 1 >= ratings.length) { + if (ratings[index - 1] == ratings[index]) { + count[index] = 1; + } else { + count[index] = count[index - 1] + 1; } - int result = 0; - for(int c : count){ - result += c; + } else { + if ((ratings[index - 1] == ratings[index]) && (ratings[index + 1] == ratings[index])) { + count[index] = 1; + } else { + if (((ratings[index - 1] == ratings[index]) && (ratings[index + 1] > ratings[index])) + || ((ratings[index + 1] == ratings[index]) + && (ratings[index - 1] > ratings[index]))) { + count[index] = 1; + } else if (((ratings[index - 1] == ratings[index]) + && (ratings[index + 1] < ratings[index]))) { + count[index] = count[index + 1] + 1; + } else if (((ratings[index + 1] == ratings[index]) + && (ratings[index - 1] < ratings[index]))) { + count[index] = count[index - 1] + 1; + } else { + if (count[index - 1] > count[index + 1]) { + count[index] = count[index - 1] + 1; + } else { + count[index] = count[index + 1] + 1; + } + } } - return result; + } + } + int result = 0; + for (int c : count) { + result += c; } + return result; + } } diff --git a/problems/src/heap/FreqStack.java b/problems/src/heap/FreqStack.java index 39e7e76e..58944403 100644 --- a/problems/src/heap/FreqStack.java +++ b/problems/src/heap/FreqStack.java @@ -1,171 +1,163 @@ package heap; + import java.util.*; /** - * Created by gouthamvidyapradhan on 30/04/2019 - * Implement FreqStack, a class which simulates the operation of a stack-like data structure. - * - * 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. + * Created by gouthamvidyapradhan on 30/04/2019 Implement FreqStack, a class which simulates the + * operation of a stack-like data structure. * + *

FreqStack has two functions: * - * Example 1: + *

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. * - * Input: - * ["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: + *

Example 1: * - * pop() -> returns 5, as 5 is the most frequent. - * The stack becomes [5,7,5,7,4]. + *

Input: ["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 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, as 5 is the most frequent. The stack becomes [5,7,5,7,4]. * - * pop() -> returns 5. - * The stack becomes [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 4. - * The stack becomes [5,7]. + *

pop() -> returns 5. The stack becomes [5,7,4]. * + *

pop() -> returns 4. The stack becomes [5,7]. * - * Note: + *

Note: * - * Calls to FreqStack.push(int x) will be such that 0 <= x <= 10^9. - * It is guaranteed that FreqStack.pop() won't be called if the stack has zero elements. - * The total number of FreqStack.push calls will not exceed 10000 in a single test case. - * The total number of FreqStack.pop calls will not exceed 10000 in a single test case. - * The total number of FreqStack.push and FreqStack.pop calls will not exceed 150000 across all test cases. + *

Calls to FreqStack.push(int x) will be such that 0 <= x <= 10^9. It is guaranteed that + * FreqStack.pop() won't be called if the stack has zero elements. The total number of + * FreqStack.push calls will not exceed 10000 in a single test case. The total number of + * FreqStack.pop calls will not exceed 10000 in a single test case. The total number of + * FreqStack.push and FreqStack.pop calls will not exceed 150000 across all test cases. * - * Solution: - * push O(log N) - * pop O(log N) - * Maintain a priority queue with a FreqNode where each FreqNode contains a frequency and a stack - * with (value and pushCount). Each stack in a priority queue contains same set of values. Every time when a value - * is to be added to the stack a new Node is created and pushed to stack which contains the push value and pushCount. + *

Solution: push O(log N) pop O(log N) Maintain a priority queue with a FreqNode where each + * FreqNode contains a frequency and a stack with (value and pushCount). Each stack in a priority + * queue contains same set of values. Every time when a value is to be added to the stack a new Node + * is created and pushed to stack which contains the push value and pushCount. * - * Example: For the below push operation - * push 5, push 5, push 5, push 6, push 6, push 7 - * the state of priority stack will be - * 3 : 5(0) -> 5(1) -> 5(2) - * 2 : 6(3) -> 6(4) - * 1 : 7(5) + *

Example: For the below push operation push 5, push 5, push 5, push 6, push 6, push 7 the state + * of priority stack will be 3 : 5(0) -> 5(1) -> 5(2) 2 : 6(3) -> 6(4) 1 : 7(5) * - * When a push operation is invoked we have to identify in which stack the value has to go in + *

When a push operation is invoked we have to identify in which stack the value has to go in * therefore maintain a hashmap with push-value as key and value contains the reference to FreqNode * in priority queue. Remove this FreqNode from priority queue and update the stack. * - * When a pop operation is invoked remove the FreqNode from the top of the priority queue and pop the - * value from top of its stack. + *

When a pop operation is invoked remove the FreqNode from the top of the priority queue and pop + * the value from top of its stack. */ public class FreqStack { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - FreqStack freqStack = new FreqStack(); - freqStack.push(5); - freqStack.push(5); - freqStack.push(5); - freqStack.push(5); - freqStack.push(6); - System.out.println(freqStack.pop()); - freqStack.push(7); - System.out.println(freqStack.pop()); - System.out.println(freqStack.pop()); - freqStack.push(1); - freqStack.push(2); - System.out.println(freqStack.pop()); - System.out.println(freqStack.pop()); - System.out.println(freqStack.pop()); - System.out.println(freqStack.pop()); - System.out.println(freqStack.pop()); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + FreqStack freqStack = new FreqStack(); + freqStack.push(5); + freqStack.push(5); + freqStack.push(5); + freqStack.push(5); + freqStack.push(6); + System.out.println(freqStack.pop()); + freqStack.push(7); + System.out.println(freqStack.pop()); + System.out.println(freqStack.pop()); + freqStack.push(1); + freqStack.push(2); + System.out.println(freqStack.pop()); + System.out.println(freqStack.pop()); + System.out.println(freqStack.pop()); + System.out.println(freqStack.pop()); + System.out.println(freqStack.pop()); + } - class Node{ - int val, pos; - Node(int val, int pushCount){ - this.val = val; - this.pos = pushCount; - } - } + class Node { + int val, pos; - class FreqNode{ - int freq; - Stack stack; - FreqNode(int freq, Stack stack){ - this.freq = freq; - this.stack = stack; - } + Node(int val, int pushCount) { + this.val = val; + this.pos = pushCount; + } + } - public int getFreq() { - return freq; - } + class FreqNode { + int freq; + Stack stack; - public int getTop() { - return !stack.isEmpty() ? stack.peek().pos : -1; - } + FreqNode(int freq, Stack stack) { + this.freq = freq; + this.stack = stack; + } - public void push(Node e){ - freq++; - stack.push(e); - } + public int getFreq() { + return freq; + } - public Node pop(){ - freq--; - return stack.pop(); - } + public int getTop() { + return !stack.isEmpty() ? stack.peek().pos : -1; } - private PriorityQueue priorityQueue; - private Map map; - private int pushCount; + public void push(Node e) { + freq++; + stack.push(e); + } - public FreqStack() { - priorityQueue = - new PriorityQueue<>((o1, o2) -> { - if(o1.freq == o2.freq){ - return Integer.compare(o2.getTop(), o1.getTop()); - } else{ - return Integer.compare(o2.freq, o1.freq); - } - }); - map = new HashMap<>(); - pushCount = 0; + public Node pop() { + freq--; + return stack.pop(); } + } + + private PriorityQueue priorityQueue; + private Map map; + private int pushCount; + + public FreqStack() { + priorityQueue = + new PriorityQueue<>( + (o1, o2) -> { + if (o1.freq == o2.freq) { + return Integer.compare(o2.getTop(), o1.getTop()); + } else { + return Integer.compare(o2.freq, o1.freq); + } + }); + map = new HashMap<>(); + pushCount = 0; + } - public void push(int x) { - pushCount++; - Node node = new Node(x, pushCount); - FreqNode freqNode; - if(map.containsKey(x)){ - freqNode = map.get(x); - priorityQueue.remove(freqNode); - freqNode.push(node); - } else{ - Stack stack = new Stack<>(); - stack.push(node); - freqNode = new FreqNode(1, stack); - map.put(x, freqNode); - } - priorityQueue.offer(freqNode); + public void push(int x) { + pushCount++; + Node node = new Node(x, pushCount); + FreqNode freqNode; + if (map.containsKey(x)) { + freqNode = map.get(x); + priorityQueue.remove(freqNode); + freqNode.push(node); + } else { + Stack stack = new Stack<>(); + stack.push(node); + freqNode = new FreqNode(1, stack); + map.put(x, freqNode); } + priorityQueue.offer(freqNode); + } - public int pop() { - FreqNode freqNode = priorityQueue.poll(); - Node topNode = freqNode.pop(); - if(freqNode.freq == 0){ - map.remove(topNode.val); - } else{ - priorityQueue.offer(freqNode); - } - return topNode.val; + public int pop() { + FreqNode freqNode = priorityQueue.poll(); + Node topNode = freqNode.pop(); + if (freqNode.freq == 0) { + map.remove(topNode.val); + } else { + priorityQueue.offer(freqNode); } + return topNode.val; + } } diff --git a/problems/src/heap/MeetingRoomsII.java b/problems/src/heap/MeetingRoomsII.java index d152686b..50a013de 100644 --- a/problems/src/heap/MeetingRoomsII.java +++ b/problems/src/heap/MeetingRoomsII.java @@ -4,54 +4,61 @@ import java.util.PriorityQueue; /** - * Created by gouthamvidyapradhan on 27/11/2017. - * Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), find the minimum number of conference rooms required. - - For example, - Given [[0, 30],[5, 10],[15, 20]], - return 2. - - Solution: Sort the array based on start-time of the interval. Then, use the min-heap based on min end time. For - every interval remove the top element of the priority queue if the end time of the top <= start time of the new - interval. Add the new interval to the queue. The max size of the priority queue attained during this process - will be the answer. + * Created by gouthamvidyapradhan on 27/11/2017. Given an array of meeting time intervals consisting + * of start and end times [[s1,e1],[s2,e2],...] (si < ei), find the minimum number of conference + * rooms required. + * + *

For example, Given [[0, 30],[5, 10],[15, 20]], return 2. + * + *

Solution: Sort the array based on start-time of the interval. Then, use the min-heap based on + * min end time. For every interval remove the top element of the priority queue if the end time of + * the top <= start time of the new interval. Add the new interval to the queue. The max size of the + * priority queue attained during this process will be the answer. */ public class MeetingRoomsII { - public static class Interval { - int start; - int end; - Interval() { start = 0; end = 0; } - Interval(int s, int e) { start = s; end = e; } - } - /** - * Main method - * @param args - */ - public static void main(String[] args) { - Interval i1 = new Interval(0, 40); - Interval i2 = new Interval(2, 10); - Interval i3 = new Interval(10, 40); - Interval i4 = new Interval(15, 20); - Interval i5 = new Interval(20, 30); - Interval i6 = new Interval(20, 40); - Interval i7 = new Interval(1, 5); - Interval[] intervals = {i1, i2, i3, i4, i5, i6, i7}; - System.out.println(minMeetingRooms(intervals)); + public static class Interval { + int start; + int end; + + Interval() { + start = 0; + end = 0; } - public static int minMeetingRooms(Interval[] intervals) { - Arrays.sort(intervals, (a, b) -> Integer.compare(a.start, b.start)); - PriorityQueue queue = new PriorityQueue<>((a, b) -> Integer.compare(a.end, b.end)); - int max = 0; - for(Interval i : intervals){ - while(!queue.isEmpty() && queue.peek().end <= i.start){ - queue.poll(); - } - queue.offer(i); - max = Math.max(max, queue.size()); - } - return max; + Interval(int s, int e) { + start = s; + end = e; } + } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + Interval i1 = new Interval(0, 40); + Interval i2 = new Interval(2, 10); + Interval i3 = new Interval(10, 40); + Interval i4 = new Interval(15, 20); + Interval i5 = new Interval(20, 30); + Interval i6 = new Interval(20, 40); + Interval i7 = new Interval(1, 5); + Interval[] intervals = {i1, i2, i3, i4, i5, i6, i7}; + System.out.println(minMeetingRooms(intervals)); + } + public static int minMeetingRooms(Interval[] intervals) { + Arrays.sort(intervals, (a, b) -> Integer.compare(a.start, b.start)); + PriorityQueue queue = new PriorityQueue<>((a, b) -> Integer.compare(a.end, b.end)); + int max = 0; + for (Interval i : intervals) { + while (!queue.isEmpty() && queue.peek().end <= i.start) { + queue.poll(); + } + queue.offer(i); + max = Math.max(max, queue.size()); + } + return max; + } } diff --git a/problems/src/heap/SlidingWindowMaximum.java b/problems/src/heap/SlidingWindowMaximum.java index 76682aa3..495ae420 100644 --- a/problems/src/heap/SlidingWindowMaximum.java +++ b/problems/src/heap/SlidingWindowMaximum.java @@ -4,65 +4,55 @@ import java.util.Deque; /** - * Created by gouthamvidyapradhan on 10/03/2017. - * Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. - *

- * For example, - * Given nums = [1,3,-1,-3,5,3,6,7], and k = 3. - *

- * Window position Max - * --------------- ----- - * [1 3 -1] -3 5 3 6 7 3 - * 1 [3 -1 -3] 5 3 6 7 3 - * 1 3 [-1 -3 5] 3 6 7 5 - * 1 3 -1 [-3 5 3] 6 7 5 - * 1 3 -1 -3 [5 3 6] 7 6 - * 1 3 -1 -3 5 [3 6 7] 7 - * Therefore, return the max sliding window as [3,3,5,5,6,7]. - *

- * Note: - * You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array. + * Created by gouthamvidyapradhan on 10/03/2017. Given an array nums, there is a sliding window of + * size k which is moving from the very left of the array to the very right. You can only see the k + * numbers in the window. Each time the sliding window moves right by one position. + * + *

For example, Given nums = [1,3,-1,-3,5,3,6,7], and k = 3. + * + *

Window position Max --------------- ----- [1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 + * -3 5] 3 6 7 5 1 3 -1 [-3 5 3] 6 7 5 1 3 -1 -3 [5 3 6] 7 6 1 3 -1 -3 5 [3 6 7] 7 Therefore, return + * the max sliding window as [3,3,5,5,6,7]. + * + *

Note: You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array. */ public class SlidingWindowMaximum { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] a = {1, 3, 1, 2, 0, 5}; - int[] result = new SlidingWindowMaximum().maxSlidingWindow(a, 3); - for (int i : result) - System.out.print(i + " "); - } - - /** - * @param nums - * @param k - * @return - */ - public int[] maxSlidingWindow(int[] nums, int k) { - int[] result = new int[nums.length - (k - 1)]; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] a = {1, 3, 1, 2, 0, 5}; + int[] result = new SlidingWindowMaximum().maxSlidingWindow(a, 3); + for (int i : result) System.out.print(i + " "); + } - if (nums.length == 0) return new int[0]; + /** + * @param nums + * @param k + * @return + */ + public int[] maxSlidingWindow(int[] nums, int k) { + int[] result = new int[nums.length - (k - 1)]; - Deque queue = new ArrayDeque<>(); - for (int i = 0, j = 0, l = nums.length; i < l; i++) { - int head = i - (k - 1); - if (head >= 0) { - //remove out of range - if (queue.peek() != null && queue.peek() < head) - queue.poll(); - } - while (queue.peekLast() != null && nums[queue.peekLast()] <= nums[i]) { - queue.pollLast(); - } - queue.offer(i); - if (i >= k - 1) - result[j++] = nums[queue.peek()]; - } + if (nums.length == 0) return new int[0]; - return result; + Deque queue = new ArrayDeque<>(); + for (int i = 0, j = 0, l = nums.length; i < l; i++) { + int head = i - (k - 1); + if (head >= 0) { + // remove out of range + if (queue.peek() != null && queue.peek() < head) queue.poll(); + } + while (queue.peekLast() != null && nums[queue.peekLast()] <= nums[i]) { + queue.pollLast(); + } + queue.offer(i); + if (i >= k - 1) result[j++] = nums[queue.peek()]; } + + return result; + } } diff --git a/problems/src/heap/SmallestRotationWithHighestScore.java b/problems/src/heap/SmallestRotationWithHighestScore.java index 5d3d0bb4..faefc394 100644 --- a/problems/src/heap/SmallestRotationWithHighestScore.java +++ b/problems/src/heap/SmallestRotationWithHighestScore.java @@ -4,101 +4,89 @@ import java.util.PriorityQueue; /** - * Created by gouthamvidyapradhan on 06/04/2019 - * Given an array A, we may rotate it by a non-negative integer K so that the array becomes A[K], A[K+1], A{K+2], ... - * A[A.length - 1], A[0], A[1], ..., A[K-1]. Afterward, any entries that are less than or equal to their index are - * worth 1 point. + * Created by gouthamvidyapradhan on 06/04/2019 Given an array A, we may rotate it by a non-negative + * integer K so that the array becomes A[K], A[K+1], A{K+2], ... A[A.length - 1], A[0], A[1], ..., + * A[K-1]. Afterward, any entries that are less than or equal to their index are worth 1 point. * - * For example, if we have [2, 4, 1, 3, 0], and we rotate by K = 2, it becomes [1, 3, 0, 2, 4]. This is worth 3 - * points because 1 > 0 [no points], 3 > 1 [no points], 0 <= 2 [one point], 2 <= 3 [one point], 4 <= 4 [one point]. + *

For example, if we have [2, 4, 1, 3, 0], and we rotate by K = 2, it becomes [1, 3, 0, 2, 4]. + * This is worth 3 points because 1 > 0 [no points], 3 > 1 [no points], 0 <= 2 [one point], 2 <= 3 + * [one point], 4 <= 4 [one point]. * - * Over all possible rotations, return the rotation index K that corresponds to the highest score we could receive. - * If there are multiple answers, return the smallest such index K. + *

Over all possible rotations, return the rotation index K that corresponds to the highest score + * we could receive. If there are multiple answers, return the smallest such index K. * - * Example 1: - * Input: [2, 3, 1, 4, 0] - * Output: 3 - * Explanation: - * Scores for each K are listed below: - * K = 0, A = [2,3,1,4,0], score 2 - * K = 1, A = [3,1,4,0,2], score 3 - * K = 2, A = [1,4,0,2,3], score 3 - * K = 3, A = [4,0,2,3,1], score 4 - * K = 4, A = [0,2,3,1,4], score 3 - * So we should choose K = 3, which has the highest score. + *

Example 1: Input: [2, 3, 1, 4, 0] Output: 3 Explanation: Scores for each K are listed below: K + * = 0, A = [2,3,1,4,0], score 2 K = 1, A = [3,1,4,0,2], score 3 K = 2, A = [1,4,0,2,3], score 3 K = + * 3, A = [4,0,2,3,1], score 4 K = 4, A = [0,2,3,1,4], score 3 So we should choose K = 3, which has + * the highest score. * + *

Example 2: Input: [1, 3, 0, 2, 4] Output: 0 Explanation: A will always have 3 points no matter + * how it shifts. So we will choose the smallest K, which is 0. Note: * + *

A will have length at most 20000. A[i] will be in the range [0, A.length]. * - * Example 2: - * Input: [1, 3, 0, 2, 4] - * Output: 0 - * Explanation: A will always have 3 points no matter how it shifts. - * So we will choose the smallest K, which is 0. - * Note: - * - * A will have length at most 20000. - * A[i] will be in the range [0, A.length]. - * - * Solution O(NLogN). The key insight to this problem is to notice that the point of a number - * changes to 1 from 0 if the position changes to A.length - 1 and similarly the point changes to 1 from 0 if the - * position changes to a index = NUM - 1. - * Maintain a priority queue with rotation_count (the number of rotation required to change its points from either - * 0 to 1 or from 1 to 0), pop all the indices from priority queue which has rotation_count equal to current rotation - * count and update the rotation_count to its next value. - * Maintain a max count and the rotation index pair and return rotation index as the answer. + *

Solution O(NLogN). The key insight to this problem is to notice that the point of a number + * changes to 1 from 0 if the position changes to A.length - 1 and similarly the point changes to 1 + * from 0 if the position changes to a index = NUM - 1. Maintain a priority queue with + * rotation_count (the number of rotation required to change its points from either 0 to 1 or from 1 + * to 0), pop all the indices from priority queue which has rotation_count equal to current rotation + * count and update the rotation_count to its next value. Maintain a max count and the rotation + * index pair and return rotation index as the answer. */ public class SmallestRotationWithHighestScore { - private class Node{ - int i, n, r, v; - Node(int i, int n, int r, int v){ - this.i = i; - this.n = n; - this.r = r; - this.v = v; - } - } - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int[] A = {2, 3, 1, 4, 0}; - System.out.println(new SmallestRotationWithHighestScore().bestRotation(A)); + private class Node { + int i, n, r, v; + + Node(int i, int n, int r, int v) { + this.i = i; + this.n = n; + this.r = r; + this.v = v; } + } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[] A = {2, 3, 1, 4, 0}; + System.out.println(new SmallestRotationWithHighestScore().bestRotation(A)); + } - public int bestRotation(int[] A) { - PriorityQueue pq = new PriorityQueue<>(Comparator.comparingInt(o -> o.r)); - int curr = 0; - for(int i = 0; i < A.length; i ++){ - int num = A[i]; - int v = 0, r = Integer.MAX_VALUE; - if(num <= i){ - v = 1; - curr++; - } - if(num != 0){ - r = v == 0 ? i + 1 : (i - num + 1); - } - pq.offer(new Node(i, num, r , v)); - } - int R = 0, max = curr, ans = 0; - while(R < A.length){ - while(pq.peek().r - R == 0){ - Node top = pq.poll(); - top.v = (top.v + 1) % 2; - top.i = (top.i - R < 0) ? (A.length + (top.i - R)) : (top.i - R); - top.r = top.v == 0 ? top.i + 1 : (top.i - top.n + 1); - top.r += R; - curr = (top.v == 0) ? curr - 1 : curr + 1; - pq.offer(top); - } - if(curr > max){ - ans = R; - max = curr; - } - R++; - } - return ans; + public int bestRotation(int[] A) { + PriorityQueue pq = new PriorityQueue<>(Comparator.comparingInt(o -> o.r)); + int curr = 0; + for (int i = 0; i < A.length; i++) { + int num = A[i]; + int v = 0, r = Integer.MAX_VALUE; + if (num <= i) { + v = 1; + curr++; + } + if (num != 0) { + r = v == 0 ? i + 1 : (i - num + 1); + } + pq.offer(new Node(i, num, r, v)); + } + int R = 0, max = curr, ans = 0; + while (R < A.length) { + while (pq.peek().r - R == 0) { + Node top = pq.poll(); + top.v = (top.v + 1) % 2; + top.i = (top.i - R < 0) ? (A.length + (top.i - R)) : (top.i - R); + top.r = top.v == 0 ? top.i + 1 : (top.i - top.n + 1); + top.r += R; + curr = (top.v == 0) ? curr - 1 : curr + 1; + pq.offer(top); + } + if (curr > max) { + ans = R; + max = curr; + } + R++; } + return ans; + } } diff --git a/problems/src/heap/TheSkylineProblem.java b/problems/src/heap/TheSkylineProblem.java index fd5fcce9..6cf65f95 100644 --- a/problems/src/heap/TheSkylineProblem.java +++ b/problems/src/heap/TheSkylineProblem.java @@ -4,142 +4,174 @@ /** * Created by gouthamvidyapradhan on 13/09/2017. + * + *

A city's skyline is the outer contour of the silhouette formed by all the buildings in that + * city when viewed from a distance. Now suppose you are given the locations and height of all the + * buildings as shown on a cityscape photo (Figure A), write a program to output the skyline formed + * by these buildings collectively (Figure B). + * *

- * A city's skyline is the outer contour of the silhouette formed by all the buildings in that city when viewed from a distance. - * Now suppose you are given the locations and height of all the buildings as shown on a cityscape photo (Figure A), - * write a program to output the skyline formed by these buildings collectively (Figure B). + * + *

See below link for image. https://leetcode.com/problems/the-skyline-problem/description/ + * *

- *

- * See below link for image. - * https://leetcode.com/problems/the-skyline-problem/description/ - *

- *

- * Buildings Skyline Contour - * The geometric information of each building is represented by a triplet of integers [Li, Ri, Hi], where Li and Ri are the x coordinates of the left and right edge of the ith building, respectively, and Hi is its height. It is guaranteed that 0 ≤ Li, Ri ≤ INT_MAX, 0 < Hi ≤ INT_MAX, and Ri - Li > 0. You may assume all buildings are perfect rectangles grounded on an absolutely flat surface at height 0. - *

- * For instance, the dimensions of all buildings in Figure A are recorded as: [ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ] . - *

- * The output is a list of "key points" (red dots in Figure B) in the format of [ [x1,y1], [x2, y2], [x3, y3], ... ] that uniquely defines a skyline. A key point is the left endpoint of a horizontal line segment. Note that the last key point, where the rightmost building ends, is merely used to mark the termination of the skyline, and always has zero height. Also, the ground in between any two adjacent buildings should be considered part of the skyline contour. - *

- * For instance, the skyline in Figure B should be represented as:[ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ]. - *

- * Notes: - *

- * The number of buildings in any input list is guaranteed to be in the range [0, 10000]. - * The input list is already sorted in ascending order by the left x position Li. - * The output list must be sorted by the x position. - * There must be no consecutive horizontal lines of equal height in the output skyline. For instance, [...[2 3], [4 5], [7 5], [11 5], [12 7]...] is not acceptable; the three lines of height 5 should be merged into one in the final output as such: [...[2 3], [4 5], [12 7], ...] - *

- * Solution: - * 1. Sort array of points. Each point here is either a start of a rectangle or end of a rectangle. - * 2. Maintain a priority queue of rectangles ordered by increasing order of height, if height of two rectangle is same then, - * order by left most start index. - * 3. For each point starting from left-most point: - * 3.a. Add all the rectangles which starts at this point. - * 3.b. Remove all the rectangles which ends at this point. Keep a max of height for each rectangle removed. - * 3.c. If the current priority queue is empty then, include current point (x, 0) to the result set. This indicates this was the last rectangle and after this - * there is a gap of at least 1 unit. - *

- * If the max calculated in step b is greater than current max then, include current x and max height from priority queue to the result set. - * This indicates one of the larger rectangle's right edge intersects with a smaller one. - *

- * If the max calculated in stop b is smaller then check if the peek element in priority queue has the left edge value equal to current point. If so, - * then this indicates that a new larger rectangle starts from this point therefore add this point to the result set. - * 4. Return the result set + * + *

Buildings Skyline Contour The geometric information of each building is represented by a + * triplet of integers [Li, Ri, Hi], where Li and Ri are the x coordinates of the left and right + * edge of the ith building, respectively, and Hi is its height. It is guaranteed that 0 ≤ Li, Ri ≤ + * INT_MAX, 0 < Hi ≤ INT_MAX, and Ri - Li > 0. You may assume all buildings are perfect rectangles + * grounded on an absolutely flat surface at height 0. + * + *

For instance, the dimensions of all buildings in Figure A are recorded as: [ [2 9 10], [3 7 + * 15], [5 12 12], [15 20 10], [19 24 8] ] . + * + *

The output is a list of "key points" (red dots in Figure B) in the format of [ [x1,y1], [x2, + * y2], [x3, y3], ... ] that uniquely defines a skyline. A key point is the left endpoint of a + * horizontal line segment. Note that the last key point, where the rightmost building ends, is + * merely used to mark the termination of the skyline, and always has zero height. Also, the ground + * in between any two adjacent buildings should be considered part of the skyline contour. + * + *

For instance, the skyline in Figure B should be represented as:[ [2 10], [3 15], [7 12], [12 + * 0], [15 10], [20 8], [24, 0] ]. + * + *

Notes: + * + *

The number of buildings in any input list is guaranteed to be in the range [0, 10000]. The + * input list is already sorted in ascending order by the left x position Li. The output list must + * be sorted by the x position. There must be no consecutive horizontal lines of equal height in the + * output skyline. For instance, [...[2 3], [4 5], [7 5], [11 5], [12 7]...] is not acceptable; the + * three lines of height 5 should be merged into one in the final output as such: [...[2 3], [4 5], + * [12 7], ...] + * + *

Solution: 1. Sort array of points. Each point here is either a start of a rectangle or end of + * a rectangle. 2. Maintain a priority queue of rectangles ordered by increasing order of height, if + * height of two rectangle is same then, order by left most start index. 3. For each point starting + * from left-most point: 3.a. Add all the rectangles which starts at this point. 3.b. Remove all the + * rectangles which ends at this point. Keep a max of height for each rectangle removed. 3.c. If the + * current priority queue is empty then, include current point (x, 0) to the result set. This + * indicates this was the last rectangle and after this there is a gap of at least 1 unit. + * + *

If the max calculated in step b is greater than current max then, include current x and max + * height from priority queue to the result set. This indicates one of the larger rectangle's right + * edge intersects with a smaller one. + * + *

If the max calculated in stop b is smaller then check if the peek element in priority queue + * has the left edge value equal to current point. If so, then this indicates that a new larger + * rectangle starts from this point therefore add this point to the result set. 4. Return the result + * set */ public class TheSkylineProblem { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[][] A = {{0, 30, 30}, {2, 9, 10}, {3, 7, 15}, {4, 8, 10}, {5, 12, 12}, {15, 20, 10}, {19, 24, 8}}; - //int[][] A = {{2,9,10}, {3,9,11}, {4,9,12}, {5,9,13}}; - List result = new TheSkylineProblem().getSkyline(A); - result.forEach(x -> { - System.out.println(x[0] + " " + x[1]); + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[][] A = { + {0, 30, 30}, {2, 9, 10}, {3, 7, 15}, {4, 8, 10}, {5, 12, 12}, {15, 20, 10}, {19, 24, 8} + }; + // int[][] A = {{2,9,10}, {3,9,11}, {4,9,12}, {5,9,13}}; + List result = new TheSkylineProblem().getSkyline(A); + result.forEach( + x -> { + System.out.println(x[0] + " " + x[1]); }); - } + } - public List getSkyline(int[][] buildings) { - PriorityQueue pq = new PriorityQueue<>(Comparator.comparing(Rectangle::getH) + public List getSkyline(int[][] buildings) { + PriorityQueue pq = + new PriorityQueue<>( + Comparator.comparing(Rectangle::getH) .reversed() - .thenComparing(Rectangle::getX1)); //order by height, if height is same then, order by left most starting edge. - List result = new ArrayList<>(); - Set set = new HashSet<>(); - for (int[] p : buildings) { - set.add(p[0]); - set.add(p[1]); - } - List points = new ArrayList<>(); - points.addAll(set); - points.sort(Integer::compare); + .thenComparing( + Rectangle + ::getX1)); // order by height, if height is same then, order by left most + // starting edge. + List result = new ArrayList<>(); + Set set = new HashSet<>(); + for (int[] p : buildings) { + set.add(p[0]); + set.add(p[1]); + } + List points = new ArrayList<>(); + points.addAll(set); + points.sort(Integer::compare); - for (int i = 0, j = 0, l = points.size(); i < l; i++) { - int curr = points.get(i); + for (int i = 0, j = 0, l = points.size(); i < l; i++) { + int curr = points.get(i); - for (int k = j; k < buildings.length; k++) { //add all the rectangles that begin at this point - int[] rectangle = buildings[k]; - if (rectangle[0] == curr) { - pq.offer(new Rectangle(rectangle[0], rectangle[1], rectangle[2])); - } else if (rectangle[0] > curr) { - j = k; - break; - } - } - int max = Integer.MIN_VALUE; - while (!pq.isEmpty()) { // remove all the rectangles that end at this point - if (pq.peek().getX2() == curr) { - Rectangle top = pq.poll(); - max = Math.max(max, top.getH()); - } else if (pq.peek().getX2() < curr) { - pq.poll(); - } else { - break; - } - } - if (pq.isEmpty()) { - result.add(makeNewPoint(curr, 0)); //This is the last rectangle after this there is a gap of at least one unit - } else { - if (max > pq.peek().getH()) { - result.add(makeNewPoint(curr, pq.peek().getH())); //one of the larger rectangle's right edge intersects with a smaller one - } else if (max < pq.peek().getH() && pq.peek().getX1() == curr) { - result.add(makeNewPoint(curr, pq.peek().getH())); //new larger rectangle begins at this point - } - } + for (int k = j; + k < buildings.length; + k++) { // add all the rectangles that begin at this point + int[] rectangle = buildings[k]; + if (rectangle[0] == curr) { + pq.offer(new Rectangle(rectangle[0], rectangle[1], rectangle[2])); + } else if (rectangle[0] > curr) { + j = k; + break; + } + } + int max = Integer.MIN_VALUE; + while (!pq.isEmpty()) { // remove all the rectangles that end at this point + if (pq.peek().getX2() == curr) { + Rectangle top = pq.poll(); + max = Math.max(max, top.getH()); + } else if (pq.peek().getX2() < curr) { + pq.poll(); + } else { + break; } - return result; + } + if (pq.isEmpty()) { + result.add( + makeNewPoint( + curr, + 0)); // This is the last rectangle after this there is a gap of at least one unit + } else { + if (max > pq.peek().getH()) { + result.add( + makeNewPoint( + curr, + pq.peek() + .getH())); // one of the larger rectangle's right edge intersects with a + // smaller one + } else if (max < pq.peek().getH() && pq.peek().getX1() == curr) { + result.add( + makeNewPoint(curr, pq.peek().getH())); // new larger rectangle begins at this point + } + } } + return result; + } - private int[] makeNewPoint(int x, int y) { - int[] point = new int[2]; - point[0] = x; - point[1] = y; - return point; - } + private int[] makeNewPoint(int x, int y) { + int[] point = new int[2]; + point[0] = x; + point[1] = y; + return point; + } - class Rectangle { - private int x1, x2, h; + class Rectangle { + private int x1, x2, h; - Rectangle(int x1, int x2, int h) { - this.x1 = x1; - this.x2 = x2; - this.h = h; - } + Rectangle(int x1, int x2, int h) { + this.x1 = x1; + this.x2 = x2; + this.h = h; + } - public int getH() { - return h; - } + public int getH() { + return h; + } - public int getX2() { - return x2; - } + public int getX2() { + return x2; + } - public int getX1() { - return x1; - } + public int getX1() { + return x1; } + } } diff --git a/problems/src/heap/TopKFrequentWords.java b/problems/src/heap/TopKFrequentWords.java index f47cf236..f0bf249b 100644 --- a/problems/src/heap/TopKFrequentWords.java +++ b/problems/src/heap/TopKFrequentWords.java @@ -3,75 +3,73 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 07/04/2018. - * Given a non-empty list of words, return the k most frequent elements. - - Your answer should be sorted by frequency from highest to lowest. If two words have the same frequency, then the - word with the lower alphabetical order comes first. - - Example 1: - Input: ["i", "love", "leetcode", "i", "love", "coding"], k = 2 - Output: ["i", "love"] - Explanation: "i" and "love" are the two most frequent words. - Note that "i" comes before "love" due to a lower alphabetical order. - Example 2: - Input: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4 - Output: ["the", "is", "sunny", "day"] - Explanation: "the", "is", "sunny" and "day" are the four most frequent words, - with the number of occurrence being 4, 3, 2 and 1 respectively. - Note: - You may assume k is always valid, 1 ≤ k ≤ number of unique elements. - Input words contain only lowercase letters. - Follow up: - Try to solve it in O(n log k) time and O(n) extra space. - - Solution: O(n log k). Calculate frequency and maintain a inverse priority queue of size k and add elements. Return - result by reversing the priority queue elements. + * Created by gouthamvidyapradhan on 07/04/2018. Given a non-empty list of words, return the k most + * frequent elements. + * + *

Your answer should be sorted by frequency from highest to lowest. If two words have the same + * frequency, then the word with the lower alphabetical order comes first. + * + *

Example 1: Input: ["i", "love", "leetcode", "i", "love", "coding"], k = 2 Output: ["i", + * "love"] Explanation: "i" and "love" are the two most frequent words. Note that "i" comes before + * "love" due to a lower alphabetical order. Example 2: Input: ["the", "day", "is", "sunny", "the", + * "the", "the", "sunny", "is", "is"], k = 4 Output: ["the", "is", "sunny", "day"] Explanation: + * "the", "is", "sunny" and "day" are the four most frequent words, with the number of occurrence + * being 4, 3, 2 and 1 respectively. Note: You may assume k is always valid, 1 ≤ k ≤ number of + * unique elements. Input words contain only lowercase letters. Follow up: Try to solve it in O(n + * log k) time and O(n) extra space. + * + *

Solution: O(n log k). Calculate frequency and maintain a inverse priority queue of size k and + * add elements. Return result by reversing the priority queue elements. */ public class TopKFrequentWords { - class Pair{ - String word; - int freq; - Pair(String word, int freq){ - this.word = word; - this.freq = freq; - } - } + class Pair { + String word; + int freq; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - String[] words = {"i", "love", "leetcode", "i", "love", "coding"}; - List sorted = new TopKFrequentWords().topKFrequent(words, 2); - sorted.stream().forEach(System.out::println); + Pair(String word, int freq) { + this.word = word; + this.freq = freq; } + } - public List topKFrequent(String[] words, int k) { - Map map = new HashMap<>(); - for(String w : words){ - map.putIfAbsent(w, 0); - int freq = map.get(w); - map.put(w, freq + 1); - } - Queue pq = new PriorityQueue<>((o1, o2) -> (o1.freq == o2.freq) ? o2.word.compareTo(o1.word) : - Integer.compare(o1.freq, o2.freq)); - for(String w : map.keySet()){ - int f = map.get(w); - pq.offer(new Pair(w, f)); - if(pq.size() > k){ - pq.poll(); - } - } - List result = new ArrayList<>(); - while(!pq.isEmpty()){ - result.add(pq.poll().word); - } - Collections.reverse(result); - return result; - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + String[] words = {"i", "love", "leetcode", "i", "love", "coding"}; + List sorted = new TopKFrequentWords().topKFrequent(words, 2); + sorted.stream().forEach(System.out::println); + } + public List topKFrequent(String[] words, int k) { + Map map = new HashMap<>(); + for (String w : words) { + map.putIfAbsent(w, 0); + int freq = map.get(w); + map.put(w, freq + 1); + } + Queue pq = + new PriorityQueue<>( + (o1, o2) -> + (o1.freq == o2.freq) + ? o2.word.compareTo(o1.word) + : Integer.compare(o1.freq, o2.freq)); + for (String w : map.keySet()) { + int f = map.get(w); + pq.offer(new Pair(w, f)); + if (pq.size() > k) { + pq.poll(); + } + } + List result = new ArrayList<>(); + while (!pq.isEmpty()) { + result.add(pq.poll().word); + } + Collections.reverse(result); + return result; + } } diff --git a/problems/src/linked_list/DeleteNode.java b/problems/src/linked_list/DeleteNode.java index b22be8cc..28479dcf 100644 --- a/problems/src/linked_list/DeleteNode.java +++ b/problems/src/linked_list/DeleteNode.java @@ -1,45 +1,46 @@ package linked_list; /** - * Created by gouthamvidyapradhan on 04/07/2017. - * Write a function to delete a node (except the tail) in a singly linked list, given only access to that node. - *

- * Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function. + * Created by gouthamvidyapradhan on 04/07/2017. Write a function to delete a node (except the tail) + * in a singly linked list, given only access to that node. + * + *

Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, + * the linked list should become 1 -> 2 -> 4 after calling your function. */ public class DeleteNode { - public static class ListNode { - int val; - ListNode next; + public static class ListNode { + int val; + ListNode next; - ListNode(int x) { - val = x; - } + ListNode(int x) { + val = x; } + } - 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); - new DeleteNode().deleteNode(node.next.next); - while (node != null) { - System.out.println(node.val); - node = node.next; - } + 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); + new DeleteNode().deleteNode(node.next.next); + while (node != null) { + System.out.println(node.val); + node = node.next; } + } - public void deleteNode(ListNode node) { - ListNode prev = node; - ListNode last = node; - ListNode next = node.next; - while (next != null) { - last = prev; - int temp = prev.val; - prev.val = next.val; - next.val = temp; - prev = prev.next; - next = next.next; - } - last.next = null; + public void deleteNode(ListNode node) { + ListNode prev = node; + ListNode last = node; + ListNode next = node.next; + while (next != null) { + last = prev; + int temp = prev.val; + prev.val = next.val; + next.val = temp; + prev = prev.next; + next = next.next; } + last.next = null; + } } diff --git a/problems/src/linked_list/IntersectionOfTwoLists.java b/problems/src/linked_list/IntersectionOfTwoLists.java index 5e9ae0c2..e52392c8 100644 --- a/problems/src/linked_list/IntersectionOfTwoLists.java +++ b/problems/src/linked_list/IntersectionOfTwoLists.java @@ -1,94 +1,88 @@ package linked_list; /** - * Created by gouthamvidyapradhan on 24/02/2017. - * Write a program to find the node at which the intersection of two singly linked lists begins. + * Created by gouthamvidyapradhan on 24/02/2017. Write a program to find the node at which the + * intersection of two singly linked lists begins. + * *

+ * + *

For example, the following two linked lists: + * + *

A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3 begin to intersect at node c1. + * *

- * For example, the following two linked lists: - *

- * A: a1 → a2 - * ↘ - * c1 → c2 → c3 - * ↗ - * B: b1 → b2 → b3 - * begin to intersect at node c1. - *

- *

- * Notes: - *

- * If the two linked lists have no intersection at all, return null. - * The linked lists must retain their original structure after the function returns. - * You may assume there are no cycles anywhere in the entire linked structure. - * Your code should preferably run in O(n) time and use only O(1) memory. + * + *

Notes: + * + *

If the two linked lists have no intersection at all, return null. The linked lists must retain + * their original structure after the function returns. You may assume there are no cycles anywhere + * in the entire linked structure. Your code should preferably run in O(n) time and use only O(1) + * memory. */ public class IntersectionOfTwoLists { - public static class ListNode { - int val; - ListNode next; - - ListNode(int x) { - val = x; - next = null; - } - } + public static class ListNode { + int val; + ListNode next; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - ListNode node1 = new ListNode(2); - ListNode node2 = new ListNode(3); - node1.next = node2; - System.out.println(new IntersectionOfTwoLists().getIntersectionNode(node1, node2)); + ListNode(int x) { + val = x; + next = null; } + } - public ListNode getIntersectionNode(ListNode headA, ListNode headB) { - if (headA == null || headB == null) - return null; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + ListNode node1 = new ListNode(2); + ListNode node2 = new ListNode(3); + node1.next = node2; + System.out.println(new IntersectionOfTwoLists().getIntersectionNode(node1, node2)); + } - int l1len = 0, l2len = 0; - ListNode temp1 = headA; - while (temp1 != null) { - temp1 = temp1.next; - l1len++; - } - temp1 = headB; - - while (temp1 != null) { - temp1 = temp1.next; - l2len++; - } + public ListNode getIntersectionNode(ListNode headA, ListNode headB) { + if (headA == null || headB == null) return null; + int l1len = 0, l2len = 0; + ListNode temp1 = headA; + while (temp1 != null) { + temp1 = temp1.next; + l1len++; + } + temp1 = headB; - int diff = Math.abs(l1len - l2len); + while (temp1 != null) { + temp1 = temp1.next; + l2len++; + } - ListNode temp2; + int diff = Math.abs(l1len - l2len); - if (l1len > l2len) { - temp1 = headA; - temp2 = headB; - } else { - temp1 = headB; - temp2 = headA; - } + ListNode temp2; - while (diff != 0) { - temp1 = temp1.next; - diff--; - } - while (!temp1.equals(temp2)) { - temp1 = temp1.next; - temp2 = temp2.next; - if (temp1 == null || temp2 == null) return null; - } + if (l1len > l2len) { + temp1 = headA; + temp2 = headB; + } else { + temp1 = headB; + temp2 = headA; + } - if (temp1.equals(temp2)) - return temp1; - return null; + while (diff != 0) { + temp1 = temp1.next; + diff--; + } + while (!temp1.equals(temp2)) { + temp1 = temp1.next; + temp2 = temp2.next; + if (temp1 == null || temp2 == null) return null; } + + if (temp1.equals(temp2)) return temp1; + return null; + } } diff --git a/problems/src/linked_list/LinkedListCycle.java b/problems/src/linked_list/LinkedListCycle.java index 72f5fa07..3b7bfa56 100644 --- a/problems/src/linked_list/LinkedListCycle.java +++ b/problems/src/linked_list/LinkedListCycle.java @@ -4,53 +4,49 @@ import java.util.Set; /** - * Created by gouthamvidyapradhan on 23/02/2017. - * Given a linked list, determine if it has a cycle in it. - *

- * Follow up: - * Can you solve it without using extra space? + * Created by gouthamvidyapradhan on 23/02/2017. Given a linked list, determine if it has a cycle in + * it. + * + *

Follow up: Can you solve it without using extra space? */ public class LinkedListCycle { - private static Set hashCode = new HashSet<>(); + private static Set hashCode = new HashSet<>(); - static class ListNode { - int val; - ListNode next; + static class ListNode { + int val; + ListNode next; - ListNode(int x) { - val = x; - next = null; - } + ListNode(int x) { + val = x; + next = null; } + } - /** - * Main method - * - * @param args - */ - public static void main(String[] args) throws Exception { - ListNode node1 = new ListNode(1); - ListNode node2 = new ListNode(2); - ListNode node3 = new ListNode(3); - node1.next = node2; - node2.next = node3; - node3.next = node1; - System.out.println(new LinkedListCycle().hasCycle(node1)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) throws Exception { + ListNode node1 = new ListNode(1); + ListNode node2 = new ListNode(2); + ListNode node3 = new ListNode(3); + node1.next = node2; + node2.next = node3; + node3.next = node1; + System.out.println(new LinkedListCycle().hasCycle(node1)); + } - public boolean hasCycle(ListNode head) { - ListNode slow = head; - ListNode fast = head; - while (slow != null && fast != null) { - slow = slow.next; - fast = fast.next; - if (fast != null) - fast = fast.next; - else break; - if (fast != null && slow != null) - if (fast.equals(slow)) return true; - } - return false; + public boolean hasCycle(ListNode head) { + ListNode slow = head; + ListNode fast = head; + while (slow != null && fast != null) { + slow = slow.next; + fast = fast.next; + if (fast != null) fast = fast.next; + else break; + if (fast != null && slow != null) if (fast.equals(slow)) return true; } - + return false; + } } diff --git a/problems/src/linked_list/MergeKSortedLists.java b/problems/src/linked_list/MergeKSortedLists.java index 8e3cd62f..3797b0d6 100644 --- a/problems/src/linked_list/MergeKSortedLists.java +++ b/problems/src/linked_list/MergeKSortedLists.java @@ -1,103 +1,101 @@ package linked_list; /** - * Created by gouthamvidyapradhan on 11/03/2017. - * Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. + * Created by gouthamvidyapradhan on 11/03/2017. Merge k sorted linked lists and return it as one + * sorted list. Analyze and describe its complexity. */ public class MergeKSortedLists { - public static class ListNode { - int val; - ListNode next; + public static class ListNode { + int val; + ListNode next; - ListNode(int x) { - val = x; - next = null; - } + ListNode(int x) { + val = x; + next = null; } + } - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - ListNode node2 = new ListNode(-1); - ListNode node3 = new ListNode(5); - ListNode node4 = new ListNode(11); + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + ListNode node2 = new ListNode(-1); + ListNode node3 = new ListNode(5); + ListNode node4 = new ListNode(11); - ListNode node6 = new ListNode(6); - ListNode node10 = new ListNode(10); + ListNode node6 = new ListNode(6); + ListNode node10 = new ListNode(10); + /*ListNode node1 = new ListNode(2); + ListNode node5 = new ListNode(3); + ListNode node7 = new ListNode(7); + ListNode node26 = new ListNode(26); + ListNode node111 = new ListNode(111); - /*ListNode node1 = new ListNode(2); - ListNode node5 = new ListNode(3); - ListNode node7 = new ListNode(7); - ListNode node26 = new ListNode(26); - ListNode node111 = new ListNode(111); + ListNode node11 = new ListNode(1); + ListNode node9 = new ListNode(9); + ListNode node10 = new ListNode(10); + ListNode node12 = new ListNode(12); + ListNode node119 = new ListNode(119); + */ - ListNode node11 = new ListNode(1); - ListNode node9 = new ListNode(9); - ListNode node10 = new ListNode(10); - ListNode node12 = new ListNode(12); - ListNode node119 = new ListNode(119); - */ + node2.next = node3; + node3.next = node4; - node2.next = node3; - node3.next = node4; + node6.next = node10; - node6.next = node10; + /*node1.next = node5; + node5.next = node7; + node7.next = node26; + node26.next = node111; - /*node1.next = node5; - node5.next = node7; - node7.next = node26; - node26.next = node111; + node11.next = node9; + node9.next = node10; + node10.next = node12; + node12.next = node119;*/ + ListNode[] list = new ListNode[4]; + list[0] = null; + list[1] = node2; + list[2] = null; + list[3] = node6; + ListNode result = new MergeKSortedLists().mergeKLists(list); + } - node11.next = node9; - node9.next = node10; - node10.next = node12; - node12.next = node119;*/ - ListNode[] list = new ListNode[4]; - list[0] = null; - list[1] = node2; - list[2] = null; - list[3] = node6; - ListNode result = new MergeKSortedLists().mergeKLists(list); - } - - public ListNode mergeKLists(ListNode[] lists) { - if (lists.length == 0) return null; - if (lists.length == 1) return lists[0]; - return merge(lists, 0, lists.length - 1); - } + public ListNode mergeKLists(ListNode[] lists) { + if (lists.length == 0) return null; + if (lists.length == 1) return lists[0]; + return merge(lists, 0, lists.length - 1); + } - private ListNode merge(ListNode[] lists, int s, int e) { - if (s == e) return lists[s]; - int m = s + (e - s) / 2; - ListNode left = merge(lists, s, m); - ListNode right = merge(lists, m + 1, e); - ListNode prev, temp; - ListNode headNode = new ListNode(0); - headNode.next = left; - prev = headNode; - if (left == null && right == null) return null; - else if (left == null) return right; - else if (right == null) return left; - while (left != null && right != null) { - if (left.val > right.val) { - temp = right; - right = right.next; - prev.next = temp; - temp.next = left; - prev = prev.next; - } else { - left = left.next; - prev = prev.next; - } - } - if (left == null && right != null) - prev.next = right; - return headNode.next; + private ListNode merge(ListNode[] lists, int s, int e) { + if (s == e) return lists[s]; + int m = s + (e - s) / 2; + ListNode left = merge(lists, s, m); + ListNode right = merge(lists, m + 1, e); + ListNode prev, temp; + ListNode headNode = new ListNode(0); + headNode.next = left; + prev = headNode; + if (left == null && right == null) return null; + else if (left == null) return right; + else if (right == null) return left; + while (left != null && right != null) { + if (left.val > right.val) { + temp = right; + right = right.next; + prev.next = temp; + temp.next = left; + prev = prev.next; + } else { + left = left.next; + prev = prev.next; + } } + if (left == null && right != null) prev.next = right; + return headNode.next; + } } diff --git a/problems/src/linked_list/MergeTwoSortedList.java b/problems/src/linked_list/MergeTwoSortedList.java index 377ebf10..24fc4678 100644 --- a/problems/src/linked_list/MergeTwoSortedList.java +++ b/problems/src/linked_list/MergeTwoSortedList.java @@ -1,54 +1,54 @@ package linked_list; /** - * Created by gouthamvidyapradhan on 18/03/2017. - * Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. + * Created by gouthamvidyapradhan on 18/03/2017. Merge two sorted linked lists and return it as a + * new list. The new list should be made by splicing together the nodes of the first two lists. */ public class MergeTwoSortedList { - public static class ListNode { - int val; - ListNode next; - - ListNode(int x) { - val = x; - next = null; - } - } + public static class ListNode { + int val; + ListNode next; - public static void main(String[] args) throws Exception { - ListNode head = new ListNode(0); - ListNode head1 = new ListNode(3); - ListNode head2 = new ListNode(8); - - ListNode head3 = new ListNode(1); - ListNode head4 = new ListNode(2); - ListNode head5 = new ListNode(7); - ListNode head6 = new ListNode(10); - - head.next = head1; - head1.next = head2; - - head3.next = head4; - head4.next = head5; - head5.next = head6; - - ListNode newHead = new MergeTwoSortedList().mergeTwoLists(head, head3); - ListNode link = newHead; - while (link != null) { - System.out.println(link.val); - link = link.next; - } + ListNode(int x) { + val = x; + next = null; } - - public ListNode mergeTwoLists(ListNode l1, ListNode l2) { - if (l1 == null) return l2; - else if (l2 == null) return l1; - if (l1.val <= l2.val) { - l1.next = mergeTwoLists(l1.next, l2); - return l1; - } else { - l2.next = mergeTwoLists(l1, l2.next); - return l2; - } + } + + public static void main(String[] args) throws Exception { + ListNode head = new ListNode(0); + ListNode head1 = new ListNode(3); + ListNode head2 = new ListNode(8); + + ListNode head3 = new ListNode(1); + ListNode head4 = new ListNode(2); + ListNode head5 = new ListNode(7); + ListNode head6 = new ListNode(10); + + head.next = head1; + head1.next = head2; + + head3.next = head4; + head4.next = head5; + head5.next = head6; + + ListNode newHead = new MergeTwoSortedList().mergeTwoLists(head, head3); + ListNode link = newHead; + while (link != null) { + System.out.println(link.val); + link = link.next; + } + } + + public ListNode mergeTwoLists(ListNode l1, ListNode l2) { + if (l1 == null) return l2; + else if (l2 == null) return l1; + if (l1.val <= l2.val) { + l1.next = mergeTwoLists(l1.next, l2); + return l1; + } else { + l2.next = mergeTwoLists(l1, l2.next); + return l2; } + } } diff --git a/problems/src/linked_list/MiddleOfLinkedList.java b/problems/src/linked_list/MiddleOfLinkedList.java index 33425f14..ec5a0a37 100644 --- a/problems/src/linked_list/MiddleOfLinkedList.java +++ b/problems/src/linked_list/MiddleOfLinkedList.java @@ -1,57 +1,53 @@ package linked_list; /** - * Created by gouthamvidyapradhan on 22/03/2019 - * Given a non-empty, singly linked list with head node head, return a middle node of linked list. + * Created by gouthamvidyapradhan on 22/03/2019 Given a non-empty, singly linked list with head node + * head, return a middle node of linked list. * - * If there are two middle nodes, return the second middle node. + *

If there are two middle nodes, return the second middle node. * + *

Example 1: * + *

Input: [1,2,3,4,5] Output: Node 3 from this list (Serialization: [3,4,5]) The returned node + * has value 3. (The judge's serialization of this node is [3,4,5]). Note that we returned a + * ListNode object ans, such that: ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, and + * ans.next.next.next = NULL. Example 2: * - * Example 1: + *

Input: [1,2,3,4,5,6] Output: Node 4 from this list (Serialization: [4,5,6]) Since the list has + * two middle nodes with values 3 and 4, we return the second one. * - * Input: [1,2,3,4,5] - * Output: Node 3 from this list (Serialization: [3,4,5]) - * The returned node has value 3. (The judge's serialization of this node is [3,4,5]). - * Note that we returned a ListNode object ans, such that: - * ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, and ans.next.next.next = NULL. - * Example 2: - * - * Input: [1,2,3,4,5,6] - * Output: Node 4 from this list (Serialization: [4,5,6]) - * Since the list has two middle nodes with values 3 and 4, we return the second one. - * - * Solution: O(N) - * Return the middle node. middle = count / 2 + *

Solution: O(N) Return the middle node. middle = count / 2 */ public class MiddleOfLinkedList { - public class ListNode { - int val; - ListNode next; - ListNode(int x) { val = x; } - } - /** - * Main method - * @param args - */ - public static void main(String[] args) { - } + public class ListNode { + int val; + ListNode next; - public ListNode middleNode(ListNode head) { - int count = 0; - ListNode temp = head; - while(temp != null){ - temp = temp.next; - count++; - } - int mid = count / 2; - int c = 0; - while(head != null && c < mid){ - head = head.next; - c++; - } - return head; + ListNode(int x) { + val = x; } + } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) {} + public ListNode middleNode(ListNode head) { + int count = 0; + ListNode temp = head; + while (temp != null) { + temp = temp.next; + count++; + } + int mid = count / 2; + int c = 0; + while (head != null && c < mid) { + head = head.next; + c++; + } + return head; + } } diff --git a/problems/src/linked_list/PaliandromeList.java b/problems/src/linked_list/PaliandromeList.java index c1c930fe..b8ea89d1 100644 --- a/problems/src/linked_list/PaliandromeList.java +++ b/problems/src/linked_list/PaliandromeList.java @@ -1,86 +1,83 @@ package linked_list; /** - * Created by gouthamvidyapradhan on 25/02/2017. - * Given a singly linked list, determine if it is a palindrome. - *

- * Follow up: - * Could you do it in O(n) time and O(1) space? + * Created by gouthamvidyapradhan on 25/02/2017. Given a singly linked list, determine if it is a + * palindrome. + * + *

Follow up: Could you do it in O(n) time and O(1) space? */ public class PaliandromeList { - public static class ListNode { - int val; - ListNode next; + public static class ListNode { + int val; + ListNode next; - ListNode(int x) { - val = x; - next = null; - } + ListNode(int x) { + val = x; + next = null; } + } - ListNode headNode; + ListNode headNode; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - ListNode node1 = new ListNode(1); - //ListNode node2 = new ListNode(2); - //ListNode node3 = new ListNode(3); - //ListNode node4 = new ListNode(3); - //ListNode node5 = new ListNode(2); - //ListNode node6 = new ListNode(1); - //node1.next = node2; - //node2.next = node3; - //node3.next = node5; - //node4.next = node5; - //node5.next = node6; - System.out.println(new PaliandromeList().isPalindrome(node1)); - } - - public boolean isPalindrome(ListNode head) { - int length = 0, count = 0; - if (head == null) return true; - ListNode temp = head; - while (temp != null) { - temp = temp.next; - length++; - } - if (length == 1) return true; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + ListNode node1 = new ListNode(1); + // ListNode node2 = new ListNode(2); + // ListNode node3 = new ListNode(3); + // ListNode node4 = new ListNode(3); + // ListNode node5 = new ListNode(2); + // ListNode node6 = new ListNode(1); + // node1.next = node2; + // node2.next = node3; + // node3.next = node5; + // node4.next = node5; + // node5.next = node6; + System.out.println(new PaliandromeList().isPalindrome(node1)); + } - int halfLen = length / 2; + public boolean isPalindrome(ListNode head) { + int length = 0, count = 0; + if (head == null) return true; + ListNode temp = head; + while (temp != null) { + temp = temp.next; + length++; + } + if (length == 1) return true; - temp = head; - while (count < halfLen - 1) { - temp = temp.next; - count++; - } + int halfLen = length / 2; - ListNode newHead = temp.next; - temp.next = null; - reverse(newHead); - ListNode first = head, second = headNode; - for (int i = 0; i < halfLen; i++) { - if (first.val != second.val) - return false; - first = first.next; - second = second.next; - } - return true; + temp = head; + while (count < halfLen - 1) { + temp = temp.next; + count++; } - private ListNode reverse(ListNode node) { - if (node.next == null) { - headNode = node; - return node; - } - ListNode prev = reverse(node.next); - node.next = null; - prev.next = node; - return node; + ListNode newHead = temp.next; + temp.next = null; + reverse(newHead); + ListNode first = head, second = headNode; + for (int i = 0; i < halfLen; i++) { + if (first.val != second.val) return false; + first = first.next; + second = second.next; } + return true; + } + private ListNode reverse(ListNode node) { + if (node.next == null) { + headNode = node; + return node; + } + ListNode prev = reverse(node.next); + node.next = null; + prev.next = node; + return node; + } } diff --git a/problems/src/linked_list/ReverseLinkedList.java b/problems/src/linked_list/ReverseLinkedList.java index 36df8437..6109d070 100644 --- a/problems/src/linked_list/ReverseLinkedList.java +++ b/problems/src/linked_list/ReverseLinkedList.java @@ -1,58 +1,55 @@ package linked_list; -/** - * Created by gouthamvidyapradhan on 24/02/2017. - * Reverse a singly linked list. - */ +/** Created by gouthamvidyapradhan on 24/02/2017. Reverse a singly linked list. */ public class ReverseLinkedList { - private ListNode newHead; + private ListNode newHead; - public static class ListNode { - int val; - ListNode next; + public static class ListNode { + int val; + ListNode next; - ListNode(int x) { - val = x; - next = null; - } + ListNode(int x) { + val = x; + next = null; } + } - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - ListNode node1 = new ListNode(1); - ListNode node2 = new ListNode(2); - ListNode node3 = new ListNode(3); - ListNode node4 = new ListNode(4); - ListNode node5 = new ListNode(5); - ListNode node6 = new ListNode(6); - node1.next = node2; - node2.next = node3; - node3.next = node4; - node4.next = node5; - //node5.next = node6; - ListNode newNode = new ReverseLinkedList().reverseList(node1); - System.out.println(newNode.val); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + ListNode node1 = new ListNode(1); + ListNode node2 = new ListNode(2); + ListNode node3 = new ListNode(3); + ListNode node4 = new ListNode(4); + ListNode node5 = new ListNode(5); + ListNode node6 = new ListNode(6); + node1.next = node2; + node2.next = node3; + node3.next = node4; + node4.next = node5; + // node5.next = node6; + ListNode newNode = new ReverseLinkedList().reverseList(node1); + System.out.println(newNode.val); + } - public ListNode reverseList(ListNode head) { - if (head == null) return null; - else if (head.next == null) return head; - reverse(head).next = null; - return newHead; - } + public ListNode reverseList(ListNode head) { + if (head == null) return null; + else if (head.next == null) return head; + reverse(head).next = null; + return newHead; + } - private ListNode reverse(ListNode head) { - if (head.next == null) { - newHead = head; - return head; - } - ListNode node = reverse(head.next); - node.next = head; - return head; + private ListNode reverse(ListNode head) { + if (head.next == null) { + newHead = head; + return head; } + ListNode node = reverse(head.next); + node.next = head; + return head; + } } diff --git a/problems/src/linked_list/ReverseNodesKGroup.java b/problems/src/linked_list/ReverseNodesKGroup.java index 11dc19ca..f300fb3b 100644 --- a/problems/src/linked_list/ReverseNodesKGroup.java +++ b/problems/src/linked_list/ReverseNodesKGroup.java @@ -1,97 +1,94 @@ package linked_list; /** - * Created by gouthamvidyapradhan on 06/07/2017. - * Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. + * Created by gouthamvidyapradhan on 06/07/2017. Given a linked list, reverse the nodes of a linked + * list k at a time and return its modified list. + * + *

k is a positive integer and is less than or equal to the length of the linked list. If the + * number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. + * + *

You may not alter the values in the nodes, only nodes itself may be changed. + * + *

Only constant memory is allowed. + * + *

For example, Given this linked list: 1->2->3->4->5 + * + *

For k = 2, you should return: 2->1->4->3->5 + * + *

For k = 3, you should return: 3->2->1->4->5 + * *

- * k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. - *

- * You may not alter the values in the nodes, only nodes itself may be changed. - *

- * Only constant memory is allowed. - *

- * For example, - * Given this linked list: 1->2->3->4->5 - *

- * For k = 2, you should return: 2->1->4->3->5 - *

- * For k = 3, you should return: 3->2->1->4->5 - *

- *

- * Solution: O(N) solution with constant space. - * Recursively reverse a group of K nodes and for each group join the tail of the prev group to the head - * of the next group. + * + *

Solution: O(N) solution with constant space. Recursively reverse a group of K nodes and for + * each group join the tail of the prev group to the head of the next group. */ public class ReverseNodesKGroup { - public static class ListNode { - int val; - ListNode next; + public static class ListNode { + int val; + ListNode next; - ListNode(int x) { - val = x; - } + ListNode(int x) { + val = x; } + } - private ListNode newHead, newStart, prev; + private ListNode newHead, newStart, prev; - public static void main(String[] args) throws Exception { - 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); - ListNode result = new ReverseNodesKGroup().reverseKGroup(node, 2); - while (result != null) { - System.out.println(result.val + " "); - result = result.next; - } + public static void main(String[] args) throws Exception { + 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); + ListNode result = new ReverseNodesKGroup().reverseKGroup(node, 2); + while (result != null) { + System.out.println(result.val + " "); + result = result.next; } + } - public ListNode reverseKGroup(ListNode head, int k) { - if (head == null) return null; - ListNode node = head; - int count = 0; - while (node != null) { - node = node.next; - count++; - } - if (k > count) return head; - int N = count / k; - newStart = head; - ListNode tail = null; - ListNode result = null; - while (N-- > 0) { - tail = reverse(newStart, 1, k); - tail.next = null; - if (result == null) - result = newHead; //save the head only once - if (prev != null) { - prev.next = newHead; - } - prev = tail; - } - if (tail != null) - tail.next = newStart; - return result; + public ListNode reverseKGroup(ListNode head, int k) { + if (head == null) return null; + ListNode node = head; + int count = 0; + while (node != null) { + node = node.next; + count++; } - - /** - * Reverse k nodes - * - * @param node head node - * @param count count - * @param k K - * @return - */ - private ListNode reverse(ListNode node, int count, int k) { - if (count == k) { - newStart = node.next; //new start node - newHead = node; //mark this as the new head - } else { - ListNode nNode = reverse(node.next, count + 1, k); - nNode.next = node; - } - return node; + if (k > count) return head; + int N = count / k; + newStart = head; + ListNode tail = null; + ListNode result = null; + while (N-- > 0) { + tail = reverse(newStart, 1, k); + tail.next = null; + if (result == null) result = newHead; // save the head only once + if (prev != null) { + prev.next = newHead; + } + prev = tail; } + if (tail != null) tail.next = newStart; + return result; + } + /** + * Reverse k nodes + * + * @param node head node + * @param count count + * @param k K + * @return + */ + private ListNode reverse(ListNode node, int count, int k) { + if (count == k) { + newStart = node.next; // new start node + newHead = node; // mark this as the new head + } else { + ListNode nNode = reverse(node.next, count + 1, k); + nNode.next = node; + } + return node; + } } diff --git a/problems/src/linked_list/SwapNodesInPairs.java b/problems/src/linked_list/SwapNodesInPairs.java index 4a9bba13..a74da9a1 100644 --- a/problems/src/linked_list/SwapNodesInPairs.java +++ b/problems/src/linked_list/SwapNodesInPairs.java @@ -1,59 +1,57 @@ package linked_list; /** - * Created by gouthamvidyapradhan on 13/08/2017. - * Given a linked list, swap every two adjacent nodes and return its head. - *

- * For example, - * Given 1->2->3->4, you should return the list as 2->1->4->3. - *

- * Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed. + * Created by gouthamvidyapradhan on 13/08/2017. Given a linked list, swap every two adjacent nodes + * and return its head. + * + *

For example, Given 1->2->3->4, you should return the list as 2->1->4->3. + * + *

Your algorithm should use only constant space. You may not modify the values in the list, only + * nodes itself can be changed. */ public class SwapNodesInPairs { - public static class ListNode { - int val; - ListNode next; + public static class ListNode { + int val; + ListNode next; - ListNode(int x) { - val = x; - } + ListNode(int x) { + val = x; } + } - public static void main(String[] args) throws Exception { - 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); - node.next.next.next.next.next = new ListNode(6); - ListNode head = new SwapNodesInPairs().swapPairs(node); - while (head != null) { - System.out.println(head.val); - head = head.next; - } + public static void main(String[] args) throws Exception { + 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); + node.next.next.next.next.next = new ListNode(6); + ListNode head = new SwapNodesInPairs().swapPairs(node); + while (head != null) { + System.out.println(head.val); + head = head.next; } + } - public ListNode swapPairs(ListNode head) { - if (head == null || head.next == null) - return head; - ListNode newHead = head.next; - ListNode curr = head.next; - ListNode prev = head; - ListNode prevPrev = new ListNode(-1); //dummy node - while (curr != null) { - prev.next = curr.next; - curr.next = prev; - prevPrev.next = curr; - if (prev.next != null) { - curr = prev.next.next; - prev = prev.next; - prevPrev = prevPrev.next.next; - } else { - curr = null; - } - } - return newHead; + public ListNode swapPairs(ListNode head) { + if (head == null || head.next == null) return head; + ListNode newHead = head.next; + ListNode curr = head.next; + ListNode prev = head; + ListNode prevPrev = new ListNode(-1); // dummy node + while (curr != null) { + prev.next = curr.next; + curr.next = prev; + prevPrev.next = curr; + if (prev.next != null) { + curr = prev.next.next; + prev = prev.next; + prevPrev = prevPrev.next.next; + } else { + curr = null; + } } - + return newHead; + } } diff --git a/problems/src/math/AddDigits.java b/problems/src/math/AddDigits.java index 596714e0..62a46a3c 100644 --- a/problems/src/math/AddDigits.java +++ b/problems/src/math/AddDigits.java @@ -1,25 +1,24 @@ package math; /** - * Created by gouthamvidyapradhan on 02/08/2017. - * Given a non-negative integer num, repeatedly add all its digits until the result has only one digit. - *

- * For example: - *

- * Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it. - *

- * Follow up: - * Could you do it without any loop/recursion in O(1) runtime? + * Created by gouthamvidyapradhan on 02/08/2017. Given a non-negative integer num, repeatedly add + * all its digits until the result has only one digit. + * + *

For example: + * + *

Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return + * it. + * + *

Follow up: Could you do it without any loop/recursion in O(1) runtime? */ public class AddDigits { - public static void main(String[] args) throws Exception { - System.out.println(new AddDigits().addDigits(38)); - } - - public int addDigits(int num) { - if (num == 0) return 0; - return num % 9 == 0 ? 9 : num % 9; - } + public static void main(String[] args) throws Exception { + System.out.println(new AddDigits().addDigits(38)); + } + public int addDigits(int num) { + if (num == 0) return 0; + return num % 9 == 0 ? 9 : num % 9; + } } diff --git a/problems/src/math/AddTwoNumbers.java b/problems/src/math/AddTwoNumbers.java index a2387ab4..89e6a6fb 100644 --- a/problems/src/math/AddTwoNumbers.java +++ b/problems/src/math/AddTwoNumbers.java @@ -1,78 +1,77 @@ package math; /** - * Created by gouthamvidyapradhan on 13/03/2017. - * You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. - *

- * You may assume the two numbers do not contain any leading zero, except the number 0 itself. - *

- * Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) - * Output: 7 -> 0 -> 8 + * Created by gouthamvidyapradhan on 13/03/2017. You are given two non-empty linked lists + * representing two non-negative integers. The digits are stored in reverse order and each of their + * nodes contain a single digit. Add the two numbers and return it as a linked list. + * + *

You may assume the two numbers do not contain any leading zero, except the number 0 itself. + * + *

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 0 -> 8 */ public class AddTwoNumbers { - public static class ListNode { - int val; - ListNode next; + public static class ListNode { + int val; + ListNode next; - ListNode(int x) { - val = x; - next = null; - } + ListNode(int x) { + val = x; + next = null; } + } - public static void main(String[] args) { - ListNode node = new ListNode(2); - node.next = new ListNode(4); - node.next.next = new ListNode(4); + public static void main(String[] args) { + ListNode node = new ListNode(2); + node.next = new ListNode(4); + node.next.next = new ListNode(4); - ListNode node1 = new ListNode(5); - node1.next = new ListNode(6); - node1.next.next = new ListNode(6); + ListNode node1 = new ListNode(5); + node1.next = new ListNode(6); + node1.next.next = new ListNode(6); - ListNode result = new AddTwoNumbers().addTwoNumbers(node, node1); - } + ListNode result = new AddTwoNumbers().addTwoNumbers(node, node1); + } - private ListNode addTwoNumbers(ListNode l1, ListNode l2) { - if (l1 == null && l2 == null) return null; - ListNode first = l1; - ListNode second = l2; - int carry = 0; - ListNode head = new ListNode(0); - ListNode prev = head; - while (first != null && second != null) { - int q = (first.val + second.val + carry) / 10; - int r = (first.val + second.val + carry) % 10; - carry = q; - ListNode node = new ListNode(r); - prev.next = node; - prev = node; - first = first.next; - second = second.next; - } + private ListNode addTwoNumbers(ListNode l1, ListNode l2) { + if (l1 == null && l2 == null) return null; + ListNode first = l1; + ListNode second = l2; + int carry = 0; + ListNode head = new ListNode(0); + ListNode prev = head; + while (first != null && second != null) { + int q = (first.val + second.val + carry) / 10; + int r = (first.val + second.val + carry) % 10; + carry = q; + ListNode node = new ListNode(r); + prev.next = node; + prev = node; + first = first.next; + second = second.next; + } - while (first != null) { - int q = (first.val + carry) / 10; - int r = (first.val + carry) % 10; - carry = q; - ListNode node = new ListNode(r); - prev.next = node; - prev = node; - first = first.next; - } + while (first != null) { + int q = (first.val + carry) / 10; + int r = (first.val + carry) % 10; + carry = q; + ListNode node = new ListNode(r); + prev.next = node; + prev = node; + first = first.next; + } - while (second != null) { - int q = (second.val + carry) / 10; - int r = (second.val + carry) % 10; - carry = q; - ListNode node = new ListNode(r); - prev.next = node; - prev = node; - second = second.next; - } + while (second != null) { + int q = (second.val + carry) / 10; + int r = (second.val + carry) % 10; + carry = q; + ListNode node = new ListNode(r); + prev.next = node; + prev = node; + second = second.next; + } - if (carry != 0) - prev.next = new ListNode(carry); + if (carry != 0) prev.next = new ListNode(carry); - return head.next; - } + return head.next; + } } diff --git a/problems/src/math/BulbSwitcherII.java b/problems/src/math/BulbSwitcherII.java index 8bbeeb3d..53196e8d 100644 --- a/problems/src/math/BulbSwitcherII.java +++ b/problems/src/math/BulbSwitcherII.java @@ -1,52 +1,42 @@ package math; - /** - * Created by gouthamvidyapradhan on 08/09/2017. - * There is a room with n lights which are turned on initially and 4 buttons on the wall. - * After performing exactly m unknown operations towards buttons, you need to return how many different kinds of status of the n lights could be. - *

- * Suppose n lights are labeled as number [1, 2, 3 ..., n], function of these 4 buttons are given below: - *

- * Flip all the lights. - * Flip lights with even numbers. - * Flip lights with odd numbers. - * Flip lights with (3k + 1) numbers, k = 0, 1, 2, ... - *

- * Example 1: - * Input: n = 1, m = 1. - * Output: 2 - * Explanation: Status can be: [on], [off] - *

- * Example 2: - * Input: n = 2, m = 1. - * Output: 3 - * Explanation: Status can be: [on, off], [off, on], [off, off] - *

- * Example 3: - * Input: n = 3, m = 1. - * Output: 4 - * Explanation: Status can be: [off, on, off], [on, off, on], [off, off, off], [off, on, on]. - *

- * Note: n and m both fit in range [0, 1000]. + * Created by gouthamvidyapradhan on 08/09/2017. There is a room with n lights which are turned on + * initially and 4 buttons on the wall. After performing exactly m unknown operations towards + * buttons, you need to return how many different kinds of status of the n lights could be. + * + *

Suppose n lights are labeled as number [1, 2, 3 ..., n], function of these 4 buttons are given + * below: + * + *

Flip all the lights. Flip lights with even numbers. Flip lights with odd numbers. Flip lights + * with (3k + 1) numbers, k = 0, 1, 2, ... + * + *

Example 1: Input: n = 1, m = 1. Output: 2 Explanation: Status can be: [on], [off] + * + *

Example 2: Input: n = 2, m = 1. Output: 3 Explanation: Status can be: [on, off], [off, on], + * [off, off] + * + *

Example 3: Input: n = 3, m = 1. Output: 4 Explanation: Status can be: [off, on, off], [on, + * off, on], [off, off, off], [off, on, on]. + * + *

Note: n and m both fit in range [0, 1000]. */ public class BulbSwitcherII { - public static void main(String[] args) throws Exception { - System.out.println(new BulbSwitcherII().flipLights(1, 1000)); - } + public static void main(String[] args) throws Exception { + System.out.println(new BulbSwitcherII().flipLights(1, 1000)); + } - public int flipLights(int n, int m) { - if (n == 0 || m == 0) return 1; - if (n == 1 && m >= 1) return 2; - if (n == 2) { - if (m == 1) return 3; - if (m >= 2) return 4; - } else if (n >= 3) { - if (m == 1) return 4; - if (m == 2) return 7; - } - return 8; + public int flipLights(int n, int m) { + if (n == 0 || m == 0) return 1; + if (n == 1 && m >= 1) return 2; + if (n == 2) { + if (m == 1) return 3; + if (m >= 2) return 4; + } else if (n >= 3) { + if (m == 1) return 4; + if (m == 2) return 7; } - + return 8; + } } diff --git a/problems/src/math/CountPrimes.java b/problems/src/math/CountPrimes.java index a72140d1..ce212ea9 100644 --- a/problems/src/math/CountPrimes.java +++ b/problems/src/math/CountPrimes.java @@ -3,40 +3,38 @@ import java.util.BitSet; /** - * Created by gouthamvidyapradhan on 21/03/2017. - * Description: - *

- * Count the number of prime numbers less than a non-negative number, n. + * Created by gouthamvidyapradhan on 21/03/2017. Description: + * + *

Count the number of prime numbers less than a non-negative number, n. */ public class CountPrimes { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new CountPrimes().countPrimes(999187)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new CountPrimes().countPrimes(999187)); + } - public int countPrimes(int n) { - if (n == 0 || n == 1 || n == 2) return 0; - else if (n == 3) return 1; - BitSet set = new BitSet(); - n = n - 1; - int sqRt = (int) Math.sqrt(n); - int count = n; - for (int i = 2; i <= sqRt; i++) { - if (!set.get(i)) { - for (int j = 2; (i * j) <= n; j++) { - if (!set.get(i * j)) { - count--; - set.set(i * j); - } - } - } + public int countPrimes(int n) { + if (n == 0 || n == 1 || n == 2) return 0; + else if (n == 3) return 1; + BitSet set = new BitSet(); + n = n - 1; + int sqRt = (int) Math.sqrt(n); + int count = n; + for (int i = 2; i <= sqRt; i++) { + if (!set.get(i)) { + for (int j = 2; (i * j) <= n; j++) { + if (!set.get(i * j)) { + count--; + set.set(i * j); + } } - return count - 1; + } } - + return count - 1; + } } diff --git a/problems/src/math/CouplesHoldingHands.java b/problems/src/math/CouplesHoldingHands.java index 7a1a8906..65bbc71e 100644 --- a/problems/src/math/CouplesHoldingHands.java +++ b/problems/src/math/CouplesHoldingHands.java @@ -1,81 +1,78 @@ package math; /** - * Created by gouthamvidyapradhan on 23/06/2018. - * N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum number of swaps so - * that every couple is sitting side by side. A swap consists of choosing any two people, then they stand up and - * switch seats. - - The people and seats are represented by an integer from 0 to 2N-1, the couples are numbered in order, the first - couple being (0, 1), the second couple being (2, 3), and so on with the last couple being (2N-2, 2N-1). - - The couples' initial seating is given by row[i] being the value of the person who is initially sitting in the i-th - seat. - - Example 1: - - Input: row = [0, 2, 1, 3] - Output: 1 - Explanation: We only need to swap the second (row[1]) and third (row[2]) person. - Example 2: - - Input: row = [3, 2, 0, 1] - Output: 0 - Explanation: All couples are already seated side by side. - Note: - - len(row) is even and in the range of [4, 60]. - row is guaranteed to be a permutation of 0...len(row)-1. - - Solution: O(N ^ 2). Find the index i of every even-number n and (n + 1)th number. If the index i of number n is even - then swap the number (n + 1) with index i + 1, else swap the number (n + 1) with index i - 1. Count the total swaps - and return the answer. + * Created by gouthamvidyapradhan on 23/06/2018. N couples sit in 2N seats arranged in a row and + * want to hold hands. We want to know the minimum number of swaps so that every couple is sitting + * side by side. A swap consists of choosing any two people, then they stand up and switch seats. + * + *

The people and seats are represented by an integer from 0 to 2N-1, the couples are numbered in + * order, the first couple being (0, 1), the second couple being (2, 3), and so on with the last + * couple being (2N-2, 2N-1). + * + *

The couples' initial seating is given by row[i] being the value of the person who is initially + * sitting in the i-th seat. + * + *

Example 1: + * + *

Input: row = [0, 2, 1, 3] Output: 1 Explanation: We only need to swap the second (row[1]) and + * third (row[2]) person. Example 2: + * + *

Input: row = [3, 2, 0, 1] Output: 0 Explanation: All couples are already seated side by side. + * Note: + * + *

len(row) is even and in the range of [4, 60]. row is guaranteed to be a permutation of + * 0...len(row)-1. + * + *

Solution: O(N ^ 2). Find the index i of every even-number n and (n + 1)th number. If the index + * i of number n is even then swap the number (n + 1) with index i + 1, else swap the number (n + 1) + * with index i - 1. Count the total swaps and return the answer. */ public class CouplesHoldingHands { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1, 3, 4, 0, 2, 5}; - System.out.println(new CouplesHoldingHands().minSwapsCouples(A)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 3, 4, 0, 2, 5}; + System.out.println(new CouplesHoldingHands().minSwapsCouples(A)); + } - public int minSwapsCouples(int[] row) { - int N = row.length; - int count = 0; - for(int i = 0; i < N; i +=2){ - int pos = find(row, i); - if((pos % 2) == 0){ - if(row[pos + 1] != i + 1){ - int nexNumPos = find(row, i + 1); - swap(row, pos + 1, nexNumPos); - count ++; - } - } else{ - if(row[pos - 1] != i + 1){ - int nexNumPos = find(row, i + 1); - swap(row, pos - 1, nexNumPos); - count ++; - } - } + public int minSwapsCouples(int[] row) { + int N = row.length; + int count = 0; + for (int i = 0; i < N; i += 2) { + int pos = find(row, i); + if ((pos % 2) == 0) { + if (row[pos + 1] != i + 1) { + int nexNumPos = find(row, i + 1); + swap(row, pos + 1, nexNumPos); + count++; } - return count; - } - - private int find(int[] A, int n){ - for(int i = 0; i < A.length; i ++){ - if(A[i] == n){ - return i; - } + } else { + if (row[pos - 1] != i + 1) { + int nexNumPos = find(row, i + 1); + swap(row, pos - 1, nexNumPos); + count++; } - return -1; + } } + return count; + } - private void swap(int[] A, int i, int j){ - int temp = A[i]; - A[i] = A[j]; - A[j] = temp; + private int find(int[] A, int n) { + for (int i = 0; i < A.length; i++) { + if (A[i] == n) { + return i; + } } + return -1; + } + + private void swap(int[] A, int i, int j) { + int temp = A[i]; + A[i] = A[j]; + A[j] = temp; + } } diff --git a/problems/src/math/ExcelSheetColumnTitle.java b/problems/src/math/ExcelSheetColumnTitle.java index 21c43c4c..e6f9e7e5 100644 --- a/problems/src/math/ExcelSheetColumnTitle.java +++ b/problems/src/math/ExcelSheetColumnTitle.java @@ -1,47 +1,39 @@ package math; /** - * Created by gouthamvidyapradhan on 12/08/2017. - * Given a positive integer, return its corresponding column title as appear in an Excel sheet. - *

- * For example: - *

- * 1 -> A - * 2 -> B - * 3 -> C - * ... - * 26 -> Z - * 27 -> AA - * 28 -> AB + * Created by gouthamvidyapradhan on 12/08/2017. Given a positive integer, return its corresponding + * column title as appear in an Excel sheet. + * + *

For example: + * + *

1 -> A 2 -> B 3 -> C ... 26 -> Z 27 -> AA 28 -> AB */ public class ExcelSheetColumnTitle { - private static final String CONST = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new ExcelSheetColumnTitle().convertToTitle(52)); - } + private static final String CONST = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new ExcelSheetColumnTitle().convertToTitle(52)); + } - public String convertToTitle(int n) { - StringBuilder ans = new StringBuilder(); - while (n > 0) { - int mod = n % 26; - n /= 26; - if (mod == 0) { - ans.append('Z'); - n -= 1; - } else { - ans.append(CONST.charAt(mod - 1)); - } - } - return ans.reverse().toString(); + public String convertToTitle(int n) { + StringBuilder ans = new StringBuilder(); + while (n > 0) { + int mod = n % 26; + n /= 26; + if (mod == 0) { + ans.append('Z'); + n -= 1; + } else { + ans.append(CONST.charAt(mod - 1)); + } } - + return ans.reverse().toString(); + } } diff --git a/problems/src/math/GlobalAndLocalInversions.java b/problems/src/math/GlobalAndLocalInversions.java index 4da900af..eb974f0e 100644 --- a/problems/src/math/GlobalAndLocalInversions.java +++ b/problems/src/math/GlobalAndLocalInversions.java @@ -3,52 +3,48 @@ /** * Created by gouthamvidyapradhan on 01/02/2018. * - * We have some permutation A of [0, 1, ..., N - 1], where N is the length of A. - - The number of (global) inversions is the number of i < j with 0 <= i < j < N and A[i] > A[j]. - - The number of local inversions is the number of i with 0 <= i < N and A[i] > A[i+1]. - - Return true if and only if the number of global inversions is equal to the number of local inversions. - - Example 1: - - Input: A = [1,0,2] - Output: true - Explanation: There is 1 global inversion, and 1 local inversion. - Example 2: - - Input: A = [1,2,0] - Output: false - Explanation: There are 2 global inversions, and 1 local inversion. - Note: - - A will be a permutation of [0, 1, ..., A.length - 1]. - A will have length in range [1, 5000]. - The time limit for this problem has been reduced. - - Solution: O(N) For every i, Maintain a max value up until (i - 1). If the current element at i < max value return false + *

We have some permutation A of [0, 1, ..., N - 1], where N is the length of A. + * + *

The number of (global) inversions is the number of i < j with 0 <= i < j < N and A[i] > A[j]. + * + *

The number of local inversions is the number of i with 0 <= i < N and A[i] > A[i+1]. + * + *

Return true if and only if the number of global inversions is equal to the number of local + * inversions. + * + *

Example 1: + * + *

Input: A = [1,0,2] Output: true Explanation: There is 1 global inversion, and 1 local + * inversion. Example 2: + * + *

Input: A = [1,2,0] Output: false Explanation: There are 2 global inversions, and 1 local + * inversion. Note: + * + *

A will be a permutation of [0, 1, ..., A.length - 1]. A will have length in range [1, 5000]. + * The time limit for this problem has been reduced. + * + *

Solution: O(N) For every i, Maintain a max value up until (i - 1). If the current element at i + * < max value return false */ public class GlobalAndLocalInversions { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - - } - - public boolean isIdealPermutation(int[] A) { - if(A.length == 0 || A.length == 1) return true; - int max = Integer.MIN_VALUE; - for(int i = 1; i < A.length; i ++) { - if(A[i] < max){ - return false; - } else{ - max = Math.max(max, A[i - 1]); - } - } - return true; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception {} + + public boolean isIdealPermutation(int[] A) { + if (A.length == 0 || A.length == 1) return true; + int max = Integer.MIN_VALUE; + for (int i = 1; i < A.length; i++) { + if (A[i] < max) { + return false; + } else { + max = Math.max(max, A[i - 1]); + } } + return true; + } } diff --git a/problems/src/math/NthMagicalNumber.java b/problems/src/math/NthMagicalNumber.java index 38ac55e1..c25560b6 100644 --- a/problems/src/math/NthMagicalNumber.java +++ b/problems/src/math/NthMagicalNumber.java @@ -3,92 +3,77 @@ import java.math.BigInteger; /** - * Created by gouthamvidyapradhan on 23/03/2019 - * A positive integer is magical if it is divisible by either A or B. + * Created by gouthamvidyapradhan on 23/03/2019 A positive integer is magical if it is divisible by + * either A or B. * - * Return the N-th magical number. Since the answer may be very large, return it modulo 10^9 + 7. + *

Return the N-th magical number. Since the answer may be very large, return it modulo 10^9 + 7. * + *

Example 1: * + *

Input: N = 1, A = 2, B = 3 Output: 2 Example 2: * - * Example 1: + *

Input: N = 4, A = 2, B = 3 Output: 6 Example 3: * - * Input: N = 1, A = 2, B = 3 - * Output: 2 - * Example 2: + *

Input: N = 5, A = 2, B = 4 Output: 10 Example 4: * - * Input: N = 4, A = 2, B = 3 - * Output: 6 - * Example 3: + *

Input: N = 3, A = 6, B = 4 Output: 8 * - * Input: N = 5, A = 2, B = 4 - * Output: 10 - * Example 4: + *

Note: * - * Input: N = 3, A = 6, B = 4 - * Output: 8 + *

1 <= N <= 10^9 2 <= A <= 40000 2 <= B <= 40000 * + *

Solution: O(log((2 ^ 64) - 1)) Lets take example of N = 5, A = 4 and B = 6 The multiple of A + * are 4, 8, 12, 16, 20, 24 . . . The multiple of B are 6, 12, 18, 24 . . . * - * Note: + *

Lets take a arbitrary number E = 21 and see if this fits the correct answer E / A = 5 E / B = + * 3 This means there are 5 + 3 = 8 numbers which are divisible by either A or B such as 4, 6, 8, + * 12, 12, 16, 18, 20 but we have double counted number 12 so we have to reduce 8 by 1 therefore + * there are 7 numbers. But, 7 is greater than required number N = 5 that means we have to search + * between 0 and E - 1. Thus we can binary search to arrive at the answer. * - * 1 <= N <= 10^9 - * 2 <= A <= 40000 - * 2 <= B <= 40000 - * - * Solution: O(log((2 ^ 64) - 1)) - * Lets take example of N = 5, A = 4 and B = 6 - * The multiple of A are 4, 8, 12, 16, 20, 24 . . . - * The multiple of B are 6, 12, 18, 24 . . . - * - * Lets take a arbitrary number E = 21 and see if this fits the correct answer - * E / A = 5 - * E / B = 3 - * This means there are 5 + 3 = 8 numbers which are divisible by either A or B such as - * 4, 6, 8, 12, 12, 16, 18, 20 but we have double counted number 12 so we have to reduce 8 by 1 therefore there are - * 7 numbers. But, 7 is greater than required number N = 5 that means we have to search between 0 and E - 1. - * Thus we can binary search to arrive at the answer. - * - * The number of common multiples such as 12 in the above example can be found by E / LCM(4, 6) + *

The number of common multiples such as 12 in the above example can be found by E / LCM(4, 6) */ public class NthMagicalNumber { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - System.out.println(new NthMagicalNumber().nthMagicalNumber(3, 2, 4)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + System.out.println(new NthMagicalNumber().nthMagicalNumber(3, 2, 4)); + } - public int nthMagicalNumber(int N, int A, int B) { - final int CONST = 1000000007; - BigInteger bigInteger = new BigInteger(String.valueOf(A)); - long aL = (long)A * B; - long lcm = aL / bigInteger.gcd(new BigInteger(String.valueOf(B))).longValue(); - long l = 0, h = Long.MAX_VALUE; - while(l <= h){ - long m = l + (h - l) / 2; - int status = check(N, m, A, B, lcm); - if(status == 0){ - long modA = m % A; - long modB = m % B; - if(modA == 0 || modB == 0) return (int)(m % CONST); - else if(modA < modB) return (int)((m - modA) % CONST); - else return (int)((m - modB) % CONST); - } else if(status == -1){ - l = m + 1; - } else { - h = m - 1; - } - } - return 0; + public int nthMagicalNumber(int N, int A, int B) { + final int CONST = 1000000007; + BigInteger bigInteger = new BigInteger(String.valueOf(A)); + long aL = (long) A * B; + long lcm = aL / bigInteger.gcd(new BigInteger(String.valueOf(B))).longValue(); + long l = 0, h = Long.MAX_VALUE; + while (l <= h) { + long m = l + (h - l) / 2; + int status = check(N, m, A, B, lcm); + if (status == 0) { + long modA = m % A; + long modB = m % B; + if (modA == 0 || modB == 0) return (int) (m % CONST); + else if (modA < modB) return (int) ((m - modA) % CONST); + else return (int) ((m - modB) % CONST); + } else if (status == -1) { + l = m + 1; + } else { + h = m - 1; + } } + return 0; + } - private int check(int N, long num, int A, int B, long lcm){ - long sum = (num / A) + (num / B); - long common = num / lcm; - sum -= common; - if(sum == N) return 0; - else if(sum > N) return 1; - else return -1; - } + private int check(int N, long num, int A, int B, long lcm) { + long sum = (num / A) + (num / B); + long common = num / lcm; + sum -= common; + if (sum == N) return 0; + else if (sum > N) return 1; + else return -1; + } } diff --git a/problems/src/math/ReachingPoints.java b/problems/src/math/ReachingPoints.java index 40b47bf8..2297a7c8 100644 --- a/problems/src/math/ReachingPoints.java +++ b/problems/src/math/ReachingPoints.java @@ -1,88 +1,83 @@ package math; /** - * Created by gouthamvidyapradhan on 14/07/2018. - * A move consists of taking a point (x, y) and transforming it to either (x, x+y) or (x+y, y). - - Given a starting point (sx, sy) and a target point (tx, ty), return True if and only if a sequence of moves exists - to transform the point (sx, sy) to (tx, ty). Otherwise, return False. - - Examples: - Input: sx = 1, sy = 1, tx = 3, ty = 5 - Output: True - Explanation: - One series of moves that transforms the starting point to the target is: - (1, 1) -> (1, 2) - (1, 2) -> (3, 2) - (3, 2) -> (3, 5) - - Input: sx = 1, sy = 1, tx = 2, ty = 2 - Output: False - - Input: sx = 1, sy = 1, tx = 1, ty = 1 - Output: True - - Note: - - sx, sy, tx, ty will all be integers in the range [1, 10^9]. - - Solution: Start from the target, reduce the target value to start value. - If at any stage the target value goes below start value then there exist no solution hence return false. + * Created by gouthamvidyapradhan on 14/07/2018. A move consists of taking a point (x, y) and + * transforming it to either (x, x+y) or (x+y, y). + * + *

Given a starting point (sx, sy) and a target point (tx, ty), return True if and only if a + * sequence of moves exists to transform the point (sx, sy) to (tx, ty). Otherwise, return False. + * + *

Examples: Input: sx = 1, sy = 1, tx = 3, ty = 5 Output: True Explanation: One series of moves + * that transforms the starting point to the target is: (1, 1) -> (1, 2) (1, 2) -> (3, 2) (3, 2) -> + * (3, 5) + * + *

Input: sx = 1, sy = 1, tx = 2, ty = 2 Output: False + * + *

Input: sx = 1, sy = 1, tx = 1, ty = 1 Output: True + * + *

Note: + * + *

sx, sy, tx, ty will all be integers in the range [1, 10^9]. + * + *

Solution: Start from the target, reduce the target value to start value. If at any stage the + * target value goes below start value then there exist no solution hence return false. */ public class ReachingPoints { - class Pair{ - int x, y; - Pair(int x, int y){ - this.x = x; - this.y = y; - } - } + class Pair { + int x, y; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new ReachingPoints().reachingPoints(1, 1, 153, 10)); + Pair(int x, int y) { + this.x = x; + this.y = y; } + } - public boolean reachingPoints(int sx, int sy, int tx, int ty) { - Pair target = new Pair(tx, ty); - Pair start = new Pair(sx, sy); - while(true){ - if(start.x == target.x && start.y == target.y){ - return true; - } else if(start.x > target.x || start.y > target.y || target.x == target.y){ - return false; - } else if(start.x == target.x){ - int t = target.y - start.y; - return (t % target.x) == 0; - } else if(start.y == target.y){ - int t = target.x - start.x; - return (t % target.y) == 0; - } else{ - if(target.x > target.y){ - int[] R = reduce(target.x, target.y); - target.x = R[0]; - target.y = R[1]; - } else { - int[] R = reduce(target.y, target.x); - target.x = R[1]; - target.y = R[0]; - } - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new ReachingPoints().reachingPoints(1, 1, 153, 10)); + } + + public boolean reachingPoints(int sx, int sy, int tx, int ty) { + Pair target = new Pair(tx, ty); + Pair start = new Pair(sx, sy); + while (true) { + if (start.x == target.x && start.y == target.y) { + return true; + } else if (start.x > target.x || start.y > target.y || target.x == target.y) { + return false; + } else if (start.x == target.x) { + int t = target.y - start.y; + return (t % target.x) == 0; + } else if (start.y == target.y) { + int t = target.x - start.x; + return (t % target.y) == 0; + } else { + if (target.x > target.y) { + int[] R = reduce(target.x, target.y); + target.x = R[0]; + target.y = R[1]; + } else { + int[] R = reduce(target.y, target.x); + target.x = R[1]; + target.y = R[0]; } + } } + } - private int[] reduce(int x, int y){ - int t = x - y; - int q = t / y; - x -= (y * q); - if((t % y) != 0){ - x -= y; - } - return new int[]{x, y}; + private int[] reduce(int x, int y) { + int t = x - y; + int q = t / y; + x -= (y * q); + if ((t % y) != 0) { + x -= y; } + return new int[] {x, y}; + } } diff --git a/problems/src/math/RomanToInteger.java b/problems/src/math/RomanToInteger.java index 9b3a87d8..6e45b23c 100644 --- a/problems/src/math/RomanToInteger.java +++ b/problems/src/math/RomanToInteger.java @@ -5,45 +5,44 @@ /** * Created by gouthamvidyapradhan on 12/08/2017. - *

- * Given a roman numeral, convert it to an integer. - *

- * Input is guaranteed to be within the range from 1 to 3999. + * + *

Given a roman numeral, convert it to an integer. + * + *

Input is guaranteed to be within the range from 1 to 3999. */ public class RomanToInteger { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new RomanToInteger().romanToInt("DXCIX")); - } - - public int romanToInt(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); + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new RomanToInteger().romanToInt("DXCIX")); + } - String str = new StringBuilder(s).reverse().toString(); - int sum = 0, prev = -1; - for (int i = 0, l = str.length(); i < l; i++) { - int curr = map.get(str.charAt(i)); - if (curr < prev) { - sum -= curr; - } else { - sum += curr; - } - prev = curr; - } + public int romanToInt(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); - return sum; + String str = new StringBuilder(s).reverse().toString(); + int sum = 0, prev = -1; + for (int i = 0, l = str.length(); i < l; i++) { + int curr = map.get(str.charAt(i)); + if (curr < prev) { + sum -= curr; + } else { + sum += curr; + } + prev = curr; } + return sum; + } } diff --git a/problems/src/math/RotateFunction.java b/problems/src/math/RotateFunction.java index e0789341..f3abf97b 100644 --- a/problems/src/math/RotateFunction.java +++ b/problems/src/math/RotateFunction.java @@ -1,55 +1,54 @@ package math; /** - * Created by gouthamvidyapradhan on 18/03/2017. - * Given an array of integers A and let n to be its length. - *

- * Assume Bk to be an array obtained by rotating the array A k positions clock-wise, we define a "rotation function" F on A as follow: - *

- * F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1]. - *

- * Calculate the maximum value of F(0), F(1), ..., F(n-1). - *

- * Note: - * n is guaranteed to be less than 105. - *

- * Example: - *

- * A = [4, 3, 2, 6] - *

- * F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25 - * F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16 - * F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23 - * F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26 - *

- * So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26. + * Created by gouthamvidyapradhan on 18/03/2017. Given an array of integers A and let n to be its + * length. + * + *

Assume Bk to be an array obtained by rotating the array A k positions clock-wise, we define a + * "rotation function" F on A as follow: + * + *

F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1]. + * + *

Calculate the maximum value of F(0), F(1), ..., F(n-1). + * + *

Note: n is guaranteed to be less than 105. + * + *

Example: + * + *

A = [4, 3, 2, 6] + * + *

F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25 F(1) = (0 * 6) + (1 * 4) + + * (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16 F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + + * 9 = 23 F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26 + * + *

So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26. */ public class RotateFunction { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] a = {4, 3, 2, 6}; - System.out.println(new RotateFunction().maxRotateFunction(a)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] a = {4, 3, 2, 6}; + System.out.println(new RotateFunction().maxRotateFunction(a)); + } - public int maxRotateFunction(int[] A) { - if (A.length == 0 || A.length == 1) return 0; - int max = Integer.MIN_VALUE; - int l = A.length; - int sum = 0, prodSum = 0; - for (int i = 0; i < l; i++) { - prodSum += (A[i] * i); - sum += A[i]; - } - max = Math.max(max, prodSum); - for (int i = 0; i < l - 1; i++) { - prodSum = (prodSum - sum + A[i] + ((l - 1) * A[i])); - max = Math.max(max, prodSum); - } - return max; + public int maxRotateFunction(int[] A) { + if (A.length == 0 || A.length == 1) return 0; + int max = Integer.MIN_VALUE; + int l = A.length; + int sum = 0, prodSum = 0; + for (int i = 0; i < l; i++) { + prodSum += (A[i] * i); + sum += A[i]; + } + max = Math.max(max, prodSum); + for (int i = 0; i < l - 1; i++) { + prodSum = (prodSum - sum + A[i] + ((l - 1) * A[i])); + max = Math.max(max, prodSum); } + return max; + } } diff --git a/problems/src/math/SolveTheEquation.java b/problems/src/math/SolveTheEquation.java index 23b230f1..c17e48c7 100644 --- a/problems/src/math/SolveTheEquation.java +++ b/problems/src/math/SolveTheEquation.java @@ -1,117 +1,105 @@ package math; /** - * Created by gouthamvidyapradhan on 16/02/2018. - * Solve a given equation and return the value of x in the form of string "x=#value". The equation contains only - * '+', '-' operation, the variable x and its coefficient. - - If there is no solution for the equation, return "No solution". - - If there are infinite solutions for the equation, return "Infinite solutions". - - If there is exactly one solution for the equation, we ensure that the value of x is an integer. - - Example 1: - Input: "x+5-3+x=6+x-2" - Output: "x=2" - Example 2: - Input: "x=x" - Output: "Infinite solutions" - Example 3: - Input: "2x=x" - Output: "x=0" - Example 4: - Input: "2x+3x-6x=x+2" - Output: "x=-1" - Example 5: - Input: "x=x+2" - Output: "No solution" - - Solution: Solve the left and right part separately and then sum up the results. + * Created by gouthamvidyapradhan on 16/02/2018. Solve a given equation and return the value of x in + * the form of string "x=#value". The equation contains only '+', '-' operation, the variable x and + * its coefficient. + * + *

If there is no solution for the equation, return "No solution". + * + *

If there are infinite solutions for the equation, return "Infinite solutions". + * + *

If there is exactly one solution for the equation, we ensure that the value of x is an + * integer. + * + *

Example 1: Input: "x+5-3+x=6+x-2" Output: "x=2" Example 2: Input: "x=x" Output: "Infinite + * solutions" Example 3: Input: "2x=x" Output: "x=0" Example 4: Input: "2x+3x-6x=x+2" Output: "x=-1" + * Example 5: Input: "x=x+2" Output: "No solution" + * + *

Solution: Solve the left and right part separately and then sum up the results. */ - public class SolveTheEquation { - int xL = 0, xR = 0, tL = 0, tR = 0; - public static void main(String[] args) throws Exception{ - System.out.println(new SolveTheEquation().solveEquation("x=x+2")); - } + int xL = 0, xR = 0, tL = 0, tR = 0; - public String solveEquation(String equation) { - String[] parts = equation.split("="); - solve(parts[0], true); - solve(parts[1], false); - long right = (long)tR - tL; - long left = (long)xL - xR; - if(left == 0 && right == 0){ - return "Infinite solutions"; - } else if(left == 0){ - return "No solution"; - } else if(right == 0){ - return "x=0"; - } else{ - return "x=" + (right / left); - } + public static void main(String[] args) throws Exception { + System.out.println(new SolveTheEquation().solveEquation("x=x+2")); + } + + public String solveEquation(String equation) { + String[] parts = equation.split("="); + solve(parts[0], true); + solve(parts[1], false); + long right = (long) tR - tL; + long left = (long) xL - xR; + if (left == 0 && right == 0) { + return "Infinite solutions"; + } else if (left == 0) { + return "No solution"; + } else if (right == 0) { + return "x=0"; + } else { + return "x=" + (right / left); } + } - private void solve(String s, boolean isLeft){ - String num = ""; - int xSum = 0; - int rest = 0; - boolean isNeg = false; - for(int i = 0; i < s.length(); i ++){ - char c = s.charAt(i); - if(c == '-'){ - if(!num.isEmpty()){ - xSum = calculate(num, isNeg, xSum, rest)[0]; - rest = calculate(num, isNeg, xSum, rest)[1]; - } - isNeg = true; - num = ""; - }else if(c == '+'){ - if(!num.isEmpty()){ - xSum = calculate(num, isNeg, xSum, rest)[0]; - rest = calculate(num, isNeg, xSum, rest)[1]; - } - isNeg = false; - num = ""; - } else{ - num += c; - } + private void solve(String s, boolean isLeft) { + String num = ""; + int xSum = 0; + int rest = 0; + boolean isNeg = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '-') { + if (!num.isEmpty()) { + xSum = calculate(num, isNeg, xSum, rest)[0]; + rest = calculate(num, isNeg, xSum, rest)[1]; } - if(!num.isEmpty()){ - xSum = calculate(num, isNeg, xSum, rest)[0]; - rest = calculate(num, isNeg, xSum, rest)[1]; - } - if(isLeft){ - xL = xSum; - tL = rest; - } else{ - xR = xSum; - tR = rest; + isNeg = true; + num = ""; + } else if (c == '+') { + if (!num.isEmpty()) { + xSum = calculate(num, isNeg, xSum, rest)[0]; + rest = calculate(num, isNeg, xSum, rest)[1]; } + isNeg = false; + num = ""; + } else { + num += c; + } + } + if (!num.isEmpty()) { + xSum = calculate(num, isNeg, xSum, rest)[0]; + rest = calculate(num, isNeg, xSum, rest)[1]; } + if (isLeft) { + xL = xSum; + tL = rest; + } else { + xR = xSum; + tR = rest; + } + } - private int[] calculate(String num, boolean isNeg, int xSum, int rest){ - int[] A = new int[2]; - if(num.contains("x")){ - num = num.substring(0, num.length() - 1); - if(isNeg){ - xSum -= num.isEmpty() ? 1 : Integer.parseInt(num); - } else{ - xSum += num.isEmpty() ? 1 : Integer.parseInt(num); - } + private int[] calculate(String num, boolean isNeg, int xSum, int rest) { + int[] A = new int[2]; + if (num.contains("x")) { + num = num.substring(0, num.length() - 1); + if (isNeg) { + xSum -= num.isEmpty() ? 1 : Integer.parseInt(num); + } else { + xSum += num.isEmpty() ? 1 : Integer.parseInt(num); + } - } else{ - if(isNeg){ - rest -= Integer.parseInt(num); - } else{ - rest += Integer.parseInt(num); - } - } - A[0] = xSum; - A[1] = rest; - return A; + } else { + if (isNeg) { + rest -= Integer.parseInt(num); + } else { + rest += Integer.parseInt(num); + } } - + A[0] = xSum; + A[1] = rest; + return A; + } } diff --git a/problems/src/math/SquirrelSimulation.java b/problems/src/math/SquirrelSimulation.java index 54e77abf..a2a681f1 100644 --- a/problems/src/math/SquirrelSimulation.java +++ b/problems/src/math/SquirrelSimulation.java @@ -1,57 +1,45 @@ package math; /** - * Created by gouthamvidyapradhan on 25/04/2019 - * There's a tree, a squirrel, and several nuts. Positions are represented by the cells in a 2D grid. Your goal is - * to find the minimal distance for the squirrel to collect all the nuts and put them under the tree one by one. The - * squirrel can only take at most one nut at one time and can move in four directions - up, down, left and right, to - * the adjacent cell. The distance is represented by the number of moves. - * Example 1: + * Created by gouthamvidyapradhan on 25/04/2019 There's a tree, a squirrel, and several nuts. + * Positions are represented by the cells in a 2D grid. Your goal is to find the minimal distance + * for the squirrel to collect all the nuts and put them under the tree one by one. The squirrel can + * only take at most one nut at one time and can move in four directions - up, down, left and right, + * to the adjacent cell. The distance is represented by the number of moves. Example 1: * - * Input: - * Height : 5 - * Width : 7 - * Tree position : [2,2] - * Squirrel : [4,4] - * Nuts : [[3,0], [2,5]] - * Output: 12 - * Explanation: - * ​​​​​ - * Note: + *

Input: Height : 5 Width : 7 Tree position : [2,2] Squirrel : [4,4] Nuts : [[3,0], [2,5]] + * Output: 12 Explanation: ​​​​​ Note: * - * All given positions won't overlap. - * The squirrel can take at most one nut at one time. - * The given positions of nuts have no order. - * Height and width are positive integers. 3 <= height * width <= 10,000. - * The given positions contain at least one nut, only one tree and one squirrel. + *

All given positions won't overlap. The squirrel can take at most one nut at one time. The + * given positions of nuts have no order. Height and width are positive integers. 3 <= height * + * width <= 10,000. The given positions contain at least one nut, only one tree and one squirrel. * - * Solution O(N) - * Calculate the Manhattan Distance from each of the nut to the tree and double this value - Let this - * value be D. We are doubling here to simulate going from tree to a nut and back. - * Now, to get the minimum distance - for each distance d from squirrel position to nut position do, - * Min(D + d - (distance from this nut to tree)) + *

Solution O(N) Calculate the Manhattan Distance from each of the nut to the tree and double + * this value - Let this value be D. We are doubling here to simulate going from tree to a nut and + * back. Now, to get the minimum distance - for each distance d from squirrel position to nut + * position do, Min(D + d - (distance from this nut to tree)) */ public class SquirrelSimulation { - public static void main(String[] args) { - int height = 5; - int width = 7; - int[] tree = {2, 2}; - int[] squirrel = {4, 4}; - int[][] nuts = {{3, 0}, {2, 5}}; - System.out.println(new SquirrelSimulation().minDistance(height, width, tree, squirrel, nuts)); - } + public static void main(String[] args) { + int height = 5; + int width = 7; + int[] tree = {2, 2}; + int[] squirrel = {4, 4}; + int[][] nuts = {{3, 0}, {2, 5}}; + System.out.println(new SquirrelSimulation().minDistance(height, width, tree, squirrel, nuts)); + } - public int minDistance(int height, int width, int[] tree, int[] squirrel, int[][] nuts) { - int dist = 0; - for(int[] n : nuts){ - dist += Math.abs(n[0] - tree[0]) + Math.abs(n[1] - tree[1]); - } - dist *= 2; - int ans = Integer.MAX_VALUE; - for(int[] n : nuts){ - int nutDist = Math.abs(n[0] - squirrel[0]) + Math.abs(n[1] - squirrel[1]); - ans = Math.min(ans, dist - (Math.abs(n[0] - tree[0]) + Math.abs(n[1] - tree[1])) + nutDist); - } - return ans; + public int minDistance(int height, int width, int[] tree, int[] squirrel, int[][] nuts) { + int dist = 0; + for (int[] n : nuts) { + dist += Math.abs(n[0] - tree[0]) + Math.abs(n[1] - tree[1]); + } + dist *= 2; + int ans = Integer.MAX_VALUE; + for (int[] n : nuts) { + int nutDist = Math.abs(n[0] - squirrel[0]) + Math.abs(n[1] - squirrel[1]); + ans = Math.min(ans, dist - (Math.abs(n[0] - tree[0]) + Math.abs(n[1] - tree[1])) + nutDist); } + return ans; + } } diff --git a/problems/src/math/WaterAndJugProblem.java b/problems/src/math/WaterAndJugProblem.java index 37572a85..fabc0ada 100644 --- a/problems/src/math/WaterAndJugProblem.java +++ b/problems/src/math/WaterAndJugProblem.java @@ -3,42 +3,40 @@ import java.math.BigInteger; /** - * Created by gouthamvidyapradhan on 29/07/2017. - * You are given two jugs with capacities x and y litres. There is an infinite amount of water supply available. You need to determine whether it is possible to measure exactly z litres using these two jugs. - *

- * If z liters of water is measurable, you must have z liters of water contained within one or both buckets by the end. - *

- * Operations allowed: - *

- * Fill any of the jugs completely with water. - * Empty any of the jugs. - * Pour water from one jug into another till the other jug is completely full or the first jug itself is empty. - * Example 1: (From the famous "Die Hard" example) - *

- * Input: x = 3, y = 5, z = 4 - * Output: True - * Example 2: - *

- * Input: x = 2, y = 6, z = 5 - * Output: False + * Created by gouthamvidyapradhan on 29/07/2017. You are given two jugs with capacities x and y + * litres. There is an infinite amount of water supply available. You need to determine whether it + * is possible to measure exactly z litres using these two jugs. + * + *

If z liters of water is measurable, you must have z liters of water contained within one or + * both buckets by the end. + * + *

Operations allowed: + * + *

Fill any of the jugs completely with water. Empty any of the jugs. Pour water from one jug + * into another till the other jug is completely full or the first jug itself is empty. Example 1: + * (From the famous "Die Hard" example) + * + *

Input: x = 3, y = 5, z = 4 Output: True Example 2: + * + *

Input: x = 2, y = 6, z = 5 Output: False */ public class WaterAndJugProblem { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new WaterAndJugProblem().canMeasureWater(0, 0, 1)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new WaterAndJugProblem().canMeasureWater(0, 0, 1)); + } - public boolean canMeasureWater(int x, int y, int z) { - if (x == y && y == z) return true; - if (z > (x + y)) return false; - BigInteger b1 = new BigInteger(String.valueOf(x)); - BigInteger b2 = new BigInteger(String.valueOf(y)); - BigInteger b3 = b1.gcd(b2); - return b3.intValue() != 0 && (z % b3.intValue()) == 0; - } + public boolean canMeasureWater(int x, int y, int z) { + if (x == y && y == z) return true; + if (z > (x + y)) return false; + BigInteger b1 = new BigInteger(String.valueOf(x)); + BigInteger b2 = new BigInteger(String.valueOf(y)); + BigInteger b3 = b1.gcd(b2); + return b3.intValue() != 0 && (z % b3.intValue()) == 0; + } } diff --git a/problems/src/reservoir_sampling/RandomPickIndex.java b/problems/src/reservoir_sampling/RandomPickIndex.java index 8671f82e..519ecf1b 100644 --- a/problems/src/reservoir_sampling/RandomPickIndex.java +++ b/problems/src/reservoir_sampling/RandomPickIndex.java @@ -3,60 +3,57 @@ import java.util.Random; /** - * Created by gouthamvidyapradhan on 10/12/2017. - * Given an array of integers with possible duplicates, randomly output the index of a given target number. You can - * assume that the given target number must exist in the array. - - Note: - The array size can be very large. Solution that uses too much extra space will not pass the judge. - - Example: - - int[] nums = new int[] {1,2,3,3,3}; - Solution solution = new Solution(nums); - - // pick(3) should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning. - solution.pick(3); - - // pick(1) should return 0. Since in the array only nums[0] is equal to 1. - solution.pick(1); - + * Created by gouthamvidyapradhan on 10/12/2017. Given an array of integers with possible + * duplicates, randomly output the index of a given target number. You can assume that the given + * target number must exist in the array. + * + *

Note: The array size can be very large. Solution that uses too much extra space will not pass + * the judge. + * + *

Example: + * + *

int[] nums = new int[] {1,2,3,3,3}; Solution solution = new Solution(nums); + * + *

// pick(3) should return either index 2, 3, or 4 randomly. Each index should have equal + * probability of returning. solution.pick(3); + * + *

// pick(1) should return 0. Since in the array only nums[0] is equal to 1. solution.pick(1); */ public class RandomPickIndex { - private int[] nums; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1,2,3,3,3}; - System.out.println(new RandomPickIndex(A).pick(1)); + private int[] nums; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 2, 3, 3, 3}; + System.out.println(new RandomPickIndex(A).pick(1)); + } + + public RandomPickIndex(int[] nums) { + this.nums = nums; + } + + public int pick(int target) { + int count = 0; + for (int num : nums) { + if (num == target) { + count++; + } } - - public RandomPickIndex(int[] nums) { - this.nums = nums; - } - - public int pick(int target) { - int count = 0; - for (int num : nums) { - if (num == target) { - count++; - } + Random random = new Random(); + int nPick = 1 + random.nextInt(count); + count = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] == target) { + if (++count == nPick) { + return i; } - Random random = new Random(); - int nPick = 1 + random.nextInt(count); - count = 0; - for(int i = 0; i < nums.length; i ++){ - if(nums[i] == target){ - if(++count == nPick){ - return i; - } - } - } - return 0; //this is impossible + } } - + return 0; // this is impossible + } } diff --git a/problems/src/stack/BasicCalculator.java b/problems/src/stack/BasicCalculator.java index d5992129..165dc496 100644 --- a/problems/src/stack/BasicCalculator.java +++ b/problems/src/stack/BasicCalculator.java @@ -3,83 +3,82 @@ import java.util.Stack; /** - * Created by gouthamvidyapradhan on 06/02/2018. - * Implement a basic calculator to evaluate a simple expression string. - - The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative - integers and empty spaces . - - You may assume that the given expression is always valid. - - Some examples: - "1 + 1" = 2 - " 2-1 + 2 " = 3 - "(1+(4+5+2)-3)+(6+8)" = 23 - Note: Do not use the eval built-in library function. - - Solution: O(n) where n is the length of the string. - Maintain a stack and push each character from the string (ignore space). As soon as a close parentheses ')' - is encountered, start to pop values and sum-up the total until '(' is poped. Push the total back to stack - and continue to iterate. The final result will be in the top of the stack which is the last - and only element in stack. + * Created by gouthamvidyapradhan on 06/02/2018. Implement a basic calculator to evaluate a simple + * expression string. + * + *

The expression string may contain open ( and closing parentheses ), the plus + or minus sign + * -, non-negative integers and empty spaces . + * + *

You may assume that the given expression is always valid. + * + *

Some examples: "1 + 1" = 2 " 2-1 + 2 " = 3 "(1+(4+5+2)-3)+(6+8)" = 23 Note: Do not use the + * eval built-in library function. + * + *

Solution: O(n) where n is the length of the string. Maintain a stack and push each character + * from the string (ignore space). As soon as a close parentheses ')' is encountered, start to pop + * values and sum-up the total until '(' is poped. Push the total back to stack and continue to + * iterate. The final result will be in the top of the stack which is the last and only element in + * stack. */ public class BasicCalculator { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new BasicCalculator().calculate("2-1 + (2 - 3) - ((2 - (2 - (3 - (4 - 5)))))")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println( + new BasicCalculator().calculate("2-1 + (2 - 3) - ((2 - (2 - (3 - (4 - 5)))))")); + } - public int calculate(String s) { - Stack stack = new Stack<>(); - String num = ""; - s = "(" + s + ")"; - for(char c : s.toCharArray()){ - switch (c){ - case ' ': - case '(': - case '+': - case '-': - if(!num.equals("")){ - stack.push(String.valueOf(num)); - num = ""; - } - if(c != ' '){ //ignore blank - stack.push(String.valueOf(c)); - } - break; - case ')': - if(!num.equals("")){ - stack.push(String.valueOf(num)); - num = ""; - } - int sum = 0; - int prev = 0; //maintain a prev value inorder to handle minus '-' - while(!stack.isEmpty()){ - String top = stack.pop(); - if(top.equals("-")){ - sum -= (prev * 2); - prev = 0; - } else if(top.equals("+")){ - //ignore - } else if(top.equals("(")){ - stack.push(String.valueOf(sum)); - break; - } else{ - sum += Integer.parseInt(top); - prev = Integer.parseInt(top); - } - } - break; - default: - num += String.valueOf(c); - break; + public int calculate(String s) { + Stack stack = new Stack<>(); + String num = ""; + s = "(" + s + ")"; + for (char c : s.toCharArray()) { + switch (c) { + case ' ': + case '(': + case '+': + case '-': + if (!num.equals("")) { + stack.push(String.valueOf(num)); + num = ""; + } + if (c != ' ') { // ignore blank + stack.push(String.valueOf(c)); + } + break; + case ')': + if (!num.equals("")) { + stack.push(String.valueOf(num)); + num = ""; + } + int sum = 0; + int prev = 0; // maintain a prev value inorder to handle minus '-' + while (!stack.isEmpty()) { + String top = stack.pop(); + if (top.equals("-")) { + sum -= (prev * 2); + prev = 0; + } else if (top.equals("+")) { + // ignore + } else if (top.equals("(")) { + stack.push(String.valueOf(sum)); + break; + } else { + sum += Integer.parseInt(top); + prev = Integer.parseInt(top); } - } - return Integer.parseInt(stack.peek()); + } + break; + default: + num += String.valueOf(c); + break; + } } + return Integer.parseInt(stack.peek()); + } } diff --git a/problems/src/stack/DecodeString.java b/problems/src/stack/DecodeString.java index e87eccb7..39d021cc 100644 --- a/problems/src/stack/DecodeString.java +++ b/problems/src/stack/DecodeString.java @@ -1,68 +1,68 @@ package stack; import java.util.Stack; + /** - * Created by gouthamvidyapradhan on 12/04/2018. - * Given an encoded string, return it's decoded string. - *

- * The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated - * exactly k times. Note that k is guaranteed to be a positive integer. - *

- * You may assume that the input string is always valid; No extra white spaces, square brackets are well-formed, etc. - *

- * Furthermore, you may assume that the original data does not contain any digits and that digits are only for those - * repeat numbers, k. For example, there won't be input like 3a or 2[4]. - *

- * Examples: - *

- * s = "3[a]2[bc]", return "aaabcbc". - * s = "3[a2[c]]", return "accaccacc". - * s = "2[abc]3[cd]ef", return "abcabccdcdcdef". + * Created by gouthamvidyapradhan on 12/04/2018. Given an encoded string, return it's decoded + * string. + * + *

The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets + * is being repeated exactly k times. Note that k is guaranteed to be a positive integer. + * + *

You may assume that the input string is always valid; No extra white spaces, square brackets + * are well-formed, etc. + * + *

Furthermore, you may assume that the original data does not contain any digits and that digits + * are only for those repeat numbers, k. For example, there won't be input like 3a or 2[4]. + * + *

Examples: + * + *

s = "3[a]2[bc]", return "aaabcbc". s = "3[a2[c]]", return "accaccacc". s = "2[abc]3[cd]ef", + * return "abcabccdcdcdef". * - * Solution: Maintain a stack and push items when a character other than ] is encountered. When a character ] is - * encountered pop elements, build string and duplicate it. + *

Solution: Maintain a stack and push items when a character other than ] is encountered. When a + * character ] is encountered pop elements, build string and duplicate it. */ public class DecodeString { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new DecodeString().decodeString("100[leetcode]")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new DecodeString().decodeString("100[leetcode]")); + } - public String decodeString(String s) { - Stack stack = new Stack<>(); - for (int i = 0; i < s.length(); i++) { - if (s.charAt(i) == ']') { - StringBuilder stackBuff = new StringBuilder(); - while (stack.peek() != '[') { - stackBuff.append(stack.pop()); - } - stack.pop(); //pop '[' - String num = ""; - while (!stack.isEmpty() && !Character.isAlphabetic(stack.peek()) && stack.peek() != '[') { - num = stack.pop() + num; - } - String str = stackBuff.reverse().toString(); - StringBuilder stringMultiple = new StringBuilder(); - int N = Integer.parseInt(num); - while (N-- > 0) { - stringMultiple.append(str); - } - for (int j = 0; j < stringMultiple.length(); j++) { - stack.push(stringMultiple.charAt(j)); - } - } else stack.push(s.charAt(i)); + public String decodeString(String s) { + Stack stack = new Stack<>(); + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == ']') { + StringBuilder stackBuff = new StringBuilder(); + while (stack.peek() != '[') { + stackBuff.append(stack.pop()); + } + stack.pop(); // pop '[' + String num = ""; + while (!stack.isEmpty() && !Character.isAlphabetic(stack.peek()) && stack.peek() != '[') { + num = stack.pop() + num; + } + String str = stackBuff.reverse().toString(); + StringBuilder stringMultiple = new StringBuilder(); + int N = Integer.parseInt(num); + while (N-- > 0) { + stringMultiple.append(str); } - StringBuilder result = new StringBuilder(); - while (!stack.isEmpty()) { - result.append(stack.pop()); + for (int j = 0; j < stringMultiple.length(); j++) { + stack.push(stringMultiple.charAt(j)); } - return result.reverse().toString(); + } else stack.push(s.charAt(i)); } - + StringBuilder result = new StringBuilder(); + while (!stack.isEmpty()) { + result.append(stack.pop()); + } + return result.reverse().toString(); + } } diff --git a/problems/src/stack/ExclusiveTimeOfFunctions.java b/problems/src/stack/ExclusiveTimeOfFunctions.java index 23b27d24..bf0f8cec 100644 --- a/problems/src/stack/ExclusiveTimeOfFunctions.java +++ b/problems/src/stack/ExclusiveTimeOfFunctions.java @@ -6,96 +6,87 @@ import java.util.Stack; /** - * Created by gouthamvidyapradhan on 20/01/2018. - * Given the running logs of n functions that are executed in a nonpreemptive single threaded CPU, find the exclusive - * time of these functions. - - Each function has a unique id, start from 0 to n-1. A function may be called recursively or by another function. - - A log is a string has this format : function_id:start_or_end:timestamp. For example, "0:start:0" means function 0 - starts from the very beginning of time 0. "0:end:0" means function 0 ends to the very end of time 0. - - Exclusive time of a function is defined as the time spent within this function, the time spent by calling other - functions should not be considered as this function's exclusive time. You should return the exclusive time of each - function sorted by their function id. - - Example 1: - Input: - n = 2 - logs = - ["0:start:0", - "1:start:2", - "1:end:5", - "0:end:6"] - Output:[3, 4] - Explanation: - Function 0 starts at time 0, then it executes 2 units of time and reaches the end of time 1. - Now function 0 calls function 1, function 1 starts at time 2, executes 4 units of time and end at time 5. - Function 0 is running again at time 6, and also end at the time 6, thus executes 1 unit of time. - So function 0 totally execute 2 + 1 = 3 units of time, and function 1 totally execute 4 units of time. - Note: - Input logs will be sorted by timestamp, NOT log id. - Your output should be sorted by function id, which means the 0th element of your output corresponds to the - exclusive time of function 0. - Two functions won't start or end at the same time. - Functions could be called recursively, and will always end. - 1 <= n <= 100 - - Solution: Use a stack to store the logs and update time. - + * Created by gouthamvidyapradhan on 20/01/2018. Given the running logs of n functions that are + * executed in a nonpreemptive single threaded CPU, find the exclusive time of these functions. + * + *

Each function has a unique id, start from 0 to n-1. A function may be called recursively or by + * another function. + * + *

A log is a string has this format : function_id:start_or_end:timestamp. For example, + * "0:start:0" means function 0 starts from the very beginning of time 0. "0:end:0" means function 0 + * ends to the very end of time 0. + * + *

Exclusive time of a function is defined as the time spent within this function, the time spent + * by calling other functions should not be considered as this function's exclusive time. You should + * return the exclusive time of each function sorted by their function id. + * + *

Example 1: Input: n = 2 logs = ["0:start:0", "1:start:2", "1:end:5", "0:end:6"] Output:[3, 4] + * Explanation: Function 0 starts at time 0, then it executes 2 units of time and reaches the end of + * time 1. Now function 0 calls function 1, function 1 starts at time 2, executes 4 units of time + * and end at time 5. Function 0 is running again at time 6, and also end at the time 6, thus + * executes 1 unit of time. So function 0 totally execute 2 + 1 = 3 units of time, and function 1 + * totally execute 4 units of time. Note: Input logs will be sorted by timestamp, NOT log id. Your + * output should be sorted by function id, which means the 0th element of your output corresponds to + * the exclusive time of function 0. Two functions won't start or end at the same time. Functions + * could be called recursively, and will always end. 1 <= n <= 100 + * + *

Solution: Use a stack to store the logs and update time. */ public class ExclusiveTimeOfFunctions { - class Log{ - int funId, time; - String fun; - Log(int funId, String fun, int time){ - this.funId = funId; - this.fun = fun; - this.time = time; - } - } + class Log { + int funId, time; + String fun; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] N = new ExclusiveTimeOfFunctions().exclusiveTime(2, Arrays.asList("0:start:0", "1:start:2", "1:end:5", - "0:end:6")); - Arrays.stream(N).forEach(System.out::println); + Log(int funId, String fun, int time) { + this.funId = funId; + this.fun = fun; + this.time = time; } + } - public int[] exclusiveTime(int n, List logs) { - int[] N = new int[n]; - List functions = new ArrayList<>(); - for(String s : logs){ - String[] parts = s.split(":"); - functions.add(new Log(Integer.parseInt(parts[0]), parts[1], Integer.parseInt(parts[2]))); - } - Stack stack = new Stack<>(); - stack.push(functions.get(0)); - for(int i = 1, l = functions.size(); i < l; i ++){ - Log next = functions.get(i); - if(stack.isEmpty()){ - stack.push(next); - continue; - } - Log curr = stack.peek(); - if(next.fun.equals("end")){ - N[curr.funId] += (next.time - curr.time + 1); - stack.pop(); //since the end has reached, remove from stack - if(!stack.isEmpty()){ - stack.peek().time = next.time + 1; //IMPORTANT: update the time of the old function to a new start - // time - } - } else { - stack.push(next); - N[curr.funId] += (next.time - curr.time); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] N = + new ExclusiveTimeOfFunctions() + .exclusiveTime(2, Arrays.asList("0:start:0", "1:start:2", "1:end:5", "0:end:6")); + Arrays.stream(N).forEach(System.out::println); + } + + public int[] exclusiveTime(int n, List logs) { + int[] N = new int[n]; + List functions = new ArrayList<>(); + for (String s : logs) { + String[] parts = s.split(":"); + functions.add(new Log(Integer.parseInt(parts[0]), parts[1], Integer.parseInt(parts[2]))); + } + Stack stack = new Stack<>(); + stack.push(functions.get(0)); + for (int i = 1, l = functions.size(); i < l; i++) { + Log next = functions.get(i); + if (stack.isEmpty()) { + stack.push(next); + continue; + } + Log curr = stack.peek(); + if (next.fun.equals("end")) { + N[curr.funId] += (next.time - curr.time + 1); + stack.pop(); // since the end has reached, remove from stack + if (!stack.isEmpty()) { + stack.peek().time = + next.time + 1; // IMPORTANT: update the time of the old function to a new start + // time } - return N; + } else { + stack.push(next); + N[curr.funId] += (next.time - curr.time); + } } - + return N; + } } diff --git a/problems/src/stack/LargestRectangleInHistogram.java b/problems/src/stack/LargestRectangleInHistogram.java index 985b2e6e..aff156a4 100644 --- a/problems/src/stack/LargestRectangleInHistogram.java +++ b/problems/src/stack/LargestRectangleInHistogram.java @@ -3,49 +3,51 @@ import java.util.Stack; /** - * Created by gouthamvidyapradhan on 20/06/2017. - * Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram. - *

- * For example, - * Given heights = [2,1,5,6,2,3], - * return 10. (min of index 2 and 3 multiplied by two) - *

- * Solution O(N): - *

- * 1) Create an empty stack. - *

- * 2) Start from first bar, and do following for every bar ‘hist[i]’ where ‘i’ varies from 0 to n-1. - * a) If stack is empty or hist[i] is higher than the bar at top of stack, then push ‘i’ to stack. - * b) If this bar is smaller than the top of stack, then keep removing the top of stack while top of the stack is greater. Let the removed bar be hist[tp]. - * Calculate area of rectangle with hist[tp] as smallest bar. For hist[tp], the ‘left index’ is previous (previous to tp) item in stack and ‘right index’ is ‘i’ (current index). - *

- * 3) If the stack is not empty, then one by one remove all bars from stack and do step 2.b for every removed bar. + * Created by gouthamvidyapradhan on 20/06/2017. Given n non-negative integers representing the + * histogram's bar height where the width of each bar is 1, find the area of largest rectangle in + * the histogram. + * + *

For example, Given heights = [2,1,5,6,2,3], return 10. (min of index 2 and 3 multiplied by + * two) + * + *

Solution O(N): + * + *

1) Create an empty stack. + * + *

2) Start from first bar, and do following for every bar ‘hist[i]’ where ‘i’ varies from 0 to + * n-1. a) If stack is empty or hist[i] is higher than the bar at top of stack, then push ‘i’ to + * stack. b) If this bar is smaller than the top of stack, then keep removing the top of stack while + * top of the stack is greater. Let the removed bar be hist[tp]. Calculate area of rectangle with + * hist[tp] as smallest bar. For hist[tp], the ‘left index’ is previous (previous to tp) item in + * stack and ‘right index’ is ‘i’ (current index). + * + *

3) If the stack is not empty, then one by one remove all bars from stack and do step 2.b for + * every removed bar. */ public class LargestRectangleInHistogram { - public static void main(String[] args) throws Exception { - int[] A = {2, 3}; - System.out.println(new LargestRectangleInHistogram().largestRectangleArea(A)); - } + public static void main(String[] args) throws Exception { + int[] A = {2, 3}; + System.out.println(new LargestRectangleInHistogram().largestRectangleArea(A)); + } - public int largestRectangleArea(int[] heights) { - if (heights.length == 0) return 0; - int maxArea = Integer.MIN_VALUE; - Stack stack = new Stack<>(); - int i = 0; - for (; i < heights.length; i++) { - while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) { - int top = stack.pop(); - int base = stack.isEmpty() ? i : i - stack.peek() - 1; - maxArea = Math.max(maxArea, base * heights[top]); - } - stack.push(i); - } - while (!stack.isEmpty()) { - int top = stack.pop(); - int base = stack.isEmpty() ? i : i - stack.peek() - 1; - maxArea = Math.max(maxArea, base * heights[top]); - } - return maxArea; + public int largestRectangleArea(int[] heights) { + if (heights.length == 0) return 0; + int maxArea = Integer.MIN_VALUE; + Stack stack = new Stack<>(); + int i = 0; + for (; i < heights.length; i++) { + while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) { + int top = stack.pop(); + int base = stack.isEmpty() ? i : i - stack.peek() - 1; + maxArea = Math.max(maxArea, base * heights[top]); + } + stack.push(i); } - + while (!stack.isEmpty()) { + int top = stack.pop(); + int base = stack.isEmpty() ? i : i - stack.peek() - 1; + maxArea = Math.max(maxArea, base * heights[top]); + } + return maxArea; + } } diff --git a/problems/src/stack/LongestValidParentheses.java b/problems/src/stack/LongestValidParentheses.java index d4d3ae0a..f4b6bb38 100644 --- a/problems/src/stack/LongestValidParentheses.java +++ b/problems/src/stack/LongestValidParentheses.java @@ -3,73 +3,67 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 08/07/2018. - * Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) - * parentheses substring. - - Example 1: - - Input: "(()" - Output: 2 - Explanation: The longest valid parentheses substring is "()" - Example 2: - - Input: ")()())" - Output: 4 - Explanation: The longest valid parentheses substring is "()()" - - Solution: O(N) Iterate through each of the parentheses and if '(' is encountered push it to stack else check the top - of the stack to see if there is a matching parentheses, if yes pop it and then take the length (currIndex - index at - top of the stack). Maintain a max length and return this as the answer. + * Created by gouthamvidyapradhan on 08/07/2018. Given a string containing just the characters '(' + * and ')', find the length of the longest valid (well-formed) parentheses substring. + * + *

Example 1: + * + *

Input: "(()" Output: 2 Explanation: The longest valid parentheses substring is "()" Example 2: + * + *

Input: ")()())" Output: 4 Explanation: The longest valid parentheses substring is "()()" + * + *

Solution: O(N) Iterate through each of the parentheses and if '(' is encountered push it to + * stack else check the top of the stack to see if there is a matching parentheses, if yes pop it + * and then take the length (currIndex - index at top of the stack). Maintain a max length and + * return this as the answer. */ public class LongestValidParentheses { - private class Node{ - char c; - int i; - Node(char c, int i){ - this.c = c; - this.i = i; - } - } + private class Node { + char c; + int i; - /** - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new LongestValidParentheses().longestValidParentheses("((()()(((())))))")); + Node(char c, int i) { + this.c = c; + this.i = i; } + } + + /** + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new LongestValidParentheses().longestValidParentheses("((()()(((())))))")); + } - public int longestValidParentheses(String s) { - Stack stack = new Stack<>(); - int max = 0; - for(int i = 0, l = s.length(); i < l; i ++){ - char c = s.charAt(i); - switch (c){ - case '(': - stack.push(new Node(c, i)); - break; + public int longestValidParentheses(String s) { + Stack stack = new Stack<>(); + int max = 0; + for (int i = 0, l = s.length(); i < l; i++) { + char c = s.charAt(i); + switch (c) { + case '(': + stack.push(new Node(c, i)); + break; - case ')': - if(!stack.isEmpty()){ - if(stack.peek().c == '('){ - stack.pop(); - if(stack.isEmpty()){ - max = Math.max(max, i + 1); - } else { - max = Math.max(max, i - stack.peek().i); - } - } else{ - stack.push(new Node(c, i)); - } - } else{ - stack.push(new Node(c, i)); - } + case ')': + if (!stack.isEmpty()) { + if (stack.peek().c == '(') { + stack.pop(); + if (stack.isEmpty()) { + max = Math.max(max, i + 1); + } else { + max = Math.max(max, i - stack.peek().i); + } + } else { + stack.push(new Node(c, i)); } - } - return max; + } else { + stack.push(new Node(c, i)); + } + } } - + return max; + } } diff --git a/problems/src/stack/MaximalRectangle.java b/problems/src/stack/MaximalRectangle.java index 7840e5ae..2a710592 100644 --- a/problems/src/stack/MaximalRectangle.java +++ b/problems/src/stack/MaximalRectangle.java @@ -5,76 +5,79 @@ /** * Created by gouthamvidyapradhan on 29/11/2017. * - * Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area. - - For example, given the following matrix: - - 1 0 1 0 0 - 1 0 1 1 1 - 1 1 1 1 1 - 1 0 0 1 0 - Return 6. - - Solution O(n * m): This problem is similar to LargestRectangleInHistogram. - Run the largest rectangle in histogram algorithm for each row. + *

Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only + * 1's and return its area. + * + *

For example, given the following matrix: + * + *

1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 Return 6. + * + *

Solution O(n * m): This problem is similar to LargestRectangleInHistogram. Run the largest + * rectangle in histogram algorithm for each row. */ public class MaximalRectangle { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - char[][] matrix = {{'1','0','1','0','0'}, {'1', '0', '1', '1', '1'}, {'1', '1', '1', '1', '1'}, - {'1', '0', '0', '1', '0'}}; - System.out.println(new MaximalRectangle().maximalRectangle(matrix)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + char[][] matrix = { + {'1', '0', '1', '0', '0'}, + {'1', '0', '1', '1', '1'}, + {'1', '1', '1', '1', '1'}, + {'1', '0', '0', '1', '0'} + }; + System.out.println(new MaximalRectangle().maximalRectangle(matrix)); + } - public int maximalRectangle(char[][] matrix) { - if(matrix.length == 0 || matrix[0].length == 0) return 0; - int[] A = new int[matrix[0].length]; - int max = Integer.MIN_VALUE; - for(int i = 0; i < matrix.length; i ++){ - for(int j = 0; j < matrix[0].length; j++){ - if(matrix[i][j] == '1'){ - if(i > 0 && matrix[i - 1][j] == '1'){ - A[j] = A[j] + 1; - } else{ - A[j] = 1; - } - } else { - A[j] = 0; - } - } - //calculate max rectangle for this row - max = Math.max(max, getMaxRectangle(A)); + public int maximalRectangle(char[][] matrix) { + if (matrix.length == 0 || matrix[0].length == 0) return 0; + int[] A = new int[matrix[0].length]; + int max = Integer.MIN_VALUE; + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix[0].length; j++) { + if (matrix[i][j] == '1') { + if (i > 0 && matrix[i - 1][j] == '1') { + A[j] = A[j] + 1; + } else { + A[j] = 1; + } + } else { + A[j] = 0; } - return max; + } + // calculate max rectangle for this row + max = Math.max(max, getMaxRectangle(A)); } + return max; + } - /** - * Get max rectangle algorithm similar to max rectangle in histogram - * @param heights - * @return - */ - private int getMaxRectangle(int[] heights){ - int maxArea = Integer.MIN_VALUE; - Stack stack = new Stack<>(); - int i = 0; - for (; i < heights.length; i++) { - while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) { - int top = stack.pop(); - int base = stack.isEmpty() ? i : i - stack.peek() - 1; - maxArea = Math.max(maxArea, base * heights[top]); - } - stack.push(i); - } - while (!stack.isEmpty()) { - int top = stack.pop(); - int base = stack.isEmpty() ? i : i - stack.peek() - 1; - maxArea = Math.max(maxArea, base * heights[top]); - } - return maxArea; + /** + * Get max rectangle algorithm similar to max rectangle in histogram + * + * @param heights + * @return + */ + private int getMaxRectangle(int[] heights) { + int maxArea = Integer.MIN_VALUE; + Stack stack = new Stack<>(); + int i = 0; + for (; i < heights.length; i++) { + while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) { + int top = stack.pop(); + int base = stack.isEmpty() ? i : i - stack.peek() - 1; + maxArea = Math.max(maxArea, base * heights[top]); + } + stack.push(i); + } + while (!stack.isEmpty()) { + int top = stack.pop(); + int base = stack.isEmpty() ? i : i - stack.peek() - 1; + maxArea = Math.max(maxArea, base * heights[top]); } + return maxArea; + } } diff --git a/problems/src/stack/MinStack.java b/problems/src/stack/MinStack.java index 5cd66d68..512846f5 100644 --- a/problems/src/stack/MinStack.java +++ b/problems/src/stack/MinStack.java @@ -3,77 +3,66 @@ import java.util.Stack; /** - * Created by gouthamvidyapradhan on 08/03/2017. - * Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. - *

- * push(x) -- Push element x onto stack. - * pop() -- Removes the element on top of the stack. - * top() -- Get the top element. - * getMin() -- Retrieve the minimum element in the stack. - * Example: - * MinStack minStack = new MinStack(); - * minStack.push(-2); - * minStack.push(0); - * minStack.push(-3); - * minStack.getMin(); --> Returns -3. - * minStack.pop(); - * minStack.top(); --> Returns 0. - * minStack.getMin(); --> Returns -2. + * Created by gouthamvidyapradhan on 08/03/2017. Design a stack that supports push, pop, top, and + * retrieving the minimum element in constant time. + * + *

push(x) -- Push element x onto stack. pop() -- Removes the element on top of the stack. top() + * -- Get the top element. getMin() -- Retrieve the minimum element in the stack. Example: MinStack + * minStack = new MinStack(); minStack.push(-2); minStack.push(0); minStack.push(-3); + * minStack.getMin(); --> Returns -3. minStack.pop(); minStack.top(); --> Returns 0. + * minStack.getMin(); --> Returns -2. */ public class MinStack { - class Node { - int value, min; + class Node { + int value, min; - Node(int value, int min) { - this.value = value; - this.min = min; - } + Node(int value, int min) { + this.value = value; + this.min = min; } + } - private Stack stack = new Stack<>(); + private Stack stack = new Stack<>(); - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - MinStack minStack = new MinStack(); - minStack.push(-2); - minStack.push(0); - minStack.push(-3); - System.out.println(minStack.getMin()); - minStack.pop(); - System.out.println(minStack.top()); - System.out.println(minStack.getMin()); - } - - public MinStack() { + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + MinStack minStack = new MinStack(); + minStack.push(-2); + minStack.push(0); + minStack.push(-3); + System.out.println(minStack.getMin()); + minStack.pop(); + System.out.println(minStack.top()); + System.out.println(minStack.getMin()); + } - } + public MinStack() {} - public void push(int x) { - Node node; - if (!stack.isEmpty()) { - Node top = stack.peek(); - node = new Node(x, Math.min(top.min, x)); - } else { - node = new Node(x, x); - } - stack.push(node); + public void push(int x) { + Node node; + if (!stack.isEmpty()) { + Node top = stack.peek(); + node = new Node(x, Math.min(top.min, x)); + } else { + node = new Node(x, x); } + stack.push(node); + } - public void pop() { - stack.pop(); - } + public void pop() { + stack.pop(); + } - public int top() { - return stack.peek().value; - } - - public int getMin() { - return stack.peek().min; - } + public int top() { + return stack.peek().value; + } + public int getMin() { + return stack.peek().min; + } } diff --git a/problems/src/stack/MyQueue.java b/problems/src/stack/MyQueue.java index 0b29d36e..a5547f48 100644 --- a/problems/src/stack/MyQueue.java +++ b/problems/src/stack/MyQueue.java @@ -3,85 +3,73 @@ import java.util.Stack; /** - * Created by gouthamvidyapradhan on 29/07/2017. - * Implement the following operations of a queue using stacks. - *

- * push(x) -- Push element x to the back of queue. - * pop() -- Removes the element from in front of queue. - * peek() -- Get the front element. - * empty() -- Return whether the queue is empty. - *

- * Notes: - * You must use only standard operations of a stack -- which means only push to top, peek/pop from top, size, and is empty operations are valid. - * Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack. - * You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue). + * Created by gouthamvidyapradhan on 29/07/2017. Implement the following operations of a queue using + * stacks. + * + *

push(x) -- Push element x to the back of queue. pop() -- Removes the element from in front of + * queue. peek() -- Get the front element. empty() -- Return whether the queue is empty. + * + *

Notes: You must use only standard operations of a stack -- which means only push to top, + * peek/pop from top, size, and is empty operations are valid. Depending on your language, stack may + * not be supported natively. You may simulate a stack by using a list or deque (double-ended + * queue), as long as you use only standard operations of a stack. You may assume that all + * operations are valid (for example, no pop or peek operations will be called on an empty queue). */ public class MyQueue { - private Stack stack; + private Stack stack; - public static void main(String[] args) throws Exception { - MyQueue myQueue = new MyQueue(); - myQueue.push(5); - myQueue.push(12); - myQueue.push(7); - myQueue.push(9); - System.out.println(myQueue.peek()); - System.out.println(myQueue.pop()); - myQueue.push(56); - myQueue.push(53); - System.out.println(myQueue.pop()); - } + public static void main(String[] args) throws Exception { + MyQueue myQueue = new MyQueue(); + myQueue.push(5); + myQueue.push(12); + myQueue.push(7); + myQueue.push(9); + System.out.println(myQueue.peek()); + System.out.println(myQueue.pop()); + myQueue.push(56); + myQueue.push(53); + System.out.println(myQueue.pop()); + } - /** - * Initialize your data structure here. - */ - public MyQueue() { - stack = new Stack<>(); - } + /** Initialize your data structure here. */ + public MyQueue() { + stack = new Stack<>(); + } - /** - * Push element x to the back of queue. - */ - public void push(int x) { - stack.push(x); - } + /** Push element x to the back of queue. */ + public void push(int x) { + stack.push(x); + } - /** - * Removes the element from in front of queue and returns that element. - */ - public int pop() { - Stack auxStack = new Stack<>(); - while (!stack.isEmpty()) { - auxStack.push(stack.pop()); - } - int result = auxStack.pop(); - while (!auxStack.isEmpty()) { - stack.push(auxStack.pop()); - } - return result; + /** Removes the element from in front of queue and returns that element. */ + public int pop() { + Stack auxStack = new Stack<>(); + while (!stack.isEmpty()) { + auxStack.push(stack.pop()); } - - /** - * Get the front element. - */ - public int peek() { - Stack auxStack = new Stack<>(); - while (!stack.isEmpty()) { - auxStack.push(stack.pop()); - } - int result = auxStack.peek(); - while (!auxStack.isEmpty()) { - stack.push(auxStack.pop()); - } - return result; + int result = auxStack.pop(); + while (!auxStack.isEmpty()) { + stack.push(auxStack.pop()); } + return result; + } - /** - * Returns whether the queue is empty. - */ - public boolean empty() { - return stack.isEmpty(); + /** Get the front element. */ + public int peek() { + Stack auxStack = new Stack<>(); + while (!stack.isEmpty()) { + auxStack.push(stack.pop()); + } + int result = auxStack.peek(); + while (!auxStack.isEmpty()) { + stack.push(auxStack.pop()); } + return result; + } + /** Returns whether the queue is empty. */ + public boolean empty() { + return stack.isEmpty(); + } } diff --git a/problems/src/stack/ValidParentheses.java b/problems/src/stack/ValidParentheses.java index d3a6213a..d9d77afd 100644 --- a/problems/src/stack/ValidParentheses.java +++ b/problems/src/stack/ValidParentheses.java @@ -5,49 +5,50 @@ import java.util.Stack; /** - * Created by gouthamvidyapradhan on 25/02/2017. - * Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. - *

- * The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not. + * Created by gouthamvidyapradhan on 25/02/2017. Given a string containing just the characters '(', + * ')', '{', '}', '[' and ']', determine if the input string is valid. + * + *

The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and + * "([)]" are not. */ public class ValidParentheses { - public static void main(String[] args) { - System.out.println(hasBalancedBrackets("(h[e")); - } - - private static Map MAP = new HashMap<>(); - - // METHOD SIGNATURE BEGINS, THIS METHOD IS REQUIRED - public static int hasBalancedBrackets(String str) { - if (str == null) return 1; - - MAP.put(')', '('); - MAP.put('}', '{'); - MAP.put('>', '<'); - MAP.put(']', '['); - - Stack stack = new Stack<>(); - for (int i = 0, l = str.length(); i < l; i++) { - switch (str.charAt(i)) { - case '(': - case '{': - case '[': - case '<': - stack.push(str.charAt(i)); - break; - - case ')': - case '}': - case ']': - case '>': - if (stack.isEmpty()) return 0; - char top = stack.pop(); - if (top != MAP.get(str.charAt(i))) return 0; - break; - - default: //ignore - } - } - return stack.isEmpty() ? 1 : 0; + public static void main(String[] args) { + System.out.println(hasBalancedBrackets("(h[e")); + } + + private static Map MAP = new HashMap<>(); + + // METHOD SIGNATURE BEGINS, THIS METHOD IS REQUIRED + public static int hasBalancedBrackets(String str) { + if (str == null) return 1; + + MAP.put(')', '('); + MAP.put('}', '{'); + MAP.put('>', '<'); + MAP.put(']', '['); + + Stack stack = new Stack<>(); + for (int i = 0, l = str.length(); i < l; i++) { + switch (str.charAt(i)) { + case '(': + case '{': + case '[': + case '<': + stack.push(str.charAt(i)); + break; + + case ')': + case '}': + case ']': + case '>': + if (stack.isEmpty()) return 0; + char top = stack.pop(); + if (top != MAP.get(str.charAt(i))) return 0; + break; + + default: // ignore + } } + return stack.isEmpty() ? 1 : 0; + } } diff --git a/problems/src/string/AddBinary.java b/problems/src/string/AddBinary.java index 04f823e1..9f813def 100644 --- a/problems/src/string/AddBinary.java +++ b/problems/src/string/AddBinary.java @@ -3,48 +3,46 @@ /** * Created by gouthamvidyapradhan on 25/11/2017. * - * Given two binary strings, return their sum (also a binary string). - - For example, - a = "11" - b = "1" - Return "100". + *

Given two binary strings, return their sum (also a binary string). + * + *

For example, a = "11" b = "1" Return "100". */ public class AddBinary { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - System.out.println(new AddBinary().addBinary("000001010000101001", "0")); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + System.out.println(new AddBinary().addBinary("000001010000101001", "0")); + } - public String addBinary(String a, String b) { - if(a.length() > b.length()){ - return calculate(a, b); - } else return calculate(b, a); - } + public String addBinary(String a, String b) { + if (a.length() > b.length()) { + return calculate(a, b); + } else return calculate(b, a); + } - /** - * Calculate sum - * @param a length of a should always be greater or equal to b - * @param b length of b should always be smaller of equal to a - * @return - */ - private String calculate(String a, String b){ - int carry = 0; - int d = a.length() - b.length(); - StringBuilder sb = new StringBuilder(); - for(int i = a.length() - 1; i >= 0; i --){ - int first = Integer.parseInt(String.valueOf(a.charAt(i))); - int second = i - d >= 0 ? Integer.parseInt(String.valueOf(b.charAt(i - d))) : 0; - int sum = (first + second + carry); - carry = sum / 2; - sb.append(sum % 2); - } - if(carry != 0) - sb.append(carry); - return sb.reverse().toString(); + /** + * Calculate sum + * + * @param a length of a should always be greater or equal to b + * @param b length of b should always be smaller of equal to a + * @return + */ + private String calculate(String a, String b) { + int carry = 0; + int d = a.length() - b.length(); + StringBuilder sb = new StringBuilder(); + for (int i = a.length() - 1; i >= 0; i--) { + int first = Integer.parseInt(String.valueOf(a.charAt(i))); + int second = i - d >= 0 ? Integer.parseInt(String.valueOf(b.charAt(i - d))) : 0; + int sum = (first + second + carry); + carry = sum / 2; + sb.append(sum % 2); } + if (carry != 0) sb.append(carry); + return sb.reverse().toString(); + } } diff --git a/problems/src/string/CompareVersionNumbers.java b/problems/src/string/CompareVersionNumbers.java index 82419240..bffac314 100644 --- a/problems/src/string/CompareVersionNumbers.java +++ b/problems/src/string/CompareVersionNumbers.java @@ -3,52 +3,47 @@ import java.util.StringTokenizer; /** - * Created by pradhang on 7/11/2017. - * Compare two version numbers version1 and version2. - * If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0. - *

- * You may assume that the version strings are non-empty and contain only digits and the . character. - * The . character does not represent a decimal point and is used to separate number sequences. - * For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision. - *

- * Here is an example of version numbers ordering: - *

- * 0.1 < 1.1 < 1.2 < 13.37 + * Created by pradhang on 7/11/2017. Compare two version numbers version1 and version2. If version1 + * > version2 return 1, if version1 < version2 return -1, otherwise return 0. + * + *

You may assume that the version strings are non-empty and contain only digits and the . + * character. The . character does not represent a decimal point and is used to separate number + * sequences. For instance, 2.5 is not "two and a half" or "half way to version three", it is the + * fifth second-level revision of the second first-level revision. + * + *

Here is an example of version numbers ordering: + * + *

0.1 < 1.1 < 1.2 < 13.37 */ public class CompareVersionNumbers { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new CompareVersionNumbers().compareVersion("1.11.1", "1.11")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new CompareVersionNumbers().compareVersion("1.11.1", "1.11")); + } - public int compareVersion(String version1, String version2) { - StringTokenizer st1 = new StringTokenizer(version1, "."); - StringTokenizer st2 = new StringTokenizer(version2, "."); - while (st1.hasMoreTokens() & st2.hasMoreTokens()) { - int token1 = Integer.parseInt(st1.nextToken()); - int token2 = Integer.parseInt(st2.nextToken()); - if (token1 > token2) - return 1; - else if (token2 > token1) - return -1; - } - if (st1.countTokens() > st2.countTokens()) { - while (st1.hasMoreTokens()) { - if (Integer.parseInt(st1.nextToken()) > 0) - return 1; - } - } else if (st2.countTokens() > st1.countTokens()) { - while (st2.hasMoreTokens()) { - if (Integer.parseInt(st2.nextToken()) > 0) - return -1; - } - } - return 0; + public int compareVersion(String version1, String version2) { + StringTokenizer st1 = new StringTokenizer(version1, "."); + StringTokenizer st2 = new StringTokenizer(version2, "."); + while (st1.hasMoreTokens() & st2.hasMoreTokens()) { + int token1 = Integer.parseInt(st1.nextToken()); + int token2 = Integer.parseInt(st2.nextToken()); + if (token1 > token2) return 1; + else if (token2 > token1) return -1; } - + if (st1.countTokens() > st2.countTokens()) { + while (st1.hasMoreTokens()) { + if (Integer.parseInt(st1.nextToken()) > 0) return 1; + } + } else if (st2.countTokens() > st1.countTokens()) { + while (st2.hasMoreTokens()) { + if (Integer.parseInt(st2.nextToken()) > 0) return -1; + } + } + return 0; + } } diff --git a/problems/src/string/CountAndSay.java b/problems/src/string/CountAndSay.java index 1ed7e39a..55536426 100644 --- a/problems/src/string/CountAndSay.java +++ b/problems/src/string/CountAndSay.java @@ -3,58 +3,49 @@ /** * Created by gouthamvidyapradhan on 20/01/2018. * - * The count-and-say sequence is the sequence of integers with the first five terms as following: - - 1. 1 - 2. 11 - 3. 21 - 4. 1211 - 5. 111221 - 1 is read off as "one 1" or 11. - 11 is read off as "two 1s" or 21. - 21 is read off as "one 2, then one 1" or 1211. - Given an integer n, generate the nth term of the count-and-say sequence. - - Note: Each term of the sequence of integers will be represented as a string. - - Example 1: - - Input: 1 - Output: "1" - Example 2: - - Input: 4 - Output: "1211" - + *

The count-and-say sequence is the sequence of integers with the first five terms as following: + * + *

1. 1 2. 11 3. 21 4. 1211 5. 111221 1 is read off as "one 1" or 11. 11 is read off as "two 1s" + * or 21. 21 is read off as "one 2, then one 1" or 1211. Given an integer n, generate the nth term + * of the count-and-say sequence. + * + *

Note: Each term of the sequence of integers will be represented as a string. + * + *

Example 1: + * + *

Input: 1 Output: "1" Example 2: + * + *

Input: 4 Output: "1211" */ public class CountAndSay { - /** - * Main method - * @param args - */ - public static void main(String[] args) throws Exception { - System.out.println(new CountAndSay().countAndSay(4)); - } - - public String countAndSay(int n) { - String result = "1"; - for(int i = 1; i < n; i ++){ - int count = 1; - char num = result.charAt(0); - StringBuilder temp = new StringBuilder(); - for(int j = 1, l = result.length(); j < l; j++){ - if(result.charAt(j) == num){ - count++; - } else{ - temp = temp.append(String.valueOf(count)).append(String.valueOf(num)); - num = result.charAt(j); - count = 1; - } - } - temp = temp.append(String.valueOf(count)).append(String.valueOf(num)); - result = temp.toString(); + /** + * Main method + * + * @param args + */ + public static void main(String[] args) throws Exception { + System.out.println(new CountAndSay().countAndSay(4)); + } + + public String countAndSay(int n) { + String result = "1"; + for (int i = 1; i < n; i++) { + int count = 1; + char num = result.charAt(0); + StringBuilder temp = new StringBuilder(); + for (int j = 1, l = result.length(); j < l; j++) { + if (result.charAt(j) == num) { + count++; + } else { + temp = temp.append(String.valueOf(count)).append(String.valueOf(num)); + num = result.charAt(j); + count = 1; } - return result; + } + temp = temp.append(String.valueOf(count)).append(String.valueOf(num)); + result = temp.toString(); } + return result; + } } diff --git a/problems/src/string/ExcelSheetColumnNumber.java b/problems/src/string/ExcelSheetColumnNumber.java index 9431f510..889aa710 100644 --- a/problems/src/string/ExcelSheetColumnNumber.java +++ b/problems/src/string/ExcelSheetColumnNumber.java @@ -1,36 +1,29 @@ package string; /** - * Created by gouthamvidyapradhan on 07/07/2017. - * Given a column title as appear in an Excel sheet, return its corresponding column number. - *

- * For example: - *

- * A -> 1 - * B -> 2 - * C -> 3 - * ... - * Z -> 26 - * AA -> 27 - * AB -> 28 + * Created by gouthamvidyapradhan on 07/07/2017. Given a column title as appear in an Excel sheet, + * return its corresponding column number. + * + *

For example: + * + *

A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -> 28 */ public class ExcelSheetColumnNumber { - String CONST = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + String CONST = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - public static void main(String[] args) throws Exception { - System.out.println(new ExcelSheetColumnNumber().titleToNumber("AAB")); - } + public static void main(String[] args) throws Exception { + System.out.println(new ExcelSheetColumnNumber().titleToNumber("AAB")); + } - public int titleToNumber(String s) { - int total = 0; - int j = 0; - for (int i = s.length() - 1; i >= 0; i--) { - char c = s.charAt(i); - int pos = CONST.indexOf(c) + 1; - int pow = (int) Math.pow(26, j++); - total += (pow * pos); - } - return total; + public int titleToNumber(String s) { + int total = 0; + int j = 0; + for (int i = s.length() - 1; i >= 0; i--) { + char c = s.charAt(i); + int pos = CONST.indexOf(c) + 1; + int pow = (int) Math.pow(26, j++); + total += (pow * pos); } - + return total; + } } diff --git a/problems/src/string/FindTheClosestPalindrome.java b/problems/src/string/FindTheClosestPalindrome.java index 1667d708..f9c3e096 100644 --- a/problems/src/string/FindTheClosestPalindrome.java +++ b/problems/src/string/FindTheClosestPalindrome.java @@ -1,121 +1,132 @@ package string; /** - * Created by gouthamvidyapradhan on 21/04/2018. - * Given an integer n, find the closest integer (not including itself), which is a palindrome. - - The 'closest' is defined as absolute difference minimized between two integers. - - Example 1: - Input: "123" - Output: "121" - Note: - The input n is a positive integer represented by string, whose length will not exceed 18. - If there is a tie, return the smaller one as answer. - - Solution O(N): General idea is to consider the first half of the string and make a new string by reversing the first - half of string. Concatenate the first_half and the new_string and return this as an answer. There are also - a lot of edge cases to be considered using this approach. -*/ + * Created by gouthamvidyapradhan on 21/04/2018. Given an integer n, find the closest integer (not + * including itself), which is a palindrome. + * + *

The 'closest' is defined as absolute difference minimized between two integers. + * + *

Example 1: Input: "123" Output: "121" Note: The input n is a positive integer represented by + * string, whose length will not exceed 18. If there is a tie, return the smaller one as answer. + * + *

Solution O(N): General idea is to consider the first half of the string and make a new string + * by reversing the first half of string. Concatenate the first_half and the new_string and return + * this as an answer. There are also a lot of edge cases to be considered using this approach. + */ public class FindTheClosestPalindrome { - public static void main(String[] args) throws Exception { - System.out.println(new FindTheClosestPalindrome().nearestPalindromic("1837722381")); - } + public static void main(String[] args) throws Exception { + System.out.println(new FindTheClosestPalindrome().nearestPalindromic("1837722381")); + } - public String nearestPalindromic(String n) { - if(n.length() == 1) return String.valueOf(Integer.parseInt(n) - 1); - String p1, p2; - String palindrome; - if(isPaliandrome(n)){ - String newFirstHalf; - if(n.length() % 2 == 0){ - String firstHalf = n.substring(0, n.length() / 2); - newFirstHalf = String.valueOf(Long.parseLong(firstHalf) - 1); - p1 = newFirstHalf + new StringBuilder(newFirstHalf).reverse(); - newFirstHalf = String.valueOf(Long.parseLong(firstHalf) + 1); - p2 = newFirstHalf + new StringBuilder(newFirstHalf).reverse(); - } else{ - String firstHalf = n.substring(0, n.length() / 2); - char middle = n.charAt(n.length() / 2); - if(middle == '0'){ - p1 = firstHalf + "1" + new StringBuilder(firstHalf).reverse(); - } else{ - p1 = firstHalf + (Integer.parseInt(String.valueOf(middle)) - 1) + new StringBuilder - (firstHalf).reverse(); - } - newFirstHalf = String.valueOf(Long.parseLong(firstHalf) + 1); - p2 = newFirstHalf + "0" + new StringBuilder(newFirstHalf).reverse(); - } - }else{ - String firstHalf = n.substring(0, n.length() / 2); - if(n.length() % 2 == 0){ - p1 = firstHalf + new StringBuilder(firstHalf).reverse(); - String temp = String.valueOf(Long.parseLong(firstHalf) + 1); - p2 = temp + new StringBuilder(temp).reverse(); - temp = String.valueOf(Long.parseLong(firstHalf) - 1); - String p3 = temp + new StringBuilder(temp).reverse(); - p1 = Math.abs(Long.parseLong(p3) - Long.parseLong(n)) <= Math.abs(Long.parseLong(p1) - Long.parseLong - (n)) ? p3 : p1; - } else { - char middle = n.charAt(n.length() / 2); - p1 = firstHalf + middle + new StringBuilder(firstHalf).reverse(); - String temp = String.valueOf(Long.parseLong(firstHalf) + 1); - p2 = temp + "0" + new StringBuilder(temp).reverse(); - String p3 = firstHalf + (Integer.parseInt(String.valueOf(middle)) + 1) + new StringBuilder(firstHalf) - .reverse(); - String p4 = null; - if(middle != '0'){ - p4 = firstHalf + (Integer.parseInt(String.valueOf(middle)) - 1) + new StringBuilder - (firstHalf).reverse(); - } - p1 = Math.abs(Long.parseLong(p1) - Long.parseLong(n)) <= Math.abs(Long.parseLong(p3) - Long.parseLong - (n)) ? p1 : p3; - if(p4 != null){ - p1 = Math.abs(Long.parseLong(p4) - Long.parseLong(n)) <= Math.abs(Long.parseLong(p1) - Long - .parseLong(n)) ? p4 : p1; - } - } + public String nearestPalindromic(String n) { + if (n.length() == 1) return String.valueOf(Integer.parseInt(n) - 1); + String p1, p2; + String palindrome; + if (isPaliandrome(n)) { + String newFirstHalf; + if (n.length() % 2 == 0) { + String firstHalf = n.substring(0, n.length() / 2); + newFirstHalf = String.valueOf(Long.parseLong(firstHalf) - 1); + p1 = newFirstHalf + new StringBuilder(newFirstHalf).reverse(); + newFirstHalf = String.valueOf(Long.parseLong(firstHalf) + 1); + p2 = newFirstHalf + new StringBuilder(newFirstHalf).reverse(); + } else { + String firstHalf = n.substring(0, n.length() / 2); + char middle = n.charAt(n.length() / 2); + if (middle == '0') { + p1 = firstHalf + "1" + new StringBuilder(firstHalf).reverse(); + } else { + p1 = + firstHalf + + (Integer.parseInt(String.valueOf(middle)) - 1) + + new StringBuilder(firstHalf).reverse(); + } + newFirstHalf = String.valueOf(Long.parseLong(firstHalf) + 1); + p2 = newFirstHalf + "0" + new StringBuilder(newFirstHalf).reverse(); + } + } else { + String firstHalf = n.substring(0, n.length() / 2); + if (n.length() % 2 == 0) { + p1 = firstHalf + new StringBuilder(firstHalf).reverse(); + String temp = String.valueOf(Long.parseLong(firstHalf) + 1); + p2 = temp + new StringBuilder(temp).reverse(); + temp = String.valueOf(Long.parseLong(firstHalf) - 1); + String p3 = temp + new StringBuilder(temp).reverse(); + p1 = + Math.abs(Long.parseLong(p3) - Long.parseLong(n)) + <= Math.abs(Long.parseLong(p1) - Long.parseLong(n)) + ? p3 + : p1; + } else { + char middle = n.charAt(n.length() / 2); + p1 = firstHalf + middle + new StringBuilder(firstHalf).reverse(); + String temp = String.valueOf(Long.parseLong(firstHalf) + 1); + p2 = temp + "0" + new StringBuilder(temp).reverse(); + String p3 = + firstHalf + + (Integer.parseInt(String.valueOf(middle)) + 1) + + new StringBuilder(firstHalf).reverse(); + String p4 = null; + if (middle != '0') { + p4 = + firstHalf + + (Integer.parseInt(String.valueOf(middle)) - 1) + + new StringBuilder(firstHalf).reverse(); } - long l1 = Math.abs(Long.parseLong(n) - Long.parseLong(p1)); - long l2 = Math.abs(Long.parseLong(n) - Long.parseLong(p2)); - if(l1 <= l2){ - palindrome = p1; - } else palindrome = p2; - long m1 = Math.abs(Long.parseLong(getLow(n)) - Long.parseLong(n)); - long m2 = Math.abs(Long.parseLong(palindrome) - Long.parseLong(n)); - long m3 = Math.abs(Long.parseLong(getHigh(n)) - Long.parseLong(n)); - long min = Math.min(Math.min(m1, m2), m3); - if(min == m1) return getLow(n); - else if(min == m2) return palindrome; - else return getHigh(n); + p1 = + Math.abs(Long.parseLong(p1) - Long.parseLong(n)) + <= Math.abs(Long.parseLong(p3) - Long.parseLong(n)) + ? p1 + : p3; + if (p4 != null) { + p1 = + Math.abs(Long.parseLong(p4) - Long.parseLong(n)) + <= Math.abs(Long.parseLong(p1) - Long.parseLong(n)) + ? p4 + : p1; + } + } } + long l1 = Math.abs(Long.parseLong(n) - Long.parseLong(p1)); + long l2 = Math.abs(Long.parseLong(n) - Long.parseLong(p2)); + if (l1 <= l2) { + palindrome = p1; + } else palindrome = p2; + long m1 = Math.abs(Long.parseLong(getLow(n)) - Long.parseLong(n)); + long m2 = Math.abs(Long.parseLong(palindrome) - Long.parseLong(n)); + long m3 = Math.abs(Long.parseLong(getHigh(n)) - Long.parseLong(n)); + long min = Math.min(Math.min(m1, m2), m3); + if (min == m1) return getLow(n); + else if (min == m2) return palindrome; + else return getHigh(n); + } - private String getLow(String s){ - int n = s.length() - 1; - StringBuilder sb = new StringBuilder(); - for(int i = 0; i < n; i ++){ - sb.append("9"); - } - return sb.toString(); + private String getLow(String s) { + int n = s.length() - 1; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < n; i++) { + sb.append("9"); } + return sb.toString(); + } - private String getHigh(String s){ - int n = s.length() - 1; - StringBuilder sb = new StringBuilder(); - sb.append("1"); - for(int i = 0; i < n; i ++){ - sb.append("0"); - } - sb.append("1"); - return sb.toString(); + private String getHigh(String s) { + int n = s.length() - 1; + StringBuilder sb = new StringBuilder(); + sb.append("1"); + for (int i = 0; i < n; i++) { + sb.append("0"); } + sb.append("1"); + return sb.toString(); + } - private boolean isPaliandrome(String s){ - for(int i = 0, j = s.length() - 1; i < j; i++, j--){ - if(s.charAt(i) != s.charAt(j)){ - return false; - } - } - return true; + private boolean isPaliandrome(String s) { + for (int i = 0, j = s.length() - 1; i < j; i++, j--) { + if (s.charAt(i) != s.charAt(j)) { + return false; + } } + return true; + } } diff --git a/problems/src/string/FirstUniqueCharacterInAString.java b/problems/src/string/FirstUniqueCharacterInAString.java index 08aa90ad..13e9a8c5 100644 --- a/problems/src/string/FirstUniqueCharacterInAString.java +++ b/problems/src/string/FirstUniqueCharacterInAString.java @@ -1,42 +1,37 @@ package string; /** - * Created by gouthamvidyapradhan on 09/03/2017. - * Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1. - *

- * Examples: - *

- * s = "leetcode" - * return 0. - *

- * s = "loveleetcode", - * return 2. - * Note: You may assume the string contain only lowercase letters. + * Created by gouthamvidyapradhan on 09/03/2017. Given a string, find the first non-repeating + * character in it and return it's index. If it doesn't exist, return -1. + * + *

Examples: + * + *

s = "leetcode" return 0. + * + *

s = "loveleetcode", return 2. Note: You may assume the string contain only lowercase letters. */ public class FirstUniqueCharacterInAString { - int[] CHAR = new int[256]; + int[] CHAR = new int[256]; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new FirstUniqueCharacterInAString().firstUniqChar("loveleetcode")); - } - - public int firstUniqChar(String s) { - if (s == null || s.isEmpty()) return -1; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new FirstUniqueCharacterInAString().firstUniqChar("loveleetcode")); + } - for (int i = 0, l = s.length(); i < l; i++) - CHAR[s.charAt(i)]++; + public int firstUniqChar(String s) { + if (s == null || s.isEmpty()) return -1; - for (int i = 0, l = s.length(); i < l; i++) { - if (CHAR[s.charAt(i)] == 1) - return i; - } + for (int i = 0, l = s.length(); i < l; i++) CHAR[s.charAt(i)]++; - return -1; + for (int i = 0, l = s.length(); i < l; i++) { + if (CHAR[s.charAt(i)] == 1) return i; } + + return -1; + } } diff --git a/problems/src/string/ImplementStrStr.java b/problems/src/string/ImplementStrStr.java index 374908d8..11349152 100644 --- a/problems/src/string/ImplementStrStr.java +++ b/problems/src/string/ImplementStrStr.java @@ -1,42 +1,38 @@ package string; /** - * Created by gouthamvidyapradhan on 24/06/2017. - * Implement strStr(). - *

- * Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. - *

- * Solution O(N ^ 2) + * Created by gouthamvidyapradhan on 24/06/2017. Implement strStr(). + * + *

Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part + * of haystack. + * + *

Solution O(N ^ 2) */ public class ImplementStrStr { - public static void main(String[] args) throws Exception { - System.out.println(new ImplementStrStr().strStr("AABB", "")); - } + public static void main(String[] args) throws Exception { + System.out.println(new ImplementStrStr().strStr("AABB", "")); + } - public int strStr(String haystack, String needle) { - if (haystack.isEmpty() && needle.isEmpty()) return 0; - if (needle.isEmpty()) return 0; - for (int i = 0, l = haystack.length(); i < l; i++) { - if (haystack.charAt(i) == needle.charAt(0)) { - if (isEqual(haystack, needle, i)) - return i; - } - } - return -1; + public int strStr(String haystack, String needle) { + if (haystack.isEmpty() && needle.isEmpty()) return 0; + if (needle.isEmpty()) return 0; + for (int i = 0, l = haystack.length(); i < l; i++) { + if (haystack.charAt(i) == needle.charAt(0)) { + if (isEqual(haystack, needle, i)) return i; + } } + return -1; + } - private boolean isEqual(String haystack, String needle, int i) { - int hL = haystack.length(); - int nL = needle.length(); - int j = 0; - while (i < hL && j < nL) { - if (haystack.charAt(i) != needle.charAt(j)) - return false; - i++; - j++; - } - return j >= nL; + private boolean isEqual(String haystack, String needle, int i) { + int hL = haystack.length(); + int nL = needle.length(); + int j = 0; + while (i < hL && j < nL) { + if (haystack.charAt(i) != needle.charAt(j)) return false; + i++; + j++; } - - + return j >= nL; + } } diff --git a/problems/src/string/IntegerToEnglishWords.java b/problems/src/string/IntegerToEnglishWords.java deleted file mode 100644 index ae7e296a..00000000 --- a/problems/src/string/IntegerToEnglishWords.java +++ /dev/null @@ -1,10 +0,0 @@ -package string; - -/** - * Created by gouthamvidyapradhan on 12/08/2017. - */ -public class IntegerToEnglishWords { - public static void main(String[] args) { - System.out.println(Integer.MAX_VALUE); - } -} diff --git a/problems/src/string/IsomorphicStrings.java b/problems/src/string/IsomorphicStrings.java index 73d2d512..f9c44de5 100644 --- a/problems/src/string/IsomorphicStrings.java +++ b/problems/src/string/IsomorphicStrings.java @@ -4,51 +4,50 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 11/04/2018. - * Given two strings s and t, determine if they are isomorphic. - - Two strings are isomorphic if the characters in s can be replaced to get t. - - All occurrences of a character must be replaced with another character while preserving the order of characters. No - two characters may map to the same character but a character may map to itself. - - For example, - Given "egg", "add", return true. - - Given "foo", "bar", return false. - - Given "paper", "title", return true. - - Note: - You may assume both s and t have the same length. - Solution O(N): Maintain two hashmaps and compare character by character. + * Created by gouthamvidyapradhan on 11/04/2018. Given two strings s and t, determine if they are + * isomorphic. + * + *

Two strings are isomorphic if the characters in s can be replaced to get t. + * + *

All occurrences of a character must be replaced with another character while preserving the + * order of characters. No two characters may map to the same character but a character may map to + * itself. + * + *

For example, Given "egg", "add", return true. + * + *

Given "foo", "bar", return false. + * + *

Given "paper", "title", return true. + * + *

Note: You may assume both s and t have the same length. Solution O(N): Maintain two hashmaps + * and compare character by character. */ public class IsomorphicStrings { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new IsomorphicStrings().isIsomorphic("abc", "dea")); - } - - public boolean isIsomorphic(String s, String t) { - if(s.length() != t.length()) return false; - Map first = new HashMap<>(); - Map second = new HashMap<>(); - for(int i = 0; i < s.length(); i ++){ - char c = s.charAt(i); - if(first.containsKey(c)){ - char secondC = first.get(c); - if(t.charAt(i) != secondC) return false; - } else{ - first.put(c, t.charAt(i)); - if(second.containsKey(t.charAt(i))) return false; - second.put(t.charAt(i), c); - } - } - return true; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new IsomorphicStrings().isIsomorphic("abc", "dea")); + } + + public boolean isIsomorphic(String s, String t) { + if (s.length() != t.length()) return false; + Map first = new HashMap<>(); + Map second = new HashMap<>(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (first.containsKey(c)) { + char secondC = first.get(c); + if (t.charAt(i) != secondC) return false; + } else { + first.put(c, t.charAt(i)); + if (second.containsKey(t.charAt(i))) return false; + second.put(t.charAt(i), c); + } } - + return true; + } } diff --git a/problems/src/string/KeyboardRow.java b/problems/src/string/KeyboardRow.java index 9fd5729e..f91ff886 100644 --- a/problems/src/string/KeyboardRow.java +++ b/problems/src/string/KeyboardRow.java @@ -1,63 +1,55 @@ -package string; /** +package string; +/** * Created by gouthamvidyapradhan on 09/04/2019 * - * Given a List of words, return the words that can be typed using letters of alphabet on only one row's of American - * keyboard like the image below. + *

Given a List of words, return the words that can be typed using letters of alphabet on only + * one row's of American keyboard like the image below. * + *

Example: * + *

Input: ["Hello", "Alaska", "Dad", "Peace"] Output: ["Alaska", "Dad"] * + *

Note: * - * - * - * Example: - * - * Input: ["Hello", "Alaska", "Dad", "Peace"] - * Output: ["Alaska", "Dad"] - * - * Note: - * - * You may use one character in the keyboard more than once. - * You may assume the input string will only contain letters of alphabet. + *

You may use one character in the keyboard more than once. You may assume the input string will + * only contain letters of alphabet. */ import java.util.*; -public class KeyboardRow { - /** - * Main method - * @param args - */ - public static void main(String[] args) { +public class KeyboardRow { - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) {} - public String[] findWords(String[] words) { - String R1 = "qwertyuiop"; - String R2 = "asdfghjkl"; - String R3 = "zxcvbnm"; - List answer = new ArrayList<>(); - for(String s : words){ - Set set = new HashSet<>(); - for(char c : s.toCharArray()){ - if(R1.indexOf(c) != -1){ - set.add('1'); - } - else if(R2.indexOf(c) != -1){ - set.add('2'); - } - else if(R3.indexOf(c) != -1){ - set.add('3'); - } - } - if(set.size() == 1){ - answer.add(s); - } - } - String[] ans = new String[answer.size()]; - int i = 0; - for(String s : answer){ - ans[i++] = s; + public String[] findWords(String[] words) { + String R1 = "qwertyuiop"; + String R2 = "asdfghjkl"; + String R3 = "zxcvbnm"; + List answer = new ArrayList<>(); + for (String s : words) { + Set set = new HashSet<>(); + for (char c : s.toCharArray()) { + if (R1.indexOf(c) != -1) { + set.add('1'); + } else if (R2.indexOf(c) != -1) { + set.add('2'); + } else if (R3.indexOf(c) != -1) { + set.add('3'); } - return ans; + } + if (set.size() == 1) { + answer.add(s); + } } - + String[] ans = new String[answer.size()]; + int i = 0; + for (String s : answer) { + ans[i++] = s; + } + return ans; + } } diff --git a/problems/src/string/LongestCommonPrefix.java b/problems/src/string/LongestCommonPrefix.java index 716c459c..4d220ccf 100644 --- a/problems/src/string/LongestCommonPrefix.java +++ b/problems/src/string/LongestCommonPrefix.java @@ -1,34 +1,35 @@ package string; /** - * Created by gouthamvidyapradhan on 12/04/2018. - * Write a function to find the longest common prefix string amongst an array of strings. + * Created by gouthamvidyapradhan on 12/04/2018. Write a function to find the longest common prefix + * string amongst an array of strings. * - * Solution: O(N x M) where N is the length of the given array and M is the max_length of a string. + *

Solution: O(N x M) where N is the length of the given array and M is the max_length of a + * string. */ public class LongestCommonPrefix { - /** - * Main method - * @param args - */ - public static void main(String[] args) throws Exception{ - String[] A = {"abc", "a", "adkd"}; - System.out.println(new LongestCommonPrefix().longestCommonPrefix(A)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) throws Exception { + String[] A = {"abc", "a", "adkd"}; + System.out.println(new LongestCommonPrefix().longestCommonPrefix(A)); + } - public String longestCommonPrefix(String[] strs) { - if(strs.length == 0) return ""; - String result = strs[0]; - for(int i = 1; i < strs.length; i ++){ - String s = strs[i]; - for(int j = 0; j < result.length(); j++){ - if(j >= s.length() || result.charAt(j) != s.charAt(j)) { - result = result.substring(0, j); - break; - } - } + public String longestCommonPrefix(String[] strs) { + if (strs.length == 0) return ""; + String result = strs[0]; + for (int i = 1; i < strs.length; i++) { + String s = strs[i]; + for (int j = 0; j < result.length(); j++) { + if (j >= s.length() || result.charAt(j) != s.charAt(j)) { + result = result.substring(0, j); + break; } - return result; + } } - + return result; + } } diff --git a/problems/src/string/LongestPalindrome.java b/problems/src/string/LongestPalindrome.java index a5bc9792..9c6f69bf 100644 --- a/problems/src/string/LongestPalindrome.java +++ b/problems/src/string/LongestPalindrome.java @@ -1,57 +1,53 @@ package string; /** - * Created by gouthamvidyapradhan on 20/03/2019 - * Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that - * can be built with those letters. + * Created by gouthamvidyapradhan on 20/03/2019 Given a string which consists of lowercase or + * uppercase letters, find the length of the longest palindromes that can be built with those + * letters. * - * This is case sensitive, for example "Aa" is not considered a palindrome here. + *

This is case sensitive, for example "Aa" is not considered a palindrome here. * - * Note: - * Assume the length of given string will not exceed 1,010. + *

Note: Assume the length of given string will not exceed 1,010. * - * Example: + *

Example: * - * Input: - * "abccccdd" + *

Input: "abccccdd" * - * Output: - * 7 + *

Output: 7 * - * Explanation: - * One longest palindrome that can be built is "dccaccd", whose length is 7. + *

Explanation: One longest palindrome that can be built is "dccaccd", whose length is 7. */ import java.util.*; public class LongestPalindrome { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - int result = new LongestPalindrome().longestPalindrome( - "asdfasdf"); - System.out.println(result); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int result = new LongestPalindrome().longestPalindrome("asdfasdf"); + System.out.println(result); + } - public int longestPalindrome(String s) { - Map map = new HashMap<>(); - for(char c : s.toCharArray()){ - map.putIfAbsent(c, 0); - int count = map.get(c); - map.put(c, count + 1); - } - int max = 0; - boolean odd = false; - for(char c : map.keySet()){ - int count = map.get(c); - max += count; - if((count % 2) != 0){ - max --; - odd = true; - } - } - if(odd) max ++; - return max; + public int longestPalindrome(String s) { + Map map = new HashMap<>(); + for (char c : s.toCharArray()) { + map.putIfAbsent(c, 0); + int count = map.get(c); + map.put(c, count + 1); + } + int max = 0; + boolean odd = false; + for (char c : map.keySet()) { + int count = map.get(c); + max += count; + if ((count % 2) != 0) { + max--; + odd = true; + } } + if (odd) max++; + return max; + } } diff --git a/problems/src/string/LongestWordInDictonary.java b/problems/src/string/LongestWordInDictonary.java index 910c2946..85968ef0 100644 --- a/problems/src/string/LongestWordInDictonary.java +++ b/problems/src/string/LongestWordInDictonary.java @@ -3,58 +3,52 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 15/02/2018. - * Given a string and a string dictionary, find the longest string in the dictionary that can be formed by deleting - * some characters of the given string. If there are more than one possible results, return the longest word with the - * smallest lexicographical order. If there is no possible result, return the empty string. - - Example 1: - Input: - s = "abpcplea", d = ["ale","apple","monkey","plea"] - - Output: - "apple" - Example 2: - Input: - s = "abpcplea", d = ["a","b","c"] - - Output: - "a" - Note: - All the strings in the input will only contain lower-case letters. - The size of the dictionary won't exceed 1,000. - The length of all the strings in the input won't exceed 1,000. - - Solution: O((n x m x log n) + (m ^ 2 + m x n))) sort the dictionary based on the longest first and then - lexicographically and compare each sorted word with given word and do a two pointer comparison to check for - sub-sequence. + * Created by gouthamvidyapradhan on 15/02/2018. Given a string and a string dictionary, find the + * longest string in the dictionary that can be formed by deleting some characters of the given + * string. If there are more than one possible results, return the longest word with the smallest + * lexicographical order. If there is no possible result, return the empty string. + * + *

Example 1: Input: s = "abpcplea", d = ["ale","apple","monkey","plea"] + * + *

Output: "apple" Example 2: Input: s = "abpcplea", d = ["a","b","c"] + * + *

Output: "a" Note: All the strings in the input will only contain lower-case letters. The size + * of the dictionary won't exceed 1,000. The length of all the strings in the input won't exceed + * 1,000. + * + *

Solution: O((n x m x log n) + (m ^ 2 + m x n))) sort the dictionary based on the longest first + * and then lexicographically and compare each sorted word with given word and do a two pointer + * comparison to check for sub-sequence. */ public class LongestWordInDictonary { - /** - * Main method - * @param args - */ - public static void main(String[] args) throws Exception{ - List dict = Arrays.asList("ale","apple","monkey","plea"); - System.out.println(new LongestWordInDictonary().findLongestWord("abpcplea", dict)); - } - - public String findLongestWord(String s, List d) { - Collections.sort(d, Comparator.comparing(String::length).reversed().thenComparing(String::compareTo)); - for(String str : d){ - if(str.length() <= s.length()){ - int i = 0, j = 0; - for(int l1 = s.length(), l2 = str.length(); i < l1 && j < l2; ){ - if(s.charAt(i) == str.charAt(j)){ - i++; j++; - } else{ - i++; - } - } - if(j >= str.length()) return str; - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) throws Exception { + List dict = Arrays.asList("ale", "apple", "monkey", "plea"); + System.out.println(new LongestWordInDictonary().findLongestWord("abpcplea", dict)); + } + + public String findLongestWord(String s, List d) { + Collections.sort( + d, Comparator.comparing(String::length).reversed().thenComparing(String::compareTo)); + for (String str : d) { + if (str.length() <= s.length()) { + int i = 0, j = 0; + for (int l1 = s.length(), l2 = str.length(); i < l1 && j < l2; ) { + if (s.charAt(i) == str.charAt(j)) { + i++; + j++; + } else { + i++; + } } - return ""; + if (j >= str.length()) return str; + } } + return ""; + } } diff --git a/problems/src/string/MonotoneIncreasingDigits.java b/problems/src/string/MonotoneIncreasingDigits.java index b8dd0784..e354b7a1 100644 --- a/problems/src/string/MonotoneIncreasingDigits.java +++ b/problems/src/string/MonotoneIncreasingDigits.java @@ -1,66 +1,58 @@ package string; /** - * Created by gouthamvidyapradhan on 01/05/2018. - * Given a non-negative integer N, find the largest number that is less than or equal to N with monotone - * increasing digits. - - (Recall that an integer has monotone increasing digits if and only if each pair of - adjacent digits x and y satisfy x <= y.) - - Example 1: - Input: N = 10 - Output: 9 - Example 2: - Input: N = 1234 - Output: 1234 - Example 3: - Input: N = 332 - Output: 299 - Note: N is an integer in the range [0, 10^9]. - - Solution O(N): Convert to string for easier manipulation. - Start from N.length - 1 and iterate through until index 0.Mark the index where the violation occurs. - Decrement the value of the latest index where the violation occurs and append '9' to - rest of the trailing digits. Convert the string to integer before returning. + * Created by gouthamvidyapradhan on 01/05/2018. Given a non-negative integer N, find the largest + * number that is less than or equal to N with monotone increasing digits. + * + *

(Recall that an integer has monotone increasing digits if and only if each pair of adjacent + * digits x and y satisfy x <= y.) + * + *

Example 1: Input: N = 10 Output: 9 Example 2: Input: N = 1234 Output: 1234 Example 3: Input: N + * = 332 Output: 299 Note: N is an integer in the range [0, 10^9]. + * + *

Solution O(N): Convert to string for easier manipulation. Start from N.length - 1 and iterate + * through until index 0.Mark the index where the violation occurs. Decrement the value of the + * latest index where the violation occurs and append '9' to rest of the trailing digits. Convert + * the string to integer before returning. */ public class MonotoneIncreasingDigits { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new MonotoneIncreasingDigits().monotoneIncreasingDigits(100001)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new MonotoneIncreasingDigits().monotoneIncreasingDigits(100001)); + } - public int monotoneIncreasingDigits(int N) { - String s = String.valueOf(N); - if(s.length() == 1) return N; - int p = -1; - int prev = N % 10; - for(int i = s.length() - 2; i >= 0; i--){ - int curr = Integer.parseInt(String.valueOf(s.charAt(i))); - if(curr > prev){ - p = i; - prev = curr - 1; - } else { - prev = curr; - } - } - if(p == -1) return N; - StringBuilder result = new StringBuilder(); - for(int i = 0; i < s.length(); i ++){ - if(i == p){ - int pV = Integer.parseInt(String.valueOf(s.charAt(i))); - result.append(pV - 1); - break; - } result.append(String.valueOf(s.charAt(i))); - } - for(int i = p + 1; i < s.length(); i ++){ - result.append("9"); - } - return Integer.parseInt(result.toString()); + public int monotoneIncreasingDigits(int N) { + String s = String.valueOf(N); + if (s.length() == 1) return N; + int p = -1; + int prev = N % 10; + for (int i = s.length() - 2; i >= 0; i--) { + int curr = Integer.parseInt(String.valueOf(s.charAt(i))); + if (curr > prev) { + p = i; + prev = curr - 1; + } else { + prev = curr; + } } - + if (p == -1) return N; + StringBuilder result = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { + if (i == p) { + int pV = Integer.parseInt(String.valueOf(s.charAt(i))); + result.append(pV - 1); + break; + } + result.append(String.valueOf(s.charAt(i))); + } + for (int i = p + 1; i < s.length(); i++) { + result.append("9"); + } + return Integer.parseInt(result.toString()); + } } diff --git a/problems/src/string/MultiplyStrings.java b/problems/src/string/MultiplyStrings.java index ac9b98f2..5d98ddc7 100644 --- a/problems/src/string/MultiplyStrings.java +++ b/problems/src/string/MultiplyStrings.java @@ -1,72 +1,73 @@ package string; /** - * Created by gouthamvidyapradhan on 01/02/2018. - * Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2. - - Note: - - The length of both num1 and num2 is < 110. - Both num1 and num2 contains only digits 0-9. - Both num1 and num2 does not contain any leading zero. - You must not use any built-in BigInteger library or convert the inputs to integer directly. - - Solution: O(N x M) where N and M are length of strings + * Created by gouthamvidyapradhan on 01/02/2018. Given two non-negative integers num1 and num2 + * represented as strings, return the product of num1 and num2. + * + *

Note: + * + *

The length of both num1 and num2 is < 110. Both num1 and num2 contains only digits 0-9. Both + * num1 and num2 does not contain any leading zero. You must not use any built-in BigInteger library + * or convert the inputs to integer directly. + * + *

Solution: O(N x M) where N and M are length of strings */ public class MultiplyStrings { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new MultiplyStrings().multiply("00", "0000")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new MultiplyStrings().multiply("00", "0000")); + } - public String multiply(String num1, String num2) { - if((num1.length() == 1 && num1.equals("0")) || (num2.length() == 1 && num2.equals("0"))) return "0"; - if(num1.length() < num2.length()) return multiply(num2, num1); - String temp2 = "", trail = ""; - int carry = 0; - for(int i = 0; i < num1.length(); i ++){ - temp2 += "0"; - } - for(int i = num1.length() - 1; i >= 0; i --){ - String temp1 = ""; - for(int j = num2.length() - 1; j >= 0; j --){ - int prod = Integer.parseInt(String.valueOf(num2.charAt(j))) * - Integer.parseInt(String.valueOf(num1.charAt(i))); - prod += carry; - temp1 = (prod % 10) + temp1; - carry = (prod / 10); - } - if(carry > 0){ - temp1 = String.valueOf(carry) + temp1; - carry = 0; - } - String temp3 = add(temp1, temp2); - temp2 = temp3.substring(0, temp3.length() - 1); - trail = temp3.substring(temp3.length() - 1, temp3.length()) + trail; - } - return temp2 + trail; + public String multiply(String num1, String num2) { + if ((num1.length() == 1 && num1.equals("0")) || (num2.length() == 1 && num2.equals("0"))) + return "0"; + if (num1.length() < num2.length()) return multiply(num2, num1); + String temp2 = "", trail = ""; + int carry = 0; + for (int i = 0; i < num1.length(); i++) { + temp2 += "0"; } - - private String add(String s1, String s2){ - String result = ""; - int carry = 0; - int i = s1.length() - 1, j = s2.length() - 1; - for(; i >= 0 || j >= 0; i --, j--){ - int l = (i >= 0) ? Integer.parseInt(String.valueOf(s1.charAt(i))) : 0; - int r = (j >= 0) ? Integer.parseInt(String.valueOf(s2.charAt(j))) : 0; - int sum = l + r + carry; - carry = sum / 10; - result = sum % 10 + result; - } - if(carry > 0){ - result = carry + result; - } - return result; + for (int i = num1.length() - 1; i >= 0; i--) { + String temp1 = ""; + for (int j = num2.length() - 1; j >= 0; j--) { + int prod = + Integer.parseInt(String.valueOf(num2.charAt(j))) + * Integer.parseInt(String.valueOf(num1.charAt(i))); + prod += carry; + temp1 = (prod % 10) + temp1; + carry = (prod / 10); + } + if (carry > 0) { + temp1 = String.valueOf(carry) + temp1; + carry = 0; + } + String temp3 = add(temp1, temp2); + temp2 = temp3.substring(0, temp3.length() - 1); + trail = temp3.substring(temp3.length() - 1, temp3.length()) + trail; } + return temp2 + trail; + } + private String add(String s1, String s2) { + String result = ""; + int carry = 0; + int i = s1.length() - 1, j = s2.length() - 1; + for (; i >= 0 || j >= 0; i--, j--) { + int l = (i >= 0) ? Integer.parseInt(String.valueOf(s1.charAt(i))) : 0; + int r = (j >= 0) ? Integer.parseInt(String.valueOf(s2.charAt(j))) : 0; + int sum = l + r + carry; + carry = sum / 10; + result = sum % 10 + result; + } + if (carry > 0) { + result = carry + result; + } + return result; + } } diff --git a/problems/src/string/NumberOfMatchingSubsequences.java b/problems/src/string/NumberOfMatchingSubsequences.java index 02f63b8c..1fb85193 100644 --- a/problems/src/string/NumberOfMatchingSubsequences.java +++ b/problems/src/string/NumberOfMatchingSubsequences.java @@ -1,59 +1,53 @@ package string; /** - * Created by gouthamvidyapradhan on 04/04/2019 - * Given string S and a dictionary of words words, find the number of words[i] that is a subsequence of S. + * Created by gouthamvidyapradhan on 04/04/2019 Given string S and a dictionary of words words, find + * the number of words[i] that is a subsequence of S. * - * Example : - * Input: - * S = "abcde" - * words = ["a", "bb", "acd", "ace"] - * Output: 3 - * Explanation: There are three words in words that are a subsequence of S: "a", "acd", "ace". - * Note: + *

Example : Input: S = "abcde" words = ["a", "bb", "acd", "ace"] Output: 3 Explanation: There + * are three words in words that are a subsequence of S: "a", "acd", "ace". Note: * - * All words in words and S will only consists of lowercase letters. - * The length of S will be in the range of [1, 50000]. - * The length of words will be in the range of [1, 5000]. - * The length of words[i] will be in the range of [1, 50]. + *

All words in words and S will only consists of lowercase letters. The length of S will be in + * the range of [1, 50000]. The length of words will be in the range of [1, 5000]. The length of + * words[i] will be in the range of [1, 50]. */ public class NumberOfMatchingSubsequences { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - String[] A = {"a", "bb", "acd", "ace"}; - System.out.println(new NumberOfMatchingSubsequences().numMatchingSubseq("abcde", A)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + String[] A = {"a", "bb", "acd", "ace"}; + System.out.println(new NumberOfMatchingSubsequences().numMatchingSubseq("abcde", A)); + } - public int numMatchingSubseq(String S, String[] words) { - int count = 0; - for(int i = 0; i < words.length; i ++){ - String w = words[i]; - if(isSubsequence(S, w)){ - count ++; - } - } - return count; + public int numMatchingSubseq(String S, String[] words) { + int count = 0; + for (int i = 0; i < words.length; i++) { + String w = words[i]; + if (isSubsequence(S, w)) { + count++; + } } + return count; + } - private boolean isSubsequence(String S, String P){ - int i = 0, j = 0; - if(P.length() > S.length()) return false; - for(;;){ - if(j >= P.length()) return true; - else if(i >= S.length()) return false; - else { - if(S.charAt(i) == P.charAt(j)){ - i ++; - j ++; - } else { - i ++; - } - } + private boolean isSubsequence(String S, String P) { + int i = 0, j = 0; + if (P.length() > S.length()) return false; + for (; ; ) { + if (j >= P.length()) return true; + else if (i >= S.length()) return false; + else { + if (S.charAt(i) == P.charAt(j)) { + i++; + j++; + } else { + i++; } + } } - + } } diff --git a/problems/src/string/OneEditDistance.java b/problems/src/string/OneEditDistance.java index fc65eb7e..b06af63e 100644 --- a/problems/src/string/OneEditDistance.java +++ b/problems/src/string/OneEditDistance.java @@ -3,49 +3,52 @@ /** * Created by gouthamvidyapradhan on 09/12/2017. * - * Given two strings S and T, determine if they are both one edit distance apart. + *

Given two strings S and T, determine if they are both one edit distance apart. */ public class OneEditDistance { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new OneEditDistance().isOneEditDistance("abxd", "adxb")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new OneEditDistance().isOneEditDistance("abxd", "adxb")); + } - public boolean isOneEditDistance(String s, String t) { - if(Math.abs(s.length() - t.length()) > 1 || s.equals(t)) return false; - if(s.length() > t.length()){ - return hasDiffOne(s, t, false); - } else if(t.length() > s.length()){ - return hasDiffOne(t, s, false); - } else{ - return hasDiffOne(s, t, true); - } + public boolean isOneEditDistance(String s, String t) { + if (Math.abs(s.length() - t.length()) > 1 || s.equals(t)) return false; + if (s.length() > t.length()) { + return hasDiffOne(s, t, false); + } else if (t.length() > s.length()) { + return hasDiffOne(t, s, false); + } else { + return hasDiffOne(s, t, true); } + } - private boolean hasDiffOne(String s, String t, boolean sameLength){ - int count = 0, i = 0, j = 0; - for(int l1 = s.length(), l2 = t.length(); i < l1 && j < l2;){ - if(s.charAt(i) == t.charAt(j)){ - i++; j++; - } else{ - if(count > 0) return false; - count++; - if(sameLength){ - i++; j++; - } else{ - i++; - } - } - } - if(i == j){ - return true; - } else{ - return (s.charAt(s.length() - 1) == t.charAt(t.length() - 1)); + private boolean hasDiffOne(String s, String t, boolean sameLength) { + int count = 0, i = 0, j = 0; + for (int l1 = s.length(), l2 = t.length(); i < l1 && j < l2; ) { + if (s.charAt(i) == t.charAt(j)) { + i++; + j++; + } else { + if (count > 0) return false; + count++; + if (sameLength) { + i++; + j++; + } else { + i++; } + } + } + if (i == j) { + return true; + } else { + return (s.charAt(s.length() - 1) == t.charAt(t.length() - 1)); } + } } diff --git a/problems/src/string/PermutationInString.java b/problems/src/string/PermutationInString.java index 86cccc94..3a908c28 100644 --- a/problems/src/string/PermutationInString.java +++ b/problems/src/string/PermutationInString.java @@ -1,60 +1,53 @@ package string; /** - * Created by gouthamvidyapradhan on 18/09/2017. - * 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. - - Example 1: - Input:s1 = "ab" s2 = "eidbaooo" - Output:True - Explanation: s2 contains one permutation of s1 ("ba"). - - Example 2: - Input:s1= "ab" s2 = "eidboaoo" - Output: False - Note: - The input strings only contain lower case letters. - The length of both given strings is in range [1, 10,000]. - + * Created by gouthamvidyapradhan on 18/09/2017. 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. + * + *

Example 1: Input:s1 = "ab" s2 = "eidbaooo" Output:True Explanation: s2 contains one + * permutation of s1 ("ba"). + * + *

Example 2: Input:s1= "ab" s2 = "eidboaoo" Output: False Note: The input strings only contain + * lower case letters. The length of both given strings is in range [1, 10,000]. */ public class PermutationInString { - private int[] S1 = new int[256]; - private int[] S2 = new int[256]; - - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new PermutationInString().checkInclusion("ab", "eidboaoo")); + private int[] S1 = new int[256]; + private int[] S2 = new int[256]; + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new PermutationInString().checkInclusion("ab", "eidboaoo")); + } + + public boolean checkInclusion(String s1, String s2) { + if (s2.length() < s1.length()) return false; + for (int i = 0, l = s1.length(); i < l; i++) { + S1[s1.charAt(i)]++; + S2[s2.charAt(i)]++; } - - public boolean checkInclusion(String s1, String s2) { - if(s2.length() < s1.length()) return false; - for(int i = 0, l = s1.length(); i < l; i ++){ - S1[s1.charAt(i)] ++; - S2[s2.charAt(i)] ++; - } - if(isEqual()) return true; - for(int i = 1, j = s1.length(), l = s2.length(); j < l; i++, j++){ - S2[s2.charAt(i - 1)] --; - S2[s2.charAt(j)] ++; - if(isEqual()) return true; - } - return false; + if (isEqual()) return true; + for (int i = 1, j = s1.length(), l = s2.length(); j < l; i++, j++) { + S2[s2.charAt(i - 1)]--; + S2[s2.charAt(j)]++; + if (isEqual()) return true; } - - private boolean isEqual(){ - boolean equal = true; - for(int i = 0; i < 256; i ++){ - if(S1[i] != S2[i]){ - equal = false; - break; - } - } - return equal; + return false; + } + + private boolean isEqual() { + boolean equal = true; + for (int i = 0; i < 256; i++) { + if (S1[i] != S2[i]) { + equal = false; + break; + } } - + return equal; + } } diff --git a/problems/src/string/RepeatedSubstringPattern.java b/problems/src/string/RepeatedSubstringPattern.java index 9acc361a..2479e6bc 100644 --- a/problems/src/string/RepeatedSubstringPattern.java +++ b/problems/src/string/RepeatedSubstringPattern.java @@ -1,56 +1,52 @@ package string; /** - * Created by gouthamvidyapradhan on 25/03/2017. - * Given a non-empty string check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. You may assume the given string consists of lowercase English letters only and its length will not exceed 10000. - *

- * Example 1: - * Input: "abab" - *

- * Output: True - *

- * Explanation: It's the substring "ab" twice. - * Example 2: - * Input: "aba" - *

- * Output: False - * Example 3: - * Input: "abcabcabcabc" - *

- * Output: True - *

- * Explanation: It's the substring "abc" four times. (And the substring "abcabc" twice.) + * Created by gouthamvidyapradhan on 25/03/2017. Given a non-empty string check if it can be + * constructed by taking a substring of it and appending multiple copies of the substring together. + * You may assume the given string consists of lowercase English letters only and its length will + * not exceed 10000. + * + *

Example 1: Input: "abab" + * + *

Output: True + * + *

Explanation: It's the substring "ab" twice. Example 2: Input: "aba" + * + *

Output: False Example 3: Input: "abcabcabcabc" + * + *

Output: True + * + *

Explanation: It's the substring "abc" four times. (And the substring "abcabc" twice.) */ public class RepeatedSubstringPattern { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new RepeatedSubstringPattern().repeatedSubstringPattern("a")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new RepeatedSubstringPattern().repeatedSubstringPattern("a")); + } - public boolean repeatedSubstringPattern(String s) { - boolean found; - for (int i = 1, l = s.length(); i < l; i++) { - found = true; - String subI = s.substring(0, i); - int j = i; - if (j >= l) return false; - while (j < l) { - if ((j + i) >= l + 1) - return false; - String subJ = s.substring(j, j + i); - if (!subI.equals(subJ)) { - found = false; - break; - } - j += i; - } - if (found) return true; + public boolean repeatedSubstringPattern(String s) { + boolean found; + for (int i = 1, l = s.length(); i < l; i++) { + found = true; + String subI = s.substring(0, i); + int j = i; + if (j >= l) return false; + while (j < l) { + if ((j + i) >= l + 1) return false; + String subJ = s.substring(j, j + i); + if (!subI.equals(subJ)) { + found = false; + break; } - return false; + j += i; + } + if (found) return true; } + return false; + } } diff --git a/problems/src/string/ReplaceWords.java b/problems/src/string/ReplaceWords.java index d5f99f6d..7c2dede5 100644 --- a/problems/src/string/ReplaceWords.java +++ b/problems/src/string/ReplaceWords.java @@ -7,103 +7,101 @@ import java.util.stream.Stream; /** - * Created by gouthamvidyapradhan on 04/04/2019 - * In English, we have a concept called root, which can be followed by some other words to form another longer word - * - let's call this word successor. For example, the root an, followed by other, which can form another word another. + * Created by gouthamvidyapradhan on 04/04/2019 In English, we have a concept called root, which can + * be followed by some other words to form another longer word - let's call this word successor. For + * example, the root an, followed by other, which can form another word another. * - * Now, given a dictionary consisting of many roots and a sentence. You need to replace all the successor in the - * sentence with the root forming it. If a successor has many roots can form it, replace it with the root with the - * shortest length. + *

Now, given a dictionary consisting of many roots and a sentence. You need to replace all the + * successor in the sentence with the root forming it. If a successor has many roots can form it, + * replace it with the root with the shortest length. * - * You need to output the sentence after the replacement. + *

You need to output the sentence after the replacement. * - * Example 1: + *

Example 1: * - * Input: dict = ["cat", "bat", "rat"] - * sentence = "the cattle was rattled by the battery" - * Output: "the cat was rat by the bat" + *

Input: dict = ["cat", "bat", "rat"] sentence = "the cattle was rattled by the battery" Output: + * "the cat was rat by the bat" * + *

Note: * - * Note: + *

The input will only have lower-case letters. 1 <= dict words number <= 1000 1 <= sentence + * words number <= 1000 1 <= root length <= 100 1 <= sentence words length <= 1000 * - * The input will only have lower-case letters. - * 1 <= dict words number <= 1000 - * 1 <= sentence words number <= 1000 - * 1 <= root length <= 100 - * 1 <= sentence words length <= 1000 - * - * Solution: O(w + S) where w is the max length of each word in the dictionary and S is the length of the string. - * Add all the words in the dictionary to a trie and evaluate each word in the string to check if it matches any path - * in the trie. Terminate the search as soon as a leaf node in the trie has been reached. + *

Solution: O(w + S) where w is the max length of each word in the dictionary and S is the + * length of the string. Add all the words in the dictionary to a trie and evaluate each word in the + * string to check if it matches any path in the trie. Terminate the search as soon as a leaf node + * in the trie has been reached. */ public class ReplaceWords { - class Trie { - private Map map; + class Trie { + private Map map; - /** - * Initialize your data structure here. - */ - public Trie() { - map = new HashMap<>(); - } + /** Initialize your data structure here. */ + public Trie() { + map = new HashMap<>(); + } - /** - * Inserts a word into the trie. - */ - public void insert(String word) { - if (word != null) { - add(0, word, word.length()); - } - } + /** Inserts a word into the trie. */ + public void insert(String word) { + if (word != null) { + add(0, word, word.length()); + } + } - public String find(String s){ - return search(this, s, 0, new StringBuilder()); - } + public String find(String s) { + return search(this, s, 0, new StringBuilder()); + } - private void add(int i, String word, int length) { - if (i < length) { - char c = word.charAt(i); - Trie subTrie = map.get(c); - if (subTrie == null) { - subTrie = new Trie(); - map.put(c, subTrie); - } - subTrie.add(i + 1, word, length); - } else map.put(null, new Trie()); //use null to indicate end of string + private void add(int i, String word, int length) { + if (i < length) { + char c = word.charAt(i); + Trie subTrie = map.get(c); + if (subTrie == null) { + subTrie = new Trie(); + map.put(c, subTrie); } + subTrie.add(i + 1, word, length); + } else map.put(null, new Trie()); // use null to indicate end of string + } - private String search(Trie curr, String s, int i, StringBuilder sb){ - if(s.length() == i) return sb.toString(); - else { - Trie subTrie = curr.map.get(s.charAt(i)); - if(subTrie == null){ - return curr.map.containsKey(null) ? sb.toString() : ""; - } else { - sb.append(s.charAt(i)); - if(subTrie.map.containsKey(null)) return sb.toString(); - return search(subTrie, s, i + 1, sb); - } - } + private String search(Trie curr, String s, int i, StringBuilder sb) { + if (s.length() == i) return sb.toString(); + else { + Trie subTrie = curr.map.get(s.charAt(i)); + if (subTrie == null) { + return curr.map.containsKey(null) ? sb.toString() : ""; + } else { + sb.append(s.charAt(i)); + if (subTrie.map.containsKey(null)) return sb.toString(); + return search(subTrie, s, i + 1, sb); } + } } + } - /** - * Main method - * @param args - */ - public static void main(String[] args) { - List words = Arrays.asList("a", "aa", "aaa"); - String sentence = "aa aa"; - System.out.println(new ReplaceWords().replaceWords(words, sentence)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + List words = Arrays.asList("a", "aa", "aaa"); + String sentence = "aa aa"; + System.out.println(new ReplaceWords().replaceWords(words, sentence)); + } - public String replaceWords(List dict, String sentence) { - Trie root = new Trie(); - dict.forEach(root::insert); - String[] words = sentence.split(" "); - StringBuilder result = new StringBuilder(); - Stream.of(words).map(w -> {String s = root.find(w); return s.isEmpty() ? w.concat(" ") : - s.concat(" ");}).forEach(result::append); - return result.toString().trim(); - } + public String replaceWords(List dict, String sentence) { + Trie root = new Trie(); + dict.forEach(root::insert); + String[] words = sentence.split(" "); + StringBuilder result = new StringBuilder(); + Stream.of(words) + .map( + w -> { + String s = root.find(w); + return s.isEmpty() ? w.concat(" ") : s.concat(" "); + }) + .forEach(result::append); + return result.toString().trim(); + } } diff --git a/problems/src/string/ReverseWordsII.java b/problems/src/string/ReverseWordsII.java index a948fa7b..7aa9f9c0 100644 --- a/problems/src/string/ReverseWordsII.java +++ b/problems/src/string/ReverseWordsII.java @@ -1,67 +1,65 @@ package string; /** - * Created by gouthamvidyapradhan on 21/03/2017. - * Given an input string, reverse the string word by word. A word is defined as a sequence of non-space characters. - *

- * The input string does not contain leading or trailing spaces and the words are always separated by a single space. - *

- * For example, - * Given s = "the sky is blue", - * return "blue is sky the". - *

- * Could you do it in-place without allocating extra space? + * Created by gouthamvidyapradhan on 21/03/2017. Given an input string, reverse the string word by + * word. A word is defined as a sequence of non-space characters. + * + *

The input string does not contain leading or trailing spaces and the words are always + * separated by a single space. + * + *

For example, Given s = "the sky is blue", return "blue is sky the". + * + *

Could you do it in-place without allocating extra space? */ public class ReverseWordsII { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - char[] c = {'t', 'h', 'e', ' ', 's', 'k', 'y', ' ', 'i', 's', ' ', 'b', 'l', 'u', 'e'}; - new ReverseWordsII().reverseWords(c); - for (char i : c) - System.out.print(i); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + char[] c = {'t', 'h', 'e', ' ', 's', 'k', 'y', ' ', 'i', 's', ' ', 'b', 'l', 'u', 'e'}; + new ReverseWordsII().reverseWords(c); + for (char i : c) System.out.print(i); + } - public void reverseWords(char[] s) { - for (int i = 0, j = s.length - 1; i < j; i++, j--) { - char temp = s[i]; - s[i] = s[j]; - s[j] = temp; + public void reverseWords(char[] s) { + for (int i = 0, j = s.length - 1; i < j; i++, j--) { + char temp = s[i]; + s[i] = s[j]; + s[j] = temp; + } + for (int i = 0, j = 0, l = s.length; i < l; ) { + if (s[i] == ' ') { + if (s[i - 1] == ' ') { + j = i; + i++; + j++; + } else { + i = i - 1; + for (int p = j, q = i; p < q; p++, q--) { + char temp = s[p]; + s[p] = s[q]; + s[q] = temp; + } + i = i + 1; + j = i; + i++; + j++; } - for (int i = 0, j = 0, l = s.length; i < l; ) { - if (s[i] == ' ') { - if (s[i - 1] == ' ') { - j = i; - i++; - j++; - } else { - i = i - 1; - for (int p = j, q = i; p < q; p++, q--) { - char temp = s[p]; - s[p] = s[q]; - s[q] = temp; - } - i = i + 1; - j = i; - i++; - j++; - } - } else if (i == l - 1) { - for (int p = j, q = i; p < q; p++, q--) { - char temp = s[p]; - s[p] = s[q]; - s[q] = temp; - } - j = i; - i++; - j++; - } else { - i++; - } + } else if (i == l - 1) { + for (int p = j, q = i; p < q; p++, q--) { + char temp = s[p]; + s[p] = s[q]; + s[q] = temp; } + j = i; + i++; + j++; + } else { + i++; + } } + } } diff --git a/problems/src/string/ReverseWordsInAString.java b/problems/src/string/ReverseWordsInAString.java index a29b6850..e930ab84 100644 --- a/problems/src/string/ReverseWordsInAString.java +++ b/problems/src/string/ReverseWordsInAString.java @@ -5,45 +5,39 @@ import java.util.StringTokenizer; /** - * Created by gouthamvidyapradhan on 04/07/2017. - * Given an input string, reverse the string word by word. - *

- * For example, - * Given s = "the sky is blue", - * return "blue is sky the". - *

- * Clarification: - * What constitutes a word? - * A sequence of non-space characters constitutes a word. - * Could the input string contain leading or trailing spaces? - * Yes. However, your reversed string should not contain leading or trailing spaces. - * How about multiple spaces between two words? + * Created by gouthamvidyapradhan on 04/07/2017. Given an input string, reverse the string word by + * word. + * + *

For example, Given s = "the sky is blue", return "blue is sky the". + * + *

Clarification: What constitutes a word? A sequence of non-space characters constitutes a word. + * Could the input string contain leading or trailing spaces? Yes. However, your reversed string + * should not contain leading or trailing spaces. How about multiple spaces between two words? * Reduce them to a single space in the reversed string. */ public class ReverseWordsInAString { - public static void main(String[] args) throws Exception { - System.out.println(new ReverseWordsInAString().reverseWords(" the sky is blue")); - } + public static void main(String[] args) throws Exception { + System.out.println(new ReverseWordsInAString().reverseWords(" the sky is blue")); + } - public String reverseWords(String s) { - if (s == null || s.isEmpty()) return ""; - StringBuilder sb = new StringBuilder(s.trim()); - String reverse = sb.reverse().toString(); - StringTokenizer st = new StringTokenizer(reverse, " "); - List list = new ArrayList<>(); - while (st.hasMoreTokens()) { - list.add(st.nextToken()); - } - for (int i = 0, l = list.size(); i < l; i++) { - String str = list.get(i); - String newStr = new StringBuilder(str).reverse().toString(); - list.set(i, newStr); - } - StringBuilder result = new StringBuilder(); - for (String str : list) { - result.append(str).append(" "); - } - return result.toString().trim(); + public String reverseWords(String s) { + if (s == null || s.isEmpty()) return ""; + StringBuilder sb = new StringBuilder(s.trim()); + String reverse = sb.reverse().toString(); + StringTokenizer st = new StringTokenizer(reverse, " "); + List list = new ArrayList<>(); + while (st.hasMoreTokens()) { + list.add(st.nextToken()); } - + for (int i = 0, l = list.size(); i < l; i++) { + String str = list.get(i); + String newStr = new StringBuilder(str).reverse().toString(); + list.set(i, newStr); + } + StringBuilder result = new StringBuilder(); + for (String str : list) { + result.append(str).append(" "); + } + return result.toString().trim(); + } } diff --git a/problems/src/string/RotateString.java b/problems/src/string/RotateString.java index 2811d539..02978688 100644 --- a/problems/src/string/RotateString.java +++ b/problems/src/string/RotateString.java @@ -1,45 +1,40 @@ package string; /** - * Created by gouthamvidyapradhan on 28/03/2019 - * We are given two strings, A and B. + * Created by gouthamvidyapradhan on 28/03/2019 We are given two strings, A and B. * - * A shift on A consists of taking string A and moving the leftmost character to the rightmost position. For - * example, if A = 'abcde', then it will be 'bcdea' after one shift on A. Return True if and only if A can become B - * after some number of shifts on A. + *

A shift on A consists of taking string A and moving the leftmost character to the rightmost + * position. For example, if A = 'abcde', then it will be 'bcdea' after one shift on A. Return True + * if and only if A can become B after some number of shifts on A. * - * Example 1: - * Input: A = 'abcde', B = 'cdeab' - * Output: true + *

Example 1: Input: A = 'abcde', B = 'cdeab' Output: true * - * Example 2: - * Input: A = 'abcde', B = 'abced' - * Output: false - * Note: + *

Example 2: Input: A = 'abcde', B = 'abced' Output: false Note: * - * A and B will have length at most 100. + *

A and B will have length at most 100. */ public class RotateString { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - System.out.println(new RotateString().rotateString("abcde", "cdeab")); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + System.out.println(new RotateString().rotateString("abcde", "cdeab")); + } - public boolean rotateString(String A, String B) { - if(A.length() == 1 || A.isEmpty() || B.length() == 1 || B.isEmpty()) { - return A.equals(B); - } else if(A.length() != B.length()){ - return false; - } - for(int i = 0, l = A.length(); i < l; i ++){ - char s = A.charAt(0); - A = A.substring(1) + s; - if(A.equals(B)) return true; - } - return false; + public boolean rotateString(String A, String B) { + if (A.length() == 1 || A.isEmpty() || B.length() == 1 || B.isEmpty()) { + return A.equals(B); + } else if (A.length() != B.length()) { + return false; + } + for (int i = 0, l = A.length(); i < l; i++) { + char s = A.charAt(0); + A = A.substring(1) + s; + if (A.equals(B)) return true; } + return false; + } } diff --git a/problems/src/string/ShortestPalindrome.java b/problems/src/string/ShortestPalindrome.java index 6b07e66b..66df78de 100644 --- a/problems/src/string/ShortestPalindrome.java +++ b/problems/src/string/ShortestPalindrome.java @@ -3,59 +3,57 @@ /** * Created by gouthamvidyapradhan on 21/07/2018. * - * Given a string s, you are allowed to convert it to a palindrome by adding characters in front of it. Find and - * return the shortest palindrome you can find by performing this transformation. - - Example 1: - - Input: "aacecaaa" - Output: "aaacecaaa" - Example 2: - - Input: "abcd" - Output: "dcbabcd" - - Solution: O(N ^ 2): for i : (s.length() - 1 -> 0) check if (0, i) is a paliandrome, if not append char at i to - result string else return string (result + (0, i)) + *

Given a string s, you are allowed to convert it to a palindrome by adding characters in front + * of it. Find and return the shortest palindrome you can find by performing this transformation. + * + *

Example 1: + * + *

Input: "aacecaaa" Output: "aaacecaaa" Example 2: + * + *

Input: "abcd" Output: "dcbabcd" + * + *

Solution: O(N ^ 2): for i : (s.length() - 1 -> 0) check if (0, i) is a paliandrome, if not + * append char at i to result string else return string (result + (0, i)) */ public class ShortestPalindrome { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new ShortestPalindrome().shortestPalindrome("aaaaaaaaaa")); + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new ShortestPalindrome().shortestPalindrome("aaaaaaaaaa")); + } + + public String shortestPalindrome(String s) { + if (s.length() == 0 || s.length() == 1) { + return s; + } else if (s.length() == 2) { + if (s.charAt(0) == s.charAt(1)) { + return s; + } else { + return (s.charAt(1) + s); + } } - - public String shortestPalindrome(String s) { - if(s.length() == 0 || s.length() == 1){ - return s; - } else if(s.length() == 2){ - if(s.charAt(0) == s.charAt(1)){ - return s; - } else{ - return (s.charAt(1) + s); - } - } - if(isPaliandrome(s, 0, s.length() - 1)) return s; - StringBuilder sb = new StringBuilder(""); - for(int i = 0, j = s.length() - 1; j >= i; j--){ - if(!isPaliandrome(s, i, j)){ - sb.append(s.charAt(j)); - } else{ - sb.append(s.substring(0, s.length())); - break; - } - } - return sb.toString(); + if (isPaliandrome(s, 0, s.length() - 1)) return s; + StringBuilder sb = new StringBuilder(""); + for (int i = 0, j = s.length() - 1; j >= i; j--) { + if (!isPaliandrome(s, i, j)) { + sb.append(s.charAt(j)); + } else { + sb.append(s.substring(0, s.length())); + break; + } } + return sb.toString(); + } - boolean isPaliandrome(String s, int x, int y){ - for(int i = x, j = y; i < j; i++, j--){ - if(s.charAt(i) != s.charAt(j)) return false; - } - return true; + boolean isPaliandrome(String s, int x, int y) { + for (int i = x, j = y; i < j; i++, j--) { + if (s.charAt(i) != s.charAt(j)) return false; } + return true; + } } diff --git a/problems/src/string/SimplifyPath.java b/problems/src/string/SimplifyPath.java index 7905249d..e500171f 100644 --- a/problems/src/string/SimplifyPath.java +++ b/problems/src/string/SimplifyPath.java @@ -6,50 +6,43 @@ /** * Created by gouthamvidyapradhan on 28/07/2017. - *

- * Given an absolute path for a file (Unix-style), simplify it. - *

- * For example, - * path = "/home/", => "/home" - * path = "/a/./b/../../c/", => "/c" - *

- * Corner Cases: - * Did you consider the case where path = "/../"? - * In this case, you should return "/". - * Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/". - * In this case, you should ignore redundant slashes and return "/home/foo". + * + *

Given an absolute path for a file (Unix-style), simplify it. + * + *

For example, path = "/home/", => "/home" path = "/a/./b/../../c/", => "/c" + * + *

Corner Cases: Did you consider the case where path = "/../"? In this case, you should return + * "/". Another corner case is the path might contain multiple slashes '/' together, such as + * "/home//foo/". In this case, you should ignore redundant slashes and return "/home/foo". */ public class SimplifyPath { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new SimplifyPath().simplifyPath("/home/")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new SimplifyPath().simplifyPath("/home/")); + } - public String simplifyPath(String path) { - if (path == null || path.isEmpty()) return "/"; - StringTokenizer st = new StringTokenizer(path, "/"); - Deque dQueue = new ArrayDeque<>(); - while (st.hasMoreTokens()) { - String token = st.nextToken(); - if (token.trim().equals("..")) { - if (!dQueue.isEmpty()) - dQueue.pop(); - } else if (token.trim().equals(".")) { - //ignore - } else dQueue.push(token); - } - if (dQueue.isEmpty()) return "/"; - StringBuilder finalStr = new StringBuilder(); - while (!dQueue.isEmpty()) { - finalStr.append("/").append(dQueue.removeLast()); - } - return finalStr.toString(); + public String simplifyPath(String path) { + if (path == null || path.isEmpty()) return "/"; + StringTokenizer st = new StringTokenizer(path, "/"); + Deque dQueue = new ArrayDeque<>(); + while (st.hasMoreTokens()) { + String token = st.nextToken(); + if (token.trim().equals("..")) { + if (!dQueue.isEmpty()) dQueue.pop(); + } else if (token.trim().equals(".")) { + // ignore + } else dQueue.push(token); } - - + if (dQueue.isEmpty()) return "/"; + StringBuilder finalStr = new StringBuilder(); + while (!dQueue.isEmpty()) { + finalStr.append("/").append(dQueue.removeLast()); + } + return finalStr.toString(); + } } diff --git a/problems/src/string/StringCompression.java b/problems/src/string/StringCompression.java index 8c88c805..160afa09 100644 --- a/problems/src/string/StringCompression.java +++ b/problems/src/string/StringCompression.java @@ -1,95 +1,80 @@ package string; /** - * Created by gouthamvidyapradhan on 12/04/2018. - * Given an array of characters, compress it in-place. - - The length after compression must always be smaller than or equal to the original array. - - Every element of the array should be a character (not int) of length 1. - - After you are done modifying the input array in-place, return the new length of the array. - - - Follow up: - Could you solve it using only O(1) extra space? - - - Example 1: - Input: - ["a","a","b","b","c","c","c"] - - Output: - Return 6, and the first 6 characters of the input array should be: ["a","2","b","2","c","3"] - - Explanation: - "aa" is replaced by "a2". "bb" is replaced by "b2". "ccc" is replaced by "c3". - Example 2: - Input: - ["a"] - - Output: - Return 1, and the first 1 characters of the input array should be: ["a"] - - Explanation: - Nothing is replaced. - Example 3: - Input: - ["a","b","b","b","b","b","b","b","b","b","b","b","b"] - - Output: - Return 4, and the first 4 characters of the input array should be: ["a","b","1","2"]. - - Explanation: - Since the character "a" does not repeat, it is not compressed. "bbbbbbbbbbbb" is replaced by "b12". - Notice each digit has it's own entry in the array. - Note: - All characters have an ASCII value in [35, 126]. - 1 <= len(chars) <= 1000. - - Solution O(N) time complexity and O(1) space complexity. Maintain read and write pointers. Read from read pointer and - increment count when a repetition is found, when there is no repetition write the count value using write pointer. + * Created by gouthamvidyapradhan on 12/04/2018. Given an array of characters, compress it in-place. + * + *

The length after compression must always be smaller than or equal to the original array. + * + *

Every element of the array should be a character (not int) of length 1. + * + *

After you are done modifying the input array in-place, return the new length of the array. + * + *

Follow up: Could you solve it using only O(1) extra space? + * + *

Example 1: Input: ["a","a","b","b","c","c","c"] + * + *

Output: Return 6, and the first 6 characters of the input array should be: + * ["a","2","b","2","c","3"] + * + *

Explanation: "aa" is replaced by "a2". "bb" is replaced by "b2". "ccc" is replaced by "c3". + * Example 2: Input: ["a"] + * + *

Output: Return 1, and the first 1 characters of the input array should be: ["a"] + * + *

Explanation: Nothing is replaced. Example 3: Input: + * ["a","b","b","b","b","b","b","b","b","b","b","b","b"] + * + *

Output: Return 4, and the first 4 characters of the input array should be: ["a","b","1","2"]. + * + *

Explanation: Since the character "a" does not repeat, it is not compressed. "bbbbbbbbbbbb" is + * replaced by "b12". Notice each digit has it's own entry in the array. Note: All characters have + * an ASCII value in [35, 126]. 1 <= len(chars) <= 1000. + * + *

Solution O(N) time complexity and O(1) space complexity. Maintain read and write pointers. + * Read from read pointer and increment count when a repetition is found, when there is no + * repetition write the count value using write pointer. */ public class StringCompression { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - char[] A = {'a','a','b','b','c','c','c'}; - System.out.println(new StringCompression().compress(A)); - } - - public int compress(char[] chars) { - int count = 0; - int i = 0; - int p = 0; - for(int j = 0; j < chars.length; j ++){ - if(chars[i] == chars[j]){ - count ++; - } else{ - chars[p] = chars[i]; - p++; - if(count > 1){ - String countStr = String.valueOf(count); - for (int l = 0; l < countStr.length(); l++){ - chars[p++] = countStr.charAt(l); - } - } - i = j; - count = 1; - } - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + char[] A = {'a', 'a', 'b', 'b', 'c', 'c', 'c'}; + System.out.println(new StringCompression().compress(A)); + } + + public int compress(char[] chars) { + int count = 0; + int i = 0; + int p = 0; + for (int j = 0; j < chars.length; j++) { + if (chars[i] == chars[j]) { + count++; + } else { chars[p] = chars[i]; p++; - if(count > 1){ - String countStr = String.valueOf(count); - for (int l = 0; l < countStr.length(); l++){ - chars[p++] = countStr.charAt(l); - } + if (count > 1) { + String countStr = String.valueOf(count); + for (int l = 0; l < countStr.length(); l++) { + chars[p++] = countStr.charAt(l); + } } - return p; + i = j; + count = 1; + } + } + chars[p] = chars[i]; + p++; + if (count > 1) { + String countStr = String.valueOf(count); + for (int l = 0; l < countStr.length(); l++) { + chars[p++] = countStr.charAt(l); + } } + return p; + } } diff --git a/problems/src/string/StringToInteger.java b/problems/src/string/StringToInteger.java index f9d790b0..da4e8235 100644 --- a/problems/src/string/StringToInteger.java +++ b/problems/src/string/StringToInteger.java @@ -1,57 +1,53 @@ package string; /** - * Created by gouthamvidyapradhan on 21/03/2017. - * Implement atoi to convert a string to an integer. - *

- * Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases. - *

- * Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front. + * Created by gouthamvidyapradhan on 21/03/2017. Implement atoi to convert a string to an integer. + * + *

Hint: Carefully consider all possible input cases. If you want a challenge, please do not see + * below and ask yourself what are the possible input cases. + * + *

Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You + * are responsible to gather all the input requirements up front. */ public class StringToInteger { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new StringToInteger().myAtoi(" 2147483649a sdfasdf")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new StringToInteger().myAtoi(" 2147483649a sdfasdf")); + } - public int myAtoi(String str) { - boolean isPositive = true; - if (str == null || str.trim().isEmpty()) return 0; - str = str.trim(); - if (str.charAt(0) == '+') { - isPositive = true; - str = str.substring(1, str.length()); - } else if (str.charAt(0) == '-') { - isPositive = false; - str = str.substring(1, str.length()); - } else if (str.charAt(0) > '9' || str.charAt(0) < '0') - return 0; - int i = 0; - for (int l = str.length(); i < l; i++) { - if (str.charAt(i) > '9' || str.charAt(i) < '0') - break; - } - str = str.substring(0, i); - long num = 0; - for (int j = 0, l = str.length(); j < l; j++) { - int n = (str.charAt(j) - '0'); - num *= 10; - num += n; - if (isPositive) { - if (num > Integer.MAX_VALUE) return Integer.MAX_VALUE; - } else { - if ((num * -1) < Integer.MIN_VALUE) return Integer.MIN_VALUE; - } - } - if (isPositive) - return (int) num; - else return (int) (num * -1); + public int myAtoi(String str) { + boolean isPositive = true; + if (str == null || str.trim().isEmpty()) return 0; + str = str.trim(); + if (str.charAt(0) == '+') { + isPositive = true; + str = str.substring(1, str.length()); + } else if (str.charAt(0) == '-') { + isPositive = false; + str = str.substring(1, str.length()); + } else if (str.charAt(0) > '9' || str.charAt(0) < '0') return 0; + int i = 0; + for (int l = str.length(); i < l; i++) { + if (str.charAt(i) > '9' || str.charAt(i) < '0') break; } - - + str = str.substring(0, i); + long num = 0; + for (int j = 0, l = str.length(); j < l; j++) { + int n = (str.charAt(j) - '0'); + num *= 10; + num += n; + if (isPositive) { + if (num > Integer.MAX_VALUE) return Integer.MAX_VALUE; + } else { + if ((num * -1) < Integer.MIN_VALUE) return Integer.MIN_VALUE; + } + } + if (isPositive) return (int) num; + else return (int) (num * -1); + } } diff --git a/problems/src/string/TextJustification.java b/problems/src/string/TextJustification.java index 74c35307..e17b5b13 100644 --- a/problems/src/string/TextJustification.java +++ b/problems/src/string/TextJustification.java @@ -4,83 +4,77 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 09/03/2017. - * Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified. - *

- * You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly L characters. - *

- * Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right. - *

- * For the last line of text, it should be left justified and no extra space is inserted between words. - *

- * For example, - * words: ["This", "is", "an", "example", "of", "text", "justification."] - * L: 16. - *

- * Return the formatted lines as: - * [ - * "This is an", - * "example of text", - * "justification. " - * ] - * Note: Each word is guaranteed not to exceed L in length. + * Created by gouthamvidyapradhan on 09/03/2017. Given an array of words and a length L, format the + * text such that each line has exactly L characters and is fully (left and right) justified. + * + *

You should pack your words in a greedy approach; that is, pack as many words as you can in + * each line. Pad extra spaces ' ' when necessary so that each line has exactly L characters. + * + *

Extra spaces between words should be distributed as evenly as possible. If the number of + * spaces on a line do not divide evenly between words, the empty slots on the left will be assigned + * more spaces than the slots on the right. + * + *

For the last line of text, it should be left justified and no extra space is inserted between + * words. + * + *

For example, words: ["This", "is", "an", "example", "of", "text", "justification."] L: 16. + * + *

Return the formatted lines as: [ "This is an", "example of text", "justification. " ] Note: + * Each word is guaranteed not to exceed L in length. */ public class TextJustification { - public List fullJustify(String[] words, int L) { - int wCount = 0, charCount = 0; - List line = new ArrayList<>(); - List result = new ArrayList<>(); - StringBuilder sb = new StringBuilder(); + public List fullJustify(String[] words, int L) { + int wCount = 0, charCount = 0; + List line = new ArrayList<>(); + List result = new ArrayList<>(); + StringBuilder sb = new StringBuilder(); - for (int i = 0, l = words.length; i < l; i++) { - String next = words[i]; - if ((L - (charCount + wCount)) >= next.length()) { - line.add(next); - charCount += next.length(); - wCount++; - } else { - //justify and add to list - sb.append(line.get(0)); - StringBuilder space = new StringBuilder(); - if (line.size() > 1) { - int spaceCount = (L - charCount) / (wCount - 1); - int remaining = (L - charCount) % (wCount - 1); + for (int i = 0, l = words.length; i < l; i++) { + String next = words[i]; + if ((L - (charCount + wCount)) >= next.length()) { + line.add(next); + charCount += next.length(); + wCount++; + } else { + // justify and add to list + sb.append(line.get(0)); + StringBuilder space = new StringBuilder(); + if (line.size() > 1) { + int spaceCount = (L - charCount) / (wCount - 1); + int remaining = (L - charCount) % (wCount - 1); - for (int j = 0; j < spaceCount; j++) - space.append(' '); + for (int j = 0; j < spaceCount; j++) space.append(' '); - for (int k = 1, kl = line.size(); k < kl; k++) { - sb.append(space); - if (remaining > 0) { - sb.append(' '); - --remaining; - } - sb.append(line.get(k)); - } - } else { - int balance = L - (charCount + (wCount - 1)); - for (int j = 0; j < balance; j++) - sb.append(' '); - } - result.add(sb.toString()); - sb = new StringBuilder(); - line.clear(); - line.add(next); - charCount = next.length(); - wCount = 1; + for (int k = 1, kl = line.size(); k < kl; k++) { + sb.append(space); + if (remaining > 0) { + sb.append(' '); + --remaining; } + sb.append(line.get(k)); + } + } else { + int balance = L - (charCount + (wCount - 1)); + for (int j = 0; j < balance; j++) sb.append(' '); } - if (!line.isEmpty()) { - sb.append(line.get(0)); - for (int i = 1, l = line.size(); i < l; i++) { - sb.append(' '); - sb.append(line.get(i)); - } - } - int balance = L - (charCount + (wCount - 1)); - for (int i = 0; i < balance; i++) - sb.append(' '); result.add(sb.toString()); - return result; + sb = new StringBuilder(); + line.clear(); + line.add(next); + charCount = next.length(); + wCount = 1; + } + } + if (!line.isEmpty()) { + sb.append(line.get(0)); + for (int i = 1, l = line.size(); i < l; i++) { + sb.append(' '); + sb.append(line.get(i)); + } } + int balance = L - (charCount + (wCount - 1)); + for (int i = 0; i < balance; i++) sb.append(' '); + result.add(sb.toString()); + return result; + } } diff --git a/problems/src/string/ValidPalindrome.java b/problems/src/string/ValidPalindrome.java index 3144d001..7295d3cd 100644 --- a/problems/src/string/ValidPalindrome.java +++ b/problems/src/string/ValidPalindrome.java @@ -1,43 +1,40 @@ package string; /** - * Created by gouthamvidyapradhan on 13/07/2017. - * Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. - *

- * For example, - * "A man, a plan, a canal: Panama" is a palindrome. - * "race a car" is not a palindrome. - *

- * Note: - * Have you consider that the string might be empty? This is a good question to ask during an interview. - *

- * For the purpose of this problem, we define empty string as valid palindrome. + * Created by gouthamvidyapradhan on 13/07/2017. Given a string, determine if it is a palindrome, + * considering only alphanumeric characters and ignoring cases. + * + *

For example, "A man, a plan, a canal: Panama" is a palindrome. "race a car" is not a + * palindrome. + * + *

Note: Have you consider that the string might be empty? This is a good question to ask during + * an interview. + * + *

For the purpose of this problem, we define empty string as valid palindrome. */ public class ValidPalindrome { - public static void main(String[] args) throws Exception { - System.out.println(new ValidPalindrome().isPalindrome("989 ")); - } + public static void main(String[] args) throws Exception { + System.out.println(new ValidPalindrome().isPalindrome("989 ")); + } - public boolean isPalindrome(String s) { - if (s == null || s.isEmpty()) return true; - s = s.toLowerCase(); - for (int i = 0, j = s.length() - 1; i < j; ) { - char f = s.charAt(i); - char l = s.charAt(j); - if (!(f >= 'a' && f <= 'z') && !(f >= '0' && f <= '9')) { - i++; - continue; - } - if (!(l >= 'a' && l <= 'z') && !(l >= '0' && l <= '9')) { - j--; - continue; - } - if (f != l) - return false; - i++; - j--; - } - return true; + public boolean isPalindrome(String s) { + if (s == null || s.isEmpty()) return true; + s = s.toLowerCase(); + for (int i = 0, j = s.length() - 1; i < j; ) { + char f = s.charAt(i); + char l = s.charAt(j); + if (!(f >= 'a' && f <= 'z') && !(f >= '0' && f <= '9')) { + i++; + continue; + } + if (!(l >= 'a' && l <= 'z') && !(l >= '0' && l <= '9')) { + j--; + continue; + } + if (f != l) return false; + i++; + j--; } - + return true; + } } diff --git a/problems/src/string/ValidPalindromeII.java b/problems/src/string/ValidPalindromeII.java index b652e70f..2cc37d09 100644 --- a/problems/src/string/ValidPalindromeII.java +++ b/problems/src/string/ValidPalindromeII.java @@ -1,47 +1,44 @@ package string; /** - * Created by gouthamvidyapradhan on 09/12/2017. - * Given a non-empty string s, you may delete at most one character. Judge whether you can make it a palindrome. - - Example 1: - Input: "aba" - Output: True - Example 2: - Input: "abca" - Output: True - Explanation: You could delete the character 'c'. - Note: - The string will only contain lowercase characters a-z. The maximum length of the string is 50000. + * Created by gouthamvidyapradhan on 09/12/2017. Given a non-empty string s, you may delete at most + * one character. Judge whether you can make it a palindrome. + * + *

Example 1: Input: "aba" Output: True Example 2: Input: "abca" Output: True Explanation: You + * could delete the character 'c'. Note: The string will only contain lowercase characters a-z. The + * maximum length of the string is 50000. */ public class ValidPalindromeII { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new ValidPalindromeII().validPalindrome("aaaaaab")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new ValidPalindromeII().validPalindrome("aaaaaab")); + } - public boolean validPalindrome(String s) { - for(int i = 0, j = s.length() - 1; i < j;){ - if(s.charAt(i) == s.charAt(j)){ - i++; j--; - } else { - return isPaliandrome(s.substring(i, j)) || isPaliandrome(s.substring(i + 1, j + 1)); - } - } - return true; + public boolean validPalindrome(String s) { + for (int i = 0, j = s.length() - 1; i < j; ) { + if (s.charAt(i) == s.charAt(j)) { + i++; + j--; + } else { + return isPaliandrome(s.substring(i, j)) || isPaliandrome(s.substring(i + 1, j + 1)); + } } + return true; + } - private boolean isPaliandrome(String s){ - for(int i = 0, j = s.length() - 1; i < j;){ - if(s.charAt(i) == s.charAt(j)){ - i++; j--; - } else return false; - } - return true; + private boolean isPaliandrome(String s) { + for (int i = 0, j = s.length() - 1; i < j; ) { + if (s.charAt(i) == s.charAt(j)) { + i++; + j--; + } else return false; } + return true; + } } diff --git a/problems/src/string/ValidWordAbbreviation.java b/problems/src/string/ValidWordAbbreviation.java index e3653943..bf5dfbae 100644 --- a/problems/src/string/ValidWordAbbreviation.java +++ b/problems/src/string/ValidWordAbbreviation.java @@ -1,73 +1,70 @@ package string; /** - * Created by gouthamvidyapradhan on 20/03/2019 - * Given a non-empty string s and an abbreviation abbr, return whether the string matches with the given abbreviation. + * Created by gouthamvidyapradhan on 20/03/2019 Given a non-empty string s and an abbreviation abbr, + * return whether the string matches with the given abbreviation. * - * A string such as "word" contains only the following valid abbreviations: + *

A string such as "word" contains only the following valid abbreviations: * - * ["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"] - * Notice that only the above abbreviations are valid abbreviations of the string "word". Any other string is not a - * valid abbreviation of "word". + *

["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", + * "2r1", "3d", "w3", "4"] Notice that only the above abbreviations are valid abbreviations of the + * string "word". Any other string is not a valid abbreviation of "word". * - * Note: - * Assume s contains only lowercase letters and abbr contains only lowercase letters and digits. + *

Note: Assume s contains only lowercase letters and abbr contains only lowercase letters and + * digits. * - * Example 1: - * Given s = "internationalization", abbr = "i12iz4n": + *

Example 1: Given s = "internationalization", abbr = "i12iz4n": * - * Return true. - * Example 2: - * Given s = "apple", abbr = "a2e": + *

Return true. Example 2: Given s = "apple", abbr = "a2e": * - * Return false. + *

Return false. */ - public class ValidWordAbbreviation { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - System.out.println(new ValidWordAbbreviation().validWordAbbreviation("abbreviation", "a10n")); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + System.out.println(new ValidWordAbbreviation().validWordAbbreviation("abbreviation", "a10n")); + } - public boolean validWordAbbreviation(String word, String abbr) { - if(abbr.length() > word.length()) return false; - StringBuilder num = new StringBuilder(); - int j = 0; - for(int i = 0; i < abbr.length() && j < word.length(); i ++){ - char curr = abbr.charAt(i); - if(curr == '0' && num.toString().isEmpty()) return false; - if(curr >= '0' && curr <= '9'){ - num.append(curr); - } else{ - if(num.toString().isEmpty()){ - if(word.charAt(j) != abbr.charAt(i)){ - return false; - } - j++; - } else{ - int next = Integer.parseInt(num.toString()); - j += next; - if(word.length() <= j){ - return false; - } - if(word.charAt(j) != abbr.charAt(i)){ - return false; - } - num = new StringBuilder(); - j++; - } - } + public boolean validWordAbbreviation(String word, String abbr) { + if (abbr.length() > word.length()) return false; + StringBuilder num = new StringBuilder(); + int j = 0; + for (int i = 0; i < abbr.length() && j < word.length(); i++) { + char curr = abbr.charAt(i); + if (curr == '0' && num.toString().isEmpty()) return false; + if (curr >= '0' && curr <= '9') { + num.append(curr); + } else { + if (num.toString().isEmpty()) { + if (word.charAt(j) != abbr.charAt(i)) { + return false; + } + j++; + } else { + int next = Integer.parseInt(num.toString()); + j += next; + if (word.length() <= j) { + return false; + } + if (word.charAt(j) != abbr.charAt(i)) { + return false; + } + num = new StringBuilder(); + j++; } - if(!num.toString().isEmpty()){ - int next = Integer.parseInt(num.toString()); - j += next; - if(j > word.length() || j < word.length()){ - return false; - } - } - return true; + } + } + if (!num.toString().isEmpty()) { + int next = Integer.parseInt(num.toString()); + j += next; + if (j > word.length() || j < word.length()) { + return false; + } } + return true; + } } diff --git a/problems/src/string/ZigZagConversion.java b/problems/src/string/ZigZagConversion.java index f88c9aff..5867fba1 100644 --- a/problems/src/string/ZigZagConversion.java +++ b/problems/src/string/ZigZagConversion.java @@ -5,68 +5,64 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 19/05/2017. - * The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) - *

- * P A H N - * A P L S I I G - * Y I R - * And then read line by line: "PAHNAPLSIIGYIR" - * Write the code that will take a string and make this conversion given a number of rows: - *

- * string convert(string text, int nRows); - * convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR". + * Created by gouthamvidyapradhan on 19/05/2017. The string "PAYPALISHIRING" is written in a zigzag + * pattern on a given number of rows like this: (you may want to display this pattern in a fixed + * font for better legibility) + * + *

P A H N A P L S I I G Y I R And then read line by line: "PAHNAPLSIIGYIR" Write the code that + * will take a string and make this conversion given a number of rows: + * + *

string convert(string text, int nRows); convert("PAYPALISHIRING", 3) should return + * "PAHNAPLSIIGYIR". */ public class ZigZagConversion { - /** - * Main method - * - * @param args - */ - public static void main(String[] args) { - System.out.println(new ZigZagConversion().convert("PAYPALISHIRING", 5)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + System.out.println(new ZigZagConversion().convert("PAYPALISHIRING", 5)); + } - /** - * Convert and return the result - * - * @param s input string - * @param numRows max rows - * @return Result string - */ - public String convert(String s, int numRows) { - if (s == null || s.length() <= numRows || numRows == 1) return s; - List list = new ArrayList<>(); - char[] A = new char[numRows]; - int direction = 1; // 1 indicates forward, 0 indicates backwards - int n = 1; - A[0] = s.charAt(0); - for (int j = 1; j < numRows; ) { - if (n >= s.length()) break; - A[j] = s.charAt(n++); - if (j == numRows - 1) { - list.add(String.valueOf(A)); - A = new char[numRows]; - Arrays.fill(A, ' '); - direction = 0; - } else if (j == 0) { - list.add(String.valueOf(A)); - A = new char[numRows]; - Arrays.fill(A, ' '); - direction = 1; - } - j = direction == 1 ? j + 1 : j - 1; - } - if (!String.valueOf(A).trim().isEmpty()) - list.add(String.valueOf(A)); - char[] arr = new char[s.length()]; - int k = 0; - for (int j = 0; j < numRows; j++) { - for (String aList : list) { - if (aList.charAt(j) != ' ') - arr[k++] = aList.charAt(j); - } - } - return new String(arr).trim(); + /** + * Convert and return the result + * + * @param s input string + * @param numRows max rows + * @return Result string + */ + public String convert(String s, int numRows) { + if (s == null || s.length() <= numRows || numRows == 1) return s; + List list = new ArrayList<>(); + char[] A = new char[numRows]; + int direction = 1; // 1 indicates forward, 0 indicates backwards + int n = 1; + A[0] = s.charAt(0); + for (int j = 1; j < numRows; ) { + if (n >= s.length()) break; + A[j] = s.charAt(n++); + if (j == numRows - 1) { + list.add(String.valueOf(A)); + A = new char[numRows]; + Arrays.fill(A, ' '); + direction = 0; + } else if (j == 0) { + list.add(String.valueOf(A)); + A = new char[numRows]; + Arrays.fill(A, ' '); + direction = 1; + } + j = direction == 1 ? j + 1 : j - 1; + } + if (!String.valueOf(A).trim().isEmpty()) list.add(String.valueOf(A)); + char[] arr = new char[s.length()]; + int k = 0; + for (int j = 0; j < numRows; j++) { + for (String aList : list) { + if (aList.charAt(j) != ' ') arr[k++] = aList.charAt(j); + } } + return new String(arr).trim(); + } } diff --git a/problems/src/test/MyList.java b/problems/src/test/MyList.java deleted file mode 100644 index 2a442251..00000000 --- a/problems/src/test/MyList.java +++ /dev/null @@ -1,20 +0,0 @@ -package test; - -/** - * Created by gouthamvidyapradhan on 05/05/2018. - */ -import java.util.*; -public class MyList { - - private static final int[] R = {0, 0, 1, -1}; - private static final int[] C = {1, -1, 0, 0}; - private boolean[][] done; - //private Set done; - - public static void main(String[] args) { - - } - - - -} diff --git a/problems/src/tomtom/Solution1.java b/problems/src/tomtom/Solution1.java deleted file mode 100644 index 2c0730f5..00000000 --- a/problems/src/tomtom/Solution1.java +++ /dev/null @@ -1,11 +0,0 @@ -package tomtom; - -import java.util.Stack; - -/** - * Created by gouthamvidyapradhan on 03/10/2017. - */ -public class Solution1 { - public static void main(String[] args) throws Exception{ - } -} diff --git a/problems/src/tree/AllNodesDistanceKInBinaryTree.java b/problems/src/tree/AllNodesDistanceKInBinaryTree.java index f74e40ba..e65c19f0 100644 --- a/problems/src/tree/AllNodesDistanceKInBinaryTree.java +++ b/problems/src/tree/AllNodesDistanceKInBinaryTree.java @@ -1,126 +1,115 @@ package tree; + import java.util.*; + /** - * Created by gouthamvidyapradhan on 26/04/2019 - * We are given a binary tree (with root node root), a target node, and an integer value K. - * - * Return a list of the values of all nodes that have a distance K from the target node. The answer can be returned - * in any order. - * - * + * Created by gouthamvidyapradhan on 26/04/2019 We are given a binary tree (with root node root), a + * target node, and an integer value K. * - * Example 1: + *

Return a list of the values of all nodes that have a distance K from the target node. The + * answer can be returned in any order. * - * Input: root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, K = 2 + *

Example 1: * - * Output: [7,4,1] + *

Input: root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, K = 2 * - * 3 - * / \ - * 5 1 - * / \ / \ - * 6 2 0 8 - * / \ - * 7 4 - * Explanation: - * The nodes that are a distance 2 from the target node (with value 5) - * have values 7, 4, and 1. + *

Output: [7,4,1] * + *

3 / \ 5 1 / \ / \ 6 2 0 8 / \ 7 4 Explanation: The nodes that are a distance 2 from the target + * node (with value 5) have values 7, 4, and 1. * + *

Note that the inputs "root" and "target" are actually TreeNodes. The descriptions of the + * inputs above are just serializations of these objects. * - * Note that the inputs "root" and "target" are actually TreeNodes. - * The descriptions of the inputs above are just serializations of these objects. + *

Note: * + *

The given tree is non-empty. Each node in the tree has unique values 0 <= node.val <= 500. The + * target node is a node in the tree. 0 <= K <= 1000. * - * Note: - * - * The given tree is non-empty. - * Each node in the tree has unique values 0 <= node.val <= 500. - * The target node is a node in the tree. - * 0 <= K <= 1000. - * - * Solution: O(N) - * The general intuition is as below. - * All the nodes from which a target nodes can be reached (including the target node) can have child nodes at a - * distance of K from target node. All the nodes from which a target node cannot be reached definitely cannot have a - * child node at a distance of K from target node. - * Do a dfs from root to find the target node. As soon as a target node is found, all the nodes in the - * recursion stack are the ancestors of target node i.e the target node can be reached from each of these - * nodes. Now do another dfs from each of the nodes starting from target node and all its ancestors up to - * the root to find nodes at a distance of (K - dk) where dk is the distance to the target node. - * Keep track of visited nodes in order not to revisit the same node once again. + *

Solution: O(N) The general intuition is as below. All the nodes from which a target nodes can + * be reached (including the target node) can have child nodes at a distance of K from target node. + * All the nodes from which a target node cannot be reached definitely cannot have a child node at a + * distance of K from target node. Do a dfs from root to find the target node. As soon as a target + * node is found, all the nodes in the recursion stack are the ancestors of target node i.e the + * target node can be reached from each of these nodes. Now do another dfs from each of the nodes + * starting from target node and all its ancestors up to the root to find nodes at a distance of (K + * - dk) where dk is the distance to the target node. Keep track of visited nodes in order not to + * revisit the same node once again. */ public class AllNodesDistanceKInBinaryTree { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; } + } - /** - * Main method - * @param args - */ - public static void main(String[] args) { + /** + * Main method + * + * @param args + */ + public static void main(String[] args) {} - } + class Node { + int v, d; - class Node{ - int v, d; - Node(int v, int d){ - this.d = d; - this.v = v; - } + Node(int v, int d) { + this.d = d; + this.v = v; } + } - private Set done; + private Set done; - public List distanceK(TreeNode root, TreeNode target, int K) { - done = new HashSet<>(); - List result = new ArrayList<>(); - findAndProcess(root, result, K, target); - return result; - } + public List distanceK(TreeNode root, TreeNode target, int K) { + done = new HashSet<>(); + List result = new ArrayList<>(); + findAndProcess(root, result, K, target); + return result; + } - private int findAndProcess(TreeNode node, List result, int K, TreeNode target){ - if(node != null){ - if(target == node){ - fillResult(node, result, 0, K); - return 1; - } else{ - int status = findAndProcess(node.left, result, K, target); - if(status > 0){ - if(K - status >= 0){ - fillResult(node, result, 0, K - status); - } - return status + 1; - } else { - status = findAndProcess(node.right, result, K, target); - if(status > 0){ - if(K - status >= 0){ - fillResult(node, result, 0, K - status); - } - return status + 1; - } - } - return -1; + private int findAndProcess(TreeNode node, List result, int K, TreeNode target) { + if (node != null) { + if (target == node) { + fillResult(node, result, 0, K); + return 1; + } else { + int status = findAndProcess(node.left, result, K, target); + if (status > 0) { + if (K - status >= 0) { + fillResult(node, result, 0, K - status); + } + return status + 1; + } else { + status = findAndProcess(node.right, result, K, target); + if (status > 0) { + if (K - status >= 0) { + fillResult(node, result, 0, K - status); } - } else return -1; - } - - private void fillResult(TreeNode node, List result, int d, int K){ - done.add(node.val); - if(d == K){ - result.add(node.val); - return; - } - if(node.left != null && !done.contains(node.left.val)){ - fillResult(node.left, result, d + 1, K); - } - if(node.right != null && !done.contains(node.right.val)){ - fillResult(node.right, result, d + 1, K); + return status + 1; + } } + return -1; + } + } else return -1; + } + + private void fillResult(TreeNode node, List result, int d, int K) { + done.add(node.val); + if (d == K) { + result.add(node.val); + return; + } + if (node.left != null && !done.contains(node.left.val)) { + fillResult(node.left, result, d + 1, K); + } + if (node.right != null && !done.contains(node.right.val)) { + fillResult(node.right, result, d + 1, K); } + } } diff --git a/problems/src/tree/AllPossibleFullBinaryTrees.java b/problems/src/tree/AllPossibleFullBinaryTrees.java index c9ab3816..fc66fafa 100644 --- a/problems/src/tree/AllPossibleFullBinaryTrees.java +++ b/problems/src/tree/AllPossibleFullBinaryTrees.java @@ -1,80 +1,78 @@ package tree; + import java.util.*; /** - * Created by gouthamvidyapradhan on 30/04/2019 - * A full binary tree is a binary tree where each node has exactly 0 or 2 children. - * - * Return a list of all possible full binary trees with N nodes. Each element of the answer is the root node of one - * possible tree. - * - * Each node of each tree in the answer must have node.val = 0. + * Created by gouthamvidyapradhan on 30/04/2019 A full binary tree is a binary tree where each node + * has exactly 0 or 2 children. * - * You may return the final list of trees in any order. + *

Return a list of all possible full binary trees with N nodes. Each element of the answer is + * the root node of one possible tree. * + *

Each node of each tree in the answer must have node.val = 0. * + *

You may return the final list of trees in any order. * - * Example 1: + *

Example 1: * - * Input: 7 - * Output: [[0,0,0,null,null,0,0,null,null,0,0],[0,0,0,null,null,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,null,null,null, - * null,0,0],[0,0,0,0,0,null,null,0,0]] + *

Input: 7 Output: + * [[0,0,0,null,null,0,0,null,null,0,0],[0,0,0,null,null,0,0,0,0],[0,0,0,0,0,0,0], + * [0,0,0,0,0,null,null,null, null,0,0],[0,0,0,0,0,null,null,0,0]] * - * Note: + *

Note: * - * 1 <= N <= 20 + *

1 <= N <= 20 * - * Solution: - * O(2 ^ N) - * A full binary tree can only be generated for a case with odd number of nodes. - * Start with a base case - when only one node is given a full binary tree can be formed with only one - * node. Cache this value in a hashmap. + *

Solution: O(2 ^ N) A full binary tree can only be generated for a case with odd number of + * nodes. Start with a base case - when only one node is given a full binary tree can be formed with + * only one node. Cache this value in a hashmap. * - * Now, iteratively generate a list of possible trees for 3, 5, 7 . . . N - ((N + 1) % 2) and cache - * this in a hashmap. + *

Now, iteratively generate a list of possible trees for 3, 5, 7 . . . N - ((N + 1) % 2) and + * cache this in a hashmap. */ public class AllPossibleFullBinaryTrees { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - /** - * Main method - * @param args - */ - public static void main(String[] args) { - List result = new AllPossibleFullBinaryTrees().allPossibleFBT(7); - System.out.println(result.size()); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + List result = new AllPossibleFullBinaryTrees().allPossibleFBT(7); + System.out.println(result.size()); + } - public List allPossibleFBT(int N) { - if(N % 2 == 0) return new ArrayList<>(); - Map> map = new HashMap<>(); - map.put(1, Arrays.asList(new TreeNode(0))); - for(int i = 3; i <= N; i += 2){ - List list = new ArrayList<>(); - for(int j = 1; j < i - 1; j += 2){ - int l = j, r = i - 1 - j; - List leftList = map.get(l); - List rightList = map.get(r); - for(TreeNode leftNode : leftList){ - for(TreeNode rightNode : rightList){ - TreeNode root = new TreeNode(0); - root.left = leftNode; - root.right = rightNode; - list.add(root); - } - } - } - map.put(i, list); + public List allPossibleFBT(int N) { + if (N % 2 == 0) return new ArrayList<>(); + Map> map = new HashMap<>(); + map.put(1, Arrays.asList(new TreeNode(0))); + for (int i = 3; i <= N; i += 2) { + List list = new ArrayList<>(); + for (int j = 1; j < i - 1; j += 2) { + int l = j, r = i - 1 - j; + List leftList = map.get(l); + List rightList = map.get(r); + for (TreeNode leftNode : leftList) { + for (TreeNode rightNode : rightList) { + TreeNode root = new TreeNode(0); + root.left = leftNode; + root.right = rightNode; + list.add(root); + } } - return map.get(N); + } + map.put(i, list); } + return map.get(N); + } } diff --git a/problems/src/tree/AverageOfLevelsInBinaryTree.java b/problems/src/tree/AverageOfLevelsInBinaryTree.java index 74c917b4..aba33987 100644 --- a/problems/src/tree/AverageOfLevelsInBinaryTree.java +++ b/problems/src/tree/AverageOfLevelsInBinaryTree.java @@ -6,77 +6,70 @@ import java.util.Queue; /** - * Created by gouthamvidyapradhan on 16/12/2017. - * Given a non-empty binary tree, return the average value of the nodes on each level in the form of an array. - Example 1: - Input: - 3 - / \ - 9 20 - / \ - 15 7 - Output: [3, 14.5, 11] - Explanation: - The average value of nodes on level 0 is 3, on level 1 is 14.5, and on level 2 is 11. Hence return [3, 14.5, 11]. - Note: - The range of node's value is in the range of 32-bit signed integer. - - Solution O(n) : Perform a BFS and calculate average for each level. + * Created by gouthamvidyapradhan on 16/12/2017. Given a non-empty binary tree, return the average + * value of the nodes on each level in the form of an array. Example 1: Input: 3 / \ 9 20 / \ 15 7 + * Output: [3, 14.5, 11] Explanation: The average value of nodes on level 0 is 3, on level 1 is + * 14.5, and on level 2 is 11. Hence return [3, 14.5, 11]. Note: The range of node's value is in the + * range of 32-bit signed integer. + * + *

Solution O(n) : Perform a BFS and calculate average for each level. */ public class AverageOfLevelsInBinaryTree { - class LevelNode { - int level; - TreeNode node; - LevelNode(int level, TreeNode node){ - this.level = level; - this.node = node; - } - } + class LevelNode { + int level; + TreeNode node; - public class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } + LevelNode(int level, TreeNode node) { + this.level = level; + this.node = node; } + } - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { + val = x; } + } - public List averageOfLevels(TreeNode root) { - Queue queue = new ArrayDeque<>(); - LevelNode node = new LevelNode(0, root); - queue.offer(node); - int curLevel = 0, count = 0; - long sum = 0L; - List result = new ArrayList<>(); - while(!queue.isEmpty()){ - LevelNode first = queue.poll(); - if(first.level == curLevel){ - sum += first.node.val; - count++; - } else{ - result.add((double)sum/count); - sum = first.node.val; - count = 1; - curLevel++; - } - if(first.node.left != null){ - queue.offer(new LevelNode(curLevel + 1, first.node.left)); - } if(first.node.right != null){ - queue.offer(new LevelNode(curLevel + 1, first.node.right)); - } - } - result.add((double)sum/count); - return result; - } - + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception {} + public List averageOfLevels(TreeNode root) { + Queue queue = new ArrayDeque<>(); + LevelNode node = new LevelNode(0, root); + queue.offer(node); + int curLevel = 0, count = 0; + long sum = 0L; + List result = new ArrayList<>(); + while (!queue.isEmpty()) { + LevelNode first = queue.poll(); + if (first.level == curLevel) { + sum += first.node.val; + count++; + } else { + result.add((double) sum / count); + sum = first.node.val; + count = 1; + curLevel++; + } + if (first.node.left != null) { + queue.offer(new LevelNode(curLevel + 1, first.node.left)); + } + if (first.node.right != null) { + queue.offer(new LevelNode(curLevel + 1, first.node.right)); + } + } + result.add((double) sum / count); + return result; + } } diff --git a/problems/src/tree/BSTtoDoublyLinkedList.java b/problems/src/tree/BSTtoDoublyLinkedList.java index 9cfbe71e..3e450d61 100644 --- a/problems/src/tree/BSTtoDoublyLinkedList.java +++ b/problems/src/tree/BSTtoDoublyLinkedList.java @@ -1,57 +1,57 @@ package tree; /** - * Created by gouthamvidyapradhan on 23/01/2018. - * Convert a BST to a sorted circular doubly-linked list in-place. Think of the left and right pointers as synonymous - * to the previous and next pointers in a doubly-linked list. + * Created by gouthamvidyapradhan on 23/01/2018. Convert a BST to a sorted circular doubly-linked + * list in-place. Think of the left and right pointers as synonymous to the previous and next + * pointers in a doubly-linked list. * - * Solution: Do a preorder traversal, keep track of previous node at every step and construct the dd-linked list - * in-place. + *

Solution: Do a preorder traversal, keep track of previous node at every step and construct the + * dd-linked list in-place. */ public class BSTtoDoublyLinkedList { - static class Node { - public int val; - public Node left; - public Node right; + static class Node { + public int val; + public Node left; + public Node right; - public Node() {} + public Node() {} - public Node(int _val,Node _left,Node _right) { - val = _val; - left = _left; - right = _right; - } + public Node(int _val, Node _left, Node _right) { + val = _val; + left = _left; + right = _right; } - - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - Node root = new Node(4, new Node(2, null, null), new Node(5, null, null)); - Node result = new BSTtoDoublyLinkedList().treeToDoublyList(root); - //print result - } - - public Node treeToDoublyList(Node root) { - if(root == null) return null; - Node head = new Node(); - Node last = preorder(root, head); - last.right = head.right; - head.right.left = last; - return head.right; + } + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + Node root = new Node(4, new Node(2, null, null), new Node(5, null, null)); + Node result = new BSTtoDoublyLinkedList().treeToDoublyList(root); + // print result + } + + public Node treeToDoublyList(Node root) { + if (root == null) return null; + Node head = new Node(); + Node last = preorder(root, head); + last.right = head.right; + head.right.left = last; + return head.right; + } + + Node preorder(Node node, Node prev) { + if (node == null) return prev; + else { + Node left = preorder(node.left, prev); + left.right = node; + node.left = left; + return preorder(node.right, node); } - - Node preorder(Node node, Node prev){ - if(node == null) return prev; - else{ - Node left = preorder(node.left, prev); - left.right = node; - node.left = left; - return preorder(node.right, node); - } - } - + } } diff --git a/problems/src/tree/BinarayTreeRightSideView.java b/problems/src/tree/BinarayTreeRightSideView.java index 821cd279..9e29e495 100644 --- a/problems/src/tree/BinarayTreeRightSideView.java +++ b/problems/src/tree/BinarayTreeRightSideView.java @@ -4,67 +4,60 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 12/03/2017. - * Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom. - *

- * For example: - * Given the following binary tree, - * 1 <--- - * / \ - * 2 3 <--- - * \ \ - * 5 4 <--- - * You should return [1, 3, 4]. + * Created by gouthamvidyapradhan on 12/03/2017. Given a binary tree, imagine yourself standing on + * the right side of it, return the values of the nodes you can see ordered from top to bottom. + * + *

For example: Given the following binary tree, 1 <--- / \ 2 3 <--- \ \ 5 4 <--- You should + * return [1, 3, 4]. */ - public class BinarayTreeRightSideView { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } - - private int maxHeigh = Integer.MIN_VALUE; - List list = new ArrayList<>(); + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - TreeNode root = new TreeNode(2); - root.left = new TreeNode(3); - root.right = new TreeNode(4); - root.right.right = new TreeNode(5); - root.right.left = new TreeNode(4); - root.right.left.right = new TreeNode(8); - root.right.left.left = new TreeNode(7); - root.right.left.left.right = new TreeNode(10); - root.right.left.left.left = new TreeNode(7); - - List list = new BinarayTreeRightSideView().rightSideView(root); - } - - public List rightSideView(TreeNode root) { - if (root == null) return list; - dfs(root, 0); - return list; + TreeNode(int x) { + val = x; } - - private void dfs(TreeNode node, int height) { - if (node != null) { - if (height > maxHeigh) { - list.add(node.val); - maxHeigh = height; - } - dfs(node.right, height + 1); - dfs(node.left, height + 1); - } + } + + private int maxHeigh = Integer.MIN_VALUE; + List list = new ArrayList<>(); + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(2); + root.left = new TreeNode(3); + root.right = new TreeNode(4); + root.right.right = new TreeNode(5); + root.right.left = new TreeNode(4); + root.right.left.right = new TreeNode(8); + root.right.left.left = new TreeNode(7); + root.right.left.left.right = new TreeNode(10); + root.right.left.left.left = new TreeNode(7); + + List list = new BinarayTreeRightSideView().rightSideView(root); + } + + public List rightSideView(TreeNode root) { + if (root == null) return list; + dfs(root, 0); + return list; + } + + private void dfs(TreeNode node, int height) { + if (node != null) { + if (height > maxHeigh) { + list.add(node.val); + maxHeigh = height; + } + dfs(node.right, height + 1); + dfs(node.left, height + 1); } + } } diff --git a/problems/src/tree/BinaryTreeInorderTraversal.java b/problems/src/tree/BinaryTreeInorderTraversal.java index 42aedb08..b52a1cfb 100644 --- a/problems/src/tree/BinaryTreeInorderTraversal.java +++ b/problems/src/tree/BinaryTreeInorderTraversal.java @@ -5,59 +5,51 @@ import java.util.Stack; /** - * Created by gouthamvidyapradhan on 06/08/2017. - * Given a binary tree, return the inorder traversal of its nodes' values. - *

- * For example: - * Given binary tree [1,null,2,3], - * 1 - * \ - * 2 - * / - * 3 - * return [1,3,2]. - *

- * Note: Recursive solution is trivial, could you do it iteratively? + * Created by gouthamvidyapradhan on 06/08/2017. Given a binary tree, return the inorder traversal + * of its nodes' values. + * + *

For example: Given binary tree [1,null,2,3], 1 \ 2 / 3 return [1,3,2]. + * + *

Note: Recursive solution is trivial, could you do it iteratively? */ public class BinaryTreeInorderTraversal { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - public static void main(String[] args) throws Exception { - TreeNode root = new TreeNode(3); - root.left = new TreeNode(4); - root.left.left = new TreeNode(5); - root.left.right = new TreeNode(6); - root.left.left.left = new TreeNode(9); - root.left.left.right = new TreeNode(10); - root.right = new TreeNode(2); - root.right.left = new TreeNode(7); - root.right.right = new TreeNode(8); - List result = new BinaryTreeInorderTraversal().inorderTraversal(root); - System.out.println(result); - } + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(3); + root.left = new TreeNode(4); + root.left.left = new TreeNode(5); + root.left.right = new TreeNode(6); + root.left.left.left = new TreeNode(9); + root.left.left.right = new TreeNode(10); + root.right = new TreeNode(2); + root.right.left = new TreeNode(7); + root.right.right = new TreeNode(8); + List result = new BinaryTreeInorderTraversal().inorderTraversal(root); + System.out.println(result); + } - public List inorderTraversal(TreeNode root) { - Stack stack = new Stack<>(); - TreeNode curr = root; - List result = new ArrayList<>(); - while (curr != null || !stack.isEmpty()) { - while (curr != null) { - stack.push(curr); - curr = curr.left; - } - curr = stack.pop(); - result.add(curr.val); - curr = curr.right; - } - return result; + public List inorderTraversal(TreeNode root) { + Stack stack = new Stack<>(); + TreeNode curr = root; + List result = new ArrayList<>(); + while (curr != null || !stack.isEmpty()) { + while (curr != null) { + stack.push(curr); + curr = curr.left; + } + curr = stack.pop(); + result.add(curr.val); + curr = curr.right; } - + return result; + } } diff --git a/problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java b/problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java index 3a50fad7..ab4b3146 100644 --- a/problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java +++ b/problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java @@ -1,104 +1,95 @@ package tree; /** - * Created by gouthamvidyapradhan on 11/02/2018. - * Given a binary tree, you need to find the length of Longest Consecutive Path in Binary Tree. - - Especially, this path can be either increasing or decreasing. For example, [1,2,3,4] and [4,3,2,1] are both - considered valid, but the path [1,2,4,3] is not valid. On the other hand, the path can be in the child-Parent-child - order, where not necessarily be parent-child order. - - Example 1: - Input: - 1 - / \ - 2 3 - Output: 2 - Explanation: The longest consecutive path is [1, 2] or [2, 1]. - Example 2: - Input: - 2 - / \ - 1 3 - Output: 3 - Explanation: The longest consecutive path is [1, 2, 3] or [3, 2, 1]. - Note: All the values of tree nodes are in the range of [-1e7, 1e7]. + * Created by gouthamvidyapradhan on 11/02/2018. Given a binary tree, you need to find the length of + * Longest Consecutive Path in Binary Tree. + * + *

Especially, this path can be either increasing or decreasing. For example, [1,2,3,4] and + * [4,3,2,1] are both considered valid, but the path [1,2,4,3] is not valid. On the other hand, the + * path can be in the child-Parent-child order, where not necessarily be parent-child order. + * + *

Example 1: Input: 1 / \ 2 3 Output: 2 Explanation: The longest consecutive path is [1, 2] or + * [2, 1]. Example 2: Input: 2 / \ 1 3 Output: 3 Explanation: The longest consecutive path is [1, 2, + * 3] or [3, 2, 1]. Note: All the values of tree nodes are in the range of [-1e7, 1e7]. */ public class BinaryTreeLongestConsecutiveSequenceII { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } - } + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - private class Node{ - int i, d; - int val; - Node(int i, int d, int val){ - this.i = i; - this.d = d; - this.val = val; - } - } - private int max = Integer.MIN_VALUE; - public static void main(String[] args) throws Exception{ - TreeNode root = new TreeNode(2); - root.left = new TreeNode(1); - //root.left.left = new TreeNode(4); - root.right = new TreeNode(3); - System.out.println(new BinaryTreeLongestConsecutiveSequenceII().longestConsecutive(root)); + TreeNode(int x) { + val = x; } + } + private class Node { + int i, d; + int val; - public int longestConsecutive(TreeNode root) { - Node n = preorder(root); - if(n != null){ - max = Math.max(max, n.d); - max = Math.max(max, n.i); - if(n.i > 1 && n.d > 1){ - max = Math.max(max, n.d + n.i - 1); - } - } - if(max == Integer.MIN_VALUE) return 0; - return max; + Node(int i, int d, int val) { + this.i = i; + this.d = d; + this.val = val; } + } + private int max = Integer.MIN_VALUE; - private Node preorder(TreeNode node){ - if(node == null) return null; - Node left = preorder(node.left); - Node curr = new Node(1, 1, node.val); - if(left != null){ - max = Math.max(max, left.d); - max = Math.max(max, left.i); - if(left.val == node.val + 1){ - curr.d = left.d + 1; - curr.i = 1; - } else if(left.val == node.val - 1){ - curr.i = left.i + 1; - curr.d = 1; - } - } - Node right = preorder(node.right); - if(right != null){ - max = Math.max(max, right.d); - max = Math.max(max, right.i); - if(right.val == node.val + 1){ - if(right.d + 1 > curr.d){ - curr.d = right.d + 1; - } - } else if(right.val == node.val - 1){ - if(right.i + 1 > curr.i){ - curr.i = right.i + 1; - } - } + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(2); + root.left = new TreeNode(1); + // root.left.left = new TreeNode(4); + root.right = new TreeNode(3); + System.out.println(new BinaryTreeLongestConsecutiveSequenceII().longestConsecutive(root)); + } + + public int longestConsecutive(TreeNode root) { + Node n = preorder(root); + if (n != null) { + max = Math.max(max, n.d); + max = Math.max(max, n.i); + if (n.i > 1 && n.d > 1) { + max = Math.max(max, n.d + n.i - 1); + } + } + if (max == Integer.MIN_VALUE) return 0; + return max; + } + + private Node preorder(TreeNode node) { + if (node == null) return null; + Node left = preorder(node.left); + Node curr = new Node(1, 1, node.val); + if (left != null) { + max = Math.max(max, left.d); + max = Math.max(max, left.i); + if (left.val == node.val + 1) { + curr.d = left.d + 1; + curr.i = 1; + } else if (left.val == node.val - 1) { + curr.i = left.i + 1; + curr.d = 1; + } + } + Node right = preorder(node.right); + if (right != null) { + max = Math.max(max, right.d); + max = Math.max(max, right.i); + if (right.val == node.val + 1) { + if (right.d + 1 > curr.d) { + curr.d = right.d + 1; } - if(curr.i > 1 && curr.d > 1){ - max = Math.max(max, curr.d + curr.i - 1); + } else if (right.val == node.val - 1) { + if (right.i + 1 > curr.i) { + curr.i = right.i + 1; } - return curr; + } } - + if (curr.i > 1 && curr.d > 1) { + max = Math.max(max, curr.d + curr.i - 1); + } + return curr; + } } diff --git a/problems/src/tree/BinaryTreeMaximumPathSum.java b/problems/src/tree/BinaryTreeMaximumPathSum.java index c2d5ce30..8ab9ad11 100644 --- a/problems/src/tree/BinaryTreeMaximumPathSum.java +++ b/problems/src/tree/BinaryTreeMaximumPathSum.java @@ -1,65 +1,62 @@ package tree; /** - * Created by gouthamvidyapradhan on 03/04/2017. - * Given a binary tree, find the maximum path sum. - *

- * For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root. - *

- * For example: - * Given the below binary tree, - *

- * 1 - * / \ - * 2 3 - * Return 6. + * Created by gouthamvidyapradhan on 03/04/2017. Given a binary tree, find the maximum path sum. + * + *

For this problem, a path is defined as any sequence of nodes from some starting node to any + * node in the tree along the parent-child connections. The path must contain at least one node and + * does not need to go through the root. + * + *

For example: Given the below binary tree, + * + *

1 / \ 2 3 Return 6. */ public class BinaryTreeMaximumPathSum { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - private int max = Integer.MIN_VALUE; + private int max = Integer.MIN_VALUE; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - TreeNode root = new TreeNode(5); - root.left = new TreeNode(4); - root.left.left = new TreeNode(3); - root.left.left.left = new TreeNode(-1); - root.right = new TreeNode(7); - root.right.left = new TreeNode(2); - root.right.left.left = new TreeNode(9); - System.out.println(new BinaryTreeMaximumPathSum().maxPathSum(root)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(5); + root.left = new TreeNode(4); + root.left.left = new TreeNode(3); + root.left.left.left = new TreeNode(-1); + root.right = new TreeNode(7); + root.right.left = new TreeNode(2); + root.right.left.left = new TreeNode(9); + System.out.println(new BinaryTreeMaximumPathSum().maxPathSum(root)); + } - public int maxPathSum(TreeNode root) { - if (root == null) return 0; - dfs(root); - return max; - } + public int maxPathSum(TreeNode root) { + if (root == null) return 0; + dfs(root); + return max; + } - private int dfs(TreeNode root) { - if (root == null) return 0; - int left = dfs(root.left); - int right = dfs(root.right); - max = Math.max(max, root.val); - max = Math.max(max, root.val + left); - max = Math.max(max, root.val + right); - max = Math.max(max, root.val + left + right); - int leftVal = Math.max(root.val, root.val + left); - int rightVal = Math.max(root.val, root.val + right); - return Math.max(leftVal, rightVal); - } + private int dfs(TreeNode root) { + if (root == null) return 0; + int left = dfs(root.left); + int right = dfs(root.right); + max = Math.max(max, root.val); + max = Math.max(max, root.val + left); + max = Math.max(max, root.val + right); + max = Math.max(max, root.val + left + right); + int leftVal = Math.max(root.val, root.val + left); + int rightVal = Math.max(root.val, root.val + right); + return Math.max(leftVal, rightVal); + } } diff --git a/problems/src/tree/BinaryTreePaths.java b/problems/src/tree/BinaryTreePaths.java index 13e49644..35a098d9 100644 --- a/problems/src/tree/BinaryTreePaths.java +++ b/problems/src/tree/BinaryTreePaths.java @@ -4,44 +4,40 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 09/12/2017. - * Given a binary tree, return all root-to-leaf paths. - - For example, given the following binary tree: - - 1 - / \ - 2 3 - \ - 5 - All root-to-leaf paths are: - - ["1->2->5", "1->3"] + * Created by gouthamvidyapradhan on 09/12/2017. Given a binary tree, return all root-to-leaf paths. + * + *

For example, given the following binary tree: + * + *

1 / \ 2 3 \ 5 All root-to-leaf paths are: + * + *

["1->2->5", "1->3"] */ public class BinaryTreePaths { - public class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } - } + public class TreeNode { + int val; + TreeNode left; + TreeNode right; - public List binaryTreePaths(TreeNode root) { - List result = new ArrayList<>(); - new BinaryTreePaths().inorder(root, result, ""); - return result; + TreeNode(int x) { + val = x; } - - private void inorder(TreeNode node, List list, String path){ - if(node != null){ - if(node.left == null && node.right == null){ - list.add(path + node.val); - } else { - inorder(node.left, list, path + node.val + "->"); - inorder(node.right, list, path + node.val + "->"); - } - } + } + + public List binaryTreePaths(TreeNode root) { + List result = new ArrayList<>(); + new BinaryTreePaths().inorder(root, result, ""); + return result; + } + + private void inorder(TreeNode node, List list, String path) { + if (node != null) { + if (node.left == null && node.right == null) { + list.add(path + node.val); + } else { + inorder(node.left, list, path + node.val + "->"); + inorder(node.right, list, path + node.val + "->"); + } } - + } } diff --git a/problems/src/tree/BinaryTreePostorderTraversal.java b/problems/src/tree/BinaryTreePostorderTraversal.java index c7533312..6a5d369d 100644 --- a/problems/src/tree/BinaryTreePostorderTraversal.java +++ b/problems/src/tree/BinaryTreePostorderTraversal.java @@ -1,62 +1,56 @@ package tree; -import java.util.*; -/** - * Created by gouthamvidyapradhan on 28/07/2018. - * Given a binary tree, return the postorder traversal of its nodes' values. - - Example: - Input: [1,null,2,3] - 1 - \ - 2 - / - 3 - - Output: [3,2,1] - Follow up: Recursive solution is trivial, could you do it iteratively? +import java.util.*; -Solution: O(N). Maintain a stack, for every node which you pop from stack add it to result list, push left - and right node to stack. Reverse the result list and return this as the answer. +/** + * Created by gouthamvidyapradhan on 28/07/2018. Given a binary tree, return the postorder traversal + * of its nodes' values. + * + *

Example: + * + *

Input: [1,null,2,3] 1 \ 2 / 3 + * + *

Output: [3,2,1] Follow up: Recursive solution is trivial, could you do it iteratively? + * + *

Solution: O(N). Maintain a stack, for every node which you pop from stack add it to result + * list, push left and right node to stack. Reverse the result list and return this as the answer. */ public class BinaryTreePostorderTraversal { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } - - public static void main(String[] args) throws Exception{ - TreeNode root = new TreeNode(1); - root.right = new TreeNode(2); - root.right.left = new TreeNode(3); - List result = new BinaryTreePostorderTraversal().postorderTraversal(root); - result.forEach(System.out::println); + } + + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(1); + root.right = new TreeNode(2); + root.right.left = new TreeNode(3); + List result = new BinaryTreePostorderTraversal().postorderTraversal(root); + result.forEach(System.out::println); + } + + public List postorderTraversal(TreeNode root) { + Stack stack = new Stack<>(); + List result = new ArrayList<>(); + if (root != null) { + stack.push(root); } - - public List postorderTraversal(TreeNode root) { - Stack stack = new Stack<>(); - List result = new ArrayList<>(); - if(root != null){ - stack.push(root); - } - while(!stack.isEmpty()){ - TreeNode node = stack.pop(); - result.add(node.val); - if(node.left != null){ - stack.push(node.left); - } if(node.right != null){ - stack.push(node.right); - } - } - Collections.reverse(result); - return result; + while (!stack.isEmpty()) { + TreeNode node = stack.pop(); + result.add(node.val); + if (node.left != null) { + stack.push(node.left); + } + if (node.right != null) { + stack.push(node.right); + } } - - - + Collections.reverse(result); + return result; + } } diff --git a/problems/src/tree/BoundaryOfBinaryTree.java b/problems/src/tree/BoundaryOfBinaryTree.java index a4a96f34..2dd6260a 100644 --- a/problems/src/tree/BoundaryOfBinaryTree.java +++ b/problems/src/tree/BoundaryOfBinaryTree.java @@ -3,153 +3,138 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 27/03/2017. - * Given a binary tree, return the values of its boundary in anti-clockwise direction starting from root. Boundary includes left boundary, leaves, and right boundary in order without duplicate nodes. - *

- * Left boundary is defined as the path from root to the left-most node. Right boundary is defined as the path from root to the right-most node. If the root doesn't have left subtree or right subtree, then the root itself is left boundary or right boundary. Note this definition only applies to the input binary tree, and not applies to any subtrees. - *

- * The left-most node is defined as a leaf node you could reach when you always firstly travel to the left subtree if exists. If not, travel to the right subtree. Repeat until you reach a leaf node. - *

- * The right-most node is also defined by the same way with left and right exchanged. - *

- * Example 1 - * Input: - * 1 - * \ - * 2 - * / \ - * 3 4 - *

- * Ouput: - * [1, 3, 4, 2] - *

- * Explanation: - * The root doesn't have left subtree, so the root itself is left boundary. - * The leaves are node 3 and 4. - * The right boundary are node 1,2,4. Note the anti-clockwise direction means you should output reversed right boundary. - * So order them in anti-clockwise without duplicates and we have [1,3,4,2]. - * Example 2 - * Input: - * ____1_____ - * / \ - * 2 3 - * / \ / - * 4 5 6 - * / \ / \ - * 7 8 9 10 - *

- * Ouput: - * [1,2,4,7,8,9,10,6,3] - *

- * Explanation: - * The left boundary are node 1,2,4. (4 is the left-most node according to definition) - * The leaves are node 4,7,8,9,10. - * The right boundary are node 1,3,6,10. (10 is the right-most node). - * So order them in anti-clockwise without duplicate nodes we have [1,2,4,7,8,9,10,6,3]. + * Created by gouthamvidyapradhan on 27/03/2017. Given a binary tree, return the values of its + * boundary in anti-clockwise direction starting from root. Boundary includes left boundary, leaves, + * and right boundary in order without duplicate nodes. + * + *

Left boundary is defined as the path from root to the left-most node. Right boundary is + * defined as the path from root to the right-most node. If the root doesn't have left subtree or + * right subtree, then the root itself is left boundary or right boundary. Note this definition only + * applies to the input binary tree, and not applies to any subtrees. + * + *

The left-most node is defined as a leaf node you could reach when you always firstly travel to + * the left subtree if exists. If not, travel to the right subtree. Repeat until you reach a leaf + * node. + * + *

The right-most node is also defined by the same way with left and right exchanged. + * + *

Example 1 Input: 1 \ 2 / \ 3 4 + * + *

Ouput: [1, 3, 4, 2] + * + *

Explanation: The root doesn't have left subtree, so the root itself is left boundary. The + * leaves are node 3 and 4. The right boundary are node 1,2,4. Note the anti-clockwise direction + * means you should output reversed right boundary. So order them in anti-clockwise without + * duplicates and we have [1,3,4,2]. Example 2 Input: ____1_____ / \ 2 3 / \ / 4 5 6 / \ / \ 7 8 9 + * 10 + * + *

Ouput: [1,2,4,7,8,9,10,6,3] + * + *

Explanation: The left boundary are node 1,2,4. (4 is the left-most node according to + * definition) The leaves are node 4,7,8,9,10. The right boundary are node 1,3,6,10. (10 is the + * right-most node). So order them in anti-clockwise without duplicate nodes we have + * [1,2,4,7,8,9,10,6,3]. */ public class BoundaryOfBinaryTree { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - private Set done = new HashSet<>(); + private Set done = new HashSet<>(); - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - TreeNode root = new TreeNode(1); - /*root.right = new TreeNode(2); - root.right.right = new TreeNode(3); - root.right.right.right = new TreeNode(4); - root.right.right.right.left = new TreeNode(5); - root.right.right.right.left.right = new TreeNode(6); - /*root.left = new TreeNode(2); - root.left.left = new TreeNode(4); - root.left.right = new TreeNode(5); - root.left.right.left = new TreeNode(7); - root.left.right.right = new TreeNode(8); - root.right = new TreeNode(3); - root.right.left = new TreeNode(6); - root.right.left.left = new TreeNode(9); - root.right.left.right = new TreeNode(10);*/ - System.out.println(new BoundaryOfBinaryTree().boundaryOfBinaryTree(root)); - } - - public List boundaryOfBinaryTree(TreeNode root) { - if (root == null) return new ArrayList<>(); - List antiClockwiseCollection = new ArrayList<>(); - List collection = new ArrayList<>(); + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(1); + /*root.right = new TreeNode(2); + root.right.right = new TreeNode(3); + root.right.right.right = new TreeNode(4); + root.right.right.right.left = new TreeNode(5); + root.right.right.right.left.right = new TreeNode(6); + /*root.left = new TreeNode(2); + root.left.left = new TreeNode(4); + root.left.right = new TreeNode(5); + root.left.right.left = new TreeNode(7); + root.left.right.right = new TreeNode(8); + root.right = new TreeNode(3); + root.right.left = new TreeNode(6); + root.right.left.left = new TreeNode(9); + root.right.left.right = new TreeNode(10);*/ + System.out.println(new BoundaryOfBinaryTree().boundaryOfBinaryTree(root)); + } - if (root.left != null) - leftShoulder(root, collection); - else { - if (!done.contains(root)) { - done.add(root); - collection.add(root.val); - } - } + public List boundaryOfBinaryTree(TreeNode root) { + if (root == null) return new ArrayList<>(); + List antiClockwiseCollection = new ArrayList<>(); + List collection = new ArrayList<>(); - antiClockwiseCollection.addAll(collection); - collection.clear(); - leafNode(root, collection); - antiClockwiseCollection.addAll(collection); - collection.clear(); + if (root.left != null) leftShoulder(root, collection); + else { + if (!done.contains(root)) { + done.add(root); + collection.add(root.val); + } + } - if (root.right != null) - rightShoulder(root, collection); - else { - if (!done.contains(root)) { - done.add(root); - collection.add(root.val); - } - } + antiClockwiseCollection.addAll(collection); + collection.clear(); + leafNode(root, collection); + antiClockwiseCollection.addAll(collection); + collection.clear(); - Stack stack = new Stack<>(); - stack.addAll(collection); - while (!stack.isEmpty()) - antiClockwiseCollection.add(stack.pop()); - return new ArrayList<>(antiClockwiseCollection); + if (root.right != null) rightShoulder(root, collection); + else { + if (!done.contains(root)) { + done.add(root); + collection.add(root.val); + } } - private void leftShoulder(TreeNode node, List list) { - if (node == null) return; - if (!done.contains(node)) { - list.add(node.val); - done.add(node); - } + Stack stack = new Stack<>(); + stack.addAll(collection); + while (!stack.isEmpty()) antiClockwiseCollection.add(stack.pop()); + return new ArrayList<>(antiClockwiseCollection); + } - if (node.left != null) leftShoulder(node.left, list); - else if (node.right != null) leftShoulder(node.right, list); + private void leftShoulder(TreeNode node, List list) { + if (node == null) return; + if (!done.contains(node)) { + list.add(node.val); + done.add(node); } - private void rightShoulder(TreeNode node, List list) { - if (node == null) return; - if (!done.contains(node)) { - list.add(node.val); - done.add(node); - } - if (node.right != null) rightShoulder(node.right, list); - else if (node.left != null) rightShoulder(node.left, list); - } + if (node.left != null) leftShoulder(node.left, list); + else if (node.right != null) leftShoulder(node.right, list); + } - private void leafNode(TreeNode node, List list) { - if (node == null) return; - if (node.left == null && node.right == null) - if (!done.contains(node)) { - list.add(node.val); - done.add(node); - } - leafNode(node.left, list); - leafNode(node.right, list); + private void rightShoulder(TreeNode node, List list) { + if (node == null) return; + if (!done.contains(node)) { + list.add(node.val); + done.add(node); } + if (node.right != null) rightShoulder(node.right, list); + else if (node.left != null) rightShoulder(node.left, list); + } + + private void leafNode(TreeNode node, List list) { + if (node == null) return; + if (node.left == null && node.right == null) + if (!done.contains(node)) { + list.add(node.val); + done.add(node); + } + leafNode(node.left, list); + leafNode(node.right, list); + } } diff --git a/problems/src/tree/ClosestBinarySearchTreeValue.java b/problems/src/tree/ClosestBinarySearchTreeValue.java index b64113fa..4d2cd451 100644 --- a/problems/src/tree/ClosestBinarySearchTreeValue.java +++ b/problems/src/tree/ClosestBinarySearchTreeValue.java @@ -1,62 +1,57 @@ package tree; /** - * Created by gouthamvidyapradhan on 10/05/2017. - * Given a non-empty binary search tree and a target value, find the value in the BST that is closest to the target. - *

- * Note: - * Given target value is a floating point. - * You are guaranteed to have only one unique value in the BST that is closest to the target. - *

- * Solution: Simple dfs recursive algorithm to find the closest match. - * Worst case time complexity is O(h) where h is height of the tree + * Created by gouthamvidyapradhan on 10/05/2017. Given a non-empty binary search tree and a target + * value, find the value in the BST that is closest to the target. + * + *

Note: Given target value is a floating point. You are guaranteed to have only one unique value + * in the BST that is closest to the target. + * + *

Solution: Simple dfs recursive algorithm to find the closest match. Worst case time complexity + * is O(h) where h is height of the tree */ public class ClosestBinarySearchTreeValue { - /** - * TreeNode - */ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + /** TreeNode */ + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - private double absDiff = Double.MAX_VALUE; - private int closest; + private double absDiff = Double.MAX_VALUE; + private int closest; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - TreeNode root = new TreeNode(10); - root.left = new TreeNode(9); - root.left.left = new TreeNode(8); - System.out.println(new ClosestBinarySearchTreeValue().closestValue(root, 7.63354D)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(10); + root.left = new TreeNode(9); + root.left.left = new TreeNode(8); + System.out.println(new ClosestBinarySearchTreeValue().closestValue(root, 7.63354D)); + } - /** - * Find closest - * - * @param root Root node - * @param target double target - * @return closest value - */ - public int closestValue(TreeNode root, double target) { - if (root == null) return closest; - if (Math.abs(target - root.val) < absDiff) { - absDiff = Math.abs(target - root.val); - closest = root.val; - } - if (root.val > target) - return closestValue(root.left, target); - else return closestValue(root.right, target); + /** + * Find closest + * + * @param root Root node + * @param target double target + * @return closest value + */ + public int closestValue(TreeNode root, double target) { + if (root == null) return closest; + if (Math.abs(target - root.val) < absDiff) { + absDiff = Math.abs(target - root.val); + closest = root.val; } - + if (root.val > target) return closestValue(root.left, target); + else return closestValue(root.right, target); + } } diff --git a/problems/src/tree/ClosestLeafInABinaryTree.java b/problems/src/tree/ClosestLeafInABinaryTree.java index 8a33ac7a..e08b5e8a 100644 --- a/problems/src/tree/ClosestLeafInABinaryTree.java +++ b/problems/src/tree/ClosestLeafInABinaryTree.java @@ -3,143 +3,130 @@ import java.util.*; /** - * Created by gouthamvidyapradhan on 02/05/2018. - * Given a binary tree where every node has a unique value, and a target key k, find the value of the nearest leaf node to target k in the tree. - - Here, nearest to a leaf means the least number of edges travelled on the binary tree to reach any leaf of the tree. Also, a node is called a leaf if it has no children. - - In the following examples, the input tree is represented in flattened form row by row. The actual root tree given will be a TreeNode object. - - Example 1: - - Input: - root = [1, 3, 2], k = 1 - Diagram of binary tree: - 1 - / \ - 3 2 - - Output: 2 (or 3) - - Explanation: Either 2 or 3 is the nearest leaf node to the target of 1. - Example 2: - - Input: - root = [1], k = 1 - Output: 1 - - Explanation: The nearest leaf node is the root node itself. - Example 3: - - Input: - root = [1,2,3,4,null,null,null,5,null,6], k = 2 - Diagram of binary tree: - 1 - / \ - 2 3 - / - 4 - / - 5 - / - 6 - - Output: 3 - Explanation: The leaf node with value 3 (and not the leaf node with value 6) is nearest to the node with value 2. - Note: - root represents a binary tree with at least 1 node and at most 1000 nodes. - Every node has a unique node.val in range [1, 1000]. - There exists some node in the given binary tree for which node.val == k. - - Solution: O(N): Maintain a hashmap of distances from each node in the first iteration. In the second iteration, - find the key value node and then calculate distance from each node during backtrack. + * Created by gouthamvidyapradhan on 02/05/2018. Given a binary tree where every node has a unique + * value, and a target key k, find the value of the nearest leaf node to target k in the tree. + * + *

Here, nearest to a leaf means the least number of edges travelled on the binary tree to reach + * any leaf of the tree. Also, a node is called a leaf if it has no children. + * + *

In the following examples, the input tree is represented in flattened form row by row. The + * actual root tree given will be a TreeNode object. + * + *

Example 1: + * + *

Input: root = [1, 3, 2], k = 1 Diagram of binary tree: 1 / \ 3 2 + * + *

Output: 2 (or 3) + * + *

Explanation: Either 2 or 3 is the nearest leaf node to the target of 1. Example 2: + * + *

Input: root = [1], k = 1 Output: 1 + * + *

Explanation: The nearest leaf node is the root node itself. Example 3: + * + *

Input: root = [1,2,3,4,null,null,null,5,null,6], k = 2 Diagram of binary tree: 1 / \ 2 3 / 4 / + * 5 / 6 + * + *

Output: 3 Explanation: The leaf node with value 3 (and not the leaf node with value 6) is + * nearest to the node with value 2. Note: root represents a binary tree with at least 1 node and at + * most 1000 nodes. Every node has a unique node.val in range [1, 1000]. There exists some node in + * the given binary tree for which node.val == k. + * + *

Solution: O(N): Maintain a hashmap of distances from each node in the first iteration. In the + * second iteration, find the key value node and then calculate distance from each node during + * backtrack. */ public class ClosestLeafInABinaryTree { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } - } + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - private static class Pair{ - int n, d; - Pair(int n, int d){ - this.n = n; - this.d = d; - } + TreeNode(int x) { + val = x; } + } - private Map map; - private Pair minNode; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - TreeNode root = new TreeNode(1); - root.left = new TreeNode(2); - root.right = new TreeNode(3); - root.left.left = new TreeNode(4); - root.left.left.left = new TreeNode(5); - root.left.left.left.left = new TreeNode(6); - //root.right = new TreeNode(3); - System.out.println(new ClosestLeafInABinaryTree().findClosestLeaf(root, 2)); - } + private static class Pair { + int n, d; - public int findClosestLeaf(TreeNode root, int k) { - map = new HashMap<>(); - minNode = new Pair(-1, Integer.MAX_VALUE); - findDistanceToLeaf(root); - findMin(root, k); - return minNode.n; + Pair(int n, int d) { + this.n = n; + this.d = d; } - - private Pair findDistanceToLeaf(TreeNode node){ - if(node != null){ - if(node.left == null && node.right == null){ - map.put(node.val, new Pair(node.val, 0)); - return new Pair(node.val, 1); - } else { - Pair left = findDistanceToLeaf(node.left); - Pair right = findDistanceToLeaf(node.right); - if(left.d < right.d){ - map.put(node.val, left); - return new Pair(left.n, left.d + 1); - } else{ - map.put(node.val, right); - return new Pair(right.n, right.d + 1); - } - } - } return new Pair(-1, Integer.MAX_VALUE); + } + + private Map map; + private Pair minNode; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(1); + root.left = new TreeNode(2); + root.right = new TreeNode(3); + root.left.left = new TreeNode(4); + root.left.left.left = new TreeNode(5); + root.left.left.left.left = new TreeNode(6); + // root.right = new TreeNode(3); + System.out.println(new ClosestLeafInABinaryTree().findClosestLeaf(root, 2)); + } + + public int findClosestLeaf(TreeNode root, int k) { + map = new HashMap<>(); + minNode = new Pair(-1, Integer.MAX_VALUE); + findDistanceToLeaf(root); + findMin(root, k); + return minNode.n; + } + + private Pair findDistanceToLeaf(TreeNode node) { + if (node != null) { + if (node.left == null && node.right == null) { + map.put(node.val, new Pair(node.val, 0)); + return new Pair(node.val, 1); + } else { + Pair left = findDistanceToLeaf(node.left); + Pair right = findDistanceToLeaf(node.right); + if (left.d < right.d) { + map.put(node.val, left); + return new Pair(left.n, left.d + 1); + } else { + map.put(node.val, right); + return new Pair(right.n, right.d + 1); + } + } } - - private int findMin(TreeNode node, int k){ - if(node != null){ - if(node.val == k){ - if(map.get(node.val).d < minNode.d){ - minNode = map.get(node.val); - } - return 1; - } else{ - int left = findMin(node.left, k); - int right = findMin(node.right, k); - if(left != -1){ - if((left + map.get(node.val).d) < minNode.d){ - minNode = new Pair(map.get(node.val).n, (left + map.get(node.val).d)); - } - return left + 1; - } - else if(right != -1){ - if((right + map.get(node.val).d) < minNode.d){ - minNode = new Pair(map.get(node.val).n, (right + map.get(node.val).d)); - } - return right + 1; - } - } + return new Pair(-1, Integer.MAX_VALUE); + } + + private int findMin(TreeNode node, int k) { + if (node != null) { + if (node.val == k) { + if (map.get(node.val).d < minNode.d) { + minNode = map.get(node.val); + } + return 1; + } else { + int left = findMin(node.left, k); + int right = findMin(node.right, k); + if (left != -1) { + if ((left + map.get(node.val).d) < minNode.d) { + minNode = new Pair(map.get(node.val).n, (left + map.get(node.val).d)); + } + return left + 1; + } else if (right != -1) { + if ((right + map.get(node.val).d) < minNode.d) { + minNode = new Pair(map.get(node.val).n, (right + map.get(node.val).d)); + } + return right + 1; } - return -1; + } } + return -1; + } } diff --git a/problems/src/tree/ConstructStringFromBinaryTree.java b/problems/src/tree/ConstructStringFromBinaryTree.java index d390eb03..7c63b612 100644 --- a/problems/src/tree/ConstructStringFromBinaryTree.java +++ b/problems/src/tree/ConstructStringFromBinaryTree.java @@ -1,74 +1,59 @@ package tree; /** - * Created by gouthamvidyapradhan on 10/06/2017. - * Accepted - * You need to construct a string consists of parenthesis and integers from a binary tree with the preorder traversing way. - *

- * The null node needs to be represented by empty parenthesis pair "()". And you need to omit all the empty parenthesis pairs that don't affect the one-to-one mapping relationship between the string and the original binary tree. - *

- * Example 1: - * Input: Binary tree: [1,2,3,4] - * 1 - * / \ - * 2 3 - * / - * 4 - *

- * Output: "1(2(4))(3)" - *

- * Explanation: Originallay it needs to be "1(2(4)())(3()())", - * but you need to omit all the unnecessary empty parenthesis pairs. - * And it will be "1(2(4))(3)". - * Example 2: - * Input: Binary tree: [1,2,3,null,4] - * 1 - * / \ - * 2 3 - * \ - * 4 - *

- * Output: "1(2()(4))(3)" - *

- * Explanation: Almost the same as the first example, - * except we can't omit the first parenthesis pair to break the one-to-one mapping relationship between the input and the output. + * Created by gouthamvidyapradhan on 10/06/2017. Accepted You need to construct a string consists of + * parenthesis and integers from a binary tree with the preorder traversing way. + * + *

The null node needs to be represented by empty parenthesis pair "()". And you need to omit all + * the empty parenthesis pairs that don't affect the one-to-one mapping relationship between the + * string and the original binary tree. + * + *

Example 1: Input: Binary tree: [1,2,3,4] 1 / \ 2 3 / 4 + * + *

Output: "1(2(4))(3)" + * + *

Explanation: Originallay it needs to be "1(2(4)())(3()())", but you need to omit all the + * unnecessary empty parenthesis pairs. And it will be "1(2(4))(3)". Example 2: Input: Binary tree: + * [1,2,3,null,4] 1 / \ 2 3 \ 4 + * + *

Output: "1(2()(4))(3)" + * + *

Explanation: Almost the same as the first example, except we can't omit the first parenthesis + * pair to break the one-to-one mapping relationship between the input and the output. */ public class ConstructStringFromBinaryTree { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - TreeNode t = new TreeNode(1); - t.left = new TreeNode(2); - t.left.left = new TreeNode(4); - t.right = new TreeNode(3); - System.out.println(new ConstructStringFromBinaryTree().tree2str(t)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + TreeNode t = new TreeNode(1); + t.left = new TreeNode(2); + t.left.left = new TreeNode(4); + t.right = new TreeNode(3); + System.out.println(new ConstructStringFromBinaryTree().tree2str(t)); + } - public String tree2str(TreeNode t) { - if (t == null) return ""; - String left = tree2str(t.left); - String right = tree2str(t.right); - if (left.equals("") && right.equals("")) - return String.valueOf(t.val); - if (left.equals("")) - left = "()"; - else left = "(" + left + ")"; - if (!right.equals("")) - right = "(" + right + ")"; - return t.val + left + right; - } + public String tree2str(TreeNode t) { + if (t == null) return ""; + String left = tree2str(t.left); + String right = tree2str(t.right); + if (left.equals("") && right.equals("")) return String.valueOf(t.val); + if (left.equals("")) left = "()"; + else left = "(" + left + ")"; + if (!right.equals("")) right = "(" + right + ")"; + return t.val + left + right; + } } diff --git a/problems/src/tree/ConvertBSTToGreaterTree.java b/problems/src/tree/ConvertBSTToGreaterTree.java index 74064013..ff3b0a4f 100644 --- a/problems/src/tree/ConvertBSTToGreaterTree.java +++ b/problems/src/tree/ConvertBSTToGreaterTree.java @@ -1,54 +1,52 @@ package tree; /** - * Created by gouthamvidyapradhan on 14/03/2019 - * Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed - * to the original key plus sum of all keys greater than the original key in BST. + * Created by gouthamvidyapradhan on 14/03/2019 Given a Binary Search Tree (BST), convert it to a + * Greater Tree such that every key of the original BST is changed to the original key plus sum of + * all keys greater than the original key in BST. * - * Example: + *

Example: * - * Input: The root of a Binary Search Tree like this: - * 5 - * / \ - * 2 13 + *

Input: The root of a Binary Search Tree like this: 5 / \ 2 13 * - * Output: The root of a Greater Tree like this: - * 18 - * / \ - * 20 13 + *

Output: The root of a Greater Tree like this: 18 / \ 20 13 */ public class ConvertBSTToGreaterTree { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } - } + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - /** - * Main method - * @param args - */ - public static void main(String[] args) { - TreeNode node = new TreeNode(5); - node.right = new TreeNode(13); - node.left = new TreeNode(2); - node.left.left = new TreeNode(1); - node.left.right = new TreeNode(3); - TreeNode result = new ConvertBSTToGreaterTree().convertBST(node); - System.out.println(result); + TreeNode(int x) { + val = x; } + } - public TreeNode convertBST(TreeNode root) { - postOrder(root, 0); - return root; - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + TreeNode node = new TreeNode(5); + node.right = new TreeNode(13); + node.left = new TreeNode(2); + node.left.left = new TreeNode(1); + node.left.right = new TreeNode(3); + TreeNode result = new ConvertBSTToGreaterTree().convertBST(node); + System.out.println(result); + } - private int postOrder(TreeNode node, int value){ - if(node == null) return value; - int right = postOrder(node.right, value); - node.val = node.val + right; - return postOrder(node.left, node.val); - } + public TreeNode convertBST(TreeNode root) { + postOrder(root, 0); + return root; + } + + private int postOrder(TreeNode node, int value) { + if (node == null) return value; + int right = postOrder(node.right, value); + node.val = node.val + right; + return postOrder(node.left, node.val); + } } diff --git a/problems/src/tree/ConvertSortedArrayToBST.java b/problems/src/tree/ConvertSortedArrayToBST.java index 5c9f7bbe..c2033157 100644 --- a/problems/src/tree/ConvertSortedArrayToBST.java +++ b/problems/src/tree/ConvertSortedArrayToBST.java @@ -1,37 +1,36 @@ package tree; /** - * Created by gouthamvidyapradhan on 09/03/2017. - * Given an array where elements are sorted in ascending order, convert it to a height balanced BST. + * Created by gouthamvidyapradhan on 09/03/2017. Given an array where elements are sorted in + * ascending order, convert it to a height balanced BST. */ public class ConvertSortedArrayToBST { - public class TreeNode { - int val; - TreeNode left; - TreeNode right; + public class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - public TreeNode sortedArrayToBST(int[] nums) { - if (nums.length == 0) return null; - return build(0, nums.length - 1, nums); - } + public TreeNode sortedArrayToBST(int[] nums) { + if (nums.length == 0) return null; + return build(0, nums.length - 1, nums); + } - private TreeNode build(int s, int e, int[] nums) { - if (s > e) return null; + private TreeNode build(int s, int e, int[] nums) { + if (s > e) return null; - int m = (e - s) / 2; - int node = nums[s + m]; - TreeNode root = new TreeNode(node); - if (s == e) - return root; + int m = (e - s) / 2; + int node = nums[s + m]; + TreeNode root = new TreeNode(node); + if (s == e) return root; - root.left = build(s, s + m - 1, nums); - root.right = build(s + m + 1, e, nums); + root.left = build(s, s + m - 1, nums); + root.right = build(s + m + 1, e, nums); - return root; - } + return root; + } } diff --git a/problems/src/tree/DiameterOfBinaryTree.java b/problems/src/tree/DiameterOfBinaryTree.java index fee3d54e..3f0954d3 100644 --- a/problems/src/tree/DiameterOfBinaryTree.java +++ b/problems/src/tree/DiameterOfBinaryTree.java @@ -3,53 +3,52 @@ /** * Created by gouthamvidyapradhan on 18/10/2017. * - * Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is - * the length of the longest path between any two nodes in a tree. This path may or may not pass through the root. - - Example: - Given a binary tree - 1 - / \ - 2 3 - / \ - 4 5 - Return 3, which is the length of the path [4,2,1,3] or [5,2,1,3]. - - Note: The length of path between two nodes is represented by the number of edges between them. + *

Given a binary tree, you need to compute the length of the diameter of the tree. The diameter + * of a binary tree is the length of the longest path between any two nodes in a tree. This path may + * or may not pass through the root. + * + *

Example: Given a binary tree 1 / \ 2 3 / \ 4 5 Return 3, which is the length of the path + * [4,2,1,3] or [5,2,1,3]. + * + *

Note: The length of path between two nodes is represented by the number of edges between them. */ public class DiameterOfBinaryTree { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } - } + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - private int max = 0; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - TreeNode root = new TreeNode(5); - root.left = new TreeNode(4); - System.out.println(new DiameterOfBinaryTree().diameterOfBinaryTree(root)); + TreeNode(int x) { + val = x; } + } - public int diameterOfBinaryTree(TreeNode root) { - dfs(root); - return max; - } + private int max = 0; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(5); + root.left = new TreeNode(4); + System.out.println(new DiameterOfBinaryTree().diameterOfBinaryTree(root)); + } + + public int diameterOfBinaryTree(TreeNode root) { + dfs(root); + return max; + } - private int dfs(TreeNode node){ - if(node != null){ - int left = dfs(node.left); - int right = dfs(node.right); - max = Math.max(max, left + right); - return left > right ? left + 1 : right + 1; - } - return 0; + private int dfs(TreeNode node) { + if (node != null) { + int left = dfs(node.left); + int right = dfs(node.right); + max = Math.max(max, left + right); + return left > right ? left + 1 : right + 1; } + return 0; + } } diff --git a/problems/src/tree/EqualTreePartition.java b/problems/src/tree/EqualTreePartition.java index b8590c7a..c4c44535 100644 --- a/problems/src/tree/EqualTreePartition.java +++ b/problems/src/tree/EqualTreePartition.java @@ -1,95 +1,76 @@ package tree; /** - * Created by gouthamvidyapradhan on 17/02/2018. - * Given a binary tree with n nodes, your task is to check if it's possible to partition the tree to two trees which - * have the equal sum of values after removing exactly one edge on the original tree. - - Example 1: - Input: - 5 - / \ - 10 10 - / \ - 2 3 - - Output: True - Explanation: - 5 - / - 10 + * Created by gouthamvidyapradhan on 17/02/2018. Given a binary tree with n nodes, your task is to + * check if it's possible to partition the tree to two trees which have the equal sum of values + * after removing exactly one edge on the original tree. + * + *

Example 1: Input: 5 / \ 10 10 / \ 2 3 + * + *

Output: True Explanation: 5 / 10 + * + *

Sum: 15 + * + *

10 / \ 2 3 + * + *

Sum: 15 Example 2: Input: 1 / \ 2 10 / \ 2 20 + * + *

Output: False Explanation: You can't split the tree into two trees with equal sum after + * removing exactly one edge on the tree. Note: The range of tree node value is in the range of + * [-100000, 100000]. 1 <= n <= 10000 + */ +public class EqualTreePartition { + public class TreeNode { + int val; + TreeNode left; + TreeNode right; - Sum: 15 + TreeNode(int x) { + val = x; + } + } - 10 - / \ - 2 3 + private long sum; + private boolean possible = false; - Sum: 15 - Example 2: - Input: - 1 - / \ - 2 10 - / \ - 2 20 + public static void main(String[] args) throws Exception {} - Output: False - Explanation: You can't split the tree into two trees with equal sum after removing exactly one edge on the tree. - Note: - The range of tree node value is in the range of [-100000, 100000]. - 1 <= n <= 10000 - */ + public boolean checkEqualTree(TreeNode root) { + sum = 0L; + getSum(root); + getDiff(root); + return possible; + } -public class EqualTreePartition { - public class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } + private void getSum(TreeNode node) { + if (node != null) { + sum += node.val; + getSum(node.left); + getSum(node.right); } - private long sum; - private boolean possible = false; - - public static void main(String[] args) throws Exception{ + } + private Long getDiff(TreeNode node) { + if (node == null) return null; + Long left = getDiff(node.left); + Long right = getDiff(node.right); + if (left != null) { + if ((sum - left) == left) { + possible = true; + } } - - public boolean checkEqualTree(TreeNode root) { - sum = 0L; - getSum(root); - getDiff(root); - return possible; + if (right != null) { + if ((sum - right) == right) { + possible = true; + } } - - private void getSum(TreeNode node){ - if(node != null){ - sum += node.val; - getSum(node.left); - getSum(node.right); - } + Long curr = (long) node.val; + if (left != null) { + curr += left; } - - private Long getDiff(TreeNode node){ - if(node == null) return null; - Long left = getDiff(node.left); - Long right = getDiff(node.right); - if(left != null){ - if((sum - left) == left){ - possible = true; - } - }if(right != null){ - if((sum - right) == right){ - possible = true; - } - } - Long curr = (long)node.val; - if(left != null){ - curr += left; - } if(right != null){ - curr += right; - } - return curr; + if (right != null) { + curr += right; } - + return curr; + } } diff --git a/problems/src/tree/FindBottomLeftTreeValue.java b/problems/src/tree/FindBottomLeftTreeValue.java index 0624e351..2de54d84 100644 --- a/problems/src/tree/FindBottomLeftTreeValue.java +++ b/problems/src/tree/FindBottomLeftTreeValue.java @@ -1,70 +1,56 @@ package tree; /** - * Created by gouthamvidyapradhan on 30/08/2017. - * Given a binary tree, find the leftmost value in the last row of the tree. - *

- * Example 1: - * Input: - *

- * 2 - * / \ - * 1 3 - *

- * Output: - * 1 - * Example 2: - * Input: - *

- * 1 - * / \ - * 2 3 - * / / \ - * 4 5 6 - * / - * 7 - *

- * Output: - * 7 - * Note: You may assume the tree (i.e., the given root node) is not NULL. + * Created by gouthamvidyapradhan on 30/08/2017. Given a binary tree, find the leftmost value in the + * last row of the tree. + * + *

Example 1: Input: + * + *

2 / \ 1 3 + * + *

Output: 1 Example 2: Input: + * + *

1 / \ 2 3 / / \ 4 5 6 / 7 + * + *

Output: 7 Note: You may assume the tree (i.e., the given root node) is not NULL. */ public class FindBottomLeftTreeValue { - private int max = 0, result; + private int max = 0, result; - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - public static void main(String[] args) throws Exception { - TreeNode root = new TreeNode(1); - root.left = new TreeNode(2); - root.left.left = new TreeNode(4); - root.right = new TreeNode(3); - root.right.left = new TreeNode(5); - root.right.left.left = new TreeNode(7); - root.right.right = new TreeNode(6); - System.out.println(new FindBottomLeftTreeValue().findBottomLeftValue(root)); - } + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(1); + root.left = new TreeNode(2); + root.left.left = new TreeNode(4); + root.right = new TreeNode(3); + root.right.left = new TreeNode(5); + root.right.left.left = new TreeNode(7); + root.right.right = new TreeNode(6); + System.out.println(new FindBottomLeftTreeValue().findBottomLeftValue(root)); + } - public int findBottomLeftValue(TreeNode root) { - preorder(root, 1); - return result; - } + public int findBottomLeftValue(TreeNode root) { + preorder(root, 1); + return result; + } - private void preorder(TreeNode node, int level) { - if (node != null) { - if (level > max) { - result = node.val; - max = level; - } - preorder(node.left, level + 1); - preorder(node.right, level + 1); - } + private void preorder(TreeNode node, int level) { + if (node != null) { + if (level > max) { + result = node.val; + max = level; + } + preorder(node.left, level + 1); + preorder(node.right, level + 1); } + } } diff --git a/problems/src/tree/FlattenBinaryTree.java b/problems/src/tree/FlattenBinaryTree.java index 65024e51..dfcaad3c 100644 --- a/problems/src/tree/FlattenBinaryTree.java +++ b/problems/src/tree/FlattenBinaryTree.java @@ -1,95 +1,76 @@ package tree; /** - * Created by gouthamvidyapradhan on 04/07/2017. - * Given a binary tree, flatten it to a linked list in-place. - *

- * For example, - * Given - *

- * 1 - * / \ - * 2 5 - * / \ \ - * 3 4 6 - *

- * The flattened tree should look like: - * 1 - * \ - * 2 - * \ - * 3 - * \ - * 4 - * \ - * 5 - * \ - * 6 - *

- * Solution: Do a pre-order traversal and maintain head and tail of a linked list at each recursive step. - * i. Join the current node to the head of the left sub-list to form the current node as the new head. - * ii. Join the tail of the left sub-list to the head of the right sub-list. + * Created by gouthamvidyapradhan on 04/07/2017. Given a binary tree, flatten it to a linked list + * in-place. + * + *

For example, Given + * + *

1 / \ 2 5 / \ \ 3 4 6 + * + *

The flattened tree should look like: 1 \ 2 \ 3 \ 4 \ 5 \ 6 + * + *

Solution: Do a pre-order traversal and maintain head and tail of a linked list at each + * recursive step. i. Join the current node to the head of the left sub-list to form the current + * node as the new head. ii. Join the tail of the left sub-list to the head of the right sub-list. * iii. Mark the left of the current node as null */ public class FlattenBinaryTree { - /** - * Class to keep track of head and tail - */ - private class LinkNode { - TreeNode head; - TreeNode tail; + /** Class to keep track of head and tail */ + private class LinkNode { + TreeNode head; + TreeNode tail; - LinkNode(TreeNode head, TreeNode tail) { - this.head = head; - this.tail = tail; - } + LinkNode(TreeNode head, TreeNode tail) { + this.head = head; + this.tail = tail; } + } - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - public static void main(String[] args) throws Exception { - TreeNode root = new TreeNode(3); - root.left = new TreeNode(2); - root.right = new TreeNode(1); - new FlattenBinaryTree().flatten(root); - System.out.print(root.val + " "); - System.out.print(root.right.val + " "); - System.out.print(root.right.right.val); - } + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(3); + root.left = new TreeNode(2); + root.right = new TreeNode(1); + new FlattenBinaryTree().flatten(root); + System.out.print(root.val + " "); + System.out.print(root.right.val + " "); + System.out.print(root.right.right.val); + } - public void flatten(TreeNode root) { - preOrder(root); - } + public void flatten(TreeNode root) { + preOrder(root); + } - private LinkNode preOrder(TreeNode node) { - if (node == null) return null; - LinkNode left = preOrder(node.left); - LinkNode right = preOrder(node.right); - LinkNode lNode; - if (left == null && right == null) { - lNode = new LinkNode(node, node); - } else if (left == null) { - node.right = right.head; - lNode = new LinkNode(node, right.tail); - } else if (right == null) { - node.right = left.head; - lNode = new LinkNode(node, left.tail); - } else { - node.right = left.head; - left.tail.right = right.head; - lNode = new LinkNode(node, right.tail); - } - node.left = null; - return lNode; + private LinkNode preOrder(TreeNode node) { + if (node == null) return null; + LinkNode left = preOrder(node.left); + LinkNode right = preOrder(node.right); + LinkNode lNode; + if (left == null && right == null) { + lNode = new LinkNode(node, node); + } else if (left == null) { + node.right = right.head; + lNode = new LinkNode(node, right.tail); + } else if (right == null) { + node.right = left.head; + lNode = new LinkNode(node, left.tail); + } else { + node.right = left.head; + left.tail.right = right.head; + lNode = new LinkNode(node, right.tail); } - + node.left = null; + return lNode; + } } diff --git a/problems/src/tree/InorderSuccessorInBST.java b/problems/src/tree/InorderSuccessorInBST.java index 79399792..3150230e 100644 --- a/problems/src/tree/InorderSuccessorInBST.java +++ b/problems/src/tree/InorderSuccessorInBST.java @@ -1,71 +1,70 @@ package tree; /** - * Created by gouthamvidyapradhan on 14/05/2017. - * Given a binary search tree and a node in it, find the in-order successor of that node in the BST. - *

- * Note: If the given node has no in-order successor in the tree, return null. - *

- * Solution: The below solution works with worst case time complexity of O(h) where h is the height of the tree. - * If the current node is <= target_node, recursively iterate the right of the current node. - * else if the current node is > target_node then mark the current node as the successor and recursively iterate the left of the current node. + * Created by gouthamvidyapradhan on 14/05/2017. Given a binary search tree and a node in it, find + * the in-order successor of that node in the BST. + * + *

Note: If the given node has no in-order successor in the tree, return null. + * + *

Solution: The below solution works with worst case time complexity of O(h) where h is the + * height of the tree. If the current node is <= target_node, recursively iterate the right of the + * current node. else if the current node is > target_node then mark the current node as the + * successor and recursively iterate the left of the current node. */ public class InorderSuccessorInBST { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - TreeNode root = new TreeNode(10); - root.left = new TreeNode(5); - root.left.left = new TreeNode(3); - root.left.right = new TreeNode(6); - root.right = new TreeNode(15); - root.right.left = new TreeNode(13); - root.right.left.left = new TreeNode(12); - root.right.left.right = new TreeNode(14); - root.right.right = new TreeNode(17); - TreeNode ans = new InorderSuccessorInBST().inorderSuccessor(root, root.right.left.right); - if (ans != null) - System.out.println(ans.val); - else System.out.println(ans); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(10); + root.left = new TreeNode(5); + root.left.left = new TreeNode(3); + root.left.right = new TreeNode(6); + root.right = new TreeNode(15); + root.right.left = new TreeNode(13); + root.right.left.left = new TreeNode(12); + root.right.left.right = new TreeNode(14); + root.right.right = new TreeNode(17); + TreeNode ans = new InorderSuccessorInBST().inorderSuccessor(root, root.right.left.right); + if (ans != null) System.out.println(ans.val); + else System.out.println(ans); + } - /** - * Find successor - * - * @param root root node - * @param p target - * @return successor - */ - public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { - return inOrder(root, p, null); - } + /** + * Find successor + * + * @param root root node + * @param p target + * @return successor + */ + public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { + return inOrder(root, p, null); + } - /** - * Inorder traversal - * - * @param curr current node - * @param target target node - * @param successor successor - * @return successor node - */ - private TreeNode inOrder(TreeNode curr, TreeNode target, TreeNode successor) { - if (curr == null) return successor; - if (curr.val <= target.val) - return inOrder(curr.right, target, successor); - return inOrder(curr.left, target, curr); //make the current node as successor - } + /** + * Inorder traversal + * + * @param curr current node + * @param target target node + * @param successor successor + * @return successor node + */ + private TreeNode inOrder(TreeNode curr, TreeNode target, TreeNode successor) { + if (curr == null) return successor; + if (curr.val <= target.val) return inOrder(curr.right, target, successor); + return inOrder(curr.left, target, curr); // make the current node as successor + } } diff --git a/problems/src/tree/LCA.java b/problems/src/tree/LCA.java index c34799f9..ccd284d4 100644 --- a/problems/src/tree/LCA.java +++ b/problems/src/tree/LCA.java @@ -1,52 +1,45 @@ package tree; /** - * Created by gouthamvidyapradhan on 21/03/2017. - * 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 v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” - *

- * _______3______ - * / \ - * ___5__ ___1__ - * / \ / \ - * 6 _2 0 8 - * / \ - * 7 4 - * For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition. + * Created by gouthamvidyapradhan on 21/03/2017. 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 v and w as the lowest node in T that has both v and w as descendants (where we + * allow a node to be a descendant of itself).” + * + *

_______3______ / \ ___5__ ___1__ / \ / \ 6 _2 0 8 / \ 7 4 For example, the lowest common + * ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node + * can be a descendant of itself according to the LCA definition. */ public class LCA { - public class TreeNode { - int val; - TreeNode left; - TreeNode right; + public class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception {} + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root != null) { + if (root.equals(p) || root.equals(q)) return root; + TreeNode left = lowestCommonAncestor(root.left, p, q); + TreeNode right = lowestCommonAncestor(root.right, p, q); + if (left != null && right != null) return root; + else if (left != null) return left; + else return right; } - - public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { - if (root != null) { - if (root.equals(p) || root.equals(q)) return root; - TreeNode left = lowestCommonAncestor(root.left, p, q); - TreeNode right = lowestCommonAncestor(root.right, p, q); - if (left != null && right != null) return root; - else if (left != null) return left; - else return right; - } - return null; - } - - + return null; + } } diff --git a/problems/src/tree/LargestBSTSubtree.java b/problems/src/tree/LargestBSTSubtree.java index 43c6dfe8..4b58398b 100644 --- a/problems/src/tree/LargestBSTSubtree.java +++ b/problems/src/tree/LargestBSTSubtree.java @@ -2,116 +2,104 @@ /** * Created by gouthamvidyapradhan on 08/05/2017. - *

- * Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest means subtree with largest number of nodes in it. - *

- * Note: - * A subtree must include all of its descendants. - * Here's an example: - * 10 - * / \ - * 5 15 - * / \ \ - * 1 8 7 - * The Largest BST Subtree in this case is the highlighted one (5-1-8). - * The return value is the subtree's size, which is 3. - *

- * Follow up: - * Can you figure out ways to solve it with O(n) time complexity? - *

- * Solution: The below solution works with O(n). Validate the BST property from the leaf node and increment the count, as soon as a violation - * of BST property is found terminate the count. + * + *

Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where + * largest means subtree with largest number of nodes in it. + * + *

Note: A subtree must include all of its descendants. Here's an example: 10 / \ 5 15 / \ \ 1 8 + * 7 The Largest BST Subtree in this case is the highlighted one (5-1-8). The return value is the + * subtree's size, which is 3. + * + *

Follow up: Can you figure out ways to solve it with O(n) time complexity? + * + *

Solution: The below solution works with O(n). Validate the BST property from the leaf node and + * increment the count, as soon as a violation of BST property is found terminate the count. */ public class LargestBSTSubtree { - /** - * Range class - */ - private class Range { - int min, max, count; + /** Range class */ + private class Range { + int min, max, count; - Range(int min, int max, int count) { - this.min = min; - this.max = max; - this.count = count; - } + Range(int min, int max, int count) { + this.min = min; + this.max = max; + this.count = count; } + } - /** - * TreeNode - */ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + /** TreeNode */ + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - /** - * Count - */ - private static int count = 0; + /** Count */ + private static int count = 0; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - TreeNode root = new TreeNode(10); - root.left = new TreeNode(9); - root.left.left = new TreeNode(8); - System.out.println(new LargestBSTSubtree().largestBSTSubtree(root)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(10); + root.left = new TreeNode(9); + root.left.left = new TreeNode(8); + System.out.println(new LargestBSTSubtree().largestBSTSubtree(root)); + } - /** - * Largest subtree count - * - * @param root root node - * @return count - */ - public int largestBSTSubtree(TreeNode root) { - getCount(root); - return count; - } + /** + * Largest subtree count + * + * @param root root node + * @return count + */ + public int largestBSTSubtree(TreeNode root) { + getCount(root); + return count; + } - /** - * Get count - * - * @param node root node - * @return Range - */ - private Range getCount(TreeNode node) { - if (node == null) return null; - Range left = getCount(node.left); - Range right = getCount(node.right); - if (left == null && right == null) { - count = Math.max(count, 1); - return new Range(node.val, node.val, 1); - } else if (left == null) { - if (node.val < right.min && right.count != -1) //check for -1 ensures that there is no violation of BST property - return countMaxAndBuildNewRange(right.count + 1, node.val, right.max); - } else if (right == null) { - if (node.val > left.max && left.count != -1) - return countMaxAndBuildNewRange(left.count + 1, left.min, node.val); - } else if (node.val > left.max && node.val < right.min && right.count != -1 && left.count != -1) - return countMaxAndBuildNewRange(left.count + right.count + 1, left.min, right.max); - return new Range(0, 0, -1); //violation of BST property - } + /** + * Get count + * + * @param node root node + * @return Range + */ + private Range getCount(TreeNode node) { + if (node == null) return null; + Range left = getCount(node.left); + Range right = getCount(node.right); + if (left == null && right == null) { + count = Math.max(count, 1); + return new Range(node.val, node.val, 1); + } else if (left == null) { + if (node.val < right.min + && right.count != -1) // check for -1 ensures that there is no violation of BST property + return countMaxAndBuildNewRange(right.count + 1, node.val, right.max); + } else if (right == null) { + if (node.val > left.max && left.count != -1) + return countMaxAndBuildNewRange(left.count + 1, left.min, node.val); + } else if (node.val > left.max && node.val < right.min && right.count != -1 && left.count != -1) + return countMaxAndBuildNewRange(left.count + right.count + 1, left.min, right.max); + return new Range(0, 0, -1); // violation of BST property + } - /** - * Record max and build new range - * - * @param sum total sum - * @param min min - * @param max max - * @return new Range - */ - private Range countMaxAndBuildNewRange(int sum, int min, int max) { - count = Math.max(count, sum); - return new Range(min, max, sum); - } + /** + * Record max and build new range + * + * @param sum total sum + * @param min min + * @param max max + * @return new Range + */ + private Range countMaxAndBuildNewRange(int sum, int min, int max) { + count = Math.max(count, sum); + return new Range(min, max, sum); + } } diff --git a/problems/src/tree/LowestCommonAncestorBST.java b/problems/src/tree/LowestCommonAncestorBST.java index d8e9091c..80591d92 100644 --- a/problems/src/tree/LowestCommonAncestorBST.java +++ b/problems/src/tree/LowestCommonAncestorBST.java @@ -1,48 +1,37 @@ package tree; /** - * Created by gouthamvidyapradhan on 09/03/2017. - * Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. - *

- * According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” - *

- * _______6______ - * / \ - * ___2__ ___8__ - * / \ / \ - * 0 _4 7 9 - * / \ - * 3 5 - * For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition. + * Created by gouthamvidyapradhan on 09/03/2017. Given a binary search tree (BST), find the lowest + * common ancestor (LCA) of two given nodes in the BST. + * + *

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined + * between two nodes v and w as the lowest node in T that has both v and w as descendants (where we + * allow a node to be a descendant of itself).” + * + *

_______6______ / \ ___2__ ___8__ / \ / \ 0 _4 7 9 / \ 3 5 For example, the lowest common + * ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node + * can be a descendant of itself according to the LCA definition. */ - public class LowestCommonAncestorBST { - class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } - - public static void main(String[] args) throws Exception { + class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { + val = x; } + } - private TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { - if (root == null) return null; + public static void main(String[] args) throws Exception {} - if (p.val == root.val || q.val == root.val) return root; + private TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == null) return null; - else if ((p.val < root.val && q.val > root.val) || (q.val < root.val && p.val > root.val)) - return root; - - else if (p.val < root.val && q.val < root.val) - return lowestCommonAncestor(root.left, p, q); - - else - return lowestCommonAncestor(root.right, p, q); - } + if (p.val == root.val || q.val == root.val) return root; + else if ((p.val < root.val && q.val > root.val) || (q.val < root.val && p.val > root.val)) + return root; + else if (p.val < root.val && q.val < root.val) return lowestCommonAncestor(root.left, p, q); + else return lowestCommonAncestor(root.right, p, q); + } } diff --git a/problems/src/tree/MaximumBinaryTree.java b/problems/src/tree/MaximumBinaryTree.java index 4af5a666..d8b47275 100644 --- a/problems/src/tree/MaximumBinaryTree.java +++ b/problems/src/tree/MaximumBinaryTree.java @@ -1,83 +1,74 @@ package tree; /** - * Created by gouthamvidyapradhan on 19/08/2017. - * Given an integer array with no duplicates. A maximum tree building on this array is defined as follow: - *

- * The root is the maximum number in the array. - * The left subtree is the maximum tree constructed from left part subarray divided by the maximum number. - * The right subtree is the maximum tree constructed from right part subarray divided by the maximum number. - * Construct the maximum tree by the given array and output the root node of this tree. - *

- * Example 1: - * Input: [3,2,1,6,0,5] - * Output: return the tree root node representing the following tree: - *

- * 6 - * / \ - * 3 5 - * \ / - * 2 0 - * \ - * 1 - *

- * Note: - * The size of the given array will be in the range [1,1000]. + * Created by gouthamvidyapradhan on 19/08/2017. Given an integer array with no duplicates. A + * maximum tree building on this array is defined as follow: + * + *

The root is the maximum number in the array. The left subtree is the maximum tree constructed + * from left part subarray divided by the maximum number. The right subtree is the maximum tree + * constructed from right part subarray divided by the maximum number. Construct the maximum tree by + * the given array and output the root node of this tree. + * + *

Example 1: Input: [3,2,1,6,0,5] Output: return the tree root node representing the following + * tree: + * + *

6 / \ 3 5 \ / 2 0 \ 1 + * + *

Note: The size of the given array will be in the range [1,1000]. */ public class MaximumBinaryTree { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - private int[][] max; + private int[][] max; - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] nums = {3, 2, 1, 6, 0, 5}; - TreeNode root = new MaximumBinaryTree().constructMaximumBinaryTree(nums); - System.out.println(root.val); //print root - } - - public TreeNode constructMaximumBinaryTree(int[] nums) { - - max = new int[nums.length][nums.length]; + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] nums = {3, 2, 1, 6, 0, 5}; + TreeNode root = new MaximumBinaryTree().constructMaximumBinaryTree(nums); + System.out.println(root.val); // print root + } - //pre-fill with initial values - for (int i = 0; i < nums.length; i++) { - max[i][i] = i; - } + public TreeNode constructMaximumBinaryTree(int[] nums) { - //pre-calculate max for range index - for (int i = 0; i < nums.length; i++) { - for (int j = i + 1; j < nums.length; j++) { - max[i][j] = nums[max[i][j - 1]] > nums[j] ? max[i][j - 1] : j; - } - } + max = new int[nums.length][nums.length]; - return build(0, nums.length - 1, nums); + // pre-fill with initial values + for (int i = 0; i < nums.length; i++) { + max[i][i] = i; } - private TreeNode build(int s, int e, int[] nums) { - if (s <= e) { - int val = nums[max[s][e]]; - TreeNode n = new TreeNode(val); - n.left = build(s, max[s][e] - 1, nums); - n.right = build(max[s][e] + 1, e, nums); - return n; - } - return null; + // pre-calculate max for range index + for (int i = 0; i < nums.length; i++) { + for (int j = i + 1; j < nums.length; j++) { + max[i][j] = nums[max[i][j - 1]] > nums[j] ? max[i][j - 1] : j; + } } + return build(0, nums.length - 1, nums); + } + + private TreeNode build(int s, int e, int[] nums) { + if (s <= e) { + int val = nums[max[s][e]]; + TreeNode n = new TreeNode(val); + n.left = build(s, max[s][e] - 1, nums); + n.right = build(max[s][e] + 1, e, nums); + return n; + } + return null; + } } diff --git a/problems/src/tree/MaximumWidthOfBinaryTree.java b/problems/src/tree/MaximumWidthOfBinaryTree.java index 4ca38690..9536e1d2 100644 --- a/problems/src/tree/MaximumWidthOfBinaryTree.java +++ b/problems/src/tree/MaximumWidthOfBinaryTree.java @@ -6,97 +6,74 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 03/05/2018. - * 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. - - The width of one level is defined as the length between the end-nodes (the leftmost and right most non-null nodes in the level, where the null nodes between the end-nodes are also counted into the length calculation. - - Example 1: - Input: - - 1 - / \ - 3 2 - / \ \ - 5 3 9 - - Output: 4 - Explanation: The maximum width existing in the third level with the length 4 (5,3,null,9). - Example 2: - Input: - - 1 - / - 3 - / \ - 5 3 - - Output: 2 - Explanation: The maximum width existing in the third level with the length 2 (5,3). - Example 3: - Input: - - 1 - / \ - 3 2 - / - 5 - - Output: 2 - Explanation: The maximum width existing in the second level with the length 2 (3,2). - Example 4: - Input: - - 1 - / \ - 3 2 - / \ - 5 9 - / \ - 6 7 - Output: 8 - Explanation:The maximum width existing in the fourth level with the length 8 (6,null,null,null,null,null,null,7). - - - Solution: O(N): General idea is to give a position value to each node. - On every left traversal give the value curr_pos * 2 and on every right traversal give the value curr_pos * 2 + 1 - Calculate maximum width for each level using right - left + 1 + * Created by gouthamvidyapradhan on 03/05/2018. 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. + * + *

The width of one level is defined as the length between the end-nodes (the leftmost and right + * most non-null nodes in the level, where the null nodes between the end-nodes are also counted + * into the length calculation. + * + *

Example 1: Input: + * + *

1 / \ 3 2 / \ \ 5 3 9 + * + *

Output: 4 Explanation: The maximum width existing in the third level with the length 4 + * (5,3,null,9). Example 2: Input: + * + *

1 / 3 / \ 5 3 + * + *

Output: 2 Explanation: The maximum width existing in the third level with the length 2 (5,3). + * Example 3: Input: + * + *

1 / \ 3 2 / 5 + * + *

Output: 2 Explanation: The maximum width existing in the second level with the length 2 (3,2). + * Example 4: Input: + * + *

1 / \ 3 2 / \ 5 9 / \ 6 7 Output: 8 Explanation:The maximum width existing in the fourth level + * with the length 8 (6,null,null,null,null,null,null,7). + * + *

Solution: O(N): General idea is to give a position value to each node. On every left traversal + * give the value curr_pos * 2 and on every right traversal give the value curr_pos * 2 + 1 + * Calculate maximum width for each level using right - left + 1 */ public class MaximumWidthOfBinaryTree { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } - } - - private Map> map; - public static void main(String[] args) { + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { + val = x; } - - public int widthOfBinaryTree(TreeNode root) { - map = new HashMap<>(); - preorder(root, 1, 1); - int max = 0; - for(int k : map.keySet()){ - List list = map.get(k); - if(list.size() == 1){ - max = Math.max(max, 1); - } else { - max = Math.max(max, list.get(list.size() - 1) - list.get(0) + 1); - } - } - return max; + } + + private Map> map; + + public static void main(String[] args) {} + + public int widthOfBinaryTree(TreeNode root) { + map = new HashMap<>(); + preorder(root, 1, 1); + int max = 0; + for (int k : map.keySet()) { + List list = map.get(k); + if (list.size() == 1) { + max = Math.max(max, 1); + } else { + max = Math.max(max, list.get(list.size() - 1) - list.get(0) + 1); + } } - - private void preorder(TreeNode node, int level, int pos){ - if(node != null){ - preorder(node.left, level + 1, pos * 2); - map.putIfAbsent(level, new ArrayList<>()); - map.get(level).add(pos); - preorder(node.right, level + 1, pos * 2 + 1); - } + return max; + } + + private void preorder(TreeNode node, int level, int pos) { + if (node != null) { + preorder(node.left, level + 1, pos * 2); + map.putIfAbsent(level, new ArrayList<>()); + map.get(level).add(pos); + preorder(node.right, level + 1, pos * 2 + 1); } - + } } diff --git a/problems/src/tree/MinimumAbsoluteDifferenceInBST.java b/problems/src/tree/MinimumAbsoluteDifferenceInBST.java index 7714bc88..7be241e4 100644 --- a/problems/src/tree/MinimumAbsoluteDifferenceInBST.java +++ b/problems/src/tree/MinimumAbsoluteDifferenceInBST.java @@ -1,57 +1,52 @@ package tree; /** - * Created by gouthamvidyapradhan on 15/02/2018. - * Given a binary search tree with non-negative values, find the minimum absolute difference between values of any - * two nodes. - - Example: - - Input: - - 1 - \ - 3 - / - 2 - - Output: - 1 - - Explanation: - The minimum absolute difference is 1, which is the difference between 2 and 1 (or between 2 and 3). - Note: There are at least two nodes in this BST. + * Created by gouthamvidyapradhan on 15/02/2018. Given a binary search tree with non-negative + * values, find the minimum absolute difference between values of any two nodes. + * + *

Example: + * + *

Input: + * + *

1 \ 3 / 2 + * + *

Output: 1 + * + *

Explanation: The minimum absolute difference is 1, which is the difference between 2 and 1 (or + * between 2 and 3). Note: There are at least two nodes in this BST. */ public class MinimumAbsoluteDifferenceInBST { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } - } + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - int min = Integer.MAX_VALUE; - - public static void main(String[] args) throws Exception{ - TreeNode root = new TreeNode(1); - root.right = new TreeNode(2); - root.right.right = new TreeNode(3); - new MinimumAbsoluteDifferenceInBST().getMinimumDifference(root); + TreeNode(int x) { + val = x; } - - public int getMinimumDifference(TreeNode root) { - getMin(root, null); - return min; + } + + int min = Integer.MAX_VALUE; + + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(1); + root.right = new TreeNode(2); + root.right.right = new TreeNode(3); + new MinimumAbsoluteDifferenceInBST().getMinimumDifference(root); + } + + public int getMinimumDifference(TreeNode root) { + getMin(root, null); + return min; + } + + private Integer getMin(TreeNode node, Integer prev) { + if (node == null) return prev; + Integer left = getMin(node.left, prev); + if (left != null) { + min = Math.min(min, Math.abs(node.val - left)); } - - private Integer getMin(TreeNode node, Integer prev){ - if(node == null) return prev; - Integer left = getMin(node.left, prev); - if(left != null){ - min = Math.min(min, Math.abs(node.val - left)); - } - return getMin(node.right, node.val); - } - + return getMin(node.right, node.val); + } } diff --git a/problems/src/tree/MostFrequentSubtreeSum.java b/problems/src/tree/MostFrequentSubtreeSum.java index aa8a2250..1f0a0261 100644 --- a/problems/src/tree/MostFrequentSubtreeSum.java +++ b/problems/src/tree/MostFrequentSubtreeSum.java @@ -6,84 +6,74 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 27/03/2017. - * Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). So what is the most frequent subtree sum value? If there is a tie, return all the values with the highest frequency in any order. - *

- * Examples 1 - * Input: - *

- * 5 - * / \ - * 2 -3 - * return [2, -3, 4], since all the values happen only once, return all of them in any order. - * Examples 2 - * Input: - *

- * 5 - * / \ - * 2 -5 - * return [2], since 2 happens twice, however -5 only occur once. - * Note: You may assume the sum of values in any subtree is in the range of 32-bit signed integer. + * Created by gouthamvidyapradhan on 27/03/2017. Given the root of a tree, you are asked to find the + * most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values + * formed by the subtree rooted at that node (including the node itself). So what is the most + * frequent subtree sum value? If there is a tie, return all the values with the highest frequency + * in any order. + * + *

Examples 1 Input: + * + *

5 / \ 2 -3 return [2, -3, 4], since all the values happen only once, return all of them in any + * order. Examples 2 Input: + * + *

5 / \ 2 -5 return [2], since 2 happens twice, however -5 only occur once. Note: You may assume + * the sum of values in any subtree is in the range of 32-bit signed integer. */ public class MostFrequentSubtreeSum { - static class TreeNode { - int val; - TreeNode left; - TreeNode right; + static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - private Map> fList = new HashMap<>(); - private Map fCount = new HashMap<>(); + private Map> fList = new HashMap<>(); + private Map fCount = new HashMap<>(); - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - MostFrequentSubtreeSum mfs = new MostFrequentSubtreeSum(); - TreeNode node = new TreeNode(5); - //node.left = new TreeNode(2); - //node.right = new TreeNode(-5); - int[] result = mfs.findFrequentTreeSum(node); - } - - public int[] findFrequentTreeSum(TreeNode root) { - int[] resArr = new int[0]; - if (root == null) return resArr; - postOrder(root); - for (Map.Entry entry : fCount.entrySet()) { - int frequency = entry.getValue(); - List list = fList.get(frequency); - if (list == null) - list = new ArrayList<>(); - list.add(entry.getKey()); - fList.put(frequency, list); - } - int max = Integer.MIN_VALUE; - List result; - for (int key : fList.keySet()) - max = Math.max(max, key); - result = fList.get(max); - resArr = new int[result.size()]; - for (int i = 0, l = resArr.length; i < l; i++) - resArr[i] = result.get(i); - return resArr; - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + MostFrequentSubtreeSum mfs = new MostFrequentSubtreeSum(); + TreeNode node = new TreeNode(5); + // node.left = new TreeNode(2); + // node.right = new TreeNode(-5); + int[] result = mfs.findFrequentTreeSum(node); + } - private int postOrder(TreeNode root) { - if (root == null) return 0; - int sum = postOrder(root.left) + postOrder(root.right) + root.val; - Integer fSum = fCount.get(sum); - if (fSum == null) - fCount.put(sum, 1); - else fCount.put(sum, fSum + 1); - return sum; + public int[] findFrequentTreeSum(TreeNode root) { + int[] resArr = new int[0]; + if (root == null) return resArr; + postOrder(root); + for (Map.Entry entry : fCount.entrySet()) { + int frequency = entry.getValue(); + List list = fList.get(frequency); + if (list == null) list = new ArrayList<>(); + list.add(entry.getKey()); + fList.put(frequency, list); } + int max = Integer.MIN_VALUE; + List result; + for (int key : fList.keySet()) max = Math.max(max, key); + result = fList.get(max); + resArr = new int[result.size()]; + for (int i = 0, l = resArr.length; i < l; i++) resArr[i] = result.get(i); + return resArr; + } + private int postOrder(TreeNode root) { + if (root == null) return 0; + int sum = postOrder(root.left) + postOrder(root.right) + root.val; + Integer fSum = fCount.get(sum); + if (fSum == null) fCount.put(sum, 1); + else fCount.put(sum, fSum + 1); + return sum; + } } diff --git a/problems/src/tree/NextRightPointer.java b/problems/src/tree/NextRightPointer.java index 5f12415f..f082e2ad 100644 --- a/problems/src/tree/NextRightPointer.java +++ b/problems/src/tree/NextRightPointer.java @@ -5,87 +5,72 @@ /** * Created by gouthamvidyapradhan on 07/07/2017. - *

- * Given a binary tree - *

- * struct TreeLinkNode { - * TreeLinkNode *left; - * TreeLinkNode *right; - * TreeLinkNode *next; - * } - * Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. - *

- * Initially, all next pointers are set to NULL. - *

- * Note: - *

- * You may only use constant extra space. - * You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children). - * For example, - * Given the following perfect binary tree, - * 1 - * / \ - * 2 3 - * / \ / \ - * 4 5 6 7 - * After calling your function, the tree should look like: - * 1 -> NULL - * / \ - * 2 -> 3 -> NULL - * / \ / \ - * 4->5->6->7 -> NULL - *

- * Solution: Perform a level order traversal using BFS, keep track of prev node at each level. Link the prev node to - * current node if both the nodes are in the same level. + * + *

Given a binary tree + * + *

struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; } Populate + * each next pointer to point to its next right node. If there is no next right node, the next + * pointer should be set to NULL. + * + *

Initially, all next pointers are set to NULL. + * + *

Note: + * + *

You may only use constant extra space. You may assume that it is a perfect binary tree (ie, + * all leaves are at the same level, and every parent has two children). For example, Given the + * following perfect binary tree, 1 / \ 2 3 / \ / \ 4 5 6 7 After calling your function, the tree + * should look like: 1 -> NULL / \ 2 -> 3 -> NULL / \ / \ 4->5->6->7 -> NULL + * + *

Solution: Perform a level order traversal using BFS, keep track of prev node at each level. + * Link the prev node to current node if both the nodes are in the same level. */ public class NextRightPointer { - private class LevelNode { - int level; - TreeLinkNode node; + private class LevelNode { + int level; + TreeLinkNode node; - LevelNode(TreeLinkNode node, int level) { - this.node = node; - this.level = level; - } + LevelNode(TreeLinkNode node, int level) { + this.node = node; + this.level = level; } + } - public static class TreeLinkNode { - int val; - TreeLinkNode left, right, next; + public static class TreeLinkNode { + int val; + TreeLinkNode left, right, next; - TreeLinkNode(int x) { - val = x; - } + TreeLinkNode(int x) { + val = x; } + } - public static void main(String[] args) throws Exception { - TreeLinkNode node = new TreeLinkNode(2); - node.left = new TreeLinkNode(1); - node.right = new TreeLinkNode(3); - new NextRightPointer().connect(node); - System.out.println(node.next); - System.out.println(node.left.next.val); - System.out.println(node.right.next); - } + public static void main(String[] args) throws Exception { + TreeLinkNode node = new TreeLinkNode(2); + node.left = new TreeLinkNode(1); + node.right = new TreeLinkNode(3); + new NextRightPointer().connect(node); + System.out.println(node.next); + System.out.println(node.left.next.val); + System.out.println(node.right.next); + } - public void connect(TreeLinkNode root) { - Queue queue = new ArrayDeque<>(); - LevelNode zero = new LevelNode(root, 0); - queue.offer(zero); - LevelNode prev = null; - while (!queue.isEmpty()) { - LevelNode levelNode = queue.poll(); - if (levelNode.node == null) break; - TreeLinkNode curr = levelNode.node; - if (prev != null) { - if (prev.level == levelNode.level) { - prev.node.next = levelNode.node; - } - } - prev = levelNode; - queue.offer(new LevelNode(curr.left, levelNode.level + 1)); - queue.offer(new LevelNode(curr.right, levelNode.level + 1)); + public void connect(TreeLinkNode root) { + Queue queue = new ArrayDeque<>(); + LevelNode zero = new LevelNode(root, 0); + queue.offer(zero); + LevelNode prev = null; + while (!queue.isEmpty()) { + LevelNode levelNode = queue.poll(); + if (levelNode.node == null) break; + TreeLinkNode curr = levelNode.node; + if (prev != null) { + if (prev.level == levelNode.level) { + prev.node.next = levelNode.node; } + } + prev = levelNode; + queue.offer(new LevelNode(curr.left, levelNode.level + 1)); + queue.offer(new LevelNode(curr.right, levelNode.level + 1)); } - + } } diff --git a/problems/src/tree/NextRightPointerII.java b/problems/src/tree/NextRightPointerII.java index 777213f0..644e5536 100644 --- a/problems/src/tree/NextRightPointerII.java +++ b/problems/src/tree/NextRightPointerII.java @@ -2,73 +2,62 @@ /** * Created by gouthamvidyapradhan on 03/10/2017. - *

- * Follow up for problem "Populating Next Right Pointers in Each Node". - *

- * What if the given tree could be any binary tree? Would your previous solution still work? - *

- * Note: - *

- * You may only use constant extra space. - * For example, - * Given the following binary tree, - * 1 - * / \ - * 2 3 - * / \ \ - * 4 5 7 - * After calling your function, the tree should look like: - * 1 -> NULL - * / \ - * 2 -> 3 -> NULL - * / \ \ - * 4-> 5 -> 7 -> NULL + * + *

Follow up for problem "Populating Next Right Pointers in Each Node". + * + *

What if the given tree could be any binary tree? Would your previous solution still work? + * + *

Note: + * + *

You may only use constant extra space. For example, Given the following binary tree, 1 / \ 2 3 + * / \ \ 4 5 7 After calling your function, the tree should look like: 1 -> NULL / \ 2 -> 3 -> NULL + * / \ \ 4-> 5 -> 7 -> NULL */ public class NextRightPointerII { - public static void main(String[] args) throws Exception { - TreeLinkNode root = new TreeLinkNode(1); - root.left = new TreeLinkNode(2); - root.right = new TreeLinkNode(3); - root.right.right = new TreeLinkNode(4); - root.right.right.left = new TreeLinkNode(5); - root.right.right.right = new TreeLinkNode(6); - new NextRightPointerII().connect(root); - } + public static void main(String[] args) throws Exception { + TreeLinkNode root = new TreeLinkNode(1); + root.left = new TreeLinkNode(2); + root.right = new TreeLinkNode(3); + root.right.right = new TreeLinkNode(4); + root.right.right.left = new TreeLinkNode(5); + root.right.right.right = new TreeLinkNode(6); + new NextRightPointerII().connect(root); + } - public void connect(TreeLinkNode root) { - TreeLinkNode prev = new TreeLinkNode(0); - TreeLinkNode first = null; - while (root != null) { - if (root.left != null) { - prev.next = root.left; - prev = root.left; - if (first == null) { - first = root.left; - } - } - if (root.right != null) { - prev.next = root.right; - prev = root.right; - if (first == null) { - first = root.right; - } - } - root = root.next; - if (root == null) { - root = first; - first = null; - prev = new TreeLinkNode(0); - } + public void connect(TreeLinkNode root) { + TreeLinkNode prev = new TreeLinkNode(0); + TreeLinkNode first = null; + while (root != null) { + if (root.left != null) { + prev.next = root.left; + prev = root.left; + if (first == null) { + first = root.left; + } + } + if (root.right != null) { + prev.next = root.right; + prev = root.right; + if (first == null) { + first = root.right; } + } + root = root.next; + if (root == null) { + root = first; + first = null; + prev = new TreeLinkNode(0); + } } + } - public static class TreeLinkNode { - int val; - TreeLinkNode left, right, next; + public static class TreeLinkNode { + int val; + TreeLinkNode left, right, next; - TreeLinkNode(int x) { - val = x; - } + TreeLinkNode(int x) { + val = x; } + } } diff --git a/problems/src/tree/PathSumIII.java b/problems/src/tree/PathSumIII.java index c1c7c870..cb911281 100644 --- a/problems/src/tree/PathSumIII.java +++ b/problems/src/tree/PathSumIII.java @@ -4,71 +4,61 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 08/04/2017. - * 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. - *

- * Example: - *

- * root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8 - *

- * 10 - * / \ - * 5 -3 - * / \ \ - * 3 2 11 - * / \ \ - * 3 -2 1 - *

- * Return 3. The paths that sum to 8 are: - *

- * 1. 5 -> 3 - * 2. 5 -> 2 -> 1 - * 3. -3 -> 11 + * Created by gouthamvidyapradhan on 08/04/2017. 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. + * + *

Example: + * + *

root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8 + * + *

10 / \ 5 -3 / \ \ 3 2 11 / \ \ 3 -2 1 + * + *

Return 3. The paths that sum to 8 are: + * + *

1. 5 -> 3 2. 5 -> 2 -> 1 3. -3 -> 11 */ - public class PathSumIII { - /** - * - */ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + /** */ + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - private Map pathCount = new HashMap<>(); - private int totalCount; + private Map pathCount = new HashMap<>(); + private int totalCount; - public static void main(String[] args) throws Exception { - TreeNode node = new TreeNode(1); - System.out.println(new PathSumIII().pathSum(node, 0)); - } + public static void main(String[] args) throws Exception { + TreeNode node = new TreeNode(1); + System.out.println(new PathSumIII().pathSum(node, 0)); + } - public int pathSum(TreeNode root, int sum) { - if (root == null) return 0; - dfs(root, sum, 0); - return totalCount; - } + public int pathSum(TreeNode root, int sum) { + if (root == null) return 0; + dfs(root, sum, 0); + return totalCount; + } - private void dfs(TreeNode root, int target, int pSum) { - if (root != null) { - pSum += root.val; - if (pSum == target) totalCount++; - totalCount += pathCount.getOrDefault(pSum - target, 0); - pathCount.put(pSum, pathCount.getOrDefault(pSum, 0) + 1); - dfs(root.left, target, pSum); - dfs(root.right, target, pSum); - pathCount.put(pSum, pathCount.get(pSum) - 1); - } + private void dfs(TreeNode root, int target, int pSum) { + if (root != null) { + pSum += root.val; + if (pSum == target) totalCount++; + totalCount += pathCount.getOrDefault(pSum - target, 0); + pathCount.put(pSum, pathCount.getOrDefault(pSum, 0) + 1); + dfs(root.left, target, pSum); + dfs(root.right, target, pSum); + pathCount.put(pSum, pathCount.get(pSum) - 1); } + } } diff --git a/problems/src/tree/PostorderToBT.java b/problems/src/tree/PostorderToBT.java index bb724d88..3ca60f7f 100644 --- a/problems/src/tree/PostorderToBT.java +++ b/problems/src/tree/PostorderToBT.java @@ -4,74 +4,70 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 23/02/2017. - * Given inorder and postorder traversal of a tree, construct the binary tree. - *

- * Note: - * You may assume that duplicates do not exist in the tree. + * Created by gouthamvidyapradhan on 23/02/2017. Given inorder and postorder traversal of a tree, + * construct the binary tree. + * + *

Note: You may assume that duplicates do not exist in the tree. */ public class PostorderToBT { - private Map INDEX = new HashMap<>(); - private static int postIndex; + private Map INDEX = new HashMap<>(); + private static int postIndex; - public class TreeNode { - int val; - TreeNode left; - TreeNode right; + public class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int in[] = new int[]{1, 2}; - int post[] = new int[]{1, 2}; - TreeNode root = new PostorderToBT().buildTree(in, post); - new PostorderToBT().preorderPrint(root); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int in[] = new int[] {1, 2}; + int post[] = new int[] {1, 2}; + TreeNode root = new PostorderToBT().buildTree(in, post); + new PostorderToBT().preorderPrint(root); + } - public TreeNode buildTree(int[] inorder, int[] postorder) { - int count = 0; - for (int i : inorder) - INDEX.put(i, count++); - postIndex = postorder.length - 1; - return build(0, inorder.length - 1, postorder); - } + public TreeNode buildTree(int[] inorder, int[] postorder) { + int count = 0; + for (int i : inorder) INDEX.put(i, count++); + postIndex = postorder.length - 1; + return build(0, inorder.length - 1, postorder); + } - private void preorderPrint(TreeNode root) { - if (root != null) { - System.out.print(root.val + " "); - preorderPrint(root.left); - preorderPrint(root.right); - } + private void preorderPrint(TreeNode root) { + if (root != null) { + System.out.print(root.val + " "); + preorderPrint(root.left); + preorderPrint(root.right); } + } - private TreeNode build(int s, int e, int[] postorder) { - if (postIndex >= 0 && s <= e) { - int poi = postorder[postIndex]; + private TreeNode build(int s, int e, int[] postorder) { + if (postIndex >= 0 && s <= e) { + int poi = postorder[postIndex]; - int ini = INDEX.get(poi); + int ini = INDEX.get(poi); - TreeNode node = new TreeNode(poi); - postIndex--; + TreeNode node = new TreeNode(poi); + postIndex--; - if (s == e) - return node; //leaf node + if (s == e) return node; // leaf node - node.right = build(ini + 1, e, postorder); - node.left = build(s, ini - 1, postorder); + node.right = build(ini + 1, e, postorder); + node.left = build(s, ini - 1, postorder); - return node; - } - return null; + return node; } - + return null; + } } diff --git a/problems/src/tree/PreorderToBT.java b/problems/src/tree/PreorderToBT.java index 5982da4e..06729549 100644 --- a/problems/src/tree/PreorderToBT.java +++ b/problems/src/tree/PreorderToBT.java @@ -4,56 +4,54 @@ import java.util.Map; /** - * Created by gouthamvidyapradhan on 25/02/2017. - * Given preorder and inorder traversal of a tree, construct the binary tree. - *

- * Note: - * You may assume that duplicates do not exist in the tree. + * Created by gouthamvidyapradhan on 25/02/2017. Given preorder and inorder traversal of a tree, + * construct the binary tree. + * + *

Note: You may assume that duplicates do not exist in the tree. */ public class PreorderToBT { - public class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } - - Map MAP = new HashMap<>(); - private int index = 0, totalLen = 0; - - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] perorder = {7, -10, -4, 3, -1, 2, -8, 11}; - int[] inorder = {-4, -10, 3, -1, 7, 11, -8, 2}; - new PreorderToBT().buildTree(perorder, inorder); - } - - public TreeNode buildTree(int[] preorder, int[] inorder) { - for (int i = 0, l = inorder.length; i < l; i++) - MAP.put(inorder[i], i); - totalLen = preorder.length; - return build(preorder, 0, inorder.length - 1); - } - - private TreeNode build(int[] preorder, int s, int e) { - if (s > e || index >= totalLen) return null; - - int n = preorder[index++]; - int pos = MAP.get(n); - - TreeNode node = new TreeNode(n); - if (s == e) return node; + public class TreeNode { + int val; + TreeNode left; + TreeNode right; - node.left = build(preorder, s, pos - 1); - node.right = build(preorder, pos + 1, e); - return node; + TreeNode(int x) { + val = x; } + } + + Map MAP = new HashMap<>(); + private int index = 0, totalLen = 0; + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] perorder = {7, -10, -4, 3, -1, 2, -8, 11}; + int[] inorder = {-4, -10, 3, -1, 7, 11, -8, 2}; + new PreorderToBT().buildTree(perorder, inorder); + } + + public TreeNode buildTree(int[] preorder, int[] inorder) { + for (int i = 0, l = inorder.length; i < l; i++) MAP.put(inorder[i], i); + totalLen = preorder.length; + return build(preorder, 0, inorder.length - 1); + } + + private TreeNode build(int[] preorder, int s, int e) { + if (s > e || index >= totalLen) return null; + + int n = preorder[index++]; + int pos = MAP.get(n); + + TreeNode node = new TreeNode(n); + if (s == e) return node; + + node.left = build(preorder, s, pos - 1); + node.right = build(preorder, pos + 1, e); + return node; + } } diff --git a/problems/src/tree/RecoverBinarySearchTree.java b/problems/src/tree/RecoverBinarySearchTree.java index 1ae01804..d2b0d907 100644 --- a/problems/src/tree/RecoverBinarySearchTree.java +++ b/problems/src/tree/RecoverBinarySearchTree.java @@ -1,107 +1,88 @@ package tree; /** - * Created by gouthamvidyapradhan on 28/07/2018. - * Two elements of a binary search tree (BST) are swapped by mistake. - - Recover the tree without changing its structure. - - Example 1: - - Input: [1,3,null,null,2] - - 1 - / - 3 - \ - 2 - - Output: [3,1,null,null,2] - - 3 - / - 1 - \ - 2 - Example 2: - - Input: [3,1,4,null,null,2] - - 3 - / \ - 1 4 - / - 2 - - Output: [2,1,4,null,null,3] - - 2 - / \ - 1 4 - / - 3 - Follow up: - - A solution using O(n) space is pretty straight forward. - Could you devise a constant space solution? - - Solution: O(N) time and O(1) space. Step 1, perform a inorder traversal and mark left and right pointer at the node - where violation of BST occurs. Step2, find the next node which is smaller or equal to right pointer node. - Finally swap left and right node values. + * Created by gouthamvidyapradhan on 28/07/2018. Two elements of a binary search tree (BST) are + * swapped by mistake. + * + *

Recover the tree without changing its structure. + * + *

Example 1: + * + *

Input: [1,3,null,null,2] + * + *

1 / 3 \ 2 + * + *

Output: [3,1,null,null,2] + * + *

3 / 1 \ 2 Example 2: + * + *

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

3 / \ 1 4 / 2 + * + *

Output: [2,1,4,null,null,3] + * + *

2 / \ 1 4 / 3 Follow up: + * + *

A solution using O(n) space is pretty straight forward. Could you devise a constant space + * solution? + * + *

Solution: O(N) time and O(1) space. Step 1, perform a inorder traversal and mark left and + * right pointer at the node where violation of BST occurs. Step2, find the next node which is + * smaller or equal to right pointer node. Finally swap left and right node values. */ public class RecoverBinarySearchTree { - private boolean violation; - private TreeNode left, right, prev; + private boolean violation; + private TreeNode left, right, prev; - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } - - public static void main(String[] args) throws Exception{ - TreeNode root = new TreeNode(10); - root.left = new TreeNode(1); - root.left.left = new TreeNode(3); - root.left.left.left = new TreeNode(5); - new RecoverBinarySearchTree().recoverTree(root); + } + + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(10); + root.left = new TreeNode(1); + root.left.left = new TreeNode(3); + root.left.left.left = new TreeNode(5); + new RecoverBinarySearchTree().recoverTree(root); + } + + public void recoverTree(TreeNode root) { + inorder(root); + if (left != null && right != null) { + int temp = left.val; + left.val = right.val; + right.val = temp; } - - public void recoverTree(TreeNode root) { - inorder(root); - if(left != null && right != null){ - int temp = left.val; - left.val = right.val; - right.val = temp; + } + + private void inorder(TreeNode root) { + if (root != null) { + inorder(root.left); + if (prev != null) { + if (!violation) { + if (prev.val > root.val) { + violation = true; + left = prev; + right = root; + } else { + prev = root; + } + } else { + if (root.val <= right.val) { + right = root; + } } + } else { + prev = root; + } + inorder(root.right); } - - private void inorder(TreeNode root){ - if(root != null){ - inorder(root.left); - if(prev != null){ - if(!violation){ - if(prev.val > root.val){ - violation = true; - left = prev; - right = root; - } else{ - prev = root; - } - } else{ - if(root.val <= right.val){ - right = root; - } - } - } else { - prev = root; - } - inorder(root.right); - } - } - + } } diff --git a/problems/src/tree/SameTree.java b/problems/src/tree/SameTree.java index 9d1dfa98..ca8b2c16 100644 --- a/problems/src/tree/SameTree.java +++ b/problems/src/tree/SameTree.java @@ -1,69 +1,63 @@ package tree; /** - * Created by gouthamvidyapradhan on 23/01/2018. - * 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. - - - Example 1: - - Input: 1 1 - / \ / \ - 2 3 2 3 - - [1,2,3], [1,2,3] - - Output: true - Example 2: - - Input: 1 1 - / \ - 2 2 - - [1,2], [1,null,2] - - Output: false - Example 3: - - Input: 1 1 - / \ / \ - 2 1 1 2 - - [1,2,1], [1,1,2] - - Output: false - - Solution: Do a pre-order traversal of both the trees in parallel and compare each node + * Created by gouthamvidyapradhan on 23/01/2018. 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. + * + *

Example 1: + * + *

Input: 1 1 / \ / \ 2 3 2 3 + * + *

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

Output: true Example 2: + * + *

Input: 1 1 / \ 2 2 + * + *

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

Output: false Example 3: + * + *

Input: 1 1 / \ / \ 2 1 1 2 + * + *

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

Output: false + * + *

Solution: Do a pre-order traversal of both the trees in parallel and compare each node */ public class SameTree { - public class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } - } - - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { + val = x; } - - public boolean isSameTree(TreeNode p, TreeNode q) { - if((p == null && q != null) || (p != null && q == null)) return false; - if(p == null && q == null) return true; - else{ - boolean status = isSameTree(p.left, q.left); - if(!status || p.val != q.val){ - return false; - } - return isSameTree(p.right, q.right); - } + } + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception {} + + public boolean isSameTree(TreeNode p, TreeNode q) { + if ((p == null && q != null) || (p != null && q == null)) return false; + if (p == null && q == null) return true; + else { + boolean status = isSameTree(p.left, q.left); + if (!status || p.val != q.val) { + return false; + } + return isSameTree(p.right, q.right); } + } } diff --git a/problems/src/tree/SerializeAndDeserializeNAryTree.java b/problems/src/tree/SerializeAndDeserializeNAryTree.java index 03f67496..03487353 100644 --- a/problems/src/tree/SerializeAndDeserializeNAryTree.java +++ b/problems/src/tree/SerializeAndDeserializeNAryTree.java @@ -1,121 +1,119 @@ package tree; + import java.util.*; import java.util.stream.Collectors; /** - * Created by gouthamvidyapradhan on 16/03/2019 - * Serialization is the process of converting a data structure or object into a sequence of bits so that it can be - * stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in - * the same or another computer environment. - * - * Design an algorithm to serialize and deserialize an N-ary tree. An N-ary tree is a rooted tree in which each node - * has no more than N children. There is no restriction on how your serialization/deserialization algorithm should - * work. You just need to ensure that an N-ary tree can be serialized to a string and this string can be - * deserialized to the original tree structure. + * Created by gouthamvidyapradhan on 16/03/2019 Serialization is the process of converting a data + * structure or object into a sequence of bits so that it can be stored in a file or memory buffer, + * or transmitted across a network connection link to be reconstructed later in the same or another + * computer environment. * - * For example, you may serialize the following 3-ary tree + *

Design an algorithm to serialize and deserialize an N-ary tree. An N-ary tree is a rooted tree + * in which each node has no more than N children. There is no restriction on how your + * serialization/deserialization algorithm should work. You just need to ensure that an N-ary tree + * can be serialized to a string and this string can be deserialized to the original tree structure. * - * 1 - * /|\ - * 3 2 4 - * /\ - * 5 6 + *

For example, you may serialize the following 3-ary tree * - * as [1 [3[5 6] 2 4]]. You do not necessarily need to follow this format, so please be creative and come up with - * different approaches yourself. + *

1 /|\ 3 2 4 /\ 5 6 * + *

as [1 [3[5 6] 2 4]]. You do not necessarily need to follow this format, so please be creative + * and come up with different approaches yourself. * + *

Note: * - * Note: + *

N is in the range of [1, 1000] Do not use class member/global/static variables to store + * states. Your serialize and deserialize algorithms should be stateless. * - * N is in the range of [1, 1000] - * Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should - * be stateless. - * - * Solution: To encode recursively iterate through each node and build a root and its children as 3[5,6] where 3 is the - * root and 5, 6 are its children. - * To decode, build the root node first and then recursively build its children. + *

Solution: To encode recursively iterate through each node and build a root and its children as + * 3[5,6] where 3 is the root and 5, 6 are its children. To decode, build the root node first and + * then recursively build its children. */ public class SerializeAndDeserializeNAryTree { - static class Node { - public int val; - public List children; + static class Node { + public int val; + public List children; - public Node() {} + public Node() {} - public Node(int _val,List _children) { - val = _val; - children = _children; - } + public Node(int _val, List _children) { + val = _val; + children = _children; } + } - /** - * Main method - * @param args - */ - public static void main(String[] args) { - Node n1 = new Node(5, new ArrayList<>()); - Node n2 = new Node(6, Arrays.asList(n1)); - Node n3 = new Node(2, Arrays.asList(n2)); - Node n4 = new Node(4, Arrays.asList(n3)); - Node n5 = new Node(3, Arrays.asList(n4)); - Node root = new Node(1, Arrays.asList(n5)); - SerializeAndDeserializeNAryTree serializer = new SerializeAndDeserializeNAryTree(); - String result = serializer.serialize(root); - Node rootNode = serializer.deserialize(result); - System.out.println(result); - System.out.println(rootNode); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + Node n1 = new Node(5, new ArrayList<>()); + Node n2 = new Node(6, Arrays.asList(n1)); + Node n3 = new Node(2, Arrays.asList(n2)); + Node n4 = new Node(4, Arrays.asList(n3)); + Node n5 = new Node(3, Arrays.asList(n4)); + Node root = new Node(1, Arrays.asList(n5)); + SerializeAndDeserializeNAryTree serializer = new SerializeAndDeserializeNAryTree(); + String result = serializer.serialize(root); + Node rootNode = serializer.deserialize(result); + System.out.println(result); + System.out.println(rootNode); + } - // Encodes a tree to a single string. - public String serialize(Node root) { - if(root != null){ - String curr = String.valueOf(root.val); - List children = root.children; - return children != null ? - curr + "[" + children.stream().map(this::serialize).collect(Collectors.joining(",")) + "]" : - curr + "[]"; - } else { - return ""; - } + // Encodes a tree to a single string. + public String serialize(Node root) { + if (root != null) { + String curr = String.valueOf(root.val); + List children = root.children; + return children != null + ? curr + + "[" + + children.stream().map(this::serialize).collect(Collectors.joining(",")) + + "]" + : curr + "[]"; + } else { + return ""; } + } - // Decodes your encoded data to tree. - public Node deserialize(String data) { - char[] arr = data.toCharArray(); - StringBuilder num = new StringBuilder(); - Queue queue = new ArrayDeque<>(); - for(char c : arr){ - if(c >= '0' && c <= '9'){ - num.append(c); - } else if(c == '['){ - if(num.length() != 0){ - queue.offer(num.toString()); - num = new StringBuilder(); - } - queue.offer("["); - } else { - queue.offer(String.valueOf(c)); - } + // Decodes your encoded data to tree. + public Node deserialize(String data) { + char[] arr = data.toCharArray(); + StringBuilder num = new StringBuilder(); + Queue queue = new ArrayDeque<>(); + for (char c : arr) { + if (c >= '0' && c <= '9') { + num.append(c); + } else if (c == '[') { + if (num.length() != 0) { + queue.offer(num.toString()); + num = new StringBuilder(); } - if(queue.isEmpty()) return null; - return decode(queue).get(0); + queue.offer("["); + } else { + queue.offer(String.valueOf(c)); + } } + if (queue.isEmpty()) return null; + return decode(queue).get(0); + } - private List decode(Queue elements){ - List children = new ArrayList<>(); - while(!elements.isEmpty()){ - String curr = elements.poll(); - if(curr.equals("[") || curr.equals(",")){ - } else if(curr.equals("]")){ - return children; - } else{ - int num = Integer.parseInt(curr); - Node currNode = new Node(num, decode(elements)); - children.add(currNode); - } - } + private List decode(Queue elements) { + List children = new ArrayList<>(); + while (!elements.isEmpty()) { + String curr = elements.poll(); + if (curr.equals("[") || curr.equals(",")) { + } else if (curr.equals("]")) { return children; + } else { + int num = Integer.parseInt(curr); + Node currNode = new Node(num, decode(elements)); + children.add(currNode); + } } + return children; + } } diff --git a/problems/src/tree/SortedArrayToBST.java b/problems/src/tree/SortedArrayToBST.java index 18eb0b6f..e445c34c 100644 --- a/problems/src/tree/SortedArrayToBST.java +++ b/problems/src/tree/SortedArrayToBST.java @@ -1,61 +1,58 @@ package tree; /** - * Created by gouthamvidyapradhan on 25/02/2017. - * Given an array where elements are sorted in ascending order, convert it to a height balanced BST. + * Created by gouthamvidyapradhan on 25/02/2017. Given an array where elements are sorted in + * ascending order, convert it to a height balanced BST. */ public class SortedArrayToBST { - public class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } - - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] A = {1, 2, 3, 4, 5, 6}; - new SortedArrayToBST().sortedArrayToBST(A); - - } + public class TreeNode { + int val; + TreeNode left; + TreeNode right; - public TreeNode sortedArrayToBST(int[] nums) { - if (nums.length == 0) return null; - - TreeNode root = new SortedArrayToBST().build(0, nums.length - 1, nums); - preorder(root); - return root; + TreeNode(int x) { + val = x; } - - private void preorder(TreeNode node) { - if (node != null) { - preorder(node.left); - System.out.println(node.val); - preorder(node.right); - } + } + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 2, 3, 4, 5, 6}; + new SortedArrayToBST().sortedArrayToBST(A); + } + + public TreeNode sortedArrayToBST(int[] nums) { + if (nums.length == 0) return null; + + TreeNode root = new SortedArrayToBST().build(0, nums.length - 1, nums); + preorder(root); + return root; + } + + private void preorder(TreeNode node) { + if (node != null) { + preorder(node.left); + System.out.println(node.val); + preorder(node.right); } + } - private TreeNode build(int s, int e, int[] nums) { - if (s > e) return null; + private TreeNode build(int s, int e, int[] nums) { + if (s > e) return null; - int m = (e - s) / 2; - int node = nums[s + m]; - TreeNode root = new TreeNode(node); - if (s == e) - return root; + int m = (e - s) / 2; + int node = nums[s + m]; + TreeNode root = new TreeNode(node); + if (s == e) return root; - root.left = build(s, s + m - 1, nums); - root.right = build(s + m + 1, e, nums); - - return root; - } + root.left = build(s, s + m - 1, nums); + root.right = build(s + m + 1, e, nums); + return root; + } } diff --git a/problems/src/tree/SplitBST.java b/problems/src/tree/SplitBST.java index bd1284d8..19f74cd4 100644 --- a/problems/src/tree/SplitBST.java +++ b/problems/src/tree/SplitBST.java @@ -1,92 +1,84 @@ package tree; /** - * Created by gouthamvidyapradhan on 01/05/2018. - * Given a Binary Search Tree (BST) with root node root, and a target value V, split the tree into two subtrees - * where one subtree has nodes that are all smaller or equal to the target value, while the other subtree has all - * nodes that are greater than the target value. It's not necessarily the case that the tree contains a node with - * value V. - - Additionally, most of the structure of the original tree should remain. Formally, for any child C with parent P in - the original tree, if they are both in the same subtree after the split, then node C should still have the parent P. - - You should output the root TreeNode of both subtrees after splitting, in any order. - - Example 1: - - Input: root = [4,2,6,1,3,5,7], V = 2 - Output: [[2,1],[4,3,6,null,null,5,7]] - Explanation: - Note that root, output[0], and output[1] are TreeNode objects, not arrays. - - The given tree [4,2,6,1,3,5,7] is represented by the following diagram: - - 4 - / \ - 2 6 - / \ / \ - 1 3 5 7 - - while the diagrams for the outputs are: - - 4 - / \ - 3 6 and 2 - / \ / - 5 7 1 - Note: - - The size of the BST will not exceed 50. - The BST is always valid and each node's value is different. - - Solution: O(N) if a current node is <= to key then the current node and its child nodes form the left sub-tree. Split - the right node further recursively + * Created by gouthamvidyapradhan on 01/05/2018. Given a Binary Search Tree (BST) with root node + * root, and a target value V, split the tree into two subtrees where one subtree has nodes that are + * all smaller or equal to the target value, while the other subtree has all nodes that are greater + * than the target value. It's not necessarily the case that the tree contains a node with value V. + * + *

Additionally, most of the structure of the original tree should remain. Formally, for any + * child C with parent P in the original tree, if they are both in the same subtree after the split, + * then node C should still have the parent P. + * + *

You should output the root TreeNode of both subtrees after splitting, in any order. + * + *

Example 1: + * + *

Input: root = [4,2,6,1,3,5,7], V = 2 Output: [[2,1],[4,3,6,null,null,5,7]] Explanation: Note + * that root, output[0], and output[1] are TreeNode objects, not arrays. + * + *

The given tree [4,2,6,1,3,5,7] is represented by the following diagram: + * + *

4 / \ 2 6 / \ / \ 1 3 5 7 + * + *

while the diagrams for the outputs are: + * + *

4 / \ 3 6 and 2 / \ / 5 7 1 Note: + * + *

The size of the BST will not exceed 50. The BST is always valid and each node's value is + * different. + * + *

Solution: O(N) if a current node is <= to key then the current node and its child nodes form + * the left sub-tree. Split the right node further recursively */ public class SplitBST { - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } - } + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - TreeNode root = new TreeNode(4); - root.left = new TreeNode(2); - root.left.left = new TreeNode(1); - root.left.right = new TreeNode(3); - root.right = new TreeNode(6); - root.right.left = new TreeNode(5); - root.right.right = new TreeNode(7); - root.right.right.right = new TreeNode(9); - TreeNode[] result = new SplitBST().splitBST(root, 3); + TreeNode(int x) { + val = x; } + } - public TreeNode[] splitBST(TreeNode root, int V) { - if(root == null){ - return new TreeNode[] {null, null}; - } else{ - TreeNode[] result = new TreeNode[2]; - if(root.val <= V){ - result[0] = root; - TreeNode[] right = splitBST(root.right, V); - root.right = right[0]; - result[1] = right[1]; - return result; - } else{ - TreeNode[] left = splitBST(root.left, V); - root.left = left[1]; - result[0] = left[0]; - result[1] = root; - return result; - } - } - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(4); + root.left = new TreeNode(2); + root.left.left = new TreeNode(1); + root.left.right = new TreeNode(3); + root.right = new TreeNode(6); + root.right.left = new TreeNode(5); + root.right.right = new TreeNode(7); + root.right.right.right = new TreeNode(9); + TreeNode[] result = new SplitBST().splitBST(root, 3); + } + public TreeNode[] splitBST(TreeNode root, int V) { + if (root == null) { + return new TreeNode[] {null, null}; + } else { + TreeNode[] result = new TreeNode[2]; + if (root.val <= V) { + result[0] = root; + TreeNode[] right = splitBST(root.right, V); + root.right = right[0]; + result[1] = right[1]; + return result; + } else { + TreeNode[] left = splitBST(root.left, V); + root.left = left[1]; + result[0] = left[0]; + result[1] = root; + return result; + } + } + } } diff --git a/problems/src/tree/SubtreeOfAnotherTree.java b/problems/src/tree/SubtreeOfAnotherTree.java index 0d94d926..eef75737 100644 --- a/problems/src/tree/SubtreeOfAnotherTree.java +++ b/problems/src/tree/SubtreeOfAnotherTree.java @@ -1,70 +1,45 @@ package tree; /** - * Created by gouthamvidyapradhan on 07/07/2017. - * Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node's descendants. The tree s could also be considered as a subtree of itself. - *

- * Example 1: - * Given tree s: - *

- * 3 - * / \ - * 4 5 - * / \ - * 1 2 - * Given tree t: - * 4 - * / \ - * 1 2 - * Return true, because t has the same structure and node values with a subtree of s. - * Example 2: - * Given tree s: - *

- * 3 - * / \ - * 4 5 - * / \ - * 1 2 - * / - * 0 - * Given tree t: - * 4 - * / \ - * 1 2 - * Return false. + * Created by gouthamvidyapradhan on 07/07/2017. Given two non-empty binary trees s and t, check + * whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s + * is a tree consists of a node in s and all of this node's descendants. The tree s could also be + * considered as a subtree of itself. + * + *

Example 1: Given tree s: + * + *

3 / \ 4 5 / \ 1 2 Given tree t: 4 / \ 1 2 Return true, because t has the same structure and + * node values with a subtree of s. Example 2: Given tree s: + * + *

3 / \ 4 5 / \ 1 2 / 0 Given tree t: 4 / \ 1 2 Return false. */ public class SubtreeOfAnotherTree { - public class TreeNode { - int val; - TreeNode left; - TreeNode right; + public class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - public static void main(String[] args) throws Exception { - } - - public boolean isSubtree(TreeNode s, TreeNode t) { - if (s != null) { - if (s.val == t.val) { - if (equal(s, t)) - return true; - else return (isSubtree(s.left, t) || isSubtree(s.right, t)); - } else return (isSubtree(s.left, t) || isSubtree(s.right, t)); - } - return false; - } + public static void main(String[] args) throws Exception {} - private boolean equal(TreeNode s, TreeNode t) { - if (s == null && t == null) - return true; - else if (s == null || t == null) - return false; - else if (s.val != t.val) return false; - else return equal(s.left, t.left) && equal(s.right, t.right); + public boolean isSubtree(TreeNode s, TreeNode t) { + if (s != null) { + if (s.val == t.val) { + if (equal(s, t)) return true; + else return (isSubtree(s.left, t) || isSubtree(s.right, t)); + } else return (isSubtree(s.left, t) || isSubtree(s.right, t)); } + return false; + } + private boolean equal(TreeNode s, TreeNode t) { + if (s == null && t == null) return true; + else if (s == null || t == null) return false; + else if (s.val != t.val) return false; + else return equal(s.left, t.left) && equal(s.right, t.right); + } } diff --git a/problems/src/tree/SumofLeftLeaves.java b/problems/src/tree/SumofLeftLeaves.java index a5814f1e..9c5391fd 100644 --- a/problems/src/tree/SumofLeftLeaves.java +++ b/problems/src/tree/SumofLeftLeaves.java @@ -1,51 +1,48 @@ package tree; /** - * Created by gouthamvidyapradhan on 13/12/2017. - * Find the sum of all left leaves in a given binary tree. - - Example: - - 3 - / \ - 9 20 - / \ - 15 7 - - There are two left leaves in the binary tree, with values 9 and 15 respectively. Return 24. - + * Created by gouthamvidyapradhan on 13/12/2017. Find the sum of all left leaves in a given binary + * tree. + * + *

Example: + * + *

3 / \ 9 20 / \ 15 7 + * + *

There are two left leaves in the binary tree, with values 9 and 15 respectively. Return 24. */ public class SumofLeftLeaves { - public class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } - } - - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { + val = x; } - - public int sumOfLeftLeaves(TreeNode root) { - return inorder(root, false); + } + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception {} + + public int sumOfLeftLeaves(TreeNode root) { + return inorder(root, false); + } + + private int inorder(TreeNode node, boolean isLeft) { + if (node != null) { + if (node.left == null && node.right == null) { + if (isLeft) { + return node.val; + } else return 0; + } + return inorder(node.left, true) + inorder(node.right, false); } - - private int inorder(TreeNode node, boolean isLeft){ - if(node != null){ - if(node.left == null && node.right == null){ - if(isLeft){ - return node.val; - } else return 0; - } - return inorder(node.left, true) + inorder(node.right, false); - } return 0; - } - + return 0; + } } diff --git a/problems/src/tree/SymmetricTree.java b/problems/src/tree/SymmetricTree.java index 287db22a..cfda674a 100644 --- a/problems/src/tree/SymmetricTree.java +++ b/problems/src/tree/SymmetricTree.java @@ -1,57 +1,48 @@ package tree; /** - * Created by gouthamvidyapradhan on 14/08/2017. - * Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). - *

- * For example, this binary tree [1,2,2,3,4,4,3] is symmetric: - *

- * 1 - * / \ - * 2 2 - * / \ / \ - * 3 4 4 3 - *

- * But the following [1,2,2,null,3,null,3] is not: - * 1 - * / \ - * 2 2 - * \ \ - * 3 3 + * Created by gouthamvidyapradhan on 14/08/2017. Given a binary tree, check whether it is a mirror + * of itself (ie, symmetric around its center). + * + *

For example, this binary tree [1,2,2,3,4,4,3] is symmetric: + * + *

1 / \ 2 2 / \ / \ 3 4 4 3 + * + *

But the following [1,2,2,null,3,null,3] is not: 1 / \ 2 2 \ \ 3 3 */ public class SymmetricTree { - static class TreeNode { - int val; - TreeNode left; - TreeNode right; + static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - TreeNode node = new TreeNode(3); - node.left = new TreeNode(4); - node.right = new TreeNode(5); - System.out.println(new SymmetricTree().isSymmetric(node)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + TreeNode node = new TreeNode(3); + node.left = new TreeNode(4); + node.right = new TreeNode(5); + System.out.println(new SymmetricTree().isSymmetric(node)); + } - public boolean isSymmetric(TreeNode root) { - if (root == null) return true; - return dfs(root.left, root.right); - } + public boolean isSymmetric(TreeNode root) { + if (root == null) return true; + return dfs(root.left, root.right); + } - private boolean dfs(TreeNode left, TreeNode right) { - if (left == null && right == null) return true; - else if (left == null || right == null) return false; - return dfs(left.left, right.right) && left.val == right.val && dfs(left.right, right.left); - } + private boolean dfs(TreeNode left, TreeNode right) { + if (left == null && right == null) return true; + else if (left == null || right == null) return false; + return dfs(left.left, right.right) && left.val == right.val && dfs(left.right, right.left); + } } diff --git a/problems/src/tree/TwoSumIV.java b/problems/src/tree/TwoSumIV.java index 2c32b15f..ddac36cf 100644 --- a/problems/src/tree/TwoSumIV.java +++ b/problems/src/tree/TwoSumIV.java @@ -3,68 +3,59 @@ import java.util.HashSet; /** - * Created by gouthamvidyapradhan on 16/12/2017. - * Given a Binary Search Tree and a target number, return true if there exist two elements in the BST such that - * their sum is equal to the given target. - - Example 1: - Input: - 5 - / \ - 3 6 - / \ \ - 2 4 7 - - Target = 9 - - Output: True - Example 2: - Input: - 5 - / \ - 3 6 - / \ \ - 2 4 7 - - Target = 28 - - Output: False + * Created by gouthamvidyapradhan on 16/12/2017. Given a Binary Search Tree and a target number, + * return true if there exist two elements in the BST such that their sum is equal to the given + * target. + * + *

Example 1: Input: 5 / \ 3 6 / \ \ 2 4 7 + * + *

Target = 9 + * + *

Output: True Example 2: Input: 5 / \ 3 6 / \ \ 2 4 7 + * + *

Target = 28 + * + *

Output: False */ public class TwoSumIV { - public class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } - } - - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - } + public class TreeNode { + int val; + TreeNode left; + TreeNode right; - public boolean findTarget(TreeNode root, int k) { - return inorder(root, new HashSet<>(), k); + TreeNode(int x) { + val = x; } - - private boolean inorder(TreeNode node, HashSet set, int k){ - if(node != null){ - int req = k - (node.val); - if(set.contains(req)){ - return true; - } - set.add(node.val); - if(inorder(node.left, set, k)){ - return true; - } else{ - if(inorder(node.right, set, k)){ - return true; - } - } - } return false; + } + + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception {} + + public boolean findTarget(TreeNode root, int k) { + return inorder(root, new HashSet<>(), k); + } + + private boolean inorder(TreeNode node, HashSet set, int k) { + if (node != null) { + int req = k - (node.val); + if (set.contains(req)) { + return true; + } + set.add(node.val); + if (inorder(node.left, set, k)) { + return true; + } else { + if (inorder(node.right, set, k)) { + return true; + } + } } + return false; + } } diff --git a/problems/src/tree/ValidBinarySearchTree.java b/problems/src/tree/ValidBinarySearchTree.java index 4ab6893a..87d36ab1 100644 --- a/problems/src/tree/ValidBinarySearchTree.java +++ b/problems/src/tree/ValidBinarySearchTree.java @@ -1,75 +1,64 @@ package tree; /** - * Created by gouthamvidyapradhan on 09/03/2017. - * Given a binary tree, determine if it is a valid binary search tree (BST). - *

- * Assume a BST is defined as follows: - *

- * The left subtree of a node contains only nodes with keys less than the node's key. - * The right subtree of a node contains only nodes with keys greater than the node's key. - * Both the left and right subtrees must also be binary search trees. - * Example 1: - * 2 - * / \ - * 1 3 - * Binary tree [2,1,3], return true. - * Example 2: - * 1 - * / \ - * 2 3 - * Binary tree [1,2,3], return false. + * Created by gouthamvidyapradhan on 09/03/2017. Given a binary tree, determine if it is a valid + * binary search tree (BST). + * + *

Assume a BST is defined as follows: + * + *

The left subtree of a node contains only nodes with keys less than the node's key. The right + * subtree of a node contains only nodes with keys greater than the node's key. Both the left and + * right subtrees must also be binary search trees. Example 1: 2 / \ 1 3 Binary tree [2,1,3], return + * true. Example 2: 1 / \ 2 3 Binary tree [1,2,3], return false. */ public class ValidBinarySearchTree { - class Range { - long low, high; - } + class Range { + long low, high; + } - static class TreeNode { - int val; - TreeNode left; - TreeNode right; + static class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } + } - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - TreeNode root = new TreeNode(Integer.MIN_VALUE); - root.right = new TreeNode(Integer.MAX_VALUE); - System.out.println(new ValidBinarySearchTree().isValidBST(root)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + TreeNode root = new TreeNode(Integer.MIN_VALUE); + root.right = new TreeNode(Integer.MAX_VALUE); + System.out.println(new ValidBinarySearchTree().isValidBST(root)); + } - private boolean isValidBST(TreeNode root) { - if (root == null || - (root.right == null && root.left == null)) return true; - Range range = new Range(); - range.high = Long.MAX_VALUE; - range.low = Long.MIN_VALUE; - return validate(root, range); - } - - private boolean validate(TreeNode root, Range range) { - if ((root.val > range.low) && (root.val < range.high)) { - long temp = range.high; - if (root.left != null) { - range.high = root.val; - if (!validate(root.left, range)) return false; - } - if (root.right != null) { - range.high = temp; - range.low = root.val; - if (!validate(root.right, range)) return false; - } - return true; - } else return false; - } + private boolean isValidBST(TreeNode root) { + if (root == null || (root.right == null && root.left == null)) return true; + Range range = new Range(); + range.high = Long.MAX_VALUE; + range.low = Long.MIN_VALUE; + return validate(root, range); + } + private boolean validate(TreeNode root, Range range) { + if ((root.val > range.low) && (root.val < range.high)) { + long temp = range.high; + if (root.left != null) { + range.high = root.val; + if (!validate(root.left, range)) return false; + } + if (root.right != null) { + range.high = temp; + range.low = root.val; + if (!validate(root.right, range)) return false; + } + return true; + } else return false; + } } diff --git a/problems/src/tree/ZigZagTraversal.java b/problems/src/tree/ZigZagTraversal.java index 60100c2f..1b114e16 100644 --- a/problems/src/tree/ZigZagTraversal.java +++ b/problems/src/tree/ZigZagTraversal.java @@ -5,59 +5,46 @@ import java.util.List; /** - * Created by pradhang on 7/11/2017. - * Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). - *

- * For example: - * Given binary tree [3,9,20,null,null,15,7], - * 3 - * / \ - * 9 20 - * / \ - * 15 7 - * return its zigzag level order traversal as: - * [ - * [3], - * [20,9], - * [15,7] - * ] + * Created by pradhang on 7/11/2017. Given a binary tree, return the zigzag level order traversal of + * its nodes' values. (ie, from left to right, then right to left for the next level and alternate + * between). + * + *

For example: Given binary tree [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 return its zigzag + * level order traversal as: [ [3], [20,9], [15,7] ] */ public class ZigZagTraversal { - public class TreeNode { - int val; - TreeNode left; - TreeNode right; + public class TreeNode { + int val; + TreeNode left; + TreeNode right; - TreeNode(int x) { - val = x; - } + TreeNode(int x) { + val = x; } - - public static void main(String[] args) throws Exception { - - } - - public List> zigzagLevelOrder(TreeNode root) { - List> result = new ArrayList<>(); - if (root == null) return result; - dfs(root, 0, result); - return result; - } - - @SuppressWarnings("unchecked") - private void dfs(TreeNode root, int level, List> result) { - if (root != null) { - LinkedList subList; - if (level >= result.size()) { - subList = new LinkedList<>(); - result.add(subList); - } else subList = (LinkedList) result.get(level); - if (level % 2 == 0) - subList.addFirst(root.val); //add to right - else subList.add(root.val); //add to left - dfs(root.right, level + 1, result); - dfs(root.left, level + 1, result); - } + } + + public static void main(String[] args) throws Exception {} + + public List> zigzagLevelOrder(TreeNode root) { + List> result = new ArrayList<>(); + if (root == null) return result; + dfs(root, 0, result); + return result; + } + + @SuppressWarnings("unchecked") + private void dfs(TreeNode root, int level, List> result) { + if (root != null) { + LinkedList subList; + if (level >= result.size()) { + subList = new LinkedList<>(); + result.add(subList); + } else subList = (LinkedList) result.get(level); + if (level % 2 == 0) subList.addFirst(root.val); // add to right + else subList.add(root.val); // add to left + dfs(root.right, level + 1, result); + dfs(root.left, level + 1, result); } + } } diff --git a/problems/src/two_pointers/FourSum.java b/problems/src/two_pointers/FourSum.java index 3df8ee11..95896184 100644 --- a/problems/src/two_pointers/FourSum.java +++ b/problems/src/two_pointers/FourSum.java @@ -5,63 +5,58 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 29/03/2017. - * Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target. - *

- * Note: The solution set must not contain duplicate quadruplets. - *

- * For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0. - *

- * A solution set is: - * [ - * [-1, 0, 0, 1], - * [-2, -1, 1, 2], - * [-2, 0, 0, 2] - * ] + * Created by gouthamvidyapradhan on 29/03/2017. Given an array S of n integers, are there elements + * a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array + * which gives the sum of target. + * + *

Note: The solution set must not contain duplicate quadruplets. + * + *

For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0. + * + *

A solution set is: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ] */ public class FourSum { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] nums = {1, 0, -1, 0, -2, 2}; - System.out.println(new FourSum().fourSum(nums, 0)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] nums = {1, 0, -1, 0, -2, 2}; + System.out.println(new FourSum().fourSum(nums, 0)); + } - public List> fourSum(int[] nums, int target) { - List> result = new ArrayList<>(); - if (nums.length < 4) return result; - Arrays.sort(nums); - for (int i = 0; i < nums.length - 3; i++) { - if (i == 0 || nums[i] != nums[i - 1]) { - for (int j = i + 1; j < nums.length - 2; j++) { - if (j == i + 1 || nums[j] != nums[j - 1]) { - int k = j + 1, l = nums.length - 1; - while (k < l) { - if (k != j + 1 && nums[k] == nums[k + 1]) { - k++; - continue; - } - int sum = nums[i] + nums[j] + nums[k] + nums[l]; - if (sum == target) { - result.add(Arrays.asList(nums[i], nums[j], nums[k], nums[l])); - k++; - l--; - } else if (sum < target) { - k++; - } else { - l--; - } - } - } - } + public List> fourSum(int[] nums, int target) { + List> result = new ArrayList<>(); + if (nums.length < 4) return result; + Arrays.sort(nums); + for (int i = 0; i < nums.length - 3; i++) { + if (i == 0 || nums[i] != nums[i - 1]) { + for (int j = i + 1; j < nums.length - 2; j++) { + if (j == i + 1 || nums[j] != nums[j - 1]) { + int k = j + 1, l = nums.length - 1; + while (k < l) { + if (k != j + 1 && nums[k] == nums[k + 1]) { + k++; + continue; + } + int sum = nums[i] + nums[j] + nums[k] + nums[l]; + if (sum == target) { + result.add(Arrays.asList(nums[i], nums[j], nums[k], nums[l])); + k++; + l--; + } else if (sum < target) { + k++; + } else { + l--; + } } + } } - return result; + } } - + return result; + } } diff --git a/problems/src/two_pointers/LongestSubstringWitoutRepeats.java b/problems/src/two_pointers/LongestSubstringWitoutRepeats.java index fb20367b..5ca40efd 100644 --- a/problems/src/two_pointers/LongestSubstringWitoutRepeats.java +++ b/problems/src/two_pointers/LongestSubstringWitoutRepeats.java @@ -6,41 +6,44 @@ import java.util.Set; /** - * Created by gouthamvidyapradhan on 09/03/2017. - * Given a string, find the length of the longest substring without repeating characters. - *

- * Examples: - *

- * Given "abcabcbb", the answer is "abc", which the length is 3. - *

- * Given "bbbbb", the answer is "b", with the length of 1. - *

- * Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring. + * Created by gouthamvidyapradhan on 09/03/2017. Given a string, find the length of the longest + * substring without repeating characters. + * + *

Examples: + * + *

Given "abcabcbb", the answer is "abc", which the length is 3. + * + *

Given "bbbbb", the answer is "b", with the length of 1. + * + *

Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a + * substring, "pwke" is a subsequence and not a substring. */ public class LongestSubstringWitoutRepeats { - Set set = new HashSet<>(); + Set set = new HashSet<>(); - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - System.out.println(new LongestSubstringWitoutRepeats().lengthOfLongestSubstring("asdfsdfsdfsdfasdfdjdjjdjjdjjjjjajsdjjdjdjjd")); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println( + new LongestSubstringWitoutRepeats() + .lengthOfLongestSubstring("asdfsdfsdfsdfasdfdjdjjdjjdjjjjjajsdjjdjdjjd")); + } - private int lengthOfLongestSubstring(String s) { - if (s == null || s.isEmpty()) return 0; - Map map = new HashMap<>(); - int i = 0, max = Integer.MIN_VALUE; - for (int j = 0, l = s.length(); j < l; j++) { - if (map.keySet().contains(s.charAt(j))) { - i = Math.max(map.get(s.charAt(j)) + 1, i); - } - map.put(s.charAt(j), j); - max = Math.max(max, (j - i) + 1); - } - return max; + private int lengthOfLongestSubstring(String s) { + if (s == null || s.isEmpty()) return 0; + Map map = new HashMap<>(); + int i = 0, max = Integer.MIN_VALUE; + for (int j = 0, l = s.length(); j < l; j++) { + if (map.keySet().contains(s.charAt(j))) { + i = Math.max(map.get(s.charAt(j)) + 1, i); + } + map.put(s.charAt(j), j); + max = Math.max(max, (j - i) + 1); } + return max; + } } diff --git a/problems/src/two_pointers/MinimumSizeSubarraySum.java b/problems/src/two_pointers/MinimumSizeSubarraySum.java index de30cb1e..ac983997 100644 --- a/problems/src/two_pointers/MinimumSizeSubarraySum.java +++ b/problems/src/two_pointers/MinimumSizeSubarraySum.java @@ -3,54 +3,54 @@ /** * Created by gouthamvidyapradhan on 03/12/2017. * - * Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous - * subarray of which the sum ≥ s. If there isn't one, return 0 instead. - - For example, given the array [2,3,1,2,4,3] and s = 7, - the subarray [4,3] has the minimal length under the problem constraint. - - click to show more practice. - - Credits: - Special thanks to @Freezen for adding this problem and creating all test cases. - - Solution: O(n) solution. Solve using sliding window sub-array sum using two pointers. + *

Given an array of n positive integers and a positive integer s, find the minimal length of a + * contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead. + * + *

For example, given the array [2,3,1,2,4,3] and s = 7, the subarray [4,3] has the minimal + * length under the problem constraint. + * + *

click to show more practice. + * + *

Credits: Special thanks to @Freezen for adding this problem and creating all test cases. + * + *

Solution: O(n) solution. Solve using sliding window sub-array sum using two pointers. */ public class MinimumSizeSubarraySum { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] nums = {2,3,1,2,4,3}; - System.out.println(new MinimumSizeSubarraySum().minSubArrayLen(7, nums)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] nums = {2, 3, 1, 2, 4, 3}; + System.out.println(new MinimumSizeSubarraySum().minSubArrayLen(7, nums)); + } - public int minSubArrayLen(int s, int[] nums) { - int sum = 0, count = 0, min = Integer.MAX_VALUE; - for(int i = 0, j = 0; j < nums.length;){ - if(nums[j] >= s){ - return 1; - } else{ - sum += nums[j]; - count ++; - if(sum >= s){ - min = Math.min(min, count); - while(j > i){ - sum -= nums[i]; - count --; - i ++; - if(sum < s) break; - min = Math.min(min, count); - } - } - } - j ++; + public int minSubArrayLen(int s, int[] nums) { + int sum = 0, count = 0, min = Integer.MAX_VALUE; + for (int i = 0, j = 0; j < nums.length; ) { + if (nums[j] >= s) { + return 1; + } else { + sum += nums[j]; + count++; + if (sum >= s) { + min = Math.min(min, count); + while (j > i) { + sum -= nums[i]; + count--; + i++; + if (sum < s) break; + min = Math.min(min, count); + } } - if(min == Integer.MAX_VALUE){ - return 0; - } - return min; + } + j++; + } + if (min == Integer.MAX_VALUE) { + return 0; } + return min; + } } diff --git a/problems/src/two_pointers/MinimumWindowSubstring.java b/problems/src/two_pointers/MinimumWindowSubstring.java index 39089823..79f2bfd3 100644 --- a/problems/src/two_pointers/MinimumWindowSubstring.java +++ b/problems/src/two_pointers/MinimumWindowSubstring.java @@ -3,82 +3,79 @@ /** * Created by gouthamvidyapradhan on 03/12/2017. * - * Given a string S and a string T, find the minimum window in S which will contain all the characters in - * T in complexity O(n). - - For example, - S = "ADOBECODEBANC" - T = "ABC" - Minimum window is "BANC". - - Note: - If there is no such window in S that covers all characters in T, return the empty string "". - - If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S. - - Solution O(n). Sliding window sub-sting using two pointers. - + *

Given a string S and a string T, find the minimum window in S which will contain all the + * characters in T in complexity O(n). + * + *

For example, S = "ADOBECODEBANC" T = "ABC" Minimum window is "BANC". + * + *

Note: If there is no such window in S that covers all characters in T, return the empty string + * "". + * + *

If there are multiple such windows, you are guaranteed that there will always be only one + * unique minimum window in S. + * + *

Solution O(n). Sliding window sub-sting using two pointers. */ public class MinimumWindowSubstring { - private int[] hash = new int[256]; - private int[] curr = new int[256]; + private int[] hash = new int[256]; + private int[] curr = new int[256]; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - System.out.println(new MinimumWindowSubstring().minWindow("ADOBECODEBANC", "ABC")); + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + System.out.println(new MinimumWindowSubstring().minWindow("ADOBECODEBANC", "ABC")); + } + + public String minWindow(String s, String t) { + if (s.isEmpty() && t.isEmpty()) return ""; + if (t.length() > s.length()) return ""; + int start = -1, end = -1, min = Integer.MAX_VALUE; + for (int i = 0, l = t.length(); i < l; i++) { + hash[t.charAt(i)]++; } - public String minWindow(String s, String t) { - if(s.isEmpty() && t.isEmpty()) return ""; - if(t.length() > s.length()) return ""; - int start = -1, end = -1, min = Integer.MAX_VALUE; - for(int i = 0, l = t.length(); i < l; i ++){ - hash[t.charAt(i)]++; - } + for (int i = 0, l = t.length() - 1; i < l; i++) { + curr[s.charAt(i)]++; + } - for(int i = 0, l = t.length() - 1; i < l; i ++){ - curr[s.charAt(i)]++; + for (int i = 0, j = t.length() - 1, l = s.length(); j < l; ) { + curr[s.charAt(j)]++; + if (isMatch()) { + if (j - i < min) { + min = j - i; + start = i; + end = j; } - - for(int i = 0, j = t.length() - 1, l = s.length(); j < l;){ - curr[s.charAt(j)]++; - if(isMatch()){ - if(j - i < min){ - min = j - i; - start = i; - end = j; - } - while(j > i){ - curr[s.charAt(i)]--; - i ++; - if(isMatch()){ - if(j - i < min){ - min = j - i; - start = i; - end = j; - } - } else break; - } + while (j > i) { + curr[s.charAt(i)]--; + i++; + if (isMatch()) { + if (j - i < min) { + min = j - i; + start = i; + end = j; } - j ++; - } - if(min == Integer.MAX_VALUE){ - return ""; + } else break; } - return s.substring(start, end + 1); + } + j++; } + if (min == Integer.MAX_VALUE) { + return ""; + } + return s.substring(start, end + 1); + } - - private boolean isMatch(){ - for(int i = 0; i < 256; i ++){ - if(curr[i] < hash[i]){ - return false; - } - } - return true; + private boolean isMatch() { + for (int i = 0; i < 256; i++) { + if (curr[i] < hash[i]) { + return false; + } } + return true; + } } diff --git a/problems/src/two_pointers/MoveZeroes.java b/problems/src/two_pointers/MoveZeroes.java index 9805b6df..c3ec945f 100644 --- a/problems/src/two_pointers/MoveZeroes.java +++ b/problems/src/two_pointers/MoveZeroes.java @@ -1,39 +1,34 @@ package two_pointers; /** - * Created by gouthamvidyapradhan on 13/06/2017. - * Accepted - * Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements. - *

- * For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0]. - *

- * Note: - * You must do this in-place without making a copy of the array. - * Minimize the total number of operations. + * Created by gouthamvidyapradhan on 13/06/2017. Accepted Given an array nums, write a function to + * move all 0's to the end of it while maintaining the relative order of the non-zero elements. + * + *

For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, + * 12, 0, 0]. + * + *

Note: You must do this in-place without making a copy of the array. Minimize the total number + * of operations. */ public class MoveZeroes { - public static void main(String[] args) throws Exception { - int[] nums = {0, 0, 0, 0, 1, 0, 1, 0, 2}; - new MoveZeroes().moveZeroes(nums); - for (int n : nums) - System.out.print(n); - } + public static void main(String[] args) throws Exception { + int[] nums = {0, 0, 0, 0, 1, 0, 1, 0, 2}; + new MoveZeroes().moveZeroes(nums); + for (int n : nums) System.out.print(n); + } - public void moveZeroes(int[] nums) { - int i = 0; - for (int j = 0, l = nums.length; j < l; ) { - if (nums[j] == 0) - j++; - else { - int temp = nums[i]; - nums[i] = nums[j]; - nums[j] = temp; - i++; - j++; - } - } - while (i < nums.length) - nums[i++] = 0; + public void moveZeroes(int[] nums) { + int i = 0; + for (int j = 0, l = nums.length; j < l; ) { + if (nums[j] == 0) j++; + else { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + i++; + j++; + } } - + while (i < nums.length) nums[i++] = 0; + } } diff --git a/problems/src/two_pointers/NumberOfMatchingSubsequences.java b/problems/src/two_pointers/NumberOfMatchingSubsequences.java index 51dd3dc4..d41408ed 100644 --- a/problems/src/two_pointers/NumberOfMatchingSubsequences.java +++ b/problems/src/two_pointers/NumberOfMatchingSubsequences.java @@ -1,63 +1,56 @@ package two_pointers; /** - * Created by gouthamvidyapradhan on 04/04/2019 - * Given string S and a dictionary of words words, find the number of words[i] that is a subsequence of S. + * Created by gouthamvidyapradhan on 04/04/2019 Given string S and a dictionary of words words, find + * the number of words[i] that is a subsequence of S. * - * Example : - * Input: - * S = "abcde" - * words = ["a", "bb", "acd", "ace"] - * Output: 3 - * Explanation: There are three words in words that are a subsequence of S: "a", "acd", "ace". - * Note: + *

Example : Input: S = "abcde" words = ["a", "bb", "acd", "ace"] Output: 3 Explanation: There + * are three words in words that are a subsequence of S: "a", "acd", "ace". Note: * - * All words in words and S will only consists of lowercase letters. - * The length of S will be in the range of [1, 50000]. - * The length of words will be in the range of [1, 5000]. - * The length of words[i] will be in the range of [1, 50]. - * - * Solution: O((w + S) x N (no of words)) - * Using two pointers technique check if each of the given string is a sub-sequence of the main string. + *

All words in words and S will only consists of lowercase letters. The length of S will be in + * the range of [1, 50000]. The length of words will be in the range of [1, 5000]. The length of + * words[i] will be in the range of [1, 50]. * + *

Solution: O((w + S) x N (no of words)) Using two pointers technique check if each of the given + * string is a sub-sequence of the main string. */ public class NumberOfMatchingSubsequences { - /** - * Main method - * @param args - */ - public static void main(String[] args) { - String[] A = {"a", "bb", "acd", "ace"}; - System.out.println(new NumberOfMatchingSubsequences().numMatchingSubseq("abcde", A)); - } + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + String[] A = {"a", "bb", "acd", "ace"}; + System.out.println(new NumberOfMatchingSubsequences().numMatchingSubseq("abcde", A)); + } - public int numMatchingSubseq(String S, String[] words) { - int count = 0; - for(int i = 0; i < words.length; i ++){ - String w = words[i]; - if(isSubsequence(S, w)){ - count ++; - } - } - return count; + public int numMatchingSubseq(String S, String[] words) { + int count = 0; + for (int i = 0; i < words.length; i++) { + String w = words[i]; + if (isSubsequence(S, w)) { + count++; + } } + return count; + } - private boolean isSubsequence(String S, String P){ - int i = 0, j = 0; - if(P.length() > S.length()) return false; - for(;;){ - if(j >= P.length()) return true; - else if(i >= S.length()) return false; - else { - if(S.charAt(i) == P.charAt(j)){ - i ++; - j ++; - } else { - i ++; - } - } + private boolean isSubsequence(String S, String P) { + int i = 0, j = 0; + if (P.length() > S.length()) return false; + for (; ; ) { + if (j >= P.length()) return true; + else if (i >= S.length()) return false; + else { + if (S.charAt(i) == P.charAt(j)) { + i++; + j++; + } else { + i++; } + } } - + } } diff --git a/problems/src/two_pointers/RemoveDuplicates.java b/problems/src/two_pointers/RemoveDuplicates.java index 9d1e9741..34fb1352 100644 --- a/problems/src/two_pointers/RemoveDuplicates.java +++ b/problems/src/two_pointers/RemoveDuplicates.java @@ -1,34 +1,33 @@ package two_pointers; /** - * Created by gouthamvidyapradhan on 04/07/2017. - * Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. - *

- * Do not allocate extra space for another array, you must do this in place with constant memory. - *

- * For example, - * Given input array nums = [1,1,2], - *

- * Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length. + * Created by gouthamvidyapradhan on 04/07/2017. Given a sorted array, remove the duplicates in + * place such that each element appear only once and return the new length. + * + *

Do not allocate extra space for another array, you must do this in place with constant memory. + * + *

For example, Given input array nums = [1,1,2], + * + *

Your function should return length = 2, with the first two elements of nums being 1 and 2 + * respectively. It doesn't matter what you leave beyond the new length. */ public class RemoveDuplicates { - public static void main(String[] args) throws Exception { - int[] nums = {1, 1, 2}; - int N = new RemoveDuplicates().removeDuplicates(nums); - for (int i = 0; i < N; i++) - System.out.print(nums[i] + " "); - } + public static void main(String[] args) throws Exception { + int[] nums = {1, 1, 2}; + int N = new RemoveDuplicates().removeDuplicates(nums); + for (int i = 0; i < N; i++) System.out.print(nums[i] + " "); + } - public int removeDuplicates(int[] nums) { - if (nums.length == 1) return 1; - int size = 1; - for (int j = 0, i = 1; i < nums.length; i++) { - if (nums[i] != nums[i - 1]) { - size++; - j++; - nums[j] = nums[i]; - } - } - return size; + public int removeDuplicates(int[] nums) { + if (nums.length == 1) return 1; + int size = 1; + for (int j = 0, i = 1; i < nums.length; i++) { + if (nums[i] != nums[i - 1]) { + size++; + j++; + nums[j] = nums[i]; + } } + return size; + } } diff --git a/problems/src/two_pointers/RemoveDuplicatesII.java b/problems/src/two_pointers/RemoveDuplicatesII.java index 10c59f98..e2c302d6 100644 --- a/problems/src/two_pointers/RemoveDuplicatesII.java +++ b/problems/src/two_pointers/RemoveDuplicatesII.java @@ -1,44 +1,42 @@ package two_pointers; /** - * Created by gouthamvidyapradhan on 20/01/2018. - * Follow up for "Remove Duplicates": - What if duplicates are allowed at most twice? - - For example, - Given sorted array nums = [1,1,1,2,2,3], - - Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 and 3. It doesn't - matter what you leave beyond the new length. + * Created by gouthamvidyapradhan on 20/01/2018. Follow up for "Remove Duplicates": What if + * duplicates are allowed at most twice? + * + *

For example, Given sorted array nums = [1,1,1,2,2,3], + * + *

Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 + * and 3. It doesn't matter what you leave beyond the new length. */ public class RemoveDuplicatesII { - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - int[] A = {1, 1, 1, 2, 2, 2, 3, 4, 4}; - System.out.println(new RemoveDuplicatesII().removeDuplicates(A)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] A = {1, 1, 1, 2, 2, 2, 3, 4, 4}; + System.out.println(new RemoveDuplicatesII().removeDuplicates(A)); + } - public int removeDuplicates(int[] nums) { - if(nums.length == 0) return 0; - int j = 0; - int count = 1; - for(int i = 1; i < nums.length; i++){ - if(nums[i - 1] == nums[i]){ - count ++; - } else{ - count = 1; - } - if(count == 1 || count == 2){ - j++; - nums[j] = nums[i]; - } - } - return j + 1; + public int removeDuplicates(int[] nums) { + if (nums.length == 0) return 0; + int j = 0; + int count = 1; + for (int i = 1; i < nums.length; i++) { + if (nums[i - 1] == nums[i]) { + count++; + } else { + count = 1; + } + if (count == 1 || count == 2) { + j++; + nums[j] = nums[i]; + } } - + return j + 1; + } } diff --git a/problems/src/two_pointers/SmallestRange.java b/problems/src/two_pointers/SmallestRange.java index f0d66392..90152485 100644 --- a/problems/src/two_pointers/SmallestRange.java +++ b/problems/src/two_pointers/SmallestRange.java @@ -6,81 +6,75 @@ import java.util.PriorityQueue; /** - * Created by gouthamvidyapradhan on 23/01/2018. - * You have k lists of sorted integers in ascending order. Find the smallest range that includes at least one number - * from each of the k lists. - - We define the range [a,b] is smaller than range [c,d] if b-a < d-c or a < c if b-a == d-c. - - Example 1: - Input:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]] - Output: [20,24] - Explanation: - List 1: [4, 10, 15, 24,26], 24 is in range [20,24]. - List 2: [0, 9, 12, 20], 20 is in range [20,24]. - List 3: [5, 18, 22, 30], 22 is in range [20,24]. - Note: - The given list may contain duplicates, so ascending order means >= here. - 1 <= k <= 3500 - -105 <= value of elements <= 105. - For Java users, please note that the input type has been changed to List>. And after you reset the - code template, you'll see this point. - - Solution O(n log m) where m is the total number of lists and n in the total elements in all the list combined. - + * Created by gouthamvidyapradhan on 23/01/2018. You have k lists of sorted integers in ascending + * order. Find the smallest range that includes at least one number from each of the k lists. + * + *

We define the range [a,b] is smaller than range [c,d] if b-a < d-c or a < c if b-a == d-c. + * + *

Example 1: Input:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]] Output: [20,24] Explanation: + * List 1: [4, 10, 15, 24,26], 24 is in range [20,24]. List 2: [0, 9, 12, 20], 20 is in range + * [20,24]. List 3: [5, 18, 22, 30], 22 is in range [20,24]. Note: The given list may contain + * duplicates, so ascending order means >= here. 1 <= k <= 3500 -105 <= value of elements <= 105. + * For Java users, please note that the input type has been changed to List>. And + * after you reset the code template, you'll see this point. + * + *

Solution O(n log m) where m is the total number of lists and n in the total elements in all + * the list combined. */ public class SmallestRange { - class MinIndex{ - int i, j; - MinIndex(int i, int j){ - this.i = i; - this.j = j; - } - } + class MinIndex { + int i, j; - /** - * Main method - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception{ - List> list = new ArrayList<>(); - List row1 = Arrays.asList(4,10,15,24,26); - List row2 = Arrays.asList(0,9,12,20); - List row3 = Arrays.asList(5,18,22,30); - list.add(row1); - list.add(row2); - list.add(row3); - int[] R = new SmallestRange().smallestRange(list); - System.out.println(R[0] + " " + R[1]); + MinIndex(int i, int j) { + this.i = i; + this.j = j; } + } - public int[] smallestRange(List> nums) { - PriorityQueue pq = new PriorityQueue<>((o1, o2) -> - Integer.compare(nums.get(o1.i).get(o1.j), nums.get(o2.i).get(o2.j))); - int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE; - for(int i = 0, l = nums.size(); i < l; i ++){ - min = Math.min(min, nums.get(i).get(0)); - max = Math.max(max, nums.get(i).get(0)); - pq.offer(new MinIndex(i, 0)); - } - if(min == max) return new int[]{min, max}; - int ansMin = min, ansMax = max; - while(true){ - MinIndex minIndex = pq.poll(); - if(minIndex.j + 1 >= nums.get(minIndex.i).size()){ - return new int[]{ansMin, ansMax}; - } - int next = nums.get(minIndex.i).get(minIndex.j + 1); - max = Math.max(max, next); //update max if any - pq.offer(new MinIndex(minIndex.i, minIndex.j + 1)); - min = nums.get(pq.peek().i).get(pq.peek().j); //new minimum - if((max - min) < (ansMax - ansMin)){ - ansMax = max; - ansMin = min; - } - } - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + List> list = new ArrayList<>(); + List row1 = Arrays.asList(4, 10, 15, 24, 26); + List row2 = Arrays.asList(0, 9, 12, 20); + List row3 = Arrays.asList(5, 18, 22, 30); + list.add(row1); + list.add(row2); + list.add(row3); + int[] R = new SmallestRange().smallestRange(list); + System.out.println(R[0] + " " + R[1]); + } + public int[] smallestRange(List> nums) { + PriorityQueue pq = + new PriorityQueue<>( + (o1, o2) -> Integer.compare(nums.get(o1.i).get(o1.j), nums.get(o2.i).get(o2.j))); + int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE; + for (int i = 0, l = nums.size(); i < l; i++) { + min = Math.min(min, nums.get(i).get(0)); + max = Math.max(max, nums.get(i).get(0)); + pq.offer(new MinIndex(i, 0)); + } + if (min == max) return new int[] {min, max}; + int ansMin = min, ansMax = max; + while (true) { + MinIndex minIndex = pq.poll(); + if (minIndex.j + 1 >= nums.get(minIndex.i).size()) { + return new int[] {ansMin, ansMax}; + } + int next = nums.get(minIndex.i).get(minIndex.j + 1); + max = Math.max(max, next); // update max if any + pq.offer(new MinIndex(minIndex.i, minIndex.j + 1)); + min = nums.get(pq.peek().i).get(pq.peek().j); // new minimum + if ((max - min) < (ansMax - ansMin)) { + ansMax = max; + ansMin = min; + } + } + } } diff --git a/problems/src/two_pointers/SubarrayProductLessThanK.java b/problems/src/two_pointers/SubarrayProductLessThanK.java index 553ce797..75ccbba9 100644 --- a/problems/src/two_pointers/SubarrayProductLessThanK.java +++ b/problems/src/two_pointers/SubarrayProductLessThanK.java @@ -1,68 +1,59 @@ -package two_pointers; /** - * Created by gouthamvidyapradhan on 17/02/2018. - * Your are given an array of positive integers nums. - - Count and print the number of (contiguous) subarrays where the product of all the elements in the subarray is less - than k. - - Example 1: - Input: nums = [10, 5, 2, 6], k = 100 - Output: 8 - Explanation: The 8 subarrays that have product less than 100 are: [10], [5], [2], [6], [10, 5], [5, 2], [2, 6], - [5, 2, 6]. - Note that [10, 5, 2] is not included as the product of 100 is not strictly less than k. - Note: - - 0 < nums.length <= 50000. - 0 < nums[i] < 1000. - 0 <= k < 10^6. +package two_pointers; +/** + * Created by gouthamvidyapradhan on 17/02/2018. Your are given an array of positive integers nums. + * + *

Count and print the number of (contiguous) subarrays where the product of all the elements in + * the subarray is less than k. + * + *

Example 1: Input: nums = [10, 5, 2, 6], k = 100 Output: 8 Explanation: The 8 subarrays that + * have product less than 100 are: [10], [5], [2], [6], [10, 5], [5, 2], [2, 6], [5, 2, 6]. Note + * that [10, 5, 2] is not included as the product of 100 is not strictly less than k. Note: + * + *

0 < nums.length <= 50000. 0 < nums[i] < 1000. 0 <= k < 10^6. */ - import java.util.ArrayDeque; import java.util.Queue; public class SubarrayProductLessThanK { - public static void main(String[] args) throws Exception{ - int[] A = {10,2,2,5,4,4,4,3,7,7}; - System.out.println(new SubarrayProductLessThanK().numSubarrayProductLessThanK(A, 289)); - } - - - public int numSubarrayProductLessThanK(int[] nums, int k) { - long prod = 1; - int count = 0; - Queue queue = new ArrayDeque<>(); - for(int i = 0; i < nums.length; i++){ - if(nums[i] < k){ - count++; - if((prod * nums[i]) < k){ - prod *= nums[i]; - if(!queue.isEmpty()){ - count += (i - queue.peek()); - } - }else{ - while(!queue.isEmpty()){ - int last = queue.poll(); - prod /= nums[last]; - if((prod * nums[i]) < k){ - prod = prod * nums[i]; - if(!queue.isEmpty()){ - count += (i - queue.peek()); - } - break; - } - } - } - if(queue.isEmpty()){ - prod = nums[i]; - } - queue.offer(i); - } else{ - queue.clear(); + public static void main(String[] args) throws Exception { + int[] A = {10, 2, 2, 5, 4, 4, 4, 3, 7, 7}; + System.out.println(new SubarrayProductLessThanK().numSubarrayProductLessThanK(A, 289)); + } + + public int numSubarrayProductLessThanK(int[] nums, int k) { + long prod = 1; + int count = 0; + Queue queue = new ArrayDeque<>(); + for (int i = 0; i < nums.length; i++) { + if (nums[i] < k) { + count++; + if ((prod * nums[i]) < k) { + prod *= nums[i]; + if (!queue.isEmpty()) { + count += (i - queue.peek()); + } + } else { + while (!queue.isEmpty()) { + int last = queue.poll(); + prod /= nums[last]; + if ((prod * nums[i]) < k) { + prod = prod * nums[i]; + if (!queue.isEmpty()) { + count += (i - queue.peek()); + } + break; } + } } - return count; + if (queue.isEmpty()) { + prod = nums[i]; + } + queue.offer(i); + } else { + queue.clear(); + } } - + return count; + } } diff --git a/problems/src/two_pointers/ThreeSum.java b/problems/src/two_pointers/ThreeSum.java index 22d91ad9..42ab17e0 100644 --- a/problems/src/two_pointers/ThreeSum.java +++ b/problems/src/two_pointers/ThreeSum.java @@ -5,53 +5,53 @@ import java.util.List; /** - * Created by gouthamvidyapradhan on 29/03/2017. - * Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. - *

- * Note: The solution set must not contain duplicate triplets. - *

- * For example, given array S = [-1, 0, 1, 2, -1, -4], - *

- * A solution set is: - * [ - * [-1, 0, 1], - * [-1, -1, 2] - * ] + * Created by gouthamvidyapradhan on 29/03/2017. Given an array S of n integers, are there elements + * a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum + * of zero. + * + *

Note: The solution set must not contain duplicate triplets. + * + *

For example, given array S = [-1, 0, 1, 2, -1, -4], + * + *

A solution set is: [ [-1, 0, 1], [-1, -1, 2] ] */ public class ThreeSum { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] nums = {-1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4}; - System.out.println(new ThreeSum().threeSum(nums)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] nums = { + -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, + 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4 + }; + System.out.println(new ThreeSum().threeSum(nums)); + } - public List> threeSum(int[] nums) { - List> result = new ArrayList<>(); - if (nums.length < 3) return result; - Arrays.sort(nums); - for (int i = 0, l = nums.length; i < l - 2; i++) { - if (i == 0 || nums[i] != nums[i - 1]) { - int j = i + 1, k = l - 1; - while (k > j) { - if (j != i + 1 && nums[j] == nums[j - 1]) { - j++; - continue; - } - int sum = nums[i] + nums[j] + nums[k]; - if (sum == 0) { - result.add(Arrays.asList(nums[i], nums[j], nums[k])); - k--; - j++; - } else if (sum > 0) k--; - else j++; - } - } + public List> threeSum(int[] nums) { + List> result = new ArrayList<>(); + if (nums.length < 3) return result; + Arrays.sort(nums); + for (int i = 0, l = nums.length; i < l - 2; i++) { + if (i == 0 || nums[i] != nums[i - 1]) { + int j = i + 1, k = l - 1; + while (k > j) { + if (j != i + 1 && nums[j] == nums[j - 1]) { + j++; + continue; + } + int sum = nums[i] + nums[j] + nums[k]; + if (sum == 0) { + result.add(Arrays.asList(nums[i], nums[j], nums[k])); + k--; + j++; + } else if (sum > 0) k--; + else j++; } - return result; + } } + return result; + } } diff --git a/problems/src/two_pointers/ThreeSumClosest.java b/problems/src/two_pointers/ThreeSumClosest.java index 769db5c8..97329084 100644 --- a/problems/src/two_pointers/ThreeSumClosest.java +++ b/problems/src/two_pointers/ThreeSumClosest.java @@ -3,53 +3,53 @@ import java.util.Arrays; /** - * Created by gouthamvidyapradhan on 13/06/2017. - * Accepted - * Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. - *

- * For example, given array S = {-1 2 1 -4}, and target = 1. - *

- * The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). + * Created by gouthamvidyapradhan on 13/06/2017. Accepted Given an array S of n integers, find three + * integers in S such that the sum is closest to a given number, target. Return the sum of the three + * integers. You may assume that each input would have exactly one solution. + * + *

For example, given array S = {-1 2 1 -4}, and target = 1. + * + *

The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). */ public class ThreeSumClosest { - public static void main(String[] args) { - int[] a = {-1, 2, 1, -4}; - System.out.println(new ThreeSumClosest().threeSumClosest(a, 1)); - } + public static void main(String[] args) { + int[] a = {-1, 2, 1, -4}; + System.out.println(new ThreeSumClosest().threeSumClosest(a, 1)); + } - public int threeSumClosest(int[] a, int target) { - Arrays.sort(a); - int min = Integer.MAX_VALUE, ans = -1; - for (int i = 0, l = a.length; i < l - 2; i++) { - if (i == 0 || !(a[i] == a[i - 1])) { - int j = i + 1, k = l - 1; - while (k > j) { - if (j != i + 1 && (a[j] == a[j - 1])) { - j++; - continue; - } - int sum = a[i] + a[j] + a[k]; - if (sum < target) { - int diff = Math.abs(sum - target); - if (diff < min) { - min = diff; - ans = sum; - } - j++; - } else if (sum > target) { - int diff = Math.abs(sum - target); - if (diff < min) { - min = diff; - ans = sum; - } - k--; - } else { - return sum; - } - } + public int threeSumClosest(int[] a, int target) { + Arrays.sort(a); + int min = Integer.MAX_VALUE, ans = -1; + for (int i = 0, l = a.length; i < l - 2; i++) { + if (i == 0 || !(a[i] == a[i - 1])) { + int j = i + 1, k = l - 1; + while (k > j) { + if (j != i + 1 && (a[j] == a[j - 1])) { + j++; + continue; + } + int sum = a[i] + a[j] + a[k]; + if (sum < target) { + int diff = Math.abs(sum - target); + if (diff < min) { + min = diff; + ans = sum; + } + j++; + } else if (sum > target) { + int diff = Math.abs(sum - target); + if (diff < min) { + min = diff; + ans = sum; } + k--; + } else { + return sum; + } } - return ans; + } } + return ans; + } } diff --git a/problems/src/two_pointers/TrappingRainWater.java b/problems/src/two_pointers/TrappingRainWater.java index 3fda5a3c..cf8d3f06 100644 --- a/problems/src/two_pointers/TrappingRainWater.java +++ b/problems/src/two_pointers/TrappingRainWater.java @@ -1,50 +1,50 @@ package two_pointers; /** - * Created by gouthamvidyapradhan on 08/03/2017. - * Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. - *

- * For example, - * Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6. + * Created by gouthamvidyapradhan on 08/03/2017. Given n non-negative integers representing an + * elevation map where the width of each bar is 1, compute how much water it is able to trap after + * raining. + * + *

For example, Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6. */ public class TrappingRainWater { - /** - * Main method - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - int[] height = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1}; - System.out.println(new TrappingRainWater().trap(height)); - } + /** + * Main method + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + int[] height = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1}; + System.out.println(new TrappingRainWater().trap(height)); + } - private int trap(int[] height) { - if (height.length == 0) return 0; + private int trap(int[] height) { + if (height.length == 0) return 0; - int[] left = new int[height.length]; - int[] right = new int[height.length]; - int max = 0; - left[0] = 0; - right[height.length - 1] = 0; + int[] left = new int[height.length]; + int[] right = new int[height.length]; + int max = 0; + left[0] = 0; + right[height.length - 1] = 0; - int total = 0; + int total = 0; - for (int i = 1, l = height.length; i < l; i++) { - left[i] = Math.max(max, height[i - 1]); - max = left[i]; - } - max = 0; - for (int i = height.length - 2; i >= 0; i--) { - right[i] = Math.max(max, height[i + 1]); - max = right[i]; - } - for (int i = 0, l = height.length; i < l; i++) { - int min = Math.min(left[i], right[i]); - if (min > height[i]) { - total += (min - height[i]); - } - } - return total; + for (int i = 1, l = height.length; i < l; i++) { + left[i] = Math.max(max, height[i - 1]); + max = left[i]; + } + max = 0; + for (int i = height.length - 2; i >= 0; i--) { + right[i] = Math.max(max, height[i + 1]); + max = right[i]; + } + for (int i = 0, l = height.length; i < l; i++) { + int min = Math.min(left[i], right[i]); + if (min > height[i]) { + total += (min - height[i]); + } } + return total; + } } diff --git a/problems/src/zalando/TaskA.java b/problems/src/zalando/TaskA.java deleted file mode 100644 index 52a848ae..00000000 --- a/problems/src/zalando/TaskA.java +++ /dev/null @@ -1,7 +0,0 @@ -package zalando; - -/** - * Created by gouthamvidyapradhan on 05/07/2018. - */ -public class TaskA { -} diff --git a/problems/src/zalando/TaskB.java b/problems/src/zalando/TaskB.java deleted file mode 100644 index ec33b9d5..00000000 --- a/problems/src/zalando/TaskB.java +++ /dev/null @@ -1,7 +0,0 @@ -package zalando; - -/** - * Created by gouthamvidyapradhan on 05/07/2018. - */ -public class TaskB { -} From f6feb9f1e15fe134e2d17e0094077398cbe3235a Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 3 Jul 2019 09:17:49 +0200 Subject: [PATCH 212/235] Solved problems --- README.md | 20 +++- problems/src/array/MaxConsecutiveOnes.java | 37 ++++++ problems/src/array/MaxConsecutiveOnesII.java | 72 +++++++++++ .../src/backtracking/MatchsticksToSquare.java | 112 ++++++++++++++++++ problems/src/backtracking/ZumaGame.java | 88 ++++++++++++++ .../binary_search/TimeBasedKeyValuePair.java | 82 +++++++++++++ .../BinaryNumberWithAlternatingBits.java | 32 +++++ .../depth_first_search/MaxAreaOfIsland.java | 71 +++++++++++ .../divide_and_conquer/TwentyFourGame.java | 109 +++++++++++++++++ .../MinimumCostForTickets.java | 84 +++++++++++++ .../OutOfBoundaryPaths.java | 47 ++++++++ .../src/dynamic_programming/RemoveBoxes.java | 43 +++++++ .../RussianDollEnvelopes.java | 70 +++++++++++ problems/src/greedy/BoatsToSavePeople.java | 65 ++++++++++ problems/src/greedy/StringWithout3A3B.java | 63 ++++++++++ .../heap/ReachableNodesInSubdividedGraph.java | 111 +++++++++++++++++ .../src/math/ProjectionAreaOf3DShapes.java | 74 ++++++++++++ problems/src/stack/DecodedStringAtIndex.java | 68 +++++++++++ .../src/stack/StudentAttendanceRecordII.java | 51 ++++++++ .../ReconstructOriginalDigitsFromEnglish.java | 87 ++++++++++++++ .../src/string/SplitConcatenatedStrings.java | 67 +++++++++++ .../src/string/StudentAttendanceRecordI.java | 31 +++++ problems/src/string/ValidWordSquare.java | 77 ++++++++++++ 23 files changed, 1560 insertions(+), 1 deletion(-) create mode 100644 problems/src/array/MaxConsecutiveOnes.java create mode 100644 problems/src/array/MaxConsecutiveOnesII.java create mode 100644 problems/src/backtracking/MatchsticksToSquare.java create mode 100644 problems/src/backtracking/ZumaGame.java create mode 100644 problems/src/binary_search/TimeBasedKeyValuePair.java create mode 100644 problems/src/bit_manipulation/BinaryNumberWithAlternatingBits.java create mode 100644 problems/src/depth_first_search/MaxAreaOfIsland.java create mode 100644 problems/src/divide_and_conquer/TwentyFourGame.java create mode 100644 problems/src/dynamic_programming/MinimumCostForTickets.java create mode 100644 problems/src/dynamic_programming/OutOfBoundaryPaths.java create mode 100644 problems/src/dynamic_programming/RemoveBoxes.java create mode 100644 problems/src/dynamic_programming/RussianDollEnvelopes.java create mode 100644 problems/src/greedy/BoatsToSavePeople.java create mode 100644 problems/src/greedy/StringWithout3A3B.java create mode 100644 problems/src/heap/ReachableNodesInSubdividedGraph.java create mode 100644 problems/src/math/ProjectionAreaOf3DShapes.java create mode 100644 problems/src/stack/DecodedStringAtIndex.java create mode 100644 problems/src/stack/StudentAttendanceRecordII.java create mode 100644 problems/src/string/ReconstructOriginalDigitsFromEnglish.java create mode 100644 problems/src/string/SplitConcatenatedStrings.java create mode 100644 problems/src/string/StudentAttendanceRecordI.java create mode 100644 problems/src/string/ValidWordSquare.java diff --git a/README.md b/README.md index 6070d906..7ed1aaaf 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,8 @@ My accepted leetcode solutions to some of the common interview problems. - [Valid Tic-Tac-Toe State](problems/src/array/ValidTicTacToeState.java) (Medium) - [Number of Subarrays with Bounded Maximum](problems/src/array/SubArraysWithBoundedMaximum.java) (Medium) - [Surface Area of 3D Shapes](problems/src/array/SurfaceAreaOfThreeDShapes.java) (Easy) +- [Max Consecutive Ones](problems/src/array/MaxConsecutiveOnes.java) (Easy) +- [Max Consecutive Ones II](problems/src/array/MaxConsecutiveOnesII.java) (Medium) #### [Backtracking](problems/src/backtracking) @@ -67,7 +69,8 @@ My accepted leetcode solutions to some of the common interview problems. - [Expression Add Operators](problems/src/backtracking/ExpressionAddOperators.java) (Hard) - [Wildcard Matching](problems/src/backtracking/WildcardMatching.java) (Hard) - [Letter Case Permutation](problems/src/backtracking/LetterCasePermutation.java) (Easy) - +- [Zuma Game](problems/src/backtracking/ZumaGame.java) (Hard) +- [Matchsticks to Square](problems/src/backtracking/MatchsticksToSquare.java) (Medium) #### [Binary Search](problems/src/binary_search) @@ -82,6 +85,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Target Sum](problems/src/binary_search/TargetSum.java) (Medium) - [H-Index II](problems/src/binary_search/HIndexII.java) (Medium) - [Swim in Rising Water](problems/src/binary_search/SwimInRisingWater.java) (Hard) +- [Time Based Key-Value Store](problems/src/binary_search/TimeBasedKeyValuePair.java) (Medium) #### [Bit Manipulation](problems/src/bit_manipulation) @@ -89,6 +93,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Hamming Distance](problems/src/bit_manipulation/HammingDistance.java) (Easy) - [Total Hamming Distance](problems/src/bit_manipulation/TotalHammingDistance.java) (Medium) - [Divide Two Integers](problems/src/bit_manipulation/DivideTwoIntegers.java) (Medium) +- [Binary Number with Alternating Bits](problems/src/bit_manipulation/BinaryNumberWithAlternatingBits.java) (Easy) #### [Breadth First Search](problems/src/breadth_first_search) @@ -123,6 +128,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Robot Room Cleaner](problems/src/depth_first_search/RobotRoomCleaner.java) (Hard) - [Cracking the Safe](problems/src/depth_first_search/CrackingTheSafe.java) (Hard) - [All Paths From Source to Target](problems/src/depth_first_search/AllPathsFromSourceToTarget.java) (Medium) +- [Max Area of Island](problems/src/depth_first_search/MaxAreaOfIsland.java) (Medium) #### [Design](problems/src/design) @@ -148,6 +154,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Kth Largest Element In a Array](problems/src/divide_and_conquer/KthLargestElementInAnArray.java) (Medium) - [Reverse Pairs](problems/src/divide_and_conquer/ReversePairs.java) (Hard) - [Search in a 2D Matrix](problems/src/divide_and_conquer/SearchA2DMatrix.java) (Medium) +- [24 Game](problems/src/divide_and_conquer/TwentyFourGame.java) (Hard) #### [Dynamic Programming](problems/src/dynamic_programming) @@ -197,6 +204,9 @@ My accepted leetcode solutions to some of the common interview problems. - [Odd Even Jump](problems/src/dynamic_programming/OddEvenJump.java) (Hard) - [Profitable Schemes](problems/src/dynamic_programming/ProfitableSchemes.java) (Hard) - [Maximum Vacation Days](problems/src/dynamic_programming/MaximumVacationDays.java) (Hard) +- [Russian Doll Envelopes](problems/src/dynamic_programming/RussianDollEnvelopes.java) (Hard) +- [Student Attendance Record II](problems/src/dynamic_programming/StudentAttendanceRecordII.java) (Hard) +- [Out of Boundary Paths](problems/src/dynamic_programming/OutOfBoundaryPaths.java) (Medium) #### [Greedy](problems/src/greedy) @@ -212,6 +222,8 @@ My accepted leetcode solutions to some of the common interview problems. - [Lemonade Change](problems/src/greedy/LemonadeChange.java) (Easy) - [Score After Flipping Matrix](problems/src/greedy/ScoreAfterFlippingMatrix.java) (Medium) - [IPO](problems/src/greedy/IPO.java) (Hard) +- [String Without AAA or BBB](problems/src/greedy/StringWithout3A3B.java) (Medium) +- [Boats to Save People](problems/src/greedy/BoatsToSavePeople.java) (Medium) #### [Hashing](problems/src/hashing) @@ -240,6 +252,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Candy](problems/src/heap/Candy.java) (Hard) - [Smallest Rotation with Highest Score](problems/src/heap/SmallestRotationWithHighestScore.java) (Hard) - [Maximum Frequency Stack](problems/src/heap/FreqStack.java) (Hard) +- [Reachable Nodes In Subdivided Graph](problems/src/heap/ReachableNodesInSubdividedGraph.java) (Hard) #### [Linked List](problems/src/linked_list) @@ -270,6 +283,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Reaching Points](problems/src/math/ReachingPoints.java) (Hard) - [Nth Magical Number](problems/src/math/NthMagicalNumber.java) (Hard) - [Squirrel Simulation](problems/src/math/SquirrelSimulation.java) (Medium) +- [Projection Area of 3D Shapes](problems/src/math/ProjectionAreaOf3DShapes.java) (Easy) #### [Reservoir Sampling](problems/src/reservoir_sampling) @@ -320,6 +334,10 @@ My accepted leetcode solutions to some of the common interview problems. - [Replace Words](problems/src/string/ReplaceWords.java) (Medium) - [Rotate String](problems/src/string/RotateString.java) (Easy) - [Keyboard Row](problems/src/string/KeyboardRow.java) (Easy) +- [Student Attendance Record I](problems/src/string/StudentAttendanceRecordI.java) (Easy) +- [Split Concatenated Strings](problems/src/string/SplitConcatenatedStrings.java) (Medium) +- [Valid Word Square](problems/src/string/ValidWordSquare.java) (Easy) +- [Reconstruct Original Digits from English](problems/src/string/ReconstructOriginalDigitsFromEnglish.java) (Medium) #### [Tree](problems/src/tree) diff --git a/problems/src/array/MaxConsecutiveOnes.java b/problems/src/array/MaxConsecutiveOnes.java new file mode 100644 index 00000000..93626cad --- /dev/null +++ b/problems/src/array/MaxConsecutiveOnes.java @@ -0,0 +1,37 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 08/05/2019 Given a binary array, find the maximum number of + * consecutive 1s in this array. + * + *

Example 1: Input: [1,1,0,1,1,1] Output: 3 Explanation: The first two digits or the last three + * digits are consecutive 1s. The maximum number of consecutive 1s is 3. Note: + * + *

The input array will only contain 0 and 1. The length of input array is a positive integer and + * will not exceed 10,000 + */ +public class MaxConsecutiveOnes { + public static void main(String[] args) { + // + } + + public int findMaxConsecutiveOnes(int[] nums) { + int max = 0; + boolean flag = false; + int count = 0; + for(int i = 0; i < nums.length; i ++){ + if(nums[i] == 1){ + if(!flag){ + flag = true; + } + count++; + max = Math.max(max, count); + } else{ + count = 0; + flag = false; + } + } + return max; + } + +} diff --git a/problems/src/array/MaxConsecutiveOnesII.java b/problems/src/array/MaxConsecutiveOnesII.java new file mode 100644 index 00000000..99d8041f --- /dev/null +++ b/problems/src/array/MaxConsecutiveOnesII.java @@ -0,0 +1,72 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 08/05/2019 Given a binary array, find the maximum number of + * consecutive 1s in this array if you can flip at most one 0. + * + *

Example 1: Input: [1,0,1,1,0] Output: 4 Explanation: Flip the first zero will get the the + * maximum number of consecutive 1s. After flipping, the maximum number of consecutive 1s is 4. + * Note: + * + *

The input array will only contain 0 and 1. The length of input array is a positive integer and + * will not exceed 10,000 Follow up: What if the input numbers come in one by one as an infinite + * stream? In other words, you can't store all numbers coming from the stream as it's too large to + * hold in memory. Could you solve it efficiently? + * + * Solution: O(N) + * Maintain a left and right auxiliary array with counts of contagious 1's from both directions. + * Now, iterate through the array and flip a 0 to 1 and sum up left and right contagious sum of 1's and return the + * max sum as the answer + */ +public class MaxConsecutiveOnesII { + public static void main(String[] args) { + // + } + public int findMaxConsecutiveOnes(int[] nums) { + int[] L = new int[nums.length]; + int[] R = new int[nums.length]; + boolean flag = false; + int count = 0; + int max = 0; + for(int j = 0; j < nums.length; j ++){ + if(nums[j] == 1){ + if(!flag){ + flag = true; + } + count++; + L[j] = count; + } else{ + count = 0; + flag = false; + L[j] = count; + } + max = Math.max(max, count); + } + + flag = false; + count = 0; + for(int j = nums.length - 1; j >= 0; j --){ + if(nums[j] == 1){ + if(!flag){ + flag = true; + } + count++; + R[j] = count; + } else{ + count = 0; + flag = false; + R[j] = count; + } + } + + for(int i = 0; i < nums.length; i ++){ + if(nums[i] == 0){ + int l = i == 0 ? 0 : L[i - 1]; + int r = i == nums.length - 1 ? 0 : R[i + 1]; + max = Math.max(max, l + r + 1); + } + } + return max; + } + +} diff --git a/problems/src/backtracking/MatchsticksToSquare.java b/problems/src/backtracking/MatchsticksToSquare.java new file mode 100644 index 00000000..6a2a78aa --- /dev/null +++ b/problems/src/backtracking/MatchsticksToSquare.java @@ -0,0 +1,112 @@ +package backtracking; +import java.util.*; +/** + * Created by gouthamvidyapradhan on 25/05/2019 Remember the story of Little Match Girl? By now, you + * know exactly what matchsticks the little match girl has, please find out a way you can make one + * square by using up all those matchsticks. You should not break any stick, but you can link them + * up, and each matchstick must be used exactly one time. + * + *

Your input will be several matchsticks the girl has, represented with their stick length. Your + * output will either be true or false, to represent whether you could make one square using all the + * matchsticks the little match girl has. + * + *

Example 1: Input: [1,1,2,2,2] Output: true + * + *

Explanation: You can form a square with length 2, one side of the square came two sticks with + * length 1. Example 2: Input: [3,3,3,3,4] Output: false + * + *

Explanation: You cannot find a way to form a square with all the matchsticks. Note: The length + * sum of the given matchsticks is in the range of 0 to 10^9. The length of the given matchstick + * array will not exceed 15. + * + * Solution: O(2 ^ N): Generate a power set of all combination of numbers for the given array which sum up to the + * length of a side of square. + * Now, to check if a square can be made using all the sides sticks of different length, generate a hash for for each of + * the combination which was generated in the previous step. The hash function should be such that it uses unique + * indexes of each match stick. If 4 different hash values are formed using unique and all indices then a square is + * possible. + */ +public class MatchsticksToSquare { + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[] A = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 6, 10, 10}; + System.out.println(new MatchsticksToSquare().makesquare(A)); + } + + class Pair { + int value, i; + Pair(int value, int i){ + this.value = value; + this.i = i; + } + } + + public boolean makesquare(int[] nums) { + if(nums.length == 0) return false; + int sum = 0; + for(int n : nums){ + sum += n; + } + int side = sum / 4; + if((sum % 4) != 0) return false; + List> list = powerSet(nums, side); + Set hashIndex = new HashSet<>(); + int cons = 0; + for(int i = 0; i < nums.length; i ++){ + cons |= (1 << i); + } + for(int i = 0; i < list.size(); i ++){ + for(int j = i + 1; j < list.size(); j ++){ + Set indexList = new HashSet<>(); + List list1 = list.get(i); + List list2 = list.get(j); + int hash = 0; + for(Pair l1 : list1){ + indexList.add(l1.i); + hash |= (1 << l1.i); + } + boolean allUnique = true; + for(Pair l2 : list2){ + if(indexList.contains(l2.i)) { + allUnique = false; + break; + } + indexList.add(l2.i); + hash |= (1 << l2.i); + } + if(allUnique){ + hashIndex.add(hash); + int complement = ((~ hash) & cons); + if(hashIndex.contains(complement)) return true; + } + } + } + return false; + } + + private List> powerSet(int[] nums, int expectedSum){ + List> result = new ArrayList<>(); + generate(0, nums, new ArrayList<>(), result, 0, expectedSum); + return result; + } + + private void generate(int i, int[] nums, List subList, List> result, int sum, + int expected){ + if(i >= nums.length){ + if(sum == expected){ + List pairs = new ArrayList<>(subList); + result.add(pairs); + } + } else{ + if(sum + nums[i] <= expected){ + subList.add(new Pair(nums[i], i)); + generate(i + 1, nums, subList, result, sum + nums[i], expected); + subList.remove(subList.size() - 1); + } + generate(i + 1, nums, subList, result, sum, expected); + } + } +} diff --git a/problems/src/backtracking/ZumaGame.java b/problems/src/backtracking/ZumaGame.java new file mode 100644 index 00000000..39715913 --- /dev/null +++ b/problems/src/backtracking/ZumaGame.java @@ -0,0 +1,88 @@ +package backtracking; +import java.util.*; +/** + * Created by gouthamvidyapradhan on 14/05/2019 Think about Zuma Game. You have a row of balls on + * the table, colored red(R), yellow(Y), blue(B), green(G), and white(W). You also have several + * balls in your hand. + * + *

Each time, you may choose a ball in your hand, and insert it into the row (including the + * leftmost place and rightmost place). Then, if there is a group of 3 or more balls in the same + * color touching, remove these balls. Keep doing this until no more balls can be removed. + * + *

Find the minimal balls you have to insert to remove all the balls on the table. If you cannot + * remove all the balls, output -1. + * + *

Examples: + * + *

Input: "WRRBBW", "RB" Output: -1 Explanation: WRRBBW -> WRR[R]BBW -> WBBW -> WBB[B]W -> WW + * + *

Input: "WWRRBBWW", "WRBRW" Output: 2 Explanation: WWRRBBWW -> WWRR[R]BBWW -> WWBBWW -> + * WWBB[B]WW -> WWWW -> empty + * + *

Input:"G", "GGGGG" Output: 2 Explanation: G -> G[G] -> GG[G] -> empty + * + *

Input: "RBYYBBRRB", "YRBGB" Output: 3 Explanation: RBYYBBRRB -> RBYY[Y]BBRRB -> RBBBRRB -> + * RRRB -> B -> B[B] -> BB[B] -> empty + * + *

Note: You may assume that the initial row of balls on the table won’t have any 3 or more + * consecutive balls with the same color. The number of balls on the table won't exceed 20, and the + * string represents these balls is called "board" in the input. The number of balls in your hand + * won't exceed 5, and the string represents these balls is called "hand" in the input. Both input + * strings will be non-empty and only contain characters 'R','Y','B','G','W'. + * + * Solution: Maintain a count of each colored balls. Reduce the string to a new string by removing the contiguous + * same coloured balls which exceeds the count of 3 starting from index i = 0. Each new string formed (by adding a + * new ball to a position i) makes a new state. Backtrack and traverse the search space and keep track of count of + * balls used. Maintain a minimum count variable and return that as the answer. + */ +public class ZumaGame { + public static void main(String[] args) { + System.out.println(new ZumaGame().findMinStep("BBWWRRYYRRWWBB", "Y")); + } + + Map map; + int min = Integer.MAX_VALUE; + public int findMinStep(String board, String hand) { + map = new HashMap<>(); + for(char c : hand.toCharArray()){ + map.putIfAbsent(c, 0); + map.put(c, map.get(c) + 1); + } + backtrack(board, 0); + return min == Integer.MAX_VALUE ? -1 : min; + } + + private void backtrack(String board, int total){ + if(board.isEmpty()){ + min = Math.min(min, total); + } else{ + int i = 0, j = 0; + for(int l = board.length(); i < l;){ + if(j < l && board.charAt(j) == board.charAt(i)){ + j++; + } else{ + if(j - i > 2){ + backtrack(board.substring(0, i) + ((j < l) ? board.substring(j) : ""), total); + } else{ + int a = j - i; + char c = board.charAt(i); + if(map.containsKey(c)){ + int count = map.get(c); + if(count >= (3 - a)){ + if((count - (3 - a)) == 0) { + map.remove(c); + } else{ + map.put(c, count - (3 - a)); + } + backtrack(board.substring(0, i) + ((j < l) ? board.substring(j) : ""), total + (3 - a)); + map.put(c, count); + } + } + } + i = j; + j++; + } + } + } + } +} diff --git a/problems/src/binary_search/TimeBasedKeyValuePair.java b/problems/src/binary_search/TimeBasedKeyValuePair.java new file mode 100644 index 00000000..14e7a606 --- /dev/null +++ b/problems/src/binary_search/TimeBasedKeyValuePair.java @@ -0,0 +1,82 @@ +package binary_search; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 07/05/2019 Create a timebased 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 (""). + * + *

Example 1: + * + *

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" + * + *

Example 2: + * + *

Input: inputs = ["TimeMap","set","set","get","get","get","get","get"], inputs = + * [[],["love","high",10],["love","low",20],["love",5],["love",10],["love",15],["love",20],["love",25]] + * Output: [null,null,null,"","high","high","low","low"] + * + *

Note: + * + *

All key/value strings are lowercase. All key/value strings have length in the range [1, 100] + * The timestamps for all TimeMap.set operations are strictly increasing. 1 <= timestamp <= 10^7 + * TimeMap.set and TimeMap.get functions will be called a total of 120000 times (combined) per test + * case. + * + * Solution O(log N) where N is the number of values for the same key (but different timestamp) + * Idea is to use the HashMap to store the unique key and a TreeMap as value containing all different timestamps and + * value. Use the floor function in treemap to get the value for a given timestamp. + */ +public class TimeBasedKeyValuePair { + + private Map> map; + + public TimeBasedKeyValuePair() { + map = new HashMap<>(); + } + + public void set(String key, String value, int timestamp) { + map.putIfAbsent(key, new TreeMap<>()); + TreeMap treeMap = map.get(key); + treeMap.put(timestamp, value); + } + + public String get(String key, int timestamp) { + if(!map.containsKey(key)){ + return ""; + }else { + TreeMap treeMap = map.get(key); + Map.Entry entry = treeMap.floorEntry(timestamp); + if(entry == null){ + return ""; + } else{ + return entry.getValue(); + } + } + } + + public static void main(String[] args) { + TimeBasedKeyValuePair task = new TimeBasedKeyValuePair(); + task.set("foo", "bar", 1); + System.out.println(task.get("foo", 1)); + System.out.println(task.get("foo", 3)); + System.out.println(task.get("foo", 0)); + task.set("foo", "bar2", 4); + System.out.println(task.get("foo", 3)); + System.out.println(task.get("foo", 4)); + System.out.println(task.get("foo", 5)); + } +} diff --git a/problems/src/bit_manipulation/BinaryNumberWithAlternatingBits.java b/problems/src/bit_manipulation/BinaryNumberWithAlternatingBits.java new file mode 100644 index 00000000..e3fe3e4c --- /dev/null +++ b/problems/src/bit_manipulation/BinaryNumberWithAlternatingBits.java @@ -0,0 +1,32 @@ +package bit_manipulation; +/** + * Created by gouthamvidyapradhan on 28/05/2019\ Given a positive integer, check whether it has + * alternating bits: namely, if two adjacent bits will always have different values. + * + *

Example 1: Input: 5 Output: True Explanation: The binary representation of 5 is: 101 Example + * 2: Input: 7 Output: False Explanation: The binary representation of 7 is: 111. Example 3: Input: + * 11 Output: False Explanation: The binary representation of 11 is: 1011. Example 4: Input: 10 + * Output: True Explanation: The binary representation of 10 is: 1010. + */ +public class BinaryNumberWithAlternatingBits { + public static void main(String[] args) { + System.out.println(new BinaryNumberWithAlternatingBits().hasAlternatingBits(18)); + } + + public boolean hasAlternatingBits(int n) { + int curr = n & 1; + int pos = 0; + for(int i = 0; i < 32; i++){ + if((n & (1 << i)) > 0){ + pos = i; + } + } + + for(int i = 1; i <= pos; i++){ + int temp = (1 << i) & n; + if((temp > 0 && curr > 0) || (temp == 0 && curr == 0)) return false; + curr = temp; + } + return true; + } +} diff --git a/problems/src/depth_first_search/MaxAreaOfIsland.java b/problems/src/depth_first_search/MaxAreaOfIsland.java new file mode 100644 index 00000000..2148e075 --- /dev/null +++ b/problems/src/depth_first_search/MaxAreaOfIsland.java @@ -0,0 +1,71 @@ +package depth_first_search; + +/** + * Created by gouthamvidyapradhan on 28/05/2019 + * Given a non-empty 2D array grid of 0's and 1's, an + * island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) + * You may assume all four edges of the grid are surrounded by water. + * + *

Find the maximum area of an island in the given 2D array. (If there is no island, the maximum + * area is 0.) + * + *

Example 1: + * + *

[[0,0,1,0,0,0,0,1,0,0,0,0,0], [0,0,0,0,0,0,0,1,1,1,0,0,0], [0,1,1,0,1,0,0,0,0,0,0,0,0], + * [0,1,0,0,1,1,0,0,1,0,1,0,0], [0,1,0,0,1,1,0,0,1,1,1,0,0], [0,0,0,0,0,0,0,0,0,0,1,0,0], + * [0,0,0,0,0,0,0,1,1,1,0,0,0], [0,0,0,0,0,0,0,1,1,0,0,0,0]] Given the above grid, return 6. Note + * the answer is not 11, because the island must be connected 4-directionally. Example 2: + * + *

[[0,0,0,0,0,0,0,0]] Given the above grid, return 0. Note: The length of each dimension in the + * given grid does not exceed 50. + * + * Solution: O(N x M) Do a dfs and keep track of max connected 1's + */ +public class MaxAreaOfIsland { + final int[] R = {0, 0, -1, 1}; + final int[] C = {1, -1, 0, 0}; + + int count = 0; + int max = 0; + boolean[][] done; + public static void main(String[] args) { + int[][] grid = {{0,0,1,0,0,0,0,1,0,0,0,0,0}, + {0,0,0,0,0,0,0,1,1,1,0,0,0}, + {0,1,1,0,1,0,0,0,0,0,0,0,0}, + {0,1,0,0,1,1,0,0,1,0,1,0,0}, + {0,1,0,0,1,1,0,0,1,1,1,0,0}, + {0,0,0,0,0,0,0,0,0,0,1,0,0}, + {0,0,0,0,0,0,0,1,1,1,0,0,0}, + {0,0,0,0,0,0,0,1,1,0,0,0,0}}; + + System.out.println(new MaxAreaOfIsland().maxAreaOfIsland(grid)); + } + + + public int maxAreaOfIsland(int[][] grid) { + done = new boolean[grid.length][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 && !done[i][j]){ + count = 0; + dfs(grid, i, j); + max = Math.max(max, count); + } + } + } + return max; + } + + private void dfs(int[][] grid, int r, int c){ + done[r][c] = true; + count++; + for(int i = 0; i < 4; i++){ + int newR = r + R[i]; + int newC = c + C[i]; + if(newR >= 0 && newC >= 0 && newR < grid.length && newC < grid[0].length && !done[newR][newC] && grid[newR][newC] == 1){ + dfs(grid, newR, newC); + } + } + } + +} diff --git a/problems/src/divide_and_conquer/TwentyFourGame.java b/problems/src/divide_and_conquer/TwentyFourGame.java new file mode 100644 index 00000000..867d54d3 --- /dev/null +++ b/problems/src/divide_and_conquer/TwentyFourGame.java @@ -0,0 +1,109 @@ +package divide_and_conquer; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 18/05/2019 You have 4 cards each containing a number from 1 to + * 9. You need to judge whether they could operated through *, /, +, -, (, ) to get the value of 24. + * + *

Example 1: Input: [4, 1, 8, 7] Output: True Explanation: (8-4) * (7-1) = 24 Example 2: Input: + * [1, 2, 1, 2] Output: False Note: The division operator / represents real division, not integer + * division. For example, 4 / (1 - 2/3) = 12. Every operation done is between two numbers. In + * particular, we cannot use - as a unary operator. For example, with [1, 1, 1, 1] as input, the + * expression -1 - 1 - 1 - 1 is not allowed. You cannot concatenate numbers together. For example, + * if the input is [1, 2, 1, 2], we cannot write this as 12 + 12. + * + * Solution O(1) Generate all permutation of a given 4 digit number and for each permutation split the number into + * two parts with left and right (at various possible split points). Now perform all possible operations(+, -, * and /) + * for each left and right and check if any of the operation results in 24 + */ +public class TwentyFourGame { + + public static void main(String[] args) { + int[] A = {4, 7, 7, 7}; + System.out.println(new TwentyFourGame().judgePoint24(A)); + } + + class Fraction{ + int n, d; + Fraction(int n, int d){ + this.n = n; + this.d = d; + } + } + + public boolean judgePoint24(int[] nums) { + List result = new ArrayList<>(); + permute(0, nums, result); + for(int[] A : result){ + List list = generate(0, 3, A); + for(Fraction f : list){ + if((f.d != 0) &&(f.n / f.d) == 24 && (f.n % f.d) == 0) return true; + } + } + return false; + } + + private void permute(int i, int[] nums, List result){ + if(i >= nums.length) { + result.add(Arrays.copyOf(nums, 4)); + } else{ + for(int j = i; j < nums.length; j ++){ + swap(i, j, nums); + permute(i + 1, nums, result); + swap(i, j, nums); + } + } + } + + private void swap(int i, int j, int[] nums){ + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } + + private List generate(int l, int r, int[] nums){ + if(l > r){ + return new ArrayList<>(); + } else if(l == r){ + return Arrays.asList(new Fraction(nums[l], 1)); + } else{ + List result = new ArrayList<>(); + for(int i = l; i < r; i ++){ + for(int j = l; j <= i; j ++){ + List left = generate(l, j, nums); + List right = generate(j + 1, r, nums); + if(right.isEmpty()){ + result.addAll(left); + } else if(left.isEmpty()){ + result.addAll(right); + } else{ + for(Fraction lF : left){ + for(Fraction rF : right){ + int n = (lF.n * rF.d + rF.n * lF.d); + int d = (lF.d * rF.d); + Fraction sum = new Fraction(n, d); + + n = (lF.n * rF.d - (rF.n * lF.d)); + d = (lF.d * rF.d); + Fraction diff = new Fraction(n, d); + + n = (lF.n * rF.n); + d = (lF.d * rF.d); + Fraction prod = new Fraction(n, d); + + n = (lF.n * rF.d); + d = (lF.d * rF.n); + Fraction div = new Fraction(n, d); + result.add(sum); + result.add(diff); + result.add(prod); + result.add(div); + } + } + } + } + } + return result; + } + } +} diff --git a/problems/src/dynamic_programming/MinimumCostForTickets.java b/problems/src/dynamic_programming/MinimumCostForTickets.java new file mode 100644 index 00000000..daa77c4e --- /dev/null +++ b/problems/src/dynamic_programming/MinimumCostForTickets.java @@ -0,0 +1,84 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 05/05/2019 In a country popular for train travel, you have + * planned some train travelling one year in advance. The days of the year that you will travel is + * given as an array days. Each day is an integer from 1 to 365. + * + *

Train tickets are sold in 3 different ways: + * + *

a 1-day pass is sold for costs[0] dollars; a 7-day pass is sold for costs[1] dollars; a 30-day + * pass is sold for costs[2] dollars. The passes allow that many days of consecutive travel. For + * example, if we get a 7-day pass on day 2, then we can travel for 7 days: day 2, 3, 4, 5, 6, 7, + * and 8. + * + *

Return the minimum number of dollars you need to travel every day in the given list of days. + * + *

Example 1: + * + *

Input: days = [1,4,6,7,8,20], costs = [2,7,15] Output: 11 Explanation: For example, here is + * one way to buy passes that lets you travel your travel plan: On day 1, you bought a 1-day pass + * for costs[0] = $2, which covered day 1. On day 3, you bought a 7-day pass for costs[1] = $7, + * which covered days 3, 4, ..., 9. On day 20, you bought a 1-day pass for costs[0] = $2, which + * covered day 20. In total you spent $11 and covered all the days of your travel. Example 2: + * + *

Input: days = [1,2,3,4,5,6,7,8,9,10,30,31], costs = [2,7,15] Output: 17 Explanation: For + * example, here is one way to buy passes that lets you travel your travel plan: On day 1, you + * bought a 30-day pass for costs[2] = $15 which covered days 1, 2, ..., 30. On day 31, you bought a + * 1-day pass for costs[0] = $2 which covered day 31. In total you spent $17 and covered all the + * days of your travel. + * + *

Note: + * + *

1 <= days.length <= 365 1 <= days[i] <= 365 days is in strictly increasing order. costs.length + * == 3 1 <= costs[i] <= 1000 + + Solution: O(N ^ 2 x 3) + */ +public class MinimumCostForTickets { + + public static void main(String[] args) { + int[] days = {1,2,3,4,5,6,7,8,9,10,30,31}; + int[] costs = {2, 7, 15}; + System.out.println(new MinimumCostForTickets().mincostTickets(days, costs)); + } + /** + * Main method + * + * @param days + * @param costs + * @return + */ + public int mincostTickets(int[] days, int[] costs) { + int[] min = new int[days.length]; + Arrays.fill(min, Integer.MAX_VALUE); + for (int i = days.length - 1; i >= 0; i--) { + for (int j = 0; j < costs.length; j++) { + if (j == 0) { + min[i] = Math.min(min[i], costs[j] + ((i + 1 >= min.length) ? 0 : min[i + 1])); + } else if (j == 1) { + int c = 0; + for (int k = i + 1; k < days.length; k++) { + if (days[k] >= (days[i] + 7)) { + c = min[k]; + break; + } + } + min[i] = Math.min(min[i], costs[j] + c); + } else { + int c = 0; + for (int k = i + 1; k < days.length; k++) { + if (days[k] >= (days[i] + 30)) { + c = min[k]; + break; + } + } + min[i] = Math.min(min[i], costs[j] + c); + } + } + } + return min[0]; + } +} diff --git a/problems/src/dynamic_programming/OutOfBoundaryPaths.java b/problems/src/dynamic_programming/OutOfBoundaryPaths.java new file mode 100644 index 00000000..ee0201d0 --- /dev/null +++ b/problems/src/dynamic_programming/OutOfBoundaryPaths.java @@ -0,0 +1,47 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 15/05/2019 + * There is an m by n grid with a ball. Given the start coordinate (i,j) of the ball, you can move the ball to + * adjacent cell or cross the grid boundary in four directions (up, down, left, right). However, you can at most move + * N times. Find out the number of paths to move the ball out of grid boundary. The answer may be very large, return + * it after mod 10 ^ 9 + 7. + * + * Solution: O(m x n x N x 4) Move in all possible directions from the starting position (i, j) and keep track of + * distance traversed and ensure the distance traversed does not exceed N. Keep the count of number of possibilities + * to go out of the boundary for each cell reached. Return the sum in cell (a, b) + */ +public class OutOfBoundaryPaths { + + final int[] R = {1, -1, 0, 0}; + final int[] C = {0, 0, 1, -1}; + int[][][] DP; + int mod = 1000000007; + public static void main(String[] args) { + System.out.println(new OutOfBoundaryPaths().findPaths(2, 2, 2, 0, 0)); + } + + public int findPaths(int m, int n, int N, int a, int b) { + if(N == 0) return 0; + DP = new int[m][n][N + 1]; + + for(int k = 1; k <= N; k++){ + for(int i = 0; i < m; i ++){ + for(int j = 0; j < n; j ++){ + for(int p = 0; p < 4; p++){ + int newR = i + R[p]; + int newC = j + C[p]; + if(newR < 0 || newC < 0 || newR >= m || newC >= n){ + DP[i][j][k] = ((DP[i][j][k] + 1) % mod); + } else{ + DP[i][j][k] = (((DP[i][j][k] + DP[newR][newC][k - 1])) % mod); + } + } + } + } + } + + return DP[a][b][N]; + } + +} diff --git a/problems/src/dynamic_programming/RemoveBoxes.java b/problems/src/dynamic_programming/RemoveBoxes.java new file mode 100644 index 00000000..7d63b12f --- /dev/null +++ b/problems/src/dynamic_programming/RemoveBoxes.java @@ -0,0 +1,43 @@ +package dynamic_programming; +/** + * Created by gouthamvidyapradhan on 28/05/2019 Given several boxes with different colors + * represented by different positive numbers. You may experience several rounds to remove boxes + * until there is no box left. Each time you can choose some continuous boxes with the same color + * (composed of k boxes, k >= 1), remove them and get k*k points. Find the maximum points you can + * get. + * + *

Example 1: Input: + * + *

[1, 3, 2, 2, 2, 3, 4, 3, 1] Output: 23 Explanation: [1, 3, 2, 2, 2, 3, 4, 3, 1] ----> [1, 3, + * 3, 4, 3, 1] (3*3=9 points) ----> [1, 3, 3, 3, 1] (1*1=1 points) ----> [1, 1] (3*3=9 points) ----> + * [] (2*2=4 points) Note: The number of boxes n would not exceed 100. + */ +public class RemoveBoxes { + + int[][][] dp; + public static void main(String[] args) { + int[] boxes = {3, 3, 3}; + System.out.println(new RemoveBoxes().removeBoxes(boxes)); + } + + public int removeBoxes(int[] boxes) { + dp = new int[boxes.length][boxes.length][boxes.length + 1]; + return calculate(0, boxes.length - 1, 1, boxes); + } + + int calculate(int l, int r, int rep, int[] boxes){ + if(l == r) return rep * rep; + else if(l > r) return 0; + else if(dp[l][r][rep] != 0) return dp[l][r][rep]; + else{ + dp[l][r][rep] = calculate(l, r - 1, 1, boxes) + (rep * rep); + for(int i = l; i < r; i ++){ + if(boxes[i] == boxes[r]){ + dp[l][r][rep] = Math.max(dp[l][r][rep], + calculate(l, i, rep + 1, boxes) + calculate(i + 1, r - 1, 1, boxes)); + } + } + return dp[l][r][rep]; + } + } +} diff --git a/problems/src/dynamic_programming/RussianDollEnvelopes.java b/problems/src/dynamic_programming/RussianDollEnvelopes.java new file mode 100644 index 00000000..cb90f274 --- /dev/null +++ b/problems/src/dynamic_programming/RussianDollEnvelopes.java @@ -0,0 +1,70 @@ +package dynamic_programming; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 05/05/2019 You have a number of envelopes with widths and + * heights given as a pair of integers (w, h). One envelope can fit into another if and only if both + * the width and height of one envelope is greater than the width and height of the other envelope. + * + *

What is the maximum number of envelopes can you Russian doll? (put one inside other) + * + *

Note: Rotation is not allowed. + * + *

Example: + * + *

Input: [[5,4],[6,4],[6,7],[2,3]] Output: 3 Explanation: The maximum number of envelopes you + * can Russian doll is 3 ([2,3] => [5,4] => [6,7]). + * + * Solution: O(N ^ 2) + * Sort the envelopes based on increasing order of area and for each envelope iterate through all the possible + * envelopes which are smaller than that the current envelope and check the maximum possible + * envelopes which an be russian dolled. + */ +public class RussianDollEnvelopes { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[][] A = {{5,4}, {6,4}, {6,7}, {2,3}}; + System.out.println(new RussianDollEnvelopes().maxEnvelopes(A)); + } + + class Envelope{ + int l, b; + Envelope(int l, int b){ + this.l = l; + this.b = b; + } + } + /** + * + * @param envelopes + * @return + */ + public int maxEnvelopes(int[][] envelopes) { + if(envelopes.length == 0) return 0; + List list = new ArrayList<>(); + for(int[] row : envelopes){ + list.add(new Envelope(row[0], row[1])); + } + list.sort(((o1, o2) -> Integer.compare(o2.l * o2.b, o1.l * o1.b))); + int[] DP = new int[envelopes.length]; + Arrays.fill(DP, 1); + for(int i = list.size() - 1; i >= 0; i --){ + Envelope env = list.get(i); + for(int j = i + 1, l = list.size(); j < l; j ++){ + Envelope childEnv = list.get(j); + if(env.l > childEnv.l && env.b > childEnv.b){ + DP[i] = Math.max(DP[i], DP[j] + 1); + } + } + } + int ans = 1; + for(int i : DP){ + ans = Math.max(ans, i); + } + return ans; + } +} diff --git a/problems/src/greedy/BoatsToSavePeople.java b/problems/src/greedy/BoatsToSavePeople.java new file mode 100644 index 00000000..9b99a7af --- /dev/null +++ b/problems/src/greedy/BoatsToSavePeople.java @@ -0,0 +1,65 @@ +package greedy; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 09/05/2019 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.) + * + *

Example 1: + * + *

Input: people = [1,2], limit = 3 Output: 1 Explanation: 1 boat (1, 2) Example 2: + * + *

Input: people = [3,2,2,1], limit = 3 Output: 3 Explanation: 3 boats (1, 2), (2) and (3) + * Example 3: + * + *

Input: people = [3,5,3,4], limit = 5 Output: 4 Explanation: 4 boats (3), (3), (4), (5) Note: + * + *

1 <= people.length <= 50000 1 <= people[i] <= limit <= 30000 + * + * Solution O N log N + * Simple strategy is to greedy try to put in maximum possible people in a boat and increment the boat counter. Use + * TreeMap and sorting to achieve this easily + */ +public class BoatsToSavePeople { + public static void main(String[] args) { + int[] A = {3, 5, 3, 4}; + System.out.println(new BoatsToSavePeople().numRescueBoats(A, 8)); + } + + public int numRescueBoats(int[] people, int limit) { + TreeMap treeMap = new TreeMap<>(); + int boats = 0; + for(int p : people){ + treeMap.putIfAbsent(p, 0); + treeMap.put(p, treeMap.get(p) + 1); + } + Arrays.sort(people); + for(int p : people){ + if(treeMap.containsKey(p)){ + int count = treeMap.remove(p); + --count; + if(count != 0){ + treeMap.put(p, count); + } + int balance = limit - p; + Map.Entry floor = treeMap.floorEntry(balance); + if(floor != null){ + int c = floor.getValue(); + --c; + treeMap.remove(floor.getKey()); + if(c != 0){ + treeMap.put(floor.getKey(), c); + } + } + boats++; + } + } + return boats; + } +} diff --git a/problems/src/greedy/StringWithout3A3B.java b/problems/src/greedy/StringWithout3A3B.java new file mode 100644 index 00000000..d44ecafb --- /dev/null +++ b/problems/src/greedy/StringWithout3A3B.java @@ -0,0 +1,63 @@ +package greedy; + +/** + * Created by gouthamvidyapradhan on 07/05/2019 + * + *

Given two integers A and B, return any string S such that: + * + *

S has length A + B and contains exactly A 'a' letters, and exactly B 'b' letters; The + * substring 'aaa' does not occur in S; The substring 'bbb' does not occur in S. + * + *

Example 1: + * + *

Input: A = 1, B = 2 Output: "abb" Explanation: "abb", "bab" and "bba" are all correct answers. + * Example 2: + * + *

Input: A = 4, B = 1 Output: "aabaa" + * + * Solution O(N) idea is to greedily try to put two a's if number of a's is > b and + * similarly for b + * + */ +public class StringWithout3A3B { + + public static void main(String[] args) { + System.out.println(new StringWithout3A3B().strWithout3a3b(4, 1)); + } + + public String strWithout3a3b(int A, int B) { + StringBuilder sb = new StringBuilder(); + while(A > 0 || B > 0){ + if(A > B && A > 1 && B > 0){ + sb.append("a").append("a"); + sb.append("b"); + A -= 2; + B -= 1; + } + else if(B > A && B > 1 && A > 0){ + sb.append("b").append("b"); + sb.append("a"); + B -= 2; + A -= 1; + } else{ + if(A > B && A > 1){ + sb.append("a"); + sb.append("a"); + A -= 2; + } else if(A > B && A > 0){ + sb.append("a"); + A -= 1; + } else if(B > A && B > 1){ + sb.append("b"); + sb.append("b"); + B -= 2; + } else { + sb.append("b"); + B -= 1; + } + } + } + return sb.toString(); + } + +} diff --git a/problems/src/heap/ReachableNodesInSubdividedGraph.java b/problems/src/heap/ReachableNodesInSubdividedGraph.java new file mode 100644 index 00000000..5fbfe0b8 --- /dev/null +++ b/problems/src/heap/ReachableNodesInSubdividedGraph.java @@ -0,0 +1,111 @@ +package heap; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 07/05/2019 Starting with an undirected graph (the "original + * graph") with nodes from 0 to N-1, subdivisions are made to some of the edges. + * + *

The graph is given as follows: edges[k] is a list of integer pairs (i, j, n) such that (i, j) + * is an edge of the original graph, + * + *

and n is the total number of new nodes on that edge. + * + *

Then, the edge (i, j) is deleted from the original graph, n new nodes (x_1, x_2, ..., x_n) are + * added to the original graph, + * + *

and n+1 new edges (i, x_1), (x_1, x_2), (x_2, x_3), ..., (x_{n-1}, x_n), (x_n, j) are added to + * the original graph. + * + *

Now, you start at node 0 from the original graph, and in each move, you travel along one edge. + * + *

Return how many nodes you can reach in at most M moves. + * + *

Example 1: + * + *

Input: edges = [[0,1,10],[0,2,1],[1,2,2]], M = 6, N = 3 Output: 13 Explanation: The nodes that + * are reachable in the final graph after M = 6 moves are indicated below. + * + *

Example 2: + * + *

Input: edges = [[0,1,4],[1,2,6],[0,2,8],[1,3,1]], M = 10, N = 4 Output: 23 + * + *

Note: + * + *

0 <= edges.length <= 10000 0 <= edges[i][0] < edges[i][1] < N There does not exist any i != j + * for which edges[i][0] == edges[j][0] and edges[i][1] == edges[j][1]. The original graph has no + * parallel edges. 0 <= edges[i][2] <= 10000 0 <= M <= 10^9 1 <= N <= 3000 A reachable node is a + * node that can be travelled to using at most M moves starting from node 0. + * + * Solution: O(E log N) E is the length of edges and N is the number of nodes. The n nodes on a edge form a weight + * and thus the graph becomes a weighted graph. Keep track of number of moves available and run a Dijkstra's algorithm. + */ +public class ReachableNodesInSubdividedGraph { + + /** + * Main method + * @param args + */ + public static void main(String[] args) { + int[][] edges = {{0,1,1000}, {0,2,1}, {1,2,1}}; + System.out.println(new ReachableNodesInSubdividedGraph().reachableNodes(edges, 200, 3)); + } + + + static class Node{ + int n, w; + Node(int n, int w){ + this.n = n; + this.w = w; + } + } + + public int reachableNodes(int[][] edges, int M, int N) { + Map> graph = new HashMap<>(); + for(int[] e : edges){ + graph.putIfAbsent(e[0], new ArrayList<>()); + graph.get(e[0]).add(new Node(e[1], e[2] + 1)); + + graph.putIfAbsent(e[1], new ArrayList<>()); + graph.get(e[1]).add(new Node(e[0], e[2] + 1)); + } + + PriorityQueue pq = new PriorityQueue<>(Comparator.comparingInt(o -> o.w)); + Map distance = new HashMap<>(); + int count = 0; + pq.offer(new Node(0, 0)); + while(!pq.isEmpty()){ + Node curr = pq.poll(); + if(!distance.containsKey(curr.n)){ + count += 1; + distance.put(curr.n, curr.w); + List children = graph.get(curr.n); + if(children != null){ + for(Node c : children){ + if(!distance.containsKey(c.n)){ + int availableMoves = M - curr.w; + int nodesInBetween = c.w - 1; + if(nodesInBetween >= availableMoves){ + count += availableMoves; + } else{ + count += nodesInBetween; + if(availableMoves >= c.w){ + Node child = new Node(c.n, distance.get(curr.n) + c.w); + pq.offer(child); + } + } + } else{ + int childAvailableMoves = M - distance.get(c.n); + int nodesInBetween = c.w - 1; + int unvisitedNodes = nodesInBetween - childAvailableMoves; + if(unvisitedNodes > 0){ + int availableMovesForCurr = M - distance.get(curr.n); + count += (unvisitedNodes >= availableMovesForCurr ? availableMovesForCurr : unvisitedNodes); + } + } + } + } + } + } + return count; + } +} diff --git a/problems/src/math/ProjectionAreaOf3DShapes.java b/problems/src/math/ProjectionAreaOf3DShapes.java new file mode 100644 index 00000000..c176d0f3 --- /dev/null +++ b/problems/src/math/ProjectionAreaOf3DShapes.java @@ -0,0 +1,74 @@ +package math; +/** + * Created by gouthamvidyapradhan on 09/05/2019 + * + *

On a N * N grid, we place some 1 * 1 * 1 cubes that are axis-aligned with the x, y, and z + * axes. + * + *

Each value v = grid[i][j] represents a tower of v cubes placed on top of grid cell (i, j). + * + *

Now we view the projection of these cubes onto the xy, yz, and zx planes. + * + *

A projection is like a shadow, that maps our 3 dimensional figure to a 2 dimensional plane. + * + *

Here, we are viewing the "shadow" when looking at the cubes from the top, the front, and the + * side. + * + *

Return the total area of all three projections. + * + *

Example 1: + * + *

Input: [[2]] Output: 5 Example 2: + * + *

Input: [[1,2],[3,4]] Output: 17 Explanation: Here are the three projections ("shadows") of the + * shape made with each axis-aligned plane. + * + *

Example 3: + * + *

Input: [[1,0],[0,2]] Output: 8 Example 4: + * + *

Input: [[1,1,1],[1,0,1],[1,1,1]] Output: 14 Example 5: + * + *

Input: [[2,2,2],[2,1,2],[2,2,2]] Output: 21 + * + *

Note: + * + *

1 <= grid.length = grid[0].length <= 50 0 <= grid[i][j] <= 50 + * + * Solution O(N x N) project the view on all three different planes. For top view its pretty + * simple because area of each cube is just 1 * 1, for all other planes take the maximum value of each + * grid. Sum up values on each planes + * + */ +public class ProjectionAreaOf3DShapes { + public static void main(String[] args) { + // + } + + public int projectionArea(int[][] grid) { + int area = 0; + for(int i = 0; i < grid.length; i ++){ + for(int j = 0; j < grid.length; j ++){ + area += (grid[i][j] > 0 ? 1 : 0); + } + } + + for(int i = 0; i < grid.length; i ++){ + int max = 0; + for(int j = 0; j < grid[0].length; j ++){ + max = Math.max(max, grid[i][j]); + } + area += max; + } + + for(int i = 0; i < grid[0].length; i ++){ + int max = 0; + for(int j = 0; j < grid.length; j ++){ + max = Math.max(max, grid[j][i]); + } + area += max; + } + + return area; + } +} diff --git a/problems/src/stack/DecodedStringAtIndex.java b/problems/src/stack/DecodedStringAtIndex.java new file mode 100644 index 00000000..bc94dcf0 --- /dev/null +++ b/problems/src/stack/DecodedStringAtIndex.java @@ -0,0 +1,68 @@ +package stack; + +import java.util.Stack; + +/** + * Created by gouthamvidyapradhan on 12/05/2019 + */ +public class DecodedStringAtIndex { + + public static void main(String[] args) { + System.out.println(new DecodedStringAtIndex().decodeAtIndex("ha22", 5)); + } + + class Node{ + String S; + long count; + int multiple; + Node(String S, long count, int multiple){ + this.S = S; + this.count = count; + this.multiple = multiple; + } + } + + public String decodeAtIndex(String S, int K) { + Stack stack = new Stack<>(); + StringBuilder sb = new StringBuilder(); + char prev = ' '; + for(char c : S.toCharArray()){ + if(Character.isDigit(c)){ + String currStr = sb.toString(); + long len = 0L; + if(!stack.isEmpty()){ + len = stack.peek().count * stack.peek().multiple; + } + stack.push(new Node(currStr, len + (currStr.length()), Integer.parseInt(String.valueOf(c)))); + if(((len + (currStr.length())) * Integer.parseInt(String.valueOf(c))) >= K){ + break; + } + prev = c; + } else{ + if(Character.isDigit(prev)){ + sb = new StringBuilder(); + } + sb.append(c); + prev = c; + } + } + while(!stack.isEmpty()){ + Node top = stack.peek(); + long l = top.count; + if(K <= l){ + return String.valueOf(top.S.charAt((int)l - K - 1)); + } + long mod = (K % l); + if(mod == 0){ + return String.valueOf(top.S.charAt(top.S.length() - 1)); + } + if(l - top.S.length() < mod){ + long i = l - mod; + return String.valueOf(top.S.charAt(top.S.length() - (int)i - 1)); + } else{ + stack.pop(); + } + } + return ""; + } +} diff --git a/problems/src/stack/StudentAttendanceRecordII.java b/problems/src/stack/StudentAttendanceRecordII.java new file mode 100644 index 00000000..a482bfbb --- /dev/null +++ b/problems/src/stack/StudentAttendanceRecordII.java @@ -0,0 +1,51 @@ +package stack; + +/** + * Created by gouthamvidyapradhan on 10/05/2019 Given a positive integer n, return the number of all + * possible attendance records with length n, which will be regarded as rewardable. The answer may + * be very large, return it after mod 109 + 7. + * + *

A student attendance record is a string that only contains the following three characters: + * + *

'A' : Absent. 'L' : Late. 'P' : Present. A record is regarded as rewardable if it doesn't + * contain more than one 'A' (absent) or more than two continuous 'L' (late). + * + *

Example 1: Input: n = 2 Output: 8 Explanation: There are 8 records with length 2 will be + * regarded as rewardable: "PP" , "AP", "PA", "LP", "PL", "AL", "LA", "LL" Only "AA" won't be + * regarded as rewardable owing to more than one absent times. Note: The value of n won't exceed + * 100,000. + * + * Solution O(N): Start with a base case for a single days attendance record which is 'A', 'P' and 'L' so, in total + * there are three possible records. Now, keep adding a new possible attendance record to all the above three + * possibilities. Now, since we cannot have a combination such as 'AA' we can maintain a variable with count of + * combinations which already has one 'A' in it and similarly maintain a combination which already has two 'L's it it, + * only one 'L' and only 'P' in it - keep incrementing the count of each of the variables when a new combination + * belongs to any one of this. Continue upto n and sum up the all the variables and return the answer % 10 ^ 9 + 7 + */ +public class StudentAttendanceRecordII { + public static void main(String[] args) { + System.out.println(new StudentAttendanceRecordII().checkRecord(5)); + } + int mod = 1000000007; + public int checkRecord(int n) { + if(n == 0) return 1; + int P = 1; int A = 1; + int LA = 0, LX = 1, LLA = 0, LLX = 0; + for(int i = n - 1; i > 0; i --){ + int temP = (((P + LX) % mod) + LLX) % mod; + int tempLX = P; + int tempLA = A; + int tempLLX = LX; + int tempLLA = LA; + int tempA = ((((((((((P + LX) % mod) + LLX) % mod) + A) % mod) + LA) % mod) + LLA) % mod); //A + LA + LLA + // is because we can add P to each of these forming PA, PLA and PLLA + P = temP; + LX = tempLX; + LA = tempLA; + LLX = tempLLX; + LLA = tempLLA; + A = tempA; + } + return ((((((((((P + LX) % mod) + LA) % mod) + LLX) % mod) + LLA) % mod) + A) % mod); + } +} diff --git a/problems/src/string/ReconstructOriginalDigitsFromEnglish.java b/problems/src/string/ReconstructOriginalDigitsFromEnglish.java new file mode 100644 index 00000000..a1643628 --- /dev/null +++ b/problems/src/string/ReconstructOriginalDigitsFromEnglish.java @@ -0,0 +1,87 @@ +package string; +import java.util.*; +/** + * Created by gouthamvidyapradhan on 04/06/2019 Given a non-empty string containing an out-of-order + * English representation of digits 0-9, output the digits in ascending order. + * + *

Note: Input contains only lowercase English letters. Input is guaranteed to be valid and can + * be transformed to its original digits. That means invalid inputs such as "abc" or "zerone" are + * not permitted. Input length is less than 50,000. Example 1: Input: "owoztneoer" + * + *

Output: "012" Example 2: Input: "fviefuro" + * + *

Output: "45" + * + * Solution: O(N) General idea is to note some unique characters in english representation of a digit such as 'x' + * 'x' can occur only in digit 6, similarly for 'z' it can occur only for digit 0 and likewise. Keep a character + * frequency hashmap and decrement the count as and when a new digit is formed. Sort the digits and return a + * concatenated string. + */ +public class ReconstructOriginalDigitsFromEnglish { + public static void main(String[] args) { + System.out.println(new ReconstructOriginalDigitsFromEnglish().originalDigits("fviefurofviefurofviefurofviefurofviefurofviefurofviefurofviefurofviefurofviefuro")); + } + + public String originalDigits(String s) { + Map map = new HashMap<>(); + for(char c : s.toCharArray()){ + map.putIfAbsent(c, 0); + map.put(c, map.get(c) + 1); + } + Map intMap = new HashMap<>(); + if(map.containsKey('x')){ + update(map, intMap, 6, 'x', Arrays.asList('s', 'i', 'x')); + } + if(map.containsKey('g')){ + update(map, intMap, 8, 'g', Arrays.asList('e', 'i', 'g', 'h', 't')); + } + if(map.containsKey('w')){ + update(map, intMap, 2, 'w', Arrays.asList('t', 'w', 'o')); + } + if(map.containsKey('z')){ + update(map, intMap, 0, 'z', Arrays.asList('z', 'e', 'r', 'o')); + } + if(map.containsKey('u')){ + update(map, intMap, 4, 'u', Arrays.asList('f', 'o', 'u', 'r')); + } + if(map.containsKey('f')){ + update(map, intMap, 5, 'f', Arrays.asList('f', 'i', 'v', 'e')); + } + if(map.containsKey('v')){ + update(map, intMap, 7, 'v', Arrays.asList('s', 'e', 'v', 'e', 'n')); + } + if(map.containsKey('i')){ + update(map, intMap, 9, 'i', Arrays.asList('n', 'i', 'n', 'e')); + } + if(map.containsKey('t')){ + update(map, intMap, 3, 't', Arrays.asList('t', 'h', 'r', 'e', 'e')); + } + if(map.containsKey('o')){ + update(map, intMap, 1, 'o', Arrays.asList('o', 'n', 'e')); + } + Set keys = intMap.keySet(); + List list = new ArrayList<>(keys); + list.sort(Comparator.comparingInt(o -> o)); + StringBuilder sb = new StringBuilder(); + for(int i : list){ + int count = intMap.get(i); + while(count-- > 0){ + sb.append(i); + } + } + return sb.toString(); + } + + private void update(Map map, Map intMap, int num, char id, + List list) { + if(map.containsKey(id)){ + int count = map.get(id); + intMap.put(num, count); + while(count-- > 0){ + for(char c : list){ + map.put(c, map.get(c) - 1); + } + } + } + } +} diff --git a/problems/src/string/SplitConcatenatedStrings.java b/problems/src/string/SplitConcatenatedStrings.java new file mode 100644 index 00000000..b6ef5955 --- /dev/null +++ b/problems/src/string/SplitConcatenatedStrings.java @@ -0,0 +1,67 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 10/05/2019 Given a list of strings, you could concatenate these + * strings together into a loop, where for each string you could choose to reverse it or not. Among + * all the possible loops, you need to find the lexicographically biggest string after cutting the + * loop, which will make the looped string into a regular one. + * + *

Specifically, to find the lexicographically biggest string, you need to experience two phases: + * + *

Concatenate all the strings into a loop, where you can reverse some strings or not and connect + * them in the same order as given. Cut and make one breakpoint in any place of the loop, which will + * make the looped string into a regular one starting from the character at the cutpoint. And your + * job is to find the lexicographically biggest one among all the possible regular strings. + * + *

Example: Input: "abc", "xyz" Output: "zyxcba" Explanation: You can get the looped string + * "-abcxyz-", "-abczyx-", "-cbaxyz-", "-cbazyx-", where '-' represents the looped status. The + * answer string came from the fourth looped one, where you could cut from the middle character 'a' + * and get "zyxcba". Note: The input strings will only contain lowercase letters. The total length + * of all the strings will not over 1,000. + * + */ +public class SplitConcatenatedStrings { + public static void main(String[] args) { + String[] A = {"abc"}; + System.out.println(new SplitConcatenatedStrings().splitLoopedString(A)); + } + + public String splitLoopedString(String[] strs) { + String max = ""; + for(int i = 0; i < strs.length; i ++){ + String s = strs[i]; + String result = findMax(strs, (i + 1) % strs.length); + + String ans; + for(int k = 0, l = s.length(); k < l; k ++){ + StringBuilder sb = new StringBuilder(); + String start = s.substring(k); + String end = s.substring(0, k); + ans = sb.append(start).append(result).append(end).toString(); + max = max.compareTo(ans) > 0 ? max : ans; + } + + s = new StringBuilder(s).reverse().toString(); + for(int k = 0, l = s.length(); k < l; k ++){ + StringBuilder sb = new StringBuilder(); + String start = s.substring(k); + String end = s.substring(0, k); + ans = sb.append(start).append(result).append(end).toString(); + max = max.compareTo(ans) > 0 ? max : ans; + } + } + return max; + } + + private String findMax(String[] strs, int i){ + int c = 1; + StringBuilder sb = new StringBuilder(); + for(int j = i, l = strs.length; c < l; j = (j + 1) % l, c++){ + String nextStr = strs[j]; + String reverse = new StringBuilder(nextStr).reverse().toString(); + String result = nextStr.compareTo(reverse) > 0 ? nextStr : reverse; + sb.append(result); + } + return sb.toString(); + } +} diff --git a/problems/src/string/StudentAttendanceRecordI.java b/problems/src/string/StudentAttendanceRecordI.java new file mode 100644 index 00000000..e8148583 --- /dev/null +++ b/problems/src/string/StudentAttendanceRecordI.java @@ -0,0 +1,31 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 10/05/2019 You are given a string representing an attendance + * record for a student. The record only contains the following three characters: 'A' : Absent. 'L' + * : Late. 'P' : Present. A student could be rewarded if his attendance record doesn't contain more + * than one 'A' (absent) or more than two continuous 'L' (late). + * + *

You need to return whether the student could be rewarded according to his attendance record. + * + *

Example 1: Input: "PPALLP" Output: True Example 2: Input: "PPALLL" Output: False + * + * Solution O(N) Simple linear check + */ +public class StudentAttendanceRecordI { + public static void main(String[] args) { + } + + public boolean checkRecord(String s) { + int count = 0; + for(int c : s.toCharArray()){ + if(c == 'A'){ + count++; + } + if(count > 1) return false; + } + if(s.contains("LLL")) return false; + return true; + } + +} diff --git a/problems/src/string/ValidWordSquare.java b/problems/src/string/ValidWordSquare.java new file mode 100644 index 00000000..46307b8a --- /dev/null +++ b/problems/src/string/ValidWordSquare.java @@ -0,0 +1,77 @@ +package string; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 04/06/2019 Given a sequence of words, check whether it forms a + * valid word square. + * + *

A sequence of words forms a valid word square if the kth row and column read the exact same + * string, where 0 ≤ k < max(numRows, numColumns). + * + *

Note: The number of words given is at least 1 and does not exceed 500. Word length will be at + * least 1 and does not exceed 500. Each word contains only lowercase English alphabet a-z. Example + * 1: + * + *

Input: [ "abcd", "bnrt", "crmy", "dtye" ] + * + *

Output: true + * + *

Explanation: The first row and first column both read "abcd". The second row and second column + * both read "bnrt". The third row and third column both read "crmy". The fourth row and fourth + * column both read "dtye". + * + *

Therefore, it is a valid word square. Example 2: + * + *

Input: [ "abcd", "bnrt", "crm", "dt" ] + * + *

Output: true + * + *

Explanation: The first row and first column both read "abcd". The second row and second column + * both read "bnrt". The third row and third column both read "crm". The fourth row and fourth + * column both read "dt". + * + *

Therefore, it is a valid word square. Example 3: + * + *

Input: [ "ball", "area", "read", "lady" ] + * + *

Output: false + * + *

Explanation: The third row reads "read" while the third column reads "lead". + * + *

Therefore, it is NOT a valid word square. + * + * Solution: O(N x M) where N is number of words and M is max length of a string. + * Save strings for each column and each row in a array and compare them both. + */ +public class ValidWordSquare { + public static void main(String[] args) { + List arr = Arrays.asList("abcd", "bnrt", "crmy", "dtye"); + System.out.println(new ValidWordSquare().validWordSquare(arr)); + } + + public boolean validWordSquare(List words) { + List newList = new ArrayList<>(); + int max = 0; + for(int i = 0; i < words.size(); i ++){ + max = Math.max(max, words.get(i).length()); + } + + + for(int i = 0; i < max; i ++){ + StringBuilder sb = new StringBuilder(); + for(String w : words){ + if(i < w.length()){ + sb.append(w.charAt(i)); + } else break; + } + newList.add(sb.toString()); + } + + if(words.size() != newList.size()) return false; + + for(int i = 0, l = words.size(); i < l; i ++){ + if(!words.get(i).equals(newList.get(i))) return false; + } + return true; + } +} From 6d17f4c386931ab595a738f30c5e44755ced6015 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 3 Jul 2019 09:19:50 +0200 Subject: [PATCH 213/235] Solved problems --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7ed1aaaf..3154d0be 100644 --- a/README.md +++ b/README.md @@ -207,6 +207,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Russian Doll Envelopes](problems/src/dynamic_programming/RussianDollEnvelopes.java) (Hard) - [Student Attendance Record II](problems/src/dynamic_programming/StudentAttendanceRecordII.java) (Hard) - [Out of Boundary Paths](problems/src/dynamic_programming/OutOfBoundaryPaths.java) (Medium) +- [Remove Boxes](problems/src/dynamic_programming/RemoveBoxes.java) (Hard) #### [Greedy](problems/src/greedy) From 2627da31e64aa45e3501219e9d8e7c26abee8242 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 13 Jul 2019 11:42:24 +0200 Subject: [PATCH 214/235] Some improvements and solution update --- .gitignore | 5 +- problems/src/array/MaxConsecutiveOnes.java | 33 ++-- problems/src/array/MaxConsecutiveOnesII.java | 89 +++++----- .../src/backtracking/MatchsticksToSquare.java | 152 +++++++++--------- problems/src/backtracking/ZumaGame.java | 93 ++++++----- .../binary_search/TimeBasedKeyValuePair.java | 72 +++++---- .../BinaryNumberWithAlternatingBits.java | 8 +- .../depth_first_search/MaxAreaOfIsland.java | 87 +++++----- .../divide_and_conquer/TwentyFourGame.java | 147 ++++++++--------- .../MinimumCostForTickets.java | 8 +- .../OutOfBoundaryPaths.java | 61 +++---- .../src/dynamic_programming/RemoveBoxes.java | 47 +++--- .../RussianDollEnvelopes.java | 85 +++++----- problems/src/greedy/BoatsToSavePeople.java | 62 +++---- problems/src/greedy/StringWithout3A3B.java | 69 ++++---- .../heap/ReachableNodesInSubdividedGraph.java | 100 ++++++------ .../src/math/ProjectionAreaOf3DShapes.java | 53 +++--- problems/src/stack/DecodedStringAtIndex.java | 104 ++++++------ .../src/stack/StudentAttendanceRecordII.java | 60 +++---- .../ReconstructOriginalDigitsFromEnglish.java | 139 ++++++++-------- .../src/string/SplitConcatenatedStrings.java | 69 ++++---- .../src/string/StudentAttendanceRecordI.java | 26 ++- problems/src/string/ValidWordSquare.java | 46 +++--- 23 files changed, 826 insertions(+), 789 deletions(-) diff --git a/.gitignore b/.gitignore index 4042776d..076f3db0 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,5 @@ leetcode.ipr leetcode.iws out/ problems/src.iml -.idea/codeStyles/ -.idea/copyright/ -.idea/markdown-navigator/ +.idea/* +.gradle/ diff --git a/problems/src/array/MaxConsecutiveOnes.java b/problems/src/array/MaxConsecutiveOnes.java index 93626cad..3a4fcad9 100644 --- a/problems/src/array/MaxConsecutiveOnes.java +++ b/problems/src/array/MaxConsecutiveOnes.java @@ -15,23 +15,22 @@ public static void main(String[] args) { // } - public int findMaxConsecutiveOnes(int[] nums) { - int max = 0; - boolean flag = false; - int count = 0; - for(int i = 0; i < nums.length; i ++){ - if(nums[i] == 1){ - if(!flag){ - flag = true; - } - count++; - max = Math.max(max, count); - } else{ - count = 0; - flag = false; - } + public int findMaxConsecutiveOnes(int[] nums) { + int max = 0; + boolean flag = false; + int count = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] == 1) { + if (!flag) { + flag = true; } - return max; + count++; + max = Math.max(max, count); + } else { + count = 0; + flag = false; + } } - + return max; + } } diff --git a/problems/src/array/MaxConsecutiveOnesII.java b/problems/src/array/MaxConsecutiveOnesII.java index 99d8041f..09207589 100644 --- a/problems/src/array/MaxConsecutiveOnesII.java +++ b/problems/src/array/MaxConsecutiveOnesII.java @@ -13,60 +13,59 @@ * stream? In other words, you can't store all numbers coming from the stream as it's too large to * hold in memory. Could you solve it efficiently? * - * Solution: O(N) - * Maintain a left and right auxiliary array with counts of contagious 1's from both directions. - * Now, iterate through the array and flip a 0 to 1 and sum up left and right contagious sum of 1's and return the - * max sum as the answer + *

Solution: O(N) Maintain a left and right auxiliary array with counts of contagious 1's from + * both directions. Now, iterate through the array and flip a 0 to 1 and sum up left and right + * contagious sum of 1's and return the max sum as the answer */ public class MaxConsecutiveOnesII { public static void main(String[] args) { // } - public int findMaxConsecutiveOnes(int[] nums) { - int[] L = new int[nums.length]; - int[] R = new int[nums.length]; - boolean flag = false; - int count = 0; - int max = 0; - for(int j = 0; j < nums.length; j ++){ - if(nums[j] == 1){ - if(!flag){ - flag = true; - } - count++; - L[j] = count; - } else{ - count = 0; - flag = false; - L[j] = count; - } - max = Math.max(max, count); - } - flag = false; - count = 0; - for(int j = nums.length - 1; j >= 0; j --){ - if(nums[j] == 1){ - if(!flag){ - flag = true; - } - count++; - R[j] = count; - } else{ - count = 0; - flag = false; - R[j] = count; - } + public int findMaxConsecutiveOnes(int[] nums) { + int[] L = new int[nums.length]; + int[] R = new int[nums.length]; + boolean flag = false; + int count = 0; + int max = 0; + for (int j = 0; j < nums.length; j++) { + if (nums[j] == 1) { + if (!flag) { + flag = true; } + count++; + L[j] = count; + } else { + count = 0; + flag = false; + L[j] = count; + } + max = Math.max(max, count); + } - for(int i = 0; i < nums.length; i ++){ - if(nums[i] == 0){ - int l = i == 0 ? 0 : L[i - 1]; - int r = i == nums.length - 1 ? 0 : R[i + 1]; - max = Math.max(max, l + r + 1); - } + flag = false; + count = 0; + for (int j = nums.length - 1; j >= 0; j--) { + if (nums[j] == 1) { + if (!flag) { + flag = true; } - return max; + count++; + R[j] = count; + } else { + count = 0; + flag = false; + R[j] = count; + } } + for (int i = 0; i < nums.length; i++) { + if (nums[i] == 0) { + int l = i == 0 ? 0 : L[i - 1]; + int r = i == nums.length - 1 ? 0 : R[i + 1]; + max = Math.max(max, l + r + 1); + } + } + return max; + } } diff --git a/problems/src/backtracking/MatchsticksToSquare.java b/problems/src/backtracking/MatchsticksToSquare.java index 6a2a78aa..db9f729f 100644 --- a/problems/src/backtracking/MatchsticksToSquare.java +++ b/problems/src/backtracking/MatchsticksToSquare.java @@ -1,5 +1,7 @@ package backtracking; + import java.util.*; + /** * Created by gouthamvidyapradhan on 25/05/2019 Remember the story of Little Match Girl? By now, you * know exactly what matchsticks the little match girl has, please find out a way you can make one @@ -19,94 +21,96 @@ * sum of the given matchsticks is in the range of 0 to 10^9. The length of the given matchstick * array will not exceed 15. * - * Solution: O(2 ^ N): Generate a power set of all combination of numbers for the given array which sum up to the - * length of a side of square. - * Now, to check if a square can be made using all the sides sticks of different length, generate a hash for for each of - * the combination which was generated in the previous step. The hash function should be such that it uses unique - * indexes of each match stick. If 4 different hash values are formed using unique and all indices then a square is - * possible. + *

Solution: O(2 ^ N): Generate a power set of all combination of numbers for the given array + * which sum up to the length of a side of square. Now, to check if a square can be made using all + * the sides sticks of different length, generate a hash for for each of the combination which was + * generated in the previous step. The hash function should be such that it uses unique indexes of + * each match stick. If 4 different hash values are formed using unique and all indices then a + * square is possible. */ public class MatchsticksToSquare { - /** - * Main method - * @param args - */ + /** + * Main method + * + * @param args + */ public static void main(String[] args) { - int[] A = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 6, 10, 10}; + int[] A = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 6, 10, 10}; System.out.println(new MatchsticksToSquare().makesquare(A)); } - class Pair { - int value, i; - Pair(int value, int i){ - this.value = value; - this.i = i; - } + class Pair { + int value, i; + + Pair(int value, int i) { + this.value = value; + this.i = i; } + } - public boolean makesquare(int[] nums) { - if(nums.length == 0) return false; - int sum = 0; - for(int n : nums){ - sum += n; - } - int side = sum / 4; - if((sum % 4) != 0) return false; - List> list = powerSet(nums, side); - Set hashIndex = new HashSet<>(); - int cons = 0; - for(int i = 0; i < nums.length; i ++){ - cons |= (1 << i); + public boolean makesquare(int[] nums) { + if (nums.length == 0) return false; + int sum = 0; + for (int n : nums) { + sum += n; + } + int side = sum / 4; + if ((sum % 4) != 0) return false; + List> list = powerSet(nums, side); + Set hashIndex = new HashSet<>(); + int cons = 0; + for (int i = 0; i < nums.length; i++) { + cons |= (1 << i); + } + for (int i = 0; i < list.size(); i++) { + for (int j = i + 1; j < list.size(); j++) { + Set indexList = new HashSet<>(); + List list1 = list.get(i); + List list2 = list.get(j); + int hash = 0; + for (Pair l1 : list1) { + indexList.add(l1.i); + hash |= (1 << l1.i); } - for(int i = 0; i < list.size(); i ++){ - for(int j = i + 1; j < list.size(); j ++){ - Set indexList = new HashSet<>(); - List list1 = list.get(i); - List list2 = list.get(j); - int hash = 0; - for(Pair l1 : list1){ - indexList.add(l1.i); - hash |= (1 << l1.i); - } - boolean allUnique = true; - for(Pair l2 : list2){ - if(indexList.contains(l2.i)) { - allUnique = false; - break; - } - indexList.add(l2.i); - hash |= (1 << l2.i); - } - if(allUnique){ - hashIndex.add(hash); - int complement = ((~ hash) & cons); - if(hashIndex.contains(complement)) return true; - } + boolean allUnique = true; + for (Pair l2 : list2) { + if (indexList.contains(l2.i)) { + allUnique = false; + break; } + indexList.add(l2.i); + hash |= (1 << l2.i); + } + if (allUnique) { + hashIndex.add(hash); + int complement = ((~hash) & cons); + if (hashIndex.contains(complement)) return true; + } } - return false; } + return false; + } - private List> powerSet(int[] nums, int expectedSum){ - List> result = new ArrayList<>(); - generate(0, nums, new ArrayList<>(), result, 0, expectedSum); - return result; - } + private List> powerSet(int[] nums, int expectedSum) { + List> result = new ArrayList<>(); + generate(0, nums, new ArrayList<>(), result, 0, expectedSum); + return result; + } - private void generate(int i, int[] nums, List subList, List> result, int sum, - int expected){ - if(i >= nums.length){ - if(sum == expected){ - List pairs = new ArrayList<>(subList); - result.add(pairs); - } - } else{ - if(sum + nums[i] <= expected){ - subList.add(new Pair(nums[i], i)); - generate(i + 1, nums, subList, result, sum + nums[i], expected); - subList.remove(subList.size() - 1); - } - generate(i + 1, nums, subList, result, sum, expected); + private void generate( + int i, int[] nums, List subList, List> result, int sum, int expected) { + if (i >= nums.length) { + if (sum == expected) { + List pairs = new ArrayList<>(subList); + result.add(pairs); } + } else { + if (sum + nums[i] <= expected) { + subList.add(new Pair(nums[i], i)); + generate(i + 1, nums, subList, result, sum + nums[i], expected); + subList.remove(subList.size() - 1); + } + generate(i + 1, nums, subList, result, sum, expected); } + } } diff --git a/problems/src/backtracking/ZumaGame.java b/problems/src/backtracking/ZumaGame.java index 39715913..4787654c 100644 --- a/problems/src/backtracking/ZumaGame.java +++ b/problems/src/backtracking/ZumaGame.java @@ -1,5 +1,7 @@ package backtracking; + import java.util.*; + /** * Created by gouthamvidyapradhan on 14/05/2019 Think about Zuma Game. You have a row of balls on * the table, colored red(R), yellow(Y), blue(B), green(G), and white(W). You also have several @@ -30,59 +32,62 @@ * won't exceed 5, and the string represents these balls is called "hand" in the input. Both input * strings will be non-empty and only contain characters 'R','Y','B','G','W'. * - * Solution: Maintain a count of each colored balls. Reduce the string to a new string by removing the contiguous - * same coloured balls which exceeds the count of 3 starting from index i = 0. Each new string formed (by adding a - * new ball to a position i) makes a new state. Backtrack and traverse the search space and keep track of count of - * balls used. Maintain a minimum count variable and return that as the answer. + *

Solution: Maintain a count of each colored balls. Reduce the string to a new string by + * removing the contiguous same coloured balls which exceeds the count of 3 starting from index i = + * 0. Each new string formed (by adding a new ball to a position i) makes a new state. Backtrack and + * traverse the search space and keep track of count of balls used. Maintain a minimum count + * variable and return that as the answer. */ public class ZumaGame { public static void main(String[] args) { - System.out.println(new ZumaGame().findMinStep("BBWWRRYYRRWWBB", "Y")); + System.out.println(new ZumaGame().findMinStep("BBWWRRYYRRWWBB", "Y")); } - Map map; - int min = Integer.MAX_VALUE; - public int findMinStep(String board, String hand) { - map = new HashMap<>(); - for(char c : hand.toCharArray()){ - map.putIfAbsent(c, 0); - map.put(c, map.get(c) + 1); - } - backtrack(board, 0); - return min == Integer.MAX_VALUE ? -1 : min; + Map map; + int min = Integer.MAX_VALUE; + + public int findMinStep(String board, String hand) { + map = new HashMap<>(); + for (char c : hand.toCharArray()) { + map.putIfAbsent(c, 0); + map.put(c, map.get(c) + 1); } + backtrack(board, 0); + return min == Integer.MAX_VALUE ? -1 : min; + } - private void backtrack(String board, int total){ - if(board.isEmpty()){ - min = Math.min(min, total); - } else{ - int i = 0, j = 0; - for(int l = board.length(); i < l;){ - if(j < l && board.charAt(j) == board.charAt(i)){ - j++; - } else{ - if(j - i > 2){ - backtrack(board.substring(0, i) + ((j < l) ? board.substring(j) : ""), total); - } else{ - int a = j - i; - char c = board.charAt(i); - if(map.containsKey(c)){ - int count = map.get(c); - if(count >= (3 - a)){ - if((count - (3 - a)) == 0) { - map.remove(c); - } else{ - map.put(c, count - (3 - a)); - } - backtrack(board.substring(0, i) + ((j < l) ? board.substring(j) : ""), total + (3 - a)); - map.put(c, count); - } - } - } - i = j; - j++; + private void backtrack(String board, int total) { + if (board.isEmpty()) { + min = Math.min(min, total); + } else { + int i = 0, j = 0; + for (int l = board.length(); i < l; ) { + if (j < l && board.charAt(j) == board.charAt(i)) { + j++; + } else { + if (j - i > 2) { + backtrack(board.substring(0, i) + ((j < l) ? board.substring(j) : ""), total); + } else { + int a = j - i; + char c = board.charAt(i); + if (map.containsKey(c)) { + int count = map.get(c); + if (count >= (3 - a)) { + if ((count - (3 - a)) == 0) { + map.remove(c); + } else { + map.put(c, count - (3 - a)); } + backtrack( + board.substring(0, i) + ((j < l) ? board.substring(j) : ""), total + (3 - a)); + map.put(c, count); + } } + } + i = j; + j++; } + } } + } } diff --git a/problems/src/binary_search/TimeBasedKeyValuePair.java b/problems/src/binary_search/TimeBasedKeyValuePair.java index 14e7a606..f61c3d0c 100644 --- a/problems/src/binary_search/TimeBasedKeyValuePair.java +++ b/problems/src/binary_search/TimeBasedKeyValuePair.java @@ -1,4 +1,5 @@ package binary_search; + import java.util.*; /** @@ -36,47 +37,48 @@ * TimeMap.set and TimeMap.get functions will be called a total of 120000 times (combined) per test * case. * - * Solution O(log N) where N is the number of values for the same key (but different timestamp) - * Idea is to use the HashMap to store the unique key and a TreeMap as value containing all different timestamps and - * value. Use the floor function in treemap to get the value for a given timestamp. + *

Solution O(log N) where N is the number of values for the same key (but different timestamp) + * Idea is to use the HashMap to store the unique key and a TreeMap as value containing all + * different timestamps and value. Use the floor function in treemap to get the value for a given + * timestamp. */ public class TimeBasedKeyValuePair { - private Map> map; + private Map> map; - public TimeBasedKeyValuePair() { - map = new HashMap<>(); - } + public TimeBasedKeyValuePair() { + map = new HashMap<>(); + } - public void set(String key, String value, int timestamp) { - map.putIfAbsent(key, new TreeMap<>()); - TreeMap treeMap = map.get(key); - treeMap.put(timestamp, value); - } + public void set(String key, String value, int timestamp) { + map.putIfAbsent(key, new TreeMap<>()); + TreeMap treeMap = map.get(key); + treeMap.put(timestamp, value); + } - public String get(String key, int timestamp) { - if(!map.containsKey(key)){ - return ""; - }else { - TreeMap treeMap = map.get(key); - Map.Entry entry = treeMap.floorEntry(timestamp); - if(entry == null){ - return ""; - } else{ - return entry.getValue(); - } - } + public String get(String key, int timestamp) { + if (!map.containsKey(key)) { + return ""; + } else { + TreeMap treeMap = map.get(key); + Map.Entry entry = treeMap.floorEntry(timestamp); + if (entry == null) { + return ""; + } else { + return entry.getValue(); + } } + } - public static void main(String[] args) { - TimeBasedKeyValuePair task = new TimeBasedKeyValuePair(); - task.set("foo", "bar", 1); - System.out.println(task.get("foo", 1)); - System.out.println(task.get("foo", 3)); - System.out.println(task.get("foo", 0)); - task.set("foo", "bar2", 4); - System.out.println(task.get("foo", 3)); - System.out.println(task.get("foo", 4)); - System.out.println(task.get("foo", 5)); - } + public static void main(String[] args) { + TimeBasedKeyValuePair task = new TimeBasedKeyValuePair(); + task.set("foo", "bar", 1); + System.out.println(task.get("foo", 1)); + System.out.println(task.get("foo", 3)); + System.out.println(task.get("foo", 0)); + task.set("foo", "bar2", 4); + System.out.println(task.get("foo", 3)); + System.out.println(task.get("foo", 4)); + System.out.println(task.get("foo", 5)); + } } diff --git a/problems/src/bit_manipulation/BinaryNumberWithAlternatingBits.java b/problems/src/bit_manipulation/BinaryNumberWithAlternatingBits.java index e3fe3e4c..7c9e2bfe 100644 --- a/problems/src/bit_manipulation/BinaryNumberWithAlternatingBits.java +++ b/problems/src/bit_manipulation/BinaryNumberWithAlternatingBits.java @@ -16,15 +16,15 @@ public static void main(String[] args) { public boolean hasAlternatingBits(int n) { int curr = n & 1; int pos = 0; - for(int i = 0; i < 32; i++){ - if((n & (1 << i)) > 0){ + for (int i = 0; i < 32; i++) { + if ((n & (1 << i)) > 0) { pos = i; } } - for(int i = 1; i <= pos; i++){ + for (int i = 1; i <= pos; i++) { int temp = (1 << i) & n; - if((temp > 0 && curr > 0) || (temp == 0 && curr == 0)) return false; + if ((temp > 0 && curr > 0) || (temp == 0 && curr == 0)) return false; curr = temp; } return true; diff --git a/problems/src/depth_first_search/MaxAreaOfIsland.java b/problems/src/depth_first_search/MaxAreaOfIsland.java index 2148e075..0851ed8d 100644 --- a/problems/src/depth_first_search/MaxAreaOfIsland.java +++ b/problems/src/depth_first_search/MaxAreaOfIsland.java @@ -1,8 +1,7 @@ package depth_first_search; /** - * Created by gouthamvidyapradhan on 28/05/2019 - * Given a non-empty 2D array grid of 0's and 1's, an + * Created by gouthamvidyapradhan on 28/05/2019 Given a non-empty 2D array grid of 0's and 1's, an * island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) * You may assume all four edges of the grid are surrounded by water. * @@ -19,53 +18,59 @@ *

[[0,0,0,0,0,0,0,0]] Given the above grid, return 0. Note: The length of each dimension in the * given grid does not exceed 50. * - * Solution: O(N x M) Do a dfs and keep track of max connected 1's + *

Solution: O(N x M) Do a dfs and keep track of max connected 1's */ public class MaxAreaOfIsland { - final int[] R = {0, 0, -1, 1}; - final int[] C = {1, -1, 0, 0}; + final int[] R = {0, 0, -1, 1}; + final int[] C = {1, -1, 0, 0}; - int count = 0; - int max = 0; - boolean[][] done; - public static void main(String[] args) { - int[][] grid = {{0,0,1,0,0,0,0,1,0,0,0,0,0}, - {0,0,0,0,0,0,0,1,1,1,0,0,0}, - {0,1,1,0,1,0,0,0,0,0,0,0,0}, - {0,1,0,0,1,1,0,0,1,0,1,0,0}, - {0,1,0,0,1,1,0,0,1,1,1,0,0}, - {0,0,0,0,0,0,0,0,0,0,1,0,0}, - {0,0,0,0,0,0,0,1,1,1,0,0,0}, - {0,0,0,0,0,0,0,1,1,0,0,0,0}}; + int count = 0; + int max = 0; + boolean[][] done; - System.out.println(new MaxAreaOfIsland().maxAreaOfIsland(grid)); - } + public static void main(String[] args) { + int[][] grid = { + {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0}, + {0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0}, + {0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0} + }; + System.out.println(new MaxAreaOfIsland().maxAreaOfIsland(grid)); + } - public int maxAreaOfIsland(int[][] grid) { - done = new boolean[grid.length][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 && !done[i][j]){ - count = 0; - dfs(grid, i, j); - max = Math.max(max, count); - } - } + public int maxAreaOfIsland(int[][] grid) { + done = new boolean[grid.length][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 && !done[i][j]) { + count = 0; + dfs(grid, i, j); + max = Math.max(max, count); } - return max; + } } + return max; + } - private void dfs(int[][] grid, int r, int c){ - done[r][c] = true; - count++; - for(int i = 0; i < 4; i++){ - int newR = r + R[i]; - int newC = c + C[i]; - if(newR >= 0 && newC >= 0 && newR < grid.length && newC < grid[0].length && !done[newR][newC] && grid[newR][newC] == 1){ - dfs(grid, newR, newC); - } - } + private void dfs(int[][] grid, int r, int c) { + done[r][c] = true; + count++; + for (int i = 0; i < 4; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 + && newC >= 0 + && newR < grid.length + && newC < grid[0].length + && !done[newR][newC] + && grid[newR][newC] == 1) { + dfs(grid, newR, newC); + } } - + } } diff --git a/problems/src/divide_and_conquer/TwentyFourGame.java b/problems/src/divide_and_conquer/TwentyFourGame.java index 867d54d3..ed8b81e1 100644 --- a/problems/src/divide_and_conquer/TwentyFourGame.java +++ b/problems/src/divide_and_conquer/TwentyFourGame.java @@ -1,4 +1,5 @@ package divide_and_conquer; + import java.util.*; /** @@ -12,98 +13,100 @@ * expression -1 - 1 - 1 - 1 is not allowed. You cannot concatenate numbers together. For example, * if the input is [1, 2, 1, 2], we cannot write this as 12 + 12. * - * Solution O(1) Generate all permutation of a given 4 digit number and for each permutation split the number into - * two parts with left and right (at various possible split points). Now perform all possible operations(+, -, * and /) - * for each left and right and check if any of the operation results in 24 + *

Solution O(1) Generate all permutation of a given 4 digit number and for each permutation + * split the number into two parts with left and right (at various possible split points). Now + * perform all possible operations(+, -, * and /) for each left and right and check if any of the + * operation results in 24 */ public class TwentyFourGame { public static void main(String[] args) { - int[] A = {4, 7, 7, 7}; + int[] A = {4, 7, 7, 7}; System.out.println(new TwentyFourGame().judgePoint24(A)); } - class Fraction{ - int n, d; - Fraction(int n, int d){ - this.n = n; - this.d = d; - } - } + class Fraction { + int n, d; - public boolean judgePoint24(int[] nums) { - List result = new ArrayList<>(); - permute(0, nums, result); - for(int[] A : result){ - List list = generate(0, 3, A); - for(Fraction f : list){ - if((f.d != 0) &&(f.n / f.d) == 24 && (f.n % f.d) == 0) return true; - } - } - return false; + Fraction(int n, int d) { + this.n = n; + this.d = d; } + } - private void permute(int i, int[] nums, List result){ - if(i >= nums.length) { - result.add(Arrays.copyOf(nums, 4)); - } else{ - for(int j = i; j < nums.length; j ++){ - swap(i, j, nums); - permute(i + 1, nums, result); - swap(i, j, nums); - } + public boolean judgePoint24(int[] nums) { + List result = new ArrayList<>(); + permute(0, nums, result); + for (int[] A : result) { + List list = generate(0, 3, A); + for (Fraction f : list) { + if ((f.d != 0) && (f.n / f.d) == 24 && (f.n % f.d) == 0) return true; } } + return false; + } - private void swap(int i, int j, int[] nums){ - int temp = nums[i]; - nums[i] = nums[j]; - nums[j] = temp; + private void permute(int i, int[] nums, List result) { + if (i >= nums.length) { + result.add(Arrays.copyOf(nums, 4)); + } else { + for (int j = i; j < nums.length; j++) { + swap(i, j, nums); + permute(i + 1, nums, result); + swap(i, j, nums); + } } + } + + private void swap(int i, int j, int[] nums) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } - private List generate(int l, int r, int[] nums){ - if(l > r){ - return new ArrayList<>(); - } else if(l == r){ - return Arrays.asList(new Fraction(nums[l], 1)); - } else{ - List result = new ArrayList<>(); - for(int i = l; i < r; i ++){ - for(int j = l; j <= i; j ++){ - List left = generate(l, j, nums); - List right = generate(j + 1, r, nums); - if(right.isEmpty()){ - result.addAll(left); - } else if(left.isEmpty()){ - result.addAll(right); - } else{ - for(Fraction lF : left){ - for(Fraction rF : right){ - int n = (lF.n * rF.d + rF.n * lF.d); - int d = (lF.d * rF.d); - Fraction sum = new Fraction(n, d); + private List generate(int l, int r, int[] nums) { + if (l > r) { + return new ArrayList<>(); + } else if (l == r) { + return Arrays.asList(new Fraction(nums[l], 1)); + } else { + List result = new ArrayList<>(); + for (int i = l; i < r; i++) { + for (int j = l; j <= i; j++) { + List left = generate(l, j, nums); + List right = generate(j + 1, r, nums); + if (right.isEmpty()) { + result.addAll(left); + } else if (left.isEmpty()) { + result.addAll(right); + } else { + for (Fraction lF : left) { + for (Fraction rF : right) { + int n = (lF.n * rF.d + rF.n * lF.d); + int d = (lF.d * rF.d); + Fraction sum = new Fraction(n, d); - n = (lF.n * rF.d - (rF.n * lF.d)); - d = (lF.d * rF.d); - Fraction diff = new Fraction(n, d); + n = (lF.n * rF.d - (rF.n * lF.d)); + d = (lF.d * rF.d); + Fraction diff = new Fraction(n, d); - n = (lF.n * rF.n); - d = (lF.d * rF.d); - Fraction prod = new Fraction(n, d); + n = (lF.n * rF.n); + d = (lF.d * rF.d); + Fraction prod = new Fraction(n, d); - n = (lF.n * rF.d); - d = (lF.d * rF.n); - Fraction div = new Fraction(n, d); - result.add(sum); - result.add(diff); - result.add(prod); - result.add(div); - } - } - } + n = (lF.n * rF.d); + d = (lF.d * rF.n); + Fraction div = new Fraction(n, d); + result.add(sum); + result.add(diff); + result.add(prod); + result.add(div); } + } } - return result; + } } + return result; } + } } diff --git a/problems/src/dynamic_programming/MinimumCostForTickets.java b/problems/src/dynamic_programming/MinimumCostForTickets.java index daa77c4e..e8a7c202 100644 --- a/problems/src/dynamic_programming/MinimumCostForTickets.java +++ b/problems/src/dynamic_programming/MinimumCostForTickets.java @@ -34,14 +34,14 @@ * *

1 <= days.length <= 365 1 <= days[i] <= 365 days is in strictly increasing order. costs.length * == 3 1 <= costs[i] <= 1000 - - Solution: O(N ^ 2 x 3) + * + *

Solution: O(N ^ 2 x 3) */ public class MinimumCostForTickets { public static void main(String[] args) { - int[] days = {1,2,3,4,5,6,7,8,9,10,30,31}; - int[] costs = {2, 7, 15}; + int[] days = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 31}; + int[] costs = {2, 7, 15}; System.out.println(new MinimumCostForTickets().mincostTickets(days, costs)); } /** diff --git a/problems/src/dynamic_programming/OutOfBoundaryPaths.java b/problems/src/dynamic_programming/OutOfBoundaryPaths.java index ee0201d0..a7e89b4f 100644 --- a/problems/src/dynamic_programming/OutOfBoundaryPaths.java +++ b/problems/src/dynamic_programming/OutOfBoundaryPaths.java @@ -1,47 +1,48 @@ package dynamic_programming; /** - * Created by gouthamvidyapradhan on 15/05/2019 - * There is an m by n grid with a ball. Given the start coordinate (i,j) of the ball, you can move the ball to - * adjacent cell or cross the grid boundary in four directions (up, down, left, right). However, you can at most move - * N times. Find out the number of paths to move the ball out of grid boundary. The answer may be very large, return - * it after mod 10 ^ 9 + 7. + * Created by gouthamvidyapradhan on 15/05/2019 There is an m by n grid with a ball. Given the start + * coordinate (i,j) of the ball, you can move the ball to adjacent cell or cross the grid boundary + * in four directions (up, down, left, right). However, you can at most move N times. Find out the + * number of paths to move the ball out of grid boundary. The answer may be very large, return it + * after mod 10 ^ 9 + 7. * - * Solution: O(m x n x N x 4) Move in all possible directions from the starting position (i, j) and keep track of - * distance traversed and ensure the distance traversed does not exceed N. Keep the count of number of possibilities - * to go out of the boundary for each cell reached. Return the sum in cell (a, b) + *

Solution: O(m x n x N x 4) Move in all possible directions from the starting position (i, j) + * and keep track of distance traversed and ensure the distance traversed does not exceed N. Keep + * the count of number of possibilities to go out of the boundary for each cell reached. Return the + * sum in cell (a, b) */ public class OutOfBoundaryPaths { - final int[] R = {1, -1, 0, 0}; - final int[] C = {0, 0, 1, -1}; - int[][][] DP; - int mod = 1000000007; + final int[] R = {1, -1, 0, 0}; + final int[] C = {0, 0, 1, -1}; + int[][][] DP; + int mod = 1000000007; + public static void main(String[] args) { System.out.println(new OutOfBoundaryPaths().findPaths(2, 2, 2, 0, 0)); } - public int findPaths(int m, int n, int N, int a, int b) { - if(N == 0) return 0; - DP = new int[m][n][N + 1]; + public int findPaths(int m, int n, int N, int a, int b) { + if (N == 0) return 0; + DP = new int[m][n][N + 1]; - for(int k = 1; k <= N; k++){ - for(int i = 0; i < m; i ++){ - for(int j = 0; j < n; j ++){ - for(int p = 0; p < 4; p++){ - int newR = i + R[p]; - int newC = j + C[p]; - if(newR < 0 || newC < 0 || newR >= m || newC >= n){ - DP[i][j][k] = ((DP[i][j][k] + 1) % mod); - } else{ - DP[i][j][k] = (((DP[i][j][k] + DP[newR][newC][k - 1])) % mod); - } - } - } + for (int k = 1; k <= N; k++) { + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + for (int p = 0; p < 4; p++) { + int newR = i + R[p]; + int newC = j + C[p]; + if (newR < 0 || newC < 0 || newR >= m || newC >= n) { + DP[i][j][k] = ((DP[i][j][k] + 1) % mod); + } else { + DP[i][j][k] = (((DP[i][j][k] + DP[newR][newC][k - 1])) % mod); } + } } - - return DP[a][b][N]; + } } + return DP[a][b][N]; + } } diff --git a/problems/src/dynamic_programming/RemoveBoxes.java b/problems/src/dynamic_programming/RemoveBoxes.java index 7d63b12f..77181c6c 100644 --- a/problems/src/dynamic_programming/RemoveBoxes.java +++ b/problems/src/dynamic_programming/RemoveBoxes.java @@ -11,33 +11,38 @@ *

[1, 3, 2, 2, 2, 3, 4, 3, 1] Output: 23 Explanation: [1, 3, 2, 2, 2, 3, 4, 3, 1] ----> [1, 3, * 3, 4, 3, 1] (3*3=9 points) ----> [1, 3, 3, 3, 1] (1*1=1 points) ----> [1, 1] (3*3=9 points) ----> * [] (2*2=4 points) Note: The number of boxes n would not exceed 100. + * + * Solution O(N ^ 4) For each sub-array [l, r] make a dp cache and calculate maximum of [l, i][1] + [i + 1, r][1] or + * maximum of [l + 1, i - 1][n] + [i, r][1] where boxes[l] == boxes[i] where n is the count of repetitions */ public class RemoveBoxes { - int[][][] dp; - public static void main(String[] args) { - int[] boxes = {3, 3, 3}; + int[][][] dp; + + public static void main(String[] args) { + int[] boxes = {3, 3, 3}; System.out.println(new RemoveBoxes().removeBoxes(boxes)); - } + } - public int removeBoxes(int[] boxes) { - dp = new int[boxes.length][boxes.length][boxes.length + 1]; - return calculate(0, boxes.length - 1, 1, boxes); - } + public int removeBoxes(int[] boxes) { + dp = new int[boxes.length][boxes.length][boxes.length + 1]; + return calculate(0, boxes.length - 1, 1, boxes); + } - int calculate(int l, int r, int rep, int[] boxes){ - if(l == r) return rep * rep; - else if(l > r) return 0; - else if(dp[l][r][rep] != 0) return dp[l][r][rep]; - else{ - dp[l][r][rep] = calculate(l, r - 1, 1, boxes) + (rep * rep); - for(int i = l; i < r; i ++){ - if(boxes[i] == boxes[r]){ - dp[l][r][rep] = Math.max(dp[l][r][rep], - calculate(l, i, rep + 1, boxes) + calculate(i + 1, r - 1, 1, boxes)); - } - } - return dp[l][r][rep]; + int calculate(int l, int r, int n, int[] boxes) { + if (l > r) return 0; + else { + if (dp[l][r][n] != 0) return dp[l][r][n]; + dp[l][r][n] = (n * n) + calculate(l + 1, r, 1, boxes); + for (int i = l + 1; i <= r; i++) { + int center = 0, next = 0; + if (boxes[l] == boxes[i]) { + center = calculate(l + 1, i - 1, 1, boxes); + next = calculate(i, r, n + 1, boxes); } + dp[l][r][n] = Math.max(dp[l][r][n], center + next); + } } + return dp[l][r][n]; + } } diff --git a/problems/src/dynamic_programming/RussianDollEnvelopes.java b/problems/src/dynamic_programming/RussianDollEnvelopes.java index cb90f274..a8b10ebc 100644 --- a/problems/src/dynamic_programming/RussianDollEnvelopes.java +++ b/problems/src/dynamic_programming/RussianDollEnvelopes.java @@ -1,4 +1,5 @@ package dynamic_programming; + import java.util.*; /** @@ -15,56 +16,56 @@ *

Input: [[5,4],[6,4],[6,7],[2,3]] Output: 3 Explanation: The maximum number of envelopes you * can Russian doll is 3 ([2,3] => [5,4] => [6,7]). * - * Solution: O(N ^ 2) - * Sort the envelopes based on increasing order of area and for each envelope iterate through all the possible - * envelopes which are smaller than that the current envelope and check the maximum possible - * envelopes which an be russian dolled. + *

Solution: O(N ^ 2) Sort the envelopes based on increasing order of area and for each envelope + * iterate through all the possible envelopes which are smaller than that the current envelope and + * check the maximum possible envelopes which an be russian dolled. */ public class RussianDollEnvelopes { - /** - * Main method - * @param args - */ + /** + * Main method + * + * @param args + */ public static void main(String[] args) { - int[][] A = {{5,4}, {6,4}, {6,7}, {2,3}}; + int[][] A = {{5, 4}, {6, 4}, {6, 7}, {2, 3}}; System.out.println(new RussianDollEnvelopes().maxEnvelopes(A)); } - class Envelope{ - int l, b; - Envelope(int l, int b){ - this.l = l; - this.b = b; - } + class Envelope { + int l, b; + + Envelope(int l, int b) { + this.l = l; + this.b = b; + } } - /** - * - * @param envelopes - * @return - */ - public int maxEnvelopes(int[][] envelopes) { - if(envelopes.length == 0) return 0; - List list = new ArrayList<>(); - for(int[] row : envelopes){ - list.add(new Envelope(row[0], row[1])); - } - list.sort(((o1, o2) -> Integer.compare(o2.l * o2.b, o1.l * o1.b))); - int[] DP = new int[envelopes.length]; - Arrays.fill(DP, 1); - for(int i = list.size() - 1; i >= 0; i --){ - Envelope env = list.get(i); - for(int j = i + 1, l = list.size(); j < l; j ++){ - Envelope childEnv = list.get(j); - if(env.l > childEnv.l && env.b > childEnv.b){ - DP[i] = Math.max(DP[i], DP[j] + 1); - } - } - } - int ans = 1; - for(int i : DP){ - ans = Math.max(ans, i); + /** + * @param envelopes + * @return + */ + public int maxEnvelopes(int[][] envelopes) { + if (envelopes.length == 0) return 0; + List list = new ArrayList<>(); + for (int[] row : envelopes) { + list.add(new Envelope(row[0], row[1])); + } + list.sort(((o1, o2) -> Integer.compare(o2.l * o2.b, o1.l * o1.b))); + int[] DP = new int[envelopes.length]; + Arrays.fill(DP, 1); + for (int i = list.size() - 1; i >= 0; i--) { + Envelope env = list.get(i); + for (int j = i + 1, l = list.size(); j < l; j++) { + Envelope childEnv = list.get(j); + if (env.l > childEnv.l && env.b > childEnv.b) { + DP[i] = Math.max(DP[i], DP[j] + 1); } - return ans; + } } + int ans = 1; + for (int i : DP) { + ans = Math.max(ans, i); + } + return ans; + } } diff --git a/problems/src/greedy/BoatsToSavePeople.java b/problems/src/greedy/BoatsToSavePeople.java index 9b99a7af..c85cfc54 100644 --- a/problems/src/greedy/BoatsToSavePeople.java +++ b/problems/src/greedy/BoatsToSavePeople.java @@ -1,4 +1,5 @@ package greedy; + import java.util.*; /** @@ -22,44 +23,43 @@ * *

1 <= people.length <= 50000 1 <= people[i] <= limit <= 30000 * - * Solution O N log N - * Simple strategy is to greedy try to put in maximum possible people in a boat and increment the boat counter. Use - * TreeMap and sorting to achieve this easily + *

Solution O N log N Simple strategy is to greedy try to put in maximum possible people in a + * boat and increment the boat counter. Use TreeMap and sorting to achieve this easily */ public class BoatsToSavePeople { public static void main(String[] args) { - int[] A = {3, 5, 3, 4}; + int[] A = {3, 5, 3, 4}; System.out.println(new BoatsToSavePeople().numRescueBoats(A, 8)); } - public int numRescueBoats(int[] people, int limit) { - TreeMap treeMap = new TreeMap<>(); - int boats = 0; - for(int p : people){ - treeMap.putIfAbsent(p, 0); - treeMap.put(p, treeMap.get(p) + 1); + public int numRescueBoats(int[] people, int limit) { + TreeMap treeMap = new TreeMap<>(); + int boats = 0; + for (int p : people) { + treeMap.putIfAbsent(p, 0); + treeMap.put(p, treeMap.get(p) + 1); + } + Arrays.sort(people); + for (int p : people) { + if (treeMap.containsKey(p)) { + int count = treeMap.remove(p); + --count; + if (count != 0) { + treeMap.put(p, count); } - Arrays.sort(people); - for(int p : people){ - if(treeMap.containsKey(p)){ - int count = treeMap.remove(p); - --count; - if(count != 0){ - treeMap.put(p, count); - } - int balance = limit - p; - Map.Entry floor = treeMap.floorEntry(balance); - if(floor != null){ - int c = floor.getValue(); - --c; - treeMap.remove(floor.getKey()); - if(c != 0){ - treeMap.put(floor.getKey(), c); - } - } - boats++; - } + int balance = limit - p; + Map.Entry floor = treeMap.floorEntry(balance); + if (floor != null) { + int c = floor.getValue(); + --c; + treeMap.remove(floor.getKey()); + if (c != 0) { + treeMap.put(floor.getKey(), c); + } } - return boats; + boats++; + } } + return boats; + } } diff --git a/problems/src/greedy/StringWithout3A3B.java b/problems/src/greedy/StringWithout3A3B.java index d44ecafb..c6e19f37 100644 --- a/problems/src/greedy/StringWithout3A3B.java +++ b/problems/src/greedy/StringWithout3A3B.java @@ -15,9 +15,8 @@ * *

Input: A = 4, B = 1 Output: "aabaa" * - * Solution O(N) idea is to greedily try to put two a's if number of a's is > b and - * similarly for b - * + *

Solution O(N) idea is to greedily try to put two a's if number of a's is > b and similarly for + * b */ public class StringWithout3A3B { @@ -25,39 +24,37 @@ public static void main(String[] args) { System.out.println(new StringWithout3A3B().strWithout3a3b(4, 1)); } - public String strWithout3a3b(int A, int B) { - StringBuilder sb = new StringBuilder(); - while(A > 0 || B > 0){ - if(A > B && A > 1 && B > 0){ - sb.append("a").append("a"); - sb.append("b"); - A -= 2; - B -= 1; - } - else if(B > A && B > 1 && A > 0){ - sb.append("b").append("b"); - sb.append("a"); - B -= 2; - A -= 1; - } else{ - if(A > B && A > 1){ - sb.append("a"); - sb.append("a"); - A -= 2; - } else if(A > B && A > 0){ - sb.append("a"); - A -= 1; - } else if(B > A && B > 1){ - sb.append("b"); - sb.append("b"); - B -= 2; - } else { - sb.append("b"); - B -= 1; - } - } + public String strWithout3a3b(int A, int B) { + StringBuilder sb = new StringBuilder(); + while (A > 0 || B > 0) { + if (A > B && A > 1 && B > 0) { + sb.append("a").append("a"); + sb.append("b"); + A -= 2; + B -= 1; + } else if (B > A && B > 1 && A > 0) { + sb.append("b").append("b"); + sb.append("a"); + B -= 2; + A -= 1; + } else { + if (A > B && A > 1) { + sb.append("a"); + sb.append("a"); + A -= 2; + } else if (A > B && A > 0) { + sb.append("a"); + A -= 1; + } else if (B > A && B > 1) { + sb.append("b"); + sb.append("b"); + B -= 2; + } else { + sb.append("b"); + B -= 1; + } } - return sb.toString(); } - + return sb.toString(); + } } diff --git a/problems/src/heap/ReachableNodesInSubdividedGraph.java b/problems/src/heap/ReachableNodesInSubdividedGraph.java index 5fbfe0b8..eb30a9d5 100644 --- a/problems/src/heap/ReachableNodesInSubdividedGraph.java +++ b/problems/src/heap/ReachableNodesInSubdividedGraph.java @@ -1,4 +1,5 @@ package heap; + import java.util.*; /** @@ -36,75 +37,80 @@ * parallel edges. 0 <= edges[i][2] <= 10000 0 <= M <= 10^9 1 <= N <= 3000 A reachable node is a * node that can be travelled to using at most M moves starting from node 0. * - * Solution: O(E log N) E is the length of edges and N is the number of nodes. The n nodes on a edge form a weight - * and thus the graph becomes a weighted graph. Keep track of number of moves available and run a Dijkstra's algorithm. + *

Solution: O(E log N) E is the length of edges and N is the number of nodes. The n nodes on a + * edge form a weight and thus the graph becomes a weighted graph. Keep track of number of moves + * available and run a Dijkstra's algorithm. */ public class ReachableNodesInSubdividedGraph { - /** - * Main method - * @param args - */ + /** + * Main method + * + * @param args + */ public static void main(String[] args) { - int[][] edges = {{0,1,1000}, {0,2,1}, {1,2,1}}; + int[][] edges = {{0, 1, 1000}, {0, 2, 1}, {1, 2, 1}}; System.out.println(new ReachableNodesInSubdividedGraph().reachableNodes(edges, 200, 3)); } + static class Node { + int n, w; - static class Node{ - int n, w; - Node(int n, int w){ - this.n = n; - this.w = w; - } + Node(int n, int w) { + this.n = n; + this.w = w; + } } public int reachableNodes(int[][] edges, int M, int N) { Map> graph = new HashMap<>(); - for(int[] e : edges){ - graph.putIfAbsent(e[0], new ArrayList<>()); - graph.get(e[0]).add(new Node(e[1], e[2] + 1)); + for (int[] e : edges) { + graph.putIfAbsent(e[0], new ArrayList<>()); + graph.get(e[0]).add(new Node(e[1], e[2] + 1)); - graph.putIfAbsent(e[1], new ArrayList<>()); - graph.get(e[1]).add(new Node(e[0], e[2] + 1)); + graph.putIfAbsent(e[1], new ArrayList<>()); + graph.get(e[1]).add(new Node(e[0], e[2] + 1)); } PriorityQueue pq = new PriorityQueue<>(Comparator.comparingInt(o -> o.w)); Map distance = new HashMap<>(); int count = 0; pq.offer(new Node(0, 0)); - while(!pq.isEmpty()){ - Node curr = pq.poll(); - if(!distance.containsKey(curr.n)){ - count += 1; - distance.put(curr.n, curr.w); - List children = graph.get(curr.n); - if(children != null){ - for(Node c : children){ - if(!distance.containsKey(c.n)){ - int availableMoves = M - curr.w; - int nodesInBetween = c.w - 1; - if(nodesInBetween >= availableMoves){ - count += availableMoves; - } else{ - count += nodesInBetween; - if(availableMoves >= c.w){ - Node child = new Node(c.n, distance.get(curr.n) + c.w); - pq.offer(child); - } - } - } else{ - int childAvailableMoves = M - distance.get(c.n); - int nodesInBetween = c.w - 1; - int unvisitedNodes = nodesInBetween - childAvailableMoves; - if(unvisitedNodes > 0){ - int availableMovesForCurr = M - distance.get(curr.n); - count += (unvisitedNodes >= availableMovesForCurr ? availableMovesForCurr : unvisitedNodes); - } - } + while (!pq.isEmpty()) { + Node curr = pq.poll(); + if (!distance.containsKey(curr.n)) { + count += 1; + distance.put(curr.n, curr.w); + List children = graph.get(curr.n); + if (children != null) { + for (Node c : children) { + if (!distance.containsKey(c.n)) { + int availableMoves = M - curr.w; + int nodesInBetween = c.w - 1; + if (nodesInBetween >= availableMoves) { + count += availableMoves; + } else { + count += nodesInBetween; + if (availableMoves >= c.w) { + Node child = new Node(c.n, distance.get(curr.n) + c.w); + pq.offer(child); } + } + } else { + int childAvailableMoves = M - distance.get(c.n); + int nodesInBetween = c.w - 1; + int unvisitedNodes = nodesInBetween - childAvailableMoves; + if (unvisitedNodes > 0) { + int availableMovesForCurr = M - distance.get(curr.n); + count += + (unvisitedNodes >= availableMovesForCurr + ? availableMovesForCurr + : unvisitedNodes); + } } + } } + } } return count; } diff --git a/problems/src/math/ProjectionAreaOf3DShapes.java b/problems/src/math/ProjectionAreaOf3DShapes.java index c176d0f3..13de9353 100644 --- a/problems/src/math/ProjectionAreaOf3DShapes.java +++ b/problems/src/math/ProjectionAreaOf3DShapes.java @@ -35,40 +35,39 @@ * *

1 <= grid.length = grid[0].length <= 50 0 <= grid[i][j] <= 50 * - * Solution O(N x N) project the view on all three different planes. For top view its pretty - * simple because area of each cube is just 1 * 1, for all other planes take the maximum value of each - * grid. Sum up values on each planes - * + *

Solution O(N x N) project the view on all three different planes. For top view its pretty + * simple because area of each cube is just 1 * 1, for all other planes take the maximum value of + * each grid. Sum up values on each planes */ public class ProjectionAreaOf3DShapes { public static void main(String[] args) { // } - public int projectionArea(int[][] grid) { - int area = 0; - for(int i = 0; i < grid.length; i ++){ - for(int j = 0; j < grid.length; j ++){ - area += (grid[i][j] > 0 ? 1 : 0); - } - } - - for(int i = 0; i < grid.length; i ++){ - int max = 0; - for(int j = 0; j < grid[0].length; j ++){ - max = Math.max(max, grid[i][j]); - } - area += max; - } + public int projectionArea(int[][] grid) { + int area = 0; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid.length; j++) { + area += (grid[i][j] > 0 ? 1 : 0); + } + } - for(int i = 0; i < grid[0].length; i ++){ - int max = 0; - for(int j = 0; j < grid.length; j ++){ - max = Math.max(max, grid[j][i]); - } - area += max; - } + for (int i = 0; i < grid.length; i++) { + int max = 0; + for (int j = 0; j < grid[0].length; j++) { + max = Math.max(max, grid[i][j]); + } + area += max; + } - return area; + for (int i = 0; i < grid[0].length; i++) { + int max = 0; + for (int j = 0; j < grid.length; j++) { + max = Math.max(max, grid[j][i]); + } + area += max; } + + return area; + } } diff --git a/problems/src/stack/DecodedStringAtIndex.java b/problems/src/stack/DecodedStringAtIndex.java index bc94dcf0..f537a58f 100644 --- a/problems/src/stack/DecodedStringAtIndex.java +++ b/problems/src/stack/DecodedStringAtIndex.java @@ -2,67 +2,67 @@ import java.util.Stack; -/** - * Created by gouthamvidyapradhan on 12/05/2019 - */ +/** Created by gouthamvidyapradhan on 12/05/2019 */ public class DecodedStringAtIndex { public static void main(String[] args) { System.out.println(new DecodedStringAtIndex().decodeAtIndex("ha22", 5)); } - class Node{ - String S; - long count; - int multiple; - Node(String S, long count, int multiple){ - this.S = S; - this.count = count; - this.multiple = multiple; - } + class Node { + String S; + long count; + int multiple; + + Node(String S, long count, int multiple) { + this.S = S; + this.count = count; + this.multiple = multiple; } + } - public String decodeAtIndex(String S, int K) { - Stack stack = new Stack<>(); - StringBuilder sb = new StringBuilder(); - char prev = ' '; - for(char c : S.toCharArray()){ - if(Character.isDigit(c)){ - String currStr = sb.toString(); - long len = 0L; - if(!stack.isEmpty()){ - len = stack.peek().count * stack.peek().multiple; - } - stack.push(new Node(currStr, len + (currStr.length()), Integer.parseInt(String.valueOf(c)))); - if(((len + (currStr.length())) * Integer.parseInt(String.valueOf(c))) >= K){ - break; - } - prev = c; - } else{ - if(Character.isDigit(prev)){ - sb = new StringBuilder(); - } - sb.append(c); - prev = c; - } + public String decodeAtIndex(String S, int K) { + Stack stack = new Stack<>(); + StringBuilder sb = new StringBuilder(); + char prev = ' '; + for (char c : S.toCharArray()) { + if (Character.isDigit(c)) { + String currStr = sb.toString(); + long len = 0L; + if (!stack.isEmpty()) { + len = stack.peek().count * stack.peek().multiple; } - while(!stack.isEmpty()){ - Node top = stack.peek(); - long l = top.count; - if(K <= l){ - return String.valueOf(top.S.charAt((int)l - K - 1)); - } - long mod = (K % l); - if(mod == 0){ - return String.valueOf(top.S.charAt(top.S.length() - 1)); - } - if(l - top.S.length() < mod){ - long i = l - mod; - return String.valueOf(top.S.charAt(top.S.length() - (int)i - 1)); - } else{ - stack.pop(); - } + stack.push( + new Node(currStr, len + (currStr.length()), Integer.parseInt(String.valueOf(c)))); + if (((len + (currStr.length())) * Integer.parseInt(String.valueOf(c))) >= K) { + break; } - return ""; + prev = c; + } else { + if (Character.isDigit(prev)) { + sb = new StringBuilder(); + } + sb.append(c); + prev = c; + } + } + while (!stack.isEmpty()) { + Node top = stack.peek(); + long l = top.count; + if (K <= l) { + return String.valueOf(top.S.charAt((int) l - K - 1)); + } + long mod = (K % l); + if (mod == 0) { + return String.valueOf(top.S.charAt(top.S.length() - 1)); + } + if (l - top.S.length() < mod) { + long i = l - mod; + return String.valueOf(top.S.charAt(top.S.length() - (int) i - 1)); + } else { + stack.pop(); + } } + return ""; + } } diff --git a/problems/src/stack/StudentAttendanceRecordII.java b/problems/src/stack/StudentAttendanceRecordII.java index a482bfbb..4e896693 100644 --- a/problems/src/stack/StudentAttendanceRecordII.java +++ b/problems/src/stack/StudentAttendanceRecordII.java @@ -15,37 +15,43 @@ * regarded as rewardable owing to more than one absent times. Note: The value of n won't exceed * 100,000. * - * Solution O(N): Start with a base case for a single days attendance record which is 'A', 'P' and 'L' so, in total - * there are three possible records. Now, keep adding a new possible attendance record to all the above three - * possibilities. Now, since we cannot have a combination such as 'AA' we can maintain a variable with count of - * combinations which already has one 'A' in it and similarly maintain a combination which already has two 'L's it it, - * only one 'L' and only 'P' in it - keep incrementing the count of each of the variables when a new combination - * belongs to any one of this. Continue upto n and sum up the all the variables and return the answer % 10 ^ 9 + 7 + *

Solution O(N): Start with a base case for a single days attendance record which is 'A', 'P' + * and 'L' so, in total there are three possible records. Now, keep adding a new possible attendance + * record to all the above three possibilities. Now, since we cannot have a combination such as 'AA' + * we can maintain a variable with count of combinations which already has one 'A' in it and + * similarly maintain a combination which already has two 'L's it it, only one 'L' and only 'P' in + * it - keep incrementing the count of each of the variables when a new combination belongs to any + * one of this. Continue upto n and sum up the all the variables and return the answer % 10 ^ 9 + 7 */ public class StudentAttendanceRecordII { public static void main(String[] args) { System.out.println(new StudentAttendanceRecordII().checkRecord(5)); } - int mod = 1000000007; - public int checkRecord(int n) { - if(n == 0) return 1; - int P = 1; int A = 1; - int LA = 0, LX = 1, LLA = 0, LLX = 0; - for(int i = n - 1; i > 0; i --){ - int temP = (((P + LX) % mod) + LLX) % mod; - int tempLX = P; - int tempLA = A; - int tempLLX = LX; - int tempLLA = LA; - int tempA = ((((((((((P + LX) % mod) + LLX) % mod) + A) % mod) + LA) % mod) + LLA) % mod); //A + LA + LLA - // is because we can add P to each of these forming PA, PLA and PLLA - P = temP; - LX = tempLX; - LA = tempLA; - LLX = tempLLX; - LLA = tempLLA; - A = tempA; - } - return ((((((((((P + LX) % mod) + LA) % mod) + LLX) % mod) + LLA) % mod) + A) % mod); + + int mod = 1000000007; + + public int checkRecord(int n) { + if (n == 0) return 1; + int P = 1; + int A = 1; + int LA = 0, LX = 1, LLA = 0, LLX = 0; + for (int i = n - 1; i > 0; i--) { + int temP = (((P + LX) % mod) + LLX) % mod; + int tempLX = P; + int tempLA = A; + int tempLLX = LX; + int tempLLA = LA; + int tempA = + ((((((((((P + LX) % mod) + LLX) % mod) + A) % mod) + LA) % mod) + LLA) + % mod); // A + LA + LLA + // is because we can add P to each of these forming PA, PLA and PLLA + P = temP; + LX = tempLX; + LA = tempLA; + LLX = tempLLX; + LLA = tempLLA; + A = tempA; } + return ((((((((((P + LX) % mod) + LA) % mod) + LLX) % mod) + LLA) % mod) + A) % mod); + } } diff --git a/problems/src/string/ReconstructOriginalDigitsFromEnglish.java b/problems/src/string/ReconstructOriginalDigitsFromEnglish.java index a1643628..619ef629 100644 --- a/problems/src/string/ReconstructOriginalDigitsFromEnglish.java +++ b/problems/src/string/ReconstructOriginalDigitsFromEnglish.java @@ -1,5 +1,7 @@ package string; + import java.util.*; + /** * Created by gouthamvidyapradhan on 04/06/2019 Given a non-empty string containing an out-of-order * English representation of digits 0-9, output the digits in ascending order. @@ -12,76 +14,83 @@ * *

Output: "45" * - * Solution: O(N) General idea is to note some unique characters in english representation of a digit such as 'x' - * 'x' can occur only in digit 6, similarly for 'z' it can occur only for digit 0 and likewise. Keep a character - * frequency hashmap and decrement the count as and when a new digit is formed. Sort the digits and return a - * concatenated string. + *

Solution: O(N) General idea is to note some unique characters in english representation of a + * digit such as 'x' 'x' can occur only in digit 6, similarly for 'z' it can occur only for digit 0 + * and likewise. Keep a character frequency hashmap and decrement the count as and when a new digit + * is formed. Sort the digits and return a concatenated string. */ public class ReconstructOriginalDigitsFromEnglish { - public static void main(String[] args) { - System.out.println(new ReconstructOriginalDigitsFromEnglish().originalDigits("fviefurofviefurofviefurofviefurofviefurofviefurofviefurofviefurofviefurofviefuro")); - } + public static void main(String[] args) { + System.out.println( + new ReconstructOriginalDigitsFromEnglish() + .originalDigits( + "fviefurofviefurofviefurofviefurofviefurofviefurofviefurofviefurofviefurofviefuro")); + } - public String originalDigits(String s) { - Map map = new HashMap<>(); - for(char c : s.toCharArray()){ - map.putIfAbsent(c, 0); - map.put(c, map.get(c) + 1); - } - Map intMap = new HashMap<>(); - if(map.containsKey('x')){ - update(map, intMap, 6, 'x', Arrays.asList('s', 'i', 'x')); - } - if(map.containsKey('g')){ - update(map, intMap, 8, 'g', Arrays.asList('e', 'i', 'g', 'h', 't')); - } - if(map.containsKey('w')){ - update(map, intMap, 2, 'w', Arrays.asList('t', 'w', 'o')); - } - if(map.containsKey('z')){ - update(map, intMap, 0, 'z', Arrays.asList('z', 'e', 'r', 'o')); - } - if(map.containsKey('u')){ - update(map, intMap, 4, 'u', Arrays.asList('f', 'o', 'u', 'r')); - } - if(map.containsKey('f')){ - update(map, intMap, 5, 'f', Arrays.asList('f', 'i', 'v', 'e')); - } - if(map.containsKey('v')){ - update(map, intMap, 7, 'v', Arrays.asList('s', 'e', 'v', 'e', 'n')); - } - if(map.containsKey('i')){ - update(map, intMap, 9, 'i', Arrays.asList('n', 'i', 'n', 'e')); - } - if(map.containsKey('t')){ - update(map, intMap, 3, 't', Arrays.asList('t', 'h', 'r', 'e', 'e')); - } - if(map.containsKey('o')){ - update(map, intMap, 1, 'o', Arrays.asList('o', 'n', 'e')); - } - Set keys = intMap.keySet(); - List list = new ArrayList<>(keys); - list.sort(Comparator.comparingInt(o -> o)); - StringBuilder sb = new StringBuilder(); - for(int i : list){ - int count = intMap.get(i); - while(count-- > 0){ - sb.append(i); - } - } - return sb.toString(); + public String originalDigits(String s) { + Map map = new HashMap<>(); + for (char c : s.toCharArray()) { + map.putIfAbsent(c, 0); + map.put(c, map.get(c) + 1); + } + Map intMap = new HashMap<>(); + if (map.containsKey('x')) { + update(map, intMap, 6, 'x', Arrays.asList('s', 'i', 'x')); + } + if (map.containsKey('g')) { + update(map, intMap, 8, 'g', Arrays.asList('e', 'i', 'g', 'h', 't')); + } + if (map.containsKey('w')) { + update(map, intMap, 2, 'w', Arrays.asList('t', 'w', 'o')); + } + if (map.containsKey('z')) { + update(map, intMap, 0, 'z', Arrays.asList('z', 'e', 'r', 'o')); + } + if (map.containsKey('u')) { + update(map, intMap, 4, 'u', Arrays.asList('f', 'o', 'u', 'r')); + } + if (map.containsKey('f')) { + update(map, intMap, 5, 'f', Arrays.asList('f', 'i', 'v', 'e')); + } + if (map.containsKey('v')) { + update(map, intMap, 7, 'v', Arrays.asList('s', 'e', 'v', 'e', 'n')); + } + if (map.containsKey('i')) { + update(map, intMap, 9, 'i', Arrays.asList('n', 'i', 'n', 'e')); + } + if (map.containsKey('t')) { + update(map, intMap, 3, 't', Arrays.asList('t', 'h', 'r', 'e', 'e')); + } + if (map.containsKey('o')) { + update(map, intMap, 1, 'o', Arrays.asList('o', 'n', 'e')); + } + Set keys = intMap.keySet(); + List list = new ArrayList<>(keys); + list.sort(Comparator.comparingInt(o -> o)); + StringBuilder sb = new StringBuilder(); + for (int i : list) { + int count = intMap.get(i); + while (count-- > 0) { + sb.append(i); + } } + return sb.toString(); + } - private void update(Map map, Map intMap, int num, char id, - List list) { - if(map.containsKey(id)){ - int count = map.get(id); - intMap.put(num, count); - while(count-- > 0){ - for(char c : list){ - map.put(c, map.get(c) - 1); - } - } + private void update( + Map map, + Map intMap, + int num, + char id, + List list) { + if (map.containsKey(id)) { + int count = map.get(id); + intMap.put(num, count); + while (count-- > 0) { + for (char c : list) { + map.put(c, map.get(c) - 1); } + } } + } } diff --git a/problems/src/string/SplitConcatenatedStrings.java b/problems/src/string/SplitConcatenatedStrings.java index b6ef5955..eb6b8204 100644 --- a/problems/src/string/SplitConcatenatedStrings.java +++ b/problems/src/string/SplitConcatenatedStrings.java @@ -18,50 +18,49 @@ * answer string came from the fourth looped one, where you could cut from the middle character 'a' * and get "zyxcba". Note: The input strings will only contain lowercase letters. The total length * of all the strings will not over 1,000. - * */ public class SplitConcatenatedStrings { public static void main(String[] args) { - String[] A = {"abc"}; + String[] A = {"abc"}; System.out.println(new SplitConcatenatedStrings().splitLoopedString(A)); } - public String splitLoopedString(String[] strs) { - String max = ""; - for(int i = 0; i < strs.length; i ++){ - String s = strs[i]; - String result = findMax(strs, (i + 1) % strs.length); + public String splitLoopedString(String[] strs) { + String max = ""; + for (int i = 0; i < strs.length; i++) { + String s = strs[i]; + String result = findMax(strs, (i + 1) % strs.length); - String ans; - for(int k = 0, l = s.length(); k < l; k ++){ - StringBuilder sb = new StringBuilder(); - String start = s.substring(k); - String end = s.substring(0, k); - ans = sb.append(start).append(result).append(end).toString(); - max = max.compareTo(ans) > 0 ? max : ans; - } + String ans; + for (int k = 0, l = s.length(); k < l; k++) { + StringBuilder sb = new StringBuilder(); + String start = s.substring(k); + String end = s.substring(0, k); + ans = sb.append(start).append(result).append(end).toString(); + max = max.compareTo(ans) > 0 ? max : ans; + } - s = new StringBuilder(s).reverse().toString(); - for(int k = 0, l = s.length(); k < l; k ++){ - StringBuilder sb = new StringBuilder(); - String start = s.substring(k); - String end = s.substring(0, k); - ans = sb.append(start).append(result).append(end).toString(); - max = max.compareTo(ans) > 0 ? max : ans; - } - } - return max; + s = new StringBuilder(s).reverse().toString(); + for (int k = 0, l = s.length(); k < l; k++) { + StringBuilder sb = new StringBuilder(); + String start = s.substring(k); + String end = s.substring(0, k); + ans = sb.append(start).append(result).append(end).toString(); + max = max.compareTo(ans) > 0 ? max : ans; + } } + return max; + } - private String findMax(String[] strs, int i){ - int c = 1; - StringBuilder sb = new StringBuilder(); - for(int j = i, l = strs.length; c < l; j = (j + 1) % l, c++){ - String nextStr = strs[j]; - String reverse = new StringBuilder(nextStr).reverse().toString(); - String result = nextStr.compareTo(reverse) > 0 ? nextStr : reverse; - sb.append(result); - } - return sb.toString(); + private String findMax(String[] strs, int i) { + int c = 1; + StringBuilder sb = new StringBuilder(); + for (int j = i, l = strs.length; c < l; j = (j + 1) % l, c++) { + String nextStr = strs[j]; + String reverse = new StringBuilder(nextStr).reverse().toString(); + String result = nextStr.compareTo(reverse) > 0 ? nextStr : reverse; + sb.append(result); } + return sb.toString(); + } } diff --git a/problems/src/string/StudentAttendanceRecordI.java b/problems/src/string/StudentAttendanceRecordI.java index e8148583..49fddc42 100644 --- a/problems/src/string/StudentAttendanceRecordI.java +++ b/problems/src/string/StudentAttendanceRecordI.java @@ -10,22 +10,20 @@ * *

Example 1: Input: "PPALLP" Output: True Example 2: Input: "PPALLL" Output: False * - * Solution O(N) Simple linear check + *

Solution O(N) Simple linear check */ public class StudentAttendanceRecordI { - public static void main(String[] args) { - } + public static void main(String[] args) {} - public boolean checkRecord(String s) { - int count = 0; - for(int c : s.toCharArray()){ - if(c == 'A'){ - count++; - } - if(count > 1) return false; - } - if(s.contains("LLL")) return false; - return true; + public boolean checkRecord(String s) { + int count = 0; + for (int c : s.toCharArray()) { + if (c == 'A') { + count++; + } + if (count > 1) return false; } - + if (s.contains("LLL")) return false; + return true; + } } diff --git a/problems/src/string/ValidWordSquare.java b/problems/src/string/ValidWordSquare.java index 46307b8a..2205bd19 100644 --- a/problems/src/string/ValidWordSquare.java +++ b/problems/src/string/ValidWordSquare.java @@ -1,4 +1,5 @@ package string; + import java.util.*; /** @@ -40,38 +41,37 @@ * *

Therefore, it is NOT a valid word square. * - * Solution: O(N x M) where N is number of words and M is max length of a string. - * Save strings for each column and each row in a array and compare them both. + *

Solution: O(N x M) where N is number of words and M is max length of a string. Save strings + * for each column and each row in a array and compare them both. */ public class ValidWordSquare { public static void main(String[] args) { - List arr = Arrays.asList("abcd", "bnrt", "crmy", "dtye"); + List arr = Arrays.asList("abcd", "bnrt", "crmy", "dtye"); System.out.println(new ValidWordSquare().validWordSquare(arr)); } - public boolean validWordSquare(List words) { - List newList = new ArrayList<>(); - int max = 0; - for(int i = 0; i < words.size(); i ++){ - max = Math.max(max, words.get(i).length()); - } - + public boolean validWordSquare(List words) { + List newList = new ArrayList<>(); + int max = 0; + for (int i = 0; i < words.size(); i++) { + max = Math.max(max, words.get(i).length()); + } - for(int i = 0; i < max; i ++){ - StringBuilder sb = new StringBuilder(); - for(String w : words){ - if(i < w.length()){ - sb.append(w.charAt(i)); - } else break; - } - newList.add(sb.toString()); + for (int i = 0; i < max; i++) { + StringBuilder sb = new StringBuilder(); + for (String w : words) { + if (i < w.length()) { + sb.append(w.charAt(i)); + } else break; } + newList.add(sb.toString()); + } - if(words.size() != newList.size()) return false; + if (words.size() != newList.size()) return false; - for(int i = 0, l = words.size(); i < l; i ++){ - if(!words.get(i).equals(newList.get(i))) return false; - } - return true; + for (int i = 0, l = words.size(); i < l; i++) { + if (!words.get(i).equals(newList.get(i))) return false; } + return true; + } } From 83e1de54a06026139722046e41a175a3a3d9d349 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 20 Jul 2019 13:09:42 +0200 Subject: [PATCH 215/235] Solved Problems --- README.md | 1 + .../src/dynamic_programming/RemoveBoxes.java | 5 +- .../StickersToSpellWord.java | 105 ++++++++++++++++++ 3 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 problems/src/dynamic_programming/StickersToSpellWord.java diff --git a/README.md b/README.md index 3154d0be..42b8c896 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Student Attendance Record II](problems/src/dynamic_programming/StudentAttendanceRecordII.java) (Hard) - [Out of Boundary Paths](problems/src/dynamic_programming/OutOfBoundaryPaths.java) (Medium) - [Remove Boxes](problems/src/dynamic_programming/RemoveBoxes.java) (Hard) +- [Stickers to Spell Word](problems/src/dynamic_programming/StickersToSpellWord.java) (Hard) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/RemoveBoxes.java b/problems/src/dynamic_programming/RemoveBoxes.java index 77181c6c..96ac5f4f 100644 --- a/problems/src/dynamic_programming/RemoveBoxes.java +++ b/problems/src/dynamic_programming/RemoveBoxes.java @@ -12,8 +12,9 @@ * 3, 4, 3, 1] (3*3=9 points) ----> [1, 3, 3, 3, 1] (1*1=1 points) ----> [1, 1] (3*3=9 points) ----> * [] (2*2=4 points) Note: The number of boxes n would not exceed 100. * - * Solution O(N ^ 4) For each sub-array [l, r] make a dp cache and calculate maximum of [l, i][1] + [i + 1, r][1] or - * maximum of [l + 1, i - 1][n] + [i, r][1] where boxes[l] == boxes[i] where n is the count of repetitions + *

Solution O(N ^ 4) For each sub-array [l, r] make a dp cache and calculate maximum of [l, i][1] + * + [i + 1, r][1] or maximum of [l + 1, i - 1][n] + [i, r][1] where boxes[l] == boxes[i] where n is + * the count of repetitions */ public class RemoveBoxes { diff --git a/problems/src/dynamic_programming/StickersToSpellWord.java b/problems/src/dynamic_programming/StickersToSpellWord.java new file mode 100644 index 00000000..e88914dc --- /dev/null +++ b/problems/src/dynamic_programming/StickersToSpellWord.java @@ -0,0 +1,105 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 14/07/2019 We are given N different types of stickers. Each + * sticker has a lowercase English word on it. + * + *

You would like to spell out the given target string by cutting individual letters from your + * collection of stickers and rearranging them. + * + *

You can use each sticker more than once if you want, and you have infinite quantities of each + * sticker. + * + *

What is the minimum number of stickers that you need to spell out the target? If the task is + * impossible, return -1. + * + *

Example 1: + * + *

Input: + * + *

["with", "example", "science"], "thehat" Output: + * + *

3 Explanation: + * + *

We can use 2 "with" stickers, and 1 "example" sticker. After cutting and rearrange the letters + * of those stickers, we can form the target "thehat". Also, this is the minimum number of stickers + * necessary to form the target string. Example 2: + * + *

Input: + * + *

["notice", "possible"], "basicbasic" Output: + * + *

-1 Explanation: + * + *

We can't form the target "basicbasic" from cutting letters from the given stickers. Note: + * + *

stickers has length in the range [1, 50]. stickers consists of lowercase English words + * (without apostrophes). target has length in the range [1, 15], and consists of lowercase English + * letters. In all test cases, all words were chosen randomly from the 1000 most common US English + * words, and the target was chosen as a concatenation of two random words. The time limit may be + * more challenging than usual. It is expected that a 50 sticker test case can be solved within 35ms + * on average. + * + *

Solution: O(2 ^ T x T x S) where T is the length of target and S is length of sticker array. + * Each state is a combination of characters selected in the target sticker plus the total count of + * stickers used. Cache the minimum count in each state and explore all the different possible + * states. + */ +public class StickersToSpellWord { + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + String[] stickers = {"bright", "neighbor", "capital"}; + + System.out.println(new StickersToSpellWord().minStickers(stickers, "originalchair")); + } + + private int destination = 0; + private int min = Integer.MAX_VALUE; + private int[][] DP; + + public int minStickers(String[] stickers, String target) { + for (int i = 0; i < target.length(); i++) { + destination |= (1 << i); + } + DP = new int[destination][target.length() + 1]; + int answer = dp(stickers, target, 0, 0); + return answer == Integer.MAX_VALUE ? -1 : answer; + } + + private int dp(String[] stickers, String target, int curr, int count) { + if (curr == destination) { + return count; + } else { + if (count > min) return Integer.MAX_VALUE; + if (DP[curr][count] != 0) return DP[curr][count]; + DP[curr][count] = Integer.MAX_VALUE; + for (String s : stickers) { + int temp = 0; + char[] arr = s.toCharArray(); + for (int i = 0, l = target.length(); i < l; i++) { + if ((curr & (1 << i)) == 0) { + char targetChar = target.charAt(i); + for (int j = 0; j < arr.length; j++) { + if (arr[j] == targetChar) { + arr[j] = '0'; + temp |= (1 << i); + break; + } + } + } + } + if (temp > 0) { + int child = (curr | temp); + int retValue = dp(stickers, target, child, count + 1); + DP[curr][count] = Math.min(DP[curr][count], retValue); + min = Math.min(min, DP[curr][count]); + } + } + return DP[curr][count]; + } + } +} From ab16d6365d8f1b9f2bf1b86df515ee9ebc404505 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 21 Jul 2019 13:43:42 +0200 Subject: [PATCH 216/235] Solved problems --- README.md | 1 + problems/src/math/DecodedStringAtIndex.java | 70 +++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 problems/src/math/DecodedStringAtIndex.java diff --git a/README.md b/README.md index 42b8c896..3124583b 100644 --- a/README.md +++ b/README.md @@ -286,6 +286,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Nth Magical Number](problems/src/math/NthMagicalNumber.java) (Hard) - [Squirrel Simulation](problems/src/math/SquirrelSimulation.java) (Medium) - [Projection Area of 3D Shapes](problems/src/math/ProjectionAreaOf3DShapes.java) (Easy) +- [Decoded String at Index](problems/src/math/DecodedStringAtIndex.java) (Medium) #### [Reservoir Sampling](problems/src/reservoir_sampling) diff --git a/problems/src/math/DecodedStringAtIndex.java b/problems/src/math/DecodedStringAtIndex.java new file mode 100644 index 00000000..6f0e5a2e --- /dev/null +++ b/problems/src/math/DecodedStringAtIndex.java @@ -0,0 +1,70 @@ +package math; + +/** + * Created by gouthamvidyapradhan on 21/07/2019 An encoded string S is given. To find and write the + * decoded string to a tape, the encoded string is read one character at a time and the following + * steps are taken: + * + *

If the character read is a letter, that letter is written onto the tape. If the character read + * is a digit (say d), the entire current tape is repeatedly written d-1 more times in total. Now + * for some encoded string S, and an index K, find and return the K-th letter (1 indexed) in the + * decoded string. + * + *

Example 1: + * + *

Input: S = "leet2code3", K = 10 Output: "o" Explanation: The decoded string is + * "leetleetcodeleetleetcodeleetleetcode". The 10th letter in the string is "o". Example 2: + * + *

Input: S = "ha22", K = 5 Output: "h" Explanation: The decoded string is "hahahaha". The 5th + * letter is "h". Example 3: + * + *

Input: S = "a2345678999999999999999", K = 1 Output: "a" Explanation: The decoded string is "a" + * repeated 8301530446056247680 times. The 1st letter is "a". + * + *

Note: + * + *

2 <= S.length <= 100 S will only contain lowercase letters and digits 2 through 9. S starts + * with a letter. 1 <= K <= 10^9 The decoded string is guaranteed to have less than 2^63 letters. + * + *

Solution: General idea is as shown below example: If S = "leet2" and K = 6 the answer is "e" + * which is same as finding answer for K = 2. As soon as the product exceeds the total value of K as + * in this case the product of 4 (leet) x 2 is 8 and 8 clearly exceeds 6 therefore we can reduce K + * to 8 - 6 = 2 and start from the beginning once again. Repeat the same process until we reach the + * answer. + */ +public class DecodedStringAtIndex { + public static void main(String[] args) { + System.out.println( + new DecodedStringAtIndex().decodeAtIndex("a2345678999999999999999", 1000000000)); + } + + public String decodeAtIndex(String S, int K) { + long product = 0; + char lastC = S.charAt(0); + for (int i = 0, l = S.length(); i < l; ) { + char c = S.charAt(i); + if (Character.isLetter(c)) { + lastC = c; + product++; + i++; + if (K == product) break; + } else { + long temp = (product * Integer.parseInt(String.valueOf(c))); + if (temp == K) break; + else { + if (temp > K) { + long x = (K / product); + if ((product * x) == K) break; + K -= (product * x); + i = 0; + product = 0; + } else { + product = temp; + i++; + } + } + } + } + return String.valueOf(lastC); + } +} From 07772408b691545ddf295ae19acad5aac3d2bd60 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 28 Jul 2019 13:02:11 +0200 Subject: [PATCH 217/235] Solved Problems --- .../src/array/AddToArrayFormOfInteger.java | 26 +++++ .../SatisfiabilityOfEquations.java | 102 ++++++++++++++++++ problems/src/greedy/BrokenCalculator.java | 58 ++++++++++ problems/src/string/PushDominoes.java | 75 +++++++++++++ .../SubarraysWithKDifferentIntegers.java | 56 ++++++++++ 5 files changed, 317 insertions(+) create mode 100644 problems/src/array/AddToArrayFormOfInteger.java create mode 100644 problems/src/depth_first_search/SatisfiabilityOfEquations.java create mode 100644 problems/src/greedy/BrokenCalculator.java create mode 100644 problems/src/string/PushDominoes.java create mode 100644 problems/src/two_pointers/SubarraysWithKDifferentIntegers.java diff --git a/problems/src/array/AddToArrayFormOfInteger.java b/problems/src/array/AddToArrayFormOfInteger.java new file mode 100644 index 00000000..bdb529b5 --- /dev/null +++ b/problems/src/array/AddToArrayFormOfInteger.java @@ -0,0 +1,26 @@ +package heap; +import java.math.BigInteger; +import java.util.*; +/** + * Created by gouthamvidyapradhan on 25/07/2019 + */ +public class Task1 { + public static void main(String[] args) { + // + } + + public List addToArrayForm(int[] A, int K) { + StringBuilder sb = new StringBuilder(); + for(int a : A){ + sb.append(a); + } + BigInteger big = new BigInteger(sb.toString()); + BigInteger result = big.add(BigInteger.valueOf(K)); + String resultStr = result.toString(); + List list = new ArrayList<>(); + for(char a : resultStr.toCharArray()){ + list.add(Integer.parseInt(String.valueOf(a))); + } + return list; + } +} diff --git a/problems/src/depth_first_search/SatisfiabilityOfEquations.java b/problems/src/depth_first_search/SatisfiabilityOfEquations.java new file mode 100644 index 00000000..4c967986 --- /dev/null +++ b/problems/src/depth_first_search/SatisfiabilityOfEquations.java @@ -0,0 +1,102 @@ +package heap; +import java.util.*; +/** + * Created by gouthamvidyapradhan on 25/07/2019 Given an array equations of strings that represent + * relationships between variables, each string equations[i] has length 4 and takes one of two + * different forms: "a==b" or "a!=b". Here, a and b are lowercase letters (not necessarily + * different) that represent one-letter variable names. + * + *

Return true if and only if it is possible to assign integers to variable names so as to + * satisfy all the given equations. + * + *

Example 1: + * + *

Input: ["a==b","b!=a"] Output: false Explanation: If we assign say, a = 1 and b = 1, then the + * first equation is satisfied, but not the second. There is no way to assign the variables to + * satisfy both equations. Example 2: + * + *

Input: ["b==a","a==b"] Output: true Explanation: We could assign a = 1 and b = 1 to satisfy + * both equations. Example 3: + * + *

Input: ["a==b","b==c","a==c"] Output: true Example 4: + * + *

Input: ["a==b","b!=c","c==a"] Output: false Example 5: + * + *

Input: ["c==c","b==d","x!=z"] Output: true + * + *

Note: + * + *

1 <= equations.length <= 500 equations[i].length == 4 equations[i][0] and equations[i][3] are + * lowercase letters equations[i][1] is either '=' or '!' equations[i][2] is '=' + * + * Solution: O(N) For all the equations which are of the form 'a==b' form a graph of connected components. Start + * assigning values to each of the connected components. All the nodes in the connected components should have the + * same value assigned - If any of the connected components fails this criteria + * then return false. + */ +public class Task2 { + public static void main(String[] args) { + String[] input = {"c==c","f!=a","f==b","b==c"}; + System.out.println(new Task2().equationsPossible(input)); + } + + private Set done; + private Map valueMap; + private int count = 0; + public boolean equationsPossible(String[] equations) { + Map> graph = new HashMap<>(); + done = new HashSet<>(); + valueMap = new HashMap<>(); + for(String eq : equations){ + if(eq.charAt(1) == '='){ + graph.putIfAbsent(eq.charAt(0), new ArrayList<>()); + graph.get(eq.charAt(0)).add(eq.charAt(3)); + graph.putIfAbsent(eq.charAt(3), new ArrayList<>()); + graph.get(eq.charAt(3)).add(eq.charAt(0)); + + } + } + for(char c : graph.keySet()){ + if(!done.contains(c)){ + dfs(c, graph, ++count); + } + } + + for(String eq : equations){ + if(eq.charAt(1) == '!'){ + char a = eq.charAt(0); + char b = eq.charAt(3); + if(a == b) return false; + if(valueMap.containsKey(a) && valueMap.containsKey(b)){ + if(valueMap.get(a).intValue() == valueMap.get(b).intValue()){ + return false; + } + } + } + } + return true; + } + + + private boolean dfs(char node, Map> graph, int value){ + done.add(node); + valueMap.put(node, value); + List children = graph.get(node); + if(!children.isEmpty()){ + for(char c : children){ + if(!done.contains(c)){ + boolean status = dfs(c, graph, value); + if(!status) { + return status; + } + } else{ + if(valueMap.get(c) != value){ + return false; + } + } + } + } + return true; + } + +} diff --git a/problems/src/greedy/BrokenCalculator.java b/problems/src/greedy/BrokenCalculator.java new file mode 100644 index 00000000..ce0cffce --- /dev/null +++ b/problems/src/greedy/BrokenCalculator.java @@ -0,0 +1,58 @@ +package heap; +import java.util.*; +/** + * Created by gouthamvidyapradhan on 25/07/2019 On a broken calculator that has a number showing on + * its display, we can perform two operations: + * + *

Double: Multiply the number on the display by 2, or; Decrement: Subtract 1 from the number on + * the display. Initially, the calculator is displaying the number X. + * + *

Return the minimum number of operations needed to display the number Y. + * + *

Example 1: + * + *

Input: X = 2, Y = 3 Output: 2 Explanation: Use double operation and then decrement operation + * {2 -> 4 -> 3}. Example 2: + * + *

Input: X = 5, Y = 8 Output: 2 Explanation: Use decrement and then double {5 -> 4 -> 8}. + * Example 3: + * + *

Input: X = 3, Y = 10 Output: 3 Explanation: Use double, decrement and double {3 -> 6 -> 5 -> + * 10}. Example 4: + * + *

Input: X = 1024, Y = 1 Output: 1023 Explanation: Use decrement operations 1023 times. + * + *

Note: + * + *

1 <= X <= 10^9 1 <= Y <= 10^9 + * + * Solution: O(log Y) Arrive at the solution by working backwards starting from Y. + * General idea is as follows. + * If Y is even then find the minimum steps required to arrive at Y by finding the quotient after dividing by 2. If Y + * is odd then find the minimum steps required to arrive at Y + 1 (even number) + 1 (to move backwards) + */ +public class BrokenCalculator { + public static void main(String[] args) { + // + } + + public int brokenCalc(int X, int Y) { + if(X == Y) return 0; + else if(Y < X) return X - Y; + else { + int count = 0; + while(Y > X){ + if(Y % 2 == 0){ + Y /= 2; + count++; + } else{ + Y += 1; + Y /= 2; + count+=2; + } + } + if(X == Y) return count; + else return count + (X - Y); + } + } +} diff --git a/problems/src/string/PushDominoes.java b/problems/src/string/PushDominoes.java new file mode 100644 index 00000000..c14fc9bc --- /dev/null +++ b/problems/src/string/PushDominoes.java @@ -0,0 +1,75 @@ +package math; +import java.util.*; +/** + * Created by gouthamvidyapradhan on 24/07/2019 There are N dominoes in a line, and we place each + * domino vertically upright. + * + *

In the beginning, we simultaneously push some of the dominoes either to the left or to the + * right. + * + *

After each second, each domino that is falling to the left pushes the adjacent domino on the + * left. + * + *

Similarly, the dominoes falling to the right push their adjacent dominoes standing on the + * right. + * + *

When a vertical domino has dominoes falling on it from both sides, it stays still due to the + * balance of the forces. + * + *

For the purposes of this question, we will consider that a falling domino expends no + * additional force to a falling or already fallen domino. + * + *

Given a string "S" representing the initial state. S[i] = 'L', if the i-th domino has been + * pushed to the left; S[i] = 'R', if the i-th domino has been pushed to the right; S[i] = '.', if + * the i-th domino has not been pushed. + * + *

Return a string representing the final state. + * + *

Example 1: + * + *

Input: ".L.R...LR..L.." Output: "LL.RR.LLRRLL.." Example 2: + * + *

Input: "RR.L" Output: "RR.L" Explanation: The first domino expends no additional force on the + * second domino. Note: + * + *

0 <= N <= 10^5 String dominoes contains only 'L', 'R' and '.' + */ +public class Task2 { + public static void main(String[] args) { + System.out.println(new Task2().pushDominoes("RR.L")); + } + + public String pushDominoes(String dominoes) { + int R = -1, L = -1; + char[] A = dominoes.toCharArray(); + for(int i = 0; i < A.length; i ++){ + if(A[i] == 'L'){ + if(R > L){ + int d = (i - R); + int st; + st = R + d/2; + if((d % 2) == 0){ + A[st] = '.'; + } + for(int j = st + 1; j < i; j ++){ + A[j] = 'L'; + } + } else{ + for(int j = (L == -1 ? 0 : L); j < i; j ++){ + A[j] = 'L'; + } + } + L = i; + } else { + if(A[i] == 'R'){ + R = i; + } else{ + if(R > L){ + A[i] = 'R'; + } + } + } + } + return String.valueOf(A); + } +} diff --git a/problems/src/two_pointers/SubarraysWithKDifferentIntegers.java b/problems/src/two_pointers/SubarraysWithKDifferentIntegers.java new file mode 100644 index 00000000..deb86444 --- /dev/null +++ b/problems/src/two_pointers/SubarraysWithKDifferentIntegers.java @@ -0,0 +1,56 @@ +package two_pointers; +/** + * Created by gouthamvidyapradhan on 25/07/2019 Given an array A of positive integers, call a + * (contiguous, not necessarily distinct) subarray of A good if the number of different integers in + * that subarray is exactly K. + * + *

(For example, [1,2,3,1,2] has 3 different integers: 1, 2, and 3.) + * + *

Return the number of good subarrays of A. + * + *

Example 1: + * + *

Input: A = [1,2,1,2,3], K = 2 Output: 7 Explanation: Subarrays formed with exactly 2 different + * integers: [1,2], [2,1], [1,2], [2,3], [1,2,1], [2,1,2], [1,2,1,2]. Example 2: + * + *

Input: A = [1,2,1,3,4], K = 3 Output: 3 Explanation: Subarrays formed with exactly 3 different + * integers: [1,2,1,3], [2,1,3], [1,3,4]. + * + *

Note: + * + *

1 <= A.length <= 20000 1 <= A[i] <= A.length 1 <= K <= A.length + * Solution: O(N) General idea is to find subarraysWithKDistinct(A, atMost(K)) - subarraysWithKDistinct(A, atMost(K - + * 1)). + */ +public class Task4 { + public static void main(String[] args) { + int[] A = {1,2,1,2,3}; + Task4 task = new Task4(); + System.out.println(task.subarraysWithKDistinct(A, 2)); + } + + public int subarraysWithKDistinct(int[] A, int K) { + return calculate(A, K) - calculate(A, K - 1); + } + + private int calculate(int[] A, int K) { + int count = 0; + int[] frequency = new int[A.length + 1]; + int currCount = 0; + for(int i = 0, j = 0; i < A.length; i ++){ + frequency[A[i]]++; + if(frequency[A[i]] == 1){ + currCount ++; + } + while(currCount > K){ + frequency[A[j]]--; + if(frequency[A[j]] == 0){ + currCount --; + } + j++; + } + count += (i - j + 1); + } + return count; + } +} From 9a2e79491db675d2f857d96f49e27f281db3323a Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 28 Jul 2019 13:02:25 +0200 Subject: [PATCH 218/235] Solved Problems --- README.md | 5 + .../src/array/AddToArrayFormOfInteger.java | 54 +++++--- .../SatisfiabilityOfEquations.java | 120 +++++++++--------- problems/src/greedy/BrokenCalculator.java | 46 +++---- problems/src/string/PushDominoes.java | 72 +++++------ .../SubarraysWithKDifferentIntegers.java | 53 ++++---- 6 files changed, 190 insertions(+), 160 deletions(-) diff --git a/README.md b/README.md index 3124583b..93a65217 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Surface Area of 3D Shapes](problems/src/array/SurfaceAreaOfThreeDShapes.java) (Easy) - [Max Consecutive Ones](problems/src/array/MaxConsecutiveOnes.java) (Easy) - [Max Consecutive Ones II](problems/src/array/MaxConsecutiveOnesII.java) (Medium) +- [Add to Array-Form of Integer](problems/src/array/AddToArrayFormOfInteger.java) (Easy) #### [Backtracking](problems/src/backtracking) @@ -129,6 +130,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Cracking the Safe](problems/src/depth_first_search/CrackingTheSafe.java) (Hard) - [All Paths From Source to Target](problems/src/depth_first_search/AllPathsFromSourceToTarget.java) (Medium) - [Max Area of Island](problems/src/depth_first_search/MaxAreaOfIsland.java) (Medium) +- [Satisfiability of Equality Equations](problems/src/depth_first_search/SatisfiabilityOfEquations.java) (Medium) #### [Design](problems/src/design) @@ -226,6 +228,7 @@ My accepted leetcode solutions to some of the common interview problems. - [IPO](problems/src/greedy/IPO.java) (Hard) - [String Without AAA or BBB](problems/src/greedy/StringWithout3A3B.java) (Medium) - [Boats to Save People](problems/src/greedy/BoatsToSavePeople.java) (Medium) +- [Broken Calculator](problems/src/greedy/BrokenCalculator.java) (Medium) #### [Hashing](problems/src/hashing) @@ -341,6 +344,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Split Concatenated Strings](problems/src/string/SplitConcatenatedStrings.java) (Medium) - [Valid Word Square](problems/src/string/ValidWordSquare.java) (Easy) - [Reconstruct Original Digits from English](problems/src/string/ReconstructOriginalDigitsFromEnglish.java) (Medium) +- [Push Dominoes](problems/src/string/PushDominoes.java) (Medium) #### [Tree](problems/src/tree) @@ -404,4 +408,5 @@ My accepted leetcode solutions to some of the common interview problems. - [Smallest Range](problems/src/two_pointers/SmallestRange.java) (Hard) - [Subarray Product Less Than K](problems/src/two_pointers/SubarrayProductLessThanK.java) (Medium) - [Number of Matching Subsequences](problems/src/two_pointers/NumberOfMatchingSubsequences.java) (Medium) +- [Subarrays with K Different Integers](problems/src/two_pointers/SubarraysWithKDifferentIntegers.java) (Hard) diff --git a/problems/src/array/AddToArrayFormOfInteger.java b/problems/src/array/AddToArrayFormOfInteger.java index bdb529b5..35f9c30e 100644 --- a/problems/src/array/AddToArrayFormOfInteger.java +++ b/problems/src/array/AddToArrayFormOfInteger.java @@ -1,26 +1,50 @@ -package heap; +package array; + import java.math.BigInteger; import java.util.*; + /** * Created by gouthamvidyapradhan on 25/07/2019 + * + *

For a non-negative integer X, the array-form of X is an array of its digits in left to right + * order. For example, if X = 1231, then the array form is [1,2,3,1]. + * + *

Given the array-form A of a non-negative integer X, return the array-form of the integer X+K. + * + *

Example 1: + * + *

Input: A = [1,2,0,0], K = 34 Output: [1,2,3,4] Explanation: 1200 + 34 = 1234 Example 2: + * + *

Input: A = [2,7,4], K = 181 Output: [4,5,5] Explanation: 274 + 181 = 455 Example 3: + * + *

Input: A = [2,1,5], K = 806 Output: [1,0,2,1] Explanation: 215 + 806 = 1021 Example 4: + * + *

Input: A = [9,9,9,9,9,9,9,9,9,9], K = 1 Output: [1,0,0,0,0,0,0,0,0,0,0] Explanation: + * 9999999999 + 1 = 10000000000 + * + *

Note: + * + *

1 <= A.length <= 10000 0 <= A[i] <= 9 0 <= K <= 10000 If A.length > 1, then A[0] != 0 + * + *

Solution: O(N) use BigInteger to add long numbers */ -public class Task1 { +public class AddToArrayFormOfInteger { public static void main(String[] args) { // } - public List addToArrayForm(int[] A, int K) { - StringBuilder sb = new StringBuilder(); - for(int a : A){ - sb.append(a); - } - BigInteger big = new BigInteger(sb.toString()); - BigInteger result = big.add(BigInteger.valueOf(K)); - String resultStr = result.toString(); - List list = new ArrayList<>(); - for(char a : resultStr.toCharArray()){ - list.add(Integer.parseInt(String.valueOf(a))); - } - return list; + public List addToArrayForm(int[] A, int K) { + StringBuilder sb = new StringBuilder(); + for (int a : A) { + sb.append(a); } + BigInteger big = new BigInteger(sb.toString()); + BigInteger result = big.add(BigInteger.valueOf(K)); + String resultStr = result.toString(); + List list = new ArrayList<>(); + for (char a : resultStr.toCharArray()) { + list.add(Integer.parseInt(String.valueOf(a))); + } + return list; + } } diff --git a/problems/src/depth_first_search/SatisfiabilityOfEquations.java b/problems/src/depth_first_search/SatisfiabilityOfEquations.java index 4c967986..2e6ce48d 100644 --- a/problems/src/depth_first_search/SatisfiabilityOfEquations.java +++ b/problems/src/depth_first_search/SatisfiabilityOfEquations.java @@ -1,5 +1,7 @@ -package heap; +package depth_first_search; + import java.util.*; + /** * Created by gouthamvidyapradhan on 25/07/2019 Given an array equations of strings that represent * relationships between variables, each string equations[i] has length 4 and takes one of two @@ -29,74 +31,72 @@ *

1 <= equations.length <= 500 equations[i].length == 4 equations[i][0] and equations[i][3] are * lowercase letters equations[i][1] is either '=' or '!' equations[i][2] is '=' * - * Solution: O(N) For all the equations which are of the form 'a==b' form a graph of connected components. Start - * assigning values to each of the connected components. All the nodes in the connected components should have the - * same value assigned - If any of the connected components fails this criteria - * then return false. + *

Solution: O(N) For all the equations which are of the form 'a==b' form a graph of connected + * components. Start assigning values to each of the connected components. All the nodes in the + * connected components should have the same value assigned - If any of the connected components + * fails this criteria then return false. */ -public class Task2 { +public class SatisfiabilityOfEquations { public static void main(String[] args) { - String[] input = {"c==c","f!=a","f==b","b==c"}; - System.out.println(new Task2().equationsPossible(input)); + String[] input = {"c==c", "f!=a", "f==b", "b==c"}; + System.out.println(new SatisfiabilityOfEquations().equationsPossible(input)); } - private Set done; - private Map valueMap; - private int count = 0; - public boolean equationsPossible(String[] equations) { - Map> graph = new HashMap<>(); - done = new HashSet<>(); - valueMap = new HashMap<>(); - for(String eq : equations){ - if(eq.charAt(1) == '='){ - graph.putIfAbsent(eq.charAt(0), new ArrayList<>()); - graph.get(eq.charAt(0)).add(eq.charAt(3)); - graph.putIfAbsent(eq.charAt(3), new ArrayList<>()); - graph.get(eq.charAt(3)).add(eq.charAt(0)); + private Set done; + private Map valueMap; + private int count = 0; - } - } - for(char c : graph.keySet()){ - if(!done.contains(c)){ - dfs(c, graph, ++count); - } - } + public boolean equationsPossible(String[] equations) { + Map> graph = new HashMap<>(); + done = new HashSet<>(); + valueMap = new HashMap<>(); + for (String eq : equations) { + if (eq.charAt(1) == '=') { + graph.putIfAbsent(eq.charAt(0), new ArrayList<>()); + graph.get(eq.charAt(0)).add(eq.charAt(3)); + graph.putIfAbsent(eq.charAt(3), new ArrayList<>()); + graph.get(eq.charAt(3)).add(eq.charAt(0)); + } + } + for (char c : graph.keySet()) { + if (!done.contains(c)) { + dfs(c, graph, ++count); + } + } - for(String eq : equations){ - if(eq.charAt(1) == '!'){ - char a = eq.charAt(0); - char b = eq.charAt(3); - if(a == b) return false; - if(valueMap.containsKey(a) && valueMap.containsKey(b)){ - if(valueMap.get(a).intValue() == valueMap.get(b).intValue()){ - return false; - } - } - } + for (String eq : equations) { + if (eq.charAt(1) == '!') { + char a = eq.charAt(0); + char b = eq.charAt(3); + if (a == b) return false; + if (valueMap.containsKey(a) && valueMap.containsKey(b)) { + if (valueMap.get(a).intValue() == valueMap.get(b).intValue()) { + return false; + } } - return true; + } } + return true; + } - - private boolean dfs(char node, Map> graph, int value){ - done.add(node); - valueMap.put(node, value); - List children = graph.get(node); - if(!children.isEmpty()){ - for(char c : children){ - if(!done.contains(c)){ - boolean status = dfs(c, graph, value); - if(!status) { - return status; - } - } else{ - if(valueMap.get(c) != value){ - return false; - } - } - } + private boolean dfs(char node, Map> graph, int value) { + done.add(node); + valueMap.put(node, value); + List children = graph.get(node); + if (!children.isEmpty()) { + for (char c : children) { + if (!done.contains(c)) { + boolean status = dfs(c, graph, value); + if (!status) { + return status; + } + } else { + if (valueMap.get(c) != value) { + return false; + } } - return true; + } } - + return true; + } } diff --git a/problems/src/greedy/BrokenCalculator.java b/problems/src/greedy/BrokenCalculator.java index ce0cffce..a65becad 100644 --- a/problems/src/greedy/BrokenCalculator.java +++ b/problems/src/greedy/BrokenCalculator.java @@ -1,5 +1,7 @@ -package heap; +package greedy; + import java.util.*; + /** * Created by gouthamvidyapradhan on 25/07/2019 On a broken calculator that has a number showing on * its display, we can perform two operations: @@ -26,33 +28,33 @@ * *

1 <= X <= 10^9 1 <= Y <= 10^9 * - * Solution: O(log Y) Arrive at the solution by working backwards starting from Y. - * General idea is as follows. - * If Y is even then find the minimum steps required to arrive at Y by finding the quotient after dividing by 2. If Y - * is odd then find the minimum steps required to arrive at Y + 1 (even number) + 1 (to move backwards) + *

Solution: O(log Y) Arrive at the solution by working backwards starting from Y. General idea + * is as follows. If Y is even then find the minimum steps required to arrive at Y by finding the + * quotient after dividing by 2. If Y is odd then find the minimum steps required to arrive at Y + 1 + * (even number) + 1 (to move backwards) */ public class BrokenCalculator { public static void main(String[] args) { // } - public int brokenCalc(int X, int Y) { - if(X == Y) return 0; - else if(Y < X) return X - Y; - else { - int count = 0; - while(Y > X){ - if(Y % 2 == 0){ - Y /= 2; - count++; - } else{ - Y += 1; - Y /= 2; - count+=2; - } - } - if(X == Y) return count; - else return count + (X - Y); + public int brokenCalc(int X, int Y) { + if (X == Y) return 0; + else if (Y < X) return X - Y; + else { + int count = 0; + while (Y > X) { + if (Y % 2 == 0) { + Y /= 2; + count++; + } else { + Y += 1; + Y /= 2; + count += 2; } + } + if (X == Y) return count; + else return count + (X - Y); } + } } diff --git a/problems/src/string/PushDominoes.java b/problems/src/string/PushDominoes.java index c14fc9bc..83b8a0cc 100644 --- a/problems/src/string/PushDominoes.java +++ b/problems/src/string/PushDominoes.java @@ -1,5 +1,5 @@ -package math; -import java.util.*; +package string; + /** * Created by gouthamvidyapradhan on 24/07/2019 There are N dominoes in a line, and we place each * domino vertically upright. @@ -32,44 +32,44 @@ *

Input: "RR.L" Output: "RR.L" Explanation: The first domino expends no additional force on the * second domino. Note: * - *

0 <= N <= 10^5 String dominoes contains only 'L', 'R' and '.' + *

0 <= N <= 10^5 String dominoes contains only 'L', 'R' and '.' Solution: O(N) */ -public class Task2 { +public class PushDominoes { public static void main(String[] args) { - System.out.println(new Task2().pushDominoes("RR.L")); + System.out.println(new PushDominoes().pushDominoes("RR.L")); } - public String pushDominoes(String dominoes) { - int R = -1, L = -1; - char[] A = dominoes.toCharArray(); - for(int i = 0; i < A.length; i ++){ - if(A[i] == 'L'){ - if(R > L){ - int d = (i - R); - int st; - st = R + d/2; - if((d % 2) == 0){ - A[st] = '.'; - } - for(int j = st + 1; j < i; j ++){ - A[j] = 'L'; - } - } else{ - for(int j = (L == -1 ? 0 : L); j < i; j ++){ - A[j] = 'L'; - } - } - L = i; - } else { - if(A[i] == 'R'){ - R = i; - } else{ - if(R > L){ - A[i] = 'R'; - } - } - } + public String pushDominoes(String dominoes) { + int R = -1, L = -1; + char[] A = dominoes.toCharArray(); + for (int i = 0; i < A.length; i++) { + if (A[i] == 'L') { + if (R > L) { + int d = (i - R); + int st; + st = R + d / 2; + if ((d % 2) == 0) { + A[st] = '.'; + } + for (int j = st + 1; j < i; j++) { + A[j] = 'L'; + } + } else { + for (int j = (L == -1 ? 0 : L); j < i; j++) { + A[j] = 'L'; + } + } + L = i; + } else { + if (A[i] == 'R') { + R = i; + } else { + if (R > L) { + A[i] = 'R'; + } } - return String.valueOf(A); + } } + return String.valueOf(A); + } } diff --git a/problems/src/two_pointers/SubarraysWithKDifferentIntegers.java b/problems/src/two_pointers/SubarraysWithKDifferentIntegers.java index deb86444..ef1357e2 100644 --- a/problems/src/two_pointers/SubarraysWithKDifferentIntegers.java +++ b/problems/src/two_pointers/SubarraysWithKDifferentIntegers.java @@ -18,39 +18,38 @@ * *

Note: * - *

1 <= A.length <= 20000 1 <= A[i] <= A.length 1 <= K <= A.length - * Solution: O(N) General idea is to find subarraysWithKDistinct(A, atMost(K)) - subarraysWithKDistinct(A, atMost(K - - * 1)). + *

1 <= A.length <= 20000 1 <= A[i] <= A.length 1 <= K <= A.length Solution: O(N) General idea is + * to find subarraysWithKDistinct(A, atMost(K)) - subarraysWithKDistinct(A, atMost(K - 1)). */ -public class Task4 { +public class SubarraysWithKDifferentIntegers { public static void main(String[] args) { - int[] A = {1,2,1,2,3}; - Task4 task = new Task4(); + int[] A = {1, 2, 1, 2, 3}; + SubarraysWithKDifferentIntegers task = new SubarraysWithKDifferentIntegers(); System.out.println(task.subarraysWithKDistinct(A, 2)); } - public int subarraysWithKDistinct(int[] A, int K) { - return calculate(A, K) - calculate(A, K - 1); - } + public int subarraysWithKDistinct(int[] A, int K) { + return calculate(A, K) - calculate(A, K - 1); + } - private int calculate(int[] A, int K) { - int count = 0; - int[] frequency = new int[A.length + 1]; - int currCount = 0; - for(int i = 0, j = 0; i < A.length; i ++){ - frequency[A[i]]++; - if(frequency[A[i]] == 1){ - currCount ++; - } - while(currCount > K){ - frequency[A[j]]--; - if(frequency[A[j]] == 0){ - currCount --; - } - j++; - } - count += (i - j + 1); + private int calculate(int[] A, int K) { + int count = 0; + int[] frequency = new int[A.length + 1]; + int currCount = 0; + for (int i = 0, j = 0; i < A.length; i++) { + frequency[A[i]]++; + if (frequency[A[i]] == 1) { + currCount++; + } + while (currCount > K) { + frequency[A[j]]--; + if (frequency[A[j]] == 0) { + currCount--; } - return count; + j++; + } + count += (i - j + 1); } + return count; + } } From cb44265d4571eccf803d5bf78e1b0fcf737bbab6 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 10 Aug 2019 13:03:14 +0200 Subject: [PATCH 219/235] Solved Problems --- README.md | 19 ++- problems/src/array/FindPivotIndex.java | 65 ++++++++ .../src/array/LargestTimeForGivenDigits.java | 54 +++++++ problems/src/array/MinimumTimeDifference.java | 40 +++++ .../MinimumWindowSubsequence.java | 79 ++++++++++ .../depth_first_search/NumberOfEnclaves.java | 75 +++++++++ .../divide_and_conquer/ReversePairsII.java | 86 ++++++++++ .../dynamic_programming/OnesAndZeroes.java | 64 ++++++++ problems/src/hashing/NumberOfAtoms.java | 147 ++++++++++++++++++ .../NextGreaterNodeInLinkedList.java | 89 +++++++++++ .../linked_list/SplitLinkedListInParts.java | 89 +++++++++++ problems/src/math/Base7.java | 29 ++++ problems/src/string/ReverseStringII.java | 37 +++++ problems/src/string/ValidateIPAddress.java | 94 +++++++++++ .../tree/ConstructBinaryTreefromString.java | 88 +++++++++++ .../src/tree/FindBottomLeftTreeValue.java | 10 +- .../tree/FindLargestValueInEachTreeRow.java | 61 ++++++++ .../src/tree/FlipEquivalentBinaryTrees.java | 124 +++++++++++++++ 18 files changed, 1245 insertions(+), 5 deletions(-) create mode 100644 problems/src/array/FindPivotIndex.java create mode 100644 problems/src/array/LargestTimeForGivenDigits.java create mode 100644 problems/src/array/MinimumTimeDifference.java create mode 100644 problems/src/binary_search/MinimumWindowSubsequence.java create mode 100644 problems/src/depth_first_search/NumberOfEnclaves.java create mode 100644 problems/src/divide_and_conquer/ReversePairsII.java create mode 100644 problems/src/dynamic_programming/OnesAndZeroes.java create mode 100644 problems/src/hashing/NumberOfAtoms.java create mode 100644 problems/src/linked_list/NextGreaterNodeInLinkedList.java create mode 100644 problems/src/linked_list/SplitLinkedListInParts.java create mode 100644 problems/src/math/Base7.java create mode 100644 problems/src/string/ReverseStringII.java create mode 100644 problems/src/string/ValidateIPAddress.java create mode 100644 problems/src/tree/ConstructBinaryTreefromString.java create mode 100644 problems/src/tree/FindLargestValueInEachTreeRow.java create mode 100644 problems/src/tree/FlipEquivalentBinaryTrees.java diff --git a/README.md b/README.md index 93a65217..4daf89ac 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,9 @@ My accepted leetcode solutions to some of the common interview problems. - [Max Consecutive Ones](problems/src/array/MaxConsecutiveOnes.java) (Easy) - [Max Consecutive Ones II](problems/src/array/MaxConsecutiveOnesII.java) (Medium) - [Add to Array-Form of Integer](problems/src/array/AddToArrayFormOfInteger.java) (Easy) +- [Find Pivot Index](problems/src/array/FindPivotIndex.java) (Easy) +- [Largest Time for Given Digits](problems/src/array/LargestTimeForGivenDigits.java) (Easy) +- [Minimum Time Difference](problems/src/array/MinimumTimeDifference.java) (Medium) #### [Backtracking](problems/src/backtracking) @@ -87,6 +90,7 @@ My accepted leetcode solutions to some of the common interview problems. - [H-Index II](problems/src/binary_search/HIndexII.java) (Medium) - [Swim in Rising Water](problems/src/binary_search/SwimInRisingWater.java) (Hard) - [Time Based Key-Value Store](problems/src/binary_search/TimeBasedKeyValuePair.java) (Medium) +- [Minimum Window Subsequence](problems/src/binary_search/MinimumWindowSubsequence.java) (Hard) #### [Bit Manipulation](problems/src/bit_manipulation) @@ -131,6 +135,7 @@ My accepted leetcode solutions to some of the common interview problems. - [All Paths From Source to Target](problems/src/depth_first_search/AllPathsFromSourceToTarget.java) (Medium) - [Max Area of Island](problems/src/depth_first_search/MaxAreaOfIsland.java) (Medium) - [Satisfiability of Equality Equations](problems/src/depth_first_search/SatisfiabilityOfEquations.java) (Medium) +- [Number of Enclaves](problems/src/depth_first_search/NumberOfEnclaves.java) (Medium) #### [Design](problems/src/design) @@ -157,6 +162,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Reverse Pairs](problems/src/divide_and_conquer/ReversePairs.java) (Hard) - [Search in a 2D Matrix](problems/src/divide_and_conquer/SearchA2DMatrix.java) (Medium) - [24 Game](problems/src/divide_and_conquer/TwentyFourGame.java) (Hard) +- [Reverse Pairs II](problems/src/divide_and_conquer/ReversePairsII.java) (Hard) #### [Dynamic Programming](problems/src/dynamic_programming) @@ -211,6 +217,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Out of Boundary Paths](problems/src/dynamic_programming/OutOfBoundaryPaths.java) (Medium) - [Remove Boxes](problems/src/dynamic_programming/RemoveBoxes.java) (Hard) - [Stickers to Spell Word](problems/src/dynamic_programming/StickersToSpellWord.java) (Hard) +- [Ones and Zeroes](problems/src/dynamic_programming/OnesAndZeroes.java) (Medium) #### [Greedy](problems/src/greedy) @@ -247,6 +254,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Substring with Concatenation of All Words](problems/src/hashing/SubstringConcatenationOfWords.java) (Hard) - [Distribute Candies](problems/src/hashing/DistributeCandies.java) (Easy) - [Groups of Special-Equivalent Strings](problems/src/hashing/GroupsOfSpecialEquivalentStrings.java) (Easy) +- [Number of Atoms](problems/src/hashing/NumberOfAtoms.java) (Hard) #### [Heap](problems/src/heap) @@ -271,6 +279,8 @@ My accepted leetcode solutions to some of the common interview problems. - [Reverse Nodes in k-Group](problems/src/linked_list/ReverseNodesKGroup.java) (Hard) - [Swap Nodes in Pairs](problems/src/linked_list/SwapNodesInPairs.java) (Medium) - [Middle of Linked List](problems/src/linked_list/MiddleOfLinkedList.java) (Easy) +- [Split Linked List in Parts](problems/src/linked_list/SplitLinkedListInParts.java) (Medium) +- [Next Greater Node In Linked List](problems/src/linked_list/NextGreaterNodeInLinkedList.java) (Medium) #### [Math](problems/src/math) @@ -290,6 +300,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Squirrel Simulation](problems/src/math/SquirrelSimulation.java) (Medium) - [Projection Area of 3D Shapes](problems/src/math/ProjectionAreaOf3DShapes.java) (Easy) - [Decoded String at Index](problems/src/math/DecodedStringAtIndex.java) (Medium) +- [Base 7](problems/src/math/Base7.java) (Easy) #### [Reservoir Sampling](problems/src/reservoir_sampling) @@ -345,6 +356,8 @@ My accepted leetcode solutions to some of the common interview problems. - [Valid Word Square](problems/src/string/ValidWordSquare.java) (Easy) - [Reconstruct Original Digits from English](problems/src/string/ReconstructOriginalDigitsFromEnglish.java) (Medium) - [Push Dominoes](problems/src/string/PushDominoes.java) (Medium) +- [Validate IP Address](problems/src/string/ValidateIPAddress.java) (Medium) +- [Reverse String II](problems/src/string/ReverseStringII.java) (Easy) #### [Tree](problems/src/tree) @@ -380,7 +393,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Average of Levels in Binary Tree](problems/src/tree/AverageOfLevelsInBinaryTree.java) (Easy) - [Convert Binary Search Tree to Sorted Doubly Linked List](problems/src/tree/BSTtoDoublyLinkedList.java) (Easy) - [Same Tree](problems/src/tree/SameTree.java) (Easy) -- [Binary Tree Longest Consecutive Sequence II](problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java) (Medium) +- [Binary Tree Longest Consecutive SequencefindMinDifference II](problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java) (Medium) - [Minimum Absolute Difference in BST](problems/src/tree/MinimumAbsoluteDifferenceInBST.java) (Medium) - [Equal Tree Partition](problems/src/tree/EqualTreePartition.java) (Medium) - [Split BST](problems/src/tree/SplitBST.java) (Medium) @@ -392,6 +405,10 @@ My accepted leetcode solutions to some of the common interview problems. - [Convert BST to Greater Tree](problems/src/tree/ConvertBSTToGreaterTree.java) (Easy) - [All Nodes Distance K in Binary Tree](problems/src/tree/AllNodesDistanceKInBinaryTree.java) (Medium) - [All Possible Full Binary Trees](problems/src/tree/AllPossibleFullBinaryTrees.java) (Medium) +- [Flip Equivalent Binary Trees](problems/src/tree/FlipEquivalentBinaryTrees.java) (Medium) +- [Construct Binary Tree from String](problems/src/tree/ConstructBinaryTreefromString.java) (Medium) +- [Find Largest Value in Each Tree Row](problems/src/tree/FindLargestValueInEachTreeRow.java) (Medium) +- [Find Bottom Left Tree Value](problems/src/tree/FindBottomLeftTreeValue.java) (Medium) #### [Two Pointers](problems/src/two_pointers) diff --git a/problems/src/array/FindPivotIndex.java b/problems/src/array/FindPivotIndex.java new file mode 100644 index 00000000..cd27226d --- /dev/null +++ b/problems/src/array/FindPivotIndex.java @@ -0,0 +1,65 @@ +package array; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 06/08/2019 Given an array of integers nums, write a method that + * returns the "pivot" index of this array. + * + *

We define the pivot index as the index where the sum of the numbers to the left of the index + * is equal to the sum of the numbers to the right of the index. + * + *

If no such index exists, we should return -1. If there are multiple pivot indexes, you should + * return the left-most pivot index. + * + *

Example 1: + * + *

Input: nums = [1, 7, 3, 6, 5, 6] Output: 3 Explanation: The sum of the numbers to the left of + * index 3 (nums[3] = 6) is equal to the sum of numbers to the right of index 3. Also, 3 is the + * first index where this occurs. + * + *

Example 2: + * + *

Input: nums = [1, 2, 3] Output: -1 Explanation: There is no index that satisfies the + * conditions in the problem statement. + * + *

Note: + * + *

The length of nums will be in the range [0, 10000]. Each element nums[i] will be an integer in + * the range [-1000, 1000]. + * + * Solution: O(N) maintain a prefix and posfix sum array and then use this to arrive at the answer. + */ +public class FindPivotIndex { + public static void main(String[] args) { + } + + public int pivotIndex(int[] nums) { + if(nums.length == 1) return 0; + int[] left = new int[nums.length]; + int[] right = new int[nums.length]; + left[0] = nums[0]; + for(int i = 1; i < nums.length; i ++){ + left[i] = left[i - 1] + nums[i]; + } + right[nums.length - 1] = nums[nums.length - 1]; + for(int i = nums.length - 2; i >= 0; i --){ + right[i] = right[i + 1] + nums[i]; + } + for(int i = 0; i < nums.length; i ++){ + int l, r; + if(i == 0){ + l = 0; + } else { + l = left[i - 1]; + } + + if(i == nums.length - 1){ + r = 0; + } else { + r = right[i + 1]; + } + if(l == r) return i; + } + return -1; + } +} diff --git a/problems/src/array/LargestTimeForGivenDigits.java b/problems/src/array/LargestTimeForGivenDigits.java new file mode 100644 index 00000000..267c7fed --- /dev/null +++ b/problems/src/array/LargestTimeForGivenDigits.java @@ -0,0 +1,54 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 06/08/2019 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. + * + *

Example 1: + * + *

Input: [1,2,3,4] Output: "23:41" Example 2: + * + *

Input: [5,5,5,5] Output: "" + * + *

Note: + * + *

A.length == 4 0 <= A[i] <= 9 + * Solution O(N ^ 4) Check all combinations of time possible and return the maximum possible as the answer. + */ +public class LargestTimeForGivenDigits { + public static void main(String[] args) { + int[] A = {2, 0, 6, 6}; + System.out.println(new LargestTimeForGivenDigits().largestTimeFromDigits(A)); + } + + public String largestTimeFromDigits(int[] A) { + int max = -1; + String result = ""; + for(int i = 0; i < A.length; i ++){ + if(A[i] > 2) continue; + for(int j = 0; j < A.length; j ++){ + if(j == i) continue; + if(A[i] == 2 && A[j] > 3) continue; + for(int k = 0; k < A.length; k ++){ + if(k == i || k == j) continue; + if(A[k] > 5) continue; + for(int l = 0; l < A.length; l ++){ + if(l == i || l == j || l == k) continue; + int value = ((A[i] * 10 + A[j]) * 60) + A[k] * 10 + A[l]; + if(value > max){ + max = value; + result = A[i] + "" + A[j] + ":" + A[k] + "" + A[l]; + } + } + } + } + } + return result; + } +} diff --git a/problems/src/array/MinimumTimeDifference.java b/problems/src/array/MinimumTimeDifference.java new file mode 100644 index 00000000..757e87ee --- /dev/null +++ b/problems/src/array/MinimumTimeDifference.java @@ -0,0 +1,40 @@ +package array; +import java.util.*; +import java.util.stream.Collectors; + +/** + * Created by gouthamvidyapradhan on 30/07/2019 Given a list of 24-hour clock time points in + * "Hour:Minutes" format, find the minimum minutes difference between any two time points in the + * list. Example 1: Input: ["23:59","00:00"] Output: 1 Note: The number of time points in the given + * list is at least 2 and won't exceed 20000. The input time is legal and ranges from 00:00 to + * 23:59. + * + * Solution: O(N log N) convert each time value of the form hh:mm to minutes and sort the array. For every pair (i, + * j) where j = i + 1 (also for the case where i = 0 and j = N - 1) check the minute difference and return the + * minimum time difference as the answer. + */ +public class MinimumTimeDifference { + public static void main(String[] args) { + List list = Arrays.asList("23:59","00:00"); + System.out.println(new MinimumTimeDifference().findMinDifference(list)); + } + + public int findMinDifference(List timePoints) { + List timeInMinutes = timePoints.stream().map(t -> { + String[] strings = t.split(":"); + return Integer.parseInt(strings[0]) * 60 + Integer.parseInt(strings[1]); + }).sorted(Integer::compareTo).collect(Collectors.toList()); + int min = Integer.MAX_VALUE; + for(int i = 1, l = timeInMinutes.size(); i < l; i ++){ + int prev = timeInMinutes.get(i - 1); + int curr = timeInMinutes.get(i); + min = Math.min(min, curr - prev); + min = Math.min(min, ((24 * 60) - curr) + prev); + } + int prev = timeInMinutes.get(0); + int curr = timeInMinutes.get(timeInMinutes.size() - 1); + min = Math.min(min, curr - prev); + min = Math.min(min, ((24 * 60) - curr) + prev); + return min; + } +} diff --git a/problems/src/binary_search/MinimumWindowSubsequence.java b/problems/src/binary_search/MinimumWindowSubsequence.java new file mode 100644 index 00000000..b1a174f4 --- /dev/null +++ b/problems/src/binary_search/MinimumWindowSubsequence.java @@ -0,0 +1,79 @@ +package binary_search; +import java.util.*; +/** + * Created by gouthamvidyapradhan on 06/08/2019 Given strings S and T, find the minimum (contiguous) + * substring W of S, so that T is a subsequence of W. + * + *

If there is no such window in S that covers all characters in T, return the empty string "". + * If there are multiple such minimum-length windows, return the one with the left-most starting + * index. + * + *

Example 1: + * + *

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. + * + *

Note: + * + *

All the strings in the input will only contain lowercase letters. The length of S will be in + * the range [1, 20000]. The length of T will be in the range [1, 100]. + * + * Solution O(S x T x log S) General idea is to first find the left-most left (l) and right (r) index where r - l is + * minimum and the minimum window contains the sub-sequence and iteratively check the next left-most indices and + * continue for the entire string S. A naive implementation would result in O(S ^ 2) + * therefore to speed up we have to maintain a hashtable of character as key and all its index of occurrence in a + * sorted list. Now, since this list is sorted we can easily find the next left-most by binarySearch or even better + * by using a TreeSet higher or ceil function. + */ +public class MinimumWindowSubsequence { + public static void main(String[] args) { + System.out.println(new MinimumWindowSubsequence().minWindow("abcdebdde", "x")); + } + + public String minWindow(String S, String T) { + if(T.isEmpty() || S.isEmpty()) return ""; + Map> charMap = new HashMap<>(); + for(int i = 0, l = S.length(); i < l; i ++){ + char c = S.charAt(i); + charMap.putIfAbsent(c, new TreeSet<>()); + charMap.get(c).add(i); + } + int min = Integer.MAX_VALUE; + int start = -1, end; + int ansStart = -1, ansEnd = -1; + boolean finished = false; + while(true){ + int index = start; + end = -1; + for(int i = 0, l = T.length(); i < l; i ++){ + char c = T.charAt(i); + if(!charMap.containsKey(c)){ + return ""; + } else{ + TreeSet indicies = charMap.get(c); + Integer found = indicies.higher(index); + if(found == null){ + finished = true; + break; + } else{ + index = found; + if(i == 0){ + start = index; + } if(i == l - 1){ + end = index; + } + } + } + } + if(start != -1 && end != -1){ + if((end - start) < min){ + min = end - start; + ansStart = start; + ansEnd = end; + } + } + if(finished) return ansStart == -1 ? "" : S.substring(ansStart, ansEnd + 1); + } + } +} diff --git a/problems/src/depth_first_search/NumberOfEnclaves.java b/problems/src/depth_first_search/NumberOfEnclaves.java new file mode 100644 index 00000000..f35ebbbf --- /dev/null +++ b/problems/src/depth_first_search/NumberOfEnclaves.java @@ -0,0 +1,75 @@ +package depth_first_search; + +/** + * Created by gouthamvidyapradhan on 31/07/2019 Given a 2D array A, each cell is 0 (representing + * sea) or 1 (representing land) + * + *

A move consists of walking from one land square 4-directionally to another land square, or off + * the boundary of the grid. + * + *

Return the number of land squares in the grid for which we cannot walk off the boundary of the + * grid in any number of moves. + * + *

Example 1: + * + *

Input: [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]] Output: 3 Explanation: There are three 1s + * that are enclosed by 0s, and one 1 that isn't enclosed because its on the boundary. Example 2: + * + *

Input: [[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]] Output: 0 Explanation: All 1s are either on + * the boundary or can reach the boundary. + * + *

Note: + * + *

1 <= A.length <= 500 1 <= A[i].length <= 500 0 <= A[i][j] <= 1 All rows have the same size. + * Solution O(N x M) Do a dfs to count number of enclaves - in each dfs check if it violates the condition to be + * considered a enclave. + */ +public class NumberOfEnclaves { + + final int[] R = {0, 0, -1, 1}; + final int[] C = {1, -1, 0, 0}; + + boolean[][] done; + int count = 0; + int answer = 0; + boolean possible = true; + public static void main(String[] args) { + int[][] A = {{0, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}}; + System.out.println(new NumberOfEnclaves().numEnclaves(A)); + } + + public int numEnclaves(int[][] A) { + done = new boolean[A.length][A[0].length]; + for(int i = 0; i < A.length; i ++){ + for(int j = 0; j < A[0].length; j ++){ + if(!done[i][j] && A[i][j] == 1){ + count = 0; + possible = true; + dfs(A, i, j); + if(possible){ + answer += count; + } + } + } + } + return answer; + } + + private void dfs(int[][] A, int r, int c){ + done[r][c] = true; + if(r == 0 || c == 0 || r == A.length - 1 || c == A[0].length - 1){ + possible = false; + } + count++; + for(int i = 0; i < 4; i ++){ + int newR = r + R[i]; + int newC = c + C[i]; + if(newR < A.length && newC < A[0].length && newR >= 0 && newC >= 0 && !done[newR][newC]){ + if(A[newR][newC] == 1){ + dfs(A, newR, newC); + } + } + } + } + +} diff --git a/problems/src/divide_and_conquer/ReversePairsII.java b/problems/src/divide_and_conquer/ReversePairsII.java new file mode 100644 index 00000000..46b8a8a9 --- /dev/null +++ b/problems/src/divide_and_conquer/ReversePairsII.java @@ -0,0 +1,86 @@ +package divide_and_conquer; + +/** + * Created by gouthamvidyapradhan on 01/08/2019 Given an array nums, we call (i, j) an important + * reverse pair if i < j and nums[i] > 2*nums[j]. + * + *

You need to return the number of important reverse pairs in the given array. + * + *

Example1: + * + *

Input: [1,3,2,3,1] Output: 2 Example2: + * + *

Input: [2,4,3,5,1] Output: 3 Note: The length of the given array will not exceed 50,000. All + * the numbers in the input array are in the range of 32-bit integer. + + * Solution: O(N log N) Given two sorted arrays A[] and B[] it is quite easy to see for every element i in A, how + * many elements in A have a value > 2 * B[j] using binary search (also possible using two pointers) - using this idea + * we can implement standard merge sort algorithm and for every sorted pairs A[] and B[] before we merge we can total + * number of elements in A which are > 2 x B[i] + * + */ +public class ReversePairsII { + public static void main(String[] args) { + int[] A = {2,4,3,5,1}; + System.out.println(new ReversePairsII().reversePairs(A)); + } + + int answer = 0; + public int reversePairs(int[] nums) { + mergeSort(nums, 0, nums.length - 1); + return answer; + } + + + private int[] mergeSort(int[] num, int l, int h){ + if(l < h){ + int m = l + (h - l) / 2; + int[] left = mergeSort(num, l, m); + int[] right = mergeSort(num, m + 1, h); + return merge(left, right); + } else if(l == h){ + return new int[]{num[l]}; + } else { + return new int[]{}; + } + } + + private int[] merge(int[] A, int[] B){ + for(int i = 0 ; i < B.length; i ++){ + int num = B[i]; + int l = 0, h = A.length; + int index = -1; + while(l < h){ + int m = l + (h - l) / 2; + if((long)A[m] > (2 * (long)num)){ + index = m; + h = m; + } else { + l = m + 1; + } + } + if(index > -1){ + answer += ((A.length - index)); + } + } + int[] C = new int[A.length + B.length]; + int k = 0; + int i = 0, j = 0; + for(; i < A.length && j < B.length;){ + if(A[i] < B[j]){ + C[k++] = A[i]; + i ++; + } else { + C[k++] = B[j]; + j ++; + } + } + while(i < A.length){ + C[k++] = A[i++]; + } + while(j < B.length){ + C[k++] = B[j++]; + } + return C; + } +} diff --git a/problems/src/dynamic_programming/OnesAndZeroes.java b/problems/src/dynamic_programming/OnesAndZeroes.java new file mode 100644 index 00000000..5325ae0e --- /dev/null +++ b/problems/src/dynamic_programming/OnesAndZeroes.java @@ -0,0 +1,64 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 01/08/2019 In the computer world, use restricted resource you + * have to generate maximum benefit is what we always want to pursue. + * + *

For now, suppose you are a dominator of m 0s and n 1s respectively. On the other hand, there + * is an array with strings consisting of only 0s and 1s. + * + *

Now your task is to find the maximum number of strings that you can form with given m 0s and n + * 1s. Each 0 and 1 can be used at most once. + * + *

Note: + * + *

The given numbers of 0s and 1s will both not exceed 100 The size of given string array won't + * exceed 600. + * + *

Example 1: + * + *

Input: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3 Output: 4 + * + *

Explanation: This are totally 4 strings can be formed by the using of 5 0s and 3 1s, which are + * “10,”0001”,”1”,”0” + * + *

Example 2: + * + *

Input: Array = {"10", "0", "1"}, m = 1, n = 1 Output: 2 + * + *

Explanation: You could form "10", but then you'd have nothing left. Better form "0" and "1". + * + * Solution: O(S x m x n) For every string array position we have two choices i. pick this value or ii. + * not pick this value. Evaluate both these cases and cache the result in a dp array. + */ +public class OnesAndZeroes { + public static void main(String[] args) { + String[] str = {"10", "0", "1"}; + System.out.println(new OnesAndZeroes().findMaxForm(str, 1, 1)); + } + + public int findMaxForm(String[] strs, int m, int n) { + int[][][] dp = new int[strs.length + 1][m + 1][n + 1]; + for(int i = strs.length - 1; i >= 0; i --){ + String string = strs[i]; + int zero = 0; + int one = 0; + for(char c : string.toCharArray()){ + if(c == '0'){ + zero++; + } else{ + one ++; + } + } + for(int p = m; p >= 0; p --){ + for(int q = n; q >= 0; q--){ + dp[i][p][q] = dp[i + 1][p][q]; + if(p - zero >= 0 && q - one >= 0){ + dp[i][p][q] = Math.max(dp[i][p][q], dp[i + 1][p - zero][q - one] + 1); + } + } + } + } + return dp[0][m][n]; + } +} diff --git a/problems/src/hashing/NumberOfAtoms.java b/problems/src/hashing/NumberOfAtoms.java new file mode 100644 index 00000000..a8655182 --- /dev/null +++ b/problems/src/hashing/NumberOfAtoms.java @@ -0,0 +1,147 @@ +package hashing; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 06/08/2019 Given a chemical formula (given as a string), return + * the count of each atom. + * + *

An atomic element always starts with an uppercase character, then zero or more lowercase + * letters, representing the name. + * + *

1 or more digits representing the count of that element may follow if the count is greater + * than 1. If the count is 1, no digits will follow. For example, H2O and H2O2 are possible, but + * H1O2 is impossible. + * + *

Two formulas concatenated together produce another formula. For example, H2O2He3Mg4 is also a + * formula. + * + *

A formula placed in parentheses, and a count (optionally added) is also a formula. For + * example, (H2O2) and (H2O2)3 are formulas. + * + *

Given a formula, output the count of all elements as a string in the following form: the first + * name (in sorted order), followed by its count (if that count is more than 1), followed by the + * second name (in sorted order), followed by its count (if that count is more than 1), and so on. + * + *

Example 1: Input: formula = "H2O" Output: "H2O" Explanation: The count of elements are {'H': + * 2, 'O': 1}. Example 2: Input: formula = "Mg(OH)2" Output: "H2MgO2" Explanation: The count of + * elements are {'H': 2, 'Mg': 1, 'O': 2}. Example 3: Input: formula = "K4(ON(SO3)2)2" Output: + * "K4N2O14S4" Explanation: The count of elements are {'K': 4, 'N': 2, 'O': 14, 'S': 4}. Note: + * + *

All atom names consist of lowercase letters, except for the first character which is + * uppercase. The length of formula will be in the range [1, 1000]. formula will only consist of + * letters, digits, and round parentheses, and is a valid formula as defined in the problem. + * + * Solution O(N ^ 2) Recursively solve each substring within round braces as subformula. Consider each subformula as + * right subformula and each each subformula before the round braces as left subformula - sum up value of both left + * and right subformula to get the answer. + */ +public class NumberOfAtoms { + public static void main(String[] args) { + String result = new NumberOfAtoms().countOfAtoms("K4(((K4)K4)2)2"); + System.out.println(result); + } + + public String countOfAtoms(String formula) { + Map atomCountResult = new NumberOfAtoms().countOfAtoms(formula, 0); + List sortedKeys = new ArrayList<>(atomCountResult.keySet()); + sortedKeys.sort(Comparator.naturalOrder()); + StringBuilder result = new StringBuilder(); + for(String k : sortedKeys){ + int count = atomCountResult.get(k); + if(count > 1){ + result.append(k).append(count); + } else result.append(k); + } + return result.toString(); + } + + private Map countOfAtoms(String formula, int startPos){ + Map left = new HashMap<>(); + StringBuilder atom = new StringBuilder(); + StringBuilder atomCount = new StringBuilder(); + for (int i = startPos; i < formula.length();){ + char c = formula.charAt(i); + if(c >= 'A' && c <= 'Z'){ + if(atom.length() > 0){ + int count = 1; + if(atomCount.length() > 0){ + count = Integer.parseInt(atomCount.toString()); + } + String atomKey = atom.toString(); + if(left.containsKey(atomKey)){ + left.put(atomKey, left.get(atomKey) + count); + } else left.put(atom.toString(), count); + atom = new StringBuilder(); + atomCount = new StringBuilder(); + } + atom.append(c); + i++; + } else if(c >= 'a' && c <= 'z'){ + atom.append(c); + i++; + } else if(c >= '0' && c <= '9'){ + atomCount.append(c); + i++; + } else{ + //this is equal to '(' + if(atom.length() > 0){ + int count = 1; + if(atomCount.length() > 0){ + count = Integer.parseInt(atomCount.toString()); + } + String atomKey = atom.toString(); + if(left.containsKey(atomKey)){ + left.put(atomKey, left.get(atomKey) + count); + } else left.put(atom.toString(), count); + atom = new StringBuilder(); + atomCount = new StringBuilder(); + } + int j = i, count = 0; + for(int l = formula.length(); j < l; j ++){ + if(formula.charAt(j) == '('){ + count ++; + } else if(formula.charAt(j) == ')'){ + count --; + } + if(count == 0) break; + } + Map right = countOfAtoms(formula.substring(i + 1, j), 0); + j++; + StringBuilder rightAtomCount = new StringBuilder(); + for(int l = formula.length(); j < l; j ++){ + if(formula.charAt(j) >= '0' && formula.charAt(j) <= '9'){ + rightAtomCount.append(formula.charAt(j)); + } else break; + } + if(rightAtomCount.length() > 0){ + int mulFactor = Integer.parseInt(rightAtomCount.toString()); + for(String k : right.keySet()){ + right.put(k, right.get(k) * mulFactor); + } + } + left = merge(left, right); + i = j; + } + } + if(atom.length() > 0){ + int count = 1; + if(atomCount.length() > 0){ + count = Integer.parseInt(atomCount.toString()); + } + String atomKey = atom.toString(); + if(left.containsKey(atomKey)){ + left.put(atomKey, left.get(atomKey) + count); + } else left.put(atom.toString(), count); + } + return left; + } + + private Map merge(Map left, Map right){ + for(String k : left.keySet()){ + if(right.containsKey(k)){ + right.put(k, right.get(k) + left.get(k)); + } else right.put(k, left.get(k)); + } + return right; + } +} diff --git a/problems/src/linked_list/NextGreaterNodeInLinkedList.java b/problems/src/linked_list/NextGreaterNodeInLinkedList.java new file mode 100644 index 00000000..1967d6c3 --- /dev/null +++ b/problems/src/linked_list/NextGreaterNodeInLinkedList.java @@ -0,0 +1,89 @@ +package linked_list; +import java.util.*; +/** + * Created by gouthamvidyapradhan on 31/07/2019 We are given a linked list with head as the first + * node. Let's number the nodes in the list: node_1, node_2, node_3, ... etc. + * + *

Each node may have a next larger value: for node_i, next_larger(node_i) is the node_j.val such + * that j > i, node_j.val > node_i.val, and j is the smallest possible choice. If such a j does not + * exist, the next larger value is 0. + * + *

Return an array of integers answer, where answer[i] = next_larger(node_{i+1}). + * + *

Note that in the example inputs (not outputs) below, arrays such as [2,1,5] represent the + * serialization of a linked list with a head node value of 2, second node value of 1, and third + * node value of 5. + * + *

Example 1: + * + *

Input: [2,1,5] Output: [5,5,0] Example 2: + * + *

Input: [2,7,4,3,5] Output: [7,0,5,5,0] Example 3: + * + *

Input: [1,7,5,1,9,2,5,1] Output: [7,9,9,9,0,5,0,0] + * + *

Note: + * + *

1 <= node.val <= 10^9 for each node in the linked list. The given list has length in the range + * [0, 10000]. + * + * Solution O(N) solve the problem in the inverse order starting from the tail of the list. Maintain a stack of + * values and on each iteration pop() all the values from the stack which are smaller then the current element. + */ +public class NextGreaterNodeInLinkedList { + + public static class ListNode { + int val; + ListNode next; + ListNode(int x) { val = x; } + } + + private List result; + public static void main(String[] args) { + ListNode node = new ListNode(1); + node.next = new ListNode(2); + new NextGreaterNodeInLinkedList().nextLargerNodes(node); + } + + public int[] nextLargerNodes(ListNode head) { + result = new ArrayList<>(); + find(head, result); + Collections.reverse(result); + int[] answer = new int[result.size()]; + for(int i = 0, l = result.size(); i < l; i ++){ + answer[i] = result.get(i); + } + return answer; + } + + + + private Stack find(ListNode head, List answer){ + if(head == null){ + return new Stack<>(); + } + Stack stack = find(head.next, answer); + if(stack.isEmpty()){ + answer.add(0); + stack.push(head.val); + } else{ + if(stack.peek() > head.val){ + answer.add(stack.peek()); + stack.push(head.val); + } else { + while(!stack.isEmpty() && stack.peek() <= head.val){ + stack.pop(); + } + if(stack.isEmpty()){ + stack.push(head.val); + answer.add(0); + } else{ + answer.add(stack.peek()); + stack.push(head.val); + } + } + } + return stack; + } + +} diff --git a/problems/src/linked_list/SplitLinkedListInParts.java b/problems/src/linked_list/SplitLinkedListInParts.java new file mode 100644 index 00000000..46b02c24 --- /dev/null +++ b/problems/src/linked_list/SplitLinkedListInParts.java @@ -0,0 +1,89 @@ +package linked_list; +import java.util.*; +/** + * Created by gouthamvidyapradhan on 06/08/2019 Given a (singly) linked list with head node root, + * write a function to split the linked list into k consecutive linked list "parts". + * + *

The length of each part should be as equal as possible: no two parts should have a size + * differing by more than 1. This may lead to some parts being null. + * + *

The parts should be in order of occurrence in the input list, and parts occurring earlier + * should always have a size greater than or equal parts occurring later. + * + *

Return a List of ListNode's representing the linked list parts that are formed. + * + *

Examples 1->2->3->4, k = 5 // 5 equal parts [ [1], [2], [3], [4], null ] Example 1: Input: + * root = [1, 2, 3], k = 5 Output: [[1],[2],[3],[],[]] Explanation: The input and each element of + * the output are ListNodes, not arrays. For example, the input root has root.val = 1, root.next.val + * = 2, \root.next.next.val = 3, and root.next.next.next = null. The first element output[0] has + * output[0].val = 1, output[0].next = null. The last element output[4] is null, but it's string + * representation as a ListNode is []. Example 2: Input: root = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], k = + * 3 Output: [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]] Explanation: The input has been split into + * consecutive parts with size difference at most 1, and earlier parts are a larger size than the + * later parts. Note: + * + *

The length of root will be in the range [0, 1000]. Each value of a node in the input will be + * an integer in the range [0, 999]. k will be an integer in the range [1, 50]. + * + * Solution O(N) do a linear scan and split the array by required size. + */ +public class SplitLinkedListInParts { + public static class ListNode { + int val; + ListNode next; + ListNode(int x) { val = x; } + } + public static void main(String[] args) { + ListNode root = new ListNode(1); + root.next = new ListNode(2); + root.next.next = new ListNode(3); + ListNode[] result = new SplitLinkedListInParts().splitListToParts(root, 5); + System.out.println(result); + } + + public ListNode[] splitListToParts(ListNode root, int k) { + List list = new ArrayList<>(); + while(root != null){ + list.add(root.val); + root = root.next; + } + int tempK = k; + int N = list.size(); + List result = new ArrayList<>(); + ListNode head = new ListNode(-1); + ListNode prev = head; + int i = 0, j = 0; + int count = 0; + int P = N / tempK; + if((N % tempK) > 0){ + P++; + } + for(; j < N; ){ + if(j - i < P){ + prev.next = new ListNode(list.get(j)); + prev = prev.next; + j ++; + count ++; + } else{ + result.add(head.next); + i = j; + head = new ListNode(-1); + prev = head; + tempK --; + P = (N - count) / tempK; + if(((N - count) % tempK) > 0){ + P++; + } + } + } + result.add(head.next); + while(result.size() < k){ + result.add(null); + } + ListNode[] nodes = new ListNode[result.size()]; + for(int l = 0; l < result.size(); l ++){ + nodes[l] = result.get(l); + } + return nodes; + } +} diff --git a/problems/src/math/Base7.java b/problems/src/math/Base7.java new file mode 100644 index 00000000..438a7468 --- /dev/null +++ b/problems/src/math/Base7.java @@ -0,0 +1,29 @@ +package math; +import java.util.*; +/** + * Created by gouthamvidyapradhan on 01/08/2019 Given an integer, return its base 7 string + * representation. + * + *

Example 1: Input: 100 Output: "202" Example 2: Input: -7 Output: "-10" Note: The input will be + * in range of [-1e7, 1e7]. + */ +public class Base7 { + public static void main(String[] args) { + // + } + + public String convertToBase7(int num) { + Integer.toString(7, 7); + if(num == 0) return "0"; + int q = Math.abs(num), r; + StringBuilder sb = new StringBuilder(); + while(q != 0){ + r = q % 7; + sb.append(r); + q /= 7; + } + if(num < 0){ + return "-" + sb.reverse().toString(); + } else return sb.reverse().toString(); + } +} diff --git a/problems/src/string/ReverseStringII.java b/problems/src/string/ReverseStringII.java new file mode 100644 index 00000000..b4eef278 --- /dev/null +++ b/problems/src/string/ReverseStringII.java @@ -0,0 +1,37 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 30/07/2019 Given a string and an integer k, you need to reverse + * the first k characters for every 2k characters counting from the start of the string. If there + * are less than k characters left, reverse all of them. If there are less than 2k but greater than + * or equal to k characters, then reverse the first k characters and left the other as original. + * Example: Input: s = "abcdefg", k = 2 Output: "bacdfeg" Restrictions: The string consists of lower + * English letters only. Length of the given string and k will in the range [1, 10000] + * + * Solution O(N) + */ +public class ReverseStringII { + public static void main(String[] args) { + System.out.println(new ReverseStringII().reverseStr("abcdefg", 2)); + } + + public String reverseStr(String s, int k) { + StringBuilder sb = new StringBuilder(); + for(int i = 0, l = s.length(); i < l; i ++){ + if(i % (2 * k) == 0){ + int count = 0; + StringBuilder temp = new StringBuilder(); + while(count < k && i < l){ + temp.append(s.charAt(i)); + count ++; + i ++; + } + sb.append(temp.reverse()); + } + if(i < l){ + sb.append(s.charAt(i)); + } + } + return sb.toString(); + } +} diff --git a/problems/src/string/ValidateIPAddress.java b/problems/src/string/ValidateIPAddress.java new file mode 100644 index 00000000..88e8e877 --- /dev/null +++ b/problems/src/string/ValidateIPAddress.java @@ -0,0 +1,94 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 01/08/2019 Write a function to check whether an input string is + * a valid IPv4 address or IPv6 address or neither. + * + *

IPv4 addresses are canonically represented in dot-decimal notation, which consists of four + * decimal numbers, each ranging from 0 to 255, separated by dots ("."), e.g.,172.16.254.1; + * + *

Besides, leading zeros in the IPv4 is invalid. For example, the address 172.16.254.01 is + * invalid. + * + *

IPv6 addresses are represented as eight groups of four hexadecimal digits, each group + * representing 16 bits. The groups are separated by colons (":"). For example, the address + * 2001:0db8:85a3:0000:0000:8a2e:0370:7334 is a valid one. Also, we could omit some leading zeros + * among four hexadecimal digits and some low-case characters in the address to upper-case ones, so + * 2001:db8:85a3:0:0:8A2E:0370:7334 is also a valid IPv6 address(Omit leading zeros and using upper + * cases). + * + *

However, we don't replace a consecutive group of zero value with a single empty group using + * two consecutive colons (::) to pursue simplicity. For example, 2001:0db8:85a3::8A2E:0370:7334 is + * an invalid IPv6 address. + * + *

Besides, extra leading zeros in the IPv6 is also invalid. For example, the address + * 02001:0db8:85a3:0000:0000:8a2e:0370:7334 is invalid. + * + *

Note: You may assume there is no extra space or special characters in the input string. + * + *

Example 1: Input: "172.16.254.1" + * + *

Output: "IPv4" + * + *

Explanation: This is a valid IPv4 address, return "IPv4". Example 2: Input: + * "2001:0db8:85a3:0:0:8A2E:0370:7334" + * + *

Output: "IPv6" + * + *

Explanation: This is a valid IPv6 address, return "IPv6". Example 3: Input: "256.256.256.256" + * + *

Output: "Neither" + * + *

Explanation: This is neither a IPv4 address nor a IPv6 address. + * + * Solution: O(N) split the string by each '.' or ':' and then validate each parts. + */ +public class ValidateIPAddress { + public static void main(String[] args) { + + System.out.println(new ValidateIPAddress().validIPAddress("02001:0db8:85a3:0000:0000:8a2e:0370:7334")); + } + + public String validIPAddress(String IP) { + if(IP.contains(".")){ + if(IP.endsWith(".") || IP.startsWith("."))return "Neither"; + String[] ipv4 = IP.split("\\."); + if(ipv4.length != 4) return "Neither"; + else { + for(String part : ipv4){ + if(part.isEmpty()) return "Neither"; + if(part.length() > 1 && part.startsWith("0")) return "Neither"; + else { + if(part.length() > 3) return "Neither"; + for(char c : part.toCharArray()){ + if(c < '0' || c > '9') return "Neither"; + } + int value = Integer.parseInt(part); + if(value < 0 || value > 255) return "Neither"; + } + } + } + return "IPv4"; + } else if(IP.contains(":")){ + if(IP.endsWith(":") || IP.startsWith(":"))return "Neither"; + String[] ipv6 = IP.split(":"); + if(ipv6.length != 8) return "Neither"; + else { + for(String part : ipv6){ + if(part.isEmpty()) return "Neither"; + if(part.length() > 4) return "Neither"; + else { + for(char c : part.toCharArray()){ + if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')){ + + } else{ + return "Neither"; + } + } + } + } + } + return "IPv6"; + } else return "Neither"; + } +} diff --git a/problems/src/tree/ConstructBinaryTreefromString.java b/problems/src/tree/ConstructBinaryTreefromString.java new file mode 100644 index 00000000..af5d497a --- /dev/null +++ b/problems/src/tree/ConstructBinaryTreefromString.java @@ -0,0 +1,88 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 30/07/2019 You need to construct a binary tree from a string + * consisting of parenthesis and integers. + * + *

The whole input represents a binary tree. It contains an integer followed by zero, one or two + * pairs of parenthesis. The integer represents the root's value and a pair of parenthesis contains + * a child binary tree with the same structure. + * + *

You always start to construct the left child node of the parent first if it exists. + * + *

Example: Input: "4(2(3)(1))(6(5))" Output: return the tree root node representing the + * following tree: + * + *

+ * 4 + * / \ + * 2 6 + * /\ / + * 3 1 5 + + Note: There will only be '(', ')', '-' and '0' ~ '9' in the input + * string. An empty tree is represented by "" instead of "()". + * + * Solution: O(N ^ 2) Form a node for every number and treat the first sub-string within round braces as left node and + * the second sub-string within the round braces as the right node. Recursively solve each substring within the round + * braces. + */ +public class ConstructBinaryTreefromString { + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + public static void main(String[] args) { + System.out.println(new ConstructBinaryTreefromString().str2tree("4(2(3)(1))(6(5))")); + } + + private TreeNode str2tree(String s){ + if(s == null || s.isEmpty()) return null; + TreeNode current; + StringBuilder num = new StringBuilder(); + boolean isNeg = false; + int i = 0; + for(; i < s.length(); i ++){ + if(s.charAt(i) == '-'){ + isNeg = true; + } else if(s.charAt(i) >= '0' && s.charAt(i) <= '9'){ + num.append(s.charAt(i)); + } else break; + } + if(isNeg){ + current = new TreeNode(Integer.parseInt(num.toString()) * -1); + } else current = new TreeNode(Integer.parseInt(num.toString())); + int count = 0; + StringBuilder left = new StringBuilder(); + for(; i < s.length(); i ++){ + if(s.charAt(i) == '('){ + count ++; + } else if(s.charAt(i) == ')'){ + count --; + } + left.append(s.charAt(i)); + if(count == 0){ + break; + } + } + i ++; + String leftStr = ""; + String rightStr = ""; + if(i < s.length()){ + rightStr = s.substring(i); + } + if(left.length() > 0){ + leftStr = left.subSequence(1, left.length() - 1).toString(); + } if(rightStr.length() > 0){ + rightStr = rightStr.substring(1, rightStr.length() - 1); + } + TreeNode leftNode = str2tree(leftStr); + TreeNode rightNode = str2tree(rightStr); + current.left = leftNode; + current.right = rightNode; + return current; + } +} diff --git a/problems/src/tree/FindBottomLeftTreeValue.java b/problems/src/tree/FindBottomLeftTreeValue.java index 2de54d84..c6caf9c7 100644 --- a/problems/src/tree/FindBottomLeftTreeValue.java +++ b/problems/src/tree/FindBottomLeftTreeValue.java @@ -13,6 +13,8 @@ *

1 / \ 2 3 / / \ 4 5 6 / 7 * *

Output: 7 Note: You may assume the tree (i.e., the given root node) is not NULL. + * Solution: O(N) do a inorder search to find the left most value. Keep a level counter to keep track of what level + * you are at when you do a inorder search. */ public class FindBottomLeftTreeValue { private int max = 0, result; @@ -39,18 +41,18 @@ public static void main(String[] args) throws Exception { } public int findBottomLeftValue(TreeNode root) { - preorder(root, 1); + inorder(root, 1); return result; } - private void preorder(TreeNode node, int level) { + private void inorder(TreeNode node, int level) { if (node != null) { if (level > max) { result = node.val; max = level; } - preorder(node.left, level + 1); - preorder(node.right, level + 1); + inorder(node.left, level + 1); + inorder(node.right, level + 1); } } } diff --git a/problems/src/tree/FindLargestValueInEachTreeRow.java b/problems/src/tree/FindLargestValueInEachTreeRow.java new file mode 100644 index 00000000..3c5a3bfd --- /dev/null +++ b/problems/src/tree/FindLargestValueInEachTreeRow.java @@ -0,0 +1,61 @@ +package tree; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 01/08/2019 You need to find the largest value in each row of a + * binary tree. + * + *

Example: Input: + * + *

1 / \ 3 2 / \ \ 5 3 9 + * + *

Output: [1, 3, 9] + * Solution: O(N) do a bfs to check largest in each row. + */ +public class FindLargestValueInEachTreeRow { + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + Map maxRow = new HashMap<>(); + + class Node { + int row; + TreeNode val; + Node(int row, TreeNode val){ + this.row = row; + this.val = val; + } + } + + public List largestValues(TreeNode root) { + if(root == null) return new ArrayList<>(); + Queue queue = new ArrayDeque<>(); + queue.offer(new Node(0, root)); + while(!queue.isEmpty()){ + Node top = queue.poll(); + maxRow.putIfAbsent(top.row, top.val.val); + maxRow.put(top.row, Math.max(maxRow.get(top.row), top.val.val)); + if(top.val.left != null){ + queue.offer(new Node(top.row + 1, top.val.left)); + } + if(top.val.right != null){ + queue.offer(new Node(top.row + 1, top.val.right)); + } + } + List answer = new ArrayList<>(); + List keyList = new ArrayList<>(maxRow.keySet()); + keyList.sort(Integer::compareTo); + for(int k : keyList){ + answer.add(maxRow.get(k)); + } + return answer; + } + + public static void main(String[] args) { + // + } +} diff --git a/problems/src/tree/FlipEquivalentBinaryTrees.java b/problems/src/tree/FlipEquivalentBinaryTrees.java new file mode 100644 index 00000000..18f3fdf7 --- /dev/null +++ b/problems/src/tree/FlipEquivalentBinaryTrees.java @@ -0,0 +1,124 @@ +package tree; + +/** + * Created by gouthamvidyapradhan on 06/08/2019 For a binary tree T, we can define a flip operation + * as follows: choose any node, and swap the left and right child subtrees. + * + *

A binary tree X is flip equivalent to a binary tree Y if and only if we can make X equal to Y + * after some number of flip operations. + * + *

Write a function that determines whether two binary trees are flip equivalent. The trees are + * given by root nodes root1 and root2. + * + *

Example 1: + * + *

Input: root1 = [1,2,3,4,5,6,null,null,null,7,8], root2 = + * [1,3,2,null,6,4,5,null,null,null,null,8,7] Output: true Explanation: We flipped at nodes with + * values 1, 3, and 5. Flipped Trees Diagram + * + *

Note: + * + *

Each tree will have at most 100 nodes. Each value in each tree will be a unique integer in the + * range [0, 99]. + * Solution O(N ^ 2) Since the node values are unique general idea is to find the node on right tree for every node + * on the left tree and check if the values need to be swapped, if yes then swap the node's left and right child in + * the left tree. After this operation is complete check if both the trees are equal + */ +public class FlipEquivalentBinaryTrees { + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + public static void main(String[] args) { + TreeNode node = new TreeNode(1); + node.left = new TreeNode(2); + node.left.left = new TreeNode(4); + node.left.right = new TreeNode(5); + node.left.right.left = new TreeNode(7); + node.left.right.right = new TreeNode(8); + node.right = new TreeNode(3); + node.right.left = new TreeNode(6); + + TreeNode node1 = new TreeNode(1); + node1.left = new TreeNode(3); + node1.left.right = new TreeNode(6); + node1.right = new TreeNode(2); + node1.right.left = new TreeNode(4); + node1.right.right = new TreeNode(5); + node1.right.right.left = new TreeNode(8); + node1.right.right.right = new TreeNode(7); + System.out.println(new FlipEquivalentBinaryTrees().flipEquiv(node, node1)); + } + + public boolean flipEquiv(TreeNode root1, TreeNode root2) { + flip(root1, root2); + return checkIfBothAreSame(root1, root2); + } + + private boolean checkIfBothAreSame(TreeNode root1, TreeNode root2){ + if(root1 == null && root2 == null) return true; + else if(root1 == null) return false; + else if(root2 == null) return false; + else { + if(root1.val != root2.val) return false; + if(!checkIfBothAreSame(root1.left, root2.left)) return false; + return checkIfBothAreSame(root1.right, root2.right); + } + } + + private void flip(TreeNode root1, TreeNode root2){ + if(root1 != null){ + TreeNode result = find(root2, root1.val); + boolean valid = true; + if(result != null){ + if(root1.left == null){ + if(result.right != null){ + valid = false; + } + }if(root1.right == null){ + if(result.left != null){ + valid = false; + } + } + if(root1.left != null){ + if(result.right == null){ + valid = false; + } else { + if(root1.left.val != result.right.val){ + valid = false; + } + } + } if(root1.right != null){ + if(result.left == null){ + valid = false; + } else { + if(root1.right.val != result.left.val){ + valid = false; + } + } + } + if(valid){ + TreeNode temp = result.left; + result.left = result.right; + result.right = temp; + } + } + flip(root1.left, root2); + flip(root1.right, root2); + } + } + + private TreeNode find(TreeNode node, int value){ + if(node != null){ + if(node.val == value) return node; + TreeNode left = find(node.left, value); + if(left != null) return left; + TreeNode right = find(node.right, value); + if(right != null) return right; + } return null; + } +} From b0e7b60d830b52717830ecc2c61ddc085d848cc3 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Mon, 12 Aug 2019 23:40:29 +0200 Subject: [PATCH 220/235] Solved Problems and code format --- README.md | 1 + problems/src/array/FindPivotIndex.java | 61 +++--- .../src/array/LargestTimeForGivenDigits.java | 26 +-- problems/src/array/MinimumTimeDifference.java | 49 +++-- .../array/RevealCardsInIncreasingOrder.java | 62 ++++++ .../MinimumWindowSubsequence.java | 102 ++++----- .../depth_first_search/NumberOfEnclaves.java | 76 +++---- .../divide_and_conquer/ReversePairsII.java | 46 ++-- .../dynamic_programming/OnesAndZeroes.java | 54 ++--- problems/src/hashing/NumberOfAtoms.java | 199 +++++++++--------- .../NextGreaterNodeInLinkedList.java | 94 +++++---- .../linked_list/SplitLinkedListInParts.java | 106 +++++----- problems/src/math/Base7.java | 34 +-- problems/src/string/ReverseStringII.java | 36 ++-- problems/src/string/ValidateIPAddress.java | 77 +++---- .../tree/ConstructBinaryTreefromString.java | 123 ++++++----- .../src/tree/FindBottomLeftTreeValue.java | 6 +- .../tree/FindLargestValueInEachTreeRow.java | 82 ++++---- .../src/tree/FlipEquivalentBinaryTrees.java | 76 ++++--- 19 files changed, 704 insertions(+), 606 deletions(-) create mode 100644 problems/src/array/RevealCardsInIncreasingOrder.java diff --git a/README.md b/README.md index 4daf89ac..32b6eb6e 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Find Pivot Index](problems/src/array/FindPivotIndex.java) (Easy) - [Largest Time for Given Digits](problems/src/array/LargestTimeForGivenDigits.java) (Easy) - [Minimum Time Difference](problems/src/array/MinimumTimeDifference.java) (Medium) +- [Reveal Cards In Increasing Order](problems/src/array/RevealCardsInIncreasingOrder.java) (Medium) #### [Backtracking](problems/src/backtracking) diff --git a/problems/src/array/FindPivotIndex.java b/problems/src/array/FindPivotIndex.java index cd27226d..2de89a50 100644 --- a/problems/src/array/FindPivotIndex.java +++ b/problems/src/array/FindPivotIndex.java @@ -1,4 +1,5 @@ package array; + import java.util.*; /** @@ -27,39 +28,39 @@ *

The length of nums will be in the range [0, 10000]. Each element nums[i] will be an integer in * the range [-1000, 1000]. * - * Solution: O(N) maintain a prefix and posfix sum array and then use this to arrive at the answer. + *

Solution: O(N) maintain a prefix and posfix sum array and then use this to arrive at the + * answer. */ public class FindPivotIndex { - public static void main(String[] args) { - } + public static void main(String[] args) {} - public int pivotIndex(int[] nums) { - if(nums.length == 1) return 0; - int[] left = new int[nums.length]; - int[] right = new int[nums.length]; - left[0] = nums[0]; - for(int i = 1; i < nums.length; i ++){ - left[i] = left[i - 1] + nums[i]; - } - right[nums.length - 1] = nums[nums.length - 1]; - for(int i = nums.length - 2; i >= 0; i --){ - right[i] = right[i + 1] + nums[i]; - } - for(int i = 0; i < nums.length; i ++){ - int l, r; - if(i == 0){ - l = 0; - } else { - l = left[i - 1]; - } + public int pivotIndex(int[] nums) { + if (nums.length == 1) return 0; + int[] left = new int[nums.length]; + int[] right = new int[nums.length]; + left[0] = nums[0]; + for (int i = 1; i < nums.length; i++) { + left[i] = left[i - 1] + nums[i]; + } + right[nums.length - 1] = nums[nums.length - 1]; + for (int i = nums.length - 2; i >= 0; i--) { + right[i] = right[i + 1] + nums[i]; + } + for (int i = 0; i < nums.length; i++) { + int l, r; + if (i == 0) { + l = 0; + } else { + l = left[i - 1]; + } - if(i == nums.length - 1){ - r = 0; - } else { - r = right[i + 1]; - } - if(l == r) return i; - } - return -1; + if (i == nums.length - 1) { + r = 0; + } else { + r = right[i + 1]; + } + if (l == r) return i; } + return -1; + } } diff --git a/problems/src/array/LargestTimeForGivenDigits.java b/problems/src/array/LargestTimeForGivenDigits.java index 267c7fed..32b63b5c 100644 --- a/problems/src/array/LargestTimeForGivenDigits.java +++ b/problems/src/array/LargestTimeForGivenDigits.java @@ -18,8 +18,8 @@ * *

Note: * - *

A.length == 4 0 <= A[i] <= 9 - * Solution O(N ^ 4) Check all combinations of time possible and return the maximum possible as the answer. + *

A.length == 4 0 <= A[i] <= 9 Solution O(N ^ 4) Check all combinations of time possible and + * return the maximum possible as the answer. */ public class LargestTimeForGivenDigits { public static void main(String[] args) { @@ -30,18 +30,18 @@ public static void main(String[] args) { public String largestTimeFromDigits(int[] A) { int max = -1; String result = ""; - for(int i = 0; i < A.length; i ++){ - if(A[i] > 2) continue; - for(int j = 0; j < A.length; j ++){ - if(j == i) continue; - if(A[i] == 2 && A[j] > 3) continue; - for(int k = 0; k < A.length; k ++){ - if(k == i || k == j) continue; - if(A[k] > 5) continue; - for(int l = 0; l < A.length; l ++){ - if(l == i || l == j || l == k) continue; + for (int i = 0; i < A.length; i++) { + if (A[i] > 2) continue; + for (int j = 0; j < A.length; j++) { + if (j == i) continue; + if (A[i] == 2 && A[j] > 3) continue; + for (int k = 0; k < A.length; k++) { + if (k == i || k == j) continue; + if (A[k] > 5) continue; + for (int l = 0; l < A.length; l++) { + if (l == i || l == j || l == k) continue; int value = ((A[i] * 10 + A[j]) * 60) + A[k] * 10 + A[l]; - if(value > max){ + if (value > max) { max = value; result = A[i] + "" + A[j] + ":" + A[k] + "" + A[l]; } diff --git a/problems/src/array/MinimumTimeDifference.java b/problems/src/array/MinimumTimeDifference.java index 757e87ee..a70e86f2 100644 --- a/problems/src/array/MinimumTimeDifference.java +++ b/problems/src/array/MinimumTimeDifference.java @@ -1,4 +1,5 @@ package array; + import java.util.*; import java.util.stream.Collectors; @@ -9,32 +10,38 @@ * list is at least 2 and won't exceed 20000. The input time is legal and ranges from 00:00 to * 23:59. * - * Solution: O(N log N) convert each time value of the form hh:mm to minutes and sort the array. For every pair (i, - * j) where j = i + 1 (also for the case where i = 0 and j = N - 1) check the minute difference and return the - * minimum time difference as the answer. + *

Solution: O(N log N) convert each time value of the form hh:mm to minutes and sort the array. + * For every pair (i, j) where j = i + 1 (also for the case where i = 0 and j = N - 1) check the + * minute difference and return the minimum time difference as the answer. */ public class MinimumTimeDifference { public static void main(String[] args) { - List list = Arrays.asList("23:59","00:00"); + List list = Arrays.asList("23:59", "00:00"); System.out.println(new MinimumTimeDifference().findMinDifference(list)); } - public int findMinDifference(List timePoints) { - List timeInMinutes = timePoints.stream().map(t -> { - String[] strings = t.split(":"); - return Integer.parseInt(strings[0]) * 60 + Integer.parseInt(strings[1]); - }).sorted(Integer::compareTo).collect(Collectors.toList()); - int min = Integer.MAX_VALUE; - for(int i = 1, l = timeInMinutes.size(); i < l; i ++){ - int prev = timeInMinutes.get(i - 1); - int curr = timeInMinutes.get(i); - min = Math.min(min, curr - prev); - min = Math.min(min, ((24 * 60) - curr) + prev); - } - int prev = timeInMinutes.get(0); - int curr = timeInMinutes.get(timeInMinutes.size() - 1); - min = Math.min(min, curr - prev); - min = Math.min(min, ((24 * 60) - curr) + prev); - return min; + public int findMinDifference(List timePoints) { + List timeInMinutes = + timePoints + .stream() + .map( + t -> { + String[] strings = t.split(":"); + return Integer.parseInt(strings[0]) * 60 + Integer.parseInt(strings[1]); + }) + .sorted(Integer::compareTo) + .collect(Collectors.toList()); + int min = Integer.MAX_VALUE; + for (int i = 1, l = timeInMinutes.size(); i < l; i++) { + int prev = timeInMinutes.get(i - 1); + int curr = timeInMinutes.get(i); + min = Math.min(min, curr - prev); + min = Math.min(min, ((24 * 60) - curr) + prev); } + int prev = timeInMinutes.get(0); + int curr = timeInMinutes.get(timeInMinutes.size() - 1); + min = Math.min(min, curr - prev); + min = Math.min(min, ((24 * 60) - curr) + prev); + return min; + } } diff --git a/problems/src/array/RevealCardsInIncreasingOrder.java b/problems/src/array/RevealCardsInIncreasingOrder.java new file mode 100644 index 00000000..f48432ed --- /dev/null +++ b/problems/src/array/RevealCardsInIncreasingOrder.java @@ -0,0 +1,62 @@ +package array; + +import java.util.ArrayDeque; +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 12/08/2019 In a deck of cards, every card has a unique integer. + * You can order the deck in any order you want. + * + *

Initially, all the cards start face down (unrevealed) in one deck. + * + *

Now, you do the following steps repeatedly, until all cards are revealed: + * + *

Take the top card of the deck, reveal it, and take it out of the deck. If there are still + * cards in the deck, put the next top card of the deck at the bottom of the deck. If there are + * still unrevealed cards, go back to step 1. Otherwise, stop. Return an ordering of the deck that + * would reveal the cards in increasing order. + * + *

The first entry in the answer is considered to be the top of the deck. + * + *

Example 1: + * + *

Input: [17,13,11,2,3,5,7] Output: [2,13,3,11,5,17,7] Explanation: We get the deck in the order + * [17,13,11,2,3,5,7] (this order doesn't matter), and reorder it. After reordering, the deck starts + * as [2,13,3,11,5,17,7], where 2 is the top of the deck. We reveal 2, and move 13 to the bottom. + * The deck is now [3,11,5,17,7,13]. We reveal 3, and move 11 to the bottom. The deck is now + * [5,17,7,13,11]. We reveal 5, and move 17 to the bottom. The deck is now [7,13,11,17]. We reveal + * 7, and move 13 to the bottom. The deck is now [11,17,13]. We reveal 11, and move 17 to the + * bottom. The deck is now [13,17]. We reveal 13, and move 17 to the bottom. The deck is now [17]. + * We reveal 17. Since all the cards revealed are in increasing order, the answer is correct. + * + *

Note: + * + *

1 <= A.length <= 1000 1 <= A[i] <= 10^6 A[i] != A[j] for all i != j + * + *

Solution: O(N) General idea is to start from the last element and build the array of element + * in the backwards order. Use a doubly-ended queue which allows you to poll from either end of a + * queue. + */ +public class RevealCardsInIncreasingOrder { + public static void main(String[] args) { + int[] A = {17, 13, 11, 2, 3, 5, 7}; + int[] R = new RevealCardsInIncreasingOrder().deckRevealedIncreasing(A); + } + + public int[] deckRevealedIncreasing(int[] deck) { + Arrays.sort(deck); + ArrayDeque queue = new ArrayDeque<>(); + for (int i = deck.length - 1; i >= 0; i--) { + queue.offer(deck[i]); + if (i == 0) break; + int temp = queue.pollFirst(); + queue.offer(temp); + } + int[] answer = new int[deck.length]; + int i = 0; + while (!queue.isEmpty()) { + answer[i++] = queue.pollLast(); + } + return answer; + } +} diff --git a/problems/src/binary_search/MinimumWindowSubsequence.java b/problems/src/binary_search/MinimumWindowSubsequence.java index b1a174f4..d3310d8d 100644 --- a/problems/src/binary_search/MinimumWindowSubsequence.java +++ b/problems/src/binary_search/MinimumWindowSubsequence.java @@ -1,5 +1,7 @@ package binary_search; + import java.util.*; + /** * Created by gouthamvidyapradhan on 06/08/2019 Given strings S and T, find the minimum (contiguous) * substring W of S, so that T is a subsequence of W. @@ -19,12 +21,13 @@ *

All the strings in the input will only contain lowercase letters. The length of S will be in * the range [1, 20000]. The length of T will be in the range [1, 100]. * - * Solution O(S x T x log S) General idea is to first find the left-most left (l) and right (r) index where r - l is - * minimum and the minimum window contains the sub-sequence and iteratively check the next left-most indices and - * continue for the entire string S. A naive implementation would result in O(S ^ 2) - * therefore to speed up we have to maintain a hashtable of character as key and all its index of occurrence in a - * sorted list. Now, since this list is sorted we can easily find the next left-most by binarySearch or even better - * by using a TreeSet higher or ceil function. + *

Solution O(S x T x log S) General idea is to first find the left-most left (l) and right (r) + * index where r - l is minimum and the minimum window contains the sub-sequence and iteratively + * check the next left-most indices and continue for the entire string S. A naive implementation + * would result in O(S ^ 2) therefore to speed up we have to maintain a hashtable of character as + * key and all its index of occurrence in a sorted list. Now, since this list is sorted we can + * easily find the next left-most by binarySearch or even better by using a TreeSet higher or ceil + * function. */ public class MinimumWindowSubsequence { public static void main(String[] args) { @@ -32,48 +35,49 @@ public static void main(String[] args) { } public String minWindow(String S, String T) { - if(T.isEmpty() || S.isEmpty()) return ""; - Map> charMap = new HashMap<>(); - for(int i = 0, l = S.length(); i < l; i ++){ - char c = S.charAt(i); - charMap.putIfAbsent(c, new TreeSet<>()); - charMap.get(c).add(i); - } - int min = Integer.MAX_VALUE; - int start = -1, end; - int ansStart = -1, ansEnd = -1; - boolean finished = false; - while(true){ - int index = start; - end = -1; - for(int i = 0, l = T.length(); i < l; i ++){ - char c = T.charAt(i); - if(!charMap.containsKey(c)){ - return ""; - } else{ - TreeSet indicies = charMap.get(c); - Integer found = indicies.higher(index); - if(found == null){ - finished = true; - break; - } else{ - index = found; - if(i == 0){ - start = index; - } if(i == l - 1){ - end = index; - } - } - } - } - if(start != -1 && end != -1){ - if((end - start) < min){ - min = end - start; - ansStart = start; - ansEnd = end; - } - } - if(finished) return ansStart == -1 ? "" : S.substring(ansStart, ansEnd + 1); - } + if (T.isEmpty() || S.isEmpty()) return ""; + Map> charMap = new HashMap<>(); + for (int i = 0, l = S.length(); i < l; i++) { + char c = S.charAt(i); + charMap.putIfAbsent(c, new TreeSet<>()); + charMap.get(c).add(i); + } + int min = Integer.MAX_VALUE; + int start = -1, end; + int ansStart = -1, ansEnd = -1; + boolean finished = false; + while (true) { + int index = start; + end = -1; + for (int i = 0, l = T.length(); i < l; i++) { + char c = T.charAt(i); + if (!charMap.containsKey(c)) { + return ""; + } else { + TreeSet indicies = charMap.get(c); + Integer found = indicies.higher(index); + if (found == null) { + finished = true; + break; + } else { + index = found; + if (i == 0) { + start = index; + } + if (i == l - 1) { + end = index; + } + } + } + } + if (start != -1 && end != -1) { + if ((end - start) < min) { + min = end - start; + ansStart = start; + ansEnd = end; + } + } + if (finished) return ansStart == -1 ? "" : S.substring(ansStart, ansEnd + 1); + } } } diff --git a/problems/src/depth_first_search/NumberOfEnclaves.java b/problems/src/depth_first_search/NumberOfEnclaves.java index f35ebbbf..aa6438c7 100644 --- a/problems/src/depth_first_search/NumberOfEnclaves.java +++ b/problems/src/depth_first_search/NumberOfEnclaves.java @@ -21,55 +21,55 @@ *

Note: * *

1 <= A.length <= 500 1 <= A[i].length <= 500 0 <= A[i][j] <= 1 All rows have the same size. - * Solution O(N x M) Do a dfs to count number of enclaves - in each dfs check if it violates the condition to be - * considered a enclave. + * Solution O(N x M) Do a dfs to count number of enclaves - in each dfs check if it violates the + * condition to be considered a enclave. */ public class NumberOfEnclaves { - final int[] R = {0, 0, -1, 1}; - final int[] C = {1, -1, 0, 0}; + final int[] R = {0, 0, -1, 1}; + final int[] C = {1, -1, 0, 0}; + + boolean[][] done; + int count = 0; + int answer = 0; + boolean possible = true; - boolean[][] done; - int count = 0; - int answer = 0; - boolean possible = true; public static void main(String[] args) { - int[][] A = {{0, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}}; + int[][] A = {{0, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}}; System.out.println(new NumberOfEnclaves().numEnclaves(A)); } - public int numEnclaves(int[][] A) { - done = new boolean[A.length][A[0].length]; - for(int i = 0; i < A.length; i ++){ - for(int j = 0; j < A[0].length; j ++){ - if(!done[i][j] && A[i][j] == 1){ - count = 0; - possible = true; - dfs(A, i, j); - if(possible){ - answer += count; - } - } - } + public int numEnclaves(int[][] A) { + done = new boolean[A.length][A[0].length]; + for (int i = 0; i < A.length; i++) { + for (int j = 0; j < A[0].length; j++) { + if (!done[i][j] && A[i][j] == 1) { + count = 0; + possible = true; + dfs(A, i, j); + if (possible) { + answer += count; + } } - return answer; + } } + return answer; + } - private void dfs(int[][] A, int r, int c){ - done[r][c] = true; - if(r == 0 || c == 0 || r == A.length - 1 || c == A[0].length - 1){ - possible = false; - } - count++; - for(int i = 0; i < 4; i ++){ - int newR = r + R[i]; - int newC = c + C[i]; - if(newR < A.length && newC < A[0].length && newR >= 0 && newC >= 0 && !done[newR][newC]){ - if(A[newR][newC] == 1){ - dfs(A, newR, newC); - } - } + private void dfs(int[][] A, int r, int c) { + done[r][c] = true; + if (r == 0 || c == 0 || r == A.length - 1 || c == A[0].length - 1) { + possible = false; + } + count++; + for (int i = 0; i < 4; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR < A.length && newC < A[0].length && newR >= 0 && newC >= 0 && !done[newR][newC]) { + if (A[newR][newC] == 1) { + dfs(A, newR, newC); } + } } - + } } diff --git a/problems/src/divide_and_conquer/ReversePairsII.java b/problems/src/divide_and_conquer/ReversePairsII.java index 46b8a8a9..60326d1e 100644 --- a/problems/src/divide_and_conquer/ReversePairsII.java +++ b/problems/src/divide_and_conquer/ReversePairsII.java @@ -12,73 +12,73 @@ * *

Input: [2,4,3,5,1] Output: 3 Note: The length of the given array will not exceed 50,000. All * the numbers in the input array are in the range of 32-bit integer. - - * Solution: O(N log N) Given two sorted arrays A[] and B[] it is quite easy to see for every element i in A, how - * many elements in A have a value > 2 * B[j] using binary search (also possible using two pointers) - using this idea - * we can implement standard merge sort algorithm and for every sorted pairs A[] and B[] before we merge we can total - * number of elements in A which are > 2 x B[i] * + *

Solution: O(N log N) Given two sorted arrays A[] and B[] it is quite easy to see for every + * element i in A, how many elements in A have a value > 2 * B[j] using binary search (also possible + * using two pointers) - using this idea we can implement standard merge sort algorithm and for + * every sorted pairs A[] and B[] before we merge we can total number of elements in A which are > 2 + * x B[i] */ public class ReversePairsII { public static void main(String[] args) { - int[] A = {2,4,3,5,1}; + int[] A = {2, 4, 3, 5, 1}; System.out.println(new ReversePairsII().reversePairs(A)); } int answer = 0; + public int reversePairs(int[] nums) { mergeSort(nums, 0, nums.length - 1); return answer; } - - private int[] mergeSort(int[] num, int l, int h){ - if(l < h){ + private int[] mergeSort(int[] num, int l, int h) { + if (l < h) { int m = l + (h - l) / 2; int[] left = mergeSort(num, l, m); int[] right = mergeSort(num, m + 1, h); return merge(left, right); - } else if(l == h){ - return new int[]{num[l]}; + } else if (l == h) { + return new int[] {num[l]}; } else { - return new int[]{}; + return new int[] {}; } } - private int[] merge(int[] A, int[] B){ - for(int i = 0 ; i < B.length; i ++){ + private int[] merge(int[] A, int[] B) { + for (int i = 0; i < B.length; i++) { int num = B[i]; int l = 0, h = A.length; int index = -1; - while(l < h){ + while (l < h) { int m = l + (h - l) / 2; - if((long)A[m] > (2 * (long)num)){ + if ((long) A[m] > (2 * (long) num)) { index = m; h = m; } else { l = m + 1; } } - if(index > -1){ + if (index > -1) { answer += ((A.length - index)); } } int[] C = new int[A.length + B.length]; int k = 0; int i = 0, j = 0; - for(; i < A.length && j < B.length;){ - if(A[i] < B[j]){ + for (; i < A.length && j < B.length; ) { + if (A[i] < B[j]) { C[k++] = A[i]; - i ++; + i++; } else { C[k++] = B[j]; - j ++; + j++; } } - while(i < A.length){ + while (i < A.length) { C[k++] = A[i++]; } - while(j < B.length){ + while (j < B.length) { C[k++] = B[j++]; } return C; diff --git a/problems/src/dynamic_programming/OnesAndZeroes.java b/problems/src/dynamic_programming/OnesAndZeroes.java index 5325ae0e..fe4d0bde 100644 --- a/problems/src/dynamic_programming/OnesAndZeroes.java +++ b/problems/src/dynamic_programming/OnesAndZeroes.java @@ -28,37 +28,37 @@ * *

Explanation: You could form "10", but then you'd have nothing left. Better form "0" and "1". * - * Solution: O(S x m x n) For every string array position we have two choices i. pick this value or ii. - * not pick this value. Evaluate both these cases and cache the result in a dp array. + *

Solution: O(S x m x n) For every string array position we have two choices i. pick this value + * or ii. not pick this value. Evaluate both these cases and cache the result in a dp array. */ public class OnesAndZeroes { - public static void main(String[] args) { - String[] str = {"10", "0", "1"}; + public static void main(String[] args) { + String[] str = {"10", "0", "1"}; System.out.println(new OnesAndZeroes().findMaxForm(str, 1, 1)); - } + } - public int findMaxForm(String[] strs, int m, int n) { - int[][][] dp = new int[strs.length + 1][m + 1][n + 1]; - for(int i = strs.length - 1; i >= 0; i --){ - String string = strs[i]; - int zero = 0; - int one = 0; - for(char c : string.toCharArray()){ - if(c == '0'){ - zero++; - } else{ - one ++; - } - } - for(int p = m; p >= 0; p --){ - for(int q = n; q >= 0; q--){ - dp[i][p][q] = dp[i + 1][p][q]; - if(p - zero >= 0 && q - one >= 0){ - dp[i][p][q] = Math.max(dp[i][p][q], dp[i + 1][p - zero][q - one] + 1); - } - } - } + public int findMaxForm(String[] strs, int m, int n) { + int[][][] dp = new int[strs.length + 1][m + 1][n + 1]; + for (int i = strs.length - 1; i >= 0; i--) { + String string = strs[i]; + int zero = 0; + int one = 0; + for (char c : string.toCharArray()) { + if (c == '0') { + zero++; + } else { + one++; + } + } + for (int p = m; p >= 0; p--) { + for (int q = n; q >= 0; q--) { + dp[i][p][q] = dp[i + 1][p][q]; + if (p - zero >= 0 && q - one >= 0) { + dp[i][p][q] = Math.max(dp[i][p][q], dp[i + 1][p - zero][q - one] + 1); + } } - return dp[0][m][n]; + } } + return dp[0][m][n]; + } } diff --git a/problems/src/hashing/NumberOfAtoms.java b/problems/src/hashing/NumberOfAtoms.java index a8655182..09513fae 100644 --- a/problems/src/hashing/NumberOfAtoms.java +++ b/problems/src/hashing/NumberOfAtoms.java @@ -1,4 +1,5 @@ package hashing; + import java.util.*; /** @@ -31,9 +32,9 @@ * uppercase. The length of formula will be in the range [1, 1000]. formula will only consist of * letters, digits, and round parentheses, and is a valid formula as defined in the problem. * - * Solution O(N ^ 2) Recursively solve each substring within round braces as subformula. Consider each subformula as - * right subformula and each each subformula before the round braces as left subformula - sum up value of both left - * and right subformula to get the answer. + *

Solution O(N ^ 2) Recursively solve each substring within round braces as subformula. Consider + * each subformula as right subformula and each each subformula before the round braces as left + * subformula - sum up value of both left and right subformula to get the answer. */ public class NumberOfAtoms { public static void main(String[] args) { @@ -41,107 +42,107 @@ public static void main(String[] args) { System.out.println(result); } - public String countOfAtoms(String formula) { - Map atomCountResult = new NumberOfAtoms().countOfAtoms(formula, 0); - List sortedKeys = new ArrayList<>(atomCountResult.keySet()); - sortedKeys.sort(Comparator.naturalOrder()); - StringBuilder result = new StringBuilder(); - for(String k : sortedKeys){ - int count = atomCountResult.get(k); - if(count > 1){ - result.append(k).append(count); - } else result.append(k); - } - return result.toString(); + public String countOfAtoms(String formula) { + Map atomCountResult = new NumberOfAtoms().countOfAtoms(formula, 0); + List sortedKeys = new ArrayList<>(atomCountResult.keySet()); + sortedKeys.sort(Comparator.naturalOrder()); + StringBuilder result = new StringBuilder(); + for (String k : sortedKeys) { + int count = atomCountResult.get(k); + if (count > 1) { + result.append(k).append(count); + } else result.append(k); } + return result.toString(); + } - private Map countOfAtoms(String formula, int startPos){ - Map left = new HashMap<>(); - StringBuilder atom = new StringBuilder(); - StringBuilder atomCount = new StringBuilder(); - for (int i = startPos; i < formula.length();){ - char c = formula.charAt(i); - if(c >= 'A' && c <= 'Z'){ - if(atom.length() > 0){ - int count = 1; - if(atomCount.length() > 0){ - count = Integer.parseInt(atomCount.toString()); - } - String atomKey = atom.toString(); - if(left.containsKey(atomKey)){ - left.put(atomKey, left.get(atomKey) + count); - } else left.put(atom.toString(), count); - atom = new StringBuilder(); - atomCount = new StringBuilder(); - } - atom.append(c); - i++; - } else if(c >= 'a' && c <= 'z'){ - atom.append(c); - i++; - } else if(c >= '0' && c <= '9'){ - atomCount.append(c); - i++; - } else{ - //this is equal to '(' - if(atom.length() > 0){ - int count = 1; - if(atomCount.length() > 0){ - count = Integer.parseInt(atomCount.toString()); - } - String atomKey = atom.toString(); - if(left.containsKey(atomKey)){ - left.put(atomKey, left.get(atomKey) + count); - } else left.put(atom.toString(), count); - atom = new StringBuilder(); - atomCount = new StringBuilder(); - } - int j = i, count = 0; - for(int l = formula.length(); j < l; j ++){ - if(formula.charAt(j) == '('){ - count ++; - } else if(formula.charAt(j) == ')'){ - count --; - } - if(count == 0) break; - } - Map right = countOfAtoms(formula.substring(i + 1, j), 0); - j++; - StringBuilder rightAtomCount = new StringBuilder(); - for(int l = formula.length(); j < l; j ++){ - if(formula.charAt(j) >= '0' && formula.charAt(j) <= '9'){ - rightAtomCount.append(formula.charAt(j)); - } else break; - } - if(rightAtomCount.length() > 0){ - int mulFactor = Integer.parseInt(rightAtomCount.toString()); - for(String k : right.keySet()){ - right.put(k, right.get(k) * mulFactor); - } - } - left = merge(left, right); - i = j; + private Map countOfAtoms(String formula, int startPos) { + Map left = new HashMap<>(); + StringBuilder atom = new StringBuilder(); + StringBuilder atomCount = new StringBuilder(); + for (int i = startPos; i < formula.length(); ) { + char c = formula.charAt(i); + if (c >= 'A' && c <= 'Z') { + if (atom.length() > 0) { + int count = 1; + if (atomCount.length() > 0) { + count = Integer.parseInt(atomCount.toString()); } - } - if(atom.length() > 0){ - int count = 1; - if(atomCount.length() > 0){ - count = Integer.parseInt(atomCount.toString()); - } - String atomKey = atom.toString(); - if(left.containsKey(atomKey)){ - left.put(atomKey, left.get(atomKey) + count); - } else left.put(atom.toString(), count); + String atomKey = atom.toString(); + if (left.containsKey(atomKey)) { + left.put(atomKey, left.get(atomKey) + count); + } else left.put(atom.toString(), count); + atom = new StringBuilder(); + atomCount = new StringBuilder(); + } + atom.append(c); + i++; + } else if (c >= 'a' && c <= 'z') { + atom.append(c); + i++; + } else if (c >= '0' && c <= '9') { + atomCount.append(c); + i++; + } else { + // this is equal to '(' + if (atom.length() > 0) { + int count = 1; + if (atomCount.length() > 0) { + count = Integer.parseInt(atomCount.toString()); + } + String atomKey = atom.toString(); + if (left.containsKey(atomKey)) { + left.put(atomKey, left.get(atomKey) + count); + } else left.put(atom.toString(), count); + atom = new StringBuilder(); + atomCount = new StringBuilder(); + } + int j = i, count = 0; + for (int l = formula.length(); j < l; j++) { + if (formula.charAt(j) == '(') { + count++; + } else if (formula.charAt(j) == ')') { + count--; + } + if (count == 0) break; + } + Map right = countOfAtoms(formula.substring(i + 1, j), 0); + j++; + StringBuilder rightAtomCount = new StringBuilder(); + for (int l = formula.length(); j < l; j++) { + if (formula.charAt(j) >= '0' && formula.charAt(j) <= '9') { + rightAtomCount.append(formula.charAt(j)); + } else break; } - return left; + if (rightAtomCount.length() > 0) { + int mulFactor = Integer.parseInt(rightAtomCount.toString()); + for (String k : right.keySet()) { + right.put(k, right.get(k) * mulFactor); + } + } + left = merge(left, right); + i = j; + } } - - private Map merge(Map left, Map right){ - for(String k : left.keySet()){ - if(right.containsKey(k)){ - right.put(k, right.get(k) + left.get(k)); - } else right.put(k, left.get(k)); + if (atom.length() > 0) { + int count = 1; + if (atomCount.length() > 0) { + count = Integer.parseInt(atomCount.toString()); } - return right; + String atomKey = atom.toString(); + if (left.containsKey(atomKey)) { + left.put(atomKey, left.get(atomKey) + count); + } else left.put(atom.toString(), count); } + return left; + } + + private Map merge(Map left, Map right) { + for (String k : left.keySet()) { + if (right.containsKey(k)) { + right.put(k, right.get(k) + left.get(k)); + } else right.put(k, left.get(k)); + } + return right; + } } diff --git a/problems/src/linked_list/NextGreaterNodeInLinkedList.java b/problems/src/linked_list/NextGreaterNodeInLinkedList.java index 1967d6c3..3abc6bca 100644 --- a/problems/src/linked_list/NextGreaterNodeInLinkedList.java +++ b/problems/src/linked_list/NextGreaterNodeInLinkedList.java @@ -1,5 +1,7 @@ package linked_list; + import java.util.*; + /** * Created by gouthamvidyapradhan on 31/07/2019 We are given a linked list with head as the first * node. Let's number the nodes in the list: node_1, node_2, node_3, ... etc. @@ -27,63 +29,65 @@ *

1 <= node.val <= 10^9 for each node in the linked list. The given list has length in the range * [0, 10000]. * - * Solution O(N) solve the problem in the inverse order starting from the tail of the list. Maintain a stack of - * values and on each iteration pop() all the values from the stack which are smaller then the current element. + *

Solution O(N) solve the problem in the inverse order starting from the tail of the list. + * Maintain a stack of values and on each iteration pop() all the values from the stack which are + * smaller then the current element. */ public class NextGreaterNodeInLinkedList { - public static class ListNode { + public static class ListNode { int val; - ListNode next; - ListNode(int x) { val = x; } - } + ListNode next; + + ListNode(int x) { + val = x; + } + } private List result; + public static void main(String[] args) { - ListNode node = new ListNode(1); - node.next = new ListNode(2); + ListNode node = new ListNode(1); + node.next = new ListNode(2); new NextGreaterNodeInLinkedList().nextLargerNodes(node); } - public int[] nextLargerNodes(ListNode head) { - result = new ArrayList<>(); - find(head, result); - Collections.reverse(result); - int[] answer = new int[result.size()]; - for(int i = 0, l = result.size(); i < l; i ++){ - answer[i] = result.get(i); - } - return answer; + public int[] nextLargerNodes(ListNode head) { + result = new ArrayList<>(); + find(head, result); + Collections.reverse(result); + int[] answer = new int[result.size()]; + for (int i = 0, l = result.size(); i < l; i++) { + answer[i] = result.get(i); + } + return answer; } - - - private Stack find(ListNode head, List answer){ - if(head == null){ - return new Stack<>(); + private Stack find(ListNode head, List answer) { + if (head == null) { + return new Stack<>(); + } + Stack stack = find(head.next, answer); + if (stack.isEmpty()) { + answer.add(0); + stack.push(head.val); + } else { + if (stack.peek() > head.val) { + answer.add(stack.peek()); + stack.push(head.val); + } else { + while (!stack.isEmpty() && stack.peek() <= head.val) { + stack.pop(); } - Stack stack = find(head.next, answer); - if(stack.isEmpty()){ - answer.add(0); - stack.push(head.val); - } else{ - if(stack.peek() > head.val){ - answer.add(stack.peek()); - stack.push(head.val); - } else { - while(!stack.isEmpty() && stack.peek() <= head.val){ - stack.pop(); - } - if(stack.isEmpty()){ - stack.push(head.val); - answer.add(0); - } else{ - answer.add(stack.peek()); - stack.push(head.val); - } - } - } - return stack; + if (stack.isEmpty()) { + stack.push(head.val); + answer.add(0); + } else { + answer.add(stack.peek()); + stack.push(head.val); + } + } } - + return stack; + } } diff --git a/problems/src/linked_list/SplitLinkedListInParts.java b/problems/src/linked_list/SplitLinkedListInParts.java index 46b02c24..44f0908a 100644 --- a/problems/src/linked_list/SplitLinkedListInParts.java +++ b/problems/src/linked_list/SplitLinkedListInParts.java @@ -1,5 +1,7 @@ package linked_list; + import java.util.*; + /** * Created by gouthamvidyapradhan on 06/08/2019 Given a (singly) linked list with head node root, * write a function to split the linked list into k consecutive linked list "parts". @@ -25,65 +27,69 @@ *

The length of root will be in the range [0, 1000]. Each value of a node in the input will be * an integer in the range [0, 999]. k will be an integer in the range [1, 50]. * - * Solution O(N) do a linear scan and split the array by required size. + *

Solution O(N) do a linear scan and split the array by required size. */ public class SplitLinkedListInParts { - public static class ListNode { + public static class ListNode { int val; ListNode next; - ListNode(int x) { val = x; } - } + + ListNode(int x) { + val = x; + } + } + public static void main(String[] args) { - ListNode root = new ListNode(1); - root.next = new ListNode(2); - root.next.next = new ListNode(3); - ListNode[] result = new SplitLinkedListInParts().splitListToParts(root, 5); + ListNode root = new ListNode(1); + root.next = new ListNode(2); + root.next.next = new ListNode(3); + ListNode[] result = new SplitLinkedListInParts().splitListToParts(root, 5); System.out.println(result); } - public ListNode[] splitListToParts(ListNode root, int k) { - List list = new ArrayList<>(); - while(root != null){ - list.add(root.val); - root = root.next; - } - int tempK = k; - int N = list.size(); - List result = new ArrayList<>(); - ListNode head = new ListNode(-1); - ListNode prev = head; - int i = 0, j = 0; - int count = 0; - int P = N / tempK; - if((N % tempK) > 0){ - P++; - } - for(; j < N; ){ - if(j - i < P){ - prev.next = new ListNode(list.get(j)); - prev = prev.next; - j ++; - count ++; - } else{ - result.add(head.next); - i = j; - head = new ListNode(-1); - prev = head; - tempK --; - P = (N - count) / tempK; - if(((N - count) % tempK) > 0){ - P++; - } - } - } + public ListNode[] splitListToParts(ListNode root, int k) { + List list = new ArrayList<>(); + while (root != null) { + list.add(root.val); + root = root.next; + } + int tempK = k; + int N = list.size(); + List result = new ArrayList<>(); + ListNode head = new ListNode(-1); + ListNode prev = head; + int i = 0, j = 0; + int count = 0; + int P = N / tempK; + if ((N % tempK) > 0) { + P++; + } + for (; j < N; ) { + if (j - i < P) { + prev.next = new ListNode(list.get(j)); + prev = prev.next; + j++; + count++; + } else { result.add(head.next); - while(result.size() < k){ - result.add(null); - } - ListNode[] nodes = new ListNode[result.size()]; - for(int l = 0; l < result.size(); l ++){ - nodes[l] = result.get(l); + i = j; + head = new ListNode(-1); + prev = head; + tempK--; + P = (N - count) / tempK; + if (((N - count) % tempK) > 0) { + P++; } - return nodes; + } } + result.add(head.next); + while (result.size() < k) { + result.add(null); + } + ListNode[] nodes = new ListNode[result.size()]; + for (int l = 0; l < result.size(); l++) { + nodes[l] = result.get(l); + } + return nodes; + } } diff --git a/problems/src/math/Base7.java b/problems/src/math/Base7.java index 438a7468..e35fd649 100644 --- a/problems/src/math/Base7.java +++ b/problems/src/math/Base7.java @@ -1,5 +1,7 @@ package math; + import java.util.*; + /** * Created by gouthamvidyapradhan on 01/08/2019 Given an integer, return its base 7 string * representation. @@ -8,22 +10,22 @@ * in range of [-1e7, 1e7]. */ public class Base7 { - public static void main(String[] args) { - // - } + public static void main(String[] args) { + // + } - public String convertToBase7(int num) { - Integer.toString(7, 7); - if(num == 0) return "0"; - int q = Math.abs(num), r; - StringBuilder sb = new StringBuilder(); - while(q != 0){ - r = q % 7; - sb.append(r); - q /= 7; - } - if(num < 0){ - return "-" + sb.reverse().toString(); - } else return sb.reverse().toString(); + public String convertToBase7(int num) { + Integer.toString(7, 7); + if (num == 0) return "0"; + int q = Math.abs(num), r; + StringBuilder sb = new StringBuilder(); + while (q != 0) { + r = q % 7; + sb.append(r); + q /= 7; } + if (num < 0) { + return "-" + sb.reverse().toString(); + } else return sb.reverse().toString(); + } } diff --git a/problems/src/string/ReverseStringII.java b/problems/src/string/ReverseStringII.java index b4eef278..58fb777b 100644 --- a/problems/src/string/ReverseStringII.java +++ b/problems/src/string/ReverseStringII.java @@ -8,30 +8,30 @@ * Example: Input: s = "abcdefg", k = 2 Output: "bacdfeg" Restrictions: The string consists of lower * English letters only. Length of the given string and k will in the range [1, 10000] * - * Solution O(N) + *

Solution O(N) */ public class ReverseStringII { public static void main(String[] args) { System.out.println(new ReverseStringII().reverseStr("abcdefg", 2)); } - public String reverseStr(String s, int k) { - StringBuilder sb = new StringBuilder(); - for(int i = 0, l = s.length(); i < l; i ++){ - if(i % (2 * k) == 0){ - int count = 0; - StringBuilder temp = new StringBuilder(); - while(count < k && i < l){ - temp.append(s.charAt(i)); - count ++; - i ++; - } - sb.append(temp.reverse()); - } - if(i < l){ - sb.append(s.charAt(i)); - } + public String reverseStr(String s, int k) { + StringBuilder sb = new StringBuilder(); + for (int i = 0, l = s.length(); i < l; i++) { + if (i % (2 * k) == 0) { + int count = 0; + StringBuilder temp = new StringBuilder(); + while (count < k && i < l) { + temp.append(s.charAt(i)); + count++; + i++; } - return sb.toString(); + sb.append(temp.reverse()); + } + if (i < l) { + sb.append(s.charAt(i)); + } } + return sb.toString(); + } } diff --git a/problems/src/string/ValidateIPAddress.java b/problems/src/string/ValidateIPAddress.java index 88e8e877..3f96d5ce 100644 --- a/problems/src/string/ValidateIPAddress.java +++ b/problems/src/string/ValidateIPAddress.java @@ -41,54 +41,55 @@ * *

Explanation: This is neither a IPv4 address nor a IPv6 address. * - * Solution: O(N) split the string by each '.' or ':' and then validate each parts. + *

Solution: O(N) split the string by each '.' or ':' and then validate each parts. */ public class ValidateIPAddress { public static void main(String[] args) { - System.out.println(new ValidateIPAddress().validIPAddress("02001:0db8:85a3:0000:0000:8a2e:0370:7334")); + System.out.println( + new ValidateIPAddress().validIPAddress("02001:0db8:85a3:0000:0000:8a2e:0370:7334")); } - public String validIPAddress(String IP) { - if(IP.contains(".")){ - if(IP.endsWith(".") || IP.startsWith("."))return "Neither"; - String[] ipv4 = IP.split("\\."); - if(ipv4.length != 4) return "Neither"; - else { - for(String part : ipv4){ - if(part.isEmpty()) return "Neither"; - if(part.length() > 1 && part.startsWith("0")) return "Neither"; - else { - if(part.length() > 3) return "Neither"; - for(char c : part.toCharArray()){ - if(c < '0' || c > '9') return "Neither"; - } - int value = Integer.parseInt(part); - if(value < 0 || value > 255) return "Neither"; - } + public String validIPAddress(String IP) { + if (IP.contains(".")) { + if (IP.endsWith(".") || IP.startsWith(".")) return "Neither"; + String[] ipv4 = IP.split("\\."); + if (ipv4.length != 4) return "Neither"; + else { + for (String part : ipv4) { + if (part.isEmpty()) return "Neither"; + if (part.length() > 1 && part.startsWith("0")) return "Neither"; + else { + if (part.length() > 3) return "Neither"; + for (char c : part.toCharArray()) { + if (c < '0' || c > '9') return "Neither"; } + int value = Integer.parseInt(part); + if (value < 0 || value > 255) return "Neither"; + } } - return "IPv4"; - } else if(IP.contains(":")){ - if(IP.endsWith(":") || IP.startsWith(":"))return "Neither"; - String[] ipv6 = IP.split(":"); - if(ipv6.length != 8) return "Neither"; + } + return "IPv4"; + } else if (IP.contains(":")) { + if (IP.endsWith(":") || IP.startsWith(":")) return "Neither"; + String[] ipv6 = IP.split(":"); + if (ipv6.length != 8) return "Neither"; + else { + for (String part : ipv6) { + if (part.isEmpty()) return "Neither"; + if (part.length() > 4) return "Neither"; else { - for(String part : ipv6){ - if(part.isEmpty()) return "Neither"; - if(part.length() > 4) return "Neither"; - else { - for(char c : part.toCharArray()){ - if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')){ + for (char c : part.toCharArray()) { + if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { - } else{ - return "Neither"; - } - } - } + } else { + return "Neither"; } + } } - return "IPv6"; - } else return "Neither"; - } + } + } + return "IPv6"; + } else return "Neither"; + } } diff --git a/problems/src/tree/ConstructBinaryTreefromString.java b/problems/src/tree/ConstructBinaryTreefromString.java index af5d497a..78bce3e1 100644 --- a/problems/src/tree/ConstructBinaryTreefromString.java +++ b/problems/src/tree/ConstructBinaryTreefromString.java @@ -13,76 +13,75 @@ *

Example: Input: "4(2(3)(1))(6(5))" Output: return the tree root node representing the * following tree: * - *

- * 4 - * / \ - * 2 6 - * /\ / - * 3 1 5 - - Note: There will only be '(', ')', '-' and '0' ~ '9' in the input - * string. An empty tree is represented by "" instead of "()". + *

4 / \ 2 6 /\ / 3 1 5 + * + *

Note: There will only be '(', ')', '-' and '0' ~ '9' in the input string. An empty tree is + * represented by "" instead of "()". * - * Solution: O(N ^ 2) Form a node for every number and treat the first sub-string within round braces as left node and - * the second sub-string within the round braces as the right node. Recursively solve each substring within the round - * braces. + *

Solution: O(N ^ 2) Form a node for every number and treat the first sub-string within round + * braces as left node and the second sub-string within the round braces as the right node. + * Recursively solve each substring within the round braces. */ public class ConstructBinaryTreefromString { - public class TreeNode { + public class TreeNode { int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } - } + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } public static void main(String[] args) { System.out.println(new ConstructBinaryTreefromString().str2tree("4(2(3)(1))(6(5))")); } - private TreeNode str2tree(String s){ - if(s == null || s.isEmpty()) return null; - TreeNode current; - StringBuilder num = new StringBuilder(); - boolean isNeg = false; - int i = 0; - for(; i < s.length(); i ++){ - if(s.charAt(i) == '-'){ - isNeg = true; - } else if(s.charAt(i) >= '0' && s.charAt(i) <= '9'){ - num.append(s.charAt(i)); - } else break; - } - if(isNeg){ - current = new TreeNode(Integer.parseInt(num.toString()) * -1); - } else current = new TreeNode(Integer.parseInt(num.toString())); - int count = 0; - StringBuilder left = new StringBuilder(); - for(; i < s.length(); i ++){ - if(s.charAt(i) == '('){ - count ++; - } else if(s.charAt(i) == ')'){ - count --; - } - left.append(s.charAt(i)); - if(count == 0){ - break; - } - } - i ++; - String leftStr = ""; - String rightStr = ""; - if(i < s.length()){ - rightStr = s.substring(i); - } - if(left.length() > 0){ - leftStr = left.subSequence(1, left.length() - 1).toString(); - } if(rightStr.length() > 0){ - rightStr = rightStr.substring(1, rightStr.length() - 1); - } - TreeNode leftNode = str2tree(leftStr); - TreeNode rightNode = str2tree(rightStr); - current.left = leftNode; - current.right = rightNode; - return current; + private TreeNode str2tree(String s) { + if (s == null || s.isEmpty()) return null; + TreeNode current; + StringBuilder num = new StringBuilder(); + boolean isNeg = false; + int i = 0; + for (; i < s.length(); i++) { + if (s.charAt(i) == '-') { + isNeg = true; + } else if (s.charAt(i) >= '0' && s.charAt(i) <= '9') { + num.append(s.charAt(i)); + } else break; } + if (isNeg) { + current = new TreeNode(Integer.parseInt(num.toString()) * -1); + } else current = new TreeNode(Integer.parseInt(num.toString())); + int count = 0; + StringBuilder left = new StringBuilder(); + for (; i < s.length(); i++) { + if (s.charAt(i) == '(') { + count++; + } else if (s.charAt(i) == ')') { + count--; + } + left.append(s.charAt(i)); + if (count == 0) { + break; + } + } + i++; + String leftStr = ""; + String rightStr = ""; + if (i < s.length()) { + rightStr = s.substring(i); + } + if (left.length() > 0) { + leftStr = left.subSequence(1, left.length() - 1).toString(); + } + if (rightStr.length() > 0) { + rightStr = rightStr.substring(1, rightStr.length() - 1); + } + TreeNode leftNode = str2tree(leftStr); + TreeNode rightNode = str2tree(rightStr); + current.left = leftNode; + current.right = rightNode; + return current; + } } diff --git a/problems/src/tree/FindBottomLeftTreeValue.java b/problems/src/tree/FindBottomLeftTreeValue.java index c6caf9c7..cc9fe291 100644 --- a/problems/src/tree/FindBottomLeftTreeValue.java +++ b/problems/src/tree/FindBottomLeftTreeValue.java @@ -12,9 +12,9 @@ * *

1 / \ 2 3 / / \ 4 5 6 / 7 * - *

Output: 7 Note: You may assume the tree (i.e., the given root node) is not NULL. - * Solution: O(N) do a inorder search to find the left most value. Keep a level counter to keep track of what level - * you are at when you do a inorder search. + *

Output: 7 Note: You may assume the tree (i.e., the given root node) is not NULL. Solution: + * O(N) do a inorder search to find the left most value. Keep a level counter to keep track of what + * level you are at when you do a inorder search. */ public class FindBottomLeftTreeValue { private int max = 0, result; diff --git a/problems/src/tree/FindLargestValueInEachTreeRow.java b/problems/src/tree/FindLargestValueInEachTreeRow.java index 3c5a3bfd..27717430 100644 --- a/problems/src/tree/FindLargestValueInEachTreeRow.java +++ b/problems/src/tree/FindLargestValueInEachTreeRow.java @@ -1,4 +1,5 @@ package tree; + import java.util.*; /** @@ -9,53 +10,56 @@ * *

1 / \ 3 2 / \ \ 5 3 9 * - *

Output: [1, 3, 9] - * Solution: O(N) do a bfs to check largest in each row. + *

Output: [1, 3, 9] Solution: O(N) do a bfs to check largest in each row. */ public class FindLargestValueInEachTreeRow { - public class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; } + } + + Map maxRow = new HashMap<>(); - Map maxRow = new HashMap<>(); + class Node { + int row; + TreeNode val; - class Node { - int row; - TreeNode val; - Node(int row, TreeNode val){ - this.row = row; - this.val = val; - } + Node(int row, TreeNode val) { + this.row = row; + this.val = val; } + } - public List largestValues(TreeNode root) { - if(root == null) return new ArrayList<>(); - Queue queue = new ArrayDeque<>(); - queue.offer(new Node(0, root)); - while(!queue.isEmpty()){ - Node top = queue.poll(); - maxRow.putIfAbsent(top.row, top.val.val); - maxRow.put(top.row, Math.max(maxRow.get(top.row), top.val.val)); - if(top.val.left != null){ - queue.offer(new Node(top.row + 1, top.val.left)); - } - if(top.val.right != null){ - queue.offer(new Node(top.row + 1, top.val.right)); - } - } - List answer = new ArrayList<>(); - List keyList = new ArrayList<>(maxRow.keySet()); - keyList.sort(Integer::compareTo); - for(int k : keyList){ - answer.add(maxRow.get(k)); - } - return answer; + public List largestValues(TreeNode root) { + if (root == null) return new ArrayList<>(); + Queue queue = new ArrayDeque<>(); + queue.offer(new Node(0, root)); + while (!queue.isEmpty()) { + Node top = queue.poll(); + maxRow.putIfAbsent(top.row, top.val.val); + maxRow.put(top.row, Math.max(maxRow.get(top.row), top.val.val)); + if (top.val.left != null) { + queue.offer(new Node(top.row + 1, top.val.left)); + } + if (top.val.right != null) { + queue.offer(new Node(top.row + 1, top.val.right)); + } } + List answer = new ArrayList<>(); + List keyList = new ArrayList<>(maxRow.keySet()); + keyList.sort(Integer::compareTo); + for (int k : keyList) { + answer.add(maxRow.get(k)); + } + return answer; + } - public static void main(String[] args) { + public static void main(String[] args) { // - } + } } diff --git a/problems/src/tree/FlipEquivalentBinaryTrees.java b/problems/src/tree/FlipEquivalentBinaryTrees.java index 18f3fdf7..00a476c8 100644 --- a/problems/src/tree/FlipEquivalentBinaryTrees.java +++ b/problems/src/tree/FlipEquivalentBinaryTrees.java @@ -19,19 +19,22 @@ *

Note: * *

Each tree will have at most 100 nodes. Each value in each tree will be a unique integer in the - * range [0, 99]. - * Solution O(N ^ 2) Since the node values are unique general idea is to find the node on right tree for every node - * on the left tree and check if the values need to be swapped, if yes then swap the node's left and right child in - * the left tree. After this operation is complete check if both the trees are equal + * range [0, 99]. Solution O(N ^ 2) Since the node values are unique general idea is to find the + * node on right tree for every node on the left tree and check if the values need to be swapped, if + * yes then swap the node's left and right child in the left tree. After this operation is complete + * check if both the trees are equal */ public class FlipEquivalentBinaryTrees { public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } - } + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } public static void main(String[] args) { TreeNode node = new TreeNode(1); @@ -59,49 +62,51 @@ public boolean flipEquiv(TreeNode root1, TreeNode root2) { return checkIfBothAreSame(root1, root2); } - private boolean checkIfBothAreSame(TreeNode root1, TreeNode root2){ - if(root1 == null && root2 == null) return true; - else if(root1 == null) return false; - else if(root2 == null) return false; + private boolean checkIfBothAreSame(TreeNode root1, TreeNode root2) { + if (root1 == null && root2 == null) return true; + else if (root1 == null) return false; + else if (root2 == null) return false; else { - if(root1.val != root2.val) return false; - if(!checkIfBothAreSame(root1.left, root2.left)) return false; + if (root1.val != root2.val) return false; + if (!checkIfBothAreSame(root1.left, root2.left)) return false; return checkIfBothAreSame(root1.right, root2.right); } } - private void flip(TreeNode root1, TreeNode root2){ - if(root1 != null){ + private void flip(TreeNode root1, TreeNode root2) { + if (root1 != null) { TreeNode result = find(root2, root1.val); boolean valid = true; - if(result != null){ - if(root1.left == null){ - if(result.right != null){ + if (result != null) { + if (root1.left == null) { + if (result.right != null) { valid = false; } - }if(root1.right == null){ - if(result.left != null){ + } + if (root1.right == null) { + if (result.left != null) { valid = false; } } - if(root1.left != null){ - if(result.right == null){ + if (root1.left != null) { + if (result.right == null) { valid = false; } else { - if(root1.left.val != result.right.val){ + if (root1.left.val != result.right.val) { valid = false; } } - } if(root1.right != null){ - if(result.left == null){ + } + if (root1.right != null) { + if (result.left == null) { valid = false; } else { - if(root1.right.val != result.left.val){ + if (root1.right.val != result.left.val) { valid = false; } } } - if(valid){ + if (valid) { TreeNode temp = result.left; result.left = result.right; result.right = temp; @@ -112,13 +117,14 @@ private void flip(TreeNode root1, TreeNode root2){ } } - private TreeNode find(TreeNode node, int value){ - if(node != null){ - if(node.val == value) return node; + private TreeNode find(TreeNode node, int value) { + if (node != null) { + if (node.val == value) return node; TreeNode left = find(node.left, value); - if(left != null) return left; + if (left != null) return left; TreeNode right = find(node.right, value); - if(right != null) return right; - } return null; + if (right != null) return right; + } + return null; } } From ee0b6b9d40e529ea78a3be33b993017b2e147b1d Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 22 Sep 2019 12:03:07 +0200 Subject: [PATCH 221/235] Solved Problems --- README.md | 196 ++++++++++-------- problems/src/array/ArrayPartitionI.java | 33 +++ .../LongestLineofConsecutiveOneinMatrix.java | 117 +++++++++++ .../src/array/MatrixCellsinDistanceOrder.java | 67 ++++++ ...aximumSumofTwoNonOverlappingSubarrays.java | 80 +++++++ problems/src/array/SortArrayByParityII.java | 43 ++++ .../src/binary_search/KokoEatingBananas.java | 75 +++++++ .../AsFarfromLandAsPossible.java | 86 ++++++++ .../MinimizeMalwareSpread.java | 136 ++++++++++++ .../EncodeStringWithShortestLength.java | 89 ++++++++ .../LengthofLongestFibonacciSubsequence.java | 62 ++++++ problems/src/greedy/TwoCityScheduling.java | 66 ++++++ .../LargestComponentSizebyCommonFactor.java | 160 ++++++++++++++ problems/src/math/SmallestRangeI.java | 43 ++++ .../FindWordsThatCanBeFormedbyCharacters.java | 63 ++++++ .../MinimumAddtoMakeParenthesesValid.java | 53 +++++ problems/src/tree/BinaryTreeTilt.java | 54 +++++ problems/src/tree/LeafSimilarTrees.java | 57 +++++ .../tree/MaximumLevelSumofABinaryTree.java | 63 ++++++ .../LastSubstringInLexicographicalOrder.java | 68 ++++++ 20 files changed, 1523 insertions(+), 88 deletions(-) create mode 100644 problems/src/array/ArrayPartitionI.java create mode 100644 problems/src/array/LongestLineofConsecutiveOneinMatrix.java create mode 100644 problems/src/array/MatrixCellsinDistanceOrder.java create mode 100644 problems/src/array/MaximumSumofTwoNonOverlappingSubarrays.java create mode 100644 problems/src/array/SortArrayByParityII.java create mode 100644 problems/src/binary_search/KokoEatingBananas.java create mode 100644 problems/src/depth_first_search/AsFarfromLandAsPossible.java create mode 100644 problems/src/depth_first_search/MinimizeMalwareSpread.java create mode 100644 problems/src/dynamic_programming/EncodeStringWithShortestLength.java create mode 100644 problems/src/dynamic_programming/LengthofLongestFibonacciSubsequence.java create mode 100644 problems/src/greedy/TwoCityScheduling.java create mode 100644 problems/src/math/LargestComponentSizebyCommonFactor.java create mode 100644 problems/src/math/SmallestRangeI.java create mode 100644 problems/src/string/FindWordsThatCanBeFormedbyCharacters.java create mode 100644 problems/src/string/MinimumAddtoMakeParenthesesValid.java create mode 100644 problems/src/tree/BinaryTreeTilt.java create mode 100644 problems/src/tree/LeafSimilarTrees.java create mode 100644 problems/src/tree/MaximumLevelSumofABinaryTree.java create mode 100644 problems/src/two_pointers/LastSubstringInLexicographicalOrder.java diff --git a/README.md b/README.md index 32b6eb6e..d4cd0247 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ My accepted leetcode solutions to some of the common interview problems. - [TwoSum II](problems/src/array/TwoSumII.java) (Easy) - [Can Place Flowers](problems/src/array/CanPlaceFlowers.java) (Easy) - [Merge Intervals](problems/src/array/MergeIntervals.java) (Medium) -- [First Missing Positive](problems/src/array/FirstMissingPositive.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [First Missing Positive](problems/src/array/FirstMissingPositive.java) (Hard) - [Fruit Into Baskets](problems/src/array/FruitIntoBaskets.java) (Medium) - [MaxProduct Of Three Numbers](problems/src/array/MaxProductOfThreeNumbers.java) (Easy) - [Missing Number](problems/src/array/MissingNumber.java) (Easy) @@ -28,9 +28,9 @@ My accepted leetcode solutions to some of the common interview problems. - [Read N Characters Given Read4](problems/src/array/ReadNCharacters.java) (Easy) - [Maximum Swap](problems/src/array/MaximumSwap.java) (Medium) - [H-Index](problems/src/array/HIndex.java) (Medium) -- [Insert Interval](problems/src/array/InsertInterval.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Insert Interval](problems/src/array/InsertInterval.java) (Hard) - [Increasing Triplet Subsequence](problems/src/array/IncreasingTripletSubsequence.java) (Medium) -- [K Empty Slots](problems/src/array/KEmptySlots.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [K Empty Slots](problems/src/array/KEmptySlots.java) (Hard) - [Subarray Sum Equals K](problems/src/array/SubarraySumEqualsK.java) (Medium) - [Pour Water](problems/src/array/PourWater.java) (Medium) - [Relative Ranks](problems/src/array/RelativeRanks.java) (Easy) @@ -40,9 +40,9 @@ My accepted leetcode solutions to some of the common interview problems. - [Image Smoother](problems/src/array/ImageSmoother.java) (Easy) - [Minimum Index Sum of Two Lists](problems/src/array/MinimumIndexSumOfTwoLists.java) (Easy) - [Card Flipping Game](problems/src/array/CardFilipGame.java) (Medium) -- [Employee Free Time](problems/src/array/EmployeeFreeTime.java) (Hard) -- [Best Meeting Point](problems/src/array/BestMeetingPoint.java) (Hard) -- [My Calendar III](problems/src/array/MyCalendarThree.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Employee Free Time](problems/src/array/EmployeeFreeTime.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Best Meeting Point](problems/src/array/BestMeetingPoint.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [My Calendar III](problems/src/array/MyCalendarThree.java) (Hard) - [Champagne Tower](problems/src/array/ChampagneTower.java) (Medium) - [Valid Tic-Tac-Toe State](problems/src/array/ValidTicTacToeState.java) (Medium) - [Number of Subarrays with Bounded Maximum](problems/src/array/SubArraysWithBoundedMaximum.java) (Medium) @@ -54,6 +54,11 @@ My accepted leetcode solutions to some of the common interview problems. - [Largest Time for Given Digits](problems/src/array/LargestTimeForGivenDigits.java) (Easy) - [Minimum Time Difference](problems/src/array/MinimumTimeDifference.java) (Medium) - [Reveal Cards In Increasing Order](problems/src/array/RevealCardsInIncreasingOrder.java) (Medium) +- [Sort Array By Parity II](problems/src/array/SortArrayByParityII.java) (Easy) +- [Matrix Cells in Distance Order](problems/src/array/MatrixCellsinDistanceOrder.java) (Easy) +- [Maximum Sum of Two Non-Overlapping Subarrays](problems/src/array/MaximumSumofTwoNonOverlappingSubarrays.java) (Medium) +- [Longest Line of Consecutive One in Matrix](problems/src/array/LongestLineofConsecutiveOneinMatrix.java) (Medium) +- [Array Partition I](problems/src/array/ArrayPartitionI.java) (Easy) #### [Backtracking](problems/src/backtracking) @@ -67,14 +72,14 @@ My accepted leetcode solutions to some of the common interview problems. - [SubSets](problems/src/backtracking/Subsets.java) (Medium) - [SubSet II](problems/src/backtracking/SubsetsII.java) (Medium) - [Word Search](problems/src/backtracking/WordSearch.java) (Medium) -- [Word Search II](problems/src/backtracking/WordSearchII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Word Search II](problems/src/backtracking/WordSearchII.java) (Hard) - [Generate Parentheses](problems/src/backtracking/GenerateParentheses.java) (Medium) -- [Remove Invalid Parentheses](problems/src/backtracking/RemoveInvalidParentheses.java) (Hard) -- [Regular Expression Matching](problems/src/backtracking/RegularExpressionMatching.java) (Hard) -- [Expression Add Operators](problems/src/backtracking/ExpressionAddOperators.java) (Hard) -- [Wildcard Matching](problems/src/backtracking/WildcardMatching.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Remove Invalid Parentheses](problems/src/backtracking/RemoveInvalidParentheses.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Regular Expression Matching](problems/src/backtracking/RegularExpressionMatching.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Expression Add Operators](problems/src/backtracking/ExpressionAddOperators.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Wildcard Matching](problems/src/backtracking/WildcardMatching.java) (Hard) - [Letter Case Permutation](problems/src/backtracking/LetterCasePermutation.java) (Easy) -- [Zuma Game](problems/src/backtracking/ZumaGame.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Zuma Game](problems/src/backtracking/ZumaGame.java) (Hard) - [Matchsticks to Square](problems/src/backtracking/MatchsticksToSquare.java) (Medium) #### [Binary Search](problems/src/binary_search) @@ -84,14 +89,15 @@ My accepted leetcode solutions to some of the common interview problems. - [Search for a Range](problems/src/binary_search/SearchForARange.java) (Medium) - [Sqrt(x)](problems/src/binary_search/SqrtX.java) (Easy) - [Search Insert Position](problems/src/binary_search/SearchInsertPosition.java) (Easy) -- [Median of Two Sorted Arrays](problems/src/binary_search/MedianOfTwoSortedArrays.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Median of Two Sorted Arrays](problems/src/binary_search/MedianOfTwoSortedArrays.java) (Hard) - [Pow(x, n)](problems/src/binary_search/PowXN.java) (Medium) - [Find Peak Element](problems/src/binary_search/FindPeakElement.java) (Medium) - [Target Sum](problems/src/binary_search/TargetSum.java) (Medium) - [H-Index II](problems/src/binary_search/HIndexII.java) (Medium) -- [Swim in Rising Water](problems/src/binary_search/SwimInRisingWater.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Swim in Rising Water](problems/src/binary_search/SwimInRisingWater.java) (Hard) - [Time Based Key-Value Store](problems/src/binary_search/TimeBasedKeyValuePair.java) (Medium) -- [Minimum Window Subsequence](problems/src/binary_search/MinimumWindowSubsequence.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Window Subsequence](problems/src/binary_search/MinimumWindowSubsequence.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Koko Eating Bananas](problems/src/binary_search/KokoEatingBananas.java) (Hard) #### [Bit Manipulation](problems/src/bit_manipulation) @@ -105,13 +111,13 @@ My accepted leetcode solutions to some of the common interview problems. - [Binaray Tree Level Order Traversal](problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java) (Medium) - [Word Ladder](problems/src/breadth_first_search/WordLadder.java) (Medium) -- [Word Ladder II](problems/src/breadth_first_search/WordLadderII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Word Ladder II](problems/src/breadth_first_search/WordLadderII.java) (Hard) - [Walls and Gates](problems/src/breadth_first_search/WallsAndGates.java) (Medium) - [Open the lock](problems/src/breadth_first_search/OpenTheLock.java) (Medium) -- [Cut Off Trees for Golf Event](problems/src/breadth_first_search/CutOffTreesForGolfEvent.java) (Hard) -- [Race Car](problems/src/breadth_first_search/RaceCar.java) (Hard) -- [Bus Routes](problems/src/breadth_first_search/BusRoutes.java) (Hard) -- [Sliding Puzzle](problems/src/breadth_first_search/SlidingPuzzle.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cut Off Trees for Golf Event](problems/src/breadth_first_search/CutOffTreesForGolfEvent.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Race Car](problems/src/breadth_first_search/RaceCar.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Bus Routes](problems/src/breadth_first_search/BusRoutes.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Sliding Puzzle](problems/src/breadth_first_search/SlidingPuzzle.java) (Hard) - [Matrix](problems/src/breadth_first_search/Matrix.java) (Medium) #### [Depth First Search](problems/src/depth_first_search) @@ -121,54 +127,56 @@ My accepted leetcode solutions to some of the common interview problems. - [Number Of Islands](problems/src/depth_first_search/NumberOfIslands.java) (Medium) - [Course Schedule](problems/src/depth_first_search/CourseSchedule.java) (Medium) - [Course Schedule II](problems/src/depth_first_search/CourseScheduleII.java) (Medium) -- [Alien Dictionary](problems/src/depth_first_search/AlienDictionary.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Alien Dictionary](problems/src/depth_first_search/AlienDictionary.java) (Hard) - [Graph Valid Tree](problems/src/depth_first_search/GraphValidTree.java) (Medium) -- [Longest Consecutive Sequence](problems/src/depth_first_search/LongestConsecutiveSequence.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Longest Consecutive Sequence](problems/src/depth_first_search/LongestConsecutiveSequence.java) (Hard) - [Accounts Merge](problems/src/depth_first_search/AccountsMerge.java) (Medium) - [CloneGraph](problems/src/depth_first_search/CloneGraph.java) (Medium) - [Island Perimeter](problems/src/depth_first_search/IslandPerimeter.java) (Easy) - [Number of Distinct Islands](problems/src/depth_first_search/NumberOfDistinctIslands.java) (Medium) -- [Number of Distinct Islands II](problems/src/depth_first_search/NumberOfDistinctIslandsII.java) (Hard) -- [Smallest Rectangle Enclosing Black Pixels](problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java) (Hard) -- [Bricks Falling When Hit](problems/src/depth_first_search/BricksFallingWhenHit.java) (Hard) -- [Robot Room Cleaner](problems/src/depth_first_search/RobotRoomCleaner.java) (Hard) -- [Cracking the Safe](problems/src/depth_first_search/CrackingTheSafe.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Distinct Islands II](problems/src/depth_first_search/NumberOfDistinctIslandsII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Rectangle Enclosing Black Pixels](problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Bricks Falling When Hit](problems/src/depth_first_search/BricksFallingWhenHit.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Robot Room Cleaner](problems/src/depth_first_search/RobotRoomCleaner.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cracking the Safe](problems/src/depth_first_search/CrackingTheSafe.java) (Hard) - [All Paths From Source to Target](problems/src/depth_first_search/AllPathsFromSourceToTarget.java) (Medium) - [Max Area of Island](problems/src/depth_first_search/MaxAreaOfIsland.java) (Medium) - [Satisfiability of Equality Equations](problems/src/depth_first_search/SatisfiabilityOfEquations.java) (Medium) - [Number of Enclaves](problems/src/depth_first_search/NumberOfEnclaves.java) (Medium) +- [As Far from Land as Possible](problems/src/depth_first_search/AsFarfromLandAsPossible.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimize Malware Spread](problems/src/depth_first_search/MinimizeMalwareSpread.java) (Hard) #### [Design](problems/src/design) - [Copy List With Random Pointer](problems/src/design/CopyListWithRandomPointer.java) (Medium) - [Encode and Decode Tiny URL](problems/src/design/EncodeAndDecodeTinyURL.java) (Medium) -- [LFU Cache](problems/src/design/LFUCache.java) (Hard) -- [LRU Cache](problems/src/design/LRUCache.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [LFU Cache](problems/src/design/LFUCache.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [LRU Cache](problems/src/design/LRUCache.java) (Hard) - [Insert Delete Get Random](problems/src/design/RandomizedSet.java) (Medium) -- [Serialize Deserialize Binary Tree](problems/src/design/SerializeDeserializeBinaryTree.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Serialize Deserialize Binary Tree](problems/src/design/SerializeDeserializeBinaryTree.java) (Hard) - [Design Twitter](problems/src/design/Twitter.java) (Medium) - [Tic-Tac-Toe](problems/src/design/TicTacToe.java) (Medium) - [Implement Trie (Prefix Tree)](problems/src/design/Trie.java) (Medium) - [Binary Search Tree Iterator](problems/src/design/BSTIterator.java) (Medium) -- [Design Search Autocomplete System](problems/src/design/AutocompleteSystem.java) (Hard) -- [Design Excel Sum Formula](problems/src/design/Excel.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Design Search Autocomplete System](problems/src/design/AutocompleteSystem.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Design Excel Sum Formula](problems/src/design/Excel.java) (Hard) - [Flatten Nested List Iterator](problems/src/design/NestedIterator.java) (Medium) - [Add and Search Word - Data structure design](problems/src/design/WordDictionary.java) (Medium) -- [Prefix and Suffix Search](problems/src/design/WordFilter.java) (Hard) -- [Insert Delete GetRandom O(1) - Duplicates allowed](problems/src/design/RandomizedCollection.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Prefix and Suffix Search](problems/src/design/WordFilter.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Insert Delete GetRandom O(1) - Duplicates allowed](problems/src/design/RandomizedCollection.java) (Hard) #### [Divide and Conquer](problems/src/divide_and_conquer) - [Kth Largest Element In a Array](problems/src/divide_and_conquer/KthLargestElementInAnArray.java) (Medium) -- [Reverse Pairs](problems/src/divide_and_conquer/ReversePairs.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reverse Pairs](problems/src/divide_and_conquer/ReversePairs.java) (Hard) - [Search in a 2D Matrix](problems/src/divide_and_conquer/SearchA2DMatrix.java) (Medium) -- [24 Game](problems/src/divide_and_conquer/TwentyFourGame.java) (Hard) -- [Reverse Pairs II](problems/src/divide_and_conquer/ReversePairsII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [24 Game](problems/src/divide_and_conquer/TwentyFourGame.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reverse Pairs II](problems/src/divide_and_conquer/ReversePairsII.java) (Hard) #### [Dynamic Programming](problems/src/dynamic_programming) - [Best Time To Buy and Sell Stocks](problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java) (Easy) -- [Best Time to Buy and Sell Stock III](problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Best Time to Buy and Sell Stock III](problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java) (Hard) - [Best Time to Buy and Sell Stock with Transaction Fee](problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java) (Medium) - [Climbing Stairs](problems/src/dynamic_programming/ClimbingStairs.java) (Easy) - [Coin Change](problems/src/dynamic_programming/CoinChange.java) (Medium) @@ -181,49 +189,52 @@ My accepted leetcode solutions to some of the common interview problems. - [Longest Palindromic Subsequence](problems/src/dynamic_programming/LongestPalindromicSubsequence.java) (Medium) - [Maximum Product Subarray](problems/src/dynamic_programming/MaximumProductSubarray.java) (Medium) - [Min Cost Climbing Stairs](problems/src/dynamic_programming/MinCostClimbingStairs.java) (Easy) -- [Palindrome Partitioning II](problems/src/dynamic_programming/PalindromePartitioningII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Palindrome Partitioning II](problems/src/dynamic_programming/PalindromePartitioningII.java) (Hard) - [UniqueBinary Search Trees](problems/src/dynamic_programming/UniqueBinarySearchTrees.java) (Medium) - [Unique Binary Search Trees II](problems/src/dynamic_programming/UniqueBinarySearchTreesII.java) (Medium) - [WordBreak](problems/src/dynamic_programming/WordBreak.java) (Medium) -- [WordBreak II](problems/src/dynamic_programming/WordBreakII.java) (Hard) -- [Concatenated Words](problems/src/dynamic_programming/ConcatenatedWords.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [WordBreak II](problems/src/dynamic_programming/WordBreakII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Concatenated Words](problems/src/dynamic_programming/ConcatenatedWords.java) (Hard) - [Can I Win](problems/src/dynamic_programming/CanIWin.java) (Medium) - [Maximum Subarray](problems/src/dynamic_programming/MaximumSubarray.java) (Easy) -- [Dungeon Game](problems/src/dynamic_programming/DungeonGame.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Dungeon Game](problems/src/dynamic_programming/DungeonGame.java) (Hard) - [2 Keys Keyboard](problems/src/dynamic_programming/TwoKeysKeyboard.java) (Medium) -- [Maximum Sum of 3 Non-Overlapping Subarrays](problems/src/dynamic_programming/MaxSum3SubArray.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximum Sum of 3 Non-Overlapping Subarrays](problems/src/dynamic_programming/MaxSum3SubArray.java) (Hard) - [Maximal Square](problems/src/dynamic_programming/MaximalSquare.java) (Medium) - [Continuous Subarray Sum](problems/src/dynamic_programming/ContinuousSubarraySum.java) (Medium) -- [Decode Ways II](problems/src/dynamic_programming/DecodeWaysII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Decode Ways II](problems/src/dynamic_programming/DecodeWaysII.java) (Hard) - [Palindromic Substrings](problems/src/dynamic_programming/PalindromicSubstrings.java) (Medium) - [Number of Longest Increasing Subsequence](problems/src/dynamic_programming/NumberOfLIS.java) (Medium) - [Combination Sum IV](problems/src/dynamic_programming/CombinationSumIV.java) (Medium) -- [Paint House II](problems/src/dynamic_programming/PaintHouseII.java) (Hard) -- [Split Array Largest Sum](problems/src/dynamic_programming/SplitArrayLargestSum.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Paint House II](problems/src/dynamic_programming/PaintHouseII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Split Array Largest Sum](problems/src/dynamic_programming/SplitArrayLargestSum.java) (Hard) - [Number Of Corner Rectangles](problems/src/dynamic_programming/CornerRectangles.java) (Medium) -- [Burst Balloons](problems/src/dynamic_programming/BurstBalloons.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Burst Balloons](problems/src/dynamic_programming/BurstBalloons.java) (Hard) - [Largest Plus Sign](problems/src/dynamic_programming/LargestPlusSign.java) (Medium) -- [Palindrome Pairs](problems/src/dynamic_programming/PalindromePairs.java) (Hard) -- [Cherry Pickup](problems/src/dynamic_programming/CherryPickup.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Palindrome Pairs](problems/src/dynamic_programming/PalindromePairs.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cherry Pickup](problems/src/dynamic_programming/CherryPickup.java) (Hard) - [Knight Probability in Chessboard](problems/src/dynamic_programming/KnightProbabilityInChessboard.java) (Medium) - [Largest Sum of Averages](problems/src/dynamic_programming/LargestSumOfAverages.java) (Medium) -- [Minimum Number of Refueling Stops](problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java) (Hard) -- [Cat and Mouse](problems/src/dynamic_programming/CatAndMouse.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Number of Refueling Stops](problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cat and Mouse](problems/src/dynamic_programming/CatAndMouse.java) (Hard) - [Stone Game](problems/src/dynamic_programming/StoneGame.java) (Medium) -- [Odd Even Jump](problems/src/dynamic_programming/OddEvenJump.java) (Hard) -- [Profitable Schemes](problems/src/dynamic_programming/ProfitableSchemes.java) (Hard) -- [Maximum Vacation Days](problems/src/dynamic_programming/MaximumVacationDays.java) (Hard) -- [Russian Doll Envelopes](problems/src/dynamic_programming/RussianDollEnvelopes.java) (Hard) -- [Student Attendance Record II](problems/src/dynamic_programming/StudentAttendanceRecordII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Odd Even Jump](problems/src/dynamic_programming/OddEvenJump.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Profitable Schemes](problems/src/dynamic_programming/ProfitableSchemes.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximum Vacation Days](problems/src/dynamic_programming/MaximumVacationDays.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Russian Doll Envelopes](problems/src/dynamic_programming/RussianDollEnvelopes.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Student Attendance Record II](problems/src/dynamic_programming/StudentAttendanceRecordII.java) (Hard) - [Out of Boundary Paths](problems/src/dynamic_programming/OutOfBoundaryPaths.java) (Medium) -- [Remove Boxes](problems/src/dynamic_programming/RemoveBoxes.java) (Hard) -- [Stickers to Spell Word](problems/src/dynamic_programming/StickersToSpellWord.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Remove Boxes](problems/src/dynamic_programming/RemoveBoxes.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Stickers to Spell Word](problems/src/dynamic_programming/StickersToSpellWord.java) (Hard) - [Ones and Zeroes](problems/src/dynamic_programming/OnesAndZeroes.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Encode String with Shortest Length](problems/src/dynamic_programming/EncodeStringWithShortestLength.java) (Hard) +- [Length of Longest Fibonacci Subsequence](problems/src/dynamic_programming/LengthofLongestFibonacciSubsequence.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Encode String with Shortest Length](problems/src/dynamic_programming/EncodeStringWithShortestLength.java) (Hard) #### [Greedy](problems/src/greedy) - [Jump Game](problems/src/greedy/JumpGame.java) (Medium) -- [Jump Game II](problems/src/greedy/JumpGameII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Jump Game II](problems/src/greedy/JumpGameII.java) (Hard) - [Course Schedule III](problems/src/greedy/CourseScheduleIII.java) (Medium) - [GasStation](problems/src/greedy/GasStation.java) (Medium) - [Non-Overlapping Intervals](problems/src/greedy/NonOverlappingIntervals.java) (Medium) @@ -233,10 +244,11 @@ My accepted leetcode solutions to some of the common interview problems. - [Maximum Length of Pair Chain](problems/src/greedy/MaximumLengthOfPairChain.java) (Medium) - [Lemonade Change](problems/src/greedy/LemonadeChange.java) (Easy) - [Score After Flipping Matrix](problems/src/greedy/ScoreAfterFlippingMatrix.java) (Medium) -- [IPO](problems/src/greedy/IPO.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [IPO](problems/src/greedy/IPO.java) (Hard) - [String Without AAA or BBB](problems/src/greedy/StringWithout3A3B.java) (Medium) - [Boats to Save People](problems/src/greedy/BoatsToSavePeople.java) (Medium) - [Broken Calculator](problems/src/greedy/BrokenCalculator.java) (Medium) +- [Two City Scheduling](problems/src/greedy/TwoCityScheduling.java) (Easy) #### [Hashing](problems/src/hashing) @@ -252,32 +264,32 @@ My accepted leetcode solutions to some of the common interview problems. - [Partition Labels](problems/src/hashing/PartitionLabels.java) (Medium) - [Custom Sort String](problems/src/hashing/CustomSortString.java) (Medium) - [Short Encoding of Words](problems/src/hashing/ShortEncodingOfWords.java) (Medium) -- [Substring with Concatenation of All Words](problems/src/hashing/SubstringConcatenationOfWords.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Substring with Concatenation of All Words](problems/src/hashing/SubstringConcatenationOfWords.java) (Hard) - [Distribute Candies](problems/src/hashing/DistributeCandies.java) (Easy) - [Groups of Special-Equivalent Strings](problems/src/hashing/GroupsOfSpecialEquivalentStrings.java) (Easy) -- [Number of Atoms](problems/src/hashing/NumberOfAtoms.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Atoms](problems/src/hashing/NumberOfAtoms.java) (Hard) #### [Heap](problems/src/heap) -- [Sliding Window Maximum](problems/src/heap/SlidingWindowMaximum.java) (Hard) -- [The Skyline Problem](problems/src/heap/TheSkylineProblem.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Sliding Window Maximum](problems/src/heap/SlidingWindowMaximum.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [The Skyline Problem](problems/src/heap/TheSkylineProblem.java) (Hard) - [Meeting Rooms II](problems/src/heap/MeetingRoomsII.java) (Medium) - [Top K Frequent Words](problems/src/heap/TopKFrequentWords.java) (Medium) -- [Candy](problems/src/heap/Candy.java) (Hard) -- [Smallest Rotation with Highest Score](problems/src/heap/SmallestRotationWithHighestScore.java) (Hard) -- [Maximum Frequency Stack](problems/src/heap/FreqStack.java) (Hard) -- [Reachable Nodes In Subdivided Graph](problems/src/heap/ReachableNodesInSubdividedGraph.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Candy](problems/src/heap/Candy.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Rotation with Highest Score](problems/src/heap/SmallestRotationWithHighestScore.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximum Frequency Stack](problems/src/heap/FreqStack.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reachable Nodes In Subdivided Graph](problems/src/heap/ReachableNodesInSubdividedGraph.java) (Hard) #### [Linked List](problems/src/linked_list) - [Intersection of two Linked-Lists](problems/src/linked_list/IntersectionOfTwoLists.java) (Easy) - [Linked List Cycle](problems/src/linked_list/LinkedListCycle.java) (Easy) -- [Merge K Sorted Lists](problems/src/linked_list/MergeKSortedLists.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Merge K Sorted Lists](problems/src/linked_list/MergeKSortedLists.java) (Hard) - [Merge Two Sorted List](problems/src/linked_list/MergeTwoSortedList.java) (Easy) - [Paliandrome List](problems/src/linked_list/PaliandromeList.java) (Easy) - [Reverse Linked List](problems/src/linked_list/ReverseLinkedList.java) (Easy) - [Delete Node in a Linked List](problems/src/linked_list/DeleteNode.java) (Easy) -- [Reverse Nodes in k-Group](problems/src/linked_list/ReverseNodesKGroup.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reverse Nodes in k-Group](problems/src/linked_list/ReverseNodesKGroup.java) (Hard) - [Swap Nodes in Pairs](problems/src/linked_list/SwapNodesInPairs.java) (Medium) - [Middle of Linked List](problems/src/linked_list/MiddleOfLinkedList.java) (Easy) - [Split Linked List in Parts](problems/src/linked_list/SplitLinkedListInParts.java) (Medium) @@ -295,13 +307,15 @@ My accepted leetcode solutions to some of the common interview problems. - [Bulb Switcher II](problems/src/math/BulbSwitcherII.java) (Medium) - [Global and Local Inversions](problems/src/math/GlobalAndLocalInversions.java) (Medium) - [Solve the Equation](problems/src/math/SolveTheEquation.java) (Medium) -- [Couples Holding Hands](problems/src/math/CouplesHoldingHands.java) (Hard) -- [Reaching Points](problems/src/math/ReachingPoints.java) (Hard) -- [Nth Magical Number](problems/src/math/NthMagicalNumber.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Couples Holding Hands](problems/src/math/CouplesHoldingHands.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reaching Points](problems/src/math/ReachingPoints.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Nth Magical Number](problems/src/math/NthMagicalNumber.java) (Hard) - [Squirrel Simulation](problems/src/math/SquirrelSimulation.java) (Medium) - [Projection Area of 3D Shapes](problems/src/math/ProjectionAreaOf3DShapes.java) (Easy) - [Decoded String at Index](problems/src/math/DecodedStringAtIndex.java) (Medium) - [Base 7](problems/src/math/Base7.java) (Easy) +- [Smallest Range I](problems/src/math/SmallestRangeI.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Largest Component Size by Common Factor](problems/src/math/LargestComponentSizebyCommonFactor.java) (Hard) #### [Reservoir Sampling](problems/src/reservoir_sampling) @@ -311,13 +325,13 @@ My accepted leetcode solutions to some of the common interview problems. - [Min Stack](problems/src/stack/MinStack.java) (Easy) - [Valid Parentheses](problems/src/stack/ValidParentheses.java) (Easy) -- [Largest Rectangle In Histogram](problems/src/stack/LargestRectangleInHistogram.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Largest Rectangle In Histogram](problems/src/stack/LargestRectangleInHistogram.java) (Hard) - [Implement Queue using Stacks](problems/src/stack/MyQueue.java) (Easy) -- [Maximal Rectangle](problems/src/stack/MaximalRectangle.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximal Rectangle](problems/src/stack/MaximalRectangle.java) (Hard) - [Exclusive Time of Functions](problems/src/stack/ExclusiveTimeOfFunctions.java) (Medium) -- [Basic Calculator](problems/src/stack/BasicCalculator.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Basic Calculator](problems/src/stack/BasicCalculator.java) (Hard) - [Decode String](problems/src/stack/DecodeString.java) (Medium) -- [Longest Valid Parentheses](problems/src/stack/LongestValidParentheses.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Longest Valid Parentheses](problems/src/stack/LongestValidParentheses.java) (Hard) #### [String](problems/src/string) @@ -327,7 +341,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Reverse Words In a String](problems/src/string/ReverseWordsInAString.java) (Medium) - [ReverseWords II](problems/src/string/ReverseWordsII.java) (Medium) - [String to Integer](problems/src/string/StringToInteger.java) (Medium) -- [Text Justification](problems/src/string/TextJustification.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Text Justification](problems/src/string/TextJustification.java) (Hard) - [ZigZag Conversion](problems/src/string/ZigZagConversion.java) (Medium) - [Implement StrStr](problems/src/string/ImplementStrStr.java) (Easy) - [Excel Sheet Column Number](problems/src/string/ExcelSheetColumnNumber.java) (Easy) @@ -344,9 +358,9 @@ My accepted leetcode solutions to some of the common interview problems. - [Isomorphic Strings](problems/src/string/IsomorphicStrings.java) (Easy) - [String Compression](problems/src/string/StringCompression.java) (Easy) - [Longest Common Prefix](problems/src/string/LongestCommonPrefix.java) (Easy) -- [Find the Closest Palindrome](problems/src/string/FindTheClosestPalindrome.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Find the Closest Palindrome](problems/src/string/FindTheClosestPalindrome.java) (Hard) - [Monotone Increasing Digits](problems/src/string/MonotoneIncreasingDigits.java) (Medium) -- [Shortest Palindrome](problems/src/string/ShortestPalindrome.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Shortest Palindrome](problems/src/string/ShortestPalindrome.java) (Hard) - [Valid Word Abbreviation](problems/src/string/ValidWordAbbreviation.java) (Easy) - [Longest Palindrome](problems/src/string/LongestPalindrome.java) (Easy) - [Replace Words](problems/src/string/ReplaceWords.java) (Medium) @@ -359,11 +373,13 @@ My accepted leetcode solutions to some of the common interview problems. - [Push Dominoes](problems/src/string/PushDominoes.java) (Medium) - [Validate IP Address](problems/src/string/ValidateIPAddress.java) (Medium) - [Reverse String II](problems/src/string/ReverseStringII.java) (Easy) +- [Find Words That Can Be Formed by Characters](problems/src/string/FindWordsThatCanBeFormedbyCharacters.java) (Easy) +- [Minimum Add to Make Parentheses Valid](problems/src/string/MinimumAddtoMakeParenthesesValid.java) (Medium) #### [Tree](problems/src/tree) - [Binaray Tree Right Side View](problems/src/tree/BinarayTreeRightSideView.java) (Medium) -- [Binary Tree Maximum Path Sum](problems/src/tree/BinaryTreeMaximumPathSum.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Binary Tree Maximum Path Sum](problems/src/tree/BinaryTreeMaximumPathSum.java) (Hard) - [Boundary of Binary Tree](problems/src/tree/BoundaryOfBinaryTree.java) (Medium) - [Convert sorted array to BST](problems/src/tree/ConvertSortedArrayToBST.java) (Medium) - [Lowest Common Ancestor of a Binary Tree](problems/src/tree/LCA.java) (Medium) @@ -400,9 +416,9 @@ My accepted leetcode solutions to some of the common interview problems. - [Split BST](problems/src/tree/SplitBST.java) (Medium) - [Closest Leaf in a Binary Tree](problems/src/tree/ClosestLeafInABinaryTree.java) (Medium) - [Maximum Width of Binary Tree](problems/src/tree/MaximumWidthOfBinaryTree.java) (Medium) -- [Recover Binary Search Tree](problems/src/tree/RecoverBinarySearchTree.java) (Hard) -- [Binary Tree Postorder Traversal](problems/src/tree/BinaryTreePostorderTraversal.java) (Hard) -- [Serialize and Deserialize N-ary Tree](problems/src/tree/SerializeAndDeserializeNAryTree.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Recover Binary Search Tree](problems/src/tree/RecoverBinarySearchTree.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Binary Tree Postorder Traversal](problems/src/tree/BinaryTreePostorderTraversal.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Serialize and Deserialize N-ary Tree](problems/src/tree/SerializeAndDeserializeNAryTree.java) (Hard) - [Convert BST to Greater Tree](problems/src/tree/ConvertBSTToGreaterTree.java) (Easy) - [All Nodes Distance K in Binary Tree](problems/src/tree/AllNodesDistanceKInBinaryTree.java) (Medium) - [All Possible Full Binary Trees](problems/src/tree/AllPossibleFullBinaryTrees.java) (Medium) @@ -410,21 +426,25 @@ My accepted leetcode solutions to some of the common interview problems. - [Construct Binary Tree from String](problems/src/tree/ConstructBinaryTreefromString.java) (Medium) - [Find Largest Value in Each Tree Row](problems/src/tree/FindLargestValueInEachTreeRow.java) (Medium) - [Find Bottom Left Tree Value](problems/src/tree/FindBottomLeftTreeValue.java) (Medium) +- [Maximum Level Sum of a Binary Tree](problems/src/tree/MaximumLevelSumofABinaryTree.java) (Medium) +- [Leaf-Similar Trees](problems/src/tree/LeafSimilarTrees.java) (Easy) +- [Binary Tree Tilt](problems/src/tree/BinaryTreeTilt.java) (Easy) #### [Two Pointers](problems/src/two_pointers) - [Four Sum](problems/src/two_pointers/FourSum.java) (Medium) - [Longest Substring Witout Repeats](problems/src/two_pointers/LongestSubstringWitoutRepeats.java) (Medium) - [Three Sum](problems/src/two_pointers/ThreeSum.java) (Medium) -- [Trapping Rain Water](problems/src/two_pointers/TrappingRainWater.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Trapping Rain Water](problems/src/two_pointers/TrappingRainWater.java) (Hard) - [3Sum Closest](problems/src/two_pointers/ThreeSumClosest.java) (Medium) - [Move Zeroes](problems/src/two_pointers/MoveZeroes.java) (Easy) - [Remove Duplicates](problems/src/two_pointers/RemoveDuplicates.java) (Easy) - [Remove Duplicates II](problems/src/two_pointers/RemoveDuplicatesII.java) (Medium) - [Minimum Size Subarray Sum](problems/src/two_pointers/MinimumSizeSubarraySum.java) (Medium) -- [Minimum Window Substring](problems/src/two_pointers/MinimumWindowSubstring.java) (Hard) -- [Smallest Range](problems/src/two_pointers/SmallestRange.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Window Substring](problems/src/two_pointers/MinimumWindowSubstring.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Range](problems/src/two_pointers/SmallestRange.java) (Hard) - [Subarray Product Less Than K](problems/src/two_pointers/SubarrayProductLessThanK.java) (Medium) - [Number of Matching Subsequences](problems/src/two_pointers/NumberOfMatchingSubsequences.java) (Medium) -- [Subarrays with K Different Integers](problems/src/two_pointers/SubarraysWithKDifferentIntegers.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Subarrays with K Different Integers](problems/src/two_pointers/SubarraysWithKDifferentIntegers.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Last Substring in Lexicographical Order](problems/src/two_pointers/LastSubstringInLexicographicalOrder.java) (Hard) diff --git a/problems/src/array/ArrayPartitionI.java b/problems/src/array/ArrayPartitionI.java new file mode 100644 index 00000000..35a370a6 --- /dev/null +++ b/problems/src/array/ArrayPartitionI.java @@ -0,0 +1,33 @@ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 14/08/2019 Given an array of 2n integers, your task is to group + * these integers into n pairs of integer, say (a1, b1), (a2, b2), ..., (an, bn) which makes sum of + * min(ai, bi) for all i from 1 to n as large as possible. + * + *

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

Output: 4 Explanation: n is 2, and the maximum sum of pairs is 4 = min(1, 2) + min(3, 4). + * Note: n is a positive integer, which is in the range of [1, 10000]. All the integers in the array + * will be in the range of [-10000, 10000]. + * + *

Solution: O(n log n) General idea is to pair the smallest with the next smallest value inorder + * to get the max sum of minimum. + */ +public class ArrayPartitionI { + public static void main(String[] args) { + int[] A = {1, 2, 3, 4}; + System.out.println(new ArrayPartitionI().arrayPairSum(A)); + } + + public int arrayPairSum(int[] nums) { + Arrays.sort(nums); + int sum = 0; + for (int i = 1; i < nums.length; i += 2) { + sum += Math.min(nums[i - 1], nums[i]); + } + return sum; + } +} diff --git a/problems/src/array/LongestLineofConsecutiveOneinMatrix.java b/problems/src/array/LongestLineofConsecutiveOneinMatrix.java new file mode 100644 index 00000000..f322be99 --- /dev/null +++ b/problems/src/array/LongestLineofConsecutiveOneinMatrix.java @@ -0,0 +1,117 @@ +package array; + +/** + * Created by gouthamvidyapradhan on 14/08/2019 Given a 01 matrix M, find the longest line of + * consecutive one in the matrix. The line could be horizontal, vertical, diagonal or anti-diagonal. + * Example: Input: [[0,1,1,0], [0,1,1,0], [0,0,0,1]] Output: 3 Hint: The number of elements in the + * given matrix will not exceed 10,000. + * + *

Solution O(N x M) for each cell keep track of maximum value possible horizontally, vertically + * and diagonally. Start iterating from left-right and top-bottom and repeat the same from + * right-left and top to bottom to get max for anti-diagonal and return the max value. + */ +public class LongestLineofConsecutiveOneinMatrix { + final int[] R = {0, 0, -1, 1}; + final int[] C = {1, -1, 0, 0}; + + public static void main(String[] args) { + int[][] M = { + {1, 1, 0, 0, 1, 0, 0, 1, 1, 0}, + {1, 0, 0, 1, 0, 1, 1, 1, 1, 1}, + {1, 1, 1, 0, 0, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 0, 1, 1, 1, 1, 1}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 0, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 0, 0, 1}, + {1, 1, 1, 1, 1, 0, 0, 1, 1, 1}, + {0, 1, 0, 1, 1, 0, 1, 1, 1, 1}, + {1, 1, 1, 0, 1, 0, 1, 1, 1, 1} + }; + System.out.println(new LongestLineofConsecutiveOneinMatrix().longestLine(M)); + } + + class Cell { + int h, v, d; + + Cell(int h, int v, int d) { + this.h = h; + this.v = v; + this.d = d; + } + } + + public int longestLine(int[][] M) { + if (M.length == 0) return 0; + int max = 0; + Cell[][] cells = new Cell[M.length][M[0].length]; + for (int i = 0; i < M.length; i++) { + for (int j = 0; j < M[0].length; j++) { + int h = 0, v = 0, d = 0; + if (M[i][j] == 1) { + h = 1; + v = 1; + d = 1; + max = Math.max(max, 1); + if (j - 1 >= 0) { + Cell left = cells[i][j - 1]; + if (left.h > 0) { + h += left.h; + max = Math.max(max, h); + } + } + if (i - 1 >= 0) { + Cell top = cells[i - 1][j]; + if (top.v > 0) { + v += top.v; + max = Math.max(max, v); + } + } + if (i - 1 >= 0 && j - 1 >= 0) { + Cell diagonal = cells[i - 1][j - 1]; + if (diagonal.d > 0) { + d += diagonal.d; + max = Math.max(max, d); + } + } + } + cells[i][j] = new Cell(h, v, d); + } + } + + for (int i = 0; i < M.length; i++) { + for (int j = M[0].length - 1; j >= 0; j--) { + int h = 0, v = 0, d = 0; + if (M[i][j] == 1) { + h = 1; + v = 1; + d = 1; + max = Math.max(max, 1); + if (j + 1 < M[0].length) { + Cell left = cells[i][j + 1]; + if (left.h > 0) { + h += left.h; + max = Math.max(max, h); + } + } + if (i - 1 >= 0) { + Cell top = cells[i - 1][j]; + if (top.v > 0) { + v += top.v; + max = Math.max(max, v); + } + } + if (i - 1 >= 0 && j + 1 < M[0].length) { + Cell diagonal = cells[i - 1][j + 1]; + if (diagonal.d > 0) { + d += diagonal.d; + max = Math.max(max, d); + } + } + } + cells[i][j] = new Cell(h, v, d); + } + } + + return max; + } +} diff --git a/problems/src/array/MatrixCellsinDistanceOrder.java b/problems/src/array/MatrixCellsinDistanceOrder.java new file mode 100644 index 00000000..e71569bb --- /dev/null +++ b/problems/src/array/MatrixCellsinDistanceOrder.java @@ -0,0 +1,67 @@ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 15/08/2019 We are given a matrix with R rows and C columns has + * cells with integer coordinates (r, c), where 0 <= r < R and 0 <= c < C. + * + *

Additionally, we are given a cell in that matrix with coordinates (r0, c0). + * + *

Return the coordinates of all cells in the matrix, sorted by their distance from (r0, c0) from + * smallest distance to largest distance. Here, the distance between two cells (r1, c1) and (r2, c2) + * is the Manhattan distance, |r1 - r2| + |c1 - c2|. (You may return the answer in any order that + * satisfies this condition.) + * + *

Example 1: + * + *

Input: R = 1, C = 2, r0 = 0, c0 = 0 Output: [[0,0],[0,1]] Explanation: The distances from (r0, + * c0) to other cells are: [0,1] Example 2: + * + *

Input: R = 2, C = 2, r0 = 0, c0 = 1 Output: [[0,1],[0,0],[1,1],[1,0]] Explanation: The + * distances from (r0, c0) to other cells are: [0,1,1,2] The answer [[0,1],[1,1],[0,0],[1,0]] would + * also be accepted as correct. Example 3: + * + *

Input: R = 2, C = 3, r0 = 1, c0 = 2 Output: [[1,2],[0,2],[1,1],[0,1],[1,0],[0,0]] Explanation: + * The distances from (r0, c0) to other cells are: [0,1,1,2,2,3] There are other answers that would + * also be accepted as correct, such as [[1,2],[1,1],[0,2],[1,0],[0,1],[0,0]]. + * + *

Note: + * + *

1 <= R <= 100 1 <= C <= 100 0 <= r0 < R 0 <= c0 < C + * + *

Solution: O (log (R x C)) Straight forward solution, find the Manhattan distance from the + * given cell to all the cells in the grid and sort by min distance and return their coordinates. + */ +public class MatrixCellsinDistanceOrder { + public static void main(String[] args) { + // + } + + class Cell { + int max, i, j; + + Cell(int max, int i, int j) { + this.max = max; + this.i = i; + this.j = j; + } + } + + public int[][] allCellsDistOrder(int R, int C, int r0, int c0) { + List list = new ArrayList<>(); + for (int i = 0; i < R; i++) { + for (int j = 0; j < C; j++) { + int sum = Math.abs(r0 - i) + Math.abs(c0 - j); + list.add(new Cell(sum, i, j)); + } + } + list.sort(Comparator.comparingInt(o -> o.max)); + int[][] A = new int[list.size()][2]; + for (int i = 0; i < A.length; i++) { + A[i][0] = list.get(i).i; + A[i][1] = list.get(i).j; + } + return A; + } +} diff --git a/problems/src/array/MaximumSumofTwoNonOverlappingSubarrays.java b/problems/src/array/MaximumSumofTwoNonOverlappingSubarrays.java new file mode 100644 index 00000000..0592fbdc --- /dev/null +++ b/problems/src/array/MaximumSumofTwoNonOverlappingSubarrays.java @@ -0,0 +1,80 @@ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 15/08/2019 Given an array A of non-negative integers, return + * the maximum sum of elements in two non-overlapping (contiguous) subarrays, which have lengths L + * and M. (For clarification, the L-length subarray could occur before or after the M-length + * subarray.) + * + *

Formally, return the largest V for which V = (A[i] + A[i+1] + ... + A[i+L-1]) + (A[j] + A[j+1] + * + ... + A[j+M-1]) and either: + * + *

0 <= i < i + L - 1 < j < j + M - 1 < A.length, or 0 <= j < j + M - 1 < i < i + L - 1 < + * A.length. + * + *

Example 1: + * + *

Input: A = [0,6,5,2,2,5,1,9,4], L = 1, M = 2 Output: 20 Explanation: One choice of subarrays + * is [9] with length 1, and [6,5] with length 2. Example 2: + * + *

Input: A = [3,8,1,3,2,1,8,9,0], L = 3, M = 2 Output: 29 Explanation: One choice of subarrays + * is [3,8,1] with length 3, and [8,9] with length 2. Example 3: + * + *

Input: A = [2,1,5,6,0,9,5,0,3,8], L = 4, M = 3 Output: 31 Explanation: One choice of subarrays + * is [5,6,0,9] with length 4, and [3,8] with length 3. + * + *

Note: + * + *

L >= 1 M >= 1 L + M <= A.length <= 1000 0 <= A[i] <= 1000 Solution O(N ^ 2) Find prefix sum of + * array of length L and array of length M and keep track of their begin and end indices. Now, + * brute-force compare pairs of prefix array sum where their indices don't overlap and return the + * max possible answer. + */ +public class MaximumSumofTwoNonOverlappingSubarrays { + public static void main(String[] args) { + int[] A = {2, 1, 5, 6, 0, 9, 5, 0, 3, 8}; + System.out.println(new MaximumSumofTwoNonOverlappingSubarrays().maxSumTwoNoOverlap(A, 4, 3)); + } + + class MaxWithIndex { + int max, i, j; + + MaxWithIndex(int max, int i, int j) { + this.max = max; + this.i = i; + this.j = j; + } + } + + public int maxSumTwoNoOverlap(int[] A, int L, int M) { + List first = getMax(A, L); + List second = getMax(A, M); + int max = 0; + for (MaxWithIndex f : first) { + for (MaxWithIndex s : second) { + if (f.j < s.i || s.j < f.i) { + max = Math.max(max, f.max + s.max); + } + } + } + return max; + } + + private List getMax(int[] A, int L) { + List list = new ArrayList<>(); + int i = 0, j = L; + int sum = 0; + for (; i < L; i++) { + sum += A[i]; + } + list.add(new MaxWithIndex(sum, 0, j - 1)); + for (i = 1; j < A.length; i++, j++) { + sum -= A[i - 1]; + sum += A[j]; + list.add(new MaxWithIndex(sum, i, j)); + } + return list; + } +} diff --git a/problems/src/array/SortArrayByParityII.java b/problems/src/array/SortArrayByParityII.java new file mode 100644 index 00000000..0b775f5c --- /dev/null +++ b/problems/src/array/SortArrayByParityII.java @@ -0,0 +1,43 @@ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 20/08/2019 Given an array A of non-negative integers, half of + * the integers in A are odd, and half of the integers are even. + * + *

Sort the array so that whenever A[i] is odd, i is odd; and whenever A[i] is even, i is even. + * + *

You may return any answer array that satisfies this condition. + * + *

Example 1: + * + *

Input: [4,2,5,7] Output: [4,5,2,7] Explanation: [4,7,2,5], [2,5,4,7], [2,7,4,5] would also + * have been accepted. + * + *

Note: + * + *

2 <= A.length <= 20000 A.length % 2 == 0 0 <= A[i] <= 1000 Solution: O(N) straight forward + * linear solution, keep track of odd and even indices and increment by 2 every time a value is + * added at the index. + */ +public class SortArrayByParityII { + public static void main(String[] args) { + // + } + + public int[] sortArrayByParityII(int[] A) { + int[] R = new int[A.length]; + int i = 0, j = 1; + for (int a : A) { + if (a % 2 == 0) { + R[i] = a; + i += 2; + } else { + R[j] = a; + j += 2; + } + } + return R; + } +} diff --git a/problems/src/binary_search/KokoEatingBananas.java b/problems/src/binary_search/KokoEatingBananas.java new file mode 100644 index 00000000..8c1f6193 --- /dev/null +++ b/problems/src/binary_search/KokoEatingBananas.java @@ -0,0 +1,75 @@ +package binary_search; + +/** + * Created by gouthamvidyapradhan on 23/08/2019 Koko loves to eat bananas. There are N piles of + * bananas, the i-th pile has piles[i] bananas. The guards have gone and will come back in H hours. + * + *

Koko can decide her bananas-per-hour eating speed of K. Each hour, she chooses some pile of + * bananas, and eats K bananas from that pile. If the pile has less than K bananas, she eats all of + * them instead, and won't eat any more bananas during this hour. + * + *

Koko likes to eat slowly, but still wants to finish eating all the bananas before the guards + * come back. + * + *

Return the minimum integer K such that she can eat all the bananas within H hours. + * + *

Example 1: + * + *

Input: piles = [3,6,7,11], H = 8 Output: 4 Example 2: + * + *

Input: piles = [30,11,23,4,20], H = 5 Output: 30 Example 3: + * + *

Input: piles = [30,11,23,4,20], H = 6 Output: 23 + * + *

Note: + * + *

1 <= piles.length <= 10^4 piles.length <= H <= 10^9 1 <= piles[i] <= 10^9 + * + *

Solution: O(N x log Max(piles[i])) Binary search for the minimum possible value between (1 and + * max(piles[i])) + */ +public class KokoEatingBananas { + public static void main(String[] args) { + int[] A = {312884470}; + System.out.println(new KokoEatingBananas().minEatingSpeed(A, 968709470)); + } + + public int minEatingSpeed(int[] piles, int H) { + int max = 0; + for (int i = 0; i < piles.length; i++) { + max = Math.max(max, piles[i]); + } + if (H == piles.length) return max; + int h = max, l = 1; + int answer = H; + while (l <= h) { + int m = l + (h - l) / 2; + boolean status = check(piles, H, m); + if (status) { + answer = m; + h = m - 1; + } else { + l = m + 1; + } + } + return answer; + } + + private boolean check(int[] piles, int H, int k) { + for (int p : piles) { + if (p <= k) { + H--; + } else { + int q = p / k; + if ((p % k) > 0) { + q++; + } + H -= q; + } + if (H < 0) { + return false; + } + } + return true; + } +} diff --git a/problems/src/depth_first_search/AsFarfromLandAsPossible.java b/problems/src/depth_first_search/AsFarfromLandAsPossible.java new file mode 100644 index 00000000..4739eafe --- /dev/null +++ b/problems/src/depth_first_search/AsFarfromLandAsPossible.java @@ -0,0 +1,86 @@ +package depth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 28/08/2019 Given an N x N grid containing only values 0 and 1, + * where 0 represents water and 1 represents land, find a water cell such that its distance to the + * nearest land cell is maximized and return the distance. + * + *

The distance used in this problem is the Manhattan distance: the distance between two cells + * (x0, y0) and (x1, y1) is |x0 - x1| + |y0 - y1|. + * + *

If no land or water exists in the grid, return -1. + * + *

Example 1: + * + *

Input: [[1,0,1],[0,0,0],[1,0,1]] Output: 2 Explanation: The cell (1, 1) is as far as possible + * from all the land with distance 2. Example 2: + * + *

Input: [[1,0,0],[0,0,0],[0,0,0]] Output: 4 Explanation: The cell (2, 2) is as far as possible + * from all the land with distance 4. + * + *

Note: + * + *

1 <= grid.length == grid[0].length <= 100 grid[i][j] is 0 or 1 + * + *

Solution: O(N x N) Do a multi-sources BFS starting from each of the water cell and end as soon + * as a land cell is found. Record the maximum distance to the land cell and return the value. + */ +public class AsFarfromLandAsPossible { + final int[] R = {1, -1, 0, 0}; + final int[] C = {0, 0, -1, 1}; + + public static void main(String[] args) { + int[][] G = {{1, 0, 1}, {0, 0, 0}, {1, 0, 1}}; + System.out.println(new AsFarfromLandAsPossible().maxDistance(G)); + } + + private class Node { + int r, c, d; + + Node(int r, int c, int d) { + this.r = r; + this.c = c; + this.d = d; + } + } + + public int maxDistance(int[][] grid) { + int[][] D = new int[grid.length][grid[0].length]; + Queue queue = new ArrayDeque<>(); + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 1) { + queue.offer(new Node(i, j, 0)); + } else { + D[i][j] = -1; + } + } + } + if (queue.isEmpty()) return -1; + while (!queue.isEmpty()) { + Node current = queue.poll(); + for (int i = 0; i < 4; i++) { + int newR = current.r + R[i]; + int newC = current.c + C[i]; + if (newR >= 0 && newC >= 0 && newR < grid.length && newC < grid[0].length) { + if (D[newR][newC] < 0) { + D[newR][newC] = current.d + 1; + Node child = new Node(newR, newC, current.d + 1); + queue.offer(child); + } + } + } + } + int max = 0; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 0) { + max = Math.max(max, D[i][j]); + } + } + } + return max == 0 ? -1 : max; + } +} diff --git a/problems/src/depth_first_search/MinimizeMalwareSpread.java b/problems/src/depth_first_search/MinimizeMalwareSpread.java new file mode 100644 index 00000000..751db4ad --- /dev/null +++ b/problems/src/depth_first_search/MinimizeMalwareSpread.java @@ -0,0 +1,136 @@ +package depth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 20/08/2019 In a network of nodes, each node i is directly + * connected to another node j if and only if graph[i][j] = 1. + * + *

Some nodes initial are initially infected by malware. Whenever two nodes are directly + * connected and at least one of those two nodes is infected by malware, both nodes will be infected + * by malware. This spread of malware will continue until no more nodes can be infected in this + * manner. + * + *

Suppose M(initial) is the final number of nodes infected with malware in the entire network, + * after the spread of malware stops. + * + *

We will remove one node from the initial list. Return the node that if removed, would minimize + * M(initial). If multiple nodes could be removed to minimize M(initial), return such a node with + * the smallest index. + * + *

Note that if a node was removed from the initial list of infected nodes, it may still be + * infected later as a result of the malware spread. + * + *

Example 1: + * + *

Input: graph = [[1,1,0],[1,1,0],[0,0,1]], initial = [0,1] Output: 0 Example 2: + * + *

Input: graph = [[1,0,0],[0,1,0],[0,0,1]], initial = [0,2] Output: 0 Example 3: + * + *

Input: graph = [[1,1,1],[1,1,1],[1,1,1]], initial = [1,2] Output: 1 + * + *

Note: + * + *

1 < graph.length = graph[0].length <= 300 0 <= graph[i][j] == graph[j][i] <= 1 graph[i][i] = 1 + * 1 <= initial.length < graph.length 0 <= initial[i] < graph.length + * + *

Solution: O(N x M x I) + O(I ^ 2) where N x M is number of nodes and I is the size of the + * initial Do a dfs from each of the initial nodes and color the reachable nodes with color i (color + * of initial node) and keep track of count of nodes reachable by this node - do not re-visit the + * already visited nodes. Check the list of initial nodes which have unique color which no other + * initial nodes have and mark this as eligible candidate. Sort the eligible candidates by pick the + * candidate which has maximum count of nodes reachable from it. + */ +public class MinimizeMalwareSpread { + public static void main(String[] args) { + int[][] graph = { + {1, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 0}, + {0, 0, 0, 1, 1, 0}, + {0, 0, 0, 0, 0, 1} + }; + int[] i = {5, 0}; + new MinimizeMalwareSpread().minMalwareSpread(graph, i); + } + + Map> graphMap; + Map size; + Set done; + Map color; + int count = 0; + + public int minMalwareSpread(int[][] graph, int[] initial) { + graphMap = new HashMap<>(); + done = new HashSet<>(); + color = new HashMap<>(); + size = new HashMap<>(); + for (int i = 0; i < graph.length; i++) { + for (int j = 0; j < graph[0].length; j++) { + if (graph[i][j] == 1) { + graphMap.putIfAbsent(i, new ArrayList<>()); + graphMap.get(i).add(j); + graphMap.putIfAbsent(j, new ArrayList<>()); + graphMap.get(j).add(i); + } + } + } + for (int i : initial) { + if (!done.contains(i)) { + count = 0; + dfs(i, i); + size.put(i, count); + } + } + List eligible = new ArrayList<>(); + boolean candidate; + for (int i = 0; i < initial.length; i++) { + int iColor = color.get(initial[i]); + candidate = true; + for (int j = 0; j < initial.length; j++) { + if (j != i) { + if (color.get(initial[j]) == iColor) { + candidate = false; + break; + } + } + } + if (candidate) { + eligible.add(initial[i]); + } + } + Arrays.sort(initial); + eligible.sort(Comparator.comparingInt(o -> o)); + if (eligible.isEmpty()) { + return initial[0]; + } else { + int answer = initial[0]; + int max = 0; + for (int i = 0, l = eligible.size(); i < l; i++) { + int node = eligible.get(i); + if (size.containsKey(node)) { + if (size.get(node) > max) { + max = size.get(node); + answer = node; + } + } + } + return answer; + } + } + + private void dfs(int i, int col) { + done.add(i); + color.put(i, col); + count++; + List children = graphMap.get(i); + if (children != null && !children.isEmpty()) { + for (int c : children) { + if (!done.contains(c)) { + dfs(c, col); + } + } + } + } +} diff --git a/problems/src/dynamic_programming/EncodeStringWithShortestLength.java b/problems/src/dynamic_programming/EncodeStringWithShortestLength.java new file mode 100644 index 00000000..614c6c97 --- /dev/null +++ b/problems/src/dynamic_programming/EncodeStringWithShortestLength.java @@ -0,0 +1,89 @@ +package dynamic_programming; +/** + * Created by gouthamvidyapradhan on 15/09/2019 Given a non-empty string, encode the string such + * that its encoded length is the shortest. + * + *

The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets + * is being repeated exactly k times. + * + *

Note: + * + *

k will be a positive integer and encoded string will not be empty or have extra space. You may + * assume that the input string contains only lowercase English letters. The string's length is at + * most 160. If an encoding process does not make the string shorter, then do not encode it. If + * there are several solutions, return any of them is fine. + * + *

Example 1: + * + *

Input: "aaa" Output: "aaa" Explanation: There is no way to encode it such that it is shorter + * than the input string, so we do not encode it. + * + *

Example 2: + * + *

Input: "aaaaa" Output: "5[a]" Explanation: "5[a]" is shorter than "aaaaa" by 1 character. + * + *

Example 3: + * + *

Input: "aaaaaaaaaa" Output: "10[a]" Explanation: "a9[a]" or "9[a]a" are also valid solutions, + * both of them have the same length = 5, which is the same as "10[a]". + * + *

Example 4: + * + *

Input: "aabcaabcd" Output: "2[aabc]d" Explanation: "aabc" occurs twice, so one answer can be + * "2[aabc]d". + * + *

Example 5: + * + *

Input: "abbbabbbcabbbabbbc" Output: "2[2[abbb]c]" Explanation: "abbbabbbc" occurs twice, but + * "abbbabbbc" can also be encoded to "2[abbb]c", so one answer can be "2[2[abbb]c]". + * + *

Solution: O(N ^ 4) Maintain a 2d String array of minimum substring and split each substring + * and combine the minimum substrings So, the answer could be either DP[i][j] = min(DP[i][k] + DP[k + * + 1][j]) or split (i, j) at every index k and check if a new minimum substring can be formed + * which is lesser than the current minimum. + */ +public class EncodeStringWithShortestLength { + + private String[][] DP; + + public static void main(String[] args) { + System.out.println( + new EncodeStringWithShortestLength() + .encode( + "xabcabcabcxxabcabcabcxxabcabcabcxxabcdabcabcxxabcabcabcxxabcabcabcxxabcabcabcxxabcabcabcx")); + } + + public String encode(String s) { + DP = new String[s.length()][s.length()]; + return encodeStr(s, 0, s.length() - 1); + } + + private String encodeStr(String s, int i, int j) { + if (i == j) { + DP[i][j] = String.valueOf(s.charAt(i)); + return DP[i][j]; + } else if (DP[i][j] != null) return DP[i][j]; + String currSubStr = s.substring(i, j + 1); + DP[i][j] = currSubStr; + for (int k = i + 1; k < j + 1; k++) { + String left = encodeStr(s, i, k - 1); + String right = encodeStr(s, k, j); + if (left.length() + right.length() < DP[i][j].length()) { + DP[i][j] = left + right; + } + } + for (int k = i + 1; k < j + 1; k++) { + if (currSubStr.length() % (k - i) == 0) { + String subStr = s.substring(i, k); + if (currSubStr.replaceAll(subStr, "").trim().isEmpty()) { + String candidate = + (currSubStr.length() / subStr.length()) + "[" + encodeStr(s, i, k - 1) + "]"; + if (candidate.length() < DP[i][j].length()) { + DP[i][j] = candidate; + } + } + } + } + return DP[i][j]; + } +} diff --git a/problems/src/dynamic_programming/LengthofLongestFibonacciSubsequence.java b/problems/src/dynamic_programming/LengthofLongestFibonacciSubsequence.java new file mode 100644 index 00000000..79a00083 --- /dev/null +++ b/problems/src/dynamic_programming/LengthofLongestFibonacciSubsequence.java @@ -0,0 +1,62 @@ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 23/08/2019 A sequence X_1, X_2, ..., X_n is fibonacci-like if: + * + *

n >= 3 X_i + X_{i+1} = X_{i+2} for all i + 2 <= n Given a strictly increasing array A of + * positive integers forming a sequence, find the length of the longest fibonacci-like subsequence + * of A. If one does not exist, return 0. + * + *

(Recall that a subsequence is derived from another sequence A by deleting any number of + * elements (including none) from A, without changing the order of the remaining elements. For + * example, [3, 5, 8] is a subsequence of [3, 4, 5, 6, 7, 8].) + * + *

Example 1: + * + *

Input: [1,2,3,4,5,6,7,8] Output: 5 Explanation: The longest subsequence that is + * fibonacci-like: [1,2,3,5,8]. Example 2: + * + *

Input: [1,3,7,11,12,14,18] Output: 3 Explanation: The longest subsequence that is + * fibonacci-like: [1,11,12], [3,11,14] or [7,11,18]. + * + *

Note: + * + *

3 <= A.length <= 1000 1 <= A[0] < A[1] < ... < A[A.length - 1] <= 10^9 (The time limit has + * been reduced by 50% for submissions in Java, C, and C++.) + * + *

Solution O(N ^ 2) For every value at index i sum up with every value at index j and check if + * this sum is already known if known then increment the sub-sequence length by 1, continue this + * process until max length is found. + */ +public class LengthofLongestFibonacciSubsequence { + public static void main(String[] args) { + int[] A = {1, 2, 4, 7, 12, 20}; + System.out.println(new LengthofLongestFibonacciSubsequence().lenLongestFibSubseq(A)); + } + + public int lenLongestFibSubseq(int[] A) { + if (A.length < 3) return 0; + Map> indexMap = new HashMap<>(); + int max = 0; + for (int i = A.length - 1; i >= 0; i--) { + Map subHashMap = new HashMap<>(); + for (int j = 0; j < i; j++) { + int sum = A[i] + A[j]; + if (indexMap.containsKey(sum)) { + if (indexMap.get(sum).containsKey(A[i])) { + int value = 1 + indexMap.get(sum).get(A[i]); + subHashMap.put(A[j], value); + max = Math.max(max, value); + } else { + subHashMap.put(A[j], 1); + max = Math.max(max, 1); + } + } + } + indexMap.put(A[i], subHashMap); + } + return max == 0 ? 0 : max + 2; + } +} diff --git a/problems/src/greedy/TwoCityScheduling.java b/problems/src/greedy/TwoCityScheduling.java new file mode 100644 index 00000000..17a8da11 --- /dev/null +++ b/problems/src/greedy/TwoCityScheduling.java @@ -0,0 +1,66 @@ +package greedy; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 15/08/2019 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. + * + *

Example 1: + * + *

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. + * + *

Note: + * + *

1 <= costs.length <= 100 It is guaranteed that costs.length is even. 1 <= costs[i][0], + * costs[i][1] <= 1000 + * + *

Solution: O(N log N) The general idea is to first allocate all the candidates to city A and + * sum up the cost and mark this as MIN. Now, make pairs with (costA - CostB, i) and sort this list + * of pairs in descending order (this is a greedy way of getting to the minimum possible value) - + * take the first half of this sorted list and sum of their values and reduce this value from MIN to + * get the answer. + */ +public class TwoCityScheduling { + public static void main(String[] args) { + int[][] A = {{10, 20}, {30, 200}, {400, 50}, {30, 20}}; + System.out.println(new TwoCityScheduling().twoCitySchedCost(A)); + } + + class Pair { + int max, i; + + Pair(int max, int i) { + this.max = max; + this.i = i; + } + } + + public int twoCitySchedCost(int[][] costs) { + int min = 0; + + for (int i = 0; i < costs.length; i++) { + min += costs[i][0]; + } + + List list = new ArrayList<>(); + for (int i = 0; i < costs.length; i++) { + list.add(new Pair(costs[i][0] - costs[i][1], i)); + } + list.sort((o1, o2) -> Integer.compare(o2.max, o1.max)); + + for (int i = 0, N = (list.size() / 2); i < N; i++) { + min -= list.get(i).max; + } + return min; + } +} diff --git a/problems/src/math/LargestComponentSizebyCommonFactor.java b/problems/src/math/LargestComponentSizebyCommonFactor.java new file mode 100644 index 00000000..80288ebd --- /dev/null +++ b/problems/src/math/LargestComponentSizebyCommonFactor.java @@ -0,0 +1,160 @@ +package math; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * Created by gouthamvidyapradhan on 20/08/2019 Given a non-empty array of unique positive integers + * A, consider the following graph: + * + *

There are A.length nodes, labelled A[0] to A[A.length - 1]; There is an edge between A[i] and + * A[j] if and only if A[i] and A[j] share a common factor greater than 1. Return the size of the + * largest connected component in the graph. + * + *

Example 1: + * + *

Input: [4,6,15,35] Output: 4 + * + *

Example 2: + * + *

Input: [20,50,9,63] Output: 2 + * + *

Example 3: + * + *

Input: [2,3,6,7,4,12,21,39] Output: 8 + * + *

Note: + * + *

1 <= A.length <= 20000 1 <= A[i] <= 100000 + * + *

Solution: O(primes upto max[A[i]] x N) Find all the primes upto maximum of A[i] and build + * components (using union-find) by finding all the numbers in A[] which are divisible by each prime + * number - keep track of size of each component and return the size of the largest component. + */ +public class LargestComponentSizebyCommonFactor { + private static class UnionFind { + private int[] p; + private int[] rank; + private int[] size; + + UnionFind(int s) { + this.p = new int[s]; + this.rank = new int[s]; + this.size = new int[s]; + init(); + } + /** Initialize with its same index as its parent */ + private void init() { + for (int i = 0; i < p.length; i++) { + p[i] = i; + size[i] = 1; + } + } + /** + * Find the representative vertex + * + * @param i + * @return + */ + private int findSet(int i) { + if (p[i] != i) { + p[i] = findSet(p[i]); + } + return p[i]; + } + + /** + * Perform union of two vertex + * + * @param i + * @param j + * @return true if union is performed successfully, false otherwise + */ + public boolean union(int i, int j) { + int x = findSet(i); + int y = findSet(j); + if (x != y) { + if (rank[x] > rank[y]) { + p[y] = p[x]; + size[x] = size[x] + size[y]; + } else { + p[x] = p[y]; + size[y] = size[x] + size[y]; + if (rank[x] == rank[y]) { + rank[y]++; // increment the rank + } + } + return true; + } + return false; + } + + /** + * is attached to roof + * + * @param i + * @return + */ + public int size(int i) { + return size[findSet(i)]; + } + } + + public static void main(String[] args) { + int[] A = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + System.out.println(new LargestComponentSizebyCommonFactor().largestComponentSize(A)); + } + + public int largestComponentSize(int[] A) { + int max = 0; + for (int a : A) { + max = Math.max(max, a); + } + UnionFind unionFind = new UnionFind(max + 1); + List primeNums = primes(max, A); + int answer = 1; + for (int p : primeNums) { + int curr = -1; + for (int a : A) { + if ((a % p) == 0) { + if (curr != -1) { + unionFind.union(curr, a); + } else curr = a; + } + } + answer = Math.max(answer, unionFind.size(curr)); + } + return answer; + } + + private List primes(int N, int[] A) { + boolean[] P = new boolean[N + 1]; + int[] pF = new int[N + 1]; + int sqRt = (int) Math.sqrt(N); + for (int i = 2; i <= sqRt; i++) { + if (!P[i]) { + for (int j = 2; ; j++) { + if (i * j > N) break; + P[i * j] = true; + if (pF[i * j] == 0) { + pF[i * j] = i; + } + } + } + } + Map result = new HashMap<>(); + for (int a : A) { + if (a == 1) continue; + int n = pF[a]; + while (n != 0) { + result.putIfAbsent(n, 0); + result.put(n, result.get(n) + 1); + a /= n; + n = pF[a]; + } + result.putIfAbsent(a, 0); + result.put(a, result.get(a) + 1); + } + return result.keySet().stream().filter(x -> result.get(x) > 1).collect(Collectors.toList()); + } +} diff --git a/problems/src/math/SmallestRangeI.java b/problems/src/math/SmallestRangeI.java new file mode 100644 index 00000000..95b47fc9 --- /dev/null +++ b/problems/src/math/SmallestRangeI.java @@ -0,0 +1,43 @@ +package math; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 22/08/2019 Given an array A of integers, for each integer A[i] + * we may choose any x with -K <= x <= K, and add x to A[i]. + * + *

After this process, we have some array B. + * + *

Return the smallest possible difference between the maximum value of B and the minimum value + * of B. + * + *

Example 1: + * + *

Input: A = [1], K = 0 Output: 0 Explanation: B = [1] Example 2: + * + *

Input: A = [0,10], K = 2 Output: 6 Explanation: B = [2,8] Example 3: + * + *

Input: A = [1,3,6], K = 3 Output: 0 Explanation: B = [3,3,3] or B = [4,4,4] + * + *

Note: + * + *

1 <= A.length <= 10000 0 <= A[i] <= 10000 0 <= K <= 10000 + */ +public class SmallestRangeI { + public static void main(String[] args) { + // + } + + public int smallestRangeI(int[] A, int K) { + Arrays.sort(A); + if (A.length == 0 || A.length == 1) return 0; + else { + int low = A[0]; + int high = A[A.length - 1]; + int l = low + (K); + int r = high - (K); + if (r > l) return r - l; + else return 0; + } + } +} diff --git a/problems/src/string/FindWordsThatCanBeFormedbyCharacters.java b/problems/src/string/FindWordsThatCanBeFormedbyCharacters.java new file mode 100644 index 00000000..ba29748b --- /dev/null +++ b/problems/src/string/FindWordsThatCanBeFormedbyCharacters.java @@ -0,0 +1,63 @@ +package string; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 28/08/2019 You are given an array of strings words and a string + * chars. + * + *

A string is good if it can be formed by characters from chars (each character can only be used + * once). + * + *

Return the sum of lengths of all good strings in words. + * + *

Example 1: + * + *

Input: words = ["cat","bt","hat","tree"], chars = "atach" Output: 6 Explanation: The strings + * that can be formed are "cat" and "hat" so the answer is 3 + 3 = 6. Example 2: + * + *

Input: words = ["hello","world","leetcode"], chars = "welldonehoneyr" Output: 10 Explanation: + * The strings that can be formed are "hello" and "world" so the answer is 5 + 5 = 10. + * + *

Note: + * + *

1 <= words.length <= 1000 1 <= words[i].length, chars.length <= 100 All strings contain + * lowercase English letters only. + * + *

Solution Do a linear check for each of the words and each of the characters and sum up the + * lengths. Keep a hashmap of key-values to avoid picking the same character again. + */ +public class FindWordsThatCanBeFormedbyCharacters { + public static void main(String[] args) { + String[] A = {"cat", "bt", "hat", "tree"}; + String chars = "atach"; + new FindWordsThatCanBeFormedbyCharacters().countCharacters(A, chars); + } + + public int countCharacters(String[] words, String chars) { + Map countMap = new HashMap<>(); + for (char c : chars.toCharArray()) { + countMap.putIfAbsent(c, 0); + countMap.put(c, countMap.get(c) + 1); + } + int ans = 0; + for (String s : words) { + Map subMap = new HashMap<>(); + for (char c : s.toCharArray()) { + subMap.putIfAbsent(c, 0); + subMap.put(c, subMap.get(c) + 1); + } + boolean possible = true; + for (char k : subMap.keySet()) { + if (!countMap.containsKey(k) || subMap.get(k) > countMap.get(k)) { + possible = false; + break; + } + } + if (possible) { + ans += s.length(); + } + } + return ans; + } +} diff --git a/problems/src/string/MinimumAddtoMakeParenthesesValid.java b/problems/src/string/MinimumAddtoMakeParenthesesValid.java new file mode 100644 index 00000000..ba5c8226 --- /dev/null +++ b/problems/src/string/MinimumAddtoMakeParenthesesValid.java @@ -0,0 +1,53 @@ +package string; + +/** + * Created by gouthamvidyapradhan on 20/08/2019 Given a string S of '(' and ')' parentheses, we add + * the minimum number of parentheses ( '(' or ')', and in any positions ) so that the resulting + * parentheses string is valid. + * + *

Formally, a parentheses string is valid if and only if: + * + *

It is the empty string, or It can be written as AB (A concatenated with B), where A and B are + * valid strings, or It can be written as (A), where A is a valid string. Given a parentheses + * string, return the minimum number of parentheses we must add to make the resulting string valid. + * + *

Example 1: + * + *

Input: "())" Output: 1 Example 2: + * + *

Input: "(((" Output: 3 Example 3: + * + *

Input: "()" Output: 0 Example 4: + * + *

Input: "()))((" Output: 4 + * + *

Note: + * + *

S.length <= 1000 S only consists of '(' and ')' characters. + * + *

Solution O(N) Keep track of count of open parentheses, when ever a closed parentheses appear + * if the count of open parentheses is greater than 0 then decrement this value (identifying that + * there is a matching parentheses already), if the count is 0 then there is a miss match with + * parentheses and hence add one to the result. The final answer is the total of result + open + * parentheses + */ +public class MinimumAddtoMakeParenthesesValid { + public static void main(String[] args) { + System.out.println(new MinimumAddtoMakeParenthesesValid().minAddToMakeValid("()))((")); + } + + public int minAddToMakeValid(String S) { + int result = 0; + int open = 0; + for (char c : S.toCharArray()) { + if (c == '(') { + open++; + } else if (c == ')') { + if (open > 0) { + open--; + } else result++; + } + } + return result + open; + } +} diff --git a/problems/src/tree/BinaryTreeTilt.java b/problems/src/tree/BinaryTreeTilt.java new file mode 100644 index 00000000..76deb62e --- /dev/null +++ b/problems/src/tree/BinaryTreeTilt.java @@ -0,0 +1,54 @@ +package tree; +/** + * Created by gouthamvidyapradhan on 14/08/2019 Given a binary tree, return the tilt of the whole + * tree. + * + *

The tilt of a tree node is defined as the absolute difference between the sum of all left + * subtree node values and the sum of all right subtree node values. Null node has tilt 0. + * + *

The tilt of the whole tree is defined as the sum of all nodes' tilt. + * + *

Example: Input: 1 / \ 2 3 Output: 1 Explanation: Tilt of node 2 : 0 Tilt of node 3 : 0 Tilt of + * node 1 : |2-3| = 1 Tilt of binary tree : 0 + 0 + 1 = 1 Note: + * + *

The sum of node values in any subtree won't exceed the range of 32-bit integer. All the tilt + * values won't exceed the range of 32-bit integer. + * + *

Solution: Find tilt of left node and find tilt of right node and return left + right + curr to + * its parent. + */ +public class BinaryTreeTilt { + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public static void main(String[] args) { + TreeNode node = new TreeNode(1); + node.left = new TreeNode(2); + node.right = new TreeNode(3); + System.out.println(new BinaryTreeTilt().findTilt(node)); + } + + int sum = 0; + + public int findTilt(TreeNode root) { + if (root == null) return 0; + tilt(root); + return sum; + } + + private int tilt(TreeNode node) { + if (node == null) return 0; + int left = tilt(node.left); + int right = tilt(node.right); + sum += Math.abs(left - right); + return left + right + node.val; + } +} diff --git a/problems/src/tree/LeafSimilarTrees.java b/problems/src/tree/LeafSimilarTrees.java new file mode 100644 index 00000000..3250d606 --- /dev/null +++ b/problems/src/tree/LeafSimilarTrees.java @@ -0,0 +1,57 @@ +package tree; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 23/08/2019 Consider all the leaves of a binary tree. From left + * to right order, the values of those leaves form a leaf value sequence. + * + *

For example, in the given tree above, the leaf value sequence is (6, 7, 4, 9, 8). + * + *

Two binary trees are considered leaf-similar if their leaf value sequence is the same. + * + *

Return true if and only if the two given trees with head nodes root1 and root2 are + * leaf-similar. + * + *

Solution: Do a inorder traversal for each trree and keep track of all the leaf nodes of the + * tree in a list. Compare the list and return the answer. + */ +public class LeafSimilarTrees { + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public static void main(String[] args) {} + + public boolean leafSimilar(TreeNode root1, TreeNode root2) { + List list1 = new ArrayList<>(); + List list2 = new ArrayList<>(); + inorder(root1, list1); + inorder(root2, list2); + if (list1.size() != list2.size()) return false; + else { + for (int i = 0, l = list1.size(); i < l; i++) { + if (list1.get(i).intValue() != list2.get(i).intValue()) { + return false; + } + } + } + return true; + } + + private void inorder(TreeNode node, List list) { + if (node != null) { + if (node.left == null && node.right == null) { + list.add(node.val); + } + inorder(node.left, list); + inorder(node.right, list); + } + } +} diff --git a/problems/src/tree/MaximumLevelSumofABinaryTree.java b/problems/src/tree/MaximumLevelSumofABinaryTree.java new file mode 100644 index 00000000..cde5e02b --- /dev/null +++ b/problems/src/tree/MaximumLevelSumofABinaryTree.java @@ -0,0 +1,63 @@ +package tree; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 28/08/2019 Given the root of a binary tree, the level of its + * root is 1, the level of its children is 2, and so on. + * + *

Return the smallest level X such that the sum of all the values of nodes at level X is + * maximal. + * + *

Example 1: + * + *

Input: [1,7,0,7,-8,null,null] Output: 2 Explanation: Level 1 sum = 1. Level 2 sum = 7 + 0 = 7. + * Level 3 sum = 7 + -8 = -1. So we return the level with the maximum sum which is level 2. + * + *

Note: + * + *

The number of nodes in the given tree is between 1 and 10^4. -10^5 <= node.val <= 10^5 + * + *

Solution: Keep a hashmap key-value pairs where key is the level and value is the sum of values + * at that level, do a inorder search in the tree and sum up the values at each level. + */ +public class MaximumLevelSumofABinaryTree { + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + Map levelMap; + + public static void main(String[] args) { + // + } + + public int maxLevelSum(TreeNode root) { + levelMap = new HashMap<>(); + inorder(root, 1); + int max = Integer.MIN_VALUE; + int ans = 0; + for (int k : levelMap.keySet()) { + if (levelMap.get(k) > max) { + max = levelMap.get(k); + ans = k; + } + } + return ans; + } + + private void inorder(TreeNode root, int level) { + if (root != null) { + levelMap.putIfAbsent(level, 0); + levelMap.put(level, levelMap.get(level) + root.val); + inorder(root.left, level + 1); + inorder(root.right, level + 1); + } + } +} diff --git a/problems/src/two_pointers/LastSubstringInLexicographicalOrder.java b/problems/src/two_pointers/LastSubstringInLexicographicalOrder.java new file mode 100644 index 00000000..fb688ff4 --- /dev/null +++ b/problems/src/two_pointers/LastSubstringInLexicographicalOrder.java @@ -0,0 +1,68 @@ +package two_pointers; +/** + * Created by gouthamvidyapradhan on 30/08/2019 Given a string s, return the last substring of s in + * lexicographical order. + * + *

Example 1: + * + *

Input: "abab" Output: "bab" Explanation: The substrings are ["a", "ab", "aba", "abab", "b", + * "ba", "bab"]. The lexicographically maximum substring is "bab". Example 2: + * + *

Input: "leetcode" Output: "tcode" + * + *

Note: + * + *

1 <= s.length <= 4 * 10^5 s contains only lowercase English letters. + * + *

Solution O(N) General idea is as below. Fix the index 0 as the answer initially and start + * iterating the string character by character, if a char is encountered with is greater than the + * current answer then mark this as the answer, if it is same as the current answer then this new + * char can be a potential candidate for a answer hence mark this as a candidate and start comparing + * all the further characters of candidate char and all further chars of current answer if any point + * the char further down the candidate is greater than the char further down the current answer then + * mark the new candidate as the answer. + */ +public class LastSubstringInLexicographicalOrder { + public static void main(String[] args) { + System.out.println(new LastSubstringInLexicographicalOrder().lastSubstring("babcbd")); + } + + public String lastSubstring(String s) { + int currAns = 0; + int candidate = -1; + int prevIndex = 1; + for (int i = 1, l = s.length(); i < l; i++) { + if (candidate != -1) { + if (s.charAt(i) == s.charAt(prevIndex)) { + prevIndex++; + } else if (s.charAt(i) > s.charAt(prevIndex)) { + if (s.charAt(i) > s.charAt(candidate)) { + currAns = i; + candidate = -1; + prevIndex = currAns + 1; + } else if (s.charAt(i) == s.charAt(candidate)) { + currAns = candidate; + candidate = i; + prevIndex = currAns + 1; + } else { + currAns = candidate; + candidate = -1; + prevIndex = currAns + 1; + } + } else { + candidate = -1; + prevIndex = currAns + 1; + } + } else { + if (s.charAt(i) > s.charAt(currAns)) { + currAns = i; + candidate = -1; + prevIndex = currAns + 1; + } else if (s.charAt(i) == s.charAt(currAns)) { + candidate = i; + } + } + } + return s.substring(currAns); + } +} From 214984e9a14ccdb1a8df393f27dce1b55b47d4ea Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Mon, 11 May 2020 22:22:11 +0200 Subject: [PATCH 222/235] New solved problems --- README.md | 46 ++++++- problems/src/array/ArrayNesting.java | 56 ++++++++ problems/src/array/MeetingScheduler.java | 86 ++++++++++++ .../MinimumSwapsToGroupAll1Together.java | 61 +++++++++ problems/src/array/RelativeSortArray.java | 60 +++++++++ .../src/binary_search/ArmstrongNumber.java | 45 +++++++ .../SingleElementInASortedArray.java | 56 ++++++++ .../src/bit_manipulation/BinaryWatch.java | 55 ++++++++ .../breadth_first_search/RottingOranges.java | 84 ++++++++++++ .../ConnectingCitiesWithMinimumCost.java | 117 +++++++++++++++++ .../CriticalConnection.java | 79 ++++++++++++ .../src/depth_first_search/FloodFill.java | 44 +++++++ .../depth_first_search/ParallelCourses.java | 90 +++++++++++++ .../src/divide_and_conquer/MyCalendarII.java | 98 ++++++++++++++ .../src/dynamic_programming/BombEnemy.java | 72 +++++++++++ .../dynamic_programming/BurstBalloons.java | 23 +++- .../CountVowelsPermutation.java | 71 ++++++++++ .../DeleteColumnsToMakeSortedIII.java | 74 +++++++++++ .../DistinctSubsequences.java | 55 ++++++++ .../DistinctSubsequencesII.java | 48 +++++++ .../src/dynamic_programming/FreedomTrail.java | 66 ++++++++++ .../HandshakesThatDontCross.java | 63 +++++++++ .../InterleavingString.java | 39 ++++++ .../src/dynamic_programming/JumpGameV.java | 70 ++++++++++ .../src/dynamic_programming/KnightDialer.java | 81 ++++++++++++ ...LongestChunkedPalindromeDecomposition.java | 56 ++++++++ .../MakeArrayStrictlyIncreasing.java | 81 ++++++++++++ .../MinimumCostToMergeStones.java | 96 ++++++++++++++ .../MinimumDifficultyOfAJobSchedule.java | 65 ++++++++++ ...mumDistanceToTypeAWordUsingTwoFingers.java | 98 ++++++++++++++ .../MinimumNumberOfTaps.java | 70 ++++++++++ ...egativeIntegersWithoutConsecutiveOnes.java | 84 ++++++++++++ .../NumberOfDiceRollsWithTargetSum.java | 52 ++++++++ .../NumberOfWaysToStayInTheSamePlace.java | 67 ++++++++++ .../PalindromePartitioningIII.java | 79 ++++++++++++ .../src/dynamic_programming/StoneGameIII.java | 97 ++++++++++++++ .../dynamic_programming/StrangePrinter.java | 45 +++++++ .../dynamic_programming/TilingARectangle.java | 100 ++++++++++++++ .../dynamic_programming/TossStrangeCoins.java | 34 +++++ .../ValidPalindromeIII.java | 50 +++++++ .../src/greedy/MinimumTimeToBuildBlocks.java | 52 ++++++++ problems/src/greedy/PartitionLabels.java | 43 ++++++ .../AnalyzeUserWebsiteVisitPattern.java | 119 +++++++++++++++++ problems/src/hashing/LargestUniqueNumber.java | 42 ++++++ .../StringTransformsIntoAnotherString.java | 51 ++++++++ problems/src/heap/DistantBarcodes.java | 80 ++++++++++++ problems/src/heap/KClosestPointsToOrigin.java | 66 ++++++++++ .../src/math/MinimumIndexSumOfTwoLists.java | 60 +++++++++ problems/src/math/NthDigit.java | 27 ++++ problems/src/math/RangeAdditionII.java | 44 +++++++ problems/src/math/RectangleOverlap.java | 36 ++++++ problems/src/math/SuperWashingMachines.java | 55 ++++++++ problems/src/string/StampingTheSequence.java | 122 ++++++++++++++++++ problems/src/tree/FlipBinaryTree.java | 60 +++++++++ .../InsufficientNodesinRoottoLeafPaths.java | 56 ++++++++ 55 files changed, 3621 insertions(+), 5 deletions(-) create mode 100644 problems/src/array/ArrayNesting.java create mode 100644 problems/src/array/MeetingScheduler.java create mode 100644 problems/src/array/MinimumSwapsToGroupAll1Together.java create mode 100644 problems/src/array/RelativeSortArray.java create mode 100644 problems/src/binary_search/ArmstrongNumber.java create mode 100644 problems/src/binary_search/SingleElementInASortedArray.java create mode 100644 problems/src/bit_manipulation/BinaryWatch.java create mode 100644 problems/src/breadth_first_search/RottingOranges.java create mode 100644 problems/src/depth_first_search/ConnectingCitiesWithMinimumCost.java create mode 100644 problems/src/depth_first_search/CriticalConnection.java create mode 100644 problems/src/depth_first_search/FloodFill.java create mode 100644 problems/src/depth_first_search/ParallelCourses.java create mode 100644 problems/src/divide_and_conquer/MyCalendarII.java create mode 100644 problems/src/dynamic_programming/BombEnemy.java create mode 100644 problems/src/dynamic_programming/CountVowelsPermutation.java create mode 100644 problems/src/dynamic_programming/DeleteColumnsToMakeSortedIII.java create mode 100644 problems/src/dynamic_programming/DistinctSubsequences.java create mode 100644 problems/src/dynamic_programming/DistinctSubsequencesII.java create mode 100644 problems/src/dynamic_programming/FreedomTrail.java create mode 100644 problems/src/dynamic_programming/HandshakesThatDontCross.java create mode 100644 problems/src/dynamic_programming/InterleavingString.java create mode 100644 problems/src/dynamic_programming/JumpGameV.java create mode 100644 problems/src/dynamic_programming/KnightDialer.java create mode 100644 problems/src/dynamic_programming/LongestChunkedPalindromeDecomposition.java create mode 100644 problems/src/dynamic_programming/MakeArrayStrictlyIncreasing.java create mode 100644 problems/src/dynamic_programming/MinimumCostToMergeStones.java create mode 100644 problems/src/dynamic_programming/MinimumDifficultyOfAJobSchedule.java create mode 100644 problems/src/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java create mode 100644 problems/src/dynamic_programming/MinimumNumberOfTaps.java create mode 100644 problems/src/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java create mode 100644 problems/src/dynamic_programming/NumberOfDiceRollsWithTargetSum.java create mode 100644 problems/src/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java create mode 100644 problems/src/dynamic_programming/PalindromePartitioningIII.java create mode 100644 problems/src/dynamic_programming/StoneGameIII.java create mode 100644 problems/src/dynamic_programming/StrangePrinter.java create mode 100644 problems/src/dynamic_programming/TilingARectangle.java create mode 100644 problems/src/dynamic_programming/TossStrangeCoins.java create mode 100644 problems/src/dynamic_programming/ValidPalindromeIII.java create mode 100644 problems/src/greedy/MinimumTimeToBuildBlocks.java create mode 100644 problems/src/greedy/PartitionLabels.java create mode 100644 problems/src/hashing/AnalyzeUserWebsiteVisitPattern.java create mode 100644 problems/src/hashing/LargestUniqueNumber.java create mode 100644 problems/src/hashing/StringTransformsIntoAnotherString.java create mode 100644 problems/src/heap/DistantBarcodes.java create mode 100644 problems/src/heap/KClosestPointsToOrigin.java create mode 100644 problems/src/math/MinimumIndexSumOfTwoLists.java create mode 100644 problems/src/math/NthDigit.java create mode 100644 problems/src/math/RangeAdditionII.java create mode 100644 problems/src/math/RectangleOverlap.java create mode 100644 problems/src/math/SuperWashingMachines.java create mode 100644 problems/src/string/StampingTheSequence.java create mode 100644 problems/src/tree/FlipBinaryTree.java create mode 100644 problems/src/tree/InsufficientNodesinRoottoLeafPaths.java diff --git a/README.md b/README.md index d4cd0247..f9a2df47 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,10 @@ My accepted leetcode solutions to some of the common interview problems. - [Maximum Sum of Two Non-Overlapping Subarrays](problems/src/array/MaximumSumofTwoNonOverlappingSubarrays.java) (Medium) - [Longest Line of Consecutive One in Matrix](problems/src/array/LongestLineofConsecutiveOneinMatrix.java) (Medium) - [Array Partition I](problems/src/array/ArrayPartitionI.java) (Easy) +- [Relative Sort Array](problems/src/array/RelativeSortArray.java) (Easy) +- [Meeting Scheduler](problems/src/array/MeetingScheduler.java) (Medium) +- [Minimum Swaps to Group All 1's Together](problems/src/array/MinimumSwapsToGroupAll1Together.java) (Medium) +- [Array Nesting](problems/src/array/ArrayNesting.java) (Medium) #### [Backtracking](problems/src/backtracking) @@ -98,6 +102,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Time Based Key-Value Store](problems/src/binary_search/TimeBasedKeyValuePair.java) (Medium) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Window Subsequence](problems/src/binary_search/MinimumWindowSubsequence.java) (Hard) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Koko Eating Bananas](problems/src/binary_search/KokoEatingBananas.java) (Hard) +- [Single Element in a Sorted Array](problems/src/binary_search/SingleElementInASortedArray.java) (Medium) #### [Bit Manipulation](problems/src/bit_manipulation) @@ -106,6 +111,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Total Hamming Distance](problems/src/bit_manipulation/TotalHammingDistance.java) (Medium) - [Divide Two Integers](problems/src/bit_manipulation/DivideTwoIntegers.java) (Medium) - [Binary Number with Alternating Bits](problems/src/bit_manipulation/BinaryNumberWithAlternatingBits.java) (Easy) +- [Binary Watch](problems/src/bit_manipulation/BinaryWatch.java) (Easy) #### [Breadth First Search](problems/src/breadth_first_search) @@ -119,6 +125,7 @@ My accepted leetcode solutions to some of the common interview problems. - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Bus Routes](problems/src/breadth_first_search/BusRoutes.java) (Hard) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Sliding Puzzle](problems/src/breadth_first_search/SlidingPuzzle.java) (Hard) - [Matrix](problems/src/breadth_first_search/Matrix.java) (Medium) +- [Rotting Oranges](problems/src/breadth_first_search/RottingOranges.java) (Medium) #### [Depth First Search](problems/src/depth_first_search) @@ -145,6 +152,9 @@ My accepted leetcode solutions to some of the common interview problems. - [Number of Enclaves](problems/src/depth_first_search/NumberOfEnclaves.java) (Medium) - [As Far from Land as Possible](problems/src/depth_first_search/AsFarfromLandAsPossible.java) (Medium) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimize Malware Spread](problems/src/depth_first_search/MinimizeMalwareSpread.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Parallel Courses](problems/src/depth_first_search/ParallelCourses.java) (Hard) +- [Connecting Cities With Minimum Cost](problems/src/depth_first_search/ConnectingCitiesWithMinimumCost.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Critical Connections in a Network](problems/src/depth_first_search/CriticalConnection.java) (Hard) #### [Design](problems/src/design) @@ -172,6 +182,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Search in a 2D Matrix](problems/src/divide_and_conquer/SearchA2DMatrix.java) (Medium) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [24 Game](problems/src/divide_and_conquer/TwentyFourGame.java) (Hard) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reverse Pairs II](problems/src/divide_and_conquer/ReversePairsII.java) (Hard) +- [My Calendar II](problems/src/divide_and_conquer/MyCalendarII.java) (Medium) #### [Dynamic Programming](problems/src/dynamic_programming) @@ -229,7 +240,32 @@ My accepted leetcode solutions to some of the common interview problems. - [Ones and Zeroes](problems/src/dynamic_programming/OnesAndZeroes.java) (Medium) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Encode String with Shortest Length](problems/src/dynamic_programming/EncodeStringWithShortestLength.java) (Hard) - [Length of Longest Fibonacci Subsequence](problems/src/dynamic_programming/LengthofLongestFibonacciSubsequence.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Encode String with Shortest Length](problems/src/dynamic_programming/EncodeStringWithShortestLength.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Make Array Strictly Increasing](problems/src/dynamic_programming/MakeArrayStrictlyIncreasing.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Number of Taps to Open to Water a Garden](problems/src/dynamic_programming/MinimumNumberOfTaps.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Delete Columns to Make Sorted III](problems/src/dynamic_programming/DeleteColumnsToMakeSortedIII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Handshakes That Don't Cross](problems/src/dynamic_programming/HandshakesThatDontCross.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Difficulty of a Job Schedule](problems/src/dynamic_programming/MinimumDifficultyOfAJobSchedule.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Jump Game V](problems/src/dynamic_programming/JumpGameV.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Freedom Trail](problems/src/dynamic_programming/FreedomTrail.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Strange Printer](problems/src/dynamic_programming/StrangePrinter.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Cost to Merge Stones](problems/src/dynamic_programming/MinimumCostToMergeStones.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Interleaving String](problems/src/dynamic_programming/InterleavingString.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Count Vowels Permutation](problems/src/dynamic_programming/CountVowelsPermutation.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Non-negative Integers without Consecutive Ones](problems/src/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java) (Hard) +- [Bomb Enemy](problems/src/dynamic_programming/BombEnemy.java) (Medium) +- [Number of Dice Rolls With Target Sum](problems/src/dynamic_programming/NumberOfDiceRollsWithTargetSum.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Distinct Subsequences](problems/src/dynamic_programming/DistinctSubsequences.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Distinct Subsequences II](problems/src/dynamic_programming/DistinctSubsequencesII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Distance to Type a Word Using Two Fingers](problems/src/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Valid Palindrome III](problems/src/dynamic_programming/ValidPalindromeIII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Palindrome Partitioning III](problems/src/dynamic_programming/PalindromePartitioningIII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Tiling a Rectangle with the Fewest Squares](problems/src/dynamic_programming/TilingARectangle.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Longest Chunked Palindrome Decomposition](problems/src/dynamic_programming/LongestChunkedPalindromeDecomposition.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Stone Game III](problems/src/dynamic_programming/StoneGameIII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Ways to Stay in the Same Place After Some Steps](problems/src/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java) (Hard) +- [Toss Strange Coins](problems/src/dynamic_programming/TossStrangeCoins.java) (Medium) +- [Knight Dialer](problems/src/dynamic_programming/KnightDialer.java) (Medium) + #### [Greedy](problems/src/greedy) @@ -249,6 +285,7 @@ My accepted leetcode solutions to some of the common interview problems. - [Boats to Save People](problems/src/greedy/BoatsToSavePeople.java) (Medium) - [Broken Calculator](problems/src/greedy/BrokenCalculator.java) (Medium) - [Two City Scheduling](problems/src/greedy/TwoCityScheduling.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Time to Build Blocks](problems/src/greedy/MinimumTimeToBuildBlocks.java) (Hard) #### [Hashing](problems/src/hashing) @@ -268,6 +305,8 @@ My accepted leetcode solutions to some of the common interview problems. - [Distribute Candies](problems/src/hashing/DistributeCandies.java) (Easy) - [Groups of Special-Equivalent Strings](problems/src/hashing/GroupsOfSpecialEquivalentStrings.java) (Easy) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Atoms](problems/src/hashing/NumberOfAtoms.java) (Hard) +- [Analyze User Website Visit Pattern](problems/src/hashing/AnalyzeUserWebsiteVisitPattern.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [String Transforms Into Another String](problems/src/hashing/StringTransformsIntoAnotherString.java) (Hard) #### [Heap](problems/src/heap) @@ -279,6 +318,8 @@ My accepted leetcode solutions to some of the common interview problems. - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Rotation with Highest Score](problems/src/heap/SmallestRotationWithHighestScore.java) (Hard) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximum Frequency Stack](problems/src/heap/FreqStack.java) (Hard) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reachable Nodes In Subdivided Graph](problems/src/heap/ReachableNodesInSubdividedGraph.java) (Hard) +- [K Closest Points to Origin](problems/src/heap/KClosestPointsToOrigin.java) (Medium) +- [Distant Barcodes](problems/src/heap/DistantBarcodes.java) (Medium) #### [Linked List](problems/src/linked_list) @@ -316,6 +357,9 @@ My accepted leetcode solutions to some of the common interview problems. - [Base 7](problems/src/math/Base7.java) (Easy) - [Smallest Range I](problems/src/math/SmallestRangeI.java) (Easy) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Largest Component Size by Common Factor](problems/src/math/LargestComponentSizebyCommonFactor.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Super Washing Machines](problems/src/math/SuperWashingMachines.java) (Hard) +- [Rectangle Overlap](problems/src/math/RectangleOverlap.java) (Easy) +- [Nth Digit](problems/src/math/NthDigit.java) (Easy) #### [Reservoir Sampling](problems/src/reservoir_sampling) diff --git a/problems/src/array/ArrayNesting.java b/problems/src/array/ArrayNesting.java new file mode 100644 index 00000000..afe3ad20 --- /dev/null +++ b/problems/src/array/ArrayNesting.java @@ -0,0 +1,56 @@ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 09/10/2019 A zero-indexed array A of length N contains all + * integers from 0 to N-1. Find and return the longest length of set S, where S[i] = {A[i], A[A[i]], + * A[A[A[i]]], ... } subjected to the rule below. + * + *

Suppose the first element in S starts with the selection of element A[i] of index = i, the + * next element in S should be A[A[i]], and then A[A[A[i]]]… By that analogy, we stop adding right + * before a duplicate element occurs in S. + * + *

Example 1: + * + *

Input: A = [5,4,0,3,1,6,2] Output: 4 Explanation: A[0] = 5, A[1] = 4, A[2] = 0, A[3] = 3, A[4] + * = 1, A[5] = 6, A[6] = 2. + * + *

One of the longest S[K]: S[0] = {A[0], A[5], A[6], A[2]} = {5, 6, 2, 0} + * + *

Note: + * + *

N is an integer within the range [1, 20,000]. The elements of A are all distinct. Each element + * of A is an integer within the range [0, N-1]. + */ +public class ArrayNesting { + public static void main(String[] args) { + int[] A = {5, 4, 0, 3, 1, 6, 2}; + System.out.println(new ArrayNesting().arrayNesting(A)); + } + + Set done; + int count; + + public int arrayNesting(int[] nums) { + done = new HashSet<>(); + int max = 0; + for (int i = 0; i < nums.length; i++) { + if (!done.contains(i)) { + count = 0; + dfs(i, nums); + max = Math.max(max, count); + } + } + return max; + } + + private void dfs(int i, int[] nums) { + done.add(i); + count++; + int n = nums[i]; + if (!done.contains(n)) { + dfs(n, nums); + } + } +} diff --git a/problems/src/array/MeetingScheduler.java b/problems/src/array/MeetingScheduler.java new file mode 100644 index 00000000..29049230 --- /dev/null +++ b/problems/src/array/MeetingScheduler.java @@ -0,0 +1,86 @@ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 19/11/2019 Given the availability time slots arrays slots1 and + * slots2 of two people and a meeting duration duration, return the earliest time slot that works + * for both of them and is of duration duration. + * + *

If there is no common time slot that satisfies the requirements, return an empty array. + * + *

The format of a time slot is an array of two elements [start, end] representing an inclusive + * time range from start to end. + * + *

It is guaranteed that no two availability slots of the same person intersect with each other. + * That is, for any two time slots [start1, end1] and [start2, end2] of the same person, either + * start1 > end2 or start2 > end1. + * + *

Example 1: + * + *

Input: slots1 = [[10,50],[60,120],[140,210]], slots2 = [[0,15],[60,70]], duration = 8 Output: + * [60,68] Example 2: + * + *

Input: slots1 = [[10,50],[60,120],[140,210]], slots2 = [[0,15],[60,70]], duration = 12 Output: + * [] + * + *

Constraints: + * + *

1 <= slots1.length, slots2.length <= 10^4 slots1[i].length, slots2[i].length == 2 slots1[i][0] + * < slots1[i][1] slots2[i][0] < slots2[i][1] 0 <= slots1[i][j], slots2[i][j] <= 10^9 1 <= duration + * <= 10^6 + */ +public class MeetingScheduler { + public static void main(String[] args) { + int[][] slots1 = {{10, 50}, {60, 120}, {140, 210}}; + int[][] slots2 = {{0, 15}, {60, 70}}; + List result = new MeetingScheduler().minAvailableDuration(slots1, slots2, 12); + System.out.println(); + } + + private class Node { + int s, e, type; + + Node(int s, int e, int type) { + this.s = s; + this.e = e; + this.type = type; + } + } + + public List minAvailableDuration(int[][] slots1, int[][] slots2, int duration) { + PriorityQueue pq = + new PriorityQueue<>( + (o1, o2) -> { + int r = Integer.compare(o1.s, o2.s); + if (r == 0) { + return Integer.compare(o1.e, o2.e); + } else return r; + }); + for (int[] s : slots1) { + pq.offer(new Node(s[0], s[1], 1)); + } + for (int[] s : slots2) { + pq.offer(new Node(s[0], s[1], 2)); + } + Node prev = null; + while (!pq.isEmpty()) { + Node node = pq.poll(); + if (prev == null) { + prev = node; + } else { + if (prev.type != node.type) { + int s = Math.max(prev.s, node.s); + int e = Math.min(prev.e, node.e); + if ((e - s) >= duration) { + return Arrays.asList(s, s + duration); + } + } + if (node.e > prev.e) { + prev = node; + } + } + } + return new ArrayList<>(); + } +} diff --git a/problems/src/array/MinimumSwapsToGroupAll1Together.java b/problems/src/array/MinimumSwapsToGroupAll1Together.java new file mode 100644 index 00000000..bbf752a0 --- /dev/null +++ b/problems/src/array/MinimumSwapsToGroupAll1Together.java @@ -0,0 +1,61 @@ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 23/10/2019 Given a binary array data, return the minimum number + * of swaps required to group all 1’s present in the array together in any place in the array. + * + *

Example 1: + * + *

Input: [1,0,1,0,1] Output: 1 Explanation: There are 3 ways to group all 1's together: + * [1,1,1,0,0] using 1 swap. [0,1,1,1,0] using 2 swaps. [0,0,1,1,1] using 1 swap. The minimum is 1. + * Example 2: + * + *

Input: [0,0,0,1,0] Output: 0 Explanation: Since there is only one 1 in the array, no swaps + * needed. Example 3: + * + *

Input: [1,0,1,0,1,0,0,1,1,0,1] Output: 3 Explanation: One possible solution that uses 3 swaps + * is [0,0,0,0,0,1,1,1,1,1,1]. Solution: O(N) All the 1s to be grouped together would mean that all + * 1s should occupy a small window in a array, this window could be in any part of the array - a + * window with minimum number of 0s is the minimum number of swap required. + */ +public class MinimumSwapsToGroupAll1Together { + public static void main(String[] args) { + // + } + + public int minSwaps(int[] data) { + int one = 0; + int zero = 0; + for (int i = 0; i < data.length; i++) { + if (data[i] == 1) { + one++; + } else zero++; + } + if (one == 0) return 0; + int window = one; + one = 0; + zero = 0; + int i = 0, j = window - 1; + for (int k = i; k <= j; k++) { + if (data[k] == 1) { + one++; + } else zero++; + } + i++; + j++; + int min = zero; + for (; j < data.length; i++, j++) { + if (data[j] == 0) { + zero++; + } else one++; + + if (data[i - 1] == 0) { + zero--; + } else one--; + min = Math.min(min, zero); + } + return min; + } +} diff --git a/problems/src/array/RelativeSortArray.java b/problems/src/array/RelativeSortArray.java new file mode 100644 index 00000000..2f15b1d6 --- /dev/null +++ b/problems/src/array/RelativeSortArray.java @@ -0,0 +1,60 @@ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 05/12/2019 Given two arrays arr1 and arr2, the elements of arr2 + * are distinct, and all elements in arr2 are also in arr1. + * + *

Sort the elements of arr1 such that the relative ordering of items in arr1 are the same as in + * arr2. Elements that don't appear in arr2 should be placed at the end of arr1 in ascending order. + * + *

Example 1: + * + *

Input: arr1 = [2,3,1,3,2,4,6,7,9,2,19], arr2 = [2,1,4,3,9,6] Output: [2,2,2,1,4,3,3,9,6,7,19] + * + *

Constraints: + * + *

arr1.length, arr2.length <= 1000 0 <= arr1[i], arr2[i] <= 1000 Each arr2[i] is distinct. Each + * arr2[i] is in arr1. + */ +public class RelativeSortArray { + public static void main(String[] args) { + // + } + + public int[] relativeSortArray(int[] arr1, int[] arr2) { + List notPresent = new ArrayList<>(); + Map map = new HashMap<>(); + Set set = new HashSet<>(); + for (int i : arr2) { + set.add(i); + } + for (int i : arr1) { + map.putIfAbsent(i, 0); + map.put(i, map.get(i) + 1); + } + List result = new ArrayList<>(); + for (int i : arr2) { + int count = map.get(i); + for (int j = 0; j < count; j++) { + result.add(i); + } + } + for (int k : map.keySet()) { + if (!set.contains(k)) { + int count = map.get(k); + for (int i = 0; i < count; i++) { + notPresent.add(k); + } + } + } + notPresent.sort(Comparator.comparingInt(o -> o)); + result.addAll(notPresent); + int[] resA = new int[result.size()]; + for (int i = 0; i < result.size(); i++) { + resA[i] = result.get(i); + } + return resA; + } +} diff --git a/problems/src/binary_search/ArmstrongNumber.java b/problems/src/binary_search/ArmstrongNumber.java new file mode 100644 index 00000000..2a71b088 --- /dev/null +++ b/problems/src/binary_search/ArmstrongNumber.java @@ -0,0 +1,45 @@ +package binary_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 26/11/2019 The k-digit number N is an Armstrong number if and + * only if the k-th power of each digit sums to N. + * + *

Given a positive integer N, return true if and only if it is an Armstrong number. + * + *

Example 1: + * + *

Input: 153 Output: true Explanation: 153 is a 3-digit number, and 153 = 1^3 + 5^3 + 3^3. + * Example 2: + * + *

Input: 123 Output: false Explanation: 123 is a 3-digit number, and 123 != 1^3 + 2^3 + 3^3 = + * 36. + * + *

Note: + * + *

1 <= N <= 10^8 + */ +public class ArmstrongNumber { + public static void main(String[] args) { + // + } + + public boolean isArmstrong(int N) { + int s = String.valueOf(N).length(); + long sum = 0; + for (char c : String.valueOf(N).toCharArray()) { + int i = Integer.parseInt(String.valueOf(c)); + sum += power(i, s); + } + return (sum == N); + } + + private long power(int n, int p) { + long res = 1L; + for (int i = 0; i < p; i++) { + res *= n; + } + return res; + } +} diff --git a/problems/src/binary_search/SingleElementInASortedArray.java b/problems/src/binary_search/SingleElementInASortedArray.java new file mode 100644 index 00000000..f2feb412 --- /dev/null +++ b/problems/src/binary_search/SingleElementInASortedArray.java @@ -0,0 +1,56 @@ +package binary_search; + +/** + * Created by gouthamvidyapradhan on 30/01/2020 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. + * + *

Example 1: + * + *

Input: [1,1,2,3,3,4,4,8,8] Output: 2 Example 2: + * + *

Input: [3,3,7,7,10,11,11] Output: 10 + * + *

Note: Your solution should run in O(log n) time and O(1) space. + */ +public class SingleElementInASortedArray { + public static void main(String[] args) { + int[] A = {3, 3, 7, 7, 10, 11, 11}; + System.out.println(new SingleElementInASortedArray().singleNonDuplicate(A)); + } + + public int singleNonDuplicate(int[] nums) { + if (nums.length == 1) return nums[0]; + int l = 0, h = nums.length - 1; + while (l <= h) { + int m = l + ((h - l) / 2); + int N = nums[m]; + if (m + 1 >= nums.length) { + if (nums[m - 1] != N) { + return N; + } + h = m - 1; + } else if (m - 1 < 0) { + if (nums[m + 1] != N) { + return N; + } + l = m + 1; + } else { + if (m % 2 == 0) { + if (nums[m + 1] != N && nums[m - 1] != N) { + return N; + } else if (nums[m + 1] != N) { + h = m - 1; + } else l = m + 1; + } else { + if (nums[m + 1] != N && nums[m - 1] != N) { + return N; + } else if (nums[m - 1] != N) { + h = m - 1; + } else l = m + 1; + } + } + } + return -1; + } +} diff --git a/problems/src/bit_manipulation/BinaryWatch.java b/problems/src/bit_manipulation/BinaryWatch.java new file mode 100644 index 00000000..965e81d6 --- /dev/null +++ b/problems/src/bit_manipulation/BinaryWatch.java @@ -0,0 +1,55 @@ +package bit_manipulation; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 05/11/2019 A binary watch has 4 LEDs on the top which represent + * the hours (0-11), and the 6 LEDs on the bottom represent the minutes (0-59). + * + *

Each LED represents a zero or one, with the least significant bit on the right. + * + *

For example, the above binary watch reads "3:25". + * + *

Given a non-negative integer n which represents the number of LEDs that are currently on, + * return all possible times the watch could represent. + * + *

Example: + * + *

Input: n = 1 Return: ["1:00", "2:00", "4:00", "8:00", "0:01", "0:02", "0:04", "0:08", "0:16", + * "0:32"] Note: The order of output does not matter. The hour must not contain a leading zero, for + * example "01:00" is not valid, it should be "1:00". The minute must be consist of two digits and + * may contain a leading zero, for example "10:2" is not valid, it should be "10:02". + */ +public class BinaryWatch { + public static void main(String[] args) { + System.out.println(new BinaryWatch().readBinaryWatch(1)); + } + + public List readBinaryWatch(int num) { + int H = 11, M = 59; + List result = new ArrayList<>(); + if (num == 0) { + result.add("0:00"); + return result; + } + for (int i = 0; i <= H; i++) { + for (int j = 0; j <= M; j++) { + int count = 0; + for (int k = 0; k < 4; k++) { + if (((1 << k) & i) > 0) { + count++; + } + } + for (int k = 0; k < 6; k++) { + if (((1 << k) & j) > 0) { + count++; + } + } + if (count == num) { + result.add(i + ":" + ((String.valueOf(j).length() == 1) ? ("0" + j) : j)); + } + } + } + return result; + } +} diff --git a/problems/src/breadth_first_search/RottingOranges.java b/problems/src/breadth_first_search/RottingOranges.java new file mode 100644 index 00000000..c812cad2 --- /dev/null +++ b/problems/src/breadth_first_search/RottingOranges.java @@ -0,0 +1,84 @@ +package breadth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 04/12/2019 In a given grid, each cell can have one of three + * values: + * + *

the value 0 representing an empty cell; the value 1 representing a fresh orange; the value 2 + * representing a rotten orange. Every minute, any fresh orange that is adjacent (4-directionally) + * to a rotten orange becomes rotten. + * + *

Return the minimum number of minutes that must elapse until no cell has a fresh orange. If + * this is impossible, return -1 instead. + * + *

Example 1: + * + *

Input: [[2,1,1],[1,1,0],[0,1,1]] Output: 4 Example 2: + * + *

Input: [[2,1,1],[0,1,1],[1,0,1]] Output: -1 Explanation: The orange in the bottom left corner + * (row 2, column 0) is never rotten, because rotting only happens 4-directionally. Example 3: + * + *

Input: [[0,2]] Output: 0 Explanation: Since there are already no fresh oranges at minute 0, + * the answer is just 0. + * + *

Note: + * + *

1 <= grid.length <= 10 1 <= grid[0].length <= 10 grid[i][j] is only 0, 1, or 2. + */ +public class RottingOranges { + final int[] R = {1, -1, 0, 0}; + final int[] C = {0, 0, 1, -1}; + + public static void main(String[] args) { + int[][] A = {{2, 1, 1}, {1, 1, 0}, {0, 1, 1}}; + System.out.println(new RottingOranges().orangesRotting(A)); + } + + private class Node { + int r, c, v; + + Node(int r, int c, int v) { + this.r = r; + this.c = c; + this.v = v; + } + } + + public int orangesRotting(int[][] grid) { + Queue queue = new ArrayDeque<>(); + boolean[][] done = new boolean[grid.length][grid[0].length]; + 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 Node(i, j, 0)); + done[i][j] = true; + } + } + } + int max = 0; + while (!queue.isEmpty()) { + Node curr = queue.poll(); + for (int i = 0; i < 4; i++) { + int newR = curr.r + R[i]; + int newC = curr.c + C[i]; + if (newR >= 0 && newR < grid.length && newC >= 0 && newC < grid[0].length) { + if (!done[newR][newC] && grid[newR][newC] != 0) { + done[newR][newC] = true; + max = Math.max(max, curr.v + 1); + queue.offer(new Node(newR, newC, curr.v + 1)); + } + } + } + } + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 1 && !done[i][j]) { + return -1; + } + } + } + return max; + } +} diff --git a/problems/src/depth_first_search/ConnectingCitiesWithMinimumCost.java b/problems/src/depth_first_search/ConnectingCitiesWithMinimumCost.java new file mode 100644 index 00000000..c4b92280 --- /dev/null +++ b/problems/src/depth_first_search/ConnectingCitiesWithMinimumCost.java @@ -0,0 +1,117 @@ +package depth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 26/11/2019 There are N cities numbered from 1 to N. + * + *

You are given connections, where each connections[i] = [city1, city2, cost] represents the + * cost to connect city1 and city2 together. (A connection is bidirectional: connecting city1 and + * city2 is the same as connecting city2 and city1.) + * + *

Return the minimum cost so that for every pair of cities, there exists a path of connections + * (possibly of length 1) that connects those two cities together. The cost is the sum of the + * connection costs used. If the task is impossible, return -1. + * + *

Example 1: + * + *

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. Example 2: + * + *

Input: N = 4, connections = [[1,2,3],[3,4,4]] Output: -1 Explanation: There is no way to + * connect all cities even if all edges are used. + * + *

Note: + * + *

1 <= N <= 10000 1 <= connections.length <= 10000 1 <= connections[i][0], connections[i][1] <= + * N 0 <= connections[i][2] <= 10^5 connections[i][0] != connections[i][1] + */ +public class ConnectingCitiesWithMinimumCost { + + /** @author gouthamvidyapradhan Class to represent UnionFind Disjoint Set */ + private class UnionFind { + private int[] p; + private int[] rank; + private int numOfDisjoinSet; + + UnionFind(int s) { + this.p = new int[s]; + this.rank = new int[s]; + this.numOfDisjoinSet = s - 1; + init(); + } + + /** Initialize with its same index as its parent */ + public void init() { + for (int i = 0; i < p.length; i++) p[i] = i; + } + /** + * Find the representative vertex + * + * @param i + * @return + */ + private int findSet(int i) { + if (p[i] != i) p[i] = findSet(p[i]); + return p[i]; + } + /** + * Perform union of two vertex + * + * @param i + * @param j + * @return true if union is performed successfully, false otherwise + */ + public boolean union(int i, int j) { + int x = findSet(i); + int y = findSet(j); + if (x != y) { + if (rank[x] > rank[y]) p[y] = p[x]; + else { + p[x] = p[y]; + if (rank[x] == rank[y]) rank[y]++; // increment the rank + } + numOfDisjoinSet--; + return true; + } + return false; + } + } + + private class Edge { + int v1; + int v2; + int distance; + + Edge(int v1, int v2, int distance) { + this.v1 = v1; + this.v2 = v2; + this.distance = distance; + } + } + + private List edges = new ArrayList<>(); + int min = 0; + + public static void main(String[] args) { + int[][] A = {{1, 2, 3}, {3, 4, 4}}; + System.out.println(new ConnectingCitiesWithMinimumCost().minimumCost(4, A)); + } + + public int minimumCost(int N, int[][] connections) { + UnionFind uF = new UnionFind(N + 1); + for (int i = 0; i < connections.length; i++) { + edges.add(new Edge(connections[i][0], connections[i][1], connections[i][2])); + } + edges.sort(Comparator.comparingInt(o -> o.distance)); + for (Edge e : edges) { + if (uF.union(e.v1, e.v2)) { + min += e.distance; + } + if (uF.numOfDisjoinSet == 1) { + return min; + } + } + return -1; + } +} diff --git a/problems/src/depth_first_search/CriticalConnection.java b/problems/src/depth_first_search/CriticalConnection.java new file mode 100644 index 00000000..221ccb17 --- /dev/null +++ b/problems/src/depth_first_search/CriticalConnection.java @@ -0,0 +1,79 @@ +package depth_first_search; + +import java.util.*; + +/** Created by gouthamvidyapradhan on 05/12/2019 */ +public class CriticalConnection { + public static void main(String[] args) { + CriticalConnection task = new CriticalConnection(); + List c = new ArrayList<>(); + c.add(0); + c.add(1); + + List c1 = new ArrayList<>(); + c1.add(1); + c1.add(2); + + List c2 = new ArrayList<>(); + c2.add(2); + c2.add(0); + + List c3 = new ArrayList<>(); + c3.add(1); + c3.add(3); + + List> connections = new ArrayList<>(); + connections.add(c); + connections.add(c1); + connections.add(c2); + connections.add(c3); + List> result = task.criticalConnections(4, connections); + System.out.println(); + } + + private int[] dLow; + private int[] dNum; + private int num = 0; + + public List> criticalConnections(int n, List> connections) { + dLow = new int[n]; + dNum = new int[n]; + Map> graph = new HashMap<>(); + Arrays.fill(dLow, -1); + Arrays.fill(dNum, -1); + for (List connection : connections) { + graph.putIfAbsent(connection.get(0), new ArrayList<>()); + graph.putIfAbsent(connection.get(1), new ArrayList<>()); + graph.get(connection.get(0)).add(connection.get(1)); + graph.get(connection.get(1)).add(connection.get(0)); + } + dfs(-1, 0, graph); + List> result = new ArrayList<>(); + for (List connection : connections) { + if (dLow[connection.get(1)] > dNum[connection.get(0)] + || dLow[connection.get(0)] > dNum[connection.get(1)]) { + result.add(connection); + } + } + return result; + } + + private int dfs(int u, int v, Map> graph) { + int n = num++; + dNum[v] = n; + dLow[v] = n; + List children = graph.get(v); + if (children != null) { + for (int c : children) { + if (c != u) { + if (dNum[c] == -1) { + dLow[v] = Math.min(dLow[v], dfs(v, c, graph)); + } else { + dLow[v] = Math.min(dLow[c], dLow[v]); + } + } + } + } + return dLow[v]; + } +} diff --git a/problems/src/depth_first_search/FloodFill.java b/problems/src/depth_first_search/FloodFill.java new file mode 100644 index 00000000..de52df09 --- /dev/null +++ b/problems/src/depth_first_search/FloodFill.java @@ -0,0 +1,44 @@ +package depth_first_search; + +import java.util.*; + +/** Created by gouthamvidyapradhan on 29/01/2020 */ +public class FloodFill { + final int[] R = {1, -1, 0, 0}; + final int[] C = {0, 0, -1, 1}; + + public static void main(String[] args) { + // + } + + boolean done[][]; + + public int[][] floodFill(int[][] image, int sr, int sc, int newColor) { + done = new boolean[image.length][image[0].length]; + int[][] copy = new int[image.length][image[0].length]; + for (int i = 0; i < image.length; i++) { + for (int j = 0; j < image[0].length; j++) { + copy[i][j] = image[i][j]; + } + } + dfs(copy, sr, sc, image[sr][sc], newColor); + return copy; + } + + private void dfs(int[][] image, int r, int c, int c1, int c2) { + done[r][c] = true; + image[r][c] = c2; + for (int i = 0; i < 4; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 + && newC >= 0 + && newR < image.length + && newC < image[0].length + && image[newR][newC] == c1 + && !done[newR][newC]) { + dfs(image, newR, newC, c1, c2); + } + } + } +} diff --git a/problems/src/depth_first_search/ParallelCourses.java b/problems/src/depth_first_search/ParallelCourses.java new file mode 100644 index 00000000..9d1d81ec --- /dev/null +++ b/problems/src/depth_first_search/ParallelCourses.java @@ -0,0 +1,90 @@ +package depth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 26/11/2019 There are N courses, labelled from 1 to N. + * + *

We are given relations[i] = [X, Y], representing a prerequisite relationship between course X + * and course Y: course X has to be studied before course Y. + * + *

In one semester you can study any number of courses as long as you have studied all the + * prerequisites for the course you are studying. + * + *

Return the minimum number of semesters needed to study all courses. If there is no way to + * study all the courses, return -1. + * + *

Example 1: + * + *

Input: N = 3, relations = [[1,3],[2,3]] Output: 2 Explanation: In the first semester, courses + * 1 and 2 are studied. In the second semester, course 3 is studied. Example 2: + * + *

Input: N = 3, relations = [[1,2],[2,3],[3,1]] Output: -1 Explanation: No course can be studied + * because they depend on each other. + * + *

Note: + * + *

1 <= N <= 5000 1 <= relations.length <= 5000 relations[i][0] != relations[i][1] There are no + * repeated relations in the input. + */ +public class ParallelCourses { + public static void main(String[] args) { + int[][] A = {{1, 3}, {2, 3}}; + System.out.println(new ParallelCourses().minimumSemesters(3, A)); + } + + Map> graph; + Set done; + Set visited; + + public int minimumSemesters(int N, int[][] relations) { + graph = new HashMap<>(); + for (int[] E : relations) { + graph.putIfAbsent(E[0], new ArrayList<>()); + graph.get(E[0]).add(E[1]); + } + done = new HashSet<>(); + visited = new HashSet<>(); + Stack stack = new Stack<>(); + for (int v : graph.keySet()) { + if (!done.contains(v)) { + boolean status = dfs(v, stack); // toposort and return false if a cycle is found + if (!status) return -1; + } + } + int[] DP = new int[N + 1]; + int max = 0; + while (!stack.isEmpty()) { + int v = stack.pop(); + List children = graph.get(v); + if (children != null) { + for (int c : children) { + DP[c] = Math.max(DP[c], DP[v] + 1); + max = Math.max(max, DP[c]); + } + } + } + return max + 1; + } + + private boolean dfs(int v, Stack stack) { + done.add(v); + visited.add(v); + List children = graph.get(v); + if (children != null) { + for (int c : children) { + if (!visited.contains(c)) { + if (!done.contains(c)) { + boolean status = dfs(c, stack); + if (!status) return false; + } + } else { + return false; + } + } + } + visited.remove(v); + stack.push(v); + return true; + } +} diff --git a/problems/src/divide_and_conquer/MyCalendarII.java b/problems/src/divide_and_conquer/MyCalendarII.java new file mode 100644 index 00000000..7cbcf2d9 --- /dev/null +++ b/problems/src/divide_and_conquer/MyCalendarII.java @@ -0,0 +1,98 @@ +package divide_and_conquer; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 02/11/2019 Implement a MyCalendarTwo class to store your + * events. A new event can be added if adding the event will not cause a triple booking. + * + *

Your class will have one method, book(int start, int end). Formally, this represents a booking + * on the half open interval [start, end), the range of real numbers x such that start <= x < end. + * + *

A triple booking happens when three events have some non-empty intersection (ie., there is + * some time that is common to all 3 events.) + * + *

For each call to the method MyCalendar.book, return true if the event can be added to the + * calendar successfully without causing a triple booking. Otherwise, return false and do not add + * the event to the calendar. + * + *

Your class will be called like this: MyCalendar cal = new MyCalendar(); MyCalendar.book(start, + * end) Example 1: + * + *

MyCalendar(); MyCalendar.book(10, 20); // returns true MyCalendar.book(50, 60); // returns + * true MyCalendar.book(10, 40); // returns true MyCalendar.book(5, 15); // returns false + * MyCalendar.book(5, 10); // returns true MyCalendar.book(25, 55); // returns true Explanation: The + * first two events can be booked. The third event can be double booked. The fourth event (5, 15) + * can't be booked, because it would result in a triple booking. The fifth event (5, 10) can be + * booked, as it does not use time 10 which is already double booked. The sixth event (25, 55) can + * be booked, as the time in [25, 40) will be double booked with the third event; the time [40, 50) + * will be single booked, and the time [50, 55) will be double booked with the second event. + * + *

Note: + * + *

The number of calls to MyCalendar.book per test case will be at most 1000. In calls to + * MyCalendar.book(start, end), start and end are integers in the range [0, 10^9]. + */ +public class MyCalendarII { + public static void main(String[] args) { + MyCalendarII t = new MyCalendarII(); + System.out.println(t.book(20, 27)); + System.out.println(t.book(27, 36)); + System.out.println(t.book(27, 36)); + System.out.println(t.book(24, 33)); + } + + private class Pair { + int a, b, index; + + Pair(int a, int b, int index) { + this.a = a; + this.b = b; + this.index = index; + } + } + + TreeSet treeSet; + int count; + + public MyCalendarII() { + count = 0; + treeSet = + new TreeSet<>( + (o1, o2) -> { + int r = Integer.compare(o1.a, o2.a); + if (r == 0) { + int r2 = Integer.compare(o1.b, o2.b); + if (r2 == 0) { + return Integer.compare(o1.index, o2.index); + } else return r2; + } + return r; + }); + } + + public boolean book(int start, int end) { + Pair range = new Pair(start, end, count++); + Iterator ascending = treeSet.iterator(); + Pair prev = null; + while (ascending.hasNext()) { + Pair cur = ascending.next(); + if (prev != null) { + if ((range.a >= prev.a && range.a < prev.b) && (range.a >= cur.a && range.a < cur.b)) { + return false; + } else if ((prev.a >= range.a && prev.a < range.b) + && (cur.a >= prev.a && cur.a < Math.min(prev.b, range.b))) { + return false; + } else if ((range.a >= prev.a && range.a < range.b) + && (cur.a >= range.a && cur.a < Math.min(prev.b, range.b))) { + return false; + } + } + if ((range.a >= cur.a && range.a < cur.b) || (cur.a >= range.a && cur.a < range.b)) { + prev = cur; + } + } + treeSet.add(range); + return true; + } +} diff --git a/problems/src/dynamic_programming/BombEnemy.java b/problems/src/dynamic_programming/BombEnemy.java new file mode 100644 index 00000000..2fcbedb3 --- /dev/null +++ b/problems/src/dynamic_programming/BombEnemy.java @@ -0,0 +1,72 @@ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 25/01/2020 Given a 2D grid, each cell is either a wall 'W', an + * enemy 'E' or empty '0' (the number zero), return the maximum enemies you can kill using one bomb. + * The bomb kills all the enemies in the same row and column from the planted point until it hits + * the wall since the wall is too strong to be destroyed. Note: You can only put the bomb at an + * empty cell. + * + *

Example: + * + *

Input: [["0","E","0","0"],["E","0","W","E"],["0","E","0","0"]] Output: 3 Explanation: For the + * given grid, + * + *

0 E 0 0 E 0 W E 0 E 0 0 + * + *

Placing a bomb at (1,1) kills 3 enemies. + */ +public class BombEnemy { + public static void main(String[] args) { + char[][] grid = {{'0', 'E', '0', '0'}, {'E', '0', 'W', 'E'}, {'0', 'E', '0', '0'}}; + System.out.println(new BombEnemy().maxKilledEnemies(grid)); + } + + public int maxKilledEnemies(char[][] grid) { + int[][] DP1 = new int[grid.length][grid[0].length]; + int[][] DP2 = new int[grid.length][grid[0].length]; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 'E') { + DP1[i][j] = 1; + } + if (grid[i][j] != 'W') { + if (j - 1 >= 0) { + DP1[i][j] += DP1[i][j - 1]; + } + if (i - 1 >= 0) { + DP1[i][j] += DP1[i - 1][j]; + } + } + } + } + + for (int i = grid.length - 1; i >= 0; i--) { + for (int j = grid[0].length - 1; j >= 0; j--) { + if (grid[i][j] == 'E') { + DP2[i][j] = 1; + } + if (grid[i][j] != 'W') { + if (j + 1 < grid[0].length) { + DP2[i][j] += DP2[i][j + 1]; + } + if (i + 1 < grid.length) { + DP2[i][j] += DP2[i + 1][j]; + } + } + } + } + + int max = 0; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == '0') { + max = Math.max(max, DP1[i][j] + DP2[i][j]); + } + } + } + return max; + } +} diff --git a/problems/src/dynamic_programming/BurstBalloons.java b/problems/src/dynamic_programming/BurstBalloons.java index 0379ebad..e74b6048 100644 --- a/problems/src/dynamic_programming/BurstBalloons.java +++ b/problems/src/dynamic_programming/BurstBalloons.java @@ -1,7 +1,5 @@ package dynamic_programming; -import java.util.Arrays; - /** * Created by gouthamvidyapradhan on 02/01/2018. Given n balloons, indexed from 0 to n-1. Each * balloon is painted with a number on it represented by array nums. You are asked to burst all the @@ -52,11 +50,28 @@ public int maxCoins(int[] nums) { for (int i = 0; i < nums.length; i++) { N[i + 1] = nums[i]; } + int[][] DP = new int[N.length][N.length]; + for (int r = 2; r < N.length; r++) { + for (int i = 0; i < N.length; i++) { + int j = i + r; + if (j < N.length) { + int max = Integer.MIN_VALUE; + for (int t = i + 1; t < j; t++) { + max = Math.max(max, N[t] * N[i] * N[j] + DP[t][j] + DP[i][t]); + } + DP[i][j] = max; + } + } + } + return DP[0][N.length - 1]; + /* for (int i = 0; i < nums.length; i++) { + N[i + 1] = nums[i]; + } dp = new int[N.length][N.length]; for (int[] aDp : dp) { Arrays.fill(aDp, -1); - } - return dp(0, N.length - 1); + }*/ + // return dp(0, N.length - 1); } private int dp(int l, int r) { diff --git a/problems/src/dynamic_programming/CountVowelsPermutation.java b/problems/src/dynamic_programming/CountVowelsPermutation.java new file mode 100644 index 00000000..613b3bba --- /dev/null +++ b/problems/src/dynamic_programming/CountVowelsPermutation.java @@ -0,0 +1,71 @@ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 25/01/2020 Given an integer n, your task is to count how many + * strings of length n can be formed under the following rules: + * + *

Each character is a lower case vowel ('a', 'e', 'i', 'o', 'u') Each vowel 'a' may only be + * followed by an 'e'. Each vowel 'e' may only be followed by an 'a' or an 'i'. Each vowel 'i' may + * not be followed by another 'i'. Each vowel 'o' may only be followed by an 'i' or a 'u'. Each + * vowel 'u' may only be followed by an 'a'. Since the answer may be too large, return it modulo + * 10^9 + 7. + * + *

Example 1: + * + *

Input: n = 1 Output: 5 Explanation: All possible strings are: "a", "e", "i" , "o" and "u". + * Example 2: + * + *

Input: n = 2 Output: 10 Explanation: All possible strings are: "ae", "ea", "ei", "ia", "ie", + * "io", "iu", "oi", "ou" and "ua". Example 3: + * + *

Input: n = 5 Output: 68 + */ +public class CountVowelsPermutation { + public static void main(String[] args) {} + + public int countVowelPermutation(int n) { + if (n == 1) return 5; + Map> graph = new HashMap<>(); + List vowels = Arrays.asList('a', 'e', 'i', 'o', 'u'); + Map count = new HashMap<>(); + vowels.forEach(v -> graph.put(v, new ArrayList<>())); + graph.get('a').add('e'); + graph.get('e').add('a'); + graph.get('e').add('i'); + graph.get('i').add('a'); + graph.get('i').add('e'); + graph.get('i').add('o'); + graph.get('i').add('u'); + graph.get('u').add('a'); + graph.get('o').add('i'); + graph.get('o').add('u'); + count.put('a', 1); + count.put('e', 2); + count.put('i', 4); + count.put('o', 2); + count.put('u', 1); + int[] charCount = new int[5]; + for (int i = 2; i < n; i++) { + int j = 0; + Arrays.fill(charCount, 0); + for (char c : vowels) { + List children = graph.get(c); + for (char child : children) { + charCount[j] = ((charCount[j] + count.get(child)) % 1000000007); + } + j++; + } + j = 0; + for (char c : vowels) { + count.put(c, charCount[j++]); + } + } + int sum = 0; + for (char c : vowels) { + sum = ((sum + (count.get(c))) % 1000000007); + } + return sum; + } +} diff --git a/problems/src/dynamic_programming/DeleteColumnsToMakeSortedIII.java b/problems/src/dynamic_programming/DeleteColumnsToMakeSortedIII.java new file mode 100644 index 00000000..fc28ed7d --- /dev/null +++ b/problems/src/dynamic_programming/DeleteColumnsToMakeSortedIII.java @@ -0,0 +1,74 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 21/02/2020 We are given an array A of N lowercase letter + * strings, all of the same length. + * + *

Now, we may choose any set of deletion indices, and for each string, we delete all the + * characters in those indices. + * + *

For example, if we have an array A = ["babca","bbazb"] and deletion indices {0, 1, 4}, then + * the final array after deletions is ["bc","az"]. + * + *

Suppose we chose a set of deletion indices D such that after deletions, the final array has + * every element (row) in lexicographic order. + * + *

For clarity, A[0] is in lexicographic order (ie. A[0][0] <= A[0][1] <= ... <= A[0][A[0].length + * - 1]), A[1] is in lexicographic order (ie. A[1][0] <= A[1][1] <= ... <= A[1][A[1].length - 1]), + * and so on. + * + *

Return the minimum possible value of D.length. + * + *

Example 1: + * + *

Input: ["babca","bbazb"] Output: 3 Explanation: After deleting columns 0, 1, and 4, the final + * array is A = ["bc", "az"]. Both these rows are individually in lexicographic order (ie. A[0][0] + * <= A[0][1] and A[1][0] <= A[1][1]). Note that A[0] > A[1] - the array A isn't necessarily in + * lexicographic order. Example 2: + * + *

Input: ["edcba"] Output: 4 Explanation: If we delete less than 4 columns, the only row won't + * be lexicographically sorted. Example 3: + * + *

Input: ["ghi","def","abc"] Output: 0 Explanation: All rows are already lexicographically + * sorted. + * + *

Note: + * + *

1 <= A.length <= 100 1 <= A[i].length <= 100 + */ +public class DeleteColumnsToMakeSortedIII { + public static void main(String[] args) { + String[] A = {"ghi", "def", "abc"}; + System.out.println(new DeleteColumnsToMakeSortedIII().minDeletionSize(A)); + } + + int[] DP; + + public int minDeletionSize(String[] A) { + DP = new int[A[0].length()]; + int max = 0; + for (int i = 0; i < A[0].length(); i++) { + max = Math.max(max, dp(A, i)); + } + return A[0].length() - max; + } + + private int dp(String[] A, int i) { + if (i >= A[0].length()) return 0; + else if (DP[i] != 0) return DP[i]; + DP[i] = 1; + for (int j = i + 1; j < A[0].length(); j++) { + boolean possible = true; + for (String str : A) { + if (str.charAt(j) < str.charAt(i)) { + possible = false; + break; + } + } + if (possible) { + DP[i] = Math.max(DP[i], dp(A, j) + 1); + } + } + return DP[i]; + } +} diff --git a/problems/src/dynamic_programming/DistinctSubsequences.java b/problems/src/dynamic_programming/DistinctSubsequences.java new file mode 100644 index 00000000..90155fe4 --- /dev/null +++ b/problems/src/dynamic_programming/DistinctSubsequences.java @@ -0,0 +1,55 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 08/05/2020 Given a string S and a string T, count the number of + * distinct subsequences of S which equals T. + * + *

A subsequence of a string is a new string which is formed from the original string by deleting + * some (can be none) of the characters without disturbing the relative positions of the remaining + * characters. (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not). + * + *

It's guaranteed the answer fits on a 32-bit signed integer. + * + *

Example 1: + * + *

Input: S = "rabbbit", T = "rabbit" Output: 3 Explanation: As shown below, there are 3 ways you + * can generate "rabbit" from S. (The caret symbol ^ means the chosen letters) + * + *

rabbbit ^^^^ ^^ rabbbit ^^ ^^^^ rabbbit ^^^ ^^^ Example 2: + * + *

Input: S = "babgbag", T = "bag" Output: 5 Explanation: As shown below, there are 5 ways you + * can generate "bag" from S. (The caret symbol ^ means the chosen letters) + * + *

babgbag ^^ ^ babgbag ^^ ^ babgbag ^ ^^ babgbag ^ ^^ babgbag ^^^ + */ +public class DistinctSubsequences { + int[][] DP; + + public static void main(String[] args) { + System.out.println(new DistinctSubsequences().numDistinct("babgbag", "bag")); + } + + public int numDistinct(String s, String t) { + DP = new int[s.length()][t.length()]; + for (int i = 0; i < s.length(); i++) { + Arrays.fill(DP[i], -1); + } + return dp(0, 0, s, t); + } + + private int dp(int i, int j, String s, String t) { + if (j >= t.length()) return 1; + else if (i >= s.length()) return 0; + else if (DP[i][j] != -1) return DP[i][j]; + else { + if (s.charAt(i) != t.charAt(j)) { + DP[i][j] = dp(i + 1, j, s, t); + } else { + DP[i][j] = dp(i + 1, j + 1, s, t) + dp(i + 1, j, s, t); + } + return DP[i][j]; + } + } +} diff --git a/problems/src/dynamic_programming/DistinctSubsequencesII.java b/problems/src/dynamic_programming/DistinctSubsequencesII.java new file mode 100644 index 00000000..ad5678d9 --- /dev/null +++ b/problems/src/dynamic_programming/DistinctSubsequencesII.java @@ -0,0 +1,48 @@ +package dynamic_programming; +/** + * Created by gouthamvidyapradhan on 08/05/2020 Given a string S, count the number of distinct, + * non-empty subsequences of S . + * + *

Since the result may be large, return the answer modulo 10^9 + 7. + * + *

Example 1: + * + *

Input: "abc" Output: 7 Explanation: The 7 distinct subsequences are "a", "b", "c", "ab", "ac", + * "bc", and "abc". Example 2: + * + *

Input: "aba" Output: 6 Explanation: The 6 distinct subsequences are "a", "b", "ab", "ba", "aa" + * and "aba". Example 3: + * + *

Input: "aaa" Output: 3 Explanation: The 3 distinct subsequences are "a", "aa" and "aaa". + * + *

Note: + * + *

S contains only lowercase letters. 1 <= S.length <= 2000 + */ +public class DistinctSubsequencesII { + public static void main(String[] args) { + System.out.println(new DistinctSubsequencesII().distinctSubseqII("abac")); + } + + final int MOD = (int) 1e9 + 7; + + public int distinctSubseqII(String S) { + int[] DP = new int[S.length() + 1]; + DP[S.length()] = 1; + for (int i = S.length() - 1; i >= 0; i--) { + int sum = 0; + for (int j = i + 1; j <= S.length(); j++) { + sum = ((sum + DP[j]) % MOD); + if (j < S.length() && S.charAt(j) == S.charAt(i)) { + break; + } + } + DP[i] = sum; + } + int ans = 0; + for (int i : DP) { + ans = ((ans + i) % MOD); + } + return ans - 1; + } +} diff --git a/problems/src/dynamic_programming/FreedomTrail.java b/problems/src/dynamic_programming/FreedomTrail.java new file mode 100644 index 00000000..776b86b1 --- /dev/null +++ b/problems/src/dynamic_programming/FreedomTrail.java @@ -0,0 +1,66 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 15/02/2020 In the video game Fallout 4, the quest "Road to + * Freedom" requires players to reach a metal dial called the "Freedom Trail Ring", and use the dial + * to spell a specific keyword in order to open the door. + * + *

Given a string ring, which represents the code engraved on the outer ring and another string + * key, which represents the keyword needs to be spelled. You need to find the minimum number of + * steps in order to spell all the characters in the keyword. + * + *

Initially, the first character of the ring is aligned at 12:00 direction. You need to spell + * all the characters in the string key one by one by rotating the ring clockwise or anticlockwise + * to make each character of the string key aligned at 12:00 direction and then by pressing the + * center button. + * + *

At the stage of rotating the ring to spell the key character key[i]: + * + *

You can rotate the ring clockwise or anticlockwise one place, which counts as 1 step. The + * final purpose of the rotation is to align one of the string ring's characters at the 12:00 + * direction, where this character must equal to the character key[i]. If the character key[i] has + * been aligned at the 12:00 direction, you need to press the center button to spell, which also + * counts as 1 step. After the pressing, you could begin to spell the next character in the key + * (next stage), otherwise, you've finished all the spelling. Example: + * + *

Input: ring = "godding", key = "gd" Output: 4 Explanation: For the first key character 'g', + * since it is already in place, we just need 1 step to spell this character. For the second key + * character 'd', we need to rotate the ring "godding" anticlockwise by two steps to make it become + * "ddinggo". Also, we need 1 more step for spelling. So the final output is 4. Note: + * + *

Length of both ring and key will be in range 1 to 100. There are only lowercase letters in + * both strings and might be some duplcate characters in both strings. It's guaranteed that string + * key could always be spelled by rotating the string ring. + */ +public class FreedomTrail { + public static void main(String[] args) { + System.out.println(new FreedomTrail().findRotateSteps("godding", "gd")); + } + + int[][] DP; + + public int findRotateSteps(String ring, String key) { + DP = new int[ring.length()][key.length()]; + return dp(0, ring, key, 0) + key.length(); + } + + private int dp(int i, String ring, String key, int k) { + if (k == key.length()) return 0; + else { + if (DP[i][k] != 0) return DP[i][k]; + char c = key.charAt(k); + int min = Integer.MAX_VALUE; + for (int j = 0; j < ring.length(); j++) { + if (ring.charAt(j) == c) { + min = + Math.min( + min, + Math.min(Math.abs(i - j), ring.length() - Math.abs(i - j)) + + dp(j, ring, key, k + 1)); + } + } + DP[i][k] = min; + return min; + } + } +} diff --git a/problems/src/dynamic_programming/HandshakesThatDontCross.java b/problems/src/dynamic_programming/HandshakesThatDontCross.java new file mode 100644 index 00000000..56b75b4b --- /dev/null +++ b/problems/src/dynamic_programming/HandshakesThatDontCross.java @@ -0,0 +1,63 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 19/02/2020 You are given an even number of people num_people + * that stand around a circle and each person shakes hands with someone else, so that there are + * num_people / 2 handshakes total. + * + *

Return the number of ways these handshakes could occur such that none of the handshakes cross. + * + *

Since this number could be very big, return the answer mod 10^9 + 7 + * + *

Example 1: + * + *

Input: num_people = 2 Output: 1 Example 2: + * + *

Input: num_people = 4 Output: 2 Explanation: There are two ways to do it, the first way is + * [(1,2),(3,4)] and the second one is [(2,3),(4,1)]. Example 3: + * + *

Input: num_people = 6 Output: 5 Example 4: + * + *

Input: num_people = 8 Output: 14 + * + *

Constraints: + * + *

2 <= num_people <= 1000 num_people % 2 == 0 + */ +public class HandshakesThatDontCross { + public static void main(String[] args) { + System.out.println(new HandshakesThatDontCross().numberOfWays(20)); + } + + int[] DP; + final int MOD = 1000000007; + + public int numberOfWays(int N) { + // DP = new int[N + 1][N + 1]; + DP = new int[N + 1]; + Arrays.fill(DP, -1); + // + // for(int i = 0; i <= N; i ++){ + // Arrays.fill(DP[i], -1); + // } + return dp(0, N - 1); + } + + private int dp(int i, int j) { + if (i > j) return 1; + else if ((j - i + 1) % 2 != 0) return 0; + else if (DP[j - i + 1] != -1) return DP[j - i + 1]; + else { + int sum = 0; + for (int k = i; k <= j; k++) { + int left = (dp(i + 1, k - 1) % MOD); + int right = (dp(k + 1, j) % MOD); + sum = ((sum + ((left * right) % MOD)) % MOD); + } + DP[j - i + 1] = sum; + return sum; + } + } +} diff --git a/problems/src/dynamic_programming/InterleavingString.java b/problems/src/dynamic_programming/InterleavingString.java new file mode 100644 index 00000000..2a3e5e78 --- /dev/null +++ b/problems/src/dynamic_programming/InterleavingString.java @@ -0,0 +1,39 @@ +package dynamic_programming; +/** + * Created by gouthamvidyapradhan on 30/01/2020 Given s1, s2, s3, find whether s3 is formed by the + * interleaving of s1 and s2. + * + *

Example 1: + * + *

Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac" Output: true Example 2: + * + *

Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc" Output: false + */ +public class InterleavingString { + public static void main(String[] args) { + System.out.println(new InterleavingString().isInterleave("aabcc", "aabcc", "aabcaabccc")); + } + + public boolean isInterleave(String s1, String s2, String s3) { + boolean[][] DP = new boolean[s1.length() + 1][s2.length() + 1]; + DP[0][0] = true; + if (s3.length() != (s2.length() + s1.length())) return false; + for (int i = 0; i <= s1.length(); i++) { + for (int j = 0; j <= s2.length(); j++) { + if (i == 0 && j == 0) continue; + int index = (i + j); + if (j > 0) { + if (s3.charAt(index - 1) == s2.charAt(j - 1) && DP[i][j - 1]) { + DP[i][j] = true; + } + } + if (i > 0) { + if (s3.charAt(index - 1) == s1.charAt(i - 1) && DP[i - 1][j]) { + DP[i][j] = true; + } + } + } + } + return DP[s1.length()][s2.length()]; + } +} diff --git a/problems/src/dynamic_programming/JumpGameV.java b/problems/src/dynamic_programming/JumpGameV.java new file mode 100644 index 00000000..8241d084 --- /dev/null +++ b/problems/src/dynamic_programming/JumpGameV.java @@ -0,0 +1,70 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 18/02/2020 Given an array of integers arr and an integer d. In + * one step you can jump from index i to index: + * + *

i + x where: i + x < arr.length and 0 < x <= d. i - x where: i - x >= 0 and 0 < x <= d. In + * addition, you can only jump from index i to index j if arr[i] > arr[j] and arr[i] > arr[k] for + * all indices k between i and j (More formally min(i, j) < k < max(i, j)). + * + *

You can choose any index of the array and start jumping. Return the maximum number of indices + * you can visit. + * + *

Notice that you can not jump outside of the array at any time. + * + *

Example 1: + * + *

Input: arr = [6,4,14,6,8,13,9,7,10,6,12], d = 2 Output: 4 Explanation: You can start at index + * 10. You can jump 10 --> 8 --> 6 --> 7 as shown. Note that if you start at index 6 you can only + * jump to index 7. You cannot jump to index 5 because 13 > 9. You cannot jump to index 4 because + * index 5 is between index 4 and 6 and 13 > 9. Similarly You cannot jump from index 3 to index 2 or + * index 1. Example 2: + * + *

Input: arr = [3,3,3,3,3], d = 3 Output: 1 Explanation: You can start at any index. You always + * cannot jump to any index. Example 3: + * + *

Input: arr = [7,6,5,4,3,2,1], d = 1 Output: 7 Explanation: Start at index 0. You can visit all + * the indicies. Example 4: + * + *

Input: arr = [7,1,7,1,7,1], d = 2 Output: 2 Example 5: + * + *

Input: arr = [66], d = 1 Output: 1 + * + *

Constraints: + * + *

1 <= arr.length <= 1000 1 <= arr[i] <= 10^5 1 <= d <= arr.length + */ +public class JumpGameV { + public static void main(String[] args) { + int[] A = {7, 1, 7, 1, 7, 1}; + System.out.println(new JumpGameV().maxJumps(A, 2)); + } + + int[] DP; + + public int maxJumps(int[] arr, int d) { + DP = new int[arr.length]; + // Arrays.fill(DP, -1); + int max = 0; + for (int i = 0; i < arr.length; i++) { + max = Math.max(max, dp(arr, d, i)); + } + return max; + } + + private int dp(int[] A, int d, int i) { + if (DP[i] != 0) return DP[i]; + int max = 1; + for (int j = i - 1; j >= (i - d); j--) { + if (j < 0 || A[j] >= A[i]) break; + max = Math.max(max, dp(A, d, j) + 1); + } + for (int j = i + 1; j <= (i + d); j++) { + if (j >= A.length || A[j] >= A[i]) break; + max = Math.max(max, dp(A, d, j) + 1); + } + DP[i] = max; + return max; + } +} diff --git a/problems/src/dynamic_programming/KnightDialer.java b/problems/src/dynamic_programming/KnightDialer.java new file mode 100644 index 00000000..be002fef --- /dev/null +++ b/problems/src/dynamic_programming/KnightDialer.java @@ -0,0 +1,81 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 24/09/2019 A chess knight can move as indicated in the chess + * diagram below: + * + *

. + * + *

This time, we place our chess knight on any numbered key of a phone pad (indicated above), and + * the knight makes N-1 hops. Each hop must be from one key to another numbered key. + * + *

Each time it lands on a key (including the initial placement of the knight), it presses the + * number of that key, pressing N digits total. + * + *

How many distinct numbers can you dial in this manner? + * + *

Since the answer may be large, output the answer modulo 10^9 + 7. + * + *

Example 1: + * + *

Input: 1 Output: 10 Example 2: + * + *

Input: 2 Output: 20 Example 3: + * + *

Input: 3 Output: 46 + * + *

Note: + * + *

1 <= N <= 5000 + * + *

Solution: O(N x 4 x 3) Visit all different possible states and sum up the total possible + * moves. Cache the states to avoid recalculating. + */ +public class KnightDialer { + + final int[] R = {-1, -1, -2, -2, 1, 1, 2, 2}; + final int[] C = {2, -2, -1, 1, 2, -2, 1, -1}; + + public static void main(String[] args) { + System.out.println(new KnightDialer().knightDialer(2)); + } + + int[][][] DP; + + public int knightDialer(int N) { + DP = new int[4][3][N + 1]; + int ans = 0; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + if ((i == 3 && j == 0) || (i == 3 && j == 2)) continue; + DP[i][j][0] = 1; + } + } + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + if ((i == 3 && j == 0) || (i == 3 && j == 2)) continue; + ans += (dp(N - 1, i, j) % 10e9 + 7); + ans %= 10e9 + 7; + } + } + return ans; + } + + private int dp(int N, int r, int c) { + if (N < 0) return 0; + if (r == 3 && c == 0) return 0; + if (r == 3 && c == 2) return 0; + if (DP[r][c][N] != 0) return DP[r][c][N]; + int sum = 0; + for (int i = 0; i < 8; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 && newC >= 0 && newR < 4 && newC < 3) { + sum += (dp(N - 1, newR, newC) % 10e9 + 7); + sum %= 10e9 + 7; + } + } + DP[r][c][N] = sum; + return sum; + } +} diff --git a/problems/src/dynamic_programming/LongestChunkedPalindromeDecomposition.java b/problems/src/dynamic_programming/LongestChunkedPalindromeDecomposition.java new file mode 100644 index 00000000..aa721339 --- /dev/null +++ b/problems/src/dynamic_programming/LongestChunkedPalindromeDecomposition.java @@ -0,0 +1,56 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 17/04/2020 Return the largest possible k such that there exists + * a_1, a_2, ..., a_k such that: + * + *

Each a_i is a non-empty string; Their concatenation a_1 + a_2 + ... + a_k is equal to text; + * For all 1 <= i <= k, a_i = a_{k+1 - i}. + * + *

Example 1: + * + *

Input: text = "ghiabcdefhelloadamhelloabcdefghi" Output: 7 Explanation: We can split the + * string on "(ghi)(abcdef)(hello)(adam)(hello)(abcdef)(ghi)". Example 2: + * + *

Input: text = "merchant" Output: 1 Explanation: We can split the string on "(merchant)". + * Example 3: + * + *

Input: text = "antaprezatepzapreanta" Output: 11 Explanation: We can split the string on + * "(a)(nt)(a)(pre)(za)(tpe)(za)(pre)(a)(nt)(a)". Example 4: + * + *

Input: text = "aaa" Output: 3 Explanation: We can split the string on "(a)(a)(a)". + * + *

Constraints: + * + *

text consists only of lowercase English characters. 1 <= text.length <= 1000 + */ +public class LongestChunkedPalindromeDecomposition { + public static void main(String[] args) { + System.out.println( + new LongestChunkedPalindromeDecomposition().longestDecomposition("merchant")); + } + + private int[] DP; + + public int longestDecomposition(String text) { + DP = new int[text.length()]; + return dp(0, text.length() - 1, text); + } + + private int dp(int i, int e, String text) { + if (i > e) return 0; + else if (i == e) return 1; + else if (DP[i] > 0) return DP[i]; + else { + for (int j = e; j > i; j--) { + if (text.charAt(j) == text.charAt(i)) { + if (text.substring(j, e + 1).equals(text.substring(i, i + (e - j + 1)))) { + DP[i] = Math.max(DP[i], dp(i + (e - j + 1), j - 1, text) + 2); + } + } + } + DP[i] = DP[i] == 0 ? 1 : DP[i]; + return DP[i]; + } + } +} diff --git a/problems/src/dynamic_programming/MakeArrayStrictlyIncreasing.java b/problems/src/dynamic_programming/MakeArrayStrictlyIncreasing.java new file mode 100644 index 00000000..85617d79 --- /dev/null +++ b/problems/src/dynamic_programming/MakeArrayStrictlyIncreasing.java @@ -0,0 +1,81 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 28/02/2020 Given two integer arrays arr1 and arr2, return the + * minimum number of operations (possibly zero) needed to make arr1 strictly increasing. + * + *

In one operation, you can choose two indices 0 <= i < arr1.length and 0 <= j < arr2.length and + * do the assignment arr1[i] = arr2[j]. + * + *

If there is no way to make arr1 strictly increasing, return -1. + * + *

Example 1: + * + *

Input: arr1 = [1,5,3,6,7], arr2 = [1,3,2,4] Output: 1 Explanation: Replace 5 with 2, then arr1 + * = [1, 2, 3, 6, 7]. Example 2: + * + *

Input: arr1 = [1,5,3,6,7], arr2 = [4,3,1] Output: 2 Explanation: Replace 5 with 3 and then + * replace 3 with 4. arr1 = [1, 3, 4, 6, 7]. Example 3: + * + *

Input: arr1 = [1,5,3,6,7], arr2 = [1,6,3,3] Output: -1 Explanation: You can't make arr1 + * strictly increasing. + * + *

Constraints: + * + *

1 <= arr1.length, arr2.length <= 2000 0 <= arr1[i], arr2[i] <= 10^9 + */ +public class MakeArrayStrictlyIncreasing { + public static void main(String[] args) { + int[] A = {1, 5, 3, 6, 7}; + int[] B = {4, 3, 1}; + System.out.println(new MakeArrayStrictlyIncreasing().makeArrayIncreasing(A, B)); + } + + private int[][] DP; + + public int makeArrayIncreasing(int[] arr1, int[] arr2) { + DP = new int[arr1.length][arr2.length + 1]; + Arrays.sort(arr2); + for (int i = 0; i < arr1.length; i++) { + Arrays.fill(DP[i], -1); + } + int min = dp(1, 0, arr1, arr2); + for (int i = 0; i < arr2.length; i++) { + min = Math.min(min, dp(1, i + 1, arr1, arr2) + 1); + } + return min == 2000 ? -1 : min; + } + + private int dp(int i, int j, int[] arr1, int[] arr2) { + if (i >= arr1.length) return 0; + else if (DP[i][j] != -1) return DP[i][j]; + else { + int curr = (j == 0 ? arr1[i - 1] : arr2[j - 1]); + int min = 2000; + if (arr1[i] > curr) { + min = dp(i + 1, 0, arr1, arr2); + } + int k = binarySearch(arr2, curr); + if (k != -1) { + min = Math.min(min, dp(i + 1, k + 1, arr1, arr2) + 1); + } + DP[i][j] = min; + return min; + } + } + + private int binarySearch(int[] A, int k) { + int l = 0, h = A.length; + int ans = -1; + while (l < h) { + int m = l + (h - l) / 2; + if (A[m] > k) { + ans = m; + h = m; + } else l = m + 1; + } + return ans; + } +} diff --git a/problems/src/dynamic_programming/MinimumCostToMergeStones.java b/problems/src/dynamic_programming/MinimumCostToMergeStones.java new file mode 100644 index 00000000..86442f22 --- /dev/null +++ b/problems/src/dynamic_programming/MinimumCostToMergeStones.java @@ -0,0 +1,96 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 02/02/2020 There are N piles of stones arranged in a row. The + * i-th pile has stones[i] stones. + * + *

A move consists of merging exactly K consecutive piles into one pile, and the cost of this + * move is equal to the total number of stones in these K piles. + * + *

Find the minimum cost to merge all piles of stones into one pile. If it is impossible, return + * -1. + * + *

Example 1: + * + *

Input: stones = [3,2,4,1], K = 2 Output: 20 Explanation: We start with [3, 2, 4, 1]. We merge + * [3, 2] for a cost of 5, and we are left with [5, 4, 1]. We merge [4, 1] for a cost of 5, and we + * are left with [5, 5]. We merge [5, 5] for a cost of 10, and we are left with [10]. The total cost + * was 20, and this is the minimum possible. Example 2: + * + *

Input: stones = [3,2,4,1], K = 3 Output: -1 Explanation: After any merge operation, there are + * 2 piles left, and we can't merge anymore. So the task is impossible. Example 3: + * + *

Input: stones = [3,5,1,2,6], K = 3 Output: 25 Explanation: We start with [3, 5, 1, 2, 6]. We + * merge [5, 1, 2] for a cost of 8, and we are left with [3, 8, 6]. We merge [3, 8, 6] for a cost of + * 17, and we are left with [17]. The total cost was 25, and this is the minimum possible. + * + *

Note: + * + *

1 <= stones.length <= 30 2 <= K <= 30 1 <= stones[i] <= 100 + */ +public class MinimumCostToMergeStones { + public static void main(String[] args) { + int[] A = {3, 5, 1, 2, 6}; + System.out.println(new MinimumCostToMergeStones().mergeStones(A, 2)); + } + + private int[][][] DP; + private int K; + private int[] sum; + + public int mergeStones(int[] stones, int K) { + if (((stones.length - 1) % (K - 1)) != 0) return -1; + DP = new int[stones.length][stones.length][K + 1]; + this.K = K; + sum = new int[stones.length]; + sum[0] = stones[0]; + for (int i = 1; i < stones.length; i++) { + sum[i] = (sum[i - 1] + stones[i]); + } + for (int i = 0; i < stones.length; i++) { + for (int j = 0; j < stones.length; j++) { + for (int k = 1; k <= K; k++) { + if (k == 1 && i == j) { + DP[i][j][k] = 0; + } else DP[i][j][k] = 999999; + } + } + } + for (int r = 2; r <= stones.length; r++) { + for (int i = 0; i < stones.length; i++) { + int j = i + r - 1; + if (j < stones.length) { + for (int k = 2; k <= K; k++) { + int min = Integer.MAX_VALUE; + for (int t = i; t < j; t++) { + min = Math.min(min, DP[i][t][k - 1] + DP[t + 1][j][1]); + } + DP[i][j][k] = min; + } + DP[i][j][1] = DP[i][j][K] + (sum[j] - ((i - 1) >= 0 ? sum[i - 1] : 0)); + } + } + } + return DP[0][stones.length - 1][1]; + // return dp(0, stones.length - 1, 1); + } + + private int dp(int s, int e, int X) { + if (s == e) { + if (X == 1) return 0; + else return 999999; + } + if (DP[s][e][X] != 0) return DP[s][e][X]; + if (X == 1) { + DP[s][e][X] = dp(s, e, K) + sum[e] - ((s - 1) >= 0 ? sum[s - 1] : 0); + return DP[s][e][X]; + } else { + int min = Integer.MAX_VALUE; + for (int t = s; t < e; t++) { + min = Math.min(min, dp(s, t, X - 1) + dp(t + 1, e, 1)); + } + DP[s][e][X] = min; + return DP[s][e][X]; + } + } +} diff --git a/problems/src/dynamic_programming/MinimumDifficultyOfAJobSchedule.java b/problems/src/dynamic_programming/MinimumDifficultyOfAJobSchedule.java new file mode 100644 index 00000000..8771e62c --- /dev/null +++ b/problems/src/dynamic_programming/MinimumDifficultyOfAJobSchedule.java @@ -0,0 +1,65 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 19/02/2020 You want to schedule a list of jobs in d days. Jobs + * are dependent (i.e To work on the i-th job, you have to finish all the jobs j where 0 <= j < i). + * + *

You have to finish at least one task every day. The difficulty of a job schedule is the sum of + * difficulties of each day of the d days. The difficulty of a day is the maximum difficulty of a + * job done in that day. + * + *

Given an array of integers jobDifficulty and an integer d. The difficulty of the i-th job is + * jobDifficulty[i]. + * + *

Return the minimum difficulty of a job schedule. If you cannot find a schedule for the jobs + * return -1. + * + *

Example 1: + * + *

Input: jobDifficulty = [6,5,4,3,2,1], d = 2 Output: 7 Explanation: First day you can finish + * the first 5 jobs, total difficulty = 6. Second day you can finish the last job, total difficulty + * = 1. The difficulty of the schedule = 6 + 1 = 7 Example 2: + * + *

Input: jobDifficulty = [9,9,9], d = 4 Output: -1 Explanation: If you finish a job per day you + * will still have a free day. you cannot find a schedule for the given jobs. Example 3: + * + *

Input: jobDifficulty = [1,1,1], d = 3 Output: 3 Explanation: The schedule is one job per day. + * total difficulty will be 3. Example 4: + * + *

Input: jobDifficulty = [7,1,7,1,7,1], d = 3 Output: 15 Example 5: + * + *

Input: jobDifficulty = [11,111,22,222,33,333,44,444], d = 6 Output: 843 + * + *

Constraints: + * + *

1 <= jobDifficulty.length <= 300 0 <= jobDifficulty[i] <= 1000 1 <= d <= 10 + */ +public class MinimumDifficultyOfAJobSchedule { + public static void main(String[] args) { + int[] A = {11, 111, 22, 222, 33, 333, 44, 444}; + System.out.println(new MinimumDifficultyOfAJobSchedule().minDifficulty(A, 6)); + } + + int[][] DP; + + public int minDifficulty(int[] jobDifficulty, int d) { + DP = new int[jobDifficulty.length][d + 1]; + int result = dp(0, d, jobDifficulty); + if (result == 50000) return -1; + else return result; + } + + private int dp(int i, int d, int[] J) { + if (i >= J.length && d == 0) return 0; + else if (J.length - i < d || d <= 0) return 50000; + else if (DP[i][d] != 0) return DP[i][d]; + int max = J[i]; + int min = Integer.MAX_VALUE; + for (int k = i; k <= J.length - 1; k++) { + max = Math.max(max, J[k]); + min = Math.min(min, max + dp(k + 1, d - 1, J)); + } + DP[i][d] = min; + return min; + } +} diff --git a/problems/src/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java b/problems/src/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java new file mode 100644 index 00000000..9d66912d --- /dev/null +++ b/problems/src/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java @@ -0,0 +1,98 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 26/04/2020 + * + *

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z + * + *

You have a keyboard layout as shown above in the XY plane, where each English uppercase letter + * is located at some coordinate, for example, the letter A is located at coordinate (0,0), the + * letter B is located at coordinate (0,1), the letter P is located at coordinate (2,3) and the + * letter Z is located at coordinate (4,1). + * + *

Given the string word, return the minimum total distance to type such string using only two + * fingers. The distance between coordinates (x1,y1) and (x2,y2) is |x1 - x2| + |y1 - y2|. + * + *

Note that the initial positions of your two fingers are considered free so don't count towards + * your total distance, also your two fingers do not have to start at the first letter or the first + * two letters. + * + *

Example 1: + * + *

Input: word = "CAKE" Output: 3 Explanation: Using two fingers, one optimal way to type "CAKE" + * is: Finger 1 on letter 'C' -> cost = 0 Finger 1 on letter 'A' -> cost = Distance from letter 'C' + * to letter 'A' = 2 Finger 2 on letter 'K' -> cost = 0 Finger 2 on letter 'E' -> cost = Distance + * from letter 'K' to letter 'E' = 1 Total distance = 3 Example 2: + * + *

Input: word = "HAPPY" Output: 6 Explanation: Using two fingers, one optimal way to type + * "HAPPY" is: Finger 1 on letter 'H' -> cost = 0 Finger 1 on letter 'A' -> cost = Distance from + * letter 'H' to letter 'A' = 2 Finger 2 on letter 'P' -> cost = 0 Finger 2 on letter 'P' -> cost = + * Distance from letter 'P' to letter 'P' = 0 Finger 1 on letter 'Y' -> cost = Distance from letter + * 'A' to letter 'Y' = 4 Total distance = 6 Example 3: + * + *

Input: word = "NEW" Output: 3 Example 4: + * + *

Input: word = "YEAR" Output: 7 + * + *

Constraints: + * + *

2 <= word.length <= 300 Each word[i] is an English uppercase letter. + */ +public class MinimumDistanceToTypeAWordUsingTwoFingers { + int[][] DP; + int[][] dist; + + public static void main(String[] args) { + System.out.println(new MinimumDistanceToTypeAWordUsingTwoFingers().minimumDistance("YEAR")); + } + + public int minimumDistance(String word) { + DP = new int[word.length()][word.length()]; + dist = new int[26][26]; + char[][] chars = { + {'A', 'B', 'C', 'D', 'E', 'F'}, + {'G', 'H', 'I', 'J', 'K', 'L'}, + {'M', 'N', 'O', 'P', 'Q', 'R'}, + {'S', 'T', 'U', 'V', 'W', 'X'}, + {'Y', 'Z', ' ', ' ', ' ', ' '} + }; + for (int i = 0; i < chars.length; i++) { + for (int j = 0; j < chars[0].length; j++) { + char from = chars[i][j]; + if (from == ' ') break; + for (int k = 0; k < chars.length; k++) { + for (int l = 0; l < chars[0].length; l++) { + char to = chars[k][l]; + if (to == ' ') break; + dist[from - 'A'][to - 'A'] = Math.abs(k - i) + Math.abs(l - j); + } + } + } + } + for (int i = 0; i < word.length(); i++) { + for (int j = 0; j < word.length(); j++) { + DP[i][j] = -1; + } + } + int min = Integer.MAX_VALUE; + for (int i = 1; i < word.length(); i++) { + min = Math.min(min, dp(0, i, word)); + } + return min; + } + + private int dp(int p, int i, String S) { + if (DP[p][i] != -1) return DP[p][i]; + else { + int left = Integer.MAX_VALUE, right; + int min = Integer.MAX_VALUE; + if (p + 1 == S.length()) return 0; + if (p + 1 != i) { + left = dp(p + 1, i, S) + dist[S.charAt(p) - 'A'][S.charAt(p + 1) - 'A']; + } + right = dp(p + 1, p, S) + dist[S.charAt(i) - 'A'][S.charAt(p + 1) - 'A']; + DP[p][i] = Math.min(min, Math.min(left, right)); + return DP[p][i]; + } + } +} diff --git a/problems/src/dynamic_programming/MinimumNumberOfTaps.java b/problems/src/dynamic_programming/MinimumNumberOfTaps.java new file mode 100644 index 00000000..8cce9d6f --- /dev/null +++ b/problems/src/dynamic_programming/MinimumNumberOfTaps.java @@ -0,0 +1,70 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 01/03/2020 There is a one-dimensional garden on the x-axis. The + * garden starts at the point 0 and ends at the point n. (i.e The length of the garden is n). + * + *

There are n + 1 taps located at points [0, 1, ..., n] in the garden. + * + *

Given an integer n and an integer array ranges of length n + 1 where ranges[i] (0-indexed) + * means the i-th tap can water the area [i - ranges[i], i + ranges[i]] if it was open. + * + *

Return the minimum number of taps that should be open to water the whole garden, If the garden + * cannot be watered return -1. + * + *

Example 1: + * + *

Input: n = 5, ranges = [3,4,1,1,0,0] Output: 1 Explanation: The tap at point 0 can cover the + * interval [-3,3] The tap at point 1 can cover the interval [-3,5] The tap at point 2 can cover the + * interval [1,3] The tap at point 3 can cover the interval [2,4] The tap at point 4 can cover the + * interval [4,4] The tap at point 5 can cover the interval [5,5] Opening Only the second tap will + * water the whole garden [0,5] Example 2: + * + *

Input: n = 3, ranges = [0,0,0,0] Output: -1 Explanation: Even if you activate all the four + * taps you cannot water the whole garden. Example 3: + * + *

Input: n = 7, ranges = [1,2,1,0,2,1,0,1] Output: 3 Example 4: + * + *

Input: n = 8, ranges = [4,0,0,0,0,0,0,0,4] Output: 2 Example 5: + * + *

Input: n = 8, ranges = [4,0,0,0,4,0,0,0,4] Output: 1 + * + *

Constraints: + * + *

1 <= n <= 10^4 ranges.length == n + 1 0 <= ranges[i] <= 100 + */ +public class MinimumNumberOfTaps { + public static void main(String[] args) { + int[] A = {0, 1, 2, 0, 0, 1, 1, 0}; + System.out.println(new MinimumNumberOfTaps().minTaps(7, A)); + } + + int[] DP; + + public int minTaps(int n, int[] ranges) { + DP = new int[n + 1]; + Arrays.fill(DP, -2); + return dp(0, 0, ranges, n); + } + + private int dp(int i, int prev, int[] R, int n) { + if (i > n) return 0; + else if (DP[i] != -2) return DP[i]; + else { + int min = Integer.MAX_VALUE; + int start = R[prev] > 0 ? prev : i; + for (int j = start; j < start + 100 && j <= n; j++) { + if (j - R[j] <= prev) { + int result = dp(j + R[j] + 1, j + R[j], R, n); + if (result >= 0) { + min = Math.min(min, result + 1); + } + } + } + DP[i] = (min == Integer.MAX_VALUE ? -1 : min); + return DP[i]; + } + } +} diff --git a/problems/src/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java b/problems/src/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java new file mode 100644 index 00000000..6117b1ce --- /dev/null +++ b/problems/src/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java @@ -0,0 +1,84 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 20/10/2019 Given a positive integer n, find the number of + * non-negative integers less than or equal to n, whose binary representations do NOT contain + * consecutive ones. + * + *

Example 1: Input: 5 Output: 5 Explanation: Here are the non-negative integers <= 5 with their + * corresponding binary representations: 0 : 0 1 : 1 2 : 10 3 : 11 4 : 100 5 : 101 Among them, only + * integer 3 disobeys the rule (two consecutive ones) and the other 5 satisfy the rule. Note: 1 <= n + * <= 109 + * + *

Solution: O(1) (30 ^ 2) For each bit we can set either '0' or '1' starting from index i to 0, + * if we set 0 then the next bit i + 1 can be either set to 0 or 1 but, if we set it to 1 then the + * next bit at position i + 1 can only be 0 because two consecutive 1s are invalid. This gives us a + * general dp formula DP[0][i] = DP[0][i + 1] + DP[1][i + 1] for bit 0 and similarly DP[1][i] = + * DP[0][i + 1]. + * + *

Lets consider an example with number = 4 (binary representation is 100). Now, the above + * approach would calculate all possible number ranging from 0 (000) -> 7 (111), lets say the count + * is x. But, we actually want to restrict until only 100. Therefore we have to calculate all valid + * states starting from 100 until 111 and lets say this is y. Now, the answer would be x - y + 1. + * Adding 1 here because the state 100 (which is a valid state) would be counted twice in x and also + * in y. For cases where a binary representation of given N is like 1100 we have to find a max + * possible valid state which occurs just before 1100 which in this case is 1010 and now calculate y + * starting from 1010 to 1111. + */ +public class NonNegativeIntegersWithoutConsecutiveOnes { + public static void main(String[] args) { + System.out.println(new NonNegativeIntegersWithoutConsecutiveOnes().findIntegers(1000000000)); + } + + public int findIntegers(int num) { + int msbIndex = 0; + for (int i = 0; i < 31; i++) { + if (((1 << i) & num) > 0) { + msbIndex = i; + } + } + int[][] DP1 = new int[2][msbIndex + 1]; // count from 0 until all possible value. + int[][] DP2 = new int[2][msbIndex + 2]; // count from given N until max possible value + for (int i = msbIndex; i >= 0; i--) { + if (i == msbIndex) { + DP1[0][msbIndex] = 1; + DP1[1][msbIndex] = 1; + } else { + DP1[0][i] = DP1[0][i + 1] + DP1[1][i + 1]; + DP1[1][i] = DP1[0][i + 1]; + } + } + // find valid state just before given num + int[] bits = new int[msbIndex + 1]; + boolean bitFlipped = false; + for (int i = msbIndex, j = 0; i >= 0; i--, j++) { + if (j == 0) { + bits[j] = 1; + } else { + if (bitFlipped) { + bits[j] = bits[j - 1] == 0 ? 1 : 0; + } else { + if (((1 << i) & num) > 0) { + if (bits[j - 1] > 0) { + bits[j] = 0; + bitFlipped = true; + } else bits[j] = 1; + } + } + } + } + DP2[0][msbIndex + 1] = 1; + for (int i = bits.length - 1; i >= 0; i--) { + if (bits[i] == 0) { + DP2[0][i] = DP2[0][i + 1] + DP2[1][i + 1]; + // if the curr bit is 0 then, we can make this 1 provided the previous bit was not 1 + if (bits[i - 1] == 0) { + DP2[1][i] = (i == bits.length - 1) ? 1 : DP1[0][i + 1]; + } + } else { + DP2[1][i] = DP2[0][i + 1]; + } + } + return (DP1[0][0] + DP1[1][0]) - (DP2[0][0] + DP2[1][0]) + 1; + } +} diff --git a/problems/src/dynamic_programming/NumberOfDiceRollsWithTargetSum.java b/problems/src/dynamic_programming/NumberOfDiceRollsWithTargetSum.java new file mode 100644 index 00000000..024ded3b --- /dev/null +++ b/problems/src/dynamic_programming/NumberOfDiceRollsWithTargetSum.java @@ -0,0 +1,52 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 29/11/2019 You have d dice, and each die has f faces numbered + * 1, 2, ..., f. + * + *

Return the number of possible ways (out of fd total ways) modulo 10^9 + 7 to roll the dice so + * the sum of the face up numbers equals target. + * + *

Example 1: + * + *

Input: d = 1, f = 6, target = 3 Output: 1 Explanation: You throw one die with 6 faces. There + * is only one way to get a sum of 3. Example 2: + * + *

Input: d = 2, f = 6, target = 7 Output: 6 Explanation: You throw two dice, each with 6 faces. + * There are 6 ways to get a sum of 7: 1+6, 2+5, 3+4, 4+3, 5+2, 6+1. Example 3: + * + *

Input: d = 2, f = 5, target = 10 Output: 1 Explanation: You throw two dice, each with 5 faces. + * There is only one way to get a sum of 10: 5+5. Example 4: + * + *

Input: d = 1, f = 2, target = 3 Output: 0 Explanation: You throw one die with 2 faces. There + * is no way to get a sum of 3. Example 5: + * + *

Input: d = 30, f = 30, target = 500 Output: 222616187 Explanation: The answer must be returned + * modulo 10^9 + 7. + * + *

Constraints: + * + *

1 <= d, f <= 30 1 <= target <= 1000 + */ +public class NumberOfDiceRollsWithTargetSum { + public static void main(String[] args) { + System.out.println(new NumberOfDiceRollsWithTargetSum().numRollsToTarget(3, 3, 3)); + } + + private final int MOD = 1000000007; + + public int numRollsToTarget(int d, int f, int target) { + int[][] DP = new int[d + 1][target + 1]; + for (int i = 1; i <= Math.min(f, target); i++) { + DP[1][i] = 1; + } + for (int i = 2; i <= d; i++) { + for (int j = 1; j <= target; j++) { + for (int k = 1; k <= Math.min(f, j); k++) { + DP[i][j] = (DP[i - 1][j - k]) == 0 ? DP[i][j] : ((DP[i][j] + (DP[i - 1][j - k])) % MOD); + } + } + } + return DP[d][target]; + } +} diff --git a/problems/src/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java b/problems/src/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java new file mode 100644 index 00000000..80a51890 --- /dev/null +++ b/problems/src/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java @@ -0,0 +1,67 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 05/04/2020 You have a pointer at index 0 in an array of size + * arrLen. At each step, you can move 1 position to the left, 1 position to the right in the array + * or stay in the same place (The pointer should not be placed outside the array at any time). + * + *

Given two integers steps and arrLen, return the number of ways such that your pointer still at + * index 0 after exactly steps steps. + * + *

Since the answer may be too large, return it modulo 10^9 + 7. + * + *

Example 1: + * + *

Input: steps = 3, arrLen = 2 Output: 4 Explanation: There are 4 differents ways to stay at + * index 0 after 3 steps. Right, Left, Stay Stay, Right, Left Right, Stay, Left Stay, Stay, Stay + * Example 2: + * + *

Input: steps = 2, arrLen = 4 Output: 2 Explanation: There are 2 differents ways to stay at + * index 0 after 2 steps Right, Left Stay, Stay Example 3: + * + *

Input: steps = 4, arrLen = 2 Output: 8 + * + *

Constraints: + * + *

1 <= steps <= 500 1 <= arrLen <= 10^6 + * + *

Solution O(S x S) where S is number of steps. This is quite a straight forward problem. Every + * state is a combination of position in the array and the number of steps. From every state we can + * traverse in three direction remain in the same position i.e (i, n - 1), move right (i + 1, n - 1) + * and move left (i - 1, n - 1). The base state will be (0, 0) which is equal to count of 1, memoize + * each state and do a dop down dp staring from state (0, N). + */ +public class NumberOfWaysToStayInTheSamePlace { + + private static final int MOD = (int) (1e9 + 7); + + public static void main(String[] args) { + System.out.println(new NumberOfWaysToStayInTheSamePlace().numWays(500, 1000000)); + } + + int[][] DP; + + public int numWays(int steps, int arrLen) { + int colLimit = arrLen < steps ? arrLen : steps; + DP = new int[colLimit + 1][steps + 1]; + for (int i = 0; i <= colLimit; i++) { + Arrays.fill(DP[i], -1); + } + DP[0][0] = 1; + return (int) dp(0, steps, arrLen); + } + + private long dp(int i, int n, int A) { + if (i < 0 || i >= A) return 0; + else if (n < 0) return 0; + if (DP[i][n] != -1) return DP[i][n]; + DP[i][n] = + (int) + (((((dp(i, n - 1, A) % MOD) + (dp(i - 1, n - 1, A) % MOD)) % MOD) + + (dp(i + 1, n - 1, A) % MOD)) + % MOD); + return DP[i][n]; + } +} diff --git a/problems/src/dynamic_programming/PalindromePartitioningIII.java b/problems/src/dynamic_programming/PalindromePartitioningIII.java new file mode 100644 index 00000000..a75e49b5 --- /dev/null +++ b/problems/src/dynamic_programming/PalindromePartitioningIII.java @@ -0,0 +1,79 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 22/04/2020 You are given a string s containing lowercase + * letters and an integer k. You need to : + * + *

First, change some characters of s to other lowercase English letters. Then divide s into k + * non-empty disjoint substrings such that each substring is palindrome. Return the minimal number + * of characters that you need to change to divide the string. + * + *

Example 1: + * + *

Input: s = "abc", k = 2 Output: 1 Explanation: You can split the string into "ab" and "c", and + * change 1 character in "ab" to make it palindrome. Example 2: + * + *

Input: s = "aabbc", k = 3 Output: 0 Explanation: You can split the string into "aa", "bb" and + * "c", all of them are palindrome. Example 3: + * + *

Input: s = "leetcode", k = 8 Output: 0 + * + *

Constraints: + * + *

1 <= k <= s.length <= 100. s only contains lowercase English letters. + */ +public class PalindromePartitioningIII { + + public static void main(String[] args) { + System.out.println(new PalindromePartitioningIII().palindromePartition("leetcode", 8)); + } + + int[][][] DP; + + public int palindromePartition(String s, int k) { + DP = new int[s.length()][s.length()][k + 1]; + for (int i = 0; i < s.length(); i++) { + for (int j = 0; j < s.length(); j++) { + Arrays.fill(DP[i][j], -1); + } + } + return dp(0, s.length() - 1, k, s); + } + + private int dp(int i, int j, int n, String s) { + if (i == j && n == 1) return 0; + else if ((j - i + 1 < n) || (n <= 0)) return -1; + else if (DP[i][j][n] != -1) return DP[i][j][n]; + else if (n == 1) { + int result = count(s.substring(i, j + 1)); + DP[i][j][n] = result; + return result; + } else { + int min = Integer.MAX_VALUE; + for (int k = i; k < j; k++) { + int left = dp(i, k, 1, s); + int right = dp(k + 1, j, n - 1, s); + if (right != -1) { + min = Math.min(min, left + right); + } + } + if (min != Integer.MAX_VALUE) { + DP[i][j][n] = min; + return min; + } + return -1; + } + } + + private int count(String s) { + int cnt = 0; + for (int i = 0, j = s.length() - 1; i < j; i++, j--) { + if (s.charAt(i) != s.charAt(j)) { + cnt++; + } + } + return cnt; + } +} diff --git a/problems/src/dynamic_programming/StoneGameIII.java b/problems/src/dynamic_programming/StoneGameIII.java new file mode 100644 index 00000000..3d0ac82c --- /dev/null +++ b/problems/src/dynamic_programming/StoneGameIII.java @@ -0,0 +1,97 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 16/04/2020 Alice and Bob continue their games with piles of + * stones. There are several stones arranged in a row, and each stone has an associated value which + * is an integer given in the array stoneValue. + * + *

Alice and Bob take turns, with Alice starting first. On each player's turn, that player can + * take 1, 2 or 3 stones from the first remaining stones in the row. + * + *

The score of each player is the sum of values of the stones taken. The score of each player is + * 0 initially. + * + *

The objective of the game is to end with the highest score, and the winner is the player with + * the highest score and there could be a tie. The game continues until all the stones have been + * taken. + * + *

Assume Alice and Bob play optimally. + * + *

Return "Alice" if Alice will win, "Bob" if Bob will win or "Tie" if they end the game with the + * same score. + * + *

Example 1: + * + *

Input: values = [1,2,3,7] Output: "Bob" Explanation: Alice will always lose. Her best move + * will be to take three piles and the score become 6. Now the score of Bob is 7 and Bob wins. + * Example 2: + * + *

Input: values = [1,2,3,-9] Output: "Alice" Explanation: Alice must choose all the three piles + * at the first move to win and leave Bob with negative score. If Alice chooses one pile her score + * will be 1 and the next move Bob's score becomes 5. The next move Alice will take the pile with + * value = -9 and lose. If Alice chooses two piles her score will be 3 and the next move Bob's score + * becomes 3. The next move Alice will take the pile with value = -9 and also lose. Remember that + * both play optimally so here Alice will choose the scenario that makes her win. Example 3: + * + *

Input: values = [1,2,3,6] Output: "Tie" Explanation: Alice cannot win this game. She can end + * the game in a draw if she decided to choose all the first three piles, otherwise she will lose. + * Example 4: + * + *

Input: values = [1,2,3,-1,-2,-3,7] Output: "Alice" Example 5: + * + *

Input: values = [-1,-2,-3] Output: "Tie" + * + *

Constraints: + * + *

1 <= values.length <= 50000 -1000 <= values[i] <= 1000 + */ +public class StoneGameIII { + private class State { + int a, b; + + State(int a, int b) { + this.a = a; + this.b = b; + } + } + + public static void main(String[] args) { + int[] V = {-1, -2, -3}; + System.out.println(new StoneGameIII().stoneGameIII(V)); + } + + private State[][] DP; + + public String stoneGameIII(int[] stoneValue) { + DP = new State[2][stoneValue.length]; + State result = dp(0, 0, stoneValue); + return (result.a > result.b) ? "Alice" : (result.b > result.a) ? "Bob" : "Tie"; + } + + private State dp(int i, int p, int[] stoneValue) { + if (i >= stoneValue.length) return new State(0, 0); + else if (DP[p][i] != null) return DP[p][i]; + else { + int sum = 0; + for (int j = 0; j < 3; j++) { + if (i + j >= stoneValue.length) break; + sum += (stoneValue[i + j]); + State result = dp(i + j + 1, (p + 1) % 2, stoneValue); + if (p == 0) { + if (DP[p][i] == null) { + DP[p][i] = new State((sum + result.a), result.b); + } else if (DP[p][i].a < (sum + result.a)) { + DP[p][i] = new State((sum + result.a), result.b); + } + } else { + if (DP[p][i] == null) { + DP[p][i] = new State(result.a, (sum + result.b)); + } else if (DP[p][i].b < (sum + result.b)) { + DP[p][i] = new State(result.a, (sum + result.b)); + } + } + } + return DP[p][i]; + } + } +} diff --git a/problems/src/dynamic_programming/StrangePrinter.java b/problems/src/dynamic_programming/StrangePrinter.java new file mode 100644 index 00000000..a3dae96f --- /dev/null +++ b/problems/src/dynamic_programming/StrangePrinter.java @@ -0,0 +1,45 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 11/02/2020 There is a strange printer with the following two + * special requirements: + * + *

The printer can only print a sequence of the same character each time. At each turn, the + * printer can print new characters starting from and ending at any places, and will cover the + * original existing characters. Given a string consists of lower English letters only, your job is + * to count the minimum number of turns the printer needed in order to print it. + * + *

Example 1: Input: "aaabbb" Output: 2 Explanation: Print "aaa" first and then print "bbb". + * Example 2: Input: "aba" Output: 2 Explanation: Print "aaa" first and then print "b" from the + * second place of the string, which will cover the existing character 'a'. Hint: Length of the + * given string will not exceed 100. + */ +public class StrangePrinter { + public static void main(String[] args) { + String A = "aaaaaaa"; + System.out.println(new StrangePrinter().strangePrinter(A)); + } + + int DP[][]; + + public int strangePrinter(String s) { + DP = new int[s.length() + 1][s.length() + 1]; + return calculate(0, s.length() - 1, s); + } + + private int calculate(int i, int j, String s) { + if (i > j) return 0; + else if (DP[i][j] != 0) return DP[i][j]; + else { + DP[i][j] = calculate(i, j - 1, s) + 1; + int min = DP[i][j]; + for (int m = i; m < j; m++) { + if (s.charAt(m) == s.charAt(j)) { + min = Math.min(min, calculate(i, m, s) + calculate(m + 1, j - 1, s)); + } + } + DP[i][j] = min; + return DP[i][j]; + } + } +} diff --git a/problems/src/dynamic_programming/TilingARectangle.java b/problems/src/dynamic_programming/TilingARectangle.java new file mode 100644 index 00000000..badb9a50 --- /dev/null +++ b/problems/src/dynamic_programming/TilingARectangle.java @@ -0,0 +1,100 @@ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 18/04/2020 + * + *

Given a rectangle of size n x m, find the minimum number of integer-sided squares that tile + * the rectangle. + * + *

Example 1: + * + *

Input: n = 2, m = 3 Output: 3 Explanation: 3 squares are necessary to cover the rectangle. 2 + * (squares of 1x1) 1 (square of 2x2) Example 2: + * + *

Input: n = 5, m = 8 Output: 5 Example 3: + * + *

Input: n = 11, m = 13 Output: 6 + * + *

Constraints: + * + *

1 <= n <= 13 1 <= m <= 13 + */ +public class TilingARectangle { + + public static void main(String[] args) { + System.out.println(new TilingARectangle().tilingRectangle(11, 13)); + } + + Map DP; + + public int tilingRectangle(int n, int m) { + DP = new HashMap<>(); + boolean[][] state = new boolean[n][m]; + return dp(state, 0, n, m); + } + + private int dp(boolean[][] state, int r, int n, int m) { + if (r >= n) return 0; + int[] A = new int[m]; + for (int i = r; i < n; i++) { + for (int j = 0; j < m; j++) { + if (state[i][j]) { + A[j]++; + } + } + } + long hashCode = 1; + for (int i = 0; i < A.length; i++) { + A[i] += r; + hashCode = (hashCode * 31) + A[i]; + } + if (DP.containsKey(hashCode)) return DP.get(hashCode); + else { + int min = Integer.MAX_VALUE; + int c = m; + for (int j = 0; j < m; j++) { + if (!state[r][j]) { + c = j; + break; + } + } + int k = 1; + for (; k <= Math.min(n, m); k++) { + if (r + k > n || c + k > m) break; + else if (state[r][c + k - 1] || state[r + k - 1][c]) break; + for (int a = r; a < (r + k); a++) { + for (int b = c; b < (c + k); b++) { + state[a][b] = true; + A[b]++; + } + } + int next = n; + int j = c + k; + for (int i = r; i < n; i++) { + for (; j < m; j++) { + if (!state[i][j]) { + next = i; + break; + } + } + if (next != n) break; + j = 0; + } + int result = dp(state, next, n, m); + if (result > -1) { + min = Math.min(min, result + 1); + } + } + k--; + for (int a = r; a < (r + k); a++) { + for (int b = c; b < (c + k); b++) { + state[a][b] = false; + } + } + DP.put(hashCode, min == Integer.MAX_VALUE ? -1 : min); + return DP.get(hashCode); + } + } +} diff --git a/problems/src/dynamic_programming/TossStrangeCoins.java b/problems/src/dynamic_programming/TossStrangeCoins.java new file mode 100644 index 00000000..6d1eb4ad --- /dev/null +++ b/problems/src/dynamic_programming/TossStrangeCoins.java @@ -0,0 +1,34 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 19/11/2019 You have some coins. The i-th coin has a probability + * prob[i] of facing heads when tossed. + * + *

Return the probability that the number of coins facing heads equals target if you toss every + * coin exactly once. + * + *

Example 1: + * + *

Input: prob = [0.4], target = 1 Output: 0.40000 Example 2: + * + *

Input: prob = [0.5,0.5,0.5,0.5,0.5], target = 0 Output: 0.03125 + */ +public class TossStrangeCoins { + public static void main(String[] args) { + double[] A = {0.4, 0.4}; + System.out.println(new TossStrangeCoins().probabilityOfHeads(A, 1)); + } + + public double probabilityOfHeads(double[] prob, int target) { + double[][] DP = new double[target + 1][prob.length]; + DP[0][0] = 1 - prob[0]; + DP[1][0] = prob[0]; + for (int c = 1; c < prob.length; c++) { + for (int t = 0; t <= target; t++) { + if (t == 0) DP[t][c] = DP[t][c - 1] * (1 - prob[c]); + else DP[t][c] = DP[t][c - 1] * (1 - prob[c]) + DP[t - 1][c - 1] * (prob[c]); + } + } + return DP[target][prob.length - 1]; + } +} diff --git a/problems/src/dynamic_programming/ValidPalindromeIII.java b/problems/src/dynamic_programming/ValidPalindromeIII.java new file mode 100644 index 00000000..d8a93b8a --- /dev/null +++ b/problems/src/dynamic_programming/ValidPalindromeIII.java @@ -0,0 +1,50 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 23/04/2020 Given a string s and an integer k, find out if the + * given string is a K-Palindrome or not. + * + *

A string is K-Palindrome if it can be transformed into a palindrome by removing at most k + * characters from it. + * + *

Example 1: + * + *

Input: s = "abcdeca", k = 2 Output: true Explanation: Remove 'b' and 'e' characters. + * + *

Constraints: + * + *

1 <= s.length <= 1000 s has only lowercase English letters. 1 <= k <= s.length + */ +public class ValidPalindromeIII { + public static void main(String[] args) { + System.out.println(new ValidPalindromeIII().isValidPalindrome("abc", 0)); + } + + int[][] DP; + + public boolean isValidPalindrome(String s, int k) { + DP = new int[s.length()][s.length()]; + for (int i = 0; i < s.length(); i++) { + Arrays.fill(DP[i], -1); + } + return dp(0, s.length() - 1, s) <= k; + } + + private int dp(int i, int j, String S) { + if (i == j) return 0; + else if (i > j) return 0; + else if (DP[i][j] != -1) return DP[i][j]; + else { + int min = Integer.MAX_VALUE; + if (S.charAt(i) != S.charAt(j)) { + min = Math.min(min, Math.min(dp(i + 1, j, S), dp(i, j - 1, S)) + 1); + } else { + min = dp(i + 1, j - 1, S); + } + DP[i][j] = min; + return min; + } + } +} diff --git a/problems/src/greedy/MinimumTimeToBuildBlocks.java b/problems/src/greedy/MinimumTimeToBuildBlocks.java new file mode 100644 index 00000000..62a4ef7f --- /dev/null +++ b/problems/src/greedy/MinimumTimeToBuildBlocks.java @@ -0,0 +1,52 @@ +package greedy; + +import java.util.PriorityQueue; + +/** + * Created by gouthamvidyapradhan on 05/05/2020 You are given a list of blocks, where blocks[i] = t + * means that the i-th block needs t units of time to be built. A block can only be built by exactly + * one worker. + * + *

A worker can either split into two workers (number of workers increases by one) or build a + * block then go home. Both decisions cost some time. + * + *

The time cost of spliting one worker into two workers is given as an integer split. Note that + * if two workers split at the same time, they split in parallel so the cost would be split. + * + *

Output the minimum time needed to build all blocks. + * + *

Initially, there is only one worker. + * + *

Example 1: + * + *

Input: blocks = [1], split = 1 Output: 1 Explanation: We use 1 worker to build 1 block in 1 + * time unit. Example 2: + * + *

Input: blocks = [1,2], split = 5 Output: 7 Explanation: We split the worker into 2 workers in + * 5 time units then assign each of them to a block so the cost is 5 + max(1, 2) = 7. Example 3: + * + *

Input: blocks = [1,2,3], split = 1 Output: 4 Explanation: Split 1 worker into 2, then assign + * the first worker to the last block and split the second worker into 2. Then, use the two + * unassigned workers to build the first two blocks. The cost is 1 + max(3, 1 + max(1, 2)) = 4. + * + *

Constraints: + * + *

1 <= blocks.length <= 1000 1 <= blocks[i] <= 10^5 1 <= split <= 100 + */ +public class MinimumTimeToBuildBlocks { + public static void main(String[] args) { + int[] A = {1, 2, 3}; + System.out.println(new MinimumTimeToBuildBlocks().minBuildTime(A, 2)); + } + + public int minBuildTime(int[] blocks, int split) { + PriorityQueue queue = new PriorityQueue<>(); + for (int b : blocks) queue.offer(b); + while (queue.size() != 1) { + int a = queue.poll(); + int b = queue.poll(); + queue.offer(Math.max(a, b) + split); + } + return queue.poll(); + } +} diff --git a/problems/src/greedy/PartitionLabels.java b/problems/src/greedy/PartitionLabels.java new file mode 100644 index 00000000..daa68cab --- /dev/null +++ b/problems/src/greedy/PartitionLabels.java @@ -0,0 +1,43 @@ +package greedy; + +import java.util.*; + +/** Created by gouthamvidyapradhan on 30/11/2019 */ +public class PartitionLabels { + public static void main(String[] args) { + System.out.println(new PartitionLabels().partitionLabels("ababcbacadefegdehijhklij")); + } + + public List partitionLabels(String S) { + Map map = new HashMap<>(); + for (int i = 0; i < S.length(); i++) { + char c = S.charAt(i); + map.putIfAbsent(c, i); + map.remove(c); + map.put(c, i); + } + char start = S.charAt(0); + int currMax = map.get(start); + int startIndex = 0; + List list = new ArrayList<>(); + while (true) { + int i = startIndex; + for (; i <= currMax; i++) { + char c = S.charAt(i); + int pos = map.get(c); + currMax = Math.max(currMax, pos); + } + if (i > currMax && i < S.length()) { + list.add(i - startIndex); + startIndex = i; + currMax = map.get(S.charAt(i)); + } else { + if (i == S.length()) { + list.add(i - startIndex); + break; + } + } + } + return list; + } +} diff --git a/problems/src/hashing/AnalyzeUserWebsiteVisitPattern.java b/problems/src/hashing/AnalyzeUserWebsiteVisitPattern.java new file mode 100644 index 00000000..9168cc3d --- /dev/null +++ b/problems/src/hashing/AnalyzeUserWebsiteVisitPattern.java @@ -0,0 +1,119 @@ +package hashing; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 23/10/2019 We are given some website visits: the user with name + * username[i] visited the website website[i] at time timestamp[i]. + * + *

A 3-sequence is a list of websites of length 3 sorted in ascending order by the time of their + * visits. (The websites in a 3-sequence are not necessarily distinct.) + * + *

Find the 3-sequence visited by the largest number of users. If there is more than one + * solution, return the lexicographically smallest such 3-sequence. + * + *

Example 1: + * + *

Input: username = ["joe","joe","joe","james","james","james","james","mary","mary","mary"], + * timestamp = [1,2,3,4,5,6,7,8,9,10], website = + * ["home","about","career","home","cart","maps","home","home","about","career"] Output: + * ["home","about","career"] Explanation: The tuples in this example are: ["joe", 1, "home"] ["joe", + * 2, "about"] ["joe", 3, "career"] ["james", 4, "home"] ["james", 5, "cart"] ["james", 6, "maps"] + * ["james", 7, "home"] ["mary", 8, "home"] ["mary", 9, "about"] ["mary", 10, "career"] The + * 3-sequence ("home", "about", "career") was visited at least once by 2 users. The 3-sequence + * ("home", "cart", "maps") was visited at least once by 1 user. The 3-sequence ("home", "cart", + * "home") was visited at least once by 1 user. The 3-sequence ("home", "maps", "home") was visited + * at least once by 1 user. The 3-sequence ("cart", "maps", "home") was visited at least once by 1 + * user. + * + *

Note: + * + *

3 <= N = username.length = timestamp.length = website.length <= 50 1 <= username[i].length <= + * 10 0 <= timestamp[i] <= 10^9 1 <= website[i].length <= 10 Both username[i] and website[i] contain + * only lowercase characters. It is guaranteed that there is at least one user who visited at least + * 3 websites. No user visits two websites at the same time. + */ +public class AnalyzeUserWebsiteVisitPattern { + private class VisitCount { + String site; + int count; + + VisitCount(String site, int count) { + this.site = site; + this.count = count; + } + + public String getSite() { + return site; + } + + public int getCount() { + return count; + } + } + + private class WebsiteTime { + String website; + int time; + + WebsiteTime(String website, int time) { + this.website = website; + this.time = time; + } + + public int getTime() { + return time; + } + } + + Map> userVisitCount; + + public static void main(String[] args) { + String[] userName = { + "joe", "joe", "joe", "james", "james", "james", "james", "mary", "mary", "mary" + }; + int[] time = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + String[] website = { + "home", "about", "career", "home", "cart", "maps", "home", "home", "about", "career" + }; + List result = + new AnalyzeUserWebsiteVisitPattern().mostVisitedPattern(userName, time, website); + System.out.println(result); + } + + public List mostVisitedPattern(String[] username, int[] timestamp, String[] website) { + userVisitCount = new HashMap<>(); + for (int i = 0; i < username.length; i++) { + for (int j = i + 1; j < username.length; j++) { + if (username[i].equals(username[j])) { + for (int k = j + 1; k < username.length; k++) { + if (username[i].equals(username[j]) && username[j].equals(username[k])) { + List visits = + Arrays.asList( + new WebsiteTime(website[i], timestamp[i]), + new WebsiteTime(website[j], timestamp[j]), + new WebsiteTime(website[k], timestamp[k])); + visits.sort(Comparator.comparingInt(WebsiteTime::getTime)); + String concatinatedWebsite = + String.join( + "-", visits.get(0).website, visits.get(1).website, visits.get(2).website); + userVisitCount.putIfAbsent(concatinatedWebsite, new HashSet<>()); + userVisitCount.get(concatinatedWebsite).add(username[i]); + } + } + } + } + } + List visitCounts = new ArrayList<>(); + for (String k : userVisitCount.keySet()) { + visitCounts.add(new VisitCount(k, userVisitCount.get(k).size())); + } + visitCounts.sort( + Comparator.comparingInt(VisitCount::getCount) + .reversed() + .thenComparing(VisitCount::getSite)); + VisitCount visitCount = visitCounts.get(0); + String[] result = visitCount.getSite().split("-"); + return Arrays.asList(result[0], result[1], result[2]); + } +} diff --git a/problems/src/hashing/LargestUniqueNumber.java b/problems/src/hashing/LargestUniqueNumber.java new file mode 100644 index 00000000..12c2e4db --- /dev/null +++ b/problems/src/hashing/LargestUniqueNumber.java @@ -0,0 +1,42 @@ +package hashing; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 26/11/2019 Given an array of integers A, return the largest + * integer that only occurs once. + * + *

If no integer occurs once, return -1. + * + *

Example 1: + * + *

Input: [5,7,3,9,4,9,8,3,1] Output: 8 Explanation: The maximum integer in the array is 9 but it + * is repeated. The number 8 occurs only once, so it's the answer. Example 2: + * + *

Input: [9,9,8,8] Output: -1 Explanation: There is no number that occurs only once. + * + *

Note: + * + *

1 <= A.length <= 2000 0 <= A[i] <= 1000 + */ +public class LargestUniqueNumber { + public static void main(String[] args) { + // + } + + public int largestUniqueNumber(int[] A) { + Map map = new HashMap<>(); + for (int i : A) { + map.putIfAbsent(i, 0); + int v = map.get(i) + 1; + map.put(i, v); + } + int max = -1; + for (int k : map.keySet()) { + if (map.get(k) == 1) { + max = Math.max(max, k); + } + } + return max; + } +} diff --git a/problems/src/hashing/StringTransformsIntoAnotherString.java b/problems/src/hashing/StringTransformsIntoAnotherString.java new file mode 100644 index 00000000..920c4780 --- /dev/null +++ b/problems/src/hashing/StringTransformsIntoAnotherString.java @@ -0,0 +1,51 @@ +package hashing; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 23/10/2019 Given two strings str1 and str2 of the same length, + * determine whether you can transform str1 into str2 by doing zero or more conversions. + * + *

In one conversion you can convert all occurrences of one character in str1 to any other + * lowercase English character. + * + *

Return true if and only if you can transform str1 into str2. + * + *

Example 1: + * + *

Input: str1 = "aabcc", str2 = "ccdee" Output: true Explanation: Convert 'c' to 'e' then 'b' to + * 'd' then 'a' to 'c'. Note that the order of conversions matter. Example 2: + * + *

Input: str1 = "leetcode", str2 = "codeleet" Output: false Explanation: There is no way to + * transform str1 to str2. + * + *

Note: + * + *

1 <= str1.length == str2.length <= 10^4 Both str1 and str2 contain only lowercase English + * letters. + */ +public class StringTransformsIntoAnotherString { + public static void main(String[] args) { + System.out.println(new StringTransformsIntoAnotherString().canConvert("ab", "ba")); + } + + public boolean canConvert(String str1, String str2) { + if (str1.length() != str2.length()) return false; + if (str1.equals(str2)) return true; + Map mapping = new HashMap<>(); + for (int i = 0; i < str1.length(); i++) { + char c1 = str1.charAt(i); + char c2 = str2.charAt(i); + if (mapping.containsKey(c1)) { + if (mapping.get(c1) != c2) return false; + } else { + mapping.put(c1, c2); + } + } + Set set = new HashSet<>(); + for (char k : mapping.keySet()) { + set.add(mapping.get(k)); + } + return (set.size() < 26); + } +} diff --git a/problems/src/heap/DistantBarcodes.java b/problems/src/heap/DistantBarcodes.java new file mode 100644 index 00000000..652c8ff1 --- /dev/null +++ b/problems/src/heap/DistantBarcodes.java @@ -0,0 +1,80 @@ +package heap; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 04/12/2019 In a warehouse, there is a row of barcodes, where + * the i-th barcode is barcodes[i]. + * + *

Rearrange the barcodes so that no two adjacent barcodes are equal. You may return any answer, + * and it is guaranteed an answer exists. + * + *

Example 1: + * + *

Input: [1,1,1,2,2,2] Output: [2,1,2,1,2,1] Example 2: + * + *

Input: [1,1,1,1,2,2,3,3] Output: [1,3,1,3,2,1,2,1] + * + *

Note: + * + *

1 <= barcodes.length <= 10000 1 <= barcodes[i] <= 10000 + */ +public class DistantBarcodes { + public static void main(String[] args) { + int[] barcode = {1, 1, 1, 2, 2, 2}; + int[] result = new DistantBarcodes().rearrangeBarcodes(barcode); + for (int i : result) { + System.out.print(i + " "); + } + System.out.println(); + } + + class Node { + int value, count, rank; + + Node(int value, int count, int rank) { + this.value = value; + this.count = count; + this.rank = rank; + } + } + + public int[] rearrangeBarcodes(int[] barcodes) { + PriorityQueue pq = + new PriorityQueue<>( + (o1, o2) -> { + int r = Integer.compare(o2.count, o1.count); + return r == 0 ? Integer.compare(o1.rank, o2.rank) : r; + }); + Map map = new HashMap<>(); + for (int b : barcodes) { + map.putIfAbsent(b, 0); + map.put(b, map.get(b) + 1); + } + for (int k : map.keySet()) { + pq.offer(new Node(k, map.get(k), -1)); + } + int[] result = new int[barcodes.length]; + int i = 0; + int rank = 0; + while (!pq.isEmpty()) { + Node node = pq.poll(); + result[i++] = node.value; + node.count -= 1; + node.rank = rank++; + if (!pq.isEmpty()) { + Node next = pq.poll(); + result[i++] = next.value; + next.count -= 1; + next.rank = rank++; + if (next.count > 0) { + pq.offer(next); + } + } + if (node.count > 0) { + pq.offer(node); + } + } + return result; + } +} diff --git a/problems/src/heap/KClosestPointsToOrigin.java b/problems/src/heap/KClosestPointsToOrigin.java new file mode 100644 index 00000000..ed4bc1e3 --- /dev/null +++ b/problems/src/heap/KClosestPointsToOrigin.java @@ -0,0 +1,66 @@ +package heap; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 30/11/2019 We have a list of points on the plane. Find the K + * closest points to the origin (0, 0). + * + *

(Here, the distance between two points on a plane is the Euclidean distance.) + * + *

You may return the answer in any order. The answer is guaranteed to be unique (except for the + * order that it is in.) + * + *

Example 1: + * + *

Input: points = [[1,3],[-2,2]], K = 1 Output: [[-2,2]] Explanation: The distance between (1, + * 3) and the origin is sqrt(10). The distance between (-2, 2) and the origin is sqrt(8). Since + * sqrt(8) < sqrt(10), (-2, 2) is closer to the origin. We only want the closest K = 1 points from + * the origin, so the answer is just [[-2,2]]. Example 2: + * + *

Input: points = [[3,3],[5,-1],[-2,4]], K = 2 Output: [[3,3],[-2,4]] (The answer [[-2,4],[3,3]] + * would also be accepted.) + * + *

Note: + * + *

1 <= K <= points.length <= 10000 -10000 < points[i][0] < 10000 -10000 < points[i][1] < 10000 + */ +public class KClosestPointsToOrigin { + public static void main(String[] args) { + int[][] A = {{3, 3}, {5, -1}, {-2, 4}}; + int[][] ans = new KClosestPointsToOrigin().kClosest(A, 2); + System.out.println(); + } + + class Point { + int a, b; + + Point(int a, int b) { + this.a = a; + this.b = b; + } + + public long distance() { + return (long) (a * a) + (long) (b * b); + } + } + + public int[][] kClosest(int[][] points, int K) { + PriorityQueue pq = + new PriorityQueue<>((o1, o2) -> Long.compare(o2.distance(), o1.distance())); + for (int[] p : points) { + pq.offer(new Point(p[0], p[1])); + if (pq.size() > K) { + pq.poll(); + } + } + int[][] ans = new int[K][2]; + int i = 0; + while (!pq.isEmpty()) { + Point point = pq.poll(); + ans[i][0] = point.a; + ans[i++][1] = point.b; + } + return ans; + } +} diff --git a/problems/src/math/MinimumIndexSumOfTwoLists.java b/problems/src/math/MinimumIndexSumOfTwoLists.java new file mode 100644 index 00000000..942e3a99 --- /dev/null +++ b/problems/src/math/MinimumIndexSumOfTwoLists.java @@ -0,0 +1,60 @@ +package math; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 09/10/2019 Suppose Andy and Doris want to choose a restaurant + * for dinner, and they both have a list of favorite restaurants represented by strings. + * + *

You need to help them find out their common interest with the least list index sum. If there + * is a choice tie between answers, output all of them with no order requirement. You could assume + * there always exists an answer. + * + *

Example 1: Input: ["Shogun", "Tapioca Express", "Burger King", "KFC"] ["Piatti", "The Grill at + * Torrey Pines", "Hungry Hunter Steakhouse", "Shogun"] Output: ["Shogun"] Explanation: The only + * restaurant they both like is "Shogun". Example 2: Input: ["Shogun", "Tapioca Express", "Burger + * King", "KFC"] ["KFC", "Shogun", "Burger King"] Output: ["Shogun"] Explanation: The restaurant + * they both like and have the least index sum is "Shogun" with index sum 1 (0+1). Note: The length + * of both lists will be in the range of [1, 1000]. The length of strings in both lists will be in + * the range of [1, 30]. The index is starting from 0 to the list length minus 1. No duplicates in + * both lists. + * + *

Solution O(N) Maintain a hashmap of restaurant_name with index for one of the list. In the + * first iteration calculate the minimum of sum of indices and in the second iteration add the + * restaurant name to the list if any sum of indices equals the minimum. + */ +public class MinimumIndexSumOfTwoLists { + public static void main(String[] args) { + // + } + + public String[] findRestaurant(String[] list1, String[] list2) { + Map index = new HashMap<>(); + for (int i = 0; i < list2.length; i++) { + String s = list2[i]; + index.put(s, i); + } + int min = Integer.MAX_VALUE; + List list = new ArrayList<>(); + for (int i = 0; i < list1.length; i++) { + if (index.containsKey(list1[i])) { + if (i + index.get(list1[i]) <= min) { + min = i + index.get(list1[i]); + } + } + } + for (int i = 0; i < list1.length; i++) { + if (index.containsKey(list1[i])) { + if (i + index.get(list1[i]) == min) { + list.add(list1[i]); + } + } + } + String[] ans = new String[list.size()]; + int i = 0; + for (String s : list) { + ans[i++] = s; + } + return ans; + } +} diff --git a/problems/src/math/NthDigit.java b/problems/src/math/NthDigit.java new file mode 100644 index 00000000..b4715676 --- /dev/null +++ b/problems/src/math/NthDigit.java @@ -0,0 +1,27 @@ +package math; + +/** Created by gouthamvidyapradhan on 05/11/2019 */ +public class NthDigit { + public static void main(String[] args) { + System.out.println(new NthDigit().findNthDigit(1000000000)); + } + + public int findNthDigit(int n) { + if (n >= 1 && n <= 9) return n; + long sum = 0L; + for (int i = 0; ; i++) { + long pow = (9 * (new Double(Math.pow(10, i)).longValue())) * (i + 1); + sum += pow; + if (sum >= n) { + long diff = (long) n - (sum - pow); + long num = diff / (i + 1); + long mod = diff % (i + 1); + long result = new Double(Math.pow(10, i)).intValue() + (num - 1) + (mod > 0 ? 1 : 0); + String resultStr = String.valueOf(result); + return (mod == 0) + ? Integer.parseInt(String.valueOf(resultStr.charAt(resultStr.length() - 1))) + : Integer.parseInt(String.valueOf(resultStr.charAt((int) mod - 1))); + } + } + } +} diff --git a/problems/src/math/RangeAdditionII.java b/problems/src/math/RangeAdditionII.java new file mode 100644 index 00000000..800a85c7 --- /dev/null +++ b/problems/src/math/RangeAdditionII.java @@ -0,0 +1,44 @@ +package math; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 09/10/2019 Given an m * n matrix M initialized with all 0's and + * several update operations. + * + *

Operations are represented by a 2D array, and each operation is represented by an array with + * two positive integers a and b, which means M[i][j] should be added by one for all 0 <= i < a and + * 0 <= j < b. + * + *

You need to count and return the number of maximum integers in the matrix after performing all + * the operations. + * + *

Example 1: Input: m = 3, n = 3 operations = [[2,2],[3,3]] Output: 4 Explanation: Initially, M + * = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] + * + *

After performing [2,2], M = [[1, 1, 0], [1, 1, 0], [0, 0, 0]] + * + *

After performing [3,3], M = [[2, 2, 1], [2, 2, 1], [1, 1, 1]] + * + *

So the maximum integer in M is 2, and there are four of it in M. So return 4. Note: The range + * of m and n is [1,40000]. The range of a is [1,m], and the range of b is [1,n]. The range of + * operations size won't exceed 10,000. + * + *

Solution: O(N) where N is the number of operations. For every operation, keep track of minimum + * of each row and column and return the product of minR x minC + */ +public class RangeAdditionII { + public static void main(String[] args) { + // + } + + public int maxCount(int m, int n, int[][] ops) { + int minR = m; + int minC = n; + for (int[] v : ops) { + minR = Math.min(minR, v[0]); + minC = Math.min(minC, v[1]); + } + return minR * minC; + } +} diff --git a/problems/src/math/RectangleOverlap.java b/problems/src/math/RectangleOverlap.java new file mode 100644 index 00000000..303c4a0a --- /dev/null +++ b/problems/src/math/RectangleOverlap.java @@ -0,0 +1,36 @@ +package math; + +/** + * Created by gouthamvidyapradhan on 30/11/2019 A rectangle is represented as a list [x1, y1, x2, + * y2], where (x1, y1) are the coordinates of its bottom-left corner, and (x2, y2) are the + * coordinates of its top-right corner. + * + *

Two rectangles overlap if the area of their intersection is positive. To be clear, two + * rectangles that only touch at the corner or edges do not overlap. + * + *

Given two (axis-aligned) rectangles, return whether they overlap. + * + *

Example 1: + * + *

Input: rec1 = [0,0,2,2], rec2 = [1,1,3,3] Output: true Example 2: + * + *

Input: rec1 = [0,0,1,1], rec2 = [1,0,2,1] Output: false Notes: + * + *

Both rectangles rec1 and rec2 are lists of 4 integers. All coordinates in rectangles will be + * between -10^9 and 10^9. + */ +public class RectangleOverlap { + public static void main(String[] args) { + int[] A = {0, 0, 2, 2}; + int[] B = {1, 1, 3, 3}; + System.out.println(new RectangleOverlap().isRectangleOverlap(A, B)); + } + + public boolean isRectangleOverlap(int[] rec1, int[] rec2) { + boolean x = + ((rec1[0] >= rec2[0] && rec1[0] < rec2[2]) || (rec2[0] >= rec1[0] && rec2[0] < rec1[2])); + boolean y = + ((rec1[1] >= rec2[1] && rec1[1] < rec2[3]) || (rec2[1] >= rec1[1] && rec2[1] < rec1[3])); + return x && y; + } +} diff --git a/problems/src/math/SuperWashingMachines.java b/problems/src/math/SuperWashingMachines.java new file mode 100644 index 00000000..a1fa2dc5 --- /dev/null +++ b/problems/src/math/SuperWashingMachines.java @@ -0,0 +1,55 @@ +package math; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 30/01/2020 You have n super washing machines on a line. + * Initially, each washing machine has some dresses or is empty. + * + *

For each move, you could choose any m (1 ≤ m ≤ n) washing machines, and pass one dress of each + * washing machine to one of its adjacent washing machines at the same time . + * + *

Given an integer array representing the number of dresses in each washing machine from left to + * right on the line, you should find the minimum number of moves to make all the washing machines + * have the same number of dresses. If it is not possible to do it, return -1. + * + *

Example1 + * + *

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

Output: 3 + * + *

Explanation: 1st move: 1 0 <-- 5 => 1 1 4 2nd move: 1 <-- 1 <-- 4 => 2 1 3 3rd move: 2 1 <-- 3 + * => 2 2 2 Example2 + * + *

Input: [0,3,0] + * + *

Output: 2 + * + *

Explanation: 1st move: 0 <-- 3 0 => 1 2 0 2nd move: 1 2 --> 0 => 1 1 1 Example3 + * + *

Input: [0,2,0] + * + *

Output: -1 + * + *

Explanation: It's impossible to make all the three washing machines have the same number of + * dresses. Note: The range of n is [1, 10000]. The range of dresses number in a super washing + * machine is [0, 1e5]. + */ +public class SuperWashingMachines { + public static void main(String[] args) { + // + } + + public int findMinMoves(int[] machines) { + long sum = Arrays.stream(machines).asLongStream().sum(); + if (((sum / machines.length) < 0) || ((sum % machines.length) != 0)) return -1; + int n = (int) (sum / machines.length); + int count = 0, moves = Integer.MIN_VALUE; + for (int i = 0; i < machines.length; i++) { + count += (machines[i] - n); + moves = Math.max(moves, Math.max(Math.abs(count), (machines[i] - n))); + } + return moves; + } +} diff --git a/problems/src/string/StampingTheSequence.java b/problems/src/string/StampingTheSequence.java new file mode 100644 index 00000000..77efffd5 --- /dev/null +++ b/problems/src/string/StampingTheSequence.java @@ -0,0 +1,122 @@ +package string; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * Created by gouthamvidyapradhan on 12/10/2019 You want to form a target string of lowercase + * letters. + * + *

At the beginning, your sequence is target.length '?' marks. You also have a stamp of lowercase + * letters. + * + *

On each turn, you may place the stamp over the sequence, and replace every letter in the + * sequence with the corresponding letter from the stamp. You can make up to 10 * target.length + * turns. + * + *

For example, if the initial sequence is "?????", and your stamp is "abc", then you may make + * "abc??", "?abc?", "??abc" in the first turn. (Note that the stamp must be fully contained in the + * boundaries of the sequence in order to stamp.) + * + *

If the sequence is possible to stamp, then return an array of the index of the left-most + * letter being stamped at each turn. If the sequence is not possible to stamp, return an empty + * array. + * + *

For example, if the sequence is "ababc", and the stamp is "abc", then we could return the + * answer [0, 2], corresponding to the moves "?????" -> "abc??" -> "ababc". + * + *

Also, if the sequence is possible to stamp, it is guaranteed it is possible to stamp within 10 + * * target.length moves. Any answers specifying more than this number of moves will not be + * accepted. + * + *

Example 1: + * + *

Input: stamp = "abc", target = "ababc" Output: [0,2] ([1,0,2] would also be accepted as an + * answer, as well as some other answers.) Example 2: + * + *

Input: stamp = "abca", target = "aabcaca" Output: [3,0,1] + * + *

Note: + * + *

1 <= stamp.length <= target.length <= 1000 stamp and target only contain lowercase letters. + * + *

Solution: O(N ^ 2) General idea is to work the answer in the reverse order. For example if the + * target string is 'aaabb' and stamp is 'aabb' then first stamp would be at 0 resulting in aabb? + * and the next stamp would be at 1 resulting in 'aaabb' Consider each window of size = stamp.size + * from index 0 (call this window at index i). For every window keep track of matched indices and + * unmatched indices. Also, additionally Maintain a general-matched-index set containing all the + * indices that are already matched. For every window, if all the characters at each index of stamp + * sequence and target sequence match then add the window index to the answer also additionally + * revisit every widow index that have been previously visited in starting from i - 1 to 0 and + * verify if any window contains all the matched indices this can be checked by verifying the + * unmatched set at each widow to general-matched-index - if any of the window satisfy this + * condition then add this window index to the answer. Return the answer in the reverse order. + */ +public class StampingTheSequence { + public static void main(String[] args) { + int[] ans = new StampingTheSequence().movesToStamp("abca", "aaaaaaaaabcaaca"); + for (int a : ans) System.out.print(a + " "); + } + + private class Window { + Set matched, unmatched; + + Window(Set matched, Set unmatched) { + this.matched = matched; + this.unmatched = unmatched; + } + } + + public int[] movesToStamp(String stamp, String target) { + List windows = new ArrayList<>(); + Set matchedTarget = new HashSet<>(); + Stack answer = new Stack<>(); + for (int i = 0; i <= target.length() - stamp.length(); i++) { + Window current = new Window(new HashSet<>(), new HashSet<>()); + for (int j = i, s = 0; j < (i + stamp.length()); j++, s++) { + if (stamp.charAt(s) == target.charAt(j) || matchedTarget.contains(j)) { + current.matched.add(j); + } else current.unmatched.add(j); + } + if (current.unmatched.isEmpty()) { + answer.push(i); + matchedTarget.addAll(current.matched); + for (int k = windows.size() - 1; k >= 0; k--) { + if (!windows.get(k).unmatched.isEmpty()) { + Set newUnmatched = + windows + .get(k) + .unmatched + .stream() + .filter(u -> !matchedTarget.contains(u)) + .collect(Collectors.toSet()); + windows.get(k).unmatched = newUnmatched; + if (newUnmatched.isEmpty()) { + Set newMatched = + windows + .get(k) + .matched + .stream() + .filter(m -> !matchedTarget.contains(m)) + .collect(Collectors.toSet()); + if (!newMatched.isEmpty()) { + answer.push(k); + matchedTarget.addAll(newMatched); + } + } + } else break; + } + } + windows.add(current); + } + if (matchedTarget.size() == target.length()) { + int[] finalAns = new int[answer.size()]; + int i = 0; + while (!answer.isEmpty()) { + finalAns[i++] = answer.pop(); + } + return finalAns; + } + return new int[] {}; + } +} diff --git a/problems/src/tree/FlipBinaryTree.java b/problems/src/tree/FlipBinaryTree.java new file mode 100644 index 00000000..31445be5 --- /dev/null +++ b/problems/src/tree/FlipBinaryTree.java @@ -0,0 +1,60 @@ +package tree; + +import java.util.*; + +/** Created by gouthamvidyapradhan on 26/01/2020 */ +public class FlipBinaryTree { + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public static void main(String[] args) { + // + } + + private int i, count; + private List result; + + public List flipMatchVoyage(TreeNode root, int[] voyage) { + i = 0; + count = 0; + result = new ArrayList<>(); + inorderCount(root); + if (count != voyage.length) return Arrays.asList(-1); + preorder(root, voyage); + if (i == voyage.length) return result; + return Arrays.asList(-1); + } + + private void inorderCount(TreeNode node) { + if (node != null) { + count++; + inorderCount(node.left); + inorderCount(node.right); + } + } + + private void preorder(TreeNode node, int[] voyage) { + if (node != null) { + if (voyage[i] == node.val) { + i++; + } + if (node.left != null && node.right != null) { + if (voyage[i] == node.right.val) { + TreeNode temp = node.left; + node.left = node.right; + node.right = temp; + result.add(node.val); + } + } + preorder(node.left, voyage); + preorder(node.right, voyage); + } + } +} diff --git a/problems/src/tree/InsufficientNodesinRoottoLeafPaths.java b/problems/src/tree/InsufficientNodesinRoottoLeafPaths.java new file mode 100644 index 00000000..5660ac3e --- /dev/null +++ b/problems/src/tree/InsufficientNodesinRoottoLeafPaths.java @@ -0,0 +1,56 @@ +package tree; + +/** Created by gouthamvidyapradhan on 29/01/2020 */ +public class InsufficientNodesinRoottoLeafPaths { + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public static void main(String[] args) { + TreeNode root = new TreeNode(1); + root.left = new TreeNode(2); + root.left.left = new TreeNode(-5); + root.right = new TreeNode(-3); + root.right.left = new TreeNode(4); + System.out.println(new InsufficientNodesinRoottoLeafPaths().sufficientSubset(root, -1)); + } + + public TreeNode sufficientSubset(TreeNode root, int limit) { + long result = dfs(root, 0, limit); + if (result < limit) return null; + else return root; + } + + private long dfs(TreeNode node, long curr, int limit) { + if (node == null) return Integer.MIN_VALUE; + long sumLeft = dfs(node.left, curr + node.val, limit); + long sumRight = dfs(node.right, curr + node.val, limit); + if (sumLeft == Integer.MIN_VALUE && sumRight == Integer.MIN_VALUE) { + return node.val; + } else if (sumLeft == Integer.MIN_VALUE) { + if ((sumRight + curr + node.val) < limit) { + node.right = null; + } + return node.val + sumRight; + } else if (sumRight == Integer.MIN_VALUE) { + if ((sumLeft + curr + node.val) < limit) { + node.left = null; + } + return node.val + sumLeft; + } else { + if ((sumLeft + curr + node.val) < limit) { + node.left = null; + } + if ((sumRight + curr + node.val) < limit) { + node.right = null; + } + return Math.max(node.val + sumLeft, node.val + sumRight); + } + } +} From 94b9e8b4275298cdacff81efb69139cfe4031fd3 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Tue, 12 May 2020 21:05:08 +0200 Subject: [PATCH 223/235] Solved Problems --- README.md | 1 + .../PalindromeRemoval.java | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 problems/src/dynamic_programming/PalindromeRemoval.java diff --git a/README.md b/README.md index f9a2df47..371753e0 100644 --- a/README.md +++ b/README.md @@ -265,6 +265,7 @@ My accepted leetcode solutions to some of the common interview problems. - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Ways to Stay in the Same Place After Some Steps](problems/src/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java) (Hard) - [Toss Strange Coins](problems/src/dynamic_programming/TossStrangeCoins.java) (Medium) - [Knight Dialer](problems/src/dynamic_programming/KnightDialer.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Palindrome Removal](problems/src/dynamic_programming/PalindromeRemoval.java) (Hard) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/PalindromeRemoval.java b/problems/src/dynamic_programming/PalindromeRemoval.java new file mode 100644 index 00000000..bc41f25e --- /dev/null +++ b/problems/src/dynamic_programming/PalindromeRemoval.java @@ -0,0 +1,49 @@ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 12/05/2020 Given an integer array arr, in one move you can + * select a palindromic subarray arr[i], arr[i+1], ..., arr[j] where i <= j, and remove that + * subarray from the given array. Note that after removing a subarray, the elements on the left and + * on the right of that subarray move to fill the gap left by the removal. + * + *

Return the minimum number of moves needed to remove all numbers from the array. + * + *

Example 1: + * + *

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

Input: arr = [1,3,4,1,5] Output: 3 Explanation: Remove [4] then remove [1,3,1] then remove + * [5]. + * + *

Constraints: + * + *

1 <= arr.length <= 100 1 <= arr[i] <= 20 + */ +public class PalindromeRemoval { + public static void main(String[] args) { + int[] A = {1, 3, 1, 2, 4, 2}; + System.out.println(new PalindromeRemoval().minimumMoves(A)); + } + + int[][] DP; + + public int minimumMoves(int[] arr) { + DP = new int[arr.length][arr.length]; + return dp(0, arr.length - 1, arr); + } + + private int dp(int i, int j, int[] arr) { + if (i > j) return 1; + else if (DP[i][j] != 0) return DP[i][j]; + else { + int min = Integer.MAX_VALUE; + for (int t = j; t >= i; t--) { + if (arr[i] == arr[t]) { + min = Math.min(min, dp(i + 1, t - 1, arr) + ((t + 1 > j) ? 0 : dp(t + 1, j, arr))); + } + } + DP[i][j] = min; + return min; + } + } +} From a06b103a8905971f7fda82fdf0656718f0e2708e Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 6 Feb 2021 12:25:24 +0100 Subject: [PATCH 224/235] Some new solved problems --- .gitignore | 2 +- .idea/gradle.xml | 1 + ...rorprone_error_prone_annotations_2_2_0.xml | 11 -- ..._errorprone_javac_shaded_9_181_r4173_1.xml | 11 -- ...ooglejavaformat_google_java_format_1_7.xml | 12 -- ...dle__com_google_guava_guava_27_0_1_jre.xml | 11 -- ...m_google_j2objc_j2objc_annotations_1_1.xml | 11 -- ...rg_checkerframework_checker_qual_2_5_2.xml | 11 -- ...s_mojo_animal_sniffer_annotations_1_17.xml | 11 -- .idea/modules/leetcode_main.iml | 4 +- .idea/modules/leetcode_test.iml | 4 +- README.md | 12 ++ .../dynamic_programming/CherryPickupII.java | 89 +++++++++++++ .../ConstrainedSubsequenceSum.java | 52 ++++++++ .../LargestMultipleOfThree.java | 80 ++++++++++++ .../MaximumProfitInJobScheduling.java | 80 ++++++++++++ .../NumberOfMusicPlaylists.java | 35 +++++ .../dynamic_programming/PaintHouseIII.java | 104 +++++++++++++++ .../dynamic_programming/RestoreTheArray.java | 71 ++++++++++ .../ShortestPathVisitingAllNodes.java | 104 +++++++++++++++ .../SmallestSufficientTeam.java | 122 ++++++++++++++++++ .../src/dynamic_programming/StoneGameIV.java | 88 +++++++++++++ .../dynamic_programming/TallestBillboard.java | 91 +++++++++++++ problems/src/greedy/ReducingDishes.java | 54 ++++++++ 24 files changed, 988 insertions(+), 83 deletions(-) delete mode 100644 .idea/libraries/Gradle__com_google_errorprone_error_prone_annotations_2_2_0.xml delete mode 100644 .idea/libraries/Gradle__com_google_errorprone_javac_shaded_9_181_r4173_1.xml delete mode 100644 .idea/libraries/Gradle__com_google_googlejavaformat_google_java_format_1_7.xml delete mode 100644 .idea/libraries/Gradle__com_google_guava_guava_27_0_1_jre.xml delete mode 100644 .idea/libraries/Gradle__com_google_j2objc_j2objc_annotations_1_1.xml delete mode 100644 .idea/libraries/Gradle__org_checkerframework_checker_qual_2_5_2.xml delete mode 100644 .idea/libraries/Gradle__org_codehaus_mojo_animal_sniffer_annotations_1_17.xml create mode 100644 problems/src/dynamic_programming/CherryPickupII.java create mode 100644 problems/src/dynamic_programming/ConstrainedSubsequenceSum.java create mode 100644 problems/src/dynamic_programming/LargestMultipleOfThree.java create mode 100644 problems/src/dynamic_programming/MaximumProfitInJobScheduling.java create mode 100644 problems/src/dynamic_programming/NumberOfMusicPlaylists.java create mode 100644 problems/src/dynamic_programming/PaintHouseIII.java create mode 100644 problems/src/dynamic_programming/RestoreTheArray.java create mode 100644 problems/src/dynamic_programming/ShortestPathVisitingAllNodes.java create mode 100644 problems/src/dynamic_programming/SmallestSufficientTeam.java create mode 100644 problems/src/dynamic_programming/StoneGameIV.java create mode 100644 problems/src/dynamic_programming/TallestBillboard.java create mode 100644 problems/src/greedy/ReducingDishes.java diff --git a/.gitignore b/.gitignore index 076f3db0..9914da4d 100644 --- a/.gitignore +++ b/.gitignore @@ -13,5 +13,5 @@ leetcode.ipr leetcode.iws out/ problems/src.iml -.idea/* +.idea .gradle/ diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 0ca37c94..5422ecef 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,5 +1,6 @@ +

You have two robots that can collect cherries for you, Robot #1 is located at the top-left + * corner (0,0) , and Robot #2 is located at the top-right corner (0, cols-1) of the grid. + * + *

Return the maximum number of cherries collection using both robots by following the rules + * below: + * + *

From a cell (i,j), robots can move to cell (i+1, j-1) , (i+1, j) or (i+1, j+1). When any robot + * is passing through a cell, It picks it up all cherries, and the cell becomes an empty cell (0). + * When both robots stay on the same cell, only one of them takes the cherries. Both robots cannot + * move outside of the grid at any moment. Both robots should reach the bottom row in the grid. + * + *

Example 1: + * + *

Input: grid = [[3,1,1],[2,5,1],[1,5,5],[2,1,1]] Output: 24 Explanation: Path of robot #1 and + * #2 are described in color green and blue respectively. Cherries taken by Robot #1, (3 + 2 + 5 + + * 2) = 12. Cherries taken by Robot #2, (1 + 5 + 5 + 1) = 12. Total of cherries: 12 + 12 = 24. + * Example 2: + * + *

Input: grid = + * [[1,0,0,0,0,0,1],[2,0,0,0,0,3,0],[2,0,9,0,0,0,0],[0,3,0,5,4,0,0],[1,0,2,3,0,0,6]] Output: 28 + * Explanation: Path of robot #1 and #2 are described in color green and blue respectively. Cherries + * taken by Robot #1, (1 + 9 + 5 + 2) = 17. Cherries taken by Robot #2, (1 + 3 + 4 + 3) = 11. Total + * of cherries: 17 + 11 = 28. Example 3: + * + *

Input: grid = [[1,0,0,3],[0,0,0,3],[0,0,3,3],[9,0,3,3]] Output: 22 Example 4: + * + *

Input: grid = [[1,1],[1,1]] Output: 4 + * + *

Constraints: + * + *

rows == grid.length cols == grid[i].length 2 <= rows, cols <= 70 0 <= grid[i][j] <= 100 + */ +public class CherryPickupII { + private final int[] R = {1, 1, 1}; + private final int[] C = {0, -1, 1}; + + public static void main(String[] args) { + int[][] A = { + {1, 0, 0, 3}, + {2, 0, 0, 0, 0, 3, 0}, + {2, 0, 9, 0, 0, 0, 0}, + {0, 3, 0, 5, 4, 0, 0}, + {1, 0, 2, 3, 0, 0, 6} + }; + System.out.println(new CherryPickupII().cherryPickup(A)); + } + + int[][][] DP; + + public int cherryPickup(int[][] grid) { + DP = new int[grid.length][grid[0].length][grid[0].length]; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + Arrays.fill(DP[i][j], -1); + } + } + return dp(0, 0, grid[0].length - 1, grid); + } + + private int dp(int r, int c1, int c2, int[][] grid) { + if (DP[r][c1][c2] != -1) return DP[r][c1][c2]; + else { + int count = (c1 == c2) ? grid[r][c1] : (grid[r][c1] + grid[r][c2]); + int max = count; + for (int i = 0; i < 3; i++) { + int newR = r + R[i]; + int newC1 = c1 + C[i]; + if (newR >= 0 && newR < grid.length && newC1 >= 0 && newC1 < grid[0].length) { + for (int j = 0; j < 3; j++) { + int newC2 = c2 + C[j]; + if (newC2 >= 0 && newC2 < grid[0].length) { + max = Math.max(max, count + dp(newR, newC1, newC2, grid)); + } + } + } + } + DP[r][c1][c2] = max; + return max; + } + } +} diff --git a/problems/src/dynamic_programming/ConstrainedSubsequenceSum.java b/problems/src/dynamic_programming/ConstrainedSubsequenceSum.java new file mode 100644 index 00000000..b57de7b3 --- /dev/null +++ b/problems/src/dynamic_programming/ConstrainedSubsequenceSum.java @@ -0,0 +1,52 @@ +package dynamic_programming; + +import java.util.*; + +/** Created by gouthamvidyapradhan on 14/05/2020 */ +public class ConstrainedSubsequenceSum { + + public static void main(String[] args) { + int[] A = {10, -2, -10, -5, 20}; + System.out.println(new ConstrainedSubsequenceSum().constrainedSubsetSum(A, 2)); + } + + class Node { + int v, i; + + public int getV() { + return v; + } + + public int getI() { + return i; + } + + Node(int v, int i) { + this.v = v; + this.i = i; + } + } + + public int constrainedSubsetSum(int[] nums, int k) { + Queue pQ = + new PriorityQueue<>(Comparator.comparing(Node::getV).thenComparing(Node::getI).reversed()); + int max = Integer.MIN_VALUE; + for (int i = 0; i < nums.length; i++) { + int value = nums[i]; + while (!pQ.isEmpty() && (i - pQ.peek().i > k)) { + pQ.poll(); + } + if (pQ.isEmpty()) { + pQ.offer(new Node(value, i)); + } else { + if (pQ.peek().v + value > value) { + pQ.offer(new Node(pQ.peek().v + value, i)); + } else { + pQ.offer(new Node(value, i)); + } + } + max = Math.max(max, pQ.peek().v); + } + return max; + } +} diff --git a/problems/src/dynamic_programming/LargestMultipleOfThree.java b/problems/src/dynamic_programming/LargestMultipleOfThree.java new file mode 100644 index 00000000..42febb10 --- /dev/null +++ b/problems/src/dynamic_programming/LargestMultipleOfThree.java @@ -0,0 +1,80 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 29/05/2020 Given an integer array of digits, return the largest + * multiple of three that can be formed by concatenating some of the given digits in any order. + * + *

Since the answer may not fit in an integer data type, return the answer as a string. + * + *

If there is no answer return an empty string. + * + *

Example 1: + * + *

Input: digits = [8,1,9] Output: "981" Example 2: + * + *

Input: digits = [8,6,7,1,0] Output: "8760" Example 3: + * + *

Input: digits = [1] Output: "" Example 4: + * + *

Input: digits = [0,0,0,0,0,0] Output: "0" + * + *

Constraints: + * + *

1 <= digits.length <= 10^4 0 <= digits[i] <= 9 The returning answer must not contain + * unnecessary leading zeros. + */ +public class LargestMultipleOfThree { + public static void main(String[] args) { + int[] A = {8, 4, 1, 7}; + System.out.println(new LargestMultipleOfThree().largestMultipleOfThree(A)); + } + + int[][][] DP; + + public String largestMultipleOfThree(int[] digits) { + Arrays.sort(digits); + for (int i = 0, j = digits.length - 1; i < j; i++, j--) { + int t = digits[i]; + digits[i] = digits[j]; + digits[j] = t; + } + DP = new int[digits.length][3][2]; + for (int i = 0; i < digits.length; i++) { + for (int j = 0; j < 3; j++) { + Arrays.fill(DP[i][j], -2); + } + } + dp(0, 0, digits); + StringBuilder sb = new StringBuilder(); + int r = 0; + for (int i = 0; i < digits.length; i++) { + if (DP[i][r][1] >= DP[i][r][0]) { + if (sb.length() != 1 || sb.charAt(0) != '0') { + sb.append(digits[i]); + } + r = (Integer.parseInt(String.valueOf(r + "" + digits[i])) % 3); + } + } + return sb.toString(); + } + + private int dp(int i, int r, int[] A) { + if (i == A.length) { + return r == 0 ? 0 : -1; + } else if (DP[i][r][0] != -2) { + return Math.max(DP[i][r][0], DP[i][r][1]); + } else { + int d = A[i]; + int newR = (Integer.parseInt(String.valueOf(r + "" + d)) % 3); + int result = dp(i + 1, newR, A); + if (result >= 0) { + result = result + 1; + } + DP[i][r][1] = result; + DP[i][r][0] = dp(i + 1, r, A); + return Math.max(DP[i][r][0], DP[i][r][1]); + } + } +} diff --git a/problems/src/dynamic_programming/MaximumProfitInJobScheduling.java b/problems/src/dynamic_programming/MaximumProfitInJobScheduling.java new file mode 100644 index 00000000..fcb2036f --- /dev/null +++ b/problems/src/dynamic_programming/MaximumProfitInJobScheduling.java @@ -0,0 +1,80 @@ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 18/06/2020 We have n jobs, where every job is scheduled to be + * done from startTime[i] to endTime[i], obtaining a profit of profit[i]. + * + *

You're given the startTime, endTime and profit arrays, return the maximum profit you can take + * such that there are no two jobs in the subset with overlapping time range. + * + *

If you choose a job that ends at time X you will be able to start another job that starts at + * time X. + * + *

Example 1: + * + *

Input: startTime = [1,2,3,3], endTime = [3,4,5,6], profit = [50,10,40,70] Output: 120 + * Explanation: The subset chosen is the first and fourth job. Time range [1-3]+[3-6] , we get + * profit of 120 = 50 + 70. Example 2: + * + *

Input: startTime = [1,2,3,4,6], endTime = [3,5,10,6,9], profit = [20,20,100,70,60] Output: 150 + * Explanation: The subset chosen is the first, fourth and fifth job. Profit obtained 150 = 20 + 70 + * + 60. Example 3: + * + *

Input: startTime = [1,1,1], endTime = [2,3,4], profit = [5,6,4] Output: 6 + * + *

Constraints: + * + *

1 <= startTime.length == endTime.length == profit.length <= 5 * 104 1 <= startTime[i] < + * endTime[i] <= 109 1 <= profit[i] <= 104 + */ +public class MaximumProfitInJobScheduling { + private class Pair { + int a, b; + + Pair(int a, int b) { + this.a = a; + this.b = b; + } + } + + public static void main(String[] args) { + int[] st = {4, 2, 4, 8, 2}; + int[] et = {5, 5, 5, 10, 8}; + int[] p = {1, 2, 8, 10, 4}; + System.out.println(new MaximumProfitInJobScheduling().jobScheduling(st, et, p)); + } + + Map DP; + TreeMap> graph; + + public int jobScheduling(int[] startTime, int[] endTime, int[] profit) { + DP = new HashMap<>(); + graph = new TreeMap<>(); + int start = 0; + for (int i = 0; i < startTime.length; i++) { + List children = graph.getOrDefault(startTime[i], new ArrayList<>()); + children.add(new Pair(endTime[i], profit[i])); + graph.putIfAbsent(startTime[i], children); + start = Math.min(start, startTime[i]); + } + return dp(start); + } + + private int dp(int i) { + Integer current = graph.ceilingKey(i); + if (current == null) return 0; + else if (DP.containsKey(current)) return DP.get(current); + else { + List children = graph.get(current); + int profit = 0; + for (Pair c : children) { + profit = Math.max(profit, dp(c.a) + c.b); + } + profit = Math.max(profit, dp(current + 1)); + DP.put(current, profit); + return profit; + } + } +} diff --git a/problems/src/dynamic_programming/NumberOfMusicPlaylists.java b/problems/src/dynamic_programming/NumberOfMusicPlaylists.java new file mode 100644 index 00000000..d10793a3 --- /dev/null +++ b/problems/src/dynamic_programming/NumberOfMusicPlaylists.java @@ -0,0 +1,35 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** Created by gouthamvidyapradhan on 13/06/2020 */ +public class NumberOfMusicPlaylists { + public static void main(String[] args) { + // + } + + int[][] DP; + final int MOD = (int) 1e9 + 7; + + public int numMusicPlaylists(int N, int L, int K) { + DP = new int[L + 1][N + 1]; + for (int i = 0; i <= L; i++) { + Arrays.fill(DP[i], -1); + } + DP[0][0] = 1; + return (int) dp(L, N, K, N); + } + + private long dp(int i, int j, int K, int N) { + if (i < j) return 0; + else if (i < 0 || j < 0) return 0; + else if (DP[i][j] != -1) return DP[i][j]; + else { + long sum = 0L; + sum += ((dp(i - 1, j - 1, K, N) * (N - (j - 1))) % MOD); + sum += (dp(i - 1, j, K, N) * (Math.max(j - K, 0)) % MOD); + DP[i][j] = (int) (sum % MOD); + return DP[i][j]; + } + } +} diff --git a/problems/src/dynamic_programming/PaintHouseIII.java b/problems/src/dynamic_programming/PaintHouseIII.java new file mode 100644 index 00000000..5b94ef90 --- /dev/null +++ b/problems/src/dynamic_programming/PaintHouseIII.java @@ -0,0 +1,104 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 22/10/2020 There is a row of m houses in a small city, each + * house must be painted with one of the n colors (labeled from 1 to n), some houses that has been + * painted last summer should not be painted again. + * + *

A neighborhood is a maximal group of continuous houses that are painted with the same color. + * (For example: houses = [1,2,2,3,3,2,1,1] contains 5 neighborhoods [{1}, {2,2}, {3,3}, {2}, + * {1,1}]). + * + *

Given an array houses, an m * n matrix cost and an integer target where: + * + *

houses[i]: is the color of the house i, 0 if the house is not painted yet. cost[i][j]: is the + * cost of paint the house i with the color j+1. Return the minimum cost of painting all the + * remaining houses in such a way that there are exactly target neighborhoods, if not possible + * return -1. + * + *

Example 1: + * + *

Input: houses = [0,0,0,0,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], m = 5, n = 2, target + * = 3 Output: 9 Explanation: Paint houses of this way [1,2,2,1,1] This array contains target = 3 + * neighborhoods, [{1}, {2,2}, {1,1}]. Cost of paint all houses (1 + 1 + 1 + 1 + 5) = 9. Example 2: + * + *

Input: houses = [0,2,1,2,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], m = 5, n = 2, target + * = 3 Output: 11 Explanation: Some houses are already painted, Paint the houses of this way + * [2,2,1,2,2] This array contains target = 3 neighborhoods, [{2,2}, {1}, {2,2}]. Cost of paint the + * first and last house (10 + 1) = 11. Example 3: + * + *

Input: houses = [0,0,0,0,0], cost = [[1,10],[10,1],[1,10],[10,1],[1,10]], m = 5, n = 2, target + * = 5 Output: 5 Example 4: + * + *

Input: houses = [3,1,2,3], cost = [[1,1,1],[1,1,1],[1,1,1],[1,1,1]], m = 4, n = 3, target = 3 + * Output: -1 Explanation: Houses are already painted with a total of 4 neighborhoods + * [{3},{1},{2},{3}] different of target = 3. + * + *

Constraints: + * + *

m == houses.length == cost.length n == cost[i].length 1 <= m <= 100 1 <= n <= 20 1 <= target + * <= m 0 <= houses[i] <= n 1 <= cost[i][j] <= 10^4 + */ +public class PaintHouseIII { + public static void main(String[] args) { + // int[] h = {0,0}; + // int[][] cost = {{1,2}, {1,2}}; + int[] h = {3, 1, 2, 3}; + int[][] cost = {{1, 10}, {10, 1}, {1, 10}, {10, 1}, {1, 10}}; + int m = 5; + int n = 2; + int target = 5; + System.out.println(new PaintHouseIII().minCost(h, cost, m, n, target)); + } + + int[][][] DP; + + public int minCost(int[] houses, int[][] cost, int m, int n, int target) { + DP = new int[houses.length][target + 1][n + 1]; + for (int i = 0; i < houses.length; i++) { + for (int j = 0; j < target + 1; j++) { + Arrays.fill(DP[i][j], -2); + } + } + int result = dp(0, 0, target, cost, houses); + return result; + } + + private int dp(int i, int c, int t, int[][] cost, int[] houses) { + if (t == 0 && i == houses.length) return 0; + else if (t == -1 || i == houses.length) return -1; + else if (DP[i][t][c] != -2) return DP[i][t][c]; + else { + int min = Integer.MAX_VALUE; + if (houses[i] != 0) { + int result; + if (houses[i] == c) { + result = dp(i + 1, c, t, cost, houses); + } else { + result = dp(i + 1, houses[i], t - 1, cost, houses); + } + if (result != -1) { + if (c != 0) { + min = Math.min(min, result); + } else min = result; + } + } else { + for (int co = 1; co < cost[0].length + 1; co++) { + int result; + if (co != c) { + result = dp(i + 1, co, t - 1, cost, houses); + } else { + result = dp(i + 1, co, t, cost, houses); + } + if (result != -1) { + min = Math.min(min, cost[i][co - 1] + result); + } + } + } + DP[i][t][c] = (min == Integer.MAX_VALUE ? -1 : min); + return DP[i][t][c]; + } + } +} diff --git a/problems/src/dynamic_programming/RestoreTheArray.java b/problems/src/dynamic_programming/RestoreTheArray.java new file mode 100644 index 00000000..8359f298 --- /dev/null +++ b/problems/src/dynamic_programming/RestoreTheArray.java @@ -0,0 +1,71 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 28/05/2020 + * + *

A program was supposed to print an array of integers. The program forgot to print whitespaces + * and the array is printed as a string of digits and all we know is that all integers in the array + * were in the range [1, k] and there are no leading zeros in the array. + * + *

Given the string s and the integer k. There can be multiple ways to restore the array. + * + *

Return the number of possible array that can be printed as a string s using the mentioned + * program. + * + *

The number of ways could be very large so return it modulo 10^9 + 7 + * + *

Example 1: + * + *

Input: s = "1000", k = 10000 Output: 1 Explanation: The only possible array is [1000] Example + * 2: + * + *

Input: s = "1000", k = 10 Output: 0 Explanation: There cannot be an array that was printed + * this way and has all integer >= 1 and <= 10. Example 3: + * + *

Input: s = "1317", k = 2000 Output: 8 Explanation: Possible arrays are + * [1317],[131,7],[13,17],[1,317],[13,1,7],[1,31,7],[1,3,17],[1,3,1,7] Example 4: + * + *

Input: s = "2020", k = 30 Output: 1 Explanation: The only possible array is [20,20]. [2020] is + * invalid because 2020 > 30. [2,020] is ivalid because 020 contains leading zeros. Example 5: + * + *

Input: s = "1234567890", k = 90 Output: 34 + * + *

Constraints: + * + *

1 <= s.length <= 10^5. s consists of only digits and doesn't contain leading zeros. 1 <= k <= + * 10^9. + */ +public class RestoreTheArray { + public static void main(String[] args) { + System.out.println(new RestoreTheArray().numberOfArrays("19284738192", 90)); + } + + int[] DP; + int MOD = (int) 1e9 + 7; + + public int numberOfArrays(String s, int k) { + DP = new int[s.length() + 1]; + Arrays.fill(DP, -1); + return dp(0, s, k); + } + + private int dp(int i, String s, int k) { + if (i == s.length()) return 1; + else if (DP[i] != -1) return DP[i]; + else if (s.charAt(i) == '0') return 0; + else { + long sum = 0L; + String num = ""; + for (int j = i; j < (i + 10) && j < s.length(); j++) { + num = num + s.charAt(j); + if (Long.parseLong(num) <= k) { + sum = ((sum + dp(j + 1, s, k)) % MOD); + } + } + DP[i] = (int) sum; + return DP[i]; + } + } +} diff --git a/problems/src/dynamic_programming/ShortestPathVisitingAllNodes.java b/problems/src/dynamic_programming/ShortestPathVisitingAllNodes.java new file mode 100644 index 00000000..548ed02e --- /dev/null +++ b/problems/src/dynamic_programming/ShortestPathVisitingAllNodes.java @@ -0,0 +1,104 @@ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 16/10/2020 + * + *

An undirected, connected graph of N nodes (labeled 0, 1, 2, ..., N-1) is given as graph. + * + *

graph.length = N, and j != i is in the list graph[i] exactly once, if and only if nodes i and + * j are connected. + * + *

Return the length of the shortest path that visits every node. You may start and stop at any + * node, you may revisit nodes multiple times, and you may reuse edges. + * + *

Example 1: + * + *

Input: [[1,2,3],[0],[0],[0]] Output: 4 Explanation: One possible path is [1,0,2,0,3] Example + * 2: + * + *

Input: [[1],[0,2,4],[1,3,4],[2],[1,2]] Output: 4 Explanation: One possible path is [0,1,4,2,3] + * + *

Note: + * + *

1 <= graph.length <= 12 0 <= graph[i].length < graph.length + */ +public class ShortestPathVisitingAllNodes { + public static void main(String[] args) { + int[][] graph = {{2, 3, 4, 8}, {8}, {0}, {0, 8}, {0, 5, 6}, {4, 7}, {4}, {5}, {0, 3, 1}}; + System.out.println(new ShortestPathVisitingAllNodes().shortestPathLength(graph)); + } + + Stack stack; + Set done; + + class Node { + int v, s; + + Node(int v, int s) { + this.v = v; + this.s = s; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Node)) return false; + Node node = (Node) o; + return v == node.v && s == node.s; + } + + @Override + public int hashCode() { + return Objects.hash(v, s); + } + } + + public int shortestPathLength(int[][] G) { + int dest = (int) Math.pow(2, G.length) - 1; + int[][] DP = new int[G.length][dest + 1]; + done = new HashSet<>(); + stack = new Stack<>(); + for (int i = 0; i < G.length; i++) { + Node n = new Node(i, 1 << i); + if (!done.contains(n)) { + dfs(n, G); + } + } + for (int i = 0; i < G.length; i++) { + Arrays.fill(DP[i], Integer.MAX_VALUE); + } + while (!stack.isEmpty()) { + Node node = stack.pop(); + int[] children = G[node.v]; + int currDist = DP[node.v][node.s] == Integer.MAX_VALUE ? 0 : DP[node.v][node.s]; + for (int c : children) { + if (DP[c][node.s | (1 << c)] < Integer.MAX_VALUE + && ((currDist + 1) < DP[c][node.s | (1 << c)])) { + stack.push(new Node(c, node.s | (1 << c))); + } + DP[c][node.s | (1 << c)] = Math.min(DP[c][node.s | (1 << c)], currDist + 1); + } + } + int min = Integer.MAX_VALUE; + for (int i = 0; i < G.length; i++) { + min = Math.min(min, DP[i][dest]); + } + return min == Integer.MAX_VALUE ? 0 : min; + } + + private void dfs(Node n, int[][] graph) { + done.add(n); + int[] children = graph[n.v]; + if (children != null) { + for (int c : children) { + Node child = new Node(c, (n.s | (1 << c))); + if (!done.contains(child)) { + dfs(child, graph); + } + } + } + stack.push(n); + } +} diff --git a/problems/src/dynamic_programming/SmallestSufficientTeam.java b/problems/src/dynamic_programming/SmallestSufficientTeam.java new file mode 100644 index 00000000..79195e5e --- /dev/null +++ b/problems/src/dynamic_programming/SmallestSufficientTeam.java @@ -0,0 +1,122 @@ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 04/06/2020 In a project, you have a list of required skills + * req_skills, and a list of people. The i-th person people[i] contains a list of skills that person + * has. + * + *

Consider a sufficient team: a set of people such that for every required skill in req_skills, + * there is at least one person in the team who has that skill. We can represent these teams by the + * index of each person: for example, team = [0, 1, 3] represents the people with skills people[0], + * people[1], and people[3]. + * + *

Return any sufficient team of the smallest possible size, represented by the index of each + * person. + * + *

You may return the answer in any order. It is guaranteed an answer exists. + * + *

Example 1: + * + *

Input: req_skills = ["java","nodejs","reactjs"], people = + * [["java"],["nodejs"],["nodejs","reactjs"]] Output: [0,2] Example 2: + * + *

Input: req_skills = ["algorithms","math","java","reactjs","csharp","aws"], people = + * [["algorithms","math","java"],["algorithms","math","reactjs"],["java","csharp","aws"],["reactjs","csharp"],["csharp","math"],["aws","java"]] + * Output: [1,2] + * + *

Constraints: + * + *

1 <= req_skills.length <= 16 1 <= people.length <= 60 1 <= people[i].length, + * req_skills[i].length, people[i][j].length <= 16 Elements of req_skills and people[i] are + * (respectively) distinct. req_skills[i][j], people[i][j][k] are lowercase English letters. Every + * skill in people[i] is a skill in req_skills. It is guaranteed a sufficient team exists. + */ +public class SmallestSufficientTeam { + + public static void main(String[] args) { + String[] req = {"java", "nodejs", "reactjs"}; + List> people = new ArrayList<>(); + people.add(Arrays.asList("java")); + people.add(Arrays.asList("nodejs")); + people.add(Arrays.asList("nodejs", "reactjs")); + int[] R = new SmallestSufficientTeam().smallestSufficientTeam(req, people); + for (int r : R) { + System.out.print(r + " "); + } + System.out.println(); + } + + private int allSkills; + Map peopleSkillSet; + Map skillMap; + final int MAX_SKILLS = 63; + final int CHOOSE_PEOPLE = 64; + + public int[] smallestSufficientTeam(String[] reqSkills, List> people) { + skillMap = new HashMap<>(); + peopleSkillSet = new HashMap<>(); + int i = 0; + for (String s : reqSkills) { + skillMap.put(s, i++); + } + for (i = 0; i < people.size(); i++) { + for (String s : people.get(i)) { + int skillIndex = skillMap.get(s); + int skills = peopleSkillSet.getOrDefault(i, 0); + skills = (skills | (1 << skillIndex)); + peopleSkillSet.put(i, skills); + } + } + int S = ((int) (Math.pow(2, reqSkills.length)) + 1); + int[][] DP = new int[S][people.size()]; + allSkills = (1 << reqSkills.length) - 1; + for (i = 0; i < DP.length; i++) { + for (int j = 0; j < DP[0].length; j++) { + DP[i][j] = -1; + } + } + int n = dp(0, 0, DP); + n &= MAX_SKILLS; + if (n == Integer.MAX_VALUE) return new int[0]; + List answer = new ArrayList<>(); + i = 0; + for (int j = 0; j < people.size(); j++) { + if (((DP[i][j] & MAX_SKILLS) == n) && (DP[i][j] & CHOOSE_PEOPLE) > 0) { + i |= (peopleSkillSet.getOrDefault(j, 0)); + answer.add(j); + n--; + } + if (n == 0) break; + } + int[] result = new int[answer.size()]; + for (int a = 0; a < result.length; a++) { + result[a] = answer.get(a); + } + return result; + } + + private int dp(int i, int skill, int[][] DP) { + if (i >= DP[0].length) { + if (skill >= allSkills) { + return 0; + } else return Integer.MAX_VALUE; + } + if (skill == allSkills) return 0; + else if (DP[skill][i] != -1) return DP[skill][i]; + else { + int withOut = dp(i + 1, skill, DP); + int with = dp(i + 1, (skill | peopleSkillSet.getOrDefault(i, 0)), DP); + with += with != Integer.MAX_VALUE ? 1 : 0; + if (Math.min(with, withOut) == Integer.MAX_VALUE) { + DP[skill][i] = Integer.MAX_VALUE; + } else + DP[skill][i] = + ((with & MAX_SKILLS) < (withOut & MAX_SKILLS)) + ? ((with & MAX_SKILLS) | CHOOSE_PEOPLE) + : (withOut & MAX_SKILLS); + return DP[skill][i]; + } + } +} diff --git a/problems/src/dynamic_programming/StoneGameIV.java b/problems/src/dynamic_programming/StoneGameIV.java new file mode 100644 index 00000000..1d5b8cc4 --- /dev/null +++ b/problems/src/dynamic_programming/StoneGameIV.java @@ -0,0 +1,88 @@ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 03/12/2020 Alice and Bob take turns playing a game, with Alice + * starting first. + * + *

Initially, there are n stones in a pile. On each player's turn, that player makes a move + * consisting of removing any non-zero square number of stones in the pile. + * + *

Also, if a player cannot make a move, he/she loses the game. + * + *

Given a positive integer n. Return True if and only if Alice wins the game otherwise return + * False, assuming both players play optimally. + * + *

Example 1: + * + *

Input: n = 1 Output: true Explanation: Alice can remove 1 stone winning the game because Bob + * doesn't have any moves. Example 2: + * + *

Input: n = 2 Output: false Explanation: Alice can only remove 1 stone, after that Bob removes + * the last one winning the game (2 -> 1 -> 0). Example 3: + * + *

Input: n = 4 Output: true Explanation: n is already a perfect square, Alice can win with one + * move, removing 4 stones (4 -> 0). Example 4: + * + *

Input: n = 7 Output: false Explanation: Alice can't win the game if Bob plays optimally. If + * Alice starts removing 4 stones, Bob will remove 1 stone then Alice should remove only 1 stone and + * finally Bob removes the last one (7 -> 3 -> 2 -> 1 -> 0). If Alice starts removing 1 stone, Bob + * will remove 4 stones then Alice only can remove 1 stone and finally Bob removes the last one (7 + * -> 6 -> 2 -> 1 -> 0). Example 5: + * + *

Input: n = 17 Output: false Explanation: Alice can't win the game if Bob plays optimally. + * + *

Constraints: + * + *

1 <= n <= 10^5 + */ +public class StoneGameIV { + public static void main(String[] args) { + System.out.println(new StoneGameIV().winnerSquareGame(1000)); + } + + public boolean winnerSquareGame(int n) { + Set perfectSquare = new HashSet<>(); + perfectSquare.add(1); + for (int i = 2; (long) (i * i) <= n; i++) { + genSquare(i * i, n, perfectSquare); + } + int[] pq = new int[perfectSquare.size()]; + int i = 0; + for (int s : perfectSquare) { + pq[i++] = s; + } + Arrays.sort(pq); + int[] DP = new int[n + 1]; + int status = dp(n, 0, pq, DP); + return status != 1; + } + + private int dp(int n, int p, int[] perfectSquares, int[] DP) { + if (n == 0) return 1; + else if (DP[n] != 0) return DP[n]; + else { + int result = 1; + for (int sq : perfectSquares) { + if (n < sq) break; + int r = dp(n - sq, ((p + 1) % 2), perfectSquares, DP); + if (r == 1) { + result = 2; + break; + } + } + DP[n] = result; + return result; + } + } + + private void genSquare(int sq, int limit, Set perfectSquare) { + if (!perfectSquare.contains(sq)) { + perfectSquare.add(sq); + if (((long) sq * sq) <= limit) { + genSquare(sq * sq, limit, perfectSquare); + } + } + } +} diff --git a/problems/src/dynamic_programming/TallestBillboard.java b/problems/src/dynamic_programming/TallestBillboard.java new file mode 100644 index 00000000..94ede7d0 --- /dev/null +++ b/problems/src/dynamic_programming/TallestBillboard.java @@ -0,0 +1,91 @@ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 19/05/2020 + * + *

You are installing a billboard and want it to have the largest height. The billboard will have + * two steel supports, one on each side. Each steel support must be an equal height. + * + *

You are given a collection of rods that can be welded together. For example, if you have rods + * of lengths 1, 2, and 3, you can weld them together to make a support of length 6. + * + *

Return the largest possible height of your billboard installation. If you cannot support the + * billboard, return 0. + * + *

Example 1: + * + *

Input: rods = [1,2,3,6] Output: 6 Explanation: We have two disjoint subsets {1,2,3} and {6}, + * which have the same sum = 6. Example 2: + * + *

Input: rods = [1,2,3,4,5,6] Output: 10 Explanation: We have two disjoint subsets {2,3,5} and + * {4,6}, which have the same sum = 10. Example 3: + * + *

Input: rods = [1,2] Output: 0 Explanation: The billboard cannot be supported, so we return 0. + * + *

Constraints: + * + *

1 <= rods.length <= 20 1 <= rods[i] <= 1000 sum(rods[i]) <= 5000 + */ +public class TallestBillboard { + + public static void main(String[] args) { + int[] A = {1, 2, 3, 4, 5, 6}; + System.out.println(new TallestBillboard().tallestBillboard(A)); + } + + public int tallestBillboard(int[] rods) { + if (rods.length == 0) return 0; + Map leftMap = partition(rods, 0, rods.length / 2); + Map rightMap = partition(rods, (rods.length / 2) + 1, rods.length - 1); + int max = 0; + for (int d : leftMap.keySet()) { + if (rightMap.containsKey(d)) { + int m1 = leftMap.get(d); + int m2 = rightMap.get(d); + max = Math.max(max, m1 + (m2 - d)); + max = Math.max(max, m2 + (m1 - d)); + } + } + return max; + } + + private Map partition(int[] rods, int i, int j) { + if (i > j) { + Map map = new HashMap<>(); + map.put(0, 0); + return map; + } else if (i == j) { + Map map = new HashMap<>(); + map.put(rods[i], rods[i]); + map.put(0, 0); + return map; + } else { + int m = (i + (j - i) / 2); + Map left = partition(rods, i, m); + Map right = partition(rods, m + 1, j); + Map newMap = new HashMap<>(); + for (int lDiff : left.keySet()) { + int lMax = left.get(lDiff); + for (int rDiff : right.keySet()) { + int rMax = right.get(rDiff); + int r1, r2, r3, r4; + r1 = lMax; + r2 = lMax - lDiff; + r3 = rMax; + r4 = rMax - rDiff; + update(newMap, Math.abs(((r1 + r3) - (r2 + r4))), r1 + r3, r2 + r4); + update(newMap, Math.abs(((r1 + r4) - (r2 + r3))), r1 + r4, r2 + r3); + } + } + return newMap; + } + } + + private void update(Map map, int diff, int rod1, int rod2) { + if (map.getOrDefault(diff, 0) < Math.max(rod1, rod2)) { + map.put(diff, Math.max(rod1, rod2)); + } + } +} diff --git a/problems/src/greedy/ReducingDishes.java b/problems/src/greedy/ReducingDishes.java new file mode 100644 index 00000000..de9640ca --- /dev/null +++ b/problems/src/greedy/ReducingDishes.java @@ -0,0 +1,54 @@ +package greedy; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 16/06/2020 A chef has collected data on the satisfaction level + * of his n dishes. Chef can cook any dish in 1 unit of time. + * + *

Like-time coefficient of a dish is defined as the time taken to cook that dish including + * previous dishes multiplied by its satisfaction level i.e. time[i]*satisfaction[i] + * + *

Return the maximum sum of Like-time coefficient that the chef can obtain after dishes + * preparation. + * + *

Dishes can be prepared in any order and the chef can discard some dishes to get this maximum + * value. + * + *

Example 1: + * + *

Input: satisfaction = [-1,-8,0,5,-9] Output: 14 Explanation: After Removing the second and + * last dish, the maximum total Like-time coefficient will be equal to (-1*1 + 0*2 + 5*3 = 14). Each + * dish is prepared in one unit of time. Example 2: + * + *

Input: satisfaction = [4,3,2] Output: 20 Explanation: Dishes can be prepared in any order, + * (2*1 + 3*2 + 4*3 = 20) Example 3: + * + *

Input: satisfaction = [-1,-4,-5] Output: 0 Explanation: People don't like the dishes. No dish + * is prepared. Example 4: + * + *

Input: satisfaction = [-2,5,-1,0,3,-3] Output: 35 + * + *

Constraints: + * + *

n == satisfaction.length 1 <= n <= 500 -10^3 <= satisfaction[i] <= 10^3 + */ +public class ReducingDishes { + public static void main(String[] args) { + int[] A = {4, 3, 2}; + System.out.println(new ReducingDishes().maxSatisfaction(A)); + } + + public int maxSatisfaction(int[] satisfaction) { + Queue pq = new PriorityQueue<>(((o1, o2) -> o2 - o1)); + Arrays.stream(satisfaction).forEach(pq::offer); + int max = 0, sum = 0; + while (!pq.isEmpty()) { + if ((max + sum) >= max) { + max += sum; + sum += pq.poll(); + } else break; + } + return max; + } +} From afac3f64abdd025cc2899c7a6698f9b00ebd4e27 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sat, 6 Feb 2021 12:31:13 +0100 Subject: [PATCH 225/235] Remove cached idea files --- .idea/google-java-format.xml | 6 ----- .idea/gradle.xml | 18 --------------- ..._com_google_code_findbugs_jsr305_3_0_2.xml | 11 ---------- ...__com_google_guava_failureaccess_1_0_1.xml | 11 ---------- ...9_0_empty_to_avoid_conflict_with_guava.xml | 9 -------- .idea/modules/leetcode_main.iml | 20 ----------------- .idea/modules/leetcode_test.iml | 22 ------------------- 7 files changed, 97 deletions(-) delete mode 100644 .idea/google-java-format.xml delete mode 100644 .idea/gradle.xml delete mode 100644 .idea/libraries/Gradle__com_google_code_findbugs_jsr305_3_0_2.xml delete mode 100644 .idea/libraries/Gradle__com_google_guava_failureaccess_1_0_1.xml delete mode 100644 .idea/libraries/Gradle__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml delete mode 100644 .idea/modules/leetcode_main.iml delete mode 100644 .idea/modules/leetcode_test.iml diff --git a/.idea/google-java-format.xml b/.idea/google-java-format.xml deleted file mode 100644 index 8b57f452..00000000 --- a/.idea/google-java-format.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 5422ecef..00000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_3_0_2.xml b/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_3_0_2.xml deleted file mode 100644 index 122552e3..00000000 --- a/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_3_0_2.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_guava_failureaccess_1_0_1.xml b/.idea/libraries/Gradle__com_google_guava_failureaccess_1_0_1.xml deleted file mode 100644 index 8ba66b57..00000000 --- a/.idea/libraries/Gradle__com_google_guava_failureaccess_1_0_1.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml b/.idea/libraries/Gradle__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml deleted file mode 100644 index 11f8cce0..00000000 --- a/.idea/libraries/Gradle__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/leetcode_main.iml b/.idea/modules/leetcode_main.iml deleted file mode 100644 index bf1b6e67..00000000 --- a/.idea/modules/leetcode_main.iml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/leetcode_test.iml b/.idea/modules/leetcode_test.iml deleted file mode 100644 index fd3228d0..00000000 --- a/.idea/modules/leetcode_test.iml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 30ab3a3745c613b2071be48ce92d9bc12b58a03f Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 11 Apr 2021 12:20:32 +0200 Subject: [PATCH 226/235] Solved problems --- ...CountDifferentPalindromicSubsequences.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java diff --git a/problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java b/problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java new file mode 100644 index 00000000..75a1e267 --- /dev/null +++ b/problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java @@ -0,0 +1,61 @@ +package dynamic_programming; + +import java.util.Arrays; + +/** Created by gouthamvidyapradhan on 10/04/2021 */ +public class CountDifferentPalindromicSubsequences { + public static void main(String[] args) { + System.out.println( + new CountDifferentPalindromicSubsequences() + .countPalindromicSubsequences( + "abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba")); + } + + private long[][][] DP; + final char[] chars = {'a', 'b', 'c', 'd'}; + final int MOD = (int) 1e9 + 7; + + public int countPalindromicSubsequences(String S) { + DP = new long[S.length()][S.length()][4]; + for (int i = 0; i < S.length(); i++) { + for (int j = 0; j < S.length(); j++) { + Arrays.fill(DP[i][j], -1); + } + } + long result = 0L; + for (char c : chars) { + long r = dp(0, S.length() - 1, S, c); + result = ((result + r) % MOD); + } + return (int) result; + } + + private long dp(int i, int j, String s, char c) { + if (i > j) return 0; + else if (DP[i][j][c - 'a'] != -1) return DP[i][j][c - 'a']; + else if (s.charAt(i) == s.charAt(j) && s.charAt(i) == c) { + if (i == j) return 1; + else { + long sum = 0L; + for (char aChar : chars) { + long r = dp(i + 1, j - 1, s, aChar); + if (aChar == c) { + r = ((r + 2) % MOD); + } + sum = ((sum + r) % MOD); + } + DP[i][j][c - 'a'] = sum; + return DP[i][j][c - 'a']; + } + } else if (s.charAt(i) == c) { + DP[i][j][c - 'a'] = dp(i, j - 1, s, c); + return DP[i][j][c - 'a']; + } else if (s.charAt(j) == c) { + DP[i][j][c - 'a'] = dp(i + 1, j, s, c); + return DP[i][j][c - 'a']; + } else { + DP[i][j][c - 'a'] = dp(i + 1, j - 1, s, c); + return DP[i][j][c - 'a']; + } + } +} From cfd01e62c9434252cac3216e82059796f0083d38 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Sun, 11 Apr 2021 12:28:24 +0200 Subject: [PATCH 227/235] Solved problems --- README.md | 1 + ...CountDifferentPalindromicSubsequences.java | 24 ++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7d5753fc..f8c99d99 100644 --- a/README.md +++ b/README.md @@ -277,6 +277,7 @@ My accepted leetcode solutions to some of the common interview problems. - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Sufficient Team](problems/src/dynamic_programming/SmallestSufficientTeam.java) (Hard) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Stone Game IV](problems/src/dynamic_programming/StoneGameIV.java) (Hard) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Tallest Billboard](problems/src/dynamic_programming/TallestBillboard.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Count Different Palindromic Subsequences](problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java) (Hard) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java b/problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java index 75a1e267..d5ac0357 100644 --- a/problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java +++ b/problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java @@ -2,7 +2,29 @@ import java.util.Arrays; -/** Created by gouthamvidyapradhan on 10/04/2021 */ +/** + * Created by gouthamvidyapradhan on 10/04/2021 Given a string S, find the number of different + * non-empty palindromic subsequences in S, and return that number modulo 10^9 + 7. + * + *

A subsequence of a string S is obtained by deleting 0 or more characters from S. + * + *

A sequence is palindromic if it is equal to the sequence reversed. + * + *

Two sequences A_1, A_2, ... and B_1, B_2, ... are different if there is some i for which A_i + * != B_i. + * + *

Example 1: Input: S = 'bccb' Output: 6 Explanation: The 6 different non-empty palindromic + * subsequences are 'b', 'c', 'bb', 'cc', 'bcb', 'bccb'. Note that 'bcb' is counted only once, even + * though it occurs twice. Example 2: Input: S = + * 'abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba' Output: 104860361 Explanation: + * There are 3104860382 different non-empty palindromic subsequences, which is 104860361 modulo 10^9 + * + 7. Note: + * + *

The length of S will be in the range [1, 1000]. Each character S[i] will be in the set {'a', + * 'b', 'c', 'd'}. + * + * Solution: O(N ^ 2) x 4 + */ public class CountDifferentPalindromicSubsequences { public static void main(String[] args) { System.out.println( From 7c6c36565643868039e652c8f970ece93eae7fb3 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Wed, 14 Apr 2021 08:18:21 +0200 Subject: [PATCH 228/235] Solved Problems --- README.md | 1 + ...CountDifferentPalindromicSubsequences.java | 2 +- .../NumberOfPathsWithMaxScore.java | 83 +++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 problems/src/dynamic_programming/NumberOfPathsWithMaxScore.java diff --git a/README.md b/README.md index f8c99d99..df2c05dd 100644 --- a/README.md +++ b/README.md @@ -278,6 +278,7 @@ My accepted leetcode solutions to some of the common interview problems. - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Stone Game IV](problems/src/dynamic_programming/StoneGameIV.java) (Hard) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Tallest Billboard](problems/src/dynamic_programming/TallestBillboard.java) (Hard) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Count Different Palindromic Subsequences](problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Paths with Max Score](problems/src/dynamic_programming/NumberOfPathsWithMaxScore.java) (Hard) #### [Greedy](problems/src/greedy) diff --git a/problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java b/problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java index d5ac0357..7395dcb9 100644 --- a/problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java +++ b/problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java @@ -23,7 +23,7 @@ *

The length of S will be in the range [1, 1000]. Each character S[i] will be in the set {'a', * 'b', 'c', 'd'}. * - * Solution: O(N ^ 2) x 4 + *

Solution: O(N ^ 2) x 4 */ public class CountDifferentPalindromicSubsequences { public static void main(String[] args) { diff --git a/problems/src/dynamic_programming/NumberOfPathsWithMaxScore.java b/problems/src/dynamic_programming/NumberOfPathsWithMaxScore.java new file mode 100644 index 00000000..22f148a3 --- /dev/null +++ b/problems/src/dynamic_programming/NumberOfPathsWithMaxScore.java @@ -0,0 +1,83 @@ +package dynamic_programming; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * Created by gouthamvidyapradhan on 13/04/2021 You are given a square board of characters. You can + * move on the board starting at the bottom right square marked with the character 'S'. + * + *

You need to reach the top left square marked with the character 'E'. The rest of the squares + * are labeled either with a numeric character 1, 2, ..., 9 or with an obstacle 'X'. In one move you + * can go up, left or up-left (diagonally) only if there is no obstacle there. + * + *

Return a list of two integers: the first integer is the maximum sum of numeric characters you + * can collect, and the second is the number of such paths that you can take to get that maximum + * sum, taken modulo 10^9 + 7. + * + *

In case there is no path, return [0, 0]. + * + *

Example 1: + * + *

Input: board = ["E23","2X2","12S"] Output: [7,1] Example 2: + * + *

Input: board = ["E12","1X1","21S"] Output: [4,2] Example 3: + * + *

Input: board = ["E11","XXX","11S"] Output: [0,0] + * + *

Constraints: + * + *

2 <= board.length == board[i].length <= 100 Solution: O(N x N) where N is the length of board. + */ +public class NumberOfPathsWithMaxScore { + public static void main(String[] args) { + String[] board = {"E11", "XXX", "11S"}; + List input = Arrays.stream(board).collect(Collectors.toList()); + int[] r = new NumberOfPathsWithMaxScore().pathsWithMaxScore(input); + System.out.println(r[0] + " " + r[1]); + } + + long[][] M, N; + final int[] R = {0, 1, 1}; + final int[] C = {1, 1, 0}; + int MOD = (int) 1e9 + 7; + + public int[] pathsWithMaxScore(List board) { + M = new long[board.size()][board.get(0).length()]; + N = new long[board.size()][board.get(0).length()]; + N[board.size() - 1][board.get(0).length() - 1] = 1; + for (int i = board.size() - 1; i >= 0; i--) { + for (int j = board.get(i).length() - 1; j >= 0; j--) { + char curr = board.get(i).charAt(j); + if (curr != 'X') { + int currInt = 0; + if (curr != 'S' && curr != 'E') { + currInt = Integer.parseInt(String.valueOf(curr)); + } + long currMax = -1; + for (int k = 0; k < 3; k++) { + int newR = i + R[k]; + int newC = j + C[k]; + if (newR < board.size() + && newC < board.get(0).length() + && board.get(newR).charAt(newC) != 'X' + && N[newR][newC] != 0) { + M[i][j] = Math.max(M[i][j], ((currInt + M[newR][newC]) % MOD)); + long newMax = ((currInt + M[newR][newC]) % MOD); + if (newMax > currMax) { + currMax = newMax; + N[i][j] = N[newR][newC]; + } else if (newMax == currMax) { + N[i][j] = ((N[newR][newC] + N[i][j]) % MOD); + } + } + } + } + } + } + int[] res = new int[2]; + res[0] = (int) M[0][0]; + res[1] = (int) N[0][0]; + return res; + } +} From d5a2d45a20890cb11608cb5cb5e854ded5e2542b Mon Sep 17 00:00:00 2001 From: Goutham Vidya Pradhan Date: Thu, 11 Nov 2021 07:05:49 +0100 Subject: [PATCH 229/235] Update to google java format --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2a27034e..397f2517 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } dependencies { - compile 'com.google.googlejavaformat:google-java-format:1.7' + implementation 'com.google.googlejavaformat:google-java-format:1.12.0' } repositories { From 2f69b2f03397301012e74e106b0e93941f3ff925 Mon Sep 17 00:00:00 2001 From: Goutham Vidya Pradhan Date: Thu, 11 Nov 2021 07:47:50 +0100 Subject: [PATCH 230/235] Rename and fix directory structure to standard gradle project --- .gitignore | 1 + README.md | 1008 ++++++++--------- build.gradle | 2 +- .../java}/array/AddToArrayFormOfInteger.java | 0 .../main/java}/array/ArrayNesting.java | 0 .../main/java}/array/ArrayPartitionI.java | 0 .../main/java}/array/BattleshipsInABoard.java | 0 .../main/java}/array/BestMeetingPoint.java | 0 .../main/java}/array/CanPlaceFlowers.java | 0 .../main/java}/array/CardFilipGame.java | 0 .../main/java}/array/ChampagneTower.java | 0 .../main/java}/array/EmployeeFreeTime.java | 0 .../main/java}/array/FindPivotIndex.java | 0 .../main/java}/array/FindTheCelebrity.java | 0 .../java}/array/FirstMissingPositive.java | 0 .../main/java}/array/FruitIntoBaskets.java | 0 .../src => src/main/java}/array/HIndex.java | 0 .../main/java}/array/ImageSmoother.java | 0 .../array/IncreasingTripletSubsequence.java | 0 .../main/java}/array/InsertInterval.java | 0 .../main/java}/array/KEmptySlots.java | 0 .../array/LargestNumberAtLeastTwice.java | 0 .../array/LargestTimeForGivenDigits.java | 0 .../array/LongestIncreasingSubsequence.java | 0 .../LongestLineofConsecutiveOneinMatrix.java | 0 .../array/MatrixCellsinDistanceOrder.java | 0 .../main/java}/array/MaxConsecutiveOnes.java | 0 .../java}/array/MaxConsecutiveOnesII.java | 0 .../java}/array/MaxProductOfThreeNumbers.java | 0 ...aximumSumofTwoNonOverlappingSubarrays.java | 0 .../main/java}/array/MaximumSwap.java | 0 .../main/java}/array/MeetingRooms.java | 0 .../main/java}/array/MeetingScheduler.java | 0 .../main/java}/array/MergeIntervals.java | 0 .../main/java}/array/MergeSortedArray.java | 0 .../array/MinimumIndexSumOfTwoLists.java | 0 .../java}/array/MinimumMovesToEqualArray.java | 0 .../MinimumSwapsToGroupAll1Together.java | 0 .../java}/array/MinimumTimeDifference.java | 0 .../main/java}/array/MissingNumber.java | 0 .../main/java}/array/MyCalendarThree.java | 0 .../main/java}/array/NextGreaterElementI.java | 0 .../main/java}/array/PascalsTriangle.java | 0 .../main/java}/array/PourWater.java | 0 .../java}/array/ProductOfArrayExceptSelf.java | 0 .../main/java}/array/ReadNCharacters.java | 0 .../main/java}/array/RelativeRanks.java | 0 .../main/java}/array/RelativeSortArray.java | 0 .../array/RevealCardsInIncreasingOrder.java | 0 .../main/java}/array/RotateArray.java | 0 .../main/java}/array/RotateMatrix.java | 0 .../main/java}/array/SetMatrixZeroes.java | 0 .../main/java}/array/SortArrayByParityII.java | 0 .../main/java}/array/SortColors.java | 0 .../array/SparseMatrixMultiplication.java | 0 .../array/SubArraysWithBoundedMaximum.java | 0 .../main/java}/array/SubarraySumEqualsK.java | 0 .../array/SurfaceAreaOfThreeDShapes.java | 0 .../main/java}/array/ThirdMaximumNumber.java | 0 .../src => src/main/java}/array/TwoSum.java | 0 .../src => src/main/java}/array/TwoSumII.java | 0 .../main/java}/array/ValidTicTacToeState.java | 0 .../java}/backtracking/CombinationSum.java | 0 .../java}/backtracking/CombinationSumII.java | 0 .../main/java}/backtracking/Combinations.java | 0 .../backtracking/ExpressionAddOperators.java | 0 .../backtracking/GenerateParentheses.java | 0 .../backtracking/LetterCasePermutation.java | 0 .../java}/backtracking/LetterPhoneNumber.java | 0 .../backtracking/MatchsticksToSquare.java | 0 .../backtracking/PalindromePartitioning.java | 0 .../main/java}/backtracking/Permutations.java | 0 .../java}/backtracking/PermutationsII.java | 0 .../RegularExpressionMatching.java | 0 .../RemoveInvalidParentheses.java | 0 .../main/java}/backtracking/Subsets.java | 0 .../main/java}/backtracking/SubsetsII.java | 0 .../main/java}/backtracking/TargetSum.java | 0 .../java}/backtracking/WildcardMatching.java | 0 .../main/java}/backtracking/WordSearch.java | 0 .../main/java}/backtracking/WordSearchII.java | 0 .../main/java}/backtracking/ZumaGame.java | 0 .../java}/binary_search/ArmstrongNumber.java | 0 .../java}/binary_search/FindPeakElement.java | 0 .../java}/binary_search/FirstBadVersion.java | 0 .../main/java}/binary_search/HIndexII.java | 0 .../binary_search/KokoEatingBananas.java | 0 .../MedianOfTwoSortedArrays.java | 0 .../binary_search/MinSortedRotatedArray.java | 0 .../MinimumWindowSubsequence.java | 0 .../main/java}/binary_search/PowXN.java | 0 .../java}/binary_search/SearchForARange.java | 0 .../binary_search/SearchInsertPosition.java | 0 .../SearchRotatedSortedArray.java | 0 .../SingleElementInASortedArray.java | 0 .../main/java}/binary_search/SqrtX.java | 0 .../binary_search/SwimInRisingWater.java | 0 .../binary_search/TimeBasedKeyValuePair.java | 0 .../BinaryNumberWithAlternatingBits.java | 0 .../java}/bit_manipulation/BinaryWatch.java | 0 .../bit_manipulation/DivideTwoIntegers.java | 0 .../main/java}/bit_manipulation/GrayCode.java | 0 .../bit_manipulation/HammingDistance.java | 0 .../TotalHammingDistance.java | 0 .../BinarayTreeLevelOrderTraversal.java | 0 .../java}/breadth_first_search/BusRoutes.java | 0 .../CutOffTreesForGolfEvent.java | 0 .../java}/breadth_first_search/Matrix.java | 0 .../breadth_first_search/OpenTheLock.java | 0 .../java}/breadth_first_search/RaceCar.java | 0 .../breadth_first_search/RottingOranges.java | 0 .../breadth_first_search/SlidingPuzzle.java | 0 .../breadth_first_search/WallsAndGates.java | 0 .../breadth_first_search/WordLadder.java | 0 .../breadth_first_search/WordLadderII.java | 0 .../depth_first_search/AccountsMerge.java | 0 .../depth_first_search/AlienDictionary.java | 0 .../AllPathsFromSourceToTarget.java | 0 .../AsFarfromLandAsPossible.java | 0 .../BricksFallingWhenHit.java | 0 .../java}/depth_first_search/CloneGraph.java | 0 .../ConnectingCitiesWithMinimumCost.java | 0 .../depth_first_search/CourseSchedule.java | 0 .../depth_first_search/CourseScheduleII.java | 0 .../depth_first_search/CrackingTheSafe.java | 0 .../CriticalConnection.java | 0 .../java}/depth_first_search/FloodFill.java | 0 .../depth_first_search/GraphValidTree.java | 0 .../depth_first_search/IslandPerimeter.java | 0 .../LongestConsecutiveSequence.java | 0 .../depth_first_search/MaxAreaOfIsland.java | 0 .../java}/depth_first_search/Minesweeper.java | 0 .../MinimizeMalwareSpread.java | 0 .../depth_first_search/MovieRecommend.java | 0 .../NumberOfDistinctIslands.java | 0 .../NumberOfDistinctIslandsII.java | 0 .../depth_first_search/NumberOfEnclaves.java | 0 .../depth_first_search/NumberOfIslands.java | 0 .../depth_first_search/ParallelCourses.java | 0 .../depth_first_search/RobotRoomCleaner.java | 0 .../SatisfiabilityOfEquations.java | 0 ...SmallestRectangleEnclosingBlackPixels.java | 0 .../main/java}/design/AutocompleteSystem.java | 0 .../main/java}/design/BSTIterator.java | 0 .../design/CopyListWithRandomPointer.java | 0 .../java}/design/EncodeAndDecodeTinyURL.java | 0 .../src => src/main/java}/design/Excel.java | 0 .../main/java}/design/LFUCache.java | 0 .../main/java}/design/LRUCache.java | 0 .../main/java}/design/NestedIterator.java | 0 .../java}/design/RandomizedCollection.java | 0 .../main/java}/design/RandomizedSet.java | 0 .../SerializeDeserializeBinaryTree.java | 0 .../main/java}/design/TicTacToe.java | 0 .../src => src/main/java}/design/Trie.java | 0 .../src => src/main/java}/design/Twitter.java | 0 .../main/java}/design/WordDictionary.java | 0 .../main/java}/design/WordFilter.java | 0 .../KthLargestElementInAnArray.java | 0 .../divide_and_conquer/MyCalendarII.java | 0 .../divide_and_conquer/ReversePairs.java | 0 .../divide_and_conquer/ReversePairsII.java | 0 .../divide_and_conquer/SearchA2DMatrix.java | 0 .../divide_and_conquer/TwentyFourGame.java | 0 .../BestTimeToBuyAndSellStockIII.java | 0 .../BestTimeToBuyAndSellStocks.java | 0 .../BestTimeToBuyAndSellStocksWithFee.java | 0 .../java}/dynamic_programming/BombEnemy.java | 0 .../dynamic_programming/BurstBalloons.java | 0 .../java}/dynamic_programming/CanIWin.java | 0 .../dynamic_programming/CatAndMouse.java | 0 .../dynamic_programming/CherryPickup.java | 0 .../dynamic_programming/CherryPickupII.java | 0 .../dynamic_programming/ClimbingStairs.java | 0 .../java}/dynamic_programming/CoinChange.java | 0 .../dynamic_programming/CoinChange2.java | 0 .../dynamic_programming/CombinationSumIV.java | 0 .../ConcatenatedWords.java | 0 .../ConstrainedSubsequenceSum.java | 0 .../ContinuousSubarraySum.java | 0 .../dynamic_programming/CornerRectangles.java | 0 ...CountDifferentPalindromicSubsequences.java | 0 .../CountVowelsPermutation.java | 0 .../java}/dynamic_programming/DecodeWays.java | 0 .../dynamic_programming/DecodeWaysII.java | 0 .../DeleteColumnsToMakeSortedIII.java | 0 .../DistinctSubsequences.java | 0 .../DistinctSubsequencesII.java | 0 .../dynamic_programming/DungeonGame.java | 0 .../EncodeStringWithShortestLength.java | 0 .../dynamic_programming/FreedomTrail.java | 0 .../HandshakesThatDontCross.java | 0 .../dynamic_programming/HouseRobber.java | 0 .../dynamic_programming/HouseRobberII.java | 0 .../InterleavingString.java | 0 .../java}/dynamic_programming/JumpGameV.java | 0 .../dynamic_programming/KnightDialer.java | 0 .../KnightProbabilityInChessboard.java | 0 .../LargestMultipleOfThree.java | 0 .../dynamic_programming/LargestPlusSign.java | 0 .../LargestSumOfAverages.java | 0 .../LengthofLongestFibonacciSubsequence.java | 0 ...LongestChunkedPalindromeDecomposition.java | 0 .../LongestIncreasingSubsequence.java | 0 .../LongestPaliandromicSubstring.java | 0 .../LongestPalindromicSubsequence.java | 0 .../MakeArrayStrictlyIncreasing.java | 0 .../dynamic_programming/MaxSum3SubArray.java | 0 .../dynamic_programming/MaximalSquare.java | 0 .../MaximumProductSubarray.java | 0 .../MaximumProfitInJobScheduling.java | 0 .../dynamic_programming/MaximumSubarray.java | 0 .../MaximumVacationDays.java | 0 .../MinCostClimbingStairs.java | 0 .../MinimumCostForTickets.java | 0 .../MinimumCostToMergeStones.java | 0 .../MinimumDifficultyOfAJobSchedule.java | 0 ...mumDistanceToTypeAWordUsingTwoFingers.java | 0 .../MinimumNumberOfRefuelingStops.java | 0 .../MinimumNumberOfTaps.java | 0 ...egativeIntegersWithoutConsecutiveOnes.java | 0 .../NumberOfDiceRollsWithTargetSum.java | 0 .../dynamic_programming/NumberOfLIS.java | 0 .../NumberOfMusicPlaylists.java | 0 .../NumberOfPathsWithMaxScore.java | 0 .../NumberOfWaysToStayInTheSamePlace.java | 0 .../dynamic_programming/OddEvenJump.java | 0 .../dynamic_programming/OnesAndZeroes.java | 0 .../OutOfBoundaryPaths.java | 0 .../dynamic_programming/PaintHouseII.java | 0 .../dynamic_programming/PaintHouseIII.java | 0 .../dynamic_programming/PalindromePairs.java | 0 .../PalindromePartitioningII.java | 0 .../PalindromePartitioningIII.java | 0 .../PalindromeRemoval.java | 0 .../PalindromicSubstrings.java | 0 .../ProfitableSchemes.java | 0 .../dynamic_programming/RemoveBoxes.java | 0 .../dynamic_programming/RestoreTheArray.java | 0 .../RussianDollEnvelopes.java | 0 .../ShortestPathVisitingAllNodes.java | 0 .../SmallestSufficientTeam.java | 0 .../SplitArrayLargestSum.java | 0 .../StickersToSpellWord.java | 0 .../java}/dynamic_programming/StoneGame.java | 0 .../dynamic_programming/StoneGameIII.java | 0 .../dynamic_programming/StoneGameIV.java | 0 .../dynamic_programming/StrangePrinter.java | 0 .../dynamic_programming/TallestBillboard.java | 0 .../dynamic_programming/TilingARectangle.java | 0 .../dynamic_programming/TossStrangeCoins.java | 0 .../dynamic_programming/TwoKeysKeyboard.java | 0 .../UniqueBinarySearchTrees.java | 0 .../UniqueBinarySearchTreesII.java | 0 .../ValidPalindromeIII.java | 0 .../java}/dynamic_programming/WordBreak.java | 0 .../dynamic_programming/WordBreakII.java | 0 .../main/java}/greedy/BoatsToSavePeople.java | 0 .../main/java}/greedy/BrokenCalculator.java | 0 .../main/java}/greedy/BurstBalloons.java | 0 .../main/java}/greedy/CourseScheduleIII.java | 0 .../main/java}/greedy/GasStation.java | 0 .../src => src/main/java}/greedy/IPO.java | 0 .../main/java}/greedy/JumpGame.java | 0 .../main/java}/greedy/JumpGameII.java | 0 .../main/java}/greedy/LemonadeChange.java | 0 .../greedy/MaximumLengthOfPairChain.java | 0 .../greedy/MinimumTimeToBuildBlocks.java | 0 .../java}/greedy/NonOverlappingIntervals.java | 0 .../main/java}/greedy/PartitionLabels.java | 0 .../greedy/QueueReconstructionByHeight.java | 0 .../main/java}/greedy/ReducingDishes.java | 0 .../greedy/ScoreAfterFlippingMatrix.java | 0 .../main/java}/greedy/StringWithout3A3B.java | 0 .../main/java}/greedy/TaskScheduler.java | 0 .../main/java}/greedy/TwoCityScheduling.java | 0 .../main/java}/hashing/Anagrams.java | 0 .../AnalyzeUserWebsiteVisitPattern.java | 0 .../main/java}/hashing/BrickWall.java | 0 .../main/java}/hashing/ContiguousArray.java | 0 .../main/java}/hashing/CustomSortString.java | 0 .../main/java}/hashing/DistributeCandies.java | 0 .../main/java}/hashing/GroupAnagrams.java | 0 .../GroupsOfSpecialEquivalentStrings.java | 0 .../java}/hashing/KdiffPairsInanArray.java | 0 .../java}/hashing/LargestUniqueNumber.java | 0 .../MaximumSizeSubarraySumEqualsk.java | 0 .../main/java}/hashing/NumberOfAtoms.java | 0 .../main/java}/hashing/PartitionLabels.java | 0 .../java}/hashing/ShortEncodingOfWords.java | 0 .../java}/hashing/SortCharByFrequency.java | 0 .../StringTransformsIntoAnotherString.java | 0 .../SubstringConcatenationOfWords.java | 0 .../src => src/main/java}/hashing/TwoSum.java | 0 .../main/java}/hashing/ValidAnagram.java | 0 .../src => src/main/java}/heap/Candy.java | 0 .../main/java}/heap/DistantBarcodes.java | 0 .../src => src/main/java}/heap/FreqStack.java | 0 .../java}/heap/KClosestPointsToOrigin.java | 0 .../main/java}/heap/MeetingRoomsII.java | 0 .../heap/ReachableNodesInSubdividedGraph.java | 0 .../main/java}/heap/SlidingWindowMaximum.java | 0 .../SmallestRotationWithHighestScore.java | 0 .../main/java}/heap/TheSkylineProblem.java | 0 .../main/java}/heap/TopKFrequentWords.java | 0 .../main/java}/linked_list/DeleteNode.java | 0 .../linked_list/IntersectionOfTwoLists.java | 0 .../java}/linked_list/LinkedListCycle.java | 0 .../java}/linked_list/MergeKSortedLists.java | 0 .../java}/linked_list/MergeTwoSortedList.java | 0 .../java}/linked_list/MiddleOfLinkedList.java | 0 .../NextGreaterNodeInLinkedList.java | 0 .../java}/linked_list/PaliandromeList.java | 0 .../java}/linked_list/ReverseLinkedList.java | 0 .../java}/linked_list/ReverseNodesKGroup.java | 0 .../linked_list/SplitLinkedListInParts.java | 0 .../java}/linked_list/SwapNodesInPairs.java | 0 .../src => src/main/java}/math/AddDigits.java | 0 .../main/java}/math/AddTwoNumbers.java | 0 .../src => src/main/java}/math/Base7.java | 0 .../main/java}/math/BulbSwitcherII.java | 0 .../main/java}/math/CountPrimes.java | 0 .../main/java}/math/CouplesHoldingHands.java | 0 .../main/java}/math/DecodedStringAtIndex.java | 0 .../java}/math/ExcelSheetColumnTitle.java | 0 .../java}/math/GlobalAndLocalInversions.java | 0 .../LargestComponentSizebyCommonFactor.java | 0 .../java}/math/MinimumIndexSumOfTwoLists.java | 0 .../src => src/main/java}/math/NthDigit.java | 0 .../main/java}/math/NthMagicalNumber.java | 0 .../java}/math/ProjectionAreaOf3DShapes.java | 0 .../main/java}/math/RangeAdditionII.java | 0 .../main/java}/math/ReachingPoints.java | 0 .../main/java}/math/RectangleOverlap.java | 0 .../main/java}/math/RomanToInteger.java | 0 .../main/java}/math/RotateFunction.java | 0 .../main/java}/math/SmallestRangeI.java | 0 .../main/java}/math/SolveTheEquation.java | 0 .../main/java}/math/SquirrelSimulation.java | 0 .../main/java}/math/SuperWashingMachines.java | 0 .../main/java}/math/WaterAndJugProblem.java | 0 .../reservoir_sampling/RandomPickIndex.java | 0 .../main/java}/stack/BasicCalculator.java | 0 .../main/java}/stack/DecodeString.java | 0 .../java}/stack/DecodedStringAtIndex.java | 0 .../java}/stack/ExclusiveTimeOfFunctions.java | 0 .../stack/LargestRectangleInHistogram.java | 0 .../java}/stack/LongestValidParentheses.java | 0 .../main/java}/stack/MaximalRectangle.java | 0 .../src => src/main/java}/stack/MinStack.java | 0 .../src => src/main/java}/stack/MyQueue.java | 0 .../stack/StudentAttendanceRecordII.java | 0 .../main/java}/stack/ValidParentheses.java | 0 .../main/java}/string/AddBinary.java | 0 .../java}/string/CompareVersionNumbers.java | 0 .../main/java}/string/CountAndSay.java | 0 .../java}/string/ExcelSheetColumnNumber.java | 0 .../string/FindTheClosestPalindrome.java | 0 .../FindWordsThatCanBeFormedbyCharacters.java | 2 +- .../string/FirstUniqueCharacterInAString.java | 0 .../main/java}/string/ImplementStrStr.java | 0 .../main/java}/string/IsomorphicStrings.java | 0 .../main/java}/string/KeyboardRow.java | 0 .../java}/string/LongestCommonPrefix.java | 0 .../main/java}/string/LongestPalindrome.java | 0 .../java}/string/LongestWordInDictonary.java | 0 .../MinimumAddtoMakeParenthesesValid.java | 0 .../string/MonotoneIncreasingDigits.java | 0 .../main/java}/string/MultiplyStrings.java | 0 .../string/NumberOfMatchingSubsequences.java | 0 .../main/java}/string/OneEditDistance.java | 0 .../java}/string/PermutationInString.java | 0 .../main/java}/string/PushDominoes.java | 0 .../ReconstructOriginalDigitsFromEnglish.java | 0 .../string/RepeatedSubstringPattern.java | 0 .../main/java}/string/ReplaceWords.java | 0 .../main/java}/string/ReverseStringII.java | 0 .../main/java}/string/ReverseWordsII.java | 0 .../java}/string/ReverseWordsInAString.java | 0 .../main/java}/string/RotateString.java | 0 .../main/java}/string/ShortestPalindrome.java | 0 .../main/java}/string/SimplifyPath.java | 0 .../string/SplitConcatenatedStrings.java | 0 .../java}/string/StampingTheSequence.java | 0 .../main/java}/string/StringCompression.java | 0 .../main/java}/string/StringToInteger.java | 0 .../string/StudentAttendanceRecordI.java | 0 .../main/java}/string/TextJustification.java | 0 .../main/java}/string/ValidPalindrome.java | 0 .../main/java}/string/ValidPalindromeII.java | 0 .../java}/string/ValidWordAbbreviation.java | 0 .../main/java}/string/ValidWordSquare.java | 0 .../main/java}/string/ValidateIPAddress.java | 0 .../main/java}/string/ZigZagConversion.java | 0 .../tree/AllNodesDistanceKInBinaryTree.java | 0 .../tree/AllPossibleFullBinaryTrees.java | 0 .../tree/AverageOfLevelsInBinaryTree.java | 0 .../java}/tree/BSTtoDoublyLinkedList.java | 0 .../java}/tree/BinarayTreeRightSideView.java | 0 .../tree/BinaryTreeInorderTraversal.java | 0 ...inaryTreeLongestConsecutiveSequenceII.java | 0 .../java}/tree/BinaryTreeMaximumPathSum.java | 0 .../main/java}/tree/BinaryTreePaths.java | 0 .../tree/BinaryTreePostorderTraversal.java | 0 .../main/java}/tree/BinaryTreeTilt.java | 0 .../main/java}/tree/BoundaryOfBinaryTree.java | 0 .../tree/ClosestBinarySearchTreeValue.java | 0 .../java}/tree/ClosestLeafInABinaryTree.java | 0 .../tree/ConstructBinaryTreefromString.java | 0 .../tree/ConstructStringFromBinaryTree.java | 0 .../java}/tree/ConvertBSTToGreaterTree.java | 0 .../java}/tree/ConvertSortedArrayToBST.java | 0 .../main/java}/tree/DiameterOfBinaryTree.java | 0 .../main/java}/tree/EqualTreePartition.java | 0 .../java}/tree/FindBottomLeftTreeValue.java | 0 .../tree/FindLargestValueInEachTreeRow.java | 0 .../main/java}/tree/FlattenBinaryTree.java | 0 .../main/java}/tree/FlipBinaryTree.java | 0 .../java}/tree/FlipEquivalentBinaryTrees.java | 0 .../java}/tree/InorderSuccessorInBST.java | 0 .../InsufficientNodesinRoottoLeafPaths.java | 0 {problems/src => src/main/java}/tree/LCA.java | 0 .../main/java}/tree/LargestBSTSubtree.java | 0 .../main/java}/tree/LeafSimilarTrees.java | 0 .../java}/tree/LowestCommonAncestorBST.java | 0 .../main/java}/tree/MaximumBinaryTree.java | 0 .../tree/MaximumLevelSumofABinaryTree.java | 0 .../java}/tree/MaximumWidthOfBinaryTree.java | 0 .../tree/MinimumAbsoluteDifferenceInBST.java | 0 .../java}/tree/MostFrequentSubtreeSum.java | 0 .../main/java}/tree/NextRightPointer.java | 0 .../main/java}/tree/NextRightPointerII.java | 0 .../main/java}/tree/PathSumIII.java | 0 .../main/java}/tree/PostorderToBT.java | 0 .../main/java}/tree/PreorderToBT.java | 0 .../java}/tree/RecoverBinarySearchTree.java | 0 .../src => src/main/java}/tree/SameTree.java | 0 .../tree/SerializeAndDeserializeNAryTree.java | 0 .../main/java}/tree/SortedArrayToBST.java | 0 .../src => src/main/java}/tree/SplitBST.java | 0 .../main/java}/tree/SubtreeOfAnotherTree.java | 0 .../main/java}/tree/SumofLeftLeaves.java | 0 .../main/java}/tree/SymmetricTree.java | 0 .../src => src/main/java}/tree/TwoSumIV.java | 0 .../java}/tree/ValidBinarySearchTree.java | 0 .../main/java}/tree/ZigZagTraversal.java | 0 .../main/java}/two_pointers/FourSum.java | 0 .../LastSubstringInLexicographicalOrder.java | 0 .../LongestSubstringWitoutRepeats.java | 0 .../two_pointers/MinimumSizeSubarraySum.java | 0 .../two_pointers/MinimumWindowSubstring.java | 0 .../main/java}/two_pointers/MoveZeroes.java | 0 .../NumberOfMatchingSubsequences.java | 0 .../java}/two_pointers/RemoveDuplicates.java | 0 .../two_pointers/RemoveDuplicatesII.java | 0 .../java}/two_pointers/SmallestRange.java | 0 .../SubarrayProductLessThanK.java | 0 .../SubarraysWithKDifferentIntegers.java | 0 .../main/java}/two_pointers/ThreeSum.java | 0 .../java}/two_pointers/ThreeSumClosest.java | 0 .../java}/two_pointers/TrappingRainWater.java | 0 461 files changed, 507 insertions(+), 506 deletions(-) rename {problems/src => src/main/java}/array/AddToArrayFormOfInteger.java (100%) rename {problems/src => src/main/java}/array/ArrayNesting.java (100%) rename {problems/src => src/main/java}/array/ArrayPartitionI.java (100%) rename {problems/src => src/main/java}/array/BattleshipsInABoard.java (100%) rename {problems/src => src/main/java}/array/BestMeetingPoint.java (100%) rename {problems/src => src/main/java}/array/CanPlaceFlowers.java (100%) rename {problems/src => src/main/java}/array/CardFilipGame.java (100%) rename {problems/src => src/main/java}/array/ChampagneTower.java (100%) rename {problems/src => src/main/java}/array/EmployeeFreeTime.java (100%) rename {problems/src => src/main/java}/array/FindPivotIndex.java (100%) rename {problems/src => src/main/java}/array/FindTheCelebrity.java (100%) rename {problems/src => src/main/java}/array/FirstMissingPositive.java (100%) rename {problems/src => src/main/java}/array/FruitIntoBaskets.java (100%) rename {problems/src => src/main/java}/array/HIndex.java (100%) rename {problems/src => src/main/java}/array/ImageSmoother.java (100%) rename {problems/src => src/main/java}/array/IncreasingTripletSubsequence.java (100%) rename {problems/src => src/main/java}/array/InsertInterval.java (100%) rename {problems/src => src/main/java}/array/KEmptySlots.java (100%) rename {problems/src => src/main/java}/array/LargestNumberAtLeastTwice.java (100%) rename {problems/src => src/main/java}/array/LargestTimeForGivenDigits.java (100%) rename {problems/src => src/main/java}/array/LongestIncreasingSubsequence.java (100%) rename {problems/src => src/main/java}/array/LongestLineofConsecutiveOneinMatrix.java (100%) rename {problems/src => src/main/java}/array/MatrixCellsinDistanceOrder.java (100%) rename {problems/src => src/main/java}/array/MaxConsecutiveOnes.java (100%) rename {problems/src => src/main/java}/array/MaxConsecutiveOnesII.java (100%) rename {problems/src => src/main/java}/array/MaxProductOfThreeNumbers.java (100%) rename {problems/src => src/main/java}/array/MaximumSumofTwoNonOverlappingSubarrays.java (100%) rename {problems/src => src/main/java}/array/MaximumSwap.java (100%) rename {problems/src => src/main/java}/array/MeetingRooms.java (100%) rename {problems/src => src/main/java}/array/MeetingScheduler.java (100%) rename {problems/src => src/main/java}/array/MergeIntervals.java (100%) rename {problems/src => src/main/java}/array/MergeSortedArray.java (100%) rename {problems/src => src/main/java}/array/MinimumIndexSumOfTwoLists.java (100%) rename {problems/src => src/main/java}/array/MinimumMovesToEqualArray.java (100%) rename {problems/src => src/main/java}/array/MinimumSwapsToGroupAll1Together.java (100%) rename {problems/src => src/main/java}/array/MinimumTimeDifference.java (100%) rename {problems/src => src/main/java}/array/MissingNumber.java (100%) rename {problems/src => src/main/java}/array/MyCalendarThree.java (100%) rename {problems/src => src/main/java}/array/NextGreaterElementI.java (100%) rename {problems/src => src/main/java}/array/PascalsTriangle.java (100%) rename {problems/src => src/main/java}/array/PourWater.java (100%) rename {problems/src => src/main/java}/array/ProductOfArrayExceptSelf.java (100%) rename {problems/src => src/main/java}/array/ReadNCharacters.java (100%) rename {problems/src => src/main/java}/array/RelativeRanks.java (100%) rename {problems/src => src/main/java}/array/RelativeSortArray.java (100%) rename {problems/src => src/main/java}/array/RevealCardsInIncreasingOrder.java (100%) rename {problems/src => src/main/java}/array/RotateArray.java (100%) rename {problems/src => src/main/java}/array/RotateMatrix.java (100%) rename {problems/src => src/main/java}/array/SetMatrixZeroes.java (100%) rename {problems/src => src/main/java}/array/SortArrayByParityII.java (100%) rename {problems/src => src/main/java}/array/SortColors.java (100%) rename {problems/src => src/main/java}/array/SparseMatrixMultiplication.java (100%) rename {problems/src => src/main/java}/array/SubArraysWithBoundedMaximum.java (100%) rename {problems/src => src/main/java}/array/SubarraySumEqualsK.java (100%) rename {problems/src => src/main/java}/array/SurfaceAreaOfThreeDShapes.java (100%) rename {problems/src => src/main/java}/array/ThirdMaximumNumber.java (100%) rename {problems/src => src/main/java}/array/TwoSum.java (100%) rename {problems/src => src/main/java}/array/TwoSumII.java (100%) rename {problems/src => src/main/java}/array/ValidTicTacToeState.java (100%) rename {problems/src => src/main/java}/backtracking/CombinationSum.java (100%) rename {problems/src => src/main/java}/backtracking/CombinationSumII.java (100%) rename {problems/src => src/main/java}/backtracking/Combinations.java (100%) rename {problems/src => src/main/java}/backtracking/ExpressionAddOperators.java (100%) rename {problems/src => src/main/java}/backtracking/GenerateParentheses.java (100%) rename {problems/src => src/main/java}/backtracking/LetterCasePermutation.java (100%) rename {problems/src => src/main/java}/backtracking/LetterPhoneNumber.java (100%) rename {problems/src => src/main/java}/backtracking/MatchsticksToSquare.java (100%) rename {problems/src => src/main/java}/backtracking/PalindromePartitioning.java (100%) rename {problems/src => src/main/java}/backtracking/Permutations.java (100%) rename {problems/src => src/main/java}/backtracking/PermutationsII.java (100%) rename {problems/src => src/main/java}/backtracking/RegularExpressionMatching.java (100%) rename {problems/src => src/main/java}/backtracking/RemoveInvalidParentheses.java (100%) rename {problems/src => src/main/java}/backtracking/Subsets.java (100%) rename {problems/src => src/main/java}/backtracking/SubsetsII.java (100%) rename {problems/src => src/main/java}/backtracking/TargetSum.java (100%) rename {problems/src => src/main/java}/backtracking/WildcardMatching.java (100%) rename {problems/src => src/main/java}/backtracking/WordSearch.java (100%) rename {problems/src => src/main/java}/backtracking/WordSearchII.java (100%) rename {problems/src => src/main/java}/backtracking/ZumaGame.java (100%) rename {problems/src => src/main/java}/binary_search/ArmstrongNumber.java (100%) rename {problems/src => src/main/java}/binary_search/FindPeakElement.java (100%) rename {problems/src => src/main/java}/binary_search/FirstBadVersion.java (100%) rename {problems/src => src/main/java}/binary_search/HIndexII.java (100%) rename {problems/src => src/main/java}/binary_search/KokoEatingBananas.java (100%) rename {problems/src => src/main/java}/binary_search/MedianOfTwoSortedArrays.java (100%) rename {problems/src => src/main/java}/binary_search/MinSortedRotatedArray.java (100%) rename {problems/src => src/main/java}/binary_search/MinimumWindowSubsequence.java (100%) rename {problems/src => src/main/java}/binary_search/PowXN.java (100%) rename {problems/src => src/main/java}/binary_search/SearchForARange.java (100%) rename {problems/src => src/main/java}/binary_search/SearchInsertPosition.java (100%) rename {problems/src => src/main/java}/binary_search/SearchRotatedSortedArray.java (100%) rename {problems/src => src/main/java}/binary_search/SingleElementInASortedArray.java (100%) rename {problems/src => src/main/java}/binary_search/SqrtX.java (100%) rename {problems/src => src/main/java}/binary_search/SwimInRisingWater.java (100%) rename {problems/src => src/main/java}/binary_search/TimeBasedKeyValuePair.java (100%) rename {problems/src => src/main/java}/bit_manipulation/BinaryNumberWithAlternatingBits.java (100%) rename {problems/src => src/main/java}/bit_manipulation/BinaryWatch.java (100%) rename {problems/src => src/main/java}/bit_manipulation/DivideTwoIntegers.java (100%) rename {problems/src => src/main/java}/bit_manipulation/GrayCode.java (100%) rename {problems/src => src/main/java}/bit_manipulation/HammingDistance.java (100%) rename {problems/src => src/main/java}/bit_manipulation/TotalHammingDistance.java (100%) rename {problems/src => src/main/java}/breadth_first_search/BinarayTreeLevelOrderTraversal.java (100%) rename {problems/src => src/main/java}/breadth_first_search/BusRoutes.java (100%) rename {problems/src => src/main/java}/breadth_first_search/CutOffTreesForGolfEvent.java (100%) rename {problems/src => src/main/java}/breadth_first_search/Matrix.java (100%) rename {problems/src => src/main/java}/breadth_first_search/OpenTheLock.java (100%) rename {problems/src => src/main/java}/breadth_first_search/RaceCar.java (100%) rename {problems/src => src/main/java}/breadth_first_search/RottingOranges.java (100%) rename {problems/src => src/main/java}/breadth_first_search/SlidingPuzzle.java (100%) rename {problems/src => src/main/java}/breadth_first_search/WallsAndGates.java (100%) rename {problems/src => src/main/java}/breadth_first_search/WordLadder.java (100%) rename {problems/src => src/main/java}/breadth_first_search/WordLadderII.java (100%) rename {problems/src => src/main/java}/depth_first_search/AccountsMerge.java (100%) rename {problems/src => src/main/java}/depth_first_search/AlienDictionary.java (100%) rename {problems/src => src/main/java}/depth_first_search/AllPathsFromSourceToTarget.java (100%) rename {problems/src => src/main/java}/depth_first_search/AsFarfromLandAsPossible.java (100%) rename {problems/src => src/main/java}/depth_first_search/BricksFallingWhenHit.java (100%) rename {problems/src => src/main/java}/depth_first_search/CloneGraph.java (100%) rename {problems/src => src/main/java}/depth_first_search/ConnectingCitiesWithMinimumCost.java (100%) rename {problems/src => src/main/java}/depth_first_search/CourseSchedule.java (100%) rename {problems/src => src/main/java}/depth_first_search/CourseScheduleII.java (100%) rename {problems/src => src/main/java}/depth_first_search/CrackingTheSafe.java (100%) rename {problems/src => src/main/java}/depth_first_search/CriticalConnection.java (100%) rename {problems/src => src/main/java}/depth_first_search/FloodFill.java (100%) rename {problems/src => src/main/java}/depth_first_search/GraphValidTree.java (100%) rename {problems/src => src/main/java}/depth_first_search/IslandPerimeter.java (100%) rename {problems/src => src/main/java}/depth_first_search/LongestConsecutiveSequence.java (100%) rename {problems/src => src/main/java}/depth_first_search/MaxAreaOfIsland.java (100%) rename {problems/src => src/main/java}/depth_first_search/Minesweeper.java (100%) rename {problems/src => src/main/java}/depth_first_search/MinimizeMalwareSpread.java (100%) rename {problems/src => src/main/java}/depth_first_search/MovieRecommend.java (100%) rename {problems/src => src/main/java}/depth_first_search/NumberOfDistinctIslands.java (100%) rename {problems/src => src/main/java}/depth_first_search/NumberOfDistinctIslandsII.java (100%) rename {problems/src => src/main/java}/depth_first_search/NumberOfEnclaves.java (100%) rename {problems/src => src/main/java}/depth_first_search/NumberOfIslands.java (100%) rename {problems/src => src/main/java}/depth_first_search/ParallelCourses.java (100%) rename {problems/src => src/main/java}/depth_first_search/RobotRoomCleaner.java (100%) rename {problems/src => src/main/java}/depth_first_search/SatisfiabilityOfEquations.java (100%) rename {problems/src => src/main/java}/depth_first_search/SmallestRectangleEnclosingBlackPixels.java (100%) rename {problems/src => src/main/java}/design/AutocompleteSystem.java (100%) rename {problems/src => src/main/java}/design/BSTIterator.java (100%) rename {problems/src => src/main/java}/design/CopyListWithRandomPointer.java (100%) rename {problems/src => src/main/java}/design/EncodeAndDecodeTinyURL.java (100%) rename {problems/src => src/main/java}/design/Excel.java (100%) rename {problems/src => src/main/java}/design/LFUCache.java (100%) rename {problems/src => src/main/java}/design/LRUCache.java (100%) rename {problems/src => src/main/java}/design/NestedIterator.java (100%) rename {problems/src => src/main/java}/design/RandomizedCollection.java (100%) rename {problems/src => src/main/java}/design/RandomizedSet.java (100%) rename {problems/src => src/main/java}/design/SerializeDeserializeBinaryTree.java (100%) rename {problems/src => src/main/java}/design/TicTacToe.java (100%) rename {problems/src => src/main/java}/design/Trie.java (100%) rename {problems/src => src/main/java}/design/Twitter.java (100%) rename {problems/src => src/main/java}/design/WordDictionary.java (100%) rename {problems/src => src/main/java}/design/WordFilter.java (100%) rename {problems/src => src/main/java}/divide_and_conquer/KthLargestElementInAnArray.java (100%) rename {problems/src => src/main/java}/divide_and_conquer/MyCalendarII.java (100%) rename {problems/src => src/main/java}/divide_and_conquer/ReversePairs.java (100%) rename {problems/src => src/main/java}/divide_and_conquer/ReversePairsII.java (100%) rename {problems/src => src/main/java}/divide_and_conquer/SearchA2DMatrix.java (100%) rename {problems/src => src/main/java}/divide_and_conquer/TwentyFourGame.java (100%) rename {problems/src => src/main/java}/dynamic_programming/BestTimeToBuyAndSellStockIII.java (100%) rename {problems/src => src/main/java}/dynamic_programming/BestTimeToBuyAndSellStocks.java (100%) rename {problems/src => src/main/java}/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java (100%) rename {problems/src => src/main/java}/dynamic_programming/BombEnemy.java (100%) rename {problems/src => src/main/java}/dynamic_programming/BurstBalloons.java (100%) rename {problems/src => src/main/java}/dynamic_programming/CanIWin.java (100%) rename {problems/src => src/main/java}/dynamic_programming/CatAndMouse.java (100%) rename {problems/src => src/main/java}/dynamic_programming/CherryPickup.java (100%) rename {problems/src => src/main/java}/dynamic_programming/CherryPickupII.java (100%) rename {problems/src => src/main/java}/dynamic_programming/ClimbingStairs.java (100%) rename {problems/src => src/main/java}/dynamic_programming/CoinChange.java (100%) rename {problems/src => src/main/java}/dynamic_programming/CoinChange2.java (100%) rename {problems/src => src/main/java}/dynamic_programming/CombinationSumIV.java (100%) rename {problems/src => src/main/java}/dynamic_programming/ConcatenatedWords.java (100%) rename {problems/src => src/main/java}/dynamic_programming/ConstrainedSubsequenceSum.java (100%) rename {problems/src => src/main/java}/dynamic_programming/ContinuousSubarraySum.java (100%) rename {problems/src => src/main/java}/dynamic_programming/CornerRectangles.java (100%) rename {problems/src => src/main/java}/dynamic_programming/CountDifferentPalindromicSubsequences.java (100%) rename {problems/src => src/main/java}/dynamic_programming/CountVowelsPermutation.java (100%) rename {problems/src => src/main/java}/dynamic_programming/DecodeWays.java (100%) rename {problems/src => src/main/java}/dynamic_programming/DecodeWaysII.java (100%) rename {problems/src => src/main/java}/dynamic_programming/DeleteColumnsToMakeSortedIII.java (100%) rename {problems/src => src/main/java}/dynamic_programming/DistinctSubsequences.java (100%) rename {problems/src => src/main/java}/dynamic_programming/DistinctSubsequencesII.java (100%) rename {problems/src => src/main/java}/dynamic_programming/DungeonGame.java (100%) rename {problems/src => src/main/java}/dynamic_programming/EncodeStringWithShortestLength.java (100%) rename {problems/src => src/main/java}/dynamic_programming/FreedomTrail.java (100%) rename {problems/src => src/main/java}/dynamic_programming/HandshakesThatDontCross.java (100%) rename {problems/src => src/main/java}/dynamic_programming/HouseRobber.java (100%) rename {problems/src => src/main/java}/dynamic_programming/HouseRobberII.java (100%) rename {problems/src => src/main/java}/dynamic_programming/InterleavingString.java (100%) rename {problems/src => src/main/java}/dynamic_programming/JumpGameV.java (100%) rename {problems/src => src/main/java}/dynamic_programming/KnightDialer.java (100%) rename {problems/src => src/main/java}/dynamic_programming/KnightProbabilityInChessboard.java (100%) rename {problems/src => src/main/java}/dynamic_programming/LargestMultipleOfThree.java (100%) rename {problems/src => src/main/java}/dynamic_programming/LargestPlusSign.java (100%) rename {problems/src => src/main/java}/dynamic_programming/LargestSumOfAverages.java (100%) rename {problems/src => src/main/java}/dynamic_programming/LengthofLongestFibonacciSubsequence.java (100%) rename {problems/src => src/main/java}/dynamic_programming/LongestChunkedPalindromeDecomposition.java (100%) rename {problems/src => src/main/java}/dynamic_programming/LongestIncreasingSubsequence.java (100%) rename {problems/src => src/main/java}/dynamic_programming/LongestPaliandromicSubstring.java (100%) rename {problems/src => src/main/java}/dynamic_programming/LongestPalindromicSubsequence.java (100%) rename {problems/src => src/main/java}/dynamic_programming/MakeArrayStrictlyIncreasing.java (100%) rename {problems/src => src/main/java}/dynamic_programming/MaxSum3SubArray.java (100%) rename {problems/src => src/main/java}/dynamic_programming/MaximalSquare.java (100%) rename {problems/src => src/main/java}/dynamic_programming/MaximumProductSubarray.java (100%) rename {problems/src => src/main/java}/dynamic_programming/MaximumProfitInJobScheduling.java (100%) rename {problems/src => src/main/java}/dynamic_programming/MaximumSubarray.java (100%) rename {problems/src => src/main/java}/dynamic_programming/MaximumVacationDays.java (100%) rename {problems/src => src/main/java}/dynamic_programming/MinCostClimbingStairs.java (100%) rename {problems/src => src/main/java}/dynamic_programming/MinimumCostForTickets.java (100%) rename {problems/src => src/main/java}/dynamic_programming/MinimumCostToMergeStones.java (100%) rename {problems/src => src/main/java}/dynamic_programming/MinimumDifficultyOfAJobSchedule.java (100%) rename {problems/src => src/main/java}/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java (100%) rename {problems/src => src/main/java}/dynamic_programming/MinimumNumberOfRefuelingStops.java (100%) rename {problems/src => src/main/java}/dynamic_programming/MinimumNumberOfTaps.java (100%) rename {problems/src => src/main/java}/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java (100%) rename {problems/src => src/main/java}/dynamic_programming/NumberOfDiceRollsWithTargetSum.java (100%) rename {problems/src => src/main/java}/dynamic_programming/NumberOfLIS.java (100%) rename {problems/src => src/main/java}/dynamic_programming/NumberOfMusicPlaylists.java (100%) rename {problems/src => src/main/java}/dynamic_programming/NumberOfPathsWithMaxScore.java (100%) rename {problems/src => src/main/java}/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java (100%) rename {problems/src => src/main/java}/dynamic_programming/OddEvenJump.java (100%) rename {problems/src => src/main/java}/dynamic_programming/OnesAndZeroes.java (100%) rename {problems/src => src/main/java}/dynamic_programming/OutOfBoundaryPaths.java (100%) rename {problems/src => src/main/java}/dynamic_programming/PaintHouseII.java (100%) rename {problems/src => src/main/java}/dynamic_programming/PaintHouseIII.java (100%) rename {problems/src => src/main/java}/dynamic_programming/PalindromePairs.java (100%) rename {problems/src => src/main/java}/dynamic_programming/PalindromePartitioningII.java (100%) rename {problems/src => src/main/java}/dynamic_programming/PalindromePartitioningIII.java (100%) rename {problems/src => src/main/java}/dynamic_programming/PalindromeRemoval.java (100%) rename {problems/src => src/main/java}/dynamic_programming/PalindromicSubstrings.java (100%) rename {problems/src => src/main/java}/dynamic_programming/ProfitableSchemes.java (100%) rename {problems/src => src/main/java}/dynamic_programming/RemoveBoxes.java (100%) rename {problems/src => src/main/java}/dynamic_programming/RestoreTheArray.java (100%) rename {problems/src => src/main/java}/dynamic_programming/RussianDollEnvelopes.java (100%) rename {problems/src => src/main/java}/dynamic_programming/ShortestPathVisitingAllNodes.java (100%) rename {problems/src => src/main/java}/dynamic_programming/SmallestSufficientTeam.java (100%) rename {problems/src => src/main/java}/dynamic_programming/SplitArrayLargestSum.java (100%) rename {problems/src => src/main/java}/dynamic_programming/StickersToSpellWord.java (100%) rename {problems/src => src/main/java}/dynamic_programming/StoneGame.java (100%) rename {problems/src => src/main/java}/dynamic_programming/StoneGameIII.java (100%) rename {problems/src => src/main/java}/dynamic_programming/StoneGameIV.java (100%) rename {problems/src => src/main/java}/dynamic_programming/StrangePrinter.java (100%) rename {problems/src => src/main/java}/dynamic_programming/TallestBillboard.java (100%) rename {problems/src => src/main/java}/dynamic_programming/TilingARectangle.java (100%) rename {problems/src => src/main/java}/dynamic_programming/TossStrangeCoins.java (100%) rename {problems/src => src/main/java}/dynamic_programming/TwoKeysKeyboard.java (100%) rename {problems/src => src/main/java}/dynamic_programming/UniqueBinarySearchTrees.java (100%) rename {problems/src => src/main/java}/dynamic_programming/UniqueBinarySearchTreesII.java (100%) rename {problems/src => src/main/java}/dynamic_programming/ValidPalindromeIII.java (100%) rename {problems/src => src/main/java}/dynamic_programming/WordBreak.java (100%) rename {problems/src => src/main/java}/dynamic_programming/WordBreakII.java (100%) rename {problems/src => src/main/java}/greedy/BoatsToSavePeople.java (100%) rename {problems/src => src/main/java}/greedy/BrokenCalculator.java (100%) rename {problems/src => src/main/java}/greedy/BurstBalloons.java (100%) rename {problems/src => src/main/java}/greedy/CourseScheduleIII.java (100%) rename {problems/src => src/main/java}/greedy/GasStation.java (100%) rename {problems/src => src/main/java}/greedy/IPO.java (100%) rename {problems/src => src/main/java}/greedy/JumpGame.java (100%) rename {problems/src => src/main/java}/greedy/JumpGameII.java (100%) rename {problems/src => src/main/java}/greedy/LemonadeChange.java (100%) rename {problems/src => src/main/java}/greedy/MaximumLengthOfPairChain.java (100%) rename {problems/src => src/main/java}/greedy/MinimumTimeToBuildBlocks.java (100%) rename {problems/src => src/main/java}/greedy/NonOverlappingIntervals.java (100%) rename {problems/src => src/main/java}/greedy/PartitionLabels.java (100%) rename {problems/src => src/main/java}/greedy/QueueReconstructionByHeight.java (100%) rename {problems/src => src/main/java}/greedy/ReducingDishes.java (100%) rename {problems/src => src/main/java}/greedy/ScoreAfterFlippingMatrix.java (100%) rename {problems/src => src/main/java}/greedy/StringWithout3A3B.java (100%) rename {problems/src => src/main/java}/greedy/TaskScheduler.java (100%) rename {problems/src => src/main/java}/greedy/TwoCityScheduling.java (100%) rename {problems/src => src/main/java}/hashing/Anagrams.java (100%) rename {problems/src => src/main/java}/hashing/AnalyzeUserWebsiteVisitPattern.java (100%) rename {problems/src => src/main/java}/hashing/BrickWall.java (100%) rename {problems/src => src/main/java}/hashing/ContiguousArray.java (100%) rename {problems/src => src/main/java}/hashing/CustomSortString.java (100%) rename {problems/src => src/main/java}/hashing/DistributeCandies.java (100%) rename {problems/src => src/main/java}/hashing/GroupAnagrams.java (100%) rename {problems/src => src/main/java}/hashing/GroupsOfSpecialEquivalentStrings.java (100%) rename {problems/src => src/main/java}/hashing/KdiffPairsInanArray.java (100%) rename {problems/src => src/main/java}/hashing/LargestUniqueNumber.java (100%) rename {problems/src => src/main/java}/hashing/MaximumSizeSubarraySumEqualsk.java (100%) rename {problems/src => src/main/java}/hashing/NumberOfAtoms.java (100%) rename {problems/src => src/main/java}/hashing/PartitionLabels.java (100%) rename {problems/src => src/main/java}/hashing/ShortEncodingOfWords.java (100%) rename {problems/src => src/main/java}/hashing/SortCharByFrequency.java (100%) rename {problems/src => src/main/java}/hashing/StringTransformsIntoAnotherString.java (100%) rename {problems/src => src/main/java}/hashing/SubstringConcatenationOfWords.java (100%) rename {problems/src => src/main/java}/hashing/TwoSum.java (100%) rename {problems/src => src/main/java}/hashing/ValidAnagram.java (100%) rename {problems/src => src/main/java}/heap/Candy.java (100%) rename {problems/src => src/main/java}/heap/DistantBarcodes.java (100%) rename {problems/src => src/main/java}/heap/FreqStack.java (100%) rename {problems/src => src/main/java}/heap/KClosestPointsToOrigin.java (100%) rename {problems/src => src/main/java}/heap/MeetingRoomsII.java (100%) rename {problems/src => src/main/java}/heap/ReachableNodesInSubdividedGraph.java (100%) rename {problems/src => src/main/java}/heap/SlidingWindowMaximum.java (100%) rename {problems/src => src/main/java}/heap/SmallestRotationWithHighestScore.java (100%) rename {problems/src => src/main/java}/heap/TheSkylineProblem.java (100%) rename {problems/src => src/main/java}/heap/TopKFrequentWords.java (100%) rename {problems/src => src/main/java}/linked_list/DeleteNode.java (100%) rename {problems/src => src/main/java}/linked_list/IntersectionOfTwoLists.java (100%) rename {problems/src => src/main/java}/linked_list/LinkedListCycle.java (100%) rename {problems/src => src/main/java}/linked_list/MergeKSortedLists.java (100%) rename {problems/src => src/main/java}/linked_list/MergeTwoSortedList.java (100%) rename {problems/src => src/main/java}/linked_list/MiddleOfLinkedList.java (100%) rename {problems/src => src/main/java}/linked_list/NextGreaterNodeInLinkedList.java (100%) rename {problems/src => src/main/java}/linked_list/PaliandromeList.java (100%) rename {problems/src => src/main/java}/linked_list/ReverseLinkedList.java (100%) rename {problems/src => src/main/java}/linked_list/ReverseNodesKGroup.java (100%) rename {problems/src => src/main/java}/linked_list/SplitLinkedListInParts.java (100%) rename {problems/src => src/main/java}/linked_list/SwapNodesInPairs.java (100%) rename {problems/src => src/main/java}/math/AddDigits.java (100%) rename {problems/src => src/main/java}/math/AddTwoNumbers.java (100%) rename {problems/src => src/main/java}/math/Base7.java (100%) rename {problems/src => src/main/java}/math/BulbSwitcherII.java (100%) rename {problems/src => src/main/java}/math/CountPrimes.java (100%) rename {problems/src => src/main/java}/math/CouplesHoldingHands.java (100%) rename {problems/src => src/main/java}/math/DecodedStringAtIndex.java (100%) rename {problems/src => src/main/java}/math/ExcelSheetColumnTitle.java (100%) rename {problems/src => src/main/java}/math/GlobalAndLocalInversions.java (100%) rename {problems/src => src/main/java}/math/LargestComponentSizebyCommonFactor.java (100%) rename {problems/src => src/main/java}/math/MinimumIndexSumOfTwoLists.java (100%) rename {problems/src => src/main/java}/math/NthDigit.java (100%) rename {problems/src => src/main/java}/math/NthMagicalNumber.java (100%) rename {problems/src => src/main/java}/math/ProjectionAreaOf3DShapes.java (100%) rename {problems/src => src/main/java}/math/RangeAdditionII.java (100%) rename {problems/src => src/main/java}/math/ReachingPoints.java (100%) rename {problems/src => src/main/java}/math/RectangleOverlap.java (100%) rename {problems/src => src/main/java}/math/RomanToInteger.java (100%) rename {problems/src => src/main/java}/math/RotateFunction.java (100%) rename {problems/src => src/main/java}/math/SmallestRangeI.java (100%) rename {problems/src => src/main/java}/math/SolveTheEquation.java (100%) rename {problems/src => src/main/java}/math/SquirrelSimulation.java (100%) rename {problems/src => src/main/java}/math/SuperWashingMachines.java (100%) rename {problems/src => src/main/java}/math/WaterAndJugProblem.java (100%) rename {problems/src => src/main/java}/reservoir_sampling/RandomPickIndex.java (100%) rename {problems/src => src/main/java}/stack/BasicCalculator.java (100%) rename {problems/src => src/main/java}/stack/DecodeString.java (100%) rename {problems/src => src/main/java}/stack/DecodedStringAtIndex.java (100%) rename {problems/src => src/main/java}/stack/ExclusiveTimeOfFunctions.java (100%) rename {problems/src => src/main/java}/stack/LargestRectangleInHistogram.java (100%) rename {problems/src => src/main/java}/stack/LongestValidParentheses.java (100%) rename {problems/src => src/main/java}/stack/MaximalRectangle.java (100%) rename {problems/src => src/main/java}/stack/MinStack.java (100%) rename {problems/src => src/main/java}/stack/MyQueue.java (100%) rename {problems/src => src/main/java}/stack/StudentAttendanceRecordII.java (100%) rename {problems/src => src/main/java}/stack/ValidParentheses.java (100%) rename {problems/src => src/main/java}/string/AddBinary.java (100%) rename {problems/src => src/main/java}/string/CompareVersionNumbers.java (100%) rename {problems/src => src/main/java}/string/CountAndSay.java (100%) rename {problems/src => src/main/java}/string/ExcelSheetColumnNumber.java (100%) rename {problems/src => src/main/java}/string/FindTheClosestPalindrome.java (100%) rename {problems/src => src/main/java}/string/FindWordsThatCanBeFormedbyCharacters.java (97%) rename {problems/src => src/main/java}/string/FirstUniqueCharacterInAString.java (100%) rename {problems/src => src/main/java}/string/ImplementStrStr.java (100%) rename {problems/src => src/main/java}/string/IsomorphicStrings.java (100%) rename {problems/src => src/main/java}/string/KeyboardRow.java (100%) rename {problems/src => src/main/java}/string/LongestCommonPrefix.java (100%) rename {problems/src => src/main/java}/string/LongestPalindrome.java (100%) rename {problems/src => src/main/java}/string/LongestWordInDictonary.java (100%) rename {problems/src => src/main/java}/string/MinimumAddtoMakeParenthesesValid.java (100%) rename {problems/src => src/main/java}/string/MonotoneIncreasingDigits.java (100%) rename {problems/src => src/main/java}/string/MultiplyStrings.java (100%) rename {problems/src => src/main/java}/string/NumberOfMatchingSubsequences.java (100%) rename {problems/src => src/main/java}/string/OneEditDistance.java (100%) rename {problems/src => src/main/java}/string/PermutationInString.java (100%) rename {problems/src => src/main/java}/string/PushDominoes.java (100%) rename {problems/src => src/main/java}/string/ReconstructOriginalDigitsFromEnglish.java (100%) rename {problems/src => src/main/java}/string/RepeatedSubstringPattern.java (100%) rename {problems/src => src/main/java}/string/ReplaceWords.java (100%) rename {problems/src => src/main/java}/string/ReverseStringII.java (100%) rename {problems/src => src/main/java}/string/ReverseWordsII.java (100%) rename {problems/src => src/main/java}/string/ReverseWordsInAString.java (100%) rename {problems/src => src/main/java}/string/RotateString.java (100%) rename {problems/src => src/main/java}/string/ShortestPalindrome.java (100%) rename {problems/src => src/main/java}/string/SimplifyPath.java (100%) rename {problems/src => src/main/java}/string/SplitConcatenatedStrings.java (100%) rename {problems/src => src/main/java}/string/StampingTheSequence.java (100%) rename {problems/src => src/main/java}/string/StringCompression.java (100%) rename {problems/src => src/main/java}/string/StringToInteger.java (100%) rename {problems/src => src/main/java}/string/StudentAttendanceRecordI.java (100%) rename {problems/src => src/main/java}/string/TextJustification.java (100%) rename {problems/src => src/main/java}/string/ValidPalindrome.java (100%) rename {problems/src => src/main/java}/string/ValidPalindromeII.java (100%) rename {problems/src => src/main/java}/string/ValidWordAbbreviation.java (100%) rename {problems/src => src/main/java}/string/ValidWordSquare.java (100%) rename {problems/src => src/main/java}/string/ValidateIPAddress.java (100%) rename {problems/src => src/main/java}/string/ZigZagConversion.java (100%) rename {problems/src => src/main/java}/tree/AllNodesDistanceKInBinaryTree.java (100%) rename {problems/src => src/main/java}/tree/AllPossibleFullBinaryTrees.java (100%) rename {problems/src => src/main/java}/tree/AverageOfLevelsInBinaryTree.java (100%) rename {problems/src => src/main/java}/tree/BSTtoDoublyLinkedList.java (100%) rename {problems/src => src/main/java}/tree/BinarayTreeRightSideView.java (100%) rename {problems/src => src/main/java}/tree/BinaryTreeInorderTraversal.java (100%) rename {problems/src => src/main/java}/tree/BinaryTreeLongestConsecutiveSequenceII.java (100%) rename {problems/src => src/main/java}/tree/BinaryTreeMaximumPathSum.java (100%) rename {problems/src => src/main/java}/tree/BinaryTreePaths.java (100%) rename {problems/src => src/main/java}/tree/BinaryTreePostorderTraversal.java (100%) rename {problems/src => src/main/java}/tree/BinaryTreeTilt.java (100%) rename {problems/src => src/main/java}/tree/BoundaryOfBinaryTree.java (100%) rename {problems/src => src/main/java}/tree/ClosestBinarySearchTreeValue.java (100%) rename {problems/src => src/main/java}/tree/ClosestLeafInABinaryTree.java (100%) rename {problems/src => src/main/java}/tree/ConstructBinaryTreefromString.java (100%) rename {problems/src => src/main/java}/tree/ConstructStringFromBinaryTree.java (100%) rename {problems/src => src/main/java}/tree/ConvertBSTToGreaterTree.java (100%) rename {problems/src => src/main/java}/tree/ConvertSortedArrayToBST.java (100%) rename {problems/src => src/main/java}/tree/DiameterOfBinaryTree.java (100%) rename {problems/src => src/main/java}/tree/EqualTreePartition.java (100%) rename {problems/src => src/main/java}/tree/FindBottomLeftTreeValue.java (100%) rename {problems/src => src/main/java}/tree/FindLargestValueInEachTreeRow.java (100%) rename {problems/src => src/main/java}/tree/FlattenBinaryTree.java (100%) rename {problems/src => src/main/java}/tree/FlipBinaryTree.java (100%) rename {problems/src => src/main/java}/tree/FlipEquivalentBinaryTrees.java (100%) rename {problems/src => src/main/java}/tree/InorderSuccessorInBST.java (100%) rename {problems/src => src/main/java}/tree/InsufficientNodesinRoottoLeafPaths.java (100%) rename {problems/src => src/main/java}/tree/LCA.java (100%) rename {problems/src => src/main/java}/tree/LargestBSTSubtree.java (100%) rename {problems/src => src/main/java}/tree/LeafSimilarTrees.java (100%) rename {problems/src => src/main/java}/tree/LowestCommonAncestorBST.java (100%) rename {problems/src => src/main/java}/tree/MaximumBinaryTree.java (100%) rename {problems/src => src/main/java}/tree/MaximumLevelSumofABinaryTree.java (100%) rename {problems/src => src/main/java}/tree/MaximumWidthOfBinaryTree.java (100%) rename {problems/src => src/main/java}/tree/MinimumAbsoluteDifferenceInBST.java (100%) rename {problems/src => src/main/java}/tree/MostFrequentSubtreeSum.java (100%) rename {problems/src => src/main/java}/tree/NextRightPointer.java (100%) rename {problems/src => src/main/java}/tree/NextRightPointerII.java (100%) rename {problems/src => src/main/java}/tree/PathSumIII.java (100%) rename {problems/src => src/main/java}/tree/PostorderToBT.java (100%) rename {problems/src => src/main/java}/tree/PreorderToBT.java (100%) rename {problems/src => src/main/java}/tree/RecoverBinarySearchTree.java (100%) rename {problems/src => src/main/java}/tree/SameTree.java (100%) rename {problems/src => src/main/java}/tree/SerializeAndDeserializeNAryTree.java (100%) rename {problems/src => src/main/java}/tree/SortedArrayToBST.java (100%) rename {problems/src => src/main/java}/tree/SplitBST.java (100%) rename {problems/src => src/main/java}/tree/SubtreeOfAnotherTree.java (100%) rename {problems/src => src/main/java}/tree/SumofLeftLeaves.java (100%) rename {problems/src => src/main/java}/tree/SymmetricTree.java (100%) rename {problems/src => src/main/java}/tree/TwoSumIV.java (100%) rename {problems/src => src/main/java}/tree/ValidBinarySearchTree.java (100%) rename {problems/src => src/main/java}/tree/ZigZagTraversal.java (100%) rename {problems/src => src/main/java}/two_pointers/FourSum.java (100%) rename {problems/src => src/main/java}/two_pointers/LastSubstringInLexicographicalOrder.java (100%) rename {problems/src => src/main/java}/two_pointers/LongestSubstringWitoutRepeats.java (100%) rename {problems/src => src/main/java}/two_pointers/MinimumSizeSubarraySum.java (100%) rename {problems/src => src/main/java}/two_pointers/MinimumWindowSubstring.java (100%) rename {problems/src => src/main/java}/two_pointers/MoveZeroes.java (100%) rename {problems/src => src/main/java}/two_pointers/NumberOfMatchingSubsequences.java (100%) rename {problems/src => src/main/java}/two_pointers/RemoveDuplicates.java (100%) rename {problems/src => src/main/java}/two_pointers/RemoveDuplicatesII.java (100%) rename {problems/src => src/main/java}/two_pointers/SmallestRange.java (100%) rename {problems/src => src/main/java}/two_pointers/SubarrayProductLessThanK.java (100%) rename {problems/src => src/main/java}/two_pointers/SubarraysWithKDifferentIntegers.java (100%) rename {problems/src => src/main/java}/two_pointers/ThreeSum.java (100%) rename {problems/src => src/main/java}/two_pointers/ThreeSumClosest.java (100%) rename {problems/src => src/main/java}/two_pointers/TrappingRainWater.java (100%) diff --git a/.gitignore b/.gitignore index 9914da4d..c432b382 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ out/ problems/src.iml .idea .gradle/ +.DS_Store diff --git a/README.md b/README.md index df2c05dd..525f428b 100644 --- a/README.md +++ b/README.md @@ -2,508 +2,508 @@ My accepted leetcode solutions to some of the common interview problems. -#### [Array](problems/src/array) - -- [Pascals Traiangle II](problems/src/array/PascalsTriangle.java) (Easy) -- [Product Of Array Except Self](problems/src/array/ProductOfArrayExceptSelf.java) (Medium) -- [Rotate Matrix](problems/src/array/RotateMatrix.java) (Medium) -- [Set Matrix Zeroes](problems/src/array/SetMatrixZeroes.java) (Medium) -- [Third Maximum Number](problems/src/array/ThirdMaximumNumber.java) (Easy) -- [Two Sum](problems/src/array/TwoSum.java) (Easy) -- [TwoSum II](problems/src/array/TwoSumII.java) (Easy) -- [Can Place Flowers](problems/src/array/CanPlaceFlowers.java) (Easy) -- [Merge Intervals](problems/src/array/MergeIntervals.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [First Missing Positive](problems/src/array/FirstMissingPositive.java) (Hard) -- [Fruit Into Baskets](problems/src/array/FruitIntoBaskets.java) (Medium) -- [MaxProduct Of Three Numbers](problems/src/array/MaxProductOfThreeNumbers.java) (Easy) -- [Missing Number](problems/src/array/MissingNumber.java) (Easy) -- [Merge Sorted Array](problems/src/array/MergeSortedArray.java) (Easy) -- [Rotate Array](problems/src/array/RotateArray.java) (Easy) -- [Sort Colors](problems/src/array/SortColors.java) (Medium) -- [Battleships in a Board](problems/src/array/BattleshipsInABoard.java) (Medium) -- [Find the Celebrity](problems/src/array/FindTheCelebrity.java) (Medium) -- [Meeting Rooms](problems/src/array/MeetingRooms.java) (Easy) -- [Longest Continuous Increasing Subsequence](problems/src/array/LongestIncreasingSubsequence.java) (Easy) -- [Sparse Matrix Multiplication](problems/src/array/SparseMatrixMultiplication.java) (Medium) -- [Read N Characters Given Read4](problems/src/array/ReadNCharacters.java) (Easy) -- [Maximum Swap](problems/src/array/MaximumSwap.java) (Medium) -- [H-Index](problems/src/array/HIndex.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Insert Interval](problems/src/array/InsertInterval.java) (Hard) -- [Increasing Triplet Subsequence](problems/src/array/IncreasingTripletSubsequence.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [K Empty Slots](problems/src/array/KEmptySlots.java) (Hard) -- [Subarray Sum Equals K](problems/src/array/SubarraySumEqualsK.java) (Medium) -- [Pour Water](problems/src/array/PourWater.java) (Medium) -- [Relative Ranks](problems/src/array/RelativeRanks.java) (Easy) -- [Next Greater Element I](problems/src/array/NextGreaterElementI.java) (Easy) -- [Largest Number At Least Twice of Others](problems/src/array/LargestNumberAtLeastTwice.java) (Easy) -- [Minimum Moves to Equal Array Elements II](problems/src/array/MinimumMovesToEqualArray.java) (Median) -- [Image Smoother](problems/src/array/ImageSmoother.java) (Easy) -- [Minimum Index Sum of Two Lists](problems/src/array/MinimumIndexSumOfTwoLists.java) (Easy) -- [Card Flipping Game](problems/src/array/CardFilipGame.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Employee Free Time](problems/src/array/EmployeeFreeTime.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Best Meeting Point](problems/src/array/BestMeetingPoint.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [My Calendar III](problems/src/array/MyCalendarThree.java) (Hard) -- [Champagne Tower](problems/src/array/ChampagneTower.java) (Medium) -- [Valid Tic-Tac-Toe State](problems/src/array/ValidTicTacToeState.java) (Medium) -- [Number of Subarrays with Bounded Maximum](problems/src/array/SubArraysWithBoundedMaximum.java) (Medium) -- [Surface Area of 3D Shapes](problems/src/array/SurfaceAreaOfThreeDShapes.java) (Easy) -- [Max Consecutive Ones](problems/src/array/MaxConsecutiveOnes.java) (Easy) -- [Max Consecutive Ones II](problems/src/array/MaxConsecutiveOnesII.java) (Medium) -- [Add to Array-Form of Integer](problems/src/array/AddToArrayFormOfInteger.java) (Easy) -- [Find Pivot Index](problems/src/array/FindPivotIndex.java) (Easy) -- [Largest Time for Given Digits](problems/src/array/LargestTimeForGivenDigits.java) (Easy) -- [Minimum Time Difference](problems/src/array/MinimumTimeDifference.java) (Medium) -- [Reveal Cards In Increasing Order](problems/src/array/RevealCardsInIncreasingOrder.java) (Medium) -- [Sort Array By Parity II](problems/src/array/SortArrayByParityII.java) (Easy) -- [Matrix Cells in Distance Order](problems/src/array/MatrixCellsinDistanceOrder.java) (Easy) -- [Maximum Sum of Two Non-Overlapping Subarrays](problems/src/array/MaximumSumofTwoNonOverlappingSubarrays.java) (Medium) -- [Longest Line of Consecutive One in Matrix](problems/src/array/LongestLineofConsecutiveOneinMatrix.java) (Medium) -- [Array Partition I](problems/src/array/ArrayPartitionI.java) (Easy) -- [Relative Sort Array](problems/src/array/RelativeSortArray.java) (Easy) -- [Meeting Scheduler](problems/src/array/MeetingScheduler.java) (Medium) -- [Minimum Swaps to Group All 1's Together](problems/src/array/MinimumSwapsToGroupAll1Together.java) (Medium) -- [Array Nesting](problems/src/array/ArrayNesting.java) (Medium) - -#### [Backtracking](problems/src/backtracking) - -- [Combinations](problems/src/backtracking/Combinations.java) (Medium) -- [Combinations Sum](problems/src/backtracking/CombinationSum.java) (Medium) -- [Combinations Sum II](problems/src/backtracking/CombinationSumII.java) (Medium) -- [Letter Phone Number](problems/src/backtracking/LetterPhoneNumber.java) (Medium) -- [Paliandrome Partitioning](problems/src/backtracking/PalindromePartitioning.java) (Medium) -- [Permutations](problems/src/backtracking/Permutations.java) (Medium) -- [Permutations II](problems/src/backtracking/PermutationsII.java) (Medium) -- [SubSets](problems/src/backtracking/Subsets.java) (Medium) -- [SubSet II](problems/src/backtracking/SubsetsII.java) (Medium) -- [Word Search](problems/src/backtracking/WordSearch.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Word Search II](problems/src/backtracking/WordSearchII.java) (Hard) -- [Generate Parentheses](problems/src/backtracking/GenerateParentheses.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Remove Invalid Parentheses](problems/src/backtracking/RemoveInvalidParentheses.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Regular Expression Matching](problems/src/backtracking/RegularExpressionMatching.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Expression Add Operators](problems/src/backtracking/ExpressionAddOperators.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Wildcard Matching](problems/src/backtracking/WildcardMatching.java) (Hard) -- [Letter Case Permutation](problems/src/backtracking/LetterCasePermutation.java) (Easy) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Zuma Game](problems/src/backtracking/ZumaGame.java) (Hard) -- [Matchsticks to Square](problems/src/backtracking/MatchsticksToSquare.java) (Medium) - -#### [Binary Search](problems/src/binary_search) - -- [Minimum Sorted Rotated Array](problems/src/binary_search/MinSortedRotatedArray.java) (Medium) -- [Search in a Rotated Sorted Array](problems/src/binary_search/SearchRotatedSortedArray.java) (Medium) -- [Search for a Range](problems/src/binary_search/SearchForARange.java) (Medium) -- [Sqrt(x)](problems/src/binary_search/SqrtX.java) (Easy) -- [Search Insert Position](problems/src/binary_search/SearchInsertPosition.java) (Easy) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Median of Two Sorted Arrays](problems/src/binary_search/MedianOfTwoSortedArrays.java) (Hard) -- [Pow(x, n)](problems/src/binary_search/PowXN.java) (Medium) -- [Find Peak Element](problems/src/binary_search/FindPeakElement.java) (Medium) -- [Target Sum](problems/src/binary_search/TargetSum.java) (Medium) -- [H-Index II](problems/src/binary_search/HIndexII.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Swim in Rising Water](problems/src/binary_search/SwimInRisingWater.java) (Hard) -- [Time Based Key-Value Store](problems/src/binary_search/TimeBasedKeyValuePair.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Window Subsequence](problems/src/binary_search/MinimumWindowSubsequence.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Koko Eating Bananas](problems/src/binary_search/KokoEatingBananas.java) (Hard) -- [Single Element in a Sorted Array](problems/src/binary_search/SingleElementInASortedArray.java) (Medium) - -#### [Bit Manipulation](problems/src/bit_manipulation) - -- [Gray Code](problems/src/bit_manipulation/GrayCode.java) (Medium) -- [Hamming Distance](problems/src/bit_manipulation/HammingDistance.java) (Easy) -- [Total Hamming Distance](problems/src/bit_manipulation/TotalHammingDistance.java) (Medium) -- [Divide Two Integers](problems/src/bit_manipulation/DivideTwoIntegers.java) (Medium) -- [Binary Number with Alternating Bits](problems/src/bit_manipulation/BinaryNumberWithAlternatingBits.java) (Easy) -- [Binary Watch](problems/src/bit_manipulation/BinaryWatch.java) (Easy) - -#### [Breadth First Search](problems/src/breadth_first_search) - -- [Binaray Tree Level Order Traversal](problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java) (Medium) -- [Word Ladder](problems/src/breadth_first_search/WordLadder.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Word Ladder II](problems/src/breadth_first_search/WordLadderII.java) (Hard) -- [Walls and Gates](problems/src/breadth_first_search/WallsAndGates.java) (Medium) -- [Open the lock](problems/src/breadth_first_search/OpenTheLock.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cut Off Trees for Golf Event](problems/src/breadth_first_search/CutOffTreesForGolfEvent.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Race Car](problems/src/breadth_first_search/RaceCar.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Bus Routes](problems/src/breadth_first_search/BusRoutes.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Sliding Puzzle](problems/src/breadth_first_search/SlidingPuzzle.java) (Hard) -- [Matrix](problems/src/breadth_first_search/Matrix.java) (Medium) -- [Rotting Oranges](problems/src/breadth_first_search/RottingOranges.java) (Medium) - -#### [Depth First Search](problems/src/depth_first_search) - -- [Minesweeper](problems/src/depth_first_search/Minesweeper.java) (Medium) -- [Movie Recommend](problems/src/depth_first_search/MovieRecommend.java) (Medium) -- [Number Of Islands](problems/src/depth_first_search/NumberOfIslands.java) (Medium) -- [Course Schedule](problems/src/depth_first_search/CourseSchedule.java) (Medium) -- [Course Schedule II](problems/src/depth_first_search/CourseScheduleII.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Alien Dictionary](problems/src/depth_first_search/AlienDictionary.java) (Hard) -- [Graph Valid Tree](problems/src/depth_first_search/GraphValidTree.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Longest Consecutive Sequence](problems/src/depth_first_search/LongestConsecutiveSequence.java) (Hard) -- [Accounts Merge](problems/src/depth_first_search/AccountsMerge.java) (Medium) -- [CloneGraph](problems/src/depth_first_search/CloneGraph.java) (Medium) -- [Island Perimeter](problems/src/depth_first_search/IslandPerimeter.java) (Easy) -- [Number of Distinct Islands](problems/src/depth_first_search/NumberOfDistinctIslands.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Distinct Islands II](problems/src/depth_first_search/NumberOfDistinctIslandsII.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Rectangle Enclosing Black Pixels](problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Bricks Falling When Hit](problems/src/depth_first_search/BricksFallingWhenHit.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Robot Room Cleaner](problems/src/depth_first_search/RobotRoomCleaner.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cracking the Safe](problems/src/depth_first_search/CrackingTheSafe.java) (Hard) -- [All Paths From Source to Target](problems/src/depth_first_search/AllPathsFromSourceToTarget.java) (Medium) -- [Max Area of Island](problems/src/depth_first_search/MaxAreaOfIsland.java) (Medium) -- [Satisfiability of Equality Equations](problems/src/depth_first_search/SatisfiabilityOfEquations.java) (Medium) -- [Number of Enclaves](problems/src/depth_first_search/NumberOfEnclaves.java) (Medium) -- [As Far from Land as Possible](problems/src/depth_first_search/AsFarfromLandAsPossible.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimize Malware Spread](problems/src/depth_first_search/MinimizeMalwareSpread.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Parallel Courses](problems/src/depth_first_search/ParallelCourses.java) (Hard) -- [Connecting Cities With Minimum Cost](problems/src/depth_first_search/ConnectingCitiesWithMinimumCost.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Critical Connections in a Network](problems/src/depth_first_search/CriticalConnection.java) (Hard) - -#### [Design](problems/src/design) - -- [Copy List With Random Pointer](problems/src/design/CopyListWithRandomPointer.java) (Medium) -- [Encode and Decode Tiny URL](problems/src/design/EncodeAndDecodeTinyURL.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [LFU Cache](problems/src/design/LFUCache.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [LRU Cache](problems/src/design/LRUCache.java) (Hard) -- [Insert Delete Get Random](problems/src/design/RandomizedSet.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Serialize Deserialize Binary Tree](problems/src/design/SerializeDeserializeBinaryTree.java) (Hard) -- [Design Twitter](problems/src/design/Twitter.java) (Medium) -- [Tic-Tac-Toe](problems/src/design/TicTacToe.java) (Medium) -- [Implement Trie (Prefix Tree)](problems/src/design/Trie.java) (Medium) -- [Binary Search Tree Iterator](problems/src/design/BSTIterator.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Design Search Autocomplete System](problems/src/design/AutocompleteSystem.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Design Excel Sum Formula](problems/src/design/Excel.java) (Hard) -- [Flatten Nested List Iterator](problems/src/design/NestedIterator.java) (Medium) -- [Add and Search Word - Data structure design](problems/src/design/WordDictionary.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Prefix and Suffix Search](problems/src/design/WordFilter.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Insert Delete GetRandom O(1) - Duplicates allowed](problems/src/design/RandomizedCollection.java) (Hard) - -#### [Divide and Conquer](problems/src/divide_and_conquer) - -- [Kth Largest Element In a Array](problems/src/divide_and_conquer/KthLargestElementInAnArray.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reverse Pairs](problems/src/divide_and_conquer/ReversePairs.java) (Hard) -- [Search in a 2D Matrix](problems/src/divide_and_conquer/SearchA2DMatrix.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [24 Game](problems/src/divide_and_conquer/TwentyFourGame.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reverse Pairs II](problems/src/divide_and_conquer/ReversePairsII.java) (Hard) -- [My Calendar II](problems/src/divide_and_conquer/MyCalendarII.java) (Medium) - -#### [Dynamic Programming](problems/src/dynamic_programming) - -- [Best Time To Buy and Sell Stocks](problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java) (Easy) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Best Time to Buy and Sell Stock III](problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java) (Hard) -- [Best Time to Buy and Sell Stock with Transaction Fee](problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java) (Medium) -- [Climbing Stairs](problems/src/dynamic_programming/ClimbingStairs.java) (Easy) -- [Coin Change](problems/src/dynamic_programming/CoinChange.java) (Medium) -- [Coin Change 2](problems/src/dynamic_programming/CoinChange2.java) (Medium) -- [Decode Ways](problems/src/dynamic_programming/DecodeWays.java) (Medium) -- [House Robber](problems/src/dynamic_programming/HouseRobber.java) (Easy) -- [House Robber II](problems/src/dynamic_programming/HouseRobberII.java) (Medium) -- [Longest Increasing Subsequence](problems/src/dynamic_programming/LongestIncreasingSubsequence.java) (Medium) -- [Longest Paliandromic Substring](problems/src/dynamic_programming/LongestPaliandromicSubstring.java) (Medium) -- [Longest Palindromic Subsequence](problems/src/dynamic_programming/LongestPalindromicSubsequence.java) (Medium) -- [Maximum Product Subarray](problems/src/dynamic_programming/MaximumProductSubarray.java) (Medium) -- [Min Cost Climbing Stairs](problems/src/dynamic_programming/MinCostClimbingStairs.java) (Easy) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Palindrome Partitioning II](problems/src/dynamic_programming/PalindromePartitioningII.java) (Hard) -- [UniqueBinary Search Trees](problems/src/dynamic_programming/UniqueBinarySearchTrees.java) (Medium) -- [Unique Binary Search Trees II](problems/src/dynamic_programming/UniqueBinarySearchTreesII.java) (Medium) -- [WordBreak](problems/src/dynamic_programming/WordBreak.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [WordBreak II](problems/src/dynamic_programming/WordBreakII.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Concatenated Words](problems/src/dynamic_programming/ConcatenatedWords.java) (Hard) -- [Can I Win](problems/src/dynamic_programming/CanIWin.java) (Medium) -- [Maximum Subarray](problems/src/dynamic_programming/MaximumSubarray.java) (Easy) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Dungeon Game](problems/src/dynamic_programming/DungeonGame.java) (Hard) -- [2 Keys Keyboard](problems/src/dynamic_programming/TwoKeysKeyboard.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximum Sum of 3 Non-Overlapping Subarrays](problems/src/dynamic_programming/MaxSum3SubArray.java) (Hard) -- [Maximal Square](problems/src/dynamic_programming/MaximalSquare.java) (Medium) -- [Continuous Subarray Sum](problems/src/dynamic_programming/ContinuousSubarraySum.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Decode Ways II](problems/src/dynamic_programming/DecodeWaysII.java) (Hard) -- [Palindromic Substrings](problems/src/dynamic_programming/PalindromicSubstrings.java) (Medium) -- [Number of Longest Increasing Subsequence](problems/src/dynamic_programming/NumberOfLIS.java) (Medium) -- [Combination Sum IV](problems/src/dynamic_programming/CombinationSumIV.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Paint House II](problems/src/dynamic_programming/PaintHouseII.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Split Array Largest Sum](problems/src/dynamic_programming/SplitArrayLargestSum.java) (Hard) -- [Number Of Corner Rectangles](problems/src/dynamic_programming/CornerRectangles.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Burst Balloons](problems/src/dynamic_programming/BurstBalloons.java) (Hard) -- [Largest Plus Sign](problems/src/dynamic_programming/LargestPlusSign.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Palindrome Pairs](problems/src/dynamic_programming/PalindromePairs.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cherry Pickup](problems/src/dynamic_programming/CherryPickup.java) (Hard) -- [Knight Probability in Chessboard](problems/src/dynamic_programming/KnightProbabilityInChessboard.java) (Medium) -- [Largest Sum of Averages](problems/src/dynamic_programming/LargestSumOfAverages.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Number of Refueling Stops](problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cat and Mouse](problems/src/dynamic_programming/CatAndMouse.java) (Hard) -- [Stone Game](problems/src/dynamic_programming/StoneGame.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Odd Even Jump](problems/src/dynamic_programming/OddEvenJump.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Profitable Schemes](problems/src/dynamic_programming/ProfitableSchemes.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximum Vacation Days](problems/src/dynamic_programming/MaximumVacationDays.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Russian Doll Envelopes](problems/src/dynamic_programming/RussianDollEnvelopes.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Student Attendance Record II](problems/src/dynamic_programming/StudentAttendanceRecordII.java) (Hard) -- [Out of Boundary Paths](problems/src/dynamic_programming/OutOfBoundaryPaths.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Remove Boxes](problems/src/dynamic_programming/RemoveBoxes.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Stickers to Spell Word](problems/src/dynamic_programming/StickersToSpellWord.java) (Hard) -- [Ones and Zeroes](problems/src/dynamic_programming/OnesAndZeroes.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Encode String with Shortest Length](problems/src/dynamic_programming/EncodeStringWithShortestLength.java) (Hard) -- [Length of Longest Fibonacci Subsequence](problems/src/dynamic_programming/LengthofLongestFibonacciSubsequence.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Make Array Strictly Increasing](problems/src/dynamic_programming/MakeArrayStrictlyIncreasing.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Number of Taps to Open to Water a Garden](problems/src/dynamic_programming/MinimumNumberOfTaps.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Delete Columns to Make Sorted III](problems/src/dynamic_programming/DeleteColumnsToMakeSortedIII.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Handshakes That Don't Cross](problems/src/dynamic_programming/HandshakesThatDontCross.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Difficulty of a Job Schedule](problems/src/dynamic_programming/MinimumDifficultyOfAJobSchedule.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Jump Game V](problems/src/dynamic_programming/JumpGameV.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Freedom Trail](problems/src/dynamic_programming/FreedomTrail.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Strange Printer](problems/src/dynamic_programming/StrangePrinter.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Cost to Merge Stones](problems/src/dynamic_programming/MinimumCostToMergeStones.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Interleaving String](problems/src/dynamic_programming/InterleavingString.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Count Vowels Permutation](problems/src/dynamic_programming/CountVowelsPermutation.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Non-negative Integers without Consecutive Ones](problems/src/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java) (Hard) -- [Bomb Enemy](problems/src/dynamic_programming/BombEnemy.java) (Medium) -- [Number of Dice Rolls With Target Sum](problems/src/dynamic_programming/NumberOfDiceRollsWithTargetSum.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Distinct Subsequences](problems/src/dynamic_programming/DistinctSubsequences.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Distinct Subsequences II](problems/src/dynamic_programming/DistinctSubsequencesII.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Distance to Type a Word Using Two Fingers](problems/src/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Valid Palindrome III](problems/src/dynamic_programming/ValidPalindromeIII.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Palindrome Partitioning III](problems/src/dynamic_programming/PalindromePartitioningIII.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Tiling a Rectangle with the Fewest Squares](problems/src/dynamic_programming/TilingARectangle.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Longest Chunked Palindrome Decomposition](problems/src/dynamic_programming/LongestChunkedPalindromeDecomposition.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Stone Game III](problems/src/dynamic_programming/StoneGameIII.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Ways to Stay in the Same Place After Some Steps](problems/src/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java) (Hard) -- [Toss Strange Coins](problems/src/dynamic_programming/TossStrangeCoins.java) (Medium) -- [Knight Dialer](problems/src/dynamic_programming/KnightDialer.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Palindrome Removal](problems/src/dynamic_programming/PalindromeRemoval.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Restore The Array](problems/src/dynamic_programming/RestoreTheArray.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cherry Pickup II](problems/src/dynamic_programming/CherryPickupII.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Constrained Subsequence Sum](problems/src/dynamic_programming/ConstrainedSubsequenceSum.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Largest Multiple of Three](problems/src/dynamic_programming/LargestMultipleOfThree.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Largest Multiple of Three](problems/src/dynamic_programming/MaximumProfitInJobScheduling.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Music Playlists](problems/src/dynamic_programming/NumberOfMusicPlaylists.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Paint House III](problems/src/dynamic_programming/PaintHouseIII.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Shortest Path Visiting All Nodes](problems/src/dynamic_programming/ShortestPathVisitingAllNodes.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Sufficient Team](problems/src/dynamic_programming/SmallestSufficientTeam.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Stone Game IV](problems/src/dynamic_programming/StoneGameIV.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Tallest Billboard](problems/src/dynamic_programming/TallestBillboard.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Count Different Palindromic Subsequences](problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Paths with Max Score](problems/src/dynamic_programming/NumberOfPathsWithMaxScore.java) (Hard) - - -#### [Greedy](problems/src/greedy) - -- [Jump Game](problems/src/greedy/JumpGame.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Jump Game II](problems/src/greedy/JumpGameII.java) (Hard) -- [Course Schedule III](problems/src/greedy/CourseScheduleIII.java) (Medium) -- [GasStation](problems/src/greedy/GasStation.java) (Medium) -- [Non-Overlapping Intervals](problems/src/greedy/NonOverlappingIntervals.java) (Medium) -- [Minimum Number of Arrows to Burst Balloons](problems/src/greedy/BurstBalloons.java) (Medium) -- [Queue Reconstruction By Height](problems/src/greedy/QueueReconstructionByHeight.java) (Medium) -- [Task Scheduler](problems/src/greedy/TaskScheduler.java) (Medium) -- [Maximum Length of Pair Chain](problems/src/greedy/MaximumLengthOfPairChain.java) (Medium) -- [Lemonade Change](problems/src/greedy/LemonadeChange.java) (Easy) -- [Score After Flipping Matrix](problems/src/greedy/ScoreAfterFlippingMatrix.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [IPO](problems/src/greedy/IPO.java) (Hard) -- [String Without AAA or BBB](problems/src/greedy/StringWithout3A3B.java) (Medium) -- [Boats to Save People](problems/src/greedy/BoatsToSavePeople.java) (Medium) -- [Broken Calculator](problems/src/greedy/BrokenCalculator.java) (Medium) -- [Two City Scheduling](problems/src/greedy/TwoCityScheduling.java) (Easy) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Time to Build Blocks](problems/src/greedy/MinimumTimeToBuildBlocks.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reducing Dishes](problems/src/greedy/ReducingDishes.java) (Hard) - -#### [Hashing](problems/src/hashing) - -- [Anagrams](problems/src/hashing/Anagrams.java) (Medium) -- [Group Anagrams](problems/src/hashing/GroupAnagrams.java) (Medium) -- [Kdiff Pairs In a Array](problems/src/hashing/KdiffPairsInanArray.java) (Easy) -- [Sort Character by Frequency](problems/src/hashing/SortCharByFrequency.java) (Medium) -- [Two Sum](problems/src/hashing/TwoSum.java) (Easy) -- [Valid Anagram](problems/src/hashing/ValidAnagram.java) (Easy) -- [Maximum Size Subarray Sum Equals k](problems/src/hashing/MaximumSizeSubarraySumEqualsk.java) (Medium) -- [Contiguous Array](problems/src/hashing/ContiguousArray.java) (Medium) -- [Brick Wall](problems/src/hashing/BrickWall.java) (Medium) -- [Partition Labels](problems/src/hashing/PartitionLabels.java) (Medium) -- [Custom Sort String](problems/src/hashing/CustomSortString.java) (Medium) -- [Short Encoding of Words](problems/src/hashing/ShortEncodingOfWords.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Substring with Concatenation of All Words](problems/src/hashing/SubstringConcatenationOfWords.java) (Hard) -- [Distribute Candies](problems/src/hashing/DistributeCandies.java) (Easy) -- [Groups of Special-Equivalent Strings](problems/src/hashing/GroupsOfSpecialEquivalentStrings.java) (Easy) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Atoms](problems/src/hashing/NumberOfAtoms.java) (Hard) -- [Analyze User Website Visit Pattern](problems/src/hashing/AnalyzeUserWebsiteVisitPattern.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [String Transforms Into Another String](problems/src/hashing/StringTransformsIntoAnotherString.java) (Hard) - -#### [Heap](problems/src/heap) - -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Sliding Window Maximum](problems/src/heap/SlidingWindowMaximum.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [The Skyline Problem](problems/src/heap/TheSkylineProblem.java) (Hard) -- [Meeting Rooms II](problems/src/heap/MeetingRoomsII.java) (Medium) -- [Top K Frequent Words](problems/src/heap/TopKFrequentWords.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Candy](problems/src/heap/Candy.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Rotation with Highest Score](problems/src/heap/SmallestRotationWithHighestScore.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximum Frequency Stack](problems/src/heap/FreqStack.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reachable Nodes In Subdivided Graph](problems/src/heap/ReachableNodesInSubdividedGraph.java) (Hard) -- [K Closest Points to Origin](problems/src/heap/KClosestPointsToOrigin.java) (Medium) -- [Distant Barcodes](problems/src/heap/DistantBarcodes.java) (Medium) - -#### [Linked List](problems/src/linked_list) - -- [Intersection of two Linked-Lists](problems/src/linked_list/IntersectionOfTwoLists.java) (Easy) -- [Linked List Cycle](problems/src/linked_list/LinkedListCycle.java) (Easy) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Merge K Sorted Lists](problems/src/linked_list/MergeKSortedLists.java) (Hard) -- [Merge Two Sorted List](problems/src/linked_list/MergeTwoSortedList.java) (Easy) -- [Paliandrome List](problems/src/linked_list/PaliandromeList.java) (Easy) -- [Reverse Linked List](problems/src/linked_list/ReverseLinkedList.java) (Easy) -- [Delete Node in a Linked List](problems/src/linked_list/DeleteNode.java) (Easy) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reverse Nodes in k-Group](problems/src/linked_list/ReverseNodesKGroup.java) (Hard) -- [Swap Nodes in Pairs](problems/src/linked_list/SwapNodesInPairs.java) (Medium) -- [Middle of Linked List](problems/src/linked_list/MiddleOfLinkedList.java) (Easy) -- [Split Linked List in Parts](problems/src/linked_list/SplitLinkedListInParts.java) (Medium) -- [Next Greater Node In Linked List](problems/src/linked_list/NextGreaterNodeInLinkedList.java) (Medium) - -#### [Math](problems/src/math) - -- [Add Two Numbers](problems/src/math/AddTwoNumbers.java) (Medium) -- [Count Primes](problems/src/math/CountPrimes.java) (Easy) -- [Rotate Function](problems/src/math/RotateFunction.java) (Medium) -- [Water and Jug Problem](problems/src/math/WaterAndJugProblem.java) (Medium) -- [Add Digits](problems/src/math/AddDigits.java) (Easy) -- [Excel Sheet Column Title](problems/src/math/ExcelSheetColumnTitle.java) (Easy) -- [Roman to Integer](problems/src/math/RomanToInteger.java) (Easy) -- [Bulb Switcher II](problems/src/math/BulbSwitcherII.java) (Medium) -- [Global and Local Inversions](problems/src/math/GlobalAndLocalInversions.java) (Medium) -- [Solve the Equation](problems/src/math/SolveTheEquation.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Couples Holding Hands](problems/src/math/CouplesHoldingHands.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reaching Points](problems/src/math/ReachingPoints.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Nth Magical Number](problems/src/math/NthMagicalNumber.java) (Hard) -- [Squirrel Simulation](problems/src/math/SquirrelSimulation.java) (Medium) -- [Projection Area of 3D Shapes](problems/src/math/ProjectionAreaOf3DShapes.java) (Easy) -- [Decoded String at Index](problems/src/math/DecodedStringAtIndex.java) (Medium) -- [Base 7](problems/src/math/Base7.java) (Easy) -- [Smallest Range I](problems/src/math/SmallestRangeI.java) (Easy) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Largest Component Size by Common Factor](problems/src/math/LargestComponentSizebyCommonFactor.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Super Washing Machines](problems/src/math/SuperWashingMachines.java) (Hard) -- [Rectangle Overlap](problems/src/math/RectangleOverlap.java) (Easy) -- [Nth Digit](problems/src/math/NthDigit.java) (Easy) - -#### [Reservoir Sampling](problems/src/reservoir_sampling) - -- [Random Pick Index](problems/src/reservoir_sampling/RandomPickIndex.java) (Medium) - -#### [Stack](problems/src/stack) - -- [Min Stack](problems/src/stack/MinStack.java) (Easy) -- [Valid Parentheses](problems/src/stack/ValidParentheses.java) (Easy) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Largest Rectangle In Histogram](problems/src/stack/LargestRectangleInHistogram.java) (Hard) -- [Implement Queue using Stacks](problems/src/stack/MyQueue.java) (Easy) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximal Rectangle](problems/src/stack/MaximalRectangle.java) (Hard) -- [Exclusive Time of Functions](problems/src/stack/ExclusiveTimeOfFunctions.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Basic Calculator](problems/src/stack/BasicCalculator.java) (Hard) -- [Decode String](problems/src/stack/DecodeString.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Longest Valid Parentheses](problems/src/stack/LongestValidParentheses.java) (Hard) - - -#### [String](problems/src/string) - -- [First Unique Character In a String](problems/src/string/FirstUniqueCharacterInAString.java) (Easy) -- [Repeated Substring Pattern](problems/src/string/RepeatedSubstringPattern.java) (Easy) -- [Reverse Words In a String](problems/src/string/ReverseWordsInAString.java) (Medium) -- [ReverseWords II](problems/src/string/ReverseWordsII.java) (Medium) -- [String to Integer](problems/src/string/StringToInteger.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Text Justification](problems/src/string/TextJustification.java) (Hard) -- [ZigZag Conversion](problems/src/string/ZigZagConversion.java) (Medium) -- [Implement StrStr](problems/src/string/ImplementStrStr.java) (Easy) -- [Excel Sheet Column Number](problems/src/string/ExcelSheetColumnNumber.java) (Easy) -- [Compare Version Numbers](problems/src/string/CompareVersionNumbers.java) (Easy) -- [Valid Palindrome](problems/src/string/ValidPalindrome.java) (Easy) -- [Simplify Path](problems/src/string/SimplifyPath.java) (Medium) -- [Permutation in String](problems/src/string/PermutationInString.java) (Medium) -- [Add Binary](problems/src/string/AddBinary.java) (Easy) -- [Valid Palindrome II](problems/src/string/ValidPalindromeII.java) (Easy) -- [One Edit Distance](problems/src/string/OneEditDistance.java) (Medium) -- [Count and Say](problems/src/string/CountAndSay.java) (Easy) -- [Multiply Strings](problems/src/string/MultiplyStrings.java) (Medium) -- [Longest Word in Dictionary through Deleting](problems/src/string/LongestWordInDictonary.java) (Medium) -- [Isomorphic Strings](problems/src/string/IsomorphicStrings.java) (Easy) -- [String Compression](problems/src/string/StringCompression.java) (Easy) -- [Longest Common Prefix](problems/src/string/LongestCommonPrefix.java) (Easy) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Find the Closest Palindrome](problems/src/string/FindTheClosestPalindrome.java) (Hard) -- [Monotone Increasing Digits](problems/src/string/MonotoneIncreasingDigits.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Shortest Palindrome](problems/src/string/ShortestPalindrome.java) (Hard) -- [Valid Word Abbreviation](problems/src/string/ValidWordAbbreviation.java) (Easy) -- [Longest Palindrome](problems/src/string/LongestPalindrome.java) (Easy) -- [Replace Words](problems/src/string/ReplaceWords.java) (Medium) -- [Rotate String](problems/src/string/RotateString.java) (Easy) -- [Keyboard Row](problems/src/string/KeyboardRow.java) (Easy) -- [Student Attendance Record I](problems/src/string/StudentAttendanceRecordI.java) (Easy) -- [Split Concatenated Strings](problems/src/string/SplitConcatenatedStrings.java) (Medium) -- [Valid Word Square](problems/src/string/ValidWordSquare.java) (Easy) -- [Reconstruct Original Digits from English](problems/src/string/ReconstructOriginalDigitsFromEnglish.java) (Medium) -- [Push Dominoes](problems/src/string/PushDominoes.java) (Medium) -- [Validate IP Address](problems/src/string/ValidateIPAddress.java) (Medium) -- [Reverse String II](problems/src/string/ReverseStringII.java) (Easy) -- [Find Words That Can Be Formed by Characters](problems/src/string/FindWordsThatCanBeFormedbyCharacters.java) (Easy) -- [Minimum Add to Make Parentheses Valid](problems/src/string/MinimumAddtoMakeParenthesesValid.java) (Medium) - -#### [Tree](problems/src/tree) - -- [Binaray Tree Right Side View](problems/src/tree/BinarayTreeRightSideView.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Binary Tree Maximum Path Sum](problems/src/tree/BinaryTreeMaximumPathSum.java) (Hard) -- [Boundary of Binary Tree](problems/src/tree/BoundaryOfBinaryTree.java) (Medium) -- [Convert sorted array to BST](problems/src/tree/ConvertSortedArrayToBST.java) (Medium) -- [Lowest Common Ancestor of a Binary Tree](problems/src/tree/LCA.java) (Medium) -- [Lowest Common Ancestor of a BST](problems/src/tree/LowestCommonAncestorBST.java) (Easy) -- [Most Frequent Subtree Sum](problems/src/tree/MostFrequentSubtreeSum.java) (Medium) -- [Path Sum III](problems/src/tree/PathSumIII.java) (Easy) -- [Convert Postorder and Inorder traversal to Binary Tree](problems/src/tree/PostorderToBT.java) (Medium) -- [Convert Preorder and Inorder traversal to Binary Tree](problems/src/tree/PreorderToBT.java) (Medium) -- [Sorted Array to BST](problems/src/tree/SortedArrayToBST.java) (Medium) -- [Valid Binary Search Tree](problems/src/tree/ValidBinarySearchTree.java) (Medium) -- [Largest BST Subtree](problems/src/tree/LargestBSTSubtree.java) (Medium) -- [Closest Binary Search Tree Value](problems/src/tree/ClosestBinarySearchTreeValue.java) (Easy) -- [Inorder Successor in BST](problems/src/tree/InorderSuccessorInBST.java) (Medium) -- [Construct String From Binary Tree](problems/src/tree/ConstructStringFromBinaryTree.java) (Easy) -- [Flatten Binary Tree to Linked List](problems/src/tree/FlattenBinaryTree.java) (Medium) -- [Populating Next Right Pointers in Each Node](problems/src/tree/NextRightPointer.java) (Medium) -- [Populating Next Right Pointers in Each Node II](problems/src/tree/NextRightPointerII.java) (Medium) -- [Subtree of Another Tree](problems/src/tree/SubtreeOfAnotherTree.java) (Easy) -- [Binary Tree Zigzag Level Order Traversal](problems/src/tree/ZigZagTraversal.java) (Medium) -- [Binary Tree Inorder Traversal](problems/src/tree/BinaryTreeInorderTraversal.java) (Medium) -- [Symmetric Tree](problems/src/tree/SymmetricTree.java) (Easy) -- [Maximum Binary Tree](problems/src/tree/MaximumBinaryTree.java) (Medium) -- [Find Bottom Left Tree Value](problems/src/tree/FindBottomLeftTreeValue.java) (Medium) -- [Diameter of Binary Tree](problems/src/tree/DiameterOfBinaryTree.java) (Easy) -- [Binary Tree Paths](problems/src/tree/BinaryTreePaths.java) (Easy) -- [Sum of Left Leaves](problems/src/tree/SumofLeftLeaves.java) (Easy) -- [Two Sum IV - Input is a BST](problems/src/tree/TwoSumIV.java) (Easy) -- [Average of Levels in Binary Tree](problems/src/tree/AverageOfLevelsInBinaryTree.java) (Easy) -- [Convert Binary Search Tree to Sorted Doubly Linked List](problems/src/tree/BSTtoDoublyLinkedList.java) (Easy) -- [Same Tree](problems/src/tree/SameTree.java) (Easy) -- [Binary Tree Longest Consecutive SequencefindMinDifference II](problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java) (Medium) -- [Minimum Absolute Difference in BST](problems/src/tree/MinimumAbsoluteDifferenceInBST.java) (Medium) -- [Equal Tree Partition](problems/src/tree/EqualTreePartition.java) (Medium) -- [Split BST](problems/src/tree/SplitBST.java) (Medium) -- [Closest Leaf in a Binary Tree](problems/src/tree/ClosestLeafInABinaryTree.java) (Medium) -- [Maximum Width of Binary Tree](problems/src/tree/MaximumWidthOfBinaryTree.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Recover Binary Search Tree](problems/src/tree/RecoverBinarySearchTree.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Binary Tree Postorder Traversal](problems/src/tree/BinaryTreePostorderTraversal.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Serialize and Deserialize N-ary Tree](problems/src/tree/SerializeAndDeserializeNAryTree.java) (Hard) -- [Convert BST to Greater Tree](problems/src/tree/ConvertBSTToGreaterTree.java) (Easy) -- [All Nodes Distance K in Binary Tree](problems/src/tree/AllNodesDistanceKInBinaryTree.java) (Medium) -- [All Possible Full Binary Trees](problems/src/tree/AllPossibleFullBinaryTrees.java) (Medium) -- [Flip Equivalent Binary Trees](problems/src/tree/FlipEquivalentBinaryTrees.java) (Medium) -- [Construct Binary Tree from String](problems/src/tree/ConstructBinaryTreefromString.java) (Medium) -- [Find Largest Value in Each Tree Row](problems/src/tree/FindLargestValueInEachTreeRow.java) (Medium) -- [Find Bottom Left Tree Value](problems/src/tree/FindBottomLeftTreeValue.java) (Medium) -- [Maximum Level Sum of a Binary Tree](problems/src/tree/MaximumLevelSumofABinaryTree.java) (Medium) -- [Leaf-Similar Trees](problems/src/tree/LeafSimilarTrees.java) (Easy) -- [Binary Tree Tilt](problems/src/tree/BinaryTreeTilt.java) (Easy) - -#### [Two Pointers](problems/src/two_pointers) - -- [Four Sum](problems/src/two_pointers/FourSum.java) (Medium) -- [Longest Substring Witout Repeats](problems/src/two_pointers/LongestSubstringWitoutRepeats.java) (Medium) -- [Three Sum](problems/src/two_pointers/ThreeSum.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Trapping Rain Water](problems/src/two_pointers/TrappingRainWater.java) (Hard) -- [3Sum Closest](problems/src/two_pointers/ThreeSumClosest.java) (Medium) -- [Move Zeroes](problems/src/two_pointers/MoveZeroes.java) (Easy) -- [Remove Duplicates](problems/src/two_pointers/RemoveDuplicates.java) (Easy) -- [Remove Duplicates II](problems/src/two_pointers/RemoveDuplicatesII.java) (Medium) -- [Minimum Size Subarray Sum](problems/src/two_pointers/MinimumSizeSubarraySum.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Window Substring](problems/src/two_pointers/MinimumWindowSubstring.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Range](problems/src/two_pointers/SmallestRange.java) (Hard) -- [Subarray Product Less Than K](problems/src/two_pointers/SubarrayProductLessThanK.java) (Medium) -- [Number of Matching Subsequences](problems/src/two_pointers/NumberOfMatchingSubsequences.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Subarrays with K Different Integers](problems/src/two_pointers/SubarraysWithKDifferentIntegers.java) (Hard) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Last Substring in Lexicographical Order](problems/src/two_pointers/LastSubstringInLexicographicalOrder.java) (Hard) +#### [Array](src/main/java/array) + +- [Pascals Traiangle II](src/main/java/array/PascalsTriangle.java) (Easy) +- [Product Of Array Except Self](src/main/java/array/ProductOfArrayExceptSelf.java) (Medium) +- [Rotate Matrix](src/main/java/array/RotateMatrix.java) (Medium) +- [Set Matrix Zeroes](src/main/java/array/SetMatrixZeroes.java) (Medium) +- [Third Maximum Number](src/main/java/array/ThirdMaximumNumber.java) (Easy) +- [Two Sum](src/main/java/array/TwoSum.java) (Easy) +- [TwoSum II](src/main/java/array/TwoSumII.java) (Easy) +- [Can Place Flowers](src/main/java/array/CanPlaceFlowers.java) (Easy) +- [Merge Intervals](src/main/java/array/MergeIntervals.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [First Missing Positive](src/main/java/array/FirstMissingPositive.java) (Hard) +- [Fruit Into Baskets](src/main/java/array/FruitIntoBaskets.java) (Medium) +- [MaxProduct Of Three Numbers](src/main/java/array/MaxProductOfThreeNumbers.java) (Easy) +- [Missing Number](src/main/java/array/MissingNumber.java) (Easy) +- [Merge Sorted Array](src/main/java/array/MergeSortedArray.java) (Easy) +- [Rotate Array](src/main/java/array/RotateArray.java) (Easy) +- [Sort Colors](src/main/java/array/SortColors.java) (Medium) +- [Battleships in a Board](src/main/java/array/BattleshipsInABoard.java) (Medium) +- [Find the Celebrity](src/main/java/array/FindTheCelebrity.java) (Medium) +- [Meeting Rooms](src/main/java/array/MeetingRooms.java) (Easy) +- [Longest Continuous Increasing Subsequence](src/main/java/array/LongestIncreasingSubsequence.java) (Easy) +- [Sparse Matrix Multiplication](src/main/java/array/SparseMatrixMultiplication.java) (Medium) +- [Read N Characters Given Read4](src/main/java/array/ReadNCharacters.java) (Easy) +- [Maximum Swap](src/main/java/array/MaximumSwap.java) (Medium) +- [H-Index](src/main/java/array/HIndex.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Insert Interval](src/main/java/array/InsertInterval.java) (Hard) +- [Increasing Triplet Subsequence](src/main/java/array/IncreasingTripletSubsequence.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [K Empty Slots](src/main/java/array/KEmptySlots.java) (Hard) +- [Subarray Sum Equals K](src/main/java/array/SubarraySumEqualsK.java) (Medium) +- [Pour Water](src/main/java/array/PourWater.java) (Medium) +- [Relative Ranks](src/main/java/array/RelativeRanks.java) (Easy) +- [Next Greater Element I](src/main/java/array/NextGreaterElementI.java) (Easy) +- [Largest Number At Least Twice of Others](src/main/java/array/LargestNumberAtLeastTwice.java) (Easy) +- [Minimum Moves to Equal Array Elements II](src/main/java/array/MinimumMovesToEqualArray.java) (Median) +- [Image Smoother](src/main/java/array/ImageSmoother.java) (Easy) +- [Minimum Index Sum of Two Lists](src/main/java/array/MinimumIndexSumOfTwoLists.java) (Easy) +- [Card Flipping Game](src/main/java/array/CardFilipGame.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Employee Free Time](src/main/java/array/EmployeeFreeTime.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Best Meeting Point](src/main/java/array/BestMeetingPoint.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [My Calendar III](src/main/java/array/MyCalendarThree.java) (Hard) +- [Champagne Tower](src/main/java/array/ChampagneTower.java) (Medium) +- [Valid Tic-Tac-Toe State](src/main/java/array/ValidTicTacToeState.java) (Medium) +- [Number of Subarrays with Bounded Maximum](src/main/java/array/SubArraysWithBoundedMaximum.java) (Medium) +- [Surface Area of 3D Shapes](src/main/java/array/SurfaceAreaOfThreeDShapes.java) (Easy) +- [Max Consecutive Ones](src/main/java/array/MaxConsecutiveOnes.java) (Easy) +- [Max Consecutive Ones II](src/main/java/array/MaxConsecutiveOnesII.java) (Medium) +- [Add to Array-Form of Integer](src/main/java/array/AddToArrayFormOfInteger.java) (Easy) +- [Find Pivot Index](src/main/java/array/FindPivotIndex.java) (Easy) +- [Largest Time for Given Digits](src/main/java/array/LargestTimeForGivenDigits.java) (Easy) +- [Minimum Time Difference](src/main/java/array/MinimumTimeDifference.java) (Medium) +- [Reveal Cards In Increasing Order](src/main/java/array/RevealCardsInIncreasingOrder.java) (Medium) +- [Sort Array By Parity II](src/main/java/array/SortArrayByParityII.java) (Easy) +- [Matrix Cells in Distance Order](src/main/java/array/MatrixCellsinDistanceOrder.java) (Easy) +- [Maximum Sum of Two Non-Overlapping Subarrays](src/main/java/array/MaximumSumofTwoNonOverlappingSubarrays.java) (Medium) +- [Longest Line of Consecutive One in Matrix](src/main/java/array/LongestLineofConsecutiveOneinMatrix.java) (Medium) +- [Array Partition I](src/main/java/array/ArrayPartitionI.java) (Easy) +- [Relative Sort Array](src/main/java/array/RelativeSortArray.java) (Easy) +- [Meeting Scheduler](src/main/java/array/MeetingScheduler.java) (Medium) +- [Minimum Swaps to Group All 1's Together](src/main/java/array/MinimumSwapsToGroupAll1Together.java) (Medium) +- [Array Nesting](src/main/java/array/ArrayNesting.java) (Medium) + +#### [Backtracking](src/main/java/backtracking) + +- [Combinations](src/main/java/backtracking/Combinations.java) (Medium) +- [Combinations Sum](src/main/java/backtracking/CombinationSum.java) (Medium) +- [Combinations Sum II](src/main/java/backtracking/CombinationSumII.java) (Medium) +- [Letter Phone Number](src/main/java/backtracking/LetterPhoneNumber.java) (Medium) +- [Paliandrome Partitioning](src/main/java/backtracking/PalindromePartitioning.java) (Medium) +- [Permutations](src/main/java/backtracking/Permutations.java) (Medium) +- [Permutations II](src/main/java/backtracking/PermutationsII.java) (Medium) +- [SubSets](src/main/java/backtracking/Subsets.java) (Medium) +- [SubSet II](src/main/java/backtracking/SubsetsII.java) (Medium) +- [Word Search](src/main/java/backtracking/WordSearch.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Word Search II](src/main/java/backtracking/WordSearchII.java) (Hard) +- [Generate Parentheses](src/main/java/backtracking/GenerateParentheses.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Remove Invalid Parentheses](src/main/java/backtracking/RemoveInvalidParentheses.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Regular Expression Matching](src/main/java/backtracking/RegularExpressionMatching.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Expression Add Operators](src/main/java/backtracking/ExpressionAddOperators.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Wildcard Matching](src/main/java/backtracking/WildcardMatching.java) (Hard) +- [Letter Case Permutation](src/main/java/backtracking/LetterCasePermutation.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Zuma Game](src/main/java/backtracking/ZumaGame.java) (Hard) +- [Matchsticks to Square](src/main/java/backtracking/MatchsticksToSquare.java) (Medium) + +#### [Binary Search](src/main/java/binary_search) + +- [Minimum Sorted Rotated Array](src/main/java/binary_search/MinSortedRotatedArray.java) (Medium) +- [Search in a Rotated Sorted Array](src/main/java/binary_search/SearchRotatedSortedArray.java) (Medium) +- [Search for a Range](src/main/java/binary_search/SearchForARange.java) (Medium) +- [Sqrt(x)](src/main/java/binary_search/SqrtX.java) (Easy) +- [Search Insert Position](src/main/java/binary_search/SearchInsertPosition.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Median of Two Sorted Arrays](src/main/java/binary_search/MedianOfTwoSortedArrays.java) (Hard) +- [Pow(x, n)](src/main/java/binary_search/PowXN.java) (Medium) +- [Find Peak Element](src/main/java/binary_search/FindPeakElement.java) (Medium) +- [Target Sum](src/main/java/binary_search/TargetSum.java) (Medium) +- [H-Index II](src/main/java/binary_search/HIndexII.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Swim in Rising Water](src/main/java/binary_search/SwimInRisingWater.java) (Hard) +- [Time Based Key-Value Store](src/main/java/binary_search/TimeBasedKeyValuePair.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Window Subsequence](src/main/java/binary_search/MinimumWindowSubsequence.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Koko Eating Bananas](src/main/java/binary_search/KokoEatingBananas.java) (Hard) +- [Single Element in a Sorted Array](src/main/java/binary_search/SingleElementInASortedArray.java) (Medium) + +#### [Bit Manipulation](src/main/java/bit_manipulation) + +- [Gray Code](src/main/java/bit_manipulation/GrayCode.java) (Medium) +- [Hamming Distance](src/main/java/bit_manipulation/HammingDistance.java) (Easy) +- [Total Hamming Distance](src/main/java/bit_manipulation/TotalHammingDistance.java) (Medium) +- [Divide Two Integers](src/main/java/bit_manipulation/DivideTwoIntegers.java) (Medium) +- [Binary Number with Alternating Bits](src/main/java/bit_manipulation/BinaryNumberWithAlternatingBits.java) (Easy) +- [Binary Watch](src/main/java/bit_manipulation/BinaryWatch.java) (Easy) + +#### [Breadth First Search](src/main/java/breadth_first_search) + +- [Binaray Tree Level Order Traversal](src/main/java/breadth_first_search/BinarayTreeLevelOrderTraversal.java) (Medium) +- [Word Ladder](src/main/java/breadth_first_search/WordLadder.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Word Ladder II](src/main/java/breadth_first_search/WordLadderII.java) (Hard) +- [Walls and Gates](src/main/java/breadth_first_search/WallsAndGates.java) (Medium) +- [Open the lock](src/main/java/breadth_first_search/OpenTheLock.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cut Off Trees for Golf Event](src/main/java/breadth_first_search/CutOffTreesForGolfEvent.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Race Car](src/main/java/breadth_first_search/RaceCar.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Bus Routes](src/main/java/breadth_first_search/BusRoutes.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Sliding Puzzle](src/main/java/breadth_first_search/SlidingPuzzle.java) (Hard) +- [Matrix](src/main/java/breadth_first_search/Matrix.java) (Medium) +- [Rotting Oranges](src/main/java/breadth_first_search/RottingOranges.java) (Medium) + +#### [Depth First Search](src/main/java/depth_first_search) + +- [Minesweeper](src/main/java/depth_first_search/Minesweeper.java) (Medium) +- [Movie Recommend](src/main/java/depth_first_search/MovieRecommend.java) (Medium) +- [Number Of Islands](src/main/java/depth_first_search/NumberOfIslands.java) (Medium) +- [Course Schedule](src/main/java/depth_first_search/CourseSchedule.java) (Medium) +- [Course Schedule II](src/main/java/depth_first_search/CourseScheduleII.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Alien Dictionary](src/main/java/depth_first_search/AlienDictionary.java) (Hard) +- [Graph Valid Tree](src/main/java/depth_first_search/GraphValidTree.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Longest Consecutive Sequence](src/main/java/depth_first_search/LongestConsecutiveSequence.java) (Hard) +- [Accounts Merge](src/main/java/depth_first_search/AccountsMerge.java) (Medium) +- [CloneGraph](src/main/java/depth_first_search/CloneGraph.java) (Medium) +- [Island Perimeter](src/main/java/depth_first_search/IslandPerimeter.java) (Easy) +- [Number of Distinct Islands](src/main/java/depth_first_search/NumberOfDistinctIslands.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Distinct Islands II](src/main/java/depth_first_search/NumberOfDistinctIslandsII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Rectangle Enclosing Black Pixels](src/main/java/depth_first_search/SmallestRectangleEnclosingBlackPixels.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Bricks Falling When Hit](src/main/java/depth_first_search/BricksFallingWhenHit.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Robot Room Cleaner](src/main/java/depth_first_search/RobotRoomCleaner.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cracking the Safe](src/main/java/depth_first_search/CrackingTheSafe.java) (Hard) +- [All Paths From Source to Target](src/main/java/depth_first_search/AllPathsFromSourceToTarget.java) (Medium) +- [Max Area of Island](src/main/java/depth_first_search/MaxAreaOfIsland.java) (Medium) +- [Satisfiability of Equality Equations](src/main/java/depth_first_search/SatisfiabilityOfEquations.java) (Medium) +- [Number of Enclaves](src/main/java/depth_first_search/NumberOfEnclaves.java) (Medium) +- [As Far from Land as Possible](src/main/java/depth_first_search/AsFarfromLandAsPossible.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimize Malware Spread](src/main/java/depth_first_search/MinimizeMalwareSpread.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Parallel Courses](src/main/java/depth_first_search/ParallelCourses.java) (Hard) +- [Connecting Cities With Minimum Cost](src/main/java/depth_first_search/ConnectingCitiesWithMinimumCost.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Critical Connections in a Network](src/main/java/depth_first_search/CriticalConnection.java) (Hard) + +#### [Design](src/main/java/design) + +- [Copy List With Random Pointer](src/main/java/design/CopyListWithRandomPointer.java) (Medium) +- [Encode and Decode Tiny URL](src/main/java/design/EncodeAndDecodeTinyURL.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [LFU Cache](src/main/java/design/LFUCache.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [LRU Cache](src/main/java/design/LRUCache.java) (Hard) +- [Insert Delete Get Random](src/main/java/design/RandomizedSet.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Serialize Deserialize Binary Tree](src/main/java/design/SerializeDeserializeBinaryTree.java) (Hard) +- [Design Twitter](src/main/java/design/Twitter.java) (Medium) +- [Tic-Tac-Toe](src/main/java/design/TicTacToe.java) (Medium) +- [Implement Trie (Prefix Tree)](src/main/java/design/Trie.java) (Medium) +- [Binary Search Tree Iterator](src/main/java/design/BSTIterator.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Design Search Autocomplete System](src/main/java/design/AutocompleteSystem.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Design Excel Sum Formula](src/main/java/design/Excel.java) (Hard) +- [Flatten Nested List Iterator](src/main/java/design/NestedIterator.java) (Medium) +- [Add and Search Word - Data structure design](src/main/java/design/WordDictionary.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Prefix and Suffix Search](src/main/java/design/WordFilter.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Insert Delete GetRandom O(1) - Duplicates allowed](src/main/java/design/RandomizedCollection.java) (Hard) + +#### [Divide and Conquer](src/main/java/divide_and_conquer) + +- [Kth Largest Element In a Array](src/main/java/divide_and_conquer/KthLargestElementInAnArray.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reverse Pairs](src/main/java/divide_and_conquer/ReversePairs.java) (Hard) +- [Search in a 2D Matrix](src/main/java/divide_and_conquer/SearchA2DMatrix.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [24 Game](src/main/java/divide_and_conquer/TwentyFourGame.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reverse Pairs II](src/main/java/divide_and_conquer/ReversePairsII.java) (Hard) +- [My Calendar II](src/main/java/divide_and_conquer/MyCalendarII.java) (Medium) + +#### [Dynamic Programming](src/main/java/dynamic_programming) + +- [Best Time To Buy and Sell Stocks](src/main/java/dynamic_programming/BestTimeToBuyAndSellStocks.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Best Time to Buy and Sell Stock III](src/main/java/dynamic_programming/BestTimeToBuyAndSellStockIII.java) (Hard) +- [Best Time to Buy and Sell Stock with Transaction Fee](src/main/java/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java) (Medium) +- [Climbing Stairs](src/main/java/dynamic_programming/ClimbingStairs.java) (Easy) +- [Coin Change](src/main/java/dynamic_programming/CoinChange.java) (Medium) +- [Coin Change 2](src/main/java/dynamic_programming/CoinChange2.java) (Medium) +- [Decode Ways](src/main/java/dynamic_programming/DecodeWays.java) (Medium) +- [House Robber](src/main/java/dynamic_programming/HouseRobber.java) (Easy) +- [House Robber II](src/main/java/dynamic_programming/HouseRobberII.java) (Medium) +- [Longest Increasing Subsequence](src/main/java/dynamic_programming/LongestIncreasingSubsequence.java) (Medium) +- [Longest Paliandromic Substring](src/main/java/dynamic_programming/LongestPaliandromicSubstring.java) (Medium) +- [Longest Palindromic Subsequence](src/main/java/dynamic_programming/LongestPalindromicSubsequence.java) (Medium) +- [Maximum Product Subarray](src/main/java/dynamic_programming/MaximumProductSubarray.java) (Medium) +- [Min Cost Climbing Stairs](src/main/java/dynamic_programming/MinCostClimbingStairs.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Palindrome Partitioning II](src/main/java/dynamic_programming/PalindromePartitioningII.java) (Hard) +- [UniqueBinary Search Trees](src/main/java/dynamic_programming/UniqueBinarySearchTrees.java) (Medium) +- [Unique Binary Search Trees II](src/main/java/dynamic_programming/UniqueBinarySearchTreesII.java) (Medium) +- [WordBreak](src/main/java/dynamic_programming/WordBreak.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [WordBreak II](src/main/java/dynamic_programming/WordBreakII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Concatenated Words](src/main/java/dynamic_programming/ConcatenatedWords.java) (Hard) +- [Can I Win](src/main/java/dynamic_programming/CanIWin.java) (Medium) +- [Maximum Subarray](src/main/java/dynamic_programming/MaximumSubarray.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Dungeon Game](src/main/java/dynamic_programming/DungeonGame.java) (Hard) +- [2 Keys Keyboard](src/main/java/dynamic_programming/TwoKeysKeyboard.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximum Sum of 3 Non-Overlapping Subarrays](src/main/java/dynamic_programming/MaxSum3SubArray.java) (Hard) +- [Maximal Square](src/main/java/dynamic_programming/MaximalSquare.java) (Medium) +- [Continuous Subarray Sum](src/main/java/dynamic_programming/ContinuousSubarraySum.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Decode Ways II](src/main/java/dynamic_programming/DecodeWaysII.java) (Hard) +- [Palindromic Substrings](src/main/java/dynamic_programming/PalindromicSubstrings.java) (Medium) +- [Number of Longest Increasing Subsequence](src/main/java/dynamic_programming/NumberOfLIS.java) (Medium) +- [Combination Sum IV](src/main/java/dynamic_programming/CombinationSumIV.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Paint House II](src/main/java/dynamic_programming/PaintHouseII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Split Array Largest Sum](src/main/java/dynamic_programming/SplitArrayLargestSum.java) (Hard) +- [Number Of Corner Rectangles](src/main/java/dynamic_programming/CornerRectangles.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Burst Balloons](src/main/java/dynamic_programming/BurstBalloons.java) (Hard) +- [Largest Plus Sign](src/main/java/dynamic_programming/LargestPlusSign.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Palindrome Pairs](src/main/java/dynamic_programming/PalindromePairs.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cherry Pickup](src/main/java/dynamic_programming/CherryPickup.java) (Hard) +- [Knight Probability in Chessboard](src/main/java/dynamic_programming/KnightProbabilityInChessboard.java) (Medium) +- [Largest Sum of Averages](src/main/java/dynamic_programming/LargestSumOfAverages.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Number of Refueling Stops](src/main/java/dynamic_programming/MinimumNumberOfRefuelingStops.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cat and Mouse](src/main/java/dynamic_programming/CatAndMouse.java) (Hard) +- [Stone Game](src/main/java/dynamic_programming/StoneGame.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Odd Even Jump](src/main/java/dynamic_programming/OddEvenJump.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Profitable Schemes](src/main/java/dynamic_programming/ProfitableSchemes.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximum Vacation Days](src/main/java/dynamic_programming/MaximumVacationDays.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Russian Doll Envelopes](src/main/java/dynamic_programming/RussianDollEnvelopes.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Student Attendance Record II](src/main/java/dynamic_programming/StudentAttendanceRecordII.java) (Hard) +- [Out of Boundary Paths](src/main/java/dynamic_programming/OutOfBoundaryPaths.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Remove Boxes](src/main/java/dynamic_programming/RemoveBoxes.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Stickers to Spell Word](src/main/java/dynamic_programming/StickersToSpellWord.java) (Hard) +- [Ones and Zeroes](src/main/java/dynamic_programming/OnesAndZeroes.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Encode String with Shortest Length](src/main/java/dynamic_programming/EncodeStringWithShortestLength.java) (Hard) +- [Length of Longest Fibonacci Subsequence](src/main/java/dynamic_programming/LengthofLongestFibonacciSubsequence.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Make Array Strictly Increasing](src/main/java/dynamic_programming/MakeArrayStrictlyIncreasing.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Number of Taps to Open to Water a Garden](src/main/java/dynamic_programming/MinimumNumberOfTaps.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Delete Columns to Make Sorted III](src/main/java/dynamic_programming/DeleteColumnsToMakeSortedIII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Handshakes That Don't Cross](src/main/java/dynamic_programming/HandshakesThatDontCross.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Difficulty of a Job Schedule](src/main/java/dynamic_programming/MinimumDifficultyOfAJobSchedule.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Jump Game V](src/main/java/dynamic_programming/JumpGameV.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Freedom Trail](src/main/java/dynamic_programming/FreedomTrail.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Strange Printer](src/main/java/dynamic_programming/StrangePrinter.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Cost to Merge Stones](src/main/java/dynamic_programming/MinimumCostToMergeStones.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Interleaving String](src/main/java/dynamic_programming/InterleavingString.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Count Vowels Permutation](src/main/java/dynamic_programming/CountVowelsPermutation.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Non-negative Integers without Consecutive Ones](src/main/java/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java) (Hard) +- [Bomb Enemy](src/main/java/dynamic_programming/BombEnemy.java) (Medium) +- [Number of Dice Rolls With Target Sum](src/main/java/dynamic_programming/NumberOfDiceRollsWithTargetSum.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Distinct Subsequences](src/main/java/dynamic_programming/DistinctSubsequences.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Distinct Subsequences II](src/main/java/dynamic_programming/DistinctSubsequencesII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Distance to Type a Word Using Two Fingers](src/main/java/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Valid Palindrome III](src/main/java/dynamic_programming/ValidPalindromeIII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Palindrome Partitioning III](src/main/java/dynamic_programming/PalindromePartitioningIII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Tiling a Rectangle with the Fewest Squares](src/main/java/dynamic_programming/TilingARectangle.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Longest Chunked Palindrome Decomposition](src/main/java/dynamic_programming/LongestChunkedPalindromeDecomposition.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Stone Game III](src/main/java/dynamic_programming/StoneGameIII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Ways to Stay in the Same Place After Some Steps](src/main/java/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java) (Hard) +- [Toss Strange Coins](src/main/java/dynamic_programming/TossStrangeCoins.java) (Medium) +- [Knight Dialer](src/main/java/dynamic_programming/KnightDialer.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Palindrome Removal](src/main/java/dynamic_programming/PalindromeRemoval.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Restore The Array](src/main/java/dynamic_programming/RestoreTheArray.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cherry Pickup II](src/main/java/dynamic_programming/CherryPickupII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Constrained Subsequence Sum](src/main/java/dynamic_programming/ConstrainedSubsequenceSum.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Largest Multiple of Three](src/main/java/dynamic_programming/LargestMultipleOfThree.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Largest Multiple of Three](src/main/java/dynamic_programming/MaximumProfitInJobScheduling.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Music Playlists](src/main/java/dynamic_programming/NumberOfMusicPlaylists.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Paint House III](src/main/java/dynamic_programming/PaintHouseIII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Shortest Path Visiting All Nodes](src/main/java/dynamic_programming/ShortestPathVisitingAllNodes.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Sufficient Team](src/main/java/dynamic_programming/SmallestSufficientTeam.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Stone Game IV](src/main/java/dynamic_programming/StoneGameIV.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Tallest Billboard](src/main/java/dynamic_programming/TallestBillboard.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Count Different Palindromic Subsequences](src/main/java/dynamic_programming/CountDifferentPalindromicSubsequences.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Paths with Max Score](src/main/java/dynamic_programming/NumberOfPathsWithMaxScore.java) (Hard) + + +#### [Greedy](src/main/java/greedy) + +- [Jump Game](src/main/java/greedy/JumpGame.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Jump Game II](src/main/java/greedy/JumpGameII.java) (Hard) +- [Course Schedule III](src/main/java/greedy/CourseScheduleIII.java) (Medium) +- [GasStation](src/main/java/greedy/GasStation.java) (Medium) +- [Non-Overlapping Intervals](src/main/java/greedy/NonOverlappingIntervals.java) (Medium) +- [Minimum Number of Arrows to Burst Balloons](src/main/java/greedy/BurstBalloons.java) (Medium) +- [Queue Reconstruction By Height](src/main/java/greedy/QueueReconstructionByHeight.java) (Medium) +- [Task Scheduler](src/main/java/greedy/TaskScheduler.java) (Medium) +- [Maximum Length of Pair Chain](src/main/java/greedy/MaximumLengthOfPairChain.java) (Medium) +- [Lemonade Change](src/main/java/greedy/LemonadeChange.java) (Easy) +- [Score After Flipping Matrix](src/main/java/greedy/ScoreAfterFlippingMatrix.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [IPO](src/main/java/greedy/IPO.java) (Hard) +- [String Without AAA or BBB](src/main/java/greedy/StringWithout3A3B.java) (Medium) +- [Boats to Save People](src/main/java/greedy/BoatsToSavePeople.java) (Medium) +- [Broken Calculator](src/main/java/greedy/BrokenCalculator.java) (Medium) +- [Two City Scheduling](src/main/java/greedy/TwoCityScheduling.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Time to Build Blocks](src/main/java/greedy/MinimumTimeToBuildBlocks.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reducing Dishes](src/main/java/greedy/ReducingDishes.java) (Hard) + +#### [Hashing](src/main/java/hashing) + +- [Anagrams](src/main/java/hashing/Anagrams.java) (Medium) +- [Group Anagrams](src/main/java/hashing/GroupAnagrams.java) (Medium) +- [Kdiff Pairs In a Array](src/main/java/hashing/KdiffPairsInanArray.java) (Easy) +- [Sort Character by Frequency](src/main/java/hashing/SortCharByFrequency.java) (Medium) +- [Two Sum](src/main/java/hashing/TwoSum.java) (Easy) +- [Valid Anagram](src/main/java/hashing/ValidAnagram.java) (Easy) +- [Maximum Size Subarray Sum Equals k](src/main/java/hashing/MaximumSizeSubarraySumEqualsk.java) (Medium) +- [Contiguous Array](src/main/java/hashing/ContiguousArray.java) (Medium) +- [Brick Wall](src/main/java/hashing/BrickWall.java) (Medium) +- [Partition Labels](src/main/java/hashing/PartitionLabels.java) (Medium) +- [Custom Sort String](src/main/java/hashing/CustomSortString.java) (Medium) +- [Short Encoding of Words](src/main/java/hashing/ShortEncodingOfWords.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Substring with Concatenation of All Words](src/main/java/hashing/SubstringConcatenationOfWords.java) (Hard) +- [Distribute Candies](src/main/java/hashing/DistributeCandies.java) (Easy) +- [Groups of Special-Equivalent Strings](src/main/java/hashing/GroupsOfSpecialEquivalentStrings.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Atoms](src/main/java/hashing/NumberOfAtoms.java) (Hard) +- [Analyze User Website Visit Pattern](src/main/java/hashing/AnalyzeUserWebsiteVisitPattern.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [String Transforms Into Another String](src/main/java/hashing/StringTransformsIntoAnotherString.java) (Hard) + +#### [Heap](src/main/java/heap) + +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Sliding Window Maximum](src/main/java/heap/SlidingWindowMaximum.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [The Skyline Problem](src/main/java/heap/TheSkylineProblem.java) (Hard) +- [Meeting Rooms II](src/main/java/heap/MeetingRoomsII.java) (Medium) +- [Top K Frequent Words](src/main/java/heap/TopKFrequentWords.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Candy](src/main/java/heap/Candy.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Rotation with Highest Score](src/main/java/heap/SmallestRotationWithHighestScore.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximum Frequency Stack](src/main/java/heap/FreqStack.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reachable Nodes In Subdivided Graph](src/main/java/heap/ReachableNodesInSubdividedGraph.java) (Hard) +- [K Closest Points to Origin](src/main/java/heap/KClosestPointsToOrigin.java) (Medium) +- [Distant Barcodes](src/main/java/heap/DistantBarcodes.java) (Medium) + +#### [Linked List](src/main/java/linked_list) + +- [Intersection of two Linked-Lists](src/main/java/linked_list/IntersectionOfTwoLists.java) (Easy) +- [Linked List Cycle](src/main/java/linked_list/LinkedListCycle.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Merge K Sorted Lists](src/main/java/linked_list/MergeKSortedLists.java) (Hard) +- [Merge Two Sorted List](src/main/java/linked_list/MergeTwoSortedList.java) (Easy) +- [Paliandrome List](src/main/java/linked_list/PaliandromeList.java) (Easy) +- [Reverse Linked List](src/main/java/linked_list/ReverseLinkedList.java) (Easy) +- [Delete Node in a Linked List](src/main/java/linked_list/DeleteNode.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reverse Nodes in k-Group](src/main/java/linked_list/ReverseNodesKGroup.java) (Hard) +- [Swap Nodes in Pairs](src/main/java/linked_list/SwapNodesInPairs.java) (Medium) +- [Middle of Linked List](src/main/java/linked_list/MiddleOfLinkedList.java) (Easy) +- [Split Linked List in Parts](src/main/java/linked_list/SplitLinkedListInParts.java) (Medium) +- [Next Greater Node In Linked List](src/main/java/linked_list/NextGreaterNodeInLinkedList.java) (Medium) + +#### [Math](src/main/java/math) + +- [Add Two Numbers](src/main/java/math/AddTwoNumbers.java) (Medium) +- [Count Primes](src/main/java/math/CountPrimes.java) (Easy) +- [Rotate Function](src/main/java/math/RotateFunction.java) (Medium) +- [Water and Jug Problem](src/main/java/math/WaterAndJugProblem.java) (Medium) +- [Add Digits](src/main/java/math/AddDigits.java) (Easy) +- [Excel Sheet Column Title](src/main/java/math/ExcelSheetColumnTitle.java) (Easy) +- [Roman to Integer](src/main/java/math/RomanToInteger.java) (Easy) +- [Bulb Switcher II](src/main/java/math/BulbSwitcherII.java) (Medium) +- [Global and Local Inversions](src/main/java/math/GlobalAndLocalInversions.java) (Medium) +- [Solve the Equation](src/main/java/math/SolveTheEquation.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Couples Holding Hands](src/main/java/math/CouplesHoldingHands.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reaching Points](src/main/java/math/ReachingPoints.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Nth Magical Number](src/main/java/math/NthMagicalNumber.java) (Hard) +- [Squirrel Simulation](src/main/java/math/SquirrelSimulation.java) (Medium) +- [Projection Area of 3D Shapes](src/main/java/math/ProjectionAreaOf3DShapes.java) (Easy) +- [Decoded String at Index](src/main/java/math/DecodedStringAtIndex.java) (Medium) +- [Base 7](src/main/java/math/Base7.java) (Easy) +- [Smallest Range I](src/main/java/math/SmallestRangeI.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Largest Component Size by Common Factor](src/main/java/math/LargestComponentSizebyCommonFactor.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Super Washing Machines](src/main/java/math/SuperWashingMachines.java) (Hard) +- [Rectangle Overlap](src/main/java/math/RectangleOverlap.java) (Easy) +- [Nth Digit](src/main/java/math/NthDigit.java) (Easy) + +#### [Reservoir Sampling](src/main/java/reservoir_sampling) + +- [Random Pick Index](src/main/java/reservoir_sampling/RandomPickIndex.java) (Medium) + +#### [Stack](src/main/java/stack) + +- [Min Stack](src/main/java/stack/MinStack.java) (Easy) +- [Valid Parentheses](src/main/java/stack/ValidParentheses.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Largest Rectangle In Histogram](src/main/java/stack/LargestRectangleInHistogram.java) (Hard) +- [Implement Queue using Stacks](src/main/java/stack/MyQueue.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximal Rectangle](src/main/java/stack/MaximalRectangle.java) (Hard) +- [Exclusive Time of Functions](src/main/java/stack/ExclusiveTimeOfFunctions.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Basic Calculator](src/main/java/stack/BasicCalculator.java) (Hard) +- [Decode String](src/main/java/stack/DecodeString.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Longest Valid Parentheses](src/main/java/stack/LongestValidParentheses.java) (Hard) + + +#### [String](src/main/java/string) + +- [First Unique Character In a String](src/main/java/string/FirstUniqueCharacterInAString.java) (Easy) +- [Repeated Substring Pattern](src/main/java/string/RepeatedSubstringPattern.java) (Easy) +- [Reverse Words In a String](src/main/java/string/ReverseWordsInAString.java) (Medium) +- [ReverseWords II](src/main/java/string/ReverseWordsII.java) (Medium) +- [String to Integer](src/main/java/string/StringToInteger.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Text Justification](src/main/java/string/TextJustification.java) (Hard) +- [ZigZag Conversion](src/main/java/string/ZigZagConversion.java) (Medium) +- [Implement StrStr](src/main/java/string/ImplementStrStr.java) (Easy) +- [Excel Sheet Column Number](src/main/java/string/ExcelSheetColumnNumber.java) (Easy) +- [Compare Version Numbers](src/main/java/string/CompareVersionNumbers.java) (Easy) +- [Valid Palindrome](src/main/java/string/ValidPalindrome.java) (Easy) +- [Simplify Path](src/main/java/string/SimplifyPath.java) (Medium) +- [Permutation in String](src/main/java/string/PermutationInString.java) (Medium) +- [Add Binary](src/main/java/string/AddBinary.java) (Easy) +- [Valid Palindrome II](src/main/java/string/ValidPalindromeII.java) (Easy) +- [One Edit Distance](src/main/java/string/OneEditDistance.java) (Medium) +- [Count and Say](src/main/java/string/CountAndSay.java) (Easy) +- [Multiply Strings](src/main/java/string/MultiplyStrings.java) (Medium) +- [Longest Word in Dictionary through Deleting](src/main/java/string/LongestWordInDictonary.java) (Medium) +- [Isomorphic Strings](src/main/java/string/IsomorphicStrings.java) (Easy) +- [String Compression](src/main/java/string/StringCompression.java) (Easy) +- [Longest Common Prefix](src/main/java/string/LongestCommonPrefix.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Find the Closest Palindrome](src/main/java/string/FindTheClosestPalindrome.java) (Hard) +- [Monotone Increasing Digits](src/main/java/string/MonotoneIncreasingDigits.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Shortest Palindrome](src/main/java/string/ShortestPalindrome.java) (Hard) +- [Valid Word Abbreviation](src/main/java/string/ValidWordAbbreviation.java) (Easy) +- [Longest Palindrome](src/main/java/string/LongestPalindrome.java) (Easy) +- [Replace Words](src/main/java/string/ReplaceWords.java) (Medium) +- [Rotate String](src/main/java/string/RotateString.java) (Easy) +- [Keyboard Row](src/main/java/string/KeyboardRow.java) (Easy) +- [Student Attendance Record I](src/main/java/string/StudentAttendanceRecordI.java) (Easy) +- [Split Concatenated Strings](src/main/java/string/SplitConcatenatedStrings.java) (Medium) +- [Valid Word Square](src/main/java/string/ValidWordSquare.java) (Easy) +- [Reconstruct Original Digits from English](src/main/java/string/ReconstructOriginalDigitsFromEnglish.java) (Medium) +- [Push Dominoes](src/main/java/string/PushDominoes.java) (Medium) +- [Validate IP Address](src/main/java/string/ValidateIPAddress.java) (Medium) +- [Reverse String II](src/main/java/string/ReverseStringII.java) (Easy) +- [Find Words That Can Be Formed by Characters](src/main/java/string/FindWordsThatCanBeFormedbyCharacters.java) (Easy) +- [Minimum Add to Make Parentheses Valid](src/main/java/string/MinimumAddtoMakeParenthesesValid.java) (Medium) + +#### [Tree](src/main/java/tree) + +- [Binaray Tree Right Side View](src/main/java/tree/BinarayTreeRightSideView.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Binary Tree Maximum Path Sum](src/main/java/tree/BinaryTreeMaximumPathSum.java) (Hard) +- [Boundary of Binary Tree](src/main/java/tree/BoundaryOfBinaryTree.java) (Medium) +- [Convert sorted array to BST](src/main/java/tree/ConvertSortedArrayToBST.java) (Medium) +- [Lowest Common Ancestor of a Binary Tree](src/main/java/tree/LCA.java) (Medium) +- [Lowest Common Ancestor of a BST](src/main/java/tree/LowestCommonAncestorBST.java) (Easy) +- [Most Frequent Subtree Sum](src/main/java/tree/MostFrequentSubtreeSum.java) (Medium) +- [Path Sum III](src/main/java/tree/PathSumIII.java) (Easy) +- [Convert Postorder and Inorder traversal to Binary Tree](src/main/java/tree/PostorderToBT.java) (Medium) +- [Convert Preorder and Inorder traversal to Binary Tree](src/main/java/tree/PreorderToBT.java) (Medium) +- [Sorted Array to BST](src/main/java/tree/SortedArrayToBST.java) (Medium) +- [Valid Binary Search Tree](src/main/java/tree/ValidBinarySearchTree.java) (Medium) +- [Largest BST Subtree](src/main/java/tree/LargestBSTSubtree.java) (Medium) +- [Closest Binary Search Tree Value](src/main/java/tree/ClosestBinarySearchTreeValue.java) (Easy) +- [Inorder Successor in BST](src/main/java/tree/InorderSuccessorInBST.java) (Medium) +- [Construct String From Binary Tree](src/main/java/tree/ConstructStringFromBinaryTree.java) (Easy) +- [Flatten Binary Tree to Linked List](src/main/java/tree/FlattenBinaryTree.java) (Medium) +- [Populating Next Right Pointers in Each Node](src/main/java/tree/NextRightPointer.java) (Medium) +- [Populating Next Right Pointers in Each Node II](src/main/java/tree/NextRightPointerII.java) (Medium) +- [Subtree of Another Tree](src/main/java/tree/SubtreeOfAnotherTree.java) (Easy) +- [Binary Tree Zigzag Level Order Traversal](src/main/java/tree/ZigZagTraversal.java) (Medium) +- [Binary Tree Inorder Traversal](src/main/java/tree/BinaryTreeInorderTraversal.java) (Medium) +- [Symmetric Tree](src/main/java/tree/SymmetricTree.java) (Easy) +- [Maximum Binary Tree](src/main/java/tree/MaximumBinaryTree.java) (Medium) +- [Find Bottom Left Tree Value](src/main/java/tree/FindBottomLeftTreeValue.java) (Medium) +- [Diameter of Binary Tree](src/main/java/tree/DiameterOfBinaryTree.java) (Easy) +- [Binary Tree Paths](src/main/java/tree/BinaryTreePaths.java) (Easy) +- [Sum of Left Leaves](src/main/java/tree/SumofLeftLeaves.java) (Easy) +- [Two Sum IV - Input is a BST](src/main/java/tree/TwoSumIV.java) (Easy) +- [Average of Levels in Binary Tree](src/main/java/tree/AverageOfLevelsInBinaryTree.java) (Easy) +- [Convert Binary Search Tree to Sorted Doubly Linked List](src/main/java/tree/BSTtoDoublyLinkedList.java) (Easy) +- [Same Tree](src/main/java/tree/SameTree.java) (Easy) +- [Binary Tree Longest Consecutive SequencefindMinDifference II](src/main/java/tree/BinaryTreeLongestConsecutiveSequenceII.java) (Medium) +- [Minimum Absolute Difference in BST](src/main/java/tree/MinimumAbsoluteDifferenceInBST.java) (Medium) +- [Equal Tree Partition](src/main/java/tree/EqualTreePartition.java) (Medium) +- [Split BST](src/main/java/tree/SplitBST.java) (Medium) +- [Closest Leaf in a Binary Tree](src/main/java/tree/ClosestLeafInABinaryTree.java) (Medium) +- [Maximum Width of Binary Tree](src/main/java/tree/MaximumWidthOfBinaryTree.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Recover Binary Search Tree](src/main/java/tree/RecoverBinarySearchTree.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Binary Tree Postorder Traversal](src/main/java/tree/BinaryTreePostorderTraversal.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Serialize and Deserialize N-ary Tree](src/main/java/tree/SerializeAndDeserializeNAryTree.java) (Hard) +- [Convert BST to Greater Tree](src/main/java/tree/ConvertBSTToGreaterTree.java) (Easy) +- [All Nodes Distance K in Binary Tree](src/main/java/tree/AllNodesDistanceKInBinaryTree.java) (Medium) +- [All Possible Full Binary Trees](src/main/java/tree/AllPossibleFullBinaryTrees.java) (Medium) +- [Flip Equivalent Binary Trees](src/main/java/tree/FlipEquivalentBinaryTrees.java) (Medium) +- [Construct Binary Tree from String](src/main/java/tree/ConstructBinaryTreefromString.java) (Medium) +- [Find Largest Value in Each Tree Row](src/main/java/tree/FindLargestValueInEachTreeRow.java) (Medium) +- [Find Bottom Left Tree Value](src/main/java/tree/FindBottomLeftTreeValue.java) (Medium) +- [Maximum Level Sum of a Binary Tree](src/main/java/tree/MaximumLevelSumofABinaryTree.java) (Medium) +- [Leaf-Similar Trees](src/main/java/tree/LeafSimilarTrees.java) (Easy) +- [Binary Tree Tilt](src/main/java/tree/BinaryTreeTilt.java) (Easy) + +#### [Two Pointers](src/main/java/two_pointers) + +- [Four Sum](src/main/java/two_pointers/FourSum.java) (Medium) +- [Longest Substring Witout Repeats](src/main/java/two_pointers/LongestSubstringWitoutRepeats.java) (Medium) +- [Three Sum](src/main/java/two_pointers/ThreeSum.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Trapping Rain Water](src/main/java/two_pointers/TrappingRainWater.java) (Hard) +- [3Sum Closest](src/main/java/two_pointers/ThreeSumClosest.java) (Medium) +- [Move Zeroes](src/main/java/two_pointers/MoveZeroes.java) (Easy) +- [Remove Duplicates](src/main/java/two_pointers/RemoveDuplicates.java) (Easy) +- [Remove Duplicates II](src/main/java/two_pointers/RemoveDuplicatesII.java) (Medium) +- [Minimum Size Subarray Sum](src/main/java/two_pointers/MinimumSizeSubarraySum.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Window Substring](src/main/java/two_pointers/MinimumWindowSubstring.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Range](src/main/java/two_pointers/SmallestRange.java) (Hard) +- [Subarray Product Less Than K](src/main/java/two_pointers/SubarrayProductLessThanK.java) (Medium) +- [Number of Matching Subsequences](src/main/java/two_pointers/NumberOfMatchingSubsequences.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Subarrays with K Different Integers](src/main/java/two_pointers/SubarraysWithKDifferentIntegers.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Last Substring in Lexicographical Order](src/main/java/two_pointers/LastSubstringInLexicographicalOrder.java) (Hard) diff --git a/build.gradle b/build.gradle index 397f2517..22aa07b4 100644 --- a/build.gradle +++ b/build.gradle @@ -8,5 +8,5 @@ dependencies { } repositories { - jcenter() // or mavenCentral() + mavenCentral() } \ No newline at end of file diff --git a/problems/src/array/AddToArrayFormOfInteger.java b/src/main/java/array/AddToArrayFormOfInteger.java similarity index 100% rename from problems/src/array/AddToArrayFormOfInteger.java rename to src/main/java/array/AddToArrayFormOfInteger.java diff --git a/problems/src/array/ArrayNesting.java b/src/main/java/array/ArrayNesting.java similarity index 100% rename from problems/src/array/ArrayNesting.java rename to src/main/java/array/ArrayNesting.java diff --git a/problems/src/array/ArrayPartitionI.java b/src/main/java/array/ArrayPartitionI.java similarity index 100% rename from problems/src/array/ArrayPartitionI.java rename to src/main/java/array/ArrayPartitionI.java diff --git a/problems/src/array/BattleshipsInABoard.java b/src/main/java/array/BattleshipsInABoard.java similarity index 100% rename from problems/src/array/BattleshipsInABoard.java rename to src/main/java/array/BattleshipsInABoard.java diff --git a/problems/src/array/BestMeetingPoint.java b/src/main/java/array/BestMeetingPoint.java similarity index 100% rename from problems/src/array/BestMeetingPoint.java rename to src/main/java/array/BestMeetingPoint.java diff --git a/problems/src/array/CanPlaceFlowers.java b/src/main/java/array/CanPlaceFlowers.java similarity index 100% rename from problems/src/array/CanPlaceFlowers.java rename to src/main/java/array/CanPlaceFlowers.java diff --git a/problems/src/array/CardFilipGame.java b/src/main/java/array/CardFilipGame.java similarity index 100% rename from problems/src/array/CardFilipGame.java rename to src/main/java/array/CardFilipGame.java diff --git a/problems/src/array/ChampagneTower.java b/src/main/java/array/ChampagneTower.java similarity index 100% rename from problems/src/array/ChampagneTower.java rename to src/main/java/array/ChampagneTower.java diff --git a/problems/src/array/EmployeeFreeTime.java b/src/main/java/array/EmployeeFreeTime.java similarity index 100% rename from problems/src/array/EmployeeFreeTime.java rename to src/main/java/array/EmployeeFreeTime.java diff --git a/problems/src/array/FindPivotIndex.java b/src/main/java/array/FindPivotIndex.java similarity index 100% rename from problems/src/array/FindPivotIndex.java rename to src/main/java/array/FindPivotIndex.java diff --git a/problems/src/array/FindTheCelebrity.java b/src/main/java/array/FindTheCelebrity.java similarity index 100% rename from problems/src/array/FindTheCelebrity.java rename to src/main/java/array/FindTheCelebrity.java diff --git a/problems/src/array/FirstMissingPositive.java b/src/main/java/array/FirstMissingPositive.java similarity index 100% rename from problems/src/array/FirstMissingPositive.java rename to src/main/java/array/FirstMissingPositive.java diff --git a/problems/src/array/FruitIntoBaskets.java b/src/main/java/array/FruitIntoBaskets.java similarity index 100% rename from problems/src/array/FruitIntoBaskets.java rename to src/main/java/array/FruitIntoBaskets.java diff --git a/problems/src/array/HIndex.java b/src/main/java/array/HIndex.java similarity index 100% rename from problems/src/array/HIndex.java rename to src/main/java/array/HIndex.java diff --git a/problems/src/array/ImageSmoother.java b/src/main/java/array/ImageSmoother.java similarity index 100% rename from problems/src/array/ImageSmoother.java rename to src/main/java/array/ImageSmoother.java diff --git a/problems/src/array/IncreasingTripletSubsequence.java b/src/main/java/array/IncreasingTripletSubsequence.java similarity index 100% rename from problems/src/array/IncreasingTripletSubsequence.java rename to src/main/java/array/IncreasingTripletSubsequence.java diff --git a/problems/src/array/InsertInterval.java b/src/main/java/array/InsertInterval.java similarity index 100% rename from problems/src/array/InsertInterval.java rename to src/main/java/array/InsertInterval.java diff --git a/problems/src/array/KEmptySlots.java b/src/main/java/array/KEmptySlots.java similarity index 100% rename from problems/src/array/KEmptySlots.java rename to src/main/java/array/KEmptySlots.java diff --git a/problems/src/array/LargestNumberAtLeastTwice.java b/src/main/java/array/LargestNumberAtLeastTwice.java similarity index 100% rename from problems/src/array/LargestNumberAtLeastTwice.java rename to src/main/java/array/LargestNumberAtLeastTwice.java diff --git a/problems/src/array/LargestTimeForGivenDigits.java b/src/main/java/array/LargestTimeForGivenDigits.java similarity index 100% rename from problems/src/array/LargestTimeForGivenDigits.java rename to src/main/java/array/LargestTimeForGivenDigits.java diff --git a/problems/src/array/LongestIncreasingSubsequence.java b/src/main/java/array/LongestIncreasingSubsequence.java similarity index 100% rename from problems/src/array/LongestIncreasingSubsequence.java rename to src/main/java/array/LongestIncreasingSubsequence.java diff --git a/problems/src/array/LongestLineofConsecutiveOneinMatrix.java b/src/main/java/array/LongestLineofConsecutiveOneinMatrix.java similarity index 100% rename from problems/src/array/LongestLineofConsecutiveOneinMatrix.java rename to src/main/java/array/LongestLineofConsecutiveOneinMatrix.java diff --git a/problems/src/array/MatrixCellsinDistanceOrder.java b/src/main/java/array/MatrixCellsinDistanceOrder.java similarity index 100% rename from problems/src/array/MatrixCellsinDistanceOrder.java rename to src/main/java/array/MatrixCellsinDistanceOrder.java diff --git a/problems/src/array/MaxConsecutiveOnes.java b/src/main/java/array/MaxConsecutiveOnes.java similarity index 100% rename from problems/src/array/MaxConsecutiveOnes.java rename to src/main/java/array/MaxConsecutiveOnes.java diff --git a/problems/src/array/MaxConsecutiveOnesII.java b/src/main/java/array/MaxConsecutiveOnesII.java similarity index 100% rename from problems/src/array/MaxConsecutiveOnesII.java rename to src/main/java/array/MaxConsecutiveOnesII.java diff --git a/problems/src/array/MaxProductOfThreeNumbers.java b/src/main/java/array/MaxProductOfThreeNumbers.java similarity index 100% rename from problems/src/array/MaxProductOfThreeNumbers.java rename to src/main/java/array/MaxProductOfThreeNumbers.java diff --git a/problems/src/array/MaximumSumofTwoNonOverlappingSubarrays.java b/src/main/java/array/MaximumSumofTwoNonOverlappingSubarrays.java similarity index 100% rename from problems/src/array/MaximumSumofTwoNonOverlappingSubarrays.java rename to src/main/java/array/MaximumSumofTwoNonOverlappingSubarrays.java diff --git a/problems/src/array/MaximumSwap.java b/src/main/java/array/MaximumSwap.java similarity index 100% rename from problems/src/array/MaximumSwap.java rename to src/main/java/array/MaximumSwap.java diff --git a/problems/src/array/MeetingRooms.java b/src/main/java/array/MeetingRooms.java similarity index 100% rename from problems/src/array/MeetingRooms.java rename to src/main/java/array/MeetingRooms.java diff --git a/problems/src/array/MeetingScheduler.java b/src/main/java/array/MeetingScheduler.java similarity index 100% rename from problems/src/array/MeetingScheduler.java rename to src/main/java/array/MeetingScheduler.java diff --git a/problems/src/array/MergeIntervals.java b/src/main/java/array/MergeIntervals.java similarity index 100% rename from problems/src/array/MergeIntervals.java rename to src/main/java/array/MergeIntervals.java diff --git a/problems/src/array/MergeSortedArray.java b/src/main/java/array/MergeSortedArray.java similarity index 100% rename from problems/src/array/MergeSortedArray.java rename to src/main/java/array/MergeSortedArray.java diff --git a/problems/src/array/MinimumIndexSumOfTwoLists.java b/src/main/java/array/MinimumIndexSumOfTwoLists.java similarity index 100% rename from problems/src/array/MinimumIndexSumOfTwoLists.java rename to src/main/java/array/MinimumIndexSumOfTwoLists.java diff --git a/problems/src/array/MinimumMovesToEqualArray.java b/src/main/java/array/MinimumMovesToEqualArray.java similarity index 100% rename from problems/src/array/MinimumMovesToEqualArray.java rename to src/main/java/array/MinimumMovesToEqualArray.java diff --git a/problems/src/array/MinimumSwapsToGroupAll1Together.java b/src/main/java/array/MinimumSwapsToGroupAll1Together.java similarity index 100% rename from problems/src/array/MinimumSwapsToGroupAll1Together.java rename to src/main/java/array/MinimumSwapsToGroupAll1Together.java diff --git a/problems/src/array/MinimumTimeDifference.java b/src/main/java/array/MinimumTimeDifference.java similarity index 100% rename from problems/src/array/MinimumTimeDifference.java rename to src/main/java/array/MinimumTimeDifference.java diff --git a/problems/src/array/MissingNumber.java b/src/main/java/array/MissingNumber.java similarity index 100% rename from problems/src/array/MissingNumber.java rename to src/main/java/array/MissingNumber.java diff --git a/problems/src/array/MyCalendarThree.java b/src/main/java/array/MyCalendarThree.java similarity index 100% rename from problems/src/array/MyCalendarThree.java rename to src/main/java/array/MyCalendarThree.java diff --git a/problems/src/array/NextGreaterElementI.java b/src/main/java/array/NextGreaterElementI.java similarity index 100% rename from problems/src/array/NextGreaterElementI.java rename to src/main/java/array/NextGreaterElementI.java diff --git a/problems/src/array/PascalsTriangle.java b/src/main/java/array/PascalsTriangle.java similarity index 100% rename from problems/src/array/PascalsTriangle.java rename to src/main/java/array/PascalsTriangle.java diff --git a/problems/src/array/PourWater.java b/src/main/java/array/PourWater.java similarity index 100% rename from problems/src/array/PourWater.java rename to src/main/java/array/PourWater.java diff --git a/problems/src/array/ProductOfArrayExceptSelf.java b/src/main/java/array/ProductOfArrayExceptSelf.java similarity index 100% rename from problems/src/array/ProductOfArrayExceptSelf.java rename to src/main/java/array/ProductOfArrayExceptSelf.java diff --git a/problems/src/array/ReadNCharacters.java b/src/main/java/array/ReadNCharacters.java similarity index 100% rename from problems/src/array/ReadNCharacters.java rename to src/main/java/array/ReadNCharacters.java diff --git a/problems/src/array/RelativeRanks.java b/src/main/java/array/RelativeRanks.java similarity index 100% rename from problems/src/array/RelativeRanks.java rename to src/main/java/array/RelativeRanks.java diff --git a/problems/src/array/RelativeSortArray.java b/src/main/java/array/RelativeSortArray.java similarity index 100% rename from problems/src/array/RelativeSortArray.java rename to src/main/java/array/RelativeSortArray.java diff --git a/problems/src/array/RevealCardsInIncreasingOrder.java b/src/main/java/array/RevealCardsInIncreasingOrder.java similarity index 100% rename from problems/src/array/RevealCardsInIncreasingOrder.java rename to src/main/java/array/RevealCardsInIncreasingOrder.java diff --git a/problems/src/array/RotateArray.java b/src/main/java/array/RotateArray.java similarity index 100% rename from problems/src/array/RotateArray.java rename to src/main/java/array/RotateArray.java diff --git a/problems/src/array/RotateMatrix.java b/src/main/java/array/RotateMatrix.java similarity index 100% rename from problems/src/array/RotateMatrix.java rename to src/main/java/array/RotateMatrix.java diff --git a/problems/src/array/SetMatrixZeroes.java b/src/main/java/array/SetMatrixZeroes.java similarity index 100% rename from problems/src/array/SetMatrixZeroes.java rename to src/main/java/array/SetMatrixZeroes.java diff --git a/problems/src/array/SortArrayByParityII.java b/src/main/java/array/SortArrayByParityII.java similarity index 100% rename from problems/src/array/SortArrayByParityII.java rename to src/main/java/array/SortArrayByParityII.java diff --git a/problems/src/array/SortColors.java b/src/main/java/array/SortColors.java similarity index 100% rename from problems/src/array/SortColors.java rename to src/main/java/array/SortColors.java diff --git a/problems/src/array/SparseMatrixMultiplication.java b/src/main/java/array/SparseMatrixMultiplication.java similarity index 100% rename from problems/src/array/SparseMatrixMultiplication.java rename to src/main/java/array/SparseMatrixMultiplication.java diff --git a/problems/src/array/SubArraysWithBoundedMaximum.java b/src/main/java/array/SubArraysWithBoundedMaximum.java similarity index 100% rename from problems/src/array/SubArraysWithBoundedMaximum.java rename to src/main/java/array/SubArraysWithBoundedMaximum.java diff --git a/problems/src/array/SubarraySumEqualsK.java b/src/main/java/array/SubarraySumEqualsK.java similarity index 100% rename from problems/src/array/SubarraySumEqualsK.java rename to src/main/java/array/SubarraySumEqualsK.java diff --git a/problems/src/array/SurfaceAreaOfThreeDShapes.java b/src/main/java/array/SurfaceAreaOfThreeDShapes.java similarity index 100% rename from problems/src/array/SurfaceAreaOfThreeDShapes.java rename to src/main/java/array/SurfaceAreaOfThreeDShapes.java diff --git a/problems/src/array/ThirdMaximumNumber.java b/src/main/java/array/ThirdMaximumNumber.java similarity index 100% rename from problems/src/array/ThirdMaximumNumber.java rename to src/main/java/array/ThirdMaximumNumber.java diff --git a/problems/src/array/TwoSum.java b/src/main/java/array/TwoSum.java similarity index 100% rename from problems/src/array/TwoSum.java rename to src/main/java/array/TwoSum.java diff --git a/problems/src/array/TwoSumII.java b/src/main/java/array/TwoSumII.java similarity index 100% rename from problems/src/array/TwoSumII.java rename to src/main/java/array/TwoSumII.java diff --git a/problems/src/array/ValidTicTacToeState.java b/src/main/java/array/ValidTicTacToeState.java similarity index 100% rename from problems/src/array/ValidTicTacToeState.java rename to src/main/java/array/ValidTicTacToeState.java diff --git a/problems/src/backtracking/CombinationSum.java b/src/main/java/backtracking/CombinationSum.java similarity index 100% rename from problems/src/backtracking/CombinationSum.java rename to src/main/java/backtracking/CombinationSum.java diff --git a/problems/src/backtracking/CombinationSumII.java b/src/main/java/backtracking/CombinationSumII.java similarity index 100% rename from problems/src/backtracking/CombinationSumII.java rename to src/main/java/backtracking/CombinationSumII.java diff --git a/problems/src/backtracking/Combinations.java b/src/main/java/backtracking/Combinations.java similarity index 100% rename from problems/src/backtracking/Combinations.java rename to src/main/java/backtracking/Combinations.java diff --git a/problems/src/backtracking/ExpressionAddOperators.java b/src/main/java/backtracking/ExpressionAddOperators.java similarity index 100% rename from problems/src/backtracking/ExpressionAddOperators.java rename to src/main/java/backtracking/ExpressionAddOperators.java diff --git a/problems/src/backtracking/GenerateParentheses.java b/src/main/java/backtracking/GenerateParentheses.java similarity index 100% rename from problems/src/backtracking/GenerateParentheses.java rename to src/main/java/backtracking/GenerateParentheses.java diff --git a/problems/src/backtracking/LetterCasePermutation.java b/src/main/java/backtracking/LetterCasePermutation.java similarity index 100% rename from problems/src/backtracking/LetterCasePermutation.java rename to src/main/java/backtracking/LetterCasePermutation.java diff --git a/problems/src/backtracking/LetterPhoneNumber.java b/src/main/java/backtracking/LetterPhoneNumber.java similarity index 100% rename from problems/src/backtracking/LetterPhoneNumber.java rename to src/main/java/backtracking/LetterPhoneNumber.java diff --git a/problems/src/backtracking/MatchsticksToSquare.java b/src/main/java/backtracking/MatchsticksToSquare.java similarity index 100% rename from problems/src/backtracking/MatchsticksToSquare.java rename to src/main/java/backtracking/MatchsticksToSquare.java diff --git a/problems/src/backtracking/PalindromePartitioning.java b/src/main/java/backtracking/PalindromePartitioning.java similarity index 100% rename from problems/src/backtracking/PalindromePartitioning.java rename to src/main/java/backtracking/PalindromePartitioning.java diff --git a/problems/src/backtracking/Permutations.java b/src/main/java/backtracking/Permutations.java similarity index 100% rename from problems/src/backtracking/Permutations.java rename to src/main/java/backtracking/Permutations.java diff --git a/problems/src/backtracking/PermutationsII.java b/src/main/java/backtracking/PermutationsII.java similarity index 100% rename from problems/src/backtracking/PermutationsII.java rename to src/main/java/backtracking/PermutationsII.java diff --git a/problems/src/backtracking/RegularExpressionMatching.java b/src/main/java/backtracking/RegularExpressionMatching.java similarity index 100% rename from problems/src/backtracking/RegularExpressionMatching.java rename to src/main/java/backtracking/RegularExpressionMatching.java diff --git a/problems/src/backtracking/RemoveInvalidParentheses.java b/src/main/java/backtracking/RemoveInvalidParentheses.java similarity index 100% rename from problems/src/backtracking/RemoveInvalidParentheses.java rename to src/main/java/backtracking/RemoveInvalidParentheses.java diff --git a/problems/src/backtracking/Subsets.java b/src/main/java/backtracking/Subsets.java similarity index 100% rename from problems/src/backtracking/Subsets.java rename to src/main/java/backtracking/Subsets.java diff --git a/problems/src/backtracking/SubsetsII.java b/src/main/java/backtracking/SubsetsII.java similarity index 100% rename from problems/src/backtracking/SubsetsII.java rename to src/main/java/backtracking/SubsetsII.java diff --git a/problems/src/backtracking/TargetSum.java b/src/main/java/backtracking/TargetSum.java similarity index 100% rename from problems/src/backtracking/TargetSum.java rename to src/main/java/backtracking/TargetSum.java diff --git a/problems/src/backtracking/WildcardMatching.java b/src/main/java/backtracking/WildcardMatching.java similarity index 100% rename from problems/src/backtracking/WildcardMatching.java rename to src/main/java/backtracking/WildcardMatching.java diff --git a/problems/src/backtracking/WordSearch.java b/src/main/java/backtracking/WordSearch.java similarity index 100% rename from problems/src/backtracking/WordSearch.java rename to src/main/java/backtracking/WordSearch.java diff --git a/problems/src/backtracking/WordSearchII.java b/src/main/java/backtracking/WordSearchII.java similarity index 100% rename from problems/src/backtracking/WordSearchII.java rename to src/main/java/backtracking/WordSearchII.java diff --git a/problems/src/backtracking/ZumaGame.java b/src/main/java/backtracking/ZumaGame.java similarity index 100% rename from problems/src/backtracking/ZumaGame.java rename to src/main/java/backtracking/ZumaGame.java diff --git a/problems/src/binary_search/ArmstrongNumber.java b/src/main/java/binary_search/ArmstrongNumber.java similarity index 100% rename from problems/src/binary_search/ArmstrongNumber.java rename to src/main/java/binary_search/ArmstrongNumber.java diff --git a/problems/src/binary_search/FindPeakElement.java b/src/main/java/binary_search/FindPeakElement.java similarity index 100% rename from problems/src/binary_search/FindPeakElement.java rename to src/main/java/binary_search/FindPeakElement.java diff --git a/problems/src/binary_search/FirstBadVersion.java b/src/main/java/binary_search/FirstBadVersion.java similarity index 100% rename from problems/src/binary_search/FirstBadVersion.java rename to src/main/java/binary_search/FirstBadVersion.java diff --git a/problems/src/binary_search/HIndexII.java b/src/main/java/binary_search/HIndexII.java similarity index 100% rename from problems/src/binary_search/HIndexII.java rename to src/main/java/binary_search/HIndexII.java diff --git a/problems/src/binary_search/KokoEatingBananas.java b/src/main/java/binary_search/KokoEatingBananas.java similarity index 100% rename from problems/src/binary_search/KokoEatingBananas.java rename to src/main/java/binary_search/KokoEatingBananas.java diff --git a/problems/src/binary_search/MedianOfTwoSortedArrays.java b/src/main/java/binary_search/MedianOfTwoSortedArrays.java similarity index 100% rename from problems/src/binary_search/MedianOfTwoSortedArrays.java rename to src/main/java/binary_search/MedianOfTwoSortedArrays.java diff --git a/problems/src/binary_search/MinSortedRotatedArray.java b/src/main/java/binary_search/MinSortedRotatedArray.java similarity index 100% rename from problems/src/binary_search/MinSortedRotatedArray.java rename to src/main/java/binary_search/MinSortedRotatedArray.java diff --git a/problems/src/binary_search/MinimumWindowSubsequence.java b/src/main/java/binary_search/MinimumWindowSubsequence.java similarity index 100% rename from problems/src/binary_search/MinimumWindowSubsequence.java rename to src/main/java/binary_search/MinimumWindowSubsequence.java diff --git a/problems/src/binary_search/PowXN.java b/src/main/java/binary_search/PowXN.java similarity index 100% rename from problems/src/binary_search/PowXN.java rename to src/main/java/binary_search/PowXN.java diff --git a/problems/src/binary_search/SearchForARange.java b/src/main/java/binary_search/SearchForARange.java similarity index 100% rename from problems/src/binary_search/SearchForARange.java rename to src/main/java/binary_search/SearchForARange.java diff --git a/problems/src/binary_search/SearchInsertPosition.java b/src/main/java/binary_search/SearchInsertPosition.java similarity index 100% rename from problems/src/binary_search/SearchInsertPosition.java rename to src/main/java/binary_search/SearchInsertPosition.java diff --git a/problems/src/binary_search/SearchRotatedSortedArray.java b/src/main/java/binary_search/SearchRotatedSortedArray.java similarity index 100% rename from problems/src/binary_search/SearchRotatedSortedArray.java rename to src/main/java/binary_search/SearchRotatedSortedArray.java diff --git a/problems/src/binary_search/SingleElementInASortedArray.java b/src/main/java/binary_search/SingleElementInASortedArray.java similarity index 100% rename from problems/src/binary_search/SingleElementInASortedArray.java rename to src/main/java/binary_search/SingleElementInASortedArray.java diff --git a/problems/src/binary_search/SqrtX.java b/src/main/java/binary_search/SqrtX.java similarity index 100% rename from problems/src/binary_search/SqrtX.java rename to src/main/java/binary_search/SqrtX.java diff --git a/problems/src/binary_search/SwimInRisingWater.java b/src/main/java/binary_search/SwimInRisingWater.java similarity index 100% rename from problems/src/binary_search/SwimInRisingWater.java rename to src/main/java/binary_search/SwimInRisingWater.java diff --git a/problems/src/binary_search/TimeBasedKeyValuePair.java b/src/main/java/binary_search/TimeBasedKeyValuePair.java similarity index 100% rename from problems/src/binary_search/TimeBasedKeyValuePair.java rename to src/main/java/binary_search/TimeBasedKeyValuePair.java diff --git a/problems/src/bit_manipulation/BinaryNumberWithAlternatingBits.java b/src/main/java/bit_manipulation/BinaryNumberWithAlternatingBits.java similarity index 100% rename from problems/src/bit_manipulation/BinaryNumberWithAlternatingBits.java rename to src/main/java/bit_manipulation/BinaryNumberWithAlternatingBits.java diff --git a/problems/src/bit_manipulation/BinaryWatch.java b/src/main/java/bit_manipulation/BinaryWatch.java similarity index 100% rename from problems/src/bit_manipulation/BinaryWatch.java rename to src/main/java/bit_manipulation/BinaryWatch.java diff --git a/problems/src/bit_manipulation/DivideTwoIntegers.java b/src/main/java/bit_manipulation/DivideTwoIntegers.java similarity index 100% rename from problems/src/bit_manipulation/DivideTwoIntegers.java rename to src/main/java/bit_manipulation/DivideTwoIntegers.java diff --git a/problems/src/bit_manipulation/GrayCode.java b/src/main/java/bit_manipulation/GrayCode.java similarity index 100% rename from problems/src/bit_manipulation/GrayCode.java rename to src/main/java/bit_manipulation/GrayCode.java diff --git a/problems/src/bit_manipulation/HammingDistance.java b/src/main/java/bit_manipulation/HammingDistance.java similarity index 100% rename from problems/src/bit_manipulation/HammingDistance.java rename to src/main/java/bit_manipulation/HammingDistance.java diff --git a/problems/src/bit_manipulation/TotalHammingDistance.java b/src/main/java/bit_manipulation/TotalHammingDistance.java similarity index 100% rename from problems/src/bit_manipulation/TotalHammingDistance.java rename to src/main/java/bit_manipulation/TotalHammingDistance.java diff --git a/problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java b/src/main/java/breadth_first_search/BinarayTreeLevelOrderTraversal.java similarity index 100% rename from problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java rename to src/main/java/breadth_first_search/BinarayTreeLevelOrderTraversal.java diff --git a/problems/src/breadth_first_search/BusRoutes.java b/src/main/java/breadth_first_search/BusRoutes.java similarity index 100% rename from problems/src/breadth_first_search/BusRoutes.java rename to src/main/java/breadth_first_search/BusRoutes.java diff --git a/problems/src/breadth_first_search/CutOffTreesForGolfEvent.java b/src/main/java/breadth_first_search/CutOffTreesForGolfEvent.java similarity index 100% rename from problems/src/breadth_first_search/CutOffTreesForGolfEvent.java rename to src/main/java/breadth_first_search/CutOffTreesForGolfEvent.java diff --git a/problems/src/breadth_first_search/Matrix.java b/src/main/java/breadth_first_search/Matrix.java similarity index 100% rename from problems/src/breadth_first_search/Matrix.java rename to src/main/java/breadth_first_search/Matrix.java diff --git a/problems/src/breadth_first_search/OpenTheLock.java b/src/main/java/breadth_first_search/OpenTheLock.java similarity index 100% rename from problems/src/breadth_first_search/OpenTheLock.java rename to src/main/java/breadth_first_search/OpenTheLock.java diff --git a/problems/src/breadth_first_search/RaceCar.java b/src/main/java/breadth_first_search/RaceCar.java similarity index 100% rename from problems/src/breadth_first_search/RaceCar.java rename to src/main/java/breadth_first_search/RaceCar.java diff --git a/problems/src/breadth_first_search/RottingOranges.java b/src/main/java/breadth_first_search/RottingOranges.java similarity index 100% rename from problems/src/breadth_first_search/RottingOranges.java rename to src/main/java/breadth_first_search/RottingOranges.java diff --git a/problems/src/breadth_first_search/SlidingPuzzle.java b/src/main/java/breadth_first_search/SlidingPuzzle.java similarity index 100% rename from problems/src/breadth_first_search/SlidingPuzzle.java rename to src/main/java/breadth_first_search/SlidingPuzzle.java diff --git a/problems/src/breadth_first_search/WallsAndGates.java b/src/main/java/breadth_first_search/WallsAndGates.java similarity index 100% rename from problems/src/breadth_first_search/WallsAndGates.java rename to src/main/java/breadth_first_search/WallsAndGates.java diff --git a/problems/src/breadth_first_search/WordLadder.java b/src/main/java/breadth_first_search/WordLadder.java similarity index 100% rename from problems/src/breadth_first_search/WordLadder.java rename to src/main/java/breadth_first_search/WordLadder.java diff --git a/problems/src/breadth_first_search/WordLadderII.java b/src/main/java/breadth_first_search/WordLadderII.java similarity index 100% rename from problems/src/breadth_first_search/WordLadderII.java rename to src/main/java/breadth_first_search/WordLadderII.java diff --git a/problems/src/depth_first_search/AccountsMerge.java b/src/main/java/depth_first_search/AccountsMerge.java similarity index 100% rename from problems/src/depth_first_search/AccountsMerge.java rename to src/main/java/depth_first_search/AccountsMerge.java diff --git a/problems/src/depth_first_search/AlienDictionary.java b/src/main/java/depth_first_search/AlienDictionary.java similarity index 100% rename from problems/src/depth_first_search/AlienDictionary.java rename to src/main/java/depth_first_search/AlienDictionary.java diff --git a/problems/src/depth_first_search/AllPathsFromSourceToTarget.java b/src/main/java/depth_first_search/AllPathsFromSourceToTarget.java similarity index 100% rename from problems/src/depth_first_search/AllPathsFromSourceToTarget.java rename to src/main/java/depth_first_search/AllPathsFromSourceToTarget.java diff --git a/problems/src/depth_first_search/AsFarfromLandAsPossible.java b/src/main/java/depth_first_search/AsFarfromLandAsPossible.java similarity index 100% rename from problems/src/depth_first_search/AsFarfromLandAsPossible.java rename to src/main/java/depth_first_search/AsFarfromLandAsPossible.java diff --git a/problems/src/depth_first_search/BricksFallingWhenHit.java b/src/main/java/depth_first_search/BricksFallingWhenHit.java similarity index 100% rename from problems/src/depth_first_search/BricksFallingWhenHit.java rename to src/main/java/depth_first_search/BricksFallingWhenHit.java diff --git a/problems/src/depth_first_search/CloneGraph.java b/src/main/java/depth_first_search/CloneGraph.java similarity index 100% rename from problems/src/depth_first_search/CloneGraph.java rename to src/main/java/depth_first_search/CloneGraph.java diff --git a/problems/src/depth_first_search/ConnectingCitiesWithMinimumCost.java b/src/main/java/depth_first_search/ConnectingCitiesWithMinimumCost.java similarity index 100% rename from problems/src/depth_first_search/ConnectingCitiesWithMinimumCost.java rename to src/main/java/depth_first_search/ConnectingCitiesWithMinimumCost.java diff --git a/problems/src/depth_first_search/CourseSchedule.java b/src/main/java/depth_first_search/CourseSchedule.java similarity index 100% rename from problems/src/depth_first_search/CourseSchedule.java rename to src/main/java/depth_first_search/CourseSchedule.java diff --git a/problems/src/depth_first_search/CourseScheduleII.java b/src/main/java/depth_first_search/CourseScheduleII.java similarity index 100% rename from problems/src/depth_first_search/CourseScheduleII.java rename to src/main/java/depth_first_search/CourseScheduleII.java diff --git a/problems/src/depth_first_search/CrackingTheSafe.java b/src/main/java/depth_first_search/CrackingTheSafe.java similarity index 100% rename from problems/src/depth_first_search/CrackingTheSafe.java rename to src/main/java/depth_first_search/CrackingTheSafe.java diff --git a/problems/src/depth_first_search/CriticalConnection.java b/src/main/java/depth_first_search/CriticalConnection.java similarity index 100% rename from problems/src/depth_first_search/CriticalConnection.java rename to src/main/java/depth_first_search/CriticalConnection.java diff --git a/problems/src/depth_first_search/FloodFill.java b/src/main/java/depth_first_search/FloodFill.java similarity index 100% rename from problems/src/depth_first_search/FloodFill.java rename to src/main/java/depth_first_search/FloodFill.java diff --git a/problems/src/depth_first_search/GraphValidTree.java b/src/main/java/depth_first_search/GraphValidTree.java similarity index 100% rename from problems/src/depth_first_search/GraphValidTree.java rename to src/main/java/depth_first_search/GraphValidTree.java diff --git a/problems/src/depth_first_search/IslandPerimeter.java b/src/main/java/depth_first_search/IslandPerimeter.java similarity index 100% rename from problems/src/depth_first_search/IslandPerimeter.java rename to src/main/java/depth_first_search/IslandPerimeter.java diff --git a/problems/src/depth_first_search/LongestConsecutiveSequence.java b/src/main/java/depth_first_search/LongestConsecutiveSequence.java similarity index 100% rename from problems/src/depth_first_search/LongestConsecutiveSequence.java rename to src/main/java/depth_first_search/LongestConsecutiveSequence.java diff --git a/problems/src/depth_first_search/MaxAreaOfIsland.java b/src/main/java/depth_first_search/MaxAreaOfIsland.java similarity index 100% rename from problems/src/depth_first_search/MaxAreaOfIsland.java rename to src/main/java/depth_first_search/MaxAreaOfIsland.java diff --git a/problems/src/depth_first_search/Minesweeper.java b/src/main/java/depth_first_search/Minesweeper.java similarity index 100% rename from problems/src/depth_first_search/Minesweeper.java rename to src/main/java/depth_first_search/Minesweeper.java diff --git a/problems/src/depth_first_search/MinimizeMalwareSpread.java b/src/main/java/depth_first_search/MinimizeMalwareSpread.java similarity index 100% rename from problems/src/depth_first_search/MinimizeMalwareSpread.java rename to src/main/java/depth_first_search/MinimizeMalwareSpread.java diff --git a/problems/src/depth_first_search/MovieRecommend.java b/src/main/java/depth_first_search/MovieRecommend.java similarity index 100% rename from problems/src/depth_first_search/MovieRecommend.java rename to src/main/java/depth_first_search/MovieRecommend.java diff --git a/problems/src/depth_first_search/NumberOfDistinctIslands.java b/src/main/java/depth_first_search/NumberOfDistinctIslands.java similarity index 100% rename from problems/src/depth_first_search/NumberOfDistinctIslands.java rename to src/main/java/depth_first_search/NumberOfDistinctIslands.java diff --git a/problems/src/depth_first_search/NumberOfDistinctIslandsII.java b/src/main/java/depth_first_search/NumberOfDistinctIslandsII.java similarity index 100% rename from problems/src/depth_first_search/NumberOfDistinctIslandsII.java rename to src/main/java/depth_first_search/NumberOfDistinctIslandsII.java diff --git a/problems/src/depth_first_search/NumberOfEnclaves.java b/src/main/java/depth_first_search/NumberOfEnclaves.java similarity index 100% rename from problems/src/depth_first_search/NumberOfEnclaves.java rename to src/main/java/depth_first_search/NumberOfEnclaves.java diff --git a/problems/src/depth_first_search/NumberOfIslands.java b/src/main/java/depth_first_search/NumberOfIslands.java similarity index 100% rename from problems/src/depth_first_search/NumberOfIslands.java rename to src/main/java/depth_first_search/NumberOfIslands.java diff --git a/problems/src/depth_first_search/ParallelCourses.java b/src/main/java/depth_first_search/ParallelCourses.java similarity index 100% rename from problems/src/depth_first_search/ParallelCourses.java rename to src/main/java/depth_first_search/ParallelCourses.java diff --git a/problems/src/depth_first_search/RobotRoomCleaner.java b/src/main/java/depth_first_search/RobotRoomCleaner.java similarity index 100% rename from problems/src/depth_first_search/RobotRoomCleaner.java rename to src/main/java/depth_first_search/RobotRoomCleaner.java diff --git a/problems/src/depth_first_search/SatisfiabilityOfEquations.java b/src/main/java/depth_first_search/SatisfiabilityOfEquations.java similarity index 100% rename from problems/src/depth_first_search/SatisfiabilityOfEquations.java rename to src/main/java/depth_first_search/SatisfiabilityOfEquations.java diff --git a/problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java b/src/main/java/depth_first_search/SmallestRectangleEnclosingBlackPixels.java similarity index 100% rename from problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java rename to src/main/java/depth_first_search/SmallestRectangleEnclosingBlackPixels.java diff --git a/problems/src/design/AutocompleteSystem.java b/src/main/java/design/AutocompleteSystem.java similarity index 100% rename from problems/src/design/AutocompleteSystem.java rename to src/main/java/design/AutocompleteSystem.java diff --git a/problems/src/design/BSTIterator.java b/src/main/java/design/BSTIterator.java similarity index 100% rename from problems/src/design/BSTIterator.java rename to src/main/java/design/BSTIterator.java diff --git a/problems/src/design/CopyListWithRandomPointer.java b/src/main/java/design/CopyListWithRandomPointer.java similarity index 100% rename from problems/src/design/CopyListWithRandomPointer.java rename to src/main/java/design/CopyListWithRandomPointer.java diff --git a/problems/src/design/EncodeAndDecodeTinyURL.java b/src/main/java/design/EncodeAndDecodeTinyURL.java similarity index 100% rename from problems/src/design/EncodeAndDecodeTinyURL.java rename to src/main/java/design/EncodeAndDecodeTinyURL.java diff --git a/problems/src/design/Excel.java b/src/main/java/design/Excel.java similarity index 100% rename from problems/src/design/Excel.java rename to src/main/java/design/Excel.java diff --git a/problems/src/design/LFUCache.java b/src/main/java/design/LFUCache.java similarity index 100% rename from problems/src/design/LFUCache.java rename to src/main/java/design/LFUCache.java diff --git a/problems/src/design/LRUCache.java b/src/main/java/design/LRUCache.java similarity index 100% rename from problems/src/design/LRUCache.java rename to src/main/java/design/LRUCache.java diff --git a/problems/src/design/NestedIterator.java b/src/main/java/design/NestedIterator.java similarity index 100% rename from problems/src/design/NestedIterator.java rename to src/main/java/design/NestedIterator.java diff --git a/problems/src/design/RandomizedCollection.java b/src/main/java/design/RandomizedCollection.java similarity index 100% rename from problems/src/design/RandomizedCollection.java rename to src/main/java/design/RandomizedCollection.java diff --git a/problems/src/design/RandomizedSet.java b/src/main/java/design/RandomizedSet.java similarity index 100% rename from problems/src/design/RandomizedSet.java rename to src/main/java/design/RandomizedSet.java diff --git a/problems/src/design/SerializeDeserializeBinaryTree.java b/src/main/java/design/SerializeDeserializeBinaryTree.java similarity index 100% rename from problems/src/design/SerializeDeserializeBinaryTree.java rename to src/main/java/design/SerializeDeserializeBinaryTree.java diff --git a/problems/src/design/TicTacToe.java b/src/main/java/design/TicTacToe.java similarity index 100% rename from problems/src/design/TicTacToe.java rename to src/main/java/design/TicTacToe.java diff --git a/problems/src/design/Trie.java b/src/main/java/design/Trie.java similarity index 100% rename from problems/src/design/Trie.java rename to src/main/java/design/Trie.java diff --git a/problems/src/design/Twitter.java b/src/main/java/design/Twitter.java similarity index 100% rename from problems/src/design/Twitter.java rename to src/main/java/design/Twitter.java diff --git a/problems/src/design/WordDictionary.java b/src/main/java/design/WordDictionary.java similarity index 100% rename from problems/src/design/WordDictionary.java rename to src/main/java/design/WordDictionary.java diff --git a/problems/src/design/WordFilter.java b/src/main/java/design/WordFilter.java similarity index 100% rename from problems/src/design/WordFilter.java rename to src/main/java/design/WordFilter.java diff --git a/problems/src/divide_and_conquer/KthLargestElementInAnArray.java b/src/main/java/divide_and_conquer/KthLargestElementInAnArray.java similarity index 100% rename from problems/src/divide_and_conquer/KthLargestElementInAnArray.java rename to src/main/java/divide_and_conquer/KthLargestElementInAnArray.java diff --git a/problems/src/divide_and_conquer/MyCalendarII.java b/src/main/java/divide_and_conquer/MyCalendarII.java similarity index 100% rename from problems/src/divide_and_conquer/MyCalendarII.java rename to src/main/java/divide_and_conquer/MyCalendarII.java diff --git a/problems/src/divide_and_conquer/ReversePairs.java b/src/main/java/divide_and_conquer/ReversePairs.java similarity index 100% rename from problems/src/divide_and_conquer/ReversePairs.java rename to src/main/java/divide_and_conquer/ReversePairs.java diff --git a/problems/src/divide_and_conquer/ReversePairsII.java b/src/main/java/divide_and_conquer/ReversePairsII.java similarity index 100% rename from problems/src/divide_and_conquer/ReversePairsII.java rename to src/main/java/divide_and_conquer/ReversePairsII.java diff --git a/problems/src/divide_and_conquer/SearchA2DMatrix.java b/src/main/java/divide_and_conquer/SearchA2DMatrix.java similarity index 100% rename from problems/src/divide_and_conquer/SearchA2DMatrix.java rename to src/main/java/divide_and_conquer/SearchA2DMatrix.java diff --git a/problems/src/divide_and_conquer/TwentyFourGame.java b/src/main/java/divide_and_conquer/TwentyFourGame.java similarity index 100% rename from problems/src/divide_and_conquer/TwentyFourGame.java rename to src/main/java/divide_and_conquer/TwentyFourGame.java diff --git a/problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java b/src/main/java/dynamic_programming/BestTimeToBuyAndSellStockIII.java similarity index 100% rename from problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java rename to src/main/java/dynamic_programming/BestTimeToBuyAndSellStockIII.java diff --git a/problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java b/src/main/java/dynamic_programming/BestTimeToBuyAndSellStocks.java similarity index 100% rename from problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java rename to src/main/java/dynamic_programming/BestTimeToBuyAndSellStocks.java diff --git a/problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java b/src/main/java/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java similarity index 100% rename from problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java rename to src/main/java/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java diff --git a/problems/src/dynamic_programming/BombEnemy.java b/src/main/java/dynamic_programming/BombEnemy.java similarity index 100% rename from problems/src/dynamic_programming/BombEnemy.java rename to src/main/java/dynamic_programming/BombEnemy.java diff --git a/problems/src/dynamic_programming/BurstBalloons.java b/src/main/java/dynamic_programming/BurstBalloons.java similarity index 100% rename from problems/src/dynamic_programming/BurstBalloons.java rename to src/main/java/dynamic_programming/BurstBalloons.java diff --git a/problems/src/dynamic_programming/CanIWin.java b/src/main/java/dynamic_programming/CanIWin.java similarity index 100% rename from problems/src/dynamic_programming/CanIWin.java rename to src/main/java/dynamic_programming/CanIWin.java diff --git a/problems/src/dynamic_programming/CatAndMouse.java b/src/main/java/dynamic_programming/CatAndMouse.java similarity index 100% rename from problems/src/dynamic_programming/CatAndMouse.java rename to src/main/java/dynamic_programming/CatAndMouse.java diff --git a/problems/src/dynamic_programming/CherryPickup.java b/src/main/java/dynamic_programming/CherryPickup.java similarity index 100% rename from problems/src/dynamic_programming/CherryPickup.java rename to src/main/java/dynamic_programming/CherryPickup.java diff --git a/problems/src/dynamic_programming/CherryPickupII.java b/src/main/java/dynamic_programming/CherryPickupII.java similarity index 100% rename from problems/src/dynamic_programming/CherryPickupII.java rename to src/main/java/dynamic_programming/CherryPickupII.java diff --git a/problems/src/dynamic_programming/ClimbingStairs.java b/src/main/java/dynamic_programming/ClimbingStairs.java similarity index 100% rename from problems/src/dynamic_programming/ClimbingStairs.java rename to src/main/java/dynamic_programming/ClimbingStairs.java diff --git a/problems/src/dynamic_programming/CoinChange.java b/src/main/java/dynamic_programming/CoinChange.java similarity index 100% rename from problems/src/dynamic_programming/CoinChange.java rename to src/main/java/dynamic_programming/CoinChange.java diff --git a/problems/src/dynamic_programming/CoinChange2.java b/src/main/java/dynamic_programming/CoinChange2.java similarity index 100% rename from problems/src/dynamic_programming/CoinChange2.java rename to src/main/java/dynamic_programming/CoinChange2.java diff --git a/problems/src/dynamic_programming/CombinationSumIV.java b/src/main/java/dynamic_programming/CombinationSumIV.java similarity index 100% rename from problems/src/dynamic_programming/CombinationSumIV.java rename to src/main/java/dynamic_programming/CombinationSumIV.java diff --git a/problems/src/dynamic_programming/ConcatenatedWords.java b/src/main/java/dynamic_programming/ConcatenatedWords.java similarity index 100% rename from problems/src/dynamic_programming/ConcatenatedWords.java rename to src/main/java/dynamic_programming/ConcatenatedWords.java diff --git a/problems/src/dynamic_programming/ConstrainedSubsequenceSum.java b/src/main/java/dynamic_programming/ConstrainedSubsequenceSum.java similarity index 100% rename from problems/src/dynamic_programming/ConstrainedSubsequenceSum.java rename to src/main/java/dynamic_programming/ConstrainedSubsequenceSum.java diff --git a/problems/src/dynamic_programming/ContinuousSubarraySum.java b/src/main/java/dynamic_programming/ContinuousSubarraySum.java similarity index 100% rename from problems/src/dynamic_programming/ContinuousSubarraySum.java rename to src/main/java/dynamic_programming/ContinuousSubarraySum.java diff --git a/problems/src/dynamic_programming/CornerRectangles.java b/src/main/java/dynamic_programming/CornerRectangles.java similarity index 100% rename from problems/src/dynamic_programming/CornerRectangles.java rename to src/main/java/dynamic_programming/CornerRectangles.java diff --git a/problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java b/src/main/java/dynamic_programming/CountDifferentPalindromicSubsequences.java similarity index 100% rename from problems/src/dynamic_programming/CountDifferentPalindromicSubsequences.java rename to src/main/java/dynamic_programming/CountDifferentPalindromicSubsequences.java diff --git a/problems/src/dynamic_programming/CountVowelsPermutation.java b/src/main/java/dynamic_programming/CountVowelsPermutation.java similarity index 100% rename from problems/src/dynamic_programming/CountVowelsPermutation.java rename to src/main/java/dynamic_programming/CountVowelsPermutation.java diff --git a/problems/src/dynamic_programming/DecodeWays.java b/src/main/java/dynamic_programming/DecodeWays.java similarity index 100% rename from problems/src/dynamic_programming/DecodeWays.java rename to src/main/java/dynamic_programming/DecodeWays.java diff --git a/problems/src/dynamic_programming/DecodeWaysII.java b/src/main/java/dynamic_programming/DecodeWaysII.java similarity index 100% rename from problems/src/dynamic_programming/DecodeWaysII.java rename to src/main/java/dynamic_programming/DecodeWaysII.java diff --git a/problems/src/dynamic_programming/DeleteColumnsToMakeSortedIII.java b/src/main/java/dynamic_programming/DeleteColumnsToMakeSortedIII.java similarity index 100% rename from problems/src/dynamic_programming/DeleteColumnsToMakeSortedIII.java rename to src/main/java/dynamic_programming/DeleteColumnsToMakeSortedIII.java diff --git a/problems/src/dynamic_programming/DistinctSubsequences.java b/src/main/java/dynamic_programming/DistinctSubsequences.java similarity index 100% rename from problems/src/dynamic_programming/DistinctSubsequences.java rename to src/main/java/dynamic_programming/DistinctSubsequences.java diff --git a/problems/src/dynamic_programming/DistinctSubsequencesII.java b/src/main/java/dynamic_programming/DistinctSubsequencesII.java similarity index 100% rename from problems/src/dynamic_programming/DistinctSubsequencesII.java rename to src/main/java/dynamic_programming/DistinctSubsequencesII.java diff --git a/problems/src/dynamic_programming/DungeonGame.java b/src/main/java/dynamic_programming/DungeonGame.java similarity index 100% rename from problems/src/dynamic_programming/DungeonGame.java rename to src/main/java/dynamic_programming/DungeonGame.java diff --git a/problems/src/dynamic_programming/EncodeStringWithShortestLength.java b/src/main/java/dynamic_programming/EncodeStringWithShortestLength.java similarity index 100% rename from problems/src/dynamic_programming/EncodeStringWithShortestLength.java rename to src/main/java/dynamic_programming/EncodeStringWithShortestLength.java diff --git a/problems/src/dynamic_programming/FreedomTrail.java b/src/main/java/dynamic_programming/FreedomTrail.java similarity index 100% rename from problems/src/dynamic_programming/FreedomTrail.java rename to src/main/java/dynamic_programming/FreedomTrail.java diff --git a/problems/src/dynamic_programming/HandshakesThatDontCross.java b/src/main/java/dynamic_programming/HandshakesThatDontCross.java similarity index 100% rename from problems/src/dynamic_programming/HandshakesThatDontCross.java rename to src/main/java/dynamic_programming/HandshakesThatDontCross.java diff --git a/problems/src/dynamic_programming/HouseRobber.java b/src/main/java/dynamic_programming/HouseRobber.java similarity index 100% rename from problems/src/dynamic_programming/HouseRobber.java rename to src/main/java/dynamic_programming/HouseRobber.java diff --git a/problems/src/dynamic_programming/HouseRobberII.java b/src/main/java/dynamic_programming/HouseRobberII.java similarity index 100% rename from problems/src/dynamic_programming/HouseRobberII.java rename to src/main/java/dynamic_programming/HouseRobberII.java diff --git a/problems/src/dynamic_programming/InterleavingString.java b/src/main/java/dynamic_programming/InterleavingString.java similarity index 100% rename from problems/src/dynamic_programming/InterleavingString.java rename to src/main/java/dynamic_programming/InterleavingString.java diff --git a/problems/src/dynamic_programming/JumpGameV.java b/src/main/java/dynamic_programming/JumpGameV.java similarity index 100% rename from problems/src/dynamic_programming/JumpGameV.java rename to src/main/java/dynamic_programming/JumpGameV.java diff --git a/problems/src/dynamic_programming/KnightDialer.java b/src/main/java/dynamic_programming/KnightDialer.java similarity index 100% rename from problems/src/dynamic_programming/KnightDialer.java rename to src/main/java/dynamic_programming/KnightDialer.java diff --git a/problems/src/dynamic_programming/KnightProbabilityInChessboard.java b/src/main/java/dynamic_programming/KnightProbabilityInChessboard.java similarity index 100% rename from problems/src/dynamic_programming/KnightProbabilityInChessboard.java rename to src/main/java/dynamic_programming/KnightProbabilityInChessboard.java diff --git a/problems/src/dynamic_programming/LargestMultipleOfThree.java b/src/main/java/dynamic_programming/LargestMultipleOfThree.java similarity index 100% rename from problems/src/dynamic_programming/LargestMultipleOfThree.java rename to src/main/java/dynamic_programming/LargestMultipleOfThree.java diff --git a/problems/src/dynamic_programming/LargestPlusSign.java b/src/main/java/dynamic_programming/LargestPlusSign.java similarity index 100% rename from problems/src/dynamic_programming/LargestPlusSign.java rename to src/main/java/dynamic_programming/LargestPlusSign.java diff --git a/problems/src/dynamic_programming/LargestSumOfAverages.java b/src/main/java/dynamic_programming/LargestSumOfAverages.java similarity index 100% rename from problems/src/dynamic_programming/LargestSumOfAverages.java rename to src/main/java/dynamic_programming/LargestSumOfAverages.java diff --git a/problems/src/dynamic_programming/LengthofLongestFibonacciSubsequence.java b/src/main/java/dynamic_programming/LengthofLongestFibonacciSubsequence.java similarity index 100% rename from problems/src/dynamic_programming/LengthofLongestFibonacciSubsequence.java rename to src/main/java/dynamic_programming/LengthofLongestFibonacciSubsequence.java diff --git a/problems/src/dynamic_programming/LongestChunkedPalindromeDecomposition.java b/src/main/java/dynamic_programming/LongestChunkedPalindromeDecomposition.java similarity index 100% rename from problems/src/dynamic_programming/LongestChunkedPalindromeDecomposition.java rename to src/main/java/dynamic_programming/LongestChunkedPalindromeDecomposition.java diff --git a/problems/src/dynamic_programming/LongestIncreasingSubsequence.java b/src/main/java/dynamic_programming/LongestIncreasingSubsequence.java similarity index 100% rename from problems/src/dynamic_programming/LongestIncreasingSubsequence.java rename to src/main/java/dynamic_programming/LongestIncreasingSubsequence.java diff --git a/problems/src/dynamic_programming/LongestPaliandromicSubstring.java b/src/main/java/dynamic_programming/LongestPaliandromicSubstring.java similarity index 100% rename from problems/src/dynamic_programming/LongestPaliandromicSubstring.java rename to src/main/java/dynamic_programming/LongestPaliandromicSubstring.java diff --git a/problems/src/dynamic_programming/LongestPalindromicSubsequence.java b/src/main/java/dynamic_programming/LongestPalindromicSubsequence.java similarity index 100% rename from problems/src/dynamic_programming/LongestPalindromicSubsequence.java rename to src/main/java/dynamic_programming/LongestPalindromicSubsequence.java diff --git a/problems/src/dynamic_programming/MakeArrayStrictlyIncreasing.java b/src/main/java/dynamic_programming/MakeArrayStrictlyIncreasing.java similarity index 100% rename from problems/src/dynamic_programming/MakeArrayStrictlyIncreasing.java rename to src/main/java/dynamic_programming/MakeArrayStrictlyIncreasing.java diff --git a/problems/src/dynamic_programming/MaxSum3SubArray.java b/src/main/java/dynamic_programming/MaxSum3SubArray.java similarity index 100% rename from problems/src/dynamic_programming/MaxSum3SubArray.java rename to src/main/java/dynamic_programming/MaxSum3SubArray.java diff --git a/problems/src/dynamic_programming/MaximalSquare.java b/src/main/java/dynamic_programming/MaximalSquare.java similarity index 100% rename from problems/src/dynamic_programming/MaximalSquare.java rename to src/main/java/dynamic_programming/MaximalSquare.java diff --git a/problems/src/dynamic_programming/MaximumProductSubarray.java b/src/main/java/dynamic_programming/MaximumProductSubarray.java similarity index 100% rename from problems/src/dynamic_programming/MaximumProductSubarray.java rename to src/main/java/dynamic_programming/MaximumProductSubarray.java diff --git a/problems/src/dynamic_programming/MaximumProfitInJobScheduling.java b/src/main/java/dynamic_programming/MaximumProfitInJobScheduling.java similarity index 100% rename from problems/src/dynamic_programming/MaximumProfitInJobScheduling.java rename to src/main/java/dynamic_programming/MaximumProfitInJobScheduling.java diff --git a/problems/src/dynamic_programming/MaximumSubarray.java b/src/main/java/dynamic_programming/MaximumSubarray.java similarity index 100% rename from problems/src/dynamic_programming/MaximumSubarray.java rename to src/main/java/dynamic_programming/MaximumSubarray.java diff --git a/problems/src/dynamic_programming/MaximumVacationDays.java b/src/main/java/dynamic_programming/MaximumVacationDays.java similarity index 100% rename from problems/src/dynamic_programming/MaximumVacationDays.java rename to src/main/java/dynamic_programming/MaximumVacationDays.java diff --git a/problems/src/dynamic_programming/MinCostClimbingStairs.java b/src/main/java/dynamic_programming/MinCostClimbingStairs.java similarity index 100% rename from problems/src/dynamic_programming/MinCostClimbingStairs.java rename to src/main/java/dynamic_programming/MinCostClimbingStairs.java diff --git a/problems/src/dynamic_programming/MinimumCostForTickets.java b/src/main/java/dynamic_programming/MinimumCostForTickets.java similarity index 100% rename from problems/src/dynamic_programming/MinimumCostForTickets.java rename to src/main/java/dynamic_programming/MinimumCostForTickets.java diff --git a/problems/src/dynamic_programming/MinimumCostToMergeStones.java b/src/main/java/dynamic_programming/MinimumCostToMergeStones.java similarity index 100% rename from problems/src/dynamic_programming/MinimumCostToMergeStones.java rename to src/main/java/dynamic_programming/MinimumCostToMergeStones.java diff --git a/problems/src/dynamic_programming/MinimumDifficultyOfAJobSchedule.java b/src/main/java/dynamic_programming/MinimumDifficultyOfAJobSchedule.java similarity index 100% rename from problems/src/dynamic_programming/MinimumDifficultyOfAJobSchedule.java rename to src/main/java/dynamic_programming/MinimumDifficultyOfAJobSchedule.java diff --git a/problems/src/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java b/src/main/java/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java similarity index 100% rename from problems/src/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java rename to src/main/java/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java diff --git a/problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java b/src/main/java/dynamic_programming/MinimumNumberOfRefuelingStops.java similarity index 100% rename from problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java rename to src/main/java/dynamic_programming/MinimumNumberOfRefuelingStops.java diff --git a/problems/src/dynamic_programming/MinimumNumberOfTaps.java b/src/main/java/dynamic_programming/MinimumNumberOfTaps.java similarity index 100% rename from problems/src/dynamic_programming/MinimumNumberOfTaps.java rename to src/main/java/dynamic_programming/MinimumNumberOfTaps.java diff --git a/problems/src/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java b/src/main/java/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java similarity index 100% rename from problems/src/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java rename to src/main/java/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java diff --git a/problems/src/dynamic_programming/NumberOfDiceRollsWithTargetSum.java b/src/main/java/dynamic_programming/NumberOfDiceRollsWithTargetSum.java similarity index 100% rename from problems/src/dynamic_programming/NumberOfDiceRollsWithTargetSum.java rename to src/main/java/dynamic_programming/NumberOfDiceRollsWithTargetSum.java diff --git a/problems/src/dynamic_programming/NumberOfLIS.java b/src/main/java/dynamic_programming/NumberOfLIS.java similarity index 100% rename from problems/src/dynamic_programming/NumberOfLIS.java rename to src/main/java/dynamic_programming/NumberOfLIS.java diff --git a/problems/src/dynamic_programming/NumberOfMusicPlaylists.java b/src/main/java/dynamic_programming/NumberOfMusicPlaylists.java similarity index 100% rename from problems/src/dynamic_programming/NumberOfMusicPlaylists.java rename to src/main/java/dynamic_programming/NumberOfMusicPlaylists.java diff --git a/problems/src/dynamic_programming/NumberOfPathsWithMaxScore.java b/src/main/java/dynamic_programming/NumberOfPathsWithMaxScore.java similarity index 100% rename from problems/src/dynamic_programming/NumberOfPathsWithMaxScore.java rename to src/main/java/dynamic_programming/NumberOfPathsWithMaxScore.java diff --git a/problems/src/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java b/src/main/java/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java similarity index 100% rename from problems/src/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java rename to src/main/java/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java diff --git a/problems/src/dynamic_programming/OddEvenJump.java b/src/main/java/dynamic_programming/OddEvenJump.java similarity index 100% rename from problems/src/dynamic_programming/OddEvenJump.java rename to src/main/java/dynamic_programming/OddEvenJump.java diff --git a/problems/src/dynamic_programming/OnesAndZeroes.java b/src/main/java/dynamic_programming/OnesAndZeroes.java similarity index 100% rename from problems/src/dynamic_programming/OnesAndZeroes.java rename to src/main/java/dynamic_programming/OnesAndZeroes.java diff --git a/problems/src/dynamic_programming/OutOfBoundaryPaths.java b/src/main/java/dynamic_programming/OutOfBoundaryPaths.java similarity index 100% rename from problems/src/dynamic_programming/OutOfBoundaryPaths.java rename to src/main/java/dynamic_programming/OutOfBoundaryPaths.java diff --git a/problems/src/dynamic_programming/PaintHouseII.java b/src/main/java/dynamic_programming/PaintHouseII.java similarity index 100% rename from problems/src/dynamic_programming/PaintHouseII.java rename to src/main/java/dynamic_programming/PaintHouseII.java diff --git a/problems/src/dynamic_programming/PaintHouseIII.java b/src/main/java/dynamic_programming/PaintHouseIII.java similarity index 100% rename from problems/src/dynamic_programming/PaintHouseIII.java rename to src/main/java/dynamic_programming/PaintHouseIII.java diff --git a/problems/src/dynamic_programming/PalindromePairs.java b/src/main/java/dynamic_programming/PalindromePairs.java similarity index 100% rename from problems/src/dynamic_programming/PalindromePairs.java rename to src/main/java/dynamic_programming/PalindromePairs.java diff --git a/problems/src/dynamic_programming/PalindromePartitioningII.java b/src/main/java/dynamic_programming/PalindromePartitioningII.java similarity index 100% rename from problems/src/dynamic_programming/PalindromePartitioningII.java rename to src/main/java/dynamic_programming/PalindromePartitioningII.java diff --git a/problems/src/dynamic_programming/PalindromePartitioningIII.java b/src/main/java/dynamic_programming/PalindromePartitioningIII.java similarity index 100% rename from problems/src/dynamic_programming/PalindromePartitioningIII.java rename to src/main/java/dynamic_programming/PalindromePartitioningIII.java diff --git a/problems/src/dynamic_programming/PalindromeRemoval.java b/src/main/java/dynamic_programming/PalindromeRemoval.java similarity index 100% rename from problems/src/dynamic_programming/PalindromeRemoval.java rename to src/main/java/dynamic_programming/PalindromeRemoval.java diff --git a/problems/src/dynamic_programming/PalindromicSubstrings.java b/src/main/java/dynamic_programming/PalindromicSubstrings.java similarity index 100% rename from problems/src/dynamic_programming/PalindromicSubstrings.java rename to src/main/java/dynamic_programming/PalindromicSubstrings.java diff --git a/problems/src/dynamic_programming/ProfitableSchemes.java b/src/main/java/dynamic_programming/ProfitableSchemes.java similarity index 100% rename from problems/src/dynamic_programming/ProfitableSchemes.java rename to src/main/java/dynamic_programming/ProfitableSchemes.java diff --git a/problems/src/dynamic_programming/RemoveBoxes.java b/src/main/java/dynamic_programming/RemoveBoxes.java similarity index 100% rename from problems/src/dynamic_programming/RemoveBoxes.java rename to src/main/java/dynamic_programming/RemoveBoxes.java diff --git a/problems/src/dynamic_programming/RestoreTheArray.java b/src/main/java/dynamic_programming/RestoreTheArray.java similarity index 100% rename from problems/src/dynamic_programming/RestoreTheArray.java rename to src/main/java/dynamic_programming/RestoreTheArray.java diff --git a/problems/src/dynamic_programming/RussianDollEnvelopes.java b/src/main/java/dynamic_programming/RussianDollEnvelopes.java similarity index 100% rename from problems/src/dynamic_programming/RussianDollEnvelopes.java rename to src/main/java/dynamic_programming/RussianDollEnvelopes.java diff --git a/problems/src/dynamic_programming/ShortestPathVisitingAllNodes.java b/src/main/java/dynamic_programming/ShortestPathVisitingAllNodes.java similarity index 100% rename from problems/src/dynamic_programming/ShortestPathVisitingAllNodes.java rename to src/main/java/dynamic_programming/ShortestPathVisitingAllNodes.java diff --git a/problems/src/dynamic_programming/SmallestSufficientTeam.java b/src/main/java/dynamic_programming/SmallestSufficientTeam.java similarity index 100% rename from problems/src/dynamic_programming/SmallestSufficientTeam.java rename to src/main/java/dynamic_programming/SmallestSufficientTeam.java diff --git a/problems/src/dynamic_programming/SplitArrayLargestSum.java b/src/main/java/dynamic_programming/SplitArrayLargestSum.java similarity index 100% rename from problems/src/dynamic_programming/SplitArrayLargestSum.java rename to src/main/java/dynamic_programming/SplitArrayLargestSum.java diff --git a/problems/src/dynamic_programming/StickersToSpellWord.java b/src/main/java/dynamic_programming/StickersToSpellWord.java similarity index 100% rename from problems/src/dynamic_programming/StickersToSpellWord.java rename to src/main/java/dynamic_programming/StickersToSpellWord.java diff --git a/problems/src/dynamic_programming/StoneGame.java b/src/main/java/dynamic_programming/StoneGame.java similarity index 100% rename from problems/src/dynamic_programming/StoneGame.java rename to src/main/java/dynamic_programming/StoneGame.java diff --git a/problems/src/dynamic_programming/StoneGameIII.java b/src/main/java/dynamic_programming/StoneGameIII.java similarity index 100% rename from problems/src/dynamic_programming/StoneGameIII.java rename to src/main/java/dynamic_programming/StoneGameIII.java diff --git a/problems/src/dynamic_programming/StoneGameIV.java b/src/main/java/dynamic_programming/StoneGameIV.java similarity index 100% rename from problems/src/dynamic_programming/StoneGameIV.java rename to src/main/java/dynamic_programming/StoneGameIV.java diff --git a/problems/src/dynamic_programming/StrangePrinter.java b/src/main/java/dynamic_programming/StrangePrinter.java similarity index 100% rename from problems/src/dynamic_programming/StrangePrinter.java rename to src/main/java/dynamic_programming/StrangePrinter.java diff --git a/problems/src/dynamic_programming/TallestBillboard.java b/src/main/java/dynamic_programming/TallestBillboard.java similarity index 100% rename from problems/src/dynamic_programming/TallestBillboard.java rename to src/main/java/dynamic_programming/TallestBillboard.java diff --git a/problems/src/dynamic_programming/TilingARectangle.java b/src/main/java/dynamic_programming/TilingARectangle.java similarity index 100% rename from problems/src/dynamic_programming/TilingARectangle.java rename to src/main/java/dynamic_programming/TilingARectangle.java diff --git a/problems/src/dynamic_programming/TossStrangeCoins.java b/src/main/java/dynamic_programming/TossStrangeCoins.java similarity index 100% rename from problems/src/dynamic_programming/TossStrangeCoins.java rename to src/main/java/dynamic_programming/TossStrangeCoins.java diff --git a/problems/src/dynamic_programming/TwoKeysKeyboard.java b/src/main/java/dynamic_programming/TwoKeysKeyboard.java similarity index 100% rename from problems/src/dynamic_programming/TwoKeysKeyboard.java rename to src/main/java/dynamic_programming/TwoKeysKeyboard.java diff --git a/problems/src/dynamic_programming/UniqueBinarySearchTrees.java b/src/main/java/dynamic_programming/UniqueBinarySearchTrees.java similarity index 100% rename from problems/src/dynamic_programming/UniqueBinarySearchTrees.java rename to src/main/java/dynamic_programming/UniqueBinarySearchTrees.java diff --git a/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java b/src/main/java/dynamic_programming/UniqueBinarySearchTreesII.java similarity index 100% rename from problems/src/dynamic_programming/UniqueBinarySearchTreesII.java rename to src/main/java/dynamic_programming/UniqueBinarySearchTreesII.java diff --git a/problems/src/dynamic_programming/ValidPalindromeIII.java b/src/main/java/dynamic_programming/ValidPalindromeIII.java similarity index 100% rename from problems/src/dynamic_programming/ValidPalindromeIII.java rename to src/main/java/dynamic_programming/ValidPalindromeIII.java diff --git a/problems/src/dynamic_programming/WordBreak.java b/src/main/java/dynamic_programming/WordBreak.java similarity index 100% rename from problems/src/dynamic_programming/WordBreak.java rename to src/main/java/dynamic_programming/WordBreak.java diff --git a/problems/src/dynamic_programming/WordBreakII.java b/src/main/java/dynamic_programming/WordBreakII.java similarity index 100% rename from problems/src/dynamic_programming/WordBreakII.java rename to src/main/java/dynamic_programming/WordBreakII.java diff --git a/problems/src/greedy/BoatsToSavePeople.java b/src/main/java/greedy/BoatsToSavePeople.java similarity index 100% rename from problems/src/greedy/BoatsToSavePeople.java rename to src/main/java/greedy/BoatsToSavePeople.java diff --git a/problems/src/greedy/BrokenCalculator.java b/src/main/java/greedy/BrokenCalculator.java similarity index 100% rename from problems/src/greedy/BrokenCalculator.java rename to src/main/java/greedy/BrokenCalculator.java diff --git a/problems/src/greedy/BurstBalloons.java b/src/main/java/greedy/BurstBalloons.java similarity index 100% rename from problems/src/greedy/BurstBalloons.java rename to src/main/java/greedy/BurstBalloons.java diff --git a/problems/src/greedy/CourseScheduleIII.java b/src/main/java/greedy/CourseScheduleIII.java similarity index 100% rename from problems/src/greedy/CourseScheduleIII.java rename to src/main/java/greedy/CourseScheduleIII.java diff --git a/problems/src/greedy/GasStation.java b/src/main/java/greedy/GasStation.java similarity index 100% rename from problems/src/greedy/GasStation.java rename to src/main/java/greedy/GasStation.java diff --git a/problems/src/greedy/IPO.java b/src/main/java/greedy/IPO.java similarity index 100% rename from problems/src/greedy/IPO.java rename to src/main/java/greedy/IPO.java diff --git a/problems/src/greedy/JumpGame.java b/src/main/java/greedy/JumpGame.java similarity index 100% rename from problems/src/greedy/JumpGame.java rename to src/main/java/greedy/JumpGame.java diff --git a/problems/src/greedy/JumpGameII.java b/src/main/java/greedy/JumpGameII.java similarity index 100% rename from problems/src/greedy/JumpGameII.java rename to src/main/java/greedy/JumpGameII.java diff --git a/problems/src/greedy/LemonadeChange.java b/src/main/java/greedy/LemonadeChange.java similarity index 100% rename from problems/src/greedy/LemonadeChange.java rename to src/main/java/greedy/LemonadeChange.java diff --git a/problems/src/greedy/MaximumLengthOfPairChain.java b/src/main/java/greedy/MaximumLengthOfPairChain.java similarity index 100% rename from problems/src/greedy/MaximumLengthOfPairChain.java rename to src/main/java/greedy/MaximumLengthOfPairChain.java diff --git a/problems/src/greedy/MinimumTimeToBuildBlocks.java b/src/main/java/greedy/MinimumTimeToBuildBlocks.java similarity index 100% rename from problems/src/greedy/MinimumTimeToBuildBlocks.java rename to src/main/java/greedy/MinimumTimeToBuildBlocks.java diff --git a/problems/src/greedy/NonOverlappingIntervals.java b/src/main/java/greedy/NonOverlappingIntervals.java similarity index 100% rename from problems/src/greedy/NonOverlappingIntervals.java rename to src/main/java/greedy/NonOverlappingIntervals.java diff --git a/problems/src/greedy/PartitionLabels.java b/src/main/java/greedy/PartitionLabels.java similarity index 100% rename from problems/src/greedy/PartitionLabels.java rename to src/main/java/greedy/PartitionLabels.java diff --git a/problems/src/greedy/QueueReconstructionByHeight.java b/src/main/java/greedy/QueueReconstructionByHeight.java similarity index 100% rename from problems/src/greedy/QueueReconstructionByHeight.java rename to src/main/java/greedy/QueueReconstructionByHeight.java diff --git a/problems/src/greedy/ReducingDishes.java b/src/main/java/greedy/ReducingDishes.java similarity index 100% rename from problems/src/greedy/ReducingDishes.java rename to src/main/java/greedy/ReducingDishes.java diff --git a/problems/src/greedy/ScoreAfterFlippingMatrix.java b/src/main/java/greedy/ScoreAfterFlippingMatrix.java similarity index 100% rename from problems/src/greedy/ScoreAfterFlippingMatrix.java rename to src/main/java/greedy/ScoreAfterFlippingMatrix.java diff --git a/problems/src/greedy/StringWithout3A3B.java b/src/main/java/greedy/StringWithout3A3B.java similarity index 100% rename from problems/src/greedy/StringWithout3A3B.java rename to src/main/java/greedy/StringWithout3A3B.java diff --git a/problems/src/greedy/TaskScheduler.java b/src/main/java/greedy/TaskScheduler.java similarity index 100% rename from problems/src/greedy/TaskScheduler.java rename to src/main/java/greedy/TaskScheduler.java diff --git a/problems/src/greedy/TwoCityScheduling.java b/src/main/java/greedy/TwoCityScheduling.java similarity index 100% rename from problems/src/greedy/TwoCityScheduling.java rename to src/main/java/greedy/TwoCityScheduling.java diff --git a/problems/src/hashing/Anagrams.java b/src/main/java/hashing/Anagrams.java similarity index 100% rename from problems/src/hashing/Anagrams.java rename to src/main/java/hashing/Anagrams.java diff --git a/problems/src/hashing/AnalyzeUserWebsiteVisitPattern.java b/src/main/java/hashing/AnalyzeUserWebsiteVisitPattern.java similarity index 100% rename from problems/src/hashing/AnalyzeUserWebsiteVisitPattern.java rename to src/main/java/hashing/AnalyzeUserWebsiteVisitPattern.java diff --git a/problems/src/hashing/BrickWall.java b/src/main/java/hashing/BrickWall.java similarity index 100% rename from problems/src/hashing/BrickWall.java rename to src/main/java/hashing/BrickWall.java diff --git a/problems/src/hashing/ContiguousArray.java b/src/main/java/hashing/ContiguousArray.java similarity index 100% rename from problems/src/hashing/ContiguousArray.java rename to src/main/java/hashing/ContiguousArray.java diff --git a/problems/src/hashing/CustomSortString.java b/src/main/java/hashing/CustomSortString.java similarity index 100% rename from problems/src/hashing/CustomSortString.java rename to src/main/java/hashing/CustomSortString.java diff --git a/problems/src/hashing/DistributeCandies.java b/src/main/java/hashing/DistributeCandies.java similarity index 100% rename from problems/src/hashing/DistributeCandies.java rename to src/main/java/hashing/DistributeCandies.java diff --git a/problems/src/hashing/GroupAnagrams.java b/src/main/java/hashing/GroupAnagrams.java similarity index 100% rename from problems/src/hashing/GroupAnagrams.java rename to src/main/java/hashing/GroupAnagrams.java diff --git a/problems/src/hashing/GroupsOfSpecialEquivalentStrings.java b/src/main/java/hashing/GroupsOfSpecialEquivalentStrings.java similarity index 100% rename from problems/src/hashing/GroupsOfSpecialEquivalentStrings.java rename to src/main/java/hashing/GroupsOfSpecialEquivalentStrings.java diff --git a/problems/src/hashing/KdiffPairsInanArray.java b/src/main/java/hashing/KdiffPairsInanArray.java similarity index 100% rename from problems/src/hashing/KdiffPairsInanArray.java rename to src/main/java/hashing/KdiffPairsInanArray.java diff --git a/problems/src/hashing/LargestUniqueNumber.java b/src/main/java/hashing/LargestUniqueNumber.java similarity index 100% rename from problems/src/hashing/LargestUniqueNumber.java rename to src/main/java/hashing/LargestUniqueNumber.java diff --git a/problems/src/hashing/MaximumSizeSubarraySumEqualsk.java b/src/main/java/hashing/MaximumSizeSubarraySumEqualsk.java similarity index 100% rename from problems/src/hashing/MaximumSizeSubarraySumEqualsk.java rename to src/main/java/hashing/MaximumSizeSubarraySumEqualsk.java diff --git a/problems/src/hashing/NumberOfAtoms.java b/src/main/java/hashing/NumberOfAtoms.java similarity index 100% rename from problems/src/hashing/NumberOfAtoms.java rename to src/main/java/hashing/NumberOfAtoms.java diff --git a/problems/src/hashing/PartitionLabels.java b/src/main/java/hashing/PartitionLabels.java similarity index 100% rename from problems/src/hashing/PartitionLabels.java rename to src/main/java/hashing/PartitionLabels.java diff --git a/problems/src/hashing/ShortEncodingOfWords.java b/src/main/java/hashing/ShortEncodingOfWords.java similarity index 100% rename from problems/src/hashing/ShortEncodingOfWords.java rename to src/main/java/hashing/ShortEncodingOfWords.java diff --git a/problems/src/hashing/SortCharByFrequency.java b/src/main/java/hashing/SortCharByFrequency.java similarity index 100% rename from problems/src/hashing/SortCharByFrequency.java rename to src/main/java/hashing/SortCharByFrequency.java diff --git a/problems/src/hashing/StringTransformsIntoAnotherString.java b/src/main/java/hashing/StringTransformsIntoAnotherString.java similarity index 100% rename from problems/src/hashing/StringTransformsIntoAnotherString.java rename to src/main/java/hashing/StringTransformsIntoAnotherString.java diff --git a/problems/src/hashing/SubstringConcatenationOfWords.java b/src/main/java/hashing/SubstringConcatenationOfWords.java similarity index 100% rename from problems/src/hashing/SubstringConcatenationOfWords.java rename to src/main/java/hashing/SubstringConcatenationOfWords.java diff --git a/problems/src/hashing/TwoSum.java b/src/main/java/hashing/TwoSum.java similarity index 100% rename from problems/src/hashing/TwoSum.java rename to src/main/java/hashing/TwoSum.java diff --git a/problems/src/hashing/ValidAnagram.java b/src/main/java/hashing/ValidAnagram.java similarity index 100% rename from problems/src/hashing/ValidAnagram.java rename to src/main/java/hashing/ValidAnagram.java diff --git a/problems/src/heap/Candy.java b/src/main/java/heap/Candy.java similarity index 100% rename from problems/src/heap/Candy.java rename to src/main/java/heap/Candy.java diff --git a/problems/src/heap/DistantBarcodes.java b/src/main/java/heap/DistantBarcodes.java similarity index 100% rename from problems/src/heap/DistantBarcodes.java rename to src/main/java/heap/DistantBarcodes.java diff --git a/problems/src/heap/FreqStack.java b/src/main/java/heap/FreqStack.java similarity index 100% rename from problems/src/heap/FreqStack.java rename to src/main/java/heap/FreqStack.java diff --git a/problems/src/heap/KClosestPointsToOrigin.java b/src/main/java/heap/KClosestPointsToOrigin.java similarity index 100% rename from problems/src/heap/KClosestPointsToOrigin.java rename to src/main/java/heap/KClosestPointsToOrigin.java diff --git a/problems/src/heap/MeetingRoomsII.java b/src/main/java/heap/MeetingRoomsII.java similarity index 100% rename from problems/src/heap/MeetingRoomsII.java rename to src/main/java/heap/MeetingRoomsII.java diff --git a/problems/src/heap/ReachableNodesInSubdividedGraph.java b/src/main/java/heap/ReachableNodesInSubdividedGraph.java similarity index 100% rename from problems/src/heap/ReachableNodesInSubdividedGraph.java rename to src/main/java/heap/ReachableNodesInSubdividedGraph.java diff --git a/problems/src/heap/SlidingWindowMaximum.java b/src/main/java/heap/SlidingWindowMaximum.java similarity index 100% rename from problems/src/heap/SlidingWindowMaximum.java rename to src/main/java/heap/SlidingWindowMaximum.java diff --git a/problems/src/heap/SmallestRotationWithHighestScore.java b/src/main/java/heap/SmallestRotationWithHighestScore.java similarity index 100% rename from problems/src/heap/SmallestRotationWithHighestScore.java rename to src/main/java/heap/SmallestRotationWithHighestScore.java diff --git a/problems/src/heap/TheSkylineProblem.java b/src/main/java/heap/TheSkylineProblem.java similarity index 100% rename from problems/src/heap/TheSkylineProblem.java rename to src/main/java/heap/TheSkylineProblem.java diff --git a/problems/src/heap/TopKFrequentWords.java b/src/main/java/heap/TopKFrequentWords.java similarity index 100% rename from problems/src/heap/TopKFrequentWords.java rename to src/main/java/heap/TopKFrequentWords.java diff --git a/problems/src/linked_list/DeleteNode.java b/src/main/java/linked_list/DeleteNode.java similarity index 100% rename from problems/src/linked_list/DeleteNode.java rename to src/main/java/linked_list/DeleteNode.java diff --git a/problems/src/linked_list/IntersectionOfTwoLists.java b/src/main/java/linked_list/IntersectionOfTwoLists.java similarity index 100% rename from problems/src/linked_list/IntersectionOfTwoLists.java rename to src/main/java/linked_list/IntersectionOfTwoLists.java diff --git a/problems/src/linked_list/LinkedListCycle.java b/src/main/java/linked_list/LinkedListCycle.java similarity index 100% rename from problems/src/linked_list/LinkedListCycle.java rename to src/main/java/linked_list/LinkedListCycle.java diff --git a/problems/src/linked_list/MergeKSortedLists.java b/src/main/java/linked_list/MergeKSortedLists.java similarity index 100% rename from problems/src/linked_list/MergeKSortedLists.java rename to src/main/java/linked_list/MergeKSortedLists.java diff --git a/problems/src/linked_list/MergeTwoSortedList.java b/src/main/java/linked_list/MergeTwoSortedList.java similarity index 100% rename from problems/src/linked_list/MergeTwoSortedList.java rename to src/main/java/linked_list/MergeTwoSortedList.java diff --git a/problems/src/linked_list/MiddleOfLinkedList.java b/src/main/java/linked_list/MiddleOfLinkedList.java similarity index 100% rename from problems/src/linked_list/MiddleOfLinkedList.java rename to src/main/java/linked_list/MiddleOfLinkedList.java diff --git a/problems/src/linked_list/NextGreaterNodeInLinkedList.java b/src/main/java/linked_list/NextGreaterNodeInLinkedList.java similarity index 100% rename from problems/src/linked_list/NextGreaterNodeInLinkedList.java rename to src/main/java/linked_list/NextGreaterNodeInLinkedList.java diff --git a/problems/src/linked_list/PaliandromeList.java b/src/main/java/linked_list/PaliandromeList.java similarity index 100% rename from problems/src/linked_list/PaliandromeList.java rename to src/main/java/linked_list/PaliandromeList.java diff --git a/problems/src/linked_list/ReverseLinkedList.java b/src/main/java/linked_list/ReverseLinkedList.java similarity index 100% rename from problems/src/linked_list/ReverseLinkedList.java rename to src/main/java/linked_list/ReverseLinkedList.java diff --git a/problems/src/linked_list/ReverseNodesKGroup.java b/src/main/java/linked_list/ReverseNodesKGroup.java similarity index 100% rename from problems/src/linked_list/ReverseNodesKGroup.java rename to src/main/java/linked_list/ReverseNodesKGroup.java diff --git a/problems/src/linked_list/SplitLinkedListInParts.java b/src/main/java/linked_list/SplitLinkedListInParts.java similarity index 100% rename from problems/src/linked_list/SplitLinkedListInParts.java rename to src/main/java/linked_list/SplitLinkedListInParts.java diff --git a/problems/src/linked_list/SwapNodesInPairs.java b/src/main/java/linked_list/SwapNodesInPairs.java similarity index 100% rename from problems/src/linked_list/SwapNodesInPairs.java rename to src/main/java/linked_list/SwapNodesInPairs.java diff --git a/problems/src/math/AddDigits.java b/src/main/java/math/AddDigits.java similarity index 100% rename from problems/src/math/AddDigits.java rename to src/main/java/math/AddDigits.java diff --git a/problems/src/math/AddTwoNumbers.java b/src/main/java/math/AddTwoNumbers.java similarity index 100% rename from problems/src/math/AddTwoNumbers.java rename to src/main/java/math/AddTwoNumbers.java diff --git a/problems/src/math/Base7.java b/src/main/java/math/Base7.java similarity index 100% rename from problems/src/math/Base7.java rename to src/main/java/math/Base7.java diff --git a/problems/src/math/BulbSwitcherII.java b/src/main/java/math/BulbSwitcherII.java similarity index 100% rename from problems/src/math/BulbSwitcherII.java rename to src/main/java/math/BulbSwitcherII.java diff --git a/problems/src/math/CountPrimes.java b/src/main/java/math/CountPrimes.java similarity index 100% rename from problems/src/math/CountPrimes.java rename to src/main/java/math/CountPrimes.java diff --git a/problems/src/math/CouplesHoldingHands.java b/src/main/java/math/CouplesHoldingHands.java similarity index 100% rename from problems/src/math/CouplesHoldingHands.java rename to src/main/java/math/CouplesHoldingHands.java diff --git a/problems/src/math/DecodedStringAtIndex.java b/src/main/java/math/DecodedStringAtIndex.java similarity index 100% rename from problems/src/math/DecodedStringAtIndex.java rename to src/main/java/math/DecodedStringAtIndex.java diff --git a/problems/src/math/ExcelSheetColumnTitle.java b/src/main/java/math/ExcelSheetColumnTitle.java similarity index 100% rename from problems/src/math/ExcelSheetColumnTitle.java rename to src/main/java/math/ExcelSheetColumnTitle.java diff --git a/problems/src/math/GlobalAndLocalInversions.java b/src/main/java/math/GlobalAndLocalInversions.java similarity index 100% rename from problems/src/math/GlobalAndLocalInversions.java rename to src/main/java/math/GlobalAndLocalInversions.java diff --git a/problems/src/math/LargestComponentSizebyCommonFactor.java b/src/main/java/math/LargestComponentSizebyCommonFactor.java similarity index 100% rename from problems/src/math/LargestComponentSizebyCommonFactor.java rename to src/main/java/math/LargestComponentSizebyCommonFactor.java diff --git a/problems/src/math/MinimumIndexSumOfTwoLists.java b/src/main/java/math/MinimumIndexSumOfTwoLists.java similarity index 100% rename from problems/src/math/MinimumIndexSumOfTwoLists.java rename to src/main/java/math/MinimumIndexSumOfTwoLists.java diff --git a/problems/src/math/NthDigit.java b/src/main/java/math/NthDigit.java similarity index 100% rename from problems/src/math/NthDigit.java rename to src/main/java/math/NthDigit.java diff --git a/problems/src/math/NthMagicalNumber.java b/src/main/java/math/NthMagicalNumber.java similarity index 100% rename from problems/src/math/NthMagicalNumber.java rename to src/main/java/math/NthMagicalNumber.java diff --git a/problems/src/math/ProjectionAreaOf3DShapes.java b/src/main/java/math/ProjectionAreaOf3DShapes.java similarity index 100% rename from problems/src/math/ProjectionAreaOf3DShapes.java rename to src/main/java/math/ProjectionAreaOf3DShapes.java diff --git a/problems/src/math/RangeAdditionII.java b/src/main/java/math/RangeAdditionII.java similarity index 100% rename from problems/src/math/RangeAdditionII.java rename to src/main/java/math/RangeAdditionII.java diff --git a/problems/src/math/ReachingPoints.java b/src/main/java/math/ReachingPoints.java similarity index 100% rename from problems/src/math/ReachingPoints.java rename to src/main/java/math/ReachingPoints.java diff --git a/problems/src/math/RectangleOverlap.java b/src/main/java/math/RectangleOverlap.java similarity index 100% rename from problems/src/math/RectangleOverlap.java rename to src/main/java/math/RectangleOverlap.java diff --git a/problems/src/math/RomanToInteger.java b/src/main/java/math/RomanToInteger.java similarity index 100% rename from problems/src/math/RomanToInteger.java rename to src/main/java/math/RomanToInteger.java diff --git a/problems/src/math/RotateFunction.java b/src/main/java/math/RotateFunction.java similarity index 100% rename from problems/src/math/RotateFunction.java rename to src/main/java/math/RotateFunction.java diff --git a/problems/src/math/SmallestRangeI.java b/src/main/java/math/SmallestRangeI.java similarity index 100% rename from problems/src/math/SmallestRangeI.java rename to src/main/java/math/SmallestRangeI.java diff --git a/problems/src/math/SolveTheEquation.java b/src/main/java/math/SolveTheEquation.java similarity index 100% rename from problems/src/math/SolveTheEquation.java rename to src/main/java/math/SolveTheEquation.java diff --git a/problems/src/math/SquirrelSimulation.java b/src/main/java/math/SquirrelSimulation.java similarity index 100% rename from problems/src/math/SquirrelSimulation.java rename to src/main/java/math/SquirrelSimulation.java diff --git a/problems/src/math/SuperWashingMachines.java b/src/main/java/math/SuperWashingMachines.java similarity index 100% rename from problems/src/math/SuperWashingMachines.java rename to src/main/java/math/SuperWashingMachines.java diff --git a/problems/src/math/WaterAndJugProblem.java b/src/main/java/math/WaterAndJugProblem.java similarity index 100% rename from problems/src/math/WaterAndJugProblem.java rename to src/main/java/math/WaterAndJugProblem.java diff --git a/problems/src/reservoir_sampling/RandomPickIndex.java b/src/main/java/reservoir_sampling/RandomPickIndex.java similarity index 100% rename from problems/src/reservoir_sampling/RandomPickIndex.java rename to src/main/java/reservoir_sampling/RandomPickIndex.java diff --git a/problems/src/stack/BasicCalculator.java b/src/main/java/stack/BasicCalculator.java similarity index 100% rename from problems/src/stack/BasicCalculator.java rename to src/main/java/stack/BasicCalculator.java diff --git a/problems/src/stack/DecodeString.java b/src/main/java/stack/DecodeString.java similarity index 100% rename from problems/src/stack/DecodeString.java rename to src/main/java/stack/DecodeString.java diff --git a/problems/src/stack/DecodedStringAtIndex.java b/src/main/java/stack/DecodedStringAtIndex.java similarity index 100% rename from problems/src/stack/DecodedStringAtIndex.java rename to src/main/java/stack/DecodedStringAtIndex.java diff --git a/problems/src/stack/ExclusiveTimeOfFunctions.java b/src/main/java/stack/ExclusiveTimeOfFunctions.java similarity index 100% rename from problems/src/stack/ExclusiveTimeOfFunctions.java rename to src/main/java/stack/ExclusiveTimeOfFunctions.java diff --git a/problems/src/stack/LargestRectangleInHistogram.java b/src/main/java/stack/LargestRectangleInHistogram.java similarity index 100% rename from problems/src/stack/LargestRectangleInHistogram.java rename to src/main/java/stack/LargestRectangleInHistogram.java diff --git a/problems/src/stack/LongestValidParentheses.java b/src/main/java/stack/LongestValidParentheses.java similarity index 100% rename from problems/src/stack/LongestValidParentheses.java rename to src/main/java/stack/LongestValidParentheses.java diff --git a/problems/src/stack/MaximalRectangle.java b/src/main/java/stack/MaximalRectangle.java similarity index 100% rename from problems/src/stack/MaximalRectangle.java rename to src/main/java/stack/MaximalRectangle.java diff --git a/problems/src/stack/MinStack.java b/src/main/java/stack/MinStack.java similarity index 100% rename from problems/src/stack/MinStack.java rename to src/main/java/stack/MinStack.java diff --git a/problems/src/stack/MyQueue.java b/src/main/java/stack/MyQueue.java similarity index 100% rename from problems/src/stack/MyQueue.java rename to src/main/java/stack/MyQueue.java diff --git a/problems/src/stack/StudentAttendanceRecordII.java b/src/main/java/stack/StudentAttendanceRecordII.java similarity index 100% rename from problems/src/stack/StudentAttendanceRecordII.java rename to src/main/java/stack/StudentAttendanceRecordII.java diff --git a/problems/src/stack/ValidParentheses.java b/src/main/java/stack/ValidParentheses.java similarity index 100% rename from problems/src/stack/ValidParentheses.java rename to src/main/java/stack/ValidParentheses.java diff --git a/problems/src/string/AddBinary.java b/src/main/java/string/AddBinary.java similarity index 100% rename from problems/src/string/AddBinary.java rename to src/main/java/string/AddBinary.java diff --git a/problems/src/string/CompareVersionNumbers.java b/src/main/java/string/CompareVersionNumbers.java similarity index 100% rename from problems/src/string/CompareVersionNumbers.java rename to src/main/java/string/CompareVersionNumbers.java diff --git a/problems/src/string/CountAndSay.java b/src/main/java/string/CountAndSay.java similarity index 100% rename from problems/src/string/CountAndSay.java rename to src/main/java/string/CountAndSay.java diff --git a/problems/src/string/ExcelSheetColumnNumber.java b/src/main/java/string/ExcelSheetColumnNumber.java similarity index 100% rename from problems/src/string/ExcelSheetColumnNumber.java rename to src/main/java/string/ExcelSheetColumnNumber.java diff --git a/problems/src/string/FindTheClosestPalindrome.java b/src/main/java/string/FindTheClosestPalindrome.java similarity index 100% rename from problems/src/string/FindTheClosestPalindrome.java rename to src/main/java/string/FindTheClosestPalindrome.java diff --git a/problems/src/string/FindWordsThatCanBeFormedbyCharacters.java b/src/main/java/string/FindWordsThatCanBeFormedbyCharacters.java similarity index 97% rename from problems/src/string/FindWordsThatCanBeFormedbyCharacters.java rename to src/main/java/string/FindWordsThatCanBeFormedbyCharacters.java index ba29748b..c483f816 100644 --- a/problems/src/string/FindWordsThatCanBeFormedbyCharacters.java +++ b/src/main/java/string/FindWordsThatCanBeFormedbyCharacters.java @@ -29,7 +29,7 @@ */ public class FindWordsThatCanBeFormedbyCharacters { public static void main(String[] args) { - String[] A = {"cat", "bt", "hat", "tree"}; + String[] A = {"cat", "bt", "hat", "problems/src/tree"}; String chars = "atach"; new FindWordsThatCanBeFormedbyCharacters().countCharacters(A, chars); } diff --git a/problems/src/string/FirstUniqueCharacterInAString.java b/src/main/java/string/FirstUniqueCharacterInAString.java similarity index 100% rename from problems/src/string/FirstUniqueCharacterInAString.java rename to src/main/java/string/FirstUniqueCharacterInAString.java diff --git a/problems/src/string/ImplementStrStr.java b/src/main/java/string/ImplementStrStr.java similarity index 100% rename from problems/src/string/ImplementStrStr.java rename to src/main/java/string/ImplementStrStr.java diff --git a/problems/src/string/IsomorphicStrings.java b/src/main/java/string/IsomorphicStrings.java similarity index 100% rename from problems/src/string/IsomorphicStrings.java rename to src/main/java/string/IsomorphicStrings.java diff --git a/problems/src/string/KeyboardRow.java b/src/main/java/string/KeyboardRow.java similarity index 100% rename from problems/src/string/KeyboardRow.java rename to src/main/java/string/KeyboardRow.java diff --git a/problems/src/string/LongestCommonPrefix.java b/src/main/java/string/LongestCommonPrefix.java similarity index 100% rename from problems/src/string/LongestCommonPrefix.java rename to src/main/java/string/LongestCommonPrefix.java diff --git a/problems/src/string/LongestPalindrome.java b/src/main/java/string/LongestPalindrome.java similarity index 100% rename from problems/src/string/LongestPalindrome.java rename to src/main/java/string/LongestPalindrome.java diff --git a/problems/src/string/LongestWordInDictonary.java b/src/main/java/string/LongestWordInDictonary.java similarity index 100% rename from problems/src/string/LongestWordInDictonary.java rename to src/main/java/string/LongestWordInDictonary.java diff --git a/problems/src/string/MinimumAddtoMakeParenthesesValid.java b/src/main/java/string/MinimumAddtoMakeParenthesesValid.java similarity index 100% rename from problems/src/string/MinimumAddtoMakeParenthesesValid.java rename to src/main/java/string/MinimumAddtoMakeParenthesesValid.java diff --git a/problems/src/string/MonotoneIncreasingDigits.java b/src/main/java/string/MonotoneIncreasingDigits.java similarity index 100% rename from problems/src/string/MonotoneIncreasingDigits.java rename to src/main/java/string/MonotoneIncreasingDigits.java diff --git a/problems/src/string/MultiplyStrings.java b/src/main/java/string/MultiplyStrings.java similarity index 100% rename from problems/src/string/MultiplyStrings.java rename to src/main/java/string/MultiplyStrings.java diff --git a/problems/src/string/NumberOfMatchingSubsequences.java b/src/main/java/string/NumberOfMatchingSubsequences.java similarity index 100% rename from problems/src/string/NumberOfMatchingSubsequences.java rename to src/main/java/string/NumberOfMatchingSubsequences.java diff --git a/problems/src/string/OneEditDistance.java b/src/main/java/string/OneEditDistance.java similarity index 100% rename from problems/src/string/OneEditDistance.java rename to src/main/java/string/OneEditDistance.java diff --git a/problems/src/string/PermutationInString.java b/src/main/java/string/PermutationInString.java similarity index 100% rename from problems/src/string/PermutationInString.java rename to src/main/java/string/PermutationInString.java diff --git a/problems/src/string/PushDominoes.java b/src/main/java/string/PushDominoes.java similarity index 100% rename from problems/src/string/PushDominoes.java rename to src/main/java/string/PushDominoes.java diff --git a/problems/src/string/ReconstructOriginalDigitsFromEnglish.java b/src/main/java/string/ReconstructOriginalDigitsFromEnglish.java similarity index 100% rename from problems/src/string/ReconstructOriginalDigitsFromEnglish.java rename to src/main/java/string/ReconstructOriginalDigitsFromEnglish.java diff --git a/problems/src/string/RepeatedSubstringPattern.java b/src/main/java/string/RepeatedSubstringPattern.java similarity index 100% rename from problems/src/string/RepeatedSubstringPattern.java rename to src/main/java/string/RepeatedSubstringPattern.java diff --git a/problems/src/string/ReplaceWords.java b/src/main/java/string/ReplaceWords.java similarity index 100% rename from problems/src/string/ReplaceWords.java rename to src/main/java/string/ReplaceWords.java diff --git a/problems/src/string/ReverseStringII.java b/src/main/java/string/ReverseStringII.java similarity index 100% rename from problems/src/string/ReverseStringII.java rename to src/main/java/string/ReverseStringII.java diff --git a/problems/src/string/ReverseWordsII.java b/src/main/java/string/ReverseWordsII.java similarity index 100% rename from problems/src/string/ReverseWordsII.java rename to src/main/java/string/ReverseWordsII.java diff --git a/problems/src/string/ReverseWordsInAString.java b/src/main/java/string/ReverseWordsInAString.java similarity index 100% rename from problems/src/string/ReverseWordsInAString.java rename to src/main/java/string/ReverseWordsInAString.java diff --git a/problems/src/string/RotateString.java b/src/main/java/string/RotateString.java similarity index 100% rename from problems/src/string/RotateString.java rename to src/main/java/string/RotateString.java diff --git a/problems/src/string/ShortestPalindrome.java b/src/main/java/string/ShortestPalindrome.java similarity index 100% rename from problems/src/string/ShortestPalindrome.java rename to src/main/java/string/ShortestPalindrome.java diff --git a/problems/src/string/SimplifyPath.java b/src/main/java/string/SimplifyPath.java similarity index 100% rename from problems/src/string/SimplifyPath.java rename to src/main/java/string/SimplifyPath.java diff --git a/problems/src/string/SplitConcatenatedStrings.java b/src/main/java/string/SplitConcatenatedStrings.java similarity index 100% rename from problems/src/string/SplitConcatenatedStrings.java rename to src/main/java/string/SplitConcatenatedStrings.java diff --git a/problems/src/string/StampingTheSequence.java b/src/main/java/string/StampingTheSequence.java similarity index 100% rename from problems/src/string/StampingTheSequence.java rename to src/main/java/string/StampingTheSequence.java diff --git a/problems/src/string/StringCompression.java b/src/main/java/string/StringCompression.java similarity index 100% rename from problems/src/string/StringCompression.java rename to src/main/java/string/StringCompression.java diff --git a/problems/src/string/StringToInteger.java b/src/main/java/string/StringToInteger.java similarity index 100% rename from problems/src/string/StringToInteger.java rename to src/main/java/string/StringToInteger.java diff --git a/problems/src/string/StudentAttendanceRecordI.java b/src/main/java/string/StudentAttendanceRecordI.java similarity index 100% rename from problems/src/string/StudentAttendanceRecordI.java rename to src/main/java/string/StudentAttendanceRecordI.java diff --git a/problems/src/string/TextJustification.java b/src/main/java/string/TextJustification.java similarity index 100% rename from problems/src/string/TextJustification.java rename to src/main/java/string/TextJustification.java diff --git a/problems/src/string/ValidPalindrome.java b/src/main/java/string/ValidPalindrome.java similarity index 100% rename from problems/src/string/ValidPalindrome.java rename to src/main/java/string/ValidPalindrome.java diff --git a/problems/src/string/ValidPalindromeII.java b/src/main/java/string/ValidPalindromeII.java similarity index 100% rename from problems/src/string/ValidPalindromeII.java rename to src/main/java/string/ValidPalindromeII.java diff --git a/problems/src/string/ValidWordAbbreviation.java b/src/main/java/string/ValidWordAbbreviation.java similarity index 100% rename from problems/src/string/ValidWordAbbreviation.java rename to src/main/java/string/ValidWordAbbreviation.java diff --git a/problems/src/string/ValidWordSquare.java b/src/main/java/string/ValidWordSquare.java similarity index 100% rename from problems/src/string/ValidWordSquare.java rename to src/main/java/string/ValidWordSquare.java diff --git a/problems/src/string/ValidateIPAddress.java b/src/main/java/string/ValidateIPAddress.java similarity index 100% rename from problems/src/string/ValidateIPAddress.java rename to src/main/java/string/ValidateIPAddress.java diff --git a/problems/src/string/ZigZagConversion.java b/src/main/java/string/ZigZagConversion.java similarity index 100% rename from problems/src/string/ZigZagConversion.java rename to src/main/java/string/ZigZagConversion.java diff --git a/problems/src/tree/AllNodesDistanceKInBinaryTree.java b/src/main/java/tree/AllNodesDistanceKInBinaryTree.java similarity index 100% rename from problems/src/tree/AllNodesDistanceKInBinaryTree.java rename to src/main/java/tree/AllNodesDistanceKInBinaryTree.java diff --git a/problems/src/tree/AllPossibleFullBinaryTrees.java b/src/main/java/tree/AllPossibleFullBinaryTrees.java similarity index 100% rename from problems/src/tree/AllPossibleFullBinaryTrees.java rename to src/main/java/tree/AllPossibleFullBinaryTrees.java diff --git a/problems/src/tree/AverageOfLevelsInBinaryTree.java b/src/main/java/tree/AverageOfLevelsInBinaryTree.java similarity index 100% rename from problems/src/tree/AverageOfLevelsInBinaryTree.java rename to src/main/java/tree/AverageOfLevelsInBinaryTree.java diff --git a/problems/src/tree/BSTtoDoublyLinkedList.java b/src/main/java/tree/BSTtoDoublyLinkedList.java similarity index 100% rename from problems/src/tree/BSTtoDoublyLinkedList.java rename to src/main/java/tree/BSTtoDoublyLinkedList.java diff --git a/problems/src/tree/BinarayTreeRightSideView.java b/src/main/java/tree/BinarayTreeRightSideView.java similarity index 100% rename from problems/src/tree/BinarayTreeRightSideView.java rename to src/main/java/tree/BinarayTreeRightSideView.java diff --git a/problems/src/tree/BinaryTreeInorderTraversal.java b/src/main/java/tree/BinaryTreeInorderTraversal.java similarity index 100% rename from problems/src/tree/BinaryTreeInorderTraversal.java rename to src/main/java/tree/BinaryTreeInorderTraversal.java diff --git a/problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java b/src/main/java/tree/BinaryTreeLongestConsecutiveSequenceII.java similarity index 100% rename from problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java rename to src/main/java/tree/BinaryTreeLongestConsecutiveSequenceII.java diff --git a/problems/src/tree/BinaryTreeMaximumPathSum.java b/src/main/java/tree/BinaryTreeMaximumPathSum.java similarity index 100% rename from problems/src/tree/BinaryTreeMaximumPathSum.java rename to src/main/java/tree/BinaryTreeMaximumPathSum.java diff --git a/problems/src/tree/BinaryTreePaths.java b/src/main/java/tree/BinaryTreePaths.java similarity index 100% rename from problems/src/tree/BinaryTreePaths.java rename to src/main/java/tree/BinaryTreePaths.java diff --git a/problems/src/tree/BinaryTreePostorderTraversal.java b/src/main/java/tree/BinaryTreePostorderTraversal.java similarity index 100% rename from problems/src/tree/BinaryTreePostorderTraversal.java rename to src/main/java/tree/BinaryTreePostorderTraversal.java diff --git a/problems/src/tree/BinaryTreeTilt.java b/src/main/java/tree/BinaryTreeTilt.java similarity index 100% rename from problems/src/tree/BinaryTreeTilt.java rename to src/main/java/tree/BinaryTreeTilt.java diff --git a/problems/src/tree/BoundaryOfBinaryTree.java b/src/main/java/tree/BoundaryOfBinaryTree.java similarity index 100% rename from problems/src/tree/BoundaryOfBinaryTree.java rename to src/main/java/tree/BoundaryOfBinaryTree.java diff --git a/problems/src/tree/ClosestBinarySearchTreeValue.java b/src/main/java/tree/ClosestBinarySearchTreeValue.java similarity index 100% rename from problems/src/tree/ClosestBinarySearchTreeValue.java rename to src/main/java/tree/ClosestBinarySearchTreeValue.java diff --git a/problems/src/tree/ClosestLeafInABinaryTree.java b/src/main/java/tree/ClosestLeafInABinaryTree.java similarity index 100% rename from problems/src/tree/ClosestLeafInABinaryTree.java rename to src/main/java/tree/ClosestLeafInABinaryTree.java diff --git a/problems/src/tree/ConstructBinaryTreefromString.java b/src/main/java/tree/ConstructBinaryTreefromString.java similarity index 100% rename from problems/src/tree/ConstructBinaryTreefromString.java rename to src/main/java/tree/ConstructBinaryTreefromString.java diff --git a/problems/src/tree/ConstructStringFromBinaryTree.java b/src/main/java/tree/ConstructStringFromBinaryTree.java similarity index 100% rename from problems/src/tree/ConstructStringFromBinaryTree.java rename to src/main/java/tree/ConstructStringFromBinaryTree.java diff --git a/problems/src/tree/ConvertBSTToGreaterTree.java b/src/main/java/tree/ConvertBSTToGreaterTree.java similarity index 100% rename from problems/src/tree/ConvertBSTToGreaterTree.java rename to src/main/java/tree/ConvertBSTToGreaterTree.java diff --git a/problems/src/tree/ConvertSortedArrayToBST.java b/src/main/java/tree/ConvertSortedArrayToBST.java similarity index 100% rename from problems/src/tree/ConvertSortedArrayToBST.java rename to src/main/java/tree/ConvertSortedArrayToBST.java diff --git a/problems/src/tree/DiameterOfBinaryTree.java b/src/main/java/tree/DiameterOfBinaryTree.java similarity index 100% rename from problems/src/tree/DiameterOfBinaryTree.java rename to src/main/java/tree/DiameterOfBinaryTree.java diff --git a/problems/src/tree/EqualTreePartition.java b/src/main/java/tree/EqualTreePartition.java similarity index 100% rename from problems/src/tree/EqualTreePartition.java rename to src/main/java/tree/EqualTreePartition.java diff --git a/problems/src/tree/FindBottomLeftTreeValue.java b/src/main/java/tree/FindBottomLeftTreeValue.java similarity index 100% rename from problems/src/tree/FindBottomLeftTreeValue.java rename to src/main/java/tree/FindBottomLeftTreeValue.java diff --git a/problems/src/tree/FindLargestValueInEachTreeRow.java b/src/main/java/tree/FindLargestValueInEachTreeRow.java similarity index 100% rename from problems/src/tree/FindLargestValueInEachTreeRow.java rename to src/main/java/tree/FindLargestValueInEachTreeRow.java diff --git a/problems/src/tree/FlattenBinaryTree.java b/src/main/java/tree/FlattenBinaryTree.java similarity index 100% rename from problems/src/tree/FlattenBinaryTree.java rename to src/main/java/tree/FlattenBinaryTree.java diff --git a/problems/src/tree/FlipBinaryTree.java b/src/main/java/tree/FlipBinaryTree.java similarity index 100% rename from problems/src/tree/FlipBinaryTree.java rename to src/main/java/tree/FlipBinaryTree.java diff --git a/problems/src/tree/FlipEquivalentBinaryTrees.java b/src/main/java/tree/FlipEquivalentBinaryTrees.java similarity index 100% rename from problems/src/tree/FlipEquivalentBinaryTrees.java rename to src/main/java/tree/FlipEquivalentBinaryTrees.java diff --git a/problems/src/tree/InorderSuccessorInBST.java b/src/main/java/tree/InorderSuccessorInBST.java similarity index 100% rename from problems/src/tree/InorderSuccessorInBST.java rename to src/main/java/tree/InorderSuccessorInBST.java diff --git a/problems/src/tree/InsufficientNodesinRoottoLeafPaths.java b/src/main/java/tree/InsufficientNodesinRoottoLeafPaths.java similarity index 100% rename from problems/src/tree/InsufficientNodesinRoottoLeafPaths.java rename to src/main/java/tree/InsufficientNodesinRoottoLeafPaths.java diff --git a/problems/src/tree/LCA.java b/src/main/java/tree/LCA.java similarity index 100% rename from problems/src/tree/LCA.java rename to src/main/java/tree/LCA.java diff --git a/problems/src/tree/LargestBSTSubtree.java b/src/main/java/tree/LargestBSTSubtree.java similarity index 100% rename from problems/src/tree/LargestBSTSubtree.java rename to src/main/java/tree/LargestBSTSubtree.java diff --git a/problems/src/tree/LeafSimilarTrees.java b/src/main/java/tree/LeafSimilarTrees.java similarity index 100% rename from problems/src/tree/LeafSimilarTrees.java rename to src/main/java/tree/LeafSimilarTrees.java diff --git a/problems/src/tree/LowestCommonAncestorBST.java b/src/main/java/tree/LowestCommonAncestorBST.java similarity index 100% rename from problems/src/tree/LowestCommonAncestorBST.java rename to src/main/java/tree/LowestCommonAncestorBST.java diff --git a/problems/src/tree/MaximumBinaryTree.java b/src/main/java/tree/MaximumBinaryTree.java similarity index 100% rename from problems/src/tree/MaximumBinaryTree.java rename to src/main/java/tree/MaximumBinaryTree.java diff --git a/problems/src/tree/MaximumLevelSumofABinaryTree.java b/src/main/java/tree/MaximumLevelSumofABinaryTree.java similarity index 100% rename from problems/src/tree/MaximumLevelSumofABinaryTree.java rename to src/main/java/tree/MaximumLevelSumofABinaryTree.java diff --git a/problems/src/tree/MaximumWidthOfBinaryTree.java b/src/main/java/tree/MaximumWidthOfBinaryTree.java similarity index 100% rename from problems/src/tree/MaximumWidthOfBinaryTree.java rename to src/main/java/tree/MaximumWidthOfBinaryTree.java diff --git a/problems/src/tree/MinimumAbsoluteDifferenceInBST.java b/src/main/java/tree/MinimumAbsoluteDifferenceInBST.java similarity index 100% rename from problems/src/tree/MinimumAbsoluteDifferenceInBST.java rename to src/main/java/tree/MinimumAbsoluteDifferenceInBST.java diff --git a/problems/src/tree/MostFrequentSubtreeSum.java b/src/main/java/tree/MostFrequentSubtreeSum.java similarity index 100% rename from problems/src/tree/MostFrequentSubtreeSum.java rename to src/main/java/tree/MostFrequentSubtreeSum.java diff --git a/problems/src/tree/NextRightPointer.java b/src/main/java/tree/NextRightPointer.java similarity index 100% rename from problems/src/tree/NextRightPointer.java rename to src/main/java/tree/NextRightPointer.java diff --git a/problems/src/tree/NextRightPointerII.java b/src/main/java/tree/NextRightPointerII.java similarity index 100% rename from problems/src/tree/NextRightPointerII.java rename to src/main/java/tree/NextRightPointerII.java diff --git a/problems/src/tree/PathSumIII.java b/src/main/java/tree/PathSumIII.java similarity index 100% rename from problems/src/tree/PathSumIII.java rename to src/main/java/tree/PathSumIII.java diff --git a/problems/src/tree/PostorderToBT.java b/src/main/java/tree/PostorderToBT.java similarity index 100% rename from problems/src/tree/PostorderToBT.java rename to src/main/java/tree/PostorderToBT.java diff --git a/problems/src/tree/PreorderToBT.java b/src/main/java/tree/PreorderToBT.java similarity index 100% rename from problems/src/tree/PreorderToBT.java rename to src/main/java/tree/PreorderToBT.java diff --git a/problems/src/tree/RecoverBinarySearchTree.java b/src/main/java/tree/RecoverBinarySearchTree.java similarity index 100% rename from problems/src/tree/RecoverBinarySearchTree.java rename to src/main/java/tree/RecoverBinarySearchTree.java diff --git a/problems/src/tree/SameTree.java b/src/main/java/tree/SameTree.java similarity index 100% rename from problems/src/tree/SameTree.java rename to src/main/java/tree/SameTree.java diff --git a/problems/src/tree/SerializeAndDeserializeNAryTree.java b/src/main/java/tree/SerializeAndDeserializeNAryTree.java similarity index 100% rename from problems/src/tree/SerializeAndDeserializeNAryTree.java rename to src/main/java/tree/SerializeAndDeserializeNAryTree.java diff --git a/problems/src/tree/SortedArrayToBST.java b/src/main/java/tree/SortedArrayToBST.java similarity index 100% rename from problems/src/tree/SortedArrayToBST.java rename to src/main/java/tree/SortedArrayToBST.java diff --git a/problems/src/tree/SplitBST.java b/src/main/java/tree/SplitBST.java similarity index 100% rename from problems/src/tree/SplitBST.java rename to src/main/java/tree/SplitBST.java diff --git a/problems/src/tree/SubtreeOfAnotherTree.java b/src/main/java/tree/SubtreeOfAnotherTree.java similarity index 100% rename from problems/src/tree/SubtreeOfAnotherTree.java rename to src/main/java/tree/SubtreeOfAnotherTree.java diff --git a/problems/src/tree/SumofLeftLeaves.java b/src/main/java/tree/SumofLeftLeaves.java similarity index 100% rename from problems/src/tree/SumofLeftLeaves.java rename to src/main/java/tree/SumofLeftLeaves.java diff --git a/problems/src/tree/SymmetricTree.java b/src/main/java/tree/SymmetricTree.java similarity index 100% rename from problems/src/tree/SymmetricTree.java rename to src/main/java/tree/SymmetricTree.java diff --git a/problems/src/tree/TwoSumIV.java b/src/main/java/tree/TwoSumIV.java similarity index 100% rename from problems/src/tree/TwoSumIV.java rename to src/main/java/tree/TwoSumIV.java diff --git a/problems/src/tree/ValidBinarySearchTree.java b/src/main/java/tree/ValidBinarySearchTree.java similarity index 100% rename from problems/src/tree/ValidBinarySearchTree.java rename to src/main/java/tree/ValidBinarySearchTree.java diff --git a/problems/src/tree/ZigZagTraversal.java b/src/main/java/tree/ZigZagTraversal.java similarity index 100% rename from problems/src/tree/ZigZagTraversal.java rename to src/main/java/tree/ZigZagTraversal.java diff --git a/problems/src/two_pointers/FourSum.java b/src/main/java/two_pointers/FourSum.java similarity index 100% rename from problems/src/two_pointers/FourSum.java rename to src/main/java/two_pointers/FourSum.java diff --git a/problems/src/two_pointers/LastSubstringInLexicographicalOrder.java b/src/main/java/two_pointers/LastSubstringInLexicographicalOrder.java similarity index 100% rename from problems/src/two_pointers/LastSubstringInLexicographicalOrder.java rename to src/main/java/two_pointers/LastSubstringInLexicographicalOrder.java diff --git a/problems/src/two_pointers/LongestSubstringWitoutRepeats.java b/src/main/java/two_pointers/LongestSubstringWitoutRepeats.java similarity index 100% rename from problems/src/two_pointers/LongestSubstringWitoutRepeats.java rename to src/main/java/two_pointers/LongestSubstringWitoutRepeats.java diff --git a/problems/src/two_pointers/MinimumSizeSubarraySum.java b/src/main/java/two_pointers/MinimumSizeSubarraySum.java similarity index 100% rename from problems/src/two_pointers/MinimumSizeSubarraySum.java rename to src/main/java/two_pointers/MinimumSizeSubarraySum.java diff --git a/problems/src/two_pointers/MinimumWindowSubstring.java b/src/main/java/two_pointers/MinimumWindowSubstring.java similarity index 100% rename from problems/src/two_pointers/MinimumWindowSubstring.java rename to src/main/java/two_pointers/MinimumWindowSubstring.java diff --git a/problems/src/two_pointers/MoveZeroes.java b/src/main/java/two_pointers/MoveZeroes.java similarity index 100% rename from problems/src/two_pointers/MoveZeroes.java rename to src/main/java/two_pointers/MoveZeroes.java diff --git a/problems/src/two_pointers/NumberOfMatchingSubsequences.java b/src/main/java/two_pointers/NumberOfMatchingSubsequences.java similarity index 100% rename from problems/src/two_pointers/NumberOfMatchingSubsequences.java rename to src/main/java/two_pointers/NumberOfMatchingSubsequences.java diff --git a/problems/src/two_pointers/RemoveDuplicates.java b/src/main/java/two_pointers/RemoveDuplicates.java similarity index 100% rename from problems/src/two_pointers/RemoveDuplicates.java rename to src/main/java/two_pointers/RemoveDuplicates.java diff --git a/problems/src/two_pointers/RemoveDuplicatesII.java b/src/main/java/two_pointers/RemoveDuplicatesII.java similarity index 100% rename from problems/src/two_pointers/RemoveDuplicatesII.java rename to src/main/java/two_pointers/RemoveDuplicatesII.java diff --git a/problems/src/two_pointers/SmallestRange.java b/src/main/java/two_pointers/SmallestRange.java similarity index 100% rename from problems/src/two_pointers/SmallestRange.java rename to src/main/java/two_pointers/SmallestRange.java diff --git a/problems/src/two_pointers/SubarrayProductLessThanK.java b/src/main/java/two_pointers/SubarrayProductLessThanK.java similarity index 100% rename from problems/src/two_pointers/SubarrayProductLessThanK.java rename to src/main/java/two_pointers/SubarrayProductLessThanK.java diff --git a/problems/src/two_pointers/SubarraysWithKDifferentIntegers.java b/src/main/java/two_pointers/SubarraysWithKDifferentIntegers.java similarity index 100% rename from problems/src/two_pointers/SubarraysWithKDifferentIntegers.java rename to src/main/java/two_pointers/SubarraysWithKDifferentIntegers.java diff --git a/problems/src/two_pointers/ThreeSum.java b/src/main/java/two_pointers/ThreeSum.java similarity index 100% rename from problems/src/two_pointers/ThreeSum.java rename to src/main/java/two_pointers/ThreeSum.java diff --git a/problems/src/two_pointers/ThreeSumClosest.java b/src/main/java/two_pointers/ThreeSumClosest.java similarity index 100% rename from problems/src/two_pointers/ThreeSumClosest.java rename to src/main/java/two_pointers/ThreeSumClosest.java diff --git a/problems/src/two_pointers/TrappingRainWater.java b/src/main/java/two_pointers/TrappingRainWater.java similarity index 100% rename from problems/src/two_pointers/TrappingRainWater.java rename to src/main/java/two_pointers/TrappingRainWater.java From c2e7d31bd70b993b790204d5d237050578ae9f67 Mon Sep 17 00:00:00 2001 From: Goutham Vidya Pradhan Date: Thu, 5 Dec 2024 21:36:29 +0100 Subject: [PATCH 231/235] Minimize the Maximum Adjacent Element Difference --- README.md | 1 + build.gradle | 4 +- ...zeTheMaximumAdjacentElementDifference.java | 107 ++++++++++++++++++ 3 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 src/main/java/binary_search/MinimizeTheMaximumAdjacentElementDifference.java diff --git a/README.md b/README.md index 525f428b..5bd66863 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,7 @@ My accepted leetcode solutions to some of the common interview problems. - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Window Subsequence](src/main/java/binary_search/MinimumWindowSubsequence.java) (Hard) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Koko Eating Bananas](src/main/java/binary_search/KokoEatingBananas.java) (Hard) - [Single Element in a Sorted Array](src/main/java/binary_search/SingleElementInASortedArray.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimize the Maximum Adjacent Element Difference](src/main/java/binary_search/MinimizeTheMaximumAdjacentElementDifference.java) (Hard) #### [Bit Manipulation](src/main/java/bit_manipulation) diff --git a/build.gradle b/build.gradle index 22aa07b4..e807b14d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,10 @@ plugins { id 'java' - id 'com.github.sherter.google-java-format' version '0.8' + id 'com.github.sherter.google-java-format' version '0.9' } dependencies { - implementation 'com.google.googlejavaformat:google-java-format:1.12.0' + implementation 'com.google.googlejavaformat:google-java-format:1.8.0' } repositories { diff --git a/src/main/java/binary_search/MinimizeTheMaximumAdjacentElementDifference.java b/src/main/java/binary_search/MinimizeTheMaximumAdjacentElementDifference.java new file mode 100644 index 00000000..63e054a4 --- /dev/null +++ b/src/main/java/binary_search/MinimizeTheMaximumAdjacentElementDifference.java @@ -0,0 +1,107 @@ +package binary_search; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class MinimizeTheMaximumAdjacentElementDifference { + record Interval(int s, int e, boolean hasMoreThanOne){ + static boolean check(int a, int mid, int b, int range){ + return Math.abs(mid - a) <= range && Math.abs(mid - b) <= range; + } + static boolean check(int a, int mid1, int mid2, int b, int range){ + return Math.abs(mid1 - a) <= range && Math.abs(mid1 - mid2) <= range && Math.abs(mid2 - b) <= range; + } + } + + public static void main(String[] args) { + int[] nums = new int[]{-1,10,-1,8}; + int res = new MinimizeTheMaximumAdjacentElementDifference().minDifference(nums); + System.out.println(res); + } + + public int minDifference(int[] nums) { + boolean noPositiveNum = Arrays.stream(nums).filter(i -> i != -1).findAny().isEmpty(); + if(noPositiveNum){ + return 0; + } + int currentMax = getCurrentMax(nums); + List intervals = buildIntervals(nums); + int minStart = Integer.MAX_VALUE, maxEnd = Integer.MIN_VALUE; + for (Interval interval : intervals) { + minStart = Math.min(minStart, Math.min(interval.e, interval.s)); + maxEnd = Math.max(maxEnd, Math.max(interval.e, interval.s)); + } + int l = 0, h = maxEnd, m; + int ans = -1; + while(l <= h){ + m = l + (h - l) / 2; + boolean result = checkIfThisNumberSatisfiesAllIntervals(intervals, minStart + m, maxEnd - m, m); + if(result){ + ans = m; + h = m - 1; + } else { + l = m + 1; + } + } + return Math.max(ans, currentMax); + } + + private int getCurrentMax(int[] nums){ + int currMax = Integer.MIN_VALUE; + int previous = nums[0]; + for(int i = 1; i < nums.length; i ++){ + if(nums[i] != -1){ + if(previous != -1){ + currMax = Math.max(currMax, Math.abs(previous - nums[i])); + } + previous = nums[i]; + } else { + previous = -1; + } + } + return currMax; + } + + private List buildIntervals(int[] nums) { + int previous = -1; + int minusOneCount = 0; + List intervals = new ArrayList<>(); + for (int num : nums) { + if (num == -1) { + minusOneCount ++; + } else { + if (minusOneCount > 0) { + intervals.add(new Interval(previous != -1 ? previous : num, num, minusOneCount > 1)); + minusOneCount = 0; + } + previous = num; + } + } + if(nums[nums.length - 1] == -1){ + intervals.add(new Interval(previous, previous, minusOneCount > 1)); + } + return intervals; + } + + boolean checkIfThisNumberSatisfiesAllIntervals(List intervals, int minStart, int maxEnd, int maxDiff){ + for (Interval interval : intervals) { + if (interval.hasMoreThanOne) { + boolean res1 = Interval.check(interval.s, minStart, minStart, interval.e, maxDiff); + boolean res2 = Interval.check(interval.s, minStart, maxEnd, interval.e, maxDiff); + boolean res3 = Interval.check(interval.s, maxEnd, minStart, interval.e, maxDiff); + boolean res4 = Interval.check(interval.s, maxEnd, maxEnd, interval.e, maxDiff); + if (!res1 && !res2 && !res3 && !res4) { + return false; + } + } else { + boolean res1 = Interval.check(interval.s, minStart, interval.e, maxDiff); + boolean res2 = Interval.check(interval.s, maxEnd, interval.e, maxDiff); + if (!res1 && !res2) { + return false; + } + } + } + return true; + } +} From 26db48717370a02e47ce1fab76b3e4e697a4512e Mon Sep 17 00:00:00 2001 From: Goutham Vidya Pradhan Date: Thu, 5 Dec 2024 23:08:26 +0100 Subject: [PATCH 232/235] Adding youtube video link --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5bd66863..cadb8796 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Leetcode solutions in Java -My accepted leetcode solutions to some of the common interview problems. +My accepted leetcode solutions to some of the common interview problems. +Also, some solutions have youtube video link. #### [Array](src/main/java/array) @@ -103,7 +104,8 @@ My accepted leetcode solutions to some of the common interview problems. - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Window Subsequence](src/main/java/binary_search/MinimumWindowSubsequence.java) (Hard) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Koko Eating Bananas](src/main/java/binary_search/KokoEatingBananas.java) (Hard) - [Single Element in a Sorted Array](src/main/java/binary_search/SingleElementInASortedArray.java) (Medium) -- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimize the Maximum Adjacent Element Difference](src/main/java/binary_search/MinimizeTheMaximumAdjacentElementDifference.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimize the Maximum Adjacent Element Difference](src/main/java/binary_search/MinimizeTheMaximumAdjacentElementDifference.java) (Hard) + - [Youtube video explanation](https://www.youtube.com/watch?v=2fCtjA_eitU&t=496s) #### [Bit Manipulation](src/main/java/bit_manipulation) From 0f83c2fea20c68dcc357162ba18af638b74cd1c4 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 6 Dec 2024 08:54:34 +0100 Subject: [PATCH 233/235] update youtube link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cadb8796..0a7c2afb 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ Also, some solutions have youtube video link. - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Koko Eating Bananas](src/main/java/binary_search/KokoEatingBananas.java) (Hard) - [Single Element in a Sorted Array](src/main/java/binary_search/SingleElementInASortedArray.java) (Medium) - ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimize the Maximum Adjacent Element Difference](src/main/java/binary_search/MinimizeTheMaximumAdjacentElementDifference.java) (Hard) - - [Youtube video explanation](https://www.youtube.com/watch?v=2fCtjA_eitU&t=496s) + - [Youtube video explanation](https://www.youtube.com/watch?v=2fCtjA_eitU) #### [Bit Manipulation](src/main/java/bit_manipulation) From 30eb429f5a81f5c27050514983ea466555011124 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 6 Dec 2024 09:48:41 +0100 Subject: [PATCH 234/235] Formatting and upgrade to latest gradle and java23 --- build.gradle | 27 ++++++++++++++++--- .../java/array/AddToArrayFormOfInteger.java | 1 + src/main/java/array/ArrayNesting.java | 1 + src/main/java/array/ArrayPartitionI.java | 1 + src/main/java/array/BattleshipsInABoard.java | 1 + src/main/java/array/BestMeetingPoint.java | 1 + src/main/java/array/CanPlaceFlowers.java | 1 + src/main/java/array/CardFilipGame.java | 1 + src/main/java/array/ChampagneTower.java | 1 + src/main/java/array/EmployeeFreeTime.java | 1 + src/main/java/array/FindPivotIndex.java | 1 + src/main/java/array/FindTheCelebrity.java | 1 + src/main/java/array/FirstMissingPositive.java | 1 + src/main/java/array/FruitIntoBaskets.java | 1 + src/main/java/array/HIndex.java | 1 + src/main/java/array/ImageSmoother.java | 1 + .../array/IncreasingTripletSubsequence.java | 1 + src/main/java/array/InsertInterval.java | 1 + src/main/java/array/KEmptySlots.java | 1 + .../java/array/LargestNumberAtLeastTwice.java | 1 + .../java/array/LargestTimeForGivenDigits.java | 1 + .../array/LongestIncreasingSubsequence.java | 1 + .../LongestLineofConsecutiveOneinMatrix.java | 1 + .../array/MatrixCellsinDistanceOrder.java | 1 + src/main/java/array/MaxConsecutiveOnes.java | 1 + src/main/java/array/MaxConsecutiveOnesII.java | 1 + .../java/array/MaxProductOfThreeNumbers.java | 1 + ...aximumSumofTwoNonOverlappingSubarrays.java | 1 + src/main/java/array/MaximumSwap.java | 1 + src/main/java/array/MeetingRooms.java | 1 + src/main/java/array/MeetingScheduler.java | 1 + src/main/java/array/MergeIntervals.java | 1 + src/main/java/array/MergeSortedArray.java | 1 + .../java/array/MinimumIndexSumOfTwoLists.java | 1 + .../java/array/MinimumMovesToEqualArray.java | 1 + .../MinimumSwapsToGroupAll1Together.java | 1 + .../java/array/MinimumTimeDifference.java | 1 + src/main/java/array/MissingNumber.java | 1 + src/main/java/array/MyCalendarThree.java | 1 + src/main/java/array/NextGreaterElementI.java | 1 + src/main/java/array/PascalsTriangle.java | 1 + src/main/java/array/PourWater.java | 1 + .../java/array/ProductOfArrayExceptSelf.java | 1 + src/main/java/array/ReadNCharacters.java | 1 + src/main/java/array/RelativeRanks.java | 1 + src/main/java/array/RelativeSortArray.java | 1 + .../array/RevealCardsInIncreasingOrder.java | 1 + src/main/java/array/RotateArray.java | 1 + src/main/java/array/RotateMatrix.java | 1 + src/main/java/array/SetMatrixZeroes.java | 1 + src/main/java/array/SortArrayByParityII.java | 1 + src/main/java/array/SortColors.java | 1 + .../array/SparseMatrixMultiplication.java | 1 + .../array/SubArraysWithBoundedMaximum.java | 1 + src/main/java/array/SubarraySumEqualsK.java | 1 + .../java/array/SurfaceAreaOfThreeDShapes.java | 1 + src/main/java/array/ThirdMaximumNumber.java | 1 + src/main/java/array/TwoSum.java | 1 + src/main/java/array/TwoSumII.java | 1 + src/main/java/array/ValidTicTacToeState.java | 1 + .../java/backtracking/CombinationSum.java | 1 + .../java/backtracking/CombinationSumII.java | 1 + src/main/java/backtracking/Combinations.java | 1 + .../backtracking/ExpressionAddOperators.java | 1 + .../backtracking/GenerateParentheses.java | 1 + .../backtracking/LetterCasePermutation.java | 1 + .../java/backtracking/LetterPhoneNumber.java | 1 + .../backtracking/MatchsticksToSquare.java | 1 + .../backtracking/PalindromePartitioning.java | 1 + src/main/java/backtracking/Permutations.java | 1 + .../java/backtracking/PermutationsII.java | 1 + .../RegularExpressionMatching.java | 1 + .../RemoveInvalidParentheses.java | 1 + src/main/java/backtracking/Subsets.java | 1 + src/main/java/backtracking/SubsetsII.java | 1 + src/main/java/backtracking/TargetSum.java | 1 + .../java/backtracking/WildcardMatching.java | 1 + src/main/java/backtracking/WordSearch.java | 1 + src/main/java/backtracking/WordSearchII.java | 1 + src/main/java/backtracking/ZumaGame.java | 1 + .../java/binary_search/ArmstrongNumber.java | 1 + .../java/binary_search/FindPeakElement.java | 1 + .../java/binary_search/FirstBadVersion.java | 1 + src/main/java/binary_search/HIndexII.java | 1 + .../java/binary_search/KokoEatingBananas.java | 1 + .../MedianOfTwoSortedArrays.java | 1 + .../binary_search/MinSortedRotatedArray.java | 1 + ...zeTheMaximumAdjacentElementDifference.java | 1 + .../MinimumWindowSubsequence.java | 1 + src/main/java/binary_search/PowXN.java | 1 + .../java/binary_search/SearchForARange.java | 1 + .../binary_search/SearchInsertPosition.java | 1 + .../SearchRotatedSortedArray.java | 1 + .../SingleElementInASortedArray.java | 1 + src/main/java/binary_search/SqrtX.java | 1 + .../java/binary_search/SwimInRisingWater.java | 1 + .../binary_search/TimeBasedKeyValuePair.java | 1 + .../BinaryNumberWithAlternatingBits.java | 1 + .../java/bit_manipulation/BinaryWatch.java | 1 + .../bit_manipulation/DivideTwoIntegers.java | 1 + src/main/java/bit_manipulation/GrayCode.java | 1 + .../bit_manipulation/HammingDistance.java | 1 + .../TotalHammingDistance.java | 1 + .../BinarayTreeLevelOrderTraversal.java | 1 + .../java/breadth_first_search/BusRoutes.java | 1 + .../CutOffTreesForGolfEvent.java | 1 + .../java/breadth_first_search/Matrix.java | 1 + .../breadth_first_search/OpenTheLock.java | 1 + .../java/breadth_first_search/RaceCar.java | 1 + .../breadth_first_search/RottingOranges.java | 1 + .../breadth_first_search/SlidingPuzzle.java | 1 + .../breadth_first_search/WallsAndGates.java | 1 + .../java/breadth_first_search/WordLadder.java | 1 + .../breadth_first_search/WordLadderII.java | 1 + .../depth_first_search/AccountsMerge.java | 1 + .../depth_first_search/AlienDictionary.java | 1 + .../AllPathsFromSourceToTarget.java | 1 + .../AsFarfromLandAsPossible.java | 1 + .../BricksFallingWhenHit.java | 1 + .../java/depth_first_search/CloneGraph.java | 1 + .../ConnectingCitiesWithMinimumCost.java | 1 + .../depth_first_search/CourseSchedule.java | 1 + .../depth_first_search/CourseScheduleII.java | 1 + .../depth_first_search/CrackingTheSafe.java | 1 + .../CriticalConnection.java | 1 + .../java/depth_first_search/FloodFill.java | 1 + .../depth_first_search/GraphValidTree.java | 1 + .../depth_first_search/IslandPerimeter.java | 1 + .../LongestConsecutiveSequence.java | 1 + .../depth_first_search/MaxAreaOfIsland.java | 1 + .../java/depth_first_search/Minesweeper.java | 1 + .../MinimizeMalwareSpread.java | 1 + .../depth_first_search/MovieRecommend.java | 1 + .../NumberOfDistinctIslands.java | 1 + .../NumberOfDistinctIslandsII.java | 1 + .../depth_first_search/NumberOfEnclaves.java | 1 + .../depth_first_search/NumberOfIslands.java | 1 + .../depth_first_search/ParallelCourses.java | 1 + .../depth_first_search/RobotRoomCleaner.java | 1 + .../SatisfiabilityOfEquations.java | 1 + ...SmallestRectangleEnclosingBlackPixels.java | 1 + src/main/java/design/AutocompleteSystem.java | 1 + src/main/java/design/BSTIterator.java | 1 + .../design/CopyListWithRandomPointer.java | 1 + .../java/design/EncodeAndDecodeTinyURL.java | 1 + src/main/java/design/Excel.java | 1 + src/main/java/design/LFUCache.java | 1 + src/main/java/design/LRUCache.java | 1 + src/main/java/design/NestedIterator.java | 1 + .../java/design/RandomizedCollection.java | 1 + src/main/java/design/RandomizedSet.java | 1 + .../SerializeDeserializeBinaryTree.java | 1 + src/main/java/design/TicTacToe.java | 1 + src/main/java/design/Trie.java | 1 + src/main/java/design/Twitter.java | 1 + src/main/java/design/WordDictionary.java | 1 + src/main/java/design/WordFilter.java | 1 + .../KthLargestElementInAnArray.java | 1 + .../java/divide_and_conquer/MyCalendarII.java | 1 + .../java/divide_and_conquer/ReversePairs.java | 1 + .../divide_and_conquer/ReversePairsII.java | 1 + .../divide_and_conquer/SearchA2DMatrix.java | 1 + .../divide_and_conquer/TwentyFourGame.java | 1 + .../BestTimeToBuyAndSellStockIII.java | 1 + .../BestTimeToBuyAndSellStocks.java | 1 + .../BestTimeToBuyAndSellStocksWithFee.java | 1 + .../java/dynamic_programming/BombEnemy.java | 1 + .../dynamic_programming/BurstBalloons.java | 1 + .../java/dynamic_programming/CanIWin.java | 1 + .../java/dynamic_programming/CatAndMouse.java | 1 + .../dynamic_programming/CherryPickup.java | 1 + .../dynamic_programming/CherryPickupII.java | 1 + .../dynamic_programming/ClimbingStairs.java | 1 + .../java/dynamic_programming/CoinChange.java | 1 + .../java/dynamic_programming/CoinChange2.java | 1 + .../dynamic_programming/CombinationSumIV.java | 1 + .../ConcatenatedWords.java | 1 + .../ConstrainedSubsequenceSum.java | 1 + .../ContinuousSubarraySum.java | 1 + .../dynamic_programming/CornerRectangles.java | 1 + ...CountDifferentPalindromicSubsequences.java | 1 + .../CountVowelsPermutation.java | 1 + .../java/dynamic_programming/DecodeWays.java | 1 + .../dynamic_programming/DecodeWaysII.java | 1 + .../DeleteColumnsToMakeSortedIII.java | 1 + .../DistinctSubsequences.java | 1 + .../DistinctSubsequencesII.java | 1 + .../java/dynamic_programming/DungeonGame.java | 1 + .../EncodeStringWithShortestLength.java | 1 + .../dynamic_programming/FreedomTrail.java | 1 + .../HandshakesThatDontCross.java | 1 + .../java/dynamic_programming/HouseRobber.java | 1 + .../dynamic_programming/HouseRobberII.java | 1 + .../InterleavingString.java | 1 + .../java/dynamic_programming/JumpGameV.java | 1 + .../dynamic_programming/KnightDialer.java | 1 + .../KnightProbabilityInChessboard.java | 1 + .../LargestMultipleOfThree.java | 1 + .../dynamic_programming/LargestPlusSign.java | 1 + .../LargestSumOfAverages.java | 1 + .../LengthofLongestFibonacciSubsequence.java | 1 + ...LongestChunkedPalindromeDecomposition.java | 1 + .../LongestIncreasingSubsequence.java | 1 + .../LongestPaliandromicSubstring.java | 1 + .../LongestPalindromicSubsequence.java | 1 + .../MakeArrayStrictlyIncreasing.java | 1 + .../dynamic_programming/MaxSum3SubArray.java | 1 + .../dynamic_programming/MaximalSquare.java | 1 + .../MaximumProductSubarray.java | 1 + .../MaximumProfitInJobScheduling.java | 1 + .../dynamic_programming/MaximumSubarray.java | 1 + .../MaximumVacationDays.java | 1 + .../MinCostClimbingStairs.java | 1 + .../MinimumCostForTickets.java | 1 + .../MinimumCostToMergeStones.java | 1 + .../MinimumDifficultyOfAJobSchedule.java | 1 + ...mumDistanceToTypeAWordUsingTwoFingers.java | 1 + .../MinimumNumberOfRefuelingStops.java | 1 + .../MinimumNumberOfTaps.java | 1 + ...egativeIntegersWithoutConsecutiveOnes.java | 1 + .../NumberOfDiceRollsWithTargetSum.java | 1 + .../java/dynamic_programming/NumberOfLIS.java | 1 + .../NumberOfMusicPlaylists.java | 1 + .../NumberOfPathsWithMaxScore.java | 1 + .../NumberOfWaysToStayInTheSamePlace.java | 1 + .../java/dynamic_programming/OddEvenJump.java | 1 + .../dynamic_programming/OnesAndZeroes.java | 1 + .../OutOfBoundaryPaths.java | 1 + .../dynamic_programming/PaintHouseII.java | 1 + .../dynamic_programming/PaintHouseIII.java | 1 + .../dynamic_programming/PalindromePairs.java | 1 + .../PalindromePartitioningII.java | 1 + .../PalindromePartitioningIII.java | 1 + .../PalindromeRemoval.java | 1 + .../PalindromicSubstrings.java | 1 + .../ProfitableSchemes.java | 1 + .../java/dynamic_programming/RemoveBoxes.java | 1 + .../dynamic_programming/RestoreTheArray.java | 1 + .../RussianDollEnvelopes.java | 1 + .../ShortestPathVisitingAllNodes.java | 1 + .../SmallestSufficientTeam.java | 1 + .../SplitArrayLargestSum.java | 1 + .../StickersToSpellWord.java | 1 + .../java/dynamic_programming/StoneGame.java | 1 + .../dynamic_programming/StoneGameIII.java | 1 + .../java/dynamic_programming/StoneGameIV.java | 1 + .../dynamic_programming/StrangePrinter.java | 1 + .../dynamic_programming/TallestBillboard.java | 1 + .../dynamic_programming/TilingARectangle.java | 1 + .../dynamic_programming/TossStrangeCoins.java | 1 + .../dynamic_programming/TwoKeysKeyboard.java | 1 + .../UniqueBinarySearchTrees.java | 1 + .../UniqueBinarySearchTreesII.java | 1 + .../ValidPalindromeIII.java | 1 + .../java/dynamic_programming/WordBreak.java | 1 + .../java/dynamic_programming/WordBreakII.java | 1 + src/main/java/greedy/BoatsToSavePeople.java | 1 + src/main/java/greedy/BrokenCalculator.java | 1 + src/main/java/greedy/BurstBalloons.java | 1 + src/main/java/greedy/CourseScheduleIII.java | 1 + src/main/java/greedy/GasStation.java | 1 + src/main/java/greedy/IPO.java | 1 + src/main/java/greedy/JumpGame.java | 1 + src/main/java/greedy/JumpGameII.java | 1 + src/main/java/greedy/LemonadeChange.java | 1 + .../java/greedy/MaximumLengthOfPairChain.java | 1 + .../java/greedy/MinimumTimeToBuildBlocks.java | 1 + .../java/greedy/NonOverlappingIntervals.java | 1 + src/main/java/greedy/PartitionLabels.java | 1 + .../greedy/QueueReconstructionByHeight.java | 1 + src/main/java/greedy/ReducingDishes.java | 1 + .../java/greedy/ScoreAfterFlippingMatrix.java | 1 + src/main/java/greedy/StringWithout3A3B.java | 1 + src/main/java/greedy/TaskScheduler.java | 1 + src/main/java/greedy/TwoCityScheduling.java | 1 + src/main/java/hashing/Anagrams.java | 1 + .../AnalyzeUserWebsiteVisitPattern.java | 1 + src/main/java/hashing/BrickWall.java | 1 + src/main/java/hashing/ContiguousArray.java | 1 + src/main/java/hashing/CustomSortString.java | 1 + src/main/java/hashing/DistributeCandies.java | 1 + src/main/java/hashing/GroupAnagrams.java | 1 + .../GroupsOfSpecialEquivalentStrings.java | 1 + .../java/hashing/KdiffPairsInanArray.java | 1 + .../java/hashing/LargestUniqueNumber.java | 1 + .../MaximumSizeSubarraySumEqualsk.java | 1 + src/main/java/hashing/NumberOfAtoms.java | 1 + src/main/java/hashing/PartitionLabels.java | 1 + .../java/hashing/ShortEncodingOfWords.java | 1 + .../java/hashing/SortCharByFrequency.java | 1 + .../StringTransformsIntoAnotherString.java | 1 + .../SubstringConcatenationOfWords.java | 1 + src/main/java/hashing/TwoSum.java | 1 + src/main/java/hashing/ValidAnagram.java | 1 + src/main/java/heap/Candy.java | 1 + src/main/java/heap/DistantBarcodes.java | 1 + src/main/java/heap/FreqStack.java | 1 + .../java/heap/KClosestPointsToOrigin.java | 1 + src/main/java/heap/MeetingRoomsII.java | 1 + .../heap/ReachableNodesInSubdividedGraph.java | 1 + src/main/java/heap/SlidingWindowMaximum.java | 1 + .../SmallestRotationWithHighestScore.java | 1 + src/main/java/heap/TheSkylineProblem.java | 1 + src/main/java/heap/TopKFrequentWords.java | 1 + src/main/java/linked_list/DeleteNode.java | 1 + .../linked_list/IntersectionOfTwoLists.java | 1 + .../java/linked_list/LinkedListCycle.java | 1 + .../java/linked_list/MergeKSortedLists.java | 1 + .../java/linked_list/MergeTwoSortedList.java | 1 + .../java/linked_list/MiddleOfLinkedList.java | 1 + .../NextGreaterNodeInLinkedList.java | 1 + .../java/linked_list/PaliandromeList.java | 1 + .../java/linked_list/ReverseLinkedList.java | 1 + .../java/linked_list/ReverseNodesKGroup.java | 1 + .../linked_list/SplitLinkedListInParts.java | 1 + .../java/linked_list/SwapNodesInPairs.java | 1 + src/main/java/math/AddDigits.java | 1 + src/main/java/math/AddTwoNumbers.java | 1 + src/main/java/math/Base7.java | 1 + src/main/java/math/BulbSwitcherII.java | 1 + src/main/java/math/CountPrimes.java | 1 + src/main/java/math/CouplesHoldingHands.java | 1 + src/main/java/math/DecodedStringAtIndex.java | 1 + src/main/java/math/ExcelSheetColumnTitle.java | 1 + .../java/math/GlobalAndLocalInversions.java | 1 + .../LargestComponentSizebyCommonFactor.java | 1 + .../java/math/MinimumIndexSumOfTwoLists.java | 1 + src/main/java/math/NthDigit.java | 1 + src/main/java/math/NthMagicalNumber.java | 1 + .../java/math/ProjectionAreaOf3DShapes.java | 1 + src/main/java/math/RangeAdditionII.java | 1 + src/main/java/math/ReachingPoints.java | 1 + src/main/java/math/RectangleOverlap.java | 1 + src/main/java/math/RomanToInteger.java | 1 + src/main/java/math/RotateFunction.java | 1 + src/main/java/math/SmallestRangeI.java | 1 + src/main/java/math/SolveTheEquation.java | 1 + src/main/java/math/SquirrelSimulation.java | 1 + src/main/java/math/SuperWashingMachines.java | 1 + src/main/java/math/WaterAndJugProblem.java | 1 + .../reservoir_sampling/RandomPickIndex.java | 1 + src/main/java/stack/BasicCalculator.java | 1 + src/main/java/stack/DecodeString.java | 1 + src/main/java/stack/DecodedStringAtIndex.java | 1 + .../java/stack/ExclusiveTimeOfFunctions.java | 1 + .../stack/LargestRectangleInHistogram.java | 1 + .../java/stack/LongestValidParentheses.java | 1 + src/main/java/stack/MaximalRectangle.java | 1 + src/main/java/stack/MinStack.java | 1 + src/main/java/stack/MyQueue.java | 1 + .../java/stack/StudentAttendanceRecordII.java | 1 + src/main/java/stack/ValidParentheses.java | 1 + src/main/java/string/AddBinary.java | 1 + .../java/string/CompareVersionNumbers.java | 1 + src/main/java/string/CountAndSay.java | 1 + .../java/string/ExcelSheetColumnNumber.java | 1 + .../java/string/FindTheClosestPalindrome.java | 1 + .../FindWordsThatCanBeFormedbyCharacters.java | 1 + .../string/FirstUniqueCharacterInAString.java | 1 + src/main/java/string/ImplementStrStr.java | 1 + src/main/java/string/IsomorphicStrings.java | 1 + src/main/java/string/KeyboardRow.java | 1 + src/main/java/string/LongestCommonPrefix.java | 1 + src/main/java/string/LongestPalindrome.java | 1 + .../java/string/LongestWordInDictonary.java | 1 + .../MinimumAddtoMakeParenthesesValid.java | 1 + .../java/string/MonotoneIncreasingDigits.java | 1 + src/main/java/string/MultiplyStrings.java | 1 + .../string/NumberOfMatchingSubsequences.java | 1 + src/main/java/string/OneEditDistance.java | 1 + src/main/java/string/PermutationInString.java | 1 + src/main/java/string/PushDominoes.java | 1 + .../ReconstructOriginalDigitsFromEnglish.java | 1 + .../java/string/RepeatedSubstringPattern.java | 1 + src/main/java/string/ReplaceWords.java | 1 + src/main/java/string/ReverseStringII.java | 1 + src/main/java/string/ReverseWordsII.java | 1 + .../java/string/ReverseWordsInAString.java | 1 + src/main/java/string/RotateString.java | 1 + src/main/java/string/ShortestPalindrome.java | 1 + src/main/java/string/SimplifyPath.java | 1 + .../java/string/SplitConcatenatedStrings.java | 1 + src/main/java/string/StampingTheSequence.java | 1 + src/main/java/string/StringCompression.java | 1 + src/main/java/string/StringToInteger.java | 1 + .../java/string/StudentAttendanceRecordI.java | 1 + src/main/java/string/TextJustification.java | 1 + src/main/java/string/ValidPalindrome.java | 1 + src/main/java/string/ValidPalindromeII.java | 1 + .../java/string/ValidWordAbbreviation.java | 1 + src/main/java/string/ValidWordSquare.java | 1 + src/main/java/string/ValidateIPAddress.java | 1 + src/main/java/string/ZigZagConversion.java | 1 + .../tree/AllNodesDistanceKInBinaryTree.java | 1 + .../java/tree/AllPossibleFullBinaryTrees.java | 1 + .../tree/AverageOfLevelsInBinaryTree.java | 1 + src/main/java/tree/BSTtoDoublyLinkedList.java | 1 + .../java/tree/BinarayTreeRightSideView.java | 1 + .../java/tree/BinaryTreeInorderTraversal.java | 1 + ...inaryTreeLongestConsecutiveSequenceII.java | 1 + .../java/tree/BinaryTreeMaximumPathSum.java | 1 + src/main/java/tree/BinaryTreePaths.java | 1 + .../tree/BinaryTreePostorderTraversal.java | 1 + src/main/java/tree/BinaryTreeTilt.java | 1 + src/main/java/tree/BoundaryOfBinaryTree.java | 1 + .../tree/ClosestBinarySearchTreeValue.java | 1 + .../java/tree/ClosestLeafInABinaryTree.java | 1 + .../tree/ConstructBinaryTreefromString.java | 1 + .../tree/ConstructStringFromBinaryTree.java | 1 + .../java/tree/ConvertBSTToGreaterTree.java | 1 + .../java/tree/ConvertSortedArrayToBST.java | 1 + src/main/java/tree/DiameterOfBinaryTree.java | 1 + src/main/java/tree/EqualTreePartition.java | 1 + .../java/tree/FindBottomLeftTreeValue.java | 1 + .../tree/FindLargestValueInEachTreeRow.java | 1 + src/main/java/tree/FlattenBinaryTree.java | 1 + src/main/java/tree/FlipBinaryTree.java | 1 + .../java/tree/FlipEquivalentBinaryTrees.java | 1 + src/main/java/tree/InorderSuccessorInBST.java | 1 + .../InsufficientNodesinRoottoLeafPaths.java | 1 + src/main/java/tree/LCA.java | 1 + src/main/java/tree/LargestBSTSubtree.java | 1 + src/main/java/tree/LeafSimilarTrees.java | 1 + .../java/tree/LowestCommonAncestorBST.java | 1 + src/main/java/tree/MaximumBinaryTree.java | 1 + .../tree/MaximumLevelSumofABinaryTree.java | 1 + .../java/tree/MaximumWidthOfBinaryTree.java | 1 + .../tree/MinimumAbsoluteDifferenceInBST.java | 1 + .../java/tree/MostFrequentSubtreeSum.java | 1 + src/main/java/tree/NextRightPointer.java | 1 + src/main/java/tree/NextRightPointerII.java | 1 + src/main/java/tree/PathSumIII.java | 1 + src/main/java/tree/PostorderToBT.java | 1 + src/main/java/tree/PreorderToBT.java | 1 + .../java/tree/RecoverBinarySearchTree.java | 1 + src/main/java/tree/SameTree.java | 1 + .../tree/SerializeAndDeserializeNAryTree.java | 1 + src/main/java/tree/SortedArrayToBST.java | 1 + src/main/java/tree/SplitBST.java | 1 + src/main/java/tree/SubtreeOfAnotherTree.java | 1 + src/main/java/tree/SumofLeftLeaves.java | 1 + src/main/java/tree/SymmetricTree.java | 1 + src/main/java/tree/TwoSumIV.java | 1 + src/main/java/tree/ValidBinarySearchTree.java | 1 + src/main/java/tree/ZigZagTraversal.java | 1 + src/main/java/two_pointers/FourSum.java | 1 + .../LastSubstringInLexicographicalOrder.java | 1 + .../LongestSubstringWitoutRepeats.java | 1 + .../two_pointers/MinimumSizeSubarraySum.java | 1 + .../two_pointers/MinimumWindowSubstring.java | 1 + src/main/java/two_pointers/MoveZeroes.java | 1 + .../NumberOfMatchingSubsequences.java | 1 + .../java/two_pointers/RemoveDuplicates.java | 1 + .../java/two_pointers/RemoveDuplicatesII.java | 1 + src/main/java/two_pointers/SmallestRange.java | 1 + .../SubarrayProductLessThanK.java | 1 + .../SubarraysWithKDifferentIntegers.java | 1 + src/main/java/two_pointers/ThreeSum.java | 1 + .../java/two_pointers/ThreeSumClosest.java | 1 + .../java/two_pointers/TrappingRainWater.java | 1 + 460 files changed, 482 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index e807b14d..9f9314b2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,31 @@ plugins { id 'java' - id 'com.github.sherter.google-java-format' version '0.9' + id 'com.diffplug.spotless' version '7.0.0.BETA4' } -dependencies { - implementation 'com.google.googlejavaformat:google-java-format:1.8.0' +java { + toolchain { + languageVersion = JavaLanguageVersion.of(23) // Replace with your desired version + } +} + +spotless { + java { + // Use the default import order configuration + importOrder('java', 'javax', 'com.acme', '', '#com.acme', '#') + + // Remove unused imports + removeUnusedImports() + + // Apply formatting to annotations + formatAnnotations() + } +} + +tasks.withType(JavaCompile).configureEach { + options.release = 23 // Match the desired version } repositories { mavenCentral() -} \ No newline at end of file +} diff --git a/src/main/java/array/AddToArrayFormOfInteger.java b/src/main/java/array/AddToArrayFormOfInteger.java index 35f9c30e..8b8e7eef 100644 --- a/src/main/java/array/AddToArrayFormOfInteger.java +++ b/src/main/java/array/AddToArrayFormOfInteger.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.math.BigInteger; diff --git a/src/main/java/array/ArrayNesting.java b/src/main/java/array/ArrayNesting.java index afe3ad20..05686dc3 100644 --- a/src/main/java/array/ArrayNesting.java +++ b/src/main/java/array/ArrayNesting.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.*; diff --git a/src/main/java/array/ArrayPartitionI.java b/src/main/java/array/ArrayPartitionI.java index 35a370a6..c0ac8770 100644 --- a/src/main/java/array/ArrayPartitionI.java +++ b/src/main/java/array/ArrayPartitionI.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.*; diff --git a/src/main/java/array/BattleshipsInABoard.java b/src/main/java/array/BattleshipsInABoard.java index 566221fe..f714ea45 100644 --- a/src/main/java/array/BattleshipsInABoard.java +++ b/src/main/java/array/BattleshipsInABoard.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/BestMeetingPoint.java b/src/main/java/array/BestMeetingPoint.java index 46c04225..6252d428 100644 --- a/src/main/java/array/BestMeetingPoint.java +++ b/src/main/java/array/BestMeetingPoint.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/CanPlaceFlowers.java b/src/main/java/array/CanPlaceFlowers.java index d811e108..8936f37d 100644 --- a/src/main/java/array/CanPlaceFlowers.java +++ b/src/main/java/array/CanPlaceFlowers.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/CardFilipGame.java b/src/main/java/array/CardFilipGame.java index 5a8e1e90..1b145691 100644 --- a/src/main/java/array/CardFilipGame.java +++ b/src/main/java/array/CardFilipGame.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayList; diff --git a/src/main/java/array/ChampagneTower.java b/src/main/java/array/ChampagneTower.java index 6296214d..2cfec24d 100644 --- a/src/main/java/array/ChampagneTower.java +++ b/src/main/java/array/ChampagneTower.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/EmployeeFreeTime.java b/src/main/java/array/EmployeeFreeTime.java index f6aff8dc..4eb584c1 100644 --- a/src/main/java/array/EmployeeFreeTime.java +++ b/src/main/java/array/EmployeeFreeTime.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayList; diff --git a/src/main/java/array/FindPivotIndex.java b/src/main/java/array/FindPivotIndex.java index 2de89a50..7bb8aeda 100644 --- a/src/main/java/array/FindPivotIndex.java +++ b/src/main/java/array/FindPivotIndex.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.*; diff --git a/src/main/java/array/FindTheCelebrity.java b/src/main/java/array/FindTheCelebrity.java index c18bf6c1..c4b4b5ca 100644 --- a/src/main/java/array/FindTheCelebrity.java +++ b/src/main/java/array/FindTheCelebrity.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.HashMap; diff --git a/src/main/java/array/FirstMissingPositive.java b/src/main/java/array/FirstMissingPositive.java index 1e704581..b589eb20 100644 --- a/src/main/java/array/FirstMissingPositive.java +++ b/src/main/java/array/FirstMissingPositive.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/FruitIntoBaskets.java b/src/main/java/array/FruitIntoBaskets.java index 5a6404e8..10a3d9be 100644 --- a/src/main/java/array/FruitIntoBaskets.java +++ b/src/main/java/array/FruitIntoBaskets.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.Stack; diff --git a/src/main/java/array/HIndex.java b/src/main/java/array/HIndex.java index 2cc1dad3..5360b375 100644 --- a/src/main/java/array/HIndex.java +++ b/src/main/java/array/HIndex.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/ImageSmoother.java b/src/main/java/array/ImageSmoother.java index 5c8894f1..af1d4903 100644 --- a/src/main/java/array/ImageSmoother.java +++ b/src/main/java/array/ImageSmoother.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** * Created by gouthamvidyapradhan on 17/02/2018. * Given a 2D integer matrix M representing the gray diff --git a/src/main/java/array/IncreasingTripletSubsequence.java b/src/main/java/array/IncreasingTripletSubsequence.java index 23f258c1..02fe1d96 100644 --- a/src/main/java/array/IncreasingTripletSubsequence.java +++ b/src/main/java/array/IncreasingTripletSubsequence.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.Arrays; diff --git a/src/main/java/array/InsertInterval.java b/src/main/java/array/InsertInterval.java index 5202ade0..8216e270 100644 --- a/src/main/java/array/InsertInterval.java +++ b/src/main/java/array/InsertInterval.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayList; diff --git a/src/main/java/array/KEmptySlots.java b/src/main/java/array/KEmptySlots.java index 2055612f..f83dc515 100644 --- a/src/main/java/array/KEmptySlots.java +++ b/src/main/java/array/KEmptySlots.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.TreeSet; diff --git a/src/main/java/array/LargestNumberAtLeastTwice.java b/src/main/java/array/LargestNumberAtLeastTwice.java index 664ace41..03905711 100644 --- a/src/main/java/array/LargestNumberAtLeastTwice.java +++ b/src/main/java/array/LargestNumberAtLeastTwice.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/LargestTimeForGivenDigits.java b/src/main/java/array/LargestTimeForGivenDigits.java index 32b63b5c..d934f6f9 100644 --- a/src/main/java/array/LargestTimeForGivenDigits.java +++ b/src/main/java/array/LargestTimeForGivenDigits.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/LongestIncreasingSubsequence.java b/src/main/java/array/LongestIncreasingSubsequence.java index 9f7a7e2f..5d009116 100644 --- a/src/main/java/array/LongestIncreasingSubsequence.java +++ b/src/main/java/array/LongestIncreasingSubsequence.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/LongestLineofConsecutiveOneinMatrix.java b/src/main/java/array/LongestLineofConsecutiveOneinMatrix.java index f322be99..4e03d461 100644 --- a/src/main/java/array/LongestLineofConsecutiveOneinMatrix.java +++ b/src/main/java/array/LongestLineofConsecutiveOneinMatrix.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/MatrixCellsinDistanceOrder.java b/src/main/java/array/MatrixCellsinDistanceOrder.java index e71569bb..2efe7f7a 100644 --- a/src/main/java/array/MatrixCellsinDistanceOrder.java +++ b/src/main/java/array/MatrixCellsinDistanceOrder.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.*; diff --git a/src/main/java/array/MaxConsecutiveOnes.java b/src/main/java/array/MaxConsecutiveOnes.java index 3a4fcad9..95b3f749 100644 --- a/src/main/java/array/MaxConsecutiveOnes.java +++ b/src/main/java/array/MaxConsecutiveOnes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/MaxConsecutiveOnesII.java b/src/main/java/array/MaxConsecutiveOnesII.java index 09207589..f42b0ab3 100644 --- a/src/main/java/array/MaxConsecutiveOnesII.java +++ b/src/main/java/array/MaxConsecutiveOnesII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/MaxProductOfThreeNumbers.java b/src/main/java/array/MaxProductOfThreeNumbers.java index 0658073c..eb3972d0 100644 --- a/src/main/java/array/MaxProductOfThreeNumbers.java +++ b/src/main/java/array/MaxProductOfThreeNumbers.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.Arrays; diff --git a/src/main/java/array/MaximumSumofTwoNonOverlappingSubarrays.java b/src/main/java/array/MaximumSumofTwoNonOverlappingSubarrays.java index 0592fbdc..bf2b7fdc 100644 --- a/src/main/java/array/MaximumSumofTwoNonOverlappingSubarrays.java +++ b/src/main/java/array/MaximumSumofTwoNonOverlappingSubarrays.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.*; diff --git a/src/main/java/array/MaximumSwap.java b/src/main/java/array/MaximumSwap.java index df8df20e..8093da65 100644 --- a/src/main/java/array/MaximumSwap.java +++ b/src/main/java/array/MaximumSwap.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/MeetingRooms.java b/src/main/java/array/MeetingRooms.java index ee7d2dd8..b5626f4a 100644 --- a/src/main/java/array/MeetingRooms.java +++ b/src/main/java/array/MeetingRooms.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.Arrays; diff --git a/src/main/java/array/MeetingScheduler.java b/src/main/java/array/MeetingScheduler.java index 29049230..1039599c 100644 --- a/src/main/java/array/MeetingScheduler.java +++ b/src/main/java/array/MeetingScheduler.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.*; diff --git a/src/main/java/array/MergeIntervals.java b/src/main/java/array/MergeIntervals.java index c8638b32..d3657670 100644 --- a/src/main/java/array/MergeIntervals.java +++ b/src/main/java/array/MergeIntervals.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayList; diff --git a/src/main/java/array/MergeSortedArray.java b/src/main/java/array/MergeSortedArray.java index 6121ed33..472fb9e2 100644 --- a/src/main/java/array/MergeSortedArray.java +++ b/src/main/java/array/MergeSortedArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/MinimumIndexSumOfTwoLists.java b/src/main/java/array/MinimumIndexSumOfTwoLists.java index 771a1db3..a550910b 100644 --- a/src/main/java/array/MinimumIndexSumOfTwoLists.java +++ b/src/main/java/array/MinimumIndexSumOfTwoLists.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayList; diff --git a/src/main/java/array/MinimumMovesToEqualArray.java b/src/main/java/array/MinimumMovesToEqualArray.java index a431b840..c65394d6 100644 --- a/src/main/java/array/MinimumMovesToEqualArray.java +++ b/src/main/java/array/MinimumMovesToEqualArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.Arrays; diff --git a/src/main/java/array/MinimumSwapsToGroupAll1Together.java b/src/main/java/array/MinimumSwapsToGroupAll1Together.java index bbf752a0..c1d699e6 100644 --- a/src/main/java/array/MinimumSwapsToGroupAll1Together.java +++ b/src/main/java/array/MinimumSwapsToGroupAll1Together.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.*; diff --git a/src/main/java/array/MinimumTimeDifference.java b/src/main/java/array/MinimumTimeDifference.java index a70e86f2..92acfd51 100644 --- a/src/main/java/array/MinimumTimeDifference.java +++ b/src/main/java/array/MinimumTimeDifference.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.*; diff --git a/src/main/java/array/MissingNumber.java b/src/main/java/array/MissingNumber.java index 3be7a426..9532902b 100644 --- a/src/main/java/array/MissingNumber.java +++ b/src/main/java/array/MissingNumber.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/MyCalendarThree.java b/src/main/java/array/MyCalendarThree.java index 335341c3..267eb8ea 100644 --- a/src/main/java/array/MyCalendarThree.java +++ b/src/main/java/array/MyCalendarThree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.*; diff --git a/src/main/java/array/NextGreaterElementI.java b/src/main/java/array/NextGreaterElementI.java index 9021407c..33c7f426 100644 --- a/src/main/java/array/NextGreaterElementI.java +++ b/src/main/java/array/NextGreaterElementI.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/PascalsTriangle.java b/src/main/java/array/PascalsTriangle.java index be60ed1d..32c8ada8 100644 --- a/src/main/java/array/PascalsTriangle.java +++ b/src/main/java/array/PascalsTriangle.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayList; diff --git a/src/main/java/array/PourWater.java b/src/main/java/array/PourWater.java index aa377d8b..e0c5ed20 100644 --- a/src/main/java/array/PourWater.java +++ b/src/main/java/array/PourWater.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/ProductOfArrayExceptSelf.java b/src/main/java/array/ProductOfArrayExceptSelf.java index d9ebac09..e905ce2f 100644 --- a/src/main/java/array/ProductOfArrayExceptSelf.java +++ b/src/main/java/array/ProductOfArrayExceptSelf.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/ReadNCharacters.java b/src/main/java/array/ReadNCharacters.java index fc58afae..75017539 100644 --- a/src/main/java/array/ReadNCharacters.java +++ b/src/main/java/array/ReadNCharacters.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/RelativeRanks.java b/src/main/java/array/RelativeRanks.java index 9423baa7..adfbf31f 100644 --- a/src/main/java/array/RelativeRanks.java +++ b/src/main/java/array/RelativeRanks.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayList; diff --git a/src/main/java/array/RelativeSortArray.java b/src/main/java/array/RelativeSortArray.java index 2f15b1d6..8244f7c0 100644 --- a/src/main/java/array/RelativeSortArray.java +++ b/src/main/java/array/RelativeSortArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.*; diff --git a/src/main/java/array/RevealCardsInIncreasingOrder.java b/src/main/java/array/RevealCardsInIncreasingOrder.java index f48432ed..dea70a6d 100644 --- a/src/main/java/array/RevealCardsInIncreasingOrder.java +++ b/src/main/java/array/RevealCardsInIncreasingOrder.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayDeque; diff --git a/src/main/java/array/RotateArray.java b/src/main/java/array/RotateArray.java index 4b809291..863c60f1 100644 --- a/src/main/java/array/RotateArray.java +++ b/src/main/java/array/RotateArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/RotateMatrix.java b/src/main/java/array/RotateMatrix.java index 367e9c1c..42251de7 100644 --- a/src/main/java/array/RotateMatrix.java +++ b/src/main/java/array/RotateMatrix.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/SetMatrixZeroes.java b/src/main/java/array/SetMatrixZeroes.java index 4a80b448..c30b919e 100644 --- a/src/main/java/array/SetMatrixZeroes.java +++ b/src/main/java/array/SetMatrixZeroes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.HashSet; diff --git a/src/main/java/array/SortArrayByParityII.java b/src/main/java/array/SortArrayByParityII.java index 0b775f5c..b3fea546 100644 --- a/src/main/java/array/SortArrayByParityII.java +++ b/src/main/java/array/SortArrayByParityII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.*; diff --git a/src/main/java/array/SortColors.java b/src/main/java/array/SortColors.java index dc9c7e39..14d563c2 100644 --- a/src/main/java/array/SortColors.java +++ b/src/main/java/array/SortColors.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/SparseMatrixMultiplication.java b/src/main/java/array/SparseMatrixMultiplication.java index 04f6c8ed..c8d2f669 100644 --- a/src/main/java/array/SparseMatrixMultiplication.java +++ b/src/main/java/array/SparseMatrixMultiplication.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/SubArraysWithBoundedMaximum.java b/src/main/java/array/SubArraysWithBoundedMaximum.java index 5ed30588..05baf09a 100644 --- a/src/main/java/array/SubArraysWithBoundedMaximum.java +++ b/src/main/java/array/SubArraysWithBoundedMaximum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/SubarraySumEqualsK.java b/src/main/java/array/SubarraySumEqualsK.java index 282c1f80..3cd9ca34 100644 --- a/src/main/java/array/SubarraySumEqualsK.java +++ b/src/main/java/array/SubarraySumEqualsK.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.HashMap; diff --git a/src/main/java/array/SurfaceAreaOfThreeDShapes.java b/src/main/java/array/SurfaceAreaOfThreeDShapes.java index 2f35ef3d..9c646c68 100644 --- a/src/main/java/array/SurfaceAreaOfThreeDShapes.java +++ b/src/main/java/array/SurfaceAreaOfThreeDShapes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/ThirdMaximumNumber.java b/src/main/java/array/ThirdMaximumNumber.java index 59259b33..ba0e42c4 100644 --- a/src/main/java/array/ThirdMaximumNumber.java +++ b/src/main/java/array/ThirdMaximumNumber.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/TwoSum.java b/src/main/java/array/TwoSum.java index 546b04ff..3b45668e 100644 --- a/src/main/java/array/TwoSum.java +++ b/src/main/java/array/TwoSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayList; diff --git a/src/main/java/array/TwoSumII.java b/src/main/java/array/TwoSumII.java index b7a3fe3c..837dba97 100644 --- a/src/main/java/array/TwoSumII.java +++ b/src/main/java/array/TwoSumII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/ValidTicTacToeState.java b/src/main/java/array/ValidTicTacToeState.java index 6d2fa83c..22bc822b 100644 --- a/src/main/java/array/ValidTicTacToeState.java +++ b/src/main/java/array/ValidTicTacToeState.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/backtracking/CombinationSum.java b/src/main/java/backtracking/CombinationSum.java index 0ec28dc3..281dda21 100644 --- a/src/main/java/backtracking/CombinationSum.java +++ b/src/main/java/backtracking/CombinationSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/src/main/java/backtracking/CombinationSumII.java b/src/main/java/backtracking/CombinationSumII.java index 30fd2d20..4fa9f73d 100644 --- a/src/main/java/backtracking/CombinationSumII.java +++ b/src/main/java/backtracking/CombinationSumII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/src/main/java/backtracking/Combinations.java b/src/main/java/backtracking/Combinations.java index 625ed94e..613c832e 100644 --- a/src/main/java/backtracking/Combinations.java +++ b/src/main/java/backtracking/Combinations.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/src/main/java/backtracking/ExpressionAddOperators.java b/src/main/java/backtracking/ExpressionAddOperators.java index 1a61b49e..33d74351 100644 --- a/src/main/java/backtracking/ExpressionAddOperators.java +++ b/src/main/java/backtracking/ExpressionAddOperators.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/src/main/java/backtracking/GenerateParentheses.java b/src/main/java/backtracking/GenerateParentheses.java index 9d61c2a3..6de5d66f 100644 --- a/src/main/java/backtracking/GenerateParentheses.java +++ b/src/main/java/backtracking/GenerateParentheses.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/src/main/java/backtracking/LetterCasePermutation.java b/src/main/java/backtracking/LetterCasePermutation.java index b5b09c56..935e27eb 100644 --- a/src/main/java/backtracking/LetterCasePermutation.java +++ b/src/main/java/backtracking/LetterCasePermutation.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/src/main/java/backtracking/LetterPhoneNumber.java b/src/main/java/backtracking/LetterPhoneNumber.java index b32a09eb..e63a38fa 100644 --- a/src/main/java/backtracking/LetterPhoneNumber.java +++ b/src/main/java/backtracking/LetterPhoneNumber.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/src/main/java/backtracking/MatchsticksToSquare.java b/src/main/java/backtracking/MatchsticksToSquare.java index db9f729f..4e79a9ba 100644 --- a/src/main/java/backtracking/MatchsticksToSquare.java +++ b/src/main/java/backtracking/MatchsticksToSquare.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.*; diff --git a/src/main/java/backtracking/PalindromePartitioning.java b/src/main/java/backtracking/PalindromePartitioning.java index b3718570..f1aeb823 100644 --- a/src/main/java/backtracking/PalindromePartitioning.java +++ b/src/main/java/backtracking/PalindromePartitioning.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/src/main/java/backtracking/Permutations.java b/src/main/java/backtracking/Permutations.java index 5509d3d1..13a26e37 100644 --- a/src/main/java/backtracking/Permutations.java +++ b/src/main/java/backtracking/Permutations.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/src/main/java/backtracking/PermutationsII.java b/src/main/java/backtracking/PermutationsII.java index 27f55f8e..56a9f5ca 100644 --- a/src/main/java/backtracking/PermutationsII.java +++ b/src/main/java/backtracking/PermutationsII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/src/main/java/backtracking/RegularExpressionMatching.java b/src/main/java/backtracking/RegularExpressionMatching.java index 0db4538b..c31929f7 100644 --- a/src/main/java/backtracking/RegularExpressionMatching.java +++ b/src/main/java/backtracking/RegularExpressionMatching.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; /** diff --git a/src/main/java/backtracking/RemoveInvalidParentheses.java b/src/main/java/backtracking/RemoveInvalidParentheses.java index 2ab68beb..145dee39 100644 --- a/src/main/java/backtracking/RemoveInvalidParentheses.java +++ b/src/main/java/backtracking/RemoveInvalidParentheses.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/src/main/java/backtracking/Subsets.java b/src/main/java/backtracking/Subsets.java index 03956e3e..3251446a 100644 --- a/src/main/java/backtracking/Subsets.java +++ b/src/main/java/backtracking/Subsets.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/src/main/java/backtracking/SubsetsII.java b/src/main/java/backtracking/SubsetsII.java index daa83bf9..76d4e7b2 100644 --- a/src/main/java/backtracking/SubsetsII.java +++ b/src/main/java/backtracking/SubsetsII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/src/main/java/backtracking/TargetSum.java b/src/main/java/backtracking/TargetSum.java index dce00652..e586d33a 100644 --- a/src/main/java/backtracking/TargetSum.java +++ b/src/main/java/backtracking/TargetSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; /** diff --git a/src/main/java/backtracking/WildcardMatching.java b/src/main/java/backtracking/WildcardMatching.java index 90b383bd..811aee77 100644 --- a/src/main/java/backtracking/WildcardMatching.java +++ b/src/main/java/backtracking/WildcardMatching.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; /** diff --git a/src/main/java/backtracking/WordSearch.java b/src/main/java/backtracking/WordSearch.java index 5fa5df91..c6c2abdd 100644 --- a/src/main/java/backtracking/WordSearch.java +++ b/src/main/java/backtracking/WordSearch.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; /** diff --git a/src/main/java/backtracking/WordSearchII.java b/src/main/java/backtracking/WordSearchII.java index 07377143..4cf67e8b 100644 --- a/src/main/java/backtracking/WordSearchII.java +++ b/src/main/java/backtracking/WordSearchII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.*; diff --git a/src/main/java/backtracking/ZumaGame.java b/src/main/java/backtracking/ZumaGame.java index 4787654c..5d905143 100644 --- a/src/main/java/backtracking/ZumaGame.java +++ b/src/main/java/backtracking/ZumaGame.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.*; diff --git a/src/main/java/binary_search/ArmstrongNumber.java b/src/main/java/binary_search/ArmstrongNumber.java index 2a71b088..c3c13c8d 100644 --- a/src/main/java/binary_search/ArmstrongNumber.java +++ b/src/main/java/binary_search/ArmstrongNumber.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; import java.util.*; diff --git a/src/main/java/binary_search/FindPeakElement.java b/src/main/java/binary_search/FindPeakElement.java index 8904353f..8c5b9d5e 100644 --- a/src/main/java/binary_search/FindPeakElement.java +++ b/src/main/java/binary_search/FindPeakElement.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/src/main/java/binary_search/FirstBadVersion.java b/src/main/java/binary_search/FirstBadVersion.java index b4dbb393..0e1c0a89 100644 --- a/src/main/java/binary_search/FirstBadVersion.java +++ b/src/main/java/binary_search/FirstBadVersion.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/src/main/java/binary_search/HIndexII.java b/src/main/java/binary_search/HIndexII.java index 9a9733ee..5450d3b3 100644 --- a/src/main/java/binary_search/HIndexII.java +++ b/src/main/java/binary_search/HIndexII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/src/main/java/binary_search/KokoEatingBananas.java b/src/main/java/binary_search/KokoEatingBananas.java index 8c1f6193..bd5c3400 100644 --- a/src/main/java/binary_search/KokoEatingBananas.java +++ b/src/main/java/binary_search/KokoEatingBananas.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/src/main/java/binary_search/MedianOfTwoSortedArrays.java b/src/main/java/binary_search/MedianOfTwoSortedArrays.java index d908e664..221a1228 100644 --- a/src/main/java/binary_search/MedianOfTwoSortedArrays.java +++ b/src/main/java/binary_search/MedianOfTwoSortedArrays.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; import java.util.ArrayList; diff --git a/src/main/java/binary_search/MinSortedRotatedArray.java b/src/main/java/binary_search/MinSortedRotatedArray.java index ee5e151f..3a3d7f3c 100644 --- a/src/main/java/binary_search/MinSortedRotatedArray.java +++ b/src/main/java/binary_search/MinSortedRotatedArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/src/main/java/binary_search/MinimizeTheMaximumAdjacentElementDifference.java b/src/main/java/binary_search/MinimizeTheMaximumAdjacentElementDifference.java index 63e054a4..260cc55d 100644 --- a/src/main/java/binary_search/MinimizeTheMaximumAdjacentElementDifference.java +++ b/src/main/java/binary_search/MinimizeTheMaximumAdjacentElementDifference.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; import java.util.ArrayList; diff --git a/src/main/java/binary_search/MinimumWindowSubsequence.java b/src/main/java/binary_search/MinimumWindowSubsequence.java index d3310d8d..0d92648f 100644 --- a/src/main/java/binary_search/MinimumWindowSubsequence.java +++ b/src/main/java/binary_search/MinimumWindowSubsequence.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; import java.util.*; diff --git a/src/main/java/binary_search/PowXN.java b/src/main/java/binary_search/PowXN.java index 05c3eef4..e45def72 100644 --- a/src/main/java/binary_search/PowXN.java +++ b/src/main/java/binary_search/PowXN.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/src/main/java/binary_search/SearchForARange.java b/src/main/java/binary_search/SearchForARange.java index 8da19dfe..a53816e6 100644 --- a/src/main/java/binary_search/SearchForARange.java +++ b/src/main/java/binary_search/SearchForARange.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/src/main/java/binary_search/SearchInsertPosition.java b/src/main/java/binary_search/SearchInsertPosition.java index 4b9e9fac..78312a18 100644 --- a/src/main/java/binary_search/SearchInsertPosition.java +++ b/src/main/java/binary_search/SearchInsertPosition.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/src/main/java/binary_search/SearchRotatedSortedArray.java b/src/main/java/binary_search/SearchRotatedSortedArray.java index a4380b01..e6edcc7c 100644 --- a/src/main/java/binary_search/SearchRotatedSortedArray.java +++ b/src/main/java/binary_search/SearchRotatedSortedArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/src/main/java/binary_search/SingleElementInASortedArray.java b/src/main/java/binary_search/SingleElementInASortedArray.java index f2feb412..29d5a503 100644 --- a/src/main/java/binary_search/SingleElementInASortedArray.java +++ b/src/main/java/binary_search/SingleElementInASortedArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/src/main/java/binary_search/SqrtX.java b/src/main/java/binary_search/SqrtX.java index 1cb3462e..e3cb34a3 100644 --- a/src/main/java/binary_search/SqrtX.java +++ b/src/main/java/binary_search/SqrtX.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/src/main/java/binary_search/SwimInRisingWater.java b/src/main/java/binary_search/SwimInRisingWater.java index 3d8febc8..5f13d9a1 100644 --- a/src/main/java/binary_search/SwimInRisingWater.java +++ b/src/main/java/binary_search/SwimInRisingWater.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; import java.util.HashSet; diff --git a/src/main/java/binary_search/TimeBasedKeyValuePair.java b/src/main/java/binary_search/TimeBasedKeyValuePair.java index f61c3d0c..c94ff317 100644 --- a/src/main/java/binary_search/TimeBasedKeyValuePair.java +++ b/src/main/java/binary_search/TimeBasedKeyValuePair.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; import java.util.*; diff --git a/src/main/java/bit_manipulation/BinaryNumberWithAlternatingBits.java b/src/main/java/bit_manipulation/BinaryNumberWithAlternatingBits.java index 7c9e2bfe..bced945e 100644 --- a/src/main/java/bit_manipulation/BinaryNumberWithAlternatingBits.java +++ b/src/main/java/bit_manipulation/BinaryNumberWithAlternatingBits.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package bit_manipulation; /** * Created by gouthamvidyapradhan on 28/05/2019\ Given a positive integer, check whether it has diff --git a/src/main/java/bit_manipulation/BinaryWatch.java b/src/main/java/bit_manipulation/BinaryWatch.java index 965e81d6..34fa3f48 100644 --- a/src/main/java/bit_manipulation/BinaryWatch.java +++ b/src/main/java/bit_manipulation/BinaryWatch.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package bit_manipulation; import java.util.*; diff --git a/src/main/java/bit_manipulation/DivideTwoIntegers.java b/src/main/java/bit_manipulation/DivideTwoIntegers.java index 7bdeab67..0929dfc6 100644 --- a/src/main/java/bit_manipulation/DivideTwoIntegers.java +++ b/src/main/java/bit_manipulation/DivideTwoIntegers.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package bit_manipulation; /** diff --git a/src/main/java/bit_manipulation/GrayCode.java b/src/main/java/bit_manipulation/GrayCode.java index 9c74430d..d08695fa 100644 --- a/src/main/java/bit_manipulation/GrayCode.java +++ b/src/main/java/bit_manipulation/GrayCode.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package bit_manipulation; import java.util.ArrayList; diff --git a/src/main/java/bit_manipulation/HammingDistance.java b/src/main/java/bit_manipulation/HammingDistance.java index 63fb1fd5..d800eda0 100644 --- a/src/main/java/bit_manipulation/HammingDistance.java +++ b/src/main/java/bit_manipulation/HammingDistance.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package bit_manipulation; /** diff --git a/src/main/java/bit_manipulation/TotalHammingDistance.java b/src/main/java/bit_manipulation/TotalHammingDistance.java index e0e89307..b685dced 100644 --- a/src/main/java/bit_manipulation/TotalHammingDistance.java +++ b/src/main/java/bit_manipulation/TotalHammingDistance.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package bit_manipulation; /** diff --git a/src/main/java/breadth_first_search/BinarayTreeLevelOrderTraversal.java b/src/main/java/breadth_first_search/BinarayTreeLevelOrderTraversal.java index 92462939..8e8bd36a 100644 --- a/src/main/java/breadth_first_search/BinarayTreeLevelOrderTraversal.java +++ b/src/main/java/breadth_first_search/BinarayTreeLevelOrderTraversal.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.ArrayDeque; diff --git a/src/main/java/breadth_first_search/BusRoutes.java b/src/main/java/breadth_first_search/BusRoutes.java index 4b975dc2..dbb3e892 100644 --- a/src/main/java/breadth_first_search/BusRoutes.java +++ b/src/main/java/breadth_first_search/BusRoutes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/src/main/java/breadth_first_search/CutOffTreesForGolfEvent.java b/src/main/java/breadth_first_search/CutOffTreesForGolfEvent.java index 72e2057b..1bc7df05 100644 --- a/src/main/java/breadth_first_search/CutOffTreesForGolfEvent.java +++ b/src/main/java/breadth_first_search/CutOffTreesForGolfEvent.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/src/main/java/breadth_first_search/Matrix.java b/src/main/java/breadth_first_search/Matrix.java index 1c6eb9da..c2c63988 100644 --- a/src/main/java/breadth_first_search/Matrix.java +++ b/src/main/java/breadth_first_search/Matrix.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/src/main/java/breadth_first_search/OpenTheLock.java b/src/main/java/breadth_first_search/OpenTheLock.java index 49bcde56..3ad720a9 100644 --- a/src/main/java/breadth_first_search/OpenTheLock.java +++ b/src/main/java/breadth_first_search/OpenTheLock.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/src/main/java/breadth_first_search/RaceCar.java b/src/main/java/breadth_first_search/RaceCar.java index 21c8705a..6cda24fc 100644 --- a/src/main/java/breadth_first_search/RaceCar.java +++ b/src/main/java/breadth_first_search/RaceCar.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/src/main/java/breadth_first_search/RottingOranges.java b/src/main/java/breadth_first_search/RottingOranges.java index c812cad2..0d84292a 100644 --- a/src/main/java/breadth_first_search/RottingOranges.java +++ b/src/main/java/breadth_first_search/RottingOranges.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/src/main/java/breadth_first_search/SlidingPuzzle.java b/src/main/java/breadth_first_search/SlidingPuzzle.java index 4fa7723a..73a96103 100644 --- a/src/main/java/breadth_first_search/SlidingPuzzle.java +++ b/src/main/java/breadth_first_search/SlidingPuzzle.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/src/main/java/breadth_first_search/WallsAndGates.java b/src/main/java/breadth_first_search/WallsAndGates.java index 29c027ec..84136ba3 100644 --- a/src/main/java/breadth_first_search/WallsAndGates.java +++ b/src/main/java/breadth_first_search/WallsAndGates.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.ArrayDeque; diff --git a/src/main/java/breadth_first_search/WordLadder.java b/src/main/java/breadth_first_search/WordLadder.java index 6a71f9d1..1054b222 100644 --- a/src/main/java/breadth_first_search/WordLadder.java +++ b/src/main/java/breadth_first_search/WordLadder.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/src/main/java/breadth_first_search/WordLadderII.java b/src/main/java/breadth_first_search/WordLadderII.java index 686dd9cf..d5374242 100644 --- a/src/main/java/breadth_first_search/WordLadderII.java +++ b/src/main/java/breadth_first_search/WordLadderII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/AccountsMerge.java b/src/main/java/depth_first_search/AccountsMerge.java index de15f02a..ab049aad 100644 --- a/src/main/java/depth_first_search/AccountsMerge.java +++ b/src/main/java/depth_first_search/AccountsMerge.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/AlienDictionary.java b/src/main/java/depth_first_search/AlienDictionary.java index f5dae3b9..6de53887 100644 --- a/src/main/java/depth_first_search/AlienDictionary.java +++ b/src/main/java/depth_first_search/AlienDictionary.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/AllPathsFromSourceToTarget.java b/src/main/java/depth_first_search/AllPathsFromSourceToTarget.java index fa03bba1..72f9f479 100644 --- a/src/main/java/depth_first_search/AllPathsFromSourceToTarget.java +++ b/src/main/java/depth_first_search/AllPathsFromSourceToTarget.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/AsFarfromLandAsPossible.java b/src/main/java/depth_first_search/AsFarfromLandAsPossible.java index 4739eafe..2a7a4efc 100644 --- a/src/main/java/depth_first_search/AsFarfromLandAsPossible.java +++ b/src/main/java/depth_first_search/AsFarfromLandAsPossible.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/BricksFallingWhenHit.java b/src/main/java/depth_first_search/BricksFallingWhenHit.java index 466bcc36..9b4baefb 100644 --- a/src/main/java/depth_first_search/BricksFallingWhenHit.java +++ b/src/main/java/depth_first_search/BricksFallingWhenHit.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.ArrayList; diff --git a/src/main/java/depth_first_search/CloneGraph.java b/src/main/java/depth_first_search/CloneGraph.java index 42232959..2ef7caed 100644 --- a/src/main/java/depth_first_search/CloneGraph.java +++ b/src/main/java/depth_first_search/CloneGraph.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.ArrayList; diff --git a/src/main/java/depth_first_search/ConnectingCitiesWithMinimumCost.java b/src/main/java/depth_first_search/ConnectingCitiesWithMinimumCost.java index c4b92280..788c7336 100644 --- a/src/main/java/depth_first_search/ConnectingCitiesWithMinimumCost.java +++ b/src/main/java/depth_first_search/ConnectingCitiesWithMinimumCost.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/CourseSchedule.java b/src/main/java/depth_first_search/CourseSchedule.java index 1e96e567..93383963 100644 --- a/src/main/java/depth_first_search/CourseSchedule.java +++ b/src/main/java/depth_first_search/CourseSchedule.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/CourseScheduleII.java b/src/main/java/depth_first_search/CourseScheduleII.java index 77b12023..cba31a4a 100644 --- a/src/main/java/depth_first_search/CourseScheduleII.java +++ b/src/main/java/depth_first_search/CourseScheduleII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/CrackingTheSafe.java b/src/main/java/depth_first_search/CrackingTheSafe.java index ffa5f443..359dc597 100644 --- a/src/main/java/depth_first_search/CrackingTheSafe.java +++ b/src/main/java/depth_first_search/CrackingTheSafe.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.HashSet; diff --git a/src/main/java/depth_first_search/CriticalConnection.java b/src/main/java/depth_first_search/CriticalConnection.java index 221ccb17..57fd6f9f 100644 --- a/src/main/java/depth_first_search/CriticalConnection.java +++ b/src/main/java/depth_first_search/CriticalConnection.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/FloodFill.java b/src/main/java/depth_first_search/FloodFill.java index de52df09..834a7286 100644 --- a/src/main/java/depth_first_search/FloodFill.java +++ b/src/main/java/depth_first_search/FloodFill.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/GraphValidTree.java b/src/main/java/depth_first_search/GraphValidTree.java index 43543bc3..2b69ec1f 100644 --- a/src/main/java/depth_first_search/GraphValidTree.java +++ b/src/main/java/depth_first_search/GraphValidTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.ArrayList; diff --git a/src/main/java/depth_first_search/IslandPerimeter.java b/src/main/java/depth_first_search/IslandPerimeter.java index 0cc67fa1..3a020f91 100644 --- a/src/main/java/depth_first_search/IslandPerimeter.java +++ b/src/main/java/depth_first_search/IslandPerimeter.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; /** diff --git a/src/main/java/depth_first_search/LongestConsecutiveSequence.java b/src/main/java/depth_first_search/LongestConsecutiveSequence.java index 1d4cd980..053cacbe 100644 --- a/src/main/java/depth_first_search/LongestConsecutiveSequence.java +++ b/src/main/java/depth_first_search/LongestConsecutiveSequence.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/MaxAreaOfIsland.java b/src/main/java/depth_first_search/MaxAreaOfIsland.java index 0851ed8d..c4001310 100644 --- a/src/main/java/depth_first_search/MaxAreaOfIsland.java +++ b/src/main/java/depth_first_search/MaxAreaOfIsland.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; /** diff --git a/src/main/java/depth_first_search/Minesweeper.java b/src/main/java/depth_first_search/Minesweeper.java index eb71da36..b2243211 100644 --- a/src/main/java/depth_first_search/Minesweeper.java +++ b/src/main/java/depth_first_search/Minesweeper.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; /** diff --git a/src/main/java/depth_first_search/MinimizeMalwareSpread.java b/src/main/java/depth_first_search/MinimizeMalwareSpread.java index 751db4ad..4731f44d 100644 --- a/src/main/java/depth_first_search/MinimizeMalwareSpread.java +++ b/src/main/java/depth_first_search/MinimizeMalwareSpread.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/MovieRecommend.java b/src/main/java/depth_first_search/MovieRecommend.java index 1acb16b2..df6cf76b 100644 --- a/src/main/java/depth_first_search/MovieRecommend.java +++ b/src/main/java/depth_first_search/MovieRecommend.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/NumberOfDistinctIslands.java b/src/main/java/depth_first_search/NumberOfDistinctIslands.java index e20e8960..e774fb17 100644 --- a/src/main/java/depth_first_search/NumberOfDistinctIslands.java +++ b/src/main/java/depth_first_search/NumberOfDistinctIslands.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.HashSet; diff --git a/src/main/java/depth_first_search/NumberOfDistinctIslandsII.java b/src/main/java/depth_first_search/NumberOfDistinctIslandsII.java index ae4af067..84f30333 100644 --- a/src/main/java/depth_first_search/NumberOfDistinctIslandsII.java +++ b/src/main/java/depth_first_search/NumberOfDistinctIslandsII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/NumberOfEnclaves.java b/src/main/java/depth_first_search/NumberOfEnclaves.java index aa6438c7..a5b65dc6 100644 --- a/src/main/java/depth_first_search/NumberOfEnclaves.java +++ b/src/main/java/depth_first_search/NumberOfEnclaves.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; /** diff --git a/src/main/java/depth_first_search/NumberOfIslands.java b/src/main/java/depth_first_search/NumberOfIslands.java index a4745b05..1d6925dd 100644 --- a/src/main/java/depth_first_search/NumberOfIslands.java +++ b/src/main/java/depth_first_search/NumberOfIslands.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; /** diff --git a/src/main/java/depth_first_search/ParallelCourses.java b/src/main/java/depth_first_search/ParallelCourses.java index 9d1d81ec..010ca8dc 100644 --- a/src/main/java/depth_first_search/ParallelCourses.java +++ b/src/main/java/depth_first_search/ParallelCourses.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/RobotRoomCleaner.java b/src/main/java/depth_first_search/RobotRoomCleaner.java index 189a6478..9da6a0f5 100644 --- a/src/main/java/depth_first_search/RobotRoomCleaner.java +++ b/src/main/java/depth_first_search/RobotRoomCleaner.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.HashSet; diff --git a/src/main/java/depth_first_search/SatisfiabilityOfEquations.java b/src/main/java/depth_first_search/SatisfiabilityOfEquations.java index 2e6ce48d..034f7247 100644 --- a/src/main/java/depth_first_search/SatisfiabilityOfEquations.java +++ b/src/main/java/depth_first_search/SatisfiabilityOfEquations.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/SmallestRectangleEnclosingBlackPixels.java b/src/main/java/depth_first_search/SmallestRectangleEnclosingBlackPixels.java index b82ed190..055f6026 100644 --- a/src/main/java/depth_first_search/SmallestRectangleEnclosingBlackPixels.java +++ b/src/main/java/depth_first_search/SmallestRectangleEnclosingBlackPixels.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; /** diff --git a/src/main/java/design/AutocompleteSystem.java b/src/main/java/design/AutocompleteSystem.java index ebe9deb2..105100d4 100644 --- a/src/main/java/design/AutocompleteSystem.java +++ b/src/main/java/design/AutocompleteSystem.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.*; diff --git a/src/main/java/design/BSTIterator.java b/src/main/java/design/BSTIterator.java index 743eae61..107d86ba 100644 --- a/src/main/java/design/BSTIterator.java +++ b/src/main/java/design/BSTIterator.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.Stack; diff --git a/src/main/java/design/CopyListWithRandomPointer.java b/src/main/java/design/CopyListWithRandomPointer.java index dbcb225c..2c1c5eb6 100644 --- a/src/main/java/design/CopyListWithRandomPointer.java +++ b/src/main/java/design/CopyListWithRandomPointer.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; /** diff --git a/src/main/java/design/EncodeAndDecodeTinyURL.java b/src/main/java/design/EncodeAndDecodeTinyURL.java index 94ca34f8..859a0684 100644 --- a/src/main/java/design/EncodeAndDecodeTinyURL.java +++ b/src/main/java/design/EncodeAndDecodeTinyURL.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.ArrayList; diff --git a/src/main/java/design/Excel.java b/src/main/java/design/Excel.java index c00bd33a..240acab5 100644 --- a/src/main/java/design/Excel.java +++ b/src/main/java/design/Excel.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.*; diff --git a/src/main/java/design/LFUCache.java b/src/main/java/design/LFUCache.java index 371054bf..3f5d2143 100644 --- a/src/main/java/design/LFUCache.java +++ b/src/main/java/design/LFUCache.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.HashMap; diff --git a/src/main/java/design/LRUCache.java b/src/main/java/design/LRUCache.java index 2d12a86e..9f02b5c1 100644 --- a/src/main/java/design/LRUCache.java +++ b/src/main/java/design/LRUCache.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.HashMap; diff --git a/src/main/java/design/NestedIterator.java b/src/main/java/design/NestedIterator.java index b7d1fc09..54ffa9c0 100644 --- a/src/main/java/design/NestedIterator.java +++ b/src/main/java/design/NestedIterator.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.ArrayList; diff --git a/src/main/java/design/RandomizedCollection.java b/src/main/java/design/RandomizedCollection.java index 466178c4..9d3abb76 100644 --- a/src/main/java/design/RandomizedCollection.java +++ b/src/main/java/design/RandomizedCollection.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.*; diff --git a/src/main/java/design/RandomizedSet.java b/src/main/java/design/RandomizedSet.java index 42babec3..5d52197e 100644 --- a/src/main/java/design/RandomizedSet.java +++ b/src/main/java/design/RandomizedSet.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.*; diff --git a/src/main/java/design/SerializeDeserializeBinaryTree.java b/src/main/java/design/SerializeDeserializeBinaryTree.java index 2313ad53..cdb5a640 100644 --- a/src/main/java/design/SerializeDeserializeBinaryTree.java +++ b/src/main/java/design/SerializeDeserializeBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.*; diff --git a/src/main/java/design/TicTacToe.java b/src/main/java/design/TicTacToe.java index 1e0728b8..2f356a77 100644 --- a/src/main/java/design/TicTacToe.java +++ b/src/main/java/design/TicTacToe.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; /** diff --git a/src/main/java/design/Trie.java b/src/main/java/design/Trie.java index f49eeccf..e896bb0a 100644 --- a/src/main/java/design/Trie.java +++ b/src/main/java/design/Trie.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.HashMap; diff --git a/src/main/java/design/Twitter.java b/src/main/java/design/Twitter.java index 8c58506a..f5c0e622 100644 --- a/src/main/java/design/Twitter.java +++ b/src/main/java/design/Twitter.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.*; diff --git a/src/main/java/design/WordDictionary.java b/src/main/java/design/WordDictionary.java index af1c8e58..b24468ca 100644 --- a/src/main/java/design/WordDictionary.java +++ b/src/main/java/design/WordDictionary.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.HashMap; diff --git a/src/main/java/design/WordFilter.java b/src/main/java/design/WordFilter.java index 566f5999..23e21b71 100644 --- a/src/main/java/design/WordFilter.java +++ b/src/main/java/design/WordFilter.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.HashMap; diff --git a/src/main/java/divide_and_conquer/KthLargestElementInAnArray.java b/src/main/java/divide_and_conquer/KthLargestElementInAnArray.java index d1666fb3..d87be858 100644 --- a/src/main/java/divide_and_conquer/KthLargestElementInAnArray.java +++ b/src/main/java/divide_and_conquer/KthLargestElementInAnArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package divide_and_conquer; /** diff --git a/src/main/java/divide_and_conquer/MyCalendarII.java b/src/main/java/divide_and_conquer/MyCalendarII.java index 7cbcf2d9..45462d50 100644 --- a/src/main/java/divide_and_conquer/MyCalendarII.java +++ b/src/main/java/divide_and_conquer/MyCalendarII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package divide_and_conquer; import java.util.*; diff --git a/src/main/java/divide_and_conquer/ReversePairs.java b/src/main/java/divide_and_conquer/ReversePairs.java index a919a4ef..0706ccf8 100644 --- a/src/main/java/divide_and_conquer/ReversePairs.java +++ b/src/main/java/divide_and_conquer/ReversePairs.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package divide_and_conquer; import java.util.*; diff --git a/src/main/java/divide_and_conquer/ReversePairsII.java b/src/main/java/divide_and_conquer/ReversePairsII.java index 60326d1e..fb79020b 100644 --- a/src/main/java/divide_and_conquer/ReversePairsII.java +++ b/src/main/java/divide_and_conquer/ReversePairsII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package divide_and_conquer; /** diff --git a/src/main/java/divide_and_conquer/SearchA2DMatrix.java b/src/main/java/divide_and_conquer/SearchA2DMatrix.java index e6941fb0..5234afae 100644 --- a/src/main/java/divide_and_conquer/SearchA2DMatrix.java +++ b/src/main/java/divide_and_conquer/SearchA2DMatrix.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package divide_and_conquer; /** diff --git a/src/main/java/divide_and_conquer/TwentyFourGame.java b/src/main/java/divide_and_conquer/TwentyFourGame.java index ed8b81e1..a9c5535a 100644 --- a/src/main/java/divide_and_conquer/TwentyFourGame.java +++ b/src/main/java/divide_and_conquer/TwentyFourGame.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package divide_and_conquer; import java.util.*; diff --git a/src/main/java/dynamic_programming/BestTimeToBuyAndSellStockIII.java b/src/main/java/dynamic_programming/BestTimeToBuyAndSellStockIII.java index 01bffcb1..9e03a07e 100644 --- a/src/main/java/dynamic_programming/BestTimeToBuyAndSellStockIII.java +++ b/src/main/java/dynamic_programming/BestTimeToBuyAndSellStockIII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/BestTimeToBuyAndSellStocks.java b/src/main/java/dynamic_programming/BestTimeToBuyAndSellStocks.java index acb6eb14..5945831f 100644 --- a/src/main/java/dynamic_programming/BestTimeToBuyAndSellStocks.java +++ b/src/main/java/dynamic_programming/BestTimeToBuyAndSellStocks.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java b/src/main/java/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java index 7154a204..ba4b3100 100644 --- a/src/main/java/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java +++ b/src/main/java/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/BombEnemy.java b/src/main/java/dynamic_programming/BombEnemy.java index 2fcbedb3..ece7d3d1 100644 --- a/src/main/java/dynamic_programming/BombEnemy.java +++ b/src/main/java/dynamic_programming/BombEnemy.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/BurstBalloons.java b/src/main/java/dynamic_programming/BurstBalloons.java index e74b6048..7a7db0f3 100644 --- a/src/main/java/dynamic_programming/BurstBalloons.java +++ b/src/main/java/dynamic_programming/BurstBalloons.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/CanIWin.java b/src/main/java/dynamic_programming/CanIWin.java index f68e925d..183b85aa 100644 --- a/src/main/java/dynamic_programming/CanIWin.java +++ b/src/main/java/dynamic_programming/CanIWin.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.HashMap; diff --git a/src/main/java/dynamic_programming/CatAndMouse.java b/src/main/java/dynamic_programming/CatAndMouse.java index b0dbbdb0..7d8e847d 100644 --- a/src/main/java/dynamic_programming/CatAndMouse.java +++ b/src/main/java/dynamic_programming/CatAndMouse.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/CherryPickup.java b/src/main/java/dynamic_programming/CherryPickup.java index 348c11d0..082c03a6 100644 --- a/src/main/java/dynamic_programming/CherryPickup.java +++ b/src/main/java/dynamic_programming/CherryPickup.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/CherryPickupII.java b/src/main/java/dynamic_programming/CherryPickupII.java index a2032e6c..0118620b 100644 --- a/src/main/java/dynamic_programming/CherryPickupII.java +++ b/src/main/java/dynamic_programming/CherryPickupII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/ClimbingStairs.java b/src/main/java/dynamic_programming/ClimbingStairs.java index 531687ac..6d283ed8 100644 --- a/src/main/java/dynamic_programming/ClimbingStairs.java +++ b/src/main/java/dynamic_programming/ClimbingStairs.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/CoinChange.java b/src/main/java/dynamic_programming/CoinChange.java index fedb648c..1233b457 100644 --- a/src/main/java/dynamic_programming/CoinChange.java +++ b/src/main/java/dynamic_programming/CoinChange.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/CoinChange2.java b/src/main/java/dynamic_programming/CoinChange2.java index fe5e84e6..86c5ff2f 100644 --- a/src/main/java/dynamic_programming/CoinChange2.java +++ b/src/main/java/dynamic_programming/CoinChange2.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/CombinationSumIV.java b/src/main/java/dynamic_programming/CombinationSumIV.java index 33a6634a..f0d2e714 100644 --- a/src/main/java/dynamic_programming/CombinationSumIV.java +++ b/src/main/java/dynamic_programming/CombinationSumIV.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/ConcatenatedWords.java b/src/main/java/dynamic_programming/ConcatenatedWords.java index eae5112d..f462ac00 100644 --- a/src/main/java/dynamic_programming/ConcatenatedWords.java +++ b/src/main/java/dynamic_programming/ConcatenatedWords.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.ArrayList; diff --git a/src/main/java/dynamic_programming/ConstrainedSubsequenceSum.java b/src/main/java/dynamic_programming/ConstrainedSubsequenceSum.java index b57de7b3..5b1dcc06 100644 --- a/src/main/java/dynamic_programming/ConstrainedSubsequenceSum.java +++ b/src/main/java/dynamic_programming/ConstrainedSubsequenceSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/ContinuousSubarraySum.java b/src/main/java/dynamic_programming/ContinuousSubarraySum.java index 53c17413..4cdeb35d 100644 --- a/src/main/java/dynamic_programming/ContinuousSubarraySum.java +++ b/src/main/java/dynamic_programming/ContinuousSubarraySum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.HashMap; diff --git a/src/main/java/dynamic_programming/CornerRectangles.java b/src/main/java/dynamic_programming/CornerRectangles.java index 2ee8ec0f..649278dc 100644 --- a/src/main/java/dynamic_programming/CornerRectangles.java +++ b/src/main/java/dynamic_programming/CornerRectangles.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/CountDifferentPalindromicSubsequences.java b/src/main/java/dynamic_programming/CountDifferentPalindromicSubsequences.java index 7395dcb9..6b0476d6 100644 --- a/src/main/java/dynamic_programming/CountDifferentPalindromicSubsequences.java +++ b/src/main/java/dynamic_programming/CountDifferentPalindromicSubsequences.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/CountVowelsPermutation.java b/src/main/java/dynamic_programming/CountVowelsPermutation.java index 613b3bba..f0484020 100644 --- a/src/main/java/dynamic_programming/CountVowelsPermutation.java +++ b/src/main/java/dynamic_programming/CountVowelsPermutation.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/DecodeWays.java b/src/main/java/dynamic_programming/DecodeWays.java index bfd708f5..fb82e92d 100644 --- a/src/main/java/dynamic_programming/DecodeWays.java +++ b/src/main/java/dynamic_programming/DecodeWays.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/DecodeWaysII.java b/src/main/java/dynamic_programming/DecodeWaysII.java index e17c441e..25cc3f2f 100644 --- a/src/main/java/dynamic_programming/DecodeWaysII.java +++ b/src/main/java/dynamic_programming/DecodeWaysII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/DeleteColumnsToMakeSortedIII.java b/src/main/java/dynamic_programming/DeleteColumnsToMakeSortedIII.java index fc28ed7d..6b4a31e1 100644 --- a/src/main/java/dynamic_programming/DeleteColumnsToMakeSortedIII.java +++ b/src/main/java/dynamic_programming/DeleteColumnsToMakeSortedIII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/DistinctSubsequences.java b/src/main/java/dynamic_programming/DistinctSubsequences.java index 90155fe4..24a6ebaa 100644 --- a/src/main/java/dynamic_programming/DistinctSubsequences.java +++ b/src/main/java/dynamic_programming/DistinctSubsequences.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/DistinctSubsequencesII.java b/src/main/java/dynamic_programming/DistinctSubsequencesII.java index ad5678d9..54499fc4 100644 --- a/src/main/java/dynamic_programming/DistinctSubsequencesII.java +++ b/src/main/java/dynamic_programming/DistinctSubsequencesII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** * Created by gouthamvidyapradhan on 08/05/2020 Given a string S, count the number of distinct, diff --git a/src/main/java/dynamic_programming/DungeonGame.java b/src/main/java/dynamic_programming/DungeonGame.java index e275dca5..80b669cd 100644 --- a/src/main/java/dynamic_programming/DungeonGame.java +++ b/src/main/java/dynamic_programming/DungeonGame.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/EncodeStringWithShortestLength.java b/src/main/java/dynamic_programming/EncodeStringWithShortestLength.java index 614c6c97..2520dde5 100644 --- a/src/main/java/dynamic_programming/EncodeStringWithShortestLength.java +++ b/src/main/java/dynamic_programming/EncodeStringWithShortestLength.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** * Created by gouthamvidyapradhan on 15/09/2019 Given a non-empty string, encode the string such diff --git a/src/main/java/dynamic_programming/FreedomTrail.java b/src/main/java/dynamic_programming/FreedomTrail.java index 776b86b1..69cd9e1c 100644 --- a/src/main/java/dynamic_programming/FreedomTrail.java +++ b/src/main/java/dynamic_programming/FreedomTrail.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/HandshakesThatDontCross.java b/src/main/java/dynamic_programming/HandshakesThatDontCross.java index 56b75b4b..1450b29e 100644 --- a/src/main/java/dynamic_programming/HandshakesThatDontCross.java +++ b/src/main/java/dynamic_programming/HandshakesThatDontCross.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/HouseRobber.java b/src/main/java/dynamic_programming/HouseRobber.java index 3f363840..8d6c0762 100644 --- a/src/main/java/dynamic_programming/HouseRobber.java +++ b/src/main/java/dynamic_programming/HouseRobber.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/HouseRobberII.java b/src/main/java/dynamic_programming/HouseRobberII.java index bc469bea..23b67131 100644 --- a/src/main/java/dynamic_programming/HouseRobberII.java +++ b/src/main/java/dynamic_programming/HouseRobberII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/InterleavingString.java b/src/main/java/dynamic_programming/InterleavingString.java index 2a3e5e78..defcddd3 100644 --- a/src/main/java/dynamic_programming/InterleavingString.java +++ b/src/main/java/dynamic_programming/InterleavingString.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** * Created by gouthamvidyapradhan on 30/01/2020 Given s1, s2, s3, find whether s3 is formed by the diff --git a/src/main/java/dynamic_programming/JumpGameV.java b/src/main/java/dynamic_programming/JumpGameV.java index 8241d084..142c49d2 100644 --- a/src/main/java/dynamic_programming/JumpGameV.java +++ b/src/main/java/dynamic_programming/JumpGameV.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/KnightDialer.java b/src/main/java/dynamic_programming/KnightDialer.java index be002fef..0424ecc7 100644 --- a/src/main/java/dynamic_programming/KnightDialer.java +++ b/src/main/java/dynamic_programming/KnightDialer.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/KnightProbabilityInChessboard.java b/src/main/java/dynamic_programming/KnightProbabilityInChessboard.java index 34afbea9..5674e4cb 100644 --- a/src/main/java/dynamic_programming/KnightProbabilityInChessboard.java +++ b/src/main/java/dynamic_programming/KnightProbabilityInChessboard.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/LargestMultipleOfThree.java b/src/main/java/dynamic_programming/LargestMultipleOfThree.java index 42febb10..1042aca3 100644 --- a/src/main/java/dynamic_programming/LargestMultipleOfThree.java +++ b/src/main/java/dynamic_programming/LargestMultipleOfThree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/LargestPlusSign.java b/src/main/java/dynamic_programming/LargestPlusSign.java index 11206209..19310d26 100644 --- a/src/main/java/dynamic_programming/LargestPlusSign.java +++ b/src/main/java/dynamic_programming/LargestPlusSign.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/LargestSumOfAverages.java b/src/main/java/dynamic_programming/LargestSumOfAverages.java index 2b63ef84..11377ce4 100644 --- a/src/main/java/dynamic_programming/LargestSumOfAverages.java +++ b/src/main/java/dynamic_programming/LargestSumOfAverages.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** * Created by gouthamvidyapradhan on 04/05/2018. We partition a row of numbers A into at most K diff --git a/src/main/java/dynamic_programming/LengthofLongestFibonacciSubsequence.java b/src/main/java/dynamic_programming/LengthofLongestFibonacciSubsequence.java index 79a00083..d7966bee 100644 --- a/src/main/java/dynamic_programming/LengthofLongestFibonacciSubsequence.java +++ b/src/main/java/dynamic_programming/LengthofLongestFibonacciSubsequence.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/LongestChunkedPalindromeDecomposition.java b/src/main/java/dynamic_programming/LongestChunkedPalindromeDecomposition.java index aa721339..2d2ed539 100644 --- a/src/main/java/dynamic_programming/LongestChunkedPalindromeDecomposition.java +++ b/src/main/java/dynamic_programming/LongestChunkedPalindromeDecomposition.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/LongestIncreasingSubsequence.java b/src/main/java/dynamic_programming/LongestIncreasingSubsequence.java index e594a47e..1550be7d 100644 --- a/src/main/java/dynamic_programming/LongestIncreasingSubsequence.java +++ b/src/main/java/dynamic_programming/LongestIncreasingSubsequence.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/LongestPaliandromicSubstring.java b/src/main/java/dynamic_programming/LongestPaliandromicSubstring.java index da69442f..30b34e83 100644 --- a/src/main/java/dynamic_programming/LongestPaliandromicSubstring.java +++ b/src/main/java/dynamic_programming/LongestPaliandromicSubstring.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/LongestPalindromicSubsequence.java b/src/main/java/dynamic_programming/LongestPalindromicSubsequence.java index d49d6a1b..ce06e81a 100644 --- a/src/main/java/dynamic_programming/LongestPalindromicSubsequence.java +++ b/src/main/java/dynamic_programming/LongestPalindromicSubsequence.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/MakeArrayStrictlyIncreasing.java b/src/main/java/dynamic_programming/MakeArrayStrictlyIncreasing.java index 85617d79..1a403009 100644 --- a/src/main/java/dynamic_programming/MakeArrayStrictlyIncreasing.java +++ b/src/main/java/dynamic_programming/MakeArrayStrictlyIncreasing.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/MaxSum3SubArray.java b/src/main/java/dynamic_programming/MaxSum3SubArray.java index b57f4ec1..ce9cfe6e 100644 --- a/src/main/java/dynamic_programming/MaxSum3SubArray.java +++ b/src/main/java/dynamic_programming/MaxSum3SubArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** * Created by gouthamvidyapradhan on 22/11/2017. diff --git a/src/main/java/dynamic_programming/MaximalSquare.java b/src/main/java/dynamic_programming/MaximalSquare.java index c87eb9da..c2ec8835 100644 --- a/src/main/java/dynamic_programming/MaximalSquare.java +++ b/src/main/java/dynamic_programming/MaximalSquare.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/MaximumProductSubarray.java b/src/main/java/dynamic_programming/MaximumProductSubarray.java index ae67a77c..b669a656 100644 --- a/src/main/java/dynamic_programming/MaximumProductSubarray.java +++ b/src/main/java/dynamic_programming/MaximumProductSubarray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/MaximumProfitInJobScheduling.java b/src/main/java/dynamic_programming/MaximumProfitInJobScheduling.java index fcb2036f..3495aec1 100644 --- a/src/main/java/dynamic_programming/MaximumProfitInJobScheduling.java +++ b/src/main/java/dynamic_programming/MaximumProfitInJobScheduling.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/MaximumSubarray.java b/src/main/java/dynamic_programming/MaximumSubarray.java index c51abb4b..82ed2628 100644 --- a/src/main/java/dynamic_programming/MaximumSubarray.java +++ b/src/main/java/dynamic_programming/MaximumSubarray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/MaximumVacationDays.java b/src/main/java/dynamic_programming/MaximumVacationDays.java index 5f57de6a..a530a7a8 100644 --- a/src/main/java/dynamic_programming/MaximumVacationDays.java +++ b/src/main/java/dynamic_programming/MaximumVacationDays.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/MinCostClimbingStairs.java b/src/main/java/dynamic_programming/MinCostClimbingStairs.java index decdae74..d316b922 100644 --- a/src/main/java/dynamic_programming/MinCostClimbingStairs.java +++ b/src/main/java/dynamic_programming/MinCostClimbingStairs.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/MinimumCostForTickets.java b/src/main/java/dynamic_programming/MinimumCostForTickets.java index e8a7c202..e1477c5c 100644 --- a/src/main/java/dynamic_programming/MinimumCostForTickets.java +++ b/src/main/java/dynamic_programming/MinimumCostForTickets.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/MinimumCostToMergeStones.java b/src/main/java/dynamic_programming/MinimumCostToMergeStones.java index 86442f22..8e0a1c80 100644 --- a/src/main/java/dynamic_programming/MinimumCostToMergeStones.java +++ b/src/main/java/dynamic_programming/MinimumCostToMergeStones.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/MinimumDifficultyOfAJobSchedule.java b/src/main/java/dynamic_programming/MinimumDifficultyOfAJobSchedule.java index 8771e62c..16015802 100644 --- a/src/main/java/dynamic_programming/MinimumDifficultyOfAJobSchedule.java +++ b/src/main/java/dynamic_programming/MinimumDifficultyOfAJobSchedule.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java b/src/main/java/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java index 9d66912d..a0e3198f 100644 --- a/src/main/java/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java +++ b/src/main/java/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/MinimumNumberOfRefuelingStops.java b/src/main/java/dynamic_programming/MinimumNumberOfRefuelingStops.java index 2c1026be..d2185f69 100644 --- a/src/main/java/dynamic_programming/MinimumNumberOfRefuelingStops.java +++ b/src/main/java/dynamic_programming/MinimumNumberOfRefuelingStops.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/MinimumNumberOfTaps.java b/src/main/java/dynamic_programming/MinimumNumberOfTaps.java index 8cce9d6f..45b1de6e 100644 --- a/src/main/java/dynamic_programming/MinimumNumberOfTaps.java +++ b/src/main/java/dynamic_programming/MinimumNumberOfTaps.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java b/src/main/java/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java index 6117b1ce..e4fa996d 100644 --- a/src/main/java/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java +++ b/src/main/java/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/NumberOfDiceRollsWithTargetSum.java b/src/main/java/dynamic_programming/NumberOfDiceRollsWithTargetSum.java index 024ded3b..3922b23f 100644 --- a/src/main/java/dynamic_programming/NumberOfDiceRollsWithTargetSum.java +++ b/src/main/java/dynamic_programming/NumberOfDiceRollsWithTargetSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/NumberOfLIS.java b/src/main/java/dynamic_programming/NumberOfLIS.java index a678340a..a6dd2ce6 100644 --- a/src/main/java/dynamic_programming/NumberOfLIS.java +++ b/src/main/java/dynamic_programming/NumberOfLIS.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/NumberOfMusicPlaylists.java b/src/main/java/dynamic_programming/NumberOfMusicPlaylists.java index d10793a3..e81aae24 100644 --- a/src/main/java/dynamic_programming/NumberOfMusicPlaylists.java +++ b/src/main/java/dynamic_programming/NumberOfMusicPlaylists.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/NumberOfPathsWithMaxScore.java b/src/main/java/dynamic_programming/NumberOfPathsWithMaxScore.java index 22f148a3..09d2fcee 100644 --- a/src/main/java/dynamic_programming/NumberOfPathsWithMaxScore.java +++ b/src/main/java/dynamic_programming/NumberOfPathsWithMaxScore.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java b/src/main/java/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java index 80a51890..9da8381b 100644 --- a/src/main/java/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java +++ b/src/main/java/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/OddEvenJump.java b/src/main/java/dynamic_programming/OddEvenJump.java index 177b2d48..f7238aed 100644 --- a/src/main/java/dynamic_programming/OddEvenJump.java +++ b/src/main/java/dynamic_programming/OddEvenJump.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/OnesAndZeroes.java b/src/main/java/dynamic_programming/OnesAndZeroes.java index fe4d0bde..7f260040 100644 --- a/src/main/java/dynamic_programming/OnesAndZeroes.java +++ b/src/main/java/dynamic_programming/OnesAndZeroes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/OutOfBoundaryPaths.java b/src/main/java/dynamic_programming/OutOfBoundaryPaths.java index a7e89b4f..3bf44810 100644 --- a/src/main/java/dynamic_programming/OutOfBoundaryPaths.java +++ b/src/main/java/dynamic_programming/OutOfBoundaryPaths.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/PaintHouseII.java b/src/main/java/dynamic_programming/PaintHouseII.java index 68c9d8a6..b22086be 100644 --- a/src/main/java/dynamic_programming/PaintHouseII.java +++ b/src/main/java/dynamic_programming/PaintHouseII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/PaintHouseIII.java b/src/main/java/dynamic_programming/PaintHouseIII.java index 5b94ef90..7b981013 100644 --- a/src/main/java/dynamic_programming/PaintHouseIII.java +++ b/src/main/java/dynamic_programming/PaintHouseIII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/PalindromePairs.java b/src/main/java/dynamic_programming/PalindromePairs.java index ebcab5c3..1ca89e4d 100644 --- a/src/main/java/dynamic_programming/PalindromePairs.java +++ b/src/main/java/dynamic_programming/PalindromePairs.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/PalindromePartitioningII.java b/src/main/java/dynamic_programming/PalindromePartitioningII.java index a04e7747..6dedd2c3 100644 --- a/src/main/java/dynamic_programming/PalindromePartitioningII.java +++ b/src/main/java/dynamic_programming/PalindromePartitioningII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/PalindromePartitioningIII.java b/src/main/java/dynamic_programming/PalindromePartitioningIII.java index a75e49b5..be678971 100644 --- a/src/main/java/dynamic_programming/PalindromePartitioningIII.java +++ b/src/main/java/dynamic_programming/PalindromePartitioningIII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/PalindromeRemoval.java b/src/main/java/dynamic_programming/PalindromeRemoval.java index bc41f25e..3c81a1fb 100644 --- a/src/main/java/dynamic_programming/PalindromeRemoval.java +++ b/src/main/java/dynamic_programming/PalindromeRemoval.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/PalindromicSubstrings.java b/src/main/java/dynamic_programming/PalindromicSubstrings.java index cc461c24..d8dcf944 100644 --- a/src/main/java/dynamic_programming/PalindromicSubstrings.java +++ b/src/main/java/dynamic_programming/PalindromicSubstrings.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/ProfitableSchemes.java b/src/main/java/dynamic_programming/ProfitableSchemes.java index 0f483933..b6f3becc 100644 --- a/src/main/java/dynamic_programming/ProfitableSchemes.java +++ b/src/main/java/dynamic_programming/ProfitableSchemes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** * Created by gouthamvidyapradhan on 26/03/2019 There are G people in a gang, and a list of various diff --git a/src/main/java/dynamic_programming/RemoveBoxes.java b/src/main/java/dynamic_programming/RemoveBoxes.java index 96ac5f4f..094f9497 100644 --- a/src/main/java/dynamic_programming/RemoveBoxes.java +++ b/src/main/java/dynamic_programming/RemoveBoxes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** * Created by gouthamvidyapradhan on 28/05/2019 Given several boxes with different colors diff --git a/src/main/java/dynamic_programming/RestoreTheArray.java b/src/main/java/dynamic_programming/RestoreTheArray.java index 8359f298..abae42d0 100644 --- a/src/main/java/dynamic_programming/RestoreTheArray.java +++ b/src/main/java/dynamic_programming/RestoreTheArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/RussianDollEnvelopes.java b/src/main/java/dynamic_programming/RussianDollEnvelopes.java index a8b10ebc..2b454d20 100644 --- a/src/main/java/dynamic_programming/RussianDollEnvelopes.java +++ b/src/main/java/dynamic_programming/RussianDollEnvelopes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/ShortestPathVisitingAllNodes.java b/src/main/java/dynamic_programming/ShortestPathVisitingAllNodes.java index 548ed02e..c56069de 100644 --- a/src/main/java/dynamic_programming/ShortestPathVisitingAllNodes.java +++ b/src/main/java/dynamic_programming/ShortestPathVisitingAllNodes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/SmallestSufficientTeam.java b/src/main/java/dynamic_programming/SmallestSufficientTeam.java index 79195e5e..c91247c0 100644 --- a/src/main/java/dynamic_programming/SmallestSufficientTeam.java +++ b/src/main/java/dynamic_programming/SmallestSufficientTeam.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/SplitArrayLargestSum.java b/src/main/java/dynamic_programming/SplitArrayLargestSum.java index 7112af7e..4e33b849 100644 --- a/src/main/java/dynamic_programming/SplitArrayLargestSum.java +++ b/src/main/java/dynamic_programming/SplitArrayLargestSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/StickersToSpellWord.java b/src/main/java/dynamic_programming/StickersToSpellWord.java index e88914dc..994dc62e 100644 --- a/src/main/java/dynamic_programming/StickersToSpellWord.java +++ b/src/main/java/dynamic_programming/StickersToSpellWord.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/StoneGame.java b/src/main/java/dynamic_programming/StoneGame.java index 514165ed..b3869d5c 100644 --- a/src/main/java/dynamic_programming/StoneGame.java +++ b/src/main/java/dynamic_programming/StoneGame.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/StoneGameIII.java b/src/main/java/dynamic_programming/StoneGameIII.java index 3d0ac82c..8b4ba08d 100644 --- a/src/main/java/dynamic_programming/StoneGameIII.java +++ b/src/main/java/dynamic_programming/StoneGameIII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/StoneGameIV.java b/src/main/java/dynamic_programming/StoneGameIV.java index 1d5b8cc4..70060906 100644 --- a/src/main/java/dynamic_programming/StoneGameIV.java +++ b/src/main/java/dynamic_programming/StoneGameIV.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/StrangePrinter.java b/src/main/java/dynamic_programming/StrangePrinter.java index a3dae96f..9db36a72 100644 --- a/src/main/java/dynamic_programming/StrangePrinter.java +++ b/src/main/java/dynamic_programming/StrangePrinter.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/TallestBillboard.java b/src/main/java/dynamic_programming/TallestBillboard.java index 94ede7d0..fcd356c9 100644 --- a/src/main/java/dynamic_programming/TallestBillboard.java +++ b/src/main/java/dynamic_programming/TallestBillboard.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/TilingARectangle.java b/src/main/java/dynamic_programming/TilingARectangle.java index badb9a50..9fbf1aa7 100644 --- a/src/main/java/dynamic_programming/TilingARectangle.java +++ b/src/main/java/dynamic_programming/TilingARectangle.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/TossStrangeCoins.java b/src/main/java/dynamic_programming/TossStrangeCoins.java index 6d1eb4ad..c36fba82 100644 --- a/src/main/java/dynamic_programming/TossStrangeCoins.java +++ b/src/main/java/dynamic_programming/TossStrangeCoins.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/TwoKeysKeyboard.java b/src/main/java/dynamic_programming/TwoKeysKeyboard.java index f51a223e..fe790f4c 100644 --- a/src/main/java/dynamic_programming/TwoKeysKeyboard.java +++ b/src/main/java/dynamic_programming/TwoKeysKeyboard.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/UniqueBinarySearchTrees.java b/src/main/java/dynamic_programming/UniqueBinarySearchTrees.java index 1297b3f8..d2080f20 100644 --- a/src/main/java/dynamic_programming/UniqueBinarySearchTrees.java +++ b/src/main/java/dynamic_programming/UniqueBinarySearchTrees.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/UniqueBinarySearchTreesII.java b/src/main/java/dynamic_programming/UniqueBinarySearchTreesII.java index ec3e00b9..1036c7ca 100644 --- a/src/main/java/dynamic_programming/UniqueBinarySearchTreesII.java +++ b/src/main/java/dynamic_programming/UniqueBinarySearchTreesII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/ValidPalindromeIII.java b/src/main/java/dynamic_programming/ValidPalindromeIII.java index d8a93b8a..e3be5fad 100644 --- a/src/main/java/dynamic_programming/ValidPalindromeIII.java +++ b/src/main/java/dynamic_programming/ValidPalindromeIII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/WordBreak.java b/src/main/java/dynamic_programming/WordBreak.java index 6a4ed7a4..7b54b113 100644 --- a/src/main/java/dynamic_programming/WordBreak.java +++ b/src/main/java/dynamic_programming/WordBreak.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/WordBreakII.java b/src/main/java/dynamic_programming/WordBreakII.java index 9739e6be..b4e7a682 100644 --- a/src/main/java/dynamic_programming/WordBreakII.java +++ b/src/main/java/dynamic_programming/WordBreakII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/greedy/BoatsToSavePeople.java b/src/main/java/greedy/BoatsToSavePeople.java index c85cfc54..73736e0c 100644 --- a/src/main/java/greedy/BoatsToSavePeople.java +++ b/src/main/java/greedy/BoatsToSavePeople.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.*; diff --git a/src/main/java/greedy/BrokenCalculator.java b/src/main/java/greedy/BrokenCalculator.java index a65becad..24f1c25e 100644 --- a/src/main/java/greedy/BrokenCalculator.java +++ b/src/main/java/greedy/BrokenCalculator.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.*; diff --git a/src/main/java/greedy/BurstBalloons.java b/src/main/java/greedy/BurstBalloons.java index 0ebca988..b0795e09 100644 --- a/src/main/java/greedy/BurstBalloons.java +++ b/src/main/java/greedy/BurstBalloons.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.Arrays; diff --git a/src/main/java/greedy/CourseScheduleIII.java b/src/main/java/greedy/CourseScheduleIII.java index e7afb7e8..0ce37550 100644 --- a/src/main/java/greedy/CourseScheduleIII.java +++ b/src/main/java/greedy/CourseScheduleIII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.Arrays; diff --git a/src/main/java/greedy/GasStation.java b/src/main/java/greedy/GasStation.java index 7b0da2c2..62a2d396 100644 --- a/src/main/java/greedy/GasStation.java +++ b/src/main/java/greedy/GasStation.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; /** diff --git a/src/main/java/greedy/IPO.java b/src/main/java/greedy/IPO.java index 6b5dd2cf..049cbf93 100644 --- a/src/main/java/greedy/IPO.java +++ b/src/main/java/greedy/IPO.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; /** * Created by gouthamvidyapradhan on 09/04/2019 Suppose LeetCode will start its IPO soon. In order diff --git a/src/main/java/greedy/JumpGame.java b/src/main/java/greedy/JumpGame.java index 8ad08d96..dcb916e4 100644 --- a/src/main/java/greedy/JumpGame.java +++ b/src/main/java/greedy/JumpGame.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; /** diff --git a/src/main/java/greedy/JumpGameII.java b/src/main/java/greedy/JumpGameII.java index 9969fc40..5ffd6dd1 100644 --- a/src/main/java/greedy/JumpGameII.java +++ b/src/main/java/greedy/JumpGameII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; /** diff --git a/src/main/java/greedy/LemonadeChange.java b/src/main/java/greedy/LemonadeChange.java index f0aaf52d..43d4fa2c 100644 --- a/src/main/java/greedy/LemonadeChange.java +++ b/src/main/java/greedy/LemonadeChange.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; /** diff --git a/src/main/java/greedy/MaximumLengthOfPairChain.java b/src/main/java/greedy/MaximumLengthOfPairChain.java index ee8eb86c..8e363bcd 100644 --- a/src/main/java/greedy/MaximumLengthOfPairChain.java +++ b/src/main/java/greedy/MaximumLengthOfPairChain.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.Arrays; diff --git a/src/main/java/greedy/MinimumTimeToBuildBlocks.java b/src/main/java/greedy/MinimumTimeToBuildBlocks.java index 62a4ef7f..68a9f445 100644 --- a/src/main/java/greedy/MinimumTimeToBuildBlocks.java +++ b/src/main/java/greedy/MinimumTimeToBuildBlocks.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.PriorityQueue; diff --git a/src/main/java/greedy/NonOverlappingIntervals.java b/src/main/java/greedy/NonOverlappingIntervals.java index c9d9cffc..93bec062 100644 --- a/src/main/java/greedy/NonOverlappingIntervals.java +++ b/src/main/java/greedy/NonOverlappingIntervals.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.Arrays; diff --git a/src/main/java/greedy/PartitionLabels.java b/src/main/java/greedy/PartitionLabels.java index daa68cab..f33c929b 100644 --- a/src/main/java/greedy/PartitionLabels.java +++ b/src/main/java/greedy/PartitionLabels.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.*; diff --git a/src/main/java/greedy/QueueReconstructionByHeight.java b/src/main/java/greedy/QueueReconstructionByHeight.java index 2ae1f5a7..2e04f6dc 100644 --- a/src/main/java/greedy/QueueReconstructionByHeight.java +++ b/src/main/java/greedy/QueueReconstructionByHeight.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.Arrays; diff --git a/src/main/java/greedy/ReducingDishes.java b/src/main/java/greedy/ReducingDishes.java index de9640ca..f21b0729 100644 --- a/src/main/java/greedy/ReducingDishes.java +++ b/src/main/java/greedy/ReducingDishes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.*; diff --git a/src/main/java/greedy/ScoreAfterFlippingMatrix.java b/src/main/java/greedy/ScoreAfterFlippingMatrix.java index 3fc6b6f1..fd7a9d1d 100644 --- a/src/main/java/greedy/ScoreAfterFlippingMatrix.java +++ b/src/main/java/greedy/ScoreAfterFlippingMatrix.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; /** diff --git a/src/main/java/greedy/StringWithout3A3B.java b/src/main/java/greedy/StringWithout3A3B.java index c6e19f37..91c69416 100644 --- a/src/main/java/greedy/StringWithout3A3B.java +++ b/src/main/java/greedy/StringWithout3A3B.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; /** diff --git a/src/main/java/greedy/TaskScheduler.java b/src/main/java/greedy/TaskScheduler.java index d084359c..d959cc10 100644 --- a/src/main/java/greedy/TaskScheduler.java +++ b/src/main/java/greedy/TaskScheduler.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.*; diff --git a/src/main/java/greedy/TwoCityScheduling.java b/src/main/java/greedy/TwoCityScheduling.java index 17a8da11..495023fd 100644 --- a/src/main/java/greedy/TwoCityScheduling.java +++ b/src/main/java/greedy/TwoCityScheduling.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.*; diff --git a/src/main/java/hashing/Anagrams.java b/src/main/java/hashing/Anagrams.java index 6bcbba8c..85684cc5 100644 --- a/src/main/java/hashing/Anagrams.java +++ b/src/main/java/hashing/Anagrams.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.ArrayList; diff --git a/src/main/java/hashing/AnalyzeUserWebsiteVisitPattern.java b/src/main/java/hashing/AnalyzeUserWebsiteVisitPattern.java index 9168cc3d..1c128bf0 100644 --- a/src/main/java/hashing/AnalyzeUserWebsiteVisitPattern.java +++ b/src/main/java/hashing/AnalyzeUserWebsiteVisitPattern.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.*; diff --git a/src/main/java/hashing/BrickWall.java b/src/main/java/hashing/BrickWall.java index 3376c5b3..33bca838 100644 --- a/src/main/java/hashing/BrickWall.java +++ b/src/main/java/hashing/BrickWall.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.ArrayList; diff --git a/src/main/java/hashing/ContiguousArray.java b/src/main/java/hashing/ContiguousArray.java index 2702df6f..481408e2 100644 --- a/src/main/java/hashing/ContiguousArray.java +++ b/src/main/java/hashing/ContiguousArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.HashMap; diff --git a/src/main/java/hashing/CustomSortString.java b/src/main/java/hashing/CustomSortString.java index de7e44bb..a54cfe4c 100644 --- a/src/main/java/hashing/CustomSortString.java +++ b/src/main/java/hashing/CustomSortString.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.*; diff --git a/src/main/java/hashing/DistributeCandies.java b/src/main/java/hashing/DistributeCandies.java index 9b8d18f5..473888a7 100644 --- a/src/main/java/hashing/DistributeCandies.java +++ b/src/main/java/hashing/DistributeCandies.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.*; diff --git a/src/main/java/hashing/GroupAnagrams.java b/src/main/java/hashing/GroupAnagrams.java index 69251926..be1b90e6 100644 --- a/src/main/java/hashing/GroupAnagrams.java +++ b/src/main/java/hashing/GroupAnagrams.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.ArrayList; diff --git a/src/main/java/hashing/GroupsOfSpecialEquivalentStrings.java b/src/main/java/hashing/GroupsOfSpecialEquivalentStrings.java index fd37ad63..958de35f 100644 --- a/src/main/java/hashing/GroupsOfSpecialEquivalentStrings.java +++ b/src/main/java/hashing/GroupsOfSpecialEquivalentStrings.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.*; diff --git a/src/main/java/hashing/KdiffPairsInanArray.java b/src/main/java/hashing/KdiffPairsInanArray.java index ab5ef28a..c724a8fe 100644 --- a/src/main/java/hashing/KdiffPairsInanArray.java +++ b/src/main/java/hashing/KdiffPairsInanArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.HashMap; diff --git a/src/main/java/hashing/LargestUniqueNumber.java b/src/main/java/hashing/LargestUniqueNumber.java index 12c2e4db..1d2fb3a0 100644 --- a/src/main/java/hashing/LargestUniqueNumber.java +++ b/src/main/java/hashing/LargestUniqueNumber.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.*; diff --git a/src/main/java/hashing/MaximumSizeSubarraySumEqualsk.java b/src/main/java/hashing/MaximumSizeSubarraySumEqualsk.java index 9616f9a4..219cd4a8 100644 --- a/src/main/java/hashing/MaximumSizeSubarraySumEqualsk.java +++ b/src/main/java/hashing/MaximumSizeSubarraySumEqualsk.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.HashMap; diff --git a/src/main/java/hashing/NumberOfAtoms.java b/src/main/java/hashing/NumberOfAtoms.java index 09513fae..0fbdccbe 100644 --- a/src/main/java/hashing/NumberOfAtoms.java +++ b/src/main/java/hashing/NumberOfAtoms.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.*; diff --git a/src/main/java/hashing/PartitionLabels.java b/src/main/java/hashing/PartitionLabels.java index 0b00ccdd..6b5bc435 100644 --- a/src/main/java/hashing/PartitionLabels.java +++ b/src/main/java/hashing/PartitionLabels.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.ArrayList; diff --git a/src/main/java/hashing/ShortEncodingOfWords.java b/src/main/java/hashing/ShortEncodingOfWords.java index 56b80a15..ada03526 100644 --- a/src/main/java/hashing/ShortEncodingOfWords.java +++ b/src/main/java/hashing/ShortEncodingOfWords.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.*; diff --git a/src/main/java/hashing/SortCharByFrequency.java b/src/main/java/hashing/SortCharByFrequency.java index 29e40bc7..1f1aec8a 100644 --- a/src/main/java/hashing/SortCharByFrequency.java +++ b/src/main/java/hashing/SortCharByFrequency.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.ArrayList; diff --git a/src/main/java/hashing/StringTransformsIntoAnotherString.java b/src/main/java/hashing/StringTransformsIntoAnotherString.java index 920c4780..20932803 100644 --- a/src/main/java/hashing/StringTransformsIntoAnotherString.java +++ b/src/main/java/hashing/StringTransformsIntoAnotherString.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.*; diff --git a/src/main/java/hashing/SubstringConcatenationOfWords.java b/src/main/java/hashing/SubstringConcatenationOfWords.java index 1c23716e..73eceaf0 100644 --- a/src/main/java/hashing/SubstringConcatenationOfWords.java +++ b/src/main/java/hashing/SubstringConcatenationOfWords.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.ArrayList; diff --git a/src/main/java/hashing/TwoSum.java b/src/main/java/hashing/TwoSum.java index 5e1bba45..0c321989 100644 --- a/src/main/java/hashing/TwoSum.java +++ b/src/main/java/hashing/TwoSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.HashMap; diff --git a/src/main/java/hashing/ValidAnagram.java b/src/main/java/hashing/ValidAnagram.java index 0fb2a6c9..97b51a97 100644 --- a/src/main/java/hashing/ValidAnagram.java +++ b/src/main/java/hashing/ValidAnagram.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; /** diff --git a/src/main/java/heap/Candy.java b/src/main/java/heap/Candy.java index 387389a2..0f1b657c 100644 --- a/src/main/java/heap/Candy.java +++ b/src/main/java/heap/Candy.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.*; diff --git a/src/main/java/heap/DistantBarcodes.java b/src/main/java/heap/DistantBarcodes.java index 652c8ff1..54ce859b 100644 --- a/src/main/java/heap/DistantBarcodes.java +++ b/src/main/java/heap/DistantBarcodes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.*; diff --git a/src/main/java/heap/FreqStack.java b/src/main/java/heap/FreqStack.java index 58944403..78ca3dce 100644 --- a/src/main/java/heap/FreqStack.java +++ b/src/main/java/heap/FreqStack.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.*; diff --git a/src/main/java/heap/KClosestPointsToOrigin.java b/src/main/java/heap/KClosestPointsToOrigin.java index ed4bc1e3..d15fe579 100644 --- a/src/main/java/heap/KClosestPointsToOrigin.java +++ b/src/main/java/heap/KClosestPointsToOrigin.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.*; diff --git a/src/main/java/heap/MeetingRoomsII.java b/src/main/java/heap/MeetingRoomsII.java index 50a013de..33131b41 100644 --- a/src/main/java/heap/MeetingRoomsII.java +++ b/src/main/java/heap/MeetingRoomsII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.Arrays; diff --git a/src/main/java/heap/ReachableNodesInSubdividedGraph.java b/src/main/java/heap/ReachableNodesInSubdividedGraph.java index eb30a9d5..00c85813 100644 --- a/src/main/java/heap/ReachableNodesInSubdividedGraph.java +++ b/src/main/java/heap/ReachableNodesInSubdividedGraph.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.*; diff --git a/src/main/java/heap/SlidingWindowMaximum.java b/src/main/java/heap/SlidingWindowMaximum.java index 495ae420..138f78fe 100644 --- a/src/main/java/heap/SlidingWindowMaximum.java +++ b/src/main/java/heap/SlidingWindowMaximum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.ArrayDeque; diff --git a/src/main/java/heap/SmallestRotationWithHighestScore.java b/src/main/java/heap/SmallestRotationWithHighestScore.java index faefc394..35cf6be0 100644 --- a/src/main/java/heap/SmallestRotationWithHighestScore.java +++ b/src/main/java/heap/SmallestRotationWithHighestScore.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.Comparator; diff --git a/src/main/java/heap/TheSkylineProblem.java b/src/main/java/heap/TheSkylineProblem.java index 6cf65f95..ad19755a 100644 --- a/src/main/java/heap/TheSkylineProblem.java +++ b/src/main/java/heap/TheSkylineProblem.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.*; diff --git a/src/main/java/heap/TopKFrequentWords.java b/src/main/java/heap/TopKFrequentWords.java index f0bf249b..7774d477 100644 --- a/src/main/java/heap/TopKFrequentWords.java +++ b/src/main/java/heap/TopKFrequentWords.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.*; diff --git a/src/main/java/linked_list/DeleteNode.java b/src/main/java/linked_list/DeleteNode.java index 28479dcf..7b935e4c 100644 --- a/src/main/java/linked_list/DeleteNode.java +++ b/src/main/java/linked_list/DeleteNode.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** diff --git a/src/main/java/linked_list/IntersectionOfTwoLists.java b/src/main/java/linked_list/IntersectionOfTwoLists.java index e52392c8..b3abc9dd 100644 --- a/src/main/java/linked_list/IntersectionOfTwoLists.java +++ b/src/main/java/linked_list/IntersectionOfTwoLists.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** diff --git a/src/main/java/linked_list/LinkedListCycle.java b/src/main/java/linked_list/LinkedListCycle.java index 3b7bfa56..b9bcc130 100644 --- a/src/main/java/linked_list/LinkedListCycle.java +++ b/src/main/java/linked_list/LinkedListCycle.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; import java.util.HashSet; diff --git a/src/main/java/linked_list/MergeKSortedLists.java b/src/main/java/linked_list/MergeKSortedLists.java index 3797b0d6..c128fce3 100644 --- a/src/main/java/linked_list/MergeKSortedLists.java +++ b/src/main/java/linked_list/MergeKSortedLists.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** diff --git a/src/main/java/linked_list/MergeTwoSortedList.java b/src/main/java/linked_list/MergeTwoSortedList.java index 24fc4678..c3a5f87c 100644 --- a/src/main/java/linked_list/MergeTwoSortedList.java +++ b/src/main/java/linked_list/MergeTwoSortedList.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** diff --git a/src/main/java/linked_list/MiddleOfLinkedList.java b/src/main/java/linked_list/MiddleOfLinkedList.java index ec5a0a37..a75150d8 100644 --- a/src/main/java/linked_list/MiddleOfLinkedList.java +++ b/src/main/java/linked_list/MiddleOfLinkedList.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** diff --git a/src/main/java/linked_list/NextGreaterNodeInLinkedList.java b/src/main/java/linked_list/NextGreaterNodeInLinkedList.java index 3abc6bca..b5e4a196 100644 --- a/src/main/java/linked_list/NextGreaterNodeInLinkedList.java +++ b/src/main/java/linked_list/NextGreaterNodeInLinkedList.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; import java.util.*; diff --git a/src/main/java/linked_list/PaliandromeList.java b/src/main/java/linked_list/PaliandromeList.java index b8ea89d1..6629d699 100644 --- a/src/main/java/linked_list/PaliandromeList.java +++ b/src/main/java/linked_list/PaliandromeList.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** diff --git a/src/main/java/linked_list/ReverseLinkedList.java b/src/main/java/linked_list/ReverseLinkedList.java index 6109d070..e7b00d28 100644 --- a/src/main/java/linked_list/ReverseLinkedList.java +++ b/src/main/java/linked_list/ReverseLinkedList.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** Created by gouthamvidyapradhan on 24/02/2017. Reverse a singly linked list. */ diff --git a/src/main/java/linked_list/ReverseNodesKGroup.java b/src/main/java/linked_list/ReverseNodesKGroup.java index f300fb3b..a253c32e 100644 --- a/src/main/java/linked_list/ReverseNodesKGroup.java +++ b/src/main/java/linked_list/ReverseNodesKGroup.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** diff --git a/src/main/java/linked_list/SplitLinkedListInParts.java b/src/main/java/linked_list/SplitLinkedListInParts.java index 44f0908a..e0a43138 100644 --- a/src/main/java/linked_list/SplitLinkedListInParts.java +++ b/src/main/java/linked_list/SplitLinkedListInParts.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; import java.util.*; diff --git a/src/main/java/linked_list/SwapNodesInPairs.java b/src/main/java/linked_list/SwapNodesInPairs.java index a74da9a1..66e4a432 100644 --- a/src/main/java/linked_list/SwapNodesInPairs.java +++ b/src/main/java/linked_list/SwapNodesInPairs.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** diff --git a/src/main/java/math/AddDigits.java b/src/main/java/math/AddDigits.java index 62a46a3c..2fd67cf4 100644 --- a/src/main/java/math/AddDigits.java +++ b/src/main/java/math/AddDigits.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/AddTwoNumbers.java b/src/main/java/math/AddTwoNumbers.java index 89e6a6fb..fcd60431 100644 --- a/src/main/java/math/AddTwoNumbers.java +++ b/src/main/java/math/AddTwoNumbers.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/Base7.java b/src/main/java/math/Base7.java index e35fd649..1037a6e4 100644 --- a/src/main/java/math/Base7.java +++ b/src/main/java/math/Base7.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; import java.util.*; diff --git a/src/main/java/math/BulbSwitcherII.java b/src/main/java/math/BulbSwitcherII.java index 53196e8d..e7c04b80 100644 --- a/src/main/java/math/BulbSwitcherII.java +++ b/src/main/java/math/BulbSwitcherII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/CountPrimes.java b/src/main/java/math/CountPrimes.java index ce212ea9..ee971487 100644 --- a/src/main/java/math/CountPrimes.java +++ b/src/main/java/math/CountPrimes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; import java.util.BitSet; diff --git a/src/main/java/math/CouplesHoldingHands.java b/src/main/java/math/CouplesHoldingHands.java index 65bbc71e..6d81c96b 100644 --- a/src/main/java/math/CouplesHoldingHands.java +++ b/src/main/java/math/CouplesHoldingHands.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/DecodedStringAtIndex.java b/src/main/java/math/DecodedStringAtIndex.java index 6f0e5a2e..357f7947 100644 --- a/src/main/java/math/DecodedStringAtIndex.java +++ b/src/main/java/math/DecodedStringAtIndex.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/ExcelSheetColumnTitle.java b/src/main/java/math/ExcelSheetColumnTitle.java index e6f9e7e5..9b523996 100644 --- a/src/main/java/math/ExcelSheetColumnTitle.java +++ b/src/main/java/math/ExcelSheetColumnTitle.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/GlobalAndLocalInversions.java b/src/main/java/math/GlobalAndLocalInversions.java index eb974f0e..444dca0e 100644 --- a/src/main/java/math/GlobalAndLocalInversions.java +++ b/src/main/java/math/GlobalAndLocalInversions.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/LargestComponentSizebyCommonFactor.java b/src/main/java/math/LargestComponentSizebyCommonFactor.java index 80288ebd..59df14d8 100644 --- a/src/main/java/math/LargestComponentSizebyCommonFactor.java +++ b/src/main/java/math/LargestComponentSizebyCommonFactor.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; import java.util.*; diff --git a/src/main/java/math/MinimumIndexSumOfTwoLists.java b/src/main/java/math/MinimumIndexSumOfTwoLists.java index 942e3a99..19acde3b 100644 --- a/src/main/java/math/MinimumIndexSumOfTwoLists.java +++ b/src/main/java/math/MinimumIndexSumOfTwoLists.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; import java.util.*; diff --git a/src/main/java/math/NthDigit.java b/src/main/java/math/NthDigit.java index b4715676..eb02406d 100644 --- a/src/main/java/math/NthDigit.java +++ b/src/main/java/math/NthDigit.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** Created by gouthamvidyapradhan on 05/11/2019 */ diff --git a/src/main/java/math/NthMagicalNumber.java b/src/main/java/math/NthMagicalNumber.java index c25560b6..9f957863 100644 --- a/src/main/java/math/NthMagicalNumber.java +++ b/src/main/java/math/NthMagicalNumber.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; import java.math.BigInteger; diff --git a/src/main/java/math/ProjectionAreaOf3DShapes.java b/src/main/java/math/ProjectionAreaOf3DShapes.java index 13de9353..1416f844 100644 --- a/src/main/java/math/ProjectionAreaOf3DShapes.java +++ b/src/main/java/math/ProjectionAreaOf3DShapes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** * Created by gouthamvidyapradhan on 09/05/2019 diff --git a/src/main/java/math/RangeAdditionII.java b/src/main/java/math/RangeAdditionII.java index 800a85c7..17f197e4 100644 --- a/src/main/java/math/RangeAdditionII.java +++ b/src/main/java/math/RangeAdditionII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; import java.util.*; diff --git a/src/main/java/math/ReachingPoints.java b/src/main/java/math/ReachingPoints.java index 2297a7c8..36036e4c 100644 --- a/src/main/java/math/ReachingPoints.java +++ b/src/main/java/math/ReachingPoints.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/RectangleOverlap.java b/src/main/java/math/RectangleOverlap.java index 303c4a0a..dd8d32b2 100644 --- a/src/main/java/math/RectangleOverlap.java +++ b/src/main/java/math/RectangleOverlap.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/RomanToInteger.java b/src/main/java/math/RomanToInteger.java index 6e45b23c..273ec3c4 100644 --- a/src/main/java/math/RomanToInteger.java +++ b/src/main/java/math/RomanToInteger.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; import java.util.HashMap; diff --git a/src/main/java/math/RotateFunction.java b/src/main/java/math/RotateFunction.java index f3abf97b..c634ea54 100644 --- a/src/main/java/math/RotateFunction.java +++ b/src/main/java/math/RotateFunction.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/SmallestRangeI.java b/src/main/java/math/SmallestRangeI.java index 95b47fc9..fa5e1bb0 100644 --- a/src/main/java/math/SmallestRangeI.java +++ b/src/main/java/math/SmallestRangeI.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; import java.util.*; diff --git a/src/main/java/math/SolveTheEquation.java b/src/main/java/math/SolveTheEquation.java index c17e48c7..b829ad6c 100644 --- a/src/main/java/math/SolveTheEquation.java +++ b/src/main/java/math/SolveTheEquation.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/SquirrelSimulation.java b/src/main/java/math/SquirrelSimulation.java index a2a681f1..4b40f2f3 100644 --- a/src/main/java/math/SquirrelSimulation.java +++ b/src/main/java/math/SquirrelSimulation.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/SuperWashingMachines.java b/src/main/java/math/SuperWashingMachines.java index a1fa2dc5..35fa07d5 100644 --- a/src/main/java/math/SuperWashingMachines.java +++ b/src/main/java/math/SuperWashingMachines.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; import java.util.Arrays; diff --git a/src/main/java/math/WaterAndJugProblem.java b/src/main/java/math/WaterAndJugProblem.java index fabc0ada..dfc239b0 100644 --- a/src/main/java/math/WaterAndJugProblem.java +++ b/src/main/java/math/WaterAndJugProblem.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; import java.math.BigInteger; diff --git a/src/main/java/reservoir_sampling/RandomPickIndex.java b/src/main/java/reservoir_sampling/RandomPickIndex.java index 519ecf1b..68d6e750 100644 --- a/src/main/java/reservoir_sampling/RandomPickIndex.java +++ b/src/main/java/reservoir_sampling/RandomPickIndex.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package reservoir_sampling; import java.util.Random; diff --git a/src/main/java/stack/BasicCalculator.java b/src/main/java/stack/BasicCalculator.java index 165dc496..5338b314 100644 --- a/src/main/java/stack/BasicCalculator.java +++ b/src/main/java/stack/BasicCalculator.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.Stack; diff --git a/src/main/java/stack/DecodeString.java b/src/main/java/stack/DecodeString.java index 39d021cc..1e03fb91 100644 --- a/src/main/java/stack/DecodeString.java +++ b/src/main/java/stack/DecodeString.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.Stack; diff --git a/src/main/java/stack/DecodedStringAtIndex.java b/src/main/java/stack/DecodedStringAtIndex.java index f537a58f..47f8d3f8 100644 --- a/src/main/java/stack/DecodedStringAtIndex.java +++ b/src/main/java/stack/DecodedStringAtIndex.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.Stack; diff --git a/src/main/java/stack/ExclusiveTimeOfFunctions.java b/src/main/java/stack/ExclusiveTimeOfFunctions.java index bf0f8cec..23890ad6 100644 --- a/src/main/java/stack/ExclusiveTimeOfFunctions.java +++ b/src/main/java/stack/ExclusiveTimeOfFunctions.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.ArrayList; diff --git a/src/main/java/stack/LargestRectangleInHistogram.java b/src/main/java/stack/LargestRectangleInHistogram.java index aff156a4..9c53b2e6 100644 --- a/src/main/java/stack/LargestRectangleInHistogram.java +++ b/src/main/java/stack/LargestRectangleInHistogram.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.Stack; diff --git a/src/main/java/stack/LongestValidParentheses.java b/src/main/java/stack/LongestValidParentheses.java index f4b6bb38..3535b33d 100644 --- a/src/main/java/stack/LongestValidParentheses.java +++ b/src/main/java/stack/LongestValidParentheses.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.*; diff --git a/src/main/java/stack/MaximalRectangle.java b/src/main/java/stack/MaximalRectangle.java index 2a710592..8d56347e 100644 --- a/src/main/java/stack/MaximalRectangle.java +++ b/src/main/java/stack/MaximalRectangle.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.Stack; diff --git a/src/main/java/stack/MinStack.java b/src/main/java/stack/MinStack.java index 512846f5..07948d21 100644 --- a/src/main/java/stack/MinStack.java +++ b/src/main/java/stack/MinStack.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.Stack; diff --git a/src/main/java/stack/MyQueue.java b/src/main/java/stack/MyQueue.java index a5547f48..d15ba1f7 100644 --- a/src/main/java/stack/MyQueue.java +++ b/src/main/java/stack/MyQueue.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.Stack; diff --git a/src/main/java/stack/StudentAttendanceRecordII.java b/src/main/java/stack/StudentAttendanceRecordII.java index 4e896693..753d2f35 100644 --- a/src/main/java/stack/StudentAttendanceRecordII.java +++ b/src/main/java/stack/StudentAttendanceRecordII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; /** diff --git a/src/main/java/stack/ValidParentheses.java b/src/main/java/stack/ValidParentheses.java index d9d77afd..fbe69062 100644 --- a/src/main/java/stack/ValidParentheses.java +++ b/src/main/java/stack/ValidParentheses.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.HashMap; diff --git a/src/main/java/string/AddBinary.java b/src/main/java/string/AddBinary.java index 9f813def..5eb80046 100644 --- a/src/main/java/string/AddBinary.java +++ b/src/main/java/string/AddBinary.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/CompareVersionNumbers.java b/src/main/java/string/CompareVersionNumbers.java index bffac314..c45f221e 100644 --- a/src/main/java/string/CompareVersionNumbers.java +++ b/src/main/java/string/CompareVersionNumbers.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.StringTokenizer; diff --git a/src/main/java/string/CountAndSay.java b/src/main/java/string/CountAndSay.java index 55536426..e50983a4 100644 --- a/src/main/java/string/CountAndSay.java +++ b/src/main/java/string/CountAndSay.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/ExcelSheetColumnNumber.java b/src/main/java/string/ExcelSheetColumnNumber.java index 889aa710..f0ecd7e2 100644 --- a/src/main/java/string/ExcelSheetColumnNumber.java +++ b/src/main/java/string/ExcelSheetColumnNumber.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/FindTheClosestPalindrome.java b/src/main/java/string/FindTheClosestPalindrome.java index f9c3e096..86459c41 100644 --- a/src/main/java/string/FindTheClosestPalindrome.java +++ b/src/main/java/string/FindTheClosestPalindrome.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/FindWordsThatCanBeFormedbyCharacters.java b/src/main/java/string/FindWordsThatCanBeFormedbyCharacters.java index c483f816..6a16bf0b 100644 --- a/src/main/java/string/FindWordsThatCanBeFormedbyCharacters.java +++ b/src/main/java/string/FindWordsThatCanBeFormedbyCharacters.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.*; diff --git a/src/main/java/string/FirstUniqueCharacterInAString.java b/src/main/java/string/FirstUniqueCharacterInAString.java index 13e9a8c5..9eabdc6a 100644 --- a/src/main/java/string/FirstUniqueCharacterInAString.java +++ b/src/main/java/string/FirstUniqueCharacterInAString.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/ImplementStrStr.java b/src/main/java/string/ImplementStrStr.java index 11349152..a2e52a32 100644 --- a/src/main/java/string/ImplementStrStr.java +++ b/src/main/java/string/ImplementStrStr.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/IsomorphicStrings.java b/src/main/java/string/IsomorphicStrings.java index f9c44de5..5956e51d 100644 --- a/src/main/java/string/IsomorphicStrings.java +++ b/src/main/java/string/IsomorphicStrings.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.HashMap; diff --git a/src/main/java/string/KeyboardRow.java b/src/main/java/string/KeyboardRow.java index f91ff886..ab25ecfe 100644 --- a/src/main/java/string/KeyboardRow.java +++ b/src/main/java/string/KeyboardRow.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** * Created by gouthamvidyapradhan on 09/04/2019 diff --git a/src/main/java/string/LongestCommonPrefix.java b/src/main/java/string/LongestCommonPrefix.java index 4d220ccf..f6ec92c0 100644 --- a/src/main/java/string/LongestCommonPrefix.java +++ b/src/main/java/string/LongestCommonPrefix.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/LongestPalindrome.java b/src/main/java/string/LongestPalindrome.java index 9c6f69bf..5e90a731 100644 --- a/src/main/java/string/LongestPalindrome.java +++ b/src/main/java/string/LongestPalindrome.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** * Created by gouthamvidyapradhan on 20/03/2019 Given a string which consists of lowercase or diff --git a/src/main/java/string/LongestWordInDictonary.java b/src/main/java/string/LongestWordInDictonary.java index 85968ef0..e0ab0776 100644 --- a/src/main/java/string/LongestWordInDictonary.java +++ b/src/main/java/string/LongestWordInDictonary.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.*; diff --git a/src/main/java/string/MinimumAddtoMakeParenthesesValid.java b/src/main/java/string/MinimumAddtoMakeParenthesesValid.java index ba5c8226..eaa5cb7b 100644 --- a/src/main/java/string/MinimumAddtoMakeParenthesesValid.java +++ b/src/main/java/string/MinimumAddtoMakeParenthesesValid.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/MonotoneIncreasingDigits.java b/src/main/java/string/MonotoneIncreasingDigits.java index e354b7a1..238ba12f 100644 --- a/src/main/java/string/MonotoneIncreasingDigits.java +++ b/src/main/java/string/MonotoneIncreasingDigits.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/MultiplyStrings.java b/src/main/java/string/MultiplyStrings.java index 5d98ddc7..cce90724 100644 --- a/src/main/java/string/MultiplyStrings.java +++ b/src/main/java/string/MultiplyStrings.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/NumberOfMatchingSubsequences.java b/src/main/java/string/NumberOfMatchingSubsequences.java index 1fb85193..a873117b 100644 --- a/src/main/java/string/NumberOfMatchingSubsequences.java +++ b/src/main/java/string/NumberOfMatchingSubsequences.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/OneEditDistance.java b/src/main/java/string/OneEditDistance.java index b06af63e..657391c4 100644 --- a/src/main/java/string/OneEditDistance.java +++ b/src/main/java/string/OneEditDistance.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/PermutationInString.java b/src/main/java/string/PermutationInString.java index 3a908c28..b9998019 100644 --- a/src/main/java/string/PermutationInString.java +++ b/src/main/java/string/PermutationInString.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/PushDominoes.java b/src/main/java/string/PushDominoes.java index 83b8a0cc..2514d9ae 100644 --- a/src/main/java/string/PushDominoes.java +++ b/src/main/java/string/PushDominoes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/ReconstructOriginalDigitsFromEnglish.java b/src/main/java/string/ReconstructOriginalDigitsFromEnglish.java index 619ef629..92efa05d 100644 --- a/src/main/java/string/ReconstructOriginalDigitsFromEnglish.java +++ b/src/main/java/string/ReconstructOriginalDigitsFromEnglish.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.*; diff --git a/src/main/java/string/RepeatedSubstringPattern.java b/src/main/java/string/RepeatedSubstringPattern.java index 2479e6bc..c0a31d9e 100644 --- a/src/main/java/string/RepeatedSubstringPattern.java +++ b/src/main/java/string/RepeatedSubstringPattern.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/ReplaceWords.java b/src/main/java/string/ReplaceWords.java index 7c2dede5..b85be6ba 100644 --- a/src/main/java/string/ReplaceWords.java +++ b/src/main/java/string/ReplaceWords.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.Arrays; diff --git a/src/main/java/string/ReverseStringII.java b/src/main/java/string/ReverseStringII.java index 58fb777b..7550f99e 100644 --- a/src/main/java/string/ReverseStringII.java +++ b/src/main/java/string/ReverseStringII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/ReverseWordsII.java b/src/main/java/string/ReverseWordsII.java index 7aa9f9c0..ba001240 100644 --- a/src/main/java/string/ReverseWordsII.java +++ b/src/main/java/string/ReverseWordsII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/ReverseWordsInAString.java b/src/main/java/string/ReverseWordsInAString.java index e930ab84..6e71c8c2 100644 --- a/src/main/java/string/ReverseWordsInAString.java +++ b/src/main/java/string/ReverseWordsInAString.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.ArrayList; diff --git a/src/main/java/string/RotateString.java b/src/main/java/string/RotateString.java index 02978688..548bb2fe 100644 --- a/src/main/java/string/RotateString.java +++ b/src/main/java/string/RotateString.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/ShortestPalindrome.java b/src/main/java/string/ShortestPalindrome.java index 66df78de..ef68c011 100644 --- a/src/main/java/string/ShortestPalindrome.java +++ b/src/main/java/string/ShortestPalindrome.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/SimplifyPath.java b/src/main/java/string/SimplifyPath.java index e500171f..0f4ab3bc 100644 --- a/src/main/java/string/SimplifyPath.java +++ b/src/main/java/string/SimplifyPath.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.ArrayDeque; diff --git a/src/main/java/string/SplitConcatenatedStrings.java b/src/main/java/string/SplitConcatenatedStrings.java index eb6b8204..139605c1 100644 --- a/src/main/java/string/SplitConcatenatedStrings.java +++ b/src/main/java/string/SplitConcatenatedStrings.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/StampingTheSequence.java b/src/main/java/string/StampingTheSequence.java index 77efffd5..1ba7694d 100644 --- a/src/main/java/string/StampingTheSequence.java +++ b/src/main/java/string/StampingTheSequence.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.*; diff --git a/src/main/java/string/StringCompression.java b/src/main/java/string/StringCompression.java index 160afa09..5c2144aa 100644 --- a/src/main/java/string/StringCompression.java +++ b/src/main/java/string/StringCompression.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/StringToInteger.java b/src/main/java/string/StringToInteger.java index da4e8235..fb5df48f 100644 --- a/src/main/java/string/StringToInteger.java +++ b/src/main/java/string/StringToInteger.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/StudentAttendanceRecordI.java b/src/main/java/string/StudentAttendanceRecordI.java index 49fddc42..da553682 100644 --- a/src/main/java/string/StudentAttendanceRecordI.java +++ b/src/main/java/string/StudentAttendanceRecordI.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/TextJustification.java b/src/main/java/string/TextJustification.java index e17b5b13..a8cb70c9 100644 --- a/src/main/java/string/TextJustification.java +++ b/src/main/java/string/TextJustification.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.ArrayList; diff --git a/src/main/java/string/ValidPalindrome.java b/src/main/java/string/ValidPalindrome.java index 7295d3cd..384ec3ac 100644 --- a/src/main/java/string/ValidPalindrome.java +++ b/src/main/java/string/ValidPalindrome.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/ValidPalindromeII.java b/src/main/java/string/ValidPalindromeII.java index 2cc37d09..37114591 100644 --- a/src/main/java/string/ValidPalindromeII.java +++ b/src/main/java/string/ValidPalindromeII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/ValidWordAbbreviation.java b/src/main/java/string/ValidWordAbbreviation.java index bf5dfbae..5630c91b 100644 --- a/src/main/java/string/ValidWordAbbreviation.java +++ b/src/main/java/string/ValidWordAbbreviation.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** * Created by gouthamvidyapradhan on 20/03/2019 Given a non-empty string s and an abbreviation abbr, diff --git a/src/main/java/string/ValidWordSquare.java b/src/main/java/string/ValidWordSquare.java index 2205bd19..6b5a8f3e 100644 --- a/src/main/java/string/ValidWordSquare.java +++ b/src/main/java/string/ValidWordSquare.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.*; diff --git a/src/main/java/string/ValidateIPAddress.java b/src/main/java/string/ValidateIPAddress.java index 3f96d5ce..a1df8914 100644 --- a/src/main/java/string/ValidateIPAddress.java +++ b/src/main/java/string/ValidateIPAddress.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/ZigZagConversion.java b/src/main/java/string/ZigZagConversion.java index 5867fba1..182e0015 100644 --- a/src/main/java/string/ZigZagConversion.java +++ b/src/main/java/string/ZigZagConversion.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.ArrayList; diff --git a/src/main/java/tree/AllNodesDistanceKInBinaryTree.java b/src/main/java/tree/AllNodesDistanceKInBinaryTree.java index e65c19f0..aba385bb 100644 --- a/src/main/java/tree/AllNodesDistanceKInBinaryTree.java +++ b/src/main/java/tree/AllNodesDistanceKInBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.*; diff --git a/src/main/java/tree/AllPossibleFullBinaryTrees.java b/src/main/java/tree/AllPossibleFullBinaryTrees.java index fc66fafa..0925a91c 100644 --- a/src/main/java/tree/AllPossibleFullBinaryTrees.java +++ b/src/main/java/tree/AllPossibleFullBinaryTrees.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.*; diff --git a/src/main/java/tree/AverageOfLevelsInBinaryTree.java b/src/main/java/tree/AverageOfLevelsInBinaryTree.java index aba33987..d136b3ed 100644 --- a/src/main/java/tree/AverageOfLevelsInBinaryTree.java +++ b/src/main/java/tree/AverageOfLevelsInBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.ArrayDeque; diff --git a/src/main/java/tree/BSTtoDoublyLinkedList.java b/src/main/java/tree/BSTtoDoublyLinkedList.java index 3e450d61..087bd4dc 100644 --- a/src/main/java/tree/BSTtoDoublyLinkedList.java +++ b/src/main/java/tree/BSTtoDoublyLinkedList.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/BinarayTreeRightSideView.java b/src/main/java/tree/BinarayTreeRightSideView.java index 9e29e495..360ade9e 100644 --- a/src/main/java/tree/BinarayTreeRightSideView.java +++ b/src/main/java/tree/BinarayTreeRightSideView.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.ArrayList; diff --git a/src/main/java/tree/BinaryTreeInorderTraversal.java b/src/main/java/tree/BinaryTreeInorderTraversal.java index b52a1cfb..31c4d8a5 100644 --- a/src/main/java/tree/BinaryTreeInorderTraversal.java +++ b/src/main/java/tree/BinaryTreeInorderTraversal.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.ArrayList; diff --git a/src/main/java/tree/BinaryTreeLongestConsecutiveSequenceII.java b/src/main/java/tree/BinaryTreeLongestConsecutiveSequenceII.java index ab4b3146..3505a092 100644 --- a/src/main/java/tree/BinaryTreeLongestConsecutiveSequenceII.java +++ b/src/main/java/tree/BinaryTreeLongestConsecutiveSequenceII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/BinaryTreeMaximumPathSum.java b/src/main/java/tree/BinaryTreeMaximumPathSum.java index 8ab9ad11..44e80fb0 100644 --- a/src/main/java/tree/BinaryTreeMaximumPathSum.java +++ b/src/main/java/tree/BinaryTreeMaximumPathSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/BinaryTreePaths.java b/src/main/java/tree/BinaryTreePaths.java index 35a098d9..e15fabd1 100644 --- a/src/main/java/tree/BinaryTreePaths.java +++ b/src/main/java/tree/BinaryTreePaths.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.ArrayList; diff --git a/src/main/java/tree/BinaryTreePostorderTraversal.java b/src/main/java/tree/BinaryTreePostorderTraversal.java index 6a5d369d..53c465e7 100644 --- a/src/main/java/tree/BinaryTreePostorderTraversal.java +++ b/src/main/java/tree/BinaryTreePostorderTraversal.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.*; diff --git a/src/main/java/tree/BinaryTreeTilt.java b/src/main/java/tree/BinaryTreeTilt.java index 76deb62e..21feebec 100644 --- a/src/main/java/tree/BinaryTreeTilt.java +++ b/src/main/java/tree/BinaryTreeTilt.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** * Created by gouthamvidyapradhan on 14/08/2019 Given a binary tree, return the tilt of the whole diff --git a/src/main/java/tree/BoundaryOfBinaryTree.java b/src/main/java/tree/BoundaryOfBinaryTree.java index 2dd6260a..708e86e7 100644 --- a/src/main/java/tree/BoundaryOfBinaryTree.java +++ b/src/main/java/tree/BoundaryOfBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.*; diff --git a/src/main/java/tree/ClosestBinarySearchTreeValue.java b/src/main/java/tree/ClosestBinarySearchTreeValue.java index 4d2cd451..843ec3eb 100644 --- a/src/main/java/tree/ClosestBinarySearchTreeValue.java +++ b/src/main/java/tree/ClosestBinarySearchTreeValue.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/ClosestLeafInABinaryTree.java b/src/main/java/tree/ClosestLeafInABinaryTree.java index e08b5e8a..7afc7ba4 100644 --- a/src/main/java/tree/ClosestLeafInABinaryTree.java +++ b/src/main/java/tree/ClosestLeafInABinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.*; diff --git a/src/main/java/tree/ConstructBinaryTreefromString.java b/src/main/java/tree/ConstructBinaryTreefromString.java index 78bce3e1..a73aae56 100644 --- a/src/main/java/tree/ConstructBinaryTreefromString.java +++ b/src/main/java/tree/ConstructBinaryTreefromString.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/ConstructStringFromBinaryTree.java b/src/main/java/tree/ConstructStringFromBinaryTree.java index 7c63b612..28138cbf 100644 --- a/src/main/java/tree/ConstructStringFromBinaryTree.java +++ b/src/main/java/tree/ConstructStringFromBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/ConvertBSTToGreaterTree.java b/src/main/java/tree/ConvertBSTToGreaterTree.java index ff3b0a4f..2c84753f 100644 --- a/src/main/java/tree/ConvertBSTToGreaterTree.java +++ b/src/main/java/tree/ConvertBSTToGreaterTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/ConvertSortedArrayToBST.java b/src/main/java/tree/ConvertSortedArrayToBST.java index c2033157..60317bea 100644 --- a/src/main/java/tree/ConvertSortedArrayToBST.java +++ b/src/main/java/tree/ConvertSortedArrayToBST.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/DiameterOfBinaryTree.java b/src/main/java/tree/DiameterOfBinaryTree.java index 3f0954d3..0d41b272 100644 --- a/src/main/java/tree/DiameterOfBinaryTree.java +++ b/src/main/java/tree/DiameterOfBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/EqualTreePartition.java b/src/main/java/tree/EqualTreePartition.java index c4c44535..c90a1280 100644 --- a/src/main/java/tree/EqualTreePartition.java +++ b/src/main/java/tree/EqualTreePartition.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/FindBottomLeftTreeValue.java b/src/main/java/tree/FindBottomLeftTreeValue.java index cc9fe291..86ee8a57 100644 --- a/src/main/java/tree/FindBottomLeftTreeValue.java +++ b/src/main/java/tree/FindBottomLeftTreeValue.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/FindLargestValueInEachTreeRow.java b/src/main/java/tree/FindLargestValueInEachTreeRow.java index 27717430..a54e869b 100644 --- a/src/main/java/tree/FindLargestValueInEachTreeRow.java +++ b/src/main/java/tree/FindLargestValueInEachTreeRow.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.*; diff --git a/src/main/java/tree/FlattenBinaryTree.java b/src/main/java/tree/FlattenBinaryTree.java index dfcaad3c..274e45fd 100644 --- a/src/main/java/tree/FlattenBinaryTree.java +++ b/src/main/java/tree/FlattenBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/FlipBinaryTree.java b/src/main/java/tree/FlipBinaryTree.java index 31445be5..b1e0e41a 100644 --- a/src/main/java/tree/FlipBinaryTree.java +++ b/src/main/java/tree/FlipBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.*; diff --git a/src/main/java/tree/FlipEquivalentBinaryTrees.java b/src/main/java/tree/FlipEquivalentBinaryTrees.java index 00a476c8..03c3d6f4 100644 --- a/src/main/java/tree/FlipEquivalentBinaryTrees.java +++ b/src/main/java/tree/FlipEquivalentBinaryTrees.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/InorderSuccessorInBST.java b/src/main/java/tree/InorderSuccessorInBST.java index 3150230e..6d25ae6f 100644 --- a/src/main/java/tree/InorderSuccessorInBST.java +++ b/src/main/java/tree/InorderSuccessorInBST.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/InsufficientNodesinRoottoLeafPaths.java b/src/main/java/tree/InsufficientNodesinRoottoLeafPaths.java index 5660ac3e..da5338fd 100644 --- a/src/main/java/tree/InsufficientNodesinRoottoLeafPaths.java +++ b/src/main/java/tree/InsufficientNodesinRoottoLeafPaths.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** Created by gouthamvidyapradhan on 29/01/2020 */ diff --git a/src/main/java/tree/LCA.java b/src/main/java/tree/LCA.java index ccd284d4..0d9f52ee 100644 --- a/src/main/java/tree/LCA.java +++ b/src/main/java/tree/LCA.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/LargestBSTSubtree.java b/src/main/java/tree/LargestBSTSubtree.java index 4b58398b..04d7edaa 100644 --- a/src/main/java/tree/LargestBSTSubtree.java +++ b/src/main/java/tree/LargestBSTSubtree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/LeafSimilarTrees.java b/src/main/java/tree/LeafSimilarTrees.java index 3250d606..d5247e5e 100644 --- a/src/main/java/tree/LeafSimilarTrees.java +++ b/src/main/java/tree/LeafSimilarTrees.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.*; diff --git a/src/main/java/tree/LowestCommonAncestorBST.java b/src/main/java/tree/LowestCommonAncestorBST.java index 80591d92..48df25f1 100644 --- a/src/main/java/tree/LowestCommonAncestorBST.java +++ b/src/main/java/tree/LowestCommonAncestorBST.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/MaximumBinaryTree.java b/src/main/java/tree/MaximumBinaryTree.java index d8b47275..f23823aa 100644 --- a/src/main/java/tree/MaximumBinaryTree.java +++ b/src/main/java/tree/MaximumBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/MaximumLevelSumofABinaryTree.java b/src/main/java/tree/MaximumLevelSumofABinaryTree.java index cde5e02b..6e0b7763 100644 --- a/src/main/java/tree/MaximumLevelSumofABinaryTree.java +++ b/src/main/java/tree/MaximumLevelSumofABinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.*; diff --git a/src/main/java/tree/MaximumWidthOfBinaryTree.java b/src/main/java/tree/MaximumWidthOfBinaryTree.java index 9536e1d2..6b419e8c 100644 --- a/src/main/java/tree/MaximumWidthOfBinaryTree.java +++ b/src/main/java/tree/MaximumWidthOfBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.ArrayList; diff --git a/src/main/java/tree/MinimumAbsoluteDifferenceInBST.java b/src/main/java/tree/MinimumAbsoluteDifferenceInBST.java index 7be241e4..a3b3d40a 100644 --- a/src/main/java/tree/MinimumAbsoluteDifferenceInBST.java +++ b/src/main/java/tree/MinimumAbsoluteDifferenceInBST.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/MostFrequentSubtreeSum.java b/src/main/java/tree/MostFrequentSubtreeSum.java index 1f0a0261..e801de74 100644 --- a/src/main/java/tree/MostFrequentSubtreeSum.java +++ b/src/main/java/tree/MostFrequentSubtreeSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.ArrayList; diff --git a/src/main/java/tree/NextRightPointer.java b/src/main/java/tree/NextRightPointer.java index f082e2ad..a49b5f7b 100644 --- a/src/main/java/tree/NextRightPointer.java +++ b/src/main/java/tree/NextRightPointer.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.ArrayDeque; diff --git a/src/main/java/tree/NextRightPointerII.java b/src/main/java/tree/NextRightPointerII.java index 644e5536..a70faea4 100644 --- a/src/main/java/tree/NextRightPointerII.java +++ b/src/main/java/tree/NextRightPointerII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/PathSumIII.java b/src/main/java/tree/PathSumIII.java index cb911281..bac60064 100644 --- a/src/main/java/tree/PathSumIII.java +++ b/src/main/java/tree/PathSumIII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.HashMap; diff --git a/src/main/java/tree/PostorderToBT.java b/src/main/java/tree/PostorderToBT.java index 3ca60f7f..655a528f 100644 --- a/src/main/java/tree/PostorderToBT.java +++ b/src/main/java/tree/PostorderToBT.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.HashMap; diff --git a/src/main/java/tree/PreorderToBT.java b/src/main/java/tree/PreorderToBT.java index 06729549..23958b59 100644 --- a/src/main/java/tree/PreorderToBT.java +++ b/src/main/java/tree/PreorderToBT.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.HashMap; diff --git a/src/main/java/tree/RecoverBinarySearchTree.java b/src/main/java/tree/RecoverBinarySearchTree.java index d2b0d907..e18c7f91 100644 --- a/src/main/java/tree/RecoverBinarySearchTree.java +++ b/src/main/java/tree/RecoverBinarySearchTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/SameTree.java b/src/main/java/tree/SameTree.java index ca8b2c16..69bf6a81 100644 --- a/src/main/java/tree/SameTree.java +++ b/src/main/java/tree/SameTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/SerializeAndDeserializeNAryTree.java b/src/main/java/tree/SerializeAndDeserializeNAryTree.java index 03487353..a525061a 100644 --- a/src/main/java/tree/SerializeAndDeserializeNAryTree.java +++ b/src/main/java/tree/SerializeAndDeserializeNAryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.*; diff --git a/src/main/java/tree/SortedArrayToBST.java b/src/main/java/tree/SortedArrayToBST.java index e445c34c..dcb3d57f 100644 --- a/src/main/java/tree/SortedArrayToBST.java +++ b/src/main/java/tree/SortedArrayToBST.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/SplitBST.java b/src/main/java/tree/SplitBST.java index 19f74cd4..741c68c6 100644 --- a/src/main/java/tree/SplitBST.java +++ b/src/main/java/tree/SplitBST.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/SubtreeOfAnotherTree.java b/src/main/java/tree/SubtreeOfAnotherTree.java index eef75737..026ba64b 100644 --- a/src/main/java/tree/SubtreeOfAnotherTree.java +++ b/src/main/java/tree/SubtreeOfAnotherTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/SumofLeftLeaves.java b/src/main/java/tree/SumofLeftLeaves.java index 9c5391fd..7d6bf15d 100644 --- a/src/main/java/tree/SumofLeftLeaves.java +++ b/src/main/java/tree/SumofLeftLeaves.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/SymmetricTree.java b/src/main/java/tree/SymmetricTree.java index cfda674a..f167a51e 100644 --- a/src/main/java/tree/SymmetricTree.java +++ b/src/main/java/tree/SymmetricTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/TwoSumIV.java b/src/main/java/tree/TwoSumIV.java index ddac36cf..9e32e2a5 100644 --- a/src/main/java/tree/TwoSumIV.java +++ b/src/main/java/tree/TwoSumIV.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.HashSet; diff --git a/src/main/java/tree/ValidBinarySearchTree.java b/src/main/java/tree/ValidBinarySearchTree.java index 87d36ab1..bb0fbb18 100644 --- a/src/main/java/tree/ValidBinarySearchTree.java +++ b/src/main/java/tree/ValidBinarySearchTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/ZigZagTraversal.java b/src/main/java/tree/ZigZagTraversal.java index 1b114e16..5236a18c 100644 --- a/src/main/java/tree/ZigZagTraversal.java +++ b/src/main/java/tree/ZigZagTraversal.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.ArrayList; diff --git a/src/main/java/two_pointers/FourSum.java b/src/main/java/two_pointers/FourSum.java index 95896184..0eeb74d8 100644 --- a/src/main/java/two_pointers/FourSum.java +++ b/src/main/java/two_pointers/FourSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; import java.util.ArrayList; diff --git a/src/main/java/two_pointers/LastSubstringInLexicographicalOrder.java b/src/main/java/two_pointers/LastSubstringInLexicographicalOrder.java index fb688ff4..4b9195c2 100644 --- a/src/main/java/two_pointers/LastSubstringInLexicographicalOrder.java +++ b/src/main/java/two_pointers/LastSubstringInLexicographicalOrder.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** * Created by gouthamvidyapradhan on 30/08/2019 Given a string s, return the last substring of s in diff --git a/src/main/java/two_pointers/LongestSubstringWitoutRepeats.java b/src/main/java/two_pointers/LongestSubstringWitoutRepeats.java index 5ca40efd..85b80c54 100644 --- a/src/main/java/two_pointers/LongestSubstringWitoutRepeats.java +++ b/src/main/java/two_pointers/LongestSubstringWitoutRepeats.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; import java.util.HashMap; diff --git a/src/main/java/two_pointers/MinimumSizeSubarraySum.java b/src/main/java/two_pointers/MinimumSizeSubarraySum.java index ac983997..0800c502 100644 --- a/src/main/java/two_pointers/MinimumSizeSubarraySum.java +++ b/src/main/java/two_pointers/MinimumSizeSubarraySum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** diff --git a/src/main/java/two_pointers/MinimumWindowSubstring.java b/src/main/java/two_pointers/MinimumWindowSubstring.java index 79f2bfd3..fa1f641d 100644 --- a/src/main/java/two_pointers/MinimumWindowSubstring.java +++ b/src/main/java/two_pointers/MinimumWindowSubstring.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** diff --git a/src/main/java/two_pointers/MoveZeroes.java b/src/main/java/two_pointers/MoveZeroes.java index c3ec945f..460f09df 100644 --- a/src/main/java/two_pointers/MoveZeroes.java +++ b/src/main/java/two_pointers/MoveZeroes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** diff --git a/src/main/java/two_pointers/NumberOfMatchingSubsequences.java b/src/main/java/two_pointers/NumberOfMatchingSubsequences.java index d41408ed..6eca1354 100644 --- a/src/main/java/two_pointers/NumberOfMatchingSubsequences.java +++ b/src/main/java/two_pointers/NumberOfMatchingSubsequences.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** diff --git a/src/main/java/two_pointers/RemoveDuplicates.java b/src/main/java/two_pointers/RemoveDuplicates.java index 34fb1352..749db9a4 100644 --- a/src/main/java/two_pointers/RemoveDuplicates.java +++ b/src/main/java/two_pointers/RemoveDuplicates.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** diff --git a/src/main/java/two_pointers/RemoveDuplicatesII.java b/src/main/java/two_pointers/RemoveDuplicatesII.java index e2c302d6..db90a4ab 100644 --- a/src/main/java/two_pointers/RemoveDuplicatesII.java +++ b/src/main/java/two_pointers/RemoveDuplicatesII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** diff --git a/src/main/java/two_pointers/SmallestRange.java b/src/main/java/two_pointers/SmallestRange.java index 90152485..73e4cb4c 100644 --- a/src/main/java/two_pointers/SmallestRange.java +++ b/src/main/java/two_pointers/SmallestRange.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; import java.util.ArrayList; diff --git a/src/main/java/two_pointers/SubarrayProductLessThanK.java b/src/main/java/two_pointers/SubarrayProductLessThanK.java index 75ccbba9..5d255e71 100644 --- a/src/main/java/two_pointers/SubarrayProductLessThanK.java +++ b/src/main/java/two_pointers/SubarrayProductLessThanK.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** * Created by gouthamvidyapradhan on 17/02/2018. Your are given an array of positive integers nums. diff --git a/src/main/java/two_pointers/SubarraysWithKDifferentIntegers.java b/src/main/java/two_pointers/SubarraysWithKDifferentIntegers.java index ef1357e2..9728d4fd 100644 --- a/src/main/java/two_pointers/SubarraysWithKDifferentIntegers.java +++ b/src/main/java/two_pointers/SubarraysWithKDifferentIntegers.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** * Created by gouthamvidyapradhan on 25/07/2019 Given an array A of positive integers, call a diff --git a/src/main/java/two_pointers/ThreeSum.java b/src/main/java/two_pointers/ThreeSum.java index 42ab17e0..5f928fd9 100644 --- a/src/main/java/two_pointers/ThreeSum.java +++ b/src/main/java/two_pointers/ThreeSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; import java.util.ArrayList; diff --git a/src/main/java/two_pointers/ThreeSumClosest.java b/src/main/java/two_pointers/ThreeSumClosest.java index 97329084..98f9118c 100644 --- a/src/main/java/two_pointers/ThreeSumClosest.java +++ b/src/main/java/two_pointers/ThreeSumClosest.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; import java.util.Arrays; diff --git a/src/main/java/two_pointers/TrappingRainWater.java b/src/main/java/two_pointers/TrappingRainWater.java index cf8d3f06..a2462374 100644 --- a/src/main/java/two_pointers/TrappingRainWater.java +++ b/src/main/java/two_pointers/TrappingRainWater.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** From d10c6bca478a38ac71ed32ee73e62fa5bafd64db Mon Sep 17 00:00:00 2001 From: Goutham Vidya Pradhan Date: Thu, 19 Dec 2024 13:17:15 +0100 Subject: [PATCH 235/235] Update README.md Added youtube channel --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 0a7c2afb..50b25b37 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,9 @@ My accepted leetcode solutions to some of the common interview problems. Also, some solutions have youtube video link. +[Youtube channel](https://www.youtube.com/@codernaut) + + #### [Array](src/main/java/array) - [Pascals Traiangle II](src/main/java/array/PascalsTriangle.java) (Easy)