LeetCode(17)-两数相加

题目描述:

给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。

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

 

进阶:

如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。

题解:

方法一:因为通常意义的加法是从个位数开始的,所以是从链表的后面往前加的,由于这是两个单链表的相加,在不改变链表的结构前提下,先颠倒两个链表,再进行相加,将结果链表再颠倒。

算法:

  • 颠倒链表l1,l2
  • 遍历l1,l2将l1和l2指向的结点值和进位值加起来,构成一个新的节点

PS:有三种情况是要创建一个新的节点:1:l1不为空

                                                                2:l2不为空

                                                                3:进位值不为0

代码:


class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    ListNode *head1=NULL;
		while(l1)
	{
		ListNode *temp=l1->next;
		l1->next=head1;
		head1=l1;
		l1=temp;
	}
    ListNode *head2=NULL;
    	while(l2)
	{
		ListNode *temp=l2->next;
		l2->next=head2;
		head2=l2;
		l2=temp;
	}
    
    ListNode *dumpy=new ListNode(-1);
dumpy->next=NULL;
    ListNode *head=dumpy;
    int carry=0;
  while(head1 || head2 || carry){//三种情况,链表加完之后看是否还有进位
            int sum = 0;
            if (head1){
                sum += head1->val;
                head1 = head1->next;
            }
            if (head2){
                sum += head2->val;
                head2 = head2->next;
            }
            sum = sum + carry;//各个位置的和
            head->next = new ListNode(sum%10);//直接构造链表值
            head = head->next;
            carry = sum/10;//进位情况
        }
 ListNode *p=dumpy->next;
  ListNode* h=NULL;
  	while(p)
	{
		ListNode *temp=p->next;
		p->next=h;
		h=p;
		p=temp;
	}
    return h;
    
    }

};

 方法二:一般逆序处理,都要想到用栈。

算法:

  • 将l1和l2分别压入栈s1和s2中
  • 然后判断栈s1和s2是否非空,还有进位三种情况
  • 初始sum=0;还有一个临时节点初始化为NULL

l1非空:则sum=sum+l1->val;

l2非空:则sum=sum+=l2->val; 

进位不为0:sum=sum+carry

  • 创建一个新节点(三种情况都会新产生一位,所以要创建一个新节点)new ListNode(sum%10),改变进位carry=sum/10;
  • 让新节点指向临时节点,然后让临时节点=当前节点

 

代码:

/**
 * 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) {
        stack<int>s1,s2;
   while(l1)
     {
     	s1.push(l1->val);
     	l1=l1->next;
	 }
	 while(l2)
     {
     	s2.push(l2->val);
     	l2=l2->next;
	 }


        int carry=0;
	 ListNode *head=NULL;
	 
	while(!s1.empty()||!s2.empty()||carry)
	{
		int sum=0;
		if(!s1.empty())
		{
			sum+=s1.top();
			s1.pop();
		}
		if(!s2.empty())
		{
			sum+=s2.top();
			s2.pop(); 
		}
		sum=(sum+carry);
		carry=sum/10;
		ListNode *newNode=new ListNode(sum%10);
		newNode->next=head;
		head=newNode;
	}
	
    return head;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值