复习Day07:链表part03:21. 合并两个有序链表、2. 两数相加

之前的blog链接:https://blog.csdn.net/weixin_43303286/article/details/131700482?spm=1001.2014.3001.5501

我用的方法是在leetcode再过一遍例题,明显会的就复制粘贴,之前没写出来就重写,然后从拓展题目中找题目来写。辅以Labuladong的文章看。然后刷题不用CLion了,使用leetcode自带模拟面试环境。

链表章节的题目都体现出思想简单,但很难一次写对的特点,注意循环后条件什么时候是空指针,防止越界访问。

  1. 合并两个有序链表

复习Day07:链表part03:21. 合并两个有序链表、2. 两数相加_第1张图片

这道题的整体思路就是使用两个指针,分别遍历l1和l2,取最小的那个作为结果链表p的next:

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        ListNode* p1 = list1;
        ListNode* p2 = list2;
        ListNode* dummy = new ListNode(0), *p = dummy;
        while(p1 != nullptr && p2 != nullptr){
            if(p1->val > p2->val){//插入p2到res中
                p->next = p2;
                p2 = p2->next;
            }else{
                p->next = p1;
                p1 = p1->next;
            }
            p = p->next;
        }
        if (p1 != NULL) {
        p->next = p1;
    }
    
    if (p2 != NULL) {
        p->next = p2;
    }
        return dummy->next;
    }
};

注意循环条件,一旦跳出循环,肯定说明p1或p2有一个结束了,那么就怕剩下的那个直接接上去,使用虚拟头节点简化运算。

(什么时候需要用虚拟头结点?我这里总结下:当你需要创造一条新链表的时候,可以使用虚拟头结点简化边界情况的处理。)

2 两数相加

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

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

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


复习Day07:链表part03:21. 合并两个有序链表、2. 两数相加_第2张图片

这个的意思就是说将一个数字逐位存在了链表中,其中前面存的是低位,后面存的是高位。这样对于遍历顺序来说是符合我们的加法习惯的,如果相反还难搞些。

最终代码:

// 注意:cpp 代码由 chatGPT 根据我的 java 代码翻译,旨在帮助不同背景的读者理解算法逻辑。
// 本代码已经通过力扣的测试用例,应该可直接成功提交。

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        // 在两条链表上的指针
        ListNode *p1 = l1, *p2 = l2;
        // 虚拟头结点(构建新链表时的常用技巧)
        ListNode *dummy = new ListNode(-1);
        // 指针 p 负责构建新链表
        ListNode *p = dummy;
        // 记录进位
        int carry = 0;
        // 开始执行加法,两条链表走完且没有进位时才能结束循环
        while (p1 != nullptr || p2 != nullptr || carry > 0) {
            // 先加上上次的进位
            int val = carry;
            if (p1 != nullptr) {
                val += p1->val;
                p1 = p1->next;
            }
            if (p2 != nullptr) {
                val += p2->val;
                p2 = p2->next;
            }
            // 处理进位情况
            carry = val / 10;
            val = val % 10;
            // 构建新节点
            p->next = new ListNode(val);
            p = p->next;
        }
        // 返回结果链表的头结点(去除虚拟头结点)
        return dummy->next;
    }
};

你可能感兴趣的:(链表,数据结构)