面試題 02.05. 鏈表求和


面試題 02.05. 鏈表求和

1、題目描述

  1. 給定兩個用鏈表表示的整數,每個節點包含一個數位。

  2. 這些數位是反向存放的,也就是個位排在鏈表首部。

  3. 編寫函數對這兩個整數求和,並用鏈表形式返回結果。

試題鏈接:https://leetcode-cn.com/problems/sum-lists-lcci/

2、java題解一(未通過):

 public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode pCurrent = l1;
        //遍歷
        int index = 0;
        int num1 = 0;
        while(pCurrent != null) {
            int num = pCurrent.val;     //個、十、百依次
            num1 += num * Math.pow(10,index);
            index++;
            pCurrent = pCurrent.next;
        }

        //重復
        pCurrent = l2;
        index = 0;
        int num2 = 0;
        while(pCurrent != null) {
            int num = pCurrent.val;     //個、十、百依次
            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;
    }

測試結果:

因為測試數值較大,int類型無法正確的進行保存,故出現了錯誤。將int類型改為long類型,在進行測試。

發現所測試的數據遠遠比我們想想的大,因此我們得另辟蹊徑。

3、java題解二

考慮到該算法有超大規模的測試數據,我們引入了BigInteger這個類,來進行測試。

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;     //個、十、百依次
            num1 += num;
            pCurrent = pCurrent.next;
        }

        //重復
        pCurrent = l2;
        String num2 = "";
        while(pCurrent != null) {
            int num = pCurrent.val;     //個、十、百依次
            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;
    }
}

測試結果:

可以看到,該算法的用時較長,且如果改寫成C語言代碼時,我們並沒有BigInteger這個類。

4、java題解三

對此,我們像將鏈表拆分,引入對位相加的計算策略。

   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中的運行效率還是可以的。

5、C語言題解

    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語言中,該算法的計算效率偏低。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM