Tehtävien deadline: ma-su yö 22.2. 1:59.
Tällä ja kaikilla muillakin viikoilla on algoritmien pystyttävä
tuottamaan oikea vastaus alle yhdessä sekunnissa, ellei erikseen muuta
mainita. Viikon aiheena on hajautus, ja erilaisten hajautusrakenteiden soveltaminen. Javassa löytyvät valmiit luokat HashMap
ja HashSet
. Huomaathan merkkijonohajautuksesta kertovan lisämateriaalin. Jos kiinnostaa, niin tässä kerrotaan miten voi generoida yhteentörmäyksiä tietyssä erikoistapauksessa.
Uolevi on äärettömässä ruudukossa ja lähtee
liikkeelle ruudusta (0, 0)
.
Hän kulkee joka askeleella yhden ruudun
vasemmalle, oikealle, ylöspäin tai alaspäin.
Milloin Uolevi palaa ruutuun, jossa hän on ollut aiemmin
(mihin tahansa matkan varrella olleeseen ruutuun)?
Toteuta seuraava metodi:
int reitinPituus(String reitti)
Parametri reitti
kuvaa Uolevin reitin.
Se sisältää järjestyksessä suunnat, joihin Uolevi liikkuu.
Jokainen suunta on yksi merkeistä V, O, Y ja A.
Merkkijonon pituus on 1..105
merkkiä.
Metodin tulee palauttaa, montako askelta Uolevi liikkuu,
ennen kuin hän palaa uudestaan samaan ruutuun.
Jos Uolevi ei palaa koskaan samaan ruutuun reitin aikana,
metodin tulee palauttaa 0
.
# | metodin kutsu | haluttu palautusarvo |
---|---|---|
1 | reitinPituus("YYVVAAOO") | 8 |
2 | reitinPituus("YVAOYVAO") | 4 |
3 | reitinPituus("YYYYYYYY") | 0 |
4 | reitinPituus("OYVVAOOO") | 6 |
Kannat mukanasi suurta reppua ja haluaisit pystyä selvittämään nopeasti, onko repussasi tiettyä esinettä. Lisäksi reppusi sisältö voi muuttua kun lisäät sinne tavaraa, tai kun otat sieltä jotain pois. Tehtävänäsi on toteuttaa kirjanpitosysteemi repun sisällölle.
Toteuta seuraavat metodit koodipohjan mukana tulevaan luokkaan Reppu
:
Reppu()
alustaa tyhjän repun, jossa ei ole mitäänvoid lisaa(int x)
lisää reppuun esineen x
void heitaPois(int x)
ottaa yhden repussasi olevan esineen x
, jos sellainen on olemassa ja heittää sen poisboolean sisaltaako(int x)
selvittää, onko repussasi esinettä x
Metodien saamat kokonaisluvut, jotka ovat välillä 0..109
, vastaavat aina jotain konkreettista asiaa, kuten vaikka kynää tai leipää. Jos lisäät reppuusi kaksi kertaa kynän, sisältää reppusi kaksi kynää, ja yhden kynän pois heittämisen jälkeen repussasi on vielä yksi kynä. Luokan metodeja kutsutaan korkeintaan 500000
kertaa.
Reppu r = new Reppu(); Nyt sisaltaako(1) pitäisi palauttaa 'false', sillä reppu on tyhjä. r.lisaa(1); Nyt sisaltaako(1) on 'true', mutta sisaltaako(2) on 'false'. r.heitaPois(1); Nyt sisaltaako(1) on jälleen 'false'. r.lisaa(1000); r.lisaa(1000); Nyt sisaltaako(1000) on 'true'. r.heitaPois(1000); sisaltaako(1000) on vieläkin 'true', ainoastaan toinen '1000' heitettiin pois.
Lue lisämateriaalista merkkijonohajautuksesta. Saat syötteenä kaksi merkkijonoa a
ja b
. Tehtävänäsi on selvittää "Rolling Hash" -hajautustekniikkaa käyttäen, onko merkkijono a
merkkijonon b
osajono (substring).
Toteuta seuraava metodi:
boolean onkoOsajono(String a, String b)
Merkkijonojen a
ja b
pituudet ovat välillä 1..200000
ja ne koostuvat merkeistä A..Z. Huomaathan, että potenssien laskeminen Math.pow käyttäen ei tule toimimaan tehtävässä. Liukulukujen laskutoimituksissa esiintyy suurilla luvuilla epätarkkuutta, jonka takia hajautusfunktiota ei saa laskettua oikein niitä käyttäen.
# | metodin kutsu | haluttu palautusarvo |
---|---|---|
1 | onkoOsajono("AB", "ACACACAB") | true |
2 | onkoOsajono("AA", "ABBA") | false |
3 | onkoOsajono("AAAA", "AAAA") | true |
4 | onkoOsajono("ABABAC", "ABABABAB") | false |
Sinulle on annettu DNA-ketju, joka muodostuu merkeistä A, C, G ja T. Tehtäväsi on selvittää, kuinka pitkä on lyhin DNA-ketju, joka ei ole annetun ketjun osajonona.
Esimerkiksi DNA-ketju ACGTACGT
sisältää osajonona kaikki 1:n pituiset
DNA-ketjut eli A, C, G ja T.
Kahden pituiset osajonot ovat järjestyksessä
AC, CG, GT, TA, AC, CG ja GT,
eli esimerkiksi ketju AA puuttuu osajonoista.
Niinpä lyhimmän ketjun pituus on 2
.
Toteuta seuraava metodi:
int lyhinPuuttuva(String mjono)
Merkkijono mjono
on
DNA-ketju, jonka pituus on 1..105
merkkiä.
Metodin tulee palauttaa lyhimmän ketjun pituus, joka ei ole osajonona annetussa ketjussa.
# | metodin kutsu | haluttu palautusarvo |
---|---|---|
1 | lyhinPuuttuva("CCCCCCCC") | 1 |
2 | lyhinPuuttuva("ACGTACGT") | 2 |
3 | lyhinPuuttuva("ACAAGCAG") | 1 |
4 | lyhinPuuttuva("ACACACGT") | 2 |
Sinulle on annettu DNA-ketju, joka muodostuu merkeistä A, C, G ja T. Tehtäväsi on selvittää, kuinka pitkä on pisin DNA-ketju, joka esiintyy annetussa ketjussa vähintään kahdesti osajonona.
Esimerkiksi DNA-ketjun ACGTACGT tapauksessa, pisin tällainen DNA-ketju on ACGT, joten
vastaus tässä tapauksessa olisi 4
. Toisaalta merkkijonon AAAA tapauksessa, pisin kelpaava jono on AAA, joten vastaus olisi 3
.
Toteuta seuraava metodi:
int pisinToisto(String mjono)
Merkkijono mjono
on
DNA-ketju, jonka pituus on 1..200000
merkkiä. Tehtävän aikaraja on poikkeuksellisesti 2 sekuntia.
Vihje: binäärihausta saattaa olla apua.
# | metodin kutsu | haluttu palautusarvo |
---|---|---|
1 | pisinToisto("ACGTACGT") | 4 |
2 | pisinToisto("AAAA") | 3 |
3 | pisinToisto("ACACCACCCACCCC") | 6 |
4 | pisinToisto("ACG") | 0 |