modify code

master
algorithmzuo 2 years ago
parent 6ac967d999
commit 0dfd08357a

@ -1,224 +0,0 @@
package class001;
import java.util.ArrayList;
public class Code01_PosArrayToBST {
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int v) {
value = v;
}
}
public static Node posArrayToBST1(int[] posArr) {
// 0~N-1
return process1(posArr, 0, posArr.length - 1);
}
// 目前我们在使用posArr[L..R]这些数字,来建树
// 建出的每一个节点都连好,然后把整棵树的头节点返回
public static Node process1(int[] posArr, int L, int R) {
if (L > R) {
return null;
}
Node head = new Node(posArr[R]);
if (L == R) {
return head;
}
int M = L - 1;
for (int i = L; i < R; i++) { // i -> L..R-1
if (posArr[i] < posArr[R]) {
M = i;
}
}
head.left = process1(posArr, L, M);
head.right = process1(posArr, M + 1, R - 1);
return head;
}
public static Node process3(int[] posArr, int L, int R) {
Node head = new Node(posArr[R]);
if (L == R) {
return head;
}
int M = -1;
for (int i = L; i < R; i++) { // i -> L..R-1
if (posArr[i] < posArr[R]) {
M = i;
}
}
// >
if(M==-1) {
head.right = process3(posArr, L, R - 1);
}else if(M == R-1) {
head.left = process3(posArr, L, R - 1);
}else {
head.left = process3(posArr, L, M);
head.right = process3(posArr, M + 1, R - 1);
}
return head;
}
public static Node posArrayToBST2(int[] posArr) {
return process2(posArr, 0, posArr.length - 1);
}
public static Node process2(int[] posArr, int L, int R) {
if (L > R) {
return null;
}
Node head = new Node(posArr[R]);
if (L == R) {
return head;
}
int M = L - 1;
int left = L;
int right = R - 1;
while (left <= right) {
int mid = left + ((right - left) >> 1);
if (posArr[mid] < posArr[R]) {
M = mid;
left = mid + 1;
} else {
right = mid - 1;
}
}
head.left = process2(posArr, L, M);
head.right = process2(posArr, M + 1, R - 1);
return head;
}
// for test
public static int[] getBstPosArray(Node head) {
ArrayList<Integer> posList = new ArrayList<>();
pos(head, posList);
int[] ans = new int[posList.size()];
for (int i = 0; i < ans.length; i++) {
ans[i] = posList.get(i);
}
return ans;
}
// for test
public static void pos(Node head, ArrayList<Integer> posList) {
if (head != null) {
pos(head.left, posList);
pos(head.right, posList);
posList.add(head.value);
}
}
// for test [0~1000]
// N
public static Node generateRandomBST(int min, int max, int N) {
if (min > max) {
return null;
}
return createTree(min, max, 1, N);
}
// for test
public static Node createTree(int min, int max, int level, int N) {
if (min > max || level > N) {
return null;
}
Node head = new Node(random(min, max));
head.left = createTree(min, head.value - 1, level + 1, N);
head.right = createTree(head.value + 1, max, level + 1, N);
return head;
}
// for test
public static int random(int min, int max) {
return min + (int) (Math.random() * (max - min + 1));
}
// for test
public static boolean isSameValueStructure(Node head1, Node head2) {
if (head1 == null && head2 != null) {
return false;
}
if (head1 != null && head2 == null) {
return false;
}
if (head1 == null && head2 == null) {
return true;
}
return head1.value == head2.value && isSameValueStructure(head1.left, head2.left)
&& isSameValueStructure(head1.right, head2.right);
}
// for test
public static void printTree(Node head) {
System.out.println("Binary Tree:");
printInOrder(head, 0, "H", 17);
System.out.println();
}
// for test
public static void printInOrder(Node head, int height, String to, int len) {
if (head == null) {
return;
}
printInOrder(head.right, height + 1, "v", len);
String val = to + head.value + to;
int lenM = val.length();
int lenL = (len - lenM) / 2;
int lenR = len - lenM - lenL;
val = getSpace(lenL) + val + getSpace(lenR);
System.out.println(getSpace(height * len) + val);
printInOrder(head.left, height + 1, "^", len);
}
// for test
public static String getSpace(int num) {
String space = " ";
StringBuffer buf = new StringBuffer("");
for (int i = 0; i < num; i++) {
buf.append(space);
}
return buf.toString();
}
// for test
public static void main(String[] args) {
int min = 0;
int max = 12;
int level = 4;
Node head = generateRandomBST(min, max, level);
int[] pos = getBstPosArray(head);
printTree(head);
printTree(posArrayToBST1(pos));
printTree(posArrayToBST2(pos));
System.out.println(isSameValueStructure(head, posArrayToBST1(pos)));
System.out.println(isSameValueStructure(head, posArrayToBST2(pos)));
int testTimes = 5000000;
System.out.println("test begin, time time : " + testTimes);
for (int i = 0; i < testTimes; i++) {
head = generateRandomBST(min, max, level);
pos = getBstPosArray(head);
if (!isSameValueStructure(head, posArrayToBST1(pos)) || !isSameValueStructure(head, posArrayToBST2(pos))) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,115 +0,0 @@
package class001;
import java.util.Arrays;
public class Code02_ContainAllCharExactly {
public static int containExactly1(String s, String a) {
if (s == null || a == null || s.length() < a.length()) {
return -1;
}
char[] aim = a.toCharArray();
Arrays.sort(aim);
String aimSort = String.valueOf(aim);
for (int L = 0; L < s.length(); L++) {
for (int R = L; R < s.length(); R++) {
char[] cur = s.substring(L, R + 1).toCharArray();
Arrays.sort(cur);
String curSort = String.valueOf(cur);
if (curSort.equals(aimSort)) {
return L;
}
}
}
return -1;
}
public static int containExactly2(String s, String a) {
if (s == null || a == null || s.length() < a.length()) {
return -1;
}
char[] str = s.toCharArray();
char[] aim = a.toCharArray();
for (int L = 0; L <= str.length - aim.length; L++) {
if (isCountEqual(str, L, aim)) {
return L;
}
}
return -1;
}
public static boolean isCountEqual(char[] str, int L, char[] aim) {
int[] count = new int[256];
for (int i = 0; i < aim.length; i++) {
count[aim[i]]++;
}
for (int i = 0; i < aim.length; i++) {
if (count[str[L + i]]-- == 0) {
return false;
}
}
return true;
}
public static int containExactly3(String s, String a) {
if (s == null || a == null || s.length() < a.length()) {
return -1;
}
char[] aim = a.toCharArray();
int[] count = new int[256];
for (int i = 0; i < aim.length; i++) {
count[aim[i]]++;
}
int M = aim.length;
char[] str = s.toCharArray();
int inValidTimes = 0;
int R = 0;
for (; R < M; R++) {
if (count[str[R]]-- <= 0) {
inValidTimes++;
}
}
for (; R < str.length; R++) {
if (inValidTimes == 0) {
return R - M;
}
if (count[str[R]]-- <= 0) {
inValidTimes++;
}
if (count[str[R - M]]++ < 0) {
inValidTimes--;
}
}
return inValidTimes == 0 ? R - M : -1;
}
// for test
public static String getRandomString(int possibilities, int maxSize) {
char[] ans = new char[(int) (Math.random() * maxSize) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (char) ((int) (Math.random() * possibilities) + 'a');
}
return String.valueOf(ans);
}
public static void main(String[] args) {
int possibilities = 5;
int strMaxSize = 20;
int aimMaxSize = 5;
int testTimes = 500000;
System.out.println("test begin, test time : " + testTimes);
for (int i = 0; i < testTimes; i++) {
String str = getRandomString(possibilities, strMaxSize);
String aim = getRandomString(possibilities, aimMaxSize);
int ans1 = containExactly1(str, aim);
int ans2 = containExactly2(str, aim);
int ans3 = containExactly3(str, aim);
if (ans1 != ans2 || ans2 != ans3) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,50 +0,0 @@
package class002;
public class Code01_MakeNo {
public static int[] makeNo(int size) {
if (size == 1) {
return new int[] { 1 };
}
int halfSize = (size + 1) / 2;
int[] base = makeNo(halfSize);
int[] ans = new int[size];
int index = 0;
for (; index < halfSize; index++) {
ans[index] = base[index] * 2 + 1;
}
for (int i = 0; index < size; index++, i++) {
ans[index] = base[i] * 2;
}
return ans;
}
// 检验函数
public static boolean isValid(int[] arr) {
int N = arr.length;
for (int i = 0; i < N; i++) {
for (int k = i + 1; k < N; k++) {
for (int j = k + 1; j < N; j++) {
if (arr[i] + arr[j] == 2 * arr[k]) {
return false;
}
}
}
}
return true;
}
public static void main(String[] args) {
System.out.println("test begin");
for (int N = 1; N < 1000; N++) {
int[] arr = makeNo(N);
if (!isValid(arr)) {
System.out.println("Oops!");
}
}
System.out.println("test end");
System.out.println(isValid(makeNo(1042)));
System.out.println(isValid(makeNo(2981)));
}
}

@ -1,214 +0,0 @@
package class002;
import java.util.Arrays;
import java.util.Comparator;
public class Code02_KthMinPair {
public static class Pair {
public int x;
public int y;
Pair(int x, int y) {
this.x = x;
this.y = y;
}
}
public static class PairComparator implements Comparator<Pair> {
@Override
public int compare(Pair arg0, Pair arg1) {
return arg0.x != arg1.x ? arg0.x - arg1.x : arg0.y - arg1.y;
}
}
// O(N^2 * log (N^2))的复杂度,你肯定过不了
// 返回的int[] 长度是2{3,1} int[2] = [3,1]
public static int[] kthMinPair1(int[] arr, int k) {
int N = arr.length;
if (k > N * N) {
return null;
}
Pair[] pairs = new Pair[N * N];
int index = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
pairs[index++] = new Pair(arr[i], arr[j]);
}
}
Arrays.sort(pairs, new PairComparator());
return new int[] { pairs[k - 1].x, pairs[k - 1].y };
}
// O(N*logN)的复杂度,你肯定过了
public static int[] kthMinPair2(int[] arr, int k) {
int N = arr.length;
if (k > N * N) {
return null;
}
// O(N*logN)
Arrays.sort(arr);
// 第K小的数值对第一维数字是什么 是arr中
int fristNum = arr[(k - 1) / N];
int lessFristNumSize = 0;// 数出比fristNum小的数有几个
int fristNumSize = 0; // 数出==fristNum的数有几个
// <= fristNum
for (int i = 0; i < N && arr[i] <= fristNum; i++) {
if (arr[i] < fristNum) {
lessFristNumSize++;
} else {
fristNumSize++;
}
}
int rest = k - (lessFristNumSize * N);
return new int[] { fristNum, arr[(rest - 1) / fristNumSize] };
}
// O(N)的复杂度,你肯定蒙了
public static int[] kthMinPair3(int[] arr, int k) {
int N = arr.length;
if (k > N * N) {
return null;
}
// 在无序数组中找到第K小的数返回值
// 第K小以1作为开始
int fristNum = getMinKthByBFPRT(arr, ((k - 1) / N) + 1);
int lessFristNumSize = 0;
int fristNumSize = 0;
for (int i = 0; i < N; i++) {
if (arr[i] < fristNum) {
lessFristNumSize++;
}
if (arr[i] == fristNum) {
fristNumSize++;
}
}
int rest = k - (lessFristNumSize * N);
return new int[] { fristNum, getMinKthByBFPRT(arr, ((rest - 1) / fristNumSize) + 1) };
}
// 利用bfprt算法求解是O(N)的过程
// 在arr上找到第K小的数并返回。K范围是[1,N],范围不是[0,N-1]
// 对你来讲,它可能永远不会被你想起,但确实本题最优解的算法原型
public static int getMinKthByBFPRT(int[] arr, int K) {
return select(arr, 0, arr.length - 1, K - 1);
}
public static int select(int[] arr, int begin, int end, int i) {
if (begin == end) {
return arr[begin];
}
int pivot = medianOfMedians(arr, begin, end);
int[] pivotRange = partition(arr, begin, end, pivot);
if (i >= pivotRange[0] && i <= pivotRange[1]) {
return arr[i];
} else if (i < pivotRange[0]) {
return select(arr, begin, pivotRange[0] - 1, i);
} else {
return select(arr, pivotRange[1] + 1, end, i);
}
}
public static int medianOfMedians(int[] arr, int begin, int end) {
int num = end - begin + 1;
int offset = num % 5 == 0 ? 0 : 1;
int[] mArr = new int[num / 5 + offset];
for (int i = 0; i < mArr.length; i++) {
int beginI = begin + i * 5;
int endI = beginI + 4;
mArr[i] = getMedian(arr, beginI, Math.min(end, endI));
}
return select(mArr, 0, mArr.length - 1, mArr.length / 2);
}
public static int[] partition(int[] arr, int begin, int end, int pivotValue) {
int small = begin - 1;
int cur = begin;
int big = end + 1;
while (cur != big) {
if (arr[cur] < pivotValue) {
swap(arr, ++small, cur++);
} else if (arr[cur] > pivotValue) {
swap(arr, cur, --big);
} else {
cur++;
}
}
int[] range = new int[2];
range[0] = small + 1;
range[1] = big - 1;
return range;
}
public static int getMedian(int[] arr, int begin, int end) {
insertionSort(arr, begin, end);
int sum = end + begin;
int mid = (sum / 2) + (sum % 2);
return arr[mid];
}
public static void insertionSort(int[] arr, int begin, int end) {
for (int i = begin + 1; i != end + 1; i++) {
for (int j = i; j != begin; j--) {
if (arr[j - 1] > arr[j]) {
swap(arr, j - 1, j);
} else {
break;
}
}
}
}
public static void swap(int[] arr, int index1, int index2) {
int tmp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = tmp;
}
// 为了测试,生成值也随机,长度也随机的随机数组
public static int[] getRandomArray(int max, int len) {
int[] arr = new int[(int) (Math.random() * len) + 1];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * max) - (int) (Math.random() * max);
}
return arr;
}
// 为了测试
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// 随机测试了百万组,保证三种方法都是对的
public static void main(String[] args) {
int max = 100;
int len = 30;
int testTimes = 100000;
System.out.println("test bagin, time times : " + testTimes);
for (int i = 0; i < testTimes; i++) {
int[] arr = getRandomArray(max, len);
int[] arr1 = copyArray(arr);
int[] arr2 = copyArray(arr);
int[] arr3 = copyArray(arr);
int N = arr.length * arr.length;
int k = (int) (Math.random() * N) + 1;
int[] ans1 = kthMinPair1(arr1, k);
int[] ans2 = kthMinPair2(arr2, k);
int[] ans3 = kthMinPair3(arr3, k);
if (ans1[0] != ans2[0] || ans2[0] != ans3[0] || ans1[1] != ans2[1] || ans2[1] != ans3[1]) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,77 +0,0 @@
package class003;
public class Code01_LongestNoRepeatSubstring {
/*
* a~zstr
*
*/
public static int lnrs1(String s) {
if (s == null || s.length() == 0) {
return 0;
}
char[] str = s.toCharArray();
int N = str.length;
int max = 0;
for (int i = 0; i < N; i++) {
boolean[] set = new boolean[26];
for (int j = i; j < N; j++) {
if (set[str[j] - 'a']) {
break;
}
set[str[j] - 'a'] = true;
max = Math.max(max, j - i + 1);
}
}
return max;
}
public static int lnrs2(String s) {
if (s == null || s.length() == 0) {
return 0;
}
char[] str = s.toCharArray();
int N = str.length;
int[] last = new int[26];
for (int i = 0; i < 26; i++) {
last[i] = -1;
}
last[str[0] - 'a'] = 0;
int max = 1;
int preMaxLen = 1;
for (int i = 1; i < N; i++) {
preMaxLen = Math.min(i - last[str[i] - 'a'], preMaxLen + 1);
max = Math.max(max, preMaxLen);
last[str[i] - 'a'] = i;
}
return max;
}
// for test
public static String getRandomString(int possibilities, int maxSize) {
char[] ans = new char[(int) (Math.random() * maxSize) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (char) ((int) (Math.random() * possibilities) + 'a');
}
return String.valueOf(ans);
}
public static void main(String[] args) {
int possibilities = 26;
int strMaxSize = 100;
int testTimes = 1000000;
System.out.println("test begin, test time : " + testTimes);
for (int i = 0; i < testTimes; i++) {
String str = getRandomString(possibilities, strMaxSize);
int ans1 = lnrs1(str);
int ans2 = lnrs2(str);
if (ans1 != ans2) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,82 +0,0 @@
package class003;
import java.util.HashSet;
public class Code02_HowManyTypes {
/*
* a~zString[] arr
* baacbabac
* abc arr
*
*/
public static int types1(String[] arr) {
HashSet<String> types = new HashSet<>();
for (String str : arr) {
char[] chs = str.toCharArray();
boolean[] map = new boolean[26];
for (int i = 0; i < chs.length; i++) {
map[chs[i] - 'a'] = true;
}
String key = "";
for (int i = 0; i < 26; i++) {
if (map[i]) {
key += String.valueOf((char) (i + 'a'));
}
}
types.add(key);
}
return types.size();
}
public static int types2(String[] arr) {
HashSet<Integer> types = new HashSet<>();
for (String str : arr) {
char[] chs = str.toCharArray();
int key = 0;
for(int i = 0 ; i < chs.length;i++) {
key |= (1 << (chs[i] - 'a'));
}
types.add(key);
}
return types.size();
}
// for test
public static String[] getRandomStringArray(int possibilities, int strMaxSize, int arrMaxSize) {
String[] ans = new String[(int) (Math.random() * arrMaxSize) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = getRandomString(possibilities, strMaxSize);
}
return ans;
}
// for test
public static String getRandomString(int possibilities, int strMaxSize) {
char[] ans = new char[(int) (Math.random() * strMaxSize) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (char) ((int) (Math.random() * possibilities) + 'a');
}
return String.valueOf(ans);
}
public static void main(String[] args) {
int possibilities = 5;
int strMaxSize = 10;
int arrMaxSize = 100;
int testTimes = 500000;
System.out.println("test begin, test time : " + testTimes);
for (int i = 0; i < testTimes; i++) {
String[] arr = getRandomStringArray(possibilities, strMaxSize, arrMaxSize);
int ans1 = types1(arr);
int ans2 = types2(arr);
if (ans1 != ans2) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,144 +0,0 @@
package class003;
import java.util.HashSet;
import java.util.TreeSet;
public class Code03_SubsquenceMaxModM {
/*
* arrm arr%m
*
*/
public static int max1(int[] arr, int m) {
HashSet<Integer> set = new HashSet<>();
process(arr, 0, 0, set);
int max = 0;
for (Integer sum : set) {
max = Math.max(max, sum % m);
}
return max;
}
public static void process(int[] arr, int index, int sum, HashSet<Integer> set) {
if (index == arr.length) {
set.add(sum);
} else {
process(arr, index + 1, sum, set);
process(arr, index + 1, sum + arr[index], set);
}
}
public static int max2(int[] arr, int m) {
int sum = 0;
int N = arr.length;
for (int i = 0; i < N; i++) {
sum += arr[i];
}
boolean[][] dp = new boolean[N][sum + 1];
for (int i = 0; i < N; i++) {
dp[i][0] = true;
}
dp[0][arr[0]] = true;
for (int i = 1; i < N; i++) {
for (int j = 1; j <= sum; j++) {
dp[i][j] = dp[i - 1][j];
if (j - arr[i] >= 0) {
dp[i][j] = dp[i][j] | dp[i - 1][j - arr[i]];
}
}
}
int ans = 0;
for (int j = 0; j <= sum; j++) {
if (dp[N - 1][j]) {
ans = Math.max(ans, j % m);
}
}
return ans;
}
public static int max3(int[] arr, int m) {
int N = arr.length;
boolean[][] dp = new boolean[N][m];
for (int i = 0; i < N; i++) {
dp[i][0] = true;
}
dp[0][arr[0] % m] = true;
for (int i = 1; i < N; i++) {
for (int j = 1; j < m; j++) {
dp[i][j] = dp[i - 1][j];
int cur = arr[i] % m;
if (j - cur >= 0) {
dp[i][j] = dp[i][j] | dp[i - 1][j - cur];
}
if (m + j - cur < m) {
dp[i][j] = dp[i][j] | dp[i - 1][m + j - cur];
}
}
}
int ans = 0;
for (int i = 0; i < m; i++) {
if (dp[N - 1][i]) {
ans = i;
}
}
return ans;
}
// 如果arr的累加和很大m也很大
// 但是arr的长度相对不大
public static int max4(int[] arr, int m) {
if (arr.length == 1) {
return arr[0] % m;
}
int mid = (arr.length - 1) / 2;
TreeSet<Integer> sortSet1 = new TreeSet<>();
process4(arr, 0, 0, mid, m, sortSet1);
TreeSet<Integer> sortSet2 = new TreeSet<>();
process4(arr, mid + 1, 0, arr.length - 1, m, sortSet2);
int ans = 0;
for (Integer left : sortSet1) {
ans = Math.max(ans, left + sortSet2.floor(m - 1 - left));
}
return ans;
}
public static void process4(int[] arr, int index, int sum, int end, int m, TreeSet<Integer> sortSet) {
if (index == end + 1) {
sortSet.add(sum % m);
} else {
process4(arr, index + 1, sum, end, m, sortSet);
process4(arr, index + 1, sum + arr[index], end, m, sortSet);
}
}
public static int[] generateRandomArray(int len, int value) {
int[] ans = new int[(int) (Math.random() * len) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * value);
}
return ans;
}
public static void main(String[] args) {
int len = 10;
int value = 100;
int m = 76;
int testTime = 500000;
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int[] arr = generateRandomArray(len, value);
int ans1 = max1(arr, m);
int ans2 = max2(arr, m);
int ans3 = max3(arr, m);
int ans4 = max4(arr, m);
if (ans1 != ans2 || ans2 != ans3 || ans3 != ans4) {
System.out.print("Oops!");
}
}
System.out.println("test finish!");
}
}

@ -1,115 +0,0 @@
package class004;
import java.util.ArrayList;
import java.util.HashMap;
public class Code01_QueryHobby {
/*
*
*
* {3, 2, 2, 3, 1}(0, 3, 2)0~322
* arr
*
*/
public static class QueryBox1 {
private int[] arr;
public QueryBox1(int[] array) {
arr = new int[array.length];
for (int i = 0; i < arr.length; i++) {
arr[i] = array[i];
}
}
public int query(int L, int R, int v) {
int ans = 0;
for (; L <= R; L++) {
if (arr[L] == v) {
ans++;
}
}
return ans;
}
}
public static class QueryBox2 {
private HashMap<Integer, ArrayList<Integer>> map;
public QueryBox2(int[] arr) {
map = new HashMap<>();
for (int i = 0; i < arr.length; i++) {
if (!map.containsKey(arr[i])) {
map.put(arr[i], new ArrayList<>());
}
map.get(arr[i]).add(i);
}
}
public int query(int L, int R, int value) {
if (!map.containsKey(value)) {
return 0;
}
ArrayList<Integer> indexArr = map.get(value);
// 查询 < L 的下标有几个
int a = countLess(indexArr, L);
// 查询 < R+1 的下标有几个
int b = countLess(indexArr, R + 1);
return b - a;
}
// 在有序数组arr中用二分的方法数出<limit的数有几个
// 也就是用二分法,找到<limit的数中最右的位置
private int countLess(ArrayList<Integer> arr, int limit) {
int L = 0;
int R = arr.size() - 1;
int mostRight = -1;
while (L <= R) {
int mid = L + ((R - L) >> 1);
if (arr.get(mid) < limit) {
mostRight = mid;
L = mid + 1;
} else {
R = mid - 1;
}
}
return mostRight + 1;
}
}
public static int[] generateRandomArray(int len, int value) {
int[] ans = new int[(int) (Math.random() * len) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * value) + 1;
}
return ans;
}
public static void main(String[] args) {
int len = 300;
int value = 20;
int testTimes = 1000;
int queryTimes = 1000;
System.out.println("test begin");
for (int i = 0; i < testTimes; i++) {
int[] arr = generateRandomArray(len, value);
int N = arr.length;
QueryBox1 box1 = new QueryBox1(arr);
QueryBox2 box2 = new QueryBox2(arr);
for (int j = 0; j < queryTimes; j++) {
int a = (int) (Math.random() * N);
int b = (int) (Math.random() * N);
int L = Math.min(a, b);
int R = Math.max(a, b);
int v = (int) (Math.random() * value) + 1;
if (box1.query(L, R, v) != box2.query(L, R, v)) {
System.out.println("Oops!");
}
}
}
System.out.println("test end");
}
}

@ -1,216 +0,0 @@
package class004;
public class Code02_MergeRecord {
/*
*
*
* powerarrreverse
* arr2powerreverse0~power
* power = 2, arr = {3, 1, 4, 2}reverse = {0, 1, 0, 2}
*
* arr(3,1)(3,2)(4,2)3
* reversearr
* reverse[0] = 0, arr1(20)arr
* [3,1,4,2]3
* reverse[1] = 1, arr2(21)arr
* [1,3,2,4]1
* reverse[2] = 0, arr1(20)arr
* [1,3,2,4]1
* reverse[3] = 2, arr4(22)arr
* [4,2,3,1]4
* [3,1,1,4]
*
*
* power[0,20]
* arr[1,107]
* reverse[1,106]
*
* */
public static int[] reversePair1(int[] originArr, int[] reverseArr, int power) {
int[] ans = new int[reverseArr.length];
for (int i = 0; i < reverseArr.length; i++) {
reverseArray(originArr, 1 << (reverseArr[i]));
ans[i] = countReversePair(originArr);
}
return ans;
}
public static void reverseArray(int[] originArr, int teamSize) {
if (teamSize < 2) {
return;
}
for (int i = 0; i < originArr.length; i += teamSize) {
reversePart(originArr, i, i + teamSize - 1);
}
}
public static void reversePart(int[] arr, int L, int R) {
while (L < R) {
int tmp = arr[L];
arr[L++] = arr[R];
arr[R--] = tmp;
}
}
public static int countReversePair(int[] originArr) {
int ans = 0;
for (int i = 0; i < originArr.length; i++) {
for (int j = i + 1; j < originArr.length; j++) {
if (originArr[i] > originArr[j]) {
ans++;
}
}
}
return ans;
}
public static int[] reversePair2(int[] originArr, int[] reverseArr, int power) {
int[] reverse = copyArray(originArr);
reversePart(reverse, 0, reverse.length - 1);
int[] recordDown = new int[power + 1];
int[] recordUp = new int[power + 1];
process(originArr, 0, originArr.length - 1, power, recordDown);
process(reverse, 0, reverse.length - 1, power, recordUp);
int[] ans = new int[reverseArr.length];
for (int i = 0; i < reverseArr.length; i++) {
int curPower = reverseArr[i];
for (int p = 1; p <= curPower; p++) {
int tmp = recordDown[p];
recordDown[p] = recordUp[p];
recordUp[p] = tmp;
}
for (int p = 1; p <= power; p++) {
ans[i] += recordDown[p];
}
}
return ans;
}
public static void process(int[] originArr, int L, int R, int power, int[] record) {
if (L == R) {
return;
}
int mid = L + ((R - L) >> 1);
process(originArr, L, mid, power - 1, record);
process(originArr, mid + 1, R, power - 1, record);
record[power] += merge(originArr, L, mid, R);
}
public static int merge(int[] arr, int L, int m, int r) {
int[] help = new int[r - L + 1];
int i = 0;
int p1 = L;
int p2 = m + 1;
int ans = 0;
while (p1 <= m && p2 <= r) {
ans += arr[p1] > arr[p2] ? (m - p1 + 1) : 0;
help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= m) {
help[i++] = arr[p1++];
}
while (p2 <= r) {
help[i++] = arr[p2++];
}
for (i = 0; i < help.length; i++) {
arr[L + i] = help[i];
}
return ans;
}
// for test
public static int[] generateRandomOriginArray(int power, int value) {
int[] ans = new int[1 << power];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * value);
}
return ans;
}
// for test
public static int[] generateRandomReverseArray(int len, int power) {
int[] ans = new int[len];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * (power + 1));
}
return ans;
}
// for test
public static void printArray(int[] arr) {
System.out.println("arr size : " + arr.length);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
// for test
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// for test
public static boolean isEqual(int[] arr1, int[] arr2) {
if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
return false;
}
if (arr1 == null && arr2 == null) {
return true;
}
if (arr1.length != arr2.length) {
return false;
}
for (int i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) {
return false;
}
}
return true;
}
public static void main(String[] args) {
int powerMax = 8;
int msizeMax = 10;
int value = 30;
int testTime = 50000;
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int power = (int) (Math.random() * powerMax) + 1;
int msize = (int) (Math.random() * msizeMax) + 1;
int[] originArr = generateRandomOriginArray(power, value);
int[] originArr1 = copyArray(originArr);
int[] originArr2 = copyArray(originArr);
int[] reverseArr = generateRandomReverseArray(msize, power);
int[] reverseArr1 = copyArray(reverseArr);
int[] reverseArr2 = copyArray(reverseArr);
int[] ans1 = reversePair1(originArr1, reverseArr1, power);
int[] ans2 = reversePair2(originArr2, reverseArr2, power);
if (!isEqual(ans1, ans2)) {
System.out.println("Oops!");
}
}
System.out.println("test finish!");
powerMax = 20;
msizeMax = 1000000;
value = 1000;
int[] originArr = generateRandomOriginArray(powerMax, value);
int[] reverseArr = generateRandomReverseArray(msizeMax, powerMax);
// int[] ans1 = reversePair1(originArr1, reverseArr1, powerMax);
long start = System.currentTimeMillis();
reversePair2(originArr, reverseArr, powerMax);
long end = System.currentTimeMillis();
System.out.println("run time : " + (end - start) + " ms");
}
}

@ -1,93 +0,0 @@
package class005;
public class Code01_RotateString {
public static String rotate1(String s, int leftSize) {
if (leftSize <= 0 || leftSize >= s.length()) {
return s;
}
return process1(s.toCharArray(), 0, leftSize - 1, s.length() - 1);
}
public static String process1(char[] str, int L, int M, int R) {
reverse(str, L, M);
reverse(str, M + 1, R);
reverse(str, L, R);
return String.valueOf(str);
}
public static void reverse(char[] str, int L, int R) {
while (L < R) {
char tmp = str[L];
str[L++] = str[R];
str[R--] = tmp;
}
}
public static String rotate2(String s, int leftSize) {
if (leftSize <= 0 || leftSize >= s.length()) {
return s;
}
char[] str = s.toCharArray();
int L = 0;
int R = str.length - 1;
int lpart = leftSize;
int rpart = str.length - leftSize;
int same = Math.min(lpart, rpart);
int diff = lpart - rpart;
exchange(str, L, R, same);
while (diff != 0) {
if (diff > 0) {
L += same;
lpart = diff;
} else {
R -= same;
rpart = -diff;
}
same = Math.min(lpart, rpart);
diff = lpart - rpart;
exchange(str, L, R, same);
}
return String.valueOf(str);
}
public static void exchange(char[] chas, int start, int end, int size) {
int i = end - size + 1;
char tmp = 0;
while (size-- != 0) {
tmp = chas[start];
chas[start] = chas[i];
chas[i] = tmp;
start++;
i++;
}
}
// for test
public static String getRandomString(int possibilities, int strMaxSize) {
char[] ans = new char[(int) (Math.random() * strMaxSize) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (char) ((int) (Math.random() * possibilities) + 'a');
}
return String.valueOf(ans);
}
public static void main(String[] args) {
int possibilities = 5;
int strMaxSize = 10;
int testTimes = 5000000;
System.out.println("test begin, test time : " + testTimes);
for (int i = 0; i < testTimes; i++) {
String str = getRandomString(possibilities, strMaxSize);
int leftSize = (int) (Math.random() * (str.length() + 1));
String ans1 = rotate1(str, leftSize);
String ans2 = rotate2(str, leftSize);
if (!ans1.equals(ans2)) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,237 +0,0 @@
package class005;
public class Code02_RestoreWays {
/*
* arrn(3 <= n <= 10^4)<=200 1. arr[0] <= arr[1] 2.
* arr[n-1] <= arr[n-2] 3. arr[i] <= max(arr[i-1], arr[i+1])
* arrkk0 arr
* [6,0,9] [6,9,9]1
*
*/
public static int ways0(int[] arr) {
return process0(arr, 0);
}
public static int process0(int[] arr, int index) {
if (index == arr.length) {
return isValid(arr) ? 1 : 0;
} else {
if (arr[index] != 0) {
return process0(arr, index + 1);
} else {
int ways = 0;
for (int v = 1; v < 201; v++) {
arr[index] = v;
ways += process0(arr, index + 1);
}
arr[index] = 0;
return ways;
}
}
}
public static boolean isValid(int[] arr) {
if (arr[0] > arr[1]) {
return false;
}
if (arr[arr.length - 1] > arr[arr.length - 2]) {
return false;
}
for (int i = 1; i < arr.length - 1; i++) {
if (arr[i] > Math.max(arr[i - 1], arr[i + 1])) {
return false;
}
}
return true;
}
public static int ways1(int[] arr) {
int N = arr.length;
if (arr[N - 1] != 0) {
return process1(arr, N - 1, arr[N - 1], 2);
} else {
int ways = 0;
for (int v = 1; v < 201; v++) {
ways += process1(arr, N - 1, v, 2);
}
return ways;
}
}
// 如果index位置的数字变成了v,
// 并且arr[index]和arr[index+1]的关系为s
// s==0代表arr[index] < arr[index+1]
// s==1代表arr[index] = arr[index+1]
// s==2代表arr[index] > arr[index+1]
// 返回有多少种转化方式?
public static int process1(int[] arr, int i, int v, int s) {
if (i == 0) {
return ((s == 0 || s == 1) && (arr[i] == 0 || v == arr[i])) ? 1 : 0;
}
if (arr[i] != 0 && v != arr[i]) {
return 0;
}
int ways = 0;
if (s == 0 || s == 1) {
for (int pre = 1; pre < 201; pre++) {
ways += process1(arr, i - 1, pre, pre < v ? 0 : (pre == v ? 1 : 2));
}
} else {
for (int pre = v; pre < 201; pre++) {
ways += process1(arr, i - 1, pre, pre < v ? 0 : (pre == v ? 1 : 2));
}
}
return ways;
}
public static int ways2(int[] arr) {
int N = arr.length;
int[][][] dp = new int[N][201][3];
if (arr[0] != 0) {
dp[0][arr[0]][0] = 1;
dp[0][arr[0]][1] = 1;
} else {
for (int v = 1; v < 201; v++) {
dp[0][v][0] = 1;
dp[0][v][1] = 1;
}
}
for (int i = 1; i < N; i++) {
for (int v = 1; v < 201; v++) {
for (int s = 0; s < 3; s++) {
if (arr[i] == 0 || v == arr[i]) {
if (s == 0 || s == 1) {
// A[i] = dp[i-1][0~v-1][0]
// A[0] = dp[i-1][0][0]
// dp[i-1][1~v-1][0] A[v-1] - A[0]
// dp[i-1][v][1]
// dp[i-1][v+1~200][2]
for (int pre = 1; pre < 201; pre++) {
dp[i][v][s] += dp[i - 1][pre][pre < v ? 0 : (pre == v ? 1 : 2)];
}
} else {
for (int pre = v; pre < 201; pre++) {
dp[i][v][s] += dp[i - 1][pre][pre < v ? 0 : (pre == v ? 1 : 2)];
}
}
}
}
}
}
if (arr[N - 1] != 0) {
return dp[N - 1][arr[N - 1]][2];
} else {
int ways = 0;
for (int v = 1; v < 201; v++) {
ways += dp[N - 1][v][2];
}
return ways;
}
}
public static int ways3(int[] arr) {
int N = arr.length;
int[][][] dp = new int[N][201][3];
if (arr[0] != 0) {
dp[0][arr[0]][0] = 1;
dp[0][arr[0]][1] = 1;
} else {
for (int v = 1; v < 201; v++) {
dp[0][v][0] = 1;
dp[0][v][1] = 1;
}
}
// presum[0~V][0] -> A
// presum[0~V][1] -> B
// presum[0~V][2] -> C
int[][] presum = new int[201][3];
// presum -> dp[0][..][..] 三张表
for (int v = 1; v < 201; v++) {
for (int s = 0; s < 3; s++) {
presum[v][s] = presum[v - 1][s] + dp[0][v][s];
}
}
for (int i = 1; i < N; i++) {
for (int v = 1; v < 201; v++) {
for (int s = 0; s < 3; s++) {
if (arr[i] == 0 || v == arr[i]) {
if (s == 0 || s == 1) {
// dp[i][..][..] -> dp[i-1][..][..]
dp[i][v][s] += sum(1, v - 1, 0, presum);
dp[i][v][s] += dp[i - 1][v][1];
dp[i][v][s] += sum(v + 1, 200, 2, presum);
} else {
dp[i][v][s] += dp[i - 1][v][1];
dp[i][v][s] += sum(v + 1, 200, 2, presum);
}
}
}
}
for (int v = 1; v < 201; v++) {
for (int s = 0; s < 3; s++) {
presum[v][s] = presum[v - 1][s] + dp[i][v][s];
}
}
}
if (arr[N - 1] != 0) {
return dp[N - 1][arr[N - 1]][2];
} else {
return sum(1, 200, 2, presum);
}
}
public static int sum(int begin, int end, int relation, int[][] presum) {
return presum[end][relation] - presum[begin - 1][relation];
}
// for test
public static int[] generateRandomArray(int len) {
int[] ans = new int[(int) (Math.random() * len) + 2];
for (int i = 0; i < ans.length; i++) {
if (Math.random() < 0.5) {
ans[i] = 0;
} else {
ans[i] = (int) (Math.random() * 200) + 1;
}
}
return ans;
}
// for test
public static void printArray(int[] arr) {
System.out.println("arr size : " + arr.length);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int len = 3;
int testTime = 10;
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int[] arr = generateRandomArray(len);
int ans0 = ways0(arr);
int ans1 = ways1(arr);
int ans2 = ways2(arr);
int ans3 = ways3(arr);
if (ans0 != ans1 || ans2 != ans3 || ans0 != ans2) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
int[] arr = generateRandomArray(100000);
System.out.println(arr.length);
long begin = System.currentTimeMillis();
ways3(arr);
long end = System.currentTimeMillis();
System.out.println("run time : " + (end - begin) + " ms");
}
}

@ -1,97 +0,0 @@
package class006;
import java.util.Arrays;
import java.util.HashSet;
public class Code01_Power2Diffs {
/*
* arr0 arr
*
* arrarr
*
*/
// 时间复杂度O(N)额外空间复杂度O(N)
public static int diff1(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
HashSet<Integer> set = new HashSet<>();
for (int cur : arr) {
set.add(cur * cur);
}
return set.size();
}
// 时间复杂度O(N)额外空间复杂度O(1)
public static int diff2(int[] arr) {
int N = arr.length;
int L = 0;
int R = N - 1;
int count = 0;
int leftAbs = 0;
int rightAbs = 0;
while (L <= R) {
count++;
leftAbs = Math.abs(arr[L]);
rightAbs = Math.abs(arr[R]);
if (leftAbs < rightAbs) {
while (R >= 0 && Math.abs(arr[R]) == rightAbs) {
R--;
}
} else if (leftAbs > rightAbs) {
while (L < N && Math.abs(arr[L]) == leftAbs) {
L++;
}
} else {
while (L < N && Math.abs(arr[L]) == leftAbs) {
L++;
}
while (R >= 0 && Math.abs(arr[R]) == rightAbs) {
R--;
}
}
}
return count;
}
// for test
public static int[] randomSortedArray(int len, int value) {
int[] ans = new int[(int) (Math.random() * len) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * value) - (int) (Math.random() * value);
}
Arrays.sort(ans);
return ans;
}
// for test
public static void printArray(int[] arr) {
for (int cur : arr) {
System.out.print(cur + " ");
}
System.out.println();
}
public static void main(String[] args) {
int len = 100;
int value = 500;
int testTimes = 200000;
System.out.println("test begin");
for (int i = 0; i < testTimes; i++) {
int[] arr = randomSortedArray(len, value);
int ans1 = diff1(arr);
int ans2 = diff2(arr);
if (ans1 != ans2) {
printArray(arr);
System.out.println(ans1);
System.out.println(ans2);
System.out.println("Oops!");
break;
}
}
System.out.println("test finish");
}
}

@ -1,121 +0,0 @@
package class006;
public class Code02_Water {
/*
* arrarr
*
*/
public static int water1(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int water = 0;
for (int i = 1; i < N - 1; i++) {
int leftMax = Integer.MIN_VALUE;
for (int j = 0; j < i; j++) {
leftMax = Math.max(leftMax, arr[j]);
}
int rightMax = Integer.MIN_VALUE;
for (int j = i + 1; j < N; j++) {
rightMax = Math.max(rightMax, arr[j]);
}
water += Math.max(Math.min(leftMax, rightMax) - arr[i], 0);
}
return water;
}
public static int water2(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int[] leftMaxs = new int[N];
leftMaxs[0] = arr[0];
for (int i = 1; i < N; i++) {
leftMaxs[i] = Math.max(leftMaxs[i - 1], arr[i]);
}
int[] rightMaxs = new int[N];
rightMaxs[N - 1] = arr[N - 1];
for (int i = N - 2; i >= 0; i--) {
rightMaxs[i] = Math.max(rightMaxs[i + 1], arr[i]);
}
int water = 0;
for (int i = 1; i < N - 1; i++) {
water += Math.max(Math.min(leftMaxs[i - 1], rightMaxs[i + 1]) - arr[i], 0);
}
return water;
}
public static int water3(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int[] rightMaxs = new int[N];
rightMaxs[N - 1] = arr[N - 1];
for (int i = N - 2; i >= 0; i--) {
rightMaxs[i] = Math.max(rightMaxs[i + 1], arr[i]);
}
int water = 0;
int leftMax = arr[0];
for (int i = 1; i < N - 1; i++) {
water += Math.max(Math.min(leftMax, rightMaxs[i + 1]) - arr[i], 0);
leftMax = Math.max(leftMax, arr[i]);
}
return water;
}
public static int water4(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int L = 1;
int leftMax = arr[0];
int R = N - 2;
int rightMax = arr[N - 1];
int water = 0;
while (L <= R) {
if (leftMax <= rightMax) {
water += Math.max(0, leftMax - arr[L]);
leftMax = Math.max(leftMax, arr[L++]);
} else {
water += Math.max(0, rightMax - arr[R]);
rightMax = Math.max(rightMax, arr[R--]);
}
}
return water;
}
// for test
public static int[] generateRandomArray(int len, int value) {
int[] ans = new int[(int) (Math.random() * len) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * value) + 1;
}
return ans;
}
public static void main(String[] args) {
int len = 100;
int value = 200;
int testTimes = 100000;
System.out.println("test begin");
for (int i = 0; i < testTimes; i++) {
int[] arr = generateRandomArray(len, value);
int ans1 = water1(arr);
int ans2 = water2(arr);
int ans3 = water3(arr);
int ans4 = water4(arr);
if (ans1 != ans2 || ans3 != ans4 || ans1 != ans3) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,93 +0,0 @@
package class007;
public class Code01_RandToRand {
// 这个结构是唯一的随机机制
// 你只能初始化并使用,不可修改
public static class RandomBox {
private final int min;
private final int max;
// 初始化时请一定不要让mi==ma
public RandomBox(int mi, int ma) {
min = mi;
max = ma;
}
// 13 ~ 17
// 13 + [0,4]
public int random() {
return min + (int) (Math.random() * (max - min + 1));
}
public int min() {
return min;
}
public int max() {
return max;
}
}
// 利用条件RandomBox如何等概率返回0和1
public static int rand01(RandomBox randomBox) {
int min = randomBox.min();
int max = randomBox.max();
// min ~ max
int size = max - min + 1;
// size是不是奇数odd 奇数
boolean odd = (size & 1) != 0;
int mid = size / 2;
int ans = 0;
do {
ans = randomBox.random() - min;
} while (odd && ans == mid);
return ans < mid ? 0 : 1;
}
// 给你一个RandomBox这是唯一能借助的随机机制
// 等概率返回from~to范围上任何一个数
// 要求from<=to
public static int random(RandomBox randomBox, int from, int to) {
if (from == to) {
return from;
}
// 3 ~ 9
// 0 ~ 6
// 0 ~ range
int range = to - from;
int num = 1;
// 求0range需要几个2进制位
while ((1 << num) - 1 < range) {
num++;
}
// 我们一共需要num位
// 最终的累加和,首先+0位上是1还是01位上是1还是02位上是1还是0...
int ans = 0;
do {
ans = 0;
for (int i = 0; i < num; i++) {
ans |= (rand01(randomBox) << i);
}
} while (ans > range);
return ans + from;
}
public static void main(String[] args) {
RandomBox randomBox = new RandomBox(3, 9);
int from = 17;
int to = 29;
int[] ans = new int[to + 1];
int testTime1 = 1000000;
for (int i = 0; i < testTime1; i++) {
ans[random(randomBox, from, to)]++;
}
for (int i = 0; i < ans.length; i++) {
System.out.println(ans[i]);
}
System.out.println("==========");
}
}

@ -1,46 +0,0 @@
package class007;
public class Code02_EqualProbabilityRandom {
// 这个结构是唯一的随机机制
// 你只能初始化并使用,不可修改
public static class RandomBox {
private final double p;
// 初始化时请一定满足0 < zeroP < 1
public RandomBox(double zeroP) {
p = zeroP;
}
public int random() {
return Math.random() < p ? 0 : 1;
}
}
// 底层依赖一个以p概率返回0以1-p概率返回1的随机函数rand01p
// 如何加工出等概率返回0和1的函数
public static int rand01(RandomBox randomBox) {
int num;
do {
num = randomBox.random();
} while (num == randomBox.random());
return num;
}
public static void main(String[] args) {
double zeroP = 0.88;
RandomBox randomBox = new RandomBox(zeroP);
int testTime = 10000000;
int count = 0;
for (int i = 0; i < testTime; i++) {
if (rand01(randomBox) == 0) {
count++;
}
}
System.out.println((double) count / (double) testTime);
}
}

@ -1,77 +0,0 @@
package class007;
import java.util.HashMap;
import java.util.Map.Entry;
public class Code03_FindHalfMajority {
public static int halfMajor(int[] arr) {
int cand = 0;
int HP = 0;
// 遍历一遍数组arr一次删掉两个不同的数谁会剩下来谁就是cand
for (int i = 0; i != arr.length; i++) {
if (HP == 0) { // 如果没有候选
cand = arr[i];
HP = 1;
} else if (arr[i] == cand) {
HP++;
} else {
HP--;
}
}
if (HP == 0) {
return -1;
}
HP = 0;
for (int i = 0; i != arr.length; i++) {
if (arr[i] == cand) {
HP++;
}
}
return HP > arr.length / 2 ? cand : -1;
}
// for test
public static int right(int[] arr) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int cur : arr) {
if (!map.containsKey(cur)) {
map.put(cur, 0);
}
map.put(cur, map.get(cur) + 1);
}
for (Entry<Integer, Integer> entry : map.entrySet()) {
if (entry.getValue() > arr.length / 2) {
return entry.getKey();
}
}
return -1;
}
// for test
public static int[] genareteRandomArray(int len, int max) {
int[] ans = new int[(int) (Math.random() * len) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * max) + 1;
}
return ans;
}
public static void main(String[] args) {
int len = 100;
int max = 10;
int testTime = 100000;
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int[] arr = genareteRandomArray(len, max);
int ans1 = halfMajor(arr);
int ans2 = right(arr);
if (ans1 != ans2) {
System.out.println("Oops!");
break;
}
}
System.out.println("test end");
}
}

@ -1,135 +0,0 @@
package class007;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
public class Code04_FindKMajor {
public static List<Integer> kMajor(int[] arr, int K) {
List<Integer> ans = new ArrayList<>();
if (K < 2) {
return ans;
}
// 候选表记录数一定是O(K) > N/K k-1
HashMap<Integer, Integer> cands = new HashMap<Integer, Integer>();
for (int i = 0; i != arr.length; i++) {
if (cands.containsKey(arr[i])) {
cands.put(arr[i], cands.get(arr[i]) + 1);
} else {
if (cands.size() == K - 1) {
allCandsMinusOne(cands);
} else {
cands.put(arr[i], 1);
}
}
}
HashMap<Integer, Integer> reals = getReals(arr, cands);
for (Entry<Integer, Integer> set : cands.entrySet()) {
Integer key = set.getKey();
if (reals.get(key) > arr.length / K) {
ans.add(key);
}
}
return ans;
}
public static void allCandsMinusOne(HashMap<Integer, Integer> map) {
List<Integer> removeList = new LinkedList<Integer>();
for (Entry<Integer, Integer> set : map.entrySet()) {
Integer key = set.getKey();
Integer value = set.getValue();
if (value == 1) {
removeList.add(key);
}
map.put(key, value - 1);
}
for (Integer removeKey : removeList) {
map.remove(removeKey);
}
}
// for test
public static List<Integer> right(int[] arr, int K) {
List<Integer> ans = new ArrayList<>();
if (K < 2) {
return ans;
}
HashMap<Integer, Integer> times = new HashMap<>();
for (int num : arr) {
if (!times.containsKey(num)) {
times.put(num, 1);
} else {
times.put(num, times.get(num) + 1);
}
}
for (Entry<Integer, Integer> entry : times.entrySet()) {
if (entry.getValue() > arr.length / K) {
ans.add(entry.getKey());
}
}
return ans;
}
public static HashMap<Integer, Integer> getReals(int[] arr, HashMap<Integer, Integer> cands) {
HashMap<Integer, Integer> reals = new HashMap<Integer, Integer>();
for (int i = 0; i != arr.length; i++) {
int curNum = arr[i];
if (cands.containsKey(curNum)) {
if (reals.containsKey(curNum)) {
reals.put(curNum, reals.get(curNum) + 1);
} else {
reals.put(curNum, 1);
}
}
}
return reals;
}
public static int[] genareteRandomArray(int len, int max) {
int[] ans = new int[(int) (Math.random() * len) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * max) + 1;
}
return ans;
}
public static boolean isEqual(List<Integer> ans1, List<Integer> ans2) {
if (ans1.size() != ans2.size()) {
return false;
}
HashSet<Integer> set1 = new HashSet<>();
for (Integer num : ans1) {
set1.add(num);
}
if (set1.size() != ans1.size()) {
return false;
}
for (Integer num : ans2) {
set1.remove(num);
}
return set1.size() == 0;
}
public static void main(String[] args) {
int len = 100;
int max = 10;
int K = 5;
int testTime = 100000;
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int[] arr = genareteRandomArray(len, max);
List<Integer> ans1 = kMajor(arr, K);
List<Integer> ans2 = right(arr, K);
if (!isEqual(ans1, ans2)) {
System.out.println("Oops!");
break;
}
}
System.out.println("test end");
}
}

