CPP杂记——开始做点基础题

一些杂题

  • LeetCode
    • 两数之和
    • 三数之和
    • 正则表达式匹配
    • 按序打印
    • 交替打印FooBar
    • 打印奇数与偶数
    • 水生成
    • 最小的必要团队

LeetCode

两数之和

内存100% 耗时43% 回头看看题解(难道要哈希?内存++)

#include 
#include 
using std::map;
using std::vector;

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        map<int, int>   targetMap;
        for(
            int i = 0, size = nums.size();
            i < size;
            i++
        ) {
            int curItem = nums[i];
            if(targetMap.find(curItem) != targetMap.end()) {
                return vector<int>{targetMap[curItem], i};
            }
            targetMap[target - curItem] = i;
        }

        return vector<int>{-1,-1};
    }
};

三数之和

暴力,排序后再向内搜索,内存100%,耗时37.6%,回头看看题解,感觉是去重跳过不够效率

#include 
#include 
using namespace std;

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        size_t              size = nums.size();
        if(nums.size() < 3) {
            return result;
        }
        sort(nums.begin(), nums.end(), [](int a, int b) {
            return a < b;
        });
        const int* alias = nums.data();

        for(int left = 0; left < size - 2; left++) {
            if(alias[left] > 0)
                break;
            if(left > 0 && alias[left] == alias[left-1])
                continue;
            for(
                    int mid = left+1, right = static_cast<int>(size)-1;
                    mid < right;
            ) {
                if(mid > left+1 && alias[mid] == alias[mid-1]) {
                    mid++;
                    continue;
                }
                if(right < static_cast<int>(size)-1 && alias[right] == alias[right+1]) {
                    right--;
                    continue;
                }
                long temp = alias[left] + alias[mid] + alias[right];
                if(temp == 0) {
                    result.emplace_back(vector<int>{alias[left], alias[mid], alias[right]});
                    mid++, right--;
                } else if(temp < 0){
                    mid++;
                } else if(temp > 0) {
                    right--;
                }
            }
        }
        return result;
    }
};

正则表达式匹配

114甚至514月没写过dp了,,整的WA了三回啊三回 耗时82%,内存100%

#include 
#include 
using namespace std;

class Solution {
public:
    inline bool isMatch(string& s, string& p) {
        s = " "+s;
        p = " "+p;
        size_t  sIndex = 0,
                pIndex = 0;
        size_t  sSize = s.size(),
                pSize = p.size();
        bool    pervMatched = true;

        bool **stat = new bool*[sSize+1];
        for(size_t i = 0; i < sSize+1; i++) {
            stat[i] = new bool[pSize+1];
            memset(stat[i], false, pSize+1);
        }
        stat[0][0] = true;

        for(sIndex = 0; sIndex < sSize; sIndex++) {
            for(pIndex = 0; pIndex < pSize; pIndex++) {

                if(p[pIndex] == s[sIndex] || p[pIndex] == '.') {
                    stat[sIndex+1][pIndex+1] = stat[sIndex][pIndex];
                } else if(p[pIndex] == '*') {
                    if(
                        p[pIndex-1] != s[sIndex] &&
                        p[pIndex-1] != '.')
                    {
                        stat[sIndex+1][pIndex+1] = stat[sIndex+1][pIndex-1];
                    } else {
                        stat[sIndex+1][pIndex+1] = (
                                stat[sIndex][pIndex+1] ||
                                stat[sIndex+1][pIndex-1] ||
                                stat[sIndex+1][pIndex]
                        );
                    }
                }
            }
        }

        bool res = stat[sSize][pSize];
        delete []stat;
        return res;
    }
};

按序打印

两把大锁, 省点cpu的写法

#include 

class Foo {
public:
    Foo() {
        _sync1.lock();
        _sync2.lock();
    }

    void first(function<void()> printFirst) {
        // printFirst() outputs "first". Do not change or remove this line.
        printFirst();
        _sync1.unlock();
    }

    void second(function<void()> printSecond) {
        std::lock_guard<std::mutex> mtx(_sync1);
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
        _sync2.unlock();
    }

    void third(function<void()> printThird) {
        std::lock_guard<std::mutex> mtx(_sync2);
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
    }

private:
    std::mutex _sync1;
    std::mutex _sync2;
};

交替打印FooBar

atomic操作,顺便吐槽atomic_flag是真的难用

#include 

class FooBar {
private:
    int                     _n;
    std::atomic<bool>       _flag = false;
public:
    FooBar(int n) {
        this->_n = n;
    }

