持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情
1. 题目与解析
给定两个大小相等的数组 nums1 和 nums2,nums1 相对于 nums2 的优势可以用满足 nums1[i] > nums2[i] 的索引 i 的数目来描述。
返回 nums1 的任意排列,使其相对于 nums2 的优势最大化。
输入:nums1 = [2,7,11,15], nums2 = [1,10,4,11]
输出:[2,11,7,15]
输入:nums1 = [12,24,8,32], nums2 = [13,25,32,11]
输出:[24,32,8,12]
根据题意,第一反应是通过贪心算法确定排列组合的方式:
- 升序将两个数组都排序;
- 利用双指针,由小到大的寻找比
nums2中数值大的第一个数值,填写到对应的位置; - 经过前两步,如果
num1中的所有值都已经使用了,那么就已经找到了答案解,如果num1中有部分值没有使用,那就把这些值记录下来,之后随意顺序填写到答案解空白的位置即可。
2. 题解
- 针对
num2的改造,根据我们前面的分析,我们需要在双指针比较大小的过程中完成一个对于num2中元素原来位置的寻址过程,因此需要对nums2进行简单的改造:
int len = nums1.length;
int[][] nums2List = new int[len][2];
for (int i = 0; i < len; i++) {
nums2List[i] = new int[]{nums2[i], i};
}
- 之后我们就可以针对
nums1以及改造后的nums2List进行升序排序,这里可以借助Java中的Arrays.sort()来完成:
Arrays.sort(nums1);
Arrays.sort(nums2List, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] - o2[0];
}
});
- 由于
nums1中元素有可能取值为0,为了区别出是否填入了元素,我们初始化答案解的原始数值为-1:
int[] ans = new int[len];
Arrays.fill(ans, -1);
- 之后就是对于排序后的列表进行双指针比较与答案解的初步填写:
Stack<Integer> sta = new Stack<>();
int index1 = 0, index2 = 0;
while (index1 < len && index2 < len) {
if (nums2List[index2][0] >= nums1[index1]) {
sta.push(nums1[index1]);
index1++;
continue;
}
ans[nums2List[index2][1]] = nums1[index1];
index1++;
index2++;
}
- 最后是将压入栈中的元素取出,填入答案解中还没有填写数值的位置:
for (int i = 0; i < len; i++) {
if (ans[i] == -1) {
ans[i] = sta.pop();
}
}
return ans;
总体的解如下所示:
class Solution {
public int[] advantageCount(int[] nums1, int[] nums2) {
int len = nums1.length;
int[][] nums2List = new int[len][2];
for (int i = 0; i < len; i++) {
nums2List[i] = new int[]{nums2[i], i};
}
Arrays.sort(nums1);
Arrays.sort(nums2List, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] - o2[0];
}
});
int[] ans = new int[len];
Arrays.fill(ans, -1);
Stack<Integer> sta = new Stack<>();
int index1 = 0, index2 = 0;
while (index1 < len && index2 < len) {
if (nums2List[index2][0] >= nums1[index1]) {
sta.push(nums1[index1]);
index1++;
continue;
}
ans[nums2List[index2][1]] = nums1[index1];
index1++;
index2++;
}
for (int i = 0; i < len; i++) {
if (ans[i] == -1) {
ans[i] = sta.pop();
}
}
return ans;
}
}