时空复杂度题目讲解

简介: 时空复杂度题目讲解

题目一


给定一个整数sum,从有N个有序元素的数组中寻找元素a,b,使得a+b的结果最接近sum,最快的平均时间复杂度是( )


作业内容

A.O(n)

B.O(n^2)

C.O(nlogn)

D.O(logn)


此题目中,数组元素有序,所以a,b两个数可以分别从开始和结尾处开始搜,根据首尾元素的和是否大于sum,决定搜索的移动,整个数组被搜索一遍,就可以得到结果,所以最好时间复杂度为n


题目二


  int** fun(int n) {
    int ** s = (int **)malloc(n * sizeof(int *));
    while(n--)
      s[n] = (int *)malloc(n * sizeof(int));
    return s;
  }


要求下面整个函数的空间复杂度


首先它定义了一个二级指针s


然后在下面 首先循环n次


每一次都创建一个指针 指向n个int大小的空间


所以说它的空间复杂度是1 +2 +3 + …+n


实际上的空间复杂度是O(n^2)


题目三


找到消失的数字


数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?


注意:本题相对书上原题稍作改动


示例 1:


输入:[3,0,1]

输出:2


示例 2:


输入:[9,6,4,2,3,5,7,0,1]

输出:8


来源:力扣(LeetCode)

链接:https://leetcode.cn/problems/missing-number-lcci


对于一个有序数组 要求我们找到其中缺失的数字


这道题目 我们至少有四种解法


解法一


我们将这个数组进行一个快速排序 然后看看每一个数字是否等于对应的i就可以


这样解法的时间复杂度是(NlogN) 空间复杂度是O(1)


代码表示如下


int cmp(const void* e1, const void* e2)
{
  return *(int*)e1 - *(int*)e2;
}
int main()
{
  int i = 0;
  int arr[] = { 0, 1, 4, 3, 7, 6, 5, 9, 8 };
  qsort(arr, 9, 4, cmp);
  for ( i = 0; i < 9; i++)
  {
    printf("%d ", arr[i]);
  }
  for ( i = 0; i < 9; i++)
  {
    if (arr[i]!=i)
    {
      printf("\n消失的数字是%d", i);
      break;
    }
  }
  return 0;
}


这样子我们就可以成功找到消失的数字啦


运行效果如下


2930b3a8575e4b2eb4a08b4e7da1b5f5.png


解法二


我们将1~sum的所有数字相加


之后再将数组中的所有元素相加


两者相减 就是消失的那个数字


此种解法的时间复杂度是O(N) 空间复杂度是O(1)


代码和表示结果如下

d0df5d4ad9644162b037cf8c2968ccd3.png


解法三


我们创建一个新数组 将这些数据依次填入数组中


哪个数组的元素未被赋值 那么消失的数字就是这个数


int  main()
{
  int i = 0;
  int arr1[10] = { 0 };
  for ( i = 0; i <= 9; i++)
  {
    arr1[i] = -1;
  }
  int arr[] = { 0, 1, 4, 3, 7, 6, 5, 9, 8 };
  for (i = 0; i < 9; i++)
  {
    int tmp = 0;
    tmp = arr[i];
    arr1[tmp] = tmp;
  }
  for ( i = 0; i < 9; i++)
  {
    if (arr1[i]==-1)
    {
      printf("消失的数字是%d", i );
      break;
    }
  }
  return 0;
}


这个解法的时间复杂度是O(N) 空间复杂度也是O(N)


解法四


我们都知道异或这个操作符 相同为0 想异为1


并且两个相同的数字异或的结果为0


0与任何数异或都等于它本身


那这样子我们的思路就很清晰了 创建一个数字ret 使用这个数字异或0~n所有数字


之后再异或数组中的所有数 这样子我们就能得到消失的数啦


int main()
{
  int ret = 0;
  int i = 0;
  int arr[] = { 0, 1, 4, 3, 7, 6, 5, 9, 8 };
  for ( i = 0; i <= 9; i++)
  {
    ret ^= i;
  }
  for ( i = 0; i < 9; i++)
  {
    ret ^= arr[i];
  }
  printf("消失的数字是%d", ret);
  return 0;
}

3e56014030f54d88913c060a8d4600ad.png


题目四


一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。


https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof


解法一


这里我们第一时间想到的是排序之后看看和前面一个数 后面一个数比较 如果不同就输出它


