Leetcode medium

¡Supera tus tareas y exámenes ahora con Quizwiz!

// Approach #1 // Using Arrays.sort directly. class Solution { public int findKthLargest(int[] nums, int k) { Arrays.sort(nums); return nums[nums.length - k]; } } // Approach #2 // Use built-in Priority Queue. class Solution { public int findKthLargest(int[] nums, int k) { Queue<Integer> q = new PriorityQueue<>((n1, n2) -> (n2 - n1)); for (int num : nums) { q.offer(num); } for (int i = 0; i < k - 1; i++) { q.poll(); } return (int)q.poll(); } }

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. Example 1: Input: [3,2,1,5,6,4] and k = 2 Output: 5

public String shortestCompletingWord(String licensePlate, String[] words) { int[] freq = new int[26]; for (char c: licensePlate.toLowerCase().toCharArray()) { if(Character.isLowerCase(c)) freq[c - 'a']++; } String res = ""; for (String s: words) { if ((res.length() == 0 || s.length() < res.length()) && ok(Arrays.copyOf(freq, 26), s)) res = s; } return res; } public boolean ok(int[] freq, String s){ for (char c : s.toCharArray()) freq[c - 'a']--; for (int f : freq) if (f > 0) return false; return true; }

Find the minimum length word from a given dictionary words, which has all the letters from the string licensePlate. Such a word is said to complete the given string licensePlate Here, for letters we ignore case. For example, "P" on the licensePlate still matches "p" on the word. It is guaranteed an answer exists. If there are multiple answers, return the one that occurs first in the array. The license plate might have the same letter occurring multiple times. For example, given a licensePlate of "PP", the word "pair" does not complete the licensePlate, but the word "supper" does. Example 1: Input: licensePlate = "1s3 PSt", words = ["step", "steps", "stripe", "stepple"] Output: "steps" Explanation: The smallest length word that contains the letters "S", "P", "S", and "T". Note that the answer is not "step", because the letter "s" must occur in the word twice. Also note that we ignored case for the purposes of comparing whether a letter exists in the word.

public boolean isValidBST(TreeNode root) { return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE); } private boolean isValidBST(TreeNode root, long left, long right) { if(root == null) return true; if(root.val <= left || root.val >= right) { return false; } return isValidBST(root.left, left, root.val) && isValidBST(root.right, root.val, right); }

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: Input: 2 / \ 1 3 Output: true

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if(!covers(root, p) || !covers(root, q)) return null; return ancestorHelper(root, p, q); } private TreeNode ancestorHelper(TreeNode root, TreeNode p, TreeNode q) { if(root == null || root == p || root == q) return root; boolean pOnLeft = covers(root.left, p); boolean qOnLeft = covers(root.left, q); if(pOnLeft != qOnLeft) { return root; } TreeNode childSide = pOnLeft ? root.left : root.right; return ancestorHelper(childSide, p, q); } private boolean covers(TreeNode root, TreeNode p) { if(root == null) return false; if(root == p) return true; return covers(root.left, p) || covers(root.right, p); }

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According to the definition of LCA on Wikipedia: "The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself)." Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4] _______3______ / \ ___5__ ___1__ / \ / \ 6 _2 0 8 / \ 7 4 Example 1: Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 Output: 3 Explanation: The LCA of of nodes 5 and 1 is 3.

Traverse each node in breadth-first order, keeping track of that node's position. For each depth, the first node reached is the left-most, while the last node reached is the right-most. public int widthOfBinaryTree(TreeNode root) { Queue<AnnotatedNode> queue = new LinkedList(); queue.add(new AnnotatedNode(root, 0, 0)); int curDepth = 0, left = 0, ans = 0; while (!queue.isEmpty()) { AnnotatedNode a = queue.poll(); if (a.node != null) { queue.add(new AnnotatedNode(a.node.left, a.depth + 1, a.pos * 2)); queue.add(new AnnotatedNode(a.node.right, a.depth + 1, a.pos * 2 + 1)); if (curDepth != a.depth) { curDepth = a.depth; left = a.pos; } ans = Math.max(ans, a.pos - left + 1); } } return ans; } class AnnotatedNode { TreeNode node; int depth, pos; AnnotatedNode(TreeNode n, int d, int p) { node = n; depth = d; pos = p; } }

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).

Convert each number into a string. Sort. (Strings automatically sorted by lexicographically). Convert back to int. public List<Integer> lexicalOrder(int n) { String[] strs = new String[n]; for(int i = 1; i <= n; i++) { strs[i - 1] = "" + i; } Arrays.sort(strs); List<Integer> result = new ArrayList<>(); for(String s : strs) { result.add(Integer.parseInt(s)); } return result; }

Given an integer n, return 1 - n in lexicographical order. For example, given 13, return: [1,10,11,12,13,2,3,4,5,6,7,8,9]. Please optimize your algorithm to use less time and space. The input size may be as large as 5,000,000.

public TreeNode insertIntoBST(TreeNode root, int val) { TreeNode rootTrack = root; while(root != null) { if(val > root.val && root.right != null) { root = root.right; } else if(val < root.val && root.left != null) { root = root.left; } else break; } TreeNode tmp = new TreeNode(val); if(val < root.val) root.left = tmp; else root.right = tmp; return rootTrack; }

Given the root node of a binary search tree (BST) and a value to be inserted into the tree, insert the value into the BST. Return the root node of the BST after the insertion. It is guaranteed that the new value does not exist in the original BST. Note that there may exist multiple valid ways for the insertion, as long as the tree remains a BST after insertion. You can return any of them. For example, Given the tree: 4 / \ 2 7 / \ 1 3 And the value to insert: 5

// Same idea of Longest Common Substring public int findLength(int[] A, int[] B) { if(A == null||B == null) return 0; int m = A.length; int n = B.length; int max = 0; //dp[i][j] is the length of longest common subarray ending with nums[i] and nums[j] int[][] dp = new int[m + 1][n + 1]; dp[0][0] = 0; for(int i = 1; i <= m; i++) { for(int j = 1; j <= n; j++) { if(A[i - 1] == B[j - 1]) { dp[i][j] = 1 + dp[i - 1][j - 1]; max = Math.max(max, dp[i][j]); } } } return max; }

Given two integer arrays A and B, return the maximum length of an subarray that appears in both arrays. Example 1: Input: A: [1,2,3,2,1] B: [3,2,1,4,7] Output: 3 Explanation: The repeated subarray with maximum length is [3, 2, 1].

Brute force O(n^2) solution: List<int[]> calendar; MyCalendar() { calendar = new ArrayList(); } public boolean book(int start, int end) { for (int[] iv: calendar) { if (iv[0] < end && start < iv[1]) return false; } calendar.add(new int[]{start, end}); return true; }

Implement a MyCalendar class to store your events. A new event can be added if adding the event will not cause a double booking. Your class will have the 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 double booking happens when two events have some non-empty intersection (ie., there is some time that is common to both events.) For each call to the method MyCalendar.book, return true if the event can be added to the calendar successfully without causing a double 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(15, 25); // returns false MyCalendar.book(20, 30); // returns true Explanation: The first event can be booked. The second can't because time 15 is already booked by another event. The third event can be booked, as the first event takes every time less than 20, but not including 20.

public class Solution { private int[] original; private int[] copy; public Solution(int[] nums) { original = new int[nums.length]; copy = new int[nums.length]; for(int i = 0; i < nums.length; i++) { original[i] = nums[i]; copy[i] = nums[i]; } } /** Resets the array to its original configuration and return it. */ public int[] reset() { for(int i = 0; i < original.length; i++) copy[i] = original[i]; return copy; } /** Returns a random shuffling of the array. */ public int[] shuffle() { int N = copy.length; for(int i = 0; i < N; i++) { int r = i + (int) (Math.random() * (N - i)); int tmp = copy[r]; copy[r] = copy[i]; copy[i] = tmp; } return copy; } }

Shuffle a set of numbers without duplicates. Example: // Init an array with set 1, 2, and 3. int[] nums = {1,2,3}; Solution solution = new Solution(nums); // Shuffle the array [1,2,3] and return its result. Any permutation of [1,2,3] must equally likely to be returned. solution.shuffle(); // Resets the array back to its original configuration [1,2,3]. solution.reset(); // Returns the random shuffling of array [1,2,3]. solution.shuffle();

public int numComponents(ListNode head, int[] G) { Set<Integer> Gset = new HashSet(); for (int x: G) Gset.add(x); ListNode cur = head; int ans = 0; while (cur != null) { if (Gset.contains(cur.val) && (cur.next == null || !Gset.contains(cur.next.val))) ans++; cur = cur.next; } return ans; }

We are given head, the head node of a linked list containing unique integer values. We are also given the list G, a subset of the values in the linked list. Return the number of connected components in G, where two values are connected if they appear consecutively in the linked list. Example 1: Input: head: 0->1->2->3 G = [0, 1, 3] Output: 2 Explanation: 0 and 1 are connected, so [0, 1] and [3] are the two connected components.

public boolean circularArrayLoop(int[] nums) { int len = nums.length; Set<Integer> set = new HashSet<>(); boolean[] visited = new boolean[len]; for(int i = 0; i < len; i++){ if(visited[i]) continue; int cur = i; while(true) { visited[cur] = true; int next = (cur + nums[cur]) % len; if(next < 0) next += len; if(cur == next || nums[cur] * nums[next] < 0) break; if(set.contains(next)) return true; set.add(cur); cur = next; } } return false; }

You are given an array of positive and negative integers. If a number n at an index is positive, then move forward n steps. Conversely, if it's negative (-n), move backward n steps. Assume the first element of the array is forward next to the last element, and the last element is backward next to the first element. Determine if there is a loop in this array. A loop starts and ends at a particular index with more than 1 element along the loop. The loop must be "forward" or "backward'. Example 1: Given the array [2, -1, 1, 2, 2], there is a loop, from index 0 -> 2 -> 3 -> 0. Example 2: Given the array [-1, 2], there is no loop. Note: The given array is guaranteed to contain no element "0". Can you do it in O(n) time complexity and O(1) space complexity?

public ListNode swapPairs(ListNode head) { ListNode dummy = new ListNode(0); dummy.next = head; ListNode current = dummy; while (current.next != null && current.next.next != null) { ListNode first = current.next; ListNode second = current.next.next; first.next = second.next; current.next = second; current.next.next = first; current = current.next.next; } return dummy.next; }

Given a linked list, swap every two adjacent nodes and return its head. Example: Given 1->2->3->4, you should return the list as 2->1->4->3.

