August LeetCoding Challenge

Day1

359.Logger Rate Limiter

Design a logger system that receive stream of messages along with its timestamps, each message should be printed if and only if it is not printed in the last 10 seconds.

Given a message and a timestamp (in seconds granularity), return true if the message should be printed in the given timestamp, otherwise returns false.

It is possible that several messages arrive roughly at the same time.

1.hashmap

#include <map>
#include <iostream>
#include <cassert>

using namespace std;

struct Logger {
    map<string, int> map_keyword_time;
    bool shouldPrintMessage(int ts, const string &s) {
        if (map_keyword_time.find(s) != map_keyword_time.end()) {
            if (ts - 10 < map_keyword_time[s]) {
                return false;
            }
        } 
        map_keyword_time[s] = ts;
        return true;
    }
    
};


int main() {
    Logger logger = Logger();
    
    // logging string "foo" at timestamp 1
    assert(logger.shouldPrintMessage(1, "foo") == true); 
    
    // logging string "bar" at timestamp 2
    assert(logger.shouldPrintMessage(2,"bar")== true);// returns true;
    
    // logging string "foo" at timestamp 3
    assert(logger.shouldPrintMessage(3,"foo") == false); //returns false;
    
    // logging string "bar" at timestamp 8
    assert(logger.shouldPrintMessage(8,"bar") == false); //returns false;
    
    // logging string "foo" at timestamp 10
    assert(logger.shouldPrintMessage(10,"foo") == false); //returns false;
    
    // logging string "foo" at timestamp 11
    assert(logger.shouldPrintMessage(11,"foo") == true); //returns true;
}

string一直存在hashmap里面很耗内存->queue&set来优化

queue & set

#include <set>
#include <queue>
#include <iostream>
#include <cassert>

using namespace std;

struct Logger {
    struct Log {
        string msg {};
        int ts;
        Log (string msg, int ts) : msg(msg), ts(ts) 
        {}
    };
    
    set<string> msgSet;
    queue<Log> qLogs;
    
    bool shouldPrintMessage(int ts, const string &s) {
        if (msgSet.find(s) != msgSet.end()) {
            while (qLogs.size() && qLogs.front().ts +10 <= ts) {
                Log log = qLogs.front();
                msgSet.erase(log.msg);
                qLogs.pop();
                if (log.msg == s) {
                    log.ts = ts;
                    qLogs.push(log);
                    return true;
                }
            }
        } else {
           msgSet.insert(s);
           qLogs.push(Log {s, ts});
           return true;
        }
        return false;
    }
    
};

520. Detect Capital

可精简掉switch

class Solution {
public:
    bool detectCapitalUse(string word) {
        int flag = 0;  // all uppercase
        if (word[0] > 'Z') flag = 1;  // all lowercase 
        else if (word.length() > 1 && word[1] > 'Z') flag = 2; // first uppercase

        switch(flag) {
            case 0:
                for (auto c : word) {
                    if (c > 'Z') return false;
                }
                break;
            case 1:
                for (auto c : word) {
                    if (c < 'a') return false;
                }
                break;
            case 2:
                for (int i=1; i<word.length(); i++) {
                    if (word[i] < 'a') return false;
                }
        }

        return true;
    }
};

705.Design HashSet

bitset

class MyHashSet {
    bitset<1000001> data;

public:
    /** Initialize your data structure here. */    
    MyHashSet() 
    {
    }
    
    void add(int key) {
        data[key] = 1;
    }
    
    void remove(int key) {
        data[key] = 0;
    }
    
    /** Returns true if this set contains the specified element */
    bool contains(int key) {
        return data[key];
    }
};

不用bitset用array和fill也ok
array<bool, 1000001> data;
fill(data.begin(), data.end(), false);
or
bool data[1000001] = {false};

bucket

