519 随机翻转矩阵

思路:

这道题起始很简单就是说每次抽取一个数,然后把这个数消去再下一次随机抽取。

这里思路有两种:一是如果抽到这个数,就不需要把它从数组中删除,而是将他的值和最后一个元素的值进行互换,然后把SIZE - 1,这样就不需要用set,list这种,可以直接用下标访问元素,很快;或者如果说这个数的值是发生改变了的,利用一个数组存储发生改变后的值,然后再返回答案;二是利用分块的思想,我们不是要求第几个大于0的数嘛,这就是很明显的分块思想,每一块都是根号m * n个数,用cnt[i]表示第i块中0的数量,这样只要找到第一个sum[i - 1] < x < sum[i]的就可以了

代码:

思路一:

class Solution {
public:
    // vector<int> cur;
    unordered_map<int, int> book;
    // vector<int> src;
    int sz;
    int _n;
    int src = 0;
    Solution(int m, int n) {
        _n = n;
        // end = m * n - 1;
        // cur.resize(m * n);
        // for(int i = 0;i<=end;i++){
        //     // src.push_back(i);
        //     cur[i] = i;
        // }
        sz = src = m * n;
    }
    
    vector<int> flip() {
        int idx = next();
        vector<int> ans;
        if(book.count(idx)){
            ans = {book[idx] / _n, book[idx] % _n};
        }else{
            ans = {idx / _n, idx % _n};
        }

        if(book.count(sz - 1)){
            book[idx] = book[sz - 1];
        }else{
            book[idx] = sz - 1;
        }
        sz--;

        return ans;
    }
    
    void reset() {
        // cur = src;
        sz = src;
        book.clear();
    }
    inline int next(){
        return rand() % sz;
    }
};

/**
 * Your Solution object will be instantiated and called as such:
 * Solution* obj = new Solution(m, n);
 * vector<int> param_1 = obj->flip();
 * obj->reset();
 */

思路二:

class Solution {
public:
    Solution(int m, int n) {
        this->m = m;
        this->n = n;
        total = m * n;
        bucketSize = sqrt(m * n);
        for (int i = 0; i < total; i += bucketSize) {
            buckets.push_back({});
        }
        srand(time(nullptr));
    }

    vector<int> flip() {
        int x = rand() % total;
        int sumZero = 0;
        int curr = 0;
        total--;

        for (auto & bucket : buckets) {
            if (sumZero + bucketSize - bucket.size() > x) {
                for (int i = 0; i < bucketSize; ++i) {
                    if (!bucket.count(curr + i)) {
                        if (sumZero == x) {
                            bucket.emplace(curr + i);
                            return {(curr + i) / n, (curr + i) % n};
                        } 
                        sumZero++;
                    }
                }
            }
            curr += bucketSize;
            sumZero += bucketSize - bucket.size();
        }
        
        return {};
    }

    void reset() {
        for (auto & bucket : buckets) {
            bucket.clear();
        }
        total = m * n;
    }
private:
    int m;
    int n;
    int bucketSize;
    int total;
    vector<unordered_set<int>> buckets;
};

 

上一篇:进步一点点丨迅为4412开发板Linux内核开发基础


下一篇:迅为4412开发板Qt界面切换