时间复杂度和空间复杂度

时间复杂度

        时间复杂度算的不是时间而是算法执行次数,用O()渐进表示法表示

1、当M和N不知道大谁小的时候,都要考虑到

//时间复杂度为O(M+N)
void Func3(int N,int M)
{
    int count = 0;
    
    for(int k = 0; k < M; ++k)
        {
            ++count;
        }

    for(int k = 0; k < N; ++k)
        {
            ++count;
        }
    printf("%d\n",count);
}

2、当算法存在最好、最坏、平均这三种情况的时候,我们要算最坏的情况

//时间复杂度为O(N)
const char* strchr(const char* str, char character)
{
    while(*str != '\0')
    {
        if(*str == character)
            return str;
        ++str;
    }
    return NULL;
}

3、冒泡排序实现:第一趟冒泡排序数是N、第二趟冒泡排序数是N-1、

第三趟冒泡排序数是N-3、......、第N-1趟冒泡数是2、第N趟冒泡数是1,等差数列(N+1)*N/2

//时间复杂度为O(N^2)
void BubbleSort(int* a, int n)
{
    assert(a);
    for(size_t end = n; end > 0; --end)
        {
            int exchange = 0;
            for(size_t i = 1; i < end; ++i)
                {
                    if(a[i-1] > a[i])
                    {
                        Swap(&a[i-1], &a[i]);
                        exchange = 1;
                    }                                                                     
                }
        }
            if(exchange == 0)
            break;
}

4、二分查找、找了1次是1、找了2次是2、找了3次是4、找了4次是8,因为是考虑最坏的情况,所以1*2*2*2=N,2^x=N——>X=logN

//时间复杂度为O(logN) 以2为底,写不出来
int BinarySearch(int* a, int n, int x)
{
    assert(a);
    int begin = 0;
    int end = n;
    while(begin < end)
    {
        int mid = begin + ((end - begin)>>1);
        if(a[mid] < x)
            begin = mid + 1;
        else if(a[mid] > x)
            end = mid;
        else
            return mid;
    }
    return -1;
}

5、递归调用了N次,时间复杂度为O(N)

//阶乘递归的时间复杂度为O(N)
long long Factorial(size_t N)
{
    return N < 2 ? N : Factorial(N-1)*N;
}

空间复杂度

        空间复杂度算的不是空间而是变量的个数 

1、时间是累计的,空间是不累计的

//时间复杂度是O(1)
void BubbleSort(int* a,int n)
{
    assert(a);
    for(size_t end = n; end > 0; --end)
    {
        int exchange = 0;
        for(size_t i = 1; i < end; ++i)
        {
            if(a[i-1] > a[i])
            {
                Swap(&a[i-1], &a[i]);
                exchange = 1;
            }
        }
        if(exchange == 0)
        break;
    }
}

2、计算的是影响结果最大的那一项

//空间复杂度是O(N)
long long* Fibonacci(size_t n)
{
    if(n==0)
        return NULL;
    long long* fibArray = (long long*)malloc((n+1)*sizeof(long long));
    fibArray[0] = 0;
    fibArray[1] = 1;
    for(int i = 2; i <= n; ++i)
    {
        fibArray[i ] = fibArray[ i - 1] + fibArray[i - 2]
    }
    return fibArray;
}

3、计算累积变量最多的,最终都会被销毁

//空间复杂度是O(N)
long long Factorial(size_t N)
{
    return N < 2 ? N : Factorial(N-1)*N;
}

练习

1、数组中缺失了一个数,请找出缺失的数,你能在时间复杂度O(N)内完成吗

思路:异或——>用0~N的数和数组的数异或,剩下的数就是缺失的

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

2、旋转数组,给定一个数组,将数组中的元素向右移动k个位置,其中k是非负数,你能在空间复杂度O(1)内完成吗

思路:后k个逆置,前n-k个逆置,再整体逆置

void Reverse(int* nums, int left, int right)
{
    while(left < right)
    {
        int tmp = nums[left];
        nums[left] = nums[right];
        nums[right] = tmp;
        ++left;
        --right;
    }
}

void rotate(int* nums, int numsSize, int k)
{
    if(k >= numsSize)
    {
        k %= numsSize;
    }
    Reverse(nums, numsSize-k,numsSize-1);
    Reverse(nums, 0, numsSize-k-1);
    Reverse(nums, 0, numsSize-1);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值