链表OJ(六)链表相加(一) 链表相加(二)

目录

链表相加(一)

链表相加(二)

描述  二与一相比多了俩次反转而已


链表相加(一)

描述

给定两个非空链表逆序存储的的非负整数,每个节点只存储一位数组。

请你把两个链表相加以下相同方法返回链表,保证两个数都不会以 0 开头。

【我的解法】长到离谱

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

class Solution {
public:
    /**
     * 
     * @param head1 ListNode类 
     * @param head2 ListNode类 
     * @return ListNode类
     */
    ListNode* reverse(ListNode* head)
    {
        ListNode* pre = nullptr, *Next = nullptr;
        while(head)
        {
            Next = head->next;
            head->next = pre;
            pre = head;
            head = Next;
        }
        return pre;
    }
    ListNode* addInList(ListNode* l1, ListNode* l2) {
        // write code here
        l1 = reverse(l1);
        l2 = reverse(l2);
        if (l1->val == 0)
            return l2;
        else if (l2->val == 0)
            return l1;
        ListNode* newhead = new ListNode(0);
        ListNode* p = newhead;
        int step = 0;
        while (l1 && l2) {
            int num = l1->val + l2->val + step;
            if (num >= 10)
                step = 1;
            else
                step = 0;
            ListNode* newnode = new ListNode(num % 10);
            p->next = newnode;
            p = p->next;
            l1 = l1->next;
            l2 = l2->next;
        }
        if (l1) {
            p->next = l1;
            while (l1) {
                l1->val += step;
                if (l1->val >= 10) {
                    step = 1;
                    l1->val %= 10;
                } else
                    step = 0;
                l1 = l1->next;
                p = p->next;
            }
        } else if (l2) {
            p->next = l2;
            while (l2) {
                l2->val += step;
                if (l2->val >= 10) {
                    step = 1;
                    l2->val %= 10;
                } else
                    step = 0;
                l2 = l2->next;
                p = p->next;
            }
        }
        if (step) {
            ListNode* newNode = new ListNode(step);
            p->next = newNode;
        }
        return reverse(newhead->next);
    }
};

 【答案】

具体做法:

  • step 1:任意一个链表为空,返回另一个链表就行了,因为链表为空相当于0,0加任何数为0,包括另一个加数为0的情况。
  • step 2:相继反转两个待相加的链表,反转过程可以参考反转链表
  • step 3:设置返回链表的链表头,设置进位carry=0.
  • step 4:从头开始遍历两个链表,直到两个链表节点都为空且carry也不为1. 每次取出不为空的链表节点值,为空就设置为0,将两个数字与carry相加,然后查看是否进位,将进位后的结果(对10取模)加入新的链表节点,连接在返回链表后面,并继续往后遍历。
  • step 5:返回前将结果链表再反转回来。
class Solution {
public:
    ListNode* ListAdd(ListNode* head1, ListNode* head2) {
        ListNode* res = new ListNode(-1);
        ListNode* head = res;
        //进位符号
        int carry = 0;
        //只要某个链表还有或者进位还有
        while(head1 != NULL || head2 != NULL || carry != 0){
            //链表不为空则取其值
            int val1 = head1 == NULL ? 0 : head1->val;
            int val2 = head2 == NULL ? 0 : head2->val;
            //相加
            int temp = val1 + val2 + carry;
            //获取进位
            carry = temp / 10;
            temp %= 10;
            //添加元素
            head->next = new ListNode(temp);
            head = head->next;
            //移动下一个
            if(head1 != NULL)
                head1 = head1->next;    // 确实一个规避段错误的小技巧
            if(head2 != NULL)
                head2 = head2->next;
        }
        //结果反转回来
        return ReverseList(res->next); 
    }
};

链表相加(二)

描述  二与一相比多了俩次反转而已

假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。

给定两个这种链表,请生成代表两个整数相加值的结果链表。

class Solution {
public:
    //反转链表
    ListNode* ReverseList(ListNode* pHead) { 
        if(pHead == NULL)
            return NULL;
        ListNode* cur = pHead;
        ListNode* pre = NULL;
        while(cur != NULL){
            //断开链表,要记录后续一个
            ListNode* temp = cur->next; 
            //当前的next指向前一个
            cur->next = pre; 
            //前一个更新为当前
            pre = cur; 
            //当前更新为刚刚记录的后一个
            cur = temp; 
        }
        return pre;
    }
    
    ListNode* addInList(ListNode* head1, ListNode* head2) {
        //任意一个链表为空,返回另一个
        if(head1 == NULL) 
            return head2;
        if(head2 == NULL)
            return head1;
        //反转两个链表
        head1 = ReverseList(head1); 
        head2 = ReverseList(head2);
        //添加表头
        ListNode* res = new ListNode(-1); 
        ListNode* head = res;
        //进位符号
        int carry = 0; 
        //只要某个链表还有或者进位还有
        while(head1 != NULL || head2 != NULL || carry != 0){ 
            //链表不为空则取其值
            int val1 = head1 == NULL ? 0 : head1->val; 
            int val2 = head2 == NULL ? 0 : head2->val;
            //相加
            int temp = val1 + val2 + carry; 
            //获取进位
            carry = temp / 10; 
            temp %= 10; 
            //添加元素
            head->next = new ListNode(temp); 
            head = head->next;
            //移动下一个
            if(head1 != NULL) 
                head1 = head1->next;
            if(head2 != NULL)
                head2 = head2->next;
        }
        //结果反转回来
        return ReverseList(res->next); 
    }
};

 

猜你喜欢

转载自blog.csdn.net/weixin_66151870/article/details/129105959