1 leetCode 273 Integer to English Words
思路 三个数一起,分3个特殊数组

1 public class Solution { 2 private final String[] LESS_THAN_20 = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", 3 "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"}; 4 private final String[] TENS = {"", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"}; 5 private final String[] THOUSANDS = {"", "Thousand", "Million", "Billion"}; 6 public String numberToWords(int num) { 7 if (num == 0) return "Zero"; 8 int i = 0; 9 String word = ""; 10 while (num > 0){ 11 if (num % 1000 != 0){ 12 word = help(num % 1000) + THOUSANDS[i] + " " + word; 13 } 14 i++; 15 num /= 1000; 16 } 17 return word.trim(); 18 } 19 20 21 private String help(int n) { 22 if (n == 0) return ""; 23 else if (n < 20){ 24 return LESS_THAN_20[n] + " "; 25 } else if (n < 100) { 26 return TENS[n / 10] + " " + help(n % 10); 27 } else { 28 return LESS_THAN_20[n / 100] + " Hundred " + help(n % 100); 29 } 30 } 31 }
2 592 Fraction Addition and Subtration
每次读入3个字母

public class Solution { public String fractionAddition(String expression) { Scanner sc = new Scanner(expression).useDelimiter("/|(?=[-+])"); int A = 0, B = 1; while (sc.hasNext()){ int a = sc.nextInt(), b = sc.nextInt(); A = A * b + B * a; B = B * b; int g = gcd(A, B); A /= g; B /= g; } return A + "/" + B; } public int gcd(int a, int b){ return a == 0 ? Math.abs(b) : gcd(b % a, a); } }
3 275 H-Index|| d
思路,二分查找,找到a[m] = len - m;

public class Solution { public int hIndex(int[] cit) { int len = cit.length; int l = 0, r = len - 1; while (l <= r) { int m = (l + r) / 2; if (cit[m] == len - m) return cit[m]; else if (cit[m] > len - m) r = m - 1; else l = m + 1; } return len - l; } }
4 278 First Bad Version
二分,<

public int firstBadVersion(int n) { int l = 1, r = n; while (l < r) { int m = (r - l) / 2 + l; if (isBadVersion(m)) { r = m; } else { l = m + 1; } } return r; }
5 279 Perfect Squares
1 递归 超时

public int numSquares(int n) { int res = n, num = 2; while (num * num <= n) { int a = n / (num * num), b = n % (num * num); res = Math.min(res, a + numSquares(b)); } return res; }
2 数学

