文章目录
36. (必备)二叉树高频题目上
package class036;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class Code01_LevelOrderTraversal {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
}
public static List<List<Integer>> levelOrder1(TreeNode root) {
List<List<Integer>> ans = new ArrayList<>();
if (root != null) {
Queue<TreeNode> queue = new LinkedList<>();
HashMap<TreeNode, Integer> levels = new HashMap<>();
queue.add(root);
levels.put(root, 0);
while (!queue.isEmpty()) {
TreeNode cur = queue.poll();
int level = levels.get(cur);
if (ans.size() == level) {
ans.add(new ArrayList<>());
}
ans.get(level).add(cur.val);
if (cur.left != null) {
queue.add(cur.left);
levels.put(cur.left, level + 1);
}
if (cur.right != null) {
queue.add(cur.right);
levels.put(cur.right, level + 1);
}
}
}
return ans;
}
public static int MAXN = 2001;
public static TreeNode[] queue = new TreeNode[MAXN];
public static int l, r;
public static List<List<Integer>> levelOrder2(TreeNode root) {
List<List<Integer>> ans = new ArrayList<>();
if (root != null) {
l = r = 0;
queue[r++] = root;
while (l < r) {
int size = r - l;
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < size; i++) {
TreeNode cur = queue[l++];
list.add(cur.val);
if (cur.left != null) {
queue[r++] = cur.left;
}
if (cur.right != null) {
queue[r++] = cur.right;
}
}
ans.add(list);
}
}
return ans;
}
}
package class036;
import java.util.ArrayList;
import java.util.List;
public class Code02_ZigzagLevelOrderTraversal {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
}
public static int MAXN = 2001;
public static TreeNode[] queue = new TreeNode[MAXN];
public static int l, r;
public static List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> ans = new ArrayList<>();
if (root != null) {
l = r = 0;
queue[r++] = root;
boolean reverse = false;
while (l < r) {
int size = r - l;
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = reverse ? r - 1 : l, j = reverse ? -1 : 1, k = 0; k < size; i += j, k++) {
TreeNode cur = queue[i];
list.add(cur.val);
}
for (int i = 0; i < size; i++) {
TreeNode cur = queue[l++];
if (cur.left != null) {
queue[r++] = cur.left;
}
if (cur.right != null) {
queue[r++] = cur.right;
}
}
ans.add(list);
reverse = !reverse;
}
}
return ans;
}
}
package class036;
public class Code03_WidthOfBinaryTree {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
}
public static int MAXN = 3001;
public static TreeNode[] nq = new TreeNode[MAXN];
public static int[] iq = new int[MAXN];
public static int l, r;
public static int widthOfBinaryTree(TreeNode root) {
int ans = 1;
l = r = 0;
nq[r] = root;
iq[r++] = 1;
while (l < r) {
int size = r - l;
ans = Math.max(ans, iq[r - 1] - iq[l] + 1);
for (int i = 0; i < size; i++) {
TreeNode node = nq[l];
int id = iq[l++];
if (node.left != null) {
nq[r] = node.left;
iq[r++] = id * 2;
}
if (node.right != null) {
nq[r] = node.right;
iq[r++] = id * 2 + 1;
}
}
}
return ans;
}
}
package class036;
public class Code04_DepthOfBinaryTree {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
}
public static int maxDepth(TreeNode root) {
return root == null ? 0 : Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
}
if (root.left == null && root.right == null) {
return 1;
}
int ldeep = Integer.MAX_VALUE;
int rdeep = Integer.MAX_VALUE;
if (root.left != null) {
ldeep = minDepth(root.left);
}
if (root.right != null) {
rdeep = minDepth(root.right);
}
return Math.min(ldeep, rdeep) + 1;
}
}
package class036;
public class Code05_PreorderSerializeAndDeserialize {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int v) {
val = v;
}
}
public class Codec {
public String serialize(TreeNode root) {
StringBuilder builder = new StringBuilder();
f(root, builder);
return builder.toString();
}
void f(TreeNode root, StringBuilder builder) {
if (root == null) {
builder.append("#,");
} else {
builder.append(root.val + ",");
f(root.left, builder);
f(root.right, builder);
}
}
public TreeNode deserialize(String data) {
String[] vals = data.split(",");
cnt = 0;
return g(vals);
}
public static int cnt;
TreeNode g(String[] vals) {
String cur = vals[cnt++];
if (cur.equals("#")) {
return null;
} else {
TreeNode head = new TreeNode(Integer.valueOf(cur));
head.left = g(vals);
head.right = g(vals);
return head;
}
}
}
}
package class036;
public class Code06_LevelorderSerializeAndDeserialize {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int v) {
val = v;
}
}
public class Codec {
public static int MAXN = 10001;
public static TreeNode[] queue = new TreeNode[MAXN];
public static int l, r;
public String serialize(TreeNode root) {
StringBuilder builder = new StringBuilder();
if (root != null) {
builder.append(root.val + ",");
l = 0;
r = 0;
queue[r++] = root;
while (l < r) {
root = queue[l++];
if (root.left != null) {
builder.append(root.left.val + ",");
queue[r++] = root.left;
} else {
builder.append("#,");
}
if (root.right != null) {
builder.append(root.right.val + ",");
queue[r++] = root.right;
} else {
builder.append("#,");
}
}
}
return builder.toString();
}
public TreeNode deserialize(String data) {
if (data.equals("")) {
return null;
}
String[] nodes = data.split(",");
int index = 0;
TreeNode root = generate(nodes[index++]);
l = 0;
r = 0;
queue[r++] = root;
while (l < r) {
TreeNode cur = queue[l++];
cur.left = generate(nodes[index++]);
cur.right = generate(nodes[index++]);
if (cur.left != null) {
queue[r++] = cur.left;
}
if (cur.right != null) {
queue[r++] = cur.right;
}
}
return root;
}
private TreeNode generate(String val) {
return val.equals("#") ? null : new TreeNode(Integer.valueOf(val));
}
}
}
package class036;
import java.util.HashMap;
public class Code07_PreorderInorderBuildBinaryTree {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int v) {
val = v;
}
}
public static TreeNode buildTree(int[] pre, int[] in) {
if (pre == null || in == null || pre.length != in.length) {
return null;
}
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < in.length; i++) {
map.put(in[i], i);
}
return f(pre, 0, pre.length - 1, in, 0, in.length - 1, map);
}
public static TreeNode f(int[] pre, int l1, int r1, int[] in, int l2, int r2, HashMap<Integer, Integer> map) {
if (l1 > r1) {
return null;
}
TreeNode head = new TreeNode(pre[l1]);
if (l1 == r1) {
return head;
}
int k = map.get(pre[l1]);
head.left = f(pre, l1 + 1, l1 + k - l2, in, l2, k - 1, map);
head.right = f(pre, l1 + k - l2 + 1, r1, in, k + 1, r2, map);
return head;
}
}
package class036;
public class Code08_CompletenessOfBinaryTree {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
}
public static int MAXN = 101;
public static TreeNode[] queue = new TreeNode[MAXN];
public static int l, r;
public static boolean isCompleteTree(TreeNode h) {
if (h == null) {
return true;
}
l = r = 0;
queue[r++] = h;
boolean leaf = false;
while (l < r) {
h = queue[l++];
if ((h.left == null && h.right != null) || (leaf && (h.left != null || h.right != null))) {
return false;
}
if (h.left != null) {
queue[r++] = h.left;
}
if (h.right != null) {
queue[r++] = h.right;
}
if (h.left == null || h.right == null) {
leaf = true;
}
}
return true;
}
}
package class036;
public class Code09_CountCompleteTreeNodes {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
}
public static int countNodes(TreeNode head) {
if (head == null) {
return 0;
}
return f(head, 1, mostLeft(head, 1));
}
public static int f(TreeNode cur, int level, int h) {
if (level == h) {
return 1;
}
if (mostLeft(cur.right, level + 1) == h) {
return (1 << (h - level)) + f(cur.right, level + 1, h);
} else {
return (1 << (h - level - 1)) + f(cur.left, level + 1, h);
}
}
public static int mostLeft(TreeNode cur, int level) {
while (cur != null) {
level++;
cur = cur.left;
}
return level - 1;
}
}
37. (必备)二叉树高频题目下
package class037;
public class Code01_LowestCommonAncestor {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
}
public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) {
return root;
}
TreeNode l = lowestCommonAncestor(root.left, p, q);
TreeNode r = lowestCommonAncestor(root.right, p, q);
if (l != null && r != null) {
return root;
}
if (l == null && r == null) {
return null;
}
return l != null ? l : r;
}
}
package class037;
public class Code02_LowestCommonAncestorBinarySearch {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
}
public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
while (root.val != p.val && root.val != q.val) {
if (Math.min(p.val, q.val) < root.val && root.val < Math.max(p.val, q.val)) {
break;
}
root = root.val < Math.min(p.val, q.val) ? root.right : root.left;
}
return root;
}
package class037;
import java.util.ArrayList;
import java.util.List;
public class Code03_PathSumII {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
}
public static List<List<Integer>> pathSum(TreeNode root, int aim) {
List<List<Integer>> ans = new ArrayList<>();
if (root != null) {
List<Integer> path = new ArrayList<>();
f(root, aim, 0, path, ans);
}
return ans;
}
public static void f(TreeNode cur, int aim, int sum, List<Integer> path, List<List<Integer>> ans) {
if (cur.left == null && cur.right == null) {
if (cur.val + sum == aim) {
path.add(cur.val);
copy(path, ans);
path.remove(path.size() - 1);
}
} else {
path.add(cur.val);
if (cur.left != null) {
f(cur.left, aim, sum + cur.val, path, ans);
}
if (cur.right != null) {
f(cur.right, aim, sum + cur.val, path, ans);
}
path.remove(path.size() - 1);
}
}
public static void copy(List<Integer> path, List<List<Integer>> ans) {
List<Integer> copy = new ArrayList<>();
for (Integer num : path) {
copy.add(num);
}
ans.add(copy);
}
}
package class037;
public class Code04_BalancedBinaryTree {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
}
public static boolean balance;
public static boolean isBalanced(TreeNode root) {
balance = true;
height(root);
return balance;
}
public static int height(TreeNode cur) {
if (!balance || cur == null) {
return 0;
}
int lh = height(cur.left);
int rh = height(cur.right);
if (Math.abs(lh - rh) > 1) {
balance = false;
}
return Math.max(lh, rh) + 1;
}
}
package class037;
public class Code05_ValidateBinarySearchTree {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
}
public static int MAXN = 10001;
public static TreeNode[] stack = new TreeNode[MAXN];
public static int r;
public static boolean isValidBST1(TreeNode head) {
if (head == null) {
return true;
}
TreeNode pre = null;
r = 0;
while (r > 0 || head != null) {
if (head != null) {
stack[r++] = head;
head = head.left;
} else {
head = stack[--r];
if (pre != null && pre.val >= head.val) {
return false;
}
pre = head;
head = head.right;
}
}
return true;
}
public static long min, max;
public static boolean isValidBST2(TreeNode head) {
if (head == null) {
min = Long.MAX_VALUE;
max = Long.MIN_VALUE;
return true;
}
boolean lok = isValidBST2(head.left);
long lmin = min;
long lmax = max;
boolean rok = isValidBST2(head.right);
long rmin = min;
long rmax = max;
min = Math.min(Math.min(lmin, rmin), head.val);
max = Math.max(Math.max(lmax, rmax), head.val);
return lok && rok && lmax < head.val && head.val < rmin;
}
}
package class037;
public class Code06_TrimBinarySearchTree {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
}
public static TreeNode trimBST(TreeNode cur, int low, int high) {
if (cur == null) {
return null;
}
if (cur.val < low) {
return trimBST(cur.right, low, high);
}
if (cur.val > high) {
return trimBST(cur.left, low, high);
}
cur.left = trimBST(cur.left, low, high);
cur.right = trimBST(cur.right, low, high);
return cur;
}
}
package class037;
public class Code07_HouseRobberIII {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
}
public static int rob(TreeNode root) {
f(root);
return Math.max(yes, no);
}
public static int yes;
public static int no;
public static void f(TreeNode root) {
if (root == null) {
yes = 0;
no = 0;
} else {
int y = root.val;
int n = 0;
f(root.left);
y += no;
n += Math.max(yes, no);
f(root.right);
y += no;
n += Math.max(yes, no);
yes = y;
no = n;
}
}
}
38. (必备)常见经典递归过程解析
package class038;
import java.util.HashSet;
public class Code01_Subsequences {
public static String[] generatePermutation1(String str) {
char[] s = str.toCharArray();
HashSet<String> set = new HashSet<>();
f1(s, 0, new StringBuilder(), set);
int m = set.size();
String[] ans = new String[m];
int i = 0;
for (String cur : set) {
ans[i++] = cur;
}
return ans;
}
public static void f1(char[] s, int i, StringBuilder path, HashSet<String> set) {
if (i == s.length) {
set.add(path.toString());
} else {
path.append(s[i]);
f1(s, i + 1, path, set);
path.deleteCharAt(path.length() - 1);
f1(s, i + 1, path, set);
}
}
public static String[] generatePermutation2(String str) {
char[] s = str.toCharArray();
HashSet<String> set = new HashSet<>();
f2(s, 0, new char[s.length], 0, set);
int m = set.size();
String[] ans = new String[m];
int i = 0;
for (String cur : set) {
ans[i++] = cur;
}
return ans;
}
public static void f2(char[] s, int i, char[] path, int size, HashSet<String> set) {
if (i == s.length) {
set.add(String.valueOf(path, 0, size));
} else {
path[size] = s[i];
f2(s, i + 1, path, size + 1, set);
f2(s, i + 1, path, size, set);
}
}
}
package class038;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Code02_Combinations {
public static List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
Arrays.sort(nums);
f(nums, 0, new int[nums.length], 0, ans);
return ans;
}
public static void f(int[] nums, int i, int[] path, int size, List<List<Integer>> ans) {
if (i == nums.length) {
ArrayList<Integer> cur = new ArrayList<>();
for (int j = 0; j < size; j++) {
cur.add(path[j]);
}
ans.add(cur);
} else {
int j = i + 1;
while (j < nums.length && nums[i] == nums[j]) {
j++;
}
f(nums, j, path, size, ans);
for (; i < j; i++) {
path[size++] = nums[i];
f(nums, j, path, size, ans);
}
}
}
}
package class038;
import java.util.ArrayList;
import java.util.List;
public class Code03_Permutations {
public static List<List<Integer>> permute(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
f(nums, 0, ans);
return ans;
}
public static void f(int[] nums, int i, List<List<Integer>> ans) {
if (i == nums.length) {
List<Integer> cur = new ArrayList<>();
for (int num : nums) {
cur.add(num);
}
ans.add(cur);
} else {
for (int j = i; j < nums.length; j++) {
swap(nums, i, j);
f(nums, i + 1, ans);
swap(nums, i, j);
}
}
}
public static void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
public static void main(String[] args) {
int[] nums = { 1, 2, 3 };
List<List<Integer>> ans = permute(nums);
for (List<Integer> list : ans) {
for (int num : list) {
System.out.print(num + " ");
}
System.out.println();
}
}
}
package class038;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
public class Code04_PermutationWithoutRepetition {
public static List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
f(nums, 0, ans);
return ans;
}
public static void f(int[] nums, int i, List<List<Integer>> ans) {
if (i == nums.length) {
List<Integer> cur = new ArrayList<>();
for (int num : nums) {
cur.add(num);
}
ans.add(cur);
} else {
HashSet<Integer> set = new HashSet<>();
for (int j = i; j < nums.length; j++) {
if (!set.contains(nums[j])) {
set.add(nums[j]);
swap(nums, i, j);
f(nums, i + 1, ans);
swap(nums, i, j);
}
}
}
}
public static void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
package class038;
import java.util.Stack;
public class Code05_ReverseStackWithRecursive {
public static void reverse(Stack<Integer> stack) {
if (stack.isEmpty()) {
return;
}
int num = bottomOut(stack);
reverse(stack);
stack.push(num);
}
public static int bottomOut(Stack<Integer> stack) {
int ans = stack.pop();
if (stack.isEmpty()) {
return ans;
} else {
int last = bottomOut(stack);
stack.push(ans);
return last;
}
}
public static void main(String[] args) {
Stack<Integer> stack = new Stack<Integer>();
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);
reverse(stack);
while (!stack.isEmpty()) {
System.out.println(stack.pop());
}
}
}
package class038;
import java.util.Stack;
public class Code06_SortStackWithRecursive {
public static void sort(Stack<Integer> stack) {
int deep = deep(stack);
while (deep > 0) {
int max = max(stack, deep);
int k = times(stack, deep, max);
down(stack, deep, max, k);
deep -= k;
}
}
public static int deep(Stack<Integer> stack) {
if (stack.isEmpty()) {
return 0;
}
int num = stack.pop();
int deep = deep(stack) + 1;
stack.push(num);
return deep;
}
public static int max(Stack<Integer> stack, int deep) {
if (deep == 0) {
return Integer.MIN_VALUE;
}
int num = stack.pop();
int restMax = max(stack, deep - 1);
int max = Math.max(num, restMax);
stack.push(num);
return max;
}
public static int times(Stack<Integer> stack, int deep, int max) {
if (deep == 0) {
return 0;
}
int num = stack.pop();
int restTimes = times(stack, deep - 1, max);
int times = restTimes + (num == max ? 1 : 0);
stack.push(num);
return times;
}
public static void down(Stack<Integer> stack, int deep, int max, int k) {
if (deep == 0) {
for (int i = 0; i < k; i++) {
stack.push(max);
}
} else {
int num = stack.pop();
down(stack, deep - 1, max, k);
if (num != max) {
stack.push(num);
}
}
}
public static Stack<Integer> randomStack(int n, int v) {
Stack<Integer> ans = new Stack<Integer>();
for (int i = 0; i < n; i++) {
ans.add((int) (Math.random() * v));
}
return ans;
}
public static boolean isSorted(Stack<Integer> stack) {
int step = Integer.MIN_VALUE;
while (!stack.isEmpty()) {
if (step > stack.peek()) {
return false;
}
step = stack.pop();
}
return true;
}
public static void main(String[] args) {
Stack<Integer> test = new Stack<Integer>();
test.add(1);
test.add(5);
test.add(4);
test.add(5);
test.add(3);
test.add(2);
test.add(3);
test.add(1);
test.add(4);
test.add(2);
sort(test);
while (!test.isEmpty()) {
System.out.println(test.pop());
}
int N = 20;
int V = 20;
int testTimes = 20000;
System.out.println("测试开始");
for (int i = 0; i < testTimes; i++) {
int n = (int) (Math.random() * N);
Stack<Integer> stack = randomStack(n, V);
sort(stack);
if (!isSorted(stack)) {
System.out.println("出错了!");
break;
}
}
System.out.println("测试结束");
}
}
package class038;
public class Code07_TowerOfHanoi {
public static void hanoi(int n) {
if (n > 0) {
f(n, "左", "右", "中");
}
}
public static void f(int i, String from, String to, String other) {
if (i == 1) {
System.out.println("移动圆盘 1 从 " + from + " 到 " + to);
} else {
f(i - 1, from, other, to);
System.out.println("移动圆盘 " + i + " 从 " + from + " 到 " + to);
f(i - 1, other, to, from);
}
}
public static void main(String[] args) {
int n = 3;
hanoi(n);
}
}
39. (必备)嵌套类问题的递归解题套路
package class039;
import java.util.ArrayList;
public class Code01_BasicCalculatorIII {
public static int calculate(String str) {
where = 0;
return f(str.toCharArray(), 0);
}
public static int where;
public static int f(char[] s, int i) {
int cur = 0;
ArrayList<Integer> numbers = new ArrayList<>();
ArrayList<Character> ops = new ArrayList<>();
while (i < s.length && s[i] != ')') {
if (s[i] >= '0' && s[i] <= '9') {
cur = cur * 10 + s[i++] - '0';
} else if (s[i] != '(') {
push(numbers, ops, cur, s[i++]);
cur = 0;
} else {
cur = f(s, i + 1);
i = where + 1;
}
}
push(numbers, ops, cur, '+');
where = i;
return compute(numbers, ops);
}
public static void push(ArrayList<Integer> numbers, ArrayList<Character> ops, int cur, char op) {
int n = numbers.size();
if (n == 0 || ops.get(n - 1) == '+' || ops.get(n - 1) == '-') {
numbers.add(cur);
ops.add(op);
} else {
int topNumber = numbers.get(n - 1);
char topOp = ops.get(n - 1);
if (topOp == '*') {
numbers.set(n - 1, topNumber * cur);
} else {
numbers.set(n - 1, topNumber / cur);
}
ops.set(n - 1, op);
}
}
public static int compute(ArrayList<Integer> numbers, ArrayList<Character> ops) {
int n = numbers.size();
int ans = numbers.get(0);
for (int i = 1; i < n; i++) {
ans += ops.get(i - 1) == '+' ? numbers.get(i) : -numbers.get(i);
}
return ans;
}
}
package class039;
public class Code02_DecodeString {
public static String decodeString(String str) {
where = 0;
return f(str.toCharArray(), 0);
}
public static int where;
public static String f(char[] s, int i) {
StringBuilder path = new StringBuilder();
int cnt = 0;
while (i < s.length && s[i] != ']') {
if ((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z')) {
path.append(s[i++]);
} else if (s[i] >= '0' && s[i] <= '9') {
cnt = cnt * 10 + s[i++] - '0';
} else {
path.append(get(cnt, f(s, i + 1)));
i = where + 1;
cnt = 0;
}
}
where = i;
return path.toString();
}
public static String get(int cnt, String str) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < cnt; i++) {
builder.append(str);
}
return builder.toString();
}
}
package class039;
import java.util.TreeMap;
public class Code03_NumberOfAtoms {
public static String countOfAtoms(String str) {
where = 0;
TreeMap<String, Integer> map = f(str.toCharArray(), 0);
StringBuilder ans = new StringBuilder();
for (String key : map.keySet()) {
ans.append(key);
int cnt = map.get(key);
if (cnt > 1) {
ans.append(cnt);
}
}
return ans.toString();
}
public static int where;
public static TreeMap<String, Integer> f(char[] s, int i) {
TreeMap<String, Integer> ans = new TreeMap<>();
StringBuilder name = new StringBuilder();
TreeMap<String, Integer> pre = null;
int cnt = 0;
while (i < s.length && s[i] != ')') {
if (s[i] >= 'A' && s[i] <= 'Z' || s[i] == '(') {
fill(ans, name, pre, cnt);
name.setLength(0);
pre = null;
cnt = 0;
if (s[i] >= 'A' && s[i] <= 'Z') {
name.append(s[i++]);
} else {
pre = f(s, i + 1);
i = where + 1;
}
} else if (s[i] >= 'a' && s[i] <= 'z') {
name.append(s[i++]);
} else {
cnt = cnt * 10 + s[i++] - '0';
}
}
fill(ans, name, pre, cnt);
where = i;
return ans;
}
public static void fill(TreeMap<String, Integer> ans, StringBuilder name, TreeMap<String, Integer> pre, int cnt) {
if (name.length() > 0 || pre != null) {
cnt = cnt == 0 ? 1 : cnt;
if (name.length() > 0) {
String key = name.toString();
ans.put(key, ans.getOrDefault(key, 0) + cnt);
} else {
for (String key : pre.keySet()) {
ans.put(key, ans.getOrDefault(key, 0) + pre.get(key) * cnt);
}
}
}
}
}
40. (必备)N皇后问题(含位运算求解)
package class040;
public class NQueens {
public static int totalNQueens1(int n) {
if (n < 1) {
return 0;
}
return f1(0, new int[n], n);
}
public static int f1(int i, int[] path, int n) {
if (i == n) {
return 1;
}
int ans = 0;
for (int j = 0; j < n; j++) {
if (check(path, i, j)) {
path[i] = j;
ans += f1(i + 1, path, n);
}
}
return ans;
}
public static boolean check(int[] path, int i, int j) {
for (int k = 0; k < i; k++) {
if (j == path[k] || Math.abs(i - k) == Math.abs(j - path[k])) {
return false;
}
}
return true;
}
public static int totalNQueens2(int n) {
if (n < 1) {
return 0;
}
int limit = (1 << n) - 1;
return f2(limit, 0, 0, 0);
}
public static int f2(int limit, int col, int left, int right) {
if (col == limit) {
return 1;
}
int ban = col | left | right;
int candidate = limit & (~ban);
int place = 0;
int ans = 0;
while (candidate != 0) {
place = candidate & (-candidate);
candidate ^= place;
ans += f2(limit, col | place, (left | place) >> 1, (right | place) << 1);
}
return ans;
}
public static void main(String[] args) {
int n = 14;
long start, end;
System.out.println("测试开始");
System.out.println("解决" + n + "皇后问题");
start = System.currentTimeMillis();
System.out.println("方法1答案 : " + totalNQueens1(n));
end = System.currentTimeMillis();
System.out.println("方法1运行时间 : " + (end - start) + " 毫秒");
start = System.currentTimeMillis();
System.out.println("方法2答案 : " + totalNQueens2(n));
end = System.currentTimeMillis();
System.out.println("方法2运行时间 : " + (end - start) + " 毫秒");
System.out.println("测试结束");
System.out.println("=======");
System.out.println("只有位运算的版本,才能10秒内跑完16皇后问题的求解过程");
start = System.currentTimeMillis();
int ans = totalNQueens2(16);
end = System.currentTimeMillis();
System.out.println("16皇后问题的答案 : " + ans);
System.out.println("运行时间 : " + (end - start) + " 毫秒");
}
}
41. (必备)最大公约数, 同余原理
package class041;
public class Code01_GcdAndLcm {
public static long gcd(long a, long b) {
return b == 0 ? a : gcd(b, a % b);
}
public static long lcm(long a, long b) {
return (long) a / gcd(a, b) * b;
}
}
package class041;
public class Code02_NthMagicalNumber {
public static int nthMagicalNumber(int n, int a, int b) {
long lcm = lcm(a, b);
long ans = 0;
for (long l = 0, r = (long) n * Math.min(a, b), m = 0; l <= r;) {
m = (l + r) / 2;
if (m / a + m / b - m / lcm >= n) {
ans = m;
r = m - 1;
} else {
l = m + 1;
}
}
return (int) (ans % 1000000007);
}
public static long gcd(long a, long b) {
return b == 0 ? a : gcd(b, a % b);
}
public static long lcm(long a, long b) {
return (long) a / gcd(a, b) * b;
}
}
package class041;
import java.math.BigInteger;
public class Code03_SameMod {
public static long random() {
return (long) (Math.random() * Long.MAX_VALUE);
}
public static int f1(long a, long b, long c, long d, int mod) {
BigInteger o1 = new BigInteger(String.valueOf(a));
BigInteger o2 = new BigInteger(String.valueOf(b));
BigInteger o3 = new BigInteger(String.valueOf(c));
BigInteger o4 = new BigInteger(String.valueOf(d));
BigInteger o5 = o1.add(o2);
BigInteger o6 = o3.subtract(o4);
BigInteger o7 = o1.multiply(o3);
BigInteger o8 = o2.multiply(o4);
BigInteger o9 = o5.multiply(o6);
BigInteger o10 = o7.subtract(o8);
BigInteger o11 = o9.add(o10);
BigInteger o12 = o11.mod(new BigInteger(String.valueOf(mod)));
if (o12.signum() == -1) {
return o12.add(new BigInteger(String.valueOf(mod))).intValue();
} else {
return o12.intValue();
}
}
public static int f2(long a, long b, long c, long d, int mod) {
int o1 = (int) (a % mod);
int o2 = (int) (b % mod);
int o3 = (int) (c % mod);
int o4 = (int) (d % mod);
int o5 = (o1 + o2) % mod;
int o6 = (o3 - o4 + mod) % mod;
int o7 = (int) (((long) o1 * o3) % mod);
int o8 = (int) (((long) o2 * o4) % mod);
int o9 = (int) (((long) o5 * o6) % mod);
int o10 = (o7 - o8 + mod) % mod;
int ans = (o9 + o10) % mod;
return ans;
}
public static void main(String[] args) {
System.out.println("测试开始");
int testTime = 100000;
int mod = 1000000007;
for (int i = 0; i < testTime; i++) {
long a = random();
long b = random();
long c = random();
long d = random();
if (f1(a, b, c, d, mod) != f2(a, b, c, d, mod)) {
System.out.println("出错了!");
}
}
System.out.println("测试结束");
System.out.println("===");
long a = random();
long b = random();
long c = random();
long d = random();
System.out.println("a : " + a);
System.out.println("b : " + b);
System.out.println("c : " + c);
System.out.println("d : " + d);
System.out.println("===");
System.out.println("f1 : " + f1(a, b, c, d, mod));
System.out.println("f2 : " + f2(a, b, c, d, mod));
}
}
42. (必备)对数器打表找规律的技巧
package class042;
public class Code01_AppleMinBags {
public static int bags1(int apple) {
int ans = f(apple);
return ans == Integer.MAX_VALUE ? -1 : ans;
}
public static int f(int rest) {
if (rest < 0) {
return Integer.MAX_VALUE;
}
if (rest == 0) {
return 0;
}
int p1 = f(rest - 8);
int p2 = f(rest - 6);
p1 += p1 != Integer.MAX_VALUE ? 1 : 0;
p2 += p2 != Integer.MAX_VALUE ? 1 : 0;
return Math.min(p1, p2);
}
public static int bags2(int apple) {
if ((apple & 1) != 0) {
return -1;
}
if (apple < 18) {
if (apple == 0) {
return 0;
}
if (apple == 6 || apple == 8) {
return 1;
}
if (apple == 12 || apple == 14 || apple == 16) {
return 2;
}
return -1;
}
return (apple - 18) / 8 + 3;
}
public static void main(String[] args) {
for (int apple = 0; apple < 100; apple++) {
System.out.println(apple + " : " + bags1(apple));
}
}
}
package class042;
public class Code02_EatGrass {
public static String win1(int n) {
return f(n, "A");
}
public static String f(int rest, String cur) {
String enemy = cur.equals("A") ? "B" : "A";
if (rest < 5) {
return (rest == 0 || rest == 2) ? enemy : cur;
}
int pick = 1;
while (pick <= rest) {
if (f(rest - pick, enemy).equals(cur)) {
return cur;
}
pick *= 4;
}
return enemy;
}
public static String win2(int n) {
if (n % 5 == 0 || n % 5 == 2) {
return "B";
} else {
return "A";
}
}
public static void main(String[] args) {
for (int i = 0; i <= 50; i++) {
System.out.println(i + " : " + win1(i));
}
}
}
package class042;
public class Code03_IsSumOfConsecutiveNumbers {
public static boolean is1(int num) {
for (int start = 1, sum; start <= num; start++) {
sum = start;
for (int j = start + 1; j <= num; j++) {
if (sum + j > num) {
break;
}
if (sum + j == num) {
return true;
}
sum += j;
}
}
return false;
}
public static boolean is2(int num) {
return (num & (num - 1)) != 0;
}
public static void main(String[] args) {
for (int num = 1; num < 200; num++) {
System.out.println(num + " : " + (is1(num) ? "T" : "F"));
}
}
}
package class042;
public class Code04_RedPalindromeGoodStrings {
public static int num1(int n) {
char[] path = new char[n];
return f(path, 0);
}
public static int f(char[] path, int i) {
if (i == path.length) {
int cnt = 0;
for (int l = 0; l < path.length; l++) {
for (int r = l + 1; r < path.length; r++) {
if (is(path, l, r)) {
cnt++;
}
if (cnt > 1) {
return 0;
}
}
}
return cnt == 1 ? 1 : 0;
} else {
int ans = 0;
path[i] = 'r';
ans += f(path, i + 1);
path[i] = 'e';
ans += f(path, i + 1);
path[i] = 'd';
ans += f(path, i + 1);
return ans;
}
}
public static boolean is(char[] s, int l, int r) {
while (l < r) {
if (s[l] != s[r]) {
return false;
}
l++;
r--;
}
return true;
}
public static int num2(int n) {
if (n == 1) {
return 0;
}
if (n == 2) {
return 3;
}
if (n == 3) {
return 18;
}
return (int) (((long) 6 * (n + 1)) % 1000000007);
}
public static void main(String[] args) {
for (int i = 1; i <= 10; i++) {
System.out.println("长度为" + i + ", 答案:" + num1(i));
}
}
}
43. (必备)根据数据量猜解法的技巧-天字第一号重要技巧
package class043;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
public class Code01_KillMonsterEverySkillUseOnce {
public static int MAXN = 11;
public static int[] kill = new int[MAXN];
public static int[] blood = new int[MAXN];
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StreamTokenizer in = new StreamTokenizer(br);
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
while (in.nextToken() != StreamTokenizer.TT_EOF) {
int t = (int) in.nval;
for (int i = 0; i < t; i++) {
in.nextToken();
int n = (int) in.nval;
in.nextToken();
int m = (int) in.nval;
for (int j = 0; j < n; j++) {
in.nextToken();
kill[j] = (int) in.nval;
in.nextToken();
blood[j] = (int) in.nval;
}
int ans = f(n, 0, m);
out.println(ans == Integer.MAX_VALUE ? -1 : ans);
}
}
out.flush();
br.close();
out.close();
}
public static int f(int n, int i, int r) {
if (r <= 0) {
return i;
}
if (i == n) {
return Integer.MAX_VALUE;
}
int ans = Integer.MAX_VALUE;
for (int j = i; j < n; j++) {
swap(i, j);
ans = Math.min(ans, f(n, i + 1, r - (r > blood[i] ? kill[i] : kill[i] * 2)));
swap(i, j);
}
return ans;
}
public static void swap(int i, int j) {
int tmp = kill[i];
kill[i] = kill[j];
kill[j] = tmp;
tmp = blood[i];
blood[i] = blood[j];
blood[j] = tmp;
}
}
package class043;
import java.util.ArrayList;
import java.util.List;
public class Code02_SuperPalindromes {
public static int superpalindromesInRange1(String left, String right) {
long l = Long.valueOf(left);
long r = Long.valueOf(right);
long limit = (long) Math.sqrt((double) r);
long seed = 1;
long num = 0;
int ans = 0;
do {
num = evenEnlarge(seed);
if (check(num * num, l, r)) {
ans++;
}
num = oddEnlarge(seed);
if (check(num * num, l, r)) {
ans++;
}
seed++;
} while (num < limit);
return ans;
}
public static long evenEnlarge(long seed) {
long ans = seed;
while (seed != 0) {
ans = ans * 10 + seed % 10;
seed /= 10;
}
return ans;
}
public static long oddEnlarge(long seed) {
long ans = seed;
seed /= 10;
while (seed != 0) {
ans = ans * 10 + seed % 10;
seed /= 10;
}
return ans;
}
public static boolean check(long ans, long l, long r) {
return ans >= l && ans <= r && isPalindrome(ans);
}
public static boolean isPalindrome(long num) {
long offset = 1;
while (num / offset >= 10) {
offset *= 10;
}
while (num != 0) {
if (num / offset != num % 10) {
return false;
}
num = (num % offset) / 10;
offset /= 100;
}
return true;
}
public static int superpalindromesInRange2(String left, String right) {
long l = Long.parseLong(left);
long r = Long.parseLong(right);
int i = 0;
for (; i < record.length; i++) {
if (record[i] >= l) {
break;
}
}
int j = record.length - 1;
for (; j >= 0; j--) {
if (record[j] <= r) {
break;
}
}
return j - i + 1;
}
public static long[] record = new long[] {
1L,
4L,
9L,
121L,
484L,
10201L,
12321L,
14641L,
40804L,
44944L,
1002001L,
1234321L,
4008004L,
100020001L,
102030201L,
104060401L,
121242121L,
123454321L,
125686521L,
400080004L,
404090404L,
10000200001L,
10221412201L,
12102420121L,
12345654321L,
40000800004L,
1000002000001L,
1002003002001L,
1004006004001L,
1020304030201L,
1022325232201L,
1024348434201L,
1210024200121L,
1212225222121L,
1214428244121L,
1232346432321L,
1234567654321L,
4000008000004L,
4004009004004L,
100000020000001L,
100220141022001L,
102012040210201L,
102234363432201L,
121000242000121L,
121242363242121L,
123212464212321L,
123456787654321L,
400000080000004L,
10000000200000001L,
10002000300020001L,
10004000600040001L,
10020210401202001L,
10022212521222001L,
10024214841242001L,
10201020402010201L,
10203040504030201L,
10205060806050201L,
10221432623412201L,
10223454745432201L,
12100002420000121L,
12102202520220121L,
12104402820440121L,
12122232623222121L,
12124434743442121L,
12321024642012321L,
12323244744232321L,
12343456865434321L,
12345678987654321L,
40000000800000004L,
40004000900040004L,
1000000002000000001L,
1000220014100220001L,
1002003004003002001L,
1002223236323222001L,
1020100204020010201L,
1020322416142230201L,
1022123226223212201L,
1022345658565432201L,
1210000024200000121L,
1210242036302420121L,
1212203226223022121L,
1212445458545442121L,
1232100246420012321L,
1232344458544432321L,
1234323468643234321L,
4000000008000000004L
};
public static List<Long> collect() {
long l = 1;
long r = Long.MAX_VALUE;
long limit = (long) Math.sqrt((double) r);
long seed = 1;
long enlarge = 0;
ArrayList<Long> ans = new ArrayList<>();
do {
enlarge = evenEnlarge(seed);
if (check(enlarge * enlarge, l, r)) {
ans.add(enlarge * enlarge);
}
enlarge = oddEnlarge(seed);
if (check(enlarge * enlarge, l, r)) {
ans.add(enlarge * enlarge);
}
seed++;
} while (enlarge < limit);
ans.sort((a, b) -> a.compareTo(b));
return ans;
}
public static void main(String[] args) {
List<Long> ans = collect();
for (long p : ans) {
System.out.println(p + "L,");
}
System.out.println("size : " + ans.size());
}
}
package class043;
public class Code03_IsPalindrome {
public static boolean isPalindrome(int num) {
if (num < 0) {
return false;
}
int offset = 1;
while (num / offset >= 10) {
offset *= 10;
}
while (num != 0) {
if (num / offset != num % 10) {
return false;
}
num = (num % offset) / 10;
offset /= 100;
}
return true;
}
}
44. (必备)前缀树原理与代码详解
package class044;
import java.util.HashMap;
public class Code01_TrieTree {
class Trie1 {
class TrieNode {
public int pass;
public int end;
public TrieNode[] nexts;
public TrieNode() {
pass = 0;
end = 0;
nexts = new TrieNode[26];
}
}
private TrieNode root;
public Trie1() {
root = new TrieNode();
}
public void insert(String word) {
TrieNode node = root;
node.pass++;
for (int i = 0, path; i < word.length(); i++) {
path = word.charAt(i) - 'a';
if (node.nexts[path] == null) {
node.nexts[path] = new TrieNode();
}
node = node.nexts[path];
node.pass++;
}
node.end++;
}
public void erase(String word) {
if (countWordsEqualTo(word) > 0) {
TrieNode node = root;
node.pass--;
for (int i = 0, path; i < word.length(); i++) {
path = word.charAt(i) - 'a';
if (--node.nexts[path].pass == 0) {
node.nexts[path] = null;
return;
}
node = node.nexts[path];
}
node.end--;
}
}
public int countWordsEqualTo(String word) {
TrieNode node = root;
for (int i = 0, path; i < word.length(); i++) {
path = word.charAt(i) - 'a';
if (node.nexts[path] == null) {
return 0;
}
node = node.nexts[path];
}
return node.end;
}
public int countWordsStartingWith(String pre) {
TrieNode node = root;
for (int i = 0, path; i < pre.length(); i++) {
path = pre.charAt(i) - 'a';
if (node.nexts[path] == null) {
return 0;
}
node = node.nexts[path];
}
return node.pass;
}
}
class Trie2 {
class TrieNode {
public int pass;
public int end;
HashMap<Integer, TrieNode> nexts;
public TrieNode() {
pass = 0;
end = 0;
nexts = new HashMap<>();
}
}
private TrieNode root;
public Trie2() {
root = new TrieNode();
}
public void insert(String word) {
TrieNode node = root;
node.pass++;
for (int i = 0, path; i < word.length(); i++) {
path = word.charAt(i);
if (!node.nexts.containsKey(path)) {
node.nexts.put(path, new TrieNode());
}
node = node.nexts.get(path);
node.pass++;
}
node.end++;
}
public void erase(String word) {
if (countWordsEqualTo(word) > 0) {
TrieNode node = root;
TrieNode next;
node.pass--;
for (int i = 0, path; i < word.length(); i++) {
path = word.charAt(i);
next = node.nexts.get(path);
if (--next.pass == 0) {
node.nexts.remove(path);
return;
}
node = next;
}
node.end--;
}
}
public int countWordsEqualTo(String word) {
TrieNode node = root;
for (int i = 0, path; i < word.length(); i++) {
path = word.charAt(i);
if (!node.nexts.containsKey(path)) {
return 0;
}
node = node.nexts.get(path);
}
return node.end;
}
public int countWordsStartingWith(String pre) {
TrieNode node = root;
for (int i = 0, path; i < pre.length(); i++) {
path = pre.charAt(i);
if (!node.nexts.containsKey(path)) {
return 0;
}
node = node.nexts.get(path);
}
return node.pass;
}
}
}
package class044;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;
public class Code02_TrieTree {
public static int MAXN = 150001;
public static int[][] tree = new int[MAXN][26];
public static int[] end = new int[MAXN];
public static int[] pass = new int[MAXN];
public static int cnt;
public static void build() {
cnt = 1;
}
public static void insert(String word) {
int cur = 1;
pass[cur]++;
for (int i = 0, path; i < word.length(); i++) {
path = word.charAt(i) - 'a';
if (tree[cur][path] == 0) {
tree[cur][path] = ++cnt;
}
cur = tree[cur][path];
pass[cur]++;
}
end[cur]++;
}
public static int search(String word) {
int cur = 1;
for (int i = 0, path; i < word.length(); i++) {
path = word.charAt(i) - 'a';
if (tree[cur][path] == 0) {
return 0;
}
cur = tree[cur][path];
}
return end[cur];
}
public static int prefixNumber(String pre) {
int cur = 1;
for (int i = 0, path; i < pre.length(); i++) {
path = pre.charAt(i) - 'a';
if (tree[cur][path] == 0) {
return 0;
}
cur = tree[cur][path];
}
return pass[cur];
}
public static void delete(String word) {
if (search(word) > 0) {
int cur = 1;
for (int i = 0, path; i < word.length(); i++) {
path = word.charAt(i) - 'a';
if (--pass[tree[cur][path]] == 0) {
tree[cur][path] = 0;
return;
}
cur = tree[cur][path];
}
end[cur]--;
}
}
public static void clear() {
for (int i = 1; i <= cnt; i++) {
Arrays.fill(tree[i], 0);
end[i] = 0;
pass[i] = 0;
}
}
public static int m, op;
public static String[] splits;
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
String line = null;
while ((line = in.readLine()) != null) {
build();
m = Integer.valueOf(line);
for (int i = 1; i <= m; i++) {
splits = in.readLine().split(" ");
op = Integer.valueOf(splits[0]);
if (op == 1) {
insert(splits[1]);
} else if (op == 2) {
delete(splits[1]);
} else if (op == 3) {
out.println(search(splits[1]) > 0 ? "YES" : "NO");
} else if (op == 4) {
out.println(prefixNumber(splits[1]));
}
}
clear();
}
out.flush();
in.close();
out.close();
}
}
45. (必备)前缀树的相关题目
package class045;
import java.util.Arrays;
public class Code01_CountConsistentKeys {
public static int[] countConsistentKeys(int[][] b, int[][] a) {
build();
StringBuilder builder = new StringBuilder();
for (int[] nums : a) {
builder.setLength(0);
for (int i = 1; i < nums.length; i++) {
builder.append(String.valueOf(nums[i] - nums[i - 1]) + "#");
}
insert(builder.toString());
}
int[] ans = new int[b.length];
for (int i = 0; i < b.length; i++) {
builder.setLength(0);
int[] nums = b[i];
for (int j = 1; j < nums.length; j++) {
builder.append(String.valueOf(nums[j] - nums[j - 1]) + "#");
}
ans[i] = count(builder.toString());
}
clear();
return ans;
}
public static int MAXN = 2000001;
public static int[][] tree = new int[MAXN][12];
public static int[] pass = new int[MAXN];
public static int cnt;
public static void build() {
cnt = 1;
}
public static int path(char cha) {
if (cha == '#') {
return 10;
} else if (cha == '-') {
return 11;
} else {
return cha - '0';
}
}
public static void insert(String word) {
int cur = 1;
pass[cur]++;
for (int i = 0, path; i < word.length(); i++) {
path = path(word.charAt(i));
if (tree[cur][path] == 0) {
tree[cur][path] = ++cnt;
}
cur = tree[cur][path];
pass[cur]++;
}
}
public static int count(String pre) {
int cur = 1;
for (int i = 0, path; i < pre.length(); i++) {
path = path(pre.charAt(i));
if (tree[cur][path] == 0) {
return 0;
}
cur = tree[cur][path];
}
return pass[cur];
}
public static void clear() {
for (int i = 1; i <= cnt; i++) {
Arrays.fill(tree[i], 0);
pass[i] = 0;
}
}
}
package class045;
import java.util.HashSet;
public class Code02_TwoNumbersMaximumXor {
public static int findMaximumXOR1(int[] nums) {
build(nums);
int ans = 0;
for (int num : nums) {
ans = Math.max(ans, maxXor(num));
}
clear();
return ans;
}
public static int MAXN = 3000001;
public static int[][] tree = new int[MAXN][2];
public static int cnt;
public static int high;
public static void build(int[] nums) {
cnt = 1;
int max = Integer.MIN_VALUE;
for (int num : nums) {
max = Math.max(num, max);
}
high = 31 - Integer.numberOfLeadingZeros(max);
for (int num : nums) {
insert(num);
}
}
public static void insert(int num) {
int cur = 1;
for (int i = high, path; i >= 0; i--) {
path = (num >> i) & 1;
if (tree[cur][path] == 0) {
tree[cur][path] = ++cnt;
}
cur = tree[cur][path];
}
}
public static int maxXor(int num) {
int ans = 0;
int cur = 1;
for (int i = high, status, want; i >= 0; i--) {
status = (num >> i) & 1;
want = status ^ 1;
if (tree[cur][want] == 0) {
want ^= 1;
}
ans |= (status ^ want) << i;
cur = tree[cur][want];
}
return ans;
}
public static void clear() {
for (int i = 1; i <= cnt; i++) {
tree[i][0] = tree[i][1] = 0;
}
}
public int findMaximumXOR2(int[] nums) {
int max = Integer.MIN_VALUE;
for (int num : nums) {
max = Math.max(num, max);
}
int ans = 0;
HashSet<Integer> set = new HashSet<>();
for (int i = 31 - Integer.numberOfLeadingZeros(max); i >= 0; i--) {
int better = ans | (1 << i);
set.clear();
for (int num : nums) {
num = (num >> i) << i;
set.add(num);
if (set.contains(better ^ num)) {
ans = better;
break;
}
}
}
return ans;
}
}
package class045;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Code03_WordSearchII {
public static List<String> findWords(char[][] board, String[] words) {
build(words);
List<String> ans = new ArrayList<>();
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
dfs(board, i, j, 1, ans);
}
}
clear();
return ans;
}
public static int dfs(char[][] board, int i, int j, int t, List<String> ans) {
if (i < 0 || i == board.length || j < 0 || j == board[0].length || board[i][j] == 0) {
return 0;
}
char tmp = board[i][j];
int road = tmp - 'a';
t = tree[t][road];
if (pass[t] == 0) {
return 0;
}
int fix = 0;
if (end[t] != null) {
fix++;
ans.add(end[t]);
end[t] = null;
}
board[i][j] = 0;
fix += dfs(board, i - 1, j, t, ans);
fix += dfs(board, i + 1, j, t, ans);
fix += dfs(board, i, j - 1, t, ans);
fix += dfs(board, i, j + 1, t, ans);
pass[t] -= fix;
board[i][j] = tmp;
return fix;
}
public static int MAXN = 10001;
public static int[][] tree = new int[MAXN][26];
public static int[] pass = new int[MAXN];
public static String[] end = new String[MAXN];
public static int cnt;
public static void build(String[] words) {
cnt = 1;
for (String word : words) {
int cur = 1;
pass[cur]++;
for (int i = 0, path; i < word.length(); i++) {
path = word.charAt(i) - 'a';
if (tree[cur][path] == 0) {
tree[cur][path] = ++cnt;
}
cur = tree[cur][path];
pass[cur]++;
}
end[cur] = word;
}
}
public static void clear() {
for (int i = 1; i <= cnt; i++) {
Arrays.fill(tree[i], 0);
pass[i] = 0;
end[i] = null;
}
}
}
46. (必备)构建前缀数量信息的技巧-解决子数组相关问题
package class046;
public class Code01_PrefixSumArray {
class NumArray {
public int[] sum;
public NumArray(int[] nums) {
sum = new int[nums.length + 1];
for (int i = 1; i <= nums.length; i++) {
sum[i] = sum[i - 1] + nums[i - 1];
}
}
public int sumRange(int left, int right) {
return sum[right + 1] - sum[left];
}
}
}
package class046;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.HashMap;
public class Code02_LongestSubarraySumEqualsAim {
public static int MAXN = 100001;
public static int[] arr = new int[MAXN];
public static int n, aim;
public static HashMap<Integer, Integer> map = new HashMap<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StreamTokenizer in = new StreamTokenizer(br);
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
while (in.nextToken() != StreamTokenizer.TT_EOF) {
n = (int) in.nval;
in.nextToken();
aim = (int) in.nval;
for (int i = 0; i < n; i++) {
in.nextToken();
arr[i] = (int) in.nval;
}
out.println(compute());
}
out.flush();
out.close();
br.close();
}
public static int compute() {
map.clear();
map.put(0, -1);
int ans = 0;
for (int i = 0, sum = 0; i < n; i++) {
sum += arr[i];
if (map.containsKey(sum - aim)) {
ans = Math.max(ans, i - map.get(sum - aim));
}
if (!map.containsKey(sum)) {
map.put(sum, i);
}
}
return ans;
}
}
package class046;
import java.util.HashMap;
public class Code03_NumberOfSubarraySumEqualsAim {
public static int subarraySum(int[] nums, int aim) {
HashMap<Integer, Integer> map = new HashMap<>();
map.put(0, 1);
int ans = 0;
for (int i = 0, sum = 0; i < nums.length; i++) {
sum += nums[i];
ans += map.getOrDefault(sum - aim, 0);
map.put(sum, map.getOrDefault(sum, 0) + 1);
}
return ans;
}
}
package class046;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.HashMap;
public class Code04_PositivesEqualsNegtivesLongestSubarray {
public static int MAXN = 100001;
public static int[] arr = new int[MAXN];
public static int n;
public static HashMap<Integer, Integer> map = new HashMap<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StreamTokenizer in = new StreamTokenizer(br);
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
while (in.nextToken() != StreamTokenizer.TT_EOF) {
n = (int) in.nval;
for (int i = 0, num; i < n; i++) {
in.nextToken();
num = (int) in.nval;
arr[i] = num != 0 ? (num > 0 ? 1 : -1) : 0;
}
out.println(compute());
}
out.flush();
out.close();
br.close();
}
public static int compute() {
map.clear();
map.put(0, -1);
int ans = 0;
for (int i = 0, sum = 0; i < n; i++) {
sum += arr[i];
if (map.containsKey(sum)) {
ans = Math.max(ans, i - map.get(sum));
} else {
map.put(sum, i);
}
}
return ans;
}
}
package class046;
import java.util.HashMap;
public class Code05_LongestWellPerformingInterval {
public static int longestWPI(int[] hours) {
HashMap<Integer, Integer> map = new HashMap<>();
map.put(0, -1);
int ans = 0;
for (int i = 0, sum = 0; i < hours.length; i++) {
sum += hours[i] > 8 ? 1 : -1;
if (sum > 0) {
ans = i + 1;
} else {
if (map.containsKey(sum - 1)) {
ans = Math.max(ans, i - map.get(sum - 1));
}
}
if (!map.containsKey(sum)) {
map.put(sum, i);
}
}
return ans;
}
}
package class046;
import java.util.HashMap;
public class Code06_MakeSumDivisibleByP {
public static int minSubarray(int[] nums, int p) {
int mod = 0;
for (int num : nums) {
mod = (mod + num) % p;
}
if (mod == 0) {
return 0;
}
HashMap<Integer, Integer> map = new HashMap<>();
map.put(0, -1);
int ans = Integer.MAX_VALUE;
for (int i = 0, cur = 0, find; i < nums.length; i++) {
cur = (cur + nums[i]) % p;
find = cur >= mod ? (cur - mod) : (cur + p - mod);
if (map.containsKey(find)) {
ans = Math.min(ans, i - map.get(find));
}
map.put(cur, i);
}
return ans == nums.length ? -1 : ans;
}
}
package class046;
import java.util.Arrays;
public class Code07_EvenCountsLongestSubarray {
public static int findTheLongestSubstring(String s) {
int n = s.length();
int[] map = new int[32];
Arrays.fill(map, -2);
map[0] = -1;
int ans = 0;
for (int i = 0, status = 0, m; i < n; i++) {
m = move(s.charAt(i));
if (m != -1) {
status ^= 1 << m;
}
if (map[status] != -2) {
ans = Math.max(ans, i - map[status]);
} else {
map[status] = i;
}
}
return ans;
}
public static int move(char cha) {
switch (cha) {
case 'a': return 0;
case 'e': return 1;
case 'i': return 2;
case 'o': return 3;
case 'u': return 4;
default: return -1;
}
}
}