leetcode每天一题2
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
1. 自己的思路
这个题的时候,第一时间想到的是学习数据结构时,课本上讲的有序表的归并算法。所以我是采用这个思路来写的,可能当出学数据结构的时候用的是c语言,所以即便用的时Java也还是没用转变过来。
主要需要做的就是将所有可能出现出现的情况考虑
a. 第一种情况就是两个链表的长度是相等的,所以只需要将对应位置的数进行加减,当出现进位的时候将其中一个链表的下一个位置的数值+1,最后在判断一下,在临界位置(最后一个节点)的加法会不会出现需要进位的情况,如果需要则创建新节点并将新结点的数值置为1.
b.当出先其中一方比另一方的位数多时:就需要将链表分解为两段,最开始的一段为a情况,当其中一个链表走到结尾时,将需要对还有数值的链表进行操作,这时需要判断是否有进位情况,当接受到低位来的进位时,就需要+1,同时判断自身是否已经大于10。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int number=0;//用来存储同位置的两个数的和
ListNode l3;//创造新的链表用于存放和
ListNode l4=new ListNode(0);
l3=l4;
while(l1.next!=null && l2.next!=null){ //说明到目前位置为止这两链表都还没断,可以正常相加减
number=l1.val+l2.val;
if(number>=10){ //当同位置的数相加超过10,是需要进位
number=number%10;
l1.next.val++;//随便找一个链表的节点+1即可
}
l4.val=number;
//找下一个节点
l1=l1.next;
l2=l2.next;
//因为两个链表后续都还有值,所以l4将链接一个节点
l4.next=new ListNode(0);
//将l4也移到下一个节点
l4=l4.next;
}
//如果l1还有后续节点的话
if(l1.next!=null){
//将l1上该结点的值与剩下的一下l2的节点值进行加法运算
number=l1.val+l2.val;
if(number>=10){ //当同位置的数相加超过10,是需要进位
number=number%10;
l1.next.val++; //只能找剩余还有节点的链表的下一个节点+1
}
l4.val=number;
//l1移到下一个节点
l1=l1.next;
l2=l2.next;
//因为l1链表后续都还有值,所以l4将链接一个节点
l4.next=new ListNode(0);
//将l4也移到下一个节点
l4=l4.next;
//将剩余节点(除最后一个节点外)加到新的链表中,如果有进位的进行进位
while(l1.next!=null){
if(l1.val>=10){
l1.val=l1.val%10;
l1.next.val++;
}
l4.val=l1.val;
l4.next=new ListNode(0);
l1=l1.next;
l4=l4.next;
}
//将最后一个节点加到新链表 --需要判断最后一个节点是否为10
if(l1.val>=10){
l4.val=l1.val%10;
l4.next=new ListNode(1);
l4.next.next=null;
}else{
l4.val=l1.val;
l4.next=null;
}
}
else if(l2.next!=null){//如果l2还有后续节点的话
//将l2上该结点的值与剩下的一下l1的节点值进行加法运算
number=l1.val+l2.val;
if(number>=10){ //当同位置的数相加超过10,是需要进位
number=number%10;
l2.next.val++; //只能找剩余还有节点的链表的下一个节点+1
}
l4.val=number;
//l2移到下一个节点
l1=l1.next;
l2=l2.next;
//因为l2链表后续都还有值,所以l4将链接一个节点
l4.next=new ListNode(0);
//将l4也移到下一个节点
l4=l4.next;
//将剩余节点(除最后一个节点外)加到新的链表中,如果有进位的进行进位
while(l2.next!=null){
if(l2.val>=10){
l2.val=l2.val%10;
l2.next.val++;
}
l4.val=l2.val;
l4.next=new ListNode(0);
l2=l2.next;
l4=l4.next;
}
//将最后一个节点加到新链表 --需要判断最后一个节点是否为10
if(l2.val>=10){
l2.val=l2.val%10;
l4.val=l2.val;
l4.next=new ListNode(1);
l4.next.next=null;
}else{
l4.val=l2.val;
l4.next=null;
}
}
else if(l1.next==null&&l2.next==null){//两个链表都没有下一个节点时
number=l1.val+l2.val;
if(number>=10){
number=number%10;
l4.next=new ListNode(1);
l4.next.next=null;
}
l4.val=number;
}
return l3;
//throw new IllegalArgumentException("No two sum solution");
}
}
出现的错误:
a.忘记给新的链表,创建第二个指向他的对象,而是直接对其进行操作,导致最后只能输出末尾数值而是最前的数值全部丢失。
b.在考虑第二种情况时,最后阶段忘记处理,已走到头的对象,导致最后在单独处理剩余链表的剩余部分时,影响结果
2. 官方的题解:
至于官方的思路确实简单而且易懂,这里就不班门弄斧了。代码如下
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head = null, tail = null;
int carry = 0;
while (l1 != null || l2 != null) {
int n1 = l1 != null ? l1.val : 0;
int n2 = l2 != null ? l2.val : 0;
int sum = n1 + n2 + carry;
if (head == null) {
head = tail = new ListNode(sum % 10);
} else {
tail.next = new ListNode(sum % 10);
tail = tail.next;
}
carry = sum / 10;
if (l1 != null) {
l1 = l1.next;
}
if (l2 != null) {
l2 = l2.next;
}
}
if (carry > 0) {
tail.next = new ListNode(carry);
}
return head;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/add-two-numbers/solution/liang-shu-xiang-jia-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。