请用c语言实现问题:给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (m+n)) 。
时间: 2023-03-13 17:42:53 浏览: 159
首先,将两个数组合并,排序为一个新数组。然后,用两个指针分别从开头和结尾遍历新数组,当它们相遇的时候,返回中位数。下面是c语言实现的代码: int findMedian(int* nums1, int m, int* nums2, int n) {
int i, j, k;
int *arr = malloc((m+n)*sizeof(int));
for (i = 0, j = 0, k = 0; i < m && j < n; k++) {
if (nums1[i] <= nums2[j])
arr[k] = nums1[i++];
else
arr[k] = nums2[j++];
}
while (i < m)
arr[k++] = nums1[i++];
while (j < n)
arr[k++] = nums2[j++];
int median = (m + n) / 2;
if ((m + n) % 2 == 0)
return (arr[median] + arr[median - 1]) / 2;
else
return arr[median];
}
相关问题
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (m+n)) 。 c语言
解法:二分查找
题目要求时间复杂度为 O(log(m+n)),可以考虑使用二分查找。
假设我们要在两个有序数组 nums1 和 nums2 中找到第 k 小的数,我们可以分别在 nums1 和 nums2 中查找第 k/2 小的数,设其为 mid1 和 mid2,比较这两个数的大小:
- 如果 mid1 小于 mid2,则说明 nums1 中的前 k/2 个数都不是第 k 小的数,因为这些数加起来也不到 k,所以我们可以将 nums1 中的前 k/2 个数全部排除。更新 k 的值,让 k 减去 nums1 中排除的数的个数,同时让 nums1 的起始位置向后移动 k/2 个位置。
- 如果 mid1 大于 mid2,则说明 nums2 中的前 k/2 个数都不是第 k 小的数,因为这些数加起来也不到 k,所以我们可以将 nums2 中的前 k/2 个数全部排除。更新 k 的值,让 k 减去 nums2 中排除的数的个数,同时让 nums2 的起始位置向后移动 k/2 个位置。
- 如果 mid1 等于 mid2,则说明找到了第 k 小的数,直接返回 mid1 或 mid2 即可。
注意边界情况:
- 当其中一个数组的起始位置超过数组长度,说明该数组已经全部排除,直接返回另一个数组的第 k 小的数。
- 如果 k=1,则两个数组中的最小值即为第一小的数,直接返回两个数组的起始位置指向的数中的最小值。
具体实现见下面的代码:
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
int totalSize = nums1Size + nums2Size;
if (totalSize % 2 == 1) { // 总数为奇数
return findKthSmallest(nums1, nums1Size, nums2, nums2Size, totalSize / 2 + 1);
} else { // 总数为偶数
return (findKthSmallest(nums1, nums1Size, nums2, nums2Size, totalSize / 2) +
findKthSmallest(nums1, nums1Size, nums2, nums2Size, totalSize / 2 + 1)) / 2.0;
}
}
// 在 nums1 和 nums2 中查找第 k 小的数
int findKthSmallest(int* nums1, int nums1Size, int* nums2, int nums2Size, int k) {
if (nums1Size > nums2Size) { // 保证 nums1 的长度不大于 nums2 的长度
return findKthSmallest(nums2, nums2Size, nums1, nums1Size, k);
}
if (nums1Size == 0) { // nums1 数组为空
return nums2[k - 1];
}
if (k == 1) { // 找第一小的数,即两个数组中的最小值
return fmin(nums1[0], nums2[0]);
}
int mid1 = fmin(nums1Size, k / 2); // 在 nums1 中查找第 k/2 小的数
int mid2 = k - mid1; // 在 nums2 中查找第 k-mid1 小的数
if (nums1[mid1 - 1] < nums2[mid2 - 1]) { // nums1 的前 mid1 个数都不是第 k 小的数
return findKthSmallest(nums1 + mid1, nums1Size - mid1, nums2, nums2Size, k - mid1);
} else if (nums1[mid1 - 1] > nums2[mid2 - 1]) { // nums2 的前 mid2 个数都不是第 k 小的数
return findKthSmallest(nums1, nums1Size, nums2 + mid2, nums2Size - mid2, k - mid2);
} else { // 找到了第 k 小的数
return nums1[mid1 - 1];
}
}
时间复杂度分析:每次查找时,我们都可以排除掉 k/2 个数,因此最多需要查找 log(k) 次,即时间复杂度为 O(log(k))。由于 k 最大为 m+n,因此时间复杂度为 O(log(m+n))。
请用C语言编写程序解决问题:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。要求用哈希表实现。参考思路:一个简单的实现使用了两次迭代。在第一次迭代中,我们将每个元素的值和它的索引添加到表中。然后,在第二次迭代中,我们将检查每个元素所对应的目标元素(target - nums[i])是否存在于表中。注意,该目标元素不能是 nums[i]本身! 比如,给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] 输入: 第一行: 数组nums 的元素个数 第二行:逐个、依次输入nums 数组元素 第三行:输入目标值 target 输出:按照从小到大顺序输出正确的数组下标值(不是数组元素)
以下是C语言的代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int val;
int index;
struct Node *next;
} Node;
int main() {
int n, target;
scanf("%d", &n);
int *nums = (int*)malloc(sizeof(int) * n);
Node **hashTable = (Node**)calloc(10001, sizeof(Node*));
for (int i = 0; i < n; i++) {
scanf("%d", &nums[i]);
int idx = nums[i] % 10001;
Node *p = hashTable[idx];
if (p == NULL) {
hashTable[idx] = (Node*)malloc(sizeof(Node));
hashTable[idx]->val = nums[i];
hashTable[idx]->index = i;
hashTable[idx]->next = NULL;
} else {
while (p->next != NULL) {
p = p->next;
}
p->next = (Node*)malloc(sizeof(Node));
p->next->val = nums[i];
p->next->index = i;
p->next->next = NULL;
}
}
scanf("%d", &target);
for (int i = 0; i < n; i++) {
int idx = (target - nums[i]) % 10001;
Node *p = hashTable[idx];
while (p != NULL) {
if (p->val == target - nums[i] && p->index != i) {
printf("%d %d\n", i, p->index);
free(nums);
for (int j = 0; j < 10001; j++) {
Node *q = hashTable[j];
while (q != NULL) {
Node *tmp = q;
q = q->next;
free(tmp);
}
}
free(hashTable);
return 0;
}
p = p->next;
}
}
free(nums);
for (int i = 0; i < 10001; i++) {
Node *p = hashTable[i];
while (p != NULL) {
Node *tmp = p;
p = p->next;
free(tmp);
}
}
free(hashTable);
return 0;
}
```
该程序首先读入数组的元素个数和数组元素,然后使用哈希表将每个元素的值和索引添加到表中。接着读入目标值 target,并在哈希表中查找与数组中当前元素配对的元素。如果找到了,则输出它们的索引。最后释放内存并退出程序。
阅读全文