每天来点 C 之 LeetCode 第 0004 题

259 阅读2分钟

课前叨叨

终于决定要来写点东西了,我本人并不是写 C 的,主业也不是 C。对于 C 比较感兴趣,很多地方论框架造轮子第一时间绝对不会想到 C,原因在于实在是太简单又太难了。

简单是因为语言本身太简单了,语法简单,标准库简单,没有各种容器语法糖,大部分操作又很底层,算法各种操作写起来很痛苦。

难是因为,很难用这么简单的语言来做出很复杂很安全的应用来,内存安全是一件特别复杂,并且是极难做到的事。

LeetCode 是一个很好的契机,为了学习一些算法,我们尽可以用我们很熟悉的语法来做,但是比较高级的语言为我们封装了一些东西,导致我们对某些东西,理解仅停留在很高的层面,或者说是表面上。为了督促自己写一些比较深入的 Code 和算法,从每一个细节开始,开始 LeetCode 的征程,一方面学习一些算法,一方面使自己更好的掌握 C 这个很神秘的东西。

Median of Two Sorted Arrays

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

You may assume nums1 and nums1 cannot be both empty.

Example 1:

nums1 = [1, 3]
nums2 = [2]

The median is 2.0

Example 2:

nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5

题解

求两个数组的中位数,首先第一步肯定是合并数组,然后得出数组总长度,然后对数组进行快速排序,快排的算法在这不具体实现,C 里边有具体的实现,然后算出最中间的位置的数,返回。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int cmpfunc(const void *a, const void *b) {
  return (*(signed int *)b > *(signed int *)a) ? 1 : 0;
}

double findMedianSortedArrays(int *nums1, int nums1Size, int *nums2, int nums2Size) {
  int total_length = nums1Size + nums2Size;

  int *merge = (int *)malloc(sizeof(int) * total_length);

  memcpy(merge, nums1, sizeof(int) * nums1Size);
  memcpy(merge + nums1Size, nums2, sizeof(int) * nums2Size);

  qsort(merge, total_length, sizeof(int), cmpfunc);

  double result = 0;

  if (total_length % 2 == 0) {
    result = (*(merge + total_length / 2 - 1) + *(merge + total_length / 2)) / 2.0;
  } else {
    result = *(merge + total_length / 2);
  }

  free(merge);
  return result;
}

int main(int argc, char const *argv[]) {
  int input1[] = {0, 1, 2, 3};
  int input2[] = {4, 5, 6, 7};
  printf("Input:  [[%d", input1[0]);
  for (int i = 1; i < sizeof(input1) / sizeof(int); i++) {
    printf(", %d", input1[i]);
  }
  printf("], [%d", input2[0]);
  for (int i = 1; i < sizeof(input2) / sizeof(int); i++) {
    printf(", %d", input2[i]);
  }
  printf("]]\n");
  printf("Output: %f\n", findMedianSortedArrays(input1, sizeof(input1) / sizeof(int), input2, sizeof(input2) / sizeof(int)));
  return 0;
}
gcc main.c
./a.out

memcpy 是 C 里边做内存拷贝的函数。与这个对应的有个函数叫 strcpy,是字符串拷贝,是 null-terminated 的。memcpy 做拷贝的时候需要指明复制的数据长度。

代码中其实也完全可以用 realloc 来扩充其中一个数组的内存长度,然后将另一个数组的数据复制过来,也完全 OK。

预告

  • 用 C 求线性代数中的行列式的值
  • 用 C 实现 callback
  • 用 C 实现 hashmap