From 0172c299c7cb3394ff8700c71c2cc00d24451994 Mon Sep 17 00:00:00 2001 From: Azad Date: Wed, 4 Nov 2020 16:28:51 +0530 Subject: [PATCH 1/9] Added New Java file in Java/Misc --- Misc/largestRange.java | 46 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 Misc/largestRange.java diff --git a/Misc/largestRange.java b/Misc/largestRange.java new file mode 100644 index 000000000000..fd61c38446d2 --- /dev/null +++ b/Misc/largestRange.java @@ -0,0 +1,46 @@ +import java.util.*; +public class largestRange +{ + // Finds the length of longest occurring consecutive numbers range in an array + public static int longestRange(int[] nums) + { + int longestRange = 0; + HashMap num = new HashMap<>(); // Stores a mapping of a number to whether the current number is part of a particular consecutive range or not + for(int x : nums) + num.put(x, true); + for(int x : nums) + { + if(!num.get(x)) + continue; + num.replace(x, false); + int currentRange=1; + int left = x - 1; + int right = x + 1; + while(num.containsKey(left)) // Search leftwards for consecutive range + { + num.replace(left, false); + currentRange+=1; + left--; + } + while(num.containsKey(right)) // Search rightwards for consecutive range + { + num.replace(right, false); + currentRange+=1; + right++; + } + if(currentRange > longestRange) // Store longest range at every interation + longestRange = currentRange; + } + return longestRange; + } + + public static void main(String[] args) { + // Testcases + assert longestRange(new int[]{1, 2, 3, 4, -1, 11, 10}) == 4; + // The longest consecutive number range is of length 4 i.e. {1, 2, 3, 4} + assert longestRange(new int[]{-1, 1, 3, 5, 7})==1; + // The longest consecutive number range is of length 1 i.e. any of the element alone + assert longestRange(new int[]{0, 1, 2, 3, 4, 7, 6, 5})==8; + // The longest consecutive number range is of length 8 i.e. {0, 1, 2, 3, 4, 5, 6, 7} + } +} From ee34da41ed97b131f9356260370107fd6aba3d96 Mon Sep 17 00:00:00 2001 From: Azad Nautiyal Date: Wed, 4 Nov 2020 16:38:42 +0530 Subject: [PATCH 2/9] Update largestRange.java --- Misc/largestRange.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/largestRange.java b/Misc/largestRange.java index fd61c38446d2..6877a0a600aa 100644 --- a/Misc/largestRange.java +++ b/Misc/largestRange.java @@ -1,3 +1,4 @@ +package Misc; import java.util.*; public class largestRange { From 4bee137ea6f5318f95c71b06c343a59f9309717c Mon Sep 17 00:00:00 2001 From: Azad Nautiyal Date: Wed, 4 Nov 2020 16:40:53 +0530 Subject: [PATCH 3/9] Update largestRange.java --- Misc/largestRange.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/largestRange.java b/Misc/largestRange.java index 6877a0a600aa..7dc300450834 100644 --- a/Misc/largestRange.java +++ b/Misc/largestRange.java @@ -1,4 +1,5 @@ package Misc; + import java.util.*; public class largestRange { From 603e0100e177be498bedad122498b1e69d1d7805 Mon Sep 17 00:00:00 2001 From: Azad Nautiyal Date: Wed, 4 Nov 2020 18:24:12 +0530 Subject: [PATCH 4/9] Update largestRange.java --- Misc/largestRange.java | 84 +++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/Misc/largestRange.java b/Misc/largestRange.java index 7dc300450834..3b6a7f48ff7c 100644 --- a/Misc/largestRange.java +++ b/Misc/largestRange.java @@ -1,48 +1,48 @@ package Misc; import java.util.*; -public class largestRange -{ - // Finds the length of longest occurring consecutive numbers range in an array - public static int longestRange(int[] nums) - { - int longestRange = 0; - HashMap num = new HashMap<>(); // Stores a mapping of a number to whether the current number is part of a particular consecutive range or not - for(int x : nums) - num.put(x, true); - for(int x : nums) - { - if(!num.get(x)) - continue; - num.replace(x, false); - int currentRange=1; - int left = x - 1; - int right = x + 1; - while(num.containsKey(left)) // Search leftwards for consecutive range - { - num.replace(left, false); - currentRange+=1; - left--; - } - while(num.containsKey(right)) // Search rightwards for consecutive range - { - num.replace(right, false); - currentRange+=1; - right++; - } - if(currentRange > longestRange) // Store longest range at every interation - longestRange = currentRange; - } - return longestRange; - } - public static void main(String[] args) { - // Testcases - assert longestRange(new int[]{1, 2, 3, 4, -1, 11, 10}) == 4; - // The longest consecutive number range is of length 4 i.e. {1, 2, 3, 4} - assert longestRange(new int[]{-1, 1, 3, 5, 7})==1; - // The longest consecutive number range is of length 1 i.e. any of the element alone - assert longestRange(new int[]{0, 1, 2, 3, 4, 7, 6, 5})==8; - // The longest consecutive number range is of length 8 i.e. {0, 1, 2, 3, 4, 5, 6, 7} +public class largestRange { + + // Finds the length of longest occurring consecutive numbers range in an array + public static int longestRange(int[] nums) { + int longestRange = 0; + HashMap num = new HashMap<>(); + + /** + * Stores a mapping of a number to whether the current number is part of a particular + * consecutive range or not. + */ + for (int x : nums) num.put(x, true); + for (int x : nums) { + if (!num.get(x)) continue; + num.replace(x, false); + int currentRange = 1; + int left = x - 1; + int right = x + 1; + while (num.containsKey(left)) { // Search leftwards for consecutive range + num.replace(left, false); + currentRange += 1; + left--; + } + while (num.containsKey(right)) { // Search rightwards for consecutive range + num.replace(right, false); + currentRange += 1; + right++; + } + if (currentRange > longestRange) + longestRange = currentRange; // Store longest range at every interation } + return longestRange; + } + + public static void main(String[] args) { + // Testcases + assert longestRange(new int[] {1, 2, 3, 4, -1, 11, 10}) == 4; + // The longest consecutive number range is of length 4 i.e. {1, 2, 3, 4} + assert longestRange(new int[] {-1, 1, 3, 5, 7}) == 1; + // The longest consecutive number range is of length 1 i.e. any of the element alone + assert longestRange(new int[] {0, 1, 2, 3, 4, 7, 6, 5}) == 8; + // The longest consecutive number range is of length 8 i.e. {0, 1, 2, 3, 4, 5, 6, 7} + } } From a6f88cd038fac7b41a28d8302c87e20f10280516 Mon Sep 17 00:00:00 2001 From: Azad Nautiyal Date: Wed, 4 Nov 2020 18:27:45 +0530 Subject: [PATCH 5/9] Update largestRange.java --- Misc/largestRange.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/Misc/largestRange.java b/Misc/largestRange.java index 3b6a7f48ff7c..f24e5e2438a8 100644 --- a/Misc/largestRange.java +++ b/Misc/largestRange.java @@ -1,5 +1,3 @@ -package Misc; - import java.util.*; public class largestRange { From 9e1c9637a5a68e54a6cab7fac70d7b0074491066 Mon Sep 17 00:00:00 2001 From: Azad Nautiyal Date: Wed, 4 Nov 2020 20:25:54 +0530 Subject: [PATCH 6/9] Revert "Largest range" --- Misc/largestRange.java | 46 ------------------------------------------ 1 file changed, 46 deletions(-) delete mode 100644 Misc/largestRange.java diff --git a/Misc/largestRange.java b/Misc/largestRange.java deleted file mode 100644 index f24e5e2438a8..000000000000 --- a/Misc/largestRange.java +++ /dev/null @@ -1,46 +0,0 @@ -import java.util.*; - -public class largestRange { - - // Finds the length of longest occurring consecutive numbers range in an array - public static int longestRange(int[] nums) { - int longestRange = 0; - HashMap num = new HashMap<>(); - - /** - * Stores a mapping of a number to whether the current number is part of a particular - * consecutive range or not. - */ - for (int x : nums) num.put(x, true); - for (int x : nums) { - if (!num.get(x)) continue; - num.replace(x, false); - int currentRange = 1; - int left = x - 1; - int right = x + 1; - while (num.containsKey(left)) { // Search leftwards for consecutive range - num.replace(left, false); - currentRange += 1; - left--; - } - while (num.containsKey(right)) { // Search rightwards for consecutive range - num.replace(right, false); - currentRange += 1; - right++; - } - if (currentRange > longestRange) - longestRange = currentRange; // Store longest range at every interation - } - return longestRange; - } - - public static void main(String[] args) { - // Testcases - assert longestRange(new int[] {1, 2, 3, 4, -1, 11, 10}) == 4; - // The longest consecutive number range is of length 4 i.e. {1, 2, 3, 4} - assert longestRange(new int[] {-1, 1, 3, 5, 7}) == 1; - // The longest consecutive number range is of length 1 i.e. any of the element alone - assert longestRange(new int[] {0, 1, 2, 3, 4, 7, 6, 5}) == 8; - // The longest consecutive number range is of length 8 i.e. {0, 1, 2, 3, 4, 5, 6, 7} - } -} From a382936636b8de56d0ad32d5a4a3da3c8d96e942 Mon Sep 17 00:00:00 2001 From: Azad Date: Wed, 4 Nov 2020 20:57:18 +0530 Subject: [PATCH 7/9] Added WordBoggle.java --- Misc/WordBoggle.java | 130 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 Misc/WordBoggle.java diff --git a/Misc/WordBoggle.java b/Misc/WordBoggle.java new file mode 100644 index 000000000000..ea3f44ada29a --- /dev/null +++ b/Misc/WordBoggle.java @@ -0,0 +1,130 @@ +import java.util.*; + +public class wordBoggle { + + /** + * O(nm * 8^s + ws) time where n=width of boggle board, m=height of boggle board, s=length of + * longest word in string array, w= length of string array, 8 is due to 8 explorable neighbours + * O(nm + ws) space. + */ + public static List boggleBoard(char[][] board, String[] words) { + Trie trie = new Trie(); + for (String word : words) trie.add(word); + Set finalWords = new HashSet<>(); + boolean[][] visited = new boolean[board.length][board.length]; + for (int i = 0; i < board.length; i++) + for (int j = 0; j < board[i].length; j++) + explore(i, j, board, trie.root, visited, finalWords); + return new ArrayList<>(finalWords); + } + + public static void main(String[] args) { + // Testcase + List ans = + new ArrayList<>( + Arrays.asList("a", "boggle", "this", "NOTRE_PEATED", "is", "simple", "board")); + assert (boggleBoard( + new char[][] { + {'t', 'h', 'i', 's', 'i', 's', 'a'}, + {'s', 'i', 'm', 'p', 'l', 'e', 'x'}, + {'b', 'x', 'x', 'x', 'x', 'e', 'b'}, + {'x', 'o', 'g', 'g', 'l', 'x', 'o'}, + {'x', 'x', 'x', 'D', 'T', 'r', 'a'}, + {'R', 'E', 'P', 'E', 'A', 'd', 'x'}, + {'x', 'x', 'x', 'x', 'x', 'x', 'x'}, + {'N', 'O', 'T', 'R', 'E', '_', 'P'}, + {'x', 'x', 'D', 'E', 'T', 'A', 'E'}, + }, + new String[] { + "this", + "is", + "not", + "a", + "simple", + "test", + "boggle", + "board", + "REPEATED", + "NOTRE_PEATED", + }) + .equals(ans)); + } + + public static void explore( + int i, + int j, + char[][] board, + TrieNode trieNode, + boolean[][] visited, + Set finalWords) { + if (visited[i][j]) return; + + char letter = board[i][j]; + if (!trieNode.children.containsKey(letter)) { + return; + } + visited[i][j] = true; + trieNode = trieNode.children.get(letter); + if (trieNode.children.containsKey('*')) finalWords.add(trieNode.word); + + List neighbors = getNeighbors(i, j, board); + for (Integer[] neighbor : neighbors) + explore(neighbor[0], neighbor[1], board, trieNode, visited, finalWords); + + visited[i][j] = false; + } + + public static List getNeighbors(int i, int j, char[][] board) { + List neighbors = new ArrayList<>(); + if (i > 0 && j > 0) neighbors.add(new Integer[] {i - 1, j - 1}); + + if (i > 0 && j < board[0].length - 1) neighbors.add(new Integer[] {i - 1, j + 1}); + + if (i < board.length - 1 && j < board[0].length - 1) + neighbors.add(new Integer[] {i + 1, j + 1}); + + if (i < board.length - 1 && j > 0) neighbors.add(new Integer[] {i + 1, j - 1}); + + if (i > 0) neighbors.add(new Integer[] {i - 1, j}); + + if (i < board.length - 1) neighbors.add(new Integer[] {i + 1, j}); + + if (j > 0) neighbors.add(new Integer[] {i, j - 1}); + + if (j < board[0].length - 1) neighbors.add(new Integer[] {i, j + 1}); + + return neighbors; + } +} + +// Trie used to optimize string search +class TrieNode { + + Map children = new HashMap<>(); + String word = ""; +} + +class Trie { + + TrieNode root; + char endSymbol; + + public Trie() { + this.root = new TrieNode(); + this.endSymbol = '*'; + } + + public void add(String str) { + TrieNode node = this.root; + for (int i = 0; i < str.length(); i++) { + char letter = str.charAt(i); + if (!node.children.containsKey(letter)) { + TrieNode newNode = new TrieNode(); + node.children.put(letter, newNode); + } + node = node.children.get(letter); + } + node.children.put(this.endSymbol, null); + node.word = str; + } +} \ No newline at end of file From cab263ecfc7495a81402b1813f75ca1ea3404b94 Mon Sep 17 00:00:00 2001 From: Azad Nautiyal Date: Wed, 4 Nov 2020 21:04:39 +0530 Subject: [PATCH 8/9] Update WordBoggle.java --- Misc/WordBoggle.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Misc/WordBoggle.java b/Misc/WordBoggle.java index ea3f44ada29a..130784ac7ff4 100644 --- a/Misc/WordBoggle.java +++ b/Misc/WordBoggle.java @@ -1,6 +1,6 @@ import java.util.*; -public class wordBoggle { +public class WordBoggle { /** * O(nm * 8^s + ws) time where n=width of boggle board, m=height of boggle board, s=length of @@ -127,4 +127,4 @@ public void add(String str) { node.children.put(this.endSymbol, null); node.word = str; } -} \ No newline at end of file +} From ffbc3b1bead0cde256e91f8b613412e399db46d9 Mon Sep 17 00:00:00 2001 From: Azad Date: Wed, 4 Nov 2020 21:18:02 +0530 Subject: [PATCH 9/9] Added RangeInSortedArray.java in Java/Misc --- Misc/RangeInSortedArray.java | 82 ++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 Misc/RangeInSortedArray.java diff --git a/Misc/RangeInSortedArray.java b/Misc/RangeInSortedArray.java new file mode 100644 index 000000000000..65056444ff03 --- /dev/null +++ b/Misc/RangeInSortedArray.java @@ -0,0 +1,82 @@ +package Misc; + +import java.util.*; + +public class RangeInSortedArray { + + public static void main(String[] args) { + // Testcases + assert Arrays.equals(sortedRange(new int[] {1, 2, 3, 3, 3, 4, 5}, 3), new int[] {2, 4}); + assert Arrays.equals(sortedRange(new int[] {1, 2, 3, 3, 3, 4, 5}, 4), new int[] {5, 5}); + assert Arrays.equals(sortedRange(new int[] {0, 1, 2}, 3), new int[] {-1, -1}); + } + + // Get the 1st and last occurrence index of a number 'key' in a non-decreasing array 'nums' + // Gives [-1, -1] in case element doesn't exist in array + public static int[] sortedRange(int[] nums, int key) { + int[] range = new int[] {-1, -1}; + alteredBinSearchIter(nums, key, 0, nums.length - 1, range, true); + alteredBinSearchIter(nums, key, 0, nums.length - 1, range, false); + return range; + } + + // Recursive altered binary search which searches for leftmost as well as rightmost occurrence of + // 'key' + public static void alteredBinSearch( + int[] nums, int key, int left, int right, int[] range, boolean goLeft) { + if (left > right) return; + int mid = (left + right) / 2; + if (nums[mid] > key) alteredBinSearch(nums, key, left, mid - 1, range, goLeft); + else if (nums[mid] < key) alteredBinSearch(nums, key, mid + 1, right, range, goLeft); + else { + if (goLeft) { + if (mid == 0 || nums[mid - 1] != key) range[0] = mid; + else alteredBinSearch(nums, key, left, mid - 1, range, goLeft); + } else { + if (mid == nums.length - 1 || nums[mid + 1] != key) range[1] = mid; + else alteredBinSearch(nums, key, mid + 1, right, range, goLeft); + } + } + } + + // Iterative altered binary search which searches for leftmost as well as rightmost occurrence of + // 'key' + public static void alteredBinSearchIter( + int[] nums, int key, int left, int right, int[] range, boolean goLeft) { + while (left <= right) { + int mid = (left + right) / 2; + if (nums[mid] > key) right = mid - 1; + else if (nums[mid] < key) left = mid + 1; + else { + if (goLeft) { + if (mid == 0 || nums[mid - 1] != key) { + range[0] = mid; + return; + } else right = mid - 1; + } else { + if (mid == nums.length - 1 || nums[mid + 1] != key) { + range[1] = mid; + return; + } else left = mid + 1; + } + } + } + } + + public static int getCountLessThan(int[] nums, int key) { + return getLessThan(nums, key, 0, nums.length - 1); + } + + public static int getLessThan(int[] nums, int key, int left, int right) { + int count = 0; + while (left <= right) { + int mid = (left + right) / 2; + if (nums[mid] > key) right = mid - 1; + else if (nums[mid] <= key) { + count = mid + 1; // Atleast mid+1 elements exist which are <= key + left = mid + 1; + } + } + return count; + } +} \ No newline at end of file