目录
两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2 的元素。
合并两个有序数组
合并后排序
public void merge (int[] nums1, int m, int[] nums2, int n) {
System.arraycopy(nums2, 0, nums1, m, n);
Arrays.sort(nums1);
}
该函数的详细分析如下:
System.arraycopy
方法被用来将nums2
数组中的所有元素复制到nums1
数组中从下标m
开始的位置。这个操作假设nums1
数组有足够的空间来容纳所有来自nums2
的元素。也就是说,nums1
的长度至少应该是m + n
。
Arrays.sort(nums1)
调用是用来对合并后的数组进行排序。由于nums1
和nums2
原本就是有序的,这种方法虽然能够得到正确结果,但是并不是最高效的。实际上,这个排序步骤的时间复杂度是 O((m+n)log(m+n)),这不是合并两个有序数组最优的时间复杂度。
双指针
一个更高效的方法是使用双指针技术,从两个数组的末尾开始,将较大的元素依次放入 nums1
的末尾。这样,可以保持数组的有序性,而不需要进行全局排序。这种方法的时间复杂度是 O(m+n),因为每个元素只需要比较和移动一次。
public void merge(int[] nums1, int m, int[] nums2, int n) {
// 初始化两个指针的位置在两个数组的末尾
int i = m - 1;
int j = n - 1;
// 初始化另一个指针在合并后的数组的末尾
int k = m + n - 1;
// 当两个数组都还有元素时
while (i >= 0 && j >= 0) {
// 将较大的元素复制到 nums1 的末尾
if (nums1[i] > nums2[j]) {
nums1[k] = nums1[i];
i--;
} else {
nums1[k] = nums2[j];
j--;
}
k--;
}
// 如果 nums2 中还有元素未复制完,将其余的元素复制到 nums1 中
while (j >= 0) {
nums1[k] = nums2[j];
j--;
k--;
}
// 如果 nums1 中还有元素未处理完,它们已经在正确的位置上,不需要再移动
}
不再使用
Arrays.sort
方法,而是通过比较和移动,直接将元素放置在合适的位置上。
子数组最大平均数
给一个整数数组,找出平均数最大且长度为 k 的下标连续的子数组,并输出该最大平均数。
public double findMaxAverage(int[] nums, int k) {
int sum = 0;
int n = nums.length;
for (int i = 0; i < k; i++) {
sum += nums[i];
}
int maxSum = sum;
for (int i = k; i < n; i++) {
sum = sum - nums[i - k] + nums[i];
maxSum = Math.max(maxSum, sum);
}
return 1.0 * maxSum / k;
}
该函数的详细分析如下:
初始化变量
sum
为 0,用来存储当前考虑的子数组的元素和。
n
是数组nums
的长度。第一个
for
循环遍历数组nums
的前k
个元素,并计算这些元素的和,存储在sum
中。
maxSum
初始化为sum
,用来追踪遇到的最大子数组和。第二个
for
循环从数组的第k
个元素开始,到数组的末尾。在每一步中,更新sum
为考虑新的连续子数组的和。这是通过从sum
中减去滑动窗口最左边的元素nums[i - k]
并加上最右边的新元素nums[i]
来完成的。在每次更新
sum
之后,通过Math.max(maxSum, sum)
更新maxSum
为最大值。循环结束后,我们得到了所有长度为
k
的连续子数组中的最大和。最后,函数返回
maxSum / k
的结果,这是最大子数组和的平均值。由于
maxSum
和k
都是整数,因此使用1.0 * maxSum / k
来确保结果是double
类型的。
其实这个函数实现了一个称为“滑动窗口”的算法,它以 O(n) 的时间复杂度有效地找到了最大平均值的子数组。
这种方法避免了对每个可能的子数组重新计算和的低效操作,而是利用了连续子数组之间的重叠。
通过在滑动窗口中添加一个新元素的同时移除一个旧元素,可以快速更新子数组的和。