@ -1,27 +0,0 @@
package class008;
public class Code01_JumpGameII {
/*
* leetcodeJump Game II
*
*/
public static int jump(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
int jump = 0;
int cur = 0;
int next = 0;
for (int i = 0; i < arr.length; i++) {
if (cur < i) {
jump++;
cur = next;
}
next = Math.max(next, i + arr[i]);
}
return jump;
}
}

@ -1,24 +0,0 @@
package class008;
import java.util.HashMap;
public class Code02_LongestConsecutiveSequence {
public static int longestConsecutive(int[] nums) {
HashMap<Integer, Integer> map = new HashMap<>();
int len = 0;
for (int num : nums) {
if (!map.containsKey(num)) {
map.put(num, 1);
int preLen = map.containsKey(num - 1) ? map.get(num - 1) : 0;
int posLen = map.containsKey(num + 1) ? map.get(num + 1) : 0;
int all = preLen + posLen + 1;
map.put(num - preLen, all);
map.put(num + posLen, all);
len = Math.max(len, all);
}
}
return len;
}
}

@ -1,84 +0,0 @@
package class009;
public class Code01_SetMatrixZeroes {
/*
* leetcodeSet Matrix Zeroes
*
*/
public static void setZeroes1(int[][] matrix) {
boolean row0Zero = false;
boolean col0Zero = false;
int i = 0;
int j = 0;
for (i = 0; i < matrix[0].length; i++) {
if (matrix[0][i] == 0) {
row0Zero = true;
break;
}
}
for (i = 0; i < matrix.length; i++) {
if (matrix[i][0] == 0) {
col0Zero = true;
break;
}
}
// 跳过了所有0行、0列的数据
for (i = 1; i < matrix.length; i++) {
for (j = 1; j < matrix[0].length; j++) {
if (matrix[i][j] == 0) {
matrix[i][0] = 0;
matrix[0][j] = 0;
}
}
}
for (i = 1; i < matrix.length; i++) {
for (j = 1; j < matrix[0].length; j++) {
if (matrix[i][0] == 0 || matrix[0][j] == 0) {
matrix[i][j] = 0;
}
}
}
if (row0Zero) {
for (i = 0; i < matrix[0].length; i++) {
matrix[0][i] = 0;
}
}
if (col0Zero) {
for (i = 0; i < matrix.length; i++) {
matrix[i][0] = 0;
}
}
}
public static void setZeroes2(int[][] matrix) {
boolean col0 = false;
int i = 0;
int j = 0;
for (i = 0; i < matrix.length; i++) {
for (j = 0; j < matrix[0].length; j++) {
if (matrix[i][j] == 0) {
matrix[i][0] = 0;
if (j == 0) {
col0 = true;
} else {
matrix[0][j] = 0;
}
}
}
}
for (i = matrix.length - 1; i >= 0; i--) {
for (j = 1; j < matrix[0].length; j++) {
if (matrix[i][0] == 0 || matrix[0][j] == 0) {
matrix[i][j] = 0;
}
}
}
if (col0) {
for (i = 0; i < matrix.length; i++) {
matrix[i][0] = 0;
}
}
}
}

