Thursday, September 26, 2019

Move Zeros

Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements.
Example:
Input: [0,1,0,3,12]
Output: [1,3,12,0,0]
Note:
  1. You must do this in-place without making a copy of the array.
  2. Minimize the total number of operations.

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        if (nums.size() == 0) {
            return;
        }
     
        int zero_iter = 0, iter = 0;
        while (iter < nums.size()) {
            if (nums[iter] == 0) {
                break;
            }
            iter++;
        }
        if (iter == nums.size()) {
            return;
        }
     
        zero_iter = iter;
        iter = zero_iter + 1;
        while (iter < nums.size()) {
            if (nums[iter] != 0) {
                nums[zero_iter] = nums[iter];
                nums[iter] = 0;
                zero_iter++;
                while (zero_iter < nums.size()) {
                    if (nums[zero_iter] == 0) {
                        break;
                    } else {
                        zero_iter++;
                    }
                }
            }
            iter++;
        }
        return;
    }
};

==============
class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int size = nums.size();
        if (size == 0) {
            return;
        }
        int pos = 0, iter = 0;
        while (iter < size) {
            if (nums[iter] != 0) {
                nums[pos++] = nums[iter];
            }
            iter++;
        }
        while (pos != size) {
            nums[pos++] = 0;
        }
        return;
    }
};


============
class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        /*
        int zero_idx = 0, cur_idx = 0;
        while (zero_idx < nums.size() && nums[zero_idx] != 0) {
            zero_idx++;
        }
        cur_idx = zero_idx;
        while (cur_idx < nums.size()) {
            if (nums[cur_idx] == 0) {
                cur_idx++;
            } else {
                nums[zero_idx++] = nums[cur_idx];
                nums[cur_idx] = 0;
                while (zero_idx < nums.size() && nums[zero_idx] != 0) {
                    zero_idx++;
                }
                cur_idx = zero_idx;
            }
        }
        */
        int size = nums.size();
        if (size == 0) {
            return;
        }
        int pos = 0, iter = 0;
        while (iter < size) {
            if (nums[iter] != 0) {
                nums[pos++] = nums[iter];
            }
            iter++;
        }
        while (pos != size) {
            nums[pos++] = 0;
        }
        return;
    }
};

Sunday, September 8, 2019

LRU Cache

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.
get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
The cache is initialized with a positive capacity.
Follow up:
Could you do both operations in O(1) time complexity?
Example:
LRUCache cache = new LRUCache( 2 /* capacity */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1);       // returns 1
cache.put(3, 3);    // evicts key 2
cache.get(2);       // returns -1 (not found)
cache.put(4, 4);    // evicts key 1
cache.get(1);       // returns -1 (not found)
cache.get(3);       // returns 3
cache.get(4);       // returns 4

class LRUCache {
    private:
    list<pair<int, int>> lst;
    unordered_map<int, list<pair<int, int>>::iterator> mp;
    int cap;
    
    void makeHot(list<pair<int, int>>::iterator it) {
            pair<int, int> data = *it;
            lst.erase(it);
            
            lst.push_front(data);
            mp[data.first] = lst.begin();
    }
public:
    LRUCache(int capacity) {
        cap = capacity;
    }
    
    int get(int key) {
        if (mp.find(key) == mp.end()) {
            return -1;
        }

        int val = (*mp[key]).second;
        makeHot(mp[key]);
        return val;
    }
    
    void put(int key, int value) {
        if (mp.find(key) != mp.end()) {
            lst.erase(mp[key]);
        } else if (lst.size() == cap && cap >= 1) {
            int key = lst.back().first;
            lst.pop_back();
            mp.erase(key);
        }

        lst.push_front(make_pair(key, value));
        mp[key] = lst.begin();
    }
};

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache* obj = new LRUCache(capacity);
 * int param_1 = obj->get(key);
 * obj->put(key,value);
 */

Thursday, September 5, 2019

Minimum Window Substring

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
Example:
Input: S = "ADOBECODEBANC", T = "ABC"
Output: "BANC"
Note:
  • If there is no such window in S that covers all characters in T, return the empty string "".
  • If there is such window, you are guaranteed that there will always be only one unique minimum window in S.



class Solution {

public:
    string minWindow(string s, string t) {
        if (s.empty() || t.empty() || s.size() < t.size()) {
            return "";
        }
        map<char, int> mp;
        string ans;
        
        for (int i = 0; i < t.size(); i++) {
            mp[t[i]]++;
        }
        
        int st = 0, ed = 0, count = 0;
        
        while (ed < s.size()) {
            if (mp.find(s[ed]) != mp.end()) {
                mp[s[ed]]--;
                if (mp[s[ed]] >= 0) {
                    count++;
                }
                
                if (count == t.size()) {
                    while (st < s.size()) {
                        if (mp.find(s[st]) != mp.end() && mp[s[st]] >= 0) {
                            break;
                        } else if (mp.find(s[st]) != mp.end() && mp[s[st]] < 0) {
                            mp[s[st]]++;
                        }
                        st++;
                    }
                    string tmp = s.substr(st, ed - st + 1);
                    if (ans.empty()) {
                        ans = tmp;
                    } else if (tmp.size() < ans.size()) {
                        ans = tmp;
                    }
                }
            }
            ed++;
        }
        return ans;
    }
};

============ Efficient one =========
vector<int> letterCnt(128,0); int left = 0, cnt = 0, minLeft = -1, minLen = INT_MAX; for(char c:t) letterCnt[c]++; for(int i=0;i<s.size();i++){ if(--letterCnt[s[i]]>=0) cnt++; while(cnt == t.size()){ if(minLen > i-left+1){ minLen = i-left+1; minLeft = left; } if(++letterCnt[s[left]]>0) cnt--; left++; } } return minLeft == -1 ? "":s.substr(minLeft,minLen);

============== Another =======
class Solution { public: string minWindow(string s, string t) { map<char, int> mp; int count = 0; int left = 0, right = 0; int finalLeft = -1, finalRight = -1; int diff = INT_MAX; if (s.empty() || t.empty()) { return ""; } for (auto ch : t) { mp[ch]++; } while (right < s.size()) { if (mp.find(s[right]) == mp.end()) { right++; continue; } if (mp[s[right]] > 0) { count++; } mp[s[right]]--; while (count == t.size() && left < s.size()) { if (mp.find(s[left]) == mp.end()) { left++; continue; } int ans = right - left + 1; if (ans <= diff) { diff = ans; finalLeft = left; finalRight = right; } if (mp[s[left]] < 0) { mp[s[left]]++; left++; } else { break; } } right++; } if (finalLeft >= 0) { return s.substr(finalLeft, finalRight - finalLeft + 1); } return ""; } };