题解 | #两个链表生成相加链表#

两个链表生成相加链表

http://www.nowcoder.com/practice/c56f6c70fb3f4849bc56e33ff2a50b6b

方案

这个代码效率不高,这我承认,但是它便于阅读以及修改、调试是真的,如果你不追求那么一点点性能上的优势,可以看一下。

效率的主要损耗在于把链表打平为数组,以及计算其长度,这些可以写为紧耦合的,不过看起来以及调试起来可能就有点头痛了。

/**
 * 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* addInList(ListNode*  head1, ListNode* head2) {
        // 1 - 防止进位出现,先多分配一个内存
        ListNode* pHead = new ListNode(0);
        // 2 - 找一个较长的链表作为返回值
        // Hint : 较长链表为 head1
        int head1Len = 0, head2Len = 0;
        {
            // 2.1 - 先解决一下异常流
            int tmp1 = calLen(head1), tmp2 = calLen(head2);
            if(tmp1 == 0) return head2;
            if(tmp2 == 0) return head1;
            if(tmp2 > tmp1){
                swap(head2, head1);
                head1Len = tmp2;
                head2Len = tmp1;
            }else{
                head1Len = tmp1;
                head2Len = tmp2;
            }
        }
        // 3 - 将链表打平,便于操作
        vector<ListNode*> head1Buf(head1Len+1);
        vector<ListNode*> head2Buf(head2Len);
        head1Buf[0] = pHead;
        plain(head1Buf.begin()+1, head1, head1Len);
        plain(head2Buf.begin(), head2, head2Len);
        head1Buf[0]->next = head1Buf[1];
        // 4 - 核心算法,加法实现
        addOperation(head1Buf, head2Buf);
        // 5 - 分情况返回结果
        if(head1Buf[0]->val == 0){
            delete head1Buf[0];
            return head1Buf[1];
        }else{
            return head1Buf[0];
        }
    }

private:
    // 计算链表长度
    size_t calLen(ListNode* node){
        size_t ret = 0;
        while(node != nullptr){
            ret++;
            node = node->next;
        }
        return ret;
    }
    
    // 交换指针
    void swap(ListNode*& node1, ListNode*& node2){
        ListNode* tmp = node1;
        node1 = node2;
        node2 = tmp;
        return;
    }
    
    // 打平 : 链表打平为数组
    void plain(vector<ListNode*>::iterator itr, ListNode* node, size_t listLen){
        for(int i=0; i < listLen; i++){
            *itr = node;
            itr++;
            node = node->next;
        }
        return;
    }

    // 数组加法实现
    void addOperation(vector<ListNode*>& num1, vector<ListNode*>& num2){
#define VAL(x)   ((*(x))->val)
        // 1 - 获取循环的最小次数
        size_t num1Len = num1.size(), num2Len = num2.size();
        size_t loopTime = min(num1Len, num2Len);
        // 2 - 循环计算结果
        auto itr1 = num1.rbegin(), itr2 = num2.rbegin();
        for(int i=0; i<loopTime; i++){
            VAL(itr1) += VAL(itr2);
            if(VAL(itr1) >= 10){
                VAL(itr1) -= 10;
                VAL(itr1+1) += 1;
            }
            itr1++;
            itr2++;
        }
        // 3 - 异常分流流 - 计算完毕
        if(VAL(itr1) < 10) return;
        // 4 - num1 自己进行步进
        while(VAL(itr1) >= 10){
            VAL(itr1) -= 10;
            VAL(itr1+1) += 1;
            itr1++;
        }
#undef VAL
    }
};






















全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务