面试题答案
一键面试#include <stdio.h>
#include <stdlib.h>
// 定义函数,参数为指针数组,每个指针指向一个整数数组
int* performOperations(int** arrays, int numArrays, int* lengths) {
int count = 0;
int maxSum = 0;
int* maxArray = NULL;
for (int i = 0; i < numArrays; i++) {
int hasOdd = 0;
int sum = 0;
// 检查数组中是否有奇数,并计算总和
for (int j = 0; j < lengths[i]; j++) {
if (arrays[i][j] % 2 != 0) {
hasOdd = 1;
}
sum += arrays[i][j];
}
// 如果有奇数,将数组中所有元素翻倍
if (hasOdd) {
for (int j = 0; j < lengths[i]; j++) {
arrays[i][j] *= 2;
}
}
// 统计元素值大于100的个数
for (int j = 0; j < lengths[i]; j++) {
if (arrays[i][j] > 100) {
count++;
}
}
// 找到元素总和最大的数组
if (sum > maxSum) {
maxSum = sum;
maxArray = arrays[i];
}
}
// 打印统计结果
printf("元素值大于100的个数: %d\n", count);
return maxArray;
}
时间复杂度分析
- 外层循环遍历
numArrays
次,每次循环中有三个内层循环,分别遍历数组的长度lengths[i]
。 - 第一个内层循环检查奇数,时间复杂度为 $O(\sum_{i = 0}^{numArrays - 1} lengths[i])$。
- 第二个内层循环翻倍奇数,最坏情况下(所有数组都有奇数),时间复杂度为 $O(\sum_{i = 0}^{numArrays - 1} lengths[i])$。
- 第三个内层循环统计大于100的元素,时间复杂度为 $O(\sum_{i = 0}^{numArrays - 1} lengths[i])$。
- 总体时间复杂度为 $O(\sum_{i = 0}^{numArrays - 1} lengths[i])$,如果所有数组长度相同,设为 $n$,则时间复杂度为 $O(numArrays * n)$。
空间复杂度分析
- 除了输入的数组,只使用了常数级别的额外空间,如
count
、maxSum
、maxArray
等变量。 - 空间复杂度为 $O(1)$。
优化
- 减少内层循环次数:可以在第一次遍历数组时,同时完成检查奇数、计算总和以及统计大于100的元素,这样可以将内层循环次数从3次减少到1次,在一定程度上提高效率。
#include <stdio.h>
#include <stdlib.h>
// 定义函数,参数为指针数组,每个指针指向一个整数数组
int* performOperations(int** arrays, int numArrays, int* lengths) {
int count = 0;
int maxSum = 0;
int* maxArray = NULL;
for (int i = 0; i < numArrays; i++) {
int hasOdd = 0;
int sum = 0;
// 同时检查奇数、计算总和以及统计大于100的元素
for (int j = 0; j < lengths[i]; j++) {
if (arrays[i][j] % 2 != 0) {
hasOdd = 1;
}
sum += arrays[i][j];
if (arrays[i][j] > 100) {
count++;
}
}
// 如果有奇数,将数组中所有元素翻倍
if (hasOdd) {
for (int j = 0; j < lengths[i]; j++) {
arrays[i][j] *= 2;
}
}
// 找到元素总和最大的数组
if (sum > maxSum) {
maxSum = sum;
maxArray = arrays[i];
}
}
// 打印统计结果
printf("元素值大于100的个数: %d\n", count);
return maxArray;
}
这种优化后的实现,时间复杂度依然是 $O(\sum_{i = 0}^{numArrays - 1} lengths[i])$,但实际运行效率会有所提升,因为减少了内层循环的执行次数。空间复杂度仍然为 $O(1)$。