(一)、单链表实现

package com.lin.leetcode.addTwoNumbers;

/**
* Created by Yaooo on 2019/8/26.
*/
public class ListNode {
int data;
ListNode next;
ListNode(int data){
this.data = data;
}
}
package com.lin.leetcode.addTwoNumbers;

import java.util.List;

/**
* Created by Yaooo on 2019/8/25.
*/
public class SingleLinkedList{ public int size;
public ListNode head; // head|next ->null
public SingleLinkedList(){
size = 0;
head = null;
} // head -> a|next ->b|next ->null
public void addData(int obj){
ListNode node = new ListNode(obj);
if(size == 0){
head = node;
node.data= obj;
}else{
node.next = head;
head = node;
node.data = obj;
}
size++;
}
// head -> a|next ->b|next ->c|next ->null
public boolean deleteData(int value){
if (size == 0){
return false;
}
ListNode current = head;
ListNode previous = head;
while(current.data!=value){
if (current.next == null){
return false;
}else{
previous = current;
current = current.next;
}
}
if(current == head){
head = current.next;
size--;
}else {
previous.next = current.next;
size--;
}
return true;
} public void display(){
ListNode node = head;
while (node!=null){
if (node.next==null){
System.out.print(node.data );
node = node.next;
}else{
System.out.print(node.data + "->");
node = node.next;
}
}
} public static void main(String[] args){
SingleLinkedList list = new SingleLinkedList();
list.addData(1);
list.addData(2);
list.addData(5);
list.deleteData(5);
list.display();
} }

实现单链表两数相加:

思路

我们使用变量来跟踪进位,并从包含最低有效位的表头开始模拟逐位相加的过程。

图1,对两数相加方法的可视化: 342 + 465 = 807342+465=807,每个结点都包含一个数字,并且数字按位逆序存储。

算法

就像你在纸上计算两个数字的和那样,我们首先从最低有效位也就是列表 l1l1 和 l2l2 的表头开始相加。由于每位数字都应当处于 0 \ldots 90…9 的范围内,我们计算两个数字的和时可能会出现 “溢出”。例如,5 + 7 = 125+7=12。在这种情况下,我们会将当前位的数值设置为 22,并将进位 carry = 1carry=1 带入下一次迭代。进位 carrycarry 必定是 00 或 11,这是因为两个数字相加(考虑到进位)可能出现的最大和为 9 + 9 + 1 = 199+9+1=19。

伪代码如下:

  • 将当前结点初始化为返回列表的哑结点。
  • 将进位 carry 初始化为 0。
  • 将 p 和 q 分别初始化为列表 l1 和 l2 的头部。
  • 遍历列表 l1 和 l2 直至到达它们的尾端。
  1. 将 x 设为结点 p 的值。如果 pp 已经到达 l1 的末尾,则将其值设置为 0。
  2. 将 y 设为结点 qq 的值。如果 qq 已经到达 l2 的末尾,则将其值设置为 0。
  3. 设定 sum=x+y+carry。
  4. 更新进位的值,carry=sum/10。
  5. 创建一个数值为(sum mod 10) 的新结点,并将其设置为当前结点的下一个结点,然后将当前结点前进到下一个结点。
  6. 同时,将 p 和 q 前进到下一个结点。
  • 检查carry=1 是否成立,如果成立,则向返回列表追加一个含有数字 11 的新结点。
  • 返回哑结点的下一个结点。

请注意,我们使用哑结点来简化代码。如果没有哑结点,则必须编写额外的条件语句来初始化表头的值。

请特别注意以下情况:

测试用例 说明

package com.lin.leetcode.addTwoNumbers;

import java.lang.reflect.Array;

/**
* Created by Yaooo on 2019/8/25.
*/
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dumpHead = new ListNode(0);
ListNode p = l1, q = l2, curr = dumpHead;
int carry = 0;
while (p != null || q != null) {
int x = (p != null) ? p.data : 0;
int y = (q != null) ? q.data : 0;
int sum = x + y + carry;
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 dumpHead.next;
} public static void main(String[] args){
SingleLinkedList l1 = new SingleLinkedList();
l1.addData(1);
l1.addData(2);
l1.addData(5);
SingleLinkedList l2 = new SingleLinkedList();
l2.addData(3);
l2.addData(2);
l2.addData(7);
Solution solution = new Solution();
ListNode l3 = solution.addTwoNumbers(l1.head,l2.head);
while (l3!=null){
if(l3.next == null ){
System.out.print(l3.data);
l3 = l3.next;
}else{
System.out.print(l3.data+"->");
l3 = l3.next;
}
}
}
}

复杂度分析

时间复杂度:O(max(m,n)),假设 mm 和 nn 分别表示 l1l1 和 l2l2 的长度,上面的算法最多重复max(m,n) 次。

空间复杂度:O(max(m,n)), 新列表的长度最多为max(m,n)+1。

拓展

如果链表中的数字不是按逆序存储的呢?例如:

(3→4→2)+(4→6→5)=8→0→7

算法引用于链接:https://leetcode-cn.com/problems/add-two-numbers/solution/liang-shu-xiang-jia-by-leetcode/

最新文章

  1. 如何使用JS来检测游览器是什么类型,或android是什么版本号- 转载
  2. 【转】Caffe初试(六)激活层及参数
  3. Json_异常_net.sf.json.JSONException: JSONObject["solution"] not found.
  4. 网络编程3--毕向东java基础教程视频学习笔记
  5. C#实现大数字的运算
  6. .NET设计模式(7):创建型模式专题总结(Creational Pattern)(转)
  7. [转]如何编译tizen源码(图文教程)?
  8. 谢尔排序/缩减增量排序(C++)
  9. QT下的几种透明效果(三种方法:调色板,透明度属性,自绘)
  10. BZOJ 1649: [Usaco2006 Dec]Cow Roller Coaster( dp )
  11. poj3468 A Simple Problem with Integers(线段树模板 功能:区间增减,区间求和)
  12. C#中常用关键字的作用
  13. PHP奇怪现象
  14. java 数组流
  15. 在Intellij Idea中使用JSTL标签库
  16. 关于request、response转发与重定向的简述
  17. Dev修改gridview 背景色
  18. 动态环境下的slam问题如何解决?
  19. 一只青蛙从第一级台阶跳到第n级,每次可以跳任意级,共有多少种跳法,并写出递推式
  20. std__vector介绍

热门文章

  1. [小试牛刀]部署在IDEA的JFinal 3.0 demo
  2. Rsync+sersync部署
  3. PREPARE - 创建一个准备好的查询
  4. UVAlive 3485 Bridge(抛物线弧长积分)
  5. [Luogu1436]棋盘分割(动态规划)
  6. pandas数据查询(数值、列表、区间、条件、函数)
  7. linux下caffe的命令运行脚本
  8. 06 IntelliJ IDEA构建多模块项目
  9. selenium 浏览器无界面模式运行
  10. UE4-PS4开发渲染线程优化方法及记录