class MyHashSet {
    static const int MAGIC_VALUE = 366661;
    vector<vector<int>> hash;

public:
    /** Initialize your data structure here. */    
    MyHashSet() : hash(MAGIC_VALUE-1)
    {}
    
    void add(int key) {
        int idx = key % MAGIC_VALUE;
        if (find(hash[idx].begin(), hash[idx].end(), idx) == hash[idx].end()) {
            hash[idx].push_back(key);
        }
    }
    
    void remove(int key) {
        int idx = key % MAGIC_VALUE;
        auto it = find(hash[idx].begin(), hash[idx].end(), idx);
        if (it != hash[idx].end()) {
            hash[idx].erase(it);
        }
    }
    
    /** Returns true if this set contains the specified element */
    bool contains(int key) {
        int idx = key % MAGIC_VALUE;
        return find(hash[idx].begin(), hash[idx].end(), idx)  != hash[idx].end();
    }
};

125.Valid Palindrome

isdigit
isalpha
tolower

class Solution {
public:
    bool isPalindrome(string s) {
        int size = s.length();
        
        int fast = size-1;
        int slow = 0;
        while (fast > slow) {
            while (fast >= 0 && !(isalpha(s[fast]) || isdigit(s[fast]))) fast --;
            while (slow < size && !(isalpha(s[slow]) || isdigit(s[slow]))) slow ++;
            
            if (fast >= 0 && slow < size) {
                if (!(isalpha(s[fast]) ^ isdigit(s[slow]))) return false;
                else if (tolower(s[fast]) != tolower(s[slow])) return false;
            }
                
            fast --;
            slow ++;
        }
        return true;
    }
};

342. Power of Four

class Solution {
public:
    bool isPowerOfFour(int num) {
        while (num / 4) {
            if (num % 4) return false;
            num /= 4;
        }
        return num == 1;
    }
};

211.Add and Search Word - Data Structure Design

trie tree/ Prefix Tree
trie node

struct TrieNode {
    map<char, TrieNode*> children;
    bool isCompleted;
    TrieNode() : isCompleted(false)
    {}
};
class WordDictionary {
    struct TrieNode {
        map<char, TrieNode*> children;
        bool isCompleted;
        TrieNode() : isCompleted(false)
        {}
    };
    
    TrieNode *header;
public:
    /** Initialize your data structure here. */
    WordDictionary() : header(new TrieNode()) 
    {}
    
    /** Adds a word into the data structure. */
    void addWord(string word) {
        auto lHeader = header;
        for (auto c: word) {
            if (lHeader->children.find(c) == lHeader->children.end()) {
                lHeader->children[c] = new TrieNode();
            } 
            lHeader = lHeader->children[c];
        }
        lHeader->isCompleted = true;
    }
    
    /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
    bool check(int idx, string &word, TrieNode *lHeader) {
        char c = word[idx];
        
        if (idx == word.length() - 1) {
            if(word[idx] == '.') {
                for (auto [key, val] : lHeader->children) {
                    if (val->isCompleted) return true;
                }
                return false;
            } else {
                return lHeader->children.find(word[idx]) != lHeader->children.end() ? 
                       lHeader->children[word[idx]]->isCompleted : false;
            }
        }

        
        if (c == '.') {
            for (auto [key, val] : lHeader->children) {
                if (check(idx+1, word, val)) return true;
            }
        } else {
            if (lHeader->children.find(word[idx]) == lHeader->children.end()) return false;
            if (check(idx+1, word, lHeader->children[word[idx]])) return true;
        }
        return false;
    }
    
    bool search(string word) { 
        return check(0, word, header);
    }
};

442. Find All Duplicates in an Array

O(N) & no extra space
不停换位(其实就是在排序了),再遍历找坐标不符合的(出现了两次的)

