LeetCode第二题:两数相加

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

/**
 * 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) {
     }
};

//思路1(循环):

首先想到的就是比较头铁的全加器模型,有两个加数和sum还有进位Carry
步骤:

  1. 入口阶段: 动态分配一个虚头结点,while(l1&&l2)然后就进入循环
  2. 加法阶段: 循环体里分别判断l1,l2和Carry是否有值,然后加到sum中
  3. 下一次循环: 首先判断sum是否>=10,如果是则Carry为1,否则Carry为0. 然后将相加的结果sum通过动态分配调用构造函数的方法存储到新结点val中
  4. 终止阶段: delete掉虚头结点,返回指向头部指针
class Solution {
    
    
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    
    
    	int Carry=0,sum=0;
    	ListNode* l3 = new ListNode(0);
    	ListNode* head = l3;
    	while(l1!=NULL||l2!=NULL)
    	{
    
    
    		sum=0;
    		if(l1)
    		{
    
    
    			sum += l1->val;
    			l1=l1->next;
			}
			if(l2)
			{
    
    
				sum += l2->val;
				l2=l2->next;
			}
			if(Carry)
				sum += Carry;
			Carry = sum>=10?1:0;
			l3->next = new ListNode(sum%10);
			l3 = l3->next;
		}
		if(Carry)
		{
    
    
			l3->next = new ListNode(1);
		}
		l3 = head->next;
		delete head;
        return l3;}
};

在这里插入图片描述

  1. 如果把Carry放在循环体判断条件中while(l1||l2||Carry),那么虽然内存消耗少了一丢丢,但是时间多了更多,因为执行循环体一次用的时间大于在外面if一次时间。. 在这里插入图片描述

更短一点点的:

		int Carry=0,sum=0;
   		ListNode* l3 = new ListNode(0);
    	ListNode* head = l3;
    	while(l1!=NULL||l2!=NULL)
    	{
    
    
    		sum=0;
    		sum = (l1?l1->val:0)+(l2?l2->val:0)+Carry;
    		if(l1)
    			l1=l1->next;
    		if(l2)
    			l2=l2->next;
    		Carry = sum>=10?1:0;
    		l3->next = new ListNode(sum%10);
    		l3=l3->next;}
    	if(Carry) l3->next  = new ListNode(1);
    	l3 = head->next;
    	delete head;
    	return l3;

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200929222759726.png#pic_ce
//思想2(递归):
递归的思想和循环思想类似,也是判断这样子判断,每一hi 次us递归传递参数两个加数的指针和Carry位,当三者都是0的时候返回。然后执行程序跟上面差不多,但是递归看起来更精简,因为函数调用代替了链表移位。

class Solution {
    
    
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    
    
    	return dsf(l1,l2,0);}
    ListNode* dsf(ListNode* l1,ListNode* l2,int n)
    {
    
    
    	if(!l1&&!l2&&!n) return NULL;
    	int sum = (l1?l1->val:0)+(l2?l2->val:0)+n;
    	ListNode* node = new ListNode(sum%10);
    	node->next = dsf(l1?l1->next:NULL,l2?
    	l2->next:NULL,sum/10);
    	return node;
	}
};

在这里插入图片描述

PS. 每次执行,用时和消耗都可能不一样,所以学方法就好

猜你喜欢

转载自blog.csdn.net/ZmJ6666/article/details/108876680
今日推荐