力扣刷题1、7、9(小小白亲测,Bug你准没我的多,hhh)

来刷题啊

  • 小问题
  • 1.简单题3道:
    • 1.1  num1:两数之和(1)
      • 暴力题解:
      • 哈希表解法
    • 1.2  num2:整数反转(7)
    • 1.3  num3:回文数(9)
  • 2.心路历程(2021.8.2)

小问题

哈希表解决两数之和尚待解决
回文数自己写的bug暂时为解决

1.简单题3道:

1.1  num1:两数之和(1)

 题目链接:两数之和

暴力题解:

此才为正解啊:

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* twoSum(int* nums, int numsSize, int target, int* returnSize)
{	
	int i,j;
	int *a=(int*)malloc(sizeof(int)*2);
	for(i=0;i<numsSize;i++)
	{
		for(j=i+1;j<numsSize;j++)
		{
			if(nums[i]+nums[j]==target)
			{
				a[0]=i;
				a[1]=j;
				*returnSize=2;
				return a;
			}
		}
	}
	*returnSize=0;
	return NULL;
}
使用两个for循环,可看作使用双指针,时间复杂度O(n^2)

 做错了~,已修改:(请慎用,防止跑偏)

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* twoSum(int* nums, int numsSize, int target, int* returnSize)
{
    int i,j,x=0;
    
    //找出i,j
    for(i=0;i<numsSize-1;i++)
    {
        for(j=i+1;j<numsSize;j++)
        {
            if(nums[i]+nums[j]==target)
            {
                /* 第一版:⭐1
                returnSize[0]=i;
                returnSize[1]=j;
                return returnSize;
                */
			//第二版:
                int *a=(int*)malloc(sizeof(int)*2);
                a[0]=i;
                a[1]=j;
                *returnSize=2;
                x=1;
                 break;
            }
        }
        //三目运算⭐2
        //x==1?break:continue;
        if(x)
            break;
    }
    //讲存有下标i,j的值返回⭐3
     if(x)
        return a;
    else
        {
            *returnSize=0;
            return NULL;
       }
}

⭐1指针与指针数组
1.1returnSize类型为指针类型,而非指针数组不能那样使用
1.2而且returnSize为返回的个数,可能为0、2,而非让他返回两个i,j
⭐2三目运算:
2.1三目运算符为赋值运算符,而不是单纯的一条语句,形如:c = a>b? a:b;
⭐3作用域
3.1不一定非要结束循环,才返回值,显得很冗余
3.2而且变量有作用范围,a变量的作用域是局部变量,不能脱离作用范围使用,可以把他写到函数的第一个作用域中

哈希表解法

下边的可不对啊,(哈希表刚刚了解了一部分,暂时只能写到这儿,有哈希冲突,之后再重新补充吧,勇敢牛牛,不怕bug)

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
 struct kvalue {
     int key;
     int value;
 }Kvalue;
struct kvalue a[10000];
int* twoSum(int* nums, int numsSize, int target, int* returnSize)
{	
	int i,t,k;
    for(i=0;i<numsSize;i++)
    {
        t=target-nums[i];
        if(a[t].key==t)
        {
            *returnSize=2;
            int *ret=(int*)malloc(sizeof(int)*2);
            ret[1]=i,ret[0]=a[t].value;
            return ret;
        }
          else
          { 
              k=nums[i];
              a[k].key=nums[i];
              a[k].value=i;
          }  
    }
    *returnSize=0;
    return NULL;
}

1.2  num2:整数反转(7)

题目链接:整数反转

坎坎坷坷,头大,一句话终于点醒我,终于终于明白了!!!开心开心。想法真的不要太赞吧,学习学习学习

优秀代码奉上(所谓的“短小精悍”)

int reverse(int x){
    int z,s=0;
    while(x)
    {
        z=x%10;
        x/=10;
        if(s<INT_MIN/10||s>INT_MAX/10)
            return 0;
        s=s*10+z;
    }
    return s;
}

困惑解决啦!!
1.INT_MIN ,INT_MAX

#include 用于C或C++中,常量INT_MIN INT_MAX分别表示最小、最大
INT_MAX = 2^31-1=2147483647;
INT_MIN= -2^31=-2147483648;
注意:在C/C++语言中,不能够直接使用-2147483648来代替最小负数,因为这不是一个数字,而是一个表达式。表达式的意思是对整数21473648取负,但是2147483648已经溢出了int的上限。

2.if (sINT_MAX/10)

(这条语句折磨我好苦),解决溢出问题的精髓啊
在一些语言中,当数据过大发生溢出时会报错,而这条语句很好的避免了这一情况的发生
if (sINT_MAX/10)它通过提前判断,来看即将运算的语句是否会发生溢出