    void foo(function<void()> printFoo) {
        
        for (int i = 0; i < _n; i++) {
            while(_flag.load(std::memory_order::acquire))
                std::this_thread::yield();
        	// printFoo() outputs "foo". Do not change or remove this line.
        	printFoo();
            _flag.store(true, std::memory_order::release);
        }
    }

    void bar(function<void()> printBar) {
        
        for (int i = 0; i < _n; i++) {
            while(!_flag.load(std::memory_order::acquire))
                std::this_thread::yield();
        	// printBar() outputs "bar". Do not change or remove this line.
        	printBar();
            _flag.store(false, std::memory_order::release);
        }
    }
};

打印奇数与偶数

把odd和even搞反了,紫菜,,, 耗时68.3% 内存100%

#include 
#include 

class ZeroEvenOdd {
private:
    std::condition_variable
            _cv;
    std::mutex
            _sync;
    int     _n;
    unsigned char
            _numType = 0;
public:
    ZeroEvenOdd(int n): _sync(), _numType(0), _cv() {
        this->_n = n;
    }

    // printNumber(x) outputs "x", where x is an integer.
    void zero(function<void(int)> printNumber) {
        for(int i = 0; i < _n; i++) {
            std::unique_lock<std::mutex> lock(_sync);
            _cv.wait(lock, [this]{return _numType == 0;});

            printNumber(0);
            _numType = (i&1)? 2: 1;
            _cv.notify_all();
        }
    }

    void odd(function<void(int)> printNumber) {
        for(int i = 1; i <= _n; i += 2) {
            std::unique_lock<std::mutex> lock(_sync);
            _cv.wait(lock, [this]{return _numType == 1;});

            printNumber(i);
            _numType = 0;
            _cv.notify_all();
        }
    }

    void even(function<void(int)> printNumber) {
        for(int i = 2; i <= _n; i += 2) {
            std::unique_lock<std::mutex> lock(_sync);
            _cv.wait(lock, [this]{return _numType == 2;});

            printNumber(i);
            _numType = 0;
            _cv.notify_all();
        }
    }
};

水生成

65%,100%
怀念vk的semaphore,,,

#include 
#include 

class H2O {
public:
    H2O(): _cv(), _sync(), _hydrogenCnt(0), _oxygenCnt(0) {}

    void hydrogen(function<void()> releaseHydrogen) {
        std::unique_lock<std::mutex> lock(_sync);
        _cv.wait(lock, [this]{return _hydrogenCnt < 2;});
        
        // releaseHydrogen() outputs "H". Do not change or remove this line.
        releaseHydrogen();
        _hydrogenCnt++;
        _cv.notify_all();
    }

    void oxygen(function<void()> releaseOxygen) {
        std::unique_lock<std::mutex> lock(_sync);
        _cv.wait(lock, [this]{return _hydrogenCnt == 2;});

        // releaseOxygen() outputs "O". Do not change or remove this line.
        releaseOxygen();
        _hydrogenCnt = 0;
        _cv.notify_all();
    }
private:
    std::condition_variable
        _cv;
    std::mutex
        _sync;
    size_t 
        _hydrogenCnt;
//    size_t
//        _oxygenCnt;	凭直觉写的,发现没用上,,
};

最小的必要团队

位图+dp 耗时72% 内存100%

#include 
#include 
#include 
#include 
#include 

using namespace std;
constexpr unsigned short FULL = 0xFF;

class Solution {
public:
    vector<int> smallestSufficientTeam (
            vector<string>& reqSkills,
            vector<vector<string>>& people
    ) {
        using skillType = unsigned short;

        size_t pSize = people.size();
        size_t sSize = reqSkills.size();

        vector<int> team[1u << sSize];
        auto *stat     = new unsigned char[1u << sSize];
        auto *property = new skillType[pSize];
        memset(stat, FULL, (1u << sSize) * sizeof(unsigned char));
        stat[0] = 0;
        memset(property, 0, pSize * sizeof(skillType));

        unordered_map<string, skillType> skills;        //查找较多, string也不用实现hash特化
        for(size_t i = 0; i < sSize; i++) {
            skills[reqSkills[i]] = 1u << i;
        }

        for(size_t i = 0; i < pSize; i++) {
            for(auto& skill : people[i]) {
                property[i] |= skills[skill];
            }
            if(property[i] == 0)
                continue;
            for(size_t j = 0, size = 1u << sSize; j < size; j++) {
                if(stat[j] != FULL) {
                    skillType temp = j | property[i];
                    if(/*stat[temp] == FULL ||*/ stat[temp] > stat[j]+1) {
                        stat[temp] = stat[j] + 1;
                        team[temp] = team[j];
                        team[temp].push_back(i);
                    }
                }
            }
        }

        return team[(1u << sSize)-1];
    }
};

你可能感兴趣的:(cpp,杂学)