力扣算法第二题:两数相加

力扣第二题

前面后来自己做的,后面是之前看答案的思路

题目

两数相加
两数相加

思路及问题

1.首先想了最笨的方法,就是先把两个数分别提出来,然后直接相加,最后得出一个数,然后再把他放进链表里。。。代码如下

public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
		int num1 = 0;
		int num2 = 0;
		int sum = 0;
		// 幂次方
		int i = 0;
		// 记录最大的次幂,方便用模运算后面拆分
		int j = 0;
		while (l1 != null) {
			num1 = l1.val * (int)Math.pow(10, i) + num1;
			i++;
			l1 = l1.next;
		}
		j = 1;
		i = 0;
		while (l2 != null) {
			num2 = l2.val * (int)Math.pow(10, i) + num2;
			i++;
			l2 = l2.next;
		}
		i = 3;
		sum = num1 + num2;
		while (sum / Math.pow(10, j) > 0) {
			j++;
		}
		ListNode output = new ListNode((int) (sum % 10));
		if (sum < 10) {
			return output;
		}
		ListNode node = new ListNode((int) (sum % 100 / 10));
		output.next = node;
		int temp;
		while (i <= j) {
			node.next = new ListNode((int) (sum % Math.pow(10, i) / Math.pow(10, i - 1)));
			node = node.next;
			i++;
		}
		return output;
	}

但是有个问题,里面的数超过了int最大值就会出错!换成long或者double之后要么运行超时,要么出错,要么超时,无奈,只能用另外一种方法了

  1. 另一种方法比较明智,就是每一位各自相加,然后有进位就提出来,然后再下一位计算的时候放进去。
    注意: 每次进位之后,相加,要继续判断。 然后就是如果两个数长度不相等得处理。以下自己做的代码:
	public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
		ListNode t1 = l1;
		ListNode t2 = l2;
		int jinwei = 0;
		ListNode output;
		if (t1.val + t2.val < 10) {
			output = new ListNode(t1.val + t2.val);
			jinwei = 0;
		} else {
			output = new ListNode(t1.val + t2.val - 10);
			jinwei = 1;
		}
		ListNode out = output;
		while (t1.next != null && t2.next != null) {
			t1 = t1.next;
			t2 = t2.next;
			if (t1.val + t2.val + jinwei < 10) {
				output.next = new ListNode(t1.val + t2.val + jinwei);
				jinwei = 0;
			} else {
				output.next = new ListNode(t1.val + t2.val - 10 + jinwei);
				jinwei = 1;
			}
			output = output.next;
		}
		while(t1.next != null) {
			t1 = t1.next;
			if (t1.val + jinwei < 10) {
				output.next = new ListNode(t1.val + jinwei);
				jinwei = 0;
			} else {
				output.next = new ListNode(t1.val - 10 + jinwei);
				jinwei = 1;
			}
			output = output.next;
		}
		while(t2.next != null) {
			t2 = t2.next;
			if (t2.val + jinwei < 10) {
				output.next = new ListNode(t2.val + jinwei);
				jinwei = 0;
			} else {
				output.next = new ListNode(t2.val - 10 + jinwei);
				jinwei = 1;
			}
			output = output.next;
		}
		if(jinwei == 1) {
			output.next = new ListNode(1);
			jinwei = 0;
		}
		return out;
	}

最后如果还有进位的话,记住最后再加一位。

在这里插入图片描述

总结

基本就是在题目下,先大题想一个思路,然后编码,放进去调试,根据错误点继续修改。


----------------------------------------------------------我是分割线---------------------------------------------------------------------


1.首先,没学过怎么用java表示链表,或者学过忘了。所以得查一下怎么表示。
JAVA表示链表*[作者YSOcean]
2.行吧,看了一下午还是不会,然后就直接看答案了,看答案还是有点一愣一愣的,理解得有点模糊,状态都不在了,先缓一下。但是先贴上答案代码,然后再说说自己的理解。

代码

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    ListNode dummyHead = new ListNode(0);
    ListNode p = l1, q = l2, curr = dummyHead;
    int carry = 0;
    while (p != null || q != null) {
        int x = (p != null) ? p.val : 0;
        int y = (q != null) ? q.val : 0;
        int sum = carry + x + y;
        carry = sum / 10;
        curr.next = new ListNode(sum % 10);
        curr = curr.next;
        if (p != null) p = p.next;
        if (q != null) q = q.next;
    }
    if (carry > 0) {
        curr.next = new ListNode(carry);
    }
    return dummyHead.next;
}

理解

  • 首先看它原题给出的单向链表的代码
  //Definition for singly-linked list.
  public class ListNode {
      int val;
      ListNode next;
      ListNode(int x) { val = x; }
  }

这里的val就是一个链表里存的值,next存的是指向下一个链表的地址。然后一个构造函数,把参数的值赋予到链表类的变量中。

然后就看答案给的代码了,一步一步讲。

  • 第一条代码
ListNode dummyHead = new ListNode(0);

设置一个最头头的节点,作用就是引出相加和得出的节点,0为参数,得出的答案就是0xxxx(xxx为整数);

  • 然后两条
ListNode p = l1, q = l2, curr = dummyHead;
   int carry = 0;
  1. 前面一句没啥,就是换一下变量,(应该算是方便?),然后第二句是进制,就是两个个位数相加溢出,carry就得1(微原倒是有详细的说),再说下这的思路。
  2. 本来我的思路是用一个整数sum把链表里每个数通过循环然后相加然后乘十再相加的方法,把两个链表中的数提取出来,相加完,再分解存进链表里的。然后一开始链表就卡主了。
  3. 答案这种思路也想过,只是想得个大概,各个对应的数相加,溢出就拿东西存着。但真正看这答案的实现,还是挺复杂的,想不到这么绕。
  • 接着看循环体
while (p != null || q != null) {
        int x = (p != null) ? p.val : 0;
        int y = (q != null) ? q.val : 0;
        int sum = carry + x + y;
        carry = sum / 10;
        curr.next = new ListNode(sum % 10);
        curr = curr.next;
        if (p != null) p = p.next;
        if (q != null) q = q.next;
    }
  1. 首先循环条件是p不为空或q不为空,也就是两个不同时为空,空就是这个节点没有任何东西,没有val,没有next。为什么要求不同时为空呢?这是以防出现一个的位数比另外一个的位数多的情况,这时,空的一方,就可以将其值设置为0,然后与不空的节点的值相加。
  2. x,y的初始化就是把p和q的val值存起来,如果p或q为空的话,则设置为0
  3. 相加
  4. 因为carry是int类型,而carry+x+y最大的值不超过19(carry=1,x=9,y=9),所以carry等于1或者0(用于处理加法溢出,然后进一位)
  5. 将得出的数模十(因为要求一个结点只取一位,所以只取个位,溢出的十位由carry存储,并加入下一次加法中),将得出的个位存到curr的next指针中(0开头,然后开始存储下一位)
  6. 下面三步都是准备下一步循环,将下一节点存储上当前节点,以便进行下一次循环,直至p和q都为空,然后就curr以0开头的链表就存了除最后一位可能进制的位数外所有l1和l2的对应数的 和。
  • 然后当然是解决最后一位可能进制的位数啦
if (carry > 0) {
        curr.next = new ListNode(carry);

在整个循环结束后,最后补上,如果carry>0,也就是,最后一次循环,两个对应的节点存储的数相加,还有溢出的(还有进一位的),就再新建一个参数为carry的节点,存到curr.next中去。完成了最后一步。

  • 最后返回
return dummyHead.next;

返回以dummyHead.next开头的链表,也就是以curr.next开头的,最后两个对应数相加(或者溢出的数)得出的结果为开头的链表。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
力扣第二是一道链表相关的目,要求实现一个函数来将两个非负整数链表相加,并返回一个新的链表表示它们的和。 在解决这个问时,可以设立一个表示进位的变量carried,并建立一个新的链表来存储结果。然后,使用while循环来同时处理两个输入链表,每次取出对应的节点值相加,并将结果加上进位值carried后的值作为一个新节点加入新链表的后面。当遍历完两个链表后,如果最后还有进位,需要再添加一个节点来存储进位的值。最后返回新链表的头节点即可。 下面是使用Java语言编写的实现代码: ```java public class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode dummy = new ListNode(0); int sum = 0; ListNode cur = dummy; ListNode p1 = l1, p2 = l2; while (p1 != null || p2 != null) { if (p1 != null) { sum += p1.val; p1 = p1.next; } if (p2 != null) { sum += p2.val; p2 = p2.next; } cur.next = new ListNode(sum % 10); sum /= 10; cur = cur.next; } if (sum == 1) { cur.next = new ListNode(1); } return dummy.next; } } ``` 以上就是力扣两数相加第二Java实现代码。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [【Java版】LeetCode 力扣第 2 两数相加 (Add Two Numbers)](https://blog.csdn.net/monokai/article/details/108132843)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值