leetcode之路002 Add Two Numbers

Add Two Numbers

题目大意:用两个链表来代表两个非负的数,这两个数是逆序存在链表中的,并且每一个点中只存放一位数字,现在要加两个数字,用一个此格式的链表来存储并返回。例:

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8

题目有点难理解,刚开始一位只是对应位单纯的相加,然后留下个位数。但上述例子中却不满足,纠结了好长一段时间。感觉leetcode的例子应该多给几个,太长了不便于理解题意= =。

思路:

1、设两个链表指针pl1,pl2,分别指向两个链表首,取各自值相加得temp,判断temp是否大于等于10,若是,则将进位标志位设flag设为1并将temp=temp-10,将temp存到l1链表。完成后,指针分别指向下一个元素。

2、判断两个指针pl1,pl2是否都不为空,若都不为空,则继续讲两个指针的值相加,并加上flag值得temp,判断temp是否大于等于10,若是,则将进位标志位设flag设为1并将temp=temp-10,将temp存到l1链表。完成后,指针分别指向下一个元素。否则执行3。

3、分三种情况:

a:pl1,pl2都为空,即两链表位数相同。此时,若flag=0,则直接返回l1,若flag=1,则需要新建一个结点,其值为1,接到l1的末尾,然后返回l1.

b:pl1不为空,pl2为空。此时,若flag不为0,则取pl1得值加1得temp,并且此时仍需判断temp是否等于10(只可能等于10,不能大于),若大于则将进位标志位设为1。一直循环到flag=0或者,pl1为空为止。例:l1={9,9,9,9,9},l2={1},此时会一直进位。

c:pl1为空,pl2不为空。这种情况和b差不多,但是我的程序结果保存在原来的链表l1中的,因此处理时有一定的差别。

对链表不熟悉,第一次写链表相关的,写的比较复杂冗余。ok,最终ac的代码如下(方便本地调试,加了测试代码的整个程序):

#include<iostream>
#include<algorithm>
#include<algorithm>
using namespace std;

///**
 // 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) {
		ListNode *pl1=l1;
		ListNode *pl2=l2;
		ListNode *ltemp1=pl1;
		ListNode *ltemp2=pl2;
		int temp,flag=0;
		while(pl1&&pl2)
		{
			temp=pl1->val+pl2->val+flag;
			if(temp>=10)
			{
				temp=temp-10;
				flag=1;
			}
			else 
			{
				flag=0;
			}
			pl1->val=temp;
			ltemp1=pl1;
			ltemp2=pl2;
			pl1=pl1->next;
			pl2=pl2->next;
		}
		if(pl1==0&&pl2==0)
		{
			if(flag==0)
				return l1;
			else
			{
				ListNode *ln=new ListNode(1);
				ltemp1->next=ln;
				return l1;
			}
		}
		else if(pl2==0)
		{
			if(flag==0)
				return l1;
			else
			{
				while(flag&&pl1)
				{
					temp=pl1->val+1;
					if(temp==10)
					{
						flag=1;
						pl1->val=0;
						ltemp1=pl1;
						pl1=pl1->next;	
					}
					else 
						flag=0;
				}
				if(pl1==0)
				{
					ListNode *ln=new ListNode(1);
					ltemp1->next=ln;
					return l1;
				}
				else
					pl1->val+=1;
				return l1;
			}
		}
		else if(pl1==0)
		{
			if(flag==0)
			{
				ltemp1->next=pl2;
				return l1;
			}
			
			else
			{	
				ltemp1->next=pl2;
				while(flag&&pl2)
				{
					temp=pl2->val+1;
					if(temp==10)
					{
						flag=1;
						pl2->val=0;
						ltemp2=pl2;
						pl2=pl2->next;	
					}
					else 
						flag=0;
				}
				if(pl2==0)
				{
					ListNode *ln=new ListNode(1);
					ltemp2->next=ln;
					return l1;
				}
				else
					pl2->val+=1;
				return l1;
			}
		}
		return l1;
    }
};

int main()
{	
	ListNode *ll1=new ListNode(3); //测试输入
	ll1->next=new ListNode(7);
	ListNode *ll2=new ListNode(9);
	ll2->next=new ListNode(2);
	Solution so;
	ListNode* rr;
	rr=so.addTwoNumbers(ll1,ll2);
	return 0;
}

