经过面试之后,感觉除了实习经历和项目经历之外,编程基础也很重要,其中算法和数据结构尤为重要。因此,最近没事的话,就会在leetcode上刷题,今天恰好遇到了一个知识的盲区——链表,在解题过程中同时利用首次尝试使用单元测试进行代码的测试(以前都是自己写main函数或者或其他方式测试)。
下面,分享给大家,并提供自己的解题过程。
题目:
You are given two non-empty linked lists representing two non-negative integers. 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.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
其实就是243,564反过来342+465=807(反过来就是708),题目的前提是假定两个数字不包含前置0。
下面是本人的解题代码:
package test;
//* Definition for singly-linked list.
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public class linklist {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) throws Exception {
ListNode res=new ListNode(0);
ListNode head=res;//这一步关键,需要返回链表的头节点
int last_val=0;
int cur_val;
int l1_val,l2_val;
while(l1!=null||l2!=null){
if((l1!=null&&l1.val==0&&l1.next==null)||(l2!=null&&l2.val==0&&l2.next==null)){//判断是否链表中有前置0
throw new Exception("输入的链表有前导0");
}
l1_val=l1==null?0:l1.val;
l2_val=l2==null?0:l2.val;
cur_val=l1_val+l2_val+last_val;
last_val=cur_val/10;
res.val=cur_val%10;//需要取余,因为可能会进位
if(((l1!=null&&l1.next==null)||l1==null)&&((l2!=null&&l2.next==null)||l2==null)){//该条件判断很重要
if(cur_val>=10){
res.next=new ListNode(1);
res=res.next;
res.next=null;
}
res.next=null;
return head;
}
res.next=new ListNode(1);
res=res.next;
l1=l1==null?null:l1.next;
l2=l2==null?null:l2.next;
}
return head;
}
}
单元测试
package test;
import static org.junit.Assert.*;
import org.hamcrest.core.Is;
import org.junit.Test;
public class junit {
@Test
public void testAddTwoNumbers() {
ListNode l1=new ListNode(2);
ListNode l1_head=l1;
l1.next=new ListNode(4);
l1=l1.next;
l1.next=new ListNode(4);
l1=l1.next;
l1.next=null;
ListNode l2=new ListNode(9);
ListNode l2_head=l2;
l2.next=new ListNode(0);
l2=l2.next;
// l2.next=new ListNode(6);
// l2=l2.next;
l2.next=null;
ListNode res=null;
try {
res = new linklist().addTwoNumbers(l1_head, l2_head);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ListNode actual = new ListNode(1);
ListNode actual_head=actual;
actual.next=new ListNode(1);
actual=actual.next;
actual.next=new ListNode(5);
actual=actual.next;
// actual.next=new ListNode(1);
// actual=actual.next;
actual.next=null;
while(res!=null){
assertEquals(res.val, actual_head.val);
System.out.println(res.val);
System.out.println(actual_head.val);
res=res.next;
actual_head=actual_head.next;
}
}
}
测试结果如下:
测试通过(看右侧进度条为绿色)。
解题技巧:
(1)链表遍历最后一次的条件判断,因为有一种情况可能不太一样(可能需要进位,新的一位为1)。
例如:
l1: 2-->4-->9;
l2: 5-->6
结果应该:
7-->0-->0-->1
(2)两个链表可能长度不一样
(3)就是返回的结果应该是链表的首节点
所用知识点:
(1)链表(单向链表,双向链表,循环链表)
链表原理http://blog.csdn.net/jianyuerensheng/article/details/51200274
(2)单元测试
单元测试http://blog.csdn.net/liushuijinger/article/details/32140843
链接分享
在线编程测试网站:
https://leetcode.com(会有详细的解题思路,以及各个用户自己提交的代码以供相互交流)