可惜这一题的时间复杂度要求是O(N)直接毙掉所有的排序方法


解法二


我们可以将一个数组中所有元素设置为0 然后使用数组中的数字异或它们对应大小的位数


但是这个方法要创建一个数组 空间复杂度为O(N) 毙掉


解法三


对于这个数组 我们先将整个数组进行异或得到这两个数的异或结果


然后将这个数组进行分组


注意 这里难点来了 怎么分组?


我们可以找到这个数异或结果为1的位数(说明这两个数在这个位上不同)


那么我们就按照这个位来分组 1的一组 0的一组


它们两组自身异或 就能得到两个不同的数


这两个数就是我们要找的数


int main()
{
  int nums[8] = {1, 2, 10, 4, 1, 4, 3, 3};
  int* arr = (int*)malloc(8);
  int ret = 0;
  int pos = 0;
  int i = 0;
  // 全部异或得到一个数
  for (i = 0; i < 8; i++)
  {
    ret ^= nums[i];
  }
  // 找到1的位数
  for ( i = 0; i < 32; i++)
  {
    if ((ret >> i) & 1 == 1)
    {
      pos = i;
      break;
    }
  }
  // 按照位数来分组
  int num1 = 0;
  int num2 = 0;
  for ( i = 0; i < 8; i++)
  {
    if ((nums[i] >> pos) & 1 == 1)
    {
      num1 ^= nums[i];
    }
    else
    {
      num2 ^= nums[i];
    }
  }
  // 将num1 num2放到数组中输出 
  // 这里我就直接打印了
  printf("%d %d", num1, num2);
  arr[0] = num1;
  arr[1] = num2;
  free(arr);
  arr = NULL;
  return 0;
}


运行结果如下


89fde50a3771407fbb9c26d73a8bb1ee.png


以上就是本篇博客的全部内容啦 由于博主才疏学浅 所以难免会出现纰漏 希望大佬们看到错误之后能够


不吝赐教 在评论区或者私信指正 博主一定及时修正


那么大家下期再见咯


相关文章
|
3月前
|
监控 算法
|
5月前
|
算法 C++
计算机算法设计与分析 第2章 递归与分治策略 (笔记)
计算机算法设计与分析 第2章 递归与分治策略 (笔记)
|
6月前
|
存储 算法 人工智能
【算法设计与分析】——动态规划算法
【算法设计与分析】——动态规划算法
【算法设计与分析】——动态规划算法
|
6月前
|
设计模式 算法 知识图谱
算法设计与分析(贪心法)
【1月更文挑战第1天】在分析问题是否具有最优子结构性质时,通常先设出问题的最优解,给出子问题的解一定是最优的结论。证明思路是:设原问题的最优解导出子问题的解不是最优的,然后在这个假设下可以构造出比原问题的最优解更好的解,从而导致矛盾。(一个问题能够分解成各个子问题来解决,通过各个子问题的最优解能递推到原问题的最优解,此时原问题的最优解一定包含各个子问题的最优解,这是能够采用贪心法来求解问题的关键)贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择获得,即通过一系列的逐步局部最优选择使得最终的选择方案是全局最优的。
118 1
|
机器学习/深度学习 算法
时空复杂度
时空复杂度
45 0
|
存储 算法
时空复杂度详解
我们写出来了一个算法,但是这个算法怎么样呢?
树的子结构(中等难度,好题目)
树的子结构(中等难度,好题目)
93 0
树的子结构(中等难度,好题目)
|
机器学习/深度学习 算法 Windows
快速掌握算法复杂度分析
快速掌握算法复杂度分析
129 0
快速掌握算法复杂度分析
|
算法 搜索推荐
算法与数据结构全阶班-左程云版(二)基础阶段之1.复杂度、对数器、二分法和异或运算(上)
本文主要介绍了数据结构与算法的基本概念,包括算法评价指标、复杂度、对数器、二分法和异或运算。
算法与数据结构全阶班-左程云版(二)基础阶段之1.复杂度、对数器、二分法和异或运算(上)
|
机器学习/深度学习 算法 测试技术
算法与数据结构全阶班-左程云版(二)基础阶段之1.复杂度、对数器、二分法和异或运算(下)
本文主要介绍了数据结构与算法的基本概念,包括算法评价指标、复杂度、对数器、二分法和异或运算。
算法与数据结构全阶班-左程云版(二)基础阶段之1.复杂度、对数器、二分法和异或运算(下)