2021-10-05每日刷题打卡

2021-10-05每日刷题打卡

力扣——链表

1019. 链表中的下一个更大节点

给出一个以头节点 head 作为第一个节点的链表。链表中的节点分别编号为:node_1, node_2, node_3, … 。

每个节点都可能有下一个更大值(next larger value):对于 node_i,如果其 next_larger(node_i) 是 node_j.val,那么就有 j > i 且 node_j.val > node_i.val,而 j 是可能的选项中最小的那个。如果不存在这样的 j,那么下一个更大值为 0 。

返回整数答案数组 answer,其中 answer[i] = next_larger(node_{i+1}) 。

注意:在下面的示例中,诸如 [2,1,5] 这样的输入(不是输出)是链表的序列化表示,其头节点的值为 2,第二个节点值为 1,第三个节点值为 5 。

示例 1:

输入:[2,1,5]
输出:[5,5,0]

这题没理解好题意吃了个陷阱,以为是找到后面的数里最大的那个插入vector,没想到是找到一个大于自身的就直接插,不一定是要最大的那个。先创建两个结点p、q,都等于head,准备好一个vector容器v存数,还有两个整数num和math。开始遍历只要p不为空就一直遍历,每遍历一个结点就让num=p->val,q=p,while里开个while用来遍历q,每遍历一个结点判断值是否大于num,如果不大于就继续遍历,如果大于就让math=q->val并break结束while(我们要的是第一个大于num的值),当q遍历结束后if判断,如果math>num,就把math插入v里,如果不是就插入0,最后返回容器v。

/**
 * 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:
    vector<int> nextLargerNodes(ListNode* head) {
        vector<int>nums;
        ListNode *p,*q;
        int num,math;
        p=head;
        while(p!=nullptr)
        {
            num=p->val;
            q=p;
            math=num;
            while(q!=nullptr)
            {
                if(q->val>math)
                {
                    math=q->val;
                    break;
                }
                q=q->next;
            }
            if(math>num)
            {
                nums.push_back(math);
            }else
            {
                nums.push_back(0);
            }
            p=p->next;
        }
        return nums;
    }
};
23. 合并K个升序链表

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

关于这题要用上之前写过的21. 合并两个有序链表的知识,合并两个有序链表用的是,先创建一个空结点head用来当作合并链表的新链表,然后创建三个指针:o,p,q。o指向head, p和q指向要合并的两个链表,然后开始遍历,当p或q有一个为空时结束遍历。对比p和q当前结点的val,把小的差在o的next上,然后被插入的链表向下遍历一位,o也向下遍历一位。当遍历结束时判断一下p或q哪一个不为空,不为空的那个接在o的后面,这样合并就完成了。至于这里合并k个链表,就先创建一个主链表,把各个lites里的链表当成副链表,用如上方法依次3插入,最后返回主链表。

/**
 * 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* mergeKLists(vector<ListNode*>& lists) {
        ListNode* head;
        head=nullptr;
        for(int i=0;i<lists.size();i++)
        {
            ListNode o,*p,*q,*h;
            p=head;
            q=lists[i];
            h=&o;
            while(p&&q)
            {
                if(q->val > p->val)
                {
                    h->next=p;
                    p=p->next;
                }else
                {
                    h->next=q;
                    q=q->next;
                }
                h=h->next;
            }
            h->next=p?p:q;
            head=o.next;
        }
        return head;
    }
};
445. 两数相加 II

给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。

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

示例1:

在这里插入图片描述

输入:l1 = [7,2,4,3], l2 = [5,6,4]
输出:[7,8,0,7]

我这不能算偷懒嗷,反正它分支就在链表逆转里,我就用链表逆转写他,关于链表逆转要请到之前写的206. 反转链表,之前写过这里就不重复说明了,这题我就是用反转链表先把两条链表反转了并用p,q接收反转好的链表,准备好一个头结点一个尾结点一个作为新链表的o结点,还有两个整数num和math。开始遍历,当p或q一个为空时退出,每次math=p->val+q->val+num,num=math/10,然后用math开辟新结点o,这里开辟不能用malloc,主要是力扣的毛病,最好是用new开辟新结点,然后首先第一个结点让头结点head一直指向它(之后也不变了),尾结点end一直保持在尾部,好插入新结点o。当遍历结束时判断一下q或p有没有非空的,如果有就用那个再继续遍历,math=p->val+num或math=q->val+num,用上述方法知道这条链表为空。再在后面加一个判断,判断num是否为0,如果不为0说明有进1,就创建一个结点赋值为1连在end后面就行,最后用头结点head通过反转链表再反转一次,返回翻转后的结点就行。

/**
 * 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* reverseList(ListNode* head) {
    ListNode* p, * q, * o;
    p = NULL;
    q = head;
    while (q != NULL)
    {
        o = q->next;
        q->next = p;
        p = q;
        q = o;
    }
    return p;
}

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    ListNode* p = reverseList(l1);
    ListNode* q = reverseList(l2);
    ListNode* head = NULL, * end, * o;
    int i = 1;
    int num = 0, math;
    while (p && q)
    {
        math = p->val + q->val + num;
        p = p->next;
        q = q->next;
        num = math / 10;
        o = new ListNode(math % 10);
        if (i == 1)
        {
            head = o;
        }
        else
        {
            end->next = o;
        }
        end = o;
        i++;
    }
    if (q)
    {
        while (q != NULL)
        {
            math = q->val + num;
            num = math / 10;
            q = q->next;
            o = new ListNode(math % 10);
            end->next = o;
            end = o;
        }
    }
    else if (p)
    {
        while (p != NULL)
        {
            math = p->val + num;
            num = math / 10;
            p = p->next;
            o = new ListNode(math % 10);
            end->next = o;
            end = o;
        }
    }
    if (num)
    {
        end->next = new ListNode(1);
    }
    head = reverseList(head);
    return head;
}

};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值