链表

16 阅读2分钟

2. 两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

 

示例 1:

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

刚看到傻傻地把链表表达的数算出来相加,再把数组成链表。这很蠢,链表表示的数可以无穷大,任何一个类型都无法表示。只要用双指针相加相同位,做好进位信息的接收和传递即可。

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    ListNode* dummy = new ListNode(0);
    ListNode* ans = new ListNode(0);
    dummy = ans;
    int carry = 0;

    while(l1 || l2 || carry){//有数或有进位未处理
        int num = 0;
        if(l1){
            num += l1->val;
            l1 = l1->next;
        }
        if(l2){
            num += l2->val;
            l2 = l2->next;
        }
        if(carry == 1){
            num += 1;
            carry = 0;
        }
        if(num > 9){
            num = num % 10;
            carry = 1;
        }
        ListNode* node = new ListNode(num);
        ans->next = node;
        ans = ans->next;
    }
    return dummy->next;
}

160. 相交链表

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

图示两个链表在节点 c1 开始相交

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构 。

若链表相交,则通过两种不同的顺序拼接链表再遍历,一定可以再同样位置遇到一样的节点。不只是值一样!而是节点一样!

但是千万不能直接把两个链表连起来,不然很可能成环,最后永远遍历不完。

应该维护两个指针分别从A B开始遍历,遇到空指针就跳转到另一个链表,这样是否会无限循环?不会,因为会同时第二次遇到空指针,而空指针也是一样的,会结束while循环。

ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    ListNode* p1 = headA;
    ListNode* p2 = headB;
    while(p1!=p2){
        if(!p1){ //遇到空指针
            p1 = headB;  //跳转
        }
        else p1 = p1->next;
        if(!p2){
            p2 = headA;
        }
        else p2 = p2->next;
    }
    return p1;
}