@ -1,30 +0,0 @@
package class009;
public class Code02_SearchA2DMatrixII {
/*
* leetcodeSearch a 2D Matrix II
*
*/
public static boolean searchMatrix(int[][] m, int target) {
if (m == null || m.length == 0 || m[0] == null || m[0].length == 0) {
return false;
}
int N = m.length;
int M = m[0].length;
int row = 0;
int col = M - 1;
while (row < N && col >= 0) {
if (m[row][col] > target) {
col--;
} else if (m[row][col] < target) {
row++;
} else {
return true;
}
}
return false;
}
}

@ -1,155 +0,0 @@
package class009;
import java.util.ArrayList;
import java.util.List;
public class Code03_LongestOnes {
public static List<Integer> longestOnes1(int[][] matrix) {
int N = matrix.length;
int M = matrix[0].length;
List<Integer> ans = new ArrayList<>();
int maxLen = 0;
for (int i = 0; i < N; i++) { // 每一行的答案i
int j = M; // 最左发现的1的位置
while (j > 0 && matrix[i][j - 1] == 1) {
j--;
}
if (maxLen < M - j) {
maxLen = M - j;
ans.clear();
}
if (maxLen == M - j) {
ans.add(i);
}
}
return ans;
}
public static List<Integer> longestOnes2(int[][] matrix) {
int N = matrix.length;
int M = matrix[0].length;
List<Integer> ans = new ArrayList<>();
int maxLen = 0;
int col = M;
for (int i = 0; i < N; i++) {
while (col > 0 && matrix[i][col - 1] == 1) {
col--;
}
// col来到当前i行最左侧的1的位置
if (maxLen < M - col) {
maxLen = M - col;
ans.clear();
}
if (matrix[i][col] == 1) {
ans.add(i);
}
}
return ans;
}
public static List<Integer> longestOnes3(int[][] matrix) {
int N = matrix.length;
int M = matrix[0].length;
List<Integer> ans = new ArrayList<>();
int maxLen = 0;
for (int i = 0; i < N; i++) {
int j = mostLeftOne(matrix[i], 0, M - 1);
if (maxLen < M - j) {
maxLen = M - j;
ans.clear();
}
if (maxLen == M - j) {
ans.add(i);
}
}
return ans;
}
public static List<Integer> longestOnes4(int[][] matrix) {
int N = matrix.length;
int M = matrix[0].length;
List<Integer> ans = new ArrayList<>();
int maxLen = 0;
int col = M;
for (int i = 0; i < N; i++) {
col = mostLeftOne(matrix[i], 0, col - 1);
if (maxLen < M - col) {
maxLen = M - col;
ans.clear();
}
if (matrix[i][col] == 1) {
ans.add(i);
}
}
return ans;
}
// arr[L..R]上一定有一个前期要么都是0要么都是1如果0和1都有0在左侧1在右侧
public static int mostLeftOne(int[] arr, int L, int R) {
int ans = R + 1; // R + 1 -> [L..R] 没有1的
int M = 0;
while (L <= R) {
M = (L + R) / 2;
if (arr[M] == 1) {
ans = M;
R = M - 1;
} else {
L = M + 1;
}
}
return ans;
}
// for test
// 随机生成一个最大规模达到rowSize * colSize的矩阵
// 确保每一行都是0在左侧1在右侧
public static int[][] generateRandomMatrix(int rowSize, int colSize) {
int N = (int) (Math.random() * rowSize) + 1;
int M = (int) (Math.random() * colSize) + 1;
int[][] matrix = new int[N][M];
for (int i = 0; i < N; i++) {
int[] arr = new int[M];
int rightStart = (int) (Math.random() * M);
for (int j = rightStart; j < M; j++) {
arr[j] = 1;
}
matrix[i] = arr;
}
return matrix;
}
public static boolean equal(List<Integer> ans1, List<Integer> ans2) {
if (ans1.size() != ans2.size()) {
return false;
}
int N = ans1.size();
for (int i = 0; i < N; i++) {
if (!ans1.get(i).equals(ans2.get(i))) {
return false;
}
}
return true;
}
public static void main(String[] args) {
System.out.println("Hello!");
int rowSize = 30;
int colSize = 100;
int testTimes = 300000;
System.out.println("test begin");
for (int i = 0; i < testTimes; i++) {
int[][] matrix = generateRandomMatrix(rowSize, colSize);
List<Integer> ans1 = longestOnes1(matrix);
List<Integer> ans2 = longestOnes2(matrix);
List<Integer> ans3 = longestOnes3(matrix);
List<Integer> ans4 = longestOnes4(matrix);
if (!equal(ans1, ans2) || !equal(ans3, ans4) || !equal(ans1, ans3)) {
System.out.println("Oops");
}
}
System.out.println("test end");
}
}

@ -1,17 +0,0 @@
package class010;
public class Code01_SwapWithoutTmp {
public static void main(String[] args) {
int a = 111;
int b = 111;
System.out.println(a);
System.out.println(b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println(a);
System.out.println(b);
}
}

@ -1,53 +0,0 @@
package class010;
public class Code02_GetMax {
// 请确保n不是0就是1
// 0 -> 1 1 -> 0
public static int flip(int n) {
return n ^ 1;
}
// 如果n是非负数返回1
// 如果n是负数返回0
public static int sign(int n) {
// (n >> 31) & 1 0(int 非负数) 1(int 负数)
// >>> >>
return flip((n >> 31) & 1);
}
// 确保 a-b 是不会溢出的
public static int getMax1(int a, int b) {
int c = a - b;
int scA = sign(c); // scA == 1 a - b >= 0 a返回 sca == 0 a-b < 0 b返回
int scB = flip(scA);
return a * scA + b * scB;
}
public static int getMax2(int a, int b) {
int c = a - b;
int sa = sign(a);
int sb = sign(b);
int sc = sign(c);
int difSab = sa ^ sb;
int sameSab = flip(difSab);
// 返回a的条件 returnA == 1 应该返回a;
// returnA == 0不应该返回a
int returnA = difSab * sa + sameSab * sc;
int returnB = flip(returnA);
return a * returnA + b * returnB;
}
public static void main(String[] args) {
int a = -16;
int b = 1;
System.out.println(getMax1(a, b));
System.out.println(getMax2(a, b));
a = 2147483647;
b = -2147480000;
System.out.println(getMax1(a, b)); // wrong answer because of overflow
System.out.println(getMax2(a, b));
}
}

@ -1,89 +0,0 @@
package class010;
public class Code03_EvenTimesOddTimes {
// arr中只有一种数出现奇数次
public static void printOddTimesNum1(int[] arr) {
int eor = 0;
for (int i = 0; i < arr.length; i++) {
eor ^= arr[i];
}
System.out.println(eor);
}
// arr中有两种数出现奇数次
public static void printOddTimesNum2(int[] arr) {
int eor = 0;
for (int i = 0; i < arr.length; i++) {
eor ^= arr[i];
}
// eor = a ^ b
// eor != 0
// eor必然有一个位置上是1
// 0110010000
// 0000010000
int rightOne = eor & (~eor + 1); // 提取出最右的1
int onlyOne = 0; // e'
for (int i = 0 ; i < arr.length;i++) {
// arr[1] = 111100011110000
// rightOne= 000000000010000
if ((arr[i] & rightOne) != 0) {
onlyOne ^= arr[i];
}
}
System.out.println(onlyOne + " " + (eor ^ onlyOne));
}
public static int bit1counts(int N) {
int count = 0;
while(N != 0) {
int rightOne = N & ((~N) + 1);
count++;
N -= rightOne;
}
return count;
}
public static int add(int a, int b) {
int t = 0;
while( b != 0) {
t = a;
a = a ^ b;
b = ((t & b) << 1);
}
return a;
}
public static int minus(int a, int b) {
// -b ~b + 1
return add(a, add(~b , 1));
}
public static void main(String[] args) {
int a = 5;
int b = 7;
System.out.println(minus(a,b));
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println(a);
System.out.println(b);
int[] arr1 = { 3, 3, 2, 3, 1, 1, 1, 3, 1, 1, 1 };
printOddTimesNum1(arr1);
int[] arr2 = { 4, 3, 4, 2, 2, 2, 4, 1, 1, 1, 3, 3, 1, 1, 1, 4, 2, 2 };
printOddTimesNum2(arr2);
}
}

@ -1,133 +0,0 @@
package class011;
import java.util.HashMap;
public class Code01_CopyListWithRandom {
public static class Node {
public int value;
public Node next;
public Node rand;
public Node(int data) {
this.value = data;
}
}
public static Node copyListWithRand1(Node head) {
HashMap<Node, Node> map = new HashMap<Node, Node>();
Node cur = head;
while (cur != null) {
map.put(cur, new Node(cur.value));
cur = cur.next;
}
cur = head;
while (cur != null) {
// cur 老
// map.get(cur) 新
map.get(cur).next = map.get(cur.next);
map.get(cur).rand = map.get(cur.rand);
cur = cur.next;
}
return map.get(head);
}
public static Node copyListWithRand2(Node head) {
if (head == null) {
return null;
}
Node cur = head;
Node next = null;
// copy node and link to every node
// 1 -> 2
// 1 -> 1' -> 2
while (cur != null) {
// 1 -> 2 -> 3
// cur next
// 1 -> 1' -> 2 -> 2'
next = cur.next;
cur.next = new Node(cur.value);
cur.next.next = next;
cur = next;
}
cur = head;
Node curCopy = null;
// set copy node rand
// 1 -> 1' -> 2 -> 2'
while (cur != null) {
// 1 -> 1' -> 2 -> 2'
// cur next
// cur 老 cur.next 新
next = cur.next.next;
curCopy = cur.next;
curCopy.rand = cur.rand != null ? cur.rand.next : null;
cur = next;
}
// head head.next
Node res = head.next;
cur = head;
// split
while (cur != null) {
next = cur.next.next;
curCopy = cur.next;
cur.next = next;
curCopy.next = next != null ? next.next : null;
cur = next;
}
return res;
}
public static void printRandLinkedList(Node head) {
Node cur = head;
System.out.print("order: ");
while (cur != null) {
System.out.print(cur.value + " ");
cur = cur.next;
}
System.out.println();
cur = head;
System.out.print("rand: ");
while (cur != null) {
System.out.print(cur.rand == null ? "- " : cur.rand.value + " ");
cur = cur.next;
}
System.out.println();
}
public static void main(String[] args) {
Node head = null;
Node res1 = null;
Node res2 = null;
printRandLinkedList(head);
res1 = copyListWithRand1(head);
printRandLinkedList(res1);
res2 = copyListWithRand2(head);
printRandLinkedList(res2);
printRandLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(4);
head.next.next.next.next = new Node(5);
head.next.next.next.next.next = new Node(6);
head.rand = head.next.next.next.next.next; // 1 -> 6
head.next.rand = head.next.next.next.next.next; // 2 -> 6
head.next.next.rand = head.next.next.next.next; // 3 -> 5
head.next.next.next.rand = head.next.next; // 4 -> 3
head.next.next.next.next.rand = null; // 5 -> null
head.next.next.next.next.next.rand = head.next.next.next; // 6 -> 4
printRandLinkedList(head);
res1 = copyListWithRand1(head);
printRandLinkedList(res1);
res2 = copyListWithRand2(head);
printRandLinkedList(res2);
printRandLinkedList(head);
System.out.println("=========================");
}
}

@ -1,201 +0,0 @@
package class011;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
public class Code02_JumpMinTimes {
public static int jumpMinTimes1(int N, int start, int end, int[] arr) {
boolean[] map = new boolean[N + 1];
return f1(N, start, end, 0, arr, map);
}
// 一共有N个位置, 每个位置如何跳,记录在arr中
// 之前一共走了步数是step步
// 当前来到cur位置最终想去aim位置
// 返回从start开始到aim最少的步数
// 如果map[i] == true 表示i位置之前来过
// 如果map[i] == false 表示i位置之前没来过
public static int f1(int N, int cur, int aim, int step, int[] arr, boolean[] map) {
if (cur < 1 || cur > N) {
return -1;
}
if (map[cur]) {
return -1;
}
// 有效的位置,又没来过
if (cur == aim) {
return step;
}
map[cur] = true;
int ans1 = f1(N, cur + arr[cur - 1], aim, step + 1, arr, map);
int ans2 = f1(N, cur - arr[cur - 1], aim, step + 1, arr, map);
map[cur] = false;
if (ans1 != -1 && ans2 != -1) {
return Math.min(ans1, ans2);
}
if (ans1 != -1 && ans2 == -1) {
return ans1;
}
if (ans1 == -1 && ans2 != -1) {
return ans2;
}
return -1;
}
// 一共有N个位置
// 最终要去aim位置
// arr中描述怎么跳
// 当前来到了i位置
// 已经走了k步
// 最后到达aim至少几步
public static int process(int N, int aim, int[] arr, int i, int k) {
if (i < 1 || i > N || k > N - 1) {
return -1;
}
if (i == aim) {
return k;
}
// 请注意arr的下标是从0开始的但是题目规定的下标从1开始
// 所以拿出i位置能跳的距离需要拿arr[i-1]位置的值
int ans1 = process(N, aim, arr, i + arr[i - 1], k + 1);
int ans2 = process(N, aim, arr, i - arr[i - 1], k + 1);
int ans = -1;
if (ans1 != -1 && ans2 != -1) {
ans = Math.min(ans1, ans2);
}
if (ans1 != -1 && ans2 == -1) {
ans = ans1;
}
if (ans1 == -1 && ans2 != -1) {
ans = ans2;
}
return ans;
}
public static int jumpMinTimes2(int N, int start, int end, int[] arr) {
int[][] dp = new int[N + 1][N + 1];
for (int i = 0; i < dp.length; i++) {
for (int j = 0; j < dp[0].length; j++) {
dp[i][j] = -2;
}
}
// dp[i][k] == -2表示这个过程没算过
// dp[i][k] != -2表示这个过程算过了
return f2(N, end, arr, start, 0, dp);
}
// 一共有N个位置跳的过程中如果你又跳回到某个位置其实这已经说明不是最优步数了
// 也就是说如果存在最优的跳法那么这个最优跳法一定不会大于N-1步
// 所以增加了一个参数k表示已经跳了多少步
// 整个函数的含义:
// 一共有1~N个位置目标是aim位置
// 所有位置能跳的距离都记录在arr中并且对任意的arr[i] > 0
// 当前来到的位置是i, 之前已经跳过了k步
// 返回最后到达aim位置跳的最少的步数
// 如果返回-1表示怎么也无法到达
public static int f2(int N, int aim, int[] arr, int i, int k, int[][] dp) {
if (i < 1 || i > N || k > N - 1) {
return -1;
}
if (dp[i][k] != -2) {
return dp[i][k];
}
if (i == aim) {
dp[i][k] = k;
return k;
}
// 请注意arr的下标是从0开始的但是题目规定的下标从1开始
// 所以拿出i位置能跳的距离需要拿arr[i-1]位置的值
int ans1 = f2(N, aim, arr, i + arr[i - 1], k + 1, dp);
int ans2 = f2(N, aim, arr, i - arr[i - 1], k + 1, dp);
int ans = -1;
if (ans1 != -1 && ans2 != -1) {
ans = Math.min(ans1, ans2);
}
if (ans1 != -1 && ans2 == -1) {
ans = ans1;
}
if (ans1 == -1 && ans2 != -1) {
ans = ans2;
}
dp[i][k] = ans;
return ans;
}
// bfs
public static int jumpMinTimes3(int N, int start, int end, int[] arr) {
if (start < 1 || start > N || end < 1 || end > N) {
return -1;
}
Queue<Integer> queue = new LinkedList<>();
HashMap<Integer, Integer> levelMap = new HashMap<>();
queue.add(start);
levelMap.put(start, 0);
while (!queue.isEmpty()) {
int cur = queue.poll();
int level = levelMap.get(cur);
if (cur == end) {
return level;
} else {
int left = cur - arr[cur - 1];
int right = cur + arr[cur - 1];
if (left > 0 && !levelMap.containsKey(left)) {
queue.add(left);
levelMap.put(left, level + 1);
}
if (right <= N && !levelMap.containsKey(right)) {
queue.add(right);
levelMap.put(right, level + 1);
}
}
}
return -1;
}
// for test
public static int[] gerRandomArray(int N, int R) {
int[] arr = new int[N];
for (int i = 0; i < N; i++) {
arr[i] = (int) (Math.random() * R);
}
return arr;
}
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int maxN = 20;
int maxV = 10;
int testTimes = 200000;
System.out.println("test begin");
for (int i = 0; i < testTimes; i++) {
int[] arr = gerRandomArray(maxN, maxV);
int N = arr.length;
int start = (int) (Math.random() * N) + 1;
int end = (int) (Math.random() * N) + 1;
int ans1 = jumpMinTimes1(N, start, end, arr);
int ans2 = jumpMinTimes2(N, start, end, arr);
int ans3 = jumpMinTimes3(N, start, end, arr);
if (ans1 != ans2 || ans2 != ans3) {
printArray(arr);
System.out.println("start : " + start);
System.out.println("end : " + end);
System.out.println("ans1 : " + ans1);
System.out.println("ans2 : " + ans2);
System.out.println("ans3 : " + ans2);
System.out.println("Oops!");
break;
}
}
System.out.println("test end");
}
}

@ -1,200 +0,0 @@
package class012;
import java.util.HashMap;
public class Code01_MoneyProblem {
public static long func1(int[] d, int[] p) {
return process(d, p, 0, 0);
}
// int[] d d[i]i号怪兽的武力
// int[] p p[i]i号怪兽要求的钱
// hp 当前你所具有的能力
// index 来到了第index个怪兽的面前
// 目前你的能力是hp你来到了index号怪兽的面前如果要通过后续所有的怪兽
// 请返回需要花的最少钱数
public static long process(int[] d, int[] p, int hp, int index) {
if (index == d.length) { // base case
return 0;
}
// index < d.length 还有怪兽要面对
if (hp < d[index]) {
return p[index] + process(d, p, hp + d[index], index + 1);
} else { // hp >= d[index] 可以贿赂,也可以不贿赂
return Math.min(p[index] + process(d, p, hp + d[index], index + 1),
process(d, p, hp, index + 1));
}
}
// 正数数组 d p
public static int dp1(int[] d, int[] p) {
if (d == null || d.length == 0) {
return 0;
}
int sum = 0;
for (int ability : d) {
sum += ability;
}
int N = d.length;
int[][] dp = new int[N + 1][sum + 1];
// dp[N][...] = 0;
for (int i = N - 1; i >= 0; i--) {
for (int j = 0; j <= sum; j++) {
// j 能力 i 怪兽号
if (j + d[i] > sum) {
continue;
}
if (j < d[i]) {
dp[i][j] = p[i] + dp[i + 1][j + d[i]];
} else {
dp[i][j] = Math.min(p[i] + dp[i + 1][j + d[i]], dp[i + 1][j]);
}
}
}
return dp[0][0];
}
public static long func2(int[] d, int[] p) {
int sum = 0;
for (int num : d) {
sum += num;
}
long[][] dp = new long[d.length + 1][sum + 1];
for (int i = 0; i <= sum; i++) {
dp[0][i] = 0;
}
for (int cur = d.length - 1; cur >= 0; cur--) {
for (int hp = 0; hp <= sum; hp++) {
// 如果这种情况发生那么这个hp必然是递归过程中不会出现的状态
// 既然动态规划是尝试过程的优化,尝试过程碰不到的状态,不必计算
if (hp + d[cur] > sum) {
continue;
}
if (hp < d[cur]) {
dp[cur][hp] = p[cur] + dp[cur + 1][hp + d[cur]];
} else {
dp[cur][hp] = Math.min(p[cur] + dp[cur + 1][hp + d[cur]], dp[cur + 1][hp]);
}
}
}
return dp[0][0];
}
public static long func1dp(int[] d, int[] p) {
HashMap<String,Long> dp = new HashMap<>();
return processdp(d, p, 0, 0, dp);
}
// int[] d d[i]i号怪兽的武力
// int[] p p[i]i号怪兽要求的钱
// hp 当前你所具有的能力
// index 来到了第index个怪兽的面前
// 目前你的能力是hp你来到了index号怪兽的面前如果要通过后续所有的怪兽
// 请返回需要花的最少钱数
public static long processdp(int[] d, int[] p, int hp, int index,HashMap<String,Long> dp) {
String key = String.valueOf(hp) + "_" + String.valueOf(index);
if(dp.containsKey(key)) {
return dp.get(key);
}
long ans = 0;
if(index < d.length) {
if (hp < d[index]) {
ans = p[index] + process(d, p, hp + d[index], index + 1);
} else { // hp >= d[index] 可以贿赂,也可以不贿赂
ans = Math.min(p[index] + process(d, p, hp + d[index], index + 1),
process(d, p, hp, index + 1));
}
}
dp.put(key, ans);
return ans;
}
public static long func3(int[] d, int[] p) {
int sum = 0;
for (int num : p) {
sum += num;
}
// dp[i][j]含义:
// 能经过0i的怪兽且花钱为j花钱的严格等于j时的武力值最大是多少
// 如果dp[i][j]==-1表示经过0i的怪兽花钱为j是无法通过的或者之前的钱怎么组合也得不到正好为j的钱数
int[][] dp = new int[d.length][sum + 1];
for (int i = 0; i < dp.length; i++) {
for (int j = 0; j <= sum; j++) {
dp[i][j] = -1;
}
}
// 经过0i的怪兽花钱数一定为p[0]达到武力值d[0]的地步。其他第0行的状态一律是无效的
dp[0][p[0]] = d[0];
for (int i = 1; i < d.length; i++) {
for (int j = 0; j <= sum; j++) {
// 可能性一,为当前怪兽花钱
// 存在条件:
// j - p[i]要不越界并且在钱数为j - p[i]时要能通过0i-1的怪兽并且钱数组合是有效的。
if (j >= p[i] && dp[i - 1][j - p[i]] != -1) {
dp[i][j] = dp[i - 1][j - p[i]] + d[i];
}
// 可能性二,不为当前怪兽花钱
// 存在条件:
// 0~i-1怪兽在花钱为j的情况下能保证通过当前i位置的怪兽
if (dp[i - 1][j] >= d[i]) {
// 两种可能性中,选武力值最大的
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j]);
}
}
}
int ans = 0;
// dp表最后一行上dp[N-1][j]代表:
// 能经过0N-1的怪兽且花钱为j花钱的严格等于j时的武力值最大是多少
// 那么最后一行上,最左侧的不为-1的列数(j),就是答案
for (int j = 0; j <= sum; j++) {
if (dp[d.length - 1][j] != -1) {
ans = j;
break;
}
}
return ans;
}
public static int[][] generateTwoRandomArray(int len, int value) {
int size = (int) (Math.random() * len) + 1;
int[][] arrs = new int[2][size];
for (int i = 0; i < size; i++) {
arrs[0][i] = (int) (Math.random() * value) + 1;
arrs[1][i] = (int) (Math.random() * value) + 1;
}
return arrs;
}
public static void main(String[] args) {
int len = 10;
int value = 20;
int testTimes = 1000000;
for (int i = 0; i < testTimes; i++) {
int[][] arrs = generateTwoRandomArray(len, value);
int[] d = arrs[0];
int[] p = arrs[1];
long ans1 = func1(d, p);
long ans2 = func2(d, p);
long ans3 = func3(d, p);
if (ans1 != ans2 || ans2 != ans3) {
System.out.println("oops!");
}
}
}
}

