• 2 两数相加


    题库:https://leetcode-cn.com/problems/add-two-numbers/

    给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
     请你将两个数相加,并以相同形式返回一个表示和的链表。
     你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

     输入:l1 = [2,4,3], l2 = [5,6,4]
     输出:[7,0,8]
     解释:342 + 465 = 807.

    import org.junit.Test;
    
    /**
     * 2 两数相加
     * 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
     * 请你将两个数相加,并以相同形式返回一个表示和的链表。
     * 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
     * 
     * 示例 1:
     * 输入:l1 = [2,4,3], l2 = [5,6,4]
     * 输出:[7,0,8]
     * 解释:342 + 465 = 807.
     * 
     * @author zj
     *
     */
    public class Solution2 {
        
        @Test
        public void method() {
            Node node1 = addTwoNumbers(build11(), build12());
            printNode(node1);
            System.out.println();
            Node node2 = addTwoNumbers(build21(), build22());
            printNode(node2);
        }
        //打印链表
        public void printNode(Node node) {
            while(null != node) {
                if(null == node.next) {
                    //链表的当前节点的下一个节点为空,或者理解为最后一个节点
                    System.out.print(node.val);
                }else {
                    //链表当前节点的下一个节点不为空,或者理解为不是最后一个节点
                    System.out.print(node.val + "-->");
                }
                //获取下一个节点
                node = node.next;
            }
        }
        //创建第一个链表
        public Node build11() {
            Node node1 = new Node(2);
            Node node2 = new Node(4);
            Node node3 = new Node(3);
            node2.addNode(node3);
            node1.addNode(node2);
            return node1;
        }
        //创建第二个链表
        public Node build12() {
            Node node1 = new Node(5);
            Node node2 = new Node(6);
            Node node3 = new Node(4);
            node2.addNode(node3);
            node1.addNode(node2);
            return node1;
        }
        public Node build21() {
            Node node1 = new Node(9);
            Node node2 = new Node(9);
            Node node3 = new Node(9);
            Node node4 = new Node(9);
            Node node5 = new Node(9);
            Node node6 = new Node(9);
            Node node7 = new Node(9);
            node6.addNode(node7);
            node5.addNode(node6);
            node4.addNode(node5);
            node3.addNode(node4);
            node2.addNode(node3);
            node1.addNode(node2);
            return node1;
        }
        public Node build22() {
            Node node1 = new Node(9);
            Node node2 = new Node(9);
            Node node3 = new Node(9);
            Node node4 = new Node(9);
            node3.addNode(node4);
            node2.addNode(node3);
            node1.addNode(node2);
            return node1;
        }
        /**
         * 两个链表相加
         * 两个链表相加,可以理解为剥洋葱,
         * 计算第一个值放在洋葱的最外一层,计算第二个值放在洋葱的最外第二层。。。
         * 但是想要的结果为整个洋葱,所以就需要两个链表进行收集计算值,
         * 一个链表作为想要的结果链表,一个链表为剥开的洋葱链表
         * @param node1
         * @param node2
         * @return
         */
        public Node addTwoNumbers(Node node1, Node node2) {
            if(null == node1) {
                return node2;
            }
            if(null == node2) {
                return node1;
            }
            //作为返回的洋葱
            Node result =null;
            //作为将要剥开的洋葱
            Node temp = null;
            //进位值
            int carry = 0;
            //只要有一个链表不为空,就继续剥(遍历)
            while(null != node1 || null != node2) {
                //第一遍:获取第一个链表的第一个值
                //第二遍:获取第一个链表的第二个值
                int val1 = ((null != node1) ? node1.val : 0);
                //第一遍:获取第二个链表的第一个值
                //第二遍:获取第二个链表的第二个值
                int val2 = ((null != node2) ? node2.val : 0);
                //第一遍:计算两个链表的第一个值之和(此时carry为0)
                //第二遍:计算两个链表的第二个值之和(此时carry为0)
                int sum = val1 + val2 + carry;
                if(null == result) {
                    //第一遍时:返回的洋葱为空,将要剥开的洋葱也是空,
                    //  那么将计算结果存储在两个洋葱中,或者可以理解为初始化
                    temp = new Node(sum % 10);
                    result = temp;
                }else {
                    //第二遍:将结果值存储到剥开洋葱的第二层(temp为第一层)
                    temp.next = new Node(sum % 10);
                    //第二遍:获取剥开洋葱的第二层
                    temp = temp.next;
                }
                //第一遍:获取进位值(sum=2+5),不进位
                //第二遍:获取进位值(sum=4+6),进位1
                carry = sum / 10;
                if(null != node1) {
                    //第一遍:获取第一个链表的第二个值,为下一循环做准备
                    //第二遍:获取第一个链表的第三个值,为下一循环做准备
                    node1 = node1.next;
                }
                if(null != node2) {
                    //第一遍:获取第二个链表的第二个值,为下一循环做准备
                    //第二遍:获取第二个链表的第三个值,为下一循环做准备
                    node2 = node2.next;
                }
                if(carry > 0) {
                    //第二遍:将要剥开的洋葱的下一层(temp为第二层,temp.next为第三层)
                    temp.next = new Node(carry);
                }
            }
            return result;
        }
        class Node{
            int val;
            Node next;
            public Node() {}
            public Node(int val) {
                this.val = val;
            }
            //添加节点
            public void addNode(Node t) {
                //当前节点的下一节点
                this.next = t;
            }
        }
    }
  • 相关阅读:
    PHP入门03 -- 数组与数据结构
    PHP入门02 -- 函数
    PHP入门01 -- 基本语法
    node文章
    Mongodb08
    Mongodb07
    ISO处理jq事件
    map
    Django自定义模板
    JS this指向
  • 原文地址:https://www.cnblogs.com/zj68/p/15595101.html
Copyright © 2020-2023  润新知