Given two integers n and k, return the $k^{th}$ lexicographically smallest integer in the range [1, n].
Example 1:
Input: n = 13, k = 2 Output: 10 Explanation: The lexicographical order is [1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9], so the second smallest number is 10.
classSolution { publicintfindKthNumber(int n, int k) { --k; intnum=1; while (k > 0) { intstep= helper(num, n); if (step <= k) { ++num; k -= step; } else { num *= 10; --k; } } return num; }
privateinthelper(int num, int n) { longfirst= num, last = first, step = 0; while (first <= n) { step += Math.min(n, last) - first + 1; first *= 10; last = last * 10 + 9; } return (int)step; } }
2227. Encrypt and Decrypt Strings
You are given a character array keys containing unique characters and a string array values containing strings of length 2. You are also given another string array dictionary that contains all permitted original strings after decryption. You should implement a data structure that can encrypt or decrypt a 0-indexed string.
A string is encrypted with the following process:
For each character c in the string, we find the index i satisfying keys[i] == c in keys
Replace c with values[i] in the string
Note that in case a character of the string is not present in keys, the encryption process cannot be carried out, and an empty string "" is returned.
A string is decrypted with the following process:
For each substring s of length 2 occurring at an even index in the string, we find an i such that values[i] == s. If there are multiple valid i, we choose any one of them. This means a string could have multiple possible strings it can decrypt to.
Replace s with keys[i] in the string.
Implement the Encrypter class:
Encrypter(char[] keys, String[] values, String[] dictionary) Initializes the Encrypter class with keys, values, and dictionary.
String encrypt(String word1) Encrypts word1 with the encryption process described above and returns the encrypted string.
int decrypt(String word2) Returns the number of possible strings word2 could decrypt to that also appear in dictionary.
Explanation: /** * return "eizfeiam". * 'a' maps to "ei", 'b' maps to "zf", 'c' maps to "ei", and 'd' maps to "am" */ encrypter.encrypt("abcd"); /** * return 2. * "ei" can map to 'a' or 'c', "zf" maps to 'b', and "am" maps to 'd'. * Thus, the possible strings after decryption are "abad", "cbad", "abcd", and "cbcd". * 2 of those strings, "abad" and "abcd", appear in dictionary, so the answer is 2. * / encrypter.decrypt("eizfeiam");
privatevoidaddString(String s) { if (s == null) return; Nodet= root; for (char c: s.toCharArray()) { intm= c - 'a'; if (t.next[m] == null) { t.next[m] = newNode(); } t = t.next[m]; } ++t.count; }
publicEncrypter(char[] keys, String[] values, String[] dictionary) { this.root = newNode(); for (inti=0; i < keys.length; i++) { map.put(keys[i], values[i]); } for (String s: dictionary) { addString(encrypt(s)); } } public String encrypt(String word1) { StringBuildersb=newStringBuilder(); for (char c: word1.toCharArray()) { if (!map.containsKey(c)) returnnull; sb.append(map.get(c)); } return sb.toString(); } publicintdecrypt(String word2) { Nodet=this.root; for (char c: word2.toCharArray()) { t = t.next[c - 'a']; if (t == null) return0; } return t.count; } }
1032. Stream of Characters
Design an algorithm that accepts a stream of characters and checks if a suffix of these characters is a string of a given array of strings words. For example, if words = ["abc", "xyz"] and the stream added the four characters (one by one) 'a', 'x', 'y', and 'z', your algorithm should detect that the suffix "xyz" of the characters "axyz" matches "xyz" from words. Implement the StreamChecker class:
StreamChecker(String[] words) Initializes the object with the strings array words.
boolean query(char letter) Accepts a new character from the stream and returns true if any non-empty suffix from the stream forms a word that is in words.
publicStreamChecker(String[] words) { this.root = newNode(); this.curr = this.root; for (String word: words) { Nodet=this.root; for (inti= word.length() - 1; i >= 0; i--) { intm= word.charAt(i) - 'a'; if (t.next[m] == null) { t.next[m] = newNode(); } t = t.next[m]; } t.isEnd = true; } } publicbooleanquery(char letter) { sb.append(letter); Nodet=this.root; for (inti= sb.length() - 1; i >= 0; i--) { t = t.next[sb.charAt(i) - 'a']; if (t == null) returnfalse; if (t.isEnd) returntrue; } returnfalse; } }
588. Design In-Memory File System
Design a data structure that simulates an in-memory file system.
Implement the FileSystem class:
FileSystem() Initializes the object of the system.
List<String> ls(String path) The answer should in lexicographic order.
If path is a file path, returns a list that only contains this file's name.
If path is a directory path, returns the list of file and directory names in this directory.
void mkdir(String path) Makes a new directory according to the given path. The given directory path does not exist. If the middle directories in the path do not exist, you should create them as well.
classFileSystem { classNode { public Map<String, Node> map; public StringBuilder content; public String filename; publicNode() { this.map = newHashMap<>(); this.content = newStringBuilder(); } }
private Node root;
publicFileSystem() { this.root = newNode(); } public List<String> ls(String path) { Nodet=this.root; String[] arr = path.split("/"); for (String s: arr) { if (s.length() == 0) continue; Nodenext= t.map.get(s); if (next == null) returnnewArrayList<>(); t = next; } List<String> res = newArrayList<>(); if (t.filename != null) { res.add(t.filename); return res; } for (String name: t.map.keySet()) { res.add(name); } Collections.sort(res, (a,b)->a.compareTo(b)); return res; } publicvoidmkdir(String path) { Nodet=this.root; String[] arr = path.split("/"); for (String s: arr) { if (s.length() == 0) continue; t.map.putIfAbsent(s, newNode()); t = t.map.get(s); } } publicvoidaddContentToFile(String filePath, String content) { Nodet=this.root; String[] arr = filePath.split("/"); for (String s: arr) { if (s.length() == 0) continue; t.map.putIfAbsent(s, newNode()); t = t.map.get(s); } t.content.append(content); t.filename = arr[arr.length - 1]; } public String readContentFromFile(String filePath) { Nodet=this.root; String[] arr = filePath.split("/"); for (String s: arr) { if (s.length() == 0) continue; t = t.map.get(s); } return t.content.toString(); } }
140. Word Break II
Given a string s and a dictionary of strings wordDict, add spaces in s to construct a sentence where each word is a valid dictionary word. Return all such possible sentences in any order.
Note that the same word in the dictionary may be reused multiple times in the segmentation.
Example 1:
Input: s = "catsanddog", wordDict = ["cat","cats","and","sand","dog"] Output: ["cats and dog","cat sand dog"]
Example 2:
Input: s = "pineapplepenapple", wordDict = ["apple","pen","applepen","pine","pineapple"] Output: ["pine apple pen apple","pineapple pen apple","pine applepen apple"] Explanation: Note that you are allowed to reuse a dictionary word.
Trie
classSolution { classNode { public Node[] next; publicboolean isEnd; publicNode() { next = newNode[26]; } } privateNoderoot=newNode(); private List<String> res = newArrayList<>();
public List<String> wordBreak(String s, List<String> wordDict) { for (String word: wordDict) { Nodet= root; for (char c: word.toCharArray()) { intm= c - 'a'; if (t.next[m] == null) { t.next[m] = newNode(); } t = t.next[m]; } t.isEnd = true; } backtracking(s, 0, ""); return res; }
privatevoidbacktracking(String s, int start, String prev) { if (start == s.length()) { res.add(prev.substring(0, prev.length()-1)); return; } Nodet=this.root; for (inti= start; i < s.length() && t != null; i++) { t = t.next[s.charAt(i) - 'a']; if (t != null && t.isEnd) { backtracking(s, i+1, prev + s.substring(start, i+1) + " "); } } } }