**
Question:
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
**
My code:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
if (l1 == null && l2 == null)
return null;
if (l1 == null)
return l2;
if (l2 == null)
return l1;
int carry = 0;
int digit = 0;
int val1 = l1.val;;
int val2 = l2.val;;
int sum = val1 + val2 + carry;
digit = sum % 10;
carry = sum / 10;
ListNode temp = new ListNode(digit);
ListNode head = temp;
val1 = 0;
val2 = 0;
l1 = l1.next;
l2 = l2.next;
while (l1 != null || l2 != null) {
if (l1 != null) {
val1 = l1.val;
l1 = l1.next;
}
if (l2 != null) {
val2 = l2.val;
l2 = l2.next;
}
sum = val1 + val2 + carry;
digit = sum % 10;
carry = sum / 10;
temp.next = new ListNode(digit);
temp = temp.next;
val1 = 0;
val2 = 0;
}
if (carry != 0) {
temp.next = new ListNode(carry);
temp = temp.next;
}
return head;
}
public static void main(String[] args) {
Solution test = new Solution();
ListNode n1 = new ListNode(1);
ListNode n2 = new ListNode(9);
ListNode n3 = new ListNode(9);
ListNode n4 = new ListNode(9);
ListNode n5 = new ListNode(9);
ListNode n6 = new ListNode(9);
ListNode n7 = new ListNode(9);
ListNode n8 = new ListNode(9);
ListNode n9 = new ListNode(9);
ListNode n10 = new ListNode(9);
n1.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
n5.next = n6;
n6.next = n7;
n7.next = n8;
n8.next = n9;
n9.next = n10;
n10.next = null;
ListNode l1 = new ListNode(9);
ListNode result = test.addTwoNumbers(l1, n1);
while (result != null) {
System.out.print(result.val);
result = result.next;
}
}
}
My test result:
Paste_Image.png
这次题目,额。不难。但我的确想错思路了。所以十分钟写好了代码,花了一个小时也没有测试通过。因为我的思路,本质是错误的。
我的思路是,将第一个链表的值一个个取出来,拼成字符串,再转换为整型。第二个也如此。再把他们加起来。然后再转换会链表形式。
这其中有个问题。
当两个链表取出来的数字都特别大,
JAVA int 是32bit, 范围大概从负的二十几亿到正的二十几亿。如果超出了这个范围,Integer.parseInt()这个方法就不能再使用了。我当时在想,怎么才能解决这个问题呢。我觉得这是语法的问题。我就去寻找新的方法。但没找到。其实这不是语法问题。即使有个方法可以解决int越界。用long来接收。如果数据再次超过了long的范围怎么办?没有一劳永逸的方法来解决这个问题。
于是,我只能去看了discuss。换了一种思路。更简单的思路。
实现一个简单的加法器。
最低位先相加,得到其输出以及进位。
然后将进位和两个链表的之后一位,一共三个数,一起相加。
以此类推。
然后问题就解决了。
主要还是思录错了吧。
附上我一开始写的转换字符串的代码。
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
if (l1 == null && l2 == null)
return null;
if (l1 == null)
return l2;
if (l2 == null)
return l1;
// get the integer in list1
int num1 = 0;
String numStr1 = "";
while (l1 != null) {
numStr1 = Integer.toString(l1.val) + numStr1;
l1 = l1.next;
}
if (numStr1.length() >= "2147483647".length() && numStr1.compareTo("2147483647") > 0)
return null;
num1 = Integer.parseInt(numStr1);
// get the integer in list2
int num2 = 0;
String numStr2 = "";
while (l2 != null) {
numStr2 = Integer.toString(l2.val) + numStr2;
l2 = l2.next;
}
if (numStr2.length() >= "2147483647".length() && numStr2.compareTo("2147483647") > 0)
return null;
num2 = Integer.parseInt(numStr2);
// return the sum
int sum = num1 + num2;
int digit = 0;
ListNode temp = new ListNode(sum % 10);
ListNode head = temp;
sum = sum / 10;
while (sum != 0) {
digit = sum % 10;
temp.next = new ListNode(digit);
temp = temp.next;
sum = sum / 10;
}
return head;
}
}
**
总结:
Java int 32 bit,当心越界。不是所有的数字 Integer.parseInt 都可以处理的。
简单的加法器。
**
之前说好的一天一道题目,打断了。
回国倒计时一个月了。哦,不,是二十天。
第一,为什么回国前的最后这一个月这么难熬。
第二,时间过得好快。
五月初的时候差点和女朋友分手。自己的精神受到了很大的打击。身体也受到了很大的打击。
这是我停止刷题的最本质原因。没有任何借口。在那之前,我的各方面状态都很好。
闹分手的时候,我当时觉得自己什么都不要了,什么都没有了。
整个人很颓废。很害怕。然后放弃了一切。就窝在汗臭味极其严重的被窝里,不知道干什么。
后来还是和好了。我也在想,以后去了美国,如果又发生激烈的冲突。我在这么颓废一段时间,我的人生轨迹应该会受很大影响吧。毕竟去了美国就要开始找工作了,然后一切真的会很忙很忙。
只不过这次的确伤的够深,下次再来下,可能不会再有这次这么痛了。
分手果然不是一次就能分的掉的。但是一次次分手之后复合,这段关系在本质上,正朝着分手的方向走。
我还是不想分手的。我想她也是。
我不能保证以后我们会在一起,那太幼稚了。
我只能保证,现在的我,想和她以后在一起。
忙完了这段事,紧接着家里爸妈发生了十分激烈的争吵。然后正逢我考试,但我妈找不到倾诉的对象,只有她的儿子可以倾诉。我也明白。她需要人安慰,理解。
于是我一般复习着知识点,做着题目,一边还得安慰她。
我的确越来越明白一个男人,到底该长什么样了。
男人可以承担一切责任,一切委屈,而不吭一声。然后,继续向前。
Because we are a man.
然后,家里的事逐渐平息,结果今天又有一件不开心的事发生了。
路上走的挺好的,一个白人就过来嘲讽我们中国人。
这是我在国外第一次碰到这种情况。
我没听懂他说什么,但是,那种语气,一定是极其恶意的。我无法忘记。
他骑着车。
他没想到我会回头。我回头,问了句, pardon。
他回了句, parden?
嘲讽我的英语。
然后开始说屁话。我已经明显感受到了他的恶意。所以也严肃了起来。
他也知道可能要开打了。开始叫他的朋友过来,准备一起打。
我心里其实是怕的。
我不是怕打不过他们。或者被他们打。
我怕的是,在英国这么一块极其排外,尤其排斥中国人的国家,我打了,去了警察局,警察一定会帮他们,而且他们还会说,我口语不行,对法律也不了解。而且,一天后又要考试了。如果因为这件事错过了考试,我的毕业证将拿不到。我的美国之行也将作废。
太多的顾虑。
中国人的传统想法就出来了。
多一事不如少一事。和这些没文化的人,没必要较真。
正好同伴也拉我,我就回头继续走了。然后我能听到背后,那人在说着,
Fuck you.
这一切都好像电影里演的那样,但的确就这么真实的发生了。
我和一个朋友说了这件事,他说,还是大部分中国人太懦弱了,总觉得多一事不如少一事,就这么忍过去了。然后老外就觉得中国人好欺负。
在我看来,不是这样的。
我不知道怎么,英国这个国家,对于中国,以及中国文化,就有一种很大的误解。
我去过曼彻斯特,去过伦敦。去过那里的唐人街。唐人街都有一块匾,上面写着唐人街。
结果这些地方的唐人街牌匾,无疑不是用紫光照着的。
晚上的时候过去,看着紫光下的唐人街,就感觉这块地方是吸鸦片嫖娼的地方。很暧昧,很软弱。
中国早就不是那样的中国了。
所以,虽然每年大量的留学生出国读书,但中国文化并没有很好地传送进入欧美国家。甚至基本没有进步。
我们必须得重视文化的传输,这样才能从根本上改变老外对中国人的看法。当然,总会有一些极端分子,就是仇视中国。
其次,我们要扬国威。
英国人为什么对日本人毕恭毕敬。除了这个国家强大的经济能力和素质。也有历史的原因。
二十世纪初的时候欧美国家是看不上亚洲国家的。结果日本接连战胜了中国,俄罗斯,在越南缅甸又把英国打的打败,屠杀英国军人,美国军人。
首先,站在道德高度,日本军人是错的。
但是,站在一个客观的角度,的确通过这种最极端的方式,快速的根正了欧美人对日本人的看法,知道他们不好惹。这就好比小孩打架。可能你一直瞧不起一个小孩,哪一天,突然被他狠狠揍了一顿,你还敢看不起吗?
文化传输来改变老外对中国的印象,是慢速的,和平的,健康的方式。
战争来改变老外对中国的印象,是快速的,非和平的,恶劣的方式,但往往更有效果。
人总是贱的,总是服比他强壮的人。
弱肉强食,在哪里都改变不了。
再过二十年,我想中国一定可以达到这么一个高度,不怒自威。
希望祖国更加强大!
Anyway, Good luck, Richardo!
My code:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
if (l1 == null)
return l2;
else if (l2 == null)
return l1;
ListNode dummy = new ListNode(-1);
ListNode pre = dummy;
int carry = 0;
while (l1 != null && l2 != null) {
int sum = l1.val + l2.val + carry;
carry = sum / 10;
ListNode curr = new ListNode(sum % 10);
pre.next = curr;
pre = curr;
l1 = l1.next;
l2 = l2.next;
}
if (l2 != null) { // add carry to l2
while (l2 != null) {
int sum = l2.val + carry;
carry = sum / 10;
ListNode curr = new ListNode(sum % 10);
pre.next = curr;
pre = curr;
l2 = l2.next;
}
}
else if (l1 != null) {
while (l1 != null) {
int sum = l1.val + carry;
carry = sum / 10;
ListNode curr = new ListNode(sum % 10);
pre.next = curr;
pre = curr;
l1 = l1.next;
}
}
if (carry != 0) {
pre.next = new ListNode(carry);
}
return dummy.next;
}
}
自己写了出来,但是错了几次。错在哪里?
1.当 l1, l2 都为null时,不代表结果已经出来了。 carry可以单独形成一个结点。
2.当l1 先为null,l2再为null,不代表结果已经出来了。 carry仍然可以单独形成一个结点。
看了下之前的做法。while (l1 != null || l2 != null) {…}
的确要比我的代码简单一些。
Anyway, Good luck, Richardo!
My code:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
if (l1 == null || l2 == null) {
return (l1 == null ? l2 : l1);
}
ListNode p1 = l1;
ListNode p2 = l2;
int carry = 0;
ListNode dummy = new ListNode(-1);
ListNode curr = dummy;
while (p1 != null || p2 != null) {
if (p1 == null) {
int sum = carry + p2.val;
carry = sum / 10;
sum = sum % 10;
curr.next = new ListNode(sum);
curr = curr.next;
p2 = p2.next;
}
else if (p2 == null) {
int sum = carry + p1.val;
carry = sum / 10;
sum = sum % 10;
curr.next = new ListNode(sum);
curr = curr.next;
p1 = p1.next;
}
else {
int sum = carry + p1.val + p2.val;
carry = sum / 10;
sum = sum % 10;
curr.next = new ListNode(sum);
curr = curr.next;
p1 = p1.next;
p2 = p2.next;
}
}
if (carry != 0) {
curr.next = new ListNode(carry);
}
return dummy.next;
}
}
需要注意的一个地方就是,即使p1, p2 都是null了,但是,如果carry != 0, 仍需要多加一个结点。
Anyway, Good luck, Richardo! — 08/16/2016