@ -1,24 +0,0 @@
package class013;
public class Code01_PalindromeNumber {
public static boolean isPalindrome(int n) {
if (n < 0) {
return false;
}
n = Math.abs(n);
int help = 1;
while (n / help >= 10) {
help *= 10;
}
while (n != 0) {
if (n / help != n % 10) {
return false;
}
n = (n % help) / 10;
help /= 100;
}
return true;
}
}

@ -1,70 +0,0 @@
package class013;
public class Code03_LongestNoRepeatSubstring {
public static int maxUnique(String str) {
if (str == null || str.equals("")) {
return 0;
}
char[] chas = str.toCharArray();
// map 替代了哈希表 假设字符的码是0~255
int[] map = new int[256];
for (int i = 0; i < 256; i++) {
map[i] = -1;
}
int len = 0;
int pre = -1;
int cur = 0;
for (int i = 0; i != chas.length; i++) {
pre = Math.max(pre, map[chas[i]]);
cur = i - pre;
len = Math.max(len, cur);
map[chas[i]] = i;
}
return len;
}
// for test
public static String getRandomString(int len) {
char[] str = new char[len];
int base = 'a';
int range = 'z' - 'a' + 1;
for (int i = 0; i != len; i++) {
str[i] = (char) ((int) (Math.random() * range) + base);
}
return String.valueOf(str);
}
// for test
public static String maxUniqueString(String str) {
if (str == null || str.equals("")) {
return str;
}
char[] chas = str.toCharArray();
int[] map = new int[256];
for (int i = 0; i < 256; i++) {
map[i] = -1;
}
int len = -1;
int pre = -1;
int cur = 0;
int end = -1;
for (int i = 0; i != chas.length; i++) {
pre = Math.max(pre, map[chas[i]]);
cur = i - pre;
if (cur > len) {
len = cur;
end = i;
}
map[chas[i]] = i;
}
return str.substring(end - len + 1, end + 1);
}
public static void main(String[] args) {
String str = getRandomString(20);
System.out.println(str);
System.out.println(maxUnique(str));
System.out.println(maxUniqueString(str));
}
}

@ -1,133 +0,0 @@
package class014;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
public class Code01_CoverMax {
public static int maxCover1(int[][] lines) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < lines.length; i++) {
min = Math.min(min, lines[i][0]);
max = Math.max(max, lines[i][1]);
}
int cover = 0;
for (double p = min + 0.5; p < max; p += 1) {
int cur = 0;
for (int i = 0; i < lines.length; i++) {
if (lines[i][0] < p && lines[i][1] > p) {
cur++;
}
}
cover = Math.max(cover, cur);
}
return cover;
}
public static int maxCover2(int[][] m) {
Line[] lines = new Line[m.length];
for (int i = 0; i < m.length; i++) {
lines[i] = new Line(m[i][0], m[i][1]);
}
Arrays.sort(lines, new StartComparator());
// lines
//
PriorityQueue<Integer> heap = new PriorityQueue<>();
int max = 0;
for (int i = 0; i < lines.length; i++) {
// lines[i] -> cur 在黑盒中,把<=cur.start 东西都弹出
while (!heap.isEmpty() && heap.peek() <= lines[i].start) {
heap.poll();
}
heap.add(lines[i].end);
max = Math.max(max, heap.size());
}
return max;
}
public static class Line {
public int start;
public int end;
public Line(int s, int e) {
start = s;
end = e;
}
}
public static class EndComparator implements Comparator<Line> {
@Override
public int compare(Line o1, Line o2) {
return o1.end - o2.end;
}
}
// for test
public static int[][] generateLines(int N, int L, int R) {
int size = (int) (Math.random() * N) + 1;
int[][] ans = new int[size][2];
for (int i = 0; i < size; i++) {
int a = L + (int) (Math.random() * (R - L + 1));
int b = L + (int) (Math.random() * (R - L + 1));
if (a == b) {
b = a + 1;
}
ans[i][0] = Math.min(a, b);
ans[i][1] = Math.max(a, b);
}
return ans;
}
public static class StartComparator implements Comparator<Line> {
@Override
public int compare(Line o1, Line o2) {
return o1.start - o2.start;
}
}
public static void main(String[] args) {
Line l1 = new Line(4, 9);
Line l2 = new Line(1, 4);
Line l3 = new Line(7, 15);
Line l4 = new Line(2, 4);
Line l5 = new Line(4, 6);
Line l6 = new Line(3, 7);
// 底层堆结构heap
PriorityQueue<Line> heap = new PriorityQueue<>(new StartComparator());
heap.add(l1);
heap.add(l2);
heap.add(l3);
heap.add(l4);
heap.add(l5);
heap.add(l6);
while (!heap.isEmpty()) {
Line cur = heap.poll();
System.out.println(cur.start + "," + cur.end);
}
System.out.println("test begin");
int N = 100;
int L = 0;
int R = 200;
int testTimes = 200000;
for (int i = 0; i < testTimes; i++) {
int[][] lines = generateLines(N, L, R);
int ans1 = maxCover1(lines);
int ans2 = maxCover2(lines);
if (ans1 != ans2) {
System.out.println("Oops!");
}
}
System.out.println("test end");
}
}

@ -1,154 +0,0 @@
package class014;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class Code02_MaxDistance {
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
public static int maxDistance2(Node head) {
return f(head).allTreeMaxDis;
}
// 左:最大距离、高
// 右:最大距离、高
public static class Info {
public int allTreeMaxDis;
public int height;
public Info(int all, int h) {
allTreeMaxDis = all;
height = h;
}
}
// 以x为头情况下两个结果
public static Info f(Node x) {
if (x == null) {
return new Info(0, 0);
}
Info leftInfo = f(x.left);
Info rightInfo = f(x.right);
int allTreeMaxDis = Math.max(Math.max(leftInfo.allTreeMaxDis, rightInfo.allTreeMaxDis),
leftInfo.height + rightInfo.height + 1);
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
return new Info(allTreeMaxDis, height);
}
public static int maxDistance1(Node head) {
if (head == null) {
return 0;
}
ArrayList<Node> arr = getPrelist(head);
HashMap<Node, Node> parentMap = getParentMap(head);
int max = 0;
for (int i = 0; i < arr.size(); i++) {
for (int j = i; j < arr.size(); j++) {
max = Math.max(max, distance(parentMap, arr.get(i), arr.get(j)));
}
}
return max;
}
public static ArrayList<Node> getPrelist(Node head) {
ArrayList<Node> arr = new ArrayList<>();
fillPrelist(head, arr);
return arr;
}
public static void fillPrelist(Node head, ArrayList<Node> arr) {
if (head == null) {
return;
}
arr.add(head);
fillPrelist(head.left, arr);
fillPrelist(head.right, arr);
}
public static HashMap<Node, Node> getParentMap(Node head) {
HashMap<Node, Node> map = new HashMap<>();
map.put(head, null);
fillParentMap(head, map);
return map;
}
public static void fillParentMap(Node head, HashMap<Node, Node> parentMap) {
if (head.left != null) {
parentMap.put(head.left, head);
fillParentMap(head.left, parentMap);
}
if (head.right != null) {
parentMap.put(head.right, head);
fillParentMap(head.right, parentMap);
}
}
public static int distance(HashMap<Node, Node> parentMap, Node o1, Node o2) {
HashSet<Node> o1Set = new HashSet<>();
Node cur = o1;
o1Set.add(cur);
while (parentMap.get(cur) != null) {
cur = parentMap.get(cur);
o1Set.add(cur);
}
cur = o2;
while (!o1Set.contains(cur)) {
cur = parentMap.get(cur);
}
Node lowestAncestor = cur;
cur = o1;
int distance1 = 1;
while (cur != lowestAncestor) {
cur = parentMap.get(cur);
distance1++;
}
cur = o2;
int distance2 = 1;
while (cur != lowestAncestor) {
cur = parentMap.get(cur);
distance2++;
}
return distance1 + distance2 - 1;
}
// for test
public static Node generateRandomBST(int maxLevel, int maxValue) {
return generate(1, maxLevel, maxValue);
}
// for test
public static Node generate(int level, int maxLevel, int maxValue) {
if (level > maxLevel || Math.random() < 0.5) {
return null;
}
Node head = new Node((int) (Math.random() * maxValue));
head.left = generate(level + 1, maxLevel, maxValue);
head.right = generate(level + 1, maxLevel, maxValue);
return head;
}
public static void main(String[] args) {
int maxLevel = 4;
int maxValue = 100;
int testTimes = 1000000;
System.out.println("test begin");
for (int i = 0; i < testTimes; i++) {
Node head = generateRandomBST(maxLevel, maxValue);
if (maxDistance1(head) != maxDistance2(head)) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,88 +0,0 @@
package class015;
import java.util.Arrays;
public class Code01_CordCoverMaxPoint {
public static int maxPoint1(int[] arr, int L) {
int res = 1;
for (int i = 0; i < arr.length; i++) {
int nearest = nearestIndex(arr, i, arr[i] - L);
res = Math.max(res, i - nearest + 1);
}
return res;
}
public static int nearestIndex(int[] arr, int R, int value) {
int L = 0;
int index = R;
while (L <= R) {
int mid = L + ((R - L) >> 1);
if (arr[mid] >= value) {
index = mid;
R = mid - 1;
} else {
L = mid + 1;
}
}
return index;
}
public static int maxPoint2(int[] arr, int L) {
int left = 0;
int right = 0;
int N = arr.length;
int max = 0;
while (left < N) {
while (right < N && arr[right] - arr[left] <= L) {
right++;
}
max = Math.max(max, right - (left++));
}
return max;
}
// for test
public static int test(int[] arr, int L) {
int max = 0;
for (int i = 0; i < arr.length; i++) {
int pre = i - 1;
while (pre >= 0 && arr[i] - arr[pre] <= L) {
pre--;
}
max = Math.max(max, i - pre);
}
return max;
}
// for test
public static int[] generateArray(int len, int max) {
int[] ans = new int[(int) (Math.random() * len) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * max);
}
Arrays.sort(ans);
return ans;
}
public static void main(String[] args) {
int len = 100;
int max = 1000;
int testTime = 100000;
System.out.println("测试开始");
for (int i = 0; i < testTime; i++) {
int L = (int) (Math.random() * max);
int[] arr = generateArray(len, max);
int ans1 = maxPoint1(arr, L);
int ans2 = maxPoint2(arr, L);
int ans3 = test(arr, L);
if (ans1 != ans2 || ans2 != ans3) {
System.out.println("oops!");
break;
}
}
System.out.println("测试结束");
}
}

@ -1,72 +0,0 @@
package class015;
public class Code02_ColorLeftRight {
// RGRGR -> RRRGG
public static int minPaint(String s) {
if (s == null || s.length() < 2) {
return 0;
}
char[] str = s.toCharArray();
int N = str.length;
int rAll = 0;
for (int i = 0; i < N; i++) {
rAll += str[i] == 'R' ? 1 : 0;
}
int ans = rAll; // 如果数组所有的范围都是右侧范围都变成G
int left = 0;
for (int i = 0; i < N - 1; i++) { // 0..i 左侧 n-1..N-1
left += str[i] == 'G' ? 1 : 0;
rAll -= str[i] == 'R' ? 1 : 0;
ans = Math.min(ans, left + rAll);
}
// 0...N-1 左全部 右无
ans = Math.min(ans, left + (str[N - 1] == 'G' ? 1 : 0));
return ans;
}
// RGRGR -> RRRGG
public static int test(String s) {
if (s == null || s.length() < 2) {
return 0;
}
char[] str = s.toCharArray();
int ans = Integer.MAX_VALUE;
for (int leftEnd = -1; leftEnd < str.length; leftEnd++) {
int left = 0;
for (int i = 0; i <= leftEnd; i++) {
left += str[i] == 'G' ? 1 : 0;
}
int right = 0;
for (int i = leftEnd + 1; i < str.length; i++) {
right += str[i] == 'R' ? 1 : 0;
}
ans = Math.min(ans, left + right);
}
return ans;
}
public static String generateString(int len) {
char[] str = new char[(int) (Math.random() * len) + 1];
for (int i = 0; i < str.length; i++) {
str[i] = Math.random() < 0.5 ? 'R' : 'G';
}
return String.valueOf(str);
}
public static void main(String[] args) {
int len = 100;
int testTime = 100000;
System.out.println("测试开始");
for (int i = 0; i < testTime; i++) {
String str = generateString(len);
int ans1 = minPaint(str);
int ans2 = test(str);
if (ans1 != ans2) {
System.out.println("Oops!");
}
}
System.out.println("测试结束");
}
}

@ -1,72 +0,0 @@
package class015;
public class Code03_MaxABSBetweenLeftAndRight {
public static int maxABS1(int[] arr) {
int res = Integer.MIN_VALUE;
int maxLeft = 0;
int maxRight = 0;
for (int i = 0; i != arr.length - 1; i++) {
maxLeft = Integer.MIN_VALUE;
for (int j = 0; j != i + 1; j++) {
maxLeft = Math.max(arr[j], maxLeft);
}
maxRight = Integer.MIN_VALUE;
for (int j = i + 1; j != arr.length; j++) {
maxRight = Math.max(arr[j], maxRight);
}
res = Math.max(Math.abs(maxLeft - maxRight), res);
}
return res;
}
public static int maxABS2(int[] arr) {
int[] lArr = new int[arr.length];
int[] rArr = new int[arr.length];
lArr[0] = arr[0];
rArr[arr.length - 1] = arr[arr.length - 1];
for (int i = 1; i < arr.length; i++) {
lArr[i] = Math.max(lArr[i - 1], arr[i]);
}
for (int i = arr.length - 2; i > -1; i--) {
rArr[i] = Math.max(rArr[i + 1], arr[i]);
}
int max = 0;
for (int i = 0; i < arr.length - 1; i++) {
max = Math.max(max, Math.abs(lArr[i] - rArr[i + 1]));
}
return max;
}
public static int maxABS3(int[] arr) {
int max = Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
max = Math.max(arr[i], max);
}
return max - Math.min(arr[0], arr[arr.length - 1]);
}
public static int[] generateRandomArray(int length) {
int[] arr = new int[length];
for (int i = 0; i != arr.length; i++) {
arr[i] = (int) (Math.random() * 1000) - 499;
}
return arr;
}
public static void main(String[] args) {
int len = 100;
int testTime = 100000;
System.out.println("测试开始");
for (int i = 0; i < testTime; i++) {
int[] arr = generateRandomArray(len);
int ans1 = maxABS1(arr);
int ans2 = maxABS2(arr);
int ans3 = maxABS3(arr);
if (ans1 != ans2 || ans1 != ans3) {
System.out.println("Oops!");
}
}
System.out.println("测试结束");
}
}

@ -1,121 +0,0 @@
package class015;
public class Code04_TrappingRainWater {
/*
* arrarr
*
*/
public static int water1(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int water = 0;
for (int i = 1; i < N - 1; i++) {
int leftMax = Integer.MIN_VALUE;
for (int j = 0; j < i; j++) {
leftMax = Math.max(leftMax, arr[j]);
}
int rightMax = Integer.MIN_VALUE;
for (int j = i + 1; j < N; j++) {
rightMax = Math.max(rightMax, arr[j]);
}
water += Math.max(Math.min(leftMax, rightMax) - arr[i], 0);
}
return water;
}
public static int water2(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int[] leftMaxs = new int[N];
leftMaxs[0] = arr[0];
for (int i = 1; i < N; i++) {
leftMaxs[i] = Math.max(leftMaxs[i - 1], arr[i]);
}
int[] rightMaxs = new int[N];
rightMaxs[N - 1] = arr[N - 1];
for (int i = N - 2; i >= 0; i--) {
rightMaxs[i] = Math.max(rightMaxs[i + 1], arr[i]);
}
int water = 0;
for (int i = 1; i < N - 1; i++) {
water += Math.max(Math.min(leftMaxs[i - 1], rightMaxs[i + 1]) - arr[i], 0);
}
return water;
}
public static int water3(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int[] rightMaxs = new int[N];
rightMaxs[N - 1] = arr[N - 1];
for (int i = N - 2; i >= 0; i--) {
rightMaxs[i] = Math.max(rightMaxs[i + 1], arr[i]);
}
int water = 0;
int leftMax = arr[0];
for (int i = 1; i < N - 1; i++) {
water += Math.max(Math.min(leftMax, rightMaxs[i + 1]) - arr[i], 0);
leftMax = Math.max(leftMax, arr[i]);
}
return water;
}
public static int water4(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int L = 1;
int leftMax = arr[0];
int R = N - 2;
int rightMax = arr[N - 1];
int water = 0;
while (L <= R) {
if (leftMax <= rightMax) {
water += Math.max(0, leftMax - arr[L]);
leftMax = Math.max(leftMax, arr[L++]);
} else {
water += Math.max(0, rightMax - arr[R]);
rightMax = Math.max(rightMax, arr[R--]);
}
}
return water;
}
// for test
public static int[] generateRandomArray(int len, int value) {
int[] ans = new int[(int) (Math.random() * len) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * value) + 1;
}
return ans;
}
public static void main(String[] args) {
int len = 100;
int value = 200;
int testTimes = 100000;
System.out.println("测试开始");
for (int i = 0; i < testTimes; i++) {
int[] arr = generateRandomArray(len, value);
int ans1 = water1(arr);
int ans2 = water2(arr);
int ans3 = water3(arr);
int ans4 = water4(arr);
if (ans1 != ans2 || ans3 != ans4 || ans1 != ans3) {
System.out.println("Oops!");
}
}
System.out.println("测试结束");
}
}

@ -1,138 +0,0 @@
package class016;
public class Code01_RandToRand {
// 条件且代码不可修改1~5
public static int f() {
return (int) (Math.random() * 5) + 1;
}
// 等概率返回 0~4
public static int a() {
return f() - 1;
}
// 等概率返回 0 ~ 24
public static int b() {
return a() * 5 + a();
}
// 等概率返回 1~7
public static int g1() {
int t = 0;
do {
t = b();
} while (t > 20);
// t 0 ~ 20
return (t % 7) + 1;
}
// 利用f函数请等概率生成0和1
public static int c() {
int t = 0;
do {
t = f();
} while (t == 3);
return t < 3 ? 0 : 1;
}
// 等概率返回 1~7
public static int g2() {
int t = 0;
do {
t = (c() << 2) + (c() << 1) + c();
} while (t == 7);
return t + 1;
}
// 这个结构是唯一的随机机制
// 你只能初始化并使用,不可修改
public static class RandomBox {
private final int min;
private final int max;
// 初始化时请一定不要让mi==ma
public RandomBox(int mi, int ma) {
min = mi;
max = ma;
}
public int random() {
return min + (int) (Math.random() * (max - min + 1));
}
public int min() {
return min;
}
public int max() {
return max;
}
}
// 利用条件RandomBox如何等概率返回0和1
public static int rand01(RandomBox randomBox) {
int min = randomBox.min();
int max = randomBox.max();
// min ~ max
int size = max - min + 1;
// size是不是奇数odd 奇数
boolean odd = (size & 1) != 0;
int mid = size / 2;
int ans = 0;
do {
ans = randomBox.random() - min;
} while (odd && ans == mid);
return ans < mid ? 0 : 1;
}
// 给你一个RandomBox这是唯一能借助的随机机制
// 等概率返回from~to范围上任何一个数
// 要求from<=to
public static int random(RandomBox randomBox, int from, int to) {
if (from == to) {
return from;
}
// 3 ~ 9
// 0 ~ 6
// 0 ~ range
int range = to - from;
int num = 1;
// 求0range需要几个2进制位
while ((1 << num) - 1 < range) {
num++;
}
// 我们一共需要num位
// 最终的累加和,首先+0位上是1还是01位上是1还是02位上是1还是0...
int ans = 0;
do {
ans = 0;
for (int i = 0; i < num; i++) {
ans |= (rand01(randomBox) << i);
}
} while (ans > range);
return ans + from;
}
public static void main(String[] args) {
int hasFrom = 1;
int hasTo = 19;
int from = 7;
int to = 29;
RandomBox randomBox = new RandomBox(hasFrom, hasTo);
int[] ans = new int[to + 1];
int testTime1 = 1000000;
for (int i = 0; i < testTime1; i++) {
ans[random(randomBox, from, to)]++;
}
for (int i = 0; i < ans.length; i++) {
System.out.println(i + " 出现了 " + ans[i]);
}
System.out.println("==========");
}
}

@ -1,46 +0,0 @@
package class016;
public class Code02_EqualProbabilityRandom {
// 这个结构是唯一的随机机制
// 你只能初始化并使用,不可修改
public static class RandomBox {
private final double p;
// 初始化时请一定满足0 < zeroP < 1
public RandomBox(double zeroP) {
p = zeroP;
}
public int random() {
return Math.random() < p ? 0 : 1;
}
}
// 底层依赖一个以p概率返回0以1-p概率返回1的随机函数rand01p
// 如何加工出等概率返回0和1的函数
public static int rand01(RandomBox randomBox) {
int num;
do {
num = randomBox.random();
} while (num == randomBox.random());
return num;
}
public static void main(String[] args) {
double zeroP = 0.88;
RandomBox randomBox = new RandomBox(zeroP);
int testTime = 10000000;
int count = 0;
for (int i = 0; i < testTime; i++) {
if (rand01(randomBox) == 0) {
count++;
}
}
System.out.println((double) count / (double) testTime);
}
}

@ -1,77 +0,0 @@
package class016;
import java.util.HashMap;
import java.util.Map.Entry;
public class Code03_FindHalfMajority {
public static int halfMajor(int[] arr) {
int cand = 0;
int HP = 0;
// 遍历一遍数组arr一次删掉两个不同的数谁会剩下来谁就是cand
for (int i = 0; i != arr.length; i++) {
if (HP == 0) {
cand = arr[i];
HP = 1;
} else if (arr[i] == cand) {
HP++;
} else {
HP--;
}
}
if (HP == 0) {
return -1;
}
HP = 0;
for (int i = 0; i != arr.length; i++) {
if (arr[i] == cand) {
HP++;
}
}
return HP > arr.length / 2 ? cand : -1;
}
// for test
public static int right(int[] arr) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int cur : arr) {
if (!map.containsKey(cur)) {
map.put(cur, 0);
}
map.put(cur, map.get(cur) + 1);
}
for (Entry<Integer, Integer> entry : map.entrySet()) {
if (entry.getValue() > arr.length / 2) {
return entry.getKey();
}
}
return -1;
}
// for test
public static int[] genareteRandomArray(int len, int max) {
int[] ans = new int[(int) (Math.random() * len) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * max) + 1;
}
return ans;
}
public static void main(String[] args) {
int len = 100;
int max = 10;
int testTime = 100000;
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int[] arr = genareteRandomArray(len, max);
int ans1 = halfMajor(arr);
int ans2 = right(arr);
if (ans1 != ans2) {
System.out.println("Oops!");
break;
}
}
System.out.println("test end");
}
}

