title: leetcode-剑指offer date: 2020-12-25 16:10:37 tags: [“剑指offer”] categories: [“剑指offer”] description: 剑指offer刷题记录 top_img: “https://s3.ax1x.com/2020/12/25/rW8p8A.jpg “ cover: “https://s3.ax1x.com/2020/12/25/rW8p8A.jpg “ typora-root-url: ..
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public int findRepeatNumber (int [] nums) { Map<Integer,Integer> map = new HashMap<>(); for (int num : nums) { if (map.containsKey(num)) { return num; } else { map.put(num,1 ); } } return -1 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public boolean findNumberIn2DArray (int [][] matrix, int target) { if (matrix.length == 0 || matrix[0 ].length == 0 ) { return false ; } return dfs(matrix, target, 0 , matrix[0 ].length - 1 ); } private boolean dfs (int [][] matrix, int target, int i, int j) { if (i >= matrix.length || j < 0 ) { return false ; } if (matrix[i][j] == target) { return true ; } else if (matrix[i][j] < target) { return dfs(matrix, target, i + 1 , j); } else { return dfs(matrix, target, i, j - 1 ); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public String replaceSpace (String s) { StringBuilder sb = new StringBuilder(); for (int i = 0 ; i < s.length(); i++) { if (s.charAt(i) == ' ' ){ sb.append("%20" ); } else { sb.append(s.charAt(i)); } } return sb.toString(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public int [] reversePrint(ListNode head) { ListNode cur = head; ListNode rev = null ; int n = 0 ; while (cur != null ) { ListNode temp = cur.next; cur.next = rev; rev = cur; cur = temp; n++; } int [] res = new int [n]; int i = 0 ; while (i < n) { res[i] = rev.val; i++; rev = rev.next; } return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution { public TreeNode buildTree (int [] preorder, int [] inorder) { if (preorder == null || preorder.length == 0 ) { return null ; } Map<Integer, Integer> indexMap = new HashMap<>(); int len = preorder.length; for (int i = 0 ; i < len; i++) { indexMap.put(inorder[i], i); } TreeNode root = getTree(preorder, 0 , len - 1 , inorder, 0 , len - 1 , indexMap); return root; } private TreeNode getTree (int [] preorder, int preStart, int preEnd, int [] inorder, int inStart, int inEnd, Map<Integer, Integer> indexMap) { if (preStart > preEnd) { return null ; } int rootVal = preorder[preStart]; TreeNode root = new TreeNode(rootVal); if (preStart == preEnd) { return root; } else { int rootIndex = indexMap.get(rootVal); int leftNodes = rootIndex - inStart, rightNodes = inEnd - rootIndex; TreeNode leftSubTree = getTree(preorder, preStart + 1 , preStart + leftNodes, inorder, inStart, rootIndex - 1 , indexMap); TreeNode rightSubeTree = getTree(preorder, preEnd - rightNodes + 1 , preEnd, inorder, rootIndex + 1 , inEnd, indexMap); root.left = leftSubTree; root.right = rightSubeTree; return root; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class CQueue { LinkedList<Integer> stack1; LinkedList<Integer> stack2; public CQueue () { stack1 = new LinkedList<>(); stack2 = new LinkedList<>(); } public void appendTail (int value) { stack1.add(value); } public int deleteHead () { if (stack2.isEmpty()) { if (stack1.isEmpty()) { return -1 ; } else { while (!stack1.isEmpty()) { stack2.add(stack1.pop()); } return stack2.pop(); } }else { return stack2.pop(); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public int numWays (int n) { if (n <= 1 ) { return 1 ; } int pre = 1 ; int cur = 1 ; for (int i = 2 ; i <= n; i++) { int temp = cur; cur = (pre + cur) % 1000000007 ; pre = temp; } return cur; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public int minArray (int [] numbers) { int left = 0 , right = numbers.length - 1 ; while (left < right) { int mid = left + (right - left) / 2 ; if (numbers[mid] < numbers[right]) { right = mid; } else if (numbers[mid] > numbers[right]) { left = mid + 1 ; } else { right -= 1 ; } } return numbers[left]; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class Solution { public boolean exist (char [][] board, String word) { if (board == null || board.length == 0 || board[0 ].length == 0 ) { return false ; } boolean [][] vis = new boolean [board.length][board[0 ].length]; char [] chars = word.toCharArray(); for (int i = 0 ; i < board.length; i++) { for (int j = 0 ; j < board[0 ].length; j++) { if (board[i][j] == chars[0 ]) { if (dfs(board,i,j,vis,chars,0 )) { return true ; } } } } return false ; } private boolean dfs (char [][] board, int i, int j, boolean [][] vis, char [] chars, int index) { if (i < 0 || i == board.length || j < 0 || j == board[0 ].length || board[i][j] != chars[index] || vis[i][j]) { return false ; } if (index == chars.length - 1 ) { return true ; } vis[i][j] = true ; boolean res = dfs(board,i + 1 , j ,vis,chars,index + 1 ) || dfs(board,i - 1 , j ,vis, chars,index + 1 ) || dfs(board,i, j + 1 ,vis,chars,index + 1 ) || dfs(board, i, j - 1 ,vis,chars,index + 1 ); vis[i][j] = false ; return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { public int movingCount (int m, int n, int k) { boolean [][] vis = new boolean [m][n]; int res = dfs(m,n,k,0 ,0 ,vis); return res; } private int dfs (int m, int n, int k, int i, int j, boolean [][] vis) { if (i < 0 || i >= m || j < 0 || j >= n || vis[i][j] || (numsCount(i) + numsCount(j)) > k) { return 0 ; } vis[i][j] = true ; int res = 1 + dfs(m,n,k,i + 1 ,j,vis) + dfs(m,n,k,i - 1 ,j,vis) + dfs(m,n,k,i,j + 1 ,vis) + dfs(m,n,k,i, j - 1 ,vis); return res; } private int numsCount (int m) { int sum = 0 ; while (m > 0 ) { if (m != 0 ) { int b = m % 10 ; sum += b; m /= 10 ; } } return sum; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public int cuttingRope (int n) { int [] dp = new int [n + 1 ]; for (int i = 0 ;i <= n; i++) { int max = 0 ; for (int j = i - 1 ; j >= 0 ; j--) { max = Math.max(max,Math.max(j * (i - j), j * dp[i - j])); } dp[i] = max; } return dp[n]; } }
尽可能凑3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public int cuttingRope (int n) { if (n < 4 ) { return n - 1 ; } else if ( n == 4 ) { return n; } long res = 1 ; while (n > 4 ) { res *= 3 ; res %= 1000000007 ; n -= 3 ; } return (int )(res * n % 1000000007 ); } }
位运算!
1 2 3 4 5 6 7 8 9 10 11 public class Solution { public int hammingWeight (int n) { int res = 0 ; while (n != 0 ) { res += n & 1 ; n = n >>> 1 ; } return res; } }
位运算!!
二分快速幂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public double myPow (double x, int n) { if (n == 0 ) return 1 ; if (n == 1 ) return x; if (n == -1 ) return 1 / x; if (n % 2 == 0 ) { double t = myPow(x, n / 2 ); return t * t; } else { double t = myPow(x, n / 2 ); if (n < 0 ) x = 1 / x; return t * t * x; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public int [] printNumbers(int n) { int size = 10 ; for (int i = 1 ; i < n; i++) { size *= 10 ; } int [] res = new int [size - 1 ]; for (int i = 0 ; i < size - 1 ; i++) { res[i] = i + 1 ; } return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public int [] exchange(int [] nums) { int temp = 0 , left = 0 , right = nums.length - 1 ; while (left < right) { if (nums[left] % 2 == 1 ) { left++; } else if (nums[right] % 2 == 0 ) { right--; } else { temp = nums[left]; nums[left] = nums[right]; nums[right] = temp; left++; right--; } } return nums; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public ListNode getKthFromEnd (ListNode head, int k) { ListNode low = head, fast = head; for (int i = 1 ; i < k; i++) { fast = fast.next; } while (fast.next != null ) { fast = fast.next; low = low.next; } return low; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution { public ListNode mergeTwoLists (ListNode l1, ListNode l2) { ListNode newHead = new ListNode(-1 ), pre = newHead; while (l1 != null && l2 != null ) { if (l1.val <= l2.val) { pre.next = l1; l1 = l1.next; pre = pre.next; } else { pre.next = l2; l2 = l2.next; pre = pre.next; } } if (l1 != null ) { pre.next = l1; } if (l2 != null ) { pre.next = l2; } return newHead.next; } }
两个dfs 对A前序遍历每个节点与b比较
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public boolean isSubStructure (TreeNode A, TreeNode B) { if (A == null || B == null ) return false ; return dfs(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B); } public boolean dfs (TreeNode A, TreeNode B) { if (B == null ) return true ; if (A == null ) return false ; return A.val == B.val && dfs(A.left, B.left) && dfs(A.right, B.right); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public TreeNode mirrorTree (TreeNode root) { mirror(root); return root; } private void mirror (TreeNode root) { if (root == null ) { return ; } TreeNode temp = root.left; root.left = root.right; root.right = temp; mirror(root.left); mirror(root.right); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public boolean isSymmetric (TreeNode root) { if (root == null ) { return true ; } return dfs(root.left, root.right); } private boolean dfs (TreeNode left, TreeNode right) { if (left == null && right == null ) { return true ; } if (left == null || right == null ) { return false ; } return left.val == right.val && dfs(left.left, right.right) && dfs(left.right, right.left); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class Solution { public int [] spiralOrder(int [][] matrix) { int row = matrix.length; if (row == 0 ) { return new int [0 ]; } int col = matrix[0 ].length; int [] res = new int [row * col]; int index = 0 , left = 0 , top = 0 , right = col - 1 , bottom = row - 1 ; while (true ) { for (int i = left; i <= right; i++) { res[index++] = matrix[top][i]; } if (++top > bottom) { break ; } for (int i = top; i <= bottom; i++) { res[index++] = matrix[i][right]; } if (--right < left) { break ; } for (int i = right; i >= left; i--) { res[index++] = matrix[bottom][i]; } if (--bottom < top) { break ; } for (int i = bottom; i >= top; i--) { res[index++] = matrix[i][left]; } if (++left > right) { break ; } } return res; } }
用一个min记录当前最小值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 class MinStack { private Node head; public MinStack () { } public void push (int x) { if (head == null ){ head = new Node(x, x); } else { Node newhead = new Node(x, Math.min(head.min, x)); newhead.next = head; head = newhead; } } public void pop () { head = head.next; } public int top () { return head.val; } public int min () { return head.min; } private class Node { int val; int min; Node next; public Node (int val, int min) { this .val = val; this .min = min; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public boolean validateStackSequences (int [] pushed, int [] popped) { int n = pushed.length; if (n == 0 ) { return true ; } Stack<Integer> stack = new Stack<>(); int i = 0 , j = 0 ; while (i < n && j < n) { while (stack.isEmpty() || stack.peek() != popped[j] && i < n) { stack.push(pushed[i++]); } while (!stack.isEmpty() && stack.peek() == popped[j] && j < n) { stack.pop(); j++; } } return stack.isEmpty(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution { public int [] levelOrder(TreeNode root) { List<Integer> list = new ArrayList<>(); if (root == null ) { return new int [0 ]; } Queue<TreeNode> queue = new LinkedList<>(); queue.add(root); while (!queue.isEmpty()) { TreeNode node = queue.poll(); list.add(node.val); if (node.left != null ) { queue.offer(node.left); } if (node.right != null ) { queue.offer(node.right); } } int [] res = new int [list.size()]; for (int i = 0 ; i < list.size(); i++) { res[i] = list.get(i); } return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class Solution { public List<List<Integer>> levelOrder(TreeNode root) { List<List<Integer>> res = new ArrayList<>(); if (root == null ) { return res; } Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { List<Integer> list = new ArrayList<>(); int size = queue.size(); for (int i = 0 ; i < size; i++) { TreeNode node = queue.poll(); list.add(node.val); if (node.left != null ) { queue.offer(node.left); } if (node.right != null ) { queue.offer(node.right); } } res.add(list); } return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class Solution { public List<List<Integer>> levelOrder(TreeNode root) { List<List<Integer>> res = new ArrayList<>(); if (root == null ) { return res; } int flag = 0 ; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { flag++; LinkedList<Integer> list = new LinkedList<>(); int size = queue.size(); for (int i = 0 ; i < size; i++) { TreeNode node = queue.poll(); if (flag % 2 == 0 ) { list.addFirst(node.val); } else { list.addLast(node.val); } if (node.left != null ) { queue.offer(node.left); } if (node.right != null ) { queue.offer(node.right); } } res.add(list); } return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public boolean verifyPostorder (int [] postorder) { return isBST(postorder, 0 , postorder.length - 1 ); } private boolean isBST (int [] postorder, int i, int j) { if (i > j) { return true ; } int left = i; while (postorder[left] < postorder[j]) { left++; } int right = left; while (postorder[left] > postorder[j]) { left++; } return left == j && isBST(postorder,i, right - 1 ) && isBST(postorder, right, j - 1 ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class Solution { private List<List<Integer>> res; public List<List<Integer>> pathSum(TreeNode root, int sum) { res = new ArrayList<>(); backtrack(root, sum, new ArrayList<>()); return res; } private void backtrack (TreeNode root, int sum, List<Integer> list) { if (root == null ) { return ; } list.add(root.val); sum -= root.val; if (sum == 0 && root.left == null && root.right == null ){ res.add(new ArrayList<>(list)); } else { backtrack(root.left, sum, list); backtrack(root.right, sum, list); } sum += root.val; list.remove(list.size() - 1 ); } }
hashmap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution { public Node copyRandomList (Node head) { if (head == null ) { return head; } Map<Node, Node> map = new HashMap<>(); for (Node cur = head; cur != null ; cur = cur.next) { map.put(cur, new Node(cur.val)); } for (Node cur = head; cur != null ; cur = cur.next) { map.get(cur).next = map.get(cur.next); map.get(cur).random = map.get(cur.random); } return map.get(head); } }
构造 拼接和拆分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class Solution { public Node copyRandomList (Node head) { if (head == null ) { return head; } Node cur = head; while (cur != null ) { Node tmp = new Node(cur.val); tmp.next = cur.next; cur.next = tmp; cur = tmp.next; } cur = head; while (cur != null ) { if (cur.random != null ) { cur.next.random = cur.random.next; } cur = cur.next.next; } cur = head.next; Node pre = head, res = head.next; while (cur.next != null ) { pre.next = pre.next.next; cur.next = cur.next.next; pre = pre.next; cur = cur.next; } pre.next = null ; return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 class Solution { Node pre, head; public Node treeToDoublyList (Node root) { if (root == null ) { return root; } dfs(root); head.left = pre; pre.right = head; return head; } private void dfs (Node cur) { if (cur == null ) { return ; } dfs(cur.left); if (pre == null ) { head = cur; } else { pre.right = cur; } cur.left = pre; pre = cur; dfs(cur.right); } }
层次遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 public class Codec { String SEP = "," ; String NULL = "null" ; public String serialize (TreeNode root) { StringBuilder sb = new StringBuilder(); if (root == null ) { sb.append(NULL).append(SEP); return sb.delete(sb.length() - 1 , sb.length() - 1 ).toString(); } Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { TreeNode node = queue.poll(); if (node == null ) { sb.append(NULL).append(SEP); continue ; } sb.append(node.val).append(SEP); queue.offer(node.left); queue.offer(node.right); } sb.delete(sb.length() - 1 , sb.length() - 1 ); return sb.toString(); } public TreeNode deserialize (String data) { if (data.isEmpty()) { return null ; } String[] nodes = data.split(SEP); if (nodes[0 ].equals(NULL)) { return null ; } TreeNode root = new TreeNode(Integer.parseInt(nodes[0 ])); Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); for (int i = 1 ; i < nodes.length;) { TreeNode parent = queue.poll(); String left = nodes[i++]; if (!left.equals(NULL)) { parent.left = new TreeNode(Integer.parseInt(left)); queue.offer(parent.left); } else { parent.left = null ; } String right = nodes[i++]; if (!right.equals(NULL)) { parent.right = new TreeNode(Integer.parseInt(right)); queue.offer(parent.right); } else { parent.right = null ; } } return root; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution { List<String> res = new LinkedList<>(); char [] c; public String[] permutation(String s) { c = s.toCharArray(); dfs(0 ); return res.toArray(new String[res.size()]); } private void dfs (int x) { if (x == c.length - 1 ) { res.add(String.valueOf(c)); return ; } HashSet<Character> set = new HashSet<>(); for (int i = x; i < c.length; i++) { if (set.contains(c[i])) { continue ; } set.add(c[i]); swap(i, x); dfs(x + 1 ); swap(i, x); } } private void swap (int a, int b) { char temp = c[a]; c[a] = c[b]; c[b] = temp; } }
1 2 3 4 5 6 7 8 9 10 11 12 class Solution { public int majorityElement (int [] nums) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0 ; i < nums.length; i++) { map.put(nums[i], map.getOrDefault(nums[i], 0 ) + 1 ); if (map.get(nums[i]) > (nums.length / 2 )) { return nums[i]; } } return -1 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public int majorityElement (int [] nums) { int count = 0 ; int card = nums[0 ]; for (int num : nums) { if (count == 0 ) { card = num; } count += card == num ? 1 : -1 ; } return card; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public int [] getLeastNumbers(int [] arr, int k) { if (arr.length == 0 || k == 0 ) { return new int [0 ]; } PriorityQueue<Integer> queue = new PriorityQueue<>(k, (o1, o2) -> o1 - o2); for (int a : arr) { queue.offer(a); } int [] res = new int [k]; for (int i = 0 ; i < k; i++) { res[i] = queue.poll(); } return res; } }
保证中位数一直在堆顶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class MedianFinder { private PriorityQueue<Integer> large; private PriorityQueue<Integer> small; public MedianFinder () { large = new PriorityQueue<>(); small = new PriorityQueue<>((a, b) -> b - a); } public void addNum (int num) { if (small.size() >= large.size()) { small.offer(num); large.offer(small.poll()); } else { large.offer(num); small.offer(large.poll()); } } public double findMedian () { if (large.size() > small.size()) { return large.peek(); } else if (large.size() < small.size()) { return small.peek(); } return (large.peek() + small.peek()) / 2.0 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 class Solution { public int maxSubArray (int [] nums) { int n = nums.length; int [] dp = new int [n]; int res = dp[0 ] = nums[0 ]; for (int i = 1 ; i < nums.length; i++) { dp[i] = Math.max(nums[i], dp[i - 1 ] + nums[i]); res = Math.max(res, dp[i]); } return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int countDigitOne (int n) { int count = 0 ; long i = 1 ; while (n / i != 0 ) { long high = n / (10 * i); long cur = (n / i) % 10 ; long low = n - (n / i) * i; if (cur == 0 ) { count += high * i; } else if (cur == 1 ) { count += high * i + (low + 1 ); } else { count += (high + 1 ) * i; } i *= 10 ; } return count; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public int findNthDigit (int n) { int digit = 1 ; long start = 1 ; long count = 9 ; while (n > count) { n -= count; digit++; start *= 10 ; count = digit * start * 9 ; } long num = start + (n - 1 ) / digit; return Long.toString(num).charAt((n - 1 ) % digit) - '0' ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public String minNumber (int [] nums) { List<String> list = new ArrayList<>(); for (int num : nums) { list.add(new Integer(num).toString()); } list.sort(((o1, o2) -> (o1 + o2).compareTo(o2 + o1))); StringBuilder stringBuilder = new StringBuilder(); for (String s : list) { stringBuilder.append(s); } return stringBuilder.toString(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public int translateNum (int num) { String numStr = String.valueOf(num); char [] numChar = numStr.toCharArray(); int n = numChar.length; int [] dp = new int [n]; dp[0 ] = 1 ; if (num < 10 ) { return 1 ; } dp[1 ] = 1 + (numChar[0 ] == '1' || (numChar[0 ] == '2' && numChar[1 ] <= '5' ) ? 1 : 0 ); for (int i = 2 ; i < n; i++) { if (numChar[i - 1 ] == '1' || (numChar[i - 1 ] == '2' && numChar[i] <= '5' )) { dp[i] = dp[i - 1 ] + dp[i - 2 ]; } else { dp[i] = dp[i - 1 ]; } } for (int i = 0 ; i < n; i++) { System.out.println(dp[i]); } return dp[n - 1 ]; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public int maxValue (int [][] grid) { int row = grid.length; int col = grid[0 ].length; int [][] dp = new int [row][col]; dp[0 ][0 ] = grid[0 ][0 ]; for (int i = 1 ; i < row; i++) { dp[i][0 ] = dp[i - 1 ][0 ] + grid[i][0 ]; } for (int i = 1 ; i < col; i++) { dp[0 ][i] = dp[0 ][i - 1 ] + grid[0 ][i]; } for (int i = 1 ; i < row; i++) { for (int j = 1 ; j < col; j++) { dp[i][j] = Math.max(dp[i - 1 ][j], dp[i][j - 1 ]) + grid[i][j]; } } return dp[row - 1 ][col - 1 ]; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public int [] fairCandySwap(int [] A, int [] B) { int sumA = Arrays.stream(A).sum(); int sumB = Arrays.stream(B).sum(); int delta = (sumA - sumB) / 2 ; Set<Integer> set = new HashSet<>(); for (int a : A) { set.add(a); } for (int b : B) { if (set.contains(b + delta)) { return new int []{b + delta, b}; } } return new int []{-1 , -1 }; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution { public int lengthOfLongestSubstring (String s) { HashMap<Character, Integer> window = new HashMap<>(); int left = 0 , right = 0 , valid = 0 , res = 0 ; while (right < s.length()) { char c = s.charAt(right); right++; window.put(c, window.getOrDefault(c, 0 ) + 1 ); while (window.get(c) > 1 ) { char d = s.charAt(left); left++; window.put(d, window.get(d) - 1 ); } res = Math.max(res, right - left); } return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int nthUglyNumber (int n) { int p2 = 0 , p3 = 0 , p5 = 0 ; int [] dp = new int [n]; dp[0 ] = 1 ; for (int i = 1 ; i < n; i++) { dp[i] = Math.min(dp[p2] * 2 , Math.min(dp[p3] * 3 , dp[p5] * 5 )); if (dp[i] == dp[p2] * 2 ) { p2++; } if (dp[i] == dp[p3] * 3 ) { p3++; } if (dp[i] == dp[p5] * 5 ) { p5++; } } return dp[n - 1 ]; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public char firstUniqChar (String s) { HashMap<Character, Integer> map = new HashMap<>(); for (int i = 0 ; i < s.length(); i++) { map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0 ) + 1 ); } for (int i = 0 ; i < s.length(); i++) { if (map.get(s.charAt(i)) == 1 ) { return s.charAt(i); } } return ' ' ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public int reversePairs (int [] nums) { return merge(nums, 0 , nums.length - 1 ); } private int merge (int [] arr, int start, int end) { if (start >= end) return 0 ; int mid = start + (end - start) / 2 ; int count = merge(arr, start, mid) + merge(arr, mid + 1 , end); int [] temp = new int [end - start + 1 ]; int i = start, j = mid + 1 , k = 0 ; while (i <= mid && j <= end) { count += arr[i] <= arr[j] ? 0 : mid + 1 - i; temp[k++] = arr[i] <= arr[j] ? arr[i++] : arr[j++]; } while (i <= mid) { temp[k++] = arr[i++]; } while (j <= end) { temp[k++] = arr[j++]; } System.arraycopy(temp, 0 , arr, start, end - start + 1 ); return count; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public class Solution { public ListNode getIntersectionNode (ListNode headA, ListNode headB) { ListNode head1 = headA, head2 = headB; int num1 = 0 , num2 = 0 ; while (head1 != null ) { num1++; head1 = head1.next; } while (head2 != null ) { num2++; head2 = head2.next; } int abs = Math.abs(num1 - num2); if (num1 > num2) { while (abs-- > 0 ) { headA = headA.next; } } else { while (abs-- > 0 ) { headB = headB.next; } } while (headA != null && headB != null ) { if (headA == headB) { return headA; } headA = headA.next; headB = headB.next; } return null ; } }
1 2 3 4 5 6 7 8 9 10 public class Solution { public ListNode getIntersectionNode (ListNode headA, ListNode headB) { ListNode head1 = headA, head2 = headB; while (head1 != head2) { head1 = head1 != null ? head1.next : headB; head2 = head2 != null ? head2.next : headA; } return head1; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public int search (int [] nums, int target) { if (nums == null || nums.length == 0 ) { return 0 ; } int left = 0 , right = nums.length - 1 ; while (left <= right) { int mid = left + (right - left) / 2 ; if (nums[mid] < target) { left = mid + 1 ; } else if (nums[mid] > target) { right = mid - 1 ; } else if (nums[mid] == target) { right = mid - 1 ; } } int res = 0 ; while (left < nums.length && nums[left] == target) { res++; left++; } return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution { public int missingNumber (int [] nums) { int left = 0 , right = nums.length - 1 ; while (left <= right) { int mid = left + (right - left) / 2 ; if (nums[mid] != mid) { if (mid == 0 || nums[mid - 1 ] == mid - 1 ) { return mid; } else { right = mid - 1 ; } } else { left = mid + 1 ; } } return left; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution { private int target; private int res; public int kthLargest (TreeNode root, int k) { target = k; dfs(root); return res; } private void dfs (TreeNode root) { if (root == null ) { return ; } dfs(root.right); target--; if (target == 0 ) { res = root.val; return ; } dfs(root.left); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution { private int target; private int res; public int kthLargest (TreeNode root, int k) { target = k; dfs(root); return res; } private void dfs (TreeNode root) { if (root == null ) { return ; } dfs(root.right); target--; if (target == 0 ) { res = root.val; return ; } dfs(root.left); } }
1 2 3 4 5 6 7 8 class Solution { public int maxDepth (TreeNode root) { if (root == null ) { return 0 ; } return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public boolean isBalanced (TreeNode root) { if (root == null ) { return true ; } return isBalanced(root.left) && isBalanced(root.right) && Math.abs(maxDepth(root.left) - maxDepth(root.right)) <= 1 ; } public int maxDepth (TreeNode root) { if (root == null ) { return 0 ; } return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public int [] singleNumbers(int [] nums) { int k = 0 ; for (int num : nums) { k ^= num; } int mask = 1 ; while ((k & mask) == 0 ) { mask <<= 1 ; } int a = 0 , b = 0 ; for (int num : nums) { if ((num & mask) == 0 ) { a ^= num; } else { b ^= num; } } return new int []{a, b}; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public int [] twoSum(int [] nums, int target) { int left = 0 , right = nums.length - 1 ; while (left < right) { if (nums[left] + nums[right] > target) { right--; } else if (nums[left] + nums[right] < target) { left++; } else { return new int []{nums[left], nums[right]}; } } return new int []{-1 , -1 }; } }
1.滑动窗口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public int [][] findContinuousSequence(int target) { List<int []> list = new ArrayList<>(); int left = 1 , right = 1 , sum = 0 ; while (right < target) { sum += right; while (sum > target) { sum -= left++; } if (sum == target) { int [] temp = new int [right - left + 1 ]; for (int i = 0 ; i < temp.length; i++) { temp[i] = i + left; } list.add(temp); } right++; } int [][] res = new int [list.size()][]; for (int i = 0 ; i < list.size(); i++) { res[i] = list.get(i); } return res; } }
2.数学
如果有两个连续的数之和等于target,那么相差为1, (target - 1) % 2 == 0, 且数组一定是从 (target - 1) / 2开始的,数组的元素就是2个;如果是3个连续的数组,那么三个数之间相差为1、2,(target - 1 - 2) % 3 == 0,且数组一定是从 (target - 1 - 2) / 3开始的,数组元素是3个,依次类推,但是注意target必须是大于0的数,且res需要倒序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public int [][] findContinuousSequence(int target) { List<int []> list = new ArrayList<>(); int i = 1 ; while (target > 0 ) { target -= i++; if (target > 0 && target % i == 0 ) { int [] temp = new int [i]; for (int j = 0 ; j < i; j++) { temp[j] = target / i + j; } list.add(temp); } } Collections.reverse(list); int [][] res = new int [list.size()][]; for (int j = 0 ; j < list.size(); j++) { res[j] = list.get(j); } return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public String reverseWords (String s) { String[] strings = s.strip().split(" " ); StringBuilder stringBuilder = new StringBuilder(); for (int i = strings.length - 1 ; i >= 0 ; i--) { if (strings[i].equals("" )) { continue ; } if (i == 0 ) { stringBuilder.append(strings[i]); } else { stringBuilder.append(strings[i]).append(" " ); } } return stringBuilder.toString(); } }
1 2 3 4 5 class Solution { public String reverseLeftWords (String s, int n) { return s.substring(n) + s.substring(0 , n); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int [] maxSlidingWindow(int [] nums, int k) { if (nums == null || nums.length == 0 || k == 0 ) { return new int [0 ]; } int left = 0 , right = k - 1 ; int [] res = new int [nums.length - k + 1 ]; int i = 0 ; while (right < nums.length) { int max = nums[left]; for (int j = left + 1 ; j <= right; j++) { max = Math.max(max, nums[j]); } res[i++] = max; left++; right++; } return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public int [] maxSlidingWindow(int [] nums, int k) { if (nums == null || nums.length == 0 || k == 0 ) { return new int [0 ]; } Deque<Integer> deque = new LinkedList<>(); int [] res = new int [nums.length - k + 1 ]; for (int i = 0 ; i < k; i++) { while (!deque.isEmpty() && deque.peekLast() < nums[i]) { deque.removeLast(); } deque.addLast(nums[i]); } res[0 ] = deque.peekFirst(); for (int i = k; i < nums.length; i++) { if (deque.peekFirst() == nums[i - k]) { deque.removeFirst(); } while (!deque.isEmpty() && deque.peekLast() < nums[i]) { deque.removeLast(); } deque.addLast(nums[i]); res[i - k + 1 ] =deque.peekFirst(); } return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class MaxQueue { Queue<Integer> queue; Deque<Integer> deque; public MaxQueue () { queue = new LinkedList<>(); deque = new LinkedList<>(); } public int max_value () { if (deque.isEmpty()) { return -1 ; } else { return deque.peekFirst(); } } public void push_back (int value) { while (!deque.isEmpty() && deque.peekLast() < value) { deque.removeLast(); } deque.addLast(value); queue.offer(value); } public int pop_front () { if (queue.isEmpty()) { return -1 ; } int q = queue.poll(); if (q == deque.peekFirst()) { deque.removeFirst(); } return q; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class Solution { public double [] dicesProbability(int n) { if (n == 1 ) { return new double []{0.16667 , 0.16667 , 0.16667 , 0.16667 , 0.16667 , 0.16667 }; } int [][] dp = new int [n + 1 ][6 * n + 1 ]; double [] res = new double [5 * n + 1 ]; for (int i = 1 ; i <= 6 ; i++) { dp[1 ][i] = 1 ; } for (int i = 2 ; i <= n; i++) { for (int j = i; j <= 6 * n; j++) { dp[i][j] = dp[i - 1 ][j - 1 ]; int k = 1 ; while (k <= 5 ) { k++; if (j - k < 1 ) { break ; } dp[i][j] += dp[i - 1 ][j - k]; } } } int [] dp2 = Arrays.copyOfRange(dp[n], n, 6 * n + 1 ); double sum = 0 ; for (int i : dp2) { sum += i; } for (int i = 0 ; i < res.length; i++) { res[i] = dp2[i] / sum; } return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public boolean isStraight (int [] nums) { Arrays.sort(nums); int zeros = 0 ; for (int i = 0 ; i < nums.length - 1 ; i++) { if (nums[i] == 0 ) { zeros++; continue ; } else { if (nums[i] == nums[i + 1 ]) { return false ; } else { zeros -= nums[i + 1 ] - nums[i] - 1 ; } } } return zeros >= 0 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public int lastRemaining (int n, int m) { ArrayList<Integer> list = new ArrayList<>(); for (int i = 0 ; i < n; i++) { list.add(i); } int idx = 0 ; while (n > 1 ) { idx = (idx + m - 1 ) % n; list.remove(idx); n--; } return list.get(0 ); } }
1 2 3 4 5 6 7 8 9 10 class Solution { public int maxProfit (int [] prices) { int dp_0 = 0 , dp_1 = Integer.MIN_VALUE; for (int i = 0 ; i < prices.length; i++) { dp_0 = Math.max(dp_0, dp_1 + prices[i]); dp_1 = Math.max(dp_1, -prices[i]); } return dp_0; } }
1 2 3 4 5 6 7 8 class Solution { public int sumNums (int n) { if (n == 0 ) { return 0 ; } return n + sumNums(n - 1 ); } }
1 2 3 4 5 6 7 8 9 10 class Solution { public int add(int a, int b) { while (b != 0) { int c = (a & b) << 1; a ^= b; b = c; } return a; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public int [] constructArr(int [] a) { int [] res = new int [a.length]; for (int i = 0 , sum = 1 ; i < a.length; sum *= a[i], i++) { res[i] = sum; } for (int i = a.length - 1 , sum = 1 ; i >= 0 ; sum *= a[i], i--) { res[i] *= sum; } return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 class Solution { public int strToInt (String str) { if (str == null || str.length() == 0 ) { return 0 ; } int index = 0 ; while (index < str.length() && str.charAt(index) == ' ' ) { index++; } int flag = 0 ; if (index >= str.length()) { return 0 ; } if (str.charAt(index) == '-' ) { flag = 1 ; index++; } else if (str.charAt(index) == '+' ) { flag = 0 ; index++; } if (index >= str.length() || str.charAt(index) < '0' || str.charAt(index) > '9' ) { return 0 ; } StringBuilder stringBuilder = new StringBuilder(); int wei = -1 ; for (int i = index; i < str.length(); i++) { if (str.charAt(i) > '9' || str.charAt(i) < '0' ) { break ; } stringBuilder.append(str.charAt(i)); wei++; } if (stringBuilder.length() == 0 ) { return 0 ; } double res = 0 ; for (int i = 0 ; i < stringBuilder.length(); i++) { res += (stringBuilder.charAt(i) - '0' ) * Math.pow(10 , wei); wei--; } if (res > Integer.MAX_VALUE) { if (flag == 0 ) { return Integer.MAX_VALUE; } else { return Integer.MIN_VALUE; } } if (flag == 0 ) { return (int ) res; } else { return (int ) (0 - res); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public TreeNode lowestCommonAncestor (TreeNode root, TreeNode p, TreeNode q) { if (root == null ) { return null ; } if (root.val < p.val && root.val < q.val) { return lowestCommonAncestor(root.right, p, q); } else if (root.val > p.val && root.val > q.val) { return lowestCommonAncestor(root.left, p, q); } else { return root; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public TreeNode lowestCommonAncestor (TreeNode root, TreeNode p, TreeNode q) { if (root == null ) { return null ; } if (root == p || root == q) { return root; } TreeNode left = lowestCommonAncestor(root.left, p, q); TreeNode right = lowestCommonAncestor(root.right, p, q); if (left != null && right != null ) { return root; } else if (left != null ) { return left; } else if (right != null ) { return right; } else { return null ; } } }