Table des matières
sous-tableau avec une longueur minimale
Chaîne minimale sans répétition de longueur
Avant-propos :
Au début de cet article, nous présenterons le sujet de l'algorithme de type fenêtre glissante. La fenêtre glissante est en fait un double pointeur par nature. Cependant, les doubles pointeurs introduits précédemment se déplacent les uns vers les autres :
Les fenêtres coulissantes se déplacent dans le même sens :
Cet article présente l'utilisation de base des fenêtres coulissantes à travers 2 sujets. Les sujets introduits sont :
209. Sous-tableau avec longueur minimale - LeetCode
3. La sous-chaîne la plus longue sans caractères répétés - LeetCode
Il est introduit en trois étapes. La première étape est l'analyse du problème, la deuxième étape est le principe de l'algorithme et la troisième étape est l'écriture de l'algorithme. De même, nous vérifierons s'il existe une solution violente dans la partie analyse du problème. , passons à la première étape.
sous-tableau avec une longueur minimale
Analyse des questions
L'exigence de la question est de trouver un intervalle continu tel que la somme des valeurs de l'intervalle soit supérieure ou égale à la cible. S'il existe un intervalle de ce type, la valeur de retour doit être la longueur minimale de. ces intervalles. S'il n'existe pas de sous-tableau, 0 doit être renvoyé.
Ensuite, il y a deux exemples. Alors pouvons-nous résoudre ce problème par la violence ? Bien sûr, c'est possible.
Il nous suffit de trouver tous les intervalles qui remplissent cette condition et de déterminer leur longueur. Cependant, la complexité temporelle est définitivement O(N^2), et cela expirera sur cette question, donc je suis intéressé. les leurs.
Alors pourquoi cette question peut-elle utiliser une fenêtre coulissante à première vue ?
Parce qu'il faut un espace continu , en règle générale, lorsqu'on rencontre un problème qui nécessite un espace continu, autant se pencher vers la fenêtre coulissante.
Passons maintenant à la partie principe de l’algorithme.
Principe de l'algorithme
L'essence de la fenêtre glissante est que deux pointeurs se déplacent dans la même direction. Grâce au mouvement de ces deux pointeurs, nous déterminons si la somme des intervalles est satisfaite et, si c'est le cas, comparons les longueurs.
Et si vous utilisiez une fenêtre coulissante ?
Les points de départ des deux pointeurs doivent être les mêmes au début. Si les positions des deux pointeurs ne sont pas les mêmes, nous devrons ajouter une boucle supplémentaire pour trouver spécifiquement la somme de cet intervalle, alors maintenant :
int left = 0, right = 0;
C'est sûr, alors pour les fenêtres coulissantes, nous pouvons retenir deux noms, l'un est la fenêtre d'entrée et l'autre est la fenêtre de sortie. Quand entrer dans la fenêtre et quelle est la fenêtre de sortie sont ce qui préoccupe notre sujet.
Entrer dans la fenêtre signifie que la somme des intervalles est <cible, donc plus de nombres doivent être impliqués. C'est pourquoi nous n'avons pas besoin de trier. La question elle-même nécessite des entiers positifs, nous devons donc simplement nous assurer que le nombre est le même. le plus grand possible.
Hors de la fenêtre signifie que la somme des intervalles > cible, sortez simplement de la fenêtre et jugez la longueur minimale qui existe à l'intérieur.
Le principe de base est le suivant : vous pouvez résoudre le problème avec succès en entrant et en sortant.
Écriture d'algorithmes
class Solution
{
public:
int minSubArrayLen(int target, vector<int>& nums)
{
int ans = INT_MAX, left = 0, right = 0 ,sum = 0;
for(;right < nums.size();right++)
{
sum += nums[right];
while(sum >= target)
{
ans = min(ans,right - left + 1);//如果ans为0 那么这一步永远都是0
sum -= nums[left++];
}
}
return ans == INT_MAX ? 0 : ans;
}
};
Mais le point dégoûtant de cette question est que si la longueur initiale n'est pas définie comme un très grand nombre, lors du jugement et de la comparaison, le plus petit nombre ne peut pas être obtenu via min, nous devrions donc définir ans comme INT_MAX, tant que c'est un grand numéro, ça va.
À ce stade, l’analyse du sujet est terminée.
Chaîne minimale sans répétition de longueur
Analyse des questions
La question est très courte. La condition de réussite est de renvoyer la longueur de la chaîne la plus longue sans caractères répétés. Ainsi, pour les caractères, les exigences données dans la question sont :
Donc, pour déterminer s'il y a des doublons, nous avons besoin d'une méthode pour déterminer s'il existe une sorte de mappage. Nous pourrions aussi bien utiliser une carte de hachage ici et utiliser un tableau pour imiter une table de hachage. autant déterminer s’il y a de la violence dans la solution de la question.
Cela doit exister. Nous utilisons deux boucles for. La deuxième boucle trouve le dernier élément et détermine si la valeur de mappage est supérieure à 1. Si elle est supérieure à 1, elle peut être renvoyée directement. La complexité temporelle est définitivement O(N^2), ce qui est passable.
Mais puisque la nature de cette question est un intervalle, autant utiliser une fenêtre glissante pour y répondre.
Principe de l'algorithme
La fenêtre glissante de la question précédente est le sous-tableau avec la plus petite longueur. La condition de jugement est supérieure ou égale à >= cible. La condition de jugement de cette question est de savoir si la carte de hachage est supérieure à 1. Par conséquent, une conclusion est tirée. : Il y a trois questions utilisant des fenêtres coulissantes. La première étape consiste à entrer dans la fenêtre, la deuxième à juger et la troisième à sortir de la fenêtre .
Les questions suivantes utilisent toutes cette procédure de manière très rigide.
Ensuite, notre méthode de jugement consiste également à utiliser le mappage de hachage. Si le mappage de jugement est supérieur à 1, il sera généré une fois la sortie terminée, l'ans correspondant sera enregistré, ou si le mappage répond aux conditions, l'ans correspondant. seront également enregistrées.
Enfin, revenez simplement ans.
Écriture d'algorithmes
class Solution
{
public:
int lengthOfLongestSubstring(string s)
{
int hash[256] = { 0 }, ans = 0;
for(int left = 0, right = 0;right < s.size();right++)
{
hash[s[right]]++;
while(hash[s[right]] > 1)
{
hash[s[left++]]--;
}
ans = max(ans,right - left + 1);
}
return ans;
}
};
Le début de la fenêtre coulissante est terminé~
Merci d'avoir lu!