两数之和(无序数组中找固定和);两数相加(两个链表涉及到的大数相加)

在这里插入图片描述

首先想到是肯定是暴力破解法:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> vec;
        for(int i = 0; i < nums.size();++i)
        {
            for(int j = i + 1 ; j < nums.size();++j)
            {
                if(nums[i] + nums[j] == target)
                {
                    vec.push_back(i);
                    vec.push_back(j);

                    break;
                }
            }
        }
        return vec;
    }
};

这个不够完美,因为是暴力法,在很多方面都存在自己的缺陷

下面这个是利用哈希表的解法

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> hash;
        for(int i = 0; i < nums.size(); i++){
        	if(hash.count(target - nums[i])) return {hash[target - nums[i]], i};
        	hash[nums[i]] = i;
		}
		return {-1, -1};
    }
};
时间复复杂度减低了,但是内存的消耗却提升了。

在这里插入图片描述

//是我刚开始给出的代码,但是有的测试用例不能跑过,原因是因为,我采用的是计数然后求和,但是结点可以很多,但是数字不能特别大。所以有的用例不能跑过
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    int func(ListNode* l1)
    {
        unsigned int ret = 0;
        if(l1->next)
        {
           ret = func(l1->next); 
        }
        return (ret * 10) + l1->val;       
    }
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        unsigned int ret = func(l1) + func(l2);
        ListNode* p = new ListNode(ret % 10);
        ListNode* p1 = p;
        ret = ret / 10;
        while(ret / 10 != 0 || ret  % 10 != 0)
        {
            p1->next = new ListNode(ret % 10);
            ret = ret / 10;
            p1 = p1->next;
        }
        p1->next = nullptr;
        return p;
    }
};

下面是我重新写的代码:

//这个是可以通过全部测试用例的代码
/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
	ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
		vector<int> vec1;
		vector<int> vec2;
		ListNode* cur = l1;
		while (cur != nullptr)
		{
			vec1.push_back(cur->val);
			cur = cur->next;
		}
		cur = l2;
		while (cur != nullptr)
		{
			vec2.push_back(cur->val);
			cur = cur->next;
		}
		if (vec1.size() < vec2.size())   //因为是两个数相加,所以得知道哪一个数子比较长
		{
			swap(vec1, vec2);
		}
		vector<int> vec3;
		vec3.resize(vec1.size() + 1);  //多开辟一个空间,防止199 + 9 这样的数字。最后有进位
		int size1 = vec1.size();
		int size2 = vec2.size();
		int i = 0;
		int flag = 0;
		while (i < size1)  //长的数字在外面
		{
			if (i < size2)  //短的数字在里面
			{
				int ret = vec1[i] + vec2[i] + flag;
				flag = 0;
				if (ret >= 10)
				{
					vec3[i] = ret % 10;
					flag = 1;
				}
				else
					vec3[i] = ret;
			}
			else
			{
				int ret = vec1[i] + flag;
				flag = 0;
				if (ret >= 10)
				{
					vec3[i] = ret % 10;
					flag = 1;
				}
				else
					vec3[i] = ret;
			}
			i++;
		}
		if (flag == 1)  //最后再判断一次是否存在进位问题
			vec3[i] = 1;
		else
			vec3.erase(vec3.end() - 1);  //要是不存在的话就删除最后的一个位置
		ListNode* p = new ListNode(vec3[0]);  //最后拿着数组去拼装链表
		ListNode* p1 = p;
		for (int i = 1; i < vec3.size(); ++i)
		{
			p1->next = new ListNode(vec3[i]);
			p1 = p1->next;
		}
		p1->next = nullptr;
		return p;
	}
};

但是这段代码的时间复杂度比较高,是因为在while循环内部做了太多的相同操作的判断
在这里插入图片描述
于是对这段代码进行优化

while (i < size1)
{
	int ret;
	if (i < size2)
		ret = vec1[i] + vec2[i] + flag;
	else
		ret = vec1[i] + flag;
	flag = 0;
	if (ret >= 10)
	{
		vec3[i] = ret % 10;
		flag = 1;
	}
	else
		vec3[i] = ret;
	i++;
}

优化后的结果,如图所示:
在这里插入图片描述

发布了230 篇原创文章 · 获赞 28 · 访问量 9296

猜你喜欢

转载自blog.csdn.net/weixin_43767691/article/details/103935425