class Solution {
public:
    vector<int> findDuplicates(vector<int>& nums) {
        for(int i=0; i<nums.size(); i++){
            while(nums[i] != nums[nums[i]-1])
                swap(nums[i], nums[nums[i]-1]);
        }
        
        vector<int>v {};
        for(int i=0; i<nums.size(); i++){
            if(nums[i] != i+1){
                v.push_back(nums[i]);
            }
        }

        return v;
    }
};

原地取反,如果发现坐标对应的那个数已经为负数,就说明出现了两次

class Solution {
public:
    int abs(int num) {
        return num < 0? -num : num;
    }
    
    vector<int> findDuplicates(vector<int>& nums) {
        vector<int> res {};
        
        for (int i = 0; i < nums.size(); i++) {
            if (nums[abs(nums[i]) - 1] < 0)
                res.push_back(abs(nums[i]));
            nums[abs(nums[i]) - 1] *= -1;
        }
        
        return res;
    }
};

987. Vertical Order Traversal of a Binary

按层份bfs的思路(因为要保证同x情况下,大小按顺序排列,不然简单bfs就行),用set自动排序的思路也行,空间换时间

class Solution {
public:
    vector<vector<int>> verticalTraversal(TreeNode* root) {
        vector<vector<int>> res {};
        if (!root) return res;
        
        queue<pair<TreeNode*, int>> q {{{root, 0}}};
        map<int, vector<int>> mapX_vals {};
    
        while(q.size()) {
            map<int, int> cntr {};
            size_t size = q.size();
            for (size_t i = 0; i<size; i++) {
                auto [node, x] = q.front(); q.pop();
                mapX_vals[x].push_back(node->val);
                cntr[x] ++;
                
                if (node->left) q.push({node->left, x-1});
                if (node->right) q.push({node->right, x+1});                
            }
            
            for (auto [x, cnt] : cntr) 
                sort(mapX_vals[x].end()-cnt, mapX_vals[x].end());
        }
    
        for (auto &&[x, vec] : mapX_vals)  {
            res.emplace_back(move(vec));
        }
        
        return res;
    }
};

Day2

437. Path Sum III

bfs+dfs

class Solution {
public:
    int pathSum(TreeNode* root, int sum) {
        if (!root) return 0;
        int cnt = 0;
        
        queue<TreeNode*> q {{root}};
        while (q.size()) {
            auto node = q.front();
            q.pop();
            cnt += dfs(node, sum);
            if (node->left) q.push(node->left);
            if (node->right) q.push(node->right);
        }
        return cnt;
    }
    
    int dfs(TreeNode* root, int re) {
        int cnt = 0;
        if (!root) return cnt;
        // t << re << ", " << root->val << endl;
        if (root->val == re)
            cnt+=1;
        
        cnt += dfs(root->left, re-root->val);
        cnt += dfs(root->right, re-root->val);
        
        return cnt;
    }
};

dfs+dfs

class Solution {
public:
    int pathSum(TreeNode* root, int sum) {
        if (!root) return 0;
        int cnt = 0;
        
        cnt += dfs(root, sum);
        cnt += pathSum(root->left, sum);
        cnt += pathSum(root->right, sum);
        return cnt;
    }
    
    int dfs(TreeNode* root, int re) {
        if (!root) return 0;
        int cnt = 0;
        if (root->val == re)
            cnt+=1;
        
        cnt += dfs(root->left, re-root->val);
        cnt += dfs(root->right, re-root->val);
        
        return cnt;
    }
};

994. Rotting Oranges

bfs + 矩阵操作

class Solution {
public:
    int dx[4] {0, 0, 1, -1};
    int dy[4] {1, -1, 0, 0};
    
