diff --git a/README.md b/README.md index 139172aa..eb0d9e98 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,20 @@ -# solution algorithm problems +# Contest Kotlin + ![Kotlin](https://img.shields.io/badge/kotlin-%237F52FF.svg?style=for-the-badge&logo=kotlin&logoColor=white) ![Android Studio](https://img.shields.io/badge/Android%20Studio-3DDC84.svg?style=for-the-badge&logo=android-studio&logoColor=white) -## Task +# Description + +This repository contains problems of leetcode. We might use this repo how get solution for define +problem from leetcode. Also We might clone this repo and run or debug problems in android studio. + +# How to use + +1. Each problem will be in contest module +2. Each problem have a few solutions. Main solution with using down level code. Alternative Solution + with other approaches. Prod Variant - this code might be in prod in application or service. This + code using std lib kotlin +3. For search each problem have kotlin doc with name and number problem. Also each problem have tag + for commit for search in github. +4. Each Topic have package which contains problem -- [leetcode task](app/src/main/java/com/leetcode_kotlin/AlgorithmLeetcode.kt) -- [codeWars task](app/src/main/java/com/leetcode_kotlin/AlgorithmCodeWars.kt) diff --git a/app/src/main/java/com/leetcode_kotlin/AlgorithmLeetcode.kt b/app/src/main/java/com/leetcode_kotlin/AlgorithmLeetcode.kt index 3127f6ed..c75263b5 100644 --- a/app/src/main/java/com/leetcode_kotlin/AlgorithmLeetcode.kt +++ b/app/src/main/java/com/leetcode_kotlin/AlgorithmLeetcode.kt @@ -578,36 +578,6 @@ fun findDuplicates(nums: IntArray): List { return ans } -/** - * 73. Set Matrix Zeroes - */ - - -fun setZeroes(matrix: Array) { - val m = matrix.size - val n = matrix[0].size - - val forRows = BooleanArray(m) - val forCols = BooleanArray(n) - - for (i in 0 until m) { - for (j in 0 until n) { - if (matrix[i][j] == 0) { - forRows[i] = true - forCols[j] = true - } - } - } - - - for (i in 0 until m) { - for (j in 0 until n) { - if (forRows[i] || forCols[j]) { - matrix[i][j] = 0 - } - } - } -} /** * 48. Rotate Image diff --git a/app/src/main/java/com/leetcode_kotlin/AlgorithmProdVariant.kt b/app/src/main/java/com/leetcode_kotlin/AlgorithmProdVariant.kt index bbcc784f..19d759e8 100644 --- a/app/src/main/java/com/leetcode_kotlin/AlgorithmProdVariant.kt +++ b/app/src/main/java/com/leetcode_kotlin/AlgorithmProdVariant.kt @@ -580,43 +580,6 @@ fun heightProdVariant(root: TreeNode?): Int = when { else -> 1 + maxOf(heightProdVariant(root?.left), heightProdVariant(root?.right)) } -/** - * 73. Set Matrix Zeroes - * Prod Variant - */ - -fun setZeroesProdVariant(matrix: Array) { - val m = matrix.size - val n = matrix[0].size - var firstRowZero = false - var firstColZero = false - - - matrix.forEachIndexed { i, row -> - row.forEachIndexed { j, value -> - if (value == 0) { - if (i == 0) firstRowZero = true - if (j == 0) firstColZero = true - matrix[i][0] = 0 - matrix[0][j] = 0 - } - } - } - - - for (i in 1 until m) { - for (j in 1 until n) { - if (matrix[i][0] == 0 || matrix[0][j] == 0) { - matrix[i][j] = 0 - } - } - } - - - if (firstRowZero) matrix[0].fill(0) - if (firstColZero) for (i in 0 until m) matrix[i][0] = 0 -} - /** * 287. Find the Duplicate Number * Prod Variant diff --git a/app/src/main/java/com/leetcode_kotlin/AlternativeAlgorithmSolution.kt b/app/src/main/java/com/leetcode_kotlin/AlternativeAlgorithmSolution.kt index 4d312dad..120ff712 100644 --- a/app/src/main/java/com/leetcode_kotlin/AlternativeAlgorithmSolution.kt +++ b/app/src/main/java/com/leetcode_kotlin/AlternativeAlgorithmSolution.kt @@ -926,51 +926,6 @@ fun canBreak(start: Int, s: String, trie: TrieWordBreak): Boolean { return false } -/** - * 73. Set Matrix Zeroes - * Alternative Solution - */ - -fun setZeroesAltSolution(matrix: Array) { - val m = matrix.size - val n = matrix[0].size - var firstRowZero = false - var firstColZero = false - - - for (i in 0 until m) { - for (j in 0 until n) { - if (matrix[i][j] == 0) { - if (i == 0) firstRowZero = true - if (j == 0) firstColZero = true - matrix[i][0] = 0 - matrix[0][j] = 0 - } - } - } - - - for (i in 1 until m) { - for (j in 1 until n) { - if (matrix[i][0] == 0 || matrix[0][j] == 0) { - matrix[i][j] = 0 - } - } - } - - - if (firstRowZero) { - for (j in 0 until n) { - matrix[0][j] = 0 - } - } - if (firstColZero) { - for (i in 0 until m) { - matrix[i][0] = 0 - } - } -} - /** * 230. Kth Smallest Element in a BST * Alt Solution diff --git a/contest/src/main/java/com/github/contest/CustomEXT.kt b/contest/src/main/java/com/github/contest/CustomEXT.kt index decd3699..396f67b8 100644 --- a/contest/src/main/java/com/github/contest/CustomEXT.kt +++ b/contest/src/main/java/com/github/contest/CustomEXT.kt @@ -1,17 +1,17 @@ package com.github.contest -fun MutableMap.removeIfEmptyBucket(key: Int) { - this[key] = this.getOrDefault(key, 0) - 1 + +fun MutableMap.removeIfEmptyBucket(key: K) { if (this[key] == 0) this.remove(key) } - -fun Any.printData(label: String) { - println("$label $this") +fun MutableMap.reduceCount(key: K) { + this[key] = this.getOrDefault(key, 0) - 1 + removeIfEmptyBucket(key) } -inline fun abs(number: Int): Int = when { +fun abs(number: Int): Int = when { number < 0 -> number * -1 else -> number } \ No newline at end of file diff --git a/contest/src/main/java/com/github/contest/Execute.kt b/contest/src/main/java/com/github/contest/Execute.kt index ac3e9cd8..b943336c 100644 --- a/contest/src/main/java/com/github/contest/Execute.kt +++ b/contest/src/main/java/com/github/contest/Execute.kt @@ -2,6 +2,8 @@ package com.github.contest import com.github.contest.math.numberOfPowerfulInt +import com.github.contest.slidingWindow.customStructure.rabinKarpMultiPattern +import com.github.contest.slidingWindow.customStructure.slidingWindowClassic import com.github.contest.strings.fullJustify import com.github.contest.strings.subStrHash import java.util.TreeMap @@ -13,6 +15,59 @@ import java.util.TreeMap fun main() { + val list = mutableListOf(-1) + println(list) +} + +infix fun Int.myRange(to: Int): IntRange { + return this..to +} + + +fun launchPerformance() { + + val text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit".repeat(10) + val new = "banana".repeat(5000) + val patterns = listOf( + "Lorem", "ipsum", "dolor", "sit", "amet", + "consectetur", "adipiscing", "elit", "xyz", "abc" + ) + + measureTime("Rabin - Karp Algorithm") { + rabinKarpMultiPattern(text, patterns) + } + + measureTime("Sliding Window Algorithm") { + slidingWindowClassic(text, patterns) + } + + +} + +private fun measureTime(message: String, block: () -> Unit) { + val start = System.currentTimeMillis() + block() + val end = System.currentTimeMillis() + println("$message Time - ${end - start} ms") +} + + +fun longestDupSubStringTest() { + + val test = + "vbaemlrfvasubbuxdqohlpkuuznigzebcegorztmbngdocautqbegnbamqitrowtucjldexfsgiiiicbyeigrjjgbtbsiznccwohanmutudceffflnlfywnbqotypictesbhgndbkgfooltzahgbdtctjytzgwsnotwwhzyrifhwqbxtkewnxyjhycgfaauruqpbrnuztbxlevgobccydnhbppisqelmuapoqjnlmnyrkfflhjlkwvookwgcbtoxtdnlobwbqvsaazljjywftktgibiluzlqeybtbawrxqtzpeiyfggysbebdpozozpuatpbvlvsbortvbtaizaabfbgushkrxgtswvnhqflgyebzzdhzeicllkhdrrxqxqivnxdfeqmcupctvluztykhirmcklsjcdfrckxhallwcprxboywmidxbqbnbtzfygzbqyksjvqnljloxjkmuolxgmljhmrgsqjkovezqwmdfxrfjctfsecaspjzbahvqsfgnlfghsjnrduchnhzrkzlbkkdnuyfogmcrrkzltofyihfvpgobhzcslffhgkwowafqkgdduieeqjbhqpixqkrcswlajhohhvxrcdxylbfdmgkeyueohvsbuebdlrkvmkmonlpaougbashynlpujhvdnyizpuwdgiuvwjwkfenfwvgjixfrgcwuaevrbrvhbpdxabkffxmduundrswyxtszznrceomffpfhspmzoycltrqmmmkjhcijrblvrxdyokfibrjrsmcndszrhkaqolzgmndgkiebuklvdvnvhrkmmkgvuglkrlqgaummesnzczwiujfddqrraxmwgxgzkxfkttxzmkyqlvyhggmlwecwdoujoajyzqjukiuyuuogrppavcntiqrnglzunkvnagjmofmicbqtsgvpkjiubzhhmiezszovfahvfudjxufrcaiolqimrrufaaguzvpgxxbetgosctlgvtuhletcwpjyppsqmiyjhbocicukxhrsanzlsvpqkyocniucqtlzubbefxpceixexwpprgheevgueawwvhwqjzuqxltdvqitozkigsmmpugvwcssmqkxpgnouispyckpbvxjplwehcadhuxtmjqbsdqmmkdmmqdpnazcnxiubkaiezbqlrudxmrjwwximbzzbydrxmlzwnhdnjtycpdzbukxsihfjjgmhmdfyrgwgnztyvtdkwcmspllxvsgeaunmaumrajzqivofotqnwehlrskomsunmkzmemfhxfxfannqhfdfllsefctsuphgzgvguanrfmzhzmyitdneqfiwjdqdtzmufhachntpzuwbgwjbazfqgqoqtgtofhjnojpwzknafldnippkowcwmtmiziwhphuetlcsxruecyumnlwdhbzwuoevwccnkytdlxxjorptrjfeuehcfhabvewtizguzczlzwwqqljhxqmruvvbcvczbbsmcbgbfgoeemwuyfexwqosnmwqjyrnbmzdpffunvasixmieqfcivvwhrotrhgvtfyimfcabfsjcgtgxyjhvgffztysbenwlmhxtjxuopfswybvykeuskztdzlgdbfonmngxldocigajhxhtcdnmegrdsagvfwirkqqxvebelcpubwqdcdpgmjkgjsbqpjjbbzaxebdrfsnhqdksjcbvlnbwfcmwnxxqwxpcbstgmjndmaxxcaspnvntzzpmypfuouxrpsybblgqlgnpgiewdtpdsgrsxynovmfkefnirwyecnukvaibuzeoixhfywvtiddmiqwbmugqicddcleylkptkwaiswbcbgqjynlnhtfrvixzwdyhonaalckfalhbtxnrkagutmlowipsmnzccbepeouebdiubvnnvwjqiveefvxtlyxnabfgpzmqdwmgrcvoyfegckmhgldrkagmelutnimsfyyyctnaaticgvkmipfuplgtzcpmlbeqbeoezdgaxpcdmmrudwrtjxoicdwngadketqexwewnizbxsyaqptzokkqpgdwhginaytzwzvmiwnfolfeabfplpfawlydristimsflprtleazsgfshljucrwycvdvfwrokltvbmrmsrokzvfgiqalhzjlwnhblapvlksmyjbrdpdcmklvbngkmrwiefkrfbmqoffmqgfvxlyjvjgyymllghtkofevjqnxxslqarlzejlzuratglemuzyihcfqvspslaintunxfyzapzvxmbjgaiqjmvbhpqactkqmgdmmdloumlsamdionyyavzhksjnlwdzcilqnyghmrzmdfussussrrccjlrwjwwoehetilauecjkhfczcuutnwvzjmvtirhobnhjakffmqpvwtwypqrcmpdwdzrosycvlmgoymtmckhaddaswswijagmbxatxfpltvzrjudoemohppznjxwsxegaehudmlofipyujbinnywepxsavqsuwzvaireweudombixeslrtjxihrjehdyeetgommkqjpfvqpsuifnbrnlyewcoccuiycxkpjbyzivrxpohvbkmqwmxuqlwshfqjedyngymotenjsvgvfuodilyyywqfbjofmpvsnhijnvufscdayrdgcdeaawhdhxltmgncnvndtjkllnllerriuxkwvtadrnydtmhijulcdwoolbzsssaprnlngnsxaqdvekeqfrsinizzkarevttmihzpwrozkruqcagjszthjsitvbaqxtcfcewzxlajeuaixgrrhlarfjmammsjivrkbnlyalihikphqjyywyrbjdewqwhytykuowvqjfxtppahaahwzyzkcdgscqsvocseapxmuwfllisniajjajucocwqsoojtgnvvmhrjpcwxwkhyvrzgnbvpaniqbtjjihevqxefbaeymoyihxoubljbztrcodmxmsscqwktyqrnesvlplhsxtvyopadumaghskxquqqnkdreafvmmolhjjwylzuazahtlgjhybukfoohvktjygrjpnkbmednhkgsqrbosyzzopjjzcszjllaaxdobgbkqjeiagzvgawupfdrkxqvjdvlabaehboaltknbjihjhbbmgswdkroopaoqauzdjboeoehxoojvpmkvegaoaperrvjrpkwamlgcrnzfbkbswlpctstvjxmauxtkipmwctytizzmkcgipwnkqgizfwzausmcjaymvwheviqhkwsbufoknwlssksmegqohqccojgmsytexnirswehspamcubibryiiamwmvketekqtskooqvihvvjswutpsdztryfmilgmvyiokwcarnkpivhgpcvihvdytklbvrqsrygcwlenyqeimlodpjnweqvzagbxztqsrywnlbcjthtfuhjktwgxpdzrjarkvjdmhzbtcfewmydjhmtalbacfztqbmbwvgkdhlykseghejqmylmlmmptnkkoxnmstwxajvmccujggbsgmhtaviujsgzptmiokfqudfyfzjnfkgnwpgwkosvjyvytjihtqaptfnaewnmivzekgdxwxsfwnepyozsebhzgxzmtnackaivinselmmjcsyagzslackgzmvubvylxhifwcmhpyqrqrrwsmjtqwbriwljukurtdzrhlzwjrpbkjzdvjwnfzenyrysdslwxkofvpdgitjtcjwzsumztsotjmlpexnejdlfsondjxwlgumaoabjspdebqvhpilzmygenvjysfkazycpzdbtsgztwubmdonpnvvcqfajmmlolodmrgfmmhfjbixgxmxkhtmxamiobucmkiydofpdmvoqdnwczumipyfpnqfokicwsczihplwmzmrmiunegvthdkwtqmfaobsqcczroxfpjxeuttybpskucgnussuivoaxrarhzwwlvcfqwfslxcfcluydotmljmiaobhoagzxigoelirlmypxsndiiptsdcuufekfkldurtbcbupntennsqwchrukvrgbvqghbldseexhzovutijnahphzmrudyvyqefspimwpldqaaktkvikdxrcjlymlwkbartrcinrttjttvoeqwovuixftyseuehuydnaldtewcarxovplmlhukmpietclayjfmjqpexnixehlcwyojfkuszeyuhlwfuctfuijrvtocacexauiigcafhabqmzxidroybzpxtgztifskzbsffumovpejoeruvhswhjvcpwxzbskcvcjazvrwmxhdbyxwirvraqtsnqrqidtdieghaxfowmrykowufrlikeazxtphzknhpvqruvfqhxotnlovczdogfnfadozpbggwwxstfjaexutkiopjtdrarwbwlalojunhtfbyobeoxyyhmnririikfjgsmtgvntehbfhpjmdgmeoyrhikpruwcaqqwxnjssstzcliqqrcufcoolydcvcgxsxtrkfkexfezqmrjdtdkwryhselnitmaqgsdlehkjnkccblhxqutksacynrggdjxldcwhlhsbtwdwhktyemizomzbfikkrjwuludydxzwucvbpobtdlutzuvgcfrvqprblubptblnfgruxuqagmvhgqokxhhnyyqjuuyovmbcsuxrpptxbpekhuwhdewbcplzjjpevsiqnfjcwdzaufkbcgifkfjpuuqfffjdxrvmzeoxjpxdxhfzqpgcwptqljvrqgwoarabvrahiykfhpgxhpcdevwshtlxchlcyofvffcnfpvngbmnsqrzmnrtgcqkjemjstezzjmgyjtgniufynemavfizytichtubavcjhijtepgollmyqzangjneexgnrcqrxuchfncjcizqtlolmpbtaozenitemkxmebvjoxutftjyhxmtmnoodqsqyoxkywycytomqifvcowjokeaxvpaljsjxpvxoucmpqygaebcuznijulipckandlnugkicousevafbdjvdzgottxivhikmtxjbkrgyoyfjykmbvhgupvniuxfdfqqapzczsiagifrirdlmnsjepwnjwsmbkeeadizysbgagaixftmsnvxctmlpeatrexrkfsixuqzaqhawcmqshpuabiqiijzmisynkikezjhrshpwvgocxleztujbfkpncocmwotxzaptjeqemgikrmlkjulqedggriupxpnwrcqaiigxoqhidssoogeujmcavwrumesdiigrsoojfxrirlyhrebardcmbugnaytjjzcdnsmupfeircpihslavpmwlummuhxfgzjvtxskdwsuzjeibriyhwwusiimpfsxgdvzcnjflbbkmgunxengakbssjhkrbjxeexitgofkrrwxomxszfvjgnesuqjxzgbgdkzmagwraurogqiivdterxwnphlpnovtawhcffufznviddqyhjcajanyhapxpksrjzuoeqvfdqngvfgcpjeajuatusqlckdnjzdppyuuqiamngqervgdpjwlboxfyctjdwysxuopcobswuyqrhtgqrtrhswhurqzqqtpkhepvgjuchktofbgyuxfnwmjpejhuewgmbxjjgdlqpgguhnsdmzsklccrnjnriufjrpuashsknyeunzzcysokwsdjercmlixezrgtyydnzijohisfajrwdxhhomvzwsfvlmolmsylchclqwssfkpjjyqxkmyigdfsrudeoerqlvbdstwxfnionbnanlivpopiktmazgqkbtqtootwbbmqcaqrlzncpclbxzbwhtjlmbecpzysbnidnzxaamdrqqsorvmboxmcasepsfjtssyhtxhvjmoaegqydezrcntcfzuxedsyxrfsoppaddailqioujfywadbazzgethekowbdmdjrdtdvbrrkzsgzvhbwiiacreofdrlruuiznluofmyeggfdphzyrbciisplkaceukehyaxdovjudoxtxwtqavyinqtzqxglhksfmqkbntvtkvmhtfytcybrowrhtzsdjmixevysowlarzikgigkihbzgugztacemncriclyywzrxjcdtkndrqczlkzgkdnxqpqatbzuzalwlpzezohtemsrytylxlkpcaqxbrrardycsxiunrnrffjebjpywznabdxcwpenucrobbiotvhadseebvezwrzxxzztqfjkhcykgjabgibjagpedvdanfxmexhuesemxeydnzeuhffjnxntstthyqvcpdwuxciuigxyfdsolzyayntrgmaefwiubeqyiytrhspmwjdjkdjjqdcxrcdwamrbshabivupnldlwguglercjvbaaexasoclxeofzkumxyytgubsyvwhqxiqdhtwvvjszzaalumiumbdjevhzrrsqbktidrfaczbdzbowqwsezvngsxflozbrkxbpqgqvhryhtnfjlzplvdrpaybqyejkbkzusrpzjnieapnmpczkhqzhqczqhiciscckvrmehuijkxvzcwljomtfpsvwbygtclgxeselomvamsbormxfbqksliqmiwhmjplojpbyeyyqtcekqdprwcjhmzvuycihstxbjbbnbcduejgumwmkaxrmzmgzroijhgmsjohksmhwvnqkleulemxdafcrtkcdsrxdffqzrxvnmnzyutjyhhdimhbitenovkrcrjbjgyyvnxthsehalkkatlknrxdmjwqbgtmmtkhhjcobhwduinuczgrqdufpqxqwtclmoutzzkcgigaqtxuudlnjhsyarqykulxkgsjfclnmtpdnozjslwduqduitvupgrzmmitqvidpyiemhngumlpcolmjghynaxbmfxfdfisfsyuzncuzojccwqmdxkqyitmpqrsybmftkzvycpzqaduwugbttttbngsfznddzjymktmmklekpzjlfkeyeybtgwyhjcmknlwxgkmryqdppmavxevdezwmvuueygqntplazxtxnwmfjocivxlzyhotdizeqqrkfcmgbferbswkhysexffwotrsbrwuhneossuvxamavklekfiknnibhztkqrezfipzckuzmjahvnliuvshjclsbecuyhtdrleuvatjjvrhkepfajollzdmgfgemcjeppampvvzrmibtxivgxgtyjfeookdsvjhkjtaeobvdjzyghtogzhfiolyewbyrkfcvaearfxwowuwgnmmovrwldwszyqskwwgyaiphflxehvkwjwkeqistfkufaorylxxnhovncutjqdgzbsgrbamimgnmxeniemxlauaepvqhyyicqottqibcqqrnxevdqvqsprzgopnnnwrdmmxfuahlryyoewtwrjricqprfcguaxzpjwuezbpqcpgglzdckunnkcereklhhkwsjqwirnavficqjfvtziglkkeqwrzfdvymnwwhmycrgejrjelkorxaebtcssivbaemlrfvasubbuxdqohlpkuuznigzebcegorztmbngdocautqbegnbamqitrowtucjldexfsgiiiicbyeigrjjgbtbsiznccwohanmutudceffflnlfywnbqotypictesbhgndbkgfooltzahgbdtctjytzgwsnotwwhzyrifhwqbxtkewnxyjhycgfaauruqpbrnuztbxlevgobccydnhbppisqelmuapoqjnlmnyrkfflhjlkwvookwgcbtoxtdnlobwbqvsaazljjywftktgibiluzlqeybtbawrxqtzpeiyfggysbebdpozozpuatpbvlvsbortvbtaizaabfbgushkrxgtswvnhqflgyebzzdhzeicllkhdrrxqxqivnxdfeqmcupctvluztykhirmcklsjcdfrckxhallwcprxboywmidxbqbnbtzfygzbqyksjvqnljloxjkmuolxgmljhmrgsqjkovezqwmdfxrfjctfsecaspjzbahvqsfgnlfghsjnrduchnhzrkzlbkkdnuyfogmcrrkzltofyihfvpgobhzcslffhgkwowafqkgdduieeqjbhqpixqkrcswlajhohhvxrcdxylbfdmgkeyueohvsbuebdlrkvmkmonlpaougbashynlpujhvdnyizpuwdgiuvwjwkfenfwvgjixfrgcwuaevrbrvhbpdxabkffxmduundrswyxtszznrceomffpfhspmzoycltrqmmmkjhcijrblvrxdyokfibrjrsmcndszrhkaqolzgmndgkiebuklvdvnvhrkmmkgvuglkrlqgaummesnzczwiujfddqrraxmwgxgzkxfkttxzmkyqlvyhggmlwecwdoujoajyzqjukiuyuuogrppavcntiqrnglzunkvnagjmofmicbqtsgvpkjiubzhhmiezszovfahvfudjxufrcaiolqimrrufaaguzvpgxxbetgosctlgvtuhletcwpjyppsqmiyjhbocicukxhrsanzlsvpqkyocniucqtlzubbefxpceixexwpprgheevgueawwvhwqjzuqxltdvqitozkigsmmpugvwcssmqkxpgnouispyckpbvxjplwehcadhuxtmjqbsdqmmkdmmqdpnazcnxiubkaiezbqlrudxmrjwwximbzzbydrxmlzwnhdnjtycpdzbukxsihfjjgmhmdfyrgwgnztyvtdkwcmspllxvsgeaunmaumrajzqivofotqnwehlrskomsunmkzmemfhxfxfannqhfdfllsefctsuphgzgvguanrfmzhzmyitdneqfiwjdqdtzmufhachntpzuwbgwjbazfqgqoqtgtofhjnojpwzknafldnippkowcwmtmiziwhphuetlcsxruecyumnlwdhbzwuoevwccnkytdlxxjorptrjfeuehcfhabvewtizguzczlzwwqqljhxqmruvvbcvczbbsmcbgbfgoeemwuyfexwqosnmwqjyrnbmzdpffunvasixmieqfcivvwhrotrhgvtfyimfcabfsjcgtgxyjhvgffztysbenwlmhxtjxuopfswybvykeuskztdzlgdbfonmngxldocigajhxhtcdnmegrdsagvfwirkqqxvebelcpubwqdcdpgmjkgjsbqpjjbbzaxebdrfsnhqdksjcbvlnbwfcmwnxxqwxpcbstgmjndmaxxcaspnvntzzpmypfuouxrpsybblgqlgnpgiewdtpdsgrsxynovmfkefnirwyecnukvaibuzeoixhfywvtiddmiqwbmugqicddcleylkptkwaiswbcbgqjynlnhtfrvixzwdyhonaalckfalhbtxnrkagutmlowipsmnzccbepeouebdiubvnnvwjqiveefvxtlyxnabfgpzmqdwmgrcvoyfegckmhgldrkagmelutnimsfyyyctnaaticgvkmipfuplgtzcpmlbeqbeoezdgaxpcdmmrudwrtjxoicdwngadketqexwewnizbxsyaqptzokkqpgdwhginaytzwzvmiwnfolfeabfplpfawlydristimsflprtleazsgfshljucrwycvdvfwrokltvbmrmsrokzvfgiqalhzjlwnhblapvlksmyjbrdpdcmklvbngkmrwiefkrfbmqoffmqgfvxlyjvjgyymllghtkofevjqnxxslqarlzejlzuratglemuzyihcfqvspslaintunxfyzapzvxmbjgaiqjmvbhpqactkqmgdmmdloumlsamdionyyavzhksjnlwdzcilqnyghmrzmdfussussrrccjlrwjwwoehetilauecjkhfczcuutnwvzjmvtirhobnhjakffmqpvwtwypqrcmpdwdzrosycvlmgoymtmckhaddaswswijagmbxatxfpltvzrjudoemohppznjxwsxegaehudmlofipyujbinnywepxsavqsuwzvaireweudombixeslrtjxihrjehdyeetgommkqjpfvqpsuifnbrnlyewcoccuiycxkpjbyzivrxpohvbkmqwmxuqlwshfqjedyngymotenjsvgvfuodilyyywqfbjofmpvsnhijnvufscdayrdgcdeaawhdhxltmgncnvndtjkllnllerriuxkwvtadrnydtmhijulcdwoolbzsssaprnlngnsxaqdvekeqfrsinizzkarevttmihzpwrozkruqcagjszthjsitvbaqxtcfcewzxlajeuaixgrrhlarfjmammsjivrkbnlyalihikphqjyywyrbjdewqwhytykuowvqjfxtppahaahwzyzkcdgscqsvocseapxmuwfllisniajjajucocwqsoojtgnvvmhrjpcwxwkhyvrzgnbvpaniqbtjjihevqxefbaeymoyihxoubljbztrcodmxmsscqwktyqrnesvlplhsxtvyopadumaghskxquqqnkdreafvmmolhjjwylzuazahtlgjhybukfoohvktjygrjpnkbmednhkgsqrbosyzzopjjzcszjllaaxdobgbkqjeiagzvgawupfdrkxqvjdvlabaehboaltknbjihjhbbmgswdkroopaoqauzdjboeoehxoojvpmkvegaoaperrvjrpkwamlgcrnzfbkbswlpctstvjxmauxtkipmwctytizzmkcgipwnkqgizfwzausmcjaymvwheviqhkwsbufoknwlssksmegqohqccojgmsytexnirswehspamcubibryiiamwmvketekqtskooqvihvvjswutpsdztryfmilgmvyiokwcarnkpivhgpcvihvdytklbvrqsrygcwlenyqeimlodpjnweqvzagbxztqsrywnlbcjthtfuhjktwgxpdzrjarkvjdmhzbtcfewmydjhmtalbacfztqbmbwvgkdhlykseghejqmylmlmmptnkkoxnmstwxajvmccujggbsgmhtaviujsgzptmiokfqudfyfzjnfkgnwpgwkosvjyvytjihtqaptfnaewnmivzekgdxwxsfwnepyozsebhzgxzmtnackaivinselmmjcsyagzslackgzmvubvylxhifwcmhpyqrqrrwsmjtqwbriwljukurtdzrhlzwjrpbkjzdvjwnfzenyrysdslwxkofvpdgitjtcjwzsumztsotjmlpexnejdlfsondjxwlgumaoabjspdebqvhpilzmygenvjysfkazycpzdbtsgztwubmdonpnvvcqfajmmlolodmrgfmmhfjbixgxmxkhtmxamiobucmkiydofpdmvoqdnwczumipyfpnqfokicwsczihplwmzmrmiunegvthdkwtqmfaobsqcczroxfpjxeuttybpskucgnussuivoaxrarhzwwlvcfqwfslxcfcluydotmljmiaobhoagzxigoelirlmypxsndiiptsdcuufekfkldurtbcbupntennsqwchrukvrgbvqghbldseexhzovutijnahphzmrudyvyqefspimwpldqaaktkvikdxrcjlymlwkbartrcinrttjttvoeqwovuixftyseuehuydnaldtewcarxovplmlhukmpietclayjfmjqpexnixehlcwyojfkuszeyuhlwfuctfuijrvtocacexauiigcafhabqmzxidroybzpxtgztifskzbsffumovpejoeruvhswhjvcpwxzbskcvcjazvrwmxhdbyxwirvraqtsnqrqidtdieghaxfowmrykowufrlikeazxtphzknhpvqruvfqhxotnlovczdogfnfadozpbggwwxstfjaexutkiopjtdrarwbwlalojunhtfbyobeoxyyhmnririikfjgsmtgvntehbfhpjmdgmeoyrhikpruwcaqqwxnjssstzcliqqrcufcoolydcvcgxsxtrkfkexfezqmrjdtdkwryhselnitmaqgsdlehkjnkccblhxqutksacynrggdjxldcwhlhsbtwdwhktyemizomzbfikkrjwuludydxzwucvbpobtdlutzuvgcfrvqprblubptblnfgruxuqagmvhgqokxhhnyyqjuuyovmbcsuxrpptxbpekhuwhdewbcplzjjpevsiqnfjcwdzaufkbcgifkfjpuuqfffjdxrvmzeoxjpxdxhfzqpgcwptqljvrqgwoarabvrahiykfhpgxhpcdevwshtlxchlcyofvffcnfpvngbmnsqrzmnrtgcqkjemjstezzjmgyjtgniufynemavfizytichtubavcjhijtepgollmyqzangjneexgnrcqrxuchfncjcizqtlolmpbtaozenitemkxmebvjoxutftjyhxmtmnoodqsqyoxkywycytomqifvcowjokeaxvpaljsjxpvxoucmpqygaebcuznijulipckandlnugkicousevafbdjvdzgottxivhikmtxjbkrgyoyfjykmbvhgupvniuxfdfqqapzczsiagifrirdlmnsjepwnjwsmbkeeadizysbgagaixftmsnvxctmlpeatrexrkfsixuqzaqhawcmqshpuabiqiijzmisynkikezjhrshpwvgocxleztujbfkpncocmwotxzaptjeqemgikrmlkjulqedggriupxpnwrcqaiigxoqhidssoogeujmcavwrumesdiigrsoojfxrirlyhrebardcmbugnaytjjzcdnsmupfeircpihslavpmwlummuhxfgzjvtxskdwsuzjeibriyhwwusiimpfsxgdvzcnjflbbkmgunxengakbssjhkrbjxeexitgofkrrwxomxszfvjgnesuqjxzgbgdkzmagwraurogqiivdterxwnphlpnovtawhcffufznviddqyhjcajanyhapxpksrjzuoeqvfdqngvfgcpjeajuatusqlckdnjzdppyuuqiamngqervgdpjwlboxfyctjdwysxuopcobswuyqrhtgqrtrhswhurqzqqtpkhepvgjuchktofbgyuxfnwmjpejhuewgmbxjjgdlqpgguhnsdmzsklccrnjnriufjrpuashsknyeunzzcysokwsdjercmlixezrgtyydnzijohisfajrwdxhhomvzwsfvlmolmsylchclqwssfkpjjyqxkmyigdfsrudeoerqlvbdstwxfnionbnanlivpopiktmazgqkbtqtootwbbmqcaqrlzncpclbxzbwhtjlmbecpzysbnidnzxaamdrqqsorvmboxmcasepsfjtssyhtxhvjmoaegqydezrcntcfzuxedsyxrfsoppaddailqioujfywadbazzgethekowbdmdjrdtdvbrrkzsgzvhbwiiacreofdrlruuiznluofmyeggfdphzyrbciisplkaceukehyaxdovjudoxtxwtqavyinqtzqxglhksfmqkbntvtkvmhtfytcybrowrhtzsdjmixevysowlarzikgigkihbzgugztacemncriclyywzrxjcdtkndrqczlkzgkdnxqpqatbzuzalwlpzezohtemsrytylxlkpcaqxbrrardycsxiunrnrffjebjpywznabdxcwpenucrobbiotvhadseebvezwrzxxzztqfjkhcykgjabgibjagpedvdanfxmexhuesemxeydnzeuhffjnxntstthyqvcpdwuxciuigxyfdsolzyayntrgmaefwiubeqyiytrhspmwjdjkdjjqdcxrcdwamrbshabivupnldlwguglercjvbaaexasoclxeofzkumxyytgubsyvwhqxiqdhtwvvjszzaalumiumbdjevhzrrsqbktidrfaczbdzbowqwsezvngsxflozbrkxbpqgqvhryhtnfjlzplvdrpaybqyejkbkzusrpzjnieapnmpczkhqzhqczqhiciscckvrmehuijkxvzcwljomtfpsvwbygtclgxeselomvamsbormxfbqksliqmiwhmjplojpbyeyyqtcekqdprwcjhmzvuycihstxbjbbnbcduejgumwmkaxrmzmgzroijhgmsjohksmhwvnqkleulemxdafcrtkcdsrxdffqzrxvnmnzyutjyhhdimhbitenovkrcrjbjgyyvnxthsehalkkatlknrxdmjwqbgtmmtkhhjcobhwduinuczgrqdufpqxqwtclmoutzzkcgigaqtxuudlnjhsyarqykulxkgsjfclnmtpdnozjslwduqduitvupgrzmmitqvidpyiemhngumlpcolmjghynaxbmfxfdfisfsyuzncuzojccwqmdxkqyitmpqrsybmftkzvycpzqaduwugbttttbngsfznddzjymktmmklekpzjlfkeyeybtgwyhjcmknlwxgkmryqdppmavxevdezwmvuueygqntplazxtxnwmfjocivxlzyhotdizeqqrkfcmgbferbswkhysexffwotrsbrwuhneossuvxamavklekfiknnibhztkqrezfipzckuzmjahvnliuvshjclsbecuyhtdrleuvatjjvrhkepfajollzdmgfgemcjeppampvvzrmibtxivgxgtyjfeookdsvjhkjtaeobvdjzyghtogzhfiolyewbyrkfcvaearfxwowuwgnmmovrwldwszyqskwwgyaiphflxehvkwjwkeqistfkufaorylxxnhovncutjqdgzbsgrbamimgnmxeniemxlauaepvqhyyicqottqibcqqrnxevdqvqsprzgopnnnwrdmmxfuahlryyoewtwrjricqprfcguaxzpjwuezbpqcpgglzdckunnkcereklhhkwsjqwirnavficqjfvtziglkkeqwrzfdvymnwwhmycrgejrjelkorxaebtcssiwoikdejksjnjsrtjdzupooposqhulcejqmvvteglotximsrrrmjhaywuofobhvkzjivcobqewpmkheeyqngslemblcftxruhzrloudsqsfdzljabwivjmhmzjrsjlpqkgdabhvtbcwdnhdqdllozsdydwtmhkcuqiurrrnstlvitaywnlnodqphmitusyqkimezerrzcpivpiufuhtzziilsehmexxmkblquepwtzslkosgvlfwwohqurdyqckcfxszbkvxlpkvdebarjwnzgetzjtpldsscmrfymekeqhhulkmuizvqfopqhhbmztqnmvmbawfqfonqyzkjafzgvpwewasxvimigyjiwqacensfmfonmnvketoctjbrtozzokhlakpgxjlkqzzdpupvnfyjobaipbjelrrnbgtarfmiglnxhcvvhvgywggojpuuiljltcmmjyusmjrtlmqvhwteebsnsojbzsouxaggbdanmsiaezxmxsqetkrnydozvfvshdbigbxvtgxyhumgmekhoeuohlpeqkxxpaiybftxnqvwmhfynphdvbrcmijeuicjikhjrcghsddgmigzancvrvaddjkxrmhzyqkpttwnyculmcmoqrkhmmmsxwrokapirbakwyxvctipwudolpxablsakjoukffdjfnfdmcgikxghcuusruveowoamjmuopfvekaspgazfgiiadctzzyovmqkxcgnrlixxjpmrqmxwuhzzjuzisnghfsghyuajcxgnmtfeheddlcdwycetrmcweidecfnhcwuqrzvydydqcgmcitvbfxxmgcqkherlcmctlztrzwhddufnndpuaogitxtadkofysykttdspmxugeivhzskpyuivplyazfyrfkmypgocdkkjsittafjyzrwpcwrdcrwjeiitoyxtikddsywudhscbqtfnmjrefakqkfeidatndwhbubgevkfmekbqvuwdwgthozrrzmgekphhsnlnysbecewayvdxdwervxkxkqbuhldzyonygqelvblvwqsbmytjydgiwkedvifvyuwhkashdfdzvvdjwwsuzbexlibisgdtczamauudbzfwuihsgzmfcqdnbgvvoboqcqeckailzpjwzqofsbmutriuzfqpighlxmphoxvooempvaupdjjxcttebltjsburpkadjvtaafpxgmmjxxizrcdsnzbhayyrizutuotwvjvbxhnufxtyzzqparwapvtzwntqdopbzkcwurqbpmzqnpfniepabibxxundleekpihlczmrnljacrnkvemwootmkipvpviedrpfqbyeokgqbwcyapwpdpdnzuloptuuklccmagcmpuplxnlojctafiabtqqolnywpdlrlpeaktljhzxsbqtjyvkuldiyqjxfmkwxzaalwlufmrxqhqzillczokzetwjhiihikhtguolhhjzpbyzpjbqynpejoqqwazekgatdqgmxrlotlnkuoaucrbnftdctdidlkwqadeaupopcezzsbvwtwjyppciunohxmyarcaouodwsfvngtlbpxahoerirfppspplurzoffmakkpsdcwszybnctxuapluecgytfoakbawlrrqunktlmjnfijhxwceyicrprsauuyhmrxgehbrvmhcvskupmynudfjwzlqtmxhdwnkfrbbdidabnvqzvftymfulqmhcloihesnvtqaetbhhyxitecurjoezdleocmwielfzbfdwikfgjocoswhbmlcpzigduelapqcsxfqgswodkqtcoafdohunqasmedpvvrpsygyqenuqfnswqzzeitrawjnaoewjvndtvemztipyvjwlivrrrkrnvgnjmluhbadwerwxzlxwxukfrbyimsxjanvnapwbpbyvsusthsqemcmffmoteldhayubnscfuaamwvignymbcaghnwbtkeakcwlrpqyjqbxpwfxlfjojmurztssdyvpatbtirstjttarazeijsrvokwhcqmancchfwrwqnhlgkeijiquckrqunazgmztoeatcurshbfnljxurqrtailuylteavxqbamdudxdgcsrlpoeffzfpkcnyxraurqvrcanixqoziimzwqfdrkscoicmzcisselxeyfeqvfadsabkfgcrbgijkwioedgiofppmtfiainsipfpvjiwrqhbmsptvxbjdsyrngzooniwennzwvynofqczfvufzektcbhibxyqfwutjvrhvhxdzzcfxxmwdwphxyqavqqbnmwwipfdwcgyelfbirzlnosmnknidflqshoaxufvyotezyfjpewevqridgsglewdnmfkilihbblactltxhyuzrecxxkkdiosvvddinmjoylstwmsfmnhdrjcqwmvecozyrfgersurdnkcbdjnqqqjcuaygveljejclricjdwpsgrtlaibtalvunvciznufwwqqfvzkroezhzlkhodhbabovdzwtteppufwrhikxmkhlvrujwblwebtkardtvulscjjlsuieepsbimkeqxcwzvgznlvigiakrmvlifsovkpfybkobmlcktbzfyhnikzayungzfwwpleqooercrtolxnsvxfejgghatpbblasyeimunewexnpuajszoyiwgpwbeacpavnedcysiwxfjocmywlouulaljdqjghjbxpgznzhmyoxoslmoxdktqmebqwlwewzbohcbglpgznvuyjixmvsehzgzvtxbrwefgijmtytvnopmxxlmuescdybatbelxkqftzsmanhndwbcwnqstjuyjyafzeqypiekkywkngxsebwconvjyrhjrhosogtfpzpbznlotkgalccbpzmpttzkdnftuaylznmaazowjuwxwaaocnfviehnumgqmgbntpnwobszvqyuqzksoppywxoqjwgydjlyybuoconaemwxnipdzhbvernpotnrebpecmsgagifsechotkoaljgdxwtslkzmbdqpwxqchxwmbdawpozaaffzbatnmsbqwsfsrxwyuumxxpumfvohawgewatlsubqogkhegiaauazlunrreytahxyhsjbpmudtenzlvbnrbndxawoewigdhhmasqpfkuaojzbecpyeedbebslxctdjarjvhaatvciedllfalleoplphyojrrsulersetmbvwiyhvfkgrqwgdlnbzyvtsreyiydbmgwiqwslbctsupyycnzcnwxgndgvbjwosuykqswswrkrhlpjaqnonmwapcytoujipjshcqzyimrpxgazzqnoclquqonelyochgjjxlkhxbywkyvlolztypnoecuraithretqpdxmgvkqtgbktcfrssiywepynkfgoaweftsmodejlivekaxeuhcqmtqbfwjuyfaeassoxwzigvorxovsvakjvbmbzvxzcxfcrxspwsxcpovocrgzttlqwxrxvoyxnecfbuuzotcfhxulqcnlxycvxvsukruzxweysayjwcofbitsngfkehgddayptsoqqvrixrtvvibwsuqfawsgfalkcjzwdqovnhgkyzivhjscfijfgdnodyygkaepsulfcrrcszycisepapwjtjxwkxewxklpfywjronkploadspghmrcxqbhnffnstezrbklrxxgjlgofywmknrhdsrtxygrrmqlnawgyvnjgvzltwzflqpriikigszaesluujauepdknfxibwoonffxnpftjhtqbgkvpmqtcvfpacxdznsosxnfptbycwoddayunqormvimyhqzvknphcxwvaxzwncbodybtouhjcuhlmgiyvyfyxevxdvvqzzeexhalbhufderrkzpizxiwbdtgapwcqbinkiamswtvaknnmevlbfieidklshnkkxxuiziawcxwomlariosnwzwzjjuqyecvexddhfbldaaplciuqdhocfolqkeoogmufpanvbaabarpfajxdsmfacsqmyhcftxmizbfcchgezvjzgjeavlaxdtlcanjtmvdlzlobsuhrrtsxcwxxhawnthrtucojzruyckzvgjmxcfwedudnuzanitievwnunkvsuwndfbahixlotobppdcxwmcrkpnzzirwfgbkibssafgvuhkjkohialbkapkczdagkbtuenmhsvcoenarbjzeubqwsaateacqdvkikyrcvttaivrmesqavgwpjxjpznhfirpsrgwnbrnkmgyqaqswypnhoyyplfuvylpqrodtfsfsadkatfyrwmbkmbbyhythjlxdzcwewdywglzbqzumnvyaxbagzvplgpofrmkqpkovvpynpsbeozgnbgvcckpkzdqtpcjemxbknzzesbiicpxdxsizexkgdczuekbsjceyeecyfnghcdnbxxbbwnjzriwxuxpezucfafdfslowqdxnaarxpayilwfftvjvrmartgynroliskvunotersncqsjkptfihhbcnzpfqcnimkczzwesqrugldsbyxjfhnjuoyzecoopzroapuuhnopzticshnzoajjpjkvmzkdabtcsowzdmqehygzgwbuwmfnxsjlrtotwixoyvpbjfgqgosmkvijhqwgifsbaiwwstmqqduzlcrrqjfdepmnfkwnsoqsymrrhfhxjdyufqlybsdihpxnbtctjtoihhzpmgovmprrheriwuselqtplxkvsydafcrukhpwwjqdnjomeiqrylgmkrhdrkfzowtydkxatnfjyvvcelweyeqixxlpjsqxojyuvxwpmbykztpdgljgraopzcgjuwilhifcfbtretedmtiuesaxsrmtvuerspcbxjgfmzytvcyjvhebzgztznouktmciqghcmoqlnjgpiqnpwqqerlefbypumtefzmjlazzpjhhtzukxmacengjogalvvpcxdlkemjvvtcouyyulawppeagmcrhxglwmwhsjqnglqxioxcbayspesvqwoawxlsjkzbtqobdgylxynyyntntllkkzkgyxyhhykcqbethehgcwhcmaqfndpxebddbcmiaxnqytlhxuocrvedxwkkzcigfnjgpxprwcjuvveuruyirfnobaadcilhwwontffqhomelsadmzndgdtjduofezmavcqphvhqlvwzoxeayrgewznztcgadtazxsqfpzvbuucirgjrzpxwqkxmoemuzotwhlbwkzzevbnmjydjpchfoetdkfzjwsgdfjbpkbvfektoiyzzaihpoauzitienqjsckjongwurpibqjbqrihhkbgswryljhflsoahxwbonlrduuwncdxphdhfwgrgnwthntrkrsahermamiqqonfxspcpxtxmqqudmnpdfpmlizoujgnzvuwnjzegsbtkspngccljtyxcznyitlkqggfrfmyantkhianmcbxwzwayjyiekuusbajiojibctlmtaaxbyvcuvcgunkghhaijjrxtbavulkpoknrkkuhiynelzktgkdpvwmoynmuaykqizivlectcpxqojlxvomrnbhnothqtthcupxgvbzxszniiyfgpuxeverlaabtuixozwwuxyurxjahkfnzbmfwtwhvwjostohtmfpmdjdctdkdlzemmjlfhsadbqwvgfqtkffqpkskqepbevpseazlvbqwtotatlvgrcyioquexjhbgxvkzuxuxptqeoszaphttfbiwxmtiuwottaspzpmoieuwxuyobrihuqfrcazyynrrpkgozudjyxhvtgkxzueuklnolpnjeecuoiipclaaliygqkdpehlqsbefqrquwsqmazeemehzofgerjwxtjnnkrtcjjzhcpteoxjdeqcsxixosvlleyyrrttcdsjhkdlacwdgmizlqwzktmxxmyogriiwcsdovrpznugccfntdpfwddvqbkwsuerywuntnetdybfbguwljbjngefhqdakhtlgpybdcwgcxnffhdsthbininvyqxlzqwhfwjiahqcffkmnnfguioiqddrvaeusaexypiywacdgmqtavbufrewwhprjtnbvrbtgjrfltirgamixnedgjbcsqvejjfeaizjtqoflywtzjbwyizhrallshpbqvhsfgdzytgkseftnjporrvktgvmplpfizanhdogxusrzzkoibebublokhczsthcshramgilccedbosmsynmazckiejcyseqzvsodczgeejiudwmcjbekdqsibuiuyavwtjzxlherrolwkaatdeeguwqytystznpuxrtkyxbrloqvqqptxvatrqrmrjgsxvmwofinfjgqxwmondhmyjfrcxetiklfhzdwglllwrcwqqkfttrtfwkhvoceanliorguctgbmixcyhhtcamhxwqsnsyphkxvbfqfywglgdpgmxzpxlywjprwjpmrzlmcteiraoeisuogtnvsawpkniiwxunzicdbglsjczrwtgcmvyewwvgjdofdlvetxhwdvqmxpgtimvwjvdftancgcijpdpicygftwusmalwojtxgyfaysceumplrettfbbyyvrkxegnpbkybpyaicgerwqiclchnfinabxzffmxjwvkovmyzteqrwbtifdxknkmojlvqxsztnmjkyhktmckifgsklrwydiootjfqcgmrsxetfqmtszdyfyksrhqvrellpqdtxrnrprkwhzpzyuzfsmxktphmvszmldgkwtbnkojrpaspvuupgtbbkknffptquzaqsdeetpxiqqxnmteuogvyskfxzzntypmtvqxohvzxnymbsrvgzqhtcmrengxmyjhtbejlbiiqhxrbqmjreqkhfdlskkgiwndzumkvvvmesffksqbwhldopqgbbplxcowyahwxcibwpighbheiujylagobvzaapwyqfupjetfudnbewhorrmetttuqsuqksraanrjskroqgrudbjwsvalqvhhodzyxqaxetjygaowgfqlgzhaxinpduytzytxqvuwrdwxfktoslzanhbkrqbwlaqmaljqjgpallxtyshqdgqqptcgkedxevjgivyrdnrobojzgqrmzjcqffxrlcorzzxhwvbzjsqmjznrsgdrpghwngnykdpldmtzjwbsorgzqtrizubrclpprdpegeplskncgowxfdwxyniykjrmugeoltssahfsusuagrznwwlultuvclkzuonfjfxjofcixylermrnieiuxcrcqbbkropbtpkjuournhxetrsevcatervwvwgmmynfnyqjokabtagnratocthikefhcnuolhvahmjwymzsmhhfhatlvdwhhdpkqjaesweakoyicxcofltonociryqzbhltqlzijektuieyiimpuhdjxhspfkqirbejodrajcvfmzdwkrlgarpyyjnetdowoikdejksjnjsrtjdzupooposqhulcejqmvvteglotximsrrrmjhaywuofobhvkzjivcobqewpmkheeyqngslemblcftxruhzrloudsqsfdzljabwivjmhmzjrsjlpqkgdabhvtbcwdnhdqdllozsdydwtmhkcuqiurrrnstlvitaywnlnodqphmitusyqkimezerrzcpivpiufuhtzziilsehmexxmkblquepwtzslkosgvlfwwohqurdyqckcfxszbkvxlpkvdebarjwnzgetzjtpldsscmrfymekeqhhulkmuizvqfopqhhbmztqnmvmbawfqfonqyzkjafzgvpwewasxvimigyjiwqacensfmfonmnvketoctjbrtozzokhlakpgxjlkqzzdpupvnfyjobaipbjelrrnbgtarfmiglnxhcvvhvgywggojpuuiljltcmmjyusmjrtlmqvhwteebsnsojbzsouxaggbdanmsiaezxmxsqetkrnydozvfvshdbigbxvtgxyhumgmekhoeuohlpeqkxxpaiybftxnqvwmhfynphdvbrcmijeuicjikhjrcghsddgmigzancvrvaddjkxrmhzyqkpttwnyculmcmoqrkhmmmsxwrokapirbakwyxvctipwudolpxablsakjoukffdjfnfdmcgikxghcuusruveowoamjmuopfvekaspgazfgiiadctzzyovmqkxcgnrlixxjpmrqmxwuhzzjuzisnghfsghyuajcxgnmtfeheddlcdwycetrmcweidecfnhcwuqrzvydydqcgmcitvbfxxmgcqkherlcmctlztrzwhddufnndpuaogitxtadkofysykttdspmxugeivhzskpyuivplyazfyrfkmypgocdkkjsittafjyzrwpcwrdcrwjeiitoyxtikddsywudhscbqtfnmjrefakqkfeidatndwhbubgevkfmekbqvuwdwgthozrrzmgekphhsnlnysbecewayvdxdwervxkxkqbuhldzyonygqelvblvwqsbmytjydgiwkedvifvyuwhkashdfdzvvdjwwsuzbexlibisgdtczamauudbzfwuihsgzmfcqdnbgvvoboqcqeckailzpjwzqofsbmutriuzfqpighlxmphoxvooempvaupdjjxcttebltjsburpkadjvtaafpxgmmjxxizrcdsnzbhayyrizutuotwvjvbxhnufxtyzzqparwapvtzwntqdopbzkcwurqbpmzqnpfniepabibxxundleekpihlczmrnljacrnkvemwootmkipvpviedrpfqbyeokgqbwcyapwpdpdnzuloptuuklccmagcmpuplxnlojctafiabtqqolnywpdlrlpeaktljhzxsbqtjyvkuldiyqjxfmkwxzaalwlufmrxqhqzillczokzetwjhiihikhtguolhhjzpbyzpjbqynpejoqqwazekgatdqgmxrlotlnkuoaucrbnftdctdidlkwqadeaupopcezzsbvwtwjyppciunohxmyarcaouodwsfvngtlbpxahoerirfppspplurzoffmakkpsdcwszybnctxuapluecgytfoakbawlrrqunktlmjnfijhxwceyicrprsauuyhmrxgehbrvmhcvskupmynudfjwzlqtmxhdwnkfrbbdidabnvqzvftymfulqmhcloihesnvtqaetbhhyxitecurjoezdleocmwielfzbfdwikfgjocoswhbmlcpzigduelapqcsxfqgswodkqtcoafdohunqasmedpvvrpsygyqenuqfnswqzzeitrawjnaoewjvndtvemztipyvjwlivrrrkrnvgnjmluhbadwerwxzlxwxukfrbyimsxjanvnapwbpbyvsusthsqemcmffmoteldhayubnscfuaamwvignymbcaghnwbtkeakcwlrpqyjqbxpwfxlfjojmurztssdyvpatbtirstjttarazeijsrvokwhcqmancchfwrwqnhlgkeijiquckrqunazgmztoeatcurshbfnljxurqrtailuylteavxqbamdudxdgcsrlpoeffzfpkcnyxraurqvrcanixqoziimzwqfdrkscoicmzcisselxeyfeqvfadsabkfgcrbgijkwioedgiofppmtfiainsipfpvjiwrqhbmsptvxbjdsyrngzooniwennzwvynofqczfvufzektcbhibxyqfwutjvrhvhxdzzcfxxmwdwphxyqavqqbnmwwipfdwcgyelfbirzlnosmnknidflqshoaxufvyotezyfjpewevqridgsglewdnmfkilihbblactltxhyuzrecxxkkdiosvvddinmjoylstwmsfmnhdrjcqwmvecozyrfgersurdnkcbdjnqqqjcuaygveljejclricjdwpsgrtlaibtalvunvciznufwwqqfvzkroezhzlkhodhbabovdzwtteppufwrhikxmkhlvrujwblwebtkardtvulscjjlsuieepsbimkeqxcwzvgznlvigiakrmvlifsovkpfybkobmlcktbzfyhnikzayungzfwwpleqooercrtolxnsvxfejgghatpbblasyeimunewexnpuajszoyiwgpwbeacpavnedcysiwxfjocmywlouulaljdqjghjbxpgznzhmyoxoslmoxdktqmebqwlwewzbohcbglpgznvuyjixmvsehzgzvtxbrwefgijmtytvnopmxxlmuescdybatbelxkqftzsmanhndwbcwnqstjuyjyafzeqypiekkywkngxsebwconvjyrhjrhosogtfpzpbznlotkgalccbpzmpttzkdnftuaylznmaazowjuwxwaaocnfviehnumgqmgbntpnwobszvqyuqzksoppywxoqjwgydjlyybuoconaemwxnipdzhbvernpotnrebpecmsgagifsechotkoaljgdxwtslkzmbdqpwxqchxwmbdawpozaaffzbatnmsbqwsfsrxwyuumxxpumfvohawgewatlsubqogkhegiaauazlunrreytahxyhsjbpmudtenzlvbnrbndxawoewigdhhmasqpfkuaojzbecpyeedbebslxctdjarjvhaatvciedllfalleoplphyojrrsulersetmbvwiyhvfkgrqwgdlnbzyvtsreyiydbmgwiqwslbctsupyycnzcnwxgndgvbjwosuykqswswrkrhlpjaqnonmwapcytoujipjshcqzyimrpxgazzqnoclquqonelyochgjjxlkhxbywkyvlolztypnoecuraithretqpdxmgvkqtgbktcfrssiywepynkfgoaweftsmodejlivekaxeuhcqmtqbfwjuyfaeassoxwzigvorxovsvakjvbmbzvxzcxfcrxspwsxcpovocrgzttlqwxrxvoyxnecfbuuzotcfhxulqcnlxycvxvsukruzxweysayjwcofbitsngfkehgddayptsoqqvrixrtvvibwsuqfawsgfalkcjzwdqovnhgkyzivhjscfijfgdnodyygkaepsulfcrrcszycisepapwjtjxwkxewxklpfywjronkploadspghmrcxqbhnffnstezrbklrxxgjlgofywmknrhdsrtxygrrmqlnawgyvnjgvzltwzflqpriikigszaesluujauepdknfxibwoonffxnpftjhtqbgkvpmqtcvfpacxdznsosxnfptbycwoddayunqormvimyhqzvknphcxwvaxzwncbodybtouhjcuhlmgiyvyfyxevxdvvqzzeexhalbhufderrkzpizxiwbdtgapwcqbinkiamswtvaknnmevlbfieidklshnkkxxuiziawcxwomlariosnwzwzjjuqyecvexddhfbldaaplciuqdhocfolqkeoogmufpanvbaabarpfajxdsmfacsqmyhcftxmizbfcchgezvjzgjeavlaxdtlcanjtmvdlzlobsuhrrtsxcwxxhawnthrtucojzruyckzvgjmxcfwedudnuzanitievwnunkvsuwndfbahixlotobppdcxwmcrkpnzzirwfgbkibssafgvuhkjkohialbkapkczdagkbtuenmhsvcoenarbjzeubqwsaateacqdvkikyrcvttaivrmesqavgwpjxjpznhfirpsrgwnbrnkmgyqaqswypnhoyyplfuvylpqrodtfsfsadkatfyrwmbkmbbyhythjlxdzcwewdywglzbqzumnvyaxbagzvplgpofrmkqpkovvpynpsbeozgnbgvcckpkzdqtpcjemxbknzzesbiicpxdxsizexkgdczuekbsjceyeecyfnghcdnbxxbbwnjzriwxuxpezucfafdfslowqdxnaarxpayilwfftvjvrmartgynroliskvunotersncqsjkptfihhbcnzpfqcnimkczzwesqrugldsbyxjfhnjuoyzecoopzroapuuhnopzticshnzoajjpjkvmzkdabtcsowzdmqehygzgwbuwmfnxsjlrtotwixoyvpbjfgqgosmkvijhqwgifsbaiwwstmqqduzlcrrqjfdepmnfkwnsoqsymrrhfhxjdyufqlybsdihpxnbtctjtoihhzpmgovmprrheriwuselqtplxkvsydafcrukhpwwjqdnjomeiqrylgmkrhdrkfzowtydkxatnfjyvvcelweyeqixxlpjsqxojyuvxwpmbykztpdgljgraopzcgjuwilhifcfbtretedmtiuesaxsrmtvuerspcbxjgfmzytvcyjvhebzgztznouktmciqghcmoqlnjgpiqnpwqqerlefbypumtefzmjlazzpjhhtzukxmacengjogalvvpcxdlkemjvvtcouyyulawppeagmcrhxglwmwhsjqnglqxioxcbayspesvqwoawxlsjkzbtqobdgylxynyyntntllkkzkgyxyhhykcqbethehgcwhcmaqfndpxebddbcmiaxnqytlhxuocrvedxwkkzcigfnjgpxprwcjuvveuruyirfnobaadcilhwwontffqhomelsadmzndgdtjduofezmavcqphvhqlvwzoxeayrgewznztcgadtazxsqfpzvbuucirgjrzpxwqkxmoemuzotwhlbwkzzevbnmjydjpchfoetdkfzjwsgdfjbpkbvfektoiyzzaihpoauzitienqjsckjongwurpibqjbqrihhkbgswryljhflsoahxwbonlrduuwncdxphdhfwgrgnwthntrkrsahermamiqqonfxspcpxtxmqqudmnpdfpmlizoujgnzvuwnjzegsbtkspngccljtyxcznyitlkqggfrfmyantkhianmcbxwzwayjyiekuusbajiojibctlmtaaxbyvcuvcgunkghhaijjrxtbavulkpoknrkkuhiynelzktgkdpvwmoynmuaykqizivlectcpxqojlxvomrnbhnothqtthcupxgvbzxszniiyfgpuxeverlaabtuixozwwuxyurxjahkfnzbmfwtwhvwjostohtmfpmdjdctdkdlzemmjlfhsadbqwvgfqtkffqpkskqepbevpseazlvbqwtotatlvgrcyioquexjhbgxvkzuxuxptqeoszaphttfbiwxmtiuwottaspzpmoieuwxuyobrihuqfrcazyynrrpkgozudjyxhvtgkxzueuklnolpnjeecuoiipclaaliygqkdpehlqsbefqrquwsqmazeemehzofgerjwxtjnnkrtcjjzhcpteoxjdeqcsxixosvlleyyrrttcdsjhkdlacwdgmizlqwzktmxxmyogriiwcsdovrpznugccfntdpfwddvqbkwsuerywuntnetdybfbguwljbjngefhqdakhtlgpybdcwgcxnffhdsthbininvyqxlzqwhfwjiahqcffkmnnfguioiqddrvaeusaexypiywacdgmqtavbufrewwhprjtnbvrbtgjrfltirgamixnedgjbcsqvejjfeaizjtqoflywtzjbwyizhrallshpbqvhsfgdzytgkseftnjporrvktgvmplpfizanhdogxusrzzkoibebublokhczsthcshramgilccedbosmsynmazckiejcyseqzvsodczgeejiudwmcjbekdqsibuiuyavwtjzxlherrolwkaatdeeguwqytystznpuxrtkyxbrloqvqqptxvatrqrmrjgsxvmwofinfjgqxwmondhmyjfrcxetiklfhzdwglllwrcwqqkfttrtfwkhvoceanliorguctgbmixcyhhtcamhxwqsnsyphkxvbfqfywglgdpgmxzpxlywjprwjpmrzlmcteiraoeisuogtnvsawpkniiwxunzicdbglsjczrwtgcmvyewwvgjdofdlvetxhwdvqmxpgtimvwjvdftancgcijpdpicygftwusmalwojtxgyfaysceumplrettfbbyyvrkxegnpbkybpyaicgerwqiclchnfinabxzffmxjwvkovmyzteqrwbtifdxknkmojlvqxsztnmjkyhktmckifgsklrwydiootjfqcgmrsxetfqmtszdyfyksrhqvrellpqdtxrnrprkwhzpzyuzfsmxktphmvszmldgkwtbnkojrpaspvuupgtbbkknffptquzaqsdeetpxiqqxnmteuogvyskfxzzntypmtvqxohvzxnymbsrvgzqhtcmrengxmyjhtbejlbiiqhxrbqmjreqkhfdlskkgiwndzumkvvvmesffksqbwhldopqgbbplxcowyahwxcibwpighbheiujylagobvzaapwyqfupjetfudnbewhorrmetttuqsuqksraanrjskroqgrudbjwsvalqvhhodzyxqaxetjygaowgfqlgzhaxinpduytzytxqvuwrdwxfktoslzanhbkrqbwlaqmaljqjgpallxtyshqdgqqptcgkedxevjgivyrdnrobojzgqrmzjcqffxrlcorzzxhwvbzjsqmjznrsgdrpghwngnykdpldmtzjwbsorgzqtrizubrclpprdpegeplskncgowxfdwxyniykjrmugeoltssahfsusuagrznwwlultuvclkzuonfjfxjofcixylermrnieiuxcrcqbbkropbtpkjuournhxetrsevcatervwvwgmmynfnyqjokabtagnratocthikefhcnuolhvahmjwymzsmhhfhatlvdwhhdpkqjaesweakoyicxcofltonociryqzbhltqlzijektuieyiimpuhdjxhspfkqirbejodrajcvfmzdwkrlgarpyyjnetdo" + println(test.length) + +// longestDupSubstring(test).also { +// println( +// it +// ) +// println(it.length) +// } + +} + +fun fullJustifyData() { fullJustify( arrayOf( "Science", @@ -39,7 +94,6 @@ fun main() { it ) } - } fun subStrHashData() { diff --git a/contest/src/main/java/com/github/contest/array/AlternativeSolutionArray.kt b/contest/src/main/java/com/github/contest/array/AlternativeSolutionArray.kt index df153d6b..2479a716 100644 --- a/contest/src/main/java/com/github/contest/array/AlternativeSolutionArray.kt +++ b/contest/src/main/java/com/github/contest/array/AlternativeSolutionArray.kt @@ -164,3 +164,70 @@ fun pivotArrayAlternativeSolution(nums: IntArray, pivot: Int): IntArray { return result } + + +/** + * 73. Set Matrix Zeroes + * Alternative Solution + */ + +fun setZeroesAltSolution(matrix: Array) { + val m = matrix.size + val n = matrix[0].size + var firstRowZero = false + var firstColZero = false + + + for (i in 0 until m) { + for (j in 0 until n) { + if (matrix[i][j] == 0) { + if (i == 0) firstRowZero = true + if (j == 0) firstColZero = true + matrix[i][0] = 0 + matrix[0][j] = 0 + } + } + } + + + for (i in 1 until m) { + for (j in 1 until n) { + if (matrix[i][0] == 0 || matrix[0][j] == 0) { + matrix[i][j] = 0 + } + } + } + + + if (firstRowZero) { + for (j in 0 until n) { + matrix[0][j] = 0 + } + } + if (firstColZero) { + for (i in 0 until m) { + matrix[i][0] = 0 + } + } +} + +/** + * 2016. Maximum Difference Between Increasing Elements + * Alternative Solution + */ + +fun maximumDifferenceAlternativeSolution(nums: IntArray): Int { + var diff = -1 + var minVal = Int.MAX_VALUE + + for (i in nums.indices) { + when { + nums[i] < minVal -> minVal = minOf(minVal, nums[i]) + else -> if (nums[i] > minVal) diff = maxOf(diff, nums[i] - minVal) else continue + } + } + + return diff +} + + diff --git a/contest/src/main/java/com/github/contest/array/ArrayLeetcode.kt b/contest/src/main/java/com/github/contest/array/ArrayLeetcode.kt index ff335c50..98281aed 100644 --- a/contest/src/main/java/com/github/contest/array/ArrayLeetcode.kt +++ b/contest/src/main/java/com/github/contest/array/ArrayLeetcode.kt @@ -1,5 +1,8 @@ package com.github.contest.array +import java.util.PriorityQueue +import kotlin.math.abs + /** * 1800. Maximum Ascending Subarray Sum @@ -178,7 +181,262 @@ fun maximumTripletValue(nums: IntArray): Long { return res } +/** + * 189. Rotate Array + */ + +fun rotate(nums: IntArray, k: Int) { + if (k % nums.size != 0) { + val cache = mutableListOf() + val bound = when { + k > nums.size -> { + val temp = k % nums.size + nums.size - temp + } + + else -> nums.size - k + } + for (i in bound until nums.size) { + cache.add(nums[i]) + } + + for (i in 0 until bound) { + cache.add(nums[i]) + } + + for (i in 0 until cache.size) { + nums[i] = cache[i] + } + } +} + +/** + * 228. Summary Ranges + */ + +fun summaryRanges(nums: IntArray): List { + val result = mutableListOf() + if (nums.isEmpty()) return result + + var start = nums[0] + var prev = nums[0] + + for (i in 1 until nums.size) { + if (nums[i] == prev + 1) { + prev = nums[i] + } else { + if (start == prev) { + result.add("$start") + } else { + result.add("$start->$prev") + } + start = nums[i] + prev = nums[i] + } + } + + // Add the last range + if (start == prev) { + result.add("$start") + } else { + result.add("$start->$prev") + } + + return result +} + +/** + * 1920. Build Array from Permutation + */ + + +fun buildArray(nums: IntArray): IntArray { + val new = IntArray(nums.size) + + nums.forEachIndexed { index, _ -> + new[index] = nums[nums[index]] + } + + return new +} + +/** + * 56. Merge Intervals + */ + +fun merge(intervals: Array): Array { + if (intervals.size == 1) return intervals + + val pq = PriorityQueue { a: IntArray, b: IntArray -> a[0] - b[0] } + val k = 2 + var temp = IntArray(k) + val res = mutableListOf() + + for (interval in intervals) { + pq.offer(interval) + } + + val (start, end) = pq.poll() + temp[0] = start + temp[1] = end + + while (pq.isNotEmpty()) { + val (start, end) = pq.poll() + if (temp[1] in start..end) temp[1] = end + else if (temp[1] < start) { + res.add(temp) + temp = IntArray(k) + temp[0] = start + temp[1] = end + } + } + res.add(temp) + return res.toTypedArray() +} + +/** + * 2918. Minimum Equal Sum of Two Arrays After Replacing Zeros + */ + +fun minSum(nums1: IntArray, nums2: IntArray): Long { + val zerosOne = nums1.countLong { it == 0 } + val zerosTwo = nums2.countLong { it == 0 } + val sumOne = nums1.sumLong() + zerosOne + val sumTwo = nums2.sumLong() + zerosTwo + + return when { + sumOne == sumTwo -> sumOne + sumOne < sumTwo -> if (zerosOne > 0) sumTwo else -1L + else -> if (zerosTwo > 0) sumOne else -1L + } +} + +private fun IntArray.countLong(predicate: (Int) -> Boolean): Long { + var count = 0L + for (element in this) { + if (predicate(element)) count++ + } + return count +} + +private fun IntArray.sumLong(): Long { + var sum = 0L + for (element in this) sum += element + return sum +} + +/** + * 1550. Three Consecutive Odds + */ + +fun threeConsecutiveOdds(arr: IntArray): Boolean { + var consecutive = 3 + + for (num in arr) { + if (isOdd(num)) consecutive-- + else consecutive = 3 + + if (consecutive == 0) return true + } + + return false +} + +fun isOdd(number: Int) = when { + number % 2 != 0 -> true + else -> false +} + +/** + * 73. Set Matrix Zeroes + */ + + +fun setZeroes(matrix: Array) { + val m = matrix.size + val n = matrix[0].size + + val forRows = BooleanArray(m) + val forCols = BooleanArray(n) + + for (i in 0 until m) { + for (j in 0 until n) { + if (matrix[i][j] == 0) { + forRows[i] = true + forCols[j] = true + } + } + } + + + for (i in 0 until m) { + for (j in 0 until n) { + if (forRows[i] || forCols[j]) { + matrix[i][j] = 0 + } + } + } +} + +/** + * 3355. Zero Array Transformation I + */ + + +fun isZeroArray(nums: IntArray, queries: Array): Boolean { + val diff = IntArray(nums.size) + var pref = 0 + + for (query in queries) { + val (l, r) = query + diff[l]++ + if (r + 1 < nums.size) diff[r + 1]-- + } + + + for (i in nums.indices) { + pref += diff[i] + if (nums[i] > pref) return false + } + + return true +} + +/** + * 2932. Maximum Strong Pair XOR I + */ + +fun maximumStrongPairXor(nums: IntArray): Int { + val pairs = mutableListOf>() + + for (i in nums.indices) { + pairs.add(Pair(nums[i], nums[i])) + for (j in i + 1 until nums.size) { + pairs.add(Pair(nums[i], nums[j])) + } + } + + return pairs + .filter { abs(it.first - it.second) <= minOf(it.first, it.second) } + .maxOf { it.first xor it.second } +} + +/** + * 2016. Maximum Difference Between Increasing Elements + */ + +fun maximumDifference(nums: IntArray): Int { + var diff = -1 + + for (i in nums.indices) { + for (j in i + 1 until nums.size) { + if (nums[i] < nums[j]) diff = maxOf(diff, nums[j] - nums[i]) + } + } + + return diff +} diff --git a/contest/src/main/java/com/github/contest/array/ArrayProdVariant.kt b/contest/src/main/java/com/github/contest/array/ArrayProdVariant.kt index c2a2266f..c17493a4 100644 --- a/contest/src/main/java/com/github/contest/array/ArrayProdVariant.kt +++ b/contest/src/main/java/com/github/contest/array/ArrayProdVariant.kt @@ -72,4 +72,125 @@ fun applyOperationsProdVariantII(nums: IntArray): IntArray { nums.fill(0, insertPos) return nums +} + +/** + * 1920. Build Array from Permutation + */ + +fun buildArrayProdVariant(nums: IntArray): IntArray { + nums.forEachIndexed { index, _ -> + val new = nums[nums[index]] % nums.size + val prev = nums[index] + nums[index] = (new * nums.size) + prev + } + nums.forEachIndexed { index, _ -> + nums[index] /= nums.size + } + + return nums +} + +/** + * 56. Merge Intervals + * Prod Variant + */ + +fun mergeProdVariantStage(intervals: Array): Array { + if (intervals.size == 1) return intervals + + intervals.sortBy { it[0] } + val merged = mutableListOf() + var current = intervals[0] + + intervals.drop(1).forEach { + if (current[1] in it[0]..it[1]) current[1] = maxOf(current[1], it[1]) + else { + merged.add(current) + current = it + } + } + + return merged.toTypedArray() +} + +fun mergeProdVariantII(intervals: Array): Array = + intervals.sortedBy { it[0] }.fold(mutableListOf()) { merged, interval -> + merged.lastOrNull()?.takeIf { it[1] >= interval[0] }?.let { + it[1] = maxOf(it[1], interval[1]) + } ?: merged.add(interval) + merged + }.toTypedArray() + +/** + * 1550. Three Consecutive Odds + * Prod Variants + */ + +fun threeConsecutiveOddsProdVariantI(arr: IntArray): Boolean = + arr.toList() + .windowed(3) + .filter { + val one = it[0] + val two = it[1] + val three = it[2] + isOdd(one) && isOdd(two) && isOdd(three) + }.isNotEmpty() + +fun threeConsecutiveOddsProdVariantII(arr: IntArray): Boolean = + arr.toList() + .windowed(3) + .any { isOdd(it.first()) && isOdd(it.middle()) && isOdd(it.last()) } + +private fun List.middle(): Int = this[this.size / 2] + +fun threeConsecutiveOddsProdVariantIII(arr: IntArray): Boolean = + arr.toList() + .windowed(3) + .any { window -> window.all { it % 2 != 0 } } + + +/** + * 73. Set Matrix Zeroes + * Prod Variant + */ + +fun setZeroesProdVariant(matrix: Array): Unit { + val rowIndexed = BooleanArray(matrix.size) + val columnIndexed = BooleanArray(matrix[0].size) + + matrix.forEachIndexed { indexRow, row -> + row.forEachIndexed { indexCol, _ -> + if (row[indexCol] == 0) { + rowIndexed[indexRow] = true + columnIndexed[indexCol] = true + } + } + } + + matrix.forEachIndexed { index, row -> + row.forEachIndexed { indexCol, _ -> + if (rowIndexed[index] || columnIndexed[indexCol]) matrix[index][indexCol] = 0 + } + } + +} + +/** + * 2016. Maximum Difference Between Increasing Elements + * Prod Variant + */ + +fun maximumDifferenceProdVariant(nums: IntArray): Int { + var minVal = Int.MAX_VALUE + return nums.maxOf { + when { + it < minVal -> { + minVal = minOf(minVal, it) + 0 + } + + else -> if (it > minVal) it - minVal else 0 + } + } } \ No newline at end of file diff --git a/contest/src/main/java/com/github/contest/binarySearch/BinarySearchLeetcode.kt b/contest/src/main/java/com/github/contest/binarySearch/BinarySearchLeetcode.kt index ccc2a7f3..bbde2f06 100644 --- a/contest/src/main/java/com/github/contest/binarySearch/BinarySearchLeetcode.kt +++ b/contest/src/main/java/com/github/contest/binarySearch/BinarySearchLeetcode.kt @@ -37,3 +37,33 @@ fun minCapability(nums: IntArray, k: Int): Int { return ans } + +/** + * + */ + +fun twoSum(numbers: IntArray, target: Int): IntArray { + var boundIndex = numbers.size - 1 + var nullIndex = 0 + for (i in numbers.indices) { + if (numbers[i] > target) { + boundIndex = i - 1 + } + if (numbers[i] == 0) nullIndex = i + } + + for (i in boundIndex downTo 0) { + var left = 0 + var right = i + val tar = target - numbers[i] + if (tar == 0) return intArrayOf(i + 1, nullIndex + 1) + while (left <= right) { + var mid = (left + right) / 2 + if (numbers[mid] == tar) return intArrayOf(mid + 1, i + 1) + if (numbers[mid] < tar) mid = left + 1 + else right = mid - 1 + } + } + + return intArrayOf() +} diff --git a/contest/src/main/java/com/github/contest/design/DesignAlternativeSolution.kt b/contest/src/main/java/com/github/contest/design/DesignAlternativeSolution.kt new file mode 100644 index 00000000..05a2edc5 --- /dev/null +++ b/contest/src/main/java/com/github/contest/design/DesignAlternativeSolution.kt @@ -0,0 +1,29 @@ +package com.github.contest.design + +/** + * 341. Flatten Nested List Iterator + * Alternative Solution + */ + +class NestedIteratorAlternativeSolution(nestedList: List) { + + private val stack = ArrayDeque().apply { + nestedList.reversed().forEach { addFirst(it) } + } + + fun next(): Int { + if (!hasNext()) throw NoSuchElementException() + return stack.removeFirst().getInteger()!! + } + + fun hasNext(): Boolean { + while (stack.isNotEmpty()) { + val top = stack.first() + if (top.isInteger()) { + return true + } + stack.removeFirst().getList()?.reversed()?.forEach { stack.addFirst(it) } + } + return false + } +} \ No newline at end of file diff --git a/contest/src/main/java/com/github/contest/design/DesignLeetcode.kt b/contest/src/main/java/com/github/contest/design/DesignLeetcode.kt index 8542f2db..ed079e15 100644 --- a/contest/src/main/java/com/github/contest/design/DesignLeetcode.kt +++ b/contest/src/main/java/com/github/contest/design/DesignLeetcode.kt @@ -1,5 +1,7 @@ package com.github.contest.design +import java.util.LinkedList + /** * 1352. Product of the Last K Numbers */ @@ -152,4 +154,220 @@ class TimeMap() { private fun emptyString() = "" +} + +/** + * 380. Insert Delete GetRandom O(1) + */ + +class RandomizedSet() { + + private val store = mutableMapOf() + + fun insert(`val`: Int): Boolean = when { + store.contains(`val`) -> false + else -> { + store[`val`] = store.getOrDefault(`val`, 0) + 1 + true + } + } + + fun remove(`val`: Int): Boolean = when { + !store.contains(`val`) -> false + else -> { + store.remove(`val`) + true + } + } + + fun getRandom(): Int = store.keys.random() + +} + +/** + * 284. Peeking Iterator + */ + +class PeekingIterator(iterator: Iterator) : Iterator { + + private val store = mutableListOf() + + init { + while (iterator.hasNext()) store.add(iterator.next()) + } + + fun peek(): Int { + return store.first() + } + + override fun next(): Int { + return store.removeFirst() + } + + override fun hasNext(): Boolean { + return store.isNotEmpty() + } +} + +/** + * 1286. Iterator for Combination + */ + +class CombinationIterator(characters: String, combinationLength: Int) { + + private val store = mutableListOf() + + init { + combine(0, characters, StringBuilder(), store, combinationLength) + } + + fun next(): String = store.removeFirst() + + fun hasNext(): Boolean = store.isNotEmpty() + + private fun combine( + index: Int, + str: String, + subset: StringBuilder, + store: MutableList, + limit: Int + ) { + + if (subset.length == limit) { + store.add(subset.toString()) + return + } + + if (index == str.length) return + + subset.append(str[index]) + combine(index + 1, str, subset, store, limit) + + subset.deleteAt(subset.length - 1) + combine(index + 1, str, subset, store, limit) + } + +} + +/** + * 341. Flatten Nested List Iterator + */ + +class NestedInteger { + + fun isInteger() = true + + fun getInteger(): Int? { + return null + } + + fun getList(): List? { + return null + } +} + +class NestedIterator(nestedList: List) { + + private val store = mutableListOf() + + init { + nestedList.forEach { + dfs(it) + } + } + + private fun dfs(obj: NestedInteger) { + val action = obj.getInteger() + if (action != null) { + store.add(action) + return + } + + obj.getList()?.forEach { + dfs(it) + } + } + + + fun next(): Int = store.removeFirst() + + fun hasNext(): Boolean = store.isNotEmpty() +} + +/** + * 900. RLE Iterator + */ + +class RLEIterator(private val encoding: IntArray) { + + private var count = 0L + + init { + for (i in encoding.indices step 2) count += encoding[i].toLong() + } + + fun next(n: Int): Int { + if (n > count) { + count = -1 + return -1 + } + + var n = n + for (i in encoding.indices step 2) { + + when { + n <= encoding[i] -> { + encoding[i] -= n + count -= n + return encoding[i + 1] + } + + else -> { + n -= encoding[i] + count -= encoding[i] + encoding[i] = 0 + } + } + } + + return 0 + } + +} + +/** + * 933. Number of Recent Calls + */ + +class RecentCounter() { + + private val queue = LinkedList() + + fun ping(t: Int): Int { + queue.offer(t) + + while (queue.peek() < t - 3000) queue.poll() + + return queue.size + } + +} + +/** + * 901. Online Stock Span + */ + +class StockSpanner() { + + private val stocks = ArrayDeque>() + + fun next(price: Int): Int { + var span = 1 + + while (stocks.isNotEmpty() && stocks.last().first <= price) span += stocks.removeLast().second + + stocks.addLast(price to span) + return span + } + } \ No newline at end of file diff --git a/contest/src/main/java/com/github/contest/dp/DpAlternativeSolution.kt b/contest/src/main/java/com/github/contest/dp/DpAlternativeSolution.kt new file mode 100644 index 00000000..7466e03f --- /dev/null +++ b/contest/src/main/java/com/github/contest/dp/DpAlternativeSolution.kt @@ -0,0 +1,23 @@ +package com.github.contest.dp + +/** + * 55. Jump Game + * Alternative Solution + * Recursion Approach + */ + +fun canJumpAltSolution(nums: IntArray): Boolean = solve(nums, 0) + +private fun solve(nums: IntArray, index: Int): Boolean { + if (index >= nums.size - 1) return true + if (nums[index] == 0 && index < nums.size - 1) return false + + var step = nums[index] + + while (step != 0) { + if (solve(nums, index + step)) return true + step-- + } + + return false +} \ No newline at end of file diff --git a/contest/src/main/java/com/github/contest/dp/DpLeetcode.kt b/contest/src/main/java/com/github/contest/dp/DpLeetcode.kt index 75368cf4..cb633014 100644 --- a/contest/src/main/java/com/github/contest/dp/DpLeetcode.kt +++ b/contest/src/main/java/com/github/contest/dp/DpLeetcode.kt @@ -582,6 +582,46 @@ fun mostPointsDp(questions: Array): Long { return dp[0] } +/** + * 55. Jump Game + */ + +fun canJump(nums: IntArray): Boolean { + var prev = nums[0] + + for (i in 1 until nums.size) { + if (prev - 1 < 0) return false + prev = maxOf(prev - 1, nums[i]) + } + + return true +} + +/** + * 45. Jump Game II + */ + +fun jump(nums: IntArray): Int { + var jumps = 0 + var currentEnd = 0 + var farthest = 0 + + for (i in 0 until nums.size - 1) { + farthest = maxOf(farthest, i + nums[i]) + + if (i == currentEnd) { + jumps++ + currentEnd = farthest + + if (currentEnd >= nums.size - 1) { + break + } + } + } + + return jumps +} + diff --git a/contest/src/main/java/com/github/contest/hashTable/HashTableAlternativeSolution.kt b/contest/src/main/java/com/github/contest/hashTable/HashTableAlternativeSolution.kt index e720e671..aedd7827 100644 --- a/contest/src/main/java/com/github/contest/hashTable/HashTableAlternativeSolution.kt +++ b/contest/src/main/java/com/github/contest/hashTable/HashTableAlternativeSolution.kt @@ -45,4 +45,101 @@ fun countBadPairsAltSolution(nums: IntArray): Long { class Counter { var count: Int = 0 -} \ No newline at end of file +} + +/** + * 2537. Count the Number of Good Subarrays + * Alternative Solution Optimal + * Hash Map Approach + */ + +fun countGoodAlternativeSolution(nums: IntArray, k: Int): Long { + var left = 0 + var count = 0L + var totalPairs = 0L + val freq = mutableMapOf() + + for (right in nums.indices) { + + val num = nums[right] + val currentFreq = freq.getOrDefault(num, 0) + + totalPairs += currentFreq + freq[num] = currentFreq + 1 + + + while (totalPairs >= k) { + val leftNum = nums[left] + + totalPairs -= freq[leftNum]!! - 1 + freq[leftNum] = freq[leftNum]!! - 1 + if (freq[leftNum] == 0) { + freq.remove(leftNum) + } + left++ + } + + + count += left + } + + return count +} + +/** + * 2094. Finding 3-Digit Even Numbers + */ + +fun findEvenNumbersAlternativeSolution(digits: IntArray): IntArray { + val freq = IntArray(10) + digits.forEach { freq[it]++ } + + val result = mutableListOf() + + for (h in 1..9) { + if (freq[h] == 0) continue + + for (t in 0..9) { + if (freq[t] == 0 || (t == h && freq[t] < 2)) continue + + for (u in 0..8 step 2) { + if (freq[u] == 0) continue + if (u == h && u == t && freq[u] < 3) continue + if (u == h && freq[u] < 2) continue + if (u == t && freq[u] < 2) continue + + result.add(h * 100 + t * 10 + u) + } + } + } + + return result.sorted().toIntArray() +} + +/** + * 2131. Longest Palindrome by Concatenating Two Letter Words + */ + +fun longestPalindromeAlternativeSolution(words: Array): Int { + val freq = words.groupingBy { it }.eachCount().toMutableMap() + var len = 0 + var centralPair = 0 + + for ((word, count) in freq) { + if (word[0] == word[1]) { + if (count % 2 == 0) { + len += (count * 2) + } else { + len += (count - 1) * 2 + centralPair = 2 + } + } else { + val mirror = "${word[1]}${word[0]}" + val minPairs = minOf(count, freq.getOrDefault(mirror, 0)) + len += (minPairs * 4) + freq[word] = 0 + } + } + + return len + centralPair +} diff --git a/contest/src/main/java/com/github/contest/hashTable/HashTableLeetcode.kt b/contest/src/main/java/com/github/contest/hashTable/HashTableLeetcode.kt index 8647bbc5..c2c2578a 100644 --- a/contest/src/main/java/com/github/contest/hashTable/HashTableLeetcode.kt +++ b/contest/src/main/java/com/github/contest/hashTable/HashTableLeetcode.kt @@ -331,4 +331,306 @@ fun isAnagram(s: String, t: String): Boolean { } return true -} \ No newline at end of file +} + +/** + * 2537. Count the Number of Good Subarrays + * TLE Approach + */ + +fun countGood(nums: IntArray, k: Int): Long { + if (nums.hasSingle()) return 0L + + var count = 0L + var left = 0 + + while (left < nums.size) { + var right = left + 1 + while (right < nums.size) { + var localCounter = 0 + for (i in left..right) { + for (j in i + 1..right) { + if (nums[i] == nums[j]) localCounter++ + } + } + if (localCounter >= k) count++ + right++ + } + left++ + } + + return count +} + +private fun IntArray.hasSingle() = when { + this.size == 1 -> true + else -> false +} + + +/** + * 169. Majority Element + */ + +fun majorityElement(nums: IntArray): Int { + var majority = 0 + var res = 0 + val target = nums.size / 2 + + nums.forEach { + if (majority == 0) res = it + majority += when { + it == res -> 1 + else -> -1 + } + } + + return res +} + +/** + * 2176. Count Equal and Divisible Pairs in an Array + */ + +fun countPairs(nums: IntArray, k: Int): Int { + if (nums.size < 2) return 0 + + val store = mutableMapOf>() + var count = 0 + + for (i in nums.indices) { + val num = nums[i] + if (store.contains(num)) { + val indexed = store.getOrDefault(num, mutableListOf()) + for (index in indexed) { + if ((index * i) % k == 0) count++ + } + indexed.add(i) + store[num] = indexed + } else store[num] = mutableListOf(i) + } + + return count +} + +/** + * 2799. Count Complete SubArrays in an Array + */ + +fun countCompleteSubArrays(nums: IntArray): Int { + if (nums.size == 1) return 1 + + var count = 0 + val distinct = distinctElementsOfArray(nums) + var lastIndex = nums.size - 1 + + for (i in nums.indices) { + var j = i + val set = mutableSetOf() + + while (j < nums.size && set.size != distinct) { + set.add(nums[j]) + j++ + } + j-- + if (set.size == distinct) count += (lastIndex - j) + 1 + } + + return count + +} + +private fun distinctElementsOfArray(nums: IntArray): Int { + val set = mutableSetOf() + for (num in nums) set.add(num) + return set.size +} + +/** + * 12. Integer to Roman + */ + +fun intToRoman(num: Int): String { + val values = listOf( + 1000 to "M", + 900 to "CM", + 500 to "D", + 400 to "CD", + 100 to "C", + 90 to "XC", + 50 to "L", + 40 to "XL", + 10 to "X", + 9 to "IX", + 5 to "V", + 4 to "IV", + 1 to "I" + ) + var n = num + val result = StringBuilder() + for ((value, symbol) in values) { + while (n >= value) { + result.append(symbol) + n -= value + } + } + return result.toString() +} + +/** + * 1128. Number of Equivalent Domino Pairs + */ + +fun numEquivDominoPairs(dominoes: Array): Int { + var count = 0 + val pairs = mutableMapOf, Int>() + + for (domino in dominoes) { + val base = Pair(domino[0], domino[1]) + val reversed = Pair(domino[1], domino[0]) + + when { + !pairs.contains(base) && !pairs.contains(reversed) -> pairs[base] = + pairs.getOrDefault(base, 0) + 1 + + pairs.contains(base) -> { + count += pairs.getOrDefault(base, 0) + pairs[base] = pairs.getOrDefault(base, 0) + 1 + } + + else -> { + count += pairs.getOrDefault(reversed, 0) + pairs[reversed] = pairs.getOrDefault(reversed, 0) + 1 + } + } + } + + return count +} + +/** + * 2062. Count Vowel Substrings of a String + */ + +fun countVowelSubstrings(word: String): Int { + var count = 0 + val vowels = setOf('a', 'e', 'i', 'o', 'u') + + for (i in word.indices) { + val seen = mutableSetOf() + for (j in i until word.length) { + val char = word[j] + if (char !in vowels) break + seen.add(char) + if (seen.size == 5) count++ + } + } + + return count +} + +/** + * 2094. Finding 3-Digit Even Numbers + */ + + +fun findEvenNumbers(digits: IntArray): IntArray { + val result = mutableSetOf() + val n = digits.size + + for (i in 0 until n) { + if (digits[i] == 0) continue + + for (j in 0 until n) { + if (j == i) continue + + for (k in 0 until n) { + + if (k == i || k == j || digits[k] % 2 != 0) continue + + val num = digits[i] * 100 + digits[j] * 10 + digits[k] + result.add(num) + } + } + } + + return result.sorted().toIntArray() +} + +/** + * 2131. Longest Palindrome by Concatenating Two Letter Words + */ + +fun longestPalindrome(words: Array): Int { + var len = 0 + val freq = mutableMapOf() + + for (origin in words) { + val reverse = "${origin[1]}${origin[0]}" + + when { + origin == reverse -> { + if (freq.contains(origin)) { + len += 4 + freq.remove(origin) + } else freq[origin] = freq.getOrDefault(origin, 0) + 1 + } + + freq.contains(reverse) -> { + freq[reverse] = freq.getOrDefault(reverse, 0) - 1 + len += 4 + if (freq[reverse] == 0) freq.remove(reverse) + } + + else -> freq[origin] = freq.getOrDefault(origin, 0) + 1 + } + } + + for ((key, value) in freq) { + if ((key[0] == key[1]) && value == 1) { + len += 2 + break + } + } + + return len +} + +/** + * 594. Longest Harmonious Subsequence + */ + +fun findLHS(nums: IntArray): Int { + val freq = nums.toList().groupingBy { it }.eachCount() + var longest = 0 + + for ((key, value) in freq) { + val more = key + 1 + if (freq.contains(more)) { + longest = maxOf(longest, freq.getOrDefault(more, 0) + value) + } + } + + return longest +} + +/** + * 3442. Maximum Difference Between Even and Odd Frequency I + */ + +fun maxDifference(s: String): Int { + var odd = 0 + var even = Int.MAX_VALUE + val alpha = IntArray(26) + + for (char in s) { + alpha[char - 'a']++ + } + + for (i in 0 until 26) { + if (alpha[i] % 2 != 0) odd = maxOf(odd, alpha[i]) + else if (alpha[i] != 0) even = minOf(even, alpha[i]) + } + + return odd - even +} diff --git a/contest/src/main/java/com/github/contest/hashTable/HashTableProdVariant.kt b/contest/src/main/java/com/github/contest/hashTable/HashTableProdVariant.kt index 5245dcdb..3aef8a92 100644 --- a/contest/src/main/java/com/github/contest/hashTable/HashTableProdVariant.kt +++ b/contest/src/main/java/com/github/contest/hashTable/HashTableProdVariant.kt @@ -7,15 +7,14 @@ package com.github.contest.hashTable */ -fun areAlmostEqualProdVariant(s1: String, s2: String): Boolean = - when { - s1 == s2 -> true - s1.length != s2.length -> false - else -> s1.zip(s2).withIndex().filter { it.value.first != it.value.second }.map { it.index } - .let { diff -> - diff.size == 2 && s1[diff[0]] == s2[diff[1]] && s1[diff[1]] == s2[diff[0]] - } - } +fun areAlmostEqualProdVariant(s1: String, s2: String): Boolean = when { + s1 == s2 -> true + s1.length != s2.length -> false + else -> s1.zip(s2).withIndex().filter { it.value.first != it.value.second }.map { it.index } + .let { diff -> + diff.size == 2 && s1[diff[0]] == s2[diff[1]] && s1[diff[1]] == s2[diff[0]] + } +} /** * 2965. Find Missing and Repeated Values @@ -48,3 +47,138 @@ fun findMissingAndRepeatedValuesProdVariant(grid: Array): IntArray { } +/** + * 2799. Count Complete Subarrays in an Array + * Prod Variant + */ + +fun countCompleteSubArrayProdVariant(nums: IntArray): Int { + val unique = nums.distinct().size + var count = 0 + val freq = mutableMapOf() + var left = 0 + val n = nums.size + + nums.forEachIndexed { right, num -> + freq[num] = freq.getOrDefault(num, 0) + 1 + + while (freq.size == unique) { + count += n - right + val delete = nums[left] + freq[delete] = freq.getOrDefault(delete, 0) - 1 + if (freq[delete] == 0) freq.remove(delete) + left++ + } + } + + return count +} + +/** + * 12. Integer to Roman + * Prod Variant + */ + +fun intToRomanProdVariant(num: Int): String { + val values = mapOf( + 1000 to "M", + 900 to "CM", + 500 to "D", + 400 to "CD", + 100 to "C", + 90 to "XC", + 50 to "L", + 40 to "XL", + 10 to "X", + 9 to "IX", + 5 to "V", + 4 to "IV", + 1 to "I" + ) + var n = num + return when { + values.contains(num) -> values.getOrDefault(num, "") + else -> buildString { + values.forEach { (value, symbol) -> + while (n >= value) { + append(symbol) + n -= value + } + } + } + } +} + +/** + * 1128. Number of Equivalent Domino Pairs + */ + +fun numEquivDominoPairsProdVariant(dominoes: Array): Int = + dominoes.map { (a, b) -> if (a <= b) a to b else b to a } + .groupingBy { it } + .eachCount() + .values + .sumOf { count -> count * (count - 1) / 2 } + +/** + * 2062. Count Vowel Substrings of a String + * Prod Variant + */ + +fun countVowelSubstringProdVariant(word: String): Int = word.indices.sumOf { i -> + val seen = mutableSetOf() + word.substring(i).takeWhile { it in "aeiou" }.count { + seen.add(it) + seen.size == 5 + } +} + + +/** + * 2062. Count Vowel Substrings of a String + * Prod Variant III + */ + +fun countVowelSubstringsProdVariantIII(word: String) = sequence { + word.forEachIndexed { i, _ -> + val seen = mutableSetOf() + word.asSequence().drop(i) + .takeWhile { it in "aeiou" } + .forEach { c -> + seen += c + if (seen.size == 5) yield(1) + } + } +}.sum() + +/** + * 594. Longest Harmonious Subsequence + * Prod Variant + */ + +fun findLHSProdVariant(nums: IntArray): Int = + nums.toList().groupingBy { it }.eachCount().let { map -> + map.maxOf { (num, value) -> + val more = num + 1 + if (map.contains(more)) { + map.getOrDefault(num, 0) + value + } else 0 + } + } + +fun findLHSProdVariantII(nums: IntArray): Int { + val freq = nums.groupBy { it }.mapValues { it.value.size } + + return freq.asSequence() + .flatMap { (key, _) -> + sequenceOf( + key to (key + 1), // Check next number + key to (key - 1) // Also check previous number (optional) + ) + } + .filter { (_, adjacent) -> freq.containsKey(adjacent) } + .maxOfOrNull { (key, adjacent) -> freq[key]!! + freq[adjacent]!! } + ?: 0 +} + + diff --git a/contest/src/main/java/com/github/contest/math/MathLeetcode.kt b/contest/src/main/java/com/github/contest/math/MathLeetcode.kt index 39ac2eac..669d5e58 100644 --- a/contest/src/main/java/com/github/contest/math/MathLeetcode.kt +++ b/contest/src/main/java/com/github/contest/math/MathLeetcode.kt @@ -132,6 +132,31 @@ fun countSymmetricIntegers(low: Int, high: Int): Int { return count } +/** + * 1399. Count Largest Group + */ + +fun countLargestGroup(n: Int): Int { + val freq = IntArray(40) + var maxCount = 0 + + for (i in 1..n) { + var sum = 0 + var x = i + while (x > 0) { + sum += x % 10 + x /= 10 + } + freq[sum]++ + maxCount = maxOf(maxCount, freq[sum]) + } + + var groupCount = 0 + for (count in freq) if (count == maxCount) groupCount++ + + return groupCount +} + /** * */ @@ -166,3 +191,43 @@ fun numberOfPowerfulInt(start: Long, finish: Long, limit: Int, s: String): Long return if (s.toLong() in start..finish) counter + 1L else counter } + +/** + * 1295. Find Numbers with Even Number of Digits + */ + +val POW = intArrayOf(100_000, 10_000, 1_000, 100, 10, 1) + +fun findNumbers(nums: IntArray): Int = nums.filter { + isEven(it) +}.count() + +private fun isEven(num: Int): Boolean { + var even = true + + for (p in POW) { + if (num >= p) break + even = !even + } + + return even +} + +/** + * 3024. Type of Triangle + */ + +fun triangleType(nums: IntArray): String { + nums.sort() + val first = nums.first() + val mid = nums[nums.size / 2] + val last = nums.last() + + return when { + first + mid <= last -> "none" + first == mid && mid == last -> "equilateral" + first == mid || mid == last -> "isosceles" + else -> "scalene" + } +} + diff --git a/contest/src/main/java/com/github/contest/priorityqueue/PriorityQueueProdVariant.kt b/contest/src/main/java/com/github/contest/priorityqueue/PriorityQueueProdVariant.kt index 2869c722..a03b51fa 100644 --- a/contest/src/main/java/com/github/contest/priorityqueue/PriorityQueueProdVariant.kt +++ b/contest/src/main/java/com/github/contest/priorityqueue/PriorityQueueProdVariant.kt @@ -6,7 +6,7 @@ package com.github.contest.priorityqueue fun topKFrequentProdVariant(nums: IntArray, k: Int): IntArray { val freq = mutableMapOf() - val repeated = Array>(nums.size + 1) {mutableListOf()} + val repeated = Array>(nums.size + 1) { mutableListOf() } for (num in nums) freq[num] = freq.getOrDefault(num, 0) + 1 @@ -14,5 +14,5 @@ fun topKFrequentProdVariant(nums: IntArray, k: Int): IntArray { repeated[count].add(num) } - return repeated.flatMap {it}.takeLast(k).toIntArray() + return repeated.flatMap { it }.takeLast(k).toIntArray() } \ No newline at end of file diff --git a/contest/src/main/java/com/github/contest/slidingWindow/SlidingWindowAlternativeSolution.kt b/contest/src/main/java/com/github/contest/slidingWindow/SlidingWindowAlternativeSolution.kt index 7c2747ab..94607a0a 100644 --- a/contest/src/main/java/com/github/contest/slidingWindow/SlidingWindowAlternativeSolution.kt +++ b/contest/src/main/java/com/github/contest/slidingWindow/SlidingWindowAlternativeSolution.kt @@ -49,4 +49,93 @@ fun minWindowOptimumSolution(s: String, t: String): String { } return if (minLength == Int.MAX_VALUE) "" else s.substring(minStart, minStart + minLength) -} \ No newline at end of file +} + +/** + * 2760. Longest Even Odd Subarray With Threshold + * Alternative Solution with O(n) Time Complexity + */ + +fun longestAlternatingSubArrayAlternativeSolution(nums: IntArray, threshold: Int): Int { + var maxLength = 0 + var currentLength = 0 + + for (i in nums.indices) { + + if (nums[i] <= threshold && + (currentLength == 0 && isEven(nums[i]) || currentLength > 0 && nums[i] % 2 != nums[i - 1] % 2) + ) { + currentLength++ + maxLength = maxOf(maxLength, currentLength) + } else currentLength = if (nums[i] % 2 == 0 && nums[i] <= threshold) 1 else 0 + + } + + return maxLength +} + +private fun isEven(number: Int) = when { + number % 2 == 0 -> true + else -> false +} + +/** + * 2653. Sliding Subarray Beauty + * Alternative Solution (TLE) must be classic sliding window + */ + +fun getSubArrayBeautyAlternativeSolution(nums: IntArray, k: Int, x: Int): IntArray { + var numbers = IntArray(101) + val res = mutableListOf() + + nums.toList().windowed(k) { + it.forEach { elem -> + val value = elem + 50 + numbers[value]++ + } + var cnt = 0 + + for (i in numbers.indices) { + if (numbers[i] > 0) cnt += numbers[i] + if (cnt >= x) { + if (i >= 50) res.add(0) else res.add(-(50 - i)) + break + } + } + + numbers = IntArray(101) + } + + return res.toIntArray() +} + +/** + * 413. Arithmetic Slices + * Alternative Solution with O(n) + */ + +fun numberOfArithmeticSlicesAlternativeSolution(nums: IntArray): Int { + if (nums.size < 3) return 0 + + var left = 0 + var count = 0 + val k = 3 + var diff = nums[1] - nums[0] + + for (right in 2 until nums.size) { + + if (nums[right] - nums[right - 1] != diff) { + diff = nums[right] - nums[right - 1] + left = right - 1 + } + + if (right - left >= k - 1) { + count++ + count += ((right - left) - (k - 1)) + } + } + + return count +} + + diff --git a/contest/src/main/java/com/github/contest/slidingWindow/SlidingWindowLeetcode.kt b/contest/src/main/java/com/github/contest/slidingWindow/SlidingWindowLeetcode.kt index 915681b5..701eaf1f 100644 --- a/contest/src/main/java/com/github/contest/slidingWindow/SlidingWindowLeetcode.kt +++ b/contest/src/main/java/com/github/contest/slidingWindow/SlidingWindowLeetcode.kt @@ -1,5 +1,8 @@ package com.github.contest.slidingWindow +import java.util.TreeSet + + /** * 76. Minimum Window Substring */ @@ -53,4 +56,721 @@ private fun checkUniqueAnswer(store: MutableMap, cache: MutableMap): List { + val res = mutableListOf() + val totalLen = words[0].length * words.size + val wordLen = words[0].length + val store = mutableMapOf() + + if (totalLen > s.length) return res + + for (word in words) store[word] = store.getOrDefault(word, 0) + 1 + + var left = 0 + + for (right in s.indices) { + if (right - left == totalLen - 1) { + val str = s.substring(left, right + 1) + if (isValidWord(str, store, wordLen)) res.add(left) + left++ + } + } + + return res +} + +private fun isValidWord(s: String, map: Map, window: Int): Boolean { + val seen = mutableMapOf() + var left = 0 + + for (right in s.indices) { + if (right - left == window - 1) { + val str = s.substring(left, right + 1) + seen[str] = seen.getOrDefault(str, 0) + 1 + left = right + 1 + } + } + + return when { + equalsMap(seen, map) -> true + else -> false + } +} + +private fun equalsMap(comparable: Map, base: Map): Boolean { + + for ((str, count) in comparable) { + if (!base.contains(str)) return false + else { + val amount = base[str] + if (amount != count) return false + } + } + + return true +} + +/** + * 2962. Count Subarrays Where Max Element Appears at Least K Times + */ + +fun countSubArrayWithMaxElement(nums: IntArray, k: Int): Long { + val maxNum = nums.maxOrNull() ?: return 0 + var count = 0L + var left = 0 + var maxCount = 0 + + for (right in nums.indices) { + if (nums[right] == maxNum) { + maxCount++ + } + + + while (maxCount >= k) { + count += nums.size - right + if (nums[left] == maxNum) { + maxCount-- + } + left++ + } + } + + return count +} + +/** + * 209. Minimum Size Subarray Sum + */ + +fun minSubArrayLen(target: Int, nums: IntArray): Int { + var minLen = Int.MAX_VALUE + var sum = 0 + var left = 0 + var currentLen = 0 + + for (element in nums) { + sum += element + currentLen++ + if (sum >= target) { + minLen = minOf(minLen, currentLen) + var localLen = minLen + while (sum >= target) { + if (sum == target) break + if (localLen == 1) return 1 + if (sum - nums[left] < target) break + else { + sum -= nums[left] + localLen-- + left++ + } + } + minLen = minOf(minLen, localLen) + currentLen = minOf(currentLen, localLen) + } + + + if (currentLen == minLen) { + sum -= nums[left] + left++ + currentLen-- + } + } + + return when { + minLen == Int.MAX_VALUE -> 0 + else -> minLen + } +} + +/** + * 992. Subarrays with K Different Integers + */ + +fun subArraysWithKDistinct(nums: IntArray, k: Int): Int { + return atMostK(nums, k) - atMostK(nums, k - 1) +} + +private fun atMostK(nums: IntArray, k: Int): Int { + var count = 0 + val freq = mutableMapOf() + var left = 0 + + for (right in nums.indices) { + val num = nums[right] + freq[num] = freq.getOrDefault(num, 0) + 1 + + while (freq.size > k) { + val leftNum = nums[left] + freq[leftNum] = freq[leftNum]!! - 1 + if (freq[leftNum] == 0) { + freq.remove(leftNum) + } + left++ + } + + count += right - left + 1 + } + + return count +} + +/** + * 2062. Count Vowel Substrings of a String + */ + +fun countVowelSubstrings(word: String): Int { + if (word.length < 5) return 0 + + var count = 0 + val k = 5 + val vowels = "aeiou" + + for (window in k..word.length) { + var left = 0 + val freq = mutableMapOf() + + for (right in 0 until word.length) { + freq[word[right]] = freq.getOrDefault(word[right], 0) + 1 + + if (right - left == window - 1) { + var isValid = true + + for ((key, _) in freq) { + if (!isVowel(key)) { + isValid = false + break + } + } + + for (vowel in vowels) { + if (!freq.contains(vowel)) { + isValid = false + break + } + } + + if (isValid) count++ + + freq[word[left]] = freq.getOrDefault(word[left], 0) - 1 + if (freq[word[left]] == 0) freq.remove(word[left]) + left++ + } + } + } + + return count +} + +private fun isVowel(char: Char) = when { + char in "aeiou" -> true + else -> false +} + +/** + * 3364. Minimum Positive Sum Subarray + */ + +fun minimumSumSubarray(nums: List, l: Int, r: Int): Int { + val minSums = mutableListOf() + return TODO("Make this method") +} + +/** + * 187. Repeated DNA Sequences + */ + +fun findRepeatedDnaSequences(s: String): List { + if (s.length < 10) return listOf() + + val dnas = s.windowed(10).map { it }.groupingBy { it }.eachCount() + val res = mutableListOf() + + for ((key, value) in dnas) { + if (value > 1) res.add(key) + } + + + return res +} + +/** + * 1044. Longest Duplicate Substring + */ + +fun longestDupSubstring(s: String): String { + if (s.length == 2 && s[0] == s[1]) return "${s[0]}" + + var left = 1 + var right = s.length + var maxLen = 0 + var res = "" + + while (left < right) { + + val window = (left + right) / 2 + + if (window == maxLen) return res + + val check = findDuplicate(s, window) + + if (check != null) { + left = window + maxLen = window + res = check + } else right = window + } + + return res +} + + +private fun findDuplicate(s: String, length: Int): String? { + val base = 26 + val mod = 1_000_000_007 + var hash = 0L + var power = 1L + val seen = HashMap>() + + + for (i in 0 until length - 1) { + power = (power * base) % mod + } + + + for (i in 0 until length) { + hash = (hash * base + (s[i] - 'a')) % mod + } + seen.getOrPut(hash) { mutableListOf() }.add(0) + + + for (i in 1..s.length - length) { + + hash = (hash - (s[i - 1] - 'a') * power % mod + mod) % mod + + hash = (hash * base + (s[i + length - 1] - 'a')) % mod + + + if (seen.containsKey(hash)) { + val currentSub = s.substring(i, i + length) + for (start in seen[hash]!!) { + if (s.substring(start, start + length) == currentSub) { + return currentSub + } + } + seen[hash]!!.add(i) + } else { + seen[hash] = mutableListOf(i) + } + } + + return null +} + +/** + * 1763. Longest Nice Substring + */ + +fun longestNiceSubstring(s: String): String { + if (s.hasSingle()) return "" + + + (s.length downTo 2).forEach { window -> + s.windowed(window).forEach { + if (it.isNice()) return it + } + + } + + return emptyString() +} + +private fun String.isNice(): Boolean { + val set = mutableSetOf() + + for (char in this) { + set.add(char) + } + + for (char in this) { + if (char !in 'A'..'Z') { + if (!set.contains(char.uppercaseChar())) return false + } else { + if (!set.contains(char.lowercaseChar())) return false + } + } + + return true +} + +private fun emptyString() = "" + +private fun String.hasSingle() = when { + length == 1 -> true + else -> false +} + +/** + * 2653. Sliding SubArray Beauty + */ + +fun getSubArrayBeauty(nums: IntArray, k: Int, x: Int): IntArray { + val map = mutableMapOf() + val res = IntArray(nums.size - k + 1) + var left = 0 + val window = TreeSet() + + for (right in nums.indices) { + map[nums[right]] = map.getOrDefault(nums[right], 0) + 1 + window.add(nums[right]) + + if (right - left == k - 1) { + var cnt = 0 + var beauty = 0 + + for (num in window) { + cnt += map[num]!! + if (cnt >= x) { + beauty = if (num < 0) num else 0 + break + } + } + + res[left] = beauty + map[nums[left]] = map.getOrDefault(nums[left], 0) - 1 + if (map[nums[left]] == 0) { + map.remove(nums[left]) + window.remove(nums[left]) + } + left++ + } + } + + return res +} + +/** + * 2760. Longest Even Odd Subarray With Threshold + */ + +fun longestAlternatingSubarray(nums: IntArray, threshold: Int): Int { + var longest = 0 + + (nums.size downTo 1).forEach { window -> + nums.toList().windowed(window) { + if (isValid(it, threshold)) { + longest = window + return@windowed + } + } + if (longest > 0) return longest + } + + return longest +} + +private fun isValid(window: List, threshold: Int): Boolean { + return when { + window.isEmpty() -> false + window.first() % 2 != 0 -> false + else -> { + + for (i in 0..window.size - 2) { + if (window[i] % 2 == window[i + 1] % 2) { + return false + } + } + + for (element in window) { + if (element > threshold) { + return false + } + } + + return true + } + } +} + +/** + * 1052. Grumpy Bookstore Owner + */ + +fun maxSatisfied(customers: IntArray, grumpy: IntArray, minutes: Int): Int { + var notGrumpy = 0 + var maxCustomers = 0 + var left = 0 + var sum = 0 + + for (i in customers.indices) { + if (grumpy[i] == 0) notGrumpy += customers[i] + } + + + for (right in customers.indices) { + if (grumpy[right] == 1) sum += customers[right] + + if (right - left == minutes - 1) { + maxCustomers = maxOf(maxCustomers, notGrumpy + sum) + if (grumpy[left] == 1) sum -= customers[left] + left++ + } + } + + return maxCustomers +} + +/** + * 3090. Maximum Length Substring With Two Occurrences + */ + +fun maximumLengthSubstring(s: String): Int { + if (s.length == 2) return 2 + + var maxLen = 0 + var left = 0 + val freq = mutableMapOf() + + for (right in s.indices) { + + val char = s[right] + freq[char] = freq.getOrDefault(char, 0) + 1 + + if (!isValidSubString(freq)) { + freq[s[left]] = freq.getOrDefault(s[left], 0) - 1 + if (freq[s[left]] == 0) freq.remove(s[left]) + left++ + } + + maxLen = maxOf(maxLen, right - left + 1) + } + + return maxLen +} + +private fun isValidSubString(map: Map): Boolean { + + for ((_, value) in map) { + if (value > 2) return false + } + + return true +} + +/** + * 2398. Maximum Number of Robots Within Budget + */ + +fun maximumRobots(chargeTimes: IntArray, runningCosts: IntArray, budget: Long): Int { + var maxRobots = 0 + var left = 0 + var sum = 0L + val window = mutableListOf() + + for (right in chargeTimes.indices) { + window.add(chargeTimes[right].toLong()) + sum += runningCosts[right].toLong() + var max = window.maxOrNull() ?: 0L + var k = (right - left + 1).toLong() + var cost = max + (k * sum) + + while (cost > budget) { + sum -= runningCosts[left] + window.removeFirst() + left++ + max = window.maxOrNull() ?: 0L + k = (right - left + 1).toLong() + cost = max + (k * sum) + } + + maxRobots = maxOf(maxRobots, right - left + 1) + } + + return maxRobots +} + +/** + * 413. Arithmetic Slices + */ + +fun numberOfArithmeticSlices(nums: IntArray): Int { + if (nums.size < 3) return 0 + + var count = 0 + + (3..nums.size).forEach { window -> + nums.toList().windowed(window) { + var isValid = true + val diff = it[1] - it[0] + + for (i in 2 until it.size) { + if (it[i] - it[i - 1] != diff) { + isValid = false + break + } + } + + if (isValid) count++ + } + } + + return count +} + +/** + * 3206. Alternating Groups I + */ + +fun numberOfAlternatingGroups(colors: IntArray): Int { + var groups = 0 + var left = 0 + val k = 3 + var prevColor = colors[0] + + + for (right in 1 until colors.size + 2) { + val curr = when { + right >= colors.size -> colors[right - colors.size] + else -> colors[right] + } + + if (prevColor == curr) { + left = right + } + + prevColor = curr + + if (right - left == k - 1) { + groups++ + left++ + } + } + + return groups +} + +/** + * 1652. Defuse the Bomb + */ + +fun decrypt(code: IntArray, k: Int): IntArray = when { + k == 0 -> IntArray(code.size) + k > 0 -> { + val res = IntArray(code.size) + for (i in code.indices) { + var sum = 0 + var right = i + 1 + var k = k + + while (k != 0) { + sum += when { + right >= code.size -> code[right - code.size] + else -> code[right] + } + right++ + k-- + } + + res[i] = sum + } + res + } + + else -> { + val res = IntArray(code.size) + for (i in code.indices) { + var sum = 0 + var right = i - 1 + var k = k + + while (k < 0) { + sum += when { + right < 0 -> code[code.size + right] + else -> code[right] + } + right-- + k++ + } + + res[i] = sum + } + res + } +} + +/** + * 438. Find All Anagrams in a String + */ + +fun findAnagrams(s: String, p: String): List { + if (p.length > s.length) return listOf() + + val pattern = p.eachCount() + val store = mutableMapOf() + var left = 0 + val k = p.length + val ind = mutableListOf() + + for (right in s.indices) { + val char = s[right] + store[char] = store.getOrDefault(char, 0) + 1 + + if (right - left == k - 1) { + if (equalMaps(store, pattern)) ind.add(left) + store[s[left]] = store.getOrDefault(s[left], 0) - 1 + if (store[s[left]] == 0) store.remove(s[left]) + left++ + } + + } + + return ind +} + +private fun > equalMaps(first: Map, second: Map): Boolean { + + for ((char, count) in first) { + if (!second.contains(char) || second[char] != count) return false + } + + return true +} + +private fun String.eachCount(): MutableMap { + val count = mutableMapOf() + for (char in this) count[char] = count.getOrDefault(char, 0) + 1 + return count +} + + + + + + + diff --git a/contest/src/main/java/com/github/contest/slidingWindow/SlidingWindowProdVariant.kt b/contest/src/main/java/com/github/contest/slidingWindow/SlidingWindowProdVariant.kt index 0cac09ab..6ec79651 100644 --- a/contest/src/main/java/com/github/contest/slidingWindow/SlidingWindowProdVariant.kt +++ b/contest/src/main/java/com/github/contest/slidingWindow/SlidingWindowProdVariant.kt @@ -1,5 +1,158 @@ package com.github.contest.slidingWindow /** - * - */ \ No newline at end of file + * 30. Substring with Concatenation of All Words + * Prod Variant + */ + +fun findSubstringProdVariant(s: String, words: Array): List { + val res = mutableListOf() + val totalLen = words[0].length * words.size + val wordLen = words[0].length + val store = mutableMapOf() + + if (totalLen > s.length) return res + + for (word in words) store[word] = store.getOrDefault(word, 0) + 1 + + var left = 0 + + for (right in s.indices) { + if (right - left == totalLen - 1) { + val str = s.substring(left, right + 1) + if (isValidWord(str, store, wordLen)) res.add(left) + left++ + } + } + + return res +} + +private fun isValidWord(s: String, map: Map, window: Int): Boolean { + val seen = mutableMapOf() + + s.windowed(window, window) { + seen[it.toString()] = seen.getOrDefault(it, 0) + 1 + } + + return when { + equalsMap(seen, map) -> true + else -> false + } +} + +private fun equalsMap(comparable: Map, base: Map): Boolean { + + for ((str, count) in comparable) { + when { + !base.contains(str) || base[str] != count -> return false + else -> continue + } + } + + return true +} + + +/** + * Prod Variant with More Kotlin Sugar + */ + +fun findSubstringProdVariantII(s: String, words: Array): List { + val wordLength = words.first().length + val totalLength = wordLength * words.size + + if (s.length < totalLength) return listOf() + + val wordCount = words.groupingBy { it }.eachCount() + + + return (0..s.length - totalLength).filter { start -> + val seen = mutableMapOf() + words.indices.all { i -> + val word = s.substring(start + i * wordLength, start + (i + 1) * wordLength) + wordCount.containsKey(word) && seen.merge(word, 1, Int::plus)!! <= wordCount[word]!! + } + } +} + +/** + * 3392. Count Subarrays of Length Three With a Condition + * Prod Variant + */ + +fun countSubArraysProdVariant(nums: IntArray): Int = + nums.toList().windowed(3).count { + (it.first() + it.last()).toDouble() == it[1].toDouble() / 2.0 + } + +/** + * 3364. Minimum Positive Sum Subarray + * Prod Variant + */ + +fun minimumSumSubarrayProdVariant(nums: List, l: Int, r: Int): Int = buildList { + (l..r).forEach { window -> + nums.windowed(window).map { it.sum() }.filter { it > 0 }.forEach { add(it) } + } +}.minOrNull() ?: -1 + +/** + * 187. Repeated DNA Sequences + * Prod Variant + */ + +fun findRepeatedDnaSequencesProdVariant(s: String): List = when { + s.length < 10 -> listOf() + else -> buildList { + s.windowed(10).map { it }.groupingBy { it }.eachCount().forEach { (key, value) -> + if (value > 1) add(key) + } + } +} + +/** + * 1052. Grumpy Bookstore Owner + * Prod Variant + */ + +fun maxSatisfiedProdVariant(customers: IntArray, grumpy: IntArray, minutes: Int): Int { + var notGrumpy = 0 + var maxCustomers = 0 + + customers.forEachIndexed { index, elem -> + if (grumpy[index] == 0) notGrumpy += elem + } + + + customers.withIndex().windowed(minutes) { window -> + val sum = window.sumOf { + if (grumpy[it.index] == 1) it.value + else 0 + } + + maxCustomers = maxOf(maxCustomers, notGrumpy + sum) + } + + return maxCustomers +} + +/** + * 1052. Grumpy Bookstore Owner + * Prod Variant + * Memory Limit Exceeded + */ + +fun maxSatisfiedProdVariantII(customers: IntArray, grumpy: IntArray, minutes: Int): Int = + customers.foldIndexed(0) { index, acc, value -> + if (grumpy[index] == 0) acc + value + else acc + } + customers.withIndex().windowed(minutes).map { window -> + window.sumOf { + if (grumpy[it.index] == 1) it.value + else 0 + } + + }.max() + + diff --git a/contest/src/main/java/com/github/contest/slidingWindow/customStructure/RabinKarpImpl.kt b/contest/src/main/java/com/github/contest/slidingWindow/customStructure/RabinKarpImpl.kt new file mode 100644 index 00000000..c690d1ee --- /dev/null +++ b/contest/src/main/java/com/github/contest/slidingWindow/customStructure/RabinKarpImpl.kt @@ -0,0 +1,127 @@ +package com.github.contest.slidingWindow.customStructure + + +fun rabinKarpSearch(text: String, pattern: String): List { + val d = 256 // Размер алфавита (ASCII) + val q = 101 // Простое число для избежания переполнения + val m = pattern.length + val n = text.length + var patternHash = 0 // Хеш образца + var textHash = 0 // Хеш текущего окна в тексте + var h = 1 // Значение для "скользящего" хеша: h = d^(m-1) + val result = mutableListOf() + + if (n < m || m == 0 || n == 0) return result + + // Вычисляем h = d^(m-1) % q + for (i in 0 until m - 1) { + h = (h * d) % q + } + + // Вычисляем начальные хеши для образца и первого окна текста + for (i in 0 until m) { + patternHash = (d * patternHash + pattern[i].code) % q + textHash = (d * textHash + text[i].code) % q + } + + // Проходим по тексту + for (i in 0..n - m) { + // Если хеши совпали, проверяем символы один за другим + if (patternHash == textHash) { + var match = true + for (j in 0 until m) { + if (text[i + j] != pattern[j]) { + match = false + break + } + } + if (match) { + result.add(i) + } + } + + // Вычисляем хеш для следующего окна текста + if (i < n - m) { + textHash = (d * (textHash - text[i].code * h) + text[i + m].code) % q + // Обеспечиваем положительное значение хеша + if (textHash < 0) textHash += q + } + } + + return result +} + +fun rabinKarpMultiPattern(text: String, patterns: List): Map> { + val d = 256 + val q = 101 + val result = mutableMapOf>() + val patternHashes = mutableMapOf>() + + // Предварительно вычисляем хеши всех образцов + for (pattern in patterns.distinct()) { + val patternLen = pattern.length + if (patternLen == 0 || patternLen > text.length) continue + + var hash = 0 + for (i in 0 until patternLen) { + hash = (d * hash + pattern[i].code) % q + } + + patternHashes.getOrPut(hash) { mutableListOf() }.add(pattern) + result[pattern] = mutableListOf() + } + + // Ищем все возможные длины образцов + val lengths = patterns.map { it.length }.distinct().sorted() + + for (m in lengths) { + if (m == 0 || m > text.length) continue + + var h = 1 + for (i in 0 until m - 1) { + h = (h * d) % q + } + + var textHash = 0 + // Вычисляем хеш первого окна + for (i in 0 until m) { + textHash = (d * textHash + text[i].code) % q + } + + // Проверяем первый хеш + patternHashes[textHash]?.forEach { pattern -> + if (pattern.length == m && text.startsWith(pattern, 0)) { + result[pattern]?.add(0) + } + } + + // Скользим по тексту + for (i in 1..text.length - m) { + // Обновляем хеш + textHash = (d * (textHash - text[i - 1].code * h) + text[i + m - 1].code) % q + if (textHash < 0) textHash += q + + // Проверяем совпадения + patternHashes[textHash]?.forEach { pattern -> + if (pattern.length == m && text.startsWith(pattern, i)) { + result[pattern]?.add(i) + } + } + } + } + + return result +} + +fun slidingWindowClassic(text: String, patterns: List): List { + val res = mutableListOf() + + for (pattern in patterns) { + val window = pattern.length + text.windowed(window) { + if (it == pattern) res.add(0) + } + } + + return res +} \ No newline at end of file diff --git a/contest/src/main/java/com/github/contest/strings/StringsLeetcode.kt b/contest/src/main/java/com/github/contest/strings/StringsLeetcode.kt index e11796dc..b4b6f093 100644 --- a/contest/src/main/java/com/github/contest/strings/StringsLeetcode.kt +++ b/contest/src/main/java/com/github/contest/strings/StringsLeetcode.kt @@ -338,6 +338,57 @@ private fun lastString(store: List, maxWidth: Int): String { private fun sumOfLength(store: List): Int = store.sumOf { it.length } + +/** + * 38. Count and Say + */ + +fun countAndSay(n: Int): String = when { + n == 1 -> "1" + else -> compress(countAndSay(n - 1)) +} + +private fun compress(input: String): String { + if (input.length == 1) return "11" + var res = "" + var pattern = input[0] + var count = 1 + + for (i in 1 until input.length) { + if (input[i] == pattern) { + count++ + } else { + res += "$count$pattern" + count = 1 + pattern = input[i] + } + } + + res += "$count$pattern" + + return res +} + +/** + * 58. Length of Last Word + */ + + +fun lengthOfLastWord(s: String): Int { + var i = s.length - 1 + var size = 0 + + while (i >= 0 && s[i] == ' ') i-- + + while (i >= 0 && s[i] != ' ') { + size++ + i-- + } + + return size +} + + /** * */ diff --git a/contest/src/main/java/com/github/contest/strings/StringsProdVariant.kt b/contest/src/main/java/com/github/contest/strings/StringsProdVariant.kt index f94a8152..a92aa82a 100644 --- a/contest/src/main/java/com/github/contest/strings/StringsProdVariant.kt +++ b/contest/src/main/java/com/github/contest/strings/StringsProdVariant.kt @@ -58,4 +58,11 @@ fun smallestStringProdVariant(s: String): String { } String(modifiedChars) } -} \ No newline at end of file +} + +/** + * 58. Length of Last Word + * Prod Variant + */ + +fun lengthOfLastWordProdVariant(s: String): Int = s.trim().split(" ").lastOrNull()?.length ?: 0 \ No newline at end of file diff --git a/contest/src/main/java/com/github/contest/twoPointer/TwoPointerLeetCode.kt b/contest/src/main/java/com/github/contest/twoPointer/TwoPointerLeetCode.kt index 4ef2afc6..6ea85f7d 100644 --- a/contest/src/main/java/com/github/contest/twoPointer/TwoPointerLeetCode.kt +++ b/contest/src/main/java/com/github/contest/twoPointer/TwoPointerLeetCode.kt @@ -19,4 +19,33 @@ fun compareVersion(version1: String, version2: String): Int { } } return 0 +} + +/** + * 42. Trapping Rain Water + */ + + +fun trap(height: IntArray): Int { + if (height.isEmpty()) return 0 + + var left = 0 + var right = height.size - 1 + var leftMax = height[left] + var rightMax = height[right] + var water = 0 + + while (left < right) { + if (leftMax < rightMax) { + left++ + leftMax = maxOf(leftMax, height[left]) + water += leftMax - height[left] + } else { + right-- + rightMax = maxOf(rightMax, height[right]) + water += rightMax - height[right] + } + } + + return water } \ No newline at end of file