// Maximum Product Subarray public int maxProduct(int[] nums) { int result = nums[0]; int maxHere = nums[0]; int minHere = nums[0]; for(int i=1; i<nums.length; i++) { int a = nums[i] * maxHere; int b = nums[i] * minHere; maxHere = Math.max(nums[i], Math.max(a, b)); minHere = Math.min(nums[i], Math.min(a, b)); result = Math.max(result, maxHere); } return result; } // Neighboring classroom, given a map of m * m, and n classrooms, //determine if every classroom belongs to one single component; //bounds: (1)classroom is at most 3 * 3 in area //(2) no overlapping classrooms // (3) classrooms are at least 5% of m * m in total area //(4) isConnected returns true only when two classroom shares a common EDGE. public static class Room { int x, y, h, w; } private static int[][] dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; public boolean isConnected(int m, int n, List<Room> rooms) { boolean[][] board = new boolean[m][n]; int area = 0; for(Room room : rooms) { for(int i=room.y-room.h+1; i<=room.y; i++) { for(int j=room.x; j<=room.x+room.w-1; j++) { board[i][j] = true; } } area += room.h * room.w; } Queue<Integer> queue = new LinkedList<>(); int start = rooms.get(0).y * n + rooms.get(0).x; queue.offer(start); int sum = 0; while(!queue.isEmpty()) { sum++; int point = queue.poll(); int y = point / n; int x = point % n; board[y][x] = false; for(int i=0; i<dir.length; i++) { int row = y + dir[i][0]; int col = x + dir[i][1]; if(row >= 0 && row < m && col >=0 && col < n && board[row][col]) { queue.offer(row*n+col); } } } return sum == area; } // sliding windows max public static int[] slidingMax(int[] A, int w) { int n = A.length; w = Math.min(n, w); int k = n - w + 1; int[] max = new int[k]; Deque<Integer> deq = new ArrayDeque<>(); for(int i=0; i<n; i++) { while(!deq.isEmpty() && A[deq.getLast()] <= A[i]) { // A[deq.getLast()] >= A[i] for slidingMin deq.removeLast(); } deq.addLast(i); if(i < w-1) continue; while(!deq.isEmpty() && i-w>=deq.getFirst()) { deq.removeFirst(); } max[i-w+1] = A[deq.getFirst()]; } return max; } // given an array, return the starting and ending index of all subarrays that sums to 0; public void getZeroSumIndex(int[] A) { int n = A.length; int[] sum = new int[n+1]; Map<Integer, List<Integer>> map = new HashMap<>(); Set<Integer> result = new HashSet<>(); for(int i=0; i<n; i++) { sum[i+1] = A[i] + sum[i]; if(sum[i+1] == 0) { result.add(0*31 +i); } if(A[i] == 0) { result.add(i*31 + i); } List<Integer> list = map.get(sum[i+1]); if(list == null) { list = new ArrayList<>(); map.put(sum[i+1], list); } else { for(int index : list) { result.add((index+1)*31 + i); } } list.add(i); } for(int num: result) { System.out.println(num/31 + ", " + num%31); } } // word break 1 // 重要的是要写出时间复杂度 递归(2^n)? 和worst case(如aaac, 字典是("a", "aa", "aaa")) // Time: O(n^2) public boolean wordBreak(String s, Set<String> wordDict) { int n = s.length(); boolean[] f = new boolean[n+1]; f[0] = true; for(int i=1; i<=n; i++) { for(int j=0; j<i; j++) { String word = s.substring(j, i); f[i] = f[j] && wordDict.contains(word); if(f[i]) break; } } return f[n]; } public static boolean wordBreak(String s, Set<String> dict){ //Base case if(dict.contains(s)) return true; for(int i = 0; i < s.length(); i++){ String sstr = s.substring(0, i); if(dict.contains(sstr) && wordBreak(s.substring(i), dict)) return true; } return false; } // word break 1的另外一种写法 O(M*N), // Time: O(string length * dict size) public boolean wordBreak(String s, Set<String> dict) { boolean[] t = new boolean[s.length()+1]; t[0] = true; //set first to be true, why? //Because we need initial state for(int i=0; i<s.length(); i++){ //should continue from match position if(!t[i]) continue; for(String a: dict){ int len = a.length(); int end = i + len; if(end > s.length()) continue; if(t[end]) continue; if(s.substring(i, end).equals(a)){ t[end] = true; } } } return t[s.length()]; } } // word break II recursive method, Time is O(n^2) public List<String> wordBreak(String s, Set<String> dict) { List<String> list = new ArrayList<>(); boolean[] f = new boolean[s.length()+1]; Arrays.fill(f, true); breakWord(list, dict, f, s, 0, ""); return list; } public void breakWord(List<String> list, Set<String> dict, boolean[] f, String s, int start, String t) { if(start == s.length()) { list.add(t.substring(1)); return; } for(int i=start+1; i<=s.length(); i++) { String word = s.substring(start, i); if(dict.contains(word) && f[i]) { int size = list.size(); breakWord(list, dict, f, s, i, t+" "+word); if(list.size() == size) f[i] = false; } } } // longest palindrome substring public String longestPalindrome(String s) { String res = ""; for(int i=0; i<s.length(); i++) { String str = palindromeAtCenter(s, i, i); if(str.length() > res.length()) { res = str; } str = palindromeAtCenter(s, i, i+1); if(str.length() > res.length()) { res = str; } } return res; } private String palindromeAtCenter(String s, int c1, int c2) { while(c1>=0 && c2<s.length() && s.charAt(c1) == s.charAt(c2)) { c1--; c2++; } return s.substring(c1+1, c2); } // reservior sampling public int[] samplingK(Scanner s, int k) { int[] res = new int[k]; int i = 0; while (i < k) { res[i++] = s.nextInt(); } Random r = new Random(); while(s.hasNext()) { int num = s.nextInt(); int rand = r.nextInt(i+1); // important: inclusive range if(rand < k) { res[rand] = num; } } return res; } // topological sorting public String getOrderedString(String[] strs, int charSize) { DirectedGraph g = new DirectedGraph(charSize); boolean[] visited = new boolean[charSize]; Arrays.fill(visited, true); //~~ for(String s:strs) { if(s.isEmpty()) continue; visited[s.charAt(0)-'a'] = false; //~~ for(int i=1; i<s.length(); i++) { visited[s.charAt(i)-'a'] = false; //~~ g.addEdge(s.charAt(i-1)-'a', s.charAt(i)-'a'); } } Stack<Integer> stack = new Stack<>(); for(int i=0; i<charSize; i++) { if(!visited[i]) toposort(g, i, visited, stack); } StringBuilder sb = new StringBuilder(); while(!stack.isEmpty()) { sb.append((char)(stack.pop()+ 'a')); } System.out.println(sb.toString()); return sb.toString(); } public void toposort(DirectedGraph g, int v, boolean[] visited, Stack<Integer> stack) { visited[v] = true; for(int u : g.adj[v]) { if(!visited[u]) { toposort(g, u, visited, stack); } } stack.push(v); } // room isConnected // 第四轮的题还问到了时间复杂度 // 对于访问到的每个点判断是否满足小于k需要O(k), // 所有访问到的点形成的图形最长半径为n的话则有O(n2)个点,所以总共是O(n2*k)。 public class MonkeyProblem { static class Point { int x, y; Point(int x, int y) { this.x = x; this.y = y; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Point)) return false; Point pair = (Point) o; return x == pair.x && y == pair.y; } @Override public int hashCode() { return 31 * x + y; } } public static int digitSum(int n) { if(n < 0) n = -n; int sum = 0; while(n != 0) { sum += n % 10; n /= 10; } return sum; } private static int[][] dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; public static int countSteps(int k) { Set<Point> set = new HashSet<>(); Queue<Point> queue = new LinkedList<>(); queue.offer(new Point(0, 0)); while(!queue.isEmpty()) { Point p = queue.poll(); if(set.contains(p) || (digitSum(p.x) + digitSum(p.y)) > k) continue; set.add(p); for(int i=0; i<4; i++) { queue.offer(new Point(p.x+dir[i][0], p.y+dir[i][1])); } } return set.size(); } public static void main(String[] args) { System.out.println(countSteps(19)); } } // serialize binary tree public String serialize(TreeNode root){ StringBuilder sb = new StringBuilder(); serialize(root, sb); return sb.toString(); } private void serialize(TreeNode x, StringBuilder sb){ if (x == null) { sb.append("# "); } else { sb.append(x.val + " "); serialzie(x.left, sb); serialzie(x.right, sb); } } public TreeNode deserialize(String s){ if (s == null || s.length() == 0) return null; StringTokenizer st = new StringTokenizer(s, " "); return deserialize(st); } private TreeNode deserialize(StringTokenizer st){ if (!st.hasMoreTokens()) return null; String val = st.nextToken(); if (val.equals("#")) return null; TreeNode root = new TreeNode(Integer.parseInt(val)); root.left = deserialize(st); root.right = deserialize(st); return root; } // a?b:c tenary tree public TreeNode convertToTree (char[] values) { TreeNode root = new TreeNode(values[0]); TreeNode n = root; Stack<TreeNode> stack = new Stack<TreeNode>(); for (int i = 1; i < values.length; i += 2) { if (values[i] == '?') { n.left = new TreeNode (values[i + 1]); stack.push(n); n = n.left; } else if (values[i] == ':') { n = stack.pop(); while (n.right != null) { n = stack.pop(); } n.right = new TreeNode (values[i + 1]); stack.push(n); n = n.right; } } return root; } // mutable string public char charAt(int index) { if ((index < 0) || (index >= count)) { throw new StringIndexOutOfBoundsException(index); } return value[index + offset]; } public String substring(int beginIndex, int endIndex) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } if (endIndex > count) { throw new StringIndexOutOfBoundsException(endIndex); } if (beginIndex > endIndex) { throw new StringIndexOutOfBoundsException(endIndex - beginIndex); } return ((beginIndex == 0) && (endIndex == count)) ? this : new String(offset + beginIndex, endIndex - beginIndex, value); }