public int numSquares(int n) { if(n % 4 == 0) n/= 4; if (n % 8 == 7) return 4; for (int x = 0; x * x <= n; x++){ int y = (int)Math.sqrt(n - x * x); if (x * x + y * y == n){ int res = 0; if (x > 0) res++; if (y > 0) res++; return res; } } return 3;
3 动态规划

public int numSquares(int n) { int[] res = new int[n + 1]; Arrays.fill(res, 5); res[0] = 0; for (int i = 0; i <= n; i++) { for (int j = 1; j * j + i <= n; j++) { res[j * j + i] = Math.min(res[j * j + i], res[i] + 1); } } return res[n]; }
6 282 Expression And Operator
递归

public class Solution { List<String> res = null; public List<String> addOperators(String num, int target) { res = new ArrayList<>(); if (num == null || num.length() == 0) return res; help(num, target, "", 0, 0, 0); return res; } public void help(String num, int target, String path, int pos, long val, long mul){ if (pos == num.length() && target == val) { res.add(path); return; } for (int i = pos; i < num.length(); i++) { if (i != pos && num.charAt(pos) == '0') break; long cur = Long.parseLong(num.substring(pos, i + 1)); if (pos == 0){ help(num, target, path + cur, i + 1, cur, cur); } else{ help(num, target, path + "+" + cur, i + 1, val + cur, cur); help(num, target, path + "-" + cur, i + 1, val - cur, -cur); help(num, target, path + "*" + cur, i + 1, val - mul + mul * cur, cur *mul); } } } }
7 283 Move Zeros
把不是0的移到前面

public class Solution { public void moveZeroes(int[] nums) { if (nums == null || nums.length == 0) return; int index = 0; for (int i : nums){ if (i != 0) { nums[index++] = i; } } for (; index < nums.length; index++){ nums[index] = 0; } } }
8 284 Peeking Iterator
next 变量

class PeekingIterator implements Iterator<Integer> { Iterator<Integer> itor; Integer next = null; public PeekingIterator(Iterator<Integer> iterator) { // initialize any member here. itor = iterator; if (itor.hasNext()){ next = itor.next(); } } // Returns the next element in the iteration without advancing the iterator. public Integer peek() { return next; } // hasNext() and next() should behave the same as in the Iterator interface. // Override them if needed. @Override public Integer next() { Integer item = next; if (itor.hasNext()){ next = itor.next(); } else { next = null; } return item; } @Override public boolean hasNext() { return next != null; } }
9 289 Game of Life
4 个状态

public void gameOfLife(int[][] board) { int m = board.length, n = board[0].length; int[] dx = {-1, -1, -1, 0, 1, 1, 1, 0}; int[] dy = {-1, 0, 1, 1, 1, 0, -1, -1}; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { int cou = 0; for (int k = 0; k < dx.length; k++){ int x = i + dx[k], y = j + dy[k]; if (x < 0 || x >= m || y < 0 || y >= n) continue; if (board[x][y] == 1 || board[x][y] == 2) cou++; } if (board[i][j] == 1 && (cou < 2 || cou > 3)) board[i][j] = 2; else if (board[i][j] == 0 && cou == 3) board[i][j] = 3; } } for (int i = 0; i < m; i++){ for (int j = 0; j < n; j++) { board[i][j] %= 2; } } }
10 word Pattern
hashmap 如果有检测是否相同,如果没检测值
一一映射

public boolean wordPattern(String pattern, String str) { String[] arr = str.split(" "); HashMap<Character, String> map = new HashMap<>(); if (pattern.length() != arr.length) return false; for (int i = 0; i < arr.length; i++) { char c = pattern.charAt(i); if (map.containsKey(c)){ if (!map.get(c).equals(arr[i])){ return false; } } else { if (map.containsValue(arr[i])){ return false; } map.put(c, arr[i]); } } return true; }
11 292 Nim Game
余4

public boolean canWinNim(int n) { return n % 4 != 0; }
12 295 Find Mediam from Data Stream
两个堆 默认最小堆

public class MedianFinder { /** initialize your data structure here. */ private PriorityQueue<Long> small = new PriorityQueue<>(); private PriorityQueue<Long> large = new PriorityQueue<>(); public MedianFinder() { } public void addNum(int num) { large.add((long)num); small.add(-large.poll()); if (large.size() < small.size()){ large.add(-small.poll()); } } public double findMedian() { return large.size() > small.size() ? large.peek() : (large.peek() - small.peek()) / 2; } }
13 297 Serialize and Deseralize Binary Tree
前中后层遍历了

public class Codec { private static final String split = ","; private static final String NN = "X"; // Encodes a tree to a single string. public String serialize(TreeNode root) { StringBuilder sb = new StringBuilder(); ser(root, sb); return sb.toString(); } public void ser(TreeNode root, StringBuilder sb) { if (root == null) { sb.append(NN).append(split); return; } sb.append(root.val).append(split); ser(root.left, sb); ser(root.right, sb); } // Decodes your encoded data to tree. public TreeNode deserialize(String data) { Deque<String> nodes = new LinkedList<>(); nodes.addAll(Arrays.asList(data.split(split))); return des(nodes); } public TreeNode des(Deque<String> nodes){ String val = nodes.remove(); if (val.equals(NN)) return null; TreeNode root = new TreeNode(Integer.valueOf(val)); root.left = des(nodes); root.right = des(nodes); return root; } }

public class Codec { // Encodes a tree to a single string. public String serialize(TreeNode root) { StringBuilder res = new StringBuilder(); Queue<TreeNode> q = new LinkedList<>(); if (root == null) return ""; q.offer(root); while (!q.isEmpty()) { TreeNode node = q.poll(); if (node == null) { res.append("n "); continue; } res.append(node.val + " "); q.offer(node.left); q.offer(node.right); } return res.toString(); } // Decodes your encoded data to tree. public TreeNode deserialize(String data) { if (data == "") return null; Deque<TreeNode> nodes = new LinkedList<>(); String[] values = data.split(" "); TreeNode root = new TreeNode(Integer.parseInt(values[0])); nodes.add(root); for (int i = 1; i < values.length; i++) { TreeNode node = nodes.poll(); if (!values[i].equals("n")){ TreeNode left = new TreeNode(Integer.parseInt(values[i])); node.left = left; nodes.add(left); } if (!values[++i].equals("n")){ TreeNode right = new TreeNode(Integer.parseInt(values[i])); node.right = right; nodes.add(right); } } return root; } }
14 299 Bulls and Cows

public String getHint(String secret, String guess) { int[] num = new int[10]; int a = 0, b = 0; for (int i = 0; i < secret.length(); i++) { char c = secret.charAt(i); if (c == guess.charAt(i)) { a++; } num[c - '0']++; } for (int i = 0; i < guess.length(); i++) { if (num[guess.charAt(i) - '0'] > 0) { num[guess.charAt(i) - '0']--; b++; } } b -= a; return a + "A" + b + "B"; }
15 Longest Increasing Subsequence
动态规划dp[i] = Math.max(dp[i], dp[j] + 1)

public class Solution { public int lengthOfLIS(int[] nums) { if (nums.length == 0) return 0; int[] dp = new int[nums.length]; int res = 0; Arrays.fill(dp, 1); for (int i = 0; i < nums.length; i++) { for (int j = 0; j < i; j++) { if (nums[i] > nums[j]){ dp[i] = Math.max(dp[i], dp[j] + 1); } } res = Math.max(res, dp[i]); } return res; } }
如果遍历到的新元素比ends数组首元素大,比尾元素小时,此时用二分查找法找到第一个不小于此新元素的位置,覆盖掉位置的原来的数字,以此类推直至遍历完整个nums数组,此时ends数组的长度就是我们要求的LIS的长度,特别注意的是ends数组的值可能不是一个真实的LIS,

public int lengthOfLIS(int[] nums) { if (nums.length == 0) return 0; int[] num = new int[nums.length]; num[0] = nums[0]; int i = 0; for (int n : nums){ if (num[i] < n) num[++i] = n; else if (num[0] > n) num[0] = n; else { int l = 0, r = i; while (l < r) { int m = (r - l) / 2 + l; if (num[m] < n) l = m + 1; else r = m; } num[r] = n; } } return i + 1; }
16 301 Remove Invalid Parenthese
bfs 多分树

public List<String> removeInvalidParentheses(String s) { List<String> res = new ArrayList<>(); Set<String> set = new HashSet<>(); Queue<String> q = new LinkedList<>(); if (s == null) return res; q.offer(s); set.add(s); boolean V = false; while (!q.isEmpty()){ String str = q.poll(); if (isV(str)){ res.add(str); V = true; } if (V) continue; for (int i = 0; i < str.length(); i++) { if (str.charAt(i) != '(' && str.charAt(i) != ')') continue; String t = str.substring(0, i) + str.substring(i + 1, str.length()); if (set.add(t)) { q.offer(t); } } } return res; } public boolean isV(String s) { int count = 0; for (char c : s.toCharArray()){ if (c == '(') count++; else if (c == ')' && count-- == 0) return false; } return count == 0; }

public List<String> removeInvalidParentheses(String s) { List<String> res = new ArrayList<>(); help(s, res, 0, 0, new char[]{'(', ')'}); return res; } public void help(String s, List<String> res, int last_i, int last_j, char[] par) { for (int count = 0, i = last_i; i < s.length(); i++) { if (s.charAt(i) == par[0]) count++; if (s.charAt(i) == par[1]) count--; if (count >= 0) continue; for (int j = last_j; j <= i; j++){ if (s.charAt(j) == par[1] && (j == last_j || s.charAt(j - 1) != par[1])){ help(s.substring(0, j) + s.substring(j + 1), res, i, j, par); } } return; } String reverse = new StringBuilder(s).reverse().toString(); if (par[0] == '('){ help(reverse, res, 0, 0, new char[]{')', '('}); } else { res.add(reverse); } } }
17303 Range sum Query
sum[j] - sum[i - 1];

public class NumArray { int[] nums; public NumArray(int[] nums) { this.nums = nums; for (int i = 1; i < nums.length; i++) { nums[i] = nums[i - 1] + nums[i]; } } public int sumRange(int i, int j) { if (i == 0) { return nums[j]; } else { return nums[j] - nums[i - 1]; } } }
18 304 Range sum Query 2D
上一题

public class NumMatrix { int[][] dp; public NumMatrix(int[][] mat) { if (mat == null || mat.length == 0 || mat[0].length == 0) return; int m = mat.length, n = mat[0].length; dp = new int[m + 1][n + 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] - dp[i-1][j-1] + mat[i - 1][j - 1]; } } } public int sumRegion(int row1, int col1, int row2, int col2) { return dp[row2 + 1][col2 + 1] - dp[row1][col2 + 1] - dp[row2 + 1][col1] + dp[row1][col1]; } }
19 306 Additive Number
确定前两个数,剩下递推

public boolean isAdditiveNumber(String num) { int n = num.length(); for (int i = 1; i <= n / 2; i++) { for (int j = 1; Math.max(i, j) <= n - i - j; j++) { if (isV(i, j, num)) return true; } } return false; } public boolean isV(int i, int j, String num) { if (i > 1 && num.charAt(0) == '0') return false; if (j > 1 && num.charAt(i) == '0') return false; String sum; Long x1 = Long.parseLong(num.substring(0, i)); Long x2 = Long.parseLong(num.substring(i, j + i)); for (int start = i + j; start != num.length(); start += sum.length()){ x2 = x1 + x2; x1 = x2 - x1; sum = x2.toString(); if (!num.startsWith(sum, start)) return false; } return true; }
20 309 Best Time to Buy and Sell Stock with Cooldown
动态规划 两状态 持有,未持有

public int maxProfit(int[] prices) { if (prices.length == 0) return 0; int b0 = - prices[0], b1 = b0; int s0 = 0, s1 = 0, s2 = 0; for (int i = 1; i < prices.length; i++) { b0 = Math.max(b1, s2 - prices[i]); s0 = Math.max(s1, b1 + prices[i]); b1 = b0; s2 = s1; s1 = s0; } return s0; }
21 310 Minimum Heiht Trees
剥洋葱法

public List<Integer> findMinHeightTrees(int n, int[][] edges) { if (n == 1) return Collections.singletonList(0); List<Integer> res = new ArrayList<>(); List<Set<Integer>> graf = new ArrayList<>(); for (int i = 0; i < n; i++) graf.add(new HashSet()); for (int i = 0; i < edges.length; i++) { graf.get(edges[i][0]).add(edges[i][1]); graf.get(edges[i][1]).add(edges[i][0]); } for (int i = 0; i < graf.size(); i++) { if (graf.get(i).size() == 1) res.add(i); } while (n > 2){ n -= res.size(); List<Integer> cur = new ArrayList<>(); for (int i : res){ int t = graf.get(i).iterator().next(); graf.get(t).remove(i); if (graf.get(t).size() == 1) { cur.add(t); } } res = cur; } return res; }
22 312 Burst Ballons 动态规划, 不含边界

class Solution { public int maxCoins(int[] nums) { int[] num = new int[nums.length + 2]; num[0] = num[nums.length + 1] = 1; for (int i = 1; i <= nums.length; i++) { num[i] = nums[i - 1]; } int n = num.length; int[][] dp = new int[n][n]; for (int i = 2; i < n; i++) { for (int left = 0; left < n - i; left++) { int right = left + i; for (int k = left + 1; k < right; k++) { dp[left][right] = Math.max(dp[left][right], num[left] * num[k] * num[right] + dp[left][k] + dp[k][right]); } } } return dp[0][n - 1]; } }
23 313 Super Ugly Number

public int nthSuperUglyNumber(int n, int[] primes) { if (primes.length == 0) return 0; int[] res = new int[n], num = new int[primes.length]; res[0] = 1; for (int i = 1; i < n; i++) { res[i] = Integer.MAX_VALUE; for (int j = 0; j < primes.length; j++) { res[i] = Math.min(res[i], res[num[j]] * primes[j]); } for (int j = 0; j < primes.length; j++) { if (res[i] == res[num[j]] * primes[j]) num[j]++; } } return res[n - 1]; }
24 315 Count of Smaller Numbers After Self
二叉搜索树,比它小的数,重复数

class Solution { class Node { int val, sum, dup; Node(int v, int s) { val = v; sum = s; } } public List<Integer> countSmaller(int[] nums) { int[] res = new int[nums.length]; Node root = null; for (int i = nums.length - 1; i >= 0; i--) { root = insert(nums[i], res, i, root, 0); } return Arrays.asList(res); } public Node insert(int num, int[] res, int i, Node node, int presum) { if (node == null) { node = new Node(num, presum); res[i] = presum; } else if (node.val == num) { node.dup++; res[i] = presum + node.sum; } else if (node.val < num) { node.right = insert(num, res, i, node.right, presum + node.presum + dup); } else{ node.sum++; node.left = insert(num, res, i, node.left, presum); } return node; } }
25 671. Second Minimum Node In a Binary Tree

public int findSecondMinimumValue(TreeNode root) { if (root == null) { return -1; } int res = find(root, root.val); return res == Integer.MAX_VALUE ? -1 : res; } int find(TreeNode root, int val) { if (root == null) { return Integer.MAX_VALUE; } if (root.val != val) { return root.val; } return Math.min(find(root.left, val), find(root.right, val)); }
26 669. Trim a Binary Search Tree

class Solution { public TreeNode trimBST(TreeNode root, int L, int R) { if (root == null) { return root; } if (root.val > R) { return trimBST(root.left, L, R); } if (root.val < L) { return trimBST(root.right, L, R); } root.left = trimBST(root.left, L, R); root.right = trimBST(root.right, L, R); return root; }
27 n