LeetCode 热题 HOT 100 第三天

11. 合并两个有序链表

/**
 * 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) {
        auto dummy = new ListNode(-1);
        auto cur = dummy;
        while (l1 && l2) {
            if (l1->val <= l2->val) {
                cur->next = l1;
                cur = cur->next;
                l1 = l1->next;
            }
            else {
                cur->next = l2;
                cur = cur->next;
                l2 = l2->next;
            }
        }
        while (l1) {
            cur->next = l1;
            l1 = l1->next;
            cur = cur->next;
        }
        while (l2) {
            cur->next = l2;
            l2 = l2->next;
            cur = cur->next;
        }
        return dummy->next;
    }
};

12. 括号生成

class Solution {
public:
    vector<string> res;

    vector<string> generateParenthesis(int n) {
        dfs(n, 0, 0, "");
        return res;    
    }

    void dfs(int n, int lc, int rc, string seq) {
        if (lc == n && rc == n) res.push_back(seq);
        else {
            if (lc < n) dfs(n, lc + 1, rc, seq + '(');
            if (rc < n && rc < lc) dfs(n, lc, rc + 1, seq + ')');
        }
    }
};

13. 合并k个升序链表

思路

使用优先队列保存每一个链表头结点,重载比较函数,比较顺序为值从小到大排列,每一次取出队头元素加入新的队列中,如果链表还没有结束,加入链表后一个元素队列中,直到优先队列为空

/**
 * 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:
    struct Cmp {
        bool operator() (ListNode* a, ListNode* b) {
            return a->val > b->val;
        } 
    };
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        priority_queue<ListNode*, vector<ListNode*>, Cmp> heap;
        auto dummy = new ListNode(-1), tail = dummy;
        for (auto& l : lists) {
            if (l) heap.push(l);
        }
        while (heap.size()) {
            auto t = heap.top();
            heap.pop();

            tail = tail->next = t;
            if (t->next) heap.push(t->next);
        }
        return dummy->next;
    }
};

14. 下一个排列

思路

从末尾找第一个非降序的元素,交换后段第一个大于其元素,再对后段翻转

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int k = nums.size() - 1;
        while (k && nums[k - 1] >= nums[k]) k -- ;
        if (k == 0) reverse(nums.begin(), nums.end());
        else {
            int t = k;
            while (t < nums.size() && nums[t] > nums[k - 1]) t ++ ;
            swap(nums[k - 1], nums[t - 1]);
            reverse(nums.begin() + k, nums.end());
        }
    }
};

15. 最长有效括号

思路(较复杂,代码很简单)

分段的思想,每一段合法括号序列分开的,找出分界点,每一次碰到左括号入栈,右括号出栈,判断栈中剩余括号,如果还有,作为某一段括号合法序列的端点,如果没有剩余,从上一个端点开始到这个右括号之间都是合法的;如果右括号入栈时,栈为空,说明右括号的数量多了,右括号作为合法括号序列端点前一个点

class Solution {
public:
    int longestValidParentheses(string s) {
        stack<int> stk;
        int res = 0;
        for (int i = 0, start = -1; i < s.size(); i ++ ) {
            if (s[i] == '(') stk.push(i);
            else {
                if (stk.size()) {
                    stk.pop();
                    if (stk.size()) {
                        res = max(res, i - stk.top());
                    }
                    else res = max(res, i - start);
                }
                else {
                    start = i;
                }
            }
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shirandexiaowo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值