ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

算法入门C——35. 搜索插入位置

2021-10-26 22:30:16  阅读:147  来源: 互联网

标签:numsSize 入门 int mid 35 算法 查找 target left


LeetCode刷题——算法学习计划(入门部分)

文章目录

题目描述

在这里插入图片描述

思路介绍

由于本人学算法只是为了巩固C语言基础,所以就不会去深挖算法之根本

算法:二分法查找适用于数据量较大时,但是数据需要先排好顺序。主要思想是:(设查找的数组区间为array[low, high])
(1)确定该区间的中间位置K(2)将查找的值T与array[k]比较。若相等,查找成功返回此位置;否则确定新的查找区域,继续二分查找。区域确定如下:a.array[k]>T 由数组的有序性可知array[k,k+1,……,high]>T;故新的区间为array[low,……,K-1]b.array[k]<T 类似上面查找区间为array[k+1,……,high]。每一次查找与中间值比较,可以确定是否查找成功,不成功当前查找区间将缩小一半,递归查找即可。时间复杂度为:O(log2n)。——百度百科

若算法的T(n) =O(logn),则称其具有对数时间。由于计算机使用二进制的记数系统,对数常常以2为底(即log2n,有时写作lgn)。然而,由对数的换底公式,logan和logbn只有一个常数因子不同,这个因子在大O记法中被丢弃。因此记作O(logn),而不论对数的底是多少,是对数时间算法的标准记法。
常见的具有对数时间的算法有二叉树的相关操作和二分搜索。
对数时间的算法是非常有效的,因为每增加一个输入,其所需要的额外计算时间会变小。
递归地将字符串砍半并且输出是这个类别函数的一个简单例子。它需要O(log n)的时间因为每次输出之前我们都将字符串砍半。 这意味着,如果我们想增加输出的次数,我们需要将字符串长度加倍。——百度百科

O(1)常数阶 < O(logn)对数阶 < O(n)线性阶 < O(n2)平方阶 < O(n3)(立方阶) < O(2n) (指数阶)
二分法的时间复杂度为O(logn),这个logn怎么来的呢?

我们使用二分查找时,每次查找都会将剩下的内容一分为二,第一次为1/2,第二次1/4,第m次为(1/2)m,直到最后只剩一个查找对象(最坏情况),也就是1。假如一共有n个对象,查找m次,就可以得出公式:n(1/2) m = 1 ,简单换算得到 n = 2m ,即查找次数m=log2n,省略底数2,即得出m=logn,所以二分查找的时间复杂度为O(logn)。

我的第一次正确提交

由于昨天已经练过二分查找,所以这题也没遇到太大麻烦,但和标准答案比,我还是有优化空间的。

int searchInsert(int* nums, int numsSize, int target)
{
    int left = 0;
    int right = numsSize - 1;
    int mid = 0;
    while(left <= right)
    {
        mid = left + (right - left) / 2;
        if(target == nums[mid])
            return mid;
        else if(target > nums[mid])
            left = mid + 1;
        else 
            right = mid - 1;
    }
    if(target < nums[mid]) //这个if可以合到while循环中去,参考官方版本(下文)
        return mid;
    else 
        return mid + 1;
}

同样的代码,怎么运行时间和内存消耗都不一样呢。
在这里插入图片描述

官方版本

下面是官方版本

看来我永远都不能达到这种高度了,每次都比官方代码低一个档次。

int searchInsert(int* nums, int numsSize, int target) {
    int left = 0, right = numsSize - 1, ans = numsSize;
    while (left <= right) {
        int mid = ((right - left) >> 1) + left;
        if (target <= nums[mid]) {
            ans = mid;
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    return ans;
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/search-insert-position/solution/sou-suo-cha-ru-wei-zhi-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


虽然题目要求了时间复杂度要为O(logn),但我还是用了一个土方法提交

int searchInsert(int* nums, int numsSize, int target)
{
    int i = 0;

    if(target > nums[numsSize - 1])
        return numsSize;
    for(i = 0; i < numsSize; i++)
    {
        if(target <= nums[i])
            return i;  
    }
    return 0;
}

用这种方法,如果数组有n个数,最坏情况要找m次,那么m和n就满足m=1*n,即时间复杂度为O(n),根据O(1)常数阶 < O(logn)对数阶 < O(n)线性阶 < O(n2)平方阶 < O(n3)(立方阶) < O(2n) (指数阶),的确是不满足题目要求。

在这里插入图片描述


错误记录:没考虑小于数组最小值的情况。

在这里插入图片描述

int searchInsert(int* nums, int numsSize, int target)
{
    int left = 0;
    int right = numsSize - 1;
    int mid = 0;
    while(left <= right)
    {
        mid = left + (right - left) / 2;
        if(target == nums[mid])
            return mid;
        else if(target >= nums[mid])
            left = mid + 1;
        else 
            right = mid - 1;
    }
    return mid + 1; //如果数组中没有target,则返回插入位置
}

标签:numsSize,入门,int,mid,35,算法,查找,target,left
来源: https://blog.csdn.net/weixin_43772810/article/details/120980024

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有