[Powered by Google Translate] [Séminaire: Interviews techniques] [Kenny Yu, Université de Harvard] [C'est CS50.] [CS50.TV] Salut tout le monde, je suis Kenny. Je suis actuellement étudiant en informatique juniors. Je suis un ancien CS TF, et je souhaite que j'aie eu ça quand j'étais un Underclassman, et c'est pourquoi je te donne ce séminaire. Donc, j'espère que ça vous plaira. Ce séminaire est d'environ entretiens techniques, et toutes mes ressources sont disponibles sur ce lien, ce lien, ici, quelques ressources. J'ai donc fait une liste de problèmes, en fait, pas mal de problèmes. Également une page générale des ressources où l'on peut trouver des conseils sur la façon de se préparer pour une entrevue, conseils sur ce qu'il faut faire lors d'une interview réelle, ainsi que la façon d'aborder les problèmes et les ressources pour référence future. Il est tout en ligne. Et juste de faire précéder ce séminaire, un avertissement, comme celui-ci ne devrait pas - votre préparation à l'entrevue ne devrait pas se limiter à cette liste. Ceci est uniquement destiné à être un guide, et vous devriez certainement prendre tout ce que je dis avec un grain de sel, mais aussi d'utiliser tout ce que j'ai utilisé pour vous aider dans votre préparation à l'entrevue. Je vais pour faire défiler les diapositives qui suivent, afin que nous puissions arriver à des études de cas réels. La structure d'une entrevue pour un postion génie logiciel, il s'agit généralement 30 à 45 minutes, plusieurs tours, en fonction de l'entreprise. Souvent, vous serez codage sur un tableau blanc. Ainsi, un tableau blanc comme ça, mais souvent sur une plus petite échelle. Si vous rencontrez un entretien téléphonique, vous serez probablement en utilisant soit collabedit ou d'un Google Doc afin qu'ils puissent voir que vous vivez de codage pendant que vous êtes interviewé par téléphone. Une entrevue elle-même est généralement de 2 ou 3 problèmes tester vos connaissances en informatique. Et il sera presque certainement impliquer de codage. Les types de questions que vous allez voir sont généralement des structures de données et algorithmes. Et en faisant ce genre de problèmes, ils vont vous demander, comme, quel est le temps et la complexité en espace, grand O? Souvent, ils demandent aussi de plus haut niveau des questions, ainsi, la conception d'un système, comment voulez-vous exposer votre code? Quelles interfaces, quelles sont les classes, les modules que vous avez dans votre système, et comment ceux-ci interagissent entre eux? Donc structures de données et algorithmes ainsi que des systèmes de conception. Quelques conseils généraux avant de nous plonger dans nos études de cas. Je pense que la règle la plus importante est toujours penser à haute voix. L'entretien est censé être votre chance de montrer votre processus de pensée. Le point de l'entrevue a pour l'interviewer afin d'évaluer la façon dont vous pensez et comment vous allez résoudre un problème. La pire chose que vous pouvez faire est d'être silencieux pendant toute l'entrevue. C'est juste pas bon. Lorsque vous êtes donné une question, vous aussi vous voulez vous assurer de comprendre la question. Donc répéter la question de retour dans vos propres mots et tenter de travailler approfondies quelques cas de tests simples pour vous assurer de bien comprendre la question. Par l'intermédiaire d'un cas de test peu vous donnera également une intuition sur la manière de résoudre ce problème. Vous pourriez même découvrir quelques modèles pour vous aider à résoudre le problème. Leur gros pourboire est de ne pas être frustré. Ne soyez pas frustrés. Les entretiens sont difficiles, mais la pire chose que vous pouvez faire, en plus d'être silencieux, doit être visiblement frustré. Vous ne voulez pas donner cette impression à un intervieweur. Une chose que vous - oui, beaucoup de gens, quand ils entrent dans une interview, ils tentent de trouver la meilleure solution d'abord, alors qu'en réalité, il ya habituellement une solution saute aux yeux. Il serait peut-être lent, il pourrait être inefficace, mais vous devriez juste le dire, seulement si vous avez un point de départ pour mieux travailler. En outre, en soulignant que la solution est lente, en termes de grande complexité en temps O ou complexité en espace, fera la démonstration à l'intervieweur que vous comprenez ces questions lors de l'écriture du code. Il ne faut donc pas avoir peur de venir avec le premier algorithme simple puis mieux travailler à partir de là. Toutes les questions jusqu'ici? Okay. Donc Débutons notre premier problème. «Étant donné un tableau de n entiers, écrire une fonction qui brouille le tableau en place de telle sorte que toutes les permutations des nombres entiers n sont équiprobables. " Et supposons que vous disposez d'un générateur de nombre aléatoire qui génère un nombre entier dans la plage de 0 à i, plage de moitié. Tout le monde comprend cette question? Je vous donne un tableau de n entiers, et je veux que vous le shuffle. Dans mon répertoire, j'ai écrit quelques programmes pour démontrer ce que je veux dire. Je vais mélanger un tableau de 20 éléments, -10 à 9, et je veux que vous sortir une liste de ce genre. Voilà donc mon tableau d'entrée triés, et je veux que vous le shuffle. Nous allons le faire à nouveau. Est-ce que tout le monde comprenne la question? Okay. Donc, c'est à vous. Quelles sont certaines des idées? Pouvez-vous faire en tant que n ^ 2, n log n, n? Ouverts à vos suggestions. Okay. Alors une idée, suggérée par Emmy, est d'abord calculer un nombre aléatoire, un nombre aléatoire, dans une plage de 0 à 20. Alors assumons notre tableau a une longueur de 20. Dans notre schéma de 20 éléments, c'est notre tableau d'entrée. Et maintenant, elle a suggéré de créer un nouveau tableau, ce sera donc le tableau de sortie. Et sur la base i retournée par rand - si j'étais, disons, 17 ans, copier l'élément septième à la première position. Maintenant, nous devons supprimer - nous avons besoin de changer tous les éléments ici au cours de telle sorte que nous avons un déficit à la fin et aucun trou dans le milieu. Et maintenant, nous répétons le processus. Maintenant, nous choisissons un entier nouveau aléatoire entre 0 et 19. Nous avons une nouvelle i ici, et nous copier cet élément dans cette position. Puis nous passons articles terminée et nous répéter le processus jusqu'à ce que nous avons notre nouvelle gamme complète. Quel est le moment de l'exécution de cet algorithme? Eh bien, nous allons examiner l'impact de cette. Nous passons chaque élément. Lorsque nous supprimer ce i, nous passons tous les éléments après sur la gauche. Et c'est une opération O (n) le coût parce que si on enlève le premier élément? Ainsi, pour chaque retrait, nous supprimons - chaque retrait subit une opération O (n), et puisque nous avons n déménagements, ce qui conduit à une opération O (n ^ 2) shuffle. Okay. Donc bon début. Bon début. Une autre suggestion est d'utiliser quelque chose de connu comme le shuffle Knuth, ou la lecture aléatoire de Fisher-Yates. Et c'est en fait un remaniement temps linéaire. Et l'idée est très similaire. Encore une fois, nous avons notre tableau d'entrée, mais au lieu d'utiliser deux tableaux pour notre entrée / sortie, nous utilisons la première partie du tableau de garder une trace de notre partie mélangées, et nous gardons la trace, puis on laisse le reste de notre gamme pour la partie unshuffled. Alors, voici ce que je veux dire. Nous commençons avec - on choisit un i, un tableau de 0 à 20. Notre actuelle du pointeur pointe vers le premier indice. Nous avons choisi quelques-uns ici i et maintenant nous échangeons. Donc, si cela était de 5, ce qui était de 4, le tableau résultant aura 5 et 4 ici là. Et maintenant, nous notons un marqueur ici. Tout à gauche est mélangé, et tout ce qui suit est unshuffled. Et maintenant, nous pouvons répéter le processus. Nous choisissons un indice aléatoire compris entre 1 et 20 maintenant. Supposons donc que notre nouveau i est ici. Maintenant, nous échangeons avec notre i cette nouvelle position courante ici. Donc, nous n'avons un échange dans les deux sens comme ça. Permettez-moi de faire apparaître le code pour le rendre plus concret. Nous commençons avec notre choix de i - nous commençons avec i égal à 0, on choisit un emplacement aléatoire j dans la partie de la matrice de unshuffled, i à n-1. Donc, si je suis ici, choisissez un indice aléatoire entre ici et le reste du tableau, et nous échangeons. C'est tout le code nécessaire pour mélanger votre tableau. Des questions? Eh bien, il fallait question est, pourquoi est-ce correct? Pourquoi toutes les permutations également probables? Et je ne vais pas passer par la preuve, mais de nombreux problèmes en informatique peut être prouvée par induction. Combien d'entre vous sont familiers avec l'induction? Okay. Cool. Ainsi, vous pouvez prouver la correction de cet algorithme par simple induction, où votre hypothèse d'induction serait, supposons que mon Shuffle retourne toutes les permutations aussi susceptibles aux éléments i premier. Maintenant, considérons i + 1. Et par la façon dont nous choisissons notre indice j pour échanger, ce qui conduit à - et puis vous travailler sur les détails, au moins une preuve complète de la raison pour laquelle cet algorithme retourne chaque permutation avec une probabilité équiprobables. Bon, problème suivant. Ainsi, «étant donné un tableau d'entiers, postive, nulle, négative écrire une fonction qui calcule la somme maximale de toute sous-matrice continueous du tableau d'entrée. " Un exemple est ici, dans le cas où tous les nombres sont positifs, alors le meilleur choix actuel est de prendre tout le tableau. 1, 2, 3, 4, est égal à 10. Lorsque vous avez des négatifs là-dedans, dans ce cas, nous voulons juste les deux premiers parce que le choix -1 et / ou -3 portera notre somme vers le bas. Parfois, nous pourrions avoir à commencer par le milieu du tableau. Parfois, nous voulons ne rien choisir du tout, il est préférable de ne pas prendre n'importe quoi. Et parfois, il est préférable de prendre l'automne, parce que la chose après il est super gros. Alors des idées? (Étudiant, inintelligible) >> Oui. Supposons que je ne prends pas -1. Puis-je choisir soit 1.000 et 20.000, ou je viens de choisir les 3 milliards. Eh bien, le meilleur choix est de prendre tous les numéros. Cette -1, en dépit d'être négatif, la somme totale est meilleure que si je n'étais pas à prendre -1. Ainsi, l'un des conseils que j'ai mentionnées plus tôt était à l'évidence clairement et la solution brute force première. Quelle est la solution la force brutale dans ce problème? Ouais? [Jane] Eh bien, je pense que la solution la force brute serait d'ajouter toutes les combinaisons possibles (inintelligible). [Yu] D'accord. Donc, l'idée de Jane est possible de prendre toutes - Je paraphrase - est de prendre tous les sous-réseaux possible, continue, calculer sa somme, puis prendre le maximum de tous les sous-réseaux possibles en continu. Que identifie de manière unique un sous-tableau dans mon tableau d'entrée? Comme, quelles sont les deux choses dont j'ai besoin? Ouais? (Étudiant, inintelligible) Droit >>. Une borne inférieure sur l'indice et l'indice limite supérieure détermine un sous-réseau unique continue. [Étudiante] Sommes-nous estimer, c'est un tableau de numéros uniques? [Yu] No. Donc sa question est, supposons-nous notre gamme - est notre tableau de tous les numéros uniques, et la réponse est non. Si nous utilisons notre solution de force brutale, alors les indices de début / fin détermine de façon unique notre sous-matrice continue. Donc, si nous itérer sur toutes les entrées de démarrage possibles, et pour toutes les entrées de gamme> ou = à démarrer, et > Zéro. Il suffit de ne pas prendre l'-5. Ici, il va y avoir 0 ainsi. Ouais? (Étudiant, inintelligible) [Yu] Oh, désolé, c'est un -3. Donc, c'est un 2, il s'agit d'un -3. Okay. Donc, -4, quel est le sous-tableau maximal de mettre fin à cette position où -4 est moins? Zéro. One? 1, 5, 8. Maintenant, je dois mettre fin à l'endroit où -2 est moins. De sorte 6, 5, 7, et le dernier est 4. Sachant que ce sont mes entrées pour le problème transformé où je dois terminer à chacun de ces indices, alors ma réponse finale est juste, prendre un balayent, et de prendre le nombre maximum. Donc, dans ce cas, il est 8. Cela implique que le sous-tableau maximale se termine à cet indice, et a commencé quelque part avant. Tout le monde comprend ce sous-tableau transformé? Okay. Eh bien, essayons de voir la récurrence pour cela. Considérons seulement les entrées des premières années. Donc, ici, il était de 0, 0, 0, 1, 5, 8. Et puis il ya eu un malus de -2 ici, et qu'elle ramené à 6. Donc, si je appeler l'entrée à la position i sous-problème (i), comment puis-je utiliser la réponse à un sous-problème précédent Pour répondre à cette sous-probl? Si je regarde, disons, cette entrée. Comment puis-je calculer la réponse 6 en consultant d' une combinaison de ce tableau et les réponses aux sous-problèmes précédents de ce tableau? Oui? [Étudiante] Vous prenez l'ensemble des sommes dans la bonne position avant, de sorte que le 8, et puis vous ajoutez le sous-problème courant. [Yu] Donc sa suggestion est de regarder ces deux nombres, ce nombre et ce nombre. Donc, ce 8 se réfère à la réponse pour le sous-problème (i - 1). Et nous allons appeler mon tableau d'entrée A. Afin de trouver un sous-tableau maximale qui se termine à la position i, J'ai deux choix: je peux soit continuer le sous-tableau qui a mis fin à l'indice précédent, ou de commencer un nouveau tableau. Si je devais continuer le sous-tableau qui a commencé à l'indice précédent, alors la somme maximum que je peux faire, c'est la réponse à la précédente sous-problème ainsi que l'entrée courante du tableau. Mais, j'ai aussi le choix de commencer une nouvelle sous-tableau, Dans ce cas, la somme est 0. Donc, la réponse est au maximum de 0, sous-problème i - 1, ainsi que l'entrée courante du tableau. Est-ce que cette récurrence du sens? Notre récurrence, comme nous venons de découvrir, sous-problème est i est égale à la valeur maximale de la sous-problème précédent, plus mon entrée de réseau en cours, ce qui signifie que le sous-tableau précédent continue, ou 0, démarrez une nouvelle sous-tableau à mon index en cours. Et une fois que nous avons construit cette table de solutions, alors notre réponse finale, il suffit de faire un balayage linéaire à travers le réseau sous-problème et de prendre le nombre maximum. Il s'agit d'une implémentation exacte de ce que je viens de dire. Nous avons donc créer un tableau sous-problème nouveau, sous-problèmes. La première entrée est soit 0, soit la première entrée, le maximum de ces deux là. Et pour le reste des sous-problèmes nous utilisons la récurrence exact que nous venons de découvrir. Maintenant, nous calculons le maximum de notre réseau sous-problèmes, et c'est notre réponse finale. Alors, combien d'espace nous aide dans cet algorithme? Si vous avez seulement pris CS50, alors vous pourriez ne pas avoir discuté de beaucoup d'espace. Eh bien, une chose à noter, c'est que j'ai appelé ici avec malloc taille n. Qu'est-ce que vous suggérer? Cet algorithme utilise un espace linéaire. Pouvons-nous faire mieux? Est-il quelque chose que vous remarquez ce qui est inutile pour calculer la réponse finale? Je suppose une meilleure question est, quelles sont les informations n'avons-nous pas besoin de transporter tout le chemin jusqu'à la fin? Maintenant, si nous regardons ces deux lignes, nous ne se soucient que le sous-problème précédent, et nous ne se soucient que le maximum que nous ayons jamais vu jusqu'ici. Pour calculer notre réponse définitive, nous n'avons pas besoin de l'ensemble du réseau. Nous avons seulement besoin du dernier numéro, les deux derniers chiffres. Dernier numéro de la matrice sous-problème, et le dernier numéro du maximum. Donc, en fait, nous pouvons fusionner ces boucles ensemble et à partir de l'espace linéaire à un espace constant. La somme des courants jusqu'à présent, ici, remplace le rôle du sous-problème, notre gamme sous-problème. Donc somme actuelle, jusqu'à présent, est la réponse à la sous-problème précédent. Et cette somme, jusqu'à présent, prend la place de notre max. Nous calculons le maximum que nous avançons. Et donc nous allons de l'espace linéaire à un espace constant, et nous avons aussi une solution à notre problème linéaire sous-tableau. Ces types de questions que vous obtiendrez lors d'une interview. Quelle est la complexité en temps, quelle est la complexité de l'espace? Pouvez-vous faire mieux? Y at-il des choses qui sont inutiles à garder autour? Je l'ai fait pour mettre en évidence les analyses que vous devez prendre sur votre propre que vous travaillez sur ces problèmes. Toujours vous demander, "Puis-je faire mieux?" En fait, nous pouvons faire mieux que cela? Une sorte de question piège. Vous ne pouvez pas, parce que vous devez au moins lire l'entrée du problème. Donc, le fait que vous avez besoin de lire au moins l'entrée au problème signifie que vous ne pouvez pas faire mieux que le temps linéaire, et vous ne pouvez pas faire mieux que l'espace constant. Il s'agit donc, en fait, la meilleure solution à ce problème. Des questions? Okay. Problème de bourse: «Étant donné un tableau de n entiers, positifs, nuls ou négatifs, qui représentent le prix d'une action sur n jours, écrire une fonction pour calculer le profit maximum que vous pouvez faire étant donné que vous achetez et vendez exactement 1 stock dans ces jours-ci n ". Essentiellement, nous voulons acheter bas, vendre haut. Et nous voulons trouver la meilleure profits que l'on peut faire. Pour en revenir à mon conseil, quel est le immédiatement claire, réponse la plus simple, mais il est lent? Oui? (Étudiant, inintelligible) >> Oui. >> Donc vous suffit d'aller bien et de regarder le prix des actions à chaque point dans le temps, (inintelligible). [Yu] Ok, donc sa solution - la suggestion de l'informatique le plus bas et le plus élevé calcul ne fonctionne pas nécessairement car le plus élevé pourrait se produire avant le plus bas. Alors, quelle est la solution la force brutale à ce problème? Quelles sont les deux choses que j'ai besoin de déterminer de façon unique le profit-je faire? Droite. La solution est la force brute - oh, oui, George suggestion est que nous besoin de deux jours déterminer de façon unique au profit de ces deux jours. Donc, nous calculons chaque paire, comme acheter / vendre, calculer le profit, ce qui pourrait être négatif ou positif ou nul. Calculer le maximum de profit que nous faisons après une itération sur toutes les paires de jours. Ce sera notre réponse finale. Et cette solution sera O (n ^ 2), car il est n choisir deux paires - de jours que vous pouvez choisir parmi les jours de la fin. Bon, je ne vais pas revenir sur la solution brute force ici. Je vais vous dire qu'il ya une solution log n n. Quel algorithme ne vous connaissons actuellement qui est n log n? Ce n'est pas une question piège. Le tri par fusion. Le tri par fusion est n log n, et, en fait, une façon de résoudre ce problème est d'utiliser une sorte de tri par fusion idée appelée, en général, diviser pour régner. Et l'idée est la suivante. Vous voulez connaître le meilleur achat / vente paire dans la moitié gauche. Trouvez le meilleur profit que vous pouvez faire, juste avec le premier n sur deux jours. Alors, vous voulez oompute le meilleur achat / vente paires sur la moitié droite, de sorte que le dernier n sur deux jours. Et maintenant, la question est, comment pouvons-nous fusionner ces solutions à nouveau ensemble? Oui? (Étudiant, inintelligible) Ok >>. Permettez-moi de faire un dessin. Oui? (George, inintelligible) >> Exactement. Solution de George est tout à fait exact. Donc sa suggestion est d'abord calculer le meilleur Achat / Vente paire, et qui se produit dans la moitié gauche, nous allons donc appeler cette gauche, à gauche. Meilleur achat / vente paire qui se produit dans la moitié droite. Mais si l'on ne compare ces deux chiffres, il nous manque le cas où nous achetons ici et vendent quelque part dans la moitié droite. Nous achetons dans la moitié gauche, vendre dans la moitié droite. Et la meilleure façon de calculer le meilleur Achat / Vente paire qui s'étend sur les deux moitiés consiste à calculer le minimum ici et calculer le maximum ici et de prendre leur différence. Donc les deux cas où la paire d'achat / vente a lieu seulement ici, seulement ici, ou sur les deux moitiés est définie par ces trois nombres. Ainsi, notre algorithme de fusionner nos solutions de retour ensemble, nous voulons calculer le meilleur Achat / Vente paire où nous achetons sur la moitié gauche et la vente sur la moitié droite. Et la meilleure façon de le faire est de calculer le prix le plus bas au cours du premier semestre, le prix le plus élevé dans la moitié droite, et prendre leur différence. Les trois résultantes des bénéfices, ces trois numéros, vous prenez le maximum des trois, et c'est le meilleur profit que vous pouvez faire au cours de ces premiers jours et à la fin. Voici les lignes importantes sont en rouge. Il s'agit d'un appel récursif pour calculer la réponse dans la moitié gauche. Il s'agit d'un appel récursif pour calculer la réponse dans la moitié droite. Ces deux boucles for calculer le min et le max sur la moitié gauche et à droite, respectivement. Maintenant, je calcule le profit qui s'étend sur les deux moitiés, et la réponse finale est le maximum de ces trois. Okay. Alors, bien sûr, nous avons un algorithme, mais la grande question est, quelle est la complexité de ce temps? Et la raison pour laquelle je l'ai mentionné tri par fusion est que cette forme de diviser la réponse en deux puis la fusion de nos solutions de retour ensemble C'est exactement la forme de tri par fusion. Alors laissez-moi passer par la durée. Si nous avons défini une fonction (n) t être le nombre d'étapes pour n jours, nos deux appels récursifs sont chacun coûterait t (n / 2), et il ya deux de ces appels. Maintenant, j'ai besoin de calculer le minimum de la moitié gauche, que je peux faire en n / 2 heure, plus le maximum de la moitié droite. Donc, ce n'est que de n. Et puis, plus un certain travail constant. Et cette équation de récurrence C'est exactement l'équation de récurrence pour le tri par fusion. Et nous savons tous ce genre de fusion est n log n fois. Par conséquent, notre algorithme est également n log n fois. Est-ce que cette itération du sens? Juste un bref rappel de celle-ci: T (n) est le nombre d'étapes pour calculer le maximum de profit au cours de n jours. La façon dont nous nous sommes séparés de nos appels récursifs est d'appeler notre solution sur les n jours / 2 premiers de sorte que c'est un appel, puis nous appelons à nouveau sur le second semestre. Donc, c'est deux appels. Et puis nous trouvons un minimum sur la moitié gauche, que l'on peut faire dans un temps linéaire, trouver le maximum de la moitié droite, que nous pouvons le faire en temps linéaire. Donc n / 2 + n / 2 est juste n. Ensuite, nous avons du travail constant, ce qui est comme faire de l'arithmétique. Cette équation de récurrence est exactement l'équation de récurrence pour le tri par fusion. Ainsi, notre algorithme shuffle est également n log n. Alors, combien d'espace utilisons-nous? Revenons au code. Une meilleure question est, combien de cadres de pile ne jamais nous avons à un moment donné? Comme nous utilisons la récursion, le nombre de frames de pile détermine notre utilisation de l'espace. Prenons n = 8. Nous appelons la lecture aléatoire 8, qui fera appel shuffle sur les quatre premières entrées, qui fera appel à un remaniement sur les deux premières entrées. Donc, notre pile est - c'est notre pile. Et puis mélangez à nouveau que nous appelons le 1, et c'est ce que notre scénario de base, donc nous retourner immédiatement. Avons-nous jamais plus que ce stack frames nombreux? Non, parce que chaque fois que nous faisons un appel, un appel récursif pour mélanger, nous divisons notre taille de moitié. Ainsi, le nombre maximum de trames de pile jamais nous avons à un moment donné est de l'ordre de log n trames de pile. Chaque cadre de pile possède un espace constant, et donc la quantité totale d'espace, le montant maximum de l'espace que nous ayons jamais utiliser est en O (log n) l'espace où n est le nombre de jours. Maintenant, demandez-vous toujours: «Peut-on faire mieux?" Et, en particulier, peut-on réduire à un problème que nous avons déjà résolu? Un conseil: nous avons seulement discuté de deux autres problèmes avant cela, et ça ne va pas être aléatoire. Nous pouvons convertir ce problème en bourse sur le problème sous-tableau maximale. Comment pouvons-nous faire cela? L'un de vous? Emmy? (Emmy, inintelligible) [Yu] Exactement. Donc, le problème sous-tableau maximale, nous sommes à la recherche d'une somme sur un sous-réseau continu. Et la suggestion d'Emmy pour le problème de stocks, examiner les modifications ou les deltas. Et une photo de ceci est - c'est le prix d'une action, mais si nous avons pris la différence entre chaque journée consécutive - Nous voyons donc que le prix maximum, le bénéfice maximum que nous pouvions faire est de savoir si nous achetons ici et vendre ici. Mais penchons-nous sur le continu - regardons le problème sous-tableau. Donc, ici, nous pouvons faire - aller d'ici à là, nous avons un changement positif, et ensuite aller d'ici à là, nous avons une variation négative. Mais alors, va d'ici à là, nous avons un énorme changement positif. Et ce sont les changements que nous voulons résumer pour obtenir notre résultat final. Ensuite, nous avons des changements les plus négatifs ici. La clé pour réduire notre problème de stock dans notre problème sous-tableau maximale est de considérer les deltas entre les jours. Nous allons donc créer un nouveau tableau appelé deltas, initialiser la première entrée à 0, puis pour chaque delta (i), que ce soit là la différence de mon tableau d'entrée (i), et le tableau (i - 1). Puis nous appelons notre procédure de routine pour un sous-réseau maximale passant dans le tableau d'un delta. Et parce que sous-tableau maximale est temps linéaire, et cette réduction, ce processus de création de ce réseau delta, est aussi temps linéaire, alors la solution finale pour les stocks est en O (n) de travail plus O (n) de travail, est toujours O (n) de travail. Nous avons donc une solution en temps linéaire à notre problème. Tout le monde comprend cette transformation? En général, une bonne idée de ce que vous devriez toujours avoir est d'essayer de réduire un nouveau problème que vous voyez. Si cela semble familier à un vieux problème, essayez de la réduire à un vieux problème. Et si vous pouvez utiliser tous les outils que vous avez utilisés sur le vieux problème pour résoudre le nouveau problème. Donc, pour conclure, des entretiens techniques sont difficiles. Ces problèmes sont probablement quelques-uns des problèmes les plus difficiles que vous pourriez voir dans une interview, donc si vous ne comprenez pas tous les problèmes que je viens de couverts, c'est bon. Ce sont quelques-uns des problèmes les plus difficiles. Pratique, pratique, pratique. J'ai donné beaucoup de problèmes dans le document, il faut absolument vérifier ceux dehors. Et bonne chance pour vos entretiens. Toutes mes ressources sont affichés sur ce lien, et un de mes amis hauts a offert de faire des entrevues simulées techniques, donc si vous êtes intéressé, e-mail Will Yao à cette adresse e-mail. Si vous avez des questions, vous pouvez me demander. Ne vous les gars avez des questions spécifiques liées aux techniques d'entrevues ou tout autre problème que nous avons vu jusqu'à présent? Okay. Eh bien, bonne chance pour vos entretiens. [CS50.TV]