• 面试算法25:链表中的数字相加


    题目

    给定两个表示非负整数的单向链表,请问如何实现这两个整数的相加并且把它们的和仍然用单向链表表示?链表中的每个节点表示整数十进制的一位,并且头节点对应整数的最高位数而尾节点对应整数的个位数。例如,两个分别表示整数984和18的链表,它们相加时应该是984中的十位数8和18中的十位数1相加,984的个位数4和18的个位数8相加。此时不能从两个链表的头节点开始相加,而是应该把它们的尾节点对齐并把对应的数位相加。

    分析

    解决这个问题的办法是把表示整数的链表反转。反转之后的链表的头节点表示个位数,尾节点表示最高位数。此时从两个链表的头节点开始相加,就相当于从整数的个位数开始相加。在做加法时还需要注意的是进位。如果两个整数的个位数相加的和超过10,就会往十位数产生一个进位。在下一步做十位数相加时就要把这个进位考虑进去。
    在这里插入图片描述

    public class Test {
        public static void main(String[] args) {
            ListNode listNode1 = new ListNode(1);
            ListNode listNode2 = new ListNode(2);
            ListNode listNode3 = new ListNode(3);
            ListNode listNode4 = new ListNode(4);
            ListNode listNode5 = new ListNode(5);
            ListNode listNode6 = new ListNode(6);
            ListNode listNode7 = new ListNode(7);
            ListNode listNode8 = new ListNode(8);
            ListNode listNode9 = new ListNode(9);
    
            listNode9.next = listNode8;
            listNode8.next = listNode4;
    
            ListNode result = reverseList(listNode1);
            while (result != null) {
                System.out.println(result.val);
                result = result.next;
            }
        }
    
        public static ListNode addTwoNumbers(ListNode head1, ListNode head2) {
            head1 = reverseList(head1);
            head2 = reverseList(head2);
            ListNode reversedHead = addReversed(head1, head2);
            return reverseList(reversedHead);
        }
    
        private static ListNode addReversed(ListNode head1, ListNode head2) {
            ListNode dummy = new ListNode(0);
            ListNode sumNode = dummy;
            int carry = 0;
            while (head1 != null || head2 != null) {
                int sum = (head1 == null ? 0 : head1.val) + (head2 == null ? 0 : head2.val) + carry;
                carry = sum >= 10 ? 1 : 0;
                sum = sum >= 10 ? sum - 10 : sum;
                ListNode newNode = new ListNode(sum);
    
                sumNode.next = newNode;
                sumNode = sumNode.next;
    
                head1 = head1 == null ? null : head1.next;
                head2 = head2 == null ? null : head2.next;
            }
    
            if (carry > 0) {
                sumNode.next = new ListNode(carry);
            }
            return dummy.next;
        }
    
        public static ListNode reverseList(ListNode head) {
            ListNode prev = null;
            ListNode cur = head;
            while (cur != null) {
                ListNode next = cur.next;
                cur.next = prev;
                prev = cur;
                cur = next;
            }
    
            return prev;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
  • 相关阅读:
    C++--手动实现循环队列(数组+链表)
    nano gpt 中MLP的矩阵长度为什么是C*4的;MLP多层感知机:s x h;llama3 和chatGpt4的 MLP 隐藏层数量;
    elasticsearch 相似度计算
    13. Spring AOP(一)思想及使用
    【面试刷题】——Qt的信号和槽你了解哪些
    k8s gitlab cicd 之gradle 篇章(二)并发打包问题
    CSS3常见样式声明
    C 语言程序的执行流程
    java计算机毕业设计健身俱乐部业务关系系统MyBatis+系统+LW文档+源码+调试部署
    Linux常用监控命令(笔试面试常考)
  • 原文地址:https://blog.csdn.net/GoGleTech/article/details/133750855