题目要求:
用单向链表表示十进制整数,求两个正整数的和。
示例一:9999+999=10998,链表表示为:9->9->9->9->null和9->9->9->null的结果为1->0->9->9->8->null
示例二:12+34=46。,链表表示为:1->2->null和3->4->null的结果为4->6->null
注意单项链表的方向从前向后,不允许使用其他数据结构。
思路:
1. 如果有空链表,直接返回
2. 判断两个链表是否等长,不等长则左补0使之等长
3. 十进制加法需要进位,反转链表再相加更方便
4. 相加后,再次反转链表即为结果
代码:
链表定义:
public class ListNode { ListNode next = null; int value; // 节点数据 public ListNode(int value) { this.value = value; } }
主要方法代码如下:
public ListNode addTwoNumbers(ListNode listNode1, ListNode listNode2){ // 如果有空链表,直接返回 if(listNode1 == null) { return listNode2; }else if(listNode2 == null) { return listNode1; } // 判断两个链表是否等长,不等长则左补0使之相等 if(size(listNode1) > size(listNode2)) { listNode2 = complete(listNode2, size(listNode1) - size(listNode2)); }else if(size(listNode1) < size(listNode2)) { listNode1 = complete(listNode1, size(listNode2) - size(listNode1)); } // 反转链表 listNode1 = reserveLink(listNode1); listNode2 = reserveLink(listNode2); ListNode resultListNode = new ListNode(0); ListNode listNode = resultListNode; int sum = 0; // 相加总和 int prog = 0; // 进位值 while(listNode1 != null && listNode2 != null) { sum = listNode1.value + listNode2.value + prog; prog = sum / 10; sum = sum % 10; listNode.next = new ListNode(sum); // 尾插法 listNode = listNode.next; // 后移 listNode1 = listNode1.next; listNode2 = listNode2.next; } // 最高位还有进位 if(prog != 0){ listNode.next = new ListNode(prog); }else { // 去掉最前面的0,防止反转后数值不对 resultListNode = resultListNode.next; } return reserveLink(resultListNode); }
获取链表长度:
public int size(ListNode node) { if(node == null) { return 0; } int size = 0; while(node != null) { node = node.next; size++; } return size; }
左补N个0:
public ListNode complete(ListNode node, int num) { if(node == null) { return node; } if(num <= 0) { return node; } for (int i = 0; i < num; i++) { ListNode n0 = new ListNode(0); n0.next = node; node = n0; } return node; }
反转链表:
private ListNode reserveLink(ListNode head) { ListNode preNode = null; while(head != null) { ListNode nextNode = head.next; // 保留下一个结点 head.next = preNode; //指针反转 preNode = head; //前结点后移 head = nextNode; //当前结点后移 } return preNode; }