hash table first 47 (1 - 447)

Ace your homework & exams now with Quizwiz!

350. Intersection of Two Arrays II Given two arrays, write a function to compute their intersection. Example 1: Input: nums1 = [1,2,2,1], nums2 = [2,2] Output: [2,2]

similar to 349, we use map to record the count. class Solution { public: vector<int> intersect(vector<int>& nums1, vector<int>& nums2) { unordered_map<int, int> map1 = getMap(nums1); unordered_map<int, int> map2 = getMap(nums2); vector<int> res; for(auto& [num, count]: map1) { if(map2.find(num) != map2.end()) { int val = min(count, map2[num]); for(int i = 0; i < val; i ++) res.push_back(num); } } return res; } unordered_map<int, int> getMap(vector<int>& arr) { unordered_map<int, int> res; for(auto& num: arr) res[num] ++; return res; } };

347. Top K Frequent Elements Given a non-empty array of integers, return the k most frequent elements. Example 1: Input: nums = [1,1,1,2,2,3], k = 2 Output: [1,2]

first use countMap to record the count. then use priority_queue to get most frequent num. struct comparer { bool operator() (pair<int,int>& p1, pair<int,int>& p2) { return p1.second > p2.second; } }; class Solution { public: vector<int> topKFrequent(vector<int>& nums, int k) { int size = nums.size(); unordered_map<int ,int > countMap; for(auto& num: nums) countMap[num] ++; priority_queue<pair<int,int>, vector<pair<int,int>>, comparer> pq; for(auto& [num, count]: countMap) { if(pq.size() < k) { pq.push(pair(num, count)); } else { if(count <= pq.top().second) continue; else { pq.pop(); pq.push(pair(num,count)); } } } vector<int> res; while(! pq.empty()) { res.push_back(pq.top().first); pq.pop(); } return res; } };

49. Group Anagrams Given an array of strings, group anagrams together. Example: Input: ["eat", "tea", "tan", "ate", "nat", "bat"], Output: [ ["ate","eat","tea"], ["nat","tan"], ["bat"] ]

