Skip to main content

3 způsoby, jak zlepšit vaše řešení kódování rozhovor - múza

CS50 2016 Week 0 at Yale (pre-release) (Červen 2025)

CS50 2016 Week 0 at Yale (pre-release) (Červen 2025)
Anonim

Takže jste. Ulevilo se. Vyčerpaný. Konečně jste přišli s přístupem k řešení složité kódovací otázky, kterou se vás tazatel ptá. Možná jste to dokonce napsali na tabuli, řádek po řádku. A udělali jste si dobrý čas! Jste jen 20 minut na schůzku. Váš tazatel musí být ohromen.

Že jo?

"Bude to fungovat, ale nějaké nápady, jak to udělat efektivněji?"

Vaše srdce klesá. Mysleli jste si, že jste dokončili složitou část návrhu algoritmu! Pokoušíte se vymyslet více způsobů, jak problém vyřešit, ale jediné, na co si vzpomenete, je ten přístup, s nímž jste již přišli.

Stává se to téměř každému. A není to proto, že jsou hloupí. Je to proto, že většina lidí nemá metodu pro zlepšení účinnosti svých algoritmů.

Pravda je, že jich je spousta. Až budete příští pařez, zkuste použít tyto tři společné přístupy.

1. Použijte Hash Map

To je správně. Hašovací mapy / asociativní pole / slovníky (mají mnoho jmen, podle toho, jaký programovací jazyk používáte) mají magickou schopnost snížit běh algoritmů.

Předpokládejme například, že v řadě čísel je třeba najít nejvíce opakované číslo.

Vaše první myšlenka by mohla být skočit do nějaké smyčky. U každého z našich čísel zjistěte jeho počet a zjistěte, zda je největší. Jak získáme počet pro každé číslo? Smyčka přes pole, počítat, kolikrát to nastane! Takže mluvíme o dvou vnořených smyčkách. V pseudokódu:

def get_mode (nums): max_count = 0 mode = null pro potenciální_mode v nums: count = 0 pro číslo v our_array: count + = 1 if count> = max_count: mode = potential_mode max_count = count return mode

Právě teď procházíme celé pole jednou pro každou položku v poli - ale můžeme dělat lépe. Ve velké O notaci to je celkem O (n 2 ) čas.

Pokud naše počty uložíme do hašovací mapy (mapování čísel na jejich počty), můžeme problém vyřešit pouze jednou procházkou maticovým (O (n) časem):

def get_mode (nums): max_count = 0 mode = null countts = new HashMap, počínaje každou hodnotou na 0 pro potenciální_mode v nums: počítá + = 1, pokud se počítá> max_count: mode = potenciální_mode max_count = počítá návratový režim

Mnohem rychlejší!

2. Použijte bitovou manipulaci

To vás opravdu odliší od smečky. Nevztahuje se na všechny problémy, ale pokud si to ponecháte v zadní kapse a vyhodíte to ve správný čas, vypadáte jako rocková hvězda.

Zde je příklad: Předpokládejme, že jsme měli řadu čísel, kde se každé číslo objevuje dvakrát, s výjimkou jednoho čísla, které se vyskytuje pouze jednou. Píšeme funkci, abychom našli osamělé, neopakované číslo.

Vaším prvním instinktem by mohlo být použití hašovací mapy, protože jsme o tom právě mluvili. To je dobrý instinkt! A bude to fungovat pro tento. Můžeme vytvořit velmi podobnou „počítací“ mapu a pomocí ní zjistit, které číslo končí číslem 1.

Ale existuje ještě lepší způsob. Pokud jste obeznámeni s bitovou manipulací, možná znáte XOR. Jedna věc, která je pro XOR zvláštní, je, že pokud XOR číslo s sebou, bity se „zruší“ na 0. Pro tento problém, pokud budeme XOR každé číslo v poli společně, zůstane nám jedno číslo, které nebylo zrušit:

def find_unrepeating (nums): unrepeating = 0 pro num in nums: unpeateat = unpeateat XOR num return nerepeat

3. Jděte zdola nahoru

Napiš funkci, která vydá „n-té“ Fibonacciho číslo a dostane n. Tohle je klasika a velmi dobře se hodí k rekurzi:

def fib (n): pokud n je 0 nebo 1: návrat 1 návrat fib (n-1) + fib (n-2)

Ale jednoduchá rekurzivní odpověď není jediná! Pečlivě přemýšlejte o tom, co tato funkce dělá. Předpokládejme, že n je 5. Pro získání odpovědi rekurzivně volá vlákno (4) a vlákno (3). Co to vlastně volá vlákno (4)? To volá vlákno (3) a vlákno (2). Ale právě jsme řekli, že už jsme zavolali na fib (3)! Tato roztomilá rekurzivní funkce provádí mnoho opakovaných prací. Celková časová cena je O (2 n ). To je špatné - mnohem horší než O (n 2 ).

Místo přechodu z n rekurzivně dolů na 1 jdeme „zdola nahoru“ z 1 na n. To nám umožňuje přeskočit rekurzi:

def fib (n): previous = 0 previous_previous = 1 pro i v rozsahu 1 až n: current = previous + previous_previous previous_previous = previous previous = aktuální návratný proud

Kód je delší, ale je mnohem efektivnější! Až do O (n) času. Jako bonus s rozvinováním rekurzivních algoritmů šetříme místo. Všechna tato rekurzivní volání se hromadí v zásobníku hovorů, který sedí v paměti a započítává se do našich vesmírných nákladů. Naše rekurzivní funkce měla náklady na prostor O (n), ale tato iterativní funkce zabírá prostor O (1).

Příště vás tazatel požádá o zlepšení efektivity vašeho řešení, zkuste tyto strategie projít a zjistit, zda pomáhají. Při dostatečném tréninku se pravděpodobně ocitnete přímo na optimalizovaném řešení a přeskočíte naivnější řešení. A to je skvělá věc. Neznamená to jen, že se stanete lepším tazatelem - to znamená, že se stanete lepším inženýrem.