LeetCode哈希表
1. Two Sum https://leetcode.com/problems/two-sum/description/
不使用额外空间需要n*n的复杂度
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { for(int i=0;i<nums.size()-1;i++){ for(int j=i+1;j<nums.size();j++){ if(nums[i] + nums[j] == target){ vector<int> result; result.push_back(i); result.push_back(j); return result; } } } return vector<int>(); } };
需要关注使用hash_table来实现的方法
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { unordered_map<int,int> m; vector<int> result; for(int i=0;i<nums.size();i++){ auto r = m.find(target-nums[i]); if(r != m.end()){ result.push_back((*r).second); result.push_back(i); return result; }else{ m[nums[i]] = i; } } return result; } };
3. Longest Substring Without Repeating Characters https://leetcode.com/problems/longest-substring-without-repeating-characters/description/
使用hash表来存放每一个字符之前出现过的最右位置,代码中用pos来保存不重复子串的开头,i向前遍历,如果发现i在之前出现过,并且出现的位置在pos之后,则将pos置位当前i之前出现的位置
class Solution { public: int lengthOfLongestSubstring(string s) { unordered_map<int,int> m; int pos = -1; int result = 0; for(int i=0;i<s.size();i++){ auto r = m.find(s[i]); if(r!=m.end() && (*r).second>pos) pos = (*r).second; m[s[i]] = i; result = max(result,i-pos); } return result; } };
双指针遍历,两个指针指向的元素相等,但是两指针之间的元素不重复,pos2-pos1表示长度
class Solution { public: int lengthOfLongestSubstring(string s) { int pos1 = -1; int result = 0; for(int i=0;i<s.size();i++){ for(int j=pos1+1;j<i;j++){ if(s[j] == s[i]) pos1 = j; } result = max(result,i-pos1); } return result; } };
36. Valid Sudoku https://leetcode.com/problems/valid-sudoku/description/
class Solution { public: bool isValidSudoku(vector<vector<char>>& board) { unordered_multimap<int, pair<int, int>> hash; if (board.size() == 0) return false; for (int i = 0; i<board.size(); i++) { for (int j = 0; j<board[0].size(); j++) { if (board[i][j] == '.') continue; auto range = hash.equal_range(board[i][j]); for (auto v = range.first; v != range.second; v++) { int currenti = (*v).second.first; int currentj = (*v).second.second; if (currenti == i || currentj == j || (currenti / 3 == i / 3 && currentj / 3 == j / 3)) return false; } hash.insert(pair<int, pair<int, int>>(board[i][j], pair<int, int>(i, j))); } } return true; } };
熟悉unordered_multimap的使用
49. Group Anagrams https://leetcode.com/problems/group-anagrams/description/
vector<vector<string>> groupAnagrams(vector<string>& strs) { map<string, vector<string>> m; for (int i = 0; i<strs.size(); i++) { string current = strs[i]; sort(current.begin(), current.end()); auto r = m.find(current); if (r != m.end()) { r->second.push_back(strs[i]); } else { vector<string> v; v.push_back(strs[i]); m[current] = v; } } vector<vector<string>> result; for (auto i = m.begin(); i != m.end(); i++) { result.push_back(i->second); } return result; }
使用map很容易实现,题目也没有要求空间复杂度
187. Repeated DNA Sequences https://leetcode.com/problems/repeated-dna-sequences/description/
class Solution { public: vector<string> findRepeatedDnaSequences(string s) { vector<string> result; map<string,int> temp; int pos = 0; while (pos+10 <= s.size()) { string s_temp = s.substr(pos++,10); temp[s_temp]++; if (temp[s_temp] == 2) result.emplace_back(s_temp); } return result; } };
这题使用string作为索引还是太复杂了,可以用两个位来表示一个核苷酸,则使用一个int就可以保存一个DNA序列,比较次数可以缩减很多
202. Happy Number https://leetcode.com/problems/happy-number/description/
class Solution { public: bool isHappy(int n) { set<int> s; s.insert(n); int next = 0; while (n != 1) { while (n>0) { int i = n % 10; n = n / 10; next = next + i*i; } if (s.find(next) != s.end()) return false; else s.insert(next); n = next; next = 0; } return true; } };
用hash来判断循环
204. Count Primes https://leetcode.com/problems/count-primes/description/
class Solution { public: bool is_prime(int n){ if(n<=1) return false; int sqr=sqrt(n); for(int i=2;i<=sqr;i++) if(n%i==0) return false; return true; } int countPrimes(int n) { int result = 0; for(int i=1;i<n;i++){ if(is_prime(i)) result++; } return result; } };
记住直接判断一个是不是质数的方法,不能平方,会溢出
class Solution { public: int countPrimes(int n) { bool* isPrime = new bool[n]; for(int i = 2; i < n; i++){ isPrime[i] = true; } for(int i = 2; i*i < n; i++){ if (!isPrime[i]) continue; for(int j = i * i; j < n; j += i){ isPrime[j] = false; } } int count = 0; for (int i = 2; i < n; i++) { if (isPrime[i]) count++; } return count; } };
205. Isomorphic Strings https://leetcode.com/problems/isomorphic-strings/description/
class Solution { public: bool isIsomorphic(string s, string t) { map<char,char> m1; map<char,char> m2; for(int i=0;i<s.size();i++){ if(m1.find(s[i])==m1.end()&&m2.find(t[i])==m2.end()){ m1[s[i]] = t[i]; m2[t[i]] = s[i]; }else{ if(m1[s[i]]!=t[i]||m2[t[i]]!=s[i]) return false; } } return true; } };
217. Contains Duplicate https://leetcode.com/problems/contains-duplicate/description/
class Solution { public: bool containsDuplicate(vector<int>& nums) { unordered_set<int> s; for(int i=0;i<nums.size();i++){ auto r = s.find(nums[i]); if(r != s.end()) return true; else s.insert(nums[i]); } return false; } };
219. Contains Duplicate II https://leetcode.com/problems/contains-duplicate-ii/description/
class Solution { public: bool containsNearbyDuplicate(vector<int>& nums, int k) { map<int,int> map; for(int i=0;i<nums.size();i++){ if(map[nums[i]] != 0 && (i-map[nums[i]]+1)<=k) return true; else map[nums[i]] = i+1; } return false; } };
242. Valid Anagram https://leetcode.com/problems/valid-anagram/description/
排序
class Solution { public: bool isAnagram(string s, string t) { sort(s.begin(),s.end()); sort(t.begin(),t.end()); return s==t; } };
hash
class Solution { public: bool isAnagram(string s, string t) { map<int,int> m; if(s.size()!=t.size()) return false; for(int i=0;i<s.size();i++){ m[s[i]]++; m[t[i]]--; } for(auto i=m.begin();i!=m.end();i++){ if(i->second != 0) return false; } return true; } };
274. H-Index https://leetcode.com/problems/h-index/description/
class Solution { public: int hIndex(vector<int>& citations) { if(citations.size()==0) return 0; vector<int> v(*max_element(citations.begin(),citations.end())+1,0); for(int i=0;i<citations.size();i++){ v[citations[i]]++; } int last = 0; for(int i=v.size()-1;i>=0;i--){ v[i] = v[i]+last; last = v[i]; if(v[i]>=i) return i; } return 0; } };
290. Word Pattern https://leetcode.com/problems/word-pattern/description/
bool wordPattern(string pattern, string str) { map<char, string> m1; map<string, char> m2; int firstpos = 0; int i = 0; for (; i<pattern.size() && firstpos<str.size(); i++) { int nextspace = firstpos; while (nextspace<str.size() && str[nextspace] != ' ') { nextspace++; } string currents = str.substr(firstpos, nextspace - firstpos); //判断 if (m1.find(pattern[i]) != m1.end() || m2.find(currents) != m2.end()) { if (m1[pattern[i]] != currents || m2[currents] != pattern[i]) return false; } else { m1[pattern[i]] = currents; m2[currents] = pattern[i]; } firstpos = nextspace + 1; } if (i >= pattern.size() && firstpos >= str.size()) return true; else return false; }
边界条件必须掌握好,长度必须一样,各个对于字符的对于关系处理方式参考205
299. Bulls and Cows https://leetcode.com/problems/bulls-and-cows/description/
string getHint(string secret, string guess) { int num1 = 0; int num2 = 0; map<char, int> m1; map<char, int> m2; for (int i = 0; i<min(secret.size(), guess.size()); i++) { if (secret[i] == guess[i]) num1++; else { m1[secret[i]]++; m2[guess[i]]++; if (m1[guess[i]]!=0) { m2[guess[i]]--; m1[guess[i]]--; num2++; } if (m2[secret[i]]!= 0) { m1[secret[i]]--; m2[secret[i]]--; num2++; } } } return to_string(num1) + "A" + to_string(num2) + "B"; }
347. Top K Frequent Elements https://leetcode.com/problems/top-k-frequent-elements/description/
class Solution { public: vector<int> topKFrequent(vector<int>& nums, int k) { unordered_map<int, int> m; for (int num : nums) ++m[num]; vector<vector<int>> buckets(nums.size() + 1); for (auto p : m) buckets[p.second].push_back(p.first); vector<int> ans; for (int i = buckets.size() - 1; i >= 0 && ans.size() < k; --i) { for (int num : buckets[i]) { ans.push_back(num); if (ans.size() == k) break; } } return ans; } };
用多种方法来实现,熟悉c++中各种容器的接口
349. Intersection of Two Arrays https://leetcode.com/problems/intersection-of-two-arrays/description/
class Solution { public: vector<int> intersection(vector<int>& nums1, vector<int>& nums2) { unordered_map<int,int> hash; for(int i=0;i<nums1.size();i++){ hash[nums1[i]]++; } vector<int> result; for(int i=0;i<nums2.size();i++){ if(hash[nums2[i]] != 0){ result.push_back(nums2[i]); hash[nums2[i]] = 0; } } return result; } };
350. Intersection of Two Arrays II https://leetcode.com/problems/intersection-of-two-arrays-ii/description/
class Solution { public: vector<int> intersect(vector<int>& nums1, vector<int>& nums2) { unordered_map<int,int> hash; for(int i=0;i<nums1.size();i++){ hash[nums1[i]]++; } vector<int> result; for(int i=0;i<nums2.size();i++){ if(hash[nums2[i]]!=0){ result.push_back(nums2[i]); hash[nums2[i]]--; } } return result; } };
355. Design Twitter https://leetcode.com/problems/design-twitter/description/
380. Insert Delete GetRandom O(1) https://leetcode.com/problems/insert-delete-getrandom-o1/description/
387. First Unique Character in a String https://leetcode.com/problems/first-unique-character-in-a-string/description/
优化,最后遍历char数组而不是s来找出不重复字符
389. Find the Difference https://leetcode.com/problems/find-the-difference/description/
class Solution { public: char findTheDifference(string s, string t) { unordered_map<char,int> hash; for(int i=0;i<t.size();i++){ hash[t[i]]++; } for(int i=0;i<s.size();i++){ hash[s[i]]--; } for(auto i=hash.begin();i!=hash.end();i++){ if(i->second == 1) return i->first; } return 'A'; } };
409. Longest Palindrome https://leetcode.com/problems/longest-palindrome/description/
class Solution { public: int longestPalindrome(string s) { int result = 0; unordered_map<char,int> hash; for(int i=0;i<s.size();i++){ if(hash[s[i]]==1){ hash[s[i]] = 0; result = result + 2; }else hash[s[i]]++; } if(s.size()>result) result++; return result; } };
438. Find All Anagrams in a String https://leetcode.com/problems/find-all-anagrams-in-a-string/description/
class Solution { public: vector<int> findAnagrams(string s, string p) { int n = s.length(); int l = p.length(); vector<int> ans; vector<int> vp(26, 0); vector<int> vs(26, 0); for (char c : p) ++vp[c - 'a']; for (int i = 0; i < n; ++i) { if (i >= l) --vs[s[i - l] - 'a']; ++vs[s[i] - 'a']; if (vs == vp) ans.push_back(i + 1 - l); } return ans; } };
447. Number of Boomerangs https://leetcode.com/problems/number-of-boomerangs/description/
class Solution { public: int numberOfBoomerangs(vector<pair<int, int>>& points) { int res = 0; // iterate over all the points for (int i = 0; i < points.size(); ++i) { unordered_map<long, int> group(points.size()); // iterate over all points other than points[i] for (int j = 0; j < points.size(); ++j) { if (j == i) continue; int dy = points[i].second - points[j].second; int dx = points[i].first - points[j].first; // compute squared euclidean distance from points[i] int key = dy * dy; key += dx * dx; // accumulate # of such "j"s that are "key" distance from "i" ++group[key]; } for (auto& p : group) { if (p.second > 1) { /* * for all the groups of points, * number of ways to select 2 from n = * nP2 = n!/(n - 2)! = n * (n - 1) */ res += p.second * (p.second - 1); } } } return res; } };
451. Sort Characters By Frequency https://leetcode.com/problems/sort-characters-by-frequency/description/
class Solution { public: string frequencySort(string s) { unordered_map<char,int> hash; for(int i=0;i<s.size();i++){ hash[s[i]]++; } sort(s.begin(),s.end(),[&hash](char& a, char& b){ if(hash[a]!=hash[b]) return hash[a]>hash[b]; else return a<b; }); return s; } };
string的排序比vector<char>的慢
454. 4Sum II https://leetcode.com/problems/4sum-ii/description/
class Solution { public: int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) { unordered_map<int, int> abSum; for(auto a : A) { for(auto b : B) { ++abSum[a+b]; } } int count = 0; for(auto c : C) { for(auto d : D) { auto it = abSum.find(0 - c - d); if(it != abSum.end()) { count += it->second; } } } return count; } };
463. Island Perimeter https://leetcode.com/problems/island-perimeter/description/
class Solution { public: int islandPerimeter(vector<vector<int>>& grid) { if(grid.size()==0) return 0; int result = 0; for(int i=0;i<grid.size();i++){ for(int j=0;j<grid[0].size();j++){ if(grid[i][j] == 1){ if(i-1<0 || grid[i-1][j]==0){ ++result; } if(j-1<0 || grid[i][j-1]==0){ ++result; } if(i+1==grid.size() || grid[i+1][j]==0){ ++result; } if(j+1==grid[0].size() || grid[i][j+1]==0){ ++result; } } } } return result; } };
500. Keyboard Row https://leetcode.com/problems/keyboard-row/description/
class Solution { public: vector<string> findWords(vector<string>& words) { vector<int> dict(26); vector<string> rows = {"QWERTYUIOP", "ASDFGHJKL", "ZXCVBNM"}; for (int i = 0; i < rows.size(); i++) { for (auto c : rows[i]) dict[c-'A'] = 1 << i; } vector<string> res; for (auto w : words) { int r = 7; for (char c : w) { r &= dict[toupper(c)-'A']; if (r == 0) break; } if (r) res.push_back(w); } return res; } };
复习题
1
3
36
204
205
290
347
355
380
387
438
447
451、提高效率