├── .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