    int orangesRotting(vector<vector<int>>& grid) {
        if (grid.empty()) return 0;
        // bfs + 矩阵操作
        queue<pair<int, int>> q {};
        int row = grid.size(), col = grid[0].size();
        int tmr = 0, nFresh = 0;
        
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (grid[i][j] == 1) nFresh ++;
                else if (grid[i][j] == 2) q.push({i,j});
            }
        }

        while(q.size()) {
            int size = q.size();
            
            for (int i = 0; i < size; i++) {
                auto [x, y] = q.front();
                q.pop();
                
                for (int z = 0; z < 4; z++) {
                    int new_i = x + dx[z], new_j = y + dy[z];
                    if (new_i >= 0 && new_i < row && new_j >= 0 && new_j < col && grid[new_i][new_j] == 1){
                        nFresh --;
                        grid[new_i][new_j] = 2;
                        q.push({new_i, new_j});
                    }
                }
            }

            if (q.size()) tmr++;
        }
        
        if (nFresh) return -1; 
        return tmr;
    }
};

171. Excel Sheet Column Number

class Solution {
public:
    int titleToNumber(string s) {
        int sum = 0; size_t ss = s.length();
        for (size_t i = 0; i < ss; i++) 
            sum += (s[ss-i-1]-'A'+1) * pow(26, i);
        return sum;
    }
};

274. H-Index

sort

class Solution {
public:
    int hIndex(vector<int>& citations) {
        sort(citations.begin(), citations.end(), [] (int x, int y) {return x > y;});
        for (int i=0; i<citations.size(); i++) {
            if (citations[i] < i+1) return i;
        }
        
        return citations.size();
    }
};

119. Pascal's Triangle II

class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int> res(rowIndex+1, 1);
        for (int i=2; i<=rowIndex; i++) {
            vector<int> tmp = res;
            for (int j=1; j<i; j++) {
                res[j]=tmp[j-1]+tmp[j];
            }
        }
        return res;
    }
};

!1286. Iterator for Combination

使用bitset做permutation (int当bitset, __builtin_popcount && 位运算找1)

class CombinationIterator {
public:
    queue<string> strs {};
    CombinationIterator(string str, int cl) {
        int ss = str.length();
        int maxBitset = (1 << ss) - 1;
        for (int bs = maxBitset; bs > 0; bs--) {
            if (__builtin_popcount(bs) != cl) continue;
            int tmp_bs = bs, idx = 0; 
            string substr {};
            while(tmp_bs) {
                if (tmp_bs & 1) substr+=str[ss-1-idx];
                tmp_bs >>= 1;
                idx ++;
            }
            strs.push({substr.rbegin(), substr.rend()});
        }
        
    }
    
    string next() {
        if (strs.empty()) return nullptr;
        auto res = strs.front();
        strs.pop();
        return res;
    }
    
    bool hasNext() {
        return !strs.empty();
    }
};

/**
 * Your CombinationIterator object will be instantiated and called as such:
 * CombinationIterator* obj = new CombinationIterator(characters, combinationLength);
 * string param_1 = obj->next();
 * bool param_2 = obj->hasNext();
 */

内存优化版

class CombinationIterator {
public:
    string msg {};
    int bs;
    int lenMsg;
    
    CombinationIterator(string str, int cl) : 
        msg(move(str)), 
        lenMsg(cl), 
        bs((1 << msg.length()) - 1) // str is moved ... so bs will be 0 if we use str
    {}
    
    string next() {
        if (!hasNext()) return {};
    
        int tmp_bs = bs, idx = 0; 
        string substr {};
        while(tmp_bs) {
            if (tmp_bs & 1) substr+=msg[msg.length()-1-idx];
            tmp_bs >>= 1;
            idx ++;
        }
        bs --;
        
        return {substr.rbegin(), substr.rend()};
    }
    
    
    bool hasNext() {
        while(bs && __builtin_popcount(bs) != lenMsg) bs--;
        return bs;
    }
};

409. Longest Palindrome

intuitive

class Solution {
public:
    int longestPalindrome(string s) {
        map<char, int> m {};
        for (char c: s) m[c] ++;
        
        int cnt = 0;
        bool hasOven {false};
        for (auto [key, val] : m) {
            if (val%2) {
                hasOven = true;
                cnt += (val-1);
            } else cnt += val;
        }
        return cnt + (int)hasOven;
    }
};