@ -1,135 +0,0 @@
package class016;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
public class Code04_FindKMajor {
public static List<Integer> kMajor(int[] arr, int K) {
List<Integer> ans = new ArrayList<>();
if (K < 2) {
return ans;
}
// 候选表记录数一定是O(K) > N/K k-1
HashMap<Integer, Integer> cands = new HashMap<Integer, Integer>();
for (int i = 0; i != arr.length; i++) {
if (cands.containsKey(arr[i])) {
cands.put(arr[i], cands.get(arr[i]) + 1);
} else {
if (cands.size() == K - 1) {
allCandsMinusOne(cands);
} else {
cands.put(arr[i], 1);
}
}
}
HashMap<Integer, Integer> reals = getReals(arr, cands);
for (Entry<Integer, Integer> set : cands.entrySet()) {
Integer key = set.getKey();
if (reals.get(key) > arr.length / K) {
ans.add(key);
}
}
return ans;
}
public static void allCandsMinusOne(HashMap<Integer, Integer> map) {
List<Integer> removeList = new LinkedList<Integer>();
for (Entry<Integer, Integer> set : map.entrySet()) {
Integer key = set.getKey();
Integer value = set.getValue();
if (value == 1) {
removeList.add(key);
}
map.put(key, value - 1);
}
for (Integer removeKey : removeList) {
map.remove(removeKey);
}
}
// for test
public static List<Integer> right(int[] arr, int K) {
List<Integer> ans = new ArrayList<>();
if (K < 2) {
return ans;
}
HashMap<Integer, Integer> times = new HashMap<>();
for (int num : arr) {
if (!times.containsKey(num)) {
times.put(num, 1);
} else {
times.put(num, times.get(num) + 1);
}
}
for (Entry<Integer, Integer> entry : times.entrySet()) {
if (entry.getValue() > arr.length / K) {
ans.add(entry.getKey());
}
}
return ans;
}
public static HashMap<Integer, Integer> getReals(int[] arr, HashMap<Integer, Integer> cands) {
HashMap<Integer, Integer> reals = new HashMap<Integer, Integer>();
for (int i = 0; i != arr.length; i++) {
int curNum = arr[i];
if (cands.containsKey(curNum)) {
if (reals.containsKey(curNum)) {
reals.put(curNum, reals.get(curNum) + 1);
} else {
reals.put(curNum, 1);
}
}
}
return reals;
}
public static int[] genareteRandomArray(int len, int max) {
int[] ans = new int[(int) (Math.random() * len) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * max) + 1;
}
return ans;
}
public static boolean isEqual(List<Integer> ans1, List<Integer> ans2) {
if (ans1.size() != ans2.size()) {
return false;
}
HashSet<Integer> set1 = new HashSet<>();
for (Integer num : ans1) {
set1.add(num);
}
if (set1.size() != ans1.size()) {
return false;
}
for (Integer num : ans2) {
set1.remove(num);
}
return set1.size() == 0;
}
public static void main(String[] args) {
int len = 100;
int max = 10;
int K = 5;
int testTime = 100000;
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int[] arr = genareteRandomArray(len, max);
List<Integer> ans1 = kMajor(arr, K);
List<Integer> ans2 = right(arr, K);
if (!isEqual(ans1, ans2)) {
System.out.println("Oops!");
break;
}
}
System.out.println("test end");
}
}

@ -1,111 +0,0 @@
package class017;
import java.util.ArrayList;
import java.util.List;
public class Code01_SubArrayMaxSum {
public static int test(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
int N = arr.length;
int max = Integer.MIN_VALUE;
for (int L = 0; L < N; L++) {
for (int R = L; R < N; R++) {
// arr[L...R]
int sum = 0;
for (int i = L; i <= R; i++) {
sum += arr[i];
}
max = Math.max(max, sum);
}
}
return max;
}
public static int maxSum1(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
// 0结尾时候的答案
int pre = arr[0];
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
// i结尾时候的答案
pre = arr[i] + (pre > 0 ? pre : 0);
max = Math.max(max, pre);
}
return max;
}
public static List<List<Integer>> maxSum2(int[] arr) {
List<List<Integer>> ans = new ArrayList<>();
if (arr == null || arr.length == 0) {
return ans;
}
int L = 0;
int maxLen = 0;
int maxSum = Integer.MIN_VALUE;
int cur = 0;
for (int i = 0; i < arr.length; i++) {
// L...i sum
cur += arr[i];
if (cur == maxSum && (i - L + 1) == maxLen) {
List<Integer> curAns = new ArrayList<>();
curAns.add(L);
curAns.add(i);
ans.add(curAns);
}
if (cur > maxSum || (cur == maxSum && (i - L + 1) > maxLen)) {
ans.clear();
List<Integer> curAns = new ArrayList<>();
curAns.add(L);
curAns.add(i);
ans.add(curAns);
maxLen = i - L + 1;
}
maxSum = Math.max(maxSum, cur);
if (cur < 0) {
cur = 0;
L = i + 1;
}
}
return ans;
}
public static int[] generateArray(int N, int V) {
int n = (int) (Math.random() * N) + 1;
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = (int) (Math.random() * V) - (int) (Math.random() * V);
}
return arr;
}
public static void main(String[] args) {
// int N = 100;
// int V = 100;
// int testTime = 1000000;
// System.out.println("test begin");
// for (int i = 0; i < testTime; i++) {
// int[] arr = generateArray(N, V);
// int ans1 = maxSum1(arr);
// int ans2 = maxSum2(arr);
// if (ans1 != ans2) {
// System.out.println("Oops!");
// }
// }
// System.out.println("test finish");
int[] test = { 2, 2, 1, -9, 2, 3, -9, 6, -9, 2, 2, 2, -9, 2, 2, 2, -9, 1, 4, 1 };
List<List<Integer>> ans = maxSum2(test);
for (List<Integer> cur : ans) {
System.out.println("start : " + cur.get(0) + ", end : " + cur.get(1));
}
}
}

@ -1,83 +0,0 @@
package class017;
public class Code02_SubMatrixMaxSum {
public static int maxSum1(int[][] matrix) {
int n = matrix.length;
int m = matrix[0].length;
int max = Integer.MIN_VALUE;
for (int ai = 0; ai < n; ai++) {
for (int aj = 0; aj < m; aj++) {
for (int bi = ai; bi < n; bi++) {
for (int bj = aj; bj < m; bj++) {
max = Math.max(max, sum(matrix, ai, aj, bi, bj));
}
}
}
}
return max;
}
public static int sum(int[][] matrix, int ai, int aj, int bi, int bj) {
int sum = 0;
for (int i = ai; i <= bi; i++) {
for (int j = aj; j <= bj; j++) {
sum += matrix[i][j];
}
}
return sum;
}
public static int maxSum2(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return 0;
}
int max = Integer.MIN_VALUE;
int cur = 0;
int[] s = null;
for (int i = 0; i != matrix.length; i++) {
s = new int[matrix[0].length];
for (int j = i; j != matrix.length; j++) {
cur = 0;
for (int k = 0; k != s.length; k++) {
s[k] += matrix[j][k];
cur += s[k];
max = Math.max(max, cur);
cur = cur < 0 ? 0 : cur;
}
}
}
return max;
}
public static int[][] generateMatrix(int N, int M, int V) {
int n = (int) (Math.random() * N) + 1;
int m = (int) (Math.random() * M) + 1;
int[][] matrix = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
matrix[i][j] = (int) (Math.random() * V) - (int) (Math.random() * V);
}
}
return matrix;
}
public static void main(String[] args) {
int N = 20;
int M = 20;
int V = 100;
int testTime = 50000;
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int[][] matrix = generateMatrix(N, M, V);
int ans1 = maxSum1(matrix);
int ans2 = maxSum2(matrix);
if (ans1 != ans2) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,31 +0,0 @@
package class018;
public class Code01_SqrtX {
// x一定非负输入可以保证
public static int mySqrt(int x) {
if (x == 0) {
return 0;
}
// x != 0 1 2
if (x < 3) {
return 1;
}
// x >= 3
long ans = 1;
long L = 1;
long R = x;
long M = 0;
while (L <= R) {
M = (L + R) / 2;
if (M * M <= x) {
ans = M;
L = M + 1;
} else {
R = M - 1;
}
}
return (int) ans;
}
}

@ -1,54 +0,0 @@
package class018;
public class Code02_PowXN {
public static void main(String[] args) {
long a = 2;
long n = 13; // 1101
long t = a;
long res = 1;
while (n != 0) {
// n = 110111011111
// & 1 = 000000000001
// 000000000000
// n & (n-1)
// 把n抹掉最右侧的1
// n = 10010101100010000
// n-1 = 10010101100001111
// & = 10010101100000000
if ((n & 1) == 1) {
res *= t;
}
t = t * t;
n = n >> 1;
}
System.out.println(res);
System.out.println(Math.pow(2.0, 13));
System.out.println(-Integer.MIN_VALUE);
System.out.println(Math.abs(Integer.MIN_VALUE));
}
// 求x的n次方
public static double myPow(double x, int n) {
if (n == 0) {
return 1D;
}
if (n == Integer.MIN_VALUE) {
return (x == 1D || x == -1D) ? 1D : 0;
}
// 4.5 -3
int pow = Math.abs(n);
double t = x;
double ans = 1D;
while (pow != 0) {
if ((pow & 1) != 0) {
ans *= t;
}
pow >>= 1;
t = t * t;
}
return n < 0 ? (1D / ans) : ans;
}
}

@ -1,31 +0,0 @@
package class018;
public class Code03_ContainerWithMostWater {
public static int maxArea1(int[] h) {
int max = 0;
int N = h.length;
for (int i = 0; i < N; i++) { // h[i]
for (int j = i + 1; j < N; j++) { // h[j]
max = Math.max(max, Math.min(h[i], h[j]) * (j - i));
}
}
return max;
}
public static int maxArea2(int[] h) {
int max = 0;
int l = 0;
int r = h.length - 1;
while (l < r) {
max = Math.max(max, Math.min(h[l], h[r]) * (r - l));
if (h[l] > h[r]) {
r--;
} else {
l++;
}
}
return max;
}
}

@ -1,27 +0,0 @@
package class019;
public class Code01_RotateImage {
public static void rotate(int[][] matrix) {
// matrix.length == matrix[0].length
int a = 0;
int b = 0;
int c = matrix.length - 1;
int d = matrix[0].length - 1;
while (a < c) {
rotateEdge(matrix, a++, b++, c--, d--);
}
}
public static void rotateEdge(int[][] m, int a, int b, int c, int d) {
int tmp = 0;
for (int i = 0; i < d - b; i++) {
tmp = m[a][b + i];
m[a][b + i] = m[c - i][b];
m[c - i][b] = m[c][d - i];
m[c][d - i] = m[a + i][d];
m[a + i][d] = tmp;
}
}
}

@ -1,48 +0,0 @@
package class019;
public class Code02_ZigZagPrintMatrix {
public static void printMatrixZigZag(int[][] matrix) {
int aRow = 0;
int aCol = 0;
int bRow = 0;
int bCol = 0;
// A和B一定会共同走到右下角的位置
int endR = matrix.length - 1;
int endC = matrix[0].length - 1;
// fromUp = true 斜线打印方向应该从右上走到左下
// fromUp = false 斜线打印方向应该从左下走到右上
boolean fromUp = false;
while (aRow != endR + 1) {
printLevel(matrix, aRow, aCol, bRow, bCol, fromUp);
aRow = aCol == endC ? aRow + 1 : aRow;
aCol = aCol == endC ? aCol : aCol + 1;
bCol = bRow == endR ? bCol + 1 : bCol;
bRow = bRow == endR ? bRow : bRow + 1;
fromUp = !fromUp;
}
System.out.println();
}
public static void printLevel(int[][] m, int aRow, int aCol, int bRow, int bCol, boolean f) {
if (f) {
while (aRow != bRow + 1) {
System.out.print(m[aRow++][aCol--] + " ");
}
} else {
while (bRow != aRow - 1) {
System.out.print(m[bRow--][bCol++] + " ");
}
}
}
public static void main(String[] args) {
int[][] matrix = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 } };
printMatrixZigZag(matrix);
}
}

@ -1,46 +0,0 @@
package class019;
public class Code03_PrintStar {
public static void printStar(int N) {
int leftUp = 0;
int rightDown = N - 1;
char[][] m = new char[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
m[i][j] = ' ';
}
}
while (leftUp <= rightDown) {
set(m, leftUp, rightDown);
leftUp += 2;
rightDown -= 2;
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
System.out.print(m[i][j] + " ");
}
System.out.println();
}
}
public static void set(char[][] m, int leftUp, int rightDown) {
for (int col = leftUp; col <= rightDown; col++) {
m[leftUp][col] = '*';
}
for (int row = leftUp + 1; row <= rightDown; row++) {
m[row][rightDown] = '*';
}
for (int col = rightDown - 1; col > leftUp; col--) {
m[rightDown][col] = '*';
}
for (int row = rightDown - 1; row > leftUp + 1; row--) {
m[row][leftUp + 1] = '*';
}
}
public static void main(String[] args) {
printStar(8);
}
}

