1. 题目描述

概述:两个逆序存储的非零开头的数字链表,求两数之和,输出也是逆序的链表
leetcode 01 02两个题分别考察了列表在物理存储层面的两种表示方式:数组和链表 的加法
2. 我的解法
暴力:按顺序同时遍历两个链表,按照进位规则进行加法运算,同时需要注意两个数维数不等,以及结果可能维数增加的情况 我的问题是,代码太过复杂:- a. 在初始化L3时,由于不是控制,需要另外计算存储值。应该设立空的表头,放到循环中值。
- b. 在循环之外,分别判断了当两个值不等长时的情况,可以归并到循环中,减少代码函数
1/* Definition for singly-linked list.2* public class ListNode {3* int val;4* ListNode next;5* ListNode(int x) { val = x; }6* }7*/8class Solution {9public ListNode addTwoNumbers(ListNode l1, ListNode l2) {10int num=l1.val+l2.val;11ListNode l3 =new ListNode(num%10);12ListNode head=l3;13//同时遍历两个链表14while(l1.next!=null&&l2.next!=null)15{16l1=l1.next;17l2=l2.next;18num=l1.val+l2.val+num/10;//加上进位19l3.next=new ListNode(num%10);//超出10,求余20l3=l3.next;21}22//如果两个链表不等长,即两个数位数不同,剩下的分别遍历23while(l1.next!=null)24{25l1=l1.next;26num=l1.val+num/10;27l3.next=new ListNode(num%10);28l3=l3.next;29}30while(l2.next!=null)31{32l2=l2.next;33num=l2.val+num/10;34l3.next=new ListNode(num%10);35l3=l3.next;36}37//最后如果相加多出一位,别忘了加上38if(num/10!=0)39l3.next=new ListNode(num/10);40return head;41}42}
- 时间复杂度:O(max(m,n))
- 空间复杂度: O(max(m,n))
3. 解法二
解决我的解法的问题1class ListNode {2int val;3ListNode next;4ListNode(int x) { val = x; }5}6public ListNode addTwoNumbers(ListNode l1, ListNode l2) {7ListNode dummyHead = new ListNode(0);//设置空的链表头8ListNode p = l1, q = l2, curr = dummyHead;9int carry = 0;10while (p != null || q != null) {11int x = (p != null) ? p.val : 0;//当不等长时,补充相应值012int y = (q != null) ? q.val : 0;13int sum = carry + x + y;14carry = sum / 10;15curr.next = new ListNode(sum % 10);16curr = curr.next;17if (p != null) p = p.next;18if (q != null) q = q.next;19}20if (carry > 0) {21curr.next = new ListNode(carry);22}23return dummyHead.next;24} 时空复杂度不变
3. 扩展
如果链表存储的顺序反过来怎么办?
我首先想到的是链表先逆序计算,然后将结果再逆序呗,这就转换到我们之前的情况了。不知道还有没有其他的解法。3.1 下边是单链表逆序的代码。
1 | //逆序 |
2 | ListNode pre = null; |
3 | ListNode head = node; |
4 | while(head!=null) |
5 | { |
6 | ListNode next = head.next;//保留下一个节点,防丢失 |
7 | head.next =pre;//新head接上 |
8 | pre = head;//pre指针指向新head |
9 | head = next;//原列表更换head |
10 | } |