270.Closest Binary Search Tree Value

dfs + 记录

k个值->dfs + heap

Day3

435. Non-overlapping Intervals

sort+greedy

class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        if (intervals.empty()) return 0;
        sort(intervals.begin(), intervals.end(), [](vector<int> &v, vector<int> &v2) {
           return v[1] < v2[1]; 
        });
        
        int cnt=0, b=-0x7fffffff;
        for (auto v:intervals) {
            if (b>v[0]) cnt++;
            else b=v[1];
        }
        return cnt;
    }
};

53. Maximum Subarray

dp + push

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        if (nums.empty()) return 0;
        int ss = nums.size();
        vector<int> memo(ss+1);
        int maxi = -0x7fffffff;
        for (int i=0; i<ss; i++) {
            memo[i+1] = max(nums[i], memo[i]+nums[i]); // 若合大于0,保留
            maxi = max(memo[i+1], maxi);
        }
        return maxi;
    }
};

121. Best Time to Buy and Sell Stock

简化的双指针

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.size() < 2) return 0;
        int res = 0, mini = prices[0];
        
        for (int i=1; i<prices.size(); i++) {
            res = max(res, prices[i]-mini);
            mini = min(prices[i], mini);
        }
        return res;
    }
};

122. Best Time to Buy and Sell Stock II

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.size()<2) return 0;
        
        int res=0;
        for (int i=1; i<prices.size(); i++) {
            if (prices[i]>prices[i-1]) res+=prices[i]-prices[i-1];
        }
        return res;
    }
};

123. Best Time to Buy and Sell Stock III

最多两次

1103. Distribute Candies to People

class Solution {
public:
    vector<int> distributeCandies(int candies, int num_people) {
        if (!num_people) return {};
        
        vector<int> p (num_people);
        
        int idx = 0, nCandy = 1;
        while (candies) {
            for (int i=0; i<num_people; i++) {
                if (nCandy < candies) {
                    p[i] += nCandy;
                    candies-=nCandy++;
                } else {
                    p[i]  += candies;
                    candies = 0;
                    break;
                }
            }
        }
        return p;
    }
};

967. Numbers With Same Consecutive Differences

824. Goat Latin

class Solution {
public:
    string toGoatLatin(string S) {
        if (S.length() < 1) return S;
        set<char> cset {'a', 'e', 'o', 'i', 'u'};
        stringstream ss(S);
        string token {};
        string ending = "a";
        string res = "";
        
        while (getline(ss, token, ' ')) {
            char endc = token[token.size()-1];

            if (cset.find(tolower(token[0])) == cset.end()) {
                char c = token[0];
                token = token.substr(1) + c;
            }
            
            res += token + "ma" + ending + " ";
            ending += "a";
        }
        return {res.begin(), res.end()-1};
    }
};

143. Reorder List

/**
 * 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:
    void reorderList(ListNode* head) {
        if (!head) return;
        stack<ListNode*> s {{head}};
        auto tHead = head;
        int size=1;
        
        while(tHead->next) {
            tHead = tHead->next;
            s.push(tHead);
            size++;
        }
        
        for (int i=0; i<size/2; i++) {
            auto next = head->next;
            auto backNode = s.top(); s.pop();
            head->next = backNode;
            backNode->next = next;
            head = next;
        }
        head->next = nullptr;      
    }
};

905. Sort Array By Parity

双指针

class Solution {
public:
    vector<int> sortArrayByParity(vector<int>& A) {
        int ss = A.size(), idx = ss-1;
        for (int i=0; i<ss; i++) {
            while(idx>i && A[i] % 2) swap(A[i], A[idx--]);
        }
        return A;
    }
};

484. Find Permutation

posted @ 2020-08-21 20:05  linsinan1995  阅读(123)  评论(0)    收藏  举报