此代码运行时间为36ms。感觉在原链表存值有点复杂化了,然后重新写了一个,新建一个链表来存值,代码如下:

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
		ListNode* resu;
		ListNode* temp_resu;
		ListNode* pl1=l1;
		ListNode* pl2=l2;
		int flag=0,temp;
		while(pl1&&pl2)
		{
			temp=pl1->val+pl2->val+flag;
			if(temp>=10)
			{
				temp-=10;flag=1;
			}
			else
				flag=0;
			
			if(pl1!=l1)
			{
				temp_resu->next=new ListNode(temp);
				temp_resu=temp_resu->next;
			}
			else	
			{
				temp_resu=new ListNode(temp);
				resu=temp_resu;
			}
			pl1=pl1->next;pl2=pl2->next;
		}
		if(pl1==0&&pl2==0)
		{
			if(flag)
				temp_resu->next=new ListNode(1);
			return resu;
		}
		else if(pl2==0)
		{
			if(flag==0)
			{
				temp_resu->next=pl1;
				return resu;
			}
			while(flag&&pl1)
			{
				temp=pl1->val+1;
				if(temp==10)
				{
					flag=1;
					temp_resu->next=new ListNode(0);
					temp_resu=temp_resu->next;
					pl1=pl1->next;	
				}
				else 
					flag=0;
			}
			if(flag==0)		
			{
				temp_resu->next=pl1;
				temp_resu->next->val=temp;
			}
			else
			{
				temp_resu->next=new ListNode(1);
			}
			return resu;
		}
		else if(pl1==0)
		{
			if(flag==0)
			{
				temp_resu->next=pl2;
				return resu;
			}
			while(flag&&pl2)
			{
				temp=pl2->val+1;
				if(temp==10)
				{
					flag=1;
					temp_resu->next=new ListNode(0);
					temp_resu=temp_resu->next;
					pl2=pl2->next;	
				}
				else 
					flag=0;
			}
			if(flag==0)		
			{
				temp_resu->next=pl2;
				temp_resu->next->val=temp;
			}
			else
			{
				temp_resu->next=new ListNode(1);
			}
			return resu;
		}
		return resu;
    }
};
结果发现好不了多少,运行时间也一样为36ms。
看了讨论区的最佳代码,感觉自己弱爆了。。。代码如下,好好学习下,感觉主要的问题在于,怎么将多种情况组合处理。

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
		ListNode* resu=new ListNode(0);
		ListNode* temp_resu=resu;
		ListNode* pl1=l1;
		ListNode* pl2=l2;
		int sum=0;
		while(pl1||pl2)
		{
			sum=sum/10;
			if(pl1!=0)
			{
				sum+=pl1->val;
				pl1=pl1->next;
			}
			if(pl2!=0)
			{
				sum+=pl2->val;
				pl2=pl2->next;
			}
			temp_resu->next=new ListNode(sum%10);
			temp_resu=temp_resu->next;
		}
		if(sum/10==1)
		{
			temp_resu->next=new ListNode(1);
		}
		return resu->next;
    }
};

2016.09.01更新 JAVA代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode res = new ListNode(0);
        ListNode node = res;
        boolean flag = false;
        int value = 0;
        while(l1!=null && l2 !=null) {
            value = flag ? l1.val + l2.val + 1 : l1.val + l2.val;
            flag = value >= 10 ? true : false;
            node.next = new ListNode(value % 10);
            node = node.next;
            l1 = l1.next;
            l2 = l2.next;
        }
        while(l1 != null) {
            value = flag ? l1.val + 1 : l1.val;
            flag = value >= 10 ? true : false;
            node.next = new ListNode(value % 10);
            node = node.next;
            l1 = l1.next;
        }
        while(l2 != null) {
            value = flag ? l2.val + 1 : l2.val;
            flag = value >= 10 ? true : false;
            node.next = new ListNode(value % 10);
            node = node.next;
            l2 = l2.next;
        }
        if(flag) {
            node.next = new ListNode(1);
        }
        return res.next;
    }
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值