diff --git a/java-leetcode/src/main/java/io/github/poorguy/explore/learn/dynamicprogramming/LongestSubstringWithoutRepeatingCharacters.java b/java-leetcode/src/main/java/io/github/poorguy/explore/learn/dynamicprogramming/LongestSubstringWithoutRepeatingCharacters.java new file mode 100644 index 0000000000000000000000000000000000000000..b2a53f40d95d022e75ccc2f9dbf4c871039e350e --- /dev/null +++ b/java-leetcode/src/main/java/io/github/poorguy/explore/learn/dynamicprogramming/LongestSubstringWithoutRepeatingCharacters.java @@ -0,0 +1,28 @@ +/* All Contributors (C) 2021 */ +package io.github.poorguy.explore.learn.dynamicprogramming; + +import java.util.HashMap; +import java.util.Map; + +class LongestSubstringWithoutRepeatingCharacters { + public int lengthOfLongestSubstring(String s) { + if (s.length() == 0) { + return 0; + } + + // Character as key and index as value + Map map = new HashMap<>(); + // two pointers + int l = 0; + int max = 1; + for (int r = 0; r < s.length(); r++) { + if (map.containsKey(s.charAt(r))) { + // Math.max and +1 is important + l = Math.max(l, map.get(s.charAt(r)) + 1); + } + map.put(s.charAt(r), r); + max = Math.max(max, r - l + 1); + } + return max; + } +} diff --git a/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/AddAndSearchWordDataStructureDesign.java b/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/AddAndSearchWordDataStructureDesign.java new file mode 100644 index 0000000000000000000000000000000000000000..c477877f00293f9a21558bb355b280b761888cb5 --- /dev/null +++ b/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/AddAndSearchWordDataStructureDesign.java @@ -0,0 +1,81 @@ +/* All Contributors (C) 2021 */ +package io.github.poorguy.explore.learn.trie; + +import java.util.ArrayList; +import java.util.List; + +class AddAndSearchWordDataStructureDesign { + private Character ch = null; + private AddAndSearchWordDataStructureDesign[] children = + new AddAndSearchWordDataStructureDesign[26]; + private boolean isEnd = false; + + /** Initialize your data structure here. */ + public AddAndSearchWordDataStructureDesign() {} + + public void addWord(String word) { + AddAndSearchWordDataStructureDesign pointer = this; + char[] chars = word.toCharArray(); + for (char c : chars) { + if (pointer.children[c - 'a'] == null) { + AddAndSearchWordDataStructureDesign child = + new AddAndSearchWordDataStructureDesign(); + child.ch = c; + pointer.children[c - 'a'] = child; + } + pointer = pointer.children[c - 'a']; + } + pointer.isEnd = true; + } + + public boolean search(String word) { + AddAndSearchWordDataStructureDesign pointer = this; + char[] chars = word.toCharArray(); + List charList = new ArrayList<>(chars.length); + for (char c : chars) { + charList.add(c); + } + return search(charList, pointer); + } + + private boolean search(List charList, AddAndSearchWordDataStructureDesign pointer) { + if (charList.size() == 0) { + return false; + } + if (charList.get(0) == '.') { + for (int i = 0; i < 26; i++) { + if (pointer.children[i] == null) { + continue; + } + if (pointer.children[i].isEnd && charList.size() == 1) { + return true; + } + boolean result = search(charList, pointer.children[i]); + if (result) { + return true; + } + charList.add(0, '.'); + } + return false; + } else { + if (pointer.children[charList.get(0) - 'a'] == null) { + return false; + } + if (pointer.children[charList.get(0) - 'a'].isEnd && charList.size() == 1) { + return true; + } + Character removed = charList.remove(0); + boolean result = search(charList, pointer.children[removed - 'a']); + if (result) { + return true; + } + charList.add(0, removed); + } + return false; + } +} + +/** + * Your WordDictionary object will be instantiated and called as such: WordDictionary obj = new + * WordDictionary(); obj.addWord(word); boolean param_2 = obj.search(word); + */ diff --git a/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/ImplementTriePrefixTree.java b/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/ImplementTriePrefixTree.java new file mode 100644 index 0000000000000000000000000000000000000000..6c5ac1e26850cd257ef61b347881be1f879ca379 --- /dev/null +++ b/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/ImplementTriePrefixTree.java @@ -0,0 +1,88 @@ +/* All Contributors (C) 2021 */ +package io.github.poorguy.explore.learn.trie; + +import java.util.HashMap; +import java.util.Map; + +class ImplementTriePrefixTree { + private Character val; + private boolean isEnd; + private Map children; + + /** Initialize your data structure here. */ + public ImplementTriePrefixTree() { + val = null; + isEnd = false; + children = null; + } + + /** Inserts a word into the trie. */ + public void insert(String word) { + if (word == null || "".equals(word)) { + return; + } + char[] chars = word.toCharArray(); + ImplementTriePrefixTree pointer = this; + for (char c : chars) { + if (pointer.children == null) { + pointer.children = new HashMap<>(); + } + if (pointer.children.containsKey(c)) { + pointer = pointer.children.get(c); + } else { + ImplementTriePrefixTree trie = new ImplementTriePrefixTree(); + trie.val = c; + pointer.children.put(c, trie); + pointer = trie; + } + } + pointer.isEnd = true; + } + + /** Returns if the word is in the trie. */ + public boolean search(String word) { + if (word == null || "".equals(word)) { + return false; + } + char[] chars = word.toCharArray(); + ImplementTriePrefixTree pointer = this; + for (char c : chars) { + if (pointer.children == null || pointer.children.isEmpty()) { + return false; + } + ImplementTriePrefixTree child = pointer.children.get(c); + if (child == null) { + return false; + } else { + pointer = child; + } + } + return pointer.isEnd; + } + + /** Returns if there is any word in the trie that starts with the given prefix. */ + public boolean startsWith(String prefix) { + if (prefix == null || "".equals(prefix)) { + return false; + } + char[] chars = prefix.toCharArray(); + ImplementTriePrefixTree pointer = this; + for (char c : chars) { + if (pointer.children == null || pointer.children.isEmpty()) { + return false; + } + ImplementTriePrefixTree child = pointer.children.get(c); + if (child == null) { + return false; + } else { + pointer = child; + } + } + return true; + } +} + +/** + * Your Trie object will be instantiated and called as such: Trie obj = new Trie(); + * obj.insert(word); boolean param_2 = obj.search(word); boolean param_3 = obj.startsWith(prefix); + */ diff --git a/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/MapSumPairs.java b/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/MapSumPairs.java new file mode 100644 index 0000000000000000000000000000000000000000..9f611c0a5b892b99be9688f282068a5291d2d5fe --- /dev/null +++ b/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/MapSumPairs.java @@ -0,0 +1,73 @@ +/* All Contributors (C) 2021 */ +package io.github.poorguy.explore.learn.trie; + +import java.util.HashMap; +import java.util.Map; + +class MapSumPairs { + + private Character ch; + private Map children; + private int val; + + /** Initialize your data structure here. */ + public MapSumPairs() { + this.ch = null; + this.children = null; + this.val = 0; + } + + public void insert(String key, int val) { + char[] chars = key.toCharArray(); + MapSumPairs pointer = this; + for (char c : chars) { + if (pointer.children == null) { + pointer.children = new HashMap<>(); + } + if (pointer.children.containsKey(c)) { + pointer = pointer.children.get(c); + } else { + MapSumPairs mapSum = new MapSumPairs(); + mapSum.ch = c; + pointer.children.put(c, mapSum); + pointer = mapSum; + } + } + pointer.val = val; + } + + public int sum(String prefix) { + MapSumPairs pointer = this; + char[] chars = prefix.toCharArray(); + for (char c : chars) { + if (pointer.children == null) { + return 0; + } + MapSumPairs child = pointer.children.get(c); + if (child == null) { + return 0; + } + pointer = child; + } + return sum(pointer); + } + + private int sum(MapSumPairs mapSum) { + if (mapSum == null) { + return 0; + } + if (mapSum.children == null || mapSum.children.isEmpty()) { + return mapSum.val; + } + int sum = 0; + for (MapSumPairs child : mapSum.children.values()) { + sum += sum(child); + } + return mapSum.val + sum; + } +} + +/** + * Your MapSum object will be instantiated and called as such: MapSum obj = new MapSum(); + * obj.insert(key,val); int param_2 = obj.sum(prefix); + */ diff --git a/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/MaximumXorOfTwoNumbersInAnArray.java b/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/MaximumXorOfTwoNumbersInAnArray.java new file mode 100644 index 0000000000000000000000000000000000000000..87818ccf5ade69dfde3d6160aded7d1935a874f9 --- /dev/null +++ b/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/MaximumXorOfTwoNumbersInAnArray.java @@ -0,0 +1,20 @@ +/* All Contributors (C) 2021 */ +package io.github.poorguy.explore.learn.trie; + +class MaximumXorOfTwoNumbersInAnArray { + public int findMaximumXOR(int[] nums) { + if (nums.length == 1) { + return 0; + } + int max = 0; + for (int i = 0; i < nums.length - 1; i++) { + for (int j = i + 1; j < nums.length; j++) { + int xor = nums[i] ^ nums[j]; + if (xor > max) { + max = xor; + } + } + } + return max; + } +} diff --git a/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/ReplaceWords.java b/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/ReplaceWords.java new file mode 100644 index 0000000000000000000000000000000000000000..c1723e179442e1030fe14aa0c593669d1e25f9f0 --- /dev/null +++ b/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/ReplaceWords.java @@ -0,0 +1,70 @@ +/* All Contributors (C) 2021 */ +package io.github.poorguy.explore.learn.trie; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +class ReplaceWords { + private class Trie { + private Character ch = null; + private Map children = new HashMap<>(); + private boolean isEnd = false; + + private void insert(String str) { + Trie pointer = this; + char[] chars = str.toCharArray(); + for (char c : chars) { + if (pointer.children.containsKey(c)) { + pointer = pointer.children.get(c); + } else { + Trie child = new Trie(); + child.ch = c; + pointer.children.put(c, child); + pointer = child; + } + } + pointer.isEnd = true; + } + + // if no prefix, return str. else return shortest prefix + private String prefix(String str) { + Trie pointer = this; + char[] chars = str.toCharArray(); + List result = new ArrayList<>(); + boolean end = false; + for (char c : chars) { + if (!pointer.children.containsKey(c)) { + break; + } else { + result.add(c); + Trie child = pointer.children.get(c); + if (child.isEnd) { + end = true; + break; + } + pointer = child; + } + } + if (!end) { + return str; + } + return result.stream().map(Object::toString).collect(Collectors.joining("")); + } + } + + public String replaceWords(List dictionary, String sentence) { + Trie trie = new Trie(); + for (String str : dictionary) { + trie.insert(str); + } + String[] words = sentence.split(" "); + List wordList = new ArrayList<>(words.length); + for (String word : words) { + wordList.add(trie.prefix(word)); + } + return String.join(" ", wordList); + } +} diff --git a/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/WordSearch2.java b/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/WordSearch2.java new file mode 100644 index 0000000000000000000000000000000000000000..ae56a8e071dcd5d8e5f7ccc746d5234a6dfb0672 --- /dev/null +++ b/java-leetcode/src/main/java/io/github/poorguy/explore/learn/trie/WordSearch2.java @@ -0,0 +1,111 @@ +/* All Contributors (C) 2021 */ +package io.github.poorguy.explore.learn.trie; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** todo a little slow */ +class WordSearch2 { + private class Node { + Character ch = null; + Node[] children = new Node[26]; + boolean isEnd = false; + } + + private Set result = new HashSet<>(); + + public List findWords(char[][] board, String[] words) { + Node head = new Node(); + Node pointer = head; + for (String word : words) { + for (Character ch : word.toCharArray()) { + if (pointer.children[ch - 'a'] == null) { + Node child = new Node(); + child.ch = ch; + pointer.children[ch - 'a'] = child; + } + pointer = pointer.children[ch - 'a']; + } + pointer.isEnd = true; + pointer = head; + } + + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + pointer = head; + search( + pointer, + i, + j, + board, + new boolean[board.length][board[0].length], + new ArrayList<>()); + } + } + + return new ArrayList<>(result); + } + + private boolean search( + Node pointer, + int row, + int col, + char[][] board, + boolean[][] flag, + List chars) { + if (row < 0 || row >= board.length || col < 0 || col >= board[0].length || flag[row][col]) { + return false; + } + + char ch = board[row][col]; + Node child = pointer.children[ch - 'a']; + if (child == null) { + return false; + } + flag[row][col] = true; + + chars.add(child.ch); + if (child.isEnd) { + result.add(listToString(chars)); + } + + boolean hasNext = false; + if (search(child, row - 1, col, board, flag, chars)) { + hasNext = true; + } + if (search(child, row + 1, col, board, flag, chars)) { + hasNext = true; + } + if (search(child, row, col - 1, board, flag, chars)) { + hasNext = true; + } + if (search(child, row, col + 1, board, flag, chars)) { + hasNext = true; + } + chars.remove(chars.size() - 1); + flag[row][col] = false; + return child.isEnd || hasNext; + } + + private String listToString(List list) { + StringBuilder sb = new StringBuilder(); + for (Character ch : list) { + sb.append(sb); + } + return sb.toString(); + } + + // [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]] + // ["oath","pea","eat","rain"] + public static void main(String[] args) { + WordSearch2 solution = new WordSearch2(); + char[][] board = { + {'o', 'a', 'a', 'n'}, {'e', 't', 'a', 'e'}, {'i', 'h', 'k', 'r'}, {'i', 'f', 'l', 'v'} + }; + String[] words = {"oath", "pea", "eat", "rain"}; + List wordList = solution.findWords(board, words); + wordList.forEach(System.out::println); + } +}