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