3.负数无需单独考虑

负数情况在本题中,取反变成正数,实在多余,因为负数做取余运算,最后的符号和左操作数保持一致

4.取反进阶操作

不堪的回首:害,现在看自己用的方法好”亲民“(hh):正常的取余,做商,当时没反应过来不能像蹦豆子是的,一个一个输出数(这样也太简单了吧),后来发觉后,采取的是将每个数保存到数组中,再循环数组并依次乘以10的多少次(还得用循环),烦烦烦,而且还不能判断溢出
我懂了,真是妙啊:反转的时候,只需两步,搞定。第一:弹出x的末尾数字digit,digit=x%10; x/=10;;第二:推入reverse=reverse*10+digit;

5.些许小知识点

当数据大于最大范围时,数据只是客观上增大,实际已经不会发生变化了

不堪的回首:(错误示例,可当找bug食用,剂量较大慎用)

//问题对应步骤4
int reverse(int x){
    int y=x<0?-x:x;
    int i=0,yu,k,s=0;
    int sum[32];
    while(y)
    {
        sum[i]=y%10;
        i++;
        y/=10;
    }
    for(k=0;k<i;k++)
    {
        s+=sum[k]*fun(k,i);
    } 
}
int fun(int j,int i)
{
    int k,s=1;
    for(k=0;k<i-1-j;k++)
        s*=10;

    return s;
}

/*这个方法也是进行比较, 反转值每次更新后除10,然后跟上一次的反转值比较一下,
如果不相等,就是溢出,不适用于当溢出就报错的语言
(既然能想到这儿,就可以再进一步,它最后的会有溢出情况,
那他上一次是不是没发生溢出,那又怎么求上一次,就解决这个问题了)*/
int reverse(int x){
    int y=x<0?-x:x;
    int s=0,s1,z;
    
    while(y)
    {
        z=y%10;
        y/=10;
        s1=s;
        s=s*10+z;
        //if(z!=0&&s1==s)
        if(s1!=s/10)
            return 0;
    }
    if(x<0)
        s=-s;
    return s;

}

1.3  num3:回文数(9)

题目链接:回文数

高配版,高配不是没有道理的啊:

bool isPalindrome(int x)
{   
    if(x<0||x>0&&x%10==0)//x>0&&x%10==0,没有这条语句时,无法约束10的倍数的
        return false;
    int rev=0;
    while(x>rev)
    {
        rev=rev*10+x%10;
        x/=10;
    }
    if(x==rev||x==rev/10)
        return true;

    else
        return false;
}

要升级:
1.回文数的两种方法:

  • 例如12321,可以获得倒叙读取的数与原来的数进行比较,但一定要注意数据是否会发生溢出现象(低配版)
  • 既然是判断回文,那就可以从左到右读到中间数时,与倒叙读到的中间时的数进行比较,优点:不用判断数据溢出情况,不用循环到最后

应该是低配版吧,看了解析果然是低配,害,学习的道路永不停止hhh:

bool isPalindrome(int x){

    int rev=0,yu,y=x;
    if(x<0)
     return false;
    
    else
    {
        while(x)
        {
            yu=x%10;
            x/=10;
            if(rev<INT_MIN/10||rev>INT_MAX/10)
              return false;
            rev=rev*10+yu;
        }
        if(rev==y)
         return true;
         
         else
         return false;
    }
}

勿看:bug,你能不能不要不请自来啊,你又一次的来了,,我暂时还奈何不了你(烦~

bool isPalindrome(int x)
{
    int rev=0,yu,y;
    
    if(x<0)
     return false;
    
    else if(x<10)
        return true;
        
    else
    {
        while(x)
        {
            yu=x%10;
            y=x;
            x/=10;
            rev=rev*10+yu;

            if(rev==y)
             return true;
            if(rev>y)
              return false;
        }
    }

}

2.心路历程(2021.8.2)

心路历程,是我低估了,原以为以现在的水平力扣三道简单题和两道中等题,应该是挺轻松的吧,结果断断续续边做边学的捣鼓了三四天,今天一定要做完!!!今天做的差不多了,还有一些小问题,(小开心)。这一次很认真的想要刷力扣的题,虽然现在还是磕磕绊绊的,其中也让我头大得很,但是后来因为一句话而清楚的喜悦真的是爽啊,hhh,继续做题,不同的思路真的是让我要托下巴啊,以后CSDN我就是常客了,

你可能感兴趣的:(力扣刷题,leetcode,c语言,bug)