力扣合并K个升序链表/数组 + 双指针两道

23. 合并 K 个升序链表

代码

class Solution {
public:
    ListNode *mergeKLists(vector<ListNode *> &lists) {
        auto cmp = [](const ListNode *a, const ListNode *b) {
            return a->val > b->val; // 最小堆
        };
        priority_queue<ListNode*, vector<ListNode*>, decltype(cmp)> pq;
        for (auto head: lists)
            if (head) pq.push(head);

        auto dummy = new ListNode(); // 哨兵节点,作为合并后链表头节点的前一个节点
        auto cur = dummy;
        while (!pq.empty()) { // 循环直到堆为空
            auto node = pq.top(); // 剩余节点中的最小节点
            pq.pop();
            if (node->next) // 下一个节点不为空
                pq.push(node->next); // 下一个节点有可能是最小节点,入堆
            cur->next = node; // 合并到新链表中
            cur = cur->next; // 准备合并下一个节点
        }
        return dummy->next; // 哨兵节点的下一个节点就是新链表的头节点
    }
};

378. 有序矩阵中第 K 小的元素

代码

class Solution {
public:

    int kthSmallest(vector<vector<int>>& matrix, int k) {
        struct node{
            int x,y,val;
        };
        auto cmp = [](node a, node b){return a.val > b.val;};
        priority_queue<node, vector<node>, decltype(cmp)>q;
        int n = matrix.size();
        for(int i = 0; i < n; i++){
            q.push({i,0,matrix[i][0]});
        }
        int i  = 1;
        while(i < k){
            node it = q.top();
            q.pop();
            if(it.y < n - 1) q.push({it.x,it.y + 1, matrix[it.x][it.y + 1]});
            i++;
        }
        return q.top().val;
    }
};

719. 找出第 K 小的数对距离

代码

class Solution {
public:
//二分+双指针
    int smallestDistancePair(vector<int>& nums, int k) {
        sort(nums.begin(),nums.end());
        int n = nums.size();
        int l = 0, r = 1000010;
        while(l < r){
            int cnt = 0;//代表这个mid是第几个大数
            int mid = (l + r) >> 1;
            int i = 0;
            for(int j = 0; j < n; j++){
                while(i < j && nums[j] - nums[i] > mid)i++;
                cnt += j - i;
            }

            if(cnt < k) l = mid + 1;
            else r = mid;
        }
        return r;
    }
};

1508. 子数组和排序后的区间和

代码

class Solution {
public:
//双指针+模拟
    const int mod = 1e9 + 7;
    int rangeSum(vector<int>& nums, int n, int left, int right) {
        vector<int> sum(n + 1,0);
        sum[0] =  nums[0];
        for(int i = 1; i < n; i++) sum[i] = sum[i - 1] + nums[i];
        vector<int>tp;
        for(int r = 0; r < n; r++){
            int l = 0;
            while(l <= r){
                tp.push_back(l == 0 ? sum[r] : sum[r] - sum[l - 1]);
                l++;
            }
        }
        sort(tp.begin(),tp.end());
        left--;
        right--;
        long long ans = 0;
        for(;left <= right; left++){
            ans = (ans + tp[left]) % mod;
        }
        return ans;
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值