The idea is, if we know the max number of unique substrings in p ends with 'a', 'b', ..., 'z', then the summary of them is the answer. Why is that? The max number of unique substring ends with a letter equals to the length of max contiguous substring ends with that letter. Example "abcd", the max number of unique substring ends with 'd' is 4, apparently they are "abcd", "bcd", "cd" and "d". If there are overlapping, we only need to consider the longest one because it covers all the possible substrings. Example: "abcdbcd", the max number of unique substring ends with 'd' is 4 and all substrings formed by the 2nd "bcd" part are covered in the 4 substrings already. No matter how long is a contiguous substring in p, it is in s since s has infinite length. Now we know the max number of unique substrings in p ends with 'a', 'b', ..., 'z' and those substrings are all in s. Summary is the answer, according to the question. public int findSubstringInWraproundString(String p) { // count[i] is the maximum unique substring end with ith letter. // 0 - 'a', 1 - 'b', ..., 25 - 'z'. int[] count = new int[26]; // store longest contiguous substring ends at current position. int maxLengthCur = 0; for (int i = 0; i < p.length(); i++) { if (i > 0 && (p.charAt(i) - p.charAt(i - 1) == 1 || (p.charAt(i - 1) - p.charAt(i) == 25))) { maxLengthCur++; } else { maxLengthCur = 1; } int index = p.charAt(i) - 'a'; count[index] = Math.max(count[index], maxLengthCur); } // Sum to get result int sum = 0; for (int i = 0; i < 26; i++) { sum += count[i]; } return sum; }

Consider the string s to be the infinite wraparound string of "abcdefghijklmnopqrstuvwxyz", so s will look like this: "...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd....". Now we have another string p. Your job is to find out how many unique non-empty substrings of p are present in s. In particular, your input is the string p and you need to output the number of different non-empty substrings of p in the string s. Note: p consists of only lowercase English letters and the size of p might be over 10000. Example 1: Input: "a" Output: 1 Explanation: Only the substring "a" of string "a" is in the string s. Example 2: Input: "cac" Output: 2 Explanation: There are two substrings "a", "c" of string "cac" in the string s.

We need to parse the source line by line. Our state is that we either are in a block comment or not. public List<String> removeComments(String[] source) { boolean inBlock = false; StringBuilder newline = new StringBuilder(); List<String> ans = new ArrayList(); for (String line: source) { int i = 0; char[] chars = line.toCharArray(); if (!inBlock) newline = new StringBuilder(); while (i < line.length()) { if (!inBlock && i+1 < line.length() && chars[i] == '/' && chars[i+1] == '*') { inBlock = true; i++; } else if (inBlock && i+1 < line.length() && chars[i] == '*' && chars[i+1] == '/') { inBlock = false; i++; } else if (!inBlock && i+1 < line.length() && chars[i] == '/' && chars[i+1] == '/') { break; } else if (!inBlock) { newline.append(chars[i]); } i++; } if (!inBlock && newline.length() > 0) { ans.add(new String(newline)); } } return ans; }

Given a C++ program, remove comments from it. The program source is an array where source[i] is the i-th line of the source code. This represents the result of splitting the original source code string by the newline character \n. In C++, there are two types of comments, line comments, and block comments. The string // denotes a line comment, which represents that it and rest of the characters to the right of it in the same line should be ignored. The string /* denotes a block comment, which represents that all characters until the next (non-overlapping) occurrence of */ should be ignored. (Here, occurrences happen in reading order: line by line from left to right.) To be clear, the string /*/ does not yet end the block comment, as the ending would be overlapping the beginning. The first effective comment takes precedence over others: if the string // occurs in a block comment, it is ignored. Similarly, if the string /* occurs in a line or block comment, it is also ignored. If a certain line of code is empty after removing comments, you must not output that line: each string in the answer list will be non-empty. There will be no control characters, single quote, or double quote characters. For example, source = "string s = "/* Not a comment. */";" will not be a test case. (Also, nothing else such as defines or macros will interfere with the comments.) It is guaranteed that every open block comment will eventually be closed, so /* outside of a line or block comment always starts a new comment. Finally, implicit newline characters can be deleted by block comments. Please see the examples below for details. After removing the comments from the source code, return the source code in the same format. Example 1: Input: source = ["/*Test program */", "int main()", "{ ", " // variable declaration ", "int a, b, c;", "/* This is a test", " multiline ", " comment for ", " testing */", "a = b + c;", "}"] The line by line code is visualized as below: /*Test program */ int main() { // variable declaration int a, b, c; /* This is a test multiline comment for testing */ a = b + c; } Output: ["int main()","{ "," ","int a, b, c;","a = b + c;","}"] The line by line code is visualized as below: int main() { int a, b, c; a = b + c; } Explanation: The string /* denotes a block comment, including line 1 and lines 6-9. The string // denotes line 4 as comments.

public int findMaxLength(int[] nums) { int sum = 0; int max = 0; Map<Integer, Integer> minDiffIdx = new HashMap<>(); minDiffIdx.put(0, -1); for(int i = 0; i < nums.length; ++i) { if(nums[i] == 1) { ++sum; } int diff = (i + 1) - 2 * sum ; if(minDiffIdx.containsKey(diff)) { max = Math.max(max, i - minDiffIdx.get(diff)); } else { minDiffIdx.put(diff, i); } } return max; }

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.

public int findBottomLeftValue(TreeNode root) { int leftH = height(root.left); int rightH = height(root.right); if(leftH == 0 && rightH == 0) return root.val; return leftH >= rightH ? findBottomLeftValue(root.left) : findBottomLeftValue(root.right); } private int height(TreeNode root) { if(root == null) return 0; return 1 + Math.max(height(root.left), height(root.right)); }

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.

Map<String, Integer> count; List<TreeNode> ans; public List<TreeNode> findDuplicateSubtrees(TreeNode root) { count = new HashMap(); ans = new ArrayList(); collect(root); return ans; } public String collect(TreeNode node) { if (node == null) return "#"; String serial = node.val + "," + collect(node.left) + "," + collect(node.right); count.put(serial, count.getOrDefault(serial, 0) + 1); if (count.get(serial) == 2) ans.add(node); return serial; }

Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only need to return the root node of any one of them. Two trees are duplicate if they have the same structure with same node values. Example 1: 1 / \ 2 3 / / \ 4 2 4 / 4 The following are two duplicate subtrees: 2 / 4 and 4 Therefore, you need to return above trees' root in the form of a list.

public int leastInterval(char[] tasks, int n) { int[] map = new int[26]; for (char c: tasks) map[c - 'A']++; Arrays.sort(map); int time = 0; while (map[25] > 0) { int i = 0; while (i <= n) { if (map[25] == 0) break; if (i < 26 && map[25 - i] > 0) map[25 - i]--; time++; i++; } Arrays.sort(map); } return time; } Time complexity : O(time)O(time). Number of iterations will be equal to resultant time timetime. Space complexity : O(1)O(1). Constant size array map is used.

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.

public int[] nextGreaterElements(int[] nums) { int n = nums.length, next[] = new int[n]; Arrays.fill(next, -1); Stack<Integer> stack = new Stack<>(); // index stack for (int i = 0; i < n * 2; i++) { int num = nums[i % n]; while (!stack.isEmpty() && nums[stack.peek()] < num) next[stack.pop()] = num; if (i < n) stack.push(i); } return next; }

Given a circular array (the next element of the last element is the first element of the array), print the Next Greater Number for every element. The Next Greater Number of a number x is the first greater number to its traversing-order next in the array, which means you could search circularly to find its next greater number. If it doesn't exist, output -1 for this number. Example 1: Input: [1,2,1] Output: [2,-1,2] Explanation: The first 1's next greater number is 2; The number 2 can't find next greater number; The second 1's next greater number needs to search circularly, which is also 2.

public List<List<String>> accountsMerge(List<List<String>> accounts) { DSU dsu = new DSU(); Map<String, String> emailToName = new HashMap(); Map<String, Integer> emailToID = new HashMap(); int id = 0; for (List<String> account: accounts) { String name = ""; for (String email: account) { if (name == "") { name = email; continue; } emailToName.put(email, name); if (!emailToID.containsKey(email)) { emailToID.put(email, id++); } dsu.union(emailToID.get(account.get(1)), emailToID.get(email)); } } Map<Integer, List<String>> ans = new HashMap(); for (String email: emailToName.keySet()) { int index = dsu.find(emailToID.get(email)); ans.computeIfAbsent(index, x-> new ArrayList()).add(email); } for (List<String> component: ans.values()) { Collections.sort(component); component.add(0, emailToName.get(component.get(0))); } return new ArrayList(ans.values()); } class DSU { int[] parent; public DSU() { parent = new int[10001]; for (int i = 0; i <= 10000; ++i) parent[i] = i; } public int find(int x) { if (parent[x] != x) parent[x] = find(parent[x]); return parent[x]; } public void union(int x, int y) { parent[find(x)] = find(y); } }

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", "[email protected]", "[email protected]"], ["John", "[email protected]"], ["John", "[email protected]", "[email protected]"], ["Mary", "[email protected]"]] Output: [["John", '[email protected]', '[email protected]', '[email protected]'], ["John", "[email protected]"], ["Mary", "[email protected]"]] Explanation: The first and third John's are the same person as they have the common email "[email protected]". 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', '[email protected]'], ['John', '[email protected]'], ['John', '[email protected]', '[email protected]', '[email protected]']] would still be accepted.

public int findMinDifference(List<String> timePoints) { int n = timePoints.size(); Collections.sort(timePoints);//sort time in ascending order int res = 1440; // 0~24 * 60 (1440) for(int i = 0; i < n; i++) { int timeDiff = diff(timePoints.get(i), timePoints.get((i+1)%n));//calculate time difference between neighbours timeDiff = Math.min(timeDiff, 1440 - timeDiff);// get the smaller one among the two time difference vals res = Math.min(timeDiff, res);// update global minimum val } return res; } private int diff(String t1, String t2) {//fetch hour and minute to calculate time difference int h1 = Integer.valueOf(t1.substring(0, 2)); int m1 = Integer.valueOf(t1.substring(3, 5)); int h2 = Integer.valueOf(t2.substring(0, 2)); int m2 = Integer.valueOf(t2.substring(3, 5)); return Math.abs((h1-h2)*60 + m1 - m2); }

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.

Let's process each i in reverse (decreasing order). At each T[i], to know when the next occurrence of say, temperature 100 is, we should just remember the last one we've seen, next[100]. Then, the first occurrence of a warmer value occurs at warmer_index, the minimum of next[T[i]+1], next[T[i]+2], ..., next[100]. public int[] dailyTemperatures(int[] T) { int[] ans = new int[T.length]; int[] next = new int[101]; Arrays.fill(next, Integer.MAX_VALUE); for (int i = T.length - 1; i >= 0; --i) { int warmer_index = Integer.MAX_VALUE; for (int t = T[i] + 1; t <= 100; ++t) { if (next[t] < warmer_index) warmer_index = next[t]; } if (warmer_index < Integer.MAX_VALUE) ans[i] = warmer_index - i; next[T[i]] = i; } return ans; } Time Complexity: O(NW)O(NW), where NN is the length of T and WW is the number of allowed values for T[i]. Since W = 71W=71, we can consider this complexity O(N)O(N). Space Complexity: O(N + W)O(N+W), the size of the answer and the next array.

Given a list of daily temperatures, produce a list that, for each day in the input, tells you how many days you would have to wait until a warmer temperature. If there is no future day for which this is possible, put 0 instead. For example, given the list temperatures = [73, 74, 75, 71, 69, 72, 76, 73], your output should be [1, 1, 4, 2, 1, 1, 0, 0].

public int minMoves2(int[] nums) { if (nums.length <= 1) return 0; Arrays.sort(nums); int lMedian = (nums.length / 2) - 1; int rMedian = (nums.length /2); int lSum = 0; int rSum = 0; for (int i = 0; i < nums.length; i++){ lSum += (Math.abs(nums[lMedian] - nums[i])); rSum += (Math.abs(nums[rMedian] - nums[i])); } return Math.min(lSum, rSum); }

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]

So LUS will always be one of ths strings in the list. e.g. ["ab", "abc"] will return 3 for "abc" is not the subsequence of "ab". ["ab", "abc", "abcd"] will return 4 for "abcd" is not the subsequence of "ab" or "abc". So for each string in list, we check if it is the subsequence of the others. If it is not the subsequence of the others, it is the candidate answer. We get the overall longest one and return the length of it. public int findLUSlength(String[] strs) { int lenLUS = -1; for (int i = 0; i < strs.length; i++) { int j = 0; for (; j < strs.length; j++) { if (i == j) { continue; } if (isSubsequence(strs[j], strs[i])) { break; } } if (j == strs.length) { lenLUS = Math.max(lenLUS, strs[i].length()); } } return lenLUS; } /** * * @param s1 * @param s2 * @return true if s2 is subsequence s1 */ private boolean isSubsequence(String s1, String s2) { int i2 = 0; for (int i1 = 0; i1 < s1.length() && i2 < s2.length(); i1++) { if (s1.charAt(i1) == s2.charAt(i2)) { i2++; } } return i2 == s2.length(); }

Given a list of strings, you need to find the longest uncommon subsequence among them. The longest uncommon subsequence is defined as the longest subsequence of one of these strings and this subsequence should not be any subsequence of the other strings. A subsequence is a sequence that can be derived from one sequence by deleting some characters without changing the order of the remaining elements. Trivially, any string is a subsequence of itself and an empty string is a subsequence of any string. The input will be a list of strings, and the output needs to be the length of the longest uncommon subsequence. If the longest uncommon subsequence doesn't exist, return -1. Example 1: Input: "aba", "cdc", "eae" Output: 3

Walk patterns: If out of bottom border (row >= m) then row = m - 1; col += 2; change walk direction. if out of right border (col >= n) then col = n - 1; row += 2; change walk direction. if out of top border (row < 0) then row = 0; change walk direction. if out of left border (col < 0) then col = 0; change walk direction. Otherwise, just go along with the current direction. Time complexity: O(m * n), m = number of rows, n = number of columns. Space complexity: O(1). public int[] findDiagonalOrder(int[][] matrix) { if (matrix == null || matrix.length == 0) return new int[0]; int m = matrix.length, n = matrix[0].length; int[] result = new int[m * n]; int row = 0, col = 0, d = 0; int[][] dirs = {{-1, 1}, {1, -1}}; for (int i = 0; i < m * n; i++) { result[i] = matrix[row][col]; row += dirs[d][0]; col += dirs[d][1]; if (row >= m) { row = m - 1; col += 2; d = 1 - d;} if (col >= n) { col = n - 1; row += 2; d = 1 - d;} if (row < 0) { row = 0; d = 1 - d;} if (col < 0) { col = 0; d = 1 - d;} } return result; }

Given a matrix of M x N elements (M rows, N columns), return all elements of the matrix in diagonal order as shown in the below image. Example: Input: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] Output: [1,2,4,7,5,3,6,8,9] Explanation:

public List<String> topKFrequent(String[] words, int k) { List<String> result = new ArrayList<>(); Map<String, FreqWord> map = new HashMap<>(); Queue<FreqWord> queue = new PriorityQueue<>(); for(String word : words) { if(map.containsKey(word)) { FreqWord curr = map.get(word); curr.freq++; map.put(word, curr); } else map.put(word, new FreqWord(word, 1)); } for(String key : map.keySet()) { queue.add(map.get(key)); } while(k > 0) { result.add(queue.poll().word); k--; } return result; } class FreqWord implements Comparable<FreqWord> { String word; int freq; public FreqWord(String w, int f) { word = w; freq = f; } public int compareTo(FreqWord other) { return this.freq == other.freq ? this.word.compareTo(other.word) : other.freq - this.freq; } }

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.

public boolean find132pattern(int[] nums) { // create stack of ranges // when higher number is found, merge top range with this and recursively check for overlaps // if the new max is within the top pair's range then we have a match // if the new max is above the rop pair's range then keep merging the ranges // when lower number is found, create new range Stack<Pair> s = new Stack<>(); for (int n : nums) { if (s.isEmpty() || n < s.peek().x) { s.push(new Pair(n, n)); continue; } Pair next = new Pair(s.peek().x, n); while (!s.isEmpty() && s.peek().x < n) { if (n < s.peek().y) return true; s.pop(); } s.push(next); } return false; } static class Pair { int x; int y; Pair(int x, int y) { this.x = x; this.y = y; } }

Given a sequence of n integers a1, a2, ..., an, a 132 pattern is a subsequence ai, aj, ak such that i < j < k and ai < ak < aj. Design an algorithm that takes a list of n numbers as input and checks whether there is a 132 pattern in the list. Note: n will be less than 15,000. Example 1: Input: [1, 2, 3, 4] Output: False Explanation: There is no 132 pattern in the sequence. Example 2: Input: [3, 1, 4, 2] Output: True Explanation: There is a 132 pattern in the sequence: [1, 4, 2].

// Basically you want to find the first even-index number not followed by the same number. public int singleNonDuplicate(int[] nums) { // binary search int lo = 0, hi = nums.length / 2; while (lo < hi) { int mid = lo + (hi - lo) / 2; if (nums[2 * mid] != nums[2 * mid + 1]) hi = mid; else lo = mid + 1; } return nums[2 * lo]; }

Given a sorted array consisting of only integers where every element appears twice except for one element which appears 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

I binary-search for where the resulting elements start in the array. It's the first index i so that arr[i] is better than arr[i+k] (with "better" meaning closer to or equally close to x). Then I just return the k elements starting there. public List<Integer> findClosestElements(int[] arr, int k, int x) { int lo = 0, hi = arr.length - k; while (lo < hi) { int mid = (lo + hi) / 2; if (x - arr[mid] > arr[mid + k] - x) lo = mid + 1; else hi = mid; } List<Integer> result = new ArrayList<>(); for(int i = lo; i < lo + k; i++) { result.add(arr[i]); } return result; } Time: O(logN)

Given a sorted array, two integers k and x, find the k closest elements to x in the array. The result should also be sorted in ascending order. If there is a tie, the smaller elements are always preferred. Example 1: Input: [1,2,3,4,5], k=4, x=3 Output: [1,2,3,4] Example 2: Input: [1,2,3,4,5], k=4, x=-1 Output: [1,2,3,4]

public boolean isSubsequence(String x, String y) { int j = 0; for (int i = 0; i < y.length() && j < x.length(); i++) if (x.charAt(j) == y.charAt(i)) j++; return j == x.length(); } public String findLongestWord(String s, List < String > d) { Collections.sort(d, new Comparator < String > () { public int compare(String s1, String s2) { return s2.length() != s1.length() ? s2.length() - s1.length() : s1.compareTo(s2); } }); for (String str: d) { if (isSubsequence(str, s)) return str; } return ""; }

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"

public boolean checkValidString(String s) { if (s == null || s.length() == 0) { return true; } return check(s, 0, 0); } public boolean check(String s, int pos, int count) { if (pos == s.length()) { if (count == 0) { return true; } return false; } if (count < 0) { return false; } if (s.charAt(pos) == '(') { return check(s, pos + 1, count + 1); } else if (s.charAt(pos) == ')') { return check(s, pos + 1, count - 1); } else { return check(s, pos + 1, count) || check(s, pos + 1, count - 1) || check(s, pos + 1, count + 1); } }

Given a string containing only three types of characters: '(', ')' and '*', write a function to check whether this string is valid. We define the validity of a string by these rules: Any left parenthesis '(' must have a corresponding right parenthesis ')'. Any right parenthesis ')' must have a corresponding left parenthesis '('. Left parenthesis '(' must go before the corresponding right parenthesis ')'. '*' could be treated as a single right parenthesis ')' or a single left parenthesis '(' or an empty string. An empty string is also valid. Example 1: Input: "()" Output: True Example 2: Input: "(*)" Output: True Example 3: Input: "(*))" Output: True

public int longestPalindromeSubseq(String s) { int lo = 0; int hi = s.length(); return longestPalindromeSubseqDP(s.toCharArray(), lo, hi - 1, new Integer[hi][hi]); } private int longestPalindromeSubseqDP(char[] seq, int i, int j, Integer[][] memo) { if(memo[i][j] != null) { return memo[i][j]; } if(i > j) return 0; // Base Case 1: If there is only 1 character if(i == j) return 1; // If the first and last characters match if (seq[i] == seq[j]) { memo[i][j] = longestPalindromeSubseqDP(seq, i + 1, j - 1, memo) + 2; } else { // If the first and last characters do not match memo[i][j] = Math.max(longestPalindromeSubseqDP(seq, i + 1, j, memo), longestPalindromeSubseqDP(seq, i, j - 1, memo)); } return memo[i][j]; }

Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000. Example 1: Input: "bbbab" Output: 4 One possible longest palindromic subsequence is "bbbb". Example 2: Input: "cbbd" Output: 2

class CharNum implements Comparable<CharNum> { char c; int num; public CharNum(char c, int n) { this.c = c; this.num = n; } public int compareTo(CharNum other) { return this.num != other.num ? other.num - this.num : this.c - other.c; } } public String frequencySort(String s) { if(s == null || "".equals(s)) return ""; Map<Character, CharNum> map = new HashMap<>(); for(int i = 0; i < s.length(); i++) { char c = s.charAt(i); if(map.containsKey(c)) { map.get(c).num += 1; } else { map.put(c, new CharNum(c, 1)); } } List<CharNum> list = new ArrayList<>(); for (Character key: map.keySet()) { list.add(map.get(key)); } Collections.sort(list); StringBuilder sb = new StringBuilder(); for(int i = 0; i < list.size(); i++) { int n = list.get(i).num; for(int j = 0; j < n; j++) { sb.append(list.get(i).c); } } return sb.toString(); }

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.

Idea is start from each index and try to extend palindrome for both odd and even length. int count = 0; public int countSubstrings(String s) { if (s == null || s.length() == 0) return 0; for (int i = 0; i < s.length(); i++) { // i is the mid point extendPalindrome(s, i, i); // odd length; extendPalindrome(s, i, i + 1); // even length } return count; } private void extendPalindrome(String s, int left, int right) { while (left >=0 && right < s.length() && s.charAt(left) == s.charAt(right)) { count++; left--; right++; } }

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".

public static int subarraySum(int[] nums, int k) { int sum = 0; int res = 0; Map<Integer, Integer> map = new HashMap<>(); map.put(0, 1); for (int i = 0; i < nums.length; i++) { sum += nums[i]; if (map.containsKey(sum - k)) { res += map.get(sum - k); System.out.println(res); } map.put(sum, map.getOrDefault(sum, 0) + 1); } return res; }

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].

// when find a number i, flip the number at position i-1 to negative. // if the number at position i-1 is already negative, i is the number that occurs twice. public List<Integer> findDuplicates(int[] nums) { List<Integer> res = new ArrayList<>(); for (int i = 0; i < nums.length; ++i) { int index = Math.abs(nums[i])-1; if (nums[index] < 0) res.add(Math.abs(index+1)); nums[index] = -nums[index]; } return res; }

Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. Find all the elements that appear twice in this array. Could you do it without extra space and in O(n) runtime? Example: Input: [4,3,2,7,8,2,3,1] Output: [2,3]

public TreeNode constructMaximumBinaryTree(int[] nums) { return construct(nums, 0, nums.length); } public TreeNode construct(int[] nums, int l, int r) { if (l == r) return null; int max_i = max(nums, l, r); TreeNode root = new TreeNode(nums[max_i]); root.left = construct(nums, l, max_i); root.right = construct(nums, max_i + 1, r); return root; } public int max(int[] nums, int l, int r) { int max_i = l; for (int i = l; i < r; i++) { if (nums[max_i] < nums[i]) max_i = i; } return max_i; } Time complexity : O(n^2)O(n ​2 ​​ ). The function construct is called nn times. At each level of the recursive tree, we traverse over all the nn elements to find the maximum element. In the average case, there will be a log(n)log(n) levels leading to a complexity of O\big(nlog(n)\big)O(nlog(n)). In the worst case, the depth of the recursive tree can grow upto nn, which happens in the case of a sorted numsnums array, giving a complexity of O(n^2)O(n ​2 ​​ ). Space complexity : O(n)O(n). The size of the setset can grow upto nn in the worst case. In the average case, the size will be log(n)log(n) for nn elements in numsnums, giving an average case complexity of O(log(n))O(log(n))

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

Either include current number to current collection or don't include. public List<List<Integer>> findSubsequences(int[] nums) { Set<List<Integer>> res= new HashSet<List<Integer>>(); List<Integer> holder = new ArrayList<Integer>(); findSequence(res, holder, 0, nums); List result = new ArrayList(res); return result; } public void findSequence(Set<List<Integer>> res, List<Integer> holder, int index, int[] nums) { if (holder.size() >= 2) { res.add(new ArrayList(holder)); } for (int i = index; i < nums.length; i++) { if(holder.size() == 0 || holder.get(holder.size() - 1) <= nums[i]) { holder.add(nums[i]); findSequence(res, holder, i + 1, nums); holder.remove(holder.size() - 1); } } }

Given an integer array, your task is to find all the different possible increasing subsequences of the given array, and the length of an increasing subsequence should be at least 2 . Example: Input: [4, 6, 7, 7] Output: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]] Note: The length of the given array will not exceed 15. The range of integer in the given array is [-100,100]. The given array may contain duplicates, and two equal integers should also be considered as a special case of increasing sequence.

class Solution { public String replaceWords(List<String> dict, String sentence) { String[] tokens = sentence.split(" "); TrieNode trie = buildTrie(dict); return replaceWords(tokens, trie); } private String replaceWords(String[] tokens, TrieNode root) { StringBuilder stringBuilder = new StringBuilder(); for (String token : tokens) { stringBuilder.append(getShortestReplacement(token, root)); stringBuilder.append(" "); } return stringBuilder.substring(0, stringBuilder.length()-1); } private String getShortestReplacement(String token, final TrieNode root) { TrieNode temp = root; StringBuilder stringBuilder = new StringBuilder(); for (char c : token.toCharArray()) { stringBuilder.append(c); if (temp.children[c - 'a'] != null) { if (temp.children[c - 'a'].isWord) { return stringBuilder.toString(); } temp = temp.children[c - 'a']; } else { return token; } } return token; } private TrieNode buildTrie(List<String> dict) { TrieNode root = new TrieNode(' '); for (String word : dict) { TrieNode temp = root; for (char c : word.toCharArray()) { if (temp.children[c - 'a'] == null) { temp.children[c - 'a'] = new TrieNode(c); } temp = temp.children[c - 'a']; } temp.isWord = true; } return root; } class TrieNode { char val; TrieNode[] children; boolean isWord; public TrieNode(char val) { this.val = val; this.children = new TrieNode[26]; this.isWord = false; } } }

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"

public TreeNode addOneRow(TreeNode root, int v, int d) { if(root == null) return new TreeNode(v); return addOneRowHelper(root, v, 1, d, 0); } //left=0 private TreeNode addOneRowHelper(TreeNode node,int v,int currDepth,int d,int lr){ if(node == null) { if(currDepth == d) return new TreeNode(v); return null; } if(currDepth == d){ TreeNode newNode = new TreeNode(v); if(lr == 0) newNode.left = node; else if(lr == 1) newNode.right = node; return newNode; } node.left = addOneRowHelper(node.left, v, currDepth + 1, d, 0); node.right = addOneRowHelper(node.right, v, currDepth + 1, d, 1); return node; }

Given the root of a binary tree, then value v and depth d, you need to add a row of nodes with value v at the given depth d. The root node is at depth 1. The adding rule is: given a positive integer depth d, for each NOT null tree nodes N in depth d-1, create two tree nodes with value v as N's left subtree root and right subtree root. And N's original left subtree should be the left subtree of the new left subtree root, its original right subtree should be the right subtree of the new right subtree root. If depth d is 1 that means there is no depth d-1 at all, then create a tree node with value v as the new root of the whole original tree, and the original tree is the new root's left subtree. Example 1: Input: A binary tree as following: 4 / \ 2 6 / \ / 3 1 5 v = 1 d = 2 Output: 4 / \ 1 1 / \ 2 6 / \ / 3 1 5

public int[] exclusiveTime(int n, List<String> logs) { Stack<Log> stack = new Stack<>(); int[] result = new int[n]; for (String content : logs) { Log log = new Log(content); if (log.isStart) { stack.push(log); } else { Log top = stack.pop(); result[top.id] += (log.time - top.time + 1); if (!stack.isEmpty()) { result[stack.peek().id] -= (log.time - top.time + 1); } } } return result; } public static class Log { public int id; public boolean isStart; public int time; public Log(String content) { String[] strs = content.split(":"); id = Integer.valueOf(strs[0]); isStart = strs[1].equals("start"); time = Integer.valueOf(strs[2]); } }

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.

In order to determine the minimum number of delete operations needed, we can make use of the length of the longest common sequence among the two given strings s1s1 and s2s2, say given by lcslcs. If we can find this lcslcs value, we can easily determine the required result as m + n - 2*lcsm+n−2∗lcs. Here, mm and nn refer to the length of the two given strings s1s1 and s2s2. The above equation works because in case of complete mismatch(i.e. if the two strings can't be equalized at all), the total number of delete operations required will be m + nm+n. Now, if there is a common sequence among the two strings of length lcslcs, we need to do lcslcs lesser deletions in both the strings leading to a total of 2lcs2lcs lesser deletions, which then leads to the above equation. public int minDistance(String s1, String s2) { return s1.length() + s2.length() - 2 * lcs(s1, s2, s1.length(), s2.length()); } public int lcs(String s1, String s2, int m, int n) { if (m == 0 || n == 0) return 0; if (s1.charAt(m - 1) == s2.charAt(n - 1)) return 1 + lcs(s1, s2, m - 1, n - 1); else return Math.max(lcs(s1, s2, m, n - 1), lcs(s1, s2, m - 1, n)); } Use memoization for better time complexity

Given two words word1 and word2, find the minimum number of steps required to make word1 and word2 the same, where in each step you can delete one character in either string. Example 1: Input: "sea", "eat" Output: 2 Explanation: You need one step to make "sea" to "ea" and another step to make "eat" to "ea". Note: The length of given words won't exceed 500. Characters in given words can only be lower-case letters.

Evidently, two events [s1, e1) and [s2, e2) do not conflict if and only if one of them starts after the other one ends: either e1 <= s2 OR e2 <= s1. By De Morgan's laws, this means the events conflict when s1 < e2 AND s2 < e1. If our event conflicts with a double booking, it's invalid. Otherwise, we add conflicts with the calendar to our double bookings, and add the event to our calendar. List<int[]> calendar; List<int[]> overlaps; MyCalendarTwo() { calendar = new ArrayList(); } public boolean book(int start, int end) { for (int[] iv: overlaps) { if (iv[0] < end && start < iv[1]) return false; } for (int[] iv: calendar) { if (iv[0] < end && start < iv[1]) overlaps.add(new int[]{Math.max(start, iv[0]), Math.min(end, iv[1])}); } calendar.add(new int[]{start, end}); return true; }

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.

In every call of the function shopping(price,special,needs), we do as follows: Determine the cost of buying items as per the needsneeds array, without applying any offer. Store the result in resres. Iterate over every offer in the specialspecial list. For every offer chosen, repeat steps 3 to 5. Create a copy of the current needsneeds in a cloneclone list(so that the original needs can be used again, while selecting the next offer). Try to apply the current offer. If possible, update the required number of items in cloneclone. If the current offer could be applied, find the minimum cost out of resres and 𝑜𝑓𝑓𝑒𝑟\current + shopping(price,special,clone). Here, 𝑜𝑓𝑓𝑒𝑟\current refers to the price that needs to be paid for the current offer. Update the resres with the minimum value. Return the resres corresponding to the minimum cost. public int shoppingOffers(List < Integer > price, List < List < Integer >> special, List < Integer > needs) { return shopping(price, special, needs); } public int shopping(List < Integer > price, List < List < Integer >> special, List < Integer > needs) { int j = 0, res = dot(needs, price); for (List < Integer > s: special) { ArrayList < Integer > clone = new ArrayList < > (needs); for (j = 0; j < needs.size(); j++) { int diff = clone.get(j) - s.get(j); if (diff < 0) break; clone.set(j, diff); } if (j == needs.size()) res = Math.min(res, s.get(j) + shopping(price, special, clone)); } return res; } public int dot(List < Integer > a, List < Integer > b) { int sum = 0; for (int i = 0; i < a.size(); i++) { sum += a.get(i) * b.get(i); } return sum; } Further, memoize if necessary.

In LeetCode Store, there are some kinds of items to sell. Each item has a price. However, there are some special offers, and a special offer consists of one or more different kinds of items with a sale price. You are given the each item's price, a set of special offers, and the number we need to buy for each item. The job is to output the lowest price you have to pay for exactly certain items as given, where you could make optimal use of the special offers. Each special offer is represented in the form of an array, the last number represents the price you need to pay for this special offer, other numbers represents how many specific items you could get if you buy this offer. You could use any of special offers as many times as you want. Example 1: Input: [2,5], [[3,0,5],[1,2,10]], [3,2] Output: 14 Explanation: There are two kinds of items, A and B. Their prices are $2 and $5 respectively. In special offer 1, you can pay $5 for 3A and 0B In special offer 2, you can pay $10 for 1A and 2B. You need to buy 3A and 2B, so you may pay $10 for 1A and 2B (special offer #2), and $4 for 2A. Example 2: Input: [2,3,4], [[1,1,0,4],[2,2,1,9]], [1,2,1] Output: 11 Explanation: The price of A is $2, and $3 for B, $4 for C. You may pay $4 for 1A and 1B, and $9 for 2A ,2B and 1C. You need to buy 1A ,2B and 1C, so you may pay $4 for 1A and 1B (special offer #1), and $3 for 1B, $4 for 1C. You cannot add more items, though only $9 for 2A ,2B and 1C.

private List<Integer> idx = new ArrayList<>(); public int[] findRedundantConnection(int[][] edges) { for (int i = 0; i <= edges.length; i++) idx.add(i, i); for (int[] edge: edges){ int f = edge[0], t = edge[1]; int fId = find(f); int tId = find(t); if (fId == tId) return edge; else idx.set(fId, tId); } return new int[2]; } private int find(int f) { while (f != idx.get(f)) { f = idx.get(f); } return f; }

In this problem, a tree is an undirected graph that is connected and has no cycles. The given input is a graph that started as a tree with N nodes (with distinct values 1, 2, ..., N), with one additional edge added. The added edge has two different vertices chosen from 1 to N, and was not an edge that already existed. The resulting graph is given as a 2D-array of edges. Each element of edges is a pair [u, v] with u < v, that represents an undirected edge connecting nodes u and v. Return an edge that can be removed so that the resulting graph is a tree of N nodes. If there are multiple answers, return the answer that occurs last in the given 2D-array. The answer edge [u, v] should be in the same format, with u < v. Example 1: Input: [[1,2], [1,3], [2,3]] Output: [2,3] Explanation: The given undirected graph will be like this: 1 / \ 2 - 3 Example 2: Input: [[1,2], [2,3], [3,4], [1,4], [1,5]] Output: [1,4] Explanation: The given undirected graph will be like this: 5 - 1 - 2 | | 4 - 3

public class Codec { // Encodes a tree to a single string. public String serialize(TreeNode root) { StringBuilder sb = new StringBuilder(); serialize(root, sb); return sb.toString(); } private void serialize(TreeNode root, StringBuilder sb) { if(root == null) { sb.append("X").append(","); return; } sb.append(root.val); sb.append(","); serialize(root.left, sb); serialize(root.right, sb); } // Decodes your encoded data to tree. public TreeNode deserialize(String data) { if(data == null || "".equals(data)) return null; String[] vals = data.split(","); Queue<String> queue = new LinkedList<>(); queue.addAll(Arrays.asList(vals)); return deserialize(queue); } private TreeNode deserialize(Queue<String> queue) { String node = queue.poll(); if(node.equals("X")) { return null; } TreeNode root = new TreeNode(Integer.valueOf(node)); root.left = deserialize(queue); root.right = deserialize(queue); return root; } }

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 search tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary search tree can be serialized to a string and this string can be deserialized to the original tree structure. The encoded string should be as compact as possible. Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.

public String solveEquation(String equation) { String[] parts = equation.split("="); String leftPart = parts[0], rightPart = parts[1]; int[] leftVals = evaluate(leftPart), rightVals = evaluate(rightPart); int cntX = leftVals[0] - rightVals[0]; int cntNum = leftVals[1] - rightVals[1]; if (cntX == 0) { if (cntNum != 0) return "No solution"; return "Infinite solutions"; } int valX = (-cntNum) / cntX; StringBuilder result = new StringBuilder(); result.append("x=").append(valX); return result.toString(); } private int[] evaluate(String exp) { int[] result = new int[2]; // exp.split(""); split exp by 0-length string ("a+b-c" to "a", "+", "b", "-", "c") // exp.split("(?=[-+])");split exp by 0-length string only if they are follow by "-" or "+" ("a+b-c" to "a", "+b", "-c") String[] expElements = exp.split("(?=[-+])"); for (String ele : expElements) { if (ele.equals("+x") || ele.equals("x")) { result[0]++; } else if (ele.equals("-x")) { result[0]--; } else if (ele.contains("x")) { result[0] += Integer.valueOf(ele.substring(0, ele.indexOf("x"))); } else { result[1] += Integer.valueOf(ele); } } return result; }

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"

public int findMin(int[] nums) { int lo = 0; int hi = nums.length - 1; while(lo < hi - 1) { int mid = lo + (hi - lo) / 2; if(nums[mid] > nums[hi]) { lo = mid; } else { hi = mid; } } return Math.min(nums[lo], nums[hi]); }

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. Example 1: Input: [3,4,5,1,2] Output: 1 Example 2: Input: [4,5,6,7,0,1,2] Output: 0

int findBusiestPeriod(int[][] data) { if(data == null || data.length == 0) return -1; int maxTime = data[0][0]; int maxPeople = -1; int currTime = data[0][0]; int currPeople = data[0][2] == 1? data[0][1] : -data[0][1]; for(int i = 1; i < data.length; i++) { int p = data[i][2] == 1 ? data[i][1] : -data[i][1]; if(currTime == data[i][0]) { currPeople += p; } else { if(currPeople > maxPeople) { maxPeople = currPeople; maxTime = currTime; } currPeople += p; currTime = data[i][0]; } } if(currPeople > maxPeople) { maxPeople = currPeople; maxTime = currTime; } return maxTime; }

The Westfield Mall management is trying to figure out what the busiest moment at the mall was last year. You're given data extracted from the mall's door detectors. Each data point is represented as an integer array whose size is 3. The values at indices 0, 1 and 2 are the timestamp, the count of visitors, and whether the visitors entered or exited the mall (0 for exit and 1 for entrance), respectively. Here's an example of a data point: [ 1440084737, 4, 0 ]. Note that time is given in a Unix format called Epoch, which is a nonnegative integer holding the number of seconds that have elapsed since 00:00:00 UTC, Thursday, 1 January 1970. Given an array, data, of data points, write a function findBusiestPeriod that returns the time at which the mall reached its busiest moment last year. The return value is the timestamp, e.g. 1480640292. Note that if there is more than one period with the same visitor peak, return the earliest one. Assume that the array data is sorted in an ascending order by the timestamp. Explain your solution and analyze its time and space complexities. Example: input: data = [ [1487799425, 14, 1], [1487799425, 4, 0], [1487799425, 2, 0], [1487800378, 10, 1], [1487801478, 18, 0], [1487801478, 18, 1], [1487901013, 1, 0], [1487901211, 7, 1], [1487901211, 7, 0] ] output: 1487800378 # since the increase in the number of people # in the mall is the highest at that point

private List<Integer> idx = new ArrayList<>(); public int findCircleNum(int[][] M) { for(int i = 0; i < M.length; i++) { idx.add(i, i); } for(int i = 0; i < M.length; i++) { for(int j = 0; j < M[0].length; j++) { if(M[i][j] == 1){ union(i, j); } } } int count = 0; for(int i = 0; i < M.length; i++) { if(idx.get(i) == i) count++; } return count; } // quick union algorithm private int find(int i) { if(idx.get(i) == i) { return i; } while(i != idx.get(i)) { i = idx.get(i); } return i; } private void union(int i, int j) { int iId = find(i); int jId = find(j); if(iId == jId) return; idx.set(iId, jId); }

There are N students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a direct friend of B, and B is a direct friend of C, then A is an indirect friend of C. And we defined a friend circle is a group of students who are direct or indirect friends. Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] = 1, then the ith and jth students are direct friends with each other, otherwise not. And you have to output the total number of friend circles among all the students. Example 1: Input: [[1,1,0], [1,1,0], [0,0,1]] Output: 2 Explanation:The 0th and 1st students are direct friends, so they are in a friend circle. The 2nd student himself is in a friend circle. So return 2. Example 2: Input: [[1,1,0], [1,1,1], [0,1,1]] Output: 1 Explanation:The 0th and 1st students are direct friends, the 1st and 2nd students are direct friends, so the 0th and 2nd students are indirect friends. All of them are in the same friend circle, so return 1.

for every row, whenever add a brick, record the end position as +1. goal is to find the position where most row have a break on that position. public int leastBricks(List<List<Integer>> wall) { Map<Integer, Integer> ends = new HashMap<Integer, Integer>(); int maxend = 0; for (int i = 0; i < wall.size(); i++) { int sum = 0; for (int j = 0; j + 1 < wall.get(i).size(); j++) { sum += wall.get(i).get(j); ends.put(sum, ends.getOrDefault(sum, 0) + 1); maxend = Math.max(maxend, ends.get(sum)); } } return wall.size() - maxend; }

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

public int[] asteroidCollision(int[] asteroids) { Stack<Integer> stack = new Stack<>(); for (int i : asteroids) { if (i > 0) stack.add(i); else { while (!stack.isEmpty() && stack.peek() > 0 && stack.peek() < -i) stack.pop(); if (!stack.isEmpty() && stack.peek() == -i) stack.pop(); else if (stack.isEmpty() || stack.peek() < 0) stack.add(i); } } return stack.stream().mapToInt(i->i).toArray(); }

We are given an array asteroids of integers representing asteroids in a row. For each asteroid, the absolute value represents its size, and the sign represents its direction (positive meaning right, negative meaning left). Each asteroid moves at the same speed. Find out the state of the asteroids after all collisions. If two asteroids meet, the smaller one will explode. If both are the same size, both will explode. Two asteroids moving in the same direction will never meet. Example 1: Input: asteroids = [5, 10, -5] Output: [5, 10] Explanation: The 10 and -5 collide resulting in 10. The 5 and 10 never collide.

public TreeNode pruneTree(TreeNode root) { return containsOne(root) ? root : null; } public boolean containsOne(TreeNode node) { if (node == null) return false; boolean a1 = containsOne(node.left); boolean a2 = containsOne(node.right); if (!a1) node.left = null; if (!a2) node.right = null; return node.val == 1 || a1 || a2; }

We are given the head node root of a binary tree, where additionally every node's value is either a 0 or a 1. Return the same tree where every subtree (of the given tree) not containing a 1 has been removed. (Recall that the subtree of a node X is X, plus every node that is a descendant of X.) Example 1: Input: [1,null,0,0,1] Output: [1,null,0,null,1] Explanation: Only the red nodes satisfy the property "every subtree not containing a 1". The diagram on the right represents the answer.

public String validIPAddress(String IP) { if(IP.contains(".") && validIPv4(IP.split("\\.", -1))) { return "IPv4"; } else if(IP.contains(":") && validIPv6(IP.split(":", -1))) { return "IPv6"; } return "Neither"; } private boolean validIPv4(String[] IP) { if(IP.length != 4) return false; for(int i = 0; i < IP.length; i++) { try { if(Integer.parseInt(IP[i]) < 0 || Integer.parseInt(IP[i]) > 255) { return false; } if (IP[i].length() > 1 && (IP[i].charAt(0) <= '0' || IP[i].charAt(0) > '9')) { return false; } } catch(Exception e) { return false; } } return true; } private boolean validIPv6(String[] IP) { if(IP.length != 8) return false; for(int i = 0; i < IP.length; i++) { try { if(IP[i].length() <= 0 || IP[i].length() > 4 || IP[i].charAt(0) == '-' || IP[i].charAt(0) == '+') { return false; } long num = Long.parseLong(IP[i], 16); } catch(Exception e) { return false; } } return true; }

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".

1. We iterate through the array once to get the frequency of all the elements in the array 2. We iterate through the array once more and for each element we either see if it can be appended to a previously constructed consecutive sequence or if it can be the start of a new consecutive sequence. If neither are true, then we return false. public boolean isPossible(int[] nums) { Map<Integer, Integer> freq = new HashMap<>(), appendFreq = new HashMap<>(); for (int i : nums) freq.put(i, freq.getOrDefault(i, 0) + 1); for (int i : nums) { if (freq.get(i) == 0) continue; else if (appendFreq.getOrDefault(i,0) > 0) { appendFreq.put(i, appendFreq.get(i) - 1); appendFreq.put(i+1, appendFreq.getOrDefault(i+1, 0) + 1); } else if (freq.getOrDefault(i+1,0) > 0 && freq.getOrDefault(i+2,0) > 0) { freq.put(i+1, freq.get(i+1) - 1); freq.put(i+2, freq.get(i+2) - 1); appendFreq.put(i+3, appendFreq.getOrDefault(i+3, 0) + 1); } else return false; freq.put(i, freq.get(i) - 1); } return true; }

You are given an integer array sorted in ascending order (may contain duplicates), you need to split them into several subsequences, where each subsequences consist of at least 3 consecutive integers. Return whether you can make such a split. Example 1: Input: [1,2,3,3,4,5] Output: True Explanation: You can split them into two consecutive subsequences : 1, 2, 3 3, 4, 5 Example 2: Input: [1,2,3,3,4,4,5,5] Output: True Explanation: You can split them into two consecutive subsequences : 1, 2, 3, 4, 5 3, 4, 5 Example 3: Input: [1,2,3,4,4,5] Output: False

If the amount is 0 we have one way to make (using no coins). For each coin we add up the number of ways to make change (1 to amount) by adding the amount of ways for the amount - the coin value which was computed in the past. public int change(int amount, int[] coins) { int [] ways = new int[amount + 1]; ways[0] = 1; for(int val : coins){ for(int i = val; i <= amount; ++i){ ways[i] += ways[i - val]; } } return ways[amount]; }

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

similar to Longest Increasing Subsequence public int findLongestChain(int[][] pairs) { Arrays.sort(pairs, (a, b)-> { return Integer.compare(a[1], b[1]); }); int n = pairs.length; int[] lis = new int[n]; Arrays.fill(lis, 1); int max_len = 1; for(int i = 0; i < n; i++) { for(int j = i+1; j < n; j++) { if(pairs[j][0] > pairs[i][1]) { lis[j] = Math.max(lis[i]+1,lis[j]); max_len = Math.max(max_len,lis[j]); } } } return max_len; }

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].

public List<Integer> largestValues(TreeNode root) { List<Integer> result = new ArrayList<>(); if(root == null) return result; Queue<TreeNode> toExplore = new LinkedList<>(); toExplore.add(root); while(!toExplore.isEmpty()) { int size = toExplore.size(); int max = toExplore.peek().val; while(size-- > 0) { TreeNode curr = toExplore.poll(); if(max < curr.val) max = curr.val; if(curr.left != null) { toExplore.add(curr.left); } if(curr.right != null) { toExplore.add(curr.right); } } result.add(max); } return result; }

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]

To transition from the i-th day to the i+1-th day, we either sell our stock cash = max(cash, hold + prices[i] - fee) or buy a stock hold = max(hold, cash - prices[i]). At the end, we want to return cash. public int maxProfit(int[] prices, int fee) { int cash = 0, hold = -prices[0]; for (int i = 1; i < prices.length; i++) { cash = Math.max(cash, hold + prices[i] - fee); hold = Math.max(hold, cash - prices[i]); } return cash; }

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.

/** * The idea is always keep an max-product-window less than K; * Every time add a new number on the right(j), reduce numbers on the left(i), until the subarray product fit less than k again, (subarray could be empty); * Each step introduces x new subarrays, where x is the size of the current window (j + 1 - i); * example: * for window (5, 2, 6), when 6 is introduced, it add 3 new subarray: * (6) * (2, 6) * (5, 2, 6) */ public int numSubarrayProductLessThanK(int[] nums, int k) { if (k == 0) return 0; int cnt = 0; int pro = 1; for (int i = 0, j = 0; j < nums.length; j++) { pro *= nums[j]; while (i <= j && pro >= k) { pro /= nums[i++]; } cnt += j - i + 1; } return cnt; }

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.

class GeneNode { String gene; int numOfSteps; public GeneNode(String gene, int steps) { this.gene = gene; this.numOfSteps = steps; } } public int minMutation(String start, String end, String[] bank) { if(bank == null || bank.length == 0) return -1; if(start == end) return 0; char[] geneSet = {'A', 'C', 'G', 'T'}; Set<String> bankSet = new HashSet<>(Arrays.asList(bank)); Queue<GeneNode> toExplore = new LinkedList<>(); toExplore.add(new GeneNode(start, 0)); while(!toExplore.isEmpty()) { GeneNode curr = toExplore.poll(); if(curr.gene.equals(end)) { return curr.numOfSteps; } char[] word = curr.gene.toCharArray(); for(int i = 0; i < word.length; i++) { for(int j = 0; j < geneSet.length; j++) { char tmp = word[i]; if(word[i] != geneSet[j]) { word[i] = geneSet[j]; } String needle = new String(word); if(bankSet.contains(needle)) { toExplore.add(new GeneNode(needle, curr.numOfSteps + 1)); bankSet.remove(needle); } word[i] = tmp; } } } return -1; }

A gene string can be represented by an 8-character long string, with choices from "A", "C", "G", "T". Suppose we need to investigate about a mutation (mutation from "start" to "end"), where ONE mutation is defined as ONE single character changed in the gene string. For example, "AACCGGTT" -> "AACCGGTA" is 1 mutation. Also, there is a given gene "bank", which records all the valid gene mutations. A gene must be in the bank to make it a valid gene string. Now, given 3 things - start, end, bank, your task is to determine what is the minimum number of mutations needed to mutate from "start" to "end". If there is no such a mutation, return -1. Note: Starting point is assumed to be valid, so it might not be included in the bank. If multiple mutations are needed, all mutations during in the sequence must be valid. You may assume start and end string is not the same. Example 1: start: "AACCGGTT" end: "AACCGGTA" bank: ["AACCGGTA"] return: 1 Example 2: start: "AACCGGTT" end: "AAACGGTA" bank: ["AACCGGTA", "AACCGCTA", "AAACGGTA"] return: 2

public RandomListNode copyRandomList(RandomListNode head) { if(head == null) return null; Map<RandomListNode, RandomListNode> map = new HashMap<>(); RandomListNode curr = head; while(curr != null) { map.put(curr, new RandomListNode(curr.label)); curr = curr.next; } for(Map.Entry<RandomListNode, RandomListNode> entry : map.entrySet()) { RandomListNode tmp = entry.getValue(); tmp.next = map.get(entry.getKey().next); tmp.random = map.get(entry.getKey().random); } return map.get(head); }

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 int findPeakElement(int[] nums) { if(nums.length <= 1) return 0; int peak = 0; for(int i = 0; i < nums.length; i++) { if(isPeak(nums, i)) { peak = i; } } return peak; } private boolean isPeak(int[] nums, int curr) { if(curr == 0) { return nums[curr] > nums[curr + 1]; } else if(curr == nums.length - 1) { return nums[curr] > nums[curr - 1]; } else { return nums[curr] > nums[curr - 1] && nums[curr] > nums[curr + 1]; } }

A peak element is an element that is greater than its neighbors. Given an input array nums, where nums[i] ≠ nums[i+1], find a peak element and return its index. The array may contain multiple peaks, in that case return the index to any one of the peaks is fine. You may imagine that nums[-1] = nums[n] = -∞. Example 1: Input: nums = [1,2,3,1] Output: 2 Explanation: 3 is a peak element and your function should return the index number 2.

public int uniquePaths(int m, int n) { // recursion //if(m <= 0 || n <= 0) return 0; //if(m == 1 || n == 1) return 1; //return uniquePaths(m - 1, n) + uniquePaths(m, n - 1); int[][] dp = new int[m][n]; for(int i = 0; i < m; i++) { dp[i][0] = 1; } for(int j = 0; j < n; j++) { dp[0][j] = 1; } for(int i = 1; i < m; i++) { for(int j = 1; j < n; j++) { dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; } } return dp[m - 1][n - 1]; }

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). How many possible unique paths are there? Note: m and n will be at most 100. Example 1: Input: m = 3, n = 2 Output: 3 Explanation: From the top-left corner, there are a total of 3 ways to reach the bottom-right corner: 1. Right -> Right -> Down 2. Right -> Down -> Right 3. Down -> Right -> Right

public int uniquePathsWithObstacles(int[][] obstacleGrid) { int m = obstacleGrid.length; int n = obstacleGrid[0].length; int[][] dp = new int[m][n]; for(int i = 0; i < m && obstacleGrid[i][0] != 1; i++) { dp[i][0] = 1; } for(int j = 0; j < n && obstacleGrid[0][j] != 1; j++) { dp[0][j] = 1; } for(int i = 1; i < m; i++) { for(int j = 1; j < n; j++) { if(obstacleGrid[i][j] != 1) { dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; } } } return dp[m - 1][n - 1]; }

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). Now consider if some obstacles are added to the grids. How many unique paths would there be? An obstacle and empty space is marked as 1 and 0 respectively in the grid. Note: m and n will be at most 100. Example 1: Input: [ [0,0,0], [0,1,0], [0,0,0] ] Output: 2 Explanation: There is one obstacle in the middle of the 3x3 grid above. There are two ways to reach the bottom-right corner: 1. Right -> Right -> Down -> Down 2. Down -> Down -> Right -> Right

public List<String> findRepeatedDnaSequences(String s) { Map<String, Integer> map = new HashMap<>(); List<String> result = new ArrayList<>(); for(int i = 0; i + 10 < s.length(); i++) { String needle = s.substring(i, i + 10); if(map.containsKey(needle)) { map.put(needle, map.get(needle) + 1); } else { map.put(needle, 1); } } for(Map.Entry<String, Integer> entry : map.entrySet()) { if(entry.getValue() > 1) { result.add(entry.getKey()); } } return result; }

All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA. Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule. Example: Input: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT" Output: ["AAAAACCCCC", "CCCCCAAAAA"]

public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { if(node == null) return null; Map<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap(); // origin node : copied node UndirectedGraphNode myNode = new UndirectedGraphNode(node.label); // copy map.put(node, myNode); Queue<UndirectedGraphNode> q = new LinkedList(); // origin nodes q.add(node); // bfs traverse graph while (!q.isEmpty()) { UndirectedGraphNode cur = q.poll(); // all neighbors of current origin node for (UndirectedGraphNode neighbor : cur.neighbors) { // if the origin node is not visited if (!map.containsKey(neighbor)) { map.put(neighbor, new UndirectedGraphNode(neighbor.label)); // to avoid loop, we just add the unvisited node to queue q.offer(neighbor); } // add neighbors to the copied node // copied node: map.get(cur) -> copied node of cur // neighbors: map.get(neighbor) -> copied node of neighbor map.get(cur).neighbors.add(map.get(neighbor)); } } return myNode; }

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 / \ \_/

public int compareVersion(String version1, String version2) { String[] v1 = version1.split("\\."); String[] v2 = version2.split("\\."); int i = 0; while (i < Math.min(v1.length, v2.length)) { if (Integer.parseInt(v1[i]) < Integer.parseInt(v2[i])) { return -1; } else if (Integer.parseInt(v1[i]) > Integer.parseInt(v2[i])) { return 1; } else { i++; } } while (i < v1.length) { if (Integer.parseInt(v1[i]) > 0) { return 1; } else { i++; } } while (i < v2.length) { if (Integer.parseInt(v2[i]) > 0) { return -1; } else { i++; } } return 0; }

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. Example 1: Input: version1 = "0.1", version2 = "1.1" Output: -1 Example 2: Input: version1 = "1.0.1", version2 = "1" Output: 1 Example 3: Input: version1 = "7.5.2.4", version2 = "7.5.3" Output: -1

class WordDictionary { private class TrieNode { Map<Character, TrieNode> children; boolean endOfWord; public TrieNode() { children = new HashMap<>(); endOfWord = false; } } private TrieNode root; /** Initialize your data structure here. */ public WordDictionary() { root = new TrieNode(); } /** Adds a word into the data structure. */ public void addWord(String word) { TrieNode curr = root; for(int i = 0; i < word.length(); i++) { char c = word.charAt(i); TrieNode node = curr.children.get(c); if(node == null) { node = new TrieNode(); curr.children.put(c, node); } curr = node; } curr.endOfWord = true; } /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ public boolean search(String word) { return search(word, 0, root); } private boolean search(String word, int index, TrieNode node) { if(index == word.length()) return node.endOfWord; char c = word.charAt(index); if(c != '.') { return node.children.get(c) != null && search(word, index + 1, node.children.get(c)); } else { for(char i = 'a'; i <= 'z'; i++) { if(node.children.get(i) != null && search(word, index + 1, node.children.get(i))) return true; } } return false; } }

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. 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.

public boolean isValidSudoku(char[][] board) { Set<String> set = new HashSet<>(); for (int row = 0; row < board.length; row++) { for (int col = 0; col < board[row].length; col++) { char val = board[row][col]; if (val != '.') { int block = (row / 3 * 3) + (col / 3); if (set.contains("r" + row + val) || set.contains("c" + col + val) || set.contains("b" + block + val)) return false; else { set.add("r" + row + val); set.add("c" + col + val); set.add("b" + block + val); } } } } return true; }

Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules: Each row must contain the digits 1-9 without repetition. Each column must contain the digits 1-9 without repetition. Each of the 9 3x3 sub-boxes of the grid must contain the digits 1-9 without repetition. A partially filled sudoku which is valid. The Sudoku board could be partially filled, where empty cells are filled with the character '.'. Example 1: Input: [ ["5","3",".",".","7",".",".",".","."], ["6",".",".","1","9","5",".",".","."], [".","9","8",".",".",".",".","6","."], ["8",".",".",".","6",".",".",".","3"], ["4",".",".","8",".","3",".",".","1"], ["7",".",".",".","2",".",".",".","6"], [".","6",".",".",".",".","2","8","."], [".",".",".","4","1","9",".",".","5"], [".",".",".",".","8",".",".","7","9"] ] Output: true

public List<List<Integer>> combinationSum3(int k, int n) { if (k == 0 || n < 1) { return new ArrayList<>(); } List<List<Integer>> ans = new ArrayList<>(); int[] nums = {1, 2, 3, 4, 5, 6, 7, 8, 9}; helper(k, n, ans, new ArrayList<>(), 0, 0, nums); return ans; } public void helper(int k, int n, List<List<Integer>> ans, List<Integer> list, int sum, int pos, int[] nums) { if (sum > n) { return; } if (list.size() == k) { if (sum == n) { ans.add(new ArrayList<>(list)); } return; } for (int i = pos; i < nums.length; i++) { sum += nums[i]; list.add(nums[i]); helper(k, n, ans, list, sum, i + 1, nums); sum -= nums[i]; list.remove(list.size() - 1); } }

Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers. Note: All numbers will be positive integers. The solution set must not contain duplicate combinations. Example 1: Input: k = 3, n = 7 Output: [[1,2,4]] Example 2: Input: k = 3, n = 9 Output: [[1,2,6], [1,3,5], [2,3,4]]

public int maximalSquare(char[][] matrix) { if (matrix.length == 0) return 0; int[][] dp = new int[matrix.length][matrix[0].length]; int max = 0; for (int i = matrix.length - 1; i >= 0; i--) { for (int j = matrix[0].length - 1; j >= 0; j--) { if (matrix[i][j] == '0') { dp[i][j] = 0; } else if (i == matrix.length - 1 || j == matrix[0].length - 1) { dp[i][j] = 1; } else { dp[i][j] = Math.min(Math.min(dp[i + 1][j], dp[i][j + 1]), dp[i + 1][j + 1]) + 1; } max = Math.max(dp[i][j], max); } } return max * max; }

Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area. Example: Input: 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 Output: 4

The basic idea of the following solution is merging adjacent lands, and the merging should be done recursively. Each element is visited once only. So time is O(m*n). public int numIslands(char[][] grid) { if(grid==null || grid.length==0||grid[0].length==0) return 0; int m = grid.length; int n = grid[0].length; int count=0; for(int i=0; i<m; i++){ for(int j=0; j<n; j++){ if(grid[i][j]=='1'){ count++; merge(grid, i, j); } } } return count; } public void merge(char[][] grid, int i, int j){ int m=grid.length; int n=grid[0].length; if(i<0||i>=m||j<0||j>=n||grid[i][j]!='1') return; grid[i][j]='X'; merge(grid, i-1, j); merge(grid, i+1, j); merge(grid, i, j-1); merge(grid, i, j+1); }

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: Input: 11110 11010 11000 00000 Output: 1

public int kthSmallest(TreeNode root, int k) { if(root == null) return -1; List<Integer> resultList = new ArrayList<>(); inOrder(root, k, resultList); return resultList.get(k - 1); } public void inOrder(TreeNode root, int k, List<Integer> list) { if(root == null) return; inOrder(root.left, k, list); if(list.size() == k) return; list.add(root.val); inOrder(root.right, k, list); }

Given a binary search tree, write a function kthSmallest to find the kth smallest element in it. Note: You may assume k is always valid, 1 ≤ k ≤ BST's total elements. Example 1: Input: root = [3,1,4,null,2], k = 1 3 / \ 1 4 \ 2 Output: 1

public void connect(TreeLinkNode root) { if(root == null) return; connectNodes(root, null); } private void connectNodes(TreeLinkNode root, TreeLinkNode nextNode) { if(root == null) return; root.next = nextNode; connectNodes(root.left, root.right); if(root.next != null) { connectNodes(root.right, root.next.left); } else { connectNodes(root.right, null); } }

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. Recursive approach is fine, implicit stack space does not count as extra space for this problem. You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children). 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

public List<List<Integer>> pathSum(TreeNode root, int sum) { List<List<Integer>> result = new ArrayList<>(); List<Integer> currList = new ArrayList<>(); if(root == null) return result; pathSum(root, sum, result, currList); return result; } private void pathSum(TreeNode root, int sum, List<List<Integer>> result, List<Integer> currList) { if(root == null) { return; } if(root.left == null && root.right == null) { if(root.val == sum) { currList.add(root.val); result.add(new ArrayList<>(currList)); currList.remove(currList.size() - 1); } } currList.add(root.val); pathSum(root.left, sum - root.val, result, currList); pathSum(root.right, sum - root.val, result, currList); currList.remove(currList.size() - 1); }

Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum. Note: A leaf is a node with no children. Example: Given the below binary tree and sum = 22, 5 / \ 4 8 / / \ 11 13 4 / \ / \ 7 2 5 1 Return: [ [5,4,11,2], [5,8,4,5] ]

Idea is to do a level order traversal and in each step pass along the ((parent x 10) + child ) as the current value. If it ends up being a leaf node add it to the sum. public int sumNumbers(TreeNode root) { if(root==null) return 0; Queue<TreeNode> q = new LinkedList<>(); q.add(root); int sum=0; while(!q.isEmpty()){ TreeNode node = q.poll(); int current = node.val; if(node.left==null && node.right==null) sum+=current; if(node.left!=null){ node.left.val = current*10+node.left.val; q.add(node.left); } if(node.right!=null){ node.right.val = current*10+node.right.val; q.add(node.right); } } return sum; }

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. An example is the root-to-leaf path 1->2->3 which represents the number 123. Find the total sum of all root-to-leaf numbers. Note: A leaf is a node with no children. Example: Input: [1,2,3] 1 / \ 2 3 Output: 25 Explanation: The root-to-leaf path 1->2 represents the number 12. The root-to-leaf path 1->3 represents the number 13. Therefore, sum = 12 + 13 = 25.

private TreeNode prev = null; public void flatten(TreeNode root) { if (root == null) return; flatten(root.right); flatten(root.left); root.right = prev; root.left = null; prev = root; }

Given a binary tree, flatten it to a linked list in-place. For example, given the following tree: 1 / \ 2 5 / \ \ 3 4 6 The flattened tree should look like: 1 \ 2 \ 3 \ 4 \ 5 \ 6

public List<Integer> rightSideView(TreeNode root) { List<Integer> res = new ArrayList<>(); helper(root,0,res); return res; } void helper(TreeNode rt, int h, List<Integer> res){ if(rt == null) return; if(h >= res.size()) res.add(rt.val); helper(rt.right, h+1,res); helper(rt.left, h+1,res); }

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. Example: Input: [1,2,3,null,5,null,4] Output: [1, 3, 4] Explanation: 1 <--- / \ 2 3 <--- \ \ 5 4 <---

public List<Integer> preorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>(); preorderTraversal(root, result); return result; } // private void preorderTraversal(TreeNode root, List<Integer> result) { // if(root == null) return; // result.add(root.val); // preorderTraversal(root.left, result); // preorderTraversal(root.right, result); // } private void preorderTraversal(TreeNode root, List<Integer> result) { Stack<TreeNode> stack = new Stack<>(); stack.push(root); while (!stack.isEmpty()) { TreeNode current = stack.pop(); if (current == null) continue; result.add(current.val); stack.push(current.right); stack.push(current.left); } }

