• 算法试题——每日一练


    求整数x的平方根

    给定一个非负整数,求它的平方根,只要整数部分。
    第一次通过的代码:

    int mySqrt(int x){
        long int low,high,mid,t;
        low = 0;
        high = x;
        while(low <= high)
        {
            if(x == 1)
                break;
            else
            {   
                mid = (low + high) / 2;
                if((mid * mid) <= x)
                 {
                     t = mid + 1;
                     while((t * t) <= x)
                    {
                        t++;
                    }
                    return (t - 1);
                 }
                else
                    high = mid;
            }
        }
        return x;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    后面再看了一下,变量 l o w low low一直是0,可有可无,没有起到什么作用😑,可以把它删除,但进而一系列的代码也要做相应的改动。且当数据很大时, m i d ∗ m i d mid * mid midmid很有可能会发生溢出,因此上面代码我用的长整型变量,这里也可以在那个小于号的左右两边同时除以一个 m i d mid mid,就变成 m i d ≤ x / m i d mid\leq x / mid midx/mid了。

    int mySqrt(int x)
    {
        int g;
        if(x <= 1)
        	return x;
    	g = x / 2;
        //对应上面的while(low <= high)
        while(g > x / g)
        {
            g /= 2;
        }
        //对应上面的while(t * t <= x)
        while(g <= x / g)
        {
            g++;
        }
        return (g - 1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    爬楼梯

    假设要爬到第 n n n个台阶上,一次只能爬1阶或者2阶,那么第爬到第 n n n阶上有多少种爬法?例如:
    1阶:
    1
    2阶:
    1+1
    2
    3阶:
    1+1+1
    1+2
    2+1
    4阶:
    1+1+1+1
    2+1+1
    1+2+1
    1+1+2
    2+2

    首先我看到这个题目的时候第一个想法就是直接去敲代码,在代码里思考。但是这样的题目一般我们都可以先用数学的思想去做,先找找规律,理清自己的思路,再上手代码。

    那么,这个题目的思路其实很简单,自己多列几阶就能看出来,自第三阶开始,每阶的爬法都是前两种之和。

    这样,我首先就想到了用函数递归就可以实现。

    #include 
    int climbStairs(int n)
    {
    	if(n <= 3)
    		return n;
    	else
    		return ((climbStairs(n - 1) + climbStairs(n - 2));
    }
    int main()
    {
    	int a,b;
    	printf("Please input the number of the stairs:");
    	scanf("%d",&a);
    	b = climbStairs(a);
    	printf("%d",b);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    通过递归,n较小的时候还好,n一旦稍微大一点,运行的速度就慢下来了,因为它要不停地去调用函数,这就使非常耗费时间,于是我又开始考虑用迭代去实现,从而避免调用函数。

    #include 
    int climbStairs(int n){
    	int a,b,c;
    	if(n <= 3)
    		return n;
    	else
    	{
    		a = 2;
    		b = 3;
    	}
    	for(int i = 4 ; i <= n ; i++)
    	{
    		c = a + b;
    		a = b;
    		b = c;
    	}
    	return c;
    }
    
    int main()
    {
    	int a,b;
    	printf("Please input the number of the stairs:");
    	scanf("%d",&a);
    	b = climbStairs(a);
    	printf("%d",b);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    删除有序数组中的重复项

    给定一个有序数组,删除它里面的重复项,也就是每种数字只有一个。并返回删除重复数字后数组的长度。假如返回的数组长度为k,那么该数组中前k个元素全都是不重复的数字。
    例如,对于 [ 1 , 1 , 1 , 2 , 2 , 3 ] [1,1,1,2,2,3] [1,1,1,2,2,3],返回3,且输出为 [ 1 , 2 , 3 ] [1,2,3] [1,2,3]。(只能说输出是这个顺序,并不一定要有“ [ ] ”。)

    我首先想到的就是先找到重复的数字,再把它们删除,删除后又将后面的元素移到前面来,进而又继续找下一个重复的数字。但是写代码的时候总是有错误,也仔细把数据带进去看了,很是麻烦,😢。最后实在不行了就去欣赏了一下其他人的答法,发现好多人都是用的指针法。它们并没有把后面的数字全部都移到前面去,而是巧妙地用后面的元素将重复的元素覆盖。最后前k个元素自然就是全都不重复的了。

    #include 
    int removeDuplicates(int* nums, int numsSize){
        int i,n;
        n = 0;
        for(i = 1 ; i < numsSize ; i++)
        {
            if(nums[n] != nums[i])
            {
                n++;
                nums[n] = nums[i];
            }
        }
        return (n + 1);
    }
    
    int main()
    {
    	int a[] = {1,1,1,2,2,3},b = 6,c;
    	c = removeDuplicates(a,b);
    	for(int i = 0 ; i < c ; i++)
    		printf("%d ",a[i]);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 相关阅读:
    2024年一年一度的618正式结束了,苹果与华为手机销量看看谁是大赢家?
    推荐一个屏幕上鼠标高亮显示的小工具
    YOLOv5 Focus C3 各模块详解及代码实现
    [附源码]Python计算机毕业设计Django基于web的建设科技项目申报管理系统
    LLM应用架构 LLM application architectures
    Qt学习15 用户界面与业务逻辑的分离
    ubutun上编译出现undefined reference to symbol ‘dladdr@@GLIBC_2.2.5‘的错误
    Vuex概述及核心概念
    Django(6)路由
    【图像融合】梯度域中的多曝光多焦点图像融合算法研究附matlab代码
  • 原文地址:https://blog.csdn.net/weixin_62917800/article/details/126337218