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.

125 lines
3.0 KiB

2 years ago
package class_2022_04_1_week;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
// 来自Amazon
// 给定一个数组arr含有n个数字可能有正、有负、有0
// 给定一个正数k
// 返回所有子序列中累加和最大的前k个子序列累加和
// 假设K不大怎么算最快
public class Code07_TopMaxSubsquenceSum {
public static int[] topMaxSum1(int[] arr, int k) {
ArrayList<Integer> allAns = new ArrayList<>();
process(arr, 0, 0, allAns);
allAns.sort((a, b) -> a.compareTo(b));
int[] ans = new int[k];
for (int i = allAns.size() - 1, j = 0; j < k; i--, j++) {
ans[j] = allAns.get(i);
}
return ans;
}
public static void process(int[] arr, int index, int sum, ArrayList<Integer> ans) {
if (index == arr.length) {
ans.add(sum);
} else {
process(arr, index + 1, sum, ans);
process(arr, index + 1, sum + arr[index], ans);
}
}
public static int[] topMaxSum2(int[] arr, int k) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] >= 0) {
sum += arr[i];
} else {
arr[i] = -arr[i];
}
}
int[] ans = topMinSum(arr, k);
for (int i = 0; i < ans.length; i++) {
ans[i] = sum - ans[i];
}
return ans;
}
public static int[] topMinSum(int[] arr, int k) {
Arrays.sort(arr);
PriorityQueue<int[]> heap = new PriorityQueue<>((a, b) -> a[1] - b[1]);
heap.add(new int[] { 0, arr[0] });
int[] ans = new int[k];
for (int i = 1; i < k; i++) {
int[] cur = heap.poll();
int last = cur[0];
int sum = cur[1];
ans[i] = sum;
if (last + 1 < arr.length) {
heap.add(new int[] { last + 1, sum - arr[last] + arr[last + 1] });
heap.add(new int[] { last + 1, sum + arr[last + 1] });
}
}
return ans;
}
// 为了测试
public static int[] randomArray(int len, int value) {
int[] arr = new int[len];
for (int i = 0; i < len; i++) {
arr[i] = (int) (Math.random() * value) + 1;
}
return arr;
}
// 为了测试
public static boolean equals(int[] ans1, int[] ans2) {
if (ans1.length != ans2.length) {
return false;
}
for (int i = 0; i < ans1.length; i++) {
if (ans1[i] != ans2[i]) {
return false;
}
}
return true;
}
// 为了测试
public static void main(String[] args) {
int n = 10;
int v = 40;
int testTime = 5000;
System.out.println("测试开始");
for (int i = 0; i < testTime; i++) {
int len = (int) (Math.random() * n) + 1;
int[] arr = randomArray(len, v);
int k = (int) (Math.random() * ((1 << len) - 1)) + 1;
int[] ans1 = topMaxSum1(arr, k);
int[] ans2 = topMaxSum2(arr, k);
if (!equals(ans1, ans2)) {
System.out.println("出错了!");
System.out.print("arr : ");
for (int num : arr) {
System.out.print(num + " ");
}
System.out.println();
System.out.println("k : " + k);
for (int num : ans1) {
System.out.print(num + " ");
}
System.out.println();
for (int num : ans2) {
System.out.print(num + " ");
}
System.out.println();
break;
}
}
System.out.println("测试结束");
}
}