Given a binary tree, return the preorder traversal of its nodes' values. Example: Input: [1,null,2,3] 1 \ 2 / 3 Output: [1,2,3] Follow up: Recursive solution is trivial, could you do it iteratively?

public List<List<Integer>> combinationSum2(int[] nums, int target) { List<List<Integer>> list = new ArrayList<>(); Arrays.sort(nums); backtrack(list, new ArrayList<>(), nums, target, 0); return list; } private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){ if(remain < 0) return; else if(remain == 0) list.add(new ArrayList<>(tempList)); else{ for(int i = start; i < nums.length; i++){ if(i > start && nums[i] == nums[i-1]) continue; // skip duplicates tempList.add(nums[i]); backtrack(list, tempList, nums, remain - nums[i], i + 1); tempList.remove(tempList.size() - 1); } } }

Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target. Each number in candidates 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. Example 1: Input: candidates = [10,1,2,7,6,1,5], target = 8, A solution set is: [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ] Example 2: Input: candidates = [2,5,2,1,2], target = 5, A solution set is: [ [1,2,2], [5] ]

public List<List<Integer>> permute(int[] nums) { List<List<Integer>> list = new ArrayList<>(); // Arrays.sort(nums); // not necessary backtrack(list, new ArrayList<>(), nums); return list; } private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums){ if(tempList.size() == nums.length){ list.add(new ArrayList<>(tempList)); } else{ for(int i = 0; i < nums.length; i++){ if(tempList.contains(nums[i])) continue; // element already exists, skip tempList.add(nums[i]); backtrack(list, tempList, nums); tempList.remove(tempList.size() - 1); } } }

Given a collection of distinct integers, return all possible permutations. Example: Input: [1,2,3] Output: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]

public List<List<Integer>> subsetsWithDup(int[] nums) { List<List<Integer>> list = new ArrayList<>(); Arrays.sort(nums); backtrack(list, new ArrayList<>(), nums, 0); return list; } private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int start){ list.add(new ArrayList<>(tempList)); for(int i = start; i < nums.length; i++){ if(i > start && nums[i] == nums[i-1]) continue; // skip duplicates tempList.add(nums[i]); backtrack(list, tempList, nums, i + 1); tempList.remove(tempList.size() - 1); } }

Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set). Note: The solution set must not contain duplicate subsets. Example: Input: [1,2,2] Output: [ [2], [1], [1,2,2], [2,2], [1,2], [] ]

public List<Interval> merge(List<Interval> intervals) { Comparator<Interval> comp = new Comparator<Interval>() { public int compare(Interval v1, Interval v2) { int startCom = v1.start - v2.start; if(startCom != 0) return startCom; else return v1.end - v2.end; } }; Collections.sort(intervals, comp); Stack<Interval> stack = new Stack<>(); for(int i = 0; i < intervals.size(); i++) { if(stack.isEmpty()) { stack.push(intervals.get(i)); } else { Interval v1 = stack.pop(); Interval v2 = intervals.get(i); // when v2 start date is less then v1 end date if(v1.end >= v2.start && v1.end <= v2.end) { Interval v3 = new Interval(v1.start, v2.end); stack.push(v3); } // when v2 is inside v1, // which means both start and end dates of v2 less than v1.end else if(v1.end >= v2.start && v1.end >= v2.end) { stack.push(v1); } else { stack.push(v1); stack.push(v2); } } } return new ArrayList<>(stack); }

Given a collection of intervals, merge all overlapping intervals. Example 1: Input: [[1,3],[2,6],[8,10],[15,18]] Output: [[1,6],[8,10],[15,18]] Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6]. Example 2: Input: [[1,4],[4,5]] Output: [[1,5]] Explanation: Intervals [1,4] and [4,5] are considerred overlapping.

public List<List<Integer>> permuteUnique(int[] nums) { List<List<Integer>> list = new ArrayList<>(); Arrays.sort(nums); backtrack(list, new ArrayList<>(), nums, new boolean[nums.length]); return list; } private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, boolean [] used){ if(tempList.size() == nums.length){ list.add(new ArrayList<>(tempList)); } else{ for(int i = 0; i < nums.length; i++){ if(used[i] || i > 0 && nums[i] == nums[i-1] && !used[i - 1]) continue; used[i] = true; tempList.add(nums[i]); backtrack(list, tempList, nums, used); used[i] = false; tempList.remove(tempList.size() - 1); } } }

Given a collection of numbers that might contain duplicates, return all possible unique permutations. Example: Input: [1,1,2] Output: [ [1,1,2], [1,2,1], [2,1,1] ]

public int countNodes(TreeNode root) { if(root == null) return 0; int left = height(root); if(left < 0) return 0; if(height(root.right) == left - 1) { return (int) Math.pow(2, left) + countNodes(root.right); } return (int) Math.pow(2, left - 1) + countNodes(root.left); } private int height(TreeNode root){ if(root == null) return -1; return 1 + height(root.left); } Explanation The height of a tree can be found by just going left. Let a single node tree have height 0. Find the height h of the whole tree. If the whole tree is empty, i.e., has height -1, there are 0 nodes. Otherwise check whether the height of the right subtree is just one less than that of the whole tree, meaning left and right subtree have the same height. If yes, then the last node on the last tree row is in the right subtree and the left subtree is a full tree of height h-1. So we take the 2^h-1 nodes of the left subtree plus the 1 root node plus recursively the number of nodes in the right subtree. If no, then the last node on the last tree row is in the left subtree and the right subtree is a full tree of height h-2. So we take the 2^(h-1)-1 nodes of the right subtree plus the 1 root node plus recursively the number of nodes in the left subtree. Since I halve the tree in every recursive step, I have O(log(n)) steps. Finding a height costs O(log(n)). So overall O(log(n)^2).

Given a complete binary tree, count the number of nodes. Note: Definition of a complete binary tree from Wikipedia: In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h. Example: Input: 1 / \ 2 3 / \ / 4 5 6 Output: 6

public ListNode partition(ListNode head, int x) { if(head == null) return head; ListNode result = new ListNode(0); ListNode resultHead = result; ListNode curr = head; // work on smaller vals first while(curr != null) { if(curr.val < x) { result.next = new ListNode(curr.val); result = result.next; } curr = curr.next; } // work on greater than or equal while(head != null) { if(head.val >= x) { result.next = new ListNode(head.val); result = result.next; } head = head.next; } return resultHead.next; }

Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x. You should preserve the original relative order of the nodes in each of the two partitions. Example: Input: head = 1->4->3->2->5->2, x = 3 Output: 1->2->2->4->3->5

public ListNode removeNthFromEnd(ListNode head, int n) { ListNode tmp = head; int size = 0; while(tmp != null) { size++; tmp = tmp.next; } ListNode runner = null; ListNode runnerHead = null; int counter = 0; while(head != null) { if(counter != size - n) { if(runner == null) { runner = new ListNode(head.val); runnerHead = runner; } else { runner.next = new ListNode(head.val); runner = runner.next; } } head = head.next; counter++; } return runnerHead; }

Given a linked list, remove the n-th node from the end of list and return its head. Example: Given linked list: 1->2->3->4->5, and n = 2. After removing the second node from the end, the linked list becomes 1->2->3->5.

List<String> res = new ArrayList<>(); Map<String, List<String>> map = new HashMap<>(); public List<String> findItinerary(String[][] tickets) { for (String[] airports : tickets) { if (!map.containsKey(airports[0])) { map.put(airports[0], new ArrayList<>()); } map.get(airports[0]).add(airports[1]); } for (String str : map.keySet()) { Collections.sort(map.get(str)); } dfs("JFK"); return res; } private void dfs(String from) { if (!map.containsKey(from) || map.get(from).size() == 0) { res.add(0, from); return; } while (map.get(from).size() > 0) { String to = map.get(from).remove(0); dfs(to); } res.add(0, from); }

Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], reconstruct the itinerary in order. All of the tickets belong to a man who departs from JFK. Thus, the itinerary must begin with JFK. Note: If there are multiple valid itineraries, you should return the itinerary that has the smallest lexical order when read as a single string. For example, the itinerary ["JFK", "LGA"] has a smaller lexical order than ["JFK", "LGB"]. All airports are represented by three capital letters (IATA code). You may assume all tickets form at least one valid itinerary. Example 1: Input: tickets = [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] Output: ["JFK", "MUC", "LHR", "SFO", "SJC"]

private class LargerNumberComparator implements Comparator<String> { @Override public int compare(String a, String b) { String order1 = a + b; String order2 = b + a; return order2.compareTo(order1); } } public String largestNumber(int[] nums) { // Get input integers as strings. String[] asStrs = new String[nums.length]; for (int i = 0; i < nums.length; i++) { asStrs[i] = String.valueOf(nums[i]); } // Sort strings according to custom comparator. Arrays.sort(asStrs, new LargerNumberComparator()); // If, after being sorted, the largest number is `0`, the entire number // is zero. if (asStrs[0].equals("0")) { return "0"; } // Build largest number from sorted array. String largestNumberStr = new String(); for (String numAsStr : asStrs) { largestNumberStr += numAsStr; } return largestNumberStr; }

Given a list of non negative integers, arrange them such that they form the largest number. Example 1: Input: [10,2] Output: "210" Example 2: Input: [3,30,34,5,9] Output: "9534330"

public static int minPathSum(int[][] grid) { int m = grid.length, n = grid[0].length; int[] dp = new int[n+1]; for (int j = 0; j < n; j++) dp[j+1] = dp[j] + grid[0][j]; dp[0] = Integer.MAX_VALUE; for (int i=1; i<m; i++){ for (int j=0; j<n; j++){ dp[j+1] = Math.min(dp[j], dp[j+1]) + grid[i][j]; } } return dp[n]; }

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time. Example: Input: [ [1,3,1], [1,5,1], [4,2,1] ] Output: 7 Explanation: Because the path 1→3→1→1→1 minimizes the sum.

public void setZeroes(int[][] matrix) { int m = matrix.length; int n = matrix[0].length; boolean[][] isZero = new boolean[m][n]; for(int i = 0; i < m; i++) { for(int j = 0; j < n; j++) { if(matrix[i][j] == 0) isZero[i][j] = true; } } for(int i = 0; i < m; i++) { for(int j = 0; j < n; j++) { if(isZero[i][j]) { int counter = 0; while(counter < m) { matrix[counter][j] = 0; counter++; } counter = 0; while(counter < n) { matrix[i][counter] = 0; counter++; } } } } }

Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place. Example 1: Input: [ [1,1,1], [1,0,1], [1,1,1] ] Output: [ [1,0,1], [0,0,0], [1,0,1] ]

public int kthSmallest(int[][] matrix, int k) { int[] table = new int[matrix.length * matrix[0].length]; int count = 0; for(int i = 0; i < matrix.length; i++) { for(int j = 0; j < matrix[0].length; j++) { table[count++] = matrix[i][j]; } } Arrays.sort(table); return table[k - 1]; }

Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix. Note that it is the kth smallest element in the sorted order, not the kth distinct element. Example: matrix = [ [ 1, 5, 9], [10, 11, 13], [12, 13, 15] ], k = 8, return 13.

This problem is essentially let us to find whether there are several numbers in a set which are able to sum to a specific value (in this problem, the value is sum/2). Actually, this is a 0/1 knapsack problem, for each number, we can pick it or not. Let us assume dp[i][j] means whether the specific sum j can be gotten from the first i numbers. If we can pick such a series of numbers from 0-i whose sum is j, dp[i][j] is true, otherwise it is false. Base case: dp[0][0] is true; (zero number consists of sum 0 is true) Transition function: For each number, if we don't pick it, dp[i][j] = dp[i-1][j], which means if the first i-1 elements has made it to j, dp[i][j] would also make it to j (we can just ignore nums[i]). If we pick nums[i]. dp[i][j] = dp[i-1][j-nums[i]], which represents that j is composed of the current value nums[i] and the remaining composed of other previous numbers. Thus, the transition function is dp[i][j] = dp[i-1][j] || dp[i-1][j-nums[i]] public boolean canPartition(int[] nums) { int sum = 0; for (int num : nums) { sum += num; } if (sum % 2 == 1) { return false; } sum /= 2; int n = nums.length; boolean[] dp = new boolean[sum+1]; dp[0] = true; for (int num : nums) { for (int i = sum; i > 0; i--) { if (i >= num) { dp[i] = dp[i] || dp[i-num]; } } } return dp[sum]; }

Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal. Note: Each of the array element will not exceed 100. The array size will not exceed 200. Example 1: Input: [1, 5, 11, 5] Output: true Explanation: The array can be partitioned as [1, 5, 5] and [11]. Example 2: Input: [1, 2, 3, 5] Output: false Explanation: The array cannot be partitioned into equal sum subsets.

class Pair implements Comparable<Pair> { int val; int count; public Pair(int v, int c) { val = v; count = c; } public int compareTo(Pair that) { return that.count - this.count; } } public class Solution { public List<Integer> topKFrequent(int[] nums, int k) { Map<Integer, Integer> map = new HashMap<>(); for(int i = 0; i < nums.length; i++) { map.put(nums[i], map.containsKey(nums[i]) ? map.get(nums[i]) + 1 : 1); } PriorityQueue<Pair> pq = new PriorityQueue<>(); for(Map.Entry<Integer, Integer> entry : map.entrySet()) { pq.add(new Pair(entry.getKey(), entry.getValue())); } List<Integer> result = new ArrayList<Integer>(); while(k > 0) { result.add(pq.poll().val); k--; } return result; } }

Given a non-empty array of integers, return the k most frequent elements. Example 1: Input: nums = [1,1,1,2,2,3], k = 2 Output: [1,2] Example 2: Input: nums = [1], k = 1 Output: [1] Note: You may assume k is always valid, 1 ≤ k ≤ number of unique elements. Your algorithm's time complexity must be better than O(n log n), where n is the array's size.

where n is number of digits and each digit place is filled with 0 to 9 based on position if n==1 10^1=10 where exclusive 10 so 9 digits if n>10 no unique digits possible as we have only 10 digits if n==0 10^0=1 so only 0 is digit and answer is 1 for n between 2 to 10 _ _ _ _ _ _ _ _ _ _ preceding 0 is not allowed so 9 digits there in rest position for n=10 9 x 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 for n=9 9 x 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 for n=8 9 x 9 x 8 x 7 x 6 x 5 x 4 x 3 for n=7 9 x 9 x 8 x 7 x 6 x 5 x 4 similarly it goes... public int countNumbersWithUniqueDigits(int n) { int i, ans = 0; if(n==0) return 1; if(n==10) return 9; if(n>10) return 0; for(i = 1; i <= n; i++) { if(i == 1) { ans = ans+10; } else { int j = i-1, temp = 9, u = 9; while(j > 0) { temp = temp * u; u--; j--; } ans = ans + temp; } } return ans; }

Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Example: Input: 2 Output: 91 Explanation: The answer should be the total numbers in the range of 0 ≤ x < 100, excluding 11,22,33,44,55,66,77,88,99

public int integerReplacement(long n){ if(n == 1) return 0; if(n % 2 == 0) return integerReplacement( n / 2 ) + 1 ; else return Math.min(integerReplacement(n + 1) + 1, integerReplacement(n - 1) + 1); }

Given a positive integer n and you can do operations as follow: If n is even, replace n with n/2. If n is odd, you can replace n with either n + 1 or n - 1. What is the minimum number of replacements needed for n to become 1? Example 1: Input: 8 Output: 3 Explanation: 8 -> 4 -> 2 -> 1 Example 2: Input: 7 Output: 4 Explanation: 7 -> 8 -> 4 -> 2 -> 1 or 7 -> 6 -> 3 -> 2 -> 1

Assuming A[i] is the least number of perfect square numbers summing to i A[1] = 1 A[i] = 1 + min(A[i-j^2]), for all j's such that 1 < j^2 <= i public int numSquares(int n) { int[] A = new int[n+1]; // A[i] = least number of perfect square numbers summing to i A[1] = 1; // base case, takes one "step" (1^2) to get to 1 for (int i = 2; i < n+1; i++) { // populate A at each index // find smallest of A[i-1], A[i-4], A[i-9] ... A[i-j^2], stopping when j^2 > i int minSteps = Integer.MAX_VALUE; int j = 1; while (j*j <= i) { if (A[i-j*j] < minSteps) { minSteps = A[i-j*j]; } j++; } A[i] = minSteps+1; // add one "step" to smallest square one step below it } return A[n]; }

Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n. Example 1: Input: n = 12 Output: 3 Explanation: 12 = 4 + 4 + 4. Example 2: Input: n = 13 Output: 2 Explanation: 13 = 4 + 9.

public List<List<Integer>> combinationSum(int[] nums, int target) { List<List<Integer>> list = new ArrayList<>(); Arrays.sort(nums); backtrack(list, new ArrayList<>(), nums, target, 0); return list; } private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){ if(remain < 0) return; else if(remain == 0) list.add(new ArrayList<>(tempList)); else{ for(int i = start; i < nums.length; i++){ tempList.add(nums[i]); backtrack(list, tempList, nums, remain - nums[i], i); // not i + 1 because we can reuse same elements tempList.remove(tempList.size() - 1); } } }

Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target. The same repeated number may be chosen from candidates unlimited number of times. Note: All numbers (including target) will be positive integers. The solution set must not contain duplicate combinations. Example 1: Input: candidates = [2,3,6,7], target = 7, A solution set is: [ [7], [2,2,3] ]

public List<List<Integer>> subsets(int[] nums) { List<List<Integer>> list = new ArrayList<>(); Arrays.sort(nums); backtrack(list, new ArrayList<>(), nums, 0); return list; } private void backtrack(List<List<Integer>> list , List<Integer> tempList, int [] nums, int start){ list.add(new ArrayList<>(tempList)); for(int i = start; i < nums.length; i++){ tempList.add(nums[i]); backtrack(list, tempList, nums, i + 1); tempList.remove(tempList.size() - 1); } }

Given a set of distinct integers, nums, return all possible subsets (the power set). Note: The solution set must not contain duplicate subsets. Example: Input: nums = [1,2,3] Output: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]

private ListNode node; public TreeNode sortedListToBST(ListNode head) { if(head == null){ return null; } int size = 0; ListNode runner = head; node = head; while(runner != null){ runner = runner.next; size ++; } return inorderHelper(0, size - 1); } public TreeNode inorderHelper(int start, int end){ if(start > end){ return null; } int mid = start + (end - start) / 2; TreeNode left = inorderHelper(start, mid - 1); TreeNode treenode = new TreeNode(node.val); treenode.left = left; node = node.next; TreeNode right = inorderHelper(mid + 1, end); treenode.right = right; return treenode; }

Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST. For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1. Example: Given the sorted linked list: [-10,-3,0,5,9], One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST: 0 / \ -3 9 / / -10 5

public ListNode oddEvenList(ListNode head) { if(head == null) return null; if(head.next == null) return head; ListNode odd = new ListNode(head.val); ListNode even = new ListNode(head.next.val); ListNode result = odd; ListNode evenHead = even; head = head.next.next; int count = 1; while(head != null) { ListNode tmp = new ListNode(head.val); if(count % 2 != 0) { odd.next = tmp; odd = odd.next; } else { even.next = tmp; even = even.next; } count++; head = head.next; } odd.next = evenHead; return result; }

Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes. You should try to do it in place. The program should run in O(1) space complexity and O(nodes) time complexity. Example 1: Input: 1->2->3->4->5->NULL Output: 1->3->5->2->4->NULL Example 2: Input: 2->1->3->5->6->4->7->NULL Output: 2->3->6->7->1->5->4->NULL

Just go through the numbers and include those in the result that haven't been included twice already. public int removeDuplicates(int[] nums) { int i = 0; for (int n : nums) if (i < 2 || n > nums[i-2]) nums[i++] = n; return i; }

Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twice and return the new length. Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. Example 1: Given 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 respectively. It doesn't matter what you leave beyond the returned length.

public ListNode deleteDuplicates(ListNode head) { if(head == null) return null; ListNode result = new ListNode(0); result.next = head; ListNode pre = result; ListNode cur = head; while(cur != null){ while(cur.next != null && cur.val == cur.next.val){ cur = cur.next; } if(pre.next == cur){ pre = pre.next; } else{ pre.next = cur.next; } cur = cur.next; } return result.next; }

Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. Example 1: Input: 1->2->3->3->4->4->5 Output: 1->2->5

// O(n^2) public int maxProduct(String[] words) { int max = 0; if(words == null || words.length == 0) return max; for(int i = 0; i < words.length; i++) { for(int j = 0; j != i && j < words.length; j++) { if(!haveCommonChars(words[i], words[j])) { max = Math.max(max, words[i].length() * words[j].length()); } } } return max; } // O(m + n) private boolean haveCommonChars(String s1, String s2) { Map<Character, Integer> map = new HashMap<>(); for(int i = 0; i < s1.length(); i++) { char c = s1.charAt(i); map.put(c, 1); } for(int i = 0; i < s2.length(); i++) { char c = s2.charAt(i); if(map.containsKey(c)) return true; } return false; }

Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters. You may assume that each word will contain only lower case letters. If no such two words exist, return 0. Example 1: Input: ["abcw","baz","foo","bar","xtfn","abcdef"] Output: 16 Explanation: The two words can be "abcw", "xtfn". Example 2: Input: ["a","ab","abc","d","cd","bcd","abcd"] Output: 4 Explanation: The two words can be "ab", "cd".

public static List<String> letterCombinations(String digits) { String digitletter[] = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"}; List<String> result = new ArrayList<String>(); if (digits.length()==0) return result; result.add(""); for (int i=0; i<digits.length(); i++) result = combine(digitletter[digits.charAt(i)-'0'],result); return result; } public static List<String> combine(String digit, List<String> l) { List<String> result = new ArrayList<String>(); for (int i=0; i<digit.length(); i++) for (String x : l) result.add(x+digit.charAt(i)); return result; }

Given a string containing digits from 2-9 inclusive, 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. Note that 1 does not map to any letters. Example: Input: "23" Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

public boolean isSubsequence(String s, String t) { if(s.length() == 0) return true; int i = 0; int j = 0; while(i < s.length() && j < t.length()) { if(s.charAt(i) == t.charAt(j)) { i++; } j++; if(i == s.length()) return true; } return false; }

Given a string s and a string t, check if s is subsequence of t. You may assume that there is only lower case English letters in both s and t. t is potentially a very long (length ~= 500,000) string, and s is a short string (<=100). 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). Example 1: s = "abc", t = "ahbgdc" Return true. Example 2: s = "axc", t = "ahbgdc" Return false. Follow up: If there are lots of incoming S, say S1, S2, ... , Sk where k >= 1B, and you want to check one by one to see if T has its subsequence. In this scenario, how would you change your code?

We observe that a palindrome mirrors around its center. Therefore, a palindrome can be expanded from its center, and there are only 2n - 12n−1 such centers. public String longestPalindrome(String s) { if (s == null || s.length() < 1) return ""; int start = 0, end = 0; for (int i = 0; i < s.length(); i++) { int len1 = expandAroundCenter(s, i, i); int len2 = expandAroundCenter(s, i, i + 1); int len = Math.max(len1, len2); if (len > end - start) { start = i - (len - 1) / 2; end = i + len / 2; } } return s.substring(start, end + 1); } private int expandAroundCenter(String s, int left, int right) { int L = left, R = right; while (L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)) { L--; R++; } return R - L - 1; } Time complexity : O(n^2). Since expanding a palindrome around its center could take O(n) time, the overall complexity is O(n^2) Space complexity : O(1).

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. Example 1: Input: "babad" Output: "bab" Note: "aba" is also a valid answer.

public List<List<String>> partition(String s) { List<List<String>> list = new ArrayList<>(); backtrack(list, new ArrayList<>(), s, 0); return list; } public void backtrack(List<List<String>> list, List<String> tempList, String s, int start){ if(start == s.length()) list.add(new ArrayList<>(tempList)); else{ for(int i = start; i < s.length(); i++){ if(isPalindrome(s, start, i)){ tempList.add(s.substring(start, i + 1)); backtrack(list, tempList, s, i + 1); tempList.remove(tempList.size() - 1); } } } } public boolean isPalindrome(String s, int low, int high){ while(low < high) if(s.charAt(low++) != s.charAt(high--)) return false; return true; }

Given a string s, partition s such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of s. Example: Input: "aab" Output: [ ["aa","b"], ["a","a","b"] ]

public int lengthOfLongestSubstring(String s) { if(s == null || s.equals("")) return 0; if(s.length() == 1) return 1; int max = Integer.MIN_VALUE; Map<Character, Integer> map = new HashMap<>(); for(int i = 0; i < s.length(); i++) { char c = s.charAt(i); if(map.containsKey(c)) { max = Math.max(map.size(), max); i = map.get(c) + 1; c = s.charAt(i); map.clear(); } map.put(c, i); } max = Math.max(map.size(), max); return max; }

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 static int minimumTotal(List<List<Integer>> triangle) { int[] A = new int[triangle.size()+1]; for(int i=triangle.size()-1;i>=0;i--){ for(int j=0;j<triangle.get(i).size();j++){ A[j] = Math.min(A[j],A[j+1]) + triangle.get(i).get(j); } } return A[0]; }

Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below. For example, given the following triangle [ [2], [3,4], [6,5,7], [4,1,8,3] ] The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).

public int countBattleships(char[][] board) { if(board == null || board.length == 0) return 0; int result = 0; for(int i = 0; i < board.length; i++) { for(int j = 0; j < board[0].length; j++) { if(board[i][j] == 'X') { result++; dfs(board, i, j); } } } return result; } private void dfs(char[][] board, int i, int j) { if(i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] == '.') { return; } board[i][j] = '.'; dfs(board, i + 1, j); dfs(board, i, j + 1); }

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?

The main idea is the same with problem Linked List Cycle II,https://leetcode.com/problems/linked-list-cycle-ii/. Use two pointers the fast and the slow. The fast one goes forward two steps each time, while the slow one goes only step each time. They must meet the same item when slow==fast. In fact, they meet in a circle, the duplicate number must be the entry point of the circle when visiting the array from nums[0]. Next we just need to find the entry point. We use a point(we can use the fast one before) to visit form begining with one step each time, do the same job to slow. When fast==slow, they meet at the entry point of the circle. The easy understood code is as follows. public int findDuplicate(int[] nums) { if(nums.length <= 0) return -1; int slow = nums[0]; int fast = nums[nums[0]]; while(slow != fast) { slow = nums[slow]; fast = nums[nums[fast]]; } fast = 0; while(fast != slow) { fast = nums[fast]; slow = nums[slow]; } return slow; }

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one. Example 1: Input: [1,3,4,2,2] Output: 2 Example 2: Input: [3,1,3,4,2] Output: 3 Note: You must not modify the array (assume the array is read only). You must use only constant, O(1) extra space. Your runtime complexity should be less than O(n2). There is only one duplicate number in the array, but it could be repeated more than once.

public List<List<Integer>> threeSum(int[] num) { Arrays.sort(num); List<List<Integer>> res = new LinkedList<>(); for (int i = 0; i < num.length-2; i++) { if (i == 0 || (i > 0 && num[i] != num[i-1])) { int lo = i+1, hi = num.length-1, sum = 0 - num[i]; while (lo < hi) { if (num[lo] + num[hi] == sum) { res.add(Arrays.asList(num[i], num[lo], num[hi])); while (lo < hi && num[lo] == num[lo+1]) lo++; while (lo < hi && num[hi] == num[hi-1]) hi--; lo++; hi--; } else if (num[lo] + num[hi] < sum) lo++; else hi--; } } } return res; }

Given an array nums of n integers, are there elements a, b, c in nums 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. Example: Given array nums = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]

public int[] searchRange(int[] nums, int target) { int lo = 0; int hi = nums.length - 1; int[] result = {-1, -1}; while(lo < hi) { int mid = lo + (hi - lo) / 2; if(target > nums[mid]) { lo = mid + 1; } else if(target < nums[mid]) { hi = mid - 1; } else { int left = mid; int right = mid; while(nums[left] == target) left--; while(nums[right] == target) right++; result[0] = left + 1; result[1] = right - 1; break; } } return result; }

Given an array of integers nums 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]. Example 1: Input: nums = [5,7,7,8,8,10], target = 8 Output: [3,4] Example 2: Input: nums = [5,7,7,8,8,10], target = 6 Output: [-1,-1]

private Map<Integer, List<Integer>> places; private Random r; public Solution(int[] nums) { places = new HashMap<>(); r = new Random(); for (int i = 0; i < nums.length; i++) { List<Integer> locs = places.getOrDefault(nums[i], new ArrayList<>()); locs.add(i); places.put(nums[i], locs); } } public int pick(int target) { List<Integer> locs = places.get(target); return locs.get(r.nextInt(locs.size())); }

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);

