給定兩個用鏈表表示的整數,每一個節點包含一個數位。面試
這些數位是反向存放的,也就是個位排在鏈表首部。算法
編寫函數對這兩個整數求和,並用鏈表形式返回結果。函數
試題連接:https://leetcode-cn.com/problems/sum-lists-lcci/測試
public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode pCurrent = l1; //遍歷 int index = 0; int num1 = 0; while(pCurrent != null) { int num = pCurrent.val; //個、10、百依次 num1 += num * Math.pow(10,index); index++; pCurrent = pCurrent.next; } //重複 pCurrent = l2; index = 0; int num2 = 0; while(pCurrent != null) { int num = pCurrent.val; //個、10、百依次 num2 += num * Math.pow(10,index); index++; pCurrent = pCurrent.next; } //進行相加 int sum = num1 + num2; // System.out.println(sum); //將數字拆分,轉換爲鏈表 912 2 91 1 9 9 0 ListNode listNode = new ListNode(sum % 10); sum = sum / 10; pCurrent = listNode; while (sum != 0) { int x = sum % 10; pCurrent.next = new ListNode(x); pCurrent = pCurrent.next; sum = sum / 10; } return listNode; }
測試結果:3d
由於測試數值較大,int類型沒法正確的進行保存,故出現了錯誤。將int類型改成long類型,在進行測試。code
發現所測試的數據遠遠比咱們想一想的大,所以咱們得另闢蹊徑。blog
考慮到該算法有超大規模的測試數據,咱們引入了BigInteger這個類,來進行測試。ci
import java.math.BigInteger; class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode pCurrent = l1; //遍歷 String num1 = ""; while(pCurrent != null) { int num = pCurrent.val; //個、10、百依次 num1 += num; pCurrent = pCurrent.next; } //重複 pCurrent = l2; String num2 = ""; while(pCurrent != null) { int num = pCurrent.val; //個、10、百依次 num2 += num; pCurrent = pCurrent.next; } //逆序遍歷,進行相加 String newNum1 = ""; for(int i = 0;i < num1.length();i++) { newNum1 += num1.charAt(num1.length() - 1 - i); } String newNum2 = ""; for(int i = 0;i < num2.length();i++) { newNum2 += num2.charAt(num2.length() - 1 - i); } // System.out.println(newNum1); // System.out.println(newNum2); BigInteger bigInteger1 = new BigInteger(newNum1); BigInteger bigInteger2 = new BigInteger(newNum2); BigInteger sum = bigInteger1.add(bigInteger2); String sumStr = sum.toString(); ListNode saveNode = new ListNode(sumStr.charAt(sumStr.length() - 1) - 48); pCurrent = saveNode; for(int i = 1;i < sumStr.length();i++) { pCurrent.next = new ListNode(sumStr.charAt(sumStr.length() - 1 - i) - 48); pCurrent = pCurrent.next; } return saveNode; } }
測試結果:leetcode
能夠看到,該算法的用時較長,且若是改寫成C語言代碼時,咱們並無BigInteger這個類。
對此,咱們像將鏈表拆分,引入對位相加的計算策略。
ListNode list = new ListNode(-1); //定義輸出鏈表 ListNode p = list; int num = 0; //進位數字 int x = 0; //記錄l1鏈表的值 int y = 0; //記錄12鏈表的值 //遍歷兩個鏈表 while(l1 != null ||l2 != null) { x = l1 == null ? 0 : l1.val; y = l2 == null ? 0 : l2.val; int sum = x + y + num; if(sum < 10) { p.next = new ListNode(sum); num = 0; }else { p.next = new ListNode(sum % 10); num = sum / 10; } if(l1 != null) l1 = l1.next; if(l2 != null) l2 = l2.next; p = p.next; } if (num != 0) p.next = new ListNode(num); return list.next;
測試結果:
能夠看到,對於該算法,在java中的運行效率仍是能夠的。
struct ListNode* list = (struct ListNode*)malloc(sizeof(struct ListNode)); list->val = -1; //定義輸出鏈表 list->next = NULL; struct ListNode* p = list; int num = 0; //進位數字 int x = 0; //記錄l1鏈表的值 int y = 0; //記錄12鏈表的值 //遍歷兩個鏈表 while(l1 != NULL ||l2 != NULL) { x = l1 == NULL ? 0 : l1->val; y = l2 == NULL ? 0 : l2->val; int sum = x + y + num; if(sum < 10) { struct ListNode* temp = (struct ListNode*)malloc(sizeof(struct ListNode)); temp->val = sum; temp->next = NULL; p->next = temp; num = 0; }else { struct ListNode* temp = (struct ListNode*)malloc(sizeof(struct ListNode)); temp->val = sum % 10; temp->next = NULL; p->next = temp; num = sum / 10; } if(l1 != NULL) l1 = l1->next; if(l2 != NULL) l2 = l2->next; p = p->next; } if (num != 0) { struct ListNode* temp = (struct ListNode*)malloc(sizeof(struct ListNode)); temp->val = num; temp->next = NULL; p->next = temp; } return list->next;
測試結果:
能夠看到,在C語言中,該算法的計算效率偏低。