Så der er du. Lettet. Utslitt. Du har endelig kommet med en tilnærming for å løse det vanskelige kodingsspørsmålet intervjueren stiller deg. Kanskje du til og med skrev det opp på tavlen, linje for linje. Og du hadde god tid! Du er bare 20 minutter inn i møtet. Din intervjuer må bli imponert.
Ikke sant?
"Dette vil fungere, men noen ideer for hvordan du kan gjøre det mer effektivt?"
Hjertet ditt synker. Du trodde du var ferdig med den lure algoritmdesigndelen! Du prøver å tenke på flere måter å løse problemet på, men alt du kan tenke på er den tilnærmingen du allerede har funnet opp.
Dette skjer med nesten alle. Og det er ikke fordi de er dumme. Det er fordi de fleste ikke har en metode for å forbedre effektiviteten til algoritmene sine.
Men sannheten er at det er nok. Neste gang du er stumpet, kan du prøve å bruke disse tre vanlige tilnærmingene.
1. Bruk et Hash-kart
Det er riktig. Hash-kart / assosiative matriser / ordbøker (de går under mange navn, avhengig av hvilket programmeringsspråk du bruker) har en magisk evne til å få ned kjøretiden for algoritmer.
Anta for eksempel at spørsmålet var å finne det mest gjentatte tallet i en rekke tall.
Din første tanke kan være å hoppe inn i noen løkker. For hvert av våre tall, finn ut antallet og se om det er det største. Hvordan får vi uttellingen for hvert tall? Loop gjennom matrisen, og tell hvor mange ganger det oppstår! Så vi snakker om to nestede løkker. I pseudokode:
def get_mode (nums): max_count = 0 mode = null for potential_mode in nums: count = 0 for number in our_array: count + = 1 if count> = max_count: mode = potential_mode max_count = count return mode
Akkurat nå går vi gjennom hele matrisen en gang for hvert element i matrisen - men vi kan gjøre det bedre. I stor O-notasjon er det O (n 2 ) tid totalt.
Hvis vi lagrer tellingene våre på et hasjkart (kartlegger tallene til antallene deres), kan vi løse problemet på bare en spasertur gjennom matrisen (O (n) tid!):
def get_mode (nums): max_count = 0 mode = null count = new HashMap, start hver verdi på 0 for potential_mode i nums: count + = 1 if count> max_count: mode = potential_mode max_count = counts return mode
Mye raskere!
2. Bruk bitmanipulering
Dette skiller deg virkelig fra pakken. Det gjelder ikke alle problemer, men hvis du holder dette i lommen og pusler ut det til rett tid, vil du se ut som en rockestjerne.
Her er et eksempel: Anta at vi hadde en rekke tall, der hvert nummer vises to ganger, bortsett fra ett tall som bare forekommer en gang. Vi skriver en funksjon for å finne det ensomme, ikke-gjentatte tallet.
Det første instinktet ditt kan være å bruke et hasjkart, siden vi bare snakket om det. Det er et godt instinkt å ha! Og det vil fungere for denne. Vi kan lage et veldig likt "teller" -kart, og bruke det for å se hvilket nummer som ender med en telling på 1.
Men det er en enda bedre måte. Hvis du er kjent med bitmanipulering, er du kanskje kjent med XOR. En ting som er spesielt med XOR, er at hvis du XOR et nummer med seg selv, vil bitene "kansellere ut" til 0. For dette problemet, hvis vi XOR hvert nummer i rekken sammen, vil vi sitte igjen med det ene tallet som ikke gjorde avbryter ikke:
def find_unrepeated (nums): unrepeated = 0 for num in nums: unrepeated = unrepeated XOR num return unrepeated
3. Gå fra bunnen
Skriv en funksjon som gir ut det "n" Fibonacci-tallet, gitt et nummer n. Dette er en klassiker, og den egner seg veldig fint til rekursjon:
def fib (n): hvis n er 0 eller 1: return 1 return fib (n-1) + fib (n-2)
Men det enkle rekursive svaret er ikke det eneste! Tenk nøye gjennom hva denne funksjonen gjør. Anta at n er 5. For å få svaret kaller det rekursivt fib (4) og fib (3). Hva gjør den kallen til fib (4)? Det kaller fib (3) og fib (2). Men vi sa bare at vi allerede hadde en oppfordring til fib (3)! Denne søte rekursive funksjonen gjør mye repetisjonsarbeid. Den totale tidskostnaden viser seg å være O (2 n ). Det er ille - langt verre enn O (n 2 ).
I stedet for å gå fra n rekursivt ned til 1, la oss gå "nedenfra og opp", fra 1 til n. Dette lar oss hoppe over rekursjonen:
def fib (n): forrige = 0 forrige_forut = 1 for i i området 1 til n: nåværende = forrige + forrige_forutgående forrige_forut = = forrige forrige = nåværende returstrøm
Koden er lengre, men den er mye mer effektiv! Ned til O (n) tid. Som en ekstra bonus med å rulle rekursive algoritmer, sparer vi plass. Alle disse rekursive samtalene bygger seg opp i samtalebunken, som sitter i minnet og teller mot romprisen. Den rekursive funksjonen vår hadde en O (n) plasskostnad, men denne iterative tar O (1) plass.
Neste gang intervjueren ber deg om å forbedre effektiviteten til løsningen din, kan du prøve å gå gjennom disse strategiene og se om de hjelper. Med nok trening vil du sannsynligvis finne deg selv å hoppe rett til den optimaliserte løsningen, og hoppe over den mer naive løsningen. Og det er en flott ting. Det betyr ikke bare at du blir en bedre intervjuer - det betyr at du blir en bedre ingeniør.




