1.哈希表的用法:
https://blog.csdn.net/sevenjoin/article/details/81943864
2.相关题目:
2.1 leetcode 1 —— Two Sum
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int,int> m;
vector<int> res(2,-1);
for(int i = 0;i < nums.size();i++)
{
if(i > 0)
{
if(m.count(target - nums[i]) > 0)
{
res[0] = m[target - nums[i]];
res[1] = i;
break;
}
}
m[nums[i]] = i;
}
return res;
}
};
2.2 leetcode 3 —— Longest Substring Without Repeating Characters
class Solution {
public:
int lengthOfLongestSubstring(string s) {
map<char, int> ss;
int ans = 0,i = 0,j = 0,n = s.size();
map<char, int>::iterator iter;
for(;j < n;j++)
{
iter = ss.find(s[j]);
if(iter != ss.end()) //找到了,需要重新设置i
{
i = max(i ,iter->second + 1);
}
ans = max(ans,j - i + 1);
ss[s[j]] = j;
}
return ans;
}
};
2.3 leetcode 36 —— Valid Sudoku
用set做更简单~
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board) {
vector<set<int>> rows(9);
vector<set<int>> cols(9);
vector<set<int>> boxes(9);
for(int i = 0;i < 9;i++)
{
for(int j = 0;j < 9;j++)
{
if(board[i][j] == '.') continue;
if(rows[i].count(board[i][j] - '0') > 0) return false;
else
{
rows[i].insert(board[i][j] - '0');
}
if(cols[j].count(board[i][j] - '0') > 0) return false;
else
{
cols[j].insert(board[i][j] - '0');
}
int tmp = (i / 3) * 3 + j / 3;
if(boxes[tmp].count(board[i][j] - '0') > 0) return false;
else
{
boxes[tmp].insert(board[i][j] - '0');
}
}
}
return true;
}
};
2.4 leetcode 49 —— Group Anagrams
参考:https://leetcode-cn.com/problems/group-anagrams/solution/zi-mu-yi-wei-ci-fen-zu-by-leetcode/
方法1:
排序字符串并分类,时间复杂度O(NKlogK),空间复杂度O(NK)
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> res;
map<vector<char>, vector<string>> mmap;
for(string s : strs)
{
vector<char> tmp_c;
for(char c : s)
{
tmp_c.push_back(c);
}
sort(tmp_c.begin(),tmp_c.end());
mmap[tmp_c].push_back(s);
}
map<vector<char>, vector<string>>::iterator iter = mmap.begin();
for(;iter != mmap.end();++iter)
{
res.push_back(iter->second);
}
return res;
}
};
方法2:
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
map<string, vector<string>> mmap;
for(string s : strs)
{
vector<int> nums(26, 0);
for(char c : s)
{
nums[c - 'a']++;
}
string s_tmp;
for(int i : nums)
{
s_tmp += to_string(i) + "#";
}
mmap[s_tmp].push_back(s);
}
vector<vector<string>> res;
for(auto it : mmap)
{
res.push_back(it.second);
}
return res;
}
};
2.5 leetcode 76 —— Minimum Window Substring
参考链接(写的非常好!!!):https://leetcode-cn.com/problems/minimum-window-substring/solution/hua-dong-chuang-kou-suan-fa-tong-yong-si-xiang-by-/
用unordered_map会更快。
class Solution {
public:
string minWindow(string s, string t) {
unordered_map<char, int> windows;
unordered_map<char, int> needs;
for(char c : t) //记录t中每个字符的出现次数
{
needs[c]++;
}
int left = 0,right = 0,count = 0;
int start = 0,len = INT_MAX;
while(right < s.size())
{
char c = s[right];
if(needs.count(c))
{
windows[c]++;//记录窗口里有多少个这个字符
if(windows[c] == needs[c])
{
count++;
}
}
right++;
while(count == needs.size())
{
if(len > right - left)
{
start = left;//记录最优的开始位置
len = right - left;
}
char c1 = s[left];
if(windows.count(c1))
{
windows[c1]--;
if(windows[c1] < needs[c1])
count--;
}
left++;
}
}
if(len == INT_MAX) return "";
return s.substr(start,len);
}
};
2.6 leetcode 438 —— Find All Anagrams in a String
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> ans;
int left = 0,right = 0,count = 0;
unordered_map<char, int> windows;
unordered_map<char, int> needs;
for(char c : p)
{
needs[c]++;
}
while(right < s.size())
{
char c1 = s[right];
if(needs.count(c1))
{
windows[c1]++;
if(windows[c1] == needs[c1])
{
count++;
}
}
right++;
while(count == needs.size())
{
if((right - left) == p.size())
{
ans.push_back(left);
}
char c2 = s[left];
if(windows.count(c2))
{
windows[c2]--;
if(windows[c2] < needs[c2])
{
count--;
}
}
left++;
}
}
return ans;
}
};
2.7 leetcode 149 —— Max Points on a Line
参考:
class Solution {
public:
int gcd(int x,int y)
{
if(y == 0) return x;
return gcd(y, x % y);
}
int maxPoints(vector<vector<int>>& points) {
int N = points.size();
if(N < 3) return N;
int res = 0;
int dup = 0,dx = 0,dy = 0,tmp = 0;
map<pair<int,int>, int> line;
for(int i = 0;i < N - 1;i++)
{
line.clear();
dup = 1;
tmp = 0;
for(int j = i + 1;j < N;j++)
{
dx = points[j][0] - points[i][0];
dy = points[j][1] - points[i][1];
if(dx == 0 && dy == 0) dup++;
else
{
int g = gcd(dx,dy);
++line[{dx/g,dy/g}];
}
}
for(auto l : line)
{
if(tmp < l.second)
tmp = l.second;
}
if(tmp + dup > res) res = tmp + dup;
}
return res;
}
};
2.8 leetcode 166 —— Fraction to Recurring Decimal
class Solution {
public:
string fractionToDecimal(int numerator, int denominator) {
string res;
if(denominator == 0) return res;
if(numerator < 0 && denominator > 0 || numerator > 0 && denominator < 0)//处理结果是负数的情况
res += "-";
long num = static_cast<long>(numerator);
long denom = static_cast<long>(denominator);
num = abs(num);
denom = abs(denom);//求绝对值
res += to_string(num / denom);
num %= denom;
if(num != 0) res += ".";
int count = 0;//代表当前商对应的小数点后位数,从1开始加入res
unordered_map<long,int> mmap;
while(num != 0 && !mmap.count(num))//余数相等则出现循环小数
{
mmap[num] = count;
count++;
num *= 10;//新的除数
res += to_string(num / denom);
num %= denom;//新的余数
}
if(mmap.count(num))//如果新的余数和之前出现的相同
{
res += "()";
int cur = res.size()-2;// '(' 也为count位置
while(count-- > mmap[num])//如果最后一位小数位数不为重复余数对应的位数
{
swap(res[cur],res[cur - 1]);
cur--;
}
}
return res;
}
};
2.9 leetcode 136 —— Single Number
哈希表方法:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int res;
unordered_map<int,int> mmap;
for(int i = 0;i < nums.size();i++)
{
mmap[nums[i]]++;
}
for(auto p : mmap)
{
if(p.second == 1)
res = p.first;
}
return res;
}
};
异或方法:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int res = nums[0];
for(int i = 1;i < nums.size();i++)
{
res ^= nums[i];
}
return res;
}
};
2.10 leetcode 347 —— Top K Frequent Elements
class Solution {
typedef pair<int,int> IIpair;
struct cmp
{
bool operator()(const IIpair &a, const IIpair &b)
{
return a.second > b.second;//小顶堆
}
};
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
vector<int> res(k);
unordered_map<int,int> mmap;
priority_queue<IIpair,vector<IIpair>,cmp> q;
for(int i = 0;i < nums.size();i++)
{
mmap[nums[i]]++;
}
for(auto p : mmap)
{
if(q.size() < k)
{
q.push(p);
}
else if(p.second > q.top().second)
{
q.pop();
q.push(p);
}
}
for(int i = k - 1;i >= 0;i--)
{
res[i] = q.top().first;
q.pop();
}
return res;
}
};
2.11 leetcode 202 —— Happy Number
class Solution {
public:
bool isHappy(int n) {
set<int> sset;
while(n != 1)
{
int sum = 0;
while(n != 0)
{
sum += pow(n % 10, 2);
n /= 10;
}
n = sum;
if(sset.count(n)) return false;
sset.insert(n);
}
return true;
}
};
2.12 leetcode 204 —— Count Primes
厄拉多塞筛法:(虽然和hashmap没关系。。。)时间最快
bool类型实际上是int型
class Solution {
public:
int countPrimes(int n) {
if(n < 2) return 0;
vector<bool> tmp(n - 1,true);
tmp[0] = false;
int count = 0;
for(int i = 2;i <= n / 2;i++)
{
if(tmp[i - 1] == false) continue;
for(int k = i;k <= n / i;k++)
{
long p = i * k;
if(p < n)
{
tmp[p - 1] = false;
}
}
}
for(int i = 0;i < n - 1;i++)
{
if(tmp[i] == true) count++;
}
return count;
}
};
2.13 leetcode 217 —— Contains Duplicate
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
unordered_set<int> sset;
for(int i = 0;i < nums.size();i++)
{
if(sset.count(nums[i]) != 0) return true;
sset.insert(nums[i]);
}
return false;
}
};
2.14 leetcode 242 —— Valid Anagram
class Solution {
public:
bool isAnagram(string s, string t) {
if(s.size() != t.size()) return false;
map<char,int> mmap1;
map<char,int> mmap2;
for(int i = 0;i < s.size();i++)
{
mmap1[s[i]]++;
mmap2[t[i]]++;
}
auto iter1 = mmap1.begin();
auto iter2 = mmap2.begin();
while(iter1 != mmap1.end() && iter2 != mmap2.end())
{
if(iter1->first != iter2->first || iter1->second != iter2->second) return false;
++iter1,++iter2;
}
if(iter1 == mmap1.end() && iter2 == mmap2.end())
{
return true;
}
return false;
}
};
2.15 leetcode 350 —— Intersection of Two Arrays II
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
unordered_map<int, int> mmap;
int n1 = nums1.size();
int n2 = nums2.size();
vector<int> res;
if (n1 <= n2)
{
for (int i = 0; i < n2; i++)
{
mmap[nums2[i]]++;
}
for (int i = 0; i < n1; i++)
{
if (mmap[nums1[i]] > 0)
{
mmap[nums1[i]]--;
res.push_back(nums1[i]);
}
}
}
else
{
for (int i = 0; i < n1; i++)
{
mmap[nums1[i]]++;
}
for (int i = 0; i < n2; i++)
{
if (mmap[nums2[i]] > 0)
{
mmap[nums2[i]]--;
res.push_back(nums2[i]);
}
}
}
return res;
}
};
顺便附上349 Intersection of Two Arrays 的答案:
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_map<int, int> mmap;
int n1 = nums1.size();
int n2 = nums2.size();
vector<int> res;
if (n1 <= n2)
{
for (int i = 0; i < n2; i++)
{
mmap[nums2[i]]++;
}
for (int i = 0; i < n1; i++)
{
auto iter = mmap.find(nums1[i]);
if (iter != mmap.end())
{
res.push_back(nums1[i]);
mmap.erase(iter);
}
}
}
else
{
for (int i = 0; i < n1; i++)
{
mmap[nums1[i]]++;
}
for (int i = 0; i < n2; i++)
{
auto iter = mmap.find(nums2[i]);
if (iter != mmap.end())
{
res.push_back(nums2[i]);
mmap.erase(iter);
}
}
}
return res;
}
};
2.16 leetcode 387 —— First Unique Character in a String
class Solution {
public:
int firstUniqChar(string s) {
int res = -1;
unordered_map<char,int> mmap;
for(int i = 0;i < s.size();i++)
{
mmap[s[i]]++;
}
for(int i = 0;i < s.size();i++)
{
if(mmap[s[i]] == 1)
{
res = i;
break;
}
}
return res;
}
};