Directorio de artículos
-
- Guía de preguntas
- para resumir(***)
- Método común de tabla hash: contar el número de ocurrencias
- [242. Dislexia de letras válidas] (https://leetcode-cn.com/problems/valid-anagram/)
- [349. La intersección de dos matrices] (https://leetcode-cn.com/problems/intersection-of-two-arrays/)
- [202. Número feliz] (https://leetcode-cn.com/problems/happy-number/)
- [1. La suma de dos números] (https://leetcode-cn.com/problems/two-sum/)
- [454. Suma de cuatro números II] (https://leetcode-cn.com/problems/4sum-ii/)
- [383. Nota de rescate] (https://leetcode-cn.com/problems/ransom-note/)
- [15. La suma de tres números (clasificación + doble puntero)] (https://leetcode-cn.com/problems/3sum/)
- [18. La suma de cuatro números (clasificación + puntero doble, la suma de los mismos tres números)] (https://leetcode-cn.com/problems/4sum/)
Guía de preguntas
para resumir(***)
1. Reducir la complejidad del tiempo en el ciclo: ordenar + puntero doble, tabla hash
2. Cuando hay varias variables, como a [i] + a [j] == 0, puede corregir j, es decir, encontrar 0 ~ Si existe el número -a [j] en j-1, puede calcular mientras calcula
3. Tabla hash: ¡cuente el número de ocurrencias!
4. Punteros dobles: se pueden considerar los punteros dobles cuando se satisface la monotonicidad
Método común de tabla hash: contar el número de ocurrencias
El hash también sacrifica espacio a cambio de tiempo
242.
Análisis:
use una tabla hash para contar la cantidad de veces que aparece cada carácter y la complejidad del tiempo O(n)
. La primera vez que lo hice, se ordenó directamente, lo cual era complejo en el tiempo O(nlogn)
.
Por supuesto, el rango de mapeo de esta pregunta es relativamente pequeño y puede usar una matriz como tabla hash. Si la gama de problemas avanzados es grande, no se deben utilizar matrices.
"Y si el valor hash es relativamente pequeño, particularmente disperso, y el intervalo es muy grande, el uso de matrices provocará una gran pérdida de espacio".
class Solution {
public:
bool isAnagram(string s, string t) {
// 时间复杂度O(n)
// 空间复杂度O(26)
if(s.size() != t.size()) return false;
unordered_map<char,int> cnt; // 哈希表
for(auto c : s) cnt[c] ++;
for(auto c : t){
cnt[c] -- ;
}
for(auto x : cnt){
if(x.second != 0) return false;
}
return true;
}
};
349. Intersección de dos arreglos
Solución 1: Utiliceunordered_set
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
// 时间复杂度O(n)
unordered_set<int> num, res;
for(auto c : nums1) num.insert(c); // 把nums1的元素插到unordered_set中
for(auto c : nums2)
if(num.count(c)) res.insert(c);
vector<int> ans(res.begin(), res.end()); // 赋值
return ans;
}
};
Solución 2: Utiliceunordered_map
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
// 哈希表
unordered_map<int,int> hash;
for(auto c : nums1) hash[c] ++ ;
vector<int> res;
for(auto c : nums2)
{
if(hash[c] > 0 ) res.push_back(c), hash[c] = 0 ;
}
return res;
}
};
202.
Análisis: El
título dice "bucle infinito", lo que significa "en el proceso de suma sum会重复出现
, ¡esto es muy importante para resolver el problema!"
class Solution {
public:
bool isHappy(int n) {
unordered_map<int,int> cnt;
while(n != 1)
{
cnt[n] ++;
dfs(n); // 引用改变n的值
if(cnt[n] > 1) return false; // 只要出现次数大于1,说明循环了
}
return true;
}
void dfs(int &n)
{
int res = 0;
while(n > 0){
int t = n % 10;
res += t * t;
n /= 10;
}
n = res;
}
};
1. la suma de dos números
Análisis:
las estadísticas de una sola vez no son muy buenas, es mejor insertar mientras se busca
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> hash;
// 边求边插入
for(int i = 0;i < nums.size();i ++ ){
if(hash.count(target - nums[i])) return {
hash[target - nums[i]], i};
hash[nums[i]] = i;
}
return {
-1, -1};
}
};
454. Suma de cuatro números II
Análisis: Se
observa N = 500
que como máximo se pueden enlazar dos matrices. ¡Métodos de manipulación habituales!
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
unordered_map<int,int> hash; // 统计 a + b的值出现的次数
for(int i = 0;i < A.size();i ++ )
for(int j = 0;j < B.size();j ++)
hash[A[i] + B[j]] ++;
int res = 0;
for(int i = 0;i < C.size();i ++ )
for(int j = 0;j < D.size();j ++)
{
int s = C[i] + D[j];
if(hash.count(0 - s)) res += hash[0 - s]; // 这里的处理类似 两数之和
}
return res;
}
};
383.
class Solution {
public:
bool canConstruct(string r, string m) {
// 哈希计数
unordered_map<char,int> cnt;
for(auto c : m) cnt[c] ++;
for(auto c : r){
cnt[c] -- ;
if(cnt[c] < 0) return false; // 字符不够了
}
return true;
}
};
15. La suma de tres números (ordenar + doble puntero)
Análisis: la
tabla hash de clasificación + doble puntero debe deduplicarse y es demasiado difícil de escribir, use sort + puntero doble en su lugar, la complejidad del evento es O (n ^ 2)
para encontrar a [i] + a [l] + a [r ] == 0, puede enumerar a [i]. Debido a la clasificación anterior, debe satisfacerse la monotonicidad. A medida que i se mueve, lyr se moverán monótonamente, por lo que se pueden usar punteros dobles.
去重的常用操作
: ¡La dificultad de esta pregunta también es eliminar la duplicación!
while(l < r && nums[l] == nums[l - 1]) l ++ ;
while(l < r && nums[r] == nums[r + 1]) r -- ;
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
int n = nums.size();
if(n < 3) return res;
sort(nums.begin(), nums.end());
// a[i] + a[l] + a[r] == 0 , 固定a[i]
for(int i = 0;i < n;i ++ )
{
if(nums[i] > 0) return res; // 直接返回了
if(i != 0 && nums[i] == nums[i - 1]) continue; // 去重!关键!
int l = i + 1, r = n - 1;
while(l < r)
{
if(nums[l] + nums[i] + nums[r] == 0) {
res.push_back({
nums[i], nums[l], nums[r]});
l ++ , r -- ;
// 去重的常见操作
while(l < r && nums[l] == nums[l - 1]) l ++ ;
while(l < r && nums[r] == nums[r + 1]) r -- ;
}else if(nums[l] + nums[i] + nums[r] < 0){
l ++ ;
}else{
r -- ;
}
}
}
return res;
}
};
18. La suma de cuatro números (clasificación + doble puntero, lo mismo que la suma de tres números)
Análisis: complejidad temporal O ( n 3 n ^ {3}norte3 ), ¡más problemático que la adición de cuatro números II en el proceso de deduplicación!
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> res;
int n = nums.size();
sort(nums.begin(), nums.end());
for(int i = 0;i < n ; i++ )
for(int j = i + 1;j < n ;j ++ )
{
// 去重
if(i != 0 && nums[i] == nums[i - 1]) break;
if(j != i + 1 && nums[j] == nums[j - 1]) continue; // 这里是continue
int l = j + 1,r = n - 1;
while(l < r)
{
if(nums[i] + nums[j] + nums[l] + nums[r] == target){
res.push_back({
nums[i], nums[j], nums[l], nums[r]});
l ++ ,r -- ;
while(l < r && nums[l] == nums[l - 1]) l ++ ;
while(l < r && nums[r] == nums[r + 1]) r --;
}else if(nums[i] + nums[j] + nums[l] + nums[r] < target) l ++ ;
else r -- ;
}
}
return res;
}
};