408王道数据结构课后代码习题(六)

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情

计划更新23王道数据结构所有课后代码习题的实现,虽然考试写的一般都是伪代码,但是强迫症的我还是全部实现了一遍,仓库在这里

  • 线性表

2.2.3, 12

image.png

  • 找重复元素,且该元素个数要超过数组的一半,所以一个数组最多只有一个主元素
  • 暴力,就是拿空间换时间,类似桶排序
  • 开一个新数组,新数组的下标对应元素值,值对应元素个数(因为数的范围是确定的)
  • 时间复杂度O(n),空间复杂度O(n)
int find_main(SqList list) {
  // 1.初始化一个默认值全为0的数组
  int tmp[list.length] = {0};

  // 2.下标对应元素值, 
  for (int i = 0; i < list.length; i++) {
    tmp[list.data[i]]++;
  }

  // 3.遍历找出主元素
  for (int i = 0; i < list.length; i++) {
    if (tmp[i] > list.length / 2 ) 
      return i;
  }

  // 4.没找到返回-1
  return -1;
}
复制代码
  • 第二种方法:我们先排好序再找主元素
  • 记录每个元素出现的次数,如果后面的数不是重复元素,就判断当前元素是否为主元素
  • 因为用了快排,时间复杂度O(nlogn),空间复杂度O(logn)
  • 总分13分,这个解最高可以拿11分,所以不要强求最优解
int find_main2(SqList list) {
  // 1.快排
  sort(list.data, list.data+list.length);

  // 2.记录每个元素出现的次数,找到主元素
  int cnt = 1;
  for (int i = 0; i < list.length - 1; i++) {
    if (list.data[i+1] == list.data[i]) {
      cnt++;
    } else {
      if (cnt > list.length / 2)
        return list.data[i];
      cnt = 1;
    }
  }
  return -1;
}
复制代码
  • 这道题考试的时候(应该大概也许)可以不写跟题目无关的排序的具体实现
  • 因为快排每次递归需要的空间是固定的,递归层数即为空间复杂度,故快排的平均空间复杂度为O(logn)
  • 快排的实现如下:
void quick_sort(int l, int r) {
  if (l == r) return; 
  
  int x = a[(l+r)/2];     // 1.枢纽元素
	
  // 2.分成两块
  int i = l-1, j= r+1;
  while (i < j) {
    while (a[++i] < x);		// 找到左边比x大的元素
    while (a[--j] > x);		// 找到右边比x小的元素
    if (i < j) swap(a[i], a[j]); 	// 互换
  }
	
  // 3.递归
  quick_sort(l, j);
  quick_sort(j+1, r);
}
复制代码
  • 最优解,对对碰
  • 因为主元素个数要超过数组的一半,它就可以抵掉所有其他元素且有剩余
  • 时间复杂度O(n),空间复杂度O(1)
int find_main3(SqList list) {
  int c, cnt = 1;
  c = list.data[0];

  // 1.选定候选主元素
  for (int i = 1; i < list.length; i++) {
    if (list.data[i] == c) cnt++;
    else {
      if (cnt > 0) {
        cnt--;
      } else {
        c = list.data[i];
        cnt = 1;
      }
    }
  }

  // 2.统计实际数量
  if (cnt > 0) {
    cnt = 0;
    for (int i = 0; i < list.length; i++)
      if (list.data[i] == c) 
        cnt++;
  }
  
  // 3.确认主元素
  if (cnt > list.length / 2) return c;
  return -1;
}
复制代码

猜你喜欢

转载自juejin.im/post/7085562643016056869