LeetCode-2AddTwoNumbers(C#)
# 题目
2. Add Two Numbers
You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
# 思路
不知道各位能不能看懂题目,简单解释一下,就是把整数每一位颠倒进行加法。题目中给出的例子,最初对应342 + 465 = 807,然后颠倒变成243 + 564 = 708,在转换为链表。
这下题目给出链表的定义,我们需要对这种类型的链表进行操作。
// Definition for singly-linked list. public class ListNode { public int val; public ListNode next; public ListNode(int x) { val = x; } }
方法一:普通遍历,链表l1和l2相应位置相加,再加进位,存入链表result中。
注意点:
- 对于一段长于另外一段的链表部分,单独处理。
- 进位。
- 结果之和长于两个链表的情况,如1 + 999 = 1000。
普通遍历,时间复杂度O(n),空间复杂度O(n),时间204ms。
// normal traversal: time O(n) space O(n) result: 204ms public void calculateSum(ListNode tresult, ref int carry, int sum) { ) { carry = ; tresult.next = ); } else { carry = ; tresult.next = new ListNode(sum); } } public ListNode AddTwoNumbers(ListNode l1, ListNode l2) { ListNode tl1 = l1, tl2 = l2; ListNode result = ); ListNode tresult = result; ; // both ListNode 1 and ListNode 2 have values while (tl1 != null && tl2 != null) { calculateSum(tresult, ref carry, tl1.val + tl2.val + carry); tl1 = tl1.next; tl2 = tl2.next; tresult = tresult.next; } // Debug.Assert(!(tl1 != null && tl2 != null), "tl1 and tl2 aren't null"); // either ListNode 1 or ListNode 2 has values (maybe) and don't forget carry. while (tl1 != null) { calculateSum(tresult, ref carry, tl1.val + carry); tl1 = tl1.next; tresult = tresult.next; } while (tl2 != null) { calculateSum(tresult,ref carry, tl2.val + carry); tl2 = tl2.next; tresult = tresult.next; } // at this time, ListNode 1 and ListNode 2 should be null, however, carry could be null or not // Debug.Assert(tl1 == null && tl2 == null, "calculation doesn't finish"); ) tresult.next = ); // neither ListNode 1 nor ListNode 2 have values return result.next; } */
方法二:空间优化遍历,链表l1和l2相应位置相加,再加进位,存入链表l1中。方法二的代码没有方法一的代码清晰。
空间优化遍历,时间复杂度O(n),空间复杂度O(1),时间208ms。
// use ListNode 1 to restore result // space (and time, I think, but result doesn't prove) optimized traversal: time O(n) space O(1) result: 208ms public ListNode AddTwoNumbers(ListNode l1, ListNode l2) { if (l1 == null) return l2; if (l2 == null) return l1; , sum = ; ListNode pre = null, result = l1; ) { // calculate sum and carry sum = ; if (l1 != null) sum += l1.val; if (l2 != null) { sum += l2.val; l2 = l2.next; // ListNode1 will be used below, ListNode2 not, so if ListNode 2 next exists, ListNode 2 move to next } sum += carry; ) { carry = ; sum -= ; } else { carry = ; } // find a place for sum in ListNode 1, l1 is in use if (l1 != null) { pre = l1; ) sum -= ; l1.val = sum; l1 = l1.next; } else { ) sum -= ; pre.next = new ListNode(sum); pre = pre.next; } } return result; } */
方法三:递归,链表l1和l2相应位置相加,再加进位,存入链表node中。速度最快,是比较好的解决方案。
# 解决(递归)
递归,时间复杂度O(n),空间复杂度O(n),时间196ms。
// recursive tranversal: time O(n) space:O(n) time: 196ms (why it is faster than normal loop) public ListNode AddTwoNumbers(ListNode l1, ListNode l2) { ); } public ListNode AddTwoNumbers(ListNode l1, ListNode l2, int carry) { ) return null; // calculate sum ; if (l1 != null) sum += l1.val; if (l2 != null) sum += l2.val; sum += carry; ) { carry = ; sum -= ; } else { carry = ; } // set node's next and val and return ListNode node = new ListNode(sum); node.next = AddTwoNumbers(l1 != null ? l1.next : null, l2 != null ? l2.next : null, carry); return node; }
# 题外话
为何递归会比循环快呢?百思不得其解,若有高人知道,请指教。
# 测试用例
static void Main(string[] args) { _2AddTwoNumbers solution = new _2AddTwoNumbers(); ListNode l1 = ); ListNode l2 = ); ListNode result = ); // ListNode doesn't have a null constructor, so we can igonore this case Debug.Assert(Test.match(solution.AddTwoNumbers(l1, l2), result), "wrong 1"); // ListNode 1 length is larger than ListNode 2 length l1 = ); l1.next = ); l1.next.next = ); l2 = ); result.next = ); result.next.next = ); Debug.Assert(Test.match(solution.AddTwoNumbers(l1, l2), result), "wrong 2"); // ListNode 2 length is larger than ListNode 1 length and has carries l1 = ); l1.next = ); l2 = ); l2.next = ); l2.next.next = ); result = ); result.next = ); result.next.next = ); result.next.next.next = ); Debug.Assert(Test.match(solution.AddTwoNumbers(l1, l2), result), "wrong 3"); }
class Test { public static bool match(_2AddTwoNumbers.ListNode l1, _2AddTwoNumbers.ListNode l2) { _2AddTwoNumbers.ListNode tl1 = l1, tl2 = l2; while(tl1 != null && tl2 != null) { if (tl1.val != tl2.val) return false; tl1 = tl1.next; tl2 = tl2.next; } if (tl1 == null && tl2 == null) return true; else return false; } }
# 地址
Q: https://leetcode.com/problems/add-two-numbers/
A: https://github.com/mofadeyunduo/LeetCode/tree/master/2AddTwoNumbers
(希望各位多多支持本人刚刚建立的GitHub和博客,谢谢,有问题可以邮件609092186@qq.com或者留言,我尽快回复)
LeetCode-2AddTwoNumbers(C#)的更多相关文章
- LeetCode in action
(1) Linked List: 2-add-two-numbers,2.cpp 19-remove-nth-node-from-end-of-list,TBD 21-merge-two-sorted ...
- 我为什么要写LeetCode的博客?
# 增强学习成果 有一个研究成果,在学习中传授他人知识和讨论是最高效的做法,而看书则是最低效的做法(具体研究成果没找到地址).我写LeetCode博客主要目的是增强学习成果.当然,我也想出名,然而不知 ...
- LeetCode All in One 题目讲解汇总(持续更新中...)
终于将LeetCode的免费题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开个题目汇总贴,并附上每道题目的解题连接,方便之后查阅吧~ 477 Total Hamming Distance ...
- [LeetCode] Longest Substring with At Least K Repeating Characters 至少有K个重复字符的最长子字符串
Find the length of the longest substring T of a given string (consists of lowercase letters only) su ...
- Leetcode 笔记 113 - Path Sum II
题目链接:Path Sum II | LeetCode OJ Given a binary tree and a sum, find all root-to-leaf paths where each ...
- Leetcode 笔记 112 - Path Sum
题目链接:Path Sum | LeetCode OJ Given a binary tree and a sum, determine if the tree has a root-to-leaf ...
- Leetcode 笔记 110 - Balanced Binary Tree
题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...
- Leetcode 笔记 100 - Same Tree
题目链接:Same Tree | LeetCode OJ Given two binary trees, write a function to check if they are equal or ...
- Leetcode 笔记 99 - Recover Binary Search Tree
题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...
- Leetcode 笔记 98 - Validate Binary Search Tree
题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...
随机推荐
- ifconfig: command not found(CentOS专版,其他的可以参考)
ifconfig: command not found 查看path配置(echo相当于c中的printf,C#中的Console.WriteLine) echo $PATH 解决方案1:先看看是不是 ...
- Android数据存储之Android 6.0运行时权限下文件存储的思考
前言: 在我们做App开发的过程中基本上都会用到文件存储,所以文件存储对于我们来说是相当熟悉了,不过自从Android 6.0发布之后,基于运行时权限机制访问外置sdcard是需要动态申请权限,所以以 ...
- Java中Comparable与Comparator的区别
相同 Comparable和Comparator都是用来实现对象的比较.排序 要想对象比较.排序,都需要实现Comparable或Comparator接口 Comparable和Comparator都 ...
- UWP开发之Template10实践二:拍照功能你合理使用了吗?(TempState临时目录问题)
最近在忙Asp.Net MVC开发一直没空更新UWP这块,不过有时间的话还是需要将自己的经验和大家分享下,以求共同进步. 在上章[UWP开发之Template10实践:本地文件与照相机文件操作的MVV ...
- C#如何在PDF文件添加图片印章
文档中添加印章可以起一定的作用,比如,防止文件随意被使用,或者确保文档内容的安全性和权威性.C#添加图片印章其实也有很多实现方法,这里我使用的是免费的第三方软件Free Spire.PDF,向大家阐述 ...
- Spark踩坑记——数据库(Hbase+Mysql)
[TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...
- java中Action层、Service层和Dao层的功能区分
Action/Service/DAO简介: Action是管理业务(Service)调度和管理跳转的. Service是管理具体的功能的. Action只负责管理,而Service负责实施. DAO只 ...
- 【Java每日一题】20170103
20161230问题解析请点击今日问题下方的"[Java每日一题]20170103"查看(问题解析在公众号首发,公众号ID:weknow619) package Jan2017; ...
- Java程序员应该了解的10个面向对象设计原则
面向对象设计原则: 是OOPS(Object-Oriented Programming System,面向对象的程序设计系统)编程的核心,但大多数Java程序员追逐像Singleton.Decorat ...
- 如何使用dos命令查看MySQL当前使用的数据库?
1.dos命令安装mysqld --stall.启动net start mysql.进入MySQL数据库mysql -uroot -p后,输入select database(); 如图: