From e0c47a27e832dd6922fd4312667afc32fe0d7ea3 Mon Sep 17 00:00:00 2001 From: algorithmzuo Date: Thu, 24 Nov 2022 14:20:35 +0800 Subject: [PATCH] modify code --- .../class24/Code04_MinCoinsOnePaper.java | 8 +- .../Code01_AbsToArrayFinalLength.java | 125 ++++++++++++ .../Code02_LastStoneWeightII.java | 40 ++++ .../Code03_MinOperationsMakeSimilar.java | 47 +++++ .../Code04_SplitArrayWithSameAverage.java | 151 ++++++++++++++ .../Code05_PickBestToGetInValue.java | 191 ++++++++++++++++++ ...养的大厂算法面试题(正在直播) | 62 ++++++ 7 files changed, 622 insertions(+), 2 deletions(-) create mode 100644 算法周更班/class_2022_11_4_week/Code01_AbsToArrayFinalLength.java create mode 100644 算法周更班/class_2022_11_4_week/Code02_LastStoneWeightII.java create mode 100644 算法周更班/class_2022_11_4_week/Code03_MinOperationsMakeSimilar.java create mode 100644 算法周更班/class_2022_11_4_week/Code04_SplitArrayWithSameAverage.java create mode 100644 算法周更班/class_2022_11_4_week/Code05_PickBestToGetInValue.java diff --git a/体系学习班/class24/Code04_MinCoinsOnePaper.java b/体系学习班/class24/Code04_MinCoinsOnePaper.java index cfda95a..11ca95d 100644 --- a/体系学习班/class24/Code04_MinCoinsOnePaper.java +++ b/体系学习班/class24/Code04_MinCoinsOnePaper.java @@ -131,7 +131,7 @@ public class Code04_MinCoinsOnePaper { for (int i = N - 1; i >= 0; i--) { for (int mod = 0; mod < Math.min(aim + 1, c[i]); mod++) { // 当前面值 X - // mod mod + x mod + 2*x mod + 3 * x + // mod mod + x mod + 2*x mod + 3 * x LinkedList w = new LinkedList<>(); w.add(mod); dp[i][mod] = dp[i + 1][mod]; @@ -145,7 +145,11 @@ public class Code04_MinCoinsOnePaper { if (w.peekFirst() == overdue) { w.pollFirst(); } - dp[i][r] = dp[i + 1][w.peekFirst()] + compensate(w.peekFirst(), r, c[i]); + if (dp[i + 1][w.peekFirst()] == Integer.MAX_VALUE) { + dp[i][r] = Integer.MAX_VALUE; + } else { + dp[i][r] = dp[i + 1][w.peekFirst()] + compensate(w.peekFirst(), r, c[i]); + } } } } diff --git a/算法周更班/class_2022_11_4_week/Code01_AbsToArrayFinalLength.java b/算法周更班/class_2022_11_4_week/Code01_AbsToArrayFinalLength.java new file mode 100644 index 0000000..c54908d --- /dev/null +++ b/算法周更班/class_2022_11_4_week/Code01_AbsToArrayFinalLength.java @@ -0,0 +1,125 @@ +package class_2022_11_4_week; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +// 来自国外题目论坛 +// 给定一个非负数组arr +// 任何两个数差值的绝对值,如果arr中没有,都要加入到arr里 +// 然后新的arr继续,任何两个数差值的绝对值,如果arr中没有,都要加入到arr里 +// 一直到arr大小固定 +// 请问最终arr长度是多少 +// 1 <= arr的长度 <= 10^5 +// 0 <= arr的数值 <= 10^5 +public class Code01_AbsToArrayFinalLength { + + // 暴力方法 + // 为了验证 + public static int finalLen1(int[] arr) { + ArrayList list = new ArrayList<>(); + HashSet set = new HashSet<>(); + for (int num : arr) { + list.add(num); + set.add(num); + } + while (!finish(list, set)) + ; + return list.size(); + } + + public static boolean finish(ArrayList list, HashSet set) { + int len = list.size(); + for (int i = 0; i < len; i++) { + for (int j = i + 1; j < len; j++) { + int abs = Math.abs(list.get(i) - list.get(j)); + if (!set.contains(abs)) { + list.add(abs); + set.add(abs); + } + } + } + return len == list.size(); + } + + // 正式方法 + // 时间复杂O(N) + public static int finalLen2(int[] arr) { + int max = 0; + // 任意一个非0的值 + int gcd = 0; + for (int num : arr) { + max = Math.max(max, num); + if (num != 0) { + gcd = num; + } + } + if (gcd == 0) { // 数组中都是0 + return arr.length; + } + // 不都是0 + HashMap counts = new HashMap<>(); + for (int num : arr) { + if (num != 0) { + gcd = gcd(gcd, num); + } + counts.put(num, counts.getOrDefault(num, 0) + 1); + } + + // max / gcd + int ans = max / gcd; + ans += counts.getOrDefault(0, 0); + + boolean add = false; + // 每个数,出现的次数 + for (int key : counts.keySet()) { + if (key != 0) { + ans += counts.get(key) - 1; + } + // 3个5, 0 + // 5 5 2个 0 +1 + // 7 7 7 3个 + if (!add && counts.get(key) > 1 && !counts.containsKey(0)) { + ans++; + add = true; + } + } + return ans; + } + + // O(1) + public static int gcd(int m, int n) { + return n == 0 ? m : gcd(n, m % n); + } + + // 为了测试 + 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); + } + return ans; + } + + // 为了测试 + public static void main(String[] args) { + int N = 15; + int V = 50; + int testTime = 8000; + System.out.println("功能测试开始"); + for (int i = 0; i < testTime; i++) { + int n = (int) (Math.random() * N) + 1; + int[] arr = randomArray(n, V); + int ans1 = finalLen1(arr); + int ans2 = finalLen2(arr); + if (ans1 != ans2) { + for (int num : arr) { + System.out.print(num + " "); + } + System.out.println("出错了!"); + } + } + System.out.println("功能测试结束"); + } + +} diff --git a/算法周更班/class_2022_11_4_week/Code02_LastStoneWeightII.java b/算法周更班/class_2022_11_4_week/Code02_LastStoneWeightII.java new file mode 100644 index 0000000..594d2a8 --- /dev/null +++ b/算法周更班/class_2022_11_4_week/Code02_LastStoneWeightII.java @@ -0,0 +1,40 @@ +package class_2022_11_4_week; + +// 来自字节 +// 11.02笔试 +// leetcode原题 +// 有一堆石头,用整数数组 stones 表示 +// 其中 stones[i] 表示第 i 块石头的重量。 +// 每一回合,从中选出任意两块石头,然后将它们一起粉碎 +// 假设石头的重量分别为 x 和 y,且 x <= y +// 那么粉碎的可能结果如下: +// 如果 x == y,那么两块石头都会被完全粉碎; +// 如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。 +// 最后,最多只会剩下一块 石头 +// 返回此石头 最小的可能重量 +// 如果没有石头剩下,就返回 0 +// 测试链接 : https://leetcode.cn/problems/last-stone-weight-ii/ +public class Code02_LastStoneWeightII { + + public int lastStoneWeightII(int[] arr) { + int n = arr.length; + int sum = 0; + for (int num : arr) { + sum += num; + } + int half = sum / 2; + int[][] dp = new int[n + 1][half + 1]; + for (int i = n - 1; i >= 0; i--) { + for (int rest = 0; rest <= half; rest++) { + int p1 = dp[i + 1][rest]; + int p2 = 0; + if (arr[i] <= rest) { + p2 = arr[i] + dp[i + 1][rest - arr[i]]; + } + dp[i][rest] = Math.max(p1, p2); + } + } + return sum - dp[0][half] - dp[0][half]; + } + +} diff --git a/算法周更班/class_2022_11_4_week/Code03_MinOperationsMakeSimilar.java b/算法周更班/class_2022_11_4_week/Code03_MinOperationsMakeSimilar.java new file mode 100644 index 0000000..d2da0fc --- /dev/null +++ b/算法周更班/class_2022_11_4_week/Code03_MinOperationsMakeSimilar.java @@ -0,0 +1,47 @@ +package class_2022_11_4_week; + +import java.util.Arrays; + +// 给你两个正整数数组 nums 和 target ,两个数组长度相等。 +// 在一次操作中,你可以选择两个 不同 的下标 i 和 j , +// 其中 0 <= i, j < nums.length ,并且: +// 令 nums[i] = nums[i] + 2 且 +// 令 nums[j] = nums[j] - 2 。 +// 如果两个数组中每个元素出现的频率相等,我们称两个数组是 相似 的。 +// 请你返回将 nums 变得与 target 相似的最少操作次数。 +// 测试数据保证 nums 一定能变得与 target 相似。 +// 测试链接 : https://leetcode.cn/problems/minimum-number-of-operations-to-make-arrays-similar/ +public class Code03_MinOperationsMakeSimilar { + + public static long makeSimilar(int[] nums, int[] target) { + int n = nums.length; + int oddSize = split(nums); + split(target); + Arrays.sort(nums, 0, oddSize); + Arrays.sort(nums, oddSize, n); + Arrays.sort(target, 0, oddSize); + Arrays.sort(target, oddSize, n); + long ans = 0; + for (int i = 0; i < n; i++) { + ans += Math.abs((long) nums[i] - target[i]); + } + return ans >> 2; + } + + public static int split(int[] arr) { + int line = 0; + for (int i = 0; i < arr.length; i++) { + if ((arr[i] & 1) != 0) { + swap(arr, i, line++); + } + } + return line; + } + + public static void swap(int[] arr, int i, int j) { + int tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } + +} diff --git a/算法周更班/class_2022_11_4_week/Code04_SplitArrayWithSameAverage.java b/算法周更班/class_2022_11_4_week/Code04_SplitArrayWithSameAverage.java new file mode 100644 index 0000000..63c9b68 --- /dev/null +++ b/算法周更班/class_2022_11_4_week/Code04_SplitArrayWithSameAverage.java @@ -0,0 +1,151 @@ +package class_2022_11_4_week; + +import java.util.Arrays; + +// 给定你一个整数数组 nums +// 我们要将 nums 数组中的每个元素移动到 A 集合 或者 B 集合中 +// 使得 A 集合和 B 集合不为空,并且 average(A) == average(B) +// 如果可以完成则返回true,否则返回false。 +// 注意:对于数组 arr, average(arr) 是 arr 的所有元素的和除以 arr 长度。 +// 测试链接 : https://leetcode.cn/problems/split-array-with-same-average/ +public class Code04_SplitArrayWithSameAverage { +// +// public static int n; +// public static int sum; +// +// public static boolean can(int[] arr) { +// n = arr.length; +// if (n == 1) { +// return false; +// } +// sum = 0; +// for (int num : arr) { +// sum += num; +// } +// +// int leftSize = n / 2; +// int[] left = new int[leftSize]; +// for (int i = 0; i < leftSize; i++) { +// left[i] = arr[i]; +// } +// +// int rightSize = n - leftSize; +// int[] right = new int[leftSize]; +// for (int i = 0, j = leftSize; j < n; i++, j++) { +// right[i] = arr[j]; +// } +// +// HashSet ans1 = new HashSet<>(); +// collect(left, 0, 0, 0, ans1); +// HashSet ans2 = new HashSet<>(); +// collect(right, 0, 0, 0, ans2); +// +// +// +// // ans1 所有的指标 : 2 ^ 15 -> 3万 +// // ans2 所有的指标 : 2 ^ 15 +// +// +// +// for(int x : ans1) { // 2 ^ 15 +// // ans2 -x O(1) +// } +// +// +// // left : T1 S1 +// // right: T2 S2 +// // S1 + S2 / T1 + T2 == Sum / N +// // N * S1 - Sum * T1 == - (N * S2 - Sum * T2) +// +// } +// +// // left[i.....] X Y +// // t, s +// // ans +// public static void collect(int[] part, +// int i, int t, int s, HashSet ans) { +// if(i == part.length) { +// ans.add(n * s - sum * t); +// }else { +// collect(part, i+1, t, s, ans); +// collect(part, i+1, t+1, s + part[i], ans); +// } +// } +// +// // 左, + + public static int n; + public static int s; + public static int l; + public static int r; + public static int[] lvalues = new int[1 << 15]; + // 3000 l = 3000 + // 0...2999 + public static int[] rvalues = new int[1 << 15]; + + public static boolean splitArraySameAverage(int[] nums) { + n = nums.length; + if (n == 1) { + return false; + } + s = 0; + for (int num : nums) { + s += num; + } + l = 0; + r = 0; + int[] larr = new int[n / 2]; + int[] rarr = new int[n - larr.length]; + for (int i = 0; i < larr.length; i++) { + larr[i] = nums[i]; + } + for (int i = larr.length, j = 0; i < nums.length; i++, j++) { + rarr[j] = nums[i]; + } + // 左侧 : 收集指标的时候,不能一个数也没有 + collect(larr, true); + // 右侧 : 收集指标的时候,不能所有数都用 + collect(rarr, false); + Arrays.sort(rvalues, 0, r); + for (int i = 0; i < l; i++) { + // 左侧x -x + if (contains(-lvalues[i])) { + return true; + } + } + return false; + } + + public static void collect(int[] arr, boolean isLeft) { + process(arr, 0, 0, 0, isLeft); + } + + public static void process(int[] arr, int index, int sum, int num, boolean isLeft) { + if (index == arr.length) { + if (isLeft && num > 0) { + lvalues[l++] = s * num - n * sum; + } + if (!isLeft && num != arr.length) { + rvalues[r++] = s * num - n * sum; + } + } else { + process(arr, index + 1, sum, num, isLeft); + process(arr, index + 1, sum + arr[index], num + 1, isLeft); + } + } + + public static boolean contains(int num) { + for (int left = 0, right = r - 1, mid = 0; left <= right;) { + mid = (left + right) / 2; + if (rvalues[mid] == num) { + return true; + } else if (rvalues[mid] < num) { + left = mid + 1; + } else { + right = mid - 1; + } + } + return false; + } + +} diff --git a/算法周更班/class_2022_11_4_week/Code05_PickBestToGetInValue.java b/算法周更班/class_2022_11_4_week/Code05_PickBestToGetInValue.java new file mode 100644 index 0000000..e65121a --- /dev/null +++ b/算法周更班/class_2022_11_4_week/Code05_PickBestToGetInValue.java @@ -0,0 +1,191 @@ +package class_2022_11_4_week; + +import java.util.Arrays; + +// 来自第四届全国大学生算法设计与编程挑战赛(秋季赛) +// 给定两个长度为N的数组,a[]和b[] +// 也就是对于每个位置i来说,有a[i]和b[i]两个属性 +// i a[i] b[i] +// j a[j] b[j] +// 现在想为了i,选一个最好的j位置,搭配能得到最小的如下值: +// (a[i] + a[j]) ^ 2 + b[i] + b[j] +// 我们把这个最小的值,定义为i的最in值 +// 比如 : +// a = { 2, 3, 6, 5, 1 } +// b = { 100, 70, 20, 40, 150 } +// 0 1 2 3 4 +// 0位置和2位置搭配,可以得到最in值 : 184 +// 1位置和2位置搭配,可以得到最in值 : 171 +// 2位置和1位置搭配,可以得到最in值 : 171 +// 3位置和1位置搭配,可以得到最in值 : 174 +// 4位置和2位置搭配,可以得到最in值 : 219 +// 注意 : i位置可以和i位置(自己)搭配,并不是说i和j一定要是不同的位置 +// 返回每个位置i的最in值 +// 比如上面的例子,最后返回[184, 171, 171, 174, 219] +// 1 <= N <= 10^5 +// 1 <= a[i]、b[i] <= 10^9 +public class Code05_PickBestToGetInValue { + + // 暴力方法 + // 时间复杂度O(N^2) + // 为了测试 + public static long[] inValues1(int[] a, int[] b) { + int n = a.length; + long[] ans = new long[n]; + for (int i = 0; i < n; i++) { + long curAns = Long.MAX_VALUE; + for (int j = 0; j < n; j++) { + long cur = (long) (a[i] + a[j]) * (a[i] + a[j]) + b[i] + b[j]; + curAns = Math.min(curAns, cur); + } + ans[i] = curAns; + } + return ans; + } + + // 正式方法 + // 时间复杂度O(N*logN) + // (a[i] + a[j]) ^ 2 + b[i] + b[j] + // a[i]^2 + b[i] + 2a[i]a[j] + a[j]^2 + b[j] + // a[i] * ( a[i] + b[i]/a[i] + 2a[j] + (a[j]^2 + b[j])/a[i]) + // 令S(j) = 2a[j] + // 令T(j) = a[j]^2 + b[j] + // 那么对于i来说,就是选择j,让下面得到最小值 + // a[i] * ( a[i] + b[i]/a[i] + S(j) + T(j)/a[i]) + // 选择最小的S(j) + T(j)/a[i],就得到了答案 + // 剩下的一切都是围绕这个 + public static long[] inValues2(int[] a, int[] b) { + int n = a.length; + // i a[i] b[i] + // i s[i] t[i] + long[][] st = new long[n][2]; + for (int i = 0; i < n; i++) { + st[i][0] = 2L * a[i]; + st[i][1] = (long) a[i] * a[i] + b[i]; + } + // 只需要根据S值从大到小排序即可 + // 下面的比较器定义稍复杂,因为java里排序会严格检查传递性 + // 所以策略参考了S和T,其实只需要根据S值从大到小排序即可 + Arrays.sort(st, (x, y) -> x[0] != y[0] ? (x[0] > y[0] ? -1 : 1) : (x[1] <= y[1] ? -1 : 1)); + int[] stack = new int[n]; + int r = 0; + for (int i = 0; i < n; i++) { + // s 大 -> 小 + + long s = st[i][0]; + long t = st[i][1]; + while (r > 0 + && tail(st, stack, r) >= // 栈顶,和栈顶再下一个 ai大到什么程度,栈顶更好! + // 当前记录,当ai大到什么程度,比栈顶好 + better(st[stack[r - 1]][0], st[stack[r - 1]][1], s, t)) { + r--; + } + stack[r++] = i; + } + int[][] arr = new int[n][3]; + for (int i = 0; i < n; i++) { + arr[i][0] = i; + arr[i][1] = a[i]; + arr[i][2] = b[i]; + } + // 只需要根据a值从大到小排序即可 + // 下面的比较器定义稍复杂,排序策略参考了a和位置i,原因是: + // 因为java的系统排序会检查传递性 + // 所以只用a排序会导致java内部认为这个排序是无效的 + // 其实只需要根据a值从大到小排序即可 + Arrays.sort(arr, (x, y) -> x[1] != y[1] ? (x[1] < y[1] ? 1 : -1) : (x[0] - y[0])); + long[] ans = new long[n]; + for (int k = 0; k < n; k++) { + int i = arr[k][0]; + int ai = arr[k][1]; + int bi = arr[k][2]; + while (tail(st, stack, r) > ai) { + r--; + } + long sj = st[stack[r - 1]][0]; + long tj = st[stack[r - 1]][1]; + // a[i] * ( a[i] + b[i]/a[i] + S(j) + T(j)/a[i]) + long curAns = sj * ai + tj + (long) ai * ai + bi; + ans[i] = curAns; + } + return ans; + } + + public static int tail(long[][] st, int[] deque, int r) { + if (r == 1) { + return 1; + } + return better(st[deque[r - 2]][0], st[deque[r - 2]][1], st[deque[r - 1]][0], st[deque[r - 1]][1]); + } + + // 入参时候s1>=s2,这是一定的 + // 返回当ai大到什么值的时候,(s2+t2/ai) <= (s1+t1/ai) + // 即 : ai大到什么值的时候,后者更好 + public static int better(long s1, long t1, long s2, long t2) { + if (s1 == s2) { + return t1 <= t2 ? Integer.MAX_VALUE : 1; + } + // s1 > s2 + if (t1 >= t2) { + return 1; + } + // s1 > s2 + // t1 < t2 + long td = t2 - t1; + long sd = s1 - s2; + return (int) ((td + sd - 1) / sd); + } + + // 为了测试 + 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 boolean isSameArray(long[] arr1, long[] arr2) { + for (int i = 0; i < arr1.length; i++) { + if (arr1[i] != arr2[i]) { + return false; + } + } + return true; + } + + // 为了测试 + public static void main(String[] args) { + int N = 100; + int A = 100; + int B = 50000; + int testTime = 50000; + System.out.println("功能测试开始"); + for (int i = 0; i < testTime; i++) { + int n = (int) (Math.random() * N) + 1; + int[] a = randomArray(n, A); + int[] b = randomArray(n, B); + long[] ans1 = inValues1(a, b); + long[] ans2 = inValues2(a, b); + if (!isSameArray(ans1, ans2)) { + System.out.println("出错了!"); + } + } + System.out.println("功能测试结束"); + + System.out.println("性能测试开始"); + int n = 100000; + int v = 1000000000; + int[] a = randomArray(n, v); + int[] b = randomArray(n, v); + System.out.println("数组长度 : " + n); + System.out.println("数值范围 : " + v); + long start = System.currentTimeMillis(); + inValues2(a, b); + long end = System.currentTimeMillis(); + System.out.println("运行时间 : " + (end - start) + " 毫秒"); + System.out.println("性能测试结束"); + } + +} diff --git a/算法课堂笔记/课堂内容汇总/每周有营养的大厂算法面试题(正在直播) b/算法课堂笔记/课堂内容汇总/每周有营养的大厂算法面试题(正在直播) index 5deccb8..337870b 100644 --- a/算法课堂笔记/课堂内容汇总/每周有营养的大厂算法面试题(正在直播) +++ b/算法课堂笔记/课堂内容汇总/每周有营养的大厂算法面试题(正在直播) @@ -2464,7 +2464,69 @@ b.hello(),座位5、座位6,都是离最近人的距离最远的(3) +第049节 2022年11月第4周流行算法题目解析 +来自国外题目论坛 +给定一个非负数组arr +任何两个数差值的绝对值,如果arr中没有,都要加入到arr里 +然后新的arr继续,任何两个数差值的绝对值,如果arr中没有,都要加入到arr里 +一直到arr大小固定 +请问最终arr长度是多少 +1 <= arr的长度 <= 10^5 +0 <= arr的数值 <= 10^5 + +来自字节 +11.02笔试 +leetcode原题 +有一堆石头,用整数数组 stones 表示 +其中 stones[i] 表示第 i 块石头的重量。 +每一回合,从中选出任意两块石头,然后将它们一起粉碎 +假设石头的重量分别为 x 和 y,且 x <= y +那么粉碎的可能结果如下: +如果 x == y,那么两块石头都会被完全粉碎; +如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。 +最后,最多只会剩下一块 石头 +返回此石头 最小的可能重量 +如果没有石头剩下,就返回 0 +测试链接 : https://leetcode.cn/problems/last-stone-weight-ii/ + +给你两个正整数数组 nums 和 target ,两个数组长度相等。 +在一次操作中,你可以选择两个 不同 的下标 i 和 j , +其中 0 <= i, j < nums.length ,并且: +令 nums[i] = nums[i] + 2 且 +令 nums[j] = nums[j] - 2 。 +如果两个数组中每个元素出现的频率相等,我们称两个数组是 相似 的。 +请你返回将 nums 变得与 target 相似的最少操作次数。 +测试数据保证 nums 一定能变得与 target 相似。 +测试链接 : https://leetcode.cn/problems/minimum-number-of-operations-to-make-arrays-similar/ + +给定你一个整数数组 nums +我们要将 nums 数组中的每个元素移动到 A 集合 或者 B 集合中 +使得 A 集合和 B 集合不为空,并且 average(A) == average(B) +如果可以完成则返回true,否则返回false。 +注意:对于数组 arr, average(arr) 是 arr 的所有元素的和除以 arr 长度。 +测试链接 : https://leetcode.cn/problems/split-array-with-same-average/ + +来自第四届全国大学生算法设计与编程挑战赛(秋季赛) +给定两个长度为N的数组,a[]和b[] +也就是对于每个位置i来说,有a[i]和b[i]两个属性 +现在想为了i,选一个最好的j位置,搭配能得到最小的如下值: +(a[i] + a[j]) ^ 2 + b[i] + b[j] +我们把这个最小的值,定义为i的最in值 +比如 : +a = { 2, 3, 6, 5, 1 } +b = { 100, 70, 20, 40, 150 } + 0 1 2 3 4 +0位置和2位置搭配,可以得到最in值 : 184 +1位置和2位置搭配,可以得到最in值 : 171 +2位置和1位置搭配,可以得到最in值 : 171 +3位置和1位置搭配,可以得到最in值 : 174 +4位置和2位置搭配,可以得到最in值 : 219 +注意 : i位置可以和i位置(自己)搭配,并不是说i和j一定要是不同的位置 +返回每个位置i的最in值 +比如上面的例子,最后返回[184, 171, 171, 174, 219] +1 <= N <= 10^5 +1 <= a[i]、b[i] <= 10^9