// O(n) solution public int minSubArrayLen(int s, int[] nums) { if(nums == null || nums.length == 0) return 0; int i = 0, j = 0, sum = 0, result = Integer.MAX_VALUE; while(i < nums.length){ sum += nums[i]; while(sum >= s){ result = Math.min(result, i - j + 1); sum -= nums[j]; j++; } i++; } return result == Integer.MAX_VALUE ? 0 : result; }

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. Example: Input: s = 7, nums = [2,3,1,2,4,3] Output: 2 Explanation: the subarray [4,3] has the minimal length under the problem constraint. Follow up: If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n).

public boolean canJump(int[] nums) { int max = 0; for(int i = 0; i < nums.length; i++) { if(i > max) return false; max = Math.max(nums[i] + i, max); } return true; }

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. Example 1: Input: [2,3,1,1,4] Output: true Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index. Example 2: Input: [3,2,1,0,4] Output: false Explanation: You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index.

public List<List<String>> groupAnagrams(String[] strs) { List<List<String>> result = new ArrayList<>(); Map<String, List<String>> map = new HashMap<>(); for(String s : strs) { char[] c = s.toCharArray(); Arrays.sort(c); String keyStr = new String(c); if(!map.containsKey(keyStr)) { map.put(keyStr, new ArrayList<>()); } map.get(keyStr).add(s); } result.addAll(map.values()); return result; }

