├── CleanCode ├── .gradle │ ├── 7.4 │ │ ├── gc.properties │ │ ├── fileChanges │ │ │ └── last-build.bin │ │ ├── dependencies-accessors │ │ │ ├── gc.properties │ │ │ └── dependencies-accessors.lock │ │ ├── checksums │ │ │ └── checksums.lock │ │ ├── fileHashes │ │ │ ├── fileHashes.bin │ │ │ ├── fileHashes.lock │ │ │ └── resourceHashesCache.bin │ │ └── executionHistory │ │ │ ├── executionHistory.bin │ │ │ └── executionHistory.lock │ ├── vcs-1 │ │ └── gc.properties │ ├── buildOutputCleanup │ │ ├── cache.properties │ │ ├── outputFiles.bin │ │ └── buildOutputCleanup.lock │ └── file-system.probe ├── settings.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── build.gradle └── src │ └── test │ └── java │ └── FoodPandaTest.java ├── LeetCodeKotlin ├── gradle.properties ├── settings.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── src │ └── main │ │ └── kotlin │ │ ├── Practice.kt │ │ └── leetcode │ │ ├── utils │ │ └── TestCaseGenerator.kt │ │ ├── easy │ │ ├── math │ │ │ └── ExcelColumnNumber.kt │ │ ├── array │ │ │ └── DeleteColumnsMakeSorted.kt │ │ ├── graph │ │ │ └── PathExists.kt │ │ ├── strings │ │ │ ├── GreatestCommonDivisorStrings.kt │ │ │ └── VerifyAlienDictionary.kt │ │ └── linkedlist │ │ │ └── LinkedListCycle.kt │ │ ├── medium │ │ ├── graph │ │ │ ├── KeysAndRooms.kt │ │ │ └── FindClosestNodeGivenTwoNodes.kt │ │ ├── binarysearch │ │ │ ├── KokoEatsBanana.kt │ │ │ └── CapacityShipPackagesDays.kt │ │ ├── backtracking │ │ │ ├── LetterCasePermutation.kt │ │ │ ├── NonDecreasingSubsequence.kt │ │ │ ├── RestoreIpAddresses.kt │ │ │ └── PalindromePartitions.kt │ │ ├── array │ │ │ ├── MinRoundsCompleteTasks.kt │ │ │ └── prefixsum │ │ │ │ ├── SubarraySumEqualK.kt │ │ │ │ └── SubarraySumEqualModuloK.kt │ │ ├── linkedlist │ │ │ └── LinkedListCycleII.kt │ │ ├── dp │ │ │ ├── MaxSumCircularSubarray.kt │ │ │ ├── FlipStringMonotoneIncrease.kt │ │ │ └── BestTeamWithNoConflict.kt │ │ └── tree │ │ │ ├── FindDuplicateSubtrees.kt │ │ │ └── QuadTree.kt │ │ └── hard │ │ ├── dp │ │ ├── EditDistance.kt │ │ └── ConcatenatedWords.kt │ │ ├── misc │ │ └── NamingCompany.kt │ │ └── math │ │ └── MaxPointsLine.kt ├── build.gradle.kts └── .gitignore ├── ProblemSolving ├── practice.py ├── Hard │ ├── Trie │ │ ├── Model │ │ │ └── TrieNodeModel.py │ │ └── TriePrefixSuggestions.py │ ├── TwoEggDroppingMinFloors.py │ └── Trees │ │ ├── LCADeepestLeaves.py │ │ └── NodeDistanceByLCA.py ├── Medium │ ├── Misc │ │ └── LruCache.java │ ├── LinkedList │ │ ├── Model │ │ │ └── LinkedListNodeModel.py │ │ └── MbyNthNode.py │ ├── Recursion │ │ ├── PowerA^B.py │ │ └── kSum.py │ ├── Heap │ │ ├── TopKFrequentElements.py │ │ ├── KLargestElements.py │ │ └── ConnectRopes.py │ ├── Strings │ │ ├── CountAndSay.py │ │ └── Anagram+++.py │ ├── DP │ │ ├── UniquePaths.py │ │ ├── MinimumPathSum.py │ │ ├── LargestSquareSubMatrix.py │ │ └── TargetSumWays.py │ └── Trees │ │ └── TopView.py └── Easy │ ├── Strings │ └── CommonPrefix.py │ └── Trees │ ├── NodeLevel.py │ ├── LeafSequence.py │ └── AverageLevels.py ├── LeetCodeJava ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── src │ ├── main │ │ └── java │ │ │ ├── leetcode │ │ │ ├── concurrency │ │ │ │ ├── IntConsumer.java │ │ │ │ ├── StaticObjectLock.java │ │ │ │ ├── Deadlock.java │ │ │ │ └── FooBar.java │ │ │ ├── medium │ │ │ │ ├── linkedlist │ │ │ │ │ ├── ListNode.java │ │ │ │ │ ├── ReverseLinkedList.java │ │ │ │ │ ├── RandomNode.java │ │ │ │ │ └── ReverseLinkedListII.java │ │ │ │ ├── unionfind │ │ │ │ │ ├── ConnectedComponents.java │ │ │ │ │ ├── LexicographicallySmallestEquivalent.java │ │ │ │ │ ├── MostStonesRemoved.java │ │ │ │ │ └── AccountsMerge.java │ │ │ │ ├── misc │ │ │ │ │ └── PalindromicSubstrings.java │ │ │ │ ├── math │ │ │ │ │ ├── KthFactorOfN.java │ │ │ │ │ ├── BinomialCoefficient.java │ │ │ │ │ └── SumOfSquareNumbers.java │ │ │ │ ├── stack │ │ │ │ │ ├── MinStack.java │ │ │ │ │ ├── StockSpanner.java │ │ │ │ │ └── MinRemovesValidParentheses.java │ │ │ │ ├── sort │ │ │ │ │ ├── InsertInterval.java │ │ │ │ │ ├── SortByFrequency.java │ │ │ │ │ └── MinimumMeetingRooms.java │ │ │ │ ├── binarysearch │ │ │ │ │ └── SmallestCommonElement.java │ │ │ │ ├── dp │ │ │ │ │ ├── JumpGame.java │ │ │ │ │ ├── DominoTrominoTiling.java │ │ │ │ │ ├── JumpGameII.java │ │ │ │ │ ├── LargestDivisibleSubset.java │ │ │ │ │ ├── MinFallingPathSum.java │ │ │ │ │ ├── OutBoundaryPaths.java │ │ │ │ │ ├── LongestCommonSubsequence.java │ │ │ │ │ └── BuySellStocksCoolDown.java │ │ │ │ ├── greedy │ │ │ │ │ ├── ZigZagConversion.java │ │ │ │ │ ├── MinTimeColorfulRope.java │ │ │ │ │ └── HandOfStraights.java │ │ │ │ ├── graph │ │ │ │ │ ├── NumberOfProvinces.java │ │ │ │ │ ├── AllPathsSourceTarget.java │ │ │ │ │ └── TimeToInformAll.java │ │ │ │ ├── arrays │ │ │ │ │ ├── prefixsum │ │ │ │ │ │ ├── MinAverageDifference.java │ │ │ │ │ │ └── ContinuousSubarraySumModK.java │ │ │ │ │ └── CountGoodMeals.java │ │ │ │ ├── matrix │ │ │ │ │ ├── ImageOverlap.java │ │ │ │ │ └── WhereBallFall.java │ │ │ │ ├── trees │ │ │ │ │ ├── MaxProductSplitBinaryTree.java │ │ │ │ │ ├── MaxDiffNodeAncestor.java │ │ │ │ │ └── EvenOddTree.java │ │ │ │ ├── backtracking │ │ │ │ │ ├── WordSearch.java │ │ │ │ │ └── MaxLengthConcatenation.java │ │ │ │ └── heap │ │ │ │ │ ├── TaskScheduler.java │ │ │ │ │ └── TopKFrequent.java │ │ │ ├── easy │ │ │ │ ├── set │ │ │ │ │ └── PathCrossing.java │ │ │ │ ├── binarysearch │ │ │ │ │ ├── LongestSubsequenceLimitedSum.java │ │ │ │ │ ├── GuessNumberHigherLower.java │ │ │ │ │ └── FirstBadVersion.java │ │ │ │ ├── stack │ │ │ │ │ ├── EatLunch.java │ │ │ │ │ └── BaseBallGame.java │ │ │ │ ├── dp │ │ │ │ │ ├── MinCostClimbingStairs.java │ │ │ │ │ └── IsSubsequence.java │ │ │ │ ├── arrays │ │ │ │ │ └── GameOfLife.java │ │ │ │ └── trees │ │ │ │ │ └── SubtreeOfAnotherTree.java │ │ │ ├── hard │ │ │ │ ├── greedy │ │ │ │ │ ├── Candy.java │ │ │ │ │ └── EarliestPossibleDayOfBloom.java │ │ │ │ ├── arrays │ │ │ │ │ └── OrderlyQueue.java │ │ │ │ ├── dp │ │ │ │ │ └── ReducingDishes.java │ │ │ │ ├── heap │ │ │ │ │ └── MedianFinder.java │ │ │ │ └── backtracking │ │ │ │ │ └── UniquePathsIII.java │ │ │ └── design │ │ │ │ ├── MyHashSet.java │ │ │ │ └── PeekingIterator.java │ │ │ └── Practice.java │ └── test │ │ └── java │ │ └── interviews │ │ ├── TalabatInterviewTest.java │ │ └── GlovoInterviewTest.java ├── .gitignore └── pom.xml ├── SystemDesign ├── Medium │ ├── Instagram.py │ ├── SimCardStoreService.py │ ├── AddEventAggregation.py │ └── TypeaheadSuggestion.py ├── Hard │ └── ChatApplication.py ├── RealInterviews │ └── talabat.md └── Easy │ ├── BasicMessageQueue.py │ ├── AnagramCalculator.py │ └── BasicArchitectureBeginners.py ├── README.md └── Multithreading └── Easy └── MultiThreadedAnagram.py /CleanCode/.gradle/7.4/gc.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CleanCode/.gradle/vcs-1/gc.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CleanCode/.gradle/7.4/fileChanges/last-build.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CleanCode/.gradle/7.4/dependencies-accessors/gc.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /LeetCodeKotlin/gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.code.style=official 2 | -------------------------------------------------------------------------------- /CleanCode/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'CleanCode' 2 | 3 | -------------------------------------------------------------------------------- /LeetCodeKotlin/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | 2 | rootProject.name = "LeetCodeKotlin" 3 | 4 | -------------------------------------------------------------------------------- /ProblemSolving/practice.py: -------------------------------------------------------------------------------- 1 | if __name__ == '__main__': 2 | print("Hello World") 3 | -------------------------------------------------------------------------------- /CleanCode/.gradle/buildOutputCleanup/cache.properties: -------------------------------------------------------------------------------- 1 | #Sat Aug 20 16:19:42 ICT 2022 2 | gradle.version=7.4 3 | -------------------------------------------------------------------------------- /CleanCode/.gradle/file-system.probe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Freeze777/SDE-Interviewer-Notes/HEAD/CleanCode/.gradle/file-system.probe -------------------------------------------------------------------------------- /CleanCode/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Freeze777/SDE-Interviewer-Notes/HEAD/CleanCode/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /LeetCodeJava/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Freeze777/SDE-Interviewer-Notes/HEAD/LeetCodeJava/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /CleanCode/.gradle/7.4/checksums/checksums.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Freeze777/SDE-Interviewer-Notes/HEAD/CleanCode/.gradle/7.4/checksums/checksums.lock -------------------------------------------------------------------------------- /CleanCode/.gradle/7.4/fileHashes/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Freeze777/SDE-Interviewer-Notes/HEAD/CleanCode/.gradle/7.4/fileHashes/fileHashes.bin -------------------------------------------------------------------------------- /CleanCode/.gradle/7.4/fileHashes/fileHashes.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Freeze777/SDE-Interviewer-Notes/HEAD/CleanCode/.gradle/7.4/fileHashes/fileHashes.lock -------------------------------------------------------------------------------- /LeetCodeKotlin/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Freeze777/SDE-Interviewer-Notes/HEAD/LeetCodeKotlin/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /CleanCode/.gradle/buildOutputCleanup/outputFiles.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Freeze777/SDE-Interviewer-Notes/HEAD/CleanCode/.gradle/buildOutputCleanup/outputFiles.bin -------------------------------------------------------------------------------- /CleanCode/.gradle/7.4/fileHashes/resourceHashesCache.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Freeze777/SDE-Interviewer-Notes/HEAD/CleanCode/.gradle/7.4/fileHashes/resourceHashesCache.bin -------------------------------------------------------------------------------- /CleanCode/.gradle/7.4/executionHistory/executionHistory.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Freeze777/SDE-Interviewer-Notes/HEAD/CleanCode/.gradle/7.4/executionHistory/executionHistory.bin -------------------------------------------------------------------------------- /CleanCode/.gradle/7.4/executionHistory/executionHistory.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Freeze777/SDE-Interviewer-Notes/HEAD/CleanCode/.gradle/7.4/executionHistory/executionHistory.lock -------------------------------------------------------------------------------- /CleanCode/.gradle/buildOutputCleanup/buildOutputCleanup.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Freeze777/SDE-Interviewer-Notes/HEAD/CleanCode/.gradle/buildOutputCleanup/buildOutputCleanup.lock -------------------------------------------------------------------------------- /CleanCode/.gradle/7.4/dependencies-accessors/dependencies-accessors.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Freeze777/SDE-Interviewer-Notes/HEAD/CleanCode/.gradle/7.4/dependencies-accessors/dependencies-accessors.lock -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/concurrency/IntConsumer.java: -------------------------------------------------------------------------------- 1 | package leetcode.concurrency; 2 | 3 | class IntConsumer { 4 | public void accept(int x) { 5 | System.out.println(x); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/Practice.kt: -------------------------------------------------------------------------------- 1 | class Practice { 2 | fun solve(): String { 3 | return "Hello World!" 4 | } 5 | } 6 | 7 | fun main() { 8 | val p = Practice() 9 | println(p.solve()) 10 | } -------------------------------------------------------------------------------- /CleanCode/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /LeetCodeKotlin/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists -------------------------------------------------------------------------------- /LeetCodeJava/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.5/apache-maven-3.8.5-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar -------------------------------------------------------------------------------- /ProblemSolving/Hard/Trie/Model/TrieNodeModel.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class TrieNode: 5 | ALPHABET_SIZE: int = 256 6 | 7 | def __init__(self): 8 | self.is_word_ending: bool = False 9 | self.children: List[TrieNode] = [None] * self.ALPHABET_SIZE 10 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/Practice.java: -------------------------------------------------------------------------------- 1 | public class Practice { 2 | public Object solve() { 3 | return null; 4 | } 5 | 6 | public static void main(String[] args) { 7 | var p = new Practice(); 8 | System.out.println(p.solve()); 9 | } 10 | } 11 | 12 | 13 | -------------------------------------------------------------------------------- /CleanCode/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | } 4 | 5 | group 'org.example' 6 | version '1.0-SNAPSHOT' 7 | 8 | repositories { 9 | mavenCentral() 10 | } 11 | 12 | dependencies { 13 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' 14 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' 15 | } 16 | 17 | test { 18 | useJUnitPlatform() 19 | } -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/utils/TestCaseGenerator.kt: -------------------------------------------------------------------------------- 1 | package leetcode.utils 2 | 3 | fun randomIntList(size: Int, min: Int, max: Int): List { 4 | val list = mutableListOf() 5 | val range = (min..max) 6 | for (i in 0 until size) list.add(range.random()) 7 | return list 8 | } 9 | fun randomIntArray(size: Int, min: Int, max: Int) = randomIntList(size, min, max).toIntArray() 10 | 11 | fun main() { 12 | println(randomIntArray(15, -10, 10)) 13 | } 14 | -------------------------------------------------------------------------------- /SystemDesign/Medium/Instagram.py: -------------------------------------------------------------------------------- 1 | """ 2 | - user registration and login 3 | - user can create post 4 | - user can follow other users 5 | - user can like, comment on post of users he follow 6 | - news feed where user can see other users post 7 | """ 8 | 9 | """ 10 | 11 | scale : 1 billion users, 400 million active users per day 12 | 13 | """ 14 | 15 | """ 16 | sql - user info 17 | nosql - user feeds, activities 18 | memcache - caching 19 | app server 20 | kafka/rabbit - notifications 21 | 22 | """ 23 | 24 | -------------------------------------------------------------------------------- /SystemDesign/Medium/SimCardStoreService.py: -------------------------------------------------------------------------------- 1 | """ 2 | Design a sim card store system that gives you 3 sim cards on demand each of which has a 10 digit long phone number. 3 | - The generated numbers should be very hard to predict. 4 | - We need to keep track of the phone numbers that are sold out and also the total unused numbers the system has at any point of time. 5 | - Phone numbers should be stored very efficiently and retrieval of available phone numbers should be fast. 6 | 7 | """ 8 | 9 | """ 10 | Hint : Trie data structure 11 | """ 12 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/linkedlist/ListNode.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.linkedlist; 2 | 3 | public class ListNode { 4 | int val; 5 | ListNode next; 6 | 7 | ListNode(int x) { 8 | val = x; 9 | } 10 | 11 | public static ListNode createStub(int n) { 12 | ListNode tmp = new ListNode(1); 13 | ListNode head = tmp; 14 | for (int i = 2; i <= n; i++) { 15 | tmp.next = new ListNode(i); 16 | tmp = tmp.next; 17 | } 18 | return head; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ProblemSolving/Medium/Misc/LruCache.java: -------------------------------------------------------------------------------- 1 | class LRUCache extends LinkedHashMap { 2 | private final int MAX_CAPACITY; 3 | 4 | public LRUCache(int capacity) { 5 | super(capacity, 0.75f, true); 6 | MAX_CAPACITY = capacity; 7 | } 8 | 9 | @Override 10 | protected boolean removeEldestEntry(Map.Entry eldest) { 11 | return size() > MAX_CAPACITY; 12 | } 13 | 14 | @Override 15 | public Integer get(Object key) { 16 | return super.getOrDefault(key, -1); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /LeetCodeKotlin/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | kotlin("jvm") version "1.7.21" 5 | application 6 | } 7 | 8 | group = "org.example" 9 | version = "1.0-SNAPSHOT" 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | testImplementation(kotlin("test")) 17 | } 18 | 19 | tasks.test { 20 | useJUnitPlatform() 21 | } 22 | 23 | tasks.withType { 24 | kotlinOptions.jvmTarget = "1.8" 25 | } 26 | 27 | application { 28 | mainClass.set("MainKt") 29 | } -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/concurrency/StaticObjectLock.java: -------------------------------------------------------------------------------- 1 | package leetcode.concurrency; 2 | 3 | public class StaticObjectLock { 4 | // A single static lock object shared by all instances 5 | private static final Object func1Lock = new Object(); 6 | 7 | // func1: Synchronizes on the STATIC lock 8 | public void func1() { 9 | synchronized (func1Lock) { 10 | // do something 11 | } 12 | } 13 | 14 | // func2: Independent. Does not need the static lock. 15 | public void func2() { 16 | // do something 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ProblemSolving/Medium/LinkedList/Model/LinkedListNodeModel.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class LinkedListNode: 5 | def __init__(self, x): 6 | self.val = x 7 | self.next = None 8 | 9 | 10 | def create_mock_linked_list(size: int) -> LinkedListNode: 11 | head = LinkedListNode(1) 12 | temp = head 13 | for i in range(2, size + 1): 14 | temp.next = LinkedListNode(i) 15 | temp = temp.next 16 | return head 17 | 18 | 19 | def get_linked_list_nodes(head: LinkedListNode) -> List[int]: 20 | if head is None: 21 | return [] 22 | return [head.val] + get_linked_list_nodes(head.next) 23 | -------------------------------------------------------------------------------- /LeetCodeJava/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | !**/src/main/**/target/ 4 | !**/src/test/**/target/ 5 | 6 | ### IntelliJ IDEA ### 7 | .idea/modules.xml 8 | .idea/jarRepositories.xml 9 | .idea/compiler.xml 10 | .idea/libraries/ 11 | *.iws 12 | *.iml 13 | *.ipr 14 | 15 | ### Eclipse ### 16 | .apt_generated 17 | .classpath 18 | .factorypath 19 | .project 20 | .settings 21 | .springBeans 22 | .sts4-cache 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | build/ 31 | !**/src/main/**/build/ 32 | !**/src/test/**/build/ 33 | 34 | ### VS Code ### 35 | .vscode/ 36 | 37 | ### Mac OS ### 38 | .DS_Store -------------------------------------------------------------------------------- /LeetCodeKotlin/.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | build/ 3 | !gradle/wrapper/gradle-wrapper.jar 4 | !**/src/main/**/build/ 5 | !**/src/test/**/build/ 6 | 7 | ### IntelliJ IDEA ### 8 | .idea/modules.xml 9 | .idea/jarRepositories.xml 10 | .idea/compiler.xml 11 | .idea/libraries/ 12 | *.iws 13 | *.iml 14 | *.ipr 15 | out/ 16 | !**/src/main/**/out/ 17 | !**/src/test/**/out/ 18 | 19 | ### Eclipse ### 20 | .apt_generated 21 | .classpath 22 | .factorypath 23 | .project 24 | .settings 25 | .springBeans 26 | .sts4-cache 27 | bin/ 28 | !**/src/main/**/bin/ 29 | !**/src/test/**/bin/ 30 | 31 | ### NetBeans ### 32 | /nbproject/private/ 33 | /nbbuild/ 34 | /dist/ 35 | /nbdist/ 36 | /.nb-gradle/ 37 | 38 | ### VS Code ### 39 | .vscode/ 40 | 41 | ### Mac OS ### 42 | .DS_Store -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/easy/math/ExcelColumnNumber.kt: -------------------------------------------------------------------------------- 1 | package leetcode.easy.math 2 | 3 | /** 4 | * 171. Excel Sheet Column Number 5 | * https://leetcode.com/problems/excel-sheet-column-number/ 6 | */ 7 | class ExcelColumnNumber { 8 | fun titleToNumber(columnTitle: String): Int { 9 | var mul = 1 10 | var ans = 0 11 | columnTitle.reversed().forEach { x -> 12 | ans += (x - 'A' + 1) * mul 13 | mul *= 26 14 | } 15 | return ans 16 | } 17 | } 18 | 19 | fun main() { 20 | val s = ExcelColumnNumber() 21 | println(s.titleToNumber("A")) 22 | println(s.titleToNumber("AB")) 23 | println(s.titleToNumber("ZY")) 24 | println(s.titleToNumber("FXSHRXW")) 25 | } -------------------------------------------------------------------------------- /ProblemSolving/Easy/Strings/CommonPrefix.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | """ 4 | https://leetcode.com/problems/longest-common-prefix/ 5 | """ 6 | def longest_common_prefix(strs: List[str]) -> str: 7 | prefix = [] 8 | for i in range(200): 9 | if i >= len(strs[0]): 10 | break 11 | char = strs[0][i] 12 | flag = True 13 | for s in strs: 14 | flag = flag and i < len(s) and (s[i] == char) 15 | if flag: 16 | prefix.append(char) 17 | else: 18 | break 19 | return "".join(prefix) 20 | 21 | 22 | if __name__ == '__main__': 23 | print(longest_common_prefix(["flower", "flow", "flight"])) 24 | print(longest_common_prefix(["dog", "racecar", "car"])) 25 | -------------------------------------------------------------------------------- /SystemDesign/Medium/AddEventAggregation.py: -------------------------------------------------------------------------------- 1 | """ 2 | Assume we are at Google scale and we are planning to start displaying ads on our websites. 3 | We want to be able to let the Ad owners know how well their ads are performing in real-time 4 | and bill them later based on the number of clicks. 5 | 6 | [MVP] Features to support: 7 | - Return the number of click events for a particular ad in the last M minutes in real-time. 8 | - Return the top 100 most clicked ads in the past 1 minute in real-time. (Nice to have: Make these parameters configurable). 9 | 10 | Scale: 11 | - 2 million ads in total 12 | - 1 billion daily active users and each user will click at-least 1 ad per day. 13 | 14 | """ 15 | """ 16 | Follow ups: 17 | - Support filtering based on country 18 | 19 | """ 20 | -------------------------------------------------------------------------------- /SystemDesign/Medium/TypeaheadSuggestion.py: -------------------------------------------------------------------------------- 1 | """ 2 | ABC.com is planning to build typeahead suggestions to improve its conversions on bookings 3 | search on its frontend platforms. 4 | 5 | Requirements: 6 | As user starts searching we auto-populate suggestions based on whatever text he/she typed. 7 | These suggestion should be top 10 most searched phrases in last 1 month ordered by their frequency. 8 | 9 | eg: 10 | User types B in search box 11 | Suggestions: 12 | - Bangkok 13 | - Bangalore 14 | - Brisbane 15 | - Best hotels 16 | - Best discounts 17 | - Best deals 18 | . 19 | . 20 | . 21 | """ 22 | 23 | """ 24 | Expectations: 25 | Clarify functional requirements 26 | Clarify non functional requirements 27 | HLD - Architecture 28 | API design 29 | LLD 30 | DB schema 31 | """ 32 | -------------------------------------------------------------------------------- /SystemDesign/Hard/ChatApplication.py: -------------------------------------------------------------------------------- 1 | """ 2 | Design a realtime chat application like whatsapp, fb messenger etc.: 3 | 4 | Requirements: 5 | 1) User registration 6 | 2) 1:1 Chat - Text Message Only (Max 100,000 char per text) 7 | 3) Online/Presence Indicator 8 | Scale : 9 | - 50 million daily active users 10 | 11 | 12 | 13 | Extended feature: 14 | 1) Group chat - max 100 people 15 | 2) Push Notifications 16 | 3) Media file - image, document and video 17 | 18 | Out of Scope: 19 | 1) E2E encryption 20 | """ 21 | 22 | """ 23 | Expectations: 24 | 1) bidirectional communication. How its established? 25 | 2) Database choice - NoSQL for messages or SQL? 26 | 3) * Ordering of messages - specially in group 27 | 4) Celebrity problem in presence/online updates 28 | 5) caching.cdn 29 | 30 | """ 31 | -------------------------------------------------------------------------------- /ProblemSolving/Medium/Recursion/PowerA^B.py: -------------------------------------------------------------------------------- 1 | """ 2 | Write a function that returns a power function that computes pow(a,b) = a^b. 3 | """ 4 | """ 5 | https://leetcode.com/problems/powx-n/ 6 | Challenge: 7 | Best solution is O(logb) 8 | Find which is efficient bit operations vs mathematical operations. 9 | recursive vs while loop 10 | UTs 11 | """ 12 | 13 | 14 | def pow(a: float, b: int): 15 | if b < 0: 16 | return pow(1 / a, abs(b)) 17 | if b == 0: 18 | return 1 19 | if b & 1 == 0: 20 | return pow(a * a, b >> 1) 21 | return a * pow(a * a, b >> 1) 22 | 23 | 24 | if __name__ == '__main__': 25 | print(pow(4, 2)) 26 | print(pow(5, 5)) 27 | print(pow(4, -2)) 28 | print(pow(-4, 3)) 29 | print(pow(-5, -3)) 30 | print(pow(4, 0)) 31 | print(pow(0, 0)) # no proper value, long debate in maths 32 | -------------------------------------------------------------------------------- /ProblemSolving/Medium/Heap/TopKFrequentElements.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | https://leetcode.com/problems/top-k-frequent-elements/ 4 | https://leetcode.com/problems/top-k-frequent-words/ 5 | """ 6 | from collections import Counter 7 | from typing import List 8 | 9 | from ProblemSolving.Medium.Heap.KLargestElements import k_largest_minheap 10 | 11 | 12 | def top_k_frequent(elements: List[int], k: int): 13 | counts = [(v, k) for k, v in Counter(elements).items()] # (count, key) tuples 14 | ans = [t[::-1][0] for t in k_largest_minheap(counts, k)] 15 | return ans 16 | 17 | 18 | if __name__ == '__main__': 19 | print(top_k_frequent([1, 1, 1, 1, 2, 2, 3, 7, 9, 9, 9, 9, 9, -1, -1, -1, -1, -1], 3)) 20 | print(top_k_frequent([1], 1)) 21 | print(top_k_frequent([1, 1, 1, 2, 2, 3], 2)) 22 | print(top_k_frequent(["hi", "hi", "hello", "hi", "me", "me"], 2)) 23 | -------------------------------------------------------------------------------- /SystemDesign/RealInterviews/talabat.md: -------------------------------------------------------------------------------- 1 | ## PROBLEM STATEMENT 2 | * We have an existing secondhand book-selling site, where people can add their used books. Other users can search and buy these books. 3 | * We want to build a feature, where you can save your search term to your favorite searches and receive a daily email on any new books that match that search term, once every 24 hours. 4 | 5 | ## EXAMPLE 6 | If a user searches for ‘Javascript’ and saves that search, any book with a title containing ‘Javascript’, which was added in the last 24 hours will be emailed to the user once a day. 7 | 8 | ## Functional Requirements: 9 | * Users can add used books. 10 | * Users can save searches to favorites. 11 | * The system sends 1 email daily based on saved searches. 12 | 13 | ## Scale: 14 | * 20M total users 15 | * 4M daily active users 16 | * 500k books added daily 17 | * 5 keywords/user on average 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## SDE Interviewer Notes 2 | Useful materials needed for SDE interviewers 3 | 4 | 5 | ## Medium articles 6 | - Amazon SDE-I Interview : https://medium.com/p/e8444ee791b 7 | - Amazon SDE-III Interview : https://medium.com/p/4c753b581c3 8 | - Google L3 Phone Screen Interview : https://medium.com/p/a75c2d0e0080 9 | - Google Onsite Interview : https://medium.com/p/3b035eb9e9f1 10 | - Agoda SDE-I Interview : https://medium.com/p/de6abc2c7347 11 | - Toptal Interview : https://medium.com/p/319bbaee97b3 12 | - Foodpanda Staff/Principal Engineer Interview : https://medium.com/p/d8529ca9be2c 13 | - Tiktok Singapore SDE-III Interview : https://medium.com/p/eef5d3cbcf99 14 | - Canva Australia SDE-III Interview: https://medium.com/p/10c69a5a4943 15 | - Glovo Barcelona SDE-III Interview: https://medium.com/p/19e2c30f159d 16 | - Talabat Dubai SDE-III Interview: https://medium.com/p/2c0f8208bb09 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/easy/array/DeleteColumnsMakeSorted.kt: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array 2 | 3 | /** 4 | * 944. Delete Columns to Make Sorted 5 | * https://leetcode.com/problems/delete-columns-to-make-sorted/ 6 | */ 7 | class DeleteColumnsMakeSorted { 8 | fun minDeletionSize(arr: Array): Int { 9 | var count = 0 10 | for (col in arr[0].indices) { 11 | inner@ for (row in arr.indices) { 12 | if (row <= arr.size - 2 && arr[row][col] > arr[row + 1][col]) { 13 | count++ 14 | break@inner 15 | } 16 | } 17 | } 18 | return count 19 | } 20 | } 21 | 22 | fun main() { 23 | val s = DeleteColumnsMakeSorted() 24 | println(s.minDeletionSize(arrayOf("cba", "daf", "ghi"))) // 1 25 | println(s.minDeletionSize(arrayOf("a", "b"))) // 0 26 | println(s.minDeletionSize(arrayOf("zyx", "wvu", "tsr"))) // 3 27 | } -------------------------------------------------------------------------------- /ProblemSolving/Medium/Strings/CountAndSay.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | """ 4 | """ 5 | https://leetcode.com/problems/count-and-say/ 6 | """ 7 | 8 | 9 | def burst(num_arr, start): 10 | while start + 1 < len(num_arr) and num_arr[start] == num_arr[start + 1]: 11 | start += 1 12 | return start 13 | 14 | 15 | def get_count(num_arr): 16 | res_arr = [] 17 | start = 0 18 | while start < len(num_arr): 19 | end = burst(num_arr, start) 20 | burst_size = end - start + 1 21 | res_arr.append(str(burst_size)) 22 | res_arr.append(num_arr[start]) 23 | start = end + 1 24 | return res_arr 25 | 26 | 27 | def count_and_say(n: int) -> str: 28 | root_arr = ["1"] 29 | for i in range(n - 1): 30 | root_arr = get_count(root_arr) 31 | return "".join(root_arr) 32 | 33 | 34 | if __name__ == '__main__': 35 | print(count_and_say(1)) 36 | print(count_and_say(3)) 37 | print(count_and_say(30)) 38 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/linkedlist/ReverseLinkedList.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.linkedlist; 2 | 3 | import java.util.Stack; 4 | 5 | 6 | 7 | public class ReverseLinkedList { 8 | protected void printList(ListNode head) { 9 | while (head != null) { 10 | System.out.print(head.val + "->"); 11 | head = head.next; 12 | } 13 | System.out.print("null\n"); 14 | } 15 | 16 | public ListNode reverseList(ListNode head) { 17 | if (head == null || head.next == null) return head; 18 | Stack s = new Stack(); 19 | while (head != null) { 20 | s.add(head); 21 | head = head.next; 22 | } 23 | 24 | head = s.pop(); 25 | ListNode temp = head; 26 | while (!s.isEmpty()) { 27 | temp.next = s.pop(); 28 | temp = temp.next; 29 | } 30 | temp.next = null; 31 | return head; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ProblemSolving/Medium/Strings/Anagram+++.py: -------------------------------------------------------------------------------- 1 | from collections import Counter, defaultdict 2 | 3 | """ 4 | An anagram of a string is a string that contains the same characters with a different (or the same) ordering. 5 | You are given two strings s and t. In one step, you can append any character to either s or t. 6 | Return the minimum number of steps to make s and t anagrams of each other. 7 | 8 | Input: s = "leetcode", t = "coats" 9 | Output: 7 10 | 11 | Input: s = "night", t = "thing" 12 | Output: 0 13 | """ 14 | """ 15 | https://leetcode.com/problems/minimum-number-of-steps-to-make-two-strings-anagram-ii/ 16 | """ 17 | def min_steps(s: str, t: str) -> int: 18 | wc1, wc2, ans = defaultdict(lambda: 0, Counter(s)), defaultdict(lambda: 0, Counter(t)), 0 19 | for c in set(s + t): 20 | ans += abs(wc1[c] - wc2[c]) 21 | return ans 22 | 23 | 24 | if __name__ == '__main__': 25 | print(min_steps(s="leetcode", t="coats")) 26 | print(min_steps(s="night", t="thing")) 27 | -------------------------------------------------------------------------------- /SystemDesign/Easy/BasicMessageQueue.py: -------------------------------------------------------------------------------- 1 | """ 2 | Assume we are having food ordering system. 3 | 4 | Food App ---> Order API ---> Payment API 5 | 6 | We are having issues with Payment API not able to process payments at the rate at which Order API is operating. 7 | What architectural changes to keep our customers happy? 8 | """ 9 | 10 | """ 11 | Follow ups: 12 | How does food app know payment got processed? 13 | Payment API went down? what happens to messages? how ensure message is not lost? 14 | Payment API got huge backlog of messages in the queue, what do we do? 15 | Duplicate payments issue. how to resolve? 16 | 17 | Expected: 18 | Add a message queue between them. 19 | Order API produces a message to the queue and return success to Food App. 20 | consumers at payment api side will consume the messages and invoke payment api for processing. 21 | Frontend can keep polling a different api to get payment status 22 | OR it can give order id back to customer and let payment api charge the customer later. 23 | """ 24 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/easy/set/PathCrossing.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.set; 2 | 3 | import java.util.HashSet; 4 | 5 | /** 6 | * Path Crossing 7 | */ 8 | public class PathCrossing { 9 | public boolean isPathCrossing(String path) { 10 | record Point(int x, int y) { 11 | } 12 | var visited = new HashSet(); 13 | var start = new Point(0, 0); 14 | visited.add(start); 15 | for (var dir : path.toCharArray()) { 16 | switch (dir) { 17 | case 'N' -> start = new Point(start.x, start.y + 1); 18 | case 'S' -> start = new Point(start.x, start.y - 1); 19 | case 'E' -> start = new Point(start.x + 1, start.y); 20 | case 'W' -> start = new Point(start.x - 1, start.y); 21 | } 22 | if (visited.contains(start)) return true; 23 | visited.add(start); 24 | } 25 | return false; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ProblemSolving/Easy/Trees/NodeLevel.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | Find the level of a node from the root in a binary tree. 4 | 5 | 3 -- level 1 6 | / \ 7 | 2 5 -- level 2 8 | / \ 9 | 1 4 -- level 3 10 | 11 | """ 12 | from ProblemSolving.Hard.Trees.Model.TreeNodeModel import TreeNode 13 | 14 | 15 | def level_helper(node: TreeNode, key, level): 16 | if node is None: 17 | return None # sentinel value 18 | 19 | if node.val == key: 20 | return level 21 | 22 | return level_helper(node.left, key, level + 1) or level_helper(node.right, key, level + 1) 23 | 24 | 25 | def node_level(root_node: TreeNode, key): 26 | return level_helper(root_node, key, 1) 27 | 28 | 29 | if __name__ == '__main__': 30 | root = TreeNode(3) 31 | root.left = TreeNode(2) 32 | root.right = TreeNode(5) 33 | root.left.left = TreeNode(1) 34 | root.left.right = TreeNode(4) 35 | for x in range(1, 6): 36 | print(x, '-->', node_level(root, x)) 37 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/unionfind/ConnectedComponents.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.unionfind; 2 | 3 | /** 4 | * https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/ 5 | */ 6 | public class ConnectedComponents { 7 | 8 | public int countComponents(int n, int[][] edges) { 9 | UnionFind uf = new UnionFind(n); 10 | for (int[] edge : edges) { 11 | uf.union(edge[0], edge[1]); 12 | } 13 | return uf.getNumGroups(); 14 | } 15 | 16 | public static void main(String[] args) { 17 | ConnectedComponents cc = new ConnectedComponents(); 18 | System.out.println(cc.countComponents(5, new int[][]{{0, 1}, {1, 2}, {3, 4}})); 19 | System.out.println(cc.countComponents(5, new int[][]{{0, 1}, {1, 2}, {2, 3}, {3, 4}})); 20 | System.out.println(cc.countComponents(5, new int[][]{{0, 1}, {1, 2}, {0, 2}, {3, 4}})); 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/easy/graph/PathExists.kt: -------------------------------------------------------------------------------- 1 | package leetcode.easy.graph 2 | 3 | import java.util.LinkedList 4 | 5 | /** 6 | * 1971. Find if Path Exists in Graph 7 | * https://leetcode.com/problems/find-if-path-exists-in-graph/ 8 | */ 9 | fun validPath(n: Int, edges: Array, source: Int, destination: Int): Boolean { 10 | val graph = HashMap>() 11 | for (v in 0 until n) graph[v] = mutableListOf() 12 | for (edge in edges) { 13 | graph[edge[0]]?.add(edge[1]) 14 | graph[edge[1]]?.add(edge[0]) 15 | } 16 | 17 | val bfsQ = LinkedList() 18 | val visited = HashSet() 19 | bfsQ.add(source) 20 | while (bfsQ.isNotEmpty()) { 21 | val v = bfsQ.remove() 22 | if (visited.contains(v)) continue 23 | if (v == destination) return true 24 | graph[v]?.let { bfsQ.addAll(it) } 25 | visited.add(v) 26 | } 27 | return false 28 | } 29 | 30 | fun main() { 31 | println(validPath(3, arrayOf(intArrayOf(0, 1), intArrayOf(1, 2), intArrayOf(2, 0)), 0, 2)) 32 | } -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/misc/PalindromicSubstrings.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.misc; 2 | 3 | /** 4 | * Palindromic Substrings 5 | */ 6 | public class PalindromicSubstrings { 7 | public int countSubstrings(String s) { 8 | int total = 0; 9 | for (int i = 0; i < s.length(); i++) 10 | total += buildAndCountPalindromes(s, i, i) + buildAndCountPalindromes(s, i, i + 1); 11 | return total; 12 | } 13 | 14 | private int buildAndCountPalindromes(String s, int left, int right) { 15 | if (left < 0 || right >= s.length() || s.charAt(left) != s.charAt(right)) return 0; 16 | return 1 + buildAndCountPalindromes(s, left - 1, right + 1); 17 | } 18 | 19 | public static void main(String[] args) { 20 | var ps = new PalindromicSubstrings(); 21 | System.out.println(ps.countSubstrings("abc"));//3 22 | System.out.println(ps.countSubstrings("aaa"));//6 23 | System.out.println(ps.countSubstrings("aaaabaaaa"));//25 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/math/KthFactorOfN.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.math; 2 | 3 | import java.util.Set; 4 | import java.util.TreeSet; 5 | 6 | public class KthFactorOfN { 7 | 8 | public int kthFactor(int n, int k) { 9 | int mid = (int) Math.ceil(Math.sqrt(n)); 10 | Set ts = new TreeSet<>(); 11 | for (int i = 1; i <= mid; i++) { 12 | if (n % i == 0) { 13 | ts.add(i); 14 | ts.add(n / i); 15 | } 16 | } 17 | Object[] factors = ts.toArray(); 18 | return factors.length < k ? -1 : (int) factors[k - 1]; 19 | } 20 | 21 | public static void main(String[] args) { 22 | KthFactorOfN kthFactorOfN = new KthFactorOfN(); 23 | System.out.println(kthFactorOfN.kthFactor(1, 1)); 24 | System.out.println(kthFactorOfN.kthFactor(4, 4)); 25 | System.out.println(kthFactorOfN.kthFactor(2, 2)); 26 | System.out.println(kthFactorOfN.kthFactor(7, 2)); 27 | System.out.println(kthFactorOfN.kthFactor(12, 3)); 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/graph/KeysAndRooms.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.graph 2 | 3 | import java.util.LinkedList 4 | 5 | /** 6 | * 841. Keys and Rooms 7 | * https://leetcode.com/problems/keys-and-rooms/ 8 | */ 9 | fun canVisitAllRooms(rooms: List>): Boolean { 10 | val graph = HashMap>() 11 | for (room in rooms.indices) graph[room] = mutableListOf() 12 | for (room in rooms.indices) graph[room]?.addAll(rooms[room]) 13 | val bfsQ = LinkedList() 14 | val visited = HashSet() 15 | bfsQ.add(0) 16 | while (bfsQ.isNotEmpty()) { 17 | val room = bfsQ.remove() 18 | if (visited.size == rooms.size) return true 19 | if (visited.contains(room)) continue 20 | graph[room]?.let { bfsQ.addAll(it) } 21 | visited.add(room) 22 | } 23 | return visited.size == rooms.size 24 | } 25 | 26 | fun main() { 27 | println(canVisitAllRooms(listOf(listOf(1), listOf(2), listOf(3), listOf()))) 28 | println(canVisitAllRooms(listOf(listOf(1, 3), listOf(3, 0, 1), listOf(2), listOf(0)))) 29 | } -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/stack/MinStack.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.stack; 2 | 3 | import java.util.Stack; 4 | 5 | public class MinStack { 6 | 7 | Stack main = new Stack<>(); 8 | Stack min = new Stack<>(); 9 | 10 | public MinStack() { 11 | 12 | } 13 | 14 | public void push(int val) { 15 | main.push(val); 16 | if (min.isEmpty()) min.push(val); 17 | else if (val <= min.peek()) min.push(val); 18 | } 19 | 20 | public void pop() { 21 | int val = main.pop(); 22 | if (val == min.peek()) min.pop(); 23 | } 24 | 25 | public int top() { 26 | return main.peek(); 27 | } 28 | 29 | public int getMin() { 30 | return min.peek(); 31 | } 32 | 33 | public static void main(String[] args) { 34 | MinStack ms = new MinStack(); 35 | ms.push(-2); 36 | ms.push(-0); 37 | ms.push(-3); 38 | System.out.println(ms.getMin()); 39 | ms.pop(); 40 | System.out.println(ms.top()); 41 | System.out.println(ms.getMin()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ProblemSolving/Medium/Heap/KLargestElements.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array of integers find the k largest elements in that array 3 | """ 4 | """ 5 | https://www.geeksforgeeks.org/k-largestor-smallest-elements-in-an-array/ 6 | """ 7 | 8 | from heapq import heappop, heapify, heappushpop 9 | from typing import List 10 | 11 | 12 | # O(k+ nlogk) 13 | def k_largest_minheap(arr: List[int], k: int): 14 | heap = arr[0:k] 15 | heapify(heap) 16 | for e in arr[k:]: 17 | heappushpop(heap, e) 18 | heap.sort(reverse=True) 19 | return heap 20 | 21 | 22 | # O(n + klogn) 23 | def k_largest_maxheap(arr: List[int], k: int): 24 | heap = [-e for e in arr] 25 | heapify(heap) 26 | return [-heappop(heap) for _ in range(k)] 27 | 28 | 29 | # O(nlogn + k) 30 | def k_largest_sort(arr: List[int], k: int): 31 | arr.sort(reverse=True) 32 | return arr[0:k] 33 | 34 | 35 | if __name__ == '__main__': 36 | elements = [1, 10, 9, 3, 55, 22, -10, 0, 4] 37 | k = 4 38 | print(k_largest_minheap(elements, k)) 39 | print(k_largest_maxheap(elements, k)) 40 | print(k_largest_sort(elements, k)) 41 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/binarysearch/KokoEatsBanana.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.binarysearch 2 | 3 | import kotlin.math.ceil 4 | 5 | /** 6 | * 875. Koko Eating Bananas 7 | * https://leetcode.com/problems/koko-eating-bananas/ 8 | */ 9 | class KokoEatsBanana { 10 | 11 | fun minEatingSpeed(piles: IntArray, h: Int): Int { 12 | var (low, high) = 1 to piles.max()!! 13 | while (low < high) { 14 | val mid = low + (high - low) / 2 15 | if (canEatAllBananas(piles, h, mid)) high = mid 16 | else low = mid + 1 17 | } 18 | return low 19 | } 20 | 21 | private fun canEatAllBananas(piles: IntArray, h: Int, mid: Int): Boolean { 22 | var hours = 0 23 | for (pile in piles) hours += ceil(pile.toDouble() / mid).toInt() 24 | return hours <= h 25 | } 26 | } 27 | 28 | fun main() { 29 | val keb = KokoEatsBanana() 30 | println(keb.minEatingSpeed(intArrayOf(3, 6, 7, 11), 8))// 4 31 | println(keb.minEatingSpeed(intArrayOf(30, 11, 23, 4, 20), 5))// 30 32 | println(keb.minEatingSpeed(intArrayOf(30, 11, 23, 4, 20), 6))// 23 33 | } -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/hard/greedy/Candy.java: -------------------------------------------------------------------------------- 1 | package leetcode.hard.greedy; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * https://leetcode.com/problems/candy/ 7 | */ 8 | public class Candy { 9 | 10 | public int candy(int[] ratings) { 11 | int[] candies = new int[ratings.length]; 12 | Arrays.fill(candies, 1); // everyone gets at-least 1 candy 13 | for (int i = 1; i < ratings.length; i++) { 14 | if (ratings[i] > ratings[i - 1]) candies[i] = candies[i - 1] + 1; 15 | } 16 | for (int i = ratings.length - 2; i >= 0; i--) { 17 | if (ratings[i] > ratings[i + 1] && candies[i] <= candies[i + 1]) candies[i] = candies[i + 1] + 1; 18 | } 19 | return Arrays.stream(candies).sum(); 20 | } 21 | 22 | public static void main(String[] args) { 23 | Candy c = new Candy(); 24 | System.out.println(c.candy(new int[]{1, 0, 2})); //5 25 | System.out.println(c.candy(new int[]{1, 2, 2})); //4 26 | System.out.println(c.candy(new int[]{1, 2, 87, 87, 87, 2, 1})); //13 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/math/BinomialCoefficient.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.math; 2 | 3 | public class BinomialCoefficient { 4 | 5 | // nCr = n! / (r! * (n-r)!) 6 | // nCr = nC(n-r) 7 | // nCr = n-1Cr-1 + n-1Cr 8 | // nCr = n * n-1 * n-2 * ... * n-r+1 / 1 * 2 * 3 * ... * r 9 | public long nCr(int n, int r) { 10 | long numerator = 1; 11 | long denominator = 1; 12 | r = Math.min(r, n - r); 13 | for (int i = 1; i <= r; i++) { 14 | numerator *= (n - r + i); 15 | denominator *= i; 16 | } 17 | return numerator / denominator; 18 | } 19 | 20 | public static void main(String[] args) { 21 | System.out.println(new BinomialCoefficient().nCr(5, 2)); 22 | System.out.println(new BinomialCoefficient().nCr(20, 10)); 23 | System.out.println(new BinomialCoefficient().nCr(20, 7)); 24 | System.out.println(new BinomialCoefficient().nCr(20, 13)); 25 | System.out.println(new BinomialCoefficient().nCr(30, 13)); 26 | System.out.println(new BinomialCoefficient().nCr(50, 17)); // overflow 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/sort/InsertInterval.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.sort; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | /** 7 | * 57. Insert Interval 8 | */ 9 | public class InsertInterval extends MergeIntervals { 10 | public int[][] insert(int[][] intervals, int[] newInterval) { 11 | List _intervals = getIntervals(intervals); 12 | _intervals.add(new Interval(newInterval[0], newInterval[1])); 13 | return getFinalResult(mergeIntervals(_intervals)); 14 | } 15 | 16 | public static void main(String[] args) { 17 | var ii = new InsertInterval(); 18 | // [[1,5],[6,9]] 19 | System.out.println(Arrays.deepToString(ii.insert(new int[][]{{1, 3}, {6, 9}}, new int[]{2, 5}))); 20 | // [[1,2],[3,10],[12,16]] 21 | System.out.println(Arrays.deepToString(ii.insert(new int[][]{{1, 2}, {3, 5}, {6, 7}, {8, 10}, {12, 16}}, new int[]{4, 8}))); 22 | // [[1,5]] 23 | System.out.println(Arrays.deepToString(ii.insert(new int[][]{{1, 5}}, new int[]{2, 3}))); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/easy/binarysearch/LongestSubsequenceLimitedSum.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.binarysearch; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * 2389. Longest Subsequence Limited Sum 7 | * https://leetcode.com/problems/longest-subsequence-limited-sum/ 8 | */ 9 | public class LongestSubsequenceLimitedSum { 10 | public int[] answerQueries(int[] nums, int[] queries) { 11 | Arrays.sort(nums); 12 | for (int i = 1; i < nums.length; i++) nums[i] += nums[i - 1]; 13 | int[] answer = new int[queries.length]; 14 | for (int q = 0; q < queries.length; q++) answer[q] = Math.abs(Arrays.binarySearch(nums, queries[q]) + 1); 15 | return answer; 16 | } 17 | 18 | public static void main(String[] args) { 19 | var lsls = new LongestSubsequenceLimitedSum(); 20 | //[2, 1, 3, 4] 21 | System.out.println(Arrays.toString(lsls.answerQueries(new int[]{1, 2, 3, 4, 5}, new int[]{3, 1, 7, 11}))); 22 | //[1, 0, 1, 2] 23 | System.out.println(Arrays.toString(lsls.answerQueries(new int[]{3, 5, 10, 20, 21}, new int[]{3, 1, 7, 11}))); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ProblemSolving/Medium/DP/UniquePaths.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). 4 | 5 | The robot can only move either down or right at any point in time. 6 | The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). 7 | 8 | How many possible unique paths are there? 9 | 10 | Input: m = 3, n = 7 11 | Output: 28 12 | 13 | Input: m = 3, n = 2 14 | Output: 3 15 | 16 | Input: m = 7, n = 3 17 | Output: 28 18 | 19 | Input: m = 3, n = 3 20 | Output: 6 21 | """ 22 | 23 | """ 24 | https://leetcode.com/problems/unique-paths/ 25 | """ 26 | 27 | 28 | def unique_paths(m, n, memo=None): 29 | if memo is None: 30 | memo = {} 31 | if m == 0 or n == 0: 32 | return 0 33 | if m == 1 or n == 1: 34 | return 1 35 | if (m, n) in memo or (n, m) in memo: 36 | return memo[(m, n)] or memo[(n, m)] 37 | memo[(m, n)] = memo[(n, m)] = unique_paths(m - 1, n, memo) + unique_paths(m, n - 1, memo) 38 | return memo[(m, n)] 39 | 40 | 41 | if __name__ == '__main__': 42 | print(unique_paths(3, 7)) 43 | print(unique_paths(3, 2)) 44 | print(unique_paths(7, 3)) 45 | print(unique_paths(3, 3)) 46 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/binarysearch/SmallestCommonElement.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.binarysearch; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * https://leetcode.com/problems/find-smallest-common-element-in-all-rows/ 7 | */ 8 | public class SmallestCommonElement { 9 | public int smallestCommonElement(int[][] mat) { 10 | int[] reference = mat[0]; 11 | for (int candidate : reference) { 12 | boolean matchedAll = true; 13 | for (int i = 1; i < mat.length; i++) { 14 | int result = Arrays.binarySearch(mat[i], candidate); 15 | matchedAll &= (result >= 0); 16 | } 17 | if (matchedAll) return candidate; 18 | } 19 | return -1; 20 | } 21 | 22 | public static void main(String[] args) { 23 | SmallestCommonElement sce = new SmallestCommonElement(); 24 | System.out.println(sce.smallestCommonElement(new int[][]{{1, 2, 3, 4, 5}, {2, 4, 5, 8, 10}, {3, 5, 7, 9, 11}, {1, 3, 5, 7, 9}}));//5 25 | System.out.println(sce.smallestCommonElement(new int[][]{{1, 2, 3}, {2, 3, 4}, {2, 3, 5}}));//2 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/linkedlist/RandomNode.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.linkedlist; 2 | 3 | import java.util.concurrent.ThreadLocalRandom; 4 | 5 | /** 6 | * https://leetcode.com/problems/linked-list-random-node/ 7 | */ 8 | public class RandomNode { 9 | private ListNode head = null; 10 | private int numElements = 1; 11 | 12 | public RandomNode(ListNode head) { 13 | makeCircularList(head); 14 | } 15 | 16 | private void makeCircularList(ListNode head) { 17 | ListNode tail = this.head = head; 18 | while (tail.next != null) { 19 | tail = tail.next; 20 | numElements++; 21 | } 22 | tail.next = head; 23 | } 24 | 25 | public int getRandom() { 26 | int rn = ThreadLocalRandom.current().nextInt(1, numElements + 1); 27 | while (rn-- > 0) this.head = this.head.next; 28 | return this.head.val; 29 | } 30 | 31 | public static void main(String[] args) { 32 | RandomNode rn = new RandomNode(ListNode.createStub(10)); 33 | for (int i = 0; i < 100; i++) { 34 | System.out.println(rn.getRandom()); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/easy/strings/GreatestCommonDivisorStrings.kt: -------------------------------------------------------------------------------- 1 | package leetcode.easy.strings 2 | 3 | /** 4 | * 1071. Greatest Common Divisor of Strings 5 | * https://leetcode.com/problems/greatest-common-divisor-of-strings/ 6 | */ 7 | class GreatestCommonDivisorStrings { 8 | fun gcdOfStrings(s: String, t: String): String { 9 | if (s.toSet() != t.toSet()) return "" 10 | for (candidate in getCandidates(t)) if (s.replace(candidate, "") == "") return candidate 11 | return "" 12 | } 13 | 14 | private fun getCandidates(t: String): List { 15 | val subs = mutableListOf(t) 16 | for (i in 0..t.length / 2) { 17 | val sub = t.substring(0, i) 18 | if (t.replace(sub, "").isEmpty()) subs.add(sub) 19 | } 20 | subs.sortBy { -it.length } 21 | return subs 22 | } 23 | } 24 | 25 | fun main() { 26 | val gcds = GreatestCommonDivisorStrings() 27 | println(gcds.gcdOfStrings("ababab", "ab"))//ab 28 | println(gcds.gcdOfStrings("abaaba", "aba"))//aba 29 | println(gcds.gcdOfStrings("abababa", "abac"))//"" 30 | println(gcds.gcdOfStrings("abababa", "a"))//"" 31 | println(gcds.gcdOfStrings("aaaaaaaaa", "aaa"))//"aaa" 32 | } 33 | 34 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/hard/dp/EditDistance.kt: -------------------------------------------------------------------------------- 1 | package leetcode.hard.dp 2 | 3 | /** 4 | * 72. Edit Distance 5 | * https://leetcode.com/problems/edit-distance/ 6 | */ 7 | class EditDistance { 8 | fun minDistance( 9 | word1: String, word2: String, 10 | i: Int = 0, j: Int = 0, 11 | cache: MutableMap, Int> = mutableMapOf() 12 | ): Int { 13 | if (i == word1.length) return word2.length - j 14 | if (j == word2.length) return word1.length - i 15 | val key = Pair(i, j) 16 | if (cache.containsKey(key)) return cache[key]!! 17 | if (word1[i] == word2[j]) { 18 | cache[key] = minDistance(word1, word2, i + 1, j + 1, cache) 19 | return cache[key]!! 20 | } 21 | val insert = minDistance(word1, word2, i, j + 1, cache) 22 | val delete = minDistance(word1, word2, i + 1, j, cache) 23 | val replace = minDistance(word1, word2, i + 1, j + 1, cache) 24 | cache[key] = 1 + minOf(insert, delete, replace) 25 | return cache[key]!! 26 | } 27 | } 28 | 29 | fun main() { 30 | val ed = EditDistance() 31 | println(ed.minDistance("horse", "ros"))// 3 32 | println(ed.minDistance("intention", "execution"))// 5 33 | } -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/easy/strings/VerifyAlienDictionary.kt: -------------------------------------------------------------------------------- 1 | package leetcode.easy.strings 2 | 3 | /** 4 | * 953. Verifying an Alien Dictionary 5 | * https://leetcode.com/problems/verifying-an-alien-dictionary/ 6 | */ 7 | class VerifyAlienDictionary { 8 | fun isAlienSorted(words: Array, order: String): Boolean { 9 | val orders = order.mapIndexed { index, c -> c to index }.toMap() 10 | val comparator = Comparator { a, b -> 11 | a.zip(b) 12 | .forEach { (aChar, bChar) -> if (aChar != bChar) return@Comparator orders[aChar]!! - orders[bChar]!! } 13 | a.length - b.length 14 | } 15 | val wordsClone = words.clone() 16 | wordsClone.sortWith(comparator) 17 | return wordsClone.contentEquals(words) 18 | } 19 | } 20 | 21 | fun main() { 22 | val p = VerifyAlienDictionary() 23 | println(p.isAlienSorted(arrayOf("hello", "leetcode"), "hlabcdefgijkmnopqrstuvwxyz"))//true 24 | println(p.isAlienSorted(arrayOf("word", "world", "row"), "worldabcefghijkmnpqstuvxyz"))//false 25 | println(p.isAlienSorted(arrayOf("apple", "app"), "abcdefghijklmnopqrstuvwxyz"))//false 26 | println(p.isAlienSorted(arrayOf("kuvp", "q"), "ngxlkthsjuoqcpavbfdermiywz"))//true 27 | } 28 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/hard/misc/NamingCompany.kt: -------------------------------------------------------------------------------- 1 | package leetcode.hard.misc 2 | 3 | /** 4 | * 2306. Naming a Company 5 | * https://leetcode.com/problems/naming-a-company/ 6 | */ 7 | class NamingCompany { 8 | fun distinctNames(ideas: List): Long { 9 | val map = HashMap>() 10 | for (c in 'a'..'z') map[c] = mutableSetOf() 11 | for (w in ideas) map[w[0]]?.add(w.substring(1)) 12 | var sum = 0L 13 | for (a in 'a'..'z') { 14 | for (b in a..'z') { 15 | if (map[a].isNullOrEmpty() || map[b].isNullOrEmpty() || a == b) continue 16 | val common = map[a]?.intersect(map[b]!!) ?: mutableSetOf() 17 | val aMap = map[a]?.minus(common) 18 | val bMap = map[b]?.minus(common) 19 | sum += aMap!!.size * bMap!!.size * 2 20 | } 21 | } 22 | return sum 23 | } 24 | } 25 | 26 | fun main() { 27 | val nc = NamingCompany() 28 | println(nc.distinctNames(listOf("coffee", "donuts", "time", "toffee")))// 4 29 | println(nc.distinctNames(listOf("coffee", "donuts", "time", "toffee", "coffees")))// 10 30 | println(nc.distinctNames(listOf("coffee", "donuts", "time", "toffee", "coffees", "donut")))// 18 31 | } 32 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/backtracking/LetterCasePermutation.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.backtracking 2 | 3 | /** 4 | * 784. Letter Case Permutation 5 | * https://leetcode.com/problems/letter-case-permutation/ 6 | */ 7 | class LetterCasePermutation { 8 | fun letterCasePermutation(s: String) = letterCasePermutations(0, s, listOf()) 9 | private fun letterCasePermutations(index: Int, s: String, permutation: List): List { 10 | if (index == s.length) return listOf(permutation.joinToString("")) 11 | val result = mutableListOf() 12 | val c = s[index] 13 | if (c.isLetter()) { 14 | val next = if (c.isUpperCase()) c.lowercaseChar() else c.uppercaseChar() 15 | result.addAll(letterCasePermutations(index + 1, s, permutation + next)) 16 | } 17 | result.addAll(letterCasePermutations(index + 1, s, permutation + c)) 18 | return result 19 | } 20 | } 21 | 22 | fun main() { 23 | val l = LetterCasePermutation() 24 | println(l.letterCasePermutation("a1b2"))// ["a1b2", "a1B2", "A1b2", "A1B2"] 25 | println(l.letterCasePermutation("3z4"))// ["3z4", "3Z4"] 26 | println(l.letterCasePermutation("12345"))// ["12345"] 27 | println(l.letterCasePermutation("0"))// ["0"] 28 | println(l.letterCasePermutation("C"))// ["c", "C"] 29 | } -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/easy/binarysearch/GuessNumberHigherLower.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.binarysearch; 2 | 3 | /** 4 | * https://leetcode.com/problems/guess-number-higher-or-lower/ 5 | */ 6 | public class GuessNumberHigherLower { 7 | private final int pick; 8 | 9 | private GuessNumberHigherLower(int pick) { 10 | this.pick = pick; 11 | } 12 | 13 | private int guess(int n) { 14 | return Integer.compare(pick - n, 0); 15 | } 16 | 17 | public int guessNumber(int n) { 18 | return guessNumber(1, n); 19 | } 20 | 21 | private int guessNumber(int start, int end) { 22 | int mid = start + (end - start) / 2; 23 | int result = guess(mid); 24 | if (result == 0) return mid; 25 | if (result == 1) return guessNumber(mid + 1, end); 26 | return guessNumber(start, mid - 1); 27 | } 28 | 29 | public static void main(String[] args) { 30 | System.out.println(new GuessNumberHigherLower(6).guessNumber(10)); 31 | System.out.println(new GuessNumberHigherLower(1).guessNumber(1)); 32 | System.out.println(new GuessNumberHigherLower(1).guessNumber(2)); 33 | System.out.println(new GuessNumberHigherLower(Integer.MAX_VALUE / 2).guessNumber(Integer.MAX_VALUE)); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Multithreading/Easy/MultiThreadedAnagram.py: -------------------------------------------------------------------------------- 1 | import threading 2 | from collections import Counter 3 | 4 | 5 | def get_chunks(content, chunk_size=5): 6 | return [content[i:i + chunk_size] for i in range(0, len(content), chunk_size)] 7 | 8 | 9 | def get_letter_frequency(word1, idx, results_collector): 10 | results_collector[idx] = Counter(word1) 11 | 12 | 13 | def aggregate_letter_frequency(results_collector): 14 | final_counter = Counter() 15 | for counter in results_collector: 16 | final_counter += counter 17 | return final_counter 18 | 19 | 20 | def compute_letter_frequency(content): 21 | chunks = get_chunks(content) 22 | jobs = [None] * len(chunks) 23 | results = [None] * len(chunks) 24 | for chunk_id in range(len(chunks)): 25 | t = threading.Thread(target=get_letter_frequency, args=(chunks[chunk_id], chunk_id, results,)) 26 | jobs[chunk_id] = t 27 | [j.start() for j in jobs] 28 | [j.join() for j in jobs] 29 | return aggregate_letter_frequency(results) 30 | 31 | 32 | def is_anagram(content1, content2): 33 | return compute_letter_frequency(content1) == compute_letter_frequency(content2) 34 | 35 | 36 | if __name__ == '__main__': 37 | print(is_anagram("aaaaabbbccczijknll12333", "aaaaabbbccczijknll12333")) 38 | print(is_anagram("silent", "listen")) 39 | print(is_anagram("aaaa", "bbbb")) 40 | -------------------------------------------------------------------------------- /ProblemSolving/Hard/TwoEggDroppingMinFloors.py: -------------------------------------------------------------------------------- 1 | import cmath 2 | import math 3 | 4 | """ 5 | You are given two identical eggs and you have access to a building with n floors labeled from 1 to n. 6 | 7 | You know that there exists a floor f where 0 <= f <= n such that any egg dropped at a floor higher than f will break, 8 | and any egg dropped at or below floor f will not break. 9 | 10 | In each move, you may take an unbroken egg and drop it from any floor x (where 1 <= x <= n). If the egg breaks, 11 | you can no longer use it. However, if the egg does not break, you may reuse it in future moves. 12 | 13 | Return the minimum number of moves that you need to determine with certainty what the value of f is. 14 | """ 15 | """ 16 | https://leetcode.com/problems/egg-drop-with-2-eggs-and-n-floors/ 17 | """ 18 | 19 | 20 | def min_drops(num_floors: int) -> float: 21 | if num_floors == 1: 22 | return 1 23 | # solve for x: x(x-1)/2 = n => x^2-x-2n=0 24 | a, b, c = 1, -1, -2 * num_floors 25 | d = (b ** 2) - (4 * a * c) 26 | sqrt_d = cmath.sqrt(d) 27 | x1 = (-b + sqrt_d) / (2 * a) 28 | x2 = (-b - sqrt_d) / (2 * a) 29 | return min(abs(math.floor(x1.real)), abs(math.floor(x2.real))) 30 | 31 | 32 | if __name__ == '__main__': 33 | print(min_drops(1)) 34 | print(min_drops(2)) 35 | print(min_drops(5)) 36 | print(min_drops(6)) 37 | print(min_drops(100)) 38 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/linkedlist/ReverseLinkedListII.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.linkedlist; 2 | 3 | public class ReverseLinkedListII extends ReverseLinkedList { 4 | public ListNode reverseBetween(ListNode head, int left, int right) { 5 | if (left == right) return head; 6 | 7 | ListNode rTemp = head; 8 | while (--right > 0) rTemp = rTemp.next; 9 | ListNode rTail = rTemp.next; 10 | rTemp.next = null; 11 | 12 | if (left == 1) { 13 | ListNode newHead = reverseList(head); 14 | head.next = rTail; 15 | return newHead; 16 | } 17 | 18 | ListNode ltemp = head; 19 | while (--left > 1) ltemp = ltemp.next; 20 | ListNode lstart = ltemp.next; 21 | ltemp.next = reverseList(lstart); 22 | lstart.next = rTail; 23 | return head; 24 | } 25 | 26 | public static void main(String[] args) { 27 | ReverseLinkedListII test = new ReverseLinkedListII(); 28 | test.printList(test.reverseBetween(ListNode.createStub(5), 1, 5)); 29 | test.printList(test.reverseBetween(ListNode.createStub(5), 1, 4)); 30 | test.printList(test.reverseBetween(ListNode.createStub(5), 2, 4)); 31 | test.printList(test.reverseBetween(ListNode.createStub(5), 2, 5)); 32 | test.printList(test.reverseBetween(ListNode.createStub(5), 3, 4)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ProblemSolving/Easy/Trees/LeafSequence.py: -------------------------------------------------------------------------------- 1 | from ProblemSolving.Hard.Trees.Model.TreeNodeModel import TreeNode, create_mock_binary_tree 2 | 3 | """ 4 | Consider all the leaves of a binary tree, from left to right order, the values of those leaves form a leaf value sequence. 5 | For example, in the given tree above, the leaf value sequence is (4, 5, 8, 7). 6 | 7 | 1 8 | / \ 9 | 2 3 10 | / \ / \ 11 | 4 5 6 7 12 | \ 13 | 8 14 | Two binary trees are considered leaf-similar if their leaf value sequence is the same. 15 | Return true if and only if the two given trees with head nodes root1 and root2 are leaf-similar. 16 | """ 17 | 18 | """ 19 | https://leetcode.com/problems/leaf-similar-trees/ 20 | """ 21 | 22 | 23 | def get_leaf_sequence(root: TreeNode): 24 | if root is None: 25 | return [] 26 | if root.left is None and root.right is None: 27 | return [root.val] 28 | return get_leaf_sequence(root.left) + get_leaf_sequence(root.right) 29 | 30 | 31 | def leaf_similar(root1: TreeNode, root2: TreeNode) -> bool: 32 | return get_leaf_sequence(root1) == get_leaf_sequence(root2) 33 | 34 | 35 | if __name__ == '__main__': 36 | node = create_mock_binary_tree() 37 | print(leaf_similar(node, node.right)) 38 | print(leaf_similar(node, node)) 39 | print(leaf_similar(node, node.left)) 40 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/sort/SortByFrequency.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.sort; 2 | 3 | import java.util.*; 4 | import java.util.stream.Collectors; 5 | 6 | /** 7 | * https://leetcode.com/problems/sort-characters-by-frequency/ 8 | */ 9 | public class SortByFrequency { 10 | public String frequencySort(String s) { 11 | List letters = new ArrayList<>(s.chars().mapToObj(c -> (char) c).toList()); 12 | Map frequency = new HashMap<>(); 13 | for (char ch : letters) frequency.put(ch, frequency.getOrDefault(ch, 0) + 1); 14 | letters.sort((a, b) -> Objects.equals(frequency.get(a), frequency.get(b)) ? Character.compare(a, b) : Integer.compare(frequency.get(b), frequency.get(a))); 15 | return letters.stream() 16 | .map(Object::toString) 17 | .collect(Collectors.joining()); 18 | } 19 | 20 | public static void main(String[] args) { 21 | SortByFrequency sbf = new SortByFrequency(); 22 | System.out.println(sbf.frequencySort("tree")); 23 | System.out.println(sbf.frequencySort("cccaaa")); 24 | System.out.println(sbf.frequencySort("cccaaadddddzz")); 25 | System.out.println(sbf.frequencySort("")); 26 | System.out.println(sbf.frequencySort("a")); 27 | System.out.println(sbf.frequencySort("loveleetcode")); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/easy/stack/EatLunch.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.stack; 2 | 3 | import java.util.Arrays; 4 | import java.util.LinkedList; 5 | 6 | /** 7 | * 8 | * 1700. Number of Students Unable to Eat Lunch 9 | */ 10 | public class EatLunch { 11 | public int countStudents(int[] students, int[] sandwiches) { 12 | var sandwichCount = 0; 13 | var q = new LinkedList(); 14 | Arrays.stream(students).forEach(q::add); 15 | var prevSize = q.size(); 16 | var deadlockCounter = 0; 17 | while (!q.isEmpty() && sandwichCount < students.length) { 18 | if (sandwiches[sandwichCount] == q.peek()) { 19 | q.poll(); 20 | sandwichCount++; 21 | } else q.add(q.poll()); 22 | 23 | if (prevSize == q.size()) { 24 | deadlockCounter++; 25 | if (deadlockCounter == q.size()) break; 26 | } else deadlockCounter = 0; 27 | 28 | prevSize = q.size(); 29 | } 30 | return q.size(); 31 | } 32 | 33 | public static void main(String[] args) { 34 | var el = new EatLunch(); 35 | System.out.println(el.countStudents(new int[]{1, 1, 0, 0}, new int[]{0, 1, 0, 1})); 36 | System.out.println(el.countStudents(new int[]{1, 1, 1, 0, 0, 1}, new int[]{1, 0, 0, 0, 1, 1})); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/backtracking/NonDecreasingSubsequence.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.backtracking 2 | 3 | import leetcode.utils.randomIntArray 4 | 5 | /** 6 | * 491. Non-decreasing Subsequences 7 | * https://leetcode.com/problems/non-decreasing-subsequences/ 8 | */ 9 | class NonDecreasingSubsequence { 10 | private fun findSubsequences(prev: List, current: Int, nums: IntArray): MutableSet> { 11 | if (current >= nums.size) return if (prev.size >= 2) mutableSetOf(prev) else mutableSetOf() 12 | val total = findSubsequences(prev, current + 1, nums) 13 | if (prev.isEmpty() || prev.last() <= nums[current]) 14 | total.addAll(findSubsequences(prev.plus(nums[current]), current + 1, nums)) 15 | return total 16 | } 17 | 18 | fun findSubsequences(nums: IntArray) = findSubsequences(listOf(), 0, nums).toList() 19 | } 20 | 21 | fun main() { 22 | val nds = NonDecreasingSubsequence() 23 | println(nds.findSubsequences(intArrayOf(4, 6, 7, 7))) 24 | println(nds.findSubsequences(intArrayOf(4, 4, 3, 2, 1))) 25 | println(nds.findSubsequences(intArrayOf(1, 5, 1, 3, 6, 7))) 26 | println(nds.findSubsequences(intArrayOf(1, 1, 1, 1, 1, 1))) 27 | // measure worst case time 28 | val start = System.currentTimeMillis() 29 | println(nds.findSubsequences(randomIntArray(size = 15, min = 10, max = 10))) 30 | println("${System.currentTimeMillis() - start}ms") 31 | } 32 | -------------------------------------------------------------------------------- /ProblemSolving/Medium/DP/MinimumPathSum.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a m x n grid filled with non-negative numbers, 3 | find a path from top left to bottom right, which minimizes the sum of all numbers along its path. 4 | 5 | Note: You can only move either down or right at any point in time. 6 | 7 | Input: grid = [[1,3,1],[1,5,1],[4,2,1]] 8 | Output: 7 9 | 10 | Input: grid = [[1,2,3],[4,5,6]] 11 | Output: 12 12 | """ 13 | 14 | """ 15 | https://leetcode.com/problems/minimum-path-sum/ 16 | """ 17 | 18 | 19 | def minimum_path_sum_helper(grid, i, j, memo): 20 | if i == j == 0: 21 | memo[(i, j)] = grid[i][j] 22 | elif i == 0: 23 | memo[(i, j)] = grid[i][j] + minimum_path_sum_helper(grid, i, j - 1, memo) 24 | elif j == 0: 25 | memo[(i, j)] = grid[i][j] + minimum_path_sum_helper(grid, i - 1, j, memo) 26 | if (i, j) in memo: 27 | return memo[(i, j)] 28 | 29 | memo[(i, j)] = grid[i][j] + min(minimum_path_sum_helper(grid, i - 1, j, memo), 30 | minimum_path_sum_helper(grid, i, j - 1, memo)) 31 | return memo[(i, j)] 32 | 33 | 34 | def minimum_path_sum(grid): 35 | return minimum_path_sum_helper(grid, len(grid) - 1, len(grid[0]) - 1, {}) 36 | 37 | 38 | if __name__ == '__main__': 39 | matrix = [[1, 3, 1], 40 | [1, 5, 1], 41 | [4, 2, 1]] 42 | print(minimum_path_sum(matrix)) 43 | 44 | matrix = [[1, 2, 3], 45 | [4, 5, 6]] 46 | print(minimum_path_sum(matrix)) 47 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/dp/JumpGame.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.dp; 2 | 3 | /** 4 | * 55. Jump Game 5 | * https://leetcode.com/problems/jump-game/ 6 | */ 7 | public class JumpGame { 8 | 9 | public boolean jumpHelper(int[] nums, int current, int last, Boolean[] dp) { 10 | if (current >= last) return true; 11 | if (dp[current] != null) return dp[current]; 12 | var ans = false; 13 | for (int i = 1; i <= nums[current]; i++) { 14 | ans = jumpHelper(nums, current + i, last, dp); 15 | if (ans) break; 16 | } 17 | return dp[current] = ans; 18 | } 19 | 20 | public boolean canJump(int[] nums) { 21 | if (nums.length == 1) return true; 22 | Boolean[] dp = new Boolean[nums.length]; 23 | return jumpHelper(nums, 0, nums.length - 1, dp); 24 | } 25 | 26 | public static void main(String[] args) { 27 | var jumpGame = new JumpGame(); 28 | System.out.println(jumpGame.canJump(new int[]{2, 3, 1, 1, 4}));//true 29 | System.out.println(jumpGame.canJump(new int[]{3, 2, 1, 0, 4}));//false 30 | System.out.println(jumpGame.canJump(new int[]{2, 0, 0}));//true 31 | System.out.println(jumpGame.canJump(new int[]{0}));//true 32 | System.out.println(jumpGame.canJump(new int[]{1, 1, 1, 0}));//true 33 | System.out.println(jumpGame.canJump(new int[]{1, 2, 3}));//true 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/hard/arrays/OrderlyQueue.java: -------------------------------------------------------------------------------- 1 | package leetcode.hard.arrays; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * https://leetcode.com/problems/orderly-queue/ 7 | */ 8 | public class OrderlyQueue { 9 | private void reverse(char[] data, int left, int right) { 10 | for (; left < right; left++, right--) { 11 | char temp = data[left]; 12 | data[left] = data[right]; 13 | data[right] = temp; 14 | } 15 | } 16 | 17 | private char[] rotate(char[] arr) { 18 | reverse(arr, 1, arr.length - 1); 19 | reverse(arr, 0, arr.length - 1); 20 | return arr; 21 | } 22 | 23 | public String orderlyQueue(String s, int k) { 24 | char[] arr = s.toCharArray(); 25 | String min = s; 26 | if (k > 1) { 27 | Arrays.sort(arr); 28 | min = String.valueOf(arr); 29 | } else { 30 | for (int i = 0; i < arr.length; i++) { 31 | rotate(arr); 32 | String rotation = String.valueOf(arr); 33 | min = rotation.compareTo(min) < 0 ? rotation : min; 34 | } 35 | } 36 | return min; 37 | } 38 | 39 | public static void main(String[] args) { 40 | OrderlyQueue oq = new OrderlyQueue(); 41 | System.out.println(oq.orderlyQueue("cba", 1)); 42 | System.out.println(oq.orderlyQueue("baaca", 3)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ProblemSolving/Medium/Recursion/kSum.py: -------------------------------------------------------------------------------- 1 | """ 2 | https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/ 3 | 4 | https://leetcode.com/problems/3sum 5 | 6 | https://leetcode.com/problems/4sum/ 7 | """ 8 | 9 | 10 | def k_sum(arr, k, target): 11 | arr.sort() 12 | if k == 2: 13 | return two_sum(arr, target) 14 | else: 15 | result, visited = [], set() 16 | for i in range(len(arr) - k + 1): 17 | if arr[i] not in visited: 18 | sub_sums = k_sum(arr[i + 1:], k - 1, target - arr[i]) 19 | result += [[arr[i]] + sub for sub in sub_sums] 20 | visited.add(arr[i]) 21 | return result 22 | 23 | 24 | def two_sum(arr, target): 25 | ans = set() 26 | i, j = 0, len(arr) - 1 27 | while i < j and i < len(arr) and j >= 0: 28 | if arr[i] + arr[j] == target: 29 | ans.add((arr[i], arr[j])) 30 | i, j = i + 1, j - 1 31 | elif arr[i] + arr[j] > target: 32 | j -= 1 33 | else: 34 | i += 1 35 | return [list(t) for t in ans] 36 | 37 | 38 | if __name__ == '__main__': 39 | print(k_sum([2, 3, 4, 5, 1, 9, 12, 6, 1, 9, 0], 2, 10)) 40 | print(k_sum([2, 3, 4, 5, 1, 9, 12, 6, 1, 9, 0], 3, 10)) 41 | print(k_sum([2, 3, 4, 5, 1, 9, 12, 6, 1, 9, 0], 3, 10)) 42 | print(k_sum([2, 3, 4, 5, 1, 9, 12, 6, 1, 9, 0], 4, 10)) 43 | 44 | print(k_sum([0, 0, 0], 2, 0)) 45 | print(k_sum([0, 0, 0], 3, 0)) 46 | print(k_sum([0, 0, 0, 0, 0], 4, 0)) 47 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/dp/DominoTrominoTiling.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.dp; 2 | 3 | /** 4 | * 790. Domino and Tromino Tiling 5 | * https://leetcode.com/problems/domino-and-tromino-tiling/ 6 | */ 7 | public class DominoTrominoTiling { 8 | 9 | /** 10 | * linear equation
11 | * f(n) = x * f(n-1) + y * f(n-2) + z * f(n-3)
12 | * n = 4 => 5x + 2y + z = 11
13 | * n = 5 => 11x + 5y + 2z = 24
14 | * n = 6 => 24x + 11y + 5z = 53
15 | * with 3 equations we can find 3 unknowns.
16 | * x = 2
17 | * y = 0
18 | * z = 1
19 | * f(n) = 2*f(n-1) + f(n-3) 20 | */ 21 | public int numTilings(int n) { 22 | if (n <= 2) return n; 23 | int[] cache = new int[n + 1]; 24 | int mod = 1000000007; 25 | cache[0] = cache[1] = 1; 26 | cache[2] = 2; 27 | for (int i = 3; i <= n; i++) 28 | cache[i] = ((2 * cache[i - 1] % mod) + cache[i - 3]) % mod; 29 | return cache[n]; 30 | } 31 | 32 | public static void main(String[] args) { 33 | var dtt = new DominoTrominoTiling(); 34 | System.out.println(dtt.numTilings(3));//5 35 | System.out.println(dtt.numTilings(4));//11 36 | System.out.println(dtt.numTilings(5));//24 37 | System.out.println(dtt.numTilings(6));//53 38 | System.out.println(dtt.numTilings(1000));//979232805 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ProblemSolving/Easy/Trees/AverageLevels.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given the root of a binary tree, return the average value of the nodes on each level in the form of an array. 3 | Answers within 10-5 of the actual answer will be accepted. 4 | 5 | 1 6 | / \ 7 | 2 3 8 | / \ / \ 9 | 4 5 6 7 10 | \ 11 | 8 12 | Ans : [1, 2.5, 5.5, 8] 13 | """ 14 | 15 | """ 16 | https://leetcode.com/problems/average-of-levels-in-binary-tree/ 17 | Similar : https://leetcode.com/problems/find-largest-value-in-each-tree-row/ 18 | """ 19 | from ProblemSolving.Hard.Trees.Model.TreeNodeModel import create_mock_binary_tree, TreeNode 20 | from statistics import mean 21 | 22 | 23 | def levels_helper(root: TreeNode, avg, level): 24 | if root is None: 25 | return 26 | if level not in avg: 27 | avg[level] = [] 28 | avg[level].append(root.val) 29 | levels_helper(root.left, avg, level + 1) 30 | levels_helper(root.right, avg, level + 1) 31 | 32 | 33 | def max_levels(root: TreeNode): 34 | avg = {} 35 | levels_helper(root, avg, 0) 36 | return [max(v) for k, v in sorted(avg.items())] 37 | 38 | 39 | def average_levels(root: TreeNode): 40 | avg = {} 41 | levels_helper(root, avg, 0) 42 | return [mean(v) for k, v in sorted(avg.items())] 43 | 44 | 45 | if __name__ == '__main__': 46 | node = create_mock_binary_tree() 47 | print(average_levels(node)) 48 | print(max_levels(node)) 49 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/math/SumOfSquareNumbers.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.math; 2 | 3 | /** 4 | * https://leetcode.com/problems/sum-of-square-numbers/ 5 | */ 6 | public class SumOfSquareNumbers { 7 | 8 | public boolean judgeSquareSum(int c) { 9 | long max = (int) Math.sqrt(c); 10 | long min = 0; 11 | while (min <= max) { 12 | long sum = (min * min) + (max * max); 13 | if (sum == c) { 14 | return true; 15 | } 16 | long tmp = ((sum > c) ? max-- : min++); 17 | } 18 | return false; 19 | } 20 | 21 | public static void main(String[] args) { 22 | SumOfSquareNumbers sumOfSquareNumbers = new SumOfSquareNumbers(); 23 | 24 | // true 25 | System.out.println(sumOfSquareNumbers.judgeSquareSum(101)); 26 | System.out.println(sumOfSquareNumbers.judgeSquareSum(100)); 27 | System.out.println(sumOfSquareNumbers.judgeSquareSum(5)); 28 | System.out.println(sumOfSquareNumbers.judgeSquareSum(2)); 29 | System.out.println(sumOfSquareNumbers.judgeSquareSum(162)); 30 | System.out.println(sumOfSquareNumbers.judgeSquareSum(2147483600)); 31 | 32 | 33 | // false 34 | System.out.println(sumOfSquareNumbers.judgeSquareSum(3)); 35 | System.out.println(sumOfSquareNumbers.judgeSquareSum(99)); 36 | System.out.println(sumOfSquareNumbers.judgeSquareSum(2147483647)); 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/hard/dp/ReducingDishes.java: -------------------------------------------------------------------------------- 1 | package leetcode.hard.dp; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * https://leetcode.com/problems/reducing-dishes/ 7 | */ 8 | public class ReducingDishes { 9 | private int maxSatisfaction(int[] satisfactions, int current, int time, int[][] cache) { 10 | if (current >= satisfactions.length || time > satisfactions.length) return 0; 11 | if (cache[current][time] != 0) return cache[current][time]; 12 | int withCurrent = time * satisfactions[current] + maxSatisfaction(satisfactions, current + 1, time + 1, cache); 13 | int withoutCurrent = maxSatisfaction(satisfactions, current + 1, time, cache); 14 | return (cache[current][time] = Math.max(withCurrent, withoutCurrent)); 15 | } 16 | 17 | public int maxSatisfaction(int[] satisfactions) { 18 | Arrays.sort(satisfactions); 19 | int[][] cache = new int[satisfactions.length][satisfactions.length + 1]; 20 | return maxSatisfaction(satisfactions, 0, 1, cache); 21 | } 22 | 23 | public static void main(String[] args) { 24 | var rd = new ReducingDishes(); 25 | System.out.println(rd.maxSatisfaction(new int[]{-1, -8, 0, 5, -9})); // 14 26 | System.out.println(rd.maxSatisfaction(new int[]{4, 3, 2})); // 20 27 | System.out.println(rd.maxSatisfaction(new int[]{-1, -4, -5})); // 0 28 | System.out.println(rd.maxSatisfaction(new int[]{-2, 5, -1, 0, 3, -3})); // 35 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/dp/JumpGameII.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.dp; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * https://leetcode.com/problems/jump-game-ii/ 7 | */ 8 | public class JumpGameII { 9 | public int jump(int[] nums) { 10 | if (nums.length == 1) 11 | return 0; 12 | int[] dp = new int[nums.length]; 13 | Arrays.fill(dp, -1); 14 | return jumpHelper(nums, 0, nums.length - 1, dp); 15 | } 16 | 17 | public int jumpHelper(int[] nums, int current, int last, int[] dp) { 18 | if (current >= last) 19 | return 0; 20 | if (dp[current] != -1) 21 | return dp[current]; 22 | 23 | int ans = Integer.MAX_VALUE / 2; 24 | for (int i = 1; i <= nums[current]; i++) { 25 | ans = Math.min(ans, 1 + jumpHelper(nums, current + i, last, dp)); 26 | } 27 | dp[current] = ans; 28 | return dp[current]; 29 | } 30 | 31 | public static void main(String[] args) { 32 | JumpGameII jumpGameII = new JumpGameII(); 33 | System.out.println(jumpGameII.jump(new int[]{0})); 34 | System.out.println(jumpGameII.jump(new int[]{1, 2})); 35 | System.out.println(jumpGameII.jump(new int[]{2, 3, 0, 1, 4})); 36 | System.out.println(jumpGameII.jump(new int[]{2, 3, 1, 1, 4})); 37 | System.out.println(jumpGameII.jump(new int[]{1, 1, 1, 1, 1})); 38 | System.out.println(jumpGameII.jump(new int[]{1, 0, 0, 1})); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ProblemSolving/Medium/LinkedList/MbyNthNode.py: -------------------------------------------------------------------------------- 1 | """ 2 | Find the m/n th node in a linked list 3 | 4 | Example lets say length of the linked list L = 27 5 | 6 | Testcases: 7 | m=2 n=3 => Ans: 18th Node 8 | m=1 n=9 => Ans: 3rd Node 9 | m=3 n=9 => Ans: 9th Node 10 | m=9 n=9 => Ans: 1st Node 11 | m=1 n=5 => Ans: 5th Node 12 | m=2 n=5 => Ans: 10th Node 13 | """ 14 | 15 | """ 16 | My Amazon Interview Question 17 | 18 | """ 19 | 20 | from ProblemSolving.Medium.LinkedList.Model.LinkedListNodeModel import LinkedListNode, create_mock_linked_list, \ 21 | get_linked_list_nodes 22 | 23 | 24 | def m_by_n_node(head: LinkedListNode, m: int, n: int): 25 | from math import gcd 26 | 27 | m, n = m // gcd(m, n), n // gcd(m, n) 28 | i, temp, fractional_node = 1, head, None 29 | 30 | while temp is not None: 31 | if i % n == 0: 32 | if fractional_node is None: 33 | fractional_node = head 34 | else: 35 | fractional_node = fractional_node.next 36 | for i in range(m - 1): 37 | fractional_node = fractional_node.next 38 | i, temp = i + 1, temp.next 39 | 40 | return fractional_node 41 | 42 | 43 | if __name__ == '__main__': 44 | node = create_mock_linked_list(27) 45 | print(get_linked_list_nodes(node)) 46 | print(m_by_n_node(node, 2, 3).val) 47 | print(m_by_n_node(node, 1, 9).val) 48 | print(m_by_n_node(node, 3, 9).val) 49 | print(m_by_n_node(node, 9, 9).val) 50 | print(m_by_n_node(node, 1, 5).val) 51 | print(m_by_n_node(node, 2, 5).val) 52 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/easy/dp/MinCostClimbingStairs.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.dp; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * https://leetcode.com/problems/min-cost-climbing-stairs/description/ 7 | */ 8 | public class MinCostClimbingStairs { 9 | public final int SENTINEL = Integer.MAX_VALUE / 2; 10 | 11 | public int minCost(int[] cost, int i, int[] cache) { 12 | if (i >= cost.length) return 0; 13 | if (cache[i] != SENTINEL) return cache[i]; 14 | int minCost = cost[i] + Math.min(minCost(cost, i + 1, cache), minCost(cost, i + 2, cache)); 15 | return (cache[i] = Math.min(minCost, cache[i])); 16 | } 17 | 18 | public int minCostClimbingStairs(int[] cost) { 19 | int[] cache = new int[cost.length]; 20 | Arrays.fill(cache, SENTINEL); 21 | minCost(cost, 0, cache); 22 | return Math.min(cache[0], cache[1]); 23 | } 24 | 25 | public static void main(String[] args) { 26 | MinCostClimbingStairs mccs = new MinCostClimbingStairs(); 27 | System.out.println(mccs.minCostClimbingStairs(new int[]{10, 15, 20})); 28 | System.out.println(mccs.minCostClimbingStairs(new int[]{1, 100, 1, 1, 1, 100, 1, 1, 100, 1})); 29 | System.out.println(mccs.minCostClimbingStairs(new int[]{10, 15, 20, 9, 1, 22, 8})); 30 | System.out.println(mccs.minCostClimbingStairs(new int[]{15, 10})); 31 | System.out.println(mccs.minCostClimbingStairs(new int[]{10, 15})); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/array/MinRoundsCompleteTasks.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.array 2 | 3 | /** 4 | * 1986. Minimum Number of Work Sessions to Finish the Tasks 5 | * https://leetcode.com/problems/minimum-number-of-work-sessions-to-finish-the-tasks/ 6 | */ 7 | class MinRoundsCompleteTasks { 8 | 9 | fun minimumRounds(tasks: IntArray): Int { 10 | val frequencies = tasks.asList().groupingBy { it }.eachCount().values 11 | var count = 0 12 | for (frequency in frequencies) { 13 | count += if (frequency == 1) 14 | return -1 15 | else { 16 | val (x, y) = solve2x3y(frequency) 17 | x + y 18 | } 19 | } 20 | return count 21 | } 22 | 23 | fun solve2x3y(frequency: Int): Pair { 24 | if (frequency % 3 == 0) 25 | return (0 to frequency / 3) 26 | var freq = frequency 27 | var x = 0 28 | var y = 0 29 | while (true) { 30 | freq -= 2 31 | x++ 32 | if (freq == 0) break 33 | if (freq % 3 == 0) { 34 | y = freq / 3 35 | break 36 | } 37 | } 38 | return (x to y) 39 | } 40 | } 41 | 42 | fun main() { 43 | val mrct = MinRoundsCompleteTasks() 44 | println(mrct.minimumRounds(intArrayOf(2, 2, 3, 3, 2, 4, 4, 4, 4, 4)))// 4 45 | println(mrct.minimumRounds(intArrayOf(2, 3, 3)))// -1 46 | println(mrct.minimumRounds(intArrayOf(4, 4, 4, 4, 4, 4, 4, 4)))// 3 47 | } 48 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/dp/LargestDivisibleSubset.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.dp; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * Largest Divisible Subset 7 | */ 8 | public class LargestDivisibleSubset { 9 | public List largestDivisibleSubset(int[] nums) { 10 | Arrays.sort(nums); 11 | var dp = new int[nums.length]; 12 | var prev = new int[nums.length]; 13 | var maxIndex = 0; 14 | Arrays.fill(dp, 1); 15 | Arrays.fill(prev, -1); 16 | for (var i = 1; i < nums.length; i++) { 17 | for (var j = i - 1; j >= 0; j--) { 18 | if (nums[i] % nums[j] == 0 && 1 + dp[j] > dp[i]) { 19 | dp[i] = 1 + dp[j]; 20 | prev[i] = j; 21 | } 22 | } 23 | if (dp[i] > dp[maxIndex]) maxIndex = i; 24 | } 25 | 26 | var result = new ArrayList(); 27 | do { 28 | result.add(nums[maxIndex]); 29 | maxIndex = prev[maxIndex]; 30 | } while (maxIndex != -1); 31 | 32 | return result; 33 | } 34 | 35 | public static void main(String[] args) { 36 | var lds = new LargestDivisibleSubset(); 37 | System.out.println(lds.largestDivisibleSubset(new int[]{1, 2, 3}));//[1, 2] 38 | System.out.println(lds.largestDivisibleSubset(new int[]{1, 2, 4, 8}));//[1, 2, 4, 8] 39 | System.out.println(lds.largestDivisibleSubset(new int[]{4, 8, 10, 240}));//[4, 8, 240] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ProblemSolving/Medium/DP/LargestSquareSubMatrix.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an m x n binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area. 3 | 4 | Input: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]] 5 | Output: 4 6 | 7 | Input: matrix = [["0","1"],["1","0"]] 8 | Output: 1 9 | 10 | Input: matrix = [["0"]] 11 | Output: 0 12 | """ 13 | """ 14 | https://leetcode.com/problems/maximal-square/ 15 | """ 16 | from collections import defaultdict 17 | from typing import List 18 | 19 | 20 | def maximal_square(matrix: List[List[str]]): 21 | row, col, memo = len(matrix), len(matrix[0]), defaultdict(int) 22 | for i in range(row): 23 | for j in range(col): 24 | memo[(i, j)] = 0 if matrix[i][j] == "0" \ 25 | else min(memo[(i - 1, j)], memo[(i - 1, j - 1)], memo[(i, j - 1)]) + 1 26 | return 0 if len(memo) == 0 else max(memo.values()) ** 2 27 | 28 | 29 | if __name__ == '__main__': 30 | print(maximal_square([["1", "0", "1", "0", "0"], 31 | ["1", "0", "1", "1", "1"], 32 | ["1", "1", "1", "1", "1"], 33 | ["1", "0", "0", "1", "0"]])) 34 | print(maximal_square([["0", "1"], ["1", "0"]])) 35 | print(maximal_square([["0"]])) 36 | print(maximal_square([[]])) 37 | print(maximal_square([["1", "0", "1", "0", "0"], 38 | ["1", "0", "1", "1", "1"], 39 | ["1", "1", "1", "1", "1"], 40 | ["1", "0", "1", "1", "1"]])) 41 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/unionfind/LexicographicallySmallestEquivalent.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.unionfind; 2 | 3 | import java.util.TreeSet; 4 | 5 | /** 6 | * 1061. Lexicographically Smallest Equivalent String 7 | */ 8 | public class LexicographicallySmallestEquivalent { 9 | public String smallestEquivalentString(String a, String b, String c) { 10 | var uf = new UnionFind(26); 11 | var ans = new StringBuilder(); 12 | for (int i = 0; i < a.length(); i++) uf.union(a.charAt(i) - 'a', b.charAt(i) - 'a'); 13 | var groupByParent = uf.groupByParent(true); 14 | for (int i = 0; i < c.length(); i++) { 15 | var parent = uf.find(c.charAt(i) - 'a'); 16 | var group = (TreeSet) groupByParent.get(parent); 17 | ans.append((char) ('a' + group.first())); 18 | } 19 | return ans.toString(); 20 | } 21 | 22 | public static void main(String[] args) { 23 | var lse = new LexicographicallySmallestEquivalent(); 24 | System.out.println(lse.smallestEquivalentString("abc", "cde", "aab"));//aab 25 | System.out.println(lse.smallestEquivalentString("abc", "cde", "xyz"));//xyz 26 | System.out.println(lse.smallestEquivalentString("parker", "morris", "parser"));//makkek 27 | System.out.println(lse.smallestEquivalentString("hello", "world", "hold"));//hdld 28 | System.out.println(lse.smallestEquivalentString("leetcode", "programs", "sourcecode"));//aauaaaaada 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/backtracking/RestoreIpAddresses.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.backtracking 2 | 3 | /** 4 | * 93. Restore IP Addresses 5 | * https://leetcode.com/problems/restore-ip-addresses/ 6 | */ 7 | class RestoreIpAddresses { 8 | fun restoreIpAddresses(s: String) = restoreIpAddresses(s, 1, listOf((s[0] - '0'))) 9 | .map { it.joinToString(".") } 10 | 11 | private fun restoreIpAddresses(s: String, index: Int, ip: List): List> { 12 | if (s.length < 4 || ip.size > 4) return listOf() 13 | if (index >= s.length) return if (ip.size == 4) listOf(ip) else listOf() 14 | val result = mutableListOf>() 15 | val newDigit = s[index] - '0' 16 | if (ip.last() != 0) { 17 | val newOctet = ip.last() * 10 + newDigit 18 | if (newOctet <= 255) { 19 | val newIp = ip.toMutableList() 20 | newIp[newIp.lastIndex] = newOctet 21 | result.addAll(restoreIpAddresses(s, index + 1, newIp)) 22 | } 23 | } 24 | result.addAll(restoreIpAddresses(s, index + 1, ip.plus(newDigit))) 25 | return result 26 | } 27 | } 28 | 29 | fun main() { 30 | val ria = RestoreIpAddresses() 31 | println(ria.restoreIpAddresses("25525511135")) 32 | println(ria.restoreIpAddresses("0000")) 33 | println(ria.restoreIpAddresses("101023")) 34 | println(ria.restoreIpAddresses("10128111")) 35 | println(ria.restoreIpAddresses("11111111")) 36 | println(ria.restoreIpAddresses("1")) 37 | println(ria.restoreIpAddresses("11")) 38 | } -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/dp/MinFallingPathSum.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.dp; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * https://leetcode.com/problems/minimum-falling-path-sum/ 7 | */ 8 | public class MinFallingPathSum { 9 | public int minFallingPathSum(int[][] matrix) { 10 | int[][] cache = new int[matrix.length][matrix[0].length]; 11 | for (int[] dp : cache) Arrays.fill(dp, Integer.MAX_VALUE); 12 | // DP Tabulation 13 | System.arraycopy(matrix[matrix.length - 1], 0, cache[matrix.length - 1], 0, matrix.length); 14 | for (int row = matrix.length - 2; row >= 0; row--) { 15 | for (int col = 0; col < matrix.length; col++) { 16 | int min = cache[row + 1][col] + matrix[row][col];//down 17 | if (col >= 1) min = Math.min(cache[row + 1][col - 1] + matrix[row][col], min);//left 18 | if (col < matrix[0].length - 1) min = Math.min(cache[row + 1][col + 1] + matrix[row][col], min);//right 19 | cache[row][col] = min; 20 | } 21 | } 22 | return Arrays.stream(cache[0]).min().getAsInt(); 23 | } 24 | 25 | public static void main(String[] args) { 26 | var mfps = new MinFallingPathSum(); 27 | System.out.println(mfps.minFallingPathSum(new int[][]{{2, 1, 3}, {6, 5, 4}, {7, 8, 9}}));//13 28 | System.out.println(mfps.minFallingPathSum(new int[][]{{-19, 57}, {-40, -5}}));//-59 29 | System.out.println(mfps.minFallingPathSum(new int[][]{{-48}}));//-48 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ProblemSolving/Medium/Heap/ConnectRopes.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given n ropes of different lengths, we need to connect these ropes into one rope. 3 | We can connect only 2 ropes at a time. 4 | The cost required to connect 2 ropes is equal to the sum of their lengths. 5 | The length of this connected rope is also equal to the sum of their lengths. 6 | This process is repeated until n ropes are connected into a single rope. 7 | Find the min possible cost required to connect all the ropes. 8 | 9 | Example 1: 10 | ropes = [8, 4, 6, 12] 11 | Output: 58 12 | 13 | Example 2: 14 | ropes = [4, 3, 2, 6] 15 | Output: 29 16 | 17 | Example 3: 18 | ropes = [8, 4, 6, 7, 12] 19 | Output: 84 20 | 21 | Example 4: 22 | ropes = [4, 2, 7, 6, 9] 23 | Output: 62 24 | 25 | Example 5: 26 | ropes = [4, 3, 5, 7, 6, 9] 27 | Output: 86 28 | """ 29 | 30 | """ 31 | https://www.geeksforgeeks.org/connect-n-ropes-minimum-cost/ 32 | """ 33 | 34 | 35 | def connect_ropes(ropes) -> int: 36 | import heapq 37 | total_cost = 0 38 | heapq.heapify(ropes) 39 | while len(ropes) >= 2: 40 | first_rope, second_rope = heapq.heappop(ropes), heapq.heappop(ropes) 41 | total_cost += first_rope + second_rope 42 | heapq.heappush(ropes, first_rope + second_rope) 43 | return total_cost 44 | 45 | 46 | if __name__ == '__main__': 47 | print(connect_ropes([8, 4, 6, 12])) 48 | print(connect_ropes([4, 3, 2, 6])) 49 | print(connect_ropes([8, 4, 6, 7, 12])) 50 | print(connect_ropes([4, 2, 7, 6, 9])) 51 | print(connect_ropes([4, 3, 5, 7, 6, 9])) 52 | 53 | print(connect_ropes([4, 3])) 54 | print(connect_ropes([4])) 55 | 56 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/stack/StockSpanner.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.stack; 2 | 3 | import java.util.Stack; 4 | 5 | /** 6 | * https://leetcode.com/problems/online-stock-span/description/ 7 | */ 8 | public class StockSpanner { 9 | 10 | private static class StockSpan { 11 | int stockPrice; 12 | int span; 13 | 14 | public StockSpan(int stockPrice, int span) { 15 | this.stockPrice = stockPrice; 16 | this.span = span; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return "StockSpan{" + "stockPrice=" + stockPrice + ", span=" + span + '}'; 22 | } 23 | } 24 | 25 | private final Stack spanStack = new Stack<>(); 26 | 27 | public StockSpanner() { 28 | } 29 | 30 | public int next(int price) { 31 | if (spanStack.empty()) spanStack.add(new StockSpan(price, 1)); 32 | else { 33 | int span = 1; 34 | while (!spanStack.empty() && spanStack.peek().stockPrice <= price) { 35 | span += spanStack.pop().span; 36 | } 37 | spanStack.add(new StockSpan(price, span)); 38 | } 39 | return spanStack.peek().span; 40 | } 41 | 42 | public static void main(String[] args) { 43 | StockSpanner ss = new StockSpanner(); 44 | int[] stocks = new int[]{100, 80, 60, 70, 60, 75, 85, 200}; 45 | for (int stock : stocks) { 46 | System.out.println(ss.next(stock)); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /LeetCodeJava/src/test/java/interviews/TalabatInterviewTest.java: -------------------------------------------------------------------------------- 1 | package interviews; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | import static org.junit.jupiter.api.Assertions.assertTrue; 7 | 8 | /** 9 | * White Board 10 | */ 11 | public class TalabatInterviewTest { 12 | /** 13 | * multiply 2 numbers without using x operator. 14 | * NOTE: focus on correctness 15 | **/ 16 | public long multiply(long x, long y) { 17 | if (x < 0 && y < 0) return multiplyHelper(-x, -y); 18 | if (x >= 0 && y >= 0) return multiplyHelper(x, y); 19 | return multiplyHelper(Math.max(x, y), Math.min(x, y));// one of them is -ve 20 | } 21 | 22 | private long multiplyHelper(long x, long y) { 23 | long ans = 0L; 24 | for (long i = 0; i < x; i++) ans += y; 25 | return ans; 26 | } 27 | 28 | @Test 29 | public void test() { 30 | assertEquals(multiply(2, 3), 6); 31 | assertEquals(multiply(-2, 3), -6); 32 | assertEquals(multiply(2, -3), -6); 33 | assertEquals(multiply(-2, -3), 6); 34 | assertEquals(multiply(2, 0), 0); 35 | assertEquals(multiply(0, 2), 0); 36 | assertEquals(multiply(0, -2), 0); 37 | assertEquals(multiply(-2, 0), 0); 38 | assertEquals(multiply(0, 0), 0); 39 | assertTrue(multiply(Integer.MAX_VALUE, Integer.MAX_VALUE) > 0); 40 | assertTrue(multiply(Integer.MIN_VALUE, Integer.MIN_VALUE) > 0); 41 | } 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/linkedlist/LinkedListCycleII.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.linkedlist 2 | 3 | /** 4 | * 142. Linked List Cycle II 5 | * https://leetcode.com/problems/linked-list-cycle-ii/ 6 | */ 7 | class LinkedListCycleII { 8 | data class ListNode(var `val`: Int) { 9 | var next: ListNode? = null 10 | } 11 | 12 | private fun loopIntersection(head: ListNode?): ListNode? { 13 | var slow = head 14 | var fast = head 15 | do { 16 | slow = slow?.next 17 | fast = fast?.next?.next 18 | } while (slow != fast) 19 | return slow 20 | } 21 | 22 | fun detectCycle(head: ListNode?): ListNode? { 23 | val node = loopIntersection(head) ?: return null 24 | var slow = head 25 | var fast = node 26 | while (slow != fast) { 27 | slow = slow?.next 28 | fast = fast.next!! 29 | } 30 | return slow 31 | } 32 | } 33 | 34 | fun main() { 35 | val llc = LinkedListCycleII() 36 | val head = LinkedListCycleII.ListNode(3) 37 | head.next = LinkedListCycleII.ListNode(2) 38 | head.next?.next = LinkedListCycleII.ListNode(0) 39 | head.next?.next?.next = LinkedListCycleII.ListNode(-4) 40 | head.next?.next?.next?.next = head.next 41 | println(llc.detectCycle(head)?.`val`)// 2 42 | val head2 = LinkedListCycleII.ListNode(1) 43 | head2.next = LinkedListCycleII.ListNode(2) 44 | head2.next?.next = head2 45 | println(llc.detectCycle(head2)?.`val`)// 1 46 | val head3 = LinkedListCycleII.ListNode(1) 47 | println(llc.detectCycle(head3))// null 48 | } -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/binarysearch/CapacityShipPackagesDays.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.binarysearch 2 | 3 | /** 4 | * 1011. Capacity To Ship Packages Within D Days 5 | * https://leetcode.com/problems/capacity-to-ship-packages-within-d-days/ 6 | */ 7 | class CapacityShipPackagesDays { 8 | fun shipWithinDays(weights: IntArray, days: Int): Int { 9 | val totalWeight = weights.sum() 10 | val maxWeight = weights.max() 11 | 12 | var (maxCapacity, minCapacity) = totalWeight to maxWeight 13 | while (minCapacity < maxCapacity) { 14 | val currentCapacity = minCapacity + (maxCapacity - minCapacity) / 2 15 | if (canShip(weights, days, currentCapacity)) { 16 | maxCapacity = currentCapacity 17 | } else { 18 | minCapacity = currentCapacity + 1 19 | } 20 | } 21 | return minCapacity 22 | } 23 | 24 | private fun canShip(weights: IntArray, days: Int, capacity: Int): Boolean { 25 | var (daysUsed, currentWeight) = 1 to 0 26 | for (weight in weights) { 27 | if (currentWeight + weight > capacity) { 28 | daysUsed++ 29 | currentWeight = 0 30 | } 31 | currentWeight += weight 32 | } 33 | return daysUsed <= days 34 | } 35 | } 36 | 37 | fun main() { 38 | val cspd = CapacityShipPackagesDays() 39 | println(cspd.shipWithinDays(intArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), 5))// 15 40 | println(cspd.shipWithinDays(intArrayOf(3, 2, 2, 4, 1, 4), 3))// 6 41 | println(cspd.shipWithinDays(intArrayOf(1, 2, 3, 1, 1), 4))// 3 42 | } -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/concurrency/Deadlock.java: -------------------------------------------------------------------------------- 1 | package leetcode.concurrency; 2 | 3 | public class Deadlock { 4 | public static void main(String[] args) { 5 | final String resource1 = "Resource #1"; 6 | final String resource2 = "Resource #2"; 7 | 8 | // Thread 1: Locks resource1 then tries for resource2 9 | Thread t1 = new Thread(() -> { 10 | synchronized (resource1) { 11 | System.out.println("Thread 1: Locked " + resource1); 12 | 13 | try { 14 | Thread.sleep(100); 15 | } catch (Exception e) { 16 | } 17 | 18 | System.out.println("Thread 1: Waiting for " + resource2 + "..."); 19 | 20 | synchronized (resource2) { // Freezes here 21 | System.out.println("Thread 1: Locked " + resource2); 22 | } 23 | } 24 | }); 25 | 26 | // Thread 2: Locks resource2 then tries for resource1 27 | Thread t2 = new Thread(() -> { 28 | synchronized (resource2) { 29 | System.out.println("Thread 2: Locked " + resource2); 30 | 31 | try { 32 | Thread.sleep(100); 33 | } catch (Exception e) { 34 | } 35 | 36 | System.out.println("Thread 2: Waiting for " + resource1 + "..."); 37 | 38 | synchronized (resource1) { // Freezes here 39 | System.out.println("Thread 2: Locked " + resource1); 40 | } 41 | } 42 | }); 43 | 44 | t1.start(); 45 | t2.start(); 46 | } 47 | } -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/easy/stack/BaseBallGame.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.stack; 2 | 3 | import java.util.Arrays; 4 | import java.util.Stack; 5 | 6 | /** 7 | * https://leetcode.com/problems/baseball-game/ 8 | */ 9 | public class BaseBallGame { 10 | public int calPoints(String[] operations) { 11 | Stack stack = new Stack<>(); 12 | for (String op : operations) { 13 | switch (op) { 14 | case "+": 15 | Integer last = stack.pop(); 16 | Integer secondLast = stack.pop(); 17 | stack.addAll(Arrays.asList(secondLast, last, last + secondLast)); 18 | break; 19 | case "D": 20 | stack.push(stack.peek() * 2); 21 | break; 22 | case "C": 23 | stack.pop(); 24 | break; 25 | default: 26 | stack.push(Integer.parseInt(op)); 27 | break; 28 | } 29 | } 30 | return stack.stream().mapToInt(Integer::intValue).sum(); 31 | } 32 | 33 | public static void main(String[] args) { 34 | BaseBallGame bg = new BaseBallGame(); 35 | System.out.println(bg.calPoints(new String[]{"5", "2", "C", "D", "+"})); 36 | System.out.println(bg.calPoints(new String[]{"5", "-2", "4", "C", "D", "9", "+", "+"})); 37 | System.out.println(bg.calPoints(new String[]{"1", "C"})); 38 | System.out.println(bg.calPoints(new String[]{"-60", "D", "-36", "30", "13", "C", "C", "-33", "53", "79"})); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/easy/linkedlist/LinkedListCycle.kt: -------------------------------------------------------------------------------- 1 | package leetcode.easy.linkedlist 2 | 3 | /** 4 | * 141. Linked List Cycle 5 | * https://leetcode.com/problems/linked-list-cycle/ 6 | */ 7 | class LinkedListCycle { 8 | class ListNode(var `val`: Int) { 9 | var next: ListNode? = null 10 | } 11 | 12 | fun hasCycle(head: ListNode?): Boolean { 13 | var tmp = head 14 | val visited = HashSet() 15 | while (tmp != null) { 16 | if (visited.contains(tmp.hashCode())) return true 17 | visited.add(tmp.hashCode()) 18 | tmp = tmp.next 19 | } 20 | return false 21 | } 22 | 23 | fun hasCycleFast(head: ListNode?): Boolean { 24 | if (head?.next == null) return false 25 | var slow = head 26 | var fast = head 27 | while (fast != null) { 28 | fast = fast.next?.next 29 | slow = slow?.next 30 | if (fast == slow) return true 31 | } 32 | return false 33 | } 34 | } 35 | 36 | fun main() { 37 | val s = LinkedListCycle() 38 | val head = LinkedListCycle.ListNode(3) 39 | head.next = LinkedListCycle.ListNode(2) 40 | head.next!!.next = LinkedListCycle.ListNode(0) 41 | head.next!!.next!!.next = LinkedListCycle.ListNode(-4) 42 | head.next!!.next!!.next!!.next = head.next 43 | println(s.hasCycle(head)) // true 44 | println(s.hasCycleFast(head)) // true 45 | 46 | val head2 = LinkedListCycle.ListNode(1) 47 | head2.next = LinkedListCycle.ListNode(2) 48 | head2.next!!.next = head2 49 | println(s.hasCycle(head2)) // true 50 | println(s.hasCycleFast(head2)) // true 51 | } -------------------------------------------------------------------------------- /ProblemSolving/Medium/DP/TargetSumWays.py: -------------------------------------------------------------------------------- 1 | """ 2 | You are given an integer array nums and an integer target. 3 | 4 | You want to build an expression out of nums by adding one of the symbols '+' and '-' before each integer in nums and 5 | then concatenate all the integers. 6 | 7 | For example, if nums = [2, 1], you can add a '+' before 2 and a '-' before 1 and 8 | concatenate them to build the expression "+2-1". 9 | 10 | Return the number of different expressions that you can build, which evaluates to target. 11 | 12 | Input: nums = [1,1,1,1,1], target = 3 13 | Output: 5 14 | 15 | Input: nums = [1], target = 1 16 | Output: 1 17 | """ 18 | 19 | """ 20 | https://leetcode.com/problems/target-sum/ 21 | """ 22 | 23 | 24 | def target_sum_ways_helper(numbers, target, start, memo): 25 | if target == 0 and len(numbers) == start: 26 | return 1 27 | if len(numbers) <= start: 28 | return 0 29 | if (target, start) in memo: 30 | return memo[(target, start)] 31 | positive_inclusion = target_sum_ways_helper(numbers, target + numbers[start], start + 1, memo) 32 | negative_inclusion = target_sum_ways_helper(numbers, target - numbers[start], start + 1, memo) 33 | memo[(target, start)] = positive_inclusion + negative_inclusion 34 | return memo[(target, start)] 35 | 36 | 37 | def target_sum_ways(numbers, target): 38 | return target_sum_ways_helper(numbers, target, 0, {}) 39 | 40 | 41 | if __name__ == '__main__': 42 | print(target_sum_ways([1, 1, 1, 1, 1], 3)) 43 | print(target_sum_ways([1], 1)) 44 | print(target_sum_ways([16, 40, 9, 17, 49, 32, 30, 10, 38, 36, 31, 22, 3, 36, 32, 2, 26, 17, 30, 47], 49)) 45 | print(target_sum_ways([1, 0], 1)) 46 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/greedy/ZigZagConversion.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.greedy; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * https://www.geeksforgeeks.org/convert-array-into-zig-zag-fashion 7 | */ 8 | public class ZigZagConversion { 9 | 10 | // a[0] < a[1] > a[2] < a[3] > a[4] < a[5] > a[6] < a[7] > a[8] < a[9] 11 | public int[] convert(int[] arr) { 12 | for (int i = 0; i < arr.length; i++) { 13 | if (i % 2 == 0) { 14 | if (i + 1 < arr.length && arr[i] > arr[i + 1]) { 15 | swap(arr, i, i + 1); 16 | } 17 | } else { 18 | if (i + 1 < arr.length && arr[i] < arr[i + 1]) { 19 | swap(arr, i, i + 1); 20 | } 21 | } 22 | } 23 | return arr; 24 | } 25 | 26 | private void swap(int[] arr, int i, int i1) { 27 | int temp = arr[i]; 28 | arr[i] = arr[i1]; 29 | arr[i1] = temp; 30 | } 31 | 32 | public static void main(String[] args) { 33 | var zigZagConversion = new ZigZagConversion(); 34 | System.out.println(Arrays.toString(zigZagConversion.convert(new int[]{4, 3, 7, 8, 6, 2, 1}))); 35 | System.out.println(Arrays.toString(zigZagConversion.convert(new int[]{1, 4, 3, 2}))); 36 | System.out.println(Arrays.toString(zigZagConversion.convert(new int[]{1, 4, 3, 2, 5}))); 37 | System.out.println(Arrays.toString(zigZagConversion.convert(new int[]{1, 4, 3, 2, 5, 6}))); 38 | System.out.println(Arrays.toString(zigZagConversion.convert(new int[]{1, 2, 3, 4, 5, 6, 7}))); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/concurrency/FooBar.java: -------------------------------------------------------------------------------- 1 | package leetcode.concurrency; 2 | 3 | import java.util.concurrent.Semaphore; 4 | 5 | /** 6 | * 1115. Print FooBar Alternately 7 | */ 8 | public class FooBar { 9 | private final int n; 10 | private final Semaphore foo = new Semaphore(1); 11 | private final Semaphore bar = new Semaphore(0); 12 | 13 | public FooBar(int n) { 14 | this.n = n; 15 | } 16 | 17 | public void foo(Runnable printFoo) throws InterruptedException { 18 | for (int i = 0; i < n; i++) { 19 | foo.acquire(); 20 | printFoo.run(); 21 | bar.release(); 22 | } 23 | } 24 | 25 | public void bar(Runnable printBar) throws InterruptedException { 26 | for (int i = 0; i < n; i++) { 27 | bar.acquire(); 28 | printBar.run(); 29 | foo.release(); 30 | } 31 | } 32 | 33 | public static void main(String[] args) throws InterruptedException { 34 | FooBar fooBar = new FooBar(5); 35 | Thread foo = new Thread(() -> { 36 | try { 37 | fooBar.foo(() -> System.out.print("foo")); 38 | } catch (InterruptedException e) { 39 | e.printStackTrace(); 40 | } 41 | }); 42 | Thread bar = new Thread(() -> { 43 | try { 44 | fooBar.bar(() -> System.out.print("bar")); 45 | } catch (InterruptedException e) { 46 | e.printStackTrace(); 47 | } 48 | }); 49 | foo.start(); 50 | bar.start(); 51 | 52 | foo.join(); 53 | bar.join(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/dp/OutBoundaryPaths.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.dp; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * 576. Out of Boundary Paths 7 | */ 8 | public class OutBoundaryPaths { 9 | private static final int MOD = 1_000_000_007; 10 | private static final int[][] DIRECTIONS = new int[][]{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; 11 | private final int[][][] cache = new int[50][50][51]; 12 | 13 | private void initializeCache() { 14 | for (int[][] arr2D : cache) for (int j = 0; j < cache[0].length; j++) Arrays.fill(arr2D[j], -1); 15 | } 16 | 17 | OutBoundaryPaths() { 18 | initializeCache(); 19 | } 20 | 21 | public int findPaths(int m, int n, int maxMove, int startRow, int startColumn) { 22 | if (maxMove < 0) return 0; 23 | if (startRow < 0 || startColumn < 0 || startRow >= m || startColumn >= n) return 1; 24 | if (cache[startRow][startColumn][maxMove] != -1) return cache[startRow][startColumn][maxMove]; 25 | int paths = 0; 26 | for (int[] dir : DIRECTIONS) 27 | paths = (paths + findPaths(m, n, maxMove - 1, startRow + dir[0], startColumn + dir[1]) % MOD) % MOD; 28 | return (cache[startRow][startColumn][maxMove] = paths); 29 | } 30 | 31 | public static void main(String[] args) { 32 | var obp = new OutBoundaryPaths(); 33 | System.out.println(obp.findPaths(2, 2, 2, 0, 0));//6 34 | System.out.println(obp.findPaths(1, 3, 3, 0, 1));//13 35 | System.out.println(obp.findPaths(8, 7, 16, 1, 5));//114385532 36 | System.out.println(obp.findPaths(50, 50, 50, 25, 25));//496204127 37 | } 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/easy/dp/IsSubsequence.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.dp; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * https://leetcode.com/problems/is-subsequence/description/ 7 | */ 8 | public class IsSubsequence { 9 | 10 | public int isSubsequence(String main, int i, String sub, int j, int[][] cache) { 11 | if (i >= main.length() || j >= sub.length()) return 0; 12 | if (cache[i][j] != -1) return cache[i][j]; 13 | int result = 0; 14 | if (main.charAt(i) == sub.charAt(j)) { 15 | if (j == sub.length() - 1) result = 1; 16 | else result = isSubsequence(main, i + 1, sub, j + 1, cache); 17 | } 18 | cache[i][j] = result <= 0 ? isSubsequence(main, i + 1, sub, j, cache) : result; 19 | return cache[i][j]; 20 | } 21 | 22 | public boolean isSubsequence(String sub, String main) { 23 | if (sub.isEmpty()) return true; 24 | int[][] cache = new int[main.length()][sub.length()]; 25 | for (final int[] line : cache) Arrays.fill(line, -1); 26 | return isSubsequence(main, 0, sub, 0, cache) == 1; 27 | } 28 | 29 | public static void main(String[] args) { 30 | IsSubsequence is = new IsSubsequence(); 31 | System.out.println(is.isSubsequence("abc", "ahbgdc")); 32 | System.out.println(is.isSubsequence("axc", "ahbgdc")); 33 | System.out.println(is.isSubsequence("axc", "ahbgdcxfiowetuioewc")); 34 | System.out.println(is.isSubsequence("abc", "nmajkhobqwertyucp")); 35 | System.out.println(is.isSubsequence("abc", "najbkcp")); 36 | System.out.println(is.isSubsequence("", "abcdef")); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /SystemDesign/Easy/AnagramCalculator.py: -------------------------------------------------------------------------------- 1 | """ 2 | Code samples: 3 | Anagrams.py 4 | Anagram++.py 5 | MultiThreadedAnagram.py 6 | 7 | Design doc: 8 | https://whimsical.com/anagramservice-82Xa6ZibRcMWXV1hxcGiCo 9 | """ 10 | 11 | """ 12 | An anagram of a string is another string that contains the same characters, only the order of characters can be different. 13 | NOTE : Assume english language alphabets in lowercase for now. 14 | For example, 15 | 1. "abcd" & "dabc" - YES 16 | 2. "abccc" & "abc" - NO 17 | 3. "xyz" & "abc" - NO 18 | 4. "silent" & "listen" - YES 19 | 20 | Design a system that takes in 2 huge text files from a user and computes if they are anagrams or not. 21 | Scale: 100k requests per day and 100 GB max size per file. 22 | """ 23 | 24 | """ 25 | FR: 26 | 1. For simplicity, we will assume that huge files are stored in a cloud storage like S3. 27 | (I expect the interviewee to come up with this to keep the scope of the problem limited) 28 | 2. A simple UI for users to interact with the system. Put the 2 file paths and click on a button to check if they are anagrams or not. 29 | 3. The system should notify the user if the files are anagrams or not. 30 | (Notification system is out of scope, use any 3rd party service like Twilio or Sendgrid) 31 | 32 | 33 | NFR: 34 | 1. Scalability: 100k requests per day and 100 GB max size per file. 35 | 2. Performance: The system should be able to process the files quickly. 36 | (Realtime response is not required but it should be within a few seconds) 37 | 3. Availability: The system should be available 24x7. 38 | 4. Cost: The system should be cost effective. 39 | 5. Reliability:-The system should be reliable. Partial processing of files should not happen. 40 | 6. Monitoring: The system should be monitored. 41 | """ 42 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/graph/NumberOfProvinces.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.graph; 2 | 3 | import java.util.HashSet; 4 | import java.util.LinkedList; 5 | import java.util.Queue; 6 | import java.util.Set; 7 | 8 | /** 9 | * https://leetcode.com/problems/number-of-provinces/ 10 | */ 11 | public class NumberOfProvinces { 12 | 13 | private void bfs(int startCity, int[][] isConnected, Set visited) { 14 | Queue bfsQ = new LinkedList<>(); 15 | bfsQ.add(startCity); 16 | while (!bfsQ.isEmpty()) { 17 | int visitedCity = bfsQ.remove(); 18 | visited.add(visitedCity); 19 | for (int neighbour = 0; neighbour < isConnected.length; neighbour++) { 20 | if (isConnected[visitedCity][neighbour] == 1 && !visited.contains(neighbour)) { 21 | bfsQ.add(neighbour); 22 | } 23 | } 24 | } 25 | } 26 | 27 | public int findNumberOfProvinces(int[][] isConnected) { 28 | Set visited = new HashSet<>(); 29 | int numProvinces = 0; 30 | for (int city = 0; city < isConnected.length; city++) { 31 | if (visited.contains(city)) continue; 32 | bfs(city, isConnected, visited); 33 | numProvinces++; 34 | } 35 | return numProvinces; 36 | } 37 | 38 | public static void main(String[] args) { 39 | NumberOfProvinces nop = new NumberOfProvinces(); 40 | System.out.println(nop.findNumberOfProvinces(new int[][]{{1, 1, 0}, {1, 1, 0}, {0, 0, 1}})); //2 41 | System.out.println(nop.findNumberOfProvinces(new int[][]{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}})); //3 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/array/prefixsum/SubarraySumEqualK.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.array.prefixsum 2 | 3 | /** 4 | * 560. Subarray Sum Equals K 5 | * https://leetcode.com/problems/subarray-sum-equals-k/ 6 | */ 7 | class SubarraySumEqualK { 8 | fun subarraySumK(nums: IntArray, k: Int): Int { 9 | val (prefixSum, lookup) = computePrefixSum(nums) 10 | var total = 0 11 | for (index in nums.indices) { 12 | if (prefixSum[index] == k) total++ 13 | val target = prefixSum[index] - k // prefix[j] - prefix[i] = k 14 | if (lookup.containsKey(target)) { 15 | val totalPreviousIndices = lookup[target]!!.binarySearch(index).let { if (it < 0) -it - 1 else it } 16 | total += totalPreviousIndices 17 | } 18 | } 19 | return total 20 | } 21 | 22 | private fun computePrefixSum(nums: IntArray): Pair>> { 23 | val prefixSum = IntArray(nums.size) 24 | prefixSum[0] = nums[0] 25 | val lookup = mutableMapOf(prefixSum[0] to mutableListOf(0)) 26 | for (i in 1 until nums.size) { 27 | prefixSum[i] = prefixSum[i - 1] + nums[i] 28 | lookup.computeIfAbsent(prefixSum[i]) { mutableListOf() }.add(i) 29 | } 30 | return Pair(prefixSum, lookup) 31 | } 32 | } 33 | 34 | fun main() { 35 | val ssek = SubarraySumEqualK() 36 | println(ssek.subarraySumK(intArrayOf(1, 2, 1, 2, 1), 3))// 4 37 | println(ssek.subarraySumK(intArrayOf(1, 1, 1), 2))// 2 38 | println(ssek.subarraySumK(intArrayOf(1, 2, 3), 3))// 2 39 | println(ssek.subarraySumK(intArrayOf(1, 2, 3), 4))// 0 40 | println(ssek.subarraySumK(intArrayOf(1, 2, 3), 5))// 1 41 | } 42 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/design/MyHashSet.java: -------------------------------------------------------------------------------- 1 | package leetcode.design; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * 705. Design HashSet 7 | */ 8 | class MyGenericHashSet { 9 | final int INIT_CAPACITY = 1 << 13; 10 | @SuppressWarnings("unchecked") 11 | final LinkedList[] buckets = new LinkedList[INIT_CAPACITY]; 12 | 13 | public MyGenericHashSet() { 14 | } 15 | 16 | public void add(K key) { 17 | if (!contains(key)) getBucket(key).add(key); 18 | } 19 | 20 | public void remove(K key) { 21 | getBucket(key).remove(key); 22 | } 23 | 24 | public boolean contains(K key) { 25 | return getBucket(key).contains(key); 26 | } 27 | 28 | private int getBucketId(K key) { 29 | return key.hashCode() & (buckets.length - 1); 30 | } 31 | 32 | private LinkedList getBucket(K key) { 33 | if (buckets[getBucketId(key)] == null) buckets[getBucketId(key)] = new LinkedList<>(); 34 | return buckets[getBucketId(key)]; 35 | } 36 | } 37 | 38 | public class MyHashSet extends MyGenericHashSet { 39 | public static void main(String[] args) { 40 | MyHashSet hashSet = new MyHashSet(); 41 | hashSet.add(1); 42 | hashSet.add(2); 43 | System.out.println(hashSet.contains(1)); // returns true 44 | System.out.println(hashSet.contains(3)); // returns false (not found) 45 | System.out.println(hashSet.contains(2)); // returns true 46 | hashSet.add(2); 47 | System.out.println(hashSet.contains(2)); // returns true 48 | hashSet.remove(2); 49 | System.out.println(hashSet.contains(2)); // returns false (already removed) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/easy/binarysearch/FirstBadVersion.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.binarysearch; 2 | 3 | /** 4 | * https://leetcode.com/problems/first-bad-version/ 5 | */ 6 | public class FirstBadVersion { 7 | private final int bad; 8 | 9 | private FirstBadVersion(int bad) { 10 | this.bad = bad; 11 | } 12 | 13 | private boolean isBadVersion(int version) { 14 | return version >= bad; 15 | } 16 | 17 | public int firstBadVersion(int n) { 18 | return firstBadVersion(1, n); 19 | } 20 | 21 | private int firstBadVersion(int start, int end) { 22 | int mid = (start + end) >>> 1; // avoids overflows 23 | boolean isMidBad = isBadVersion(mid); 24 | if (isMidBad) { 25 | boolean isPrevBad = isBadVersion(mid - 1); 26 | if (isPrevBad) return firstBadVersion(start, mid - 1); 27 | else return mid; 28 | } else { 29 | boolean isNextBad = isBadVersion(mid + 1); 30 | if (isNextBad) return mid + 1; 31 | else return firstBadVersion(mid + 1, end); 32 | } 33 | } 34 | 35 | public static void main(String[] args) { 36 | System.out.println(new FirstBadVersion(4).firstBadVersion(5)); //4 37 | System.out.println(new FirstBadVersion(1).firstBadVersion(1)); //1 38 | System.out.println(new FirstBadVersion(3).firstBadVersion(7)); //3 39 | System.out.println(new FirstBadVersion(6).firstBadVersion(7)); //6 40 | System.out.println(new FirstBadVersion(1702766719).firstBadVersion(2126753390)); //1702766719 41 | System.out.println(new FirstBadVersion(Integer.MAX_VALUE / 2).firstBadVersion(Integer.MAX_VALUE)); //1073741823 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/dp/LongestCommonSubsequence.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.dp; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * https://leetcode.com/problems/longest-common-subsequence/ 7 | */ 8 | public class LongestCommonSubsequence { 9 | 10 | private int longestCommonSubsequence(String s, int i, String t, int j, int[][] cache) { 11 | if (i >= s.length() || j >= t.length()) return 0; 12 | if (cache[i][j] != -1) return cache[i][j]; 13 | if (s.charAt(i) == t.charAt(j)) return (cache[i][j] = 1 + longestCommonSubsequence(s, i + 1, t, j + 1, cache)); 14 | int moveBoth = longestCommonSubsequence(s, i + 1, t, j + 1, cache); 15 | int moveS = longestCommonSubsequence(s, i + 1, t, j, cache); 16 | int moveT = longestCommonSubsequence(s, i, t, j + 1, cache); 17 | return (cache[i][j] = Math.max(moveS, Math.max(moveT, moveBoth))); 18 | } 19 | 20 | public int longestCommonSubsequence(String s, String t) { 21 | int[][] cache = new int[s.length()][t.length()]; 22 | for (int[] dp : cache) Arrays.fill(dp, -1); 23 | return longestCommonSubsequence(s, 0, t, 0, cache); 24 | } 25 | 26 | public static void main(String[] args) { 27 | var lcs = new LongestCommonSubsequence(); 28 | System.out.println(lcs.longestCommonSubsequence("abcde", "ace"));//3 29 | System.out.println(lcs.longestCommonSubsequence("abc", "abc"));//3 30 | System.out.println(lcs.longestCommonSubsequence("abc", "def"));//0 31 | System.out.println(lcs.longestCommonSubsequence("bsbininm", "jmjkbkjkv"));//1 32 | System.out.println(lcs.longestCommonSubsequence("oxcpqrsvwf", "shmtulqrypy"));//2 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/dp/MaxSumCircularSubarray.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.dp 2 | 3 | /** 4 | * 918. Maximum Sum Circular Subarray 5 | * https://leetcode.com/problems/maximum-sum-circular-subarray/ 6 | */ 7 | class MaxSumCircularSubarray { 8 | fun maxSubarraySumCircular(nums: IntArray): Int { 9 | if (nums.all { it < 0 }) return nums.max() 10 | val linearSubArrayMinSum = kadanesAlgorithm(nums) { a, b -> minOf(a, b) } 11 | val circularSubArrayMaxSum = nums.sum() - linearSubArrayMinSum 12 | val linearSubArrayMaxSum = kadanesAlgorithm(nums) { a, b -> maxOf(a, b) } 13 | return maxOf(linearSubArrayMaxSum, circularSubArrayMaxSum) 14 | } 15 | 16 | private fun kadanesAlgorithm(nums: IntArray, f: (a: Int, b: Int) -> Int): Int { 17 | var maxSum = nums[0] 18 | var currSum = 0 19 | for (num in nums) { 20 | currSum = f(num, currSum + num) 21 | maxSum = f(maxSum, currSum) 22 | } 23 | return maxSum 24 | } 25 | } 26 | 27 | fun main() { 28 | val mcs = MaxSumCircularSubarray() 29 | println(mcs.maxSubarraySumCircular(intArrayOf(-3, -2, -3)))//-2 30 | println(mcs.maxSubarraySumCircular(intArrayOf(-2, -3, -1)))//-1 31 | println(mcs.maxSubarraySumCircular(intArrayOf(1, -2, 3, -2)))//3 32 | println(mcs.maxSubarraySumCircular(intArrayOf(5, -3, 5)))//10 33 | println(mcs.maxSubarraySumCircular(intArrayOf(3, -1, 2, -1)))//4 34 | println(mcs.maxSubarraySumCircular(intArrayOf(3, -2, 2, -3)))//3 35 | println(mcs.maxSubarraySumCircular(intArrayOf(1, 2, 3, -2, -3, -1, 2)))//8 36 | println(mcs.maxSubarraySumCircular(intArrayOf(1, 2, 3, 4, 5, 6, 100)))//121 37 | println(mcs.maxSubarraySumCircular(intArrayOf(-1, -2, -3, 100, -4, -5, -10)))//100 38 | } 39 | -------------------------------------------------------------------------------- /ProblemSolving/Hard/Trees/LCADeepestLeaves.py: -------------------------------------------------------------------------------- 1 | """ 2 | Find the root of the smallest subtree which contains all the deepest leaf nodes. 3 | 4 | 1 5 | / \ 6 | 2 3 7 | / \ / \ 8 | 4 5 6 7 9 | / \ \ \ 10 | 11 10 8 9 11 | """ 12 | 13 | """ 14 | https://leetcode.com/problems/lowest-common-ancestor-of-deepest-leaves/ 15 | https://leetcode.com/problems/smallest-subtree-with-all-the-deepest-nodes/ 16 | """ 17 | 18 | from ProblemSolving.Hard.Trees.Model.TreeNodeModel import TreeNode, create_mock_binary_tree 19 | 20 | 21 | def lca_deepest_leaves_helper(root: TreeNode, level: int) -> (int, TreeNode): 22 | if root is None: 23 | return -1, None 24 | if root.left is None and root.right is None: 25 | return level, root 26 | max_left_level, left_lca = lca_deepest_leaves_helper(root.left, level + 1) 27 | max_right_level, right_lca = lca_deepest_leaves_helper(root.right, level + 1) 28 | if max_left_level == max_right_level: 29 | return max_left_level, root 30 | max_level = max(max_right_level, max_left_level) 31 | max_lca = left_lca if max_level == max_left_level else right_lca 32 | return max_level, max_lca 33 | 34 | 35 | def lca_deepest_leaves(root: TreeNode) -> TreeNode: 36 | max_level, lca = lca_deepest_leaves_helper(root, 1) 37 | return lca 38 | 39 | 40 | if __name__ == '__main__': 41 | node = create_mock_binary_tree() 42 | node.right.right.right = TreeNode(9) 43 | node.right.left.right = TreeNode(8) 44 | node.left.left.right = TreeNode(10) 45 | node.left.left.left = TreeNode(11) 46 | print(lca_deepest_leaves(node).val) 47 | print(lca_deepest_leaves(node.left).val) 48 | print(lca_deepest_leaves(node.right).val) 49 | -------------------------------------------------------------------------------- /LeetCodeJava/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.practice.algo 8 | JavaLeetCode 9 | 1.0-SNAPSHOT 10 | JavaLeetCode 11 | 12 | 13 | UTF-8 14 | 1.8 15 | 1.8 16 | 5.8.2 17 | 18 | 19 | 20 | 21 | 22 | org.junit.jupiter 23 | junit-jupiter-api 24 | ${junit.version} 25 | test 26 | 27 | 28 | org.junit.jupiter 29 | junit-jupiter-engine 30 | ${junit.version} 31 | test 32 | 33 | 34 | 35 | 36 | 37 | 38 | org.apache.maven.plugins 39 | maven-compiler-plugin 40 | 41 | 16 42 | 16 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /LeetCodeJava/src/test/java/interviews/GlovoInterviewTest.java: -------------------------------------------------------------------------------- 1 | package interviews; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | import java.util.*; 8 | import java.util.stream.*; 9 | 10 | public class GlovoInterviewTest { 11 | 12 | // Problem 1 13 | public List missingProducts(List requested, List delivered) { 14 | var map = new TreeMap(); 15 | requested.forEach(p -> map.merge(p, 1, Integer::sum)); 16 | delivered.forEach(p -> map.merge(p, -1, Integer::sum)); 17 | 18 | return map.entrySet().stream() 19 | .filter(e -> e.getValue() > 0) 20 | .map(Map.Entry::getKey) 21 | .toList(); 22 | } 23 | 24 | 25 | // Problem 2 26 | public int countPairs(List socks) { 27 | var map = new HashMap(); 28 | socks.forEach(s -> map.merge(s, 1, Integer::sum)); 29 | return map.values().stream().mapToInt(sockCount -> sockCount / 2).sum(); 30 | } 31 | 32 | @Test 33 | public void testMissingProducts() { 34 | assertEquals(missingProducts(Arrays.asList(1, 3, 5), Arrays.asList(5, 3, 1)), Collections.emptyList()); 35 | assertEquals(missingProducts(Arrays.asList(11, 2, 4, 11, 11, 2, 3), Arrays.asList(2, 4, 2, 11)), Arrays.asList(3, 11)); 36 | } 37 | 38 | @Test 39 | public void testCountPairs() { 40 | assertEquals(countPairs(Arrays.asList(4, 4, 4, 4, 4, 5, 5)), 3); 41 | assertEquals(countPairs(Arrays.asList(4, 7, 3, 7, 4, 1, 8)), 2); 42 | assertEquals(countPairs(List.of(4)), 0); 43 | assertEquals(countPairs(Arrays.asList(4, 5, 6)), 0); 44 | assertEquals(countPairs(Arrays.asList(4, 5, 6, 6)), 1); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/array/prefixsum/SubarraySumEqualModuloK.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.array.prefixsum 2 | 3 | /** 4 | * 974. Subarray Sums Divisible by K 5 | * https://leetcode.com/problems/subarray-sums-divisible-by-k 6 | */ 7 | class SubarraySumDivisibleByK { 8 | fun subarraysDivByK(nums: IntArray, k: Int): Int { 9 | val (prefixSum, lookup) = computePrefixSum(nums, k) 10 | var total = 0 11 | for (index in nums.indices) { 12 | if (prefixSum[index] == 0) total++ 13 | val target = prefixSum[index] // (prefix[j] - prefix[i]) mod k = 0 14 | if (lookup.containsKey(target)) { 15 | val totalPreviousIndices = lookup[target]!!.binarySearch(index).let { if (it < 0) -it - 1 else it } 16 | total += totalPreviousIndices 17 | } 18 | } 19 | return total 20 | } 21 | 22 | private fun computePrefixSum(nums: IntArray, k: Int): Pair>> { 23 | val prefixSum = IntArray(nums.size) 24 | prefixSum[0] = ((nums[0].rem(k)) + k) % k 25 | val lookup = mutableMapOf(prefixSum[0] to mutableListOf(0)) 26 | for (i in 1 until nums.size) { 27 | prefixSum[i] = ((prefixSum[i - 1] + nums[i]).rem(k) + k) % k 28 | lookup.computeIfAbsent(prefixSum[i]) { mutableListOf() }.add(i) 29 | } 30 | return Pair(prefixSum, lookup) 31 | } 32 | } 33 | 34 | fun main() { 35 | val ssdbk = SubarraySumDivisibleByK() 36 | println(ssdbk.subarraysDivByK(intArrayOf(4, 5, 0, -2, -3, 1), 5))// 7 37 | println(ssdbk.subarraysDivByK(intArrayOf(-1, 2, 9), 2))// 2 38 | println(ssdbk.subarraysDivByK(intArrayOf(1, 2, 3), 3))// 3 39 | println(ssdbk.subarraysDivByK(intArrayOf(1, 2, 3), 4))// 0 40 | } 41 | -------------------------------------------------------------------------------- /ProblemSolving/Hard/Trie/TriePrefixSuggestions.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | 4 | 5 | """ 6 | from ProblemSolving.Hard.Trie.Model.TrieNodeModel import TrieNode 7 | 8 | 9 | def insert_word(root: TrieNode, word: str): 10 | crawler = root 11 | for c in word: 12 | ascii_code = ord(c) 13 | if crawler.children[ascii_code] is None: 14 | crawler.children[ascii_code] = TrieNode() 15 | crawler = crawler.children[ascii_code] 16 | crawler.is_word_ending = True 17 | 18 | 19 | def retrieve_all_words(root: TrieNode): 20 | def retrieve_all_helper(crawler, acc, words): 21 | if crawler is None: 22 | return 23 | if crawler.is_word_ending: 24 | words.append(acc) 25 | for i in range(len(crawler.children)): 26 | retrieve_all_helper(crawler.children[i], acc + chr(i), words) 27 | 28 | words = [] 29 | retrieve_all_helper(root, '', words) 30 | return words 31 | 32 | 33 | def search_prefix(root: TrieNode, word: str): 34 | crawler = root 35 | for c in word: 36 | ascii_code = ord(c) 37 | if crawler.children[ascii_code] is None: 38 | return None 39 | crawler = crawler.children[ascii_code] 40 | return crawler 41 | 42 | 43 | def typeahead_suggestions(root: TrieNode, prefix: str): 44 | suffixes = retrieve_all_words(search_prefix(root, prefix)) 45 | return [prefix + suffix for suffix in suffixes] 46 | 47 | 48 | if __name__ == '__main__': 49 | root = TrieNode() 50 | insert_word(root, 'freeze') 51 | insert_word(root, 'freeze is a programmer') 52 | insert_word(root, 'freezer') 53 | insert_word(root, 'freezing') 54 | insert_word(root, 'free') 55 | insert_word(root, 'trie data structure') 56 | print(retrieve_all_words(root)) 57 | print(typeahead_suggestions(root, 'freez')) 58 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/arrays/prefixsum/MinAverageDifference.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.arrays.prefixsum; 2 | 3 | /** 4 | * https://leetcode.com/problems/minimum-average-difference-between-two-arrays/ 5 | */ 6 | public class MinAverageDifference { 7 | 8 | public int minimumAverageDifference(int[] nums) { 9 | long[] prefixSum = new long[nums.length]; 10 | prefixSum[0] = nums[0]; 11 | for (int i = 1; i < nums.length; i++) prefixSum[i] = prefixSum[i - 1] + nums[i]; 12 | long totalSum = prefixSum[nums.length - 1]; 13 | long minAvgDiff = totalSum / nums.length; 14 | int minIndex = nums.length - 1; 15 | for (int i = 0; i < nums.length - 1; i++) { 16 | long avgDiff = Math.abs((prefixSum[i] / (i + 1)) - ((totalSum - prefixSum[i]) / (nums.length - i - 1))); 17 | if (avgDiff < minAvgDiff) { 18 | minAvgDiff = avgDiff; 19 | minIndex = i; 20 | } else if (avgDiff == minAvgDiff) minIndex = Math.min(minIndex, i); 21 | } 22 | return minIndex; 23 | } 24 | 25 | public static void main(String[] args) { 26 | var mvd = new MinAverageDifference(); 27 | System.out.println(mvd.minimumAverageDifference(new int[]{0})); // 0 28 | System.out.println(mvd.minimumAverageDifference(new int[]{10})); //0 29 | System.out.println(mvd.minimumAverageDifference(new int[]{1, 2, 3, 4})); // 0 30 | System.out.println(mvd.minimumAverageDifference(new int[]{3, 7})); // 0 31 | System.out.println(mvd.minimumAverageDifference(new int[]{6, 2, 6, 5, 1, 2, 0, 7, 0, 1})); // 5 32 | System.out.println(mvd.minimumAverageDifference(new int[]{2, 5, 3, 9, 5, 3})); // 3 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SystemDesign/Easy/BasicArchitectureBeginners.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a basic architecture for simple/minimal booking system that supports 1k users today. 3 | 4 | Frontend (1 server) <---> Backend Rest API (1 server) <---> SQL Database (1 server) 5 | 6 | Frontend - showcases a static list of 100 hotels 7 | Backend - handles all data needs of FE 8 | Database - stores all the user, hotel and booking info. 9 | 10 | Features supported today 11 | - make a booking - book a hotel with checkin and checkout date. payments are out of scope, assume pay at hotel for now. 12 | - see past bookings - all booking made by user in the past. 13 | - basic user profile - name, email, phone, language, currency etc. 14 | 15 | Architectural changes to scale this system for 1 million+ users? 16 | How to guarantee 99.9% uptime? 17 | """ 18 | 19 | """ 20 | Challenge more : 21 | Slow db queries? 22 | How to handle traffic spikes? 23 | Slow backend? How to debug? 24 | Frontend loading very slowly? How to debug? 25 | New requirement to add Payment service. A payment takes 1 minute to process. 26 | New requirement to track user activity data from frontend. How to handle realtime vs delayed statistics? 27 | How to generate unique bookingId across DCs? 28 | 1 billion users? 29 | 30 | Expectation: 31 | - horizontal scaling of backend api and frontend with LB. 32 | - autoscaling for peak traffic by request rates 33 | - caching layer for slow changing data 34 | - master-slave db architecture (geo sharded if billion users) 35 | - db indexing for queries 36 | - CDN for static content for frontend. 37 | - group the traffic to reads and writes (80:20 read-write ratio) and optimise these paths. 38 | - microservice architecture preferred. (user service, booking service) 39 | - User activity tracking is done by sending message to kafka --> hadoop --> map reduce aggregator --> Data Warehouse 40 | """ 41 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/hard/heap/MedianFinder.java: -------------------------------------------------------------------------------- 1 | package leetcode.hard.heap; 2 | 3 | import java.util.PriorityQueue; 4 | 5 | /** 6 | * https://leetcode.com/problems/find-median-from-data-stream/description/ 7 | */ 8 | public class MedianFinder { 9 | private final PriorityQueue leftMaxHeap = new PriorityQueue<>((a, b) -> -(a.compareTo(b))); 10 | private final PriorityQueue rightMinHeap = new PriorityQueue<>(); 11 | 12 | public MedianFinder() { 13 | } 14 | 15 | private void balance() { 16 | if (leftMaxHeap.size() > rightMinHeap.size() + 1) { 17 | rightMinHeap.add(leftMaxHeap.remove()); 18 | } 19 | if (rightMinHeap.size() > leftMaxHeap.size() + 1) { 20 | leftMaxHeap.add(rightMinHeap.remove()); 21 | } 22 | } 23 | 24 | public void addNum(int num) { 25 | if (!leftMaxHeap.isEmpty() && num >= leftMaxHeap.peek()) { 26 | rightMinHeap.add(num); 27 | } else { 28 | leftMaxHeap.add(num); 29 | } 30 | balance(); 31 | } 32 | 33 | public double findMedian() { 34 | if (leftMaxHeap.size() == rightMinHeap.size()) return (leftMaxHeap.peek() + rightMinHeap.peek()) / 2.0; 35 | if (leftMaxHeap.size() > rightMinHeap.size()) return leftMaxHeap.peek(); 36 | return rightMinHeap.peek(); 37 | } 38 | 39 | public static void main(String[] args) { 40 | MedianFinder mf = new MedianFinder(); 41 | for (int i = 0; i < 10; i++) { 42 | mf.addNum(i); 43 | System.out.println(mf.findMedian()); 44 | } 45 | for (int i = -9; i < 0; i++) { 46 | mf.addNum(i); 47 | System.out.println(mf.findMedian()); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/graph/AllPathsSourceTarget.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.graph; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | import java.util.Queue; 7 | 8 | /** 9 | * 797. All Paths From Source to Target 10 | * https://leetcode.com/problems/all-paths-from-source-to-target/ 11 | */ 12 | public class AllPathsSourceTarget { 13 | private static class BfsNode { 14 | int vertex; 15 | List path; 16 | 17 | BfsNode(int vertex, List path) { 18 | this.vertex = vertex; 19 | this.path = path; 20 | } 21 | } 22 | 23 | public List> allPathsSourceTarget(int[][] graph) { 24 | Queue queue = new LinkedList<>(); 25 | List> result = new ArrayList<>(); 26 | queue.add(new BfsNode(0, new ArrayList<>())); 27 | while (!queue.isEmpty()) { 28 | BfsNode node = queue.poll(); 29 | node.path.add(node.vertex); 30 | if (node.vertex == graph.length - 1) { 31 | result.add(node.path); 32 | } else { 33 | for (int nextNode : graph[node.vertex]) queue.add(new BfsNode(nextNode, new ArrayList<>(node.path))); 34 | } 35 | } 36 | return result; 37 | } 38 | 39 | public static void main(String[] args) { 40 | var apst = new AllPathsSourceTarget(); 41 | //[[0, 1, 3], [0, 2, 3]] 42 | System.out.println(apst.allPathsSourceTarget(new int[][]{{1, 2}, {3}, {3}, {}})); 43 | //[[0, 4], [0, 3, 4], [0, 1, 3, 4], [0, 1, 2, 3, 4], [0, 1, 4]] 44 | System.out.println(apst.allPathsSourceTarget(new int[][]{{4, 3, 1}, {3, 2, 4}, {3}, {4}, {}})); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/backtracking/PalindromePartitions.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.backtracking 2 | 3 | /** 4 | * 131. Palindrome Partitioning 5 | * https://leetcode.com/problems/palindrome-partitioning/ 6 | */ 7 | class PalindromePartitions { 8 | fun partition(s: String) = partition(s, 1, listOf(s[0].toString())) 9 | 10 | private fun partition(s: String, index: Int, partitions: List): List> { 11 | if (index >= s.length) return if (partitions.all { isPalindrome(it) }) listOf(partitions) else listOf() 12 | val result = mutableListOf>() 13 | val newLast = partitions.last() + s[index] 14 | result.addAll(partition(s, index + 1, partitions.dropLast(1).plus(newLast))) 15 | if (isPalindrome(partitions.last())) 16 | result.addAll(partition(s, index + 1, partitions.plus(s[index].toString()))) 17 | return result 18 | } 19 | 20 | private fun isPalindrome(s: String): Boolean { 21 | if (s.length == 1) return true 22 | for (i in 0 until s.length / 2) if (s[i] != s[s.length - 1 - i]) return false 23 | return true 24 | } 25 | } 26 | 27 | fun main() { 28 | val pp = PalindromePartitions() 29 | println(pp.partition("abba"))//[[a, b, b, a], [a, bb, a], [abba]] 30 | println(pp.partition("aab"))//[[a, a, b], [aa, b]] 31 | println(pp.partition("a"))//[[a]] 32 | println(pp.partition("aa"))//[[a, a], [aa]] 33 | println(pp.partition("abcd"))//[[a, b, c, d]] 34 | println(pp.partition("abbab"))//[[a, b, b, a, b], [a, b, bab], [abba, b], [a, bb, a, b]] 35 | // Huge input 36 | println(pp.partition("abbaabbaabbaabba").size)//553 37 | val start = System.currentTimeMillis() 38 | println(pp.partition("aaaaaaaaaaaaaaaa").size)//32768 39 | println("${System.currentTimeMillis() - start}ms") 40 | } -------------------------------------------------------------------------------- /ProblemSolving/Medium/Trees/TopView.py: -------------------------------------------------------------------------------- 1 | """ 2 | Top view of a binary tree is the set of nodes visible when the tree is viewed from the top. 3 | Given a binary tree, print the top view of it. The output nodes can be printed in any order. 4 | 5 | 6 | 1 7 | / \ 8 | 2 3 9 | / \ / \ 10 | 4 5 6 7 11 | \ 12 | 8 13 | 14 | Output : [4, 2, 6, 1, 3, 7] 15 | """ 16 | 17 | import sys 18 | from collections import deque 19 | from typing import List 20 | 21 | from ProblemSolving.Hard.Trees.Model.TreeNodeModel import TreeNode, create_mock_binary_tree 22 | 23 | 24 | def top_view(root: TreeNode) -> List[int]: 25 | bfs_queue, top_view_nodes = deque(), deque() 26 | max_vertical_level, min_vertical_level = (-sys.maxsize, sys.maxsize) 27 | 28 | bfs_queue.append(root) 29 | while len(bfs_queue) > 0: 30 | node = bfs_queue.pop() 31 | if node.vertical_level > max_vertical_level: 32 | top_view_nodes.append(node.val) 33 | max_vertical_level = node.vertical_level 34 | elif node.vertical_level < min_vertical_level: 35 | top_view_nodes.appendleft(node.val) 36 | min_vertical_level = node.vertical_level 37 | if node.left is not None: 38 | node.left.vertical_level = node.vertical_level - 1 39 | bfs_queue.append(node.left) 40 | if node.right is not None: 41 | node.right.vertical_level = node.vertical_level + 1 42 | bfs_queue.append(node.right) 43 | 44 | return list(top_view_nodes) 45 | 46 | 47 | if __name__ == '__main__': 48 | root_node = create_mock_binary_tree() 49 | print(top_view(root_node)) 50 | print(top_view(root_node.left)) 51 | print(top_view(root_node.right)) 52 | print(top_view(root_node.right.left)) 53 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/arrays/prefixsum/ContinuousSubarraySumModK.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.arrays.prefixsum; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * https://leetcode.com/problems/continuous-subarray-sum/ 8 | */ 9 | public class ContinuousSubarraySumModK { 10 | public boolean checkSubarraySum(int[] nums, int k) { 11 | if (nums.length <= 1) return false; 12 | int movingSum = 0; 13 | Map prevSums = new HashMap<>(); 14 | for (int i = 0; i < nums.length; i++) { 15 | int newSum = (movingSum + nums[i]) % k; 16 | if (i >= 1 && newSum == 0) return true; // A[0] to A[i] 17 | if (prevSums.containsKey(newSum)) { // A[j] to A[i] 18 | int prevIndex = prevSums.get(newSum); 19 | if (i - prevIndex >= 2) return true; 20 | } else { 21 | prevSums.put(newSum, i); 22 | } 23 | movingSum = newSum; 24 | } 25 | return false; 26 | } 27 | 28 | public static void main(String[] args) { 29 | ContinuousSubarraySumModK cssm = new ContinuousSubarraySumModK(); 30 | System.out.println(cssm.checkSubarraySum(new int[]{23, 2, 4, 6, 7}, 6)); //true 31 | System.out.println(cssm.checkSubarraySum(new int[]{23, 2, 6, 4, 7}, 6)); //true 32 | System.out.println(cssm.checkSubarraySum(new int[]{23, 2, 6, 4, 7}, 13)); //false 33 | System.out.println(cssm.checkSubarraySum(new int[]{23, 2, 4, 6, 6}, 7)); //true 34 | System.out.println(cssm.checkSubarraySum(new int[]{0}, 1)); //false 35 | System.out.println(cssm.checkSubarraySum(new int[]{0, 7}, 5)); //false 36 | System.out.println(cssm.checkSubarraySum(new int[]{0, 7, 0}, 5)); //false 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/tree/FindDuplicateSubtrees.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.tree 2 | 3 | import leetcode.medium.tree.FindDuplicateSubtrees.* 4 | import java.math.BigInteger 5 | import java.security.MessageDigest 6 | 7 | /** 8 | * 652. Find Duplicate Subtrees 9 | * https://leetcode.com/problems/find-duplicate-subtrees/ 10 | */ 11 | class FindDuplicateSubtrees { 12 | data class TreeNode(var `val`: Int) { 13 | var left: TreeNode? = null 14 | var right: TreeNode? = null 15 | } 16 | 17 | private fun md5Hash(s: String): String { 18 | val md = MessageDigest.getInstance("MD5") 19 | return BigInteger(1, md.digest(s.toByteArray())).toString(16).padStart(32, '0') 20 | } 21 | 22 | private fun merkleHash(root: TreeNode?, subtreeHashes: MutableMap>): String { 23 | if (root == null) return "$" 24 | val subtreeHash = md5Hash(merkleHash(root.left, subtreeHashes) + 25 | merkleHash(root.right, subtreeHashes) + 26 | md5Hash(root.`val`.toString())) 27 | subtreeHashes.getOrPut(subtreeHash) { mutableListOf() }.add(root) 28 | return subtreeHash 29 | } 30 | 31 | fun findDuplicateSubtrees(root: TreeNode?): List { 32 | val subtreeHashes = mutableMapOf>() 33 | merkleHash(root, subtreeHashes) 34 | return subtreeHashes.filter { it.value.size > 1 }.values.map { it.first() } 35 | } 36 | } 37 | 38 | fun main() { 39 | val p = FindDuplicateSubtrees() 40 | val root = TreeNode(1) 41 | root.left = TreeNode(2) 42 | root.right = TreeNode(3) 43 | root.left!!.left = TreeNode(4) 44 | root.right!!.left = TreeNode(2) 45 | root.right!!.left!!.left = TreeNode(4) 46 | root.right!!.right = TreeNode(4) 47 | println(p.findDuplicateSubtrees(root))// [2, 4], [4] 48 | } 49 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/graph/TimeToInformAll.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.graph; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * 10 | * ... 11 | * 12 | **/ 13 | public class TimeToInformAll { 14 | 15 | public int dfs(Map> adjList, int manager, int[] informTime, int timeTillNow) { 16 | int max = timeTillNow; 17 | List reportees = adjList.containsKey(manager) ? adjList.get(manager) : new ArrayList(); 18 | for (Integer reportee : reportees) { 19 | max = Math.max(max, dfs(adjList, reportee, informTime, timeTillNow + informTime[manager])); 20 | } 21 | return max; 22 | } 23 | 24 | public int numOfMinutes(int n, int headId, int[] manager, int[] informTime) { 25 | Map> adjList = new HashMap<>(); 26 | for (int i = 0; i < n; i++) { 27 | int mgr = manager[i]; 28 | if (!adjList.containsKey(mgr)) { 29 | adjList.put(mgr, new ArrayList()); 30 | } 31 | adjList.get(mgr).add(i); 32 | } 33 | return dfs(adjList, headId, informTime, 0); 34 | } 35 | 36 | public static void main(String[] args) { 37 | TimeToInformAll toInformAll = new TimeToInformAll(); 38 | System.out.println(toInformAll.numOfMinutes(6, 2, new int[]{2, 2, -1, 2, 2, 2}, new int[]{0, 0, 1, 0, 0, 0})); 39 | System.out.println(toInformAll.numOfMinutes(1, 0, new int[]{-1}, new int[]{0})); 40 | 41 | System.out.println(toInformAll.numOfMinutes(4, 0, new int[]{-1, 0, 1, 2}, new int[]{1, 1, 0, 0})); 42 | System.out.println(toInformAll.numOfMinutes(4, 0, new int[]{-1, 0, 1, 1}, new int[]{1, 100, 0, 0})); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/matrix/ImageOverlap.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.matrix; 2 | 3 | import java.awt.Point; 4 | import java.util.*; 5 | 6 | /** 7 | * https://leetcode.com/problems/image-overlap/ 8 | */ 9 | public class ImageOverlap { 10 | 11 | public List ones(int[][] img) { 12 | List oneSet = new ArrayList<>(); 13 | for (int i = 0; i < img.length; i++) { 14 | for (int j = 0; j < img[0].length; j++) { 15 | if (img[i][j] == 1) 16 | oneSet.add(new Point(i, j)); 17 | } 18 | } 19 | return oneSet; 20 | } 21 | 22 | public int largestOverlap(int[][] source, int[][] target) { 23 | List sourceOnes = ones(source); 24 | List targetOnes = ones(target); 25 | HashMap vectorCounts = new HashMap<>(); 26 | for (Point a : sourceOnes) { 27 | for (Point b : targetOnes) { 28 | Point distanceVector = new Point(a.x - b.x, a.y - b.y); // gives the direction and magnitude 29 | if (!vectorCounts.containsKey(distanceVector)) { 30 | vectorCounts.put(distanceVector, 0); 31 | } 32 | vectorCounts.compute(distanceVector, (k, v) -> v + 1); 33 | } 34 | } 35 | // the distance vector with the highest count is the answer. We should translate in its direction by its magnitude 36 | return vectorCounts.values().stream().reduce(0, Integer::max); 37 | } 38 | 39 | 40 | public static void main(String[] args) { 41 | ImageOverlap io = new ImageOverlap(); 42 | int[][] A = new int[][]{{1, 1, 0}, {0, 1, 0}, {0, 1, 0}}; 43 | int[][] B = new int[][]{{0, 0, 0}, {0, 1, 1}, {0, 0, 1}}; 44 | System.out.println(io.largestOverlap(A, B)); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/hard/dp/ConcatenatedWords.kt: -------------------------------------------------------------------------------- 1 | package leetcode.hard.dp 2 | 3 | /** 4 | * 472. Concatenated Words 5 | * https://leetcode.com/problems/concatenated-words/ 6 | */ 7 | class ConcatenatedWords { 8 | fun findAllConcatenatedWordsInADict(words: Array): List { 9 | val set = HashSet(words.toList()) 10 | val answer = mutableListOf() 11 | for (word in words) { 12 | val dp = BooleanArray(word.length + 1) 13 | dp[0] = true 14 | for (i in 1..word.length) { 15 | val jStart = if (i == word.length) 1 else 0 16 | for (j in jStart until i) { 17 | if (dp[j] && set.contains(word.substring(j, i))) { 18 | dp[i] = true 19 | } 20 | } 21 | } 22 | if (dp[word.length]) answer.add(word) 23 | } 24 | return answer 25 | } 26 | } 27 | 28 | fun main() { 29 | val cw = ConcatenatedWords() 30 | println( 31 | cw.findAllConcatenatedWordsInADict( 32 | arrayOf( 33 | "cat", 34 | "cats", 35 | "catsdogcats", 36 | "dog", 37 | "dogcatsdog", 38 | "hippopotamuses", 39 | "rat", 40 | "ratcatdogcat" 41 | ) 42 | ) 43 | )//["catsdogcats", "dogcatsdog", "ratcatdogcat"] 44 | println( 45 | cw.findAllConcatenatedWordsInADict( 46 | arrayOf( 47 | "cat", 48 | "cats", 49 | "catsdogcats", 50 | "dog", 51 | "dogcatsdog", 52 | "hippopotamuses", 53 | "rat", 54 | "ratcatdogcat", 55 | "dogcatcat" 56 | ) 57 | ) 58 | )//["catsdogcats", "dogcatsdog", "ratcatdogcat", "dogcatcat"] 59 | } -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/trees/MaxProductSplitBinaryTree.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.trees; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | /** 7 | * https://leetcode.com/problems/maximum-product-of-splitted-binary-tree/ 8 | */ 9 | public class MaxProductSplitBinaryTree { 10 | private static class TreeNode { 11 | int val; 12 | TreeNode left, right; 13 | 14 | TreeNode(int val) { 15 | this.val = val; 16 | } 17 | } 18 | 19 | private static final long MOD = 1000000007; 20 | 21 | private long maxProduct(TreeNode root, List subtreeSums) { 22 | if (root == null) return 0L; 23 | long sum = root.val + maxProduct(root.left, subtreeSums) + maxProduct(root.right, subtreeSums); 24 | subtreeSums.add(sum); 25 | return sum; 26 | } 27 | 28 | public int maxProduct(TreeNode root) { 29 | var subtreeSums = new LinkedList(); 30 | long totalSum = maxProduct(root, subtreeSums); 31 | long maxProduct = Long.MIN_VALUE; 32 | for (Long subtreeSum : subtreeSums) { 33 | long otherTreeSum = totalSum - subtreeSum; 34 | long product = otherTreeSum * subtreeSum; 35 | maxProduct = Math.max(product, maxProduct); 36 | } 37 | return (int) (maxProduct % MOD); 38 | } 39 | 40 | public static void main(String[] args) { 41 | MaxProductSplitBinaryTree mp = new MaxProductSplitBinaryTree(); 42 | TreeNode root = new TreeNode(1); 43 | root.left = new TreeNode(2); 44 | root.right = new TreeNode(3); 45 | root.left.left = new TreeNode(4); 46 | root.left.right = new TreeNode(5); 47 | root.right.left = new TreeNode(6); 48 | root.right.right = new TreeNode(7); 49 | System.out.println(mp.maxProduct(root)); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/backtracking/WordSearch.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.backtracking; 2 | 3 | /** 4 | * https://leetcode.com/problems/word-search/description/ 5 | */ 6 | public class WordSearch { 7 | private boolean exist(char[][] board, int i, int j, int depth, String word) { 8 | if (i >= 0 && j >= 0 && i < board.length && j < board[0].length) { 9 | if (board[i][j] != word.charAt(depth)) return false; 10 | if (depth == word.length() - 1) return true; 11 | char value = board[i][j]; 12 | board[i][j] = Character.MIN_VALUE; 13 | boolean exist = exist(board, i + 1, j, depth + 1, word) 14 | || exist(board, i - 1, j, depth + 1, word) 15 | || exist(board, i, j + 1, depth + 1, word) 16 | || exist(board, i, j - 1, depth + 1, word); 17 | board[i][j] = value; 18 | return exist; 19 | } 20 | return false; 21 | } 22 | 23 | public boolean exist(char[][] board, String word) { 24 | for (int i = 0; i < board.length; i++) { 25 | for (int j = 0; j < board[0].length; j++) { 26 | if (exist(board, i, j, 0, word)) return true; 27 | } 28 | } 29 | return false; 30 | } 31 | 32 | public static void main(String[] args) { 33 | WordSearch ws = new WordSearch(); 34 | System.out.println(ws.exist(new char[][]{{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}}, "ABCB")); 35 | System.out.println(ws.exist(new char[][]{{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}}, "ABCE")); 36 | System.out.println(ws.exist(new char[][]{{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}}, "SEE")); 37 | System.out.println(ws.exist(new char[][]{{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}}, "EED")); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/greedy/MinTimeColorfulRope.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.greedy; 2 | 3 | import java.awt.*; 4 | 5 | /** 6 | * https://leetcode.com/problems/minimum-time-to-make-rope-colorful/ 8 | */ 9 | public class MinTimeColorfulRope { 10 | 11 | public Point findSameColorInterval(int burstStart, String colors) { 12 | int burstEnd = burstStart; 13 | while (burstEnd < colors.length() - 1 && colors.charAt(burstEnd) == colors.charAt(burstEnd + 1)) { 14 | burstEnd++; 15 | } 16 | return new Point(burstStart, burstEnd); 17 | } 18 | 19 | public int minTimeToRemoveSameColor(Point interval, int[] neededTime) { 20 | int burstTimeMax = 0, burstTotalTime = 0; 21 | for (int i = interval.x; i <= interval.y; i++) { 22 | burstTotalTime += neededTime[i]; 23 | burstTimeMax = Math.max(burstTimeMax, neededTime[i]); 24 | } 25 | return burstTotalTime - burstTimeMax; // remove all balloon except the max 26 | } 27 | 28 | public int minCost(String colors, int[] neededTime) { 29 | int totalTime = 0; 30 | for (int start = 0; start < colors.length(); ) { 31 | Point interval = findSameColorInterval(start, colors); 32 | totalTime += minTimeToRemoveSameColor(interval, neededTime); 33 | start = interval.y + 1; 34 | } 35 | return totalTime; 36 | } 37 | 38 | public static void main(String[] args) { 39 | MinTimeColorfulRope minRope = new MinTimeColorfulRope(); 40 | System.out.println(minRope.minCost("abaac", new int[]{1, 2, 3, 4, 5})); //3 41 | System.out.println(minRope.minCost("abc", new int[]{1, 2, 3})); //0 42 | System.out.println(minRope.minCost("aabaa", new int[]{1, 2, 3, 4, 1})); //2 43 | System.out.println(minRope.minCost("aaabbbccc", new int[]{1, 2, 3, 1, 2, 3, 1, 2, 3})); //9 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/greedy/HandOfStraights.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.greedy; 2 | 3 | import java.util.Map; 4 | import java.util.TreeMap; 5 | 6 | /** 7 | * https://leetcode.com/problems/hand-of-straights 8 | *

9 | * https://leetcode.com/problems/divide-array-in-sets-of-k-consecutive-numbers/ 10 | */ 11 | public class HandOfStraights { 12 | 13 | public boolean isNStraightHand(int[] hands, int groupSize) { 14 | Map map = new TreeMap<>(); 15 | for (Integer hand : hands) { 16 | map.compute(hand, (k, v) -> v == null ? 1 : v + 1); 17 | } 18 | for (Integer currentHand : map.keySet()) { 19 | Integer numCards = map.get(currentHand); 20 | if (numCards == 0) continue; 21 | for (int i = 1; i < groupSize; i++) { 22 | Integer nextHand = currentHand + i; 23 | if (!map.containsKey(nextHand)) return false; 24 | Integer numNextHandCards = map.get(nextHand); 25 | if (numNextHandCards < numCards) return false; 26 | map.put(nextHand, numNextHandCards - numCards); 27 | } 28 | map.put(currentHand, 0); 29 | } 30 | return map.values().stream().allMatch(v -> v == 0); 31 | } 32 | 33 | public static void main(String[] args) { 34 | HandOfStraights hos = new HandOfStraights(); 35 | System.out.println(hos.isNStraightHand(new int[]{1, 2, 3, 6, 2, 3, 4, 7, 8}, 3)); 36 | System.out.println(hos.isNStraightHand(new int[]{1, 2, 3, 4, 5}, 4)); 37 | System.out.println(hos.isNStraightHand(new int[]{1, 2, 3, 3, 4, 4, 5, 6}, 4)); 38 | System.out.println(hos.isNStraightHand(new int[]{3, 2, 1, 2, 3, 4, 3, 4, 5, 9, 10, 11}, 3)); 39 | System.out.println(hos.isNStraightHand(new int[]{1, 2, 3, 4}, 3)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/heap/TaskScheduler.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.heap; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * 621. Task Scheduler 7 | */ 8 | public class TaskScheduler { 9 | 10 | public int leastInterval(char[] tasks, int n) { 11 | Map map = new HashMap<>(); 12 | for (char task : tasks) map.compute(task, (k, v) -> v == null ? 1 : v + 1); 13 | Queue maxHeap = new PriorityQueue<>((a, b) -> b - a); 14 | int tick = 0; 15 | maxHeap.addAll(map.values()); 16 | while (true) { 17 | int cpuCycle = n + 1; 18 | List coolDown = new ArrayList<>(); 19 | while (!maxHeap.isEmpty() && cpuCycle > 0) { 20 | int task = maxHeap.poll(); 21 | task--; 22 | if (task > 0) coolDown.add(task); 23 | tick++; 24 | cpuCycle--; 25 | } 26 | maxHeap.addAll(coolDown); 27 | if (maxHeap.isEmpty()) break; 28 | tick += cpuCycle;//idle time 29 | } 30 | return tick; 31 | } 32 | 33 | public static void main(String[] args) { 34 | var ts = new TaskScheduler(); 35 | System.out.println(ts.leastInterval(new char[]{'A', 'A', 'A', 'B', 'B', 'B'}, 2));//8 36 | System.out.println(ts.leastInterval(new char[]{'A', 'A', 'A', 'B', 'B', 'B'}, 0));//6 37 | System.out.println(ts.leastInterval(new char[]{'A', 'A', 'A', 'A', 'A', 'A', 'B', 'C', 'D', 'E', 'F', 'G'}, 2));//22 38 | System.out.println(ts.leastInterval(new char[]{'A', 'B', 'C', 'D', 'E', 'A', 'B', 'C', 'D', 'E'}, 4));//10 39 | System.out.println(ts.leastInterval(new char[]{'A', 'B', 'A', 'B', 'A', 'B'}, 2));//8 40 | System.out.println(ts.leastInterval(new char[]{'A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C'}, 2));//9 41 | System.out.println(ts.leastInterval(new char[]{'A', 'A', 'A', 'B', 'B', 'B'}, 50));//104 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/unionfind/MostStonesRemoved.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.unionfind; 2 | 3 | 4 | import java.util.*; 5 | 6 | /** 7 | * https://leetcode.com/problems/most-stones-removed-with-same-row-or-column/ 8 | */ 9 | public class MostStonesRemoved { 10 | 11 | private void removeStonesByUnion(UnionFind uf, Map> connectedStones) { 12 | for (List stones : connectedStones.values()) { 13 | for (int i = 0; i < stones.size() - 1; i++) { 14 | uf.union(stones.get(i), stones.get(i + 1)); 15 | } 16 | } 17 | } 18 | 19 | public int removeStones(int[][] stones) { 20 | UnionFind uf = new UnionFind(stones.length); 21 | Map> rowStones = new HashMap<>(); 22 | Map> colStones = new HashMap<>(); 23 | for (int i = 0; i < stones.length; i++) { 24 | int row = stones[i][0]; 25 | int col = stones[i][1]; 26 | rowStones.putIfAbsent(row, new ArrayList<>()); 27 | colStones.putIfAbsent(col, new ArrayList<>()); 28 | rowStones.get(row).add(i); 29 | colStones.get(col).add(i); 30 | } 31 | removeStonesByUnion(uf, rowStones); 32 | removeStonesByUnion(uf, colStones); 33 | return uf.getGroups(false).stream().mapToInt(Set::size).sum() - uf.getNumGroups(); 34 | } 35 | 36 | public static void main(String[] args) { 37 | MostStonesRemoved msr = new MostStonesRemoved(); 38 | System.out.println(msr.removeStones(new int[][]{{0, 0}, {0, 1}, {1, 0}, {1, 2}, {2, 1}, {2, 2}}));//5 39 | System.out.println(msr.removeStones(new int[][]{{0, 0}, {0, 2}, {1, 1}, {2, 0}, {2, 2}}));//3 40 | System.out.println(msr.removeStones(new int[][]{{0, 0}}));//0 41 | System.out.println(msr.removeStones(new int[][]{{0, 0}, {0, 1}, {1, 0}, {1, 1}}));//3 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/dp/BuySellStocksCoolDown.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.dp; 2 | 3 | import java.awt.*; 4 | import java.util.*; 5 | 6 | /** 7 | * 309. Best Time to Buy and Sell Stock with Cooldown 8 | * https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/ 9 | */ 10 | public class BuySellStocksCoolDown { 11 | 12 | private int maxProfit(int currentDay, int prevBuyDay, int[] prices, Map cache) { 13 | if (currentDay >= prices.length) return 0; 14 | var cacheKey = new Point(currentDay, prevBuyDay); 15 | if (cache.containsKey(cacheKey)) return cache.get(cacheKey); 16 | var maxProfit = 0; 17 | if (prevBuyDay == -1) { 18 | var buyNow = maxProfit(currentDay + 1, currentDay, prices, cache); 19 | var dontBuyNow = maxProfit(currentDay + 1, -1, prices, cache); 20 | maxProfit = Math.max(buyNow, dontBuyNow); 21 | } else if (prices[prevBuyDay] < prices[currentDay]) { 22 | var sellNow = (prices[currentDay] - prices[prevBuyDay]) + maxProfit(currentDay + 2, -1, prices, cache); 23 | var dontSellNow = maxProfit(currentDay + 1, prevBuyDay, prices, cache); 24 | maxProfit = Math.max(sellNow, dontSellNow); 25 | } 26 | cache.put(cacheKey, maxProfit); 27 | return maxProfit; 28 | } 29 | 30 | public int maxProfit(int[] prices) { 31 | return maxProfit(0, -1, prices, new HashMap<>()); 32 | } 33 | 34 | public static void main(String[] args) { 35 | var bssc = new BuySellStocksCoolDown(); 36 | System.out.println(bssc.maxProfit(new int[]{1, 2, 3, 0, 2}));//3 37 | System.out.println(bssc.maxProfit(new int[]{1}));//0 38 | System.out.println(bssc.maxProfit(new int[]{1, 2}));//1 39 | System.out.println(bssc.maxProfit(new int[]{2, 1}));//0 40 | System.out.println(bssc.maxProfit(new int[]{2, 1, 2, 0, 1}));//1 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/design/PeekingIterator.java: -------------------------------------------------------------------------------- 1 | package leetcode.design; 2 | 3 | 4 | import java.util.*; 5 | 6 | /** 7 | * 284. Peeking Iterator 8 | */ 9 | public class PeekingIterator implements Iterator { 10 | final Iterator iterator; 11 | final LinkedList queue; 12 | 13 | public PeekingIterator(Iterator iterator) { 14 | this.iterator = iterator; 15 | this.queue = new LinkedList<>(); 16 | } 17 | 18 | public Integer peek() { 19 | Integer element = next(); 20 | queue.offer(element); 21 | return element; 22 | } 23 | 24 | @Override 25 | public Integer next() { 26 | if (queue.isEmpty()) { 27 | return iterator.next(); 28 | } 29 | return queue.poll(); 30 | } 31 | 32 | @Override 33 | public boolean hasNext() { 34 | return iterator.hasNext() || !queue.isEmpty(); 35 | } 36 | 37 | public static void main(String[] args) { 38 | PeekingIterator peekingIterator = new PeekingIterator(Arrays.asList(1, 2, 3).listIterator()); // [1,2,3] 39 | System.out.println(peekingIterator.next()); // return 1 40 | System.out.println(peekingIterator.peek()); // return 2 41 | System.out.println(peekingIterator.next()); // return 2 42 | System.out.println(peekingIterator.next()); // return 3 43 | System.out.println(peekingIterator.hasNext()); // return False 44 | 45 | PeekingIterator peekingIterator1 = new PeekingIterator(Arrays.asList(1, 2, 3, 9, 10, 99).listIterator());// [1,2,3,9,10,99] 46 | System.out.println(peekingIterator1.peek()); //return 1 47 | System.out.println(peekingIterator1.peek()); //return 1 48 | System.out.println(peekingIterator1.peek()); //return 1 49 | System.out.println(peekingIterator1.next()); //return 1 50 | System.out.println(peekingIterator1.peek()); //return 2 51 | System.out.println(peekingIterator1.next()); //return 2 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/hard/greedy/EarliestPossibleDayOfBloom.java: -------------------------------------------------------------------------------- 1 | package leetcode.hard.greedy; 2 | 3 | import java.util.*; 4 | 5 | public class EarliestPossibleDayOfBloom { 6 | private static class Plant implements Comparable { 7 | int plantTime, growTime; 8 | 9 | Plant(int plantTime, int growTime) { 10 | this.plantTime = plantTime; 11 | this.growTime = growTime; 12 | } 13 | 14 | @Override 15 | public int compareTo(Plant o) { 16 | if (o.growTime == this.growTime) return (o.plantTime - this.plantTime); 17 | else return (o.growTime - this.growTime); 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "Plant{" + " plantTime=" + plantTime + ", growTime=" + growTime + '}'; 23 | } 24 | } 25 | 26 | public int earliestFullBloom(int[] plantTime, int[] growTime) { 27 | List plants = new ArrayList<>(); 28 | for (int i = 0; i < plantTime.length; i++) { 29 | plants.add(new Plant(plantTime[i], growTime[i])); 30 | } 31 | Collections.sort(plants); // highest grow time first 32 | int movingDays = 0, lastBloomDay = Integer.MIN_VALUE; 33 | for (Plant plant : plants) { 34 | movingDays += plant.plantTime; 35 | lastBloomDay = Math.max(lastBloomDay, movingDays + plant.growTime); 36 | } 37 | return lastBloomDay; 38 | } 39 | 40 | public static void main(String[] args) { 41 | EarliestPossibleDayOfBloom epdb = new EarliestPossibleDayOfBloom(); 42 | System.out.println(epdb.earliestFullBloom(new int[]{1, 4, 3}, new int[]{2, 3, 1})); 43 | System.out.println(epdb.earliestFullBloom(new int[]{1, 2, 3, 2}, new int[]{2, 1, 2, 1})); 44 | System.out.println(epdb.earliestFullBloom(new int[]{1}, new int[]{1})); 45 | System.out.println(epdb.earliestFullBloom(new int[]{7, 5, 1, 2}, new int[]{5, 1, 6, 4})); 46 | System.out.println(epdb.earliestFullBloom(new int[]{7, 5, 1, 2}, new int[]{5, 1, 6, 5})); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/matrix/WhereBallFall.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.matrix; 2 | 3 | import java.awt.Point; 4 | import java.util.Arrays; 5 | 6 | /** 7 | * https://leetcode.com/problems/where-will-the-ball-fall/ 8 | */ 9 | public class WhereBallFall { 10 | 11 | public boolean isBlocked(Point position, int[][] grid) { 12 | if (grid[position.x][position.y] == 1 && (position.y >= grid[0].length - 1 || grid[position.x][position.y + 1] == -1)) 13 | return true; 14 | if (grid[position.x][position.y] == -1 && (position.y < 1 || grid[position.x][position.y - 1] == 1)) 15 | return true; 16 | return false; 17 | } 18 | 19 | public Point nextMove(Point curr, int[][] grid) { 20 | if (isBlocked(curr, grid)) return null; 21 | if (grid[curr.x][curr.y] == 1) return new Point(curr.x + 1, curr.y + 1); 22 | return new Point(curr.x + 1, curr.y - 1); 23 | } 24 | 25 | public int[] findBall(int[][] grid) { 26 | int[] ans = new int[grid[0].length]; 27 | for (int i = 0; i < grid[0].length; i++) { 28 | Point position = new Point(0, i); 29 | while (position != null) { 30 | if (position.x >= grid.length || position.x < 0) break; 31 | position = nextMove(position, grid); 32 | } 33 | ans[i] = (position == null) ? -1 : position.y; 34 | } 35 | return ans; 36 | } 37 | 38 | public static void main(String[] args) { 39 | WhereBallFall wbf = new WhereBallFall(); 40 | System.out.println(Arrays.toString(wbf.findBall(new int[][]{{1, 1, 1, -1, -1}, {1, 1, 1, -1, -1}, {-1, -1, -1, 1, 1}, {1, 1, 1, 1, -1}, {-1, -1, -1, -1, -1}}))); //[1, -1, -1, -1, -1] 41 | System.out.println(Arrays.toString(wbf.findBall(new int[][]{{-1}}))); //[-1] 42 | System.out.println(Arrays.toString(wbf.findBall(new int[][]{{1, 1, 1, 1, 1, 1}, {-1, -1, -1, -1, -1, -1}, {1, 1, 1, 1, 1, 1}, {-1, -1, -1, -1, -1, -1}}))); //[0, 1, 2, 3, 4, -1] 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/trees/MaxDiffNodeAncestor.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.trees; 2 | 3 | /** 4 | * https://leetcode.com/problems/maximum-difference-between-node-and-ancestor/ 5 | */ 6 | public class MaxDiffNodeAncestor { 7 | 8 | private static class TreeNode { 9 | int val; 10 | TreeNode left; 11 | TreeNode right; 12 | 13 | TreeNode(int val) { 14 | this.val = val; 15 | } 16 | } 17 | 18 | public int maxAncestorDiff(TreeNode root, int low, int high) { 19 | if (root == null) return Integer.MIN_VALUE; 20 | var newLow = Math.min(low, root.val); 21 | var newHigh = Math.max(high, root.val); 22 | var subtreeMax = Math.max(maxAncestorDiff(root.left, newLow, newHigh), maxAncestorDiff(root.right, newLow, newHigh)); 23 | var rootMaxDiff = Math.max(Math.abs(root.val - low), Math.abs(root.val - high)); 24 | return Math.max(rootMaxDiff, subtreeMax); 25 | } 26 | 27 | public int maxAncestorDiff(TreeNode root) { 28 | return Math.max(maxAncestorDiff(root.left, root.val, root.val), maxAncestorDiff(root.right, root.val, root.val)); 29 | } 30 | 31 | public static void main(String[] args) { 32 | var mdna = new MaxDiffNodeAncestor(); 33 | var tree = new TreeNode(8); 34 | tree.left = new TreeNode(3); 35 | tree.right = new TreeNode(10); 36 | tree.left.left = new TreeNode(1); 37 | tree.left.right = new TreeNode(6); 38 | tree.left.right.left = new TreeNode(4); 39 | tree.left.right.right = new TreeNode(7); 40 | tree.right.right = new TreeNode(14); 41 | tree.right.right.left = new TreeNode(13); 42 | System.out.println(mdna.maxAncestorDiff(tree));//7 43 | 44 | tree = new TreeNode(1); 45 | tree.right = new TreeNode(2); 46 | tree.right.right = new TreeNode(0); 47 | tree.right.right.left = new TreeNode(3); 48 | System.out.println(mdna.maxAncestorDiff(tree));//3 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/stack/MinRemovesValidParentheses.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.stack; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * Minimum Remove to Make Valid Parentheses 7 | */ 8 | public class MinRemovesValidParentheses { 9 | 10 | private Set removeExcess(String s, char bracket) { 11 | var removed = new HashSet(); 12 | var excessBracket = 0; 13 | var stack = new Stack(); 14 | for (int i = 0; i < s.length(); i++) { 15 | if (Character.isLetter(s.charAt(i))) 16 | stack.push(s.charAt(i)); 17 | else if (s.charAt(i) == bracket) { 18 | excessBracket++; 19 | stack.push(s.charAt(i)); 20 | } else { 21 | if (excessBracket == 0) { 22 | removed.add(i); 23 | continue; 24 | } 25 | while (true) if (stack.pop() == bracket) break; 26 | excessBracket--; 27 | } 28 | } 29 | return removed; 30 | } 31 | 32 | public String minRemoveToMakeValid(String s) { 33 | var removedClosing = removeExcess(s, '('); 34 | var removedOpening = removeExcess((new StringBuilder(s)).reverse().toString(), ')'); 35 | var removed = new HashSet<>(removedClosing); 36 | for (var i : removedOpening) removed.add(s.length() - i - 1); 37 | var result = new StringBuilder(); 38 | for (int i = 0; i < s.length(); i++) if (!removed.contains(i)) result.append(s.charAt(i)); 39 | return result.toString(); 40 | } 41 | 42 | public static void main(String[] args) { 43 | var mr = new MinRemovesValidParentheses(); 44 | System.out.println(mr.minRemoveToMakeValid("))((")); 45 | System.out.println(mr.minRemoveToMakeValid("a)b(c)d")); 46 | System.out.println(mr.minRemoveToMakeValid("a)b(c)d(")); 47 | System.out.println(mr.minRemoveToMakeValid("lee(t(c)o)de)")); 48 | System.out.println(mr.minRemoveToMakeValid("))(())((")); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/arrays/CountGoodMeals.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.arrays; 2 | 3 | import java.util.Arrays; 4 | import java.util.Map; 5 | import java.util.stream.Collectors; 6 | 7 | /** 8 | * https://leetcode.com/problems/count-good-meals/ 9 | */ 10 | public class CountGoodMeals { 11 | 12 | private static int countGoodMeals(int[] deliciousness) { 13 | int mod = 1000000007; 14 | int[] powersOfTwo = new int[22]; 15 | Arrays.fill(powersOfTwo, 1); 16 | for (int i = 1; i < powersOfTwo.length; i++) { 17 | powersOfTwo[i] = powersOfTwo[i - 1] * 2; 18 | } 19 | 20 | 21 | Map frequency = Arrays.stream(deliciousness).boxed() 22 | .collect(Collectors.groupingBy(e -> e, Collectors.counting())); 23 | 24 | int result = 0; 25 | for (Integer key : frequency.keySet()) { 26 | for (int j : powersOfTwo) { 27 | if (j >= key) { 28 | int other = j - key; 29 | if (frequency.containsKey(other)) { 30 | if (key > other) { 31 | result += (frequency.get(key) * frequency.get(other)); 32 | } else if (key == other) { 33 | result += ((frequency.get(key) * (frequency.get(other) - 1)) / 2); 34 | } 35 | } 36 | result = result > mod ? result % mod : result; 37 | } 38 | } 39 | } 40 | return result; 41 | } 42 | 43 | public static void main(String[] args) { 44 | System.out.println(countGoodMeals(new int[]{1, 3, 5, 7, 9})); // 4 45 | System.out.println(countGoodMeals(new int[]{1, 1, 1, 3, 3, 3, 7})); // 15 46 | System.out.println(countGoodMeals(new int[]{149, 107, 1, 63, 0, 1, 6867, 1325, 5611, 2581, 39, 89, 46, 18, 12, 20, 22, 234})); // 12 47 | System.out.println(countGoodMeals(new int[]{64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64})); // 528 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/trees/EvenOddTree.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.trees; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * 1609. Even Odd Tree 7 | */ 8 | public class EvenOddTree { 9 | 10 | private static class TreeNode { 11 | int val; 12 | TreeNode left, right; 13 | 14 | TreeNode(int x) { 15 | val = x; 16 | } 17 | } 18 | 19 | 20 | public boolean isEvenOddTree(TreeNode root) { 21 | var bfsQ = new LinkedList(); 22 | var level = 0; 23 | var previous = Integer.MIN_VALUE; 24 | bfsQ.add(root); 25 | bfsQ.add(null); 26 | while (!bfsQ.isEmpty()) { 27 | var node = bfsQ.poll(); 28 | if (node == null) { 29 | if (bfsQ.isEmpty()) break; 30 | bfsQ.add(null); 31 | level++; 32 | previous = level % 2 == 0 ? Integer.MIN_VALUE : Integer.MAX_VALUE; 33 | continue; 34 | } 35 | if (level % 2 == 0) {//even level 36 | if (node.val % 2 == 0) return false;//even value 37 | if (node.val <= previous) return false;//not strictly increasing 38 | } else {//odd level 39 | if (node.val % 2 == 1) return false;//odd value 40 | if (node.val >= previous) return false;//not strictly decreasing 41 | } 42 | 43 | previous = node.val; 44 | if (node.left != null) bfsQ.add(node.left); 45 | if (node.right != null) bfsQ.add(node.right); 46 | } 47 | return true; 48 | } 49 | 50 | public static void main(String[] args) { 51 | var eot = new EvenOddTree(); 52 | var root = new TreeNode(2); 53 | root.left = new TreeNode(1); 54 | root.right = new TreeNode(3); 55 | System.out.println(eot.isEvenOddTree(root)); 56 | 57 | root = new TreeNode(5); 58 | root.left = new TreeNode(4); 59 | root.right = new TreeNode(2); 60 | root.left.left = new TreeNode(3); 61 | root.left.right = new TreeNode(7); 62 | System.out.println(eot.isEvenOddTree(root)); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/hard/backtracking/UniquePathsIII.java: -------------------------------------------------------------------------------- 1 | package leetcode.hard.backtracking; 2 | 3 | import java.awt.*; 4 | 5 | /** 6 | * 980. Unique Paths III 7 | * https://leetcode.com/problems/unique-paths-iii/ 8 | */ 9 | public class UniquePathsIII { 10 | 11 | private int uniquePaths(int[][] grid, int i, int j, int steps, int numEmpty, String path) { 12 | if (i >= 0 && j >= 0 && i < grid.length && j < grid[0].length) { 13 | if (grid[i][j] == 2 && steps == numEmpty) { 14 | System.err.println(path + "(" + i + "," + j + ")"); 15 | return 1; 16 | } 17 | if (grid[i][j] == -1) return 0; 18 | steps = grid[i][j] == 0 ? steps + 1 : steps; 19 | int value = grid[i][j]; 20 | grid[i][j] = -1; 21 | path = path + "(" + i + "," + j + ")->"; 22 | int sum = uniquePaths(grid, i + 1, j, steps, numEmpty, path) 23 | + uniquePaths(grid, i - 1, j, steps, numEmpty, path) 24 | + uniquePaths(grid, i, j + 1, steps, numEmpty, path) 25 | + uniquePaths(grid, i, j - 1, steps, numEmpty, path); 26 | grid[i][j] = value; 27 | return sum; 28 | } 29 | return 0; 30 | } 31 | 32 | public int uniquePathsIII(int[][] grid) { 33 | int numEmpty = 0; 34 | Point start = new Point(0, 0); 35 | for (int i = 0; i < grid.length; i++) { 36 | for (int j = 0; j < grid[0].length; j++) { 37 | if (grid[i][j] == 1) start = new Point(i, j); 38 | if (grid[i][j] == 0) numEmpty++; 39 | } 40 | } 41 | return uniquePaths(grid, start.x, start.y, 0, numEmpty, ""); 42 | } 43 | 44 | public static void main(String[] args) { 45 | UniquePathsIII upiii = new UniquePathsIII(); 46 | System.out.println(upiii.uniquePathsIII(new int[][]{{1, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 2, -1}}));//2 47 | System.out.println(upiii.uniquePathsIII(new int[][]{{1, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 2}}));//4 48 | System.out.println(upiii.uniquePathsIII(new int[][]{{0, 1}, {2, 0}}));//0 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/heap/TopKFrequent.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.heap; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * https://leetcode.com/problems/top-k-frequent-words/ 7 | */ 8 | public class TopKFrequent { 9 | 10 | public static int compareEntries(Map.Entry a, Map.Entry b) { 11 | if (Objects.equals(a.getValue(), b.getValue())) return b.getKey().compareTo(a.getKey()); 12 | return a.getValue().compareTo(b.getValue()); 13 | } 14 | 15 | public List topKFrequent(String[] words, int k) { 16 | PriorityQueue> priorityQueue = new PriorityQueue<>(TopKFrequent::compareEntries); 17 | Map freq = new HashMap<>(); 18 | for (String word : words) { 19 | if (!freq.containsKey(word)) freq.put(word, 0); 20 | freq.put(word, freq.get(word) + 1); 21 | } 22 | int i = 0; 23 | for (Map.Entry entry : freq.entrySet()) { 24 | if (i < k) { 25 | priorityQueue.add(entry); 26 | } else { 27 | if (compareEntries(priorityQueue.peek(), entry) < 0) { 28 | priorityQueue.poll(); 29 | priorityQueue.add(entry); 30 | } 31 | } 32 | i++; 33 | } 34 | List topK = new ArrayList<>(); 35 | while (!priorityQueue.isEmpty()) { 36 | topK.add(priorityQueue.poll().getKey()); 37 | } 38 | Collections.reverse(topK); 39 | return topK; 40 | } 41 | 42 | public static void main(String[] args) { 43 | TopKFrequent tkf = new TopKFrequent(); 44 | System.out.println(tkf.topKFrequent(new String[]{}, 10)); 45 | System.out.println(tkf.topKFrequent(new String[]{"i", "love", "leetcode", "i", "love", "coding"}, 2)); 46 | System.out.println(tkf.topKFrequent(new String[]{"the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"}, 4)); 47 | System.out.println(tkf.topKFrequent(new String[]{"a", "b", "c"}, 2)); 48 | System.out.println(tkf.topKFrequent(new String[]{"a", "b", "c", "c", "b"}, 2)); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/dp/FlipStringMonotoneIncrease.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.dp 2 | 3 | import kotlin.math.min 4 | 5 | /** 6 | * 926. Flip String to Monotone Increasing 7 | * https://leetcode.com/problems/flip-string-to-monotone-increasing/ 8 | */ 9 | class FlipStringMonotoneIncrease { 10 | 11 | fun minFlipsMonoIncr(s: String): Int { 12 | val cache = HashMap, Int>() 13 | fun minFlip(index: Int, prev: Char): Int { 14 | if (index == s.length) return 0 15 | val key = Pair(index, prev) 16 | if (cache.containsKey(key)) return cache[key]!! 17 | val result = when (Pair(prev, s[index])) { 18 | Pair('0', '0') -> min(1 + minFlip(index + 1, '1'), minFlip(index + 1, '0')) 19 | Pair('0', '1') -> min(1 + minFlip(index + 1, '0'), minFlip(index + 1, '1')) 20 | Pair('1', '0') -> 1 + minFlip(index + 1, '1') 21 | Pair('1', '1') -> minFlip(index + 1, '1') 22 | else -> 0 23 | } 24 | cache[key] = result 25 | return result 26 | } 27 | return min(minFlip(0, '0'), minFlip(0, '1')) 28 | } 29 | } 30 | 31 | fun main() { 32 | val fsmi = FlipStringMonotoneIncrease() 33 | println(fsmi.minFlipsMonoIncr("00110"))//1 34 | println(fsmi.minFlipsMonoIncr("010110"))//2 35 | println(fsmi.minFlipsMonoIncr("00011000"))//2 36 | println(fsmi.minFlipsMonoIncr("000110000"))//2 37 | println(fsmi.minFlipsMonoIncr("1001100100"))//4 38 | println(fsmi.minFlipsMonoIncr("10011000111"))//3 39 | //238 40 | val start = System.currentTimeMillis() 41 | println(fsmi.minFlipsMonoIncr("100110001111001100011110011000111100110001111001100011110011000111100110001111001100011110011000111100110001111001100011110011000111100110001111001100011110011000111100110001111001100011110011000111100110001111001100011110011000111100110001111001100011110011000111100110001111001100011110011000111100110001111001100011110011000111100110001111001100011110011000111100110001111001100011110011000111100110001111001100011110011000111100110001111001100011110011000111100110001111001100011110011000111100110001111001100011110011000111")) 42 | println("Time taken: ${System.currentTimeMillis() - start}ms") 43 | } -------------------------------------------------------------------------------- /ProblemSolving/Hard/Trees/NodeDistanceByLCA.py: -------------------------------------------------------------------------------- 1 | """ 2 | Find distance between two nodes in a binary tree. 3 | distance = number of edges in the path between two nodes. 4 | - Each node stores a key, left pointer, right pointer. 5 | - You are given 2 node keys who exists in the tree. No two keys in the tree have same value. 6 | 7 | 1) Binary Search Tree - algo only 8 | 2) Binary Tree - algo + code 9 | 10 | class TreeNode: 11 | def __init__(self, x): 12 | self.key = x 13 | self.left = None 14 | self.right = None 15 | 16 | 1 17 | / \ 18 | 2 3 19 | / \ / \ 20 | 4 5 6 7 21 | \ 22 | 8 23 | """ 24 | """ 25 | https://www.geeksforgeeks.org/find-distance-between-two-nodes-of-a-binary-tree/ 26 | 27 | Challenging the interviewee: 28 | - The whole algorithm is centered around LCA : Lowest common ancestor. Best O(N) time, O(N) space. 29 | - Distance between A and B = Height(A) + Height(B) - 2 * Height(LCA) 30 | - Start with BST and then take it to normal BT 31 | - Unit test to break the code 32 | - What should we do if we have large number queries for node distances. 33 | """ 34 | 35 | from ProblemSolving.Hard.Trees.Model.TreeNodeModel import TreeNode, create_mock_binary_tree 36 | from ProblemSolving.Easy.Trees.NodeLevel import node_level 37 | 38 | 39 | def lowest_common_ancestor(root_node: TreeNode, key1, key2): 40 | if root_node is None or root_node.val == key1 or root_node.val == key2: 41 | return root_node 42 | 43 | left_lca = lowest_common_ancestor(root_node.left, key1, key2) 44 | right_lca = lowest_common_ancestor(root_node.right, key1, key2) 45 | 46 | if left_lca and right_lca: 47 | return root_node 48 | 49 | return left_lca or right_lca 50 | 51 | 52 | def node_distance(root_node: TreeNode, key1, key2): 53 | lca = lowest_common_ancestor(root_node, key1, key2) 54 | key1_level, key2_level = node_level(lca, key1) - 1, node_level(lca, key2) - 1 55 | return key1_level + key2_level 56 | 57 | 58 | if __name__ == '__main__': 59 | root = create_mock_binary_tree() 60 | print(node_distance(root, 1, 7)) 61 | print(node_distance(root, 8, 7)) 62 | print(node_distance(root, 1, 8)) 63 | print(node_distance(root, 4, 8)) 64 | print(node_distance(root, 8, 8)) 65 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/dp/BestTeamWithNoConflict.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.dp 2 | 3 | import leetcode.utils.randomIntArray 4 | 5 | /** 6 | * 1626. Best Team With No Conflicts 7 | * https://leetcode.com/problems/best-team-with-no-conflicts/ 8 | */ 9 | class BestTeamWithNoConflict { 10 | private data class Player(val score: Int, val age: Int) 11 | 12 | fun bestTeamScore(scores: IntArray, ages: IntArray): Int { 13 | val players = scores.zip(ages).map { Player(it.first, it.second) }.toMutableList() 14 | players.sortBy { it.score } 15 | players.sortBy { it.age } 16 | val cache = Array(players.size) { IntArray(players.size) { -1 } } 17 | return bestTeamScoreHelper(players, 0, -1, cache) 18 | } 19 | 20 | private fun bestTeamScoreHelper(players: List, index: Int, previous: Int, cache: Array): Int { 21 | if (index >= players.size) return 0 22 | if (cache[previous + 1][index] != -1) return cache[previous + 1][index] 23 | val currentPlayer = players[index] 24 | val previousPlayer = if (previous == -1) Player(0, Int.MIN_VALUE) else players[previous] 25 | val isConflict = (currentPlayer.age > previousPlayer.age && currentPlayer.score < previousPlayer.score) 26 | val take = if (!isConflict) bestTeamScoreHelper(players, index + 1, index, cache) + currentPlayer.score else 0 27 | val dontTake = bestTeamScoreHelper(players, index + 1, previous, cache) 28 | cache[previous + 1][index] = maxOf(take, dontTake) 29 | return cache[previous + 1][index] 30 | } 31 | } 32 | 33 | fun main() { 34 | val btnc = BestTeamWithNoConflict() 35 | println(btnc.bestTeamScore(intArrayOf(2, 3, 5, 6, 7), intArrayOf(30, 25, 35, 40, 23)))//14 36 | println(btnc.bestTeamScore(intArrayOf(1, 3, 5, 10, 15), intArrayOf(1, 2, 3, 4, 5)))//34 37 | println(btnc.bestTeamScore(intArrayOf(4, 5, 6, 5), intArrayOf(2, 1, 2, 1)))//16 38 | println(btnc.bestTeamScore(intArrayOf(1, 2, 3, 5), intArrayOf(8, 9, 10, 1)))//6 39 | println(btnc.bestTeamScore(randomIntArray(10, 1, 1_000_000), randomIntArray(10, 1, 1000))) 40 | val start = System.currentTimeMillis() 41 | println(btnc.bestTeamScore(randomIntArray(1000, 1, 1_000_000), randomIntArray(1000, 1, 1000))) 42 | println("time: ${System.currentTimeMillis() - start} ms") 43 | } 44 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/tree/QuadTree.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.tree 2 | 3 | 4 | /** 5 | * 427. Construct Quad Tree 6 | * https://leetcode.com/problems/construct-quad-tree/ 7 | */ 8 | class QuadTree { 9 | data class Node(var `val`: Boolean, var isLeaf: Boolean) { 10 | var topLeft: Node? = null 11 | var topRight: Node? = null 12 | var bottomLeft: Node? = null 13 | var bottomRight: Node? = null 14 | } 15 | 16 | fun construct(grid: Array): Node? { 17 | if (grid.isEmpty()) return null 18 | return constructHelper(grid, 0, 0, grid.size) 19 | } 20 | 21 | private fun constructHelper(grid: Array, row: Int, col: Int, length: Int): Node { 22 | if (length == 1) return Node(grid[row][col] == 1, true) 23 | val topLeft = constructHelper(grid, row, col, length / 2) 24 | val topRight = constructHelper(grid, row, col + length / 2, length / 2) 25 | val bottomLeft = constructHelper(grid, row + length / 2, col, length / 2) 26 | val bottomRight = constructHelper(grid, row + length / 2, col + length / 2, length / 2) 27 | if (topLeft.isLeaf && topRight.isLeaf && bottomLeft.isLeaf && bottomRight.isLeaf && 28 | topLeft.`val` == topRight.`val` && topRight.`val` == bottomLeft.`val` && bottomLeft.`val` == bottomRight.`val` 29 | ) { 30 | return Node(topLeft.`val`, true) // all children are leafs and have the same value 31 | } 32 | return Node(`val` = false, isLeaf = false).apply { 33 | this.topLeft = topLeft 34 | this.topRight = topRight 35 | this.bottomLeft = bottomLeft 36 | this.bottomRight = bottomRight 37 | } 38 | } 39 | } 40 | 41 | fun main() { 42 | val qt = QuadTree() 43 | println( 44 | qt.construct( 45 | arrayOf( 46 | intArrayOf(1, 1, 1, 1, 0, 0, 0, 0), 47 | intArrayOf(1, 1, 1, 1, 0, 0, 0, 0), 48 | intArrayOf(1, 1, 1, 1, 1, 1, 1, 1), 49 | intArrayOf(1, 1, 1, 1, 1, 1, 1, 1), 50 | intArrayOf(1, 1, 1, 1, 0, 0, 0, 0), 51 | intArrayOf(1, 1, 1, 1, 0, 0, 0, 0), 52 | intArrayOf(1, 1, 1, 1, 0, 0, 0, 0), 53 | intArrayOf(1, 1, 1, 1, 0, 0, 0, 0) 54 | ) 55 | ) 56 | ) 57 | } 58 | -------------------------------------------------------------------------------- /CleanCode/src/test/java/FoodPandaTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions; 2 | import org.junit.jupiter.api.Test; 3 | 4 | import java.util.ArrayList; 5 | import java.util.NoSuchElementException; 6 | 7 | interface ISet { 8 | void Push(T t) throws IllegalArgumentException; 9 | T Pop() throws NoSuchElementException; 10 | T Remove(T t) throws NoSuchElementException, IllegalArgumentException; 11 | ISet Intersect(ISet otherSet) throws IllegalArgumentException; 12 | Iterable Values(); 13 | Iterable OrderedValues(boolean firstToLast); 14 | Integer Size(); 15 | } 16 | 17 | class MySet implements ISet { 18 | private final ArrayList store = new ArrayList<>(); 19 | @Override 20 | public void Push(T t) throws IllegalArgumentException { 21 | if (t == null) 22 | throw new IllegalArgumentException(); 23 | if (store.stream().noneMatch(e -> e.equals(t))) 24 | store.add(t); 25 | } 26 | 27 | @Override 28 | public T Pop() throws NoSuchElementException { 29 | return null; 30 | } 31 | 32 | @Override 33 | public T Remove(T t) throws NoSuchElementException, IllegalArgumentException { 34 | return null; 35 | } 36 | 37 | @Override 38 | public ISet Intersect(ISet otherSet) throws IllegalArgumentException { 39 | return null; 40 | } 41 | 42 | @Override 43 | public Iterable Values() { 44 | return null; 45 | } 46 | 47 | @Override 48 | public Iterable OrderedValues(boolean firstToLast) { 49 | return null; 50 | } 51 | 52 | @Override 53 | public Integer Size() { 54 | return store.size(); 55 | } 56 | } 57 | 58 | public class FoodPandaTest { 59 | @Test 60 | public void Test_Push_Integer_Null() { 61 | ISet set = new MySet<>(); 62 | Assertions.assertThrows(IllegalArgumentException.class, () -> set.Push(null)); 63 | } 64 | @Test 65 | public void Test_Push_Integer_Valid() { 66 | ISet set = new MySet<>(); 67 | set.Push(1); 68 | Assertions.assertEquals(set.Size(), 1); 69 | } 70 | @Test 71 | public void Test_Push_Integer_Uniqueness() { 72 | ISet set = new MySet<>(); 73 | set.Push(1); 74 | set.Push(1); 75 | Assertions.assertEquals(set.Size(), 1); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/hard/math/MaxPointsLine.kt: -------------------------------------------------------------------------------- 1 | package leetcode.hard.math 2 | 3 | /** 4 | * 149. Max Points on a Line 5 | * https://leetcode.com/problems/max-points-on-a-line/ 6 | */ 7 | class MaxPointsLine { 8 | fun maxPoints(points: Array): Int { 9 | val lines = mutableMapOf, MutableSet>>() 10 | for (i in points.indices) { 11 | for (j in i + 1 until points.size) { 12 | val coefficient = lineCoefficient(points[i], points[j]) 13 | lines[coefficient] = lines.getOrDefault(coefficient, mutableSetOf()).apply { 14 | add(points[i][0] to points[i][1]) 15 | add(points[j][0] to points[j][1]) 16 | } 17 | } 18 | } 19 | return if (lines.isNotEmpty()) lines.maxBy { it.value.size }.value.size else 1 20 | } 21 | 22 | private fun lineCoefficient(point: IntArray, otherPoint: IntArray): Triple { 23 | val a = point[1] - otherPoint[1] 24 | val b = otherPoint[0] - point[0] 25 | val c = point[0] * otherPoint[1] - otherPoint[0] * point[1] 26 | val gcd = gcd(a, gcd(b, c)) 27 | return Triple(a / gcd, b / gcd, c / gcd) 28 | } 29 | 30 | private fun gcd(x: Int, y: Int): Int { 31 | if (y == 0) return x 32 | return gcd(y, x % y) 33 | } 34 | } 35 | 36 | fun main() { 37 | val mpl = MaxPointsLine() 38 | println(mpl.maxPoints(arrayOf(intArrayOf(1, 1), intArrayOf(2, 2), intArrayOf(3, 3))))//3 39 | println(mpl.maxPoints(arrayOf(intArrayOf(1, 1))))//1 40 | println(mpl.maxPoints(arrayOf(intArrayOf(1, 1), intArrayOf(1000, 2000))))//2 41 | println( 42 | mpl.maxPoints( 43 | arrayOf( 44 | intArrayOf(1, 1), 45 | intArrayOf(3, 2), 46 | intArrayOf(5, 3), 47 | intArrayOf(4, 1), 48 | intArrayOf(2, 3), 49 | intArrayOf(1, 4) 50 | ) 51 | ) 52 | )//4 53 | println( 54 | mpl.maxPoints( 55 | arrayOf( 56 | intArrayOf(1, 1), 57 | intArrayOf(2, 3), 58 | intArrayOf(3, 2), 59 | intArrayOf(5, 3), 60 | intArrayOf(4, 1), 61 | intArrayOf(1, 4) 62 | ) 63 | ) 64 | )//4 65 | } -------------------------------------------------------------------------------- /LeetCodeKotlin/src/main/kotlin/leetcode/medium/graph/FindClosestNodeGivenTwoNodes.kt: -------------------------------------------------------------------------------- 1 | package leetcode.medium.graph 2 | 3 | import java.util.* 4 | import kotlin.collections.HashMap 5 | 6 | /** 7 | * 2359. Find Closest Node Given Two Nodes 8 | * https://leetcode.com/problems/find-closest-node-given-two-nodes/ 9 | */ 10 | class FindClosestNodeGivenTwoNodes { 11 | fun closestMeetingNode(edge: IntArray, n1: Int, n2: Int): Int { 12 | val (n, graph) = edge.size to HashMap>() 13 | for (i in 0 until n) graph[i] = mutableListOf() 14 | for (v in edge.indices) if (edge[v] != -1) graph[v]!!.add(edge[v]) 15 | val (distanceToN1, distanceToN2) = bfs(n1, graph) to bfs(n2, graph) 16 | val commons = distanceToN2.keys.intersect(distanceToN1.keys) 17 | if (commons.isEmpty()) return -1 18 | val nodes = commons.map { it to maxOf(distanceToN1[it]!!, distanceToN2[it]!!) } 19 | .sortedBy { it.first }.sortedBy { it.second } 20 | return nodes.first().first 21 | } 22 | 23 | private fun bfs(start: Int, graph: HashMap>): Map { 24 | val (distance, bfsQ) = HashMap() to LinkedList() 25 | val visited = BooleanArray(graph.size) 26 | bfsQ.add(start) 27 | distance[start] = 0 28 | while (bfsQ.isNotEmpty()) { 29 | val node = bfsQ.remove() 30 | for (next in graph[node]!!) { 31 | if (!visited[next]) { 32 | distance[next] = distance[node]!! + 1 33 | bfsQ.add(next) 34 | } 35 | } 36 | visited[node] = true 37 | } 38 | return distance 39 | } 40 | } 41 | 42 | fun main() { 43 | val fcn = FindClosestNodeGivenTwoNodes() 44 | println(fcn.closestMeetingNode(intArrayOf(2, 2, 3, -1), 0, 1))//2 45 | println(fcn.closestMeetingNode(intArrayOf(2, 2, 3, -1), 0, 2))//2 46 | println(fcn.closestMeetingNode(intArrayOf(2, 2, 3, -1), 0, 3))//3 47 | println(fcn.closestMeetingNode(intArrayOf(2, 2, 3, -1), 1, 2))//2 48 | println(fcn.closestMeetingNode(intArrayOf(-1, 2, 3, -1), 0, 1))//-1 49 | println(fcn.closestMeetingNode(intArrayOf(4, 3, 0, 5, 3, -1), 4, 0))//4 50 | println(fcn.closestMeetingNode(intArrayOf(4, 4, 4, 5, 1, 2, 2), 1, 1))//1 51 | println(fcn.closestMeetingNode(intArrayOf(4, 2, 5, 1, 3, 6, 5), 1, 6))//5 52 | } -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/backtracking/MaxLengthConcatenation.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.backtracking; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | /** 8 | * https://leetcode.com/problems/maximum-length-of-a-concatenated-string-with-unique-characters/ 9 | */ 10 | public class MaxLengthConcatenation { 11 | private int buildWordBitMap(String word) { 12 | int bitmap = 0; 13 | for (char ch : word.toCharArray()) { 14 | int bitMask = 1 << (ch - 'a'); 15 | if ((bitmap & bitMask) != 0) return 0; 16 | bitmap |= bitMask; 17 | } 18 | return bitmap; 19 | } 20 | 21 | private boolean hasMatch(int word, int otherWord) { 22 | return (word & otherWord) != 0; 23 | } 24 | 25 | private int concat(int word, int otherWord) { 26 | return (word | otherWord); 27 | } 28 | 29 | public int maxLength(List words) { 30 | List _words = words.stream().map(this::buildWordBitMap).collect(Collectors.toList()); 31 | return maxLengthHelper(_words, 0, 0); 32 | } 33 | 34 | public int maxLengthHelper(List words, int start, int uniqueChars) { 35 | if (start == words.size()) return Integer.bitCount(uniqueChars); 36 | int word = words.get(start); 37 | int resultWithoutWord = maxLengthHelper(words, start + 1, uniqueChars); 38 | if (hasMatch(word, uniqueChars)) return resultWithoutWord; 39 | int resultWithWord = maxLengthHelper(words, start + 1, concat(word, uniqueChars)); 40 | return Math.max(resultWithWord, resultWithoutWord); 41 | } 42 | 43 | public static void main(String[] args) { 44 | MaxLengthConcatenation mlc = new MaxLengthConcatenation(); 45 | System.out.println(mlc.maxLength(Arrays.asList("a", "ab", "az"))); 46 | System.out.println(mlc.maxLength(Arrays.asList("a", "ab", "cd"))); 47 | System.out.println(mlc.maxLength(Arrays.asList("cha", "r", "act", "ers"))); 48 | System.out.println(mlc.maxLength(Arrays.asList("abcdefghijklmnopqrstuvwxyz", "a"))); 49 | System.out.println(mlc.maxLength(Arrays.asList("un", "iq", "ue"))); 50 | System.out.println(mlc.maxLength(Arrays.asList("aa", "bb"))); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/easy/arrays/GameOfLife.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.arrays; 2 | 3 | import java.util.Arrays; 4 | 5 | import static java.lang.System.arraycopy; 6 | 7 | /** 8 | * Game of Life 9 | */ 10 | public class GameOfLife { 11 | 12 | private final int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1}}; 13 | 14 | public void gameOfLife(int[][] board) { 15 | int[][] backup = clone(board); 16 | for (int row = 0; row < board.length; row++) { 17 | for (int col = 0; col < board[0].length; col++) { 18 | int alive = aliveNeighbours(backup, row, col); 19 | if (board[row][col] == 1 && alive > 3) board[row][col] = 0; 20 | else if (board[row][col] == 1 && alive < 2) board[row][col] = 0; 21 | else if (board[row][col] == 0 && alive == 3) board[row][col] = 1; 22 | } 23 | } 24 | } 25 | 26 | private boolean isValid(int[][] board, int row, int col) { 27 | return row >= 0 && row < board.length && col >= 0 && col < board[0].length; 28 | } 29 | 30 | private int aliveNeighbours(int[][] board, int row, int col) { 31 | int alive = 0; 32 | for (int[] dir : dirs) 33 | if (isValid(board, row + dir[0], col + dir[1]) && board[row + dir[0]][col + dir[1]] == 1) alive++; 34 | return alive; 35 | } 36 | 37 | private int[][] clone(int[][] board) { 38 | int[][] backup = new int[board.length][board[0].length]; 39 | for (int row = 0; row < board.length; row++) arraycopy(board[row], 0, backup[row], 0, board[row].length); 40 | return backup; 41 | } 42 | 43 | public static void main(String[] args) { 44 | var gol = new GameOfLife(); 45 | int[][] board = {{0, 0, 0}, {1, 0, 1}, {0, 1, 1}, {0, 1, 0}}; 46 | gol.gameOfLife(board); 47 | System.out.println(Arrays.deepToString(board));//[[0,0,0],[0,0,1],[1,0,1],[0,1,1]] 48 | 49 | board = new int[][]{{1, 1}, {1, 0}}; 50 | gol.gameOfLife(board); 51 | System.out.println(Arrays.deepToString(board));//[[1,1],[1,1]] 52 | 53 | board = new int[][]{{0, 1, 0}, {0, 0, 1}, {1, 1, 1}, {0, 0, 0}}; 54 | gol.gameOfLife(board); 55 | System.out.println(Arrays.deepToString(board));//[[0,0,0],[1,0,1],[0,1,1],[0,1,0]] 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/unionfind/AccountsMerge.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.unionfind; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * https://leetcode.com/problems/accounts-merge/ 7 | */ 8 | public class AccountsMerge { 9 | public List> accountsMerge(List> accounts) { 10 | int numVertices = accounts.size(); 11 | UnionFind uf = new UnionFind(numVertices); 12 | Map emailToNameMap = new HashMap<>(); 13 | for (int i = 0; i < accounts.size(); i++) { 14 | List account = accounts.get(i); 15 | for (int j = 1; j < account.size(); j++) { 16 | String email = account.get(j); 17 | if (emailToNameMap.containsKey(email)) { 18 | uf.union(i, emailToNameMap.get(email)); 19 | } else { 20 | emailToNameMap.put(email, i); 21 | } 22 | } 23 | } 24 | 25 | Map> mergedAccounts = new HashMap<>(); 26 | for (int i = 0; i < accounts.size(); i++) { 27 | int parent = uf.find(i); 28 | if (!mergedAccounts.containsKey(parent)) mergedAccounts.put(parent, new TreeSet<>()); 29 | mergedAccounts.get(parent).addAll(accounts.get(i)); 30 | } 31 | 32 | List> finalAccounts = new ArrayList<>(); 33 | for (Map.Entry> entry : mergedAccounts.entrySet()) { 34 | String name = accounts.get(entry.getKey()).get(0); 35 | List account = new ArrayList<>(); 36 | account.add(name); 37 | entry.getValue().remove(name); 38 | account.addAll(entry.getValue()); 39 | finalAccounts.add(account); 40 | } 41 | 42 | return finalAccounts; 43 | } 44 | 45 | public static void main(String[] args) { 46 | AccountsMerge am = new AccountsMerge(); 47 | List> accounts = Arrays.asList(Arrays.asList("John", "johnsmith@mail.com", "john_newyork@mail.com"), 48 | Arrays.asList("John", "johnsmith@mail.com", "john00@mail.com"), 49 | Arrays.asList("Mary", "mary@mail.com"), 50 | Arrays.asList("John", "johnnybravo@mail.com") 51 | ); 52 | System.out.println(am.accountsMerge(accounts)); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/medium/sort/MinimumMeetingRooms.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.sort; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | /** 8 | * https://leetcode.com/problems/meeting-rooms-ii/ 9 | */ 10 | public class MinimumMeetingRooms { 11 | public int minMeetingRooms(int[][] meetings) { 12 | if (meetings.length < 2) return meetings.length; 13 | 14 | List startTimes = Arrays.stream(meetings).map(meeting -> meeting[0]) 15 | .sorted().collect(Collectors.toList()); 16 | List endTimes = Arrays.stream(meetings).map(meeting -> meeting[1]) 17 | .sorted().collect(Collectors.toList()); 18 | int ongoingMeetings = 1, maxMeetingRooms = 1, startIndex = 1, endIndex = 0; 19 | while (startIndex < meetings.length && endIndex < meetings.length) { 20 | if (endTimes.get(endIndex) < startTimes.get(startIndex)) { 21 | // a existing meeting ended 22 | endIndex++; 23 | ongoingMeetings--; 24 | } else if (endTimes.get(endIndex).equals(startTimes.get(startIndex))) { 25 | // a existing meeting ended and new meeting started simultaneously 26 | endIndex++; 27 | startIndex++; 28 | } else { 29 | // a new meeting started 30 | startIndex++; 31 | ongoingMeetings++; 32 | maxMeetingRooms = Math.max(ongoingMeetings, maxMeetingRooms); 33 | } 34 | } 35 | return maxMeetingRooms; 36 | } 37 | 38 | public static void main(String[] args) { 39 | MinimumMeetingRooms mmr = new MinimumMeetingRooms(); 40 | System.out.println(mmr.minMeetingRooms(new int[][]{{15, 18}, {1, 3}, {8, 10}, {2, 6}})); 41 | System.out.println(mmr.minMeetingRooms(new int[][]{{9, 18}, {1, 3}, {8, 10}, {2, 6}})); 42 | System.out.println(mmr.minMeetingRooms(new int[][]{{9, 18}, {1, 3}, {7, 10}, {2, 8}})); 43 | System.out.println(mmr.minMeetingRooms(new int[][]{{9, 18}})); 44 | System.out.println(mmr.minMeetingRooms(new int[][]{{9, 18}, {20, 100}})); 45 | System.out.println(mmr.minMeetingRooms(new int[][]{{9, 18}, {18, 100}})); 46 | System.out.println(mmr.minMeetingRooms(new int[][]{{0, 30}, {5, 10}, {15, 20}})); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /LeetCodeJava/src/main/java/leetcode/easy/trees/SubtreeOfAnotherTree.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.trees; 2 | 3 | import java.security.MessageDigest; 4 | import java.security.NoSuchAlgorithmException; 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | 8 | /** 9 | * Subtree of Another Tree 10 | */ 11 | public class SubtreeOfAnotherTree { 12 | private static class TreeNode { 13 | int val; 14 | TreeNode left; 15 | TreeNode right; 16 | 17 | TreeNode(int x) { 18 | val = x; 19 | } 20 | } 21 | 22 | public boolean isSubtree(TreeNode root, TreeNode subRoot) { 23 | try { 24 | var mainTreeHashes = new HashSet(); 25 | treeHash(root, mainTreeHashes); 26 | var subtreeHash = treeHash(subRoot, new HashSet<>()); 27 | return mainTreeHashes.contains(subtreeHash); 28 | } catch (NoSuchAlgorithmException e) { 29 | throw new RuntimeException(e); 30 | } 31 | } 32 | 33 | private String getHash(String input) throws NoSuchAlgorithmException { 34 | var md5Hasher = MessageDigest.getInstance("MD5"); 35 | StringBuilder sb = new StringBuilder(); 36 | for (byte b : md5Hasher.digest(input.getBytes())) sb.append(String.format("%02x", b)); 37 | return sb.toString(); 38 | } 39 | 40 | private String treeHash(TreeNode root, Set hashes) throws NoSuchAlgorithmException { 41 | if (root == null) return ""; 42 | var left = treeHash(root.left, hashes); 43 | var right = treeHash(root.right, hashes); 44 | var subtreeHash = getHash(left + root.val + right); 45 | hashes.add(subtreeHash); 46 | return subtreeHash; 47 | } 48 | 49 | public static void main(String[] args) { 50 | var sat = new SubtreeOfAnotherTree(); 51 | var root = new TreeNode(3); 52 | root.left = new TreeNode(4); 53 | root.right = new TreeNode(5); 54 | root.left.left = new TreeNode(1); 55 | root.left.right = new TreeNode(2); 56 | 57 | var subRoot = new TreeNode(4); 58 | subRoot.left = new TreeNode(1); 59 | subRoot.right = new TreeNode(2); 60 | 61 | System.out.println(sat.isSubtree(root, subRoot));//true 62 | System.out.println(sat.isSubtree(root, new TreeNode(1)));//true 63 | System.out.println(sat.isSubtree(root, new TreeNode(10)));//false 64 | } 65 | } 66 | --------------------------------------------------------------------------------