@ -1,93 +0,0 @@
package class020;
public class Code01_RotateString {
public static String rotate1(String s, int leftSize) {
if (leftSize <= 0 || leftSize >= s.length()) {
return s;
}
return process1(s.toCharArray(), 0, leftSize - 1, s.length() - 1);
}
public static String process1(char[] str, int L, int M, int R) {
reverse(str, L, M);
reverse(str, M + 1, R);
reverse(str, L, R);
return String.valueOf(str);
}
public static void reverse(char[] str, int L, int R) {
while (L < R) {
char tmp = str[L];
str[L++] = str[R];
str[R--] = tmp;
}
}
public static String rotate2(String s, int leftSize) {
if (leftSize <= 0 || leftSize >= s.length()) {
return s;
}
char[] str = s.toCharArray();
int L = 0;
int R = str.length - 1;
int lpart = leftSize;
int rpart = str.length - leftSize;
int same = Math.min(lpart, rpart);
int diff = lpart - rpart;
exchange(str, L, R, same);
while (diff != 0) {
if (diff > 0) {
L += same;
lpart = diff;
} else {
R -= same;
rpart = -diff;
}
same = Math.min(lpart, rpart);
diff = lpart - rpart;
exchange(str, L, R, same);
}
return String.valueOf(str);
}
public static void exchange(char[] chas, int start, int end, int size) {
int i = end - size + 1;
char tmp = 0;
while (size-- != 0) {
tmp = chas[start];
chas[start] = chas[i];
chas[i] = tmp;
start++;
i++;
}
}
// for test
public static String getRandomString(int possibilities, int strMaxSize) {
char[] ans = new char[(int) (Math.random() * strMaxSize) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (char) ((int) (Math.random() * possibilities) + 'a');
}
return String.valueOf(ans);
}
public static void main(String[] args) {
int possibilities = 5;
int strMaxSize = 10;
int testTimes = 5000000;
System.out.println("test begin, test time : " + testTimes);
for (int i = 0; i < testTimes; i++) {
String str = getRandomString(possibilities, strMaxSize);
int leftSize = (int) (Math.random() * (str.length() + 1));
String ans1 = rotate1(str, leftSize);
String ans2 = rotate2(str, leftSize);
if (!ans1.equals(ans2)) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,111 +0,0 @@
package class020;
import java.util.HashSet;
public class Code02_HowManyTypes {
/*
* a~zString[] arr
* baacbabac
* abc arr
*
*/
public static int types1(String[] arr) {
HashSet<String> types = new HashSet<>();
for (String str : arr) {
char[] chs = str.toCharArray();
boolean[] map = new boolean[26];
for (int i = 0; i < chs.length; i++) {
map[chs[i] - 'a'] = true;
}
String key = "";
for (int i = 0; i < 26; i++) {
if (map[i]) {
key += String.valueOf((char) (i + 'a'));
}
}
types.add(key);
}
return types.size();
}
public static int types2(String[] arr) {
HashSet<Integer> types = new HashSet<>();
for (String str : arr) {
char[] chs = str.toCharArray();
int key = 0;
for (int i = 0; i < chs.length; i++) {
key |= (1 << (chs[i] - 'a'));
}
types.add(key);
}
return types.size();
}
// for test
public static String[] getRandomStringArray(int possibilities, int strMaxSize, int arrMaxSize) {
String[] ans = new String[(int) (Math.random() * arrMaxSize) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = getRandomString(possibilities, strMaxSize);
}
return ans;
}
// for test
public static String getRandomString(int possibilities, int strMaxSize) {
char[] ans = new char[(int) (Math.random() * strMaxSize) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (char) ((int) (Math.random() * possibilities) + 'a');
}
return String.valueOf(ans);
}
public static void printIntegerBinary(int num) {
StringBuilder builder = new StringBuilder();
for (int i = 31; i >= 0; i--) {
// 依次提取出num从0位~31位的状态来
int status = ((num >> i) & 1);
builder.append(status);
}
System.out.println(builder.toString());
}
public static void main(String[] args) {
int num = 3;
printIntegerBinary(num);
char[] str = { 'b', 'b', 'z', 'k', 'o' };
int key = 0;
// 如何生成str的摘要
// 00000000000000000000000000000000
for (int i = 0; i < str.length; i++) {
char cha = str[i];
// cha = a
// cha - 'a' ? 0
// 1 << (cha - 'a') -> 1 << 0
key = key | (1 << (cha - 'a'));
}
printIntegerBinary(key);
int possibilities = 5;
int strMaxSize = 10;
int arrMaxSize = 100;
int testTimes = 500000;
System.out.println("test begin, test time : " + testTimes);
for (int i = 0; i < testTimes; i++) {
String[] arr = getRandomStringArray(possibilities, strMaxSize, arrMaxSize);
int ans1 = types1(arr);
int ans2 = types2(arr);
if (ans1 != ans2) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,77 +0,0 @@
package class020;
public class Code03_LongestNoRepeatSubstring {
/*
* a~zstr
*
*/
public static int lnrs1(String s) {
if (s == null || s.length() == 0) {
return 0;
}
char[] str = s.toCharArray();
int N = str.length;
int max = 0;
for (int i = 0; i < N; i++) {
boolean[] set = new boolean[26];
for (int j = i; j < N; j++) {
if (set[str[j] - 'a']) {
break;
}
set[str[j] - 'a'] = true;
max = Math.max(max, j - i + 1);
}
}
return max;
}
public static int lnrs2(String s) {
if (s == null || s.length() == 0) {
return 0;
}
char[] str = s.toCharArray();
int N = str.length;
int[] last = new int[26];
for (int i = 0; i < 26; i++) {
last[i] = -1;
}
last[str[0] - 'a'] = 0;
int max = 1;
int preMaxLen = 1;
for (int i = 1; i < N; i++) {
preMaxLen = Math.min(i - last[str[i] - 'a'], preMaxLen + 1);
max = Math.max(max, preMaxLen);
last[str[i] - 'a'] = i;
}
return max;
}
// for test
public static String getRandomString(int possibilities, int maxSize) {
char[] ans = new char[(int) (Math.random() * maxSize) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (char) ((int) (Math.random() * possibilities) + 'a');
}
return String.valueOf(ans);
}
public static void main(String[] args) {
int possibilities = 26;
int strMaxSize = 100;
int testTimes = 1000000;
System.out.println("test begin, test time : " + testTimes);
for (int i = 0; i < testTimes; i++) {
String str = getRandomString(possibilities, strMaxSize);
int ans1 = lnrs1(str);
int ans2 = lnrs2(str);
if (ans1 != ans2) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,133 +0,0 @@
package class020;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
public class Code04_CoverMax {
public static int maxCover1(int[][] lines) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < lines.length; i++) {
min = Math.min(min, lines[i][0]);
max = Math.max(max, lines[i][1]);
}
int cover = 0;
for (double p = min + 0.5; p < max; p += 1) {
int cur = 0;
for (int i = 0; i < lines.length; i++) {
if (lines[i][0] < p && lines[i][1] > p) {
cur++;
}
}
cover = Math.max(cover, cur);
}
return cover;
}
public static int maxCover2(int[][] m) {
Line[] lines = new Line[m.length];
for (int i = 0; i < m.length; i++) {
lines[i] = new Line(m[i][0], m[i][1]);
}
Arrays.sort(lines, new StartComparator());
// lines
//
PriorityQueue<Integer> heap = new PriorityQueue<>();
int max = 0;
for (int i = 0; i < lines.length; i++) {
// lines[i] -> cur 在黑盒中,把<=cur.start 东西都弹出
while (!heap.isEmpty() && heap.peek() <= lines[i].start) {
heap.poll();
}
heap.add(lines[i].end);
max = Math.max(max, heap.size());
}
return max;
}
public static class Line {
public int start;
public int end;
public Line(int s, int e) {
start = s;
end = e;
}
}
public static class EndComparator implements Comparator<Line> {
@Override
public int compare(Line o1, Line o2) {
return o1.end - o2.end;
}
}
// for test
public static int[][] generateLines(int N, int L, int R) {
int size = (int) (Math.random() * N) + 1;
int[][] ans = new int[size][2];
for (int i = 0; i < size; i++) {
int a = L + (int) (Math.random() * (R - L + 1));
int b = L + (int) (Math.random() * (R - L + 1));
if (a == b) {
b = a + 1;
}
ans[i][0] = Math.min(a, b);
ans[i][1] = Math.max(a, b);
}
return ans;
}
public static class StartComparator implements Comparator<Line> {
@Override
public int compare(Line o1, Line o2) {
return o1.start - o2.start;
}
}
public static void main(String[] args) {
Line l1 = new Line(4, 9);
Line l2 = new Line(1, 4);
Line l3 = new Line(7, 15);
Line l4 = new Line(2, 4);
Line l5 = new Line(4, 6);
Line l6 = new Line(3, 7);
// 底层堆结构heap
PriorityQueue<Line> heap = new PriorityQueue<>(new StartComparator());
heap.add(l1);
heap.add(l2);
heap.add(l3);
heap.add(l4);
heap.add(l5);
heap.add(l6);
while (!heap.isEmpty()) {
Line cur = heap.poll();
System.out.println(cur.start + "," + cur.end);
}
System.out.println("test begin");
int N = 100;
int L = 0;
int R = 200;
int testTimes = 200000;
for (int i = 0; i < testTimes; i++) {
int[][] lines = generateLines(N, L, R);
int ans1 = maxCover1(lines);
int ans2 = maxCover2(lines);
if (ans1 != ans2) {
System.out.println("Oops!");
}
}
System.out.println("test end");
}
}

@ -1,60 +0,0 @@
package class020;
public class Code05_MakeNo {
// 生成长度为size的达标数组
// 达标:对于任意的 i<k<j满足 [i] + [j] != [k] * 2
public static int[] makeNo(int size) {
if (size == 1) {
return new int[] { 1 };
}
// size
// 一半长达标来
// 7 : 4
// 8 : 4
// [4个奇数] [3个偶]
int halfSize = (size + 1) / 2;
int[] base = makeNo(halfSize);
// base -> 等长奇数达标来
// base -> 等长偶数达标来
int[] ans = new int[size];
int index = 0;
for(; index < halfSize;index++) {
ans[index] = base[index] * 2 + 1;
}
for(int i = 0 ;index < size;index++,i++) {
ans[index] = base[i] * 2;
}
return ans;
}
// 检验函数
public static boolean isValid(int[] arr) {
int N = arr.length;
for (int i = 0; i < N; i++) {
for (int k = i + 1; k < N; k++) {
for (int j = k + 1; j < N; j++) {
if (arr[i] + arr[j] == 2 * arr[k]) {
return false;
}
}
}
}
return true;
}
public static void main(String[] args) {
System.out.println("test begin");
for (int N = 1; N < 1000; N++) {
int[] arr = makeNo(N);
if (!isValid(arr)) {
System.out.println("Oops!");
}
}
System.out.println("test end");
System.out.println(isValid(makeNo(1042)));
System.out.println(isValid(makeNo(2981)));
}
}

@ -1,17 +0,0 @@
package class021;
public class Code01_SwapWithoutTmp {
public static void main(String[] args) {
int a = 123;
int b = -898121;
System.out.println(a);
System.out.println(b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println(a);
System.out.println(b);
}
}

@ -1,55 +0,0 @@
package class021;
public class Code02_GetMax {
// 输入参数n一定要保证n不是1就是0
// n == 0 -> 1
// n == 1 -> 0
public static int flip(int n) {
return n ^ 1;
}
// 输入参数n可以是任何一个整数
// 如果n是非负数返回1(int)
// 如果n是负数返回0(int)
public static int sign(int n) {
return flip((n >> 31) & 1);
}
// a和b中谁大返回谁
public static int getMax1(int a, int b) {
int c = a - b;
int scA = sign(c); // c >= 0 scA = 1; c < 0 scA = 0
int scB = flip(scA);
return a * scA + b * scB;
}
public static int getMax2(int a, int b) {
int c = a - b; // c是a-b的差值有可能溢出也有可能不溢出
int sa = sign(a); // a的符号求出a>=0 1, a<0 0
int sb = sign(b); // b的符号求出b>=0 1, b<0 0
int sc = sign(c); // c的符号求出c>=0 1, c<0 0
// 如果a和b的符号不一样difSab == 1
// 如果a和b的符号 一样difSab == 0
int difSab = sa ^ sb;
// 如果a和b的符号一样sameSab == 1
// 如果a和b的符号不一样sameSab == 0
int sameSab = flip(difSab);
int returnA = difSab * sa + sameSab * sc;
int returnB = flip(returnA);
return a * returnA + b * returnB;
}
public static void main(String[] args) {
int a = -16;
int b = 1;
System.out.println(getMax1(a, b));
System.out.println(getMax2(a, b));
a = 2147483647;
b = -2147480000;
System.out.println(getMax1(a, b)); // wrong answer because of overflow
System.out.println(getMax2(a, b));
}
}

@ -1,71 +0,0 @@
package class021;
public class Code03_EvenTimesOddTimes {
// arr中只有一种数出现奇数次
public static void printOddTimesNum1(int[] arr) {
int eor = 0;
for (int i = 0; i < arr.length; i++) {
eor ^= arr[i];
}
System.out.println(eor);
}
// arr中有两种数出现奇数次
public static void printOddTimesNum2(int[] arr) {
int eor = 0;
for (int i = 0; i < arr.length; i++) {
eor ^= arr[i];
}
// eor = a ^ b
// eor != 0
// eor必然有一个位置上是1
// 0110010000
// 0000010000
int rightOne = eor & (~eor + 1); // 提取出最右的1
int onlyOne = 0; // e'
for (int i = 0; i < arr.length; i++) {
// arr[1] = 111100011110000
// rightOne= 000000000010000
if ((arr[i] & rightOne) != 0) {
onlyOne ^= arr[i];
}
}
System.out.println(onlyOne + " " + (eor ^ onlyOne));
}
public static int bit1counts(int N) {
int count = 0;
while (N != 0) {
int rightOne = N & ((~N) + 1);
count++;
N -= rightOne;
}
return count;
}
public static int add(int a, int b) {
int t = 0;
while (b != 0) {
t = a;
a = a ^ b;
b = ((t & b) << 1);
}
return a;
}
public static int minus(int a, int b) {
// -b ~b + 1
return add(a, add(~b, 1));
}
public static void main(String[] args) {
int[] arr1 = { 3, 3, 4, 2, 3, 1, 1, 2, 1, 3, 4, 1, 1, 1, 4, 2, 2 };
printOddTimesNum1(arr1);
int[] arr2 = { 4, 3, 4, 2, 2, 2, 4, 1, 1, 1, 3, 3, 1, 1, 1, 4, 2, 2 };
printOddTimesNum2(arr2);
}
}

@ -1,53 +0,0 @@
package class022;
public class Code01_MinSwapStep {
public static int minSteps1(String s) {
if (s == null || s.equals("")) {
return 0;
}
char[] str = s.toCharArray();
int step1 = 0;
int gi = 0;
// 想让G都放在左侧请问至少需要交换几次需要算出step1来。
for (int i = 0; i < str.length; i++) {
if (str[i] == 'G') {
step1 += i - (gi++);
}
}
int step2 = 0;
int bi = 0;
for (int i = 0; i < str.length; i++) {
if (str[i] == 'B') {
step2 += i - (bi++);
}
}
return Math.min(step1, step2);
}
public static int minSteps(String s) {
if (s == null || s.equals("")) {
return 0;
}
char[] str = s.toCharArray();
int step1 = 0;
int step2 = 0;
int gi = 0;
int bi = 0;
for (int i = 0; i < str.length; i++) {
if (str[i] == 'G') {
step1 += i - (gi++);
} else {
step2 += i - (bi++);
}
}
return Math.min(step1, step2);
}
public static void main(String[] args) {
String s = "BGGBB";
System.out.println(minSteps(s));
}
}

@ -1,42 +0,0 @@
package class022;
import java.io.File;
import java.util.Stack;
public class Code02_CountFiles {
// 注意这个函数也会统计隐藏文件
public static int getFileNumber(String folderPath) {
// File (文件夹、文件)
File root = new File(folderPath);
if (!root.isDirectory() && !root.isFile()) {
return 0;
}
if (root.isFile()) {
return 1;
}
// File 文件夹 文件 stack只放文件夹
Stack<File> stack = new Stack<>();
stack.add(root);
int files = 0;
while (!stack.isEmpty()) {
File folder = stack.pop();
for (File next : folder.listFiles()) {
if (next.isFile() && next.getName().endsWith("java")) {
files++;
}
if (next.isDirectory()) {
stack.push(next);
}
}
}
return files;
}
public static void main(String[] args) {
// 你可以自己更改目录
String path = "/Users/zuochengyun/Desktop/";
System.out.println(getFileNumber(path));
}
}

@ -1,146 +0,0 @@
package class022;
public class Code03_Cola {
/*
* 3000MS 589824KB
*
* 退10 50100
* 100305010
* m 10,50,100 a,b,cx(x10)
* 使, m 10 a 50 b
* 100 c 1 x
* 22501003504101 1100350 2505
* 8 2 1 4 3 250 8
*/
// 暴力尝试,为了验证正式方法而已
public static int right(int m, int a, int b, int c, int x) {
int[] qian = { 100, 50, 10 };
int[] zhang = { c, b, a };
int puts = 0;
while (m != 0) {
int cur = buy(qian, zhang, x);
if (cur == -1) {
return -1;
}
puts += cur;
m--;
}
return puts;
}
public static int buy(int[] qian, int[] zhang, int rest) {
int first = -1;
for (int i = 0; i < 3; i++) {
if (zhang[i] != 0) {
first = i;
break;
}
}
if (first == -1) {
return -1;
}
if (qian[first] >= rest) {
zhang[first]--;
giveRest(qian, zhang, first + 1, qian[first] - rest, 1);
return 1;
} else {
zhang[first]--;
int next = buy(qian, zhang, rest - qian[first]);
if (next == -1) {
return -1;
}
return 1 + next;
}
}
// 正式的方法
public static int putTimes(int m, int a, int b, int c, int x) {
// 0 1 2
int[] qian = { 100, 50, 10 };
int[] zhang = { c, b, a };
// 总共需要多少次投币
int puts = 0;
// 之前面值的钱还剩下多少总钱数
int preQianRest = 0;
// 之前面值的钱还剩下多少总张数
int preQianZhang = 0;
for (int i = 0; i < 3 && m != 0; i++) {
// 要用之前剩下的钱、当前面值的钱,共同买第一瓶可乐
// 之前的面值剩下多少钱是preQianRest
// 之前的面值剩下多少张是preQianZhang
// 之所以之前的面值会剩下来,一定是剩下的钱,一直攒不出一瓶可乐的单价
// 当前的面值付出一些钱+之前剩下的钱,此时有可能凑出一瓶可乐来
// 那么当前面值参与搞定第一瓶可乐需要掏出多少张呢就是curQianFirstBuyZhang
int curQianFirstBuyZhang = (x - preQianRest + qian[i] - 1) / qian[i];
if (zhang[i] >= curQianFirstBuyZhang) { // 如果之前的钱和当前面值的钱,能凑出第一瓶可乐
// 凑出来了一瓶可乐也可能存在找钱的情况,
giveRest(qian, zhang, i + 1, (preQianRest + qian[i] * curQianFirstBuyZhang) - x, 1);
puts += curQianFirstBuyZhang + preQianZhang;
zhang[i] -= curQianFirstBuyZhang;
m--;
} else { // 如果之前的钱和当前面值的钱,不能凑出第一瓶可乐
preQianRest += qian[i] * zhang[i];
preQianZhang += zhang[i];
continue;
}
// 凑出第一瓶可乐之后,当前的面值有可能能继续买更多的可乐
// 以下过程就是后续的可乐怎么用当前面值的钱来买
// 用当前面值的钱,买一瓶可乐需要几张
int curQianBuyOneColaZhang = (x + qian[i] - 1) / qian[i];
// 用当前面值的钱,一共可以搞定几瓶可乐
int curQianBuyColas = Math.min(zhang[i] / curQianBuyOneColaZhang, m);
// 用当前面值的钱,每搞定一瓶可乐,收货机会吐出多少零钱
int oneTimeRest = qian[i] * curQianBuyOneColaZhang - x;
// 每次买一瓶可乐吐出的找零总钱数是oneTimeRest
// 一共买的可乐数是curQianBuyColas所以把零钱去提升后面几种面值的硬币数
// 就是giveRest的含义
giveRest(qian, zhang, i + 1, oneTimeRest, curQianBuyColas);
// 当前面值去搞定可乐这件事,一共投了几次币
puts += curQianBuyOneColaZhang * curQianBuyColas;
// 还剩下多少瓶可乐需要去搞定,继续用后面的面值搞定去吧
m -= curQianBuyColas;
// 当前面值可能剩下若干张,要参与到后续买可乐的过程中去,
// 所以要更新preQianRest和preQianZhang
zhang[i] -= curQianBuyOneColaZhang * curQianBuyColas;
preQianRest = qian[i] * zhang[i];
preQianZhang = zhang[i];
}
return m == 0 ? puts : -1;
}
public static void giveRest(int[] qian, int[] zhang, int i, int oneTimeRest, int times) {
for (; i < 3; i++) {
zhang[i] += (oneTimeRest / qian[i]) * times;
oneTimeRest %= qian[i];
}
}
public static void main(String[] args) {
int testTime = 1000;
int zhangMax = 10;
int colaMax = 10;
int priceMax = 20;
System.out.println("如果错误会打印错误数据,否则就是正确");
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int m = (int) (Math.random() * colaMax);
int a = (int) (Math.random() * zhangMax);
int b = (int) (Math.random() * zhangMax);
int c = (int) (Math.random() * zhangMax);
int x = ((int) (Math.random() * priceMax) + 1) * 10;
int ans1 = putTimes(m, a, b, c, x);
int ans2 = right(m, a, b, c, x);
if (ans1 != ans2) {
System.out.println("int m = " + m + ";");
System.out.println("int a = " + a + ";");
System.out.println("int b = " + b + ";");
System.out.println("int c = " + c + ";");
System.out.println("int x = " + x + ";");
break;
}
}
System.out.println("test end");
}
}

@ -1,78 +0,0 @@
package class023;
import java.util.HashMap;
import java.util.Map.Entry;
public class Code01_FindHalfMajority {
public static int halfMajor(int[] arr) {
int cand = 0;
int HP = 0;
// 遍历一遍数组arr一次删掉两个不同的数谁会剩下来谁就是cand
for (int i = 0; i != arr.length; i++) {
if (HP == 0) { // 无候选
cand = arr[i];
HP = 1;
} else if (arr[i] == cand) {
HP++;
} else {
HP--;
}
}
if (HP == 0) {
System.out.println("你他妈在逗我,没水王");
return -1;
}
HP = 0;
for (int i = 0; i != arr.length; i++) {
if (arr[i] == cand) {
HP++;
}
}
return HP > arr.length / 2 ? cand : -1;
}
// for test
public static int right(int[] arr) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int cur : arr) {
if (!map.containsKey(cur)) {
map.put(cur, 0);
}
map.put(cur, map.get(cur) + 1);
}
for (Entry<Integer, Integer> entry : map.entrySet()) {
if (entry.getValue() > arr.length / 2) {
return entry.getKey();
}
}
return -1;
}
// for test
public static int[] genareteRandomArray(int len, int max) {
int[] ans = new int[(int) (Math.random() * len) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * max) + 1;
}
return ans;
}
public static void main(String[] args) {
int len = 100;
int max = 10;
int testTime = 100000;
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int[] arr = genareteRandomArray(len, max);
int ans1 = halfMajor(arr);
int ans2 = right(arr);
if (ans1 != ans2) {
System.out.println("Oops!");
break;
}
}
System.out.println("test end");
}
}

@ -1,61 +0,0 @@
package class024;
import java.util.HashMap;
public class Code01_RotateImage {
public static void rotate(int[][] matrix) {
// matrix.length == matrix[0].length
// (a,b) 左上角的点在a行b列上
int a = 0;
int b = 0;
// (a,b) 右下角的点在c行d列上
int c = matrix.length - 1;
int d = matrix[0].length - 1;
while (a < c) { // 一定是正方形,
rotateEdge(matrix, a++, b++, c--, d--);
}
}
public static void rotateEdge(int[][] m, int a, int b, int c, int d) {
int tmp = 0;
for (int i = 0; i < d - b; i++) {
tmp = m[a][b + i];
m[a][b + i] = m[c - i][b];
m[c - i][b] = m[c][d - i];
m[c][d - i] = m[a + i][d];
m[a + i][d] = tmp;
}
}
public static HashMap<Integer, Integer> map = new HashMap<>();
public static void generateMap() {
for(int i = 0 ;i < 32;i++) {
map.put(1 << i , i);
}
}
// 返回num最右侧的1在第几位
// 高 ...... 低
public static int f(int num) {
// num = 24
// num = 00000..0000011000
// 00000..0000001000
if(map.size() == 0) {
generateMap();
}
int rightOne = num & (-num); // num & (~num + 1)
return map.get(rightOne);
}
public static void main(String[] args) {
}
}

@ -1,52 +0,0 @@
package class024;
public class Code02_ZigZagPrintMatrix {
public static void printMatrixZigZag(int[][] matrix) {
// x -> (a,b) 先往右,再往下
int a = 0;
int b = 0;
// y -> (c,d) 先往下,再往右
int c = 0;
int d = 0;
// (endR, endC) 是最右下角的位置
int endR = matrix.length - 1;
int endC = matrix[0].length - 1;
// fromUp = true 斜线打印方向应该从右上走到左下
// fromUp = false 斜线打印方向应该从左下走到右上
boolean fromUp = false;
while (a != endR + 1) {
// (a,b) (c,d) 方向
printLevel(matrix, a, b, c, d, fromUp);
a = b == endC ? a + 1 : a;
b = b == endC ? b : b + 1;
d = c == endR ? d + 1 : d;
c = c == endR ? c : c + 1;
fromUp = !fromUp;
}
System.out.println();
}
public static void printLevel(int[][] m, int aRow, int aCol, int bRow, int bCol, boolean f) {
if (f) {
while (aRow != bRow + 1) {
System.out.print(m[aRow++][aCol--] + " ");
}
} else {
while (bRow != aRow - 1) {
System.out.print(m[bRow--][bCol++] + " ");
}
}
}
public static void main(String[] args) {
int[][] matrix = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 } };
printMatrixZigZag(matrix);
}
}

@ -1,46 +0,0 @@
package class024;
public class Code03_PrintStar {
public static void printStar(int N) {
int leftUp = 0;
int rightDown = N - 1;
char[][] m = new char[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
m[i][j] = ' ';
}
}
while (leftUp <= rightDown) {
set(m, leftUp, rightDown);
leftUp += 2;
rightDown -= 2;
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
System.out.print(m[i][j] + " ");
}
System.out.println();
}
}
public static void set(char[][] m, int leftUp, int rightDown) {
for (int col = leftUp; col <= rightDown; col++) {
m[leftUp][col] = '*';
}
for (int row = leftUp + 1; row <= rightDown; row++) {
m[row][rightDown] = '*';
}
for (int col = rightDown - 1; col > leftUp; col--) {
m[rightDown][col] = '*';
}
for (int row = rightDown - 1; row > leftUp + 1; row--) {
m[row][leftUp + 1] = '*';
}
}
public static void main(String[] args) {
printStar(8);
}
}

@ -1,120 +0,0 @@
package class025;
public class Code01_Water {
/*
* arrarr
* */
public static int water1(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int water = 0;
for (int i = 1; i < N - 1; i++) {
int leftMax = Integer.MIN_VALUE;
for (int j = 0; j < i; j++) {
leftMax = Math.max(leftMax, arr[j]);
}
int rightMax = Integer.MIN_VALUE;
for (int j = i + 1; j < N; j++) {
rightMax = Math.max(rightMax, arr[j]);
}
water += Math.max(Math.min(leftMax, rightMax) - arr[i], 0);
}
return water;
}
public static int water2(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int[] leftMaxs = new int[N];
leftMaxs[0] = arr[0];
for (int i = 1; i < N; i++) {
leftMaxs[i] = Math.max(leftMaxs[i - 1], arr[i]);
}
int[] rightMaxs = new int[N];
rightMaxs[N - 1] = arr[N - 1];
for (int i = N - 2; i >= 0; i--) {
rightMaxs[i] = Math.max(rightMaxs[i + 1], arr[i]);
}
int water = 0;
for (int i = 1; i < N - 1; i++) {
water += Math.max(Math.min(leftMaxs[i - 1], rightMaxs[i + 1]) - arr[i], 0);
}
return water;
}
public static int water3(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int[] rightMaxs = new int[N];
rightMaxs[N - 1] = arr[N - 1];
for (int i = N - 2; i >= 0; i--) {
rightMaxs[i] = Math.max(rightMaxs[i + 1], arr[i]);
}
int water = 0;
int leftMax = arr[0];
for (int i = 1; i < N - 1; i++) {
water += Math.max(Math.min(leftMax, rightMaxs[i + 1]) - arr[i], 0);
leftMax = Math.max(leftMax, arr[i]);
}
return water;
}
public static int water4(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int L = 1;
int leftMax = arr[0];
int R = N - 2;
int rightMax = arr[N - 1];
int water = 0;
while (L <= R) {
if (leftMax <= rightMax) {
water += Math.max(0, leftMax - arr[L]);
leftMax = Math.max(leftMax, arr[L++]);
} else {
water += Math.max(0, rightMax - arr[R]);
rightMax = Math.max(rightMax, arr[R--]);
}
}
return water;
}
// for test
public static int[] generateRandomArray(int len, int value) {
int[] ans = new int[(int) (Math.random() * len) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * value) + 1;
}
return ans;
}
public static void main(String[] args) {
int len = 100;
int value = 200;
int testTimes = 100000;
System.out.println("test begin");
for (int i = 0; i < testTimes; i++) {
int[] arr = generateRandomArray(len, value);
int ans1 = water1(arr);
int ans2 = water2(arr);
int ans3 = water3(arr);
int ans4 = water4(arr);
if (ans1 != ans2 || ans3 != ans4 || ans1 != ans3) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,134 +0,0 @@
package class025;
public class Code02_RandToRand {
// 此函数只能用,不能修改
// 等概率返回1~5
public static int f() {
return (int) (Math.random() * 5) + 1;
}
// 等概率得到0和1
public static int a() {
int ans = 0;
do {
ans = f();
} while (ans == 3);
return ans < 3 ? 0 : 1;
}
// 等概率返回0~6
public static int b() {
int ans = 0;
do {
ans = (a() << 2) + (a() << 1) + a();
} while (ans == 7);
return ans;
}
// 等概率返回1~7
public static int c() {
return b() + 1;
}
// 这个结构是唯一的随机机制
// 你只能初始化并使用,不可修改
public static class RandomBox {
private final int min;
private final int max;
// 初始化时请一定不要让mi==ma
public RandomBox(int mi, int ma) {
min = mi;
max = ma;
}
// 13 ~ 17
// 13 + [0,4]
public int random() {
return min + (int) (Math.random() * (max - min + 1));
}
public int min() {
return min;
}
public int max() {
return max;
}
}
// 利用条件RandomBox如何等概率返回0和1
public static int rand01(RandomBox randomBox) {
int min = randomBox.min();
int max = randomBox.max();
// min ~ max
int size = max - min + 1;
// size是不是奇数odd 奇数
boolean odd = (size & 1) != 0;
int mid = size / 2;
int ans = 0;
do {
ans = randomBox.random() - min;
} while (odd && ans == mid);
return ans < mid ? 0 : 1;
}
// 给你一个RandomBox这是唯一能借助的随机机制
// 等概率返回from~to范围上任何一个数
// 要求from<=to
public static int random(RandomBox randomBox, int from, int to) {
if (from == to) {
return from;
}
// 3 ~ 9
// 0 ~ 6
// 0 ~ range
int range = to - from;
int num = 1;
// 求0range需要几个2进制位
while ((1 << num) - 1 < range) {
num++;
}
// 我们一共需要num位
// 最终的累加和,首先+0位上是1还是01位上是1还是02位上是1还是0...
int ans = 0;
do {
ans = 0;
for (int i = 0; i < num; i++) {
ans |= (rand01(randomBox) << i);
}
} while (ans > range);
return ans + from;
}
public static void main(String[] args) {
int[] count = new int[8]; // 0 1 2 .. 7
int testTime = 10000000;
for (int i = 0; i < testTime; i++) {
int ans = c();
count[ans]++;
}
for (int i = 0; i < 8; i++) {
System.out.println(i + " : " + count[i]);
}
// RandomBox randomBox = new RandomBox(3, 9);
// int from = 17;
// int to = 29;
// int[] ans = new int[to + 1];
// int testTime1 = 1000000;
// for (int i = 0; i < testTime1; i++) {
// ans[random(randomBox, from, to)]++;
// }
// for (int i = 0; i < ans.length; i++) {
// System.out.println(ans[i]);
// }
// System.out.println("==========");
}
}

@ -1,67 +0,0 @@
package class025;
public class Code03_EqualProbabilityRandom {
// 内部内容不可见
public static int f() {
return Math.random() < 0.8 ? 0 : 1;
}
// 等概率返回0和1
public static int g() {
int first = 0;
do {
first = f(); // 0 1
} while (first == f());
return first;
}
// 这个结构是唯一的随机机制
// 你只能初始化并使用,不可修改
public static class RandomBox {
private final double p;
// 初始化时请一定满足0 < zeroP < 1
public RandomBox(double zeroP) {
p = zeroP;
}
public int random() {
return Math.random() < p ? 0 : 1;
}
}
// 底层依赖一个以p概率返回0以1-p概率返回1的随机函数rand01p
// 如何加工出等概率返回0和1的函数
public static int rand01(RandomBox randomBox) {
int num;
do {
num = randomBox.random();
} while (num == randomBox.random());
return num;
}
public static void main(String[] args) {
int[] count = new int[2];// 0 1
for (int i = 0; i < 1000000; i++) {
int ans = g();
count[ans]++;
}
System.out.println(count[0] + " , " + count[1]);
// double zeroP = 0.88;
// RandomBox randomBox = new RandomBox(zeroP);
//
// int testTime = 10000000;
// int count = 0;
// for (int i = 0; i < testTime; i++) {
// if (rand01(randomBox) == 0) {
// count++;
// }
// }
// System.out.println((double) count / (double) testTime);
}
}

@ -1,161 +0,0 @@
package class026;
import java.util.ArrayList;
import java.util.List;
public class Code01_SubArrayMaxSum {
public static int test(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
int N = arr.length;
int max = Integer.MIN_VALUE;
for (int L = 0; L < N; L++) {
for (int R = L; R < N; R++) {
// arr[L...R]
int sum = 0;
for (int i = L; i <= R; i++) {
sum += arr[i];
}
max = Math.max(max, sum);
}
}
return max;
}
public static int dp1(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
int[] dp = new int[arr.length];
// dp[i] 子数组必须以i位置结尾的情况下能得到的最大累加和
dp[0] = arr[0];
for (int i = 1; i < arr.length; i++) {
int p1 = arr[i];
int p2 = dp[i - 1] + arr[i];
dp[i] = Math.max(p1, p2);
}
int max = Integer.MIN_VALUE;
for (int i = 0; i < dp.length; i++) {
max = Math.max(max, dp[i]);
}
return max;
}
public static int dp2(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
int preDp = arr[0];
int max = preDp;
for (int i = 1; i < arr.length; i++) {
int p1 = arr[i];
int p2 = preDp + arr[i];
int dp = Math.max(p1, p2);
max = Math.max(max, dp);
preDp = dp;
}
return max;
}
public static int maxSum(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
int cur = 0;
int max = Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
cur += arr[i];
max = Math.max(max, cur);
cur = cur < 0 ? 0 : cur;
}
return max;
}
public static int maxSum1(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
// 0结尾时候的答案
int pre = arr[0];
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
// i结尾时候的答案
pre = arr[i] + (pre > 0 ? pre : 0);
max = Math.max(max, pre);
}
return max;
}
public static List<List<Integer>> maxSum2(int[] arr) {
List<List<Integer>> ans = new ArrayList<>();
if (arr == null || arr.length == 0) {
return ans;
}
int L = 0;
int maxLen = 0;
int maxSum = Integer.MIN_VALUE;
int cur = 0;
for (int i = 0; i < arr.length; i++) {
// L...i sum
cur += arr[i];
if (cur == maxSum && (i - L + 1) == maxLen) {
List<Integer> curAns = new ArrayList<>();
curAns.add(L);
curAns.add(i);
ans.add(curAns);
}
if (cur > maxSum || (cur == maxSum && (i - L + 1) > maxLen)) {
ans.clear();
List<Integer> curAns = new ArrayList<>();
curAns.add(L);
curAns.add(i);
ans.add(curAns);
maxLen = i - L + 1;
}
maxSum = Math.max(maxSum, cur);
if (cur < 0) {
cur = 0;
L = i + 1;
}
}
return ans;
}
public static int[] generateArray(int N, int V) {
int n = (int) (Math.random() * N) + 1;
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = (int) (Math.random() * V) - (int) (Math.random() * V);
}
return arr;
}
public static void main(String[] args) {
int N = 100;
int V = 100;
int testTime = 10000;
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int[] arr = generateArray(N, V);
int ans1 = test(arr);
int ans2 = dp1(arr);
int ans3 = dp2(arr);
if (ans1 != ans2 || ans1 != ans3) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
int[] test = { 2, 2, 1, -9, 2, 3, -9, 6, -9, 2, 2, 2, -9, 2, 2, 2, -9, 1, 4, 1 };
List<List<Integer>> ans = maxSum2(test);
for (List<Integer> cur : ans) {
System.out.println("start : " + cur.get(0) + ", end : " + cur.get(1));
}
}
}

