├── .gitignore ├── README.md ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src └── test └── java ├── algorithm ├── basic │ ├── CharacterCompressWithLength.java │ ├── FrequencyStringInDocument.java │ ├── IsAnagram.java │ ├── StringParseToInt.java │ ├── StringReverse.java │ └── UniqueCharacterInString.java ├── basicMath │ ├── BasicCombination.java │ ├── Fibonacci.java │ ├── FindPrimeNumTest.java │ ├── GcdAndGcm.java │ ├── Ladder.java │ └── SumEachNum.java ├── dp │ └── JumpGame.java └── recursion │ ├── BraceCombination.java │ ├── Dice.java │ ├── NBitWays.java │ └── Permutation.java ├── bit ├── BitMapTest.java └── BitOperator.java ├── datastructure ├── binaryTree │ └── BinaryTree.java ├── linkedlist │ └── SingleLinkedListTest.java ├── priorityqueue │ ├── CalcTopTen.java │ └── HeapSortByUsingPQ.java ├── queue │ ├── QueueWithTwoStack.java │ └── ReverseQueueTest.java └── stack │ ├── CheckBrace.java │ ├── IsPalindromeTest.java │ ├── MinimumStackTest.java │ ├── MyStackWithArrayListTest.java │ └── MyStackWithArrayTest.java ├── exercise ├── CalenderExample.java ├── FactorialZeroCount.java ├── FindMaxSumInArray.java ├── FindSquareNum.java ├── LinkedListLength.java ├── NoTempSwapTest.java ├── OnlyTwoDigitSum.java ├── SameFaceDice.java └── SearchEquilibrium.java ├── famous_algorithm ├── KMP_Algorithm.java └── Karp_Rabin_Algorithm.java ├── search ├── BinarySearchTest.java └── SearchIn2DTest.java ├── sort ├── BubbleSort.java ├── InsertionSort.java ├── QuickSort.java ├── RadixSort.java └── SelectionSort.java └── utils └── Utils.java /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .gradle 3 | /build/ 4 | gradle-app.setting 5 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 6 | !gradle-wrapper.jar -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Algorithm_basic 2 | 기본적인 알고리즘을 정리한 Repository 입니다. 모든 코드는 `test` 디렉토리에 존재하며 주제별로 나뉘어 있습니다. 알고리즘 코드들은 java로 작성되었습니다 3 | 4 |
5 | 6 | ## Algorithm basic List 7 | 8 | ### String basic part 9 | * 주어진 문자열을 int 형으로 변환한다. [code](src/test/java/algorithm/basic/StringParseToInt.java) 10 | * 주어진 문자열을 역순으로 출력한다. [code](src/test/java/algorithm/basic/StringReverse.java) 11 | * 주어진 문자열에서 문자열을 구성하고 있는 각각의 문자열들이 고유한지를 판단한다. [code](src/test/java/algorithm/basic/UniqueCharacterInString.java) 12 | * 주어진 문자열이 애너그램인지를 판단한다. [code](src/test/java/algorithm/basic/IsAnagram.java) 13 | * 주어진 문자열을 길이와 함께 적어주면서 압축을 한다. [code](src/test/java/algorithm/basic/CharacterCompressWithLength.java) 14 | * 주어진 문서(단어별로 나뉘어진 배열)에서 특정 단어의 빈도를 구한다. [code](src/test/java/algorithm/basic/FrequencyStringInDocument.java) 15 | 16 | ### Basic Math 17 | * 주어진 두 수의 최대 공약수와 최소 공배수를 구한다. [code](src/test/java/algorithm/basicMath/GcdAndGcm.java) 18 | * n개의 서로 다른 원소 중 r개의 원소를 순서없이 선택하는 방법의 수를 구한다. [code](src/test/java/algorithm/basicMath/BasicCombination.java) 19 | * 주어진 수보다 작은 소수의 개수를 구한다. [code](src/test/java/algorithm/basicMath/FindPrimeNumTest.java) 20 | * Fibonacci 를 계산하는 함수를 작성한다. [code](src/test/java/algorithm/basicMath/Fibonacci.java) 21 | * 주어진 정수의 각 자리 수의 합을 구한다. [code](src/test/java/algorithm/basicMath/SumEachNum.java) 22 | * 사다리를 한 칸 또는 두 칸씩 오를 수 있다고 했을 때 사다리 높이에 따른 사다리 오르기 방법의 경우의 수를 구한다. [code](src/test/java/algorithm/basicMath/Ladder.java) 23 | 24 | ### Recursion part 25 | * 주사위로 이동 가능한 경우의 수를 모두 구한다. [code](src/test/java/algorithm/recursion/Dice.java) 26 | * n비트의 모든 경우의 수를 출력한다. [code](src/test/java/algorithm/recursion/NBitWays.java) 27 | * 순열을 구한다. [code](src/test/java/algorithm/recursion/Permutation.java) 28 | * N개 괄호로 만들 수 있는 모든 조합 출력하기. [code](src/test/java/algorithm/recursion/BraceCombination.java) 29 | 30 | --- 31 | 32 | ## DataStructure 33 | ### LinkedList 34 | * 첫번째 원소를 제거한다. 35 | * 중복된 원소를 제거한다. 36 | * 역순으로 출력한다. 37 | * k번째 원소를 찾는다. 38 | * 회문인지 판단한다. 39 | [code](src/test/java/datastructure/codeedlist/SinglecodeedListTest.java) 40 | 41 | ### Stack 42 | * Array를 사용하여 Stack을 구현한다. [code](src/test/java/datastructure/stack/MyStackWithArrayTest.java) 43 | * ArrayList를 사용하여 Stack을 구현한다. [code](src/test/java/datastructure/stack/MyStackWithArrayListTest.java) 44 | * Stack에 저장된 값들 중 최소값을 반환하는 minStack() 함수를 구현한다. [code](src/test/java/datastructure/stack/MinimumStackTest.java) 45 | * Stack 자료구조를 사용하여 회문을 판별한다. [code](src/test/java/datastructure/stack/IsPalindromeTest.java) 46 | * 괄호의 유효성을 체크한다. [code](src/test/java/datastructure/stack/CheckBrace.java) 47 | 48 | ### Queue 49 | * Stack을 사용하여 queue를 stack처럼 만든다. [code](src/test/java/datastructure/queue/ReverseQueueTest.java) 50 | * Stack 두 개로 Queue를 구현한다. [code](src/test/java/datastructure/queue/QueueWithTwoStack.java) 51 | 52 | ### BinaryTree 53 | * 바이너리 트리에서 최대값을 구한다. 54 | * 주어진 바이너리 트리가 균형 잡힌 트리인지 판별한다. 55 | * 오름차순으로 정렬된 배열을 Binary Search Tree로 변환한다. 56 | * 주어진 트리가 BST인지 확인한다. 57 | [code](src/test/java/datastructure/binaryTree/BinaryTree.java) 58 | 59 | ### Priority Queue 60 | * Priority queue를 사용하여 heap sort를 하라. [code](src/test/java/datastructure/priorityqueue/HeapSortByUsingPQ.java) 61 | * 많은 수 중 top 10을 구한다. [code](src/test/java/datastructure/priorityqueue/CalcTopTen.java) 62 | 63 | --- 64 | 65 | ## Sort and Search 66 | * bubble sort를 구현한다. [code](src/test/java/sort/BubbleSort.java) 67 | * Insertion sort를 구현한다. [code](src/test/java/sort/InsertionSort.java) 68 | * Selection sort를 구현한다. [code](src/test/java/sort/SelectionSort.java) 69 | * Quick sort를 구현한다. [code](src/test/java/sort/QuickSort.java) 70 | * radix sort를 구현한다. [code](src/test/java/sort/RadixSort.java) 71 | 72 | ### Search 73 | * binary search를 사용하여 O(log n)의 시간복잡도로 target을 찾는다. [code](src/test/java/search/BinarySearchTest.java) 74 | * 정렬된 2차원 배열에서 검색한다. [code](src/test/java/search/SearchIn2DTest.java) 75 | 76 | ### bit 77 | * 2의 제곱수인지 판별한다. 78 | * 두 수에서 다른 비트의 개수를 구한다. 79 | [code](src/test/java/bit/BitOperator.java) 80 | * O(1)으로 해당 데이터가 존재하는지 판단한다. [code](src/test/java/bit/BitMapTest.java) 81 | 82 | --- 83 |
84 | 85 | ## 알고리즘 문제 풀어보기 86 | 87 | ### Dynamic Programming 88 | * Jump game [code](src/test/java/algorithm/dp/JumpGame.java) 89 | 90 | ### Exercise 91 | * 주어진 배열에서 양 쪽의 합이 동일해지는 index의 값을 구한다. [code](src/test/java/exercise/SearchEquilibrium.java) 92 | * n!의 결과값에서 0의 개수를 구한다. [code](src/test/java/exercise/FactorialZeroCount.java) 93 | * temp 를 사용하지 않고 두 변수를 swap 한다. [code](src/test/java/exercise/NoTempSwapTest.java) 94 | * 어느날의 월, 일을 입력받아 요일을 반환하는 함수를 구현한다. [code](src/test/java/exercise/CalenderExample.java) 95 | * 주어진 배열에서 합이 최대가 되는 sub array의 합을 구한다. [code](src/test/java/exercise/FindMaxSumInArray.java) 96 | * 주어진 두 수 사이에 존재하는 수 중 제곱수가 되는 것을 구한다. [code](src/test/java/exercise/FindSquareNum.java) 97 | * 주어진 배열로 구성된 링크드 리스트의 길이를 구한다. [code](src/test/java/exercise/LinkedListLength.java) 98 | * 주어진 배열에서 두 자리수만 골라서 합한 값을 return 한다. [code](src/test/java/exercise/OnlyTwoDigitSum.java) 99 | * 각각의 주사위들이 모두 같은 면을 보이기 위한 최소 rotate 횟수를 구한다. [code](src/test/java/exercise/SameFaceDice.java) 100 | 101 | ### Famous Algorithm 102 | * Karp_Rabin_Algorithm [code](src/test/java/famous_algorithm/Karp_Rabin_Algorithm.java) 103 | * KMP_Algorithm [code](src/test/java/famous_algorithm/KMP_Algorithm.java) 104 | 105 |
106 | 107 | ## LICENSE 108 | 크리에이티브 커먼즈 라이선스 109 | 110 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | group 'algorithm' 2 | version '1.0-SNAPSHOT' 3 | 4 | apply plugin: 'java' 5 | 6 | sourceCompatibility = 1.8 7 | 8 | repositories { 9 | mavenCentral() 10 | } 11 | 12 | dependencies { 13 | testCompile group: 'junit', name: 'junit', version: '4.11' 14 | } 15 | 16 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbee37142/algorithm_basic_java/d4be9b940a4cb0b2568797c80fccf24314cd60d7/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun May 28 15:16:24 KST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 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 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 165 | if [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]]; then 166 | cd "$(dirname "$0")" 167 | fi 168 | 169 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 170 | -------------------------------------------------------------------------------- /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 = 'algorithm' 2 | 3 | -------------------------------------------------------------------------------- /src/test/java/algorithm/basic/CharacterCompressWithLength.java: -------------------------------------------------------------------------------- 1 | package algorithm.basic; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | import static org.hamcrest.CoreMatchers.is; 9 | import static org.junit.Assert.assertThat; 10 | 11 | public class CharacterCompressWithLength { 12 | 13 | /* 14 | TASK 15 | 주어진 문자열을 길이와 함께 적어주면서 압축을 한다. 16 | */ 17 | 18 | @Test 19 | public void test() { 20 | assertThat(null, is(runLengthCompress_USE_HASHMAP(null))); 21 | assertThat(runLengthCompress_USE_HASHMAP("aaabbbccc"), is("a3b3c3")); 22 | assertThat(runLengthCompress_USE_HASHMAP("aabbacbccc"), is("a3b3c4")); 23 | assertThat(runLengthCompress("aaabbbccc"), is("a3b3c3")); 24 | } 25 | 26 | private String runLengthCompress_USE_HASHMAP(String str) { 27 | if (str == null) return null; 28 | 29 | Map charCounter = new HashMap<>(str.length()); 30 | 31 | for (char c : str.toCharArray()) { 32 | if (!charCounter.containsKey(c)) { 33 | charCounter.put(c, 0); 34 | } 35 | charCounter.put(c, charCounter.get(c) + 1); 36 | } 37 | StringBuilder sb = new StringBuilder(); 38 | charCounter.forEach((chr, count) -> sb.append(chr + count.toString())); 39 | return sb.toString(); 40 | } 41 | 42 | private String runLengthCompress(String str) { 43 | if (str == null) return null; 44 | 45 | char[] ca = str.toCharArray(); 46 | String result = ""; 47 | int count = 1; 48 | char prev = ca[0]; 49 | 50 | for (int i = 1; i < ca.length; i++) { 51 | if (prev == ca[i]) { 52 | count++; 53 | } else { 54 | result = result + prev + count; 55 | count = 1; 56 | prev = ca[i]; 57 | } 58 | } 59 | result = result + prev + count; 60 | return result; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/algorithm/basic/FrequencyStringInDocument.java: -------------------------------------------------------------------------------- 1 | package algorithm.basic; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Arrays; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | import static org.hamcrest.CoreMatchers.is; 10 | import static org.junit.Assert.assertThat; 11 | 12 | 13 | public class FrequencyStringInDocument { 14 | 15 | /* 16 | TASK 17 | 주어진 문서(단어별로 나뉘어진 배열)에서 특정 단어의 빈도를 구한다. 18 | */ 19 | 20 | @Test 21 | public void test() { 22 | String[] strArr = new String[100]; 23 | assertThat(countStringInDocs(strArr, null), is(0)); 24 | strArr[0] = "jbee"; 25 | assertThat(countStringInDocs(strArr, "jbee"), is(1)); 26 | strArr[1] = "jbee"; 27 | assertThat(countStringInDocs(strArr, "jbee"), is(2)); 28 | strArr[2] = "jbee"; 29 | assertThat(countStringInDocs(strArr, "jbee"), is(3)); 30 | } 31 | 32 | private int countStringInDocs(String[] strArr, String target) { 33 | if (strArr == null || target == null) return 0; 34 | 35 | Map countString = new HashMap<>(); 36 | Arrays.stream(strArr).forEach(str -> { 37 | if (!countString.containsKey(str)) { 38 | countString.put(str, 0); 39 | } 40 | countString.put(str, countString.get(str) + 1); 41 | }); 42 | 43 | if (countString.get(target) == null) { 44 | return 0; 45 | } 46 | 47 | return countString.get(target); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/algorithm/basic/IsAnagram.java: -------------------------------------------------------------------------------- 1 | package algorithm.basic; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | import static org.hamcrest.CoreMatchers.is; 9 | import static org.junit.Assert.assertThat; 10 | 11 | public class IsAnagram { 12 | 13 | /* 14 | TASK 15 | 주어진 문자열이 애너그램인지를 판단한다. 16 | */ 17 | 18 | // 방법 1. O(nlogn) : 정렬 후에 비교하기 19 | // 방법 2. O(n) : 문자열 개수를 세서 비교하기 20 | 21 | @Test 22 | public void test() { 23 | assertThat(애너그램판별_USE_MAP("arc", "car"), is(true)); 24 | assertThat(애너그램판별_USE_MAP("caaabbb", "abababc"), is(true)); 25 | assertThat(애너그램판별_USE_MAP("caabbbb", "abababc"), is(false)); 26 | assertThat(애너그램판별_USE_MAP("arc", "carr"), is(false)); 27 | assertThat(애너그램판별_USE_MAP("arc", "caz"), is(false)); 28 | } 29 | 30 | private boolean 애너그램판별_USE_MAP(String str1, String str2) { 31 | if (str1.length() != str2.length()) return false; 32 | 33 | Map strMap = new HashMap<>(); 34 | 35 | for (char c : str1.toCharArray()) { 36 | if (strMap.containsKey(c)) { 37 | strMap.put(c, strMap.get(c) + 1); 38 | } else { 39 | strMap.put(c, 1); 40 | } 41 | } 42 | 43 | for (char c : str2.toCharArray()) { 44 | if (!strMap.containsKey(c)) { 45 | return false; 46 | } 47 | if (strMap.get(c) == 0) { 48 | return false; 49 | } 50 | strMap.put(c, strMap.get(c) - 1); 51 | } 52 | 53 | return true; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/algorithm/basic/StringParseToInt.java: -------------------------------------------------------------------------------- 1 | package algorithm.basic; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class StringParseToInt { 9 | 10 | /* 11 | TASK 12 | 주어진 문자열을 int 형으로 변환한다. 13 | */ 14 | 15 | @Test 16 | public void toIntFromString() { 17 | assertThat(toIntFromString("123"), is(123)); 18 | } 19 | 20 | private int toIntFromString(String str) { 21 | // return Integer.parseInt(str); 22 | char[] strArr = str.toCharArray(); 23 | int base = 0; 24 | for (char c : strArr) { 25 | base *= 10; 26 | base += c - '0'; 27 | } 28 | return base; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/algorithm/basic/StringReverse.java: -------------------------------------------------------------------------------- 1 | package algorithm.basic; 2 | 3 | import org.junit.Test; 4 | import utils.Utils; 5 | 6 | import static org.hamcrest.CoreMatchers.is; 7 | import static org.junit.Assert.assertThat; 8 | 9 | public class StringReverse { 10 | 11 | /* 12 | TASK 13 | 주어진 문자열을 역순으로 출력한다. 14 | */ 15 | 16 | @Test 17 | public void test() { 18 | assertThat(solution1("abc"), is("cba")); 19 | assertThat(solution1("abcd"), is("dcba")); 20 | 21 | assertThat(solution2("abc"), is("cba")); 22 | assertThat(solution2("abcd"), is("dcba")); 23 | } 24 | 25 | // 1. 새로운 배열에 담기 26 | public String solution1(String str) { 27 | char[] charArr = str.toCharArray(); 28 | char[] resultArr = new char[charArr.length]; 29 | 30 | for (int i = 0; i < charArr.length; i++) { 31 | resultArr[charArr.length - i - 1] = charArr[i]; 32 | } 33 | return new String(resultArr); 34 | } 35 | 36 | // 2. swap하기 37 | public String solution2(String str) { 38 | char[] charArr = str.toCharArray(); 39 | 40 | for (int i = 0; i < charArr.length / 2; i++) { 41 | Utils.swapValue(charArr, i, charArr.length - 1 - i); 42 | } 43 | return new String(charArr); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/algorithm/basic/UniqueCharacterInString.java: -------------------------------------------------------------------------------- 1 | package algorithm.basic; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | 8 | import static org.hamcrest.CoreMatchers.is; 9 | import static org.junit.Assert.assertThat; 10 | 11 | public class UniqueCharacterInString { 12 | 13 | /* 14 | TASK 15 | 주어진 문자열에서 문자열을 구성하고 있는 각각의 문자열들이 고유한지를 판단한다. 16 | */ 17 | 18 | @Test 19 | public void test() { 20 | assertThat(이중포문을_사용한_방법("abcd"), is(true)); 21 | assertThat(이중포문을_사용한_방법("abcdefghij"), is(true)); 22 | assertThat(이중포문을_사용한_방법("abccde"), is(false)); 23 | assertThat(이중포문을_사용한_방법("abca"), is(false)); 24 | 25 | assertThat(HashSet을_사용한_방법("abcd"), is(true)); 26 | assertThat(HashSet을_사용한_방법("abcdefghij"), is(true)); 27 | assertThat(HashSet을_사용한_방법("abccde"), is(false)); 28 | assertThat(HashSet을_사용한_방법("abca"), is(false)); 29 | } 30 | 31 | private boolean 이중포문을_사용한_방법(String str) { 32 | char[] strArr = str.toCharArray(); 33 | for (int i = 0; i < strArr.length - 1; i++) { 34 | for (int j = i + 1; j < strArr.length; j++) { 35 | if (strArr[i] == strArr[j]) return false; 36 | } 37 | } 38 | return true; 39 | } 40 | 41 | private boolean HashSet을_사용한_방법(String str) { 42 | Set strSet = new HashSet<>(); 43 | for (char c : str.toCharArray()) { 44 | if (strSet.contains(c)) { 45 | return false; 46 | } 47 | strSet.add(c); 48 | } 49 | return true; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/java/algorithm/basicMath/BasicCombination.java: -------------------------------------------------------------------------------- 1 | package algorithm.basicMath; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class BasicCombination { 9 | 10 | /* 11 | TASK 12 | n개의 서로 다른 원소 중 r개의 원소를 순서없이 선택하는 방법의 수를 구한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | assertThat(getByRecursion(0, 0), is(1)); 18 | assertThat(getByRecursion(1, 0), is(1)); 19 | assertThat(getByRecursion(2, 1), is(2)); 20 | assertThat(getByRecursion(8, 3), is(56)); 21 | 22 | assertThat(getByDp(0, 0), is(1)); 23 | assertThat(getByDp(1, 0), is(1)); 24 | assertThat(getByDp(2, 1), is(2)); 25 | assertThat(getByDp(8, 3), is(56)); 26 | } 27 | 28 | public int getByRecursion(int n, int r) { 29 | if (r == 0 || n == r) { 30 | return 1; 31 | } 32 | return getByRecursion(n - 1, r - 1) + getByRecursion(n - 1, r); 33 | } 34 | 35 | public int getByDp(int n, int r) { 36 | int cache[][] = new int[10][10]; 37 | if (r == 0 || n == r) { 38 | return 1; 39 | } 40 | if (cache[n][r] != 0) return cache[n][r]; 41 | return cache[n][r] = getByDp(n - 1, r - 1) + getByDp(n - 1, r); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/algorithm/basicMath/Fibonacci.java: -------------------------------------------------------------------------------- 1 | package algorithm.basicMath; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class Fibonacci { 9 | 10 | /* 11 | TASK 12 | Fibonacci 를 계산하는 함수를 작성한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | 18 | assertThat(calcFiboByFor(5), is(5)); 19 | assertThat(calcFiboByFor(6), is(8)); 20 | assertThat(calcFiboByFor(7), is(13)); 21 | 22 | assertThat(calcFiboByRec(5), is(5)); 23 | assertThat(calcFiboByRec(6), is(8)); 24 | assertThat(calcFiboByRec(7), is(13)); 25 | 26 | assertThat(fiboByDp(5), is(5)); 27 | assertThat(fiboByDp(6), is(8)); 28 | assertThat(fiboByDp(7), is(13)); 29 | } 30 | 31 | // Iteration version 32 | public int calcFiboByFor(int num) { 33 | if (num < 0) return -1; 34 | 35 | int curValue = 0; 36 | int prevValue = 1; 37 | int prevPrevValue = 0; 38 | 39 | for (int i = 2; i <= num; i++) { 40 | curValue = prevValue +prevPrevValue; 41 | prevPrevValue = prevValue; 42 | prevValue = curValue; 43 | } 44 | return curValue; 45 | } 46 | 47 | // Recursion version 48 | public int calcFiboByRec(int num) { 49 | if (num < 0) return -1; 50 | if (num < 2) return num; 51 | return calcFiboByRec(num - 1) + calcFiboByRec(num - 2); 52 | } 53 | 54 | // Dynamic Programming version 55 | public int fiboByDp(int num) { 56 | return calcFibo(num, new int[num + 1]); 57 | } 58 | 59 | private int calcFibo(int num, int[] cache) { 60 | if (num < 2) return num; 61 | if (cache[num] != 0) return cache[num];//in java, int[] is initialized by 0. 62 | 63 | cache[num] = calcFibo(num - 1, cache) + calcFibo(num - 2, cache); 64 | return cache[num]; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/test/java/algorithm/basicMath/FindPrimeNumTest.java: -------------------------------------------------------------------------------- 1 | package algorithm.basicMath; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class FindPrimeNumTest { 9 | 10 | /* 11 | TASK 12 | 주어지는 수 이하의 소수 개수를 구한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | assertThat(solution(-3), is(-1)); 18 | assertThat(solution(0), is(0)); 19 | assertThat(solution(1), is(0)); 20 | assertThat(solution(2), is(1)); 21 | assertThat(solution(3), is(2)); 22 | assertThat(solution(8), is(4)); 23 | assertThat(solution(12), is(5)); 24 | assertThat(solution(44), is(14)); 25 | //2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43 26 | } 27 | 28 | public int solution(int num) { 29 | if (num < 0) { 30 | return -1; 31 | } 32 | int[] checkList = new int[num + 1]; 33 | 34 | for (int i = 2; i <= num; i++) { 35 | checkList[i] = i; 36 | } 37 | int baseNum = (int) Math.sqrt(num); 38 | 39 | for (int i = 2; i <= baseNum; i++) { 40 | if (checkList[i] == 0) { 41 | continue; 42 | } 43 | for (int k = i; k <= num; k += i) { 44 | if (checkList[k] != i && checkList[k] % i == 0) { 45 | checkList[k] = 0; 46 | } 47 | } 48 | } 49 | 50 | int count = 0; 51 | for (int i = 0; i <= num; i++) { 52 | if (checkList[i] != 0) { 53 | count++; 54 | } 55 | } 56 | 57 | return count; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/algorithm/basicMath/GcdAndGcm.java: -------------------------------------------------------------------------------- 1 | package algorithm.basicMath; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class GcdAndGcm { 9 | 10 | /* 11 | TASK 12 | 입력받은 두 수의 최대 공약수, 최소 공배수를 구한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | assertThat(gcdByIteration(-1, 0), is(-1)); 18 | assertThat(gcdByIteration(0, 0), is(0)); 19 | assertThat(gcdByIteration(6, 8), is(2)); 20 | assertThat(gcdByIteration(3, 3), is(3)); 21 | 22 | assertThat(gcdByRecursion(-1, 0), is(-1)); 23 | assertThat(gcdByRecursion(0, 0), is(0)); 24 | assertThat(gcdByRecursion(6, 8), is(2)); 25 | assertThat(gcdByRecursion(3, 3), is(3)); 26 | 27 | assertThat(gcm(6, 8), is(24)); 28 | } 29 | 30 | public int gcdByIteration(int a, int b) { 31 | if (a < 0 || b < 0) return -1; 32 | int mod; 33 | while (b != 0) { 34 | mod = a % b; 35 | a = b; 36 | b = mod; 37 | } 38 | return a; 39 | } 40 | 41 | public int gcdByRecursion(int a, int b) { 42 | if (a < 0 || b < 0) return -1; 43 | if (b == 0) { 44 | return a; 45 | } 46 | return gcdByRecursion(b, a % b); 47 | } 48 | 49 | public int gcm(int a, int b) { 50 | return a * b / gcdByRecursion(a, b); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/algorithm/basicMath/Ladder.java: -------------------------------------------------------------------------------- 1 | package algorithm.basicMath; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class Ladder { 9 | 10 | /* 11 | TASK 12 | 사다리를 한 칸 또는 두 칸씩 오를 수 있다고 했을 때 13 | 사다리 높이에 따른 사다리 오르기 방법의 경우의 수를 구한다. 14 | */ 15 | 16 | @Test 17 | public void test() { 18 | assertThat(solution(0), is(1)); 19 | assertThat(solution(1), is(1)); 20 | assertThat(solution(2), is(2)); 21 | assertThat(solution(3), is(3)); 22 | assertThat(solution(4), is(5)); 23 | assertThat(solution(5), is(8)); 24 | assertThat(solution(6), is(13)); 25 | assertThat(solution(7), is(21)); 26 | } 27 | 28 | public int solution(int num) { 29 | return getCountOfCase(num, 0, num); 30 | // return getCountOfCaseRec(num); 31 | } 32 | 33 | // Use while statement 34 | private int getCountOfCase(int one, int two, int num) { 35 | int result = 0; 36 | while (one + two * 2 == num && one >= 0) { 37 | result += getByRecursion(one + two, two); 38 | one -= 2; 39 | two += 1; 40 | } 41 | return result; 42 | } 43 | 44 | public int getByRecursion(int n, int r) { 45 | int cache[][] = new int[n + 1][r + 1]; 46 | if (r == 0 || n == r) { 47 | return 1; 48 | } 49 | if (cache[n][r] != 0) return cache[n][r]; 50 | return cache[n][r] = getByRecursion(n - 1, r - 1) + getByRecursion(n - 1, r); 51 | } 52 | 53 | // test code를 작성하다보니 이것이 피보나치 규칙을 따른다는 것을 알게 되었다. 54 | // Recursion version 55 | private int getCountOfCaseRec(int num) { 56 | if (num < 2) { 57 | return 1; 58 | } 59 | return getCountOfCaseRec(num - 1) + getCountOfCaseRec(num - 2); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/algorithm/basicMath/SumEachNum.java: -------------------------------------------------------------------------------- 1 | package algorithm.basicMath; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class SumEachNum { 9 | 10 | /* 11 | TASK 12 | 주어진 정수의 각 자리 수의 합을 구한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | assertThat(solution(0), is(0)); 18 | assertThat(solution(235), is(10)); 19 | assertThat(solution(235678), is(31)); 20 | assertThat(solution(-1), is(1)); 21 | } 22 | 23 | public int solution(int value) { 24 | int base = Math.abs(value); 25 | int result = 0; 26 | 27 | while (base > 0) { 28 | result += base % 10; 29 | base = base / 10; 30 | } 31 | 32 | return result; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/algorithm/dp/JumpGame.java: -------------------------------------------------------------------------------- 1 | package algorithm.dp; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class JumpGame { 9 | 10 | /* 11 | TASK 12 | 외발뛰기 <215> 13 | n x n 크기의 격자에 1부터 0까지의 정수를 쓴 게임판이 존재합니다. 14 | 이 게임의 목적은 게임판의 왼쪽 위 칸에서 시작하여 게임판의 맨 오른쪽 아래 칸에 도착하는 것입니다. 15 | 중간에 게임판 밖으로 벗어나면 안되며 문제는 주어진 게임판에서 목적을 달성할 수 있는지에 대한 여부를 판단하는 것입니다. 16 | */ 17 | 18 | @Test 19 | public void test() { 20 | int[][] board1 = { 21 | { 1,1,1,1,1,1 }, 22 | { 1,1,1,1,1,1 }, 23 | { 1,1,1,1,1,1 }, 24 | { 1,1,1,1,1,1 }, 25 | { 1,1,1,1,1,1 }, 26 | { 1,1,1,1,1,1 } 27 | }; 28 | assertThat(solutionByRec(board1), is(true)); 29 | assertThat(solutionByDp(board1), is(true)); 30 | int[][] board2 = { 31 | { 1,1,1,1,1,1,1,1,1 }, 32 | { 1,1,1,1,1,1,1,1,1 }, 33 | { 1,1,1,1,1,1,1,1,1 }, 34 | { 1,1,1,1,1,1,1,1,1 }, 35 | { 1,1,1,1,1,1,1,1,1 }, 36 | { 1,1,1,1,1,1,1,1,1 }, 37 | { 1,1,1,1,1,1,2,2,1 }, 38 | { 1,1,1,1,1,1,2,1,2 }, 39 | { 1,1,1,1,1,1,1,2,1 } 40 | }; 41 | assertThat(solutionByRec(board2), is(false)); 42 | assertThat(solutionByDp(board2), is(false)); 43 | } 44 | 45 | public boolean solutionByRec(int[][] board) { 46 | return jumpByRec(board, board.length - 1, 0, 0); 47 | } 48 | 49 | public Boolean solutionByDp(int[][] board) { 50 | Boolean[][] cache = new Boolean[board.length][board.length]; 51 | for (int i = 0; i < cache.length; i++) { 52 | for (int j = 0; j < cache.length; j++) { 53 | cache[i][j] = null; 54 | } 55 | } 56 | return jumpByDp(cache, board, board.length - 1, 0, 0); 57 | } 58 | 59 | public boolean jumpByRec(int[][] board, int n, int y, int x) { 60 | if (y > n || x > n) return false; // Out of game board 61 | if (y == n && x == n) return true; // Arrive goal 62 | int jumpSize = board[y][x]; 63 | return jumpByRec(board, n, y + jumpSize, x) || jumpByRec(board, n, y, x + jumpSize); 64 | } 65 | 66 | public Boolean jumpByDp(Boolean[][] cache, int[][] board, int n, int y, int x) { 67 | if (y > n || x > n) return false; // Out of game board 68 | 69 | if (y == n && x == n) return true; // Arrive goal 70 | 71 | Boolean ret = cache[y][x]; 72 | 73 | if (ret != null) return ret; 74 | 75 | int jumpSize = board[y][x]; 76 | ret = jumpByDp(cache, board, n, y + jumpSize, x) 77 | || jumpByDp(cache, board, n, y, x + jumpSize); 78 | return ret; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/test/java/algorithm/recursion/BraceCombination.java: -------------------------------------------------------------------------------- 1 | package algorithm.recursion; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import static org.hamcrest.CoreMatchers.is; 9 | import static org.junit.Assert.assertThat; 10 | 11 | public class BraceCombination { 12 | 13 | /* 14 | TASK 15 | N개 괄호로 만들 수 있는 모든 조합 출력하기. 16 | */ 17 | 18 | @Test 19 | public void test() { 20 | assertThat(null, is(괄호경우의수구하기(0))); 21 | List actual = new ArrayList<>(); 22 | actual.add("(())"); 23 | actual.add("()()"); 24 | assertThat(괄호경우의수구하기(2), is(actual)); 25 | } 26 | 27 | public List 괄호경우의수구하기(int n) { 28 | if (n == 0) { 29 | return null; 30 | } 31 | return combination(n, n, "", new ArrayList<>()); 32 | } 33 | 34 | private List combination(int start, int end, 35 | String pairs, List result) { 36 | if (start > end) return result; 37 | if (start < 0 || end < 0) return result; 38 | if (start == 0 && end == 0) { 39 | result.add(pairs); 40 | return result; 41 | } 42 | combination(start - 1, end, pairs + "(", result); 43 | combination(start, end - 1, pairs + ")", result); 44 | return result; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/algorithm/recursion/Dice.java: -------------------------------------------------------------------------------- 1 | package algorithm.recursion; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class Dice { 9 | 10 | /* 11 | TASK 12 | 주사위로 이동 가능한 경우의 수를 모두 구한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | assertThat(calcDiceCase1(3), is(4)); 18 | assertThat(calcDiceCase1(4), is(8)); 19 | assertThat(calcDiceCase1(5), is(16)); 20 | assertThat(calcDiceCase1(6), is(32)); 21 | assertThat(calcDiceCase1(7), is(63)); 22 | assertThat(calcDiceCase1(8), is(125)); 23 | assertThat(calcDiceCase1(3), is(4)); 24 | 25 | assertThat(calcDiceCase2(4), is(8)); 26 | assertThat(calcDiceCase2(5), is(16)); 27 | assertThat(calcDiceCase2(6), is(32)); 28 | assertThat(calcDiceCase2(7), is(63)); 29 | assertThat(calcDiceCase2(8), is(125)); 30 | } 31 | 32 | private int dp[] = new int[1000]; 33 | /** 34 | * 메모이제이션을 사용하지 않은 경우 35 | * 단점 : 숫자가 커질수록 느려진다. 36 | */ 37 | public int calcDiceCase1(int n) { 38 | if (n < 0) return 0; 39 | if (n == 0) return 1; 40 | return calcDiceCase1(n - 1) + calcDiceCase1(n - 2) + 41 | calcDiceCase1(n - 3) + calcDiceCase1(n - 4) + 42 | calcDiceCase1(n - 5) + calcDiceCase1(n - 6); 43 | } 44 | /** 45 | * 메모이제이션을 사용하는 경우 46 | * 장점 : 속도가 빠르다. 47 | */ 48 | public int calcDiceCase2(int n) { 49 | if (n < 0) return 0; 50 | if (n == 0) return 1; 51 | int result = 0; 52 | for(int i = 1; i<=6; i++){ 53 | if(n - i >= 0){ 54 | if(dp[n - i] == 0){ 55 | dp[n - i] = calcDiceCase2(n - i); 56 | } 57 | result += dp[n - i]; 58 | } 59 | } 60 | return result; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/algorithm/recursion/NBitWays.java: -------------------------------------------------------------------------------- 1 | package algorithm.recursion; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import static org.hamcrest.CoreMatchers.is; 9 | import static org.junit.Assert.assertThat; 10 | 11 | public class NBitWays { 12 | 13 | /* 14 | TASK 15 | n비트의 모든 경우의 수를 출력한다. 16 | */ 17 | 18 | @Test 19 | public void test() { 20 | List actual1 = new ArrayList<>(); 21 | actual1.add("00"); 22 | actual1.add("01"); 23 | actual1.add("10"); 24 | actual1.add("11"); 25 | assertThat(calcBitCombination(2), is(actual1)); 26 | 27 | List actual2 = new ArrayList<>(); 28 | actual2.add("000"); 29 | actual2.add("001"); 30 | actual2.add("010"); 31 | actual2.add("011"); 32 | actual2.add("100"); 33 | actual2.add("101"); 34 | actual2.add("110"); 35 | actual2.add("111"); 36 | assertThat(calcBitCombination(3), is(actual2)); 37 | } 38 | 39 | public List calcBitCombination(int n) { 40 | return bitCombination(n, "", new ArrayList<>()); 41 | } 42 | 43 | private List bitCombination(int n, String str, List list) { 44 | if (n == str.length()) { 45 | list.add(str); 46 | return list; 47 | } 48 | bitCombination(n, str + "0", list); 49 | bitCombination(n, str + "1", list); 50 | return list; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/algorithm/recursion/Permutation.java: -------------------------------------------------------------------------------- 1 | package algorithm.recursion; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import static org.hamcrest.CoreMatchers.is; 9 | import static org.junit.Assert.assertThat; 10 | 11 | 12 | public class Permutation { 13 | 14 | /* 15 | TASK 16 | 순열을 구한다. 17 | */ 18 | 19 | @Test 20 | public void test() { 21 | List actual = new ArrayList<>(); 22 | actual.add("123"); 23 | actual.add("132"); 24 | actual.add("213"); 25 | actual.add("231"); 26 | actual.add("312"); 27 | actual.add("321"); 28 | assertThat(calcPermutation("123"), is(actual)); 29 | } 30 | 31 | public List calcPermutation(String str) { 32 | if (str == null) return null; 33 | return permutation(str, new boolean[str.length()], 34 | "", new ArrayList<>()); 35 | } 36 | 37 | private List permutation(String str, boolean[] isPick, 38 | String perm, List result) { 39 | if (str.length() == perm.length()) { 40 | result.add(perm); 41 | return result; 42 | } 43 | 44 | for (int i = 0; i < str.length(); i++) { 45 | if (isPick[i]) { 46 | continue; 47 | } 48 | isPick[i] = true; 49 | permutation(str, isPick, perm + str.charAt(i), result); 50 | isPick[i] = false; 51 | } 52 | return result; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/java/bit/BitMapTest.java: -------------------------------------------------------------------------------- 1 | package bit; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class BitMapTest { 9 | 10 | /* 11 | TASK 12 | O(1)으로 해당 데이터가 존재하는지 판단한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | BitMap bitMap = new BitMap(); 18 | bitMap.store("1234567"); 19 | assertThat(bitMap.exist("1234567"), is(true)); 20 | assertThat(bitMap.exist("1234568"), is(false)); 21 | } 22 | 23 | public class BitMap { 24 | public int[] cache; 25 | 26 | public BitMap() { 27 | cache = new int[(10 * 1000 * 1000) / 32]; 28 | } 29 | 30 | public void store(String data) { 31 | int dataInt = Integer.parseInt(data); 32 | int arrIndex = dataInt / 32; 33 | int byteIndex = dataInt % 32; 34 | cache[arrIndex] = cache[arrIndex] | (1 << byteIndex); 35 | } 36 | 37 | public boolean exist(String data) { 38 | int dataInt = Integer.parseInt(data); 39 | int arrIndex = dataInt / 32; 40 | int byteIndex = dataInt % 32; 41 | return (cache[arrIndex] & (1 << byteIndex)) != 0; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/bit/BitOperator.java: -------------------------------------------------------------------------------- 1 | package bit; 2 | import org.junit.Test; 3 | 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class BitOperator { 9 | 10 | @Test 11 | public void test() { 12 | assertThat(isPowerOf2(2), is(true)); 13 | assertThat(isPowerOf2(4), is(true)); 14 | assertThat(isPowerOf2(8), is(true)); 15 | assertThat(isPowerOf2(16), is(true)); 16 | assertThat(isPowerOf2(17), is(false)); 17 | } 18 | 19 | public String testFunction() { 20 | return ""; 21 | } 22 | 23 | public boolean get(int n, int i) { 24 | int mask = 1 << i; 25 | return (n & mask) != 0; 26 | } 27 | 28 | public int set(int n, int i) { 29 | int mask = 1 << i; 30 | return n | mask; 31 | } 32 | 33 | public int clear(int n, int i) { 34 | int mask = ~(1 << i); 35 | return n & mask; 36 | } 37 | 38 | /* 39 | TASK 40 | 2의 제곱수인지 판별한다. 41 | */ 42 | 43 | public boolean isPowerOf2(int n) { 44 | // 10 == 2 => 2 - 1 == 1 45 | // 100 == 4 => 4 - 1 == 11 46 | // 1000 == 8 => 8 - 1 == 111 47 | // 10000 == 16 => 16 - 1 == 1111 48 | // n에서 1을 뺀다음에 n과 and 연산을 하면 모두 0이 된다. 49 | return (n & (n - 1)) == 0; 50 | } 51 | 52 | /* 53 | TASK 54 | 두 수에서 다른 비트의 개수를 구한다. 55 | */ 56 | 57 | public int getBitDiff(int a, int b) { 58 | int diff = a ^ b; //XOR 59 | int count = 0; 60 | while (diff != 0) { 61 | diff = diff & (diff - 1); 62 | count++; 63 | } 64 | return count; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/test/java/datastructure/binaryTree/BinaryTree.java: -------------------------------------------------------------------------------- 1 | package datastructure.binaryTree; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class BinaryTree { 9 | 10 | @Test 11 | public void test() { 12 | Node node1 = new Node(); 13 | Node node2 = new Node(); 14 | Node node3 = new Node(); 15 | Node node4 = new Node(); 16 | node1.data = 1; 17 | node2.data = 2; 18 | node3.data = 3; 19 | node4.data = 4; 20 | node1.left = node2; 21 | node1.right = node3; 22 | node2.left = node4; 23 | 24 | assertThat(getMax(node1), is(4)); 25 | assertThat(isBalanced(node1), is(true)); 26 | 27 | int[] arr = {1,5,7,9,12,26,56,78}; 28 | assertThat(isBST(buildBST(arr)), is(true)); 29 | } 30 | 31 | 32 | /* 33 | TASK 34 | 바이너리 트리에서 최대값을 구한다. 35 | */ 36 | 37 | public int getMax(Node root) { 38 | int result = Integer.MIN_VALUE; 39 | if (root == null) { 40 | return result; 41 | } 42 | return getMaxRec(root, result); 43 | } 44 | 45 | public int getMaxRec(Node head, int result) { 46 | if (head == null) { 47 | return result; 48 | } 49 | if (head.data > result) { 50 | result = head.data; 51 | } 52 | result = getMaxRec(head.left, result); 53 | result = getMaxRec(head.right, result); 54 | return result; 55 | } 56 | 57 | 58 | /* 59 | TASK 60 | 주어진 바이너리 트리가 균형 잡힌 트리인지 판별한다. 61 | */ 62 | 63 | public boolean isBalanced(Node root) { 64 | return getNodeHeight(root) != -1; 65 | } 66 | 67 | private int getNodeHeight(Node node) { 68 | if (node == null) { 69 | return 0; 70 | } 71 | int leftHeight = getNodeHeight(node.left); 72 | if (leftHeight == -1) { 73 | return -1; 74 | } 75 | 76 | int rightHeight = getNodeHeight(node.right); 77 | if (rightHeight == -1) { 78 | return -1; 79 | } 80 | 81 | if (Math.abs(rightHeight - leftHeight) > 1) { 82 | return -1; 83 | } 84 | 85 | return Math.max(leftHeight, rightHeight) + 1; 86 | } 87 | 88 | 89 | /* 90 | TASK 91 | 오름차순으로 정렬된 배열을 Binary Search Tree로 변환한다. 92 | 트리의 높이를 최소화 하면서 (즉 complete binary tree로) 변환한다. 93 | */ 94 | 95 | public Node buildBST(int[] arr) { 96 | return buildBSTRec(arr, 0, arr.length - 1); 97 | } 98 | 99 | private Node buildBSTRec(int[] arr, int start, int end) { 100 | if (start > end) { 101 | return null; 102 | } 103 | int middle = start + (end - start)/2; 104 | Node leftNode = buildBSTRec(arr, start, middle - 1); 105 | Node rightNode = buildBSTRec(arr, middle + 1, end); 106 | 107 | return new Node(arr[middle], leftNode, rightNode); 108 | } 109 | 110 | 111 | /* 112 | TASK 113 | 주어진 트리가 BST인지 확인한다. 114 | Hint: 범위 탐색 115 | */ 116 | 117 | public boolean isBST(Node root) { 118 | return isBSTRec(root, Integer.MIN_VALUE, Integer.MAX_VALUE); 119 | } 120 | 121 | private boolean isBSTRec(Node node, int min, int max) { 122 | if (node == null) { 123 | return true; 124 | } 125 | 126 | if (node.data <= min || node.data > max) { 127 | return false; 128 | } 129 | 130 | boolean isBSTOfLeft = isBSTRec(node.left, min, node.data); 131 | boolean isBSTOfRight = isBSTRec(node.right, node.data, max); 132 | 133 | return isBSTOfLeft && isBSTOfRight; 134 | } 135 | 136 | 137 | public class Node { 138 | int data; 139 | Node left; 140 | Node right; 141 | 142 | public Node() {} 143 | public Node(int data) { 144 | this.data = data; 145 | } 146 | 147 | public Node(int data, Node left, Node right) { 148 | this.data = data; 149 | this.left = left; 150 | this.right = right; 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /src/test/java/datastructure/linkedlist/SingleLinkedListTest.java: -------------------------------------------------------------------------------- 1 | package datastructure.linkedlist; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | import java.util.Stack; 8 | 9 | import static org.hamcrest.CoreMatchers.is; 10 | import static org.junit.Assert.assertThat; 11 | 12 | public class SingleLinkedListTest { 13 | 14 | @Test 15 | public void test() { 16 | assertThat("", is(testFunction())); 17 | } 18 | 19 | public String testFunction() { 20 | return ""; 21 | } 22 | 23 | public class Node { 24 | int data; 25 | Node next; 26 | } 27 | 28 | private class SingleLinkedList { 29 | private Node head; 30 | 31 | public void addToHead(int n) { 32 | Node newNode = new Node(); 33 | newNode.data = n; 34 | head.next = newNode; 35 | head = newNode; 36 | } 37 | 38 | /* 39 | TASK 40 | 첫번째 원소를 제거하라. 41 | */ 42 | 43 | public void removeFirst() { 44 | if (head == null) { 45 | throw new RuntimeException("Not found"); 46 | } 47 | // head = head.next; 48 | Node temp = head; 49 | head = null; 50 | head = temp.next; 51 | } 52 | 53 | /* 54 | TASK 55 | 중복된 원소를 제거하라. 56 | */ 57 | 58 | public void removeDuplicateElm() { 59 | Set set = new HashSet<>(); 60 | Node prev = null; 61 | Node start = head; 62 | while (start != null) { 63 | if (set.contains(start.data)) { 64 | if (prev == null) { 65 | break ; 66 | } 67 | prev.next = start.next; 68 | } else { 69 | set.add(start.data); 70 | prev = start; 71 | } 72 | start = start.next; 73 | } 74 | } 75 | 76 | /* 77 | TASK 78 | 역순으로 출력하라. 79 | */ 80 | 81 | public void reverse() { 82 | Node prev = null; 83 | Node start = head; 84 | Node next = null; 85 | while (start != null) { 86 | next = start.next; 87 | start.next = prev; 88 | prev = next; 89 | } 90 | } 91 | 92 | /* 93 | TASK 94 | k번째 원소를 찾아라. 95 | */ 96 | 97 | public Node kthToLast(int k) { 98 | Node result = head; 99 | if (k < 0) { 100 | return null; 101 | } 102 | int count = 0; 103 | while(count < k) { 104 | result = head.next; 105 | head = head.next; 106 | count++; 107 | } 108 | return result; 109 | } 110 | 111 | /* 112 | TASK 113 | 회문인지 판단하라. 114 | */ 115 | 116 | public boolean isPlaindrome() { 117 | Stack stack = new Stack<>(); 118 | Node node1 = head; 119 | Node node2 = head; 120 | while (node1 != null && node2 != null) { 121 | stack.push(node1); 122 | node1 = head.next; 123 | node2 = head.next.next; 124 | } 125 | if (node2 != null) { //홀수인 경우 126 | node1 = node1.next; 127 | } 128 | 129 | while (node1 != null) { 130 | if (stack.pop().data != node1.data) { 131 | return false; 132 | } 133 | node1 = node1.next; 134 | } 135 | return true; 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/test/java/datastructure/priorityqueue/CalcTopTen.java: -------------------------------------------------------------------------------- 1 | package datastructure.priorityqueue; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.PriorityQueue; 6 | import java.util.Queue; 7 | 8 | import static org.hamcrest.CoreMatchers.is; 9 | import static org.junit.Assert.assertThat; 10 | 11 | public class CalcTopTen { 12 | 13 | /* 14 | TASK 15 | 많은 수 중 top 10을 구한다. 16 | */ 17 | 18 | @Test 19 | public void test() { 20 | TopTen t = new TopTen(); 21 | t.put(1); 22 | t.put(2); 23 | t.put(3); 24 | t.put(4); 25 | t.put(5); 26 | t.put(6); 27 | t.put(7); 28 | t.put(8); 29 | t.put(9); 30 | t.put(10); 31 | t.put(11); 32 | t.put(12); 33 | t.put(19); 34 | t.put(21); 35 | t.put(13); 36 | int[] arr = new int[10]; 37 | int j = 0; 38 | for (int i = arr.length; i > 0; i--) { 39 | arr[j] = i; 40 | j++; 41 | } 42 | assertThat(t.getTop10(), is(arr)); 43 | } 44 | 45 | public class TopTen { 46 | private Queue queue = new PriorityQueue<>(); 47 | 48 | private void put(int data) { 49 | queue.add(data); 50 | } 51 | 52 | private int[] getTop10() { 53 | int[] arr = new int[10]; 54 | for (int i = arr.length - 1; i >= 0; i--) { 55 | arr[i] = queue.poll(); 56 | } 57 | return arr; 58 | } 59 | 60 | private void read(int n) { 61 | if (queue.size() < 10) { 62 | queue.offer(n); 63 | } else { 64 | int tenth = queue.peek(); 65 | if (n > tenth) { 66 | queue.poll(); 67 | queue.offer(n); 68 | } 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/test/java/datastructure/priorityqueue/HeapSortByUsingPQ.java: -------------------------------------------------------------------------------- 1 | package datastructure.priorityqueue; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.PriorityQueue; 6 | import java.util.Queue; 7 | 8 | import static org.hamcrest.CoreMatchers.is; 9 | import static org.junit.Assert.assertThat; 10 | 11 | public class HeapSortByUsingPQ { 12 | 13 | /* 14 | TASK 15 | Priority queue를 사용하여 heap sort를 하라. 16 | */ 17 | 18 | @Test 19 | public void test() { 20 | int[] arr = new int[5]; 21 | arr[0] = 3; 22 | arr[1] = 7; 23 | arr[2] = 1; 24 | arr[3] = 9; 25 | arr[4] = 6; 26 | 27 | int[] sortedArr = new int[5]; 28 | sortedArr[0] = 1; 29 | sortedArr[1] = 3; 30 | sortedArr[2] = 6; 31 | sortedArr[3] = 7; 32 | sortedArr[4] = 9; 33 | assertThat(heapSort(arr), is(sortedArr)); 34 | } 35 | 36 | public int[] heapSort(int[] arr) { 37 | Queue queue = new PriorityQueue<>(); 38 | for (int i = 0; i < arr.length; i++) { //O(nlogn) 39 | queue.add(arr[i]); 40 | } 41 | int[] newArr = new int[arr.length]; 42 | for (int i = 0; i < newArr.length; i++) { //O(nlogn) 43 | newArr[i] = queue.poll(); 44 | } 45 | return newArr; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/datastructure/queue/QueueWithTwoStack.java: -------------------------------------------------------------------------------- 1 | package datastructure.queue; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Stack; 6 | 7 | import static org.hamcrest.CoreMatchers.is; 8 | import static org.junit.Assert.assertThat; 9 | 10 | public class QueueWithTwoStack { 11 | 12 | /* 13 | TASK 14 | Stack 두 개로 Queue를 구현한다. 15 | */ 16 | 17 | @Test 18 | public void test() { 19 | MyQueue queue = new MyQueue<>(); 20 | queue.offer(1); 21 | queue.offer(2); 22 | queue.offer(3); 23 | queue.offer(4); 24 | 25 | assertThat(queue.size(), is(4)); 26 | 27 | assertThat(queue.poll(), is(1)); 28 | assertThat(queue.poll(), is(2)); 29 | assertThat(queue.poll(), is(3)); 30 | assertThat(queue.poll(), is(4)); 31 | 32 | assertThat(queue.size(), is(0)); 33 | } 34 | 35 | public class MyQueue { 36 | private Stack stack1; 37 | private Stack stack2; 38 | 39 | public MyQueue() { 40 | stack1 = new Stack(); 41 | stack2 = new Stack(); 42 | } 43 | 44 | public void offer(T elm) { 45 | // 1. 아예 stack2를 queue와 동일하게 데이터를 저장하는 방법 46 | // while (!stack2.isEmpty()) { 47 | // stack1.push(stack2.pop()); 48 | // } 49 | // stack1.push(elm); 50 | // 51 | // while (!stack1.isEmpty()) { 52 | // stack2.push(stack1.pop()); 53 | // } 54 | 55 | // 2. poll할 때만 queue처럼 반환하는 방법 56 | stack1.push(elm); 57 | } 58 | 59 | public T poll() { 60 | // 1. 아예 stack2를 queue와 동일하게 데이터를 저장하는 방법 61 | // return stack2.pop(); 62 | 63 | // 2. poll할 때만 queue처럼 반환하는 방법 64 | if (stack2.isEmpty()) { 65 | while(!stack1.isEmpty()) { 66 | stack2.push(stack1.pop()); 67 | } 68 | } 69 | return stack2.pop(); 70 | 71 | } 72 | 73 | public int size() { 74 | // 1. 아예 stack2를 queue와 동일하게 데이터를 저장하는 방법 75 | // return stack2.size(); 76 | 77 | // 2. poll할 때만 queue처럼 반환하는 방법 78 | return stack1.size() + stack2.size(); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/test/java/datastructure/queue/ReverseQueueTest.java: -------------------------------------------------------------------------------- 1 | package datastructure.queue; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.LinkedList; 6 | import java.util.Queue; 7 | import java.util.Stack; 8 | 9 | import static org.hamcrest.CoreMatchers.is; 10 | import static org.junit.Assert.assertThat; 11 | 12 | public class ReverseQueueTest { 13 | 14 | /* 15 | TASK 16 | Stack을 사용하여 queue를 stack처럼 만든다. 17 | */ 18 | 19 | @Test 20 | public void test() { 21 | Queue que = new LinkedList<>(); 22 | que.offer(1); 23 | que.offer(2); 24 | que.offer(3); 25 | 26 | reverseQueue(que); 27 | 28 | assertThat(que.poll(), is(3)); 29 | assertThat(que.poll(), is(2)); 30 | assertThat(que.poll(), is(1)); 31 | } 32 | 33 | public Queue reverseQueue(Queue que) { 34 | Stack stack = new Stack<>(); 35 | while (!que.isEmpty()) { 36 | stack.push(que.poll()); 37 | } 38 | while(!stack.isEmpty()) { 39 | que.offer(stack.pop()); 40 | } 41 | return que; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/datastructure/stack/CheckBrace.java: -------------------------------------------------------------------------------- 1 | package datastructure.stack; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Stack; 6 | 7 | import static org.hamcrest.CoreMatchers.is; 8 | import static org.junit.Assert.assertThat; 9 | 10 | public class CheckBrace { 11 | 12 | /* 13 | TASK 14 | 괄호의 유효성을 체크한다. 15 | */ 16 | 17 | @Test 18 | public void test() { 19 | assertThat(solution("(())"), is(true)); 20 | assertThat(solution("()()"), is(true)); 21 | assertThat(solution(")(())("), is(false)); 22 | assertThat(solution("(())("), is(false)); 23 | assertThat(solution(")(())"), is(false)); 24 | assertThat(solution("(()"), is(false)); 25 | assertThat(solution("())"), is(false)); 26 | 27 | assertThat(solution("(asdc;aga;ac;dsc;)"), is(true)); 28 | assertThat(solution("(aaa(bbb)ccc)"), is(true)); 29 | } 30 | 31 | public boolean solution(String braces) { 32 | Stack stack = new Stack<>(); 33 | 34 | if (braces == null) return true; 35 | char open = "(".charAt(0); 36 | char close = ")".charAt(0); 37 | 38 | for (char c : braces.toCharArray()) { 39 | if (c == open) { 40 | stack.push(c); 41 | } else if (c == close){ 42 | if (stack.isEmpty()) { 43 | return false; 44 | } 45 | stack.pop(); 46 | } 47 | } 48 | 49 | if (stack.isEmpty()) { 50 | return true; 51 | } 52 | 53 | return false; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/datastructure/stack/IsPalindromeTest.java: -------------------------------------------------------------------------------- 1 | package datastructure.stack; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Stack; 6 | 7 | import static org.hamcrest.CoreMatchers.is; 8 | import static org.junit.Assert.assertThat; 9 | 10 | public class IsPalindromeTest { 11 | 12 | /* 13 | TASK 14 | Stack 자료구조를 사용하여 회문을 판별한다. 15 | */ 16 | 17 | @Test 18 | public void test() { 19 | assertThat(isPalindrome("abba"), is(true)); 20 | assertThat(isPalindrome("dabccbad"), is(true)); 21 | assertThat(isPalindrome("abcba"), is(true)); 22 | assertThat(isPalindrome("fabccdedccbaf"), is(true)); 23 | assertThat(isPalindrome("fabccdedccbf"), is(false)); 24 | } 25 | 26 | public boolean isPalindrome(String str) { 27 | Stack stack = new Stack<>(); 28 | char[] charArr = str.toCharArray(); 29 | for (int i = 0; i < str.length() / 2; i++) { 30 | stack.add(charArr[i]); 31 | } 32 | 33 | for (int i = (str.length() + 1)/2; i < str.length(); i++) { 34 | if (stack.pop() != charArr[i]) { 35 | return false; 36 | } 37 | } 38 | return true; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/datastructure/stack/MinimumStackTest.java: -------------------------------------------------------------------------------- 1 | package datastructure.stack; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Stack; 6 | 7 | import static org.hamcrest.CoreMatchers.is; 8 | import static org.junit.Assert.assertThat; 9 | 10 | 11 | public class MinimumStackTest { 12 | 13 | /* 14 | TASK 15 | Stack에 저장된 값들 중 최소값을 반환하는 minStack() 함수를 구현한다. 16 | */ 17 | 18 | @Test 19 | public void test() { 20 | MyStack stack = new MyStack(); 21 | stack.push(3); 22 | stack.push(5); 23 | stack.push(4); 24 | stack.push(2); 25 | stack.push(6); 26 | 27 | assertThat(stack.min(), is(2)); 28 | } 29 | 30 | public class MyStack { 31 | private Stack stack; 32 | private Stack minStack; 33 | 34 | public MyStack() { 35 | stack = new Stack<>(); 36 | minStack = new Stack<>(); 37 | } 38 | 39 | public void push(int newVal) { 40 | if (minStack.isEmpty() || newVal <= minStack.peek()) { 41 | minStack.push(newVal); 42 | } 43 | stack.push(newVal); 44 | } 45 | 46 | public int pop() { 47 | int val = stack.pop(); 48 | if (!minStack.isEmpty() && val == minStack.peek()) { 49 | minStack.pop(); 50 | } 51 | return val; 52 | } 53 | 54 | public int min() { 55 | if (minStack.isEmpty()) { 56 | throw new RuntimeException(""); 57 | } 58 | return minStack.peek(); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/datastructure/stack/MyStackWithArrayListTest.java: -------------------------------------------------------------------------------- 1 | package datastructure.stack; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import static org.hamcrest.CoreMatchers.is; 9 | import static org.junit.Assert.assertThat; 10 | 11 | public class MyStackWithArrayListTest { 12 | 13 | /* 14 | TASK 15 | ArrayList를 사용하여 Stack을 구현한다. 16 | */ 17 | 18 | @Test 19 | public void test() { 20 | MyStackWithArrayList stack = new MyStackWithArrayList<>(); 21 | 22 | stack.push(0); 23 | stack.push(1); 24 | stack.push(2); 25 | stack.push(3); 26 | stack.push(4); 27 | stack.push(5); 28 | stack.push(6); 29 | 30 | assertThat(stack.pop(), is(6)); 31 | assertThat(stack.pop(), is(5)); 32 | assertThat(stack.pop(), is(4)); 33 | assertThat(stack.pop(), is(3)); 34 | assertThat(stack.pop(), is(2)); 35 | assertThat(stack.pop(), is(1)); 36 | assertThat(stack.pop(), is(0)); 37 | // java.lang.ArrayIndexOutOfBoundsException: -1 38 | // assertThat(stack.pop(), is(0)); 39 | } 40 | 41 | public class MyStackWithArrayList { 42 | private List data; 43 | 44 | public MyStackWithArrayList() { 45 | data = new ArrayList(); 46 | } 47 | 48 | public void push(T i) { 49 | data.add(i); 50 | } 51 | 52 | public T pop() { 53 | return data.remove(data.size() - 1); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/datastructure/stack/MyStackWithArrayTest.java: -------------------------------------------------------------------------------- 1 | package datastructure.stack; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class MyStackWithArrayTest { 9 | 10 | /* 11 | TASK 12 | Array를 사용하여 Stack을 구현한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | MyStackWithArray stack = new MyStackWithArray(); 18 | 19 | stack.push(0); 20 | stack.push(1); 21 | stack.push(2); 22 | stack.push(3); 23 | stack.push(4); 24 | stack.push(5); 25 | stack.push(6); 26 | 27 | assertThat(stack.pop(), is(6)); 28 | assertThat(stack.pop(), is(5)); 29 | assertThat(stack.pop(), is(4)); 30 | assertThat(stack.pop(), is(3)); 31 | assertThat(stack.pop(), is(2)); 32 | assertThat(stack.pop(), is(1)); 33 | assertThat(stack.pop(), is(0)); 34 | 35 | // java.lang.RuntimeException: Empty Stack! 36 | // assertThat(0, is(stack.pop())); 37 | } 38 | 39 | public class MyStackWithArray { 40 | private int[] data = new int[5]; 41 | private int topIndex = -1; 42 | 43 | public synchronized void push(int i) { 44 | topIndex++; 45 | if (topIndex >= data.length) { 46 | int[] oldData = data; 47 | data = new int[data.length * 2]; 48 | // System.arraycopy(oldData, 0, data, 0, oldData.length); 49 | for (int j = 0; j < oldData.length; j++) { 50 | data[j] = oldData[j]; 51 | } 52 | } 53 | 54 | data[topIndex] = i; 55 | } 56 | 57 | public synchronized int pop() { 58 | if (topIndex < 0) { 59 | throw new RuntimeException("Empty Stack!"); 60 | } 61 | // int result = data[topIndex]; 62 | // topIndex--; 63 | return data[topIndex--]; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/test/java/exercise/CalenderExample.java: -------------------------------------------------------------------------------- 1 | package exercise; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | import static org.hamcrest.CoreMatchers.is; 9 | import static org.junit.Assert.assertThat; 10 | 11 | public class CalenderExample { 12 | 13 | /* 14 | TASK 15 | 2017년 1월 1일은 일요일이다. 16 | 2017년 어느날의 월, 일을 입력받아 요일을 반환하는 함수를 구현한다. 17 | 18 | 2017년 2월은 28일까지 있다. 19 | 요일은 월~일을 0~6으로 표현한다. 20 | 예를 들어 월요일이면 0을 반환하고, 토요일은 5, 일요일은 6을 반환한다. 21 | */ 22 | 23 | @Test 24 | public void test() { 25 | Calendar c = new Calendar(); 26 | assertThat(c.getDay(3, 20), is("금요일")); 27 | } 28 | 29 | public int getDayOfWeek(int month, int day) { 30 | int[] daysInMonth = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 31 | int count = 0; 32 | 33 | for (int i = 1; i < month; i++) { 34 | count += daysInMonth[i]; 35 | } 36 | count += day; 37 | count += 5; 38 | return count % 7; 39 | } 40 | 41 | public class Calendar { 42 | private Map calender; 43 | 44 | public Calendar() { 45 | this.calender = buildCalender(); 46 | } 47 | 48 | public String getDay(int month, int day) { 49 | switch (getDayIntFormat(month, day)) { 50 | case 0: 51 | return "월요일"; 52 | case 1: 53 | return "화요일"; 54 | case 2: 55 | return "수요일"; 56 | case 3: 57 | return "목요일"; 58 | case 4: 59 | return "금요일"; 60 | case 5: 61 | return "토요일"; 62 | case 6: 63 | return "일요일"; 64 | default: 65 | return null; 66 | } 67 | } 68 | 69 | private int getDayIntFormat(int month, int day) { 70 | for (Map.Entry entry : calender.entrySet()) { 71 | int sum = 0; 72 | if (entry.getKey() == month) { 73 | return (sum + day + 5) % 7; 74 | } 75 | sum += entry.getValue(); 76 | } 77 | return -1; 78 | } 79 | 80 | private Map buildCalender() { 81 | Map calender = new HashMap<>(); 82 | calender.put(1, 31); 83 | calender.put(2, 28); 84 | calender.put(3, 31); 85 | calender.put(4, 30); 86 | calender.put(5, 31); 87 | calender.put(6, 30); 88 | calender.put(7, 31); 89 | calender.put(8, 31); 90 | calender.put(9, 30); 91 | calender.put(10, 31); 92 | calender.put(11, 30); 93 | calender.put(12, 31); 94 | return calender; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/test/java/exercise/FactorialZeroCount.java: -------------------------------------------------------------------------------- 1 | package exercise; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class FactorialZeroCount { 9 | 10 | /* 11 | TASK 12 | n!의 결과값에서 0의 개수를 구한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | 18 | assertThat(countZero1(getFactorial(5)), is(1)); 19 | assertThat(countZero1(getFactorial(12)), is(2)); 20 | assertThat(countZero2(5), is(1)); 21 | assertThat(countZero2(12), is(2)); 22 | } 23 | 24 | public int getFactorial(int num) { 25 | int result = 1; 26 | for (int i = 1; i <= num; i++) { 27 | result *= i; 28 | } 29 | return result; 30 | } 31 | 32 | public int countZero1(int num) { 33 | int count = 0; 34 | while (num % 10 == 0) { 35 | num /= 10; 36 | count++; 37 | } 38 | return count; 39 | } 40 | 41 | 42 | // 5가 얼마나 곱해졌는지가 중요하다. 43 | public int countZero2(int num) { 44 | int count = 0; 45 | for (int i = 5; i <= num; i += 5) { 46 | int base = i; 47 | while (base % 5 == 0) { 48 | base /= 5; 49 | count++; 50 | } 51 | } 52 | return count; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/java/exercise/FindMaxSumInArray.java: -------------------------------------------------------------------------------- 1 | package exercise; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class FindMaxSumInArray { 9 | 10 | /* 11 | TASK 12 | 주어진 배열에서 합이 최대가 되는 sub array의 합을 구한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | int[] arr1 = {1,2,-9,4,-3,12,24,3,4,-8,10,9}; 18 | assertThat(solution(arr1), is(55)); 19 | int[] arr2 = {}; 20 | assertThat(solution(arr2), is(Integer.MAX_VALUE)); 21 | int[] arr3 = {1}; 22 | assertThat(solution(arr3), is(1)); 23 | int[] arr4 = {1,2}; 24 | assertThat(solution(arr4), is(3)); 25 | } 26 | 27 | public int solution(int[] arr) { 28 | if (arr == null || arr.length == 0) return Integer.MAX_VALUE; 29 | 30 | int max = arr[0]; 31 | 32 | for (int i = 1; i < arr.length; i++) { 33 | if (arr[i] > max + arr[i]) { 34 | max = arr[i]; 35 | } else { 36 | max += arr[i]; 37 | } 38 | } 39 | 40 | return max; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/exercise/FindSquareNum.java: -------------------------------------------------------------------------------- 1 | package exercise; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class FindSquareNum { 9 | 10 | /* 11 | TASK 12 | 주어진 두 수 사이에 존재하는 수 중 제곱수가 되는 것을 구한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | assertThat(solution(4, 17), is(3)); 18 | assertThat(solution(17, 37), is(2)); 19 | assertThat(solution(63, 123), is(4)); 20 | assertThat(solution(17, 4), is(0)); 21 | assertThat(solution(-1, -1), is(-1)); 22 | } 23 | 24 | public int solution(int A, int B) { 25 | if (A < 0 && B < 0) return -1; 26 | int result = 0; 27 | for (int i = (int) Math.sqrt(A); i <= (int) Math.sqrt(B); i++) { 28 | int target = i * i; 29 | if (target >= A && target <= B) { 30 | result += 1; 31 | } 32 | } 33 | return result; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/exercise/LinkedListLength.java: -------------------------------------------------------------------------------- 1 | package exercise; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class LinkedListLength { 9 | 10 | /* 11 | TASK 12 | 주어진 배열은 어떠한 링크드 리스트의 정보를 담고 있다. 13 | 배열의 각 원소는 다음 노드의 인덱스를 나타낸다. 14 | 원소의 값이 -1이면 링크드 리스트가 끝났음을 의미한다. 15 | 이 때 주어진 배열로 구성된 링크드 리스트의 길이를 구한다. 16 | */ 17 | 18 | @Test 19 | public void test() { 20 | int[] arr = {1, 4, -1, 3, 2}; 21 | assertThat(solution(arr), is(4)); 22 | int[] arr1 = {-1}; 23 | assertThat(solution(arr1), is(1)); 24 | int[] arr2 = {1, -1}; 25 | assertThat(solution(arr2), is(2)); 26 | } 27 | 28 | public int solution(int[] A) { 29 | if (A.length == 1) return 1; 30 | int pos = 0; 31 | int count = 0; 32 | while (pos != -1) { 33 | pos = A[pos]; 34 | count += 1; 35 | } 36 | 37 | return count; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/exercise/NoTempSwapTest.java: -------------------------------------------------------------------------------- 1 | package exercise; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class NoTempSwapTest { 9 | 10 | /* 11 | TASK 12 | temp 를 사용하지 않고 두 변수를 swap 한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | int a = 4; 18 | int b = 3; 19 | 20 | int[] result = swap(a, b); 21 | assertThat(result[0] == 3, is(true)); 22 | assertThat(result[1] == 4, is(true)); 23 | } 24 | 25 | public int[] swap(int a, int b) { 26 | int[] result = new int[2]; 27 | a = a + b; 28 | b = a - b; 29 | a = a - b; 30 | result[0] = a; 31 | result[1] = b; 32 | return result; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/exercise/OnlyTwoDigitSum.java: -------------------------------------------------------------------------------- 1 | package exercise; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class OnlyTwoDigitSum { 9 | 10 | /* 11 | TASK 12 | 주어진 배열에서 두 자리수만 골라서 합한 값을 return 한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | int[] arr = {1, 1000, 80, -91}; 18 | assertThat(solution(arr), is(-11)); 19 | int[] arr1 = {}; 20 | assertThat(solution(arr1), is(0)); 21 | int[] arr2 = {-1, -2}; 22 | assertThat(solution(arr2), is(0)); 23 | } 24 | 25 | public int solution(int[] A) { 26 | int result = 0; 27 | for (int i = 0; i < A.length; i++) { 28 | int target = Math.abs(A[i]); 29 | if (target / 100 < 1 && target / 10 > 0) { 30 | result += A[i]; 31 | } 32 | } 33 | return result; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/exercise/SameFaceDice.java: -------------------------------------------------------------------------------- 1 | package exercise; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class SameFaceDice { 9 | 10 | /* 11 | TASK 12 | 각각의 주사위들이 모두 같은 면을 보이기 위한 최소 rotate 횟수를 구한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | int[] arr1 = {1,2,3}; 18 | assertThat(solution(arr1), is(2)); 19 | int[] arr2 = {1,1,6}; 20 | assertThat(solution(arr2), is(2)); 21 | int[] arr3 = {1,6,2,3}; 22 | assertThat(solution(arr3), is(3)); 23 | int[] arr4 = {1,1}; 24 | assertThat(solution(arr4), is(0)); 25 | int[] arr5 = {3,3,4,4,2}; 26 | assertThat(solution(arr5), is(4)); 27 | } 28 | 29 | public int solution(int[] A) { 30 | int result = Integer.MAX_VALUE; 31 | for (int dice = 1; dice <= 6; dice++) { 32 | int count = 0; 33 | for (int i = 0; i < A.length; i++) { 34 | if (A[i] != dice) { 35 | if (A[i] + dice == 7) { 36 | count += 2; 37 | } else { 38 | count += 1; 39 | } 40 | } 41 | } 42 | if (result >= count) { 43 | result = count; 44 | } 45 | } 46 | return result; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/test/java/exercise/SearchEquilibrium.java: -------------------------------------------------------------------------------- 1 | package exercise; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class SearchEquilibrium { 9 | 10 | /* 11 | TASK 12 | 주어진 배열에서 양 쪽의 합이 동일해지는 index의 값을 구한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | int[] arr = {-4, 8, 16, -22, 0, -4, 8, 16, -22}; 18 | assertThat(true, is(solution(arr) == 0 || solution(arr) == 4)); 19 | } 20 | 21 | public int solution(int[] arr) { 22 | if (arr == null) return -1; 23 | 24 | double total = 0; 25 | for (int i = 0; i < arr.length; i++) { 26 | total += arr[i]; 27 | } 28 | 29 | if (total - arr[0] == 0) { 30 | return 0; 31 | } 32 | 33 | if (total - arr[arr.length - 1] == arr[arr.length - 1]) { 34 | return arr.length - 1; 35 | } 36 | 37 | int left = 0; 38 | for (int i = 1; i < arr.length; i++) { 39 | left += arr[i - 1]; 40 | if ((total - arr[i])/2 == left) { 41 | return i; 42 | } 43 | } 44 | 45 | return -1; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/famous_algorithm/KMP_Algorithm.java: -------------------------------------------------------------------------------- 1 | package famous_algorithm; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class KMP_Algorithm { 9 | 10 | /* 11 | TASK 12 | 장문의 문자열 A가 존재할 때, 13 | 이 문자열 A 안에 특정 문자열 B가 존재하는지 알 수 있는 방법을 해결한다. 14 | */ 15 | 16 | @Test 17 | public void test() { 18 | assertThat(KMP("abcxabcdabcdabcy".toCharArray(), "abcdabcy".toCharArray()), is(true)); 19 | } 20 | 21 | /* 22 | SOLVE 23 | Karp-Rabin에서는 한 칸씩 이동하면서 패턴 문자열과 비교해줬다. 24 | 하지만 이는 비교 과정 중에 발생한 소중한 정보를 버리고 다시 비교하는 것이다. 25 | kmp는 한 칸씩 이동하는 것이 아니라 몇 칸씩 이동하며 비교하기 때문에 26 | karp-rabin 보다 빠르게 탐색이 가능하다. 27 | 28 | 패턴의 접두사와 접미사 그리고 경계라는 것을 사용하여 비교가 필요없는 경우를 필터링해 필요할 때만 비교를 해준다. 29 | 비교를 한 다음 일치하는 부분의 접두사와 접미사를 비교하여 같은 개수 만큼 이동한다. 30 | 그리고 경계부터 다시 본문과 비교해준다. 31 | 32 | 매번 접두사와 접미사를 비교하는 것도 비용이므로 33 | 접두사와 접미사가 같은 개수에 대한 테이블을 만들어둔다. 34 | 35 | TIME COMPLEXITY : O(M + N) 36 | */ 37 | 38 | private int[] computeTemporaryArray(char[] pattern) { 39 | int[] lps = new int[pattern.length]; 40 | int idx = 0; 41 | for (int i = 1; i < pattern.length;) { 42 | if (pattern[i] == pattern[idx]) { 43 | lps[i] = idx + 1; 44 | idx++; 45 | i++; 46 | } else { 47 | if (idx != 0) { 48 | idx = lps[idx - 1]; 49 | } else { 50 | lps[i] = 0; 51 | i++; 52 | } 53 | } 54 | } 55 | return lps; 56 | } 57 | 58 | public boolean KMP(char []text, char []pattern){ 59 | 60 | int lps[] = computeTemporaryArray(pattern); 61 | int i=0; 62 | int j=0; 63 | while(i < text.length && j < pattern.length){ 64 | if(text[i] == pattern[j]){ 65 | i++; 66 | j++; 67 | }else{ 68 | if(j!=0){ 69 | j = lps[j-1]; 70 | }else{ 71 | i++; 72 | } 73 | } 74 | } 75 | if(j == pattern.length){ 76 | return true; 77 | } 78 | return false; 79 | } 80 | 81 | /* 82 | REFERENCE 83 | YOUTUBE : https://www.youtube.com/watch?v=GTJr8OvyEVQ 84 | GITHUB : https://github.com/mission-peace/interview/blob/master/src/com/interview/string/SubstringSearch.java 85 | */ 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/test/java/famous_algorithm/Karp_Rabin_Algorithm.java: -------------------------------------------------------------------------------- 1 | package famous_algorithm; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class Karp_Rabin_Algorithm { 9 | 10 | /* 11 | TASK 12 | 장문의 문자열 A가 존재할 때, 13 | 이 문자열 A 안에 특정 문자열 B가 존재하는지 알 수 있는 방법을 해결한다. 14 | */ 15 | 16 | @Test 17 | public void test() { 18 | KarpRabinSearch rbk = new KarpRabinSearch(); 19 | assertThat(rbk.patternSearch("dgethwabcafg".toCharArray(), "abc".toCharArray()), is(6)); 20 | } 21 | 22 | /* 23 | SOLVE 24 | 문자열을 수치로 변환시켜 탐색한다. 25 | 찾고자 하는 문자열을 hash 값으로 치환하여 26 | 본문에서 이와 동일한 hash 값에 대해서만 같은 문자열인지 비교해준다. 27 | (다른 문자열도 hash 값이 같을 수 있으므로) 28 | 이 때 핵심은 찾고자 하는 문자열의 hash 값은 물론이고 본문의 hash 값을 효율적으로 구할 수 있는 것이다. 29 | 즉 찾고자하는 문자열과 비교를 할 때 매번 hash 값을 생성하는 것이 아니고 30 | 수학적인 규칙 속에서 이미 계산한 값을 재사용하는 것이 핵심이다. 31 | 32 | TIME COMPLEXITY : O(MN) 33 | */ 34 | 35 | public class KarpRabinSearch { 36 | private int prime = 101; 37 | 38 | public int patternSearch(char[] text, char[] pattern) { 39 | int m = pattern.length; 40 | int n = text.length; 41 | long patternHash = createHash(pattern, m - 1); 42 | long textHash = createHash(text, m - 1); 43 | 44 | for (int i = 1; i < n - m + 1; i++) { 45 | if (patternHash == textHash && checkEqual(text, i - 1, i + m - 2, pattern, 0, m - 1)) { 46 | return i - 1; 47 | } 48 | 49 | if (i < n - m + 1) { 50 | textHash = reCalculateHash(text, i - 1, i + m - 1, textHash, m); 51 | } 52 | } 53 | return -1; 54 | } 55 | 56 | private boolean checkEqual(char[] str1, int start1, int end1, char[] str2, int start2, int end2) { 57 | if (end1 - start1 != end2 - start2) { 58 | return false; 59 | } 60 | while (start1 <= end1 && start2 <= end2) { 61 | if (str1[start1] != str2[start2]) { 62 | return false; 63 | } 64 | start1++; 65 | start2++; 66 | } 67 | return true; 68 | } 69 | 70 | private long reCalculateHash(char[] str, int oldIndex, int newIndex, long oldHash, int patternLen) { 71 | long newHash = oldHash - str[oldIndex]; 72 | newHash = newHash / prime; 73 | newHash += str[newIndex]*Math.pow(prime, patternLen - 1); 74 | return newHash; 75 | } 76 | 77 | private long createHash(char[] str, int end) { 78 | long hash = 0; 79 | for (int i = 0; i <= end; i++) { 80 | hash += str[i]*Math.pow(prime, i); 81 | 82 | } 83 | return hash; 84 | } 85 | } 86 | 87 | /* 88 | REFERENCE 89 | YOUTUBE : https://www.youtube.com/watch?v=H4VrKHVG5qI 90 | GITHUB : https://github.com/mission-peace/interview/blob/master/src/com/interview/string/RabinKarpSearch.java 91 | */ 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/test/java/search/BinarySearchTest.java: -------------------------------------------------------------------------------- 1 | package search; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class BinarySearchTest { 9 | 10 | /* 11 | TASK 12 | binary search를 사용하여 O(log n)의 시간복잡도로 target을 찾는다. 13 | */ 14 | @Test 15 | public void test() { 16 | int[] arr1 = {11,22,33,44,55,66,77,88}; 17 | int[] arr2 = {11,22,33,44,55,66,77}; 18 | int[] arr3 = {1}; 19 | int[] arr4 = {}; 20 | assertThat(search(arr1, 33), is(2)); 21 | assertThat(search(arr2, 22), is(1)); 22 | assertThat(search(arr3, 1), is(0)); 23 | assertThat(search(arr4, 1), is(-1)); 24 | 25 | assertThat(searchByRec(arr1, 33), is(2)); 26 | assertThat(searchByRec(arr2, 22), is(1)); 27 | assertThat(searchByRec(arr3, 1), is(0)); 28 | assertThat(searchByRec(arr4, 1), is(-1)); 29 | } 30 | 31 | // while version 32 | private int search(int[] arr, int target) { 33 | if (arr == null) return -1; 34 | int left = 0; 35 | int right = arr.length - 1; 36 | int mid; 37 | while (left <= right) { 38 | mid = left + (right - left) / 2; 39 | if (arr[mid] == target) { 40 | return mid; 41 | } 42 | 43 | if (arr[mid] < target) { 44 | left = mid + 1; 45 | } else { 46 | right = mid - 1; 47 | } 48 | } 49 | return -1; 50 | } 51 | 52 | //recursive version 53 | private int searchByRec(int[] arr, int target) { 54 | if (arr == null) return -1; 55 | return searchRec(arr, 0, arr.length - 1, target); 56 | } 57 | 58 | private int searchRec(int[] arr, int left, int right, int target) { 59 | if (left > right || left < 0 || right >= arr.length) return -1; 60 | int mid = left + (right - left) / 2; 61 | 62 | if (arr[mid] == target) { 63 | return mid; 64 | } else if (arr[mid] < target) { 65 | return searchRec(arr, mid + 1, right, target); 66 | } else { 67 | return searchRec(arr, left, mid - 1, target); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/test/java/search/SearchIn2DTest.java: -------------------------------------------------------------------------------- 1 | package search; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class SearchIn2DTest { 9 | 10 | /* 11 | TASK 12 | 정렬된 2차원 배열에서 검색한다. 13 | 1. 각 row 별로 for-loop 돌면서 O(log n)의 sort을 한다. 14 | 2. O(n) 15 | */ 16 | 17 | @Test 18 | public void test() { 19 | int[][] matrix = new int[5][5]; 20 | for (int i = 0; i < matrix[0].length; i++) { 21 | for (int j = 0; j < matrix[0].length; j++) { 22 | matrix[i][j] = i + j; 23 | } 24 | } 25 | assertThat(getTargetPosition(matrix, 5), is(new Position(4,1))); 26 | } 27 | 28 | public Position getTargetPosition(int[][] matrix, int target) { 29 | if (matrix == null) return null; 30 | 31 | int row = matrix.length - 1; 32 | int col = 0; 33 | 34 | while (row >= 0 && col < matrix[0].length) { 35 | if (matrix[row][col] == target) { 36 | return new Position(row, col); 37 | } else if (matrix[row][col] < target) { 38 | col++; 39 | } else { 40 | row--; 41 | } 42 | } 43 | 44 | return null; 45 | } 46 | 47 | public class Position { 48 | int row; 49 | int col; 50 | 51 | public Position(int row, int col) { 52 | this.row = row; 53 | this.col = col; 54 | } 55 | 56 | @Override 57 | public boolean equals(Object o) { 58 | if (this == o) return true; 59 | if (o == null || getClass() != o.getClass()) return false; 60 | 61 | Position position = (Position) o; 62 | 63 | if (row != position.row) return false; 64 | return col == position.col; 65 | } 66 | 67 | @Override 68 | public int hashCode() { 69 | int result = row; 70 | result = 31 * result + col; 71 | return result; 72 | } 73 | 74 | @Override 75 | public String toString() { 76 | return "Position{" + 77 | "row=" + row + 78 | ", col=" + col + 79 | '}'; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/test/java/sort/BubbleSort.java: -------------------------------------------------------------------------------- 1 | package sort; 2 | 3 | import org.junit.Test; 4 | import utils.Utils; 5 | 6 | import static org.hamcrest.CoreMatchers.is; 7 | import static org.junit.Assert.assertThat; 8 | 9 | public class BubbleSort { 10 | 11 | /* 12 | TASK 13 | bubble sort를 구현한다. 14 | */ 15 | 16 | @Test 17 | public void test() { 18 | int[] arr = {2,1,4,0,3}; 19 | int[] sortedArr = new int[arr.length]; 20 | for (int i = 0; i < sortedArr.length; i++) { 21 | sortedArr[i] = i; 22 | } 23 | assertThat(sort(arr), is(sortedArr)); 24 | } 25 | 26 | public int[] sort(int[] arr) { 27 | for (int i = 0; i < arr.length - 1; i++) { 28 | for (int j = i + 1; j < arr.length; j++) { 29 | if (arr[i] > arr[j]) { 30 | Utils.swapValue(arr, i, j); 31 | } 32 | } 33 | } 34 | return arr; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/sort/InsertionSort.java: -------------------------------------------------------------------------------- 1 | package sort; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class InsertionSort { 9 | 10 | /* 11 | TASK 12 | Insertion sort를 구현한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | int[] arr1 = {}; 18 | int[] sortedArr1 = {}; 19 | assertThat(solution(arr1), is(sortedArr1)); 20 | int[] arr2 = {6,4,1,8,9,2,7,5,3}; 21 | int[] sortedArr2 = {1,2,3,4,5,6,7,8,9}; 22 | assertThat(solution(arr2), is(sortedArr2)); 23 | int[] arr3 = {1}; 24 | int[] sortedArr3 = {1}; 25 | assertThat(solution(arr3), is(sortedArr3)); 26 | } 27 | 28 | public int[] solution(int[] arr) { 29 | if (arr == null) return null; 30 | int temp; 31 | for (int i = 1; i < arr.length; i++) { 32 | temp = arr[i]; 33 | int k; 34 | for (k = i - 1; k >= 0; k--) { 35 | if (temp >= arr[k]) { 36 | break; 37 | } 38 | arr[k + 1] = arr[k]; 39 | } 40 | arr[k + 1] = temp; 41 | } 42 | 43 | return arr; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/sort/QuickSort.java: -------------------------------------------------------------------------------- 1 | package sort; 2 | 3 | import org.junit.Test; 4 | import utils.Utils; 5 | 6 | import static org.hamcrest.CoreMatchers.is; 7 | import static org.junit.Assert.assertThat; 8 | 9 | public class QuickSort { 10 | 11 | /* 12 | TASK 13 | Quick sort를 구현한다. 14 | */ 15 | 16 | @Test 17 | public void test() { 18 | int[] arr1 = {}; 19 | int[] sortedArr1 = {}; 20 | assertThat(solution(arr1, 0, arr1.length - 1), is(sortedArr1)); 21 | int[] arr2 = {6,4,1,8,9,2,7,5,3}; 22 | int[] sortedArr2 = {1,2,3,4,5,6,7,8,9}; 23 | assertThat(solution(arr2, 0, arr2.length - 1), is(sortedArr2)); 24 | int[] arr4 = {6,4,2,10,9,1,7,11,5,3,0,8}; 25 | int[] sortedArr4 = {0,1,2,3,4,5,6,7,8,9,10,11}; 26 | assertThat(solution(arr4, 0, arr4.length - 1), is(sortedArr4)); 27 | int[] arr3 = {1}; 28 | int[] sortedArr3 = {1}; 29 | assertThat(solution(arr3, 0, arr3.length - 1), is(sortedArr3)); 30 | } 31 | 32 | public int[] solution(int[] arr, int left, int right) { 33 | if (arr == null) return null; 34 | 35 | int[] result = arr; 36 | if (left >= right) return result; 37 | 38 | int pivotPos = partition(result, left, right); 39 | 40 | result = solution(result, left, pivotPos - 1); 41 | result = solution(result, pivotPos + 1, right); 42 | 43 | return result; 44 | } 45 | 46 | private int partition(int[] arr, int left, int right) { 47 | if (arr == null || left < 0) return -1; 48 | int pivotValue = arr[right]; 49 | int endOfLowBlock = left - 1; 50 | 51 | for (int pos = left; pos < right; ++pos) { 52 | if (pivotValue > arr[pos]) { 53 | endOfLowBlock += 1; 54 | Utils.swapValue(arr, pos, endOfLowBlock); 55 | } 56 | } 57 | endOfLowBlock += 1; 58 | Utils.swapValue(arr, right, endOfLowBlock); 59 | 60 | return endOfLowBlock; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/sort/RadixSort.java: -------------------------------------------------------------------------------- 1 | package sort; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class RadixSort { 9 | 10 | /* 11 | TASK 12 | radix sort를 구현한다. 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | int[] arr = new int[5]; 18 | arr[0] = 52; 19 | arr[1] = 31; 20 | arr[2] = 24; 21 | arr[3] = 45; 22 | arr[4] = 13; 23 | 24 | int[] sortedArr = new int[arr.length]; 25 | sortedArr[0] = 13; 26 | sortedArr[1] = 24; 27 | sortedArr[2] = 31; 28 | sortedArr[3] = 45; 29 | sortedArr[4] = 52; 30 | assertThat(sort(arr), is(sortedArr)); 31 | } 32 | 33 | public int[] sort(int[] arr) { 34 | int[] newArr = new int[100]; 35 | int[] result = new int[arr.length]; 36 | for (int item : arr) { 37 | newArr[item] = item; 38 | } 39 | int index = 0; 40 | for (int item : newArr) { 41 | if (item != 0) { 42 | result[index++] = item; 43 | } 44 | } 45 | return result; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/test/java/sort/SelectionSort.java: -------------------------------------------------------------------------------- 1 | package sort; 2 | 3 | import org.junit.Test; 4 | import utils.Utils; 5 | 6 | import static org.hamcrest.CoreMatchers.is; 7 | import static org.junit.Assert.assertThat; 8 | 9 | public class SelectionSort { 10 | 11 | /* 12 | TASK 13 | Selection sort를 구현한다. 14 | */ 15 | 16 | @Test 17 | public void test() { 18 | int[] arr1 = {}; 19 | int[] sortedArr1 = {}; 20 | assertThat(solution(arr1), is(sortedArr1)); 21 | int[] arr2 = {6,4,1,8,9,2,7,5,3}; 22 | int[] sortedArr2 = {1,2,3,4,5,6,7,8,9}; 23 | assertThat(solution(arr2), is(sortedArr2)); 24 | int[] arr3 = {1}; 25 | int[] sortedArr3 = {1}; 26 | assertThat(solution(arr3), is(sortedArr3)); 27 | } 28 | 29 | public int[] solution(int[] arr) { 30 | if (arr == null) return null; 31 | int[] result = arr; 32 | int maxPos; 33 | 34 | for (int i = 0; i < result.length - 1; i++) { 35 | maxPos = i; 36 | for (int k = i + 1; k < result.length; k++) { 37 | if (result[maxPos] > result[k]) { 38 | maxPos = k; 39 | } 40 | } 41 | result = Utils.swapValue(result, i, maxPos); 42 | } 43 | return result; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.hamcrest.CoreMatchers.is; 6 | import static org.junit.Assert.assertThat; 7 | 8 | public class Utils { 9 | 10 | /* 11 | TASK 12 | swap util 분리 13 | */ 14 | 15 | @Test 16 | public void test() { 17 | int[] arr = {1,2,3}; 18 | int[] chagedArr = {1,3,2}; 19 | assertThat(swapValue(arr, 1,2), is(chagedArr)); 20 | } 21 | 22 | public static int[] swapValue(int[] arr, int a, int b) { 23 | int temp = arr[a]; 24 | arr[a] = arr[b]; 25 | arr[b] = temp; 26 | return arr; 27 | } 28 | 29 | public static char[] swapValue(char[] arr, int a, int b) { 30 | char temp = arr[a]; 31 | arr[a] = arr[b]; 32 | arr[b] = temp; 33 | return arr; 34 | } 35 | } 36 | --------------------------------------------------------------------------------