复杂度练习

简介: 复杂度练习

旋转数组

消失的数字

**

1.旋转数组

给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

示例 1:

输入: nums = [1,2,3,4,5,6,7], k = 3

输出: [5,6,7,1,2,3,4]

解释:

向右轮转 1 步: [7,1,2,3,4,5,6]

向右轮转 2 步: [6,7,1,2,3,4,5]

向右轮转 3 步: [5,6,7,1,2,3,4]

示例 2:

输入:nums = [-1,-100,3,99], k = 2

输出:[3,99,-1,-100]

解释:

向右轮转 1 步: [99,-1,-100,3]

向右轮转 2 步: [3,99,-1,-100]

提示:

1 <= nums.length <= 105

-231 <= nums[i] <= 231 - 1

0 <= k <= 105

**

思路一:

1.前n-k个元素逆置

2.后k个元素逆置

3.最后进行整体的逆置

void reverse(int* nums, int left, int right)
{
    while (left< right)
    {
        int temp = nums[left];
        nums[left] = nums[right];
        nums[right] = temp;
        ++left;
        --right;
    }
}
 if (k > numsSize)
    {
        k %= numsSize;
    }
    reverse(nums, 0, numsSize - 1);
    reverse(nums, 0, k - 1);
    reverse(nums, k, numsSize - 1);
}

复杂度分析

时间复杂度:O(n)O(n),其中 nn 为数组的长度。每个元素被翻转两次,一共 nn 个元素,因此:

总时间复杂度为 O(2n)=O(n)O(2n)=O(n)。

空间复杂度:O(1)O(1)。

思路二:

1.先创建一个新的数组

2.把后k个数放到新数组

3.在把前k个数向后移动

void rotate(int* nums, int numsSize, int k)
{
     k %= numsSize;  //变长数组
     int temp = nums[numsSize];
     //把后k个元素拷贝到前面
      int j=0;
      for(int i= numsSize - k; i<numsSize ; i++)
        {
            temp[j] = nums[i];
            ++j;
        }
        //把前n-k个拷贝到后面
        for(int i= 0; i<numsSize-k ; i++)
        {
            temp[j] = nums[i];
            ++j;
        }
        //拷贝回去
        for(int i= 0; i<numsSize ; i++)
        {
                temp[] = nums[i];     
         }
 }

这里使用malloc来创建新数组的话也可以,只是不能调试而已

复杂度分析

空间复杂度: O(n)

时间复杂度: O(n)O(n),其中 nn 为数组的长度

**

2.消失的数字

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

示例 1:

输入:[3,0,1]

输出:2

示例 2:

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

输出:8

思路一:

数学

将从 0 到 n的全部整数之和先计算出来,接着我们去遍历数组,用得到的和减去数组中的元素,便可得到我们需要的数

int missingNumber(int* nums, int numsSize){
         int n=numsSize;
         int ret=n*(n+1)/2;
         for(int i=0; i<numsSize; i++)
         {
             ret-=nums[i];
         }
        return ret;

复杂度分析

时间复杂度:O(n),其中 n是数组 nums 的长度。需要 O(1)的时间计算从 0 到 nn的全部整数之和以及需要 O(n) 的时间计算数组 nums 的元素之和。

空间复杂度:O(1)

思路二:

数组 nums 中有 n个数,在这 n个数的后面添加从 0 到 n 的每个整数,则添加了 n+1个整数,共有 2n+1个整数。

在 2n+1 个整数中,消失的数字只在后面 n+1 个整数中出现一次,其余的数字在前面 n 个整数中(即数组中)和后面 n+1个整数中各出现一次,即其余的数字都出现了两次。

根据出现的次数的奇偶性,可以使用按位异或运算得到消失的数字。按位异或运算 \oplus⊕ 满足交换律和结合律,且对任意整数x 都满足 x⊕x=0 和 x⊕0=x。

由于上述 2n+12n+1 个整数中,消失的数字出现了一次,其余的数字都出现了两次,因此对上述 2n+1个整数进行按位异或运算,结果即为消失的数字

int missingNumber(int* nums, int numsSize){
        int n=numsSize;
        int x=0;
        for(int i=0; i<numsSize; i++)
        {
            x^=nums[i];
        }
        for(size_t j=0; j<n+1; j++)
        {
            x^=j;
        } 
        return x;
}

复杂度分析:

时间复杂度:O(n),其中 n是数组 nums 的长度。需要对 2n+1个数字计算按位异或的结果。

空间复杂度:O(1)

**

相关文章
|
26天前
|
机器学习/深度学习 存储 算法
1 .算法的复杂度(超全)
1 .算法的复杂度(超全)
|
9天前
|
机器学习/深度学习 存储 算法
复杂度讲解
复杂度讲解
38 7
|
7月前
|
缓存 分布式计算 并行计算
平摊复杂度
平摊复杂度(Amortized Complexity)是一种在计算复杂度时使用的技术,用于描述算法在多次运行中的平均性能。平摊复杂度能够将一次性计算的复杂度分摊到多次运行中,从而更准确地衡量算法在实际应用中的性能。
39 3
|
8月前
|
存储 算法
【算法的复杂度】
【算法的复杂度】
28 0
|
8月前
|
算法
算法中的复杂度
算法中的复杂度
33 0
|
9月前
|
存储 算法 数据库
算法:复杂度
算法:复杂度
53 0
|
搜索推荐 算法
认识复杂度和简单排序算法
认识复杂度和简单排序算法
65 0
|
存储 算法
算法学习 | 加深了解算法的复杂度
本篇从时间复杂度和空间复杂度出发,深入了解一下算法的复杂性。
133 1
|
机器学习/深度学习 算法 C语言
[最全算法总结]我是如何将递归算法的复杂度优化到O(1)的
[最全算法总结]我是如何将递归算法的复杂度优化到O(1)的
159 0
[最全算法总结]我是如何将递归算法的复杂度优化到O(1)的
|
算法 程序员
【简单算法】什么是复杂度?
【简单算法】什么是复杂度?