You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
4.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class_2022_09_2_week;
import java.util.Arrays;
import java.util.Comparator;
import java.util.TreeSet;
// 来自百度
// 二狗买了一些小兵玩具,和大胖一起玩
// 一共有n个小兵这n个小兵拍成一列
// 第i个小兵战斗力为hi然后他们两个开始对小兵进行排列
// 一共进行m次操作二狗每次操作选择一个数k将前k个小兵战斗力从小到大排列
// 大胖每次操作选择一个数k将前k个小兵战斗力从大到小排列
// 问所有操作结束后,排列顺序什么样
// 给定一个长度为n的数组arr表示每个小兵的战斗力
// 给定一个长度为m的数组op,
// op[i] = { k , 0 }, 表示对前k个士兵执行从小到大的操作
// op[i] = { k , 1 }, 表示对前k个士兵执行从大到小的操作
// 返回数组ans表示最终的排列
// 1 <= n, m <= 2 * 10^5
// - 10^9 <= arr[i] <= + 10^9
public class Code01_SortGame {
// 暴力方法
// 为了验证
public static int[] game1(int[] arr, int[][] op) {
int n = arr.length;
Integer[] help = new Integer[n];
for (int i = 0; i < n; i++) {
help[i] = arr[i];
}
for (int[] o : op) {
if (o[1] == 0) {
Arrays.sort(help, 0, o[0], (a, b) -> a - b);
} else {
Arrays.sort(help, 0, o[0], (a, b) -> b - a);
}
}
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
ans[i] = help[i];
}
return ans;
}
// 正式方法
// 时间复杂度O(M) + O(N*logN)
public static int[] game2(int[] arr, int[][] op) {
int n = arr.length;
int m = op.length;
int[] stack = new int[m];
int r = 0;
for (int i = 0; i < m; i++) {
while (r != 0 && op[stack[r - 1]][0] <= op[i][0]) {
r--;
}
stack[r++] = i;
}
int[] ans = new int[n];
int ansi = n - 1;
int l = 0;
for (; ansi >= op[stack[l]][0]; ansi--) {
ans[ansi] = arr[ansi];
}
TreeSet<Number> sorted = new TreeSet<>(new NumberComparator());
for (int i = 0; i < op[stack[l]][0]; i++) {
sorted.add(new Number(arr[i], i));
}
while (l != r) {
// 当前处理的指令
int[] cur = op[stack[l++]];
if (l != r) {
int[] next = op[stack[l]];
int num = cur[0] - next[0];
if (cur[1] == 0) {
for (int i = 0; i < num; i++) {
ans[ansi--] = sorted.pollLast().value;
}
} else {
for (int i = 0; i < num; i++) {
ans[ansi--] = sorted.pollFirst().value;
}
}
} else {
if (cur[1] == 0) {
while (!sorted.isEmpty()) {
ans[ansi--] = sorted.pollLast().value;
}
} else {
while (!sorted.isEmpty()) {
ans[ansi--] = sorted.pollFirst().value;
}
}
}
}
return ans;
}
public static class Number {
public int value;
public int index;
public Number(int v, int i) {
value = v;
index = i;
}
}
public static class NumberComparator implements Comparator<Number> {
@Override
public int compare(Number o1, Number o2) {
if (o1.value != o2.value) {
return o1.value - o2.value;
} else {
return o1.index - o2.index;
}
}
}
// 为了测试
public static int[] randomArray(int n, int v) {
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
ans[i] = (int) (Math.random() * v) + 1;
}
return ans;
}
// 为了测试
public static int[][] randomOp(int m, int n) {
int[][] ans = new int[m][2];
for (int i = 0; i < m; i++) {
ans[i][0] = (int) (Math.random() * (n + 1));
ans[i][1] = Math.random() < 0.5 ? 0 : 1;
}
return ans;
}
// 为了测试
public static boolean isEqual(int[] arr1, int[] arr2) {
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[] arr = { 3, 3, 7, 7, 7 };
//
// TreeSet<Number> set = new TreeSet<>(new NumberComparator());
//
// for (int i = 0; i < arr.length; i++) {
// set.add(new Number(arr[i], i));
// }
//
//// System.out.println(set.size());
//
// while(!set.isEmpty()) {
// System.out.println(set.pollLast().value);
// }
int N = 100;
int M = 100;
int V = 200;
int testTimes = 5000;
System.out.println("测试开始");
for (int i = 0; i < testTimes; i++) {
int n = (int) (Math.random() * N) + 1;
int m = (int) (Math.random() * M) + 1;
int[] arr = randomArray(n, V);
int[][] op = randomOp(m, n);
int[] ans1 = game1(arr, op);
int[] ans2 = game2(arr, op);
if (!isEqual(ans1, ans2)) {
System.out.println("出错了!");
}
}
System.out.println("测试结束");
}
}