第一次用java刷像样的算法题,收获很多。
题目如下:
给定两个非空链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储单个数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
进阶:
如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。
才知道java也提供了栈操作,但还是没用,参考别人加自己思考
代码如下:
class Solution {
//题目可理解为不改变输入链表
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode resNode = new ListNode(0);
ListNode curr = resNode;
//1.反转节点
ListNode a = esec(l1);
ListNode b = esec(l2);
//2.相加 //判断一次相加是否产生进位
int bit = 0;
while(a != null || b != null){
int x = (a != null)? a.val:0;
int y = (b != null)? b.val:0;
int temp = x + y + bit;
bit = temp/10;
curr.next = new ListNode(temp % 10);
curr = curr.next;
if(a != null)a = a.next;
if(b != null)b = b.next;
}
if(bit > 0) curr.next = new ListNode(bit);
//3.返回反转
return esec(resNode.next);
}
//反转方法
public static ListNode esec(ListNode l){
ListNode node = l;//复制头节点,避免修改源数据。
ListNode store = null;//存储已反转数据的头节点
while(node != null){
//保存当前节点中因改变链表指向而需要改变的数据。
ListNode temp = node.next;
//使当前取出节点指向反转节点头部
node.next = store;
//更新已反转数据的头部
store = node;
//更新元数据头部
node = temp;
}
return store;
}
}
也许是自己以前太菜了,以为java既然封装了内存管理,那类似于C语言中的基于内存管理的链表操作好像是没法在java中实现了,今天才想通,加之看过的jvm也让我对java内存有了更深的认识。
坑一:在反转方法中自己真正体会了一次java引用类型变量的赋值是传的对象的内存地址。
当时对于反转方法的想法是:
1.取出当前节点
2.转换当前节点指向
3.存储已翻转节点头部
4.进入下一次循环
自己当时是这样写的,如果这样写,在第二行中改变node节点的next时,由于temp与node指向同一地址,会导致temp中的next值为store中的next值,而不是原来node中的next的值。经过此次,一定会吸取教训!
ListNode temp = node;
node.next = store;
store = node;
node = temp.next;
还有就是while(a != null || b != null)中既然判断条件为a,b不全为空,那么在进入下一次循环时就应考虑 a或b为空的情况,自己思维也不是很严谨,就这了,加油!