• 面试题 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语言中,该算法的计算效率偏低。

  • 相关阅读:
    k8S 搭建集群
    K8S搭建
    华为交换机常用命令
    JSP中动态include和静态include的区别
    什么情况下调用doGet()和doPost()
    get和post的区别
    什么是spring框架
    spring的作用
    什么是DI
    依赖注入的三种实现方式
  • 原文地址:https://www.cnblogs.com/xgp123/p/12376367.html
Copyright © 2020-2023  润新知