for each string in strs, we sort and use as key. class Solution { public: vector<vector<string>> groupAnagrams(vector<string>& strs) { unordered_map<string, vector<string>> keyMap; for(auto& str: strs) { string tmp = str; sort(tmp.begin(), tmp.end()); keyMap[tmp].push_back(str); } vector<vector<string>> res; for(auto& [key, arr]: keyMap) res.push_back(arr); return res; } vector<vector<string>> groupAnagrams1(vector<string>& strs) { //turn to key unordered_map<string, vector<string>> keyMap; for(auto& str: strs) { map<char, int> counts; for(auto& ch: str) counts[ch] ++; string tmp; for(auto& [ch, count]: counts) tmp += to_string(count) + ch; keyMap[tmp].push_back(str); } vector<vector<string>> res; for(auto& [key, arr]: keyMap) res.push_back(arr); return res; } };

409. Longest Palindrome Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters. This is case sensitive, for example "Aa" is not considered a palindrome here. Input: "abccccdd" Output: 7

use count map. class Solution { public: int longestPalindrome(string s) { unordered_map<char, int> counts; for(auto& ch: s) counts[ch] ++; int flag = 0; int res = 0; for(auto& [ch, count]: counts) { if(count % 2 == 1) flag = 1; res += count / 2 * 2; } res += flag; return res; } };

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.

use map to record last timestamp of message. class Logger { private: unordered_map<string, int> logs; public: /** Initialize your data structure here. */ Logger() { logs.clear(); } /** Returns true if the message should be printed in the given timestamp, otherwise returns false. If this method returns false, the message will not be printed. The timestamp is in seconds granularity. */ bool shouldPrintMessage(int timestamp, string message) { bool should = false; if(logs.find(message) == logs.end() || timestamp - logs[message] >= 10) { should = true; logs[message] = timestamp; } return should; } };

205. Isomorphic Strings Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the characters in s can be replaced to get t. All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself. Example 1: Input: s = "egg", t = "add" Output: truef

1. find current char in s, and t. same index true, else false. 2. get first appearance of char 3. maintain two map. class Solution { public: bool isIsomorphic(string s, string t) { for(int i = 0; i < s.length(); i ++) if(s.find(s[i]) != t.find(t[i])) return false; return true; } bool isIsomorphic2(string s, string t) { //record the first appearance of char unordered_map<char, int> src; unordered_map<char, int> tar; for(int i = 0; i < s.length(); i ++) { char ch1 = s[i]; char ch2 = t[i]; if(src.count(ch1) == 0) src[ch1] = i; if(tar.count(ch2) == 0) tar[ch2] = i; } for(int i = 0; i < s.length(); i ++) { if(src[s[i]] != tar[t[i]]) return false; } return true; } bool isIsomorphic1(string s, string t) { //use two map to maintain the relationship unordered_map<char, char> srcMap; unordered_map<char, char> tarMap; int len = s.length(); for(int i = 0; i < len; i ++) { char ch1 = s[i]; char ch2 = t[i]; if(srcMap.count(ch1) > 0 && srcMap[ch1] != ch2) return false; if(tarMap.count(ch2) > 0 && tarMap[ch2] != ch1) return false; srcMap[ch1] = ch2; tarMap[ch2] = ch1; } return true; } };

290. Word Pattern Given a pattern and a string str, find if str follows the same pattern. Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in str. Example 1: Input: pattern = "abba", str = "dog cat cat dog" Output: true

1. get tokens and use find function. if same index, true. 2. maintain two maps from src to target and from target to src. class Solution { public: bool wordPattern(string pattern, string str) { vector<string> tokens = getTokens(str); if(pattern.length() != tokens.size()) return false; for(int i = 0; i< pattern.length(); i ++) { if(pattern.find(pattern[i]) != find(tokens.begin(), tokens.end(), tokens[i]) - tokens.begin()) return false; } return true; } vector<string> getTokens(string s) { vector<string> res; int pos = s.find(" "); while(pos != string::npos) { string sub = s.substr(0, pos); res.push_back(sub); s.erase(0, pos + 1); pos = s.find(" "); } res.push_back(s); return res; } };

138. Copy List with Random Pointer A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. Return a deep copy of the list.

1. make copies of curr, next and random and add relationship. 2. copy the list first and add random relationship. class Solution { private: map<Node*, Node*> nodeMap; public: Node* copyRandomList(Node* head) { if(head == NULL) return NULL; nodeMap[NULL] = NULL; Node* curr = head; Node* next = curr -> next; while(curr != NULL) { if(nodeMap.count(curr) == 0) nodeMap[curr] = new Node(curr->val); if(nodeMap.count(next) == 0) nodeMap[next] = new Node(next->val); if(nodeMap.count(curr->random) == 0) nodeMap[curr->random] = new Node(curr->random->val); nodeMap[curr] -> next = nodeMap[next]; nodeMap[curr] ->random = nodeMap[curr->random]; curr = next; next = next == NULL? NULL: next->next; } return nodeMap[head]; } Node* copyRandomList1(Node* head) { //copy the list and append random Node* root = copyNode(head); Node* curr = head; while(curr != NULL) { Node* randPt = curr->random; if(randPt != NULL) { nodeMap[curr]->random = nodeMap[randPt]; } curr = curr -> next; } return root; } Node* copyNode(Node* head) { if(head == NULL) return NULL; Node* next = copyNode(head->next); Node* node = new Node(head->val, next, NULL); nodeMap[head] = node; return node; } };

274. H-Index Given an array of citations (each citation is a non-negative integer) of a researcher, write a function to compute the researcher's h-index. According to the definition of h-index on Wikipedia: "A scientist has index h if h of his/her N papers have at least h citations each, and the other N − h papers have no more than h citations each." Example: Input: citations = [3,0,6,1,5] Output: 3

1. sort citations and get min(cite, count). 2. use count sort. and from largest cite, accumulate the count. class Solution { public: int hIndex(vector<int>& citations) { int size = citations.size(); vector<int> papers(size + 1); for(auto& cite: citations) papers[min(size, cite)] ++; int k = size; for(int s = papers[size]; k > s; s += papers[k]) k --; return k; } int hIndex1(vector<int>& citations) { //sort and get min(sites, count) int size = citations.size(); sort(citations.begin(), citations.end()); int res = 0; for(int i = 0; i < size; i ++) { int curr = min(citations[i], size - i); res = max(res, curr); } return res; } };

217. Contains Duplicate Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct. Example 1: Input: [1,2,3,1] Output: true

1. sort nums array and check (faster) 2. use set class Solution { public: bool containsDuplicate(vector<int>& nums) { sort(nums.begin(), nums.end()); for(int i = 1; i < nums.size(); i ++) if(nums[i] == nums[i-1]) return true; return false; } bool containsDuplicate1(vector<int>& nums) { //use set unordered_set<int> numSet; for(auto& num: nums) { if(numSet.find(num) != numSet.end()) return true; numSet.insert(num); } return false; } };

266. Palindrome Permutation Given a string, determine if a permutation of the string could form a palindrome. Example 1: Input: "code" Output: false

1. use map + variable count, %2 ==0, count ++, else -- 2. use map only class Solution { private: unordered_map<char, int> countMap; public: bool canPermutePalindrome(string s) { int count = 0; for(auto& ch: s) { countMap[ch] ++; if(countMap[ch] % 2== 0) count --; else count ++; } return count < 2; } bool canPermutePalindrome1(string s) { //use countMap for(auto& ch:s) countMap[ch] ++; int sum = 0; for(auto& [ch, count]: countMap){ if(count % 2 == 1) sum ++; if(sum > 1) return false; } return true; } };

242. Valid Anagram Given two strings s and t , write a function to determine if t is an anagram of s. Example 1: Input: s = "anagram", t = "nagaram" Output: true

1. use map to count (fastest) 2. use vector to get count. (faster) 3. sort and compare class Solution { public: bool isAnagram(string s, string t) { if(s.length() != t.length() ) return false; unordered_map<char, int> src; unordered_map<char, int> tar; for(auto& ch: s) src[ch] ++; for(auto& ch: t) tar[ch] ++; for(auto& [ch, cou]: src) if(tar.count(ch) == 0 || tar[ch] != cou) return false; return true; } bool isAnagram(string s, string t) { if(s.length() != t.length() ) return false; vector<int> src(26); vector<int> tar(26); for(auto& ch: s) src[ch - 'a'] ++; for(auto& ch: t) tar[ch - 'a'] ++; for(int i = 0;i < 26; i++) { if(src[i] != tar[i]) return false; } return true; } bool isAnagram1(string s, string t) { //sort string sort(s.begin(), s.end()); sort(t.begin(), t.end()); return s == t; } };

389. Find the Difference Given two strings s and t which consist of only lowercase letters. String t is generated by random shuffling string s and then add one more letter at a random position. Find the letter that was added in t. Example: Input: s = "abcd" t = "abcde" Output: e

1. use map to record the count 2. use two 26 len array. class Solution { public: char findTheDifference(string s, string t) { vector<int> arr1 = getCounts(s); vector<int> arr2 = getCounts(t); for(int i = 0; i < 26; i++) { if(arr2[i] - arr1[i] == 1) return i + 'a'; } return ' '; } vector<int> getCounts(string s) { vector<int> res(26); for(auto& ch: s) { res[ch - 'a'] ++; } return res; } char findTheDifference1(string s, string t) { //use two maps unordered_map<char, int> map1 = getMap(s); unordered_map<char, int> map2 = getMap(t); char res; for(auto& [ch, count]: map2) { if(map1.find(ch) == map1.end() || count - map1[ch] == 1) return ch; } return res; } unordered_map<char, int> getMap(string s) { unordered_map<char, int> res; for(auto& ch: s) res[ch] ++; return res; } };

299. Bulls and Cows You are playing the following Bulls and Cows game with your friend: You write down a number and ask your friend to guess what the number is. Each time your friend makes a guess, you provide a hint that indicates how many digits in said guess match your secret number exactly in both digit and position (called "bulls") and how many digits match the secret number but locate in the wrong position (called "cows"). Your friend will use successive guesses and hints to eventually derive the secret number. Input: secret = "1807", guess = "7810" Output: "1A3B"

1. use set to record mismatch index. 2. use two maps. class Solution { public: string getHint(string secret, string guess) { unordered_set<int> indSet; vector<int> mismatch(10); int bull = 0; int cow = 0; for(int i = 0; i < secret.length(); i ++) { if(secret[i] == guess[i]) bull ++; else { mismatch[secret[i] - '0'] ++; indSet.insert(i); } } for(auto& ind: indSet) { char ch = guess[ind]; if(mismatch[ch - '0'] > 0) { cow ++; mismatch[ch - '0'] --; } } return to_string(bull) + 'A' + to_string(cow) + 'B'; } string getHint1(string secret, string guess) { //use two maps int bull = 0; int cow = 0; unordered_map<char, int> m1; unordered_map<char, int> m2; for(int i = 0; i < secret.length(); i ++) { if(secret[i] == guess[i]) bull ++; else { m1[secret[i]] ++; m2[guess[i]] ++; } } for(char ch = '0'; ch <= '9'; ch ++) { cow += min(m1[ch], m2[ch]); } return to_string(bull) + 'A' + to_string(cow) + 'B'; } };

204. Count Primes Count the number of prime numbers less than a non-negative number, n. Example: Input: 10 Output: 4 Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7.

1. we check each num isPrime or not, 15% 2. we mark the numbers which 2*x, 3*x ,5*x as non prime. and the rest are all primes class Solution { public: int countPrimes(int n) { if(n <= 2) return 0; vector<bool> isPrime(n, true); for(int i = 2; i*i < n; i ++) { if(!isPrime[i]) continue; for(int num = i * i; num < n; num += i) isPrime[num] = false; } int res = 0; for(int i = 2; i < n; i ++) if(isPrime[i]) res ++; return res; } int countPrimes1(int n) { //check isprime set<int> nums; if(n <= 2) return 0; nums.insert(2); for(int i = 3; i < n; i ++) { bool isPrime = true; int sqrted = sqrt(i-1) + 1; for(auto& val: nums) { if(val > sqrted) break; if(i % val == 0) { isPrime = false; break; } } if(isPrime) nums.insert(i); } return nums.size(); } };

30. Substring with Concatenation of All Words You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters. Input: s = "barfoothefoobarman", words = ["foo","bar"] Output: [0,9]

get the map of words, and get current sub str map. class Solution { public: vector<int> findSubstring(string s, vector<string>& words) { int size = words.size(); if(size == 0) return {}; int sublen = words[0].length(); set<string> strSet(words.begin(), words.end()); int len = s.length(); if(len == 0) return {}; if(len < sublen * size) return {}; unordered_map<string, int> counts; getCounts(words, counts); unordered_map<string, int> curMap; vector<int> res; for(int i = 0; i + sublen * size -1 < len; i ++) { string sub = s.substr(i, sublen); if(strSet.find(sub) != strSet.end()) { curMap = getMap(s.substr(i, size * sublen), sublen); if(isSame(counts, curMap)) res.push_back(i); } } return res; } unordered_map<string, int> getMap(string s, int len) { unordered_map<string, int> res; for(int i = 0; i < s.length(); i += len) { res[s.substr(i, len)] ++; } return res; } bool isSame(unordered_map<string, int>& map1, unordered_map<string, int>& map2) { for(auto& [str, count]: map1) { if(map2.count(str) == 0 || map2[str] != count) return false; } return true; } vector<string> getTokens(string s, int len) { vector<string> res; for(int i = 0; i< s.length(); i += len) res.push_back(s.substr(i, len)); return res; } void getCounts(vector<string>& words, unordered_map<string, int>& counts) { for(auto& str: words) counts[str] ++; } };

356. Line Reflection Given n points on a 2D plane, find if there is such a line parallel to y-axis that reflect the given points. Example 1: Input: [[1,1],[-1,1]] Output: true

if point have same y value, we store in map. and compare the mid x. class Solution { public: bool isReflected(vector<vector<int>>& points) { unordered_map<int, set<int>> yMap; for(auto& arr: points) { yMap[arr[1]].insert(arr[0]); } double mid = INT_MAX; for(auto& [y, arr]: yMap) { int size = arr.size(); auto l = arr.begin(); auto r = --(arr.end()); int i = 0; int j = size - 1; while(i <= j) { double curr = (*l + *r) / 2.0; if(mid == INT_MAX) mid = curr; else if(abs(curr - mid) > 1e-6) return false; l ++; r --; i ++; j --; } } return true; } };

311. Sparse Matrix Multiplication Given two sparse matrices A and B, return the result of AB. You may assume that A's column number is equal to B's row number. Example: Input: A = [ [ 1, 0, 0], [-1, 0, 3] ] B = [ [ 7, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 1 ] ] Output: | 1 0 0 | | 7 0 0 | | 7 0 0 | AB = | -1 0 3 | x | 0 0 0 | = | -7 0 3 | | 0 0 1 |

sparse is the point. we record the non-zeros of A rows, and B cols. use the min size of non-zero to calc. class Solution { public: vector<vector<int>> multiply(vector<vector<int>>& A, vector<vector<int>>& B) { int rowA = A.size(); if(rowA == 0) return {}; int colA = A[0].size(); int rowB = B.size(); if(rowB == 0) return {}; int colB = B[0].size(); vector<vector<int>> res(rowA, vector<int>(colB)); vector<set<int>> rowsA(rowA); for(int r = 0; r < rowA; r ++) { for(int c = 0; c< colA; c ++) { if(A[r][c]) rowsA[r].insert(c); } } vector<set<int>> colsB(colB); for(int c = 0; c < colB; c ++) { for(int r = 0; r < rowB; r ++) { if(B[r][c]) colsB[c].insert(r); } } for(int r = 0; r < rowA; r ++) { for(int c = 0; c < colB; c ++) { int curr = 0; if(rowsA[r].size() <= colsB[c].size()) { for(auto& ind: rowsA[r]) { if(colsB[c].find(ind) != colsB[c].end()) { curr += A[r][ind] * B[ind][c]; } } } else { for(auto& ind: colsB[c]) { if(rowsA[r].find(ind) != rowsA[r].end()) { curr += A[r][ind] * B[ind][c]; } } } res[r][c] = curr; } } return res; } };

381. Insert Delete GetRandom O(1) - Duplicates allowed Design a data structure that supports all following operations in average O(1) time. Note: Duplicate elements are allowed. insert(val): Inserts an item val to the collection. remove(val): Removes an item val from the collection if present. getRandom: Returns a random element from current collection of elements. The probability of each element being returned is linearly related to the number of same value the collection contains.

this is the same as #380. but it allows duplicate. so we use arr to store data. use map<int, set<int>> to store index. 1 insert: insert to arr and map. 2 remove: get last ind of val, fill in the ind with last element, update the idx set of last element, update the idx set of val, erase. 3. random: use arr. class RandomizedCollection { private: vector<int> arr; unordered_map<int, set<int> > indMap; public: /** Initialize your data structure here. */ RandomizedCollection() { arr.clear(); indMap.clear(); } /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ bool insert(int val) { indMap[val].insert(arr.size()); arr.push_back(val); return indMap[val].size() == 1; } /** Removes a value from the collection. Returns true if the collection contained the specified element. */ bool remove(int val) { if(indMap.find(val) == indMap.end() || indMap[val].size() == 0) return false; set<int> idx = indMap[val]; int last = arr.back(); int ind = *(--(idx.end()) ); arr[ind] = last; indMap[last].erase(arr.size() - 1); indMap[last].insert(ind); indMap[val].erase(ind); arr.pop_back(); return true; } /** Get a random element from the collection. */ int getRandom() { int size = arr.size(); if(size == 0) return -1; int ind = rand() % size; return arr[ind]; } };

219. Contains Duplicate II Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k. Example 1: Input: nums = [1,2,3,1], k = 3 Output: true

use map to record the latest ind. class Solution { public: bool containsNearbyDuplicate(vector<int>& nums, int k) { unordered_map<int, int > indMap; for(int i = 0; i < nums.size(); i ++) { int val = nums[i]; if(indMap.count(val) > 0) { if(i - indMap[val] <= k) return true; } indMap[val] = i; } return false; } };

325. Maximum Size Subarray Sum Equals k Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If there isn't one, return 0 instead. Note: The sum of the entire nums array is guaranteed to fit within the 32-bit signed integer range. Example 1: Input: nums = [1, -1, 5, -2, 3], k = 3 Output: 4 Explanation: The subarray [1, -1, 5, -2] sums to 3 and is the longest.

use map<int,int> to record the min index of sum. class Solution { public: int maxSubArrayLen(vector<int>& nums, int k) { int size = nums.size(); unordered_map<int, int> indMap; indMap[0] = 0; int sum = 0; int res = 0; for(int i = 0; i < size; i ++) { int num = nums[i]; sum += num; if(indMap.find(sum - k) != indMap.end()) { int dis = i+1 - indMap[sum-k]; res = max(res, dis); } if(indMap.find(sum) == indMap.end()) indMap[sum] = i + 1; } return res; } };

166. Fraction to Recurring Decimal Given two integers representing the numerator and denominator of a fraction, return the fraction in string format. If the fractional part is repeating, enclose the repeating part in parentheses. Input: numerator = 2, denominator = 3 Output: "0.(6)"

we check the sign, get first part before "." and then use map to record the numerator. If same numerator appears, we add (). class Solution { public: string fractionToDecimal(int numerator, int denominator) { string op = (numerator >= 0) ^(denominator >= 0) ? "-": ""; if(numerator == 0) op = ""; string res; long numer = labs(numerator); long denom = labs(denominator); long v = numer / denom; res += op + to_string(v); long v1 = numer % denom; if(v1 ==0) return res; res += '.'; map<int, int> numMap; while(v1 != 0) { if(numMap.count(v1) != 0) { int ind = numMap[v1]; res.insert(res.begin() + ind, '('); res += ')'; return res; } int remain = v1 * 10 / denom; numMap[v1] = res.length(); v1 = v1 * 10 % denom; res += to_string(remain); } return res; } };

447. Number of Boomerangs Given n points in the plane that are all pairwise distinct, a "boomerang" is a tuple of points (i, j, k) such that the distance between i and j equals the distance between i and k (the order of the tuple matters). Input: [[0,0],[1,0],[2,0]] Output: 2

we get the len map: count of len. class Solution { public: int numberOfBoomerangs(vector<vector<int>>& points) { int size = points.size(); unordered_map<int, int > lenMap; int res = 0; for(int i = 0; i < size; i ++) { for(int j = 0; j < size; j ++) if(i != j) { int len = pow(points[j][0] - points[i][0], 2) + pow(points[j][1] - points[i][1], 2); lenMap[len] ++; } for(auto& [len, count]: lenMap) res += (count - 1) * count; lenMap.clear(); } return res; } };

149. Max Points on a Line Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]] Output: 4 Explanation: ^ | | o | o o | o | o o +-------------------> 0 1 2 3 4 5 6

we go through each point, and calc the dx, dy and put into map. class Solution { public: int maxPoints(vector<vector<int>>& p) { int size = p.size(); int res = 0; for(int i = 0; i < size; i ++) { int x = p[i][0]; int y = p[i][1]; int same = 0; map< pair<int,int>, int> counts; int curr = 0; for(int j = 0; j < size; j ++) if(i != j) { int x1 = p[j][0]; int y1 = p[j][1]; int dx = x1-x; int dy = y1-y; if(dx == 0 && dy == 0) { same ++; continue; } else if(dx == 0) { counts[pair(0,1)] ++; curr = max(curr, counts[pair(0, 1)]); } else if(dy == 0) { counts[pair(1,0)] ++; curr = max(curr, counts[pair(1, 0)]); } else { int val = gcd(dx, dy); dx /= val; dy /= val; counts[pair(dx, dy)] ++; curr = max(curr, counts[pair(dx, dy)]); } } curr += same + 1; res = max(res, curr); } return res; } int gcd(int v1, int v2) { if(v1 == 0) return v2; return gcd(v2 % v1, v1); } };

76. 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"

we keep track how many unique char achieved target count. If it achieved, we move left pointer forward, until not achieved. class Solution { public: string minWindow(string s, string t) { if(s.length() == 0 || t.length() == 0) return ""; unordered_map<char, int> counts; for(auto& ch: t) counts[ch] ++; int needed = counts.size(); int count = 0; vector<int> ans = {-1, 0, 0}; int l = 0; int r = 0; unordered_map<char,int> curMap; while(r < s.length()) { char ch = s[r]; curMap[ch] ++; if(counts.count(ch) > 0 && curMap[ch] == counts[ch]) { count ++; if(count == needed) { while(l <= r && count == needed) { char c = s[l]; if(ans[0] == -1 || r - l + 1 < ans[0]) { ans[0] = r - l + 1; ans[1] = l; ans[2] = r; } curMap[c] --; if(counts.count(c) > 0 && curMap[c] < counts[c]) { count --; } l ++; } } } r ++; } if(ans[0] == -1) return ""; return s.substr(ans[1], ans[0]); } };

159. Longest Substring with At Most Two Distinct Characters Given a string s , find the length of the longest substring t that contains at most 2 distinct characters. Input: "ccaabbb" Output: 5

we keep track the latest index of each char. and when size > 2, we erase the char with smallest index. class Solution { public: int lengthOfLongestSubstringTwoDistinct(string s) { int len = s.length(); int res = 0; int start = 0; unordered_map<char, int> indMap; for(int i = 0; i < len; i ++) { char ch = s[i]; if(indMap.count(ch) != 0 || indMap.size() < 2) indMap[ch] = i; else { int ind = INT_MAX; for(auto& [ch, idx]: indMap) { ind = min(ind, idx); } char toDelete = s[ind]; indMap.erase(toDelete); start = ind + 1; indMap[ch] = i; } res = max(res, i - start +1); } return res; } };

246. Strobogrammatic Number A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down). Write a function to determine if a number is strobogrammatic. The number is represented as a string. Example 1: Input: "69" Output: true

we maintain a map to record the mirror. class Solution { private: unordered_map<char, char> charMap = {{'0', '0'}, {'1', '1'}, {'6', '9'}, {'8', '8'}, {'9', '6'}}; public: bool isStrobogrammatic(string num) { for(int i = 0, j = num.length() - 1; i <= j; i ++, j --) { if(charMap[num[i]] != num[j]) return false; } return true; } };

249. Group Shifted Strings Given a string, we can "shift" each of its letter to its successive letter, for example: "abc" -> "bcd". We can keep "shifting" which forms the sequence: "abc" -> "bcd" -> ... -> "xyz" Given a list of strings which contains only lowercase alphabets, group all strings that belong to the same shifting sequence. Example: Input: ["abc", "bcd", "acef", "xyz", "az", "ba", "a", "z"], Output: [ ["abc","bcd","xyz"], ["az","ba"], ["acef"], ["a","z"] ]

we turn the shifted strings back to ori str. class Solution { public: vector<vector<string>> groupStrings(vector<string>& strings) { vector<vector<string>> res; unordered_map<string, vector<string>> strMap; for(auto& str: strings) { if(str.length() == 0) { strMap[str] = {str}; continue; } string tmp = "a"; for(int i = 1; i < str.length(); i ++) tmp += (str[i] + 26 - str[0]) % 26 + 'a'; strMap[tmp].push_back(str); } for(auto& [str, arr]: strMap) res.push_back(arr); return res; } };

336. Palindrome Pairs Given a list of unique words, find all pairs of distinct indices (i, j) in the given list, so that the concatenation of the two words, i.e. words[i] + words[j] is a palindrome. Example 1: Input: ["abcd","dcba","lls","s","sssll"] Output: [[0,1],[1,0],[3,2],[2,4]] Explanation: The palindromes are ["dcbaabcd","abcddcba","slls","llssssll"]

we use a reversed map to record the reversed ind. Use a pair set to record the unique result. class Solution { public: vector<vector<int>> palindromePairs(vector<string>& words) { int size = words.size(); unordered_map<string, int> dict; for(int i = 0; i < size; i ++) { string s = words[i]; reverse(s.begin(), s.end()); dict[s] = i; } set<pair<int,int>> pairs; vector<vector<int>> ans; for(int i = 0; i < size; i ++) { string word = words[i]; int len = word.length(); for(int j = 0; j <= len; j ++) { string left = word.substr(0, j); string right = word.substr(j); if(isPalin(left) && dict.find(right) != dict.end() && dict[right] != i) { pairs.insert(pair(dict[right], i)); } if(isPalin(right) && dict.find(left) != dict.end() && dict[left] != i) { pairs.insert(pair(i, dict[left])); } } } for(auto& p: pairs) ans.push_back({p.first, p.second}); return ans; } bool isPalin(string s) { if(s == "") return true; int l = 0; int r = s.length() - 1; while(l <= r) { if(s[l] != s[r]) return false; l ++; r --; } return true; } };

380. Insert Delete GetRandom O(1) Design a data structure that supports all following operations in average O(1) time. insert(val): Inserts an item val to the set if not already present. remove(val): Removes an item val from the set if present. getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned.

we use arr to store data. use map<int,int> to store index. use size to indicate real valid data. 1. insert: insert unique data. 2. remove: swap with last element(size - 1) and size-- 3. random: get ind in size. class RandomizedSet { private: vector<int> arr; unordered_map<int, int > indMap; public: /** Initialize your data structure here. */ RandomizedSet() { arr.clear(); indMap.clear(); } /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ bool insert(int val) { if(indMap.find(val) != indMap.end()) return false; indMap[val] = arr.size(); arr.push_back(val); return true; } /** Removes a value from the set. Returns true if the set contained the specified element. */ bool remove(int val) { if(indMap.find(val) == indMap.end()) return false; int ind = indMap[val]; arr[ind] = arr.back(); indMap[arr[ind]] = ind; indMap.erase(val); arr.pop_back(); return true; } /** Get a random element from the set. */ int getRandom() { int size = arr.size(); if(size == 0) return -1; int ind = rand() % size; return arr[ind]; } };

36. Valid Sudoku Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules: Each row must contain the digits 1-9 without repetition. Each column must contain the digits 1-9 without repetition. Each of the 9 3x3 sub-boxes of the grid must contain the digits 1-9 without repetition.

we use bit operations to check whether duplicate. use array for each row, col, sqare. class Solution { public: bool isValidSudoku(vector<vector<char>>& board) { vector<int> rows(9); vector<int> cols(9); vector<int> sqrs(9); for(int r = 0; r < 9; r ++) { for(int c = 0; c < 9; c ++) { if(board[r][c] != '.') { int val = board[r][c] - '1'; if ( ((rows[r] >> val) & 1) == 1) return false; if( ((cols[c] >> val) & 1) == 1) return false; int ind = (r / 3) * 3 + (c / 3); if( ((sqrs[ind] >> val) & 1) == 1) return false; rows[r] |= (1 << val); cols[c] |= (1 << val); sqrs[ind] |= (1 << val); } } } return true; } };

94. Binary Tree Inorder Traversal Given a binary tree, return the inorder traversal of its nodes' values. Example: Input: [1,null,2,3] 1 \ 2 / 3 Output: [1,3,2]

we use both recursion and iteration to get inorder. /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<int> inorderTraversal(TreeNode* root) { stack<TreeNode*> s; if(root == NULL) return {}; TreeNode* curr = root; s.push(root); while(curr->left != NULL) { s.push(curr->left); curr = curr->left; } vector<int> res; while(! s.empty()) { TreeNode* node = s.top(); s.pop(); if(node == NULL) continue; res.push_back(node->val); if(node->right != NULL) { node = node->right; while(node != NULL) { s.push(node); node = node->left; } } } return res; } vector<int> inorderTraversal1(TreeNode* root) { //recursion vector<int> res; inorder(root, res); return res; } void inorder(TreeNode* root, vector<int>& res) { if(root == NULL) return; inorder(root->left, res); res.push_back(root->val); inorder(root->right, res); } };

387. First Unique Character in a String Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1. Examples: s = "leetcode" return 0.

we use count map to record the count of char. class Solution { public: int firstUniqChar(string s) { unordered_map<char, int> counts; for(auto& ch: s) counts[ch] ++; for(int i = 0; i < s.length(); i ++) { if(counts[s[i]] == 1) return i; } return -1; } };

358. Rearrange String k Distance Apart Given a non-empty string s and an integer k, rearrange the string such that the same characters are at least distance k from each other. All input strings are given in lowercase letters. If it is not possible to rearrange the string, return an empty string "". Example 1: Input: s = "aabbcc", k = 3 Output: "abcabc"

we use count map to record the count. then use priority_queue to list the char count. use larger count first. If count are same, use smaller char first. struct comparer { bool operator() (pair<char,int>& p1, pair<char,int>& p2) { return p1.second < p2.second || (p1.second == p2.second && p1.first > p2.first); } }; class Solution { public: string rearrangeString(string s, int k) { if(k == 0) return s; map<char, int> countMap; for(auto& ch: s) countMap[ch] ++; priority_queue<pair<char,int>, vector<pair<char,int>>, comparer> pq; for(auto& [val, count]: countMap) pq.push(pair(val, count)); int len = s.length(); string res; while(len > 0) { int val = min(len, k); vector<pair<char,int>> cache; for(int i = 0; i < val; i ++) { if(pq.empty()) return ""; pair<char,int> curr = pq.top(); pq.pop(); res += curr.first; if(curr.second - 1 > 0) cache.push_back(pair(curr.first, curr.second -1)); len --; } for(auto& pair: cache) pq.push(pair); } return res; } };

170. Two Sum III - Data structure design Design and implement a TwoSum class. It should support the following operations: add and find. add - Add the number to an internal data structure. find - Find if there exists any pair of numbers which sum is equal to the value. Example 1: add(1); add(3); add(5); find(4) -> true find(7) -> false

we use count map to record the current num counts. when find() we go through map and find. class TwoSum { private: unordered_map<int, int> nums; public: /** Initialize your data structure here. */ TwoSum() { nums.clear(); } /** Add the number to an internal data structure.. */ void add(int number) { nums[number] ++; } /** Find if there exists any pair of numbers which sum is equal to the value. */ bool find(int value) { for(auto& [val, count]: nums) { int num = value - val; if( (num == val && count > 1) || (num != val && nums.find(num) != nums.end())) return true; } return false; } }; /** * Your TwoSum object will be instantiated and called as such: * TwoSum* obj = new TwoSum(); * obj->add(number); * bool param_2 = obj->find(value); */

136. Single Number Given a non-empty array of integers, every element appears twice except for one. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? Example 1: Input: [2,2,1] Output: 1

we use map to count the num. class Solution { public: int singleNumber(vector<int>& nums) { unordered_map<int, int> counts; for(auto& num: nums) { if(counts.count(num) == 0) counts[num] ++; else { counts[num] --; if(counts[num] == 0) counts.erase(num); } } return counts.begin()->first; } };

187. Repeated DNA Sequences All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA. Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule. Example: Input: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT" Output: ["AAAAACCCCC", "CCCCCAAAAA"]

we use map to record the count of 10 len sub string. if count > 1, insert into set. class Solution { public: vector<string> findRepeatedDnaSequences(string s) { unordered_map<string, int> strMap; set<string> res; for(int i = 0; i + 9 < s.length(); i ++) { string sub = s.substr(i, 10); strMap[sub] ++; if(strMap[sub] > 1) res.insert(sub); } vector<string> resArr(res.begin(), res.end()); return resArr; } };

340. Longest Substring with At Most K Distinct Characters Given a string, find the length of the longest substring T that contains at most k distinct characters. Example 1: Input: s = "eceba", k = 2 Output: 3 Explanation: T is "ece" which its length is 3.

we use map to record the latest pos of char. ///!!!!!!!!!!!!!! res may happen in the end class Solution { private: unordered_map<char, int> charMap; public: int lengthOfLongestSubstringKDistinct(string s, int k) { if(k == 0) return 0; int start = 0; int res = 0; for(int i = 0; i < s.length(); i ++) { char ch = s[i]; if(charMap.find(ch) != charMap.end() || charMap.size() < k) charMap[ch] = i; else { int ind = i; for(auto& [ch, idx]: charMap) { ind = min(ind, idx); } res = max(res, i - start); start = ind + 1; char toDelete = s[ind]; charMap.erase(toDelete); charMap[ch] = i; } } res = max(res, int(s.length()) - start); return res; } };

202. Happy Number A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers. Example: Input: 19 Output: true Explanation: 12 + 92 = 82 82 + 22 = 68 62 + 82 = 100 12 + 02 + 02 = 1

we use map to record the nums occured until now. If num == 1, return true. if num occured before, false. class Solution { public: bool isHappy(int n) { unordered_set<int> nums; while(n != 1) { if(nums.find(n) != nums.end()) return false; nums.insert(n); n = getSums(n); } return true; } int getSums(int val) { int res = 0; while(val > 0) { int rem = val % 10; res += rem * rem; val /= 10; } return res; } };

355. Design Twitter Design a simplified version of Twitter where users can post tweets, follow/unfollow another user and is able to see the 10 most recent tweets in the user's news feed. Your design should support the following methods: postTweet(userId, tweetId): Compose a new tweet. getNewsFeed(userId): Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. follow(followerId, followeeId): Follower follows a followee. unfollow(followerId, followeeId): Follower unfollows a followee. /** * Your Twitter object will be instantiated and called as such: * Twitter* obj = new Twitter(); * obj->postTweet(userId,tweetId); * vector<int> param_2 = obj->getNewsFeed(userId); * obj->follow(followerId,followeeId); * obj->unfollow(followerId,followeeId); */

we use map<int, set<int>> to record following. we use map<int, vector<int>> to record tweets, it's sorted. struct Tweet { int id; int time; Tweet() {}; Tweet(int id, int time):id(id), time(time) {}; bool operator < (const Tweet& t) const { return time < t.time; } }; class Twitter { private: unordered_map<int, unordered_set<int> > following; unordered_map<int, vector<Tweet>> tweets; int time; public: /** Initialize your data structure here. */ Twitter() { following.clear(); tweets.clear(); time = 0; } /** Compose a new tweet. */ void postTweet(int userId, int tweetId) { tweets[userId].push_back(Tweet(tweetId, time)); time ++; } vector<int> getNewsFeed(int userId) { unordered_set<int> friends = following[userId]; vector<vector<Tweet>> total = {tweets[userId] }; for(auto& fri: friends) total.push_back(tweets[fri]); int size = total.size(); vector<int> inds(size); for(int i = 0; i < size; i ++) inds[i] = total[i].size() - 1; vector<int> res; int count = 10; while(count > 0) { int idx = -1; int latest = INT_MIN; for(int i = 0; i < size; i ++) { if(inds[i] >= 0 && total[i][inds[i]].time > latest) { idx = i; latest = total[i][inds[i]].time; } } if(idx == -1) break; res.push_back(total[idx][inds[idx]].id); inds[idx] --; count --; } return res; } /** Follower follows a followee. If the operation is invalid, it should be a no-op. */ void follow(int followerId, int followeeId) { if(followerId != followeeId) following[followerId].insert(followeeId); } /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ void unfollow(int followerId, int followeeId) { if(followerId != followeeId) following[followerId].erase(followeeId); } };

244. Shortest Word Distance II Design a class which receives a list of words in the constructor, and implements a method that takes two words word1 and word2 and return the shortest distance between these two words in the list. Your method will be called repeatedly many times with different parameters. Example: Assume that words = ["practice", "makes", "perfect", "coding", "makes"]. Input: word1 = "coding", word2 = "practice" Output: 3

we use map<string, set<int>> to store the ind. use lower_bound of set to find. class WordDistance { private: unordered_map<string, set<int> > indMap; public: WordDistance(vector<string>& words) { for(int i = 0; i < words.size(); i ++) indMap[words[i]].insert(i); } int shortest(string word1, string word2) { set<int> s1 = indMap[word1]; set<int> s2 = indMap[word2]; int res = INT_MAX; for(auto& ind: s1) { auto ite = s2.lower_bound(ind); int curr = INT_MAX; if(ite != s2.begin()) { --ite; curr = min(curr, abs(ind - *ite)); ++ite; } if(ite != s2.end()) { curr = min(curr, abs(ind - *ite)); } res = min(res, curr); } return res; } }; /** * Your WordDistance object will be instantiated and called as such: * WordDistance* obj = new WordDistance(words); * int param_1 = obj->shortest(word1,word2); */

288. Unique Word Abbreviation An abbreviation of a word follows the form <first letter><number><last letter>. Below are some examples of word abbreviations: c) i|nternationalizatio|n --> i18n d) l|ocalizatio|n --> l10n

we use map<string, set<string>> to store dict. class ValidWordAbbr { private: unordered_map<string, set<string>> strMap; public: ValidWordAbbr(vector<string>& dictionary) { for(auto& str: dictionary) { string abbr = str.length() <= 2? str: str[0] + to_string(str.length() - 2) + str.back(); strMap[abbr].insert(str); } } bool isUnique(string word) { string abbr = word.length() <= 2? word: word[0] + to_string(word.length() - 2) + word.back(); if(strMap.count(abbr) > 0 && (strMap[abbr].size() > 1 || *strMap[abbr].begin() != word)) return false; return true; } }; /** * Your ValidWordAbbr object will be instantiated and called as such: * ValidWordAbbr* obj = new ValidWordAbbr(dictionary); * bool param_1 = obj->isUnique(word); */

314. Binary Tree Vertical Order Traversal Given a binary tree, return the vertical order traversal of its nodes' values. (ie, from top to bottom, column by column). If two nodes are in the same row and column, the order should be from left to right. Examples 1: Input: [3,9,20,null,null,15,7] 3 /\ / \ 9 20 /\ / \ 15 7 Output: [ [9], [3,15], [20], [7] ]

we use queue to iterate the tree. use map<int, vector> to record the level and node info. class Solution { public: vector<vector<int>> verticalOrder(TreeNode* root) { map<int, vector<int> > levelMap; queue<pair<TreeNode*, int>> q; q.push(pair(root, 0)); while(! q.empty()) { pair<TreeNode*, int> curr = q.front(); q.pop(); TreeNode* node = curr.first; int pos = curr.second; if(node == NULL) continue; levelMap[pos].push_back(node->val); q.push(pair(node->left, pos-1)); q.push(pair(node->right, pos+1)); } vector<vector<int>> res; for(auto& [level, arr]: levelMap) res.push_back(arr); return res; } };

349. Intersection of Two Arrays Given two arrays, write a function to compute their intersection. Example 1: Input: nums1 = [1,2,2,1], nums2 = [2,2] Output: [2]

we use set. class Solution { public: vector<int> intersection(vector<int>& nums1, vector<int>& nums2) { unordered_set<int> set1(nums1.begin(), nums1.end()); unordered_set<int> set2(nums2.begin(), nums2.end()); vector<int> res; for(auto& num: set1) if(set2.find(num) != set2.end()) res.push_back(num); return res; } };

438. Find All Anagrams in a String Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100. The order of output does not matter. Example 1: Input: s: "cbaebabacd" p: "abc" Output: [0, 6]

we use sliding window. first get target count map. then get the map of first m len. then add new char and delete old char. class Solution { public: vector<int> findAnagrams(string s, string p) { int m = s.length(); int n = p.length(); if(m < n) return {}; unordered_map<char, int> tarMap = getMap(p); int total = tarMap.size(); int count = 0; vector<int> res; unordered_map<char, int> srcMap; for(int i = 0; i < n; i ++) { char ch = s[i]; srcMap[ch] ++; if(srcMap[ch] == tarMap[ch]) { count ++; if(count == total) res.push_back(0); } } for(int i = n; i < m; i ++) { char ch = s[i]; char prev = s[i-n]; srcMap[prev] --; if(srcMap[prev] == tarMap[prev] - 1) count --; srcMap[ch] ++; if(srcMap[ch] == tarMap[ch]) count ++; if(count == total) res.push_back(i - n + 1); } return res; } unordered_map<char, int> getMap(string s) { unordered_map<char, int> res; for(auto& ch: s) res[ch] ++; return res; } };

3. Longest Substring Without Repeating Characters Given a string, find the length of the longest substring without repeating characters. Example 1: Input: "abcabcbb" Output: 3

we use string ,and set to store current unique str. class Solution { public: int lengthOfLongestSubstring(string s) { set<char> chSet; int i = 0; int j = 0; int res = 0; for(; j < s.length(); j ++) { char ch = s[j]; while(chSet.find(ch) != chSet.end()) { chSet.erase(s[i++]); } chSet.insert(ch); res = max(res, j - i +1); } return res; } int lengthOfLongestSubstring1(string s) { //use string int res = 0; int len = s.length(); string str; for(int i = 0; i < len; i ++) { while(str.find(s[i]) != -1) { str.erase(str.begin()); } str += s[i]; res = max(res, int(str.length())); } return res; } };

37. Sudoku Solver Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy all of the following rules: Each of the digits 1-9 must occur exactly once in each row. Each of the digits 1-9 must occur exactly once in each column. Each of the the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid. Empty cells are indicated by the character '.'.

when there is empty ., we check the unused digit using bit operation and try to fill in the unused digit. class Solution { public: void solveSudoku(vector<vector<char>>& board) { if(board.empty()) return; solve(board); } bool solve(vector<vector<char>>& board) { for(int r = 0; r < 9; r ++) { for(int c = 0; c < 9; c ++) { if(board[r][c] == '.') { int inter = checkIntersect(board, r, c); for(int k = 0; k < 9; k ++) { if( ( (inter >> k) & 1) == 0 ) { board[r][c] = k + '1'; if(solve(board)) return true; board[r][c] = '.'; } } return false; } } } return true; } int checkIntersect(vector<vector<char>>& board, int r, int c) { int res = 0; int row = r / 3 * 3; int col = c / 3 * 3; for(int i = 0; i < 9; i ++) { res |= (board[r][i] == '.' ? 0 : (1 << (board[r][i] - '1')) ); res |= (board[i][c] == '.' ? 0: (1 << (board[i][c] - '1')) ); res |= (board[row][col] == '.' ? 0 : (1 << (board[row][col] - '1')) ); col ++; if(col % 3 == 0) { row ++; col = c / 3 * 3; } } return res; } };


Related study sets

Chapter 7 Accounting Systems Questions

View Set

Chapter 70: Management of Patients With Oncologic or Degenerative Neurologic Disorders

View Set