Given an array of strings, group anagrams together. Example: Input: ["eat", "tea", "tan", "ate", "nat", "bat"], Output: [ ["ate","eat","tea"], ["nat","tan"], ["bat"] ]

public String decodeString(String s) { Stack<String> stack = new Stack<>(); int time = 0; for (char c : s.toCharArray()) { if (c >= '0' && c <= '9') time = (time * 10) + (c - '0'); else if (c == '[') { stack.push(time + ""); stack.push("["); time = 0; } else if (c == ']') { StringBuilder temp = new StringBuilder(); while (stack.peek() != "[") { temp.insert(0, stack.pop()); } stack.pop(); // skip "[" int t = Integer.parseInt(stack.pop()); String str = temp.toString(); // do t-1 times while (t-- > 1) { temp.append(str); } stack.push(temp.toString()); } else stack.push(c+""); } StringBuilder sb = new StringBuilder(); while (!stack.isEmpty()) { sb.insert(0, stack.pop()); } return sb.toString(); }

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".

public String reverseWords(String s) { s = s.trim(); if(s == null || s.length() <= 1) return s; char[] arr = s.toCharArray(); reverse(arr, 0, arr.length - 1); int j = 0; for(int i = 0; i < arr.length; i++) { if(arr[i] == ' ') { reverse(arr, j, i - 1); j = i + 1; } } reverse(arr, j, arr.length - 1); return new String(arr); } private void reverse(char[] arr, int start, int end) { while(start <= end) { char tmp = arr[start]; arr[start] = arr[end]; arr[end] = tmp; start++; end--; } }

Given an input string, reverse the string word by word. Example: Input: "the sky is blue", Output: "blue is sky the". Note: A word is defined as a sequence of non-space characters. Input string may contain leading or trailing spaces. However, your reversed string should not contain leading or trailing spaces. You need to reduce multiple spaces between two words to a single space in the reversed string.

Boyer-Moore Majority Vote algorithm generalization public List<Integer> majorityElement(int[] nums) { //there should be at most 2 different elements in nums more than n/3 //so we can find at most 2 elements based on Boyer-Moore Majority Vote algo List<Integer> result = new ArrayList<Integer>(); if(nums.length == 0) return result; int count1 = 0, count2 = 0, m1 = 0, m2 = 0; for(int n : nums) { if(m1 == n) count1++; else if(m2 == n) count2++; else if(count1 == 0) { m1 = n; count1 = 1; } else if(count2 == 0) { m2 = n; count2 = 1; } else{ count1--; count2--; } } count1 = 0; count2 = 0; //count the number for the 2 elements for(int n : nums){ if(n == m1) count1++; else if(n == m2) count2++; } //if those appear more than n/3 if(count1 > nums.length / 3) result.add(m1); if(count2 > nums.length / 3) result.add(m2); return result; }

Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. Note: The algorithm should run in linear time and in O(1) space. Example 1: Input: [3,2,3] Output: [3]

public boolean increasingTriplet(int[] nums) { if(nums == null || nums.length <= 2) return false; int min = Integer.MAX_VALUE; int secondMin = Integer.MAX_VALUE; for(int i = 0; i < nums.length; i++) { if(nums[i] <= min) { min = nums[i]; } else if(nums[i] < secondMin) { secondMin = nums[i]; } else if(nums[i] > secondMin) return true; } return false; }

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. Note: Your algorithm should run in O(n) time complexity and O(1) space complexity. Example 1: Input: [1,2,3,4,5] Output: true

public int maxArea(int[] height) { int lo = 0; int hi = height.length - 1; int max = -1; while(lo < hi) { // area of the ractangle is // min height * number of bars (= hi - lo) max = Math.max(max, Math.min(height[lo], height[hi]) * (hi - lo)); if(height[lo] < height[hi]) { lo++; } else { hi--; } } return max; }

Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

public List<String> generateParenthesis(int n) { List<String> result = new ArrayList<>(); char[] str = new char[n * 2]; int left = n; int right = n; generateParens(left, right, result, str, 0); return result; } private void generateParens(int left, int right, List<String> result, char[] str, int index) { if(left < 0 || right < left) return; if(left == 0 && right == 0) { result.add(new String(str)); } else { str[index] = '('; generateParens(left - 1, right, result, str, index + 1); str[index] = ')'; generateParens(left, right - 1, result, str, index + 1); } }

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: [ "((()))", "(()())", "(())()", "()(())", "()()()" ]

The problem can be solved in a dynamic programming way. I'll explain the intuition and formulas in the following. Given a sequence 1...n, to construct a Binary Search Tree (BST) out of the sequence, we could enumerate each number i in the sequence, and use the number as the root, naturally, the subsequence 1...(i-1) on its left side would lay on the left branch of the root, and similarly the right subsequence (i+1)...n lay on the right branch of the root. We then can construct the subtree from the subsequence recursively. Through the above approach, we could ensure that the BST that we construct are all unique, since they have unique roots. The problem is to calculate the number of unique BST. To do so, we need to define two functions: G(n): the number of unique BST for a sequence of length n. F(i, n), 1 <= i <= n: the number of unique BST, where the number i is the root of BST, and the sequence ranges from 1 to n. As one can see, G(n) is the actual function we need to calculate in order to solve the problem. And G(n) can be derived from F(i, n), which at the end, would recursively refer to G(n). First of all, given the above definitions, we can see that the total number of unique BST G(n), is the sum of BST F(i) using each number i as a root. i.e. G(n) = F(1, n) + F(2, n) + ... + F(n, n). Particularly, the bottom cases, there is only one combination to construct a BST out of a sequence of length 1 (only a root) or 0 (empty tree). i.e. G(0)=1, G(1)=1. Given a sequence 1...n, we pick a number i out of the sequence as the root, then the number of unique BST with the specified root F(i), is the cartesian product of the number of BST for its left and right subtrees. For example, F(3, 7): the number of unique BST tree with number 3 as its root. To construct an unique BST out of the entire sequence [1, 2, 3, 4, 5, 6, 7] with 3 as the root, which is to say, we need to construct an unique BST out of its left subsequence [1, 2] and another BST out of the right subsequence [4, 5, 6, 7], and then combine them together (i.e. cartesian product). The tricky part is that we could consider the number of unique BST out of sequence [1,2] as G(2), and the number of of unique BST out of sequence [4, 5, 6, 7] as G(4). Therefore, F(3,7) = G(2) * G(4). i.e. F(i, n) = G(i-1) * G(n-i) 1 <= i <= n Combining the above two formulas, we obtain the recursive formula for G(n). i.e. G(n) = G(0) * G(n-1) + G(1) * G(n-2) + ... + G(n-1) * G(0) In terms of calculation, we need to start with the lower number, since the value of G(n) depends on the values of G(0) ... G(n-1). With the above explanation and formulas, here is the implementation in Java. public int numTrees(int n) { int [] G = new int[n+1]; G[0] = G[1] = 1; for(int i=2; i<=n; ++i) { for(int j=1; j<=i; ++j) { G[i] += G[j-1] * G[i-j]; } } return G[n]; }

Given n, how many structurally unique BST's (binary search trees) that store values 1 ... n? Example: Input: 3 Output: 5 Explanation: 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

The basic idea is here: Say we have 2 arrays, PRE and IN. Preorder traversing implies that PRE[0] is the root node. Then we can find this PRE[0] in IN, say it's IN[5]. Now we know that IN[5] is root, so we know that IN[0] - IN[4] is on the left side, IN[6] to the end is on the right side. Recursively doing this on subarrays, we can build a tree out of it :) Hope this helps. public TreeNode buildTree(int[] preorder, int[] inorder) { return helper(0, 0, inorder.length - 1, preorder, inorder); } public TreeNode helper(int preStart, int inStart, int inEnd, int[] preorder, int[] inorder) { if (preStart > preorder.length - 1 || inStart > inEnd) { return null; } TreeNode root = new TreeNode(preorder[preStart]); int inIndex = 0; // Index of current root in inorder for (int i = inStart; i <= inEnd; i++) { if (inorder[i] == root.val) { inIndex = i; } } root.left = helper(preStart + 1, inStart, inIndex - 1, preorder, inorder); root.right = helper(preStart + inIndex - inStart + 1, inIndex + 1, inEnd, preorder, inorder); return root; }

Given preorder and inorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the tree. For example, given preorder = [3,9,20,15,7] inorder = [9,3,15,20,7] Return the following binary tree: 3 / \ 9 20 / \ 15 7

public int divide(int dividend, int divisor) { if(dividend == 0) return 0; if(divisor == 0) return Integer.MAX_VALUE; if(dividend == divisor) return 1; int sign = 1; if(dividend < 0 || divisor < 0) sign = -1; dividend = Math.abs(dividend); divisor = Math.abs(divisor); int target = 0; while(divisor <= dividend) { dividend = dividend - divisor; target++; } return sign < 0 ? negate(target) : target; } private int negate(int i) { return 0 - i; }

Given two integers dividend and divisor, divide two integers without using multiplication, division and mod operator. Return the quotient after dividing dividend by divisor. The integer division should truncate toward zero. Example 1: Input: dividend = 10, divisor = 3 Output: 3 Example 2: Input: dividend = 7, divisor = -3 Output: -2

Generic approach for backtracking public List<List<Integer>> combine(int n, int k) { List<List<Integer>> result = new ArrayList<>(); backtrack(result, new ArrayList<>(), 1, n, k); return result; } private void backtrack(List<List<Integer>> result, List<Integer> tempList, int start, int n, int k) { if(tempList.size() > k) { return; } else if(tempList.size() == k) { result.add(new ArrayList<>(tempList)); } else { for(int i=start; i <= n; i++) { tempList.add(i); backtrack(result, tempList, i + 1, n, k); tempList.remove(tempList.size() - 1); } } }

Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. Example: Input: n = 4, k = 2 Output: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]

Start from right to left, perform multiplication on every pair of digits, and add them together. Let's draw the process! From the following draft, we can immediately conclude: `num1[i] * num2[j]` will be placed at indices `[i + j`, `i + j + 1]` public String multiply(String num1, String num2) { int m = num1.length(), n = num2.length(); int[] pos = new int[m + n]; for(int i = m - 1; i >= 0; i--) { for(int j = n - 1; j >= 0; j--) { int mul = (num1.charAt(i) - '0') * (num2.charAt(j) - '0'); int p1 = i + j, p2 = i + j + 1; int sum = mul + pos[p2]; pos[p1] += sum / 10; pos[p2] = (sum) % 10; } } StringBuilder sb = new StringBuilder(); for(int p : pos) if(!(sb.length() == 0 && p == 0)) sb.append(p); return sb.length() == 0 ? "0" : sb.toString(); }

Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2, also represented as a string. Example 1: Input: num1 = "2", num2 = "3" Output: "6" Example 2: Input: num1 = "123", num2 = "456" Output: "56088" Note: The length of both num1 and num2 is < 110. Both num1 and num2 contain only digits 0-9. Both num1 and num2 do not contain any leading zero, except the number 0 itself. You must not use any built-in BigInteger library or convert the inputs to integer directly.

public static int ladderLength(String s1, String s2, Set<String> dict) { Queue<WordNode> toExplore = new LinkedList<>(); toExplore.add(new WordNode(s1, 1)); dict.add(s2); while(!toExplore.isEmpty()) { WordNode curr = toExplore.poll(); if(curr.word.equals(s2)) { return curr.numSteps; } char[] arr = curr.word.toCharArray(); for(int i = 0; i < arr.length; i++) { for(char c = 'a'; c <= 'z'; c++) { char tmp = arr[i]; if(arr[i] != c) { arr[i] = c; } String tmpStr = new String(arr); if(dict.contains(tmpStr)) { toExplore.add(new WordNode(tmpStr, curr.numSteps + 1)); dict.remove(tmpStr); } arr[i] = tmp; } } } return 0; }

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. 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. Example 1: Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"] Output: 5 Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", return its length 5.

public int calculate(String s) { int len = s.length(); if(s == null || len == 0) return 0; Stack<Integer> stack = new Stack<Integer>(); int num = 0; char sign = '+'; for(int i = 0; i < len; i++){ if(Character.isDigit(s.charAt(i))){ num = num * 10 + (s.charAt(i) - '0'); } if((!Character.isDigit(s.charAt(i)) && ' ' != s.charAt(i)) || i == len-1) { if(sign == '-'){ stack.push(-num); } if(sign == '+'){ stack.push(num); } if(sign == '*'){ stack.push(stack.pop() * num); } if(sign == '/'){ stack.push(stack.pop() / num); } sign = s.charAt(i); num = 0; } } int result = 0; for(int i : stack){ result += i; } return result; }

Implement a basic calculator to evaluate a simple expression string. The expression string contains only non-negative integers, +, -, *, / operators and empty spaces . The integer division should truncate toward zero. Example 1: Input: "3+2*2" Output: 7

class Trie { private class TrieNode { Map<Character, TrieNode> children; boolean endOfWord; public TrieNode() { children = new HashMap<>(); endOfWord = false; } } private TrieNode root; /** Initialize your data structure here. */ public Trie() { this.root = new TrieNode(); } /** Inserts a word into the trie. */ public void insert(String word) { TrieNode current = root; for (int i = 0; i < word.length(); i++) { char c = word.charAt(i); TrieNode node = current.children.get(c); if(node == null) { node = new TrieNode(); current.children.put(c, node); } current = node; } current.endOfWord = true; } /** Returns if the word is in the trie. */ public boolean search(String word) { TrieNode current = root; for(int i = 0; i < word.length(); i++) { char c = word.charAt(i); TrieNode node = current.children.get(c); if(node == null) { return false; } current = node; } return current.endOfWord; } /** Returns if there is any word in the trie that starts with the given prefix. */ public boolean startsWith(String prefix) { TrieNode current = root; for(int i = 0; i < prefix.length(); i++) { char c = prefix.charAt(i); TrieNode node = current.children.get(c); if(node == null) { return false; } current = node; } 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); */

Implement a trie with insert, search, and startsWith methods. Example: Trie trie = new Trie(); trie.insert("apple"); trie.search("apple"); // returns true trie.search("app"); // returns false trie.startsWith("app"); // returns true trie.insert("app"); trie.search("app"); // returns true

public class BSTIterator { private Queue<Integer> queue; public BSTIterator(TreeNode root) { queue = new LinkedList<>(); inOrder(root); } private void inOrder(TreeNode root) { if(root == null) return; inOrder(root.left); queue.add(root.val); inOrder(root.right); } /** @return whether we have a next smallest number */ public boolean hasNext() { return queue.size() > 0; } /** @return the next smallest number */ public int next() { return queue.poll(); } }

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.

public static int atoi(String number) { boolean minus = false; int result = 0; for (int i = 0; i < number.length(); i++) { if(number.charAt(i) == '-') { minus = true; continue; } result = result * 10 + (number.charAt(i) - '0'); } return minus ? -1 * result : result; }

Implement atoi which converts a string to an integer. The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value. The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function. If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed. If no valid conversion could be performed, a zero value is returned.

public void nextPermutation(int[] nums) { int i = nums.length - 2; while (i >= 0 && nums[i + 1] <= nums[i]) { i--; } if (i >= 0) { int j = nums.length - 1; while (j >= 0 && nums[j] <= nums[i]) { j--; } swap(nums, i, j); } reverse(nums, i + 1); } private void reverse(int[] nums, int start) { int i = start, j = nums.length - 1; while (i < j) { swap(nums, i, j); i++; j--; } } private void swap(int[] nums, int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; }

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers. If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order). The replacement must be in-place and use only constant extra memory. Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column. 1,2,3 → 1,3,2 3,2,1 → 1,2,3 1,1,5 → 1,5,1

In a binary tree, if we consider null as leaves, then all non-null node provides 2 outdegree and 1 indegree (2 children and 1 parent), except root all null node provides 0 outdegree and 1 indegree (0 child and 1 parent). Suppose we try to build this tree. During building, we record the difference between out degree and in degree diff = outdegree - indegree. When the next node comes, we then decrease diff by 1, because the node provides an in degree. If the node is not null, we increase diff by 2, because it provides two out degrees. If a serialization is correct, diff should never be negative and diff will be zero when finished. public boolean isValidSerialization(String preorder) { String[] nodes = preorder.split(","); int diff = 1; for (String node: nodes) { // decrement indegree node by one diff--; if (diff < 0) return false; // increment outdegree node by two if (!node.equals("#")) diff += 2; } return diff == 0; } video: https://www.youtube.com/watch?v=_mbnPPHJmTQ

One way to serialize a binary tree is to use pre-order traversal. When we encounter a non-null node, we record the node's value. If it is a null node, we record using a sentinel value such as #. _9_ / \ 3 2 / \ / \ 4 1 # 6 / \ / \ / \ # # # # # # For example, the above binary tree can be serialized to the string "9,3,4,#,#,1,#,#,2,#,6,#,#", where # represents a null node. Given a string of comma separated values, verify whether it is a correct preorder traversal serialization of a binary tree. Find an algorithm without reconstructing the tree. Each comma separated value in the string must be either an integer or a character '#' representing null pointer. You may assume that the input format is always valid, for example it could never contain two consecutive commas such as "1,,3". Example 1: Input: "9,3,4,#,#,1,#,#,2,#,6,#,#" Output: true Example 2: Input: "1,#" Output: false

public String intToRoman(int num) { if (num < 1 || num >=4000){ return ""; } String[] M = {"", "M", "MM", "MMM"}; String[] C = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"}; String[] X = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"}; String[] I = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}; StringBuilder result = new StringBuilder(); result.append(M[num/1000]); result.append(C[(num%1000)/100]); result.append(X[(num%100)/10]); result.append(I[num%10]); return result.toString(); }

Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. Symbol Value I 1 V 5 X 10 L 50 C 100 D 500 M 1000 For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II. Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used: I can be placed before V (5) and X (10) to make 4 and 9. X can be placed before L (50) and C (100) to make 40 and 90. C can be placed before D (500) and M (1000) to make 400 and 900. Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999. Example 1: Input: 3 Output: "III"

public int lengthLongestPath(String input) { Deque<Integer> stack = new ArrayDeque<>(); String[] arr = input.split("\n"); int maxLen = 0; stack.push(0); //dummy null length for (String s: arr) { /* numOfTabs is the number of "\t", numOfTabs = 0 when "\t" is not found, because s.lastIndexOf("\t") returns -1. So normally, the first parent "dir" have numOfTabs 0. */ int numOfTabs = s.lastIndexOf("\t") + 1; /* Level is defined as numOfTabs + 1. For example, in "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext", dir is level 1, subdir1 and subdir2 are level 2, file.ext is level3 */ level = numOfTabs + 1; /* The following part of code is the case that we want to consider when there are several subdirectories in a same level. We want to remove the path length of the directory or the file of same level that we added during previous step, and calculate the path length of current directory or file that we are currently looking at. */ while (level < stack.size()) stack.poll(); int curLen = stack.peek() + s.length() - numOfTabs + 1; stack.push(curLen); if (s.contains(".")) maxLen = Math.max(maxLen, curLen - 1); //Only update the maxLen when a file is discovered, // And remove the "/" at the end of file } return maxLen; }

Suppose we abstract our file system by a string in the following manner: The string "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext" represents: dir subdir1 subdir2 file.ext The directory dir contains an empty sub-directory subdir1 and a sub-directory subdir2 containing a file file.ext. The string "dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext" represents: dir subdir1 file1.ext subsubdir1 subdir2 subsubdir2 file2.ext The directory dir contains two sub-directories subdir1 and subdir2. subdir1 contains a file file1.ext and an empty second-level sub-directory subsubdir1. subdir2 contains a second-level sub-directory subsubdir2 containing a file file2.ext. We are interested in finding the longest (number of characters) absolute path to a file within our file system. For example, in the second example above, the longest absolute path is "dir/subdir2/subsubdir2/file2.ext", and its length is 32 (not including the double quotes). Given a string representing the file system in the above format, return the length of the longest absolute path to file in the abstracted file system. If there is no file in the system, return 0. Note: The name of a file contains at least a . and an extension. The name of a directory or sub-directory will not contain a .. Time complexity required: O(n) where n is the size of the input string. Notice that a/aa/aaa/file1.txt is not the longest file path, if there is another path aaaaaaaaaaaaaaaaaaaaa/sth.png.

public int[][] reconstructQueue(int[][] people) { if(people.length==0 || people[0].length==0) return people; PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0]); for (int[] person : people) { pq.offer(person); } List<int[]> list = new ArrayList<>(); while (!pq.isEmpty()) { int[] person = pq.poll(); list.add(person[1], person); } return list.toArray(new int[people.length][people[0].length]); }

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 String getPermutation(int n, int k) { List<Integer> list = new LinkedList<Integer>(); StringBuilder s = new StringBuilder(); int[] factorial = new int[n+1]; int index = 0; factorial[0] = 1; for(int i = 1; i <= n; i++) { list.add(i); factorial[i] = factorial[i - 1] * i; } for(int i = n; i >= 1; i--) { index = (k - 1) % factorial[i] / factorial[i - 1]; s.append(list.get(index)); list.remove(index); } return s.toString(); }

The set [1,2,3,...,n] contains a total of n! unique permutations. By listing and labeling all of the permutations in order, we get the following sequence for n = 3: "123" "132" "213" "231" "312" "321" Given n and k, return the kth permutation sequence. Note: Given n will be between 1 and 9 inclusive. Given k will be between 1 and n! inclusive. Example 1: Input: n = 3, k = 3 Output: "213"

public String convert(String s, int nRows) { char[] c = s.toCharArray(); int len = c.length; StringBuffer[] sb = new StringBuffer[nRows]; for (int i = 0; i < sb.length; i++) sb[i] = new StringBuffer(); int i = 0; while (i < len) { for (int idx = 0; idx < nRows && i < len; idx++) // vertically down sb[idx].append(c[i++]); for (int idx = nRows-2; idx >= 1 && i < len; idx--) // obliquely up sb[idx].append(c[i++]); } for (int idx = 1; idx < sb.length; idx++) sb[0].append(sb[idx]); return sb[0].toString(); }

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 s, int numRows); Example 1: Input: s = "PAYPALISHIRING", numRows = 3 Output: "PAHNAPLSIIGYIR" Example 2: Input: s = "PAYPALISHIRING", numRows = 4 Output: "PINALSIGYAHRPI" Explanation: P I N A L S I G Y A H R P I

public int rob(TreeNode root) { return Math.max(rob(root, true), rob(root, false)); } private int rob(TreeNode node, boolean canRob){ if(node == null) return 0; if (node.left == null && node.right == null) return canRob ? node.val : 0; if(canRob) return node.val + rob(node.left, false) + rob(node.right, false); else return Math.max(rob(node.left, true), rob(node.left, false)) + Math.max(rob(node.right, true), rob(node.right, false)); }

The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that "all houses in this place forms a binary tree". It will automatically contact the police if two directly-linked houses were broken into on the same night. Determine the maximum amount of money the thief can rob tonight without alerting the police. Example 1: Input: [3,2,3,null,3,null,1] 3 / \ 2 3 \ \ 3 1 Output: 7 Explanation: Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.

public int canCompleteCircuit(int[] gas, int[] cost) { int start = 0; int total = 0; int tank = 0; //if car fails at 'start', record the next station for(int i = 0; i < gas.length; i++) { tank = tank + gas[i] - cost[i]; if(tank < 0) { start = i+1; total += tank; tank = 0; } } return (total + tank < 0) ? -1 : start; }

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 in the clockwise direction, otherwise return -1. Note: If there exists a solution, it is guaranteed to be unique. Both input arrays are non-empty and have the same length. Each element in the input arrays is a non-negative integer. Example 1: Input: gas = [1,2,3,4,5] cost = [3,4,5,1,2] Output: 3 Explanation: Start at station 3 (index 3) and fill up with 4 unit of gas. Your tank = 0 + 4 = 4 Travel to station 4. Your tank = 4 - 1 + 5 = 8 Travel to station 0. Your tank = 8 - 2 + 1 = 7 Travel to station 1. Your tank = 7 - 3 + 2 = 6 Travel to station 2. Your tank = 6 - 4 + 3 = 5 Travel to station 3. The cost is 5. Your gas is just enough to travel back to station 3. Therefore, return 3 as the starting index.

public boolean canFinish(int numCourses, int[][] prerequisites) { List<List<Integer>> adjList = new ArrayList<>(); for(int i = 0; i < numCourses; i++) { adjList.add(i, new ArrayList<>()); } for(int[] pre : prerequisites) { adjList.get(pre[1]).add(pre[0]); } int[] visited = new int[numCourses]; // reuse so that each node visited once // must check every node. eg.[1,0],[0,1] for(int i = 0; i < numCourses; i++) { if(dfs(adjList, i, visited)) return false; } return true; } // Check if back edge (directed cycle) exists. If not => DAG => able to topological sort private boolean dfs(List<List<Integer>> adjList, int v, int[] visited) { visited[v] = 1; for(Integer nb : adjList.get(v)) { // visited and nb is v's ancestor => back edge if(visited[nb] == 1) return true; // nb is not visited => tree edge if(visited[nb] == 0 && dfs(adjList, nb, visited)) return true; } visited[v] = 2; return false; }

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? Example 1: Input: 2, [[1,0]] Output: true Explanation: There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.

public int[] findOrder(int numCourses, int[][] prerequisites) { if(prerequisites == null){ throw new IllegalArgumentException("illegal prerequisites array"); } int len = prerequisites.length; //if there is no prerequisites, return a sequence of courses if(len == 0){ int[] res = new int[numCourses]; for(int m=0; m<numCourses; m++){ res[m]=m; } return res; } //records the number of prerequisites each course (0,...,numCourses-1) requires int[] pCounter = new int[numCourses]; for(int i=0; i<len; i++){ pCounter[prerequisites[i][0]]++; } //stores courses that have no prerequisites Queue<Integer> queue = new LinkedList<Integer>(); for(int i=0; i<numCourses; i++){ if(pCounter[i]==0){ queue.add(i); } } int numNoPre = queue.size(); //initialize result int[] result = new int[numCourses]; int j=0; while(!queue.isEmpty()){ int c = queue.remove(); result[j++]=c; for(int i=0; i<len; i++){ if(prerequisites[i][1]==c){ pCounter[prerequisites[i][0]]--; if(pCounter[prerequisites[i][0]]==0){ queue.add(prerequisites[i][0]); numNoPre++; } } } } //return result if(numNoPre==numCourses){ return result; }else{ return new int[0]; } }

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. Example 1: Input: 2, [[1,0]] Output: [0,1] Explanation: 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] .

public int nthUglyNumber(int n) { if(n==1) return 1; PriorityQueue<Long> q = new PriorityQueue(); q.add(1l); for(long i=1; i<n; i++) { long tmp = q.poll(); while(!q.isEmpty() && q.peek()==tmp) tmp = q.poll(); q.add(tmp*2); q.add(tmp*3); q.add(tmp*5); } return q.poll().intValue(); }

Write a program to find the n-th ugly number. Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. Example: Input: n = 10 Output: 12 Explanation: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers. Note: 1 is typically treated as an ugly number. n does not exceed 1690.

public boolean searchMatrix(int[][] matrix, int target) { // always test for edge cases if(matrix.length == 0 || matrix[0].length == 0) return false; for(int i = 0; i < matrix.length; i++) { int n = matrix[i].length; if(target <= matrix[i][n - 1]) { int result = binarySearch(matrix[i], target); if(result >= 0) return true; } } return false; } public int binarySearch(int[] arr, int target) { int lo = 0; int hi = arr.length - 1; while(lo <= hi) { int mid = lo + (hi - lo) / 2; if(target > arr[mid]) { lo = mid + 1; } else if(target < arr[mid]) { hi = mid - 1; } else return mid; } return -1; }

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 from left to right. The first integer of each row is greater than the last integer of the previous row. Example 1: Input: matrix = [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] target = 3 Output: true

We start search the matrix from top right corner, initialize the current position to top right corner, if the target is greater than the value in current position, then the target can not be in entire row of current position because the row is sorted, if the target is less than the value in current position, then the target can not in the entire column because the column is sorted too. We can rule out one row or one column each time, so the time complexity is O(m+n). public class Solution { public boolean searchMatrix(int[][] matrix, int target) { if(matrix == null || matrix.length < 1 || matrix[0].length <1) { return false; } int col = matrix[0].length-1; int row = 0; while(col >= 0 && row <= matrix.length-1) { if(target == matrix[row][col]) { return true; } else if(target < matrix[row][col]) { col--; } else if(target > matrix[row][col]) { row++; } } 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. 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.

// O(n) solution, since there is no recursion at all public int rob(int[] nums) { if (nums == null || nums.length == 0) return 0; int n = nums.length; if (n == 1) { return nums[0]; } return Math.max(robHelper(nums, 0, n - 2), robHelper(nums, 1, n - 1)); } private int robHelper(int[] nums, int start, int end) { int curr, prev, prev2; curr = prev = prev2 = 0; for (int i = start; i <= end; i++) { curr = Math.max(prev2 + nums[i], prev); prev2 = prev; prev = curr; } return curr; }

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, 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. Example 1: Input: [2,3,2] Output: 3 Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2), because they are adjacent houses.

public Node flatten(Node head) { if(head == null || (head.next == null && head.child == null)) { return head; } Stack<Node> stack = new Stack<>(); stack.push(head); Node prev = null; while(!stack.isEmpty()) { Node curr = stack.pop(); if(prev == null) { prev = curr; } else { prev.next = curr; curr.prev = prev; prev = curr; } if(curr.next != null) { stack.push(curr.next); } if(curr.child != null) { stack.push(curr.child); } curr.child = null; } return head; }

You are given a doubly linked list which in addition to the next and previous pointers, it could have a child pointer, which may or may not point to a separate doubly linked list. These child lists may have one or more children of their own, and so on, to produce a multilevel data structure, as shown in the example below. Flatten the list so that all the nodes appear in a single-level, doubly linked list. You are given the head of the first level of the list. Example: Input: 1---2---3---4---5---6--NULL | 7---8---9---10--NULL | 11--12--NULL Output: 1-2-3-7-8-11-12-9-10-4-5-6-NULL

public void rotate(int[][] matrix) { int len = matrix.length; rotateHelper(matrix, 0, len-1); } public void rotateHelper(int[][] matrix, int j, int n) { if(j > n/2) return; for(int i = j; i < n-j; i++) { int tmp = matrix[j][i]; matrix[j][i] = matrix[n-i][j]; matrix[n-i][j] = matrix[n-j][n-i]; matrix[n-j][n-i] = matrix[i][n-j]; matrix[i][n-j] = tmp; } rotate_helper(matrix, j+1, n); }

You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). Note: You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation. Example 1: Given input matrix = [ [1,2,3], [4,5,6], [7,8,9] ], rotate the input matrix in-place such that it becomes: [ [7,4,1], [8,5,2], [9,6,3] ]

public ListNode addTwoNumbers(ListNode l1, ListNode l2) { int carry = 0; int sum = l1.val + l2.val; if(sum >= 10) { carry = 1; sum = sum % 10; } ListNode node = new ListNode(sum); ListNode head = node; l1 = l1.next; l2 = l2.next; addNext(l1, l2, node, carry); return head; } void addNext(ListNode l1, ListNode l2, ListNode node, int carry) { if(l1 == null && l2 == null) { if(carry != 0) { node.next = new ListNode(carry); } return; } int val = carry; if(l1 != null) { val += l1.val; } if(l2 != null) { val += l2.val; } if(val >= 10) { carry = 1; val = val % 10; } else { carry = 0; } node.next = new ListNode(val); addNext(l1 == null ? null: l1.next, l2 == null ? null : l2.next, node.next, carry); }

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 Explanation: 342 + 465 = 807.


Conjuntos de estudio relacionados

Pharmacology Ch. 19 Introduction to Nerves and the Nervous System

View Set

ARHS 2 (courbet/haussmann/manet/impressionism)

View Set

IT Project Management Chapters 1-3

View Set