├── .classpath ├── .gitignore ├── .project ├── .settings ├── org.eclipse.buildship.core.prefs └── org.eclipse.jdt.core.prefs ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src └── main ├── java └── FoobarChallenge.java └── kotlin ├── AccountMerger.kt ├── AssertMap.kt ├── AuthenticationManager.kt ├── CollaborativePlaylist.kt ├── Converter.java ├── CountMatchers.kt ├── DesignHashMap.kt ├── Explore.kt ├── FindMedian.kt ├── FreqStack.kt ├── Hasmap.kt ├── InvertedBisection.kt ├── ListNode.kt ├── Main.kt ├── MaxStack.kt ├── ProductEncodedArray.kt ├── Randomized.kt ├── SnakeGame.kt ├── Solution.kt ├── SpaceVector.kt ├── SpecialString.kt ├── SupportX.kt ├── TaskServer.kt ├── TimeSpend.kt ├── TreeNode.kt ├── Trie.kt ├── TweetCountPerFrequency.kt ├── Twitter.kt ├── ValidateIP.kt ├── Vector2D.kt ├── WordDistance.kt ├── algoexpert ├── AlgoMain.kt ├── BFS.kt ├── BalanceIndex.kt ├── BuildFailure.kt ├── LruCache.kt ├── MinHeap.kt ├── PhoneNumber.kt └── RepeatedMatrix.kt ├── algomonster ├── BinarySearch.java ├── PlayingCards.java ├── TwoPointers.java └── ValidParent.java ├── foobar ├── FoobarMain.kt ├── FuelInjection.java ├── FuelInjections.kt ├── SkippingWork.kt └── SolarDoomsday.java ├── hackerrank └── CountPairs.kt ├── karat └── MainKarat.kt ├── leetcode ├── AllOne.kt ├── FindItnerary.kt ├── FoodRating.kt ├── HitCounter.kt ├── KthLargest.kt ├── LRUCache.kt ├── LogSystem.kt ├── MovingAverage.kt ├── NumAarray.kt ├── NumberMatrix.kt ├── ParkingSystem.kt ├── PhoneDirectory.kt ├── ProductOfNumber.kt ├── UniqueEmail.kt ├── ValidSudoku.kt ├── WebsiteAnalysis.kt └── WordDictionary.kt └── training └── main.kt /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 2 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 3 | 4 | # User-specific stuff 5 | .idea/**/workspace.xml 6 | .idea/**/tasks.xml 7 | .idea/**/usage.statistics.xml 8 | .idea/**/dictionaries 9 | .idea/**/shelf 10 | */.idea 11 | .idea 12 | .idea/misc.xml 13 | 14 | # AWS User-specific 15 | .idea/**/aws.xml 16 | 17 | # Generated files 18 | .idea/**/contentModel.xml 19 | 20 | # Sensitive or high-churn files 21 | .idea/**/dataSources/ 22 | .idea/**/dataSources.ids 23 | .idea/**/dataSources.local.xml 24 | .idea/**/sqlDataSources.xml 25 | .idea/**/dynamic.xml 26 | .idea/**/uiDesigner.xml 27 | .idea/**/dbnavigator.xml 28 | 29 | # Gradle 30 | .idea/**/gradle.xml 31 | .idea/**/libraries 32 | 33 | # Gradle and Maven with auto-import 34 | # When using Gradle or Maven with auto-import, you should exclude module files, 35 | # since they will be recreated, and may cause churn. Uncomment if using 36 | # auto-import. 37 | # .idea/artifacts 38 | # .idea/compiler.xml 39 | # .idea/jarRepositories.xml 40 | # .idea/modules.xml 41 | # .idea/*.iml 42 | # .idea/modules 43 | # *.iml 44 | # *.ipr 45 | 46 | # CMake 47 | cmake-build-*/ 48 | 49 | # Mongo Explorer plugin 50 | .idea/**/mongoSettings.xml 51 | 52 | # File-based project format 53 | *.iws 54 | 55 | # IntelliJ 56 | out/ 57 | 58 | # mpeltonen/sbt-idea plugin 59 | .idea_modules/ 60 | 61 | # JIRA plugin 62 | atlassian-ide-plugin.xml 63 | 64 | # Cursive Clojure plugin 65 | .idea/replstate.xml 66 | 67 | # SonarLint plugin 68 | .idea/sonarlint/ 69 | 70 | # Crashlytics plugin (for Android Studio and IntelliJ) 71 | com_crashlytics_export_strings.xml 72 | crashlytics.properties 73 | crashlytics-build.properties 74 | fabric.properties 75 | 76 | # Editor-based Rest Client 77 | .idea/httpRequests 78 | 79 | # Android studio 3.1+ serialized cache file 80 | .idea/caches/build_file_checksums.ser.idea 81 | 82 | *.bin 83 | *.lock 84 | *.tab 85 | *.class 86 | *.keystream 87 | *.len 88 | *.properties 89 | *.txt 90 | *.tab* 91 | *.at 92 | *.s 93 | *.tab.* 94 | *.kotlin_module -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | practice-algo 4 | Project practice created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.buildship.core.gradleprojectbuilder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.buildship.core.gradleprojectnature 22 | 23 | 24 | 25 | 1659710624403 26 | 27 | 30 28 | 29 | org.eclipse.core.resources.regexFilterMatcher 30 | node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | arguments= 2 | auto.sync=false 3 | build.scans.enabled=false 4 | connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) 5 | connection.project.dir= 6 | eclipse.preferences.version=1 7 | gradle.user.home= 8 | java.home=/usr/local/Cellar/openjdk@11/11.0.15/libexec/openjdk.jdk/Contents/Home 9 | jvm.arguments= 10 | offline.mode=false 11 | override.workspace.settings=true 12 | show.console.view=true 13 | show.executions.view=true 14 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 3 | org.eclipse.jdt.core.compiler.compliance=1.8 4 | org.eclipse.jdt.core.compiler.source=1.8 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # algorithm-practice 2 | my daily algorithm-practice to sharpen my Algorithm and Data structure knowledge 3 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'org.jetbrains.kotlin.jvm' version '1.3.11' 4 | } 5 | 6 | group 'practice-algo' 7 | version '1.0-SNAPSHOT' 8 | 9 | sourceCompatibility = 1.8 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8" 17 | testCompile group: 'junit', name: 'junit', version: '4.12' 18 | } 19 | 20 | compileKotlin { 21 | kotlinOptions.jvmTarget = "1.8" 22 | } 23 | compileTestKotlin { 24 | kotlinOptions.jvmTarget = "1.8" 25 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.code.style=official -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andriiginting/algorithm-practice/9ccaddabccfb483f56c485a6278150eaac616774/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'practice-algo' 2 | 3 | -------------------------------------------------------------------------------- /src/main/java/FoobarChallenge.java: -------------------------------------------------------------------------------- 1 | import org.jetbrains.annotations.NotNull; 2 | 3 | import java.util.*; 4 | import java.util.stream.IntStream; 5 | 6 | public class FoobarChallenge { 7 | public static void main(String[] args) { 8 | int[] x = new int[]{4, 3, 10, 2, 8}; 9 | int[] y = new int[]{5, 2, 5, 13}; 10 | int[] result = stationCodedMsg(x, 12); 11 | 12 | int[] stairs = doomsDayFuel( 13 | new int[][]{{0, 2, 1, 0, 0}, {0, 0, 0, 3, 4}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}} 14 | ); 15 | System.out.println(Arrays.toString(stairs)); 16 | } 17 | 18 | public static int solution(int[] x, int[] y) { 19 | int result = 0; 20 | if (x.length > y.length) { 21 | for (int ids : x) { 22 | if (!isContains(y, ids)) { 23 | result = ids; 24 | } 25 | } 26 | } else { 27 | for (int ids : y) { 28 | if (!isContains(x, ids)) { 29 | result = ids; 30 | } 31 | } 32 | } 33 | 34 | return result; 35 | } 36 | 37 | public static boolean isContains(int[] x, int key) { 38 | return IntStream.of(x).anyMatch(value -> value == key); 39 | } 40 | 41 | public static int[] stationCodedMsg(int[] l, int t) { 42 | int[] result = new int[]{-1, -1}; 43 | int sum = 0; 44 | 45 | for (int i = 0; i < l.length; i++) { 46 | 47 | for (int j = i; j < l.length; j++) { 48 | sum += l[j]; 49 | 50 | if (sum == t) { 51 | result[0] = i; 52 | result[1] = j; 53 | return result; 54 | } 55 | } 56 | sum = 0; 57 | } 58 | 59 | return result; 60 | } 61 | 62 | /* 63 | En Route Salute 64 | =============== 65 | 66 | Commander Lambda loves efficiency and hates anything that wastes time. The Commander is a busy lamb, after all! Henchmen who identify sources of inefficiency and come up with ways to remove them are generously rewarded. You've spotted one such source, and you think solving it will help you build the reputation you need to get promoted. 67 | 68 | Every time the Commander's employees pass each other in the hall, each of them must stop and salute each other -- one at a time -- before resuming their path. A salute is five seconds long, so each exchange of salutes takes a full ten seconds (Commander Lambda's salute is a bit, er, involved). You think that by removing the salute requirement, you could save several collective hours of employee time per day. But first, you need to show the Commander how bad the problem really is. 69 | 70 | Write a program that counts how many salutes are exchanged during a typical walk along a hallway. The hall is represented by a string. For example: 71 | "--->-><-><-->-" 72 | 73 | Each hallway string will contain three different types of characters: '>', an employee walking to the right; '<', an employee walking to the left; and '-', an empty space. Every employee walks at the same speed either to right or to the left, according to their direction. Whenever two employees cross, each of them salutes the other. They then continue walking until they reach the end, finally leaving the hallway. In the above example, they salute 10 times. 74 | 75 | Write a function solution(s) which takes a string representing employees walking along a hallway and returns the number of times the employees will salute. s will contain at least 1 and at most 100 characters, each one of -, >, or <. 76 | 77 | Languages 78 | ========= 79 | 80 | To provide a Python solution, edit solution.py 81 | To provide a Java solution, edit Solution.java 82 | 83 | Test cases 84 | ========== 85 | Your code should pass the following test cases. 86 | Note that it may also be run against hidden test cases not shown here. 87 | 88 | -- Python cases -- 89 | Input: 90 | solution.solution(">----<") 91 | Output: 92 | 2 93 | 94 | Input: 95 | solution.solution("<<>><") 96 | Output: 97 | 4 98 | 99 | -- Java cases -- 100 | Input: 101 | Solution.solution("<<>><") 102 | Output: 103 | 4 104 | 105 | Input: 106 | Solution.solution(">----<") 107 | Output: 108 | 2 109 | */ 110 | 111 | public static int enrouteSalute(String s) { 112 | int result = 0; 113 | 114 | for (int i = 0; i < s.length(); i++) { 115 | if (s.charAt(i) == '>') { 116 | for (int j = i + 1; j < s.length(); j++) { 117 | if (s.charAt(j) == '<') { 118 | result++; 119 | } 120 | } 121 | } 122 | } 123 | return result * 2; 124 | } 125 | 126 | public static int enrouteSaluteV2(String s) { 127 | int result = 0; 128 | int toRight = 0; 129 | String[] str = s.split(""); 130 | 131 | for (String salute : str) { 132 | if (salute.equalsIgnoreCase(">")) { 133 | toRight++; 134 | } else if (salute.equalsIgnoreCase("<")) { 135 | result += toRight; 136 | } 137 | } 138 | 139 | return result * 2; 140 | } 141 | 142 | /* 143 | Elevator Maintenance 144 | ==================== 145 | 146 | You've been assigned the onerous task of elevator maintenance -- ugh! It wouldn't be so bad, except that all the elevator documentation has been lying in a disorganized pile at the bottom of a filing cabinet for years, and you don't even know what elevator version numbers you'll be working on. 147 | 148 | Elevator versions are represented by a series of numbers, divided up into major, minor and revision integers. New versions of an elevator increase the major number, e.g. 1, 2, 3, and so on. When new features are added to an elevator without being a complete new version, a second number named "minor" can be used to represent those new additions, e.g. 1.0, 1.1, 1.2, etc. Small fixes or maintenance work can be represented by a third number named "revision", e.g. 1.1.1, 1.1.2, 1.2.0, and so on. The number zero can be used as a major for pre-release versions of elevators, e.g. 0.1, 0.5, 0.9.2, etc (Commander Lambda is careful to always beta test her new technology, with her loyal henchmen as subjects!). 149 | 150 | Given a list of elevator versions represented as strings, write a function solution(l) that returns the same list sorted in ascending order by major, minor, and revision number so that you can identify the current elevator version. The versions in list l will always contain major numbers, but minor and revision numbers are optional. If the version contains a revision number, then it will also have a minor number. 151 | 152 | For example, given the list l as ["1.1.2", "1.0", "1.3.3", "1.0.12", "1.0.2"], the function solution(l) would return the list ["1.0", "1.0.2", "1.0.12", "1.1.2", "1.3.3"]. If two or more versions are equivalent but one version contains more numbers than the others, then these versions must be sorted ascending based on how many numbers they have, e.g ["1", "1.0", "1.0.0"]. The number of elements in the list l will be at least 1 and will not exceed 100. 153 | 154 | Languages 155 | ========= 156 | 157 | To provide a Python solution, edit solution.py 158 | To provide a Java solution, edit Solution.java 159 | 160 | Test cases 161 | ========== 162 | Your code should pass the following test cases. 163 | Note that it may also be run against hidden test cases not shown here. 164 | 165 | -- Python cases -- 166 | Input: 167 | solution.solution(["1.11", "2.0.0", "1.2", "2", "0.1", "1.2.1", "1.1.1", "2.0"]) 168 | Output: 169 | 0.1,1.1.1,1.2,1.2.1,1.11,2,2.0,2.0.0 170 | 171 | Input: 172 | solution.solution(["1.1.2", "1.0", "1.3.3", "1.0.12", "1.0.2"]) 173 | Output: 174 | 1.0,1.0.2,1.0.12,1.1.2,1.3.3 175 | 176 | -- Java cases -- 177 | Input: 178 | Solution.solution({"1.11", "2.0.0", "1.2", "2", "0.1", "1.2.1", "1.1.1", "2.0"}) 179 | Output: 180 | 0.1,1.1.1,1.2,1.2.1,1.11,2,2.0,2.0.0 181 | 182 | Input: 183 | Solution.solution({"1.1.2", "1.0", "1.3.3", "1.0.12", "1.0.2"}) 184 | Output: 185 | 1.0,1.0.2,1.0.12,1.1.2,1.3.3 186 | */ 187 | 188 | @NotNull 189 | public static String[] elevationMantain(String[] l) { 190 | List list = new ArrayList<>(); 191 | 192 | for (String version : l) { 193 | String[] rawVersion = version.split("\\."); 194 | list.add(rawVersion); 195 | } 196 | 197 | list.sort((first, second) -> { 198 | int idx = 0; 199 | while (idx < Math.min(first.length, second.length)) { 200 | int parse = Integer.compare( 201 | Integer.parseInt(first[idx]), 202 | Integer.parseInt(second[idx]) 203 | ); 204 | 205 | if (parse != 0) { 206 | return parse; 207 | } 208 | idx++; 209 | } 210 | return Integer.compare(first.length, second.length); 211 | } 212 | ); 213 | 214 | return list.stream() 215 | .map(strings -> String.join(".", strings)) 216 | .toArray(String[]::new); 217 | } 218 | 219 | public static String[] elevatorMaintenance(String[] l) { 220 | Comparator comparator = (o1, o2) -> { 221 | String[] first = o1.split("\\."); 222 | String[] second = o2.split("\\."); 223 | 224 | int parse = Integer.parseInt(first[0]) - Integer.parseInt(second[0]); 225 | 226 | if (parse != 0) { 227 | return parse; 228 | } 229 | 230 | if (first.length == 1 || second.length == 1) { 231 | return first.length - second.length; 232 | } 233 | 234 | int minorVersion = Integer.parseInt(first[1]) - Integer.parseInt(second[1]); 235 | if (minorVersion != 0) { 236 | return minorVersion; 237 | } 238 | 239 | if (first.length == 2 || second.length == 2) { 240 | return first.length - second.length; 241 | } 242 | 243 | return Integer.parseInt(first[2]) - Integer.parseInt(second[2]); 244 | }; 245 | Arrays.sort(l, comparator); 246 | return l; 247 | } 248 | 249 | /* 250 | The Grandest Staircase Of Them All 251 | ================================== 252 | 253 | With the LAMBCHOP doomsday device finished, Commander Lambda is preparing to debut on the galactic stage -- but in order to make a grand entrance, Lambda needs a grand staircase! As the Commander's personal assistant, you've been tasked with figuring out how to build the best staircase EVER. 254 | 255 | Lambda has given you an overview of the types of bricks available, plus a budget. You can buy different amounts of the different types of bricks (for example, 3 little pink bricks, or 5 blue lace bricks). Commander Lambda wants to know how many different types of staircases can be built with each amount of bricks, so they can pick the one with the most options. 256 | 257 | Each type of staircase should consist of 2 or more steps. No two steps are allowed to be at the same height - each step must be lower than the previous one. All steps must contain at least one brick. A step's height is classified as the total amount of bricks that make up that step. 258 | For example, when N = 3, you have only 1 choice of how to build the staircase, with the first step having a height of 2 and the second step having a height of 1: (# indicates a brick) 259 | 260 | # 261 | ## 262 | 21 263 | 264 | When N = 4, you still only have 1 staircase choice: 265 | 266 | # 267 | # 268 | ## 269 | 31 270 | 271 | But when N = 5, there are two ways you can build a staircase from the given bricks. The two staircases can have heights (4, 1) or (3, 2), as shown below: 272 | 273 | # 274 | # 275 | # 276 | ## 277 | 41 278 | 279 | # 280 | ## 281 | ## 282 | 32 283 | 284 | Write a function called solution(n) that takes a positive integer n and returns the number of different staircases that can be built from exactly n bricks. n will always be at least 3 (so you can have a staircase at all), but no more than 200, because Commander Lambda's not made of money! 285 | */ 286 | 287 | public static int grandestStaircase(int n) { 288 | Integer[][] stair = new Integer[n + 2][n + 2]; 289 | initStair(n + 2, stair); 290 | return staircaseHelper(1, n, stair) - 1; 291 | } 292 | 293 | private static void initStair(int n, Integer[][] stair) { 294 | for (int i = 0; i < n; i++) { 295 | for (int j = 0; j < n; j++) { 296 | stair[i][j] = 0; 297 | } 298 | } 299 | } 300 | 301 | private static int staircaseHelper(int i, int j, Integer[][] stair) { 302 | if (stair[i][j] != 0) { 303 | return stair[i][j]; 304 | } 305 | 306 | if (j == 0) { 307 | return 1; 308 | } 309 | 310 | if (j < i) { 311 | return 0; 312 | } 313 | 314 | stair[i][j] = staircaseHelper(i + 1, j - i, stair) + staircaseHelper(i + 1, j, stair); 315 | return stair[i][j]; 316 | } 317 | 318 | /* 319 | Find the Access Codes 320 | ===================== 321 | 322 | In order to destroy Commander Lambda's LAMBCHOP doomsday device, you'll need access to it. But the only door leading to 323 | the LAMBCHOP chamber is secured with a unique lock system whose number of passcodes changes daily. Commander Lambda gets 324 | a report every day that includes the locks' access codes, but only the Commander knows how to figure out which of 325 | several 326 | lists contains the access codes. You need to find a way to determine which list contains the access codes once you're 327 | ready to go in. 328 | 329 | Fortunately, now that you're Commander Lambda's personal assistant, Lambda has confided to you that all the access codes 330 | are "lucky triples" in order to make it easier to find them in the lists. A "lucky triple" is a tuple (x, y, z) where 331 | x divides y and y divides z, such as (1, 2, 4). With that information, you can figure out which list contains the 332 | number of access codes that matches the number of locks on the door when you're ready to go in (for example, if there's 333 | 5 passcodes, you'd need to find a list with 5 "lucky triple" access codes). 334 | 335 | Write a function solution(l) that takes a list of positive integers l and counts the number of "lucky triples" 336 | of (li, lj, lk) where the list indices meet the requirement i < j < k. The length of l is between 2 and 2000 inclusive. 337 | The elements of l are between 1 and 999999 inclusive. The solution fits within a signed 32-bit integer. Some of the 338 | lists are purposely generated without any access codes to throw off spies, so if no triples are found, return 0. 339 | 340 | For example, [1, 2, 3, 4, 5, 6] has the triples: [1, 2, 4], [1, 2, 6], [1, 3, 6], making the solution 3 total. 341 | */ 342 | 343 | public static int findAccessCode(int[] l) { 344 | int result = 0; 345 | int[] arr = new int[l.length]; 346 | 347 | for (int i = 1; i < l.length - 1; ++i) { 348 | for (int j = 0; j < i; ++j) { 349 | if (l[i] % l[j] == 0) { 350 | ++arr[i]; 351 | } 352 | } 353 | } 354 | 355 | for (int i = 2; i < l.length; i++) { 356 | for (int j = 1; j < i; ++j) { 357 | if (l[i] % l[j] == 0) { 358 | result += arr[j]; 359 | } 360 | } 361 | } 362 | 363 | return result; 364 | } 365 | 366 | /* 367 | Doomsday Fuel 368 | ============= 369 | 370 | Making fuel for the LAMBCHOP's reactor core is a tricky process because of the exotic matter involved. It starts as raw 371 | ore, then during processing, begins randomly changing between forms, eventually reaching a stable form. There may be 372 | multiple stable forms that a sample could ultimately reach, not all of which are useful as fuel. 373 | 374 | Commander Lambda has tasked you to help the scientists increase fuel creation efficiency by predicting the end state of 375 | a given ore sample. You have carefully studied the different structures that the ore can take and which transitions it 376 | undergoes. It appears that, while random, the probability of each structure transforming is fixed. That is, each time 377 | the ore is in 1 state, it has the same probabilities of entering the next state (which might be the same state). 378 | You have recorded the observed transitions in a matrix. The others in the lab have hypothesized more exotic forms that 379 | the ore can become, but you haven't seen all of them. 380 | 381 | Write a function solution(m) that takes an array of array of nonnegative ints representing how many times that state has 382 | gone to the next state and return an array of ints for each terminal state giving the exact probabilities of each 383 | terminal state, represented as the numerator for each state, then the denominator for all of them at the end and in 384 | simplest form. The matrix is at most 10 by 10. It is guaranteed that no matter which state the ore is in, there is a 385 | path from that state to a terminal state. That is, the processing will always eventually end in a stable state. 386 | The ore starts in state 0. The denominator will fit within a signed 32-bit integer during the calculation, as long as 387 | the fraction is simplified regularly. 388 | 389 | For example, consider the matrix m: 390 | [ 391 | [0,1,0,0,0,1], # s0, the initial state, goes to s1 and s5 with equal probability 392 | [4,0,0,3,2,0], # s1 can become s0, s3, or s4, but with different probabilities 393 | [0,0,0,0,0,0], # s2 is terminal, and unreachable (never observed in practice) 394 | [0,0,0,0,0,0], # s3 is terminal 395 | [0,0,0,0,0,0], # s4 is terminal 396 | [0,0,0,0,0,0], # s5 is terminal 397 | ] 398 | So, we can consider different paths to terminal states, such as: 399 | s0 -> s1 -> s3 400 | s0 -> s1 -> s0 -> s1 -> s0 -> s1 -> s4 401 | s0 -> s1 -> s0 -> s5 402 | Tracing the probabilities of each, we find that 403 | s2 has probability 0 404 | s3 has probability 3/14 405 | s4 has probability 1/7 406 | s5 has probability 9/14 407 | So, putting that together, and making a common denominator, gives an answer in the form of 408 | [s2.numerator, s3.numerator, s4.numerator, s5.numerator, denominator] which is 409 | [0, 3, 2, 9, 14]. 410 | 411 | refferences: https://github.com/ivanseed/google-foobar-help/blob/master/challenges/doomsday_fuel/doomsday_fuel.md 412 | */ 413 | 414 | private static int[] doomsDayFuel(int[][] m) { 415 | // Your code here 416 | double[][] mDouble = toDouble(m); 417 | // GOAL ONE: find Q matrix : 418 | // 1:seperate the input into two 2d arrays 419 | ArrayList ters = new ArrayList<>(); 420 | ArrayList nonTers = new ArrayList<>(); 421 | for (int i = 0; i < mDouble.length; i++) { 422 | boolean isTerminal = true; 423 | int sum = 0; 424 | for (int j = 0; j < mDouble[0].length; j++) { 425 | sum += mDouble[i][j]; 426 | if (mDouble[i][j] != 0) { 427 | isTerminal = false; 428 | } 429 | } 430 | 431 | if (isTerminal) { 432 | ters.add(mDouble[i]); 433 | } else { 434 | for (int j = 0; j < mDouble[0].length; j++) { 435 | mDouble[i][j] = mDouble[i][j] / sum; 436 | } 437 | nonTers.add(mDouble[i]); 438 | } 439 | } 440 | double[][] terminalStates = new double[ters.size()][m.length]; 441 | double[][] nonTerminalStates = new double[nonTers.size()][m.length]; 442 | 443 | for (int i = 0; i < ters.size(); i++) { 444 | terminalStates[i] = ters.get(i); 445 | } 446 | for (int i = 0; i < nonTers.size(); i++) { 447 | nonTerminalStates[i] = nonTers.get(i); 448 | } 449 | // 2: Plug into a function that will create the 2d array 450 | double[][] QMatrix = getQMatrix(nonTerminalStates); 451 | // GOAL TWO: find I matrix 452 | double[][] IMatrix = makeIMatrix(QMatrix.length); 453 | //GOAL 3: Find F matrix 454 | //1: subtract the q matrix from the I matrix 455 | double[][] AMatrix = subtractMatrices(IMatrix, QMatrix); 456 | //2: find the inverse TODO WRITE FUNCTION 457 | double[][] FMatrix = invert(AMatrix); 458 | //GOAL 4: multiply by R Matrix 459 | //1: find r Matrx 460 | double[][] RMatrix = getRMatrix(nonTerminalStates, terminalStates.length); 461 | //2: use multiply function to get FR Matrix 462 | double[][] FRMatrix = multiplyMatrices(FMatrix, RMatrix); 463 | //GOAL 5: find answer array 464 | //1: get the one dimensional answer 465 | double[] unsimplifiedAns = FRMatrix[0]; 466 | //2: get fractions for the answers 467 | return fractionAns(unsimplifiedAns); 468 | } 469 | 470 | private static int[] fractionAns(double[] uAns) { 471 | int[] ans = new int[uAns.length + 1]; 472 | int[] denominators = new int[uAns.length]; 473 | int[] numerators = new int[uAns.length]; 474 | for (int i = 0; i < uAns.length; i++) { 475 | denominators[i] = convertDecimalToFraction(uAns[i])[1]; 476 | numerators[i] = convertDecimalToFraction(uAns[i])[0]; 477 | } 478 | int lcm = (int) lcm_of_array_elements(denominators); 479 | for (int i = 0; i < uAns.length; i++) { 480 | ans[i] = numerators[i] * (lcm / convertDecimalToFraction(uAns[i])[1]); 481 | } 482 | ans[ans.length - 1] = lcm; 483 | return ans; 484 | } 485 | 486 | static private int[] convertDecimalToFraction(double x) { 487 | double tolerance = 1.0E-10; 488 | double h1 = 1; 489 | double h2 = 0; 490 | double k1 = 0; 491 | double k2 = 1; 492 | double b = x; 493 | do { 494 | double a = Math.floor(b); 495 | double aux = h1; 496 | h1 = a * h1 + h2; 497 | h2 = aux; 498 | aux = k1; 499 | k1 = a * k1 + k2; 500 | k2 = aux; 501 | b = 1 / (b - a); 502 | } while (Math.abs(x - h1 / k1) > x * tolerance); 503 | 504 | return new int[]{(int) h1, (int) k1}; 505 | } 506 | 507 | private static long lcm_of_array_elements(int[] element_array) { 508 | long lcm_of_array_elements = 1; 509 | int divisor = 2; 510 | 511 | while (true) { 512 | int counter = 0; 513 | boolean divisible = false; 514 | 515 | for (int i = 0; i < element_array.length; i++) { 516 | 517 | // lcm_of_array_elements (n1, n2, ... 0) = 0. 518 | // For negative number we convert into 519 | // positive and calculate lcm_of_array_elements. 520 | 521 | if (element_array[i] == 0) { 522 | return 0; 523 | } else if (element_array[i] < 0) { 524 | element_array[i] = element_array[i] * (-1); 525 | } 526 | if (element_array[i] == 1) { 527 | counter++; 528 | } 529 | 530 | // Divide element_array by devisor if complete 531 | // division i.e. without remainder then replace 532 | // number with quotient; used for find next factor 533 | if (element_array[i] % divisor == 0) { 534 | divisible = true; 535 | element_array[i] = element_array[i] / divisor; 536 | } 537 | } 538 | 539 | // If divisor able to completely divide any number 540 | // from array multiply with lcm_of_array_elements 541 | // and store into lcm_of_array_elements and continue 542 | // to same divisor for next factor finding. 543 | // else increment divisor 544 | if (divisible) { 545 | lcm_of_array_elements = lcm_of_array_elements * divisor; 546 | } else { 547 | divisor++; 548 | } 549 | 550 | // Check if all element_array is 1 indicate 551 | // we found all factors and terminate while loop. 552 | if (counter == element_array.length) { 553 | return lcm_of_array_elements; 554 | } 555 | } 556 | } 557 | 558 | private static double[][] toDouble(int[][] ma) { 559 | double[][] retArr = new double[ma.length][ma.length]; 560 | for (int i = 0; i < retArr.length; i++) { 561 | for (int j = 0; j < retArr[0].length; j++) { 562 | retArr[i][j] = (ma[i][j]); 563 | } 564 | } 565 | return retArr; 566 | } 567 | 568 | private static double[][] getRMatrix(double[][] nonTerminals, int terminalLength) { 569 | double[][] retArr = new double[nonTerminals.length][terminalLength]; 570 | for (int i = 0; i < retArr.length; i++) { 571 | if (nonTerminals[0].length - nonTerminals.length >= 0) 572 | System.arraycopy( 573 | nonTerminals[i], 574 | nonTerminals.length, 575 | retArr[i], 0, nonTerminals[0].length - nonTerminals.length); 576 | } 577 | return retArr; 578 | } 579 | 580 | private static double[][] multiplyMatrices(double[][] firstMatrix, double[][] secondMatrix) { 581 | int r1 = firstMatrix.length; 582 | int c1 = firstMatrix[0].length; 583 | int c2 = secondMatrix[0].length; 584 | double[][] product = new double[r1][c2]; 585 | for (int i = 0; i < r1; i++) { 586 | for (int j = 0; j < c2; j++) { 587 | for (int k = 0; k < c1; k++) { 588 | product[i][j] += firstMatrix[i][k] * secondMatrix[k][j]; 589 | } 590 | } 591 | } 592 | 593 | return product; 594 | } 595 | 596 | public static double[][] inverseMatrix(double[][] amatrix) { 597 | return null; 598 | } 599 | 600 | private static double[][] subtractMatrices(double[][] I, double[][] Q) { 601 | double[][] retArr = new double[I.length][I.length]; 602 | for (int i = 0; i < retArr.length; i++) { 603 | for (int j = 0; j < retArr.length; j++) { 604 | retArr[i][j] = I[i][j] - Q[i][j]; 605 | } 606 | } 607 | return retArr; 608 | } 609 | 610 | private static double[][] getQMatrix(double[][] qArr) { 611 | int size = qArr.length; 612 | double[][] retArr = new double[size][size]; 613 | for (int i = 0; i < size; i++) { 614 | System.arraycopy(qArr[i], 0, retArr[i], 0, size); 615 | } 616 | return retArr; 617 | } 618 | 619 | private static double[][] makeIMatrix(int size) { 620 | double[][] retArr = new double[size][size]; 621 | for (int i = 0; i < size; i++) { 622 | for (int j = 0; j < size; j++) { 623 | if (i == j) { 624 | retArr[i][j] = 1; 625 | } else { 626 | retArr[i][j] = 0; 627 | } 628 | } 629 | } 630 | return retArr; 631 | } 632 | 633 | private static double[][] invert(double[][] a) { 634 | int n = a.length; 635 | double[][] x = new double[n][n]; 636 | double[][] b = new double[n][n]; 637 | int[] index = new int[n]; 638 | for (int i = 0; i < n; ++i) 639 | b[i][i] = 1; 640 | 641 | // Transform the matrix into an upper triangle 642 | gaussian(a, index); 643 | 644 | // Update the matrix b[i][j] with the ratios stored 645 | for (int i = 0; i < n - 1; ++i) 646 | for (int j = i + 1; j < n; ++j) 647 | for (int k = 0; k < n; ++k) 648 | b[index[j]][k] 649 | -= a[index[j]][i] * b[index[i]][k]; 650 | 651 | // Perform backward substitutions 652 | for (int i = 0; i < n; ++i) { 653 | x[n - 1][i] = b[index[n - 1]][i] / a[index[n - 1]][n - 1]; 654 | for (int j = n - 2; j >= 0; --j) { 655 | x[j][i] = b[index[j]][i]; 656 | for (int k = j + 1; k < n; ++k) { 657 | x[j][i] -= a[index[j]][k] * x[k][i]; 658 | } 659 | x[j][i] /= a[index[j]][j]; 660 | } 661 | } 662 | return x; 663 | } 664 | 665 | // Method to carry out the partial-pivoting Gaussian 666 | // elimination. Here index[] stores pivoting order. 667 | 668 | private static void gaussian(double[][] a, int[] index) { 669 | int n = index.length; 670 | double[] c = new double[n]; 671 | 672 | // Initialize the index 673 | for (int i = 0; i < n; ++i) 674 | index[i] = i; 675 | 676 | // Find the rescaling factors, one from each row 677 | for (int i = 0; i < n; ++i) { 678 | double c1 = 0; 679 | for (int j = 0; j < n; ++j) { 680 | double c0 = Math.abs(a[i][j]); 681 | if (c0 > c1) c1 = c0; 682 | } 683 | c[i] = c1; 684 | } 685 | 686 | // Search the pivoting element from each column 687 | int k = 0; 688 | for (int j = 0; j < n - 1; ++j) { 689 | double pi1 = 0; 690 | for (int i = j; i < n; ++i) { 691 | double pi0 = Math.abs(a[index[i]][j]); 692 | pi0 /= c[index[i]]; 693 | if (pi0 > pi1) { 694 | pi1 = pi0; 695 | k = i; 696 | } 697 | } 698 | 699 | // Interchange rows according to the pivoting order 700 | int itmp = index[j]; 701 | index[j] = index[k]; 702 | index[k] = itmp; 703 | for (int i = j + 1; i < n; ++i) { 704 | double pj = a[index[i]][j] / a[index[j]][j]; 705 | 706 | // Record pivoting ratios below the diagonal 707 | a[index[i]][j] = pj; 708 | 709 | // Modify other elements accordingly 710 | for (int l = j + 1; l < n; ++l) 711 | a[index[i]][l] -= pj * a[index[j]][l]; 712 | } 713 | } 714 | } 715 | } 716 | -------------------------------------------------------------------------------- /src/main/kotlin/AccountMerger.kt: -------------------------------------------------------------------------------- 1 | fun main() { 2 | val accountMerger = AccountMerger() 3 | 4 | val input = listOf( 5 | listOf("John", "johnsmith@mail.com", "john_newyork@mail.com"), 6 | listOf("John", "johnsmith@mail.com", "john00@mail.com"), 7 | listOf("Mary", "mary@mail.com"), 8 | listOf("John", "johnnybravo@mail.com") 9 | ) 10 | 11 | val result = accountMerger.accountsMerge(input) 12 | println(result) 13 | } 14 | 15 | class AccountMerger { 16 | private val accMerger = mutableListOf>() 17 | private val listOfAccount = mutableListOf() 18 | 19 | fun accountsMerge(accounts: List>): List> { 20 | 21 | accounts.forEach { accountInternal -> 22 | populateAccountHolder(accountInternal).also { listOfAccount.add(it) } 23 | } 24 | 25 | for (idx in 1 until listOfAccount.size) { 26 | val left = listOfAccount[idx - 1] 27 | val right = listOfAccount[idx] 28 | if (isSimilarAtLeastOnce(left, right)) { 29 | val mergerAccount = mergeAccount(left, right) 30 | accMerger.add(mergerAccount) 31 | } else { 32 | val account = mutableListOf() 33 | account.add(0, right.name) 34 | right.emails.forEach { account.add(it) } 35 | 36 | accMerger.add(account) 37 | } 38 | } 39 | 40 | return accMerger 41 | } 42 | 43 | private fun isSimilarAtLeastOnce(accountHolder: AccountHolder, accountHolder2: AccountHolder): Boolean { 44 | if (accountHolder.name == accountHolder2.name) { 45 | accountHolder2.emails.forEachIndexed { _, email -> 46 | if (accountHolder.emails.contains(email)) { 47 | accountHolder2.emails.remove(email) 48 | return true 49 | } 50 | } 51 | } 52 | 53 | return false 54 | } 55 | 56 | private fun mergeAccount(accountHolder: AccountHolder, accountHolder2: AccountHolder): List { 57 | return mutableSetOf().apply { 58 | add(accountHolder.name) 59 | addAll(accountHolder2.emails) 60 | addAll(accountHolder.emails) 61 | }.toList() 62 | } 63 | 64 | private fun populateAccountHolder(accountInternal: List): AccountHolder { 65 | val emails = mutableSetOf() 66 | 67 | accountInternal.forEachIndexed { index, s -> 68 | if (index != 0) { 69 | emails.add(s) 70 | } 71 | } 72 | 73 | return AccountHolder(accountInternal[0], emails) 74 | } 75 | } 76 | 77 | 78 | /** 79 | * [ 80 | * ["John","johnsmith@mail.com","john_newyork@mail.com"], 81 | * ["John","johnsmith@mail.com","john00@mail.com"], 82 | * ["Mary","mary@mail.com"], 83 | * ["John","johnnybravo@mail.com"] 84 | * ] 85 | * 86 | * output: 87 | * [ 88 | * ["John","john00@mail.com","john_newyork@mail.com","johnsmith@mail.com"], 89 | * ["Mary","mary@mail.com"], 90 | * ["John","johnnybravo@mail.com"]] 91 | */ 92 | data class AccountHolder( 93 | val name: String, 94 | val emails: MutableSet 95 | ) -------------------------------------------------------------------------------- /src/main/kotlin/AssertMap.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * Given two maps in assertThat(map1, map2), write a function that can help the user with the comparison. The signature they gave was: 3 | * 4 | * ??? diff (Map left, Map right) 5 | * 6 | * ??? denotes any datastructure I would like to create/use. 7 | */ 8 | 9 | fun assertMap(map1: Map, map2: Map): Boolean { 10 | if (map1.size != map2.size) return false 11 | 12 | // loop to check each key. we can use any map1 or map 2 since both has same size 13 | for ((key, value) in map1) { 14 | if (!map2.containsKey(key)) { 15 | return false 16 | } 17 | 18 | if ((map2[key]?.equals(value)) == false) { 19 | return false 20 | } 21 | } 22 | 23 | // loop to each of value. the best case scenario is use primitive data type like Int, String, etc 24 | // then we need to check if it is a list. SO we can run the iterable or loop 25 | 26 | return true 27 | } 28 | 29 | fun assertMap2(map1: Map, map2: Map): Boolean { 30 | if (map1.size != map2.size) return false 31 | val set = mutableSetOf>() 32 | // loop to check each key. we can use any map1 or map 2 since both has same size 33 | for ((key, value) in map1) { 34 | set.add(key to value) 35 | } 36 | 37 | for ((key, value) in map2) { 38 | val pairs = key to value 39 | if (!set.contains(pairs)) { 40 | return false 41 | } 42 | } 43 | 44 | // loop to each of value. the best case scenario is use primitive data type like Int, String, etc 45 | // then we need to check if it is a list. SO we can run the iterable or loop 46 | 47 | return true 48 | } 49 | 50 | fun main() { 51 | 52 | val map1 = mutableMapOf( 53 | 1 to 1, 54 | 2 to 23 55 | ) 56 | 57 | val map2 = mutableMapOf( 58 | 1 to 1, 59 | 2 to 23 60 | ) 61 | 62 | println(assertMap2(map1, map2)) 63 | } -------------------------------------------------------------------------------- /src/main/kotlin/AuthenticationManager.kt: -------------------------------------------------------------------------------- 1 | class AuthenticationManager(private val timeToLive: Int) { 2 | private val authMap = mutableMapOf() 3 | 4 | fun generate(tokenId: String, currentTime: Int) { 5 | if (authMap.contains(tokenId)) return 6 | 7 | authMap[tokenId] = currentTime + timeToLive 8 | } 9 | 10 | fun renew(tokenId: String, currentTime: Int) { 11 | val expiredToken = authMap.getOrDefault(tokenId, currentTime) 12 | if (expiredToken < currentTime) { 13 | authMap.remove(tokenId) 14 | } else { 15 | authMap[tokenId] = currentTime + timeToLive 16 | } 17 | } 18 | 19 | fun countUnexpiredTokens(currentTime: Int): Int { 20 | val iterator = authMap.iterator() 21 | while (iterator.hasNext()) { 22 | val (token, time) = iterator.next() 23 | 24 | if (time <= currentTime) { 25 | iterator.remove() 26 | } 27 | } 28 | 29 | return authMap.size 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /src/main/kotlin/CollaborativePlaylist.kt: -------------------------------------------------------------------------------- 1 | import java.util.ArrayDeque 2 | 3 | class CollaborativePlaylist(private val playlists: List) { 4 | 5 | private val deque = ArrayDeque() 6 | 7 | init { 8 | initialize() 9 | } 10 | 11 | fun getNextSong(): Song? { 12 | if (hasNextSong()) { 13 | return deque.pop() 14 | } 15 | 16 | return null 17 | } 18 | 19 | fun hasNextSong(): Boolean { 20 | return deque.isNotEmpty() 21 | } 22 | 23 | private fun initialize() { 24 | var index = 0 25 | 26 | if (playlists.isEmpty()) return 27 | 28 | playlists.forEach { playlist -> 29 | 30 | } 31 | } 32 | } 33 | 34 | interface Playlist { 35 | fun nextSong(): Song? 36 | fun hasNextSong(): Boolean 37 | } 38 | 39 | data class Song(val name: String) 40 | 41 | /** 42 | * P1 = [a, b] 43 | * P2 = [c, d, e] 44 | * playlist = [a,c,b,d,e] 45 | */ -------------------------------------------------------------------------------- /src/main/kotlin/Converter.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Converter { 4 | int top = 9; 5 | int left = 9; 6 | int bottom = 9; 7 | int right = 9; 8 | int size = 10; 9 | ArrayList nums = new ArrayList(); 10 | 11 | 12 | private void solution() { 13 | for(int i = left; i <= right && nums.size() < size;i++ ) { 14 | 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/CountMatchers.kt: -------------------------------------------------------------------------------- 1 | class CountMatchers { 2 | fun countMatches(items: List>, ruleKey: String, ruleValue: String): Int { 3 | var count = 0 4 | 5 | val position = when (ruleKey) { 6 | "type" -> { 7 | 0 8 | } 9 | "color" -> { 10 | 1 11 | } 12 | else -> { 13 | 2 14 | } 15 | } 16 | 17 | items.forEach { items -> 18 | if (items[position] == ruleValue) { 19 | count++ 20 | } 21 | } 22 | 23 | return count 24 | } 25 | 26 | data class Item( 27 | val type: String, 28 | val color: String, 29 | val name: String 30 | ) 31 | } -------------------------------------------------------------------------------- /src/main/kotlin/DesignHashMap.kt: -------------------------------------------------------------------------------- 1 | class DesignHashMap { 2 | 3 | private val _map = mutableMapOf() 4 | 5 | fun put(key: Int, value: Int) { 6 | _map.put(key, value) 7 | } 8 | 9 | fun get(key: Int): Int { 10 | return _map[key] ?: -1 11 | } 12 | 13 | fun remove(key: Int) { 14 | _map.remove(key) 15 | } 16 | 17 | } 18 | 19 | /** 20 | * Your MyHashMap object will be instantiated and called as such: 21 | * var obj = MyHashMap() 22 | * obj.put(key,value) 23 | * var param_2 = obj.get(key) 24 | * obj.remove(key) 25 | */ 26 | 27 | fun main() { 28 | val hashMap = DesignHashMap() 29 | } -------------------------------------------------------------------------------- /src/main/kotlin/Explore.kt: -------------------------------------------------------------------------------- 1 | import java.util.* 2 | 3 | class Explore { 4 | fun deque() { 5 | val deque = ArrayDeque() 6 | } 7 | 8 | fun stackSample() { 9 | val stack = Stack() 10 | 11 | stack.peek() 12 | } 13 | 14 | fun exploreLinkedHashMap() { 15 | val map = LinkedHashMap() 16 | 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/kotlin/FindMedian.kt: -------------------------------------------------------------------------------- 1 | 2 | class MedianFinder() { 3 | 4 | /** initialize your data structure here. */ 5 | private val list = mutableListOf() 6 | 7 | fun addNum(num: Int) { 8 | list.add(num) 9 | } 10 | 11 | fun findMedian(): Double { 12 | 13 | val size = list.size 14 | return if (list.size % 2 != 0) { 15 | list[size / 2].toDouble() 16 | } else { 17 | (list[(size - 1) / 2] + list[size / 2]) / 2.0 18 | } 19 | } 20 | 21 | } 22 | 23 | fun main() { 24 | println(0/2) 25 | } -------------------------------------------------------------------------------- /src/main/kotlin/FreqStack.kt: -------------------------------------------------------------------------------- 1 | import java.util.* 2 | 3 | class FreqStack { 4 | private val frequencyMap = mutableMapOf() 5 | private val stackMap = mutableMapOf>() 6 | private var maxFreq = 0 7 | 8 | fun push(`val`: Int) { 9 | frequencyMap[`val`] = frequencyMap.getOrDefault(`val`, 0) + 1 10 | val currentFreq = frequencyMap.getOrDefault(`val`, 0) 11 | 12 | stackMap.computeIfAbsent(currentFreq) { mutableListOf() }.add(`val`) 13 | 14 | maxFreq = Math.max(maxFreq, currentFreq) 15 | } 16 | 17 | /** 18 | - get the value from the stack 19 | 20 | currentFreqNumber = stackMap.get(maxFreq).pop() // 5 21 | 22 | frequencyMap[currentFreqNumber] = frequencyMap.get(currentFreqNumber) - 1 23 | 24 | if stackMap[currentFreqNumber] is empty 25 | decrease the maxFreq 26 | 27 | return the currentFreqNumber 28 | */ 29 | fun pop(): Int { 30 | return 0 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/kotlin/Hasmap.kt: -------------------------------------------------------------------------------- 1 | class MyHashMap() { 2 | 3 | /** Initialize your data structure here. */ 4 | val list = mutableListOf>() 5 | 6 | 7 | /** value will always be non-negative. */ 8 | fun put(key: Int, value: Int) { 9 | if(isExist(key)) { 10 | val position = list.indexOfLast { it.first() == key } 11 | list[position][1] = value 12 | } else { 13 | list.add(mutableListOf(key, value)) 14 | } 15 | 16 | } 17 | 18 | /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */ 19 | fun get(key: Int): Int { 20 | val position = list.indexOfLast { it.first() == key } 21 | if (position != -1) { 22 | return list[position].last() 23 | } 24 | return 0 25 | } 26 | 27 | /** Removes the mapping of the specified value key if this map contains a mapping for the key */ 28 | fun remove(key: Int) { 29 | val position = list.indexOfLast { it.first() == key } 30 | list.removeAt(position) 31 | } 32 | 33 | private fun isExist(key: Int): Boolean { 34 | return list.find { it.first() == key } != null 35 | } 36 | } 37 | 38 | /** 39 | * Your MyHashMap object will be instantiated and called as such: 40 | * var obj = MyHashMap() 41 | * obj.put(key,value) 42 | * var param_2 = obj.get(key) 43 | * obj.remove(key) 44 | */ -------------------------------------------------------------------------------- /src/main/kotlin/InvertedBisection.kt: -------------------------------------------------------------------------------- 1 | 2 | 3 | fun main() { 4 | println(7/2) 5 | } 6 | 7 | fun invertedBisection(head: LinkedList): LinkedList { 8 | if (head.next == null) { 9 | return head 10 | } 11 | 12 | var odd = head 13 | var even = head.next 14 | val evenHead = even 15 | 16 | while (even?.next != null){ 17 | odd.next = even.next 18 | odd = odd.next!! 19 | even.next = odd.next 20 | even = even.next 21 | } 22 | odd = evenHead?.next!! 23 | return head 24 | } 25 | 26 | // This is an input class. Do not edit. 27 | open class LinkedList(value: Int) { 28 | var value = value 29 | var next: LinkedList? = null 30 | } 31 | -------------------------------------------------------------------------------- /src/main/kotlin/ListNode.kt: -------------------------------------------------------------------------------- 1 | class ListNode(var `val`: Int) { 2 | var next: ListNode? = null 3 | } -------------------------------------------------------------------------------- /src/main/kotlin/Main.kt: -------------------------------------------------------------------------------- 1 | import java.util.* 2 | import java.util.LinkedList 3 | import kotlin.math.min 4 | 5 | 6 | fun main() { 7 | val result = largestCountValue( 8 | intArrayOf(2,3,1) 9 | ) 10 | 11 | println(result) 12 | } 13 | 14 | /** 15 | * banking problem 3 16 | * 17 | * count the number of operation when merging number 18 | * 19 | */ 20 | fun largestCountValue(arr: IntArray): Int { 21 | // Create an auxiliary array to store the sorted array during merging 22 | val temp = IntArray(arr.size) 23 | // Create an array to count the number of times each element from the right is merged before the left 24 | val count = IntArray(arr.size) { 0 } 25 | 26 | // Recursive function for modified merge sort 27 | fun mergeSort(left: Int, right: Int) { 28 | if (left >= right) return 29 | 30 | val mid = left + (right - left) / 2 31 | // Sort the left half 32 | mergeSort(left, mid) 33 | // Sort the right half 34 | mergeSort(mid + 1, right) 35 | // Merge the two halves and update counts 36 | mergeHelper(temp, arr, count, left, mid, right) 37 | } 38 | 39 | 40 | 41 | // Start the merge sort 42 | mergeSort(0, arr.size - 1) 43 | 44 | // Return the maximum count value 45 | return count.max() ?: 0 46 | } 47 | 48 | // Function to merge two halves and count right-before-left merges 49 | fun mergeHelper(temp: IntArray, arr: IntArray, count: IntArray, left: Int, mid: Int, right: Int) { 50 | // Copy to temp array 51 | for (i in left..right) { 52 | temp[i] = arr[i] 53 | } 54 | 55 | var i = left // Pointer for the left half 56 | var j = mid + 1 // Pointer for the right half 57 | var k = left // Pointer for the final merged array 58 | 59 | while (i <= mid && j <= right) { 60 | if (temp[i] <= temp[j]) { 61 | // Element from the left half is smaller or equal, no counter update 62 | arr[k++] = temp[i++] 63 | } else { 64 | // Element from the right half is smaller, update the count 65 | arr[k++] = temp[j++] 66 | count[temp[j - 1]] += (mid - i + 1) // All remaining elements in left half are counted 67 | } 68 | } 69 | 70 | // Copy remaining elements from the left half 71 | while (i <= mid) { 72 | arr[k++] = temp[i++] 73 | } 74 | 75 | // Copy remaining elements from the right half 76 | while (j <= right) { 77 | arr[k++] = temp[j++] 78 | } 79 | } 80 | 81 | /** 82 | * banking problem 2 83 | * 84 | * Sorting name based on Name and Roman number 85 | * [Steven XL, Steven XXI, David IX, Andri III] 86 | * 87 | * return [Andri III, David IX, Steven XXI, Steven XL] 88 | */ 89 | fun sortRoman(names: List): List { 90 | val sortedName = mutableListOf() 91 | // simplest approach will be sort the names twice 92 | // first, sort based on name 93 | // second, sort based on roman number 94 | // give us flexibility to sort names 95 | // with comparator, it will be more faster O(n) -> n will be name 96 | 97 | return names.sortedWith(compareBy({ it.split(" ")[0] }, { romanToInt(it.split(" ")[1]) })) 98 | } 99 | 100 | /** 101 | * banking problem 1 102 | * 103 | * Count number which dont have repeating number, fox example 102, 89, 23 104 | */ 105 | fun countNumbers(numbers: List): Int { 106 | // naive solution using set to avoid duplication. 107 | // with this approach, the minimum time complexity O(MxN) M -> col, N -> row 108 | //optimize will be O(n.logn) 109 | val setNumber = mutableListOf() 110 | 111 | fun hasRepeatingDigits(num: Int): Boolean { 112 | var n = num 113 | val seenDigits = BooleanArray(10) 114 | 115 | while (n > 0) { 116 | val digit = n % 10 117 | if (seenDigits[digit]) { 118 | return true 119 | } 120 | seenDigits[digit] = true 121 | n /= 10 122 | } 123 | 124 | return false 125 | } 126 | 127 | numbers.forEach { arr -> 128 | arr.forEach { number -> 129 | if (!hasRepeatingDigits(number)) { 130 | setNumber.add(number) 131 | } 132 | } 133 | } 134 | 135 | return setNumber.size 136 | } 137 | 138 | fun lengthOfLastWord(s: String): Int { 139 | val word = s.trim().splitToSequence(' ') 140 | .filter { it.isNotEmpty() } 141 | .toList() 142 | 143 | return word.lastIndex 144 | } 145 | 146 | fun getPermutation(n: Int, k: Int): String { 147 | // StringBuilder to create the resulting permutation string 148 | var k = k 149 | val permutation = java.lang.StringBuilder() 150 | // Visited array keeps track of which numbers have been used 151 | val visited = BooleanArray(n + 1) 152 | 153 | 154 | // Loop through each position in the permutation 155 | for (i in 0 until n) { 156 | // Calculate the factorial of the numbers left 157 | var factorial = 1 158 | for (j in 1 until n - i) { 159 | factorial *= j 160 | } 161 | 162 | 163 | // Find the number to put in the current position 164 | for (j in 1..n) { 165 | if (!visited[j]) { 166 | // If the remaining permutations are more than k, 167 | // decrease k and find the next number 168 | if (k > factorial) { 169 | k -= factorial 170 | } else { 171 | // Add the number to the result and mark it as visited 172 | permutation.append(j) 173 | visited[j] = true 174 | break 175 | } 176 | } 177 | } 178 | } 179 | 180 | 181 | // Return the final permutation string 182 | return permutation.toString() 183 | } 184 | 185 | fun firstMissingPositive(nums: IntArray): Int { 186 | val maxNumber = nums.size * 2 187 | val numberOfMap = mutableMapOf() 188 | 189 | // populate possible number from 1 -> maxNumber 190 | for (i in 1 until maxNumber) { 191 | numberOfMap[i] = 1 //indicate that number is reserve 192 | } 193 | 194 | // loop through the nums parameter 195 | // check if the number is actually available in number of array 196 | for (number in nums) { 197 | if (numberOfMap[number] == 1) { 198 | numberOfMap.remove(number) 199 | } 200 | } 201 | 202 | return numberOfMap.keys.first() 203 | } 204 | 205 | fun countBlackBlocks(m: Int, n: Int, coordinates: Array): LongArray { 206 | val map: MutableMap = HashMap(coordinates.size) 207 | val directions = arrayOf(0, 0, -1, -1, 0) 208 | 209 | for (coordinate in coordinates) { 210 | val x = coordinate[0] 211 | val y = coordinate[1] 212 | 213 | for (i in 0 until 4) { 214 | val newXAxis = x + directions[i] 215 | val newYAxis = y + directions[i + 1] 216 | 217 | if (newXAxis >= 0 && newXAxis < m - 1 && newYAxis >= 0 && newXAxis < n - 1) { 218 | val index = 1L * newXAxis * n + newYAxis 219 | map.merge(index, 1, Integer::sum) 220 | } 221 | } 222 | } 223 | 224 | val result = LongArray(5) 225 | result[0] = ((m - 1) * (n - 1)).toLong() 226 | 227 | for (key in map.values) { 228 | result[key]++ 229 | result[0]-- 230 | } 231 | 232 | return result 233 | } 234 | 235 | fun splitMessage(message: String, limit: Int): List { 236 | val messageLength: Int = message.length // Length of the original message. 237 | var sumOfDigits = 0 // To keep track of the sum of the digits of all parts. 238 | 239 | 240 | // Initialize the array to hold the split message parts. 241 | var answer = arrayOfNulls(0) 242 | 243 | 244 | // Looping over the possible number of parts from 1 to messageLength. 245 | for (parts in 1..messageLength) { 246 | // Length of digits in the current part number. 247 | val lengthOfCurrentPartDigits = "$parts".length 248 | // Update the sum of the digits with current part number's digit length. 249 | sumOfDigits += lengthOfCurrentPartDigits 250 | 251 | 252 | // Total length consumed by the digit parts. 253 | val totalDigitsLength = lengthOfCurrentPartDigits * parts 254 | // Total length consumed by the delimiters "<" and "/>". 255 | val totalDelimiterLength = 3 * parts 256 | 257 | 258 | // Check if the current breakup fits into the limits. 259 | if (limit * parts - (sumOfDigits + totalDigitsLength + totalDelimiterLength) >= messageLength) { 260 | var currentIndex = 0 // Start index for the substring. 261 | answer = arrayOfNulls(parts) // Initialize the answer array with the number of parts. 262 | 263 | 264 | // Split the message into the determined number of parts. 265 | for (part in 1..parts) { 266 | // Generate the tail string for the current part. 267 | val tail = "<$part/$parts>" 268 | // Calculate the end index for the substring; it's either the end of the message or the max allowed by the limit, minus the length of the tail. 269 | val endIndex = min(messageLength, currentIndex + limit - tail.length) 270 | // Create the substring for the current part, add the tail, and store it in the answer array. 271 | val splitPart = message.substring(currentIndex, endIndex) + tail 272 | answer[part - 1] = splitPart 273 | // Update the start index for the next part. 274 | currentIndex += limit - tail.length 275 | } 276 | // Everything fitted perfectly, break out of the loop. 277 | break 278 | } 279 | } 280 | 281 | // Return the split message parts. 282 | return answer.filterNotNull().toList() 283 | } 284 | 285 | private fun splitPattern(index: Int, count: Int): String { 286 | return "<${index + 1}/$count>" 287 | } 288 | 289 | fun removeOccurrences(s: String, part: String): String { 290 | var first = 0 291 | var second = part.length 292 | val stringBuilder = StringBuilder(s) 293 | 294 | while (second <= stringBuilder.length) { 295 | val subs = stringBuilder.substring(first, second) 296 | 297 | if (subs == part) { 298 | stringBuilder.delete(first, second) 299 | //reset first index 300 | first = 0 301 | second = part.length 302 | continue 303 | } else { 304 | first++ 305 | second++ 306 | } 307 | } 308 | 309 | return stringBuilder.toString() 310 | } 311 | 312 | fun isOneEditDistance(word1: String, word2: String): Boolean { 313 | var countDif = 0 314 | 315 | for (i in word1.indices) { 316 | if (word1[i] != word2[i]) { 317 | countDif += 1 318 | 319 | if (countDif > 1) return false 320 | } 321 | } 322 | 323 | return true 324 | } 325 | 326 | fun minTotalDistance(grid: Array): Int { 327 | /** 328 | the approach here is to minimize calculation by row and column 329 | 330 | */ 331 | 332 | val rowCoordinate = mutableListOf() 333 | val colCoordinate = mutableListOf() 334 | 335 | grid.forEachIndexed { rowIndex, row -> 336 | row.forEachIndexed { colIndex, _ -> 337 | if (grid[rowIndex][colIndex] == 1) { 338 | rowCoordinate.add(rowIndex) 339 | colCoordinate.add(colIndex) 340 | } 341 | } 342 | } 343 | 344 | colCoordinate.sorted() 345 | 346 | val medianRow = rowCoordinate[rowCoordinate.size shr 1] 347 | val medianCol = colCoordinate[colCoordinate.size shr 1] 348 | 349 | return calculateDistance(rowCoordinate, medianRow) + calculateDistance(colCoordinate, medianCol) 350 | } 351 | 352 | private fun calculateDistance(list: List, median: Int): Int { 353 | var sum = 0 354 | 355 | for (point in list) { 356 | sum += Math.abs(point - median) 357 | } 358 | 359 | return sum 360 | } 361 | 362 | /** 363 | * Input: nums = [1,3,-1,-3,5,3,6,7], k = 3 364 | * Output: [3,3,5,5,6,7] 365 | * Explanation: 366 | * Window position Max 367 | * --------------- ----- 368 | * [1 3 -1] -3 5 3 6 7 3 369 | * 1 [3 -1 -3] 5 3 6 7 3 370 | * 1 3 [-1 -3 5] 3 6 7 5 371 | * 1 3 -1 [-3 5 3] 6 7 5 372 | * 1 3 -1 -3 [5 3 6] 7 6 373 | * 1 3 -1 -3 5 [3 6 7] 7 374 | */ 375 | fun maxSlidingWindow(nums: IntArray, k: Int): IntArray { 376 | val maxSliding = mutableListOf() 377 | 378 | if (nums.size == 1) return nums 379 | 380 | var left = 0 381 | var maxIdx = left + k - 1 382 | 383 | while (maxIdx < nums.size) { 384 | maxSliding.add( 385 | findMaxSlidingValue(nums, left, maxIdx) 386 | ) 387 | left++ 388 | } 389 | 390 | return maxSliding.toIntArray() 391 | } 392 | 393 | private fun findMaxSlidingValue(nums: IntArray, start: Int, end: Int): Int { 394 | var max = 0 395 | 396 | for (idx in start until end) { 397 | max = Math.max(max, nums[start]) 398 | } 399 | 400 | return max 401 | } 402 | 403 | fun minMutation(startGene: String, endGene: String, bank: Array): Int { 404 | if (startGene == endGene) return 0 405 | val mutationMap = mutableMapOf( 406 | 'A' to "TCG", 'T' to "ACG", 'C' to "ATG", 'G' to "ATC" 407 | ) 408 | 409 | val geneSet = mutableSetOf() 410 | geneSet.addAll(bank) 411 | 412 | // initialize deque to traverse all gene 413 | val deque = LinkedList>() 414 | deque.offer(startGene to 0) // add starting point 415 | 416 | while (deque.isNotEmpty()) { 417 | val current = deque.poll() 418 | val currentGene = current.first 419 | val currentStep = current.second 420 | 421 | if (endGene == currentGene) return currentStep // return every current gene and match with end gene 422 | 423 | //otherwise, traverse all possibility of gene mutation with current gene 424 | 425 | for (i in currentGene.indices) { 426 | 427 | //check all gene mutation from map 428 | for (mutation in mutationMap[currentGene[i]]?.toCharArray()!!) { 429 | 430 | //construct new mutation 431 | val mutated = currentGene.substring(0, i) + mutation + currentGene.substring(i + 1) 432 | 433 | if (geneSet.contains(mutated)) { 434 | deque.offer(mutated to currentStep + 1) 435 | geneSet.remove(mutated) 436 | } 437 | } 438 | } 439 | } 440 | 441 | return -1 442 | 443 | } 444 | 445 | fun lastRemaining(n: Int): Int { 446 | val list = mutableListOf() 447 | list.addAll(1..n) 448 | 449 | var shouldStartFromLeft = true 450 | 451 | while (list.size > 1) { 452 | if (!shouldStartFromLeft) { 453 | for (idx in list.lastIndex downTo 0 step 2) { 454 | if (idx >= 0) list.removeAt(idx) 455 | } 456 | } else { 457 | for (idx in 0 until list.size step 2) { 458 | list.removeAt(idx) 459 | } 460 | } 461 | 462 | println(list) 463 | shouldStartFromLeft = !shouldStartFromLeft 464 | } 465 | 466 | return list[0] 467 | } 468 | 469 | fun findTheDifference(s: String, t: String): Char { 470 | var sum = 0 471 | for (char in t) { 472 | sum += char.hashCode() 473 | } 474 | 475 | for (char in s) { 476 | sum -= char.hashCode() 477 | } 478 | 479 | return sum.toChar() 480 | } 481 | 482 | 483 | fun kthSmallest(matrix: Array, k: Int): Int { 484 | val heap = PriorityQueue> { a, b -> 485 | matrix[a[0]][a[1]].compareTo(matrix[b[0]][b[1]]) 486 | } 487 | 488 | //indicate initial index is 0,0 489 | heap.offer(listOf(0, 0)) 490 | 491 | var smallest = k 492 | 493 | val topColumn = IntArray(matrix.size) 494 | val firstRow = IntArray(matrix.size) 495 | 496 | while (smallest > 1) { 497 | smallest-- 498 | val result = heap.poll() 499 | 500 | val row = result[0] 501 | val col = result[1] 502 | 503 | firstRow[row] = col + 1 504 | 505 | if (col + 1 < matrix.size && topColumn[col + 1] == row) { 506 | heap.offer(listOf(row, col + 1)) 507 | } 508 | 509 | topColumn[col] = row + 1 510 | 511 | if (row + 1 < matrix.size && firstRow[row + 1] == col) { 512 | heap.offer(listOf(row + 1, col)) 513 | } 514 | } 515 | 516 | val result = heap.poll() 517 | return matrix[result[0]][result[1]] 518 | } 519 | 520 | fun topKFrequentInt(nums: IntArray, k: Int): IntArray { 521 | val map = nums.toList().groupingBy { it }.eachCount().entries.sortedBy { it.value } 522 | //grouping and count similar number 1 to 2, 2 to 1, 3 to 3 523 | 524 | val result = mutableListOf() 525 | map.forEach { (key, value) -> 526 | result.add(key) 527 | } 528 | 529 | return result.takeLast(k).toIntArray() 530 | } 531 | 532 | fun maskPII(s: String): String { 533 | val lowercaseText = s.toLowerCase() 534 | return if (isEmailFormat(s)) { 535 | buildString { 536 | append(lowercaseText[0]) 537 | append("*****") 538 | append(lowercaseText.substring(lowercaseText.indexOf('@') - 1, lowercaseText.length)) 539 | } 540 | } else if (isPhoneNumberFormat(s)) { 541 | "" 542 | } else { 543 | "" 544 | } 545 | } 546 | 547 | private fun isEmailFormat(s: String): Boolean { 548 | return s[0].isLetter() 549 | } 550 | 551 | private fun isPhoneNumberFormat(s: String): Boolean { 552 | return s[0].isDigit() 553 | } 554 | 555 | private fun maskEmail(email: String, builder: StringBuilder): String { 556 | val emailLower = email.toLowerCase() 557 | 558 | val annotationIndex = emailLower.indexOf("@") 559 | 560 | builder.append(emailLower.first()) 561 | builder.append("*****") 562 | builder.append(emailLower.substring(annotationIndex - 1)) 563 | 564 | return builder.toString() 565 | } 566 | 567 | private fun maskPhoneNumber(phoneNumber: String, builder: StringBuilder): String { 568 | 569 | for (number in phoneNumber) { 570 | if (Character.isDigit(number)) { 571 | builder.append(number) 572 | } 573 | } 574 | 575 | // check whether there is a international code number from the string 576 | val internationalNumber = builder.length - 10 577 | 578 | val maskingNumber = "***-***-${builder.substring(builder.length - 4)}" 579 | if (internationalNumber == 0) { 580 | return maskingNumber 581 | } else { 582 | var prefixNumber = "+" 583 | for (count in 0 until internationalNumber) { 584 | prefixNumber += "*" 585 | } 586 | 587 | return "$prefixNumber-$maskingNumber" 588 | } 589 | } 590 | 591 | private fun chunkKeyFromEnd(key: String, k: Int): List { 592 | var temp = key 593 | //25G3J 594 | val stack = ArrayDeque() 595 | val lastSubstringIdx = key.length - 1 596 | 597 | for (lastIdx in lastSubstringIdx downTo k) { 598 | if (temp.length < k) break 599 | val subs = key.substring(lastIdx - k, lastIdx) 600 | println("subs -> $subs from temp $temp") 601 | temp = temp.removeRange(lastIdx - k, lastIdx) 602 | stack.add(subs) 603 | println(temp) 604 | } 605 | 606 | if (temp.isNotEmpty()) { 607 | stack.add(temp) 608 | } 609 | 610 | return stack.toList().reversed() 611 | } 612 | 613 | fun removeKdigits(num: String, k: Int): String { 614 | if (num.length < k) return "0" 615 | 616 | var min = 0 617 | var lastIndex = num.length - 1 618 | 619 | for (idx in num.indices) { 620 | val removedNumber = num.removeRange(idx, idx) 621 | } 622 | 623 | return "$min" 624 | } 625 | 626 | fun wordBreak(s: String, wordDict: List?): Boolean { 627 | val wordDictSet: Set = HashSet(wordDict) 628 | val dp = BooleanArray(s.length + 1) 629 | dp[0] = true 630 | for (i in 1..s.length) { 631 | for (j in 0 until i) { 632 | if (dp[j] && wordDictSet.contains(s.substring(j, i))) { 633 | dp[i] = true 634 | break 635 | } 636 | } 637 | } 638 | return dp[s.length] 639 | } 640 | 641 | fun minDeletions(s: String): Int { 642 | var counter = 0 643 | val map = mutableMapOf() 644 | 645 | for (char in s) { 646 | map[char] = map.getOrDefault(char, 0) + 1 647 | } 648 | 649 | map.forEach { t, u -> 650 | println("before: $t $u") 651 | } 652 | 653 | map.toSortedMap() 654 | val seen = hashSetOf() 655 | 656 | for ((key, value) in map) { 657 | println("$key $value") 658 | if (seen.contains(key)) { 659 | map[key] = value - 1 660 | counter++ 661 | } else { 662 | seen.add(key) 663 | } 664 | } 665 | 666 | return counter 667 | } 668 | 669 | fun mergeKLists(lists: Array): ListNode? { 670 | val heap = PriorityQueue() 671 | 672 | for (node in lists) { 673 | var head = node 674 | while (head != null) { 675 | heap.add(head.`val`) 676 | head = head.next 677 | } 678 | } 679 | 680 | var dummy = ListNode(0) 681 | var head = dummy 682 | 683 | while (!heap.isEmpty()) { 684 | val nextNode = ListNode(heap.remove()) 685 | head.next = nextNode 686 | } 687 | 688 | return dummy.next 689 | } 690 | 691 | fun earliestAcq(logs: Array, n: Int): Int { 692 | val list = IntArray(2) 693 | Arrays.sort(logs) { a: IntArray, b: IntArray -> a[0] - b[0] } 694 | val groups = hashSetOf()/* 695 | [20190101,0,1], 696 | [20190104,3,4], 697 | [20190107,2,3], 698 | [20190211,1,5], 699 | [20190224,2,4], 700 | [20190301,0,3], 701 | [20190312,1,2], 702 | [20190322,4,5] 703 | 704 | n=6 705 | */ 706 | var earlyTime = -1 707 | for (log in logs) { 708 | mutableListOf().apply { 709 | add(log[1]) 710 | add(log[2]) 711 | }.let { 712 | if (groups.addAll(it)) { 713 | earlyTime = log[0] 714 | } 715 | } 716 | } 717 | 718 | return earlyTime 719 | } 720 | 721 | fun longestCommonSubsequence(text1: String, text2: String): Int { 722 | val list = mutableListOf() 723 | var longest = 0 724 | return lcsHelper(0, 0, text1, text2, longest) 725 | } 726 | 727 | fun lcsHelper(i: Int, j: Int, str1: String, str2: String, count: Int): Int { 728 | return if (str1[i].isWhitespace() || str2[j].isWhitespace()) { 729 | count 730 | } else if (str1[i] == str2[j]) { 731 | 1 + lcsHelper(i + 1, j + 1, str1, str2, count) 732 | } else { 733 | Math.max( 734 | lcsHelper(i + 1, j, str1, str2, count), lcsHelper(i, j + 1, str1, str2, count) 735 | ) 736 | } 737 | } 738 | 739 | fun countPoints(rings: String): Int { 740 | val red = BooleanArray(10) 741 | val green = BooleanArray(10) 742 | val blue = BooleanArray(10) 743 | var count = 0 744 | 745 | for (i in 1 until rings.length step 2) { 746 | val color = rings[i - 1] 747 | val position = rings[i].toString().toInt() 748 | when (color) { 749 | 'R' -> { 750 | red[position] = true 751 | } 752 | 753 | 'G' -> { 754 | green[position] = true 755 | } 756 | 757 | 'B' -> { 758 | blue[position] = true 759 | } 760 | } 761 | } 762 | 763 | for (i in 0 until red.size) { 764 | if (red[i] && green[i] && blue[i]) { 765 | count++ 766 | } 767 | } 768 | 769 | return count 770 | } 771 | 772 | fun reverseKGroup(head: ListNode?, k: Int): ListNode? { 773 | val list = mutableListOf() 774 | 775 | var groups = head 776 | while (groups != null) { 777 | list.add(groups) 778 | groups = groups.next 779 | } 780 | 781 | for (i in 0 until list.size) { 782 | if (i / k == 0) { 783 | list.slice(i..10).reversed() 784 | } 785 | println(list[i]) 786 | } 787 | 788 | return head 789 | } 790 | 791 | fun reverse(list: MutableList, i: Int, j: Int) { 792 | list.slice(i..j) 793 | } 794 | 795 | /* 796 | Pick a starting point. 797 | while(Problem is not solved) 798 | For each path from the starting point. 799 | check if selected path is safe, if yes select it 800 | and make recursive call to rest of the problem 801 | before which undo the current move. 802 | End For 803 | If none of the move works out, return false, NO SOLUTON. 804 | */ 805 | fun subsets(nums: IntArray): List> { 806 | val result = mutableListOf>() 807 | backtracking(nums, result, 0, mutableListOf()) 808 | 809 | return result 810 | } 811 | 812 | 813 | private fun backtracking(nums: IntArray, res: MutableList>, indx: Int, subList: MutableList) { 814 | 815 | // base case 816 | if (subList.size <= nums.size) { 817 | val candidate = subList.toMutableList() 818 | candidate.sort() // sorting is needed here because it should not contain the duplicate number in the sublist aka candidate 819 | if (!res.contains(candidate)) { 820 | res.add(candidate) // if it is suitable just add it to the result list 821 | } 822 | } 823 | 824 | for (i in indx until nums.size) if (!subList.contains(nums[i])) { // this if statement is needed to prevent using the same numbers again and again 825 | subList.add(nums[i]) 826 | backtracking(nums, res, indx + 1, subList) 827 | subList.removeAt(subList.size - 1) // we need to pop up the element back since the next iteration will contain different combination 828 | } 829 | } 830 | 831 | fun decodeString(s: String): String { 832 | val numberStack = Stack() 833 | val stringStack = Stack() 834 | var number = 0 // to keep track the number in case has more than 10 835 | var builder = StringBuilder() 836 | 837 | for (i in 0 until s.length) { 838 | val input = s.get(i) 839 | 840 | if (input.isDigit()) { 841 | number = number * 10 + (input - '0') 842 | } else if (input.isLetter()) { 843 | builder.append(input) 844 | } else if (input == '[') { 845 | numberStack.add(number) 846 | stringStack.add(builder.toString()) 847 | 848 | number = 0 849 | builder = StringBuilder() 850 | } else { 851 | val count = numberStack.pop() 852 | val duplicateWord = StringBuilder(stringStack.pop()) 853 | 854 | var idx = 1 855 | while (idx <= count) { 856 | duplicateWord.append(stringStack) 857 | idx++ 858 | } 859 | builder = duplicateWord 860 | } 861 | } 862 | 863 | return builder.toString() 864 | } 865 | 866 | fun subsetsWithDup(nums: IntArray): List> { 867 | val subs = mutableListOf>() 868 | 869 | 870 | 871 | return subs 872 | } 873 | 874 | fun bulbSwitch(n: Int): Int { 875 | val list = mutableListOf() 876 | initBuild(n, list) 877 | var counter = list.size 878 | 879 | for (i in 1 until n) { 880 | list[i] = false 881 | counter-- 882 | } 883 | 884 | return counter 885 | } 886 | 887 | private fun initBuild(size: Int, list: MutableList) { 888 | for (i in 0 until size) { 889 | list.add(true) 890 | } 891 | } 892 | 893 | fun medianSlidingWindow(nums: IntArray, k: Int): DoubleArray {/* 894 | Input: nums = [1,3,-1,-3,5,3,6,7], k = 3 895 | Output: [1.00000,-1.00000,-1.00000,3.00000,5.00000,6.00000] 896 | Explanation: 897 | Window position Median 898 | --------------- ----- 899 | [1 3 -1] -3 5 3 6 7 1 900 | 1 [3 -1 -3] 5 3 6 7 -1 901 | 1 3 [-1 -3 5] 3 6 7 -1 902 | 1 3 -1 [-3 5 3] 6 7 3 903 | 1 3 -1 -3 [5 3 6] 7 5 904 | 1 3 -1 -3 5 [3 6 7] 6 905 | */ 906 | val medians = mutableListOf() 907 | val queue = PriorityQueue() 908 | var first = 0 909 | var second = k - 1 910 | 911 | while (second < nums.size) { 912 | queue.addAll(nums.slice(first..second)) 913 | medians.add(findMedianNumber(queue.toList())) 914 | first++ 915 | second++ 916 | queue.clear() 917 | } 918 | 919 | return medians.toDoubleArray() 920 | } 921 | 922 | private fun findMedianNumber(number: List): Double { 923 | return if (number.size % 2 == 0) { 924 | ((number[number.size / 2] + number[number.size / 2 - 1]) / 2).toDouble() 925 | } else { 926 | number[number.size / 2].toDouble() 927 | } 928 | } 929 | 930 | fun removeNthFromEnd(head: ListNode?, n: Int): ListNode? { 931 | var size = 0 932 | var temp = ListNode(0) 933 | temp.next = head 934 | var first = temp 935 | var second = temp 936 | 937 | return head 938 | } 939 | 940 | fun lengthOfLongestSubstringV2(s: String): Int { 941 | var first = 0 942 | var second = 0 943 | var maxLength = 0 944 | val nonRepeating = hashSetOf() 945 | 946 | while (second < s.length) { 947 | if (nonRepeating.contains(s[second]).not()) { 948 | nonRepeating.add(s[second]) 949 | maxLength = Math.max(nonRepeating.size, maxLength) 950 | second++ 951 | } else { 952 | nonRepeating.remove(s[first]) 953 | first++ 954 | } 955 | } 956 | 957 | 958 | return maxLength 959 | } 960 | 961 | fun longestPalindrome(s: String): String { 962 | var first = 0 963 | var second = 0 964 | 965 | for (i in 0 until s.length) { 966 | val firstScan = scanText(s, i, i) 967 | val secondScan = scanText(s, i, i + 1) 968 | val longest = Math.max(firstScan, secondScan) 969 | 970 | if (longest > second - first) { 971 | first = i - (longest - 1) / 2 972 | second = i + longest / 2 973 | } 974 | } 975 | 976 | return s.substring(first, second + 1) 977 | } 978 | 979 | private fun scanText(s: String, first: Int, last: Int): Int { 980 | var left = first 981 | var right = last 982 | if (s.isEmpty() || left < 0 || right > s.length) { 983 | return 0 984 | } 985 | 986 | while (s.isNotEmpty() || left > 0 || right <= s.length || s[left] == s[right]) { 987 | left-- 988 | right++ 989 | } 990 | 991 | return right - left - 1 992 | } 993 | 994 | fun isLongestPalindrome(origin: String): Boolean { 995 | return origin == origin.reversed() 996 | } 997 | 998 | fun mergeTwoLists(list1: ListNode?, list2: ListNode?): ListNode? { 999 | val first = mutableListOf() 1000 | val second = mutableListOf() 1001 | 1002 | var firstNode = list1 1003 | while (firstNode?.next != null) { 1004 | first.add(firstNode.`val`) 1005 | firstNode = firstNode.next 1006 | } 1007 | 1008 | var secondNode = list2 1009 | while (secondNode?.next != null) { 1010 | second.add(secondNode.`val`) 1011 | secondNode = secondNode.next 1012 | } 1013 | 1014 | val merged = first.zip(second) 1015 | 1016 | var populateLinkedlist: ListNode? = null 1017 | 1018 | for (node in merged) { 1019 | val current = ListNode(node.first) 1020 | populateLinkedlist?.next = current 1021 | populateLinkedlist?.next?.next = ListNode(node.second) 1022 | } 1023 | 1024 | return populateLinkedlist 1025 | } 1026 | 1027 | fun maxRepeatedChar(word: String, max: Int): String {/* 1028 | given a string of consecutive repeated characters and max value, 1029 | return another string of max repeated characters : for ex: aaaaabbbbbcccdd and max is 2 should be aabbccdd 1030 | */ 1031 | val mapWord = mutableMapOf() 1032 | val builder = StringBuilder() 1033 | 1034 | for (char in word) { 1035 | mapWord[char] = mapWord.getOrDefault(char, 0) + 1 1036 | } 1037 | 1038 | for ((key, value) in mapWord) { 1039 | if (value > max) { 1040 | val repeatedWord = key.toString().repeat(max) 1041 | builder.append(repeatedWord) 1042 | } else { 1043 | val repeatedWord = key.toString().repeat(value) 1044 | builder.append(repeatedWord) 1045 | } 1046 | } 1047 | 1048 | return builder.toString() 1049 | } 1050 | 1051 | fun mostVisitedPattern(username: Array, timestamp: IntArray, website: Array): List { 1052 | val map = mutableMapOf>() // map name to map of timestamp and website only 1053 | 1054 | for (i in 0 until timestamp.size) { 1055 | if (!map.containsKey(username[i])) { 1056 | map.putIfAbsent(username[i], TreeMap()) 1057 | } 1058 | val treeMap = map.getOrDefault(username[i], TreeMap()) 1059 | treeMap[timestamp[i]] = website[i] 1060 | map[username[i]] = treeMap 1061 | } 1062 | 1063 | 1064 | 1065 | return listOf() 1066 | } 1067 | 1068 | fun intersect(nums1: IntArray, nums2: IntArray): IntArray { 1069 | return nums1.intersect(nums2.toList()).toIntArray() 1070 | } 1071 | 1072 | fun isLongPressedName(name: String, typed: String): Boolean { 1073 | var counter = name.length 1074 | val builder = StringBuilder(typed) 1075 | 1076 | for (i in 0 until name.length) { 1077 | if (typed.contains(name[i])) { 1078 | val idx = builder.indexOf(name[i]) 1079 | if (idx != -1) { 1080 | builder.deleteCharAt(idx) 1081 | counter-- 1082 | } 1083 | } 1084 | } 1085 | 1086 | return counter == 0 1087 | } 1088 | 1089 | fun anagramMappings(nums1: IntArray, nums2: IntArray): IntArray {/* 1090 | Input: nums1 = [12,28,46,32,50], nums2 = [50,12,32,46,28] 1091 | Output: [1,4,3,2,0] 1092 | Explanation: As mapping[0] = 1 because the 0th element of nums1 appears at nums2[1], and mapping[1] = 4 1093 | because the 1st element of nums1 appears at nums2[4], and so on. 1094 | */ 1095 | val result = mutableListOf() 1096 | 1097 | for (i in 0 until nums1.size) { 1098 | if (nums2.contains(nums1[i])) { 1099 | val idx = nums2.indexOf(nums1[i]) 1100 | result.add(idx) 1101 | } 1102 | } 1103 | 1104 | return result.toIntArray() 1105 | } 1106 | 1107 | fun rangeSumBST(root: TreeNode?, low: Int, high: Int): Int { 1108 | var current = 0 1109 | helperRangeSumBST(root, low, high, current) 1110 | return current 1111 | } 1112 | 1113 | private fun helperRangeSumBST(root: TreeNode?, low: Int, high: Int, current: Int): Int { 1114 | if (root != null) { 1115 | if (isWithinRange(low, high, root.`val`)) { 1116 | return current + root.`val` 1117 | } 1118 | helperRangeSumBST(root.left, low, high, current) 1119 | helperRangeSumBST(root.right, low, high, current) 1120 | } 1121 | 1122 | return current 1123 | } 1124 | 1125 | private fun isWithinRange(low: Int, high: Int, target: Int): Boolean { 1126 | return target in low..high 1127 | } 1128 | 1129 | fun removeDuplicates(s: String, k: Int): String {/* 1130 | Input: s = "deeedbbcccbdaa", k = 3 1131 | Output: "aa" 1132 | Explanation: 1133 | First delete "eee" and "ccc", get "ddbbbdaa" 1134 | Then delete "bbb", get "dddaa" 1135 | Finally delete "ddd", get "aa" 1136 | */ 1137 | val builder = StringBuilder(s) 1138 | val memo = IntArray(builder.length) 1139 | var first = 0 1140 | 1141 | while (first != builder.length) { 1142 | if (first == 0 || builder[first] !== builder[first - 1]) { 1143 | memo[first] = 1 1144 | } else { 1145 | memo[first] = memo[first - 1] + 1 1146 | if (memo[first] == k) { 1147 | builder.delete(first - k + 1, first + 1) 1148 | first -= k 1149 | } 1150 | } 1151 | 1152 | first++ 1153 | } 1154 | 1155 | 1156 | return builder.toString() 1157 | } 1158 | 1159 | fun longestConsecutive(nums: IntArray): Int { 1160 | 1161 | /* 1162 | Input: nums = [100,4,200,1,3,2] 1163 | Output: 4 1164 | Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4. 1165 | */ 1166 | nums.sort() 1167 | var counter = 1 1168 | var longest = 1 1169 | 1170 | for (i in 1 until nums.size) { 1171 | if (nums[i] != nums[i - 1]) { 1172 | val remain = nums[i] - nums[i - 1] 1173 | if (remain == 1) { 1174 | counter++ 1175 | } else { 1176 | longest = Math.max(longest, counter) 1177 | counter = 1 1178 | } 1179 | } 1180 | } 1181 | 1182 | return Math.max(longest, counter) 1183 | } 1184 | 1185 | fun wallsAndGates(rooms: Array): Unit {/* 1186 | Input: rooms = [ 1187 | [2147483647, -1, 0, 2147483647], 1188 | [2147483647, 2147483647, 2147483647, -1], 1189 | [2147483647, -1, 2147483647, -1], 1190 | [0, -1, 2147483647, 2147483647]] 1191 | 1192 | Output: [ 1193 | [3, -1, 0, 1], 1194 | [2, 2, 1, -1], 1195 | [1, -1, 2, -1], 1196 | [0, -1, 3, 4]] 1197 | */ 1198 | 1199 | 1200 | } 1201 | 1202 | private fun wallsAndGatesDfs(rooms: Array) { 1203 | 1204 | } 1205 | 1206 | fun findAnagrams(s: String, p: String): List { 1207 | val sorted = p.toCharArray().sorted().joinToString("") 1208 | 1209 | var first = 0 1210 | val indexs = mutableListOf() 1211 | 1212 | while (first < s.length) { 1213 | var second = first + 1 1214 | 1215 | while (second <= s.length) { 1216 | if (isFindAnagramValid(sorted, s.substring(first until second))) { 1217 | indexs.add(first) 1218 | } 1219 | 1220 | second++ 1221 | } 1222 | 1223 | first++ 1224 | } 1225 | 1226 | return indexs 1227 | } 1228 | 1229 | private fun isFindAnagramValid(str1: String, str2: String): Boolean { 1230 | return str1 == str2.toCharArray().sorted().joinToString("") 1231 | } 1232 | 1233 | fun groupAnagrams(strs: Array): List> {/* 1234 | Input: strs = ["eat","tea","tan","ate","nat","bat"] 1235 | Output: [["bat"],["nat","tan"],["ate","eat","tea"]] 1236 | */ 1237 | val groups = mutableMapOf>() 1238 | val result = mutableListOf>() 1239 | strs.sorted() 1240 | 1241 | for (word in strs) { 1242 | val sorted = sortedWord(word) 1243 | 1244 | if (!groups.containsKey(sorted)) { 1245 | groups[sorted] = groups.getOrDefault(sorted, mutableListOf()) 1246 | } 1247 | 1248 | groups[sorted]?.add(word) 1249 | } 1250 | 1251 | for ((key, value) in groups) { 1252 | result.add(value) 1253 | } 1254 | 1255 | return result.reversed() 1256 | } 1257 | 1258 | private fun sortedWord(str: String): String { 1259 | return str.toCharArray().sorted().joinToString("") 1260 | } 1261 | 1262 | fun lengthOfLongestSubstring(s: String): Int { 1263 | var current = "" 1264 | var maxChar = 0 1265 | var first = 0 1266 | var second = first + 1 1267 | 1268 | while (first < s.length) { 1269 | while (second < s.length) { 1270 | val subs = s.subSequence(first, second) 1271 | if (!hasRepeatingChar(subs.toString())) { 1272 | current = subs.toString() 1273 | maxChar = Math.max(subs.length, maxChar) 1274 | } 1275 | second++ 1276 | } 1277 | first++ 1278 | } 1279 | 1280 | return maxChar 1281 | } 1282 | 1283 | private fun hasRepeatingChar(s: String): Boolean { 1284 | val hashSet = hashSetOf() 1285 | 1286 | for (char in s) { 1287 | if (hashSet.add(char).not()) { 1288 | return true 1289 | } 1290 | } 1291 | 1292 | return false 1293 | } 1294 | 1295 | fun balanceBracket(bracket: String): Boolean {/* 1296 | Write a function to check that a String is parenthetically balanced. 1297 | For example: 1298 | - "(bar)" - balanced 1299 | - "(()" - not balanced 1300 | - "(())(()" - not balanced 1301 | 1302 | Given a string, which contains '(' and ')' and some other characters, 1303 | verify if it is a valid parantheses. It will not contains '{' or '['. 1304 | */ 1305 | 1306 | var counter = 0 1307 | 1308 | for (char in bracket) { 1309 | if (char == '(') { 1310 | counter++ 1311 | } else if (char == ')') { 1312 | counter-- 1313 | } 1314 | } 1315 | 1316 | return counter == 0 1317 | } 1318 | 1319 | fun findMissingRanges(nums: IntArray, lower: Int, upper: Int): List { 1320 | val result = mutableListOf() 1321 | val list = mutableListOf() 1322 | 1323 | for (i in lower until upper) { 1324 | list.add(i) 1325 | } 1326 | 1327 | for (i in 0 until nums.size) { 1328 | // if (nums[i + 1] - nums[i] > 2) { 1329 | // val lowerRange = nums[i] + 1 1330 | // val topRange = nums[i + 1] - 1 1331 | // 1332 | // if (lowerRange == topRange) { 1333 | // result.add("$lowerRange") 1334 | // } else { 1335 | // result.add("$lowerRange->$topRange") 1336 | // } 1337 | // } 1338 | 1339 | } 1340 | 1341 | return result 1342 | } 1343 | 1344 | fun matrixBlockSum(mat: Array, k: Int): Array { 1345 | val result = mutableListOf() 1346 | 1347 | for (block in mat) { 1348 | 1349 | } 1350 | 1351 | return arrayOf(result.toIntArray()) 1352 | } 1353 | 1354 | fun addToArrayForm(num: IntArray, k: Int): List { 1355 | val result = mutableListOf() 1356 | val convertedNumber = convertListToInt(num) + k 1357 | return result.toList() 1358 | } 1359 | 1360 | private fun convertIntToList(number: Int, result: MutableList) { 1361 | val numberInString = "$number" 1362 | numberInString.forEach { 1363 | result.add(Integer.parseInt(it.toString())) 1364 | } 1365 | } 1366 | 1367 | private fun convertListToInt(nums: IntArray): Int { 1368 | val size = nums.size - 1 1369 | var result = 0 1370 | var multiply = Math.pow(10 * 1.0, size * 1.0).toInt() 1371 | 1372 | for (number in nums) { 1373 | val current = number * multiply 1374 | result += current 1375 | multiply /= 10 1376 | } 1377 | 1378 | var numberInString = "" 1379 | nums.forEach { 1380 | numberInString += it 1381 | } 1382 | return numberInString.toBigInteger().toInt() 1383 | } 1384 | 1385 | fun arrayRankTransform(arr: IntArray): IntArray { 1386 | val tranform = arr.toMutableSet().sorted() 1387 | val result = mutableListOf() 1388 | 1389 | for (i in 0 until arr.size) { 1390 | val idx = tranform.indexOf(arr[i]) + 1 1391 | result.add(idx) 1392 | } 1393 | 1394 | return result.toIntArray() 1395 | } 1396 | 1397 | fun findPeakElement(nums: IntArray): Int { 1398 | val peekNumber = nums.max() ?: 0 1399 | return nums.indexOf(peekNumber) 1400 | } 1401 | 1402 | fun findRestaurant(list1: Array, list2: Array): Array { 1403 | val result = mutableSetOf() 1404 | 1405 | for (i in 0 until list1.size) { 1406 | if (list2.contains(list1[i])) { 1407 | result.add(list1[i]) 1408 | } 1409 | } 1410 | 1411 | return result.toTypedArray() 1412 | } 1413 | 1414 | fun restoreString(s: String, indices: IntArray): String { 1415 | val map = mutableMapOf() 1416 | val builder = StringBuilder() 1417 | 1418 | for (i in 0 until s.length) { 1419 | val idx = indices[i] 1420 | map[idx] = s[i] 1421 | } 1422 | 1423 | //c o d e l e e t 1424 | //0 1 2 3 4 5 6 7 1425 | //4,5,6,7,0,2,1,3 1426 | //leetc 1427 | 1428 | for (i in 0 until map.size) { 1429 | builder.append(map[i]) 1430 | } 1431 | 1432 | return builder.toString() 1433 | } 1434 | 1435 | fun exist(board: Array, word: String): Boolean { 1436 | val flattenBoard = board.flatMap { it.toList() } 1437 | val map = mutableMapOf() 1438 | 1439 | for (char in word) { 1440 | map[char] = map.getOrDefault(char, 0) + 1 1441 | } 1442 | 1443 | flattenBoard.forEach { char -> 1444 | if (map.containsKey(char)) { 1445 | if (map.getOrDefault(char, 0) > 0) { 1446 | map[char] = map.getOrDefault(char, 0) - 1 1447 | } 1448 | 1449 | if (map[char] == 0) { 1450 | map.remove(char) 1451 | } 1452 | } 1453 | } 1454 | 1455 | return map.isEmpty() 1456 | } 1457 | 1458 | //for above function 1459 | private fun chunkWord(word: String): ArrayDeque { 1460 | val deque = ArrayDeque() 1461 | 1462 | for (char in word) { 1463 | deque.offerFirst(char) 1464 | } 1465 | 1466 | return deque 1467 | } 1468 | 1469 | fun reverseString(s: CharArray): Unit { 1470 | var idx = 0 1471 | s.reverse() 1472 | for (i in s.size - 1 downTo 0) { 1473 | 1474 | } 1475 | s.reverse() 1476 | } 1477 | 1478 | fun wordPattern(pattern: String, s: String): Boolean { 1479 | val word = s.split(" ").toMutableSet() 1480 | val wordCount = s.split(" ") 1481 | val patternMap = mutableMapOf() 1482 | 1483 | if (pattern.length != wordCount.size) { 1484 | return false 1485 | } 1486 | 1487 | for (code in pattern) { 1488 | patternMap[code] = patternMap.getOrDefault(code, 0) + 1 1489 | } 1490 | 1491 | return patternMap.keys.size == word.size 1492 | } 1493 | 1494 | fun countAndSay(n: Int): String { 1495 | val mapWord = mutableMapOf( 1496 | 1 to "one", 1497 | 2 to "two", 1498 | 3 to "three", 1499 | 4 to "four", 1500 | 5 to "five", 1501 | 6 to "six", 1502 | 7 to "seven", 1503 | 8 to "eight", 1504 | 9 to "nine" 1505 | ) 1506 | 1507 | return "1" 1508 | } 1509 | 1510 | fun numTilePossibilities(tiles: String): Int { 1511 | if (tiles.length < 2) { 1512 | return tiles.length 1513 | } 1514 | return 0 1515 | } 1516 | 1517 | fun nextGreaterElement(nums1: IntArray, nums2: IntArray): IntArray { 1518 | val list = mutableListOf() 1519 | 1520 | for (i in 0 until nums1.size) { 1521 | if (nums1[i] in nums2) { 1522 | val idx = nums2.indexOf(nums1[i]) 1523 | val maxSize = nums2.size - 1 1524 | 1525 | if (maxSize == idx) { 1526 | list.add(-1) 1527 | } else { 1528 | list.add( 1529 | nextGreater(nums2, idx) 1530 | ) 1531 | } 1532 | } 1533 | } 1534 | 1535 | return list.toIntArray() 1536 | } 1537 | 1538 | private fun nextGreater(nums: IntArray, idx: Int): Int { 1539 | for (i in idx until nums.size) { 1540 | if (nums[idx] < nums[i]) { 1541 | return nums[i] 1542 | } 1543 | } 1544 | 1545 | return -1 1546 | } 1547 | 1548 | fun arraysIntersection(arr1: IntArray, arr2: IntArray, arr3: IntArray): List { 1549 | val seen = arr1.intersect(arr2.asIterable()).intersect(arr3.asIterable()) 1550 | 1551 | return seen.toList() 1552 | } 1553 | 1554 | fun countCharacters(words: Array, chars: String): Int { 1555 | var count = 0 1556 | for (word in words) { 1557 | if (isValidChar(chars, word)) { 1558 | count += word.length 1559 | } 1560 | } 1561 | return count 1562 | } 1563 | 1564 | private fun isValidChar(chars: String, word: String): Boolean { 1565 | for (char in word) { 1566 | if (char !in chars) { 1567 | return false 1568 | } 1569 | } 1570 | 1571 | return true 1572 | } 1573 | 1574 | fun alertNames(keyName: Array, keyTime: Array): List { 1575 | val map = mutableMapOf>() 1576 | val list = mutableListOf() 1577 | 1578 | for (i in 0 until keyName.size) { 1579 | 1580 | } 1581 | 1582 | return list.toList() 1583 | } 1584 | 1585 | fun customSortString(order: String, s: String): String { 1586 | val mapChar = mutableMapOf() 1587 | 1588 | for (char in order) { 1589 | mapChar[char] = mapChar.getOrDefault(char, 0) + 1 1590 | } 1591 | 1592 | for (char in s) { 1593 | mapChar[char] = mapChar.getOrDefault(char, 0) - 1 1594 | } 1595 | 1596 | 1597 | val builder = StringBuilder() 1598 | mapChar.keys.forEach { 1599 | builder.append(it) 1600 | } 1601 | 1602 | return builder.toString() 1603 | } 1604 | 1605 | fun deliManipulation(n: String): String { 1606 | var counter = 1 1607 | val builder = StringBuilder() 1608 | for (char in n) { 1609 | if (char.isWhitespace()) { 1610 | counter = 0 1611 | builder.append(" ") 1612 | } 1613 | 1614 | if (counter == 2) { 1615 | counter++ 1616 | continue 1617 | } 1618 | 1619 | if (counter != 2) { 1620 | builder.append(char) 1621 | counter++ 1622 | } 1623 | } 1624 | 1625 | return builder.toString() 1626 | } 1627 | 1628 | fun maxValue(n: String, x: Int): String {/* 1629 | n = "99", 1630 | x = 9 1631 | 1632 | first, convert it into an array [9,9] 1633 | second, create new list with size prev array + 1, because we want to add a new number and try 1634 | to get max value 1635 | 1636 | */ 1637 | var pos = 0 1638 | var neg = 1 1639 | var builder = StringBuilder(n) 1640 | 1641 | if (n[0] == '-') { 1642 | while (neg < n.length) { 1643 | val value = n[neg] - '0' 1644 | if (value < x) { 1645 | break 1646 | } 1647 | 1648 | neg++ 1649 | } 1650 | 1651 | builder.insert(neg, x) 1652 | } else { 1653 | while (pos < n.length) { 1654 | val value = n[pos] - '0' 1655 | if (value > x) { 1656 | break 1657 | } 1658 | 1659 | pos++ 1660 | } 1661 | builder.insert(pos, x) 1662 | } 1663 | 1664 | return builder.toString() 1665 | } 1666 | 1667 | fun helperMaxValue(n: String, x: Int): String { 1668 | var current = n.toList() 1669 | val list = mutableListOf().addAll(current) 1670 | var max = 0 1671 | 1672 | for (i in 0 until current.size + 1) { 1673 | 1674 | max = Math.max(0, 0) 1675 | } 1676 | 1677 | return "$max" 1678 | } 1679 | 1680 | fun isNegativeValue(n: String): Boolean { 1681 | return n[0] == '-' 1682 | } 1683 | 1684 | fun buyStock(list: IntArray): List {/* 1685 | [7,1,5,3,6,4] 1686 | */ 1687 | 1688 | var current = 0 1689 | var maxProfit = 0 1690 | var result = mutableListOf() 1691 | 1692 | for (idx in 1 until list.size) { 1693 | current += list[idx] - list[idx - 1] 1694 | current = Math.max(0, current) 1695 | maxProfit = Math.max(current, maxProfit) 1696 | result.add(maxProfit) 1697 | } 1698 | 1699 | return result.takeLast(2) 1700 | } 1701 | 1702 | fun reverseStringWithChar(s: String, symbols: String): String {/* 1703 | for example the text is: deliveryhero 1704 | the output: o*r*e*h*y*r*e*v*i*l*e*d 1705 | */ 1706 | 1707 | val builder = StringBuilder() 1708 | 1709 | for (idx in s.length - 1 downTo 0) { 1710 | builder.append(s[idx]) 1711 | builder.append(symbols) 1712 | } 1713 | 1714 | return builder.toString() 1715 | } 1716 | 1717 | fun reverseStringWithCharEveryPos(s: String, symbols: String, position: Int): String {/* 1718 | for example the text is: deliveryhero 1719 | the output: o*r*e*h*y*r*e*v*i*l*e*d 1720 | */ 1721 | 1722 | val builder = StringBuilder() 1723 | 1724 | for (idx in s.length - 1 downTo 0) { 1725 | if (idx % position == 0) { 1726 | builder.append(symbols) 1727 | } else { 1728 | builder.append(s[idx]) 1729 | } 1730 | } 1731 | 1732 | return builder.toString() 1733 | } 1734 | 1735 | fun stringShift(s: String, shift: Array): String { 1736 | var shifted = s 1737 | for (pos in shift) { 1738 | shifted = swapShift(shifted, pos[0], pos[1]) 1739 | } 1740 | 1741 | return shifted 1742 | } 1743 | 1744 | private fun swapShift(s: String, i: Int, j: Int): String { 1745 | val swapped = s.toCharArray() 1746 | var temp = swapped[i] 1747 | swapped[i] = swapped[j] 1748 | temp = swapped[i] 1749 | return swapped.joinToString("") 1750 | } 1751 | 1752 | fun merge(nums1: IntArray, m: Int, nums2: IntArray, n: Int): Unit { 1753 | val first = nums1.take(m) 1754 | val second = nums2.take(n) 1755 | 1756 | println(first.plus(second)) 1757 | } 1758 | 1759 | fun numberOfArithmeticSlices(nums: IntArray): Int { 1760 | return 0 1761 | } 1762 | 1763 | private fun replace(delimeter: String, s: String): String { 1764 | val builder = StringBuilder() 1765 | 1766 | return builder.toString() 1767 | } 1768 | 1769 | fun rearrangeElement(list: IntArray): IntArray { 1770 | var idx = 0 1771 | 1772 | for (i in 0 until list.size) { 1773 | if (list[i] != 0) { 1774 | list[idx++] = list[i] 1775 | } 1776 | } 1777 | 1778 | for (i in idx until list.size) { 1779 | list[i] = 0 1780 | } 1781 | 1782 | return list 1783 | } 1784 | 1785 | fun closestValue(root: TreeNode?, target: Double): Int { 1786 | val list = mutableListOf() 1787 | var target = 0 1788 | helper(root, list) 1789 | 1790 | return Collections.min(list, Comparator { o1, o2 -> 1791 | return@Comparator if (Math.abs(o1 - target) < Math.abs(o2 - target)) { 1792 | -1 1793 | } else { 1794 | 1 1795 | } 1796 | }) 1797 | } 1798 | 1799 | private fun helper(root: TreeNode?, list: MutableList) { 1800 | if (root == null) { 1801 | return 1802 | } 1803 | 1804 | helper(root.left, list) 1805 | list.add(root.`val`) 1806 | helper(root.right, list) 1807 | } 1808 | 1809 | fun removeDuplicates(s: String): String { 1810 | val builder = StringBuilder() 1811 | val deque = ArrayDeque() 1812 | //input = abbaca 1813 | //stack = ab 1814 | 1815 | for (char in s) { 1816 | if (char == deque.peek()) { 1817 | deque.pop() 1818 | } else { 1819 | deque.push(char) 1820 | } 1821 | 1822 | } 1823 | 1824 | for (char in deque) { 1825 | builder.append(char) 1826 | } 1827 | 1828 | return builder.toString() 1829 | } 1830 | 1831 | fun isValidSubsequence(array: List, sequence: List): Boolean { 1832 | if (array.containsAll(sequence)) { 1833 | return false 1834 | } 1835 | 1836 | 1837 | sequence.forEach { 1838 | if (!array.contains(it)) { 1839 | return false 1840 | } 1841 | } 1842 | 1843 | return true 1844 | } 1845 | 1846 | //zalando codility 1847 | fun first(n: Int): String { 1848 | val result = StringBuilder() 1849 | for (i in 0 until n) { 1850 | if (i % 2 == 0) { 1851 | result.append("-") 1852 | } else { 1853 | result.append("+") 1854 | } 1855 | } 1856 | 1857 | return result.toString() 1858 | } 1859 | 1860 | fun second(N: Int): Int { 1861 | //add 5 into number 1862 | val additionalNumber = 5 1863 | 1864 | if (N == 0) { 1865 | return additionalNumber * 10 1866 | } 1867 | 1868 | var currentMaxValue = Int.MAX_VALUE 1869 | var negativeValue = N / Math.abs(N) 1870 | var number = Math.abs(N) 1871 | var counter = 0 1872 | var position = 1 1873 | 1874 | while (number > 0) { 1875 | counter++ 1876 | number = number / 10 1877 | } 1878 | 1879 | for (i in 0..counter) { 1880 | val current = ((number / position) * (position * 10)) + (additionalNumber * position) + (number % position) 1881 | 1882 | if (current * negativeValue > currentMaxValue) { 1883 | currentMaxValue = current * negativeValue 1884 | } 1885 | 1886 | position *= 10 1887 | } 1888 | 1889 | return currentMaxValue 1890 | } 1891 | 1892 | fun third(A: IntArray): Int { 1893 | if (A.size == 2) { 1894 | return 0 1895 | } 1896 | 1897 | var slow = A[0] + A[1] 1898 | var slowIndex = 0 1899 | 1900 | var fast = Int.MAX_VALUE 1901 | var fastIdx = 0 1902 | 1903 | for (i in 2 until A.size) { 1904 | val temp = A[i - 1] + A[i] 1905 | if (temp < slow) { 1906 | slow = temp 1907 | slowIndex = i - 1 1908 | } 1909 | 1910 | val tempFast = temp + A[i - 2] 1911 | if (tempFast < fast) { 1912 | fast = tempFast 1913 | fastIdx = i - 2 1914 | } 1915 | } 1916 | 1917 | val minTwoIndx = slow * 3 1918 | val minThreeIdx = fast * 2 1919 | 1920 | return if (minTwoIndx == minThreeIdx) { 1921 | Math.min(slowIndex, fastIdx) 1922 | } else { 1923 | if (minTwoIndx < minThreeIdx) { 1924 | slowIndex 1925 | } else { 1926 | fastIdx 1927 | } 1928 | 1929 | } 1930 | } 1931 | 1932 | fun missingElement(nums: IntArray, k: Int): Int {/* 1933 | Input: nums = [4,7,9,10], k = 1 1934 | Output: 5 1935 | Explanation: The first missing number is 5. 1936 | */ 1937 | 1938 | if (nums.isEmpty()) { 1939 | return 0 1940 | } 1941 | val cache = IntArray(nums.size + 1) 1942 | val startPoint = nums[0] 1943 | val numbers = mutableListOf() 1944 | val unknownNumber = mutableListOf() 1945 | 1946 | for (i in startPoint..(nums.size * 2)) { 1947 | numbers.add(i) 1948 | } 1949 | 1950 | println(numbers) 1951 | for (digit in nums) { 1952 | if (!numbers.contains(digit)) { 1953 | unknownNumber.add(digit) 1954 | } 1955 | } 1956 | 1957 | println(unknownNumber) 1958 | return numbers.elementAt(k).or(0) 1959 | } 1960 | 1961 | fun frequencySort(s: String): String { 1962 | val map = mutableMapOf() 1963 | val builder = StringBuilder() 1964 | 1965 | for (char in s) { 1966 | map[char] = map.getOrDefault(char, 0) + 1 1967 | } 1968 | 1969 | map.toSortedMap(Comparator.reverseOrder()).forEach { t, u -> 1970 | repeat(u) { 1971 | builder.append("$t") 1972 | } 1973 | } 1974 | 1975 | return builder.toString() 1976 | } 1977 | 1978 | fun validWordAbbreviation(word: String, abbr: String): Boolean {/* 1979 | s10n ; word = substitution 1980 | we have first text as s and will take 10 characters from the word that start after the s 1981 | which mean will start from 2nd char until the number 1982 | */ 1983 | val stringBuilder = StringBuilder() 1984 | for (i in 0 until abbr.length) { 1985 | if (!abbr[i].isDigit()) { 1986 | stringBuilder.append(abbr[i]) 1987 | } else { 1988 | if (abbr[i] == '0') { 1989 | return false 1990 | } 1991 | 1992 | stringBuilder.append( 1993 | word.substring(i..Character.getNumericValue(abbr[i])) 1994 | ) 1995 | } 1996 | } 1997 | 1998 | return stringBuilder.toString() == word 1999 | } 2000 | 2001 | fun uncommonFromSentences(s1: String, s2: String): Array {/* 2002 | s1 = "this apple is sweet", 2003 | s2 = "this apple is sour" 2004 | output = ["sweet","sour"] 2005 | 2006 | 1st approach: 2007 | we can use list to store all words from s1 2008 | */ 2009 | 2010 | val map = mutableMapOf() 2011 | val result = mutableListOf() 2012 | 2013 | val firstSentence = s1.split(" ").toMutableSet() // it will list of string 2014 | val secondSentence = s2.split(" ").toMutableSet()// it will list of string 2015 | 2016 | for (word in firstSentence) { //[this, apple, is, sweet] 2017 | 2018 | //this-, apple-, is-, sour 2019 | map[word] = map.getOrDefault(word, 0) + 1 2020 | } 2021 | 2022 | for (word in secondSentence) { 2023 | if (map.containsKey(word)) { 2024 | map[word] = map.getOrDefault(word, 0) - 1 2025 | } else { 2026 | result.add(word) 2027 | } 2028 | } 2029 | println(map) 2030 | return result.toTypedArray() 2031 | } 2032 | 2033 | fun canConstruct(ransomNote: String, magazine: String): Boolean { 2034 | val map = mutableMapOf() 2035 | 2036 | for (char in magazine.toCharArray()) { 2037 | map[char] = map.getOrDefault(char, 0) + 1 2038 | } 2039 | 2040 | for (note in ransomNote.toCharArray()) { 2041 | if (!map.containsKey(note) || map[note]!! <= 0) { 2042 | return false 2043 | } 2044 | 2045 | map[note] = map.getOrDefault(note, 0) - 1 2046 | } 2047 | 2048 | return true 2049 | } 2050 | 2051 | fun findDisappearedNumbers(nums: IntArray): List { 2052 | //4,3,2,7,8,2,3,1 2053 | val seen = mutableSetOf() 2054 | val result = mutableListOf() 2055 | nums.forEach { 2056 | seen.add(it) 2057 | } 2058 | 2059 | val max = nums.size 2060 | 2061 | for (i in 0 until max) { 2062 | if (i in seen || i == 0) { 2063 | //do nothing 2064 | } else { 2065 | result.add(i) 2066 | } 2067 | } 2068 | 2069 | return result 2070 | } 2071 | 2072 | fun isPowerOfTwo(n: Int): Boolean { 2073 | if (n == 1) return true 2074 | 2075 | var i = 0 2076 | while (i < n) { 2077 | if (Math.pow(2.0, i.toDouble()) == n.toDouble()) { 2078 | return true 2079 | } 2080 | } 2081 | 2082 | return false 2083 | } 2084 | 2085 | fun commonChars(words: Array): List {/* 2086 | ["bella","label","roller"] 2087 | output = ["e","l","l"] 2088 | 2089 | loop the words to get each of word 2090 | "bella" 2091 | loop the map into the map 2092 | if the char is in the map, add to map 2093 | else ignore 2094 | */ 2095 | 2096 | val map = mutableMapOf() 2097 | val list = mutableListOf() 2098 | 2099 | for (text in words) { 2100 | for (j in 0 until text.length) { 2101 | val char = text[j] 2102 | if (char in map.keys) { 2103 | map[char] = map.getOrDefault(char, 0) + 1 2104 | } 2105 | } 2106 | } 2107 | 2108 | println(map) 2109 | return list 2110 | } 2111 | 2112 | fun removeElement(nums: IntArray, `val`: Int): Int { 2113 | // nums.toMutableList().filter { it == target }.shuffled() 2114 | nums.binarySearch(`val`) 2115 | for (i in 0 until nums.size) { 2116 | if (nums[i] == `val`) { 2117 | nums.toMutableList().remove(nums[i]) 2118 | } 2119 | } 2120 | 2121 | return nums.size 2122 | } 2123 | 2124 | class NodeApple(var `val`: Int) { 2125 | var children: List = listOf() 2126 | } 2127 | 2128 | fun postorder(root: NodeApple?): List { 2129 | val list = mutableListOf() 2130 | if (root == null) { 2131 | return emptyList() 2132 | } 2133 | 2134 | var i = 0 2135 | while (i < root.children.size) { 2136 | if (root.children.isNotEmpty()) { 2137 | val lastValue = root.children.last() 2138 | list.add(lastValue!!.`val`) 2139 | } 2140 | i++ 2141 | } 2142 | 2143 | return list 2144 | } 2145 | 2146 | fun singleNumbers(nums: IntArray): IntArray { 2147 | val set = mutableSetOf() 2148 | 2149 | for (number in nums) { 2150 | if (set.contains(number)) { 2151 | set.remove(number) 2152 | } 2153 | set.add(number) 2154 | } 2155 | 2156 | return set.toIntArray() 2157 | } 2158 | 2159 | fun longestValidParentheses(s: String): Int { 2160 | var count = 0 2161 | 2162 | val bracketMap = mutableMapOf( 2163 | '(' to ')', '[' to ']', '{' to '}' 2164 | ) 2165 | val stack = ArrayDeque() 2166 | for (bracket in s) { 2167 | if (bracketMap[stack.peek()] == bracket) { 2168 | stack.pop() 2169 | count++ 2170 | } else { 2171 | stack.push(bracket) 2172 | } 2173 | } 2174 | 2175 | return count 2176 | } 2177 | 2178 | fun getFolderNames(names: Array): Array { 2179 | val fileMap = mutableMapOf() 2180 | val listOfFolder = mutableListOf() 2181 | 2182 | for (folder in names) { 2183 | fileMap[folder] = fileMap.getOrDefault(folder, 0) + 1 2184 | } 2185 | 2186 | return listOfFolder.toTypedArray() 2187 | } 2188 | 2189 | private val list = listOf( 2190 | RomanValue("M", 1000), 2191 | RomanValue("CM", 900), 2192 | RomanValue("D", 500), 2193 | RomanValue("CD", 400), 2194 | RomanValue("C", 100), 2195 | RomanValue("XC", 90), 2196 | RomanValue("L", 50), 2197 | RomanValue("XL", 40), 2198 | RomanValue("X", 10), 2199 | RomanValue("IX", 9), 2200 | RomanValue("V", 5), 2201 | RomanValue("IV", 4), 2202 | RomanValue("I", 1) 2203 | ) 2204 | 2205 | fun romanToInt(roman: String): Int { 2206 | 2207 | val mapOfRoman = mapOf( 2208 | 'M' to 1000, 'D' to 500, 'C' to 100, 'L' to 50, 'X' to 10, 'V' to 5, 'I' to 1 2209 | )/* 2210 | IV = 4 2211 | XL = 40 2212 | */ 2213 | 2214 | var result = 0 2215 | 2216 | for (i in 0 until roman.length) { 2217 | result += if (i > 0 && mapOfRoman.getOrDefault(roman[i], 0) > mapOfRoman.getOrDefault(roman[i - 1], 0)) { 2218 | mapOfRoman.getOrDefault(roman[i], 0) - 2 * mapOfRoman.getOrDefault(roman[i - 1], 0) 2219 | } else { 2220 | mapOfRoman.getOrDefault(roman[i], 0) 2221 | } 2222 | } 2223 | 2224 | return result 2225 | } 2226 | 2227 | fun intToRoman(num: Int): String { 2228 | var input = num 2229 | val result = StringBuilder() 2230 | 2231 | for (number in list) { 2232 | val numberOfRoman = input / number.value 2233 | if (numberOfRoman != 0) { 2234 | result.append(number.roman.repeat(numberOfRoman)) 2235 | } 2236 | input %= number.value 2237 | } 2238 | 2239 | return result.toString() 2240 | } 2241 | 2242 | data class RomanValue(val roman: String, val value: Int) 2243 | 2244 | fun lowestCommonAncestor(root: TreeNode?, p: TreeNode?, q: TreeNode?): TreeNode? { 2245 | if (root == null && p == null && q == null) { 2246 | return root 2247 | } 2248 | 2249 | return if (root?.`val`!! > p?.`val`!! && root.`val` > q?.`val`!!) { 2250 | lowestCommonAncestor(root.left, p, q) 2251 | } else if (root.`val` < p.`val` && root.`val` < q?.`val`!!) { 2252 | lowestCommonAncestor(root.right, p, q) 2253 | } else { 2254 | root 2255 | } 2256 | } 2257 | 2258 | fun findKthLargest(nums: IntArray, k: Int): Int { 2259 | val size = nums.size - 1 2260 | var swaps = 0 2261 | for (i in 0 until size) { 2262 | for (j in 0 until size - i) { 2263 | if (nums[j] > nums[j + 1]) { 2264 | swapElements(nums, j, j + 1) 2265 | } 2266 | } 2267 | } 2268 | 2269 | nums.forEach { print("$it, ") } 2270 | println() 2271 | return nums[nums.size - k] 2272 | } 2273 | 2274 | 2275 | fun swapElements(nums: IntArray, i: Int, j: Int) { 2276 | val temp = nums[j] 2277 | nums[j] = nums[i] 2278 | nums[i] = temp 2279 | } 2280 | 2281 | fun shortestDistance(wordsDict: Array, word1: String, word2: String): Int { 2282 | val firstIdx = wordsDict.lastIndexOf(word1) 2283 | val secondIdx = wordsDict.lastIndexOf(word2) 2284 | 2285 | println("$firstIdx $secondIdx") 2286 | 2287 | return if (firstIdx > secondIdx) { 2288 | firstIdx - secondIdx 2289 | } else { 2290 | secondIdx - firstIdx 2291 | } 2292 | 2293 | } 2294 | 2295 | fun topKFrequent(words: Array, k: Int): List { 2296 | val result = mutableListOf() 2297 | val frequentMap = mutableMapOf() 2298 | 2299 | for (word in words) { 2300 | frequentMap[word] = frequentMap.getOrDefault(word, 0) + 1 2301 | } 2302 | 2303 | val sortedMap = 2304 | frequentMap.toList().sortedByDescending { (key, value) -> key }.sortedBy { (key, value) -> value }.takeLast(k) 2305 | .reversed().toMap() 2306 | 2307 | for ((key, value) in sortedMap) { 2308 | result.add(key) 2309 | } 2310 | return result 2311 | } 2312 | 2313 | fun myAtoi(s: String): Int { 2314 | s.trim(' ') 2315 | val builder = StringBuilder() 2316 | if (s.isEmpty() || s[0].isLetter()) { 2317 | return 0 2318 | } 2319 | 2320 | for (i in 0 until s.length) { 2321 | 2322 | if (s[i] == '-') { 2323 | builder.append(s[i]) 2324 | } else if (s[i].isDigit()) { 2325 | builder.append(s[i]) 2326 | } 2327 | } 2328 | 2329 | val temp: Long = builder.toString().toLong() 2330 | var result = builder.toString() 2331 | if (temp > Integer.MAX_VALUE) { 2332 | result = "${Integer.MAX_VALUE}" 2333 | } else if (temp < Integer.MIN_VALUE) { 2334 | result = "${Integer.MIN_VALUE}" 2335 | } 2336 | 2337 | return result.toInt() 2338 | } 2339 | 2340 | fun spiralOrder(matrix: Array): List { 2341 | val result = mutableListOf() 2342 | if (matrix.isEmpty()) { 2343 | return emptyList() 2344 | } 2345 | 2346 | var left = 0 2347 | var right = matrix[0].size - 1 2348 | var bottom = matrix.size - 1 2349 | var top = 0 2350 | val size = matrix.size * matrix[0].size 2351 | 2352 | while (result.size <= size) { 2353 | 2354 | for (i in left until right) { 2355 | result.add(matrix[top][i]) 2356 | } 2357 | top++ 2358 | 2359 | for (i in top until bottom) { 2360 | result.add(matrix[i][right]) 2361 | } 2362 | right-- 2363 | 2364 | for (i in right until left) { 2365 | result.add(matrix[bottom][i]) 2366 | } 2367 | bottom-- 2368 | 2369 | for (i in bottom until top) { 2370 | result.add(matrix[i][left]) 2371 | } 2372 | left++ 2373 | } 2374 | 2375 | return result 2376 | } 2377 | 2378 | data class VisitedWebsite( 2379 | val username: String, val timestamp: Int, val website: String 2380 | ) 2381 | 2382 | fun maxNumberOfBalloons(text: String): Int { 2383 | val pattern = "balloon" 2384 | val map = mutableMapOf() 2385 | 2386 | for (char in text) { 2387 | if (pattern.contains(char)) { 2388 | map[char] = map.getOrDefault(char, 0) + 1 2389 | } 2390 | } 2391 | 2392 | return map.values.sum() / 7 2393 | } 2394 | 2395 | fun fib(n: Int): Int { 2396 | return fibMemoization(n, listOf(n + 1)) 2397 | } 2398 | 2399 | private fun fibMemoization(n: Int, memo: List): Int { 2400 | if (n == 0 || n == 1) { 2401 | return n 2402 | } 2403 | 2404 | if (memo[n] == 0) { 2405 | memo[n] == fibMemoization(n - 1, memo) + fibMemoization(n - 2, memo) 2406 | } 2407 | 2408 | return memo[n] 2409 | } 2410 | 2411 | fun addBinary(a: String, b: String): String { 2412 | val firstValue = Integer.parseInt(a, 2) 2413 | val secondValue = Integer.parseInt(b, 2) 2414 | firstValue.shl(1) 2415 | return "$firstValue" 2416 | } 2417 | 2418 | fun validPalindromeII(s: String): Boolean { 2419 | var first = 0 2420 | val last = s.length - 1 2421 | 2422 | while (first < last) { 2423 | if (isValidPalindromeII(s, first)) { 2424 | return true 2425 | } 2426 | first++ 2427 | } 2428 | 2429 | return false 2430 | } 2431 | 2432 | fun isValidPalindromeII(s: String, position: Int): Boolean { 2433 | if (s == s.reversed()) { 2434 | return true 2435 | } 2436 | 2437 | val char = s[position] 2438 | val word = s.trim(char) 2439 | return word.reversed() == word 2440 | } 2441 | 2442 | fun removeDuplicates(nums: IntArray): Int { 2443 | if (nums.isEmpty()) { 2444 | return 0 2445 | } 2446 | 2447 | var count = 0 2448 | for (i in 1 until nums.size) { 2449 | if (nums[i] == nums[i - 1]) { 2450 | nums.drop(nums[i]) 2451 | count++ 2452 | } 2453 | } 2454 | 2455 | 2456 | return count + 1 2457 | } 2458 | 2459 | fun sortedSquares(nums: IntArray): IntArray { 2460 | // nums.map { number -> number * number } 2461 | 2462 | for (i in 0 until nums.size) { 2463 | nums[i] = nums[i] * nums[i] 2464 | } 2465 | nums.sort() 2466 | return nums 2467 | } 2468 | 2469 | fun majorityElement(nums: IntArray): List {/* 2470 | Input: nums = [3,2,3] 2471 | Output: [3] 2472 | 2473 | Input: nums = [1,2] 2474 | Output: [1,2] 2475 | */ 2476 | val frequency = if (nums.size / 3 != 0) nums.size / 3 else 1 2477 | val mapFrequency = mutableMapOf() 2478 | val result = mutableListOf() 2479 | 2480 | println(frequency) 2481 | for (number in nums) { 2482 | mapFrequency[number] = mapFrequency.getOrDefault(number, 0) + 1 2483 | if (mapFrequency.getOrDefault(number, 0) > frequency) { 2484 | result.add(number) 2485 | } 2486 | } 2487 | 2488 | 2489 | return result 2490 | } 2491 | 2492 | fun findAndReplacePattern(words: Array, pattern: String): List {/* 2493 | Input: words = ["abc","deq","mee","aqq","dkd","ccc"], pattern = "abb" 2494 | Output: ["mee","aqq"] 2495 | Explanation: "mee" matches the pattern because there is a permutation {a -> m, b -> e, ...}. 2496 | "ccc" does not match the pattern because {a -> c, b -> c, ...} is not a permutation, since a and b map to the same letter. 2497 | */ 2498 | 2499 | val patternMap = mutableMapOf() 2500 | pattern.forEach { char -> 2501 | patternMap[char] = patternMap.getOrDefault(char, 0) + 1 2502 | } 2503 | 2504 | val result = mutableListOf() 2505 | for (word in words) { 2506 | if (isMatchPattern(word, patternMap)) { 2507 | result.add(word) 2508 | } 2509 | } 2510 | 2511 | return result 2512 | } 2513 | 2514 | private fun isMatchPattern(s: String, patternMap: MutableMap): Boolean { 2515 | val map = mutableMapOf() 2516 | s.forEach { char -> 2517 | map[char] = map.getOrDefault(char, 0) + 1 2518 | } 2519 | 2520 | return map.keys == patternMap.keys 2521 | } 2522 | 2523 | 2524 | fun convertToTitle(columnNumber: Int): String {/* 2525 | Input: columnNumber = 1 2526 | Output: "A" 2527 | 2528 | Input: columnNumber = 28 2529 | Output: "AB" 2530 | 2531 | Input: columnNumber = 701 2532 | Output: "ZY" 2533 | 2534 | Input: columnNumber = 2147483647 2535 | Output: "FXSHRXW" 2536 | */ 2537 | 2538 | var number = columnNumber 2539 | val builder = StringBuilder() 2540 | 2541 | while (number > 0) { 2542 | number-- 2543 | builder.append('A' + number % 26) 2544 | number /= 26 2545 | } 2546 | 2547 | builder.reverse() 2548 | return builder.toString() 2549 | } 2550 | 2551 | fun balancedStringSplit(s: String): Int { 2552 | var count = 0 2553 | var balancer = 0 2554 | 2555 | for (char in s) { 2556 | if (char == 'R') { 2557 | balancer += 1 2558 | } else if (char == 'L') { 2559 | balancer -= 1 2560 | } 2561 | 2562 | if (balancer == 0) { 2563 | count++ 2564 | } 2565 | } 2566 | 2567 | return count 2568 | } 2569 | 2570 | fun decompressRLElist(nums: IntArray): IntArray { 2571 | val result = mutableListOf() 2572 | 2573 | for (i in 0 until nums.size step 2) { 2574 | val list = mutableListOf() 2575 | for (j in 0 until nums[i]) { 2576 | list.add(nums[i + 1]) 2577 | } 2578 | 2579 | result.addAll(list) 2580 | } 2581 | 2582 | return result.toIntArray() 2583 | } 2584 | 2585 | fun numIdenticalPairs(nums: IntArray): Int { 2586 | 2587 | /* 2588 | Input: nums = [1,2,3,1,1,3] 2589 | Output: 4 2590 | (0,3) = > [1,1] 2591 | (0,4) => [1,1] 2592 | (3,4) => [1,1] 2593 | (2,5) => [3,3 2594 | Explanation: There are 4 good pairs (0,3), (0,4), (3,4), (2,5) 0-indexed. 2595 | */ 2596 | 2597 | var answer = 0 2598 | val map = mutableMapOf() 2599 | for (num in nums) { 2600 | map[num] = map.getOrDefault(num, 0) + 1 2601 | answer += map[num]?.minus(1) ?: 0 2602 | } 2603 | return answer 2604 | } 2605 | 2606 | fun shuffle(nums: IntArray, n: Int): IntArray { 2607 | val result = intArrayOf(2 * n) 2608 | for (i in 0 until nums.size) { 2609 | result[2 * i] = nums[i] 2610 | result[2 * i + 1] = nums[n + 1] 2611 | } 2612 | 2613 | return result 2614 | } 2615 | 2616 | fun runningSum(nums: IntArray): IntArray { 2617 | for (i in 1 until nums.size) { 2618 | nums[i] += nums[i - 1] 2619 | } 2620 | 2621 | return nums 2622 | } 2623 | 2624 | fun defangIPaddr(address: String): String { 2625 | return address.replace(".", "[.]") 2626 | } 2627 | 2628 | fun globMatching(fileName: String, pattern: String): Boolean { 2629 | 2630 | // val sample = "bcdefg" 2631 | // val pattern = "*e?g" 2632 | 2633 | val matching = ArrayDeque() 2634 | val cache = mutableListOf() 2635 | 2636 | 2637 | for (i in fileName.length - 1 downTo 0) { 2638 | matching.add(fileName[i]) 2639 | } 2640 | 2641 | for (i in 0 until pattern.length) { 2642 | when (pattern[i]) { 2643 | '*' -> { 2644 | 2645 | } 2646 | 2647 | '?' -> { 2648 | matching.pop() 2649 | } 2650 | 2651 | else -> { 2652 | if (pattern[i] == matching.peekFirst()) { 2653 | matching.pop() 2654 | } 2655 | } 2656 | } 2657 | } 2658 | 2659 | return matching.isEmpty() 2660 | } 2661 | 2662 | 2663 | fun minimumCharactersForWords(words: List): List {/* 2664 | words = ["this", "that", "did", "deed", "them!", "a"] 2665 | this => t,h,i,s (t = 1, h=1, i=1, s=1) 2666 | that => t,h,a,t (t = 2, h = 1, a=1) 2667 | did => d,i,d (d=2, i=1) 2668 | deed => d,e,e,d (d=2, e=2) 2669 | them! => t,h,e,m,!(t=1, h=1, e=1, m=1, !=1) 2670 | a => a (a=1) 2671 | 2672 | t = 2 2673 | h = 1 2674 | i = 1 2675 | s = 1 2676 | d = 2 2677 | e = 2 2678 | m = 1 2679 | ! = 1 2680 | a = 1 2681 | output = ["!", "a", "d", "d", "e", "e", "h", "i", "m", "s", "t", "t"] 2682 | */ 2683 | 2684 | val maxCharacter = mutableMapOf() 2685 | 2686 | for (word in words) { 2687 | val minimumChar = getWordsMap(word) 2688 | updateCharacter(minimumChar, maxCharacter) 2689 | } 2690 | 2691 | val result = mutableListOf() 2692 | for ((character, frequency) in maxCharacter) { 2693 | for (i in 0 until frequency) { 2694 | result.add(character) 2695 | } 2696 | } 2697 | 2698 | return result 2699 | } 2700 | 2701 | private fun getWordsMap(word: String): MutableMap { 2702 | val minimumChar = mutableMapOf() 2703 | for (char in word) { 2704 | minimumChar[char] = minimumChar.getOrDefault(char, 0) + 1 2705 | } 2706 | 2707 | return minimumChar 2708 | } 2709 | 2710 | private fun updateCharacter(current: MutableMap, maximum: MutableMap) { 2711 | for ((char, number) in current) { 2712 | if (char in maximum) { 2713 | maximum[char] = Math.max(number, maximum[char]!!) 2714 | } else { 2715 | maximum[char] = number 2716 | } 2717 | } 2718 | } 2719 | 2720 | fun countPrimes(n: Int): Int { 2721 | var result = 0 2722 | if (n == 0 || n == 1) { 2723 | return 0 2724 | } 2725 | 2726 | for (i in 2..n / 2) { 2727 | if (i % i == 0) { 2728 | result += 1 2729 | } 2730 | } 2731 | 2732 | return result 2733 | } 2734 | 2735 | fun isMonotonic(array: List): Boolean { 2736 | var isNonDecrease = true 2737 | var isNonIncrease = true 2738 | for (i in 1 until array.size) { 2739 | if (array[i] > array[i - 1]) { 2740 | isNonIncrease = false 2741 | } 2742 | 2743 | if (array[i] < array[i - 1]) { 2744 | isNonDecrease = false 2745 | } 2746 | } 2747 | return isNonDecrease || isNonIncrease 2748 | } 2749 | 2750 | fun plusOne(digits: IntArray): IntArray { 2751 | 2752 | /* 2753 | input = [9,9] 2754 | output = [1,0,0] 2755 | */ 2756 | val n: Int = digits.size 2757 | for (i in n - 1 downTo 0) { 2758 | if (digits[i] < 9) { 2759 | digits[i]++ 2760 | return digits 2761 | } 2762 | digits[i] = 0 2763 | } 2764 | val arr = IntArray(n + 1) 2765 | arr[0] = 1 2766 | return arr 2767 | } 2768 | 2769 | fun moveElementToEnd(array: MutableList, toMove: Int): List {/* 2770 | input = [2,1,2,2,2,3,4,2] 2771 | move = 2 2772 | 2773 | result = [1,3,4,2,2,2,2,2] 2774 | */ 2775 | 2776 | var first = 0 2777 | var last = array.size - 1 2778 | 2779 | while (first < last) { 2780 | while (first < last && array[last] == toMove) { 2781 | last-- 2782 | } 2783 | 2784 | if (array[first] == toMove) { 2785 | swap(first, last, array) 2786 | } 2787 | 2788 | first++ 2789 | } 2790 | 2791 | 2792 | return array 2793 | } 2794 | 2795 | private fun swap(first: Int, last: Int, array: MutableList) { 2796 | array[first] = array[last].also { array[last] = array[first] } 2797 | } 2798 | 2799 | fun maxSubArray(nums: IntArray): Int { 2800 | // var subArray = Integer.MIN_VALUE 2801 | // 2802 | // for (i in 0 until nums.size){ 2803 | // var current = 0 2804 | // for (j in i until nums.size){ 2805 | // current += nums[j] 2806 | // subArray = Math.max(subArray, current) 2807 | // } 2808 | // } 2809 | 2810 | //kadanes algorithm 2811 | 2812 | var subArray = nums[0] 2813 | var current = nums[0] 2814 | 2815 | for (i in 1 until nums.size) { 2816 | current = Math.max(nums[i], current + nums[i]) 2817 | subArray = Math.max(subArray, current) 2818 | } 2819 | 2820 | return subArray 2821 | } 2822 | 2823 | fun letterCombinations(digits: String): List { 2824 | 2825 | /* 2826 | Input: digits = "23" 2827 | Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"] 2828 | */ 2829 | 2830 | val keyword = mutableMapOf( 2831 | '2' to "abc", '3' to "def", '4' to "ghi", '5' to "jkl", '6' to "mno", '7' to "pqrs", '8' to "tuv", '9' to "wxyz" 2832 | ) 2833 | val combination = mutableSetOf() 2834 | digits.forEach { digit -> 2835 | combine( 2836 | keyword.getOrDefault('2', ""), keyword.getOrDefault('3', ""), combination 2837 | ) 2838 | } 2839 | return combination.toMutableList() 2840 | } 2841 | 2842 | private fun combine(first: String, second: String, set: MutableSet) { 2843 | for (i in 0 until first.length) { 2844 | for (j in 0 until second.length) { 2845 | set.add("${first[i]}${second[j]}") 2846 | } 2847 | } 2848 | } 2849 | 2850 | fun firstUniqChar(s: String): Int { 2851 | val unique = mutableMapOf() 2852 | 2853 | for (letter in s) { 2854 | unique[letter] = unique.getOrDefault(letter, 0) + 1 2855 | } 2856 | 2857 | for (i in 0 until s.length) { 2858 | if (unique[s[i]] == 1) { 2859 | return i 2860 | } 2861 | } 2862 | 2863 | return -1 2864 | } 2865 | 2866 | fun missingNumber(nums: IntArray): Int { 2867 | val set = mutableSetOf() 2868 | 2869 | for (number in nums) { 2870 | set.add(number) 2871 | } 2872 | 2873 | val expectedNumber = nums.size + 1 2874 | for (i in 0 until expectedNumber) { 2875 | if (set.contains(i).not()) { 2876 | return i 2877 | } 2878 | } 2879 | 2880 | return -1 2881 | } 2882 | 2883 | fun numIslands(grid: Array): Int {/* 2884 | Input: grid = [ 2885 | ["1","1","1","1","0"], 2886 | ["1","1","0","1","0"], 2887 | ["1","1","0","0","0"], 2888 | ["0","0","0","0","0"] 2889 | ] 2890 | Output: 1 2891 | 2892 | Input: grid = [ 2893 | ["1","1","0","0","0"], 2894 | ["1","1","0","0","0"], 2895 | ["0","0","1","0","0"], 2896 | ["0","0","0","1","1"] 2897 | ] 2898 | Output: 3 2899 | */ 2900 | 2901 | if (grid.isEmpty()) { 2902 | return 0 2903 | } 2904 | 2905 | var numberIsland = 0 2906 | val row = grid.size 2907 | val column = grid[0].size 2908 | 2909 | for (r in 0 until row) { 2910 | for (c in 0 until column) { 2911 | if (grid[r][c] == '1') { 2912 | ++numberIsland 2913 | dfs(grid, r, c) 2914 | } 2915 | } 2916 | } 2917 | 2918 | return numberIsland 2919 | } 2920 | 2921 | private fun dfs(grid: Array, r: Int, c: Int) { 2922 | val row = grid.size 2923 | val column = grid[0].size 2924 | 2925 | if (c >= row || c >= column || r < 0 || c < 0 || grid[r][c] == '0') { 2926 | return 2927 | } 2928 | 2929 | grid[r][c] = '0' 2930 | dfs(grid, r - 1, c) 2931 | dfs(grid, r + 1, c) 2932 | dfs(grid, r, c - 1) 2933 | dfs(grid, r, c + 1) 2934 | } 2935 | 2936 | fun lengthLongestPath(input: String): Int {/* 2937 | Input: input = "dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext" 2938 | Output: 32 2939 | Explanation: We have two files: 2940 | "dir/subdir1/file1.ext" of length 21 2941 | "dir/subdir2/subsubdir2/file2.ext" of length 32. 2942 | We return 32 since it is the longest absolute path to a file. 2943 | */ 2944 | 2945 | var directory = "" 2946 | 2947 | var left = 0 2948 | var right = left + 1 2949 | 2950 | 2951 | while (right < input.length) { 2952 | 2953 | } 2954 | 2955 | return directory.length 2956 | } 2957 | 2958 | fun canConvert(str1: String, str2: String): Boolean {/* 2959 | Input: str1 = "aabcc", str2 = "ccdee" 2960 | Output: true 2961 | Explanation: Convert 'c' to 'e' then 'b' to 'd' then 'a' to 'c'. Note that the order of conversions matter. 2962 | 2963 | Input: str1 = "leetcode", str2 = "codeleet" 2964 | Output: false 2965 | Explanation: There is no way to transform str1 to str2. 2966 | */ 2967 | return false 2968 | } 2969 | 2970 | fun singleNumber(nums: IntArray): Int { 2971 | val map = mutableMapOf() 2972 | 2973 | for (i in nums) { 2974 | map[i] = map.getOrDefault(map[i], 0) + 1 2975 | } 2976 | 2977 | for (i in nums) { 2978 | if (map[i] == 1) { 2979 | return i 2980 | } 2981 | } 2982 | 2983 | return 0 2984 | } 2985 | 2986 | fun calculateII(s: String): Int { 2987 | val stack = Stack() 2988 | val result = 0 2989 | 2990 | s.trim() 2991 | for (calc in s) { 2992 | 2993 | } 2994 | 2995 | return result 2996 | } 2997 | 2998 | fun accountsMerge(accounts: List>): List> {/* 2999 | Input: accounts = [ 3000 | ["John","johnsmith@mail.com","john_newyork@mail.com"], 3001 | ["John","johnsmith@mail.com","john00@mail.com"], 3002 | ["Mary","mary@mail.com"], 3003 | ["John","johnnybravo@mail.com"] 3004 | ] 3005 | Output: [ 3006 | ["John","john00@mail.com","john_newyork@mail.com","johnsmith@mail.com"], 3007 | ["Mary","mary@mail.com"], 3008 | ["John","johnnybravo@mail.com"] 3009 | ] 3010 | Explanation: 3011 | The first and third John's are the same person as they have the common email "johnsmith@mail.com". 3012 | The second John and Mary are different people as none of their email addresses are used by other accounts. 3013 | We could return these lists in any order, for example the answer [['Mary', 'mary@mail.com'], ['John', 'johnnybravo@mail.com'], 3014 | ['John', 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com']] would still be accepted. 3015 | */ 3016 | val accountsMap = mutableMapOf>() 3017 | 3018 | for (acc in accounts) { 3019 | accountsMap[acc.first()] = getEmail(acc) 3020 | } 3021 | accountsMap.mapValues { entry -> 3022 | 3023 | } 3024 | return emptyList() 3025 | } 3026 | 3027 | private fun getEmail(accounts: List): MutableList { 3028 | val acc = mutableListOf() 3029 | 3030 | for (i in 1 until accounts.size) { 3031 | acc.add(accounts[i]) 3032 | } 3033 | return acc 3034 | } 3035 | 3036 | fun searchMatrix(matrix: Array, target: Int): Boolean { 3037 | for (block in matrix) { 3038 | if (block.any { it == target }) { 3039 | return true 3040 | } 3041 | } 3042 | return false 3043 | } 3044 | 3045 | fun searchRange(nums: IntArray, target: Int): IntArray { 3046 | return intArrayOf(nums.indexOfFirst { it == target }, nums.lastIndexOf(target)) 3047 | } 3048 | 3049 | fun simplifyPath(path: String): String {/* 3050 | Input: path = "/home/" 3051 | Output: "/home" 3052 | Explanation: Note that there is no trailing slash after the last directory name. 3053 | */ 3054 | 3055 | val stack = Stack() 3056 | for (dir in path.split("/")) { 3057 | if (dir.isEmpty() || dir == ".") { 3058 | continue 3059 | } else if (dir == "..") { 3060 | if (stack.isNotEmpty()) { 3061 | stack.pop() 3062 | } 3063 | } else { 3064 | stack.push(dir) 3065 | } 3066 | } 3067 | 3068 | val finalPath = StringBuilder() 3069 | for (directory in stack) { 3070 | finalPath.apply { 3071 | append("/") 3072 | append(directory) 3073 | } 3074 | } 3075 | return if (finalPath.isNotEmpty()) finalPath.toString() else "/" 3076 | } 3077 | 3078 | fun minRemoveToMakeValid(s: String): String {/* 3079 | Input: s = "a)b(c)d" 3080 | Output: "ab(c)d" 3081 | 3082 | Input: s = "(a(b(c)d)" 3083 | Output: "a(b(c)d)" 3084 | */ 3085 | val bracketMap = mutableMapOf( 3086 | '(' to ')', '[' to ']', '{' to '}' 3087 | ) 3088 | val stack = ArrayDeque() 3089 | 3090 | for (letter in s) { 3091 | 3092 | } 3093 | 3094 | return s 3095 | } 3096 | 3097 | fun minAddToMakeValid(s: String): Int { 3098 | val bracketMap = mutableMapOf( 3099 | '(' to ')', '[' to ']', '{' to '}' 3100 | ) 3101 | val stack = ArrayDeque() 3102 | for (bracket in s) { 3103 | if (bracketMap[stack.peekFirst()] == bracket) { 3104 | stack.pop() 3105 | } else { 3106 | stack.push(bracket) 3107 | } 3108 | } 3109 | return stack.size 3110 | } 3111 | 3112 | fun isValid(s: String): Boolean { 3113 | 3114 | /* 3115 | Input: s = "()[]{}" 3116 | Output: true 3117 | */ 3118 | 3119 | val bracketMap = mutableMapOf( 3120 | '(' to ')', '[' to ']', '{' to '}' 3121 | ) 3122 | val stack = ArrayDeque() 3123 | for (bracket in s) { 3124 | if (bracketMap[stack.peekFirst()] == bracket) { 3125 | stack.pop() 3126 | } else { 3127 | stack.push(bracket) 3128 | } 3129 | } 3130 | 3131 | return stack.isEmpty() 3132 | } 3133 | 3134 | fun removeDuplicateLetters(s: String): String {/* 3135 | Input: s = "cbacdcbc" 3136 | Output: "acdb" 3137 | */ 3138 | 3139 | val duplicate = mutableListOf() 3140 | val seen = mutableSetOf() 3141 | for (char in s) { 3142 | if (seen.contains(char)) { 3143 | duplicate.add(char) 3144 | } else { 3145 | seen.add(char) 3146 | } 3147 | } 3148 | 3149 | return seen.sorted().joinToString("") 3150 | } 3151 | 3152 | fun findDuplicates(nums: IntArray): List { 3153 | val seen = mutableSetOf() 3154 | val duplicate = mutableListOf() 3155 | 3156 | 3157 | for (number in nums) { 3158 | if (seen.contains(number)) { 3159 | duplicate.add(number) 3160 | } else { 3161 | seen.add(number) 3162 | } 3163 | } 3164 | 3165 | return duplicate 3166 | } 3167 | 3168 | fun maxValues(n: String, x: Int): String { 3169 | var isNegative = false 3170 | var number = n 3171 | if (number[0] == '-') { 3172 | isNegative = true 3173 | } 3174 | 3175 | for (i in 0 until n.length) { 3176 | var current = n[i] - '0' 3177 | println("current $current") 3178 | 3179 | if (isNegative.not() && current < x || isNegative && current > x) { 3180 | return "" 3181 | } 3182 | } 3183 | 3184 | return if (isNegative) "-" else "" 3185 | } 3186 | 3187 | fun expressiveWords(s: String, words: Array): Int {/* 3188 | Input: s = "heeellooo", words = ["hello", "hi", "helo"] 3189 | Output: 1 3190 | Explanation: 3191 | We can extend "e" and "o" in the word "hello" to get "heeellooo". 3192 | We can't extend "helo" to get "heeellooo" because the group "ll" is not size 3 or more. 3193 | */ 3194 | var result = 0 3195 | for (word in words) { 3196 | if (word.contentEquals(s)) { 3197 | result += 1 3198 | } 3199 | } 3200 | return result 3201 | } 3202 | 3203 | fun validPalindrome(s: String): Boolean { 3204 | for (i in 0 until s.length) { 3205 | val words = s.trim().toMutableList() 3206 | words.removeAt(i) 3207 | if (isValids(words.joinToString(""))) { 3208 | return true 3209 | } 3210 | } 3211 | 3212 | return false 3213 | } 3214 | 3215 | private fun isValids(s: String): Boolean { 3216 | return s == s.reversed() 3217 | } 3218 | 3219 | fun moveZeroes(nums: IntArray): Unit { 3220 | val movedZeroes = nums 3221 | var nonZeroPosition = 0 3222 | 3223 | for (i in 0 until nums.size) { 3224 | if (movedZeroes[i] != 0) { 3225 | movedZeroes[nonZeroPosition++] = movedZeroes[i] 3226 | } 3227 | } 3228 | 3229 | for (i in nonZeroPosition until nums.size) { 3230 | movedZeroes[i] = 0 3231 | } 3232 | } 3233 | 3234 | fun balancedBrackets(str: String): Boolean { 3235 | val map = mutableMapOf( 3236 | '(' to ')', '[' to ']', '{' to '}' 3237 | ) 3238 | val deque = ArrayDeque() 3239 | 3240 | str.toList().forEach { 3241 | deque.push(it) 3242 | if (it in map.keys) { 3243 | deque.pop() 3244 | } 3245 | } 3246 | 3247 | return deque.isEmpty() 3248 | } 3249 | 3250 | fun intersection(nums1: IntArray, nums2: IntArray): IntArray {/* 3251 | Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] 3252 | Output: [9,4] 3253 | Explanation: [4,9] is also accepted. 3254 | */ 3255 | 3256 | val sets = mutableSetOf() 3257 | 3258 | for (num in nums1) { 3259 | sets.add(num) 3260 | } 3261 | 3262 | val result = mutableListOf() 3263 | 3264 | for (i in nums2) { 3265 | if (sets.contains(i)) { 3266 | result.add(i) 3267 | sets.remove(i) 3268 | } 3269 | } 3270 | 3271 | return result.toIntArray() 3272 | } 3273 | 3274 | fun intersectionII(nums1: IntArray, nums2: IntArray): IntArray {/* 3275 | Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] 3276 | Output: [9,4] 3277 | Explanation: [4,9] is also accepted. 3278 | */ 3279 | 3280 | val sets = mutableSetOf() 3281 | 3282 | for (num in nums2) { 3283 | sets.add(num) 3284 | } 3285 | 3286 | val result = mutableListOf() 3287 | 3288 | for (i in nums1) { 3289 | if (sets.contains(i)) { 3290 | result.add(i) 3291 | sets.remove(i) 3292 | } 3293 | } 3294 | 3295 | return result.toIntArray() 3296 | } 3297 | 3298 | fun isAnagram(s: String, t: String): Boolean { 3299 | return Arrays.equals( 3300 | s.chars().sorted().toArray(), t.chars().sorted().toArray() 3301 | ) 3302 | } 3303 | 3304 | fun merge(intervals: Array): Array { 3305 | Arrays.sort(intervals) { a, b -> 3306 | Integer.compare(a[0], b[0]) 3307 | } 3308 | 3309 | val merged = ArrayDeque() 3310 | 3311 | for (interval in intervals) { 3312 | if (merged.isEmpty() || merged.last[1] < interval[0]) { 3313 | merged.add(interval) 3314 | } else { 3315 | merged.last[1] = Math.max(merged.last[1], interval[1]) 3316 | } 3317 | } 3318 | 3319 | return merged.toArray(arrayOf(intArrayOf(merged.size))) 3320 | } 3321 | 3322 | fun search(nums: IntArray, target: Int): Int { 3323 | return nums.indexOf(target) 3324 | } 3325 | 3326 | fun reverseList(head: ListNode?): ListNode? { 3327 | if (head?.next == null) { 3328 | return head 3329 | } 3330 | 3331 | val reversed = reverseList(head.next) 3332 | head.next!!.next = head 3333 | head.next = null 3334 | return reversed 3335 | } 3336 | 3337 | fun twoSum2(nums: IntArray, target: Int): IntArray { 3338 | 3339 | val map = mutableMapOf() 3340 | 3341 | for (i in 0 until nums.size) { 3342 | val remain = target - nums[i] 3343 | 3344 | if (map.containsKey(remain)) { 3345 | return intArrayOf(map[remain]!!, i) 3346 | } 3347 | 3348 | map[nums[i]] = i 3349 | } 3350 | 3351 | return intArrayOf() 3352 | } 3353 | 3354 | fun mostCommonWord(paragraph: String, banned: Array): String { 3355 | val words = paragraph.toLowerCase().splitToSequence(" ").toList() 3356 | 3357 | 3358 | return "" 3359 | } 3360 | 3361 | fun backspaceCompare(s: String, t: String): Boolean { 3362 | val dequeS = ArrayDeque() 3363 | val dequeT = ArrayDeque() 3364 | 3365 | s.toList().forEach { 3366 | if (it == '#') { 3367 | if (dequeS.isNotEmpty()) { 3368 | dequeS.pop() 3369 | } 3370 | } else { 3371 | dequeS.push(it) 3372 | } 3373 | } 3374 | 3375 | t.toList().forEach { 3376 | if (it == '#') { 3377 | if (dequeT.isNotEmpty()) { 3378 | dequeT.pop() 3379 | } 3380 | } else { 3381 | dequeT.push(it) 3382 | } 3383 | } 3384 | 3385 | return dequeS.joinToString("") == dequeT.joinToString("") 3386 | } 3387 | 3388 | fun filterRestaurants(restaurants: Array, veganFriendly: Int, maxPrice: Int, maxDistance: Int): List { 3389 | val restaurant = mutableListOf() 3390 | 3391 | restaurants.forEach { 3392 | restaurant.add( 3393 | Restaurant(it[0], it[1], it[2], it[3], it[4]) 3394 | ) 3395 | } 3396 | 3397 | restaurant.filter { it.veganFriendly == veganFriendly && it.price <= maxPrice && it.distance <= maxDistance } 3398 | 3399 | return restaurant.map { it.id } 3400 | } 3401 | 3402 | 3403 | data class Restaurant( 3404 | val id: Int, val rating: Int, val veganFriendly: Int, val price: Int, val distance: Int 3405 | ) 3406 | 3407 | fun fizzBuzz(n: Int): List { 3408 | val minstack = ArrayDeque() 3409 | 3410 | 3411 | val solutions = mutableListOf() 3412 | 3413 | for (i in 1..n) { 3414 | if (i / 3 == 0) { 3415 | solutions.add("Fizz") 3416 | } else if (i / 5 == 0) { 3417 | solutions.add("Buzz") 3418 | } else if (i / 5 == 0 && i / 3 == 0) { 3419 | solutions.add("FizzBuzz") 3420 | } else { 3421 | solutions.add("$i") 3422 | } 3423 | } 3424 | 3425 | return solutions 3426 | } 3427 | 3428 | fun encode(num: Int): String {/* 3429 | 3430 | Assume g(n) = "1" + f(n) 3431 | we can find: 3432 | g(0) = "1" g(1) = "10" g(2) = "111" g(3) = "100" g(4) = "101" g(5) = "110" g(6) = "111" 3433 | 3434 | Now everything is obvious: 3435 | 3436 | g(n) = binary(n + 1) 3437 | "1" + f(n) = binary(n + 1) 3438 | f(n) = binary(n + 1).substring(1) 3439 | */ 3440 | return Integer.toBinaryString(num + 1).substring(1) 3441 | } 3442 | 3443 | fun isPalindrome(x: Int): Boolean { 3444 | return "$x" == "$x".reversed() 3445 | } 3446 | 3447 | fun findLengthOfShortestSubarray(arr: IntArray): Int { 3448 | 3449 | //[1,2,3,10,4,2,3,5] 3450 | /* 3451 | The shortest subarray we can remove is [10,4,2] of length 3. 3452 | The remaining elements after that will be [1,2,3,3,5] which are sorted. 3453 | Another correct solution is to remove the subarray [3,10,4]. 3454 | */ 3455 | val removed = mutableListOf() 3456 | 3457 | for (i in 0 until arr.size - 1) { 3458 | if (arr[i] > arr[i + 1]) { 3459 | println(arr[i]) 3460 | removed.add(arr[i]) 3461 | } 3462 | } 3463 | 3464 | return removed.size 3465 | } 3466 | 3467 | fun isSubsequence(s: String, t: String): Boolean { 3468 | return t.subSequence(0..t.length) == s 3469 | } 3470 | 3471 | fun next(`val`: Int): Double { 3472 | val streams = mutableListOf() 3473 | streams.add(`val`) 3474 | streams.add(10) 3475 | streams.add(3) 3476 | streams.add(5) 3477 | return (streams.takeLast(3).sum().toDouble() / streams.size) 3478 | } 3479 | 3480 | private fun sum(size: Int, list: List): Int { 3481 | var sums = 0 3482 | 3483 | return list.takeLast(size).sum() 3484 | } 3485 | 3486 | fun reverseWords(s: String): String { 3487 | 3488 | val sentence = s.trim() 3489 | val words = Arrays.asList(sentence.split("\\s+")) 3490 | 3491 | return words.apply { 3492 | reverse() 3493 | }.joinToString(" ") 3494 | 3495 | } 3496 | 3497 | fun isPalindrome(s: String): Boolean { 3498 | val sentence = s.toLowerCase().replace(" ", "").replace(Regex("[^A-Za-z0-9 ]"), "") 3499 | return sentence == sentence.reversed() 3500 | } 3501 | 3502 | fun addStrings(num1: String, num2: String): String { 3503 | val sum = num1.toBigInteger() + num2.toBigInteger() 3504 | return "$sum" 3505 | } 3506 | 3507 | fun twoSums(nums: IntArray, target: Int): IntArray { 3508 | var firstPointer = 0 3509 | var lastPointer = nums.size - 1 3510 | 3511 | while (firstPointer <= lastPointer) { 3512 | val sum = nums[firstPointer] + nums[lastPointer] 3513 | 3514 | if (sum > target) { 3515 | lastPointer -= 1 3516 | } else if (sum < target) { 3517 | firstPointer += 1 3518 | } else { 3519 | return intArrayOf(firstPointer, lastPointer) 3520 | } 3521 | } 3522 | 3523 | return intArrayOf(firstPointer, lastPointer) 3524 | } 3525 | 3526 | fun compress(chars: CharArray): Int { 3527 | //["a","a","b","b","c","c","c"] 3528 | var indexSize = 0 3529 | var first = 0 3530 | 3531 | while (first < chars.size) { 3532 | var last = first 3533 | 3534 | while (last < chars.size && chars[first] == chars[last]) { 3535 | last++ 3536 | } 3537 | 3538 | chars[indexSize++] = chars[first] 3539 | 3540 | if (last - first > 1) { 3541 | val count = "$${last - first}" 3542 | for (char in count) { 3543 | chars[indexSize++] = char 3544 | } 3545 | } 3546 | 3547 | first = last 3548 | } 3549 | 3550 | return indexSize 3551 | } 3552 | 3553 | fun replaces(text: String) { 3554 | val input = text.trim().toList() 3555 | println(input) 3556 | } 3557 | 3558 | fun isMatchesWith(text: String): Boolean { 3559 | return text.startsWith("(") && text.endsWith(")") 3560 | } 3561 | 3562 | fun findMedianSortedArrays(nums1: IntArray, nums2: IntArray): Double { 3563 | val list = nums1.plus(nums2) 3564 | list.forEach { 3565 | println(it) 3566 | } 3567 | 3568 | list.sort() 3569 | 3570 | return getMedian(list) 3571 | } 3572 | 3573 | fun getMedian(arr: IntArray): Double { 3574 | val size = arr.size 3575 | return if (arr.size % 2 != 0) { 3576 | arr[size / 2].toDouble() 3577 | } else { 3578 | (arr[(size - 1) / 2] + arr[size / 2]) / 2.0 3579 | } 3580 | } 3581 | 3582 | fun twoSum(nums: IntArray, target: Int): IntArray { 3583 | var first = 1 3584 | var last = nums.size - 1 3585 | val pairs = intArrayOf() 3586 | 3587 | while (first < last) { 3588 | if (nums[first] + nums[last] == target) { 3589 | pairs[0] = first 3590 | pairs[1] = last 3591 | } 3592 | 3593 | last-- 3594 | first++ 3595 | } 3596 | 3597 | return pairs 3598 | } 3599 | 3600 | fun licenseKeyFormatting(s: String, k: Int): String { 3601 | val trimmedKey = s.replace("-", "").toUpperCase() 3602 | val chunkedKey = trimmedKey.chunked(k) 3603 | val keyFormatting = StringBuilder() 3604 | 3605 | chunkedKey.forEachIndexed { index, key -> 3606 | keyFormatting.append(key) 3607 | if (index != chunkedKey.lastIndex) { 3608 | keyFormatting.append("-") 3609 | } 3610 | } 3611 | 3612 | return keyFormatting.toString().reversed() 3613 | } 3614 | 3615 | fun multiply(num1: String, num2: String): String { 3616 | val result = num1.toBigInteger() * num2.toBigInteger() 3617 | return "$result" 3618 | } 3619 | -------------------------------------------------------------------------------- /src/main/kotlin/MaxStack.kt: -------------------------------------------------------------------------------- 1 | import java.util.* 2 | 3 | class MaxStack() { 4 | 5 | /** initialize your data structure here. */ 6 | 7 | private val stack = ArrayDeque() 8 | fun push(x: Int) { 9 | stack.push(x) 10 | } 11 | 12 | fun pop(): Int { 13 | return stack.pop() 14 | } 15 | } 16 | 17 | /** 18 | * Your MaxStack object will be instantiated and called as such: 19 | * var obj = MaxStack() 20 | * obj.push(x) 21 | * var param_2 = obj.pop() 22 | * var param_3 = obj.top() 23 | * var param_4 = obj.peekMax() 24 | * var param_5 = obj.popMax() 25 | */ -------------------------------------------------------------------------------- /src/main/kotlin/ProductEncodedArray.kt: -------------------------------------------------------------------------------- 1 | fun main() { 2 | val prod = ProductEncodedArray() 3 | 4 | val input1 = arrayOf( 5 | intArrayOf(1,1), 6 | intArrayOf(2,1), 7 | intArrayOf(1,1), 8 | intArrayOf(2,1), 9 | intArrayOf(1,1) 10 | ) 11 | 12 | val input2 = arrayOf( 13 | intArrayOf(1,1), 14 | intArrayOf(2,1), 15 | intArrayOf(1,1), 16 | intArrayOf(2,1), 17 | intArrayOf(1,1) 18 | ) 19 | 20 | val result = prod.findRLEArray(input1, input2) 21 | println(result) 22 | } 23 | 24 | class ProductEncodedArray { 25 | 26 | /** 27 | * encoded1 = [[1,1],[2,1],[1,1],[2,1],[1,1]] 28 | *encoded2 = [[1,1],[2,1],[1,1],[2,1],[1,1]] 29 | * 30 | * 31 | * 32 | * The product of two run-length encoded arrays encoded1 and encoded2 can be calculated using the following steps: 33 | * 34 | * Expand both encoded1 and encoded2 into the full arrays nums1 and nums2 respectively. 35 | * Create a new array prodNums of length nums1.length and set prodNums[i] = nums1[i] * nums2[i]. 36 | * Compress prodNums into a run-length encoded array and return it. 37 | */ 38 | fun findRLEArray( 39 | encoded1: Array, 40 | encoded2: Array 41 | ): List> { 42 | 43 | val expandedEncoded1 = mutableListOf() 44 | val expandedEncoded2 = mutableListOf() 45 | val prodNums = mutableListOf() 46 | 47 | encoded1.forEach { 48 | expandedEncoded1 += expands(it) 49 | println("expanded1: $expandedEncoded1") 50 | } 51 | 52 | encoded2.forEach { 53 | expandedEncoded2 += expands(it) 54 | println("expanded2: $expandedEncoded2") 55 | } 56 | 57 | 58 | println("expandedEncoded1: $expandedEncoded1") 59 | println("expandedEncoded2: $expandedEncoded2") 60 | for (idx in 0 until expandedEncoded1.size) { 61 | val multiply = expandedEncoded1[idx] * expandedEncoded2[idx] 62 | prodNums.add(idx, multiply) 63 | } 64 | println("prodNums: $prodNums") 65 | 66 | return compress(prodNums) 67 | } 68 | 69 | private fun expands(encoded: IntArray): List { 70 | val expanded = mutableListOf() 71 | var counter = 0 72 | while (counter < encoded[1]) { 73 | expanded.add(encoded[0]) 74 | counter++ 75 | } 76 | 77 | return expanded 78 | } 79 | 80 | private fun compress(list: List): List> { 81 | val result = mutableListOf>() 82 | val group = list.groupingBy { it } 83 | .eachCount() 84 | 85 | group.forEach { (t, u) -> 86 | result.add(listOf(t, u)) 87 | } 88 | 89 | return result 90 | } 91 | } -------------------------------------------------------------------------------- /src/main/kotlin/Randomized.kt: -------------------------------------------------------------------------------- 1 | import kotlin.random.Random 2 | 3 | 4 | class RandomizedSet() { 5 | 6 | private val valueToIdx = mutableMapOf() 7 | private val result = mutableListOf() 8 | 9 | fun insert(`val`: Int): Boolean { 10 | if (valueToIdx.containsKey(`val`)) return false 11 | 12 | result.add(`val`) 13 | valueToIdx[`val`] = result.lastIndex 14 | 15 | return true 16 | } 17 | 18 | fun remove(`val`: Int): Boolean { 19 | if (!valueToIdx.containsKey(`val`)) return false 20 | 21 | val idx = valueToIdx[`val`]!! 22 | if (idx < result.lastIndex) { 23 | val lastVal = result[result.lastIndex] 24 | result[idx] = lastVal 25 | valueToIdx[lastVal] = idx 26 | } 27 | result.removeAt(result.lastIndex) 28 | valueToIdx.remove(`val`) 29 | return true 30 | } 31 | 32 | fun getRandom(): Int { 33 | val randomIdx = Random.nextInt(result.size) 34 | return result[randomIdx] 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /src/main/kotlin/SnakeGame.kt: -------------------------------------------------------------------------------- 1 | import java.util.* 2 | 3 | class SnakeGame(private val width: Int, private val height: Int, private val food: Array) { 4 | 5 | private var foodsStack = arrayOf() 6 | private var snakeBody = ArrayDeque() //initial state of snake 7 | private val visited = mutableSetOf() 8 | private var collectedFood = 0 9 | private var foodIndex = 0 10 | 11 | init { 12 | foodsStack = food 13 | 14 | visited.add(0) 15 | snakeBody.offer(0) 16 | } 17 | 18 | fun move(direction: String): Int { 19 | val head = snakeBody.peekFirst() 20 | val row = head / width 21 | val col = head % width 22 | 23 | var newRow = row 24 | var newCol = col 25 | 26 | //'U', 'D', 'L', or 'R'. 27 | when (direction) { 28 | "U" -> { 29 | newRow-- 30 | } 31 | 32 | "D" -> { 33 | newRow++ 34 | } 35 | 36 | "L" -> { 37 | newCol-- 38 | } 39 | 40 | "R" -> { 41 | newCol++ 42 | } 43 | } 44 | 45 | if (newRow < 0 || newRow >= height || newCol < 0 || newCol >= width) { 46 | return -1 47 | } 48 | 49 | //up or down 50 | if (foodIndex < food.size && newRow == food[foodIndex][0] && newCol == food[foodIndex][1]) { 51 | collectedFood++ 52 | foodIndex++ 53 | } else { 54 | // If not eating, move the tail. 55 | val tail = snakeBody.pollLast() 56 | visited.remove(tail) 57 | } 58 | 59 | val newHead = flatten(newRow, newCol) 60 | 61 | if (visited.contains(newHead)) { 62 | return -1 63 | } 64 | 65 | snakeBody.offerFirst(newHead) 66 | visited.add(newHead) 67 | 68 | return collectedFood 69 | } 70 | 71 | private fun flatten(row: Int, col: Int): Int { 72 | return col + width + row 73 | } 74 | } 75 | 76 | fun main() { 77 | val foods = arrayOf( 78 | intArrayOf(1, 2), 79 | intArrayOf(0, 1) 80 | ) 81 | val game = SnakeGame(3, 2, foods) 82 | 83 | // ["R"],["D"],["R"],["U"],["L"],["U"] 84 | println(game.move("R")) 85 | println(game.move("D")) 86 | println(game.move("R")) 87 | println(game.move("U")) 88 | println(game.move("L")) 89 | println(game.move("U")) 90 | 91 | val result = 10 and 8 92 | println("bitwise $result and is power of two ${isPowerOfTwos(result)}") 93 | } 94 | 95 | private fun isPowerOfTwos(number: Int): Boolean { 96 | return number % 2 == 0 || number % 2 == 1 97 | } -------------------------------------------------------------------------------- /src/main/kotlin/Solution.kt: -------------------------------------------------------------------------------- 1 | class Solution { 2 | val list = mutableListOf>() 3 | 4 | fun levelOrder(root: TreeNode?): List> { 5 | if(root == null) { 6 | return emptyList() 7 | } 8 | 9 | helper(root, 0) 10 | 11 | return list 12 | } 13 | 14 | fun helper(root: TreeNode?, position: Int) { 15 | if(list.size == position) { 16 | list.add(mutableListOf()) 17 | } 18 | 19 | list[position].add(root?.`val` ?: 0) 20 | 21 | if(root?.left != null) { 22 | helper(root.left, list.size + 1) 23 | } 24 | if(root?.right != null) { 25 | helper(root.right, list.size + 1) 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/kotlin/SpaceVector.kt: -------------------------------------------------------------------------------- 1 | 2 | class SparseVector(nums: IntArray) { 3 | // Return the dotProduct of two sparse vectors 4 | fun dotProduct(vec: SparseVector): Int { 5 | 6 | return 0 7 | } 8 | } -------------------------------------------------------------------------------- /src/main/kotlin/SpecialString.kt: -------------------------------------------------------------------------------- 1 | fun main() { 2 | println( 3 | specialStrings( 4 | listOf( 5 | "foobarbaz", 6 | "foo", 7 | "bar", 8 | "foobarfoo", 9 | "baz", 10 | "foobaz", 11 | "foofoofoo", 12 | "foobazar" 13 | ) 14 | ) 15 | ) 16 | } 17 | 18 | fun specialStrings(strings: List): List { 19 | // out put => ["foobarbaz", "foobarfoo", "foobaz", "foofoofoo"] 20 | if (strings.isEmpty()) { 21 | return emptyList() 22 | } 23 | 24 | val result = mutableListOf() 25 | var currentPrefix = strings[0] 26 | for (i in 1 until strings.size) { 27 | if (currentPrefix.contains(strings[i])) { 28 | 29 | } 30 | } 31 | 32 | return result 33 | } -------------------------------------------------------------------------------- /src/main/kotlin/SupportX.kt: -------------------------------------------------------------------------------- 1 | class SupportX { 2 | 3 | } -------------------------------------------------------------------------------- /src/main/kotlin/TaskServer.kt: -------------------------------------------------------------------------------- 1 | import java.util.* 2 | 3 | 4 | class TaskServer { 5 | fun assignTasks(servers: IntArray, tasks: IntArray): IntArray { 6 | val availableServer = PriorityQueue { server1, server2 -> 7 | if (server1[0] == server2[0]) { 8 | server1[1] - server2[1] 9 | } else server1[0] - server2[0] 10 | } 11 | 12 | //timefree, weight of server, index 13 | val unavailableServer = PriorityQueue( 14 | Comparator { server1: IntArray, server2: IntArray -> 15 | if (server1[0] == server2[0]) { 16 | return@Comparator if (server1[1] == server2[1]) server1[2] - server2[2] else server1[1] - server2[1] 17 | } 18 | server1[0] - server2[0] 19 | } 20 | ) 21 | 22 | val result = IntArray(tasks.size) 23 | 24 | for (i in servers.indices) { 25 | availableServer.offer(intArrayOf(servers[i], i)) 26 | } 27 | 28 | //time free tracker 29 | var timeFree = 0 30 | 31 | 32 | 33 | for (i in tasks.indices) { 34 | val duration = tasks[i] 35 | 36 | // Release all servers that have completed their tasks by this second. 37 | while(unavailableServer.isNotEmpty() && unavailableServer.peek()[0] <= timeFree) { 38 | val server = unavailableServer.poll() 39 | availableServer.offer(intArrayOf(server[1], server[2])) 40 | } 41 | 42 | // assign to task to current server 43 | if(availableServer.isNotEmpty()){ 44 | val server = availableServer.poll() 45 | result[timeFree++] = server[1] 46 | unavailableServer.offer(intArrayOf(i + duration, server[0], server[1])) 47 | } else { 48 | val server = unavailableServer.poll() 49 | result[timeFree++] = server[2] 50 | unavailableServer.offer(intArrayOf(server[0] + duration, server[1], server[2])) 51 | } 52 | } 53 | 54 | 55 | 56 | return result 57 | } 58 | } -------------------------------------------------------------------------------- /src/main/kotlin/TimeSpend.kt: -------------------------------------------------------------------------------- 1 | 2 | class TimeSpend { 3 | 4 | /** 5 | * static String [][] requests = { 6 | * {"create", "xyz", "1", "1619916081"}, // Sat May 01 2021 17:41:21 GMT-0700 7 | * {"join", "xyz", "2", "1619916681"}, // Sat May 01 2021 17:51:21 GMT-0700 8 | * {"create", "abc", "3", "1619916881"}, //12:01 9 | * {"leave", "xyz", "2", "1619920281"}, 10 | * {"join", "abc", "4", "1619920881"}, 11 | * {"create", "ghi", "5", "1619923999"}, 12 | * {"leave", "xyz", "1", "1619923881"}, 13 | * {"leave", "abc", "3", "1619927481"}, //12:07 time spent = 6 minutes 14 | * {"leave", "abc", "4", "1619927481"}, 15 | * {"leave", "ghi", "5", "1619958001"} 16 | * }; 17 | */ 18 | 19 | val spaces = mutableMapOf>() 20 | 21 | fun create(spaceId: String, id: String) { 22 | val availableSpace = spaces.getOrDefault(spaceId, mutableListOf()) 23 | 24 | val isNotExist = availableSpace.none { user -> 25 | user.userId == id 26 | } 27 | 28 | if (isNotExist) { 29 | availableSpace.add(UsersTime(id, System.currentTimeMillis())) 30 | } 31 | println("created $spaces") 32 | } 33 | 34 | fun join(spaceId: String, id: String) { 35 | val availableSpace = spaces.getOrDefault(spaceId, mutableListOf()) 36 | 37 | availableSpace.first { it.userId == id } 38 | .copy(joinedAt = System.currentTimeMillis()) 39 | println("joined $spaces") 40 | } 41 | 42 | fun leave(spaceId: String, id: String): Int { 43 | val availableSpace = spaces.getOrDefault(spaceId, mutableListOf()) 44 | 45 | return (System.currentTimeMillis() - availableSpace.first { it.userId == id } 46 | .joinedAt).toInt() 47 | } 48 | } 49 | 50 | data class UsersTime( 51 | val userId: String, 52 | val createdAt: Long, 53 | var joinedAt: Long = 0 54 | ) 55 | 56 | fun main() { 57 | val timeSpend = TimeSpend() 58 | 59 | timeSpend.create("xyz", "1") 60 | timeSpend.create("xyz", "1") 61 | } -------------------------------------------------------------------------------- /src/main/kotlin/TreeNode.kt: -------------------------------------------------------------------------------- 1 | 2 | class TreeNode(var `val`: Int = 0) { 3 | var left: TreeNode? = null 4 | var right: TreeNode? = null 5 | } -------------------------------------------------------------------------------- /src/main/kotlin/Trie.kt: -------------------------------------------------------------------------------- 1 | class Trie { 2 | 3 | private val children: Array = arrayOfNulls(26) 4 | 5 | // isEndOfWord is true if the node represents the end of a word. 6 | private var isEndOfWord: Boolean = false; 7 | 8 | fun insert(word: String) { 9 | var currentNode = this 10 | for (char in word) { 11 | val index = char - 'a' //get the index from ASCII code 12 | 13 | //if the character not exist in the child, initialize new object 14 | if (currentNode.children[index] == null) { 15 | currentNode.children[index] = Trie() 16 | } 17 | 18 | //move trie to the next node -> which mean append to last of childern 19 | currentNode = currentNode.children[index]!! 20 | } 21 | 22 | // mark the character as the last of char in the list 23 | currentNode.isEndOfWord = true 24 | } 25 | 26 | fun search(word: String): Boolean { 27 | val currentNode = searchPrefix(word) 28 | 29 | return currentNode != null && currentNode.isEndOfWord 30 | } 31 | 32 | fun startsWith(prefix: String): Boolean { 33 | val currentNode = searchPrefix(prefix) 34 | 35 | return currentNode != null 36 | } 37 | 38 | //helper function to find the prefix character from query 39 | private fun searchPrefix(query: String): Trie? { 40 | var currentNode = this 41 | for (char in query) { 42 | val index = char - 'a' 43 | if (currentNode.children[index] == null) { 44 | //return null if query not exist in the children 45 | return null 46 | } 47 | 48 | currentNode = currentNode.children[index]!! 49 | } 50 | 51 | return currentNode 52 | } 53 | } 54 | 55 | fun main() { 56 | val trie = Trie() 57 | 58 | //["Trie","insert","search","search","startsWith","insert","search"] 59 | //[[],["apple"],["apple"],["app"],["app"],["app"],["app"]] 60 | trie.insert("apple").printObject() 61 | trie.search("apple").printObject() 62 | trie.search("app").printObject() 63 | trie.startsWith("app").printObject() 64 | trie.insert("app").printObject() 65 | trie.search("app").printObject() 66 | } 67 | 68 | fun Any.printObject(): Any { 69 | return apply { 70 | println(this) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/kotlin/TweetCountPerFrequency.kt: -------------------------------------------------------------------------------- 1 | import java.util.* 2 | 3 | class TweetCounts() { 4 | 5 | private val tweetsStorage = mutableMapOf>() 6 | 7 | fun recordTweet(tweetName: String, time: Int) { 8 | tweetsStorage.getOrPut(tweetName) { TreeMap() }[time] = tweetsStorage[tweetName]?.get(time)?.inc() ?: 1 9 | 10 | tweetsStorage.values.forEach { 11 | println(it) 12 | } 13 | } 14 | 15 | fun getTweetCountsPerFrequency(freq: String, tweetName: String, startTime: Int, endTime: Int): List { 16 | if (tweetsStorage.isEmpty()) return emptyList() 17 | 18 | val tweets = tweetsStorage[tweetName] 19 | if (tweets.isNullOrEmpty()) return emptyList() 20 | 21 | val chunkType = ChunkFrequency.getChunkType(freq) 22 | 23 | val intervalSize = chunkType.timeInSecond 24 | 25 | val result = mutableListOf() 26 | 27 | var currentTime = startTime 28 | 29 | while (currentTime <= endTime) { 30 | val key = tweets.floorKey(currentTime) 31 | val frequency = if (key != null && key <= endTime) { 32 | tweets[key]!! 33 | } else { 34 | 0 35 | } 36 | 37 | result.add(frequency) 38 | currentTime += intervalSize 39 | } 40 | 41 | return result 42 | } 43 | } 44 | 45 | /** 46 | * Your TweetCounts object will be instantiated and called as such: 47 | * var obj = TweetCounts() 48 | * obj.recordTweet(tweetName,time) 49 | * var param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime) 50 | */ 51 | 52 | enum class ChunkFrequency(val timeInSecond: Int) { 53 | MINUTE(60), 54 | HOUR(3600), 55 | DAY(86400), 56 | UNKNOWN(-1); 57 | 58 | companion object { 59 | fun getChunkType(freq: String): ChunkFrequency { 60 | return when (freq) { 61 | "minute" -> MINUTE 62 | 63 | "hour" -> HOUR 64 | 65 | "day" -> DAY 66 | 67 | else -> UNKNOWN 68 | } 69 | } 70 | } 71 | } 72 | 73 | fun main() { 74 | val tweets = TweetCounts() 75 | 76 | tweets.recordTweet("tw", 0) 77 | tweets.recordTweet("tw", 40) 78 | tweets.recordTweet("tw", 20) 79 | tweets.recordTweet("tw", 59) 80 | tweets.recordTweet("tw", 9) 81 | println(tweets.getTweetCountsPerFrequency("minute", "tw", 0, 50)) 82 | } -------------------------------------------------------------------------------- /src/main/kotlin/Twitter.kt: -------------------------------------------------------------------------------- 1 | class Twitter { 2 | 3 | private val userToTweets = mutableListOf>() 4 | 5 | // userId to followers 6 | private val userToMapFriends = mutableMapOf>() 7 | 8 | fun postTweet(userId: Int, tweetId: Int) { 9 | userToTweets.add(userId to tweetId) 10 | } 11 | 12 | fun getNewsFeed(userId: Int): List { 13 | return userToTweets.filter { tweets -> 14 | userToMapFriends[userId]?.contains(tweets.first) == true || tweets.first == userId 15 | }.map { 16 | it.second 17 | }.takeLast(10) 18 | .reversed() 19 | } 20 | 21 | /** 22 | * The user with ID followerId started following the user with ID followeeId. 23 | */ 24 | fun follow(followerId: Int, followeeId: Int) { 25 | userToMapFriends[followerId]?.add(followeeId) ?: run { 26 | userToMapFriends[followerId] = mutableListOf() 27 | userToMapFriends[followerId]?.add(followeeId) 28 | } 29 | } 30 | 31 | fun unfollow(followerId: Int, followeeId: Int) { 32 | userToMapFriends[followerId]?.remove(followeeId) 33 | } 34 | } 35 | 36 | fun main() { 37 | val twitter = Twitter() 38 | 39 | //postTweet [1,5] 40 | twitter.postTweet(1, 5) 41 | 42 | //follow [1,2] 43 | twitter.follow(1, 2) 44 | 45 | //follow [2,1] 46 | twitter.follow(2, 1) 47 | 48 | //getNewsFeed 2 49 | twitter.getNewsFeed(2) 50 | 51 | //postTweet 2,6 52 | twitter.postTweet(2, 6) 53 | 54 | // getNewsFeed 1 55 | twitter.getNewsFeed(1) 56 | 57 | //getNewsFeed 2 58 | twitter.getNewsFeed(2) 59 | 60 | //unfollow 2, 1 61 | twitter.unfollow(2, 1) 62 | 63 | //getNewsFeed 1 64 | twitter.getNewsFeed(1) 65 | 66 | //getNewsFeed 2 67 | twitter.getNewsFeed(2) 68 | 69 | //unfollow 2, 1 70 | twitter.unfollow(1, 2) 71 | 72 | // getNewsFeed 1 73 | twitter.getNewsFeed(1) 74 | 75 | //getNewsFeed 2 76 | twitter.getNewsFeed(2) 77 | } -------------------------------------------------------------------------------- /src/main/kotlin/ValidateIP.kt: -------------------------------------------------------------------------------- 1 | class ValidateIP { 2 | 3 | fun validIPAddress(queryIP: String): String { 4 | return when { 5 | isIPv4Type(queryIP) -> IpType.IPV4.type 6 | isIPv6Type(queryIP) -> IpType.IPV6.type 7 | else -> IpType.NEITHER.type 8 | } 9 | } 10 | 11 | /** 12 | * "x1.x2.x3.x4" where 0 <= xi <= 255 and xi cannot contain leading zeros. For example, 13 | * "192.168.1.1" and "192.168.1.0" are valid IPv4 addresses while "192.168.01.1", "192.168.1.00", and 14 | * "192.168@1.1" are invalid IPv4 addresses. 15 | */ 16 | private fun isIPv4Type(query: String): Boolean { 17 | val zeroTo255 = "([0-9]|[1-9]\\d{1}|1\\d{2}|2[0-4]\\d|25[0-5])" 18 | val rgv4 = "$zeroTo255\\.$zeroTo255\\.$zeroTo255\\.$zeroTo255" 19 | val v4Reg = Regex(rgv4) 20 | return query.matches(v4Reg) 21 | } 22 | 23 | /** 24 | * A valid IPv6 address is an IP in the form "x1:x2:x3:x4:x5:x6:x7:x8" where: 25 | * 26 | * 1 <= xi.length <= 4 27 | * 28 | * xi is a hexadecimal string which may contain digits, lowercase English letter ('a' to 'f') 29 | * and upper-case English letters ('A' to 'F'). 30 | * 31 | * Leading zeros are allowed in xi. 32 | */ 33 | private fun isIPv6Type(query: String): Boolean { 34 | val fourHexa = "^[0-9A-Fa-f]+\$" 35 | val split = query.split(":") 36 | 37 | if (split.size < 8) return false 38 | 39 | for (address in split) { 40 | if (address.length > 4 || !address.matches(Regex(fourHexa))) { 41 | return false 42 | } 43 | } 44 | 45 | return true 46 | } 47 | 48 | } 49 | 50 | enum class IpType(val type: String) { 51 | IPV4("IPv4"), 52 | IPV6("IPv6"), 53 | NEITHER("Neither") 54 | } -------------------------------------------------------------------------------- /src/main/kotlin/Vector2D.kt: -------------------------------------------------------------------------------- 1 | import java.util.LinkedList 2 | 3 | class Vector2D(vec: Array) { 4 | private val vector = LinkedList() 5 | 6 | init { 7 | initializeVector(vec) 8 | println(vector) 9 | } 10 | 11 | fun next(): Int { 12 | return vector.removeFirst() 13 | } 14 | 15 | fun hasNext(): Boolean { 16 | return vector.isNotEmpty() 17 | } 18 | 19 | private fun initializeVector(vec: Array) { 20 | 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/kotlin/WordDistance.kt: -------------------------------------------------------------------------------- 1 | class WordDistance(wordsDict: Array) { 2 | 3 | private val dictionary = mutableListOf() 4 | init { 5 | dictionary.addAll(wordsDict) 6 | } 7 | fun shortest(word1: String, word2: String): Int { 8 | val first = dictionary.indexOf(word1) 9 | val second = dictionary.indexOf(word2) 10 | 11 | return if (first > second) { 12 | first - second 13 | } else { 14 | second - first 15 | } 16 | } 17 | 18 | } 19 | 20 | fun main() { 21 | val dictionary = arrayOf("practice", "makes", "perfect", "coding", "makes") 22 | val word = WordDistance(dictionary) 23 | 24 | //3 - 0 25 | println(word.shortest("coding", "practice")) 26 | 27 | //1-3 => 28 | println(word.shortest("makes", "coding")) 29 | } -------------------------------------------------------------------------------- /src/main/kotlin/algoexpert/AlgoMain.kt: -------------------------------------------------------------------------------- 1 | package algoexpert 2 | 3 | import java.util.* 4 | 5 | fun main() { 6 | println( 7 | runLengthEncoding("AAAAAAAAAAAAABBCCCCDD") 8 | ) 9 | } 10 | 11 | fun tournamentWinner(competitions: List>, results: List): String { 12 | val rank = mutableMapOf() 13 | 14 | for(i in 0 until competitions.size) { 15 | val homeAway = results[i] 16 | val winner = getWinner(competitions[i], homeAway) 17 | rank[winner] = rank.getOrDefault(winner, 0) + 1 18 | } 19 | 20 | val result = rank.maxBy { it.value } 21 | return result?.key.orEmpty() 22 | } 23 | 24 | private fun getWinner(list: List, winner: Int): String { 25 | return if (winner == 0) { 26 | list[1] 27 | } else { 28 | list[0] 29 | } 30 | } 31 | 32 | fun shortenPath(path: String): String { 33 | /* 34 | /foo/bar/baz 35 | */ 36 | val split = path.replace("//","/") 37 | .split("/") 38 | 39 | println(split) 40 | val builder = StringBuilder() 41 | 42 | var idx = split.size - 1 43 | while (idx != 0) { 44 | val dir = split[idx] 45 | if (dir == "..") { 46 | idx -= 2 47 | } else if(dir != ".") { 48 | builder.append("$dir/") 49 | idx-- 50 | } 51 | } 52 | 53 | return builder.toString() 54 | } 55 | 56 | fun underscorifySubstring(string: String, substring: String): String { 57 | return string.replace(substring, "_${substring}_") 58 | } 59 | 60 | fun permutations(array: List): MutableList> { 61 | val perm = mutableListOf>() 62 | permutationHelper(0, array.toMutableList(), perm) 63 | return perm 64 | } 65 | 66 | private fun permutationHelper(idx: Int, array: MutableList, permutation: MutableList>) { 67 | if(idx == array.size - 1) { 68 | permutation.add(array.toList()) 69 | return 70 | } 71 | 72 | for (j in idx until array.size){ 73 | permSwap(array, idx, j) 74 | permutationHelper(idx+1, array, permutation) 75 | permSwap(array, idx, j) 76 | } 77 | } 78 | 79 | private fun permSwap(array: MutableList, i: Int, j:Int) { 80 | val temp = array[i] 81 | array[i] = array[j] 82 | array[j] = temp 83 | } 84 | 85 | fun balancedBrackets(str: String): Boolean { 86 | val map = mutableMapOf( 87 | '(' to ')', 88 | '[' to ']', 89 | '{' to '}' 90 | ) 91 | 92 | val deque = ArrayDeque() 93 | val open = "({[" 94 | val close = ")]}" 95 | 96 | for(bracket in str) { 97 | if (str.contains(open)) { 98 | deque.push(bracket) 99 | } else { 100 | if (deque.size == 0) { 101 | return false 102 | } 103 | 104 | if (deque.peek() == map[bracket]){ 105 | deque.pop() 106 | } else { 107 | return false 108 | } 109 | } 110 | } 111 | 112 | return deque.isEmpty() 113 | } 114 | 115 | 116 | fun generateDocument(characters: String, document: String): Boolean { 117 | val charMap = mutableMapOf() 118 | 119 | for(char in characters) { 120 | if(char !in charMap) { 121 | charMap[char] = 0 122 | } 123 | 124 | charMap[char] = charMap.getOrDefault(char, 0) + 1 125 | } 126 | 127 | for(doc in document) { 128 | if(doc !in charMap || charMap[doc] == 0) { 129 | return false 130 | } 131 | 132 | charMap[doc] = charMap.getOrDefault(doc, 0) - 1 133 | } 134 | 135 | return true 136 | } 137 | 138 | fun runLengthEncoding(string: String): String { 139 | var counter = 0 140 | var builder = StringBuilder() 141 | 142 | if (string.length < 2) { 143 | return string 144 | } 145 | 146 | for(i in 1 until string.length) { 147 | if (builder[i] == builder[i-1]) { 148 | counter++ 149 | builder.append("$counter${string[i-1]}") 150 | } else { 151 | counter = 0 152 | builder.append("${string[i-1]}") 153 | } 154 | } 155 | 156 | return string 157 | } -------------------------------------------------------------------------------- /src/main/kotlin/algoexpert/BFS.kt: -------------------------------------------------------------------------------- 1 | package algoexpert 2 | 3 | import java.util.* 4 | 5 | class Node(name: String) { 6 | val name: String = name 7 | val children = mutableListOf() 8 | 9 | fun breadthFirstSearch(): List { 10 | val queue = ArrayDeque() 11 | val result = mutableListOf() 12 | 13 | queue.add(this) 14 | while(queue.size != 0) { 15 | val currentNode = queue.poll() 16 | result.add(currentNode.name) 17 | queue.addAll(currentNode.children) 18 | } 19 | 20 | return result 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/kotlin/algoexpert/BalanceIndex.kt: -------------------------------------------------------------------------------- 1 | package algoexpert 2 | 3 | fun main() { 4 | val result = balanceIndex(listOf(0, 9, -8, 2, 7, 1, 11, -2, 1)) 5 | println(result) 6 | } 7 | 8 | fun balanceIndex(array: List): Int { 9 | var first = 0 10 | var last = array.size - 1 11 | val listSize = array.size - 1 12 | var maxSum = 0 13 | 14 | while(first < last) { 15 | val left = getSumValue(array, 0, first) 16 | val right = getSumValue(array, listSize, last) 17 | 18 | if(left > right) { 19 | last-- 20 | } else if (left < right){ 21 | first++ 22 | } else if (left == right){ 23 | return first 24 | } 25 | } 26 | 27 | return -1 28 | } 29 | 30 | fun getSumValue(array: List, start: Int, end: Int): Int { 31 | var sum = 0 32 | 33 | sum = array.subList(start, end).sum() 34 | 35 | println("total value $sum, $start, $end") 36 | return sum 37 | } 38 | -------------------------------------------------------------------------------- /src/main/kotlin/algoexpert/BuildFailure.kt: -------------------------------------------------------------------------------- 1 | package algoexpert 2 | 3 | fun main() { 4 | 5 | } 6 | 7 | fun buildFailures(buildRuns: List>): Int { 8 | var count = -1 9 | var max = 0 10 | for(ci in buildRuns) { 11 | if (max < calculateSuccessPercentage(ci)) { 12 | count++ 13 | max = Math.max(calculateSuccessPercentage(ci), max) 14 | } 15 | } 16 | 17 | return count 18 | } 19 | 20 | fun calculateSuccessPercentage(list: List): Int { 21 | return list.count { it.not() } 22 | } -------------------------------------------------------------------------------- /src/main/kotlin/algoexpert/LruCache.kt: -------------------------------------------------------------------------------- 1 | package algoexpert 2 | 3 | import java.util.LinkedHashMap 4 | 5 | fun main() { 6 | 7 | } 8 | 9 | class LRUCache(private val maxSize: Int): LinkedHashMap(maxSize, 0.75F, true) { 10 | fun insertKeyValuePair(key: String, value: Int) { 11 | super.put(key, value) 12 | } 13 | 14 | fun getValueFromKey(key: String): Int? { 15 | return super.get(key) 16 | } 17 | 18 | fun getMostRecentKey(): String? { 19 | return super.keys.last() 20 | } 21 | 22 | override fun removeEldestEntry(eldest: MutableMap.MutableEntry?): Boolean { 23 | return size > maxSize 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/kotlin/algoexpert/MinHeap.kt: -------------------------------------------------------------------------------- 1 | package algoexpert 2 | 3 | import java.util.* 4 | 5 | class MinHeap(array: MutableList) { 6 | val heap = this.buildHeap(array) 7 | private val queue = PriorityQueue() 8 | 9 | fun buildHeap(array: MutableList): MutableList { 10 | 11 | return array 12 | } 13 | 14 | fun siftDown(currentIdx: Int, endIdx: Int, heap: MutableList) { 15 | // Write your code here. 16 | } 17 | 18 | fun siftUp(currentIdx: Int, heap: MutableList) { 19 | // Write your code here. 20 | } 21 | 22 | fun peek(): Int? { 23 | // Write your code here. 24 | return -1 25 | } 26 | 27 | fun remove(): Int? { 28 | // Write your code here. 29 | return -1 30 | } 31 | 32 | fun insert(value: Int) { 33 | // Write your code here. 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/kotlin/algoexpert/PhoneNumber.kt: -------------------------------------------------------------------------------- 1 | package algoexpert 2 | 3 | fun main() { 4 | 5 | } 6 | 7 | val map = mutableMapOf( 8 | '2' to charArrayOf('a','b','c'), 9 | '3' to charArrayOf('d','e','f'), 10 | '4' to charArrayOf('g','h','i'), 11 | '5' to charArrayOf('j','k','l'), 12 | '6' to charArrayOf('m','n','o'), 13 | '7' to charArrayOf('p','q','r', 's'), 14 | '8' to charArrayOf('t','u','v'), 15 | '9' to charArrayOf('w','x','y', 'z') 16 | ) 17 | 18 | fun phoneNumberMnemonics(phoneNumber: String): List { 19 | // Write your code here. 20 | val result = mutableListOf() 21 | dfs(phoneNumber.toCharArray(), result, StringBuilder()) 22 | return result 23 | } 24 | 25 | fun dfs(number: CharArray, helper: MutableList, path: StringBuilder) { 26 | if(path.length == number.size) { 27 | helper.add(path.toString()) 28 | return 29 | } 30 | 31 | val nextDigit = number[path.length] 32 | for(letter in map.getOrDefault(nextDigit, charArrayOf())) { 33 | path.append(letter) 34 | dfs(number, helper, path) 35 | path.deleteCharAt(path.length - 1) 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/kotlin/algoexpert/RepeatedMatrix.kt: -------------------------------------------------------------------------------- 1 | package algoexpert 2 | 3 | fun repeatedMatrixValues(matrix: List>): List { 4 | val result = mutableListOf() 5 | val repeatedMap = mutableMapOf() 6 | 7 | for (row in 0 until matrix.size) { 8 | for (col in 0 until matrix[0].size) { 9 | val repeat = matrix[row][col] 10 | repeatedMap[repeat] = repeatedMap.getOrDefault(repeat, 0) + 1 11 | } 12 | } 13 | 14 | for ((key, value ) in repeatedMap) { 15 | if (value >= matrix.size) { 16 | result.add(key) 17 | } 18 | } 19 | 20 | repeatedMap.mapValues { 21 | if (it.value > matrix.size) { 22 | result.add(it.key) 23 | } 24 | } 25 | return result 26 | } -------------------------------------------------------------------------------- /src/main/kotlin/algomonster/BinarySearch.java: -------------------------------------------------------------------------------- 1 | package algomonster; 2 | 3 | import java.util.List; 4 | 5 | public class BinarySearch { 6 | public static void main(String[] args) { 7 | 8 | } 9 | 10 | public static int binarySearch(List arr, int target) { 11 | int first = 0; 12 | int last = arr.size() - 1; 13 | 14 | while(first <= last) { 15 | int mid = (first + last) / 2; 16 | 17 | if(arr.get(mid) == target) { 18 | return mid; 19 | } else if(arr.get(mid) < target) { 20 | first = mid + 1; 21 | } else { 22 | last = mid - 1; 23 | } 24 | } 25 | 26 | return -1; 27 | } 28 | 29 | public static int findBoundary(boolean[] arr) { 30 | int first = 0; 31 | int last = arr.length - 1; 32 | int result = -1; 33 | while(first <= last) { 34 | int mid = first + (last-first) / 2; 35 | 36 | if(arr[mid]) { 37 | result = mid; 38 | first = mid + 1; 39 | } else { 40 | last = mid - 1; 41 | } 42 | } 43 | 44 | return result; 45 | } 46 | 47 | public static int firstNotSmaller(List arr, int target) { 48 | int first = 0; 49 | int last = arr.size() - 1; 50 | int idx = -1; 51 | 52 | while(first <= last) { 53 | int mid = first + (last - first) / 2; 54 | 55 | if(arr.get(mid) >= target) { 56 | idx = mid; 57 | last = mid - 1; 58 | } else { 59 | first = mid + 1; 60 | } 61 | } 62 | 63 | return idx; 64 | } 65 | 66 | public static int findFirstOccurrence(List arr, int target) { 67 | int first = 0; 68 | int last = arr.size() - 1; 69 | int firstIdx = -1; 70 | 71 | while(first <= last) { 72 | int mid = first + (last-first)/2; 73 | 74 | if (arr.get(mid) == target) { 75 | firstIdx = mid; 76 | last = mid - 1; 77 | } else if (arr.get(mid) < target) { 78 | first = mid + 1; 79 | } else { 80 | last = mid - 1; 81 | } 82 | } 83 | 84 | return firstIdx; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/kotlin/algomonster/PlayingCards.java: -------------------------------------------------------------------------------- 1 | package algomonster; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | 7 | public class PlayingCards { 8 | public static void main(String[] args) { 9 | 10 | } 11 | 12 | public static class Game { 13 | HashMap deck; 14 | public Game() { 15 | deck = new HashMap<>(); 16 | } 17 | 18 | public void addCard(String suit, String value) { 19 | deck.put(suit, value); 20 | } 21 | 22 | public String cardString(int card) { 23 | 24 | return ""; 25 | } 26 | 27 | public boolean cardBeats(int cardA, int cardB) { 28 | // Implement function here 29 | return false; 30 | } 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/main/kotlin/algomonster/TwoPointers.java: -------------------------------------------------------------------------------- 1 | package algomonster; 2 | 3 | import java.util.List; 4 | 5 | public class TwoPointers { 6 | public static void main(String[] args) { 7 | 8 | } 9 | 10 | public static int removeDuplicates(List arr) { 11 | return 0; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/kotlin/algomonster/ValidParent.java: -------------------------------------------------------------------------------- 1 | package algomonster; 2 | 3 | import java.util.ArrayDeque; 4 | import java.util.HashMap; 5 | 6 | public class ValidParent { 7 | public static void main(String[] args) { 8 | boolean result = validParent("([][]{}){}{"); 9 | 10 | System.out.println(result); 11 | }; 12 | 13 | public static boolean validParent(String s) { 14 | HashMap validMap = new HashMap<>(); 15 | validMap.put('(', ')'); 16 | validMap.put('[', ']'); 17 | validMap.put('{', '}'); 18 | 19 | ArrayDeque deque = new ArrayDeque<>(); 20 | 21 | //([][]{}){}{ 22 | String bracketList = "{}()[]"; 23 | for (char bracket: s.toCharArray()) { 24 | if (validMap.getOrDefault(deque.peekFirst(), ' ') == bracket) { 25 | deque.pop(); 26 | } else { 27 | if (isContains(bracket)) { 28 | deque.add(bracket); 29 | } 30 | } 31 | } 32 | 33 | return deque.isEmpty(); 34 | }; 35 | 36 | public static boolean isContains(char bracket) { 37 | String bracketList = "{}()[]"; 38 | 39 | for(char item: bracketList.toCharArray()) { 40 | if (item != bracket) { 41 | return false; 42 | } 43 | } 44 | 45 | return true; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/kotlin/foobar/FoobarMain.kt: -------------------------------------------------------------------------------- 1 | package foobar 2 | 3 | fun main() { 4 | val result = elevatorMaintenance(arrayOf("1.11", "2.0.0", "1.2", "2", "0.1", "1.2.1", "1.1.1", "2.0")) 5 | result.map { 6 | println(it) 7 | } 8 | } 9 | 10 | fun elevatorMaintenance(l: Array): Array> { 11 | val list = mutableListOf>() 12 | 13 | for (version in l) { 14 | list.add( 15 | version.split(".") 16 | ) 17 | } 18 | list.sortWith(Comparator { o1, o2 -> 19 | var idx = 0 20 | while (idx < Math.min(o1.size, o2.size)) { 21 | val parse = Integer.compare( 22 | Integer.parseInt(o1[idx]), 23 | Integer.parseInt(o2[idx]) 24 | ) 25 | 26 | if (parse != 0) { 27 | return@Comparator parse 28 | } 29 | idx++ 30 | } 31 | 32 | return@Comparator Integer.compare(o1.size, o2.size) 33 | }) 34 | 35 | return arrayOf( 36 | list.map { 37 | it.joinToString(".") 38 | } 39 | ) 40 | 41 | } -------------------------------------------------------------------------------- /src/main/kotlin/foobar/FuelInjection.java: -------------------------------------------------------------------------------- 1 | package foobar; 2 | 3 | public class FuelInjection { 4 | public static void main(String[] args) { 5 | System.out.println(solution("15")); 6 | } 7 | 8 | public static int solution(String x) { 9 | 10 | if(x == "0") { 11 | return 0; 12 | } 13 | 14 | int fuel = Integer.getInteger(x); 15 | /* 16 | - add fuel pallet 17 | - remove one fuel pallet 18 | - divide by 2 19 | */ 20 | 21 | if(fuel % 2 != 0) { 22 | fuel -= 1; 23 | } 24 | 25 | while(fuel < 0) { 26 | fuel /= 2; 27 | } 28 | 29 | return fuel; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/kotlin/foobar/FuelInjections.kt: -------------------------------------------------------------------------------- 1 | package foobar 2 | 3 | fun main() { 4 | println(solution("4")) 5 | } 6 | 7 | fun solution(x: String): Int { 8 | var fuel = x.toInt() 9 | var counter = 0 10 | if (x == "0") { 11 | return 0 12 | } 13 | 14 | if(fuel % 4 != 0) { 15 | fuel += 1 16 | counter++ 17 | } 18 | 19 | while (fuel > 1) { 20 | fuel /= 2 21 | counter++ 22 | } 23 | 24 | return counter 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/foobar/SkippingWork.kt: -------------------------------------------------------------------------------- 1 | package foobar 2 | 3 | fun main() { 4 | println( 5 | solution( 6 | intArrayOf(13, 5, 2, 6, 5), 7 | intArrayOf(13, 5, 2, 5) 8 | ) 9 | ) 10 | } 11 | 12 | fun solution(x: IntArray, y: IntArray): Int { 13 | var result = 0 14 | if (x.size > y.size) { 15 | for (id in x) { 16 | if (!y.contains(id)) { 17 | result = id 18 | } 19 | } 20 | } else { 21 | for (id in y) { 22 | if (!x.contains(id)) { 23 | result = id 24 | } 25 | } 26 | } 27 | 28 | return result 29 | } -------------------------------------------------------------------------------- /src/main/kotlin/foobar/SolarDoomsday.java: -------------------------------------------------------------------------------- 1 | package foobar; 2 | 3 | import java.util.ArrayDeque; 4 | import java.util.Arrays; 5 | 6 | public class SolarDoomsday { 7 | public static void main(String[] args) { 8 | 9 | } 10 | 11 | public static int[] solution(int area) { 12 | int[] result = {}; 13 | 14 | int idx = area; 15 | 16 | while(idx >= 1) { 17 | while (Arrays.stream(result).sum() < area){ 18 | 19 | } 20 | } 21 | return result; 22 | } 23 | 24 | public static int helper(int value) { 25 | return (int) (Math.sqrt(value) + 0.5); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/kotlin/hackerrank/CountPairs.kt: -------------------------------------------------------------------------------- 1 | package hackerrank 2 | 3 | fun countPairs(arr: Array): Long { 4 | var count = 0L 5 | 6 | for (i in arr.indices) { 7 | for (j in i + 1 until arr.size) { 8 | val bitwiseAnd = arr[i] and arr[j] 9 | if (isPowerOfTwo(bitwiseAnd)) { 10 | count++ 11 | } 12 | } 13 | } 14 | 15 | return count 16 | } 17 | 18 | private fun isPowerOfTwo(number: Int): Boolean { 19 | return number > 0 && number and (number - 1) == 0 20 | } -------------------------------------------------------------------------------- /src/main/kotlin/karat/MainKarat.kt: -------------------------------------------------------------------------------- 1 | package karat 2 | 3 | -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/AllOne.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | import java.util.* 4 | 5 | class AllOne() { 6 | 7 | private val queue = PriorityQueue() 8 | 9 | fun inc(key: String) { 10 | queue.add(key) 11 | } 12 | 13 | fun dec(key: String) { 14 | queue.remove(key) 15 | } 16 | 17 | fun getMaxKey(): String { 18 | return if (queue.isEmpty()) { 19 | "" 20 | } else { 21 | queue.peek() 22 | } 23 | } 24 | 25 | fun getMinKey(): String { 26 | return if (queue.isEmpty()) { 27 | "" 28 | } else{ 29 | queue.remove() 30 | } 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/FindItnerary.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | import java.util.* 4 | 5 | fun main() { 6 | val result = findItinerary( 7 | listOf( 8 | listOf("MUC","LHR"), 9 | listOf("JFK","MUC"), 10 | listOf("SFO","SJC"), 11 | listOf("LHR","SFO") 12 | ) 13 | ) 14 | 15 | println(result) 16 | } 17 | 18 | fun findItinerary(tickets: List>): List { 19 | val linkedList = LinkedList() 20 | 21 | for(ticket in tickets){ 22 | linkedList.add(ticket[0]) 23 | linkedList.add(ticket[1]) 24 | } 25 | return linkedList.toMutableSet().toList() 26 | } 27 | 28 | data class Airport( 29 | val from: String, 30 | val to: String 31 | ) -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/FoodRating.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | import java.util.* 3 | 4 | class FoodRatings(private val foods: Array, private val cuisines: Array, private val ratings: IntArray) { 5 | 6 | private val foodRatingMap = mutableMapOf() 7 | private val foodCuisineMap = mutableMapOf>() 8 | 9 | init { 10 | initFoodRatings() 11 | } 12 | 13 | fun changeRating(food: String, newRating: Int) { 14 | foodRatingMap[food] = newRating 15 | } 16 | 17 | fun highestRated(cuisine: String): String { 18 | val foodList = foodCuisineMap[cuisine] 19 | 20 | return foodList?.maxBy { it }.toString() 21 | } 22 | 23 | 24 | private fun initFoodRatings() { 25 | for(i in foods.indices) { 26 | foodRatingMap[foods[i]] = ratings[i] 27 | } 28 | 29 | for(i in cuisines.indices) { 30 | foodCuisineMap[cuisines[i]] = foodCuisineMap.getOrDefault(foods[i], mutableListOf()).apply { add(foods[i]) } 31 | } 32 | } 33 | } 34 | 35 | /** 36 | * Your FoodRatings object will be instantiated and called as such: 37 | * var obj = FoodRatings(foods, cuisines, ratings) 38 | * obj.changeRating(food,newRating) 39 | * var param_2 = obj.highestRated(cuisine) 40 | */ -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/HitCounter.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | class HitCounter { 4 | private val counter = mutableMapOf() // timestamp to count of hit 5 | 6 | fun hit(timestamp: Int) { 7 | counter[timestamp] = counter.getOrDefault(timestamp, 0) + 1 8 | } 9 | 10 | fun getHits(timestamp: Int): Int { 11 | var count = 0 12 | 13 | for ((key, value) in counter) { 14 | val timeDiff = timestamp - key 15 | 16 | if (timeDiff < 300) { 17 | count += value 18 | } 19 | } 20 | 21 | return count 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/KthLargest.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | class KthLargest(private val k: Int, private val nums: IntArray) { 4 | private val list = nums.sorted().toMutableList() 5 | private val index = nums.size - 1 6 | 7 | fun add(`val`: Int): Int { 8 | for (i in 0 until list.size) { 9 | 10 | } 11 | return `val` 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/LRUCache.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | import kotlin.collections.LinkedHashMap 4 | 5 | fun main() { 6 | 7 | } 8 | 9 | class LRUCache(private val capacity: Int): LinkedHashMap(capacity, 0.75F, true) { 10 | 11 | private val cache: LinkedHashMap = object : LinkedHashMap(capacity) { 12 | override fun removeEldestEntry(eldest: MutableMap.MutableEntry): Boolean { 13 | return size > capacity 14 | } 15 | } 16 | 17 | override fun get(key: Int): Int { 18 | return cache.getOrDefault(key, 0) 19 | } 20 | 21 | override fun put(key: Int, value: Int): Int? { 22 | return cache.put(key, value) 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/LogSystem.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | class LogSystem() { 4 | 5 | private val logs = mutableListOf() 6 | 7 | //mapping time with index within timestamp string 8 | private val timestampMap = mutableMapOf() 9 | 10 | init { 11 | //"2017:01:01:23:59:59" 12 | timestampMap.apply { 13 | put("Year", 4) 14 | put("Month", 7) 15 | put("Day", 10) 16 | put("Hour", 13) 17 | put("Minute", 16) 18 | put("Second", 19) 19 | } 20 | } 21 | 22 | //timestamp: Year:Month:Day:Hour:Minute:Second 23 | fun put(id: Int, timestamp: String) { 24 | logs.add(Logger(id, timestamp)) 25 | } 26 | 27 | fun retrieve(start: String, end: String, granularity: String): List { 28 | val result = mutableListOf() 29 | val granular = timestampMap[granularity] ?: 0 30 | 31 | val startTime = start.substring(0, granular) 32 | val endTime = end.substring(0, granular) 33 | 34 | for (log in logs) { 35 | val timestamp = log.timestamp.substring(0, granular) 36 | 37 | if (startTime.compareTo(timestamp) <= 0 && timestamp.compareTo(endTime)<= 0) { 38 | result.add(log.id) 39 | } 40 | } 41 | 42 | return result 43 | } 44 | } 45 | 46 | data class Logger( 47 | val id: Int, 48 | val timestamp: String 49 | ) 50 | 51 | /** 52 | * Your LogSystem object will be instantiated and called as such: 53 | * var obj = LogSystem() 54 | * obj.put(id,timestamp) 55 | * var param_2 = obj.retrieve(start,end,granularity) 56 | */ -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/MovingAverage.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | fun main() { 4 | val instance = numEquivDominoPairs( 5 | arrayOf( 6 | intArrayOf(1,2), 7 | intArrayOf(1,2), 8 | intArrayOf(1,1), 9 | intArrayOf(1,2), 10 | intArrayOf(2,2) 11 | ) 12 | ) 13 | 14 | println(instance) 15 | } 16 | 17 | /* 18 | [ 19 | [1,2], 20 | [2,1], 21 | [3,4], 22 | [5,6] 23 | ] 24 | */ 25 | fun numEquivDominoPairs(dominoes: Array): Int { 26 | val pairs = mutableListOf>() 27 | var first = 0 28 | var second = dominoes.size - 1 29 | 30 | while(first < dominoes.size) { 31 | while (second <= dominoes.size) { 32 | if(isEquivalent(dominoes[first], dominoes[second])) { 33 | pairs.add(Pair(first, second)) 34 | } 35 | second-- 36 | } 37 | first++ 38 | } 39 | 40 | return pairs.size 41 | } 42 | 43 | //[a, b] -> i 44 | //[c, d] -> j 45 | // if a == c and b == d 46 | // or if a == d and b == c 47 | fun isEquivalent(first: IntArray, second: IntArray): Boolean { 48 | val firstRotation = (first[0] == second[0] && first[1] == second[1]) 49 | val secondRotation = (first[0] == second[1] && first[1] == second[0]) 50 | 51 | return firstRotation || secondRotation 52 | } 53 | 54 | class MovingAverage(size: Int) { 55 | val list = mutableListOf() 56 | val listSize = size 57 | fun next(`val`: Int): Double { 58 | list.add(`val`) 59 | val average = list.takeLast(listSize) 60 | return average.average() 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/NumAarray.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | class NumArray(private val nums: IntArray) { 4 | fun sumRange(left: Int, right: Int): Int { 5 | var result = 0 6 | var leftIdx = left 7 | 8 | while(leftIdx <= right) { 9 | val sum = nums[leftIdx] 10 | result += sum 11 | leftIdx++ 12 | } 13 | return result 14 | } 15 | 16 | fun update(index: Int, `val`: Int) { 17 | //need tp update index into val 18 | 19 | nums[index] = `val` 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/NumberMatrix.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | class NumMatrix(matrix: Array) { 4 | 5 | } -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/ParkingSystem.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | class ParkingSystem(big: Int, medium: Int, small: Int) { 4 | val map = mutableMapOf( 5 | 1 to big, 6 | 2 to medium, 7 | 3 to small 8 | ) 9 | fun addCar(carType: Int): Boolean { 10 | if (map.getOrDefault(carType, 0) > 1) { 11 | map[carType] = map.getOrDefault(carType, 0) - 1 12 | return true 13 | } 14 | return false 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/PhoneDirectory.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | import java.util.* 4 | 5 | fun main() { 6 | 7 | } 8 | 9 | class PhoneDirectory(private val maxNumbers: Int) { 10 | private val directory = mutableMapOf() 11 | init { 12 | for (i in 0 until maxNumbers) { 13 | directory[i] = directory.getOrDefault(i, false) 14 | } 15 | } 16 | 17 | fun get(): Int { 18 | var number = 0 19 | directory.toSortedMap().forEach { key, value -> 20 | if (!value) { 21 | number = key 22 | directory[key] = true 23 | } 24 | } 25 | 26 | return number 27 | } 28 | 29 | fun check(number: Int): Boolean { 30 | for ((key, value ) in directory) { 31 | if (number == key) { 32 | return value 33 | } 34 | } 35 | 36 | return false 37 | } 38 | 39 | fun release(number: Int) { 40 | directory[number] = directory.getOrDefault(number, false) 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/ProductOfNumber.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | import java.util.* 4 | 5 | class ProductOfNumbers() { 6 | 7 | private val product = ArrayDeque() 8 | 9 | fun add(num: Int) { 10 | product.add(num) 11 | } 12 | 13 | fun getProduct(k: Int): Int { 14 | var result = 1 15 | product.toList() 16 | .takeLast(k) 17 | .forEach { 18 | result *= it 19 | } 20 | 21 | return result 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/UniqueEmail.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | import java.lang.StringBuilder 4 | 5 | fun main() { 6 | 7 | } 8 | 9 | fun numUniqueEmails(emails: Array): Int { 10 | val uniqueList = mutableSetOf() 11 | 12 | for(email in emails) { 13 | uniqueList.add(formatEmail(email)) 14 | } 15 | 16 | return uniqueList.size 17 | } 18 | 19 | fun formatEmail(email: String): String { 20 | val formattedEmail = StringBuilder() 21 | val localName = email.substringBefore("@") 22 | val domainName = email.substringAfter("@") 23 | 24 | if (hasPlusSignInLocal(localName)) { 25 | formattedEmail.append(localName.substringBefore("+")) 26 | } else if (hasDotSignInLocal(localName)) { 27 | formattedEmail.append(localName.replace(".", "")) 28 | } else { 29 | formattedEmail.append(localName) 30 | } 31 | formattedEmail.append("@") 32 | formattedEmail.append(validateDomain(domainName)) 33 | return formattedEmail.toString() 34 | } 35 | 36 | fun hasPlusSignInLocal(local: String): Boolean { 37 | return local.contains("+") 38 | } 39 | 40 | fun hasDotSignInLocal(local: String): Boolean { 41 | return local.contains(".") 42 | } 43 | 44 | //"testemail@leetcode.com" and "testemail@lee.tcode.com" actually receive mails. 45 | fun validateDomain(domain: String): String { 46 | val domainAdd = domain.substringBefore(".com") 47 | domainAdd.replace(".", "") 48 | return domainAdd 49 | } -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/ValidSudoku.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | fun isValidSudoku(board: Array): Boolean { 4 | val seen = hashSetOf() 5 | for (i in 0 until board[0].size) { 6 | for (j in 0 until board.size) { 7 | val current = board[i][j] 8 | 9 | if (current != '.') { 10 | if ( 11 | isDuplicateInRow(seen, current, i) || 12 | isDuplicateInCol(seen, current, j) || 13 | isDuplicateInSubBox(seen, current, i, j) 14 | ) { 15 | return false 16 | } 17 | } 18 | } 19 | } 20 | 21 | return true 22 | } 23 | 24 | fun isDuplicateInRow(set: HashSet, value: Char, index: Int): Boolean { 25 | return !set.add("$value found in row $index") 26 | } 27 | 28 | fun isDuplicateInCol(set: HashSet, value: Char, index: Int): Boolean { 29 | return !set.add("$value found in col $index") 30 | } 31 | 32 | fun isDuplicateInSubBox(set: HashSet, value: Char, i: Int, j: Int): Boolean { 33 | return !set.add("$value found in sub-box ${i / 3} <-> ${j / 3}") 34 | } -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/WebsiteAnalysis.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | 4 | fun main() { 5 | } 6 | 7 | fun mostVisitedPattern(username: Array, timestamp: IntArray, website: Array): List { 8 | val map = mutableMapOf>() 9 | val result = mutableListOf() 10 | 11 | for (i in 0 until username.size) { 12 | val currentList = map.getOrDefault(username[i], emptyList()).toMutableList() 13 | currentList.add(WebsiteKit(timestamp[i], website[i])) 14 | map[username[i]] = currentList 15 | } 16 | 17 | return result 18 | } 19 | 20 | data class WebsiteKit( 21 | val timestamp: Int, 22 | val website: String 23 | ) -------------------------------------------------------------------------------- /src/main/kotlin/leetcode/WordDictionary.kt: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | class WordDictionary() { 4 | 5 | val dictionary = mutableSetOf() 6 | 7 | fun addWord(word: String) { 8 | dictionary.add(word) 9 | } 10 | 11 | fun search(word: String): Boolean { 12 | word.replace(".", "") 13 | 14 | for (dict in dictionary) { 15 | return dict.matches(Regex(word)) 16 | } 17 | 18 | return false 19 | } 20 | } 21 | 22 | fun main() { 23 | val dictionary = WordDictionary() 24 | 25 | dictionary.addWord("bad") 26 | dictionary.addWord("dad") 27 | dictionary.addWord("mad") 28 | 29 | println("dictionary: ${dictionary.dictionary}") 30 | val result = dictionary.search("co") 31 | 32 | println("isFound: $result") 33 | } 34 | -------------------------------------------------------------------------------- /src/main/kotlin/training/main.kt: -------------------------------------------------------------------------------- 1 | package training 2 | 3 | fun main() { 4 | val data = listOf( 5 | BCSConfig("transport", "GO_CAR,GO_RIDE,GO_BLUE_BIRD,GO_SILVER_BIRD,GO_BIRD_COMBO,GO_HAIL_BIKE,GO_CAR_EXTRA,SG_GO_CAR,GO_TAXI,GO_RIDE_HYGIENE,GO_CAR_HYGIENE,GO_RIDE_EV,GO_CAR_PREMIUM"), 6 | BCSConfig("food", "GO_FOOD,GO_FOOD_PICK_UP"), 7 | BCSConfig("send", "GO_SEND,GO_KILAT,GOKILAT_SHOP,GO_KILAT_NEW,SAMEDAY_KILAT,SAMEDAY_SEND,LOGISTICS_INTERCITY"), 8 | BCSConfig("shop", "GO_SHOP") 9 | ) 10 | 11 | val serviceName = data.first { it.service.contains("GO_CAR_EXTRA") } 12 | .value 13 | val litmusConfigApproach = data.firstOrNull { it.value == "food" } 14 | ?.service.orEmpty() 15 | 16 | //format object payload 17 | val bcs = mutableMapOf( 18 | "transport" to Transport("Transport", listOf("GO_RIDE", "GO_CAR")), 19 | "food" to Food("Food", listOf("GO_FOOD", "GO_FOOD_PICKUP")) 20 | ) 21 | 22 | val inputLitmus = "food" 23 | val inputOrders = "GO_FOOD" 24 | 25 | val response = bcs[inputLitmus] 26 | var responseOrders = "" 27 | 28 | responseOrders = getDynamicTag(bcs, inputOrders) 29 | 30 | println("with array approach $serviceName services $litmusConfigApproach") 31 | println("with object map approach: litmus $response") 32 | println("with object map approach: recent orders $responseOrders") 33 | } 34 | 35 | private fun getDynamicTag( 36 | bcs: MutableMap, 37 | inputOrders: String 38 | ): String { 39 | for ((key, value) in bcs) { 40 | if (value.serviceName.contains(inputOrders)) { 41 | return key 42 | } 43 | } 44 | return "" 45 | } 46 | 47 | interface ProductGroup { 48 | val title: String 49 | val serviceName: List 50 | } 51 | 52 | data class BcsConfiguration( 53 | val transport: Transport, 54 | val food: Food 55 | ) 56 | 57 | data class Transport( 58 | override val title: String, 59 | override val serviceName: List 60 | ) : ProductGroup 61 | 62 | data class Food( 63 | override val title: String, 64 | override val serviceName: List 65 | ) : ProductGroup 66 | 67 | data class BCSConfig( 68 | val value: String, 69 | val service: String 70 | ) --------------------------------------------------------------------------------