LeetCode 445——两数相加 II

1. 题目

2. 解答

2.1 方法一

LeetCode 206——反转链表LeetCode 2——两数相加 的基础上,先对两个链表进行反转,然后求出和后再进行反转即可。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        
        // 先将两个链表反序
        l1 = reverseList(l1);
        l2 = reverseList(l2);
        
        ListNode *head = new ListNode(0); // 建立哨兵结点
        ListNode *temp = head; 

        
        int carry = 0; // 保留进位
        int sum = 0;
            
        while(l1 || l2)
        {
            if (l1 && l2) // 两个链表都非空
            {
                sum = l1->val + l2->val + carry;
                l1 = l1->next;
                l2 = l2->next;
            }
            else if (l1) // l2 链表为空,只对进位和 l1 元素求和
            {
                sum = l1->val + carry;
                l1 = l1->next;
            }
            else // l1 链表为空,只对进位和 l2 元素求和
            {
                sum = l2->val + carry;
                l2 = l2->next;
            } 
            
            // 求出和以及进位,将和添加到新链表中
            carry = sum >= 10 ? 1 : 0;
            sum = sum % 10;
            head->next = new ListNode(sum);
            head = head->next;
            
            if ( (l1 == NULL || l2 == NULL) && carry == 0 )
            {
                head->next = l1 ? l1 : l2;
                return reverseList(temp->next);
            }

        }
          
    
        if (carry) // 若最后一位还有进位,进位即为最后一位的和
        {
            head->next = new ListNode(carry);    
        }
        head->next->next = NULL;
        

        return reverseList(temp->next);
        
    }
    
    ListNode* reverseList(ListNode* head) {
    
        if (head == NULL || head->next == NULL) return head; 
        else 
        { 
            ListNode * p1 = head; 
            ListNode * p2 = p1->next; 
            ListNode * p3 = p2->next; 
            
            while (p2) 
            { 
                p3 = p2->next; p2->next = p1; 
                p1 = p2; 
                p2 = p3; 
            } 
            head->next = NULL; 
            head = p1; 

            return head; 
        }

    }

};
2.2 方法二

先求出两个链表的长度,然后对齐两个链表,按照对应位分别求出每一位的和以及进位,最后从最低位也就是最右边开始,将和与进位相加,新建节点在链表头部插入即可。

例 1
l1 7 2 4 3
l2 5 6 4
7 7 0 7
进位 0 1 0 0
结果 7 8 0 7
例 2
l1 9 9 9
l2 9 9
0 9 8 8
进位 0 1 1 0
结果 1 0 9 8
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        
        int n1 = countListNodeNumber(l1);
        int n2 = countListNodeNumber(l2);
        
        ListNode* long_list = NULL;
        ListNode* short_list = NULL;
        int bigger_n = 0;
        int smaller_n = 0;
        
        if (n1 <= n2)
        {
            long_list = l2;
            short_list = l1;
            bigger_n = n2;
            smaller_n = n1;
        }
        else
        {
            long_list = l1;
            short_list = l2;
            bigger_n = n1;
            smaller_n = n2;   
        }
        int temp = bigger_n - smaller_n + 1;
        int sum_array[bigger_n + 1] = {0};
        int carry_array[bigger_n + 1] = {0};
        int sum = 0;
        int carry = 0;
        
        ListNode* long_temp = long_list;
        ListNode* short_temp = short_list;
        
        for (unsigned int i = 1; i <= bigger_n; i++)
        {
            carry = 0;
            if (i < temp)
            {
                sum = long_temp->val;
            }
            else
            {
                sum = long_temp->val + short_temp->val;
                if (sum >= 10)
                {
                    sum = sum % 10;
                    carry = 1;
                }
                short_temp = short_temp->next;
            }
            sum_array[i] = sum;
            carry_array[i-1] = carry;
            long_temp = long_temp->next;
        }
        
               
        ListNode* new_head = new ListNode(0);
        long_temp = new_head;
        
        for (unsigned int i = bigger_n; i > 0; i--)
        {
            // 在链表头部进行插入
            sum = sum_array[i] + carry_array[i];
            if (sum >= 10)
            {
                sum = sum % 10;
                carry_array[i-1] = 1;
            }
            short_temp = new ListNode(sum);
            short_temp->next = long_temp->next;
            long_temp->next = short_temp;
        }
        
        sum = sum_array[0] + carry_array[0];
        if (sum)
        {
            short_temp = new ListNode(sum);
            short_temp->next = long_temp->next;
            long_temp->next = short_temp;
        }
        
        return new_head->next;

    }
    
    int countListNodeNumber(ListNode *head)
    {
        int node_num = 0;
        ListNode* slow = head; 
        ListNode* fast = head; 
        
        while(fast && fast->next) 
        {
            slow = slow->next; 
            fast = fast->next->next; 
            node_num++; 
        } 
        
        if (fast) 
        { 
            node_num = node_num * 2 + 1;
        } 
        else 
        { 
            node_num = node_num * 2; 
        }
        
        return node_num;
    }
    
    
};
2.3 方法三

将两个链表的节点分别放入两个栈中,若两个栈都非空,拿两个栈顶元素和进位,求出和以及新的进位;若其中一个栈为空,则拿一个栈顶元素和进位,求出和以及新的进位。然后新建节点,在链表头部进行插入,最后只用处理一下最高位的进位即可。

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        
        stack<ListNode *> stack1;
        stack<ListNode *> stack2;
        
        while (l1)
        {
            stack1.push(l1);
            l1 = l1->next;
        }
        
        while (l2)
        {
            stack2.push(l2);
            l2 = l2->next;
        }
        
        int sum = 0;
        int carry = 0;
        
        ListNode *new_head = new ListNode(0);
        ListNode *temp = NULL;
        
        while (!stack1.empty() && !stack2.empty())
        {
            sum = stack1.top()->val + stack2.top()->val + carry;
            
            if (sum >= 10)
            {
                sum = sum % 10;
                carry = 1;
            }
            else
                carry = 0;
            
            temp = new ListNode(sum);
            temp->next = new_head->next;
            new_head->next = temp; 
            
            stack1.pop();
            stack2.pop();
        }
                

         while (!stack1.empty())
         {
            sum = stack1.top()->val + carry;

            if (sum >= 10)
            {
                sum = sum % 10;
                carry = 1;
            }
            else
                carry = 0;

            temp = new ListNode(sum);
            temp->next = new_head->next;
            new_head->next = temp; 

            stack1.pop();
         }
        

         while (!stack2.empty())
         {
            sum = stack2.top()->val + carry;

            if (sum >= 10)
            {
                sum = sum % 10;
                carry = 1;
            }
            else
                carry = 0;

            temp = new ListNode(sum);
            temp->next = new_head->next;
            new_head->next = temp; 

            stack2.pop();
         }
        
        if (carry)
        {
            temp = new ListNode(carry);
            temp->next = new_head->next;
            new_head->next = temp; 
        }
        
        return new_head->next;
    }   
};

获取更多精彩,请关注「seniusen」!


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352

推荐阅读更多精彩内容