算法练习(1):Add Two Numbers

准备锻炼一下算法分析和程序设计的能力,现在各大公司都挺看重这方面的能力,然而我感觉这方面能力还有待加强,所以,加油练习吧。。。今天分享一道比较简单的题,没多少思维难度,毕竟刚开始~~~话不多说,进入正文,先上题目:


一看题应该就懂了,这是两个数的加法,但是参数用链表表示,每个数字是一个节点,然后开头节点是最低位。

分析与设计思想:说到加法,就像考虑高精度加法的问题差不多(其实这也是实现高精度加法的一种有效途径),加法,比较需要考虑的是进位问题还有增位问题(结果位数增加)。首先,如何相加,加法都是从最低位开始加,这里链表头就是最低位,正好符合,所以基本思路就是把两个参数链表对应节点相加,加完同时进入各自的下一个节点,然后用一个标志位(代码中的isUp变量)标记是否进位,这时,有个问题就是,两个参数不等长呢?还怎么同时进入各自下一个节点。所以就要考虑如何处理其中一条链表到达尾部的情况。在这里,我想到个办法,就是当A链表没结束,B链表结束时,对应结果链表的节点值就用A链对应节点值加0就好,然后A链继续遍历,直到到达链表尾部。当全部到达尾部时,就可以结束运算了,当然要判断一下isUp的值是否有进位,有进位则要增位。

一开始写的代码是这样的:

/*struct ListNode {
     int val;
     ListNode *next;
     ListNode(int x) : val(x), next(NULL) {}
};*/
class Solution {
 public:
	 ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
		 bool isUp = false;							//判断是否需要进位
		 int sum = 0;								//当前位运算结果
		 ListNode* head = NULL;							//标记结果的首节点
		 ListNode* temp = new ListNode(0);					//用来暂时替代结果节点
		 ListNode* temp1 = l1;							//用来暂时替代替代参数1的节点
		 ListNode* temp2 = l2;							//用来暂时替代替代参数2的节点
		 while (1) {
			 if (temp1 == NULL&&temp2 == NULL) {
				 if (isUp == true) {					//判断在运算结束时是否需要增位
					 temp->next = new ListNode(1);
					 if (head == NULL) head = temp->next;
				 }
				 break;							//只有两条链表都到达尾部时才跳出循环
			 else {
				 if (temp1 == NULL) {
					 sum = 0 + temp2->val;
					 if (isUp == true) {
						 sum += 1;
						 isUp = false;
					 }
					 if (sum>9) {
						 isUp = true;
						 sum -= 10;
					 }
					 temp->next = new ListNode(sum);
					 if (head == NULL) head = temp->next;
					 temp = temp->next;
					 temp2 = temp2->next;
				 }
				 else if(temp2 == NULL) {
					 sum = 0 + temp1->val;
					 if (isUp == true) {
						 sum += 1;
						 isUp = false;
					 }
					 if (sum>9) {
						 isUp = true;
						 sum -= 10;
					 }
					 temp->next = new ListNode(sum);
					 if (head == NULL) head = temp->next;
					 temp = temp->next;
					 temp1 = temp1->next;
				 }
				 else {
					 sum = temp1->val + temp2->val;
					 if (isUp == true) {
						 sum += 1;
						 isUp = false;
					 }
					 if (sum>9) {
						 isUp = true;
						 sum -= 10;
					 }
					 temp->next = new ListNode(sum);
					 if (head == NULL) head = temp->next;
					 temp = temp->next;
					 temp1 = temp1->next;
					 temp2 = temp2->next;
				 }
			 }
		 }
		 return head;
	 }
 };

后来发现有很多的代码重用,就简化了一下,最后的代码如下:

class Solution {
 public:
	 ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
         bool isUp = false;								//判断是否需要进位
		 int sum = 0;								//当前位运算结果
		 ListNode* head = NULL;							//标记结果的首节点
		 ListNode* temp = new ListNode(0);					//用来暂时替代结果节点
		 ListNode* temp1 = l1;							//用来暂时替代替代参数1的节点
		 ListNode* temp2 = l2;							//用来暂时替代替代参数2的节点
		 while (1) {
			 if (temp1 == NULL&&temp2 == NULL) {
				 if (isUp == true) {					//判断在运算结束时是否需要增位
					 temp->next = new ListNode(1);
					 if (head == NULL) head = temp->next;
				 }
				 break;							//只有两条链表都到达尾部时才跳出循环
			 }
			 else {
				 if (temp1 == NULL || temp2 == NULL) {
					 sum = (temp1 == NULL) ? 0 : (temp1->val) + (temp2 == NULL) ? 0 : (temp2->val);
					 if(isUp == true) {				//判断上一位是否有进位
						 sum += 1;
						 isUp = false;
					 }
					 if (sum > 9) {					//判断是否进位
						 isUp = true;
						 sum -= 10;
					 }
					 temp->next = new ListNode(sum);
					 if (head == NULL) head = temp->next;
					 temp = temp->next;
					 if(temp1==NULL) temp2 = temp2->next;
					 else temp1 = temp1->next;
				 }
				 else {
					 sum = temp1->val + temp2->val;
					 if (isUp == true) {
						 sum += 1;
						 isUp = false;
					 }
					 if (sum>9) {
						 isUp = true;
						 sum -= 10;
					 }
					 temp->next = new ListNode(sum);
					 if (head == NULL) head = temp->next;
					 temp = temp->next;
					 temp1 = temp1->next;
					 temp2 = temp2->next;
				 }
			 }
		 }
		 return head;
	 }
 };
当然提交结果是accepted的:


然后标准答案如下:


答案的思路跟我的是差不多的,好了,接下来继续奋战。。。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值