[LeetCode] 2.AddTwoSums

[LeetCode] 2.AddTwoSums

题目

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807

思路

大数加法的实现之一

由于是逆序链表,也就是 从头到尾 分别对应数字的 低位到高位 (个->十->百)

那么我们只需要按照加法的逻辑来即可

加法原则:满十进一,这里用到整除和取余运算

解法一

新建一个链表后把结果尾插

有几个注意点

  • 两个链表的长度可能不等
  • 可能存在空链表
  • 链表长度等同于长链表或者长链表+1
class Solution {
public:
	ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
		int extern_data = 0;
		ListNode* head = NULL;
		ListNode* tail = NULL;
		int val = 0;
		while (l1 != NULL && l2 != NULL) {
			val = l1->val + l2->val + extern_data;
			extern_data = val / 10;
			insert_data(head, tail, val % 10);
			l1 = l1->next;
			l2 = l2->next;
		}
		
		while (l1 != NULL) {
			if (extern_data != 0) {
				l1->val += extern_data;
				extern_data = l1->val / 10;
				l1->val %= 10;
			}
			insert_data(head, tail, l1->val);
			l1 = l1->next;
		}
		
		while (l2 != NULL) {
			if (extern_data != 0) {
				l2->val += extern_data;
				extern_data = l2->val / 10;
				l2->val %= 10;
			}
			insert_data(head, tail, l2->val);
			l2 = l2->next;
		}
		if (extern_data != 0) {
			insert_data(head, tail, extern_data);
		}
		return head;
	}
	
	void insert_data(ListNode *&head,ListNode *&tail,int val) {    //插入数据
		if (head == NULL) {
			head = new ListNode(val);
			tail = head;
		}
		else {
			ListNode* temp = new ListNode(val);
			tail->next = temp;
			tail = temp;
		}
	}
};

这样的时间复杂度为 O(m+n)
空间复杂度为 O(m+n)

解法二

是对解法一的优化

解法一是新建了链表,这样的话其实是浪费了很多的空间,其实完全可以用原链表

class Solution {
public:
	ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
		int extern_data = 0;
		int val = 0;
		if (l1 == NULL) {    //这一步是为了防止下面的next出错
			l1 = new ListNode(0);
		}
		ListNode* head = l1;
		if (l2 == NULL) {
			l2 = new ListNode(0);
		}
		while (l1->next != NULL && l2->next != NULL) {
			val = l1->val + l2->val + extern_data;
			extern_data = val / 10;
			l1->val = val % 10;
			l1 = l1->next;
			l2 = l2->next;
		}
		
		val = l1->val + l2->val + extern_data;
		extern_data = val / 10;
		l1->val = val % 10;

		while (l1->next != NULL) {
			l1 = l1->next;    //这边的向下查询要循环前面,因为上面代码的后一次查询并没有做
			if (extern_data != 0) {
				l1->val += extern_data;
				extern_data = l1->val / 10;
				l1->val %= 10;
			}
		}

		while (l2->next != NULL) {
			l2 = l2->next;
			if (extern_data != 0) {
				l2->val += extern_data;
				extern_data = l2->val / 10;
				l2->val %= 10;
			}
			l1->next = l2;    //直接把l1的next链接到l2以节省空间
			l1 = l2;
		}
		if (extern_data != 0) {
			if (l1->next != NULL)
			    l1 = l1->next;
			insert_data(head, l1, extern_data);
		}
		return head;
	}

	void insert_data(ListNode *&head, ListNode *&tail, int val) {
		if (head == NULL) {
			head = new ListNode(val);
			tail = head;
		}
		else {
			ListNode* temp = new ListNode(val);
			tail->next = temp;
			tail = temp;
		}
	}
};
L) {
			head = new ListNode(val);
			tail = head;
		}
		else {
			ListNode* temp = new ListNode(val);
			tail->next = temp;
			tail = temp;
		}
	}
};

GitHub地址

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值