### 632. Smallest Range



题目:
https://leetcode.com/problems/smallest-range/

难度:
Hard

题意：

1. 给定n个序列，求一个最小区间，使得每个序列至少一个数在这个区间里面

思路：

- 采用移动区间的做法。如果区间左端点为l，那么我们需要在所有的序列中寻找比l大的最小数，构成一个区间[l, r]
- 首先，将所有序列的第一个数字入堆，我们记录一个最大值。这时候堆里面的数形成一个区间，判断和记录下来。接着区间开始移动，将堆里面的最小数弹出丢掉，再从这个最小数所在的序列取出下一个数放进堆，又形成一个区间，判断和记录下来。如此循环，直到其中一个序列没有数可以进堆

解法：

```c++
class Solution {
public:
    struct myData {
        int x, y, value;
        myData(int _x = 0, int _y = 0, int _value = 0): x(_x), y(_y), value(_value) {}
        bool operator<(const myData &b) const {
            return value > b.value;
        }
    };
    vector<int> smallestRange(vector<vector<int>>& nums) {
        int l = -10000000, r = -10000000;
        priority_queue<myData> q;
        int res = -10000000;
        for (int i = 0;i < nums.size();i++) {
            q.push(myData(i, 0, nums[i][0]));
            res = res > nums[i][0] ? res : nums[i][0];
        }
        while (q.size() == nums.size()) {            
            myData t = q.top();
            q.pop();
            if (l == -10000000 || (res - t.value) < (r - l)) {
                l = t.value;
                r = res;
            }
            if (t.y + 1 < nums[t.x].size()) {
                q.push(myData(t.x, t.y + 1, nums[t.x][t.y + 1]));
                res = res > nums[t.x][t.y + 1] ? res : nums[t.x][t.y + 1];
            }
        }
        vector<int> ret;
        ret.push_back(l);
        ret.push_back(r);
        return ret;
    }
};
```