@ -1,58 +0,0 @@
package class026;
public class Code02_SubArrayMaxSumFollowUp {
public static int subSqeMaxSumNoNext(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
if (arr.length == 1) {
return arr[0];
}
int[] dp = new int[arr.length];
// dp[i] : arr[0..i]挑选,满足不相邻设定的情况下,随意挑选,最大的累加和
dp[0] = arr[0];
dp[1] = Math.max(arr[0], arr[1]);
for (int i = 2; i < arr.length; i++) {
int p1 = dp[i - 1];
int p2 = arr[i] + Math.max(dp[i - 2], 0);
dp[i] = Math.max(p1, p2);
}
return dp[arr.length - 1];
}
// 给定一个数组arr在不能取相邻数的情况下返回所有组合中的最大累加和
// 思路:
// 定义dp[i] : 表示arr[0...i]范围上,在不能取相邻数的情况下,返回所有组合中的最大累加和
// 在arr[0...i]范围上,在不能取相邻数的情况下,得到的最大累加和,可能性分类:
// 可能性 1) 选出的组合不包含arr[i]。那么dp[i] = dp[i-1]
// 比如arr[0...i] = {3,4,-4}最大累加和是不包含i位置数的时候
//
// 可能性 2) 选出的组合只包含arr[i]。那么dp[i] = arr[i]
// 比如arr[0...i] = {-3,-4,4}最大累加和是只包含i位置数的时候
//
// 可能性 3) 选出的组合包含arr[i], 且包含arr[0...i-2]范围上的累加和。那么dp[i] = arr[i] + dp[i-2]
// 比如arr[0...i] = {3,1,4}最大累加和是3和4组成的7因为相邻不能选所以i-1位置的数要跳过
//
// 综上所述dp[i] = Max { dp[i-1], arr[i] , arr[i] + dp[i-2] }
public static int maxSum(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
int N = arr.length;
if (N == 1) {
return arr[0];
}
if (N == 2) {
return Math.max(arr[0], arr[1]);
}
int[] dp = new int[N];
dp[0] = arr[0];
dp[1] = Math.max(arr[0], arr[1]);
for (int i = 2; i < N; i++) {
dp[i] = Math.max(Math.max(dp[i - 1], arr[i]), arr[i] + dp[i - 2]);
}
return dp[N - 1];
}
}

@ -1,83 +0,0 @@
package class026;
public class Code03_SubMatrixMaxSum {
public static int maxSum1(int[][] matrix) {
int n = matrix.length;
int m = matrix[0].length;
int max = Integer.MIN_VALUE;
for (int ai = 0; ai < n; ai++) {
for (int aj = 0; aj < m; aj++) {
for (int bi = ai; bi < n; bi++) {
for (int bj = aj; bj < m; bj++) {
max = Math.max(max, sum(matrix, ai, aj, bi, bj));
}
}
}
}
return max;
}
public static int sum(int[][] matrix, int ai, int aj, int bi, int bj) {
int sum = 0;
for (int i = ai; i <= bi; i++) {
for (int j = aj; j <= bj; j++) {
sum += matrix[i][j];
}
}
return sum;
}
public static int maxSum2(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return 0;
}
int max = Integer.MIN_VALUE;
int cur = 0;
int[] s = null;
for (int i = 0; i != matrix.length; i++) {
s = new int[matrix[0].length];
for (int j = i; j != matrix.length; j++) {
cur = 0;
for (int k = 0; k != s.length; k++) {
s[k] += matrix[j][k];
cur += s[k];
max = Math.max(max, cur);
cur = cur < 0 ? 0 : cur;
}
}
}
return max;
}
public static int[][] generateMatrix(int N, int M, int V) {
int n = (int) (Math.random() * N) + 1;
int m = (int) (Math.random() * M) + 1;
int[][] matrix = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
matrix[i][j] = (int) (Math.random() * V) - (int) (Math.random() * V);
}
}
return matrix;
}
public static void main(String[] args) {
int N = 20;
int M = 20;
int V = 100;
int testTime = 50000;
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int[][] matrix = generateMatrix(N, M, V);
int ans1 = maxSum1(matrix);
int ans2 = maxSum2(matrix);
if (ans1 != ans2) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,71 +0,0 @@
package class027;
public class Code01_MinSwapStep {
// 一个数组中只有两种字符'G'和'B'想让所有的G都放在左侧所有的B都放在右侧
// 但是只能在相邻字符之间进行交换操作,请问请问至少需要交换几次,
public static int minSteps1(String s) {
if (s == null || s.equals("")) {
return 0;
}
char[] str = s.toCharArray();
int step1 = 0;
int gi = 0;
for (int i = 0; i < str.length; i++) {
if (str[i] == 'G') {
step1 += i - (gi++);
}
}
int step2 = 0;
int bi = 0;
for (int i = 0; i < str.length; i++) {
if (str[i] == 'B') {
step2 += i - (bi++);
}
}
return Math.min(step1, step2);
}
public static int minSteps2(String s) {
if (s == null || s.equals("")) {
return 0;
}
char[] str = s.toCharArray();
int step1 = 0;
int step2 = 0;
int gi = 0;
int bi = 0;
for (int i = 0; i < str.length; i++) {
if (str[i] == 'G') {
step1 += i - (gi++);
} else {
step2 += i - (bi++);
}
}
return Math.min(step1, step2);
}
// 为了测试
public static String randomString(int maxLen) {
char[] str = new char[(int) (Math.random() * maxLen)];
for (int i = 0; i < str.length; i++) {
str[i] = Math.random() < 0.5 ? 'G' : 'B';
}
return String.valueOf(str);
}
public static void main(String[] args) {
int maxLen = 100;
int testTime = 1000000;
System.out.println("测试开始");
for (int i = 0; i < testTime; i++) {
String str = randomString(maxLen);
int ans1 = minSteps1(str);
int ans2 = minSteps2(str);
if (ans1 != ans2) {
System.out.println("Oops!");
}
}
System.out.println("测试结束");
}
}

@ -1,42 +0,0 @@
package class027;
import java.io.File;
import java.util.Stack;
public class Code02_CountFiles {
// 注意这个函数也会统计隐藏文件
public static int getFileNumber(String folderPath) {
File root = new File(folderPath);
if (!root.isDirectory() && !root.isFile()) {
return 0;
}
if (root.isFile()) {
return 1;
}
// File分为文件夹和文件
// 而stack只放文件夹
Stack<File> stack = new Stack<>();
stack.add(root);
int files = 0;
while (!stack.isEmpty()) {
File folder = stack.pop();
for (File next : folder.listFiles()) {
if (next.isFile()) {
files++;
}
if (next.isDirectory()) {
stack.push(next);
}
}
}
return files;
}
public static void main(String[] args) {
// 你可以自己更改目录来查看这个目录下的文件个数
String path = "/Users/zuochengyun/Desktop";
System.out.println(getFileNumber(path));
}
}

@ -1,148 +0,0 @@
package class027;
public class Code03_Cola {
/*
* 3000MS 589824KB
*
* 退10 50100
* 100305010
* m 10,50,100 a,b,cx(x10)
* 使, m 10 a 50 b
* 100 c 1 x
* 22501003504101 1100350 2505
* 8 2 1 4 3 250 8
*/
// 暴力尝试,为了验证正式方法而已
public static int right(int m, int a, int b, int c, int x) {
int[] qian = { 100, 50, 10 };
int[] zhang = { c, b, a };
int puts = 0;
while (m != 0) {
int cur = buy(qian, zhang, x);
if (cur == -1) {
return -1;
}
puts += cur;
m--;
}
return puts;
}
public static int buy(int[] qian, int[] zhang, int rest) {
int first = -1;
for (int i = 0; i < 3; i++) {
if (zhang[i] != 0) {
first = i;
break;
}
}
if (first == -1) {
return -1;
}
if (qian[first] >= rest) {
zhang[first]--;
giveRest(qian, zhang, first + 1, qian[first] - rest, 1);
return 1;
} else {
zhang[first]--;
int next = buy(qian, zhang, rest - qian[first]);
if (next == -1) {
return -1;
}
return 1 + next;
}
}
// 正式的方法
public static int putTimes(int m, int a, int b, int c, int x) {
// 0 1 2
int[] qian = { 100, 50, 10 };
int[] zhang = { c, b, a };
// 总共需要多少次投币
int puts = 0;
// 之前面值的钱还剩下多少总钱数
int preQianRest = 0;
// 之前面值的钱还剩下多少总张数
int preQianZhang = 0;
for (int i = 0; i < qian.length && m != 0; i++) {
// 要用之前剩下的钱、当前面值的钱,共同买第一瓶可乐
// 之前的面值剩下多少钱是preQianRest
// 之前的面值剩下多少张是preQianZhang
// 之所以之前的面值会剩下来,一定是剩下的钱,一直攒不出一瓶可乐的单价
// 当前的面值付出一些钱+之前剩下的钱,此时有可能凑出一瓶可乐来
// 那么当前面值参与搞定第一瓶可乐需要掏出多少张呢就是curQianFirstBuyZhang
int curQianFirstBuyZhang = (x - preQianRest + qian[i] - 1) / qian[i];
if (zhang[i] >= curQianFirstBuyZhang) { // 如果之前的钱和当前面值的钱,能凑出第一瓶可乐
// 凑出来了一瓶可乐也可能存在找钱的情况,
giveRest(qian, zhang, i + 1, (preQianRest + qian[i] * curQianFirstBuyZhang) - x, 1);
puts += curQianFirstBuyZhang + preQianZhang;
zhang[i] -= curQianFirstBuyZhang;
m--;
} else { // 如果之前的钱和当前面值的钱,不能凑出第一瓶可乐
preQianRest += qian[i] * zhang[i];
preQianZhang += zhang[i];
continue;
}
// 凑出第一瓶可乐之后,当前的面值有可能能继续买更多的可乐
// 以下过程就是后续的可乐怎么用当前面值的钱来买
// 用当前面值的钱,买一瓶可乐需要几张
int curQianBuyOneColaZhang = (x + qian[i] - 1) / qian[i];
// 用当前面值的钱,一共可以搞定几瓶可乐
int curQianBuyColas = Math.min(zhang[i] / curQianBuyOneColaZhang, m);
// 用当前面值的钱,每搞定一瓶可乐,收货机会吐出多少零钱
int oneTimeRest = qian[i] * curQianBuyOneColaZhang - x;
// 每次买一瓶可乐吐出的找零总钱数是oneTimeRest
// 一共买的可乐数是curQianBuyColas所以把零钱去提升后面几种面值的硬币数
// 就是giveRest的含义
giveRest(qian, zhang, i + 1, oneTimeRest, curQianBuyColas);
// 当前面值去搞定可乐这件事,一共投了几次币
puts += curQianBuyOneColaZhang * curQianBuyColas;
// 还剩下多少瓶可乐需要去搞定,继续用后面的面值搞定去吧
m -= curQianBuyColas;
// 当前面值可能剩下若干张,要参与到后续买可乐的过程中去,
// 所以要更新preQianRest和preQianZhang
zhang[i] -= curQianBuyOneColaZhang * curQianBuyColas;
preQianRest = qian[i] * zhang[i];
preQianZhang = zhang[i];
}
return m == 0 ? puts : -1;
}
// qian [100, 50, 10]
// zhang [ 2, 10, 5]
public static void giveRest(int[] qian, int[] zhang, int i, int oneTimeRest, int times) {
for (; i < 3; i++) {
zhang[i] += (oneTimeRest / qian[i]) * times;
oneTimeRest %= qian[i];
}
}
public static void main(String[] args) {
int testTime = 1000;
int zhangMax = 10;
int colaMax = 10;
int priceMax = 20;
System.out.println("如果错误会打印错误数据,否则就是正确");
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int m = (int) (Math.random() * colaMax);
int a = (int) (Math.random() * zhangMax);
int b = (int) (Math.random() * zhangMax);
int c = (int) (Math.random() * zhangMax);
int x = ((int) (Math.random() * priceMax) + 1) * 10;
int ans1 = putTimes(m, a, b, c, x);
int ans2 = right(m, a, b, c, x);
if (ans1 != ans2) {
System.out.println("int m = " + m + ";");
System.out.println("int a = " + a + ";");
System.out.println("int b = " + b + ";");
System.out.println("int c = " + c + ";");
System.out.println("int x = " + x + ";");
break;
}
}
System.out.println("test end");
}
}

