一道常规求解方法无法完成的小例题

前言

本以为c语言各种语法学好了就能够在例如LeetCode、牛客网以及实验楼等相关网站进行刷题,没想到在做一些简单题的时候就已经够我喝一壶的了。

换句话来说,会语法并不代表你会各个题的解题思路、算法以及逻辑,也就是说会语法也仅仅是刚刚踏上手撕代码的第一步。路还很长,好好加油吧!

LeetCode(例题)

最近在Leetcode上面看到了一个比较有意思的题目: 989.数组形式的整数加法(可点击打开)。下面由博主为大家介绍与讲解(记得瞅瞅题目):

我们常规的写法一般来说都是讲数组以整数的形式拿出来,比如A = [1, 2, 3, 4]即为1234(注意这里要以整式的形式取出来的话,需要写for循环乘10,例如1×1000+2×100+3×10+4×1 = 1234),再将这个值与K相加,最后再倒放数组,用模10除10的方式放入数组里面。

好像这个题目似乎用了2~3行的文字语言就能够实现了,但是实际你去测试的时候,是错误的,并且它给你一个错误用例,是个很长很长的数组,这时候为什么呢?

我们得注意题目给的提示: 1 <= A.length <= 10000.即数组的长度,那我们要知道的是unsigned long long的数字大小只有2^64 ,2^10 是 1024 只有四位数,那么2^20大约是1 000 000,也就七位数,那么 2^60,是10亿×10亿,emmmm也不过只是18个0而已,跟10000的长度比起来简直是小巫见大巫了,估计蚂蚁都没有10亿×10亿这么多吧…

所以这样的常规做法必然是无法完成的,但是我们可以换一种思路来求解:小学生求解方法,个位加个位,十位加十位,满了则进位加一。

如图:

在这里插入图片描述

当然了,这里K = 181也是用模10除10的方法进行取值,并且每进行一次位运算就需要把结果放入数组。

有了清楚的思路,下面就可以来捋捋代码了,难度还是有的,这里我会给出注释。

代码如下:

int* addToArrayForm(int* num, int numSize, int k, int* returnSize)
{
	int kSize = 0;
	int kNum = k;
	int ASize = numSize;
	//取k的长度,例如k=1234,则kSize为4。
	while (kNum)
	{
		kNum /= 10;
		kSize++;
	}
	//建立新数组,将结果存入新数组retArr中
	//数组大小为kSize与ASize中的较大值
	int Size = (kSize > ASize ? kSize : ASize);
	//Size + 1的目的,例如55 + 51 = 106,这样长度就大了一位
	//为防止这样的情况则长度加一
	int* retArr = (int*)malloc(sizeof(int)*(Size + 1));
	int i = 0;
	//A[]数组的下标为Ai
	int Ai = ASize - 1;
	int newAdd = 0;
	//进位符号carryNum
	int carryNum = 0;
	while (Size--)
	{
		//Asize小于kSize的情况
		if (Ai < 0)
		{
			newAdd = k % 10 + carryNum;
		}
		else
		{
			//下面的情况只适用于Asize大于kSize的情况
			//如果出现A=[1,2],k=123时,A[]数组会越界。
			//所以就会有上面的判断情况。
			newAdd = num[Ai] + k % 10 + carryNum;
			Ai--;
		}
		//把个位去除
		k /= 10;
		//判断是否进位
		if (newAdd > 9)
		{
			newAdd %= 10;
			carryNum = 1;
		}
		else
		{
			carryNum = 0;
		}
		retArr[i] = newAdd;
		i++;
	}
	//把最后的进位放进去
	if (carryNum == 1)
	{
		retArr[i] = carryNum;
		i++;
	}

	*returnSize = i;
	//逆序输出retArr
	int end = i;
	int start = 0;
	int tmp = 0;
	for (start = 0; start < end / 2; start++)
	{
		tmp = retArr[start];
		retArr[start] = retArr[end - 1 - start];
		retArr[end - 1 - start] = tmp;
	}
	return retArr;
}

在这里插入图片描述
很多地方都可以优化,但是博主为了把详细的过程写出来,所以可能执行用时和内存消耗有点大。

另外我具体讲一下为什么kSize比ASize大的时候会出现越界的情况,如图:

在这里插入图片描述

以上也只是提供一个小思路,编写代码的时候非常需要自身的一个逻辑缜密性,也就是各个情况都需要考虑到

最后欢迎小伙伴们前来浏览阅读,有什么问题还望大家批评指正哦~

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值