From 6c7d858a759c22e54394afaceb91cbed0b5554f5 Mon Sep 17 00:00:00 2001 From: jw2013 Date: Fri, 30 May 2014 22:32:12 -0400 Subject: [PATCH 01/10] add more solutions --- Decode Ways.py | 13 +++++++++ Distinct Subsequences.py | 11 ++++++++ Gas Station.py | 14 ++++++++++ Implement strStr().py | 11 ++++++++ Largest Rectangle in Histogram.py | 14 ++++++++++ ... Substring Without Repeating Characters.py | 14 ++++++++++ Longest Valid Parentheses.py | 15 +++++++++++ Maximal Rectangle.py | 27 +++++++++++++++++++ Permutation Sequence.py | 12 +++++++++ Sqrt(x).py | 10 +++++++ 10 files changed, 141 insertions(+) create mode 100644 Decode Ways.py create mode 100644 Distinct Subsequences.py create mode 100644 Gas Station.py create mode 100644 Implement strStr().py create mode 100644 Largest Rectangle in Histogram.py create mode 100644 Longest Substring Without Repeating Characters.py create mode 100644 Longest Valid Parentheses.py create mode 100644 Maximal Rectangle.py create mode 100644 Permutation Sequence.py create mode 100644 Sqrt(x).py diff --git a/Decode Ways.py b/Decode Ways.py new file mode 100644 index 0000000..b905ed7 --- /dev/null +++ b/Decode Ways.py @@ -0,0 +1,13 @@ +class Solution: + def numDecodings(self, s): + if len(s) == 0: + return 0 + prev, prev_prev = 1, 0 + for i in range(len(s)): + current = 0 + if s[i] != '0': + current = prev + if i > 0 and (s[i - 1] == "1" or (s[i - 1] == "2" and s[i] <= "6")): + current += prev_prev + prev, prev_prev = current, prev + return prev \ No newline at end of file diff --git a/Distinct Subsequences.py b/Distinct Subsequences.py new file mode 100644 index 0000000..3ef3b6c --- /dev/null +++ b/Distinct Subsequences.py @@ -0,0 +1,11 @@ +class Solution: + def numDistinct(self, S, T): + ways = [[0 for j in range(len(S) + 1)] for i in range(len(T) + 1)] + for i in range(len(S) + 1): + ways[0][i] = 1 + for i in range(1, len(T) + 1): + for j in range(1, len(S) + 1): + ways[i][j] = ways[i][j - 1] + if T[i - 1] == S[j - 1]: + ways[i][j] += ways[i - 1][j - 1] + return ways[len(T)][len(S)] \ No newline at end of file diff --git a/Gas Station.py b/Gas Station.py new file mode 100644 index 0000000..ca5c382 --- /dev/null +++ b/Gas Station.py @@ -0,0 +1,14 @@ +class Solution: + def canCompleteCircuit(self, gas, cost): + start, sum_so_far, sum = 0, 0, 0 + for i in range(len(gas)): + diff = gas[i] - cost[i] + if sum_so_far + diff < 0: + start = i + 1 + sum_so_far = 0 + else: + sum_so_far += diff + sum += diff + if sum >= 0: + return start + return -1 \ No newline at end of file diff --git a/Implement strStr().py b/Implement strStr().py new file mode 100644 index 0000000..391e2e6 --- /dev/null +++ b/Implement strStr().py @@ -0,0 +1,11 @@ +class Solution: + def strStr(self, haystack, needle): + for i in range(len(haystack) - len(needle) + 1): + found = True + for j in range(len(needle)): + if haystack[i + j] != needle[j]: + found = False + break + if found: + return haystack[i:] + return None \ No newline at end of file diff --git a/Largest Rectangle in Histogram.py b/Largest Rectangle in Histogram.py new file mode 100644 index 0000000..6065fb8 --- /dev/null +++ b/Largest Rectangle in Histogram.py @@ -0,0 +1,14 @@ +class Solution: + def largestRectangleArea(self, height): + increasing, area, i = [], 0, 0 + while i <= len(height): + if len(increasing) == 0 or (i < len(height) and height[i] > height[increasing[-1]]): + increasing.append(i) + i += 1 + else: + last = increasing.pop() + if len(increasing) == 0: + area = max(area, height[last] * i) + else: + area = max(area, height[last] * (i - increasing[-1] - 1)) + return area \ No newline at end of file diff --git a/Longest Substring Without Repeating Characters.py b/Longest Substring Without Repeating Characters.py new file mode 100644 index 0000000..8d75576 --- /dev/null +++ b/Longest Substring Without Repeating Characters.py @@ -0,0 +1,14 @@ +class Solution: + def lengthOfLongestSubstring(self, s): + count, start, longest = [False for i in range(256)], 0, 0 + for i in range(len(s)): + if count[ord(s[i])] == False: + count[ord(s[i])] = True + else: + longest = max(i - start, longest) + while s[start] != s[i]: + count[ord(s[start])] = False + start += 1 + start += 1 + longest = max(len(s) - start, longest) + return longest \ No newline at end of file diff --git a/Longest Valid Parentheses.py b/Longest Valid Parentheses.py new file mode 100644 index 0000000..e0119de --- /dev/null +++ b/Longest Valid Parentheses.py @@ -0,0 +1,15 @@ +class Solution: + def longestValidParentheses(self, s): + longest, last, indices = 0, 0, [] + for i in range(len(s)): + if s[i] == '(': + indices.append(i) + elif len(indices) == 0: + last = i + 1 + else: + index = indices.pop() + if len(indices) == 0: + longest = max(longest, i - last + 1) + else: + longest = max(longest, i - indices[-1]) + return longest \ No newline at end of file diff --git a/Maximal Rectangle.py b/Maximal Rectangle.py new file mode 100644 index 0000000..211715b --- /dev/null +++ b/Maximal Rectangle.py @@ -0,0 +1,27 @@ +class Solution: + def maximalRectangle(self, matrix): + heights = [[0 for j in range(len(matrix[0]))] for i in range(len(matrix))] + for i in range(0, len(matrix)): + for j in range(len(matrix[0])): + if matrix[i][j] == "0": + heights[i][j] = 0 + elif i == 0: + heights[i][j] = 1 + else: + heights[i][j] = int(heights[i - 1][j]) + 1 + return reduce(lambda acc, i: max(acc, self.largestRectangleArea(heights[i])), range(len(heights)), 0) + + # This is the solution for question Largest Rectangle in Histogram + def largestRectangleArea(self, height): + increasing, area, i = [], 0, 0 + while i <= len(height): + if len(increasing) == 0 or (i < len(height) and height[i] > height[increasing[-1]]): + increasing.append(i) + i += 1 + else: + last = increasing.pop() + if len(increasing) == 0: + area = max(area, height[last] * i) + else: + area = max(area, height[last] * (i - increasing[-1] - 1)) + return area \ No newline at end of file diff --git a/Permutation Sequence.py b/Permutation Sequence.py new file mode 100644 index 0000000..0dde1f9 --- /dev/null +++ b/Permutation Sequence.py @@ -0,0 +1,12 @@ +class Solution: + def getPermutation(self, n, k): + seq, k, fact = "", k - 1, math.factorial(n - 1) + perm = [i for i in range(1, n + 1)] + for i in reversed(range(n)): + curr = perm[k / fact] + seq += str(curr) + perm.remove(curr) + if i > 0: + k %= fact + fact /= i + return seq \ No newline at end of file diff --git a/Sqrt(x).py b/Sqrt(x).py new file mode 100644 index 0000000..138c1c1 --- /dev/null +++ b/Sqrt(x).py @@ -0,0 +1,10 @@ +class Solution: + def sqrt(self, x): + low, high = 0, x / 2 + 1 + while high >= low: + mid = (high + low) / 2 + if x < mid * mid: + high = mid - 1 + else: + low = mid + 1 + return int(high) \ No newline at end of file From 85e822795da164a4fa6f4411f57d144b06d13845 Mon Sep 17 00:00:00 2001 From: jw2013 Date: Sun, 1 Jun 2014 22:22:53 -0400 Subject: [PATCH 02/10] add more solutions --- Binary Tree Maximum Path Sum.py | 13 +++++++++++++ Clone Graph.py | 19 +++++++++++++++++++ Insert Interval.py | 16 ++++++++++++++++ Merge Intervals.py | 13 +++++++++++++ Restore IP Addresses.py | 22 ++++++++++++++++++++++ Simplify Path.py | 10 ++++++++++ Word Search.py | 18 ++++++++++++++++++ ZigZag Conversion.py | 13 +++++++++++++ 8 files changed, 124 insertions(+) create mode 100644 Binary Tree Maximum Path Sum.py create mode 100644 Clone Graph.py create mode 100644 Insert Interval.py create mode 100644 Merge Intervals.py create mode 100644 Restore IP Addresses.py create mode 100644 Simplify Path.py create mode 100644 Word Search.py create mode 100644 ZigZag Conversion.py diff --git a/Binary Tree Maximum Path Sum.py b/Binary Tree Maximum Path Sum.py new file mode 100644 index 0000000..b48ad25 --- /dev/null +++ b/Binary Tree Maximum Path Sum.py @@ -0,0 +1,13 @@ +class Solution: + maxSum = -2147483648 + def maxPathSum(self, root): + self.maxPathRecur(root) + return self.maxSum + + def maxPathRecur(self, root): + if root == None: + return 0 + left = max(0, self.maxPathRecur(root.left)) + right = max(0, self.maxPathRecur(root.right)) + self.maxSum = max(self.maxSum, left + right + root.val) + return root.val + max(left, right) \ No newline at end of file diff --git a/Clone Graph.py b/Clone Graph.py new file mode 100644 index 0000000..459cdb7 --- /dev/null +++ b/Clone Graph.py @@ -0,0 +1,19 @@ +class Solution: + def cloneGraph(self, node): + if node == None: + return None + start = UndirectedGraphNode(node.label) + map, current = {node: start}, [node] + while len(current) > 0: + next = [] + for x in current: + for neighbor in x.neighbors: + if neighbor not in map: + neighbor_copy = UndirectedGraphNode(neighbor.label) + next.append(neighbor) + map[x].neighbors.append(neighbor_copy) + map[neighbor] = neighbor_copy + else: + map[x].neighbors.append(map[neighbor]) + current = next + return start \ No newline at end of file diff --git a/Insert Interval.py b/Insert Interval.py new file mode 100644 index 0000000..57c3897 --- /dev/null +++ b/Insert Interval.py @@ -0,0 +1,16 @@ +class Solution: + def insert(self, intervals, newInterval): + return self.merge(intervals + [newInterval]) + + def merge(self, intervals): + if len(intervals) == 0: + return intervals + intervals.sort(key = lambda x: x.start) + result = [intervals[0]] + for i in range(1, len(intervals)): + current, prev = intervals[i], result[-1] + if current.start <= prev.end: + prev.end = max(prev.end, current.end) + else: + result.append(current) + return result \ No newline at end of file diff --git a/Merge Intervals.py b/Merge Intervals.py new file mode 100644 index 0000000..90222af --- /dev/null +++ b/Merge Intervals.py @@ -0,0 +1,13 @@ +class Solution: + def merge(self, intervals): + if len(intervals) == 0: + return intervals + intervals.sort(key = lambda x: x.start) + result = [intervals[0]] + for i in range(1, len(intervals)): + current, prev = intervals[i], result[-1] + if current.start <= prev.end: + prev.end = max(prev.end, current.end) + else: + result.append(current) + return result \ No newline at end of file diff --git a/Restore IP Addresses.py b/Restore IP Addresses.py new file mode 100644 index 0000000..f355b4c --- /dev/null +++ b/Restore IP Addresses.py @@ -0,0 +1,22 @@ +class Solution: + def restoreIpAddresses(self, s): + result = [] + self.restoreIpAddressesRecur(result, s, "", 0) + return result + + def restoreIpAddressesRecur(self, result, s, current, dots): + # pruning to improve performance + if (4 - dots) * 3 < len(s): + return + if dots == 3: + if self.isValid(s): + result.append(current + s) + else: + for i in range(3): + if len(s) > i and self.isValid(s[:i + 1]): + self.restoreIpAddressesRecur(result, s[i + 1:], current + s[:i + 1] + '.', dots + 1) + + def isValid(self, s): + if len(s) == 0 or (s[0] == "0" and s != "0"): + return False + return int(s) < 256 \ No newline at end of file diff --git a/Simplify Path.py b/Simplify Path.py new file mode 100644 index 0000000..3c1a08e --- /dev/null +++ b/Simplify Path.py @@ -0,0 +1,10 @@ +class Solution: + def simplifyPath(self, path): + stack, tokens = [], path.split('/') + for token in tokens: + if token == "..": + if len(stack) > 0: + stack.pop() + elif token != "" and token != ".": + stack.append(token) + return "/" + reduce(lambda acc, x: acc + x + "/", stack, "")[:-1] \ No newline at end of file diff --git a/Word Search.py b/Word Search.py new file mode 100644 index 0000000..4243de2 --- /dev/null +++ b/Word Search.py @@ -0,0 +1,18 @@ +class Solution: + def exist(self, board, word): + visited = [[0 for y in range(len(board[0]))] for x in range(len(board))] + for i in range(len(board)): + for j in range(len(board[0])): + if self.existRecur(board, word, visited, i, j) == True: + return True + return False + + def existRecur(self, board, word, visited, i, j): + if len(word) == 0: + return True + if i >= len(board) or j >= len(board[0]) or i < 0 or j < 0 or visited[i][j] == 1 or board[i][j] != word[0]: + return False + visited[i][j] = 1 + found = self.existRecur(board, word[1:], visited, i + 1, j) or self.existRecur(board, word[1:], visited, i - 1, j) or self.existRecur(board, word[1:], visited, i, j + 1) or self.existRecur(board, word[1:], visited, i, j - 1) + visited[i][j] = 0 + return found \ No newline at end of file diff --git a/ZigZag Conversion.py b/ZigZag Conversion.py new file mode 100644 index 0000000..f2bd258 --- /dev/null +++ b/ZigZag Conversion.py @@ -0,0 +1,13 @@ +class Solution: + def convert(self, s, nRows): + step, zigzag = 2 * nRows - 2, "" + if s == None or len(s) == 0 or nRows <= 0: + return "" + if nRows == 1: + return s + for i in range(nRows): + for j in range(i, len(s), step): + zigzag += s[j] + if i > 0 and i < nRows - 1 and j + step - 2 * i < len(s): + zigzag += s[j + step - 2 * i] + return zigzag \ No newline at end of file From 61356cc433d902205ba20eb333d69d9de363657d Mon Sep 17 00:00:00 2001 From: ChenWu Date: Sat, 20 Apr 2019 09:47:45 -0700 Subject: [PATCH 03/10] ValidSqure --- ValidSquare | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 ValidSquare diff --git a/ValidSquare b/ValidSquare new file mode 100644 index 0000000..0ba4d86 --- /dev/null +++ b/ValidSquare @@ -0,0 +1,29 @@ +class Solution { + public boolean validSquare(int[] p1, int[] p2, int[] p3, int[] p4) { + int[][] p = new int[4][2]; + p[0] = p1; + p[1] = p2; + p[2] = p3; + p[3] = p4; + Map map = new HashMap<>(); + for (int i = 1; i < 4; i++) { + for (int j = i-1; j >= 0 ;j--) { + int dist = getDistanceSquare(p[i], p[j]); + map.put(dist, (map.containsKey(dist) ? map.get(dist) : 0) + 1); + } + } + if (map.size() != 2) { + return; + } + for (Integer key : map.keys()) { + if (map.get(key) != 2 && map.get(key) != 4) { + return false; + } + } + return true; + } + + private int getDistanceSquare(int[] p1, int[] p2) { + return (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]); + } +} From d0018a27e2c5623730b056a13bcbcc023057513a Mon Sep 17 00:00:00 2001 From: ChenWu Date: Sat, 20 Apr 2019 11:07:53 -0700 Subject: [PATCH 04/10] CanPlaceFlowers --- CanPlaceFlowers | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 CanPlaceFlowers diff --git a/CanPlaceFlowers b/CanPlaceFlowers new file mode 100644 index 0000000..c077e45 --- /dev/null +++ b/CanPlaceFlowers @@ -0,0 +1,57 @@ +/* +605. Can Place Flowers +Easy + +441 + +250 + +Favorite + +Share +Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, flowers cannot be planted in adjacent plots - they would compete for water and both would die. + +Given a flowerbed (represented as an array containing 0 and 1, where 0 means empty and 1 means not empty), and a number n, return if n new flowers can be planted in it without violating the no-adjacent-flowers rule. + +Example 1: +Input: flowerbed = [1,0,0,0,1], n = 1 +Output: True +Example 2: +Input: flowerbed = [1,0,0,0,1], n = 2 +Output: False +Note: +The input array won't violate no-adjacent-flowers rule. +The input array size is in the range of [1, 20000]. +n is a non-negative integer which won't exceed the input array size. +*/ +// the idea is dp, 0 means try not to plant and 1 means try to plant +// if current is 1, then cannot plant, so max so far is the same for both 0 and 1. +// for 1 meaning that we try to plant and planted, but did not use new flowerbed. +// if current is 0, means maybe able to plant, then need to check if i-1 is also 0, +// if so, it's dp[0][i-1] + 1, assuming did not plant in i-1; otherwise, it is 0, we cannot plant. + + +class Solution { + public boolean canPlaceFlowers(int[] flowerbed, int l) { + if (flowerbed.length == 0) { + return false; + } + if (flowerbed.length == 1) { + return (1 - flowerbed[0]) >= l; + } + int n = flowerbed.length; + int[][] dp = new int[2][n]; + dp[0][0] = 0; + dp[1][0] = flowerbed[0] == 0 && flowerbed[1] == 0 ? 1 : 0; + for (int i = 1; i < n; i++) { + if (flowerbed[i] == 1) { + dp[0][i] = dp[0][i-1]; + dp[1][i] = dp[0][i-1]; + } else { + dp[0][i] = Math.max(dp[0][i-1], dp[1][i-1]); + dp[1][i] = flowerbed[i-1] == 0 ? dp[0][i-1] + 1 : 0; + } + } + return Math.max(dp[0][n-1], dp[1][n-1]) >= l; + } +} From 769401cb6b76506fe8959beb470578ff25c6c86e Mon Sep 17 00:00:00 2001 From: ChenWu Date: Sat, 20 Apr 2019 11:09:12 -0700 Subject: [PATCH 05/10] ConstructStringFromBinaryTree --- ConstructStringFromBinaryTree | 71 +++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 ConstructStringFromBinaryTree diff --git a/ConstructStringFromBinaryTree b/ConstructStringFromBinaryTree new file mode 100644 index 0000000..efa21d7 --- /dev/null +++ b/ConstructStringFromBinaryTree @@ -0,0 +1,71 @@ +/* +606. Construct String from Binary Tree +Easy + +Favorite + +Share +You need to construct a string consists of parenthesis and integers from a binary tree with the preorder traversing way. + +The null node needs to be represented by empty parenthesis pair "()". And you need to omit all the empty parenthesis pairs that don't affect the one-to-one mapping relationship between the string and the original binary tree. + +Example 1: +Input: Binary tree: [1,2,3,4] + 1 + / \ + 2 3 + / + 4 + +Output: "1(2(4))(3)" + +Explanation: Originallay it needs to be "1(2(4)())(3()())", +but you need to omit all the unnecessary empty parenthesis pairs. +And it will be "1(2(4))(3)". +Example 2: +Input: Binary tree: [1,2,3,null,4] + 1 + / \ + 2 3 + \ + 4 + +Output: "1(2()(4))(3)" + +Explanation: Almost the same as the first example, +except we can't omit the first parenthesis pair to break the one-to-one mapping relationship between the input and the output. +*/ + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +class Solution { + public String tree2str(TreeNode t) { + StringBuilder sb = new StringBuilder(); + recursiveBuildString(t, sb); + return sb.toString(); + } + + public void recursiveBuildString(TreeNode node, StringBuilder sb) { + if (node == null) { + // sb.append(')'); + return; + } + sb.append(node.val); + sb.append("("); + recursiveBuildString(node.left, sb); + sb.append(")("); + recursiveBuildString(node.right, sb); + // remove last ones; + sb.append(")"); + while(sb.length() >= 2 && sb.substring(sb.length()-2).equals("()")) { + sb.setLength(sb.length()-2); + } + } +} From 817c05f8b25a23dfe89d5470f9129a980b30d034 Mon Sep 17 00:00:00 2001 From: ChenWu Date: Sat, 20 Apr 2019 21:52:25 -0700 Subject: [PATCH 06/10] ValidTriangleNumber --- ValidTriangleNumber | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 ValidTriangleNumber diff --git a/ValidTriangleNumber b/ValidTriangleNumber new file mode 100644 index 0000000..0641e44 --- /dev/null +++ b/ValidTriangleNumber @@ -0,0 +1,39 @@ +/* +611. Valid Triangle Number +Medium + +Given an array consists of non-negative integers, your task is to count the number of triplets chosen from the array that can make triangles if we take them as side lengths of a triangle. +Example 1: +Input: [2,2,3,4] +Output: 3 +Explanation: +Valid combinations are: +2,3,4 (using the first 2) +2,3,4 (using the second 2) +2,2,3 +Note: +The length of the given array won't exceed 1000. +The integers in the given array are in the range of [0, 1000]. + +*/ +class Solution { + public int triangleNumber(int[] nums) { + if (nums.length < 3) { + return 0; + } + int res = 0; + Arrays.sort(nums); + for (int i = 0; i < nums.length - 2; i++) { + for (int j = i+1; j< nums.length - 1; j++) { + int k = nums.length - 1; + while (k > j && nums[k] >= nums[i] + nums[j]) { + k--; + } + if (k>j) { + res += k-j; + } + } + } + return res; + } +} From 133b0436cf9d59717fbea2781cbe73fdeda96421 Mon Sep 17 00:00:00 2001 From: ChenWu Date: Sun, 21 Apr 2019 10:55:45 -0700 Subject: [PATCH 07/10] TaskScheduler --- FindDuplicateFileInSystem | 67 ++++++++++++++++++++++++++++++ TaskScheduler | 86 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 FindDuplicateFileInSystem create mode 100644 TaskScheduler diff --git a/FindDuplicateFileInSystem b/FindDuplicateFileInSystem new file mode 100644 index 0000000..fe27440 --- /dev/null +++ b/FindDuplicateFileInSystem @@ -0,0 +1,67 @@ +/* +609. Find Duplicate File in System +Medium + +Given a list of directory info including directory path, and all the files with contents in this directory, you need to find out all the groups of duplicate files in the file system in terms of their paths. + +A group of duplicate files consists of at least two files that have exactly the same content. + +A single directory info string in the input list has the following format: + +"root/d1/d2/.../dm f1.txt(f1_content) f2.txt(f2_content) ... fn.txt(fn_content)" + +It means there are n files (f1.txt, f2.txt ... fn.txt with content f1_content, f2_content ... fn_content, respectively) in directory root/d1/d2/.../dm. Note that n >= 1 and m >= 0. If m = 0, it means the directory is just the root directory. + +The output is a list of group of duplicate file paths. For each group, it contains all the file paths of the files that have the same content. A file path is a string that has the following format: + +"directory_path/file_name.txt" + +Example 1: + +Input: +["root/a 1.txt(abcd) 2.txt(efgh)", "root/c 3.txt(abcd)", "root/c/d 4.txt(efgh)", "root 4.txt(efgh)"] +Output: +[["root/a/2.txt","root/c/d/4.txt","root/4.txt"],["root/a/1.txt","root/c/3.txt"]] + +Note: +String.split() takes regular expression in [] that can split by multiple delimiters + +*/ +class Solution { + public List> findDuplicate(String[] paths) { + // process + Map> record = new HashMap<>(); + for (String path : paths) { + preprocess(path, record); + } + List> res = new ArrayList<>(); + for (String key : record.keySet()) { + List files = record.get(key); + if (files.size() > 1) { + res.add(files); + } + } + return res; + } + + private void preprocess(String input, Map> record) { + if (input == null || input.length() == 0) { + return; + } + String[] tokens = input.split(" "); + String dir = tokens[0]; + for (int i = 1 ;i < tokens.length; i++) { + String[] fileAndContent = tokens[i].split("[()]"); + String content; + if (fileAndContent.length == 1) { + content = ""; + } else { + content = fileAndContent[1]; + } + if (!record.containsKey(content)) { + record.put(content, new ArrayList<>()); + } + record.get(content).add(dir + "/" + fileAndContent[0]); + } + } +} diff --git a/TaskScheduler b/TaskScheduler new file mode 100644 index 0000000..050b92b --- /dev/null +++ b/TaskScheduler @@ -0,0 +1,86 @@ +/* +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: + +Input: tasks = ["A","A","A","B","B","B"], n = 2 +Output: 8 +Explanation: A -> B -> idle -> A -> B -> idle -> A -> B. + +Note: + +The number of tasks is in the range [1, 10000]. +The integer n is in the range [0, 100]. +*/ +class Solution { + static class Task { + int priority; + char task; + int time; + public Task(char task, int priority) { + this.task = task; + this.priority = priority; + this.time = 0; + } + } + + public int leastInterval(char[] tasks, int n) { + //preprocess + List taskList = groupTasks(tasks); + + PriorityQueue q = new PriorityQueue(taskList.size(), new Comparator() { + public int compare(Task t1, Task t2) { + return t2.priority - t1.priority; + } + }); + for (Task t : taskList) { + q.add(t); + } + /* + can not just use one set, otherwise it will cause exception of modifying collection while iterating + */ + Set waitSet = new HashSet<>(); + Set toAddSet = new HashSet<>(); + int time = 0; + while (q.size()> 0 || waitSet.size() > 0) { + time++; + if (q.size() > 0) { + Task t = q.poll(); + t.priority--; + t.time = time; + if (t.priority > 0) { + waitSet.add(t); + } + } + for (Task t : waitSet) { + if (time - t.time >= n) { + toAddSet.add(t); + } + } + for (Task t : toAddSet) { + waitSet.remove(t); + q.add(t); + } + toAddSet.clear(); + } + return time; + } + + private List groupTasks(char[] tasks) { + Map map = new HashMap<>(); + for (char c : tasks) { + if (!map.containsKey(c)) { + map.put(c, 0); + } + map.put(c, map.get(c) + 1); + } + List res = new ArrayList<>(); + for (Character c: map.keySet()) { + Task t = new Task(c, map.get(c)); + res.add(t); + } + return res; + } +} From 13586a92112231f20f791b0098e55d42089bb77d Mon Sep 17 00:00:00 2001 From: ChenWu Date: Sun, 21 Apr 2019 21:26:45 -0700 Subject: [PATCH 08/10] AddOneRowToTree --- AddOneRowToTree | 95 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 AddOneRowToTree diff --git a/AddOneRowToTree b/AddOneRowToTree new file mode 100644 index 0000000..603263a --- /dev/null +++ b/AddOneRowToTree @@ -0,0 +1,95 @@ +/* +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 + +Example 2: +Input: +A binary tree as following: + 4 + / + 2 + / \ + 3 1 + +v = 1 + +d = 3 + +Output: + 4 + / + 2 + / \ + 1 1 + / \ +3 1 +Note: +The given d is in range [1, maximum depth of the given tree + 1]. +The given binary tree has at least one tree node. +*/ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ + + /* +The tricky part is to add a new row at the bottom of the root and some intermediate nodes do +not reach depth d and have nulls in subtree + */ +class Solution { + public TreeNode addOneRow(TreeNode root, int v, int d) { + TreeNode newRoot = recursiveAddRow(root, d, v, true); + return newRoot; + } + + private TreeNode recursiveAddRow(TreeNode root, int d, int v, boolean isLeft) { + if (d < 1) { + return root; + } + if (d > 1) { + if (root != null) { + TreeNode left = recursiveAddRow(root.left, d - 1, v, true); + TreeNode right = recursiveAddRow(root.right, d - 1, v, false); + root.left = left; + root.right = right; + } + return root; + } + TreeNode newNode = new TreeNode(v); + if (isLeft) { + newNode.left = root; + } else { + newNode.right = root; + } + return newNode; + } +} +*/ From b5fe10320fe2651def250b9c29795d7ee25cdc9b Mon Sep 17 00:00:00 2001 From: ChenWu Date: Tue, 23 Apr 2019 19:52:08 -0700 Subject: [PATCH 09/10] CircularQueue --- DesignCircularQueue | 106 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 DesignCircularQueue diff --git a/DesignCircularQueue b/DesignCircularQueue new file mode 100644 index 0000000..d577aa0 --- /dev/null +++ b/DesignCircularQueue @@ -0,0 +1,106 @@ +/* +Design your implementation of the circular queue. The circular queue is a linear data structure in which the operations are performed based on FIFO (First In First Out) principle and the last position is connected back to the first position to make a circle. It is also called "Ring Buffer". + +One of the benefits of the circular queue is that we can make use of the spaces in front of the queue. In a normal queue, once the queue becomes full, we cannot insert the next element even if there is a space in front of the queue. But using the circular queue, we can use the space to store new values. + +Your implementation should support following operations: + +MyCircularQueue(k): Constructor, set the size of the queue to be k. +Front: Get the front item from the queue. If the queue is empty, return -1. +Rear: Get the last item from the queue. If the queue is empty, return -1. +enQueue(value): Insert an element into the circular queue. Return true if the operation is successful. +deQueue(): Delete an element from the circular queue. Return true if the operation is successful. +isEmpty(): Checks whether the circular queue is empty or not. +isFull(): Checks whether the circular queue is full or not. + + +Example: + +MyCircularQueue circularQueue = new MyCircularQueue(3); // set the size to be 3 +circularQueue.enQueue(1); // return true +circularQueue.enQueue(2); // return true +circularQueue.enQueue(3); // return true +circularQueue.enQueue(4); // return false, the queue is full +circularQueue.Rear(); // return 3 +circularQueue.isFull(); // return true +circularQueue.deQueue(); // return true +circularQueue.enQueue(4); // return true +circularQueue.Rear(); // return 4 + +Note: + +All values will be in the range of [0, 1000]. +The number of operations will be in the range of [1, 1000]. +Please do not use the built-in Queue library. + +*/ +class MyCircularQueue { + + int[] q; + int start; + int end; + int count; + /** Initialize your data structure here. Set the size of the queue to be k. */ + public MyCircularQueue(int k) { + q = new int[k]; + start = 0; + count = 0; + } + + /** Insert an element into the circular queue. Return true if the operation is successful. */ + public boolean enQueue(int value) { + if (isFull()) { + return false; + } + q[(start + count) % q.length] = value; + count++; + return true; + } + + /** Delete an element from the circular queue. Return true if the operation is successful. */ + public boolean deQueue() { + if (isEmpty()) { + return false; + } + count--; + start = (start + 1) % q.length; + return true; + } + + /** Get the front item from the queue. */ + public int Front() { + if (isEmpty()) { + return -1; + } + return q[start]; + } + + /** Get the last item from the queue. */ + public int Rear() { + if (isEmpty()) { + return -1; + } + return q[(start + count - 1) % q.length]; + } + + /** Checks whether the circular queue is empty or not. */ + public boolean isEmpty() { + return count == 0; + } + + /** Checks whether the circular queue is full or not. */ + public boolean isFull() { + return count == q.length; + } +} + +/** + * Your MyCircularQueue object will be instantiated and called as such: + * MyCircularQueue obj = new MyCircularQueue(k); + * boolean param_1 = obj.enQueue(value); + * boolean param_2 = obj.deQueue(); + * int param_3 = obj.Front(); + * int param_4 = obj.Rear(); + * boolean param_5 = obj.isEmpty(); + * boolean param_6 = obj.isFull(); + */ From 37612c1b2f3e3a6f97752fcfcdccec93c617d53a Mon Sep 17 00:00:00 2001 From: ChenWu Date: Tue, 23 Apr 2019 22:35:11 -0700 Subject: [PATCH 10/10] SmallestRange --- MaximumProductOfThreeNumbers | 42 +++++++++++++++++++++++ SmallestRange | 65 ++++++++++++++++++++++++++++++++++++ SumofSquareNumbers | 34 +++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 MaximumProductOfThreeNumbers create mode 100644 SmallestRange create mode 100644 SumofSquareNumbers diff --git a/MaximumProductOfThreeNumbers b/MaximumProductOfThreeNumbers new file mode 100644 index 0000000..ab3da01 --- /dev/null +++ b/MaximumProductOfThreeNumbers @@ -0,0 +1,42 @@ +/* +628. Maximum Product of Three Numbers +Easy +Given an integer array, find three numbers whose product is maximum and output the maximum product. + +Example 1: + +Input: [1,2,3] +Output: 6 + +Example 2: + +Input: [1,2,3,4] +Output: 24 + +Note: + +The length of the given array will be in range [3,104] and all elements are in the range [-1000, 1000]. +Multiplication of any three numbers in the input won't exceed the range of 32-bit signed integer. +*/ +class Solution { + public int maximumProduct(int[] nums) { + int n = nums.length; + int min = Math.min(nums[0], nums[1]); + int max = Math.max(nums[0], nums[1]); + int[] doubleMin = new int[n]; + int[] doubleMax = new int[n]; + doubleMin[1] = nums[0] * nums[1]; + doubleMax[1] = nums[0] * nums[1]; + for (int i = 2; i< n; i++) { + doubleMin[i] = Math.min(doubleMin[i-1], Math.min(nums[i] * min, nums[i] * max)); + doubleMax[i] = Math.max(doubleMax[i-1], Math.max(nums[i] * min, nums[i] * max)); + min = Math.min(min, nums[i]); + max = Math.max(max, nums[i]); + } + int tripleMax = nums[0] * nums[1] * nums[2]; + for (int i = 3; i= here. +1 <= k <= 3500 +-105 <= value of elements <= 105. +For Java users, please note that the input type has been changed to List>. And after you reset the code template, you'll see this point. +*/ +class Solution { + static class Tuple { + Integer value; + Integer numsIndex; + Integer listIndex; + public Tuple(Integer value, Integer listIndex, Integer numsIndex) { + this.value = value; + this.numsIndex = numsIndex; + this.listIndex = listIndex; + } + } + public int[] smallestRange(List> nums) { + int k = nums.size(); + PriorityQueue q = new PriorityQueue<>(k, new Comparator() { + public int compare(Tuple a, Tuple b) { + return a.value - b.value; + } + }); + int i = 0; + int max = Integer.MIN_VALUE; + for (List list : nums) { + if (list.size() > 0) { + Tuple t = new Tuple(list.get(0), 0, i); + q.offer(t); + max = Math.max(max, list.get(0)); + } + i++; + } + int start = 0; + int end = Integer.MAX_VALUE; + while(!q.isEmpty()) { + Tuple t = q.peek(); + if (max - t.value < end - start && q.size() == k) { + end = max; + start = t.value; + } + q.poll(); + if (t.listIndex + 1 < nums.get(t.numsIndex).size()) { + q.offer(new Tuple(nums.get(t.numsIndex).get(t.listIndex + 1), t.listIndex + 1, t.numsIndex)); + max = Math.max(nums.get(t.numsIndex).get(t.listIndex + 1), max); + } + } + return new int[]{start, end}; + + } +} diff --git a/SumofSquareNumbers b/SumofSquareNumbers new file mode 100644 index 0000000..4d54ec0 --- /dev/null +++ b/SumofSquareNumbers @@ -0,0 +1,34 @@ +/* +633. Sum of Square Numbers + +Given a non-negative integer c, your task is to decide whether there're two integers a and b such that a2 + b2 = c. + +Example 1: + +Input: 5 +Output: True +Explanation: 1 * 1 + 2 * 2 = 5 + + +Example 2: + +Input: 3 +Output: False +*/ + +class Solution { + public boolean judgeSquareSum(int c) { + if (c == 0) { + return true; + } + int a = (int)Math.sqrt(c); + for (int i = 1; i<=a ;i++) { + int bSquare = c - i * i; + int b = (int) Math.sqrt(bSquare); + if (b * b == bSquare) { + return true; + } + } + return false; + } +}