1.leetcode第二题
给定两个链表,逆序转换为数值相加,在逆序输出新链表。
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.
思路:算法刚开始是最朴素的想法,先将链表转换为整型,然后相加后再转换成链表
while(it1.hasNext()) { p=it1.next(); s1=s1+p*t1; t1*=10; } //链表转整形,p是从低到高各单值,t代表10的次方。 while(s!=0) { leave=s%10; s=s/10; } //整形数分解,leave表示从低到高的各单值。
后来发现测试集有数据超过了int型,改为long型仍然有两个数据超过,改为BigInteger类对象,最后一个数据超级大N位的那种,于是开始改思路。
可以用各位分别相加来计算,然后保留进位,终于第9次Acceptance。
代码:
public ListNode addTwoNumbers(ListNode l1, ListNode l2) { int flag=0; int s; s=(l1.val+l2.val+flag)%10; flag=(l1.val+l2.val+flag)/10; ListNode re=new ListNode(s); l1=l1.next; l2=l2.next; //这一段的作用详见第3点 while(l1!=null || l2!=null) { if(l1==null) { s=(l2.val+flag)%10; flag=(l2.val+flag)/10; ListNode newl=new ListNode(s); add(re,newl); l2=l2.next; } else if(l2==null) { s=(l1.val+flag)%10; flag=(l1.val+flag)/10; ListNode newl=new ListNode(s); add(re,newl); l1=l1.next; } else { s=(l1.val+l2.val+flag)%10; flag=(l1.val+l2.val+flag)/10; ListNode newl=new ListNode(s); add(re,newl); l1=l1.next; l2=l2.next; } } if(flag==1) { ListNode newl=new ListNode(1); add(re,newl); } return re; } void add(ListNode l,ListNode ll) { if(l==null) { l=ll; } while(l.next!=null) { l=l.next; } l.next=ll; }
2.链表复习和BigInteger的初次接触
JAVA和C中的链表不同之处
JAVA中没有指针因此直接用类作为下节点引用:
class ListNode { int val; ListNode next; ListNode(int x) { val = x; } }
C:
typedef struct ListNode { int val; struct ListNode *next; }ListNode,*LinkList; //C语言中结构体不管有没有typedef都有分号。
链表的遍历(简单)
while(l!=null) { //处理l.val l=l.next; }
链表的逆序遍历
if(l!=null) { if(l.next!=null) { //递归调用 } //处理l.val } //注意用if开始,while会陷入死循环。
一般来说使用long就足够,但有时见会遇到处理更大的数,这时我们就可以使用BigInteger对象,初始化BigInteger s=BigInteger.valueOf(10)
add(//BigInteger对象),subtract(),multiply(),divide()加减乘除操作。
divideAndRemainder()返回数组,第一个商,第二个余数。BigDecimal下次介绍。
3.遇见的问题
小问题1:文件名(类名)不能和引入的类名字相同。
小问题2:long超过int边界值后再强制转换为int会变成乱值。
Java的形参改变实参问题与C++的对比:
Java只能改变引用的值,只有类对象和数组(除去String和各基础类型(Integer、Double等)的引用)可以用作形参改变实参。
C++可以使用引用和指针。
只需再形参加上&引用符即可 声明形式void swap(int &a,int &b),调用形式 swap(a,b) 。
声明 void swap(int *a,int *b){函数体使用*a,*b},调用swap(&a,&b),而Java中形式不变。