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>();
    }
};
View Code

需要关注使用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;
    }
};
View Code

 

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;
    }
};
View Code

双指针遍历,两个指针指向的元素相等,但是两指针之间的元素不重复,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;
    }
};
View Code

 

 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;
    }
};
View Code

熟悉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;
}
View Code

使用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;
    }
};
View Code

这题使用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;
    }
};
View Code

用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;
    }
};
View Code

记住直接判断一个是不是质数的方法,不能平方,会溢出

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;
    }
};
View Code

 

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;
    }
};
View Code

 

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;
    }
};
View Code

 

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;
    }
};
View Code

 

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;
    }
};
View Code

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;
    }
};
View Code

 

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;
    }
};
View Code

 

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;
}
View Code

边界条件必须掌握好,长度必须一样,各个对于字符的对于关系处理方式参考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";
}
View Code

 

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;
    }
};
View Code

用多种方法来实现,熟悉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;
    }
};
View Code

 

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;
    }
};
View Code

 

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';
    }
};
View Code

 

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;
    }
};
View Code

 

 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;
  }
};
View Code

 

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;
    }
};
View Code

 

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;
    }
};
View Code

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;
    }
};
View Code

 

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;
    }
};
View Code

 

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;
    }
};
View Code

 

 

复习题

1

3

36

204

205

290

347

355

380

387

438

447

451、提高效率

posted @ 2018-09-03 12:34  番茄汁汁  阅读(599)  评论(0编辑  收藏  举报