7.19 链表中等&简单 445(栈) 21

445 两数相加Ⅱ

给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。

如果不使用反转链表,答案给出的解决方案是使用栈stack。利用栈先进后出的特点,将链表反转输出

思路:

  1. 存入stack
  2. 同时输出,计算和sum&进位carry,
  3. 逆序建立链表:
Listnode* head = nullptr;
while(...){
	Listnode* node = new Listnode(num);
	node->next = head;//理解为反转链表的cur->next = prev;
	head = node;//prev = cur;
}
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        stack<int> s1, s2;
        while(l1){
            s1.push(l1->val);
            l1 = l1->next;
        }
        while(l2){
            s2.push(l2->val);
            l2 = l2->next;
        }

        ListNode* curr = nullptr;
        int carry = 0 ; 
        while(!s1.empty()||!s2.empty()||carry){
            int a = s1.empty()?0:s1.top();
            int b = s2.empty()?0:s2.top();
            int sum = a + b + carry;

            if(!s1.empty())s1.pop();
            if(!s2.empty())s2.pop();
            
            carry = sum / 10;
            sum %= 10;
            //在头部和已建立的节点中插入新节点。
            ListNode* node = new ListNode(sum);
            node->next = curr;
            curr = node;
        }

        return curr;
    }
};

c++代码学习:栈的入和出

stack<int> sta;
sta.push(x);//入栈
sta.pop();//顶端出栈
x = sta.top();//获取最顶端的数

21 合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

思路:归并排序

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if (!l1) return l2;
        if (!l2) return l1;

        ListNode* dum = new ListNode(0); // 哑节点
        ListNode* cur = dum;

        while(l1 && l2){
            if(l1->val < l2->val){
                cur->next = l1;
                l1 = l1->next;
            }else{
                cur->next = l2;
                l2 = l2->next;
            }
            cur = cur->next;
        }
       /* while(l1){
            cur->next = l1;
            l1 = l1->next;
            cur = cur->next;
        }
        while(l2){
            cur->next = l2;
            l2 = l2->next;
            cur = cur->next;
        }*/
        // 如果有剩余节点,直接连接到结果链表的末尾
        cur->next = l1 ? l1 : l2;

        ListNode* newHead = dum->next;
        delete dum;
       
        return newHead;
        
    }
};

review 归并排序的模板


void merge_sort(int q[], int l, int r) {
    if (l >= r) return;

    int mid = l + r >> 1; // 计算中点
    merge_sort(q, l, mid); // 递归排序左半部分
    merge_sort(q, mid + 1, r); // 递归排序右半部分

    int k = 0, i = l, j = mid + 1;
    // 合并两个有序的子数组
    while (i <= mid && j <= r) {
        if (q[i] <= q[j]) tmp[k++] = q[i++];
        else tmp[k++] = q[j++];
    }

    // 将左半部分剩余元素复制到临时数组
    while (i <= mid) tmp[k++] = q[i++];
    // 将右半部分剩余元素复制到临时数组
    while (j <= r) tmp[k++] = q[j++];

    // 将合并后的有序数组复制回原数组
    for (i = l, j = 0; i <= r; i++, j++) q[i] = tmp[j];
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值