@ -1,93 +0,0 @@
package class028;
public class Code01_RotateString {
public static String rotate1(String s, int leftSize) {
if (leftSize <= 0 || leftSize >= s.length()) {
return s;
}
return process1(s.toCharArray(), 0, leftSize - 1, s.length() - 1);
}
public static String process1(char[] str, int L, int M, int R) {
reverse(str, L, M);
reverse(str, M + 1, R);
reverse(str, L, R);
return String.valueOf(str);
}
public static void reverse(char[] str, int L, int R) {
while (L < R) {
char tmp = str[L];
str[L++] = str[R];
str[R--] = tmp;
}
}
public static String rotate2(String s, int leftSize) {
if (leftSize <= 0 || leftSize >= s.length()) {
return s;
}
char[] str = s.toCharArray();
int L = 0;
int R = str.length - 1;
int lpart = leftSize;
int rpart = str.length - leftSize;
int same = Math.min(lpart, rpart);
int diff = lpart - rpart;
exchange(str, L, R, same);
while (diff != 0) {
if (diff > 0) {
L += same;
lpart = diff;
} else {
R -= same;
rpart = -diff;
}
same = Math.min(lpart, rpart);
diff = lpart - rpart;
exchange(str, L, R, same);
}
return String.valueOf(str);
}
public static void exchange(char[] chas, int start, int end, int size) {
int i = end - size + 1;
char tmp = 0;
while (size-- != 0) {
tmp = chas[start];
chas[start] = chas[i];
chas[i] = tmp;
start++;
i++;
}
}
// for test
public static String getRandomString(int possibilities, int strMaxSize) {
char[] ans = new char[(int) (Math.random() * strMaxSize) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (char) ((int) (Math.random() * possibilities) + 'a');
}
return String.valueOf(ans);
}
public static void main(String[] args) {
int possibilities = 5;
int strMaxSize = 10;
int testTimes = 5000000;
System.out.println("test begin, test time : " + testTimes);
for (int i = 0; i < testTimes; i++) {
String str = getRandomString(possibilities, strMaxSize);
int leftSize = (int) (Math.random() * (str.length() + 1));
String ans1 = rotate1(str, leftSize);
String ans2 = rotate2(str, leftSize);
if (!ans1.equals(ans2)) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,111 +0,0 @@
package class028;
import java.util.HashSet;
public class Code02_HowManyTypes {
/*
* a~zString[] arr
* baacbabac
* abc arr
*
*/
public static int types1(String[] arr) {
HashSet<String> types = new HashSet<>();
for (String str : arr) {
char[] chs = str.toCharArray();
boolean[] map = new boolean[26];
for (int i = 0; i < chs.length; i++) {
map[chs[i] - 'a'] = true;
}
String key = "";
for (int i = 0; i < 26; i++) {
if (map[i]) {
key += String.valueOf((char) (i + 'a'));
}
}
types.add(key);
}
return types.size();
}
public static int types2(String[] arr) {
HashSet<Integer> types = new HashSet<>();
for (String str : arr) {
char[] chs = str.toCharArray();
int key = 0;
for (int i = 0; i < chs.length; i++) {
key = key | (1 << (chs[i] - 'a'));
}
types.add(key);
}
return types.size();
}
// for test
public static String[] getRandomStringArray(int possibilities, int strMaxSize, int arrMaxSize) {
String[] ans = new String[(int) (Math.random() * arrMaxSize) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = getRandomString(possibilities, strMaxSize);
}
return ans;
}
// for test
public static String getRandomString(int possibilities, int strMaxSize) {
char[] ans = new char[(int) (Math.random() * strMaxSize) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (char) ((int) (Math.random() * possibilities) + 'a');
}
return String.valueOf(ans);
}
public static void printIntegerBinary(int num) {
StringBuilder builder = new StringBuilder();
for (int i = 31; i >= 0; i--) {
// 依次提取出num从0位~31位的状态来
int status = ((num >> i) & 1);
builder.append(status);
}
System.out.println(builder.toString());
}
public static void main(String[] args) {
int num = 3;
printIntegerBinary(num);
char[] str = { 'b', 'b', 'z', 'k', 'o' };
int key = 0;
// 如何生成str的摘要
// 00000000000000000000000000000000
for (int i = 0; i < str.length; i++) {
char cha = str[i];
// cha = a
// cha - 'a' ? 0
// 1 << (cha - 'a') -> 1 << 0
key = key | (1 << (cha - 'a'));
}
printIntegerBinary(key);
int possibilities = 5;
int strMaxSize = 10;
int arrMaxSize = 100;
int testTimes = 500000;
System.out.println("test begin, test time : " + testTimes);
for (int i = 0; i < testTimes; i++) {
String[] arr = getRandomStringArray(possibilities, strMaxSize, arrMaxSize);
int ans1 = types1(arr);
int ans2 = types2(arr);
if (ans1 != ans2) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,83 +0,0 @@
package class028;
import java.util.HashMap;
import java.util.HashSet;
public class Code03_LongestNoRepeatSubstring {
/*
* a~zstr
*
*/
public static int maxNoRepeatSubstringLen1(char[] str) {
int len = 0;
for (int L = 0; L < str.length; L++) {
for (int R = L; R < str.length; R++) {
HashSet<Character> set = new HashSet<>();
boolean noRepeat = true;
for (int i = L; i <= R; i++) {
if (set.contains(str[i])) {
noRepeat = false;
break;
}
set.add(str[i]);
}
if (noRepeat) {
int cur = R - L + 1;
len = Math.max(len, cur);
}
}
}
return len;
}
public static int maxNoRepeatSubstringLen2(char[] str) {
if (str == null || str.length == 0) {
return 0;
}
int N = str.length;
int[] dp = new int[N];
HashMap<Character, Integer> lastMap = new HashMap<>();
dp[0] = 1;
lastMap.put(str[0], 0);
int max = 1;
for (int i = 1; i < N; i++) {
int lastIndex = lastMap.containsKey(str[i]) ? lastMap.get(str[i]) : -1;
int preNo = i - 1 - dp[i - 1];
int no = Math.max(lastIndex, preNo);
int curAns = i - no;
dp[i] = curAns;
lastMap.put(str[i], i);
max = Math.max(max, dp[i]);
}
return max;
}
// for test
public static String getRandomString(int possibilities, int maxSize) {
char[] ans = new char[(int) (Math.random() * maxSize) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (char) ((int) (Math.random() * possibilities) + 'a');
}
return String.valueOf(ans);
}
public static void main(String[] args) {
int possibilities = 26;
int strMaxSize = 100;
int testTimes = 10000;
System.out.println("test begin, test time : " + testTimes);
for (int i = 0; i < testTimes; i++) {
String str = getRandomString(possibilities, strMaxSize);
int ans1 = maxNoRepeatSubstringLen1(str.toCharArray());
int ans2 = maxNoRepeatSubstringLen2(str.toCharArray());
if (ans1 != ans2) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,133 +0,0 @@
package class028;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
public class Code04_CoverMax {
public static int maxCover1(int[][] lines) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < lines.length; i++) {
min = Math.min(min, lines[i][0]);
max = Math.max(max, lines[i][1]);
}
int cover = 0;
for (double p = min + 0.5; p < max; p += 1) {
int cur = 0;
for (int i = 0; i < lines.length; i++) {
if (lines[i][0] < p && lines[i][1] > p) {
cur++;
}
}
cover = Math.max(cover, cur);
}
return cover;
}
public static int maxCover2(int[][] m) {
Line[] lines = new Line[m.length];
for (int i = 0; i < m.length; i++) {
lines[i] = new Line(m[i][0], m[i][1]);
}
Arrays.sort(lines, new StartComparator());
// lines
//
PriorityQueue<Integer> heap = new PriorityQueue<>();
int max = 0;
for (int i = 0; i < lines.length; i++) {
// lines[i] -> cur 在黑盒中,把<=cur.start 东西都弹出
while (!heap.isEmpty() && heap.peek() <= lines[i].start) {
heap.poll();
}
heap.add(lines[i].end);
max = Math.max(max, heap.size());
}
return max;
}
public static class Line {
public int start;
public int end;
public Line(int s, int e) {
start = s;
end = e;
}
}
public static class EndComparator implements Comparator<Line> {
@Override
public int compare(Line o1, Line o2) {
return o1.end - o2.end;
}
}
// for test
public static int[][] generateLines(int N, int L, int R) {
int size = (int) (Math.random() * N) + 1;
int[][] ans = new int[size][2];
for (int i = 0; i < size; i++) {
int a = L + (int) (Math.random() * (R - L + 1));
int b = L + (int) (Math.random() * (R - L + 1));
if (a == b) {
b = a + 1;
}
ans[i][0] = Math.min(a, b);
ans[i][1] = Math.max(a, b);
}
return ans;
}
public static class StartComparator implements Comparator<Line> {
@Override
public int compare(Line o1, Line o2) {
return o1.start - o2.start;
}
}
public static void main(String[] args) {
Line l1 = new Line(4, 9);
Line l2 = new Line(1, 4);
Line l3 = new Line(7, 15);
Line l4 = new Line(2, 4);
Line l5 = new Line(4, 6);
Line l6 = new Line(3, 7);
// 底层堆结构heap
PriorityQueue<Line> heap = new PriorityQueue<>(new StartComparator());
heap.add(l1);
heap.add(l2);
heap.add(l3);
heap.add(l4);
heap.add(l5);
heap.add(l6);
while (!heap.isEmpty()) {
Line cur = heap.poll();
System.out.println(cur.start + "," + cur.end);
}
System.out.println("test begin");
int N = 100;
int L = 0;
int R = 200;
int testTimes = 200000;
for (int i = 0; i < testTimes; i++) {
int[][] lines = generateLines(N, L, R);
int ans1 = maxCover1(lines);
int ans2 = maxCover2(lines);
if (ans1 != ans2) {
System.out.println("Oops!");
}
}
System.out.println("test end");
}
}

@ -1,77 +0,0 @@
package class029;
public class Code01_AppleMinBags {
public static int minBag1(int apple) {
if (apple < 0) {
return -1;
}
if (apple == 0) {
return 0;
}
// 最多的8号袋开始试
for (int max = (apple / 8); max >= 0; max--) {
int rest = apple - (max * 8);
if (rest % 6 == 0) {
return max + rest / 6;
}
}
return -1;
}
// 18 ~
// 18 ~ 25 0组 奇数 -1 偶数 3
// 26 ~ 33 1组 奇数 -1 偶数 4
// 34 ~ 41 2组 奇数 -1 偶数 5
// X
// i组 奇数 -1 偶数 i+3
// 规律解 通过
public static int minBag2(int apple) {
if (apple < 18) {
if (apple < 0) {
return -1;
}
if (apple == 0) {
return 0;
}
if (apple == 6 || apple == 8) {
return 1;
}
if (apple == 12 || apple == 14 || apple == 16) {
return 2;
}
return -1;
}
int team = (apple - 18) / 8;
return (apple & 1) == 0 ? (team + 3) : -1;
}
public static int minBagAwesome(int apple) {
if (apple < 0 || (apple & 1) != 0) {
return -1;
}
if (apple == 0) {
return 0;
}
if (apple < 18) {
if (apple == 6 || apple == 8) {
return 1;
} else if (apple == 12 || apple == 14 || apple == 16) {
return 2;
} else {
return -1;
}
} else {
return (apple - 18) / 8 + 3;
}
}
public static void main(String[] args) {
for (int apple = 0; apple <= 100; apple++) {
System.out.println(minBag1(apple) == minBag2(apple));
}
}
}

@ -1,40 +0,0 @@
package class029;
public class Code02_EatGrass {
// 当前有N份草当前轮到先手先吃然后后手再吃
// 141664...
// 返回 String "先手" "后手"
public static String winner1(int n) {
if (n < 5) {
return (n == 0 || n == 2) ? "后手" : "先手";
}
// 先手吃的草数
int eat = 1;
while (eat <= n) {
if (winner1(n - eat).equals("后手")) {
return "先手";
}
if (eat > n / 4) { // 防止溢出
break;
}
eat *= 4;
}
return "后手";
}
public static String winner2(int n) {
if (n % 5 == 0 || n % 5 == 2) {
return "后手";
} else {
return "先手";
}
}
public static void main(String[] args) {
for (int i = 0; i <= 50; i++) {
System.out.println(i + " : " + winner1(i));
}
}
}

@ -1,80 +0,0 @@
package class029;
public class Code03_MaxLeftMaxRight {
// 笨办法,但是好想
public static int solution1(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int ans = Integer.MIN_VALUE;
for (int leftEnd = 0; leftEnd < N - 1; leftEnd++) {
int leftMax = arr[0];
for (int i = 1; i <= leftEnd; i++) {
leftMax = Math.max(leftMax, arr[i]);
}
int rightMax = arr[leftEnd + 1];
for (int i = leftEnd + 2; i < N; i++) {
rightMax = Math.max(rightMax, arr[i]);
}
ans = Math.max(ans, Math.abs(leftMax - rightMax));
}
return ans;
}
// 好办法,是我们真正想测试的
public static int solution2(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int max = arr[0];
for (int i = 1; i < N; i++) {
max = Math.max(max, arr[i]);
}
return max - Math.min(arr[0], arr[N - 1]);
}
public static int[] randomArray(int maxLen, int maxValue) {
int len = (int) (Math.random() * (maxLen + 1));
int[] arr = new int[len];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * (maxValue + 1)) - (int) (Math.random() * (maxValue + 1));
}
return arr;
}
public static void main(String[] args) {
// 随机数组的最大长度
int maxLen = 6;
// 随机数组值的范围
int maxValue = 30;
// 测试次数
int testTime = 3000000;
System.out.println("如果没有错误信息打印,说明所有测试通过");
System.out.println("测试开始");
for (int i = 0; i < testTime; i++) {
// 随机得到一个数组,长度也随机,每个值也随机
int[] arr = randomArray(maxLen, maxValue);
// 用方法1跑出答案1
int ans1 = solution1(arr);
// 用方法2跑出答案2
int ans2 = solution2(arr);
// 如果答案1和答案2不一样提示出错了
if (ans1 != ans2) {
System.out.println("出错了!");
System.out.println(ans1 + " , " + ans2);
for (int k = 0; k < arr.length; k++) {
System.out.print(arr[k] + " ");
}
System.out.println();
break;
}
}
System.out.println("测试结束");
}
}

@ -1,25 +0,0 @@
package class030;
// 测试链接https://leetcode.com/problems/palindrome-number
public class Code01_IsPalindrome {
// n<0 不是回文数
public static boolean isPalindrome(int n) {
if (n < 0) {
return false;
}
int help = 1;
while (n / help >= 10) {
help *= 10;
}
while (n != 0) {
if (n / help != n % 10) {
return false;
}
n = (n % help) / 10;
help /= 100;
}
return true;
}
}

@ -1,30 +0,0 @@
package class030;
// 测试链接https://leetcode.com/problems/sqrtx
public class Code02_MySqrt {
public static int mySqrt(int x) {
if (x == 0) {
return 0;
}
if (x < 3) {
return 1;
}
long ans = 1;
long L = 1;
long R = x;
long M = 0;
// L...R 1....x
while (L <= R) {
M = (L + R) / 2;
if (M * M <= x) {
ans = M;
L = M + 1;
} else {
R = M - 1;
}
}
return (int) ans;
}
}

@ -1,51 +0,0 @@
package class030;
// 测试链接https://leetcode.com/problems/ugly-number-ii
public class Code03_UglyNumber {
public static boolean isUgly(int num) {
while (num % 2 == 0) {
num /= 2;
}
while (num % 3 == 0) {
num /= 3;
}
while (num % 5 == 0) {
num /= 5;
}
return num == 1;
}
public static int nthUglyNumber1(int n) {
int find = 0;
int num = 1;
for (; find < n; num++) {
if (isUgly(num)) {
find++;
}
}
return num - 1;
}
public static int nthUglyNumber2(int n) {
int[] ugly = new int[n + 1];
ugly[1] = 1;
int i2 = 1;
int i3 = 1;
int i5 = 1;
for (int i = 2; i <= n; i++) {
ugly[i] = Math.min(Math.min(ugly[i2] * 2, ugly[i3] * 3), ugly[i5] * 5);
if (ugly[i] == ugly[i2] * 2) {
i2++;
}
if (ugly[i] == ugly[i3] * 3) {
i3++;
}
if (ugly[i] == ugly[i5] * 5) {
i5++;
}
}
return ugly[n];
}
}

@ -1,34 +0,0 @@
package class030;
// 测试链接https://leetcode.com/problems/linked-list-cycle-ii
public class Code04_EnterLoopNode {
// 这个类不用提交
public static class ListNode {
public int val;
public ListNode next;
}
// 只提交以下的代码
public static ListNode detectCycle(ListNode head) {
if (head == null || head.next == null || head.next.next == null) {
return null;
}
ListNode slow = head.next;
ListNode fast = head.next.next;
while (slow != fast) {
if (fast.next == null || fast.next.next == null) {
return null;
}
fast = fast.next.next;
slow = slow.next;
}
fast = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}

@ -1,24 +0,0 @@
package class031;
public class Code01_SwapWithoutTmp {
public static void main(String[] args) {
int test1 = 23;
int test2 = 15;
System.out.println(test1 ^ test2);
int a = -111;
int b = 343242111;
System.out.println(a);
System.out.println(b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println(a);
System.out.println(b);
}
}

@ -1,29 +0,0 @@
package class031;
public class Code02_AddMinus {
public static int add(int a, int b) {
int t = 0;
while (b != 0) {
t = a;
a = a ^ b; // a -> a' 无进位相加信息
b = ((t & b) << 1); // b -> b' 进位信息
}
return a;
}
public static int minus(int a, int b) {
return add(a, add(~b, 1));
}
public static void main(String[] args) {
int a = 8739284;
int b = 7348472;
System.out.println(a + b);
System.out.println(add(a, b));
System.out.println(a - b);
System.out.println(minus(a, b));
}
}

@ -1,49 +0,0 @@
package class031;
public class Code03_GetMax {
// n 0或1
// 0 -> 1 1 -> 0
public static int flip(int n) {
return n ^ 1;
}
// n 任意整数
// n非负的返回1
// n负的返回0
public static int sign(int n) {
// (n >> 31) & 1 n非负的 0 n负的 1
return flip((n >> 31) & 1);
}
public static int getMax1(int a, int b) {
int c = a - b;
int scA = sign(c); // a - b >= 0 scA = 1; a - b <0 scA = 0
int scB = flip(scA); // a - b >= 0 scB = 0; a - b <0 scB = 1
return a * scA + b * scB;
}
public static int getMax2(int a, int b) {
int c = a - b;
int sa = sign(a); // a的符号非负 1 负 0
int sb = sign(b); // b的符号非负 1 负 0
int sc = sign(c); // a-b的符号非负 1 负 0
int difSab = sa ^ sb; // 如果不一样1如果一样0
int sameSab = flip(difSab);// 如果一样1如果不一样0
int returnA = difSab * sa + sameSab * sc;
int returnB = flip(returnA);
return a * returnA + b * returnB;
}
public static void main(String[] args) {
int a = -16;
int b = -19;
System.out.println(getMax1(a, b));
System.out.println(getMax2(a, b));
a = 2147483647;
b = -2147480000;
System.out.println(getMax1(a, b)); // wrong answer because of overflow
System.out.println(getMax2(a, b));
}
}

@ -1,27 +0,0 @@
package class031;
// 测试链接https://leetcode.com/problems/first-missing-positive/
public class Code04_MissingNumber {
public static int firstMissingPositive(int[] arr) {
int l = 0;
int r = arr.length;
while (l != r) {
if (arr[l] == l + 1) {
l++;
} else if (arr[l] <= l + 1 || arr[l] > r || arr[arr[l] - 1] == arr[l]) {
swap(arr, l, --r);
} else {
swap(arr, l, arr[l] - 1);
}
}
return l + 1;
}
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}

@ -1,46 +0,0 @@
package class032;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
// 测试链接https://leetcode.com/problems/binary-tree-level-order-traversal
public class Code01_BinaryTreeLevelOrderTraversal {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> ans = new ArrayList<>();
if (root == null) {
return ans;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> curAns = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode curNode = queue.poll();
curAns.add(curNode.val);
if (curNode.left != null) {
queue.add(curNode.left);
}
if (curNode.right != null) {
queue.add(curNode.right);
}
}
ans.add(curAns);
}
return ans;
}
}

@ -1,45 +0,0 @@
package class032;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
// 测试链接https://leetcode.com/problems/binary-tree-level-order-traversal-ii
public class Code01_BinaryTreeLevelOrderTraversalII {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> ans = new LinkedList<>();
if (root == null) {
return ans;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> curAns = new LinkedList<>();
for (int i = 0; i < size; i++) {
TreeNode curNode = queue.poll();
curAns.add(curNode.val);
if (curNode.left != null) {
queue.add(curNode.left);
}
if (curNode.right != null) {
queue.add(curNode.right);
}
}
ans.add(0, curAns);
}
return ans;
}
}

@ -1,74 +0,0 @@
package class032;
import java.util.HashMap;
// 测试链接https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
public class Code02_ConstructBinaryTreeFromPreorderAndInorderTraversal {
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
public static TreeNode buildTree1(int[] pre, int[] in) {
if (pre == null || in == null || pre.length != in.length) {
return null;
}
return process1(pre, 0, pre.length - 1, in, 0, in.length - 1);
}
// 只使用pre[L1...R1]这一段,作为这棵树先序遍历的结果
// 只使用in [L2...R2]这一段,作为这棵树中序遍历的结果
// 建立好这棵树,然后把头节点返回
public static TreeNode process1(int[] pre, int L1, int R1, int[] in, int L2, int R2) {
if (L1 > R1) {
return null;
}
if (L1 == R1) {
return new TreeNode(pre[L1]);
}
TreeNode head = new TreeNode(pre[L1]);
int find = L2;
while (in[find] != pre[L1]) {
find++;
}
head.left = process1(pre, L1 + 1, L1 + find - L2, in, L2, find - 1);
head.right = process1(pre, L1 + find - L2 + 1, R1, in, find + 1, R2);
return head;
}
public static TreeNode buildTree2(int[] pre, int[] in) {
if (pre == null || in == null || pre.length != in.length) {
return null;
}
HashMap<Integer, Integer> valueIndexMap = new HashMap<>();
for (int i = 0; i < in.length; i++) {
valueIndexMap.put(in[i], i);
}
return process2(pre, 0, pre.length - 1, in, 0, in.length - 1, valueIndexMap);
}
// 只使用pre[L1...R1]这一段,作为这棵树先序遍历的结果
// 只使用in [L2...R2]这一段,作为这棵树中序遍历的结果
// 建立好这棵树,然后把头节点返回
public static TreeNode process2(int[] pre, int L1, int R1, int[] in, int L2, int R2,
HashMap<Integer, Integer> valueIndexMap) {
if (L1 > R1) {
return null;
}
if (L1 == R1) {
return new TreeNode(pre[L1]);
}
TreeNode head = new TreeNode(pre[L1]);
int find = valueIndexMap.get(pre[L1]);
head.left = process2(pre, L1 + 1, L1 + find - L2, in, L2, find - 1, valueIndexMap);
head.right = process2(pre, L1 + find - L2 + 1, R1, in, find + 1, R2, valueIndexMap);
return head;
}
}

@ -1,26 +0,0 @@
package class032;
public class Code03_PaperFolding {
public static void printAllFolds(int N) {
process(1, N, true);
System.out.println();
}
// 假想中的当前节点在i层一共N层
// 假想中的当前节点凹还是凸down决定down = true 凹 down = false 凸
// 打印以假想节点为头的整棵树,中序打印
public static void process(int i, int N, boolean down) {
if (i > N) {
return;
}
process(i + 1, N, true);
System.out.print(down ? "凹 " : "凸 ");
process(i + 1, N, false);
}
public static void main(String[] args) {
int N = 4;
printAllFolds(N);
}
}

@ -1,38 +0,0 @@
package class032;
// 测试链接https://leetcode.com/problems/diameter-of-binary-tree
public class Code04_DiameterOfBinaryTree {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
}
public static int diameterOfBinaryTree(TreeNode root) {
return process(root).maxDistance;
}
public static class Info {
public int maxDistance;
public int height;
public Info(int m, int h) {
maxDistance = m;
height = h;
}
}
public static Info process(TreeNode x) {
if (x == null) {
return new Info(0, 0);
}
Info leftInfo = process(x.left);
Info rightInfo = process(x.right);
int maxDistance = Math.max(Math.max(leftInfo.maxDistance, rightInfo.maxDistance),
leftInfo.height + rightInfo.height);
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
return new Info(maxDistance, height);
}
}

@ -1,76 +0,0 @@
package class033;
import java.util.HashMap;
import java.util.Map.Entry;
public class Code01_FindHalfMajority {
public static int halfMajor(int[] arr) {
int target = 0;
int HP = 0;
for (int i = 0; i != arr.length; i++) {
if (HP == 0) {
target = arr[i];
HP = 1;
} else if (arr[i] == target) {
HP++;
} else {
HP--;
}
}
if (HP == 0) {
return -1;
}
HP = 0;
for (int i = 0; i != arr.length; i++) {
if (arr[i] == target) {
HP++;
}
}
return HP > arr.length / 2 ? target : -1;
}
// for test
public static int right(int[] arr) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int cur : arr) {
if (!map.containsKey(cur)) {
map.put(cur, 0);
}
map.put(cur, map.get(cur) + 1);
}
for (Entry<Integer, Integer> entry : map.entrySet()) {
if (entry.getValue() > arr.length / 2) {
return entry.getKey();
}
}
return -1;
}
// for test
public static int[] genareteRandomArray(int len, int max) {
int[] ans = new int[(int) (Math.random() * len) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * max) + 1;
}
return ans;
}
public static void main(String[] args) {
int len = 100;
int max = 10;
int testTime = 100000;
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int[] arr = genareteRandomArray(len, max);
int ans1 = halfMajor(arr);
int ans2 = right(arr);
if (ans1 != ans2) {
System.out.println("Oops!");
break;
}
}
System.out.println("test end");
}
}

@ -1,52 +0,0 @@
package class033;
public class Code02_RotateImage {
public static void rotate(int[][] matrix) {
int a = 0;
int b = 0;
int c = matrix.length - 1;
int d = matrix[0].length - 1;
while (a < c) {
rotateEdge(matrix, a++, b++, c--, d--);
}
}
// 在二维数组m中左上角点(a,b), 右下角点(c,d)
// 只在规定好的框上,顺时针转好
public static void rotateEdge(int[][] m, int a, int b, int c, int d) {
int tmp = 0;
for (int i = 0; i < d - b; i++) {
tmp = m[a][b + i];
m[a][b + i] = m[c - i][b];
m[c - i][b] = m[c][d - i];
m[c][d - i] = m[a + i][d];
m[a + i][d] = tmp;
}
}
public static void printMatrix(int[][] m) {
int N = m.length;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
System.out.print(m[i][j] + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
int[][] matrix = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 } };
printMatrix(matrix);
System.out.println("========");
rotate(matrix);
printMatrix(matrix);
System.out.println("========");
}
}

@ -1,48 +0,0 @@
package class033;
public class Code03_ZigZagPrintMatrix {
public static void printMatrixZigZag(int[][] m) {
// (a,b) A 先往右,再往下
int a = 0;
int b = 0;
// (c,d) B 先往下,在往右
int c = 0;
int d = 0;
int er = m.length - 1;
int ec = m[0].length - 1;
boolean fromUp = false;
while (a != er + 1) {
printLevel(m, a, b, c, d, fromUp);
// A 先往右,再往下
a = b == ec ? a + 1 : a;
b = b == ec ? b : b + 1;
// B 先往下,在往右
d = c == er ? d + 1 : d;
c = c == er ? c : c + 1;
fromUp = !fromUp;
}
}
public static void printLevel(int[][] m, int a, int b, int c, int d, boolean f) {
if (f) {
while (a != c + 1) {
System.out.print(m[a++][b--] + " ");
}
} else {
while (c != a - 1) {
System.out.print(m[c--][d++] + " ");
}
}
}
public static void main(String[] args) {
int[][] matrix = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 } };
printMatrixZigZag(matrix);
}
}

@ -1,46 +0,0 @@
package class033;
public class Code04_PrintStar {
public static void printStar(int N) {
int leftUp = 0;
int rightDown = N - 1;
char[][] m = new char[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
m[i][j] = ' ';
}
}
while (leftUp <= rightDown) {
set(m, leftUp, rightDown);
leftUp += 2;
rightDown -= 2;
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
System.out.print(m[i][j] + " ");
}
System.out.println();
}
}
public static void set(char[][] m, int leftUp, int rightDown) {
for (int col = leftUp; col <= rightDown; col++) {
m[leftUp][col] = '*';
}
for (int row = leftUp + 1; row <= rightDown; row++) {
m[row][rightDown] = '*';
}
for (int col = rightDown - 1; col > leftUp; col--) {
m[rightDown][col] = '*';
}
for (int row = rightDown - 1; row > leftUp + 1; row--) {
m[row][leftUp + 1] = '*';
}
}
public static void main(String[] args) {
printStar(8);
}
}

@ -1,118 +0,0 @@
package class034;
public class Code01_Water {
// 本题测试链接https://leetcode.com/problems/trapping-rain-water/
// 给定一个正整数数组arr把arr想象成一个直方图。返回这个直方图如果装水能装下几格水
public static int water1(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int water = 0;
for (int i = 1; i < N - 1; i++) {
int leftMax = Integer.MIN_VALUE;
for (int j = 0; j < i; j++) {
leftMax = Math.max(leftMax, arr[j]);
}
int rightMax = Integer.MIN_VALUE;
for (int j = i + 1; j < N; j++) {
rightMax = Math.max(rightMax, arr[j]);
}
water += Math.max(Math.min(leftMax, rightMax) - arr[i], 0);
}
return water;
}
public static int water2(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int[] leftMaxs = new int[N];
leftMaxs[0] = arr[0];
for (int i = 1; i < N; i++) {
leftMaxs[i] = Math.max(leftMaxs[i - 1], arr[i]);
}
int[] rightMaxs = new int[N];
rightMaxs[N - 1] = arr[N - 1];
for (int i = N - 2; i >= 0; i--) {
rightMaxs[i] = Math.max(rightMaxs[i + 1], arr[i]);
}
int water = 0;
for (int i = 1; i < N - 1; i++) {
water += Math.max(Math.min(leftMaxs[i - 1], rightMaxs[i + 1]) - arr[i], 0);
}
return water;
}
public static int water3(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int[] rightMaxs = new int[N];
rightMaxs[N - 1] = arr[N - 1];
for (int i = N - 2; i >= 0; i--) {
rightMaxs[i] = Math.max(rightMaxs[i + 1], arr[i]);
}
int water = 0;
int leftMax = arr[0];
for (int i = 1; i < N - 1; i++) {
water += Math.max(Math.min(leftMax, rightMaxs[i + 1]) - arr[i], 0);
leftMax = Math.max(leftMax, arr[i]);
}
return water;
}
public static int water4(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int N = arr.length;
int L = 1;
int leftMax = arr[0];
int R = N - 2;
int rightMax = arr[N - 1];
int water = 0;
while (L <= R) {
if (leftMax <= rightMax) {
water += Math.max(0, leftMax - arr[L]);
leftMax = Math.max(leftMax, arr[L++]);
} else {
water += Math.max(0, rightMax - arr[R]);
rightMax = Math.max(rightMax, arr[R--]);
}
}
return water;
}
// for test
public static int[] generateRandomArray(int len, int value) {
int[] ans = new int[(int) (Math.random() * len) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * value) + 1;
}
return ans;
}
public static void main(String[] args) {
int len = 100;
int value = 200;
int testTimes = 100000;
System.out.println("test begin");
for (int i = 0; i < testTimes; i++) {
int[] arr = generateRandomArray(len, value);
int ans1 = water1(arr);
int ans2 = water2(arr);
int ans3 = water3(arr);
int ans4 = water4(arr);
if (ans1 != ans2 || ans3 != ans4 || ans1 != ans3) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}

@ -1,134 +0,0 @@
package class034;
public class Code02_RandToRand {
// 此函数只能用,不能修改
// 等概率返回1~5
public static int f() {
return (int) (Math.random() * 5) + 1;
}
// 等概率得到0和1
public static int a() {
int ans = 0;
do {
ans = f();
} while (ans == 3);
return ans < 3 ? 0 : 1;
}
// 等概率返回0~6
public static int b() {
int ans = 0;
do {
ans = (a() << 2) + (a() << 1) + a();
} while (ans == 7);
return ans;
}
// 等概率返回1~7
public static int c() {
return b() + 1;
}
// 这个结构是唯一的随机机制
// 你只能初始化并使用,不可修改
public static class RandomBox {
private final int min;
private final int max;
// 初始化时请一定不要让mi==ma
public RandomBox(int mi, int ma) {
min = mi;
max = ma;
}
// 13 ~ 17
// 13 + [0,4]
public int random() {
return min + (int) (Math.random() * (max - min + 1));
}
public int min() {
return min;
}
public int max() {
return max;
}
}
// 利用条件RandomBox如何等概率返回0和1
public static int rand01(RandomBox randomBox) {
int min = randomBox.min();
int max = randomBox.max();
// min ~ max
int size = max - min + 1;
// size是不是奇数odd 奇数
boolean odd = (size & 1) != 0;
int mid = size / 2;
int ans = 0;
do {
ans = randomBox.random() - min;
} while (odd && ans == mid);
return ans < mid ? 0 : 1;
}
// 给你一个RandomBox这是唯一能借助的随机机制
// 等概率返回from~to范围上任何一个数
// 要求from<=to
public static int random(RandomBox randomBox, int from, int to) {
if (from == to) {
return from;
}
// 3 ~ 9
// 0 ~ 6
// 0 ~ range
int range = to - from;
int num = 1;
// 求0range需要几个2进制位
while ((1 << num) - 1 < range) {
num++;
}
// 我们一共需要num位
// 最终的累加和,首先+0位上是1还是01位上是1还是02位上是1还是0...
int ans = 0;
do {
ans = 0;
for (int i = 0; i < num; i++) {
ans |= (rand01(randomBox) << i);
}
} while (ans > range);
return ans + from;
}
public static void main(String[] args) {
int[] count = new int[8]; // 0 1 2 .. 7
int testTime = 10000000;
for (int i = 0; i < testTime; i++) {
int ans = c();
count[ans]++;
}
for (int i = 0; i < 8; i++) {
System.out.println(i + " : " + count[i]);
}
// RandomBox randomBox = new RandomBox(3, 9);
// int from = 17;
// int to = 29;
// int[] ans = new int[to + 1];
// int testTime1 = 1000000;
// for (int i = 0; i < testTime1; i++) {
// ans[random(randomBox, from, to)]++;
// }
// for (int i = 0; i < ans.length; i++) {
// System.out.println(ans[i]);
// }
// System.out.println("==========");
}
}

@ -1,67 +0,0 @@
package class034;
public class Code03_EqualProbabilityRandom {
// 内部内容不可见
public static int f() {
return Math.random() < 0.8 ? 0 : 1;
}
// 等概率返回0和1
public static int g() {
int first = 0;
do {
first = f(); // 0 1
} while (first == f());
return first;
}
// 这个结构是唯一的随机机制
// 你只能初始化并使用,不可修改
public static class RandomBox {
private final double p;
// 初始化时请一定满足0 < zeroP < 1
public RandomBox(double zeroP) {
p = zeroP;
}
public int random() {
return Math.random() < p ? 0 : 1;
}
}
// 底层依赖一个以p概率返回0以1-p概率返回1的随机函数rand01p
// 如何加工出等概率返回0和1的函数
public static int rand01(RandomBox randomBox) {
int num;
do {
num = randomBox.random();
} while (num == randomBox.random());
return num;
}
public static void main(String[] args) {
int[] count = new int[2];// 0 1
for (int i = 0; i < 1000000; i++) {
int ans = g();
count[ans]++;
}
System.out.println(count[0] + " , " + count[1]);
// double zeroP = 0.88;
// RandomBox randomBox = new RandomBox(zeroP);
//
// int testTime = 10000000;
// int count = 0;
// for (int i = 0; i < testTime; i++) {
// if (rand01(randomBox) == 0) {
// count++;
// }
// }
// System.out.println((double) count / (double) testTime);
}
}

@ -1,52 +0,0 @@
package class034;
public class Code04_EvenTimesOddTimes {
public static void printOddTimesNum1(int[] arr) {
int eor = 0;
for (int i = 0; i < arr.length; i++) {
eor ^= arr[i];
}
System.out.println(eor);
}
public static void printOddTimesNum2(int[] arr) {
// arr中a和b出现了奇数次其他数都是偶数次
int eor = 0;
for (int i = 0; i < arr.length; i++) {
eor ^= arr[i];
}
// eor = a ^ b
// eor != 0
// eor : 001100100
// rightOne : 000000100
int rightOne = eor & (~eor + 1);
int onlyOne = 0; // eor'
for (int i = 0; i < arr.length; i++) {
if ((arr[i] & rightOne) != 0) {
onlyOne ^= arr[i];
}
}
// eor' = a or b
System.out.println(onlyOne + " " + (eor ^ onlyOne));
}
public static int bit1counts(int N) {
int count = 0;
while (N != 0) {
int rightOne = N & ((~N) + 1);
count++;
N -= rightOne;
}
return count;
}
public static void main(String[] args) {
int[] arr1 = { 3, 3, 2, 3, 1, 1, 1, 3, 1, 1, 1 };
printOddTimesNum1(arr1);
int[] arr2 = { 4, 3, 4, 2, 2, 2, 4, 1, 1, 1, 3, 3, 1, 1, 1, 4, 2, 2 };
printOddTimesNum2(arr2);
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save